vaapidecode: use GST_ERROR to print error messages.
[platform/upstream/gstreamer-vaapi.git] / gst / vaapi / gstvaapidecode.c
1 /*
2  *  gstvaapidecode.c - VA-API video decoder
3  *
4  *  Copyright (C) 2010-2011 Splitted-Desktop Systems
5  *  Copyright (C) 2011-2012 Intel Corporation
6  *
7  *  This library is free software; you can redistribute it and/or
8  *  modify it under the terms of the GNU Lesser General Public License
9  *  as published by the Free Software Foundation; either version 2.1
10  *  of the License, or (at your option) any later version.
11  *
12  *  This library is distributed in the hope that it will be useful,
13  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
14  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15  *  Lesser General Public License for more details.
16  *
17  *  You should have received a copy of the GNU Lesser General Public
18  *  License along with this library; if not, write to the Free
19  *  Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
20  *  Boston, MA 02110-1301 USA
21 */
22
23 /**
24  * SECTION:gstvaapidecode
25  * @short_description: A VA-API based video decoder
26  *
27  * vaapidecode decodes from raw bitstreams to surfaces suitable for
28  * the vaapisink element.
29  */
30
31 #include "gst/vaapi/sysdeps.h"
32 #include <gst/vaapi/gstvaapidisplay.h>
33 #include <gst/vaapi/gstvaapivideobuffer.h>
34 #include <gst/video/videocontext.h>
35
36 #include "gstvaapidecode.h"
37 #include "gstvaapipluginutil.h"
38 #include "gstvaapipluginbuffer.h"
39
40 #include <gst/vaapi/gstvaapidecoder_h264.h>
41 #include <gst/vaapi/gstvaapidecoder_jpeg.h>
42 #include <gst/vaapi/gstvaapidecoder_mpeg2.h>
43 #include <gst/vaapi/gstvaapidecoder_mpeg4.h>
44 #include <gst/vaapi/gstvaapidecoder_vc1.h>
45
46 #define GST_PLUGIN_NAME "vaapidecode"
47 #define GST_PLUGIN_DESC "A VA-API based video decoder"
48
49 GST_DEBUG_CATEGORY_STATIC(gst_debug_vaapidecode);
50 #define GST_CAT_DEFAULT gst_debug_vaapidecode
51
52 /* ElementFactory information */
53 static const GstElementDetails gst_vaapidecode_details =
54     GST_ELEMENT_DETAILS(
55         "VA-API decoder",
56         "Codec/Decoder/Video",
57         GST_PLUGIN_DESC,
58         "Gwenole Beauchesne <gwenole.beauchesne@intel.com>");
59
60 /* Default templates */
61 #define GST_CAPS_CODEC(CODEC) CODEC "; "
62
63 static const char gst_vaapidecode_sink_caps_str[] =
64     GST_CAPS_CODEC("video/mpeg, mpegversion=2, systemstream=(boolean)false")
65     GST_CAPS_CODEC("video/mpeg, mpegversion=4")
66     GST_CAPS_CODEC("video/x-divx")
67     GST_CAPS_CODEC("video/x-xvid")
68     GST_CAPS_CODEC("video/x-h263")
69     GST_CAPS_CODEC("video/x-h264")
70     GST_CAPS_CODEC("video/x-wmv")
71     GST_CAPS_CODEC("image/jpeg")
72     ;
73
74 static const char gst_vaapidecode_src_caps_str[] =
75     GST_VAAPI_SURFACE_CAPS;
76
77 static GstStaticPadTemplate gst_vaapidecode_sink_factory =
78     GST_STATIC_PAD_TEMPLATE(
79         "sink",
80         GST_PAD_SINK,
81         GST_PAD_ALWAYS,
82         GST_STATIC_CAPS(gst_vaapidecode_sink_caps_str));
83
84 static GstStaticPadTemplate gst_vaapidecode_src_factory =
85     GST_STATIC_PAD_TEMPLATE(
86         "src",
87         GST_PAD_SRC,
88         GST_PAD_ALWAYS,
89         GST_STATIC_CAPS(gst_vaapidecode_src_caps_str));
90
91 static void
92 gst_vaapidecode_implements_iface_init(GstImplementsInterfaceClass *iface);
93
94 static void
95 gst_video_context_interface_init(GstVideoContextInterface *iface);
96
97 #define GstVideoContextClass GstVideoContextInterface
98 G_DEFINE_TYPE_WITH_CODE(
99     GstVaapiDecode,
100     gst_vaapidecode,
101     GST_TYPE_VIDEO_DECODER,
102     G_IMPLEMENT_INTERFACE(GST_TYPE_IMPLEMENTS_INTERFACE,
103                           gst_vaapidecode_implements_iface_init);
104     G_IMPLEMENT_INTERFACE(GST_TYPE_VIDEO_CONTEXT,
105                           gst_video_context_interface_init))
106
107 static gboolean
108 gst_vaapidecode_update_src_caps(GstVaapiDecode *decode,
109     GstVideoCodecState *ref_state);
110
111 static void
112 gst_vaapi_decoder_notify_caps(GObject *obj, GParamSpec *pspec, void *user_data)
113 {
114     GstVaapiDecode * const decode = GST_VAAPIDECODE(user_data);
115     GstVideoCodecState *codec_state;
116
117     g_assert(decode->decoder == GST_VAAPI_DECODER(obj));
118
119     codec_state = gst_vaapi_decoder_get_codec_state(decode->decoder);
120     gst_vaapidecode_update_src_caps(decode, codec_state);
121     gst_video_codec_state_unref(codec_state);
122 }
123
124 static inline gboolean
125 gst_vaapidecode_update_sink_caps(GstVaapiDecode *decode, GstCaps *caps)
126 {
127     gst_caps_replace(&decode->sinkpad_caps, caps);
128     return TRUE;
129 }
130
131 static gboolean
132 gst_vaapidecode_update_src_caps(GstVaapiDecode *decode,
133     GstVideoCodecState *ref_state)
134 {
135     GstVideoDecoder * const vdec = GST_VIDEO_DECODER(decode);
136     GstVideoCodecState *state;
137     GstVideoInfo *vi;
138
139     state = gst_video_decoder_set_output_state(vdec,
140         GST_VIDEO_INFO_FORMAT(&ref_state->info),
141         ref_state->info.width, ref_state->info.height, ref_state);
142     if (!state)
143         return FALSE;
144
145     vi = &state->info;
146     gst_video_codec_state_unref(state);
147
148     /* XXX: gst_video_info_to_caps() from GStreamer 0.10 does not
149        reconstruct suitable caps for "encoded" video formats */
150     state->caps = gst_caps_from_string(GST_VAAPI_SURFACE_CAPS_NAME);
151     if (!state->caps)
152         return FALSE;
153
154     gst_caps_set_simple(state->caps,
155         "type", G_TYPE_STRING, "vaapi",
156         "opengl", G_TYPE_BOOLEAN, USE_GLX,
157         "width", G_TYPE_INT, vi->width,
158         "height", G_TYPE_INT, vi->height,
159         "framerate", GST_TYPE_FRACTION, vi->fps_n, vi->fps_d,
160         "pixel-aspect-ratio", GST_TYPE_FRACTION, vi->par_n, vi->par_d,
161         NULL);
162
163     if (GST_VIDEO_INFO_IS_INTERLACED(vi))
164         gst_caps_set_simple(state->caps, "interlaced", G_TYPE_BOOLEAN,
165             TRUE, NULL);
166
167     gst_caps_replace(&decode->srcpad_caps, state->caps);
168     return TRUE;
169 }
170
171 static void
172 gst_vaapidecode_release(GstVaapiDecode *decode)
173 {
174     g_mutex_lock(&decode->decoder_mutex);
175     g_cond_signal(&decode->decoder_ready);
176     g_mutex_unlock(&decode->decoder_mutex);
177 }
178
179 static GstFlowReturn
180 gst_vaapidecode_handle_frame(GstVideoDecoder *vdec, GstVideoCodecFrame *frame)
181 {
182     GstVaapiDecode * const decode = GST_VAAPIDECODE(vdec);
183     GstVaapiSurfaceProxy *proxy;
184     GstVaapiDecoderStatus status;
185     GstVideoCodecFrame *out_frame;
186     GstFlowReturn ret;
187     gint64 end_time;
188
189     /* Decode current frame */
190     for (;;) {
191         end_time = decode->render_time_base;
192         if (!end_time)
193             end_time = g_get_monotonic_time();
194         end_time += GST_TIME_AS_USECONDS(decode->last_buffer_time);
195         end_time += G_TIME_SPAN_SECOND;
196
197         status = gst_vaapi_decoder_decode(decode->decoder, frame);
198         if (status == GST_VAAPI_DECODER_STATUS_ERROR_NO_SURFACE) {
199             gboolean was_signalled;
200             g_mutex_lock(&decode->decoder_mutex);
201             was_signalled = g_cond_wait_until(
202                 &decode->decoder_ready,
203                 &decode->decoder_mutex,
204                 end_time
205             );
206             g_mutex_unlock(&decode->decoder_mutex);
207             if (was_signalled)
208                 continue;
209             goto error_decode_timeout;
210         }
211         if (status != GST_VAAPI_DECODER_STATUS_SUCCESS)
212             goto error_decode;
213         break;
214     }
215
216     /* Output all decoded frames */
217     for (;;) {
218         status = gst_vaapi_decoder_get_frame(decode->decoder, &out_frame);
219         if (status != GST_VAAPI_DECODER_STATUS_SUCCESS)
220             return GST_FLOW_OK;
221
222         proxy = gst_video_codec_frame_get_user_data(out_frame);
223
224         gst_vaapi_surface_proxy_set_user_data(proxy,
225             decode, (GDestroyNotify)gst_vaapidecode_release);
226
227         out_frame->output_buffer = gst_vaapi_video_buffer_new(decode->display);
228         if (!out_frame->output_buffer)
229             goto error_create_buffer;
230
231         gst_vaapi_video_buffer_set_surface_proxy(
232             GST_VAAPI_VIDEO_BUFFER(out_frame->output_buffer), proxy);
233
234         ret = gst_video_decoder_finish_frame(vdec, out_frame);
235         if (ret != GST_FLOW_OK)
236             goto error_commit_buffer;
237         gst_video_codec_frame_unref(out_frame);
238     };
239     return GST_FLOW_OK;
240
241     /* ERRORS */
242 error_decode_timeout:
243     {
244         GST_WARNING("decode timeout. Decoder required a VA surface but none "
245                     "got available within one second");
246         return GST_FLOW_UNEXPECTED;
247     }
248 error_decode:
249     {
250         GST_ERROR("decode error %d", status);
251         switch (status) {
252         case GST_VAAPI_DECODER_STATUS_ERROR_UNSUPPORTED_CODEC:
253         case GST_VAAPI_DECODER_STATUS_ERROR_UNSUPPORTED_PROFILE:
254         case GST_VAAPI_DECODER_STATUS_ERROR_UNSUPPORTED_CHROMA_FORMAT:
255             ret = GST_FLOW_NOT_SUPPORTED;
256             break;
257         default:
258             ret = GST_FLOW_UNEXPECTED;
259             break;
260         }
261         gst_video_decoder_drop_frame(vdec, frame);
262         return ret;
263     }
264 error_create_buffer:
265     {
266         const GstVaapiID surface_id =
267             gst_vaapi_surface_get_id(GST_VAAPI_SURFACE_PROXY_SURFACE(proxy));
268
269         GST_ERROR("video sink failed to create video buffer for proxy'ed "
270                   "surface %" GST_VAAPI_ID_FORMAT,
271                   GST_VAAPI_ID_ARGS(surface_id));
272         gst_video_decoder_drop_frame(vdec, out_frame);
273         gst_video_codec_frame_unref(out_frame);
274         return GST_FLOW_UNEXPECTED;
275     }
276 error_commit_buffer:
277     {
278         GST_DEBUG("video sink rejected the video buffer (error %d)", ret);
279         gst_video_codec_frame_unref(out_frame);
280         return GST_FLOW_UNEXPECTED;
281     }
282 }
283
284 static inline gboolean
285 gst_vaapidecode_ensure_display(GstVaapiDecode *decode)
286 {
287     return gst_vaapi_ensure_display(decode, GST_VAAPI_DISPLAY_TYPE_ANY,
288         &decode->display);
289 }
290
291 static inline guint
292 gst_vaapi_codec_from_caps(GstCaps *caps)
293 {
294     return gst_vaapi_profile_get_codec(gst_vaapi_profile_from_caps(caps));
295 }
296
297 static gboolean
298 gst_vaapidecode_create(GstVaapiDecode *decode, GstCaps *caps)
299 {
300     GstVaapiDisplay *dpy;
301
302     if (!gst_vaapidecode_ensure_display(decode))
303         return FALSE;
304     dpy = decode->display;
305
306     switch (gst_vaapi_codec_from_caps(caps)) {
307     case GST_VAAPI_CODEC_MPEG2:
308         decode->decoder = gst_vaapi_decoder_mpeg2_new(dpy, caps);
309         break;
310     case GST_VAAPI_CODEC_MPEG4:
311     case GST_VAAPI_CODEC_H263:
312         decode->decoder = gst_vaapi_decoder_mpeg4_new(dpy, caps);
313         break;
314     case GST_VAAPI_CODEC_H264:
315         decode->decoder = gst_vaapi_decoder_h264_new(dpy, caps);
316         break;
317     case GST_VAAPI_CODEC_WMV3:
318     case GST_VAAPI_CODEC_VC1:
319         decode->decoder = gst_vaapi_decoder_vc1_new(dpy, caps);
320         break;
321 #if USE_JPEG_DECODER
322     case GST_VAAPI_CODEC_JPEG:
323         decode->decoder = gst_vaapi_decoder_jpeg_new(dpy, caps);
324         break;
325 #endif
326     default:
327         decode->decoder = NULL;
328         break;
329     }
330     if (!decode->decoder)
331         return FALSE;
332
333     g_signal_connect(
334         G_OBJECT(decode->decoder),
335         "notify::caps",
336         G_CALLBACK(gst_vaapi_decoder_notify_caps),
337         decode
338     );
339
340     decode->decoder_caps = gst_caps_ref(caps);
341     return TRUE;
342 }
343
344 static void
345 gst_vaapidecode_destroy(GstVaapiDecode *decode)
346 {
347     g_clear_object(&decode->decoder);
348     gst_caps_replace(&decode->decoder_caps, NULL);
349     gst_vaapidecode_release(decode);
350 }
351
352 static gboolean
353 gst_vaapidecode_reset(GstVaapiDecode *decode, GstCaps *caps)
354 {
355     GstVaapiCodec codec;
356
357     /* Only reset decoder if codec type changed */
358     if (decode->decoder && decode->decoder_caps) {
359         if (gst_caps_is_always_compatible(caps, decode->decoder_caps))
360             return TRUE;
361         codec = gst_vaapi_codec_from_caps(caps);
362         if (codec == gst_vaapi_decoder_get_codec(decode->decoder))
363             return TRUE;
364     }
365
366     gst_vaapidecode_destroy(decode);
367     return gst_vaapidecode_create(decode, caps);
368 }
369
370 /* GstImplementsInterface interface */
371
372 static gboolean
373 gst_vaapidecode_implements_interface_supported(
374     GstImplementsInterface *iface,
375     GType                   type
376 )
377 {
378     return (type == GST_TYPE_VIDEO_CONTEXT);
379 }
380
381 static void
382 gst_vaapidecode_implements_iface_init(GstImplementsInterfaceClass *iface)
383 {
384     iface->supported = gst_vaapidecode_implements_interface_supported;
385 }
386
387 /* GstVideoContext interface */
388
389 static void
390 gst_vaapidecode_set_video_context(GstVideoContext *context, const gchar *type,
391     const GValue *value)
392 {
393     GstVaapiDecode *decode = GST_VAAPIDECODE (context);
394     gst_vaapi_set_display (type, value, &decode->display);
395 }
396
397 static void
398 gst_video_context_interface_init(GstVideoContextInterface *iface)
399 {
400     iface->set_context = gst_vaapidecode_set_video_context;
401 }
402
403 static void
404 gst_vaapidecode_finalize(GObject *object)
405 {
406     GstVaapiDecode * const decode = GST_VAAPIDECODE(object);
407
408     gst_vaapidecode_destroy(decode);
409
410     gst_caps_replace(&decode->sinkpad_caps, NULL);
411     gst_caps_replace(&decode->srcpad_caps,  NULL);
412     gst_caps_replace(&decode->allowed_caps, NULL);
413
414     g_clear_object(&decode->display);
415
416     g_cond_clear(&decode->decoder_ready);
417     g_mutex_clear(&decode->decoder_mutex);
418
419     G_OBJECT_CLASS(gst_vaapidecode_parent_class)->finalize(object);
420 }
421
422 static gboolean
423 gst_vaapidecode_open(GstVideoDecoder *vdec)
424 {
425     GstVaapiDecode * const decode = GST_VAAPIDECODE(vdec);
426
427     decode->is_ready = TRUE;
428     return TRUE;
429 }
430
431 static gboolean
432 gst_vaapidecode_close(GstVideoDecoder *vdec)
433 {
434     GstVaapiDecode * const decode = GST_VAAPIDECODE(vdec);
435
436     gst_vaapidecode_destroy(decode);
437     g_clear_object(&decode->display);
438     decode->is_ready = FALSE;
439     return TRUE;
440 }
441
442 static gboolean
443 gst_vaapidecode_set_format(GstVideoDecoder *vdec, GstVideoCodecState *state)
444 {
445     GstVaapiDecode * const decode = GST_VAAPIDECODE(vdec);
446
447     if (!gst_vaapidecode_update_sink_caps(decode, state->caps))
448         return FALSE;
449     if (!gst_vaapidecode_update_src_caps(decode, state))
450         return FALSE;
451     if (!gst_vaapidecode_reset(decode, decode->sinkpad_caps))
452         return FALSE;
453     return TRUE;
454 }
455
456 static GstFlowReturn
457 gst_vaapidecode_parse(GstVideoDecoder *vdec,
458     GstVideoCodecFrame *frame, GstAdapter *adapter, gboolean at_eos)
459 {
460     GstVaapiDecode * const decode = GST_VAAPIDECODE(vdec);
461     GstVaapiDecoderStatus status;
462     GstFlowReturn ret;
463     guint got_unit_size;
464     gboolean got_frame;
465
466     status = gst_vaapi_decoder_parse(decode->decoder, frame,
467         adapter, at_eos, &got_unit_size, &got_frame);
468
469     switch (status) {
470     case GST_VAAPI_DECODER_STATUS_SUCCESS:
471         if (got_unit_size > 0)
472             gst_video_decoder_add_to_frame(vdec, got_unit_size);
473         if (got_frame)
474             ret = gst_video_decoder_have_frame(vdec);
475         else
476             ret = GST_FLOW_OK;
477         break;
478     case GST_VAAPI_DECODER_STATUS_ERROR_NO_DATA:
479         ret = GST_VIDEO_DECODER_FLOW_NEED_DATA;
480         break;
481     case GST_VAAPI_DECODER_STATUS_ERROR_UNSUPPORTED_CODEC:
482     case GST_VAAPI_DECODER_STATUS_ERROR_UNSUPPORTED_PROFILE:
483     case GST_VAAPI_DECODER_STATUS_ERROR_UNSUPPORTED_CHROMA_FORMAT:
484         GST_WARNING("parse error %d", status);
485         ret = GST_FLOW_NOT_SUPPORTED;
486         break;
487     default:
488         GST_ERROR("parse error %d", status);
489         ret = GST_FLOW_UNEXPECTED;
490         break;
491     }
492     return ret;
493 }
494
495 static void
496 gst_vaapidecode_class_init(GstVaapiDecodeClass *klass)
497 {
498     GObjectClass * const object_class = G_OBJECT_CLASS(klass);
499     GstElementClass * const element_class = GST_ELEMENT_CLASS(klass);
500     GstVideoDecoderClass * const vdec_class = GST_VIDEO_DECODER_CLASS(klass);
501     GstPadTemplate *pad_template;
502
503     GST_DEBUG_CATEGORY_INIT(gst_debug_vaapidecode,
504                             GST_PLUGIN_NAME, 0, GST_PLUGIN_DESC);
505
506     object_class->finalize   = gst_vaapidecode_finalize;
507
508     vdec_class->open         = GST_DEBUG_FUNCPTR(gst_vaapidecode_open);
509     vdec_class->close        = GST_DEBUG_FUNCPTR(gst_vaapidecode_close);
510     vdec_class->set_format   = GST_DEBUG_FUNCPTR(gst_vaapidecode_set_format);
511     vdec_class->parse        = GST_DEBUG_FUNCPTR(gst_vaapidecode_parse);
512     vdec_class->handle_frame = GST_DEBUG_FUNCPTR(gst_vaapidecode_handle_frame);
513
514     gst_element_class_set_details_simple(
515         element_class,
516         gst_vaapidecode_details.longname,
517         gst_vaapidecode_details.klass,
518         gst_vaapidecode_details.description,
519         gst_vaapidecode_details.author
520     );
521
522     /* sink pad */
523     pad_template = gst_static_pad_template_get(&gst_vaapidecode_sink_factory);
524     gst_element_class_add_pad_template(element_class, pad_template);
525     gst_object_unref(pad_template);
526
527     /* src pad */
528     pad_template = gst_static_pad_template_get(&gst_vaapidecode_src_factory);
529     gst_element_class_add_pad_template(element_class, pad_template);
530     gst_object_unref(pad_template);
531 }
532
533 static gboolean
534 gst_vaapidecode_ensure_allowed_caps(GstVaapiDecode *decode)
535 {
536     GstCaps *decode_caps;
537     guint i, n_decode_caps;
538
539     if (decode->allowed_caps)
540         return TRUE;
541
542     if (!gst_vaapidecode_ensure_display(decode))
543         goto error_no_display;
544
545     decode_caps = gst_vaapi_display_get_decode_caps(decode->display);
546     if (!decode_caps)
547         goto error_no_decode_caps;
548     n_decode_caps = gst_caps_get_size(decode_caps);
549
550     decode->allowed_caps = gst_caps_new_empty();
551     if (!decode->allowed_caps)
552         goto error_no_memory;
553
554     for (i = 0; i < n_decode_caps; i++) {
555         GstStructure *structure;
556         structure = gst_caps_get_structure(decode_caps, i);
557         if (!structure)
558             continue;
559         structure = gst_structure_copy(structure);
560         if (!structure)
561             continue;
562         gst_structure_remove_field(structure, "profile");
563         gst_structure_set(
564             structure,
565             "width",  GST_TYPE_INT_RANGE, 1, G_MAXINT,
566             "height", GST_TYPE_INT_RANGE, 1, G_MAXINT,
567             NULL
568         );
569         gst_caps_merge_structure(decode->allowed_caps, structure);
570     }
571
572     gst_caps_unref(decode_caps);
573     return TRUE;
574
575     /* ERRORS */
576 error_no_display:
577     {
578         GST_ERROR("failed to retrieve VA display");
579         return FALSE;
580     }
581 error_no_decode_caps:
582     {
583         GST_ERROR("failed to retrieve VA decode caps");
584         return FALSE;
585     }
586 error_no_memory:
587     {
588         GST_ERROR("failed to allocate allowed-caps set");
589         gst_caps_unref(decode_caps);
590         return FALSE;
591     }
592 }
593
594 static GstCaps *
595 gst_vaapidecode_get_caps(GstPad *pad)
596 {
597     GstVaapiDecode * const decode = GST_VAAPIDECODE(GST_OBJECT_PARENT(pad));
598
599     if (!decode->is_ready)
600         return gst_static_pad_template_get_caps(&gst_vaapidecode_sink_factory);
601
602     if (!gst_vaapidecode_ensure_allowed_caps(decode))
603         return gst_caps_new_empty();
604
605     return gst_caps_ref(decode->allowed_caps);
606 }
607
608 static gboolean
609 gst_vaapidecode_query (GstPad *pad, GstQuery *query) {
610     GstVaapiDecode *decode = GST_VAAPIDECODE (gst_pad_get_parent_element (pad));
611     gboolean res;
612
613     GST_DEBUG ("sharing display %p", decode->display);
614
615     if (gst_vaapi_reply_to_query (query, decode->display))
616       res = TRUE;
617     else if (GST_PAD_IS_SINK(pad))
618       res = decode->sinkpad_query(decode->sinkpad, query);
619     else
620       res = decode->srcpad_query(decode->srcpad, query);
621
622     g_object_unref (decode);
623     return res;
624 }
625
626 static void
627 gst_vaapidecode_init(GstVaapiDecode *decode)
628 {
629     GstVideoDecoder * const vdec = GST_VIDEO_DECODER(decode);
630
631     decode->display             = NULL;
632     decode->decoder             = NULL;
633     decode->decoder_caps        = NULL;
634     decode->allowed_caps        = NULL;
635     decode->render_time_base    = 0;
636     decode->last_buffer_time    = 0;
637     decode->is_ready            = FALSE;
638
639     g_mutex_init(&decode->decoder_mutex);
640     g_cond_init(&decode->decoder_ready);
641
642     gst_video_decoder_set_packetized(vdec, FALSE);
643
644     /* Pad through which data comes in to the element */
645     decode->sinkpad = GST_VIDEO_DECODER_SINK_PAD(vdec);
646     decode->sinkpad_query = GST_PAD_QUERYFUNC(decode->sinkpad);
647     gst_pad_set_query_function(decode->sinkpad, gst_vaapidecode_query);
648     gst_pad_set_getcaps_function(decode->sinkpad, gst_vaapidecode_get_caps);
649
650     /* Pad through which data goes out of the element */
651     decode->srcpad = GST_VIDEO_DECODER_SRC_PAD(vdec);
652     decode->srcpad_query = GST_PAD_QUERYFUNC(decode->srcpad);
653     gst_pad_set_query_function(decode->srcpad, gst_vaapidecode_query);
654 }