00001
00030 #include "omxvolcontroltest.h"
00031
00032
00033 appPrivateType* appPriv;
00034 int fd = 0;
00035 unsigned int filesize;
00036 OMX_ERRORTYPE err;
00037 OMX_HANDLETYPE handle;
00038
00039 OMX_CALLBACKTYPE callbacks = { .EventHandler = volcEventHandler,
00040 .EmptyBufferDone = volcEmptyBufferDone,
00041 .FillBufferDone = volcFillBufferDone,
00042 };
00043
00044 static void setHeader(OMX_PTR header, OMX_U32 size) {
00045 OMX_VERSIONTYPE* ver = (OMX_VERSIONTYPE*)(header + sizeof(OMX_U32));
00046 *((OMX_U32*)header) = size;
00047
00048 ver->s.nVersionMajor = VERSIONMAJOR;
00049 ver->s.nVersionMinor = VERSIONMINOR;
00050 ver->s.nRevision = VERSIONREVISION;
00051 ver->s.nStep = VERSIONSTEP;
00052 }
00053
00054 void display_help() {
00055 printf("\n");
00056 printf("Usage: omxvolcontroltest [-o outfile] [-g gain] filename\n");
00057 printf("\n");
00058 printf(" -o outfile: If this option is specified, the output stream is written to outfile\n");
00059 printf(" otherwise redirected to std output\n");
00060 printf(" -g: Gain of PCM data [0...100]\n");
00061 printf(" -h: Displays this help\n");
00062 printf("\n");
00063 exit(1);
00064 }
00065
00066 int flagIsOutputExpected;
00067 int flagOutputReceived;
00068 int flagInputReceived;
00069 int flagIsGain;
00070 char *input_file, *output_file;
00071 static OMX_BOOL bEOS=OMX_FALSE;
00072 FILE *outfile;
00073
00074 int main(int argc, char** argv) {
00075
00076 OMX_PORT_PARAM_TYPE param;
00077 OMX_BUFFERHEADERTYPE *inBuffer1, *inBuffer2, *outBuffer1, *outBuffer2;
00078 int data_read1;
00079 int data_read2;
00080 OMX_PARAM_PORTDEFINITIONTYPE sPortDef;
00081 OMX_AUDIO_CONFIG_VOLUMETYPE sVolume;
00082 int gain=100;
00083 int argn_dec;
00084
00085
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
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 , &callbacks);
00177 if(err != OMX_ErrorNone) {
00178 DEBUG(DEB_LEV_ERR, "OMX_GetHandle failed\n");
00179 exit(1);
00180 }
00181
00182 if((gain >= 0) && (gain <100)) {
00183 err = OMX_GetConfig(handle, OMX_IndexConfigAudioVolume, &sVolume);
00184 if(err!=OMX_ErrorNone) {
00185 DEBUG(DEB_LEV_ERR,"Error %08x In OMX_GetConfig 0 \n",err);
00186 }
00187 sVolume.sVolume.nValue = gain;
00188 DEBUG(DEFAULT_MESSAGES, "Setting Gain %d \n", gain);
00189 err = OMX_SetConfig(handle, OMX_IndexConfigAudioVolume, &sVolume);
00190 if(err!=OMX_ErrorNone) {
00191 DEBUG(DEB_LEV_ERR,"Error %08x In OMX_SetConfig 0 \n",err);
00192 }
00193 }
00194
00196 param.nPorts = 2;
00197 setHeader(¶m, sizeof(OMX_PORT_PARAM_TYPE));
00198 err = OMX_GetParameter(handle, OMX_IndexParamAudioInit, ¶m);
00199 if(err != OMX_ErrorNone){
00200 DEBUG(DEB_LEV_ERR, "Error in getting OMX_PORT_PARAM_TYPE parameter\n");
00201 exit(1);
00202 }
00203
00204 setHeader(&sPortDef, sizeof(OMX_PARAM_PORTDEFINITIONTYPE));
00205 sPortDef.nPortIndex = 0;
00206 err = OMX_GetParameter(handle, OMX_IndexParamPortDefinition, &sPortDef);
00207
00208 sPortDef.nBufferCountActual = 2;
00209 err = OMX_SetParameter(handle, OMX_IndexParamPortDefinition, &sPortDef);
00210 if(err != OMX_ErrorNone){
00211 DEBUG(DEB_LEV_ERR, "Error in getting OMX_PORT_PARAM_TYPE parameter\n");
00212 exit(1);
00213 }
00214 sPortDef.nPortIndex = 1;
00215 err = OMX_GetParameter(handle, OMX_IndexParamPortDefinition, &sPortDef);
00216
00217 sPortDef.nBufferCountActual = 2;
00218 err = OMX_SetParameter(handle, OMX_IndexParamPortDefinition, &sPortDef);
00219 if(err != OMX_ErrorNone){
00220 DEBUG(DEB_LEV_ERR, "Error in getting OMX_PORT_PARAM_TYPE parameter\n");
00221 exit(1);
00222 }
00223
00224 err = OMX_SendCommand(handle, OMX_CommandStateSet, OMX_StateIdle, NULL);
00225
00226 inBuffer1 = inBuffer2 = outBuffer1 = outBuffer2 = NULL;
00227 err = OMX_AllocateBuffer(handle, &inBuffer1, 0, NULL, BUFFER_IN_SIZE);
00228 if (err != OMX_ErrorNone) {
00229 DEBUG(DEB_LEV_ERR, "Error on AllocateBuffer in 1%i\n", err);
00230 exit(1);
00231 }
00232 err = OMX_AllocateBuffer(handle, &inBuffer2, 0, NULL, BUFFER_IN_SIZE);
00233 if (err != OMX_ErrorNone) {
00234 DEBUG(DEB_LEV_ERR, "Error on AllocateBuffer in 2 %i\n", err);
00235 exit(1);
00236 }
00237 err = OMX_AllocateBuffer(handle, &outBuffer1, 1, NULL, BUFFER_IN_SIZE);
00238 if (err != OMX_ErrorNone) {
00239 DEBUG(DEB_LEV_ERR, "Error on AllocateBuffer out 1 %i\n", err);
00240 exit(1);
00241 }
00242 err = OMX_AllocateBuffer(handle, &outBuffer2, 1, NULL, BUFFER_IN_SIZE);
00243 if (err != OMX_ErrorNone) {
00244 DEBUG(DEB_LEV_ERR, "Error on AllocateBuffer out 2 %i\n", err);
00245 exit(1);
00246 }
00247
00248 tsem_down(appPriv->eventSem);
00249 err = OMX_SendCommand(handle, OMX_CommandStateSet, OMX_StateExecuting, NULL);
00250
00251
00252 tsem_down(appPriv->eventSem);
00253
00254 DEBUG(DEB_LEV_PARAMS, "Had buffers at:\n0x%08x\n0x%08x\n0x%08x\n0x%08x\n",
00255 (int)inBuffer1->pBuffer, (int)inBuffer2->pBuffer, (int)outBuffer1->pBuffer, (int)outBuffer2->pBuffer);
00256 DEBUG(DEB_LEV_PARAMS, "After switch to executing\n");
00257
00258 data_read1 = read(fd, inBuffer1->pBuffer, BUFFER_IN_SIZE);
00259 inBuffer1->nFilledLen = data_read1;
00260 filesize -= data_read1;
00261
00262 data_read2 = read(fd, inBuffer2->pBuffer, BUFFER_IN_SIZE);
00263 inBuffer2->nFilledLen = data_read2;
00264 filesize -= data_read2;
00265
00266 DEBUG(DEB_LEV_PARAMS, "Empty first buffer %x\n", (int)inBuffer1);
00267 err = OMX_EmptyThisBuffer(handle, inBuffer1);
00268 DEBUG(DEB_LEV_PARAMS, "Empty second buffer %x\n", (int)inBuffer2);
00269 err = OMX_EmptyThisBuffer(handle, inBuffer2);
00270
00274 err = OMX_FillThisBuffer(handle, outBuffer1);
00275 err = OMX_FillThisBuffer(handle, outBuffer2);
00276
00277 tsem_down(appPriv->eofSem);
00278
00279 err = OMX_SendCommand(handle, OMX_CommandStateSet, OMX_StateIdle, NULL);
00280
00281 tsem_down(appPriv->eventSem);
00282
00283 err = OMX_SendCommand(handle, OMX_CommandStateSet, OMX_StateLoaded, NULL);
00284 err = OMX_FreeBuffer(handle, 0, inBuffer1);
00285 err = OMX_FreeBuffer(handle, 0, inBuffer2);
00286 err = OMX_FreeBuffer(handle, 1, outBuffer1);
00287 err = OMX_FreeBuffer(handle, 1, outBuffer2);
00288
00289
00290 tsem_down(appPriv->eventSem);
00291
00292 OMX_FreeHandle(handle);
00293
00294 free(appPriv->eventSem);
00295 free(appPriv);
00296
00297 if (flagOutputReceived) {
00298 if(fclose(outfile) != 0) {
00299 DEBUG(DEB_LEV_ERR,"Error in closing output file\n");
00300 exit(1);
00301 }
00302 free(output_file);
00303 }
00304
00305 close(fd);
00306 free(input_file);
00307
00308 return 0;
00309 }
00310
00311
00312 OMX_ERRORTYPE volcEventHandler(
00313 OMX_OUT OMX_HANDLETYPE hComponent,
00314 OMX_OUT OMX_PTR pAppData,
00315 OMX_OUT OMX_EVENTTYPE eEvent,
00316 OMX_OUT OMX_U32 Data1,
00317 OMX_OUT OMX_U32 Data2,
00318 OMX_IN OMX_PTR pEventData) {
00319
00320 DEBUG(DEB_LEV_SIMPLE_SEQ, "Hi there, I am in the %s callback\n", __func__);
00321 if(eEvent == OMX_EventCmdComplete) {
00322 if (Data1 == OMX_CommandStateSet) {
00323 DEBUG(DEB_LEV_SIMPLE_SEQ, "Volume Component State changed in ");
00324 switch ((int)Data2) {
00325 case OMX_StateInvalid:
00326 DEBUG(DEB_LEV_SIMPLE_SEQ, "OMX_StateInvalid\n");
00327 break;
00328 case OMX_StateLoaded:
00329 DEBUG(DEB_LEV_SIMPLE_SEQ, "OMX_StateLoaded\n");
00330 break;
00331 case OMX_StateIdle:
00332 DEBUG(DEB_LEV_SIMPLE_SEQ, "OMX_StateIdle\n");
00333 break;
00334 case OMX_StateExecuting:
00335 DEBUG(DEB_LEV_SIMPLE_SEQ, "OMX_StateExecuting\n");
00336 break;
00337 case OMX_StatePause:
00338 DEBUG(DEB_LEV_SIMPLE_SEQ, "OMX_StatePause\n");
00339 break;
00340 case OMX_StateWaitForResources:
00341 DEBUG(DEB_LEV_SIMPLE_SEQ, "OMX_StateWaitForResources\n");
00342 break;
00343 }
00344 tsem_up(appPriv->eventSem);
00345 } else if (Data1 == OMX_CommandPortEnable){
00346 tsem_up(appPriv->eventSem);
00347 } else if (Data1 == OMX_CommandPortDisable){
00348 tsem_up(appPriv->eventSem);
00349 }
00350 } else if(eEvent == OMX_EventBufferFlag) {
00351 if((int)Data2 == OMX_BUFFERFLAG_EOS) {
00352 tsem_up(appPriv->eofSem);
00353 }
00354 } else {
00355 DEBUG(DEB_LEV_SIMPLE_SEQ, "Param1 is %i\n", (int)Data1);
00356 DEBUG(DEB_LEV_SIMPLE_SEQ, "Param2 is %i\n", (int)Data2);
00357 }
00358
00359 return OMX_ErrorNone;
00360 }
00361
00362 OMX_ERRORTYPE volcEmptyBufferDone(
00363 OMX_OUT OMX_HANDLETYPE hComponent,
00364 OMX_OUT OMX_PTR pAppData,
00365 OMX_OUT OMX_BUFFERHEADERTYPE* pBuffer) {
00366
00367 int data_read;
00368 static int iBufferDropped=0;
00369
00370 DEBUG(DEB_LEV_FULL_SEQ, "Hi there, I am in the %s callback.\n", __func__);
00371 data_read = read(fd, pBuffer->pBuffer, BUFFER_IN_SIZE);
00372 pBuffer->nFilledLen = data_read;
00373 pBuffer->nOffset = 0;
00374 filesize -= data_read;
00375 if (data_read <= 0) {
00376 DEBUG(DEB_LEV_SIMPLE_SEQ, "In the %s no more input data available\n", __func__);
00377 iBufferDropped++;
00378 if(iBufferDropped>=2) {
00379 tsem_up(appPriv->eofSem);
00380 return OMX_ErrorNone;
00381 }
00382 pBuffer->nFilledLen=0;
00383 pBuffer->nFlags = OMX_BUFFERFLAG_EOS;
00384 bEOS=OMX_TRUE;
00385 err = OMX_EmptyThisBuffer(hComponent, pBuffer);
00386 return OMX_ErrorNone;
00387 }
00388 if(!bEOS) {
00389 DEBUG(DEB_LEV_FULL_SEQ, "Empty buffer %x\n", (int)pBuffer);
00390 err = OMX_EmptyThisBuffer(hComponent, pBuffer);
00391 }else {
00392 DEBUG(DEB_LEV_FULL_SEQ, "In %s Dropping Empty This buffer to Audio Dec\n", __func__);
00393 }
00394
00395 return OMX_ErrorNone;
00396 }
00397
00398 OMX_ERRORTYPE volcFillBufferDone(
00399 OMX_OUT OMX_HANDLETYPE hComponent,
00400 OMX_OUT OMX_PTR pAppData,
00401 OMX_OUT OMX_BUFFERHEADERTYPE* pBuffer) {
00402
00403 OMX_ERRORTYPE err;
00404 int i;
00405
00406 DEBUG(DEB_LEV_FULL_SEQ, "Hi there, I am in the %s callback. Got buflen %i for buffer at 0x%08x\n",
00407 __func__, (int)pBuffer->nFilledLen, (int)pBuffer);
00408
00409
00410 if(pBuffer != NULL) {
00411 if (pBuffer->nFilledLen == 0) {
00412 DEBUG(DEB_LEV_ERR, "Ouch! In %s: no data in the output buffer!\n", __func__);
00413 return OMX_ErrorNone;
00414 }
00415 if (flagOutputReceived) {
00416 if(pBuffer->nFilledLen > 0) {
00417 fwrite(pBuffer->pBuffer, 1, pBuffer->nFilledLen, outfile);
00418 }
00419 } else {
00420 for(i=0;i<pBuffer->nFilledLen;i++) {
00421 putchar(*(char*)(pBuffer->pBuffer + i));
00422 }
00423 }
00424 pBuffer->nFilledLen = 0;
00425 } else {
00426 DEBUG(DEB_LEV_ERR, "Ouch! In %s: had NULL buffer to output...\n", __func__);
00427 }
00428
00429 if(!bEOS) {
00430 err = OMX_FillThisBuffer(hComponent, pBuffer);
00431 }
00432 return OMX_ErrorNone;
00433 }
00434
00439 static int getFileSize(int fd) {
00440
00441 struct stat input_file_stat;
00442 int err;
00443
00444
00445 err = fstat(fd, &input_file_stat);
00446 if(err){
00447 DEBUG(DEB_LEV_ERR, "fstat failed");
00448 exit(-1);
00449 }
00450 return input_file_stat.st_size;
00451 }