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