void g_omx_core_deinit (GOmxCore *core) { if (!core->imp) return; core_for_each_port (core, g_omx_port_free); g_ptr_array_clear (core->ports); if (core->omx_state == OMX_StateLoaded || core->omx_state == OMX_StateInvalid) { if (core->omx_handle) { #ifdef USE_STATIC core->omx_error = OMX_FreeHandle (core->omx_handle); #else core->omx_error = core->imp->sym_table.free_handle (core->omx_handle); #endif GST_DEBUG_OBJECT (core->object, "OMX_FreeHandle(%p) -> %s", core->omx_handle, g_omx_error_to_str (core->omx_error)); core->omx_handle = NULL; } } g_omx_release_imp (core->imp); core->imp = NULL; }
static void omx_setup (GstOmxBaseFilter21 *omx_base) { int i; GOmxCore *gomx; OMX_ERRORTYPE eError = OMX_ErrorNone; OMX_PARAM_BUFFER_MEMORYTYPE memTypeCfg; OMX_PARAM_PORTDEFINITIONTYPE paramPort; OMX_CONFIG_VSWMOSAIC_CREATEMOSAICLAYOUT sMosaic; OMX_CONFIG_VSWMOSAIC_SETBACKGROUNDCOLOR sMosaicBg; OMX_PARAM_VSWMOSAIC_MOSAIC_PERIODICITY sMosaicFPS; GstOmxBaseFilter21 *self; gomx = (GOmxCore *) omx_base->gomx; self = GST_OMX_BASE_FILTER21(omx_base); GST_LOG_OBJECT (self, "begin"); /* set the output cap */ gst_pad_set_caps (self->srcpad, create_src_caps (omx_base)); /* Setting Memory type at input port to Raw Memory */ GST_LOG_OBJECT (self, "Setting input port to Raw memory"); _G_OMX_INIT_PARAM (&memTypeCfg); memTypeCfg.eBufMemoryType = OMX_BUFFER_MEMORY_DEFAULT; for ( i = 0; i < NUM_INPUTS; i++) { memTypeCfg.nPortIndex = omx_base->in_port[i]->port_index; eError = OMX_SetParameter (gomx->omx_handle, OMX_TI_IndexParamBuffMemType, &memTypeCfg); if (eError != OMX_ErrorNone) { return; } } /* Setting Memory type at output port to Raw Memory */ GST_LOG_OBJECT (self, "Setting output port to Raw memory"); memTypeCfg.nPortIndex = omx_base->out_port->port_index; memTypeCfg.eBufMemoryType = OMX_BUFFER_MEMORY_DEFAULT; eError = OMX_SetParameter (gomx->omx_handle, OMX_TI_IndexParamBuffMemType, &memTypeCfg); if (eError != OMX_ErrorNone) { return; } GST_LOG_OBJECT (self, "Setting port definition (input)"); for ( i = 0; i < NUM_INPUTS; i++) { /* set input height/width and color format */ G_OMX_PORT_GET_DEFINITION (omx_base->in_port[i], ¶mPort); paramPort.format.video.nFrameWidth = self->in_width[i]; paramPort.format.video.nFrameHeight = self->in_height[i]; /* swmosaic is connceted to scalar, whose stride is different than width*/ paramPort.format.video.nStride = self->in_stride[i]; paramPort.format.video.eCompressionFormat = OMX_VIDEO_CodingUnused; paramPort.format.video.eColorFormat = OMX_COLOR_FormatYCbYCr; paramPort.nBufferSize = (paramPort.format.video.nStride * paramPort.format.video.nFrameHeight); paramPort.nBufferAlignment = 0; paramPort.bBuffersContiguous = 0; G_OMX_PORT_SET_DEFINITION (omx_base->in_port[i], ¶mPort); g_omx_port_setup (omx_base->in_port[i], ¶mPort); } G_OMX_PORT_GET_DEFINITION (omx_base->out_port, ¶mPort); paramPort.format.video.nFrameWidth = self->out_width; paramPort.format.video.nFrameHeight = self->out_height; paramPort.format.video.eCompressionFormat = OMX_VIDEO_CodingUnused; paramPort.format.video.eColorFormat = OMX_COLOR_FormatYCbYCr; paramPort.nBufferAlignment = 0; paramPort.bBuffersContiguous = 0; paramPort.nBufferCountActual = 4; paramPort.format.video.nStride = self->out_stride; paramPort.nBufferSize = paramPort.format.video.nStride * paramPort.format.video.nFrameHeight; G_OMX_PORT_SET_DEFINITION (omx_base->out_port, ¶mPort); g_omx_port_setup (omx_base->out_port, ¶mPort); _G_OMX_INIT_PARAM (&sMosaic); sMosaic.nPortIndex = OMX_VSWMOSAIC_OUTPUT_PORT_START_INDEX; sMosaic.nOpWidth = self->out_width; /* Width in pixels */ sMosaic.nOpHeight = self->out_height; /* Height in pixels */ sMosaic.nOpPitch = self->out_stride; /* Pitch in bytes */ sMosaic.nNumWindows = 2; sMosaic.sMosaicWinFmt[0].dataFormat = OMX_COLOR_FormatYCbYCr; sMosaic.sMosaicWinFmt[0].nPortIndex = 0; sMosaic.sMosaicWinFmt[0].pitch[0] = self->in_stride[0]; sMosaic.sMosaicWinFmt[0].winStartX = self->x[0]; sMosaic.sMosaicWinFmt[0].winStartY = self->y[0]; sMosaic.sMosaicWinFmt[0].winWidth = self->in_width[0]; sMosaic.sMosaicWinFmt[0].winHeight = self->in_height[0]; sMosaic.sMosaicWinFmt[1].dataFormat = OMX_COLOR_FormatYCbYCr; sMosaic.sMosaicWinFmt[1].nPortIndex = 1; sMosaic.sMosaicWinFmt[1].pitch[0] = self->in_stride[1]; sMosaic.sMosaicWinFmt[1].winStartX = self->x[1]; sMosaic.sMosaicWinFmt[1].winStartY = self->y[1]; sMosaic.sMosaicWinFmt[1].winWidth = self->in_width[1]; sMosaic.sMosaicWinFmt[1].winHeight = self->in_height[1]; eError = OMX_SetConfig (gomx->omx_handle, OMX_TI_IndexConfigVSWMOSAICCreateMosaicLayout, &sMosaic); if (eError != OMX_ErrorNone) { printf("Error during Layout settings\n"); } _G_OMX_INIT_PARAM(&sMosaicBg); sMosaicBg.nPortIndex = OMX_VSWMOSAIC_OUTPUT_PORT_START_INDEX; sMosaicBg.uColor = BG_COLOR; eError = OMX_SetConfig (gomx->omx_handle, OMX_TI_IndexConfigVSWMOSAICSetBackgroundColor, &sMosaicBg); if (eError != OMX_ErrorNone) { printf("Error during background\n"); } // FPS settings didn't work actually #if 1 _G_OMX_INIT_PARAM(&sMosaicFPS); sMosaicFPS.nPortIndex = OMX_VSWMOSAIC_OUTPUT_PORT_START_INDEX; sMosaicFPS.nFps = 60; eError = OMX_SetConfig (gomx->omx_handle, OMX_TI_IndexParamVSWMOSAICMosaicPeriodicity, &sMosaicFPS); if (eError != OMX_ErrorNone) { printf("Error during FPS settings : %s\n",g_omx_error_to_str (eError)); } #endif }
static void output_loop (gpointer data) { GstPad *pad; GOmxCore *gomx; GOmxPort *out_port; GstOmxBaseFilter2 *self; GstFlowReturn ret = GST_FLOW_OK; GstOmxBaseFilter2Class *bclass; pad = data; self = GST_OMX_BASE_FILTER2 (gst_pad_get_parent (pad)); gomx = self->gomx; bclass = GST_OMX_BASE_FILTER2_GET_CLASS (self); GST_LOG_OBJECT (self, "begin"); if (!self->ready) { g_error ("not ready"); return; } out_port = (GOmxPort *)gst_pad_get_element_private(pad); if (G_LIKELY (out_port->enabled)) { gpointer obj = g_omx_port_recv (out_port); if (G_UNLIKELY (!obj)) { GST_WARNING_OBJECT (self, "null buffer: leaving"); ret = GST_FLOW_WRONG_STATE; goto leave; } if (G_LIKELY (GST_IS_BUFFER (obj))) { if (G_UNLIKELY (GST_BUFFER_FLAG_IS_SET (obj, GST_BUFFER_FLAG_IN_CAPS))) { GstCaps *caps = NULL; GstStructure *structure; GValue value = { 0 }; caps = gst_pad_get_negotiated_caps (pad); caps = gst_caps_make_writable (caps); structure = gst_caps_get_structure (caps, 0); g_value_init (&value, GST_TYPE_BUFFER); gst_value_set_buffer (&value, obj); gst_buffer_unref (obj); gst_structure_set_value (structure, "codec_data", &value); g_value_unset (&value); gst_pad_set_caps (pad, caps); } else { GstBuffer *buf = GST_BUFFER (obj); ret = bclass->push_buffer (self, buf); GST_DEBUG_OBJECT (self, "ret=%s", gst_flow_get_name (ret)); // HACK!! Dont care if one of the output pads are not connected ret = GST_FLOW_OK; } } else if (GST_IS_EVENT (obj)) { GST_DEBUG_OBJECT (self, "got eos"); gst_pad_push_event (pad, obj); ret = GST_FLOW_UNEXPECTED; goto leave; } } leave: self->last_pad_push_return = ret; if (gomx->omx_error != OMX_ErrorNone) { GST_DEBUG_OBJECT (self, "omx_error=%s", g_omx_error_to_str (gomx->omx_error)); ret = GST_FLOW_ERROR; } if (ret != GST_FLOW_OK) { GST_INFO_OBJECT (self, "pause task, reason: %s", gst_flow_get_name (ret)); gst_pad_pause_task (pad); } GST_LOG_OBJECT (self, "end"); gst_object_unref (self); }
static OMX_ERRORTYPE EventHandler (OMX_HANDLETYPE omx_handle, OMX_PTR app_data, OMX_EVENTTYPE event, OMX_U32 data_1, OMX_U32 data_2, OMX_PTR event_data) { GOmxCore *core; core = (GOmxCore *) app_data; switch (event) { case OMX_EventCmdComplete: { OMX_COMMANDTYPE cmd; cmd = (OMX_COMMANDTYPE) data_1; GST_DEBUG_OBJECT (core->object, "OMX_EventCmdComplete: %d", cmd); switch (cmd) { case OMX_CommandStateSet: complete_change_state (core, data_2); break; case OMX_CommandFlush: g_sem_up (core->flush_sem); break; case OMX_CommandPortDisable: case OMX_CommandPortEnable: g_sem_up (core->port_sem); default: break; } break; } case OMX_EventBufferFlag: { GST_DEBUG_OBJECT (core->object, "OMX_EventBufferFlag"); if (data_2 & OMX_BUFFERFLAG_EOS) { g_omx_core_set_done (core); } break; } case OMX_EventPortSettingsChanged: { GST_DEBUG_OBJECT (core->object, "OMX_EventPortSettingsChanged"); /** @todo only on the relevant port. */ if (core->settings_changed_cb) { core->settings_changed_cb (core); } break; } case OMX_EventIndexSettingChanged: { GST_DEBUG_OBJECT (core->object, "OMX_EventIndexSettingsChanged"); if (core->index_settings_changed_cb) { core->index_settings_changed_cb (core, data_1, data_2); } break; } case OMX_EventError: { core->omx_error = data_1; GST_ERROR_OBJECT (core->object, "unrecoverable error: %s (0x%lx)", g_omx_error_to_str (data_1), data_1); /* component might leave us waiting for buffers, unblock */ g_omx_core_flush_start (core); /* unlock wait_for_state */ g_mutex_lock (core->omx_state_mutex); g_cond_signal (core->omx_state_condition); g_mutex_unlock (core->omx_state_mutex); break; } #ifdef USE_OMXTICORE case OMX_TI_EventBufferRefCount: { OMX_BUFFERHEADERTYPE *omx_buffer = (OMX_BUFFERHEADERTYPE *)data_1; GOmxPort *port = get_port (core, omx_buffer->nOutputPortIndex); GST_DEBUG_OBJECT (core->object, "unref: omx_buffer=%p, pAppPrivate=%p, pBuffer=%p", omx_buffer, omx_buffer->pAppPrivate, omx_buffer->pBuffer); g_mutex_lock (core->omx_state_mutex); omx_buffer->nFlags |= GST_BUFFERFLAG_UNREF_CHECK; g_mutex_unlock (core->omx_state_mutex); g_omx_port_push_buffer (port, omx_buffer); break; } #endif default: GST_WARNING_OBJECT (core->object, "unhandled event: %d", event); break; } return OMX_ErrorNone; }
void g_omx_core_init (GOmxCore *core) { gchar *library_name=NULL, *component_name=NULL, *component_role=NULL; if (core->omx_handle) return; g_object_get (core->object, "component-role", &component_role, "component-name", &component_name, "library-name", &library_name, NULL); GST_DEBUG_OBJECT (core->object, "loading: %s %s (%s)", component_name, component_role ? component_role : "", library_name); g_return_if_fail (component_name); g_return_if_fail (library_name); core->imp = g_omx_request_imp (library_name); if (!core->imp) return; #ifdef USE_STATIC core->omx_error = core->imp->sym_table.get_handle (&core->omx_handle, (char *) component_name, core, &callbacks); #else core->omx_error = OMX_GetHandle (&core->omx_handle, (char *) component_name, core, &callbacks); #endif GST_DEBUG_OBJECT (core->object, "OMX_GetHandle(&%p) -> %s", core->omx_handle, g_omx_error_to_str (core->omx_error)); g_return_if_fail (core->omx_handle); if (component_role) { OMX_PARAM_COMPONENTROLETYPE param; GST_DEBUG_OBJECT (core->object, "setting component role: %s", component_role); G_OMX_CORE_GET_PARAM (core, OMX_IndexParamStandardComponentRole, ¶m); strcpy((char*)param.cRole, component_role); G_OMX_CORE_SET_PARAM (core, OMX_IndexParamStandardComponentRole, ¶m); g_free (component_role); } g_free (component_name); g_free (library_name); if (!core->omx_error) core->omx_state = OMX_StateLoaded; }