diff --git a/src/gstducatividdec.c b/src/gstducatividdec.c
index 4d43cd4946a97ba84ea5c8dc0e5b291f20d598dd..c3c8737dba0c4bc631210a38bb9acb6aa8377ccf 100644 (file)
--- a/src/gstducatividdec.c
+++ b/src/gstducatividdec.c
+#define USE_DTS_PTS_CODE
/*
* GStreamer
* Copyright (c) 2010, Texas Instruments Incorporated
self->first_out_buffer = TRUE;
/* allocate input buffer and initialize inBufs: */
+ /* FIXME: needed size here has nothing to do with width * height */
self->input_bo = omap_bo_new (self->device,
self->width * self->height, OMAP_BO_WC);
self->input = omap_bo_map (self->input_bo);
self->stride, self->padded_height);
gst_ducati_buffer_priv_set (buf, priv);
+ gst_mini_object_unref (GST_MINI_OBJECT (priv));
}
return priv;
}
}
}
+static void
+gst_ducati_viddec_on_flush (GstDucatiVidDec * self, gboolean eos)
+{
+}
+
static gint
codec_process (GstDucatiVidDec * self, gboolean send, gboolean flush,
GstFlowReturn * flow_ret)
if (err) {
GST_WARNING_OBJECT (self, "err=%d, extendedError=%08x",
err, self->outArgs->extendedError);
+ gst_ducati_log_extended_error_info (self->outArgs->extendedError);
err = VIDDEC3_control (self->codec, XDM_GETSTATUS,
self->dynParams, self->status);
- if (!err) {
+ if (err) {
GST_WARNING_OBJECT (self, "XDM_GETSTATUS: err=%d, extendedError=%08x",
err, self->status->extendedError);
+ gst_ducati_log_extended_error_info (self->status->extendedError);
}
if (flush)
self->outArgs->extendedError, self->status->extendedError);
}
+ /* we now let the codec decide */
+ self->dynParams->newFrameFlag = XDAS_FALSE;
+
+ if (err == XDM_EFAIL)
+ goto skip_outbuf_processing;
+
for (i = 0; i < IVIDEO2_MAX_IO_BUFFERS && self->outArgs->outputID[i]; i++) {
gboolean interlaced;
GST_DEBUG_OBJECT (self, "got buffer: %d %p (%" GST_TIME_FORMAT ")",
i, outbuf, GST_TIME_ARGS (ts));
+#ifdef USE_DTS_PTS_CODE
if (self->ts_may_be_pts) {
if ((self->last_pts != GST_CLOCK_TIME_NONE) && (self->last_pts > ts)) {
GST_DEBUG_OBJECT (self, "detected PTS going backwards, "
self->ts_is_pts = TRUE;
}
}
+#endif
self->last_pts = ts;
if (self->crop)
gst_buffer_set_video_crop (outbuf, self->crop);
- ret = gst_pad_push (self->srcpad, outbuf);
+ ret = klass->push_output (self, outbuf);
if (flow_ret)
*flow_ret = ret;
if (ret != GST_FLOW_OK) {
}
}
+skip_outbuf_processing:
for (i = 0; i < IVIDEO2_MAX_IO_BUFFERS && self->outArgs->freeBufID[i]; i++) {
codec_unlock_outbuf (self, self->outArgs->freeBufID[i]);
}
GST_DEBUG_OBJECT (self, "flush: eos=%d", eos);
+ GST_DUCATIVIDDEC_GET_CLASS (self)->on_flush (self, eos);
+
/* note: flush is synchronized against _chain() to avoid calling
* the codec from multiple threads
*/
GST_PAD_STREAM_LOCK (self->sinkpad);
+#ifdef USE_DTS_PTS_CODE
self->dts_ridx = self->dts_widx = 0;
self->last_dts = self->last_pts = GST_CLOCK_TIME_NONE;
self->ts_may_be_pts = TRUE;
self->ts_is_pts = FALSE;
+#endif
self->wait_keyframe = TRUE;
+ self->in_size = 0;
+ self->needs_flushing = FALSE;
+ self->need_out_buf = TRUE;
if (G_UNLIKELY (self->first_in_buffer)) {
goto out;
memset (&self->outArgs->outputID, 0, sizeof (self->outArgs->outputID));
memset (&self->outArgs->freeBufID, 0, sizeof (self->outArgs->freeBufID));
+ self->dynParams->newFrameFlag = XDAS_TRUE;
+
/* on a flush, it is normal (and not an error) for the last _process() call
* to return an error..
*/
return NULL;
}
+static GstFlowReturn
+gst_ducati_viddec_push_output (GstDucatiVidDec * self, GstBuffer * buf)
+{
+ return gst_pad_push (self->srcpad, buf);
+}
+
static gint
gst_ducati_viddec_handle_error (GstDucatiVidDec * self, gint ret,
gint extended_error, gint status_extended_error)
/* GstElement vmethod implementations */
static gboolean
-gst_ducati_viddec_sink_setcaps (GstPad * pad, GstCaps * caps)
+gst_ducati_viddec_set_sink_caps (GstDucatiVidDec * self, GstCaps * caps)
{
gboolean ret = TRUE;
- GstDucatiVidDec *self = GST_DUCATIVIDDEC (gst_pad_get_parent (pad));
GstDucatiVidDecClass *klass = GST_DUCATIVIDDEC_GET_CLASS (self);
GstStructure *s;
GstCaps *outcaps = NULL;
gint par_width, par_height;
gboolean par_present;
- GST_INFO_OBJECT (self, "setcaps (sink): %" GST_PTR_FORMAT, caps);
-
s = gst_caps_get_structure (caps, 0);
if (!klass->parse_caps (self, s)) {
GST_WARNING_OBJECT (self, "missing required fields");
out:
if (outcaps)
gst_caps_unref (outcaps);
+
+ return ret;
+}
+
+static gboolean
+gst_ducati_viddec_sink_setcaps (GstPad * pad, GstCaps * caps)
+{
+ gboolean ret = TRUE;
+ GstDucatiVidDec *self = GST_DUCATIVIDDEC (gst_pad_get_parent (pad));
+ GstDucatiVidDecClass *klass = GST_DUCATIVIDDEC_GET_CLASS (self);
+
+ GST_INFO_OBJECT (self, "setcaps (sink): %" GST_PTR_FORMAT, caps);
+
+ ret = klass->set_sink_caps (self, caps);
+
gst_object_unref (self);
return ret;
GST_TIME_ARGS (qostime), GST_TIME_ARGS (self->qos_earliest_time), diff,
self->qos_proportion);
- if (klass->drop_frame (self, buf, diff)) {
+ if (klass->can_drop_frame (self, buf, diff)) {
GST_INFO_OBJECT (self, "dropping frame");
return FALSE;
}
}
static gboolean
-gst_ducati_viddec_drop_frame (GstDucatiVidDec * self, GstBuffer * buf,
+gst_ducati_viddec_can_drop_frame (GstDucatiVidDec * self, GstBuffer * buf,
gint64 diff)
{
gboolean is_keyframe = !GST_BUFFER_FLAG_IS_SET (buf,
}
have_out_buf:
- self->in_size = 0;
buf = GST_DUCATIVIDDEC_GET_CLASS (self)->push_input (self, buf);
+#ifdef USE_DTS_PTS_CODE
if (ts != GST_CLOCK_TIME_NONE) {
self->dts_queue[self->dts_widx++ % NDTS] = ts;
/* if next buffer has earlier ts than previous, then the ts
}
self->last_dts = ts;
}
+#endif
if (self->in_size == 0 && outbuf) {
GST_DEBUG_OBJECT (self, "no input, skipping process");
if (err) {
GST_ELEMENT_ERROR (self, STREAM, DECODE, (NULL),
("process returned error: %d %08x", err, self->outArgs->extendedError));
+ gst_ducati_log_extended_error_info (self->outArgs->extendedError);
return GST_FLOW_ERROR;
}
if (ret != GST_FLOW_OK) {
self->first_in_buffer = FALSE;
+ if (self->params->inputDataMode != IVIDEO_ENTIREFRAME) {
+ /* The copy could be avoided by playing with the buffer pointer,
+ but it seems to be rare and for not many bytes */
+ GST_DEBUG_OBJECT (self, "Consumed %d/%d (%d) bytes, %d left",
+ self->outArgs->bytesConsumed, self->in_size,
+ self->inArgs->numBytes,
+ self->in_size - self->outArgs->bytesConsumed);
+ if (self->outArgs->bytesConsumed > 0) {
+ if (self->outArgs->bytesConsumed > self->in_size) {
+ GST_WARNING_OBJECT (self, "Codec claims to have used more bytes than supplied");
+ self->in_size = 0;
+ } else {
+ if (self->outArgs->bytesConsumed < self->in_size) {
+ memmove (self->input, self->input + self->outArgs->bytesConsumed,
+ self->in_size - self->outArgs->bytesConsumed);
+ }
+ self->in_size -= self->outArgs->bytesConsumed;
+ }
+ }
+ } else {
+ self->in_size = 0;
+ }
+
if (self->outArgs->outBufsInUseFlag) {
GST_DEBUG_OBJECT (self, "outBufsInUseFlag set");
self->need_out_buf = FALSE;
goto allocate_buffer;
}
+ if (self->needs_flushing)
+ gst_ducati_viddec_codec_flush (self, FALSE);
+
return GST_FLOW_OK;
}
GST_DEBUG_FUNCPTR (gst_ducati_viddec_allocate_params);
klass->push_input = GST_DEBUG_FUNCPTR (gst_ducati_viddec_push_input);
klass->handle_error = GST_DEBUG_FUNCPTR (gst_ducati_viddec_handle_error);
- klass->drop_frame = GST_DEBUG_FUNCPTR (gst_ducati_viddec_drop_frame);
+ klass->can_drop_frame = GST_DEBUG_FUNCPTR (gst_ducati_viddec_can_drop_frame);
klass->query = GST_DEBUG_FUNCPTR (gst_ducati_viddec_query);
+ klass->push_output = GST_DEBUG_FUNCPTR (gst_ducati_viddec_push_output);
+ klass->on_flush = GST_DEBUG_FUNCPTR (gst_ducati_viddec_on_flush);
+ klass->set_sink_caps = GST_DEBUG_FUNCPTR (gst_ducati_viddec_set_sink_caps);
g_object_class_install_property (gobject_class, PROP_VERSION,
g_param_spec_string ("version", "Version",
@@ -1350,10 +1427,12 @@ gst_ducati_viddec_init (GstDucatiVidDec * self, GstDucatiVidDecClass * klass)
self->interlaced = FALSE;
self->send_crop_event = TRUE;
+#ifdef USE_DTS_PTS_CODE
self->dts_ridx = self->dts_widx = 0;
self->last_dts = self->last_pts = GST_CLOCK_TIME_NONE;
self->ts_may_be_pts = TRUE;
self->ts_is_pts = FALSE;
+#endif
self->pageMemType = XDM_MEMTYPE_TILEDPAGE;