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); }
/* protected helper method which can be used by derived classes: */ GstFlowReturn gst_omx_base_src_create_from_port (GstOmxBaseSrc *self, GOmxPort *out_port, GstBuffer **ret_buf) { GOmxCore *gomx; GstFlowReturn ret = GST_FLOW_OK; gomx = self->gomx; GST_LOG_OBJECT (self, "begin"); if (out_port->enabled) { if (G_UNLIKELY (gomx->omx_state == OMX_StateIdle)) { GST_INFO_OBJECT (self, "omx: play"); g_omx_core_start (gomx); } if (G_UNLIKELY (gomx->omx_state != OMX_StateExecuting)) { GST_ERROR_OBJECT (self, "Whoa! very wrong"); ret = GST_FLOW_ERROR; goto beach; } while (out_port->enabled) { gpointer obj = g_omx_port_recv (out_port); if (G_UNLIKELY (!obj)) { ret = GST_FLOW_ERROR; break; } if (G_LIKELY (GST_IS_BUFFER (obj))) { GstBuffer *buf = GST_BUFFER (obj); if (G_LIKELY (GST_BUFFER_SIZE (buf) > 0)) { PRINT_BUFFER (self, buf); *ret_buf = buf; break; } } else if (GST_IS_EVENT (obj)) { GST_INFO_OBJECT (self, "got eos"); g_omx_core_set_done (gomx); break; } } } if (!out_port->enabled) { GST_WARNING_OBJECT (self, "done"); ret = GST_FLOW_UNEXPECTED; } beach: GST_LOG_OBJECT (self, "end"); return ret; }