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_priv.h"
33 #include "gstvaapidisplay_priv.h"
34 #include "gstvaapiobject_priv.h"
37 #include "gstvaapidebug.h"
39 G_DEFINE_TYPE(GstVaapiDecoderVC1,
40 gst_vaapi_decoder_vc1,
41 GST_VAAPI_TYPE_DECODER);
43 #define GST_VAAPI_DECODER_VC1_GET_PRIVATE(obj) \
44 (G_TYPE_INSTANCE_GET_PRIVATE((obj), \
45 GST_VAAPI_TYPE_DECODER_VC1, \
46 GstVaapiDecoderVC1Private))
48 struct _GstVaapiDecoderVC1Private {
49 GstVaapiProfile profile;
55 GstVC1EntryPointHdr entrypoint_hdr;
56 GstVC1FrameHdr frame_hdr;
57 GstVC1BitPlanes *bitplanes;
58 GstVaapiPicture *current_picture;
59 GstVaapiPicture *next_picture;
60 GstVaapiPicture *prev_picture;
62 GstBuffer *sub_buffer;
64 guint rbdu_buffer_size;
65 guint is_constructed : 1;
67 guint is_first_field : 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->current_picture, NULL);
103 gst_vaapi_picture_replace(&priv->next_picture, NULL);
104 gst_vaapi_picture_replace(&priv->prev_picture, NULL);
106 if (priv->sub_buffer) {
107 gst_buffer_unref(priv->sub_buffer);
108 priv->sub_buffer = NULL;
111 if (priv->bitplanes) {
112 gst_vc1_bitplanes_free(priv->bitplanes);
113 priv->bitplanes = NULL;
117 gst_adapter_clear(priv->adapter);
118 g_object_unref(priv->adapter);
119 priv->adapter = NULL;
124 gst_vaapi_decoder_vc1_open(GstVaapiDecoderVC1 *decoder, GstBuffer *buffer)
126 GstVaapiDecoderVC1Private * const priv = decoder->priv;
128 gst_vaapi_decoder_vc1_close(decoder);
130 priv->adapter = gst_adapter_new();
134 priv->bitplanes = gst_vc1_bitplanes_new();
135 if (!priv->bitplanes)
141 gst_vaapi_decoder_vc1_destroy(GstVaapiDecoderVC1 *decoder)
143 GstVaapiDecoderVC1Private * const priv = decoder->priv;
145 gst_vaapi_decoder_vc1_close(decoder);
147 if (priv->rbdu_buffer) {
148 g_free(priv->rbdu_buffer);
149 priv->rbdu_buffer = NULL;
150 priv->rbdu_buffer_size = 0;
155 gst_vaapi_decoder_vc1_create(GstVaapiDecoderVC1 *decoder)
157 if (!GST_VAAPI_DECODER_CODEC(decoder))
162 static GstVaapiDecoderStatus
163 ensure_context(GstVaapiDecoderVC1 *decoder)
165 GstVaapiDecoderVC1Private * const priv = decoder->priv;
166 GstVaapiProfile profiles[2];
167 GstVaapiEntrypoint entrypoint = GST_VAAPI_ENTRYPOINT_VLD;
168 guint i, n_profiles = 0;
169 gboolean reset_context = FALSE;
171 if (priv->profile_changed) {
172 GST_DEBUG("profile changed");
173 priv->profile_changed = FALSE;
174 reset_context = TRUE;
176 profiles[n_profiles++] = priv->profile;
177 if (priv->profile == GST_VAAPI_PROFILE_VC1_SIMPLE)
178 profiles[n_profiles++] = GST_VAAPI_PROFILE_VC1_MAIN;
180 for (i = 0; i < n_profiles; i++) {
181 if (gst_vaapi_display_has_decoder(GST_VAAPI_DECODER_DISPLAY(decoder),
182 profiles[i], entrypoint))
186 return GST_VAAPI_DECODER_STATUS_ERROR_UNSUPPORTED_PROFILE;
187 priv->profile = profiles[i];
190 if (priv->size_changed) {
191 GST_DEBUG("size changed");
192 priv->size_changed = FALSE;
193 reset_context = TRUE;
197 reset_context = gst_vaapi_decoder_ensure_context(
198 GST_VAAPI_DECODER(decoder),
203 GST_DECODER_DEFAULT_SURFACES_COUNT
206 return GST_VAAPI_DECODER_STATUS_ERROR_UNKNOWN;
208 return GST_VAAPI_DECODER_STATUS_SUCCESS;
211 static inline GstVaapiDecoderStatus
212 render_picture(GstVaapiDecoderVC1 *decoder, GstVaapiPicture *picture)
214 if (!gst_vaapi_picture_output(picture))
215 return GST_VAAPI_DECODER_STATUS_ERROR_ALLOCATION_FAILED;
216 return GST_VAAPI_DECODER_STATUS_SUCCESS;
219 static GstVaapiDecoderStatus
220 decode_current_picture(GstVaapiDecoderVC1 *decoder)
222 GstVaapiDecoderVC1Private * const priv = decoder->priv;
223 GstVaapiPicture * const picture = priv->current_picture;
224 GstVaapiDecoderStatus status = GST_VAAPI_DECODER_STATUS_SUCCESS;
227 if (!gst_vaapi_picture_decode(picture))
228 status = GST_VAAPI_DECODER_STATUS_ERROR_UNKNOWN;
229 if (!GST_VAAPI_PICTURE_IS_REFERENCE(picture)) {
230 if (priv->prev_picture && priv->next_picture)
231 status = render_picture(decoder, picture);
233 gst_vaapi_picture_replace(&priv->current_picture, NULL);
238 static GstVaapiDecoderStatus
239 decode_sequence(GstVaapiDecoderVC1 *decoder, GstVC1BDU *rbdu, GstVC1BDU *ebdu)
241 GstVaapiDecoder * const base_decoder = GST_VAAPI_DECODER(decoder);
242 GstVaapiDecoderVC1Private * const priv = decoder->priv;
243 GstVC1SeqHdr * const seq_hdr = &priv->seq_hdr;
244 GstVC1AdvancedSeqHdr * const adv_hdr = &seq_hdr->advanced;
245 GstVC1SeqStructC * const structc = &seq_hdr->struct_c;
246 GstVC1ParserResult result;
247 GstVaapiProfile profile;
248 guint width, height, fps_n, fps_d;
250 result = gst_vc1_parse_sequence_header(
251 rbdu->data + rbdu->offset,
255 if (result != GST_VC1_PARSER_OK) {
256 GST_DEBUG("failed to parse sequence layer");
257 return get_status(result);
260 priv->has_entrypoint = FALSE;
262 /* Validate profile */
263 switch (seq_hdr->profile) {
264 case GST_VC1_PROFILE_SIMPLE:
265 case GST_VC1_PROFILE_MAIN:
266 case GST_VC1_PROFILE_ADVANCED:
269 GST_DEBUG("unsupported profile %d", seq_hdr->profile);
270 return GST_VAAPI_DECODER_STATUS_ERROR_UNSUPPORTED_PROFILE;
275 switch (seq_hdr->profile) {
276 case GST_VC1_PROFILE_SIMPLE:
277 case GST_VC1_PROFILE_MAIN:
279 fps_n = structc->framerate;
283 case GST_VC1_PROFILE_ADVANCED:
284 if (adv_hdr->display_ext && adv_hdr->framerate_flag) {
285 if (adv_hdr->framerateind) {
286 // 6.1.14.4.4 - Frame Rate Explicit
287 fps_n = adv_hdr->framerateexp + 1;
291 // 6.1.14.4.2 - Frame Rate Numerator
292 static const guint frameratenr_table[] = {
302 // 6.1.14.4.3 - Frame Rate Denominator
303 static const guint frameratedr_table[] = {
308 if (adv_hdr->frameratenr < 1 || adv_hdr->frameratenr > 7) {
309 GST_DEBUG("unsupported FRAMERATENR value");
310 return GST_VAAPI_DECODER_STATUS_ERROR_BITSTREAM_PARSER;
312 fps_n = frameratenr_table[adv_hdr->frameratenr];
314 if (adv_hdr->frameratedr < 1 || adv_hdr->frameratedr > 2) {
315 GST_DEBUG("unsupported FRAMERATEDR value");
316 return GST_VAAPI_DECODER_STATUS_ERROR_BITSTREAM_PARSER;
318 fps_d = frameratedr_table[adv_hdr->frameratedr];
323 g_assert(0 && "XXX: we already validated the profile above");
326 if (fps_n && fps_d) {
329 gst_vaapi_decoder_set_framerate(base_decoder, priv->fps_n, priv->fps_d);
332 switch (seq_hdr->profile) {
333 case GST_VC1_PROFILE_SIMPLE:
334 case GST_VC1_PROFILE_MAIN:
335 width = seq_hdr->struct_c.coded_width;
336 height = seq_hdr->struct_c.coded_height;
338 case GST_VC1_PROFILE_ADVANCED:
339 width = seq_hdr->advanced.max_coded_width;
340 height = seq_hdr->advanced.max_coded_height;
343 g_assert(0 && "XXX: we already validated the profile above");
347 if (priv->width != width) {
349 priv->size_changed = TRUE;
352 if (priv->height != height) {
353 priv->height = height;
354 priv->size_changed = TRUE;
357 switch (seq_hdr->profile) {
358 case GST_VC1_PROFILE_SIMPLE:
359 profile = GST_VAAPI_PROFILE_VC1_SIMPLE;
361 case GST_VC1_PROFILE_MAIN:
362 profile = GST_VAAPI_PROFILE_VC1_MAIN;
364 case GST_VC1_PROFILE_ADVANCED:
365 profile = GST_VAAPI_PROFILE_VC1_ADVANCED;
368 g_assert(0 && "XXX: we already validated the profile above");
371 if (priv->profile != profile) {
372 priv->profile = profile;
373 priv->profile_changed = TRUE;
375 return GST_VAAPI_DECODER_STATUS_SUCCESS;
378 static GstVaapiDecoderStatus
379 decode_sequence_end(GstVaapiDecoderVC1 *decoder)
381 GstVaapiDecoderVC1Private * const priv = decoder->priv;
382 GstVaapiDecoderStatus status;
384 if (priv->current_picture) {
385 status = decode_current_picture(decoder);
386 if (status != GST_VAAPI_DECODER_STATUS_SUCCESS)
388 status = render_picture(decoder, priv->current_picture);
389 if (status != GST_VAAPI_DECODER_STATUS_SUCCESS)
393 if (priv->next_picture) {
394 status = render_picture(decoder, priv->next_picture);
395 if (status != GST_VAAPI_DECODER_STATUS_SUCCESS)
398 return GST_VAAPI_DECODER_STATUS_END_OF_STREAM;
401 static GstVaapiDecoderStatus
402 decode_entry_point(GstVaapiDecoderVC1 *decoder, GstVC1BDU *rbdu, GstVC1BDU *ebdu)
404 GstVaapiDecoderVC1Private * const priv = decoder->priv;
405 GstVC1SeqHdr * const seq_hdr = &priv->seq_hdr;
406 GstVC1EntryPointHdr * const entrypoint_hdr = &priv->entrypoint_hdr;
407 GstVC1ParserResult result;
409 result = gst_vc1_parse_entry_point_header(
410 rbdu->data + rbdu->offset,
415 if (result != GST_VC1_PARSER_OK) {
416 GST_DEBUG("failed to parse entrypoint layer");
417 return get_status(result);
420 if (entrypoint_hdr->coded_size_flag) {
421 priv->width = entrypoint_hdr->coded_width;
422 priv->height = entrypoint_hdr->coded_height;
423 priv->size_changed = TRUE;
426 priv->has_entrypoint = TRUE;
427 priv->closed_entry = entrypoint_hdr->closed_entry;
428 priv->broken_link = entrypoint_hdr->broken_link;
429 return GST_VAAPI_DECODER_STATUS_SUCCESS;
432 /* Reconstruct bitstream PTYPE (7.1.1.4, index into Table-35) */
434 get_PTYPE(guint ptype)
437 case GST_VC1_PICTURE_TYPE_I: return 0;
438 case GST_VC1_PICTURE_TYPE_P: return 1;
439 case GST_VC1_PICTURE_TYPE_B: return 2;
440 case GST_VC1_PICTURE_TYPE_BI: return 3;
442 return 4; /* skipped P-frame */
445 /* Reconstruct bitstream BFRACTION (7.1.1.14, index into Table-40) */
447 get_BFRACTION(guint bfraction)
451 static const struct {
456 { 0, GST_VC1_BFRACTION_BASIS / 2 },
457 { 1, GST_VC1_BFRACTION_BASIS / 3 },
458 { 2, (GST_VC1_BFRACTION_BASIS * 2) / 3 },
459 { 3, GST_VC1_BFRACTION_BASIS / 4 },
460 { 4, (GST_VC1_BFRACTION_BASIS * 3) / 4 },
461 { 5, GST_VC1_BFRACTION_BASIS / 5 },
462 { 6, (GST_VC1_BFRACTION_BASIS * 2) / 5 },
463 { 7, (GST_VC1_BFRACTION_BASIS * 3) / 5 },
464 { 8, (GST_VC1_BFRACTION_BASIS * 4) / 5 },
465 { 9, GST_VC1_BFRACTION_BASIS / 6 },
466 { 10, (GST_VC1_BFRACTION_BASIS * 5) / 6 },
467 { 11, GST_VC1_BFRACTION_BASIS / 7 },
468 { 12, (GST_VC1_BFRACTION_BASIS * 2) / 7 },
469 { 13, (GST_VC1_BFRACTION_BASIS * 3) / 7 },
470 { 14, (GST_VC1_BFRACTION_BASIS * 4) / 7 },
471 { 15, (GST_VC1_BFRACTION_BASIS * 5) / 7 },
472 { 16, (GST_VC1_BFRACTION_BASIS * 6) / 7 },
473 { 17, GST_VC1_BFRACTION_BASIS / 8 },
474 { 18, (GST_VC1_BFRACTION_BASIS * 3) / 8 },
475 { 19, (GST_VC1_BFRACTION_BASIS * 5) / 8 },
476 { 20, (GST_VC1_BFRACTION_BASIS * 7) / 8 },
477 { 21, GST_VC1_BFRACTION_RESERVED },
478 { 22, GST_VC1_BFRACTION_PTYPE_BI }
484 for (i = 0; i < G_N_ELEMENTS(bfraction_map); i++) {
485 if (bfraction_map[i].value == bfraction)
486 return bfraction_map[i].index;
488 return 21; /* RESERVED */
491 /* Translate GStreamer MV modes to VA-API */
493 get_VAMvModeVC1(guint mvmode)
496 case GST_VC1_MVMODE_1MV_HPEL_BILINEAR: return VAMvMode1MvHalfPelBilinear;
497 case GST_VC1_MVMODE_1MV: return VAMvMode1Mv;
498 case GST_VC1_MVMODE_1MV_HPEL: return VAMvMode1MvHalfPel;
499 case GST_VC1_MVMODE_MIXED_MV: return VAMvModeMixedMv;
500 case GST_VC1_MVMODE_INTENSITY_COMP: return VAMvModeIntensityCompensation;
505 /* Reconstruct bitstream MVMODE (7.1.1.32) */
507 get_MVMODE(GstVC1FrameHdr *frame_hdr)
511 if (frame_hdr->profile == GST_VC1_PROFILE_ADVANCED)
512 mvmode = frame_hdr->pic.advanced.mvmode;
514 mvmode = frame_hdr->pic.simple.mvmode;
516 if (frame_hdr->ptype == GST_VC1_PICTURE_TYPE_P ||
517 frame_hdr->ptype == GST_VC1_PICTURE_TYPE_B)
518 return get_VAMvModeVC1(mvmode);
522 /* Reconstruct bitstream MVMODE2 (7.1.1.33) */
524 get_MVMODE2(GstVC1FrameHdr *frame_hdr)
526 guint mvmode, mvmode2;
528 if (frame_hdr->profile == GST_VC1_PROFILE_ADVANCED) {
529 mvmode = frame_hdr->pic.advanced.mvmode;
530 mvmode2 = frame_hdr->pic.advanced.mvmode2;
533 mvmode = frame_hdr->pic.simple.mvmode;
534 mvmode2 = frame_hdr->pic.simple.mvmode2;
537 if (frame_hdr->ptype == GST_VC1_PICTURE_TYPE_P &&
538 mvmode == GST_VC1_MVMODE_INTENSITY_COMP)
539 return get_VAMvModeVC1(mvmode2);
544 has_MVTYPEMB_bitplane(GstVaapiDecoderVC1 *decoder)
546 GstVaapiDecoderVC1Private * const priv = decoder->priv;
547 GstVC1SeqHdr * const seq_hdr = &priv->seq_hdr;
548 GstVC1FrameHdr * const frame_hdr = &priv->frame_hdr;
549 guint mvmode, mvmode2;
551 if (seq_hdr->profile == GST_VC1_PROFILE_ADVANCED) {
552 GstVC1PicAdvanced * const pic = &frame_hdr->pic.advanced;
555 mvmode = pic->mvmode;
556 mvmode2 = pic->mvmode2;
559 GstVC1PicSimpleMain * const pic = &frame_hdr->pic.simple;
562 mvmode = pic->mvmode;
563 mvmode2 = pic->mvmode2;
565 return (frame_hdr->ptype == GST_VC1_PICTURE_TYPE_P &&
566 (mvmode == GST_VC1_MVMODE_MIXED_MV ||
567 (mvmode == GST_VC1_MVMODE_INTENSITY_COMP &&
568 mvmode2 == GST_VC1_MVMODE_MIXED_MV)));
572 has_SKIPMB_bitplane(GstVaapiDecoderVC1 *decoder)
574 GstVaapiDecoderVC1Private * const priv = decoder->priv;
575 GstVC1SeqHdr * const seq_hdr = &priv->seq_hdr;
576 GstVC1FrameHdr * const frame_hdr = &priv->frame_hdr;
578 if (seq_hdr->profile == GST_VC1_PROFILE_ADVANCED) {
579 GstVC1PicAdvanced * const pic = &frame_hdr->pic.advanced;
584 GstVC1PicSimpleMain * const pic = &frame_hdr->pic.simple;
588 return (frame_hdr->ptype == GST_VC1_PICTURE_TYPE_P ||
589 frame_hdr->ptype == GST_VC1_PICTURE_TYPE_B);
593 has_DIRECTMB_bitplane(GstVaapiDecoderVC1 *decoder)
595 GstVaapiDecoderVC1Private * const priv = decoder->priv;
596 GstVC1SeqHdr * const seq_hdr = &priv->seq_hdr;
597 GstVC1FrameHdr * const frame_hdr = &priv->frame_hdr;
599 if (seq_hdr->profile == GST_VC1_PROFILE_ADVANCED) {
600 GstVC1PicAdvanced * const pic = &frame_hdr->pic.advanced;
605 GstVC1PicSimpleMain * const pic = &frame_hdr->pic.simple;
609 return frame_hdr->ptype == GST_VC1_PICTURE_TYPE_B;
613 has_ACPRED_bitplane(GstVaapiDecoderVC1 *decoder)
615 GstVaapiDecoderVC1Private * const priv = decoder->priv;
616 GstVC1SeqHdr * const seq_hdr = &priv->seq_hdr;
617 GstVC1FrameHdr * const frame_hdr = &priv->frame_hdr;
618 GstVC1PicAdvanced * const pic = &frame_hdr->pic.advanced;
620 if (seq_hdr->profile != GST_VC1_PROFILE_ADVANCED)
624 return (frame_hdr->ptype == GST_VC1_PICTURE_TYPE_I ||
625 frame_hdr->ptype == GST_VC1_PICTURE_TYPE_BI);
629 has_OVERFLAGS_bitplane(GstVaapiDecoderVC1 *decoder)
631 GstVaapiDecoderVC1Private * const priv = decoder->priv;
632 GstVC1SeqHdr * const seq_hdr = &priv->seq_hdr;
633 GstVC1EntryPointHdr * const entrypoint_hdr = &priv->entrypoint_hdr;
634 GstVC1FrameHdr * const frame_hdr = &priv->frame_hdr;
635 GstVC1PicAdvanced * const pic = &frame_hdr->pic.advanced;
637 if (seq_hdr->profile != GST_VC1_PROFILE_ADVANCED)
641 return ((frame_hdr->ptype == GST_VC1_PICTURE_TYPE_I ||
642 frame_hdr->ptype == GST_VC1_PICTURE_TYPE_BI) &&
643 (entrypoint_hdr->overlap && frame_hdr->pquant <= 8) &&
644 pic->condover == GST_VC1_CONDOVER_SELECT);
648 pack_bitplanes(GstVaapiBitPlane *bitplane, guint n, const guint8 *bitplanes[3], guint x, guint y, guint stride)
650 const guint dst_index = n / 2;
651 const guint src_index = y * stride + x;
655 v |= bitplanes[0][src_index];
657 v |= bitplanes[1][src_index] << 1;
659 v |= bitplanes[2][src_index] << 2;
660 bitplane->data[dst_index] = (bitplane->data[dst_index] << 4) | v;
664 fill_picture_structc(GstVaapiDecoderVC1 *decoder, GstVaapiPicture *picture)
666 GstVaapiDecoderVC1Private * const priv = decoder->priv;
667 VAPictureParameterBufferVC1 * const pic_param = picture->param;
668 GstVC1SeqStructC * const structc = &priv->seq_hdr.struct_c;
669 GstVC1FrameHdr * const frame_hdr = &priv->frame_hdr;
670 GstVC1PicSimpleMain * const pic = &frame_hdr->pic.simple;
672 /* Fill in VAPictureParameterBufferVC1 (simple/main profile bits) */
673 pic_param->sequence_fields.bits.finterpflag = structc->finterpflag;
674 pic_param->sequence_fields.bits.multires = structc->multires;
675 pic_param->sequence_fields.bits.overlap = structc->overlap;
676 pic_param->sequence_fields.bits.syncmarker = structc->syncmarker;
677 pic_param->sequence_fields.bits.rangered = structc->rangered;
678 pic_param->sequence_fields.bits.max_b_frames = structc->maxbframes;
679 pic_param->conditional_overlap_flag = 0; /* advanced profile only */
680 pic_param->fast_uvmc_flag = structc->fastuvmc;
681 pic_param->b_picture_fraction = get_BFRACTION(pic->bfraction);
682 pic_param->cbp_table = pic->cbptab;
683 pic_param->mb_mode_table = 0; /* XXX: interlaced frame */
684 pic_param->range_reduction_frame = pic->rangeredfrm;
685 pic_param->rounding_control = 0; /* advanced profile only */
686 pic_param->post_processing = 0; /* advanced profile only */
687 pic_param->picture_resolution_index = pic->respic;
688 pic_param->luma_scale = pic->lumscale;
689 pic_param->luma_shift = pic->lumshift;
690 pic_param->raw_coding.flags.mv_type_mb = pic->mvtypemb;
691 pic_param->raw_coding.flags.direct_mb = pic->directmb;
692 pic_param->raw_coding.flags.skip_mb = pic->skipmb;
693 pic_param->bitplane_present.flags.bp_mv_type_mb = has_MVTYPEMB_bitplane(decoder);
694 pic_param->bitplane_present.flags.bp_direct_mb = has_DIRECTMB_bitplane(decoder);
695 pic_param->bitplane_present.flags.bp_skip_mb = has_SKIPMB_bitplane(decoder);
696 pic_param->mv_fields.bits.mv_table = pic->mvtab;
697 pic_param->mv_fields.bits.extended_mv_flag = structc->extended_mv;
698 pic_param->mv_fields.bits.extended_mv_range = pic->mvrange;
699 pic_param->transform_fields.bits.variable_sized_transform_flag = structc->vstransform;
700 pic_param->transform_fields.bits.mb_level_transform_type_flag = pic->ttmbf;
701 pic_param->transform_fields.bits.frame_level_transform_type = pic->ttfrm;
702 pic_param->transform_fields.bits.transform_ac_codingset_idx2 = pic->transacfrm2;
707 fill_picture_advanced(GstVaapiDecoderVC1 *decoder, GstVaapiPicture *picture)
709 GstVaapiDecoderVC1Private * const priv = decoder->priv;
710 VAPictureParameterBufferVC1 * const pic_param = picture->param;
711 GstVC1AdvancedSeqHdr * const adv_hdr = &priv->seq_hdr.advanced;
712 GstVC1EntryPointHdr * const entrypoint_hdr = &priv->entrypoint_hdr;
713 GstVC1FrameHdr * const frame_hdr = &priv->frame_hdr;
714 GstVC1PicAdvanced * const pic = &frame_hdr->pic.advanced;
716 if (!priv->has_entrypoint)
719 /* Fill in VAPictureParameterBufferVC1 (advanced profile bits) */
720 pic_param->sequence_fields.bits.pulldown = adv_hdr->pulldown;
721 pic_param->sequence_fields.bits.interlace = adv_hdr->interlace;
722 pic_param->sequence_fields.bits.tfcntrflag = adv_hdr->tfcntrflag;
723 pic_param->sequence_fields.bits.finterpflag = adv_hdr->finterpflag;
724 pic_param->sequence_fields.bits.psf = adv_hdr->psf;
725 pic_param->sequence_fields.bits.overlap = entrypoint_hdr->overlap;
726 pic_param->entrypoint_fields.bits.broken_link = entrypoint_hdr->broken_link;
727 pic_param->entrypoint_fields.bits.closed_entry = entrypoint_hdr->closed_entry;
728 pic_param->entrypoint_fields.bits.panscan_flag = entrypoint_hdr->panscan_flag;
729 pic_param->entrypoint_fields.bits.loopfilter = entrypoint_hdr->loopfilter;
730 pic_param->conditional_overlap_flag = pic->condover;
731 pic_param->fast_uvmc_flag = entrypoint_hdr->fastuvmc;
732 pic_param->range_mapping_fields.bits.luma_flag = entrypoint_hdr->range_mapy_flag;
733 pic_param->range_mapping_fields.bits.luma = entrypoint_hdr->range_mapy;
734 pic_param->range_mapping_fields.bits.chroma_flag = entrypoint_hdr->range_mapuv_flag;
735 pic_param->range_mapping_fields.bits.chroma = entrypoint_hdr->range_mapuv;
736 pic_param->b_picture_fraction = get_BFRACTION(pic->bfraction);
737 pic_param->cbp_table = pic->cbptab;
738 pic_param->mb_mode_table = 0; /* XXX: interlaced frame */
739 pic_param->range_reduction_frame = 0; /* simple/main profile only */
740 pic_param->rounding_control = pic->rndctrl;
741 pic_param->post_processing = pic->postproc;
742 pic_param->picture_resolution_index = 0; /* simple/main profile only */
743 pic_param->luma_scale = pic->lumscale;
744 pic_param->luma_shift = pic->lumshift;
745 pic_param->picture_fields.bits.frame_coding_mode = pic->fcm;
746 pic_param->picture_fields.bits.top_field_first = pic->tff;
747 pic_param->picture_fields.bits.is_first_field = pic->fcm == 0; /* XXX: interlaced frame */
748 pic_param->picture_fields.bits.intensity_compensation = pic->mvmode == GST_VC1_MVMODE_INTENSITY_COMP;
749 pic_param->raw_coding.flags.mv_type_mb = pic->mvtypemb;
750 pic_param->raw_coding.flags.direct_mb = pic->directmb;
751 pic_param->raw_coding.flags.skip_mb = pic->skipmb;
752 pic_param->raw_coding.flags.ac_pred = pic->acpred;
753 pic_param->raw_coding.flags.overflags = pic->overflags;
754 pic_param->bitplane_present.flags.bp_mv_type_mb = has_MVTYPEMB_bitplane(decoder);
755 pic_param->bitplane_present.flags.bp_direct_mb = has_DIRECTMB_bitplane(decoder);
756 pic_param->bitplane_present.flags.bp_skip_mb = has_SKIPMB_bitplane(decoder);
757 pic_param->bitplane_present.flags.bp_ac_pred = has_ACPRED_bitplane(decoder);
758 pic_param->bitplane_present.flags.bp_overflags = has_OVERFLAGS_bitplane(decoder);
759 pic_param->reference_fields.bits.reference_distance_flag = entrypoint_hdr->refdist_flag;
760 pic_param->mv_fields.bits.mv_table = pic->mvtab;
761 pic_param->mv_fields.bits.extended_mv_flag = entrypoint_hdr->extended_mv;
762 pic_param->mv_fields.bits.extended_mv_range = pic->mvrange;
763 pic_param->mv_fields.bits.extended_dmv_flag = entrypoint_hdr->extended_dmv;
764 pic_param->pic_quantizer_fields.bits.dquant = entrypoint_hdr->dquant;
765 pic_param->pic_quantizer_fields.bits.quantizer = entrypoint_hdr->quantizer;
766 pic_param->transform_fields.bits.variable_sized_transform_flag = entrypoint_hdr->vstransform;
767 pic_param->transform_fields.bits.mb_level_transform_type_flag = pic->ttmbf;
768 pic_param->transform_fields.bits.frame_level_transform_type = pic->ttfrm;
769 pic_param->transform_fields.bits.transform_ac_codingset_idx2 = pic->transacfrm2;
774 fill_picture(GstVaapiDecoderVC1 *decoder, GstVaapiPicture *picture)
776 GstVaapiDecoderVC1Private * const priv = decoder->priv;
777 VAPictureParameterBufferVC1 * const pic_param = picture->param;
778 GstVC1SeqHdr * const seq_hdr = &priv->seq_hdr;
779 GstVC1FrameHdr * const frame_hdr = &priv->frame_hdr;
781 /* Fill in VAPictureParameterBufferVC1 (common fields) */
782 pic_param->forward_reference_picture = VA_INVALID_ID;
783 pic_param->backward_reference_picture = VA_INVALID_ID;
784 pic_param->inloop_decoded_picture = VA_INVALID_ID;
785 pic_param->sequence_fields.value = 0;
786 #if VA_CHECK_VERSION(0,32,0)
787 pic_param->sequence_fields.bits.profile = seq_hdr->profile;
789 pic_param->coded_width = priv->width;
790 pic_param->coded_height = priv->height;
791 pic_param->entrypoint_fields.value = 0;
792 pic_param->range_mapping_fields.value = 0;
793 pic_param->picture_fields.value = 0;
794 pic_param->picture_fields.bits.picture_type = get_PTYPE(frame_hdr->ptype);
795 pic_param->raw_coding.value = 0;
796 pic_param->bitplane_present.value = 0;
797 pic_param->reference_fields.value = 0;
798 pic_param->mv_fields.value = 0;
799 pic_param->mv_fields.bits.mv_mode = get_MVMODE(frame_hdr);
800 pic_param->mv_fields.bits.mv_mode2 = get_MVMODE2(frame_hdr);
801 pic_param->pic_quantizer_fields.value = 0;
802 pic_param->pic_quantizer_fields.bits.half_qp = frame_hdr->halfqp;
803 pic_param->pic_quantizer_fields.bits.pic_quantizer_scale = frame_hdr->pquant;
804 pic_param->pic_quantizer_fields.bits.pic_quantizer_type = frame_hdr->pquantizer;
805 pic_param->pic_quantizer_fields.bits.dq_frame = frame_hdr->vopdquant.dquantfrm;
806 pic_param->pic_quantizer_fields.bits.dq_profile = frame_hdr->vopdquant.dqprofile;
807 pic_param->pic_quantizer_fields.bits.dq_sb_edge = frame_hdr->vopdquant.dqsbedge;
808 pic_param->pic_quantizer_fields.bits.dq_db_edge = frame_hdr->vopdquant.dqsbedge;
809 pic_param->pic_quantizer_fields.bits.dq_binary_level = frame_hdr->vopdquant.dqbilevel;
810 pic_param->pic_quantizer_fields.bits.alt_pic_quantizer = frame_hdr->vopdquant.altpquant;
811 pic_param->transform_fields.value = 0;
812 pic_param->transform_fields.bits.transform_ac_codingset_idx1 = frame_hdr->transacfrm;
813 pic_param->transform_fields.bits.intra_transform_dc_table = frame_hdr->transdctab;
815 if (seq_hdr->profile == GST_VC1_PROFILE_ADVANCED) {
816 if (!fill_picture_advanced(decoder, picture))
820 if (!fill_picture_structc(decoder, picture))
824 switch (picture->type) {
825 case GST_VAAPI_PICTURE_TYPE_B:
826 if (priv->next_picture)
827 pic_param->backward_reference_picture = priv->next_picture->surface_id;
829 case GST_VAAPI_PICTURE_TYPE_P:
830 if (priv->prev_picture)
831 pic_param->forward_reference_picture = priv->prev_picture->surface_id;
837 if (pic_param->bitplane_present.value) {
838 const guint8 *bitplanes[3];
841 switch (picture->type) {
842 case GST_VAAPI_PICTURE_TYPE_P:
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] = pic_param->bitplane_present.flags.bp_mv_type_mb ? priv->bitplanes->mvtypemb : NULL;
847 case GST_VAAPI_PICTURE_TYPE_B:
848 bitplanes[0] = pic_param->bitplane_present.flags.bp_direct_mb ? priv->bitplanes->directmb : NULL;
849 bitplanes[1] = pic_param->bitplane_present.flags.bp_skip_mb ? priv->bitplanes->skipmb : NULL;
850 bitplanes[2] = NULL; /* XXX: interlaced frame (FORWARD plane) */
852 case GST_VAAPI_PICTURE_TYPE_BI:
853 case GST_VAAPI_PICTURE_TYPE_I:
854 bitplanes[0] = NULL; /* XXX: interlaced frame (FIELDTX plane) */
855 bitplanes[1] = pic_param->bitplane_present.flags.bp_ac_pred ? priv->bitplanes->acpred : NULL;
856 bitplanes[2] = pic_param->bitplane_present.flags.bp_overflags ? priv->bitplanes->overflags : NULL;
865 picture->bitplane = GST_VAAPI_BITPLANE_NEW(
867 (seq_hdr->mb_width * seq_hdr->mb_height + 1) / 2
869 if (!picture->bitplane)
873 for (y = 0; y < seq_hdr->mb_height; y++)
874 for (x = 0; x < seq_hdr->mb_width; x++, n++)
875 pack_bitplanes(picture->bitplane, n, bitplanes, x, y, seq_hdr->mb_stride);
876 if (n & 1) /* move last nibble to the high order */
877 picture->bitplane->data[n/2] <<= 4;
882 static GstVaapiDecoderStatus
883 decode_frame(GstVaapiDecoderVC1 *decoder, GstVC1BDU *rbdu, GstVC1BDU *ebdu)
885 GstVaapiDecoderVC1Private * const priv = decoder->priv;
886 GstVC1SeqHdr * const seq_hdr = &priv->seq_hdr;
887 GstVC1FrameHdr * const frame_hdr = &priv->frame_hdr;
888 GstVC1ParserResult result;
889 GstVaapiPicture *picture;
890 GstVaapiSlice *slice;
891 GstVaapiDecoderStatus status;
892 VASliceParameterBufferVC1 *slice_param;
895 status = ensure_context(decoder);
896 if (status != GST_VAAPI_DECODER_STATUS_SUCCESS) {
897 GST_DEBUG("failed to reset context");
901 if (priv->current_picture) {
902 status = decode_current_picture(decoder);
903 if (status != GST_VAAPI_DECODER_STATUS_SUCCESS)
907 priv->current_picture = GST_VAAPI_PICTURE_NEW(VC1, decoder);
908 if (!priv->current_picture) {
909 GST_DEBUG("failed to allocate picture");
910 return GST_VAAPI_DECODER_STATUS_ERROR_ALLOCATION_FAILED;
912 picture = priv->current_picture;
914 if (!gst_vc1_bitplanes_ensure_size(priv->bitplanes, seq_hdr)) {
915 GST_DEBUG("failed to allocate bitplanes");
916 return GST_VAAPI_DECODER_STATUS_ERROR_ALLOCATION_FAILED;
919 memset(frame_hdr, 0, sizeof(*frame_hdr));
920 result = gst_vc1_parse_frame_header(
921 rbdu->data + rbdu->offset,
927 if (result != GST_VC1_PARSER_OK) {
928 GST_DEBUG("failed to parse frame layer");
929 return get_status(result);
932 switch (frame_hdr->ptype) {
933 case GST_VC1_PICTURE_TYPE_I:
934 picture->type = GST_VAAPI_PICTURE_TYPE_I;
935 GST_VAAPI_PICTURE_FLAG_SET(picture, GST_VAAPI_PICTURE_FLAG_REFERENCE);
937 case GST_VC1_PICTURE_TYPE_SKIPPED:
938 case GST_VC1_PICTURE_TYPE_P:
939 picture->type = GST_VAAPI_PICTURE_TYPE_P;
940 GST_VAAPI_PICTURE_FLAG_SET(picture, GST_VAAPI_PICTURE_FLAG_REFERENCE);
942 case GST_VC1_PICTURE_TYPE_B:
943 picture->type = GST_VAAPI_PICTURE_TYPE_B;
945 case GST_VC1_PICTURE_TYPE_BI:
946 picture->type = GST_VAAPI_PICTURE_TYPE_BI;
949 GST_DEBUG("unsupported picture type %d", frame_hdr->ptype);
950 return GST_VAAPI_DECODER_STATUS_ERROR_UNKNOWN;
953 /* Update presentation time */
954 pts = gst_adapter_prev_timestamp(priv->adapter, NULL);
957 /* Update reference pictures */
958 if (GST_VAAPI_PICTURE_IS_REFERENCE(picture)) {
959 if (priv->next_picture)
960 status = render_picture(decoder, priv->next_picture);
961 gst_vaapi_picture_replace(&priv->prev_picture, priv->next_picture);
962 gst_vaapi_picture_replace(&priv->next_picture, picture);
965 if (!fill_picture(decoder, picture))
966 return GST_VAAPI_DECODER_STATUS_ERROR_UNKNOWN;
968 slice = GST_VAAPI_SLICE_NEW(
971 ebdu->data + ebdu->sc_offset,
972 ebdu->size + ebdu->offset - ebdu->sc_offset
975 GST_DEBUG("failed to allocate slice");
976 return GST_VAAPI_DECODER_STATUS_ERROR_ALLOCATION_FAILED;
978 gst_vaapi_picture_add_slice(picture, slice);
980 /* Fill in VASliceParameterBufferVC1 */
981 slice_param = slice->param;
982 slice_param->macroblock_offset = 8 * (ebdu->offset - ebdu->sc_offset) + frame_hdr->header_size;
983 slice_param->slice_vertical_position = 0;
985 /* Decode picture right away, we got the full frame */
986 return decode_current_picture(decoder);
990 decode_rbdu(GstVaapiDecoderVC1 *decoder, GstVC1BDU *rbdu, GstVC1BDU *ebdu)
992 GstVaapiDecoderVC1Private * const priv = decoder->priv;
994 guint i, j, rbdu_buffer_size;
996 /* BDU are encapsulated in advanced profile mode only */
997 if (priv->profile != GST_VAAPI_PROFILE_VC1_ADVANCED) {
998 memcpy(rbdu, ebdu, sizeof(*rbdu));
1002 /* Reallocate unescaped bitstream buffer */
1003 rbdu_buffer = priv->rbdu_buffer;
1004 if (!rbdu_buffer || ebdu->size > priv->rbdu_buffer_size) {
1005 rbdu_buffer = g_realloc(priv->rbdu_buffer, ebdu->size);
1008 priv->rbdu_buffer = rbdu_buffer;
1009 priv->rbdu_buffer_size = ebdu->size;
1012 /* Unescape bitstream buffer */
1013 if (ebdu->size < 4) {
1014 memcpy(rbdu_buffer, ebdu->data + ebdu->offset, ebdu->size);
1015 rbdu_buffer_size = ebdu->size;
1018 guint8 * const bdu_buffer = ebdu->data + ebdu->offset;
1019 for (i = 0, j = 0; i < ebdu->size; i++) {
1020 if (i >= 2 && i < ebdu->size - 1 &&
1021 bdu_buffer[i - 1] == 0x00 &&
1022 bdu_buffer[i - 2] == 0x00 &&
1023 bdu_buffer[i ] == 0x03 &&
1024 bdu_buffer[i + 1] <= 0x03)
1026 rbdu_buffer[j++] = bdu_buffer[i];
1028 rbdu_buffer_size = j;
1031 /* Reconstruct RBDU */
1032 rbdu->type = ebdu->type;
1033 rbdu->size = rbdu_buffer_size;
1034 rbdu->sc_offset = 0;
1036 rbdu->data = rbdu_buffer;
1040 static GstVaapiDecoderStatus
1041 decode_ebdu(GstVaapiDecoderVC1 *decoder, GstVC1BDU *ebdu)
1043 GstVaapiDecoderStatus status;
1046 if (!decode_rbdu(decoder, &rbdu, ebdu))
1047 return GST_VAAPI_DECODER_STATUS_ERROR_ALLOCATION_FAILED;
1049 switch (ebdu->type) {
1050 case GST_VC1_SEQUENCE:
1051 status = decode_sequence(decoder, &rbdu, ebdu);
1053 case GST_VC1_ENTRYPOINT:
1054 status = decode_entry_point(decoder, &rbdu, ebdu);
1057 status = decode_frame(decoder, &rbdu, ebdu);
1060 GST_DEBUG("decode slice");
1061 status = GST_VAAPI_DECODER_STATUS_ERROR_BITSTREAM_PARSER;
1063 case GST_VC1_END_OF_SEQ:
1064 status = decode_sequence_end(decoder);
1067 GST_DEBUG("unsupported BDU type %d", ebdu->type);
1068 status = GST_VAAPI_DECODER_STATUS_ERROR_BITSTREAM_PARSER;
1074 static GstVaapiDecoderStatus
1075 decode_buffer(GstVaapiDecoderVC1 *decoder, GstBuffer *buffer)
1077 GstVaapiDecoderVC1Private * const priv = decoder->priv;
1078 GstVaapiDecoderStatus status;
1079 GstVC1ParserResult result;
1081 GstBuffer *codec_data;
1083 guint buf_size, ofs;
1085 buf = GST_BUFFER_DATA(buffer);
1086 buf_size = GST_BUFFER_SIZE(buffer);
1087 if (!buf && buf_size == 0)
1088 return decode_sequence_end(decoder);
1090 gst_buffer_ref(buffer);
1091 gst_adapter_push(priv->adapter, buffer);
1093 /* Assume demuxer sends out plain frames if codec-data */
1094 codec_data = GST_VAAPI_DECODER_CODEC_DATA(decoder);
1095 if (codec_data && codec_data != buffer) {
1096 ebdu.type = GST_VC1_FRAME;
1097 ebdu.size = buf_size;
1101 status = decode_ebdu(decoder, &ebdu);
1103 if (gst_adapter_available(priv->adapter) >= buf_size)
1104 gst_adapter_flush(priv->adapter, buf_size);
1108 if (priv->sub_buffer) {
1109 buffer = gst_buffer_merge(priv->sub_buffer, buffer);
1111 return GST_VAAPI_DECODER_STATUS_ERROR_ALLOCATION_FAILED;
1112 gst_buffer_unref(priv->sub_buffer);
1113 priv->sub_buffer = NULL;
1116 buf = GST_BUFFER_DATA(buffer);
1117 buf_size = GST_BUFFER_SIZE(buffer);
1120 result = gst_vc1_identify_next_bdu(
1125 status = get_status(result);
1127 if (status == GST_VAAPI_DECODER_STATUS_ERROR_NO_DATA) {
1128 priv->sub_buffer = gst_buffer_create_sub(buffer, ofs, buf_size - ofs);
1131 if (status != GST_VAAPI_DECODER_STATUS_SUCCESS)
1134 ofs += ebdu.offset + ebdu.size;
1135 if (gst_adapter_available(priv->adapter) >= ebdu.offset)
1136 gst_adapter_flush(priv->adapter, ebdu.offset);
1138 status = decode_ebdu(decoder, &ebdu);
1139 if (gst_adapter_available(priv->adapter) >= ebdu.size)
1140 gst_adapter_flush(priv->adapter, ebdu.size);
1141 } while (status == GST_VAAPI_DECODER_STATUS_SUCCESS);
1145 static GstVaapiDecoderStatus
1146 decode_codec_data(GstVaapiDecoderVC1 *decoder, GstBuffer *buffer)
1148 GstVaapiDecoderVC1Private * const priv = decoder->priv;
1149 GstVC1SeqHdr * const seq_hdr = &priv->seq_hdr;
1150 GstVaapiDecoderStatus status;
1151 GstVC1ParserResult result;
1154 GstStructure *structure;
1156 guint buf_size, ofs;
1160 buf = GST_BUFFER_DATA(buffer);
1161 buf_size = GST_BUFFER_SIZE(buffer);
1162 if (!buf || buf_size == 0)
1163 return GST_VAAPI_DECODER_STATUS_SUCCESS;
1165 caps = GST_VAAPI_DECODER_CAST(decoder)->priv->caps;
1166 structure = gst_caps_get_structure(caps, 0);
1168 if (!gst_structure_get_int(structure, "width", &width) ||
1169 !gst_structure_get_int(structure, "height", &height)) {
1170 GST_DEBUG("failed to parse size from codec-data");
1171 return GST_VAAPI_DECODER_STATUS_ERROR_UNKNOWN;
1174 if (!gst_structure_get_fourcc(structure, "format", &format)) {
1175 GST_DEBUG("failed to parse profile from codec-data");
1176 return GST_VAAPI_DECODER_STATUS_ERROR_UNSUPPORTED_CODEC;
1179 /* WMV3 -- expecting sequence header */
1180 if (format == GST_MAKE_FOURCC('W','M','V','3')) {
1181 seq_hdr->struct_c.coded_width = width;
1182 seq_hdr->struct_c.coded_height = height;
1183 ebdu.type = GST_VC1_SEQUENCE;
1184 ebdu.size = buf_size;
1188 return decode_ebdu(decoder, &ebdu);
1191 /* WVC1 -- expecting bitstream data units */
1192 if (format != GST_MAKE_FOURCC('W','V','C','1'))
1193 return GST_VAAPI_DECODER_STATUS_ERROR_UNSUPPORTED_PROFILE;
1194 seq_hdr->advanced.max_coded_width = width;
1195 seq_hdr->advanced.max_coded_height = height;
1199 result = gst_vc1_identify_next_bdu(
1206 case GST_VC1_PARSER_NO_BDU_END:
1207 /* Assume the EBDU is complete within codec-data bounds */
1208 ebdu.size = buf_size - ofs - (ebdu.offset - ebdu.sc_offset);
1210 case GST_VC1_PARSER_OK:
1211 status = decode_ebdu(decoder, &ebdu);
1212 ofs += ebdu.offset + ebdu.size;
1215 status = get_status(result);
1218 } while (status == GST_VAAPI_DECODER_STATUS_SUCCESS && ofs < buf_size);
1222 GstVaapiDecoderStatus
1223 gst_vaapi_decoder_vc1_decode(GstVaapiDecoder *base, GstBuffer *buffer)
1225 GstVaapiDecoderVC1 * const decoder = GST_VAAPI_DECODER_VC1(base);
1226 GstVaapiDecoderVC1Private * const priv = decoder->priv;
1227 GstVaapiDecoderStatus status;
1228 GstBuffer *codec_data;
1230 g_return_val_if_fail(priv->is_constructed,
1231 GST_VAAPI_DECODER_STATUS_ERROR_INIT_FAILED);
1233 if (!priv->is_opened) {
1234 priv->is_opened = gst_vaapi_decoder_vc1_open(decoder, buffer);
1235 if (!priv->is_opened)
1236 return GST_VAAPI_DECODER_STATUS_ERROR_UNSUPPORTED_CODEC;
1238 codec_data = GST_VAAPI_DECODER_CODEC_DATA(decoder);
1240 status = decode_codec_data(decoder, codec_data);
1241 if (status != GST_VAAPI_DECODER_STATUS_SUCCESS)
1245 return decode_buffer(decoder, buffer);
1249 gst_vaapi_decoder_vc1_finalize(GObject *object)
1251 GstVaapiDecoderVC1 * const decoder = GST_VAAPI_DECODER_VC1(object);
1253 gst_vaapi_decoder_vc1_destroy(decoder);
1255 G_OBJECT_CLASS(gst_vaapi_decoder_vc1_parent_class)->finalize(object);
1259 gst_vaapi_decoder_vc1_constructed(GObject *object)
1261 GstVaapiDecoderVC1 * const decoder = GST_VAAPI_DECODER_VC1(object);
1262 GstVaapiDecoderVC1Private * const priv = decoder->priv;
1263 GObjectClass *parent_class;
1265 parent_class = G_OBJECT_CLASS(gst_vaapi_decoder_vc1_parent_class);
1266 if (parent_class->constructed)
1267 parent_class->constructed(object);
1269 priv->is_constructed = gst_vaapi_decoder_vc1_create(decoder);
1273 gst_vaapi_decoder_vc1_class_init(GstVaapiDecoderVC1Class *klass)
1275 GObjectClass * const object_class = G_OBJECT_CLASS(klass);
1276 GstVaapiDecoderClass * const decoder_class = GST_VAAPI_DECODER_CLASS(klass);
1278 g_type_class_add_private(klass, sizeof(GstVaapiDecoderVC1Private));
1280 object_class->finalize = gst_vaapi_decoder_vc1_finalize;
1281 object_class->constructed = gst_vaapi_decoder_vc1_constructed;
1283 decoder_class->decode = gst_vaapi_decoder_vc1_decode;
1287 gst_vaapi_decoder_vc1_init(GstVaapiDecoderVC1 *decoder)
1289 GstVaapiDecoderVC1Private *priv;
1291 priv = GST_VAAPI_DECODER_VC1_GET_PRIVATE(decoder);
1292 decoder->priv = priv;
1297 priv->profile = (GstVaapiProfile)0;
1298 priv->current_picture = NULL;
1299 priv->next_picture = NULL;
1300 priv->prev_picture = NULL;
1301 priv->adapter = NULL;
1302 priv->sub_buffer = NULL;
1303 priv->rbdu_buffer = NULL;
1304 priv->rbdu_buffer_size = 0;
1305 priv->is_constructed = FALSE;
1306 priv->is_opened = FALSE;
1307 priv->is_first_field = FALSE;
1308 priv->has_entrypoint = FALSE;
1309 priv->size_changed = FALSE;
1310 priv->profile_changed = FALSE;
1311 priv->closed_entry = FALSE;
1312 priv->broken_link = FALSE;
1316 * gst_vaapi_decoder_vc1_new:
1317 * @display: a #GstVaapiDisplay
1318 * @caps: a #GstCaps holding codec information
1320 * Creates a new #GstVaapiDecoder for VC-1 decoding. The @caps can
1321 * hold extra information like codec-data and pictured coded size.
1323 * Return value: the newly allocated #GstVaapiDecoder object
1326 gst_vaapi_decoder_vc1_new(GstVaapiDisplay *display, GstCaps *caps)
1328 GstVaapiDecoderVC1 *decoder;
1330 g_return_val_if_fail(GST_VAAPI_IS_DISPLAY(display), NULL);
1331 g_return_val_if_fail(GST_IS_CAPS(caps), NULL);
1333 decoder = g_object_new(
1334 GST_VAAPI_TYPE_DECODER_VC1,
1339 if (!decoder->priv->is_constructed) {
1340 g_object_unref(decoder);
1343 return GST_VAAPI_DECODER_CAST(decoder);