2 * gstvaapidecoder_vc1.c - VC-1 decoder
4 * Copyright (C) 2011 Intel Corporation
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public License
8 * as published by the Free Software Foundation; either version 2.1
9 * of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free
18 * Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
19 * Boston, MA 02110-1301 USA
23 * SECTION:gstvaapidecoder_vc1
24 * @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"
36 #include "gstvaapiobject_priv.h"
39 #include "gstvaapidebug.h"
41 G_DEFINE_TYPE(GstVaapiDecoderVC1,
42 gst_vaapi_decoder_vc1,
43 GST_VAAPI_TYPE_DECODER)
45 #define GST_VAAPI_DECODER_VC1_GET_PRIVATE(obj) \
46 (G_TYPE_INSTANCE_GET_PRIVATE((obj), \
47 GST_VAAPI_TYPE_DECODER_VC1, \
48 GstVaapiDecoderVC1Private))
50 struct _GstVaapiDecoderVC1Private {
51 GstVaapiProfile profile;
55 GstVC1EntryPointHdr entrypoint_hdr;
56 GstVC1FrameHdr frame_hdr;
57 GstVC1BitPlanes *bitplanes;
58 GstVaapiPicture *current_picture;
59 GstVaapiPicture *last_non_b_picture;
63 guint rbdu_buffer_size;
64 guint is_constructed : 1;
66 guint is_first_field : 1;
67 guint has_codec_data : 1;
68 guint has_entrypoint : 1;
69 guint size_changed : 1;
70 guint profile_changed : 1;
71 guint closed_entry : 1;
72 guint broken_link : 1;
75 static GstVaapiDecoderStatus
76 get_status(GstVC1ParserResult result)
78 GstVaapiDecoderStatus status;
81 case GST_VC1_PARSER_OK:
82 status = GST_VAAPI_DECODER_STATUS_SUCCESS;
84 case GST_VC1_PARSER_NO_BDU_END:
85 status = GST_VAAPI_DECODER_STATUS_ERROR_NO_DATA;
87 case GST_VC1_PARSER_ERROR:
88 status = GST_VAAPI_DECODER_STATUS_ERROR_BITSTREAM_PARSER;
91 status = GST_VAAPI_DECODER_STATUS_ERROR_UNKNOWN;
98 gst_vaapi_decoder_vc1_close(GstVaapiDecoderVC1 *decoder)
100 GstVaapiDecoderVC1Private * const priv = decoder->priv;
102 gst_vaapi_picture_replace(&priv->last_non_b_picture, NULL);
103 gst_vaapi_picture_replace(&priv->current_picture, NULL);
104 gst_vaapi_dpb_replace(&priv->dpb, NULL);
106 if (priv->bitplanes) {
107 gst_vc1_bitplanes_free(priv->bitplanes);
108 priv->bitplanes = NULL;
113 gst_vaapi_decoder_vc1_open(GstVaapiDecoderVC1 *decoder)
115 GstVaapiDecoderVC1Private * const priv = decoder->priv;
117 gst_vaapi_decoder_vc1_close(decoder);
119 priv->dpb = gst_vaapi_dpb_new(2);
123 priv->bitplanes = gst_vc1_bitplanes_new();
124 if (!priv->bitplanes)
130 gst_vaapi_decoder_vc1_destroy(GstVaapiDecoderVC1 *decoder)
132 GstVaapiDecoderVC1Private * const priv = decoder->priv;
134 gst_vaapi_decoder_vc1_close(decoder);
136 if (priv->rbdu_buffer) {
137 g_free(priv->rbdu_buffer);
138 priv->rbdu_buffer = NULL;
139 priv->rbdu_buffer_size = 0;
144 gst_vaapi_decoder_vc1_create(GstVaapiDecoderVC1 *decoder)
146 if (!GST_VAAPI_DECODER_CODEC(decoder))
151 static GstVaapiDecoderStatus
152 ensure_context(GstVaapiDecoderVC1 *decoder)
154 GstVaapiDecoderVC1Private * const priv = decoder->priv;
155 GstVaapiProfile profiles[2];
156 GstVaapiEntrypoint entrypoint = GST_VAAPI_ENTRYPOINT_VLD;
157 guint i, n_profiles = 0;
158 gboolean reset_context = FALSE;
160 if (priv->profile_changed) {
161 GST_DEBUG("profile changed");
162 priv->profile_changed = FALSE;
163 reset_context = TRUE;
165 profiles[n_profiles++] = priv->profile;
166 if (priv->profile == GST_VAAPI_PROFILE_VC1_SIMPLE)
167 profiles[n_profiles++] = GST_VAAPI_PROFILE_VC1_MAIN;
169 for (i = 0; i < n_profiles; i++) {
170 if (gst_vaapi_display_has_decoder(GST_VAAPI_DECODER_DISPLAY(decoder),
171 profiles[i], entrypoint))
175 return GST_VAAPI_DECODER_STATUS_ERROR_UNSUPPORTED_PROFILE;
176 priv->profile = profiles[i];
179 if (priv->size_changed) {
180 GST_DEBUG("size changed");
181 priv->size_changed = FALSE;
182 reset_context = TRUE;
186 GstVaapiContextInfo info;
188 info.profile = priv->profile;
189 info.entrypoint = entrypoint;
190 info.width = priv->width;
191 info.height = priv->height;
193 reset_context = gst_vaapi_decoder_ensure_context(
194 GST_VAAPI_DECODER(decoder),
198 return GST_VAAPI_DECODER_STATUS_ERROR_UNKNOWN;
200 return GST_VAAPI_DECODER_STATUS_SUCCESS;
203 static GstVaapiDecoderStatus
204 decode_current_picture(GstVaapiDecoderVC1 *decoder)
206 GstVaapiDecoderVC1Private * const priv = decoder->priv;
207 GstVaapiPicture * const picture = priv->current_picture;
210 return GST_VAAPI_DECODER_STATUS_SUCCESS;
212 if (!gst_vaapi_picture_decode(picture))
214 if (GST_VAAPI_PICTURE_IS_COMPLETE(picture)) {
215 if (!gst_vaapi_dpb_add(priv->dpb, picture))
217 gst_vaapi_picture_replace(&priv->current_picture, NULL);
219 return GST_VAAPI_DECODER_STATUS_SUCCESS;
222 /* XXX: fix for cases where first field failed to be decoded */
223 gst_vaapi_picture_replace(&priv->current_picture, NULL);
224 return GST_VAAPI_DECODER_STATUS_ERROR_UNKNOWN;
227 static GstVaapiDecoderStatus
228 decode_sequence(GstVaapiDecoderVC1 *decoder, GstVC1BDU *rbdu, GstVC1BDU *ebdu)
230 GstVaapiDecoder * const base_decoder = GST_VAAPI_DECODER(decoder);
231 GstVaapiDecoderVC1Private * const priv = decoder->priv;
232 GstVC1SeqHdr * const seq_hdr = &priv->seq_hdr;
233 GstVC1AdvancedSeqHdr * const adv_hdr = &seq_hdr->advanced;
234 GstVC1SeqStructC * const structc = &seq_hdr->struct_c;
235 GstVC1ParserResult result;
236 GstVaapiProfile profile;
237 guint width, height, fps_n, fps_d, par_n, par_d;
239 result = gst_vc1_parse_sequence_header(
240 rbdu->data + rbdu->offset,
244 if (result != GST_VC1_PARSER_OK) {
245 GST_DEBUG("failed to parse sequence layer");
246 return get_status(result);
249 priv->has_entrypoint = FALSE;
251 /* Validate profile */
252 switch (seq_hdr->profile) {
253 case GST_VC1_PROFILE_SIMPLE:
254 case GST_VC1_PROFILE_MAIN:
255 case GST_VC1_PROFILE_ADVANCED:
258 GST_DEBUG("unsupported profile %d", seq_hdr->profile);
259 return GST_VAAPI_DECODER_STATUS_ERROR_UNSUPPORTED_PROFILE;
266 switch (seq_hdr->profile) {
267 case GST_VC1_PROFILE_SIMPLE:
268 case GST_VC1_PROFILE_MAIN:
270 fps_n = structc->framerate;
274 case GST_VC1_PROFILE_ADVANCED:
275 fps_n = adv_hdr->fps_n;
276 fps_d = adv_hdr->fps_d;
277 par_n = adv_hdr->par_n;
278 par_d = adv_hdr->par_d;
281 g_assert(0 && "XXX: we already validated the profile above");
286 gst_vaapi_decoder_set_framerate(base_decoder, fps_n, fps_d);
288 if (par_n > 0 && par_d > 0)
289 gst_vaapi_decoder_set_pixel_aspect_ratio(base_decoder, par_n, par_d);
291 switch (seq_hdr->profile) {
292 case GST_VC1_PROFILE_SIMPLE:
293 case GST_VC1_PROFILE_MAIN:
294 width = seq_hdr->struct_c.coded_width;
295 height = seq_hdr->struct_c.coded_height;
297 case GST_VC1_PROFILE_ADVANCED:
298 width = seq_hdr->advanced.max_coded_width;
299 height = seq_hdr->advanced.max_coded_height;
302 g_assert(0 && "XXX: we already validated the profile above");
306 if (priv->width != width) {
308 priv->size_changed = TRUE;
311 if (priv->height != height) {
312 priv->height = height;
313 priv->size_changed = TRUE;
316 switch (seq_hdr->profile) {
317 case GST_VC1_PROFILE_SIMPLE:
318 profile = GST_VAAPI_PROFILE_VC1_SIMPLE;
320 case GST_VC1_PROFILE_MAIN:
321 profile = GST_VAAPI_PROFILE_VC1_MAIN;
323 case GST_VC1_PROFILE_ADVANCED:
324 profile = GST_VAAPI_PROFILE_VC1_ADVANCED;
327 g_assert(0 && "XXX: we already validated the profile above");
330 if (priv->profile != profile) {
331 priv->profile = profile;
332 priv->profile_changed = TRUE;
334 return GST_VAAPI_DECODER_STATUS_SUCCESS;
337 static GstVaapiDecoderStatus
338 decode_sequence_end(GstVaapiDecoderVC1 *decoder)
340 GstVaapiDecoderVC1Private * const priv = decoder->priv;
341 GstVaapiDecoderStatus status;
343 status = decode_current_picture(decoder);
344 if (status != GST_VAAPI_DECODER_STATUS_SUCCESS)
347 gst_vaapi_dpb_flush(priv->dpb);
348 return GST_VAAPI_DECODER_STATUS_SUCCESS;
351 static GstVaapiDecoderStatus
352 decode_entry_point(GstVaapiDecoderVC1 *decoder, GstVC1BDU *rbdu, GstVC1BDU *ebdu)
354 GstVaapiDecoderVC1Private * const priv = decoder->priv;
355 GstVC1SeqHdr * const seq_hdr = &priv->seq_hdr;
356 GstVC1EntryPointHdr * const entrypoint_hdr = &priv->entrypoint_hdr;
357 GstVC1ParserResult result;
359 result = gst_vc1_parse_entry_point_header(
360 rbdu->data + rbdu->offset,
365 if (result != GST_VC1_PARSER_OK) {
366 GST_DEBUG("failed to parse entrypoint layer");
367 return get_status(result);
370 if (entrypoint_hdr->coded_size_flag) {
371 priv->width = entrypoint_hdr->coded_width;
372 priv->height = entrypoint_hdr->coded_height;
373 priv->size_changed = TRUE;
376 priv->has_entrypoint = TRUE;
377 priv->closed_entry = entrypoint_hdr->closed_entry;
378 priv->broken_link = entrypoint_hdr->broken_link;
379 return GST_VAAPI_DECODER_STATUS_SUCCESS;
382 /* Reconstruct bitstream PTYPE (7.1.1.4, index into Table-35) */
384 get_PTYPE(guint ptype)
387 case GST_VC1_PICTURE_TYPE_I: return 0;
388 case GST_VC1_PICTURE_TYPE_P: return 1;
389 case GST_VC1_PICTURE_TYPE_B: return 2;
390 case GST_VC1_PICTURE_TYPE_BI: return 3;
392 return 4; /* skipped P-frame */
395 /* Reconstruct bitstream BFRACTION (7.1.1.14, index into Table-40) */
397 get_BFRACTION(guint bfraction)
401 static const struct {
406 { 0, GST_VC1_BFRACTION_BASIS / 2 },
407 { 1, GST_VC1_BFRACTION_BASIS / 3 },
408 { 2, (GST_VC1_BFRACTION_BASIS * 2) / 3 },
409 { 3, GST_VC1_BFRACTION_BASIS / 4 },
410 { 4, (GST_VC1_BFRACTION_BASIS * 3) / 4 },
411 { 5, GST_VC1_BFRACTION_BASIS / 5 },
412 { 6, (GST_VC1_BFRACTION_BASIS * 2) / 5 },
413 { 7, (GST_VC1_BFRACTION_BASIS * 3) / 5 },
414 { 8, (GST_VC1_BFRACTION_BASIS * 4) / 5 },
415 { 9, GST_VC1_BFRACTION_BASIS / 6 },
416 { 10, (GST_VC1_BFRACTION_BASIS * 5) / 6 },
417 { 11, GST_VC1_BFRACTION_BASIS / 7 },
418 { 12, (GST_VC1_BFRACTION_BASIS * 2) / 7 },
419 { 13, (GST_VC1_BFRACTION_BASIS * 3) / 7 },
420 { 14, (GST_VC1_BFRACTION_BASIS * 4) / 7 },
421 { 15, (GST_VC1_BFRACTION_BASIS * 5) / 7 },
422 { 16, (GST_VC1_BFRACTION_BASIS * 6) / 7 },
423 { 17, GST_VC1_BFRACTION_BASIS / 8 },
424 { 18, (GST_VC1_BFRACTION_BASIS * 3) / 8 },
425 { 19, (GST_VC1_BFRACTION_BASIS * 5) / 8 },
426 { 20, (GST_VC1_BFRACTION_BASIS * 7) / 8 },
427 { 21, GST_VC1_BFRACTION_RESERVED },
428 { 22, GST_VC1_BFRACTION_PTYPE_BI }
434 for (i = 0; i < G_N_ELEMENTS(bfraction_map); i++) {
435 if (bfraction_map[i].value == bfraction)
436 return bfraction_map[i].index;
438 return 21; /* RESERVED */
441 /* Translate GStreamer MV modes to VA-API */
443 get_VAMvModeVC1(guint mvmode)
446 case GST_VC1_MVMODE_1MV_HPEL_BILINEAR: return VAMvMode1MvHalfPelBilinear;
447 case GST_VC1_MVMODE_1MV: return VAMvMode1Mv;
448 case GST_VC1_MVMODE_1MV_HPEL: return VAMvMode1MvHalfPel;
449 case GST_VC1_MVMODE_MIXED_MV: return VAMvModeMixedMv;
450 case GST_VC1_MVMODE_INTENSITY_COMP: return VAMvModeIntensityCompensation;
455 /* Reconstruct bitstream MVMODE (7.1.1.32) */
457 get_MVMODE(GstVC1FrameHdr *frame_hdr)
461 if (frame_hdr->profile == GST_VC1_PROFILE_ADVANCED)
462 mvmode = frame_hdr->pic.advanced.mvmode;
464 mvmode = frame_hdr->pic.simple.mvmode;
466 if (frame_hdr->ptype == GST_VC1_PICTURE_TYPE_P ||
467 frame_hdr->ptype == GST_VC1_PICTURE_TYPE_B)
468 return get_VAMvModeVC1(mvmode);
472 /* Reconstruct bitstream MVMODE2 (7.1.1.33) */
474 get_MVMODE2(GstVC1FrameHdr *frame_hdr)
476 guint mvmode, mvmode2;
478 if (frame_hdr->profile == GST_VC1_PROFILE_ADVANCED) {
479 mvmode = frame_hdr->pic.advanced.mvmode;
480 mvmode2 = frame_hdr->pic.advanced.mvmode2;
483 mvmode = frame_hdr->pic.simple.mvmode;
484 mvmode2 = frame_hdr->pic.simple.mvmode2;
487 if (frame_hdr->ptype == GST_VC1_PICTURE_TYPE_P &&
488 mvmode == GST_VC1_MVMODE_INTENSITY_COMP)
489 return get_VAMvModeVC1(mvmode2);
494 has_MVTYPEMB_bitplane(GstVaapiDecoderVC1 *decoder)
496 GstVaapiDecoderVC1Private * const priv = decoder->priv;
497 GstVC1SeqHdr * const seq_hdr = &priv->seq_hdr;
498 GstVC1FrameHdr * const frame_hdr = &priv->frame_hdr;
499 guint mvmode, mvmode2;
501 if (seq_hdr->profile == GST_VC1_PROFILE_ADVANCED) {
502 GstVC1PicAdvanced * const pic = &frame_hdr->pic.advanced;
505 mvmode = pic->mvmode;
506 mvmode2 = pic->mvmode2;
509 GstVC1PicSimpleMain * const pic = &frame_hdr->pic.simple;
512 mvmode = pic->mvmode;
513 mvmode2 = pic->mvmode2;
515 return (frame_hdr->ptype == GST_VC1_PICTURE_TYPE_P &&
516 (mvmode == GST_VC1_MVMODE_MIXED_MV ||
517 (mvmode == GST_VC1_MVMODE_INTENSITY_COMP &&
518 mvmode2 == GST_VC1_MVMODE_MIXED_MV)));
522 has_SKIPMB_bitplane(GstVaapiDecoderVC1 *decoder)
524 GstVaapiDecoderVC1Private * const priv = decoder->priv;
525 GstVC1SeqHdr * const seq_hdr = &priv->seq_hdr;
526 GstVC1FrameHdr * const frame_hdr = &priv->frame_hdr;
528 if (seq_hdr->profile == GST_VC1_PROFILE_ADVANCED) {
529 GstVC1PicAdvanced * const pic = &frame_hdr->pic.advanced;
534 GstVC1PicSimpleMain * const pic = &frame_hdr->pic.simple;
538 return (frame_hdr->ptype == GST_VC1_PICTURE_TYPE_P ||
539 frame_hdr->ptype == GST_VC1_PICTURE_TYPE_B);
543 has_DIRECTMB_bitplane(GstVaapiDecoderVC1 *decoder)
545 GstVaapiDecoderVC1Private * const priv = decoder->priv;
546 GstVC1SeqHdr * const seq_hdr = &priv->seq_hdr;
547 GstVC1FrameHdr * const frame_hdr = &priv->frame_hdr;
549 if (seq_hdr->profile == GST_VC1_PROFILE_ADVANCED) {
550 GstVC1PicAdvanced * const pic = &frame_hdr->pic.advanced;
555 GstVC1PicSimpleMain * const pic = &frame_hdr->pic.simple;
559 return frame_hdr->ptype == GST_VC1_PICTURE_TYPE_B;
563 has_ACPRED_bitplane(GstVaapiDecoderVC1 *decoder)
565 GstVaapiDecoderVC1Private * const priv = decoder->priv;
566 GstVC1SeqHdr * const seq_hdr = &priv->seq_hdr;
567 GstVC1FrameHdr * const frame_hdr = &priv->frame_hdr;
568 GstVC1PicAdvanced * const pic = &frame_hdr->pic.advanced;
570 if (seq_hdr->profile != GST_VC1_PROFILE_ADVANCED)
574 return (frame_hdr->ptype == GST_VC1_PICTURE_TYPE_I ||
575 frame_hdr->ptype == GST_VC1_PICTURE_TYPE_BI);
579 has_OVERFLAGS_bitplane(GstVaapiDecoderVC1 *decoder)
581 GstVaapiDecoderVC1Private * const priv = decoder->priv;
582 GstVC1SeqHdr * const seq_hdr = &priv->seq_hdr;
583 GstVC1EntryPointHdr * const entrypoint_hdr = &priv->entrypoint_hdr;
584 GstVC1FrameHdr * const frame_hdr = &priv->frame_hdr;
585 GstVC1PicAdvanced * const pic = &frame_hdr->pic.advanced;
587 if (seq_hdr->profile != GST_VC1_PROFILE_ADVANCED)
591 return ((frame_hdr->ptype == GST_VC1_PICTURE_TYPE_I ||
592 frame_hdr->ptype == GST_VC1_PICTURE_TYPE_BI) &&
593 (entrypoint_hdr->overlap && frame_hdr->pquant <= 8) &&
594 pic->condover == GST_VC1_CONDOVER_SELECT);
598 pack_bitplanes(GstVaapiBitPlane *bitplane, guint n, const guint8 *bitplanes[3], guint x, guint y, guint stride)
600 const guint dst_index = n / 2;
601 const guint src_index = y * stride + x;
605 v |= bitplanes[0][src_index];
607 v |= bitplanes[1][src_index] << 1;
609 v |= bitplanes[2][src_index] << 2;
610 bitplane->data[dst_index] = (bitplane->data[dst_index] << 4) | v;
614 fill_picture_structc(GstVaapiDecoderVC1 *decoder, GstVaapiPicture *picture)
616 GstVaapiDecoderVC1Private * const priv = decoder->priv;
617 VAPictureParameterBufferVC1 * const pic_param = picture->param;
618 GstVC1SeqStructC * const structc = &priv->seq_hdr.struct_c;
619 GstVC1FrameHdr * const frame_hdr = &priv->frame_hdr;
620 GstVC1PicSimpleMain * const pic = &frame_hdr->pic.simple;
622 /* Fill in VAPictureParameterBufferVC1 (simple/main profile bits) */
623 pic_param->sequence_fields.bits.finterpflag = structc->finterpflag;
624 pic_param->sequence_fields.bits.multires = structc->multires;
625 pic_param->sequence_fields.bits.overlap = structc->overlap;
626 pic_param->sequence_fields.bits.syncmarker = structc->syncmarker;
627 pic_param->sequence_fields.bits.rangered = structc->rangered;
628 pic_param->sequence_fields.bits.max_b_frames = structc->maxbframes;
629 pic_param->conditional_overlap_flag = 0; /* advanced profile only */
630 pic_param->fast_uvmc_flag = structc->fastuvmc;
631 pic_param->b_picture_fraction = get_BFRACTION(pic->bfraction);
632 pic_param->cbp_table = pic->cbptab;
633 pic_param->mb_mode_table = 0; /* XXX: interlaced frame */
634 pic_param->range_reduction_frame = pic->rangeredfrm;
635 pic_param->rounding_control = 0; /* advanced profile only */
636 pic_param->post_processing = 0; /* advanced profile only */
637 pic_param->picture_resolution_index = pic->respic;
638 pic_param->luma_scale = pic->lumscale;
639 pic_param->luma_shift = pic->lumshift;
640 pic_param->raw_coding.flags.mv_type_mb = pic->mvtypemb;
641 pic_param->raw_coding.flags.direct_mb = pic->directmb;
642 pic_param->raw_coding.flags.skip_mb = pic->skipmb;
643 pic_param->bitplane_present.flags.bp_mv_type_mb = has_MVTYPEMB_bitplane(decoder);
644 pic_param->bitplane_present.flags.bp_direct_mb = has_DIRECTMB_bitplane(decoder);
645 pic_param->bitplane_present.flags.bp_skip_mb = has_SKIPMB_bitplane(decoder);
646 pic_param->mv_fields.bits.mv_table = pic->mvtab;
647 pic_param->mv_fields.bits.extended_mv_flag = structc->extended_mv;
648 pic_param->mv_fields.bits.extended_mv_range = pic->mvrange;
649 pic_param->transform_fields.bits.variable_sized_transform_flag = structc->vstransform;
650 pic_param->transform_fields.bits.mb_level_transform_type_flag = pic->ttmbf;
651 pic_param->transform_fields.bits.frame_level_transform_type = pic->ttfrm;
652 pic_param->transform_fields.bits.transform_ac_codingset_idx2 = pic->transacfrm2;
657 fill_picture_advanced(GstVaapiDecoderVC1 *decoder, GstVaapiPicture *picture)
659 GstVaapiDecoderVC1Private * const priv = decoder->priv;
660 VAPictureParameterBufferVC1 * const pic_param = picture->param;
661 GstVC1AdvancedSeqHdr * const adv_hdr = &priv->seq_hdr.advanced;
662 GstVC1EntryPointHdr * const entrypoint_hdr = &priv->entrypoint_hdr;
663 GstVC1FrameHdr * const frame_hdr = &priv->frame_hdr;
664 GstVC1PicAdvanced * const pic = &frame_hdr->pic.advanced;
666 if (!priv->has_entrypoint)
669 /* Fill in VAPictureParameterBufferVC1 (advanced profile bits) */
670 pic_param->sequence_fields.bits.pulldown = adv_hdr->pulldown;
671 pic_param->sequence_fields.bits.interlace = adv_hdr->interlace;
672 pic_param->sequence_fields.bits.tfcntrflag = adv_hdr->tfcntrflag;
673 pic_param->sequence_fields.bits.finterpflag = adv_hdr->finterpflag;
674 pic_param->sequence_fields.bits.psf = adv_hdr->psf;
675 pic_param->sequence_fields.bits.overlap = entrypoint_hdr->overlap;
676 pic_param->entrypoint_fields.bits.broken_link = entrypoint_hdr->broken_link;
677 pic_param->entrypoint_fields.bits.closed_entry = entrypoint_hdr->closed_entry;
678 pic_param->entrypoint_fields.bits.panscan_flag = entrypoint_hdr->panscan_flag;
679 pic_param->entrypoint_fields.bits.loopfilter = entrypoint_hdr->loopfilter;
680 pic_param->conditional_overlap_flag = pic->condover;
681 pic_param->fast_uvmc_flag = entrypoint_hdr->fastuvmc;
682 pic_param->range_mapping_fields.bits.luma_flag = entrypoint_hdr->range_mapy_flag;
683 pic_param->range_mapping_fields.bits.luma = entrypoint_hdr->range_mapy;
684 pic_param->range_mapping_fields.bits.chroma_flag = entrypoint_hdr->range_mapuv_flag;
685 pic_param->range_mapping_fields.bits.chroma = entrypoint_hdr->range_mapuv;
686 pic_param->b_picture_fraction = get_BFRACTION(pic->bfraction);
687 pic_param->cbp_table = pic->cbptab;
688 pic_param->mb_mode_table = 0; /* XXX: interlaced frame */
689 pic_param->range_reduction_frame = 0; /* simple/main profile only */
690 pic_param->rounding_control = pic->rndctrl;
691 pic_param->post_processing = pic->postproc;
692 pic_param->picture_resolution_index = 0; /* simple/main profile only */
693 pic_param->luma_scale = pic->lumscale;
694 pic_param->luma_shift = pic->lumshift;
695 pic_param->picture_fields.bits.frame_coding_mode = pic->fcm;
696 pic_param->picture_fields.bits.top_field_first = pic->tff;
697 pic_param->picture_fields.bits.is_first_field = pic->fcm == 0; /* XXX: interlaced frame */
698 pic_param->picture_fields.bits.intensity_compensation = pic->mvmode == GST_VC1_MVMODE_INTENSITY_COMP;
699 pic_param->raw_coding.flags.mv_type_mb = pic->mvtypemb;
700 pic_param->raw_coding.flags.direct_mb = pic->directmb;
701 pic_param->raw_coding.flags.skip_mb = pic->skipmb;
702 pic_param->raw_coding.flags.ac_pred = pic->acpred;
703 pic_param->raw_coding.flags.overflags = pic->overflags;
704 pic_param->bitplane_present.flags.bp_mv_type_mb = has_MVTYPEMB_bitplane(decoder);
705 pic_param->bitplane_present.flags.bp_direct_mb = has_DIRECTMB_bitplane(decoder);
706 pic_param->bitplane_present.flags.bp_skip_mb = has_SKIPMB_bitplane(decoder);
707 pic_param->bitplane_present.flags.bp_ac_pred = has_ACPRED_bitplane(decoder);
708 pic_param->bitplane_present.flags.bp_overflags = has_OVERFLAGS_bitplane(decoder);
709 pic_param->reference_fields.bits.reference_distance_flag = entrypoint_hdr->refdist_flag;
710 pic_param->mv_fields.bits.mv_table = pic->mvtab;
711 pic_param->mv_fields.bits.extended_mv_flag = entrypoint_hdr->extended_mv;
712 pic_param->mv_fields.bits.extended_mv_range = pic->mvrange;
713 pic_param->mv_fields.bits.extended_dmv_flag = entrypoint_hdr->extended_dmv;
714 pic_param->pic_quantizer_fields.bits.dquant = entrypoint_hdr->dquant;
715 pic_param->pic_quantizer_fields.bits.quantizer = entrypoint_hdr->quantizer;
716 pic_param->transform_fields.bits.variable_sized_transform_flag = entrypoint_hdr->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 = pic->transacfrm2;
724 fill_picture(GstVaapiDecoderVC1 *decoder, GstVaapiPicture *picture)
726 GstVaapiDecoderVC1Private * const priv = decoder->priv;
727 VAPictureParameterBufferVC1 * const pic_param = picture->param;
728 GstVC1SeqHdr * const seq_hdr = &priv->seq_hdr;
729 GstVC1FrameHdr * const frame_hdr = &priv->frame_hdr;
730 GstVaapiPicture *prev_picture, *next_picture;
732 /* Fill in VAPictureParameterBufferVC1 (common fields) */
733 pic_param->forward_reference_picture = VA_INVALID_ID;
734 pic_param->backward_reference_picture = VA_INVALID_ID;
735 pic_param->inloop_decoded_picture = VA_INVALID_ID;
736 pic_param->sequence_fields.value = 0;
737 #if VA_CHECK_VERSION(0,32,0)
738 pic_param->sequence_fields.bits.profile = seq_hdr->profile;
740 pic_param->coded_width = priv->width;
741 pic_param->coded_height = priv->height;
742 pic_param->entrypoint_fields.value = 0;
743 pic_param->range_mapping_fields.value = 0;
744 pic_param->picture_fields.value = 0;
745 pic_param->picture_fields.bits.picture_type = get_PTYPE(frame_hdr->ptype);
746 pic_param->raw_coding.value = 0;
747 pic_param->bitplane_present.value = 0;
748 pic_param->reference_fields.value = 0;
749 pic_param->mv_fields.value = 0;
750 pic_param->mv_fields.bits.mv_mode = get_MVMODE(frame_hdr);
751 pic_param->mv_fields.bits.mv_mode2 = get_MVMODE2(frame_hdr);
752 pic_param->pic_quantizer_fields.value = 0;
753 pic_param->pic_quantizer_fields.bits.half_qp = frame_hdr->halfqp;
754 pic_param->pic_quantizer_fields.bits.pic_quantizer_scale = frame_hdr->pquant;
755 pic_param->pic_quantizer_fields.bits.pic_quantizer_type = frame_hdr->pquantizer;
756 pic_param->pic_quantizer_fields.bits.dq_frame = frame_hdr->vopdquant.dquantfrm;
757 pic_param->pic_quantizer_fields.bits.dq_profile = frame_hdr->vopdquant.dqprofile;
758 pic_param->pic_quantizer_fields.bits.dq_sb_edge = frame_hdr->vopdquant.dqsbedge;
759 pic_param->pic_quantizer_fields.bits.dq_db_edge = frame_hdr->vopdquant.dqsbedge;
760 pic_param->pic_quantizer_fields.bits.dq_binary_level = frame_hdr->vopdquant.dqbilevel;
761 pic_param->pic_quantizer_fields.bits.alt_pic_quantizer = frame_hdr->vopdquant.altpquant;
762 pic_param->transform_fields.value = 0;
763 pic_param->transform_fields.bits.transform_ac_codingset_idx1 = frame_hdr->transacfrm;
764 pic_param->transform_fields.bits.intra_transform_dc_table = frame_hdr->transdctab;
766 if (seq_hdr->profile == GST_VC1_PROFILE_ADVANCED) {
767 if (!fill_picture_advanced(decoder, picture))
771 if (!fill_picture_structc(decoder, picture))
775 gst_vaapi_dpb_get_neighbours(priv->dpb, picture,
776 &prev_picture, &next_picture);
778 switch (picture->type) {
779 case GST_VAAPI_PICTURE_TYPE_B:
781 pic_param->backward_reference_picture = next_picture->surface_id;
783 case GST_VAAPI_PICTURE_TYPE_P:
785 pic_param->forward_reference_picture = prev_picture->surface_id;
791 if (pic_param->bitplane_present.value) {
792 const guint8 *bitplanes[3];
795 switch (picture->type) {
796 case GST_VAAPI_PICTURE_TYPE_P:
797 bitplanes[0] = pic_param->bitplane_present.flags.bp_direct_mb ? priv->bitplanes->directmb : NULL;
798 bitplanes[1] = pic_param->bitplane_present.flags.bp_skip_mb ? priv->bitplanes->skipmb : NULL;
799 bitplanes[2] = pic_param->bitplane_present.flags.bp_mv_type_mb ? priv->bitplanes->mvtypemb : NULL;
801 case GST_VAAPI_PICTURE_TYPE_B:
802 bitplanes[0] = pic_param->bitplane_present.flags.bp_direct_mb ? priv->bitplanes->directmb : NULL;
803 bitplanes[1] = pic_param->bitplane_present.flags.bp_skip_mb ? priv->bitplanes->skipmb : NULL;
804 bitplanes[2] = NULL; /* XXX: interlaced frame (FORWARD plane) */
806 case GST_VAAPI_PICTURE_TYPE_BI:
807 case GST_VAAPI_PICTURE_TYPE_I:
808 bitplanes[0] = NULL; /* XXX: interlaced frame (FIELDTX plane) */
809 bitplanes[1] = pic_param->bitplane_present.flags.bp_ac_pred ? priv->bitplanes->acpred : NULL;
810 bitplanes[2] = pic_param->bitplane_present.flags.bp_overflags ? priv->bitplanes->overflags : NULL;
819 picture->bitplane = GST_VAAPI_BITPLANE_NEW(
821 (seq_hdr->mb_width * seq_hdr->mb_height + 1) / 2
823 if (!picture->bitplane)
827 for (y = 0; y < seq_hdr->mb_height; y++)
828 for (x = 0; x < seq_hdr->mb_width; x++, n++)
829 pack_bitplanes(picture->bitplane, n, bitplanes, x, y, seq_hdr->mb_stride);
830 if (n & 1) /* move last nibble to the high order */
831 picture->bitplane->data[n/2] <<= 4;
836 static GstVaapiDecoderStatus
837 decode_frame(GstVaapiDecoderVC1 *decoder, GstVC1BDU *rbdu, GstVC1BDU *ebdu)
839 GstVaapiDecoderVC1Private * const priv = decoder->priv;
840 GstVC1SeqHdr * const seq_hdr = &priv->seq_hdr;
841 GstVC1FrameHdr * const frame_hdr = &priv->frame_hdr;
842 GstVC1ParserResult result;
843 GstVaapiPicture *picture;
844 GstVaapiSlice *slice;
845 GstVaapiDecoderStatus status;
846 VASliceParameterBufferVC1 *slice_param;
848 status = ensure_context(decoder);
849 if (status != GST_VAAPI_DECODER_STATUS_SUCCESS) {
850 GST_DEBUG("failed to reset context");
854 if (priv->current_picture) {
855 status = decode_current_picture(decoder);
856 if (status != GST_VAAPI_DECODER_STATUS_SUCCESS)
860 picture = GST_VAAPI_PICTURE_NEW(VC1, decoder);
862 GST_DEBUG("failed to allocate picture");
863 return GST_VAAPI_DECODER_STATUS_ERROR_ALLOCATION_FAILED;
865 gst_vaapi_picture_replace(&priv->current_picture, picture);
866 gst_vaapi_picture_unref(picture);
868 if (!gst_vc1_bitplanes_ensure_size(priv->bitplanes, seq_hdr)) {
869 GST_DEBUG("failed to allocate bitplanes");
870 return GST_VAAPI_DECODER_STATUS_ERROR_ALLOCATION_FAILED;
873 memset(frame_hdr, 0, sizeof(*frame_hdr));
874 result = gst_vc1_parse_frame_header(
875 rbdu->data + rbdu->offset,
881 if (result != GST_VC1_PARSER_OK) {
882 GST_DEBUG("failed to parse frame layer");
883 return get_status(result);
886 switch (frame_hdr->ptype) {
887 case GST_VC1_PICTURE_TYPE_I:
888 picture->type = GST_VAAPI_PICTURE_TYPE_I;
889 GST_VAAPI_PICTURE_FLAG_SET(picture, GST_VAAPI_PICTURE_FLAG_REFERENCE);
891 case GST_VC1_PICTURE_TYPE_SKIPPED:
892 case GST_VC1_PICTURE_TYPE_P:
893 picture->type = GST_VAAPI_PICTURE_TYPE_P;
894 GST_VAAPI_PICTURE_FLAG_SET(picture, GST_VAAPI_PICTURE_FLAG_REFERENCE);
896 case GST_VC1_PICTURE_TYPE_B:
897 picture->type = GST_VAAPI_PICTURE_TYPE_B;
899 case GST_VC1_PICTURE_TYPE_BI:
900 picture->type = GST_VAAPI_PICTURE_TYPE_BI;
903 GST_DEBUG("unsupported picture type %d", frame_hdr->ptype);
904 return GST_VAAPI_DECODER_STATUS_ERROR_UNKNOWN;
907 /* Update presentation time */
908 if (GST_VAAPI_PICTURE_IS_REFERENCE(picture)) {
909 picture->poc = priv->last_non_b_picture ?
910 (priv->last_non_b_picture->poc + 1) : priv->next_poc;
911 priv->next_poc = picture->poc + 1;
912 gst_vaapi_picture_replace(&priv->last_non_b_picture, picture);
914 else if (!priv->last_non_b_picture)
915 picture->poc = priv->next_poc++;
917 picture->poc = priv->last_non_b_picture->poc++;
918 priv->next_poc = priv->last_non_b_picture->poc + 1;
920 picture->pts = GST_VAAPI_DECODER_CODEC_FRAME(decoder)->pts;
922 if (!fill_picture(decoder, picture))
923 return GST_VAAPI_DECODER_STATUS_ERROR_UNKNOWN;
925 slice = GST_VAAPI_SLICE_NEW(
928 ebdu->data + ebdu->sc_offset,
929 ebdu->size + ebdu->offset - ebdu->sc_offset
932 GST_DEBUG("failed to allocate slice");
933 return GST_VAAPI_DECODER_STATUS_ERROR_ALLOCATION_FAILED;
935 gst_vaapi_picture_add_slice(picture, slice);
937 /* Fill in VASliceParameterBufferVC1 */
938 slice_param = slice->param;
939 slice_param->macroblock_offset = 8 * (ebdu->offset - ebdu->sc_offset) + frame_hdr->header_size;
940 slice_param->slice_vertical_position = 0;
942 return GST_VAAPI_DECODER_STATUS_SUCCESS;
946 decode_rbdu(GstVaapiDecoderVC1 *decoder, GstVC1BDU *rbdu, GstVC1BDU *ebdu)
948 GstVaapiDecoderVC1Private * const priv = decoder->priv;
950 guint i, j, rbdu_buffer_size;
952 /* BDU are encapsulated in advanced profile mode only */
953 if (priv->profile != GST_VAAPI_PROFILE_VC1_ADVANCED) {
954 memcpy(rbdu, ebdu, sizeof(*rbdu));
958 /* Reallocate unescaped bitstream buffer */
959 rbdu_buffer = priv->rbdu_buffer;
960 if (!rbdu_buffer || ebdu->size > priv->rbdu_buffer_size) {
961 rbdu_buffer = g_realloc(priv->rbdu_buffer, ebdu->size);
964 priv->rbdu_buffer = rbdu_buffer;
965 priv->rbdu_buffer_size = ebdu->size;
968 /* Unescape bitstream buffer */
969 if (ebdu->size < 4) {
970 memcpy(rbdu_buffer, ebdu->data + ebdu->offset, ebdu->size);
971 rbdu_buffer_size = ebdu->size;
974 guint8 * const bdu_buffer = ebdu->data + ebdu->offset;
975 for (i = 0, j = 0; i < ebdu->size; i++) {
976 if (i >= 2 && i < ebdu->size - 1 &&
977 bdu_buffer[i - 1] == 0x00 &&
978 bdu_buffer[i - 2] == 0x00 &&
979 bdu_buffer[i ] == 0x03 &&
980 bdu_buffer[i + 1] <= 0x03)
982 rbdu_buffer[j++] = bdu_buffer[i];
984 rbdu_buffer_size = j;
987 /* Reconstruct RBDU */
988 rbdu->type = ebdu->type;
989 rbdu->size = rbdu_buffer_size;
992 rbdu->data = rbdu_buffer;
996 static GstVaapiDecoderStatus
997 decode_ebdu(GstVaapiDecoderVC1 *decoder, GstVC1BDU *ebdu)
999 GstVaapiDecoderStatus status;
1002 if (!decode_rbdu(decoder, &rbdu, ebdu))
1003 return GST_VAAPI_DECODER_STATUS_ERROR_ALLOCATION_FAILED;
1005 switch (ebdu->type) {
1006 case GST_VC1_SEQUENCE:
1007 status = decode_sequence(decoder, &rbdu, ebdu);
1009 case GST_VC1_ENTRYPOINT:
1010 status = decode_entry_point(decoder, &rbdu, ebdu);
1013 status = decode_frame(decoder, &rbdu, ebdu);
1016 GST_DEBUG("decode slice");
1017 status = GST_VAAPI_DECODER_STATUS_ERROR_BITSTREAM_PARSER;
1019 case GST_VC1_END_OF_SEQ:
1020 status = decode_sequence_end(decoder);
1023 GST_DEBUG("unsupported BDU type %d", ebdu->type);
1024 status = GST_VAAPI_DECODER_STATUS_ERROR_BITSTREAM_PARSER;
1030 static GstVaapiDecoderStatus
1031 decode_buffer(GstVaapiDecoderVC1 *decoder, GstBuffer *buffer)
1033 GstVaapiDecoderVC1Private * const priv = decoder->priv;
1038 buf = GST_BUFFER_DATA(buffer);
1039 buf_size = GST_BUFFER_SIZE(buffer);
1041 if (priv->has_codec_data) {
1042 ebdu.type = GST_VC1_FRAME;
1052 ebdu.size = buf_size;
1053 return decode_ebdu(decoder, &ebdu);
1056 static GstVaapiDecoderStatus
1057 decode_codec_data(GstVaapiDecoderVC1 *decoder, GstBuffer *buffer)
1059 GstVaapiDecoderVC1Private * const priv = decoder->priv;
1060 GstVC1SeqHdr * const seq_hdr = &priv->seq_hdr;
1061 GstVaapiDecoderStatus status;
1062 GstVC1ParserResult result;
1065 GstStructure *structure;
1067 guint buf_size, ofs;
1071 buf = GST_BUFFER_DATA(buffer);
1072 buf_size = GST_BUFFER_SIZE(buffer);
1073 if (!buf || buf_size == 0)
1074 return GST_VAAPI_DECODER_STATUS_SUCCESS;
1076 width = GST_VAAPI_DECODER_WIDTH(decoder);
1077 height = GST_VAAPI_DECODER_HEIGHT(decoder);
1078 if (!width || !height) {
1079 GST_DEBUG("failed to parse size from codec-data");
1080 return GST_VAAPI_DECODER_STATUS_ERROR_UNKNOWN;
1083 caps = GST_VAAPI_DECODER_CODEC_STATE(decoder)->caps;
1084 structure = gst_caps_get_structure(caps, 0);
1085 if (!gst_structure_get_fourcc(structure, "format", &format)) {
1086 GST_DEBUG("failed to parse profile from codec-data");
1087 return GST_VAAPI_DECODER_STATUS_ERROR_UNSUPPORTED_CODEC;
1090 /* WMV3 -- expecting sequence header */
1091 if (format == GST_MAKE_FOURCC('W','M','V','3')) {
1092 seq_hdr->struct_c.coded_width = width;
1093 seq_hdr->struct_c.coded_height = height;
1094 ebdu.type = GST_VC1_SEQUENCE;
1095 ebdu.size = buf_size;
1099 return decode_ebdu(decoder, &ebdu);
1102 /* WVC1 -- expecting bitstream data units */
1103 if (format != GST_MAKE_FOURCC('W','V','C','1'))
1104 return GST_VAAPI_DECODER_STATUS_ERROR_UNSUPPORTED_PROFILE;
1105 seq_hdr->advanced.max_coded_width = width;
1106 seq_hdr->advanced.max_coded_height = height;
1110 result = gst_vc1_identify_next_bdu(
1117 case GST_VC1_PARSER_NO_BDU_END:
1118 /* Assume the EBDU is complete within codec-data bounds */
1119 ebdu.size = buf_size - ofs - (ebdu.offset - ebdu.sc_offset);
1121 case GST_VC1_PARSER_OK:
1122 status = decode_ebdu(decoder, &ebdu);
1123 ofs += ebdu.offset + ebdu.size;
1126 status = get_status(result);
1129 } while (status == GST_VAAPI_DECODER_STATUS_SUCCESS && ofs < buf_size);
1133 static GstVaapiDecoderStatus
1134 ensure_decoder(GstVaapiDecoderVC1 *decoder)
1136 GstVaapiDecoderVC1Private * const priv = decoder->priv;
1137 GstVaapiDecoderStatus status;
1138 GstBuffer *codec_data;
1140 g_return_val_if_fail(priv->is_constructed,
1141 GST_VAAPI_DECODER_STATUS_ERROR_INIT_FAILED);
1143 if (!priv->is_opened) {
1144 priv->is_opened = gst_vaapi_decoder_vc1_open(decoder);
1145 if (!priv->is_opened)
1146 return GST_VAAPI_DECODER_STATUS_ERROR_UNSUPPORTED_CODEC;
1148 codec_data = GST_VAAPI_DECODER_CODEC_DATA(decoder);
1150 status = decode_codec_data(decoder, codec_data);
1151 if (status != GST_VAAPI_DECODER_STATUS_SUCCESS)
1153 priv->has_codec_data = TRUE;
1156 return GST_VAAPI_DECODER_STATUS_SUCCESS;
1160 scan_for_start_code(GstAdapter *adapter, guint ofs, guint size, guint32 *scp)
1162 return (gint)gst_adapter_masked_scan_uint32_peek(adapter,
1163 0xffffff00, 0x00000100, ofs, size, scp);
1166 static GstVaapiDecoderStatus
1167 gst_vaapi_decoder_vc1_parse(GstVaapiDecoder *base_decoder,
1168 GstAdapter *adapter, gboolean at_eos, GstVaapiDecoderUnit *unit)
1170 GstVaapiDecoderVC1 * const decoder = GST_VAAPI_DECODER_VC1(base_decoder);
1171 GstVaapiDecoderVC1Private * const priv = decoder->priv;
1172 GstVaapiDecoderStatus status;
1174 guint size, buf_size, flags = 0;
1177 status = ensure_decoder(decoder);
1178 if (status != GST_VAAPI_DECODER_STATUS_SUCCESS)
1181 size = gst_adapter_available(adapter);
1183 if (priv->has_codec_data) {
1184 // Assume demuxer sends out plain frames
1186 return GST_VAAPI_DECODER_STATUS_ERROR_NO_DATA;
1188 bdu_type = GST_VC1_FRAME;
1192 return GST_VAAPI_DECODER_STATUS_ERROR_NO_DATA;
1194 ofs = scan_for_start_code(adapter, 0, size, NULL);
1196 return GST_VAAPI_DECODER_STATUS_ERROR_NO_DATA;
1197 gst_adapter_flush(adapter, ofs);
1200 ofs = G_UNLIKELY(size < 8) ? -1 :
1201 scan_for_start_code(adapter, 4, size - 4, NULL);
1203 // Assume the whole packet is present if end-of-stream
1205 return GST_VAAPI_DECODER_STATUS_ERROR_NO_DATA;
1209 gst_adapter_copy(adapter, &bdu_type, 3, 1);
1212 unit->size = buf_size;
1214 /* Check for new picture layer */
1216 case GST_VC1_END_OF_SEQ:
1217 flags |= GST_VAAPI_DECODER_UNIT_FLAG_FRAME_END;
1218 flags |= GST_VAAPI_DECODER_UNIT_FLAG_STREAM_END;
1220 case GST_VC1_SEQUENCE:
1221 case GST_VC1_ENTRYPOINT:
1222 flags |= GST_VAAPI_DECODER_UNIT_FLAG_FRAME_START;
1225 flags |= GST_VAAPI_DECODER_UNIT_FLAG_FRAME_START;
1226 flags |= GST_VAAPI_DECODER_UNIT_FLAG_SLICE;
1229 flags |= GST_VAAPI_DECODER_UNIT_FLAG_SLICE;
1232 GST_VAAPI_DECODER_UNIT_FLAG_SET(unit, flags);
1233 return GST_VAAPI_DECODER_STATUS_SUCCESS;
1236 static GstVaapiDecoderStatus
1237 gst_vaapi_decoder_vc1_decode(GstVaapiDecoder *base_decoder,
1238 GstVaapiDecoderUnit *unit)
1240 GstVaapiDecoderVC1 * const decoder = GST_VAAPI_DECODER_VC1(base_decoder);
1241 GstVaapiDecoderStatus status;
1243 status = ensure_decoder(decoder);
1244 if (status != GST_VAAPI_DECODER_STATUS_SUCCESS)
1247 unit->buffer = gst_buffer_create_sub(
1248 GST_VAAPI_DECODER_CODEC_FRAME(decoder)->input_buffer,
1249 unit->offset, unit->size);
1251 return GST_VAAPI_DECODER_STATUS_ERROR_ALLOCATION_FAILED;
1253 status = decode_buffer(decoder, unit->buffer);
1254 if (status != GST_VAAPI_DECODER_STATUS_SUCCESS)
1256 return GST_VAAPI_DECODER_STATUS_SUCCESS;
1260 gst_vaapi_decoder_vc1_finalize(GObject *object)
1262 GstVaapiDecoderVC1 * const decoder = GST_VAAPI_DECODER_VC1(object);
1264 gst_vaapi_decoder_vc1_destroy(decoder);
1266 G_OBJECT_CLASS(gst_vaapi_decoder_vc1_parent_class)->finalize(object);
1270 gst_vaapi_decoder_vc1_constructed(GObject *object)
1272 GstVaapiDecoderVC1 * const decoder = GST_VAAPI_DECODER_VC1(object);
1273 GstVaapiDecoderVC1Private * const priv = decoder->priv;
1274 GObjectClass *parent_class;
1276 parent_class = G_OBJECT_CLASS(gst_vaapi_decoder_vc1_parent_class);
1277 if (parent_class->constructed)
1278 parent_class->constructed(object);
1280 priv->is_constructed = gst_vaapi_decoder_vc1_create(decoder);
1284 gst_vaapi_decoder_vc1_class_init(GstVaapiDecoderVC1Class *klass)
1286 GObjectClass * const object_class = G_OBJECT_CLASS(klass);
1287 GstVaapiDecoderClass * const decoder_class = GST_VAAPI_DECODER_CLASS(klass);
1289 g_type_class_add_private(klass, sizeof(GstVaapiDecoderVC1Private));
1291 object_class->finalize = gst_vaapi_decoder_vc1_finalize;
1292 object_class->constructed = gst_vaapi_decoder_vc1_constructed;
1294 decoder_class->parse = gst_vaapi_decoder_vc1_parse;
1295 decoder_class->decode = gst_vaapi_decoder_vc1_decode;
1299 gst_vaapi_decoder_vc1_init(GstVaapiDecoderVC1 *decoder)
1301 GstVaapiDecoderVC1Private *priv;
1303 priv = GST_VAAPI_DECODER_VC1_GET_PRIVATE(decoder);
1304 decoder->priv = priv;
1307 priv->profile = (GstVaapiProfile)0;
1308 priv->current_picture = NULL;
1309 priv->rbdu_buffer = NULL;
1310 priv->rbdu_buffer_size = 0;
1311 priv->is_constructed = FALSE;
1312 priv->is_opened = FALSE;
1313 priv->is_first_field = FALSE;
1314 priv->has_entrypoint = FALSE;
1315 priv->size_changed = FALSE;
1316 priv->profile_changed = FALSE;
1317 priv->closed_entry = FALSE;
1318 priv->broken_link = FALSE;
1322 * gst_vaapi_decoder_vc1_new:
1323 * @display: a #GstVaapiDisplay
1324 * @caps: a #GstCaps holding codec information
1326 * Creates a new #GstVaapiDecoder for VC-1 decoding. The @caps can
1327 * hold extra information like codec-data and pictured coded size.
1329 * Return value: the newly allocated #GstVaapiDecoder object
1332 gst_vaapi_decoder_vc1_new(GstVaapiDisplay *display, GstCaps *caps)
1334 GstVaapiDecoderVC1 *decoder;
1336 g_return_val_if_fail(GST_VAAPI_IS_DISPLAY(display), NULL);
1337 g_return_val_if_fail(GST_IS_CAPS(caps), NULL);
1339 decoder = g_object_new(
1340 GST_VAAPI_TYPE_DECODER_VC1,
1345 if (!decoder->priv->is_constructed) {
1346 g_object_unref(decoder);
1349 return GST_VAAPI_DECODER_CAST(decoder);