Tizen 2.0 Release
[framework/multimedia/gst-plugins-bad0.10.git] / sys / vdpau / mpeg / gstvdpmpegdec.c
1 /*
2  * GStreamer
3  * Copyright (C) 2009 Carl-Anton Ingmarsson <ca.ingmarsson@gmail.com>
4  *
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.
9  *
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.
14  *
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.
19  */
20
21 /**
22  * SECTION:element-vdpaumpegdec
23  *
24  * FIXME:Describe vdpaumpegdec here.
25  *
26  * <refsect2>
27  * <title>Example launch line</title>
28  * |[
29  * gst-launch -v -m fakesrc ! vdpaumpegdec ! fakesink silent=TRUE
30  * ]|
31  * </refsect2>
32  */
33
34 #ifdef HAVE_CONFIG_H
35 #include <config.h>
36 #endif
37
38 #include <gst/gst.h>
39 #include <gst/base/gstbytereader.h>
40 #include <gst/base/gstbitreader.h>
41 #include <string.h>
42
43 #include "mpegutil.h"
44
45 #include "gstvdpmpegdec.h"
46
47 GST_DEBUG_CATEGORY_STATIC (gst_vdp_mpeg_dec_debug);
48 #define GST_CAT_DEFAULT gst_vdp_mpeg_dec_debug
49
50 /* the capabilities of the inputs and outputs.
51  *
52  * describe the real formats here.
53  */
54 static GstStaticPadTemplate sink_template = GST_STATIC_PAD_TEMPLATE ("sink",
55     GST_PAD_SINK,
56     GST_PAD_ALWAYS,
57     GST_STATIC_CAPS ("video/mpeg, mpegversion = (int) [ 1, 2 ], "
58         "systemstream = (boolean) false")
59     );
60
61 #define DEBUG_INIT(bla) \
62     GST_DEBUG_CATEGORY_INIT (gst_vdp_mpeg_dec_debug, "vdpaumpegdec", 0, \
63     "VDPAU mpeg decoder");
64
65 GST_BOILERPLATE_FULL (GstVdpMpegDec, gst_vdp_mpeg_dec,
66     GstVdpDecoder, GST_TYPE_VDP_DECODER, DEBUG_INIT);
67
68 static void gst_vdp_mpeg_dec_init_info (VdpPictureInfoMPEG1Or2 * vdp_info);
69
70 #define SYNC_CODE_SIZE 3
71
72 static VdpDecoderProfile
73 gst_vdp_mpeg_dec_get_profile (MPEGSeqExtHdr * hdr)
74 {
75   VdpDecoderProfile profile;
76
77   switch (hdr->profile) {
78     case 5:
79       profile = VDP_DECODER_PROFILE_MPEG2_SIMPLE;
80       break;
81     default:
82       profile = VDP_DECODER_PROFILE_MPEG2_MAIN;
83       break;
84   }
85
86   return profile;
87 }
88
89 static gboolean
90 gst_vdp_mpeg_dec_handle_picture_coding (GstVdpMpegDec * mpeg_dec,
91     GstBuffer * buffer, GstVideoFrame * frame)
92 {
93   MPEGPictureExt pic_ext;
94   VdpPictureInfoMPEG1Or2 *info;
95   gint fields;
96
97   info = &mpeg_dec->vdp_info;
98
99   if (!mpeg_util_parse_picture_coding_extension (&pic_ext, buffer))
100     return FALSE;
101
102   memcpy (&mpeg_dec->vdp_info.f_code, &pic_ext.f_code, 4);
103
104   info->intra_dc_precision = pic_ext.intra_dc_precision;
105   info->picture_structure = pic_ext.picture_structure;
106   info->top_field_first = pic_ext.top_field_first;
107   info->frame_pred_frame_dct = pic_ext.frame_pred_frame_dct;
108   info->concealment_motion_vectors = pic_ext.concealment_motion_vectors;
109   info->q_scale_type = pic_ext.q_scale_type;
110   info->intra_vlc_format = pic_ext.intra_vlc_format;
111   info->alternate_scan = pic_ext.alternate_scan;
112
113   fields = 2;
114   if (pic_ext.picture_structure == 3) {
115     if (mpeg_dec->stream_info.interlaced) {
116       if (pic_ext.progressive_frame == 0)
117         fields = 2;
118       if (pic_ext.progressive_frame == 0 && pic_ext.repeat_first_field == 0)
119         fields = 2;
120       if (pic_ext.progressive_frame == 1 && pic_ext.repeat_first_field == 1)
121         fields = 3;
122     } else {
123       if (pic_ext.repeat_first_field == 0)
124         fields = 2;
125       if (pic_ext.repeat_first_field == 1 && pic_ext.top_field_first == 0)
126         fields = 4;
127       if (pic_ext.repeat_first_field == 1 && pic_ext.top_field_first == 1)
128         fields = 6;
129     }
130   } else
131     fields = 1;
132
133   frame->n_fields = fields;
134
135   if (pic_ext.top_field_first)
136     GST_VIDEO_FRAME_FLAG_SET (frame, GST_VIDEO_FRAME_FLAG_TFF);
137
138   return TRUE;
139 }
140
141 static gboolean
142 gst_vdp_mpeg_dec_handle_picture (GstVdpMpegDec * mpeg_dec, GstBuffer * buffer)
143 {
144   MPEGPictureHdr pic_hdr;
145
146   if (!mpeg_util_parse_picture_hdr (&pic_hdr, buffer))
147     return FALSE;
148
149   mpeg_dec->vdp_info.picture_coding_type = pic_hdr.pic_type;
150
151   if (mpeg_dec->stream_info.version == 1) {
152     mpeg_dec->vdp_info.full_pel_forward_vector =
153         pic_hdr.full_pel_forward_vector;
154     mpeg_dec->vdp_info.full_pel_backward_vector =
155         pic_hdr.full_pel_backward_vector;
156     memcpy (&mpeg_dec->vdp_info.f_code, &pic_hdr.f_code, 4);
157   }
158
159   mpeg_dec->frame_nr = mpeg_dec->gop_frame + pic_hdr.tsn;
160
161   return TRUE;
162 }
163
164 static gboolean
165 gst_vdp_mpeg_dec_handle_gop (GstVdpMpegDec * mpeg_dec, GstBuffer * buffer)
166 {
167   MPEGGop gop;
168   GstClockTime time;
169
170   if (!mpeg_util_parse_gop (&gop, buffer))
171     return FALSE;
172
173   time = GST_SECOND * (gop.hour * 3600 + gop.minute * 60 + gop.second);
174
175   GST_DEBUG ("gop timestamp: %" GST_TIME_FORMAT, GST_TIME_ARGS (time));
176
177   mpeg_dec->gop_frame =
178       gst_util_uint64_scale (time, mpeg_dec->stream_info.fps_n,
179       mpeg_dec->stream_info.fps_d * GST_SECOND) + gop.frame;
180
181   if (mpeg_dec->state == GST_VDP_MPEG_DEC_STATE_NEED_GOP)
182     mpeg_dec->state = GST_VDP_MPEG_DEC_STATE_NEED_DATA;
183
184   return TRUE;
185 }
186
187 static gboolean
188 gst_vdp_mpeg_dec_handle_quant_matrix (GstVdpMpegDec * mpeg_dec,
189     GstBuffer * buffer)
190 {
191   MPEGQuantMatrix qm;
192
193   if (!mpeg_util_parse_quant_matrix (&qm, buffer))
194     return FALSE;
195
196   memcpy (&mpeg_dec->vdp_info.intra_quantizer_matrix,
197       &qm.intra_quantizer_matrix, 64);
198   memcpy (&mpeg_dec->vdp_info.non_intra_quantizer_matrix,
199       &qm.non_intra_quantizer_matrix, 64);
200   return TRUE;
201 }
202
203 static GstFlowReturn
204 gst_vdp_mpeg_dec_handle_sequence (GstVdpMpegDec * mpeg_dec,
205     GstBuffer * seq, GstBuffer * seq_ext)
206 {
207   GstBaseVideoDecoder *base_video_decoder = GST_BASE_VIDEO_DECODER (mpeg_dec);
208
209   MPEGSeqHdr hdr;
210   GstVdpMpegStreamInfo stream_info;
211
212   if (!mpeg_util_parse_sequence_hdr (&hdr, seq))
213     return GST_FLOW_CUSTOM_ERROR;
214
215   memcpy (&mpeg_dec->vdp_info.intra_quantizer_matrix,
216       &hdr.intra_quantizer_matrix, 64);
217   memcpy (&mpeg_dec->vdp_info.non_intra_quantizer_matrix,
218       &hdr.non_intra_quantizer_matrix, 64);
219
220   stream_info.width = hdr.width;
221   stream_info.height = hdr.height;
222
223   stream_info.fps_n = hdr.fps_n;
224   stream_info.fps_d = hdr.fps_d;
225
226   stream_info.par_n = hdr.par_w;
227   stream_info.par_d = hdr.par_h;
228
229   stream_info.interlaced = FALSE;
230   stream_info.version = 1;
231   stream_info.profile = VDP_DECODER_PROFILE_MPEG1;
232
233   if (seq_ext) {
234     MPEGSeqExtHdr ext;
235
236     if (!mpeg_util_parse_sequence_extension (&ext, seq_ext))
237       return GST_FLOW_CUSTOM_ERROR;
238
239     stream_info.fps_n *= (ext.fps_n_ext + 1);
240     stream_info.fps_d *= (ext.fps_d_ext + 1);
241
242     stream_info.width += (ext.horiz_size_ext << 12);
243     stream_info.height += (ext.vert_size_ext << 12);
244
245     stream_info.interlaced = !ext.progressive;
246     stream_info.version = 2;
247     stream_info.profile = gst_vdp_mpeg_dec_get_profile (&ext);
248   }
249
250   if (memcmp (&mpeg_dec->stream_info, &stream_info,
251           sizeof (GstVdpMpegStreamInfo)) != 0) {
252     GstVideoState state;
253     GstFlowReturn ret;
254
255     state = gst_base_video_decoder_get_state (base_video_decoder);
256
257     state.width = stream_info.width;
258     state.height = stream_info.height;
259
260     state.fps_n = stream_info.fps_n;
261     state.fps_d = stream_info.fps_d;
262
263     state.par_n = stream_info.par_n;
264     state.par_d = stream_info.par_d;
265
266     state.interlaced = stream_info.interlaced;
267
268     gst_base_video_decoder_set_state (base_video_decoder, state);
269
270     ret = gst_vdp_decoder_init_decoder (GST_VDP_DECODER (mpeg_dec),
271         stream_info.profile, 2);
272     if (ret != GST_FLOW_OK)
273       return ret;
274
275     memcpy (&mpeg_dec->stream_info, &stream_info,
276         sizeof (GstVdpMpegStreamInfo));
277   }
278
279   mpeg_dec->state = GST_VDP_MPEG_DEC_STATE_NEED_DATA;
280
281   return GST_FLOW_OK;
282 }
283
284 static GstFlowReturn
285 gst_vdp_mpeg_dec_handle_frame (GstBaseVideoDecoder * base_video_decoder,
286     GstVideoFrame * frame, GstClockTimeDiff deadline)
287 {
288   GstVdpMpegDec *mpeg_dec = GST_VDP_MPEG_DEC (base_video_decoder);
289
290   VdpPictureInfoMPEG1Or2 *info;
291   GstVdpMpegFrame *mpeg_frame;
292
293   GstFlowReturn ret = GST_FLOW_OK;
294   VdpBitstreamBuffer vbit[1];
295   GstVdpVideoBuffer *outbuf;
296
297   /* MPEG_PACKET_SEQUENCE */
298   mpeg_frame = GST_VDP_MPEG_FRAME (frame);
299   if (mpeg_frame->seq) {
300     ret = gst_vdp_mpeg_dec_handle_sequence (mpeg_dec, mpeg_frame->seq,
301         mpeg_frame->seq_ext);
302     if (ret != GST_FLOW_OK) {
303       gst_base_video_decoder_skip_frame (base_video_decoder, frame);
304       return ret;
305     }
306   }
307
308   if (mpeg_dec->state == GST_VDP_MPEG_DEC_STATE_NEED_SEQUENCE) {
309     GST_DEBUG_OBJECT (mpeg_dec, "Drop frame since we haven't found a "
310         "MPEG_PACKET_SEQUENCE yet");
311
312     gst_base_video_decoder_skip_frame (base_video_decoder, frame);
313     return GST_FLOW_OK;
314   }
315
316   /* MPEG_PACKET_PICTURE */
317   if (mpeg_frame->pic)
318     gst_vdp_mpeg_dec_handle_picture (mpeg_dec, mpeg_frame->pic);
319
320   /* MPEG_PACKET_EXT_PICTURE_CODING */
321   if (mpeg_frame->pic_ext)
322     gst_vdp_mpeg_dec_handle_picture_coding (mpeg_dec, mpeg_frame->pic_ext,
323         frame);
324
325   /* MPEG_PACKET_GOP */
326   if (mpeg_frame->gop)
327     gst_vdp_mpeg_dec_handle_gop (mpeg_dec, mpeg_frame->gop);
328
329   /* MPEG_PACKET_EXT_QUANT_MATRIX */
330   if (mpeg_frame->qm_ext)
331     gst_vdp_mpeg_dec_handle_quant_matrix (mpeg_dec, mpeg_frame->qm_ext);
332
333
334   info = &mpeg_dec->vdp_info;
335
336   info->slice_count = mpeg_frame->n_slices;
337
338   /* check if we can decode the frame */
339   if (info->picture_coding_type != I_FRAME
340       && info->backward_reference == VDP_INVALID_HANDLE) {
341     GST_DEBUG_OBJECT (mpeg_dec,
342         "Drop frame since we haven't got an I_FRAME yet");
343
344     gst_base_video_decoder_skip_frame (base_video_decoder, frame);
345     return GST_FLOW_OK;
346   }
347   if (info->picture_coding_type == B_FRAME
348       && info->forward_reference == VDP_INVALID_HANDLE) {
349     GST_DEBUG_OBJECT (mpeg_dec,
350         "Drop frame since we haven't got two non B_FRAMES yet");
351
352     gst_base_video_decoder_skip_frame (base_video_decoder, frame);
353     return GST_FLOW_OK;
354   }
355
356
357   if (info->picture_coding_type != B_FRAME) {
358     if (info->backward_reference != VDP_INVALID_HANDLE) {
359       ret = gst_base_video_decoder_finish_frame (base_video_decoder,
360           mpeg_dec->b_frame);
361     }
362
363     if (info->forward_reference != VDP_INVALID_HANDLE) {
364       gst_video_frame_unref (mpeg_dec->f_frame);
365       info->forward_reference = VDP_INVALID_HANDLE;
366     }
367
368     info->forward_reference = info->backward_reference;
369     mpeg_dec->f_frame = mpeg_dec->b_frame;
370
371     info->backward_reference = VDP_INVALID_HANDLE;
372   }
373
374   if (ret != GST_FLOW_OK) {
375     gst_base_video_decoder_skip_frame (base_video_decoder, frame);
376     return ret;
377   }
378
379   /* decode */
380   vbit[0].struct_version = VDP_BITSTREAM_BUFFER_VERSION;
381   vbit[0].bitstream = GST_BUFFER_DATA (mpeg_frame->slices);
382   vbit[0].bitstream_bytes = GST_BUFFER_SIZE (mpeg_frame->slices);
383
384   ret = gst_vdp_decoder_render (GST_VDP_DECODER (mpeg_dec),
385       (VdpPictureInfo *) info, 1, vbit, &outbuf);
386   if (ret != GST_FLOW_OK)
387     return ret;
388
389   frame->src_buffer = GST_BUFFER_CAST (outbuf);
390
391   if (info->picture_coding_type == B_FRAME) {
392     ret = gst_base_video_decoder_finish_frame (base_video_decoder, frame);
393   } else {
394     info->backward_reference = GST_VDP_VIDEO_BUFFER (outbuf)->surface;
395     mpeg_dec->b_frame = gst_video_frame_ref (frame);
396   }
397
398   return ret;
399 }
400
401 static GstVideoFrame *
402 gst_vdp_mpeg_dec_create_frame (GstBaseVideoDecoder * base_video_decoder)
403 {
404   return GST_VIDEO_FRAME (gst_vdp_mpeg_frame_new ());
405 }
406
407 static GstFlowReturn
408 gst_vdp_mpeg_dec_parse_data (GstBaseVideoDecoder * base_video_decoder,
409     GstBuffer * buf, gboolean at_eos, GstVideoFrame * frame)
410 {
411   GstVdpMpegDec *mpeg_dec = GST_VDP_MPEG_DEC (base_video_decoder);
412
413   GstVdpMpegFrame *mpeg_frame;
414   GstFlowReturn ret = GST_FLOW_OK;
415   GstBitReader b_reader = GST_BIT_READER_INIT_FROM_BUFFER (buf);
416   guint8 start_code;
417
418   /* skip sync_code */
419   gst_bit_reader_skip (&b_reader, 8 * 3);
420
421   /* start_code */
422   if (!gst_bit_reader_get_bits_uint8 (&b_reader, &start_code, 8))
423     return GST_FLOW_ERROR;
424
425   mpeg_frame = GST_VDP_MPEG_FRAME_CAST (frame);
426
427   if (start_code >= MPEG_PACKET_SLICE_MIN
428       && start_code <= MPEG_PACKET_SLICE_MAX) {
429     GST_DEBUG_OBJECT (mpeg_dec, "MPEG_PACKET_SLICE");
430
431     gst_vdp_mpeg_frame_add_slice (mpeg_frame, buf);
432     goto done;
433   }
434
435   switch (start_code) {
436     case MPEG_PACKET_SEQUENCE:
437       GST_DEBUG_OBJECT (mpeg_dec, "MPEG_PACKET_SEQUENCE");
438
439       if (mpeg_dec->prev_packet != -1)
440         ret = gst_base_video_decoder_have_frame (base_video_decoder, FALSE,
441             (GstVideoFrame **) & mpeg_frame);
442
443       mpeg_frame->seq = buf;
444       break;
445
446     case MPEG_PACKET_PICTURE:
447       GST_DEBUG_OBJECT (mpeg_dec, "MPEG_PACKET_PICTURE");
448
449       if (mpeg_dec->prev_packet != MPEG_PACKET_SEQUENCE &&
450           mpeg_dec->prev_packet != MPEG_PACKET_GOP)
451         ret = gst_base_video_decoder_have_frame (base_video_decoder, FALSE,
452             (GstVideoFrame **) & mpeg_frame);
453
454       mpeg_frame->pic = buf;
455       break;
456
457     case MPEG_PACKET_GOP:
458       GST_DEBUG_OBJECT (mpeg_dec, "MPEG_PACKET_GOP");
459
460       if (mpeg_dec->prev_packet != MPEG_PACKET_SEQUENCE)
461         ret = gst_base_video_decoder_have_frame (base_video_decoder, FALSE,
462             (GstVideoFrame **) & mpeg_frame);
463
464       mpeg_frame->gop = buf;
465       break;
466
467     case MPEG_PACKET_EXTENSION:
468     {
469       guint8 ext_code;
470
471       /* ext_code */
472       if (!gst_bit_reader_get_bits_uint8 (&b_reader, &ext_code, 4)) {
473         ret = GST_FLOW_ERROR;
474         gst_buffer_unref (buf);
475         goto done;
476       }
477
478       GST_DEBUG_OBJECT (mpeg_dec, "MPEG_PACKET_EXTENSION: %d", ext_code);
479
480       switch (ext_code) {
481         case MPEG_PACKET_EXT_SEQUENCE:
482           GST_DEBUG_OBJECT (mpeg_dec, "MPEG_PACKET_EXT_SEQUENCE");
483
484
485           mpeg_frame->seq_ext = buf;
486
487           /* so that we don't finish the frame if we get a MPEG_PACKET_PICTURE
488            * or MPEG_PACKET_GOP after this */
489           start_code = MPEG_PACKET_SEQUENCE;
490           break;
491
492         case MPEG_PACKET_EXT_SEQUENCE_DISPLAY:
493           GST_DEBUG_OBJECT (mpeg_dec, "MPEG_PACKET_EXT_SEQUENCE_DISPLAY");
494
495           /* so that we don't finish the frame if we get a MPEG_PACKET_PICTURE
496            * or MPEG_PACKET_GOP after this */
497           start_code = MPEG_PACKET_SEQUENCE;
498           break;
499
500         case MPEG_PACKET_EXT_PICTURE_CODING:
501           GST_DEBUG_OBJECT (mpeg_dec, "MPEG_PACKET_EXT_PICTURE_CODING");
502
503           mpeg_frame->pic_ext = buf;
504           break;
505
506         case MPEG_PACKET_EXT_QUANT_MATRIX:
507           GST_DEBUG_OBJECT (mpeg_dec, "MPEG_PACKET_EXT_QUANT_MATRIX");
508
509           mpeg_frame->qm_ext = buf;
510           break;
511
512         default:
513           gst_buffer_unref (buf);
514       }
515       break;
516     }
517
518     default:
519       gst_buffer_unref (buf);
520   }
521
522   if (at_eos && mpeg_frame->slices)
523     ret = gst_base_video_decoder_have_frame (base_video_decoder, TRUE, NULL);
524
525 done:
526   mpeg_dec->prev_packet = start_code;
527
528   return ret;
529 }
530
531 static gint
532 gst_vdp_mpeg_dec_scan_for_sync (GstBaseVideoDecoder * base_video_decoder,
533     GstAdapter * adapter)
534 {
535   gint m;
536
537   m = gst_adapter_masked_scan_uint32 (adapter, 0xffffff00, 0x00000100, 0,
538       gst_adapter_available (adapter));
539   if (m == -1)
540     return gst_adapter_available (adapter) - SYNC_CODE_SIZE;
541
542   return m;
543 }
544
545 static GstBaseVideoDecoderScanResult
546 gst_vdp_mpeg_dec_scan_for_packet_end (GstBaseVideoDecoder * base_video_decoder,
547     GstAdapter * adapter, guint * size, gboolean at_eos)
548 {
549   guint8 *data;
550   guint32 sync_code;
551
552   data = g_slice_alloc (SYNC_CODE_SIZE);
553   gst_adapter_copy (adapter, data, 0, SYNC_CODE_SIZE);
554   sync_code = ((data[0] << 16) | (data[1] << 8) | data[2]);
555
556   if (sync_code != 0x000001)
557     return GST_BASE_VIDEO_DECODER_SCAN_RESULT_LOST_SYNC;
558
559   *size = gst_adapter_masked_scan_uint32 (adapter, 0xffffff00, 0x00000100,
560       SYNC_CODE_SIZE, gst_adapter_available (adapter) - SYNC_CODE_SIZE);
561
562   if (*size == -1)
563     return GST_BASE_VIDEO_DECODER_SCAN_RESULT_NEED_DATA;
564
565   return GST_BASE_VIDEO_DECODER_SCAN_RESULT_OK;
566 }
567
568 static gboolean
569 gst_vdp_mpeg_dec_flush (GstBaseVideoDecoder * base_video_decoder)
570 {
571   GstVdpMpegDec *mpeg_dec = GST_VDP_MPEG_DEC (base_video_decoder);
572
573   if (mpeg_dec->vdp_info.forward_reference != VDP_INVALID_HANDLE)
574     gst_video_frame_unref (mpeg_dec->f_frame);
575   if (mpeg_dec->vdp_info.backward_reference != VDP_INVALID_HANDLE)
576     gst_video_frame_unref (mpeg_dec->b_frame);
577
578   gst_vdp_mpeg_dec_init_info (&mpeg_dec->vdp_info);
579
580   mpeg_dec->prev_packet = -1;
581
582   return TRUE;
583 }
584
585 static gboolean
586 gst_vdp_mpeg_dec_start (GstBaseVideoDecoder * base_video_decoder)
587 {
588   GstVdpMpegDec *mpeg_dec = GST_VDP_MPEG_DEC (base_video_decoder);
589
590   gst_vdp_mpeg_dec_init_info (&mpeg_dec->vdp_info);
591
592   mpeg_dec->decoder = VDP_INVALID_HANDLE;
593   mpeg_dec->state = GST_VDP_MPEG_DEC_STATE_NEED_SEQUENCE;
594
595   memset (&mpeg_dec->stream_info, 0, sizeof (GstVdpMpegStreamInfo));
596
597   return GST_BASE_VIDEO_DECODER_CLASS
598       (parent_class)->start (base_video_decoder);
599 }
600
601 static gboolean
602 gst_vdp_mpeg_dec_stop (GstBaseVideoDecoder * base_video_decoder)
603 {
604   GstVdpMpegDec *mpeg_dec = GST_VDP_MPEG_DEC (base_video_decoder);
605
606   if (mpeg_dec->vdp_info.forward_reference != VDP_INVALID_HANDLE)
607     mpeg_dec->vdp_info.forward_reference = VDP_INVALID_HANDLE;
608   if (mpeg_dec->vdp_info.backward_reference != VDP_INVALID_HANDLE)
609     mpeg_dec->vdp_info.backward_reference = VDP_INVALID_HANDLE;
610
611   mpeg_dec->state = GST_VDP_MPEG_DEC_STATE_NEED_SEQUENCE;
612
613   return GST_BASE_VIDEO_DECODER_CLASS (parent_class)->stop (base_video_decoder);
614 }
615
616 static void
617 gst_vdp_mpeg_dec_base_init (gpointer gclass)
618 {
619   GstElementClass *element_class = GST_ELEMENT_CLASS (gclass);
620
621   gst_element_class_set_details_simple (element_class,
622       "VDPAU Mpeg Decoder",
623       "Decoder",
624       "Decode mpeg stream with vdpau",
625       "Carl-Anton Ingmarsson <ca.ingmarsson@gmail.com>");
626
627   gst_element_class_add_static_pad_template (element_class,
628       &sink_template);
629 }
630
631 /* initialize the vdpaumpegdecoder's class */
632 static void
633 gst_vdp_mpeg_dec_class_init (GstVdpMpegDecClass * klass)
634 {
635   GstBaseVideoDecoderClass *base_video_decoder_class;
636
637   base_video_decoder_class = GST_BASE_VIDEO_DECODER_CLASS (klass);
638
639   base_video_decoder_class->start = gst_vdp_mpeg_dec_start;
640   base_video_decoder_class->stop = gst_vdp_mpeg_dec_stop;
641   base_video_decoder_class->flush = gst_vdp_mpeg_dec_flush;
642
643   base_video_decoder_class->scan_for_sync = gst_vdp_mpeg_dec_scan_for_sync;
644   base_video_decoder_class->scan_for_packet_end =
645       gst_vdp_mpeg_dec_scan_for_packet_end;
646   base_video_decoder_class->parse_data = gst_vdp_mpeg_dec_parse_data;
647
648   base_video_decoder_class->handle_frame = gst_vdp_mpeg_dec_handle_frame;
649   base_video_decoder_class->create_frame = gst_vdp_mpeg_dec_create_frame;
650 }
651
652 static void
653 gst_vdp_mpeg_dec_init_info (VdpPictureInfoMPEG1Or2 * vdp_info)
654 {
655   vdp_info->forward_reference = VDP_INVALID_HANDLE;
656   vdp_info->backward_reference = VDP_INVALID_HANDLE;
657   vdp_info->slice_count = 0;
658   vdp_info->picture_structure = 3;
659   vdp_info->picture_coding_type = 0;
660   vdp_info->intra_dc_precision = 0;
661   vdp_info->frame_pred_frame_dct = 1;
662   vdp_info->concealment_motion_vectors = 0;
663   vdp_info->intra_vlc_format = 0;
664   vdp_info->alternate_scan = 0;
665   vdp_info->q_scale_type = 0;
666   vdp_info->top_field_first = 1;
667 }
668
669 static void
670 gst_vdp_mpeg_dec_init (GstVdpMpegDec * mpeg_dec, GstVdpMpegDecClass * gclass)
671 {
672 }