vdpau: add error parameter to gst_vdp_video_src_pad_get_device
authorCarl-Anton Ingmarsson <ca.ingmarsson@gmail.com>
Sat, 26 Jun 2010 22:35:11 +0000 (00:35 +0200)
committerCarl-Anton Ingmarsson <ca.ingmarsson@gmail.com>
Mon, 28 Jun 2010 09:11:51 +0000 (11:11 +0200)
sys/vdpau/gstvdp/gstvdpdecoder.c
sys/vdpau/gstvdp/gstvdpdecoder.h
sys/vdpau/gstvdp/gstvdpvideosrcpad.c
sys/vdpau/gstvdp/gstvdpvideosrcpad.h
sys/vdpau/h264/gstvdph264dec.c
sys/vdpau/mpeg/gstvdpmpegdec.c

index 841a69355a43f3804c1ebc24fa998899aedf1cb3..2549b246f2ac89bf5740e72885ee50e125510455 100644 (file)
@@ -65,14 +65,27 @@ gst_vdp_decoder_create_srcpad (GstBaseVideoDecoder * base_video_decoder,
   return GST_PAD (vdp_pad);
 }
 
+void
+gst_vdp_decoder_post_error (GstVdpDecoder * decoder, GError * error)
+{
+  GstMessage *message;
+
+  g_return_if_fail (GST_IS_VDP_DECODER (decoder));
+  g_return_if_fail (decoder != NULL);
+
+  message = gst_message_new_error (GST_OBJECT (decoder), error, NULL);
+  gst_element_post_message (GST_ELEMENT (decoder), message);
+  g_error_free (error);
+}
+
 GstFlowReturn
 gst_vdp_decoder_alloc_buffer (GstVdpDecoder * vdp_decoder,
-    GstVdpVideoBuffer ** video_buf)
+    GstVdpVideoBuffer ** video_buf, GError ** error)
 {
   GstVdpVideoSrcPad *vdp_pad;
 
   vdp_pad = (GstVdpVideoSrcPad *) GST_BASE_VIDEO_DECODER_SRC_PAD (vdp_decoder);
-  return gst_vdp_video_src_pad_alloc_buffer (vdp_pad, video_buf);
+  return gst_vdp_video_src_pad_alloc_buffer (vdp_pad, video_buf, error);
 }
 
 GstFlowReturn
index 91c725223a28766ca8140a1c18afe18ecdccbe09..8abc4e5a6d5aaa0a0591a68520ca2560d631e12b 100644 (file)
@@ -47,8 +47,13 @@ struct _GstVdpDecoderClass {
   GstBaseVideoDecoderClass base_video_decoder_class;
 };
 
-GstFlowReturn gst_vdp_decoder_alloc_buffer (GstVdpDecoder * vdp_decoder, GstVdpVideoBuffer **video_buf);
-GstFlowReturn gst_vdp_decoder_get_device (GstVdpDecoder * vdp_decoder, GstVdpDevice ** device, GError ** error);
+void gst_vdp_decoder_post_error (GstVdpDecoder * decoder, GError * error);
+
+GstFlowReturn gst_vdp_decoder_alloc_buffer (GstVdpDecoder * vdp_decoder,
+    GstVdpVideoBuffer **video_buf, GError ** error);
+
+GstFlowReturn gst_vdp_decoder_get_device (GstVdpDecoder * vdp_decoder,
+    GstVdpDevice ** device, GError ** error);
 
 GType gst_vdp_decoder_get_type (void);
 
index 167c4d790304dc0aa180d9b101ca6b9f18bbdff7..59c6d5f65cfc01a4acf12f1cde88a6beb9ecede5 100644 (file)
@@ -159,9 +159,41 @@ device_error:
   return FALSE;
 }
 
+static GstFlowReturn
+gst_vdp_video_src_pad_alloc_with_caps (GstVdpVideoSrcPad * vdp_pad,
+    GstCaps * caps, GstVdpVideoBuffer ** video_buf, GError ** error)
+{
+  GstFlowReturn ret;
+
+  ret = gst_pad_alloc_buffer ((GstPad *) vdp_pad, 0, 0, caps,
+      (GstBuffer **) video_buf);
+  if (ret != GST_FLOW_OK)
+    return ret;
+
+  if (!gst_caps_is_equal_fixed (caps, GST_BUFFER_CAPS (*video_buf)))
+    goto wrong_caps;
+
+  if (!GST_IS_VDP_VIDEO_BUFFER (*video_buf))
+    goto invalid_buf;
+
+  return GST_FLOW_OK;
+
+wrong_caps:
+  gst_buffer_unref (GST_BUFFER (*video_buf));
+  g_set_error (error, GST_STREAM_ERROR, GST_STREAM_ERROR_FAILED,
+      "Sink element returned buffer with wrong caps");
+  return GST_FLOW_ERROR;
+
+invalid_buf:
+  gst_buffer_unref (GST_BUFFER (*video_buf));
+  g_set_error (error, GST_STREAM_ERROR, GST_STREAM_ERROR_FAILED,
+      "Sink element returned buffer of wrong type");
+  return GST_FLOW_ERROR;
+}
+
 GstFlowReturn
 gst_vdp_video_src_pad_alloc_buffer (GstVdpVideoSrcPad * vdp_pad,
-    GstVdpVideoBuffer ** video_buf)
+    GstVdpVideoBuffer ** video_buf, GError ** error)
 {
   GstCaps *caps;
   GstFlowReturn ret;
@@ -176,8 +208,8 @@ gst_vdp_video_src_pad_alloc_buffer (GstVdpVideoSrcPad * vdp_pad,
     GstVdpDevice *device;
 
     if (G_UNLIKELY (!vdp_pad->device)) {
-      if (!gst_vdp_video_src_pad_open_device (vdp_pad, NULL))
-        goto device_error;
+      if (!gst_vdp_video_src_pad_open_device (vdp_pad, error))
+        return GST_FLOW_ERROR;
 
       gst_vdp_video_src_pad_update_caps (vdp_pad);
     }
@@ -186,16 +218,13 @@ gst_vdp_video_src_pad_alloc_buffer (GstVdpVideoSrcPad * vdp_pad,
     *video_buf = gst_vdp_video_buffer_new (device, VDP_CHROMA_TYPE_420,
         vdp_pad->width, vdp_pad->height);
     if (!*video_buf)
-      goto video_buffer_error;
+      goto video_buf_error;
   } else {
-    ret = gst_pad_alloc_buffer ((GstPad *) vdp_pad, 0, 0, caps,
-        (GstBuffer **) video_buf);
+    ret = gst_vdp_video_src_pad_alloc_with_caps (vdp_pad, caps, video_buf,
+        error);
     if (ret != GST_FLOW_OK)
       return ret;
 
-    if (!gst_caps_is_equal_fixed (caps, GST_BUFFER_CAPS (*video_buf)))
-      goto wrong_caps;
-
     if (G_UNLIKELY (!vdp_pad->device)) {
       vdp_pad->device =
           g_object_ref (GST_VDP_VIDEO_BUFFER (*video_buf)->device);
@@ -206,17 +235,9 @@ gst_vdp_video_src_pad_alloc_buffer (GstVdpVideoSrcPad * vdp_pad,
 
   return GST_FLOW_OK;
 
-device_error:
-  GST_ERROR_OBJECT (vdp_pad, "Couldn't create GstVdpDevice");
-  return GST_FLOW_ERROR;
-
-video_buffer_error:
-  GST_ERROR_OBJECT (vdp_pad, "Couldn't create GstVdpVideoBuffer");
-  return GST_FLOW_ERROR;
-
-wrong_caps:
-  GST_ERROR_OBJECT (vdp_pad, "Sink element returned buffer with wrong caps");
-  gst_buffer_unref (GST_BUFFER_CAST (*video_buf));
+video_buf_error:
+  g_set_error (error, GST_RESOURCE_ERROR, GST_RESOURCE_ERROR_READ,
+      "Couldn't create a GstVdpVideoBuffer");
   return GST_FLOW_ERROR;
 }
 
@@ -267,24 +288,15 @@ gst_vdp_video_src_pad_get_device (GstVdpVideoSrcPad * vdp_pad,
 
     else {
       GstFlowReturn ret;
-      GstBuffer *buf;
+      GstVdpVideoBuffer *buf;
 
-      ret = gst_pad_alloc_buffer (GST_PAD (vdp_pad), 0, 0,
-          GST_PAD_CAPS (vdp_pad), &buf);
+      ret = gst_vdp_video_src_pad_alloc_with_caps (vdp_pad,
+          GST_PAD_CAPS (vdp_pad), &buf, error);
       if (ret != GST_FLOW_OK)
-        goto alloc_failed;
-
-      if (!gst_caps_is_equal_fixed (GST_PAD_CAPS (vdp_pad),
-              GST_BUFFER_CAPS (buf))) {
-        gst_buffer_unref (buf);
-        goto wrong_caps;
-      }
-      if (!GST_IS_VDP_VIDEO_BUFFER (buf)) {
-        gst_buffer_unref (buf);
-        goto invalid_buffer;
-      }
-
-      vdp_pad->device = g_object_ref (GST_VDP_VIDEO_BUFFER (buf)->device);
+        return ret;
+
+      vdp_pad->device = g_object_ref (buf->device);
+      gst_buffer_unref (GST_BUFFER (buf));
     }
 
     gst_vdp_video_src_pad_update_caps (vdp_pad);
@@ -292,21 +304,6 @@ gst_vdp_video_src_pad_get_device (GstVdpVideoSrcPad * vdp_pad,
 
   *device = vdp_pad->device;
   return GST_FLOW_OK;
-
-alloc_failed:
-  g_set_error (error, GST_STREAM_ERROR, GST_STREAM_ERROR_FAILED,
-      "Couldn't allocate buffer");
-  return GST_FLOW_ERROR;
-
-wrong_caps:
-  g_set_error (error, GST_STREAM_ERROR, GST_STREAM_ERROR_FAILED,
-      "Sink element returned buffer with wrong caps");
-  return GST_FLOW_ERROR;
-
-invalid_buffer:
-  g_set_error (error, GST_STREAM_ERROR, GST_STREAM_ERROR_FAILED,
-      "Sink element returned invalid buffer type");
-  return GST_FLOW_ERROR;
 }
 
 static GstCaps *
index 427658b81a291b1bf8f5abe82b21f2f84718cb33..135f18c227db633a11558363f1f07a9ddc55d86c 100644 (file)
@@ -39,7 +39,7 @@ typedef struct _GstVdpVideoSrcPad GstVdpVideoSrcPad;
 typedef struct _GstVdpVideoSrcPadClass GstVdpVideoSrcPadClass;
 
 GstFlowReturn gst_vdp_video_src_pad_push (GstVdpVideoSrcPad *vdp_pad, GstVdpVideoBuffer *video_buf);
-GstFlowReturn gst_vdp_video_src_pad_alloc_buffer (GstVdpVideoSrcPad *vdp_pad, GstVdpVideoBuffer **video_buf);
+GstFlowReturn gst_vdp_video_src_pad_alloc_buffer (GstVdpVideoSrcPad *vdp_pad, GstVdpVideoBuffer **video_buf, GError ** error);
 
 GstFlowReturn gst_vdp_video_src_pad_get_device (GstVdpVideoSrcPad * vdp_pad, GstVdpDevice ** device, GError ** error);
 
index c5ec7c9f73f7cf4659720296f7aa95e9914b84a4..1b6d1c51514ae8e4a06ef83e92d0a4d3c5adc022 100644 (file)
@@ -440,6 +440,7 @@ gst_vdp_h264_dec_handle_frame (GstBaseVideoDecoder * base_video_decoder,
   GstH264Sequence *seq;
 
   GstFlowReturn ret;
+  GError *err = NULL;
   GstVdpVideoBuffer *outbuf;
   VdpPictureInfoH264 info;
   GstVdpDevice *device;
@@ -479,8 +480,8 @@ gst_vdp_h264_dec_handle_frame (GstBaseVideoDecoder * base_video_decoder,
 
 
   /* decoding */
-  if ((ret = gst_vdp_decoder_alloc_buffer (GST_VDP_DECODER (h264_dec), &outbuf)
-          != GST_FLOW_OK))
+  if ((ret = gst_vdp_decoder_alloc_buffer (GST_VDP_DECODER (h264_dec), &outbuf,
+              &err) != GST_FLOW_OK))
     goto alloc_error;
 
   device = GST_VDP_VIDEO_BUFFER (outbuf)->device;
@@ -566,6 +567,9 @@ gst_vdp_h264_dec_handle_frame (GstBaseVideoDecoder * base_video_decoder,
 
 alloc_error:
   gst_base_video_decoder_skip_frame (base_video_decoder, frame);
+
+  if (ret == GST_FLOW_ERROR)
+    gst_vdp_decoder_post_error (GST_VDP_DECODER (h264_dec), err);
   return ret;
 
 decode_error:
index eb122447a4039062eb04eaa3594c26dec5d5ac86..7099d071556afd9447b971ef383c6243be840fe8 100644 (file)
@@ -331,6 +331,7 @@ gst_vdp_mpeg_dec_handle_frame (GstBaseVideoDecoder * base_video_decoder,
   GstVdpMpegFrame *mpeg_frame;
 
   GstFlowReturn ret;
+  GError *err = NULL;
   GstVdpVideoBuffer *outbuf;
   VdpVideoSurface surface;
   GstVdpDevice *device;
@@ -402,8 +403,8 @@ gst_vdp_mpeg_dec_handle_frame (GstBaseVideoDecoder * base_video_decoder,
     info->backward_reference = VDP_INVALID_HANDLE;
   }
 
-  if ((ret = gst_vdp_decoder_alloc_buffer (GST_VDP_DECODER (mpeg_dec), &outbuf)
-          != GST_FLOW_OK))
+  if ((ret = gst_vdp_decoder_alloc_buffer (GST_VDP_DECODER (mpeg_dec), &outbuf,
+              &err) != GST_FLOW_OK))
     goto alloc_error;
 
   /* create decoder */
@@ -447,6 +448,9 @@ gst_vdp_mpeg_dec_handle_frame (GstBaseVideoDecoder * base_video_decoder,
 
 alloc_error:
   gst_base_video_decoder_skip_frame (base_video_decoder, frame);
+
+  if (ret == GST_FLOW_ERROR)
+    gst_vdp_decoder_post_error (GST_VDP_DECODER (mpeg_dec), err);
   return ret;
 
 decode_error: