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