]> Gitweb @ Texas Instruments - Open Source Git Repositories - git.TI.com/gitweb - glsdk/gst-plugin-ducati.git/blobdiff - src/gstducatividdec.c
ducatividdec: add a comment about a fishy, but OK, bit of code
[glsdk/gst-plugin-ducati.git] / src / gstducatividdec.c
index 198b69ecb31382915f9fc9fdf106db8fe38ed46f..afb36749a5c47048a6f095e1c685cd4c4beb2f01 100644 (file)
@@ -183,6 +183,7 @@ codec_create (GstDucatiVidDec * self)
   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);
@@ -232,6 +233,7 @@ get_buffer_priv (GstDucatiVidDec * self, GstBuffer * buf)
         self->stride, self->padded_height);
 
     gst_ducati_buffer_priv_set (buf, priv);
+    gst_mini_object_unref (GST_MINI_OBJECT (priv));
   }
   return priv;
 }
@@ -312,12 +314,14 @@ codec_process (GstDucatiVidDec * self, gboolean send, gboolean flush,
   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)
@@ -327,6 +331,12 @@ codec_process (GstDucatiVidDec * self, gboolean send, gboolean flush,
           self->outArgs->extendedError, self->status->extendedError);
   }
 
+  /* we now let the codec decide */
+  self->dynParams->newFrameFlag = XDAS_FALSE;
+
+  if (err == XDM_EFAIL || self->outArgs->outBufsInUseFlag)
+    goto skip_outbuf_processing;
+
   for (i = 0; i < IVIDEO2_MAX_IO_BUFFERS && self->outArgs->outputID[i]; i++) {
     gboolean interlaced;
 
@@ -400,7 +410,7 @@ codec_process (GstDucatiVidDec * self, gboolean send, gboolean flush,
       self->send_crop_event = FALSE;
     }
 
-    if (G_UNLIKELY (self->first_out_buffer) && send) {
+    if (G_UNLIKELY (self->first_out_buffer) && send && !self->outArgs->outBufsInUseFlag) {
       GstDRMBufferPool *pool;
       self->first_out_buffer = FALSE;
 
@@ -412,7 +422,7 @@ codec_process (GstDucatiVidDec * self, gboolean send, gboolean flush,
       gst_drm_buffer_pool_destroy (pool);
     }
 
-    if (send) {
+    if (send && !self->outArgs->outBufsInUseFlag) {
       GstClockTime ts;
 
       ts = GST_BUFFER_TIMESTAMP (outbuf);
@@ -470,6 +480,7 @@ codec_process (GstDucatiVidDec * self, gboolean send, gboolean flush,
     }
   }
 
+skip_outbuf_processing:
   for (i = 0; i < IVIDEO2_MAX_IO_BUFFERS && self->outArgs->freeBufID[i]; i++) {
     codec_unlock_outbuf (self, self->outArgs->freeBufID[i]);
   }
@@ -495,6 +506,9 @@ gst_ducati_viddec_codec_flush (GstDucatiVidDec * self, gboolean eos)
   self->ts_may_be_pts = TRUE;
   self->ts_is_pts = FALSE;
   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;
@@ -524,6 +538,8 @@ gst_ducati_viddec_codec_flush (GstDucatiVidDec * self, gboolean eos)
   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..
    */
@@ -1006,7 +1022,6 @@ allocate_buffer:
   }
 
 have_out_buf:
-  self->in_size = 0;
   buf = GST_DUCATIVIDDEC_GET_CLASS (self)->push_input (self, buf);
 
   if (ts != GST_CLOCK_TIME_NONE) {
@@ -1035,6 +1050,7 @@ have_out_buf:
   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) {
@@ -1045,6 +1061,27 @@ have_out_buf:
 
   self->first_in_buffer = FALSE;
 
+  /* 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) {
+        GST_DEBUG_OBJECT (self, "First 16 were:");
+        gst_util_dump_mem (self->input, 16);
+        memmove (self->input, self->input + self->outArgs->bytesConsumed,
+            self->in_size - self->outArgs->bytesConsumed);
+      }
+      self->in_size -= self->outArgs->bytesConsumed;
+    }
+  }
+
   if (self->outArgs->outBufsInUseFlag) {
     GST_DEBUG_OBJECT (self, "outBufsInUseFlag set");
     self->need_out_buf = FALSE;
@@ -1059,6 +1096,9 @@ have_out_buf:
     goto allocate_buffer;
   }
 
+  if (self->needs_flushing)
+    gst_ducati_viddec_codec_flush (self, FALSE);
+
   return GST_FLOW_OK;
 }
 
@@ -1093,6 +1133,7 @@ gst_ducati_viddec_event (GstPad * pad, GstEvent * event)
     case GST_EVENT_FLUSH_STOP:
       if (!gst_ducati_viddec_codec_flush (self, FALSE)) {
         GST_ERROR_OBJECT (self, "could not flush");
+        gst_event_unref (event);
         ret = FALSE;
       }
       gst_segment_init (&self->segment, GST_FORMAT_UNDEFINED);