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