diff --git a/sys/vdpau/gstvdpaudecoder.c b/sys/vdpau/gstvdpaudecoder.c index a647a5f9d0..36d6eca0c6 100644 --- a/sys/vdpau/gstvdpaudecoder.c +++ b/sys/vdpau/gstvdpaudecoder.c @@ -69,12 +69,36 @@ static void gst_vdpaudecoder_get_property (GObject * object, guint prop_id, gboolean gst_vdpaudecoder_push_video_surface (GstVdpauDecoder * dec, - VdpVideoSurface * surface) + VdpVideoSurface surface) { switch (dec->format) { case GST_MAKE_FOURCC ('Y', 'V', '1', '2'): - /* YV12 specific code */ + { + gint size; + GstFlowReturn result; + GstBuffer *buffer; + VdpStatus status; + guint8 *data[3]; + + size = dec->height * dec->width + dec->height * dec->width / 2; + result = + gst_pad_alloc_buffer_and_set_caps (dec->src, GST_BUFFER_OFFSET_NONE, + size, GST_PAD_CAPS (dec->src), &buffer); + if (G_UNLIKELY (result != GST_FLOW_OK)) + return FALSE; + + data[0] = GST_BUFFER_DATA (buffer); + data[1] = data[0] + dec->height * dec->width; + data[2] = data[1] + dec->height * dec->width / 4; + + status = + vdp_video_surface_get_bits_ycbcr (surface, VDP_YCBCR_FORMAT_YV12, + (void *) data, NULL); + if (G_UNLIKELY (status != VDP_STATUS_OK)) + return FALSE; + break; + } default: break; } @@ -223,6 +247,9 @@ gst_vdpaudecoder_init_vdpau (GstVdpauDecoder * dec) (void **) &vdp_video_surface_query_ycbcr_capabilities); vdp_get_proc_address (dec->device, VDP_FUNC_ID_DEVICE_DESTROY, (void **) &vdp_device_destroy); + vdp_get_proc_address (dec->device, + VDP_FUNC_ID_VIDEO_SURFACE_GET_BITS_Y_CB_CR, + (void **) &vdp_video_surface_get_bits_ycbcr); caps = gst_vdpaudecoder_get_vdpau_support (dec); if (!caps) { @@ -293,6 +320,8 @@ gst_vdpaudecoder_sink_set_caps (GstPad * pad, GstCaps * caps) if (!res) return FALSE; + dec->width = width; + dec->height = height; dec->format = fourcc_format; return TRUE; @@ -363,6 +392,10 @@ gst_vdpaudecoder_init (GstVdpauDecoder * dec, GstVdpauDecoderClass * klass) dec->silent = FALSE; dec->src_caps = NULL; + dec->height = 0; + dec->width = 0; + dec->format = 0; + dec->src = gst_pad_new_from_static_template (&src_template, "src"); gst_pad_set_getcaps_function (dec->src, gst_vdpaudecoder_src_getcaps); gst_element_add_pad (GST_ELEMENT (dec), dec->src); diff --git a/sys/vdpau/gstvdpaudecoder.h b/sys/vdpau/gstvdpaudecoder.h index 2c8b11f77b..336e4b8a4a 100644 --- a/sys/vdpau/gstvdpaudecoder.h +++ b/sys/vdpau/gstvdpaudecoder.h @@ -54,6 +54,7 @@ struct _GstVdpauDecoder { GstCaps *src_caps; + gint width, height; guint32 format; gboolean silent; @@ -65,7 +66,7 @@ struct _GstVdpauDecoderClass { GType gst_vdpaudecoder_get_type (void); -gboolean gst_vdpaudecoder_push_video_surface (GstVdpauDecoder * dec, VdpVideoSurface * surface); +gboolean gst_vdpaudecoder_push_video_surface (GstVdpauDecoder * dec, VdpVideoSurface surface); G_END_DECLS diff --git a/sys/vdpau/vdpauvariables.h b/sys/vdpau/vdpauvariables.h index b93a75be9b..c0f7bb4f9b 100644 --- a/sys/vdpau/vdpauvariables.h +++ b/sys/vdpau/vdpauvariables.h @@ -2,6 +2,7 @@ static VdpVideoSurfaceQueryCapabilities *vdp_video_surface_query_capabilities; static VdpVideoSurfaceQueryGetPutBitsYCbCrCapabilities *vdp_video_surface_query_ycbcr_capabilities; +static VdpVideoSurfaceGetBitsYCbCr *vdp_video_surface_get_bits_ycbcr; static VdpGetProcAddress *vdp_get_proc_address; static VdpDeviceDestroy *vdp_device_destroy;