00001
00031 #include "omxaudiomixertest.h"
00032 #include "ctype.h"
00033
00034 #define SINK_NAME "OMX.st.alsa.alsasink"
00035 #define BUFFER_COUNT_ACTUAL 2
00036 #define FRAME_SIZE 1152*2*2 // 1152 samples* 2 channels * 2byte/16bits per channel
00037
00038 OMX_CALLBACKTYPE callbacks = { .EventHandler = audiomixerEventHandler,
00039 .EmptyBufferDone = audiomixerEmptyBufferDone,
00040 .FillBufferDone = audiomixerFillBufferDone,
00041 };
00042
00043 OMX_CALLBACKTYPE audiosinkcallbacks = {
00044 .EventHandler = audiosinkEventHandler,
00045 .EmptyBufferDone = audiosinkEmptyBufferDone,
00046 .FillBufferDone = NULL
00047 };
00048
00049 static void setHeader(OMX_PTR header, OMX_U32 size) {
00050 OMX_VERSIONTYPE* ver = (OMX_VERSIONTYPE*)(header + sizeof(OMX_U32));
00051 *((OMX_U32*)header) = size;
00052
00053 ver->s.nVersionMajor = VERSIONMAJOR;
00054 ver->s.nVersionMinor = VERSIONMINOR;
00055 ver->s.nRevision = VERSIONREVISION;
00056 ver->s.nStep = VERSIONSTEP;
00057 }
00058
00059 void display_help() {
00060 printf("\n");
00061 printf("Usage: omxaudiomixertest [-o outfile] [-gi gain] -t -r 44100 -n 2 filename1 filename2\n");
00062 printf("\n");
00063 printf(" -o outfile: If this option is specified, the output stream is written to outfile\n");
00064 printf(" otherwise redirected to std output; Can't be used with -t\n");
00065 printf(" -gi : Gain of stream i[0..3] data [0...100]\n");
00066 printf(" -t : The audio mixer is tunneled with the alsa sink; Can't be used with -o\n");
00067 printf(" -r 44100 : Sample Rate [Default 44100]\n");
00068 printf(" -n 2 : Number of channel [Default 2]\n\n");
00069 printf(" -h : Displays this help\n");
00070 printf("\n");
00071 exit(1);
00072 }
00073
00074
00075 appPrivateType* appPriv;
00076 int fd = 0,fd1=0;
00077 unsigned int filesize,filesize1;
00078 int flagIsOutputExpected;
00079 int flagOutputReceived;
00080 int flagInputReceived;
00081 int flagIsGain[4];
00082 int flagPlaybackOn;
00083 int flagSetupTunnel;
00084 int flagSampleRate;
00085 int flagChannel;
00086 char *input_file[2], *output_file;
00087 static OMX_BOOL bEOS1=OMX_FALSE,bEOS2=OMX_FALSE;
00088 FILE *outfile;
00089
00090 OMX_BUFFERHEADERTYPE *inBuffer[4], *outBuffer[2],*inBufferSink[2];
00091 static OMX_BOOL isPortDisabled[4];
00092 static int iBufferDropped[2];
00093
00094 int main(int argc, char** argv) {
00095
00096 OMX_PORT_PARAM_TYPE sParam;
00097 OMX_U32 data_read,j;
00098 OMX_PARAM_PORTDEFINITIONTYPE sPortDef;
00099 OMX_AUDIO_CONFIG_VOLUMETYPE sVolume;
00100 OMX_AUDIO_PARAM_PCMMODETYPE sPcmModeType;
00101 int gain[4];
00102 int argn_dec;
00103 int i=0,fd2;
00104 OMX_U32 srate=0,nchannel=0;
00105 OMX_ERRORTYPE err;
00106 char c;
00107
00108 gain[0]=gain[1]=gain[2]=gain[3]=100;
00109
00110
00111 if(argc < 2){
00112 display_help();
00113 } else {
00114 flagIsOutputExpected = 0;
00115 flagOutputReceived = 0;
00116 flagInputReceived = 0;
00117 flagIsGain[0] = 0;
00118 flagIsGain[1] = 0;
00119 flagIsGain[2] = 0;
00120 flagIsGain[3] = 0;
00121 flagPlaybackOn = 1;
00122 flagSetupTunnel = 0;
00123 flagSampleRate = 0;
00124 flagChannel = 0;
00125
00126 argn_dec = 1;
00127 while (argn_dec<argc) {
00128 if (*(argv[argn_dec]) =='-') {
00129 if (flagIsOutputExpected) {
00130 display_help();
00131 }
00132 switch (*(argv[argn_dec]+1)) {
00133 case 'h':
00134 display_help();
00135 break;
00136 case 'o':
00137 flagIsOutputExpected = 1;
00138 flagPlaybackOn = 0;
00139 break;
00140 case 'g':
00141 i = atoi(argv[argn_dec]+2);
00142 if(i > 3) {
00143 DEBUG(DEFAULT_MESSAGES, "-g%i is not valid\n",i);
00144 i = 0;
00145 }
00146 flagIsGain[i] = 1;
00147 break;
00148 case 't':
00149 flagSetupTunnel = 1;
00150 break;
00151 case 'r':
00152 flagSampleRate = 1;
00153 break;
00154 case 'n':
00155 flagChannel = 1;
00156 break;
00157 default:
00158 display_help();
00159 }
00160 } else {
00161 if (flagIsGain[i]) {
00162 gain[i] = (int)atoi(argv[argn_dec]);
00163 DEBUG(DEFAULT_MESSAGES, "gain[%d]=%d\n",i,gain[i]);
00164 flagIsGain[i] = 0;
00165 if(gain[i] > 100) {
00166 DEBUG(DEFAULT_MESSAGES, "Gain of stream %i should be between [0..100]\n",i);
00167 gain[i] = 100;
00168 }
00169 i = 0;
00170 } else if (flagIsOutputExpected) {
00171 output_file = malloc(strlen(argv[argn_dec]) * sizeof(char) + 1);
00172 strcpy(output_file,argv[argn_dec]);
00173 flagIsOutputExpected = 0;
00174 flagOutputReceived = 1;
00175 } else if (flagSampleRate) {
00176 srate = (int)atoi(argv[argn_dec]);
00177 flagSampleRate = 0;
00178 } else if (flagChannel) {
00179 nchannel = (int)atoi(argv[argn_dec]);
00180 flagChannel = 0;
00181 } else {
00182 input_file[i] = malloc(strlen(argv[argn_dec]) * sizeof(char) + 1);
00183 strcpy(input_file[i],argv[argn_dec]);
00184 flagInputReceived = 1;
00185 i++;
00186 }
00187 }
00188 argn_dec++;
00189 }
00190 if (flagSetupTunnel) {
00191 if(flagOutputReceived) {
00192 DEBUG(DEFAULT_MESSAGES, "-o Option Ignored. No FILE output will be produced.\n");
00193 flagOutputReceived = 0;
00194 }
00195 flagPlaybackOn = 1;
00196 }
00197 if (!flagInputReceived) {
00198 display_help();
00199 }
00200 DEBUG(DEFAULT_MESSAGES, "Input file %s %s ", input_file[0],input_file[1]);
00201 DEBUG(DEFAULT_MESSAGES, " to ");
00202 if (flagOutputReceived) {
00203 DEBUG(DEFAULT_MESSAGES, " %s\n", output_file);
00204 } else {
00205 DEBUG(DEFAULT_MESSAGES, " Audio Sink\n");
00206 }
00207 }
00208
00209 if(input_file[0]== NULL || input_file[1]==NULL) {
00210 DEBUG(DEFAULT_MESSAGES, "Please Supply 2 input files\n");
00211 exit(1);
00212 }
00213 fd = open(input_file[0], O_RDONLY);
00214 if(fd < 0){
00215 perror("Error opening input file 1\n");
00216 exit(1);
00217 }
00218
00219 fd1 = open(input_file[1], O_RDONLY);
00220 if(fd1 < 0){
00221 perror("Error opening input file 2\n");
00222 exit(1);
00223 }
00224
00225 if (flagOutputReceived) {
00226 outfile = fopen(output_file,"wb");
00227 if(outfile == NULL) {
00228 DEBUG(DEB_LEV_ERR, "Error at opening the output file");
00229 exit(1);
00230 }
00231 }
00232
00233 filesize = getFileSize(fd);
00234 filesize1 = getFileSize(fd1);
00235
00236 appPriv = malloc(sizeof(appPrivateType));
00237 pthread_cond_init(&appPriv->condition, NULL);
00238 pthread_mutex_init(&appPriv->mutex, NULL);
00239 appPriv->eventSem = malloc(sizeof(tsem_t));
00240 tsem_init(appPriv->eventSem, 0);
00241 appPriv->eofSem = malloc(sizeof(tsem_t));
00242 tsem_init(appPriv->eofSem, 0);
00243 if (flagPlaybackOn) {
00244 appPriv->sinkEventSem = malloc(sizeof(tsem_t));
00245 tsem_init(appPriv->sinkEventSem, 0);
00246 }
00247 iBufferDropped[0] = 0;
00248 iBufferDropped[1] = 0;
00249
00250 err = OMX_Init();
00251 if(err != OMX_ErrorNone) {
00252 DEBUG(DEB_LEV_ERR, "OMX_Init() failed\n");
00253 exit(1);
00254 }
00256 err = OMX_GetHandle(&appPriv->handle, "OMX.st.audio.mixer", NULL , &callbacks);
00257 if(err != OMX_ErrorNone) {
00258 DEBUG(DEB_LEV_ERR, "Audio Mixer OMX_GetHandle failed\n");
00259 exit(1);
00260 }
00261 if (flagPlaybackOn) {
00262 err = OMX_GetHandle(&appPriv->audiosinkhandle, SINK_NAME, NULL , &audiosinkcallbacks);
00263 if(err != OMX_ErrorNone){
00264 DEBUG(DEB_LEV_ERR, "No sink found. Exiting...\n");
00265 exit(1);
00266 }
00267 }
00268
00269
00270 for(j=0;j<4;j++) {
00271 isPortDisabled[i] = OMX_FALSE;
00272 if((gain[j] >= 0) && (gain[j] <100)) {
00273 sVolume.nPortIndex = j;
00274 err = OMX_GetConfig(appPriv->handle, OMX_IndexConfigAudioVolume, &sVolume);
00275 if(err!=OMX_ErrorNone) {
00276 DEBUG(DEB_LEV_ERR,"Error %08x In OMX_GetConfig 0 \n",err);
00277 }
00278 sVolume.sVolume.nValue = gain[j];
00279 DEBUG(DEFAULT_MESSAGES, "Setting Gain[%i] %d \n",(int)j, gain[j]);
00280 err = OMX_SetConfig(appPriv->handle, OMX_IndexConfigAudioVolume, &sVolume);
00281 if(err!=OMX_ErrorNone) {
00282 DEBUG(DEB_LEV_ERR,"Error %08x In OMX_SetConfig 0 \n",err);
00283 }
00284 }
00285 }
00286
00287
00288 if(srate && nchannel && flagPlaybackOn) {
00289 DEBUG(DEFAULT_MESSAGES, "Sample Rate=%d,NChannel=%d\n",(int)srate,(int)nchannel);
00290 sPcmModeType.nPortIndex=0;
00291 setHeader(&sPcmModeType, sizeof(OMX_AUDIO_PARAM_PCMMODETYPE));
00292 err = OMX_GetParameter(appPriv->audiosinkhandle, OMX_IndexParamAudioPcm, &sPcmModeType);
00293
00294 sPcmModeType.nChannels = nchannel;
00295 sPcmModeType.nSamplingRate = srate;
00296 err = OMX_SetParameter(appPriv->audiosinkhandle, OMX_IndexParamAudioPcm, &sPcmModeType);
00297 if(err!=OMX_ErrorNone) {
00298 DEBUG(DEB_LEV_ERR,"Error %08x In OMX_SetParameter 0 \n",err);
00299 }
00300 }
00301
00302 if (flagSetupTunnel) {
00303 err = OMX_SetupTunnel(appPriv->handle, 4, appPriv->audiosinkhandle, 0);
00304 if(err != OMX_ErrorNone) {
00305 DEBUG(DEB_LEV_ERR, "Set up Tunnel Failed\n");
00306 exit(1);
00307 }
00308 DEBUG(DEFAULT_MESSAGES, "Set up Tunnel Completed\n");
00309 }
00310
00312 setHeader(&sParam, sizeof(OMX_PORT_PARAM_TYPE));
00313 err = OMX_GetParameter(appPriv->handle, OMX_IndexParamAudioInit, &sParam);
00314 if(err != OMX_ErrorNone){
00315 DEBUG(DEB_LEV_ERR, "Error in getting OMX_PORT_PARAM_TYPE parameter\n");
00316 exit(1);
00317 }
00318 DEBUG(DEFAULT_MESSAGES, "Audio Mixer has %d ports\n",(int)sParam.nPorts);
00319
00320 setHeader(&sPortDef, sizeof(OMX_PARAM_PORTDEFINITIONTYPE));
00321 sPortDef.nPortIndex = 0;
00322 err = OMX_GetParameter(appPriv->handle, OMX_IndexParamPortDefinition, &sPortDef);
00323
00324 sPortDef.nBufferCountActual = 2;
00325 err = OMX_SetParameter(appPriv->handle, OMX_IndexParamPortDefinition, &sPortDef);
00326 if(err != OMX_ErrorNone){
00327 DEBUG(DEB_LEV_ERR, "Error in getting OMX_PORT_PARAM_TYPE parameter\n");
00328 exit(1);
00329 }
00330 sPortDef.nPortIndex = 1;
00331 err = OMX_GetParameter(appPriv->handle, OMX_IndexParamPortDefinition, &sPortDef);
00332
00333 sPortDef.nBufferCountActual = 2;
00334 err = OMX_SetParameter(appPriv->handle, OMX_IndexParamPortDefinition, &sPortDef);
00335 if(err != OMX_ErrorNone){
00336 DEBUG(DEB_LEV_ERR, "Error in getting OMX_PORT_PARAM_TYPE parameter\n");
00337 exit(1);
00338 }
00339
00340
00341 isPortDisabled[2] = OMX_TRUE;
00342 isPortDisabled[3] = OMX_TRUE;
00343 err = OMX_SendCommand(appPriv->handle, OMX_CommandPortDisable, 2, NULL);
00344 err = OMX_SendCommand(appPriv->handle, OMX_CommandPortDisable, 3, NULL);
00345 tsem_down(appPriv->eventSem);
00346 tsem_down(appPriv->eventSem);
00347
00348
00349 err = OMX_SendCommand(appPriv->handle, OMX_CommandStateSet, OMX_StateIdle, NULL);
00350 if (flagPlaybackOn) {
00351 err = OMX_SendCommand(appPriv->audiosinkhandle, OMX_CommandStateSet, OMX_StateIdle, NULL);
00352 }
00353
00354 inBuffer[0] = inBuffer[1] = inBuffer[2] = inBuffer[3]= outBuffer[0] = outBuffer[1] = NULL;
00355
00356 for(j=0;j<BUFFER_COUNT_ACTUAL;j++) {
00357 err = OMX_AllocateBuffer(appPriv->handle, &inBuffer[j], 0, NULL, BUFFER_IN_SIZE);
00358 if (err != OMX_ErrorNone) {
00359 DEBUG(DEB_LEV_ERR, "Error on AllocateBuffer in %i %i\n",(int)j, err);
00360 exit(1);
00361 }
00362 err = OMX_AllocateBuffer(appPriv->handle, &inBuffer[j+ 2], 1, NULL, BUFFER_IN_SIZE);
00363 if (err != OMX_ErrorNone) {
00364 DEBUG(DEB_LEV_ERR, "Error on AllocateBuffer in %i %i\n",(int)j+2, err);
00365 exit(1);
00366 }
00367 }
00368
00369 if (!flagSetupTunnel) {
00370 for(j=0;j<BUFFER_COUNT_ACTUAL;j++) {
00371 err = OMX_AllocateBuffer(appPriv->handle, &outBuffer[j], 4, NULL, BUFFER_IN_SIZE);
00372 if (err != OMX_ErrorNone) {
00373 DEBUG(DEB_LEV_ERR, "Error on AllocateBuffer out %i %i\n",(int)j, err);
00374 exit(1);
00375 }
00376 }
00377 if (flagPlaybackOn) {
00378 for(j=0;j<BUFFER_COUNT_ACTUAL;j++) {
00379 err = OMX_UseBuffer(appPriv->audiosinkhandle, &inBufferSink[j], 0, NULL, BUFFER_IN_SIZE, outBuffer[j]->pBuffer);
00380 if(err != OMX_ErrorNone) {
00381 DEBUG(DEB_LEV_ERR, "Unable to use the allocated buffer %i\n",(int)j);
00382 exit(1);
00383 }
00384 }
00385 }
00386 }
00387
00388 if (flagPlaybackOn) {
00389 tsem_down(appPriv->sinkEventSem);
00390 DEBUG(DEB_LEV_SIMPLE_SEQ,"audio sink state idle\n");
00391 }
00392 tsem_down(appPriv->eventSem);
00393
00394 err = OMX_SendCommand(appPriv->handle, OMX_CommandStateSet, OMX_StateExecuting, NULL);
00395
00396
00397 tsem_down(appPriv->eventSem);
00398
00399 if (flagPlaybackOn) {
00400 DEBUG(DEB_LEV_SIMPLE_SEQ,"sending audio sink state executing\n");
00401 err = OMX_SendCommand(appPriv->audiosinkhandle, OMX_CommandStateSet, OMX_StateExecuting, NULL);
00402 if(err != OMX_ErrorNone) {
00403 DEBUG(DEB_LEV_ERR,"audio sink state executing failed\n");
00404 exit(1);
00405 }
00406 DEBUG(DEB_LEV_SIMPLE_SEQ,"waiting for audio sink state executing\n");
00407 tsem_down(appPriv->sinkEventSem);
00408 DEBUG(DEB_LEV_SIMPLE_SEQ, "audio sink state executing successful\n");
00409 }
00410 DEBUG(DEB_LEV_PARAMS, "Had buffers at:\n0x%08x\n0x%08x\n0x%08x\n0x%08x\n",
00411 (int)inBuffer[0]->pBuffer, (int)inBuffer[1]->pBuffer, (int)outBuffer[0]->pBuffer, (int)outBuffer[1]->pBuffer);
00412 DEBUG(DEB_LEV_PARAMS, "After switch to executing\n");
00413
00414 for(j=0;j<BUFFER_COUNT_ACTUAL;j++) {
00415 data_read = read(fd, inBuffer[j]->pBuffer, FRAME_SIZE);
00416 inBuffer[0]->nFilledLen = data_read;
00417 filesize -= data_read;
00418
00419 data_read = read(fd1, inBuffer[j+2]->pBuffer, FRAME_SIZE);
00420 inBuffer[2]->nFilledLen = data_read;
00421 filesize1 -= data_read;
00422 }
00423
00424 for(j=0;j<BUFFER_COUNT_ACTUAL*2;j++) {
00425 DEBUG(DEB_LEV_PARAMS, "Empty %i buffer %x\n",(int)j, (int)inBuffer[j]);
00426 err = OMX_EmptyThisBuffer(appPriv->handle, inBuffer[j]);
00427 }
00428
00432 if (!flagSetupTunnel) {
00433 for(j=0;j<BUFFER_COUNT_ACTUAL;j++) {
00434 err = OMX_FillThisBuffer(appPriv->handle, outBuffer[j]);
00435 }
00436 }
00437
00438 i=0;
00439
00440 if(!flagOutputReceived) {
00441 DEBUG(DEFAULT_MESSAGES, "\nIf you want to disabled port enter port number[0..1]: else Enter 'q' \n\n");
00442 DEBUG(DEFAULT_MESSAGES, "Entry : ");
00443 while(!bEOS1 && !bEOS2) {
00444 c = getchar();
00445 if(c=='\n') {
00446 DEBUG(DEFAULT_MESSAGES, "Entry : ");
00447 continue;
00448 } else if(toupper(c) == 'Q') {
00449 DEBUG(DEFAULT_MESSAGES,"No port to disable\n");
00450 break;
00451 } else {
00452 i= (int)atoi(&c);
00453 if(i==0 || i==1) {
00454 DEBUG(DEFAULT_MESSAGES,"Disabling Port %i\n",i);
00455 isPortDisabled[i] = OMX_TRUE;
00456 err = OMX_SendCommand(appPriv->handle, OMX_CommandPortDisable, i, NULL);
00457 while(iBufferDropped[i]!=2) {
00458 usleep(10000);
00459 }
00460
00461 for(j=0;j<BUFFER_COUNT_ACTUAL;j++) {
00462 if(i==0) {
00463 err = OMX_FreeBuffer(appPriv->handle, 0, inBuffer[j]);
00464 } else {
00465 err = OMX_FreeBuffer(appPriv->handle, 1, inBuffer[j+2]);
00466 }
00467 }
00468
00469 tsem_down(appPriv->eventSem);
00470 iBufferDropped[i] = 0;
00471 break;
00472 } else {
00473 DEBUG(DEFAULT_MESSAGES,"Either Port %i is already disabled or not valid\n",i);
00474 }
00475 }
00476 }
00477 }
00478
00479
00480 if(isPortDisabled[0] == OMX_TRUE || isPortDisabled[1] == OMX_TRUE) {
00481 DEBUG(DEFAULT_MESSAGES, "\nIf you want to re-enable port %i enter 'y' else 'n' \n\n",i);
00482 c = ' ';
00483 while(1) {
00484 c = getchar();
00485 if(c=='\n') {
00486 DEBUG(DEFAULT_MESSAGES, "Entry : ");
00487 continue;
00488 } else if(toupper(c) == 'N') {
00489 DEBUG(DEFAULT_MESSAGES,"Port to remain disable\n");
00490 break;
00491 } else if(toupper(c) == 'Y') {
00492 DEBUG(DEFAULT_MESSAGES,"Re-Enabling Port %i\n",i);
00493 err = OMX_SendCommand(appPriv->handle, OMX_CommandPortEnable, i, NULL);
00494
00495
00496 j = (i==0)?0:2;
00497
00498 err = OMX_AllocateBuffer(appPriv->handle, &inBuffer[j], i, NULL, BUFFER_IN_SIZE);
00499 if (err != OMX_ErrorNone) {
00500 DEBUG(DEB_LEV_ERR, "Error on Re-AllocateBuffer in %i %i\n",(int)j, err);
00501 exit(1);
00502 }
00503 err = OMX_AllocateBuffer(appPriv->handle, &inBuffer[j+ 1], i, NULL, BUFFER_IN_SIZE);
00504 if (err != OMX_ErrorNone) {
00505 DEBUG(DEB_LEV_ERR, "Error on Re-AllocateBuffer in %i %i\n",(int)j+1, err);
00506 exit(1);
00507 }
00508
00509 tsem_down(appPriv->eventSem);
00510 isPortDisabled[i] = OMX_FALSE;
00511
00512 fd2 = (i==0)?fd:fd1;
00513
00514 data_read = read(fd2, inBuffer[j]->pBuffer, FRAME_SIZE);
00515 inBuffer[j]->nFilledLen = data_read;
00516
00517 data_read = read(fd2, inBuffer[j+1]->pBuffer, FRAME_SIZE);
00518 inBuffer[j+1]->nFilledLen = data_read;
00519
00520
00521 err = OMX_EmptyThisBuffer(appPriv->handle, inBuffer[j]);
00522 err = OMX_EmptyThisBuffer(appPriv->handle, inBuffer[j+1]);
00523 break;
00524 }
00525
00526 }
00527 }
00528
00529
00530 DEBUG(DEFAULT_MESSAGES, "Waiting for EOS\n");
00531 if(isPortDisabled[0] == OMX_FALSE) {
00532 tsem_down(appPriv->eofSem);
00533 DEBUG(DEFAULT_MESSAGES, "Received EOS 1\n");
00534 }
00535 if(isPortDisabled[1] == OMX_FALSE) {
00536 tsem_down(appPriv->eofSem);
00537 DEBUG(DEFAULT_MESSAGES, "Received EOS 2\n");
00538 }
00539
00540 err = OMX_SendCommand(appPriv->handle, OMX_CommandStateSet, OMX_StateIdle, NULL);
00541 if (flagPlaybackOn) {
00542 err = OMX_SendCommand(appPriv->audiosinkhandle, OMX_CommandStateSet, OMX_StateIdle, NULL);
00543 }
00544 if (flagPlaybackOn) {
00545 tsem_down(appPriv->sinkEventSem);
00546 }
00547
00548 tsem_down(appPriv->eventSem);
00549
00550 err = OMX_SendCommand(appPriv->handle, OMX_CommandStateSet, OMX_StateLoaded, NULL);
00551 if (flagPlaybackOn) {
00552 err = OMX_SendCommand(appPriv->audiosinkhandle, OMX_CommandStateSet, OMX_StateLoaded, NULL);
00553 }
00554
00555 for(j=0;j<BUFFER_COUNT_ACTUAL;j++) {
00556 if(isPortDisabled[0] == OMX_FALSE) {
00557 err = OMX_FreeBuffer(appPriv->handle, 0, inBuffer[j]);
00558 }
00559 if(isPortDisabled[1] == OMX_FALSE) {
00560 err = OMX_FreeBuffer(appPriv->handle, 1, inBuffer[j+2]);
00561 }
00562 }
00563
00564 if (!flagSetupTunnel) {
00565 for(j=0;j<BUFFER_COUNT_ACTUAL;j++) {
00566 err = OMX_FreeBuffer(appPriv->handle, 4, outBuffer[j]);
00567 }
00568 }
00569
00570 if (flagPlaybackOn && !flagSetupTunnel) {
00571 for(j=0;j<BUFFER_COUNT_ACTUAL;j++) {
00572 err = OMX_FreeBuffer(appPriv->audiosinkhandle, 0, inBufferSink[j]);
00573 }
00574 }
00575 if (flagPlaybackOn) {
00576 tsem_down(appPriv->sinkEventSem);
00577 }
00578
00579
00580 tsem_down(appPriv->eventSem);
00581
00582 OMX_FreeHandle(appPriv->handle);
00583
00584 free(appPriv->eventSem);
00585 free(appPriv);
00586 if (flagPlaybackOn) {
00587 free(appPriv->sinkEventSem);
00588 appPriv->sinkEventSem = NULL;
00589 }
00590
00591 if (flagOutputReceived) {
00592 if(fclose(outfile) != 0) {
00593 DEBUG(DEB_LEV_ERR,"Error in closing output file\n");
00594 exit(1);
00595 }
00596 free(output_file);
00597 }
00598
00599 close(fd);
00600 close(fd1);
00601 free(input_file[0]);
00602 free(input_file[1]);
00603
00604 return 0;
00605 }
00606
00607
00608 OMX_ERRORTYPE audiomixerEventHandler(
00609 OMX_OUT OMX_HANDLETYPE hComponent,
00610 OMX_OUT OMX_PTR pAppData,
00611 OMX_OUT OMX_EVENTTYPE eEvent,
00612 OMX_OUT OMX_U32 Data1,
00613 OMX_OUT OMX_U32 Data2,
00614 OMX_IN OMX_PTR pEventData) {
00615
00616 DEBUG(DEB_LEV_SIMPLE_SEQ, "Hi there, I am in the %s callback\n", __func__);
00617 if(eEvent == OMX_EventCmdComplete) {
00618 if (Data1 == OMX_CommandStateSet) {
00619 DEBUG(DEB_LEV_SIMPLE_SEQ, "Volume Component State changed in ");
00620 switch ((int)Data2) {
00621 case OMX_StateInvalid:
00622 DEBUG(DEB_LEV_SIMPLE_SEQ, "OMX_StateInvalid\n");
00623 break;
00624 case OMX_StateLoaded:
00625 DEBUG(DEB_LEV_SIMPLE_SEQ, "OMX_StateLoaded\n");
00626 break;
00627 case OMX_StateIdle:
00628 DEBUG(DEB_LEV_SIMPLE_SEQ, "OMX_StateIdle\n");
00629 break;
00630 case OMX_StateExecuting:
00631 DEBUG(DEB_LEV_SIMPLE_SEQ, "OMX_StateExecuting\n");
00632 break;
00633 case OMX_StatePause:
00634 DEBUG(DEB_LEV_SIMPLE_SEQ, "OMX_StatePause\n");
00635 break;
00636 case OMX_StateWaitForResources:
00637 DEBUG(DEB_LEV_SIMPLE_SEQ, "OMX_StateWaitForResources\n");
00638 break;
00639 }
00640 tsem_up(appPriv->eventSem);
00641 } else if (Data1 == OMX_CommandPortEnable){
00642 tsem_up(appPriv->eventSem);
00643 } else if (Data1 == OMX_CommandPortDisable){
00644 tsem_up(appPriv->eventSem);
00645 }
00646 } else if(eEvent == OMX_EventBufferFlag) {
00647 if((int)Data2 == OMX_BUFFERFLAG_EOS) {
00648 tsem_up(appPriv->eofSem);
00649 }
00650 } else {
00651 DEBUG(DEB_LEV_SIMPLE_SEQ, "Param1 is %i\n", (int)Data1);
00652 DEBUG(DEB_LEV_SIMPLE_SEQ, "Param2 is %i\n", (int)Data2);
00653 }
00654
00655 return OMX_ErrorNone;
00656 }
00657
00658 OMX_ERRORTYPE audiomixerEmptyBufferDone(
00659 OMX_OUT OMX_HANDLETYPE hComponent,
00660 OMX_OUT OMX_PTR pAppData,
00661 OMX_OUT OMX_BUFFERHEADERTYPE* pBuffer) {
00662
00663 OMX_ERRORTYPE err;
00664 int data_read;
00665
00666
00667 DEBUG(DEB_LEV_FULL_SEQ, "Hi there, I am in the %s callback.\n", __func__);
00668 if(pBuffer->nInputPortIndex==0) {
00669
00670 if(isPortDisabled[0] == OMX_FALSE) {
00671 data_read = read(fd, pBuffer->pBuffer, FRAME_SIZE);
00672 pBuffer->nFilledLen = data_read;
00673 pBuffer->nOffset = 0;
00674 filesize -= data_read;
00675 DEBUG(DEB_LEV_SIMPLE_SEQ, "Sending from file 1 data read=%d\n",data_read);
00676 if (data_read <= 0) {
00677 DEBUG(DEB_LEV_SIMPLE_SEQ, "In the %s no more input data available\n", __func__);
00678 ++iBufferDropped[0];
00679 if(iBufferDropped[0]==2) {
00680 DEBUG(DEB_LEV_SIMPLE_SEQ, "In %s Dropping Empty This buffer to Audio Mixer Stream 1\n", __func__);
00681 tsem_up(appPriv->eofSem);
00682 return OMX_ErrorNone;
00683 } else if(iBufferDropped[0]>2) {
00684 DEBUG(DEB_LEV_SIMPLE_SEQ, "In %s Dropping Empty This buffer to Audio Mixer Stream 1\n", __func__);
00685 return OMX_ErrorNone;
00686 }
00687 pBuffer->nFilledLen=0;
00688 pBuffer->nFlags = OMX_BUFFERFLAG_EOS;
00689 bEOS1=OMX_TRUE;
00690 DEBUG(DEB_LEV_SIMPLE_SEQ, "In %s Sending EOS for Stream 1\n", __func__);
00691 err = OMX_EmptyThisBuffer(hComponent, pBuffer);
00692 return OMX_ErrorNone;
00693 }
00694 } else {
00695 ++iBufferDropped[0];
00696 return OMX_ErrorNone;
00697 }
00698 } else if(pBuffer->nInputPortIndex==1) {
00699
00700 if(isPortDisabled[1] == OMX_FALSE) {
00701 data_read = read(fd1, pBuffer->pBuffer, FRAME_SIZE);
00702 pBuffer->nFilledLen = data_read;
00703 pBuffer->nOffset = 0;
00704 filesize1 -= data_read;
00705 DEBUG(DEB_LEV_SIMPLE_SEQ, "Sending from file 2 data read=%d\n",data_read);
00706 if (data_read <= 0) {
00707 DEBUG(DEB_LEV_SIMPLE_SEQ, "In the %s no more input data available\n", __func__);
00708 ++iBufferDropped[1];
00709 if(iBufferDropped[1]==2) {
00710 DEBUG(DEB_LEV_SIMPLE_SEQ, "In %s Dropping Empty This buffer to Audio Mixer Stream 2\n", __func__);
00711 tsem_up(appPriv->eofSem);
00712 return OMX_ErrorNone;
00713 } else if(iBufferDropped[1]>2) {
00714 DEBUG(DEB_LEV_SIMPLE_SEQ, "In %s Dropping Empty This buffer to Audio Mixer Stream 2\n", __func__);
00715 return OMX_ErrorNone;
00716 }
00717 pBuffer->nFilledLen=0;
00718 pBuffer->nFlags = OMX_BUFFERFLAG_EOS;
00719 bEOS2=OMX_TRUE;
00720 DEBUG(DEB_LEV_SIMPLE_SEQ, "In %s Sending EOS for Stream 2\n", __func__);
00721 err = OMX_EmptyThisBuffer(hComponent, pBuffer);
00722 return OMX_ErrorNone;
00723 }
00724 }else {
00725 ++iBufferDropped[1];
00726 return OMX_ErrorNone;
00727 }
00728 }
00729 if(!bEOS1 || !bEOS2 ) {
00730 DEBUG(DEB_LEV_FULL_SEQ, "Empty buffer %x\n", (int)pBuffer);
00731 err = OMX_EmptyThisBuffer(hComponent, pBuffer);
00732 }else {
00733 DEBUG(DEB_LEV_FULL_SEQ, "In %s Dropping Empty This buffer to Audio Mixer\n", __func__);
00734 }
00735
00736 return OMX_ErrorNone;
00737 }
00738
00739 OMX_ERRORTYPE audiomixerFillBufferDone(
00740 OMX_OUT OMX_HANDLETYPE hComponent,
00741 OMX_OUT OMX_PTR pAppData,
00742 OMX_OUT OMX_BUFFERHEADERTYPE* pBuffer) {
00743
00744 OMX_ERRORTYPE err;
00745 int i;
00746
00747 DEBUG(DEB_LEV_FULL_SEQ, "Hi there, I am in the %s callback. Got buflen %i for buffer at 0x%08x\n",
00748 __func__, (int)pBuffer->nFilledLen, (int)pBuffer);
00749
00750
00751 if(pBuffer != NULL) {
00752 if (pBuffer->nFilledLen == 0) {
00753 DEBUG(DEB_LEV_ERR, "Ouch! In %s: no data in the output buffer!\n", __func__);
00754 return OMX_ErrorNone;
00755 }
00756 if (flagOutputReceived) {
00757 if(pBuffer->nFilledLen > 0) {
00758 fwrite(pBuffer->pBuffer, 1, pBuffer->nFilledLen, outfile);
00759 }
00760 pBuffer->nFilledLen = 0;
00761
00762 if(!bEOS1 || !bEOS2) {
00763 err = OMX_FillThisBuffer(hComponent, pBuffer);
00764 } else {
00765 DEBUG(DEB_LEV_FULL_SEQ, "In %s Dropping Fill This buffer to Audio Mixer\n", __func__);
00766 }
00767 } else if (flagPlaybackOn) {
00768 if(inBufferSink[0]->pBuffer == pBuffer->pBuffer) {
00769 inBufferSink[0]->nFilledLen = pBuffer->nFilledLen;
00770 err = OMX_EmptyThisBuffer(appPriv->audiosinkhandle, inBufferSink[0]);
00771 } else {
00772 inBufferSink[1]->nFilledLen = pBuffer->nFilledLen;
00773 err = OMX_EmptyThisBuffer(appPriv->audiosinkhandle, inBufferSink[1]);
00774 }
00775 if(err != OMX_ErrorNone) {
00776 DEBUG(DEB_LEV_ERR, "In %s Error %08x Calling EmptyThisBuffer\n", __func__,err);
00777 }
00778 } else {
00779 for(i=0;i<pBuffer->nFilledLen;i++) {
00780 putchar(*(char*)(pBuffer->pBuffer + i));
00781 }
00782 pBuffer->nFilledLen = 0;
00783
00784 if(!bEOS1 || !bEOS2) {
00785 err = OMX_FillThisBuffer(hComponent, pBuffer);
00786 } else {
00787 DEBUG(DEB_LEV_FULL_SEQ, "In %s Dropping Fill This buffer to Audio Mixer\n", __func__);
00788 }
00789 }
00790 } else {
00791 DEBUG(DEB_LEV_ERR, "Ouch! In %s: had NULL buffer to output...\n", __func__);
00792 }
00793
00794 return OMX_ErrorNone;
00795 }
00796
00797 OMX_ERRORTYPE audiosinkEventHandler(
00798 OMX_OUT OMX_HANDLETYPE hComponent,
00799 OMX_OUT OMX_PTR pAppData,
00800 OMX_OUT OMX_EVENTTYPE eEvent,
00801 OMX_OUT OMX_U32 Data1,
00802 OMX_OUT OMX_U32 Data2,
00803 OMX_OUT OMX_PTR pEventData) {
00804 DEBUG(DEB_LEV_SIMPLE_SEQ, "Hi there, I am in the %s callback\n", __func__);
00805 if (Data1 == OMX_CommandStateSet) {
00806 DEBUG(DEB_LEV_SIMPLE_SEQ, "Audio Sink State changed in ");
00807 switch ((int)Data2) {
00808 case OMX_StateInvalid:
00809 DEBUG(DEB_LEV_SIMPLE_SEQ, "OMX_StateInvalid\n");
00810 break;
00811 case OMX_StateLoaded:
00812 DEBUG(DEB_LEV_SIMPLE_SEQ, "OMX_StateLoaded\n");
00813 break;
00814 case OMX_StateIdle:
00815 DEBUG(DEB_LEV_SIMPLE_SEQ, "OMX_StateIdle\n");
00816 break;
00817 case OMX_StateExecuting:
00818 DEBUG(DEB_LEV_SIMPLE_SEQ, "OMX_StateExecuting\n");
00819 break;
00820 case OMX_StatePause:
00821 DEBUG(DEB_LEV_SIMPLE_SEQ, "OMX_StatePause\n");
00822 break;
00823 case OMX_StateWaitForResources:
00824 DEBUG(DEB_LEV_SIMPLE_SEQ, "OMX_StateWaitForResources\n");
00825 break;
00826 }
00827 tsem_up(appPriv->sinkEventSem);
00828 } else if (Data1 == OMX_CommandPortEnable){
00829 DEBUG(DEB_LEV_SIMPLE_SEQ, "In %s Received Port Enable Event\n",__func__);
00830 tsem_up(appPriv->sinkEventSem);
00831 } else if (Data1 == OMX_CommandPortDisable){
00832 DEBUG(DEB_LEV_SIMPLE_SEQ, "In %s Received Port Disable Event\n",__func__);
00833 tsem_up(appPriv->sinkEventSem);
00834 } else {
00835 DEBUG(DEB_LEV_SIMPLE_SEQ, "Param1 is %i\n", (int)Data1);
00836 DEBUG(DEB_LEV_SIMPLE_SEQ, "Param2 is %i\n", (int)Data2);
00837 }
00838
00839 return OMX_ErrorNone;
00840 }
00841
00842 OMX_ERRORTYPE audiosinkEmptyBufferDone(
00843 OMX_OUT OMX_HANDLETYPE hComponent,
00844 OMX_OUT OMX_PTR pAppData,
00845 OMX_OUT OMX_BUFFERHEADERTYPE* pBuffer)
00846 {
00847 OMX_ERRORTYPE err;
00848 static int alsaSinkBufferDropped=0;
00849 DEBUG(DEB_LEV_FULL_SEQ, "Hi there, I am in the %s callback.\n", __func__);
00850
00851 DEBUG(DEB_LEV_PARAMS, "Empty buffer %x\n", (int)pBuffer);
00852 if(!bEOS1 || !bEOS2) {
00853 if(outBuffer[0]->pBuffer == pBuffer->pBuffer) {
00854 outBuffer[0]->nFilledLen=0;
00855 err = OMX_FillThisBuffer(appPriv->handle, outBuffer[0]);
00856 } else {
00857 outBuffer[1]->nFilledLen=0;
00858 err = OMX_FillThisBuffer(appPriv->handle, outBuffer[1]);
00859 }
00860 if(err != OMX_ErrorNone) {
00861 DEBUG(DEB_LEV_ERR, "In %s Error %08x Calling FillThisBuffer\n", __func__,err);
00862 }
00863 } else {
00864 DEBUG(DEFAULT_MESSAGES,"In %s EOS reached\n",__func__);
00865 alsaSinkBufferDropped++;
00866 tsem_up(appPriv->eofSem);
00867 }
00868
00869 return OMX_ErrorNone;
00870 }
00871
00876 static int getFileSize(int fd) {
00877
00878 struct stat input_file_stat;
00879 int err;
00880
00881
00882 err = fstat(fd, &input_file_stat);
00883 if(err){
00884 DEBUG(DEB_LEV_ERR, "fstat failed");
00885 exit(-1);
00886 }
00887 return input_file_stat.st_size;
00888 }