decoder: properly reference count pictures.
authorGwenole Beauchesne <gwenole.beauchesne@intel.com>
Thu, 26 Jan 2012 14:19:14 +0000 (15:19 +0100)
committerGwenole Beauchesne <gwenole.beauchesne@intel.com>
Fri, 27 Jan 2012 12:28:12 +0000 (13:28 +0100)
This fixes cases where a GstVaapiPicture would be destroyed whereas
there is still a valid instance of it in either prev, current or
next picture.

gst-libs/gst/vaapi/gstvaapidecoder_mpeg2.c
gst-libs/gst/vaapi/gstvaapidecoder_mpeg4.c
gst-libs/gst/vaapi/gstvaapidecoder_vc1.c

index 33edc0f..e888426 100644 (file)
@@ -274,9 +274,8 @@ decode_current_picture(GstVaapiDecoderMpeg2 *decoder)
             if ((priv->prev_picture && priv->next_picture) ||
                 (priv->closed_gop && priv->next_picture))
                 status = render_picture(decoder, picture);
-            gst_vaapi_picture_unref(picture);
         }
-        priv->current_picture = NULL;
+        gst_vaapi_picture_replace(&priv->current_picture, NULL);
     }
     return status;
 }
@@ -494,16 +493,10 @@ decode_picture(GstVaapiDecoderMpeg2 *decoder, guchar *buf, guint buf_size)
     /* Update reference pictures */
     if (pic_hdr->pic_type != GST_MPEG_VIDEO_PICTURE_TYPE_B) {
         GST_VAAPI_PICTURE_FLAG_SET(picture, GST_VAAPI_PICTURE_FLAG_REFERENCE);
-        if (priv->prev_picture) {
-            gst_vaapi_picture_unref(priv->prev_picture);
-            priv->prev_picture = NULL;
-        }
-        if (priv->next_picture) {
-            priv->prev_picture = priv->next_picture;
-            priv->next_picture = NULL;
-            status = render_picture(decoder, priv->prev_picture);
-        }
-        priv->next_picture = picture;
+        if (priv->next_picture)
+            status = render_picture(decoder, priv->next_picture);
+        gst_vaapi_picture_replace(&priv->prev_picture, priv->next_picture);
+        gst_vaapi_picture_replace(&priv->next_picture, picture);
     }
     return status;
 }
index a81f19b..24a6757 100644 (file)
@@ -273,9 +273,8 @@ decode_current_picture(GstVaapiDecoderMpeg4 *decoder)
             if ((priv->prev_picture && priv->next_picture) ||
                 (priv->closed_gop && priv->next_picture))
                 status = render_picture(decoder, picture);
-            gst_vaapi_picture_unref(picture);
         }
-        priv->curr_picture = NULL;
+        gst_vaapi_picture_replace(&priv->curr_picture, NULL);
     }
     return status;
 }
@@ -569,16 +568,10 @@ decode_picture(GstVaapiDecoderMpeg4 *decoder, const guint8 *buf, guint buf_size)
     /* Update reference pictures */
     /* XXX: consider priv->vol_hdr.low_delay, consider packed video frames for DivX/XviD */
     if (GST_VAAPI_PICTURE_IS_REFERENCE(picture)) {
-        if (priv->prev_picture) {
-            gst_vaapi_picture_unref(priv->prev_picture);
-            priv->prev_picture = NULL;
-        }
-        if (priv->next_picture) {
-            priv->prev_picture = priv->next_picture;
-            priv->next_picture = NULL;
-            status = render_picture(decoder, priv->prev_picture);
-        }
-        priv->next_picture = picture;
+        if (priv->next_picture)
+            status = render_picture(decoder, priv->next_picture);
+        gst_vaapi_picture_replace(&priv->prev_picture, priv->next_picture);
+        gst_vaapi_picture_replace(&priv->next_picture, picture);
     }
     return status;
 }
index 9f4e6c9..b305b28 100644 (file)
@@ -227,9 +227,8 @@ decode_current_picture(GstVaapiDecoderVC1 *decoder)
         if (!GST_VAAPI_PICTURE_IS_REFERENCE(picture)) {
             if (priv->prev_picture && priv->next_picture)
                 status = render_picture(decoder, picture);
-            gst_vaapi_picture_unref(picture);
         }
-        priv->current_picture = NULL;
+        gst_vaapi_picture_replace(&priv->current_picture, NULL);
     }
     return status;
 }
@@ -957,16 +956,10 @@ decode_frame(GstVaapiDecoderVC1 *decoder, GstVC1BDU *rbdu, GstVC1BDU *ebdu)
 
     /* Update reference pictures */
     if (GST_VAAPI_PICTURE_IS_REFERENCE(picture)) {
-        if (priv->prev_picture) {
-            gst_vaapi_picture_unref(priv->prev_picture);
-            priv->prev_picture = NULL;
-        }
-        if (priv->next_picture) {
-            priv->prev_picture = priv->next_picture;
-            priv->next_picture = NULL;
-            status = render_picture(decoder, priv->prev_picture);
-        }
-        priv->next_picture = picture;
+        if (priv->next_picture)
+            status = render_picture(decoder, priv->next_picture);
+        gst_vaapi_picture_replace(&priv->prev_picture, priv->next_picture);
+        gst_vaapi_picture_replace(&priv->next_picture, picture);
     }
 
     if (!fill_picture(decoder, picture))