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   }
00268 
00269   /*Max 4 input stream*/
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   /*Set sample rate and channel no to alsa sink if specified*/
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   /*Disable 2 out of 4 ports*/
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   /* Wait for commands to complete */
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   /*Port Disable option available in case of direct play out only*/
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   /* If user want to enable previously disabled port*/
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         /*Buffer 0..1 for Port 0 and 2..3 for Port 1*/
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         /*Sending Empty buffer*/
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   /* Wait for commands to complete */
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   /* Wait for commands to complete */
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 /* Callbacks implementation */
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   /* Output data to standard output */
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       /* Reschedule the fill buffer request */
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       /* Reschedule the fill buffer request */
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   /* Obtain input file length */
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 }

Generated for OpenMAX Bellagio rel. 0.3.5-svn by  doxygen 1.5.1
SourceForge.net Logo