2 * gstvaapidecoder_h264.c - H.264 decoder
4 * Copyright (C) 2011-2012 Intel Corporation
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public License
8 * as published by the Free Software Foundation; either version 2.1
9 * of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free
18 * Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
19 * Boston, MA 02110-1301 USA
23 * SECTION:gstvaapidecoder_h264
24 * @short_description: H.264 decoder
29 #include <gst/base/gstadapter.h>
30 #include <gst/codecparsers/gsth264parser.h>
31 #include "gstvaapidecoder_h264.h"
32 #include "gstvaapidecoder_objects.h"
33 #include "gstvaapidecoder_priv.h"
34 #include "gstvaapidisplay_priv.h"
35 #include "gstvaapiobject_priv.h"
38 #include "gstvaapidebug.h"
40 /* Defined to 1 if strict ordering of DPB is needed. Only useful for debug */
41 #define USE_STRICT_DPB_ORDERING 0
43 typedef struct _GstVaapiFrameStore GstVaapiFrameStore;
44 typedef struct _GstVaapiFrameStoreClass GstVaapiFrameStoreClass;
45 typedef struct _GstVaapiPictureH264 GstVaapiPictureH264;
46 typedef struct _GstVaapiPictureH264Class GstVaapiPictureH264Class;
47 typedef struct _GstVaapiSliceH264 GstVaapiSliceH264;
48 typedef struct _GstVaapiSliceH264Class GstVaapiSliceH264Class;
50 // Used for field_poc[]
52 #define BOTTOM_FIELD 1
54 /* ------------------------------------------------------------------------- */
55 /* --- H.264 Pictures --- */
56 /* ------------------------------------------------------------------------- */
58 #define GST_VAAPI_TYPE_PICTURE_H264 \
59 (gst_vaapi_picture_h264_get_type())
61 #define GST_VAAPI_PICTURE_H264_CAST(obj) \
62 ((GstVaapiPictureH264 *)(obj))
64 #define GST_VAAPI_PICTURE_H264(obj) \
65 (G_TYPE_CHECK_INSTANCE_CAST((obj), \
66 GST_VAAPI_TYPE_PICTURE_H264, \
69 #define GST_VAAPI_PICTURE_H264_CLASS(klass) \
70 (G_TYPE_CHECK_CLASS_CAST((klass), \
71 GST_VAAPI_TYPE_PICTURE_H264, \
72 GstVaapiPictureH264Class))
74 #define GST_VAAPI_IS_PICTURE_H264(obj) \
75 (G_TYPE_CHECK_INSTANCE_TYPE((obj), GST_VAAPI_TYPE_PICTURE_H264))
77 #define GST_VAAPI_IS_PICTURE_H264_CLASS(klass) \
78 (G_TYPE_CHECK_CLASS_TYPE((klass), GST_VAAPI_TYPE_PICTURE_H264))
80 #define GST_VAAPI_PICTURE_H264_GET_CLASS(obj) \
81 (G_TYPE_INSTANCE_GET_CLASS((obj), \
82 GST_VAAPI_TYPE_PICTURE_H264, \
83 GstVaapiPictureH264Class))
86 * Extended picture flags:
88 * @GST_VAAPI_PICTURE_FLAG_IDR: flag that specifies an IDR picture
89 * @GST_VAAPI_PICTURE_FLAG_SHORT_TERM_REFERENCE: flag that specifies
90 * "used for short-term reference"
91 * @GST_VAAPI_PICTURE_FLAG_LONG_TERM_REFERENCE: flag that specifies
92 * "used for long-term reference"
93 * @GST_VAAPI_PICTURE_FLAGS_REFERENCE: mask covering any kind of
94 * reference picture (short-term reference or long-term reference)
97 GST_VAAPI_PICTURE_FLAG_IDR = (GST_VAAPI_PICTURE_FLAG_LAST << 0),
99 GST_VAAPI_PICTURE_FLAG_SHORT_TERM_REFERENCE = (
100 GST_VAAPI_PICTURE_FLAG_REFERENCE),
101 GST_VAAPI_PICTURE_FLAG_LONG_TERM_REFERENCE = (
102 GST_VAAPI_PICTURE_FLAG_REFERENCE | (GST_VAAPI_PICTURE_FLAG_LAST << 1)),
103 GST_VAAPI_PICTURE_FLAGS_REFERENCE = (
104 GST_VAAPI_PICTURE_FLAG_SHORT_TERM_REFERENCE |
105 GST_VAAPI_PICTURE_FLAG_LONG_TERM_REFERENCE),
108 #define GST_VAAPI_PICTURE_IS_IDR(picture) \
109 (GST_VAAPI_PICTURE_FLAG_IS_SET(picture, GST_VAAPI_PICTURE_FLAG_IDR))
111 #define GST_VAAPI_PICTURE_IS_SHORT_TERM_REFERENCE(picture) \
112 ((GST_VAAPI_PICTURE_FLAGS(picture) & \
113 GST_VAAPI_PICTURE_FLAGS_REFERENCE) == \
114 GST_VAAPI_PICTURE_FLAG_SHORT_TERM_REFERENCE)
116 #define GST_VAAPI_PICTURE_IS_LONG_TERM_REFERENCE(picture) \
117 ((GST_VAAPI_PICTURE_FLAGS(picture) & \
118 GST_VAAPI_PICTURE_FLAGS_REFERENCE) == \
119 GST_VAAPI_PICTURE_FLAG_LONG_TERM_REFERENCE)
121 struct _GstVaapiPictureH264 {
122 GstVaapiPicture base;
126 gint32 frame_num; // Original frame_num from slice_header()
127 gint32 frame_num_wrap; // Temporary for ref pic marking: FrameNumWrap
128 gint32 long_term_frame_idx; // Temporary for ref pic marking: LongTermFrameIdx
129 gint32 pic_num; // Temporary for ref pic marking: PicNum
130 gint32 long_term_pic_num; // Temporary for ref pic marking: LongTermPicNum
131 GstVaapiPictureH264 *other_field; // Temporary for ref pic marking: other field in the same frame store
132 guint output_flag : 1;
133 guint output_needed : 1;
136 struct _GstVaapiPictureH264Class {
138 GstVaapiPictureClass parent_class;
141 GST_VAAPI_CODEC_DEFINE_TYPE(GstVaapiPictureH264,
142 gst_vaapi_picture_h264,
143 GST_VAAPI_TYPE_PICTURE)
146 gst_vaapi_picture_h264_destroy(GstVaapiPictureH264 *decoder)
151 gst_vaapi_picture_h264_create(
152 GstVaapiPictureH264 *picture,
153 const GstVaapiCodecObjectConstructorArgs *args
160 gst_vaapi_picture_h264_init(GstVaapiPictureH264 *picture)
162 picture->field_poc[0] = G_MAXINT32;
163 picture->field_poc[1] = G_MAXINT32;
164 picture->output_needed = FALSE;
167 static inline GstVaapiPictureH264 *
168 gst_vaapi_picture_h264_new(GstVaapiDecoderH264 *decoder)
170 GstVaapiCodecObject *object;
172 g_return_val_if_fail(GST_VAAPI_IS_DECODER(decoder), NULL);
174 object = gst_vaapi_codec_object_new(
175 GST_VAAPI_TYPE_PICTURE_H264,
176 GST_VAAPI_CODEC_BASE(decoder),
177 NULL, sizeof(VAPictureParameterBufferH264),
182 return GST_VAAPI_PICTURE_H264_CAST(object);
186 gst_vaapi_picture_h264_set_reference(
187 GstVaapiPictureH264 *picture,
188 guint reference_flags,
192 g_return_if_fail(GST_VAAPI_IS_PICTURE_H264(picture));
194 GST_VAAPI_PICTURE_FLAG_UNSET(picture, GST_VAAPI_PICTURE_FLAGS_REFERENCE);
195 GST_VAAPI_PICTURE_FLAG_SET(picture, reference_flags);
197 if (!other_field || !(picture = picture->other_field))
199 GST_VAAPI_PICTURE_FLAG_UNSET(picture, GST_VAAPI_PICTURE_FLAGS_REFERENCE);
200 GST_VAAPI_PICTURE_FLAG_SET(picture, reference_flags);
203 static inline GstVaapiPictureH264 *
204 gst_vaapi_picture_h264_new_field(GstVaapiPictureH264 *picture)
206 GstVaapiPicture *base_picture;
208 g_return_val_if_fail(GST_VAAPI_IS_PICTURE_H264(picture), NULL);
210 base_picture = gst_vaapi_picture_new_field(&picture->base);
213 return GST_VAAPI_PICTURE_H264_CAST(base_picture);
216 static inline GstVaapiSliceH264 *
217 gst_vaapi_picture_h264_get_last_slice(GstVaapiPictureH264 *picture)
219 g_return_val_if_fail(GST_VAAPI_IS_PICTURE_H264(picture), NULL);
221 if (G_UNLIKELY(picture->base.slices->len < 1))
223 return g_ptr_array_index(picture->base.slices,
224 picture->base.slices->len - 1);
227 /* ------------------------------------------------------------------------- */
229 /* ------------------------------------------------------------------------- */
231 #define GST_VAAPI_TYPE_SLICE_H264 \
232 (gst_vaapi_slice_h264_get_type())
234 #define GST_VAAPI_SLICE_H264_CAST(obj) \
235 ((GstVaapiSliceH264 *)(obj))
237 #define GST_VAAPI_SLICE_H264(obj) \
238 (G_TYPE_CHECK_INSTANCE_CAST((obj), \
239 GST_VAAPI_TYPE_SLICE_H264, \
242 #define GST_VAAPI_SLICE_H264_CLASS(klass) \
243 (G_TYPE_CHECK_CLASS_CAST((klass), \
244 GST_VAAPI_TYPE_SLICE_H264, \
245 GstVaapiSliceH264Class))
247 #define GST_VAAPI_IS_SLICE_H264(obj) \
248 (G_TYPE_CHECK_INSTANCE_TYPE((obj), GST_VAAPI_TYPE_SLICE_H264))
250 #define GST_VAAPI_IS_SLICE_H264_CLASS(klass) \
251 (G_TYPE_CHECK_CLASS_TYPE((klass), GST_VAAPI_TYPE_SLICE_H264))
253 #define GST_VAAPI_SLICE_H264_GET_CLASS(obj) \
254 (G_TYPE_INSTANCE_GET_CLASS((obj), \
255 GST_VAAPI_TYPE_SLICE_H264, \
256 GstVaapiSliceH264Class))
258 struct _GstVaapiSliceH264 {
260 GstH264SliceHdr slice_hdr; // parsed slice_header()
263 struct _GstVaapiSliceH264Class {
265 GstVaapiSliceClass parent_class;
268 GST_VAAPI_CODEC_DEFINE_TYPE(GstVaapiSliceH264,
269 gst_vaapi_slice_h264,
270 GST_VAAPI_TYPE_SLICE)
273 gst_vaapi_slice_h264_destroy(GstVaapiSliceH264 *slice)
278 gst_vaapi_slice_h264_create(
279 GstVaapiSliceH264 *slice,
280 const GstVaapiCodecObjectConstructorArgs *args
287 gst_vaapi_slice_h264_init(GstVaapiSliceH264 *slice)
291 static inline GstVaapiSliceH264 *
292 gst_vaapi_slice_h264_new(
293 GstVaapiDecoderH264 *decoder,
298 GstVaapiCodecObject *object;
300 g_return_val_if_fail(GST_VAAPI_IS_DECODER(decoder), NULL);
302 object = gst_vaapi_codec_object_new(
303 GST_VAAPI_TYPE_SLICE_H264,
304 GST_VAAPI_CODEC_BASE(decoder),
305 NULL, sizeof(VASliceParameterBufferH264),
310 return GST_VAAPI_SLICE_H264_CAST(object);
313 /* ------------------------------------------------------------------------- */
314 /* --- Frame Buffers (DPB) --- */
315 /* ------------------------------------------------------------------------- */
317 #define GST_VAAPI_TYPE_FRAME_STORE \
318 (gst_vaapi_frame_store_get_type())
320 #define GST_VAAPI_FRAME_STORE_CAST(obj) \
321 ((GstVaapiFrameStore *)(obj))
323 #define GST_VAAPI_FRAME_STORE(obj) \
324 (G_TYPE_CHECK_INSTANCE_CAST((obj), \
325 GST_VAAPI_TYPE_FRAME_STORE, \
328 #define GST_VAAPI_FRAME_STORE_CLASS(klass) \
329 (G_TYPE_CHECK_CLASS_CAST((klass), \
330 GST_VAAPI_TYPE_FRAME_STORE, \
331 GstVaapiFrameStoreClass))
333 #define GST_VAAPI_IS_FRAME_STORE(obj) \
334 (G_TYPE_CHECK_INSTANCE_TYPE((obj), GST_VAAPI_TYPE_FRAME_STORE))
336 #define GST_VAAPI_IS_FRAME_STORE_CLASS(klass) \
337 (G_TYPE_CHECK_CLASS_TYPE((klass), GST_VAAPI_TYPE_FRAME_STORE))
339 #define GST_VAAPI_FRAME_STORE_GET_CLASS(obj) \
340 (G_TYPE_INSTANCE_GET_CLASS((obj), \
341 GST_VAAPI_TYPE_FRAME_STORE, \
342 GstVaapiFrameStoreClass))
344 struct _GstVaapiFrameStore {
346 GstMiniObject parent_instance;
349 GstVaapiPictureH264 *buffers[2];
354 struct _GstVaapiFrameStoreClass {
356 GstMiniObjectClass parent_class;
359 G_DEFINE_TYPE(GstVaapiFrameStore, gst_vaapi_frame_store, GST_TYPE_MINI_OBJECT)
362 gst_vaapi_frame_store_finalize(GstMiniObject *object)
364 GstVaapiFrameStore * const fs = GST_VAAPI_FRAME_STORE_CAST(object);
365 GstMiniObjectClass *parent_class;
368 for (i = 0; i < fs->num_buffers; i++)
369 gst_vaapi_picture_replace(&fs->buffers[i], NULL);
371 parent_class = GST_MINI_OBJECT_CLASS(gst_vaapi_frame_store_parent_class);
372 if (parent_class->finalize)
373 parent_class->finalize(object);
377 gst_vaapi_frame_store_init(GstVaapiFrameStore *fs)
382 gst_vaapi_frame_store_class_init(GstVaapiFrameStoreClass *klass)
384 GstMiniObjectClass * const object_class = GST_MINI_OBJECT_CLASS(klass);
386 object_class->finalize = gst_vaapi_frame_store_finalize;
389 static inline gpointer
390 _gst_vaapi_frame_store_new(void)
392 return gst_mini_object_new(GST_VAAPI_TYPE_FRAME_STORE);
395 static GstVaapiFrameStore *
396 gst_vaapi_frame_store_new(GstVaapiPictureH264 *picture)
398 GstVaapiFrameStore *fs;
400 g_return_val_if_fail(GST_VAAPI_IS_PICTURE_H264(picture), NULL);
402 fs = _gst_vaapi_frame_store_new();
406 fs->structure = picture->structure;
407 fs->buffers[0] = gst_vaapi_picture_ref(picture);
409 fs->output_needed = picture->output_needed;
414 gst_vaapi_frame_store_add(GstVaapiFrameStore *fs, GstVaapiPictureH264 *picture)
418 g_return_val_if_fail(GST_VAAPI_IS_FRAME_STORE(fs), FALSE);
419 g_return_val_if_fail(fs->num_buffers == 1, FALSE);
420 g_return_val_if_fail(GST_VAAPI_IS_PICTURE_H264(picture), FALSE);
421 g_return_val_if_fail(!GST_VAAPI_PICTURE_IS_FRAME(picture), FALSE);
423 gst_vaapi_picture_replace(&fs->buffers[fs->num_buffers++], picture);
424 if (picture->output_flag) {
425 picture->output_needed = TRUE;
429 fs->structure = GST_VAAPI_PICTURE_STRUCTURE_FRAME;
431 field = picture->structure == GST_VAAPI_PICTURE_STRUCTURE_TOP_FIELD ?
432 TOP_FIELD : BOTTOM_FIELD;
433 g_return_val_if_fail(fs->buffers[0]->field_poc[field] == G_MAXINT32, FALSE);
434 fs->buffers[0]->field_poc[field] = picture->field_poc[field];
435 g_return_val_if_fail(picture->field_poc[!field] == G_MAXINT32, FALSE);
436 picture->field_poc[!field] = fs->buffers[0]->field_poc[!field];
441 gst_vaapi_frame_store_split_fields(GstVaapiFrameStore *fs)
443 GstVaapiPictureH264 * const first_field = fs->buffers[0];
444 GstVaapiPictureH264 *second_field;
446 g_return_val_if_fail(fs->num_buffers == 1, FALSE);
448 first_field->base.structure = GST_VAAPI_PICTURE_STRUCTURE_TOP_FIELD;
449 GST_VAAPI_PICTURE_FLAG_SET(first_field, GST_VAAPI_PICTURE_FLAG_INTERLACED);
451 second_field = gst_vaapi_picture_h264_new_field(first_field);
454 gst_vaapi_picture_replace(&fs->buffers[fs->num_buffers++], second_field);
455 gst_vaapi_picture_unref(second_field);
457 second_field->frame_num = first_field->frame_num;
458 second_field->field_poc[0] = first_field->field_poc[0];
459 second_field->field_poc[1] = first_field->field_poc[1];
460 second_field->output_flag = first_field->output_flag;
461 if (second_field->output_flag) {
462 second_field->output_needed = TRUE;
468 static inline gboolean
469 gst_vaapi_frame_store_has_frame(GstVaapiFrameStore *fs)
471 return fs->structure == GST_VAAPI_PICTURE_STRUCTURE_FRAME;
474 static inline gboolean
475 gst_vaapi_frame_store_has_reference(GstVaapiFrameStore *fs)
479 for (i = 0; i < fs->num_buffers; i++) {
480 if (GST_VAAPI_PICTURE_IS_REFERENCE(fs->buffers[i]))
486 #define gst_vaapi_frame_store_ref(fs) \
487 gst_mini_object_ref(GST_MINI_OBJECT(fs))
489 #define gst_vaapi_frame_store_unref(fs) \
490 gst_mini_object_unref(GST_MINI_OBJECT(fs))
492 #define gst_vaapi_frame_store_replace(old_fs_p, new_fs) \
493 gst_mini_object_replace((GstMiniObject **)(old_fs_p), \
494 (GstMiniObject *)(new_fs))
496 /* ------------------------------------------------------------------------- */
497 /* --- H.264 Decoder --- */
498 /* ------------------------------------------------------------------------- */
500 G_DEFINE_TYPE(GstVaapiDecoderH264,
501 gst_vaapi_decoder_h264,
502 GST_VAAPI_TYPE_DECODER)
504 #define GST_VAAPI_DECODER_H264_GET_PRIVATE(obj) \
505 (G_TYPE_INSTANCE_GET_PRIVATE((obj), \
506 GST_VAAPI_TYPE_DECODER_H264, \
507 GstVaapiDecoderH264Private))
509 struct _GstVaapiDecoderH264Private {
511 GstH264NalParser *parser;
512 /* Last decoded SPS. May not be the last activated one. Just here because
513 it may not fit stack memory allocation in decode_sps() */
515 /* Last decoded PPS. May not be the last activated one. Just here because
516 it may not fit stack memory allocation in decode_pps() */
518 GstVaapiPictureH264 *current_picture;
519 GstVaapiFrameStore *prev_frame;
520 GstVaapiFrameStore *dpb[16];
523 GstVaapiProfile profile;
524 GstVaapiEntrypoint entrypoint;
525 GstVaapiChromaType chroma_type;
526 GstVaapiPictureH264 *short_ref[32];
527 guint short_ref_count;
528 GstVaapiPictureH264 *long_ref[32];
529 guint long_ref_count;
530 GstVaapiPictureH264 *RefPicList0[32];
531 guint RefPicList0_count;
532 GstVaapiPictureH264 *RefPicList1[32];
533 guint RefPicList1_count;
534 guint nal_length_size;
537 gint32 field_poc[2]; // 0:TopFieldOrderCnt / 1:BottomFieldOrderCnt
538 gint32 poc_msb; // PicOrderCntMsb
539 gint32 poc_lsb; // pic_order_cnt_lsb (from slice_header())
540 gint32 prev_poc_msb; // prevPicOrderCntMsb
541 gint32 prev_poc_lsb; // prevPicOrderCntLsb
542 gint32 frame_num_offset; // FrameNumOffset
543 gint32 frame_num; // frame_num (from slice_header())
544 gint32 prev_frame_num; // prevFrameNum
545 gboolean prev_pic_has_mmco5; // prevMmco5Pic
546 gboolean prev_pic_structure; // previous picture structure
547 guint is_constructed : 1;
552 guint has_context : 1;
553 guint progressive_sequence : 1;
557 exec_ref_pic_marking(GstVaapiDecoderH264 *decoder, GstVaapiPictureH264 *picture);
559 /* Get number of reference frames to use */
561 get_max_dec_frame_buffering(GstH264SPS *sps)
563 guint max_dec_frame_buffering, MaxDpbMbs, PicSizeMbs;
565 /* Table A-1 - Level limits */
566 switch (sps->level_idc) {
567 case 10: MaxDpbMbs = 396; break;
568 case 11: MaxDpbMbs = 900; break;
569 case 12: MaxDpbMbs = 2376; break;
570 case 13: MaxDpbMbs = 2376; break;
571 case 20: MaxDpbMbs = 2376; break;
572 case 21: MaxDpbMbs = 4752; break;
573 case 22: MaxDpbMbs = 8100; break;
574 case 30: MaxDpbMbs = 8100; break;
575 case 31: MaxDpbMbs = 18000; break;
576 case 32: MaxDpbMbs = 20480; break;
577 case 40: MaxDpbMbs = 32768; break;
578 case 41: MaxDpbMbs = 32768; break;
579 case 42: MaxDpbMbs = 34816; break;
580 case 50: MaxDpbMbs = 110400; break;
581 case 51: MaxDpbMbs = 184320; break;
583 g_assert(0 && "unhandled level");
587 PicSizeMbs = ((sps->pic_width_in_mbs_minus1 + 1) *
588 (sps->pic_height_in_map_units_minus1 + 1) *
589 (sps->frame_mbs_only_flag ? 1 : 2));
590 max_dec_frame_buffering = MaxDpbMbs / PicSizeMbs;
593 if (sps->vui_parameters_present_flag) {
594 GstH264VUIParams * const vui_params = &sps->vui_parameters;
595 if (vui_params->bitstream_restriction_flag)
596 max_dec_frame_buffering = vui_params->max_dec_frame_buffering;
598 switch (sps->profile_idc) {
599 case 44: // CAVLC 4:4:4 Intra profile
600 case 86: // Scalable High profile
601 case 100: // High profile
602 case 110: // High 10 profile
603 case 122: // High 4:2:2 profile
604 case 244: // High 4:4:4 Predictive profile
605 if (sps->constraint_set3_flag)
606 max_dec_frame_buffering = 0;
612 if (max_dec_frame_buffering > 16)
613 max_dec_frame_buffering = 16;
614 else if (max_dec_frame_buffering < sps->num_ref_frames)
615 max_dec_frame_buffering = sps->num_ref_frames;
616 return MAX(1, max_dec_frame_buffering);
620 array_remove_index_fast(void *array, guint *array_length_ptr, guint index)
622 gpointer * const entries = array;
623 guint num_entries = *array_length_ptr;
625 g_return_if_fail(index < num_entries);
627 if (index != --num_entries)
628 entries[index] = entries[num_entries];
629 entries[num_entries] = NULL;
630 *array_length_ptr = num_entries;
635 array_remove_index(void *array, guint *array_length_ptr, guint index)
637 array_remove_index_fast(array, array_length_ptr, index);
641 array_remove_index(void *array, guint *array_length_ptr, guint index)
643 gpointer * const entries = array;
644 const guint num_entries = *array_length_ptr - 1;
647 g_return_if_fail(index <= num_entries);
649 for (i = index; i < num_entries; i++)
650 entries[i] = entries[i + 1];
651 entries[num_entries] = NULL;
652 *array_length_ptr = num_entries;
656 #define ARRAY_REMOVE_INDEX(array, index) \
657 array_remove_index(array, &array##_count, index)
660 dpb_remove_index(GstVaapiDecoderH264 *decoder, guint index)
662 GstVaapiDecoderH264Private * const priv = decoder->priv;
663 guint i, num_frames = --priv->dpb_count;
665 if (USE_STRICT_DPB_ORDERING) {
666 for (i = index; i < num_frames; i++)
667 gst_vaapi_frame_store_replace(&priv->dpb[i], priv->dpb[i + 1]);
669 else if (index != num_frames)
670 gst_vaapi_frame_store_replace(&priv->dpb[index], priv->dpb[num_frames]);
671 gst_vaapi_frame_store_replace(&priv->dpb[num_frames], NULL);
676 GstVaapiDecoderH264 *decoder,
677 GstVaapiFrameStore *fs,
678 GstVaapiPictureH264 *picture
681 picture->output_needed = FALSE;
684 if (--fs->output_needed > 0)
686 picture = fs->buffers[0];
689 /* XXX: update cropping rectangle */
690 return gst_vaapi_picture_output(GST_VAAPI_PICTURE_CAST(picture));
694 dpb_evict(GstVaapiDecoderH264 *decoder, GstVaapiPictureH264 *picture, guint i)
696 GstVaapiFrameStore * const fs = decoder->priv->dpb[i];
698 if (!fs->output_needed && !gst_vaapi_frame_store_has_reference(fs))
699 dpb_remove_index(decoder, i);
703 dpb_bump(GstVaapiDecoderH264 *decoder)
705 GstVaapiDecoderH264Private * const priv = decoder->priv;
706 GstVaapiPictureH264 *found_picture = NULL;
707 guint i, j, found_index;
710 for (i = 0; i < priv->dpb_count; i++) {
711 GstVaapiFrameStore * const fs = priv->dpb[i];
712 if (!fs->output_needed)
714 for (j = 0; j < fs->num_buffers; j++) {
715 GstVaapiPictureH264 * const picture = fs->buffers[j];
716 if (!picture->output_needed)
718 if (!found_picture || found_picture->base.poc > picture->base.poc)
719 found_picture = picture, found_index = i;
725 success = dpb_output(decoder, priv->dpb[found_index], found_picture);
726 dpb_evict(decoder, found_picture, found_index);
731 dpb_clear(GstVaapiDecoderH264 *decoder)
733 GstVaapiDecoderH264Private * const priv = decoder->priv;
736 for (i = 0; i < priv->dpb_count; i++)
737 gst_vaapi_frame_store_replace(&priv->dpb[i], NULL);
740 gst_vaapi_frame_store_replace(&priv->prev_frame, NULL);
744 dpb_flush(GstVaapiDecoderH264 *decoder)
746 while (dpb_bump(decoder))
752 dpb_add(GstVaapiDecoderH264 *decoder, GstVaapiPictureH264 *picture)
754 GstVaapiDecoderH264Private * const priv = decoder->priv;
755 GstVaapiFrameStore *fs;
758 // Remove all unused pictures
759 if (!GST_VAAPI_PICTURE_IS_IDR(picture)) {
761 while (i < priv->dpb_count) {
762 GstVaapiFrameStore * const fs = priv->dpb[i];
763 if (!fs->output_needed && !gst_vaapi_frame_store_has_reference(fs))
764 dpb_remove_index(decoder, i);
770 // Check if picture is the second field and the first field is still in DPB
771 fs = priv->prev_frame;
772 if (fs && !gst_vaapi_frame_store_has_frame(fs)) {
773 g_return_val_if_fail(fs->num_buffers == 1, FALSE);
774 g_return_val_if_fail(!GST_VAAPI_PICTURE_IS_FRAME(picture), FALSE);
775 g_return_val_if_fail(!GST_VAAPI_PICTURE_IS_FIRST_FIELD(picture), FALSE);
776 return gst_vaapi_frame_store_add(fs, picture);
779 // Create new frame store, and split fields if necessary
780 fs = gst_vaapi_frame_store_new(picture);
783 gst_vaapi_frame_store_replace(&priv->prev_frame, fs);
784 gst_vaapi_frame_store_unref(fs);
786 if (!priv->progressive_sequence && gst_vaapi_frame_store_has_frame(fs)) {
787 if (!gst_vaapi_frame_store_split_fields(fs))
791 // C.4.5.1 - Storage and marking of a reference decoded picture into the DPB
792 if (GST_VAAPI_PICTURE_IS_REFERENCE(picture)) {
793 while (priv->dpb_count == priv->dpb_size) {
794 if (!dpb_bump(decoder))
797 gst_vaapi_frame_store_replace(&priv->dpb[priv->dpb_count++], fs);
798 if (picture->output_flag) {
799 picture->output_needed = TRUE;
804 // C.4.5.2 - Storage and marking of a non-reference decoded picture into the DPB
806 if (!picture->output_flag)
808 while (priv->dpb_count == priv->dpb_size) {
809 gboolean found_picture = FALSE;
810 for (i = 0; !found_picture && i < priv->dpb_count; i++) {
811 GstVaapiFrameStore * const fs = priv->dpb[i];
812 if (!fs->output_needed)
814 for (j = 0; !found_picture && j < fs->num_buffers; j++)
815 found_picture = fs->buffers[j]->output_needed &&
816 fs->buffers[j]->base.poc < picture->base.poc;
819 return dpb_output(decoder, NULL, picture);
820 if (!dpb_bump(decoder))
823 gst_vaapi_frame_store_replace(&priv->dpb[priv->dpb_count++], fs);
824 picture->output_needed = TRUE;
831 dpb_reset(GstVaapiDecoderH264 *decoder, GstH264SPS *sps)
833 GstVaapiDecoderH264Private * const priv = decoder->priv;
835 priv->dpb_size = get_max_dec_frame_buffering(sps);
836 GST_DEBUG("DPB size %u", priv->dpb_size);
839 static GstVaapiDecoderStatus
840 get_status(GstH264ParserResult result)
842 GstVaapiDecoderStatus status;
845 case GST_H264_PARSER_OK:
846 status = GST_VAAPI_DECODER_STATUS_SUCCESS;
848 case GST_H264_PARSER_NO_NAL_END:
849 status = GST_VAAPI_DECODER_STATUS_ERROR_NO_DATA;
851 case GST_H264_PARSER_ERROR:
852 status = GST_VAAPI_DECODER_STATUS_ERROR_BITSTREAM_PARSER;
855 status = GST_VAAPI_DECODER_STATUS_ERROR_UNKNOWN;
862 gst_vaapi_decoder_h264_close(GstVaapiDecoderH264 *decoder)
864 GstVaapiDecoderH264Private * const priv = decoder->priv;
866 gst_vaapi_picture_replace(&priv->current_picture, NULL);
871 gst_h264_nal_parser_free(priv->parser);
876 gst_adapter_clear(priv->adapter);
877 g_object_unref(priv->adapter);
878 priv->adapter = NULL;
883 gst_vaapi_decoder_h264_open(GstVaapiDecoderH264 *decoder, GstBuffer *buffer)
885 GstVaapiDecoderH264Private * const priv = decoder->priv;
887 gst_vaapi_decoder_h264_close(decoder);
889 priv->adapter = gst_adapter_new();
893 priv->parser = gst_h264_nal_parser_new();
900 gst_vaapi_decoder_h264_destroy(GstVaapiDecoderH264 *decoder)
902 gst_vaapi_decoder_h264_close(decoder);
906 gst_vaapi_decoder_h264_create(GstVaapiDecoderH264 *decoder)
908 if (!GST_VAAPI_DECODER_CODEC(decoder))
914 h264_get_profile(GstH264SPS *sps)
918 switch (sps->profile_idc) {
920 profile = GST_VAAPI_PROFILE_H264_BASELINE;
923 profile = GST_VAAPI_PROFILE_H264_MAIN;
926 profile = GST_VAAPI_PROFILE_H264_HIGH;
933 h264_get_chroma_type(GstH264SPS *sps)
935 guint chroma_type = 0;
937 switch (sps->chroma_format_idc) {
939 chroma_type = GST_VAAPI_CHROMA_TYPE_YUV420;
942 chroma_type = GST_VAAPI_CHROMA_TYPE_YUV422;
945 if (!sps->separate_colour_plane_flag)
946 chroma_type = GST_VAAPI_CHROMA_TYPE_YUV444;
952 static GstVaapiProfile
953 get_profile(GstVaapiDecoderH264 *decoder, GstH264SPS *sps)
955 GstVaapiDecoderH264Private * const priv = decoder->priv;
956 GstVaapiDisplay * const display = GST_VAAPI_DECODER_DISPLAY(decoder);
957 GstVaapiProfile profile, profiles[2];
958 guint i, n_profiles = 0;
960 profile = h264_get_profile(sps);
962 return GST_VAAPI_PROFILE_UNKNOWN;
964 profiles[n_profiles++] = profile;
966 case GST_VAAPI_PROFILE_H264_MAIN:
967 profiles[n_profiles++] = GST_VAAPI_PROFILE_H264_HIGH;
973 /* If the preferred profile (profiles[0]) matches one that we already
974 found, then just return it now instead of searching for it again */
975 if (profiles[0] == priv->profile)
976 return priv->profile;
978 for (i = 0; i < n_profiles; i++) {
979 if (gst_vaapi_display_has_decoder(display, profiles[i], priv->entrypoint))
982 return GST_VAAPI_PROFILE_UNKNOWN;
985 static GstVaapiDecoderStatus
986 ensure_context(GstVaapiDecoderH264 *decoder, GstH264SPS *sps)
988 GstVaapiDecoder * const base_decoder = GST_VAAPI_DECODER_CAST(decoder);
989 GstVaapiDecoderH264Private * const priv = decoder->priv;
990 GstVaapiContextInfo info;
991 GstVaapiProfile profile;
992 GstVaapiChromaType chroma_type;
993 gboolean reset_context = FALSE;
994 guint mb_width, mb_height;
996 profile = get_profile(decoder, sps);
998 GST_ERROR("unsupported profile_idc %u", sps->profile_idc);
999 return GST_VAAPI_DECODER_STATUS_ERROR_UNSUPPORTED_PROFILE;
1002 if (priv->profile != profile) {
1003 GST_DEBUG("profile changed");
1004 reset_context = TRUE;
1005 priv->profile = profile;
1008 chroma_type = h264_get_chroma_type(sps);
1009 if (!chroma_type || chroma_type != GST_VAAPI_CHROMA_TYPE_YUV420) {
1010 GST_ERROR("unsupported chroma_format_idc %u", sps->chroma_format_idc);
1011 return GST_VAAPI_DECODER_STATUS_ERROR_UNSUPPORTED_CHROMA_FORMAT;
1014 if (priv->chroma_type != chroma_type) {
1015 GST_DEBUG("chroma format changed");
1016 reset_context = TRUE;
1017 priv->chroma_type = chroma_type;
1020 mb_width = sps->pic_width_in_mbs_minus1 + 1;
1021 mb_height = (sps->pic_height_in_map_units_minus1 + 1) <<
1022 !sps->frame_mbs_only_flag;
1023 if (priv->mb_width != mb_width || priv->mb_height != mb_height) {
1024 GST_DEBUG("size changed");
1025 reset_context = TRUE;
1026 priv->mb_width = mb_width;
1027 priv->mb_height = mb_height;
1030 priv->progressive_sequence = sps->frame_mbs_only_flag;
1032 /* XXX: we only output complete frames for now */
1033 gst_vaapi_decoder_set_interlaced(base_decoder, !priv->progressive_sequence);
1036 gst_vaapi_decoder_set_pixel_aspect_ratio(
1038 sps->vui_parameters.par_n,
1039 sps->vui_parameters.par_d
1042 if (!reset_context && priv->has_context)
1043 return GST_VAAPI_DECODER_STATUS_SUCCESS;
1045 /* XXX: fix surface size when cropping is implemented */
1046 info.profile = priv->profile;
1047 info.entrypoint = priv->entrypoint;
1048 info.width = sps->width;
1049 info.height = sps->height;
1050 info.ref_frames = get_max_dec_frame_buffering(sps);
1052 if (!gst_vaapi_decoder_ensure_context(GST_VAAPI_DECODER(decoder), &info))
1053 return GST_VAAPI_DECODER_STATUS_ERROR_UNKNOWN;
1054 priv->has_context = TRUE;
1057 dpb_reset(decoder, sps);
1058 return GST_VAAPI_DECODER_STATUS_SUCCESS;
1062 fill_iq_matrix_4x4(VAIQMatrixBufferH264 *iq_matrix, const GstH264PPS *pps)
1064 const guint8 (* const ScalingList4x4)[6][16] = &pps->scaling_lists_4x4;
1067 /* There are always 6 4x4 scaling lists */
1068 g_assert(G_N_ELEMENTS(iq_matrix->ScalingList4x4) == 6);
1069 g_assert(G_N_ELEMENTS(iq_matrix->ScalingList4x4[0]) == 16);
1071 if (sizeof(iq_matrix->ScalingList4x4[0][0]) == 1)
1072 memcpy(iq_matrix->ScalingList4x4, *ScalingList4x4,
1073 sizeof(iq_matrix->ScalingList4x4));
1075 for (i = 0; i < G_N_ELEMENTS(iq_matrix->ScalingList4x4); i++) {
1076 for (j = 0; j < G_N_ELEMENTS(iq_matrix->ScalingList4x4[i]); j++)
1077 iq_matrix->ScalingList4x4[i][j] = (*ScalingList4x4)[i][j];
1083 fill_iq_matrix_8x8(VAIQMatrixBufferH264 *iq_matrix, const GstH264PPS *pps)
1085 const guint8 (* const ScalingList8x8)[6][64] = &pps->scaling_lists_8x8;
1086 const GstH264SPS * const sps = pps->sequence;
1089 /* If chroma_format_idc != 3, there are up to 2 8x8 scaling lists */
1090 if (!pps->transform_8x8_mode_flag)
1093 g_assert(G_N_ELEMENTS(iq_matrix->ScalingList8x8) >= 2);
1094 g_assert(G_N_ELEMENTS(iq_matrix->ScalingList8x8[0]) == 64);
1096 if (sizeof(iq_matrix->ScalingList8x8[0][0]) == 1)
1097 memcpy(iq_matrix->ScalingList8x8, *ScalingList8x8,
1098 sizeof(iq_matrix->ScalingList8x8));
1100 n = (sps->chroma_format_idc != 3) ? 2 : 6;
1101 for (i = 0; i < n; i++) {
1102 for (j = 0; j < G_N_ELEMENTS(iq_matrix->ScalingList8x8[i]); j++)
1103 iq_matrix->ScalingList8x8[i][j] = (*ScalingList8x8)[i][j];
1108 static GstVaapiDecoderStatus
1109 ensure_quant_matrix(GstVaapiDecoderH264 *decoder, GstVaapiPictureH264 *picture)
1111 GstVaapiPicture * const base_picture = &picture->base;
1112 GstH264PPS * const pps = picture->pps;
1113 GstH264SPS * const sps = pps->sequence;
1114 VAIQMatrixBufferH264 *iq_matrix;
1116 base_picture->iq_matrix = GST_VAAPI_IQ_MATRIX_NEW(H264, decoder);
1117 if (!base_picture->iq_matrix) {
1118 GST_ERROR("failed to allocate IQ matrix");
1119 return GST_VAAPI_DECODER_STATUS_ERROR_ALLOCATION_FAILED;
1121 iq_matrix = base_picture->iq_matrix->param;
1123 /* XXX: we can only support 4:2:0 or 4:2:2 since ScalingLists8x8[]
1124 is not large enough to hold lists for 4:4:4 */
1125 if (sps->chroma_format_idc == 3)
1126 return GST_VAAPI_DECODER_STATUS_ERROR_UNSUPPORTED_CHROMA_FORMAT;
1128 fill_iq_matrix_4x4(iq_matrix, pps);
1129 fill_iq_matrix_8x8(iq_matrix, pps);
1131 return GST_VAAPI_DECODER_STATUS_SUCCESS;
1134 static GstVaapiDecoderStatus
1135 decode_current_picture(GstVaapiDecoderH264 *decoder)
1137 GstVaapiDecoderH264Private * const priv = decoder->priv;
1138 GstVaapiPictureH264 * const picture = priv->current_picture;
1139 GstVaapiDecoderStatus status;
1142 return GST_VAAPI_DECODER_STATUS_SUCCESS;
1144 status = ensure_context(decoder, picture->pps->sequence);
1145 if (status != GST_VAAPI_DECODER_STATUS_SUCCESS)
1148 if (!exec_ref_pic_marking(decoder, picture))
1150 if (!dpb_add(decoder, picture))
1152 if (!gst_vaapi_picture_decode(GST_VAAPI_PICTURE_CAST(picture)))
1154 if (priv->prev_frame && gst_vaapi_frame_store_has_frame(priv->prev_frame))
1155 gst_vaapi_picture_replace(&priv->current_picture, NULL);
1156 return GST_VAAPI_DECODER_STATUS_SUCCESS;
1159 /* XXX: fix for cases where first field failed to be decoded */
1160 gst_vaapi_picture_replace(&priv->current_picture, NULL);
1161 return GST_VAAPI_DECODER_STATUS_ERROR_UNKNOWN;
1164 static GstVaapiDecoderStatus
1165 decode_sps(GstVaapiDecoderH264 *decoder, GstH264NalUnit *nalu)
1167 GstVaapiDecoderH264Private * const priv = decoder->priv;
1168 GstH264SPS * const sps = &priv->last_sps;
1169 GstH264ParserResult result;
1171 GST_DEBUG("decode SPS");
1173 memset(sps, 0, sizeof(*sps));
1174 result = gst_h264_parser_parse_sps(priv->parser, nalu, sps, TRUE);
1175 if (result != GST_H264_PARSER_OK)
1176 return get_status(result);
1178 priv->got_sps = TRUE;
1179 return GST_VAAPI_DECODER_STATUS_SUCCESS;
1182 static GstVaapiDecoderStatus
1183 decode_pps(GstVaapiDecoderH264 *decoder, GstH264NalUnit *nalu)
1185 GstVaapiDecoderH264Private * const priv = decoder->priv;
1186 GstH264PPS * const pps = &priv->last_pps;
1187 GstH264ParserResult result;
1189 GST_DEBUG("decode PPS");
1191 memset(pps, 0, sizeof(*pps));
1192 result = gst_h264_parser_parse_pps(priv->parser, nalu, pps);
1193 if (result != GST_H264_PARSER_OK)
1194 return get_status(result);
1196 priv->got_pps = TRUE;
1197 return GST_VAAPI_DECODER_STATUS_SUCCESS;
1200 static GstVaapiDecoderStatus
1201 decode_sei(GstVaapiDecoderH264 *decoder, GstH264NalUnit *nalu)
1203 GstVaapiDecoderH264Private * const priv = decoder->priv;
1204 GstH264SEIMessage sei;
1205 GstH264ParserResult result;
1207 GST_DEBUG("decode SEI");
1209 memset(&sei, 0, sizeof(sei));
1210 result = gst_h264_parser_parse_sei(priv->parser, nalu, &sei);
1211 if (result != GST_H264_PARSER_OK) {
1212 GST_WARNING("failed to decode SEI, payload type:%d", sei.payloadType);
1213 return get_status(result);
1216 return GST_VAAPI_DECODER_STATUS_SUCCESS;
1219 static GstVaapiDecoderStatus
1220 decode_sequence_end(GstVaapiDecoderH264 *decoder)
1222 GstVaapiDecoderStatus status;
1224 GST_DEBUG("decode sequence-end");
1226 status = decode_current_picture(decoder);
1227 if (status != GST_VAAPI_DECODER_STATUS_SUCCESS)
1231 return GST_VAAPI_DECODER_STATUS_END_OF_STREAM;
1234 /* 8.2.1.1 - Decoding process for picture order count type 0 */
1237 GstVaapiDecoderH264 *decoder,
1238 GstVaapiPictureH264 *picture,
1239 GstH264SliceHdr *slice_hdr
1242 GstVaapiDecoderH264Private * const priv = decoder->priv;
1243 GstH264PPS * const pps = slice_hdr->pps;
1244 GstH264SPS * const sps = pps->sequence;
1245 const gint32 MaxPicOrderCntLsb = 1 << (sps->log2_max_pic_order_cnt_lsb_minus4 + 4);
1248 GST_DEBUG("decode picture order count type 0");
1250 if (GST_VAAPI_PICTURE_IS_IDR(picture)) {
1251 priv->prev_poc_msb = 0;
1252 priv->prev_poc_lsb = 0;
1254 else if (priv->prev_pic_has_mmco5) {
1255 priv->prev_poc_msb = 0;
1256 priv->prev_poc_lsb =
1257 (priv->prev_pic_structure == GST_VAAPI_PICTURE_STRUCTURE_BOTTOM_FIELD ?
1258 0 : priv->field_poc[TOP_FIELD]);
1261 priv->prev_poc_msb = priv->poc_msb;
1262 priv->prev_poc_lsb = priv->poc_lsb;
1266 priv->poc_lsb = slice_hdr->pic_order_cnt_lsb;
1267 if (priv->poc_lsb < priv->prev_poc_lsb &&
1268 (priv->prev_poc_lsb - priv->poc_lsb) >= (MaxPicOrderCntLsb / 2))
1269 priv->poc_msb = priv->prev_poc_msb + MaxPicOrderCntLsb;
1270 else if (priv->poc_lsb > priv->prev_poc_lsb &&
1271 (priv->poc_lsb - priv->prev_poc_lsb) > (MaxPicOrderCntLsb / 2))
1272 priv->poc_msb = priv->prev_poc_msb - MaxPicOrderCntLsb;
1274 priv->poc_msb = priv->prev_poc_msb;
1276 temp_poc = priv->poc_msb + priv->poc_lsb;
1277 switch (picture->structure) {
1278 case GST_VAAPI_PICTURE_STRUCTURE_FRAME:
1280 priv->field_poc[TOP_FIELD] = temp_poc;
1281 priv->field_poc[BOTTOM_FIELD] = temp_poc +
1282 slice_hdr->delta_pic_order_cnt_bottom;
1284 case GST_VAAPI_PICTURE_STRUCTURE_TOP_FIELD:
1286 priv->field_poc[TOP_FIELD] = temp_poc;
1288 case GST_VAAPI_PICTURE_STRUCTURE_BOTTOM_FIELD:
1290 priv->field_poc[BOTTOM_FIELD] = temp_poc;
1295 /* 8.2.1.2 - Decoding process for picture order count type 1 */
1298 GstVaapiDecoderH264 *decoder,
1299 GstVaapiPictureH264 *picture,
1300 GstH264SliceHdr *slice_hdr
1303 GstVaapiDecoderH264Private * const priv = decoder->priv;
1304 GstH264PPS * const pps = slice_hdr->pps;
1305 GstH264SPS * const sps = pps->sequence;
1306 const gint32 MaxFrameNum = 1 << (sps->log2_max_frame_num_minus4 + 4);
1307 gint32 prev_frame_num_offset, abs_frame_num, expected_poc;
1310 GST_DEBUG("decode picture order count type 1");
1312 if (priv->prev_pic_has_mmco5)
1313 prev_frame_num_offset = 0;
1315 prev_frame_num_offset = priv->frame_num_offset;
1318 if (GST_VAAPI_PICTURE_IS_IDR(picture))
1319 priv->frame_num_offset = 0;
1320 else if (priv->prev_frame_num > priv->frame_num)
1321 priv->frame_num_offset = prev_frame_num_offset + MaxFrameNum;
1323 priv->frame_num_offset = prev_frame_num_offset;
1326 if (sps->num_ref_frames_in_pic_order_cnt_cycle != 0)
1327 abs_frame_num = priv->frame_num_offset + priv->frame_num;
1330 if (!GST_VAAPI_PICTURE_IS_REFERENCE(picture) && abs_frame_num > 0)
1331 abs_frame_num = abs_frame_num - 1;
1333 if (abs_frame_num > 0) {
1334 gint32 expected_delta_per_poc_cycle;
1335 gint32 poc_cycle_cnt, frame_num_in_poc_cycle;
1337 expected_delta_per_poc_cycle = 0;
1338 for (i = 0; i < sps->num_ref_frames_in_pic_order_cnt_cycle; i++)
1339 expected_delta_per_poc_cycle += sps->offset_for_ref_frame[i];
1342 poc_cycle_cnt = (abs_frame_num - 1) /
1343 sps->num_ref_frames_in_pic_order_cnt_cycle;
1344 frame_num_in_poc_cycle = (abs_frame_num - 1) %
1345 sps->num_ref_frames_in_pic_order_cnt_cycle;
1348 expected_poc = poc_cycle_cnt * expected_delta_per_poc_cycle;
1349 for (i = 0; i <= frame_num_in_poc_cycle; i++)
1350 expected_poc += sps->offset_for_ref_frame[i];
1354 if (!GST_VAAPI_PICTURE_IS_REFERENCE(picture))
1355 expected_poc += sps->offset_for_non_ref_pic;
1358 switch (picture->structure) {
1359 case GST_VAAPI_PICTURE_STRUCTURE_FRAME:
1360 priv->field_poc[TOP_FIELD] = expected_poc +
1361 slice_hdr->delta_pic_order_cnt[0];
1362 priv->field_poc[BOTTOM_FIELD] = priv->field_poc[TOP_FIELD] +
1363 sps->offset_for_top_to_bottom_field +
1364 slice_hdr->delta_pic_order_cnt[1];
1366 case GST_VAAPI_PICTURE_STRUCTURE_TOP_FIELD:
1367 priv->field_poc[TOP_FIELD] = expected_poc +
1368 slice_hdr->delta_pic_order_cnt[0];
1370 case GST_VAAPI_PICTURE_STRUCTURE_BOTTOM_FIELD:
1371 priv->field_poc[BOTTOM_FIELD] = expected_poc +
1372 sps->offset_for_top_to_bottom_field +
1373 slice_hdr->delta_pic_order_cnt[0];
1378 /* 8.2.1.3 - Decoding process for picture order count type 2 */
1381 GstVaapiDecoderH264 *decoder,
1382 GstVaapiPictureH264 *picture,
1383 GstH264SliceHdr *slice_hdr
1386 GstVaapiDecoderH264Private * const priv = decoder->priv;
1387 GstH264PPS * const pps = slice_hdr->pps;
1388 GstH264SPS * const sps = pps->sequence;
1389 const gint32 MaxFrameNum = 1 << (sps->log2_max_frame_num_minus4 + 4);
1390 gint32 prev_frame_num_offset, temp_poc;
1392 GST_DEBUG("decode picture order count type 2");
1394 if (priv->prev_pic_has_mmco5)
1395 prev_frame_num_offset = 0;
1397 prev_frame_num_offset = priv->frame_num_offset;
1400 if (GST_VAAPI_PICTURE_IS_IDR(picture))
1401 priv->frame_num_offset = 0;
1402 else if (priv->prev_frame_num > priv->frame_num)
1403 priv->frame_num_offset = prev_frame_num_offset + MaxFrameNum;
1405 priv->frame_num_offset = prev_frame_num_offset;
1408 if (GST_VAAPI_PICTURE_IS_IDR(picture))
1410 else if (!GST_VAAPI_PICTURE_IS_REFERENCE(picture))
1411 temp_poc = 2 * (priv->frame_num_offset + priv->frame_num) - 1;
1413 temp_poc = 2 * (priv->frame_num_offset + priv->frame_num);
1416 if (picture->structure != GST_VAAPI_PICTURE_STRUCTURE_BOTTOM_FIELD)
1417 priv->field_poc[TOP_FIELD] = temp_poc;
1418 if (picture->structure != GST_VAAPI_PICTURE_STRUCTURE_TOP_FIELD)
1419 priv->field_poc[BOTTOM_FIELD] = temp_poc;
1422 /* 8.2.1 - Decoding process for picture order count */
1425 GstVaapiDecoderH264 *decoder,
1426 GstVaapiPictureH264 *picture,
1427 GstH264SliceHdr *slice_hdr
1430 GstVaapiDecoderH264Private * const priv = decoder->priv;
1431 GstH264PPS * const pps = slice_hdr->pps;
1432 GstH264SPS * const sps = pps->sequence;
1434 switch (sps->pic_order_cnt_type) {
1436 init_picture_poc_0(decoder, picture, slice_hdr);
1439 init_picture_poc_1(decoder, picture, slice_hdr);
1442 init_picture_poc_2(decoder, picture, slice_hdr);
1446 if (picture->structure != GST_VAAPI_PICTURE_STRUCTURE_BOTTOM_FIELD)
1447 picture->field_poc[TOP_FIELD] = priv->field_poc[TOP_FIELD];
1448 if (picture->structure != GST_VAAPI_PICTURE_STRUCTURE_TOP_FIELD)
1449 picture->field_poc[BOTTOM_FIELD] = priv->field_poc[BOTTOM_FIELD];
1450 picture->base.poc = MIN(picture->field_poc[0], picture->field_poc[1]);
1454 compare_picture_pic_num_dec(const void *a, const void *b)
1456 const GstVaapiPictureH264 * const picA = *(GstVaapiPictureH264 **)a;
1457 const GstVaapiPictureH264 * const picB = *(GstVaapiPictureH264 **)b;
1459 return picB->pic_num - picA->pic_num;
1463 compare_picture_long_term_pic_num_inc(const void *a, const void *b)
1465 const GstVaapiPictureH264 * const picA = *(GstVaapiPictureH264 **)a;
1466 const GstVaapiPictureH264 * const picB = *(GstVaapiPictureH264 **)b;
1468 return picA->long_term_pic_num - picB->long_term_pic_num;
1472 compare_picture_poc_dec(const void *a, const void *b)
1474 const GstVaapiPictureH264 * const picA = *(GstVaapiPictureH264 **)a;
1475 const GstVaapiPictureH264 * const picB = *(GstVaapiPictureH264 **)b;
1477 return picB->base.poc - picA->base.poc;
1481 compare_picture_poc_inc(const void *a, const void *b)
1483 const GstVaapiPictureH264 * const picA = *(GstVaapiPictureH264 **)a;
1484 const GstVaapiPictureH264 * const picB = *(GstVaapiPictureH264 **)b;
1486 return picA->base.poc - picB->base.poc;
1490 compare_picture_frame_num_wrap_dec(const void *a, const void *b)
1492 const GstVaapiPictureH264 * const picA = *(GstVaapiPictureH264 **)a;
1493 const GstVaapiPictureH264 * const picB = *(GstVaapiPictureH264 **)b;
1495 return picB->frame_num_wrap - picA->frame_num_wrap;
1499 compare_picture_long_term_frame_idx_inc(const void *a, const void *b)
1501 const GstVaapiPictureH264 * const picA = *(GstVaapiPictureH264 **)a;
1502 const GstVaapiPictureH264 * const picB = *(GstVaapiPictureH264 **)b;
1504 return picA->long_term_frame_idx - picB->long_term_frame_idx;
1507 /* 8.2.4.1 - Decoding process for picture numbers */
1509 init_picture_refs_pic_num(
1510 GstVaapiDecoderH264 *decoder,
1511 GstVaapiPictureH264 *picture,
1512 GstH264SliceHdr *slice_hdr
1515 GstVaapiDecoderH264Private * const priv = decoder->priv;
1516 GstH264PPS * const pps = slice_hdr->pps;
1517 GstH264SPS * const sps = pps->sequence;
1518 const gint32 MaxFrameNum = 1 << (sps->log2_max_frame_num_minus4 + 4);
1521 GST_DEBUG("decode picture numbers");
1523 for (i = 0; i < priv->short_ref_count; i++) {
1524 GstVaapiPictureH264 * const pic = priv->short_ref[i];
1527 if (pic->frame_num > priv->frame_num)
1528 pic->frame_num_wrap = pic->frame_num - MaxFrameNum;
1530 pic->frame_num_wrap = pic->frame_num;
1532 // (8-28, 8-30, 8-31)
1533 if (GST_VAAPI_PICTURE_IS_FRAME(picture))
1534 pic->pic_num = pic->frame_num_wrap;
1536 if (pic->structure == picture->structure)
1537 pic->pic_num = 2 * pic->frame_num_wrap + 1;
1539 pic->pic_num = 2 * pic->frame_num_wrap;
1543 for (i = 0; i < priv->long_ref_count; i++) {
1544 GstVaapiPictureH264 * const pic = priv->long_ref[i];
1546 // (8-29, 8-32, 8-33)
1547 if (GST_VAAPI_PICTURE_IS_FRAME(picture))
1548 pic->long_term_pic_num = pic->long_term_frame_idx;
1550 if (pic->structure == picture->structure)
1551 pic->long_term_pic_num = 2 * pic->long_term_frame_idx + 1;
1553 pic->long_term_pic_num = 2 * pic->long_term_frame_idx;
1558 #define SORT_REF_LIST(list, n, compare_func) \
1559 qsort(list, n, sizeof(*(list)), compare_picture_##compare_func)
1562 init_picture_refs_fields_1(
1563 guint picture_structure,
1564 GstVaapiPictureH264 *RefPicList[32],
1565 guint *RefPicList_count,
1566 GstVaapiPictureH264 *ref_list[32],
1567 guint ref_list_count
1574 n = *RefPicList_count;
1577 for (; i < ref_list_count; i++) {
1578 if (ref_list[i]->structure == picture_structure) {
1579 RefPicList[n++] = ref_list[i++];
1583 for (; j < ref_list_count; j++) {
1584 if (ref_list[j]->structure != picture_structure) {
1585 RefPicList[n++] = ref_list[j++];
1589 } while (i < ref_list_count || j < ref_list_count);
1590 *RefPicList_count = n;
1594 init_picture_refs_fields(
1595 GstVaapiPictureH264 *picture,
1596 GstVaapiPictureH264 *RefPicList[32],
1597 guint *RefPicList_count,
1598 GstVaapiPictureH264 *short_ref[32],
1599 guint short_ref_count,
1600 GstVaapiPictureH264 *long_ref[32],
1601 guint long_ref_count
1606 /* 8.2.4.2.5 - reference picture lists in fields */
1607 init_picture_refs_fields_1(picture->structure, RefPicList, &n,
1608 short_ref, short_ref_count);
1609 init_picture_refs_fields_1(picture->structure, RefPicList, &n,
1610 long_ref, long_ref_count);
1611 *RefPicList_count = n;
1615 init_picture_refs_p_slice(
1616 GstVaapiDecoderH264 *decoder,
1617 GstVaapiPictureH264 *picture,
1618 GstH264SliceHdr *slice_hdr
1621 GstVaapiDecoderH264Private * const priv = decoder->priv;
1622 GstVaapiPictureH264 **ref_list;
1625 GST_DEBUG("decode reference picture list for P and SP slices");
1627 if (GST_VAAPI_PICTURE_IS_FRAME(picture)) {
1628 /* 8.2.4.2.1 - P and SP slices in frames */
1629 if (priv->short_ref_count > 0) {
1630 ref_list = priv->RefPicList0;
1631 for (i = 0; i < priv->short_ref_count; i++)
1632 ref_list[i] = priv->short_ref[i];
1633 SORT_REF_LIST(ref_list, i, pic_num_dec);
1634 priv->RefPicList0_count += i;
1637 if (priv->long_ref_count > 0) {
1638 ref_list = &priv->RefPicList0[priv->RefPicList0_count];
1639 for (i = 0; i < priv->long_ref_count; i++)
1640 ref_list[i] = priv->long_ref[i];
1641 SORT_REF_LIST(ref_list, i, long_term_pic_num_inc);
1642 priv->RefPicList0_count += i;
1646 /* 8.2.4.2.2 - P and SP slices in fields */
1647 GstVaapiPictureH264 *short_ref[32];
1648 guint short_ref_count = 0;
1649 GstVaapiPictureH264 *long_ref[32];
1650 guint long_ref_count = 0;
1652 if (priv->short_ref_count > 0) {
1653 for (i = 0; i < priv->short_ref_count; i++)
1654 short_ref[i] = priv->short_ref[i];
1655 SORT_REF_LIST(short_ref, i, frame_num_wrap_dec);
1656 short_ref_count = i;
1659 if (priv->long_ref_count > 0) {
1660 for (i = 0; i < priv->long_ref_count; i++)
1661 long_ref[i] = priv->long_ref[i];
1662 SORT_REF_LIST(long_ref, i, long_term_frame_idx_inc);
1666 init_picture_refs_fields(
1668 priv->RefPicList0, &priv->RefPicList0_count,
1669 short_ref, short_ref_count,
1670 long_ref, long_ref_count
1676 init_picture_refs_b_slice(
1677 GstVaapiDecoderH264 *decoder,
1678 GstVaapiPictureH264 *picture,
1679 GstH264SliceHdr *slice_hdr
1682 GstVaapiDecoderH264Private * const priv = decoder->priv;
1683 GstVaapiPictureH264 **ref_list;
1686 GST_DEBUG("decode reference picture list for B slices");
1688 if (GST_VAAPI_PICTURE_IS_FRAME(picture)) {
1689 /* 8.2.4.2.3 - B slices in frames */
1692 if (priv->short_ref_count > 0) {
1693 // 1. Short-term references
1694 ref_list = priv->RefPicList0;
1695 for (n = 0, i = 0; i < priv->short_ref_count; i++) {
1696 if (priv->short_ref[i]->base.poc < picture->base.poc)
1697 ref_list[n++] = priv->short_ref[i];
1699 SORT_REF_LIST(ref_list, n, poc_dec);
1700 priv->RefPicList0_count += n;
1702 ref_list = &priv->RefPicList0[priv->RefPicList0_count];
1703 for (n = 0, i = 0; i < priv->short_ref_count; i++) {
1704 if (priv->short_ref[i]->base.poc >= picture->base.poc)
1705 ref_list[n++] = priv->short_ref[i];
1707 SORT_REF_LIST(ref_list, n, poc_inc);
1708 priv->RefPicList0_count += n;
1711 if (priv->long_ref_count > 0) {
1712 // 2. Long-term references
1713 ref_list = &priv->RefPicList0[priv->RefPicList0_count];
1714 for (n = 0, i = 0; i < priv->long_ref_count; i++)
1715 ref_list[n++] = priv->long_ref[i];
1716 SORT_REF_LIST(ref_list, n, long_term_pic_num_inc);
1717 priv->RefPicList0_count += n;
1721 if (priv->short_ref_count > 0) {
1722 // 1. Short-term references
1723 ref_list = priv->RefPicList1;
1724 for (n = 0, i = 0; i < priv->short_ref_count; i++) {
1725 if (priv->short_ref[i]->base.poc > picture->base.poc)
1726 ref_list[n++] = priv->short_ref[i];
1728 SORT_REF_LIST(ref_list, n, poc_inc);
1729 priv->RefPicList1_count += n;
1731 ref_list = &priv->RefPicList1[priv->RefPicList1_count];
1732 for (n = 0, i = 0; i < priv->short_ref_count; i++) {
1733 if (priv->short_ref[i]->base.poc <= picture->base.poc)
1734 ref_list[n++] = priv->short_ref[i];
1736 SORT_REF_LIST(ref_list, n, poc_dec);
1737 priv->RefPicList1_count += n;
1740 if (priv->long_ref_count > 0) {
1741 // 2. Long-term references
1742 ref_list = &priv->RefPicList1[priv->RefPicList1_count];
1743 for (n = 0, i = 0; i < priv->long_ref_count; i++)
1744 ref_list[n++] = priv->long_ref[i];
1745 SORT_REF_LIST(ref_list, n, long_term_pic_num_inc);
1746 priv->RefPicList1_count += n;
1750 /* 8.2.4.2.4 - B slices in fields */
1751 GstVaapiPictureH264 *short_ref0[32];
1752 guint short_ref0_count = 0;
1753 GstVaapiPictureH264 *short_ref1[32];
1754 guint short_ref1_count = 0;
1755 GstVaapiPictureH264 *long_ref[32];
1756 guint long_ref_count = 0;
1758 /* refFrameList0ShortTerm */
1759 if (priv->short_ref_count > 0) {
1760 ref_list = short_ref0;
1761 for (n = 0, i = 0; i < priv->short_ref_count; i++) {
1762 if (priv->short_ref[i]->base.poc <= picture->base.poc)
1763 ref_list[n++] = priv->short_ref[i];
1765 SORT_REF_LIST(ref_list, n, poc_dec);
1766 short_ref0_count += n;
1768 ref_list = &short_ref0[short_ref0_count];
1769 for (n = 0, i = 0; i < priv->short_ref_count; i++) {
1770 if (priv->short_ref[i]->base.poc > picture->base.poc)
1771 ref_list[n++] = priv->short_ref[i];
1773 SORT_REF_LIST(ref_list, n, poc_inc);
1774 short_ref0_count += n;
1777 /* refFrameList1ShortTerm */
1778 if (priv->short_ref_count > 0) {
1779 ref_list = short_ref1;
1780 for (n = 0, i = 0; i < priv->short_ref_count; i++) {
1781 if (priv->short_ref[i]->base.poc > picture->base.poc)
1782 ref_list[n++] = priv->short_ref[i];
1784 SORT_REF_LIST(ref_list, n, poc_inc);
1785 short_ref1_count += n;
1787 ref_list = &short_ref1[short_ref1_count];
1788 for (n = 0, i = 0; i < priv->short_ref_count; i++) {
1789 if (priv->short_ref[i]->base.poc <= picture->base.poc)
1790 ref_list[n++] = priv->short_ref[i];
1792 SORT_REF_LIST(ref_list, n, poc_dec);
1793 short_ref1_count += n;
1796 /* refFrameListLongTerm */
1797 if (priv->long_ref_count > 0) {
1798 for (i = 0; i < priv->long_ref_count; i++)
1799 long_ref[i] = priv->long_ref[i];
1800 SORT_REF_LIST(long_ref, i, long_term_frame_idx_inc);
1804 init_picture_refs_fields(
1806 priv->RefPicList0, &priv->RefPicList0_count,
1807 short_ref0, short_ref0_count,
1808 long_ref, long_ref_count
1811 init_picture_refs_fields(
1813 priv->RefPicList1, &priv->RefPicList1_count,
1814 short_ref1, short_ref1_count,
1815 long_ref, long_ref_count
1819 /* Check whether RefPicList1 is identical to RefPicList0, then
1820 swap if necessary */
1821 if (priv->RefPicList1_count > 1 &&
1822 priv->RefPicList1_count == priv->RefPicList0_count &&
1823 memcmp(priv->RefPicList0, priv->RefPicList1,
1824 priv->RefPicList0_count * sizeof(priv->RefPicList0[0])) == 0) {
1825 GstVaapiPictureH264 * const tmp = priv->RefPicList1[0];
1826 priv->RefPicList1[0] = priv->RefPicList1[1];
1827 priv->RefPicList1[1] = tmp;
1831 #undef SORT_REF_LIST
1834 find_short_term_reference(GstVaapiDecoderH264 *decoder, gint32 pic_num)
1836 GstVaapiDecoderH264Private * const priv = decoder->priv;
1839 for (i = 0; i < priv->short_ref_count; i++) {
1840 if (priv->short_ref[i]->pic_num == pic_num)
1843 GST_ERROR("found no short-term reference picture with PicNum = %d",
1849 find_long_term_reference(GstVaapiDecoderH264 *decoder, gint32 long_term_pic_num)
1851 GstVaapiDecoderH264Private * const priv = decoder->priv;
1854 for (i = 0; i < priv->long_ref_count; i++) {
1855 if (priv->long_ref[i]->long_term_pic_num == long_term_pic_num)
1858 GST_ERROR("found no long-term reference picture with LongTermPicNum = %d",
1864 exec_picture_refs_modification_1(
1865 GstVaapiDecoderH264 *decoder,
1866 GstVaapiPictureH264 *picture,
1867 GstH264SliceHdr *slice_hdr,
1871 GstVaapiDecoderH264Private * const priv = decoder->priv;
1872 GstH264PPS * const pps = slice_hdr->pps;
1873 GstH264SPS * const sps = pps->sequence;
1874 GstH264RefPicListModification *ref_pic_list_modification;
1875 guint num_ref_pic_list_modifications;
1876 GstVaapiPictureH264 **ref_list;
1877 guint *ref_list_count_ptr, ref_list_count, ref_list_idx = 0;
1878 guint i, j, n, num_refs;
1880 gint32 MaxPicNum, CurrPicNum, picNumPred;
1882 GST_DEBUG("modification process of reference picture list %u", list);
1885 ref_pic_list_modification = slice_hdr->ref_pic_list_modification_l0;
1886 num_ref_pic_list_modifications = slice_hdr->n_ref_pic_list_modification_l0;
1887 ref_list = priv->RefPicList0;
1888 ref_list_count_ptr = &priv->RefPicList0_count;
1889 num_refs = slice_hdr->num_ref_idx_l0_active_minus1 + 1;
1892 ref_pic_list_modification = slice_hdr->ref_pic_list_modification_l1;
1893 num_ref_pic_list_modifications = slice_hdr->n_ref_pic_list_modification_l1;
1894 ref_list = priv->RefPicList1;
1895 ref_list_count_ptr = &priv->RefPicList1_count;
1896 num_refs = slice_hdr->num_ref_idx_l1_active_minus1 + 1;
1898 ref_list_count = *ref_list_count_ptr;
1900 if (!GST_VAAPI_PICTURE_IS_FRAME(picture)) {
1901 MaxPicNum = 1 << (sps->log2_max_frame_num_minus4 + 5); // 2 * MaxFrameNum
1902 CurrPicNum = 2 * slice_hdr->frame_num + 1; // 2 * frame_num + 1
1905 MaxPicNum = 1 << (sps->log2_max_frame_num_minus4 + 4); // MaxFrameNum
1906 CurrPicNum = slice_hdr->frame_num; // frame_num
1909 picNumPred = CurrPicNum;
1911 for (i = 0; i < num_ref_pic_list_modifications; i++) {
1912 GstH264RefPicListModification * const l = &ref_pic_list_modification[i];
1913 if (l->modification_of_pic_nums_idc == 3)
1916 /* 8.2.4.3.1 - Short-term reference pictures */
1917 if (l->modification_of_pic_nums_idc == 0 || l->modification_of_pic_nums_idc == 1) {
1918 gint32 abs_diff_pic_num = l->value.abs_diff_pic_num_minus1 + 1;
1919 gint32 picNum, picNumNoWrap;
1922 if (l->modification_of_pic_nums_idc == 0) {
1923 picNumNoWrap = picNumPred - abs_diff_pic_num;
1924 if (picNumNoWrap < 0)
1925 picNumNoWrap += MaxPicNum;
1930 picNumNoWrap = picNumPred + abs_diff_pic_num;
1931 if (picNumNoWrap >= MaxPicNum)
1932 picNumNoWrap -= MaxPicNum;
1934 picNumPred = picNumNoWrap;
1937 picNum = picNumNoWrap;
1938 if (picNum > CurrPicNum)
1939 picNum -= MaxPicNum;
1942 for (j = num_refs; j > ref_list_idx; j--)
1943 ref_list[j] = ref_list[j - 1];
1944 found_ref_idx = find_short_term_reference(decoder, picNum);
1945 ref_list[ref_list_idx++] =
1946 found_ref_idx >= 0 ? priv->short_ref[found_ref_idx] : NULL;
1948 for (j = ref_list_idx; j <= num_refs; j++) {
1953 GST_VAAPI_PICTURE_IS_SHORT_TERM_REFERENCE(ref_list[j]) ?
1954 ref_list[j]->pic_num : MaxPicNum;
1955 if (PicNumF != picNum)
1956 ref_list[n++] = ref_list[j];
1960 /* 8.2.4.3.2 - Long-term reference pictures */
1963 for (j = num_refs; j > ref_list_idx; j--)
1964 ref_list[j] = ref_list[j - 1];
1966 find_long_term_reference(decoder, l->value.long_term_pic_num);
1967 ref_list[ref_list_idx++] =
1968 found_ref_idx >= 0 ? priv->long_ref[found_ref_idx] : NULL;
1970 for (j = ref_list_idx; j <= num_refs; j++) {
1971 gint32 LongTermPicNumF;
1975 GST_VAAPI_PICTURE_IS_LONG_TERM_REFERENCE(ref_list[j]) ?
1976 ref_list[j]->long_term_pic_num : INT_MAX;
1977 if (LongTermPicNumF != l->value.long_term_pic_num)
1978 ref_list[n++] = ref_list[j];
1984 for (i = 0; i < num_refs; i++)
1986 GST_ERROR("list %u entry %u is empty", list, i);
1988 *ref_list_count_ptr = num_refs;
1991 /* 8.2.4.3 - Modification process for reference picture lists */
1993 exec_picture_refs_modification(
1994 GstVaapiDecoderH264 *decoder,
1995 GstVaapiPictureH264 *picture,
1996 GstH264SliceHdr *slice_hdr
1999 GST_DEBUG("execute ref_pic_list_modification()");
2002 if (!GST_H264_IS_I_SLICE(slice_hdr) && !GST_H264_IS_SI_SLICE(slice_hdr) &&
2003 slice_hdr->ref_pic_list_modification_flag_l0)
2004 exec_picture_refs_modification_1(decoder, picture, slice_hdr, 0);
2007 if (GST_H264_IS_B_SLICE(slice_hdr) &&
2008 slice_hdr->ref_pic_list_modification_flag_l1)
2009 exec_picture_refs_modification_1(decoder, picture, slice_hdr, 1);
2013 init_picture_ref_lists(GstVaapiDecoderH264 *decoder)
2015 GstVaapiDecoderH264Private * const priv = decoder->priv;
2016 guint i, j, short_ref_count, long_ref_count;
2018 short_ref_count = 0;
2020 if (GST_VAAPI_PICTURE_IS_FRAME(priv->current_picture)) {
2021 for (i = 0; i < priv->dpb_count; i++) {
2022 GstVaapiFrameStore * const fs = priv->dpb[i];
2023 GstVaapiPictureH264 *picture;
2024 if (!gst_vaapi_frame_store_has_frame(fs))
2026 picture = fs->buffers[0];
2027 if (GST_VAAPI_PICTURE_IS_SHORT_TERM_REFERENCE(picture))
2028 priv->short_ref[short_ref_count++] = picture;
2029 else if (GST_VAAPI_PICTURE_IS_LONG_TERM_REFERENCE(picture))
2030 priv->long_ref[long_ref_count++] = picture;
2031 picture->structure = GST_VAAPI_PICTURE_STRUCTURE_FRAME;
2032 picture->other_field = fs->buffers[1];
2036 for (i = 0; i < priv->dpb_count; i++) {
2037 GstVaapiFrameStore * const fs = priv->dpb[i];
2038 for (j = 0; j < fs->num_buffers; j++) {
2039 GstVaapiPictureH264 * const picture = fs->buffers[j];
2040 if (GST_VAAPI_PICTURE_IS_SHORT_TERM_REFERENCE(picture))
2041 priv->short_ref[short_ref_count++] = picture;
2042 else if (GST_VAAPI_PICTURE_IS_LONG_TERM_REFERENCE(picture))
2043 priv->long_ref[long_ref_count++] = picture;
2044 picture->structure = picture->base.structure;
2045 picture->other_field = fs->buffers[j ^ 1];
2050 for (i = short_ref_count; i < priv->short_ref_count; i++)
2051 priv->short_ref[i] = NULL;
2052 priv->short_ref_count = short_ref_count;
2054 for (i = long_ref_count; i < priv->long_ref_count; i++)
2055 priv->long_ref[i] = NULL;
2056 priv->long_ref_count = long_ref_count;
2061 GstVaapiDecoderH264 *decoder,
2062 GstVaapiPictureH264 *picture,
2063 GstH264SliceHdr *slice_hdr
2066 GstVaapiDecoderH264Private * const priv = decoder->priv;
2067 GstVaapiPicture * const base_picture = &picture->base;
2070 init_picture_ref_lists(decoder);
2071 init_picture_refs_pic_num(decoder, picture, slice_hdr);
2073 priv->RefPicList0_count = 0;
2074 priv->RefPicList1_count = 0;
2076 switch (base_picture->type) {
2077 case GST_VAAPI_PICTURE_TYPE_P:
2078 case GST_VAAPI_PICTURE_TYPE_SP:
2079 init_picture_refs_p_slice(decoder, picture, slice_hdr);
2081 case GST_VAAPI_PICTURE_TYPE_B:
2082 init_picture_refs_b_slice(decoder, picture, slice_hdr);
2088 exec_picture_refs_modification(decoder, picture, slice_hdr);
2090 switch (base_picture->type) {
2091 case GST_VAAPI_PICTURE_TYPE_B:
2092 num_refs = 1 + slice_hdr->num_ref_idx_l1_active_minus1;
2093 for (i = priv->RefPicList1_count; i < num_refs; i++)
2094 priv->RefPicList1[i] = NULL;
2095 priv->RefPicList1_count = num_refs;
2098 case GST_VAAPI_PICTURE_TYPE_P:
2099 case GST_VAAPI_PICTURE_TYPE_SP:
2100 num_refs = 1 + slice_hdr->num_ref_idx_l0_active_minus1;
2101 for (i = priv->RefPicList0_count; i < num_refs; i++)
2102 priv->RefPicList0[i] = NULL;
2103 priv->RefPicList0_count = num_refs;
2112 GstVaapiDecoderH264 *decoder,
2113 GstVaapiPictureH264 *picture,
2114 GstH264SliceHdr *slice_hdr,
2115 GstH264NalUnit *nalu
2118 GstVaapiDecoderH264Private * const priv = decoder->priv;
2119 GstVaapiPicture * const base_picture = &picture->base;
2121 priv->prev_frame_num = priv->frame_num;
2122 priv->frame_num = slice_hdr->frame_num;
2123 picture->frame_num = priv->frame_num;
2124 picture->frame_num_wrap = priv->frame_num;
2125 picture->output_flag = TRUE; /* XXX: conformant to Annex A only */
2126 base_picture->pts = gst_adapter_prev_timestamp(priv->adapter, NULL);
2128 /* Reset decoder state for IDR pictures */
2129 if (nalu->type == GST_H264_NAL_SLICE_IDR) {
2131 GST_VAAPI_PICTURE_FLAG_SET(picture, GST_VAAPI_PICTURE_FLAG_IDR);
2135 /* Initialize slice type */
2136 switch (slice_hdr->type % 5) {
2137 case GST_H264_P_SLICE:
2138 base_picture->type = GST_VAAPI_PICTURE_TYPE_P;
2140 case GST_H264_B_SLICE:
2141 base_picture->type = GST_VAAPI_PICTURE_TYPE_B;
2143 case GST_H264_I_SLICE:
2144 base_picture->type = GST_VAAPI_PICTURE_TYPE_I;
2146 case GST_H264_SP_SLICE:
2147 base_picture->type = GST_VAAPI_PICTURE_TYPE_SP;
2149 case GST_H264_SI_SLICE:
2150 base_picture->type = GST_VAAPI_PICTURE_TYPE_SI;
2154 /* Initialize picture structure */
2155 if (!slice_hdr->field_pic_flag)
2156 base_picture->structure = GST_VAAPI_PICTURE_STRUCTURE_FRAME;
2158 GST_VAAPI_PICTURE_FLAG_SET(picture, GST_VAAPI_PICTURE_FLAG_INTERLACED);
2159 if (!slice_hdr->bottom_field_flag)
2160 base_picture->structure = GST_VAAPI_PICTURE_STRUCTURE_TOP_FIELD;
2162 base_picture->structure = GST_VAAPI_PICTURE_STRUCTURE_BOTTOM_FIELD;
2164 picture->structure = base_picture->structure;
2166 /* Initialize reference flags */
2167 if (nalu->ref_idc) {
2168 GstH264DecRefPicMarking * const dec_ref_pic_marking =
2169 &slice_hdr->dec_ref_pic_marking;
2171 if (GST_VAAPI_PICTURE_IS_IDR(picture) &&
2172 dec_ref_pic_marking->long_term_reference_flag)
2173 GST_VAAPI_PICTURE_FLAG_SET(picture,
2174 GST_VAAPI_PICTURE_FLAG_LONG_TERM_REFERENCE);
2176 GST_VAAPI_PICTURE_FLAG_SET(picture,
2177 GST_VAAPI_PICTURE_FLAG_SHORT_TERM_REFERENCE);
2180 init_picture_poc(decoder, picture, slice_hdr);
2181 init_picture_refs(decoder, picture, slice_hdr);
2185 /* 8.2.5.3 - Sliding window decoded reference picture marking process */
2187 exec_ref_pic_marking_sliding_window(GstVaapiDecoderH264 *decoder)
2189 GstVaapiDecoderH264Private * const priv = decoder->priv;
2190 GstH264PPS * const pps = priv->current_picture->pps;
2191 GstH264SPS * const sps = pps->sequence;
2192 GstVaapiPictureH264 *ref_picture;
2193 guint i, m, max_num_ref_frames;
2195 GST_DEBUG("reference picture marking process (sliding window)");
2197 if (!GST_VAAPI_PICTURE_IS_FIRST_FIELD(priv->current_picture))
2200 max_num_ref_frames = sps->num_ref_frames;
2201 if (max_num_ref_frames == 0)
2202 max_num_ref_frames = 1;
2203 if (!GST_VAAPI_PICTURE_IS_FRAME(priv->current_picture))
2204 max_num_ref_frames <<= 1;
2206 if (priv->short_ref_count + priv->long_ref_count < max_num_ref_frames)
2208 if (priv->short_ref_count < 1)
2211 for (m = 0, i = 1; i < priv->short_ref_count; i++) {
2212 GstVaapiPictureH264 * const picture = priv->short_ref[i];
2213 if (picture->frame_num_wrap < priv->short_ref[m]->frame_num_wrap)
2217 ref_picture = priv->short_ref[m];
2218 gst_vaapi_picture_h264_set_reference(ref_picture, 0, TRUE);
2219 ARRAY_REMOVE_INDEX(priv->short_ref, m);
2221 /* Both fields need to be marked as "unused for reference", so
2222 remove the other field from the short_ref[] list as well */
2223 if (!GST_VAAPI_PICTURE_IS_FRAME(priv->current_picture) && ref_picture->other_field) {
2224 for (i = 0; i < priv->short_ref_count; i++) {
2225 if (priv->short_ref[i] == ref_picture->other_field) {
2226 ARRAY_REMOVE_INDEX(priv->short_ref, i);
2234 static inline gint32
2235 get_picNumX(GstVaapiPictureH264 *picture, GstH264RefPicMarking *ref_pic_marking)
2239 if (GST_VAAPI_PICTURE_IS_FRAME(picture))
2240 pic_num = picture->frame_num_wrap;
2242 pic_num = 2 * picture->frame_num_wrap + 1;
2243 pic_num -= ref_pic_marking->difference_of_pic_nums_minus1 + 1;
2247 /* 8.2.5.4.1. Mark short-term reference picture as "unused for reference" */
2249 exec_ref_pic_marking_adaptive_mmco_1(
2250 GstVaapiDecoderH264 *decoder,
2251 GstVaapiPictureH264 *picture,
2252 GstH264RefPicMarking *ref_pic_marking
2255 GstVaapiDecoderH264Private * const priv = decoder->priv;
2258 picNumX = get_picNumX(picture, ref_pic_marking);
2259 i = find_short_term_reference(decoder, picNumX);
2263 gst_vaapi_picture_h264_set_reference(priv->short_ref[i], 0,
2264 GST_VAAPI_PICTURE_IS_FRAME(picture));
2265 ARRAY_REMOVE_INDEX(priv->short_ref, i);
2268 /* 8.2.5.4.2. Mark long-term reference picture as "unused for reference" */
2270 exec_ref_pic_marking_adaptive_mmco_2(
2271 GstVaapiDecoderH264 *decoder,
2272 GstVaapiPictureH264 *picture,
2273 GstH264RefPicMarking *ref_pic_marking
2276 GstVaapiDecoderH264Private * const priv = decoder->priv;
2279 i = find_long_term_reference(decoder, ref_pic_marking->long_term_pic_num);
2283 gst_vaapi_picture_h264_set_reference(priv->long_ref[i], 0,
2284 GST_VAAPI_PICTURE_IS_FRAME(picture));
2285 ARRAY_REMOVE_INDEX(priv->long_ref, i);
2288 /* 8.2.5.4.3. Assign LongTermFrameIdx to a short-term reference picture */
2290 exec_ref_pic_marking_adaptive_mmco_3(
2291 GstVaapiDecoderH264 *decoder,
2292 GstVaapiPictureH264 *picture,
2293 GstH264RefPicMarking *ref_pic_marking
2296 GstVaapiDecoderH264Private * const priv = decoder->priv;
2297 GstVaapiPictureH264 *ref_picture;
2300 for (i = 0; i < priv->long_ref_count; i++) {
2301 if (priv->long_ref[i]->long_term_frame_idx == ref_pic_marking->long_term_frame_idx)
2304 if (i != priv->long_ref_count) {
2305 gst_vaapi_picture_h264_set_reference(priv->long_ref[i], 0, TRUE);
2306 ARRAY_REMOVE_INDEX(priv->long_ref, i);
2309 picNumX = get_picNumX(picture, ref_pic_marking);
2310 i = find_short_term_reference(decoder, picNumX);
2314 ref_picture = priv->short_ref[i];
2315 ARRAY_REMOVE_INDEX(priv->short_ref, i);
2316 priv->long_ref[priv->long_ref_count++] = ref_picture;
2318 ref_picture->long_term_frame_idx = ref_pic_marking->long_term_frame_idx;
2319 gst_vaapi_picture_h264_set_reference(ref_picture,
2320 GST_VAAPI_PICTURE_FLAG_LONG_TERM_REFERENCE,
2321 GST_VAAPI_PICTURE_IS_FRAME(picture));
2324 /* 8.2.5.4.4. Mark pictures with LongTermFramIdx > max_long_term_frame_idx
2325 * as "unused for reference" */
2327 exec_ref_pic_marking_adaptive_mmco_4(
2328 GstVaapiDecoderH264 *decoder,
2329 GstVaapiPictureH264 *picture,
2330 GstH264RefPicMarking *ref_pic_marking
2333 GstVaapiDecoderH264Private * const priv = decoder->priv;
2334 gint32 i, long_term_frame_idx;
2336 long_term_frame_idx = ref_pic_marking->max_long_term_frame_idx_plus1 - 1;
2338 for (i = 0; i < priv->long_ref_count; i++) {
2339 if (priv->long_ref[i]->long_term_frame_idx <= long_term_frame_idx)
2341 gst_vaapi_picture_h264_set_reference(priv->long_ref[i], 0, FALSE);
2342 ARRAY_REMOVE_INDEX(priv->long_ref, i);
2347 /* 8.2.5.4.5. Mark all reference pictures as "unused for reference" */
2349 exec_ref_pic_marking_adaptive_mmco_5(
2350 GstVaapiDecoderH264 *decoder,
2351 GstVaapiPictureH264 *picture,
2352 GstH264RefPicMarking *ref_pic_marking
2355 GstVaapiDecoderH264Private * const priv = decoder->priv;
2359 priv->prev_pic_has_mmco5 = TRUE;
2361 /* The picture shall be inferred to have had frame_num equal to 0 (7.4.3) */
2362 priv->frame_num = 0;
2363 priv->frame_num_offset = 0;
2364 picture->frame_num = 0;
2366 /* Update TopFieldOrderCnt and BottomFieldOrderCnt (8.2.1) */
2367 if (picture->structure != GST_VAAPI_PICTURE_STRUCTURE_BOTTOM_FIELD)
2368 picture->field_poc[TOP_FIELD] -= picture->base.poc;
2369 if (picture->structure != GST_VAAPI_PICTURE_STRUCTURE_TOP_FIELD)
2370 picture->field_poc[BOTTOM_FIELD] -= picture->base.poc;
2371 picture->base.poc = 0;
2374 /* 8.2.5.4.6. Assign a long-term frame index to the current picture */
2376 exec_ref_pic_marking_adaptive_mmco_6(
2377 GstVaapiDecoderH264 *decoder,
2378 GstVaapiPictureH264 *picture,
2379 GstH264RefPicMarking *ref_pic_marking
2382 picture->long_term_frame_idx = ref_pic_marking->long_term_frame_idx;
2383 gst_vaapi_picture_h264_set_reference(picture,
2384 GST_VAAPI_PICTURE_FLAG_LONG_TERM_REFERENCE, FALSE);
2387 /* 8.2.5.4. Adaptive memory control decoded reference picture marking process */
2389 exec_ref_pic_marking_adaptive(
2390 GstVaapiDecoderH264 *decoder,
2391 GstVaapiPictureH264 *picture,
2392 GstH264DecRefPicMarking *dec_ref_pic_marking
2397 GST_DEBUG("reference picture marking process (adaptive memory control)");
2399 typedef void (*exec_ref_pic_marking_adaptive_mmco_func)(
2400 GstVaapiDecoderH264 *decoder,
2401 GstVaapiPictureH264 *picture,
2402 GstH264RefPicMarking *ref_pic_marking
2405 static const exec_ref_pic_marking_adaptive_mmco_func mmco_funcs[] = {
2407 exec_ref_pic_marking_adaptive_mmco_1,
2408 exec_ref_pic_marking_adaptive_mmco_2,
2409 exec_ref_pic_marking_adaptive_mmco_3,
2410 exec_ref_pic_marking_adaptive_mmco_4,
2411 exec_ref_pic_marking_adaptive_mmco_5,
2412 exec_ref_pic_marking_adaptive_mmco_6,
2415 for (i = 0; i < dec_ref_pic_marking->n_ref_pic_marking; i++) {
2416 GstH264RefPicMarking * const ref_pic_marking =
2417 &dec_ref_pic_marking->ref_pic_marking[i];
2419 const guint mmco = ref_pic_marking->memory_management_control_operation;
2420 if (mmco < G_N_ELEMENTS(mmco_funcs) && mmco_funcs[mmco])
2421 mmco_funcs[mmco](decoder, picture, ref_pic_marking);
2423 GST_ERROR("unhandled MMCO %u", mmco);
2430 /* 8.2.5 - Execute reference picture marking process */
2432 exec_ref_pic_marking(GstVaapiDecoderH264 *decoder, GstVaapiPictureH264 *picture)
2434 GstVaapiDecoderH264Private * const priv = decoder->priv;
2436 priv->prev_pic_has_mmco5 = FALSE;
2437 priv->prev_pic_structure = picture->structure;
2439 if (!GST_VAAPI_PICTURE_IS_REFERENCE(picture))
2442 if (!GST_VAAPI_PICTURE_IS_IDR(picture)) {
2443 GstVaapiSliceH264 * const slice =
2444 gst_vaapi_picture_h264_get_last_slice(picture);
2445 GstH264DecRefPicMarking * const dec_ref_pic_marking =
2446 &slice->slice_hdr.dec_ref_pic_marking;
2447 if (dec_ref_pic_marking->adaptive_ref_pic_marking_mode_flag) {
2448 if (!exec_ref_pic_marking_adaptive(decoder, picture, dec_ref_pic_marking))
2452 if (!exec_ref_pic_marking_sliding_window(decoder))
2460 vaapi_init_picture(VAPictureH264 *pic)
2462 pic->picture_id = VA_INVALID_ID;
2464 pic->flags = VA_PICTURE_H264_INVALID;
2465 pic->TopFieldOrderCnt = 0;
2466 pic->BottomFieldOrderCnt = 0;
2470 vaapi_fill_picture(VAPictureH264 *pic, GstVaapiPictureH264 *picture,
2471 guint picture_structure)
2473 if (!picture_structure)
2474 picture_structure = picture->structure;
2476 pic->picture_id = picture->base.surface_id;
2479 if (GST_VAAPI_PICTURE_IS_LONG_TERM_REFERENCE(picture)) {
2480 pic->flags |= VA_PICTURE_H264_LONG_TERM_REFERENCE;
2481 pic->frame_idx = picture->long_term_frame_idx;
2484 if (GST_VAAPI_PICTURE_IS_SHORT_TERM_REFERENCE(picture))
2485 pic->flags |= VA_PICTURE_H264_SHORT_TERM_REFERENCE;
2486 pic->frame_idx = picture->frame_num;
2489 switch (picture_structure) {
2490 case GST_VAAPI_PICTURE_STRUCTURE_FRAME:
2491 pic->TopFieldOrderCnt = picture->field_poc[TOP_FIELD];
2492 pic->BottomFieldOrderCnt = picture->field_poc[BOTTOM_FIELD];
2494 case GST_VAAPI_PICTURE_STRUCTURE_TOP_FIELD:
2495 pic->flags |= VA_PICTURE_H264_TOP_FIELD;
2496 pic->TopFieldOrderCnt = picture->field_poc[TOP_FIELD];
2497 pic->BottomFieldOrderCnt = 0;
2499 case GST_VAAPI_PICTURE_STRUCTURE_BOTTOM_FIELD:
2500 pic->flags |= VA_PICTURE_H264_BOTTOM_FIELD;
2501 pic->BottomFieldOrderCnt = picture->field_poc[BOTTOM_FIELD];
2502 pic->TopFieldOrderCnt = 0;
2509 GstVaapiDecoderH264 *decoder,
2510 GstVaapiPictureH264 *picture,
2511 GstH264SliceHdr *slice_hdr,
2512 GstH264NalUnit *nalu
2515 GstVaapiDecoderH264Private * const priv = decoder->priv;
2516 GstVaapiPicture * const base_picture = &picture->base;
2517 GstH264PPS * const pps = picture->pps;
2518 GstH264SPS * const sps = pps->sequence;
2519 VAPictureParameterBufferH264 * const pic_param = base_picture->param;
2522 /* Fill in VAPictureParameterBufferH264 */
2523 vaapi_fill_picture(&pic_param->CurrPic, picture, 0);
2525 for (i = 0, n = 0; i < priv->dpb_count; i++) {
2526 GstVaapiFrameStore * const fs = priv->dpb[i];
2527 if (gst_vaapi_frame_store_has_reference(fs))
2528 vaapi_fill_picture(&pic_param->ReferenceFrames[n++],
2529 fs->buffers[0], fs->structure);
2531 for (; n < G_N_ELEMENTS(pic_param->ReferenceFrames); n++)
2532 vaapi_init_picture(&pic_param->ReferenceFrames[n]);
2534 #define COPY_FIELD(s, f) \
2535 pic_param->f = (s)->f
2537 #define COPY_BFM(a, s, f) \
2538 pic_param->a.bits.f = (s)->f
2540 pic_param->picture_width_in_mbs_minus1 = priv->mb_width - 1;
2541 pic_param->picture_height_in_mbs_minus1 = priv->mb_height - 1;
2542 pic_param->frame_num = priv->frame_num;
2544 COPY_FIELD(sps, bit_depth_luma_minus8);
2545 COPY_FIELD(sps, bit_depth_chroma_minus8);
2546 COPY_FIELD(sps, num_ref_frames);
2547 COPY_FIELD(pps, num_slice_groups_minus1);
2548 COPY_FIELD(pps, slice_group_map_type);
2549 COPY_FIELD(pps, slice_group_change_rate_minus1);
2550 COPY_FIELD(pps, pic_init_qp_minus26);
2551 COPY_FIELD(pps, pic_init_qs_minus26);
2552 COPY_FIELD(pps, chroma_qp_index_offset);
2553 COPY_FIELD(pps, second_chroma_qp_index_offset);
2555 pic_param->seq_fields.value = 0; /* reset all bits */
2556 pic_param->seq_fields.bits.residual_colour_transform_flag = sps->separate_colour_plane_flag;
2557 pic_param->seq_fields.bits.MinLumaBiPredSize8x8 = sps->level_idc >= 31; /* A.3.3.2 */
2559 COPY_BFM(seq_fields, sps, chroma_format_idc);
2560 COPY_BFM(seq_fields, sps, gaps_in_frame_num_value_allowed_flag);
2561 COPY_BFM(seq_fields, sps, frame_mbs_only_flag);
2562 COPY_BFM(seq_fields, sps, mb_adaptive_frame_field_flag);
2563 COPY_BFM(seq_fields, sps, direct_8x8_inference_flag);
2564 COPY_BFM(seq_fields, sps, log2_max_frame_num_minus4);
2565 COPY_BFM(seq_fields, sps, pic_order_cnt_type);
2566 COPY_BFM(seq_fields, sps, log2_max_pic_order_cnt_lsb_minus4);
2567 COPY_BFM(seq_fields, sps, delta_pic_order_always_zero_flag);
2569 pic_param->pic_fields.value = 0; /* reset all bits */
2570 pic_param->pic_fields.bits.field_pic_flag = slice_hdr->field_pic_flag;
2571 pic_param->pic_fields.bits.reference_pic_flag = GST_VAAPI_PICTURE_IS_REFERENCE(picture);
2573 COPY_BFM(pic_fields, pps, entropy_coding_mode_flag);
2574 COPY_BFM(pic_fields, pps, weighted_pred_flag);
2575 COPY_BFM(pic_fields, pps, weighted_bipred_idc);
2576 COPY_BFM(pic_fields, pps, transform_8x8_mode_flag);
2577 COPY_BFM(pic_fields, pps, constrained_intra_pred_flag);
2578 COPY_BFM(pic_fields, pps, pic_order_present_flag);
2579 COPY_BFM(pic_fields, pps, deblocking_filter_control_present_flag);
2580 COPY_BFM(pic_fields, pps, redundant_pic_cnt_present_flag);
2584 /* Detection of the first VCL NAL unit of a primary coded picture (7.4.1.2.4) */
2587 GstVaapiDecoderH264 *decoder,
2588 GstH264NalUnit *nalu,
2589 GstH264SliceHdr *slice_hdr
2592 GstVaapiDecoderH264Private * const priv = decoder->priv;
2593 GstH264PPS * const pps = slice_hdr->pps;
2594 GstH264SPS * const sps = pps->sequence;
2595 GstVaapiSliceH264 *slice;
2596 GstH264SliceHdr *prev_slice_hdr;
2598 if (!priv->current_picture)
2601 slice = gst_vaapi_picture_h264_get_last_slice(priv->current_picture);
2604 prev_slice_hdr = &slice->slice_hdr;
2606 #define CHECK_EXPR(expr, field_name) do { \
2608 GST_DEBUG(field_name " differs in value"); \
2613 #define CHECK_VALUE(new_slice_hdr, old_slice_hdr, field) \
2614 CHECK_EXPR(((new_slice_hdr)->field == (old_slice_hdr)->field), #field)
2616 /* frame_num differs in value, regardless of inferred values to 0 */
2617 CHECK_VALUE(slice_hdr, prev_slice_hdr, frame_num);
2619 /* pic_parameter_set_id differs in value */
2620 CHECK_VALUE(slice_hdr, prev_slice_hdr, pps);
2622 /* field_pic_flag differs in value */
2623 CHECK_VALUE(slice_hdr, prev_slice_hdr, field_pic_flag);
2625 /* bottom_field_flag is present in both and differs in value */
2626 if (slice_hdr->field_pic_flag && prev_slice_hdr->field_pic_flag)
2627 CHECK_VALUE(slice_hdr, prev_slice_hdr, bottom_field_flag);
2629 /* nal_ref_idc differs in value with one of the nal_ref_idc values is 0 */
2630 CHECK_EXPR(((GST_VAAPI_PICTURE_IS_REFERENCE(priv->current_picture) ^
2631 (nalu->ref_idc != 0)) == 0), "nal_ref_idc");
2633 /* POC type is 0 for both and either pic_order_cnt_lsb differs in
2634 value or delta_pic_order_cnt_bottom differs in value */
2635 if (sps->pic_order_cnt_type == 0) {
2636 CHECK_VALUE(slice_hdr, prev_slice_hdr, pic_order_cnt_lsb);
2637 if (pps->pic_order_present_flag && !slice_hdr->field_pic_flag)
2638 CHECK_VALUE(slice_hdr, prev_slice_hdr, delta_pic_order_cnt_bottom);
2641 /* POC type is 1 for both and either delta_pic_order_cnt[0]
2642 differs in value or delta_pic_order_cnt[1] differs in value */
2643 else if (sps->pic_order_cnt_type == 1) {
2644 CHECK_VALUE(slice_hdr, prev_slice_hdr, delta_pic_order_cnt[0]);
2645 CHECK_VALUE(slice_hdr, prev_slice_hdr, delta_pic_order_cnt[1]);
2648 /* IdrPicFlag differs in value */
2649 CHECK_EXPR(((GST_VAAPI_PICTURE_IS_IDR(priv->current_picture) ^
2650 (nalu->type == GST_H264_NAL_SLICE_IDR)) == 0), "IdrPicFlag");
2652 /* IdrPicFlag is equal to 1 for both and idr_pic_id differs in value */
2653 if (GST_VAAPI_PICTURE_IS_IDR(priv->current_picture))
2654 CHECK_VALUE(slice_hdr, prev_slice_hdr, idr_pic_id);
2661 static GstVaapiDecoderStatus
2662 decode_picture(GstVaapiDecoderH264 *decoder, GstH264NalUnit *nalu, GstH264SliceHdr *slice_hdr)
2664 GstVaapiDecoderH264Private * const priv = decoder->priv;
2665 GstVaapiPictureH264 *picture;
2666 GstVaapiDecoderStatus status;
2667 GstH264PPS * const pps = slice_hdr->pps;
2668 GstH264SPS * const sps = pps->sequence;
2670 status = decode_current_picture(decoder);
2671 if (status != GST_VAAPI_DECODER_STATUS_SUCCESS)
2674 status = ensure_context(decoder, sps);
2675 if (status != GST_VAAPI_DECODER_STATUS_SUCCESS)
2678 if (priv->current_picture) {
2679 /* Re-use current picture where the first field was decoded */
2680 picture = gst_vaapi_picture_h264_new_field(priv->current_picture);
2682 GST_ERROR("failed to allocate field picture");
2683 return GST_VAAPI_DECODER_STATUS_ERROR_ALLOCATION_FAILED;
2687 /* Create new picture */
2688 picture = gst_vaapi_picture_h264_new(decoder);
2690 GST_ERROR("failed to allocate picture");
2691 return GST_VAAPI_DECODER_STATUS_ERROR_ALLOCATION_FAILED;
2694 gst_vaapi_picture_replace(&priv->current_picture, picture);
2695 gst_vaapi_picture_unref(picture);
2699 status = ensure_quant_matrix(decoder, picture);
2700 if (status != GST_VAAPI_DECODER_STATUS_SUCCESS) {
2701 GST_ERROR("failed to reset quantizer matrix");
2705 if (!init_picture(decoder, picture, slice_hdr, nalu))
2706 return GST_VAAPI_DECODER_STATUS_ERROR_UNKNOWN;
2707 if (!fill_picture(decoder, picture, slice_hdr, nalu))
2708 return GST_VAAPI_DECODER_STATUS_ERROR_UNKNOWN;
2709 return GST_VAAPI_DECODER_STATUS_SUCCESS;
2713 get_slice_data_bit_offset(GstH264SliceHdr *slice_hdr, GstH264NalUnit *nalu)
2717 epb_count = slice_hdr->n_emulation_prevention_bytes;
2718 return 8 /* nal_unit_type */ + slice_hdr->header_size - epb_count * 8;
2722 fill_pred_weight_table(GstVaapiDecoderH264 *decoder, GstVaapiSliceH264 *slice)
2724 GstH264SliceHdr * const slice_hdr = &slice->slice_hdr;
2725 GstH264PPS * const pps = slice_hdr->pps;
2726 GstH264SPS * const sps = pps->sequence;
2727 GstH264PredWeightTable * const w = &slice_hdr->pred_weight_table;
2728 VASliceParameterBufferH264 * const slice_param = slice->base.param;
2729 guint num_weight_tables = 0;
2732 if (pps->weighted_pred_flag &&
2733 (GST_H264_IS_P_SLICE(slice_hdr) || GST_H264_IS_SP_SLICE(slice_hdr)))
2734 num_weight_tables = 1;
2735 else if (pps->weighted_bipred_idc == 1 && GST_H264_IS_B_SLICE(slice_hdr))
2736 num_weight_tables = 2;
2738 num_weight_tables = 0;
2740 slice_param->luma_log2_weight_denom = w->luma_log2_weight_denom;
2741 slice_param->chroma_log2_weight_denom = w->chroma_log2_weight_denom;
2742 slice_param->luma_weight_l0_flag = 0;
2743 slice_param->chroma_weight_l0_flag = 0;
2744 slice_param->luma_weight_l1_flag = 0;
2745 slice_param->chroma_weight_l1_flag = 0;
2747 if (num_weight_tables < 1)
2750 slice_param->luma_weight_l0_flag = 1;
2751 for (i = 0; i <= slice_param->num_ref_idx_l0_active_minus1; i++) {
2752 slice_param->luma_weight_l0[i] = w->luma_weight_l0[i];
2753 slice_param->luma_offset_l0[i] = w->luma_offset_l0[i];
2756 slice_param->chroma_weight_l0_flag = sps->chroma_array_type != 0;
2757 if (slice_param->chroma_weight_l0_flag) {
2758 for (i = 0; i <= slice_param->num_ref_idx_l0_active_minus1; i++) {
2759 for (j = 0; j < 2; j++) {
2760 slice_param->chroma_weight_l0[i][j] = w->chroma_weight_l0[i][j];
2761 slice_param->chroma_offset_l0[i][j] = w->chroma_offset_l0[i][j];
2766 if (num_weight_tables < 2)
2769 slice_param->luma_weight_l1_flag = 1;
2770 for (i = 0; i <= slice_param->num_ref_idx_l1_active_minus1; i++) {
2771 slice_param->luma_weight_l1[i] = w->luma_weight_l1[i];
2772 slice_param->luma_offset_l1[i] = w->luma_offset_l1[i];
2775 slice_param->chroma_weight_l1_flag = sps->chroma_array_type != 0;
2776 if (slice_param->chroma_weight_l1_flag) {
2777 for (i = 0; i <= slice_param->num_ref_idx_l1_active_minus1; i++) {
2778 for (j = 0; j < 2; j++) {
2779 slice_param->chroma_weight_l1[i][j] = w->chroma_weight_l1[i][j];
2780 slice_param->chroma_offset_l1[i][j] = w->chroma_offset_l1[i][j];
2788 fill_RefPicList(GstVaapiDecoderH264 *decoder, GstVaapiSliceH264 *slice)
2790 GstVaapiDecoderH264Private * const priv = decoder->priv;
2791 GstH264SliceHdr * const slice_hdr = &slice->slice_hdr;
2792 VASliceParameterBufferH264 * const slice_param = slice->base.param;
2793 guint i, num_ref_lists = 0;
2795 slice_param->num_ref_idx_l0_active_minus1 = 0;
2796 slice_param->num_ref_idx_l1_active_minus1 = 0;
2798 if (GST_H264_IS_B_SLICE(slice_hdr))
2800 else if (GST_H264_IS_I_SLICE(slice_hdr))
2805 if (num_ref_lists < 1)
2808 slice_param->num_ref_idx_l0_active_minus1 =
2809 slice_hdr->num_ref_idx_l0_active_minus1;
2811 for (i = 0; i < priv->RefPicList0_count && priv->RefPicList0[i]; i++)
2812 vaapi_fill_picture(&slice_param->RefPicList0[i], priv->RefPicList0[i], 0);
2813 for (; i <= slice_param->num_ref_idx_l0_active_minus1; i++)
2814 vaapi_init_picture(&slice_param->RefPicList0[i]);
2816 if (num_ref_lists < 2)
2819 slice_param->num_ref_idx_l1_active_minus1 =
2820 slice_hdr->num_ref_idx_l1_active_minus1;
2822 for (i = 0; i < priv->RefPicList1_count && priv->RefPicList1[i]; i++)
2823 vaapi_fill_picture(&slice_param->RefPicList1[i], priv->RefPicList1[i], 0);
2824 for (; i <= slice_param->num_ref_idx_l1_active_minus1; i++)
2825 vaapi_init_picture(&slice_param->RefPicList1[i]);
2831 GstVaapiDecoderH264 *decoder,
2832 GstVaapiSliceH264 *slice,
2833 GstH264NalUnit *nalu
2836 GstH264SliceHdr * const slice_hdr = &slice->slice_hdr;
2837 VASliceParameterBufferH264 * const slice_param = slice->base.param;
2839 /* Fill in VASliceParameterBufferH264 */
2840 slice_param->slice_data_bit_offset = get_slice_data_bit_offset(slice_hdr, nalu);
2841 slice_param->first_mb_in_slice = slice_hdr->first_mb_in_slice;
2842 slice_param->slice_type = slice_hdr->type % 5;
2843 slice_param->direct_spatial_mv_pred_flag = slice_hdr->direct_spatial_mv_pred_flag;
2844 slice_param->cabac_init_idc = slice_hdr->cabac_init_idc;
2845 slice_param->slice_qp_delta = slice_hdr->slice_qp_delta;
2846 slice_param->disable_deblocking_filter_idc = slice_hdr->disable_deblocking_filter_idc;
2847 slice_param->slice_alpha_c0_offset_div2 = slice_hdr->slice_alpha_c0_offset_div2;
2848 slice_param->slice_beta_offset_div2 = slice_hdr->slice_beta_offset_div2;
2850 if (!fill_RefPicList(decoder, slice))
2852 if (!fill_pred_weight_table(decoder, slice))
2857 static GstVaapiDecoderStatus
2858 decode_slice(GstVaapiDecoderH264 *decoder, GstH264NalUnit *nalu)
2860 GstVaapiDecoderH264Private * const priv = decoder->priv;
2861 GstVaapiDecoderStatus status;
2862 GstVaapiPictureH264 *picture;
2863 GstVaapiSliceH264 *slice = NULL;
2864 GstH264SliceHdr *slice_hdr;
2865 GstH264ParserResult result;
2867 GST_DEBUG("slice (%u bytes)", nalu->size);
2869 slice = gst_vaapi_slice_h264_new(
2871 nalu->data + nalu->offset,
2875 GST_ERROR("failed to allocate slice");
2876 return GST_VAAPI_DECODER_STATUS_ERROR_ALLOCATION_FAILED;
2879 slice_hdr = &slice->slice_hdr;
2880 memset(slice_hdr, 0, sizeof(*slice_hdr));
2881 result = gst_h264_parser_parse_slice_hdr(priv->parser, nalu, slice_hdr, TRUE, TRUE);
2882 if (result != GST_H264_PARSER_OK) {
2883 status = get_status(result);
2887 if (is_new_picture(decoder, nalu, slice_hdr)) {
2888 status = decode_picture(decoder, nalu, slice_hdr);
2889 if (status != GST_VAAPI_DECODER_STATUS_SUCCESS)
2892 picture = priv->current_picture;
2894 if (!fill_slice(decoder, slice, nalu)) {
2895 status = GST_VAAPI_DECODER_STATUS_ERROR_UNKNOWN;
2898 gst_vaapi_picture_add_slice(
2899 GST_VAAPI_PICTURE_CAST(picture),
2900 GST_VAAPI_SLICE_CAST(slice)
2902 return GST_VAAPI_DECODER_STATUS_SUCCESS;
2906 gst_mini_object_unref(GST_MINI_OBJECT(slice));
2911 scan_for_start_code(GstAdapter *adapter, guint ofs, guint size, guint32 *scp)
2913 return (gint)gst_adapter_masked_scan_uint32_peek(adapter,
2914 0xffffff00, 0x00000100,
2919 static GstVaapiDecoderStatus
2920 decode_nalu(GstVaapiDecoderH264 *decoder, GstH264NalUnit *nalu)
2922 GstVaapiDecoderH264Private * const priv = decoder->priv;
2923 GstVaapiDecoderStatus status;
2925 switch (nalu->type) {
2926 case GST_H264_NAL_SLICE_IDR:
2927 /* fall-through. IDR specifics are handled in init_picture() */
2928 case GST_H264_NAL_SLICE:
2929 if (!priv->got_sps || !priv->got_pps)
2930 return GST_VAAPI_DECODER_STATUS_SUCCESS;
2931 status = decode_slice(decoder, nalu);
2933 case GST_H264_NAL_SPS:
2934 status = decode_sps(decoder, nalu);
2936 case GST_H264_NAL_PPS:
2937 status = decode_pps(decoder, nalu);
2939 case GST_H264_NAL_SEI:
2940 status = decode_sei(decoder, nalu);
2942 case GST_H264_NAL_SEQ_END:
2943 status = decode_sequence_end(decoder);
2945 case GST_H264_NAL_AU_DELIMITER:
2946 /* skip all Access Unit NALs */
2947 status = GST_VAAPI_DECODER_STATUS_SUCCESS;
2949 case GST_H264_NAL_FILLER_DATA:
2950 /* skip all Filler Data NALs */
2951 status = GST_VAAPI_DECODER_STATUS_SUCCESS;
2954 GST_WARNING("unsupported NAL unit type %d", nalu->type);
2955 status = GST_VAAPI_DECODER_STATUS_ERROR_BITSTREAM_PARSER;
2961 static GstVaapiDecoderStatus
2962 decode_buffer(GstVaapiDecoderH264 *decoder, GstBuffer *buffer)
2964 GstVaapiDecoderH264Private * const priv = decoder->priv;
2965 GstVaapiDecoderStatus status;
2966 GstH264ParserResult result;
2967 GstH264NalUnit nalu;
2970 guint i, buf_size, nalu_size, size;
2974 buf = GST_BUFFER_DATA(buffer);
2975 buf_size = GST_BUFFER_SIZE(buffer);
2976 is_eos = GST_BUFFER_IS_EOS(buffer);
2977 if (buf && buf_size > 0)
2978 gst_adapter_push(priv->adapter, gst_buffer_ref(buffer));
2980 size = gst_adapter_available(priv->adapter);
2983 status = GST_VAAPI_DECODER_STATUS_SUCCESS;
2987 status = gst_vaapi_decoder_check_status(GST_VAAPI_DECODER(decoder));
2988 if (status != GST_VAAPI_DECODER_STATUS_SUCCESS)
2991 status = GST_VAAPI_DECODER_STATUS_ERROR_NO_DATA;
2993 if (size < priv->nal_length_size)
2995 buf = gst_adapter_peek(priv->adapter, priv->nal_length_size);
2998 for (i = 0; i < priv->nal_length_size; i++)
2999 nalu_size = (nalu_size << 8) | buf[i];
3001 buf_size = priv->nal_length_size + nalu_size;
3002 if (size < buf_size)
3004 buffer = gst_adapter_take_buffer(priv->adapter, buf_size);
3007 buf = GST_BUFFER_DATA(buffer);
3008 buf_size = GST_BUFFER_SIZE(buffer);
3010 result = gst_h264_parser_identify_nalu_avc(
3012 buf, 0, buf_size, priv->nal_length_size,
3019 ofs = scan_for_start_code(priv->adapter, 0, size, &start_code);
3022 gst_adapter_flush(priv->adapter, ofs);
3025 ofs = G_UNLIKELY(size < 8) ? -1 :
3026 scan_for_start_code(priv->adapter, 4, size - 4, NULL);
3028 // Assume the whole NAL unit is present if end-of-stream
3033 buffer = gst_adapter_take_buffer(priv->adapter, ofs);
3036 buf = GST_BUFFER_DATA(buffer);
3037 buf_size = GST_BUFFER_SIZE(buffer);
3039 result = gst_h264_parser_identify_nalu_unchecked(
3045 status = get_status(result);
3046 if (status == GST_VAAPI_DECODER_STATUS_SUCCESS)
3047 status = decode_nalu(decoder, &nalu);
3048 gst_buffer_unref(buffer);
3049 } while (status == GST_VAAPI_DECODER_STATUS_SUCCESS);
3051 if (is_eos && (status == GST_VAAPI_DECODER_STATUS_SUCCESS ||
3052 status == GST_VAAPI_DECODER_STATUS_ERROR_NO_DATA))
3053 status = decode_sequence_end(decoder);
3057 static GstVaapiDecoderStatus
3058 decode_codec_data(GstVaapiDecoderH264 *decoder, GstBuffer *buffer)
3060 GstVaapiDecoderH264Private * const priv = decoder->priv;
3061 GstVaapiDecoderStatus status;
3062 GstH264NalUnit nalu;
3063 GstH264ParserResult result;
3066 guint i, ofs, num_sps, num_pps;
3068 buf = GST_BUFFER_DATA(buffer);
3069 buf_size = GST_BUFFER_SIZE(buffer);
3070 if (!buf || buf_size == 0)
3071 return GST_VAAPI_DECODER_STATUS_SUCCESS;
3074 return GST_VAAPI_DECODER_STATUS_ERROR_NO_DATA;
3077 GST_ERROR("failed to decode codec-data, not in avcC format");
3078 return GST_VAAPI_DECODER_STATUS_ERROR_BITSTREAM_PARSER;
3081 priv->nal_length_size = (buf[4] & 0x03) + 1;
3083 num_sps = buf[5] & 0x1f;
3086 for (i = 0; i < num_sps; i++) {
3087 result = gst_h264_parser_identify_nalu_avc(
3089 buf, ofs, buf_size, 2,
3092 if (result != GST_H264_PARSER_OK)
3093 return get_status(result);
3095 status = decode_sps(decoder, &nalu);
3096 if (status != GST_VAAPI_DECODER_STATUS_SUCCESS)
3098 ofs = nalu.offset + nalu.size;
3104 for (i = 0; i < num_pps; i++) {
3105 result = gst_h264_parser_identify_nalu_avc(
3107 buf, ofs, buf_size, 2,
3110 if (result != GST_H264_PARSER_OK)
3111 return get_status(result);
3113 status = decode_pps(decoder, &nalu);
3114 if (status != GST_VAAPI_DECODER_STATUS_SUCCESS)
3116 ofs = nalu.offset + nalu.size;
3119 priv->is_avc = TRUE;
3123 GstVaapiDecoderStatus
3124 gst_vaapi_decoder_h264_decode(GstVaapiDecoder *base, GstBuffer *buffer)
3126 GstVaapiDecoderH264 * const decoder = GST_VAAPI_DECODER_H264(base);
3127 GstVaapiDecoderH264Private * const priv = decoder->priv;
3128 GstVaapiDecoderStatus status;
3129 GstBuffer *codec_data;
3131 g_return_val_if_fail(priv->is_constructed,
3132 GST_VAAPI_DECODER_STATUS_ERROR_INIT_FAILED);
3134 if (!priv->is_opened) {
3135 priv->is_opened = gst_vaapi_decoder_h264_open(decoder, buffer);
3136 if (!priv->is_opened)
3137 return GST_VAAPI_DECODER_STATUS_ERROR_UNSUPPORTED_CODEC;
3139 codec_data = GST_VAAPI_DECODER_CODEC_DATA(decoder);
3141 status = decode_codec_data(decoder, codec_data);
3142 if (status != GST_VAAPI_DECODER_STATUS_SUCCESS)
3146 return decode_buffer(decoder, buffer);
3150 gst_vaapi_decoder_h264_finalize(GObject *object)
3152 GstVaapiDecoderH264 * const decoder = GST_VAAPI_DECODER_H264(object);
3154 gst_vaapi_decoder_h264_destroy(decoder);
3156 G_OBJECT_CLASS(gst_vaapi_decoder_h264_parent_class)->finalize(object);
3160 gst_vaapi_decoder_h264_constructed(GObject *object)
3162 GstVaapiDecoderH264 * const decoder = GST_VAAPI_DECODER_H264(object);
3163 GstVaapiDecoderH264Private * const priv = decoder->priv;
3164 GObjectClass *parent_class;
3166 parent_class = G_OBJECT_CLASS(gst_vaapi_decoder_h264_parent_class);
3167 if (parent_class->constructed)
3168 parent_class->constructed(object);
3170 priv->is_constructed = gst_vaapi_decoder_h264_create(decoder);
3174 gst_vaapi_decoder_h264_class_init(GstVaapiDecoderH264Class *klass)
3176 GObjectClass * const object_class = G_OBJECT_CLASS(klass);
3177 GstVaapiDecoderClass * const decoder_class = GST_VAAPI_DECODER_CLASS(klass);
3179 g_type_class_add_private(klass, sizeof(GstVaapiDecoderH264Private));
3181 object_class->finalize = gst_vaapi_decoder_h264_finalize;
3182 object_class->constructed = gst_vaapi_decoder_h264_constructed;
3184 decoder_class->decode = gst_vaapi_decoder_h264_decode;
3188 gst_vaapi_decoder_h264_init(GstVaapiDecoderH264 *decoder)
3190 GstVaapiDecoderH264Private *priv;
3192 priv = GST_VAAPI_DECODER_H264_GET_PRIVATE(decoder);
3193 decoder->priv = priv;
3194 priv->parser = NULL;
3195 priv->current_picture = NULL;
3196 priv->dpb_count = 0;
3198 priv->profile = GST_VAAPI_PROFILE_UNKNOWN;
3199 priv->entrypoint = GST_VAAPI_ENTRYPOINT_VLD;
3200 priv->chroma_type = GST_VAAPI_CHROMA_TYPE_YUV420;
3201 priv->short_ref_count = 0;
3202 priv->long_ref_count = 0;
3203 priv->RefPicList0_count = 0;
3204 priv->RefPicList1_count = 0;
3205 priv->nal_length_size = 0;
3206 priv->adapter = NULL;
3207 priv->field_poc[0] = 0;
3208 priv->field_poc[1] = 0;
3211 priv->prev_poc_msb = 0;
3212 priv->prev_poc_lsb = 0;
3213 priv->frame_num_offset = 0;
3214 priv->frame_num = 0;
3215 priv->prev_frame_num = 0;
3216 priv->prev_pic_has_mmco5 = FALSE;
3217 priv->prev_pic_structure = GST_VAAPI_PICTURE_STRUCTURE_FRAME;
3218 priv->is_constructed = FALSE;
3219 priv->is_opened = FALSE;
3220 priv->is_avc = FALSE;
3221 priv->has_context = FALSE;
3222 priv->progressive_sequence = TRUE;
3224 memset(priv->dpb, 0, sizeof(priv->dpb));
3225 memset(priv->short_ref, 0, sizeof(priv->short_ref));
3226 memset(priv->long_ref, 0, sizeof(priv->long_ref));
3227 memset(priv->RefPicList0, 0, sizeof(priv->RefPicList0));
3228 memset(priv->RefPicList1, 0, sizeof(priv->RefPicList1));
3232 * gst_vaapi_decoder_h264_new:
3233 * @display: a #GstVaapiDisplay
3234 * @caps: a #GstCaps holding codec information
3236 * Creates a new #GstVaapiDecoder for MPEG-2 decoding. The @caps can
3237 * hold extra information like codec-data and pictured coded size.
3239 * Return value: the newly allocated #GstVaapiDecoder object
3242 gst_vaapi_decoder_h264_new(GstVaapiDisplay *display, GstCaps *caps)
3244 GstVaapiDecoderH264 *decoder;
3246 g_return_val_if_fail(GST_VAAPI_IS_DISPLAY(display), NULL);
3247 g_return_val_if_fail(GST_IS_CAPS(caps), NULL);
3249 decoder = g_object_new(
3250 GST_VAAPI_TYPE_DECODER_H264,
3255 if (!decoder->priv->is_constructed) {
3256 g_object_unref(decoder);
3259 return GST_VAAPI_DECODER_CAST(decoder);