omxaudiomixertest.c

Go to the documentation of this file.
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 /* Application private date: should go in the component field (segs...) */
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   /* Obtain file descriptor */
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   /* Initialize application private data */
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     /* disable the clock port of the ALSA sink */
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); /* audio sink clock port disabled */
00274     DEBUG(DEB_LEV_SIMPLE_SEQ, "In %s Audio Sink Clock Port Disabled\n", __func__);
00275   }
00276 
00277   /*Max 4 input stream*/
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   /*Set sample rate and channel no to alsa sink if specified*/
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   /*Disable 2 out of 4 ports*/
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   /* Wait for commands to complete */
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   /*Port Disable option available in case of direct play out only*/
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   /* If user want to enable previously disabled port*/
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         /*Buffer 0..1 for Port 0 and 2..3 for Port 1*/
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         /*Sending Empty buffer*/
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   /* Wait for commands to complete */
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   /* Wait for commands to complete */
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 /* Callbacks implementation */
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   /* Output data to standard output */
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       /* Reschedule the fill buffer request */
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       /* Reschedule the fill buffer request */
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   /* Obtain input file length */
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 }

Generated for OpenMAX Bellagio rel. 0.9.0 by  doxygen 1.5.1
SourceForge.net Logo