static GstFlowReturn pad_chain (GstPad *pad, GstBuffer *buf) { GOmxCore *gomx; GOmxPort *in_port; GstOmxBaseFilter2 *self; GstFlowReturn ret = GST_FLOW_OK; int i; self = GST_OMX_BASE_FILTER2 (GST_OBJECT_PARENT (pad)); //printf("INput!!\n"); PRINT_BUFFER (self, buf); gomx = self->gomx; GST_LOG_OBJECT (self, "begin: size=%u, state=%d", GST_BUFFER_SIZE (buf), gomx->omx_state); if (G_UNLIKELY (gomx->omx_state == OMX_StateLoaded)) { g_mutex_lock (self->ready_lock); GST_INFO_OBJECT (self, "omx: prepare"); /** @todo this should probably go after doing preparations. */ if (self->omx_setup) { self->omx_setup (self); } setup_input_buffer (self, buf); setup_ports (self); g_omx_core_prepare (self->gomx); if (gomx->omx_state == OMX_StateIdle) { self->ready = TRUE; for (i = 0; i < NUM_OUTPUTS; i++) gst_pad_start_task (self->srcpad[i], output_loop, self->srcpad[i]); } g_mutex_unlock (self->ready_lock); if (gomx->omx_state != OMX_StateIdle) goto out_flushing; } in_port = self->in_port; if (G_LIKELY (in_port->enabled)) { if (G_UNLIKELY (gomx->omx_state == OMX_StateIdle)) { GST_INFO_OBJECT (self, "omx: play"); g_omx_core_start (gomx); if (gomx->omx_state != OMX_StateExecuting) goto out_flushing; /* send buffer with codec data flag */ if (self->codec_data) { GST_BUFFER_FLAG_SET (self->codec_data, GST_BUFFER_FLAG_IN_CAPS); /* just in case */ g_omx_port_send (in_port, self->codec_data); } } if (G_UNLIKELY (gomx->omx_state != OMX_StateExecuting)) { GST_ERROR_OBJECT (self, "Whoa! very wrong"); } while (TRUE) { gint sent; if (self->last_pad_push_return != GST_FLOW_OK || !(gomx->omx_state == OMX_StateExecuting || gomx->omx_state == OMX_StatePause)) { GST_DEBUG_OBJECT (self, "last_pad_push_return=%d", self->last_pad_push_return); goto out_flushing; } if (self->input_fields_separately) { g_omx_port_send_interlaced_fields (in_port, buf, self->second_field_offset); gst_buffer_unref (buf); break; } sent = g_omx_port_send (in_port, buf); if (G_UNLIKELY (sent < 0)) { ret = GST_FLOW_WRONG_STATE; goto out_flushing; } else if (sent < GST_BUFFER_SIZE (buf)) { GstBuffer *subbuf = gst_buffer_create_sub (buf, sent, GST_BUFFER_SIZE (buf) - sent); gst_buffer_unref (buf); buf = subbuf; } else { gst_buffer_unref (buf); break; } } } else { GST_WARNING_OBJECT (self, "done"); ret = GST_FLOW_UNEXPECTED; } leave: GST_LOG_OBJECT (self, "end"); return ret; /* special conditions */ out_flushing: { const gchar *error_msg = NULL; if (gomx->omx_error) { error_msg = "Error from OpenMAX component"; } else if (gomx->omx_state != OMX_StateExecuting && gomx->omx_state != OMX_StatePause) { error_msg = "OpenMAX component in wrong state"; } if (error_msg) { GST_ELEMENT_ERROR (self, STREAM, FAILED, (NULL), (error_msg)); ret = GST_FLOW_ERROR; } gst_buffer_unref (buf); goto leave; } }
static GstFlowReturn collected_pads(GstCollectPads *pads, GstOmxBaseFilter21 *self) { GSList *item; GstCollectData *collectdata; GstFlowReturn ret = GST_FLOW_OK; GOmxCore *gomx = self->gomx; gint sink_number; GstBuffer *buffers[2]; gboolean eos = FALSE; GST_DEBUG_OBJECT(self, "Collected pads !"); // Collect buffers for( item = pads->data ; item != NULL ; item = item->next ) { collectdata = (GstCollectData *) item->data; //FIXME Use collect data if(strcmp(GST_PAD_NAME(collectdata->pad), "sink_00") == 0){ sink_number=0; } else{ sink_number=1; } buffers[sink_number] = gst_collect_pads_pop(pads, collectdata); if( buffers[sink_number] == NULL ) { eos = TRUE; } } // Detect EOS if( eos == TRUE ) { GST_INFO_OBJECT(self, "EOS"); for( sink_number=0 ; sink_number<2 ; sink_number++ ) { if( buffers[sink_number] ) { gst_buffer_unref(buffers[sink_number]); } } gst_pad_push_event(self->srcpad, gst_event_new_eos()); return GST_FLOW_UNEXPECTED; } // Setup input ports if not done yet if (G_LIKELY (gomx->omx_state != OMX_StateExecuting)) { for( sink_number=0 ; sink_number<2 ; sink_number++ ) { GST_INFO_OBJECT(self, "Setup port %d", sink_number); setup_input_buffer (self, buffers[sink_number], sink_number); } } // Call chain foreach buffer for( sink_number=0 ; sink_number<2 ; sink_number++ ) { ret = pad_chain(self->sinkpad[sink_number], buffers[sink_number]); } // Call output_loop after pad_chain output_loop(self->srcpad); return ret; }