3 * Copyright (C) 2009 Carl-Anton Ingmarsson <ca.ingmarsson@gmail.com>.
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Library General Public
7 * License as published by the Free Software Foundation; either
8 * version 2 of the License, or (at your option) any later version.
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Library General Public License for more details.
15 * You should have received a copy of the GNU Library General Public
16 * License along with this library; if not, write to the
17 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18 * Boston, MA 02111-1307, USA.
25 #include "gstvdpvideosrcpad.h"
27 #include "gstvdpdecoder.h"
29 GST_DEBUG_CATEGORY_STATIC (gst_vdp_decoder_debug);
30 #define GST_CAT_DEFAULT gst_vdp_decoder_debug
32 #define DEBUG_INIT(bla) \
33 GST_DEBUG_CATEGORY_INIT (gst_vdp_decoder_debug, "vdpdecoder", 0, \
34 "VDPAU decoder base class");
36 GST_BOILERPLATE_FULL (GstVdpDecoder, gst_vdp_decoder, GstBaseVideoDecoder,
37 GST_TYPE_BASE_VIDEO_DECODER, DEBUG_INIT);
46 gst_vdp_decoder_shape_output (GstBaseVideoDecoder * base_video_decoder,
49 GstVdpVideoSrcPad *vdp_pad;
52 (GstVdpVideoSrcPad *) GST_BASE_VIDEO_DECODER_SRC_PAD (base_video_decoder);
54 return gst_vdp_video_src_pad_push (vdp_pad, GST_VDP_VIDEO_BUFFER (buf));
58 gst_vdp_decoder_create_srcpad (GstBaseVideoDecoder * base_video_decoder,
59 GstBaseVideoDecoderClass * base_video_decoder_class)
61 GstPadTemplate *pad_template;
62 GstVdpVideoSrcPad *vdp_pad;
64 pad_template = gst_element_class_get_pad_template
65 (GST_ELEMENT_CLASS (base_video_decoder_class),
66 GST_BASE_VIDEO_DECODER_SRC_NAME);
68 vdp_pad = gst_vdp_video_src_pad_new (pad_template,
69 GST_BASE_VIDEO_DECODER_SRC_NAME);
71 return GST_PAD (vdp_pad);
75 gst_vdp_decoder_post_error (GstVdpDecoder * decoder, GError * error)
79 g_return_if_fail (GST_IS_VDP_DECODER (decoder));
80 g_return_if_fail (decoder != NULL);
82 message = gst_message_new_error (GST_OBJECT (decoder), error, NULL);
83 gst_element_post_message (GST_ELEMENT (decoder), message);
88 gst_vdp_decoder_alloc_buffer (GstVdpDecoder * vdp_decoder,
89 GstVdpVideoBuffer ** video_buf)
91 GstVdpVideoSrcPad *vdp_pad;
96 vdp_pad = (GstVdpVideoSrcPad *) GST_BASE_VIDEO_DECODER_SRC_PAD (vdp_decoder);
98 ret = gst_vdp_video_src_pad_alloc_buffer (vdp_pad, video_buf, &err);
99 if (ret == GST_FLOW_ERROR)
100 gst_vdp_decoder_post_error (vdp_decoder, err);
106 gst_vdp_decoder_render (GstVdpDecoder * vdp_decoder, VdpPictureInfo * info,
107 guint n_bufs, VdpBitstreamBuffer * bufs, GstVdpVideoBuffer ** video_buf)
111 GstVdpDevice *device;
112 VdpVideoSurface surface;
115 ret = gst_vdp_decoder_alloc_buffer (vdp_decoder, video_buf);
116 if (ret != GST_FLOW_OK)
119 device = (*video_buf)->device;
120 surface = (*video_buf)->surface;
122 status = device->vdp_decoder_render (vdp_decoder->decoder, surface,
124 if (status != VDP_STATUS_OK)
130 GST_ELEMENT_ERROR (vdp_decoder, RESOURCE, READ,
131 ("Could not decode"),
132 ("Error returned from vdpau was: %s",
133 device->vdp_get_error_string (status)));
135 gst_buffer_unref (GST_BUFFER_CAST (*video_buf));
137 return GST_FLOW_ERROR;
141 gst_vdp_decoder_init_decoder (GstVdpDecoder * vdp_decoder,
142 VdpDecoderProfile profile, guint32 max_references)
144 GstVdpDevice *device;
149 device = vdp_decoder->device;
151 if (vdp_decoder->decoder != VDP_INVALID_HANDLE) {
152 status = device->vdp_decoder_destroy (vdp_decoder->decoder);
153 if (status != VDP_STATUS_OK)
154 goto destroy_decoder_error;
157 if (!gst_base_video_decoder_set_src_caps (GST_BASE_VIDEO_DECODER
159 return GST_FLOW_NOT_NEGOTIATED;
162 gst_base_video_decoder_get_state (GST_BASE_VIDEO_DECODER (vdp_decoder));
164 status = device->vdp_decoder_create (device->device, profile,
165 state.width, state.height, max_references, &vdp_decoder->decoder);
166 if (status != VDP_STATUS_OK)
167 goto create_decoder_error;
171 destroy_decoder_error:
172 GST_ELEMENT_ERROR (vdp_decoder, RESOURCE, READ,
173 ("Could not destroy vdpau decoder"),
174 ("Error returned from vdpau was: %s",
175 device->vdp_get_error_string (status)));
177 return GST_FLOW_ERROR;
179 create_decoder_error:
180 GST_ELEMENT_ERROR (vdp_decoder, RESOURCE, READ,
181 ("Could not create vdpau decoder"),
182 ("Error returned from vdpau was: %s",
183 device->vdp_get_error_string (status)));
185 return GST_FLOW_ERROR;
189 gst_vdp_decoder_start (GstBaseVideoDecoder * base_video_decoder)
191 GstVdpDecoder *vdp_decoder = GST_VDP_DECODER (base_video_decoder);
194 GstVdpVideoSrcPad *vdp_pad;
197 vdp_decoder->device = gst_vdp_get_device (vdp_decoder->display, &err);
198 if (G_UNLIKELY (!vdp_decoder->device))
202 (GstVdpVideoSrcPad *) GST_BASE_VIDEO_DECODER_SRC_PAD (base_video_decoder);
203 g_object_set (G_OBJECT (vdp_pad), "device", vdp_decoder->device, NULL);
205 vdp_decoder->decoder = VDP_INVALID_HANDLE;
210 gst_vdp_decoder_post_error (vdp_decoder, err);
215 gst_vdp_decoder_stop (GstBaseVideoDecoder * base_video_decoder)
217 GstVdpDecoder *vdp_decoder = GST_VDP_DECODER (base_video_decoder);
219 if (vdp_decoder->decoder != VDP_INVALID_HANDLE) {
220 GstVdpDevice *device = vdp_decoder->device;
223 status = device->vdp_decoder_destroy (vdp_decoder->decoder);
224 if (status != VDP_STATUS_OK) {
225 GST_ELEMENT_ERROR (vdp_decoder, RESOURCE, READ,
226 ("Could not destroy vdpau decoder"),
227 ("Error returned from vdpau was: %s",
228 device->vdp_get_error_string (status)));
233 g_object_unref (vdp_decoder->device);
239 gst_vdp_decoder_get_property (GObject * object, guint prop_id,
240 GValue * value, GParamSpec * pspec)
242 GstVdpDecoder *vdp_decoder = GST_VDP_DECODER (object);
246 g_value_set_string (value, vdp_decoder->display);
250 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
256 gst_vdp_decoder_set_property (GObject * object, guint prop_id,
257 const GValue * value, GParamSpec * pspec)
259 GstVdpDecoder *vdp_decoder = GST_VDP_DECODER (object);
263 g_free (vdp_decoder->display);
264 vdp_decoder->display = g_value_dup_string (value);
268 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
274 gst_vdp_decoder_finalize (GObject * object)
276 GstVdpDecoder *vdp_decoder = GST_VDP_DECODER (object);
278 g_free (vdp_decoder->display);
280 G_OBJECT_CLASS (parent_class)->finalize (object);
284 gst_vdp_decoder_base_init (gpointer g_class)
286 GstElementClass *element_class = GST_ELEMENT_CLASS (g_class);
289 GstPadTemplate *src_template;
291 src_caps = gst_vdp_video_buffer_get_caps (TRUE, VDP_CHROMA_TYPE_420);
292 src_template = gst_pad_template_new (GST_BASE_VIDEO_DECODER_SRC_NAME,
293 GST_PAD_SRC, GST_PAD_ALWAYS, src_caps);
295 gst_element_class_add_pad_template (element_class, src_template);
296 gst_object_unref (src_template);
300 gst_vdp_decoder_init (GstVdpDecoder * vdp_decoder, GstVdpDecoderClass * klass)
302 vdp_decoder->display = NULL;
306 gst_vdp_decoder_class_init (GstVdpDecoderClass * klass)
308 GObjectClass *object_class;
309 GstBaseVideoDecoderClass *base_video_decoder_class;
311 object_class = G_OBJECT_CLASS (klass);
312 base_video_decoder_class = GST_BASE_VIDEO_DECODER_CLASS (klass);
314 object_class->get_property = gst_vdp_decoder_get_property;
315 object_class->set_property = gst_vdp_decoder_set_property;
316 object_class->finalize = gst_vdp_decoder_finalize;
318 base_video_decoder_class->start = gst_vdp_decoder_start;
319 base_video_decoder_class->stop = gst_vdp_decoder_stop;
321 base_video_decoder_class->create_srcpad = gst_vdp_decoder_create_srcpad;
322 base_video_decoder_class->shape_output = gst_vdp_decoder_shape_output;
324 g_object_class_install_property (object_class,
325 PROP_DISPLAY, g_param_spec_string ("display", "Display", "X Display name",
326 NULL, G_PARAM_READWRITE | G_PARAM_CONSTRUCT));