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