|
OpenMAXBellagio 0.9.3
|
00001 00027 #include "omxvolcontroltest.h" 00028 #include <extension_struct.h> 00029 00030 /* Application private date: should go in the component field (segs...) */ 00031 appPrivateType* appPriv; 00032 int fd = 0; 00033 unsigned int filesize; 00034 OMX_ERRORTYPE err; 00035 OMX_HANDLETYPE handle; 00036 00037 OMX_CALLBACKTYPE callbacks = { .EventHandler = volcEventHandler, 00038 .EmptyBufferDone = volcEmptyBufferDone, 00039 .FillBufferDone = volcFillBufferDone, 00040 }; 00041 00042 static void setHeader(OMX_PTR header, OMX_U32 size) { 00043 OMX_VERSIONTYPE* ver = (OMX_VERSIONTYPE*)(header + sizeof(OMX_U32)); 00044 *((OMX_U32*)header) = size; 00045 00046 ver->s.nVersionMajor = VERSIONMAJOR; 00047 ver->s.nVersionMinor = VERSIONMINOR; 00048 ver->s.nRevision = VERSIONREVISION; 00049 ver->s.nStep = VERSIONSTEP; 00050 } 00051 00052 void display_help() { 00053 printf("\n"); 00054 printf("Usage: omxvolcontroltest [-o outfile] [-g gain] filename\n"); 00055 printf("\n"); 00056 printf(" -o outfile: If this option is specified, the output stream is written to outfile\n"); 00057 printf(" otherwise redirected to std output\n"); 00058 printf(" -g: Gain of PCM data [0...100]\n"); 00059 printf(" -h: Displays this help\n"); 00060 printf("\n"); 00061 exit(1); 00062 } 00063 00064 int flagIsOutputExpected; 00065 int flagOutputReceived; 00066 int flagInputReceived; 00067 int flagIsGain; 00068 char *input_file, *output_file; 00069 static OMX_BOOL bEOS=OMX_FALSE; 00070 FILE *outfile; 00071 00072 int main(int argc, char** argv) { 00073 00074 OMX_PORT_PARAM_TYPE param; 00075 OMX_BUFFERHEADERTYPE *inBuffer1, *inBuffer2, *outBuffer1, *outBuffer2; 00076 int data_read1; 00077 int data_read2; 00078 OMX_PARAM_PORTDEFINITIONTYPE sPortDef; 00079 OMX_AUDIO_CONFIG_VOLUMETYPE sVolume; 00080 int gain=100; 00081 int argn_dec; 00082 OMX_PARAM_BELLAGIOTHREADS_ID threadsID; 00083 OMX_INDEXTYPE custom_index; 00084 00085 /* Obtain file descriptor */ 00086 if(argc < 2){ 00087 display_help(); 00088 } else { 00089 flagIsOutputExpected = 0; 00090 flagOutputReceived = 0; 00091 flagInputReceived = 0; 00092 flagIsGain = 0; 00093 00094 argn_dec = 1; 00095 while (argn_dec<argc) { 00096 if (*(argv[argn_dec]) =='-') { 00097 if (flagIsOutputExpected) { 00098 display_help(); 00099 } 00100 switch (*(argv[argn_dec]+1)) { 00101 case 'h': 00102 display_help(); 00103 break; 00104 case 'o': 00105 flagIsOutputExpected = 1; 00106 break; 00107 case 'g': 00108 flagIsGain = 1; 00109 break; 00110 default: 00111 display_help(); 00112 } 00113 } else { 00114 if (flagIsGain) { 00115 gain = (int)atoi(argv[argn_dec]); 00116 flagIsGain = 0; 00117 if(gain > 100) { 00118 DEBUG(DEFAULT_MESSAGES, "Gain should be between [0..100]\n"); 00119 gain = 100; 00120 } 00121 } else if (flagIsOutputExpected) { 00122 output_file = malloc(strlen(argv[argn_dec]) + 1); 00123 strcpy(output_file,argv[argn_dec]); 00124 flagIsOutputExpected = 0; 00125 flagOutputReceived = 1; 00126 } else { 00127 input_file = malloc(strlen(argv[argn_dec]) + 1); 00128 strcpy(input_file,argv[argn_dec]); 00129 flagInputReceived = 1; 00130 } 00131 } 00132 argn_dec++; 00133 } 00134 if (!flagInputReceived) { 00135 display_help(); 00136 } 00137 DEBUG(DEFAULT_MESSAGES, "Input file %s", input_file); 00138 DEBUG(DEFAULT_MESSAGES, " to "); 00139 if (flagOutputReceived) { 00140 DEBUG(DEFAULT_MESSAGES, " %s\n", output_file); 00141 } 00142 } 00143 00144 00145 fd = open(input_file, O_RDONLY); 00146 if(fd < 0){ 00147 perror("Error opening input file\n"); 00148 exit(1); 00149 } 00150 00151 if (flagOutputReceived) { 00152 outfile = fopen(output_file,"wb"); 00153 if(outfile == NULL) { 00154 DEBUG(DEB_LEV_ERR, "Error at opening the output file"); 00155 exit(1); 00156 } 00157 } 00158 00159 filesize = getFileSize(fd); 00160 /* Initialize application private data */ 00161 appPriv = malloc(sizeof(appPrivateType)); 00162 pthread_cond_init(&appPriv->condition, NULL); 00163 pthread_mutex_init(&appPriv->mutex, NULL); 00164 appPriv->eventSem = malloc(sizeof(tsem_t)); 00165 tsem_init(appPriv->eventSem, 0); 00166 appPriv->eofSem = malloc(sizeof(tsem_t)); 00167 tsem_init(appPriv->eofSem, 0); 00168 00169 err = OMX_Init(); 00170 if(err != OMX_ErrorNone) { 00171 DEBUG(DEB_LEV_ERR, "OMX_Init() failed\n"); 00172 exit(1); 00173 } 00176 err = OMX_GetHandle(&handle, "OMX.st.volume.component", NULL /*appPriv */, &callbacks); 00177 if(err != OMX_ErrorNone) { 00178 DEBUG(DEB_LEV_ERR, "OMX_GetHandle failed\n"); 00179 exit(1); 00180 } 00181 00182 /* test the new feature of thread ID detection 00183 */ 00184 err = OMX_GetExtensionIndex(handle, "OMX.st.index.param.BellagioThreadsID", &custom_index); 00185 if(err != OMX_ErrorNone) { 00186 DEBUG(DEB_LEV_ERR, "OMX_GetExtensionIndex failed\n"); 00187 exit(1); 00188 } 00189 00190 setHeader(&threadsID, sizeof(OMX_PARAM_BELLAGIOTHREADS_ID)); 00191 err = OMX_GetParameter(handle, custom_index, &threadsID); 00192 if(err != OMX_ErrorNone) { 00193 DEBUG(DEB_LEV_ERR, "OMX_GetParameter of extended index failed\n"); 00194 } else { 00195 DEBUG(DEFAULT_MESSAGES, "threadsID messages %i buffers %i\n", (int)threadsID.nThreadMessageID, (int)threadsID.nThreadBufferMngtID); 00196 } 00197 00198 if((gain >= 0) && (gain <100)) { 00199 err = OMX_GetConfig(handle, OMX_IndexConfigAudioVolume, &sVolume); 00200 if(err!=OMX_ErrorNone) { 00201 DEBUG(DEB_LEV_ERR,"Error %08x In OMX_GetConfig 0 \n",err); 00202 } 00203 sVolume.sVolume.nValue = gain; 00204 DEBUG(DEFAULT_MESSAGES, "Setting Gain %d \n", gain); 00205 err = OMX_SetConfig(handle, OMX_IndexConfigAudioVolume, &sVolume); 00206 if(err!=OMX_ErrorNone) { 00207 DEBUG(DEB_LEV_ERR,"Error %08x In OMX_SetConfig 0 \n",err); 00208 } 00209 } 00210 00212 param.nPorts = 2; 00213 setHeader(¶m, sizeof(OMX_PORT_PARAM_TYPE)); 00214 err = OMX_GetParameter(handle, OMX_IndexParamAudioInit, ¶m); 00215 if(err != OMX_ErrorNone){ 00216 DEBUG(DEB_LEV_ERR, "Error in getting OMX_PORT_PARAM_TYPE parameter\n"); 00217 exit(1); 00218 } 00219 00220 setHeader(&sPortDef, sizeof(OMX_PARAM_PORTDEFINITIONTYPE)); 00221 sPortDef.nPortIndex = 0; 00222 err = OMX_GetParameter(handle, OMX_IndexParamPortDefinition, &sPortDef); 00223 00224 sPortDef.nBufferCountActual = 2; 00225 err = OMX_SetParameter(handle, OMX_IndexParamPortDefinition, &sPortDef); 00226 if(err != OMX_ErrorNone){ 00227 DEBUG(DEB_LEV_ERR, "Error in getting OMX_PORT_PARAM_TYPE parameter\n"); 00228 exit(1); 00229 } 00230 sPortDef.nPortIndex = 1; 00231 err = OMX_GetParameter(handle, OMX_IndexParamPortDefinition, &sPortDef); 00232 00233 sPortDef.nBufferCountActual = 2; 00234 err = OMX_SetParameter(handle, OMX_IndexParamPortDefinition, &sPortDef); 00235 if(err != OMX_ErrorNone){ 00236 DEBUG(DEB_LEV_ERR, "Error in getting OMX_PORT_PARAM_TYPE parameter\n"); 00237 exit(1); 00238 } 00239 00240 err = OMX_SendCommand(handle, OMX_CommandStateSet, OMX_StateIdle, NULL); 00241 00242 inBuffer1 = inBuffer2 = outBuffer1 = outBuffer2 = NULL; 00243 err = OMX_AllocateBuffer(handle, &inBuffer1, 0, NULL, BUFFER_IN_SIZE); 00244 if (err != OMX_ErrorNone) { 00245 DEBUG(DEB_LEV_ERR, "Error on AllocateBuffer in 1%i\n", err); 00246 exit(1); 00247 } 00248 err = OMX_AllocateBuffer(handle, &inBuffer2, 0, NULL, BUFFER_IN_SIZE); 00249 if (err != OMX_ErrorNone) { 00250 DEBUG(DEB_LEV_ERR, "Error on AllocateBuffer in 2 %i\n", err); 00251 exit(1); 00252 } 00253 err = OMX_AllocateBuffer(handle, &outBuffer1, 1, NULL, BUFFER_IN_SIZE); 00254 if (err != OMX_ErrorNone) { 00255 DEBUG(DEB_LEV_ERR, "Error on AllocateBuffer out 1 %i\n", err); 00256 exit(1); 00257 } 00258 err = OMX_AllocateBuffer(handle, &outBuffer2, 1, NULL, BUFFER_IN_SIZE); 00259 if (err != OMX_ErrorNone) { 00260 DEBUG(DEB_LEV_ERR, "Error on AllocateBuffer out 2 %i\n", err); 00261 exit(1); 00262 } 00263 00264 tsem_down(appPriv->eventSem); 00265 /* in Idle the second thread has bee created, and the second thread ID 00266 * should be available 00267 */ 00268 err = OMX_GetParameter(handle, custom_index, &threadsID); 00269 if(err != OMX_ErrorNone) { 00270 DEBUG(DEB_LEV_ERR, "OMX_GetParameter of extended index failed\n"); 00271 } else { 00272 DEBUG(DEFAULT_MESSAGES, "threadsID messages %i buffers %i\n", (int)threadsID.nThreadMessageID, (int)threadsID.nThreadBufferMngtID); 00273 } 00274 00275 err = OMX_SendCommand(handle, OMX_CommandStateSet, OMX_StateExecuting, NULL); 00276 00277 /* Wait for commands to complete */ 00278 tsem_down(appPriv->eventSem); 00279 00280 DEBUG(DEB_LEV_PARAMS, "Had buffers at:\n0x%p\n0x%p\n0x%p\n0x%p\n", 00281 inBuffer1->pBuffer, inBuffer2->pBuffer, outBuffer1->pBuffer, outBuffer2->pBuffer); 00282 DEBUG(DEB_LEV_PARAMS, "After switch to executing\n"); 00283 00284 data_read1 = read(fd, inBuffer1->pBuffer, BUFFER_IN_SIZE); 00285 inBuffer1->nFilledLen = data_read1; 00286 filesize -= data_read1; 00287 00288 data_read2 = read(fd, inBuffer2->pBuffer, BUFFER_IN_SIZE); 00289 inBuffer2->nFilledLen = data_read2; 00290 filesize -= data_read2; 00291 00292 DEBUG(DEB_LEV_PARAMS, "Empty first buffer %p\n", inBuffer1); 00293 err = OMX_EmptyThisBuffer(handle, inBuffer1); 00294 DEBUG(DEB_LEV_PARAMS, "Empty second buffer %p\n", inBuffer2); 00295 err = OMX_EmptyThisBuffer(handle, inBuffer2); 00296 00300 err = OMX_FillThisBuffer(handle, outBuffer1); 00301 err = OMX_FillThisBuffer(handle, outBuffer2); 00302 00303 tsem_down(appPriv->eofSem); 00304 00305 err = OMX_SendCommand(handle, OMX_CommandStateSet, OMX_StateIdle, NULL); 00306 /* Wait for commands to complete */ 00307 tsem_down(appPriv->eventSem); 00308 00309 err = OMX_SendCommand(handle, OMX_CommandStateSet, OMX_StateLoaded, NULL); 00310 err = OMX_FreeBuffer(handle, 0, inBuffer1); 00311 err = OMX_FreeBuffer(handle, 0, inBuffer2); 00312 err = OMX_FreeBuffer(handle, 1, outBuffer1); 00313 err = OMX_FreeBuffer(handle, 1, outBuffer2); 00314 00315 /* Wait for commands to complete */ 00316 tsem_down(appPriv->eventSem); 00317 00318 OMX_FreeHandle(handle); 00319 00320 free(appPriv->eventSem); 00321 free(appPriv); 00322 00323 if (flagOutputReceived) { 00324 if(fclose(outfile) != 0) { 00325 DEBUG(DEB_LEV_ERR,"Error in closing output file\n"); 00326 exit(1); 00327 } 00328 free(output_file); 00329 } 00330 00331 close(fd); 00332 free(input_file); 00333 00334 return 0; 00335 } 00336 00337 /* Callbacks implementation */ 00338 OMX_ERRORTYPE volcEventHandler( 00339 OMX_HANDLETYPE hComponent, 00340 OMX_PTR pAppData, 00341 OMX_EVENTTYPE eEvent, 00342 OMX_U32 Data1, 00343 OMX_U32 Data2, 00344 OMX_PTR pEventData) { 00345 00346 DEBUG(DEB_LEV_SIMPLE_SEQ, "Hi there, I am in the %s callback\n", __func__); 00347 if(eEvent == OMX_EventCmdComplete) { 00348 if (Data1 == OMX_CommandStateSet) { 00349 DEBUG(DEB_LEV_SIMPLE_SEQ, "Volume Component State changed in "); 00350 switch ((int)Data2) { 00351 case OMX_StateInvalid: 00352 DEBUG(DEB_LEV_SIMPLE_SEQ, "OMX_StateInvalid\n"); 00353 break; 00354 case OMX_StateLoaded: 00355 DEBUG(DEB_LEV_SIMPLE_SEQ, "OMX_StateLoaded\n"); 00356 break; 00357 case OMX_StateIdle: 00358 DEBUG(DEB_LEV_SIMPLE_SEQ, "OMX_StateIdle\n"); 00359 break; 00360 case OMX_StateExecuting: 00361 DEBUG(DEB_LEV_SIMPLE_SEQ, "OMX_StateExecuting\n"); 00362 break; 00363 case OMX_StatePause: 00364 DEBUG(DEB_LEV_SIMPLE_SEQ, "OMX_StatePause\n"); 00365 break; 00366 case OMX_StateWaitForResources: 00367 DEBUG(DEB_LEV_SIMPLE_SEQ, "OMX_StateWaitForResources\n"); 00368 break; 00369 } 00370 tsem_up(appPriv->eventSem); 00371 } else if (Data1 == OMX_CommandPortEnable){ 00372 tsem_up(appPriv->eventSem); 00373 } else if (Data1 == OMX_CommandPortDisable){ 00374 tsem_up(appPriv->eventSem); 00375 } 00376 } else if(eEvent == OMX_EventBufferFlag) { 00377 if((int)Data2 == OMX_BUFFERFLAG_EOS) { 00378 tsem_up(appPriv->eofSem); 00379 } 00380 } else { 00381 DEBUG(DEB_LEV_SIMPLE_SEQ, "Param1 is %i\n", (int)Data1); 00382 DEBUG(DEB_LEV_SIMPLE_SEQ, "Param2 is %i\n", (int)Data2); 00383 } 00384 00385 return OMX_ErrorNone; 00386 } 00387 00388 OMX_ERRORTYPE volcEmptyBufferDone( 00389 OMX_HANDLETYPE hComponent, 00390 OMX_PTR pAppData, 00391 OMX_BUFFERHEADERTYPE* pBuffer) { 00392 00393 int data_read; 00394 static int iBufferDropped=0; 00395 00396 DEBUG(DEB_LEV_FULL_SEQ, "Hi there, I am in the %s callback.\n", __func__); 00397 data_read = read(fd, pBuffer->pBuffer, BUFFER_IN_SIZE); 00398 pBuffer->nFilledLen = data_read; 00399 pBuffer->nOffset = 0; 00400 filesize -= data_read; 00401 if (data_read <= 0) { 00402 DEBUG(DEB_LEV_SIMPLE_SEQ, "In the %s no more input data available\n", __func__); 00403 iBufferDropped++; 00404 if(iBufferDropped>=2) { 00405 tsem_up(appPriv->eofSem); 00406 return OMX_ErrorNone; 00407 } 00408 pBuffer->nFilledLen=0; 00409 pBuffer->nFlags = OMX_BUFFERFLAG_EOS; 00410 bEOS=OMX_TRUE; 00411 err = OMX_EmptyThisBuffer(hComponent, pBuffer); 00412 return OMX_ErrorNone; 00413 } 00414 if(!bEOS) { 00415 DEBUG(DEB_LEV_FULL_SEQ, "Empty buffer %p\n", pBuffer); 00416 err = OMX_EmptyThisBuffer(hComponent, pBuffer); 00417 }else { 00418 DEBUG(DEB_LEV_FULL_SEQ, "In %s Dropping Empty This buffer to Audio Dec\n", __func__); 00419 } 00420 00421 return OMX_ErrorNone; 00422 } 00423 00424 OMX_ERRORTYPE volcFillBufferDone( 00425 OMX_HANDLETYPE hComponent, 00426 OMX_PTR pAppData, 00427 OMX_BUFFERHEADERTYPE* pBuffer) { 00428 00429 OMX_ERRORTYPE err; 00430 int i; 00431 00432 DEBUG(DEB_LEV_FULL_SEQ, "Hi there, I am in the %s callback. Got buflen %i for buffer at 0x%p\n", 00433 __func__, (int)pBuffer->nFilledLen, pBuffer); 00434 00435 /* Output data to standard output */ 00436 if(pBuffer != NULL) { 00437 if (pBuffer->nFilledLen == 0) { 00438 DEBUG(DEB_LEV_ERR, "Ouch! In %s: no data in the output buffer!\n", __func__); 00439 return OMX_ErrorNone; 00440 } 00441 if (flagOutputReceived) { 00442 if(pBuffer->nFilledLen > 0) { 00443 fwrite(pBuffer->pBuffer, 1, pBuffer->nFilledLen, outfile); 00444 } 00445 } else { 00446 for(i=0;i<pBuffer->nFilledLen;i++) { 00447 putchar(*(char*)(pBuffer->pBuffer + i)); 00448 } 00449 } 00450 pBuffer->nFilledLen = 0; 00451 } else { 00452 DEBUG(DEB_LEV_ERR, "Ouch! In %s: had NULL buffer to output...\n", __func__); 00453 } 00454 /* Reschedule the fill buffer request */ 00455 if(!bEOS) { 00456 err = OMX_FillThisBuffer(hComponent, pBuffer); 00457 } 00458 return OMX_ErrorNone; 00459 } 00460 00465 static int getFileSize(int fd) { 00466 00467 struct stat input_file_stat; 00468 int err; 00469 00470 /* Obtain input file length */ 00471 err = fstat(fd, &input_file_stat); 00472 if(err){ 00473 DEBUG(DEB_LEV_ERR, "fstat failed"); 00474 exit(-1); 00475 } 00476 return input_file_stat.st_size; 00477 }