static GstFlowReturn push_buffer (GstOmxBaseFilter2 *self, GstBuffer *buf) { GstFlowReturn ret = GST_FLOW_ERROR; int i; for (i = 0; i< NUM_OUTPUTS; i++) { if (GST_GET_OMXPORT(buf) == self->out_port[i]) { break; } } if (i == NUM_OUTPUTS) return ret; GST_BUFFER_DURATION (buf) = self->duration; if (self->gomx->gen_timestamps == TRUE) { if (GST_CLOCK_TIME_NONE == GST_BUFFER_TIMESTAMP(buf) && GST_CLOCK_TIME_NONE != self->last_buf_timestamp[i] && GST_CLOCK_TIME_NONE != self->duration) { GST_BUFFER_TIMESTAMP(buf) = self->last_buf_timestamp[i] + self->duration; } self->last_buf_timestamp[i] = GST_BUFFER_TIMESTAMP(buf); } PRINT_BUFFER (self, buf); if (self->push_cb) { if (FALSE == self->push_cb (self, buf)) { gst_buffer_unref(buf); return GST_FLOW_OK; } } /** @todo check if tainted */ GST_LOG_OBJECT (self, "begin"); ret = gst_pad_push (self->srcpad[i], buf); GST_LOG_OBJECT (self, "end"); return ret; }
static GstFlowReturn push_buffer (GstOmxBaseFilter21 *self, GstBuffer *buf) { GstFlowReturn ret = GST_FLOW_ERROR; int i; if(GST_GET_OMXPORT(buf) != self->out_port){ return ret; } GST_BUFFER_DURATION (buf) = self->duration; GST_BUFFER_TIMESTAMP(buf) = self->sink_camera_timestamp; GST_DEBUG_OBJECT(self, "timestamp=%" GST_TIME_FORMAT, GST_TIME_ARGS(self->sink_camera_timestamp)); PRINT_BUFFER (self, buf); if (self->push_cb) { if (FALSE == self->push_cb (self, buf)) { gst_buffer_unref(buf); return GST_FLOW_OK; } } /** @todo check if tainted */ ret = gst_pad_push (self->srcpad, buf); return ret; }
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 pad_chain (GstPad *pad, GstBuffer *buf) { GOmxCore *gomx; GOmxPort *in_port; GstOmxBaseFilter21 *self; GstFlowReturn ret = GST_FLOW_OK; int i; static sink_init = 0; int sink_number; static gboolean init_done = FALSE; self = GST_OMX_BASE_FILTER21 (GST_OBJECT_PARENT (pad)); if(strcmp(GST_PAD_NAME(pad), "sink_00") == 0){ sink_number=0; self->sink_camera_timestamp = GST_BUFFER_TIMESTAMP(buf); } else if(strcmp(GST_PAD_NAME(pad), "sink_01") == 0){ sink_number=1; } PRINT_BUFFER (self, buf); gomx = self->gomx; GST_LOG_OBJECT (self, "begin: size=%u, state=%d, sink_number=%d", GST_BUFFER_SIZE (buf), gomx->omx_state, sink_number); /*if (G_LIKELY (gomx->omx_state != OMX_StateExecuting)) { GST_INFO_OBJECT (self, "Begin - Port %d", sink_number); //setup_input_buffer (self, buf, sink_number); //sink_init++; //g_mutex_lock (self->ready_lock); if(init_done == TRUE){ GST_INFO_OBJECT (self, "Init_done"); //g_mutex_unlock(self->ready_lock); } if(init_done == TRUE){ sink_init = 0; init_done = FALSE; } else{ while(sink_init != 2){ usleep(1000); } } }*/ if (G_UNLIKELY (gomx->omx_state == OMX_StateLoaded)) { GST_INFO_OBJECT (self, "omx: prepare"); /** @todo this should probably go after doing preparations. */ if (self->omx_setup) { self->omx_setup (self); } /* enable input port */ for(i=0;i<NUM_INPUTS;i++){ GST_INFO_OBJECT (self,"Enable Port %d",self->in_port[i]->port_index); OMX_SendCommand (gomx->omx_handle, OMX_CommandPortEnable, self->in_port[i]->port_index, NULL); g_sem_down (self->in_port[i]->core->port_sem); } GST_INFO_OBJECT (self,"Enable Port %d",self->out_port->port_index); /* enable output port */ OMX_SendCommand (gomx->omx_handle,OMX_CommandPortEnable, self->out_port->port_index, NULL); g_sem_down (self->out_port->core->port_sem); /* indicate that port is now configured */ setup_ports (self); g_omx_core_prepare (self->gomx); if (gomx->omx_state == OMX_StateIdle) { self->ready = TRUE; //gst_pad_start_task (self->srcpad, output_loop, self->srcpad); } if (gomx->omx_state != OMX_StateIdle) goto out_flushing; GST_INFO_OBJECT (self, "omx: end state Loaded"); } if (G_UNLIKELY (gomx->omx_state == OMX_StateIdle)) { g_omx_core_start (gomx); GST_INFO_OBJECT (self, "Release Port - %d", sink_number); init_done = TRUE; //g_mutex_unlock (self->ready_lock); if (gomx->omx_state != OMX_StateExecuting){ GST_INFO_OBJECT (self, "omx: executing FAILED !"); goto out_flushing; } } if (G_LIKELY (self->in_port[sink_number]->enabled)) { 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_INFO_OBJECT (self, "last_pad_push_return=%d", self->last_pad_push_return); goto out_flushing; } sent = g_omx_port_send (self->in_port[sink_number], 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; } return ret; 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; } }
/* 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; }