/* WORKAROUND for DR OMAPS00164744 */ static void goo_ti_aacenc_eos_buffer_flag (GooComponent* self, guint portindex) { g_assert (GOO_IS_COMPONENT (self)); g_assert (portindex >= 0); g_print ("INFORMATION: workaround for OMAPS00164744\n"); GooPort* port = NULL; OMX_PARAM_PORTDEFINITIONTYPE* param = NULL; GooIterator* iter = goo_component_iterate_ports (self); goo_iterator_nth (iter, portindex); port = GOO_PORT (goo_iterator_get_current (iter)); g_assert (port != NULL); goo_port_set_eos (port); param = GOO_PORT_GET_DEFINITION (port); if (param->eDir == OMX_DirOutput) { goo_component_set_done (self); } g_object_unref (G_OBJECT (port)); g_object_unref (G_OBJECT (iter)); return; }
static void omx_output_buffer_cb (GooPort* port, OMX_BUFFERHEADERTYPE* buffer, gpointer data) { g_return_if_fail (buffer->nFlags != OMX_BUFFERFLAG_DATACORRUPT); g_assert (GOO_IS_PORT (port)); g_assert (buffer != NULL); g_assert (GOO_IS_COMPONENT (data)); GooComponent* component = GOO_COMPONENT (data); GstGooEncPcm* self = GST_GOO_ENCPCM ( g_object_get_data (G_OBJECT (data), "gst") ); g_assert (self != NULL); { process_output_buffer (self, buffer); if (buffer->nFlags == OMX_BUFFERFLAG_EOS || goo_port_is_eos (port)) { GST_INFO_OBJECT (self, "EOS found in output buffer (%d)", buffer->nFilledLen); goo_component_set_done (self->component); } } GST_INFO_OBJECT (self, ""); 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; }
void gst_goo_buffer_set_data (GstBuffer* buffer, GooComponent* component, OMX_BUFFERHEADERTYPE* omx_buffer) { g_assert (GST_IS_GOO_BUFFER (buffer)); g_assert (GOO_IS_COMPONENT (component)); g_assert (omx_buffer != NULL); g_object_ref (component); GST_GOO_BUFFER (buffer)->omx_buffer = omx_buffer; GST_GOO_BUFFER (buffer)->component = component; GST_BUFFER_DATA (buffer) = omx_buffer->pBuffer + omx_buffer->nOffset; GST_BUFFER_SIZE (buffer) = omx_buffer->nFilledLen; if (GST_CLOCK_TIME_IS_VALID ((guint64) omx_buffer->nTimeStamp)) { GST_BUFFER_TIMESTAMP (buffer) = (guint64) omx_buffer->nTimeStamp; } else { GST_BUFFER_TIMESTAMP (buffer) = GST_CLOCK_TIME_NONE; } GST_BUFFER_DURATION (buffer) = GST_CLOCK_TIME_NONE; return; }
/** * goo_engine_play: * @self: An #GooEngine instance * * Interchange buffers **/ void goo_engine_play (GooEngine* self) { g_assert (GOO_IS_ENGINE (self)); g_assert (GOO_IS_COMPONENT (self->component)); g_assert (self->component->cur_state == OMX_StateExecuting); GOO_OBJECT_DEBUG (self, "playing"); if (self->enginetype == GOO_ENGINE_FILTER) { /* a filter must has an input and an output port */ g_assert (self->outstream != NULL && self->instream != NULL); } else if (self->enginetype == GOO_ENGINE_SINK) { /* a sink must has an input port */ g_assert (self->instream != NULL); // g_assert (self->outstream == NULL && self->instream != NULL); } else if (self->enginetype == GOO_ENGINE_SRC) { /* a src must has an output port */ g_assert (self->outstream != NULL); // g_assert (self->outstream != NULL && self->instream == NULL); } else { g_assert (self->enginetype != GOO_ENGINE_UNKNOWN); } if (self->enginetype == GOO_ENGINE_SINK || self->enginetype == GOO_ENGINE_FILTER) { GOO_OBJECT_INFO (self, "inport loop"); while (!goo_port_is_eos (self->inport)) { goo_engine_process_input (self); } } else if (self->enginetype == GOO_ENGINE_SRC) { GOO_OBJECT_INFO (self, "outport loop"); while (!goo_port_is_eos (self->outport)) { goo_engine_process_output (self); } } GOO_OBJECT_INFO (self, "Waiting for done..."); goo_component_wait_for_done (self->component); g_print ("\tInput buffers count: %d\n", self->incount); g_print ("\tOutput buffers count: %d\n", self->outcount); return; }
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 goo_engine_outport_cb (GooPort* port, OMX_BUFFERHEADERTYPE* buffer, gpointer data) { g_assert (GOO_IS_PORT (port)); g_assert (buffer != NULL); g_assert (GOO_IS_COMPONENT (data)); GooComponent* component = GOO_COMPONENT (data); GooEngine* self = GOO_ENGINE ( g_object_get_data (G_OBJECT (component), "engine") ); g_assert (self->outstream != NULL); if (buffer->nFilledLen <= 0 && (buffer->nFlags & OMX_BUFFERFLAG_EOS) != 0x1) { GOO_OBJECT_ERROR (self, "Empty buffer received!!"); } if (buffer->nFilledLen > 0) { GOO_OBJECT_DEBUG (self, "%d bytes written", buffer->nFilledLen); fwrite (buffer->pBuffer, 1, buffer->nFilledLen, self->outstream); /* fflush (self->outfile); */ } /* we count the empty buffer only if it have de EOS flag */ if ((buffer->nFilledLen > 0) || ((buffer->nFlags & OMX_BUFFERFLAG_EOS) == 0x1 && buffer->nFilledLen == 0)) { g_atomic_int_inc (&self->outcount); } /* if we assigned the number of buffer to process */ if (self->numbuffers != 0 && self->outcount == self->numbuffers) { goo_port_set_eos (port); } if ((buffer->nFlags & OMX_BUFFERFLAG_EOS) == 0x1 || goo_port_is_eos (port)) { goo_component_set_done (self->component); } goo_component_release_buffer (component, buffer); return; }
/** * goo_engine_new_vop: * @component: An #GooComponent instance in Executing state * @infile: the input file filename, may be %NULL * @outfile: the output file filename, may be %NULL * @vopparser: The vop file which supplies frames * Creates a new #GooEngine instance using VOP parsing * * Return value: a #GooEngine instance **/ GooEngine* goo_engine_new_vop (GooComponent* component, gchar* infile, gchar* outfile, gboolean vopparser) { g_assert (GOO_IS_COMPONENT (component)); GooEngine *self = g_object_new (GOO_TYPE_ENGINE, "component", component, "infile", infile, "outfile", outfile, "vopparser", vopparser, NULL); return self; }
/** * goo_engine_new: * @component: An #GooComponent instance in Executing state * @infile: the input file filename, may be %NULL * @outfile: the output file filename, may be %NULL * * Creates a new #GooEngine instance * * Return value: a #GooEngine instance **/ GooEngine* goo_engine_new (GooComponent* component, gchar* infile, gchar* outfile) { g_assert (GOO_IS_COMPONENT (component)); GOO_DEBUG ("creaing an engine"); GooEngine *self = g_object_new (GOO_TYPE_ENGINE, "component", component, "infile", infile, "outfile", outfile, NULL); return self; }
/** * 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; }
/** * goo_component_factory_add_component: * @self: The #GooComponentFactory instance * @component: The #GooComponent instance you want to add to the factory * * The factory maintains a list of components created by itself. This method * add component to this list. This function is intented to be used only by * the derived component factories. */ void goo_component_factory_add_component (GooComponentFactory* self, GooComponent* component) { g_assert (GOO_IS_COMPONENT_FACTORY (self)); g_assert (GOO_IS_COMPONENT (component)); goo_list_append (self->components, GOO_OBJECT (component)); goo_object_set_owner (GOO_OBJECT (component), GOO_OBJECT (self)); GOO_OBJECT_DEBUG (component, "Refing component %d", G_OBJECT (component)->ref_count); 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_output_buffer_cb (GooPort* port, OMX_BUFFERHEADERTYPE* buffer, gpointer data) { g_return_if_fail (buffer->nFlags != OMX_BUFFERFLAG_DATACORRUPT); g_assert (GOO_IS_PORT (port)); g_assert (buffer != NULL); g_assert (GOO_IS_COMPONENT (data)); GooComponent* component = GOO_COMPONENT (data); GstGooEncArmAac* self = GST_GOO_ENCARMAAC ( g_object_get_data (G_OBJECT (data), "gst") ); g_assert (self != NULL); { if (buffer->nFilledLen <= 0) { GST_INFO_OBJECT (self, "Received an empty buffer!"); goo_component_release_buffer (self->component, buffer); } else { process_output_buffer (self, buffer); } if (buffer->nFlags & OMX_BUFFERFLAG_EOS == 0x1 || goo_port_is_eos (port)) { GST_INFO_OBJECT (self, "EOS found in output buffer (%d)", buffer->nFilledLen); goo_component_set_done (self->component); } } GST_DEBUG_OBJECT (self, ""); return; }
static void goo_engine_inport_cb (GooPort* port, OMX_BUFFERHEADERTYPE* buffer, gpointer data) { g_assert (GOO_IS_PORT (port)); g_assert (buffer != NULL); g_assert (GOO_IS_COMPONENT (data)); GooComponent* component = GOO_COMPONENT (data); GooEngine* self = GOO_ENGINE ( g_object_get_data (G_OBJECT (component), "engine") ); g_assert (self->instream != NULL); guint r; guint read_bytes; read_bytes = goo_engine_get_buffer_len (self, port); r = fread (buffer->pBuffer, 1, read_bytes, self->instream); GOO_OBJECT_DEBUG (self, "%d bytes read", r); if (read_bytes == 0 || feof (self->instream)) { /* set EOS flag */ buffer->nFlags |= OMX_BUFFERFLAG_EOS; if (self->eosevent == TRUE) { goo_component_set_done (self->component); } } buffer->nFilledLen = (r >= 0) ? r : 0; return; }
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; }