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;
53 GstVC1EntryPointHdr entrypoint_hdr;
54 GstVC1FrameHdr frame_hdr;
55 GstVC1BitPlanes *bitplanes;
56 GstVaapiPicture *current_picture;
57 GstVaapiPicture *next_picture;
58 GstVaapiPicture *prev_picture;
60 GstBuffer *sub_buffer;
62 guint rbdu_buffer_size;
63 guint is_constructed : 1;
65 guint is_first_field : 1;
66 guint has_entrypoint : 1;
67 guint size_changed : 1;
68 guint profile_changed : 1;
69 guint closed_entry : 1;
70 guint broken_link : 1;
73 static GstVaapiDecoderStatus
74 get_status(GstVC1ParserResult result)
76 GstVaapiDecoderStatus status;
79 case GST_VC1_PARSER_OK:
80 status = GST_VAAPI_DECODER_STATUS_SUCCESS;
82 case GST_VC1_PARSER_NO_BDU_END:
83 status = GST_VAAPI_DECODER_STATUS_ERROR_NO_DATA;
85 case GST_VC1_PARSER_ERROR:
86 status = GST_VAAPI_DECODER_STATUS_ERROR_BITSTREAM_PARSER;
89 status = GST_VAAPI_DECODER_STATUS_ERROR_UNKNOWN;
96 gst_vaapi_decoder_vc1_close(GstVaapiDecoderVC1 *decoder)
98 GstVaapiDecoderVC1Private * const priv = decoder->priv;
100 gst_vaapi_picture_replace(&priv->current_picture, NULL);
101 gst_vaapi_picture_replace(&priv->next_picture, NULL);
102 gst_vaapi_picture_replace(&priv->prev_picture, NULL);
104 if (priv->sub_buffer) {
105 gst_buffer_unref(priv->sub_buffer);
106 priv->sub_buffer = NULL;
109 if (priv->bitplanes) {
110 gst_vc1_bitplanes_free(priv->bitplanes);
111 priv->bitplanes = NULL;
115 gst_adapter_clear(priv->adapter);
116 g_object_unref(priv->adapter);
117 priv->adapter = NULL;
122 gst_vaapi_decoder_vc1_open(GstVaapiDecoderVC1 *decoder, GstBuffer *buffer)
124 GstVaapiDecoderVC1Private * const priv = decoder->priv;
126 gst_vaapi_decoder_vc1_close(decoder);
128 priv->adapter = gst_adapter_new();
132 priv->bitplanes = gst_vc1_bitplanes_new();
133 if (!priv->bitplanes)
139 gst_vaapi_decoder_vc1_destroy(GstVaapiDecoderVC1 *decoder)
141 GstVaapiDecoderVC1Private * const priv = decoder->priv;
143 gst_vaapi_decoder_vc1_close(decoder);
145 if (priv->rbdu_buffer) {
146 g_free(priv->rbdu_buffer);
147 priv->rbdu_buffer = NULL;
148 priv->rbdu_buffer_size = 0;
153 gst_vaapi_decoder_vc1_create(GstVaapiDecoderVC1 *decoder)
155 if (!GST_VAAPI_DECODER_CODEC(decoder))
160 static GstVaapiDecoderStatus
161 ensure_context(GstVaapiDecoderVC1 *decoder)
163 GstVaapiDecoderVC1Private * const priv = decoder->priv;
164 GstVaapiProfile profiles[2];
165 GstVaapiEntrypoint entrypoint = GST_VAAPI_ENTRYPOINT_VLD;
166 guint i, n_profiles = 0;
167 gboolean reset_context = FALSE;
169 if (priv->profile_changed) {
170 GST_DEBUG("profile changed");
171 priv->profile_changed = FALSE;
172 reset_context = TRUE;
174 profiles[n_profiles++] = priv->profile;
175 if (priv->profile == GST_VAAPI_PROFILE_VC1_SIMPLE)
176 profiles[n_profiles++] = GST_VAAPI_PROFILE_VC1_MAIN;
178 for (i = 0; i < n_profiles; i++) {
179 if (gst_vaapi_display_has_decoder(GST_VAAPI_DECODER_DISPLAY(decoder),
180 profiles[i], entrypoint))
184 return GST_VAAPI_DECODER_STATUS_ERROR_UNSUPPORTED_PROFILE;
185 priv->profile = profiles[i];
188 if (priv->size_changed) {
189 GST_DEBUG("size changed");
190 priv->size_changed = FALSE;
191 reset_context = TRUE;
195 GstVaapiContextInfo info;
197 info.profile = priv->profile;
198 info.entrypoint = entrypoint;
199 info.width = priv->width;
200 info.height = priv->height;
202 reset_context = gst_vaapi_decoder_ensure_context(
203 GST_VAAPI_DECODER(decoder),
207 return GST_VAAPI_DECODER_STATUS_ERROR_UNKNOWN;
209 return GST_VAAPI_DECODER_STATUS_SUCCESS;
212 static inline GstVaapiDecoderStatus
213 render_picture(GstVaapiDecoderVC1 *decoder, GstVaapiPicture *picture)
215 if (!gst_vaapi_picture_output(picture))
216 return GST_VAAPI_DECODER_STATUS_ERROR_ALLOCATION_FAILED;
217 return GST_VAAPI_DECODER_STATUS_SUCCESS;
220 static GstVaapiDecoderStatus
221 decode_current_picture(GstVaapiDecoderVC1 *decoder)
223 GstVaapiDecoderVC1Private * const priv = decoder->priv;
224 GstVaapiPicture * const picture = priv->current_picture;
225 GstVaapiDecoderStatus status = GST_VAAPI_DECODER_STATUS_SUCCESS;
228 if (!gst_vaapi_picture_decode(picture))
229 status = GST_VAAPI_DECODER_STATUS_ERROR_UNKNOWN;
230 if (!GST_VAAPI_PICTURE_IS_REFERENCE(picture)) {
231 if (priv->prev_picture && priv->next_picture)
232 status = render_picture(decoder, picture);
234 gst_vaapi_picture_replace(&priv->current_picture, NULL);
239 static GstVaapiDecoderStatus
240 decode_sequence(GstVaapiDecoderVC1 *decoder, GstVC1BDU *rbdu, GstVC1BDU *ebdu)
242 GstVaapiDecoder * const base_decoder = GST_VAAPI_DECODER(decoder);
243 GstVaapiDecoderVC1Private * const priv = decoder->priv;
244 GstVC1SeqHdr * const seq_hdr = &priv->seq_hdr;
245 GstVC1AdvancedSeqHdr * const adv_hdr = &seq_hdr->advanced;
246 GstVC1SeqStructC * const structc = &seq_hdr->struct_c;
247 GstVC1ParserResult result;
248 GstVaapiProfile profile;
249 guint width, height, fps_n, fps_d, par_n, par_d;
251 result = gst_vc1_parse_sequence_header(
252 rbdu->data + rbdu->offset,
256 if (result != GST_VC1_PARSER_OK) {
257 GST_ERROR("failed to parse sequence layer");
258 return get_status(result);
261 priv->has_entrypoint = FALSE;
263 /* Validate profile */
264 switch (seq_hdr->profile) {
265 case GST_VC1_PROFILE_SIMPLE:
266 case GST_VC1_PROFILE_MAIN:
267 case GST_VC1_PROFILE_ADVANCED:
270 GST_ERROR("unsupported profile %d", seq_hdr->profile);
271 return GST_VAAPI_DECODER_STATUS_ERROR_UNSUPPORTED_PROFILE;
278 switch (seq_hdr->profile) {
279 case GST_VC1_PROFILE_SIMPLE:
280 case GST_VC1_PROFILE_MAIN:
282 fps_n = structc->framerate;
286 case GST_VC1_PROFILE_ADVANCED:
287 fps_n = adv_hdr->fps_n;
288 fps_d = adv_hdr->fps_d;
289 par_n = adv_hdr->par_n;
290 par_d = adv_hdr->par_d;
293 g_assert(0 && "XXX: we already validated the profile above");
298 gst_vaapi_decoder_set_framerate(base_decoder, fps_n, fps_d);
300 if (par_n > 0 && par_d > 0)
301 gst_vaapi_decoder_set_pixel_aspect_ratio(base_decoder, par_n, par_d);
303 switch (seq_hdr->profile) {
304 case GST_VC1_PROFILE_SIMPLE:
305 case GST_VC1_PROFILE_MAIN:
306 width = seq_hdr->struct_c.coded_width;
307 height = seq_hdr->struct_c.coded_height;
309 case GST_VC1_PROFILE_ADVANCED:
310 width = seq_hdr->advanced.max_coded_width;
311 height = seq_hdr->advanced.max_coded_height;
314 g_assert(0 && "XXX: we already validated the profile above");
318 if (priv->width != width) {
320 priv->size_changed = TRUE;
323 if (priv->height != height) {
324 priv->height = height;
325 priv->size_changed = TRUE;
328 switch (seq_hdr->profile) {
329 case GST_VC1_PROFILE_SIMPLE:
330 profile = GST_VAAPI_PROFILE_VC1_SIMPLE;
332 case GST_VC1_PROFILE_MAIN:
333 profile = GST_VAAPI_PROFILE_VC1_MAIN;
335 case GST_VC1_PROFILE_ADVANCED:
336 profile = GST_VAAPI_PROFILE_VC1_ADVANCED;
339 g_assert(0 && "XXX: we already validated the profile above");
342 if (priv->profile != profile) {
343 priv->profile = profile;
344 priv->profile_changed = TRUE;
346 return GST_VAAPI_DECODER_STATUS_SUCCESS;
349 static GstVaapiDecoderStatus
350 decode_sequence_end(GstVaapiDecoderVC1 *decoder)
352 GstVaapiDecoderVC1Private * const priv = decoder->priv;
353 GstVaapiDecoderStatus status;
355 if (priv->current_picture) {
356 status = decode_current_picture(decoder);
357 if (status != GST_VAAPI_DECODER_STATUS_SUCCESS)
359 status = render_picture(decoder, priv->current_picture);
360 if (status != GST_VAAPI_DECODER_STATUS_SUCCESS)
364 if (priv->next_picture) {
365 status = render_picture(decoder, priv->next_picture);
366 if (status != GST_VAAPI_DECODER_STATUS_SUCCESS)
369 return GST_VAAPI_DECODER_STATUS_END_OF_STREAM;
372 static GstVaapiDecoderStatus
373 decode_entry_point(GstVaapiDecoderVC1 *decoder, GstVC1BDU *rbdu, GstVC1BDU *ebdu)
375 GstVaapiDecoderVC1Private * const priv = decoder->priv;
376 GstVC1SeqHdr * const seq_hdr = &priv->seq_hdr;
377 GstVC1EntryPointHdr * const entrypoint_hdr = &priv->entrypoint_hdr;
378 GstVC1ParserResult result;
380 result = gst_vc1_parse_entry_point_header(
381 rbdu->data + rbdu->offset,
386 if (result != GST_VC1_PARSER_OK) {
387 GST_ERROR("failed to parse entrypoint layer");
388 return get_status(result);
391 if (entrypoint_hdr->coded_size_flag) {
392 priv->width = entrypoint_hdr->coded_width;
393 priv->height = entrypoint_hdr->coded_height;
394 priv->size_changed = TRUE;
397 priv->has_entrypoint = TRUE;
398 priv->closed_entry = entrypoint_hdr->closed_entry;
399 priv->broken_link = entrypoint_hdr->broken_link;
400 return GST_VAAPI_DECODER_STATUS_SUCCESS;
403 /* Reconstruct bitstream PTYPE (7.1.1.4, index into Table-35) */
405 get_PTYPE(guint ptype)
408 case GST_VC1_PICTURE_TYPE_I: return 0;
409 case GST_VC1_PICTURE_TYPE_P: return 1;
410 case GST_VC1_PICTURE_TYPE_B: return 2;
411 case GST_VC1_PICTURE_TYPE_BI: return 3;
413 return 4; /* skipped P-frame */
416 /* Reconstruct bitstream BFRACTION (7.1.1.14, index into Table-40) */
418 get_BFRACTION(guint bfraction)
422 static const struct {
427 { 0, GST_VC1_BFRACTION_BASIS / 2 },
428 { 1, GST_VC1_BFRACTION_BASIS / 3 },
429 { 2, (GST_VC1_BFRACTION_BASIS * 2) / 3 },
430 { 3, GST_VC1_BFRACTION_BASIS / 4 },
431 { 4, (GST_VC1_BFRACTION_BASIS * 3) / 4 },
432 { 5, GST_VC1_BFRACTION_BASIS / 5 },
433 { 6, (GST_VC1_BFRACTION_BASIS * 2) / 5 },
434 { 7, (GST_VC1_BFRACTION_BASIS * 3) / 5 },
435 { 8, (GST_VC1_BFRACTION_BASIS * 4) / 5 },
436 { 9, GST_VC1_BFRACTION_BASIS / 6 },
437 { 10, (GST_VC1_BFRACTION_BASIS * 5) / 6 },
438 { 11, GST_VC1_BFRACTION_BASIS / 7 },
439 { 12, (GST_VC1_BFRACTION_BASIS * 2) / 7 },
440 { 13, (GST_VC1_BFRACTION_BASIS * 3) / 7 },
441 { 14, (GST_VC1_BFRACTION_BASIS * 4) / 7 },
442 { 15, (GST_VC1_BFRACTION_BASIS * 5) / 7 },
443 { 16, (GST_VC1_BFRACTION_BASIS * 6) / 7 },
444 { 17, GST_VC1_BFRACTION_BASIS / 8 },
445 { 18, (GST_VC1_BFRACTION_BASIS * 3) / 8 },
446 { 19, (GST_VC1_BFRACTION_BASIS * 5) / 8 },
447 { 20, (GST_VC1_BFRACTION_BASIS * 7) / 8 },
448 { 21, GST_VC1_BFRACTION_RESERVED },
449 { 22, GST_VC1_BFRACTION_PTYPE_BI }
455 for (i = 0; i < G_N_ELEMENTS(bfraction_map); i++) {
456 if (bfraction_map[i].value == bfraction)
457 return bfraction_map[i].index;
459 return 21; /* RESERVED */
462 /* Translate GStreamer MV modes to VA-API */
464 get_VAMvModeVC1(guint mvmode)
467 case GST_VC1_MVMODE_1MV_HPEL_BILINEAR: return VAMvMode1MvHalfPelBilinear;
468 case GST_VC1_MVMODE_1MV: return VAMvMode1Mv;
469 case GST_VC1_MVMODE_1MV_HPEL: return VAMvMode1MvHalfPel;
470 case GST_VC1_MVMODE_MIXED_MV: return VAMvModeMixedMv;
471 case GST_VC1_MVMODE_INTENSITY_COMP: return VAMvModeIntensityCompensation;
476 /* Reconstruct bitstream MVMODE (7.1.1.32) */
478 get_MVMODE(GstVC1FrameHdr *frame_hdr)
482 if (frame_hdr->profile == GST_VC1_PROFILE_ADVANCED)
483 mvmode = frame_hdr->pic.advanced.mvmode;
485 mvmode = frame_hdr->pic.simple.mvmode;
487 if (frame_hdr->ptype == GST_VC1_PICTURE_TYPE_P ||
488 frame_hdr->ptype == GST_VC1_PICTURE_TYPE_B)
489 return get_VAMvModeVC1(mvmode);
493 /* Reconstruct bitstream MVMODE2 (7.1.1.33) */
495 get_MVMODE2(GstVC1FrameHdr *frame_hdr)
497 guint mvmode, mvmode2;
499 if (frame_hdr->profile == GST_VC1_PROFILE_ADVANCED) {
500 mvmode = frame_hdr->pic.advanced.mvmode;
501 mvmode2 = frame_hdr->pic.advanced.mvmode2;
504 mvmode = frame_hdr->pic.simple.mvmode;
505 mvmode2 = frame_hdr->pic.simple.mvmode2;
508 if (frame_hdr->ptype == GST_VC1_PICTURE_TYPE_P &&
509 mvmode == GST_VC1_MVMODE_INTENSITY_COMP)
510 return get_VAMvModeVC1(mvmode2);
515 has_MVTYPEMB_bitplane(GstVaapiDecoderVC1 *decoder)
517 GstVaapiDecoderVC1Private * const priv = decoder->priv;
518 GstVC1SeqHdr * const seq_hdr = &priv->seq_hdr;
519 GstVC1FrameHdr * const frame_hdr = &priv->frame_hdr;
520 guint mvmode, mvmode2;
522 if (seq_hdr->profile == GST_VC1_PROFILE_ADVANCED) {
523 GstVC1PicAdvanced * const pic = &frame_hdr->pic.advanced;
526 mvmode = pic->mvmode;
527 mvmode2 = pic->mvmode2;
530 GstVC1PicSimpleMain * const pic = &frame_hdr->pic.simple;
533 mvmode = pic->mvmode;
534 mvmode2 = pic->mvmode2;
536 return (frame_hdr->ptype == GST_VC1_PICTURE_TYPE_P &&
537 (mvmode == GST_VC1_MVMODE_MIXED_MV ||
538 (mvmode == GST_VC1_MVMODE_INTENSITY_COMP &&
539 mvmode2 == GST_VC1_MVMODE_MIXED_MV)));
543 has_SKIPMB_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_P ||
560 frame_hdr->ptype == GST_VC1_PICTURE_TYPE_B);
564 has_DIRECTMB_bitplane(GstVaapiDecoderVC1 *decoder)
566 GstVaapiDecoderVC1Private * const priv = decoder->priv;
567 GstVC1SeqHdr * const seq_hdr = &priv->seq_hdr;
568 GstVC1FrameHdr * const frame_hdr = &priv->frame_hdr;
570 if (seq_hdr->profile == GST_VC1_PROFILE_ADVANCED) {
571 GstVC1PicAdvanced * const pic = &frame_hdr->pic.advanced;
576 GstVC1PicSimpleMain * const pic = &frame_hdr->pic.simple;
580 return frame_hdr->ptype == GST_VC1_PICTURE_TYPE_B;
584 has_ACPRED_bitplane(GstVaapiDecoderVC1 *decoder)
586 GstVaapiDecoderVC1Private * const priv = decoder->priv;
587 GstVC1SeqHdr * const seq_hdr = &priv->seq_hdr;
588 GstVC1FrameHdr * const frame_hdr = &priv->frame_hdr;
589 GstVC1PicAdvanced * const pic = &frame_hdr->pic.advanced;
591 if (seq_hdr->profile != GST_VC1_PROFILE_ADVANCED)
595 return (frame_hdr->ptype == GST_VC1_PICTURE_TYPE_I ||
596 frame_hdr->ptype == GST_VC1_PICTURE_TYPE_BI);
600 has_OVERFLAGS_bitplane(GstVaapiDecoderVC1 *decoder)
602 GstVaapiDecoderVC1Private * const priv = decoder->priv;
603 GstVC1SeqHdr * const seq_hdr = &priv->seq_hdr;
604 GstVC1EntryPointHdr * const entrypoint_hdr = &priv->entrypoint_hdr;
605 GstVC1FrameHdr * const frame_hdr = &priv->frame_hdr;
606 GstVC1PicAdvanced * const pic = &frame_hdr->pic.advanced;
608 if (seq_hdr->profile != GST_VC1_PROFILE_ADVANCED)
612 return ((frame_hdr->ptype == GST_VC1_PICTURE_TYPE_I ||
613 frame_hdr->ptype == GST_VC1_PICTURE_TYPE_BI) &&
614 (entrypoint_hdr->overlap && frame_hdr->pquant <= 8) &&
615 pic->condover == GST_VC1_CONDOVER_SELECT);
619 pack_bitplanes(GstVaapiBitPlane *bitplane, guint n, const guint8 *bitplanes[3], guint x, guint y, guint stride)
621 const guint dst_index = n / 2;
622 const guint src_index = y * stride + x;
626 v |= bitplanes[0][src_index];
628 v |= bitplanes[1][src_index] << 1;
630 v |= bitplanes[2][src_index] << 2;
631 bitplane->data[dst_index] = (bitplane->data[dst_index] << 4) | v;
635 fill_picture_structc(GstVaapiDecoderVC1 *decoder, GstVaapiPicture *picture)
637 GstVaapiDecoderVC1Private * const priv = decoder->priv;
638 VAPictureParameterBufferVC1 * const pic_param = picture->param;
639 GstVC1SeqStructC * const structc = &priv->seq_hdr.struct_c;
640 GstVC1FrameHdr * const frame_hdr = &priv->frame_hdr;
641 GstVC1PicSimpleMain * const pic = &frame_hdr->pic.simple;
643 /* Fill in VAPictureParameterBufferVC1 (simple/main profile bits) */
644 pic_param->sequence_fields.bits.finterpflag = structc->finterpflag;
645 pic_param->sequence_fields.bits.multires = structc->multires;
646 pic_param->sequence_fields.bits.overlap = structc->overlap;
647 pic_param->sequence_fields.bits.syncmarker = structc->syncmarker;
648 pic_param->sequence_fields.bits.rangered = structc->rangered;
649 pic_param->sequence_fields.bits.max_b_frames = structc->maxbframes;
650 pic_param->conditional_overlap_flag = 0; /* advanced profile only */
651 pic_param->fast_uvmc_flag = structc->fastuvmc;
652 pic_param->b_picture_fraction = get_BFRACTION(pic->bfraction);
653 pic_param->cbp_table = pic->cbptab;
654 pic_param->mb_mode_table = 0; /* XXX: interlaced frame */
655 pic_param->range_reduction_frame = pic->rangeredfrm;
656 pic_param->rounding_control = 0; /* advanced profile only */
657 pic_param->post_processing = 0; /* advanced profile only */
658 pic_param->picture_resolution_index = pic->respic;
659 pic_param->luma_scale = pic->lumscale;
660 pic_param->luma_shift = pic->lumshift;
661 pic_param->raw_coding.flags.mv_type_mb = pic->mvtypemb;
662 pic_param->raw_coding.flags.direct_mb = pic->directmb;
663 pic_param->raw_coding.flags.skip_mb = pic->skipmb;
664 pic_param->bitplane_present.flags.bp_mv_type_mb = has_MVTYPEMB_bitplane(decoder);
665 pic_param->bitplane_present.flags.bp_direct_mb = has_DIRECTMB_bitplane(decoder);
666 pic_param->bitplane_present.flags.bp_skip_mb = has_SKIPMB_bitplane(decoder);
667 pic_param->mv_fields.bits.mv_table = pic->mvtab;
668 pic_param->mv_fields.bits.extended_mv_flag = structc->extended_mv;
669 pic_param->mv_fields.bits.extended_mv_range = pic->mvrange;
670 pic_param->transform_fields.bits.variable_sized_transform_flag = structc->vstransform;
671 pic_param->transform_fields.bits.mb_level_transform_type_flag = pic->ttmbf;
672 pic_param->transform_fields.bits.frame_level_transform_type = pic->ttfrm;
673 pic_param->transform_fields.bits.transform_ac_codingset_idx2 = pic->transacfrm2;
678 fill_picture_advanced(GstVaapiDecoderVC1 *decoder, GstVaapiPicture *picture)
680 GstVaapiDecoderVC1Private * const priv = decoder->priv;
681 VAPictureParameterBufferVC1 * const pic_param = picture->param;
682 GstVC1AdvancedSeqHdr * const adv_hdr = &priv->seq_hdr.advanced;
683 GstVC1EntryPointHdr * const entrypoint_hdr = &priv->entrypoint_hdr;
684 GstVC1FrameHdr * const frame_hdr = &priv->frame_hdr;
685 GstVC1PicAdvanced * const pic = &frame_hdr->pic.advanced;
687 if (!priv->has_entrypoint)
690 /* Fill in VAPictureParameterBufferVC1 (advanced profile bits) */
691 pic_param->sequence_fields.bits.pulldown = adv_hdr->pulldown;
692 pic_param->sequence_fields.bits.interlace = adv_hdr->interlace;
693 pic_param->sequence_fields.bits.tfcntrflag = adv_hdr->tfcntrflag;
694 pic_param->sequence_fields.bits.finterpflag = adv_hdr->finterpflag;
695 pic_param->sequence_fields.bits.psf = adv_hdr->psf;
696 pic_param->sequence_fields.bits.overlap = entrypoint_hdr->overlap;
697 pic_param->entrypoint_fields.bits.broken_link = entrypoint_hdr->broken_link;
698 pic_param->entrypoint_fields.bits.closed_entry = entrypoint_hdr->closed_entry;
699 pic_param->entrypoint_fields.bits.panscan_flag = entrypoint_hdr->panscan_flag;
700 pic_param->entrypoint_fields.bits.loopfilter = entrypoint_hdr->loopfilter;
701 pic_param->conditional_overlap_flag = pic->condover;
702 pic_param->fast_uvmc_flag = entrypoint_hdr->fastuvmc;
703 pic_param->range_mapping_fields.bits.luma_flag = entrypoint_hdr->range_mapy_flag;
704 pic_param->range_mapping_fields.bits.luma = entrypoint_hdr->range_mapy;
705 pic_param->range_mapping_fields.bits.chroma_flag = entrypoint_hdr->range_mapuv_flag;
706 pic_param->range_mapping_fields.bits.chroma = entrypoint_hdr->range_mapuv;
707 pic_param->b_picture_fraction = get_BFRACTION(pic->bfraction);
708 pic_param->cbp_table = pic->cbptab;
709 pic_param->mb_mode_table = 0; /* XXX: interlaced frame */
710 pic_param->range_reduction_frame = 0; /* simple/main profile only */
711 pic_param->rounding_control = pic->rndctrl;
712 pic_param->post_processing = pic->postproc;
713 pic_param->picture_resolution_index = 0; /* simple/main profile only */
714 pic_param->luma_scale = pic->lumscale;
715 pic_param->luma_shift = pic->lumshift;
716 pic_param->picture_fields.bits.frame_coding_mode = pic->fcm;
717 pic_param->picture_fields.bits.top_field_first = pic->tff;
718 pic_param->picture_fields.bits.is_first_field = pic->fcm == 0; /* XXX: interlaced frame */
719 pic_param->picture_fields.bits.intensity_compensation = pic->mvmode == GST_VC1_MVMODE_INTENSITY_COMP;
720 pic_param->raw_coding.flags.mv_type_mb = pic->mvtypemb;
721 pic_param->raw_coding.flags.direct_mb = pic->directmb;
722 pic_param->raw_coding.flags.skip_mb = pic->skipmb;
723 pic_param->raw_coding.flags.ac_pred = pic->acpred;
724 pic_param->raw_coding.flags.overflags = pic->overflags;
725 pic_param->bitplane_present.flags.bp_mv_type_mb = has_MVTYPEMB_bitplane(decoder);
726 pic_param->bitplane_present.flags.bp_direct_mb = has_DIRECTMB_bitplane(decoder);
727 pic_param->bitplane_present.flags.bp_skip_mb = has_SKIPMB_bitplane(decoder);
728 pic_param->bitplane_present.flags.bp_ac_pred = has_ACPRED_bitplane(decoder);
729 pic_param->bitplane_present.flags.bp_overflags = has_OVERFLAGS_bitplane(decoder);
730 pic_param->reference_fields.bits.reference_distance_flag = entrypoint_hdr->refdist_flag;
731 pic_param->mv_fields.bits.mv_table = pic->mvtab;
732 pic_param->mv_fields.bits.extended_mv_flag = entrypoint_hdr->extended_mv;
733 pic_param->mv_fields.bits.extended_mv_range = pic->mvrange;
734 pic_param->mv_fields.bits.extended_dmv_flag = entrypoint_hdr->extended_dmv;
735 pic_param->pic_quantizer_fields.bits.dquant = entrypoint_hdr->dquant;
736 pic_param->pic_quantizer_fields.bits.quantizer = entrypoint_hdr->quantizer;
737 pic_param->transform_fields.bits.variable_sized_transform_flag = entrypoint_hdr->vstransform;
738 pic_param->transform_fields.bits.mb_level_transform_type_flag = pic->ttmbf;
739 pic_param->transform_fields.bits.frame_level_transform_type = pic->ttfrm;
740 pic_param->transform_fields.bits.transform_ac_codingset_idx2 = pic->transacfrm2;
745 fill_picture(GstVaapiDecoderVC1 *decoder, GstVaapiPicture *picture)
747 GstVaapiDecoderVC1Private * const priv = decoder->priv;
748 VAPictureParameterBufferVC1 * const pic_param = picture->param;
749 GstVC1SeqHdr * const seq_hdr = &priv->seq_hdr;
750 GstVC1FrameHdr * const frame_hdr = &priv->frame_hdr;
751 GstVC1VopDquant * const vopdquant = &frame_hdr->vopdquant;
753 /* Fill in VAPictureParameterBufferVC1 (common fields) */
754 pic_param->forward_reference_picture = VA_INVALID_ID;
755 pic_param->backward_reference_picture = VA_INVALID_ID;
756 pic_param->inloop_decoded_picture = VA_INVALID_ID;
757 pic_param->sequence_fields.value = 0;
758 #if VA_CHECK_VERSION(0,32,0)
759 pic_param->sequence_fields.bits.profile = seq_hdr->profile;
761 pic_param->coded_width = priv->width;
762 pic_param->coded_height = priv->height;
763 pic_param->entrypoint_fields.value = 0;
764 pic_param->range_mapping_fields.value = 0;
765 pic_param->picture_fields.value = 0;
766 pic_param->picture_fields.bits.picture_type = get_PTYPE(frame_hdr->ptype);
767 pic_param->raw_coding.value = 0;
768 pic_param->bitplane_present.value = 0;
769 pic_param->reference_fields.value = 0;
770 pic_param->mv_fields.value = 0;
771 pic_param->mv_fields.bits.mv_mode = get_MVMODE(frame_hdr);
772 pic_param->mv_fields.bits.mv_mode2 = get_MVMODE2(frame_hdr);
773 pic_param->pic_quantizer_fields.value = 0;
774 pic_param->pic_quantizer_fields.bits.half_qp = frame_hdr->halfqp;
775 pic_param->pic_quantizer_fields.bits.pic_quantizer_scale = frame_hdr->pquant;
776 pic_param->pic_quantizer_fields.bits.pic_quantizer_type = frame_hdr->pquantizer;
777 pic_param->pic_quantizer_fields.bits.dq_frame = vopdquant->dquantfrm;
778 pic_param->pic_quantizer_fields.bits.dq_profile = vopdquant->dqprofile;
779 pic_param->pic_quantizer_fields.bits.dq_sb_edge = vopdquant->dqprofile == GST_VC1_DQPROFILE_SINGLE_EDGE ? vopdquant->dqbedge : 0;
780 pic_param->pic_quantizer_fields.bits.dq_db_edge = vopdquant->dqprofile == GST_VC1_DQPROFILE_DOUBLE_EDGES ? vopdquant->dqbedge : 0;
781 pic_param->pic_quantizer_fields.bits.dq_binary_level = vopdquant->dqbilevel;
782 pic_param->pic_quantizer_fields.bits.alt_pic_quantizer = vopdquant->altpquant;
783 pic_param->transform_fields.value = 0;
784 pic_param->transform_fields.bits.transform_ac_codingset_idx1 = frame_hdr->transacfrm;
785 pic_param->transform_fields.bits.intra_transform_dc_table = frame_hdr->transdctab;
787 if (seq_hdr->profile == GST_VC1_PROFILE_ADVANCED) {
788 if (!fill_picture_advanced(decoder, picture))
792 if (!fill_picture_structc(decoder, picture))
796 switch (picture->type) {
797 case GST_VAAPI_PICTURE_TYPE_B:
798 if (priv->next_picture)
799 pic_param->backward_reference_picture = priv->next_picture->surface_id;
801 case GST_VAAPI_PICTURE_TYPE_P:
802 if (priv->prev_picture)
803 pic_param->forward_reference_picture = priv->prev_picture->surface_id;
809 if (pic_param->bitplane_present.value) {
810 const guint8 *bitplanes[3];
813 switch (picture->type) {
814 case GST_VAAPI_PICTURE_TYPE_P:
815 bitplanes[0] = pic_param->bitplane_present.flags.bp_direct_mb ? priv->bitplanes->directmb : NULL;
816 bitplanes[1] = pic_param->bitplane_present.flags.bp_skip_mb ? priv->bitplanes->skipmb : NULL;
817 bitplanes[2] = pic_param->bitplane_present.flags.bp_mv_type_mb ? priv->bitplanes->mvtypemb : NULL;
819 case GST_VAAPI_PICTURE_TYPE_B:
820 bitplanes[0] = pic_param->bitplane_present.flags.bp_direct_mb ? priv->bitplanes->directmb : NULL;
821 bitplanes[1] = pic_param->bitplane_present.flags.bp_skip_mb ? priv->bitplanes->skipmb : NULL;
822 bitplanes[2] = NULL; /* XXX: interlaced frame (FORWARD plane) */
824 case GST_VAAPI_PICTURE_TYPE_BI:
825 case GST_VAAPI_PICTURE_TYPE_I:
826 bitplanes[0] = NULL; /* XXX: interlaced frame (FIELDTX plane) */
827 bitplanes[1] = pic_param->bitplane_present.flags.bp_ac_pred ? priv->bitplanes->acpred : NULL;
828 bitplanes[2] = pic_param->bitplane_present.flags.bp_overflags ? priv->bitplanes->overflags : NULL;
837 picture->bitplane = GST_VAAPI_BITPLANE_NEW(
839 (seq_hdr->mb_width * seq_hdr->mb_height + 1) / 2
841 if (!picture->bitplane)
845 for (y = 0; y < seq_hdr->mb_height; y++)
846 for (x = 0; x < seq_hdr->mb_width; x++, n++)
847 pack_bitplanes(picture->bitplane, n, bitplanes, x, y, seq_hdr->mb_stride);
848 if (n & 1) /* move last nibble to the high order */
849 picture->bitplane->data[n/2] <<= 4;
854 static GstVaapiDecoderStatus
855 decode_frame(GstVaapiDecoderVC1 *decoder, GstVC1BDU *rbdu, GstVC1BDU *ebdu)
857 GstVaapiDecoderVC1Private * const priv = decoder->priv;
858 GstVC1SeqHdr * const seq_hdr = &priv->seq_hdr;
859 GstVC1FrameHdr * const frame_hdr = &priv->frame_hdr;
860 GstVC1ParserResult result;
861 GstVaapiPicture *picture;
862 GstVaapiSlice *slice;
863 GstVaapiDecoderStatus status;
864 VASliceParameterBufferVC1 *slice_param;
867 status = ensure_context(decoder);
868 if (status != GST_VAAPI_DECODER_STATUS_SUCCESS) {
869 GST_ERROR("failed to reset context");
873 if (priv->current_picture) {
874 status = decode_current_picture(decoder);
875 if (status != GST_VAAPI_DECODER_STATUS_SUCCESS)
879 priv->current_picture = GST_VAAPI_PICTURE_NEW(VC1, decoder);
880 if (!priv->current_picture) {
881 GST_ERROR("failed to allocate picture");
882 return GST_VAAPI_DECODER_STATUS_ERROR_ALLOCATION_FAILED;
884 picture = priv->current_picture;
886 if (!gst_vc1_bitplanes_ensure_size(priv->bitplanes, seq_hdr)) {
887 GST_ERROR("failed to allocate bitplanes");
888 return GST_VAAPI_DECODER_STATUS_ERROR_ALLOCATION_FAILED;
891 memset(frame_hdr, 0, sizeof(*frame_hdr));
892 result = gst_vc1_parse_frame_header(
893 rbdu->data + rbdu->offset,
899 if (result != GST_VC1_PARSER_OK) {
900 GST_ERROR("failed to parse frame layer");
901 return get_status(result);
904 switch (frame_hdr->ptype) {
905 case GST_VC1_PICTURE_TYPE_I:
906 picture->type = GST_VAAPI_PICTURE_TYPE_I;
907 GST_VAAPI_PICTURE_FLAG_SET(picture, GST_VAAPI_PICTURE_FLAG_REFERENCE);
909 case GST_VC1_PICTURE_TYPE_SKIPPED:
910 case GST_VC1_PICTURE_TYPE_P:
911 picture->type = GST_VAAPI_PICTURE_TYPE_P;
912 GST_VAAPI_PICTURE_FLAG_SET(picture, GST_VAAPI_PICTURE_FLAG_REFERENCE);
914 case GST_VC1_PICTURE_TYPE_B:
915 picture->type = GST_VAAPI_PICTURE_TYPE_B;
917 case GST_VC1_PICTURE_TYPE_BI:
918 picture->type = GST_VAAPI_PICTURE_TYPE_BI;
921 GST_ERROR("unsupported picture type %d", frame_hdr->ptype);
922 return GST_VAAPI_DECODER_STATUS_ERROR_UNKNOWN;
925 /* Update presentation time */
926 pts = gst_adapter_prev_timestamp(priv->adapter, NULL);
929 /* Update reference pictures */
930 if (GST_VAAPI_PICTURE_IS_REFERENCE(picture)) {
931 if (priv->next_picture)
932 status = render_picture(decoder, priv->next_picture);
933 gst_vaapi_picture_replace(&priv->prev_picture, priv->next_picture);
934 gst_vaapi_picture_replace(&priv->next_picture, picture);
937 if (!fill_picture(decoder, picture))
938 return GST_VAAPI_DECODER_STATUS_ERROR_UNKNOWN;
940 slice = GST_VAAPI_SLICE_NEW(
943 ebdu->data + ebdu->sc_offset,
944 ebdu->size + ebdu->offset - ebdu->sc_offset
947 GST_ERROR("failed to allocate slice");
948 return GST_VAAPI_DECODER_STATUS_ERROR_ALLOCATION_FAILED;
950 gst_vaapi_picture_add_slice(picture, slice);
952 /* Fill in VASliceParameterBufferVC1 */
953 slice_param = slice->param;
954 slice_param->macroblock_offset = 8 * (ebdu->offset - ebdu->sc_offset) + frame_hdr->header_size;
955 slice_param->slice_vertical_position = 0;
957 /* Decode picture right away, we got the full frame */
958 return decode_current_picture(decoder);
962 decode_rbdu(GstVaapiDecoderVC1 *decoder, GstVC1BDU *rbdu, GstVC1BDU *ebdu)
964 GstVaapiDecoderVC1Private * const priv = decoder->priv;
966 guint i, j, rbdu_buffer_size;
968 /* BDU are encapsulated in advanced profile mode only */
969 if (priv->profile != GST_VAAPI_PROFILE_VC1_ADVANCED) {
970 memcpy(rbdu, ebdu, sizeof(*rbdu));
974 /* Reallocate unescaped bitstream buffer */
975 rbdu_buffer = priv->rbdu_buffer;
976 if (!rbdu_buffer || ebdu->size > priv->rbdu_buffer_size) {
977 rbdu_buffer = g_realloc(priv->rbdu_buffer, ebdu->size);
980 priv->rbdu_buffer = rbdu_buffer;
981 priv->rbdu_buffer_size = ebdu->size;
984 /* Unescape bitstream buffer */
985 if (ebdu->size < 4) {
986 memcpy(rbdu_buffer, ebdu->data + ebdu->offset, ebdu->size);
987 rbdu_buffer_size = ebdu->size;
990 guint8 * const bdu_buffer = ebdu->data + ebdu->offset;
991 for (i = 0, j = 0; i < ebdu->size; i++) {
992 if (i >= 2 && i < ebdu->size - 1 &&
993 bdu_buffer[i - 1] == 0x00 &&
994 bdu_buffer[i - 2] == 0x00 &&
995 bdu_buffer[i ] == 0x03 &&
996 bdu_buffer[i + 1] <= 0x03)
998 rbdu_buffer[j++] = bdu_buffer[i];
1000 rbdu_buffer_size = j;
1003 /* Reconstruct RBDU */
1004 rbdu->type = ebdu->type;
1005 rbdu->size = rbdu_buffer_size;
1006 rbdu->sc_offset = 0;
1008 rbdu->data = rbdu_buffer;
1012 static GstVaapiDecoderStatus
1013 decode_ebdu(GstVaapiDecoderVC1 *decoder, GstVC1BDU *ebdu)
1015 GstVaapiDecoderStatus status;
1018 if (!decode_rbdu(decoder, &rbdu, ebdu))
1019 return GST_VAAPI_DECODER_STATUS_ERROR_ALLOCATION_FAILED;
1021 switch (ebdu->type) {
1022 case GST_VC1_SEQUENCE:
1023 status = decode_sequence(decoder, &rbdu, ebdu);
1025 case GST_VC1_ENTRYPOINT:
1026 status = decode_entry_point(decoder, &rbdu, ebdu);
1029 status = decode_frame(decoder, &rbdu, ebdu);
1032 GST_DEBUG("decode slice");
1033 status = GST_VAAPI_DECODER_STATUS_ERROR_BITSTREAM_PARSER;
1035 case GST_VC1_END_OF_SEQ:
1036 status = decode_sequence_end(decoder);
1039 GST_WARNING("unsupported BDU type %d", ebdu->type);
1040 status = GST_VAAPI_DECODER_STATUS_ERROR_BITSTREAM_PARSER;
1046 static GstVaapiDecoderStatus
1047 decode_buffer(GstVaapiDecoderVC1 *decoder, GstBuffer *buffer)
1049 GstVaapiDecoderVC1Private * const priv = decoder->priv;
1050 GstVaapiDecoderStatus status;
1051 GstVC1ParserResult result;
1053 GstBuffer *codec_data;
1055 guint buf_size, ofs;
1057 buf = GST_BUFFER_DATA(buffer);
1058 buf_size = GST_BUFFER_SIZE(buffer);
1059 if (!buf && buf_size == 0)
1060 return decode_sequence_end(decoder);
1062 gst_buffer_ref(buffer);
1063 gst_adapter_push(priv->adapter, buffer);
1065 /* Assume demuxer sends out plain frames if codec-data */
1066 codec_data = GST_VAAPI_DECODER_CODEC_DATA(decoder);
1067 if (codec_data && codec_data != buffer) {
1068 ebdu.type = GST_VC1_FRAME;
1069 ebdu.size = buf_size;
1073 status = decode_ebdu(decoder, &ebdu);
1075 if (gst_adapter_available(priv->adapter) >= buf_size)
1076 gst_adapter_flush(priv->adapter, buf_size);
1080 if (priv->sub_buffer) {
1081 buffer = gst_buffer_merge(priv->sub_buffer, buffer);
1083 return GST_VAAPI_DECODER_STATUS_ERROR_ALLOCATION_FAILED;
1084 gst_buffer_unref(priv->sub_buffer);
1085 priv->sub_buffer = NULL;
1088 buf = GST_BUFFER_DATA(buffer);
1089 buf_size = GST_BUFFER_SIZE(buffer);
1092 result = gst_vc1_identify_next_bdu(
1097 status = get_status(result);
1099 if (status == GST_VAAPI_DECODER_STATUS_ERROR_NO_DATA) {
1100 priv->sub_buffer = gst_buffer_create_sub(buffer, ofs, buf_size - ofs);
1103 if (status != GST_VAAPI_DECODER_STATUS_SUCCESS)
1106 ofs += ebdu.offset + ebdu.size;
1107 if (gst_adapter_available(priv->adapter) >= ebdu.offset)
1108 gst_adapter_flush(priv->adapter, ebdu.offset);
1110 status = decode_ebdu(decoder, &ebdu);
1111 if (gst_adapter_available(priv->adapter) >= ebdu.size)
1112 gst_adapter_flush(priv->adapter, ebdu.size);
1113 } while (status == GST_VAAPI_DECODER_STATUS_SUCCESS);
1117 static GstVaapiDecoderStatus
1118 decode_codec_data(GstVaapiDecoderVC1 *decoder, GstBuffer *buffer)
1120 GstVaapiDecoderVC1Private * const priv = decoder->priv;
1121 GstVC1SeqHdr * const seq_hdr = &priv->seq_hdr;
1122 GstVaapiDecoderStatus status;
1123 GstVC1ParserResult result;
1126 GstStructure *structure;
1128 guint buf_size, ofs;
1132 buf = GST_BUFFER_DATA(buffer);
1133 buf_size = GST_BUFFER_SIZE(buffer);
1134 if (!buf || buf_size == 0)
1135 return GST_VAAPI_DECODER_STATUS_SUCCESS;
1137 caps = GST_VAAPI_DECODER_CAST(decoder)->priv->caps;
1138 structure = gst_caps_get_structure(caps, 0);
1140 if (!gst_structure_get_int(structure, "width", &width) ||
1141 !gst_structure_get_int(structure, "height", &height)) {
1142 GST_ERROR("failed to parse size from codec-data");
1143 return GST_VAAPI_DECODER_STATUS_ERROR_UNKNOWN;
1146 if (!gst_structure_get_fourcc(structure, "format", &format)) {
1147 GST_ERROR("failed to parse profile from codec-data");
1148 return GST_VAAPI_DECODER_STATUS_ERROR_UNSUPPORTED_CODEC;
1151 /* WMV3 -- expecting sequence header */
1152 if (format == GST_MAKE_FOURCC('W','M','V','3')) {
1153 seq_hdr->struct_c.coded_width = width;
1154 seq_hdr->struct_c.coded_height = height;
1155 ebdu.type = GST_VC1_SEQUENCE;
1156 ebdu.size = buf_size;
1160 return decode_ebdu(decoder, &ebdu);
1163 /* WVC1 -- expecting bitstream data units */
1164 if (format != GST_MAKE_FOURCC('W','V','C','1'))
1165 return GST_VAAPI_DECODER_STATUS_ERROR_UNSUPPORTED_PROFILE;
1166 seq_hdr->advanced.max_coded_width = width;
1167 seq_hdr->advanced.max_coded_height = height;
1171 result = gst_vc1_identify_next_bdu(
1178 case GST_VC1_PARSER_NO_BDU_END:
1179 /* Assume the EBDU is complete within codec-data bounds */
1180 ebdu.size = buf_size - ofs - (ebdu.offset - ebdu.sc_offset);
1182 case GST_VC1_PARSER_OK:
1183 status = decode_ebdu(decoder, &ebdu);
1184 ofs += ebdu.offset + ebdu.size;
1187 status = get_status(result);
1190 } while (status == GST_VAAPI_DECODER_STATUS_SUCCESS && ofs < buf_size);
1194 GstVaapiDecoderStatus
1195 gst_vaapi_decoder_vc1_decode(GstVaapiDecoder *base, GstBuffer *buffer)
1197 GstVaapiDecoderVC1 * const decoder = GST_VAAPI_DECODER_VC1(base);
1198 GstVaapiDecoderVC1Private * const priv = decoder->priv;
1199 GstVaapiDecoderStatus status;
1200 GstBuffer *codec_data;
1202 g_return_val_if_fail(priv->is_constructed,
1203 GST_VAAPI_DECODER_STATUS_ERROR_INIT_FAILED);
1205 if (!priv->is_opened) {
1206 priv->is_opened = gst_vaapi_decoder_vc1_open(decoder, buffer);
1207 if (!priv->is_opened)
1208 return GST_VAAPI_DECODER_STATUS_ERROR_UNSUPPORTED_CODEC;
1210 codec_data = GST_VAAPI_DECODER_CODEC_DATA(decoder);
1212 status = decode_codec_data(decoder, codec_data);
1213 if (status != GST_VAAPI_DECODER_STATUS_SUCCESS)
1217 return decode_buffer(decoder, buffer);
1221 gst_vaapi_decoder_vc1_finalize(GObject *object)
1223 GstVaapiDecoderVC1 * const decoder = GST_VAAPI_DECODER_VC1(object);
1225 gst_vaapi_decoder_vc1_destroy(decoder);
1227 G_OBJECT_CLASS(gst_vaapi_decoder_vc1_parent_class)->finalize(object);
1231 gst_vaapi_decoder_vc1_constructed(GObject *object)
1233 GstVaapiDecoderVC1 * const decoder = GST_VAAPI_DECODER_VC1(object);
1234 GstVaapiDecoderVC1Private * const priv = decoder->priv;
1235 GObjectClass *parent_class;
1237 parent_class = G_OBJECT_CLASS(gst_vaapi_decoder_vc1_parent_class);
1238 if (parent_class->constructed)
1239 parent_class->constructed(object);
1241 priv->is_constructed = gst_vaapi_decoder_vc1_create(decoder);
1245 gst_vaapi_decoder_vc1_class_init(GstVaapiDecoderVC1Class *klass)
1247 GObjectClass * const object_class = G_OBJECT_CLASS(klass);
1248 GstVaapiDecoderClass * const decoder_class = GST_VAAPI_DECODER_CLASS(klass);
1250 g_type_class_add_private(klass, sizeof(GstVaapiDecoderVC1Private));
1252 object_class->finalize = gst_vaapi_decoder_vc1_finalize;
1253 object_class->constructed = gst_vaapi_decoder_vc1_constructed;
1255 decoder_class->decode = gst_vaapi_decoder_vc1_decode;
1259 gst_vaapi_decoder_vc1_init(GstVaapiDecoderVC1 *decoder)
1261 GstVaapiDecoderVC1Private *priv;
1263 priv = GST_VAAPI_DECODER_VC1_GET_PRIVATE(decoder);
1264 decoder->priv = priv;
1267 priv->profile = (GstVaapiProfile)0;
1268 priv->current_picture = NULL;
1269 priv->next_picture = NULL;
1270 priv->prev_picture = NULL;
1271 priv->adapter = NULL;
1272 priv->sub_buffer = NULL;
1273 priv->rbdu_buffer = NULL;
1274 priv->rbdu_buffer_size = 0;
1275 priv->is_constructed = FALSE;
1276 priv->is_opened = FALSE;
1277 priv->is_first_field = FALSE;
1278 priv->has_entrypoint = FALSE;
1279 priv->size_changed = FALSE;
1280 priv->profile_changed = FALSE;
1281 priv->closed_entry = FALSE;
1282 priv->broken_link = FALSE;
1286 * gst_vaapi_decoder_vc1_new:
1287 * @display: a #GstVaapiDisplay
1288 * @caps: a #GstCaps holding codec information
1290 * Creates a new #GstVaapiDecoder for VC-1 decoding. The @caps can
1291 * hold extra information like codec-data and pictured coded size.
1293 * Return value: the newly allocated #GstVaapiDecoder object
1296 gst_vaapi_decoder_vc1_new(GstVaapiDisplay *display, GstCaps *caps)
1298 GstVaapiDecoderVC1 *decoder;
1300 g_return_val_if_fail(GST_VAAPI_IS_DISPLAY(display), NULL);
1301 g_return_val_if_fail(GST_IS_CAPS(caps), NULL);
1303 decoder = g_object_new(
1304 GST_VAAPI_TYPE_DECODER_VC1,
1309 if (!decoder->priv->is_constructed) {
1310 g_object_unref(decoder);
1313 return GST_VAAPI_DECODER_CAST(decoder);