00001
00031 #include "omxvideodectest.h"
00032
00034 #define MPEG4_TYPE_SEL 1
00035 #define AVC_TYPE_SEL 2
00036 #define COMPONENT_NAME_BASE "OMX.st.video_decoder"
00037 #define BASE_ROLE "video_decoder.avc"
00038 #define COMPONENT_NAME_BASE_LEN 20
00039
00041 OMX_COLOR_FORMATTYPE COLOR_CONV_OUT_RGB_FORMAT = OMX_COLOR_Format24bitRGB888;
00042
00043 appPrivateType* appPriv;
00044
00046 OMX_BUFFERHEADERTYPE *pInBuffer1, *pInBuffer2, *pOutBuffer1, *pOutBuffer2;
00048 OMX_BUFFERHEADERTYPE *pInBufferColorConv1, *pInBufferColorConv2,*pOutBufferColorConv1, *pOutBufferColorConv2;
00049 OMX_BUFFERHEADERTYPE *pInBufferSink1, *pInBufferSink2;
00050
00051 int buffer_in_size = BUFFER_IN_SIZE;
00052 OMX_U32 buffer_out_size;
00053 OMX_U32 outbuf_colorconv_size;
00054
00055 OMX_PARAM_PORTDEFINITIONTYPE paramPort;
00056 OMX_PARAM_PORTDEFINITIONTYPE omx_colorconvPortDefinition;
00057 OMX_PARAM_COMPONENTROLETYPE paramRole;
00058 OMX_VIDEO_PARAM_PORTFORMATTYPE omxVideoParam;
00059
00060 OMX_CALLBACKTYPE videodeccallbacks = {
00061 .EventHandler = videodecEventHandler,
00062 .EmptyBufferDone = videodecEmptyBufferDone,
00063 .FillBufferDone = videodecFillBufferDone
00064 };
00065
00066 OMX_CALLBACKTYPE colorconv_callbacks = {
00067 .EventHandler = colorconvEventHandler,
00068 .EmptyBufferDone = colorconvEmptyBufferDone,
00069 .FillBufferDone = colorconvFillBufferDone
00070 };
00071
00072 OMX_CALLBACKTYPE fbdev_sink_callbacks = {
00073 .EventHandler = fb_sinkEventHandler,
00074 .EmptyBufferDone = fb_sinkEmptyBufferDone,
00075 .FillBufferDone = NULL
00076 };
00077
00078
00079 OMX_U32 out_width = 0, new_out_width = 0;
00080 OMX_U32 out_height = 0, new_out_height = 0;
00081
00082 FILE *fd,*outfile;
00083 char *input_file, *output_file;
00084 int selectedType = 0;
00085
00086 int flagIsOutputEspected;
00087 int flagDecodedOutputReceived;
00088 int flagInputReceived;
00089 int flagIsColorConvRequested;
00090 int flagIsSinkRequested;
00091 int flagIsFormatRequested;
00092 int flagSetupTunnel;
00093
00094 static OMX_BOOL bEOS = OMX_FALSE;
00095
00096 static void setHeader(OMX_PTR header, OMX_U32 size) {
00097 OMX_VERSIONTYPE* ver = (OMX_VERSIONTYPE*)(header + sizeof(OMX_U32));
00098 *((OMX_U32*)header) = size;
00099
00100 ver->s.nVersionMajor = VERSIONMAJOR;
00101 ver->s.nVersionMinor = VERSIONMINOR;
00102 ver->s.nRevision = VERSIONREVISION;
00103 ver->s.nStep = VERSIONSTEP;
00104 }
00105
00106
00110 int setPortParameters() {
00111 OMX_ERRORTYPE err = OMX_ErrorNone;
00112
00113 paramPort.nPortIndex = 1;
00114 setHeader(¶mPort, sizeof(OMX_PARAM_PORTDEFINITIONTYPE));
00115 err = OMX_GetParameter(appPriv->videodechandle, OMX_IndexParamPortDefinition, ¶mPort);
00116 new_out_width = paramPort.format.video.nFrameWidth;
00117 new_out_height = paramPort.format.video.nFrameHeight;
00118 DEBUG(DEB_LEV_SIMPLE_SEQ, "input picture width : %d height : %d \n", (int)new_out_width, (int)new_out_height);
00119
00123 if(flagIsColorConvRequested == 1) {
00127 omx_colorconvPortDefinition.nPortIndex = 0;
00128 setHeader(&omx_colorconvPortDefinition, sizeof(OMX_PARAM_PORTDEFINITIONTYPE));
00129 err = OMX_GetParameter(appPriv->colorconv_handle, OMX_IndexParamPortDefinition, &omx_colorconvPortDefinition);
00130 omx_colorconvPortDefinition.format.video.nFrameWidth = new_out_width;
00131 omx_colorconvPortDefinition.format.video.nFrameHeight = new_out_height;
00132 err = OMX_SetParameter(appPriv->colorconv_handle, OMX_IndexParamPortDefinition, &omx_colorconvPortDefinition);
00133 if(err!=OMX_ErrorNone) {
00134 DEBUG(DEB_LEV_ERR, "In %s Setting Input Port Definition Error=%x\n",__func__,err);
00135 return err;
00136 }
00140 omx_colorconvPortDefinition.nPortIndex = 1;
00141 err = OMX_GetParameter(appPriv->colorconv_handle, OMX_IndexParamPortDefinition, &omx_colorconvPortDefinition);
00142 omx_colorconvPortDefinition.format.video.nFrameWidth = new_out_width;
00143 omx_colorconvPortDefinition.format.video.nFrameHeight = new_out_height;
00144 err = OMX_SetParameter(appPriv->colorconv_handle, OMX_IndexParamPortDefinition, &omx_colorconvPortDefinition);
00145 if(err!=OMX_ErrorNone) {
00146 DEBUG(DEB_LEV_ERR, "In %s Setting Output Port Definition Error=%x\n",__func__,err);
00147 return err;
00148 }
00152 paramPort.nPortIndex = 1;
00153 setHeader(¶mPort, sizeof(OMX_PARAM_PORTDEFINITIONTYPE));
00154 err = OMX_GetParameter(appPriv->videodechandle, OMX_IndexParamPortDefinition, ¶mPort);
00155 omxVideoParam.nPortIndex = 0;
00156 setHeader(&omxVideoParam, sizeof(OMX_VIDEO_PARAM_PORTFORMATTYPE));
00157 err = OMX_GetParameter(appPriv->colorconv_handle, OMX_IndexParamVideoPortFormat, &omxVideoParam);
00158 omxVideoParam.eColorFormat = paramPort.format.video.eColorFormat;
00159 err = OMX_SetParameter(appPriv->colorconv_handle, OMX_IndexParamVideoPortFormat, &omxVideoParam);
00160 if(err==OMX_ErrorBadParameter) {
00161 DEBUG(DEB_LEV_ERR,"\n bad parameter of input color format - exiting\n");
00162 exit(1);
00163 }
00165 omxVideoParam.nPortIndex = 1;
00166 err = OMX_GetParameter(appPriv->colorconv_handle, OMX_IndexParamVideoPortFormat, &omxVideoParam);
00167 omxVideoParam.eColorFormat = COLOR_CONV_OUT_RGB_FORMAT;
00168 err = OMX_SetParameter(appPriv->colorconv_handle, OMX_IndexParamVideoPortFormat, &omxVideoParam);
00169 if(err==OMX_ErrorBadParameter) {
00170 DEBUG(DEB_LEV_ERR,"\n bad parameter of output color format setting- exiting\n");
00171 exit(1);
00172 }
00176 if(flagIsSinkRequested == 1) {
00177 omx_colorconvPortDefinition.nPortIndex = 1;
00178 err = OMX_GetParameter(appPriv->colorconv_handle, OMX_IndexParamPortDefinition, &omx_colorconvPortDefinition);
00179 omx_colorconvPortDefinition.nPortIndex = 0;
00180 err = OMX_SetParameter(appPriv->fbdev_sink_handle, OMX_IndexParamPortDefinition, &omx_colorconvPortDefinition);
00181 if(err != OMX_ErrorNone) {
00182 DEBUG(DEB_LEV_ERR,"\n error in setting the inputport param of the sink component- exiting\n");
00183 exit(1);
00184 }
00185 omxVideoParam.nPortIndex = 1;
00186 err = OMX_GetParameter(appPriv->colorconv_handle, OMX_IndexParamVideoPortFormat, &omxVideoParam);
00187 omxVideoParam.nPortIndex = 0;
00188 err = OMX_SetParameter(appPriv->fbdev_sink_handle, OMX_IndexParamVideoPortFormat, &omxVideoParam);
00189 if(err != OMX_ErrorNone) {
00190 DEBUG(DEB_LEV_ERR,"\n error in setting the input video param of the sink component- exiting\n");
00191 exit(1);
00192 }
00193 }
00194 }
00195
00196 return err;
00197 }
00198
00200 int find_resolution(char* searchname) {
00201 char filename_lower[255];
00202 char* ptr = filename_lower;
00203
00204 strcpy(filename_lower, searchname);
00205 while (*ptr != '\0' && ptr - filename_lower < 255) {
00206 *ptr = tolower(*ptr);
00207 ++ptr;
00208 }
00209 if (strstr(filename_lower, "qcif") != NULL) {
00210 out_width = 176;
00211 out_height = 144;
00212 return 1;
00213 } else if (strstr(filename_lower, "qvga") != NULL) {
00214 out_width = 320;
00215 out_height = 240;
00216 return 2;
00217 } else if (strstr(filename_lower, "cif") != NULL) {
00218 out_width = 352;
00219 out_height = 288;
00220 return 3;
00221 } else if (strstr(filename_lower, "vga") != NULL) {
00222 out_width = 640;
00223 out_height = 480;
00224 return 4;
00225 }
00226 return 0;
00227 }
00228
00230 void display_help() {
00231 printf("\n");
00232 printf("Usage: omxvideodectest -o outfile [-t] [-c] [-h] [-f input_fmt] [-s] input_filename\n");
00233 printf("\n");
00234 printf(" -o outfile: If this option is specified, the output is written to user specified outfile\n");
00235 printf(" Else, the output is written in the same directory of input file\n");
00236 printf(" the file name looks like input_filename_app.yuv/rgb depending on input option\n");
00237 printf(" If the color conv option (-c) is specified then outfile will be .rgb file\n");
00238 printf(" Else outfile will be in .yuv format \n");
00239 printf(" N.B : This option is not needed if you use the sink component\n");
00240 printf("\n");
00241 printf(" -c : Color conv option - input file is decoded and color converted in outfile(.rgb file)\n");
00242 printf(" -h: Displays this help\n");
00243 printf("\n");
00244 printf(" -f : input format specification in case of color conv comp usage \n");
00245 printf(" The available input formats are - \n");
00246 printf(" - OMX_COLOR_Format24bitRGB888 (default format) \n");
00247 printf(" - OMX_COLOR_Format24bitBGR888 \n");
00248 printf(" - OMX_COLOR_Format32bitBGRA8888 \n");
00249 printf(" - OMX_COLOR_Format32bitARGB8888 \n");
00250 printf(" - OMX_COLOR_Format16bitARGB1555 \n");
00251 printf(" - OMX_COLOR_Format16bitRGB565 \n");
00252 printf(" - OMX_COLOR_Format16bitBGR565 \n");
00253 printf("\n");
00254 printf(" -s: Uses the video sink component to display the output of the color converter(.rgb file)\n");
00255 printf(" input_filename is the user specified input file name\n");
00256 printf("\n");
00257 printf(" -t: Tunneling option - if this option is selected then by default the color converter and \n");
00258 printf(" video sink components are selected even if those two options are not specified - \n");
00259 printf(" the components are tunneled between themselves\n");
00260 printf("\n");
00261 exit(1);
00262 }
00263
00264
00265 OMX_ERRORTYPE test_OMX_ComponentNameEnum() {
00266 char * name;
00267 int index;
00268
00269 OMX_ERRORTYPE err = OMX_ErrorNone;
00270
00271 DEBUG(DEFAULT_MESSAGES, "GENERAL TEST %s\n", __func__);
00272 name = malloc(OMX_MAX_STRINGNAME_SIZE);
00273 index = 0;
00274 while(1) {
00275 err = OMX_ComponentNameEnum (name, OMX_MAX_STRINGNAME_SIZE, index);
00276 if ((name != NULL) && (err == OMX_ErrorNone)) {
00277 DEBUG(DEFAULT_MESSAGES, "component %i is %s\n", index, name);
00278 } else break;
00279 if (err != OMX_ErrorNone) break;
00280 index++;
00281 }
00282 free(name);
00283 name = NULL;
00284 DEBUG(DEFAULT_MESSAGES, "GENERAL TEST %s result %i\n", __func__, err);
00285 return err;
00286 }
00287
00288 OMX_ERRORTYPE test_OMX_RoleEnum(OMX_STRING component_name) {
00289 OMX_U32 no_of_roles;
00290 OMX_U8 **string_of_roles;
00291 OMX_ERRORTYPE err = OMX_ErrorNone;
00292 int index;
00293
00294 DEBUG(DEFAULT_MESSAGES, "GENERAL TEST %s\n", __func__);
00295 DEBUG(DEB_LEV_SIMPLE_SEQ, "Getting roles of %s. Passing Null first...\n", component_name);
00296 err = OMX_GetRolesOfComponent(component_name, &no_of_roles, NULL);
00297 if (err != OMX_ErrorNone) {
00298 DEBUG(DEB_LEV_ERR, "Not able to retrieve the number of roles of the given component\n");
00299 DEBUG(DEFAULT_MESSAGES, "GENERAL TEST %s result %i\n", __func__, err);
00300 return err;
00301 }
00302 DEBUG(DEFAULT_MESSAGES, "The number of roles for the component %s is: %i\n", component_name, (int)no_of_roles);
00303
00304 if(no_of_roles == 0) {
00305 DEBUG(DEB_LEV_ERR, "The Number or roles is 0.\nThe component selected is not correct for the purpose of this test.\nExiting...\n");
00306 err = OMX_ErrorInvalidComponentName;
00307 } else {
00308 string_of_roles = malloc(no_of_roles * sizeof(OMX_STRING));
00309 for (index = 0; index < no_of_roles; index++) {
00310 *(string_of_roles + index) = malloc(no_of_roles * OMX_MAX_STRINGNAME_SIZE);
00311 }
00312 DEBUG(DEB_LEV_SIMPLE_SEQ, "...then buffers\n");
00313
00314 err = OMX_GetRolesOfComponent(component_name, &no_of_roles, string_of_roles);
00315 if (err != OMX_ErrorNone) {
00316 DEBUG(DEB_LEV_ERR, "Not able to retrieve the roles of the given component\n");
00317 } else if(string_of_roles != NULL) {
00318 for (index = 0; index < no_of_roles; index++) {
00319 DEBUG(DEFAULT_MESSAGES, "The role %i for the component: %s \n", (index + 1), *(string_of_roles+index));
00320 }
00321 } else {
00322 DEBUG(DEB_LEV_ERR, "role string is NULL!!! Exiting...\n");
00323 err = OMX_ErrorInvalidComponentName;
00324 }
00325 }
00326 DEBUG(DEFAULT_MESSAGES, "GENERAL TEST %s result %i\n", __func__, err);
00327 return err;
00328 }
00329
00330 OMX_ERRORTYPE test_OMX_ComponentEnumByRole(OMX_STRING role_name) {
00331 OMX_U32 no_of_comp_per_role;
00332 OMX_U8 **string_of_comp_per_role;
00333 OMX_ERRORTYPE err;
00334 int index;
00335
00336 DEBUG(DEFAULT_MESSAGES, "GENERAL TEST %s\n", __func__);
00337 string_of_comp_per_role = malloc (10 * sizeof(OMX_STRING));
00338 for (index = 0; index < 10; index++) {
00339 string_of_comp_per_role[index] = malloc(OMX_MAX_STRINGNAME_SIZE);
00340 }
00341
00342 DEBUG(DEFAULT_MESSAGES, "Getting number of components per role for %s\n", role_name);
00343
00344 err = OMX_GetComponentsOfRole(role_name, &no_of_comp_per_role, NULL);
00345 if (err != OMX_ErrorNone) {
00346 DEBUG(DEB_LEV_ERR, "Not able to retrieve the number of components of a given role\n");
00347 DEBUG(DEFAULT_MESSAGES, "GENERAL TEST %s result %i\n", __func__, err);
00348 return err;
00349 }
00350 DEBUG(DEFAULT_MESSAGES, "Number of components per role for %s is %i\n", role_name, (int)no_of_comp_per_role);
00351
00352 err = OMX_GetComponentsOfRole(role_name, &no_of_comp_per_role, string_of_comp_per_role);
00353 if (err != OMX_ErrorNone) {
00354 DEBUG(DEB_LEV_ERR, "Not able to retrieve the components of a given role\n");
00355 DEBUG(DEFAULT_MESSAGES, "GENERAL TEST %s result %i\n",__func__, err);
00356 return err;
00357 }
00358
00359 DEBUG(DEFAULT_MESSAGES, " The components are:\n");
00360 for (index = 0; index < no_of_comp_per_role; index++) {
00361 DEBUG(DEFAULT_MESSAGES, "%s\n", string_of_comp_per_role[index]);
00362 }
00363 for (index = 0; index<10; index++) {
00364 if(string_of_comp_per_role[index]) {
00365 free(string_of_comp_per_role[index]);
00366 string_of_comp_per_role[index] = NULL;
00367 }
00368 }
00369
00370 if(string_of_comp_per_role) {
00371 free(string_of_comp_per_role);
00372 string_of_comp_per_role = NULL;
00373 }
00374 DEBUG(DEFAULT_MESSAGES, "GENERAL TEST %s result OMX_ErrorNone\n", __func__);
00375 return OMX_ErrorNone;
00376 }
00377
00378 OMX_ERRORTYPE test_OpenClose(OMX_STRING component_name) {
00379 OMX_ERRORTYPE err = OMX_ErrorNone;
00380
00381 DEBUG(DEFAULT_MESSAGES, "GENERAL TEST %s\n",__func__);
00382 err = OMX_GetHandle(&appPriv->videodechandle, component_name, NULL , &videodeccallbacks);
00383 if(err != OMX_ErrorNone) {
00384 DEBUG(DEB_LEV_ERR, "No component found\n");
00385 } else {
00386 err = OMX_FreeHandle(appPriv->videodechandle);
00387 }
00388 DEBUG(DEFAULT_MESSAGES, "GENERAL TEST %s result %i\n", __func__, err);
00389 return err;
00390 }
00391
00392
00393 int main(int argc, char** argv) {
00394
00395 OMX_ERRORTYPE err;
00396 int data_read;
00397 int argn_dec;
00398 OMX_STRING full_component_name;
00399
00400 if(argc < 2){
00401 display_help();
00402 } else {
00403 flagIsOutputEspected = 0;
00404 flagDecodedOutputReceived = 0;
00405 flagInputReceived = 0;
00406 flagIsColorConvRequested = 0;
00407 flagSetupTunnel = 0;
00408 flagIsSinkRequested = 0;
00409 flagIsFormatRequested = 0;
00410
00411 argn_dec = 1;
00412 while (argn_dec < argc) {
00413 if (*(argv[argn_dec]) == '-') {
00414 if (flagIsOutputEspected) {
00415 display_help();
00416 }
00417 switch (*(argv[argn_dec] + 1)) {
00418 case 'h' :
00419 display_help();
00420 break;
00421 case 't' :
00422 flagSetupTunnel = 1;
00423 flagIsSinkRequested = 1;
00424 flagIsColorConvRequested = 1;
00425 break;
00426 case 's':
00427 flagIsSinkRequested = 1;
00428 break;
00429 case 'o':
00430 flagIsOutputEspected = 1;
00431 break;
00432 case 'c':
00433 flagIsColorConvRequested = 1;
00434 break;
00435 case 'f' :
00436 flagIsFormatRequested = 1;
00437 break;
00438 default:
00439 display_help();
00440 }
00441 } else {
00442 if (flagIsOutputEspected) {
00443 if(strstr(argv[argn_dec], ".yuv") == NULL && strstr(argv[argn_dec], ".rgb") == NULL) {
00444 output_file = malloc(strlen(argv[argn_dec]) + 5);
00445 strcpy(output_file,argv[argn_dec]);
00446 strcat(output_file, ".yuv");
00447 } else {
00448 output_file = malloc(strlen(argv[argn_dec]) + 1);
00449 strcpy(output_file,argv[argn_dec]);
00450 }
00451 flagIsOutputEspected = 0;
00452 flagDecodedOutputReceived = 1;
00453 } else if(flagIsFormatRequested) {
00454 if(strstr(argv[argn_dec], "OMX_COLOR_Format24bitRGB888") != NULL) {
00455 COLOR_CONV_OUT_RGB_FORMAT = OMX_COLOR_Format24bitRGB888;
00456 } else if(strstr(argv[argn_dec], "OMX_COLOR_Format24bitBGR888") != NULL) {
00457 COLOR_CONV_OUT_RGB_FORMAT = OMX_COLOR_Format24bitBGR888;
00458 } else if(strstr(argv[argn_dec], "OMX_COLOR_Format32bitBGRA8888") != NULL) {
00459 COLOR_CONV_OUT_RGB_FORMAT = OMX_COLOR_Format32bitBGRA8888;
00460 } else if(strstr(argv[argn_dec], "OMX_COLOR_Format32bitARGB8888") != NULL) {
00461 COLOR_CONV_OUT_RGB_FORMAT = OMX_COLOR_Format32bitARGB8888;
00462 } else if(strstr(argv[argn_dec], "OMX_COLOR_Format16bitARGB1555") != NULL) {
00463 COLOR_CONV_OUT_RGB_FORMAT = OMX_COLOR_Format16bitARGB1555;
00464 } else if(strstr(argv[argn_dec], "OMX_COLOR_Format16bitRGB565") != NULL) {
00465 COLOR_CONV_OUT_RGB_FORMAT = OMX_COLOR_Format16bitRGB565;
00466 } else if(strstr(argv[argn_dec], "OMX_COLOR_Format16bitBGR565") != NULL) {
00467 COLOR_CONV_OUT_RGB_FORMAT = OMX_COLOR_Format16bitBGR565;
00468 } else {
00469 DEBUG(DEB_LEV_ERR, "\n specified color converter format is unknown - keeping default format\n");
00470 }
00471 flagIsFormatRequested = 0;
00472 } else {
00473 input_file = malloc(strlen(argv[argn_dec]) + 1);
00474 strcpy(input_file,argv[argn_dec]);
00475 flagInputReceived = 1;
00476 }
00477 }
00478 argn_dec++;
00479 }
00480
00482 if ((!flagInputReceived) || ((strstr(input_file, ".m4v") == NULL) && (strstr(input_file, ".264") == NULL))) {
00483 DEBUG(DEB_LEV_ERR, "\n you must specify appropriate input file of .m4v or .264 format\n");
00484 display_help();
00485 }
00486
00488
00489 if(!flagIsOutputEspected && !flagDecodedOutputReceived) {
00490 if(flagIsColorConvRequested) {
00491 if(!flagIsSinkRequested) {
00492 DEBUG(DEB_LEV_ERR,"\n you did not enter any output file name and entered color converter option");
00493 output_file = malloc( (strlen(input_file) - strlen(strstr(input_file,".")) + 8) + 1);
00494 strncpy(output_file,input_file, (strlen(input_file) - strlen(strstr(input_file,"."))) );
00495 strcat(output_file,"_app.rgb");
00496 DEBUG(DEB_LEV_ERR,"\n the output file name will be %s ", output_file);
00497 }
00498 } else {
00499 DEBUG(DEB_LEV_ERR,"\n you did not enter any output file name");
00500 output_file = malloc( (strlen(input_file) - strlen(strstr(input_file,".")) + 8) + 1);
00501 strncpy(output_file,input_file, (strlen(input_file) - strlen(strstr(input_file,"."))) );
00502 strcat(output_file,"_app.yuv");
00503 DEBUG(DEB_LEV_ERR,"\n the decoded output file name will be %s ", output_file);
00504 }
00505 } else if(flagDecodedOutputReceived) {
00506 if(flagIsSinkRequested || flagSetupTunnel) {
00507 flagDecodedOutputReceived = 0;
00508 DEBUG(DEB_LEV_ERR, "Sink Requested or Components are tunneled. No FILE Output will be produced\n");
00509 } else {
00510
00511 if(flagIsColorConvRequested && strstr(output_file, ".rgb") == NULL) {
00512 output_file[strlen(output_file) - strlen(strstr(output_file, "."))] = '\0';
00513 strcat(output_file, ".rgb");
00514 DEBUG(DEB_LEV_ERR,"\n color conv option is selected - so the output file is %s \n", output_file);
00515 }else if(!flagIsColorConvRequested && strstr(output_file, ".yuv") == NULL) {
00516 output_file[strlen(output_file) - strlen(strstr(output_file, "."))] = '\0';
00517 strcat(output_file, ".yuv");
00518 DEBUG(DEB_LEV_ERR,"\n color conv option is not selected - so the output file is %s \n", output_file);
00519 }
00520 }
00521 }
00522
00524 if(!flagIsColorConvRequested && flagIsSinkRequested) {
00525 DEBUG(DEB_LEV_ERR, "\n you are not using color converter component - so sink component will not be used\n");
00526 flagIsSinkRequested = 0;
00527 }
00528
00530 if((strstr(input_file, ".m4v") != NULL)) {
00531 selectedType = MPEG4_TYPE_SEL;
00532 } else if((strstr(input_file, ".264") != NULL)) {
00533 selectedType = AVC_TYPE_SEL;
00534 } else {
00535 DEBUG(DEB_LEV_ERR, "\n input file format and operation not supported \n");
00536 display_help();
00537 }
00538
00539
00540 DEBUG(DEFAULT_MESSAGES, "Options selected:\n");
00541 if(flagIsColorConvRequested == 0) {
00542 DEBUG(DEFAULT_MESSAGES, "Decode file %s to produce file %s\n", input_file, output_file);
00543 } else if(!flagIsSinkRequested){
00544 DEBUG(DEFAULT_MESSAGES, "Decode file followed by Color convert file %s to produce file %s\n", input_file, output_file);
00545 } else {
00546 DEBUG(DEFAULT_MESSAGES, "As sink component works, so there is no output file storage even if you specified\n");
00547 }
00548 if(flagIsSinkRequested) {
00549 DEBUG(DEFAULT_MESSAGES, "The color converter output will be displayed in the video sink\n");
00550 }
00551 if(flagSetupTunnel) {
00552 DEBUG(DEFAULT_MESSAGES,"The components are tunneled between themselves\n");
00553 }
00554 }
00555
00556 fd = fopen(input_file, "rb");
00557 if(fd == NULL) {
00558 DEBUG(DEB_LEV_ERR, "Error in opening input file %s\n", input_file);
00559 exit(1);
00560 }
00561
00562 if(!flagIsSinkRequested) {
00563 outfile = fopen(output_file, "wb");
00564 if(outfile == NULL) {
00565 DEBUG(DEB_LEV_ERR, "Error in opening output file %s\n", output_file);
00566 exit(1);
00567 }
00568 }
00569
00571 out_width = 640;
00572 out_height = 480;
00573
00574
00575 appPriv = malloc(sizeof(appPrivateType));
00576 appPriv->decoderEventSem = malloc(sizeof(tsem_t));
00577 if(flagIsColorConvRequested == 1) {
00578 if(flagIsSinkRequested == 1) {
00579 appPriv->fbdevSinkEventSem = malloc(sizeof(tsem_t));
00580 }
00581 appPriv->colorconvEventSem = malloc(sizeof(tsem_t));
00582 }
00583 appPriv->eofSem = malloc(sizeof(tsem_t));
00584 tsem_init(appPriv->decoderEventSem, 0);
00585 if(flagIsColorConvRequested == 1) {
00586 if(flagIsSinkRequested == 1) {
00587 tsem_init(appPriv->fbdevSinkEventSem, 0);
00588 }
00589 tsem_init(appPriv->colorconvEventSem, 0);
00590 }
00591 tsem_init(appPriv->eofSem, 0);
00592
00593 DEBUG(DEB_LEV_SIMPLE_SEQ, "Init the Omx core\n");
00594 err = OMX_Init();
00595 if (err != OMX_ErrorNone) {
00596 DEBUG(DEB_LEV_ERR, "The OpenMAX core can not be initialized. Exiting...\n");
00597 exit(1);
00598 } else {
00599 DEBUG(DEB_LEV_SIMPLE_SEQ, "Omx core is initialized \n");
00600 }
00601
00602 DEBUG(DEFAULT_MESSAGES, "------------------------------------\n");
00603 test_OMX_ComponentNameEnum();
00604 DEBUG(DEFAULT_MESSAGES, "------------------------------------\n");
00605 test_OMX_RoleEnum(COMPONENT_NAME_BASE);
00606 DEBUG(DEFAULT_MESSAGES, "------------------------------------\n");
00607 test_OMX_ComponentEnumByRole(BASE_ROLE);
00608 DEBUG(DEFAULT_MESSAGES, "------------------------------------\n");
00609 test_OpenClose(COMPONENT_NAME_BASE);
00610 DEBUG(DEFAULT_MESSAGES, "------------------------------------\n");
00611
00612
00613 full_component_name = malloc(sizeof(char*) * OMX_MAX_STRINGNAME_SIZE);
00614 strcpy(full_component_name, COMPONENT_NAME_BASE);
00615 if(selectedType == MPEG4_TYPE_SEL) {
00616 strcpy(full_component_name + COMPONENT_NAME_BASE_LEN, ".mpeg4");
00617 } else if (selectedType == AVC_TYPE_SEL) {
00618 strcpy(full_component_name + COMPONENT_NAME_BASE_LEN, ".avc");
00619 }
00620
00621 DEBUG(DEFAULT_MESSAGES, "The component selected for decoding is %s\n", full_component_name);
00622
00624 err = OMX_GetHandle(&appPriv->videodechandle, full_component_name, NULL, &videodeccallbacks);
00625 if(err != OMX_ErrorNone){
00626 DEBUG(DEB_LEV_ERR, "No video decoder component found. Exiting...\n");
00627 exit(1);
00628 } else {
00629 DEBUG(DEFAULT_MESSAGES, "Found The component for decoding is %s\n", full_component_name);
00630 }
00631
00633 if(flagIsColorConvRequested == 1) {
00634 err = OMX_GetHandle(&appPriv->colorconv_handle, "OMX.st.video_colorconv.ffmpeg", NULL, &colorconv_callbacks);
00635 if(err != OMX_ErrorNone){
00636 DEBUG(DEB_LEV_ERR, "No color converter component found. Exiting...\n");
00637 exit(1);
00638 } else {
00639 DEBUG(DEFAULT_MESSAGES, "Found The component for color converter \n");
00640 }
00641
00643 if(flagIsSinkRequested == 1) {
00644 err = OMX_GetHandle(&appPriv->fbdev_sink_handle, "OMX.st.fbdev.fbdev_sink", NULL, &fbdev_sink_callbacks);
00645 if(err != OMX_ErrorNone){
00646 DEBUG(DEB_LEV_ERR, "No video sink component component found. Exiting...\n");
00647 exit(1);
00648 } else {
00649 DEBUG(DEFAULT_MESSAGES, "Found The video sink component for color converter \n");
00650 }
00651 }
00652 }
00653
00654 setHeader(¶mRole, sizeof(OMX_PARAM_COMPONENTROLETYPE));
00655 err = OMX_GetParameter(appPriv->videodechandle, OMX_IndexParamStandardComponentRole, ¶mRole);
00656 if (err != OMX_ErrorNone) {
00657 DEBUG(DEB_LEV_ERR, "The role set for this component can not be retrieved err = %i\n", err);
00658 }
00659 DEBUG(DEB_LEV_SIMPLE_SEQ, "The role currently set is %s\n", paramRole.cRole);
00660
00662 buffer_out_size = out_width * out_height * 3/2;
00663 DEBUG(DEB_LEV_SIMPLE_SEQ, "\n buffer_out_size : %d \n", (int)buffer_out_size);
00664
00666 if (flagSetupTunnel) {
00667 DEBUG(DEB_LEV_SIMPLE_SEQ, "Setting up Tunnel\n");
00668 err = OMX_SetupTunnel(appPriv->videodechandle, 1, appPriv->colorconv_handle, 0);
00669 if(err != OMX_ErrorNone) {
00670 DEBUG(DEB_LEV_ERR, "Set up Tunnel between video dec & color conv Failed\n");
00671 exit(1);
00672 }
00673 err = OMX_SetupTunnel(appPriv->colorconv_handle, 1, appPriv->fbdev_sink_handle, 0);
00674 if(err != OMX_ErrorNone) {
00675 DEBUG(DEB_LEV_ERR, "Set up Tunnel between color conv & video sink Failed\n");
00676 exit(1);
00677 }
00678 DEBUG(DEFAULT_MESSAGES, "Set up Tunnel Completed\n");
00679 }
00680
00681
00683 pInBuffer1 = pInBuffer2 = NULL;
00684 err = OMX_SendCommand(appPriv->videodechandle, OMX_CommandStateSet, OMX_StateIdle, NULL);
00685
00687 if(flagIsColorConvRequested && flagSetupTunnel) {
00688 err = OMX_SendCommand(appPriv->colorconv_handle, OMX_CommandStateSet, OMX_StateIdle, NULL);
00689 if(flagIsSinkRequested && flagSetupTunnel) {
00690 err = OMX_SendCommand(appPriv->fbdev_sink_handle, OMX_CommandStateSet, OMX_StateIdle, NULL);
00691 }
00692 }
00693
00694 err = OMX_AllocateBuffer(appPriv->videodechandle, &pInBuffer1, 0, NULL, buffer_in_size);
00695 err = OMX_AllocateBuffer(appPriv->videodechandle, &pInBuffer2, 0, NULL, buffer_in_size);
00696
00697 if(flagSetupTunnel) {
00698 if(flagIsSinkRequested) {
00699 tsem_down(appPriv->fbdevSinkEventSem);
00700 }
00701 if(flagIsColorConvRequested) {
00702 tsem_down(appPriv->colorconvEventSem);
00703 }
00704 }
00705
00707 if (!flagSetupTunnel) {
00708 pOutBuffer1 = pOutBuffer2 = NULL;
00709 err = OMX_AllocateBuffer(appPriv->videodechandle, &pOutBuffer1, 1, NULL, buffer_out_size);
00710 err = OMX_AllocateBuffer(appPriv->videodechandle, &pOutBuffer2, 1, NULL, buffer_out_size);
00711 }
00712
00713 DEBUG(DEB_LEV_SIMPLE_SEQ, "Before locking on idle wait semaphore\n");
00714 tsem_down(appPriv->decoderEventSem);
00715 DEBUG(DEB_LEV_SIMPLE_SEQ, "decoder Sem free\n");
00716
00718 err = OMX_SendCommand(appPriv->videodechandle, OMX_CommandStateSet, OMX_StateExecuting, NULL);
00719 tsem_down(appPriv->decoderEventSem);
00720
00721 DEBUG(DEB_LEV_SIMPLE_SEQ, "---> Before locking on condition and decoderMutex\n");
00722
00723 if (!flagSetupTunnel) {
00724 err = OMX_FillThisBuffer(appPriv->videodechandle, pOutBuffer1);
00725 err = OMX_FillThisBuffer(appPriv->videodechandle, pOutBuffer2);
00726 }
00727
00728 data_read = fread(pInBuffer1->pBuffer, 1, buffer_in_size, fd);
00729 pInBuffer1->nFilledLen = data_read;
00730 pInBuffer1->nOffset = 0;
00731
00735 if(!flagSetupTunnel) {
00736 data_read = fread(pInBuffer2->pBuffer, 1, buffer_in_size, fd);
00737 pInBuffer2->nFilledLen = data_read;
00738 pInBuffer2->nOffset = 0;
00739 }
00740
00741 DEBUG(DEB_LEV_PARAMS, "Empty first buffer %x\n", (int)pInBuffer1->pBuffer);
00742 err = OMX_EmptyThisBuffer(appPriv->videodechandle, pInBuffer1);
00743
00744 if(!flagSetupTunnel) {
00745 DEBUG(DEB_LEV_PARAMS, "Empty second buffer %x\n", (int)pInBuffer2->pBuffer);
00746 err = OMX_EmptyThisBuffer(appPriv->videodechandle, pInBuffer2);
00747 }
00748
00749 DEBUG(DEFAULT_MESSAGES,"Waiting for EOS\n");
00750
00754 if(flagSetupTunnel) {
00759 tsem_down(appPriv->decoderEventSem);
00761 if(flagIsColorConvRequested) {
00762 err = OMX_SendCommand(appPriv->colorconv_handle, OMX_CommandPortDisable, OMX_ALL, NULL);
00763 if(err != OMX_ErrorNone) {
00764 DEBUG(DEB_LEV_ERR,"color conv input port disable failed\n");
00765 exit(1);
00766 }
00767 if(flagIsSinkRequested) {
00768 err = OMX_SendCommand(appPriv->fbdev_sink_handle, OMX_CommandPortDisable, 0, NULL);
00769 if(err != OMX_ErrorNone) {
00770 DEBUG(DEB_LEV_ERR,"video sink input port disable failed\n");
00771 exit(1);
00772 }
00773 }
00774 }
00775
00777 if(flagIsColorConvRequested) {
00778 if(flagIsSinkRequested) {
00779 tsem_down(appPriv->fbdevSinkEventSem);
00780 }
00781 tsem_down(appPriv->colorconvEventSem);
00782 }
00783 tsem_down(appPriv->decoderEventSem);
00784 DEBUG(DEB_LEV_SIMPLE_SEQ,"All ports are disabled in %s\n", __func__);
00785
00787 setPortParameters();
00788
00790 DEBUG(DEB_LEV_SIMPLE_SEQ,"Sending Port Enable Command\n");
00791 err = OMX_SendCommand(appPriv->videodechandle, OMX_CommandPortEnable, 1, NULL);
00792 if(err != OMX_ErrorNone) {
00793 DEBUG(DEB_LEV_ERR,"video decoder port enable failed\n");
00794 exit(1);
00795 }
00796 if(flagIsColorConvRequested) {
00797 err = OMX_SendCommand(appPriv->colorconv_handle, OMX_CommandPortEnable, -1, NULL);
00798 if(err != OMX_ErrorNone) {
00799 DEBUG(DEB_LEV_ERR,"color conv input port enable failed\n");
00800 exit(1);
00801 }
00802 if(flagIsSinkRequested) {
00803 err = OMX_SendCommand(appPriv->fbdev_sink_handle, OMX_CommandPortEnable, 0, NULL);
00804 if(err != OMX_ErrorNone) {
00805 DEBUG(DEB_LEV_ERR,"video sink input port enable failed\n");
00806 exit(1);
00807 }
00808 }
00809 }
00811 if(flagIsColorConvRequested) {
00812 if(flagIsSinkRequested) {
00813 tsem_down(appPriv->fbdevSinkEventSem);
00814 }
00815 tsem_down(appPriv->colorconvEventSem);
00816 }
00817 tsem_down(appPriv->decoderEventSem);
00818 DEBUG(DEB_LEV_SIMPLE_SEQ,"All ports are enabled in %s\n", __func__);
00819
00821 if(flagIsColorConvRequested == 1) {
00822 err = OMX_SendCommand(appPriv->colorconv_handle, OMX_CommandStateSet, OMX_StateExecuting, NULL);
00823 tsem_down(appPriv->colorconvEventSem);
00824 if(flagIsSinkRequested == 1) {
00825 err = OMX_SendCommand(appPriv->fbdev_sink_handle, OMX_CommandStateSet, OMX_StateExecuting, NULL);
00826 tsem_down(appPriv->fbdevSinkEventSem);
00827 }
00828 }
00829 DEBUG(DEB_LEV_SIMPLE_SEQ, "in %s in tunneled case, after all components in executing state\n", __func__);
00830
00832 data_read = fread(pInBuffer2->pBuffer, 1, buffer_in_size, fd);
00833 pInBuffer2->nFilledLen = data_read;
00834 pInBuffer2->nOffset = 0;
00835 DEBUG(DEB_LEV_PARAMS, "Empty second buffer %x\n", (int)pInBuffer2->pBuffer);
00836 err = OMX_EmptyThisBuffer(appPriv->videodechandle, pInBuffer2);
00837 }
00838 tsem_down(appPriv->eofSem);
00839
00840 DEBUG(DEFAULT_MESSAGES, "The execution of the video decoding process is terminated\n");
00841
00843 err = OMX_SendCommand(appPriv->videodechandle, OMX_CommandStateSet, OMX_StateIdle, NULL);
00844 if(flagIsColorConvRequested == 1) {
00845 err = OMX_SendCommand(appPriv->colorconv_handle, OMX_CommandStateSet, OMX_StateIdle, NULL);
00846 if(flagIsSinkRequested == 1) {
00847 err = OMX_SendCommand(appPriv->fbdev_sink_handle, OMX_CommandStateSet, OMX_StateIdle, NULL);
00848 }
00849 }
00850
00851 tsem_down(appPriv->decoderEventSem);
00852 if(flagIsColorConvRequested == 1) {
00853 tsem_down(appPriv->colorconvEventSem);
00854 if(flagIsSinkRequested == 1) {
00855 tsem_down(appPriv->fbdevSinkEventSem);
00856 }
00857 }
00858
00859 DEBUG(DEFAULT_MESSAGES, "All video components Transitioned to Idle\n");
00860
00862 err = OMX_SendCommand(appPriv->videodechandle, OMX_CommandStateSet, OMX_StateLoaded, NULL);
00863 if(flagIsColorConvRequested == 1) {
00864 err = OMX_SendCommand(appPriv->colorconv_handle, OMX_CommandStateSet, OMX_StateLoaded, NULL);
00865 if(flagIsSinkRequested == 1) {
00866 err = OMX_SendCommand(appPriv->fbdev_sink_handle, OMX_CommandStateSet, OMX_StateLoaded, NULL);
00867 }
00868 }
00869
00871 if(flagIsColorConvRequested == 1 && !flagSetupTunnel) {
00872 if(flagIsSinkRequested == 1 && !flagSetupTunnel) {
00873 DEBUG(DEB_LEV_PARAMS, "Video sink to loaded\n");
00874 err = OMX_FreeBuffer(appPriv->fbdev_sink_handle, 0, pInBufferSink1);
00875 err = OMX_FreeBuffer(appPriv->fbdev_sink_handle, 0, pInBufferSink2);
00876 }
00877 DEBUG(DEB_LEV_PARAMS, "Color conv to loaded\n");
00878 err = OMX_FreeBuffer(appPriv->colorconv_handle, 0, pInBufferColorConv1);
00879 err = OMX_FreeBuffer(appPriv->colorconv_handle, 0, pInBufferColorConv2);
00880
00881 err = OMX_FreeBuffer(appPriv->colorconv_handle, 1, pOutBufferColorConv1);
00882 err = OMX_FreeBuffer(appPriv->colorconv_handle, 1, pOutBufferColorConv2);
00883 }
00884
00886 DEBUG(DEB_LEV_PARAMS, "Video dec to loaded\n");
00887 err = OMX_FreeBuffer(appPriv->videodechandle, 0, pInBuffer1);
00888 err = OMX_FreeBuffer(appPriv->videodechandle, 0, pInBuffer2);
00889
00890 if(!flagSetupTunnel) {
00891 DEBUG(DEB_LEV_PARAMS, "Free Video dec output ports\n");
00892 err = OMX_FreeBuffer(appPriv->videodechandle, 1, pOutBuffer1);
00893 err = OMX_FreeBuffer(appPriv->videodechandle, 1, pOutBuffer2);
00894 }
00895
00896 if(flagIsColorConvRequested == 1) {
00897 if(flagIsSinkRequested == 1) {
00898 tsem_down(appPriv->fbdevSinkEventSem);
00899 }
00900 tsem_down(appPriv->colorconvEventSem);
00901 }
00902 tsem_down(appPriv->decoderEventSem);
00903 DEBUG(DEB_LEV_SIMPLE_SEQ, "All components released\n");
00904
00905 OMX_FreeHandle(appPriv->videodechandle);
00906 if(flagIsColorConvRequested == 1) {
00907 if(flagIsSinkRequested == 1) {
00908 OMX_FreeHandle(appPriv->fbdev_sink_handle);
00909 }
00910 OMX_FreeHandle(appPriv->colorconv_handle);
00911 }
00912 DEBUG(DEB_LEV_SIMPLE_SEQ, "video dec freed\n");
00913
00914 OMX_Deinit();
00915
00916 DEBUG(DEFAULT_MESSAGES, "All components freed. Closing...\n");
00917 free(appPriv->decoderEventSem);
00918 if(flagIsColorConvRequested == 1) {
00919 if(flagIsSinkRequested == 1) {
00920 free(appPriv->fbdevSinkEventSem);
00921 }
00922 free(appPriv->colorconvEventSem);
00923 }
00924 free(appPriv->eofSem);
00925 free(appPriv);
00926
00928 if(!flagIsSinkRequested) {
00929 fclose(outfile);
00930 }
00932 fclose(fd);
00933
00934 return 0;
00935 }
00936
00937
00939 OMX_ERRORTYPE fb_sinkEventHandler(
00940 OMX_OUT OMX_HANDLETYPE hComponent,
00941 OMX_OUT OMX_PTR pAppData,
00942 OMX_OUT OMX_EVENTTYPE eEvent,
00943 OMX_OUT OMX_U32 Data1,
00944 OMX_OUT OMX_U32 Data2,
00945 OMX_OUT OMX_PTR pEventData) {
00946
00947 DEBUG(DEB_LEV_SIMPLE_SEQ, "Hi there, I am in the %s callback\n", __func__);
00948 if(eEvent == OMX_EventCmdComplete) {
00949 if (Data1 == OMX_CommandStateSet) {
00950 DEBUG(DEB_LEV_SIMPLE_SEQ, "State changed in ");
00951 switch ((int)Data2) {
00952 case OMX_StateInvalid:
00953 DEBUG(DEB_LEV_SIMPLE_SEQ, "OMX_StateInvalid\n");
00954 break;
00955 case OMX_StateLoaded:
00956 DEBUG(DEB_LEV_SIMPLE_SEQ, "OMX_StateLoaded\n");
00957 break;
00958 case OMX_StateIdle:
00959 DEBUG(DEB_LEV_SIMPLE_SEQ, "OMX_StateIdle ---- fbsink\n");
00960 break;
00961 case OMX_StateExecuting:
00962 DEBUG(DEB_LEV_SIMPLE_SEQ, "OMX_StateExecuting\n");
00963 break;
00964 case OMX_StatePause:
00965 DEBUG(DEB_LEV_SIMPLE_SEQ, "OMX_StatePause\n");
00966 break;
00967 case OMX_StateWaitForResources:
00968 DEBUG(DEB_LEV_SIMPLE_SEQ, "OMX_StateWaitForResources\n");
00969 break;
00970 }
00971 tsem_up(appPriv->fbdevSinkEventSem);
00972 } else if (OMX_CommandPortEnable || OMX_CommandPortDisable) {
00973 DEBUG(DEB_LEV_SIMPLE_SEQ, "In %s Received Port Enable/Disable Event\n",__func__);
00974 tsem_up(appPriv->fbdevSinkEventSem);
00975 }
00976 } else if(eEvent == OMX_EventBufferFlag) {
00977 DEBUG(DEB_LEV_ERR, "In %s OMX_BUFFERFLAG_EOS\n", __func__);
00978 if((int)Data2 == OMX_BUFFERFLAG_EOS) {
00979 tsem_up(appPriv->eofSem);
00980 }
00981 } else {
00982 DEBUG(DEB_LEV_SIMPLE_SEQ, "Param1 is %i\n", (int)Data1);
00983 DEBUG(DEB_LEV_SIMPLE_SEQ, "Param2 is %i\n", (int)Data2);
00984 }
00985 return OMX_ErrorNone;
00986 }
00987
00988
00989 OMX_ERRORTYPE fb_sinkEmptyBufferDone(
00990 OMX_OUT OMX_HANDLETYPE hComponent,
00991 OMX_OUT OMX_PTR pAppData,
00992 OMX_OUT OMX_BUFFERHEADERTYPE* pBuffer) {
00993
00994 OMX_ERRORTYPE err;
00995 static int inputBufferDropped = 0;
00996 if(pBuffer != NULL) {
00997 if(!bEOS) {
00998 if(pOutBufferColorConv1->pBuffer == pBuffer->pBuffer) {
00999 pOutBufferColorConv1->nFilledLen = pBuffer->nFilledLen;
01000 err = OMX_FillThisBuffer(appPriv->colorconv_handle, pOutBufferColorConv1);
01001 } else {
01002 pOutBufferColorConv2->nFilledLen = pBuffer->nFilledLen;
01003 err = OMX_FillThisBuffer(appPriv->colorconv_handle, pOutBufferColorConv2);
01004 }
01005 if(err != OMX_ErrorNone) {
01006 DEBUG(DEB_LEV_ERR, "In %s Error %08x Calling FillThisBuffer\n", __func__,err);
01007 }
01008 } else {
01009 DEBUG(DEB_LEV_ERR, "In %s: eos=%x Dropping Fill This Buffer\n", __func__,(int)pBuffer->nFlags);
01010 inputBufferDropped++;
01011 if(inputBufferDropped == 2) {
01012 tsem_up(appPriv->eofSem);
01013 }
01014 }
01015 } else {
01016 if(!bEOS) {
01017 tsem_up(appPriv->eofSem);
01018 }
01019 DEBUG(DEB_LEV_ERR, "Ouch! In %s: had NULL buffer to output...\n", __func__);
01020 }
01021 return OMX_ErrorNone;
01022 }
01023
01024
01025
01026 OMX_ERRORTYPE colorconvEventHandler(
01027 OMX_OUT OMX_HANDLETYPE hComponent,
01028 OMX_OUT OMX_PTR pAppData,
01029 OMX_OUT OMX_EVENTTYPE eEvent,
01030 OMX_OUT OMX_U32 Data1,
01031 OMX_OUT OMX_U32 Data2,
01032 OMX_OUT OMX_PTR pEventData) {
01033
01034 DEBUG(DEB_LEV_SIMPLE_SEQ, "\nHi there, I am in the %s callback\n", __func__);
01035 if(eEvent == OMX_EventCmdComplete) {
01036 if (Data1 == OMX_CommandStateSet) {
01037 DEBUG(DEB_LEV_SIMPLE_SEQ, "\nState changed in ");
01038 switch ((int)Data2) {
01039 case OMX_StateInvalid:
01040 DEBUG(DEB_LEV_SIMPLE_SEQ, "OMX_StateInvalid\n");
01041 break;
01042 case OMX_StateLoaded:
01043 DEBUG(DEB_LEV_SIMPLE_SEQ, "OMX_StateLoaded\n");
01044 break;
01045 case OMX_StateIdle:
01046 DEBUG(DEB_LEV_SIMPLE_SEQ, "OMX_StateIdle\n");
01047 break;
01048 case OMX_StateExecuting:
01049 DEBUG(DEB_LEV_SIMPLE_SEQ, "OMX_StateExecuting\n");
01050 break;
01051 case OMX_StatePause:
01052 DEBUG(DEB_LEV_SIMPLE_SEQ, "OMX_StatePause\n");
01053 break;
01054 case OMX_StateWaitForResources:
01055 DEBUG(DEB_LEV_SIMPLE_SEQ, "OMX_StateWaitForResources\n");
01056 break;
01057 }
01058 tsem_up(appPriv->colorconvEventSem);
01059 }
01060 else if (OMX_CommandPortEnable || OMX_CommandPortDisable) {
01061 DEBUG(DEB_LEV_SIMPLE_SEQ, "In %s Received Port Enable/Disable Event\n",__func__);
01062 tsem_up(appPriv->colorconvEventSem);
01063 }
01064 } else if(eEvent == OMX_EventBufferFlag) {
01065 DEBUG(DEB_LEV_ERR, "In %s OMX_BUFFERFLAG_EOS\n", __func__);
01066 if((int)Data2 == OMX_BUFFERFLAG_EOS) {
01067 tsem_up(appPriv->eofSem);
01068 }
01069 } else {
01070 DEBUG(DEB_LEV_SIMPLE_SEQ, "Param1 is %i\n", (int)Data1);
01071 DEBUG(DEB_LEV_SIMPLE_SEQ, "Param2 is %i\n", (int)Data2);
01072 }
01073 return OMX_ErrorNone;
01074 }
01075
01076
01077 OMX_ERRORTYPE colorconvEmptyBufferDone(
01078 OMX_OUT OMX_HANDLETYPE hComponent,
01079 OMX_OUT OMX_PTR pAppData,
01080 OMX_OUT OMX_BUFFERHEADERTYPE* pBuffer) {
01081
01082 OMX_ERRORTYPE err;
01083 static int iBufferDropped = 0;
01084
01085 if(pBuffer != NULL) {
01086 if(!bEOS) {
01087 if(pOutBuffer1->pBuffer == pBuffer->pBuffer) {
01088 pOutBuffer1->nFilledLen = pBuffer->nFilledLen;
01089 err = OMX_FillThisBuffer(appPriv->videodechandle, pOutBuffer1);
01090 } else {
01091 pOutBuffer2->nFilledLen = pBuffer->nFilledLen;
01092 err = OMX_FillThisBuffer(appPriv->videodechandle, pOutBuffer2);
01093 }
01094 if(err != OMX_ErrorNone) {
01095 DEBUG(DEB_LEV_ERR, "In %s Error %08x Calling FillThisBuffer\n", __func__,err);
01096 }
01097 } else {
01098 DEBUG(DEB_LEV_ERR, "In %s: eos=%x Dropping Fill This Buffer\n", __func__,(int)pBuffer->nFlags);
01099 iBufferDropped++;
01100 if(iBufferDropped == 2) {
01101 tsem_up(appPriv->eofSem);
01102 }
01103 }
01104 } else {
01105 if(!bEOS) {
01106 tsem_up(appPriv->eofSem);
01107 }
01108 DEBUG(DEB_LEV_ERR, "Ouch! In %s: had NULL buffer to output...\n", __func__);
01109 }
01110 return OMX_ErrorNone;
01111 }
01112
01113
01114 OMX_ERRORTYPE colorconvFillBufferDone(
01115 OMX_OUT OMX_HANDLETYPE hComponent,
01116 OMX_OUT OMX_PTR pAppData,
01117 OMX_OUT OMX_BUFFERHEADERTYPE* pBuffer) {
01118
01119 OMX_ERRORTYPE err;
01120 if(pBuffer != NULL) {
01121 if(!bEOS) {
01125 if(flagIsSinkRequested && (!flagSetupTunnel)) {
01126 if(pInBufferSink1->pBuffer == pBuffer->pBuffer) {
01127 pInBufferSink1->nFilledLen = pBuffer->nFilledLen;
01128 err = OMX_EmptyThisBuffer(appPriv->fbdev_sink_handle, pInBufferSink1);
01129 } else {
01130 pInBufferSink2->nFilledLen = pBuffer->nFilledLen;
01131 err = OMX_EmptyThisBuffer(appPriv->fbdev_sink_handle, pInBufferSink2);
01132 }
01133 if(err != OMX_ErrorNone) {
01134 DEBUG(DEB_LEV_ERR, "In %s Error %08x Calling FillThisBuffer\n", __func__,err);
01135 }
01136 } else if((pBuffer->nFilledLen > 0) && (!flagSetupTunnel)) {
01137 fwrite(pBuffer->pBuffer, 1, pBuffer->nFilledLen, outfile);
01138 pBuffer->nFilledLen = 0;
01139 }
01140 if(pBuffer->nFlags == OMX_BUFFERFLAG_EOS) {
01141 DEBUG(DEB_LEV_ERR, "In %s: eos=%x Calling Empty This Buffer\n", __func__, (int)pBuffer->nFlags);
01142 bEOS = OMX_TRUE;
01143 }
01144 if(!bEOS && !flagIsSinkRequested && (!flagSetupTunnel)) {
01145 err = OMX_FillThisBuffer(hComponent, pBuffer);
01146 }
01147 } else {
01148 DEBUG(DEB_LEV_ERR, "In %s: eos=%x Dropping Empty This Buffer\n", __func__,(int)pBuffer->nFlags);
01149 }
01150 } else {
01151 DEBUG(DEB_LEV_ERR, "Ouch! In %s: had NULL buffer to output...\n", __func__);
01152 }
01153 return OMX_ErrorNone;
01154 }
01155
01157 OMX_ERRORTYPE videodecEventHandler(
01158 OMX_OUT OMX_HANDLETYPE hComponent,
01159 OMX_OUT OMX_PTR pAppData,
01160 OMX_OUT OMX_EVENTTYPE eEvent,
01161 OMX_OUT OMX_U32 Data1,
01162 OMX_OUT OMX_U32 Data2,
01163 OMX_OUT OMX_PTR pEventData) {
01164
01165 OMX_ERRORTYPE err = OMX_ErrorNone;
01166
01167 DEBUG(DEB_LEV_SIMPLE_SEQ, "Hi there, I am in the %s callback\n", __func__);
01168 if(eEvent == OMX_EventCmdComplete) {
01169 if (Data1 == OMX_CommandStateSet) {
01170 DEBUG(DEB_LEV_SIMPLE_SEQ, "State changed in ");
01171 switch ((int)Data2) {
01172 case OMX_StateInvalid:
01173 DEBUG(DEB_LEV_SIMPLE_SEQ, "OMX_StateInvalid\n");
01174 break;
01175 case OMX_StateLoaded:
01176 DEBUG(DEB_LEV_SIMPLE_SEQ, "OMX_StateLoaded\n");
01177 break;
01178 case OMX_StateIdle:
01179 DEBUG(DEB_LEV_SIMPLE_SEQ, "OMX_StateIdle\n");
01180 break;
01181 case OMX_StateExecuting:
01182 DEBUG(DEB_LEV_SIMPLE_SEQ, "OMX_StateExecuting\n");
01183 break;
01184 case OMX_StatePause:
01185 DEBUG(DEB_LEV_SIMPLE_SEQ, "OMX_StatePause\n");
01186 break;
01187 case OMX_StateWaitForResources:
01188 DEBUG(DEB_LEV_SIMPLE_SEQ, "OMX_StateWaitForResources\n");
01189 break;
01190 }
01191 tsem_up(appPriv->decoderEventSem);
01192 } else if (OMX_CommandPortEnable || OMX_CommandPortDisable) {
01193 DEBUG(DEB_LEV_SIMPLE_SEQ, "In %s Received Port Enable/Disable Event\n",__func__);
01194 tsem_up(appPriv->decoderEventSem);
01195 }
01196 } else if(eEvent == OMX_EventPortSettingsChanged) {
01197 DEBUG(DEB_LEV_SIMPLE_SEQ, "\n port settings change event handler in %s \n", __func__);
01198 if(Data2 == 0) {
01199
01206 if(flagSetupTunnel) {
01207 DEBUG(DEB_LEV_SIMPLE_SEQ,"Sending Port Disable Command\n");
01208 err = OMX_SendCommand(appPriv->videodechandle, OMX_CommandPortDisable, 1, NULL);
01209 if(err != OMX_ErrorNone) {
01210 DEBUG(DEB_LEV_ERR,"video decoder port disable failed\n");
01211 exit(1);
01212 }
01213
01214 tsem_up(appPriv->decoderEventSem);
01215 }
01216
01221 if(!flagSetupTunnel) {
01222 setPortParameters();
01223 if(flagIsColorConvRequested == 1) {
01224 pOutBufferColorConv1 = pOutBufferColorConv2 = NULL;
01225 err = OMX_SendCommand(appPriv->colorconv_handle, OMX_CommandStateSet, OMX_StateIdle, NULL);
01226
01228 err = OMX_UseBuffer(appPriv->colorconv_handle, &pInBufferColorConv1, 0, NULL, buffer_out_size, pOutBuffer1->pBuffer);
01229 if(err != OMX_ErrorNone) {
01230 DEBUG(DEB_LEV_ERR, "Unable to use the video dec comp allocate buffer\n");
01231 exit(1);
01232 }
01233 err = OMX_UseBuffer(appPriv->colorconv_handle, &pInBufferColorConv2, 0, NULL, buffer_out_size, pOutBuffer2->pBuffer);
01234 if(err != OMX_ErrorNone) {
01235 DEBUG(DEB_LEV_ERR, "Unable to use the video dec comp allocate buffer\n");
01236 exit(1);
01237 }
01238
01240 omx_colorconvPortDefinition.nPortIndex = 1;
01241 setHeader(&omx_colorconvPortDefinition, sizeof(OMX_PARAM_PORTDEFINITIONTYPE));
01242 err = OMX_GetParameter(appPriv->colorconv_handle, OMX_IndexParamPortDefinition, &omx_colorconvPortDefinition);
01243 outbuf_colorconv_size = omx_colorconvPortDefinition.nBufferSize;
01244 DEBUG(DEB_LEV_SIMPLE_SEQ, " outbuf_colorconv_size : %d \n", (int)outbuf_colorconv_size);
01245
01246 err = OMX_AllocateBuffer(appPriv->colorconv_handle, &pOutBufferColorConv1, 1, NULL, outbuf_colorconv_size);
01247 if(err != OMX_ErrorNone) {
01248 DEBUG(DEB_LEV_ERR, "Unable to allocate buffer in color conv\n");
01249 exit(1);
01250 }
01251 err = OMX_AllocateBuffer(appPriv->colorconv_handle, &pOutBufferColorConv2, 1, NULL, outbuf_colorconv_size);
01252 if(err != OMX_ErrorNone) {
01253 DEBUG(DEB_LEV_ERR, "Unable to allocate buffer in colro conv\n");
01254 exit(1);
01255 }
01256
01257 DEBUG(DEB_LEV_SIMPLE_SEQ, "Before locking on idle wait semaphore\n");
01258 tsem_down(appPriv->colorconvEventSem);
01259 DEBUG(DEB_LEV_SIMPLE_SEQ, "color conv Sem free\n");
01260
01261 if(flagIsSinkRequested == 1) {
01262 err = OMX_SendCommand(appPriv->fbdev_sink_handle, OMX_CommandStateSet, OMX_StateIdle, NULL);
01263 err = OMX_UseBuffer(appPriv->fbdev_sink_handle, &pInBufferSink1, 0, NULL, outbuf_colorconv_size, pOutBufferColorConv1->pBuffer);
01264 if(err != OMX_ErrorNone) {
01265 DEBUG(DEB_LEV_ERR, "Unable to use the color conv comp allocate buffer\n");
01266 exit(1);
01267 }
01268 err = OMX_UseBuffer(appPriv->fbdev_sink_handle, &pInBufferSink2, 0, NULL, outbuf_colorconv_size, pOutBufferColorConv2->pBuffer);
01269 if(err != OMX_ErrorNone) {
01270 DEBUG(DEB_LEV_ERR, "Unable to use the color conv comp allocate buffer\n");
01271 exit(1);
01272 }
01273
01274 DEBUG(DEB_LEV_SIMPLE_SEQ, "Before locking on idle wait semaphore\n");
01275 tsem_down(appPriv->fbdevSinkEventSem);
01276 DEBUG(DEB_LEV_SIMPLE_SEQ, "video sink comp Sem free\n");
01277 }
01278 }
01279
01280 if(flagIsColorConvRequested == 1) {
01281 err = OMX_SendCommand(appPriv->colorconv_handle, OMX_CommandStateSet, OMX_StateExecuting, NULL);
01282 tsem_down(appPriv->colorconvEventSem);
01283 if(flagIsSinkRequested == 1) {
01284 err = OMX_SendCommand(appPriv->fbdev_sink_handle, OMX_CommandStateSet, OMX_StateExecuting, NULL);
01285 tsem_down(appPriv->fbdevSinkEventSem);
01286 }
01287 }
01288
01289 if(flagIsColorConvRequested == 1 ) {
01290 err = OMX_FillThisBuffer(appPriv->colorconv_handle, pOutBufferColorConv1);
01291 err = OMX_FillThisBuffer(appPriv->colorconv_handle, pOutBufferColorConv2);
01292 DEBUG(DEB_LEV_SIMPLE_SEQ, "---> After fill this buffer function calls to the color conv output buffers\n");
01293 }
01294 }
01295 }
01296 } else if(eEvent == OMX_EventBufferFlag) {
01297 DEBUG(DEB_LEV_ERR, "In %s OMX_BUFFERFLAG_EOS\n", __func__);
01298 if((int)Data2 == OMX_BUFFERFLAG_EOS) {
01299 tsem_up(appPriv->eofSem);
01300 }
01301 } else {
01302 DEBUG(DEB_LEV_SIMPLE_SEQ, "Param1 is %i\n", (int)Data1);
01303 DEBUG(DEB_LEV_SIMPLE_SEQ, "Param2 is %i\n", (int)Data2);
01304 }
01305 return err;
01306 }
01307
01308 OMX_ERRORTYPE videodecEmptyBufferDone(
01309 OMX_OUT OMX_HANDLETYPE hComponent,
01310 OMX_OUT OMX_PTR pAppData,
01311 OMX_OUT OMX_BUFFERHEADERTYPE* pBuffer) {
01312
01313 OMX_ERRORTYPE err;
01314 int data_read;
01315 DEBUG(DEB_LEV_FULL_SEQ, "Hi there, I am in the %s callback.\n", __func__);
01316
01317 data_read = fread(pBuffer->pBuffer, 1, buffer_in_size, fd);
01318 if (data_read <= 0) {
01319 DEBUG(DEB_LEV_SIMPLE_SEQ, "In the %s no more input data available\n", __func__);
01320 pBuffer->nFlags = OMX_BUFFERFLAG_EOS;
01321 pBuffer->nFilledLen = 0;
01322 tsem_up(appPriv->eofSem);
01323 return OMX_ErrorNone;
01324 }
01325 pBuffer->nFilledLen = data_read;
01326 DEBUG(DEB_LEV_PARAMS, "Empty buffer %x\n", (int)pBuffer);
01327 err = OMX_EmptyThisBuffer(hComponent, pBuffer);
01328 return OMX_ErrorNone;
01329 }
01330
01331
01332 OMX_ERRORTYPE videodecFillBufferDone(
01333 OMX_OUT OMX_HANDLETYPE hComponent,
01334 OMX_OUT OMX_PTR pAppData,
01335 OMX_OUT OMX_BUFFERHEADERTYPE* pBuffer) {
01336
01337 OMX_ERRORTYPE err;
01338 OMX_STATETYPE eState;
01339
01340 if(pBuffer != NULL) {
01341 if(!bEOS) {
01345 if(flagIsColorConvRequested && (!flagSetupTunnel)) {
01346 OMX_GetState(appPriv->colorconv_handle,&eState);
01347 if(eState == OMX_StateExecuting || eState == OMX_StatePause) {
01348 if(pInBufferColorConv1->pBuffer == pBuffer->pBuffer) {
01349 pInBufferColorConv1->nFilledLen = pBuffer->nFilledLen;
01350 err = OMX_EmptyThisBuffer(appPriv->colorconv_handle, pInBufferColorConv1);
01351 } else {
01352 pInBufferColorConv2->nFilledLen = pBuffer->nFilledLen;
01353 err = OMX_EmptyThisBuffer(appPriv->colorconv_handle, pInBufferColorConv2);
01354 }
01355 if(err != OMX_ErrorNone) {
01356 DEBUG(DEB_LEV_ERR, "In %s Error %08x Calling FillThisBuffer\n", __func__,err);
01357 }
01358 } else {
01359 err = OMX_FillThisBuffer(hComponent, pBuffer);
01360 }
01361 } else if((pBuffer->nFilledLen > 0) && (!flagSetupTunnel)) {
01362 fwrite(pBuffer->pBuffer, 1, pBuffer->nFilledLen, outfile);
01363 pBuffer->nFilledLen = 0;
01364 } else {
01365 DEBUG(DEB_LEV_ERR, "In %s Empty buffer in Else\n", __func__);
01366 }
01367 if(pBuffer->nFlags == OMX_BUFFERFLAG_EOS) {
01368 DEBUG(DEB_LEV_ERR, "In %s: eos=%x Calling Empty This Buffer\n", __func__, (int)pBuffer->nFlags);
01369 bEOS = OMX_TRUE;
01370 }
01371 if(!bEOS && !flagIsColorConvRequested && (!flagSetupTunnel)) {
01372 err = OMX_FillThisBuffer(hComponent, pBuffer);
01373 }
01374 } else {
01375 DEBUG(DEB_LEV_ERR, "In %s: eos=%x Dropping Empty This Buffer\n", __func__,(int)pBuffer->nFlags);
01376 }
01377 } else {
01378 DEBUG(DEB_LEV_ERR, "Ouch! In %s: had NULL buffer to output...\n", __func__);
01379 }
01380 return OMX_ErrorNone;
01381 }
01382
01383