OMX_ERRORTYPE Component::useEGLImage(OMX_BUFFERHEADERTYPE** ppBufferHdr, OMX_U32 nPortIndex, OMX_PTR pAppPrivate, void* eglImage) { lock(); OMX_ERRORTYPE error = OMX_UseEGLImage(handle, ppBufferHdr, nPortIndex, pAppPrivate, eglImage); OMX_TRACE(error); unlock(); return error; }
bool PureOmxBufferData::ShouldUseEGLImage() { OMX_ERRORTYPE err; err = OMX_UseEGLImage(mPlatformLayer.GetComponent(), nullptr, mPortDef.nPortIndex, nullptr, nullptr); return (err != OMX_ErrorNotImplemented); }
OMX_ERRORTYPE COMXCoreComponent::UseEGLImage(OMX_BUFFERHEADERTYPE** ppBufferHdr, OMX_U32 nPortIndex, OMX_PTR pAppPrivate, void* eglImage) { Lock(); OMX_ERRORTYPE omx_err; omx_err = OMX_UseEGLImage(m_handle, ppBufferHdr, nPortIndex, pAppPrivate, eglImage); if(omx_err != OMX_ErrorNone) { CLog::Log(LOGERROR, "COMXCoreComponent::UseEGLImage - %s failed with omx_err(0x%x)\n", m_componentName.c_str(), omx_err); } UnLock(); return omx_err; }
// Modified function prototype to work with pthreads void *video_decode_test(void* arg) { const char* filename = "/opt/vc/src/hello_pi/hello_video/test.h264"; eglImage = arg; if (eglImage == 0) { printf("eglImage is null.\n"); exit(1); } OMX_VIDEO_PARAM_PORTFORMATTYPE format; OMX_TIME_CONFIG_CLOCKSTATETYPE cstate; COMPONENT_T *video_decode = NULL, *video_scheduler = NULL, *clock = NULL; COMPONENT_T *list[5]; TUNNEL_T tunnel[4]; ILCLIENT_T *client; FILE *in; int status = 0; unsigned int data_len = 0; int packet_size = 80<<10; memset(list, 0, sizeof(list)); memset(tunnel, 0, sizeof(tunnel)); if((in = fopen(filename, "rb")) == NULL) return (void *)-2; if((client = ilclient_init()) == NULL) { fclose(in); return (void *)-3; } if(OMX_Init() != OMX_ErrorNone) { ilclient_destroy(client); fclose(in); return (void *)-4; } // callback ilclient_set_fill_buffer_done_callback(client, my_fill_buffer_done, 0); // create video_decode if(ilclient_create_component(client, &video_decode, "video_decode", ILCLIENT_DISABLE_ALL_PORTS | ILCLIENT_ENABLE_INPUT_BUFFERS) != 0) status = -14; list[0] = video_decode; // create video_render //if(status == 0 && ilclient_create_component(client, &video_render, "video_render", ILCLIENT_DISABLE_ALL_PORTS) != 0) if(status == 0 && ilclient_create_component(client, &video_render, "egl_render", ILCLIENT_DISABLE_ALL_PORTS | ILCLIENT_ENABLE_OUTPUT_BUFFERS) != 0) status = -14; list[1] = video_render; // create clock if(status == 0 && ilclient_create_component(client, &clock, "clock", ILCLIENT_DISABLE_ALL_PORTS) != 0) status = -14; list[2] = clock; memset(&cstate, 0, sizeof(cstate)); cstate.nSize = sizeof(cstate); cstate.nVersion.nVersion = OMX_VERSION; cstate.eState = OMX_TIME_ClockStateWaitingForStartTime; cstate.nWaitMask = 1; if(clock != NULL && OMX_SetParameter(ILC_GET_HANDLE(clock), OMX_IndexConfigTimeClockState, &cstate) != OMX_ErrorNone) status = -13; // create video_scheduler if(status == 0 && ilclient_create_component(client, &video_scheduler, "video_scheduler", ILCLIENT_DISABLE_ALL_PORTS) != 0) status = -14; list[3] = video_scheduler; set_tunnel(tunnel, video_decode, 131, video_scheduler, 10); //set_tunnel(tunnel+1, video_scheduler, 11, video_render, 90); set_tunnel(tunnel+1, video_scheduler, 11, video_render, 220); set_tunnel(tunnel+2, clock, 80, video_scheduler, 12); // setup clock tunnel first if(status == 0 && ilclient_setup_tunnel(tunnel+2, 0, 0) != 0) status = -15; else ilclient_change_component_state(clock, OMX_StateExecuting); if(status == 0) ilclient_change_component_state(video_decode, OMX_StateIdle); memset(&format, 0, sizeof(OMX_VIDEO_PARAM_PORTFORMATTYPE)); format.nSize = sizeof(OMX_VIDEO_PARAM_PORTFORMATTYPE); format.nVersion.nVersion = OMX_VERSION; format.nPortIndex = 130; format.eCompressionFormat = OMX_VIDEO_CodingAVC; if(status == 0 && OMX_SetParameter(ILC_GET_HANDLE(video_decode), OMX_IndexParamVideoPortFormat, &format) == OMX_ErrorNone && ilclient_enable_port_buffers(video_decode, 130, NULL, NULL, NULL) == 0) { OMX_BUFFERHEADERTYPE *buf; int port_settings_changed = 0; int first_packet = 1; ilclient_change_component_state(video_decode, OMX_StateExecuting); while((buf = ilclient_get_input_buffer(video_decode, 130, 1)) != NULL) { // feed data and wait until we get port settings changed unsigned char *dest = buf->pBuffer; // loop if at end if (feof(in)) rewind(in); data_len += fread(dest, 1, packet_size-data_len, in); if(port_settings_changed == 0 && ((data_len > 0 && ilclient_remove_event(video_decode, OMX_EventPortSettingsChanged, 131, 0, 0, 1) == 0) || (data_len == 0 && ilclient_wait_for_event(video_decode, OMX_EventPortSettingsChanged, 131, 0, 0, 1, ILCLIENT_EVENT_ERROR | ILCLIENT_PARAMETER_CHANGED, 10000) == 0))) { port_settings_changed = 1; if(ilclient_setup_tunnel(tunnel, 0, 0) != 0) { status = -7; break; } ilclient_change_component_state(video_scheduler, OMX_StateExecuting); // now setup tunnel to video_render if(ilclient_setup_tunnel(tunnel+1, 0, 1000) != 0) { status = -12; break; } // Set egl_render to idle ilclient_change_component_state(video_render, OMX_StateIdle); // Enable the output port and tell egl_render to use the texture as a buffer //ilclient_enable_port(video_render, 221); THIS BLOCKS SO CANT BE USED if (OMX_SendCommand(ILC_GET_HANDLE(video_render), OMX_CommandPortEnable, 221, NULL) != OMX_ErrorNone) { printf("OMX_CommandPortEnable failed.\n"); exit(1); } if (OMX_UseEGLImage(ILC_GET_HANDLE(video_render), &eglBuffer, 221, NULL, eglImage) != OMX_ErrorNone) { printf("OMX_UseEGLImage failed.\n"); exit(1); } // Set egl_render to executing ilclient_change_component_state(video_render, OMX_StateExecuting); // Request egl_render to write data to the texture buffer if(OMX_FillThisBuffer(ILC_GET_HANDLE(video_render), eglBuffer) != OMX_ErrorNone) { printf("OMX_FillThisBuffer failed.\n"); exit(1); } } if(!data_len) break; buf->nFilledLen = data_len; data_len = 0; buf->nOffset = 0; if(first_packet) { buf->nFlags = OMX_BUFFERFLAG_STARTTIME; first_packet = 0; } else buf->nFlags = OMX_BUFFERFLAG_TIME_UNKNOWN; if(OMX_EmptyThisBuffer(ILC_GET_HANDLE(video_decode), buf) != OMX_ErrorNone) { status = -6; break; } } buf->nFilledLen = 0; buf->nFlags = OMX_BUFFERFLAG_TIME_UNKNOWN | OMX_BUFFERFLAG_EOS; if(OMX_EmptyThisBuffer(ILC_GET_HANDLE(video_decode), buf) != OMX_ErrorNone) status = -20; // wait for EOS from render ilclient_wait_for_event(video_render, OMX_EventBufferFlag, 90, 0, OMX_BUFFERFLAG_EOS, 0, ILCLIENT_BUFFER_FLAG_EOS, 10000); // need to flush the renderer to allow video_decode to disable its input port ilclient_flush_tunnels(tunnel, 0); ilclient_disable_port_buffers(video_decode, 130, NULL, NULL, NULL); } fclose(in); ilclient_disable_tunnel(tunnel); ilclient_disable_tunnel(tunnel+1); ilclient_disable_tunnel(tunnel+2); ilclient_teardown_tunnels(tunnel); ilclient_state_transition(list, OMX_StateIdle); ilclient_state_transition(list, OMX_StateLoaded); ilclient_cleanup_components(list); OMX_Deinit(); ilclient_destroy(client); return (void *)status; }
void *video_decode_test(void* arg) { bcm_host_init(); CUBE_STATE_T *state = (CUBE_STATE_T *)arg; OMX_ERRORTYPE r; if((r = OMX_Init()) != OMX_ErrorNone) { omx_die(r, "OMX initalization failed"); } // Init context appctx ctx; memset(&ctx, 0, sizeof(ctx)); if(vcos_semaphore_create(&ctx.handler_lock, "handler_lock", 1) != VCOS_SUCCESS) { die("Failed to create handler lock semaphore"); } ctx.eglImage = state->eglImage; // Init component handles OMX_CALLBACKTYPE callbacks; memset(&ctx, 0, sizeof(callbacks)); callbacks.EventHandler = event_handler; callbacks.FillBufferDone = my_fill_buffer_done; init_component_handle("camera", &ctx.camera , &ctx, &callbacks); init_component_handle("egl_render", &ctx.render, &ctx, &callbacks); init_component_handle("null_sink", &ctx.null_sink, &ctx, &callbacks); init_component_handle("clock", &ctx.clock, &ctx, &callbacks); OMX_U32 screen_width = state->screen_width, screen_height = state->screen_height; if(graphics_get_display_size(DISPLAY_DEVICE, &screen_width, &screen_height) < 0) { die("Failed to get display size"); } say("Configuring camera..."); dump_port(ctx.clock, 80, OMX_TRUE); say("Default port definition for camera input port 73"); dump_port(ctx.camera, 73, OMX_TRUE); say("Default port definition for camera preview output port 70"); dump_port(ctx.camera, 70, OMX_TRUE); say("Default port definition for camera video output port 71"); dump_port(ctx.camera, 71, OMX_TRUE); OMX_TIME_CONFIG_CLOCKSTATETYPE cstate; OMX_INIT_STRUCTURE(cstate); cstate.eState = OMX_TIME_ClockStateRunning; cstate.nWaitMask = 1; if((r = OMX_SetConfig(ctx.clock, OMX_IndexConfigTimeClockState, &cstate)) != OMX_ErrorNone) { omx_die(r, "Failed to request camera device number parameter change callback for camera"); } // Request a callback to be made when OMX_IndexParamCameraDeviceNumber is // changed signaling that the camera device is ready for use. OMX_CONFIG_REQUESTCALLBACKTYPE cbtype; OMX_INIT_STRUCTURE(cbtype); cbtype.nPortIndex = OMX_ALL; cbtype.nIndex = OMX_IndexParamCameraDeviceNumber; cbtype.bEnable = OMX_TRUE; if((r = OMX_SetConfig(ctx.camera, OMX_IndexConfigRequestCallback, &cbtype)) != OMX_ErrorNone) { omx_die(r, "Failed to request camera device number parameter change callback for camera"); } // Set device number, this triggers the callback configured just above OMX_PARAM_U32TYPE device; OMX_INIT_STRUCTURE(device); device.nPortIndex = OMX_ALL; device.nU32 = CAM_DEVICE_NUMBER; if((r = OMX_SetParameter(ctx.camera, OMX_IndexParamCameraDeviceNumber, &device)) != OMX_ErrorNone) { omx_die(r, "Failed to set camera parameter device number"); } // Configure video format emitted by camera preview output port OMX_PARAM_PORTDEFINITIONTYPE camera_portdef; OMX_INIT_STRUCTURE(camera_portdef); camera_portdef.nPortIndex = 70; if((r = OMX_GetParameter(ctx.camera, OMX_IndexParamPortDefinition, &camera_portdef)) != OMX_ErrorNone) { omx_die(r, "Failed to get port definition for camera preview output port 70"); } camera_portdef.format.video.nFrameWidth = state->screen_width; camera_portdef.format.video.nFrameHeight = state->screen_height; camera_portdef.format.video.xFramerate = VIDEO_FRAMERATE << 16; // Stolen from gstomxvideodec.c of gst-omx camera_portdef.format.video.nStride = (camera_portdef.format.video.nFrameWidth + camera_portdef.nBufferAlignment - 1) & (~(camera_portdef.nBufferAlignment - 1)); camera_portdef.format.video.eColorFormat = OMX_COLOR_FormatYUV420PackedPlanar; if((r = OMX_SetParameter(ctx.camera, OMX_IndexParamPortDefinition, &camera_portdef)) != OMX_ErrorNone) { omx_die(r, "Failed to set port definition for camera preview output port 70"); } // Configure video format emitted by camera video output port // Use configuration from camera preview output as basis for // camera video output configuration OMX_INIT_STRUCTURE(camera_portdef); camera_portdef.nPortIndex = 70; if((r = OMX_GetParameter(ctx.camera, OMX_IndexParamPortDefinition, &camera_portdef)) != OMX_ErrorNone) { omx_die(r, "Failed to get port definition for camera preview output port 70"); } camera_portdef.nPortIndex = 71; if((r = OMX_SetParameter(ctx.camera, OMX_IndexParamPortDefinition, &camera_portdef)) != OMX_ErrorNone) { omx_die(r, "Failed to set port definition for camera video output port 71"); } // Configure frame rate OMX_CONFIG_FRAMERATETYPE framerate; OMX_INIT_STRUCTURE(framerate); framerate.nPortIndex = 70; framerate.xEncodeFramerate = camera_portdef.format.video.xFramerate; if((r = OMX_SetConfig(ctx.camera, OMX_IndexConfigVideoFramerate, &framerate)) != OMX_ErrorNone) { omx_die(r, "Failed to set framerate configuration for camera preview output port 70"); } framerate.nPortIndex = 71; if((r = OMX_SetConfig(ctx.camera, OMX_IndexConfigVideoFramerate, &framerate)) != OMX_ErrorNone) { omx_die(r, "Failed to set framerate configuration for camera video output port 71"); } // Configure sharpness OMX_CONFIG_SHARPNESSTYPE sharpness; OMX_INIT_STRUCTURE(sharpness); sharpness.nPortIndex = OMX_ALL; sharpness.nSharpness = CAM_SHARPNESS; if((r = OMX_SetConfig(ctx.camera, OMX_IndexConfigCommonSharpness, &sharpness)) != OMX_ErrorNone) { omx_die(r, "Failed to set camera sharpness configuration"); } // Configure contrast OMX_CONFIG_CONTRASTTYPE contrast; OMX_INIT_STRUCTURE(contrast); contrast.nPortIndex = OMX_ALL; contrast.nContrast = CAM_CONTRAST; if((r = OMX_SetConfig(ctx.camera, OMX_IndexConfigCommonContrast, &contrast)) != OMX_ErrorNone) { omx_die(r, "Failed to set camera contrast configuration"); } // Configure saturation OMX_CONFIG_SATURATIONTYPE saturation; OMX_INIT_STRUCTURE(saturation); saturation.nPortIndex = OMX_ALL; saturation.nSaturation = CAM_SATURATION; if((r = OMX_SetConfig(ctx.camera, OMX_IndexConfigCommonSaturation, &saturation)) != OMX_ErrorNone) { omx_die(r, "Failed to set camera saturation configuration"); } // Configure brightness OMX_CONFIG_BRIGHTNESSTYPE brightness; OMX_INIT_STRUCTURE(brightness); brightness.nPortIndex = OMX_ALL; brightness.nBrightness = CAM_BRIGHTNESS; if((r = OMX_SetConfig(ctx.camera, OMX_IndexConfigCommonBrightness, &brightness)) != OMX_ErrorNone) { omx_die(r, "Failed to set camera brightness configuration"); } // Configure exposure value OMX_CONFIG_EXPOSUREVALUETYPE exposure_value; OMX_INIT_STRUCTURE(exposure_value); exposure_value.nPortIndex = OMX_ALL; exposure_value.xEVCompensation = CAM_EXPOSURE_VALUE_COMPENSTAION; exposure_value.bAutoSensitivity = CAM_EXPOSURE_AUTO_SENSITIVITY; exposure_value.bAutoShutterSpeed = OMX_TRUE; // exposure_value.nShutterSpeedMsec = 10; exposure_value.nSensitivity = CAM_EXPOSURE_ISO_SENSITIVITY; exposure_value.eMetering = OMX_MeteringModeAverage; if((r = OMX_SetConfig(ctx.camera, OMX_IndexConfigCommonExposureValue, &exposure_value)) != OMX_ErrorNone) { omx_die(r, "Failed to set camera exposure value configuration"); } OMX_CONFIG_EXPOSURECONTROLTYPE exposure; OMX_INIT_STRUCTURE(exposure); exposure.nPortIndex = OMX_ALL; exposure.eExposureControl = OMX_ExposureControlAuto; OMX_SetConfig(ctx.camera, OMX_IndexConfigCommonExposure, &exposure); // Configure frame frame stabilisation OMX_CONFIG_FRAMESTABTYPE frame_stabilisation_control; OMX_INIT_STRUCTURE(frame_stabilisation_control); frame_stabilisation_control.nPortIndex = OMX_ALL; frame_stabilisation_control.bStab = CAM_FRAME_STABILISATION; if((r = OMX_SetConfig(ctx.camera, OMX_IndexConfigCommonFrameStabilisation, &frame_stabilisation_control)) != OMX_ErrorNone) { omx_die(r, "Failed to set camera frame frame stabilisation control configuration"); } // Configure frame white balance control /* OMX_CONFIG_LIGHTNESSTYPE lightness_control; OMX_INIT_STRUCTURE(lightness_control); lightness_control.nPortIndex = OMX_ALL; lightness_control.nLightness = 0; if((r = OMX_SetConfig(ctx.camera, OMX_IndexConfigCommonLightness, &lightness_control)) != OMX_ErrorNone) { omx_die(r, "Failed to set camera frame white balance control configuration"); }*/ // Configure frame white balance control OMX_CONFIG_WHITEBALCONTROLTYPE white_balance_control; OMX_INIT_STRUCTURE(white_balance_control); white_balance_control.nPortIndex = OMX_ALL; white_balance_control.eWhiteBalControl = CAM_WHITE_BALANCE_CONTROL; if((r = OMX_SetConfig(ctx.camera, OMX_IndexConfigCommonWhiteBalance, &white_balance_control)) != OMX_ErrorNone) { omx_die(r, "Failed to set camera frame white balance control configuration"); } // Configure image filter OMX_CONFIG_IMAGEFILTERTYPE image_filter; OMX_INIT_STRUCTURE(image_filter); image_filter.nPortIndex = OMX_ALL; image_filter.eImageFilter = CAM_IMAGE_FILTER; if((r = OMX_SetConfig(ctx.camera, OMX_IndexConfigCommonImageFilter, &image_filter)) != OMX_ErrorNone) { omx_die(r, "Failed to set camera image filter configuration"); } /* Set colour effect */ OMX_CONFIG_COLORENHANCEMENTTYPE colour; OMX_INIT_STRUCTURE(colour); colour.nPortIndex = OMX_ALL; colour.bColorEnhancement = OMX_FALSE; colour.nCustomizedU = 128; colour.nCustomizedV = 128; OMX_SetConfig(ctx.camera, OMX_IndexConfigCommonColorEnhancement, &colour); // Configure mirror OMX_MIRRORTYPE eMirror = OMX_MirrorNone; if(CAM_FLIP_HORIZONTAL && !CAM_FLIP_VERTICAL) { eMirror = OMX_MirrorHorizontal; } else if(!CAM_FLIP_HORIZONTAL && CAM_FLIP_VERTICAL) { eMirror = OMX_MirrorVertical; } else if(CAM_FLIP_HORIZONTAL && CAM_FLIP_VERTICAL) { eMirror = OMX_MirrorBoth; } OMX_CONFIG_MIRRORTYPE mirror; OMX_INIT_STRUCTURE(mirror); mirror.nPortIndex = 71; mirror.eMirror = eMirror; if((r = OMX_SetConfig(ctx.camera, OMX_IndexConfigCommonMirror, &mirror)) != OMX_ErrorNone) { omx_die(r, "Failed to set mirror configuration for camera video output port 71"); } // Ensure camera is ready while(!ctx.camera_ready) { usleep(10000); } say("Configuring render..."); say("Default port definition for render input port 90"); dump_port(ctx.render, 220, OMX_TRUE); // Render input port definition is done automatically upon tunneling say("Configuring null sink..."); say("Default port definition for null sink input port 240"); dump_port(ctx.null_sink, 240, OMX_TRUE); // Null sink input port definition is done automatically upon tunneling // Tunnel camera preview output port and null sink input port say("Setting up tunnel from camera preview output port 70 to null sink input port 240..."); if((r = OMX_SetupTunnel(ctx.clock, 80, ctx.camera, 73)) != OMX_ErrorNone) { omx_die(r, "Failed to setup tunnel between camera preview output port 70 and null sink input port 240"); } // Tunnel camera preview output port and null sink input port say("Setting up tunnel from camera preview output port 70 to null sink input port 240..."); if((r = OMX_SetupTunnel(ctx.camera, 70, ctx.null_sink, 240)) != OMX_ErrorNone) { omx_die(r, "Failed to setup tunnel between camera preview output port 70 and null sink input port 240"); } // Tunnel camera video output port and render input port say("Setting up tunnel from camera video output port 71 to render input port 220..."); if((r = OMX_SetupTunnel(ctx.camera, 71, ctx.render, 220)) != OMX_ErrorNone) { omx_die(r, "Failed to setup tunnel between camera video output port 71 and render input port 90"); } // Switch components to idle state say("Switching state of the camera component to idle..."); if((r = OMX_SendCommand(ctx.clock, OMX_CommandStateSet, OMX_StateIdle, NULL)) != OMX_ErrorNone) { omx_die(r, "Failed to switch state of the camera component to idle"); } block_until_state_changed(ctx.clock, OMX_StateIdle); say("Switching state of the camera component to idle..."); if((r = OMX_SendCommand(ctx.camera, OMX_CommandStateSet, OMX_StateIdle, NULL)) != OMX_ErrorNone) { omx_die(r, "Failed to switch state of the camera component to idle"); } block_until_state_changed(ctx.camera, OMX_StateIdle); say("Switching state of the render component to idle..."); if((r = OMX_SendCommand(ctx.render, OMX_CommandStateSet, OMX_StateIdle, NULL)) != OMX_ErrorNone) { omx_die(r, "Failed to switch state of the render component to idle"); } block_until_state_changed(ctx.render, OMX_StateIdle); say("Switching state of the null sink component to idle..."); if((r = OMX_SendCommand(ctx.null_sink, OMX_CommandStateSet, OMX_StateIdle, NULL)) != OMX_ErrorNone) { omx_die(r, "Failed to switch state of the null sink component to idle"); } block_until_state_changed(ctx.null_sink, OMX_StateIdle); // Enable ports say("Enabling ports..."); if((r = OMX_SendCommand(ctx.clock, OMX_CommandPortEnable, 80, NULL)) != OMX_ErrorNone) { omx_die(r, "Failed to enable camera input port 73"); } block_until_port_changed(ctx.clock, 80, OMX_TRUE); if((r = OMX_SendCommand(ctx.camera, OMX_CommandPortEnable, 73, NULL)) != OMX_ErrorNone) { omx_die(r, "Failed to enable camera input port 73"); } block_until_port_changed(ctx.camera, 73, OMX_TRUE); if((r = OMX_SendCommand(ctx.camera, OMX_CommandPortEnable, 70, NULL)) != OMX_ErrorNone) { omx_die(r, "Failed to enable camera preview output port 70"); } block_until_port_changed(ctx.camera, 70, OMX_TRUE); if((r = OMX_SendCommand(ctx.camera, OMX_CommandPortEnable, 71, NULL)) != OMX_ErrorNone) { omx_die(r, "Failed to enable camera video output port 71"); } block_until_port_changed(ctx.camera, 71, OMX_TRUE); if((r = OMX_SendCommand(ctx.render, OMX_CommandPortEnable, 220, NULL)) != OMX_ErrorNone) { omx_die(r, "Failed to enable render input port 220"); } block_until_port_changed(ctx.render, 220, OMX_TRUE); if((r = OMX_SendCommand(ctx.render, OMX_CommandPortEnable, 221, NULL)) != OMX_ErrorNone) { omx_die(r, "Failed to enable render input port 221"); } block_until_port_changed(ctx.render, 220, OMX_TRUE); if((r = OMX_SendCommand(ctx.null_sink, OMX_CommandPortEnable, 240, NULL)) != OMX_ErrorNone) { omx_die(r, "Failed to enable null sink input port 240"); } block_until_port_changed(ctx.null_sink, 240, OMX_TRUE); // Allocate camera input buffer, buffers for tunneled // ports are allocated internally by OMX if((r = OMX_UseEGLImage(ctx.render, &ctx.eglBuffer, 221, NULL, ctx.eglImage)) != OMX_ErrorNone) { omx_die(r, "Failed to use eglimage"); } // Switch state of the components prior to starting // the video capture and encoding loop say("Switching state of the camera component to executing..."); if((r = OMX_SendCommand(ctx.clock, OMX_CommandStateSet, OMX_StateExecuting, NULL)) != OMX_ErrorNone) { omx_die(r, "Failed to switch state of the camera component to executing"); } say("Switching state of the camera component to executing..."); if((r = OMX_SendCommand(ctx.camera, OMX_CommandStateSet, OMX_StateExecuting, NULL)) != OMX_ErrorNone) { omx_die(r, "Failed to switch state of the camera component to executing"); } block_until_state_changed(ctx.camera, OMX_StateExecuting); say("Switching state of the render component to executing..."); if((r = OMX_SendCommand(ctx.render, OMX_CommandStateSet, OMX_StateExecuting, NULL)) != OMX_ErrorNone) { omx_die(r, "Failed to switch state of the render component to executing"); } block_until_state_changed(ctx.render, OMX_StateExecuting); say("Switching state of the null sink component to executing..."); if((r = OMX_SendCommand(ctx.null_sink, OMX_CommandStateSet, OMX_StateExecuting, NULL)) != OMX_ErrorNone) { omx_die(r, "Failed to switch state of the null sink component to executing"); } block_until_state_changed(ctx.null_sink, OMX_StateExecuting); // Start capturing video with the camera say("Switching on capture on camera video output port 71..."); OMX_CONFIG_PORTBOOLEANTYPE capture; OMX_INIT_STRUCTURE(capture); capture.nPortIndex = 71; capture.bEnabled = OMX_TRUE; if((r = OMX_SetParameter(ctx.camera, OMX_IndexConfigPortCapturing, &capture)) != OMX_ErrorNone) { omx_die(r, "Failed to switch on capture on camera video output port 71"); } say("Configured port definition for camera input port 73"); dump_port(ctx.camera, 73, OMX_FALSE); say("Configured port definition for camera preview output port 70"); dump_port(ctx.camera, 70, OMX_FALSE); say("Configured port definition for camera video output port 71"); dump_port(ctx.camera, 71, OMX_FALSE); say("Configured port definition for render input port 90"); dump_port(ctx.render, 220, OMX_FALSE); say("Configured port definition for null sink input port 240"); dump_port(ctx.null_sink, 240, OMX_FALSE); say("Enter capture and playback loop, press Ctrl-C to quit..."); if((r = OMX_FillThisBuffer(ctx.render, ctx.eglBuffer)) != OMX_ErrorNone) { omx_die(r, "Failed to fill buffer"); } signal(SIGINT, signal_handler); signal(SIGTERM, signal_handler); signal(SIGQUIT, signal_handler); while(!want_quit) { // Would be better to use signaling here but hey this works too usleep(1000); } say("Cleaning up..."); // Restore signal handlers signal(SIGINT, SIG_DFL); signal(SIGTERM, SIG_DFL); signal(SIGQUIT, SIG_DFL); // Stop capturing video with the camera OMX_INIT_STRUCTURE(capture); capture.nPortIndex = 71; capture.bEnabled = OMX_FALSE; if((r = OMX_SetParameter(ctx.camera, OMX_IndexConfigPortCapturing, &capture)) != OMX_ErrorNone) { omx_die(r, "Failed to switch off capture on camera video output port 71"); } // Flush the buffers on each component if((r = OMX_SendCommand(ctx.camera, OMX_CommandFlush, 73, NULL)) != OMX_ErrorNone) { omx_die(r, "Failed to flush buffers of camera input port 73"); } block_until_flushed(&ctx); if((r = OMX_SendCommand(ctx.camera, OMX_CommandFlush, 70, NULL)) != OMX_ErrorNone) { omx_die(r, "Failed to flush buffers of camera preview output port 70"); } block_until_flushed(&ctx); if((r = OMX_SendCommand(ctx.camera, OMX_CommandFlush, 71, NULL)) != OMX_ErrorNone) { omx_die(r, "Failed to flush buffers of camera video output port 71"); } block_until_flushed(&ctx); if((r = OMX_SendCommand(ctx.render, OMX_CommandFlush, 220, NULL)) != OMX_ErrorNone) { omx_die(r, "Failed to flush buffers of render input port 220"); } block_until_flushed(&ctx); if((r = OMX_SendCommand(ctx.null_sink, OMX_CommandFlush, 240, NULL)) != OMX_ErrorNone) { omx_die(r, "Failed to flush buffers of null sink input port 240"); } block_until_flushed(&ctx); // Disable all the ports if((r = OMX_SendCommand(ctx.camera, OMX_CommandPortDisable, 73, NULL)) != OMX_ErrorNone) { omx_die(r, "Failed to disable camera input port 73"); } block_until_port_changed(ctx.camera, 73, OMX_FALSE); if((r = OMX_SendCommand(ctx.camera, OMX_CommandPortDisable, 70, NULL)) != OMX_ErrorNone) { omx_die(r, "Failed to disable camera preview output port 70"); } block_until_port_changed(ctx.camera, 70, OMX_FALSE); if((r = OMX_SendCommand(ctx.camera, OMX_CommandPortDisable, 71, NULL)) != OMX_ErrorNone) { omx_die(r, "Failed to disable camera video output port 71"); } block_until_port_changed(ctx.camera, 71, OMX_FALSE); if((r = OMX_SendCommand(ctx.render, OMX_CommandPortDisable, 220, NULL)) != OMX_ErrorNone) { omx_die(r, "Failed to disable render input port 90"); } if((r = OMX_SendCommand(ctx.null_sink, OMX_CommandPortDisable, 240, NULL)) != OMX_ErrorNone) { omx_die(r, "Failed to disable null sink input port 240"); } block_until_port_changed(ctx.null_sink, 240, OMX_FALSE); // Free all the buffers if((r = OMX_FreeBuffer(ctx.camera, 73, ctx.camera_ppBuffer_in)) != OMX_ErrorNone) { omx_die(r, "Failed to free buffer for camera input port 73"); } // Transition all the components to idle and then to loaded states if((r = OMX_SendCommand(ctx.camera, OMX_CommandStateSet, OMX_StateIdle, NULL)) != OMX_ErrorNone) { omx_die(r, "Failed to switch state of the camera component to idle"); } block_until_state_changed(ctx.camera, OMX_StateIdle); if((r = OMX_SendCommand(ctx.render, OMX_CommandStateSet, OMX_StateIdle, NULL)) != OMX_ErrorNone) { omx_die(r, "Failed to switch state of the render component to idle"); } block_until_state_changed(ctx.render, OMX_StateIdle); if((r = OMX_SendCommand(ctx.null_sink, OMX_CommandStateSet, OMX_StateIdle, NULL)) != OMX_ErrorNone) { omx_die(r, "Failed to switch state of the null sink component to idle"); } block_until_state_changed(ctx.null_sink, OMX_StateIdle); if((r = OMX_SendCommand(ctx.camera, OMX_CommandStateSet, OMX_StateLoaded, NULL)) != OMX_ErrorNone) { omx_die(r, "Failed to switch state of the camera component to loaded"); } block_until_state_changed(ctx.camera, OMX_StateLoaded); if((r = OMX_SendCommand(ctx.render, OMX_CommandStateSet, OMX_StateLoaded, NULL)) != OMX_ErrorNone) { omx_die(r, "Failed to switch state of the render component to loaded"); } block_until_state_changed(ctx.render, OMX_StateLoaded); if((r = OMX_SendCommand(ctx.null_sink, OMX_CommandStateSet, OMX_StateLoaded, NULL)) != OMX_ErrorNone) { omx_die(r, "Failed to switch state of the null sink component to loaded"); } block_until_state_changed(ctx.null_sink, OMX_StateLoaded); // Free the component handles if((r = OMX_FreeHandle(ctx.camera)) != OMX_ErrorNone) { omx_die(r, "Failed to free camera component handle"); } if((r = OMX_FreeHandle(ctx.render)) != OMX_ErrorNone) { omx_die(r, "Failed to free render component handle"); } if((r = OMX_FreeHandle(ctx.null_sink)) != OMX_ErrorNone) { omx_die(r, "Failed to free null sink component handle"); } // Exit vcos_semaphore_delete(&ctx.handler_lock); if((r = OMX_Deinit()) != OMX_ErrorNone) { omx_die(r, "OMX de-initalization failed"); } say("Exit!"); return 0; }
OMX_ERRORTYPE COpenMaxVideo::AllocOMXOutputEGLTextures(void) { OMX_ERRORTYPE omx_err; if (!eglCreateImageKHR) { GETEXTENSION(PFNEGLCREATEIMAGEKHRPROC, eglCreateImageKHR); } EGLint attrib = EGL_NONE; OpenMaxVideoBuffer *egl_buffer; // Obtain the information about the output port. OMX_PARAM_PORTDEFINITIONTYPE port_format; OMX_INIT_STRUCTURE(port_format); port_format.nPortIndex = m_omx_output_port; omx_err = OMX_GetParameter(m_omx_decoder, OMX_IndexParamPortDefinition, &port_format); #if defined(OMX_DEBUG_VERBOSE) CLog::Log(LOGDEBUG, "%s::%s (1) - oport(%d), nFrameWidth(%lu), nFrameHeight(%lu), nStride(%lx), nBufferCountMin(%lu), nBufferSize(%lu)\n", CLASSNAME, __func__, m_omx_output_port, port_format.format.video.nFrameWidth, port_format.format.video.nFrameHeight,port_format.format.video.nStride, port_format.nBufferCountMin, port_format.nBufferSize); #endif glActiveTexture(GL_TEXTURE0); for (size_t i = 0; i < port_format.nBufferCountMin; i++) { egl_buffer = new OpenMaxVideoBuffer; memset(egl_buffer, 0, sizeof(*egl_buffer)); egl_buffer->width = m_decoded_width; egl_buffer->height = m_decoded_height; glGenTextures(1, &egl_buffer->texture_id); glBindTexture(GL_TEXTURE_2D, egl_buffer->texture_id); // create space for buffer with a texture glTexImage2D( GL_TEXTURE_2D, // target 0, // level GL_RGBA, // internal format m_decoded_width, // width m_decoded_height, // height 0, // border GL_RGBA, // format GL_UNSIGNED_BYTE, // type NULL); // pixels -- will be provided later glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); // create EGLImage from texture egl_buffer->egl_image = eglCreateImageKHR( m_egl_display, m_egl_context, EGL_GL_TEXTURE_2D_KHR, (EGLClientBuffer)(egl_buffer->texture_id), &attrib); if (!egl_buffer->egl_image) { CLog::Log(LOGERROR, "%s::%s - ERROR creating EglImage\n", CLASSNAME, __func__); return(OMX_ErrorUndefined); } egl_buffer->index = i; // tell decoder output port that it will be using EGLImage omx_err = OMX_UseEGLImage( m_omx_decoder, &egl_buffer->omx_buffer, m_omx_output_port, egl_buffer, egl_buffer->egl_image); if (omx_err) { CLog::Log(LOGERROR, "%s::%s - OMX_UseEGLImage failed with omx_err(0x%x)\n", CLASSNAME, __func__, omx_err); return(omx_err); } m_omx_output_buffers.push_back(egl_buffer); CLog::Log(LOGDEBUG, "%s::%s - Texture %p Width %d Height %d\n", CLASSNAME, __func__, egl_buffer->egl_image, egl_buffer->width, egl_buffer->height); } m_omx_output_eos = false; while (!m_omx_output_busy.empty()) m_omx_output_busy.pop(); while (!m_omx_output_ready.empty()) m_omx_output_ready.pop(); return omx_err; }
// Modified function prototype to work with pthreads void *video_decode_test(void* arg) { pthread_mutex_init(&m_lock, NULL); printf("OMX version : %d.%d.%d-%d\n",OMX_VERSION_MAJOR, OMX_VERSION_MINOR, OMX_VERSION_REVISION, OMX_VERSION_STEP); printf("file to read : %s\n", filename); eglImage = arg; if (eglImage == 0) { printf("eglImage is null.\n"); exit(1); } int status = 0; unsigned int data_len = 0; int packet_size = 80<<10; memset(list, 0, sizeof(list)); memset(tunnel, 0, sizeof(tunnel)); if((in = fopen(filename, "rb")) == NULL) return (void *)-2; if((client = ilclient_init()) == NULL) { fclose(in); return (void *)-3; } if(OMX_Init() != OMX_ErrorNone) { ilclient_destroy(client); fclose(in); return (void *)-4; } // callback ilclient_set_fill_buffer_done_callback(client, my_fill_buffer_done, 0); // create video_decode if(ilclient_create_component(client, &video_decode, "video_decode", ILCLIENT_DISABLE_ALL_PORTS | ILCLIENT_ENABLE_INPUT_BUFFERS) != 0) status = -14; list[0] = video_decode; // create video_render //if(status == 0 && ilclient_create_component(client, &video_render, "video_render", ILCLIENT_DISABLE_ALL_PORTS) != 0) if(status == 0 && ilclient_create_component(client, &video_render, "egl_render", ILCLIENT_DISABLE_ALL_PORTS | ILCLIENT_ENABLE_OUTPUT_BUFFERS) != 0) status = -14; list[1] = video_render; // create clock if(status == 0 && ilclient_create_component(client, &omx_clock, "clock", ILCLIENT_DISABLE_ALL_PORTS) != 0) status = -14; list[2] = omx_clock; memset(&cstate, 0, sizeof(cstate)); cstate.nSize = sizeof(cstate); cstate.nVersion.nVersion = OMX_VERSION; cstate.eState = OMX_TIME_ClockStateWaitingForStartTime; cstate.nWaitMask = 1; if(omx_clock != NULL && OMX_SetParameter(ILC_GET_HANDLE(omx_clock), OMX_IndexConfigTimeClockState, &cstate) != OMX_ErrorNone) status = -13; // set the clock refenrece to "none" memset(&cref,0,sizeof(cref)); cref.nSize = sizeof(cref); cref.nVersion.nVersion = OMX_VERSION; cref.eClock = OMX_TIME_RefClockNone; if(omx_clock != NULL && OMX_SetParameter(ILC_GET_HANDLE(omx_clock), OMX_IndexConfigTimeActiveRefClock, &cref) != OMX_ErrorNone){ status = -13; printf("error setting refclock\n"); } // create video_scheduler if(status == 0 && ilclient_create_component(client, &video_scheduler, "video_scheduler", ILCLIENT_DISABLE_ALL_PORTS) != 0) status = -14; list[3] = video_scheduler; set_tunnel(tunnel, video_decode, 131, video_scheduler, 10); //set_tunnel(tunnel+1, video_scheduler, 11, video_render, 90); set_tunnel(tunnel+1, video_scheduler, 11, video_render, 220); set_tunnel(tunnel+2, omx_clock, 80, video_scheduler, 12); // setup clock tunnel first if(status == 0 && ilclient_setup_tunnel(tunnel+2, 0, 0) != 0) status = -15; else ilclient_change_component_state(omx_clock, OMX_StateExecuting); if(status == 0) ilclient_change_component_state(video_decode, OMX_StateIdle); memset(&format, 0, sizeof(OMX_VIDEO_PARAM_PORTFORMATTYPE)); format.nSize = sizeof(OMX_VIDEO_PARAM_PORTFORMATTYPE); format.nVersion.nVersion = OMX_VERSION; format.nPortIndex = 130; format.eCompressionFormat = OMX_VIDEO_CodingAVC; if(status == 0 && OMX_SetParameter(ILC_GET_HANDLE(video_decode), OMX_IndexParamVideoPortFormat, &format) == OMX_ErrorNone && ilclient_enable_port_buffers(video_decode, 130, NULL, NULL, NULL) == 0) { OMX_BUFFERHEADERTYPE *buf; int port_settings_changed = 0; int first_packet = 1; ilclient_change_component_state(video_decode, OMX_StateExecuting); while((buf = ilclient_get_input_buffer(video_decode, 130, 1)) != NULL && stop_flag==0 ) { // feed data and wait until we get port settings changed unsigned char *dest = buf->pBuffer; // loop if at end if (feof(in)) rewind(in); data_len += fread(dest, 1, packet_size-data_len, in); if(port_settings_changed == 0 && ((data_len > 0 && ilclient_remove_event(video_decode, OMX_EventPortSettingsChanged, 131, 0, 0, 1) == 0) || (data_len == 0 && ilclient_wait_for_event(video_decode, OMX_EventPortSettingsChanged, 131, 0, 0, 1, ILCLIENT_EVENT_ERROR | ILCLIENT_PARAMETER_CHANGED, 10000) == 0))) { port_settings_changed = 1; if(ilclient_setup_tunnel(tunnel, 0, 0) != 0) { status = -7; break; } ilclient_change_component_state(video_scheduler, OMX_StateExecuting); // now setup tunnel to video_render if(ilclient_setup_tunnel(tunnel+1, 0, 1000) != 0) { status = -12; break; } // Set egl_render to idle ilclient_change_component_state(video_render, OMX_StateIdle); // Enable the output port and tell egl_render to use the texture as a buffer //ilclient_enable_port(video_render, 221); THIS BLOCKS SO CANT BE USED if (OMX_SendCommand(ILC_GET_HANDLE(video_render), OMX_CommandPortEnable, 221, NULL) != OMX_ErrorNone) { printf("OMX_CommandPortEnable failed.\n"); exit(1); } if (OMX_UseEGLImage(ILC_GET_HANDLE(video_render), &eglBuffer, 221, NULL, eglImage) != OMX_ErrorNone) { printf("OMX_UseEGLImage failed.\n"); exit(1); } // Set egl_render to executing ilclient_change_component_state(video_render, OMX_StateExecuting); // Request egl_render to write data to the texture buffer if(OMX_FillThisBuffer(ILC_GET_HANDLE(video_render), eglBuffer) != OMX_ErrorNone) { printf("OMX_FillThisBuffer failed.\n"); //~ exit(1); } } if(!data_len) break; buf->nFilledLen = data_len; data_len = 0; buf->nOffset = 0; if(first_packet) { buf->nFlags = OMX_BUFFERFLAG_STARTTIME; first_packet = 0; } else buf->nFlags = OMX_BUFFERFLAG_TIME_UNKNOWN; if(OMX_EmptyThisBuffer(ILC_GET_HANDLE(video_decode), buf) != OMX_ErrorNone) { status = -6; break; } } printf("loop ends, now flush the buffer\n"); OMX_SendCommand(ILC_GET_HANDLE(video_decode),OMX_CommandFlush,130,NULL); OMX_SendCommand(ILC_GET_HANDLE(video_decode),OMX_CommandFlush,131,NULL); ilclient_wait_for_event(video_decode, OMX_EventCmdComplete, OMX_CommandFlush, 0, 130, 0, ILCLIENT_PORT_FLUSH, -1); ilclient_wait_for_event(video_decode, OMX_EventCmdComplete, OMX_CommandFlush, 0, 131, 0, ILCLIENT_PORT_FLUSH, -1); data_len=0; memset(&cstate, 0, sizeof(cstate)); cstate.nSize = sizeof(cstate); cstate.nVersion.nVersion = OMX_VERSION; cstate.eState = OMX_TIME_ClockStateStopped; cstate.nWaitMask = 1; OMX_SetParameter(ILC_GET_HANDLE(omx_clock), OMX_IndexConfigTimeClockState, &cstate); memset(&cstate, 0, sizeof(cstate)); cstate.nSize = sizeof(cstate); cstate.nVersion.nVersion = OMX_VERSION; cstate.eState = OMX_TIME_ClockStateWaitingForStartTime; cstate.nWaitMask = 1; OMX_SetParameter(ILC_GET_HANDLE(omx_clock), OMX_IndexConfigTimeClockState, &cstate); //~ scheduler should be stopped... buf->nFilledLen = 0; buf->nFlags = OMX_BUFFERFLAG_TIME_UNKNOWN | OMX_BUFFERFLAG_EOS; if(OMX_EmptyThisBuffer(ILC_GET_HANDLE(video_decode), buf) != OMX_ErrorNone) status = -20; // wait for EOS from render //~ printf("wait for EOS from render\n"); //~ ilclient_wait_for_event(video_render, OMX_EventBufferFlag, 90, 0, OMX_BUFFERFLAG_EOS, 0, //~ ILCLIENT_BUFFER_FLAG_EOS, 10000); while ((ilclient_remove_event(video_render, OMX_EventBufferFlag, 90, 0, OMX_BUFFERFLAG_EOS, 0) <0 ) && !stop_flag){ } printf("flush the render\n"); // need to flush the renderer to allow video_decode to disable its input port ilclient_flush_tunnels(tunnel, 0); ilclient_disable_port_buffers(video_decode, 130, NULL, NULL, NULL); } printf("close file\n"); fclose(in); ilclient_disable_tunnel(tunnel); ilclient_disable_tunnel(tunnel+1); ilclient_disable_tunnel(tunnel+2); ilclient_teardown_tunnels(tunnel); ilclient_state_transition(list, OMX_StateIdle); ilclient_state_transition(list, OMX_StateLoaded); ilclient_cleanup_components(list); OMX_Deinit(); ilclient_destroy(client); printf("thread will return...\n"); pthread_mutex_destroy(&m_lock); return (void *)status; }
bool OMX_VideoGraph::playData(OMX_BUFFERHEADERTYPE*& buf) { if (port_settings_changed == 0 && compDecoder->waitForEvent(OMX_EventPortSettingsChanged, 131, 0, -1)) { LOG_VERBOSE(LOG_TAG, "Port settings changed event thrown!"); port_settings_changed = 1; tunnelDecSched->setupTunnel(0, TIMEOUT_MS); LOG_VERBOSE(LOG_TAG, "Setting scheduler to EXECUTING..."); compScheduler->sendCommand(OMX_CommandStateSet, OMX_StateExecuting, NULL); compScheduler->waitForEvent(OMX_EventCmdComplete, OMX_CommandStateSet, OMX_StateExecuting, TIMEOUT_MS); // video_render is in LOADED here. // now setup tunnel to video_render LOG_VERBOSE(LOG_TAG, "Setting up scheduler -> renderer tunnel..."); tunnelSchedRender->setupTunnel(0, TIMEOUT_MS); // video_render is in IDLE here. // Query output buffer requirements for renderer and provide the native display // the renderer will use. OMX_PARAM_PORTDEFINITIONTYPE portdef; portdef.nSize = sizeof(OMX_PARAM_PORTDEFINITIONTYPE); portdef.nVersion.nVersion = OMX_VERSION; portdef.nPortIndex = 221; compEGLRender->GetParameter(OMX_IndexParamPortDefinition, &portdef); portdef.format.video.pNativeWindow = m_eglDisplay; compEGLRender->SetParameter(OMX_IndexParamPortDefinition, &portdef); LOG_VERBOSE(LOG_TAG, "Waiting for EXECUTING state..."); compEGLRender->sendCommand(OMX_CommandStateSet, OMX_StateExecuting, NULL); compEGLRender->waitForEvent(OMX_EventCmdComplete, OMX_CommandStateSet, OMX_StateExecuting, TIMEOUT_MS); // Wait for port settings changed. LOG_VERBOSE(LOG_TAG, "Waiting for port settings changed!"); compEGLRender->waitForEvent(OMX_EventPortSettingsChanged, 221, 0, TIMEOUT_MS); // Enable output port of video_render. LOG_VERBOSE(LOG_TAG, "Enabling output port of EGL renderer..."); compEGLRender->sendCommand(OMX_CommandPortEnable, 221, NULL); // Instead of providing a buffer I provide the EGL image to use. GLuint texture; QMetaObject::invokeMethod( m_provider, "instantiateTexture", Qt::BlockingQueuedConnection, Q_RETURN_ARG(GLuint, texture), Q_ARG(QSize, QSize(1920, 1080))); m_texture.setTexture(eglImageVideo, texture, QSize(1920, 1080)); emit textureReady(texture); LOG_VERBOSE(LOG_TAG, "Providing EGLImage: %x.", (unsigned int)eglImageVideo); OMX_ERRORTYPE omxErr = OMX_UseEGLImage(compEGLRender->GetHandle(), &m_eglBuffer, 221, NULL, eglImageVideo); if (omxErr != OMX_ErrorNone) { LOG_ERROR(LOG_TAG, "OpenMAXILTextureLoader::decode - OMX_UseEGLImage - failed with omxErr(0x%x)\n", omxErr); return false; } compEGLRender->waitForEvent(OMX_EventCmdComplete, OMX_CommandPortEnable, 221, TIMEOUT_MS); LOG_VERBOSE(LOG_TAG, "Port enabled!!!"); // video_render is in EXECUTING here. } if (first_packet) { buf->nFlags = OMX_BUFFERFLAG_STARTTIME; first_packet = 0; } else buf->nFlags = OMX_BUFFERFLAG_TIME_UNKNOWN; LOG_VERBOSE(LOG_TAG, "Calling empty this buffer (%x)...", (unsigned int)buf); compDecoder->EmptyThisBuffer(buf); if (m_eglBuffer && !fillCalled) { m_eglBuffer->nFilledLen = 0; LOG_VERBOSE(LOG_TAG, "Calling FillThisBuffer for the first time."); compEGLRender->FillThisBuffer(m_eglBuffer); fillCalled = true; } return true; }