Fix the typecast warnings:
[vaapi:sree-gstreamer-vaapi.git] / gst-libs / gst / vaapi / gstvaapidecoder_vc1.c
1 /*
2  *  gstvaapidecoder_vc1.c - VC-1 decoder
3  *
4  *  Copyright (C) 2011 Intel Corporation
5  *
6  *  This library is free software; you can redistribute it and/or
7  *  modify it under the terms of the GNU Lesser General Public License
8  *  as published by the Free Software Foundation; either version 2.1
9  *  of the License, or (at your option) any later version.
10  *
11  *  This library is distributed in the hope that it will be useful,
12  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
13  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  *  Lesser General Public License for more details.
15  *
16  *  You should have received a copy of the GNU Lesser General Public
17  *  License along with this library; if not, write to the Free
18  *  Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
19  *  Boston, MA 02110-1301 USA
20  */
21
22 /**
23  * SECTION:gstvaapidecoder_vc1
24  * @short_description: VC-1 decoder
25  */
26
27 #include "sysdeps.h"
28 #include <string.h>
29 #include <gst/codecparsers/gstvc1parser.h>
30 #include "gstvaapidecoder_vc1.h"
31 #include "gstvaapidecoder_objects.h"
32 #include "gstvaapidecoder_priv.h"
33 #include "gstvaapidisplay_priv.h"
34 #include "gstvaapiobject_priv.h"
35
36 #define DEBUG 1
37 #include "gstvaapidebug.h"
38
39 G_DEFINE_TYPE(GstVaapiDecoderVC1,
40               gst_vaapi_decoder_vc1,
41               GST_VAAPI_TYPE_DECODER)
42
43 #define GST_VAAPI_DECODER_VC1_GET_PRIVATE(obj)                  \
44     (G_TYPE_INSTANCE_GET_PRIVATE((obj),                         \
45                                  GST_VAAPI_TYPE_DECODER_VC1,    \
46                                  GstVaapiDecoderVC1Private))
47
48 struct _GstVaapiDecoderVC1Private {
49     GstVaapiProfile             profile;
50     guint                       width;
51     guint                       height;
52     guint                       fps_n;
53     guint                       fps_d;
54     GstVC1SeqHdr                seq_hdr;
55     GstVC1EntryPointHdr         entrypoint_hdr;
56     GstVC1FrameHdr              frame_hdr;
57     GstVC1BitPlanes            *bitplanes;
58     GstVaapiPicture            *current_picture;
59     GstVaapiPicture            *next_picture;
60     GstVaapiPicture            *prev_picture;
61     GstAdapter                 *adapter;
62     guint8                     *rbdu_buffer;
63     guint                       rbdu_buffer_size;
64     guint                       is_constructed          : 1;
65     guint                       is_opened               : 1;
66     guint                       is_first_field          : 1;
67     guint                       has_entrypoint          : 1;
68     guint                       size_changed            : 1;
69     guint                       profile_changed         : 1;
70     guint                       closed_entry            : 1;
71     guint                       broken_link             : 1;
72     guint                       reset_context           : 1;
73 };
74
75 static GstVaapiDecoderStatus
76 get_status(GstVC1ParserResult result)
77 {
78     GstVaapiDecoderStatus status;
79
80     switch (result) {
81     case GST_VC1_PARSER_OK:
82         status = GST_VAAPI_DECODER_STATUS_SUCCESS;
83         break;
84     case GST_VC1_PARSER_NO_BDU_END:
85         status = GST_VAAPI_DECODER_STATUS_ERROR_NO_DATA;
86         break;
87     case GST_VC1_PARSER_ERROR:
88         status = GST_VAAPI_DECODER_STATUS_ERROR_BITSTREAM_PARSER;
89         break;
90     default:
91         status = GST_VAAPI_DECODER_STATUS_ERROR_UNKNOWN;
92         break;
93     }
94     return status;
95 }
96
97 static void
98 gst_vaapi_decoder_vc1_close(GstVaapiDecoderVC1 *decoder)
99 {
100     GstVaapiDecoderVC1Private * const priv = decoder->priv;
101
102     gst_vaapi_picture_replace(&priv->current_picture, NULL);
103     gst_vaapi_picture_replace(&priv->next_picture,    NULL);
104     gst_vaapi_picture_replace(&priv->prev_picture,    NULL);
105
106     if (priv->bitplanes) {
107         gst_vc1_bitplanes_free(priv->bitplanes);
108         priv->bitplanes = NULL;
109     }
110
111 }
112
113 static gboolean
114 gst_vaapi_decoder_vc1_open(GstVaapiDecoderVC1 *decoder)
115 {
116     GstVaapiDecoderVC1Private * const priv = decoder->priv;
117
118     gst_vaapi_decoder_vc1_close(decoder);
119
120     priv->bitplanes = gst_vc1_bitplanes_new();
121     if (!priv->bitplanes)
122         return FALSE;
123     return TRUE;
124 }
125
126 static void
127 gst_vaapi_decoder_vc1_destroy(GstVaapiDecoderVC1 *decoder)
128 {
129     GstVaapiDecoderVC1Private * const priv = decoder->priv;
130
131     gst_vaapi_decoder_vc1_close(decoder);
132
133     if (priv->rbdu_buffer) {
134         g_free(priv->rbdu_buffer);
135         priv->rbdu_buffer = NULL;
136         priv->rbdu_buffer_size = 0;
137     }
138 }
139
140 static gboolean
141 gst_vaapi_decoder_vc1_create(GstVaapiDecoderVC1 *decoder)
142 {
143     if (!GST_VAAPI_DECODER_CODEC(decoder))
144         return FALSE;
145     return TRUE;
146 }
147
148 static void
149 check_context_reset (GstVaapiDecoderVC1 *decoder)
150 {
151     GstVaapiDecoderVC1Private * const priv = decoder->priv;
152     GstVaapiProfile profiles[2];
153     GstVaapiEntrypoint entrypoint = GST_VAAPI_ENTRYPOINT_VLD;
154     guint i, n_profiles = 0;
155     gboolean reset_context = FALSE;
156
157     if (priv->profile_changed) {
158         GST_DEBUG("profile changed");
159         priv->profile_changed = FALSE;
160         priv->reset_context   = TRUE;
161
162         profiles[n_profiles++] = priv->profile;
163         if (priv->profile == GST_VAAPI_PROFILE_VC1_SIMPLE)
164             profiles[n_profiles++] = GST_VAAPI_PROFILE_VC1_MAIN;
165
166         for (i = 0; i < n_profiles; i++) {
167             if (gst_vaapi_display_has_decoder(GST_VAAPI_DECODER_DISPLAY(decoder),
168                                               profiles[i], entrypoint))
169                 break;
170         }
171
172         g_return_if_fail(i != n_profiles);
173
174         priv->profile = profiles[i];
175     }
176
177     if (priv->size_changed) {
178         GST_DEBUG("size changed");
179         priv->size_changed = FALSE;
180         priv->reset_context      = TRUE;
181     }
182      if(priv->reset_context)
183         gst_vaapi_decoder_emit_caps_change(GST_VAAPI_DECODER_CAST(decoder), priv->width, priv->height);
184
185 }
186
187 static GstVaapiDecoderStatus
188 ensure_context(GstVaapiDecoderVC1 *decoder, GstBufferPool *pool)
189 {
190     GstVaapiDecoderVC1Private * const priv = decoder->priv;
191     GstVaapiEntrypoint entrypoint = GST_VAAPI_ENTRYPOINT_VLD;
192     gboolean reset_context = FALSE;
193
194     if (priv->reset_context) {
195         GstVaapiContextInfo info;
196
197         info.profile    = priv->profile;
198         info.entrypoint = entrypoint;
199         info.width      = priv->width;
200         info.height     = priv->height;
201         info.ref_frames = 2;
202         info.pool       = GST_VAAPI_SURFACE_POOL(pool);
203         reset_context   = gst_vaapi_decoder_ensure_context(
204             GST_VAAPI_DECODER(decoder),
205             &info
206         );
207         if (!reset_context)
208             return GST_VAAPI_DECODER_STATUS_ERROR_UNKNOWN;
209         priv->reset_context = FALSE;
210     }
211     return GST_VAAPI_DECODER_STATUS_SUCCESS;
212 }
213
214 static inline GstVaapiDecoderStatus
215 render_picture(GstVaapiDecoderVC1 *decoder, GstVaapiPicture *picture)
216 {
217     if (!gst_vaapi_picture_output(picture)) {
218         return GST_VAAPI_DECODER_STATUS_ERROR_ALLOCATION_FAILED;
219     }
220     return GST_VAAPI_DECODER_STATUS_SUCCESS;
221 }
222
223 static GstVaapiDecoderStatus
224 decode_current_picture(GstVaapiDecoderVC1 *decoder)
225 {
226     GstVaapiDecoderVC1Private * const priv = decoder->priv;
227     GstVaapiPicture * const picture = priv->current_picture;
228     GstVaapiDecoderStatus status = GST_VAAPI_DECODER_STATUS_SUCCESS;
229
230     if (picture) {
231         if (!gst_vaapi_picture_decode(picture))
232             status = GST_VAAPI_DECODER_STATUS_ERROR_UNKNOWN;
233         
234         if (!GST_VAAPI_PICTURE_IS_REFERENCE(picture)) {
235             if (priv->prev_picture && priv->next_picture)
236                 status = render_picture(decoder, picture);
237         }
238         gst_vaapi_picture_replace(&priv->current_picture, NULL);
239     }
240     return status;
241 }
242
243 static GstVaapiDecoderStatus
244 decode_sequence(GstVaapiDecoderVC1 *decoder, GstVC1BDU *rbdu, GstVC1BDU *ebdu)
245 {
246     GstVaapiDecoder * const base_decoder = GST_VAAPI_DECODER(decoder);
247     GstVaapiDecoderVC1Private * const priv = decoder->priv;
248     GstVC1SeqHdr * const seq_hdr = &priv->seq_hdr;
249     GstVC1AdvancedSeqHdr * const adv_hdr = &seq_hdr->advanced;
250     GstVC1SeqStructC * const structc = &seq_hdr->struct_c;
251     GstVC1ParserResult result;
252     GstVaapiProfile profile;
253     guint width, height, fps_n, fps_d;
254
255     result = gst_vc1_parse_sequence_header(
256         rbdu->data + rbdu->offset,
257         rbdu->size,
258         seq_hdr
259     );
260     if (result != GST_VC1_PARSER_OK) {
261         GST_DEBUG("failed to parse sequence layer");
262         return get_status(result);
263     }
264
265     priv->has_entrypoint = FALSE;
266
267     /* Validate profile */
268     switch (seq_hdr->profile) {
269     case GST_VC1_PROFILE_SIMPLE:
270     case GST_VC1_PROFILE_MAIN:
271     case GST_VC1_PROFILE_ADVANCED:
272         break;
273     default:
274         GST_DEBUG("unsupported profile %d", seq_hdr->profile);
275         return GST_VAAPI_DECODER_STATUS_ERROR_UNSUPPORTED_PROFILE;
276     }
277
278     fps_n = 0;
279     fps_d = 0;
280     switch (seq_hdr->profile) {
281     case GST_VC1_PROFILE_SIMPLE:
282     case GST_VC1_PROFILE_MAIN:
283         if (structc->wmvp) {
284             fps_n = structc->framerate;
285             fps_d = 1;
286         }
287         break;
288     case GST_VC1_PROFILE_ADVANCED:
289         if (adv_hdr->display_ext && adv_hdr->framerate_flag) {
290             if (adv_hdr->framerateind) {
291                 // 6.1.14.4.4 - Frame Rate Explicit
292                 fps_n = adv_hdr->framerateexp + 1;
293                 fps_d = 32;
294             }
295             else {
296                 // 6.1.14.4.2 - Frame Rate Numerator
297                 static const guint frameratenr_table[] = {
298                     [1] = 24000,
299                     [2] = 25000,
300                     [3] = 30000,
301                     [4] = 50000,
302                     [5] = 60000,
303                     [6] = 48000,
304                     [7] = 72000
305                 };
306
307                 // 6.1.14.4.3 - Frame Rate Denominator
308                 static const guint frameratedr_table[] = {
309                     [1] = 1000,
310                     [2] = 1001
311                 };
312
313                 if (adv_hdr->frameratenr < 1 || adv_hdr->frameratenr > 7) {
314                     GST_DEBUG("unsupported FRAMERATENR value");
315                     return GST_VAAPI_DECODER_STATUS_ERROR_BITSTREAM_PARSER;
316                 }
317                 fps_n = frameratenr_table[adv_hdr->frameratenr];
318
319                 if (adv_hdr->frameratedr < 1 || adv_hdr->frameratedr > 2) {
320                     GST_DEBUG("unsupported FRAMERATEDR value");
321                     return GST_VAAPI_DECODER_STATUS_ERROR_BITSTREAM_PARSER;
322                 }
323                 fps_d = frameratedr_table[adv_hdr->frameratedr];
324             }
325         }
326         break;
327     default:
328         g_assert(0 && "XXX: we already validated the profile above");
329         break;
330     }
331     if (fps_n && fps_d) {
332         priv->fps_n = fps_n;
333         priv->fps_d = fps_d;
334         gst_vaapi_decoder_set_framerate(base_decoder, priv->fps_n, priv->fps_d);
335     }
336
337     switch (seq_hdr->profile) {
338     case GST_VC1_PROFILE_SIMPLE:
339     case GST_VC1_PROFILE_MAIN:
340         width  = seq_hdr->struct_c.coded_width;
341         height = seq_hdr->struct_c.coded_height;
342         break;
343     case GST_VC1_PROFILE_ADVANCED:
344         width  = seq_hdr->advanced.max_coded_width;
345         height = seq_hdr->advanced.max_coded_height;
346         break;
347     default:
348         g_assert(0 && "XXX: we already validated the profile above");
349         break;
350     }
351
352     if (priv->width != width) {
353         priv->width = width;
354         priv->size_changed = TRUE;
355     }
356
357     if (priv->height != height) {
358         priv->height = height;
359         priv->size_changed = TRUE;
360     }
361
362     switch (seq_hdr->profile) {
363     case GST_VC1_PROFILE_SIMPLE:
364         profile = GST_VAAPI_PROFILE_VC1_SIMPLE;
365         break;
366     case GST_VC1_PROFILE_MAIN:
367         profile = GST_VAAPI_PROFILE_VC1_MAIN;
368         break;
369     case GST_VC1_PROFILE_ADVANCED:
370         profile = GST_VAAPI_PROFILE_VC1_ADVANCED;
371         break;
372     default:
373         g_assert(0 && "XXX: we already validated the profile above");
374         break;
375     }
376     if (priv->profile != profile) {
377         priv->profile = profile;
378         priv->profile_changed = TRUE;
379     }
380     return GST_VAAPI_DECODER_STATUS_SUCCESS;
381 }
382
383 static GstVaapiDecoderStatus
384 decode_sequence_end(GstVaapiDecoderVC1 *decoder)
385 {
386     GstVaapiDecoderVC1Private * const priv = decoder->priv;
387     GstVaapiDecoderStatus status;
388
389     if (priv->current_picture) {
390         status = decode_current_picture(decoder);
391         if (status != GST_VAAPI_DECODER_STATUS_SUCCESS)
392             return status;
393         status = render_picture(decoder, priv->current_picture);
394         if (status != GST_VAAPI_DECODER_STATUS_SUCCESS)
395             return status;
396     }
397
398     if (priv->next_picture) {
399         status = render_picture(decoder, priv->next_picture);
400         if (status != GST_VAAPI_DECODER_STATUS_SUCCESS)
401             return status;
402     }
403     return GST_VAAPI_DECODER_STATUS_END_OF_STREAM;
404 }
405
406 static GstVaapiDecoderStatus
407 decode_entry_point(GstVaapiDecoderVC1 *decoder, GstVC1BDU *rbdu, GstVC1BDU *ebdu)
408 {
409     GstVaapiDecoderVC1Private * const priv = decoder->priv;
410     GstVC1SeqHdr * const seq_hdr = &priv->seq_hdr;
411     GstVC1EntryPointHdr * const entrypoint_hdr = &priv->entrypoint_hdr;
412     GstVC1ParserResult result;
413
414     result = gst_vc1_parse_entry_point_header(
415         rbdu->data + rbdu->offset,
416         rbdu->size,
417         entrypoint_hdr,
418         seq_hdr
419     );
420     if (result != GST_VC1_PARSER_OK) {
421         GST_DEBUG("failed to parse entrypoint layer");
422         return get_status(result);
423     }
424
425     if (entrypoint_hdr->coded_size_flag) {
426         priv->width        = entrypoint_hdr->coded_width;
427         priv->height       = entrypoint_hdr->coded_height;
428         priv->size_changed = TRUE;
429     }
430
431     priv->has_entrypoint = TRUE;
432     priv->closed_entry   = entrypoint_hdr->closed_entry;
433     priv->broken_link    = entrypoint_hdr->broken_link;
434     return GST_VAAPI_DECODER_STATUS_SUCCESS;
435 }
436
437 /* Reconstruct bitstream PTYPE (7.1.1.4, index into Table-35) */
438 static guint
439 get_PTYPE(guint ptype)
440 {
441     switch (ptype) {
442     case GST_VC1_PICTURE_TYPE_I:  return 0;
443     case GST_VC1_PICTURE_TYPE_P:  return 1;
444     case GST_VC1_PICTURE_TYPE_B:  return 2;
445     case GST_VC1_PICTURE_TYPE_BI: return 3;
446     }
447     return 4; /* skipped P-frame */
448 }
449
450 /* Reconstruct bitstream BFRACTION (7.1.1.14, index into Table-40) */
451 static guint
452 get_BFRACTION(guint bfraction)
453 {
454     guint i;
455
456     static const struct {
457         guint16 index;
458         guint16 value;
459     }
460     bfraction_map[] = {
461         {  0,  GST_VC1_BFRACTION_BASIS      / 2 },
462         {  1,  GST_VC1_BFRACTION_BASIS      / 3 },
463         {  2, (GST_VC1_BFRACTION_BASIS * 2) / 3 },
464         {  3,  GST_VC1_BFRACTION_BASIS      / 4 },
465         {  4, (GST_VC1_BFRACTION_BASIS * 3) / 4 },
466         {  5,  GST_VC1_BFRACTION_BASIS      / 5 },
467         {  6, (GST_VC1_BFRACTION_BASIS * 2) / 5 },
468         {  7, (GST_VC1_BFRACTION_BASIS * 3) / 5 },
469         {  8, (GST_VC1_BFRACTION_BASIS * 4) / 5 },
470         {  9,  GST_VC1_BFRACTION_BASIS      / 6 },
471         { 10, (GST_VC1_BFRACTION_BASIS * 5) / 6 },
472         { 11,  GST_VC1_BFRACTION_BASIS      / 7 },
473         { 12, (GST_VC1_BFRACTION_BASIS * 2) / 7 },
474         { 13, (GST_VC1_BFRACTION_BASIS * 3) / 7 },
475         { 14, (GST_VC1_BFRACTION_BASIS * 4) / 7 },
476         { 15, (GST_VC1_BFRACTION_BASIS * 5) / 7 },
477         { 16, (GST_VC1_BFRACTION_BASIS * 6) / 7 },
478         { 17,  GST_VC1_BFRACTION_BASIS      / 8 },
479         { 18, (GST_VC1_BFRACTION_BASIS * 3) / 8 },
480         { 19, (GST_VC1_BFRACTION_BASIS * 5) / 8 },
481         { 20, (GST_VC1_BFRACTION_BASIS * 7) / 8 },
482         { 21,  GST_VC1_BFRACTION_RESERVED },
483         { 22,  GST_VC1_BFRACTION_PTYPE_BI }
484     };
485
486     if (!bfraction)
487         return 0;
488
489     for (i = 0; i < G_N_ELEMENTS(bfraction_map); i++) {
490         if (bfraction_map[i].value == bfraction)
491             return bfraction_map[i].index;
492     }
493     return 21; /* RESERVED */
494 }
495
496 /* Translate GStreamer MV modes to VA-API */
497 static guint
498 get_VAMvModeVC1(guint mvmode)
499 {
500     switch (mvmode) {
501     case GST_VC1_MVMODE_1MV_HPEL_BILINEAR: return VAMvMode1MvHalfPelBilinear;
502     case GST_VC1_MVMODE_1MV:               return VAMvMode1Mv;
503     case GST_VC1_MVMODE_1MV_HPEL:          return VAMvMode1MvHalfPel;
504     case GST_VC1_MVMODE_MIXED_MV:          return VAMvModeMixedMv;
505     case GST_VC1_MVMODE_INTENSITY_COMP:    return VAMvModeIntensityCompensation;
506     }
507     return 0;
508 }
509
510 /* Reconstruct bitstream MVMODE (7.1.1.32) */
511 static guint
512 get_MVMODE(GstVC1FrameHdr *frame_hdr)
513 {
514     guint mvmode;
515
516     if (frame_hdr->profile == GST_VC1_PROFILE_ADVANCED)
517         mvmode = frame_hdr->pic.advanced.mvmode;
518     else
519         mvmode = frame_hdr->pic.simple.mvmode;
520
521     if (frame_hdr->ptype == GST_VC1_PICTURE_TYPE_P ||
522         frame_hdr->ptype == GST_VC1_PICTURE_TYPE_B)
523         return get_VAMvModeVC1(mvmode);
524     return 0;
525 }
526
527 /* Reconstruct bitstream MVMODE2 (7.1.1.33) */
528 static guint
529 get_MVMODE2(GstVC1FrameHdr *frame_hdr)
530 {
531     guint mvmode, mvmode2;
532
533     if (frame_hdr->profile == GST_VC1_PROFILE_ADVANCED) {
534         mvmode  = frame_hdr->pic.advanced.mvmode;
535         mvmode2 = frame_hdr->pic.advanced.mvmode2;
536     }
537     else {
538         mvmode  = frame_hdr->pic.simple.mvmode;
539         mvmode2 = frame_hdr->pic.simple.mvmode2;
540     }
541
542     if (frame_hdr->ptype == GST_VC1_PICTURE_TYPE_P &&
543         mvmode == GST_VC1_MVMODE_INTENSITY_COMP)
544         return get_VAMvModeVC1(mvmode2);
545     return 0;
546 }
547
548 static inline int
549 has_MVTYPEMB_bitplane(GstVaapiDecoderVC1 *decoder)
550 {
551     GstVaapiDecoderVC1Private * const priv = decoder->priv;
552     GstVC1SeqHdr * const seq_hdr = &priv->seq_hdr;
553     GstVC1FrameHdr * const frame_hdr = &priv->frame_hdr;
554     guint mvmode, mvmode2;
555
556     if (seq_hdr->profile == GST_VC1_PROFILE_ADVANCED) {
557         GstVC1PicAdvanced * const pic = &frame_hdr->pic.advanced;
558         if (pic->mvtypemb)
559             return 0;
560         mvmode  = pic->mvmode;
561         mvmode2 = pic->mvmode2;
562     }
563     else {
564         GstVC1PicSimpleMain * const pic = &frame_hdr->pic.simple;
565         if (pic->mvtypemb)
566             return 0;
567         mvmode  = pic->mvmode;
568         mvmode2 = pic->mvmode2;
569     }
570     return (frame_hdr->ptype == GST_VC1_PICTURE_TYPE_P &&
571             (mvmode == GST_VC1_MVMODE_MIXED_MV ||
572              (mvmode == GST_VC1_MVMODE_INTENSITY_COMP &&
573               mvmode2 == GST_VC1_MVMODE_MIXED_MV)));
574 }
575
576 static inline int
577 has_SKIPMB_bitplane(GstVaapiDecoderVC1 *decoder)
578 {
579     GstVaapiDecoderVC1Private * const priv = decoder->priv;
580     GstVC1SeqHdr * const seq_hdr = &priv->seq_hdr;
581     GstVC1FrameHdr * const frame_hdr = &priv->frame_hdr;
582
583     if (seq_hdr->profile == GST_VC1_PROFILE_ADVANCED) {
584         GstVC1PicAdvanced * const pic = &frame_hdr->pic.advanced;
585         if (pic->skipmb)
586             return 0;
587     }
588     else {
589         GstVC1PicSimpleMain * const pic = &frame_hdr->pic.simple;
590         if (pic->skipmb)
591             return 0;
592     }
593     return (frame_hdr->ptype == GST_VC1_PICTURE_TYPE_P ||
594             frame_hdr->ptype == GST_VC1_PICTURE_TYPE_B);
595 }
596
597 static inline int
598 has_DIRECTMB_bitplane(GstVaapiDecoderVC1 *decoder)
599 {
600     GstVaapiDecoderVC1Private * const priv = decoder->priv;
601     GstVC1SeqHdr * const seq_hdr = &priv->seq_hdr;
602     GstVC1FrameHdr * const frame_hdr = &priv->frame_hdr;
603
604     if (seq_hdr->profile == GST_VC1_PROFILE_ADVANCED) {
605         GstVC1PicAdvanced * const pic = &frame_hdr->pic.advanced;
606         if (pic->directmb)
607             return 0;
608     }
609     else {
610         GstVC1PicSimpleMain * const pic = &frame_hdr->pic.simple;
611         if (pic->directmb)
612             return 0;
613     }
614     return frame_hdr->ptype == GST_VC1_PICTURE_TYPE_B;
615 }
616
617 static inline int
618 has_ACPRED_bitplane(GstVaapiDecoderVC1 *decoder)
619 {
620     GstVaapiDecoderVC1Private * const priv = decoder->priv;
621     GstVC1SeqHdr * const seq_hdr = &priv->seq_hdr;
622     GstVC1FrameHdr * const frame_hdr = &priv->frame_hdr;
623     GstVC1PicAdvanced * const pic = &frame_hdr->pic.advanced;
624
625     if (seq_hdr->profile != GST_VC1_PROFILE_ADVANCED)
626         return 0;
627     if (pic->acpred)
628         return 0;
629     return (frame_hdr->ptype == GST_VC1_PICTURE_TYPE_I ||
630             frame_hdr->ptype == GST_VC1_PICTURE_TYPE_BI);
631 }
632
633 static inline int
634 has_OVERFLAGS_bitplane(GstVaapiDecoderVC1 *decoder)
635 {
636     GstVaapiDecoderVC1Private * const priv = decoder->priv;
637     GstVC1SeqHdr * const seq_hdr = &priv->seq_hdr;
638     GstVC1EntryPointHdr * const entrypoint_hdr = &priv->entrypoint_hdr;
639     GstVC1FrameHdr * const frame_hdr = &priv->frame_hdr;
640     GstVC1PicAdvanced * const pic = &frame_hdr->pic.advanced;
641
642     if (seq_hdr->profile != GST_VC1_PROFILE_ADVANCED)
643         return 0;
644     if (pic->overflags)
645         return 0;
646     return ((frame_hdr->ptype == GST_VC1_PICTURE_TYPE_I ||
647              frame_hdr->ptype == GST_VC1_PICTURE_TYPE_BI) &&
648             (entrypoint_hdr->overlap && frame_hdr->pquant <= 8) &&
649             pic->condover == GST_VC1_CONDOVER_SELECT);
650 }
651
652 static inline void
653 pack_bitplanes(GstVaapiBitPlane *bitplane, guint n, const guint8 *bitplanes[3], guint x, guint y, guint stride)
654 {
655     const guint dst_index = n / 2;
656     const guint src_index = y * stride + x;
657     guint8 v = 0;
658
659     if (bitplanes[0])
660         v |= bitplanes[0][src_index];
661     if (bitplanes[1])
662         v |= bitplanes[1][src_index] << 1;
663     if (bitplanes[2])
664         v |= bitplanes[2][src_index] << 2;
665     bitplane->data[dst_index] = (bitplane->data[dst_index] << 4) | v;
666 }
667
668 static gboolean
669 fill_picture_structc(GstVaapiDecoderVC1 *decoder, GstVaapiPicture *picture)
670 {
671     GstVaapiDecoderVC1Private * const priv = decoder->priv;
672     VAPictureParameterBufferVC1 * const pic_param = picture->param;
673     GstVC1SeqStructC * const structc = &priv->seq_hdr.struct_c;
674     GstVC1FrameHdr * const frame_hdr = &priv->frame_hdr;
675     GstVC1PicSimpleMain * const pic = &frame_hdr->pic.simple;
676
677     /* Fill in VAPictureParameterBufferVC1 (simple/main profile bits) */
678     pic_param->sequence_fields.bits.finterpflag                     = structc->finterpflag;
679     pic_param->sequence_fields.bits.multires                        = structc->multires;
680     pic_param->sequence_fields.bits.overlap                         = structc->overlap;
681     pic_param->sequence_fields.bits.syncmarker                      = structc->syncmarker;
682     pic_param->sequence_fields.bits.rangered                        = structc->rangered;
683     pic_param->sequence_fields.bits.max_b_frames                    = structc->maxbframes;
684     pic_param->conditional_overlap_flag                             = 0; /* advanced profile only */
685     pic_param->fast_uvmc_flag                                       = structc->fastuvmc;
686     pic_param->b_picture_fraction                                   = get_BFRACTION(pic->bfraction);
687     pic_param->cbp_table                                            = pic->cbptab;
688     pic_param->mb_mode_table                                        = 0; /* XXX: interlaced frame */
689     pic_param->range_reduction_frame                                = pic->rangeredfrm;
690     pic_param->rounding_control                                     = 0; /* advanced profile only */
691     pic_param->post_processing                                      = 0; /* advanced profile only */
692     pic_param->picture_resolution_index                             = pic->respic;
693     pic_param->luma_scale                                           = pic->lumscale;
694     pic_param->luma_shift                                           = pic->lumshift;
695     pic_param->raw_coding.flags.mv_type_mb                          = pic->mvtypemb;
696     pic_param->raw_coding.flags.direct_mb                           = pic->directmb;
697     pic_param->raw_coding.flags.skip_mb                             = pic->skipmb;
698     pic_param->bitplane_present.flags.bp_mv_type_mb                 = has_MVTYPEMB_bitplane(decoder);
699     pic_param->bitplane_present.flags.bp_direct_mb                  = has_DIRECTMB_bitplane(decoder);
700     pic_param->bitplane_present.flags.bp_skip_mb                    = has_SKIPMB_bitplane(decoder);
701     pic_param->mv_fields.bits.mv_table                              = pic->mvtab;
702     pic_param->mv_fields.bits.extended_mv_flag                      = structc->extended_mv;
703     pic_param->mv_fields.bits.extended_mv_range                     = pic->mvrange;
704     pic_param->transform_fields.bits.variable_sized_transform_flag  = structc->vstransform;
705     pic_param->transform_fields.bits.mb_level_transform_type_flag   = pic->ttmbf;
706     pic_param->transform_fields.bits.frame_level_transform_type     = pic->ttfrm;
707     pic_param->transform_fields.bits.transform_ac_codingset_idx2    = pic->transacfrm2;
708     return TRUE;
709 }
710
711 static gboolean
712 fill_picture_advanced(GstVaapiDecoderVC1 *decoder, GstVaapiPicture *picture)
713 {
714     GstVaapiDecoderVC1Private * const priv = decoder->priv;
715     VAPictureParameterBufferVC1 * const pic_param = picture->param;
716     GstVC1AdvancedSeqHdr * const adv_hdr = &priv->seq_hdr.advanced;
717     GstVC1EntryPointHdr * const entrypoint_hdr = &priv->entrypoint_hdr;
718     GstVC1FrameHdr * const frame_hdr = &priv->frame_hdr;
719     GstVC1PicAdvanced * const pic = &frame_hdr->pic.advanced;
720
721     if (!priv->has_entrypoint)
722         return FALSE;
723
724     /* Fill in VAPictureParameterBufferVC1 (advanced profile bits) */
725     pic_param->sequence_fields.bits.pulldown                        = adv_hdr->pulldown;
726     pic_param->sequence_fields.bits.interlace                       = adv_hdr->interlace;
727     pic_param->sequence_fields.bits.tfcntrflag                      = adv_hdr->tfcntrflag;
728     pic_param->sequence_fields.bits.finterpflag                     = adv_hdr->finterpflag;
729     pic_param->sequence_fields.bits.psf                             = adv_hdr->psf;
730     pic_param->sequence_fields.bits.overlap                         = entrypoint_hdr->overlap;
731     pic_param->entrypoint_fields.bits.broken_link                   = entrypoint_hdr->broken_link;
732     pic_param->entrypoint_fields.bits.closed_entry                  = entrypoint_hdr->closed_entry;
733     pic_param->entrypoint_fields.bits.panscan_flag                  = entrypoint_hdr->panscan_flag;
734     pic_param->entrypoint_fields.bits.loopfilter                    = entrypoint_hdr->loopfilter;
735     pic_param->conditional_overlap_flag                             = pic->condover;
736     pic_param->fast_uvmc_flag                                       = entrypoint_hdr->fastuvmc;
737     pic_param->range_mapping_fields.bits.luma_flag                  = entrypoint_hdr->range_mapy_flag;
738     pic_param->range_mapping_fields.bits.luma                       = entrypoint_hdr->range_mapy;
739     pic_param->range_mapping_fields.bits.chroma_flag                = entrypoint_hdr->range_mapuv_flag;
740     pic_param->range_mapping_fields.bits.chroma                     = entrypoint_hdr->range_mapuv;
741     pic_param->b_picture_fraction                                   = get_BFRACTION(pic->bfraction);
742     pic_param->cbp_table                                            = pic->cbptab;
743     pic_param->mb_mode_table                                        = 0; /* XXX: interlaced frame */
744     pic_param->range_reduction_frame                                = 0; /* simple/main profile only */
745     pic_param->rounding_control                                     = pic->rndctrl;
746     pic_param->post_processing                                      = pic->postproc;
747     pic_param->picture_resolution_index                             = 0; /* simple/main profile only */
748     pic_param->luma_scale                                           = pic->lumscale;
749     pic_param->luma_shift                                           = pic->lumshift;
750     pic_param->picture_fields.bits.frame_coding_mode                = pic->fcm;
751     pic_param->picture_fields.bits.top_field_first                  = pic->tff;
752     pic_param->picture_fields.bits.is_first_field                   = pic->fcm == 0; /* XXX: interlaced frame */
753     pic_param->picture_fields.bits.intensity_compensation           = pic->mvmode == GST_VC1_MVMODE_INTENSITY_COMP;
754     pic_param->raw_coding.flags.mv_type_mb                          = pic->mvtypemb;
755     pic_param->raw_coding.flags.direct_mb                           = pic->directmb;
756     pic_param->raw_coding.flags.skip_mb                             = pic->skipmb;
757     pic_param->raw_coding.flags.ac_pred                             = pic->acpred;
758     pic_param->raw_coding.flags.overflags                           = pic->overflags;
759     pic_param->bitplane_present.flags.bp_mv_type_mb                 = has_MVTYPEMB_bitplane(decoder);
760     pic_param->bitplane_present.flags.bp_direct_mb                  = has_DIRECTMB_bitplane(decoder);
761     pic_param->bitplane_present.flags.bp_skip_mb                    = has_SKIPMB_bitplane(decoder);
762     pic_param->bitplane_present.flags.bp_ac_pred                    = has_ACPRED_bitplane(decoder);
763     pic_param->bitplane_present.flags.bp_overflags                  = has_OVERFLAGS_bitplane(decoder);
764     pic_param->reference_fields.bits.reference_distance_flag        = entrypoint_hdr->refdist_flag;
765     pic_param->mv_fields.bits.mv_table                              = pic->mvtab;
766     pic_param->mv_fields.bits.extended_mv_flag                      = entrypoint_hdr->extended_mv;
767     pic_param->mv_fields.bits.extended_mv_range                     = pic->mvrange;
768     pic_param->mv_fields.bits.extended_dmv_flag                     = entrypoint_hdr->extended_dmv;
769     pic_param->pic_quantizer_fields.bits.dquant                     = entrypoint_hdr->dquant;
770     pic_param->pic_quantizer_fields.bits.quantizer                  = entrypoint_hdr->quantizer;
771     pic_param->transform_fields.bits.variable_sized_transform_flag  = entrypoint_hdr->vstransform;
772     pic_param->transform_fields.bits.mb_level_transform_type_flag   = pic->ttmbf;
773     pic_param->transform_fields.bits.frame_level_transform_type     = pic->ttfrm;
774     pic_param->transform_fields.bits.transform_ac_codingset_idx2    = pic->transacfrm2;
775     return TRUE;
776 }
777
778 static gboolean
779 fill_picture(GstVaapiDecoderVC1 *decoder, GstVaapiPicture *picture)
780 {
781     GstVaapiDecoderVC1Private * const priv = decoder->priv;
782     VAPictureParameterBufferVC1 * const pic_param = picture->param;
783     GstVC1SeqHdr * const seq_hdr = &priv->seq_hdr;
784     GstVC1FrameHdr * const frame_hdr = &priv->frame_hdr;
785
786     /* Fill in VAPictureParameterBufferVC1 (common fields) */
787     pic_param->forward_reference_picture                            = VA_INVALID_ID;
788     pic_param->backward_reference_picture                           = VA_INVALID_ID;
789     pic_param->inloop_decoded_picture                               = VA_INVALID_ID;
790     pic_param->sequence_fields.value                                = 0;
791 #if VA_CHECK_VERSION(0,32,0)
792     pic_param->sequence_fields.bits.profile                         = seq_hdr->profile;
793 #endif
794     pic_param->coded_width                                          = priv->width;
795     pic_param->coded_height                                         = priv->height;
796     pic_param->entrypoint_fields.value                              = 0;
797     pic_param->range_mapping_fields.value                           = 0;
798     pic_param->picture_fields.value                                 = 0;
799     pic_param->picture_fields.bits.picture_type                     = get_PTYPE(frame_hdr->ptype);
800     pic_param->raw_coding.value                                     = 0;
801     pic_param->bitplane_present.value                               = 0;
802     pic_param->reference_fields.value                               = 0;
803     pic_param->mv_fields.value                                      = 0;
804     pic_param->mv_fields.bits.mv_mode                               = get_MVMODE(frame_hdr);
805     pic_param->mv_fields.bits.mv_mode2                              = get_MVMODE2(frame_hdr);
806     pic_param->pic_quantizer_fields.value                           = 0;
807     pic_param->pic_quantizer_fields.bits.half_qp                    = frame_hdr->halfqp;
808     pic_param->pic_quantizer_fields.bits.pic_quantizer_scale        = frame_hdr->pquant;
809     pic_param->pic_quantizer_fields.bits.pic_quantizer_type         = frame_hdr->pquantizer;
810     pic_param->pic_quantizer_fields.bits.dq_frame                   = frame_hdr->vopdquant.dquantfrm;
811     pic_param->pic_quantizer_fields.bits.dq_profile                 = frame_hdr->vopdquant.dqprofile;
812     pic_param->pic_quantizer_fields.bits.dq_sb_edge                 = frame_hdr->vopdquant.dqsbedge;
813     pic_param->pic_quantizer_fields.bits.dq_db_edge                 = frame_hdr->vopdquant.dqsbedge;
814     pic_param->pic_quantizer_fields.bits.dq_binary_level            = frame_hdr->vopdquant.dqbilevel;
815     pic_param->pic_quantizer_fields.bits.alt_pic_quantizer          = frame_hdr->vopdquant.altpquant;
816     pic_param->transform_fields.value                               = 0;
817     pic_param->transform_fields.bits.transform_ac_codingset_idx1    = frame_hdr->transacfrm;
818     pic_param->transform_fields.bits.intra_transform_dc_table       = frame_hdr->transdctab;
819
820     if (seq_hdr->profile == GST_VC1_PROFILE_ADVANCED) {
821         if (!fill_picture_advanced(decoder, picture))
822             return FALSE;
823     }
824     else {
825         if (!fill_picture_structc(decoder, picture))
826             return FALSE;
827     }
828
829     switch (picture->type) {
830     case GST_VAAPI_PICTURE_TYPE_B:
831         if (priv->next_picture)
832             pic_param->backward_reference_picture = priv->next_picture->surface_id;
833         // fall-through
834     case GST_VAAPI_PICTURE_TYPE_P:
835         if (priv->prev_picture)
836             pic_param->forward_reference_picture = priv->prev_picture->surface_id;
837         break;
838     default:
839         break;
840     }
841
842     if (pic_param->bitplane_present.value) {
843         const guint8 *bitplanes[3];
844         guint x, y, n;
845
846         switch (picture->type) {
847         case GST_VAAPI_PICTURE_TYPE_P:
848             bitplanes[0] = pic_param->bitplane_present.flags.bp_direct_mb  ? priv->bitplanes->directmb  : NULL;
849             bitplanes[1] = pic_param->bitplane_present.flags.bp_skip_mb    ? priv->bitplanes->skipmb    : NULL;
850             bitplanes[2] = pic_param->bitplane_present.flags.bp_mv_type_mb ? priv->bitplanes->mvtypemb  : NULL;
851             break;
852         case GST_VAAPI_PICTURE_TYPE_B:
853             bitplanes[0] = pic_param->bitplane_present.flags.bp_direct_mb  ? priv->bitplanes->directmb  : NULL;
854             bitplanes[1] = pic_param->bitplane_present.flags.bp_skip_mb    ? priv->bitplanes->skipmb    : NULL;
855             bitplanes[2] = NULL; /* XXX: interlaced frame (FORWARD plane) */
856             break;
857         case GST_VAAPI_PICTURE_TYPE_BI:
858         case GST_VAAPI_PICTURE_TYPE_I:
859             bitplanes[0] = NULL; /* XXX: interlaced frame (FIELDTX plane) */
860             bitplanes[1] = pic_param->bitplane_present.flags.bp_ac_pred    ? priv->bitplanes->acpred    : NULL;
861             bitplanes[2] = pic_param->bitplane_present.flags.bp_overflags  ? priv->bitplanes->overflags : NULL;
862             break;
863         default:
864             bitplanes[0] = NULL;
865             bitplanes[1] = NULL;
866             bitplanes[2] = NULL;
867             break;
868         }
869
870         picture->bitplane = GST_VAAPI_BITPLANE_NEW(
871             decoder,
872             (seq_hdr->mb_width * seq_hdr->mb_height + 1) / 2
873         );
874         if (!picture->bitplane)
875             return FALSE;
876
877         n = 0;
878         for (y = 0; y < seq_hdr->mb_height; y++)
879             for (x = 0; x < seq_hdr->mb_width; x++, n++)
880                 pack_bitplanes(picture->bitplane, n, bitplanes, x, y, seq_hdr->mb_stride);
881         if (n & 1) /* move last nibble to the high order */
882             picture->bitplane->data[n/2] <<= 4;
883     }
884     return TRUE;
885 }
886
887 static GstVaapiDecoderStatus
888 decode_frame(GstVaapiDecoderVC1 *decoder, GstVC1BDU *rbdu, GstVC1BDU *ebdu)
889 {
890     GstVaapiDecoderVC1Private * const priv = decoder->priv;
891     GstVC1SeqHdr * const seq_hdr = &priv->seq_hdr;
892     GstVC1FrameHdr * const frame_hdr = &priv->frame_hdr;
893     GstVC1ParserResult result;
894     GstVaapiPicture *picture;
895     GstVaapiSlice *slice;
896     GstVaapiDecoderStatus status;
897     VASliceParameterBufferVC1 *slice_param;
898     GstClockTime pts;
899
900     check_context_reset (decoder);
901
902     priv->current_picture = GST_VAAPI_PICTURE_NEW(VC1, decoder);
903     if (!priv->current_picture) {
904         GST_DEBUG("failed to allocate picture");
905         return GST_VAAPI_DECODER_STATUS_ERROR_ALLOCATION_FAILED;
906     }
907     picture = priv->current_picture;
908
909     if (!gst_vc1_bitplanes_ensure_size(priv->bitplanes, seq_hdr)) {
910         GST_DEBUG("failed to allocate bitplanes");
911         return GST_VAAPI_DECODER_STATUS_ERROR_ALLOCATION_FAILED;
912     }
913
914     memset(frame_hdr, 0, sizeof(*frame_hdr));
915     result = gst_vc1_parse_frame_header(
916         rbdu->data + rbdu->offset,
917         rbdu->size,
918         frame_hdr,
919         seq_hdr,
920         priv->bitplanes
921     );
922     if (result != GST_VC1_PARSER_OK) {
923         GST_DEBUG("failed to parse frame layer");
924         return get_status(result);
925     }
926
927     switch (frame_hdr->ptype) {
928     case GST_VC1_PICTURE_TYPE_I:
929         picture->type   = GST_VAAPI_PICTURE_TYPE_I;
930         GST_VAAPI_PICTURE_FLAG_SET(picture, GST_VAAPI_PICTURE_FLAG_REFERENCE);
931         break;
932     case GST_VC1_PICTURE_TYPE_SKIPPED:
933     case GST_VC1_PICTURE_TYPE_P:
934         picture->type   = GST_VAAPI_PICTURE_TYPE_P;
935         GST_VAAPI_PICTURE_FLAG_SET(picture, GST_VAAPI_PICTURE_FLAG_REFERENCE);
936         break;
937     case GST_VC1_PICTURE_TYPE_B:
938         picture->type   = GST_VAAPI_PICTURE_TYPE_B;
939         break;
940     case GST_VC1_PICTURE_TYPE_BI:
941         picture->type   = GST_VAAPI_PICTURE_TYPE_BI;
942         break;
943     default:
944         GST_DEBUG("unsupported picture type %d", frame_hdr->ptype);
945         return GST_VAAPI_DECODER_STATUS_ERROR_UNKNOWN;
946     }
947
948     /* Update presentation time */
949     pts = gst_adapter_prev_timestamp(priv->adapter, NULL);
950     picture->pts = pts;
951
952     /* Update reference pictures */
953     if (GST_VAAPI_PICTURE_IS_REFERENCE(picture)) {
954         if (priv->next_picture)
955             status = render_picture(decoder, priv->next_picture);
956         gst_vaapi_picture_replace(&priv->prev_picture, priv->next_picture);
957         gst_vaapi_picture_replace(&priv->next_picture, picture);
958     }    
959
960     if (!fill_picture(decoder, picture))
961         return GST_VAAPI_DECODER_STATUS_ERROR_UNKNOWN;
962
963     slice = GST_VAAPI_SLICE_NEW(
964         VC1,
965         decoder,
966         ebdu->data + ebdu->sc_offset,
967         ebdu->size + ebdu->offset - ebdu->sc_offset
968     );
969     if (!slice) {
970         GST_DEBUG("failed to allocate slice");
971         return GST_VAAPI_DECODER_STATUS_ERROR_ALLOCATION_FAILED;
972     }
973     gst_vaapi_picture_add_slice(picture, slice);
974
975     /* Fill in VASliceParameterBufferVC1 */
976     slice_param                            = slice->param;
977     slice_param->macroblock_offset         = 8 * (ebdu->offset - ebdu->sc_offset) + frame_hdr->header_size;
978     slice_param->slice_vertical_position   = 0;
979
980     return GST_VAAPI_DECODER_STATUS_SUCCESS;
981 }
982
983 static gboolean
984 decode_rbdu(GstVaapiDecoderVC1 *decoder, GstVC1BDU *rbdu, GstVC1BDU *ebdu)
985 {
986     GstVaapiDecoderVC1Private * const priv = decoder->priv;
987     guint8 *rbdu_buffer;
988     guint i, j, rbdu_buffer_size;
989
990     /* BDU are encapsulated in advanced profile mode only */
991     if (priv->profile != GST_VAAPI_PROFILE_VC1_ADVANCED) {
992         memcpy(rbdu, ebdu, sizeof(*rbdu));
993         return TRUE;
994     }
995
996     /* Reallocate unescaped bitstream buffer */
997     rbdu_buffer = priv->rbdu_buffer;
998     if (!rbdu_buffer || ebdu->size > priv->rbdu_buffer_size) {
999         rbdu_buffer = g_realloc(priv->rbdu_buffer, ebdu->size);
1000         if (!rbdu_buffer)
1001             return FALSE;
1002         priv->rbdu_buffer = rbdu_buffer;
1003         priv->rbdu_buffer_size = ebdu->size;
1004     }
1005
1006     /* Unescape bitstream buffer */
1007     if (ebdu->size < 4) {
1008         memcpy(rbdu_buffer, ebdu->data + ebdu->offset, ebdu->size);
1009         rbdu_buffer_size = ebdu->size;
1010     }
1011     else {
1012         guint8 * const bdu_buffer = ebdu->data + ebdu->offset;
1013         for (i = 0, j = 0; i < ebdu->size; i++) {
1014             if (i >= 2 && i < ebdu->size - 1 &&
1015                 bdu_buffer[i - 1] == 0x00   &&
1016                 bdu_buffer[i - 2] == 0x00   &&
1017                 bdu_buffer[i    ] == 0x03   &&
1018                 bdu_buffer[i + 1] <= 0x03)
1019                 i++;
1020             rbdu_buffer[j++] = bdu_buffer[i];
1021         }
1022         rbdu_buffer_size = j;
1023     }
1024
1025     /* Reconstruct RBDU */
1026     rbdu->type      = ebdu->type;
1027     rbdu->size      = rbdu_buffer_size;
1028     rbdu->sc_offset = 0;
1029     rbdu->offset    = 0;
1030     rbdu->data      = rbdu_buffer;
1031     return TRUE;
1032 }
1033
1034 static GstVaapiDecoderStatus
1035 decode_ebdu(GstVaapiDecoderVC1 *decoder, GstVC1BDU *ebdu)
1036 {
1037     GstVaapiDecoderStatus status;
1038     GstVC1BDU rbdu;
1039
1040     if (!decode_rbdu(decoder, &rbdu, ebdu))
1041         return GST_VAAPI_DECODER_STATUS_ERROR_ALLOCATION_FAILED;
1042
1043     switch (ebdu->type) {
1044     case GST_VC1_SEQUENCE:
1045         status = decode_sequence(decoder, &rbdu, ebdu);
1046         break;
1047     case GST_VC1_ENTRYPOINT:
1048         status = decode_entry_point(decoder, &rbdu, ebdu);
1049         break;
1050     case GST_VC1_FRAME:
1051         status = decode_frame(decoder, &rbdu, ebdu);
1052         break;
1053     case GST_VC1_SLICE:
1054         GST_DEBUG("decode slice");
1055         status = GST_VAAPI_DECODER_STATUS_ERROR_BITSTREAM_PARSER;
1056         break;
1057     case GST_VC1_END_OF_SEQ:
1058         status = decode_sequence_end(decoder);
1059         break;
1060     default:
1061         GST_DEBUG("unsupported BDU type %d", ebdu->type);
1062         status = GST_VAAPI_DECODER_STATUS_ERROR_BITSTREAM_PARSER;
1063         break;
1064     }
1065     return status;
1066 }
1067
1068 static GstVaapiDecoderStatus
1069 gst_vaapi_decoder_vc1_parse(
1070     GstVaapiDecoder *base, 
1071     GstAdapter *adapter, 
1072     guint *toadd,
1073     gboolean *have_frame)
1074 {
1075     GstVaapiDecoderVC1 * const decoder = GST_VAAPI_DECODER_VC1(base);
1076     GstVaapiDecoderVC1Private * const priv = decoder->priv;
1077     GstVaapiDecoderStatus status  = GST_VAAPI_DECODER_STATUS_SUCCESS;
1078     GstVC1ParserResult result;
1079     GstVC1BDU ebdu;
1080     GstBuffer *codec_data;
1081     gint size = 0,ofs = 0;
1082     guint8 *data;
1083     guint8 *buf_data = NULL;
1084     gsize buf_size = 0;
1085
1086     priv->adapter = adapter;
1087     size = gst_adapter_available (adapter);
1088     data = (guint8 *)gst_adapter_map (adapter,size);
1089     
1090     /*Fixme*/
1091     if (!data && size == 0)
1092         return decode_sequence_end(decoder);
1093
1094     /* Assume demuxer sends out plain frames if codec-data */
1095     codec_data = GST_VAAPI_DECODER_CODEC_DATA(decoder);
1096     if (codec_data) {
1097         ebdu.type      = GST_VC1_FRAME;
1098         ebdu.size      = size;
1099         ebdu.sc_offset = 0;
1100         ebdu.offset    = 0;
1101         ebdu.data      = data;
1102         status = decode_ebdu(decoder, &ebdu);
1103         if (status == GST_VAAPI_DECODER_STATUS_SUCCESS) {
1104             *toadd = size;
1105             *have_frame = TRUE; 
1106             return status;
1107         }
1108         else 
1109             return GST_VAAPI_DECODER_STATUS_ERROR_NO_DATA;
1110     }
1111         
1112     result = gst_vc1_identify_next_bdu(
1113         data + ofs,
1114         size - ofs,
1115         &ebdu
1116         );
1117     status = get_status(result);
1118
1119     if (status != GST_VAAPI_DECODER_STATUS_SUCCESS)
1120         goto beach;
1121
1122     ofs += ebdu.offset + ebdu.size;
1123     if (gst_adapter_available(priv->adapter) >= ebdu.offset)
1124         gst_adapter_flush(priv->adapter, ebdu.offset);
1125
1126     status = decode_ebdu(decoder, &ebdu);
1127     if (status == GST_VAAPI_DECODER_STATUS_SUCCESS) { 
1128         if (ebdu.type == GST_VC1_FRAME || ebdu.type == GST_VC1_END_OF_SEQ) {
1129             *toadd = ebdu.size;
1130             *have_frame = TRUE;
1131             goto beach;
1132         } else {
1133             *toadd = ebdu.size;
1134             goto beach;
1135         }
1136     }    
1137
1138 beach:
1139     return status;
1140 }
1141
1142 gboolean
1143 gst_vaapi_decoder_vc1_decide_allocation(
1144     GstVaapiDecoder *dec,
1145     GstBufferPool *pool)
1146 {
1147     GstVaapiDecoderVC1 *decoder = GST_VAAPI_DECODER_VC1(dec);
1148     GstVaapiDecoderVC1Private * priv = decoder->priv;
1149     GstVaapiDecoderStatus status = GST_VAAPI_DECODER_STATUS_SUCCESS;
1150
1151     status = ensure_context(decoder, pool);
1152
1153     if (status != GST_VAAPI_DECODER_STATUS_SUCCESS) {
1154         GST_ERROR("failed to create context,,failed to create the pool....");
1155         return FALSE;
1156     }
1157     return TRUE;
1158 }
1159
1160 static GstVaapiDecoderStatus
1161 decode_codec_data(GstVaapiDecoderVC1 *decoder, GstBuffer *buffer)
1162 {
1163     GstVaapiDecoderVC1Private * const priv = decoder->priv;
1164     GstVC1SeqHdr * const seq_hdr = &priv->seq_hdr;
1165     GstVaapiDecoderStatus status;
1166     GstVC1ParserResult result;
1167     GstVC1BDU ebdu;
1168     GstCaps *caps;
1169     GstStructure *structure;
1170     guchar *buf;
1171     guint buf_size, ofs;
1172     gint width, height;
1173     guint32 format;
1174     GstMapInfo map_info;
1175     GstVideoInfo info;
1176     const gchar *format_string;
1177
1178     gst_buffer_map (buffer, &map_info, GST_MAP_READ);
1179
1180     buf      = map_info.data;
1181     buf_size = map_info.size;
1182
1183     if (!buf || buf_size == 0)
1184         return GST_VAAPI_DECODER_STATUS_SUCCESS;
1185
1186     caps      = GST_VAAPI_DECODER_CAST(decoder)->priv->caps;
1187     structure = gst_caps_get_structure(caps, 0);
1188
1189     gst_video_info_from_caps(&info, caps);
1190     width = info.width;
1191     height = info.height;
1192
1193     if(!width || !height) {
1194         GST_DEBUG("failed to parse size from codec-data");
1195         return GST_VAAPI_DECODER_STATUS_ERROR_UNKNOWN;
1196     }
1197
1198     format_string = gst_structure_get_string (structure, "format");
1199     if (!format_string) {
1200         GST_DEBUG("failed to parse profile from codec-data");
1201         return GST_VAAPI_DECODER_STATUS_ERROR_UNSUPPORTED_CODEC;
1202     }
1203     /* WMV3 -- expecting sequence header */
1204     if (!g_strcmp0(format_string, "WMV3")) {
1205         seq_hdr->struct_c.coded_width  = width;
1206         seq_hdr->struct_c.coded_height = height;
1207         ebdu.type      = GST_VC1_SEQUENCE;
1208         ebdu.size      = buf_size;
1209         ebdu.sc_offset = 0;
1210         ebdu.offset    = 0;
1211         ebdu.data      = buf;
1212         return decode_ebdu(decoder, &ebdu);
1213     }
1214
1215     /* WVC1 -- expecting bitstream data units */
1216     if (g_strcmp0(format_string, "WVC1")) 
1217         return GST_VAAPI_DECODER_STATUS_ERROR_UNSUPPORTED_PROFILE;
1218
1219     seq_hdr->advanced.max_coded_width  = width;
1220     seq_hdr->advanced.max_coded_height = height;
1221
1222     ofs = 0;
1223     do {
1224         result = gst_vc1_identify_next_bdu(
1225             buf + ofs,
1226             buf_size - ofs,
1227             &ebdu
1228         );
1229
1230         switch (result) {
1231         case GST_VC1_PARSER_NO_BDU_END:
1232             /* Assume the EBDU is complete within codec-data bounds */
1233             ebdu.size = buf_size - ofs - (ebdu.offset - ebdu.sc_offset);
1234             // fall-through
1235         case GST_VC1_PARSER_OK:
1236             status = decode_ebdu(decoder, &ebdu);
1237             ofs += ebdu.offset + ebdu.size;
1238             break;
1239         default:
1240             status = get_status(result);
1241             break;
1242         }
1243     } while (status == GST_VAAPI_DECODER_STATUS_SUCCESS && ofs < buf_size);
1244     return status;
1245 }
1246
1247 GstVaapiDecoderStatus
1248 decode_buffer_vc1(GstVaapiDecoderVC1 *decoder, GstBuffer *buffer, GstVideoCodecFrame *frame)
1249 {
1250     GstVaapiDecoderVC1Private * const priv = decoder->priv;
1251     GstVaapiPicture *picture = priv->current_picture;
1252     GstVaapiDecoderStatus status = GST_VAAPI_DECODER_STATUS_SUCCESS;
1253
1254     if (picture) {
1255         if (!gst_vaapi_picture_allocate_surface(picture)) {
1256             GST_ERROR("failed to allocate surface for current pic");
1257             return FALSE;
1258         }
1259
1260         picture->frame_id       = frame->system_frame_number;
1261         /*decode pic*/
1262         status = decode_current_picture(decoder);
1263     } 
1264     return status;
1265 }
1266
1267 GstVaapiDecoderStatus
1268 gst_vaapi_decoder_vc1_decode(GstVaapiDecoder *base, GstVideoCodecFrame *frame)
1269 {
1270     GstVaapiDecoderVC1 * const decoder = GST_VAAPI_DECODER_VC1(base);
1271     GstVaapiDecoderVC1Private * const priv = decoder->priv;
1272     GstVaapiDecoderStatus status = GST_VAAPI_DECODER_STATUS_SUCCESS;
1273     GstBuffer *codec_data;
1274
1275     g_return_val_if_fail(priv->is_constructed,
1276                          GST_VAAPI_DECODER_STATUS_ERROR_INIT_FAILED);
1277
1278     return decode_buffer_vc1(decoder, frame->input_buffer, frame);
1279 }
1280
1281 gboolean
1282 gst_vaapi_decoder_vc1_reset(GstVaapiDecoder *bdec)
1283 {
1284     GstVaapiDecoderVC1 * const decoder = GST_VAAPI_DECODER_VC1(bdec);
1285     GstVaapiDecoderVC1Private * const priv = decoder->priv;
1286
1287     priv->adapter = NULL;
1288
1289     if (!gst_vaapi_decoder_vc1_open(decoder)) {
1290        GST_ERROR("Failed to re-initialize the mpeg2 decoder");
1291        return FALSE;
1292     }
1293     return TRUE;
1294
1295 }
1296 static void
1297 gst_vaapi_decoder_vc1_finalize(GObject *object)
1298 {
1299     GstVaapiDecoderVC1 * const decoder = GST_VAAPI_DECODER_VC1(object);
1300
1301     gst_vaapi_decoder_vc1_destroy(decoder);
1302
1303     G_OBJECT_CLASS(gst_vaapi_decoder_vc1_parent_class)->finalize(object);
1304 }
1305
1306 static void
1307 gst_vaapi_decoder_vc1_constructed(GObject *object)
1308 {
1309     GstVaapiDecoderVC1 * const decoder = GST_VAAPI_DECODER_VC1(object);
1310     GstVaapiDecoderVC1Private * const priv = decoder->priv;
1311     GstVaapiDecoderStatus status;
1312     GObjectClass *parent_class;
1313     GstBuffer *codec_data;
1314
1315     parent_class = G_OBJECT_CLASS(gst_vaapi_decoder_vc1_parent_class);
1316     if (parent_class->constructed)
1317         parent_class->constructed(object);
1318
1319     priv->is_constructed = gst_vaapi_decoder_vc1_create(decoder);
1320     
1321     if (!priv->is_opened) {
1322         priv->is_opened = gst_vaapi_decoder_vc1_open(decoder);
1323         g_return_if_fail(priv->is_opened);
1324         codec_data = GST_VAAPI_DECODER_CODEC_DATA(decoder);
1325         if (codec_data) {
1326             status = decode_codec_data(decoder, codec_data);
1327             g_return_if_fail(status ==  GST_VAAPI_DECODER_STATUS_SUCCESS);
1328         }
1329     }
1330 }
1331
1332 static void
1333 gst_vaapi_decoder_vc1_class_init(GstVaapiDecoderVC1Class *klass)
1334 {
1335     GObjectClass * const object_class = G_OBJECT_CLASS(klass);
1336     GstVaapiDecoderClass * const decoder_class = GST_VAAPI_DECODER_CLASS(klass);
1337
1338     g_type_class_add_private(klass, sizeof(GstVaapiDecoderVC1Private));
1339
1340     object_class->finalize      = gst_vaapi_decoder_vc1_finalize;
1341     object_class->constructed   = gst_vaapi_decoder_vc1_constructed;
1342     
1343     decoder_class->parse             = gst_vaapi_decoder_vc1_parse;
1344     decoder_class->decide_allocation = gst_vaapi_decoder_vc1_decide_allocation;
1345     decoder_class->decode            = gst_vaapi_decoder_vc1_decode;
1346     decoder_class->reset             = gst_vaapi_decoder_vc1_reset;
1347 }
1348
1349 static void
1350 gst_vaapi_decoder_vc1_init(GstVaapiDecoderVC1 *decoder)
1351 {
1352     GstVaapiDecoderVC1Private *priv;
1353
1354     priv                        = GST_VAAPI_DECODER_VC1_GET_PRIVATE(decoder);
1355     decoder->priv               = priv;
1356     priv->width                 = 0;
1357     priv->height                = 0;
1358     priv->fps_n                 = 0;
1359     priv->fps_d                 = 0;
1360     priv->profile               = (GstVaapiProfile)0;
1361     priv->current_picture       = NULL;
1362     priv->next_picture          = NULL;
1363     priv->prev_picture          = NULL;
1364     priv->adapter               = NULL;
1365     priv->rbdu_buffer           = NULL;
1366     priv->rbdu_buffer_size      = 0;
1367     priv->is_constructed        = FALSE;
1368     priv->is_opened             = FALSE;
1369     priv->is_first_field        = FALSE;
1370     priv->has_entrypoint        = FALSE;
1371     priv->size_changed          = FALSE;
1372     priv->profile_changed       = FALSE;
1373     priv->closed_entry          = FALSE;
1374     priv->broken_link           = FALSE;
1375     priv->reset_context         = FALSE;
1376 }
1377
1378 /**
1379  * gst_vaapi_decoder_vc1_new:
1380  * @display: a #GstVaapiDisplay
1381  * @caps: a #GstCaps holding codec information
1382  *
1383  * Creates a new #GstVaapiDecoder for VC-1 decoding.  The @caps can
1384  * hold extra information like codec-data and pictured coded size.
1385  *
1386  * Return value: the newly allocated #GstVaapiDecoder object
1387  */
1388 GstVaapiDecoder *
1389 gst_vaapi_decoder_vc1_new(GstVaapiDisplay *display, GstCaps *caps)
1390 {
1391     GstVaapiDecoderVC1 *decoder;
1392
1393     g_return_val_if_fail(GST_VAAPI_IS_DISPLAY(display), NULL);
1394     g_return_val_if_fail(GST_IS_CAPS(caps), NULL);
1395
1396     decoder = g_object_new(
1397         GST_VAAPI_TYPE_DECODER_VC1,
1398         "display",      display,
1399         "caps",         caps,
1400         NULL
1401     );
1402     if (!decoder->priv->is_constructed) {
1403         g_object_unref(decoder);
1404         return NULL;
1405     }
1406     return GST_VAAPI_DECODER_CAST(decoder);
1407 }