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