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
30 #include <gst/base/gstadapter.h>
31 #include <gst/codecparsers/gsth264parser.h>
32 #include "gstvaapidecoder_h264.h"
33 #include "gstvaapidecoder_objects.h"
34 #include "gstvaapidecoder_priv.h"
35 #include "gstvaapidisplay_priv.h"
36 #include "gstvaapiobject_priv.h"
39 #include "gstvaapidebug.h"
41 typedef struct _GstVaapiPictureH264 GstVaapiPictureH264;
42 typedef struct _GstVaapiPictureH264Class GstVaapiPictureH264Class;
43 typedef struct _GstVaapiSliceH264 GstVaapiSliceH264;
44 typedef struct _GstVaapiSliceH264Class GstVaapiSliceH264Class;
46 /* ------------------------------------------------------------------------- */
47 /* --- H.264 Pictures --- */
48 /* ------------------------------------------------------------------------- */
50 #define GST_VAAPI_TYPE_PICTURE_H264 \
51 (gst_vaapi_picture_h264_get_type())
53 #define GST_VAAPI_PICTURE_H264_CAST(obj) \
54 ((GstVaapiPictureH264 *)(obj))
56 #define GST_VAAPI_PICTURE_H264(obj) \
57 (G_TYPE_CHECK_INSTANCE_CAST((obj), \
58 GST_VAAPI_TYPE_PICTURE_H264, \
61 #define GST_VAAPI_PICTURE_H264_CLASS(klass) \
62 (G_TYPE_CHECK_CLASS_CAST((klass), \
63 GST_VAAPI_TYPE_PICTURE_H264, \
64 GstVaapiPictureH264Class))
66 #define GST_VAAPI_IS_PICTURE_H264(obj) \
67 (G_TYPE_CHECK_INSTANCE_TYPE((obj), GST_VAAPI_TYPE_PICTURE_H264))
69 #define GST_VAAPI_IS_PICTURE_H264_CLASS(klass) \
70 (G_TYPE_CHECK_CLASS_TYPE((klass), GST_VAAPI_TYPE_PICTURE_H264))
72 #define GST_VAAPI_PICTURE_H264_GET_CLASS(obj) \
73 (G_TYPE_INSTANCE_GET_CLASS((obj), \
74 GST_VAAPI_TYPE_PICTURE_H264, \
75 GstVaapiPictureH264Class))
77 struct _GstVaapiPictureH264 {
81 gint32 frame_num; // Original frame_num from slice_header()
82 gint32 frame_num_wrap; // Temporary for ref pic marking: FrameNumWrap
83 gint32 pic_num; // Temporary for ref pic marking: PicNum
84 gint32 long_term_pic_num; // Temporary for ref pic marking: LongTermPicNum
86 guint is_long_term : 1;
87 guint field_pic_flag : 1;
88 guint bottom_field_flag : 1;
90 guint output_flag : 1;
91 guint output_needed : 1;
94 struct _GstVaapiPictureH264Class {
96 GstVaapiPictureClass parent_class;
99 GST_VAAPI_CODEC_DEFINE_TYPE(GstVaapiPictureH264,
100 gst_vaapi_picture_h264,
101 GST_VAAPI_TYPE_PICTURE)
104 gst_vaapi_picture_h264_destroy(GstVaapiPictureH264 *decoder)
109 gst_vaapi_picture_h264_create(
110 GstVaapiPictureH264 *picture,
111 const GstVaapiCodecObjectConstructorArgs *args
118 gst_vaapi_picture_h264_init(GstVaapiPictureH264 *picture)
120 VAPictureH264 *va_pic;
122 va_pic = &picture->info;
124 va_pic->TopFieldOrderCnt = 0;
125 va_pic->BottomFieldOrderCnt = 0;
128 picture->is_long_term = FALSE;
129 picture->is_idr = FALSE;
130 picture->has_mmco_5 = FALSE;
131 picture->output_needed = FALSE;
134 static inline GstVaapiPictureH264 *
135 gst_vaapi_picture_h264_new(GstVaapiDecoderH264 *decoder)
137 GstVaapiCodecObject *object;
139 g_return_val_if_fail(GST_VAAPI_IS_DECODER(decoder), NULL);
141 object = gst_vaapi_codec_object_new(
142 GST_VAAPI_TYPE_PICTURE_H264,
143 GST_VAAPI_CODEC_BASE(decoder),
144 NULL, sizeof(VAPictureParameterBufferH264),
149 return GST_VAAPI_PICTURE_H264_CAST(object);
152 /* ------------------------------------------------------------------------- */
154 /* ------------------------------------------------------------------------- */
156 #define GST_VAAPI_TYPE_SLICE_H264 \
157 (gst_vaapi_slice_h264_get_type())
159 #define GST_VAAPI_SLICE_H264_CAST(obj) \
160 ((GstVaapiSliceH264 *)(obj))
162 #define GST_VAAPI_SLICE_H264(obj) \
163 (G_TYPE_CHECK_INSTANCE_CAST((obj), \
164 GST_VAAPI_TYPE_SLICE_H264, \
167 #define GST_VAAPI_SLICE_H264_CLASS(klass) \
168 (G_TYPE_CHECK_CLASS_CAST((klass), \
169 GST_VAAPI_TYPE_SLICE_H264, \
170 GstVaapiSliceH264Class))
172 #define GST_VAAPI_IS_SLICE_H264(obj) \
173 (G_TYPE_CHECK_INSTANCE_TYPE((obj), GST_VAAPI_TYPE_SLICE_H264))
175 #define GST_VAAPI_IS_SLICE_H264_CLASS(klass) \
176 (G_TYPE_CHECK_CLASS_TYPE((klass), GST_VAAPI_TYPE_SLICE_H264))
178 #define GST_VAAPI_SLICE_H264_GET_CLASS(obj) \
179 (G_TYPE_INSTANCE_GET_CLASS((obj), \
180 GST_VAAPI_TYPE_SLICE_H264, \
181 GstVaapiSliceH264Class))
183 struct _GstVaapiSliceH264 {
185 GstH264SliceHdr slice_hdr; // parsed slice_header()
188 struct _GstVaapiSliceH264Class {
190 GstVaapiSliceClass parent_class;
193 GST_VAAPI_CODEC_DEFINE_TYPE(GstVaapiSliceH264,
194 gst_vaapi_slice_h264,
195 GST_VAAPI_TYPE_SLICE)
198 gst_vaapi_slice_h264_destroy(GstVaapiSliceH264 *slice)
203 gst_vaapi_slice_h264_create(
204 GstVaapiSliceH264 *slice,
205 const GstVaapiCodecObjectConstructorArgs *args
212 gst_vaapi_slice_h264_init(GstVaapiSliceH264 *slice)
216 static inline GstVaapiSliceH264 *
217 gst_vaapi_slice_h264_new(
218 GstVaapiDecoderH264 *decoder,
223 GstVaapiCodecObject *object;
225 g_return_val_if_fail(GST_VAAPI_IS_DECODER(decoder), NULL);
227 object = gst_vaapi_codec_object_new(
228 GST_VAAPI_TYPE_SLICE_H264,
229 GST_VAAPI_CODEC_BASE(decoder),
230 NULL, sizeof(VASliceParameterBufferH264),
235 return GST_VAAPI_SLICE_H264_CAST(object);
238 /* ------------------------------------------------------------------------- */
239 /* --- H.264 Decoder --- */
240 /* ------------------------------------------------------------------------- */
242 G_DEFINE_TYPE(GstVaapiDecoderH264,
243 gst_vaapi_decoder_h264,
244 GST_VAAPI_TYPE_DECODER);
246 #define GST_VAAPI_DECODER_H264_GET_PRIVATE(obj) \
247 (G_TYPE_INSTANCE_GET_PRIVATE((obj), \
248 GST_VAAPI_TYPE_DECODER_H264, \
249 GstVaapiDecoderH264Private))
251 // Used for field_poc[]
253 #define BOTTOM_FIELD 1
255 struct _GstVaapiDecoderH264Private {
257 GstBuffer *sub_buffer;
258 GstH264NalParser *parser;
263 GstVaapiPictureH264 *current_picture;
264 GstVaapiPictureH264 *dpb[16];
267 GstVaapiProfile profile;
268 GstVaapiPictureH264 *short_ref[32];
269 guint short_ref_count;
270 GstVaapiPictureH264 *long_ref[32];
271 guint long_ref_count;
272 GstVaapiPictureH264 *RefPicList0[32];
273 guint RefPicList0_count;
274 GstVaapiPictureH264 *RefPicList1[32];
275 guint RefPicList1_count;
276 guint nal_length_size;
283 guint8 scaling_list_4x4[6][16];
284 guint8 scaling_list_8x8[6][64];
285 gint32 field_poc[2]; // 0:TopFieldOrderCnt / 1:BottomFieldOrderCnt
286 gint32 poc_msb; // PicOrderCntMsb
287 gint32 poc_lsb; // pic_order_cnt_lsb (from slice_header())
288 gint32 prev_poc_msb; // prevPicOrderCntMsb
289 gint32 prev_poc_lsb; // prevPicOrderCntLsb
290 gint32 frame_num_offset; // FrameNumOffset
291 gint32 prev_frame_num_offset; // prevFrameNumOffset
292 gint32 frame_num; // frame_num (from slice_header())
293 gint32 prev_frame_num; // prevFrameNum
294 guint is_constructed : 1;
297 guint has_context : 1;
301 decode_picture_end(GstVaapiDecoderH264 *decoder, GstVaapiPictureH264 *picture);
305 GstVaapiDecoderH264 *decoder,
306 GstVaapiPictureH264 **pictures,
311 dpb_remove_index(GstVaapiDecoderH264 *decoder, guint index)
313 GstVaapiDecoderH264Private * const priv = decoder->priv;
314 guint num_pictures = --priv->dpb_count;
316 if (index != num_pictures)
317 gst_vaapi_picture_replace(&priv->dpb[index], priv->dpb[num_pictures]);
318 gst_vaapi_picture_replace(&priv->dpb[num_pictures], NULL);
321 static inline gboolean
322 dpb_output(GstVaapiDecoderH264 *decoder, GstVaapiPictureH264 *picture)
324 /* XXX: update cropping rectangle */
325 picture->output_needed = FALSE;
326 return gst_vaapi_picture_output(GST_VAAPI_PICTURE_CAST(picture));
330 dpb_bump(GstVaapiDecoderH264 *decoder)
332 GstVaapiDecoderH264Private * const priv = decoder->priv;
333 guint i, lowest_poc_index;
336 for (i = 0; i < priv->dpb_count; i++) {
337 if (priv->dpb[i]->output_needed)
340 if (i == priv->dpb_count)
343 lowest_poc_index = i++;
344 for (; i < priv->dpb_count; i++) {
345 GstVaapiPictureH264 * const picture = priv->dpb[i];
346 if (picture->output_needed && picture->poc < priv->dpb[lowest_poc_index]->poc)
347 lowest_poc_index = i;
350 success = dpb_output(decoder, priv->dpb[lowest_poc_index]);
351 if (!GST_VAAPI_PICTURE_IS_REFERENCE(priv->dpb[lowest_poc_index]))
352 dpb_remove_index(decoder, lowest_poc_index);
357 dpb_flush(GstVaapiDecoderH264 *decoder)
359 GstVaapiDecoderH264Private * const priv = decoder->priv;
361 while (dpb_bump(decoder))
363 clear_references(decoder, priv->dpb, &priv->dpb_count);
367 dpb_add(GstVaapiDecoderH264 *decoder, GstVaapiPictureH264 *picture)
369 GstVaapiDecoderH264Private * const priv = decoder->priv;
372 // Remove all unused pictures
377 while (i < priv->dpb_count) {
378 GstVaapiPictureH264 * const picture = priv->dpb[i];
379 if (!picture->output_needed &&
380 !GST_VAAPI_PICTURE_IS_REFERENCE(picture))
381 dpb_remove_index(decoder, i);
387 // C.4.5.1 - Storage and marking of a reference decoded picture into the DPB
388 if (GST_VAAPI_PICTURE_IS_REFERENCE(picture)) {
389 while (priv->dpb_count == priv->dpb_size) {
390 if (!dpb_bump(decoder))
393 gst_vaapi_picture_replace(&priv->dpb[priv->dpb_count++], picture);
394 if (picture->output_flag)
395 picture->output_needed = TRUE;
398 // C.4.5.2 - Storage and marking of a non-reference decoded picture into the DPB
400 if (!picture->output_flag)
402 while (priv->dpb_count == priv->dpb_size) {
403 for (i = 0; i < priv->dpb_count; i++) {
404 if (priv->dpb[i]->output_needed &&
405 priv->dpb[i]->poc < picture->poc)
408 if (i == priv->dpb_count)
409 return dpb_output(decoder, picture);
410 if (!dpb_bump(decoder))
413 gst_vaapi_picture_replace(&priv->dpb[priv->dpb_count++], picture);
414 picture->output_needed = TRUE;
420 dpb_reset(GstVaapiDecoderH264 *decoder, GstH264SPS *sps)
422 GstVaapiDecoderH264Private * const priv = decoder->priv;
423 guint max_dec_frame_buffering, MaxDpbMbs, PicSizeMbs;
425 /* Table A-1 - Level limits */
426 switch (sps->level_idc) {
427 case 10: MaxDpbMbs = 396; break;
428 case 11: MaxDpbMbs = 900; break;
429 case 12: MaxDpbMbs = 2376; break;
430 case 13: MaxDpbMbs = 2376; break;
431 case 20: MaxDpbMbs = 2376; break;
432 case 21: MaxDpbMbs = 4752; break;
433 case 22: MaxDpbMbs = 8100; break;
434 case 30: MaxDpbMbs = 8100; break;
435 case 31: MaxDpbMbs = 18000; break;
436 case 32: MaxDpbMbs = 20480; break;
437 case 40: MaxDpbMbs = 32768; break;
438 case 41: MaxDpbMbs = 32768; break;
439 case 42: MaxDpbMbs = 34816; break;
440 case 50: MaxDpbMbs = 110400; break;
441 case 51: MaxDpbMbs = 184320; break;
443 g_assert(0 && "unhandled level");
447 PicSizeMbs = ((sps->pic_width_in_mbs_minus1 + 1) *
448 (sps->pic_height_in_map_units_minus1 + 1) *
449 (sps->frame_mbs_only_flag ? 1 : 2));
450 max_dec_frame_buffering = MaxDpbMbs / PicSizeMbs;
451 if (max_dec_frame_buffering > 8)
452 max_dec_frame_buffering = 8;
455 if (sps->vui_parameters_present_flag) {
456 GstH264VUIParams * const vui_params = &sps->vui_parameters;
457 if (vui_params->bitstream_restriction_flag)
458 max_dec_frame_buffering = vui_params->max_dec_frame_buffering;
460 switch (sps->profile_idc) {
461 case 44: // CAVLC 4:4:4 Intra profile
462 case 86: // Scalable High profile
463 case 100: // High profile
464 case 110: // High 10 profile
465 case 122: // High 4:2:2 profile
466 case 244: // High 4:4:4 Predictive profile
467 if (sps->constraint_set3_flag)
468 max_dec_frame_buffering = 0;
474 if (max_dec_frame_buffering > 16)
475 max_dec_frame_buffering = 16;
476 else if (max_dec_frame_buffering < sps->num_ref_frames)
477 max_dec_frame_buffering = sps->num_ref_frames;
478 priv->dpb_size = MAX(1, max_dec_frame_buffering);
479 GST_DEBUG("DPB size %u", priv->dpb_size);
482 static GstVaapiDecoderStatus
483 get_status(GstH264ParserResult result)
485 GstVaapiDecoderStatus status;
488 case GST_H264_PARSER_OK:
489 status = GST_VAAPI_DECODER_STATUS_SUCCESS;
491 case GST_H264_PARSER_NO_NAL_END:
492 status = GST_VAAPI_DECODER_STATUS_ERROR_NO_DATA;
494 case GST_H264_PARSER_ERROR:
495 status = GST_VAAPI_DECODER_STATUS_ERROR_BITSTREAM_PARSER;
498 status = GST_VAAPI_DECODER_STATUS_ERROR_UNKNOWN;
504 static inline GstH264DecRefPicMarking *
505 get_dec_ref_pic_marking(GstVaapiPictureH264 *picture_h264)
507 GstVaapiPicture * const picture = GST_VAAPI_PICTURE_CAST(picture_h264);
508 GstVaapiSliceH264 *slice;
510 slice = g_ptr_array_index(picture->slices, picture->slices->len - 1);
511 return &slice->slice_hdr.dec_ref_pic_marking;
515 gst_vaapi_decoder_h264_clear_buffer(GstVaapiDecoder *base)
517 GstVaapiDecoderH264 * const decoder = GST_VAAPI_DECODER_H264(base);
518 GstVaapiDecoderH264Private * const priv = decoder->priv;
520 gst_vaapi_picture_replace(&priv->current_picture, NULL);
521 clear_references(decoder, priv->short_ref, &priv->short_ref_count);
522 clear_references(decoder, priv->long_ref, &priv->long_ref_count );
523 clear_references(decoder, priv->dpb, &priv->dpb_count );
525 if (priv->sub_buffer) {
526 gst_buffer_unref(priv->sub_buffer);
527 priv->sub_buffer = NULL;
531 gst_adapter_clear(priv->adapter);
536 gst_vaapi_decoder_h264_close(GstVaapiDecoderH264 *decoder)
538 GstVaapiDecoderH264Private * const priv = decoder->priv;
540 gst_vaapi_decoder_h264_clear_buffer(GST_VAAPI_DECODER_CAST(decoder));
543 gst_h264_nal_parser_free(priv->parser);
548 g_object_unref(priv->adapter);
549 priv->adapter = NULL;
554 gst_vaapi_decoder_h264_open(GstVaapiDecoderH264 *decoder, GstBuffer *buffer)
556 GstVaapiDecoderH264Private * const priv = decoder->priv;
558 gst_vaapi_decoder_h264_close(decoder);
560 priv->adapter = gst_adapter_new();
564 priv->parser = gst_h264_nal_parser_new();
571 gst_vaapi_decoder_h264_destroy(GstVaapiDecoderH264 *decoder)
573 gst_vaapi_decoder_h264_close(decoder);
577 gst_vaapi_decoder_h264_create(GstVaapiDecoderH264 *decoder)
579 if (!GST_VAAPI_DECODER_CODEC(decoder))
585 min_surfaces_count(guint dbp_size)
587 guint count = dbp_size + 4;
589 if (count < GST_DECODER_DEFAULT_SURFACES_COUNT)
590 count = GST_DECODER_DEFAULT_SURFACES_COUNT;
594 static GstVaapiDecoderStatus
595 ensure_context(GstVaapiDecoderH264 *decoder, GstH264SPS *sps)
597 GstVaapiDecoderH264Private * const priv = decoder->priv;
598 GstVaapiProfile profiles[2];
599 GstVaapiEntrypoint entrypoint = GST_VAAPI_ENTRYPOINT_VLD;
600 guint i, n_profiles = 0;
601 gboolean success, reset_context = FALSE;
603 if (!priv->has_context || priv->sps->profile_idc != sps->profile_idc) {
604 GST_DEBUG("profile changed");
605 reset_context = TRUE;
607 switch (sps->profile_idc) {
609 profiles[n_profiles++] = GST_VAAPI_PROFILE_H264_BASELINE;
612 profiles[n_profiles++] = GST_VAAPI_PROFILE_H264_MAIN;
615 profiles[n_profiles++] = GST_VAAPI_PROFILE_H264_HIGH;
618 GST_DEBUG("unsupported profile %d", sps->profile_idc);
619 return GST_VAAPI_DECODER_STATUS_ERROR_UNSUPPORTED_PROFILE;
622 for (i = 0; i < n_profiles; i++) {
623 success = gst_vaapi_display_has_decoder(
624 GST_VAAPI_DECODER_DISPLAY(decoder),
632 return GST_VAAPI_DECODER_STATUS_ERROR_UNSUPPORTED_PROFILE;
633 priv->profile = profiles[i];
636 if (!priv->has_context ||
637 priv->sps->chroma_format_idc != sps->chroma_format_idc) {
638 GST_DEBUG("chroma format changed");
639 reset_context = TRUE;
641 /* XXX: theoritically, we could handle 4:2:2 format */
642 if (sps->chroma_format_idc != 1)
643 return GST_VAAPI_DECODER_STATUS_ERROR_UNSUPPORTED_CHROMA_FORMAT;
646 if (!priv->has_context ||
647 priv->sps->width != sps->width ||
648 priv->sps->height != sps->height) {
649 GST_DEBUG("size changed");
650 reset_context = TRUE;
652 priv->width = sps->width;
653 priv->height = sps->height;
654 priv->mb_width = sps->pic_width_in_mbs_minus1 + 1;
655 priv->mb_height = sps->pic_height_in_map_units_minus1 + 1;
656 priv->mb_height *= 2 - sps->frame_mbs_only_flag;
661 dpb_reset(decoder, sps);
663 success = gst_vaapi_decoder_ensure_context(
664 GST_VAAPI_DECODER(decoder),
669 min_surfaces_count(priv->dpb_size)
672 return GST_VAAPI_DECODER_STATUS_ERROR_UNKNOWN;
673 priv->has_context = TRUE;
676 return GST_VAAPI_DECODER_STATUS_SUCCESS;
679 static GstVaapiDecoderStatus
680 ensure_quant_matrix(GstVaapiDecoderH264 *decoder, GstH264PPS *pps)
682 GstVaapiDecoderH264Private * const priv = decoder->priv;
684 if (priv->pps != pps) {
685 memcpy(priv->scaling_list_4x4, pps->scaling_lists_4x4,
686 sizeof(priv->scaling_list_4x4));
687 memcpy(priv->scaling_list_8x8, pps->scaling_lists_8x8,
688 sizeof(priv->scaling_list_8x8));
690 return GST_VAAPI_DECODER_STATUS_SUCCESS;
694 decode_current_picture(GstVaapiDecoderH264 *decoder)
696 GstVaapiDecoderH264Private * const priv = decoder->priv;
697 GstVaapiPictureH264 * const picture = priv->current_picture;
698 gboolean success = FALSE;
703 if (!decode_picture_end(decoder, picture))
705 if (!gst_vaapi_picture_decode(GST_VAAPI_PICTURE_CAST(picture)))
709 gst_vaapi_picture_replace(&priv->current_picture, NULL);
713 static GstVaapiDecoderStatus
714 decode_sps(GstVaapiDecoderH264 *decoder, GstH264NalUnit *nalu)
716 GstVaapiDecoderH264Private * const priv = decoder->priv;
717 GstH264SPS * const sps = &priv->last_sps;
718 GstH264ParserResult result;
720 GST_DEBUG("decode SPS");
722 if (priv->current_picture && !decode_current_picture(decoder))
723 return GST_VAAPI_DECODER_STATUS_ERROR_UNKNOWN;
725 memset(sps, 0, sizeof(*sps));
726 result = gst_h264_parser_parse_sps(priv->parser, nalu, sps, TRUE);
727 if (result != GST_H264_PARSER_OK)
728 return get_status(result);
730 return ensure_context(decoder, sps);
733 static GstVaapiDecoderStatus
734 decode_pps(GstVaapiDecoderH264 *decoder, GstH264NalUnit *nalu)
736 GstVaapiDecoderH264Private * const priv = decoder->priv;
737 GstH264PPS * const pps = &priv->last_pps;
738 GstH264ParserResult result;
740 GST_DEBUG("decode PPS");
742 if (priv->current_picture && !decode_current_picture(decoder))
743 return GST_VAAPI_DECODER_STATUS_ERROR_UNKNOWN;
745 memset(pps, 0, sizeof(*pps));
746 result = gst_h264_parser_parse_pps(priv->parser, nalu, pps);
747 if (result != GST_H264_PARSER_OK)
748 return get_status(result);
750 return GST_VAAPI_DECODER_STATUS_SUCCESS;
753 static GstVaapiDecoderStatus
754 decode_sei(GstVaapiDecoderH264 *decoder, GstH264NalUnit *nalu)
756 GstVaapiDecoderH264Private * const priv = decoder->priv;
757 GstH264SEIMessage sei;
758 GstH264ParserResult result;
760 GST_DEBUG("decode SEI");
762 memset(&sei, 0, sizeof(sei));
763 result = gst_h264_parser_parse_sei(priv->parser, nalu, &sei);
764 if (result != GST_H264_PARSER_OK) {
765 GST_WARNING("failed to decode SEI, payload type:%d", sei.payloadType);
766 return get_status(result);
769 return GST_VAAPI_DECODER_STATUS_SUCCESS;
772 static GstVaapiDecoderStatus
773 decode_sequence_end(GstVaapiDecoderH264 *decoder)
775 GstVaapiDecoderH264Private * const priv = decoder->priv;
777 GST_DEBUG("decode sequence-end");
779 if (priv->current_picture && !decode_current_picture(decoder))
780 return GST_VAAPI_DECODER_STATUS_ERROR_UNKNOWN;
782 return GST_VAAPI_DECODER_STATUS_END_OF_STREAM;
785 /* 8.2.1.1 - Decoding process for picture order count type 0 */
788 GstVaapiDecoderH264 *decoder,
789 GstVaapiPictureH264 *picture,
790 GstH264SliceHdr *slice_hdr
793 GstVaapiDecoderH264Private * const priv = decoder->priv;
794 GstH264PPS * const pps = slice_hdr->pps;
795 GstH264SPS * const sps = pps->sequence;
796 const gint32 MaxPicOrderCntLsb = 1 << (sps->log2_max_pic_order_cnt_lsb_minus4 + 4);
798 GST_DEBUG("decode picture order count type 0");
801 priv->poc_lsb = slice_hdr->pic_order_cnt_lsb;
802 if (priv->poc_lsb < priv->prev_poc_lsb &&
803 (priv->prev_poc_lsb - priv->poc_lsb) >= (MaxPicOrderCntLsb / 2))
804 priv->poc_msb = priv->prev_poc_msb + MaxPicOrderCntLsb;
805 else if (priv->poc_lsb > priv->prev_poc_lsb &&
806 (priv->poc_lsb - priv->prev_poc_lsb) > (MaxPicOrderCntLsb / 2))
807 priv->poc_msb = priv->prev_poc_msb - MaxPicOrderCntLsb;
809 priv->poc_msb = priv->prev_poc_msb;
812 if (!slice_hdr->field_pic_flag || !slice_hdr->bottom_field_flag)
813 priv->field_poc[TOP_FIELD] = priv->poc_msb + priv->poc_lsb;
816 if (!slice_hdr->field_pic_flag)
817 priv->field_poc[BOTTOM_FIELD] = priv->field_poc[TOP_FIELD] +
818 slice_hdr->delta_pic_order_cnt_bottom;
819 else if (slice_hdr->bottom_field_flag)
820 priv->field_poc[BOTTOM_FIELD] = priv->poc_msb + priv->poc_lsb;
823 /* 8.2.1.2 - Decoding process for picture order count type 1 */
826 GstVaapiDecoderH264 *decoder,
827 GstVaapiPictureH264 *picture,
828 GstH264SliceHdr *slice_hdr
831 GstVaapiDecoderH264Private * const priv = decoder->priv;
832 GstH264PPS * const pps = slice_hdr->pps;
833 GstH264SPS * const sps = pps->sequence;
834 const gint32 MaxFrameNum = 1 << (sps->log2_max_frame_num_minus4 + 4);
835 gint32 abs_frame_num, expected_poc;
838 GST_DEBUG("decode picture order count type 1");
842 priv->frame_num_offset = 0;
843 else if (priv->prev_frame_num > priv->frame_num)
844 priv->frame_num_offset = priv->prev_frame_num_offset + MaxFrameNum;
846 priv->frame_num_offset = priv->prev_frame_num_offset;
849 if (sps->num_ref_frames_in_pic_order_cnt_cycle != 0)
850 abs_frame_num = priv->frame_num_offset + priv->frame_num;
853 if (!GST_VAAPI_PICTURE_IS_REFERENCE(picture) && abs_frame_num > 0)
854 abs_frame_num = abs_frame_num - 1;
856 if (abs_frame_num > 0) {
857 gint32 expected_delta_per_poc_cycle;
858 gint32 poc_cycle_cnt, frame_num_in_poc_cycle;
860 expected_delta_per_poc_cycle = 0;
861 for (i = 0; i < sps->num_ref_frames_in_pic_order_cnt_cycle; i++)
862 expected_delta_per_poc_cycle += sps->offset_for_ref_frame[i];
865 poc_cycle_cnt = (abs_frame_num - 1) /
866 sps->num_ref_frames_in_pic_order_cnt_cycle;
867 frame_num_in_poc_cycle = (abs_frame_num - 1) %
868 sps->num_ref_frames_in_pic_order_cnt_cycle;
871 expected_poc = poc_cycle_cnt * expected_delta_per_poc_cycle;
872 for (i = 0; i <= frame_num_in_poc_cycle; i++)
873 expected_poc += sps->offset_for_ref_frame[i];
877 if (!GST_VAAPI_PICTURE_IS_REFERENCE(picture))
878 expected_poc += sps->offset_for_non_ref_pic;
881 if (!slice_hdr->field_pic_flag) {
882 priv->field_poc[TOP_FIELD] = expected_poc +
883 slice_hdr->delta_pic_order_cnt[0];
884 priv->field_poc[BOTTOM_FIELD] = priv->field_poc[TOP_FIELD] +
885 sps->offset_for_top_to_bottom_field +
886 slice_hdr->delta_pic_order_cnt[1];
888 else if (!slice_hdr->bottom_field_flag)
889 priv->field_poc[TOP_FIELD] = expected_poc +
890 slice_hdr->delta_pic_order_cnt[0];
892 priv->field_poc[BOTTOM_FIELD] = expected_poc +
893 sps->offset_for_top_to_bottom_field + slice_hdr->delta_pic_order_cnt[0];
896 /* 8.2.1.3 - Decoding process for picture order count type 2 */
899 GstVaapiDecoderH264 *decoder,
900 GstVaapiPictureH264 *picture,
901 GstH264SliceHdr *slice_hdr
904 GstVaapiDecoderH264Private * const priv = decoder->priv;
905 GstH264PPS * const pps = slice_hdr->pps;
906 GstH264SPS * const sps = pps->sequence;
907 const gint32 MaxFrameNum = 1 << (sps->log2_max_frame_num_minus4 + 4);
910 GST_DEBUG("decode picture order count type 2");
914 priv->frame_num_offset = 0;
915 else if (priv->prev_frame_num > priv->frame_num)
916 priv->frame_num_offset = priv->prev_frame_num_offset + MaxFrameNum;
918 priv->frame_num_offset = priv->prev_frame_num_offset;
923 else if (!GST_VAAPI_PICTURE_IS_REFERENCE(picture))
924 temp_poc = 2 * (priv->frame_num_offset + priv->frame_num) - 1;
926 temp_poc = 2 * (priv->frame_num_offset + priv->frame_num);
929 if (!slice_hdr->field_pic_flag) {
930 priv->field_poc[TOP_FIELD] = temp_poc;
931 priv->field_poc[BOTTOM_FIELD] = temp_poc;
933 else if (slice_hdr->bottom_field_flag)
934 priv->field_poc[BOTTOM_FIELD] = temp_poc;
936 priv->field_poc[TOP_FIELD] = temp_poc;
939 /* 8.2.1 - Decoding process for picture order count */
942 GstVaapiDecoderH264 *decoder,
943 GstVaapiPictureH264 *picture,
944 GstH264SliceHdr *slice_hdr
947 GstVaapiDecoderH264Private * const priv = decoder->priv;
948 VAPictureH264 * const pic = &picture->info;
949 GstH264PPS * const pps = slice_hdr->pps;
950 GstH264SPS * const sps = pps->sequence;
952 switch (sps->pic_order_cnt_type) {
954 init_picture_poc_0(decoder, picture, slice_hdr);
957 init_picture_poc_1(decoder, picture, slice_hdr);
960 init_picture_poc_2(decoder, picture, slice_hdr);
964 if (!(pic->flags & VA_PICTURE_H264_BOTTOM_FIELD))
965 pic->TopFieldOrderCnt = priv->field_poc[TOP_FIELD];
966 if (!(pic->flags & VA_PICTURE_H264_TOP_FIELD))
967 pic->BottomFieldOrderCnt = priv->field_poc[BOTTOM_FIELD];
968 picture->poc = MIN(pic->TopFieldOrderCnt, pic->BottomFieldOrderCnt);
972 compare_picture_pic_num_dec(const void *a, const void *b)
974 const GstVaapiPictureH264 * const picA = *(GstVaapiPictureH264 **)a;
975 const GstVaapiPictureH264 * const picB = *(GstVaapiPictureH264 **)b;
977 return picB->pic_num - picA->pic_num;
981 compare_picture_long_term_pic_num_inc(const void *a, const void *b)
983 const GstVaapiPictureH264 * const picA = *(GstVaapiPictureH264 **)a;
984 const GstVaapiPictureH264 * const picB = *(GstVaapiPictureH264 **)b;
986 return picA->long_term_pic_num - picB->long_term_pic_num;
990 compare_picture_poc_dec(const void *a, const void *b)
992 const GstVaapiPictureH264 * const picA = *(GstVaapiPictureH264 **)a;
993 const GstVaapiPictureH264 * const picB = *(GstVaapiPictureH264 **)b;
995 return picB->poc - picA->poc;
999 compare_picture_poc_inc(const void *a, const void *b)
1001 const GstVaapiPictureH264 * const picA = *(GstVaapiPictureH264 **)a;
1002 const GstVaapiPictureH264 * const picB = *(GstVaapiPictureH264 **)b;
1004 return picA->poc - picB->poc;
1008 compare_picture_frame_num_wrap_dec(const void *a, const void *b)
1010 const GstVaapiPictureH264 * const picA = *(GstVaapiPictureH264 **)a;
1011 const GstVaapiPictureH264 * const picB = *(GstVaapiPictureH264 **)b;
1013 return picB->frame_num_wrap - picA->frame_num_wrap;
1017 compare_picture_long_term_frame_idx_inc(const void *a, const void *b)
1019 const GstVaapiPictureH264 * const picA = *(GstVaapiPictureH264 **)a;
1020 const GstVaapiPictureH264 * const picB = *(GstVaapiPictureH264 **)b;
1022 return picA->info.frame_idx - picB->info.frame_idx;
1025 /* 8.2.4.1 - Decoding process for picture numbers */
1027 init_picture_refs_pic_num(
1028 GstVaapiDecoderH264 *decoder,
1029 GstVaapiPictureH264 *picture,
1030 GstH264SliceHdr *slice_hdr
1033 GstVaapiDecoderH264Private * const priv = decoder->priv;
1034 GstH264PPS * const pps = slice_hdr->pps;
1035 GstH264SPS * const sps = pps->sequence;
1036 const gint32 MaxFrameNum = 1 << (sps->log2_max_frame_num_minus4 + 4);
1037 const guint field_flags = VA_PICTURE_H264_TOP_FIELD | VA_PICTURE_H264_BOTTOM_FIELD;
1040 GST_DEBUG("decode picture numbers");
1042 for (i = 0; i < priv->short_ref_count; i++) {
1043 GstVaapiPictureH264 * const pic = priv->short_ref[i];
1046 if (pic->frame_num > priv->frame_num)
1047 pic->frame_num_wrap = pic->frame_num - MaxFrameNum;
1049 pic->frame_num_wrap = pic->frame_num;
1051 // (8-28, 8-30, 8-31)
1052 if (!pic->field_pic_flag)
1053 pic->pic_num = pic->frame_num_wrap;
1055 if (((picture->info.flags ^ pic->info.flags) & field_flags) == 0)
1056 pic->pic_num = 2 * pic->frame_num_wrap + 1;
1058 pic->pic_num = 2 * pic->frame_num_wrap;
1062 for (i = 0; i < priv->long_ref_count; i++) {
1063 GstVaapiPictureH264 * const pic = priv->long_ref[i];
1065 // (8-29, 8-32, 8-33)
1066 if (!pic->field_pic_flag)
1067 pic->long_term_pic_num = pic->info.frame_idx;
1069 if (((picture->info.flags ^ pic->info.flags) & field_flags) == 0)
1070 pic->long_term_pic_num = 2 * pic->info.frame_idx + 1;
1072 pic->long_term_pic_num = 2 * pic->info.frame_idx;
1077 #define SORT_REF_LIST(list, n, compare_func) \
1078 qsort(list, n, sizeof(*(list)), compare_picture_##compare_func)
1081 init_picture_refs_p_slice(
1082 GstVaapiDecoderH264 *decoder,
1083 GstVaapiPictureH264 *picture,
1084 GstH264SliceHdr *slice_hdr
1087 GstVaapiDecoderH264Private * const priv = decoder->priv;
1088 GstVaapiPictureH264 **ref_list;
1091 GST_DEBUG("decode reference picture list for P and SP slices");
1093 if (!picture->field_pic_flag) {
1094 /* 8.2.4.2.1 - P and SP slices in frames */
1095 if (priv->short_ref_count > 0) {
1096 ref_list = priv->RefPicList0;
1097 for (i = 0; i < priv->short_ref_count; i++)
1098 ref_list[i] = priv->short_ref[i];
1099 SORT_REF_LIST(ref_list, i, pic_num_dec);
1100 priv->RefPicList0_count += i;
1103 if (priv->long_ref_count > 0) {
1104 ref_list = &priv->RefPicList0[priv->RefPicList0_count];
1105 for (i = 0; i < priv->long_ref_count; i++)
1106 ref_list[i] = priv->long_ref[i];
1107 SORT_REF_LIST(ref_list, i, long_term_pic_num_inc);
1108 priv->RefPicList0_count += i;
1112 /* 8.2.4.2.2 - P and SP slices in fields */
1113 GstVaapiPictureH264 *short_ref[32];
1114 guint short_ref_count = 0;
1115 GstVaapiPictureH264 *long_ref[32];
1116 guint long_ref_count = 0;
1118 // XXX: handle second field if current field is marked as
1119 // "used for short-term reference"
1120 if (priv->short_ref_count > 0) {
1121 for (i = 0; i < priv->short_ref_count; i++)
1122 short_ref[i] = priv->short_ref[i];
1123 SORT_REF_LIST(short_ref, i, frame_num_wrap_dec);
1124 short_ref_count = i;
1127 // XXX: handle second field if current field is marked as
1128 // "used for long-term reference"
1129 if (priv->long_ref_count > 0) {
1130 for (i = 0; i < priv->long_ref_count; i++)
1131 long_ref[i] = priv->long_ref[i];
1132 SORT_REF_LIST(long_ref, i, long_term_frame_idx_inc);
1136 // XXX: handle 8.2.4.2.5
1141 init_picture_refs_b_slice(
1142 GstVaapiDecoderH264 *decoder,
1143 GstVaapiPictureH264 *picture,
1144 GstH264SliceHdr *slice_hdr
1147 GstVaapiDecoderH264Private * const priv = decoder->priv;
1148 GstVaapiPictureH264 **ref_list;
1151 GST_DEBUG("decode reference picture list for B slices");
1153 if (!picture->field_pic_flag) {
1154 /* 8.2.4.2.3 - B slices in frames */
1157 if (priv->short_ref_count > 0) {
1158 // 1. Short-term references
1159 ref_list = priv->RefPicList0;
1160 for (n = 0, i = 0; i < priv->short_ref_count; i++) {
1161 if (priv->short_ref[i]->poc < picture->poc)
1162 ref_list[n++] = priv->short_ref[i];
1164 SORT_REF_LIST(ref_list, n, poc_dec);
1165 priv->RefPicList0_count += n;
1167 ref_list = &priv->RefPicList0[priv->RefPicList0_count];
1168 for (n = 0, i = 0; i < priv->short_ref_count; i++) {
1169 if (priv->short_ref[i]->poc >= picture->poc)
1170 ref_list[n++] = priv->short_ref[i];
1172 SORT_REF_LIST(ref_list, n, poc_inc);
1173 priv->RefPicList0_count += n;
1176 if (priv->long_ref_count > 0) {
1177 // 2. Long-term references
1178 ref_list = &priv->RefPicList0[priv->RefPicList0_count];
1179 for (n = 0, i = 0; i < priv->long_ref_count; i++)
1180 ref_list[n++] = priv->long_ref[i];
1181 SORT_REF_LIST(ref_list, n, long_term_pic_num_inc);
1182 priv->RefPicList0_count += n;
1186 if (priv->short_ref_count > 0) {
1187 // 1. Short-term references
1188 ref_list = priv->RefPicList1;
1189 for (n = 0, i = 0; i < priv->short_ref_count; i++) {
1190 if (priv->short_ref[i]->poc > picture->poc)
1191 ref_list[n++] = priv->short_ref[i];
1193 SORT_REF_LIST(ref_list, n, poc_inc);
1194 priv->RefPicList1_count += n;
1196 ref_list = &priv->RefPicList1[priv->RefPicList1_count];
1197 for (n = 0, i = 0; i < priv->short_ref_count; i++) {
1198 if (priv->short_ref[i]->poc <= picture->poc)
1199 ref_list[n++] = priv->short_ref[i];
1201 SORT_REF_LIST(ref_list, n, poc_dec);
1202 priv->RefPicList1_count += n;
1205 if (priv->long_ref_count > 0) {
1206 // 2. Long-term references
1207 ref_list = &priv->RefPicList1[priv->RefPicList1_count];
1208 for (n = 0, i = 0; i < priv->long_ref_count; i++)
1209 ref_list[n++] = priv->long_ref[i];
1210 SORT_REF_LIST(ref_list, n, long_term_pic_num_inc);
1211 priv->RefPicList1_count += n;
1215 /* 8.2.4.2.4 - B slices in fields */
1216 GstVaapiPictureH264 *short_ref0[32];
1217 guint short_ref0_count = 0;
1218 GstVaapiPictureH264 *short_ref1[32];
1219 guint short_ref1_count = 0;
1220 GstVaapiPictureH264 *long_ref[32];
1221 guint long_ref_count = 0;
1223 /* refFrameList0ShortTerm */
1224 if (priv->short_ref_count > 0) {
1225 ref_list = short_ref0;
1226 for (n = 0, i = 0; i < priv->short_ref_count; i++) {
1227 if (priv->short_ref[i]->poc <= picture->poc)
1228 ref_list[n++] = priv->short_ref[i];
1230 SORT_REF_LIST(ref_list, n, poc_dec);
1231 short_ref0_count += n;
1233 ref_list = &short_ref0[short_ref0_count];
1234 for (n = 0, i = 0; i < priv->short_ref_count; i++) {
1235 if (priv->short_ref[i]->poc > picture->poc)
1236 ref_list[n++] = priv->short_ref[i];
1238 SORT_REF_LIST(ref_list, n, poc_inc);
1239 short_ref0_count += n;
1242 /* refFrameList1ShortTerm */
1243 if (priv->short_ref_count > 0) {
1244 ref_list = short_ref1;
1245 for (n = 0, i = 0; i < priv->short_ref_count; i++) {
1246 if (priv->short_ref[i]->poc > picture->poc)
1247 ref_list[n++] = priv->short_ref[i];
1249 SORT_REF_LIST(ref_list, n, poc_inc);
1250 short_ref1_count += n;
1252 ref_list = &short_ref1[short_ref1_count];
1253 for (n = 0, i = 0; i < priv->short_ref_count; i++) {
1254 if (priv->short_ref[i]->poc <= picture->poc)
1255 ref_list[n++] = priv->short_ref[i];
1257 SORT_REF_LIST(ref_list, n, poc_dec);
1258 short_ref1_count += n;
1261 /* refFrameListLongTerm */
1262 if (priv->long_ref_count > 0) {
1263 for (i = 0; i < priv->long_ref_count; i++)
1264 long_ref[i] = priv->long_ref[i];
1265 SORT_REF_LIST(long_ref, i, long_term_frame_idx_inc);
1269 // XXX: handle 8.2.4.2.5
1272 /* Check whether RefPicList1 is identical to RefPicList0, then
1273 swap if necessary */
1274 if (priv->RefPicList1_count > 1 &&
1275 priv->RefPicList1_count == priv->RefPicList0_count &&
1276 memcmp(priv->RefPicList0, priv->RefPicList1,
1277 priv->RefPicList0_count * sizeof(priv->RefPicList0[0])) == 0) {
1278 GstVaapiPictureH264 * const tmp = priv->RefPicList1[0];
1279 priv->RefPicList1[0] = priv->RefPicList1[1];
1280 priv->RefPicList1[1] = tmp;
1284 #undef SORT_REF_LIST
1288 GstVaapiDecoderH264 *decoder,
1289 GstVaapiPictureH264 **pictures,
1290 guint *picture_count
1293 const guint num_pictures = *picture_count;
1296 for (i = 0; i < num_pictures; i++)
1297 gst_vaapi_picture_replace(&pictures[i], NULL);
1302 remove_reference_at(
1303 GstVaapiDecoderH264 *decoder,
1304 GstVaapiPictureH264 **pictures,
1305 guint *picture_count,
1309 guint num_pictures = *picture_count;
1311 g_return_val_if_fail(index < num_pictures, FALSE);
1313 GST_VAAPI_PICTURE_FLAG_UNSET(pictures[index], GST_VAAPI_PICTURE_FLAG_REFERENCE);
1314 if (index != --num_pictures)
1315 gst_vaapi_picture_replace(&pictures[index], pictures[num_pictures]);
1316 gst_vaapi_picture_replace(&pictures[num_pictures], NULL);
1317 *picture_count = num_pictures;
1322 find_short_term_reference(GstVaapiDecoderH264 *decoder, gint32 pic_num)
1324 GstVaapiDecoderH264Private * const priv = decoder->priv;
1327 for (i = 0; i < priv->short_ref_count; i++) {
1328 if (priv->short_ref[i]->pic_num == pic_num)
1331 GST_ERROR("found no short-term reference picture with PicNum = %d",
1337 find_long_term_reference(GstVaapiDecoderH264 *decoder, gint32 long_term_pic_num)
1339 GstVaapiDecoderH264Private * const priv = decoder->priv;
1342 for (i = 0; i < priv->long_ref_count; i++) {
1343 if (priv->long_ref[i]->long_term_pic_num == long_term_pic_num)
1346 GST_ERROR("found no long-term reference picture with LongTermPicNum = %d",
1352 exec_picture_refs_modification_1(
1353 GstVaapiDecoderH264 *decoder,
1354 GstVaapiPictureH264 *picture,
1355 GstH264SliceHdr *slice_hdr,
1359 GstVaapiDecoderH264Private * const priv = decoder->priv;
1360 GstH264PPS * const pps = slice_hdr->pps;
1361 GstH264SPS * const sps = pps->sequence;
1362 GstH264RefPicListModification *ref_pic_list_modification;
1363 guint num_ref_pic_list_modifications;
1364 GstVaapiPictureH264 **ref_list;
1365 guint *ref_list_count_ptr, ref_list_count, ref_list_idx = 0;
1366 guint i, j, n, num_refs;
1368 gint32 MaxPicNum, CurrPicNum, picNumPred;
1370 GST_DEBUG("modification process of reference picture list %u", list);
1373 ref_pic_list_modification = slice_hdr->ref_pic_list_modification_l0;
1374 num_ref_pic_list_modifications = slice_hdr->n_ref_pic_list_modification_l0;
1375 ref_list = priv->RefPicList0;
1376 ref_list_count_ptr = &priv->RefPicList0_count;
1377 num_refs = slice_hdr->num_ref_idx_l0_active_minus1 + 1;
1380 ref_pic_list_modification = slice_hdr->ref_pic_list_modification_l1;
1381 num_ref_pic_list_modifications = slice_hdr->n_ref_pic_list_modification_l1;
1382 ref_list = priv->RefPicList1;
1383 ref_list_count_ptr = &priv->RefPicList1_count;
1384 num_refs = slice_hdr->num_ref_idx_l1_active_minus1 + 1;
1386 ref_list_count = *ref_list_count_ptr;
1388 if (picture->field_pic_flag) {
1389 MaxPicNum = 1 << (sps->log2_max_frame_num_minus4 + 5); // 2 * MaxFrameNum
1390 CurrPicNum = 2 * slice_hdr->frame_num + 1; // 2 * frame_num + 1
1393 MaxPicNum = 1 << (sps->log2_max_frame_num_minus4 + 4); // MaxFrameNum
1394 CurrPicNum = slice_hdr->frame_num; // frame_num
1397 picNumPred = CurrPicNum;
1399 for (i = 0; i < num_ref_pic_list_modifications; i++) {
1400 GstH264RefPicListModification * const l = &ref_pic_list_modification[i];
1401 if (l->modification_of_pic_nums_idc == 3)
1404 /* 8.2.4.3.1 - Short-term reference pictures */
1405 if (l->modification_of_pic_nums_idc == 0 || l->modification_of_pic_nums_idc == 1) {
1406 gint32 abs_diff_pic_num = l->value.abs_diff_pic_num_minus1 + 1;
1407 gint32 picNum, picNumNoWrap;
1410 if (l->modification_of_pic_nums_idc == 0) {
1411 picNumNoWrap = picNumPred - abs_diff_pic_num;
1412 if (picNumNoWrap < 0)
1413 picNumNoWrap += MaxPicNum;
1418 picNumNoWrap = picNumPred + abs_diff_pic_num;
1419 if (picNumNoWrap >= MaxPicNum)
1420 picNumNoWrap -= MaxPicNum;
1422 picNumPred = picNumNoWrap;
1425 picNum = picNumNoWrap;
1426 if (picNum > CurrPicNum)
1427 picNum -= MaxPicNum;
1430 for (j = num_refs; j > ref_list_idx; j--)
1431 ref_list[j] = ref_list[j - 1];
1432 found_ref_idx = find_short_term_reference(decoder, picNum);
1433 ref_list[ref_list_idx++] =
1434 found_ref_idx >= 0 ? priv->short_ref[found_ref_idx] : NULL;
1436 for (j = ref_list_idx; j <= num_refs; j++) {
1440 PicNumF = ref_list[j]->is_long_term ?
1441 MaxPicNum : ref_list[j]->pic_num;
1442 if (PicNumF != picNum)
1443 ref_list[n++] = ref_list[j];
1447 /* 8.2.4.3.2 - Long-term reference pictures */
1450 for (j = num_refs; j > ref_list_idx; j--)
1451 ref_list[j] = ref_list[j - 1];
1453 find_long_term_reference(decoder, l->value.long_term_pic_num);
1454 ref_list[ref_list_idx++] =
1455 found_ref_idx >= 0 ? priv->long_ref[found_ref_idx] : NULL;
1457 for (j = ref_list_idx; j <= num_refs; j++) {
1458 gint32 LongTermPicNumF;
1461 LongTermPicNumF = ref_list[j]->is_long_term ?
1462 ref_list[j]->long_term_pic_num : INT_MAX;
1463 if (LongTermPicNumF != l->value.long_term_pic_num)
1464 ref_list[n++] = ref_list[j];
1470 for (i = 0; i < num_refs; i++)
1472 GST_ERROR("list %u entry %u is empty", list, i);
1474 *ref_list_count_ptr = num_refs;
1477 /* 8.2.4.3 - Modification process for reference picture lists */
1479 exec_picture_refs_modification(
1480 GstVaapiDecoderH264 *decoder,
1481 GstVaapiPictureH264 *picture,
1482 GstH264SliceHdr *slice_hdr
1485 GST_DEBUG("execute ref_pic_list_modification()");
1488 if (!GST_H264_IS_I_SLICE(slice_hdr) && !GST_H264_IS_SI_SLICE(slice_hdr) &&
1489 slice_hdr->ref_pic_list_modification_flag_l0)
1490 exec_picture_refs_modification_1(decoder, picture, slice_hdr, 0);
1493 if (GST_H264_IS_B_SLICE(slice_hdr) &&
1494 slice_hdr->ref_pic_list_modification_flag_l1)
1495 exec_picture_refs_modification_1(decoder, picture, slice_hdr, 1);
1500 GstVaapiDecoderH264 *decoder,
1501 GstVaapiPictureH264 *picture,
1502 GstH264SliceHdr *slice_hdr
1505 GstVaapiDecoderH264Private * const priv = decoder->priv;
1506 GstVaapiPicture * const base_picture = &picture->base;
1509 init_picture_refs_pic_num(decoder, picture, slice_hdr);
1511 priv->RefPicList0_count = 0;
1512 priv->RefPicList1_count = 0;
1514 switch (base_picture->type) {
1515 case GST_VAAPI_PICTURE_TYPE_P:
1516 case GST_VAAPI_PICTURE_TYPE_SP:
1517 init_picture_refs_p_slice(decoder, picture, slice_hdr);
1519 case GST_VAAPI_PICTURE_TYPE_B:
1520 init_picture_refs_b_slice(decoder, picture, slice_hdr);
1526 exec_picture_refs_modification(decoder, picture, slice_hdr);
1528 switch (base_picture->type) {
1529 case GST_VAAPI_PICTURE_TYPE_B:
1530 num_refs = 1 + slice_hdr->num_ref_idx_l1_active_minus1;
1531 for (i = priv->RefPicList1_count; i < num_refs; i++)
1532 priv->RefPicList1[i] = NULL;
1533 priv->RefPicList1_count = num_refs;
1536 case GST_VAAPI_PICTURE_TYPE_P:
1537 case GST_VAAPI_PICTURE_TYPE_SP:
1538 num_refs = 1 + slice_hdr->num_ref_idx_l0_active_minus1;
1539 for (i = priv->RefPicList0_count; i < num_refs; i++)
1540 priv->RefPicList0[i] = NULL;
1541 priv->RefPicList0_count = num_refs;
1551 GstVaapiDecoderH264 *decoder,
1552 GstVaapiPictureH264 *picture,
1553 GstH264SliceHdr *slice_hdr,
1554 GstH264NalUnit *nalu
1557 GstVaapiDecoderH264Private * const priv = decoder->priv;
1558 GstVaapiPicture * const base_picture = &picture->base;
1562 priv->frame_num = slice_hdr->frame_num;
1563 picture->frame_num = priv->frame_num;
1564 picture->frame_num_wrap = priv->frame_num;
1565 picture->is_idr = nalu->type == GST_H264_NAL_SLICE_IDR;
1566 picture->field_pic_flag = slice_hdr->field_pic_flag;
1567 picture->bottom_field_flag = slice_hdr->bottom_field_flag;
1568 picture->output_flag = TRUE; /* XXX: conformant to Annex A only */
1569 base_picture->pts = gst_adapter_prev_timestamp(priv->adapter, NULL);
1571 /* Reset decoder state for IDR pictures */
1572 if (picture->is_idr) {
1574 clear_references(decoder, priv->short_ref, &priv->short_ref_count);
1575 clear_references(decoder, priv->long_ref, &priv->long_ref_count );
1576 priv->prev_poc_msb = 0;
1577 priv->prev_poc_lsb = 0;
1580 /* Initialize VA picture info */
1581 pic = &picture->info;
1582 pic->picture_id = picture->base.surface_id;
1583 pic->frame_idx = priv->frame_num;
1584 if (picture->field_pic_flag) {
1585 if (picture->bottom_field_flag)
1586 pic->flags |= VA_PICTURE_H264_BOTTOM_FIELD;
1588 pic->flags |= VA_PICTURE_H264_TOP_FIELD;
1591 /* Initialize base picture */
1592 switch (slice_hdr->type % 5) {
1593 case GST_H264_P_SLICE:
1594 base_picture->type = GST_VAAPI_PICTURE_TYPE_P;
1596 case GST_H264_B_SLICE:
1597 base_picture->type = GST_VAAPI_PICTURE_TYPE_B;
1599 case GST_H264_I_SLICE:
1600 base_picture->type = GST_VAAPI_PICTURE_TYPE_I;
1602 case GST_H264_SP_SLICE:
1603 base_picture->type = GST_VAAPI_PICTURE_TYPE_SP;
1605 case GST_H264_SI_SLICE:
1606 base_picture->type = GST_VAAPI_PICTURE_TYPE_SI;
1610 if (nalu->ref_idc) {
1611 GstH264DecRefPicMarking * const dec_ref_pic_marking =
1612 &slice_hdr->dec_ref_pic_marking;
1613 GST_VAAPI_PICTURE_FLAG_SET(picture, GST_VAAPI_PICTURE_FLAG_REFERENCE);
1614 if (picture->is_idr) {
1615 if (dec_ref_pic_marking->long_term_reference_flag)
1616 picture->is_long_term = TRUE;
1618 else if (dec_ref_pic_marking->adaptive_ref_pic_marking_mode_flag) {
1619 for (i = 0; i < dec_ref_pic_marking->n_ref_pic_marking; i++) {
1620 GstH264RefPicMarking * const ref_pic_marking =
1621 &dec_ref_pic_marking->ref_pic_marking[i];
1622 switch (ref_pic_marking->memory_management_control_operation) {
1625 picture->is_long_term = TRUE;
1626 pic->frame_idx = ref_pic_marking->long_term_frame_idx;
1629 picture->has_mmco_5 = TRUE;
1634 if (picture->is_long_term)
1635 pic->flags |= VA_PICTURE_H264_LONG_TERM_REFERENCE;
1637 pic->flags |= VA_PICTURE_H264_SHORT_TERM_REFERENCE;
1640 init_picture_poc(decoder, picture, slice_hdr);
1641 if (!init_picture_refs(decoder, picture, slice_hdr)) {
1642 GST_DEBUG("failed to initialize references");
1648 /* 8.2.5.3 - Sliding window decoded reference picture marking process */
1650 exec_ref_pic_marking_sliding_window(GstVaapiDecoderH264 *decoder)
1652 GstVaapiDecoderH264Private * const priv = decoder->priv;
1653 GstH264SPS * const sps = priv->sps;
1654 guint i, max_num_ref_frames, lowest_frame_num_index;
1655 gint32 lowest_frame_num;
1657 GST_DEBUG("reference picture marking process (sliding window)");
1659 max_num_ref_frames = sps->num_ref_frames;
1660 if (max_num_ref_frames == 0)
1661 max_num_ref_frames = 1;
1663 if (priv->short_ref_count + priv->long_ref_count < max_num_ref_frames)
1665 if (priv->short_ref_count < 1)
1668 lowest_frame_num = priv->short_ref[0]->frame_num_wrap;
1669 lowest_frame_num_index = 0;
1670 for (i = 1; i < priv->short_ref_count; i++) {
1671 if (priv->short_ref[i]->frame_num_wrap < lowest_frame_num) {
1672 lowest_frame_num = priv->short_ref[i]->frame_num_wrap;
1673 lowest_frame_num_index = i;
1677 remove_reference_at(
1679 priv->short_ref, &priv->short_ref_count,
1680 lowest_frame_num_index
1685 /* 8.2.5.4. Adaptive memory control decoded reference picture marking process */
1687 exec_ref_pic_marking_adaptive(
1688 GstVaapiDecoderH264 *decoder,
1689 GstVaapiPictureH264 *picture,
1690 GstH264DecRefPicMarking *dec_ref_pic_marking
1693 GstVaapiDecoderH264Private * const priv = decoder->priv;
1694 gint32 pic_num, ref_idx;
1697 GST_DEBUG("reference picture marking process (adaptive memory control)");
1699 for (i = 0; i < dec_ref_pic_marking->n_ref_pic_marking; i++) {
1700 GstH264RefPicMarking * const ref_pic_marking =
1701 &dec_ref_pic_marking->ref_pic_marking[i];
1703 switch (ref_pic_marking->memory_management_control_operation) {
1705 // Mark short-term reference picture as "unused for reference"
1706 if (!picture->field_pic_flag)
1707 pic_num = picture->frame_num_wrap;
1709 pic_num = 2 * picture->frame_num_wrap + 1;
1710 pic_num -= ref_pic_marking->difference_of_pic_nums_minus1 + 1;
1711 ref_idx = find_short_term_reference(decoder, pic_num);
1714 remove_reference_at(
1716 priv->short_ref, &priv->short_ref_count,
1721 // Mark long-term reference picture as "unused for reference"
1722 pic_num = picture->long_term_pic_num;
1723 ref_idx = find_long_term_reference(decoder, pic_num);
1726 remove_reference_at(
1728 priv->long_ref, &priv->long_ref_count,
1733 // Assign LongTermFrameIdx to a short-term reference picture
1734 if (!picture->field_pic_flag)
1735 pic_num = picture->frame_num_wrap;
1737 pic_num = 2 * picture->frame_num_wrap + 1;
1738 pic_num -= ref_pic_marking->difference_of_pic_nums_minus1 + 1;
1739 ref_idx = find_short_term_reference(decoder, pic_num);
1744 // Mark all reference pictures as "unused for reference"
1745 clear_references(decoder, priv->short_ref, &priv->short_ref_count);
1746 clear_references(decoder, priv->long_ref, &priv->long_ref_count );
1749 g_assert(0 && "unhandled MMCO");
1756 /* 8.2.5 - Execute reference picture marking process */
1758 exec_ref_pic_marking(GstVaapiDecoderH264 *decoder, GstVaapiPictureH264 *picture)
1760 GstVaapiDecoderH264Private * const priv = decoder->priv;
1761 GstVaapiPictureH264 **picture_ptr;
1763 if (!GST_VAAPI_PICTURE_IS_REFERENCE(picture))
1766 if (!picture->is_idr) {
1767 GstH264DecRefPicMarking * const dec_ref_pic_marking =
1768 get_dec_ref_pic_marking(picture);
1769 if (dec_ref_pic_marking->adaptive_ref_pic_marking_mode_flag) {
1770 if (!exec_ref_pic_marking_adaptive(decoder, picture, dec_ref_pic_marking))
1774 if (!exec_ref_pic_marking_sliding_window(decoder))
1779 if (picture->is_long_term)
1780 picture_ptr = &priv->long_ref[priv->long_ref_count++];
1782 picture_ptr = &priv->short_ref[priv->short_ref_count++];
1783 gst_vaapi_picture_replace(picture_ptr, picture);
1787 /* Update picture order count */
1789 exit_picture_poc(GstVaapiDecoderH264 *decoder, GstVaapiPictureH264 *picture)
1791 GstVaapiDecoderH264Private * const priv = decoder->priv;
1792 GstH264SPS * const sps = priv->sps;
1794 switch (sps->pic_order_cnt_type) {
1796 if (!GST_VAAPI_PICTURE_IS_REFERENCE(picture))
1798 if (picture->has_mmco_5) {
1799 priv->prev_poc_msb = 0;
1800 if (!picture->field_pic_flag || !picture->bottom_field_flag)
1801 priv->prev_poc_lsb = picture->info.TopFieldOrderCnt;
1803 priv->prev_poc_lsb = 0;
1806 priv->prev_poc_msb = priv->poc_msb;
1807 priv->prev_poc_lsb = priv->poc_lsb;
1812 priv->prev_frame_num = priv->frame_num;
1813 if (picture->has_mmco_5)
1814 priv->prev_frame_num_offset = 0;
1816 priv->prev_frame_num_offset = priv->frame_num_offset;
1821 static inline gboolean
1822 exit_picture(GstVaapiDecoderH264 *decoder, GstVaapiPictureH264 *picture)
1824 /* Update picture order count */
1825 exit_picture_poc(decoder, picture);
1827 /* Decoded reference picture marking process */
1828 if (!exec_ref_pic_marking(decoder, picture))
1834 vaapi_init_picture(VAPictureH264 *pic)
1836 pic->picture_id = VA_INVALID_ID;
1838 pic->flags = VA_PICTURE_H264_INVALID;
1839 pic->TopFieldOrderCnt = 0;
1840 pic->BottomFieldOrderCnt = 0;
1845 GstVaapiDecoderH264 *decoder,
1846 GstVaapiPictureH264 *picture,
1847 GstH264SliceHdr *slice_hdr,
1848 GstH264NalUnit *nalu
1851 GstVaapiDecoderH264Private * const priv = decoder->priv;
1852 GstVaapiPicture * const base_picture = &picture->base;
1853 GstH264SPS * const sps = priv->sps;
1854 GstH264PPS * const pps = priv->pps;
1855 VAPictureParameterBufferH264 * const pic_param = base_picture->param;
1858 /* Fill in VAPictureParameterBufferH264 */
1859 pic_param->CurrPic = picture->info;
1860 for (i = 0, n = 0; i < priv->short_ref_count; i++)
1861 pic_param->ReferenceFrames[n++] = priv->short_ref[i]->info;
1862 for (i = 0; i < priv->long_ref_count; i++)
1863 pic_param->ReferenceFrames[n++] = priv->long_ref[i]->info;
1864 for (; n < G_N_ELEMENTS(pic_param->ReferenceFrames); n++)
1865 vaapi_init_picture(&pic_param->ReferenceFrames[n]);
1867 #define COPY_FIELD(s, f) \
1868 pic_param->f = (s)->f
1870 #define COPY_BFM(a, s, f) \
1871 pic_param->a.bits.f = (s)->f
1873 pic_param->picture_width_in_mbs_minus1 = priv->mb_width - 1;
1874 pic_param->picture_height_in_mbs_minus1 = priv->mb_height - 1;
1875 pic_param->frame_num = priv->frame_num;
1877 COPY_FIELD(sps, bit_depth_luma_minus8);
1878 COPY_FIELD(sps, bit_depth_chroma_minus8);
1879 COPY_FIELD(sps, num_ref_frames);
1880 COPY_FIELD(pps, num_slice_groups_minus1);
1881 COPY_FIELD(pps, slice_group_map_type);
1882 COPY_FIELD(pps, slice_group_change_rate_minus1);
1883 COPY_FIELD(pps, pic_init_qp_minus26);
1884 COPY_FIELD(pps, pic_init_qs_minus26);
1885 COPY_FIELD(pps, chroma_qp_index_offset);
1886 COPY_FIELD(pps, second_chroma_qp_index_offset);
1888 pic_param->seq_fields.value = 0; /* reset all bits */
1889 pic_param->seq_fields.bits.residual_colour_transform_flag = sps->separate_colour_plane_flag;
1890 pic_param->seq_fields.bits.MinLumaBiPredSize8x8 = sps->level_idc >= 31; /* A.3.3.2 */
1892 COPY_BFM(seq_fields, sps, chroma_format_idc);
1893 COPY_BFM(seq_fields, sps, gaps_in_frame_num_value_allowed_flag);
1894 COPY_BFM(seq_fields, sps, frame_mbs_only_flag);
1895 COPY_BFM(seq_fields, sps, mb_adaptive_frame_field_flag);
1896 COPY_BFM(seq_fields, sps, direct_8x8_inference_flag);
1897 COPY_BFM(seq_fields, sps, log2_max_frame_num_minus4);
1898 COPY_BFM(seq_fields, sps, pic_order_cnt_type);
1899 COPY_BFM(seq_fields, sps, log2_max_pic_order_cnt_lsb_minus4);
1900 COPY_BFM(seq_fields, sps, delta_pic_order_always_zero_flag);
1902 pic_param->pic_fields.value = 0; /* reset all bits */
1903 pic_param->pic_fields.bits.field_pic_flag = slice_hdr->field_pic_flag;
1904 pic_param->pic_fields.bits.reference_pic_flag = GST_VAAPI_PICTURE_IS_REFERENCE(picture);
1906 COPY_BFM(pic_fields, pps, entropy_coding_mode_flag);
1907 COPY_BFM(pic_fields, pps, weighted_pred_flag);
1908 COPY_BFM(pic_fields, pps, weighted_bipred_idc);
1909 COPY_BFM(pic_fields, pps, transform_8x8_mode_flag);
1910 COPY_BFM(pic_fields, pps, constrained_intra_pred_flag);
1911 COPY_BFM(pic_fields, pps, pic_order_present_flag);
1912 COPY_BFM(pic_fields, pps, deblocking_filter_control_present_flag);
1913 COPY_BFM(pic_fields, pps, redundant_pic_cnt_present_flag);
1918 fill_quant_matrix(GstVaapiDecoderH264 *decoder, GstVaapiPictureH264 *picture)
1920 GstVaapiDecoderH264Private * const priv = decoder->priv;
1921 VAIQMatrixBufferH264 * const iq_matrix = picture->base.iq_matrix->param;
1923 /* XXX: we can only support 4:2:0 or 4:2:2 since ScalingLists8x8[]
1924 is not large enough to hold lists for 4:4:4 */
1925 if (priv->sps->chroma_format_idc == 3 &&
1926 sizeof(iq_matrix->ScalingList8x8) != sizeof(priv->scaling_list_8x8))
1929 /* Fill in VAIQMatrixBufferH264 */
1930 memcpy(iq_matrix->ScalingList4x4, priv->scaling_list_4x4,
1931 sizeof(iq_matrix->ScalingList4x4));
1932 memcpy(iq_matrix->ScalingList8x8, priv->scaling_list_8x8,
1933 sizeof(iq_matrix->ScalingList8x8));
1937 static GstVaapiDecoderStatus
1938 decode_picture(GstVaapiDecoderH264 *decoder, GstH264NalUnit *nalu, GstH264SliceHdr *slice_hdr)
1940 GstVaapiDecoderH264Private * const priv = decoder->priv;
1941 GstVaapiPictureH264 *picture;
1942 GstVaapiDecoderStatus status;
1943 GstH264PPS * const pps = slice_hdr->pps;
1944 GstH264SPS * const sps = pps->sequence;
1946 status = ensure_context(decoder, sps);
1947 if (status != GST_VAAPI_DECODER_STATUS_SUCCESS) {
1948 GST_DEBUG("failed to reset context");
1952 if (priv->current_picture && !decode_current_picture(decoder))
1953 return GST_VAAPI_DECODER_STATUS_ERROR_UNKNOWN;
1955 picture = gst_vaapi_picture_h264_new(decoder);
1957 GST_DEBUG("failed to allocate picture");
1958 return GST_VAAPI_DECODER_STATUS_ERROR_ALLOCATION_FAILED;
1960 priv->current_picture = picture;
1962 picture->base.iq_matrix = GST_VAAPI_IQ_MATRIX_NEW(H264, decoder);
1963 if (!picture->base.iq_matrix) {
1964 GST_DEBUG("failed to allocate IQ matrix");
1965 return GST_VAAPI_DECODER_STATUS_ERROR_ALLOCATION_FAILED;
1968 status = ensure_quant_matrix(decoder, pps);
1969 if (status != GST_VAAPI_DECODER_STATUS_SUCCESS) {
1970 GST_DEBUG("failed to reset quantizer matrix");
1977 if (!init_picture(decoder, picture, slice_hdr, nalu))
1978 return GST_VAAPI_DECODER_STATUS_ERROR_UNKNOWN;
1979 if (!fill_picture(decoder, picture, slice_hdr, nalu))
1980 return GST_VAAPI_DECODER_STATUS_ERROR_UNKNOWN;
1981 return GST_VAAPI_DECODER_STATUS_SUCCESS;
1985 decode_picture_end(GstVaapiDecoderH264 *decoder, GstVaapiPictureH264 *picture)
1987 if (!fill_quant_matrix(decoder, picture))
1989 if (!exit_picture(decoder, picture))
1991 if (!dpb_add(decoder, picture))
1996 #ifndef HAVE_GST_H264_SLICE_HDR_EPB_COUNT
1998 get_epb_count(const guint8 *buf, guint buf_size, guint header_size)
2002 if (buf_size > header_size)
2003 buf_size = header_size;
2005 for (i = 2; i < buf_size; i++) {
2006 if (!buf[i - 2] && !buf[i - 1] && buf[i] == 0x03)
2014 get_slice_data_bit_offset(GstH264SliceHdr *slice_hdr, GstH264NalUnit *nalu)
2018 #ifdef HAVE_GST_H264_SLICE_HDR_EPB_COUNT
2019 epb_count = slice_hdr->n_emulation_prevention_bytes;
2021 epb_count = get_epb_count(
2022 nalu->data + nalu->offset,
2024 slice_hdr->header_size / 8
2027 return 8 /* nal_unit_type */ + slice_hdr->header_size - epb_count * 8;
2031 fill_pred_weight_table(GstVaapiDecoderH264 *decoder, GstVaapiSliceH264 *slice)
2033 GstH264SliceHdr * const slice_hdr = &slice->slice_hdr;
2034 GstH264PPS * const pps = slice_hdr->pps;
2035 GstH264SPS * const sps = pps->sequence;
2036 GstH264PredWeightTable * const w = &slice_hdr->pred_weight_table;
2037 VASliceParameterBufferH264 * const slice_param = slice->base.param;
2038 guint num_weight_tables = 0;
2041 if (pps->weighted_pred_flag &&
2042 (GST_H264_IS_P_SLICE(slice_hdr) || GST_H264_IS_SP_SLICE(slice_hdr)))
2043 num_weight_tables = 1;
2044 else if (pps->weighted_bipred_idc == 1 && GST_H264_IS_B_SLICE(slice_hdr))
2045 num_weight_tables = 2;
2047 num_weight_tables = 0;
2049 slice_param->luma_log2_weight_denom = w->luma_log2_weight_denom;
2050 slice_param->chroma_log2_weight_denom = w->chroma_log2_weight_denom;
2051 slice_param->luma_weight_l0_flag = 0;
2052 slice_param->chroma_weight_l0_flag = 0;
2053 slice_param->luma_weight_l1_flag = 0;
2054 slice_param->chroma_weight_l1_flag = 0;
2056 if (num_weight_tables < 1)
2059 slice_param->luma_weight_l0_flag = 1;
2060 for (i = 0; i <= slice_param->num_ref_idx_l0_active_minus1; i++) {
2061 slice_param->luma_weight_l0[i] = w->luma_weight_l0[i];
2062 slice_param->luma_offset_l0[i] = w->luma_offset_l0[i];
2065 slice_param->chroma_weight_l0_flag = sps->chroma_array_type != 0;
2066 if (slice_param->chroma_weight_l0_flag) {
2067 for (i = 0; i <= slice_param->num_ref_idx_l0_active_minus1; i++) {
2068 for (j = 0; j < 2; j++) {
2069 slice_param->chroma_weight_l0[i][j] = w->chroma_weight_l0[i][j];
2070 slice_param->chroma_offset_l0[i][j] = w->chroma_offset_l0[i][j];
2075 if (num_weight_tables < 2)
2078 slice_param->luma_weight_l1_flag = 1;
2079 for (i = 0; i <= slice_param->num_ref_idx_l1_active_minus1; i++) {
2080 slice_param->luma_weight_l1[i] = w->luma_weight_l1[i];
2081 slice_param->luma_offset_l1[i] = w->luma_offset_l1[i];
2084 slice_param->chroma_weight_l1_flag = sps->chroma_array_type != 0;
2085 if (slice_param->chroma_weight_l1_flag) {
2086 for (i = 0; i <= slice_param->num_ref_idx_l1_active_minus1; i++) {
2087 for (j = 0; j < 2; j++) {
2088 slice_param->chroma_weight_l1[i][j] = w->chroma_weight_l1[i][j];
2089 slice_param->chroma_offset_l1[i][j] = w->chroma_offset_l1[i][j];
2097 fill_RefPicList(GstVaapiDecoderH264 *decoder, GstVaapiSliceH264 *slice)
2099 GstVaapiDecoderH264Private * const priv = decoder->priv;
2100 GstH264SliceHdr * const slice_hdr = &slice->slice_hdr;
2101 VASliceParameterBufferH264 * const slice_param = slice->base.param;
2102 guint i, num_ref_lists = 0;
2104 slice_param->num_ref_idx_l0_active_minus1 = 0;
2105 slice_param->num_ref_idx_l1_active_minus1 = 0;
2107 if (GST_H264_IS_B_SLICE(slice_hdr))
2109 else if (GST_H264_IS_I_SLICE(slice_hdr))
2114 if (num_ref_lists < 1)
2117 slice_param->num_ref_idx_l0_active_minus1 =
2118 slice_hdr->num_ref_idx_l0_active_minus1;
2120 for (i = 0; i < priv->RefPicList0_count && priv->RefPicList0[i]; i++)
2121 slice_param->RefPicList0[i] = priv->RefPicList0[i]->info;
2122 for (; i <= slice_param->num_ref_idx_l0_active_minus1; i++)
2123 vaapi_init_picture(&slice_param->RefPicList0[i]);
2125 if (num_ref_lists < 2)
2128 slice_param->num_ref_idx_l1_active_minus1 =
2129 slice_hdr->num_ref_idx_l1_active_minus1;
2131 for (i = 0; i < priv->RefPicList1_count && priv->RefPicList1[i]; i++)
2132 slice_param->RefPicList1[i] = priv->RefPicList1[i]->info;
2133 for (; i <= slice_param->num_ref_idx_l1_active_minus1; i++)
2134 vaapi_init_picture(&slice_param->RefPicList1[i]);
2140 GstVaapiDecoderH264 *decoder,
2141 GstVaapiSliceH264 *slice,
2142 GstH264NalUnit *nalu
2145 GstH264SliceHdr * const slice_hdr = &slice->slice_hdr;
2146 VASliceParameterBufferH264 * const slice_param = slice->base.param;
2148 /* Fill in VASliceParameterBufferH264 */
2149 slice_param->slice_data_bit_offset = get_slice_data_bit_offset(slice_hdr, nalu);
2150 slice_param->first_mb_in_slice = slice_hdr->first_mb_in_slice;
2151 slice_param->slice_type = slice_hdr->type % 5;
2152 slice_param->direct_spatial_mv_pred_flag = slice_hdr->direct_spatial_mv_pred_flag;
2153 slice_param->cabac_init_idc = slice_hdr->cabac_init_idc;
2154 slice_param->slice_qp_delta = slice_hdr->slice_qp_delta;
2155 slice_param->disable_deblocking_filter_idc = slice_hdr->disable_deblocking_filter_idc;
2156 slice_param->slice_alpha_c0_offset_div2 = slice_hdr->slice_alpha_c0_offset_div2;
2157 slice_param->slice_beta_offset_div2 = slice_hdr->slice_beta_offset_div2;
2159 if (!fill_RefPicList(decoder, slice))
2161 if (!fill_pred_weight_table(decoder, slice))
2166 static GstVaapiDecoderStatus
2167 decode_slice(GstVaapiDecoderH264 *decoder, GstH264NalUnit *nalu)
2169 GstVaapiDecoderH264Private * const priv = decoder->priv;
2170 GstVaapiDecoderStatus status;
2171 GstVaapiPictureH264 *picture;
2172 GstVaapiSliceH264 *slice = NULL;
2173 GstH264SliceHdr *slice_hdr;
2174 GstH264ParserResult result;
2176 GST_DEBUG("slice (%u bytes)", nalu->size);
2178 slice = gst_vaapi_slice_h264_new(
2180 nalu->data + nalu->offset,
2184 GST_DEBUG("failed to allocate slice");
2185 return GST_VAAPI_DECODER_STATUS_ERROR_ALLOCATION_FAILED;
2188 slice_hdr = &slice->slice_hdr;
2189 memset(slice_hdr, 0, sizeof(*slice_hdr));
2190 result = gst_h264_parser_parse_slice_hdr(priv->parser, nalu, slice_hdr, TRUE, TRUE);
2191 if (result != GST_H264_PARSER_OK) {
2192 status = get_status(result);
2196 if (slice_hdr->first_mb_in_slice == 0) {
2197 status = decode_picture(decoder, nalu, slice_hdr);
2198 if (status != GST_VAAPI_DECODER_STATUS_SUCCESS)
2201 picture = priv->current_picture;
2203 priv->mb_x = slice_hdr->first_mb_in_slice % priv->mb_width;
2204 priv->mb_y = slice_hdr->first_mb_in_slice / priv->mb_width; // FIXME: MBAFF or field
2206 if (!fill_slice(decoder, slice, nalu)) {
2207 status = GST_VAAPI_DECODER_STATUS_ERROR_UNKNOWN;
2210 gst_vaapi_picture_add_slice(
2211 GST_VAAPI_PICTURE_CAST(picture),
2212 GST_VAAPI_SLICE_CAST(slice)
2215 /* Commit picture for decoding if we reached the last slice */
2216 if (++priv->mb_y >= priv->mb_height) {
2217 if (!decode_current_picture(decoder)) {
2218 status = GST_VAAPI_DECODER_STATUS_ERROR_UNKNOWN;
2223 return GST_VAAPI_DECODER_STATUS_SUCCESS;
2227 gst_mini_object_unref(GST_MINI_OBJECT(slice));
2231 static GstVaapiDecoderStatus
2232 decode_buffer(GstVaapiDecoderH264 *decoder, GstBuffer *buffer)
2234 GstVaapiDecoderH264Private * const priv = decoder->priv;
2235 GstVaapiDecoderStatus status;
2236 GstH264ParserResult result;
2237 GstH264NalUnit nalu;
2239 guint buf_size, ofs;
2241 buf = GST_BUFFER_DATA(buffer);
2242 buf_size = GST_BUFFER_SIZE(buffer);
2243 if (!buf && buf_size == 0)
2244 return decode_sequence_end(decoder);
2246 gst_buffer_ref(buffer);
2247 gst_adapter_push(priv->adapter, buffer);
2249 if (priv->sub_buffer) {
2250 buffer = gst_buffer_merge(priv->sub_buffer, buffer);
2252 return GST_VAAPI_DECODER_STATUS_ERROR_ALLOCATION_FAILED;
2253 gst_buffer_unref(priv->sub_buffer);
2254 priv->sub_buffer = NULL;
2257 buf = GST_BUFFER_DATA(buffer);
2258 buf_size = GST_BUFFER_SIZE(buffer);
2262 result = gst_h264_parser_identify_nalu_avc(
2264 buf, ofs, buf_size, priv->nal_length_size,
2269 result = gst_h264_parser_identify_nalu(
2275 status = get_status(result);
2277 if (status == GST_VAAPI_DECODER_STATUS_ERROR_NO_DATA) {
2278 priv->sub_buffer = gst_buffer_create_sub(buffer, ofs, buf_size - ofs);
2281 if (status != GST_VAAPI_DECODER_STATUS_SUCCESS)
2284 ofs = nalu.offset - ofs;
2285 if (gst_adapter_available(priv->adapter) >= ofs)
2286 gst_adapter_flush(priv->adapter, ofs);
2288 switch (nalu.type) {
2289 case GST_H264_NAL_SLICE_IDR:
2290 /* fall-through. IDR specifics are handled in init_picture() */
2291 case GST_H264_NAL_SLICE:
2292 status = decode_slice(decoder, &nalu);
2294 case GST_H264_NAL_SPS:
2295 status = decode_sps(decoder, &nalu);
2297 case GST_H264_NAL_PPS:
2298 status = decode_pps(decoder, &nalu);
2300 case GST_H264_NAL_SEI:
2301 status = decode_sei(decoder, &nalu);
2303 case GST_H264_NAL_SEQ_END:
2304 status = decode_sequence_end(decoder);
2306 case GST_H264_NAL_AU_DELIMITER:
2307 /* skip all Access Unit NALs */
2308 status = GST_VAAPI_DECODER_STATUS_SUCCESS;
2310 case GST_H264_NAL_FILLER_DATA:
2311 /* skip all Filler Data NALs */
2312 status = GST_VAAPI_DECODER_STATUS_SUCCESS;
2315 GST_DEBUG("unsupported NAL unit type %d", nalu.type);
2316 status = GST_VAAPI_DECODER_STATUS_ERROR_BITSTREAM_PARSER;
2320 if (gst_adapter_available(priv->adapter) >= nalu.size)
2321 gst_adapter_flush(priv->adapter, nalu.size);
2322 ofs = nalu.offset + nalu.size;
2323 } while (status == GST_VAAPI_DECODER_STATUS_SUCCESS && ofs < buf_size);
2327 static GstVaapiDecoderStatus
2328 decode_codec_data(GstVaapiDecoderH264 *decoder, GstBuffer *buffer)
2330 GstVaapiDecoderH264Private * const priv = decoder->priv;
2331 GstVaapiDecoderStatus status;
2332 GstH264NalUnit nalu;
2333 GstH264ParserResult result;
2336 guint i, ofs, num_sps, num_pps;
2338 buf = GST_BUFFER_DATA(buffer);
2339 buf_size = GST_BUFFER_SIZE(buffer);
2340 if (!buf || buf_size == 0)
2341 return GST_VAAPI_DECODER_STATUS_SUCCESS;
2344 return GST_VAAPI_DECODER_STATUS_ERROR_NO_DATA;
2347 GST_DEBUG("failed to decode codec-data, not in avcC format");
2348 return GST_VAAPI_DECODER_STATUS_ERROR_BITSTREAM_PARSER;
2351 priv->nal_length_size = (buf[4] & 0x03) + 1;
2353 num_sps = buf[5] & 0x1f;
2356 for (i = 0; i < num_sps; i++) {
2357 result = gst_h264_parser_identify_nalu_avc(
2359 buf, ofs, buf_size, 2,
2362 if (result != GST_H264_PARSER_OK)
2363 return get_status(result);
2365 status = decode_sps(decoder, &nalu);
2366 if (status != GST_VAAPI_DECODER_STATUS_SUCCESS)
2368 ofs = nalu.offset + nalu.size;
2374 for (i = 0; i < num_pps; i++) {
2375 result = gst_h264_parser_identify_nalu_avc(
2377 buf, ofs, buf_size, 2,
2380 if (result != GST_H264_PARSER_OK)
2381 return get_status(result);
2383 status = decode_pps(decoder, &nalu);
2384 if (status != GST_VAAPI_DECODER_STATUS_SUCCESS)
2386 ofs = nalu.offset + nalu.size;
2389 priv->is_avc = TRUE;
2393 GstVaapiDecoderStatus
2394 gst_vaapi_decoder_h264_decode(GstVaapiDecoder *base, GstBuffer *buffer)
2396 GstVaapiDecoderH264 * const decoder = GST_VAAPI_DECODER_H264(base);
2397 GstVaapiDecoderH264Private * const priv = decoder->priv;
2398 GstVaapiDecoderStatus status;
2399 GstBuffer *codec_data;
2401 g_return_val_if_fail(priv->is_constructed,
2402 GST_VAAPI_DECODER_STATUS_ERROR_INIT_FAILED);
2404 if (!priv->is_opened) {
2405 priv->is_opened = gst_vaapi_decoder_h264_open(decoder, buffer);
2406 if (!priv->is_opened)
2407 return GST_VAAPI_DECODER_STATUS_ERROR_UNSUPPORTED_CODEC;
2409 codec_data = GST_VAAPI_DECODER_CODEC_DATA(decoder);
2411 status = decode_codec_data(decoder, codec_data);
2412 if (status != GST_VAAPI_DECODER_STATUS_SUCCESS)
2416 return decode_buffer(decoder, buffer);
2420 gst_vaapi_decoder_h264_finalize(GObject *object)
2422 GstVaapiDecoderH264 * const decoder = GST_VAAPI_DECODER_H264(object);
2424 gst_vaapi_decoder_h264_destroy(decoder);
2426 G_OBJECT_CLASS(gst_vaapi_decoder_h264_parent_class)->finalize(object);
2430 gst_vaapi_decoder_h264_constructed(GObject *object)
2432 GstVaapiDecoderH264 * const decoder = GST_VAAPI_DECODER_H264(object);
2433 GstVaapiDecoderH264Private * const priv = decoder->priv;
2434 GObjectClass *parent_class;
2436 parent_class = G_OBJECT_CLASS(gst_vaapi_decoder_h264_parent_class);
2437 if (parent_class->constructed)
2438 parent_class->constructed(object);
2440 priv->is_constructed = gst_vaapi_decoder_h264_create(decoder);
2444 gst_vaapi_decoder_h264_class_init(GstVaapiDecoderH264Class *klass)
2446 GObjectClass * const object_class = G_OBJECT_CLASS(klass);
2447 GstVaapiDecoderClass * const decoder_class = GST_VAAPI_DECODER_CLASS(klass);
2449 g_type_class_add_private(klass, sizeof(GstVaapiDecoderH264Private));
2451 object_class->finalize = gst_vaapi_decoder_h264_finalize;
2452 object_class->constructed = gst_vaapi_decoder_h264_constructed;
2454 decoder_class->decode = gst_vaapi_decoder_h264_decode;
2455 decoder_class->clear_buffer = gst_vaapi_decoder_h264_clear_buffer;
2459 gst_vaapi_decoder_h264_init(GstVaapiDecoderH264 *decoder)
2461 GstVaapiDecoderH264Private *priv;
2463 priv = GST_VAAPI_DECODER_H264_GET_PRIVATE(decoder);
2464 decoder->priv = priv;
2465 priv->parser = NULL;
2466 priv->sps = &priv->last_sps;
2467 priv->pps = &priv->last_pps;
2468 priv->current_picture = NULL;
2469 priv->dpb_count = 0;
2471 priv->profile = GST_VAAPI_PROFILE_H264_HIGH;
2472 priv->short_ref_count = 0;
2473 priv->long_ref_count = 0;
2474 priv->RefPicList0_count = 0;
2475 priv->RefPicList1_count = 0;
2476 priv->nal_length_size = 0;
2482 priv->mb_height = 0;
2483 priv->adapter = NULL;
2484 priv->sub_buffer = NULL;
2485 priv->field_poc[0] = 0;
2486 priv->field_poc[1] = 0;
2489 priv->prev_poc_msb = 0;
2490 priv->prev_poc_lsb = 0;
2491 priv->frame_num_offset = 0;
2492 priv->prev_frame_num_offset = 0;
2493 priv->frame_num = 0;
2494 priv->prev_frame_num = 0;
2495 priv->is_constructed = FALSE;
2496 priv->is_opened = FALSE;
2497 priv->is_avc = FALSE;
2498 priv->has_context = FALSE;
2500 memset(priv->dpb, 0, sizeof(priv->dpb));
2501 memset(priv->short_ref, 0, sizeof(priv->short_ref));
2502 memset(priv->long_ref, 0, sizeof(priv->long_ref));
2503 memset(priv->RefPicList0, 0, sizeof(priv->RefPicList0));
2504 memset(priv->RefPicList1, 0, sizeof(priv->RefPicList1));
2508 * gst_vaapi_decoder_h264_new:
2509 * @display: a #GstVaapiDisplay
2510 * @caps: a #GstCaps holding codec information
2512 * Creates a new #GstVaapiDecoder for MPEG-2 decoding. The @caps can
2513 * hold extra information like codec-data and pictured coded size.
2515 * Return value: the newly allocated #GstVaapiDecoder object
2518 gst_vaapi_decoder_h264_new(GstVaapiDisplay *display, GstCaps *caps)
2520 GstVaapiDecoderH264 *decoder;
2522 g_return_val_if_fail(GST_VAAPI_IS_DISPLAY(display), NULL);
2523 g_return_val_if_fail(GST_IS_CAPS(caps), NULL);
2525 decoder = g_object_new(
2526 GST_VAAPI_TYPE_DECODER_H264,
2531 if (!decoder->priv->is_constructed) {
2532 g_object_unref(decoder);
2535 return GST_VAAPI_DECODER_CAST(decoder);