2 * gstvaapidecoder_h264.c - H.264 decoder
4 * Copyright (C) 2011-2013 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 _GstVaapiFrameStore GstVaapiFrameStore;
44 typedef struct _GstVaapiFrameStoreClass GstVaapiFrameStoreClass;
45 typedef struct _GstVaapiParserInfoH264 GstVaapiParserInfoH264;
46 typedef struct _GstVaapiPictureH264 GstVaapiPictureH264;
48 // Used for field_poc[]
50 #define BOTTOM_FIELD 1
52 /* ------------------------------------------------------------------------- */
53 /* --- H.264 Parser Info --- */
54 /* ------------------------------------------------------------------------- */
56 #define GST_VAAPI_PARSER_INFO_H264(obj) \
57 ((GstVaapiParserInfoH264 *)(obj))
59 struct _GstVaapiParserInfoH264 {
60 GstVaapiMiniObject parent_instance;
65 GstH264SliceHdr slice_hdr;
69 static inline const GstVaapiMiniObjectClass *
70 gst_vaapi_parser_info_h264_class(void)
72 static const GstVaapiMiniObjectClass GstVaapiParserInfoH264Class = {
73 sizeof(GstVaapiParserInfoH264),
76 return &GstVaapiParserInfoH264Class;
79 static inline GstVaapiParserInfoH264 *
80 gst_vaapi_parser_info_h264_new(void)
82 return (GstVaapiParserInfoH264 *)
83 gst_vaapi_mini_object_new(gst_vaapi_parser_info_h264_class());
86 #define gst_vaapi_parser_info_h264_ref(pi) \
87 gst_vaapi_mini_object_ref(GST_VAAPI_MINI_OBJECT(pi))
89 #define gst_vaapi_parser_info_h264_unref(pi) \
90 gst_vaapi_mini_object_unref(GST_VAAPI_MINI_OBJECT(pi))
92 #define gst_vaapi_parser_info_h264_replace(old_pi_ptr, new_pi) \
93 gst_vaapi_mini_object_replace((GstVaapiMiniObject **)(old_pi_ptr), \
94 (GstVaapiMiniObject *)(new_pi))
96 /* ------------------------------------------------------------------------- */
97 /* --- H.264 Pictures --- */
98 /* ------------------------------------------------------------------------- */
101 * Extended picture flags:
103 * @GST_VAAPI_PICTURE_FLAG_IDR: flag that specifies an IDR picture
104 * @GST_VAAPI_PICTURE_FLAG_SHORT_TERM_REFERENCE: flag that specifies
105 * "used for short-term reference"
106 * @GST_VAAPI_PICTURE_FLAG_LONG_TERM_REFERENCE: flag that specifies
107 * "used for long-term reference"
108 * @GST_VAAPI_PICTURE_FLAGS_REFERENCE: mask covering any kind of
109 * reference picture (short-term reference or long-term reference)
112 GST_VAAPI_PICTURE_FLAG_IDR = (GST_VAAPI_PICTURE_FLAG_LAST << 0),
114 GST_VAAPI_PICTURE_FLAG_SHORT_TERM_REFERENCE = (
115 GST_VAAPI_PICTURE_FLAG_REFERENCE),
116 GST_VAAPI_PICTURE_FLAG_LONG_TERM_REFERENCE = (
117 GST_VAAPI_PICTURE_FLAG_REFERENCE | (GST_VAAPI_PICTURE_FLAG_LAST << 1)),
118 GST_VAAPI_PICTURE_FLAGS_REFERENCE = (
119 GST_VAAPI_PICTURE_FLAG_SHORT_TERM_REFERENCE |
120 GST_VAAPI_PICTURE_FLAG_LONG_TERM_REFERENCE),
123 #define GST_VAAPI_PICTURE_IS_IDR(picture) \
124 (GST_VAAPI_PICTURE_FLAG_IS_SET(picture, GST_VAAPI_PICTURE_FLAG_IDR))
126 #define GST_VAAPI_PICTURE_IS_SHORT_TERM_REFERENCE(picture) \
127 ((GST_VAAPI_PICTURE_FLAGS(picture) & \
128 GST_VAAPI_PICTURE_FLAGS_REFERENCE) == \
129 GST_VAAPI_PICTURE_FLAG_SHORT_TERM_REFERENCE)
131 #define GST_VAAPI_PICTURE_IS_LONG_TERM_REFERENCE(picture) \
132 ((GST_VAAPI_PICTURE_FLAGS(picture) & \
133 GST_VAAPI_PICTURE_FLAGS_REFERENCE) == \
134 GST_VAAPI_PICTURE_FLAG_LONG_TERM_REFERENCE)
136 struct _GstVaapiPictureH264 {
137 GstVaapiPicture base;
139 GstH264SliceHdr *last_slice_hdr;
142 gint32 frame_num; // Original frame_num from slice_header()
143 gint32 frame_num_wrap; // Temporary for ref pic marking: FrameNumWrap
144 gint32 long_term_frame_idx; // Temporary for ref pic marking: LongTermFrameIdx
145 gint32 pic_num; // Temporary for ref pic marking: PicNum
146 gint32 long_term_pic_num; // Temporary for ref pic marking: LongTermPicNum
147 GstVaapiPictureH264 *other_field; // Temporary for ref pic marking: other field in the same frame store
148 guint output_flag : 1;
149 guint output_needed : 1;
152 GST_VAAPI_CODEC_DEFINE_TYPE(GstVaapiPictureH264, gst_vaapi_picture_h264);
155 gst_vaapi_picture_h264_destroy(GstVaapiPictureH264 *picture)
157 gst_vaapi_picture_destroy(GST_VAAPI_PICTURE(picture));
161 gst_vaapi_picture_h264_create(
162 GstVaapiPictureH264 *picture,
163 const GstVaapiCodecObjectConstructorArgs *args
166 if (!gst_vaapi_picture_create(GST_VAAPI_PICTURE(picture), args))
169 picture->field_poc[0] = G_MAXINT32;
170 picture->field_poc[1] = G_MAXINT32;
171 picture->output_needed = FALSE;
175 static inline GstVaapiPictureH264 *
176 gst_vaapi_picture_h264_new(GstVaapiDecoderH264 *decoder)
178 return (GstVaapiPictureH264 *)gst_vaapi_codec_object_new(
179 &GstVaapiPictureH264Class,
180 GST_VAAPI_CODEC_BASE(decoder),
181 NULL, sizeof(VAPictureParameterBufferH264),
187 gst_vaapi_picture_h264_set_reference(
188 GstVaapiPictureH264 *picture,
189 guint reference_flags,
195 GST_VAAPI_PICTURE_FLAG_UNSET(picture, GST_VAAPI_PICTURE_FLAGS_REFERENCE);
196 GST_VAAPI_PICTURE_FLAG_SET(picture, reference_flags);
198 if (!other_field || !(picture = picture->other_field))
200 GST_VAAPI_PICTURE_FLAG_UNSET(picture, GST_VAAPI_PICTURE_FLAGS_REFERENCE);
201 GST_VAAPI_PICTURE_FLAG_SET(picture, reference_flags);
204 static inline GstVaapiPictureH264 *
205 gst_vaapi_picture_h264_new_field(GstVaapiPictureH264 *picture)
207 g_return_val_if_fail(picture, NULL);
209 return (GstVaapiPictureH264 *)gst_vaapi_picture_new_field(&picture->base);
212 /* ------------------------------------------------------------------------- */
213 /* --- Frame Buffers (DPB) --- */
214 /* ------------------------------------------------------------------------- */
216 struct _GstVaapiFrameStore {
218 GstVaapiMiniObject parent_instance;
221 GstVaapiPictureH264 *buffers[2];
227 gst_vaapi_frame_store_finalize(gpointer object)
229 GstVaapiFrameStore * const fs = object;
232 for (i = 0; i < fs->num_buffers; i++)
233 gst_vaapi_picture_replace(&fs->buffers[i], NULL);
236 static GstVaapiFrameStore *
237 gst_vaapi_frame_store_new(GstVaapiPictureH264 *picture)
239 GstVaapiFrameStore *fs;
241 static const GstVaapiMiniObjectClass GstVaapiFrameStoreClass = {
242 sizeof(GstVaapiFrameStore),
243 gst_vaapi_frame_store_finalize
246 fs = (GstVaapiFrameStore *)
247 gst_vaapi_mini_object_new(&GstVaapiFrameStoreClass);
251 fs->structure = picture->structure;
252 fs->buffers[0] = gst_vaapi_picture_ref(picture);
253 fs->buffers[1] = NULL;
255 fs->output_needed = picture->output_needed;
260 gst_vaapi_frame_store_add(GstVaapiFrameStore *fs, GstVaapiPictureH264 *picture)
264 g_return_val_if_fail(fs->num_buffers == 1, FALSE);
265 g_return_val_if_fail(!GST_VAAPI_PICTURE_IS_FRAME(picture), FALSE);
266 g_return_val_if_fail(!GST_VAAPI_PICTURE_IS_FIRST_FIELD(picture), FALSE);
268 gst_vaapi_picture_replace(&fs->buffers[fs->num_buffers++], picture);
269 if (picture->output_flag) {
270 picture->output_needed = TRUE;
274 fs->structure = GST_VAAPI_PICTURE_STRUCTURE_FRAME;
276 field = picture->structure == GST_VAAPI_PICTURE_STRUCTURE_TOP_FIELD ?
277 TOP_FIELD : BOTTOM_FIELD;
278 g_return_val_if_fail(fs->buffers[0]->field_poc[field] == G_MAXINT32, FALSE);
279 fs->buffers[0]->field_poc[field] = picture->field_poc[field];
280 g_return_val_if_fail(picture->field_poc[!field] == G_MAXINT32, FALSE);
281 picture->field_poc[!field] = fs->buffers[0]->field_poc[!field];
286 gst_vaapi_frame_store_split_fields(GstVaapiFrameStore *fs)
288 GstVaapiPictureH264 * const first_field = fs->buffers[0];
289 GstVaapiPictureH264 *second_field;
291 g_return_val_if_fail(fs->num_buffers == 1, FALSE);
293 first_field->base.structure = GST_VAAPI_PICTURE_STRUCTURE_TOP_FIELD;
294 GST_VAAPI_PICTURE_FLAG_SET(first_field, GST_VAAPI_PICTURE_FLAG_INTERLACED);
296 second_field = gst_vaapi_picture_h264_new_field(first_field);
299 gst_vaapi_picture_replace(&fs->buffers[fs->num_buffers++], second_field);
300 gst_vaapi_picture_unref(second_field);
302 second_field->frame_num = first_field->frame_num;
303 second_field->field_poc[0] = first_field->field_poc[0];
304 second_field->field_poc[1] = first_field->field_poc[1];
305 second_field->output_flag = first_field->output_flag;
306 if (second_field->output_flag) {
307 second_field->output_needed = TRUE;
313 static inline gboolean
314 gst_vaapi_frame_store_has_frame(GstVaapiFrameStore *fs)
316 return fs->structure == GST_VAAPI_PICTURE_STRUCTURE_FRAME;
319 static inline gboolean
320 gst_vaapi_frame_store_has_reference(GstVaapiFrameStore *fs)
324 for (i = 0; i < fs->num_buffers; i++) {
325 if (GST_VAAPI_PICTURE_IS_REFERENCE(fs->buffers[i]))
331 #define gst_vaapi_frame_store_ref(fs) \
332 gst_vaapi_mini_object_ref(GST_VAAPI_MINI_OBJECT(fs))
334 #define gst_vaapi_frame_store_unref(fs) \
335 gst_vaapi_mini_object_unref(GST_VAAPI_MINI_OBJECT(fs))
337 #define gst_vaapi_frame_store_replace(old_fs_p, new_fs) \
338 gst_vaapi_mini_object_replace((GstVaapiMiniObject **)(old_fs_p), \
339 (GstVaapiMiniObject *)(new_fs))
341 /* ------------------------------------------------------------------------- */
342 /* --- H.264 Decoder --- */
343 /* ------------------------------------------------------------------------- */
345 G_DEFINE_TYPE(GstVaapiDecoderH264,
346 gst_vaapi_decoder_h264,
347 GST_VAAPI_TYPE_DECODER)
349 #define GST_VAAPI_DECODER_H264_CAST(decoder) \
350 ((GstVaapiDecoderH264 *)(decoder))
352 #define GST_VAAPI_DECODER_H264_GET_PRIVATE(obj) \
353 (G_TYPE_INSTANCE_GET_PRIVATE((obj), \
354 GST_VAAPI_TYPE_DECODER_H264, \
355 GstVaapiDecoderH264Private))
357 struct _GstVaapiDecoderH264Private {
358 GstH264NalParser *parser;
359 GstVaapiPictureH264 *current_picture;
360 GstVaapiParserInfoH264 *prev_slice_pi;
361 GstVaapiFrameStore *prev_frame;
362 GstVaapiFrameStore *dpb[16];
365 GstVaapiProfile profile;
366 GstVaapiEntrypoint entrypoint;
367 GstVaapiChromaType chroma_type;
368 GstVaapiPictureH264 *short_ref[32];
369 guint short_ref_count;
370 GstVaapiPictureH264 *long_ref[32];
371 guint long_ref_count;
372 GstVaapiPictureH264 *RefPicList0[32];
373 guint RefPicList0_count;
374 GstVaapiPictureH264 *RefPicList1[32];
375 guint RefPicList1_count;
376 guint nal_length_size;
379 gint32 field_poc[2]; // 0:TopFieldOrderCnt / 1:BottomFieldOrderCnt
380 gint32 poc_msb; // PicOrderCntMsb
381 gint32 poc_lsb; // pic_order_cnt_lsb (from slice_header())
382 gint32 prev_poc_msb; // prevPicOrderCntMsb
383 gint32 prev_poc_lsb; // prevPicOrderCntLsb
384 gint32 frame_num_offset; // FrameNumOffset
385 gint32 frame_num; // frame_num (from slice_header())
386 gint32 prev_frame_num; // prevFrameNum
387 gboolean prev_pic_has_mmco5; // prevMmco5Pic
388 gboolean prev_pic_structure; // previous picture structure
389 guint is_constructed : 1;
394 guint has_context : 1;
395 guint progressive_sequence : 1;
399 exec_ref_pic_marking(GstVaapiDecoderH264 *decoder, GstVaapiPictureH264 *picture);
401 /* Get number of reference frames to use */
403 get_max_dec_frame_buffering(GstH264SPS *sps)
405 guint max_dec_frame_buffering, MaxDpbMbs, PicSizeMbs;
407 /* Table A-1 - Level limits */
408 switch (sps->level_idc) {
409 case 10: MaxDpbMbs = 396; break;
410 case 11: MaxDpbMbs = 900; break;
411 case 12: MaxDpbMbs = 2376; break;
412 case 13: MaxDpbMbs = 2376; break;
413 case 20: MaxDpbMbs = 2376; break;
414 case 21: MaxDpbMbs = 4752; break;
415 case 22: MaxDpbMbs = 8100; break;
416 case 30: MaxDpbMbs = 8100; break;
417 case 31: MaxDpbMbs = 18000; break;
418 case 32: MaxDpbMbs = 20480; break;
419 case 40: MaxDpbMbs = 32768; break;
420 case 41: MaxDpbMbs = 32768; break;
421 case 42: MaxDpbMbs = 34816; break;
422 case 50: MaxDpbMbs = 110400; break;
423 case 51: MaxDpbMbs = 184320; break;
425 g_assert(0 && "unhandled level");
429 PicSizeMbs = ((sps->pic_width_in_mbs_minus1 + 1) *
430 (sps->pic_height_in_map_units_minus1 + 1) *
431 (sps->frame_mbs_only_flag ? 1 : 2));
432 max_dec_frame_buffering = MaxDpbMbs / PicSizeMbs;
435 if (sps->vui_parameters_present_flag) {
436 GstH264VUIParams * const vui_params = &sps->vui_parameters;
437 if (vui_params->bitstream_restriction_flag)
438 max_dec_frame_buffering = vui_params->max_dec_frame_buffering;
440 switch (sps->profile_idc) {
441 case 44: // CAVLC 4:4:4 Intra profile
442 case GST_H264_PROFILE_SCALABLE_HIGH:
443 case GST_H264_PROFILE_HIGH:
444 case GST_H264_PROFILE_HIGH10:
445 case GST_H264_PROFILE_HIGH_422:
446 case GST_H264_PROFILE_HIGH_444:
447 if (sps->constraint_set3_flag)
448 max_dec_frame_buffering = 0;
454 if (max_dec_frame_buffering > 16)
455 max_dec_frame_buffering = 16;
456 else if (max_dec_frame_buffering < sps->num_ref_frames)
457 max_dec_frame_buffering = sps->num_ref_frames;
458 return MAX(1, max_dec_frame_buffering);
462 array_remove_index_fast(void *array, guint *array_length_ptr, guint index)
464 gpointer * const entries = array;
465 guint num_entries = *array_length_ptr;
467 g_return_if_fail(index < num_entries);
469 if (index != --num_entries)
470 entries[index] = entries[num_entries];
471 entries[num_entries] = NULL;
472 *array_length_ptr = num_entries;
477 array_remove_index(void *array, guint *array_length_ptr, guint index)
479 array_remove_index_fast(array, array_length_ptr, index);
483 array_remove_index(void *array, guint *array_length_ptr, guint index)
485 gpointer * const entries = array;
486 const guint num_entries = *array_length_ptr - 1;
489 g_return_if_fail(index <= num_entries);
491 for (i = index; i < num_entries; i++)
492 entries[i] = entries[i + 1];
493 entries[num_entries] = NULL;
494 *array_length_ptr = num_entries;
498 #define ARRAY_REMOVE_INDEX(array, index) \
499 array_remove_index(array, &array##_count, index)
502 dpb_remove_index(GstVaapiDecoderH264 *decoder, guint index)
504 GstVaapiDecoderH264Private * const priv = decoder->priv;
505 guint i, num_frames = --priv->dpb_count;
507 if (USE_STRICT_DPB_ORDERING) {
508 for (i = index; i < num_frames; i++)
509 gst_vaapi_frame_store_replace(&priv->dpb[i], priv->dpb[i + 1]);
511 else if (index != num_frames)
512 gst_vaapi_frame_store_replace(&priv->dpb[index], priv->dpb[num_frames]);
513 gst_vaapi_frame_store_replace(&priv->dpb[num_frames], NULL);
518 GstVaapiDecoderH264 *decoder,
519 GstVaapiFrameStore *fs,
520 GstVaapiPictureH264 *picture
523 picture->output_needed = FALSE;
526 if (--fs->output_needed > 0)
528 picture = fs->buffers[0];
531 /* XXX: update cropping rectangle */
532 return gst_vaapi_picture_output(GST_VAAPI_PICTURE_CAST(picture));
536 dpb_evict(GstVaapiDecoderH264 *decoder, GstVaapiPictureH264 *picture, guint i)
538 GstVaapiFrameStore * const fs = decoder->priv->dpb[i];
540 if (!fs->output_needed && !gst_vaapi_frame_store_has_reference(fs))
541 dpb_remove_index(decoder, i);
545 dpb_bump(GstVaapiDecoderH264 *decoder)
547 GstVaapiDecoderH264Private * const priv = decoder->priv;
548 GstVaapiPictureH264 *found_picture = NULL;
549 guint i, j, found_index;
552 for (i = 0; i < priv->dpb_count; i++) {
553 GstVaapiFrameStore * const fs = priv->dpb[i];
554 if (!fs->output_needed)
556 for (j = 0; j < fs->num_buffers; j++) {
557 GstVaapiPictureH264 * const picture = fs->buffers[j];
558 if (!picture->output_needed)
560 if (!found_picture || found_picture->base.poc > picture->base.poc)
561 found_picture = picture, found_index = i;
567 success = dpb_output(decoder, priv->dpb[found_index], found_picture);
568 dpb_evict(decoder, found_picture, found_index);
573 dpb_clear(GstVaapiDecoderH264 *decoder)
575 GstVaapiDecoderH264Private * const priv = decoder->priv;
578 for (i = 0; i < priv->dpb_count; i++)
579 gst_vaapi_frame_store_replace(&priv->dpb[i], NULL);
582 gst_vaapi_frame_store_replace(&priv->prev_frame, NULL);
586 dpb_flush(GstVaapiDecoderH264 *decoder)
588 while (dpb_bump(decoder))
594 dpb_add(GstVaapiDecoderH264 *decoder, GstVaapiPictureH264 *picture)
596 GstVaapiDecoderH264Private * const priv = decoder->priv;
597 GstVaapiFrameStore *fs;
600 // Remove all unused pictures
601 if (!GST_VAAPI_PICTURE_IS_IDR(picture)) {
603 while (i < priv->dpb_count) {
604 GstVaapiFrameStore * const fs = priv->dpb[i];
605 if (!fs->output_needed && !gst_vaapi_frame_store_has_reference(fs))
606 dpb_remove_index(decoder, i);
612 // Check if picture is the second field and the first field is still in DPB
613 fs = priv->prev_frame;
614 if (fs && !gst_vaapi_frame_store_has_frame(fs))
615 return gst_vaapi_frame_store_add(fs, picture);
617 // Create new frame store, and split fields if necessary
618 fs = gst_vaapi_frame_store_new(picture);
621 gst_vaapi_frame_store_replace(&priv->prev_frame, fs);
622 gst_vaapi_frame_store_unref(fs);
624 if (!priv->progressive_sequence && gst_vaapi_frame_store_has_frame(fs)) {
625 if (!gst_vaapi_frame_store_split_fields(fs))
629 // C.4.5.1 - Storage and marking of a reference decoded picture into the DPB
630 if (GST_VAAPI_PICTURE_IS_REFERENCE(picture)) {
631 while (priv->dpb_count == priv->dpb_size) {
632 if (!dpb_bump(decoder))
635 gst_vaapi_frame_store_replace(&priv->dpb[priv->dpb_count++], fs);
636 if (picture->output_flag) {
637 picture->output_needed = TRUE;
642 // C.4.5.2 - Storage and marking of a non-reference decoded picture into the DPB
644 if (!picture->output_flag)
646 while (priv->dpb_count == priv->dpb_size) {
647 gboolean found_picture = FALSE;
648 for (i = 0; !found_picture && i < priv->dpb_count; i++) {
649 GstVaapiFrameStore * const fs = priv->dpb[i];
650 if (!fs->output_needed)
652 for (j = 0; !found_picture && j < fs->num_buffers; j++)
653 found_picture = fs->buffers[j]->output_needed &&
654 fs->buffers[j]->base.poc < picture->base.poc;
657 return dpb_output(decoder, NULL, picture);
658 if (!dpb_bump(decoder))
661 gst_vaapi_frame_store_replace(&priv->dpb[priv->dpb_count++], fs);
662 picture->output_needed = TRUE;
669 dpb_reset(GstVaapiDecoderH264 *decoder, GstH264SPS *sps)
671 GstVaapiDecoderH264Private * const priv = decoder->priv;
673 priv->dpb_size = get_max_dec_frame_buffering(sps);
674 GST_DEBUG("DPB size %u", priv->dpb_size);
677 static GstVaapiDecoderStatus
678 get_status(GstH264ParserResult result)
680 GstVaapiDecoderStatus status;
683 case GST_H264_PARSER_OK:
684 status = GST_VAAPI_DECODER_STATUS_SUCCESS;
686 case GST_H264_PARSER_NO_NAL_END:
687 status = GST_VAAPI_DECODER_STATUS_ERROR_NO_DATA;
689 case GST_H264_PARSER_ERROR:
690 status = GST_VAAPI_DECODER_STATUS_ERROR_BITSTREAM_PARSER;
693 status = GST_VAAPI_DECODER_STATUS_ERROR_UNKNOWN;
700 gst_vaapi_decoder_h264_close(GstVaapiDecoderH264 *decoder)
702 GstVaapiDecoderH264Private * const priv = decoder->priv;
704 gst_vaapi_picture_replace(&priv->current_picture, NULL);
705 gst_vaapi_parser_info_h264_replace(&priv->prev_slice_pi, NULL);
710 gst_h264_nal_parser_free(priv->parser);
716 gst_vaapi_decoder_h264_open(GstVaapiDecoderH264 *decoder)
718 GstVaapiDecoderH264Private * const priv = decoder->priv;
720 gst_vaapi_decoder_h264_close(decoder);
722 priv->parser = gst_h264_nal_parser_new();
729 gst_vaapi_decoder_h264_destroy(GstVaapiDecoderH264 *decoder)
731 gst_vaapi_decoder_h264_close(decoder);
735 gst_vaapi_decoder_h264_create(GstVaapiDecoderH264 *decoder)
737 if (!GST_VAAPI_DECODER_CODEC(decoder))
743 h264_get_profile(GstH264SPS *sps)
747 switch (sps->profile_idc) {
748 case GST_H264_PROFILE_BASELINE:
749 profile = GST_VAAPI_PROFILE_H264_BASELINE;
751 case GST_H264_PROFILE_MAIN:
752 profile = GST_VAAPI_PROFILE_H264_MAIN;
754 case GST_H264_PROFILE_HIGH:
755 profile = GST_VAAPI_PROFILE_H264_HIGH;
762 h264_get_chroma_type(GstH264SPS *sps)
764 guint chroma_type = 0;
766 switch (sps->chroma_format_idc) {
768 chroma_type = GST_VAAPI_CHROMA_TYPE_YUV420;
771 chroma_type = GST_VAAPI_CHROMA_TYPE_YUV422;
774 if (!sps->separate_colour_plane_flag)
775 chroma_type = GST_VAAPI_CHROMA_TYPE_YUV444;
781 static GstVaapiProfile
782 get_profile(GstVaapiDecoderH264 *decoder, GstH264SPS *sps)
784 GstVaapiDecoderH264Private * const priv = decoder->priv;
785 GstVaapiDisplay * const display = GST_VAAPI_DECODER_DISPLAY(decoder);
786 GstVaapiProfile profile, profiles[2];
787 guint i, n_profiles = 0;
789 profile = h264_get_profile(sps);
791 return GST_VAAPI_PROFILE_UNKNOWN;
793 profiles[n_profiles++] = profile;
795 case GST_VAAPI_PROFILE_H264_MAIN:
796 profiles[n_profiles++] = GST_VAAPI_PROFILE_H264_HIGH;
802 /* If the preferred profile (profiles[0]) matches one that we already
803 found, then just return it now instead of searching for it again */
804 if (profiles[0] == priv->profile)
805 return priv->profile;
807 for (i = 0; i < n_profiles; i++) {
808 if (gst_vaapi_display_has_decoder(display, profiles[i], priv->entrypoint))
811 return GST_VAAPI_PROFILE_UNKNOWN;
814 static GstVaapiDecoderStatus
815 ensure_context(GstVaapiDecoderH264 *decoder, GstH264SPS *sps)
817 GstVaapiDecoder * const base_decoder = GST_VAAPI_DECODER_CAST(decoder);
818 GstVaapiDecoderH264Private * const priv = decoder->priv;
819 GstVaapiContextInfo info;
820 GstVaapiProfile profile;
821 GstVaapiChromaType chroma_type;
822 gboolean reset_context = FALSE;
823 guint mb_width, mb_height;
825 profile = get_profile(decoder, sps);
827 GST_ERROR("unsupported profile_idc %u", sps->profile_idc);
828 return GST_VAAPI_DECODER_STATUS_ERROR_UNSUPPORTED_PROFILE;
831 if (priv->profile != profile) {
832 GST_DEBUG("profile changed");
833 reset_context = TRUE;
834 priv->profile = profile;
837 chroma_type = h264_get_chroma_type(sps);
838 if (!chroma_type || chroma_type != GST_VAAPI_CHROMA_TYPE_YUV420) {
839 GST_ERROR("unsupported chroma_format_idc %u", sps->chroma_format_idc);
840 return GST_VAAPI_DECODER_STATUS_ERROR_UNSUPPORTED_CHROMA_FORMAT;
843 if (priv->chroma_type != chroma_type) {
844 GST_DEBUG("chroma format changed");
845 reset_context = TRUE;
846 priv->chroma_type = chroma_type;
849 mb_width = sps->pic_width_in_mbs_minus1 + 1;
850 mb_height = (sps->pic_height_in_map_units_minus1 + 1) <<
851 !sps->frame_mbs_only_flag;
852 if (priv->mb_width != mb_width || priv->mb_height != mb_height) {
853 GST_DEBUG("size changed");
854 reset_context = TRUE;
855 priv->mb_width = mb_width;
856 priv->mb_height = mb_height;
859 priv->progressive_sequence = sps->frame_mbs_only_flag;
861 /* XXX: we only output complete frames for now */
862 gst_vaapi_decoder_set_interlaced(base_decoder, !priv->progressive_sequence);
865 gst_vaapi_decoder_set_pixel_aspect_ratio(
867 sps->vui_parameters.par_n,
868 sps->vui_parameters.par_d
871 if (!reset_context && priv->has_context)
872 return GST_VAAPI_DECODER_STATUS_SUCCESS;
874 /* XXX: fix surface size when cropping is implemented */
875 info.profile = priv->profile;
876 info.entrypoint = priv->entrypoint;
877 info.width = sps->width;
878 info.height = sps->height;
879 info.ref_frames = get_max_dec_frame_buffering(sps);
881 if (!gst_vaapi_decoder_ensure_context(GST_VAAPI_DECODER(decoder), &info))
882 return GST_VAAPI_DECODER_STATUS_ERROR_UNKNOWN;
883 priv->has_context = TRUE;
886 dpb_reset(decoder, sps);
887 return GST_VAAPI_DECODER_STATUS_SUCCESS;
891 fill_iq_matrix_4x4(VAIQMatrixBufferH264 *iq_matrix, const GstH264PPS *pps)
893 const guint8 (* const ScalingList4x4)[6][16] = &pps->scaling_lists_4x4;
896 /* There are always 6 4x4 scaling lists */
897 g_assert(G_N_ELEMENTS(iq_matrix->ScalingList4x4) == 6);
898 g_assert(G_N_ELEMENTS(iq_matrix->ScalingList4x4[0]) == 16);
900 if (sizeof(iq_matrix->ScalingList4x4[0][0]) == 1)
901 memcpy(iq_matrix->ScalingList4x4, *ScalingList4x4,
902 sizeof(iq_matrix->ScalingList4x4));
904 for (i = 0; i < G_N_ELEMENTS(iq_matrix->ScalingList4x4); i++) {
905 for (j = 0; j < G_N_ELEMENTS(iq_matrix->ScalingList4x4[i]); j++)
906 iq_matrix->ScalingList4x4[i][j] = (*ScalingList4x4)[i][j];
912 fill_iq_matrix_8x8(VAIQMatrixBufferH264 *iq_matrix, const GstH264PPS *pps)
914 const guint8 (* const ScalingList8x8)[6][64] = &pps->scaling_lists_8x8;
915 const GstH264SPS * const sps = pps->sequence;
918 /* If chroma_format_idc != 3, there are up to 2 8x8 scaling lists */
919 if (!pps->transform_8x8_mode_flag)
922 g_assert(G_N_ELEMENTS(iq_matrix->ScalingList8x8) >= 2);
923 g_assert(G_N_ELEMENTS(iq_matrix->ScalingList8x8[0]) == 64);
925 if (sizeof(iq_matrix->ScalingList8x8[0][0]) == 1)
926 memcpy(iq_matrix->ScalingList8x8, *ScalingList8x8,
927 sizeof(iq_matrix->ScalingList8x8));
929 n = (sps->chroma_format_idc != 3) ? 2 : 6;
930 for (i = 0; i < n; i++) {
931 for (j = 0; j < G_N_ELEMENTS(iq_matrix->ScalingList8x8[i]); j++)
932 iq_matrix->ScalingList8x8[i][j] = (*ScalingList8x8)[i][j];
937 static GstVaapiDecoderStatus
938 ensure_quant_matrix(GstVaapiDecoderH264 *decoder, GstVaapiPictureH264 *picture)
940 GstVaapiPicture * const base_picture = &picture->base;
941 GstH264PPS * const pps = picture->pps;
942 GstH264SPS * const sps = pps->sequence;
943 VAIQMatrixBufferH264 *iq_matrix;
945 base_picture->iq_matrix = GST_VAAPI_IQ_MATRIX_NEW(H264, decoder);
946 if (!base_picture->iq_matrix) {
947 GST_ERROR("failed to allocate IQ matrix");
948 return GST_VAAPI_DECODER_STATUS_ERROR_ALLOCATION_FAILED;
950 iq_matrix = base_picture->iq_matrix->param;
952 /* XXX: we can only support 4:2:0 or 4:2:2 since ScalingLists8x8[]
953 is not large enough to hold lists for 4:4:4 */
954 if (sps->chroma_format_idc == 3)
955 return GST_VAAPI_DECODER_STATUS_ERROR_UNSUPPORTED_CHROMA_FORMAT;
957 fill_iq_matrix_4x4(iq_matrix, pps);
958 fill_iq_matrix_8x8(iq_matrix, pps);
960 return GST_VAAPI_DECODER_STATUS_SUCCESS;
963 static GstVaapiDecoderStatus
964 decode_current_picture(GstVaapiDecoderH264 *decoder)
966 GstVaapiDecoderH264Private * const priv = decoder->priv;
967 GstVaapiPictureH264 * const picture = priv->current_picture;
970 return GST_VAAPI_DECODER_STATUS_SUCCESS;
972 if (!exec_ref_pic_marking(decoder, picture))
974 if (!dpb_add(decoder, picture))
976 if (!gst_vaapi_picture_decode(GST_VAAPI_PICTURE_CAST(picture)))
978 if (priv->prev_frame && gst_vaapi_frame_store_has_frame(priv->prev_frame))
979 gst_vaapi_picture_replace(&priv->current_picture, NULL);
980 return GST_VAAPI_DECODER_STATUS_SUCCESS;
983 /* XXX: fix for cases where first field failed to be decoded */
984 gst_vaapi_picture_replace(&priv->current_picture, NULL);
985 return GST_VAAPI_DECODER_STATUS_ERROR_UNKNOWN;
988 static GstVaapiDecoderStatus
989 parse_sps(GstVaapiDecoderH264 *decoder, GstVaapiDecoderUnit *unit)
991 GstVaapiDecoderH264Private * const priv = decoder->priv;
992 GstVaapiParserInfoH264 * const pi = unit->parsed_info;
993 GstH264SPS * const sps = &pi->data.sps;
994 GstH264ParserResult result;
996 GST_DEBUG("parse SPS");
998 /* Variables that don't have inferred values per the H.264
999 standard but that should get a default value anyway */
1000 sps->log2_max_pic_order_cnt_lsb_minus4 = 0;
1002 result = gst_h264_parser_parse_sps(priv->parser, &pi->nalu, sps, TRUE);
1003 if (result != GST_H264_PARSER_OK)
1004 return get_status(result);
1006 priv->got_sps = TRUE;
1007 return GST_VAAPI_DECODER_STATUS_SUCCESS;
1010 static GstVaapiDecoderStatus
1011 parse_pps(GstVaapiDecoderH264 *decoder, GstVaapiDecoderUnit *unit)
1013 GstVaapiDecoderH264Private * const priv = decoder->priv;
1014 GstVaapiParserInfoH264 * const pi = unit->parsed_info;
1015 GstH264PPS * const pps = &pi->data.pps;
1016 GstH264ParserResult result;
1018 GST_DEBUG("parse PPS");
1020 /* Variables that don't have inferred values per the H.264
1021 standard but that should get a default value anyway */
1022 pps->slice_group_map_type = 0;
1023 pps->slice_group_change_rate_minus1 = 0;
1025 result = gst_h264_parser_parse_pps(priv->parser, &pi->nalu, pps);
1026 if (result != GST_H264_PARSER_OK)
1027 return get_status(result);
1029 priv->got_pps = TRUE;
1030 return GST_VAAPI_DECODER_STATUS_SUCCESS;
1033 static GstVaapiDecoderStatus
1034 parse_sei(GstVaapiDecoderH264 *decoder, GstVaapiDecoderUnit *unit)
1036 GstVaapiDecoderH264Private * const priv = decoder->priv;
1037 GstVaapiParserInfoH264 * const pi = unit->parsed_info;
1038 GstH264SEIMessage sei;
1039 GstH264ParserResult result;
1041 GST_DEBUG("parse SEI");
1043 memset(&sei, 0, sizeof(sei));
1044 result = gst_h264_parser_parse_sei(priv->parser, &pi->nalu, &sei);
1045 if (result != GST_H264_PARSER_OK) {
1046 GST_WARNING("failed to parse SEI, payload type:%d", sei.payloadType);
1047 return get_status(result);
1050 return GST_VAAPI_DECODER_STATUS_SUCCESS;
1053 static GstVaapiDecoderStatus
1054 parse_slice(GstVaapiDecoderH264 *decoder, GstVaapiDecoderUnit *unit)
1056 GstVaapiDecoderH264Private * const priv = decoder->priv;
1057 GstVaapiParserInfoH264 * const pi = unit->parsed_info;
1058 GstH264SliceHdr * const slice_hdr = &pi->data.slice_hdr;
1059 GstH264ParserResult result;
1061 GST_DEBUG("parse slice");
1063 /* Variables that don't have inferred values per the H.264
1064 standard but that should get a default value anyway */
1065 slice_hdr->cabac_init_idc = 0;
1066 slice_hdr->direct_spatial_mv_pred_flag = 0;
1068 result = gst_h264_parser_parse_slice_hdr(priv->parser, &pi->nalu,
1069 slice_hdr, TRUE, TRUE);
1070 if (result != GST_H264_PARSER_OK)
1071 return get_status(result);
1073 return GST_VAAPI_DECODER_STATUS_SUCCESS;
1076 static GstVaapiDecoderStatus
1077 decode_sequence_end(GstVaapiDecoderH264 *decoder)
1079 GstVaapiDecoderStatus status;
1081 GST_DEBUG("decode sequence-end");
1083 status = decode_current_picture(decoder);
1084 if (status != GST_VAAPI_DECODER_STATUS_SUCCESS)
1088 return GST_VAAPI_DECODER_STATUS_SUCCESS;
1091 /* 8.2.1.1 - Decoding process for picture order count type 0 */
1094 GstVaapiDecoderH264 *decoder,
1095 GstVaapiPictureH264 *picture,
1096 GstH264SliceHdr *slice_hdr
1099 GstVaapiDecoderH264Private * const priv = decoder->priv;
1100 GstH264PPS * const pps = slice_hdr->pps;
1101 GstH264SPS * const sps = pps->sequence;
1102 const gint32 MaxPicOrderCntLsb = 1 << (sps->log2_max_pic_order_cnt_lsb_minus4 + 4);
1105 GST_DEBUG("decode picture order count type 0");
1107 if (GST_VAAPI_PICTURE_IS_IDR(picture)) {
1108 priv->prev_poc_msb = 0;
1109 priv->prev_poc_lsb = 0;
1111 else if (priv->prev_pic_has_mmco5) {
1112 priv->prev_poc_msb = 0;
1113 priv->prev_poc_lsb =
1114 (priv->prev_pic_structure == GST_VAAPI_PICTURE_STRUCTURE_BOTTOM_FIELD ?
1115 0 : priv->field_poc[TOP_FIELD]);
1118 priv->prev_poc_msb = priv->poc_msb;
1119 priv->prev_poc_lsb = priv->poc_lsb;
1123 priv->poc_lsb = slice_hdr->pic_order_cnt_lsb;
1124 if (priv->poc_lsb < priv->prev_poc_lsb &&
1125 (priv->prev_poc_lsb - priv->poc_lsb) >= (MaxPicOrderCntLsb / 2))
1126 priv->poc_msb = priv->prev_poc_msb + MaxPicOrderCntLsb;
1127 else if (priv->poc_lsb > priv->prev_poc_lsb &&
1128 (priv->poc_lsb - priv->prev_poc_lsb) > (MaxPicOrderCntLsb / 2))
1129 priv->poc_msb = priv->prev_poc_msb - MaxPicOrderCntLsb;
1131 priv->poc_msb = priv->prev_poc_msb;
1133 temp_poc = priv->poc_msb + priv->poc_lsb;
1134 switch (picture->structure) {
1135 case GST_VAAPI_PICTURE_STRUCTURE_FRAME:
1137 priv->field_poc[TOP_FIELD] = temp_poc;
1138 priv->field_poc[BOTTOM_FIELD] = temp_poc +
1139 slice_hdr->delta_pic_order_cnt_bottom;
1141 case GST_VAAPI_PICTURE_STRUCTURE_TOP_FIELD:
1143 priv->field_poc[TOP_FIELD] = temp_poc;
1145 case GST_VAAPI_PICTURE_STRUCTURE_BOTTOM_FIELD:
1147 priv->field_poc[BOTTOM_FIELD] = temp_poc;
1152 /* 8.2.1.2 - Decoding process for picture order count type 1 */
1155 GstVaapiDecoderH264 *decoder,
1156 GstVaapiPictureH264 *picture,
1157 GstH264SliceHdr *slice_hdr
1160 GstVaapiDecoderH264Private * const priv = decoder->priv;
1161 GstH264PPS * const pps = slice_hdr->pps;
1162 GstH264SPS * const sps = pps->sequence;
1163 const gint32 MaxFrameNum = 1 << (sps->log2_max_frame_num_minus4 + 4);
1164 gint32 prev_frame_num_offset, abs_frame_num, expected_poc;
1167 GST_DEBUG("decode picture order count type 1");
1169 if (priv->prev_pic_has_mmco5)
1170 prev_frame_num_offset = 0;
1172 prev_frame_num_offset = priv->frame_num_offset;
1175 if (GST_VAAPI_PICTURE_IS_IDR(picture))
1176 priv->frame_num_offset = 0;
1177 else if (priv->prev_frame_num > priv->frame_num)
1178 priv->frame_num_offset = prev_frame_num_offset + MaxFrameNum;
1180 priv->frame_num_offset = prev_frame_num_offset;
1183 if (sps->num_ref_frames_in_pic_order_cnt_cycle != 0)
1184 abs_frame_num = priv->frame_num_offset + priv->frame_num;
1187 if (!GST_VAAPI_PICTURE_IS_REFERENCE(picture) && abs_frame_num > 0)
1188 abs_frame_num = abs_frame_num - 1;
1190 if (abs_frame_num > 0) {
1191 gint32 expected_delta_per_poc_cycle;
1192 gint32 poc_cycle_cnt, frame_num_in_poc_cycle;
1194 expected_delta_per_poc_cycle = 0;
1195 for (i = 0; i < sps->num_ref_frames_in_pic_order_cnt_cycle; i++)
1196 expected_delta_per_poc_cycle += sps->offset_for_ref_frame[i];
1199 poc_cycle_cnt = (abs_frame_num - 1) /
1200 sps->num_ref_frames_in_pic_order_cnt_cycle;
1201 frame_num_in_poc_cycle = (abs_frame_num - 1) %
1202 sps->num_ref_frames_in_pic_order_cnt_cycle;
1205 expected_poc = poc_cycle_cnt * expected_delta_per_poc_cycle;
1206 for (i = 0; i <= frame_num_in_poc_cycle; i++)
1207 expected_poc += sps->offset_for_ref_frame[i];
1211 if (!GST_VAAPI_PICTURE_IS_REFERENCE(picture))
1212 expected_poc += sps->offset_for_non_ref_pic;
1215 switch (picture->structure) {
1216 case GST_VAAPI_PICTURE_STRUCTURE_FRAME:
1217 priv->field_poc[TOP_FIELD] = expected_poc +
1218 slice_hdr->delta_pic_order_cnt[0];
1219 priv->field_poc[BOTTOM_FIELD] = priv->field_poc[TOP_FIELD] +
1220 sps->offset_for_top_to_bottom_field +
1221 slice_hdr->delta_pic_order_cnt[1];
1223 case GST_VAAPI_PICTURE_STRUCTURE_TOP_FIELD:
1224 priv->field_poc[TOP_FIELD] = expected_poc +
1225 slice_hdr->delta_pic_order_cnt[0];
1227 case GST_VAAPI_PICTURE_STRUCTURE_BOTTOM_FIELD:
1228 priv->field_poc[BOTTOM_FIELD] = expected_poc +
1229 sps->offset_for_top_to_bottom_field +
1230 slice_hdr->delta_pic_order_cnt[0];
1235 /* 8.2.1.3 - Decoding process for picture order count type 2 */
1238 GstVaapiDecoderH264 *decoder,
1239 GstVaapiPictureH264 *picture,
1240 GstH264SliceHdr *slice_hdr
1243 GstVaapiDecoderH264Private * const priv = decoder->priv;
1244 GstH264PPS * const pps = slice_hdr->pps;
1245 GstH264SPS * const sps = pps->sequence;
1246 const gint32 MaxFrameNum = 1 << (sps->log2_max_frame_num_minus4 + 4);
1247 gint32 prev_frame_num_offset, temp_poc;
1249 GST_DEBUG("decode picture order count type 2");
1251 if (priv->prev_pic_has_mmco5)
1252 prev_frame_num_offset = 0;
1254 prev_frame_num_offset = priv->frame_num_offset;
1257 if (GST_VAAPI_PICTURE_IS_IDR(picture))
1258 priv->frame_num_offset = 0;
1259 else if (priv->prev_frame_num > priv->frame_num)
1260 priv->frame_num_offset = prev_frame_num_offset + MaxFrameNum;
1262 priv->frame_num_offset = prev_frame_num_offset;
1265 if (GST_VAAPI_PICTURE_IS_IDR(picture))
1267 else if (!GST_VAAPI_PICTURE_IS_REFERENCE(picture))
1268 temp_poc = 2 * (priv->frame_num_offset + priv->frame_num) - 1;
1270 temp_poc = 2 * (priv->frame_num_offset + priv->frame_num);
1273 if (picture->structure != GST_VAAPI_PICTURE_STRUCTURE_BOTTOM_FIELD)
1274 priv->field_poc[TOP_FIELD] = temp_poc;
1275 if (picture->structure != GST_VAAPI_PICTURE_STRUCTURE_TOP_FIELD)
1276 priv->field_poc[BOTTOM_FIELD] = temp_poc;
1279 /* 8.2.1 - Decoding process for picture order count */
1282 GstVaapiDecoderH264 *decoder,
1283 GstVaapiPictureH264 *picture,
1284 GstH264SliceHdr *slice_hdr
1287 GstVaapiDecoderH264Private * const priv = decoder->priv;
1288 GstH264PPS * const pps = slice_hdr->pps;
1289 GstH264SPS * const sps = pps->sequence;
1291 switch (sps->pic_order_cnt_type) {
1293 init_picture_poc_0(decoder, picture, slice_hdr);
1296 init_picture_poc_1(decoder, picture, slice_hdr);
1299 init_picture_poc_2(decoder, picture, slice_hdr);
1303 if (picture->structure != GST_VAAPI_PICTURE_STRUCTURE_BOTTOM_FIELD)
1304 picture->field_poc[TOP_FIELD] = priv->field_poc[TOP_FIELD];
1305 if (picture->structure != GST_VAAPI_PICTURE_STRUCTURE_TOP_FIELD)
1306 picture->field_poc[BOTTOM_FIELD] = priv->field_poc[BOTTOM_FIELD];
1307 picture->base.poc = MIN(picture->field_poc[0], picture->field_poc[1]);
1311 compare_picture_pic_num_dec(const void *a, const void *b)
1313 const GstVaapiPictureH264 * const picA = *(GstVaapiPictureH264 **)a;
1314 const GstVaapiPictureH264 * const picB = *(GstVaapiPictureH264 **)b;
1316 return picB->pic_num - picA->pic_num;
1320 compare_picture_long_term_pic_num_inc(const void *a, const void *b)
1322 const GstVaapiPictureH264 * const picA = *(GstVaapiPictureH264 **)a;
1323 const GstVaapiPictureH264 * const picB = *(GstVaapiPictureH264 **)b;
1325 return picA->long_term_pic_num - picB->long_term_pic_num;
1329 compare_picture_poc_dec(const void *a, const void *b)
1331 const GstVaapiPictureH264 * const picA = *(GstVaapiPictureH264 **)a;
1332 const GstVaapiPictureH264 * const picB = *(GstVaapiPictureH264 **)b;
1334 return picB->base.poc - picA->base.poc;
1338 compare_picture_poc_inc(const void *a, const void *b)
1340 const GstVaapiPictureH264 * const picA = *(GstVaapiPictureH264 **)a;
1341 const GstVaapiPictureH264 * const picB = *(GstVaapiPictureH264 **)b;
1343 return picA->base.poc - picB->base.poc;
1347 compare_picture_frame_num_wrap_dec(const void *a, const void *b)
1349 const GstVaapiPictureH264 * const picA = *(GstVaapiPictureH264 **)a;
1350 const GstVaapiPictureH264 * const picB = *(GstVaapiPictureH264 **)b;
1352 return picB->frame_num_wrap - picA->frame_num_wrap;
1356 compare_picture_long_term_frame_idx_inc(const void *a, const void *b)
1358 const GstVaapiPictureH264 * const picA = *(GstVaapiPictureH264 **)a;
1359 const GstVaapiPictureH264 * const picB = *(GstVaapiPictureH264 **)b;
1361 return picA->long_term_frame_idx - picB->long_term_frame_idx;
1364 /* 8.2.4.1 - Decoding process for picture numbers */
1366 init_picture_refs_pic_num(
1367 GstVaapiDecoderH264 *decoder,
1368 GstVaapiPictureH264 *picture,
1369 GstH264SliceHdr *slice_hdr
1372 GstVaapiDecoderH264Private * const priv = decoder->priv;
1373 GstH264PPS * const pps = slice_hdr->pps;
1374 GstH264SPS * const sps = pps->sequence;
1375 const gint32 MaxFrameNum = 1 << (sps->log2_max_frame_num_minus4 + 4);
1378 GST_DEBUG("decode picture numbers");
1380 for (i = 0; i < priv->short_ref_count; i++) {
1381 GstVaapiPictureH264 * const pic = priv->short_ref[i];
1384 if (pic->frame_num > priv->frame_num)
1385 pic->frame_num_wrap = pic->frame_num - MaxFrameNum;
1387 pic->frame_num_wrap = pic->frame_num;
1389 // (8-28, 8-30, 8-31)
1390 if (GST_VAAPI_PICTURE_IS_FRAME(picture))
1391 pic->pic_num = pic->frame_num_wrap;
1393 if (pic->structure == picture->structure)
1394 pic->pic_num = 2 * pic->frame_num_wrap + 1;
1396 pic->pic_num = 2 * pic->frame_num_wrap;
1400 for (i = 0; i < priv->long_ref_count; i++) {
1401 GstVaapiPictureH264 * const pic = priv->long_ref[i];
1403 // (8-29, 8-32, 8-33)
1404 if (GST_VAAPI_PICTURE_IS_FRAME(picture))
1405 pic->long_term_pic_num = pic->long_term_frame_idx;
1407 if (pic->structure == picture->structure)
1408 pic->long_term_pic_num = 2 * pic->long_term_frame_idx + 1;
1410 pic->long_term_pic_num = 2 * pic->long_term_frame_idx;
1415 #define SORT_REF_LIST(list, n, compare_func) \
1416 qsort(list, n, sizeof(*(list)), compare_picture_##compare_func)
1419 init_picture_refs_fields_1(
1420 guint picture_structure,
1421 GstVaapiPictureH264 *RefPicList[32],
1422 guint *RefPicList_count,
1423 GstVaapiPictureH264 *ref_list[32],
1424 guint ref_list_count
1431 n = *RefPicList_count;
1434 for (; i < ref_list_count; i++) {
1435 if (ref_list[i]->structure == picture_structure) {
1436 RefPicList[n++] = ref_list[i++];
1440 for (; j < ref_list_count; j++) {
1441 if (ref_list[j]->structure != picture_structure) {
1442 RefPicList[n++] = ref_list[j++];
1446 } while (i < ref_list_count || j < ref_list_count);
1447 *RefPicList_count = n;
1451 init_picture_refs_fields(
1452 GstVaapiPictureH264 *picture,
1453 GstVaapiPictureH264 *RefPicList[32],
1454 guint *RefPicList_count,
1455 GstVaapiPictureH264 *short_ref[32],
1456 guint short_ref_count,
1457 GstVaapiPictureH264 *long_ref[32],
1458 guint long_ref_count
1463 /* 8.2.4.2.5 - reference picture lists in fields */
1464 init_picture_refs_fields_1(picture->structure, RefPicList, &n,
1465 short_ref, short_ref_count);
1466 init_picture_refs_fields_1(picture->structure, RefPicList, &n,
1467 long_ref, long_ref_count);
1468 *RefPicList_count = n;
1472 init_picture_refs_p_slice(
1473 GstVaapiDecoderH264 *decoder,
1474 GstVaapiPictureH264 *picture,
1475 GstH264SliceHdr *slice_hdr
1478 GstVaapiDecoderH264Private * const priv = decoder->priv;
1479 GstVaapiPictureH264 **ref_list;
1482 GST_DEBUG("decode reference picture list for P and SP slices");
1484 if (GST_VAAPI_PICTURE_IS_FRAME(picture)) {
1485 /* 8.2.4.2.1 - P and SP slices in frames */
1486 if (priv->short_ref_count > 0) {
1487 ref_list = priv->RefPicList0;
1488 for (i = 0; i < priv->short_ref_count; i++)
1489 ref_list[i] = priv->short_ref[i];
1490 SORT_REF_LIST(ref_list, i, pic_num_dec);
1491 priv->RefPicList0_count += i;
1494 if (priv->long_ref_count > 0) {
1495 ref_list = &priv->RefPicList0[priv->RefPicList0_count];
1496 for (i = 0; i < priv->long_ref_count; i++)
1497 ref_list[i] = priv->long_ref[i];
1498 SORT_REF_LIST(ref_list, i, long_term_pic_num_inc);
1499 priv->RefPicList0_count += i;
1503 /* 8.2.4.2.2 - P and SP slices in fields */
1504 GstVaapiPictureH264 *short_ref[32];
1505 guint short_ref_count = 0;
1506 GstVaapiPictureH264 *long_ref[32];
1507 guint long_ref_count = 0;
1509 if (priv->short_ref_count > 0) {
1510 for (i = 0; i < priv->short_ref_count; i++)
1511 short_ref[i] = priv->short_ref[i];
1512 SORT_REF_LIST(short_ref, i, frame_num_wrap_dec);
1513 short_ref_count = i;
1516 if (priv->long_ref_count > 0) {
1517 for (i = 0; i < priv->long_ref_count; i++)
1518 long_ref[i] = priv->long_ref[i];
1519 SORT_REF_LIST(long_ref, i, long_term_frame_idx_inc);
1523 init_picture_refs_fields(
1525 priv->RefPicList0, &priv->RefPicList0_count,
1526 short_ref, short_ref_count,
1527 long_ref, long_ref_count
1533 init_picture_refs_b_slice(
1534 GstVaapiDecoderH264 *decoder,
1535 GstVaapiPictureH264 *picture,
1536 GstH264SliceHdr *slice_hdr
1539 GstVaapiDecoderH264Private * const priv = decoder->priv;
1540 GstVaapiPictureH264 **ref_list;
1543 GST_DEBUG("decode reference picture list for B slices");
1545 if (GST_VAAPI_PICTURE_IS_FRAME(picture)) {
1546 /* 8.2.4.2.3 - B slices in frames */
1549 if (priv->short_ref_count > 0) {
1550 // 1. Short-term references
1551 ref_list = priv->RefPicList0;
1552 for (n = 0, i = 0; i < priv->short_ref_count; i++) {
1553 if (priv->short_ref[i]->base.poc < picture->base.poc)
1554 ref_list[n++] = priv->short_ref[i];
1556 SORT_REF_LIST(ref_list, n, poc_dec);
1557 priv->RefPicList0_count += n;
1559 ref_list = &priv->RefPicList0[priv->RefPicList0_count];
1560 for (n = 0, i = 0; i < priv->short_ref_count; i++) {
1561 if (priv->short_ref[i]->base.poc >= picture->base.poc)
1562 ref_list[n++] = priv->short_ref[i];
1564 SORT_REF_LIST(ref_list, n, poc_inc);
1565 priv->RefPicList0_count += n;
1568 if (priv->long_ref_count > 0) {
1569 // 2. Long-term references
1570 ref_list = &priv->RefPicList0[priv->RefPicList0_count];
1571 for (n = 0, i = 0; i < priv->long_ref_count; i++)
1572 ref_list[n++] = priv->long_ref[i];
1573 SORT_REF_LIST(ref_list, n, long_term_pic_num_inc);
1574 priv->RefPicList0_count += n;
1578 if (priv->short_ref_count > 0) {
1579 // 1. Short-term references
1580 ref_list = priv->RefPicList1;
1581 for (n = 0, i = 0; i < priv->short_ref_count; i++) {
1582 if (priv->short_ref[i]->base.poc > picture->base.poc)
1583 ref_list[n++] = priv->short_ref[i];
1585 SORT_REF_LIST(ref_list, n, poc_inc);
1586 priv->RefPicList1_count += n;
1588 ref_list = &priv->RefPicList1[priv->RefPicList1_count];
1589 for (n = 0, i = 0; i < priv->short_ref_count; i++) {
1590 if (priv->short_ref[i]->base.poc <= picture->base.poc)
1591 ref_list[n++] = priv->short_ref[i];
1593 SORT_REF_LIST(ref_list, n, poc_dec);
1594 priv->RefPicList1_count += n;
1597 if (priv->long_ref_count > 0) {
1598 // 2. Long-term references
1599 ref_list = &priv->RefPicList1[priv->RefPicList1_count];
1600 for (n = 0, i = 0; i < priv->long_ref_count; i++)
1601 ref_list[n++] = priv->long_ref[i];
1602 SORT_REF_LIST(ref_list, n, long_term_pic_num_inc);
1603 priv->RefPicList1_count += n;
1607 /* 8.2.4.2.4 - B slices in fields */
1608 GstVaapiPictureH264 *short_ref0[32];
1609 guint short_ref0_count = 0;
1610 GstVaapiPictureH264 *short_ref1[32];
1611 guint short_ref1_count = 0;
1612 GstVaapiPictureH264 *long_ref[32];
1613 guint long_ref_count = 0;
1615 /* refFrameList0ShortTerm */
1616 if (priv->short_ref_count > 0) {
1617 ref_list = short_ref0;
1618 for (n = 0, i = 0; i < priv->short_ref_count; i++) {
1619 if (priv->short_ref[i]->base.poc <= picture->base.poc)
1620 ref_list[n++] = priv->short_ref[i];
1622 SORT_REF_LIST(ref_list, n, poc_dec);
1623 short_ref0_count += n;
1625 ref_list = &short_ref0[short_ref0_count];
1626 for (n = 0, i = 0; i < priv->short_ref_count; i++) {
1627 if (priv->short_ref[i]->base.poc > picture->base.poc)
1628 ref_list[n++] = priv->short_ref[i];
1630 SORT_REF_LIST(ref_list, n, poc_inc);
1631 short_ref0_count += n;
1634 /* refFrameList1ShortTerm */
1635 if (priv->short_ref_count > 0) {
1636 ref_list = short_ref1;
1637 for (n = 0, i = 0; i < priv->short_ref_count; i++) {
1638 if (priv->short_ref[i]->base.poc > picture->base.poc)
1639 ref_list[n++] = priv->short_ref[i];
1641 SORT_REF_LIST(ref_list, n, poc_inc);
1642 short_ref1_count += n;
1644 ref_list = &short_ref1[short_ref1_count];
1645 for (n = 0, i = 0; i < priv->short_ref_count; i++) {
1646 if (priv->short_ref[i]->base.poc <= picture->base.poc)
1647 ref_list[n++] = priv->short_ref[i];
1649 SORT_REF_LIST(ref_list, n, poc_dec);
1650 short_ref1_count += n;
1653 /* refFrameListLongTerm */
1654 if (priv->long_ref_count > 0) {
1655 for (i = 0; i < priv->long_ref_count; i++)
1656 long_ref[i] = priv->long_ref[i];
1657 SORT_REF_LIST(long_ref, i, long_term_frame_idx_inc);
1661 init_picture_refs_fields(
1663 priv->RefPicList0, &priv->RefPicList0_count,
1664 short_ref0, short_ref0_count,
1665 long_ref, long_ref_count
1668 init_picture_refs_fields(
1670 priv->RefPicList1, &priv->RefPicList1_count,
1671 short_ref1, short_ref1_count,
1672 long_ref, long_ref_count
1676 /* Check whether RefPicList1 is identical to RefPicList0, then
1677 swap if necessary */
1678 if (priv->RefPicList1_count > 1 &&
1679 priv->RefPicList1_count == priv->RefPicList0_count &&
1680 memcmp(priv->RefPicList0, priv->RefPicList1,
1681 priv->RefPicList0_count * sizeof(priv->RefPicList0[0])) == 0) {
1682 GstVaapiPictureH264 * const tmp = priv->RefPicList1[0];
1683 priv->RefPicList1[0] = priv->RefPicList1[1];
1684 priv->RefPicList1[1] = tmp;
1688 #undef SORT_REF_LIST
1691 find_short_term_reference(GstVaapiDecoderH264 *decoder, gint32 pic_num)
1693 GstVaapiDecoderH264Private * const priv = decoder->priv;
1696 for (i = 0; i < priv->short_ref_count; i++) {
1697 if (priv->short_ref[i]->pic_num == pic_num)
1700 GST_ERROR("found no short-term reference picture with PicNum = %d",
1706 find_long_term_reference(GstVaapiDecoderH264 *decoder, gint32 long_term_pic_num)
1708 GstVaapiDecoderH264Private * const priv = decoder->priv;
1711 for (i = 0; i < priv->long_ref_count; i++) {
1712 if (priv->long_ref[i]->long_term_pic_num == long_term_pic_num)
1715 GST_ERROR("found no long-term reference picture with LongTermPicNum = %d",
1721 exec_picture_refs_modification_1(
1722 GstVaapiDecoderH264 *decoder,
1723 GstVaapiPictureH264 *picture,
1724 GstH264SliceHdr *slice_hdr,
1728 GstVaapiDecoderH264Private * const priv = decoder->priv;
1729 GstH264PPS * const pps = slice_hdr->pps;
1730 GstH264SPS * const sps = pps->sequence;
1731 GstH264RefPicListModification *ref_pic_list_modification;
1732 guint num_ref_pic_list_modifications;
1733 GstVaapiPictureH264 **ref_list;
1734 guint *ref_list_count_ptr, ref_list_count, ref_list_idx = 0;
1735 guint i, j, n, num_refs;
1737 gint32 MaxPicNum, CurrPicNum, picNumPred;
1739 GST_DEBUG("modification process of reference picture list %u", list);
1742 ref_pic_list_modification = slice_hdr->ref_pic_list_modification_l0;
1743 num_ref_pic_list_modifications = slice_hdr->n_ref_pic_list_modification_l0;
1744 ref_list = priv->RefPicList0;
1745 ref_list_count_ptr = &priv->RefPicList0_count;
1746 num_refs = slice_hdr->num_ref_idx_l0_active_minus1 + 1;
1749 ref_pic_list_modification = slice_hdr->ref_pic_list_modification_l1;
1750 num_ref_pic_list_modifications = slice_hdr->n_ref_pic_list_modification_l1;
1751 ref_list = priv->RefPicList1;
1752 ref_list_count_ptr = &priv->RefPicList1_count;
1753 num_refs = slice_hdr->num_ref_idx_l1_active_minus1 + 1;
1755 ref_list_count = *ref_list_count_ptr;
1757 if (!GST_VAAPI_PICTURE_IS_FRAME(picture)) {
1758 MaxPicNum = 1 << (sps->log2_max_frame_num_minus4 + 5); // 2 * MaxFrameNum
1759 CurrPicNum = 2 * slice_hdr->frame_num + 1; // 2 * frame_num + 1
1762 MaxPicNum = 1 << (sps->log2_max_frame_num_minus4 + 4); // MaxFrameNum
1763 CurrPicNum = slice_hdr->frame_num; // frame_num
1766 picNumPred = CurrPicNum;
1768 for (i = 0; i < num_ref_pic_list_modifications; i++) {
1769 GstH264RefPicListModification * const l = &ref_pic_list_modification[i];
1770 if (l->modification_of_pic_nums_idc == 3)
1773 /* 8.2.4.3.1 - Short-term reference pictures */
1774 if (l->modification_of_pic_nums_idc == 0 || l->modification_of_pic_nums_idc == 1) {
1775 gint32 abs_diff_pic_num = l->value.abs_diff_pic_num_minus1 + 1;
1776 gint32 picNum, picNumNoWrap;
1779 if (l->modification_of_pic_nums_idc == 0) {
1780 picNumNoWrap = picNumPred - abs_diff_pic_num;
1781 if (picNumNoWrap < 0)
1782 picNumNoWrap += MaxPicNum;
1787 picNumNoWrap = picNumPred + abs_diff_pic_num;
1788 if (picNumNoWrap >= MaxPicNum)
1789 picNumNoWrap -= MaxPicNum;
1791 picNumPred = picNumNoWrap;
1794 picNum = picNumNoWrap;
1795 if (picNum > CurrPicNum)
1796 picNum -= MaxPicNum;
1799 for (j = num_refs; j > ref_list_idx; j--)
1800 ref_list[j] = ref_list[j - 1];
1801 found_ref_idx = find_short_term_reference(decoder, picNum);
1802 ref_list[ref_list_idx++] =
1803 found_ref_idx >= 0 ? priv->short_ref[found_ref_idx] : NULL;
1805 for (j = ref_list_idx; j <= num_refs; j++) {
1810 GST_VAAPI_PICTURE_IS_SHORT_TERM_REFERENCE(ref_list[j]) ?
1811 ref_list[j]->pic_num : MaxPicNum;
1812 if (PicNumF != picNum)
1813 ref_list[n++] = ref_list[j];
1817 /* 8.2.4.3.2 - Long-term reference pictures */
1820 for (j = num_refs; j > ref_list_idx; j--)
1821 ref_list[j] = ref_list[j - 1];
1823 find_long_term_reference(decoder, l->value.long_term_pic_num);
1824 ref_list[ref_list_idx++] =
1825 found_ref_idx >= 0 ? priv->long_ref[found_ref_idx] : NULL;
1827 for (j = ref_list_idx; j <= num_refs; j++) {
1828 gint32 LongTermPicNumF;
1832 GST_VAAPI_PICTURE_IS_LONG_TERM_REFERENCE(ref_list[j]) ?
1833 ref_list[j]->long_term_pic_num : INT_MAX;
1834 if (LongTermPicNumF != l->value.long_term_pic_num)
1835 ref_list[n++] = ref_list[j];
1841 for (i = 0; i < num_refs; i++)
1843 GST_ERROR("list %u entry %u is empty", list, i);
1845 *ref_list_count_ptr = num_refs;
1848 /* 8.2.4.3 - Modification process for reference picture lists */
1850 exec_picture_refs_modification(
1851 GstVaapiDecoderH264 *decoder,
1852 GstVaapiPictureH264 *picture,
1853 GstH264SliceHdr *slice_hdr
1856 GST_DEBUG("execute ref_pic_list_modification()");
1859 if (!GST_H264_IS_I_SLICE(slice_hdr) && !GST_H264_IS_SI_SLICE(slice_hdr) &&
1860 slice_hdr->ref_pic_list_modification_flag_l0)
1861 exec_picture_refs_modification_1(decoder, picture, slice_hdr, 0);
1864 if (GST_H264_IS_B_SLICE(slice_hdr) &&
1865 slice_hdr->ref_pic_list_modification_flag_l1)
1866 exec_picture_refs_modification_1(decoder, picture, slice_hdr, 1);
1870 init_picture_ref_lists(GstVaapiDecoderH264 *decoder)
1872 GstVaapiDecoderH264Private * const priv = decoder->priv;
1873 guint i, j, short_ref_count, long_ref_count;
1875 short_ref_count = 0;
1877 if (GST_VAAPI_PICTURE_IS_FRAME(priv->current_picture)) {
1878 for (i = 0; i < priv->dpb_count; i++) {
1879 GstVaapiFrameStore * const fs = priv->dpb[i];
1880 GstVaapiPictureH264 *picture;
1881 if (!gst_vaapi_frame_store_has_frame(fs))
1883 picture = fs->buffers[0];
1884 if (GST_VAAPI_PICTURE_IS_SHORT_TERM_REFERENCE(picture))
1885 priv->short_ref[short_ref_count++] = picture;
1886 else if (GST_VAAPI_PICTURE_IS_LONG_TERM_REFERENCE(picture))
1887 priv->long_ref[long_ref_count++] = picture;
1888 picture->structure = GST_VAAPI_PICTURE_STRUCTURE_FRAME;
1889 picture->other_field = fs->buffers[1];
1893 for (i = 0; i < priv->dpb_count; i++) {
1894 GstVaapiFrameStore * const fs = priv->dpb[i];
1895 for (j = 0; j < fs->num_buffers; j++) {
1896 GstVaapiPictureH264 * const picture = fs->buffers[j];
1897 if (GST_VAAPI_PICTURE_IS_SHORT_TERM_REFERENCE(picture))
1898 priv->short_ref[short_ref_count++] = picture;
1899 else if (GST_VAAPI_PICTURE_IS_LONG_TERM_REFERENCE(picture))
1900 priv->long_ref[long_ref_count++] = picture;
1901 picture->structure = picture->base.structure;
1902 picture->other_field = fs->buffers[j ^ 1];
1907 for (i = short_ref_count; i < priv->short_ref_count; i++)
1908 priv->short_ref[i] = NULL;
1909 priv->short_ref_count = short_ref_count;
1911 for (i = long_ref_count; i < priv->long_ref_count; i++)
1912 priv->long_ref[i] = NULL;
1913 priv->long_ref_count = long_ref_count;
1918 GstVaapiDecoderH264 *decoder,
1919 GstVaapiPictureH264 *picture,
1920 GstH264SliceHdr *slice_hdr
1923 GstVaapiDecoderH264Private * const priv = decoder->priv;
1924 GstVaapiPicture * const base_picture = &picture->base;
1927 init_picture_ref_lists(decoder);
1928 init_picture_refs_pic_num(decoder, picture, slice_hdr);
1930 priv->RefPicList0_count = 0;
1931 priv->RefPicList1_count = 0;
1933 switch (base_picture->type) {
1934 case GST_VAAPI_PICTURE_TYPE_P:
1935 case GST_VAAPI_PICTURE_TYPE_SP:
1936 init_picture_refs_p_slice(decoder, picture, slice_hdr);
1938 case GST_VAAPI_PICTURE_TYPE_B:
1939 init_picture_refs_b_slice(decoder, picture, slice_hdr);
1945 exec_picture_refs_modification(decoder, picture, slice_hdr);
1947 switch (base_picture->type) {
1948 case GST_VAAPI_PICTURE_TYPE_B:
1949 num_refs = 1 + slice_hdr->num_ref_idx_l1_active_minus1;
1950 for (i = priv->RefPicList1_count; i < num_refs; i++)
1951 priv->RefPicList1[i] = NULL;
1952 priv->RefPicList1_count = num_refs;
1955 case GST_VAAPI_PICTURE_TYPE_P:
1956 case GST_VAAPI_PICTURE_TYPE_SP:
1957 num_refs = 1 + slice_hdr->num_ref_idx_l0_active_minus1;
1958 for (i = priv->RefPicList0_count; i < num_refs; i++)
1959 priv->RefPicList0[i] = NULL;
1960 priv->RefPicList0_count = num_refs;
1969 GstVaapiDecoderH264 *decoder,
1970 GstVaapiPictureH264 *picture, GstVaapiParserInfoH264 *pi)
1972 GstVaapiDecoderH264Private * const priv = decoder->priv;
1973 GstVaapiPicture * const base_picture = &picture->base;
1974 GstH264SliceHdr * const slice_hdr = &pi->data.slice_hdr;
1976 priv->prev_frame_num = priv->frame_num;
1977 priv->frame_num = slice_hdr->frame_num;
1978 picture->frame_num = priv->frame_num;
1979 picture->frame_num_wrap = priv->frame_num;
1980 picture->output_flag = TRUE; /* XXX: conformant to Annex A only */
1981 base_picture->pts = GST_VAAPI_DECODER_CODEC_FRAME(decoder)->pts;
1983 /* Reset decoder state for IDR pictures */
1984 if (pi->nalu.type == GST_H264_NAL_SLICE_IDR) {
1986 GST_VAAPI_PICTURE_FLAG_SET(picture, GST_VAAPI_PICTURE_FLAG_IDR);
1990 /* Initialize slice type */
1991 switch (slice_hdr->type % 5) {
1992 case GST_H264_P_SLICE:
1993 base_picture->type = GST_VAAPI_PICTURE_TYPE_P;
1995 case GST_H264_B_SLICE:
1996 base_picture->type = GST_VAAPI_PICTURE_TYPE_B;
1998 case GST_H264_I_SLICE:
1999 base_picture->type = GST_VAAPI_PICTURE_TYPE_I;
2001 case GST_H264_SP_SLICE:
2002 base_picture->type = GST_VAAPI_PICTURE_TYPE_SP;
2004 case GST_H264_SI_SLICE:
2005 base_picture->type = GST_VAAPI_PICTURE_TYPE_SI;
2009 /* Initialize picture structure */
2010 if (!slice_hdr->field_pic_flag)
2011 base_picture->structure = GST_VAAPI_PICTURE_STRUCTURE_FRAME;
2013 GST_VAAPI_PICTURE_FLAG_SET(picture, GST_VAAPI_PICTURE_FLAG_INTERLACED);
2014 if (!slice_hdr->bottom_field_flag)
2015 base_picture->structure = GST_VAAPI_PICTURE_STRUCTURE_TOP_FIELD;
2017 base_picture->structure = GST_VAAPI_PICTURE_STRUCTURE_BOTTOM_FIELD;
2019 picture->structure = base_picture->structure;
2021 /* Initialize reference flags */
2022 if (pi->nalu.ref_idc) {
2023 GstH264DecRefPicMarking * const dec_ref_pic_marking =
2024 &slice_hdr->dec_ref_pic_marking;
2026 if (GST_VAAPI_PICTURE_IS_IDR(picture) &&
2027 dec_ref_pic_marking->long_term_reference_flag)
2028 GST_VAAPI_PICTURE_FLAG_SET(picture,
2029 GST_VAAPI_PICTURE_FLAG_LONG_TERM_REFERENCE);
2031 GST_VAAPI_PICTURE_FLAG_SET(picture,
2032 GST_VAAPI_PICTURE_FLAG_SHORT_TERM_REFERENCE);
2035 init_picture_poc(decoder, picture, slice_hdr);
2036 init_picture_refs(decoder, picture, slice_hdr);
2040 /* 8.2.5.3 - Sliding window decoded reference picture marking process */
2042 exec_ref_pic_marking_sliding_window(GstVaapiDecoderH264 *decoder)
2044 GstVaapiDecoderH264Private * const priv = decoder->priv;
2045 GstH264PPS * const pps = priv->current_picture->pps;
2046 GstH264SPS * const sps = pps->sequence;
2047 GstVaapiPictureH264 *ref_picture;
2048 guint i, m, max_num_ref_frames;
2050 GST_DEBUG("reference picture marking process (sliding window)");
2052 if (!GST_VAAPI_PICTURE_IS_FIRST_FIELD(priv->current_picture))
2055 max_num_ref_frames = sps->num_ref_frames;
2056 if (max_num_ref_frames == 0)
2057 max_num_ref_frames = 1;
2058 if (!GST_VAAPI_PICTURE_IS_FRAME(priv->current_picture))
2059 max_num_ref_frames <<= 1;
2061 if (priv->short_ref_count + priv->long_ref_count < max_num_ref_frames)
2063 if (priv->short_ref_count < 1)
2066 for (m = 0, i = 1; i < priv->short_ref_count; i++) {
2067 GstVaapiPictureH264 * const picture = priv->short_ref[i];
2068 if (picture->frame_num_wrap < priv->short_ref[m]->frame_num_wrap)
2072 ref_picture = priv->short_ref[m];
2073 gst_vaapi_picture_h264_set_reference(ref_picture, 0, TRUE);
2074 ARRAY_REMOVE_INDEX(priv->short_ref, m);
2076 /* Both fields need to be marked as "unused for reference", so
2077 remove the other field from the short_ref[] list as well */
2078 if (!GST_VAAPI_PICTURE_IS_FRAME(priv->current_picture) && ref_picture->other_field) {
2079 for (i = 0; i < priv->short_ref_count; i++) {
2080 if (priv->short_ref[i] == ref_picture->other_field) {
2081 ARRAY_REMOVE_INDEX(priv->short_ref, i);
2089 static inline gint32
2090 get_picNumX(GstVaapiPictureH264 *picture, GstH264RefPicMarking *ref_pic_marking)
2094 if (GST_VAAPI_PICTURE_IS_FRAME(picture))
2095 pic_num = picture->frame_num_wrap;
2097 pic_num = 2 * picture->frame_num_wrap + 1;
2098 pic_num -= ref_pic_marking->difference_of_pic_nums_minus1 + 1;
2102 /* 8.2.5.4.1. Mark short-term reference picture as "unused for reference" */
2104 exec_ref_pic_marking_adaptive_mmco_1(
2105 GstVaapiDecoderH264 *decoder,
2106 GstVaapiPictureH264 *picture,
2107 GstH264RefPicMarking *ref_pic_marking
2110 GstVaapiDecoderH264Private * const priv = decoder->priv;
2113 picNumX = get_picNumX(picture, ref_pic_marking);
2114 i = find_short_term_reference(decoder, picNumX);
2118 gst_vaapi_picture_h264_set_reference(priv->short_ref[i], 0,
2119 GST_VAAPI_PICTURE_IS_FRAME(picture));
2120 ARRAY_REMOVE_INDEX(priv->short_ref, i);
2123 /* 8.2.5.4.2. Mark long-term reference picture as "unused for reference" */
2125 exec_ref_pic_marking_adaptive_mmco_2(
2126 GstVaapiDecoderH264 *decoder,
2127 GstVaapiPictureH264 *picture,
2128 GstH264RefPicMarking *ref_pic_marking
2131 GstVaapiDecoderH264Private * const priv = decoder->priv;
2134 i = find_long_term_reference(decoder, ref_pic_marking->long_term_pic_num);
2138 gst_vaapi_picture_h264_set_reference(priv->long_ref[i], 0,
2139 GST_VAAPI_PICTURE_IS_FRAME(picture));
2140 ARRAY_REMOVE_INDEX(priv->long_ref, i);
2143 /* 8.2.5.4.3. Assign LongTermFrameIdx to a short-term reference picture */
2145 exec_ref_pic_marking_adaptive_mmco_3(
2146 GstVaapiDecoderH264 *decoder,
2147 GstVaapiPictureH264 *picture,
2148 GstH264RefPicMarking *ref_pic_marking
2151 GstVaapiDecoderH264Private * const priv = decoder->priv;
2152 GstVaapiPictureH264 *ref_picture;
2155 for (i = 0; i < priv->long_ref_count; i++) {
2156 if (priv->long_ref[i]->long_term_frame_idx == ref_pic_marking->long_term_frame_idx)
2159 if (i != priv->long_ref_count) {
2160 gst_vaapi_picture_h264_set_reference(priv->long_ref[i], 0, TRUE);
2161 ARRAY_REMOVE_INDEX(priv->long_ref, i);
2164 picNumX = get_picNumX(picture, ref_pic_marking);
2165 i = find_short_term_reference(decoder, picNumX);
2169 ref_picture = priv->short_ref[i];
2170 ARRAY_REMOVE_INDEX(priv->short_ref, i);
2171 priv->long_ref[priv->long_ref_count++] = ref_picture;
2173 ref_picture->long_term_frame_idx = ref_pic_marking->long_term_frame_idx;
2174 gst_vaapi_picture_h264_set_reference(ref_picture,
2175 GST_VAAPI_PICTURE_FLAG_LONG_TERM_REFERENCE,
2176 GST_VAAPI_PICTURE_IS_FRAME(picture));
2179 /* 8.2.5.4.4. Mark pictures with LongTermFramIdx > max_long_term_frame_idx
2180 * as "unused for reference" */
2182 exec_ref_pic_marking_adaptive_mmco_4(
2183 GstVaapiDecoderH264 *decoder,
2184 GstVaapiPictureH264 *picture,
2185 GstH264RefPicMarking *ref_pic_marking
2188 GstVaapiDecoderH264Private * const priv = decoder->priv;
2189 gint32 i, long_term_frame_idx;
2191 long_term_frame_idx = ref_pic_marking->max_long_term_frame_idx_plus1 - 1;
2193 for (i = 0; i < priv->long_ref_count; i++) {
2194 if (priv->long_ref[i]->long_term_frame_idx <= long_term_frame_idx)
2196 gst_vaapi_picture_h264_set_reference(priv->long_ref[i], 0, FALSE);
2197 ARRAY_REMOVE_INDEX(priv->long_ref, i);
2202 /* 8.2.5.4.5. Mark all reference pictures as "unused for reference" */
2204 exec_ref_pic_marking_adaptive_mmco_5(
2205 GstVaapiDecoderH264 *decoder,
2206 GstVaapiPictureH264 *picture,
2207 GstH264RefPicMarking *ref_pic_marking
2210 GstVaapiDecoderH264Private * const priv = decoder->priv;
2214 priv->prev_pic_has_mmco5 = TRUE;
2216 /* The picture shall be inferred to have had frame_num equal to 0 (7.4.3) */
2217 priv->frame_num = 0;
2218 priv->frame_num_offset = 0;
2219 picture->frame_num = 0;
2221 /* Update TopFieldOrderCnt and BottomFieldOrderCnt (8.2.1) */
2222 if (picture->structure != GST_VAAPI_PICTURE_STRUCTURE_BOTTOM_FIELD)
2223 picture->field_poc[TOP_FIELD] -= picture->base.poc;
2224 if (picture->structure != GST_VAAPI_PICTURE_STRUCTURE_TOP_FIELD)
2225 picture->field_poc[BOTTOM_FIELD] -= picture->base.poc;
2226 picture->base.poc = 0;
2229 /* 8.2.5.4.6. Assign a long-term frame index to the current picture */
2231 exec_ref_pic_marking_adaptive_mmco_6(
2232 GstVaapiDecoderH264 *decoder,
2233 GstVaapiPictureH264 *picture,
2234 GstH264RefPicMarking *ref_pic_marking
2237 picture->long_term_frame_idx = ref_pic_marking->long_term_frame_idx;
2238 gst_vaapi_picture_h264_set_reference(picture,
2239 GST_VAAPI_PICTURE_FLAG_LONG_TERM_REFERENCE, FALSE);
2242 /* 8.2.5.4. Adaptive memory control decoded reference picture marking process */
2244 exec_ref_pic_marking_adaptive(
2245 GstVaapiDecoderH264 *decoder,
2246 GstVaapiPictureH264 *picture,
2247 GstH264DecRefPicMarking *dec_ref_pic_marking
2252 GST_DEBUG("reference picture marking process (adaptive memory control)");
2254 typedef void (*exec_ref_pic_marking_adaptive_mmco_func)(
2255 GstVaapiDecoderH264 *decoder,
2256 GstVaapiPictureH264 *picture,
2257 GstH264RefPicMarking *ref_pic_marking
2260 static const exec_ref_pic_marking_adaptive_mmco_func mmco_funcs[] = {
2262 exec_ref_pic_marking_adaptive_mmco_1,
2263 exec_ref_pic_marking_adaptive_mmco_2,
2264 exec_ref_pic_marking_adaptive_mmco_3,
2265 exec_ref_pic_marking_adaptive_mmco_4,
2266 exec_ref_pic_marking_adaptive_mmco_5,
2267 exec_ref_pic_marking_adaptive_mmco_6,
2270 for (i = 0; i < dec_ref_pic_marking->n_ref_pic_marking; i++) {
2271 GstH264RefPicMarking * const ref_pic_marking =
2272 &dec_ref_pic_marking->ref_pic_marking[i];
2274 const guint mmco = ref_pic_marking->memory_management_control_operation;
2275 if (mmco < G_N_ELEMENTS(mmco_funcs) && mmco_funcs[mmco])
2276 mmco_funcs[mmco](decoder, picture, ref_pic_marking);
2278 GST_ERROR("unhandled MMCO %u", mmco);
2285 /* 8.2.5 - Execute reference picture marking process */
2287 exec_ref_pic_marking(GstVaapiDecoderH264 *decoder, GstVaapiPictureH264 *picture)
2289 GstVaapiDecoderH264Private * const priv = decoder->priv;
2291 priv->prev_pic_has_mmco5 = FALSE;
2292 priv->prev_pic_structure = picture->structure;
2294 if (!GST_VAAPI_PICTURE_IS_REFERENCE(picture))
2297 if (!GST_VAAPI_PICTURE_IS_IDR(picture)) {
2298 GstH264DecRefPicMarking * const dec_ref_pic_marking =
2299 &picture->last_slice_hdr->dec_ref_pic_marking;
2300 if (dec_ref_pic_marking->adaptive_ref_pic_marking_mode_flag) {
2301 if (!exec_ref_pic_marking_adaptive(decoder, picture, dec_ref_pic_marking))
2305 if (!exec_ref_pic_marking_sliding_window(decoder))
2313 vaapi_init_picture(VAPictureH264 *pic)
2315 pic->picture_id = VA_INVALID_ID;
2317 pic->flags = VA_PICTURE_H264_INVALID;
2318 pic->TopFieldOrderCnt = 0;
2319 pic->BottomFieldOrderCnt = 0;
2323 vaapi_fill_picture(VAPictureH264 *pic, GstVaapiPictureH264 *picture,
2324 guint picture_structure)
2326 if (!picture_structure)
2327 picture_structure = picture->structure;
2329 pic->picture_id = picture->base.surface_id;
2332 if (GST_VAAPI_PICTURE_IS_LONG_TERM_REFERENCE(picture)) {
2333 pic->flags |= VA_PICTURE_H264_LONG_TERM_REFERENCE;
2334 pic->frame_idx = picture->long_term_frame_idx;
2337 if (GST_VAAPI_PICTURE_IS_SHORT_TERM_REFERENCE(picture))
2338 pic->flags |= VA_PICTURE_H264_SHORT_TERM_REFERENCE;
2339 pic->frame_idx = picture->frame_num;
2342 switch (picture_structure) {
2343 case GST_VAAPI_PICTURE_STRUCTURE_FRAME:
2344 pic->TopFieldOrderCnt = picture->field_poc[TOP_FIELD];
2345 pic->BottomFieldOrderCnt = picture->field_poc[BOTTOM_FIELD];
2347 case GST_VAAPI_PICTURE_STRUCTURE_TOP_FIELD:
2348 pic->flags |= VA_PICTURE_H264_TOP_FIELD;
2349 pic->TopFieldOrderCnt = picture->field_poc[TOP_FIELD];
2350 pic->BottomFieldOrderCnt = 0;
2352 case GST_VAAPI_PICTURE_STRUCTURE_BOTTOM_FIELD:
2353 pic->flags |= VA_PICTURE_H264_BOTTOM_FIELD;
2354 pic->BottomFieldOrderCnt = picture->field_poc[BOTTOM_FIELD];
2355 pic->TopFieldOrderCnt = 0;
2361 fill_picture(GstVaapiDecoderH264 *decoder,
2362 GstVaapiPictureH264 *picture, GstVaapiParserInfoH264 *pi)
2364 GstVaapiDecoderH264Private * const priv = decoder->priv;
2365 GstVaapiPicture * const base_picture = &picture->base;
2366 GstH264SliceHdr * const slice_hdr = &pi->data.slice_hdr;
2367 GstH264PPS * const pps = picture->pps;
2368 GstH264SPS * const sps = pps->sequence;
2369 VAPictureParameterBufferH264 * const pic_param = base_picture->param;
2372 /* Fill in VAPictureParameterBufferH264 */
2373 vaapi_fill_picture(&pic_param->CurrPic, picture, 0);
2375 for (i = 0, n = 0; i < priv->dpb_count; i++) {
2376 GstVaapiFrameStore * const fs = priv->dpb[i];
2377 if (gst_vaapi_frame_store_has_reference(fs))
2378 vaapi_fill_picture(&pic_param->ReferenceFrames[n++],
2379 fs->buffers[0], fs->structure);
2381 for (; n < G_N_ELEMENTS(pic_param->ReferenceFrames); n++)
2382 vaapi_init_picture(&pic_param->ReferenceFrames[n]);
2384 #define COPY_FIELD(s, f) \
2385 pic_param->f = (s)->f
2387 #define COPY_BFM(a, s, f) \
2388 pic_param->a.bits.f = (s)->f
2390 pic_param->picture_width_in_mbs_minus1 = priv->mb_width - 1;
2391 pic_param->picture_height_in_mbs_minus1 = priv->mb_height - 1;
2392 pic_param->frame_num = priv->frame_num;
2394 COPY_FIELD(sps, bit_depth_luma_minus8);
2395 COPY_FIELD(sps, bit_depth_chroma_minus8);
2396 COPY_FIELD(sps, num_ref_frames);
2397 COPY_FIELD(pps, num_slice_groups_minus1);
2398 COPY_FIELD(pps, slice_group_map_type);
2399 COPY_FIELD(pps, slice_group_change_rate_minus1);
2400 COPY_FIELD(pps, pic_init_qp_minus26);
2401 COPY_FIELD(pps, pic_init_qs_minus26);
2402 COPY_FIELD(pps, chroma_qp_index_offset);
2403 COPY_FIELD(pps, second_chroma_qp_index_offset);
2405 pic_param->seq_fields.value = 0; /* reset all bits */
2406 pic_param->seq_fields.bits.residual_colour_transform_flag = sps->separate_colour_plane_flag;
2407 pic_param->seq_fields.bits.MinLumaBiPredSize8x8 = sps->level_idc >= 31; /* A.3.3.2 */
2409 COPY_BFM(seq_fields, sps, chroma_format_idc);
2410 COPY_BFM(seq_fields, sps, gaps_in_frame_num_value_allowed_flag);
2411 COPY_BFM(seq_fields, sps, frame_mbs_only_flag);
2412 COPY_BFM(seq_fields, sps, mb_adaptive_frame_field_flag);
2413 COPY_BFM(seq_fields, sps, direct_8x8_inference_flag);
2414 COPY_BFM(seq_fields, sps, log2_max_frame_num_minus4);
2415 COPY_BFM(seq_fields, sps, pic_order_cnt_type);
2416 COPY_BFM(seq_fields, sps, log2_max_pic_order_cnt_lsb_minus4);
2417 COPY_BFM(seq_fields, sps, delta_pic_order_always_zero_flag);
2419 pic_param->pic_fields.value = 0; /* reset all bits */
2420 pic_param->pic_fields.bits.field_pic_flag = slice_hdr->field_pic_flag;
2421 pic_param->pic_fields.bits.reference_pic_flag = GST_VAAPI_PICTURE_IS_REFERENCE(picture);
2423 COPY_BFM(pic_fields, pps, entropy_coding_mode_flag);
2424 COPY_BFM(pic_fields, pps, weighted_pred_flag);
2425 COPY_BFM(pic_fields, pps, weighted_bipred_idc);
2426 COPY_BFM(pic_fields, pps, transform_8x8_mode_flag);
2427 COPY_BFM(pic_fields, pps, constrained_intra_pred_flag);
2428 COPY_BFM(pic_fields, pps, pic_order_present_flag);
2429 COPY_BFM(pic_fields, pps, deblocking_filter_control_present_flag);
2430 COPY_BFM(pic_fields, pps, redundant_pic_cnt_present_flag);
2434 /* Detection of the first VCL NAL unit of a primary coded picture (7.4.1.2.4) */
2436 is_new_picture(GstVaapiParserInfoH264 *pi, GstVaapiParserInfoH264 *prev_pi)
2438 GstH264SliceHdr * const slice_hdr = &pi->data.slice_hdr;
2439 GstH264PPS * const pps = slice_hdr->pps;
2440 GstH264SPS * const sps = pps->sequence;
2441 GstH264SliceHdr *prev_slice_hdr;
2445 prev_slice_hdr = &prev_pi->data.slice_hdr;
2447 #define CHECK_EXPR(expr, field_name) do { \
2449 GST_DEBUG(field_name " differs in value"); \
2454 #define CHECK_VALUE(new_slice_hdr, old_slice_hdr, field) \
2455 CHECK_EXPR(((new_slice_hdr)->field == (old_slice_hdr)->field), #field)
2457 /* frame_num differs in value, regardless of inferred values to 0 */
2458 CHECK_VALUE(slice_hdr, prev_slice_hdr, frame_num);
2460 /* pic_parameter_set_id differs in value */
2461 CHECK_VALUE(slice_hdr, prev_slice_hdr, pps);
2463 /* field_pic_flag differs in value */
2464 CHECK_VALUE(slice_hdr, prev_slice_hdr, field_pic_flag);
2466 /* bottom_field_flag is present in both and differs in value */
2467 if (slice_hdr->field_pic_flag && prev_slice_hdr->field_pic_flag)
2468 CHECK_VALUE(slice_hdr, prev_slice_hdr, bottom_field_flag);
2470 /* nal_ref_idc differs in value with one of the nal_ref_idc values is 0 */
2471 CHECK_EXPR((pi->nalu.ref_idc != 0) ==
2472 (prev_pi->nalu.ref_idc != 0), "nal_ref_idc");
2474 /* POC type is 0 for both and either pic_order_cnt_lsb differs in
2475 value or delta_pic_order_cnt_bottom differs in value */
2476 if (sps->pic_order_cnt_type == 0) {
2477 CHECK_VALUE(slice_hdr, prev_slice_hdr, pic_order_cnt_lsb);
2478 if (pps->pic_order_present_flag && !slice_hdr->field_pic_flag)
2479 CHECK_VALUE(slice_hdr, prev_slice_hdr, delta_pic_order_cnt_bottom);
2482 /* POC type is 1 for both and either delta_pic_order_cnt[0]
2483 differs in value or delta_pic_order_cnt[1] differs in value */
2484 else if (sps->pic_order_cnt_type == 1) {
2485 CHECK_VALUE(slice_hdr, prev_slice_hdr, delta_pic_order_cnt[0]);
2486 CHECK_VALUE(slice_hdr, prev_slice_hdr, delta_pic_order_cnt[1]);
2489 /* IdrPicFlag differs in value */
2490 CHECK_VALUE(&pi->nalu, &prev_pi->nalu, idr_pic_flag);
2492 /* IdrPicFlag is equal to 1 for both and idr_pic_id differs in value */
2493 if (pi->nalu.idr_pic_flag)
2494 CHECK_VALUE(slice_hdr, prev_slice_hdr, idr_pic_id);
2501 static GstVaapiDecoderStatus
2502 decode_picture(GstVaapiDecoderH264 *decoder, GstVaapiDecoderUnit *unit)
2504 GstVaapiDecoderH264Private * const priv = decoder->priv;
2505 GstVaapiParserInfoH264 * const pi = unit->parsed_info;
2506 GstH264SliceHdr * const slice_hdr = &pi->data.slice_hdr;
2507 GstH264PPS * const pps = slice_hdr->pps;
2508 GstH264SPS * const sps = pps->sequence;
2509 GstVaapiPictureH264 *picture;
2510 GstVaapiDecoderStatus status;
2512 status = ensure_context(decoder, sps);
2513 if (status != GST_VAAPI_DECODER_STATUS_SUCCESS)
2516 if (priv->current_picture) {
2517 /* Re-use current picture where the first field was decoded */
2518 picture = gst_vaapi_picture_h264_new_field(priv->current_picture);
2520 GST_ERROR("failed to allocate field picture");
2521 return GST_VAAPI_DECODER_STATUS_ERROR_ALLOCATION_FAILED;
2525 /* Create new picture */
2526 picture = gst_vaapi_picture_h264_new(decoder);
2528 GST_ERROR("failed to allocate picture");
2529 return GST_VAAPI_DECODER_STATUS_ERROR_ALLOCATION_FAILED;
2532 gst_vaapi_picture_replace(&priv->current_picture, picture);
2533 gst_vaapi_picture_unref(picture);
2537 status = ensure_quant_matrix(decoder, picture);
2538 if (status != GST_VAAPI_DECODER_STATUS_SUCCESS) {
2539 GST_ERROR("failed to reset quantizer matrix");
2543 if (!init_picture(decoder, picture, pi))
2544 return GST_VAAPI_DECODER_STATUS_ERROR_UNKNOWN;
2545 if (!fill_picture(decoder, picture, pi))
2546 return GST_VAAPI_DECODER_STATUS_ERROR_UNKNOWN;
2547 return GST_VAAPI_DECODER_STATUS_SUCCESS;
2551 get_slice_data_bit_offset(GstH264SliceHdr *slice_hdr)
2555 epb_count = slice_hdr->n_emulation_prevention_bytes;
2556 return 8 /* nal_unit_type */ + slice_hdr->header_size - epb_count * 8;
2560 fill_pred_weight_table(GstVaapiDecoderH264 *decoder,
2561 GstVaapiSlice *slice, GstH264SliceHdr *slice_hdr)
2563 VASliceParameterBufferH264 * const slice_param = slice->param;
2564 GstH264PPS * const pps = slice_hdr->pps;
2565 GstH264SPS * const sps = pps->sequence;
2566 GstH264PredWeightTable * const w = &slice_hdr->pred_weight_table;
2567 guint num_weight_tables = 0;
2570 if (pps->weighted_pred_flag &&
2571 (GST_H264_IS_P_SLICE(slice_hdr) || GST_H264_IS_SP_SLICE(slice_hdr)))
2572 num_weight_tables = 1;
2573 else if (pps->weighted_bipred_idc == 1 && GST_H264_IS_B_SLICE(slice_hdr))
2574 num_weight_tables = 2;
2576 num_weight_tables = 0;
2578 slice_param->luma_log2_weight_denom = 0;
2579 slice_param->chroma_log2_weight_denom = 0;
2580 slice_param->luma_weight_l0_flag = 0;
2581 slice_param->chroma_weight_l0_flag = 0;
2582 slice_param->luma_weight_l1_flag = 0;
2583 slice_param->chroma_weight_l1_flag = 0;
2585 if (num_weight_tables < 1)
2588 slice_param->luma_log2_weight_denom = w->luma_log2_weight_denom;
2589 slice_param->chroma_log2_weight_denom = w->chroma_log2_weight_denom;
2591 slice_param->luma_weight_l0_flag = 1;
2592 for (i = 0; i <= slice_param->num_ref_idx_l0_active_minus1; i++) {
2593 slice_param->luma_weight_l0[i] = w->luma_weight_l0[i];
2594 slice_param->luma_offset_l0[i] = w->luma_offset_l0[i];
2597 slice_param->chroma_weight_l0_flag = sps->chroma_array_type != 0;
2598 if (slice_param->chroma_weight_l0_flag) {
2599 for (i = 0; i <= slice_param->num_ref_idx_l0_active_minus1; i++) {
2600 for (j = 0; j < 2; j++) {
2601 slice_param->chroma_weight_l0[i][j] = w->chroma_weight_l0[i][j];
2602 slice_param->chroma_offset_l0[i][j] = w->chroma_offset_l0[i][j];
2607 if (num_weight_tables < 2)
2610 slice_param->luma_weight_l1_flag = 1;
2611 for (i = 0; i <= slice_param->num_ref_idx_l1_active_minus1; i++) {
2612 slice_param->luma_weight_l1[i] = w->luma_weight_l1[i];
2613 slice_param->luma_offset_l1[i] = w->luma_offset_l1[i];
2616 slice_param->chroma_weight_l1_flag = sps->chroma_array_type != 0;
2617 if (slice_param->chroma_weight_l1_flag) {
2618 for (i = 0; i <= slice_param->num_ref_idx_l1_active_minus1; i++) {
2619 for (j = 0; j < 2; j++) {
2620 slice_param->chroma_weight_l1[i][j] = w->chroma_weight_l1[i][j];
2621 slice_param->chroma_offset_l1[i][j] = w->chroma_offset_l1[i][j];
2629 fill_RefPicList(GstVaapiDecoderH264 *decoder,
2630 GstVaapiSlice *slice, GstH264SliceHdr *slice_hdr)
2632 GstVaapiDecoderH264Private * const priv = decoder->priv;
2633 VASliceParameterBufferH264 * const slice_param = slice->param;
2634 guint i, num_ref_lists = 0;
2636 slice_param->num_ref_idx_l0_active_minus1 = 0;
2637 slice_param->num_ref_idx_l1_active_minus1 = 0;
2639 if (GST_H264_IS_B_SLICE(slice_hdr))
2641 else if (GST_H264_IS_I_SLICE(slice_hdr))
2646 if (num_ref_lists < 1)
2649 slice_param->num_ref_idx_l0_active_minus1 =
2650 slice_hdr->num_ref_idx_l0_active_minus1;
2652 for (i = 0; i < priv->RefPicList0_count && priv->RefPicList0[i]; i++)
2653 vaapi_fill_picture(&slice_param->RefPicList0[i], priv->RefPicList0[i], 0);
2654 for (; i <= slice_param->num_ref_idx_l0_active_minus1; i++)
2655 vaapi_init_picture(&slice_param->RefPicList0[i]);
2657 if (num_ref_lists < 2)
2660 slice_param->num_ref_idx_l1_active_minus1 =
2661 slice_hdr->num_ref_idx_l1_active_minus1;
2663 for (i = 0; i < priv->RefPicList1_count && priv->RefPicList1[i]; i++)
2664 vaapi_fill_picture(&slice_param->RefPicList1[i], priv->RefPicList1[i], 0);
2665 for (; i <= slice_param->num_ref_idx_l1_active_minus1; i++)
2666 vaapi_init_picture(&slice_param->RefPicList1[i]);
2671 fill_slice(GstVaapiDecoderH264 *decoder,
2672 GstVaapiSlice *slice, GstH264SliceHdr *slice_hdr)
2674 VASliceParameterBufferH264 * const slice_param = slice->param;
2676 /* Fill in VASliceParameterBufferH264 */
2677 slice_param->slice_data_bit_offset = get_slice_data_bit_offset(slice_hdr);
2678 slice_param->first_mb_in_slice = slice_hdr->first_mb_in_slice;
2679 slice_param->slice_type = slice_hdr->type % 5;
2680 slice_param->direct_spatial_mv_pred_flag = slice_hdr->direct_spatial_mv_pred_flag;
2681 slice_param->cabac_init_idc = slice_hdr->cabac_init_idc;
2682 slice_param->slice_qp_delta = slice_hdr->slice_qp_delta;
2683 slice_param->disable_deblocking_filter_idc = slice_hdr->disable_deblocking_filter_idc;
2684 slice_param->slice_alpha_c0_offset_div2 = slice_hdr->slice_alpha_c0_offset_div2;
2685 slice_param->slice_beta_offset_div2 = slice_hdr->slice_beta_offset_div2;
2687 if (!fill_RefPicList(decoder, slice, slice_hdr))
2689 if (!fill_pred_weight_table(decoder, slice, slice_hdr))
2694 static GstVaapiDecoderStatus
2695 decode_slice(GstVaapiDecoderH264 *decoder, GstVaapiDecoderUnit *unit)
2697 GstVaapiDecoderH264Private * const priv = decoder->priv;
2698 GstVaapiParserInfoH264 * const pi = unit->parsed_info;
2699 GstVaapiPictureH264 * const picture = priv->current_picture;
2700 GstH264SliceHdr * const slice_hdr = &pi->data.slice_hdr;
2701 GstVaapiSlice *slice;
2702 GstBuffer * const buffer =
2703 GST_VAAPI_DECODER_CODEC_FRAME(decoder)->input_buffer;
2704 GstMapInfo map_info;
2706 GST_DEBUG("slice (%u bytes)", pi->nalu.size);
2708 if (!priv->got_sps || !priv->got_pps) {
2709 GST_ERROR("not initialized yet");
2710 return GST_VAAPI_DECODER_STATUS_SUCCESS;
2713 if (!gst_buffer_map(buffer, &map_info, GST_MAP_READ)) {
2714 GST_ERROR("failed to map buffer");
2715 return GST_VAAPI_DECODER_STATUS_ERROR_UNKNOWN;
2718 slice = GST_VAAPI_SLICE_NEW(H264, decoder,
2719 (map_info.data + unit->offset + pi->nalu.offset), pi->nalu.size);
2720 gst_buffer_unmap(buffer, &map_info);
2722 GST_ERROR("failed to allocate slice");
2723 return GST_VAAPI_DECODER_STATUS_ERROR_ALLOCATION_FAILED;
2726 if (!fill_slice(decoder, slice, slice_hdr)) {
2727 gst_vaapi_mini_object_unref(GST_VAAPI_MINI_OBJECT(slice));
2728 return GST_VAAPI_DECODER_STATUS_ERROR_UNKNOWN;
2731 gst_vaapi_picture_add_slice(GST_VAAPI_PICTURE_CAST(picture), slice);
2732 picture->last_slice_hdr = slice_hdr;
2733 return GST_VAAPI_DECODER_STATUS_SUCCESS;
2737 scan_for_start_code(GstAdapter *adapter, guint ofs, guint size, guint32 *scp)
2739 return (gint)gst_adapter_masked_scan_uint32_peek(adapter,
2740 0xffffff00, 0x00000100,
2745 static GstVaapiDecoderStatus
2746 decode_unit(GstVaapiDecoderH264 *decoder, GstVaapiDecoderUnit *unit)
2748 GstVaapiParserInfoH264 * const pi = unit->parsed_info;
2749 GstVaapiDecoderStatus status;
2751 switch (pi->nalu.type) {
2752 case GST_H264_NAL_SLICE_IDR:
2753 /* fall-through. IDR specifics are handled in init_picture() */
2754 case GST_H264_NAL_SLICE:
2755 status = decode_slice(decoder, unit);
2757 case GST_H264_NAL_SEQ_END:
2758 case GST_H264_NAL_STREAM_END:
2759 status = decode_sequence_end(decoder);
2761 case GST_H264_NAL_SEI:
2762 status = GST_VAAPI_DECODER_STATUS_SUCCESS;
2765 GST_WARNING("unsupported NAL unit type %d", pi->nalu.type);
2766 status = GST_VAAPI_DECODER_STATUS_ERROR_BITSTREAM_PARSER;
2772 static GstVaapiDecoderStatus
2773 gst_vaapi_decoder_h264_decode_codec_data(GstVaapiDecoder *base_decoder,
2774 const guchar *buf, guint buf_size)
2776 GstVaapiDecoderH264 * const decoder =
2777 GST_VAAPI_DECODER_H264_CAST(base_decoder);
2778 GstVaapiDecoderH264Private * const priv = decoder->priv;
2779 GstVaapiDecoderStatus status;
2780 GstVaapiDecoderUnit unit;
2781 GstVaapiParserInfoH264 pi;
2782 GstH264ParserResult result;
2783 guint i, ofs, num_sps, num_pps;
2785 unit.parsed_info = π
2788 return GST_VAAPI_DECODER_STATUS_ERROR_NO_DATA;
2791 GST_ERROR("failed to decode codec-data, not in avcC format");
2792 return GST_VAAPI_DECODER_STATUS_ERROR_BITSTREAM_PARSER;
2795 priv->nal_length_size = (buf[4] & 0x03) + 1;
2797 num_sps = buf[5] & 0x1f;
2800 for (i = 0; i < num_sps; i++) {
2801 result = gst_h264_parser_identify_nalu_avc(
2803 buf, ofs, buf_size, 2,
2806 if (result != GST_H264_PARSER_OK)
2807 return get_status(result);
2809 status = parse_sps(decoder, &unit);
2810 if (status != GST_VAAPI_DECODER_STATUS_SUCCESS)
2812 ofs = pi.nalu.offset + pi.nalu.size;
2818 for (i = 0; i < num_pps; i++) {
2819 result = gst_h264_parser_identify_nalu_avc(
2821 buf, ofs, buf_size, 2,
2824 if (result != GST_H264_PARSER_OK)
2825 return get_status(result);
2827 status = parse_pps(decoder, &unit);
2828 if (status != GST_VAAPI_DECODER_STATUS_SUCCESS)
2830 ofs = pi.nalu.offset + pi.nalu.size;
2833 priv->is_avcC = TRUE;
2834 return GST_VAAPI_DECODER_STATUS_SUCCESS;
2837 static GstVaapiDecoderStatus
2838 ensure_decoder(GstVaapiDecoderH264 *decoder)
2840 GstVaapiDecoderH264Private * const priv = decoder->priv;
2841 GstVaapiDecoderStatus status;
2843 g_return_val_if_fail(priv->is_constructed,
2844 GST_VAAPI_DECODER_STATUS_ERROR_INIT_FAILED);
2846 if (!priv->is_opened) {
2847 priv->is_opened = gst_vaapi_decoder_h264_open(decoder);
2848 if (!priv->is_opened)
2849 return GST_VAAPI_DECODER_STATUS_ERROR_UNSUPPORTED_CODEC;
2851 status = gst_vaapi_decoder_decode_codec_data(
2852 GST_VAAPI_DECODER_CAST(decoder));
2853 if (status != GST_VAAPI_DECODER_STATUS_SUCCESS)
2856 return GST_VAAPI_DECODER_STATUS_SUCCESS;
2859 static GstVaapiDecoderStatus
2860 gst_vaapi_decoder_h264_parse(GstVaapiDecoder *base_decoder,
2861 GstAdapter *adapter, gboolean at_eos, GstVaapiDecoderUnit *unit)
2863 GstVaapiDecoderH264 * const decoder =
2864 GST_VAAPI_DECODER_H264_CAST(base_decoder);
2865 GstVaapiDecoderH264Private * const priv = decoder->priv;
2866 GstVaapiParserState * const ps = GST_VAAPI_PARSER_STATE(base_decoder);
2867 GstVaapiParserInfoH264 *pi;
2868 GstVaapiDecoderStatus status;
2869 GstH264ParserResult result;
2871 guint i, size, buf_size, nalu_size, flags;
2875 status = ensure_decoder(decoder);
2876 if (status != GST_VAAPI_DECODER_STATUS_SUCCESS)
2879 size = gst_adapter_available(adapter);
2881 if (priv->is_avcC) {
2882 if (size < priv->nal_length_size)
2883 return GST_VAAPI_DECODER_STATUS_ERROR_NO_DATA;
2885 buf = (guchar *)&start_code;
2886 g_assert(priv->nal_length_size <= sizeof(start_code));
2887 gst_adapter_copy(adapter, buf, 0, priv->nal_length_size);
2890 for (i = 0; i < priv->nal_length_size; i++)
2891 nalu_size = (nalu_size << 8) | buf[i];
2893 buf_size = priv->nal_length_size + nalu_size;
2894 if (size < buf_size)
2895 return GST_VAAPI_DECODER_STATUS_ERROR_NO_DATA;
2899 return GST_VAAPI_DECODER_STATUS_ERROR_NO_DATA;
2901 ofs = scan_for_start_code(adapter, 0, size, NULL);
2903 return GST_VAAPI_DECODER_STATUS_ERROR_NO_DATA;
2906 gst_adapter_flush(adapter, ofs);
2910 ofs2 = ps->input_offset2 - ofs - 4;
2914 ofs = G_UNLIKELY(size < ofs2 + 4) ? -1 :
2915 scan_for_start_code(adapter, ofs2, size - ofs2, NULL);
2917 // Assume the whole NAL unit is present if end-of-stream
2919 ps->input_offset2 = size;
2920 return GST_VAAPI_DECODER_STATUS_ERROR_NO_DATA;
2926 ps->input_offset2 = 0;
2928 buf = (guchar *)gst_adapter_map(adapter, buf_size);
2930 return GST_VAAPI_DECODER_STATUS_ERROR_NO_DATA;
2932 unit->size = buf_size;
2934 pi = gst_vaapi_parser_info_h264_new();
2936 return GST_VAAPI_DECODER_STATUS_ERROR_ALLOCATION_FAILED;
2938 gst_vaapi_decoder_unit_set_parsed_info(unit,
2939 pi, (GDestroyNotify)gst_vaapi_mini_object_unref);
2942 result = gst_h264_parser_identify_nalu_avc(priv->parser,
2943 buf, 0, buf_size, priv->nal_length_size, &pi->nalu);
2945 result = gst_h264_parser_identify_nalu_unchecked(priv->parser,
2946 buf, 0, buf_size, &pi->nalu);
2947 status = get_status(result);
2948 if (status != GST_VAAPI_DECODER_STATUS_SUCCESS)
2951 switch (pi->nalu.type) {
2952 case GST_H264_NAL_SPS:
2953 status = parse_sps(decoder, unit);
2955 case GST_H264_NAL_PPS:
2956 status = parse_pps(decoder, unit);
2958 case GST_H264_NAL_SEI:
2959 status = parse_sei(decoder, unit);
2961 case GST_H264_NAL_SLICE_IDR:
2962 case GST_H264_NAL_SLICE:
2963 status = parse_slice(decoder, unit);
2966 status = GST_VAAPI_DECODER_STATUS_SUCCESS;
2969 if (status != GST_VAAPI_DECODER_STATUS_SUCCESS)
2973 switch (pi->nalu.type) {
2974 case GST_H264_NAL_AU_DELIMITER:
2975 flags |= GST_VAAPI_DECODER_UNIT_FLAG_FRAME_START;
2977 case GST_H264_NAL_FILLER_DATA:
2978 flags |= GST_VAAPI_DECODER_UNIT_FLAG_SKIP;
2980 case GST_H264_NAL_STREAM_END:
2981 flags |= GST_VAAPI_DECODER_UNIT_FLAG_STREAM_END;
2983 case GST_H264_NAL_SEQ_END:
2984 flags |= GST_VAAPI_DECODER_UNIT_FLAG_FRAME_END;
2986 case GST_H264_NAL_SPS:
2987 case GST_H264_NAL_PPS:
2988 flags |= GST_VAAPI_DECODER_UNIT_FLAG_SKIP;
2990 case GST_H264_NAL_SEI:
2991 flags |= GST_VAAPI_DECODER_UNIT_FLAG_FRAME_START;
2993 case GST_H264_NAL_SLICE_IDR:
2994 case GST_H264_NAL_SLICE:
2995 flags |= GST_VAAPI_DECODER_UNIT_FLAG_SLICE;
2996 if (is_new_picture(pi, priv->prev_slice_pi))
2997 flags |= GST_VAAPI_DECODER_UNIT_FLAG_FRAME_START;
2998 gst_vaapi_parser_info_h264_replace(&priv->prev_slice_pi, pi);
3001 if (pi->nalu.type >= 14 && pi->nalu.type <= 18)
3002 flags |= GST_VAAPI_DECODER_UNIT_FLAG_FRAME_START;
3005 GST_VAAPI_DECODER_UNIT_FLAG_SET(unit, flags);
3007 pi->nalu.data = NULL;
3008 return GST_VAAPI_DECODER_STATUS_SUCCESS;
3011 static GstVaapiDecoderStatus
3012 gst_vaapi_decoder_h264_decode(GstVaapiDecoder *base_decoder,
3013 GstVaapiDecoderUnit *unit)
3015 GstVaapiDecoderH264 * const decoder =
3016 GST_VAAPI_DECODER_H264_CAST(base_decoder);
3017 GstVaapiDecoderStatus status;
3019 status = ensure_decoder(decoder);
3020 if (status != GST_VAAPI_DECODER_STATUS_SUCCESS)
3022 return decode_unit(decoder, unit);
3025 static GstVaapiDecoderStatus
3026 gst_vaapi_decoder_h264_start_frame(GstVaapiDecoder *base_decoder,
3027 GstVaapiDecoderUnit *unit)
3029 GstVaapiDecoderH264 * const decoder =
3030 GST_VAAPI_DECODER_H264_CAST(base_decoder);
3032 return decode_picture(decoder, unit);
3035 static GstVaapiDecoderStatus
3036 gst_vaapi_decoder_h264_end_frame(GstVaapiDecoder *base_decoder)
3038 GstVaapiDecoderH264 * const decoder =
3039 GST_VAAPI_DECODER_H264_CAST(base_decoder);
3041 return decode_current_picture(decoder);
3044 static GstVaapiDecoderStatus
3045 gst_vaapi_decoder_h264_flush(GstVaapiDecoder *base_decoder)
3047 GstVaapiDecoderH264 * const decoder =
3048 GST_VAAPI_DECODER_H264_CAST(base_decoder);
3051 return GST_VAAPI_DECODER_STATUS_SUCCESS;
3055 gst_vaapi_decoder_h264_finalize(GObject *object)
3057 GstVaapiDecoderH264 * const decoder = GST_VAAPI_DECODER_H264_CAST(object);
3059 gst_vaapi_decoder_h264_destroy(decoder);
3061 G_OBJECT_CLASS(gst_vaapi_decoder_h264_parent_class)->finalize(object);
3065 gst_vaapi_decoder_h264_constructed(GObject *object)
3067 GstVaapiDecoderH264 * const decoder = GST_VAAPI_DECODER_H264_CAST(object);
3068 GstVaapiDecoderH264Private * const priv = decoder->priv;
3069 GObjectClass *parent_class;
3071 parent_class = G_OBJECT_CLASS(gst_vaapi_decoder_h264_parent_class);
3072 if (parent_class->constructed)
3073 parent_class->constructed(object);
3075 priv->is_constructed = gst_vaapi_decoder_h264_create(decoder);
3079 gst_vaapi_decoder_h264_class_init(GstVaapiDecoderH264Class *klass)
3081 GObjectClass * const object_class = G_OBJECT_CLASS(klass);
3082 GstVaapiDecoderClass * const decoder_class = GST_VAAPI_DECODER_CLASS(klass);
3084 g_type_class_add_private(klass, sizeof(GstVaapiDecoderH264Private));
3086 object_class->finalize = gst_vaapi_decoder_h264_finalize;
3087 object_class->constructed = gst_vaapi_decoder_h264_constructed;
3089 decoder_class->parse = gst_vaapi_decoder_h264_parse;
3090 decoder_class->decode = gst_vaapi_decoder_h264_decode;
3091 decoder_class->start_frame = gst_vaapi_decoder_h264_start_frame;
3092 decoder_class->end_frame = gst_vaapi_decoder_h264_end_frame;
3093 decoder_class->flush = gst_vaapi_decoder_h264_flush;
3095 decoder_class->decode_codec_data =
3096 gst_vaapi_decoder_h264_decode_codec_data;
3100 gst_vaapi_decoder_h264_init(GstVaapiDecoderH264 *decoder)
3102 GstVaapiDecoderH264Private *priv;
3104 priv = GST_VAAPI_DECODER_H264_GET_PRIVATE(decoder);
3105 decoder->priv = priv;
3106 priv->profile = GST_VAAPI_PROFILE_UNKNOWN;
3107 priv->entrypoint = GST_VAAPI_ENTRYPOINT_VLD;
3108 priv->chroma_type = GST_VAAPI_CHROMA_TYPE_YUV420;
3109 priv->prev_pic_structure = GST_VAAPI_PICTURE_STRUCTURE_FRAME;
3110 priv->progressive_sequence = TRUE;
3114 * gst_vaapi_decoder_h264_new:
3115 * @display: a #GstVaapiDisplay
3116 * @caps: a #GstCaps holding codec information
3118 * Creates a new #GstVaapiDecoder for MPEG-2 decoding. The @caps can
3119 * hold extra information like codec-data and pictured coded size.
3121 * Return value: the newly allocated #GstVaapiDecoder object
3124 gst_vaapi_decoder_h264_new(GstVaapiDisplay *display, GstCaps *caps)
3126 GstVaapiDecoderH264 *decoder;
3128 g_return_val_if_fail(GST_VAAPI_IS_DISPLAY(display), NULL);
3129 g_return_val_if_fail(GST_IS_CAPS(caps), NULL);
3131 decoder = g_object_new(
3132 GST_VAAPI_TYPE_DECODER_H264,
3137 if (!decoder->priv->is_constructed) {
3138 g_object_unref(decoder);
3141 return GST_VAAPI_DECODER_CAST(decoder);