diff --git a/src/gstducatividdec.c b/src/gstducatividdec.c
index 94b60431526f15006de1ca0ebb4e546bd0ac35d3..d3880871f9d55f4e4cdfec66e538e750ee5cf1d4 100644 (file)
--- a/src/gstducatividdec.c
+++ b/src/gstducatividdec.c
static void
codec_delete (GstDucatiVidDec * self)
{
+ if (self->pool) {
+ gst_ducati_bufferpool_destroy (self->pool);
+ self->pool = NULL;
+ }
+
if (self->codec) {
VIDDEC3_delete(self->codec);
self->codec = NULL;
return FALSE;
}
-#if 0
- /* not entirely sure why we need to call this here.. just copying omx.. */
- err = VIDDEC3_control(self->codec, XDM_GETBUFINFO, self->dynParams, self->status);
- if (err) {
- GST_ERROR_OBJECT (self, "failed XDM_GETBUFINFO");
- return FALSE;
- }
-#endif
-
self->first_in_buffer = TRUE;
self->first_out_buffer = TRUE;
return TRUE;
}
+static inline GstBuffer *
+codec_bufferpool_get (GstDucatiVidDec * self, GstBuffer * buf)
+{
+ if (G_UNLIKELY (!self->pool)) {
+ GST_DEBUG_OBJECT (self, "creating bufferpool");
+ self->pool = gst_ducati_bufferpool_new (GST_ELEMENT (self),
+ GST_PAD_CAPS (self->srcpad));
+ }
+ return GST_BUFFER (gst_ducati_bufferpool_get (self->pool, buf));
+}
+
static XDAS_Int32
codec_prepare_outbuf (GstDucatiVidDec * self, GstBuffer * buf)
{
uv_type = gst_ducati_get_mem_type (uv_paddr);
if ((y_type < 0) || (uv_type < 0)) {
- return 0;
+ GST_DEBUG_OBJECT (self, "non TILER buffer, fallback to bufferpool");
+ return codec_prepare_outbuf (self, codec_bufferpool_get (self, buf));
}
if (!self->outBufs->numBufs) {
/* verify output buffer type matches what we've already given
* to the codec
*/
- // TODO
+ if ((self->outBufs->descs[0].memType != y_type) ||
+ (self->outBufs->descs[1].memType != uv_type)) {
+ GST_DEBUG_OBJECT (self, "buffer mismatch, fallback to bufferpool");
+ return codec_prepare_outbuf (self, codec_bufferpool_get (self, buf));
+ }
}
self->outBufs->descs[0].buf = (XDAS_Int8 *) y_paddr;
{
GstBuffer *buf = (GstBuffer *) id; // XXX use lookup table
if (buf) {
+ GST_DEBUG_OBJECT (self, "free buffer: %d %p", id, buf);
gst_buffer_unref (buf);
}
}
GstBuffer *outbuf = NULL;
gint i;
+ self->outArgs->outputID[0] = 0;
+ self->outArgs->freeBufID[0] = 0;
+
t = gst_util_get_timestamp ();
err = VIDDEC3_process (self->codec,
self->inBufs, self->outBufs, self->inArgs, self->outArgs);
GST_INFO_OBJECT (self, "%10dns", (gint) (gst_util_get_timestamp () - t));
+
if (err) {
+ GST_WARNING_OBJECT (self, "err=%d, extendedError=%08x",
+ err, self->outArgs->extendedError);
+
+ err = VIDDEC3_control (self->codec, XDM_GETSTATUS,
+ self->dynParams, self->status);
+
+ GST_WARNING_OBJECT (self, "XDM_GETSTATUS: err=%d, extendedError=%08x",
+ err, self->status->extendedError);
+
if (XDM_ISFATALERROR (self->outArgs->extendedError) || flush) {
- return err;
+ /* we are processing for display and it is a non-fatal error, so lets
+ * try to recover.. otherwise return the error
+ */
+ err = XDM_EFAIL;
}
- /* we are processing for display and it is a non-fatal error, so lets
- * try to recover..
- */
- err = XDM_EOK;
}
for (i = 0; self->outArgs->outputID[i]; i++) {
outbuf = codec_get_outbuf (self, self->outArgs->outputID[i]);
if (send) {
+ if (GST_IS_DUCATIBUFFER (outbuf)) {
+ outbuf = gst_ducati_buffer_get (GST_DUCATIBUFFER (outbuf));
+ }
GST_DEBUG_OBJECT (self, "got buffer: %d %p (%" GST_TIME_FORMAT ")",
i, outbuf, GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (outbuf)));
gst_pad_push (self->srcpad, outbuf);
} else {
+ GST_DEBUG_OBJECT (self, "free buffer: %d %p", i, outbuf);
gst_buffer_unref (outbuf);
}
}
GST_DEBUG_OBJECT (self, "flush: eos=%d", eos);
+ /* note: flush is synchronized against _chain() to avoid calling
+ * the codec from multiple threads
+ */
+ GST_PAD_STREAM_LOCK (self->sinkpad);
+
if (G_UNLIKELY (self->first_in_buffer)) {
return TRUE;
}
self->dynParams, self->status);
if (err) {
GST_ERROR_OBJECT (self, "failed XDM_FLUSH");
- return FALSE;
+ goto out;
}
+ self->inBufs->descs[0].bufSize.bytes = 0;
+ self->inArgs->numBytes = 0;
+ self->inArgs->inputID = 0;
+
do {
err = codec_process (self, eos, TRUE);
} while (err != XDM_EFAIL);
- self->first_in_buffer = TRUE;
+ /* on a flush, it is normal (and not an error) for the last _process() call
+ * to return an error..
+ */
+ err = XDM_EOK;
+out:
+ GST_PAD_STREAM_UNLOCK (self->sinkpad);
GST_DEBUG_OBJECT (self, "done");
- return TRUE;
+ return !err;
}
/* GstDucatiVidDec vmethod default implementations */
self->params->maxFrameRate = 30000;
self->params->maxBitRate = 10000000;
- //rv??
-
self->params->dataEndianness = XDM_BYTE;
self->params->forceChromaFormat = XDM_YUV_420SP;
self->params->operatingMode = IVIDEO_DECODE_ONLY;
if (klass->parse_caps (self, s)) {
GstCaps *outcaps;
+ gboolean interlaced = FALSE;
gst_structure_get_fraction (s, "framerate", &frn, &frd);
self->stride = 4096; /* TODO: don't hardcode */
+ gst_structure_get_boolean (s, "interlaced", &interlaced);
+
/* update output/padded sizes:
*/
klass->update_buffer_size (self);
"framerate", GST_TYPE_FRACTION, frn, frd,
NULL);
+ if (interlaced) {
+ gst_caps_set_simple (outcaps, "interlaced", G_TYPE_BOOLEAN, TRUE, NULL);
+ }
+
GST_DEBUG_OBJECT (self, "outcaps: %" GST_PTR_FORMAT, outcaps);
ret = gst_pad_set_caps (self->srcpad, outcaps);
GST_PAD_CAPS (self->srcpad), &outbuf);
if (ret != GST_FLOW_OK) {
- /* TODO: if we had our own buffer class, we could allocate our own
- * output buffer from TILER...
- */
- GST_WARNING_OBJECT (self, "TODO: allocate output TILER buffer");
- return ret;
+ outbuf = codec_bufferpool_get (self, NULL);
+ ret = GST_FLOW_OK;
}
if (G_UNLIKELY (!self->codec)) {
self->in_size = 0;
buf = GST_DUCATIVIDDEC_GET_CLASS (self)->push_input (self, buf);
+
+ if (self->in_size == 0) {
+ GST_DEBUG_OBJECT (self, "no input, skipping process");
+ gst_buffer_unref (outbuf);
+ return GST_FLOW_OK;
+ }
+
self->inArgs->numBytes = self->in_size;
self->inBufs->descs[0].bufSize.bytes = self->in_size;