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