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