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 err = OMX_SendCommand(appPriv->audiosinkhandle, OMX_CommandPortDisable, 1, NULL);
00269 if(err != OMX_ErrorNone) {
00270 DEBUG(DEB_LEV_ERR,"audiosink clock port disable failed err=%x \n",err);
00271 exit(1);
00272 }
00273 tsem_down(appPriv->sinkEventSem);
00274 DEBUG(DEB_LEV_SIMPLE_SEQ, "In %s Audio Sink Clock Port Disabled\n", __func__);
00275 }
00276
00277
00278 for(j=0;j<4;j++) {
00279 isPortDisabled[i] = OMX_FALSE;
00280 if((gain[j] >= 0) && (gain[j] <100)) {
00281 sVolume.nPortIndex = j;
00282 err = OMX_GetConfig(appPriv->handle, OMX_IndexConfigAudioVolume, &sVolume);
00283 if(err!=OMX_ErrorNone) {
00284 DEBUG(DEB_LEV_ERR,"Error %08x In OMX_GetConfig 0 \n",err);
00285 }
00286 sVolume.sVolume.nValue = gain[j];
00287 DEBUG(DEFAULT_MESSAGES, "Setting Gain[%i] %d \n",(int)j, gain[j]);
00288 err = OMX_SetConfig(appPriv->handle, OMX_IndexConfigAudioVolume, &sVolume);
00289 if(err!=OMX_ErrorNone) {
00290 DEBUG(DEB_LEV_ERR,"Error %08x In OMX_SetConfig 0 \n",err);
00291 }
00292 }
00293 }
00294
00295
00296 if(srate && nchannel && flagPlaybackOn) {
00297 DEBUG(DEFAULT_MESSAGES, "Sample Rate=%d,NChannel=%d\n",(int)srate,(int)nchannel);
00298 sPcmModeType.nPortIndex=0;
00299 setHeader(&sPcmModeType, sizeof(OMX_AUDIO_PARAM_PCMMODETYPE));
00300 err = OMX_GetParameter(appPriv->audiosinkhandle, OMX_IndexParamAudioPcm, &sPcmModeType);
00301
00302 sPcmModeType.nChannels = nchannel;
00303 sPcmModeType.nSamplingRate = srate;
00304 err = OMX_SetParameter(appPriv->audiosinkhandle, OMX_IndexParamAudioPcm, &sPcmModeType);
00305 if(err!=OMX_ErrorNone) {
00306 DEBUG(DEB_LEV_ERR,"Error %08x In OMX_SetParameter 0 \n",err);
00307 }
00308 }
00309
00310 if (flagSetupTunnel) {
00311 err = OMX_SetupTunnel(appPriv->handle, 4, appPriv->audiosinkhandle, 0);
00312 if(err != OMX_ErrorNone) {
00313 DEBUG(DEB_LEV_ERR, "Set up Tunnel Failed\n");
00314 exit(1);
00315 }
00316 DEBUG(DEFAULT_MESSAGES, "Set up Tunnel Completed\n");
00317 }
00318
00320 setHeader(&sParam, sizeof(OMX_PORT_PARAM_TYPE));
00321 err = OMX_GetParameter(appPriv->handle, OMX_IndexParamAudioInit, &sParam);
00322 if(err != OMX_ErrorNone){
00323 DEBUG(DEB_LEV_ERR, "Error in getting OMX_PORT_PARAM_TYPE parameter\n");
00324 exit(1);
00325 }
00326 DEBUG(DEFAULT_MESSAGES, "Audio Mixer has %d ports\n",(int)sParam.nPorts);
00327
00328 setHeader(&sPortDef, sizeof(OMX_PARAM_PORTDEFINITIONTYPE));
00329 sPortDef.nPortIndex = 0;
00330 err = OMX_GetParameter(appPriv->handle, OMX_IndexParamPortDefinition, &sPortDef);
00331
00332 sPortDef.nBufferCountActual = 2;
00333 err = OMX_SetParameter(appPriv->handle, OMX_IndexParamPortDefinition, &sPortDef);
00334 if(err != OMX_ErrorNone){
00335 DEBUG(DEB_LEV_ERR, "Error in getting OMX_PORT_PARAM_TYPE parameter\n");
00336 exit(1);
00337 }
00338 sPortDef.nPortIndex = 1;
00339 err = OMX_GetParameter(appPriv->handle, OMX_IndexParamPortDefinition, &sPortDef);
00340
00341 sPortDef.nBufferCountActual = 2;
00342 err = OMX_SetParameter(appPriv->handle, OMX_IndexParamPortDefinition, &sPortDef);
00343 if(err != OMX_ErrorNone){
00344 DEBUG(DEB_LEV_ERR, "Error in getting OMX_PORT_PARAM_TYPE parameter\n");
00345 exit(1);
00346 }
00347
00348
00349 isPortDisabled[2] = OMX_TRUE;
00350 isPortDisabled[3] = OMX_TRUE;
00351 err = OMX_SendCommand(appPriv->handle, OMX_CommandPortDisable, 2, NULL);
00352 err = OMX_SendCommand(appPriv->handle, OMX_CommandPortDisable, 3, NULL);
00353 tsem_down(appPriv->eventSem);
00354 tsem_down(appPriv->eventSem);
00355
00356
00357 err = OMX_SendCommand(appPriv->handle, OMX_CommandStateSet, OMX_StateIdle, NULL);
00358 if (flagPlaybackOn) {
00359 err = OMX_SendCommand(appPriv->audiosinkhandle, OMX_CommandStateSet, OMX_StateIdle, NULL);
00360 }
00361
00362 inBuffer[0] = inBuffer[1] = inBuffer[2] = inBuffer[3]= outBuffer[0] = outBuffer[1] = NULL;
00363
00364 for(j=0;j<BUFFER_COUNT_ACTUAL;j++) {
00365 err = OMX_AllocateBuffer(appPriv->handle, &inBuffer[j], 0, NULL, BUFFER_IN_SIZE);
00366 if (err != OMX_ErrorNone) {
00367 DEBUG(DEB_LEV_ERR, "Error on AllocateBuffer in %i %i\n",(int)j, err);
00368 exit(1);
00369 }
00370 err = OMX_AllocateBuffer(appPriv->handle, &inBuffer[j+ 2], 1, NULL, BUFFER_IN_SIZE);
00371 if (err != OMX_ErrorNone) {
00372 DEBUG(DEB_LEV_ERR, "Error on AllocateBuffer in %i %i\n",(int)j+2, err);
00373 exit(1);
00374 }
00375 }
00376
00377 if (!flagSetupTunnel) {
00378 for(j=0;j<BUFFER_COUNT_ACTUAL;j++) {
00379 err = OMX_AllocateBuffer(appPriv->handle, &outBuffer[j], 4, NULL, BUFFER_IN_SIZE);
00380 if (err != OMX_ErrorNone) {
00381 DEBUG(DEB_LEV_ERR, "Error on AllocateBuffer out %i %i\n",(int)j, err);
00382 exit(1);
00383 }
00384 }
00385 if (flagPlaybackOn) {
00386 for(j=0;j<BUFFER_COUNT_ACTUAL;j++) {
00387 err = OMX_UseBuffer(appPriv->audiosinkhandle, &inBufferSink[j], 0, NULL, BUFFER_IN_SIZE, outBuffer[j]->pBuffer);
00388 if(err != OMX_ErrorNone) {
00389 DEBUG(DEB_LEV_ERR, "Unable to use the allocated buffer %i\n",(int)j);
00390 exit(1);
00391 }
00392 }
00393 }
00394 }
00395
00396 if (flagPlaybackOn) {
00397 tsem_down(appPriv->sinkEventSem);
00398 DEBUG(DEB_LEV_SIMPLE_SEQ,"audio sink state idle\n");
00399 }
00400 tsem_down(appPriv->eventSem);
00401
00402 err = OMX_SendCommand(appPriv->handle, OMX_CommandStateSet, OMX_StateExecuting, NULL);
00403
00404
00405 tsem_down(appPriv->eventSem);
00406
00407 if (flagPlaybackOn) {
00408 DEBUG(DEB_LEV_SIMPLE_SEQ,"sending audio sink state executing\n");
00409 err = OMX_SendCommand(appPriv->audiosinkhandle, OMX_CommandStateSet, OMX_StateExecuting, NULL);
00410 if(err != OMX_ErrorNone) {
00411 DEBUG(DEB_LEV_ERR,"audio sink state executing failed\n");
00412 exit(1);
00413 }
00414 DEBUG(DEB_LEV_SIMPLE_SEQ,"waiting for audio sink state executing\n");
00415 tsem_down(appPriv->sinkEventSem);
00416 DEBUG(DEB_LEV_SIMPLE_SEQ, "audio sink state executing successful\n");
00417 }
00418 DEBUG(DEB_LEV_PARAMS, "Had buffers at:\n0x%08x\n0x%08x\n0x%08x\n0x%08x\n",
00419 (int)inBuffer[0]->pBuffer, (int)inBuffer[1]->pBuffer, (int)outBuffer[0]->pBuffer, (int)outBuffer[1]->pBuffer);
00420 DEBUG(DEB_LEV_PARAMS, "After switch to executing\n");
00421
00422 for(j=0;j<BUFFER_COUNT_ACTUAL;j++) {
00423 data_read = read(fd, inBuffer[j]->pBuffer, FRAME_SIZE);
00424 inBuffer[0]->nFilledLen = data_read;
00425 filesize -= data_read;
00426
00427 data_read = read(fd1, inBuffer[j+2]->pBuffer, FRAME_SIZE);
00428 inBuffer[2]->nFilledLen = data_read;
00429 filesize1 -= data_read;
00430 }
00431
00432 for(j=0;j<BUFFER_COUNT_ACTUAL*2;j++) {
00433 DEBUG(DEB_LEV_PARAMS, "Empty %i buffer %x\n",(int)j, (int)inBuffer[j]);
00434 err = OMX_EmptyThisBuffer(appPriv->handle, inBuffer[j]);
00435 }
00436
00440 if (!flagSetupTunnel) {
00441 for(j=0;j<BUFFER_COUNT_ACTUAL;j++) {
00442 err = OMX_FillThisBuffer(appPriv->handle, outBuffer[j]);
00443 }
00444 }
00445
00446 i=0;
00447
00448 if(!flagOutputReceived) {
00449 DEBUG(DEFAULT_MESSAGES, "\nIf you want to disabled port enter port number[0..1]: else Enter 'q' \n\n");
00450 DEBUG(DEFAULT_MESSAGES, "Entry : ");
00451 while(!bEOS1 && !bEOS2) {
00452 c = getchar();
00453 if(c=='\n') {
00454 DEBUG(DEFAULT_MESSAGES, "Entry : ");
00455 continue;
00456 } else if(toupper(c) == 'Q') {
00457 DEBUG(DEFAULT_MESSAGES,"No port to disable\n");
00458 break;
00459 } else {
00460 i= (int)atoi(&c);
00461 if(i==0 || i==1) {
00462 DEBUG(DEFAULT_MESSAGES,"Disabling Port %i\n",i);
00463 isPortDisabled[i] = OMX_TRUE;
00464 err = OMX_SendCommand(appPriv->handle, OMX_CommandPortDisable, i, NULL);
00465 while(iBufferDropped[i]!=2) {
00466 usleep(10000);
00467 }
00468
00469 for(j=0;j<BUFFER_COUNT_ACTUAL;j++) {
00470 if(i==0) {
00471 err = OMX_FreeBuffer(appPriv->handle, 0, inBuffer[j]);
00472 } else {
00473 err = OMX_FreeBuffer(appPriv->handle, 1, inBuffer[j+2]);
00474 }
00475 }
00476
00477 tsem_down(appPriv->eventSem);
00478 iBufferDropped[i] = 0;
00479 break;
00480 } else {
00481 DEBUG(DEFAULT_MESSAGES,"Either Port %i is already disabled or not valid\n",i);
00482 }
00483 }
00484 }
00485 }
00486
00487
00488 if(isPortDisabled[0] == OMX_TRUE || isPortDisabled[1] == OMX_TRUE) {
00489 DEBUG(DEFAULT_MESSAGES, "\nIf you want to re-enable port %i enter 'y' else 'n' \n\n",i);
00490 c = ' ';
00491 while(1) {
00492 c = getchar();
00493 if(c=='\n') {
00494 DEBUG(DEFAULT_MESSAGES, "Entry : ");
00495 continue;
00496 } else if(toupper(c) == 'N') {
00497 DEBUG(DEFAULT_MESSAGES,"Port to remain disable\n");
00498 break;
00499 } else if(toupper(c) == 'Y') {
00500 DEBUG(DEFAULT_MESSAGES,"Re-Enabling Port %i\n",i);
00501 err = OMX_SendCommand(appPriv->handle, OMX_CommandPortEnable, i, NULL);
00502
00503
00504 j = (i==0)?0:2;
00505
00506 err = OMX_AllocateBuffer(appPriv->handle, &inBuffer[j], i, NULL, BUFFER_IN_SIZE);
00507 if (err != OMX_ErrorNone) {
00508 DEBUG(DEB_LEV_ERR, "Error on Re-AllocateBuffer in %i %i\n",(int)j, err);
00509 exit(1);
00510 }
00511 err = OMX_AllocateBuffer(appPriv->handle, &inBuffer[j+ 1], i, NULL, BUFFER_IN_SIZE);
00512 if (err != OMX_ErrorNone) {
00513 DEBUG(DEB_LEV_ERR, "Error on Re-AllocateBuffer in %i %i\n",(int)j+1, err);
00514 exit(1);
00515 }
00516
00517 tsem_down(appPriv->eventSem);
00518 isPortDisabled[i] = OMX_FALSE;
00519
00520 fd2 = (i==0)?fd:fd1;
00521
00522 data_read = read(fd2, inBuffer[j]->pBuffer, FRAME_SIZE);
00523 inBuffer[j]->nFilledLen = data_read;
00524
00525 data_read = read(fd2, inBuffer[j+1]->pBuffer, FRAME_SIZE);
00526 inBuffer[j+1]->nFilledLen = data_read;
00527
00528
00529 err = OMX_EmptyThisBuffer(appPriv->handle, inBuffer[j]);
00530 err = OMX_EmptyThisBuffer(appPriv->handle, inBuffer[j+1]);
00531 break;
00532 }
00533
00534 }
00535 }
00536
00537
00538 DEBUG(DEFAULT_MESSAGES, "Waiting for EOS\n");
00539 if(isPortDisabled[0] == OMX_FALSE) {
00540 tsem_down(appPriv->eofSem);
00541 DEBUG(DEFAULT_MESSAGES, "Received EOS 1\n");
00542 }
00543 if(isPortDisabled[1] == OMX_FALSE) {
00544 tsem_down(appPriv->eofSem);
00545 DEBUG(DEFAULT_MESSAGES, "Received EOS 2\n");
00546 }
00547
00548 err = OMX_SendCommand(appPriv->handle, OMX_CommandStateSet, OMX_StateIdle, NULL);
00549 if (flagPlaybackOn) {
00550 err = OMX_SendCommand(appPriv->audiosinkhandle, OMX_CommandStateSet, OMX_StateIdle, NULL);
00551 }
00552 if (flagPlaybackOn) {
00553 tsem_down(appPriv->sinkEventSem);
00554 }
00555
00556 tsem_down(appPriv->eventSem);
00557
00558 err = OMX_SendCommand(appPriv->handle, OMX_CommandStateSet, OMX_StateLoaded, NULL);
00559 if (flagPlaybackOn) {
00560 err = OMX_SendCommand(appPriv->audiosinkhandle, OMX_CommandStateSet, OMX_StateLoaded, NULL);
00561 }
00562
00563 for(j=0;j<BUFFER_COUNT_ACTUAL;j++) {
00564 if(isPortDisabled[0] == OMX_FALSE) {
00565 err = OMX_FreeBuffer(appPriv->handle, 0, inBuffer[j]);
00566 }
00567 if(isPortDisabled[1] == OMX_FALSE) {
00568 err = OMX_FreeBuffer(appPriv->handle, 1, inBuffer[j+2]);
00569 }
00570 }
00571
00572 if (!flagSetupTunnel) {
00573 for(j=0;j<BUFFER_COUNT_ACTUAL;j++) {
00574 err = OMX_FreeBuffer(appPriv->handle, 4, outBuffer[j]);
00575 }
00576 }
00577
00578 if (flagPlaybackOn && !flagSetupTunnel) {
00579 for(j=0;j<BUFFER_COUNT_ACTUAL;j++) {
00580 err = OMX_FreeBuffer(appPriv->audiosinkhandle, 0, inBufferSink[j]);
00581 }
00582 }
00583 if (flagPlaybackOn) {
00584 tsem_down(appPriv->sinkEventSem);
00585 }
00586
00587
00588 tsem_down(appPriv->eventSem);
00589
00590 OMX_FreeHandle(appPriv->handle);
00591
00592 free(appPriv->eventSem);
00593 free(appPriv);
00594 if (flagPlaybackOn) {
00595 free(appPriv->sinkEventSem);
00596 appPriv->sinkEventSem = NULL;
00597 }
00598
00599 if (flagOutputReceived) {
00600 if(fclose(outfile) != 0) {
00601 DEBUG(DEB_LEV_ERR,"Error in closing output file\n");
00602 exit(1);
00603 }
00604 free(output_file);
00605 }
00606
00607 close(fd);
00608 close(fd1);
00609 free(input_file[0]);
00610 free(input_file[1]);
00611
00612 return 0;
00613 }
00614
00615
00616 OMX_ERRORTYPE audiomixerEventHandler(
00617 OMX_OUT OMX_HANDLETYPE hComponent,
00618 OMX_OUT OMX_PTR pAppData,
00619 OMX_OUT OMX_EVENTTYPE eEvent,
00620 OMX_OUT OMX_U32 Data1,
00621 OMX_OUT OMX_U32 Data2,
00622 OMX_IN OMX_PTR pEventData) {
00623
00624 DEBUG(DEB_LEV_SIMPLE_SEQ, "Hi there, I am in the %s callback\n", __func__);
00625 if(eEvent == OMX_EventCmdComplete) {
00626 if (Data1 == OMX_CommandStateSet) {
00627 DEBUG(DEB_LEV_SIMPLE_SEQ, "Volume Component State changed in ");
00628 switch ((int)Data2) {
00629 case OMX_StateInvalid:
00630 DEBUG(DEB_LEV_SIMPLE_SEQ, "OMX_StateInvalid\n");
00631 break;
00632 case OMX_StateLoaded:
00633 DEBUG(DEB_LEV_SIMPLE_SEQ, "OMX_StateLoaded\n");
00634 break;
00635 case OMX_StateIdle:
00636 DEBUG(DEB_LEV_SIMPLE_SEQ, "OMX_StateIdle\n");
00637 break;
00638 case OMX_StateExecuting:
00639 DEBUG(DEB_LEV_SIMPLE_SEQ, "OMX_StateExecuting\n");
00640 break;
00641 case OMX_StatePause:
00642 DEBUG(DEB_LEV_SIMPLE_SEQ, "OMX_StatePause\n");
00643 break;
00644 case OMX_StateWaitForResources:
00645 DEBUG(DEB_LEV_SIMPLE_SEQ, "OMX_StateWaitForResources\n");
00646 break;
00647 }
00648 tsem_up(appPriv->eventSem);
00649 } else if (Data1 == OMX_CommandPortEnable){
00650 tsem_up(appPriv->eventSem);
00651 } else if (Data1 == OMX_CommandPortDisable){
00652 tsem_up(appPriv->eventSem);
00653 }
00654 } else if(eEvent == OMX_EventBufferFlag) {
00655 if((int)Data2 == OMX_BUFFERFLAG_EOS) {
00656 tsem_up(appPriv->eofSem);
00657 }
00658 } else {
00659 DEBUG(DEB_LEV_SIMPLE_SEQ, "Param1 is %i\n", (int)Data1);
00660 DEBUG(DEB_LEV_SIMPLE_SEQ, "Param2 is %i\n", (int)Data2);
00661 }
00662
00663 return OMX_ErrorNone;
00664 }
00665
00666 OMX_ERRORTYPE audiomixerEmptyBufferDone(
00667 OMX_OUT OMX_HANDLETYPE hComponent,
00668 OMX_OUT OMX_PTR pAppData,
00669 OMX_OUT OMX_BUFFERHEADERTYPE* pBuffer) {
00670
00671 OMX_ERRORTYPE err;
00672 int data_read;
00673
00674
00675 DEBUG(DEB_LEV_FULL_SEQ, "Hi there, I am in the %s callback.\n", __func__);
00676 if(pBuffer->nInputPortIndex==0) {
00677
00678 if(isPortDisabled[0] == OMX_FALSE) {
00679 data_read = read(fd, pBuffer->pBuffer, FRAME_SIZE);
00680 pBuffer->nFilledLen = data_read;
00681 pBuffer->nOffset = 0;
00682 filesize -= data_read;
00683 DEBUG(DEB_LEV_SIMPLE_SEQ, "Sending from file 1 data read=%d\n",data_read);
00684 if (data_read <= 0) {
00685 DEBUG(DEB_LEV_SIMPLE_SEQ, "In the %s no more input data available\n", __func__);
00686 ++iBufferDropped[0];
00687 if(iBufferDropped[0]==2) {
00688 DEBUG(DEB_LEV_SIMPLE_SEQ, "In %s Dropping Empty This buffer to Audio Mixer Stream 1\n", __func__);
00689 tsem_up(appPriv->eofSem);
00690 return OMX_ErrorNone;
00691 } else if(iBufferDropped[0]>2) {
00692 DEBUG(DEB_LEV_SIMPLE_SEQ, "In %s Dropping Empty This buffer to Audio Mixer Stream 1\n", __func__);
00693 return OMX_ErrorNone;
00694 }
00695 pBuffer->nFilledLen=0;
00696 pBuffer->nFlags = OMX_BUFFERFLAG_EOS;
00697 bEOS1=OMX_TRUE;
00698 DEBUG(DEB_LEV_SIMPLE_SEQ, "In %s Sending EOS for Stream 1\n", __func__);
00699 err = OMX_EmptyThisBuffer(hComponent, pBuffer);
00700 return OMX_ErrorNone;
00701 }
00702 } else {
00703 ++iBufferDropped[0];
00704 return OMX_ErrorNone;
00705 }
00706 } else if(pBuffer->nInputPortIndex==1) {
00707
00708 if(isPortDisabled[1] == OMX_FALSE) {
00709 data_read = read(fd1, pBuffer->pBuffer, FRAME_SIZE);
00710 pBuffer->nFilledLen = data_read;
00711 pBuffer->nOffset = 0;
00712 filesize1 -= data_read;
00713 DEBUG(DEB_LEV_SIMPLE_SEQ, "Sending from file 2 data read=%d\n",data_read);
00714 if (data_read <= 0) {
00715 DEBUG(DEB_LEV_SIMPLE_SEQ, "In the %s no more input data available\n", __func__);
00716 ++iBufferDropped[1];
00717 if(iBufferDropped[1]==2) {
00718 DEBUG(DEB_LEV_SIMPLE_SEQ, "In %s Dropping Empty This buffer to Audio Mixer Stream 2\n", __func__);
00719 tsem_up(appPriv->eofSem);
00720 return OMX_ErrorNone;
00721 } else if(iBufferDropped[1]>2) {
00722 DEBUG(DEB_LEV_SIMPLE_SEQ, "In %s Dropping Empty This buffer to Audio Mixer Stream 2\n", __func__);
00723 return OMX_ErrorNone;
00724 }
00725 pBuffer->nFilledLen=0;
00726 pBuffer->nFlags = OMX_BUFFERFLAG_EOS;
00727 bEOS2=OMX_TRUE;
00728 DEBUG(DEB_LEV_SIMPLE_SEQ, "In %s Sending EOS for Stream 2\n", __func__);
00729 err = OMX_EmptyThisBuffer(hComponent, pBuffer);
00730 return OMX_ErrorNone;
00731 }
00732 }else {
00733 ++iBufferDropped[1];
00734 return OMX_ErrorNone;
00735 }
00736 }
00737 if(!bEOS1 || !bEOS2 ) {
00738 DEBUG(DEB_LEV_FULL_SEQ, "Empty buffer %x\n", (int)pBuffer);
00739 err = OMX_EmptyThisBuffer(hComponent, pBuffer);
00740 }else {
00741 DEBUG(DEB_LEV_FULL_SEQ, "In %s Dropping Empty This buffer to Audio Mixer\n", __func__);
00742 }
00743
00744 return OMX_ErrorNone;
00745 }
00746
00747 OMX_ERRORTYPE audiomixerFillBufferDone(
00748 OMX_OUT OMX_HANDLETYPE hComponent,
00749 OMX_OUT OMX_PTR pAppData,
00750 OMX_OUT OMX_BUFFERHEADERTYPE* pBuffer) {
00751
00752 OMX_ERRORTYPE err;
00753 int i;
00754
00755 DEBUG(DEB_LEV_FULL_SEQ, "Hi there, I am in the %s callback. Got buflen %i for buffer at 0x%08x\n",
00756 __func__, (int)pBuffer->nFilledLen, (int)pBuffer);
00757
00758
00759 if(pBuffer != NULL) {
00760 if (pBuffer->nFilledLen == 0) {
00761 DEBUG(DEB_LEV_ERR, "Ouch! In %s: no data in the output buffer!\n", __func__);
00762 return OMX_ErrorNone;
00763 }
00764 if (flagOutputReceived) {
00765 if(pBuffer->nFilledLen > 0) {
00766 fwrite(pBuffer->pBuffer, 1, pBuffer->nFilledLen, outfile);
00767 }
00768 pBuffer->nFilledLen = 0;
00769
00770 if(!bEOS1 || !bEOS2) {
00771 err = OMX_FillThisBuffer(hComponent, pBuffer);
00772 } else {
00773 DEBUG(DEB_LEV_FULL_SEQ, "In %s Dropping Fill This buffer to Audio Mixer\n", __func__);
00774 }
00775 } else if (flagPlaybackOn) {
00776 if(inBufferSink[0]->pBuffer == pBuffer->pBuffer) {
00777 inBufferSink[0]->nFilledLen = pBuffer->nFilledLen;
00778 err = OMX_EmptyThisBuffer(appPriv->audiosinkhandle, inBufferSink[0]);
00779 } else {
00780 inBufferSink[1]->nFilledLen = pBuffer->nFilledLen;
00781 err = OMX_EmptyThisBuffer(appPriv->audiosinkhandle, inBufferSink[1]);
00782 }
00783 if(err != OMX_ErrorNone) {
00784 DEBUG(DEB_LEV_ERR, "In %s Error %08x Calling EmptyThisBuffer\n", __func__,err);
00785 }
00786 } else {
00787 for(i=0;i<pBuffer->nFilledLen;i++) {
00788 putchar(*(char*)(pBuffer->pBuffer + i));
00789 }
00790 pBuffer->nFilledLen = 0;
00791
00792 if(!bEOS1 || !bEOS2) {
00793 err = OMX_FillThisBuffer(hComponent, pBuffer);
00794 } else {
00795 DEBUG(DEB_LEV_FULL_SEQ, "In %s Dropping Fill This buffer to Audio Mixer\n", __func__);
00796 }
00797 }
00798 } else {
00799 DEBUG(DEB_LEV_ERR, "Ouch! In %s: had NULL buffer to output...\n", __func__);
00800 }
00801
00802 return OMX_ErrorNone;
00803 }
00804
00805 OMX_ERRORTYPE audiosinkEventHandler(
00806 OMX_OUT OMX_HANDLETYPE hComponent,
00807 OMX_OUT OMX_PTR pAppData,
00808 OMX_OUT OMX_EVENTTYPE eEvent,
00809 OMX_OUT OMX_U32 Data1,
00810 OMX_OUT OMX_U32 Data2,
00811 OMX_OUT OMX_PTR pEventData) {
00812 DEBUG(DEB_LEV_SIMPLE_SEQ, "Hi there, I am in the %s callback\n", __func__);
00813 if (Data1 == OMX_CommandStateSet) {
00814 DEBUG(DEB_LEV_SIMPLE_SEQ, "Audio Sink State changed in ");
00815 switch ((int)Data2) {
00816 case OMX_StateInvalid:
00817 DEBUG(DEB_LEV_SIMPLE_SEQ, "OMX_StateInvalid\n");
00818 break;
00819 case OMX_StateLoaded:
00820 DEBUG(DEB_LEV_SIMPLE_SEQ, "OMX_StateLoaded\n");
00821 break;
00822 case OMX_StateIdle:
00823 DEBUG(DEB_LEV_SIMPLE_SEQ, "OMX_StateIdle\n");
00824 break;
00825 case OMX_StateExecuting:
00826 DEBUG(DEB_LEV_SIMPLE_SEQ, "OMX_StateExecuting\n");
00827 break;
00828 case OMX_StatePause:
00829 DEBUG(DEB_LEV_SIMPLE_SEQ, "OMX_StatePause\n");
00830 break;
00831 case OMX_StateWaitForResources:
00832 DEBUG(DEB_LEV_SIMPLE_SEQ, "OMX_StateWaitForResources\n");
00833 break;
00834 }
00835 tsem_up(appPriv->sinkEventSem);
00836 } else if (Data1 == OMX_CommandPortEnable){
00837 DEBUG(DEB_LEV_SIMPLE_SEQ, "In %s Received Port Enable Event\n",__func__);
00838 tsem_up(appPriv->sinkEventSem);
00839 } else if (Data1 == OMX_CommandPortDisable){
00840 DEBUG(DEB_LEV_SIMPLE_SEQ, "In %s Received Port Disable Event\n",__func__);
00841 tsem_up(appPriv->sinkEventSem);
00842 } else {
00843 DEBUG(DEB_LEV_SIMPLE_SEQ, "Param1 is %i\n", (int)Data1);
00844 DEBUG(DEB_LEV_SIMPLE_SEQ, "Param2 is %i\n", (int)Data2);
00845 }
00846
00847 return OMX_ErrorNone;
00848 }
00849
00850 OMX_ERRORTYPE audiosinkEmptyBufferDone(
00851 OMX_OUT OMX_HANDLETYPE hComponent,
00852 OMX_OUT OMX_PTR pAppData,
00853 OMX_OUT OMX_BUFFERHEADERTYPE* pBuffer)
00854 {
00855 OMX_ERRORTYPE err;
00856 static int alsaSinkBufferDropped=0;
00857 DEBUG(DEB_LEV_FULL_SEQ, "Hi there, I am in the %s callback.\n", __func__);
00858
00859 DEBUG(DEB_LEV_PARAMS, "Empty buffer %x\n", (int)pBuffer);
00860 if(!bEOS1 || !bEOS2) {
00861 if(outBuffer[0]->pBuffer == pBuffer->pBuffer) {
00862 outBuffer[0]->nFilledLen=0;
00863 err = OMX_FillThisBuffer(appPriv->handle, outBuffer[0]);
00864 } else {
00865 outBuffer[1]->nFilledLen=0;
00866 err = OMX_FillThisBuffer(appPriv->handle, outBuffer[1]);
00867 }
00868 if(err != OMX_ErrorNone) {
00869 DEBUG(DEB_LEV_ERR, "In %s Error %08x Calling FillThisBuffer\n", __func__,err);
00870 }
00871 } else {
00872 DEBUG(DEFAULT_MESSAGES,"In %s EOS reached\n",__func__);
00873 alsaSinkBufferDropped++;
00874 tsem_up(appPriv->eofSem);
00875 }
00876
00877 return OMX_ErrorNone;
00878 }
00879
00884 static int getFileSize(int fd) {
00885
00886 struct stat input_file_stat;
00887 int err;
00888
00889
00890 err = fstat(fd, &input_file_stat);
00891 if(err){
00892 DEBUG(DEB_LEV_ERR, "fstat failed");
00893 exit(-1);
00894 }
00895 return input_file_stat.st_size;
00896 }