CrystalHD: Change opaque_list_pop to return the node.
authorPhilip Langdale <philipl@overt.org>
Sat, 26 Mar 2011 05:43:53 +0000 (22:43 -0700)
committerPhilip Langdale <philipl@overt.org>
Sat, 9 Apr 2011 03:17:42 +0000 (20:17 -0700)
In preparation for adding additional fields to the node, return
the node instead of the pts value. This requires the caller to
free the node.

Signed-off-by: Philip Langdale <philipl@overt.org>
libavcodec/crystalhd.c

index 95fe931..f971056 100644 (file)
@@ -231,15 +231,17 @@ static uint64_t opaque_list_push(CHDContext *priv, uint64_t reordered_opaque)
  * The OpaqueList is built in decode order, while elements will be removed
  * in presentation order. If frames are reordered, this means we must be
  * able to remove elements that are not the first element.
+ *
+ * Returned node must be freed by caller.
  */
-static uint64_t opaque_list_pop(CHDContext *priv, uint64_t fake_timestamp)
+static OpaqueList *opaque_list_pop(CHDContext *priv, uint64_t fake_timestamp)
 {
     OpaqueList *node = priv->head;
 
     if (!priv->head) {
         av_log(priv->avctx, AV_LOG_ERROR,
                "CrystalHD: Attempted to query non-existent timestamps.\n");
-        return AV_NOPTS_VALUE;
+        return NULL;
     }
 
     /*
@@ -247,14 +249,13 @@ static uint64_t opaque_list_pop(CHDContext *priv, uint64_t fake_timestamp)
      * the head pointer rather than the previous element in the list.
      */
     if (priv->head->fake_timestamp == fake_timestamp) {
-        uint64_t reordered_opaque = node->reordered_opaque;
         priv->head = node->next;
-        av_free(node);
 
         if (!priv->head->next)
             priv->tail = priv->head;
 
-        return reordered_opaque;
+        node->next = NULL;
+        return node;
     }
 
     /*
@@ -262,24 +263,23 @@ static uint64_t opaque_list_pop(CHDContext *priv, uint64_t fake_timestamp)
      * previous element available to rewrite its next pointer.
      */
     while (node->next) {
-        OpaqueList *next = node->next;
-        if (next->fake_timestamp == fake_timestamp) {
-            uint64_t reordered_opaque = next->reordered_opaque;
-            node->next = next->next;
-            av_free(next);
+        OpaqueList *current = node->next;
+        if (current->fake_timestamp == fake_timestamp) {
+            node->next = current->next;
 
             if (!node->next)
                priv->tail = node;
 
-            return reordered_opaque;
+            current->next = NULL;
+            return current;
         } else {
-            node = next;
+            node = current;
         }
     }
 
     av_log(priv->avctx, AV_LOG_VERBOSE,
            "CrystalHD: Couldn't match fake_timestamp.\n");
-    return AV_NOPTS_VALUE;
+    return NULL;
 }
 
 
@@ -517,6 +517,7 @@ static inline CopyRet copy_frame(AVCodecContext *avctx,
     uint8_t interlaced;
 
     CHDContext *priv = avctx->priv_data;
+    int64_t pkt_pts  = AV_NOPTS_VALUE;
 
     uint8_t bottom_field = (output->PicInfo.flags & VDEC_FLAG_BOTTOMFIELD) ==
                            VDEC_FLAG_BOTTOMFIELD;
@@ -530,6 +531,16 @@ static inline CopyRet copy_frame(AVCodecContext *avctx,
     uint8_t *dst;
     int dStride;
 
+    if (output->PicInfo.timeStamp != 0) {
+        OpaqueList *node = opaque_list_pop(priv, output->PicInfo.timeStamp);
+        if (node) {
+            pkt_pts = node->reordered_opaque;
+            av_free(node);
+        }
+        av_log(avctx, AV_LOG_VERBOSE, "output \"pts\": %"PRIu64"\n",
+               output->PicInfo.timeStamp);
+    }
+
     ret = DtsGetDriverStatus(priv->dev, &decoder_status);
     if (ret != BC_STS_SUCCESS) {
         av_log(avctx, AV_LOG_ERROR,
@@ -608,11 +619,7 @@ static inline CopyRet copy_frame(AVCodecContext *avctx,
     if (interlaced)
         priv->pic.top_field_first = !bottom_first;
 
-    if (output->PicInfo.timeStamp != 0) {
-        priv->pic.pkt_pts = opaque_list_pop(priv, output->PicInfo.timeStamp);
-        av_log(avctx, AV_LOG_VERBOSE, "output \"pts\": %"PRIu64"\n",
-               priv->pic.pkt_pts);
-    }
+    priv->pic.pkt_pts = pkt_pts;
 
     if (!priv->need_second_field) {
         *data_size       = sizeof(AVFrame);