static void goo_engine_chain (GooEngine* self) { g_assert (GOO_IS_ENGINE (self)); g_assert (GOO_IS_COMPONENT (self->component)); gboolean input_processed = FALSE; OMX_BUFFERHEADERTYPE* buffer = NULL; while (!input_processed && !goo_component_is_done (self->component)) { /* OUTPUT PROCESSING */ if (G_LIKELY (self->outport) && !goo_port_is_tunneled (self->outport) && !goo_port_is_eos (self->outport)) { while ((buffer = goo_port_try_grab_buffer (self->outport)) != NULL) { GOO_OBJECT_DEBUG (self, "popt output buffer: 0x%x", buffer); goo_port_process_buffer (self->outport, buffer, self->component); goo_component_release_buffer (self->component, buffer); } } /* INPUT PROCESSING */ if (G_LIKELY (self->inport) && !goo_port_is_tunneled (self->inport) && !goo_port_is_eos (self->inport)) { if ((buffer = goo_port_try_grab_buffer (self->inport)) != NULL) { GOO_OBJECT_DEBUG (self, "popt input buffer: 0x%x", buffer); goo_port_process_buffer (self->inport, buffer, self); goo_component_release_buffer (self->component, buffer); input_processed = TRUE; } } } return; }
static void omx_start (GstGooEncPcm* self) { g_assert (self != NULL); g_assert (self->component != NULL); if (!goo_port_is_tunneled (self->inport)) { goo_port_set_process_buffer_function (self->outport, omx_output_buffer_cb); } if (goo_component_get_state (self->component) == OMX_StateLoaded) { omx_sync (self); GST_INFO_OBJECT (self, "going to idle"); goo_component_set_state_idle (self->component); } if (goo_component_get_state (self->component) == OMX_StateIdle) { GST_INFO_OBJECT (self, "going to executing"); goo_component_set_state_executing (self->component); } return; }
static void goo_engine_process_input (GooEngine* self) { g_assert (GOO_IS_ENGINE (self)); g_assert (GOO_IS_COMPONENT (self->component)); g_return_if_fail (G_LIKELY (self->inport)); if (goo_port_is_tunneled (self->inport) || goo_port_is_eos (self->inport)) { return; } OMX_BUFFERHEADERTYPE* buffer = NULL; buffer = goo_port_grab_buffer (self->inport); GOO_OBJECT_DEBUG (self, "popt input buffer: 0x%x", buffer); goo_engine_inport_cb (self->inport, buffer, self->component); /* goo_port_process_buffer (self->inport, buffer, self); */ g_atomic_int_inc (&self->incount); goo_component_release_buffer (self->component, buffer); return; }
/** * gst_goo_filter_outport_buffer: * @port: A #GooPort instance * @buffer: An #OMX_BUFFERHEADERTYPE pointer * @data: A pointer to extra data * * This function is a generic callback for a libgoo's output port and push * a new GStreamer's buffer. * * This method can be reused in derived classes. **/ void gst_goo_filter_outport_buffer (GooPort* port, OMX_BUFFERHEADERTYPE* buffer, gpointer data) { g_return_if_fail (buffer->nFlags != OMX_BUFFERFLAG_DATACORRUPT); GST_DEBUG ("Enter"); g_assert (GOO_IS_PORT (port)); g_assert (buffer != NULL); g_assert (GOO_IS_COMPONENT (data)); GooComponent* component = GOO_COMPONENT (data); GstGooFilter* self = GST_GOO_FILTER (g_object_get_data (G_OBJECT (data), "gst")); g_assert (self != NULL); GstGooFilterPrivate* priv = GST_GOO_FILTER_GET_PRIVATE (self); GstBuffer* gst_buffer = gst_goo_buffer_new (); gst_goo_buffer_set_data (gst_buffer, component, buffer); priv->outcount++; #if 0 if (goo_port_is_tunneled (self->inport)) { GST_DEBUG_OBJECT (self, "sem up"); gst_goo_sem_up (self->dasfsrc_sem); } #endif /** FIXME GStreamer should not insert the header. OMX component should take * care of it. Remove this function upon resolution of DR OMAPS00140835 and * OMAPS00140836 **/ gst_buffer = gst_goo_filter_insert_header (self, gst_buffer, priv->outcount); gst_goo_filter_timestamp_buffer (self, gst_buffer, buffer); GST_BUFFER_OFFSET (gst_buffer) = priv->outcount; gst_buffer_set_caps (gst_buffer, GST_PAD_CAPS (self->srcpad)); gst_pad_push (self->srcpad, gst_buffer); if (buffer->nFlags == OMX_BUFFERFLAG_EOS || goo_port_is_eos (port) || gst_goo_filter_is_last_dasf_buffer (self, priv->outcount)) { GST_INFO ("EOS flag found in output buffer (%d)", buffer->nFilledLen); goo_component_set_done (self->component); } return; }
/* output */ { GooIterator* iter = goo_component_iterate_output_ports (component); goo_iterator_nth (iter, 0); GooPort* port = GOO_PORT (goo_iterator_get_current (iter)); g_assert (port != NULL); GOO_PORT_GET_DEFINITION (port)->nBufferSize = OUTPUT_BUFFERSIZE; GOO_PORT_GET_DEFINITION (port)->nBufferCountActual = OUTPUT_NUM_BUFFERS; GOO_PORT_GET_DEFINITION (port)->format.audio.eEncoding = OMX_AUDIO_CodingPCM; g_object_unref (iter); g_object_unref (port); } return; } #if 0 /* i think it is not necessary now */ static void goo_ti_mp3dec_release_buffer (GooComponent* self, OMX_BUFFERHEADERTYPE* buffer) { g_assert (GOO_IS_COMPONENT (self)); g_assert (buffer != NULL); g_assert (self->cur_state == OMX_StateExecuting || self->cur_state == OMX_StateIdle); GooPort* port = GOO_PORT (g_object_ref (buffer->pAppPrivate)); if (goo_port_is_eos (port) || goo_port_is_tunneled (port)) { g_object_unref (port); return; } if ((buffer->nFlags & OMX_BUFFERFLAG_EOS) == 0x1) { GOO_OBJECT_INFO (port, "eos found!"); goo_port_set_eos (port); } /* We should always push the EOS buffer */ GOO_OBJECT_NOTICE (self, "OMX_EmptyThisBuffer, 0x%x", buffer); if (self->cur_state != OMX_StateIdle) { GOO_OBJECT_LOCK (self); GOO_RUN ( OMX_EmptyThisBuffer (self->handle, buffer) ); GOO_OBJECT_UNLOCK (self); } else { g_print("INFORMATION (workaround): Implementing workaround " "for DR OMAPS00143083\n"); } g_object_unref (port); GOO_OBJECT_DEBUG (self, ""); return; }
static void omx_sync (GstGooEncArmAac* self) { g_assert (self != NULL); g_assert (self->component != NULL); if (!goo_port_is_tunneled (self->inport)) { goo_port_set_process_buffer_function (self->outport, omx_output_buffer_cb); } else { g_object_set (self->component, "bitrate-mode", self->bitratemode, NULL); } GST_INFO_OBJECT (self, ""); return; }
static void omx_wait_for_done (GstGooEncPcm* self) { g_assert (self != NULL); OMX_BUFFERHEADERTYPE* omx_buffer = NULL; OMX_PARAM_PORTDEFINITIONTYPE* param = NULL; param = GOO_PORT_GET_DEFINITION (self->inport); int omxbufsiz = param->nBufferSize; int avail = gst_goo_adapter_available (self->adapter); if (goo_port_is_tunneled (self->inport)) { GST_INFO_OBJECT (self, "Tunneled Input port: Setting done"); goo_component_set_done (self->component); return; } if (avail < omxbufsiz && avail >= 0) { GST_DEBUG_OBJECT (self, "Sending an EOS buffer"); goo_component_send_eos (self->component); } else { /* For some reason the adapter didn't extract all possible buffers */ g_assert_not_reached (); } gst_goo_adapter_clear (self->adapter); GST_INFO_OBJECT (self, "Waiting for done signal"); goo_component_wait_for_done (self->component); return; }
static GstFlowReturn gst_goo_encpcm_chain (GstPad* pad, GstBuffer* buffer) { GstGooEncPcm* self = GST_GOO_ENCPCM (gst_pad_get_parent (pad)); guint omxbufsiz = GOO_PORT_GET_DEFINITION (self->inport)->nBufferSize; GstFlowReturn ret; if (self->rate == 0 || self->channels == 0 || self->component->cur_state != OMX_StateExecuting) { goto not_negotiated; } if (goo_port_is_tunneled (self->inport)) { GST_DEBUG_OBJECT (self, "DASF Source"); OMX_BUFFERHEADERTYPE* omxbuf = NULL; omxbuf = goo_port_grab_buffer (self->outport); ret = process_output_buffer (self, omxbuf); return ret; } /* discontinuity clears adapter, FIXME, maybe we can set some * encoder flag to mask the discont. */ if (GST_BUFFER_FLAG_IS_SET (buffer, GST_BUFFER_FLAG_DISCONT)) { gst_goo_adapter_clear (self->adapter); self->ts = 0; } /* take latest timestamp, FIXME timestamp is the one of the * first buffer in the adapter. */ if (GST_BUFFER_TIMESTAMP_IS_VALID (buffer)) { self->ts = GST_BUFFER_TIMESTAMP (buffer); } ret = GST_FLOW_OK; GST_DEBUG_OBJECT (self, "Pushing a GST buffer to adapter (%d)", GST_BUFFER_SIZE (buffer)); gst_goo_adapter_push (self->adapter, buffer); /* Collect samples until we have enough for an output frame */ while (gst_goo_adapter_available (self->adapter) >= omxbufsiz) { GST_DEBUG_OBJECT (self, "Popping an OMX buffer"); OMX_BUFFERHEADERTYPE* omxbuf; omxbuf = goo_port_grab_buffer (self->inport); gst_goo_adapter_peek (self->adapter, omxbufsiz, omxbuf); omxbuf->nFilledLen = omxbufsiz; gst_goo_adapter_flush (self->adapter, omxbufsiz); goo_component_release_buffer (self->component, omxbuf); } GST_DEBUG_OBJECT (self, ""); return ret; /* ERRORS */ not_negotiated: { GST_ELEMENT_ERROR (self, STREAM, TYPE_NOT_FOUND, (NULL), ("unknown type")); return GST_FLOW_NOT_NEGOTIATED; } }
static GstFlowReturn gst_goo_filter_chain (GstPad* pad, GstBuffer* buffer) { GST_LOG (""); GstGooFilter* self = GST_GOO_FILTER (gst_pad_get_parent (pad)); GstGooFilterPrivate* priv = GST_GOO_FILTER_GET_PRIVATE (self); GstGooAdapter* adapter = self->adapter; GstFlowReturn ret = GST_FLOW_OK; static OMX_S64 omx_normalize_timestamp; GstClockTime timestamp = GST_BUFFER_TIMESTAMP (buffer); if (priv->incount == 0) { omx_normalize_timestamp = (gint64)timestamp / CONVERSION; } if (goo_port_is_tunneled (self->inport)) { /* shall we send a ghost buffer here ? */ GST_INFO ("port is tunneled"); ret = GST_FLOW_OK; GST_DEBUG_OBJECT (self, "Buffer timestamp: time %" GST_TIME_FORMAT, GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (buffer))); GST_DEBUG_OBJECT (self, "Buffer duration: %" GST_TIME_FORMAT, GST_TIME_ARGS (GST_BUFFER_DURATION (buffer))); GST_DEBUG_OBJECT (self, "Pushing buffer to next element. Size =%d", GST_BUFFER_SIZE (buffer)); /** FIXME GStreamer should not insert the header. OMX component should take * care of it. Remove this function upon resolution of DR OMAPS00140835 and * OMAPS00140836 **/ priv->outcount++; buffer = gst_goo_filter_insert_header (self, buffer, priv->outcount); gst_buffer_set_caps (buffer, GST_PAD_CAPS (self->srcpad)); gst_pad_push (self->srcpad, buffer); goto done; } if (goo_port_is_eos (self->inport)) { GST_INFO ("port is eos"); ret = GST_FLOW_UNEXPECTED; goto fail; } /** @todo GstGooAdapter! */ if (GST_BUFFER_FLAG_IS_SET (buffer, GST_BUFFER_FLAG_DISCONT)) { gst_goo_adapter_clear (adapter); } if (priv->incount == 0 && goo_component_get_state (self->component) == OMX_StateLoaded) { /** Some filters require header processing, apended to the first buffer **/ buffer = gst_goo_filter_codec_data_processing (self, GST_BUFFER (buffer)); /** Todo: Use the gst_caps_fixatecaps_func to make this cleaner **/ if (!gst_goo_filter_check_fixed_src_caps (self)) return GST_FLOW_NOT_NEGOTIATED; /** Remove gst_goo_filter_check_fixed_src_caps function when fixed **/ g_object_set (self->inport, "buffercount", priv->num_input_buffers, NULL); g_object_set (self->outport, "buffercount", priv->num_output_buffers, NULL); GST_INFO ("going to idle"); goo_component_set_state_idle (self->component); GST_INFO ("going to executing"); goo_component_set_state_executing (self->component); } /** Function to perform post buffering processing **/ buffer = gst_goo_filter_extra_buffer_processing (self, GST_BUFFER (buffer)); gst_goo_adapter_push (adapter, buffer); if (self->component->cur_state != OMX_StateExecuting) { goto done; } int omxbufsiz; if (priv->process_mode == STREAMMODE) omxbufsiz = GOO_PORT_GET_DEFINITION (self->inport)->nBufferSize; else omxbufsiz = GST_BUFFER_SIZE (buffer); while (gst_goo_adapter_available (adapter) >= omxbufsiz && ret == GST_FLOW_OK && omxbufsiz != 0) { GST_DEBUG ("Adapter available =%d omxbufsiz = %d", gst_goo_adapter_available (adapter), omxbufsiz); OMX_BUFFERHEADERTYPE* omx_buffer; omx_buffer = goo_port_grab_buffer (self->inport); GST_DEBUG ("memcpy to buffer %d bytes", omxbufsiz); gst_goo_adapter_peek (adapter, omxbufsiz, omx_buffer); omx_buffer->nFilledLen = omxbufsiz; gst_goo_adapter_flush (adapter, omxbufsiz); /* transfer timestamp to openmax */ { GST_DEBUG_OBJECT (self, "checking timestamp: time %" GST_TIME_FORMAT, GST_TIME_ARGS (timestamp)); if (GST_CLOCK_TIME_IS_VALID (timestamp)) { gint64 buffer_ts = (gint64)timestamp; omx_buffer->nTimeStamp = (OMX_S64)buffer_ts / CONVERSION; omx_buffer->nTimeStamp = omx_buffer->nTimeStamp - omx_normalize_timestamp; } else GST_WARNING_OBJECT (self, "Invalid timestamp!"); } priv->incount++; goo_component_release_buffer (self->component, omx_buffer); ret = GST_FLOW_OK; } if (goo_port_is_tunneled (self->outport)) { /** @todo send a ghost buffer */ GstBuffer *ghost_buffer = (GstBuffer*) gst_ghost_buffer_new (); GST_BUFFER_TIMESTAMP (ghost_buffer) = timestamp; gst_pad_push (self->srcpad, ghost_buffer); } goto done; fail: gst_goo_adapter_clear (adapter); done: gst_object_unref (self); gst_buffer_unref (buffer); return ret; }
static void gst_goo_filter_wait_for_done (GstGooFilter* self) { g_assert (self != NULL); GstGooFilterPrivate* priv = GST_GOO_FILTER_GET_PRIVATE (self); /* flushing the last buffers in adapter */ OMX_BUFFERHEADERTYPE* omx_buffer; OMX_PARAM_PORTDEFINITIONTYPE* param = GOO_PORT_GET_DEFINITION (self->inport); GstGooAdapter* adapter = self->adapter; int omxbufsiz = param->nBufferSize; int avail = gst_goo_adapter_available (adapter); if (goo_port_is_tunneled (self->inport)) { GST_INFO ("Input port is tunneled: Setting done"); goo_component_set_done (self->component); return; } if (avail < omxbufsiz && avail > 0) { GST_INFO ("Marking EOS buffer"); omx_buffer = goo_port_grab_buffer (self->inport); GST_DEBUG ("Peek to buffer %d bytes", avail); gst_goo_adapter_peek (adapter, avail, omx_buffer); omx_buffer->nFilledLen = avail; /* let's send the EOS flag right now */ omx_buffer->nFlags = OMX_BUFFERFLAG_EOS; /** @todo timestamp the buffers */ priv->incount++; goo_component_release_buffer (self->component, omx_buffer); } else if (avail == 0) { GST_DEBUG ("Sending empty buffer with EOS flag in it"); goo_component_send_eos (self->component); } else { /* For some reason the adapter didn't extract all possible buffers */ GST_ERROR ("Adapter algorithm error!"); goo_component_send_eos (self->component); } gst_goo_adapter_clear (adapter); if (goo_port_is_tunneled (self->outport)) { GST_INFO ("Outport is tunneled: Setting done"); goo_component_set_done (self->component); } else { GST_INFO ("Waiting for done signal"); goo_component_wait_for_done (self->component); } return; }
static GstStateChangeReturn gst_goo_encjpeg_change_state (GstElement* element, GstStateChange transition) { GST_LOG (""); GstGooEncJpeg* self = GST_GOO_ENCJPEG (element); GstStateChange result; g_assert (self->component != NULL); g_assert (self->inport != NULL); g_assert (self->outport != NULL); switch (transition) { case GST_STATE_CHANGE_NULL_TO_READY: break; case GST_STATE_CHANGE_READY_TO_PAUSED: { GstGooEncJpegPrivate* priv = GST_GOO_ENCJPEG_GET_PRIVATE (self); priv->num_input_buffers = NUM_INPUT_BUFFERS_DEFAULT; priv->num_output_buffers = NUM_OUTPUT_BUFFERS_DEFAULT; priv->incount = 0; priv->outcount = 0; priv->quality = QUALITY_DEFAULT; priv->colorformat = COLOR_FORMAT_DEFAULT; priv->width = WIDTH_DEFAULT; priv->height = HEIGHT_DEFAULT; priv->omxbufsiz = 0; break; } case GST_STATE_CHANGE_PAUSED_TO_PLAYING: GST_OBJECT_LOCK (self); if (goo_component_get_state (self->component) == OMX_StatePause) { goo_component_set_state_executing (self->component); } GST_OBJECT_UNLOCK (self); break; default: break; } result = GST_ELEMENT_CLASS (parent_class)->change_state (element, transition); switch (transition) { case GST_STATE_CHANGE_PLAYING_TO_PAUSED: GST_OBJECT_LOCK (self); goo_component_set_state_pause (self->component); GST_OBJECT_UNLOCK (self); break; case GST_STATE_CHANGE_PAUSED_TO_READY: if ( ! (goo_port_is_tunneled (self->inport)) ) { omx_stop (self); } break; case GST_STATE_CHANGE_READY_TO_NULL: break; default: break; } return result; }
static GstFlowReturn gst_goo_encjpeg_chain (GstPad* pad, GstBuffer* buffer) { GST_LOG (""); GstGooEncJpeg* self = GST_GOO_ENCJPEG (gst_pad_get_parent (pad)); GstGooEncJpegPrivate* priv = GST_GOO_ENCJPEG_GET_PRIVATE (self); GstFlowReturn ret = GST_FLOW_OK; GstGooAdapter* adapter = self->adapter; OMX_BUFFERHEADERTYPE* omx_buffer = NULL; GstClockTime timestamp, duration; guint64 offset, offsetend; GstBuffer* outbuf = NULL; if (goo_port_is_tunneled (self->inport)) { GST_INFO ("Inport is tunneled"); ret = GST_FLOW_OK; priv->incount++; goto process_output; } if (goo_port_is_eos (self->inport)) { GST_INFO ("port is eos"); ret = GST_FLOW_UNEXPECTED; goto fail; } if (self->component->cur_state != OMX_StateExecuting) { goto fail; } /* let's copy the timestamp meta data */ timestamp = GST_BUFFER_TIMESTAMP (buffer); duration = GST_BUFFER_DURATION (buffer); offset = GST_BUFFER_OFFSET (buffer); offsetend = GST_BUFFER_OFFSET_END (buffer); if (GST_IS_GOO_BUFFER (buffer) && goo_port_is_my_buffer (self->inport, GST_GOO_BUFFER (buffer)->omx_buffer)) { GST_INFO ("My own OMX buffer"); priv->incount++; gst_buffer_unref (buffer); /* let's push the buffer to omx */ ret = GST_FLOW_OK; } else if (GST_IS_GOO_BUFFER (buffer) && !goo_port_is_my_buffer (self->inport, GST_GOO_BUFFER (buffer)->omx_buffer)) { GST_INFO ("Other OMX buffer"); if (GST_BUFFER_SIZE (buffer) != priv->omxbufsiz) { GST_ELEMENT_ERROR (self, STREAM, FORMAT, ("Frame is incomplete (%u!=%u)", GST_BUFFER_SIZE (buffer), priv->omxbufsiz), ("Frame is incomplete (%u!=%u)", GST_BUFFER_SIZE (buffer), priv->omxbufsiz)); ret = GST_FLOW_ERROR; } omx_buffer = goo_port_grab_buffer (self->inport); memcpy (omx_buffer->pBuffer, GST_BUFFER_DATA (buffer), priv->omxbufsiz); omx_buffer->nFilledLen = priv->omxbufsiz; priv->incount++; goo_component_release_buffer (self->component, omx_buffer); gst_buffer_unref (buffer); ret = GST_FLOW_OK; } else { if (GST_BUFFER_FLAG_IS_SET (buffer, GST_BUFFER_FLAG_DISCONT)) { gst_goo_adapter_clear (adapter); } GST_LOG ("size = %d bytes", GST_BUFFER_SIZE (buffer)); gst_goo_adapter_push (adapter, buffer); guint tmp = priv->incount; while (gst_goo_adapter_available (adapter) >= priv->omxbufsiz && ret == GST_FLOW_OK) { GST_DEBUG ("Pushing data to OMX"); OMX_BUFFERHEADERTYPE* omx_buffer; omx_buffer = goo_port_grab_buffer (self->inport); gst_goo_adapter_peek (adapter, priv->omxbufsiz, omx_buffer); omx_buffer->nFilledLen = priv->omxbufsiz; gst_goo_adapter_flush (adapter, priv->omxbufsiz); priv->incount++; goo_component_release_buffer (self->component, omx_buffer); ret = GST_FLOW_OK; } if (tmp == priv->incount) { goto done; } } process_output: if (goo_port_is_tunneled (self->outport)) { outbuf = gst_ghost_buffer_new (); GST_BUFFER_FLAG_SET (outbuf, GST_BUFFER_FLAG_READONLY); GST_BUFFER_DATA (outbuf) = NULL; GST_BUFFER_SIZE (outbuf) = 0; GST_BUFFER_TIMESTAMP (outbuf) = timestamp; GST_BUFFER_DURATION (outbuf) = duration; GST_BUFFER_OFFSET (outbuf) = offset; GST_BUFFER_OFFSET_END (outbuf) = offsetend; gst_buffer_set_caps (outbuf, GST_PAD_CAPS (self->srcpad)); gst_pad_push (self->srcpad, outbuf); goto done; } GST_DEBUG ("Poping out buffer from OMX"); omx_buffer = goo_port_grab_buffer (self->outport); if (omx_buffer->nFilledLen <= 0) { ret = GST_FLOW_ERROR; goto done; } if (gst_pad_alloc_buffer (self->srcpad, priv->outcount, omx_buffer->nFilledLen, GST_PAD_CAPS (self->srcpad), &outbuf) == GST_FLOW_OK) { priv->outcount++; /* if the buffer is a goo buffer of the peer element */ if (GST_IS_GOO_BUFFER (outbuf)) { GST_INFO ("It is a OMX buffer!"); memcpy (GST_GOO_BUFFER (outbuf)->omx_buffer->pBuffer, omx_buffer->pBuffer, omx_buffer->nFilledLen); GST_GOO_BUFFER (outbuf)->omx_buffer->nFilledLen = omx_buffer->nFilledLen; GST_GOO_BUFFER (outbuf)->omx_buffer->nFlags = omx_buffer->nFlags; GST_GOO_BUFFER (outbuf)->omx_buffer->nTimeStamp = GST2OMX_TIMESTAMP (timestamp); goo_component_release_buffer (self->component, omx_buffer); } else { /* @fixme! */ /* we do this because there is a buffer extarbation * when a filesink is used. * Maybe using multiple buffers it could be solved. */ memcpy (GST_BUFFER_DATA (outbuf), omx_buffer->pBuffer, omx_buffer->nFilledLen); goo_component_release_buffer (self->component, omx_buffer); /* gst_buffer_unref (outbuf); */ /* outbuf = GST_BUFFER (gst_goo_buffer_new ()); */ /* gst_goo_buffer_set_data (outbuf, */ /* self->component, */ /* omx_buffer); */ } GST_BUFFER_TIMESTAMP (outbuf) = timestamp; GST_BUFFER_DURATION (outbuf) = duration; GST_BUFFER_OFFSET (outbuf) = offset; GST_BUFFER_OFFSET_END (outbuf) = offsetend; gst_buffer_set_caps (outbuf, GST_PAD_CAPS (self->srcpad)); g_signal_emit (G_OBJECT (self), gst_goo_encjpeg_signals[FRAME_ENCODED], 0); ret = gst_pad_push (self->srcpad, outbuf); if (omx_buffer->nFlags & OMX_BUFFERFLAG_EOS || goo_port_is_eos (self->outport)) { GST_INFO ("EOS flag found in output buffer (%d)", omx_buffer->nFilledLen); goo_component_set_done (self->component); } goto done; } else { ret = GST_FLOW_ERROR; goto done; } fail: gst_buffer_unref (buffer); gst_goo_adapter_clear (adapter); done: gst_object_unref (self); return ret; }
static GooPort* goo_engine_get_port (GooComponent* component, GooEnginePortType porttype) { g_assert (GOO_IS_COMPONENT (component)); GooIterator* iter = NULL; GooPort* port = NULL; if (porttype == PORT_INPUT) { iter = goo_component_iterate_input_ports (component); } else if (porttype == PORT_OUTPUT) { iter = goo_component_iterate_output_ports (component); } else { g_assert_not_reached (); } g_assert (iter != NULL); while (!goo_iterator_is_done (iter)) { port = GOO_PORT (goo_iterator_get_current (iter)); GOO_OBJECT_INFO (port, ""); if (goo_port_is_enabled (port)) { if (!goo_port_is_tunneled (port)) { GOO_OBJECT_INFO (component, "%s = %s", (porttype == PORT_INPUT) ? "input" : "output", goo_object_get_name (GOO_OBJECT (port))); /* we only bind the first untunneled port */ g_object_unref (iter); return port; } else { GooComponent* peer = NULL; peer = goo_component_get_peer_component (component, port); if (peer != NULL) { GooPort* pport = NULL; pport = goo_engine_get_port (peer, porttype); g_object_unref (peer); if (pport != NULL) { g_object_unref (port); g_object_unref (iter); GOO_OBJECT_INFO (component, "%s = %s", (porttype == PORT_INPUT) ? "input" : "output", goo_object_get_name (GOO_OBJECT (port))); return pport; } } } } g_object_unref (port); goo_iterator_next (iter); } g_object_unref (iter); return NULL; }