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
30 #include <gst/codecparsers/gstvc1parser.h>
31 #include "gstvaapidecoder_vc1.h"
32 #include "gstvaapidecoder_objects.h"
33 #include "gstvaapidecoder_dpb.h"
34 #include "gstvaapidecoder_unit.h"
35 #include "gstvaapidecoder_priv.h"
36 #include "gstvaapidisplay_priv.h"
37 #include "gstvaapiobject_priv.h"
40 #include "gstvaapidebug.h"
42 #define GST_VAAPI_DECODER_VC1_CAST(decoder) \
43 ((GstVaapiDecoderVC1 *)(decoder))
45 typedef struct _GstVaapiDecoderVC1Private GstVaapiDecoderVC1Private;
46 typedef struct _GstVaapiDecoderVC1Class GstVaapiDecoderVC1Class;
51 * A decoder based on VC1.
53 struct _GstVaapiDecoderVC1Private {
54 GstVaapiProfile profile;
58 GstVC1EntryPointHdr entrypoint_hdr;
59 GstVC1FrameHdr frame_hdr;
60 GstVC1BitPlanes *bitplanes;
61 GstVaapiPicture *current_picture;
62 GstVaapiPicture *last_non_b_picture;
66 guint rbdu_buffer_size;
68 guint is_first_field : 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;
80 * A decoder based on VC1.
82 struct _GstVaapiDecoderVC1 {
84 GstVaapiDecoder parent_instance;
85 GstVaapiDecoderVC1Private priv;
89 * GstVaapiDecoderVC1Class:
91 * A decoder class based on VC1.
93 struct _GstVaapiDecoderVC1Class {
95 GstVaapiDecoderClass parent_class;
98 static GstVaapiDecoderStatus
99 get_status(GstVC1ParserResult result)
101 GstVaapiDecoderStatus status;
104 case GST_VC1_PARSER_OK:
105 status = GST_VAAPI_DECODER_STATUS_SUCCESS;
107 case GST_VC1_PARSER_NO_BDU_END:
108 status = GST_VAAPI_DECODER_STATUS_ERROR_NO_DATA;
110 case GST_VC1_PARSER_ERROR:
111 status = GST_VAAPI_DECODER_STATUS_ERROR_BITSTREAM_PARSER;
114 status = GST_VAAPI_DECODER_STATUS_ERROR_UNKNOWN;
121 gst_vaapi_decoder_vc1_close(GstVaapiDecoderVC1 *decoder)
123 GstVaapiDecoderVC1Private * const priv = &decoder->priv;
125 gst_vaapi_picture_replace(&priv->last_non_b_picture, NULL);
126 gst_vaapi_picture_replace(&priv->current_picture, NULL);
127 gst_vaapi_dpb_replace(&priv->dpb, NULL);
129 if (priv->bitplanes) {
130 gst_vc1_bitplanes_free(priv->bitplanes);
131 priv->bitplanes = NULL;
136 gst_vaapi_decoder_vc1_open(GstVaapiDecoderVC1 *decoder)
138 GstVaapiDecoderVC1Private * const priv = &decoder->priv;
140 gst_vaapi_decoder_vc1_close(decoder);
142 priv->dpb = gst_vaapi_dpb_new(2);
146 priv->bitplanes = gst_vc1_bitplanes_new();
147 if (!priv->bitplanes)
153 gst_vaapi_decoder_vc1_destroy(GstVaapiDecoder *base_decoder)
155 GstVaapiDecoderVC1 * const decoder =
156 GST_VAAPI_DECODER_VC1_CAST(base_decoder);
157 GstVaapiDecoderVC1Private * const priv = &decoder->priv;
159 gst_vaapi_decoder_vc1_close(decoder);
161 if (priv->rbdu_buffer) {
162 g_free(priv->rbdu_buffer);
163 priv->rbdu_buffer = NULL;
164 priv->rbdu_buffer_size = 0;
169 gst_vaapi_decoder_vc1_create(GstVaapiDecoder *base_decoder)
171 GstVaapiDecoderVC1 * const decoder =
172 GST_VAAPI_DECODER_VC1_CAST(base_decoder);
173 GstVaapiDecoderVC1Private * const priv = &decoder->priv;
175 priv->profile = (GstVaapiProfile)0;
179 static GstVaapiDecoderStatus
180 ensure_context(GstVaapiDecoderVC1 *decoder)
182 GstVaapiDecoderVC1Private * const priv = &decoder->priv;
183 GstVaapiProfile profiles[2];
184 GstVaapiEntrypoint entrypoint = GST_VAAPI_ENTRYPOINT_VLD;
185 guint i, n_profiles = 0;
186 gboolean reset_context = FALSE;
188 if (priv->profile_changed) {
189 GST_DEBUG("profile changed");
190 priv->profile_changed = FALSE;
191 reset_context = TRUE;
193 profiles[n_profiles++] = priv->profile;
194 if (priv->profile == GST_VAAPI_PROFILE_VC1_SIMPLE)
195 profiles[n_profiles++] = GST_VAAPI_PROFILE_VC1_MAIN;
197 for (i = 0; i < n_profiles; i++) {
198 if (gst_vaapi_display_has_decoder(GST_VAAPI_DECODER_DISPLAY(decoder),
199 profiles[i], entrypoint))
203 return GST_VAAPI_DECODER_STATUS_ERROR_UNSUPPORTED_PROFILE;
204 priv->profile = profiles[i];
207 if (priv->size_changed) {
208 GST_DEBUG("size changed");
209 priv->size_changed = FALSE;
210 reset_context = TRUE;
214 GstVaapiContextInfo info;
216 info.profile = priv->profile;
217 info.entrypoint = entrypoint;
218 info.chroma_type = GST_VAAPI_CHROMA_TYPE_YUV420;
219 info.width = priv->width;
220 info.height = priv->height;
222 reset_context = gst_vaapi_decoder_ensure_context(
223 GST_VAAPI_DECODER(decoder),
227 return GST_VAAPI_DECODER_STATUS_ERROR_UNKNOWN;
229 return GST_VAAPI_DECODER_STATUS_SUCCESS;
232 static GstVaapiDecoderStatus
233 decode_current_picture(GstVaapiDecoderVC1 *decoder)
235 GstVaapiDecoderVC1Private * const priv = &decoder->priv;
236 GstVaapiPicture * const picture = priv->current_picture;
239 return GST_VAAPI_DECODER_STATUS_SUCCESS;
241 if (!gst_vaapi_picture_decode(picture))
243 if (GST_VAAPI_PICTURE_IS_COMPLETE(picture)) {
244 if (!gst_vaapi_dpb_add(priv->dpb, picture))
246 gst_vaapi_picture_replace(&priv->current_picture, NULL);
248 return GST_VAAPI_DECODER_STATUS_SUCCESS;
251 /* XXX: fix for cases where first field failed to be decoded */
252 gst_vaapi_picture_replace(&priv->current_picture, NULL);
253 return GST_VAAPI_DECODER_STATUS_ERROR_UNKNOWN;
256 static GstVaapiDecoderStatus
257 decode_sequence(GstVaapiDecoderVC1 *decoder, GstVC1BDU *rbdu, GstVC1BDU *ebdu)
259 GstVaapiDecoder * const base_decoder = GST_VAAPI_DECODER(decoder);
260 GstVaapiDecoderVC1Private * const priv = &decoder->priv;
261 GstVC1SeqHdr * const seq_hdr = &priv->seq_hdr;
262 GstVC1AdvancedSeqHdr * const adv_hdr = &seq_hdr->advanced;
263 GstVC1SeqStructC * const structc = &seq_hdr->struct_c;
264 GstVC1ParserResult result;
265 GstVaapiProfile profile;
266 guint width, height, fps_n, fps_d, par_n, par_d;
268 result = gst_vc1_parse_sequence_header(
269 rbdu->data + rbdu->offset,
273 if (result != GST_VC1_PARSER_OK) {
274 GST_ERROR("failed to parse sequence layer");
275 return get_status(result);
278 priv->has_entrypoint = FALSE;
281 if (priv->last_non_b_picture) {
282 if (priv->last_non_b_picture->poc == priv->next_poc)
284 gst_vaapi_picture_replace(&priv->last_non_b_picture, NULL);
287 /* Validate profile */
288 switch (seq_hdr->profile) {
289 case GST_VC1_PROFILE_SIMPLE:
290 case GST_VC1_PROFILE_MAIN:
291 case GST_VC1_PROFILE_ADVANCED:
294 GST_ERROR("unsupported profile %d", seq_hdr->profile);
295 return GST_VAAPI_DECODER_STATUS_ERROR_UNSUPPORTED_PROFILE;
302 switch (seq_hdr->profile) {
303 case GST_VC1_PROFILE_SIMPLE:
304 case GST_VC1_PROFILE_MAIN:
306 fps_n = structc->framerate;
310 case GST_VC1_PROFILE_ADVANCED:
311 fps_n = adv_hdr->fps_n;
312 fps_d = adv_hdr->fps_d;
313 par_n = adv_hdr->par_n;
314 par_d = adv_hdr->par_d;
317 g_assert(0 && "XXX: we already validated the profile above");
322 gst_vaapi_decoder_set_framerate(base_decoder, fps_n, fps_d);
324 if (par_n > 0 && par_d > 0)
325 gst_vaapi_decoder_set_pixel_aspect_ratio(base_decoder, par_n, par_d);
327 switch (seq_hdr->profile) {
328 case GST_VC1_PROFILE_SIMPLE:
329 case GST_VC1_PROFILE_MAIN:
330 width = seq_hdr->struct_c.coded_width;
331 height = seq_hdr->struct_c.coded_height;
333 case GST_VC1_PROFILE_ADVANCED:
334 width = seq_hdr->advanced.max_coded_width;
335 height = seq_hdr->advanced.max_coded_height;
338 g_assert(0 && "XXX: we already validated the profile above");
342 if (priv->width != width) {
344 priv->size_changed = TRUE;
347 if (priv->height != height) {
348 priv->height = height;
349 priv->size_changed = TRUE;
352 switch (seq_hdr->profile) {
353 case GST_VC1_PROFILE_SIMPLE:
354 profile = GST_VAAPI_PROFILE_VC1_SIMPLE;
356 case GST_VC1_PROFILE_MAIN:
357 profile = GST_VAAPI_PROFILE_VC1_MAIN;
359 case GST_VC1_PROFILE_ADVANCED:
360 profile = GST_VAAPI_PROFILE_VC1_ADVANCED;
363 g_assert(0 && "XXX: we already validated the profile above");
366 if (priv->profile != profile) {
367 priv->profile = profile;
368 priv->profile_changed = TRUE;
370 return GST_VAAPI_DECODER_STATUS_SUCCESS;
373 static GstVaapiDecoderStatus
374 decode_sequence_end(GstVaapiDecoderVC1 *decoder)
376 GstVaapiDecoderVC1Private * const priv = &decoder->priv;
377 GstVaapiDecoderStatus status;
379 status = decode_current_picture(decoder);
380 if (status != GST_VAAPI_DECODER_STATUS_SUCCESS)
383 gst_vaapi_dpb_flush(priv->dpb);
384 return GST_VAAPI_DECODER_STATUS_SUCCESS;
387 static GstVaapiDecoderStatus
388 decode_entry_point(GstVaapiDecoderVC1 *decoder, GstVC1BDU *rbdu, GstVC1BDU *ebdu)
390 GstVaapiDecoderVC1Private * const priv = &decoder->priv;
391 GstVC1SeqHdr * const seq_hdr = &priv->seq_hdr;
392 GstVC1EntryPointHdr * const entrypoint_hdr = &priv->entrypoint_hdr;
393 GstVC1ParserResult result;
395 result = gst_vc1_parse_entry_point_header(
396 rbdu->data + rbdu->offset,
401 if (result != GST_VC1_PARSER_OK) {
402 GST_ERROR("failed to parse entrypoint layer");
403 return get_status(result);
406 if (entrypoint_hdr->coded_size_flag) {
407 priv->width = entrypoint_hdr->coded_width;
408 priv->height = entrypoint_hdr->coded_height;
409 priv->size_changed = TRUE;
412 priv->has_entrypoint = TRUE;
413 priv->closed_entry = entrypoint_hdr->closed_entry;
414 priv->broken_link = entrypoint_hdr->broken_link;
415 return GST_VAAPI_DECODER_STATUS_SUCCESS;
418 /* Reconstruct bitstream PTYPE (7.1.1.4, index into Table-35) */
420 get_PTYPE(guint ptype)
423 case GST_VC1_PICTURE_TYPE_I: return 0;
424 case GST_VC1_PICTURE_TYPE_P: return 1;
425 case GST_VC1_PICTURE_TYPE_B: return 2;
426 case GST_VC1_PICTURE_TYPE_BI: return 3;
428 return 4; /* skipped P-frame */
431 /* Reconstruct bitstream BFRACTION (7.1.1.14, index into Table-40) */
433 get_BFRACTION(guint bfraction)
437 static const struct {
442 { 0, GST_VC1_BFRACTION_BASIS / 2 },
443 { 1, GST_VC1_BFRACTION_BASIS / 3 },
444 { 2, (GST_VC1_BFRACTION_BASIS * 2) / 3 },
445 { 3, GST_VC1_BFRACTION_BASIS / 4 },
446 { 4, (GST_VC1_BFRACTION_BASIS * 3) / 4 },
447 { 5, GST_VC1_BFRACTION_BASIS / 5 },
448 { 6, (GST_VC1_BFRACTION_BASIS * 2) / 5 },
449 { 7, (GST_VC1_BFRACTION_BASIS * 3) / 5 },
450 { 8, (GST_VC1_BFRACTION_BASIS * 4) / 5 },
451 { 9, GST_VC1_BFRACTION_BASIS / 6 },
452 { 10, (GST_VC1_BFRACTION_BASIS * 5) / 6 },
453 { 11, GST_VC1_BFRACTION_BASIS / 7 },
454 { 12, (GST_VC1_BFRACTION_BASIS * 2) / 7 },
455 { 13, (GST_VC1_BFRACTION_BASIS * 3) / 7 },
456 { 14, (GST_VC1_BFRACTION_BASIS * 4) / 7 },
457 { 15, (GST_VC1_BFRACTION_BASIS * 5) / 7 },
458 { 16, (GST_VC1_BFRACTION_BASIS * 6) / 7 },
459 { 17, GST_VC1_BFRACTION_BASIS / 8 },
460 { 18, (GST_VC1_BFRACTION_BASIS * 3) / 8 },
461 { 19, (GST_VC1_BFRACTION_BASIS * 5) / 8 },
462 { 20, (GST_VC1_BFRACTION_BASIS * 7) / 8 },
463 { 21, GST_VC1_BFRACTION_RESERVED },
464 { 22, GST_VC1_BFRACTION_PTYPE_BI }
470 for (i = 0; i < G_N_ELEMENTS(bfraction_map); i++) {
471 if (bfraction_map[i].value == bfraction)
472 return bfraction_map[i].index;
474 return 21; /* RESERVED */
477 /* Translate GStreamer MV modes to VA-API */
479 get_VAMvModeVC1(guint mvmode)
482 case GST_VC1_MVMODE_1MV_HPEL_BILINEAR: return VAMvMode1MvHalfPelBilinear;
483 case GST_VC1_MVMODE_1MV: return VAMvMode1Mv;
484 case GST_VC1_MVMODE_1MV_HPEL: return VAMvMode1MvHalfPel;
485 case GST_VC1_MVMODE_MIXED_MV: return VAMvModeMixedMv;
486 case GST_VC1_MVMODE_INTENSITY_COMP: return VAMvModeIntensityCompensation;
491 /* Reconstruct bitstream MVMODE (7.1.1.32) */
493 get_MVMODE(GstVC1FrameHdr *frame_hdr)
497 if (frame_hdr->profile == GST_VC1_PROFILE_ADVANCED)
498 mvmode = frame_hdr->pic.advanced.mvmode;
500 mvmode = frame_hdr->pic.simple.mvmode;
502 if (frame_hdr->ptype == GST_VC1_PICTURE_TYPE_P ||
503 frame_hdr->ptype == GST_VC1_PICTURE_TYPE_B)
504 return get_VAMvModeVC1(mvmode);
508 /* Reconstruct bitstream MVMODE2 (7.1.1.33) */
510 get_MVMODE2(GstVC1FrameHdr *frame_hdr)
512 guint mvmode, mvmode2;
514 if (frame_hdr->profile == GST_VC1_PROFILE_ADVANCED) {
515 mvmode = frame_hdr->pic.advanced.mvmode;
516 mvmode2 = frame_hdr->pic.advanced.mvmode2;
519 mvmode = frame_hdr->pic.simple.mvmode;
520 mvmode2 = frame_hdr->pic.simple.mvmode2;
523 if (frame_hdr->ptype == GST_VC1_PICTURE_TYPE_P &&
524 mvmode == GST_VC1_MVMODE_INTENSITY_COMP)
525 return get_VAMvModeVC1(mvmode2);
530 has_MVTYPEMB_bitplane(GstVaapiDecoderVC1 *decoder)
532 GstVaapiDecoderVC1Private * const priv = &decoder->priv;
533 GstVC1SeqHdr * const seq_hdr = &priv->seq_hdr;
534 GstVC1FrameHdr * const frame_hdr = &priv->frame_hdr;
535 guint mvmode, mvmode2;
537 if (seq_hdr->profile == GST_VC1_PROFILE_ADVANCED) {
538 GstVC1PicAdvanced * const pic = &frame_hdr->pic.advanced;
541 mvmode = pic->mvmode;
542 mvmode2 = pic->mvmode2;
545 GstVC1PicSimpleMain * const pic = &frame_hdr->pic.simple;
548 mvmode = pic->mvmode;
549 mvmode2 = pic->mvmode2;
551 return (frame_hdr->ptype == GST_VC1_PICTURE_TYPE_P &&
552 (mvmode == GST_VC1_MVMODE_MIXED_MV ||
553 (mvmode == GST_VC1_MVMODE_INTENSITY_COMP &&
554 mvmode2 == GST_VC1_MVMODE_MIXED_MV)));
558 has_SKIPMB_bitplane(GstVaapiDecoderVC1 *decoder)
560 GstVaapiDecoderVC1Private * const priv = &decoder->priv;
561 GstVC1SeqHdr * const seq_hdr = &priv->seq_hdr;
562 GstVC1FrameHdr * const frame_hdr = &priv->frame_hdr;
564 if (seq_hdr->profile == GST_VC1_PROFILE_ADVANCED) {
565 GstVC1PicAdvanced * const pic = &frame_hdr->pic.advanced;
570 GstVC1PicSimpleMain * const pic = &frame_hdr->pic.simple;
574 return (frame_hdr->ptype == GST_VC1_PICTURE_TYPE_P ||
575 frame_hdr->ptype == GST_VC1_PICTURE_TYPE_B);
579 has_DIRECTMB_bitplane(GstVaapiDecoderVC1 *decoder)
581 GstVaapiDecoderVC1Private * const priv = &decoder->priv;
582 GstVC1SeqHdr * const seq_hdr = &priv->seq_hdr;
583 GstVC1FrameHdr * const frame_hdr = &priv->frame_hdr;
585 if (seq_hdr->profile == GST_VC1_PROFILE_ADVANCED) {
586 GstVC1PicAdvanced * const pic = &frame_hdr->pic.advanced;
591 GstVC1PicSimpleMain * const pic = &frame_hdr->pic.simple;
595 return frame_hdr->ptype == GST_VC1_PICTURE_TYPE_B;
599 has_ACPRED_bitplane(GstVaapiDecoderVC1 *decoder)
601 GstVaapiDecoderVC1Private * const priv = &decoder->priv;
602 GstVC1SeqHdr * const seq_hdr = &priv->seq_hdr;
603 GstVC1FrameHdr * const frame_hdr = &priv->frame_hdr;
604 GstVC1PicAdvanced * const pic = &frame_hdr->pic.advanced;
606 if (seq_hdr->profile != GST_VC1_PROFILE_ADVANCED)
610 return (frame_hdr->ptype == GST_VC1_PICTURE_TYPE_I ||
611 frame_hdr->ptype == GST_VC1_PICTURE_TYPE_BI);
615 has_OVERFLAGS_bitplane(GstVaapiDecoderVC1 *decoder)
617 GstVaapiDecoderVC1Private * const priv = &decoder->priv;
618 GstVC1SeqHdr * const seq_hdr = &priv->seq_hdr;
619 GstVC1EntryPointHdr * const entrypoint_hdr = &priv->entrypoint_hdr;
620 GstVC1FrameHdr * const frame_hdr = &priv->frame_hdr;
621 GstVC1PicAdvanced * const pic = &frame_hdr->pic.advanced;
623 if (seq_hdr->profile != GST_VC1_PROFILE_ADVANCED)
627 return ((frame_hdr->ptype == GST_VC1_PICTURE_TYPE_I ||
628 frame_hdr->ptype == GST_VC1_PICTURE_TYPE_BI) &&
629 (entrypoint_hdr->overlap && frame_hdr->pquant <= 8) &&
630 pic->condover == GST_VC1_CONDOVER_SELECT);
634 pack_bitplanes(GstVaapiBitPlane *bitplane, guint n, const guint8 *bitplanes[3], guint x, guint y, guint stride)
636 const guint dst_index = n / 2;
637 const guint src_index = y * stride + x;
641 v |= bitplanes[0][src_index];
643 v |= bitplanes[1][src_index] << 1;
645 v |= bitplanes[2][src_index] << 2;
646 bitplane->data[dst_index] = (bitplane->data[dst_index] << 4) | v;
650 fill_picture_structc(GstVaapiDecoderVC1 *decoder, GstVaapiPicture *picture)
652 GstVaapiDecoderVC1Private * const priv = &decoder->priv;
653 VAPictureParameterBufferVC1 * const pic_param = picture->param;
654 GstVC1SeqStructC * const structc = &priv->seq_hdr.struct_c;
655 GstVC1FrameHdr * const frame_hdr = &priv->frame_hdr;
656 GstVC1PicSimpleMain * const pic = &frame_hdr->pic.simple;
658 /* Fill in VAPictureParameterBufferVC1 (simple/main profile bits) */
659 pic_param->sequence_fields.bits.finterpflag = structc->finterpflag;
660 pic_param->sequence_fields.bits.multires = structc->multires;
661 pic_param->sequence_fields.bits.overlap = structc->overlap;
662 pic_param->sequence_fields.bits.syncmarker = structc->syncmarker;
663 pic_param->sequence_fields.bits.rangered = structc->rangered;
664 pic_param->sequence_fields.bits.max_b_frames = structc->maxbframes;
665 pic_param->conditional_overlap_flag = 0; /* advanced profile only */
666 pic_param->fast_uvmc_flag = structc->fastuvmc;
667 pic_param->b_picture_fraction = get_BFRACTION(pic->bfraction);
668 pic_param->cbp_table = pic->cbptab;
669 pic_param->mb_mode_table = 0; /* XXX: interlaced frame */
670 pic_param->range_reduction_frame = pic->rangeredfrm;
671 pic_param->rounding_control = 0; /* advanced profile only */
672 pic_param->post_processing = 0; /* advanced profile only */
673 pic_param->picture_resolution_index = pic->respic;
674 pic_param->luma_scale = pic->lumscale;
675 pic_param->luma_shift = pic->lumshift;
676 pic_param->raw_coding.flags.mv_type_mb = pic->mvtypemb;
677 pic_param->raw_coding.flags.direct_mb = pic->directmb;
678 pic_param->raw_coding.flags.skip_mb = pic->skipmb;
679 pic_param->bitplane_present.flags.bp_mv_type_mb = has_MVTYPEMB_bitplane(decoder);
680 pic_param->bitplane_present.flags.bp_direct_mb = has_DIRECTMB_bitplane(decoder);
681 pic_param->bitplane_present.flags.bp_skip_mb = has_SKIPMB_bitplane(decoder);
682 pic_param->mv_fields.bits.mv_table = pic->mvtab;
683 pic_param->mv_fields.bits.extended_mv_flag = structc->extended_mv;
684 pic_param->mv_fields.bits.extended_mv_range = pic->mvrange;
685 pic_param->transform_fields.bits.variable_sized_transform_flag = structc->vstransform;
686 pic_param->transform_fields.bits.mb_level_transform_type_flag = pic->ttmbf;
687 pic_param->transform_fields.bits.frame_level_transform_type = pic->ttfrm;
688 pic_param->transform_fields.bits.transform_ac_codingset_idx2 = pic->transacfrm2;
693 fill_picture_advanced(GstVaapiDecoderVC1 *decoder, GstVaapiPicture *picture)
695 GstVaapiDecoderVC1Private * const priv = &decoder->priv;
696 VAPictureParameterBufferVC1 * const pic_param = picture->param;
697 GstVC1AdvancedSeqHdr * const adv_hdr = &priv->seq_hdr.advanced;
698 GstVC1EntryPointHdr * const entrypoint_hdr = &priv->entrypoint_hdr;
699 GstVC1FrameHdr * const frame_hdr = &priv->frame_hdr;
700 GstVC1PicAdvanced * const pic = &frame_hdr->pic.advanced;
702 if (!priv->has_entrypoint)
705 /* Fill in VAPictureParameterBufferVC1 (advanced profile bits) */
706 pic_param->sequence_fields.bits.pulldown = adv_hdr->pulldown;
707 pic_param->sequence_fields.bits.interlace = adv_hdr->interlace;
708 pic_param->sequence_fields.bits.tfcntrflag = adv_hdr->tfcntrflag;
709 pic_param->sequence_fields.bits.finterpflag = adv_hdr->finterpflag;
710 pic_param->sequence_fields.bits.psf = adv_hdr->psf;
711 pic_param->sequence_fields.bits.overlap = entrypoint_hdr->overlap;
712 pic_param->entrypoint_fields.bits.broken_link = entrypoint_hdr->broken_link;
713 pic_param->entrypoint_fields.bits.closed_entry = entrypoint_hdr->closed_entry;
714 pic_param->entrypoint_fields.bits.panscan_flag = entrypoint_hdr->panscan_flag;
715 pic_param->entrypoint_fields.bits.loopfilter = entrypoint_hdr->loopfilter;
716 pic_param->conditional_overlap_flag = pic->condover;
717 pic_param->fast_uvmc_flag = entrypoint_hdr->fastuvmc;
718 pic_param->range_mapping_fields.bits.luma_flag = entrypoint_hdr->range_mapy_flag;
719 pic_param->range_mapping_fields.bits.luma = entrypoint_hdr->range_mapy;
720 pic_param->range_mapping_fields.bits.chroma_flag = entrypoint_hdr->range_mapuv_flag;
721 pic_param->range_mapping_fields.bits.chroma = entrypoint_hdr->range_mapuv;
722 pic_param->b_picture_fraction = get_BFRACTION(pic->bfraction);
723 pic_param->cbp_table = pic->cbptab;
724 pic_param->mb_mode_table = 0; /* XXX: interlaced frame */
725 pic_param->range_reduction_frame = 0; /* simple/main profile only */
726 pic_param->rounding_control = pic->rndctrl;
727 pic_param->post_processing = pic->postproc;
728 pic_param->picture_resolution_index = 0; /* simple/main profile only */
729 pic_param->luma_scale = pic->lumscale;
730 pic_param->luma_shift = pic->lumshift;
731 pic_param->picture_fields.bits.frame_coding_mode = pic->fcm;
732 pic_param->picture_fields.bits.top_field_first = pic->tff;
733 pic_param->picture_fields.bits.is_first_field = pic->fcm == 0; /* XXX: interlaced frame */
734 pic_param->picture_fields.bits.intensity_compensation = pic->mvmode == GST_VC1_MVMODE_INTENSITY_COMP;
735 pic_param->raw_coding.flags.mv_type_mb = pic->mvtypemb;
736 pic_param->raw_coding.flags.direct_mb = pic->directmb;
737 pic_param->raw_coding.flags.skip_mb = pic->skipmb;
738 pic_param->raw_coding.flags.ac_pred = pic->acpred;
739 pic_param->raw_coding.flags.overflags = pic->overflags;
740 pic_param->bitplane_present.flags.bp_mv_type_mb = has_MVTYPEMB_bitplane(decoder);
741 pic_param->bitplane_present.flags.bp_direct_mb = has_DIRECTMB_bitplane(decoder);
742 pic_param->bitplane_present.flags.bp_skip_mb = has_SKIPMB_bitplane(decoder);
743 pic_param->bitplane_present.flags.bp_ac_pred = has_ACPRED_bitplane(decoder);
744 pic_param->bitplane_present.flags.bp_overflags = has_OVERFLAGS_bitplane(decoder);
745 pic_param->reference_fields.bits.reference_distance_flag = entrypoint_hdr->refdist_flag;
746 pic_param->mv_fields.bits.mv_table = pic->mvtab;
747 pic_param->mv_fields.bits.extended_mv_flag = entrypoint_hdr->extended_mv;
748 pic_param->mv_fields.bits.extended_mv_range = pic->mvrange;
749 pic_param->mv_fields.bits.extended_dmv_flag = entrypoint_hdr->extended_dmv;
750 pic_param->pic_quantizer_fields.bits.dquant = entrypoint_hdr->dquant;
751 pic_param->pic_quantizer_fields.bits.quantizer = entrypoint_hdr->quantizer;
752 pic_param->transform_fields.bits.variable_sized_transform_flag = entrypoint_hdr->vstransform;
753 pic_param->transform_fields.bits.mb_level_transform_type_flag = pic->ttmbf;
754 pic_param->transform_fields.bits.frame_level_transform_type = pic->ttfrm;
755 pic_param->transform_fields.bits.transform_ac_codingset_idx2 = pic->transacfrm2;
760 fill_picture(GstVaapiDecoderVC1 *decoder, GstVaapiPicture *picture)
762 GstVaapiDecoderVC1Private * const priv = &decoder->priv;
763 VAPictureParameterBufferVC1 * const pic_param = picture->param;
764 GstVC1SeqHdr * const seq_hdr = &priv->seq_hdr;
765 GstVC1FrameHdr * const frame_hdr = &priv->frame_hdr;
766 GstVC1VopDquant * const vopdquant = &frame_hdr->vopdquant;
767 GstVaapiPicture *prev_picture, *next_picture;
769 /* Fill in VAPictureParameterBufferVC1 (common fields) */
770 pic_param->forward_reference_picture = VA_INVALID_ID;
771 pic_param->backward_reference_picture = VA_INVALID_ID;
772 pic_param->inloop_decoded_picture = VA_INVALID_ID;
773 pic_param->sequence_fields.value = 0;
774 #if VA_CHECK_VERSION(0,32,0)
775 pic_param->sequence_fields.bits.profile = seq_hdr->profile;
777 pic_param->coded_width = priv->width;
778 pic_param->coded_height = priv->height;
779 pic_param->entrypoint_fields.value = 0;
780 pic_param->range_mapping_fields.value = 0;
781 pic_param->picture_fields.value = 0;
782 pic_param->picture_fields.bits.picture_type = get_PTYPE(frame_hdr->ptype);
783 pic_param->raw_coding.value = 0;
784 pic_param->bitplane_present.value = 0;
785 pic_param->reference_fields.value = 0;
786 pic_param->mv_fields.value = 0;
787 pic_param->mv_fields.bits.mv_mode = get_MVMODE(frame_hdr);
788 pic_param->mv_fields.bits.mv_mode2 = get_MVMODE2(frame_hdr);
789 pic_param->pic_quantizer_fields.value = 0;
790 pic_param->pic_quantizer_fields.bits.half_qp = frame_hdr->halfqp;
791 pic_param->pic_quantizer_fields.bits.pic_quantizer_scale = frame_hdr->pquant;
792 pic_param->pic_quantizer_fields.bits.pic_quantizer_type = frame_hdr->pquantizer;
793 pic_param->pic_quantizer_fields.bits.dq_frame = vopdquant->dquantfrm;
794 pic_param->pic_quantizer_fields.bits.dq_profile = vopdquant->dqprofile;
795 pic_param->pic_quantizer_fields.bits.dq_sb_edge = vopdquant->dqprofile == GST_VC1_DQPROFILE_SINGLE_EDGE ? vopdquant->dqbedge : 0;
796 pic_param->pic_quantizer_fields.bits.dq_db_edge = vopdquant->dqprofile == GST_VC1_DQPROFILE_DOUBLE_EDGES ? vopdquant->dqbedge : 0;
797 pic_param->pic_quantizer_fields.bits.dq_binary_level = vopdquant->dqbilevel;
798 pic_param->pic_quantizer_fields.bits.alt_pic_quantizer = vopdquant->altpquant;
799 pic_param->transform_fields.value = 0;
800 pic_param->transform_fields.bits.transform_ac_codingset_idx1 = frame_hdr->transacfrm;
801 pic_param->transform_fields.bits.intra_transform_dc_table = frame_hdr->transdctab;
803 if (seq_hdr->profile == GST_VC1_PROFILE_ADVANCED) {
804 if (!fill_picture_advanced(decoder, picture))
808 if (!fill_picture_structc(decoder, picture))
812 gst_vaapi_dpb_get_neighbours(priv->dpb, picture,
813 &prev_picture, &next_picture);
815 switch (picture->type) {
816 case GST_VAAPI_PICTURE_TYPE_B:
818 pic_param->backward_reference_picture = next_picture->surface_id;
820 pic_param->forward_reference_picture = prev_picture->surface_id;
821 else if (!priv->closed_entry)
822 GST_VAAPI_PICTURE_FLAG_SET(picture, GST_VAAPI_PICTURE_FLAG_SKIPPED);
824 case GST_VAAPI_PICTURE_TYPE_P:
826 pic_param->forward_reference_picture = prev_picture->surface_id;
832 if (pic_param->bitplane_present.value) {
833 const guint8 *bitplanes[3];
836 switch (picture->type) {
837 case GST_VAAPI_PICTURE_TYPE_P:
838 bitplanes[0] = pic_param->bitplane_present.flags.bp_direct_mb ? priv->bitplanes->directmb : NULL;
839 bitplanes[1] = pic_param->bitplane_present.flags.bp_skip_mb ? priv->bitplanes->skipmb : NULL;
840 bitplanes[2] = pic_param->bitplane_present.flags.bp_mv_type_mb ? priv->bitplanes->mvtypemb : NULL;
842 case GST_VAAPI_PICTURE_TYPE_B:
843 bitplanes[0] = pic_param->bitplane_present.flags.bp_direct_mb ? priv->bitplanes->directmb : NULL;
844 bitplanes[1] = pic_param->bitplane_present.flags.bp_skip_mb ? priv->bitplanes->skipmb : NULL;
845 bitplanes[2] = NULL; /* XXX: interlaced frame (FORWARD plane) */
847 case GST_VAAPI_PICTURE_TYPE_BI:
848 case GST_VAAPI_PICTURE_TYPE_I:
849 bitplanes[0] = NULL; /* XXX: interlaced frame (FIELDTX plane) */
850 bitplanes[1] = pic_param->bitplane_present.flags.bp_ac_pred ? priv->bitplanes->acpred : NULL;
851 bitplanes[2] = pic_param->bitplane_present.flags.bp_overflags ? priv->bitplanes->overflags : NULL;
860 picture->bitplane = GST_VAAPI_BITPLANE_NEW(
862 (seq_hdr->mb_width * seq_hdr->mb_height + 1) / 2
864 if (!picture->bitplane)
868 for (y = 0; y < seq_hdr->mb_height; y++)
869 for (x = 0; x < seq_hdr->mb_width; x++, n++)
870 pack_bitplanes(picture->bitplane, n, bitplanes, x, y, seq_hdr->mb_stride);
871 if (n & 1) /* move last nibble to the high order */
872 picture->bitplane->data[n/2] <<= 4;
877 static GstVaapiDecoderStatus
878 decode_slice_chunk(GstVaapiDecoderVC1 *decoder, GstVC1BDU *ebdu,
879 guint slice_addr, guint header_size)
881 GstVaapiDecoderVC1Private * const priv = &decoder->priv;
882 GstVaapiPicture * const picture = priv->current_picture;
883 GstVaapiSlice *slice;
884 VASliceParameterBufferVC1 *slice_param;
886 slice = GST_VAAPI_SLICE_NEW(VC1, decoder,
887 ebdu->data + ebdu->sc_offset,
888 ebdu->size + ebdu->offset - ebdu->sc_offset);
890 GST_ERROR("failed to allocate slice");
891 return GST_VAAPI_DECODER_STATUS_ERROR_ALLOCATION_FAILED;
893 gst_vaapi_picture_add_slice(picture, slice);
895 /* Fill in VASliceParameterBufferVC1 */
896 slice_param = slice->param;
897 slice_param->macroblock_offset = 8 * (ebdu->offset - ebdu->sc_offset) +
899 slice_param->slice_vertical_position = slice_addr;
900 return GST_VAAPI_DECODER_STATUS_SUCCESS;
903 static GstVaapiDecoderStatus
904 decode_frame(GstVaapiDecoderVC1 *decoder, GstVC1BDU *rbdu, GstVC1BDU *ebdu)
906 GstVaapiDecoderVC1Private * const priv = &decoder->priv;
907 GstVC1FrameHdr * const frame_hdr = &priv->frame_hdr;
908 GstVC1ParserResult result;
909 GstVaapiPicture * const picture = priv->current_picture;
911 memset(frame_hdr, 0, sizeof(*frame_hdr));
912 result = gst_vc1_parse_frame_header(
913 rbdu->data + rbdu->offset,
919 if (result != GST_VC1_PARSER_OK) {
920 GST_ERROR("failed to parse frame layer");
921 return get_status(result);
924 switch (frame_hdr->ptype) {
925 case GST_VC1_PICTURE_TYPE_I:
926 picture->type = GST_VAAPI_PICTURE_TYPE_I;
927 GST_VAAPI_PICTURE_FLAG_SET(picture, GST_VAAPI_PICTURE_FLAG_REFERENCE);
929 case GST_VC1_PICTURE_TYPE_SKIPPED:
930 case GST_VC1_PICTURE_TYPE_P:
931 picture->type = GST_VAAPI_PICTURE_TYPE_P;
932 GST_VAAPI_PICTURE_FLAG_SET(picture, GST_VAAPI_PICTURE_FLAG_REFERENCE);
934 case GST_VC1_PICTURE_TYPE_B:
935 picture->type = GST_VAAPI_PICTURE_TYPE_B;
937 case GST_VC1_PICTURE_TYPE_BI:
938 picture->type = GST_VAAPI_PICTURE_TYPE_BI;
941 GST_ERROR("unsupported picture type %d", frame_hdr->ptype);
942 return GST_VAAPI_DECODER_STATUS_ERROR_UNKNOWN;
945 /* Update presentation time */
946 if (GST_VAAPI_PICTURE_IS_REFERENCE(picture)) {
947 picture->poc = priv->last_non_b_picture ?
948 (priv->last_non_b_picture->poc + 1) : priv->next_poc;
949 priv->next_poc = picture->poc + 1;
950 gst_vaapi_picture_replace(&priv->last_non_b_picture, picture);
952 else if (!priv->last_non_b_picture)
953 picture->poc = priv->next_poc++;
955 picture->poc = priv->last_non_b_picture->poc++;
956 priv->next_poc = priv->last_non_b_picture->poc + 1;
958 picture->pts = GST_VAAPI_DECODER_CODEC_FRAME(decoder)->pts;
960 if (!fill_picture(decoder, picture))
961 return GST_VAAPI_DECODER_STATUS_ERROR_UNKNOWN;
962 return decode_slice_chunk(decoder, ebdu, 0, frame_hdr->header_size);
965 static GstVaapiDecoderStatus
966 decode_slice(GstVaapiDecoderVC1 *decoder, GstVC1BDU *rbdu, GstVC1BDU *ebdu)
968 GstVaapiDecoderVC1Private * const priv = &decoder->priv;
969 GstVC1SliceHdr slice_hdr;
970 GstVC1ParserResult result;
972 memset(&slice_hdr, 0, sizeof(slice_hdr));
973 result = gst_vc1_parse_slice_header(
974 rbdu->data + rbdu->offset,
979 if (result != GST_VC1_PARSER_OK) {
980 GST_ERROR("failed to parse slice layer");
981 return get_status(result);
983 return decode_slice_chunk(decoder, ebdu, slice_hdr.slice_addr,
984 slice_hdr.header_size);
988 decode_rbdu(GstVaapiDecoderVC1 *decoder, GstVC1BDU *rbdu, GstVC1BDU *ebdu)
990 GstVaapiDecoderVC1Private * const priv = &decoder->priv;
992 guint i, j, rbdu_buffer_size;
994 /* BDU are encapsulated in advanced profile mode only */
995 if (priv->profile != GST_VAAPI_PROFILE_VC1_ADVANCED) {
996 memcpy(rbdu, ebdu, sizeof(*rbdu));
1000 /* Reallocate unescaped bitstream buffer */
1001 rbdu_buffer = priv->rbdu_buffer;
1002 if (!rbdu_buffer || ebdu->size > priv->rbdu_buffer_size) {
1003 rbdu_buffer = g_realloc(priv->rbdu_buffer, ebdu->size);
1006 priv->rbdu_buffer = rbdu_buffer;
1007 priv->rbdu_buffer_size = ebdu->size;
1010 /* Unescape bitstream buffer */
1011 if (ebdu->size < 4) {
1012 memcpy(rbdu_buffer, ebdu->data + ebdu->offset, ebdu->size);
1013 rbdu_buffer_size = ebdu->size;
1016 guint8 * const bdu_buffer = ebdu->data + ebdu->offset;
1017 for (i = 0, j = 0; i < ebdu->size; i++) {
1018 if (i >= 2 && i < ebdu->size - 1 &&
1019 bdu_buffer[i - 1] == 0x00 &&
1020 bdu_buffer[i - 2] == 0x00 &&
1021 bdu_buffer[i ] == 0x03 &&
1022 bdu_buffer[i + 1] <= 0x03)
1024 rbdu_buffer[j++] = bdu_buffer[i];
1026 rbdu_buffer_size = j;
1029 /* Reconstruct RBDU */
1030 rbdu->type = ebdu->type;
1031 rbdu->size = rbdu_buffer_size;
1032 rbdu->sc_offset = 0;
1034 rbdu->data = rbdu_buffer;
1038 static GstVaapiDecoderStatus
1039 decode_ebdu(GstVaapiDecoderVC1 *decoder, GstVC1BDU *ebdu)
1041 GstVaapiDecoderStatus status;
1044 if (!decode_rbdu(decoder, &rbdu, ebdu))
1045 return GST_VAAPI_DECODER_STATUS_ERROR_ALLOCATION_FAILED;
1047 switch (ebdu->type) {
1048 case GST_VC1_SEQUENCE:
1049 status = decode_sequence(decoder, &rbdu, ebdu);
1051 case GST_VC1_ENTRYPOINT:
1052 status = decode_entry_point(decoder, &rbdu, ebdu);
1055 status = decode_frame(decoder, &rbdu, ebdu);
1058 status = decode_slice(decoder, &rbdu, ebdu);
1060 case GST_VC1_END_OF_SEQ:
1061 status = decode_sequence_end(decoder);
1064 GST_WARNING("unsupported BDU type %d", ebdu->type);
1065 status = GST_VAAPI_DECODER_STATUS_ERROR_BITSTREAM_PARSER;
1071 static GstVaapiDecoderStatus
1072 decode_buffer(GstVaapiDecoderVC1 *decoder, guchar *buf, guint buf_size)
1074 GstVaapiDecoderVC1Private * const priv = &decoder->priv;
1077 if (priv->has_codec_data) {
1078 ebdu.type = GST_VC1_FRAME;
1088 ebdu.size = buf_size - ebdu.offset;
1089 return decode_ebdu(decoder, &ebdu);
1092 static GstVaapiDecoderStatus
1093 gst_vaapi_decoder_vc1_decode_codec_data(GstVaapiDecoder *base_decoder,
1094 const guchar *buf, guint buf_size)
1096 GstVaapiDecoderVC1 * const decoder =
1097 GST_VAAPI_DECODER_VC1_CAST(base_decoder);
1098 GstVaapiDecoderVC1Private * const priv = &decoder->priv;
1099 GstVC1SeqHdr * const seq_hdr = &priv->seq_hdr;
1100 GstVaapiDecoderStatus status;
1101 GstVC1ParserResult result;
1104 GstStructure *structure;
1110 priv->has_codec_data = TRUE;
1112 width = GST_VAAPI_DECODER_WIDTH(decoder);
1113 height = GST_VAAPI_DECODER_HEIGHT(decoder);
1114 if (!width || !height) {
1115 GST_ERROR("failed to parse size from codec-data");
1116 return GST_VAAPI_DECODER_STATUS_ERROR_UNKNOWN;
1119 caps = GST_VAAPI_DECODER_CODEC_STATE(decoder)->caps;
1120 structure = gst_caps_get_structure(caps, 0);
1121 if (!gst_structure_get_fourcc(structure, "format", &format)) {
1122 /* Try to determine format from "wmvversion" property */
1123 if (gst_structure_get_int(structure, "wmvversion", &version))
1124 format = (version >= 1 && version <= 3) ?
1125 GST_MAKE_FOURCC('W','M','V',('0'+version)) : 0;
1130 GST_ERROR("failed to parse profile from codec-data");
1131 return GST_VAAPI_DECODER_STATUS_ERROR_UNSUPPORTED_CODEC;
1134 /* WMV3 -- expecting sequence header */
1135 if (format == GST_MAKE_FOURCC('W','M','V','3')) {
1136 seq_hdr->struct_c.coded_width = width;
1137 seq_hdr->struct_c.coded_height = height;
1138 ebdu.type = GST_VC1_SEQUENCE;
1139 ebdu.size = buf_size;
1142 ebdu.data = (guint8 *)buf;
1143 return decode_ebdu(decoder, &ebdu);
1146 /* WVC1 -- expecting bitstream data units */
1147 if (format != GST_MAKE_FOURCC('W','V','C','1'))
1148 return GST_VAAPI_DECODER_STATUS_ERROR_UNSUPPORTED_PROFILE;
1149 seq_hdr->advanced.max_coded_width = width;
1150 seq_hdr->advanced.max_coded_height = height;
1154 result = gst_vc1_identify_next_bdu(
1161 case GST_VC1_PARSER_NO_BDU_END:
1162 /* Assume the EBDU is complete within codec-data bounds */
1163 ebdu.size = buf_size - ofs - ebdu.offset;
1165 case GST_VC1_PARSER_OK:
1166 status = decode_ebdu(decoder, &ebdu);
1167 ofs += ebdu.offset + ebdu.size;
1170 status = get_status(result);
1173 } while (status == GST_VAAPI_DECODER_STATUS_SUCCESS && ofs < buf_size);
1177 static GstVaapiDecoderStatus
1178 ensure_decoder(GstVaapiDecoderVC1 *decoder)
1180 GstVaapiDecoderVC1Private * const priv = &decoder->priv;
1181 GstVaapiDecoderStatus status;
1183 if (!priv->is_opened) {
1184 priv->is_opened = gst_vaapi_decoder_vc1_open(decoder);
1185 if (!priv->is_opened)
1186 return GST_VAAPI_DECODER_STATUS_ERROR_UNSUPPORTED_CODEC;
1188 status = gst_vaapi_decoder_decode_codec_data(
1189 GST_VAAPI_DECODER_CAST(decoder));
1190 if (status != GST_VAAPI_DECODER_STATUS_SUCCESS)
1193 return GST_VAAPI_DECODER_STATUS_SUCCESS;
1197 scan_for_start_code(GstAdapter *adapter, guint ofs, guint size, guint32 *scp)
1199 return (gint)gst_adapter_masked_scan_uint32_peek(adapter,
1200 0xffffff00, 0x00000100, ofs, size, scp);
1203 static GstVaapiDecoderStatus
1204 gst_vaapi_decoder_vc1_parse(GstVaapiDecoder *base_decoder,
1205 GstAdapter *adapter, gboolean at_eos, GstVaapiDecoderUnit *unit)
1207 GstVaapiDecoderVC1 * const decoder =
1208 GST_VAAPI_DECODER_VC1_CAST(base_decoder);
1209 GstVaapiDecoderVC1Private * const priv = &decoder->priv;
1210 GstVaapiDecoderStatus status;
1212 guint size, buf_size, flags = 0;
1215 status = ensure_decoder(decoder);
1216 if (status != GST_VAAPI_DECODER_STATUS_SUCCESS)
1219 size = gst_adapter_available(adapter);
1221 if (priv->has_codec_data) {
1222 // Assume demuxer sends out plain frames
1224 return GST_VAAPI_DECODER_STATUS_ERROR_NO_DATA;
1226 bdu_type = GST_VC1_FRAME;
1230 return GST_VAAPI_DECODER_STATUS_ERROR_NO_DATA;
1232 ofs = scan_for_start_code(adapter, 0, size, NULL);
1234 return GST_VAAPI_DECODER_STATUS_ERROR_NO_DATA;
1235 gst_adapter_flush(adapter, ofs);
1238 ofs = G_UNLIKELY(size < 8) ? -1 :
1239 scan_for_start_code(adapter, 4, size - 4, NULL);
1241 // Assume the whole packet is present if end-of-stream
1243 return GST_VAAPI_DECODER_STATUS_ERROR_NO_DATA;
1247 gst_adapter_copy(adapter, &bdu_type, 3, 1);
1250 unit->size = buf_size;
1252 /* Check for new picture layer */
1254 case GST_VC1_END_OF_SEQ:
1255 flags |= GST_VAAPI_DECODER_UNIT_FLAG_FRAME_END;
1256 flags |= GST_VAAPI_DECODER_UNIT_FLAG_STREAM_END;
1258 case GST_VC1_SEQUENCE:
1259 case GST_VC1_ENTRYPOINT:
1260 flags |= GST_VAAPI_DECODER_UNIT_FLAG_FRAME_START;
1263 flags |= GST_VAAPI_DECODER_UNIT_FLAG_FRAME_START;
1264 flags |= GST_VAAPI_DECODER_UNIT_FLAG_SLICE;
1267 flags |= GST_VAAPI_DECODER_UNIT_FLAG_SLICE;
1270 GST_VAAPI_DECODER_UNIT_FLAG_SET(unit, flags);
1271 return GST_VAAPI_DECODER_STATUS_SUCCESS;
1274 static GstVaapiDecoderStatus
1275 gst_vaapi_decoder_vc1_decode(GstVaapiDecoder *base_decoder,
1276 GstVaapiDecoderUnit *unit)
1278 GstVaapiDecoderVC1 * const decoder =
1279 GST_VAAPI_DECODER_VC1_CAST(base_decoder);
1280 GstVaapiDecoderStatus status;
1281 GstBuffer * const buffer =
1282 GST_VAAPI_DECODER_CODEC_FRAME(decoder)->input_buffer;
1283 GstMapInfo map_info;
1285 status = ensure_decoder(decoder);
1286 if (status != GST_VAAPI_DECODER_STATUS_SUCCESS)
1289 if (!gst_buffer_map(buffer, &map_info, GST_MAP_READ)) {
1290 GST_ERROR("failed to map buffer");
1291 return GST_VAAPI_DECODER_STATUS_ERROR_UNKNOWN;
1294 status = decode_buffer(decoder, map_info.data + unit->offset, unit->size);
1295 gst_buffer_unmap(buffer, &map_info);
1296 if (status != GST_VAAPI_DECODER_STATUS_SUCCESS)
1298 return GST_VAAPI_DECODER_STATUS_SUCCESS;
1301 static GstVaapiDecoderStatus
1302 gst_vaapi_decoder_vc1_start_frame(GstVaapiDecoder *base_decoder,
1303 GstVaapiDecoderUnit *unit)
1305 GstVaapiDecoderVC1 * const decoder =
1306 GST_VAAPI_DECODER_VC1_CAST(base_decoder);
1307 GstVaapiDecoderVC1Private * const priv = &decoder->priv;
1308 GstVaapiDecoderStatus status;
1309 GstVaapiPicture *picture;
1311 status = ensure_context(decoder);
1312 if (status != GST_VAAPI_DECODER_STATUS_SUCCESS) {
1313 GST_ERROR("failed to reset context");
1317 picture = GST_VAAPI_PICTURE_NEW(VC1, decoder);
1319 GST_ERROR("failed to allocate picture");
1320 return GST_VAAPI_DECODER_STATUS_ERROR_ALLOCATION_FAILED;
1322 gst_vaapi_picture_replace(&priv->current_picture, picture);
1323 gst_vaapi_picture_unref(picture);
1325 /* Update cropping rectangle */
1327 GstVC1AdvancedSeqHdr *adv_hdr;
1328 GstVaapiRectangle crop_rect;
1330 if (priv->profile != GST_VAAPI_PROFILE_VC1_ADVANCED)
1333 adv_hdr = &priv->seq_hdr.advanced;
1334 if (!adv_hdr->display_ext)
1339 crop_rect.width = adv_hdr->disp_horiz_size;
1340 crop_rect.height = adv_hdr->disp_vert_size;
1341 if (crop_rect.width <= priv->width && crop_rect.height <= priv->height)
1342 gst_vaapi_picture_set_crop_rect(picture, &crop_rect);
1345 if (!gst_vc1_bitplanes_ensure_size(priv->bitplanes, &priv->seq_hdr)) {
1346 GST_ERROR("failed to allocate bitplanes");
1347 return GST_VAAPI_DECODER_STATUS_ERROR_ALLOCATION_FAILED;
1349 return GST_VAAPI_DECODER_STATUS_SUCCESS;
1352 static GstVaapiDecoderStatus
1353 gst_vaapi_decoder_vc1_end_frame(GstVaapiDecoder *base_decoder)
1355 GstVaapiDecoderVC1 * const decoder =
1356 GST_VAAPI_DECODER_VC1_CAST(base_decoder);
1358 return decode_current_picture(decoder);
1361 static GstVaapiDecoderStatus
1362 gst_vaapi_decoder_vc1_flush(GstVaapiDecoder *base_decoder)
1364 GstVaapiDecoderVC1 * const decoder =
1365 GST_VAAPI_DECODER_VC1_CAST(base_decoder);
1366 GstVaapiDecoderVC1Private * const priv = &decoder->priv;
1368 gst_vaapi_dpb_flush(priv->dpb);
1369 return GST_VAAPI_DECODER_STATUS_SUCCESS;
1373 gst_vaapi_decoder_vc1_class_init(GstVaapiDecoderVC1Class *klass)
1375 GstVaapiMiniObjectClass * const object_class =
1376 GST_VAAPI_MINI_OBJECT_CLASS(klass);
1377 GstVaapiDecoderClass * const decoder_class = GST_VAAPI_DECODER_CLASS(klass);
1379 object_class->size = sizeof(GstVaapiDecoderVC1);
1380 object_class->finalize = (GDestroyNotify)gst_vaapi_decoder_finalize;
1382 decoder_class->create = gst_vaapi_decoder_vc1_create;
1383 decoder_class->destroy = gst_vaapi_decoder_vc1_destroy;
1384 decoder_class->parse = gst_vaapi_decoder_vc1_parse;
1385 decoder_class->decode = gst_vaapi_decoder_vc1_decode;
1386 decoder_class->start_frame = gst_vaapi_decoder_vc1_start_frame;
1387 decoder_class->end_frame = gst_vaapi_decoder_vc1_end_frame;
1388 decoder_class->flush = gst_vaapi_decoder_vc1_flush;
1390 decoder_class->decode_codec_data =
1391 gst_vaapi_decoder_vc1_decode_codec_data;
1394 static inline const GstVaapiDecoderClass *
1395 gst_vaapi_decoder_vc1_class(void)
1397 static GstVaapiDecoderVC1Class g_class;
1398 static gsize g_class_init = FALSE;
1400 if (g_once_init_enter(&g_class_init)) {
1401 gst_vaapi_decoder_vc1_class_init(&g_class);
1402 g_once_init_leave(&g_class_init, TRUE);
1404 return GST_VAAPI_DECODER_CLASS(&g_class);
1408 * gst_vaapi_decoder_vc1_new:
1409 * @display: a #GstVaapiDisplay
1410 * @caps: a #GstCaps holding codec information
1412 * Creates a new #GstVaapiDecoder for VC-1 decoding. The @caps can
1413 * hold extra information like codec-data and pictured coded size.
1415 * Return value: the newly allocated #GstVaapiDecoder object
1418 gst_vaapi_decoder_vc1_new(GstVaapiDisplay *display, GstCaps *caps)
1420 return gst_vaapi_decoder_new(gst_vaapi_decoder_vc1_class(), display, caps);