2 * gstvaapidecoder_vc1.c - VC-1 decoder
4 * Copyright (C) 2011-2013 Intel Corporation
5 * Author: Gwenole Beauchesne <gwenole.beauchesne@intel.com>
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.
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.
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
24 * SECTION:gstvaapidecoder_vc1
25 * @short_description: VC-1 decoder
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"
38 #include "gstvaapidebug.h"
40 #define GST_VAAPI_DECODER_VC1_CAST(decoder) \
41 ((GstVaapiDecoderVC1 *)(decoder))
43 typedef struct _GstVaapiDecoderVC1Private GstVaapiDecoderVC1Private;
44 typedef struct _GstVaapiDecoderVC1Class GstVaapiDecoderVC1Class;
49 * A decoder based on VC1.
51 struct _GstVaapiDecoderVC1Private
53 GstVaapiProfile profile;
57 GstVC1EntryPointHdr entrypoint_hdr;
58 GstVC1FrameHdr frame_hdr;
59 GstVC1BitPlanes *bitplanes;
60 GstVaapiPicture *current_picture;
61 GstVaapiPicture *last_non_b_picture;
66 guint rbdu_buffer_size;
68 guint has_codec_data:1;
69 guint has_entrypoint:1;
71 guint profile_changed:1;
79 * A decoder based on VC1.
81 struct _GstVaapiDecoderVC1
84 GstVaapiDecoder parent_instance;
85 GstVaapiDecoderVC1Private priv;
89 * GstVaapiDecoderVC1Class:
91 * A decoder class based on VC1.
93 struct _GstVaapiDecoderVC1Class
96 GstVaapiDecoderClass parent_class;
99 G_DEFINE_TYPE (GstVaapiDecoderVC1, gst_vaapi_decoder_vc1,
100 GST_TYPE_VAAPI_DECODER);
102 static GstVaapiDecoderStatus
103 get_status (GstVC1ParserResult result)
105 GstVaapiDecoderStatus status;
108 case GST_VC1_PARSER_OK:
109 status = GST_VAAPI_DECODER_STATUS_SUCCESS;
111 case GST_VC1_PARSER_NO_BDU_END:
112 status = GST_VAAPI_DECODER_STATUS_ERROR_NO_DATA;
114 case GST_VC1_PARSER_ERROR:
115 status = GST_VAAPI_DECODER_STATUS_ERROR_BITSTREAM_PARSER;
118 status = GST_VAAPI_DECODER_STATUS_ERROR_UNKNOWN;
125 gst_vaapi_decoder_vc1_close (GstVaapiDecoderVC1 * decoder)
127 GstVaapiDecoderVC1Private *const priv = &decoder->priv;
129 gst_vaapi_picture_replace (&priv->last_non_b_picture, NULL);
130 gst_vaapi_picture_replace (&priv->current_picture, NULL);
131 gst_vaapi_dpb_replace (&priv->dpb, NULL);
133 if (priv->bitplanes) {
134 gst_vc1_bitplanes_free (priv->bitplanes);
135 priv->bitplanes = NULL;
137 priv->is_opened = FALSE;
141 gst_vaapi_decoder_vc1_open (GstVaapiDecoderVC1 * decoder)
143 GstVaapiDecoderVC1Private *const priv = &decoder->priv;
145 gst_vaapi_decoder_vc1_close (decoder);
147 priv->dpb = gst_vaapi_dpb_new (2);
151 priv->bitplanes = gst_vc1_bitplanes_new ();
152 if (!priv->bitplanes)
155 memset (&priv->seq_hdr, 0, sizeof (GstVC1SeqHdr));
156 memset (&priv->entrypoint_hdr, 0, sizeof (GstVC1EntryPointHdr));
157 memset (&priv->frame_hdr, 0, sizeof (GstVC1FrameHdr));
163 gst_vaapi_decoder_vc1_destroy (GstVaapiDecoder * base_decoder)
165 GstVaapiDecoderVC1 *const decoder = GST_VAAPI_DECODER_VC1_CAST (base_decoder);
166 GstVaapiDecoderVC1Private *const priv = &decoder->priv;
168 gst_vaapi_decoder_vc1_close (decoder);
170 if (priv->rbdu_buffer) {
171 g_clear_pointer (&priv->rbdu_buffer, g_free);
172 priv->rbdu_buffer_size = 0;
177 gst_vaapi_decoder_vc1_create (GstVaapiDecoder * base_decoder)
179 GstVaapiDecoderVC1 *const decoder = GST_VAAPI_DECODER_VC1_CAST (base_decoder);
180 GstVaapiDecoderVC1Private *const priv = &decoder->priv;
182 priv->has_codec_data = priv->has_entrypoint =
183 priv->size_changed = priv->profile_changed =
184 priv->closed_entry = priv->broken_link = FALSE;
186 priv->profile = GST_VAAPI_PROFILE_UNKNOWN;
188 priv->width = priv->height = 0;
192 static GstVaapiDecoderStatus
193 gst_vaapi_decoder_vc1_reset (GstVaapiDecoder * base_decoder)
195 gst_vaapi_decoder_vc1_destroy (base_decoder);
196 gst_vaapi_decoder_vc1_create (base_decoder);
197 return GST_VAAPI_DECODER_STATUS_SUCCESS;
200 static GstVaapiDecoderStatus
201 ensure_context (GstVaapiDecoderVC1 * decoder)
203 GstVaapiDecoderVC1Private *const priv = &decoder->priv;
204 GstVaapiProfile profiles[2];
205 GstVaapiEntrypoint entrypoint = GST_VAAPI_ENTRYPOINT_VLD;
206 guint i, n_profiles = 0;
207 gboolean reset_context = FALSE;
209 if (priv->profile_changed) {
210 GST_DEBUG ("profile changed");
211 priv->profile_changed = FALSE;
212 reset_context = TRUE;
214 profiles[n_profiles++] = priv->profile;
215 if (priv->profile == GST_VAAPI_PROFILE_VC1_SIMPLE)
216 profiles[n_profiles++] = GST_VAAPI_PROFILE_VC1_MAIN;
218 for (i = 0; i < n_profiles; i++) {
219 if (gst_vaapi_display_has_decoder (GST_VAAPI_DECODER_DISPLAY (decoder),
220 profiles[i], entrypoint))
224 return GST_VAAPI_DECODER_STATUS_ERROR_UNSUPPORTED_PROFILE;
225 priv->profile = profiles[i];
228 if (priv->size_changed) {
229 GST_DEBUG ("size changed");
230 priv->size_changed = FALSE;
231 reset_context = TRUE;
235 GstVaapiContextInfo info;
237 info.profile = priv->profile;
238 info.entrypoint = entrypoint;
239 info.chroma_type = GST_VAAPI_CHROMA_TYPE_YUV420;
240 info.width = priv->width;
241 info.height = priv->height;
244 gst_vaapi_decoder_ensure_context (GST_VAAPI_DECODER (decoder), &info);
246 return GST_VAAPI_DECODER_STATUS_ERROR_UNKNOWN;
248 return GST_VAAPI_DECODER_STATUS_SUCCESS;
251 static GstVaapiDecoderStatus
252 decode_current_picture (GstVaapiDecoderVC1 * decoder)
254 GstVaapiDecoderVC1Private *const priv = &decoder->priv;
255 GstVaapiPicture *const picture = priv->current_picture;
258 return GST_VAAPI_DECODER_STATUS_SUCCESS;
260 if (!gst_vaapi_picture_decode (picture))
262 if (GST_VAAPI_PICTURE_IS_COMPLETE (picture)) {
263 if (!gst_vaapi_dpb_add (priv->dpb, picture))
265 gst_vaapi_picture_replace (&priv->current_picture, NULL);
267 return GST_VAAPI_DECODER_STATUS_SUCCESS;
272 /* XXX: fix for cases where first field failed to be decoded */
273 gst_vaapi_picture_replace (&priv->current_picture, NULL);
274 return GST_VAAPI_DECODER_STATUS_ERROR_UNKNOWN;
278 static GstVaapiDecoderStatus
279 decode_sequence (GstVaapiDecoderVC1 * decoder, GstVC1BDU * rbdu,
282 GstVaapiDecoder *const base_decoder = GST_VAAPI_DECODER (decoder);
283 GstVaapiDecoderVC1Private *const priv = &decoder->priv;
284 GstVC1SeqHdr *const seq_hdr = &priv->seq_hdr;
285 GstVC1AdvancedSeqHdr *const adv_hdr = &seq_hdr->advanced;
286 GstVC1SeqStructC *const structc = &seq_hdr->struct_c;
287 GstVC1ParserResult result;
288 GstVaapiProfile profile;
289 guint width, height, fps_n, fps_d, par_n, par_d;
291 result = gst_vc1_parse_sequence_header (rbdu->data + rbdu->offset,
292 rbdu->size, seq_hdr);
293 if (result != GST_VC1_PARSER_OK) {
294 GST_ERROR ("failed to parse sequence layer");
295 return get_status (result);
298 priv->has_entrypoint = FALSE;
301 if (priv->last_non_b_picture) {
302 if (priv->last_non_b_picture->poc == priv->next_poc)
304 gst_vaapi_picture_replace (&priv->last_non_b_picture, NULL);
307 /* Validate profile */
308 switch (seq_hdr->profile) {
309 case GST_VC1_PROFILE_SIMPLE:
310 case GST_VC1_PROFILE_MAIN:
311 case GST_VC1_PROFILE_ADVANCED:
314 GST_ERROR ("unsupported profile %d", seq_hdr->profile);
315 return GST_VAAPI_DECODER_STATUS_ERROR_UNSUPPORTED_PROFILE;
322 switch (seq_hdr->profile) {
323 case GST_VC1_PROFILE_SIMPLE:
324 case GST_VC1_PROFILE_MAIN:
326 fps_n = structc->framerate;
330 case GST_VC1_PROFILE_ADVANCED:
331 fps_n = adv_hdr->fps_n;
332 fps_d = adv_hdr->fps_d;
333 par_n = adv_hdr->par_n;
334 par_d = adv_hdr->par_d;
337 g_assert (0 && "XXX: we already validated the profile above");
342 gst_vaapi_decoder_set_framerate (base_decoder, fps_n, fps_d);
344 if (par_n > 0 && par_d > 0)
345 gst_vaapi_decoder_set_pixel_aspect_ratio (base_decoder, par_n, par_d);
349 switch (seq_hdr->profile) {
350 case GST_VC1_PROFILE_SIMPLE:
351 case GST_VC1_PROFILE_MAIN:
352 width = seq_hdr->struct_c.coded_width;
353 height = seq_hdr->struct_c.coded_height;
355 case GST_VC1_PROFILE_ADVANCED:
356 width = seq_hdr->advanced.max_coded_width;
357 height = seq_hdr->advanced.max_coded_height;
360 g_assert (0 && "XXX: we already validated the profile above");
364 if (priv->width != width) {
366 priv->size_changed = TRUE;
369 if (priv->height != height) {
370 priv->height = height;
371 priv->size_changed = TRUE;
374 profile = GST_VAAPI_PROFILE_UNKNOWN;
375 switch (seq_hdr->profile) {
376 case GST_VC1_PROFILE_SIMPLE:
377 profile = GST_VAAPI_PROFILE_VC1_SIMPLE;
379 case GST_VC1_PROFILE_MAIN:
380 profile = GST_VAAPI_PROFILE_VC1_MAIN;
382 case GST_VC1_PROFILE_ADVANCED:
383 profile = GST_VAAPI_PROFILE_VC1_ADVANCED;
386 g_assert (0 && "XXX: we already validated the profile above");
389 if (priv->profile != profile) {
390 priv->profile = profile;
391 priv->profile_changed = TRUE;
393 return GST_VAAPI_DECODER_STATUS_SUCCESS;
396 static GstVaapiDecoderStatus
397 decode_sequence_end (GstVaapiDecoderVC1 * decoder)
399 GstVaapiDecoderVC1Private *const priv = &decoder->priv;
400 GstVaapiDecoderStatus status;
402 status = decode_current_picture (decoder);
403 if (status != GST_VAAPI_DECODER_STATUS_SUCCESS)
406 gst_vaapi_dpb_flush (priv->dpb);
407 return GST_VAAPI_DECODER_STATUS_SUCCESS;
410 static GstVaapiDecoderStatus
411 decode_entry_point (GstVaapiDecoderVC1 * decoder, GstVC1BDU * rbdu,
414 GstVaapiDecoderVC1Private *const priv = &decoder->priv;
415 GstVC1SeqHdr *const seq_hdr = &priv->seq_hdr;
416 GstVC1EntryPointHdr *const entrypoint_hdr = &priv->entrypoint_hdr;
417 GstVC1ParserResult result;
419 result = gst_vc1_parse_entry_point_header (rbdu->data + rbdu->offset,
420 rbdu->size, entrypoint_hdr, seq_hdr);
421 if (result != GST_VC1_PARSER_OK) {
422 GST_ERROR ("failed to parse entrypoint layer");
423 return get_status (result);
426 if (entrypoint_hdr->coded_size_flag) {
427 priv->width = entrypoint_hdr->coded_width;
428 priv->height = entrypoint_hdr->coded_height;
429 priv->size_changed = TRUE;
432 priv->has_entrypoint = TRUE;
433 priv->closed_entry = entrypoint_hdr->closed_entry;
434 priv->broken_link = entrypoint_hdr->broken_link;
435 return GST_VAAPI_DECODER_STATUS_SUCCESS;
438 /* Reconstruct bitstream PTYPE (7.1.1.4, index into Table-35) */
440 get_PTYPE (guint ptype)
443 case GST_VC1_PICTURE_TYPE_I:
445 case GST_VC1_PICTURE_TYPE_P:
447 case GST_VC1_PICTURE_TYPE_B:
449 case GST_VC1_PICTURE_TYPE_BI:
452 return 4; /* skipped P-frame */
455 /* Reconstruct bitstream BFRACTION (7.1.1.14, index into Table-40) */
457 get_BFRACTION (guint bfraction)
468 0, GST_VC1_BFRACTION_BASIS / 2}, {
469 1, GST_VC1_BFRACTION_BASIS / 3}, {
470 2, (GST_VC1_BFRACTION_BASIS * 2) / 3}, {
471 3, GST_VC1_BFRACTION_BASIS / 4}, {
472 4, (GST_VC1_BFRACTION_BASIS * 3) / 4}, {
473 5, GST_VC1_BFRACTION_BASIS / 5}, {
474 6, (GST_VC1_BFRACTION_BASIS * 2) / 5}, {
475 7, (GST_VC1_BFRACTION_BASIS * 3) / 5}, {
476 8, (GST_VC1_BFRACTION_BASIS * 4) / 5}, {
477 9, GST_VC1_BFRACTION_BASIS / 6}, {
478 10, (GST_VC1_BFRACTION_BASIS * 5) / 6}, {
479 11, GST_VC1_BFRACTION_BASIS / 7}, {
480 12, (GST_VC1_BFRACTION_BASIS * 2) / 7}, {
481 13, (GST_VC1_BFRACTION_BASIS * 3) / 7}, {
482 14, (GST_VC1_BFRACTION_BASIS * 4) / 7}, {
483 15, (GST_VC1_BFRACTION_BASIS * 5) / 7}, {
484 16, (GST_VC1_BFRACTION_BASIS * 6) / 7}, {
485 17, GST_VC1_BFRACTION_BASIS / 8}, {
486 18, (GST_VC1_BFRACTION_BASIS * 3) / 8}, {
487 19, (GST_VC1_BFRACTION_BASIS * 5) / 8}, {
488 20, (GST_VC1_BFRACTION_BASIS * 7) / 8}, {
489 21, GST_VC1_BFRACTION_RESERVED}, {
490 22, GST_VC1_BFRACTION_PTYPE_BI}
496 for (i = 0; i < G_N_ELEMENTS (bfraction_map); i++) {
497 if (bfraction_map[i].value == bfraction)
498 return bfraction_map[i].index;
500 return 21; /* RESERVED */
503 /* Translate GStreamer MV modes to VA-API */
505 get_VAMvModeVC1 (guint mvmode)
508 case GST_VC1_MVMODE_1MV_HPEL_BILINEAR:
509 return VAMvMode1MvHalfPelBilinear;
510 case GST_VC1_MVMODE_1MV:
512 case GST_VC1_MVMODE_1MV_HPEL:
513 return VAMvMode1MvHalfPel;
514 case GST_VC1_MVMODE_MIXED_MV:
515 return VAMvModeMixedMv;
516 case GST_VC1_MVMODE_INTENSITY_COMP:
517 return VAMvModeIntensityCompensation;
522 /* Reconstruct bitstream MVMODE (7.1.1.32) */
524 get_MVMODE (GstVC1FrameHdr * frame_hdr)
528 if (frame_hdr->profile == GST_VC1_PROFILE_ADVANCED)
529 mvmode = frame_hdr->pic.advanced.mvmode;
531 mvmode = frame_hdr->pic.simple.mvmode;
533 if (frame_hdr->ptype == GST_VC1_PICTURE_TYPE_P ||
534 frame_hdr->ptype == GST_VC1_PICTURE_TYPE_B)
535 return get_VAMvModeVC1 (mvmode);
539 /* Reconstruct bitstream MVMODE2 (7.1.1.33) */
541 get_MVMODE2 (GstVC1FrameHdr * frame_hdr)
543 guint mvmode, mvmode2;
545 if (frame_hdr->profile == GST_VC1_PROFILE_ADVANCED) {
546 mvmode = frame_hdr->pic.advanced.mvmode;
547 mvmode2 = frame_hdr->pic.advanced.mvmode2;
549 mvmode = frame_hdr->pic.simple.mvmode;
550 mvmode2 = frame_hdr->pic.simple.mvmode2;
553 if (frame_hdr->ptype == GST_VC1_PICTURE_TYPE_P &&
554 mvmode == GST_VC1_MVMODE_INTENSITY_COMP)
555 return get_VAMvModeVC1 (mvmode2);
560 has_MVTYPEMB_bitplane (GstVaapiDecoderVC1 * decoder)
562 GstVaapiDecoderVC1Private *const priv = &decoder->priv;
563 GstVC1SeqHdr *const seq_hdr = &priv->seq_hdr;
564 GstVC1FrameHdr *const frame_hdr = &priv->frame_hdr;
565 guint mvmode, mvmode2;
567 if (seq_hdr->profile == GST_VC1_PROFILE_ADVANCED) {
568 GstVC1PicAdvanced *const pic = &frame_hdr->pic.advanced;
571 mvmode = pic->mvmode;
572 mvmode2 = pic->mvmode2;
574 GstVC1PicSimpleMain *const pic = &frame_hdr->pic.simple;
577 mvmode = pic->mvmode;
578 mvmode2 = pic->mvmode2;
580 return (frame_hdr->ptype == GST_VC1_PICTURE_TYPE_P &&
581 (mvmode == GST_VC1_MVMODE_MIXED_MV ||
582 (mvmode == GST_VC1_MVMODE_INTENSITY_COMP &&
583 mvmode2 == GST_VC1_MVMODE_MIXED_MV)));
587 has_SKIPMB_bitplane (GstVaapiDecoderVC1 * decoder)
589 GstVaapiDecoderVC1Private *const priv = &decoder->priv;
590 GstVC1SeqHdr *const seq_hdr = &priv->seq_hdr;
591 GstVC1FrameHdr *const frame_hdr = &priv->frame_hdr;
593 if (seq_hdr->profile == GST_VC1_PROFILE_ADVANCED) {
594 GstVC1PicAdvanced *const pic = &frame_hdr->pic.advanced;
598 GstVC1PicSimpleMain *const pic = &frame_hdr->pic.simple;
602 return (frame_hdr->ptype == GST_VC1_PICTURE_TYPE_P ||
603 frame_hdr->ptype == GST_VC1_PICTURE_TYPE_B);
607 has_DIRECTMB_bitplane (GstVaapiDecoderVC1 * decoder)
609 GstVaapiDecoderVC1Private *const priv = &decoder->priv;
610 GstVC1SeqHdr *const seq_hdr = &priv->seq_hdr;
611 GstVC1FrameHdr *const frame_hdr = &priv->frame_hdr;
613 if (seq_hdr->profile == GST_VC1_PROFILE_ADVANCED) {
614 GstVC1PicAdvanced *const pic = &frame_hdr->pic.advanced;
618 GstVC1PicSimpleMain *const pic = &frame_hdr->pic.simple;
622 return frame_hdr->ptype == GST_VC1_PICTURE_TYPE_B;
626 has_ACPRED_bitplane (GstVaapiDecoderVC1 * decoder)
628 GstVaapiDecoderVC1Private *const priv = &decoder->priv;
629 GstVC1SeqHdr *const seq_hdr = &priv->seq_hdr;
630 GstVC1FrameHdr *const frame_hdr = &priv->frame_hdr;
631 GstVC1PicAdvanced *const pic = &frame_hdr->pic.advanced;
633 if (seq_hdr->profile != GST_VC1_PROFILE_ADVANCED)
637 return (frame_hdr->ptype == GST_VC1_PICTURE_TYPE_I ||
638 frame_hdr->ptype == GST_VC1_PICTURE_TYPE_BI);
642 has_OVERFLAGS_bitplane (GstVaapiDecoderVC1 * decoder)
644 GstVaapiDecoderVC1Private *const priv = &decoder->priv;
645 GstVC1SeqHdr *const seq_hdr = &priv->seq_hdr;
646 GstVC1EntryPointHdr *const entrypoint_hdr = &priv->entrypoint_hdr;
647 GstVC1FrameHdr *const frame_hdr = &priv->frame_hdr;
648 GstVC1PicAdvanced *const pic = &frame_hdr->pic.advanced;
650 if (seq_hdr->profile != GST_VC1_PROFILE_ADVANCED)
654 return ((frame_hdr->ptype == GST_VC1_PICTURE_TYPE_I ||
655 frame_hdr->ptype == GST_VC1_PICTURE_TYPE_BI) &&
656 (entrypoint_hdr->overlap && frame_hdr->pquant <= 8) &&
657 pic->condover == GST_VC1_CONDOVER_SELECT);
661 pack_bitplanes (GstVaapiBitPlane * bitplane, guint n,
662 const guint8 * bitplanes[3], guint x, guint y, guint stride)
664 const guint dst_index = n / 2;
665 const guint src_index = y * stride + x;
669 v |= bitplanes[0][src_index];
671 v |= bitplanes[1][src_index] << 1;
673 v |= bitplanes[2][src_index] << 2;
674 bitplane->data[dst_index] = (bitplane->data[dst_index] << 4) | v;
678 fill_picture_structc (GstVaapiDecoderVC1 * decoder, GstVaapiPicture * picture)
680 GstVaapiDecoderVC1Private *const priv = &decoder->priv;
681 VAPictureParameterBufferVC1 *const pic_param = picture->param;
682 GstVC1SeqStructC *const structc = &priv->seq_hdr.struct_c;
683 GstVC1FrameHdr *const frame_hdr = &priv->frame_hdr;
684 GstVC1PicSimpleMain *const pic = &frame_hdr->pic.simple;
686 /* Fill in VAPictureParameterBufferVC1 (simple/main profile bits) */
687 pic_param->sequence_fields.bits.finterpflag = structc->finterpflag;
688 pic_param->sequence_fields.bits.multires = structc->multires;
689 pic_param->sequence_fields.bits.overlap = structc->overlap;
690 pic_param->sequence_fields.bits.syncmarker = structc->syncmarker;
691 pic_param->sequence_fields.bits.rangered = structc->rangered;
692 pic_param->sequence_fields.bits.max_b_frames = structc->maxbframes;
693 pic_param->conditional_overlap_flag = 0; /* advanced profile only */
694 pic_param->fast_uvmc_flag = structc->fastuvmc;
695 pic_param->b_picture_fraction = get_BFRACTION (pic->bfraction);
696 pic_param->cbp_table = pic->cbptab;
697 pic_param->mb_mode_table = 0; /* XXX: interlaced frame */
698 pic_param->range_reduction_frame = pic->rangeredfrm;
699 pic_param->post_processing = 0; /* advanced profile only */
700 pic_param->picture_resolution_index = pic->respic;
701 pic_param->luma_scale = pic->lumscale;
702 pic_param->luma_shift = pic->lumshift;
703 pic_param->raw_coding.flags.mv_type_mb = pic->mvtypemb;
704 pic_param->raw_coding.flags.direct_mb = pic->directmb;
705 pic_param->raw_coding.flags.skip_mb = pic->skipmb;
706 pic_param->bitplane_present.flags.bp_mv_type_mb =
707 has_MVTYPEMB_bitplane (decoder);
708 pic_param->bitplane_present.flags.bp_direct_mb =
709 has_DIRECTMB_bitplane (decoder);
710 pic_param->bitplane_present.flags.bp_skip_mb = has_SKIPMB_bitplane (decoder);
711 pic_param->mv_fields.bits.mv_table = pic->mvtab;
712 pic_param->mv_fields.bits.extended_mv_flag = structc->extended_mv;
713 pic_param->mv_fields.bits.extended_mv_range = pic->mvrange;
714 pic_param->transform_fields.bits.variable_sized_transform_flag =
715 structc->vstransform;
716 pic_param->transform_fields.bits.mb_level_transform_type_flag = pic->ttmbf;
717 pic_param->transform_fields.bits.frame_level_transform_type = pic->ttfrm;
718 pic_param->transform_fields.bits.transform_ac_codingset_idx2 =
721 /* Refer to 8.3.7 Rounding control for Simple and Main Profile */
722 if (frame_hdr->ptype == GST_VC1_PICTURE_TYPE_I ||
723 frame_hdr->ptype == GST_VC1_PICTURE_TYPE_BI)
725 else if (frame_hdr->ptype == GST_VC1_PICTURE_TYPE_P)
728 pic_param->rounding_control = priv->rndctrl;
734 fill_picture_advanced (GstVaapiDecoderVC1 * decoder, GstVaapiPicture * picture)
736 GstVaapiDecoderVC1Private *const priv = &decoder->priv;
737 VAPictureParameterBufferVC1 *const pic_param = picture->param;
738 GstVC1AdvancedSeqHdr *const adv_hdr = &priv->seq_hdr.advanced;
739 GstVC1EntryPointHdr *const entrypoint_hdr = &priv->entrypoint_hdr;
740 GstVC1FrameHdr *const frame_hdr = &priv->frame_hdr;
741 GstVC1PicAdvanced *const pic = &frame_hdr->pic.advanced;
743 if (!priv->has_entrypoint)
746 /* Fill in VAPictureParameterBufferVC1 (advanced profile bits) */
747 pic_param->sequence_fields.bits.pulldown = adv_hdr->pulldown;
748 pic_param->sequence_fields.bits.interlace = adv_hdr->interlace;
749 pic_param->sequence_fields.bits.tfcntrflag = adv_hdr->tfcntrflag;
750 pic_param->sequence_fields.bits.finterpflag = adv_hdr->finterpflag;
751 pic_param->sequence_fields.bits.psf = adv_hdr->psf;
752 pic_param->sequence_fields.bits.overlap = entrypoint_hdr->overlap;
753 pic_param->entrypoint_fields.bits.broken_link = entrypoint_hdr->broken_link;
754 pic_param->entrypoint_fields.bits.closed_entry = entrypoint_hdr->closed_entry;
755 pic_param->entrypoint_fields.bits.panscan_flag = entrypoint_hdr->panscan_flag;
756 pic_param->entrypoint_fields.bits.loopfilter = entrypoint_hdr->loopfilter;
757 pic_param->conditional_overlap_flag = pic->condover;
758 pic_param->fast_uvmc_flag = entrypoint_hdr->fastuvmc;
759 pic_param->range_mapping_fields.bits.luma_flag =
760 entrypoint_hdr->range_mapy_flag;
761 pic_param->range_mapping_fields.bits.luma = entrypoint_hdr->range_mapy;
762 pic_param->range_mapping_fields.bits.chroma_flag =
763 entrypoint_hdr->range_mapuv_flag;
764 pic_param->range_mapping_fields.bits.chroma = entrypoint_hdr->range_mapuv;
765 pic_param->b_picture_fraction = get_BFRACTION (pic->bfraction);
766 pic_param->cbp_table = pic->cbptab;
767 pic_param->mb_mode_table = 0; /* XXX: interlaced frame */
768 pic_param->range_reduction_frame = 0; /* simple/main profile only */
769 pic_param->rounding_control = pic->rndctrl;
770 pic_param->post_processing = pic->postproc;
771 pic_param->picture_resolution_index = 0; /* simple/main profile only */
772 pic_param->luma_scale = pic->lumscale;
773 pic_param->luma_shift = pic->lumshift;
774 pic_param->picture_fields.bits.frame_coding_mode = pic->fcm;
775 pic_param->picture_fields.bits.top_field_first = pic->tff;
776 pic_param->picture_fields.bits.is_first_field = pic->fcm == 0; /* XXX: interlaced frame */
777 pic_param->picture_fields.bits.intensity_compensation =
778 pic->mvmode == GST_VC1_MVMODE_INTENSITY_COMP;
779 pic_param->raw_coding.flags.mv_type_mb = pic->mvtypemb;
780 pic_param->raw_coding.flags.direct_mb = pic->directmb;
781 pic_param->raw_coding.flags.skip_mb = pic->skipmb;
782 pic_param->raw_coding.flags.ac_pred = pic->acpred;
783 pic_param->raw_coding.flags.overflags = pic->overflags;
784 pic_param->bitplane_present.flags.bp_mv_type_mb =
785 has_MVTYPEMB_bitplane (decoder);
786 pic_param->bitplane_present.flags.bp_direct_mb =
787 has_DIRECTMB_bitplane (decoder);
788 pic_param->bitplane_present.flags.bp_skip_mb = has_SKIPMB_bitplane (decoder);
789 pic_param->bitplane_present.flags.bp_ac_pred = has_ACPRED_bitplane (decoder);
790 pic_param->bitplane_present.flags.bp_overflags =
791 has_OVERFLAGS_bitplane (decoder);
792 pic_param->reference_fields.bits.reference_distance_flag =
793 entrypoint_hdr->refdist_flag;
794 pic_param->mv_fields.bits.mv_table = pic->mvtab;
795 pic_param->mv_fields.bits.extended_mv_flag = entrypoint_hdr->extended_mv;
796 pic_param->mv_fields.bits.extended_mv_range = pic->mvrange;
797 pic_param->mv_fields.bits.extended_dmv_flag = entrypoint_hdr->extended_dmv;
798 pic_param->pic_quantizer_fields.bits.dquant = entrypoint_hdr->dquant;
799 pic_param->pic_quantizer_fields.bits.quantizer = entrypoint_hdr->quantizer;
800 pic_param->transform_fields.bits.variable_sized_transform_flag =
801 entrypoint_hdr->vstransform;
802 pic_param->transform_fields.bits.mb_level_transform_type_flag = pic->ttmbf;
803 pic_param->transform_fields.bits.frame_level_transform_type = pic->ttfrm;
804 pic_param->transform_fields.bits.transform_ac_codingset_idx2 =
810 fill_picture (GstVaapiDecoderVC1 * decoder, GstVaapiPicture * picture)
812 GstVaapiDecoderVC1Private *const priv = &decoder->priv;
813 VAPictureParameterBufferVC1 *const pic_param = picture->param;
814 GstVC1SeqHdr *const seq_hdr = &priv->seq_hdr;
815 GstVC1FrameHdr *const frame_hdr = &priv->frame_hdr;
816 GstVC1VopDquant *const vopdquant = &frame_hdr->vopdquant;
817 GstVaapiPicture *prev_picture, *next_picture;
819 /* Fill in VAPictureParameterBufferVC1 (common fields) */
820 pic_param->forward_reference_picture = VA_INVALID_ID;
821 pic_param->backward_reference_picture = VA_INVALID_ID;
822 pic_param->inloop_decoded_picture = VA_INVALID_ID;
823 pic_param->sequence_fields.value = 0;
824 pic_param->sequence_fields.bits.profile = seq_hdr->profile;
825 pic_param->coded_width = priv->width;
826 pic_param->coded_height = priv->height;
827 pic_param->entrypoint_fields.value = 0;
828 pic_param->range_mapping_fields.value = 0;
829 pic_param->picture_fields.value = 0;
830 pic_param->picture_fields.bits.picture_type = get_PTYPE (frame_hdr->ptype);
831 pic_param->raw_coding.value = 0;
832 pic_param->bitplane_present.value = 0;
833 pic_param->reference_fields.value = 0;
834 pic_param->mv_fields.value = 0;
835 pic_param->mv_fields.bits.mv_mode = get_MVMODE (frame_hdr);
836 pic_param->mv_fields.bits.mv_mode2 = get_MVMODE2 (frame_hdr);
837 pic_param->pic_quantizer_fields.value = 0;
838 pic_param->pic_quantizer_fields.bits.half_qp = frame_hdr->halfqp;
839 pic_param->pic_quantizer_fields.bits.pic_quantizer_scale = frame_hdr->pquant;
840 pic_param->pic_quantizer_fields.bits.pic_quantizer_type =
841 frame_hdr->pquantizer;
842 pic_param->pic_quantizer_fields.bits.dq_frame = vopdquant->dquantfrm;
843 pic_param->pic_quantizer_fields.bits.dq_profile = vopdquant->dqprofile;
844 pic_param->pic_quantizer_fields.bits.dq_sb_edge =
845 vopdquant->dqprofile ==
846 GST_VC1_DQPROFILE_SINGLE_EDGE ? vopdquant->dqbedge : 0;
847 pic_param->pic_quantizer_fields.bits.dq_db_edge =
848 vopdquant->dqprofile ==
849 GST_VC1_DQPROFILE_DOUBLE_EDGES ? vopdquant->dqbedge : 0;
850 pic_param->pic_quantizer_fields.bits.dq_binary_level = vopdquant->dqbilevel;
851 pic_param->pic_quantizer_fields.bits.alt_pic_quantizer = vopdquant->altpquant;
852 pic_param->transform_fields.value = 0;
853 pic_param->transform_fields.bits.transform_ac_codingset_idx1 =
854 frame_hdr->transacfrm;
855 pic_param->transform_fields.bits.intra_transform_dc_table =
856 frame_hdr->transdctab;
858 if (seq_hdr->profile == GST_VC1_PROFILE_ADVANCED) {
859 if (!fill_picture_advanced (decoder, picture))
862 if (!fill_picture_structc (decoder, picture))
866 gst_vaapi_dpb_get_neighbours (priv->dpb, picture,
867 &prev_picture, &next_picture);
869 switch (picture->type) {
870 case GST_VAAPI_PICTURE_TYPE_B:
872 pic_param->backward_reference_picture = next_picture->surface_id;
874 pic_param->forward_reference_picture = prev_picture->surface_id;
875 else if (!priv->closed_entry)
876 GST_VAAPI_PICTURE_FLAG_SET (picture, GST_VAAPI_PICTURE_FLAG_SKIPPED);
878 case GST_VAAPI_PICTURE_TYPE_P:
880 pic_param->forward_reference_picture = prev_picture->surface_id;
886 if (pic_param->bitplane_present.value) {
887 const guint8 *bitplanes[3];
890 switch (picture->type) {
891 case GST_VAAPI_PICTURE_TYPE_P:
892 bitplanes[0] = pic_param->bitplane_present.flags.bp_direct_mb ?
893 priv->bitplanes->directmb : NULL;
894 bitplanes[1] = pic_param->bitplane_present.flags.bp_skip_mb ?
895 priv->bitplanes->skipmb : NULL;
896 bitplanes[2] = pic_param->bitplane_present.flags.bp_mv_type_mb ?
897 priv->bitplanes->mvtypemb : NULL;
899 case GST_VAAPI_PICTURE_TYPE_B:
900 bitplanes[0] = pic_param->bitplane_present.flags.bp_direct_mb ?
901 priv->bitplanes->directmb : NULL;
902 bitplanes[1] = pic_param->bitplane_present.flags.bp_skip_mb ?
903 priv->bitplanes->skipmb : NULL;
904 bitplanes[2] = NULL; /* XXX: interlaced frame (FORWARD plane) */
906 case GST_VAAPI_PICTURE_TYPE_BI:
907 case GST_VAAPI_PICTURE_TYPE_I:
908 bitplanes[0] = NULL; /* XXX: interlaced frame (FIELDTX plane) */
909 bitplanes[1] = pic_param->bitplane_present.flags.bp_ac_pred ?
910 priv->bitplanes->acpred : NULL;
911 bitplanes[2] = pic_param->bitplane_present.flags.bp_overflags ?
912 priv->bitplanes->overflags : NULL;
921 picture->bitplane = GST_VAAPI_BITPLANE_NEW (decoder,
922 (seq_hdr->mb_width * seq_hdr->mb_height + 1) / 2);
923 if (!picture->bitplane)
927 for (y = 0; y < seq_hdr->mb_height; y++)
928 for (x = 0; x < seq_hdr->mb_width; x++, n++)
929 pack_bitplanes (picture->bitplane, n, bitplanes, x, y,
931 if (n & 1) /* move last nibble to the high order */
932 picture->bitplane->data[n / 2] <<= 4;
937 static GstVaapiDecoderStatus
938 decode_slice_chunk (GstVaapiDecoderVC1 * decoder, GstVC1BDU * ebdu,
939 guint slice_addr, guint header_size)
941 GstVaapiDecoderVC1Private *const priv = &decoder->priv;
942 GstVaapiPicture *const picture = priv->current_picture;
943 GstVaapiSlice *slice;
944 VASliceParameterBufferVC1 *slice_param;
946 slice = GST_VAAPI_SLICE_NEW (VC1, decoder,
947 ebdu->data + ebdu->sc_offset,
948 ebdu->size + ebdu->offset - ebdu->sc_offset);
950 GST_ERROR ("failed to allocate slice");
951 return GST_VAAPI_DECODER_STATUS_ERROR_ALLOCATION_FAILED;
953 gst_vaapi_picture_add_slice (picture, slice);
955 /* Fill in VASliceParameterBufferVC1 */
956 slice_param = slice->param;
957 slice_param->macroblock_offset = 8 * (ebdu->offset - ebdu->sc_offset) +
959 slice_param->slice_vertical_position = slice_addr;
960 return GST_VAAPI_DECODER_STATUS_SUCCESS;
963 static GstVaapiDecoderStatus
964 decode_frame (GstVaapiDecoderVC1 * decoder, GstVC1BDU * rbdu, GstVC1BDU * ebdu)
966 GstVaapiDecoderVC1Private *const priv = &decoder->priv;
967 GstVC1FrameHdr *const frame_hdr = &priv->frame_hdr;
968 GstVC1ParserResult result;
969 GstVaapiPicture *const picture = priv->current_picture;
971 memset (frame_hdr, 0, sizeof (*frame_hdr));
972 result = gst_vc1_parse_frame_header (rbdu->data + rbdu->offset,
973 rbdu->size, frame_hdr, &priv->seq_hdr, priv->bitplanes);
974 if (result != GST_VC1_PARSER_OK) {
975 GST_ERROR ("failed to parse frame layer");
976 return get_status (result);
979 /* @FIXME: intel-driver cannot handle interlaced frames */
980 if (priv->profile == GST_VAAPI_PROFILE_VC1_ADVANCED
981 && frame_hdr->pic.advanced.fcm != GST_VC1_FRAME_PROGRESSIVE) {
982 GST_ERROR ("interlaced video not supported");
983 return GST_VAAPI_DECODER_STATUS_ERROR_UNSUPPORTED_PROFILE;
986 switch (frame_hdr->ptype) {
987 case GST_VC1_PICTURE_TYPE_I:
988 picture->type = GST_VAAPI_PICTURE_TYPE_I;
989 GST_VAAPI_PICTURE_FLAG_SET (picture, GST_VAAPI_PICTURE_FLAG_REFERENCE);
991 case GST_VC1_PICTURE_TYPE_SKIPPED:
992 case GST_VC1_PICTURE_TYPE_P:
993 picture->type = GST_VAAPI_PICTURE_TYPE_P;
994 GST_VAAPI_PICTURE_FLAG_SET (picture, GST_VAAPI_PICTURE_FLAG_REFERENCE);
996 case GST_VC1_PICTURE_TYPE_B:
997 picture->type = GST_VAAPI_PICTURE_TYPE_B;
999 case GST_VC1_PICTURE_TYPE_BI:
1000 picture->type = GST_VAAPI_PICTURE_TYPE_BI;
1003 GST_ERROR ("unsupported picture type %d", frame_hdr->ptype);
1004 return GST_VAAPI_DECODER_STATUS_ERROR_UNKNOWN;
1007 /* Update presentation time */
1008 if (GST_VAAPI_PICTURE_IS_REFERENCE (picture)) {
1009 picture->poc = priv->last_non_b_picture ?
1010 (priv->last_non_b_picture->poc + 1) : priv->next_poc;
1011 priv->next_poc = picture->poc + 1;
1012 gst_vaapi_picture_replace (&priv->last_non_b_picture, picture);
1013 } else if (!priv->last_non_b_picture)
1014 picture->poc = priv->next_poc++;
1015 else { /* B or BI */
1016 picture->poc = priv->last_non_b_picture->poc++;
1017 priv->next_poc = priv->last_non_b_picture->poc + 1;
1019 picture->pts = GST_VAAPI_DECODER_CODEC_FRAME (decoder)->pts;
1021 if (!fill_picture (decoder, picture))
1022 return GST_VAAPI_DECODER_STATUS_ERROR_UNKNOWN;
1023 return decode_slice_chunk (decoder, ebdu, 0, frame_hdr->header_size);
1026 static GstVaapiDecoderStatus
1027 decode_slice (GstVaapiDecoderVC1 * decoder, GstVC1BDU * rbdu, GstVC1BDU * ebdu)
1029 GstVaapiDecoderVC1Private *const priv = &decoder->priv;
1030 GstVC1SliceHdr slice_hdr;
1031 GstVC1ParserResult result;
1033 memset (&slice_hdr, 0, sizeof (slice_hdr));
1034 result = gst_vc1_parse_slice_header (rbdu->data + rbdu->offset,
1035 rbdu->size, &slice_hdr, &priv->seq_hdr);
1036 if (result != GST_VC1_PARSER_OK) {
1037 GST_ERROR ("failed to parse slice layer");
1038 return get_status (result);
1040 return decode_slice_chunk (decoder, ebdu, slice_hdr.slice_addr,
1041 slice_hdr.header_size);
1045 decode_rbdu (GstVaapiDecoderVC1 * decoder, GstVC1BDU * rbdu, GstVC1BDU * ebdu)
1047 GstVaapiDecoderVC1Private *const priv = &decoder->priv;
1048 guint8 *rbdu_buffer;
1049 guint i, j, rbdu_buffer_size;
1051 /* BDU are encapsulated in advanced profile mode only */
1052 if (priv->profile != GST_VAAPI_PROFILE_VC1_ADVANCED) {
1053 memcpy (rbdu, ebdu, sizeof (*rbdu));
1057 /* Reallocate unescaped bitstream buffer */
1058 rbdu_buffer = priv->rbdu_buffer;
1059 if (!rbdu_buffer || ebdu->size > priv->rbdu_buffer_size) {
1060 rbdu_buffer = g_realloc (priv->rbdu_buffer, ebdu->size);
1063 priv->rbdu_buffer = rbdu_buffer;
1064 priv->rbdu_buffer_size = ebdu->size;
1067 /* Unescape bitstream buffer */
1068 if (ebdu->size < 4) {
1069 memcpy (rbdu_buffer, ebdu->data + ebdu->offset, ebdu->size);
1070 rbdu_buffer_size = ebdu->size;
1072 guint8 *const bdu_buffer = ebdu->data + ebdu->offset;
1073 for (i = 0, j = 0; i < ebdu->size; i++) {
1074 if (i >= 2 && i < ebdu->size - 1 &&
1075 bdu_buffer[i - 1] == 0x00 &&
1076 bdu_buffer[i - 2] == 0x00 &&
1077 bdu_buffer[i] == 0x03 && bdu_buffer[i + 1] <= 0x03)
1079 rbdu_buffer[j++] = bdu_buffer[i];
1081 rbdu_buffer_size = j;
1084 /* Reconstruct RBDU */
1085 rbdu->type = ebdu->type;
1086 rbdu->size = rbdu_buffer_size;
1087 rbdu->sc_offset = 0;
1089 rbdu->data = rbdu_buffer;
1093 static GstVaapiDecoderStatus
1094 decode_ebdu (GstVaapiDecoderVC1 * decoder, GstVC1BDU * ebdu)
1096 GstVaapiDecoderStatus status;
1099 if (!decode_rbdu (decoder, &rbdu, ebdu))
1100 return GST_VAAPI_DECODER_STATUS_ERROR_ALLOCATION_FAILED;
1102 switch (ebdu->type) {
1103 case GST_VC1_SEQUENCE:
1104 status = decode_sequence (decoder, &rbdu, ebdu);
1106 case GST_VC1_ENTRYPOINT:
1107 status = decode_entry_point (decoder, &rbdu, ebdu);
1110 status = decode_frame (decoder, &rbdu, ebdu);
1113 status = decode_slice (decoder, &rbdu, ebdu);
1115 case GST_VC1_END_OF_SEQ:
1116 status = decode_sequence_end (decoder);
1118 case GST_VC1_FIELD_USER:
1119 case GST_VC1_FRAME_USER:
1120 case GST_VC1_ENTRY_POINT_USER:
1121 case GST_VC1_SEQUENCE_USER:
1122 /* Let's just ignore them */
1123 status = GST_VAAPI_DECODER_STATUS_SUCCESS;
1126 GST_WARNING ("unsupported BDU type %d", ebdu->type);
1127 status = GST_VAAPI_DECODER_STATUS_ERROR_BITSTREAM_PARSER;
1133 static GstVaapiDecoderStatus
1134 decode_buffer (GstVaapiDecoderVC1 * decoder, guchar * buf, guint buf_size)
1136 GstVaapiDecoderVC1Private *const priv = &decoder->priv;
1139 if (priv->has_codec_data) {
1140 ebdu.type = GST_VC1_FRAME;
1149 ebdu.size = buf_size - ebdu.offset;
1150 return decode_ebdu (decoder, &ebdu);
1153 static GstVaapiDecoderStatus
1154 gst_vaapi_decoder_vc1_decode_codec_data (GstVaapiDecoder * base_decoder,
1155 const guchar * buf, guint buf_size)
1157 GstVaapiDecoderVC1 *const decoder = GST_VAAPI_DECODER_VC1_CAST (base_decoder);
1158 GstVaapiDecoderVC1Private *const priv = &decoder->priv;
1159 GstVC1SeqHdr *const seq_hdr = &priv->seq_hdr;
1160 GstVaapiDecoderStatus status;
1161 GstVC1ParserResult result;
1164 GstStructure *structure;
1171 priv->has_codec_data = TRUE;
1173 width = GST_VAAPI_DECODER_WIDTH (decoder);
1174 height = GST_VAAPI_DECODER_HEIGHT (decoder);
1175 if (!width || !height) {
1176 GST_ERROR ("failed to parse size from codec-data");
1177 return GST_VAAPI_DECODER_STATUS_ERROR_UNKNOWN;
1180 caps = GST_VAAPI_DECODER_CODEC_STATE (decoder)->caps;
1181 structure = gst_caps_get_structure (caps, 0);
1182 s = gst_structure_get_string (structure, "format");
1183 if (s && strlen (s) == 4) {
1184 format = GST_MAKE_FOURCC (s[0], s[1], s[2], s[3]);
1186 /* Try to determine format from "wmvversion" property */
1187 if (gst_structure_get_int (structure, "wmvversion", &version))
1188 format = (version >= 1 && version <= 3) ?
1189 GST_MAKE_FOURCC ('W', 'M', 'V', ('0' + version)) : 0;
1194 GST_ERROR ("failed to parse profile from codec-data");
1195 return GST_VAAPI_DECODER_STATUS_ERROR_UNSUPPORTED_CODEC;
1198 /* WMV3 -- expecting sequence header */
1199 if (format == GST_MAKE_FOURCC ('W', 'M', 'V', '3')) {
1200 seq_hdr->struct_c.coded_width = width;
1201 seq_hdr->struct_c.coded_height = height;
1202 ebdu.type = GST_VC1_SEQUENCE;
1203 ebdu.size = buf_size;
1206 ebdu.data = (guint8 *) buf;
1207 return decode_ebdu (decoder, &ebdu);
1210 /* WVC1 -- expecting bitstream data units */
1211 if (format != GST_MAKE_FOURCC ('W', 'V', 'C', '1'))
1212 return GST_VAAPI_DECODER_STATUS_ERROR_UNSUPPORTED_PROFILE;
1213 seq_hdr->advanced.max_coded_width = width;
1214 seq_hdr->advanced.max_coded_height = height;
1218 result = gst_vc1_identify_next_bdu (buf + ofs, buf_size - ofs, &ebdu);
1221 case GST_VC1_PARSER_NO_BDU_END:
1222 /* Assume the EBDU is complete within codec-data bounds */
1223 ebdu.size = buf_size - ofs - ebdu.offset;
1225 case GST_VC1_PARSER_OK:
1226 status = decode_ebdu (decoder, &ebdu);
1227 ofs += ebdu.offset + ebdu.size;
1230 status = get_status (result);
1233 } while (status == GST_VAAPI_DECODER_STATUS_SUCCESS && ofs < buf_size);
1237 static GstVaapiDecoderStatus
1238 ensure_decoder (GstVaapiDecoderVC1 * decoder)
1240 GstVaapiDecoderVC1Private *const priv = &decoder->priv;
1241 GstVaapiDecoderStatus status;
1243 if (!priv->is_opened) {
1244 priv->is_opened = gst_vaapi_decoder_vc1_open (decoder);
1245 if (!priv->is_opened)
1246 return GST_VAAPI_DECODER_STATUS_ERROR_UNSUPPORTED_CODEC;
1249 gst_vaapi_decoder_decode_codec_data (GST_VAAPI_DECODER_CAST (decoder));
1250 if (status != GST_VAAPI_DECODER_STATUS_SUCCESS)
1253 return GST_VAAPI_DECODER_STATUS_SUCCESS;
1257 scan_for_start_code (GstAdapter * adapter, guint ofs, guint size, guint32 * scp)
1259 return (gint) gst_adapter_masked_scan_uint32_peek (adapter,
1260 0xffffff00, 0x00000100, ofs, size, scp);
1263 static GstVaapiDecoderStatus
1264 gst_vaapi_decoder_vc1_parse (GstVaapiDecoder * base_decoder,
1265 GstAdapter * adapter, gboolean at_eos, GstVaapiDecoderUnit * unit)
1267 GstVaapiDecoderVC1 *const decoder = GST_VAAPI_DECODER_VC1_CAST (base_decoder);
1268 GstVaapiDecoderVC1Private *const priv = &decoder->priv;
1269 GstVaapiDecoderStatus status;
1271 guint size, buf_size, flags = 0;
1274 status = ensure_decoder (decoder);
1275 if (status != GST_VAAPI_DECODER_STATUS_SUCCESS)
1278 size = gst_adapter_available (adapter);
1280 if (priv->has_codec_data) {
1281 // Assume demuxer sends out plain frames
1283 return GST_VAAPI_DECODER_STATUS_ERROR_NO_DATA;
1285 bdu_type = GST_VC1_FRAME;
1288 return GST_VAAPI_DECODER_STATUS_ERROR_NO_DATA;
1290 ofs = scan_for_start_code (adapter, 0, size, NULL);
1292 return GST_VAAPI_DECODER_STATUS_ERROR_NO_DATA;
1293 gst_adapter_flush (adapter, ofs);
1296 ofs = G_UNLIKELY (size < 8) ? -1 :
1297 scan_for_start_code (adapter, 4, size - 4, NULL);
1299 // Assume the whole packet is present if end-of-stream
1301 return GST_VAAPI_DECODER_STATUS_ERROR_NO_DATA;
1305 gst_adapter_copy (adapter, &bdu_type, 3, 1);
1308 unit->size = buf_size;
1310 /* Check for new picture layer */
1312 case GST_VC1_END_OF_SEQ:
1313 flags |= GST_VAAPI_DECODER_UNIT_FLAG_FRAME_END;
1314 flags |= GST_VAAPI_DECODER_UNIT_FLAG_STREAM_END;
1316 case GST_VC1_SEQUENCE:
1317 case GST_VC1_ENTRYPOINT:
1318 flags |= GST_VAAPI_DECODER_UNIT_FLAG_FRAME_START;
1321 flags |= GST_VAAPI_DECODER_UNIT_FLAG_FRAME_START;
1322 flags |= GST_VAAPI_DECODER_UNIT_FLAG_SLICE;
1325 flags |= GST_VAAPI_DECODER_UNIT_FLAG_SLICE;
1328 /* @FIXME: intel-driver cannot handle interlaced frames */
1329 GST_ERROR ("interlaced video not supported");
1330 return GST_VAAPI_DECODER_STATUS_ERROR_UNSUPPORTED_PROFILE;
1332 GST_VAAPI_DECODER_UNIT_FLAG_SET (unit, flags);
1333 return GST_VAAPI_DECODER_STATUS_SUCCESS;
1336 static GstVaapiDecoderStatus
1337 gst_vaapi_decoder_vc1_decode (GstVaapiDecoder * base_decoder,
1338 GstVaapiDecoderUnit * unit)
1340 GstVaapiDecoderVC1 *const decoder = GST_VAAPI_DECODER_VC1_CAST (base_decoder);
1341 GstVaapiDecoderStatus status;
1342 GstBuffer *const buffer =
1343 GST_VAAPI_DECODER_CODEC_FRAME (decoder)->input_buffer;
1344 GstMapInfo map_info;
1346 status = ensure_decoder (decoder);
1347 if (status != GST_VAAPI_DECODER_STATUS_SUCCESS)
1350 if (!gst_buffer_map (buffer, &map_info, GST_MAP_READ)) {
1351 GST_ERROR ("failed to map buffer");
1352 return GST_VAAPI_DECODER_STATUS_ERROR_UNKNOWN;
1355 status = decode_buffer (decoder, map_info.data + unit->offset, unit->size);
1356 gst_buffer_unmap (buffer, &map_info);
1357 if (status != GST_VAAPI_DECODER_STATUS_SUCCESS)
1359 return GST_VAAPI_DECODER_STATUS_SUCCESS;
1362 static GstVaapiDecoderStatus
1363 gst_vaapi_decoder_vc1_start_frame (GstVaapiDecoder * base_decoder,
1364 GstVaapiDecoderUnit * unit)
1366 GstVaapiDecoderVC1 *const decoder = GST_VAAPI_DECODER_VC1_CAST (base_decoder);
1367 GstVaapiDecoderVC1Private *const priv = &decoder->priv;
1368 GstVaapiDecoderStatus status;
1369 GstVaapiPicture *picture;
1371 status = ensure_context (decoder);
1372 if (status != GST_VAAPI_DECODER_STATUS_SUCCESS) {
1373 GST_ERROR ("failed to reset context");
1376 status = ensure_decoder (decoder);
1377 if (status != GST_VAAPI_DECODER_STATUS_SUCCESS)
1380 picture = GST_VAAPI_PICTURE_NEW (VC1, decoder);
1382 GST_ERROR ("failed to allocate picture");
1383 return GST_VAAPI_DECODER_STATUS_ERROR_ALLOCATION_FAILED;
1385 gst_vaapi_picture_replace (&priv->current_picture, picture);
1386 gst_vaapi_picture_unref (picture);
1388 /* Update cropping rectangle */
1390 GstVC1AdvancedSeqHdr *adv_hdr;
1391 GstVaapiRectangle crop_rect;
1393 if (priv->profile != GST_VAAPI_PROFILE_VC1_ADVANCED)
1396 adv_hdr = &priv->seq_hdr.advanced;
1397 if (!adv_hdr->display_ext)
1402 crop_rect.width = adv_hdr->disp_horiz_size;
1403 crop_rect.height = adv_hdr->disp_vert_size;
1404 if (crop_rect.width <= priv->width && crop_rect.height <= priv->height)
1405 gst_vaapi_picture_set_crop_rect (picture, &crop_rect);
1408 if (!gst_vc1_bitplanes_ensure_size (priv->bitplanes, &priv->seq_hdr)) {
1409 GST_ERROR ("failed to allocate bitplanes");
1410 return GST_VAAPI_DECODER_STATUS_ERROR_ALLOCATION_FAILED;
1412 return GST_VAAPI_DECODER_STATUS_SUCCESS;
1415 static GstVaapiDecoderStatus
1416 gst_vaapi_decoder_vc1_end_frame (GstVaapiDecoder * base_decoder)
1418 GstVaapiDecoderVC1 *const decoder = GST_VAAPI_DECODER_VC1_CAST (base_decoder);
1420 return decode_current_picture (decoder);
1423 static GstVaapiDecoderStatus
1424 gst_vaapi_decoder_vc1_flush (GstVaapiDecoder * base_decoder)
1426 GstVaapiDecoderVC1 *const decoder = GST_VAAPI_DECODER_VC1_CAST (base_decoder);
1427 GstVaapiDecoderVC1Private *const priv = &decoder->priv;
1429 if (priv->is_opened)
1430 gst_vaapi_dpb_flush (priv->dpb);
1431 return GST_VAAPI_DECODER_STATUS_SUCCESS;
1435 gst_vaapi_decoder_vc1_finalize (GObject * object)
1437 GstVaapiDecoder *const base_decoder = GST_VAAPI_DECODER (object);
1439 gst_vaapi_decoder_vc1_destroy (base_decoder);
1440 G_OBJECT_CLASS (gst_vaapi_decoder_vc1_parent_class)->finalize (object);
1444 gst_vaapi_decoder_vc1_class_init (GstVaapiDecoderVC1Class * klass)
1446 GObjectClass *const object_class = G_OBJECT_CLASS (klass);
1447 GstVaapiDecoderClass *const decoder_class = GST_VAAPI_DECODER_CLASS (klass);
1449 object_class->finalize = gst_vaapi_decoder_vc1_finalize;
1451 decoder_class->reset = gst_vaapi_decoder_vc1_reset;
1452 decoder_class->parse = gst_vaapi_decoder_vc1_parse;
1453 decoder_class->decode = gst_vaapi_decoder_vc1_decode;
1454 decoder_class->start_frame = gst_vaapi_decoder_vc1_start_frame;
1455 decoder_class->end_frame = gst_vaapi_decoder_vc1_end_frame;
1456 decoder_class->flush = gst_vaapi_decoder_vc1_flush;
1458 decoder_class->decode_codec_data = gst_vaapi_decoder_vc1_decode_codec_data;
1462 gst_vaapi_decoder_vc1_init (GstVaapiDecoderVC1 * decoder)
1464 GstVaapiDecoder *const base_decoder = GST_VAAPI_DECODER (decoder);
1466 gst_vaapi_decoder_vc1_create (base_decoder);
1470 * gst_vaapi_decoder_vc1_new:
1471 * @display: a #GstVaapiDisplay
1472 * @caps: a #GstCaps holding codec information
1474 * Creates a new #GstVaapiDecoder for VC-1 decoding. The @caps can
1475 * hold extra information like codec-data and pictured coded size.
1477 * Return value: the newly allocated #GstVaapiDecoder object
1480 gst_vaapi_decoder_vc1_new (GstVaapiDisplay * display, GstCaps * caps)
1482 return g_object_new (GST_TYPE_VAAPI_DECODER_VC1, "display", display,
1483 "caps", caps, NULL);