2 * gstvaapidecoder_h264.c - H.264 decoder
4 * Copyright (C) 2011-2012 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_h264
24 * @short_description: H.264 decoder
29 #include <gst/base/gstadapter.h>
30 #include <gst/codecparsers/gsth264parser.h>
31 #include "gstvaapidecoder_h264.h"
32 #include "gstvaapidecoder_objects.h"
33 #include "gstvaapidecoder_priv.h"
34 #include "gstvaapidisplay_priv.h"
35 #include "gstvaapiobject_priv.h"
38 #include "gstvaapidebug.h"
40 /* Defined to 1 if strict ordering of DPB is needed. Only useful for debug */
41 #define USE_STRICT_DPB_ORDERING 0
43 typedef struct _GstVaapiPictureH264 GstVaapiPictureH264;
44 typedef struct _GstVaapiPictureH264Class GstVaapiPictureH264Class;
45 typedef struct _GstVaapiSliceH264 GstVaapiSliceH264;
46 typedef struct _GstVaapiSliceH264Class GstVaapiSliceH264Class;
48 /* ------------------------------------------------------------------------- */
49 /* --- H.264 Pictures --- */
50 /* ------------------------------------------------------------------------- */
52 #define GST_VAAPI_TYPE_PICTURE_H264 \
53 (gst_vaapi_picture_h264_get_type())
55 #define GST_VAAPI_PICTURE_H264_CAST(obj) \
56 ((GstVaapiPictureH264 *)(obj))
58 #define GST_VAAPI_PICTURE_H264(obj) \
59 (G_TYPE_CHECK_INSTANCE_CAST((obj), \
60 GST_VAAPI_TYPE_PICTURE_H264, \
63 #define GST_VAAPI_PICTURE_H264_CLASS(klass) \
64 (G_TYPE_CHECK_CLASS_CAST((klass), \
65 GST_VAAPI_TYPE_PICTURE_H264, \
66 GstVaapiPictureH264Class))
68 #define GST_VAAPI_IS_PICTURE_H264(obj) \
69 (G_TYPE_CHECK_INSTANCE_TYPE((obj), GST_VAAPI_TYPE_PICTURE_H264))
71 #define GST_VAAPI_IS_PICTURE_H264_CLASS(klass) \
72 (G_TYPE_CHECK_CLASS_TYPE((klass), GST_VAAPI_TYPE_PICTURE_H264))
74 #define GST_VAAPI_PICTURE_H264_GET_CLASS(obj) \
75 (G_TYPE_INSTANCE_GET_CLASS((obj), \
76 GST_VAAPI_TYPE_PICTURE_H264, \
77 GstVaapiPictureH264Class))
80 * Extended picture flags:
82 * @GST_VAAPI_PICTURE_FLAG_IDR: flag that specifies an IDR picture
85 GST_VAAPI_PICTURE_FLAG_IDR = (GST_VAAPI_PICTURE_FLAG_LAST << 0),
88 #define GST_VAAPI_PICTURE_IS_IDR(picture) \
89 (GST_VAAPI_PICTURE_FLAG_IS_SET(picture, GST_VAAPI_PICTURE_FLAG_IDR))
91 struct _GstVaapiPictureH264 {
96 gint32 frame_num; // Original frame_num from slice_header()
97 gint32 frame_num_wrap; // Temporary for ref pic marking: FrameNumWrap
98 gint32 pic_num; // Temporary for ref pic marking: PicNum
99 gint32 long_term_pic_num; // Temporary for ref pic marking: LongTermPicNum
100 guint is_long_term : 1;
101 guint output_flag : 1;
102 guint output_needed : 1;
105 struct _GstVaapiPictureH264Class {
107 GstVaapiPictureClass parent_class;
110 GST_VAAPI_CODEC_DEFINE_TYPE(GstVaapiPictureH264,
111 gst_vaapi_picture_h264,
112 GST_VAAPI_TYPE_PICTURE)
115 gst_vaapi_picture_h264_destroy(GstVaapiPictureH264 *decoder)
120 gst_vaapi_picture_h264_create(
121 GstVaapiPictureH264 *picture,
122 const GstVaapiCodecObjectConstructorArgs *args
129 gst_vaapi_picture_h264_init(GstVaapiPictureH264 *picture)
131 VAPictureH264 *va_pic;
133 va_pic = &picture->info;
135 va_pic->TopFieldOrderCnt = 0;
136 va_pic->BottomFieldOrderCnt = 0;
139 picture->is_long_term = FALSE;
140 picture->output_needed = FALSE;
143 static inline GstVaapiPictureH264 *
144 gst_vaapi_picture_h264_new(GstVaapiDecoderH264 *decoder)
146 GstVaapiCodecObject *object;
148 g_return_val_if_fail(GST_VAAPI_IS_DECODER(decoder), NULL);
150 object = gst_vaapi_codec_object_new(
151 GST_VAAPI_TYPE_PICTURE_H264,
152 GST_VAAPI_CODEC_BASE(decoder),
153 NULL, sizeof(VAPictureParameterBufferH264),
158 return GST_VAAPI_PICTURE_H264_CAST(object);
161 static inline GstVaapiSliceH264 *
162 gst_vaapi_picture_h264_get_last_slice(GstVaapiPictureH264 *picture)
164 g_return_val_if_fail(GST_VAAPI_IS_PICTURE_H264(picture), NULL);
166 if (G_UNLIKELY(picture->base.slices->len < 1))
168 return g_ptr_array_index(picture->base.slices,
169 picture->base.slices->len - 1);
172 /* ------------------------------------------------------------------------- */
174 /* ------------------------------------------------------------------------- */
176 #define GST_VAAPI_TYPE_SLICE_H264 \
177 (gst_vaapi_slice_h264_get_type())
179 #define GST_VAAPI_SLICE_H264_CAST(obj) \
180 ((GstVaapiSliceH264 *)(obj))
182 #define GST_VAAPI_SLICE_H264(obj) \
183 (G_TYPE_CHECK_INSTANCE_CAST((obj), \
184 GST_VAAPI_TYPE_SLICE_H264, \
187 #define GST_VAAPI_SLICE_H264_CLASS(klass) \
188 (G_TYPE_CHECK_CLASS_CAST((klass), \
189 GST_VAAPI_TYPE_SLICE_H264, \
190 GstVaapiSliceH264Class))
192 #define GST_VAAPI_IS_SLICE_H264(obj) \
193 (G_TYPE_CHECK_INSTANCE_TYPE((obj), GST_VAAPI_TYPE_SLICE_H264))
195 #define GST_VAAPI_IS_SLICE_H264_CLASS(klass) \
196 (G_TYPE_CHECK_CLASS_TYPE((klass), GST_VAAPI_TYPE_SLICE_H264))
198 #define GST_VAAPI_SLICE_H264_GET_CLASS(obj) \
199 (G_TYPE_INSTANCE_GET_CLASS((obj), \
200 GST_VAAPI_TYPE_SLICE_H264, \
201 GstVaapiSliceH264Class))
203 struct _GstVaapiSliceH264 {
205 GstH264SliceHdr slice_hdr; // parsed slice_header()
208 struct _GstVaapiSliceH264Class {
210 GstVaapiSliceClass parent_class;
213 GST_VAAPI_CODEC_DEFINE_TYPE(GstVaapiSliceH264,
214 gst_vaapi_slice_h264,
215 GST_VAAPI_TYPE_SLICE)
218 gst_vaapi_slice_h264_destroy(GstVaapiSliceH264 *slice)
223 gst_vaapi_slice_h264_create(
224 GstVaapiSliceH264 *slice,
225 const GstVaapiCodecObjectConstructorArgs *args
232 gst_vaapi_slice_h264_init(GstVaapiSliceH264 *slice)
236 static inline GstVaapiSliceH264 *
237 gst_vaapi_slice_h264_new(
238 GstVaapiDecoderH264 *decoder,
243 GstVaapiCodecObject *object;
245 g_return_val_if_fail(GST_VAAPI_IS_DECODER(decoder), NULL);
247 object = gst_vaapi_codec_object_new(
248 GST_VAAPI_TYPE_SLICE_H264,
249 GST_VAAPI_CODEC_BASE(decoder),
250 NULL, sizeof(VASliceParameterBufferH264),
255 return GST_VAAPI_SLICE_H264_CAST(object);
258 /* ------------------------------------------------------------------------- */
259 /* --- H.264 Decoder --- */
260 /* ------------------------------------------------------------------------- */
262 G_DEFINE_TYPE(GstVaapiDecoderH264,
263 gst_vaapi_decoder_h264,
264 GST_VAAPI_TYPE_DECODER)
266 #define GST_VAAPI_DECODER_H264_GET_PRIVATE(obj) \
267 (G_TYPE_INSTANCE_GET_PRIVATE((obj), \
268 GST_VAAPI_TYPE_DECODER_H264, \
269 GstVaapiDecoderH264Private))
271 // Used for field_poc[]
273 #define BOTTOM_FIELD 1
275 struct _GstVaapiDecoderH264Private {
277 GstH264NalParser *parser;
278 /* Last decoded SPS. May not be the last activated one. Just here because
279 it may not fit stack memory allocation in decode_sps() */
281 /* Last decoded PPS. May not be the last activated one. Just here because
282 it may not fit stack memory allocation in decode_pps() */
284 GstVaapiPictureH264 *current_picture;
285 GstVaapiPictureH264 *dpb[16];
288 GstVaapiProfile profile;
289 GstVaapiEntrypoint entrypoint;
290 GstVaapiChromaType chroma_type;
291 GstVaapiPictureH264 *short_ref[32];
292 guint short_ref_count;
293 GstVaapiPictureH264 *long_ref[32];
294 guint long_ref_count;
295 GstVaapiPictureH264 *RefPicList0[32];
296 guint RefPicList0_count;
297 GstVaapiPictureH264 *RefPicList1[32];
298 guint RefPicList1_count;
299 guint nal_length_size;
302 gint32 field_poc[2]; // 0:TopFieldOrderCnt / 1:BottomFieldOrderCnt
303 gint32 poc_msb; // PicOrderCntMsb
304 gint32 poc_lsb; // pic_order_cnt_lsb (from slice_header())
305 gint32 prev_poc_msb; // prevPicOrderCntMsb
306 gint32 prev_poc_lsb; // prevPicOrderCntLsb
307 gint32 frame_num_offset; // FrameNumOffset
308 gint32 frame_num; // frame_num (from slice_header())
309 gint32 prev_frame_num; // prevFrameNum
310 gboolean prev_pic_has_mmco5; // prevMmco5Pic
311 gboolean prev_pic_structure; // previous picture structure
312 guint is_constructed : 1;
315 guint has_context : 1;
319 decode_picture_end(GstVaapiDecoderH264 *decoder, GstVaapiPictureH264 *picture);
323 GstVaapiDecoderH264 *decoder,
324 GstVaapiPictureH264 **pictures,
328 /* Get number of reference frames to use */
330 get_max_dec_frame_buffering(GstH264SPS *sps)
332 guint max_dec_frame_buffering, MaxDpbMbs, PicSizeMbs;
334 /* Table A-1 - Level limits */
335 switch (sps->level_idc) {
336 case 10: MaxDpbMbs = 396; break;
337 case 11: MaxDpbMbs = 900; break;
338 case 12: MaxDpbMbs = 2376; break;
339 case 13: MaxDpbMbs = 2376; break;
340 case 20: MaxDpbMbs = 2376; break;
341 case 21: MaxDpbMbs = 4752; break;
342 case 22: MaxDpbMbs = 8100; break;
343 case 30: MaxDpbMbs = 8100; break;
344 case 31: MaxDpbMbs = 18000; break;
345 case 32: MaxDpbMbs = 20480; break;
346 case 40: MaxDpbMbs = 32768; break;
347 case 41: MaxDpbMbs = 32768; break;
348 case 42: MaxDpbMbs = 34816; break;
349 case 50: MaxDpbMbs = 110400; break;
350 case 51: MaxDpbMbs = 184320; break;
352 g_assert(0 && "unhandled level");
356 PicSizeMbs = ((sps->pic_width_in_mbs_minus1 + 1) *
357 (sps->pic_height_in_map_units_minus1 + 1) *
358 (sps->frame_mbs_only_flag ? 1 : 2));
359 max_dec_frame_buffering = MaxDpbMbs / PicSizeMbs;
362 if (sps->vui_parameters_present_flag) {
363 GstH264VUIParams * const vui_params = &sps->vui_parameters;
364 if (vui_params->bitstream_restriction_flag)
365 max_dec_frame_buffering = vui_params->max_dec_frame_buffering;
367 switch (sps->profile_idc) {
368 case 44: // CAVLC 4:4:4 Intra profile
369 case 86: // Scalable High profile
370 case 100: // High profile
371 case 110: // High 10 profile
372 case 122: // High 4:2:2 profile
373 case 244: // High 4:4:4 Predictive profile
374 if (sps->constraint_set3_flag)
375 max_dec_frame_buffering = 0;
381 if (max_dec_frame_buffering > 16)
382 max_dec_frame_buffering = 16;
383 else if (max_dec_frame_buffering < sps->num_ref_frames)
384 max_dec_frame_buffering = sps->num_ref_frames;
385 return MAX(1, max_dec_frame_buffering);
389 dpb_remove_index(GstVaapiDecoderH264 *decoder, guint index)
391 GstVaapiDecoderH264Private * const priv = decoder->priv;
392 guint i, num_pictures = --priv->dpb_count;
394 if (USE_STRICT_DPB_ORDERING) {
395 for (i = index; i < num_pictures; i++)
396 gst_vaapi_picture_replace(&priv->dpb[i], priv->dpb[i + 1]);
398 else if (index != num_pictures)
399 gst_vaapi_picture_replace(&priv->dpb[index], priv->dpb[num_pictures]);
400 gst_vaapi_picture_replace(&priv->dpb[num_pictures], NULL);
403 static inline gboolean
404 dpb_output(GstVaapiDecoderH264 *decoder, GstVaapiPictureH264 *picture)
406 /* XXX: update cropping rectangle */
407 picture->output_needed = FALSE;
408 return gst_vaapi_picture_output(GST_VAAPI_PICTURE_CAST(picture));
412 dpb_bump(GstVaapiDecoderH264 *decoder)
414 GstVaapiDecoderH264Private * const priv = decoder->priv;
415 guint i, lowest_poc_index;
418 for (i = 0; i < priv->dpb_count; i++) {
419 if (priv->dpb[i]->output_needed)
422 if (i == priv->dpb_count)
425 lowest_poc_index = i++;
426 for (; i < priv->dpb_count; i++) {
427 GstVaapiPictureH264 * const picture = priv->dpb[i];
428 if (picture->output_needed && picture->poc < priv->dpb[lowest_poc_index]->poc)
429 lowest_poc_index = i;
432 success = dpb_output(decoder, priv->dpb[lowest_poc_index]);
433 if (!GST_VAAPI_PICTURE_IS_REFERENCE(priv->dpb[lowest_poc_index]))
434 dpb_remove_index(decoder, lowest_poc_index);
439 dpb_flush(GstVaapiDecoderH264 *decoder)
441 GstVaapiDecoderH264Private * const priv = decoder->priv;
443 while (dpb_bump(decoder))
445 clear_references(decoder, priv->dpb, &priv->dpb_count);
449 dpb_add(GstVaapiDecoderH264 *decoder, GstVaapiPictureH264 *picture)
451 GstVaapiDecoderH264Private * const priv = decoder->priv;
454 // Remove all unused pictures
455 if (GST_VAAPI_PICTURE_IS_IDR(picture))
459 while (i < priv->dpb_count) {
460 GstVaapiPictureH264 * const picture = priv->dpb[i];
461 if (!picture->output_needed &&
462 !GST_VAAPI_PICTURE_IS_REFERENCE(picture))
463 dpb_remove_index(decoder, i);
469 // C.4.5.1 - Storage and marking of a reference decoded picture into the DPB
470 if (GST_VAAPI_PICTURE_IS_REFERENCE(picture)) {
471 while (priv->dpb_count == priv->dpb_size) {
472 if (!dpb_bump(decoder))
475 gst_vaapi_picture_replace(&priv->dpb[priv->dpb_count++], picture);
476 if (picture->output_flag)
477 picture->output_needed = TRUE;
480 // C.4.5.2 - Storage and marking of a non-reference decoded picture into the DPB
482 if (!picture->output_flag)
484 while (priv->dpb_count == priv->dpb_size) {
485 for (i = 0; i < priv->dpb_count; i++) {
486 if (priv->dpb[i]->output_needed &&
487 priv->dpb[i]->poc < picture->poc)
490 if (i == priv->dpb_count)
491 return dpb_output(decoder, picture);
492 if (!dpb_bump(decoder))
495 gst_vaapi_picture_replace(&priv->dpb[priv->dpb_count++], picture);
496 picture->output_needed = TRUE;
502 dpb_reset(GstVaapiDecoderH264 *decoder, GstH264SPS *sps)
504 GstVaapiDecoderH264Private * const priv = decoder->priv;
506 priv->dpb_size = get_max_dec_frame_buffering(sps);
507 GST_DEBUG("DPB size %u", priv->dpb_size);
510 static GstVaapiDecoderStatus
511 get_status(GstH264ParserResult result)
513 GstVaapiDecoderStatus status;
516 case GST_H264_PARSER_OK:
517 status = GST_VAAPI_DECODER_STATUS_SUCCESS;
519 case GST_H264_PARSER_NO_NAL_END:
520 status = GST_VAAPI_DECODER_STATUS_ERROR_NO_DATA;
522 case GST_H264_PARSER_ERROR:
523 status = GST_VAAPI_DECODER_STATUS_ERROR_BITSTREAM_PARSER;
526 status = GST_VAAPI_DECODER_STATUS_ERROR_UNKNOWN;
533 gst_vaapi_decoder_h264_close(GstVaapiDecoderH264 *decoder)
535 GstVaapiDecoderH264Private * const priv = decoder->priv;
537 gst_vaapi_picture_replace(&priv->current_picture, NULL);
538 clear_references(decoder, priv->short_ref, &priv->short_ref_count);
539 clear_references(decoder, priv->long_ref, &priv->long_ref_count );
540 clear_references(decoder, priv->dpb, &priv->dpb_count );
543 gst_h264_nal_parser_free(priv->parser);
548 gst_adapter_clear(priv->adapter);
549 g_object_unref(priv->adapter);
550 priv->adapter = NULL;
555 gst_vaapi_decoder_h264_open(GstVaapiDecoderH264 *decoder, GstBuffer *buffer)
557 GstVaapiDecoderH264Private * const priv = decoder->priv;
559 gst_vaapi_decoder_h264_close(decoder);
561 priv->adapter = gst_adapter_new();
565 priv->parser = gst_h264_nal_parser_new();
572 gst_vaapi_decoder_h264_destroy(GstVaapiDecoderH264 *decoder)
574 gst_vaapi_decoder_h264_close(decoder);
578 gst_vaapi_decoder_h264_create(GstVaapiDecoderH264 *decoder)
580 if (!GST_VAAPI_DECODER_CODEC(decoder))
586 h264_get_profile(GstH264SPS *sps)
590 switch (sps->profile_idc) {
592 profile = GST_VAAPI_PROFILE_H264_BASELINE;
595 profile = GST_VAAPI_PROFILE_H264_MAIN;
598 profile = GST_VAAPI_PROFILE_H264_HIGH;
605 h264_get_chroma_type(GstH264SPS *sps)
607 guint chroma_type = 0;
609 switch (sps->chroma_format_idc) {
611 chroma_type = GST_VAAPI_CHROMA_TYPE_YUV420;
614 chroma_type = GST_VAAPI_CHROMA_TYPE_YUV422;
617 if (!sps->separate_colour_plane_flag)
618 chroma_type = GST_VAAPI_CHROMA_TYPE_YUV444;
624 static GstVaapiProfile
625 get_profile(GstVaapiDecoderH264 *decoder, GstH264SPS *sps)
627 GstVaapiDecoderH264Private * const priv = decoder->priv;
628 GstVaapiDisplay * const display = GST_VAAPI_DECODER_DISPLAY(decoder);
629 GstVaapiProfile profile, profiles[2];
630 guint i, n_profiles = 0;
632 profile = h264_get_profile(sps);
634 return GST_VAAPI_PROFILE_UNKNOWN;
636 profiles[n_profiles++] = profile;
638 case GST_VAAPI_PROFILE_H264_MAIN:
639 profiles[n_profiles++] = GST_VAAPI_PROFILE_H264_HIGH;
645 /* If the preferred profile (profiles[0]) matches one that we already
646 found, then just return it now instead of searching for it again */
647 if (profiles[0] == priv->profile)
648 return priv->profile;
650 for (i = 0; i < n_profiles; i++) {
651 if (gst_vaapi_display_has_decoder(display, profiles[i], priv->entrypoint))
654 return GST_VAAPI_PROFILE_UNKNOWN;
657 static GstVaapiDecoderStatus
658 ensure_context(GstVaapiDecoderH264 *decoder, GstH264SPS *sps)
660 GstVaapiDecoder * const base_decoder = GST_VAAPI_DECODER_CAST(decoder);
661 GstVaapiDecoderH264Private * const priv = decoder->priv;
662 GstVaapiContextInfo info;
663 GstVaapiProfile profile;
664 GstVaapiChromaType chroma_type;
665 gboolean reset_context = FALSE;
667 profile = get_profile(decoder, sps);
669 GST_ERROR("unsupported profile_idc %u", sps->profile_idc);
670 return GST_VAAPI_DECODER_STATUS_ERROR_UNSUPPORTED_PROFILE;
673 if (priv->profile != profile) {
674 GST_DEBUG("profile changed");
675 reset_context = TRUE;
676 priv->profile = profile;
679 chroma_type = h264_get_chroma_type(sps);
680 if (!chroma_type || chroma_type != GST_VAAPI_CHROMA_TYPE_YUV420) {
681 GST_ERROR("unsupported chroma_format_idc %u", sps->chroma_format_idc);
682 return GST_VAAPI_DECODER_STATUS_ERROR_UNSUPPORTED_CHROMA_FORMAT;
685 if (priv->chroma_type != chroma_type) {
686 GST_DEBUG("chroma format changed");
687 reset_context = TRUE;
688 priv->chroma_type = chroma_type;
691 if (priv->width != sps->width || priv->height != sps->height) {
692 GST_DEBUG("size changed");
693 reset_context = TRUE;
694 priv->width = sps->width;
695 priv->height = sps->height;
698 gst_vaapi_decoder_set_pixel_aspect_ratio(
700 sps->vui_parameters.par_n,
701 sps->vui_parameters.par_d
704 if (!reset_context && priv->has_context)
705 return GST_VAAPI_DECODER_STATUS_SUCCESS;
707 info.profile = priv->profile;
708 info.entrypoint = priv->entrypoint;
709 info.width = priv->width;
710 info.height = priv->height;
711 info.ref_frames = get_max_dec_frame_buffering(sps);
713 if (!gst_vaapi_decoder_ensure_context(GST_VAAPI_DECODER(decoder), &info))
714 return GST_VAAPI_DECODER_STATUS_ERROR_UNKNOWN;
715 priv->has_context = TRUE;
718 dpb_reset(decoder, sps);
719 return GST_VAAPI_DECODER_STATUS_SUCCESS;
723 fill_iq_matrix_4x4(VAIQMatrixBufferH264 *iq_matrix, const GstH264PPS *pps)
725 const guint8 (* const ScalingList4x4)[6][16] = &pps->scaling_lists_4x4;
728 /* There are always 6 4x4 scaling lists */
729 g_assert(G_N_ELEMENTS(iq_matrix->ScalingList4x4) == 6);
730 g_assert(G_N_ELEMENTS(iq_matrix->ScalingList4x4[0]) == 16);
732 if (sizeof(iq_matrix->ScalingList4x4[0][0]) == 1)
733 memcpy(iq_matrix->ScalingList4x4, *ScalingList4x4,
734 sizeof(iq_matrix->ScalingList4x4));
736 for (i = 0; i < G_N_ELEMENTS(iq_matrix->ScalingList4x4); i++) {
737 for (j = 0; j < G_N_ELEMENTS(iq_matrix->ScalingList4x4[i]); j++)
738 iq_matrix->ScalingList4x4[i][j] = (*ScalingList4x4)[i][j];
744 fill_iq_matrix_8x8(VAIQMatrixBufferH264 *iq_matrix, const GstH264PPS *pps)
746 const guint8 (* const ScalingList8x8)[6][64] = &pps->scaling_lists_8x8;
747 const GstH264SPS * const sps = pps->sequence;
750 /* If chroma_format_idc != 3, there are up to 2 8x8 scaling lists */
751 if (!pps->transform_8x8_mode_flag)
754 g_assert(G_N_ELEMENTS(iq_matrix->ScalingList8x8) >= 2);
755 g_assert(G_N_ELEMENTS(iq_matrix->ScalingList8x8[0]) == 64);
757 if (sizeof(iq_matrix->ScalingList8x8[0][0]) == 1)
758 memcpy(iq_matrix->ScalingList8x8, *ScalingList8x8,
759 sizeof(iq_matrix->ScalingList8x8));
761 n = (sps->chroma_format_idc != 3) ? 2 : 6;
762 for (i = 0; i < n; i++) {
763 for (j = 0; j < G_N_ELEMENTS(iq_matrix->ScalingList8x8[i]); j++)
764 iq_matrix->ScalingList8x8[i][j] = (*ScalingList8x8)[i][j];
769 static GstVaapiDecoderStatus
770 ensure_quant_matrix(GstVaapiDecoderH264 *decoder, GstVaapiPictureH264 *picture)
772 GstVaapiPicture * const base_picture = &picture->base;
773 GstH264PPS * const pps = picture->pps;
774 GstH264SPS * const sps = pps->sequence;
775 VAIQMatrixBufferH264 *iq_matrix;
777 base_picture->iq_matrix = GST_VAAPI_IQ_MATRIX_NEW(H264, decoder);
778 if (!base_picture->iq_matrix) {
779 GST_ERROR("failed to allocate IQ matrix");
780 return GST_VAAPI_DECODER_STATUS_ERROR_ALLOCATION_FAILED;
782 iq_matrix = base_picture->iq_matrix->param;
784 /* XXX: we can only support 4:2:0 or 4:2:2 since ScalingLists8x8[]
785 is not large enough to hold lists for 4:4:4 */
786 if (sps->chroma_format_idc == 3)
787 return GST_VAAPI_DECODER_STATUS_ERROR_UNSUPPORTED_CHROMA_FORMAT;
789 fill_iq_matrix_4x4(iq_matrix, pps);
790 fill_iq_matrix_8x8(iq_matrix, pps);
792 return GST_VAAPI_DECODER_STATUS_SUCCESS;
795 static GstVaapiDecoderStatus
796 decode_current_picture(GstVaapiDecoderH264 *decoder)
798 GstVaapiDecoderH264Private * const priv = decoder->priv;
799 GstVaapiPictureH264 * const picture = priv->current_picture;
800 GstVaapiDecoderStatus status;
803 return GST_VAAPI_DECODER_STATUS_SUCCESS;
805 status = ensure_context(decoder, picture->pps->sequence);
806 if (status != GST_VAAPI_DECODER_STATUS_SUCCESS)
809 if (!decode_picture_end(decoder, picture))
811 if (!gst_vaapi_picture_decode(GST_VAAPI_PICTURE_CAST(picture)))
813 gst_vaapi_picture_replace(&priv->current_picture, NULL);
814 return GST_VAAPI_DECODER_STATUS_SUCCESS;
817 gst_vaapi_picture_replace(&priv->current_picture, NULL);
818 return GST_VAAPI_DECODER_STATUS_ERROR_UNKNOWN;
821 static GstVaapiDecoderStatus
822 decode_sps(GstVaapiDecoderH264 *decoder, GstH264NalUnit *nalu)
824 GstVaapiDecoderH264Private * const priv = decoder->priv;
825 GstH264SPS * const sps = &priv->last_sps;
826 GstH264ParserResult result;
828 GST_DEBUG("decode SPS");
830 memset(sps, 0, sizeof(*sps));
831 result = gst_h264_parser_parse_sps(priv->parser, nalu, sps, TRUE);
832 if (result != GST_H264_PARSER_OK)
833 return get_status(result);
835 return GST_VAAPI_DECODER_STATUS_SUCCESS;
838 static GstVaapiDecoderStatus
839 decode_pps(GstVaapiDecoderH264 *decoder, GstH264NalUnit *nalu)
841 GstVaapiDecoderH264Private * const priv = decoder->priv;
842 GstH264PPS * const pps = &priv->last_pps;
843 GstH264ParserResult result;
845 GST_DEBUG("decode PPS");
847 memset(pps, 0, sizeof(*pps));
848 result = gst_h264_parser_parse_pps(priv->parser, nalu, pps);
849 if (result != GST_H264_PARSER_OK)
850 return get_status(result);
852 return GST_VAAPI_DECODER_STATUS_SUCCESS;
855 static GstVaapiDecoderStatus
856 decode_sei(GstVaapiDecoderH264 *decoder, GstH264NalUnit *nalu)
858 GstVaapiDecoderH264Private * const priv = decoder->priv;
859 GstH264SEIMessage sei;
860 GstH264ParserResult result;
862 GST_DEBUG("decode SEI");
864 memset(&sei, 0, sizeof(sei));
865 result = gst_h264_parser_parse_sei(priv->parser, nalu, &sei);
866 if (result != GST_H264_PARSER_OK) {
867 GST_WARNING("failed to decode SEI, payload type:%d", sei.payloadType);
868 return get_status(result);
871 return GST_VAAPI_DECODER_STATUS_SUCCESS;
874 static GstVaapiDecoderStatus
875 decode_sequence_end(GstVaapiDecoderH264 *decoder)
877 GstVaapiDecoderStatus status;
879 GST_DEBUG("decode sequence-end");
881 status = decode_current_picture(decoder);
882 if (status != GST_VAAPI_DECODER_STATUS_SUCCESS)
886 return GST_VAAPI_DECODER_STATUS_END_OF_STREAM;
889 /* 8.2.1.1 - Decoding process for picture order count type 0 */
892 GstVaapiDecoderH264 *decoder,
893 GstVaapiPictureH264 *picture,
894 GstH264SliceHdr *slice_hdr
897 GstVaapiDecoderH264Private * const priv = decoder->priv;
898 GstH264PPS * const pps = slice_hdr->pps;
899 GstH264SPS * const sps = pps->sequence;
900 const gint32 MaxPicOrderCntLsb = 1 << (sps->log2_max_pic_order_cnt_lsb_minus4 + 4);
903 GST_DEBUG("decode picture order count type 0");
905 if (GST_VAAPI_PICTURE_IS_IDR(picture)) {
906 priv->prev_poc_msb = 0;
907 priv->prev_poc_lsb = 0;
909 else if (priv->prev_pic_has_mmco5) {
910 priv->prev_poc_msb = 0;
912 (priv->prev_pic_structure == GST_VAAPI_PICTURE_STRUCTURE_BOTTOM_FIELD ?
913 0 : priv->field_poc[TOP_FIELD]);
916 priv->prev_poc_msb = priv->poc_msb;
917 priv->prev_poc_lsb = priv->poc_lsb;
921 priv->poc_lsb = slice_hdr->pic_order_cnt_lsb;
922 if (priv->poc_lsb < priv->prev_poc_lsb &&
923 (priv->prev_poc_lsb - priv->poc_lsb) >= (MaxPicOrderCntLsb / 2))
924 priv->poc_msb = priv->prev_poc_msb + MaxPicOrderCntLsb;
925 else if (priv->poc_lsb > priv->prev_poc_lsb &&
926 (priv->poc_lsb - priv->prev_poc_lsb) > (MaxPicOrderCntLsb / 2))
927 priv->poc_msb = priv->prev_poc_msb - MaxPicOrderCntLsb;
929 priv->poc_msb = priv->prev_poc_msb;
931 temp_poc = priv->poc_msb + priv->poc_lsb;
932 switch (picture->base.structure) {
933 case GST_VAAPI_PICTURE_STRUCTURE_FRAME:
935 priv->field_poc[TOP_FIELD] = temp_poc;
936 priv->field_poc[BOTTOM_FIELD] = temp_poc +
937 slice_hdr->delta_pic_order_cnt_bottom;
939 case GST_VAAPI_PICTURE_STRUCTURE_TOP_FIELD:
941 priv->field_poc[TOP_FIELD] = temp_poc;
943 case GST_VAAPI_PICTURE_STRUCTURE_BOTTOM_FIELD:
945 priv->field_poc[BOTTOM_FIELD] = temp_poc;
950 /* 8.2.1.2 - Decoding process for picture order count type 1 */
953 GstVaapiDecoderH264 *decoder,
954 GstVaapiPictureH264 *picture,
955 GstH264SliceHdr *slice_hdr
958 GstVaapiDecoderH264Private * const priv = decoder->priv;
959 GstH264PPS * const pps = slice_hdr->pps;
960 GstH264SPS * const sps = pps->sequence;
961 const gint32 MaxFrameNum = 1 << (sps->log2_max_frame_num_minus4 + 4);
962 gint32 prev_frame_num_offset, abs_frame_num, expected_poc;
965 GST_DEBUG("decode picture order count type 1");
967 if (priv->prev_pic_has_mmco5)
968 prev_frame_num_offset = 0;
970 prev_frame_num_offset = priv->frame_num_offset;
973 if (GST_VAAPI_PICTURE_IS_IDR(picture))
974 priv->frame_num_offset = 0;
975 else if (priv->prev_frame_num > priv->frame_num)
976 priv->frame_num_offset = prev_frame_num_offset + MaxFrameNum;
978 priv->frame_num_offset = prev_frame_num_offset;
981 if (sps->num_ref_frames_in_pic_order_cnt_cycle != 0)
982 abs_frame_num = priv->frame_num_offset + priv->frame_num;
985 if (!GST_VAAPI_PICTURE_IS_REFERENCE(picture) && abs_frame_num > 0)
986 abs_frame_num = abs_frame_num - 1;
988 if (abs_frame_num > 0) {
989 gint32 expected_delta_per_poc_cycle;
990 gint32 poc_cycle_cnt, frame_num_in_poc_cycle;
992 expected_delta_per_poc_cycle = 0;
993 for (i = 0; i < sps->num_ref_frames_in_pic_order_cnt_cycle; i++)
994 expected_delta_per_poc_cycle += sps->offset_for_ref_frame[i];
997 poc_cycle_cnt = (abs_frame_num - 1) /
998 sps->num_ref_frames_in_pic_order_cnt_cycle;
999 frame_num_in_poc_cycle = (abs_frame_num - 1) %
1000 sps->num_ref_frames_in_pic_order_cnt_cycle;
1003 expected_poc = poc_cycle_cnt * expected_delta_per_poc_cycle;
1004 for (i = 0; i <= frame_num_in_poc_cycle; i++)
1005 expected_poc += sps->offset_for_ref_frame[i];
1009 if (!GST_VAAPI_PICTURE_IS_REFERENCE(picture))
1010 expected_poc += sps->offset_for_non_ref_pic;
1013 switch (picture->base.structure) {
1014 case GST_VAAPI_PICTURE_STRUCTURE_FRAME:
1015 priv->field_poc[TOP_FIELD] = expected_poc +
1016 slice_hdr->delta_pic_order_cnt[0];
1017 priv->field_poc[BOTTOM_FIELD] = priv->field_poc[TOP_FIELD] +
1018 sps->offset_for_top_to_bottom_field +
1019 slice_hdr->delta_pic_order_cnt[1];
1021 case GST_VAAPI_PICTURE_STRUCTURE_TOP_FIELD:
1022 priv->field_poc[TOP_FIELD] = expected_poc +
1023 slice_hdr->delta_pic_order_cnt[0];
1025 case GST_VAAPI_PICTURE_STRUCTURE_BOTTOM_FIELD:
1026 priv->field_poc[BOTTOM_FIELD] = expected_poc +
1027 sps->offset_for_top_to_bottom_field +
1028 slice_hdr->delta_pic_order_cnt[0];
1033 /* 8.2.1.3 - Decoding process for picture order count type 2 */
1036 GstVaapiDecoderH264 *decoder,
1037 GstVaapiPictureH264 *picture,
1038 GstH264SliceHdr *slice_hdr
1041 GstVaapiDecoderH264Private * const priv = decoder->priv;
1042 GstH264PPS * const pps = slice_hdr->pps;
1043 GstH264SPS * const sps = pps->sequence;
1044 const gint32 MaxFrameNum = 1 << (sps->log2_max_frame_num_minus4 + 4);
1045 gint32 prev_frame_num_offset, temp_poc;
1047 GST_DEBUG("decode picture order count type 2");
1049 if (priv->prev_pic_has_mmco5)
1050 prev_frame_num_offset = 0;
1052 prev_frame_num_offset = priv->frame_num_offset;
1055 if (GST_VAAPI_PICTURE_IS_IDR(picture))
1056 priv->frame_num_offset = 0;
1057 else if (priv->prev_frame_num > priv->frame_num)
1058 priv->frame_num_offset = prev_frame_num_offset + MaxFrameNum;
1060 priv->frame_num_offset = prev_frame_num_offset;
1063 if (GST_VAAPI_PICTURE_IS_IDR(picture))
1065 else if (!GST_VAAPI_PICTURE_IS_REFERENCE(picture))
1066 temp_poc = 2 * (priv->frame_num_offset + priv->frame_num) - 1;
1068 temp_poc = 2 * (priv->frame_num_offset + priv->frame_num);
1071 if (picture->base.structure != GST_VAAPI_PICTURE_STRUCTURE_BOTTOM_FIELD)
1072 priv->field_poc[TOP_FIELD] = temp_poc;
1073 if (picture->base.structure != GST_VAAPI_PICTURE_STRUCTURE_TOP_FIELD)
1074 priv->field_poc[BOTTOM_FIELD] = temp_poc;
1077 /* 8.2.1 - Decoding process for picture order count */
1080 GstVaapiDecoderH264 *decoder,
1081 GstVaapiPictureH264 *picture,
1082 GstH264SliceHdr *slice_hdr
1085 GstVaapiDecoderH264Private * const priv = decoder->priv;
1086 VAPictureH264 * const pic = &picture->info;
1087 GstH264PPS * const pps = slice_hdr->pps;
1088 GstH264SPS * const sps = pps->sequence;
1090 switch (sps->pic_order_cnt_type) {
1092 init_picture_poc_0(decoder, picture, slice_hdr);
1095 init_picture_poc_1(decoder, picture, slice_hdr);
1098 init_picture_poc_2(decoder, picture, slice_hdr);
1102 if (picture->base.structure != GST_VAAPI_PICTURE_STRUCTURE_BOTTOM_FIELD)
1103 pic->TopFieldOrderCnt = priv->field_poc[TOP_FIELD];
1104 if (picture->base.structure != GST_VAAPI_PICTURE_STRUCTURE_TOP_FIELD)
1105 pic->BottomFieldOrderCnt = priv->field_poc[BOTTOM_FIELD];
1106 picture->poc = MIN(pic->TopFieldOrderCnt, pic->BottomFieldOrderCnt);
1110 compare_picture_pic_num_dec(const void *a, const void *b)
1112 const GstVaapiPictureH264 * const picA = *(GstVaapiPictureH264 **)a;
1113 const GstVaapiPictureH264 * const picB = *(GstVaapiPictureH264 **)b;
1115 return picB->pic_num - picA->pic_num;
1119 compare_picture_long_term_pic_num_inc(const void *a, const void *b)
1121 const GstVaapiPictureH264 * const picA = *(GstVaapiPictureH264 **)a;
1122 const GstVaapiPictureH264 * const picB = *(GstVaapiPictureH264 **)b;
1124 return picA->long_term_pic_num - picB->long_term_pic_num;
1128 compare_picture_poc_dec(const void *a, const void *b)
1130 const GstVaapiPictureH264 * const picA = *(GstVaapiPictureH264 **)a;
1131 const GstVaapiPictureH264 * const picB = *(GstVaapiPictureH264 **)b;
1133 return picB->poc - picA->poc;
1137 compare_picture_poc_inc(const void *a, const void *b)
1139 const GstVaapiPictureH264 * const picA = *(GstVaapiPictureH264 **)a;
1140 const GstVaapiPictureH264 * const picB = *(GstVaapiPictureH264 **)b;
1142 return picA->poc - picB->poc;
1146 compare_picture_frame_num_wrap_dec(const void *a, const void *b)
1148 const GstVaapiPictureH264 * const picA = *(GstVaapiPictureH264 **)a;
1149 const GstVaapiPictureH264 * const picB = *(GstVaapiPictureH264 **)b;
1151 return picB->frame_num_wrap - picA->frame_num_wrap;
1155 compare_picture_long_term_frame_idx_inc(const void *a, const void *b)
1157 const GstVaapiPictureH264 * const picA = *(GstVaapiPictureH264 **)a;
1158 const GstVaapiPictureH264 * const picB = *(GstVaapiPictureH264 **)b;
1160 return picA->info.frame_idx - picB->info.frame_idx;
1163 /* 8.2.4.1 - Decoding process for picture numbers */
1165 init_picture_refs_pic_num(
1166 GstVaapiDecoderH264 *decoder,
1167 GstVaapiPictureH264 *picture,
1168 GstH264SliceHdr *slice_hdr
1171 GstVaapiDecoderH264Private * const priv = decoder->priv;
1172 GstH264PPS * const pps = slice_hdr->pps;
1173 GstH264SPS * const sps = pps->sequence;
1174 const gint32 MaxFrameNum = 1 << (sps->log2_max_frame_num_minus4 + 4);
1177 GST_DEBUG("decode picture numbers");
1179 for (i = 0; i < priv->short_ref_count; i++) {
1180 GstVaapiPictureH264 * const pic = priv->short_ref[i];
1183 if (pic->frame_num > priv->frame_num)
1184 pic->frame_num_wrap = pic->frame_num - MaxFrameNum;
1186 pic->frame_num_wrap = pic->frame_num;
1188 // (8-28, 8-30, 8-31)
1189 if (GST_VAAPI_PICTURE_IS_FRAME(picture))
1190 pic->pic_num = pic->frame_num_wrap;
1192 if (pic->base.structure == picture->base.structure)
1193 pic->pic_num = 2 * pic->frame_num_wrap + 1;
1195 pic->pic_num = 2 * pic->frame_num_wrap;
1199 for (i = 0; i < priv->long_ref_count; i++) {
1200 GstVaapiPictureH264 * const pic = priv->long_ref[i];
1202 // (8-29, 8-32, 8-33)
1203 if (GST_VAAPI_PICTURE_IS_FRAME(picture))
1204 pic->long_term_pic_num = pic->info.frame_idx;
1206 if (pic->base.structure == picture->base.structure)
1207 pic->long_term_pic_num = 2 * pic->info.frame_idx + 1;
1209 pic->long_term_pic_num = 2 * pic->info.frame_idx;
1214 #define SORT_REF_LIST(list, n, compare_func) \
1215 qsort(list, n, sizeof(*(list)), compare_picture_##compare_func)
1218 init_picture_refs_p_slice(
1219 GstVaapiDecoderH264 *decoder,
1220 GstVaapiPictureH264 *picture,
1221 GstH264SliceHdr *slice_hdr
1224 GstVaapiDecoderH264Private * const priv = decoder->priv;
1225 GstVaapiPictureH264 **ref_list;
1228 GST_DEBUG("decode reference picture list for P and SP slices");
1230 if (GST_VAAPI_PICTURE_IS_FRAME(picture)) {
1231 /* 8.2.4.2.1 - P and SP slices in frames */
1232 if (priv->short_ref_count > 0) {
1233 ref_list = priv->RefPicList0;
1234 for (i = 0; i < priv->short_ref_count; i++)
1235 ref_list[i] = priv->short_ref[i];
1236 SORT_REF_LIST(ref_list, i, pic_num_dec);
1237 priv->RefPicList0_count += i;
1240 if (priv->long_ref_count > 0) {
1241 ref_list = &priv->RefPicList0[priv->RefPicList0_count];
1242 for (i = 0; i < priv->long_ref_count; i++)
1243 ref_list[i] = priv->long_ref[i];
1244 SORT_REF_LIST(ref_list, i, long_term_pic_num_inc);
1245 priv->RefPicList0_count += i;
1249 /* 8.2.4.2.2 - P and SP slices in fields */
1250 GstVaapiPictureH264 *short_ref[32];
1251 guint short_ref_count = 0;
1252 GstVaapiPictureH264 *long_ref[32];
1253 guint long_ref_count = 0;
1255 // XXX: handle second field if current field is marked as
1256 // "used for short-term reference"
1257 if (priv->short_ref_count > 0) {
1258 for (i = 0; i < priv->short_ref_count; i++)
1259 short_ref[i] = priv->short_ref[i];
1260 SORT_REF_LIST(short_ref, i, frame_num_wrap_dec);
1261 short_ref_count = i;
1264 // XXX: handle second field if current field is marked as
1265 // "used for long-term reference"
1266 if (priv->long_ref_count > 0) {
1267 for (i = 0; i < priv->long_ref_count; i++)
1268 long_ref[i] = priv->long_ref[i];
1269 SORT_REF_LIST(long_ref, i, long_term_frame_idx_inc);
1273 // XXX: handle 8.2.4.2.5
1278 init_picture_refs_b_slice(
1279 GstVaapiDecoderH264 *decoder,
1280 GstVaapiPictureH264 *picture,
1281 GstH264SliceHdr *slice_hdr
1284 GstVaapiDecoderH264Private * const priv = decoder->priv;
1285 GstVaapiPictureH264 **ref_list;
1288 GST_DEBUG("decode reference picture list for B slices");
1290 if (GST_VAAPI_PICTURE_IS_FRAME(picture)) {
1291 /* 8.2.4.2.3 - B slices in frames */
1294 if (priv->short_ref_count > 0) {
1295 // 1. Short-term references
1296 ref_list = priv->RefPicList0;
1297 for (n = 0, i = 0; i < priv->short_ref_count; i++) {
1298 if (priv->short_ref[i]->poc < picture->poc)
1299 ref_list[n++] = priv->short_ref[i];
1301 SORT_REF_LIST(ref_list, n, poc_dec);
1302 priv->RefPicList0_count += n;
1304 ref_list = &priv->RefPicList0[priv->RefPicList0_count];
1305 for (n = 0, i = 0; i < priv->short_ref_count; i++) {
1306 if (priv->short_ref[i]->poc >= picture->poc)
1307 ref_list[n++] = priv->short_ref[i];
1309 SORT_REF_LIST(ref_list, n, poc_inc);
1310 priv->RefPicList0_count += n;
1313 if (priv->long_ref_count > 0) {
1314 // 2. Long-term references
1315 ref_list = &priv->RefPicList0[priv->RefPicList0_count];
1316 for (n = 0, i = 0; i < priv->long_ref_count; i++)
1317 ref_list[n++] = priv->long_ref[i];
1318 SORT_REF_LIST(ref_list, n, long_term_pic_num_inc);
1319 priv->RefPicList0_count += n;
1323 if (priv->short_ref_count > 0) {
1324 // 1. Short-term references
1325 ref_list = priv->RefPicList1;
1326 for (n = 0, i = 0; i < priv->short_ref_count; i++) {
1327 if (priv->short_ref[i]->poc > picture->poc)
1328 ref_list[n++] = priv->short_ref[i];
1330 SORT_REF_LIST(ref_list, n, poc_inc);
1331 priv->RefPicList1_count += n;
1333 ref_list = &priv->RefPicList1[priv->RefPicList1_count];
1334 for (n = 0, i = 0; i < priv->short_ref_count; i++) {
1335 if (priv->short_ref[i]->poc <= picture->poc)
1336 ref_list[n++] = priv->short_ref[i];
1338 SORT_REF_LIST(ref_list, n, poc_dec);
1339 priv->RefPicList1_count += n;
1342 if (priv->long_ref_count > 0) {
1343 // 2. Long-term references
1344 ref_list = &priv->RefPicList1[priv->RefPicList1_count];
1345 for (n = 0, i = 0; i < priv->long_ref_count; i++)
1346 ref_list[n++] = priv->long_ref[i];
1347 SORT_REF_LIST(ref_list, n, long_term_pic_num_inc);
1348 priv->RefPicList1_count += n;
1352 /* 8.2.4.2.4 - B slices in fields */
1353 GstVaapiPictureH264 *short_ref0[32];
1354 guint short_ref0_count = 0;
1355 GstVaapiPictureH264 *short_ref1[32];
1356 guint short_ref1_count = 0;
1357 GstVaapiPictureH264 *long_ref[32];
1358 guint long_ref_count = 0;
1360 /* refFrameList0ShortTerm */
1361 if (priv->short_ref_count > 0) {
1362 ref_list = short_ref0;
1363 for (n = 0, i = 0; i < priv->short_ref_count; i++) {
1364 if (priv->short_ref[i]->poc <= picture->poc)
1365 ref_list[n++] = priv->short_ref[i];
1367 SORT_REF_LIST(ref_list, n, poc_dec);
1368 short_ref0_count += n;
1370 ref_list = &short_ref0[short_ref0_count];
1371 for (n = 0, i = 0; i < priv->short_ref_count; i++) {
1372 if (priv->short_ref[i]->poc > picture->poc)
1373 ref_list[n++] = priv->short_ref[i];
1375 SORT_REF_LIST(ref_list, n, poc_inc);
1376 short_ref0_count += n;
1379 /* refFrameList1ShortTerm */
1380 if (priv->short_ref_count > 0) {
1381 ref_list = short_ref1;
1382 for (n = 0, i = 0; i < priv->short_ref_count; i++) {
1383 if (priv->short_ref[i]->poc > picture->poc)
1384 ref_list[n++] = priv->short_ref[i];
1386 SORT_REF_LIST(ref_list, n, poc_inc);
1387 short_ref1_count += n;
1389 ref_list = &short_ref1[short_ref1_count];
1390 for (n = 0, i = 0; i < priv->short_ref_count; i++) {
1391 if (priv->short_ref[i]->poc <= picture->poc)
1392 ref_list[n++] = priv->short_ref[i];
1394 SORT_REF_LIST(ref_list, n, poc_dec);
1395 short_ref1_count += n;
1398 /* refFrameListLongTerm */
1399 if (priv->long_ref_count > 0) {
1400 for (i = 0; i < priv->long_ref_count; i++)
1401 long_ref[i] = priv->long_ref[i];
1402 SORT_REF_LIST(long_ref, i, long_term_frame_idx_inc);
1406 // XXX: handle 8.2.4.2.5
1409 /* Check whether RefPicList1 is identical to RefPicList0, then
1410 swap if necessary */
1411 if (priv->RefPicList1_count > 1 &&
1412 priv->RefPicList1_count == priv->RefPicList0_count &&
1413 memcmp(priv->RefPicList0, priv->RefPicList1,
1414 priv->RefPicList0_count * sizeof(priv->RefPicList0[0])) == 0) {
1415 GstVaapiPictureH264 * const tmp = priv->RefPicList1[0];
1416 priv->RefPicList1[0] = priv->RefPicList1[1];
1417 priv->RefPicList1[1] = tmp;
1421 #undef SORT_REF_LIST
1425 GstVaapiDecoderH264 *decoder,
1426 GstVaapiPictureH264 **pictures,
1427 guint *picture_count
1430 const guint num_pictures = *picture_count;
1433 for (i = 0; i < num_pictures; i++)
1434 gst_vaapi_picture_replace(&pictures[i], NULL);
1439 remove_reference_at(
1440 GstVaapiDecoderH264 *decoder,
1441 GstVaapiPictureH264 **pictures,
1442 guint *picture_count,
1446 guint num_pictures = *picture_count;
1447 GstVaapiPictureH264 *picture;
1449 g_return_val_if_fail(index < num_pictures, FALSE);
1451 picture = pictures[index];
1452 GST_VAAPI_PICTURE_FLAG_UNSET(picture, GST_VAAPI_PICTURE_FLAG_REFERENCE);
1453 picture->is_long_term = FALSE;
1454 picture->info.flags &= ~(VA_PICTURE_H264_SHORT_TERM_REFERENCE |
1455 VA_PICTURE_H264_LONG_TERM_REFERENCE);
1457 if (index != --num_pictures)
1458 gst_vaapi_picture_replace(&pictures[index], pictures[num_pictures]);
1459 gst_vaapi_picture_replace(&pictures[num_pictures], NULL);
1460 *picture_count = num_pictures;
1465 find_short_term_reference(GstVaapiDecoderH264 *decoder, gint32 pic_num)
1467 GstVaapiDecoderH264Private * const priv = decoder->priv;
1470 for (i = 0; i < priv->short_ref_count; i++) {
1471 if (priv->short_ref[i]->pic_num == pic_num)
1474 GST_ERROR("found no short-term reference picture with PicNum = %d",
1480 find_long_term_reference(GstVaapiDecoderH264 *decoder, gint32 long_term_pic_num)
1482 GstVaapiDecoderH264Private * const priv = decoder->priv;
1485 for (i = 0; i < priv->long_ref_count; i++) {
1486 if (priv->long_ref[i]->long_term_pic_num == long_term_pic_num)
1489 GST_ERROR("found no long-term reference picture with LongTermPicNum = %d",
1495 exec_picture_refs_modification_1(
1496 GstVaapiDecoderH264 *decoder,
1497 GstVaapiPictureH264 *picture,
1498 GstH264SliceHdr *slice_hdr,
1502 GstVaapiDecoderH264Private * const priv = decoder->priv;
1503 GstH264PPS * const pps = slice_hdr->pps;
1504 GstH264SPS * const sps = pps->sequence;
1505 GstH264RefPicListModification *ref_pic_list_modification;
1506 guint num_ref_pic_list_modifications;
1507 GstVaapiPictureH264 **ref_list;
1508 guint *ref_list_count_ptr, ref_list_count, ref_list_idx = 0;
1509 guint i, j, n, num_refs;
1511 gint32 MaxPicNum, CurrPicNum, picNumPred;
1513 GST_DEBUG("modification process of reference picture list %u", list);
1516 ref_pic_list_modification = slice_hdr->ref_pic_list_modification_l0;
1517 num_ref_pic_list_modifications = slice_hdr->n_ref_pic_list_modification_l0;
1518 ref_list = priv->RefPicList0;
1519 ref_list_count_ptr = &priv->RefPicList0_count;
1520 num_refs = slice_hdr->num_ref_idx_l0_active_minus1 + 1;
1523 ref_pic_list_modification = slice_hdr->ref_pic_list_modification_l1;
1524 num_ref_pic_list_modifications = slice_hdr->n_ref_pic_list_modification_l1;
1525 ref_list = priv->RefPicList1;
1526 ref_list_count_ptr = &priv->RefPicList1_count;
1527 num_refs = slice_hdr->num_ref_idx_l1_active_minus1 + 1;
1529 ref_list_count = *ref_list_count_ptr;
1531 if (!GST_VAAPI_PICTURE_IS_FRAME(picture)) {
1532 MaxPicNum = 1 << (sps->log2_max_frame_num_minus4 + 5); // 2 * MaxFrameNum
1533 CurrPicNum = 2 * slice_hdr->frame_num + 1; // 2 * frame_num + 1
1536 MaxPicNum = 1 << (sps->log2_max_frame_num_minus4 + 4); // MaxFrameNum
1537 CurrPicNum = slice_hdr->frame_num; // frame_num
1540 picNumPred = CurrPicNum;
1542 for (i = 0; i < num_ref_pic_list_modifications; i++) {
1543 GstH264RefPicListModification * const l = &ref_pic_list_modification[i];
1544 if (l->modification_of_pic_nums_idc == 3)
1547 /* 8.2.4.3.1 - Short-term reference pictures */
1548 if (l->modification_of_pic_nums_idc == 0 || l->modification_of_pic_nums_idc == 1) {
1549 gint32 abs_diff_pic_num = l->value.abs_diff_pic_num_minus1 + 1;
1550 gint32 picNum, picNumNoWrap;
1553 if (l->modification_of_pic_nums_idc == 0) {
1554 picNumNoWrap = picNumPred - abs_diff_pic_num;
1555 if (picNumNoWrap < 0)
1556 picNumNoWrap += MaxPicNum;
1561 picNumNoWrap = picNumPred + abs_diff_pic_num;
1562 if (picNumNoWrap >= MaxPicNum)
1563 picNumNoWrap -= MaxPicNum;
1565 picNumPred = picNumNoWrap;
1568 picNum = picNumNoWrap;
1569 if (picNum > CurrPicNum)
1570 picNum -= MaxPicNum;
1573 for (j = num_refs; j > ref_list_idx; j--)
1574 ref_list[j] = ref_list[j - 1];
1575 found_ref_idx = find_short_term_reference(decoder, picNum);
1576 ref_list[ref_list_idx++] =
1577 found_ref_idx >= 0 ? priv->short_ref[found_ref_idx] : NULL;
1579 for (j = ref_list_idx; j <= num_refs; j++) {
1583 PicNumF = ref_list[j]->is_long_term ?
1584 MaxPicNum : ref_list[j]->pic_num;
1585 if (PicNumF != picNum)
1586 ref_list[n++] = ref_list[j];
1590 /* 8.2.4.3.2 - Long-term reference pictures */
1593 for (j = num_refs; j > ref_list_idx; j--)
1594 ref_list[j] = ref_list[j - 1];
1596 find_long_term_reference(decoder, l->value.long_term_pic_num);
1597 ref_list[ref_list_idx++] =
1598 found_ref_idx >= 0 ? priv->long_ref[found_ref_idx] : NULL;
1600 for (j = ref_list_idx; j <= num_refs; j++) {
1601 gint32 LongTermPicNumF;
1604 LongTermPicNumF = ref_list[j]->is_long_term ?
1605 ref_list[j]->long_term_pic_num : INT_MAX;
1606 if (LongTermPicNumF != l->value.long_term_pic_num)
1607 ref_list[n++] = ref_list[j];
1613 for (i = 0; i < num_refs; i++)
1615 GST_ERROR("list %u entry %u is empty", list, i);
1617 *ref_list_count_ptr = num_refs;
1620 /* 8.2.4.3 - Modification process for reference picture lists */
1622 exec_picture_refs_modification(
1623 GstVaapiDecoderH264 *decoder,
1624 GstVaapiPictureH264 *picture,
1625 GstH264SliceHdr *slice_hdr
1628 GST_DEBUG("execute ref_pic_list_modification()");
1631 if (!GST_H264_IS_I_SLICE(slice_hdr) && !GST_H264_IS_SI_SLICE(slice_hdr) &&
1632 slice_hdr->ref_pic_list_modification_flag_l0)
1633 exec_picture_refs_modification_1(decoder, picture, slice_hdr, 0);
1636 if (GST_H264_IS_B_SLICE(slice_hdr) &&
1637 slice_hdr->ref_pic_list_modification_flag_l1)
1638 exec_picture_refs_modification_1(decoder, picture, slice_hdr, 1);
1643 GstVaapiDecoderH264 *decoder,
1644 GstVaapiPictureH264 *picture,
1645 GstH264SliceHdr *slice_hdr
1648 GstVaapiDecoderH264Private * const priv = decoder->priv;
1649 GstVaapiPicture * const base_picture = &picture->base;
1652 init_picture_refs_pic_num(decoder, picture, slice_hdr);
1654 priv->RefPicList0_count = 0;
1655 priv->RefPicList1_count = 0;
1657 switch (base_picture->type) {
1658 case GST_VAAPI_PICTURE_TYPE_P:
1659 case GST_VAAPI_PICTURE_TYPE_SP:
1660 init_picture_refs_p_slice(decoder, picture, slice_hdr);
1662 case GST_VAAPI_PICTURE_TYPE_B:
1663 init_picture_refs_b_slice(decoder, picture, slice_hdr);
1669 exec_picture_refs_modification(decoder, picture, slice_hdr);
1671 switch (base_picture->type) {
1672 case GST_VAAPI_PICTURE_TYPE_B:
1673 num_refs = 1 + slice_hdr->num_ref_idx_l1_active_minus1;
1674 for (i = priv->RefPicList1_count; i < num_refs; i++)
1675 priv->RefPicList1[i] = NULL;
1676 priv->RefPicList1_count = num_refs;
1679 case GST_VAAPI_PICTURE_TYPE_P:
1680 case GST_VAAPI_PICTURE_TYPE_SP:
1681 num_refs = 1 + slice_hdr->num_ref_idx_l0_active_minus1;
1682 for (i = priv->RefPicList0_count; i < num_refs; i++)
1683 priv->RefPicList0[i] = NULL;
1684 priv->RefPicList0_count = num_refs;
1694 GstVaapiDecoderH264 *decoder,
1695 GstVaapiPictureH264 *picture,
1696 GstH264SliceHdr *slice_hdr,
1697 GstH264NalUnit *nalu
1700 GstVaapiDecoderH264Private * const priv = decoder->priv;
1701 GstVaapiPicture * const base_picture = &picture->base;
1704 priv->prev_frame_num = priv->frame_num;
1705 priv->frame_num = slice_hdr->frame_num;
1706 picture->frame_num = priv->frame_num;
1707 picture->frame_num_wrap = priv->frame_num;
1708 picture->output_flag = TRUE; /* XXX: conformant to Annex A only */
1709 base_picture->pts = gst_adapter_prev_timestamp(priv->adapter, NULL);
1711 /* Reset decoder state for IDR pictures */
1712 if (nalu->type == GST_H264_NAL_SLICE_IDR) {
1714 GST_VAAPI_PICTURE_FLAG_SET(picture, GST_VAAPI_PICTURE_FLAG_IDR);
1715 clear_references(decoder, priv->short_ref, &priv->short_ref_count);
1716 clear_references(decoder, priv->long_ref, &priv->long_ref_count );
1719 /* Initialize VA picture info */
1720 pic = &picture->info;
1721 pic->picture_id = picture->base.surface_id;
1722 pic->frame_idx = priv->frame_num;
1724 /* Initialize slice type */
1725 switch (slice_hdr->type % 5) {
1726 case GST_H264_P_SLICE:
1727 base_picture->type = GST_VAAPI_PICTURE_TYPE_P;
1729 case GST_H264_B_SLICE:
1730 base_picture->type = GST_VAAPI_PICTURE_TYPE_B;
1732 case GST_H264_I_SLICE:
1733 base_picture->type = GST_VAAPI_PICTURE_TYPE_I;
1735 case GST_H264_SP_SLICE:
1736 base_picture->type = GST_VAAPI_PICTURE_TYPE_SP;
1738 case GST_H264_SI_SLICE:
1739 base_picture->type = GST_VAAPI_PICTURE_TYPE_SI;
1743 /* Initialize picture structure */
1744 if (!slice_hdr->field_pic_flag)
1745 base_picture->structure = GST_VAAPI_PICTURE_STRUCTURE_FRAME;
1746 else if (!slice_hdr->bottom_field_flag)
1747 base_picture->structure = GST_VAAPI_PICTURE_STRUCTURE_TOP_FIELD;
1749 base_picture->structure = GST_VAAPI_PICTURE_STRUCTURE_BOTTOM_FIELD;
1751 if (nalu->ref_idc) {
1752 GstH264DecRefPicMarking * const dec_ref_pic_marking =
1753 &slice_hdr->dec_ref_pic_marking;
1754 GST_VAAPI_PICTURE_FLAG_SET(picture, GST_VAAPI_PICTURE_FLAG_REFERENCE);
1755 if (GST_VAAPI_PICTURE_IS_IDR(picture)) {
1756 if (dec_ref_pic_marking->long_term_reference_flag)
1757 picture->is_long_term = TRUE;
1761 init_picture_poc(decoder, picture, slice_hdr);
1762 if (!init_picture_refs(decoder, picture, slice_hdr)) {
1763 GST_ERROR("failed to initialize references");
1769 /* 8.2.5.3 - Sliding window decoded reference picture marking process */
1771 exec_ref_pic_marking_sliding_window(GstVaapiDecoderH264 *decoder)
1773 GstVaapiDecoderH264Private * const priv = decoder->priv;
1774 GstH264PPS * const pps = priv->current_picture->pps;
1775 GstH264SPS * const sps = pps->sequence;
1776 guint i, max_num_ref_frames, lowest_frame_num_index;
1777 gint32 lowest_frame_num;
1779 GST_DEBUG("reference picture marking process (sliding window)");
1781 max_num_ref_frames = sps->num_ref_frames;
1782 if (max_num_ref_frames == 0)
1783 max_num_ref_frames = 1;
1785 if (priv->short_ref_count + priv->long_ref_count < max_num_ref_frames)
1787 if (priv->short_ref_count < 1)
1790 lowest_frame_num = priv->short_ref[0]->frame_num_wrap;
1791 lowest_frame_num_index = 0;
1792 for (i = 1; i < priv->short_ref_count; i++) {
1793 if (priv->short_ref[i]->frame_num_wrap < lowest_frame_num) {
1794 lowest_frame_num = priv->short_ref[i]->frame_num_wrap;
1795 lowest_frame_num_index = i;
1799 remove_reference_at(
1801 priv->short_ref, &priv->short_ref_count,
1802 lowest_frame_num_index
1807 static inline gint32
1808 get_picNumX(GstVaapiPictureH264 *picture, GstH264RefPicMarking *ref_pic_marking)
1812 if (GST_VAAPI_PICTURE_IS_FRAME(picture))
1813 pic_num = picture->frame_num_wrap;
1815 pic_num = 2 * picture->frame_num_wrap + 1;
1816 pic_num -= ref_pic_marking->difference_of_pic_nums_minus1 + 1;
1820 /* 8.2.5.4.1. Mark-term reference picture as "unused for reference" */
1822 exec_ref_pic_marking_adaptive_mmco_1(
1823 GstVaapiDecoderH264 *decoder,
1824 GstVaapiPictureH264 *picture,
1825 GstH264RefPicMarking *ref_pic_marking
1828 GstVaapiDecoderH264Private * const priv = decoder->priv;
1831 picNumX = get_picNumX(picture, ref_pic_marking);
1832 i = find_short_term_reference(decoder, picNumX);
1835 remove_reference_at(decoder, priv->short_ref, &priv->short_ref_count, i);
1838 /* 8.2.5.4.2. Mark long-term reference picture as "unused for reference" */
1840 exec_ref_pic_marking_adaptive_mmco_2(
1841 GstVaapiDecoderH264 *decoder,
1842 GstVaapiPictureH264 *picture,
1843 GstH264RefPicMarking *ref_pic_marking
1846 GstVaapiDecoderH264Private * const priv = decoder->priv;
1849 i = find_long_term_reference(decoder, ref_pic_marking->long_term_pic_num);
1852 remove_reference_at(decoder, priv->long_ref, &priv->long_ref_count, i);
1855 /* 8.2.5.4.3. Assign LongTermFrameIdx to a short-term reference picture */
1857 exec_ref_pic_marking_adaptive_mmco_3(
1858 GstVaapiDecoderH264 *decoder,
1859 GstVaapiPictureH264 *picture,
1860 GstH264RefPicMarking *ref_pic_marking
1863 GstVaapiDecoderH264Private * const priv = decoder->priv;
1867 for (i = 0; i < priv->long_ref_count; i++) {
1868 if (priv->long_ref[i]->info.frame_idx == ref_pic_marking->long_term_frame_idx)
1871 if (i != priv->long_ref_count)
1872 remove_reference_at(decoder, priv->long_ref, &priv->long_ref_count, i);
1874 picNumX = get_picNumX(picture, ref_pic_marking);
1875 i = find_short_term_reference(decoder, picNumX);
1879 picture = gst_vaapi_picture_ref(priv->short_ref[i]);
1880 remove_reference_at(decoder, priv->short_ref, &priv->short_ref_count, i);
1881 gst_vaapi_picture_replace(&priv->long_ref[priv->long_ref_count++], picture);
1882 gst_vaapi_picture_unref(picture);
1884 picture->is_long_term = TRUE;
1885 pic = &picture->info;
1886 pic->frame_idx = ref_pic_marking->long_term_frame_idx;
1887 pic->flags &= ~VA_PICTURE_H264_SHORT_TERM_REFERENCE;
1888 pic->flags |= VA_PICTURE_H264_LONG_TERM_REFERENCE;
1889 GST_VAAPI_PICTURE_FLAG_SET(picture, GST_VAAPI_PICTURE_FLAG_REFERENCE);
1892 /* 8.2.5.4.4. Mark pictures with LongTermFramIdx > max_long_term_frame_idx
1893 * as "unused for reference" */
1895 exec_ref_pic_marking_adaptive_mmco_4(
1896 GstVaapiDecoderH264 *decoder,
1897 GstVaapiPictureH264 *picture,
1898 GstH264RefPicMarking *ref_pic_marking
1901 GstVaapiDecoderH264Private * const priv = decoder->priv;
1902 gint32 i, long_term_frame_idx;
1904 long_term_frame_idx = ref_pic_marking->max_long_term_frame_idx_plus1 - 1;
1906 for (i = 0; i < priv->long_ref_count; i++) {
1907 if ((gint32)priv->long_ref[i]->info.frame_idx <= long_term_frame_idx)
1909 remove_reference_at(decoder, priv->long_ref, &priv->long_ref_count, i);
1914 /* 8.2.5.4.5. Mark all reference pictures as "unused for reference" */
1916 exec_ref_pic_marking_adaptive_mmco_5(
1917 GstVaapiDecoderH264 *decoder,
1918 GstVaapiPictureH264 *picture,
1919 GstH264RefPicMarking *ref_pic_marking
1922 GstVaapiDecoderH264Private * const priv = decoder->priv;
1923 VAPictureH264 * const pic = &picture->info;
1925 clear_references(decoder, priv->short_ref, &priv->short_ref_count);
1926 clear_references(decoder, priv->long_ref, &priv->long_ref_count );
1929 priv->prev_pic_has_mmco5 = TRUE;
1931 /* The picture shall be inferred to have had frame_num equal to 0 (7.4.3) */
1932 priv->frame_num = 0;
1933 priv->frame_num_offset = 0;
1934 picture->frame_num = 0;
1936 /* Update TopFieldOrderCnt and BottomFieldOrderCnt (8.2.1) */
1937 if (picture->base.structure != GST_VAAPI_PICTURE_STRUCTURE_BOTTOM_FIELD)
1938 pic->TopFieldOrderCnt -= picture->poc;
1939 if (picture->base.structure != GST_VAAPI_PICTURE_STRUCTURE_TOP_FIELD)
1940 pic->BottomFieldOrderCnt -= picture->poc;
1944 /* 8.2.5.4.6. Assign a long-term frame index to the current picture */
1946 exec_ref_pic_marking_adaptive_mmco_6(
1947 GstVaapiDecoderH264 *decoder,
1948 GstVaapiPictureH264 *picture,
1949 GstH264RefPicMarking *ref_pic_marking
1952 picture->is_long_term = TRUE;
1953 picture->info.frame_idx = ref_pic_marking->long_term_frame_idx;
1956 /* 8.2.5.4. Adaptive memory control decoded reference picture marking process */
1958 exec_ref_pic_marking_adaptive(
1959 GstVaapiDecoderH264 *decoder,
1960 GstVaapiPictureH264 *picture,
1961 GstH264DecRefPicMarking *dec_ref_pic_marking
1966 GST_DEBUG("reference picture marking process (adaptive memory control)");
1968 typedef void (*exec_ref_pic_marking_adaptive_mmco_func)(
1969 GstVaapiDecoderH264 *decoder,
1970 GstVaapiPictureH264 *picture,
1971 GstH264RefPicMarking *ref_pic_marking
1974 static const exec_ref_pic_marking_adaptive_mmco_func mmco_funcs[] = {
1976 exec_ref_pic_marking_adaptive_mmco_1,
1977 exec_ref_pic_marking_adaptive_mmco_2,
1978 exec_ref_pic_marking_adaptive_mmco_3,
1979 exec_ref_pic_marking_adaptive_mmco_4,
1980 exec_ref_pic_marking_adaptive_mmco_5,
1981 exec_ref_pic_marking_adaptive_mmco_6,
1984 for (i = 0; i < dec_ref_pic_marking->n_ref_pic_marking; i++) {
1985 GstH264RefPicMarking * const ref_pic_marking =
1986 &dec_ref_pic_marking->ref_pic_marking[i];
1988 const guint mmco = ref_pic_marking->memory_management_control_operation;
1989 if (mmco < G_N_ELEMENTS(mmco_funcs) && mmco_funcs[mmco])
1990 mmco_funcs[mmco](decoder, picture, ref_pic_marking);
1992 GST_ERROR("unhandled MMCO %u", mmco);
1999 /* 8.2.5 - Execute reference picture marking process */
2001 exec_ref_pic_marking(GstVaapiDecoderH264 *decoder, GstVaapiPictureH264 *picture)
2003 GstVaapiDecoderH264Private * const priv = decoder->priv;
2004 GstVaapiPictureH264 **picture_ptr;
2006 priv->prev_pic_has_mmco5 = FALSE;
2007 priv->prev_pic_structure = picture->base.structure;
2009 if (!GST_VAAPI_PICTURE_IS_REFERENCE(picture))
2012 if (!GST_VAAPI_PICTURE_IS_IDR(picture)) {
2013 GstVaapiSliceH264 * const slice =
2014 gst_vaapi_picture_h264_get_last_slice(picture);
2015 GstH264DecRefPicMarking * const dec_ref_pic_marking =
2016 &slice->slice_hdr.dec_ref_pic_marking;
2017 if (dec_ref_pic_marking->adaptive_ref_pic_marking_mode_flag) {
2018 if (!exec_ref_pic_marking_adaptive(decoder, picture, dec_ref_pic_marking))
2022 if (!exec_ref_pic_marking_sliding_window(decoder))
2027 if (picture->is_long_term) {
2028 picture_ptr = &priv->long_ref[priv->long_ref_count++];
2029 picture->info.flags |= VA_PICTURE_H264_LONG_TERM_REFERENCE;
2032 picture_ptr = &priv->short_ref[priv->short_ref_count++];
2033 picture->info.flags |= VA_PICTURE_H264_SHORT_TERM_REFERENCE;
2035 gst_vaapi_picture_replace(picture_ptr, picture);
2040 vaapi_init_picture(VAPictureH264 *pic)
2042 pic->picture_id = VA_INVALID_ID;
2044 pic->flags = VA_PICTURE_H264_INVALID;
2045 pic->TopFieldOrderCnt = 0;
2046 pic->BottomFieldOrderCnt = 0;
2050 vaapi_fill_picture(VAPictureH264 *pic, GstVaapiPictureH264 *picture)
2052 pic->picture_id = picture->base.surface_id;
2055 if (picture->info.flags & VA_PICTURE_H264_LONG_TERM_REFERENCE) {
2056 pic->flags |= VA_PICTURE_H264_LONG_TERM_REFERENCE;
2057 pic->frame_idx = picture->info.frame_idx;
2060 if (picture->info.flags & VA_PICTURE_H264_SHORT_TERM_REFERENCE)
2061 pic->flags |= VA_PICTURE_H264_SHORT_TERM_REFERENCE;
2062 pic->frame_idx = picture->frame_num;
2065 switch (picture->base.structure) {
2066 case GST_VAAPI_PICTURE_STRUCTURE_FRAME:
2067 pic->TopFieldOrderCnt = picture->info.TopFieldOrderCnt;
2068 pic->BottomFieldOrderCnt = picture->info.BottomFieldOrderCnt;
2070 case GST_VAAPI_PICTURE_STRUCTURE_TOP_FIELD:
2071 pic->flags |= VA_PICTURE_H264_TOP_FIELD;
2072 pic->TopFieldOrderCnt = picture->info.BottomFieldOrderCnt;
2073 pic->BottomFieldOrderCnt = 0;
2075 case GST_VAAPI_PICTURE_STRUCTURE_BOTTOM_FIELD:
2076 pic->flags |= VA_PICTURE_H264_BOTTOM_FIELD;
2077 pic->BottomFieldOrderCnt = picture->info.BottomFieldOrderCnt;
2078 pic->TopFieldOrderCnt = 0;
2085 GstVaapiDecoderH264 *decoder,
2086 GstVaapiPictureH264 *picture,
2087 GstH264SliceHdr *slice_hdr,
2088 GstH264NalUnit *nalu
2091 GstVaapiDecoderH264Private * const priv = decoder->priv;
2092 GstVaapiPicture * const base_picture = &picture->base;
2093 GstH264PPS * const pps = picture->pps;
2094 GstH264SPS * const sps = pps->sequence;
2095 VAPictureParameterBufferH264 * const pic_param = base_picture->param;
2098 /* Fill in VAPictureParameterBufferH264 */
2099 vaapi_fill_picture(&pic_param->CurrPic, picture);
2100 for (i = 0, n = 0; i < priv->short_ref_count; i++, n++)
2101 vaapi_fill_picture(&pic_param->ReferenceFrames[n], priv->short_ref[i]);
2102 for (i = 0; i < priv->long_ref_count; i++, n++)
2103 vaapi_fill_picture(&pic_param->ReferenceFrames[n], priv->long_ref[i]);
2104 for (; n < G_N_ELEMENTS(pic_param->ReferenceFrames); n++)
2105 vaapi_init_picture(&pic_param->ReferenceFrames[n]);
2107 #define COPY_FIELD(s, f) \
2108 pic_param->f = (s)->f
2110 #define COPY_BFM(a, s, f) \
2111 pic_param->a.bits.f = (s)->f
2113 pic_param->picture_width_in_mbs_minus1 = ((priv->width + 15) >> 4) - 1;
2114 pic_param->picture_height_in_mbs_minus1 = ((priv->height + 15) >> 4) - 1;
2115 pic_param->frame_num = priv->frame_num;
2117 COPY_FIELD(sps, bit_depth_luma_minus8);
2118 COPY_FIELD(sps, bit_depth_chroma_minus8);
2119 COPY_FIELD(sps, num_ref_frames);
2120 COPY_FIELD(pps, num_slice_groups_minus1);
2121 COPY_FIELD(pps, slice_group_map_type);
2122 COPY_FIELD(pps, slice_group_change_rate_minus1);
2123 COPY_FIELD(pps, pic_init_qp_minus26);
2124 COPY_FIELD(pps, pic_init_qs_minus26);
2125 COPY_FIELD(pps, chroma_qp_index_offset);
2126 COPY_FIELD(pps, second_chroma_qp_index_offset);
2128 pic_param->seq_fields.value = 0; /* reset all bits */
2129 pic_param->seq_fields.bits.residual_colour_transform_flag = sps->separate_colour_plane_flag;
2130 pic_param->seq_fields.bits.MinLumaBiPredSize8x8 = sps->level_idc >= 31; /* A.3.3.2 */
2132 COPY_BFM(seq_fields, sps, chroma_format_idc);
2133 COPY_BFM(seq_fields, sps, gaps_in_frame_num_value_allowed_flag);
2134 COPY_BFM(seq_fields, sps, frame_mbs_only_flag);
2135 COPY_BFM(seq_fields, sps, mb_adaptive_frame_field_flag);
2136 COPY_BFM(seq_fields, sps, direct_8x8_inference_flag);
2137 COPY_BFM(seq_fields, sps, log2_max_frame_num_minus4);
2138 COPY_BFM(seq_fields, sps, pic_order_cnt_type);
2139 COPY_BFM(seq_fields, sps, log2_max_pic_order_cnt_lsb_minus4);
2140 COPY_BFM(seq_fields, sps, delta_pic_order_always_zero_flag);
2142 pic_param->pic_fields.value = 0; /* reset all bits */
2143 pic_param->pic_fields.bits.field_pic_flag = slice_hdr->field_pic_flag;
2144 pic_param->pic_fields.bits.reference_pic_flag = GST_VAAPI_PICTURE_IS_REFERENCE(picture);
2146 COPY_BFM(pic_fields, pps, entropy_coding_mode_flag);
2147 COPY_BFM(pic_fields, pps, weighted_pred_flag);
2148 COPY_BFM(pic_fields, pps, weighted_bipred_idc);
2149 COPY_BFM(pic_fields, pps, transform_8x8_mode_flag);
2150 COPY_BFM(pic_fields, pps, constrained_intra_pred_flag);
2151 COPY_BFM(pic_fields, pps, pic_order_present_flag);
2152 COPY_BFM(pic_fields, pps, deblocking_filter_control_present_flag);
2153 COPY_BFM(pic_fields, pps, redundant_pic_cnt_present_flag);
2157 /* Detection of the first VCL NAL unit of a primary coded picture (7.4.1.2.4) */
2160 GstVaapiDecoderH264 *decoder,
2161 GstH264NalUnit *nalu,
2162 GstH264SliceHdr *slice_hdr
2165 GstVaapiDecoderH264Private * const priv = decoder->priv;
2166 GstH264PPS * const pps = slice_hdr->pps;
2167 GstH264SPS * const sps = pps->sequence;
2168 GstVaapiSliceH264 *slice;
2169 GstH264SliceHdr *prev_slice_hdr;
2171 if (!priv->current_picture)
2174 slice = gst_vaapi_picture_h264_get_last_slice(priv->current_picture);
2177 prev_slice_hdr = &slice->slice_hdr;
2179 #define CHECK_EXPR(expr, field_name) do { \
2181 GST_DEBUG(field_name " differs in value"); \
2186 #define CHECK_VALUE(new_slice_hdr, old_slice_hdr, field) \
2187 CHECK_EXPR(((new_slice_hdr)->field == (old_slice_hdr)->field), #field)
2189 /* frame_num differs in value, regardless of inferred values to 0 */
2190 CHECK_VALUE(slice_hdr, prev_slice_hdr, frame_num);
2192 /* pic_parameter_set_id differs in value */
2193 CHECK_VALUE(slice_hdr, prev_slice_hdr, pps);
2195 /* field_pic_flag differs in value */
2196 CHECK_VALUE(slice_hdr, prev_slice_hdr, field_pic_flag);
2198 /* bottom_field_flag is present in both and differs in value */
2199 if (slice_hdr->field_pic_flag && prev_slice_hdr->field_pic_flag)
2200 CHECK_VALUE(slice_hdr, prev_slice_hdr, bottom_field_flag);
2202 /* nal_ref_idc differs in value with one of the nal_ref_idc values is 0 */
2203 CHECK_EXPR(((GST_VAAPI_PICTURE_IS_REFERENCE(priv->current_picture) ^
2204 (nalu->ref_idc != 0)) == 0), "nal_ref_idc");
2206 /* POC type is 0 for both and either pic_order_cnt_lsb differs in
2207 value or delta_pic_order_cnt_bottom differs in value */
2208 if (sps->pic_order_cnt_type == 0) {
2209 CHECK_VALUE(slice_hdr, prev_slice_hdr, pic_order_cnt_lsb);
2210 if (pps->pic_order_present_flag && !slice_hdr->field_pic_flag)
2211 CHECK_VALUE(slice_hdr, prev_slice_hdr, delta_pic_order_cnt_bottom);
2214 /* POC type is 1 for both and either delta_pic_order_cnt[0]
2215 differs in value or delta_pic_order_cnt[1] differs in value */
2216 else if (sps->pic_order_cnt_type == 1) {
2217 CHECK_VALUE(slice_hdr, prev_slice_hdr, delta_pic_order_cnt[0]);
2218 CHECK_VALUE(slice_hdr, prev_slice_hdr, delta_pic_order_cnt[1]);
2221 /* IdrPicFlag differs in value */
2222 CHECK_EXPR(((GST_VAAPI_PICTURE_IS_IDR(priv->current_picture) ^
2223 (nalu->type == GST_H264_NAL_SLICE_IDR)) == 0), "IdrPicFlag");
2225 /* IdrPicFlag is equal to 1 for both and idr_pic_id differs in value */
2226 if (GST_VAAPI_PICTURE_IS_IDR(priv->current_picture))
2227 CHECK_VALUE(slice_hdr, prev_slice_hdr, idr_pic_id);
2234 static GstVaapiDecoderStatus
2235 decode_picture(GstVaapiDecoderH264 *decoder, GstH264NalUnit *nalu, GstH264SliceHdr *slice_hdr)
2237 GstVaapiDecoderH264Private * const priv = decoder->priv;
2238 GstVaapiPictureH264 *picture;
2239 GstVaapiDecoderStatus status;
2240 GstH264PPS * const pps = slice_hdr->pps;
2241 GstH264SPS * const sps = pps->sequence;
2243 status = decode_current_picture(decoder);
2244 if (status != GST_VAAPI_DECODER_STATUS_SUCCESS)
2247 status = ensure_context(decoder, sps);
2248 if (status != GST_VAAPI_DECODER_STATUS_SUCCESS)
2251 picture = gst_vaapi_picture_h264_new(decoder);
2253 GST_ERROR("failed to allocate picture");
2254 return GST_VAAPI_DECODER_STATUS_ERROR_ALLOCATION_FAILED;
2256 priv->current_picture = picture;
2260 status = ensure_quant_matrix(decoder, picture);
2261 if (status != GST_VAAPI_DECODER_STATUS_SUCCESS) {
2262 GST_ERROR("failed to reset quantizer matrix");
2266 if (!init_picture(decoder, picture, slice_hdr, nalu))
2267 return GST_VAAPI_DECODER_STATUS_ERROR_UNKNOWN;
2268 if (!fill_picture(decoder, picture, slice_hdr, nalu))
2269 return GST_VAAPI_DECODER_STATUS_ERROR_UNKNOWN;
2270 return GST_VAAPI_DECODER_STATUS_SUCCESS;
2274 decode_picture_end(GstVaapiDecoderH264 *decoder, GstVaapiPictureH264 *picture)
2276 if (!exec_ref_pic_marking(decoder, picture))
2278 if (!dpb_add(decoder, picture))
2284 get_slice_data_bit_offset(GstH264SliceHdr *slice_hdr, GstH264NalUnit *nalu)
2288 epb_count = slice_hdr->n_emulation_prevention_bytes;
2289 return 8 /* nal_unit_type */ + slice_hdr->header_size - epb_count * 8;
2293 fill_pred_weight_table(GstVaapiDecoderH264 *decoder, GstVaapiSliceH264 *slice)
2295 GstH264SliceHdr * const slice_hdr = &slice->slice_hdr;
2296 GstH264PPS * const pps = slice_hdr->pps;
2297 GstH264SPS * const sps = pps->sequence;
2298 GstH264PredWeightTable * const w = &slice_hdr->pred_weight_table;
2299 VASliceParameterBufferH264 * const slice_param = slice->base.param;
2300 guint num_weight_tables = 0;
2303 if (pps->weighted_pred_flag &&
2304 (GST_H264_IS_P_SLICE(slice_hdr) || GST_H264_IS_SP_SLICE(slice_hdr)))
2305 num_weight_tables = 1;
2306 else if (pps->weighted_bipred_idc == 1 && GST_H264_IS_B_SLICE(slice_hdr))
2307 num_weight_tables = 2;
2309 num_weight_tables = 0;
2311 slice_param->luma_log2_weight_denom = w->luma_log2_weight_denom;
2312 slice_param->chroma_log2_weight_denom = w->chroma_log2_weight_denom;
2313 slice_param->luma_weight_l0_flag = 0;
2314 slice_param->chroma_weight_l0_flag = 0;
2315 slice_param->luma_weight_l1_flag = 0;
2316 slice_param->chroma_weight_l1_flag = 0;
2318 if (num_weight_tables < 1)
2321 slice_param->luma_weight_l0_flag = 1;
2322 for (i = 0; i <= slice_param->num_ref_idx_l0_active_minus1; i++) {
2323 slice_param->luma_weight_l0[i] = w->luma_weight_l0[i];
2324 slice_param->luma_offset_l0[i] = w->luma_offset_l0[i];
2327 slice_param->chroma_weight_l0_flag = sps->chroma_array_type != 0;
2328 if (slice_param->chroma_weight_l0_flag) {
2329 for (i = 0; i <= slice_param->num_ref_idx_l0_active_minus1; i++) {
2330 for (j = 0; j < 2; j++) {
2331 slice_param->chroma_weight_l0[i][j] = w->chroma_weight_l0[i][j];
2332 slice_param->chroma_offset_l0[i][j] = w->chroma_offset_l0[i][j];
2337 if (num_weight_tables < 2)
2340 slice_param->luma_weight_l1_flag = 1;
2341 for (i = 0; i <= slice_param->num_ref_idx_l1_active_minus1; i++) {
2342 slice_param->luma_weight_l1[i] = w->luma_weight_l1[i];
2343 slice_param->luma_offset_l1[i] = w->luma_offset_l1[i];
2346 slice_param->chroma_weight_l1_flag = sps->chroma_array_type != 0;
2347 if (slice_param->chroma_weight_l1_flag) {
2348 for (i = 0; i <= slice_param->num_ref_idx_l1_active_minus1; i++) {
2349 for (j = 0; j < 2; j++) {
2350 slice_param->chroma_weight_l1[i][j] = w->chroma_weight_l1[i][j];
2351 slice_param->chroma_offset_l1[i][j] = w->chroma_offset_l1[i][j];
2359 fill_RefPicList(GstVaapiDecoderH264 *decoder, GstVaapiSliceH264 *slice)
2361 GstVaapiDecoderH264Private * const priv = decoder->priv;
2362 GstH264SliceHdr * const slice_hdr = &slice->slice_hdr;
2363 VASliceParameterBufferH264 * const slice_param = slice->base.param;
2364 guint i, num_ref_lists = 0;
2366 slice_param->num_ref_idx_l0_active_minus1 = 0;
2367 slice_param->num_ref_idx_l1_active_minus1 = 0;
2369 if (GST_H264_IS_B_SLICE(slice_hdr))
2371 else if (GST_H264_IS_I_SLICE(slice_hdr))
2376 if (num_ref_lists < 1)
2379 slice_param->num_ref_idx_l0_active_minus1 =
2380 slice_hdr->num_ref_idx_l0_active_minus1;
2382 for (i = 0; i < priv->RefPicList0_count && priv->RefPicList0[i]; i++)
2383 vaapi_fill_picture(&slice_param->RefPicList0[i], priv->RefPicList0[i]);
2384 for (; i <= slice_param->num_ref_idx_l0_active_minus1; i++)
2385 vaapi_init_picture(&slice_param->RefPicList0[i]);
2387 if (num_ref_lists < 2)
2390 slice_param->num_ref_idx_l1_active_minus1 =
2391 slice_hdr->num_ref_idx_l1_active_minus1;
2393 for (i = 0; i < priv->RefPicList1_count && priv->RefPicList1[i]; i++)
2394 vaapi_fill_picture(&slice_param->RefPicList1[i], priv->RefPicList1[i]);
2395 for (; i <= slice_param->num_ref_idx_l1_active_minus1; i++)
2396 vaapi_init_picture(&slice_param->RefPicList1[i]);
2402 GstVaapiDecoderH264 *decoder,
2403 GstVaapiSliceH264 *slice,
2404 GstH264NalUnit *nalu
2407 GstH264SliceHdr * const slice_hdr = &slice->slice_hdr;
2408 VASliceParameterBufferH264 * const slice_param = slice->base.param;
2410 /* Fill in VASliceParameterBufferH264 */
2411 slice_param->slice_data_bit_offset = get_slice_data_bit_offset(slice_hdr, nalu);
2412 slice_param->first_mb_in_slice = slice_hdr->first_mb_in_slice;
2413 slice_param->slice_type = slice_hdr->type % 5;
2414 slice_param->direct_spatial_mv_pred_flag = slice_hdr->direct_spatial_mv_pred_flag;
2415 slice_param->cabac_init_idc = slice_hdr->cabac_init_idc;
2416 slice_param->slice_qp_delta = slice_hdr->slice_qp_delta;
2417 slice_param->disable_deblocking_filter_idc = slice_hdr->disable_deblocking_filter_idc;
2418 slice_param->slice_alpha_c0_offset_div2 = slice_hdr->slice_alpha_c0_offset_div2;
2419 slice_param->slice_beta_offset_div2 = slice_hdr->slice_beta_offset_div2;
2421 if (!fill_RefPicList(decoder, slice))
2423 if (!fill_pred_weight_table(decoder, slice))
2428 static GstVaapiDecoderStatus
2429 decode_slice(GstVaapiDecoderH264 *decoder, GstH264NalUnit *nalu)
2431 GstVaapiDecoderH264Private * const priv = decoder->priv;
2432 GstVaapiDecoderStatus status;
2433 GstVaapiPictureH264 *picture;
2434 GstVaapiSliceH264 *slice = NULL;
2435 GstH264SliceHdr *slice_hdr;
2436 GstH264ParserResult result;
2438 GST_DEBUG("slice (%u bytes)", nalu->size);
2440 slice = gst_vaapi_slice_h264_new(
2442 nalu->data + nalu->offset,
2446 GST_ERROR("failed to allocate slice");
2447 return GST_VAAPI_DECODER_STATUS_ERROR_ALLOCATION_FAILED;
2450 slice_hdr = &slice->slice_hdr;
2451 memset(slice_hdr, 0, sizeof(*slice_hdr));
2452 result = gst_h264_parser_parse_slice_hdr(priv->parser, nalu, slice_hdr, TRUE, TRUE);
2453 if (result != GST_H264_PARSER_OK) {
2454 status = get_status(result);
2458 if (is_new_picture(decoder, nalu, slice_hdr)) {
2459 status = decode_picture(decoder, nalu, slice_hdr);
2460 if (status != GST_VAAPI_DECODER_STATUS_SUCCESS)
2463 picture = priv->current_picture;
2465 if (!fill_slice(decoder, slice, nalu)) {
2466 status = GST_VAAPI_DECODER_STATUS_ERROR_UNKNOWN;
2469 gst_vaapi_picture_add_slice(
2470 GST_VAAPI_PICTURE_CAST(picture),
2471 GST_VAAPI_SLICE_CAST(slice)
2473 return GST_VAAPI_DECODER_STATUS_SUCCESS;
2477 gst_mini_object_unref(GST_MINI_OBJECT(slice));
2482 scan_for_start_code(GstAdapter *adapter, guint ofs, guint size, guint32 *scp)
2484 return (gint)gst_adapter_masked_scan_uint32_peek(adapter,
2485 0xffffff00, 0x00000100,
2490 static GstVaapiDecoderStatus
2491 decode_nalu(GstVaapiDecoderH264 *decoder, GstH264NalUnit *nalu)
2493 GstVaapiDecoderStatus status;
2495 switch (nalu->type) {
2496 case GST_H264_NAL_SLICE_IDR:
2497 /* fall-through. IDR specifics are handled in init_picture() */
2498 case GST_H264_NAL_SLICE:
2499 status = decode_slice(decoder, nalu);
2501 case GST_H264_NAL_SPS:
2502 status = decode_sps(decoder, nalu);
2504 case GST_H264_NAL_PPS:
2505 status = decode_pps(decoder, nalu);
2507 case GST_H264_NAL_SEI:
2508 status = decode_sei(decoder, nalu);
2510 case GST_H264_NAL_SEQ_END:
2511 status = decode_sequence_end(decoder);
2513 case GST_H264_NAL_AU_DELIMITER:
2514 /* skip all Access Unit NALs */
2515 status = GST_VAAPI_DECODER_STATUS_SUCCESS;
2517 case GST_H264_NAL_FILLER_DATA:
2518 /* skip all Filler Data NALs */
2519 status = GST_VAAPI_DECODER_STATUS_SUCCESS;
2522 GST_WARNING("unsupported NAL unit type %d", nalu->type);
2523 status = GST_VAAPI_DECODER_STATUS_ERROR_BITSTREAM_PARSER;
2529 static GstVaapiDecoderStatus
2530 decode_buffer(GstVaapiDecoderH264 *decoder, GstBuffer *buffer)
2532 GstVaapiDecoderH264Private * const priv = decoder->priv;
2533 GstVaapiDecoderStatus status;
2534 GstH264ParserResult result;
2535 GstH264NalUnit nalu;
2538 guint i, buf_size, nalu_size, size;
2542 buf = GST_BUFFER_DATA(buffer);
2543 buf_size = GST_BUFFER_SIZE(buffer);
2544 is_eos = GST_BUFFER_IS_EOS(buffer);
2545 if (buf && buf_size > 0)
2546 gst_adapter_push(priv->adapter, gst_buffer_ref(buffer));
2548 size = gst_adapter_available(priv->adapter);
2551 status = GST_VAAPI_DECODER_STATUS_SUCCESS;
2555 status = gst_vaapi_decoder_check_status(GST_VAAPI_DECODER(decoder));
2556 if (status != GST_VAAPI_DECODER_STATUS_SUCCESS)
2559 status = GST_VAAPI_DECODER_STATUS_ERROR_NO_DATA;
2561 if (size < priv->nal_length_size)
2563 buf = gst_adapter_peek(priv->adapter, priv->nal_length_size);
2566 for (i = 0; i < priv->nal_length_size; i++)
2567 nalu_size = (nalu_size << 8) | buf[i];
2569 buf_size = priv->nal_length_size + nalu_size;
2570 if (size < buf_size)
2572 buffer = gst_adapter_take_buffer(priv->adapter, buf_size);
2575 buf = GST_BUFFER_DATA(buffer);
2576 buf_size = GST_BUFFER_SIZE(buffer);
2578 result = gst_h264_parser_identify_nalu_avc(
2580 buf, 0, buf_size, priv->nal_length_size,
2587 ofs = scan_for_start_code(priv->adapter, 0, size, &start_code);
2590 gst_adapter_flush(priv->adapter, ofs);
2593 ofs = G_UNLIKELY(size < 8) ? -1 :
2594 scan_for_start_code(priv->adapter, 4, size - 4, NULL);
2596 // Assume the whole NAL unit is present if end-of-stream
2601 buffer = gst_adapter_take_buffer(priv->adapter, ofs);
2604 buf = GST_BUFFER_DATA(buffer);
2605 buf_size = GST_BUFFER_SIZE(buffer);
2607 result = gst_h264_parser_identify_nalu_unchecked(
2613 status = get_status(result);
2614 if (status == GST_VAAPI_DECODER_STATUS_SUCCESS)
2615 status = decode_nalu(decoder, &nalu);
2616 gst_buffer_unref(buffer);
2617 } while (status == GST_VAAPI_DECODER_STATUS_SUCCESS);
2619 if (is_eos && (status == GST_VAAPI_DECODER_STATUS_SUCCESS ||
2620 status == GST_VAAPI_DECODER_STATUS_ERROR_NO_DATA))
2621 status = decode_sequence_end(decoder);
2625 static GstVaapiDecoderStatus
2626 decode_codec_data(GstVaapiDecoderH264 *decoder, GstBuffer *buffer)
2628 GstVaapiDecoderH264Private * const priv = decoder->priv;
2629 GstVaapiDecoderStatus status;
2630 GstH264NalUnit nalu;
2631 GstH264ParserResult result;
2634 guint i, ofs, num_sps, num_pps;
2636 buf = GST_BUFFER_DATA(buffer);
2637 buf_size = GST_BUFFER_SIZE(buffer);
2638 if (!buf || buf_size == 0)
2639 return GST_VAAPI_DECODER_STATUS_SUCCESS;
2642 return GST_VAAPI_DECODER_STATUS_ERROR_NO_DATA;
2645 GST_ERROR("failed to decode codec-data, not in avcC format");
2646 return GST_VAAPI_DECODER_STATUS_ERROR_BITSTREAM_PARSER;
2649 priv->nal_length_size = (buf[4] & 0x03) + 1;
2651 num_sps = buf[5] & 0x1f;
2654 for (i = 0; i < num_sps; i++) {
2655 result = gst_h264_parser_identify_nalu_avc(
2657 buf, ofs, buf_size, 2,
2660 if (result != GST_H264_PARSER_OK)
2661 return get_status(result);
2663 status = decode_sps(decoder, &nalu);
2664 if (status != GST_VAAPI_DECODER_STATUS_SUCCESS)
2666 ofs = nalu.offset + nalu.size;
2672 for (i = 0; i < num_pps; i++) {
2673 result = gst_h264_parser_identify_nalu_avc(
2675 buf, ofs, buf_size, 2,
2678 if (result != GST_H264_PARSER_OK)
2679 return get_status(result);
2681 status = decode_pps(decoder, &nalu);
2682 if (status != GST_VAAPI_DECODER_STATUS_SUCCESS)
2684 ofs = nalu.offset + nalu.size;
2687 priv->is_avc = TRUE;
2691 GstVaapiDecoderStatus
2692 gst_vaapi_decoder_h264_decode(GstVaapiDecoder *base, GstBuffer *buffer)
2694 GstVaapiDecoderH264 * const decoder = GST_VAAPI_DECODER_H264(base);
2695 GstVaapiDecoderH264Private * const priv = decoder->priv;
2696 GstVaapiDecoderStatus status;
2697 GstBuffer *codec_data;
2699 g_return_val_if_fail(priv->is_constructed,
2700 GST_VAAPI_DECODER_STATUS_ERROR_INIT_FAILED);
2702 if (!priv->is_opened) {
2703 priv->is_opened = gst_vaapi_decoder_h264_open(decoder, buffer);
2704 if (!priv->is_opened)
2705 return GST_VAAPI_DECODER_STATUS_ERROR_UNSUPPORTED_CODEC;
2707 codec_data = GST_VAAPI_DECODER_CODEC_DATA(decoder);
2709 status = decode_codec_data(decoder, codec_data);
2710 if (status != GST_VAAPI_DECODER_STATUS_SUCCESS)
2714 return decode_buffer(decoder, buffer);
2718 gst_vaapi_decoder_h264_finalize(GObject *object)
2720 GstVaapiDecoderH264 * const decoder = GST_VAAPI_DECODER_H264(object);
2722 gst_vaapi_decoder_h264_destroy(decoder);
2724 G_OBJECT_CLASS(gst_vaapi_decoder_h264_parent_class)->finalize(object);
2728 gst_vaapi_decoder_h264_constructed(GObject *object)
2730 GstVaapiDecoderH264 * const decoder = GST_VAAPI_DECODER_H264(object);
2731 GstVaapiDecoderH264Private * const priv = decoder->priv;
2732 GObjectClass *parent_class;
2734 parent_class = G_OBJECT_CLASS(gst_vaapi_decoder_h264_parent_class);
2735 if (parent_class->constructed)
2736 parent_class->constructed(object);
2738 priv->is_constructed = gst_vaapi_decoder_h264_create(decoder);
2742 gst_vaapi_decoder_h264_class_init(GstVaapiDecoderH264Class *klass)
2744 GObjectClass * const object_class = G_OBJECT_CLASS(klass);
2745 GstVaapiDecoderClass * const decoder_class = GST_VAAPI_DECODER_CLASS(klass);
2747 g_type_class_add_private(klass, sizeof(GstVaapiDecoderH264Private));
2749 object_class->finalize = gst_vaapi_decoder_h264_finalize;
2750 object_class->constructed = gst_vaapi_decoder_h264_constructed;
2752 decoder_class->decode = gst_vaapi_decoder_h264_decode;
2756 gst_vaapi_decoder_h264_init(GstVaapiDecoderH264 *decoder)
2758 GstVaapiDecoderH264Private *priv;
2760 priv = GST_VAAPI_DECODER_H264_GET_PRIVATE(decoder);
2761 decoder->priv = priv;
2762 priv->parser = NULL;
2763 priv->current_picture = NULL;
2764 priv->dpb_count = 0;
2766 priv->profile = GST_VAAPI_PROFILE_UNKNOWN;
2767 priv->entrypoint = GST_VAAPI_ENTRYPOINT_VLD;
2768 priv->chroma_type = GST_VAAPI_CHROMA_TYPE_YUV420;
2769 priv->short_ref_count = 0;
2770 priv->long_ref_count = 0;
2771 priv->RefPicList0_count = 0;
2772 priv->RefPicList1_count = 0;
2773 priv->nal_length_size = 0;
2776 priv->adapter = NULL;
2777 priv->field_poc[0] = 0;
2778 priv->field_poc[1] = 0;
2781 priv->prev_poc_msb = 0;
2782 priv->prev_poc_lsb = 0;
2783 priv->frame_num_offset = 0;
2784 priv->frame_num = 0;
2785 priv->prev_frame_num = 0;
2786 priv->prev_pic_has_mmco5 = FALSE;
2787 priv->prev_pic_structure = GST_VAAPI_PICTURE_STRUCTURE_FRAME;
2788 priv->is_constructed = FALSE;
2789 priv->is_opened = FALSE;
2790 priv->is_avc = FALSE;
2791 priv->has_context = FALSE;
2793 memset(priv->dpb, 0, sizeof(priv->dpb));
2794 memset(priv->short_ref, 0, sizeof(priv->short_ref));
2795 memset(priv->long_ref, 0, sizeof(priv->long_ref));
2796 memset(priv->RefPicList0, 0, sizeof(priv->RefPicList0));
2797 memset(priv->RefPicList1, 0, sizeof(priv->RefPicList1));
2801 * gst_vaapi_decoder_h264_new:
2802 * @display: a #GstVaapiDisplay
2803 * @caps: a #GstCaps holding codec information
2805 * Creates a new #GstVaapiDecoder for MPEG-2 decoding. The @caps can
2806 * hold extra information like codec-data and pictured coded size.
2808 * Return value: the newly allocated #GstVaapiDecoder object
2811 gst_vaapi_decoder_h264_new(GstVaapiDisplay *display, GstCaps *caps)
2813 GstVaapiDecoderH264 *decoder;
2815 g_return_val_if_fail(GST_VAAPI_IS_DISPLAY(display), NULL);
2816 g_return_val_if_fail(GST_IS_CAPS(caps), NULL);
2818 decoder = g_object_new(
2819 GST_VAAPI_TYPE_DECODER_H264,
2824 if (!decoder->priv->is_constructed) {
2825 g_object_unref(decoder);
2828 return GST_VAAPI_DECODER_CAST(decoder);