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 _GstVaapiDecoderH264Private GstVaapiDecoderH264Private;
44 typedef struct _GstVaapiDecoderH264Class GstVaapiDecoderH264Class;
45 typedef struct _GstVaapiFrameStore GstVaapiFrameStore;
46 typedef struct _GstVaapiFrameStoreClass GstVaapiFrameStoreClass;
47 typedef struct _GstVaapiParserInfoH264 GstVaapiParserInfoH264;
48 typedef struct _GstVaapiPictureH264 GstVaapiPictureH264;
50 // Used for field_poc[]
52 #define BOTTOM_FIELD 1
54 /* ------------------------------------------------------------------------- */
55 /* --- H.264 Parser Info --- */
56 /* ------------------------------------------------------------------------- */
58 #define GST_VAAPI_PARSER_INFO_H264(obj) \
59 ((GstVaapiParserInfoH264 *)(obj))
61 struct _GstVaapiParserInfoH264 {
62 GstVaapiMiniObject parent_instance;
67 GstH264SliceHdr slice_hdr;
71 static inline const GstVaapiMiniObjectClass *
72 gst_vaapi_parser_info_h264_class(void)
74 static const GstVaapiMiniObjectClass GstVaapiParserInfoH264Class = {
75 sizeof(GstVaapiParserInfoH264),
78 return &GstVaapiParserInfoH264Class;
81 static inline GstVaapiParserInfoH264 *
82 gst_vaapi_parser_info_h264_new(void)
84 return (GstVaapiParserInfoH264 *)
85 gst_vaapi_mini_object_new(gst_vaapi_parser_info_h264_class());
88 #define gst_vaapi_parser_info_h264_ref(pi) \
89 gst_vaapi_mini_object_ref(GST_VAAPI_MINI_OBJECT(pi))
91 #define gst_vaapi_parser_info_h264_unref(pi) \
92 gst_vaapi_mini_object_unref(GST_VAAPI_MINI_OBJECT(pi))
94 #define gst_vaapi_parser_info_h264_replace(old_pi_ptr, new_pi) \
95 gst_vaapi_mini_object_replace((GstVaapiMiniObject **)(old_pi_ptr), \
96 (GstVaapiMiniObject *)(new_pi))
98 /* ------------------------------------------------------------------------- */
99 /* --- H.264 Pictures --- */
100 /* ------------------------------------------------------------------------- */
103 * Extended picture flags:
105 * @GST_VAAPI_PICTURE_FLAG_IDR: flag that specifies an IDR picture
106 * @GST_VAAPI_PICTURE_FLAG_SHORT_TERM_REFERENCE: flag that specifies
107 * "used for short-term reference"
108 * @GST_VAAPI_PICTURE_FLAG_LONG_TERM_REFERENCE: flag that specifies
109 * "used for long-term reference"
110 * @GST_VAAPI_PICTURE_FLAGS_REFERENCE: mask covering any kind of
111 * reference picture (short-term reference or long-term reference)
114 GST_VAAPI_PICTURE_FLAG_IDR = (GST_VAAPI_PICTURE_FLAG_LAST << 0),
116 GST_VAAPI_PICTURE_FLAG_SHORT_TERM_REFERENCE = (
117 GST_VAAPI_PICTURE_FLAG_REFERENCE),
118 GST_VAAPI_PICTURE_FLAG_LONG_TERM_REFERENCE = (
119 GST_VAAPI_PICTURE_FLAG_REFERENCE | (GST_VAAPI_PICTURE_FLAG_LAST << 1)),
120 GST_VAAPI_PICTURE_FLAGS_REFERENCE = (
121 GST_VAAPI_PICTURE_FLAG_SHORT_TERM_REFERENCE |
122 GST_VAAPI_PICTURE_FLAG_LONG_TERM_REFERENCE),
125 #define GST_VAAPI_PICTURE_IS_IDR(picture) \
126 (GST_VAAPI_PICTURE_FLAG_IS_SET(picture, GST_VAAPI_PICTURE_FLAG_IDR))
128 #define GST_VAAPI_PICTURE_IS_SHORT_TERM_REFERENCE(picture) \
129 ((GST_VAAPI_PICTURE_FLAGS(picture) & \
130 GST_VAAPI_PICTURE_FLAGS_REFERENCE) == \
131 GST_VAAPI_PICTURE_FLAG_SHORT_TERM_REFERENCE)
133 #define GST_VAAPI_PICTURE_IS_LONG_TERM_REFERENCE(picture) \
134 ((GST_VAAPI_PICTURE_FLAGS(picture) & \
135 GST_VAAPI_PICTURE_FLAGS_REFERENCE) == \
136 GST_VAAPI_PICTURE_FLAG_LONG_TERM_REFERENCE)
138 struct _GstVaapiPictureH264 {
139 GstVaapiPicture base;
141 GstH264SliceHdr *last_slice_hdr;
144 gint32 frame_num; // Original frame_num from slice_header()
145 gint32 frame_num_wrap; // Temporary for ref pic marking: FrameNumWrap
146 gint32 long_term_frame_idx; // Temporary for ref pic marking: LongTermFrameIdx
147 gint32 pic_num; // Temporary for ref pic marking: PicNum
148 gint32 long_term_pic_num; // Temporary for ref pic marking: LongTermPicNum
149 GstVaapiPictureH264 *other_field; // Temporary for ref pic marking: other field in the same frame store
150 guint output_flag : 1;
151 guint output_needed : 1;
154 GST_VAAPI_CODEC_DEFINE_TYPE(GstVaapiPictureH264, gst_vaapi_picture_h264);
157 gst_vaapi_picture_h264_destroy(GstVaapiPictureH264 *picture)
159 gst_vaapi_picture_destroy(GST_VAAPI_PICTURE(picture));
163 gst_vaapi_picture_h264_create(
164 GstVaapiPictureH264 *picture,
165 const GstVaapiCodecObjectConstructorArgs *args
168 if (!gst_vaapi_picture_create(GST_VAAPI_PICTURE(picture), args))
171 picture->field_poc[0] = G_MAXINT32;
172 picture->field_poc[1] = G_MAXINT32;
173 picture->output_needed = FALSE;
177 static inline GstVaapiPictureH264 *
178 gst_vaapi_picture_h264_new(GstVaapiDecoderH264 *decoder)
180 return (GstVaapiPictureH264 *)gst_vaapi_codec_object_new(
181 &GstVaapiPictureH264Class,
182 GST_VAAPI_CODEC_BASE(decoder),
183 NULL, sizeof(VAPictureParameterBufferH264),
189 gst_vaapi_picture_h264_set_reference(
190 GstVaapiPictureH264 *picture,
191 guint reference_flags,
197 GST_VAAPI_PICTURE_FLAG_UNSET(picture, GST_VAAPI_PICTURE_FLAGS_REFERENCE);
198 GST_VAAPI_PICTURE_FLAG_SET(picture, reference_flags);
200 if (!other_field || !(picture = picture->other_field))
202 GST_VAAPI_PICTURE_FLAG_UNSET(picture, GST_VAAPI_PICTURE_FLAGS_REFERENCE);
203 GST_VAAPI_PICTURE_FLAG_SET(picture, reference_flags);
206 static inline GstVaapiPictureH264 *
207 gst_vaapi_picture_h264_new_field(GstVaapiPictureH264 *picture)
209 g_return_val_if_fail(picture, NULL);
211 return (GstVaapiPictureH264 *)gst_vaapi_picture_new_field(&picture->base);
214 /* ------------------------------------------------------------------------- */
215 /* --- Frame Buffers (DPB) --- */
216 /* ------------------------------------------------------------------------- */
218 struct _GstVaapiFrameStore {
220 GstVaapiMiniObject parent_instance;
223 GstVaapiPictureH264 *buffers[2];
229 gst_vaapi_frame_store_finalize(gpointer object)
231 GstVaapiFrameStore * const fs = object;
234 for (i = 0; i < fs->num_buffers; i++)
235 gst_vaapi_picture_replace(&fs->buffers[i], NULL);
238 static GstVaapiFrameStore *
239 gst_vaapi_frame_store_new(GstVaapiPictureH264 *picture)
241 GstVaapiFrameStore *fs;
243 static const GstVaapiMiniObjectClass GstVaapiFrameStoreClass = {
244 sizeof(GstVaapiFrameStore),
245 gst_vaapi_frame_store_finalize
248 fs = (GstVaapiFrameStore *)
249 gst_vaapi_mini_object_new(&GstVaapiFrameStoreClass);
253 fs->structure = picture->structure;
254 fs->buffers[0] = gst_vaapi_picture_ref(picture);
255 fs->buffers[1] = NULL;
257 fs->output_needed = picture->output_needed;
262 gst_vaapi_frame_store_add(GstVaapiFrameStore *fs, GstVaapiPictureH264 *picture)
266 g_return_val_if_fail(fs->num_buffers == 1, FALSE);
267 g_return_val_if_fail(!GST_VAAPI_PICTURE_IS_FRAME(picture), FALSE);
268 g_return_val_if_fail(!GST_VAAPI_PICTURE_IS_FIRST_FIELD(picture), FALSE);
270 gst_vaapi_picture_replace(&fs->buffers[fs->num_buffers++], picture);
271 if (picture->output_flag) {
272 picture->output_needed = TRUE;
276 fs->structure = GST_VAAPI_PICTURE_STRUCTURE_FRAME;
278 field = picture->structure == GST_VAAPI_PICTURE_STRUCTURE_TOP_FIELD ?
279 TOP_FIELD : BOTTOM_FIELD;
280 g_return_val_if_fail(fs->buffers[0]->field_poc[field] == G_MAXINT32, FALSE);
281 fs->buffers[0]->field_poc[field] = picture->field_poc[field];
282 g_return_val_if_fail(picture->field_poc[!field] == G_MAXINT32, FALSE);
283 picture->field_poc[!field] = fs->buffers[0]->field_poc[!field];
288 gst_vaapi_frame_store_split_fields(GstVaapiFrameStore *fs)
290 GstVaapiPictureH264 * const first_field = fs->buffers[0];
291 GstVaapiPictureH264 *second_field;
293 g_return_val_if_fail(fs->num_buffers == 1, FALSE);
295 first_field->base.structure = GST_VAAPI_PICTURE_STRUCTURE_TOP_FIELD;
296 GST_VAAPI_PICTURE_FLAG_SET(first_field, GST_VAAPI_PICTURE_FLAG_INTERLACED);
298 second_field = gst_vaapi_picture_h264_new_field(first_field);
301 gst_vaapi_picture_replace(&fs->buffers[fs->num_buffers++], second_field);
302 gst_vaapi_picture_unref(second_field);
304 second_field->frame_num = first_field->frame_num;
305 second_field->field_poc[0] = first_field->field_poc[0];
306 second_field->field_poc[1] = first_field->field_poc[1];
307 second_field->output_flag = first_field->output_flag;
308 if (second_field->output_flag) {
309 second_field->output_needed = TRUE;
315 static inline gboolean
316 gst_vaapi_frame_store_has_frame(GstVaapiFrameStore *fs)
318 return fs->structure == GST_VAAPI_PICTURE_STRUCTURE_FRAME;
321 static inline gboolean
322 gst_vaapi_frame_store_has_reference(GstVaapiFrameStore *fs)
326 for (i = 0; i < fs->num_buffers; i++) {
327 if (GST_VAAPI_PICTURE_IS_REFERENCE(fs->buffers[i]))
333 #define gst_vaapi_frame_store_ref(fs) \
334 gst_vaapi_mini_object_ref(GST_VAAPI_MINI_OBJECT(fs))
336 #define gst_vaapi_frame_store_unref(fs) \
337 gst_vaapi_mini_object_unref(GST_VAAPI_MINI_OBJECT(fs))
339 #define gst_vaapi_frame_store_replace(old_fs_p, new_fs) \
340 gst_vaapi_mini_object_replace((GstVaapiMiniObject **)(old_fs_p), \
341 (GstVaapiMiniObject *)(new_fs))
343 /* ------------------------------------------------------------------------- */
344 /* --- H.264 Decoder --- */
345 /* ------------------------------------------------------------------------- */
347 #define GST_VAAPI_DECODER_H264_CAST(decoder) \
348 ((GstVaapiDecoderH264 *)(decoder))
350 struct _GstVaapiDecoderH264Private {
351 GstH264NalParser *parser;
352 GstVaapiPictureH264 *current_picture;
353 GstVaapiParserInfoH264 *prev_slice_pi;
354 GstVaapiFrameStore *prev_frame;
355 GstVaapiFrameStore *dpb[16];
358 GstVaapiProfile profile;
359 GstVaapiEntrypoint entrypoint;
360 GstVaapiChromaType chroma_type;
361 GstVaapiPictureH264 *short_ref[32];
362 guint short_ref_count;
363 GstVaapiPictureH264 *long_ref[32];
364 guint long_ref_count;
365 GstVaapiPictureH264 *RefPicList0[32];
366 guint RefPicList0_count;
367 GstVaapiPictureH264 *RefPicList1[32];
368 guint RefPicList1_count;
369 guint nal_length_size;
372 gint32 field_poc[2]; // 0:TopFieldOrderCnt / 1:BottomFieldOrderCnt
373 gint32 poc_msb; // PicOrderCntMsb
374 gint32 poc_lsb; // pic_order_cnt_lsb (from slice_header())
375 gint32 prev_poc_msb; // prevPicOrderCntMsb
376 gint32 prev_poc_lsb; // prevPicOrderCntLsb
377 gint32 frame_num_offset; // FrameNumOffset
378 gint32 frame_num; // frame_num (from slice_header())
379 gint32 prev_frame_num; // prevFrameNum
380 gboolean prev_pic_has_mmco5; // prevMmco5Pic
381 gboolean prev_pic_structure; // previous picture structure
386 guint has_context : 1;
387 guint progressive_sequence : 1;
391 * GstVaapiDecoderH264:
393 * A decoder based on H264.
395 struct _GstVaapiDecoderH264 {
397 GstVaapiDecoder parent_instance;
398 GstVaapiDecoderH264Private priv;
402 * GstVaapiDecoderH264Class:
404 * A decoder class based on H264.
406 struct _GstVaapiDecoderH264Class {
408 GstVaapiDecoderClass parent_class;
412 exec_ref_pic_marking(GstVaapiDecoderH264 *decoder, GstVaapiPictureH264 *picture);
414 /* Get number of reference frames to use */
416 get_max_dec_frame_buffering(GstH264SPS *sps)
418 guint max_dec_frame_buffering, MaxDpbMbs, PicSizeMbs;
420 /* Table A-1 - Level limits */
421 switch (sps->level_idc) {
422 case 10: MaxDpbMbs = 396; break;
423 case 11: MaxDpbMbs = 900; break;
424 case 12: MaxDpbMbs = 2376; break;
425 case 13: MaxDpbMbs = 2376; break;
426 case 20: MaxDpbMbs = 2376; break;
427 case 21: MaxDpbMbs = 4752; break;
428 case 22: MaxDpbMbs = 8100; break;
429 case 30: MaxDpbMbs = 8100; break;
430 case 31: MaxDpbMbs = 18000; break;
431 case 32: MaxDpbMbs = 20480; break;
432 case 40: MaxDpbMbs = 32768; break;
433 case 41: MaxDpbMbs = 32768; break;
434 case 42: MaxDpbMbs = 34816; break;
435 case 50: MaxDpbMbs = 110400; break;
436 case 51: MaxDpbMbs = 184320; break;
438 g_assert(0 && "unhandled level");
442 PicSizeMbs = ((sps->pic_width_in_mbs_minus1 + 1) *
443 (sps->pic_height_in_map_units_minus1 + 1) *
444 (sps->frame_mbs_only_flag ? 1 : 2));
445 max_dec_frame_buffering = MaxDpbMbs / PicSizeMbs;
448 if (sps->vui_parameters_present_flag) {
449 GstH264VUIParams * const vui_params = &sps->vui_parameters;
450 if (vui_params->bitstream_restriction_flag)
451 max_dec_frame_buffering = vui_params->max_dec_frame_buffering;
453 switch (sps->profile_idc) {
454 case 44: // CAVLC 4:4:4 Intra profile
455 case GST_H264_PROFILE_SCALABLE_HIGH:
456 case GST_H264_PROFILE_HIGH:
457 case GST_H264_PROFILE_HIGH10:
458 case GST_H264_PROFILE_HIGH_422:
459 case GST_H264_PROFILE_HIGH_444:
460 if (sps->constraint_set3_flag)
461 max_dec_frame_buffering = 0;
467 if (max_dec_frame_buffering > 16)
468 max_dec_frame_buffering = 16;
469 else if (max_dec_frame_buffering < sps->num_ref_frames)
470 max_dec_frame_buffering = sps->num_ref_frames;
471 return MAX(1, max_dec_frame_buffering);
475 array_remove_index_fast(void *array, guint *array_length_ptr, guint index)
477 gpointer * const entries = array;
478 guint num_entries = *array_length_ptr;
480 g_return_if_fail(index < num_entries);
482 if (index != --num_entries)
483 entries[index] = entries[num_entries];
484 entries[num_entries] = NULL;
485 *array_length_ptr = num_entries;
490 array_remove_index(void *array, guint *array_length_ptr, guint index)
492 array_remove_index_fast(array, array_length_ptr, index);
496 array_remove_index(void *array, guint *array_length_ptr, guint index)
498 gpointer * const entries = array;
499 const guint num_entries = *array_length_ptr - 1;
502 g_return_if_fail(index <= num_entries);
504 for (i = index; i < num_entries; i++)
505 entries[i] = entries[i + 1];
506 entries[num_entries] = NULL;
507 *array_length_ptr = num_entries;
511 #define ARRAY_REMOVE_INDEX(array, index) \
512 array_remove_index(array, &array##_count, index)
515 dpb_remove_index(GstVaapiDecoderH264 *decoder, guint index)
517 GstVaapiDecoderH264Private * const priv = &decoder->priv;
518 guint i, num_frames = --priv->dpb_count;
520 if (USE_STRICT_DPB_ORDERING) {
521 for (i = index; i < num_frames; i++)
522 gst_vaapi_frame_store_replace(&priv->dpb[i], priv->dpb[i + 1]);
524 else if (index != num_frames)
525 gst_vaapi_frame_store_replace(&priv->dpb[index], priv->dpb[num_frames]);
526 gst_vaapi_frame_store_replace(&priv->dpb[num_frames], NULL);
531 GstVaapiDecoderH264 *decoder,
532 GstVaapiFrameStore *fs,
533 GstVaapiPictureH264 *picture
536 picture->output_needed = FALSE;
539 if (--fs->output_needed > 0)
541 picture = fs->buffers[0];
543 return gst_vaapi_picture_output(GST_VAAPI_PICTURE_CAST(picture));
547 dpb_evict(GstVaapiDecoderH264 *decoder, GstVaapiPictureH264 *picture, guint i)
549 GstVaapiDecoderH264Private * const priv = &decoder->priv;
550 GstVaapiFrameStore * const fs = priv->dpb[i];
552 if (!fs->output_needed && !gst_vaapi_frame_store_has_reference(fs))
553 dpb_remove_index(decoder, i);
557 dpb_bump(GstVaapiDecoderH264 *decoder)
559 GstVaapiDecoderH264Private * const priv = &decoder->priv;
560 GstVaapiPictureH264 *found_picture = NULL;
561 guint i, j, found_index;
564 for (i = 0; i < priv->dpb_count; i++) {
565 GstVaapiFrameStore * const fs = priv->dpb[i];
566 if (!fs->output_needed)
568 for (j = 0; j < fs->num_buffers; j++) {
569 GstVaapiPictureH264 * const picture = fs->buffers[j];
570 if (!picture->output_needed)
572 if (!found_picture || found_picture->base.poc > picture->base.poc)
573 found_picture = picture, found_index = i;
579 success = dpb_output(decoder, priv->dpb[found_index], found_picture);
580 dpb_evict(decoder, found_picture, found_index);
585 dpb_clear(GstVaapiDecoderH264 *decoder)
587 GstVaapiDecoderH264Private * const priv = &decoder->priv;
590 for (i = 0; i < priv->dpb_count; i++)
591 gst_vaapi_frame_store_replace(&priv->dpb[i], NULL);
594 gst_vaapi_frame_store_replace(&priv->prev_frame, NULL);
598 dpb_flush(GstVaapiDecoderH264 *decoder)
600 while (dpb_bump(decoder))
606 dpb_add(GstVaapiDecoderH264 *decoder, GstVaapiPictureH264 *picture)
608 GstVaapiDecoderH264Private * const priv = &decoder->priv;
609 GstVaapiFrameStore *fs;
612 // Remove all unused pictures
613 if (!GST_VAAPI_PICTURE_IS_IDR(picture)) {
615 while (i < priv->dpb_count) {
616 GstVaapiFrameStore * const fs = priv->dpb[i];
617 if (!fs->output_needed && !gst_vaapi_frame_store_has_reference(fs))
618 dpb_remove_index(decoder, i);
624 // Check if picture is the second field and the first field is still in DPB
625 fs = priv->prev_frame;
626 if (fs && !gst_vaapi_frame_store_has_frame(fs))
627 return gst_vaapi_frame_store_add(fs, picture);
629 // Create new frame store, and split fields if necessary
630 fs = gst_vaapi_frame_store_new(picture);
633 gst_vaapi_frame_store_replace(&priv->prev_frame, fs);
634 gst_vaapi_frame_store_unref(fs);
636 if (!priv->progressive_sequence && gst_vaapi_frame_store_has_frame(fs)) {
637 if (!gst_vaapi_frame_store_split_fields(fs))
641 // C.4.5.1 - Storage and marking of a reference decoded picture into the DPB
642 if (GST_VAAPI_PICTURE_IS_REFERENCE(picture)) {
643 while (priv->dpb_count == priv->dpb_size) {
644 if (!dpb_bump(decoder))
647 gst_vaapi_frame_store_replace(&priv->dpb[priv->dpb_count++], fs);
648 if (picture->output_flag) {
649 picture->output_needed = TRUE;
654 // C.4.5.2 - Storage and marking of a non-reference decoded picture into the DPB
656 if (!picture->output_flag)
658 while (priv->dpb_count == priv->dpb_size) {
659 gboolean found_picture = FALSE;
660 for (i = 0; !found_picture && i < priv->dpb_count; i++) {
661 GstVaapiFrameStore * const fs = priv->dpb[i];
662 if (!fs->output_needed)
664 for (j = 0; !found_picture && j < fs->num_buffers; j++)
665 found_picture = fs->buffers[j]->output_needed &&
666 fs->buffers[j]->base.poc < picture->base.poc;
669 return dpb_output(decoder, NULL, picture);
670 if (!dpb_bump(decoder))
673 gst_vaapi_frame_store_replace(&priv->dpb[priv->dpb_count++], fs);
674 picture->output_needed = TRUE;
681 dpb_reset(GstVaapiDecoderH264 *decoder, GstH264SPS *sps)
683 GstVaapiDecoderH264Private * const priv = &decoder->priv;
685 priv->dpb_size = get_max_dec_frame_buffering(sps);
686 GST_DEBUG("DPB size %u", priv->dpb_size);
689 static GstVaapiDecoderStatus
690 get_status(GstH264ParserResult result)
692 GstVaapiDecoderStatus status;
695 case GST_H264_PARSER_OK:
696 status = GST_VAAPI_DECODER_STATUS_SUCCESS;
698 case GST_H264_PARSER_NO_NAL_END:
699 status = GST_VAAPI_DECODER_STATUS_ERROR_NO_DATA;
701 case GST_H264_PARSER_ERROR:
702 status = GST_VAAPI_DECODER_STATUS_ERROR_BITSTREAM_PARSER;
705 status = GST_VAAPI_DECODER_STATUS_ERROR_UNKNOWN;
712 gst_vaapi_decoder_h264_close(GstVaapiDecoderH264 *decoder)
714 GstVaapiDecoderH264Private * const priv = &decoder->priv;
716 gst_vaapi_picture_replace(&priv->current_picture, NULL);
717 gst_vaapi_parser_info_h264_replace(&priv->prev_slice_pi, NULL);
722 gst_h264_nal_parser_free(priv->parser);
728 gst_vaapi_decoder_h264_open(GstVaapiDecoderH264 *decoder)
730 GstVaapiDecoderH264Private * const priv = &decoder->priv;
732 gst_vaapi_decoder_h264_close(decoder);
734 priv->parser = gst_h264_nal_parser_new();
741 gst_vaapi_decoder_h264_destroy(GstVaapiDecoder *base_decoder)
743 GstVaapiDecoderH264 * const decoder =
744 GST_VAAPI_DECODER_H264_CAST(base_decoder);
746 gst_vaapi_decoder_h264_close(decoder);
750 gst_vaapi_decoder_h264_create(GstVaapiDecoder *base_decoder)
752 GstVaapiDecoderH264 * const decoder =
753 GST_VAAPI_DECODER_H264_CAST(base_decoder);
754 GstVaapiDecoderH264Private * const priv = &decoder->priv;
756 priv->profile = GST_VAAPI_PROFILE_UNKNOWN;
757 priv->entrypoint = GST_VAAPI_ENTRYPOINT_VLD;
758 priv->chroma_type = GST_VAAPI_CHROMA_TYPE_YUV420;
759 priv->prev_pic_structure = GST_VAAPI_PICTURE_STRUCTURE_FRAME;
760 priv->progressive_sequence = TRUE;
765 h264_get_profile(GstH264SPS *sps)
769 switch (sps->profile_idc) {
770 case GST_H264_PROFILE_BASELINE:
771 profile = GST_VAAPI_PROFILE_H264_BASELINE;
773 case GST_H264_PROFILE_MAIN:
774 profile = GST_VAAPI_PROFILE_H264_MAIN;
776 case GST_H264_PROFILE_HIGH:
777 profile = GST_VAAPI_PROFILE_H264_HIGH;
784 h264_get_chroma_type(GstH264SPS *sps)
786 guint chroma_type = 0;
788 switch (sps->chroma_format_idc) {
790 chroma_type = GST_VAAPI_CHROMA_TYPE_YUV420;
793 chroma_type = GST_VAAPI_CHROMA_TYPE_YUV422;
796 if (!sps->separate_colour_plane_flag)
797 chroma_type = GST_VAAPI_CHROMA_TYPE_YUV444;
803 static GstVaapiProfile
804 get_profile(GstVaapiDecoderH264 *decoder, GstH264SPS *sps)
806 GstVaapiDecoderH264Private * const priv = &decoder->priv;
807 GstVaapiDisplay * const display = GST_VAAPI_DECODER_DISPLAY(decoder);
808 GstVaapiProfile profile, profiles[2];
809 guint i, n_profiles = 0;
811 profile = h264_get_profile(sps);
813 return GST_VAAPI_PROFILE_UNKNOWN;
815 profiles[n_profiles++] = profile;
817 case GST_VAAPI_PROFILE_H264_MAIN:
818 profiles[n_profiles++] = GST_VAAPI_PROFILE_H264_HIGH;
824 /* If the preferred profile (profiles[0]) matches one that we already
825 found, then just return it now instead of searching for it again */
826 if (profiles[0] == priv->profile)
827 return priv->profile;
829 for (i = 0; i < n_profiles; i++) {
830 if (gst_vaapi_display_has_decoder(display, profiles[i], priv->entrypoint))
833 return GST_VAAPI_PROFILE_UNKNOWN;
836 static GstVaapiDecoderStatus
837 ensure_context(GstVaapiDecoderH264 *decoder, GstH264SPS *sps)
839 GstVaapiDecoder * const base_decoder = GST_VAAPI_DECODER_CAST(decoder);
840 GstVaapiDecoderH264Private * const priv = &decoder->priv;
841 GstVaapiContextInfo info;
842 GstVaapiProfile profile;
843 GstVaapiChromaType chroma_type;
844 gboolean reset_context = FALSE;
845 guint mb_width, mb_height;
847 profile = get_profile(decoder, sps);
849 GST_ERROR("unsupported profile_idc %u", sps->profile_idc);
850 return GST_VAAPI_DECODER_STATUS_ERROR_UNSUPPORTED_PROFILE;
853 if (priv->profile != profile) {
854 GST_DEBUG("profile changed");
855 reset_context = TRUE;
856 priv->profile = profile;
859 chroma_type = h264_get_chroma_type(sps);
860 if (!chroma_type || chroma_type != GST_VAAPI_CHROMA_TYPE_YUV420) {
861 GST_ERROR("unsupported chroma_format_idc %u", sps->chroma_format_idc);
862 return GST_VAAPI_DECODER_STATUS_ERROR_UNSUPPORTED_CHROMA_FORMAT;
865 if (priv->chroma_type != chroma_type) {
866 GST_DEBUG("chroma format changed");
867 reset_context = TRUE;
868 priv->chroma_type = chroma_type;
871 mb_width = sps->pic_width_in_mbs_minus1 + 1;
872 mb_height = (sps->pic_height_in_map_units_minus1 + 1) <<
873 !sps->frame_mbs_only_flag;
874 if (priv->mb_width != mb_width || priv->mb_height != mb_height) {
875 GST_DEBUG("size changed");
876 reset_context = TRUE;
877 priv->mb_width = mb_width;
878 priv->mb_height = mb_height;
881 priv->progressive_sequence = sps->frame_mbs_only_flag;
883 /* XXX: we only output complete frames for now */
884 gst_vaapi_decoder_set_interlaced(base_decoder, !priv->progressive_sequence);
887 gst_vaapi_decoder_set_pixel_aspect_ratio(
889 sps->vui_parameters.par_n,
890 sps->vui_parameters.par_d
893 if (!reset_context && priv->has_context)
894 return GST_VAAPI_DECODER_STATUS_SUCCESS;
896 /* XXX: fix surface size when cropping is implemented */
897 info.profile = priv->profile;
898 info.entrypoint = priv->entrypoint;
899 info.width = sps->width;
900 info.height = sps->height;
901 info.ref_frames = get_max_dec_frame_buffering(sps);
903 if (!gst_vaapi_decoder_ensure_context(GST_VAAPI_DECODER(decoder), &info))
904 return GST_VAAPI_DECODER_STATUS_ERROR_UNKNOWN;
905 priv->has_context = TRUE;
908 dpb_reset(decoder, sps);
909 return GST_VAAPI_DECODER_STATUS_SUCCESS;
913 fill_iq_matrix_4x4(VAIQMatrixBufferH264 *iq_matrix, const GstH264PPS *pps)
915 const guint8 (* const ScalingList4x4)[6][16] = &pps->scaling_lists_4x4;
918 /* There are always 6 4x4 scaling lists */
919 g_assert(G_N_ELEMENTS(iq_matrix->ScalingList4x4) == 6);
920 g_assert(G_N_ELEMENTS(iq_matrix->ScalingList4x4[0]) == 16);
922 if (sizeof(iq_matrix->ScalingList4x4[0][0]) == 1)
923 memcpy(iq_matrix->ScalingList4x4, *ScalingList4x4,
924 sizeof(iq_matrix->ScalingList4x4));
926 for (i = 0; i < G_N_ELEMENTS(iq_matrix->ScalingList4x4); i++) {
927 for (j = 0; j < G_N_ELEMENTS(iq_matrix->ScalingList4x4[i]); j++)
928 iq_matrix->ScalingList4x4[i][j] = (*ScalingList4x4)[i][j];
934 fill_iq_matrix_8x8(VAIQMatrixBufferH264 *iq_matrix, const GstH264PPS *pps)
936 const guint8 (* const ScalingList8x8)[6][64] = &pps->scaling_lists_8x8;
937 const GstH264SPS * const sps = pps->sequence;
940 /* If chroma_format_idc != 3, there are up to 2 8x8 scaling lists */
941 if (!pps->transform_8x8_mode_flag)
944 g_assert(G_N_ELEMENTS(iq_matrix->ScalingList8x8) >= 2);
945 g_assert(G_N_ELEMENTS(iq_matrix->ScalingList8x8[0]) == 64);
947 if (sizeof(iq_matrix->ScalingList8x8[0][0]) == 1)
948 memcpy(iq_matrix->ScalingList8x8, *ScalingList8x8,
949 sizeof(iq_matrix->ScalingList8x8));
951 n = (sps->chroma_format_idc != 3) ? 2 : 6;
952 for (i = 0; i < n; i++) {
953 for (j = 0; j < G_N_ELEMENTS(iq_matrix->ScalingList8x8[i]); j++)
954 iq_matrix->ScalingList8x8[i][j] = (*ScalingList8x8)[i][j];
959 static GstVaapiDecoderStatus
960 ensure_quant_matrix(GstVaapiDecoderH264 *decoder, GstVaapiPictureH264 *picture)
962 GstVaapiPicture * const base_picture = &picture->base;
963 GstH264PPS * const pps = picture->pps;
964 GstH264SPS * const sps = pps->sequence;
965 VAIQMatrixBufferH264 *iq_matrix;
967 base_picture->iq_matrix = GST_VAAPI_IQ_MATRIX_NEW(H264, decoder);
968 if (!base_picture->iq_matrix) {
969 GST_ERROR("failed to allocate IQ matrix");
970 return GST_VAAPI_DECODER_STATUS_ERROR_ALLOCATION_FAILED;
972 iq_matrix = base_picture->iq_matrix->param;
974 /* XXX: we can only support 4:2:0 or 4:2:2 since ScalingLists8x8[]
975 is not large enough to hold lists for 4:4:4 */
976 if (sps->chroma_format_idc == 3)
977 return GST_VAAPI_DECODER_STATUS_ERROR_UNSUPPORTED_CHROMA_FORMAT;
979 fill_iq_matrix_4x4(iq_matrix, pps);
980 fill_iq_matrix_8x8(iq_matrix, pps);
982 return GST_VAAPI_DECODER_STATUS_SUCCESS;
985 static GstVaapiDecoderStatus
986 decode_current_picture(GstVaapiDecoderH264 *decoder)
988 GstVaapiDecoderH264Private * const priv = &decoder->priv;
989 GstVaapiPictureH264 * const picture = priv->current_picture;
992 return GST_VAAPI_DECODER_STATUS_SUCCESS;
994 if (!exec_ref_pic_marking(decoder, picture))
996 if (!dpb_add(decoder, picture))
998 if (!gst_vaapi_picture_decode(GST_VAAPI_PICTURE_CAST(picture)))
1000 if (priv->prev_frame && gst_vaapi_frame_store_has_frame(priv->prev_frame))
1001 gst_vaapi_picture_replace(&priv->current_picture, NULL);
1002 return GST_VAAPI_DECODER_STATUS_SUCCESS;
1005 /* XXX: fix for cases where first field failed to be decoded */
1006 gst_vaapi_picture_replace(&priv->current_picture, NULL);
1007 return GST_VAAPI_DECODER_STATUS_ERROR_UNKNOWN;
1010 static GstVaapiDecoderStatus
1011 parse_sps(GstVaapiDecoderH264 *decoder, GstVaapiDecoderUnit *unit)
1013 GstVaapiDecoderH264Private * const priv = &decoder->priv;
1014 GstVaapiParserInfoH264 * const pi = unit->parsed_info;
1015 GstH264SPS * const sps = &pi->data.sps;
1016 GstH264ParserResult result;
1018 GST_DEBUG("parse SPS");
1020 /* Variables that don't have inferred values per the H.264
1021 standard but that should get a default value anyway */
1022 sps->log2_max_pic_order_cnt_lsb_minus4 = 0;
1024 result = gst_h264_parser_parse_sps(priv->parser, &pi->nalu, sps, TRUE);
1025 if (result != GST_H264_PARSER_OK)
1026 return get_status(result);
1028 priv->got_sps = TRUE;
1029 return GST_VAAPI_DECODER_STATUS_SUCCESS;
1032 static GstVaapiDecoderStatus
1033 parse_pps(GstVaapiDecoderH264 *decoder, GstVaapiDecoderUnit *unit)
1035 GstVaapiDecoderH264Private * const priv = &decoder->priv;
1036 GstVaapiParserInfoH264 * const pi = unit->parsed_info;
1037 GstH264PPS * const pps = &pi->data.pps;
1038 GstH264ParserResult result;
1040 GST_DEBUG("parse PPS");
1042 /* Variables that don't have inferred values per the H.264
1043 standard but that should get a default value anyway */
1044 pps->slice_group_map_type = 0;
1045 pps->slice_group_change_rate_minus1 = 0;
1047 result = gst_h264_parser_parse_pps(priv->parser, &pi->nalu, pps);
1048 if (result != GST_H264_PARSER_OK)
1049 return get_status(result);
1051 priv->got_pps = TRUE;
1052 return GST_VAAPI_DECODER_STATUS_SUCCESS;
1055 static GstVaapiDecoderStatus
1056 parse_sei(GstVaapiDecoderH264 *decoder, GstVaapiDecoderUnit *unit)
1058 GstVaapiDecoderH264Private * const priv = &decoder->priv;
1059 GstVaapiParserInfoH264 * const pi = unit->parsed_info;
1060 GstH264SEIMessage sei;
1061 GstH264ParserResult result;
1063 GST_DEBUG("parse SEI");
1065 memset(&sei, 0, sizeof(sei));
1066 result = gst_h264_parser_parse_sei(priv->parser, &pi->nalu, &sei);
1067 if (result != GST_H264_PARSER_OK) {
1068 GST_WARNING("failed to parse SEI, payload type:%d", sei.payloadType);
1069 return get_status(result);
1072 return GST_VAAPI_DECODER_STATUS_SUCCESS;
1075 static GstVaapiDecoderStatus
1076 parse_slice(GstVaapiDecoderH264 *decoder, GstVaapiDecoderUnit *unit)
1078 GstVaapiDecoderH264Private * const priv = &decoder->priv;
1079 GstVaapiParserInfoH264 * const pi = unit->parsed_info;
1080 GstH264SliceHdr * const slice_hdr = &pi->data.slice_hdr;
1081 GstH264ParserResult result;
1083 GST_DEBUG("parse slice");
1085 /* Variables that don't have inferred values per the H.264
1086 standard but that should get a default value anyway */
1087 slice_hdr->cabac_init_idc = 0;
1088 slice_hdr->direct_spatial_mv_pred_flag = 0;
1090 result = gst_h264_parser_parse_slice_hdr(priv->parser, &pi->nalu,
1091 slice_hdr, TRUE, TRUE);
1092 if (result != GST_H264_PARSER_OK)
1093 return get_status(result);
1095 return GST_VAAPI_DECODER_STATUS_SUCCESS;
1098 static GstVaapiDecoderStatus
1099 decode_sequence_end(GstVaapiDecoderH264 *decoder)
1101 GstVaapiDecoderStatus status;
1103 GST_DEBUG("decode sequence-end");
1105 status = decode_current_picture(decoder);
1106 if (status != GST_VAAPI_DECODER_STATUS_SUCCESS)
1110 return GST_VAAPI_DECODER_STATUS_SUCCESS;
1113 /* 8.2.1.1 - Decoding process for picture order count type 0 */
1116 GstVaapiDecoderH264 *decoder,
1117 GstVaapiPictureH264 *picture,
1118 GstH264SliceHdr *slice_hdr
1121 GstVaapiDecoderH264Private * const priv = &decoder->priv;
1122 GstH264PPS * const pps = slice_hdr->pps;
1123 GstH264SPS * const sps = pps->sequence;
1124 const gint32 MaxPicOrderCntLsb = 1 << (sps->log2_max_pic_order_cnt_lsb_minus4 + 4);
1127 GST_DEBUG("decode picture order count type 0");
1129 if (GST_VAAPI_PICTURE_IS_IDR(picture)) {
1130 priv->prev_poc_msb = 0;
1131 priv->prev_poc_lsb = 0;
1133 else if (priv->prev_pic_has_mmco5) {
1134 priv->prev_poc_msb = 0;
1135 priv->prev_poc_lsb =
1136 (priv->prev_pic_structure == GST_VAAPI_PICTURE_STRUCTURE_BOTTOM_FIELD ?
1137 0 : priv->field_poc[TOP_FIELD]);
1140 priv->prev_poc_msb = priv->poc_msb;
1141 priv->prev_poc_lsb = priv->poc_lsb;
1145 priv->poc_lsb = slice_hdr->pic_order_cnt_lsb;
1146 if (priv->poc_lsb < priv->prev_poc_lsb &&
1147 (priv->prev_poc_lsb - priv->poc_lsb) >= (MaxPicOrderCntLsb / 2))
1148 priv->poc_msb = priv->prev_poc_msb + MaxPicOrderCntLsb;
1149 else if (priv->poc_lsb > priv->prev_poc_lsb &&
1150 (priv->poc_lsb - priv->prev_poc_lsb) > (MaxPicOrderCntLsb / 2))
1151 priv->poc_msb = priv->prev_poc_msb - MaxPicOrderCntLsb;
1153 priv->poc_msb = priv->prev_poc_msb;
1155 temp_poc = priv->poc_msb + priv->poc_lsb;
1156 switch (picture->structure) {
1157 case GST_VAAPI_PICTURE_STRUCTURE_FRAME:
1159 priv->field_poc[TOP_FIELD] = temp_poc;
1160 priv->field_poc[BOTTOM_FIELD] = temp_poc +
1161 slice_hdr->delta_pic_order_cnt_bottom;
1163 case GST_VAAPI_PICTURE_STRUCTURE_TOP_FIELD:
1165 priv->field_poc[TOP_FIELD] = temp_poc;
1167 case GST_VAAPI_PICTURE_STRUCTURE_BOTTOM_FIELD:
1169 priv->field_poc[BOTTOM_FIELD] = temp_poc;
1174 /* 8.2.1.2 - Decoding process for picture order count type 1 */
1177 GstVaapiDecoderH264 *decoder,
1178 GstVaapiPictureH264 *picture,
1179 GstH264SliceHdr *slice_hdr
1182 GstVaapiDecoderH264Private * const priv = &decoder->priv;
1183 GstH264PPS * const pps = slice_hdr->pps;
1184 GstH264SPS * const sps = pps->sequence;
1185 const gint32 MaxFrameNum = 1 << (sps->log2_max_frame_num_minus4 + 4);
1186 gint32 prev_frame_num_offset, abs_frame_num, expected_poc;
1189 GST_DEBUG("decode picture order count type 1");
1191 if (priv->prev_pic_has_mmco5)
1192 prev_frame_num_offset = 0;
1194 prev_frame_num_offset = priv->frame_num_offset;
1197 if (GST_VAAPI_PICTURE_IS_IDR(picture))
1198 priv->frame_num_offset = 0;
1199 else if (priv->prev_frame_num > priv->frame_num)
1200 priv->frame_num_offset = prev_frame_num_offset + MaxFrameNum;
1202 priv->frame_num_offset = prev_frame_num_offset;
1205 if (sps->num_ref_frames_in_pic_order_cnt_cycle != 0)
1206 abs_frame_num = priv->frame_num_offset + priv->frame_num;
1209 if (!GST_VAAPI_PICTURE_IS_REFERENCE(picture) && abs_frame_num > 0)
1210 abs_frame_num = abs_frame_num - 1;
1212 if (abs_frame_num > 0) {
1213 gint32 expected_delta_per_poc_cycle;
1214 gint32 poc_cycle_cnt, frame_num_in_poc_cycle;
1216 expected_delta_per_poc_cycle = 0;
1217 for (i = 0; i < sps->num_ref_frames_in_pic_order_cnt_cycle; i++)
1218 expected_delta_per_poc_cycle += sps->offset_for_ref_frame[i];
1221 poc_cycle_cnt = (abs_frame_num - 1) /
1222 sps->num_ref_frames_in_pic_order_cnt_cycle;
1223 frame_num_in_poc_cycle = (abs_frame_num - 1) %
1224 sps->num_ref_frames_in_pic_order_cnt_cycle;
1227 expected_poc = poc_cycle_cnt * expected_delta_per_poc_cycle;
1228 for (i = 0; i <= frame_num_in_poc_cycle; i++)
1229 expected_poc += sps->offset_for_ref_frame[i];
1233 if (!GST_VAAPI_PICTURE_IS_REFERENCE(picture))
1234 expected_poc += sps->offset_for_non_ref_pic;
1237 switch (picture->structure) {
1238 case GST_VAAPI_PICTURE_STRUCTURE_FRAME:
1239 priv->field_poc[TOP_FIELD] = expected_poc +
1240 slice_hdr->delta_pic_order_cnt[0];
1241 priv->field_poc[BOTTOM_FIELD] = priv->field_poc[TOP_FIELD] +
1242 sps->offset_for_top_to_bottom_field +
1243 slice_hdr->delta_pic_order_cnt[1];
1245 case GST_VAAPI_PICTURE_STRUCTURE_TOP_FIELD:
1246 priv->field_poc[TOP_FIELD] = expected_poc +
1247 slice_hdr->delta_pic_order_cnt[0];
1249 case GST_VAAPI_PICTURE_STRUCTURE_BOTTOM_FIELD:
1250 priv->field_poc[BOTTOM_FIELD] = expected_poc +
1251 sps->offset_for_top_to_bottom_field +
1252 slice_hdr->delta_pic_order_cnt[0];
1257 /* 8.2.1.3 - Decoding process for picture order count type 2 */
1260 GstVaapiDecoderH264 *decoder,
1261 GstVaapiPictureH264 *picture,
1262 GstH264SliceHdr *slice_hdr
1265 GstVaapiDecoderH264Private * const priv = &decoder->priv;
1266 GstH264PPS * const pps = slice_hdr->pps;
1267 GstH264SPS * const sps = pps->sequence;
1268 const gint32 MaxFrameNum = 1 << (sps->log2_max_frame_num_minus4 + 4);
1269 gint32 prev_frame_num_offset, temp_poc;
1271 GST_DEBUG("decode picture order count type 2");
1273 if (priv->prev_pic_has_mmco5)
1274 prev_frame_num_offset = 0;
1276 prev_frame_num_offset = priv->frame_num_offset;
1279 if (GST_VAAPI_PICTURE_IS_IDR(picture))
1280 priv->frame_num_offset = 0;
1281 else if (priv->prev_frame_num > priv->frame_num)
1282 priv->frame_num_offset = prev_frame_num_offset + MaxFrameNum;
1284 priv->frame_num_offset = prev_frame_num_offset;
1287 if (GST_VAAPI_PICTURE_IS_IDR(picture))
1289 else if (!GST_VAAPI_PICTURE_IS_REFERENCE(picture))
1290 temp_poc = 2 * (priv->frame_num_offset + priv->frame_num) - 1;
1292 temp_poc = 2 * (priv->frame_num_offset + priv->frame_num);
1295 if (picture->structure != GST_VAAPI_PICTURE_STRUCTURE_BOTTOM_FIELD)
1296 priv->field_poc[TOP_FIELD] = temp_poc;
1297 if (picture->structure != GST_VAAPI_PICTURE_STRUCTURE_TOP_FIELD)
1298 priv->field_poc[BOTTOM_FIELD] = temp_poc;
1301 /* 8.2.1 - Decoding process for picture order count */
1304 GstVaapiDecoderH264 *decoder,
1305 GstVaapiPictureH264 *picture,
1306 GstH264SliceHdr *slice_hdr
1309 GstVaapiDecoderH264Private * const priv = &decoder->priv;
1310 GstH264PPS * const pps = slice_hdr->pps;
1311 GstH264SPS * const sps = pps->sequence;
1313 switch (sps->pic_order_cnt_type) {
1315 init_picture_poc_0(decoder, picture, slice_hdr);
1318 init_picture_poc_1(decoder, picture, slice_hdr);
1321 init_picture_poc_2(decoder, picture, slice_hdr);
1325 if (picture->structure != GST_VAAPI_PICTURE_STRUCTURE_BOTTOM_FIELD)
1326 picture->field_poc[TOP_FIELD] = priv->field_poc[TOP_FIELD];
1327 if (picture->structure != GST_VAAPI_PICTURE_STRUCTURE_TOP_FIELD)
1328 picture->field_poc[BOTTOM_FIELD] = priv->field_poc[BOTTOM_FIELD];
1329 picture->base.poc = MIN(picture->field_poc[0], picture->field_poc[1]);
1333 compare_picture_pic_num_dec(const void *a, const void *b)
1335 const GstVaapiPictureH264 * const picA = *(GstVaapiPictureH264 **)a;
1336 const GstVaapiPictureH264 * const picB = *(GstVaapiPictureH264 **)b;
1338 return picB->pic_num - picA->pic_num;
1342 compare_picture_long_term_pic_num_inc(const void *a, const void *b)
1344 const GstVaapiPictureH264 * const picA = *(GstVaapiPictureH264 **)a;
1345 const GstVaapiPictureH264 * const picB = *(GstVaapiPictureH264 **)b;
1347 return picA->long_term_pic_num - picB->long_term_pic_num;
1351 compare_picture_poc_dec(const void *a, const void *b)
1353 const GstVaapiPictureH264 * const picA = *(GstVaapiPictureH264 **)a;
1354 const GstVaapiPictureH264 * const picB = *(GstVaapiPictureH264 **)b;
1356 return picB->base.poc - picA->base.poc;
1360 compare_picture_poc_inc(const void *a, const void *b)
1362 const GstVaapiPictureH264 * const picA = *(GstVaapiPictureH264 **)a;
1363 const GstVaapiPictureH264 * const picB = *(GstVaapiPictureH264 **)b;
1365 return picA->base.poc - picB->base.poc;
1369 compare_picture_frame_num_wrap_dec(const void *a, const void *b)
1371 const GstVaapiPictureH264 * const picA = *(GstVaapiPictureH264 **)a;
1372 const GstVaapiPictureH264 * const picB = *(GstVaapiPictureH264 **)b;
1374 return picB->frame_num_wrap - picA->frame_num_wrap;
1378 compare_picture_long_term_frame_idx_inc(const void *a, const void *b)
1380 const GstVaapiPictureH264 * const picA = *(GstVaapiPictureH264 **)a;
1381 const GstVaapiPictureH264 * const picB = *(GstVaapiPictureH264 **)b;
1383 return picA->long_term_frame_idx - picB->long_term_frame_idx;
1386 /* 8.2.4.1 - Decoding process for picture numbers */
1388 init_picture_refs_pic_num(
1389 GstVaapiDecoderH264 *decoder,
1390 GstVaapiPictureH264 *picture,
1391 GstH264SliceHdr *slice_hdr
1394 GstVaapiDecoderH264Private * const priv = &decoder->priv;
1395 GstH264PPS * const pps = slice_hdr->pps;
1396 GstH264SPS * const sps = pps->sequence;
1397 const gint32 MaxFrameNum = 1 << (sps->log2_max_frame_num_minus4 + 4);
1400 GST_DEBUG("decode picture numbers");
1402 for (i = 0; i < priv->short_ref_count; i++) {
1403 GstVaapiPictureH264 * const pic = priv->short_ref[i];
1406 if (pic->frame_num > priv->frame_num)
1407 pic->frame_num_wrap = pic->frame_num - MaxFrameNum;
1409 pic->frame_num_wrap = pic->frame_num;
1411 // (8-28, 8-30, 8-31)
1412 if (GST_VAAPI_PICTURE_IS_FRAME(picture))
1413 pic->pic_num = pic->frame_num_wrap;
1415 if (pic->structure == picture->structure)
1416 pic->pic_num = 2 * pic->frame_num_wrap + 1;
1418 pic->pic_num = 2 * pic->frame_num_wrap;
1422 for (i = 0; i < priv->long_ref_count; i++) {
1423 GstVaapiPictureH264 * const pic = priv->long_ref[i];
1425 // (8-29, 8-32, 8-33)
1426 if (GST_VAAPI_PICTURE_IS_FRAME(picture))
1427 pic->long_term_pic_num = pic->long_term_frame_idx;
1429 if (pic->structure == picture->structure)
1430 pic->long_term_pic_num = 2 * pic->long_term_frame_idx + 1;
1432 pic->long_term_pic_num = 2 * pic->long_term_frame_idx;
1437 #define SORT_REF_LIST(list, n, compare_func) \
1438 qsort(list, n, sizeof(*(list)), compare_picture_##compare_func)
1441 init_picture_refs_fields_1(
1442 guint picture_structure,
1443 GstVaapiPictureH264 *RefPicList[32],
1444 guint *RefPicList_count,
1445 GstVaapiPictureH264 *ref_list[32],
1446 guint ref_list_count
1453 n = *RefPicList_count;
1456 for (; i < ref_list_count; i++) {
1457 if (ref_list[i]->structure == picture_structure) {
1458 RefPicList[n++] = ref_list[i++];
1462 for (; j < ref_list_count; j++) {
1463 if (ref_list[j]->structure != picture_structure) {
1464 RefPicList[n++] = ref_list[j++];
1468 } while (i < ref_list_count || j < ref_list_count);
1469 *RefPicList_count = n;
1473 init_picture_refs_fields(
1474 GstVaapiPictureH264 *picture,
1475 GstVaapiPictureH264 *RefPicList[32],
1476 guint *RefPicList_count,
1477 GstVaapiPictureH264 *short_ref[32],
1478 guint short_ref_count,
1479 GstVaapiPictureH264 *long_ref[32],
1480 guint long_ref_count
1485 /* 8.2.4.2.5 - reference picture lists in fields */
1486 init_picture_refs_fields_1(picture->structure, RefPicList, &n,
1487 short_ref, short_ref_count);
1488 init_picture_refs_fields_1(picture->structure, RefPicList, &n,
1489 long_ref, long_ref_count);
1490 *RefPicList_count = n;
1494 init_picture_refs_p_slice(
1495 GstVaapiDecoderH264 *decoder,
1496 GstVaapiPictureH264 *picture,
1497 GstH264SliceHdr *slice_hdr
1500 GstVaapiDecoderH264Private * const priv = &decoder->priv;
1501 GstVaapiPictureH264 **ref_list;
1504 GST_DEBUG("decode reference picture list for P and SP slices");
1506 if (GST_VAAPI_PICTURE_IS_FRAME(picture)) {
1507 /* 8.2.4.2.1 - P and SP slices in frames */
1508 if (priv->short_ref_count > 0) {
1509 ref_list = priv->RefPicList0;
1510 for (i = 0; i < priv->short_ref_count; i++)
1511 ref_list[i] = priv->short_ref[i];
1512 SORT_REF_LIST(ref_list, i, pic_num_dec);
1513 priv->RefPicList0_count += i;
1516 if (priv->long_ref_count > 0) {
1517 ref_list = &priv->RefPicList0[priv->RefPicList0_count];
1518 for (i = 0; i < priv->long_ref_count; i++)
1519 ref_list[i] = priv->long_ref[i];
1520 SORT_REF_LIST(ref_list, i, long_term_pic_num_inc);
1521 priv->RefPicList0_count += i;
1525 /* 8.2.4.2.2 - P and SP slices in fields */
1526 GstVaapiPictureH264 *short_ref[32];
1527 guint short_ref_count = 0;
1528 GstVaapiPictureH264 *long_ref[32];
1529 guint long_ref_count = 0;
1531 if (priv->short_ref_count > 0) {
1532 for (i = 0; i < priv->short_ref_count; i++)
1533 short_ref[i] = priv->short_ref[i];
1534 SORT_REF_LIST(short_ref, i, frame_num_wrap_dec);
1535 short_ref_count = i;
1538 if (priv->long_ref_count > 0) {
1539 for (i = 0; i < priv->long_ref_count; i++)
1540 long_ref[i] = priv->long_ref[i];
1541 SORT_REF_LIST(long_ref, i, long_term_frame_idx_inc);
1545 init_picture_refs_fields(
1547 priv->RefPicList0, &priv->RefPicList0_count,
1548 short_ref, short_ref_count,
1549 long_ref, long_ref_count
1555 init_picture_refs_b_slice(
1556 GstVaapiDecoderH264 *decoder,
1557 GstVaapiPictureH264 *picture,
1558 GstH264SliceHdr *slice_hdr
1561 GstVaapiDecoderH264Private * const priv = &decoder->priv;
1562 GstVaapiPictureH264 **ref_list;
1565 GST_DEBUG("decode reference picture list for B slices");
1567 if (GST_VAAPI_PICTURE_IS_FRAME(picture)) {
1568 /* 8.2.4.2.3 - B slices in frames */
1571 if (priv->short_ref_count > 0) {
1572 // 1. Short-term references
1573 ref_list = priv->RefPicList0;
1574 for (n = 0, i = 0; i < priv->short_ref_count; i++) {
1575 if (priv->short_ref[i]->base.poc < picture->base.poc)
1576 ref_list[n++] = priv->short_ref[i];
1578 SORT_REF_LIST(ref_list, n, poc_dec);
1579 priv->RefPicList0_count += n;
1581 ref_list = &priv->RefPicList0[priv->RefPicList0_count];
1582 for (n = 0, i = 0; i < priv->short_ref_count; i++) {
1583 if (priv->short_ref[i]->base.poc >= picture->base.poc)
1584 ref_list[n++] = priv->short_ref[i];
1586 SORT_REF_LIST(ref_list, n, poc_inc);
1587 priv->RefPicList0_count += n;
1590 if (priv->long_ref_count > 0) {
1591 // 2. Long-term references
1592 ref_list = &priv->RefPicList0[priv->RefPicList0_count];
1593 for (n = 0, i = 0; i < priv->long_ref_count; i++)
1594 ref_list[n++] = priv->long_ref[i];
1595 SORT_REF_LIST(ref_list, n, long_term_pic_num_inc);
1596 priv->RefPicList0_count += n;
1600 if (priv->short_ref_count > 0) {
1601 // 1. Short-term references
1602 ref_list = priv->RefPicList1;
1603 for (n = 0, i = 0; i < priv->short_ref_count; i++) {
1604 if (priv->short_ref[i]->base.poc > picture->base.poc)
1605 ref_list[n++] = priv->short_ref[i];
1607 SORT_REF_LIST(ref_list, n, poc_inc);
1608 priv->RefPicList1_count += n;
1610 ref_list = &priv->RefPicList1[priv->RefPicList1_count];
1611 for (n = 0, i = 0; i < priv->short_ref_count; i++) {
1612 if (priv->short_ref[i]->base.poc <= picture->base.poc)
1613 ref_list[n++] = priv->short_ref[i];
1615 SORT_REF_LIST(ref_list, n, poc_dec);
1616 priv->RefPicList1_count += n;
1619 if (priv->long_ref_count > 0) {
1620 // 2. Long-term references
1621 ref_list = &priv->RefPicList1[priv->RefPicList1_count];
1622 for (n = 0, i = 0; i < priv->long_ref_count; i++)
1623 ref_list[n++] = priv->long_ref[i];
1624 SORT_REF_LIST(ref_list, n, long_term_pic_num_inc);
1625 priv->RefPicList1_count += n;
1629 /* 8.2.4.2.4 - B slices in fields */
1630 GstVaapiPictureH264 *short_ref0[32];
1631 guint short_ref0_count = 0;
1632 GstVaapiPictureH264 *short_ref1[32];
1633 guint short_ref1_count = 0;
1634 GstVaapiPictureH264 *long_ref[32];
1635 guint long_ref_count = 0;
1637 /* refFrameList0ShortTerm */
1638 if (priv->short_ref_count > 0) {
1639 ref_list = short_ref0;
1640 for (n = 0, i = 0; i < priv->short_ref_count; i++) {
1641 if (priv->short_ref[i]->base.poc <= picture->base.poc)
1642 ref_list[n++] = priv->short_ref[i];
1644 SORT_REF_LIST(ref_list, n, poc_dec);
1645 short_ref0_count += n;
1647 ref_list = &short_ref0[short_ref0_count];
1648 for (n = 0, i = 0; i < priv->short_ref_count; i++) {
1649 if (priv->short_ref[i]->base.poc > picture->base.poc)
1650 ref_list[n++] = priv->short_ref[i];
1652 SORT_REF_LIST(ref_list, n, poc_inc);
1653 short_ref0_count += n;
1656 /* refFrameList1ShortTerm */
1657 if (priv->short_ref_count > 0) {
1658 ref_list = short_ref1;
1659 for (n = 0, i = 0; i < priv->short_ref_count; i++) {
1660 if (priv->short_ref[i]->base.poc > picture->base.poc)
1661 ref_list[n++] = priv->short_ref[i];
1663 SORT_REF_LIST(ref_list, n, poc_inc);
1664 short_ref1_count += n;
1666 ref_list = &short_ref1[short_ref1_count];
1667 for (n = 0, i = 0; i < priv->short_ref_count; i++) {
1668 if (priv->short_ref[i]->base.poc <= picture->base.poc)
1669 ref_list[n++] = priv->short_ref[i];
1671 SORT_REF_LIST(ref_list, n, poc_dec);
1672 short_ref1_count += n;
1675 /* refFrameListLongTerm */
1676 if (priv->long_ref_count > 0) {
1677 for (i = 0; i < priv->long_ref_count; i++)
1678 long_ref[i] = priv->long_ref[i];
1679 SORT_REF_LIST(long_ref, i, long_term_frame_idx_inc);
1683 init_picture_refs_fields(
1685 priv->RefPicList0, &priv->RefPicList0_count,
1686 short_ref0, short_ref0_count,
1687 long_ref, long_ref_count
1690 init_picture_refs_fields(
1692 priv->RefPicList1, &priv->RefPicList1_count,
1693 short_ref1, short_ref1_count,
1694 long_ref, long_ref_count
1698 /* Check whether RefPicList1 is identical to RefPicList0, then
1699 swap if necessary */
1700 if (priv->RefPicList1_count > 1 &&
1701 priv->RefPicList1_count == priv->RefPicList0_count &&
1702 memcmp(priv->RefPicList0, priv->RefPicList1,
1703 priv->RefPicList0_count * sizeof(priv->RefPicList0[0])) == 0) {
1704 GstVaapiPictureH264 * const tmp = priv->RefPicList1[0];
1705 priv->RefPicList1[0] = priv->RefPicList1[1];
1706 priv->RefPicList1[1] = tmp;
1710 #undef SORT_REF_LIST
1713 find_short_term_reference(GstVaapiDecoderH264 *decoder, gint32 pic_num)
1715 GstVaapiDecoderH264Private * const priv = &decoder->priv;
1718 for (i = 0; i < priv->short_ref_count; i++) {
1719 if (priv->short_ref[i]->pic_num == pic_num)
1722 GST_ERROR("found no short-term reference picture with PicNum = %d",
1728 find_long_term_reference(GstVaapiDecoderH264 *decoder, gint32 long_term_pic_num)
1730 GstVaapiDecoderH264Private * const priv = &decoder->priv;
1733 for (i = 0; i < priv->long_ref_count; i++) {
1734 if (priv->long_ref[i]->long_term_pic_num == long_term_pic_num)
1737 GST_ERROR("found no long-term reference picture with LongTermPicNum = %d",
1743 exec_picture_refs_modification_1(
1744 GstVaapiDecoderH264 *decoder,
1745 GstVaapiPictureH264 *picture,
1746 GstH264SliceHdr *slice_hdr,
1750 GstVaapiDecoderH264Private * const priv = &decoder->priv;
1751 GstH264PPS * const pps = slice_hdr->pps;
1752 GstH264SPS * const sps = pps->sequence;
1753 GstH264RefPicListModification *ref_pic_list_modification;
1754 guint num_ref_pic_list_modifications;
1755 GstVaapiPictureH264 **ref_list;
1756 guint *ref_list_count_ptr, ref_list_count, ref_list_idx = 0;
1757 guint i, j, n, num_refs;
1759 gint32 MaxPicNum, CurrPicNum, picNumPred;
1761 GST_DEBUG("modification process of reference picture list %u", list);
1764 ref_pic_list_modification = slice_hdr->ref_pic_list_modification_l0;
1765 num_ref_pic_list_modifications = slice_hdr->n_ref_pic_list_modification_l0;
1766 ref_list = priv->RefPicList0;
1767 ref_list_count_ptr = &priv->RefPicList0_count;
1768 num_refs = slice_hdr->num_ref_idx_l0_active_minus1 + 1;
1771 ref_pic_list_modification = slice_hdr->ref_pic_list_modification_l1;
1772 num_ref_pic_list_modifications = slice_hdr->n_ref_pic_list_modification_l1;
1773 ref_list = priv->RefPicList1;
1774 ref_list_count_ptr = &priv->RefPicList1_count;
1775 num_refs = slice_hdr->num_ref_idx_l1_active_minus1 + 1;
1777 ref_list_count = *ref_list_count_ptr;
1779 if (!GST_VAAPI_PICTURE_IS_FRAME(picture)) {
1780 MaxPicNum = 1 << (sps->log2_max_frame_num_minus4 + 5); // 2 * MaxFrameNum
1781 CurrPicNum = 2 * slice_hdr->frame_num + 1; // 2 * frame_num + 1
1784 MaxPicNum = 1 << (sps->log2_max_frame_num_minus4 + 4); // MaxFrameNum
1785 CurrPicNum = slice_hdr->frame_num; // frame_num
1788 picNumPred = CurrPicNum;
1790 for (i = 0; i < num_ref_pic_list_modifications; i++) {
1791 GstH264RefPicListModification * const l = &ref_pic_list_modification[i];
1792 if (l->modification_of_pic_nums_idc == 3)
1795 /* 8.2.4.3.1 - Short-term reference pictures */
1796 if (l->modification_of_pic_nums_idc == 0 || l->modification_of_pic_nums_idc == 1) {
1797 gint32 abs_diff_pic_num = l->value.abs_diff_pic_num_minus1 + 1;
1798 gint32 picNum, picNumNoWrap;
1801 if (l->modification_of_pic_nums_idc == 0) {
1802 picNumNoWrap = picNumPred - abs_diff_pic_num;
1803 if (picNumNoWrap < 0)
1804 picNumNoWrap += MaxPicNum;
1809 picNumNoWrap = picNumPred + abs_diff_pic_num;
1810 if (picNumNoWrap >= MaxPicNum)
1811 picNumNoWrap -= MaxPicNum;
1813 picNumPred = picNumNoWrap;
1816 picNum = picNumNoWrap;
1817 if (picNum > CurrPicNum)
1818 picNum -= MaxPicNum;
1821 for (j = num_refs; j > ref_list_idx; j--)
1822 ref_list[j] = ref_list[j - 1];
1823 found_ref_idx = find_short_term_reference(decoder, picNum);
1824 ref_list[ref_list_idx++] =
1825 found_ref_idx >= 0 ? priv->short_ref[found_ref_idx] : NULL;
1827 for (j = ref_list_idx; j <= num_refs; j++) {
1832 GST_VAAPI_PICTURE_IS_SHORT_TERM_REFERENCE(ref_list[j]) ?
1833 ref_list[j]->pic_num : MaxPicNum;
1834 if (PicNumF != picNum)
1835 ref_list[n++] = ref_list[j];
1839 /* 8.2.4.3.2 - Long-term reference pictures */
1842 for (j = num_refs; j > ref_list_idx; j--)
1843 ref_list[j] = ref_list[j - 1];
1845 find_long_term_reference(decoder, l->value.long_term_pic_num);
1846 ref_list[ref_list_idx++] =
1847 found_ref_idx >= 0 ? priv->long_ref[found_ref_idx] : NULL;
1849 for (j = ref_list_idx; j <= num_refs; j++) {
1850 gint32 LongTermPicNumF;
1854 GST_VAAPI_PICTURE_IS_LONG_TERM_REFERENCE(ref_list[j]) ?
1855 ref_list[j]->long_term_pic_num : INT_MAX;
1856 if (LongTermPicNumF != l->value.long_term_pic_num)
1857 ref_list[n++] = ref_list[j];
1863 for (i = 0; i < num_refs; i++)
1865 GST_ERROR("list %u entry %u is empty", list, i);
1867 *ref_list_count_ptr = num_refs;
1870 /* 8.2.4.3 - Modification process for reference picture lists */
1872 exec_picture_refs_modification(
1873 GstVaapiDecoderH264 *decoder,
1874 GstVaapiPictureH264 *picture,
1875 GstH264SliceHdr *slice_hdr
1878 GST_DEBUG("execute ref_pic_list_modification()");
1881 if (!GST_H264_IS_I_SLICE(slice_hdr) && !GST_H264_IS_SI_SLICE(slice_hdr) &&
1882 slice_hdr->ref_pic_list_modification_flag_l0)
1883 exec_picture_refs_modification_1(decoder, picture, slice_hdr, 0);
1886 if (GST_H264_IS_B_SLICE(slice_hdr) &&
1887 slice_hdr->ref_pic_list_modification_flag_l1)
1888 exec_picture_refs_modification_1(decoder, picture, slice_hdr, 1);
1892 init_picture_ref_lists(GstVaapiDecoderH264 *decoder)
1894 GstVaapiDecoderH264Private * const priv = &decoder->priv;
1895 guint i, j, short_ref_count, long_ref_count;
1897 short_ref_count = 0;
1899 if (GST_VAAPI_PICTURE_IS_FRAME(priv->current_picture)) {
1900 for (i = 0; i < priv->dpb_count; i++) {
1901 GstVaapiFrameStore * const fs = priv->dpb[i];
1902 GstVaapiPictureH264 *picture;
1903 if (!gst_vaapi_frame_store_has_frame(fs))
1905 picture = fs->buffers[0];
1906 if (GST_VAAPI_PICTURE_IS_SHORT_TERM_REFERENCE(picture))
1907 priv->short_ref[short_ref_count++] = picture;
1908 else if (GST_VAAPI_PICTURE_IS_LONG_TERM_REFERENCE(picture))
1909 priv->long_ref[long_ref_count++] = picture;
1910 picture->structure = GST_VAAPI_PICTURE_STRUCTURE_FRAME;
1911 picture->other_field = fs->buffers[1];
1915 for (i = 0; i < priv->dpb_count; i++) {
1916 GstVaapiFrameStore * const fs = priv->dpb[i];
1917 for (j = 0; j < fs->num_buffers; j++) {
1918 GstVaapiPictureH264 * const picture = fs->buffers[j];
1919 if (GST_VAAPI_PICTURE_IS_SHORT_TERM_REFERENCE(picture))
1920 priv->short_ref[short_ref_count++] = picture;
1921 else if (GST_VAAPI_PICTURE_IS_LONG_TERM_REFERENCE(picture))
1922 priv->long_ref[long_ref_count++] = picture;
1923 picture->structure = picture->base.structure;
1924 picture->other_field = fs->buffers[j ^ 1];
1929 for (i = short_ref_count; i < priv->short_ref_count; i++)
1930 priv->short_ref[i] = NULL;
1931 priv->short_ref_count = short_ref_count;
1933 for (i = long_ref_count; i < priv->long_ref_count; i++)
1934 priv->long_ref[i] = NULL;
1935 priv->long_ref_count = long_ref_count;
1940 GstVaapiDecoderH264 *decoder,
1941 GstVaapiPictureH264 *picture,
1942 GstH264SliceHdr *slice_hdr
1945 GstVaapiDecoderH264Private * const priv = &decoder->priv;
1946 GstVaapiPicture * const base_picture = &picture->base;
1949 init_picture_ref_lists(decoder);
1950 init_picture_refs_pic_num(decoder, picture, slice_hdr);
1952 priv->RefPicList0_count = 0;
1953 priv->RefPicList1_count = 0;
1955 switch (base_picture->type) {
1956 case GST_VAAPI_PICTURE_TYPE_P:
1957 case GST_VAAPI_PICTURE_TYPE_SP:
1958 init_picture_refs_p_slice(decoder, picture, slice_hdr);
1960 case GST_VAAPI_PICTURE_TYPE_B:
1961 init_picture_refs_b_slice(decoder, picture, slice_hdr);
1967 exec_picture_refs_modification(decoder, picture, slice_hdr);
1969 switch (base_picture->type) {
1970 case GST_VAAPI_PICTURE_TYPE_B:
1971 num_refs = 1 + slice_hdr->num_ref_idx_l1_active_minus1;
1972 for (i = priv->RefPicList1_count; i < num_refs; i++)
1973 priv->RefPicList1[i] = NULL;
1974 priv->RefPicList1_count = num_refs;
1977 case GST_VAAPI_PICTURE_TYPE_P:
1978 case GST_VAAPI_PICTURE_TYPE_SP:
1979 num_refs = 1 + slice_hdr->num_ref_idx_l0_active_minus1;
1980 for (i = priv->RefPicList0_count; i < num_refs; i++)
1981 priv->RefPicList0[i] = NULL;
1982 priv->RefPicList0_count = num_refs;
1991 GstVaapiDecoderH264 *decoder,
1992 GstVaapiPictureH264 *picture, GstVaapiParserInfoH264 *pi)
1994 GstVaapiDecoderH264Private * const priv = &decoder->priv;
1995 GstVaapiPicture * const base_picture = &picture->base;
1996 GstH264SliceHdr * const slice_hdr = &pi->data.slice_hdr;
1998 priv->prev_frame_num = priv->frame_num;
1999 priv->frame_num = slice_hdr->frame_num;
2000 picture->frame_num = priv->frame_num;
2001 picture->frame_num_wrap = priv->frame_num;
2002 picture->output_flag = TRUE; /* XXX: conformant to Annex A only */
2003 base_picture->pts = GST_VAAPI_DECODER_CODEC_FRAME(decoder)->pts;
2005 /* Reset decoder state for IDR pictures */
2006 if (pi->nalu.type == GST_H264_NAL_SLICE_IDR) {
2008 GST_VAAPI_PICTURE_FLAG_SET(picture, GST_VAAPI_PICTURE_FLAG_IDR);
2012 /* Initialize slice type */
2013 switch (slice_hdr->type % 5) {
2014 case GST_H264_P_SLICE:
2015 base_picture->type = GST_VAAPI_PICTURE_TYPE_P;
2017 case GST_H264_B_SLICE:
2018 base_picture->type = GST_VAAPI_PICTURE_TYPE_B;
2020 case GST_H264_I_SLICE:
2021 base_picture->type = GST_VAAPI_PICTURE_TYPE_I;
2023 case GST_H264_SP_SLICE:
2024 base_picture->type = GST_VAAPI_PICTURE_TYPE_SP;
2026 case GST_H264_SI_SLICE:
2027 base_picture->type = GST_VAAPI_PICTURE_TYPE_SI;
2031 /* Initialize picture structure */
2032 if (!slice_hdr->field_pic_flag)
2033 base_picture->structure = GST_VAAPI_PICTURE_STRUCTURE_FRAME;
2035 GST_VAAPI_PICTURE_FLAG_SET(picture, GST_VAAPI_PICTURE_FLAG_INTERLACED);
2036 if (!slice_hdr->bottom_field_flag)
2037 base_picture->structure = GST_VAAPI_PICTURE_STRUCTURE_TOP_FIELD;
2039 base_picture->structure = GST_VAAPI_PICTURE_STRUCTURE_BOTTOM_FIELD;
2041 picture->structure = base_picture->structure;
2043 /* Initialize reference flags */
2044 if (pi->nalu.ref_idc) {
2045 GstH264DecRefPicMarking * const dec_ref_pic_marking =
2046 &slice_hdr->dec_ref_pic_marking;
2048 if (GST_VAAPI_PICTURE_IS_IDR(picture) &&
2049 dec_ref_pic_marking->long_term_reference_flag)
2050 GST_VAAPI_PICTURE_FLAG_SET(picture,
2051 GST_VAAPI_PICTURE_FLAG_LONG_TERM_REFERENCE);
2053 GST_VAAPI_PICTURE_FLAG_SET(picture,
2054 GST_VAAPI_PICTURE_FLAG_SHORT_TERM_REFERENCE);
2057 init_picture_poc(decoder, picture, slice_hdr);
2058 init_picture_refs(decoder, picture, slice_hdr);
2062 /* 8.2.5.3 - Sliding window decoded reference picture marking process */
2064 exec_ref_pic_marking_sliding_window(GstVaapiDecoderH264 *decoder)
2066 GstVaapiDecoderH264Private * const priv = &decoder->priv;
2067 GstH264PPS * const pps = priv->current_picture->pps;
2068 GstH264SPS * const sps = pps->sequence;
2069 GstVaapiPictureH264 *ref_picture;
2070 guint i, m, max_num_ref_frames;
2072 GST_DEBUG("reference picture marking process (sliding window)");
2074 if (!GST_VAAPI_PICTURE_IS_FIRST_FIELD(priv->current_picture))
2077 max_num_ref_frames = sps->num_ref_frames;
2078 if (max_num_ref_frames == 0)
2079 max_num_ref_frames = 1;
2080 if (!GST_VAAPI_PICTURE_IS_FRAME(priv->current_picture))
2081 max_num_ref_frames <<= 1;
2083 if (priv->short_ref_count + priv->long_ref_count < max_num_ref_frames)
2085 if (priv->short_ref_count < 1)
2088 for (m = 0, i = 1; i < priv->short_ref_count; i++) {
2089 GstVaapiPictureH264 * const picture = priv->short_ref[i];
2090 if (picture->frame_num_wrap < priv->short_ref[m]->frame_num_wrap)
2094 ref_picture = priv->short_ref[m];
2095 gst_vaapi_picture_h264_set_reference(ref_picture, 0, TRUE);
2096 ARRAY_REMOVE_INDEX(priv->short_ref, m);
2098 /* Both fields need to be marked as "unused for reference", so
2099 remove the other field from the short_ref[] list as well */
2100 if (!GST_VAAPI_PICTURE_IS_FRAME(priv->current_picture) && ref_picture->other_field) {
2101 for (i = 0; i < priv->short_ref_count; i++) {
2102 if (priv->short_ref[i] == ref_picture->other_field) {
2103 ARRAY_REMOVE_INDEX(priv->short_ref, i);
2111 static inline gint32
2112 get_picNumX(GstVaapiPictureH264 *picture, GstH264RefPicMarking *ref_pic_marking)
2116 if (GST_VAAPI_PICTURE_IS_FRAME(picture))
2117 pic_num = picture->frame_num_wrap;
2119 pic_num = 2 * picture->frame_num_wrap + 1;
2120 pic_num -= ref_pic_marking->difference_of_pic_nums_minus1 + 1;
2124 /* 8.2.5.4.1. Mark short-term reference picture as "unused for reference" */
2126 exec_ref_pic_marking_adaptive_mmco_1(
2127 GstVaapiDecoderH264 *decoder,
2128 GstVaapiPictureH264 *picture,
2129 GstH264RefPicMarking *ref_pic_marking
2132 GstVaapiDecoderH264Private * const priv = &decoder->priv;
2135 picNumX = get_picNumX(picture, ref_pic_marking);
2136 i = find_short_term_reference(decoder, picNumX);
2140 gst_vaapi_picture_h264_set_reference(priv->short_ref[i], 0,
2141 GST_VAAPI_PICTURE_IS_FRAME(picture));
2142 ARRAY_REMOVE_INDEX(priv->short_ref, i);
2145 /* 8.2.5.4.2. Mark long-term reference picture as "unused for reference" */
2147 exec_ref_pic_marking_adaptive_mmco_2(
2148 GstVaapiDecoderH264 *decoder,
2149 GstVaapiPictureH264 *picture,
2150 GstH264RefPicMarking *ref_pic_marking
2153 GstVaapiDecoderH264Private * const priv = &decoder->priv;
2156 i = find_long_term_reference(decoder, ref_pic_marking->long_term_pic_num);
2160 gst_vaapi_picture_h264_set_reference(priv->long_ref[i], 0,
2161 GST_VAAPI_PICTURE_IS_FRAME(picture));
2162 ARRAY_REMOVE_INDEX(priv->long_ref, i);
2165 /* 8.2.5.4.3. Assign LongTermFrameIdx to a short-term reference picture */
2167 exec_ref_pic_marking_adaptive_mmco_3(
2168 GstVaapiDecoderH264 *decoder,
2169 GstVaapiPictureH264 *picture,
2170 GstH264RefPicMarking *ref_pic_marking
2173 GstVaapiDecoderH264Private * const priv = &decoder->priv;
2174 GstVaapiPictureH264 *ref_picture;
2177 for (i = 0; i < priv->long_ref_count; i++) {
2178 if (priv->long_ref[i]->long_term_frame_idx == ref_pic_marking->long_term_frame_idx)
2181 if (i != priv->long_ref_count) {
2182 gst_vaapi_picture_h264_set_reference(priv->long_ref[i], 0, TRUE);
2183 ARRAY_REMOVE_INDEX(priv->long_ref, i);
2186 picNumX = get_picNumX(picture, ref_pic_marking);
2187 i = find_short_term_reference(decoder, picNumX);
2191 ref_picture = priv->short_ref[i];
2192 ARRAY_REMOVE_INDEX(priv->short_ref, i);
2193 priv->long_ref[priv->long_ref_count++] = ref_picture;
2195 ref_picture->long_term_frame_idx = ref_pic_marking->long_term_frame_idx;
2196 gst_vaapi_picture_h264_set_reference(ref_picture,
2197 GST_VAAPI_PICTURE_FLAG_LONG_TERM_REFERENCE,
2198 GST_VAAPI_PICTURE_IS_FRAME(picture));
2201 /* 8.2.5.4.4. Mark pictures with LongTermFramIdx > max_long_term_frame_idx
2202 * as "unused for reference" */
2204 exec_ref_pic_marking_adaptive_mmco_4(
2205 GstVaapiDecoderH264 *decoder,
2206 GstVaapiPictureH264 *picture,
2207 GstH264RefPicMarking *ref_pic_marking
2210 GstVaapiDecoderH264Private * const priv = &decoder->priv;
2211 gint32 i, long_term_frame_idx;
2213 long_term_frame_idx = ref_pic_marking->max_long_term_frame_idx_plus1 - 1;
2215 for (i = 0; i < priv->long_ref_count; i++) {
2216 if (priv->long_ref[i]->long_term_frame_idx <= long_term_frame_idx)
2218 gst_vaapi_picture_h264_set_reference(priv->long_ref[i], 0, FALSE);
2219 ARRAY_REMOVE_INDEX(priv->long_ref, i);
2224 /* 8.2.5.4.5. Mark all reference pictures as "unused for reference" */
2226 exec_ref_pic_marking_adaptive_mmco_5(
2227 GstVaapiDecoderH264 *decoder,
2228 GstVaapiPictureH264 *picture,
2229 GstH264RefPicMarking *ref_pic_marking
2232 GstVaapiDecoderH264Private * const priv = &decoder->priv;
2236 priv->prev_pic_has_mmco5 = TRUE;
2238 /* The picture shall be inferred to have had frame_num equal to 0 (7.4.3) */
2239 priv->frame_num = 0;
2240 priv->frame_num_offset = 0;
2241 picture->frame_num = 0;
2243 /* Update TopFieldOrderCnt and BottomFieldOrderCnt (8.2.1) */
2244 if (picture->structure != GST_VAAPI_PICTURE_STRUCTURE_BOTTOM_FIELD)
2245 picture->field_poc[TOP_FIELD] -= picture->base.poc;
2246 if (picture->structure != GST_VAAPI_PICTURE_STRUCTURE_TOP_FIELD)
2247 picture->field_poc[BOTTOM_FIELD] -= picture->base.poc;
2248 picture->base.poc = 0;
2251 /* 8.2.5.4.6. Assign a long-term frame index to the current picture */
2253 exec_ref_pic_marking_adaptive_mmco_6(
2254 GstVaapiDecoderH264 *decoder,
2255 GstVaapiPictureH264 *picture,
2256 GstH264RefPicMarking *ref_pic_marking
2259 picture->long_term_frame_idx = ref_pic_marking->long_term_frame_idx;
2260 gst_vaapi_picture_h264_set_reference(picture,
2261 GST_VAAPI_PICTURE_FLAG_LONG_TERM_REFERENCE, FALSE);
2264 /* 8.2.5.4. Adaptive memory control decoded reference picture marking process */
2266 exec_ref_pic_marking_adaptive(
2267 GstVaapiDecoderH264 *decoder,
2268 GstVaapiPictureH264 *picture,
2269 GstH264DecRefPicMarking *dec_ref_pic_marking
2274 GST_DEBUG("reference picture marking process (adaptive memory control)");
2276 typedef void (*exec_ref_pic_marking_adaptive_mmco_func)(
2277 GstVaapiDecoderH264 *decoder,
2278 GstVaapiPictureH264 *picture,
2279 GstH264RefPicMarking *ref_pic_marking
2282 static const exec_ref_pic_marking_adaptive_mmco_func mmco_funcs[] = {
2284 exec_ref_pic_marking_adaptive_mmco_1,
2285 exec_ref_pic_marking_adaptive_mmco_2,
2286 exec_ref_pic_marking_adaptive_mmco_3,
2287 exec_ref_pic_marking_adaptive_mmco_4,
2288 exec_ref_pic_marking_adaptive_mmco_5,
2289 exec_ref_pic_marking_adaptive_mmco_6,
2292 for (i = 0; i < dec_ref_pic_marking->n_ref_pic_marking; i++) {
2293 GstH264RefPicMarking * const ref_pic_marking =
2294 &dec_ref_pic_marking->ref_pic_marking[i];
2296 const guint mmco = ref_pic_marking->memory_management_control_operation;
2297 if (mmco < G_N_ELEMENTS(mmco_funcs) && mmco_funcs[mmco])
2298 mmco_funcs[mmco](decoder, picture, ref_pic_marking);
2300 GST_ERROR("unhandled MMCO %u", mmco);
2307 /* 8.2.5 - Execute reference picture marking process */
2309 exec_ref_pic_marking(GstVaapiDecoderH264 *decoder, GstVaapiPictureH264 *picture)
2311 GstVaapiDecoderH264Private * const priv = &decoder->priv;
2313 priv->prev_pic_has_mmco5 = FALSE;
2314 priv->prev_pic_structure = picture->structure;
2316 if (!GST_VAAPI_PICTURE_IS_REFERENCE(picture))
2319 if (!GST_VAAPI_PICTURE_IS_IDR(picture)) {
2320 GstH264DecRefPicMarking * const dec_ref_pic_marking =
2321 &picture->last_slice_hdr->dec_ref_pic_marking;
2322 if (dec_ref_pic_marking->adaptive_ref_pic_marking_mode_flag) {
2323 if (!exec_ref_pic_marking_adaptive(decoder, picture, dec_ref_pic_marking))
2327 if (!exec_ref_pic_marking_sliding_window(decoder))
2335 vaapi_init_picture(VAPictureH264 *pic)
2337 pic->picture_id = VA_INVALID_ID;
2339 pic->flags = VA_PICTURE_H264_INVALID;
2340 pic->TopFieldOrderCnt = 0;
2341 pic->BottomFieldOrderCnt = 0;
2345 vaapi_fill_picture(VAPictureH264 *pic, GstVaapiPictureH264 *picture,
2346 guint picture_structure)
2348 if (!picture_structure)
2349 picture_structure = picture->structure;
2351 pic->picture_id = picture->base.surface_id;
2354 if (GST_VAAPI_PICTURE_IS_LONG_TERM_REFERENCE(picture)) {
2355 pic->flags |= VA_PICTURE_H264_LONG_TERM_REFERENCE;
2356 pic->frame_idx = picture->long_term_frame_idx;
2359 if (GST_VAAPI_PICTURE_IS_SHORT_TERM_REFERENCE(picture))
2360 pic->flags |= VA_PICTURE_H264_SHORT_TERM_REFERENCE;
2361 pic->frame_idx = picture->frame_num;
2364 switch (picture_structure) {
2365 case GST_VAAPI_PICTURE_STRUCTURE_FRAME:
2366 pic->TopFieldOrderCnt = picture->field_poc[TOP_FIELD];
2367 pic->BottomFieldOrderCnt = picture->field_poc[BOTTOM_FIELD];
2369 case GST_VAAPI_PICTURE_STRUCTURE_TOP_FIELD:
2370 pic->flags |= VA_PICTURE_H264_TOP_FIELD;
2371 pic->TopFieldOrderCnt = picture->field_poc[TOP_FIELD];
2372 pic->BottomFieldOrderCnt = 0;
2374 case GST_VAAPI_PICTURE_STRUCTURE_BOTTOM_FIELD:
2375 pic->flags |= VA_PICTURE_H264_BOTTOM_FIELD;
2376 pic->BottomFieldOrderCnt = picture->field_poc[BOTTOM_FIELD];
2377 pic->TopFieldOrderCnt = 0;
2383 fill_picture(GstVaapiDecoderH264 *decoder,
2384 GstVaapiPictureH264 *picture, GstVaapiParserInfoH264 *pi)
2386 GstVaapiDecoderH264Private * const priv = &decoder->priv;
2387 GstVaapiPicture * const base_picture = &picture->base;
2388 GstH264SliceHdr * const slice_hdr = &pi->data.slice_hdr;
2389 GstH264PPS * const pps = picture->pps;
2390 GstH264SPS * const sps = pps->sequence;
2391 VAPictureParameterBufferH264 * const pic_param = base_picture->param;
2394 /* Fill in VAPictureParameterBufferH264 */
2395 vaapi_fill_picture(&pic_param->CurrPic, picture, 0);
2397 for (i = 0, n = 0; i < priv->dpb_count; i++) {
2398 GstVaapiFrameStore * const fs = priv->dpb[i];
2399 if (gst_vaapi_frame_store_has_reference(fs))
2400 vaapi_fill_picture(&pic_param->ReferenceFrames[n++],
2401 fs->buffers[0], fs->structure);
2403 for (; n < G_N_ELEMENTS(pic_param->ReferenceFrames); n++)
2404 vaapi_init_picture(&pic_param->ReferenceFrames[n]);
2406 #define COPY_FIELD(s, f) \
2407 pic_param->f = (s)->f
2409 #define COPY_BFM(a, s, f) \
2410 pic_param->a.bits.f = (s)->f
2412 pic_param->picture_width_in_mbs_minus1 = priv->mb_width - 1;
2413 pic_param->picture_height_in_mbs_minus1 = priv->mb_height - 1;
2414 pic_param->frame_num = priv->frame_num;
2416 COPY_FIELD(sps, bit_depth_luma_minus8);
2417 COPY_FIELD(sps, bit_depth_chroma_minus8);
2418 COPY_FIELD(sps, num_ref_frames);
2419 COPY_FIELD(pps, num_slice_groups_minus1);
2420 COPY_FIELD(pps, slice_group_map_type);
2421 COPY_FIELD(pps, slice_group_change_rate_minus1);
2422 COPY_FIELD(pps, pic_init_qp_minus26);
2423 COPY_FIELD(pps, pic_init_qs_minus26);
2424 COPY_FIELD(pps, chroma_qp_index_offset);
2425 COPY_FIELD(pps, second_chroma_qp_index_offset);
2427 pic_param->seq_fields.value = 0; /* reset all bits */
2428 pic_param->seq_fields.bits.residual_colour_transform_flag = sps->separate_colour_plane_flag;
2429 pic_param->seq_fields.bits.MinLumaBiPredSize8x8 = sps->level_idc >= 31; /* A.3.3.2 */
2431 COPY_BFM(seq_fields, sps, chroma_format_idc);
2432 COPY_BFM(seq_fields, sps, gaps_in_frame_num_value_allowed_flag);
2433 COPY_BFM(seq_fields, sps, frame_mbs_only_flag);
2434 COPY_BFM(seq_fields, sps, mb_adaptive_frame_field_flag);
2435 COPY_BFM(seq_fields, sps, direct_8x8_inference_flag);
2436 COPY_BFM(seq_fields, sps, log2_max_frame_num_minus4);
2437 COPY_BFM(seq_fields, sps, pic_order_cnt_type);
2438 COPY_BFM(seq_fields, sps, log2_max_pic_order_cnt_lsb_minus4);
2439 COPY_BFM(seq_fields, sps, delta_pic_order_always_zero_flag);
2441 pic_param->pic_fields.value = 0; /* reset all bits */
2442 pic_param->pic_fields.bits.field_pic_flag = slice_hdr->field_pic_flag;
2443 pic_param->pic_fields.bits.reference_pic_flag = GST_VAAPI_PICTURE_IS_REFERENCE(picture);
2445 COPY_BFM(pic_fields, pps, entropy_coding_mode_flag);
2446 COPY_BFM(pic_fields, pps, weighted_pred_flag);
2447 COPY_BFM(pic_fields, pps, weighted_bipred_idc);
2448 COPY_BFM(pic_fields, pps, transform_8x8_mode_flag);
2449 COPY_BFM(pic_fields, pps, constrained_intra_pred_flag);
2450 COPY_BFM(pic_fields, pps, pic_order_present_flag);
2451 COPY_BFM(pic_fields, pps, deblocking_filter_control_present_flag);
2452 COPY_BFM(pic_fields, pps, redundant_pic_cnt_present_flag);
2456 /* Detection of the first VCL NAL unit of a primary coded picture (7.4.1.2.4) */
2458 is_new_picture(GstVaapiParserInfoH264 *pi, GstVaapiParserInfoH264 *prev_pi)
2460 GstH264SliceHdr * const slice_hdr = &pi->data.slice_hdr;
2461 GstH264PPS * const pps = slice_hdr->pps;
2462 GstH264SPS * const sps = pps->sequence;
2463 GstH264SliceHdr *prev_slice_hdr;
2467 prev_slice_hdr = &prev_pi->data.slice_hdr;
2469 #define CHECK_EXPR(expr, field_name) do { \
2471 GST_DEBUG(field_name " differs in value"); \
2476 #define CHECK_VALUE(new_slice_hdr, old_slice_hdr, field) \
2477 CHECK_EXPR(((new_slice_hdr)->field == (old_slice_hdr)->field), #field)
2479 /* frame_num differs in value, regardless of inferred values to 0 */
2480 CHECK_VALUE(slice_hdr, prev_slice_hdr, frame_num);
2482 /* pic_parameter_set_id differs in value */
2483 CHECK_VALUE(slice_hdr, prev_slice_hdr, pps);
2485 /* field_pic_flag differs in value */
2486 CHECK_VALUE(slice_hdr, prev_slice_hdr, field_pic_flag);
2488 /* bottom_field_flag is present in both and differs in value */
2489 if (slice_hdr->field_pic_flag && prev_slice_hdr->field_pic_flag)
2490 CHECK_VALUE(slice_hdr, prev_slice_hdr, bottom_field_flag);
2492 /* nal_ref_idc differs in value with one of the nal_ref_idc values is 0 */
2493 CHECK_EXPR((pi->nalu.ref_idc != 0) ==
2494 (prev_pi->nalu.ref_idc != 0), "nal_ref_idc");
2496 /* POC type is 0 for both and either pic_order_cnt_lsb differs in
2497 value or delta_pic_order_cnt_bottom differs in value */
2498 if (sps->pic_order_cnt_type == 0) {
2499 CHECK_VALUE(slice_hdr, prev_slice_hdr, pic_order_cnt_lsb);
2500 if (pps->pic_order_present_flag && !slice_hdr->field_pic_flag)
2501 CHECK_VALUE(slice_hdr, prev_slice_hdr, delta_pic_order_cnt_bottom);
2504 /* POC type is 1 for both and either delta_pic_order_cnt[0]
2505 differs in value or delta_pic_order_cnt[1] differs in value */
2506 else if (sps->pic_order_cnt_type == 1) {
2507 CHECK_VALUE(slice_hdr, prev_slice_hdr, delta_pic_order_cnt[0]);
2508 CHECK_VALUE(slice_hdr, prev_slice_hdr, delta_pic_order_cnt[1]);
2511 /* IdrPicFlag differs in value */
2512 CHECK_VALUE(&pi->nalu, &prev_pi->nalu, idr_pic_flag);
2514 /* IdrPicFlag is equal to 1 for both and idr_pic_id differs in value */
2515 if (pi->nalu.idr_pic_flag)
2516 CHECK_VALUE(slice_hdr, prev_slice_hdr, idr_pic_id);
2523 static GstVaapiDecoderStatus
2524 decode_picture(GstVaapiDecoderH264 *decoder, GstVaapiDecoderUnit *unit)
2526 GstVaapiDecoderH264Private * const priv = &decoder->priv;
2527 GstVaapiParserInfoH264 * const pi = unit->parsed_info;
2528 GstH264SliceHdr * const slice_hdr = &pi->data.slice_hdr;
2529 GstH264PPS * const pps = slice_hdr->pps;
2530 GstH264SPS * const sps = pps->sequence;
2531 GstVaapiPictureH264 *picture;
2532 GstVaapiDecoderStatus status;
2534 status = ensure_context(decoder, sps);
2535 if (status != GST_VAAPI_DECODER_STATUS_SUCCESS)
2538 if (priv->current_picture) {
2539 /* Re-use current picture where the first field was decoded */
2540 picture = gst_vaapi_picture_h264_new_field(priv->current_picture);
2542 GST_ERROR("failed to allocate field picture");
2543 return GST_VAAPI_DECODER_STATUS_ERROR_ALLOCATION_FAILED;
2547 /* Create new picture */
2548 picture = gst_vaapi_picture_h264_new(decoder);
2550 GST_ERROR("failed to allocate picture");
2551 return GST_VAAPI_DECODER_STATUS_ERROR_ALLOCATION_FAILED;
2554 gst_vaapi_picture_replace(&priv->current_picture, picture);
2555 gst_vaapi_picture_unref(picture);
2557 /* Update cropping rectangle */
2558 if (sps->frame_cropping_flag) {
2559 GstVaapiRectangle crop_rect;
2560 crop_rect.x = sps->crop_rect_x;
2561 crop_rect.y = sps->crop_rect_y;
2562 crop_rect.width = sps->crop_rect_width;
2563 crop_rect.height = sps->crop_rect_height;
2564 gst_vaapi_picture_set_crop_rect(&picture->base, &crop_rect);
2569 status = ensure_quant_matrix(decoder, picture);
2570 if (status != GST_VAAPI_DECODER_STATUS_SUCCESS) {
2571 GST_ERROR("failed to reset quantizer matrix");
2575 if (!init_picture(decoder, picture, pi))
2576 return GST_VAAPI_DECODER_STATUS_ERROR_UNKNOWN;
2577 if (!fill_picture(decoder, picture, pi))
2578 return GST_VAAPI_DECODER_STATUS_ERROR_UNKNOWN;
2579 return GST_VAAPI_DECODER_STATUS_SUCCESS;
2583 get_slice_data_bit_offset(GstH264SliceHdr *slice_hdr)
2587 epb_count = slice_hdr->n_emulation_prevention_bytes;
2588 return 8 /* nal_unit_type */ + slice_hdr->header_size - epb_count * 8;
2592 fill_pred_weight_table(GstVaapiDecoderH264 *decoder,
2593 GstVaapiSlice *slice, GstH264SliceHdr *slice_hdr)
2595 VASliceParameterBufferH264 * const slice_param = slice->param;
2596 GstH264PPS * const pps = slice_hdr->pps;
2597 GstH264SPS * const sps = pps->sequence;
2598 GstH264PredWeightTable * const w = &slice_hdr->pred_weight_table;
2599 guint num_weight_tables = 0;
2602 if (pps->weighted_pred_flag &&
2603 (GST_H264_IS_P_SLICE(slice_hdr) || GST_H264_IS_SP_SLICE(slice_hdr)))
2604 num_weight_tables = 1;
2605 else if (pps->weighted_bipred_idc == 1 && GST_H264_IS_B_SLICE(slice_hdr))
2606 num_weight_tables = 2;
2608 num_weight_tables = 0;
2610 slice_param->luma_log2_weight_denom = 0;
2611 slice_param->chroma_log2_weight_denom = 0;
2612 slice_param->luma_weight_l0_flag = 0;
2613 slice_param->chroma_weight_l0_flag = 0;
2614 slice_param->luma_weight_l1_flag = 0;
2615 slice_param->chroma_weight_l1_flag = 0;
2617 if (num_weight_tables < 1)
2620 slice_param->luma_log2_weight_denom = w->luma_log2_weight_denom;
2621 slice_param->chroma_log2_weight_denom = w->chroma_log2_weight_denom;
2623 slice_param->luma_weight_l0_flag = 1;
2624 for (i = 0; i <= slice_param->num_ref_idx_l0_active_minus1; i++) {
2625 slice_param->luma_weight_l0[i] = w->luma_weight_l0[i];
2626 slice_param->luma_offset_l0[i] = w->luma_offset_l0[i];
2629 slice_param->chroma_weight_l0_flag = sps->chroma_array_type != 0;
2630 if (slice_param->chroma_weight_l0_flag) {
2631 for (i = 0; i <= slice_param->num_ref_idx_l0_active_minus1; i++) {
2632 for (j = 0; j < 2; j++) {
2633 slice_param->chroma_weight_l0[i][j] = w->chroma_weight_l0[i][j];
2634 slice_param->chroma_offset_l0[i][j] = w->chroma_offset_l0[i][j];
2639 if (num_weight_tables < 2)
2642 slice_param->luma_weight_l1_flag = 1;
2643 for (i = 0; i <= slice_param->num_ref_idx_l1_active_minus1; i++) {
2644 slice_param->luma_weight_l1[i] = w->luma_weight_l1[i];
2645 slice_param->luma_offset_l1[i] = w->luma_offset_l1[i];
2648 slice_param->chroma_weight_l1_flag = sps->chroma_array_type != 0;
2649 if (slice_param->chroma_weight_l1_flag) {
2650 for (i = 0; i <= slice_param->num_ref_idx_l1_active_minus1; i++) {
2651 for (j = 0; j < 2; j++) {
2652 slice_param->chroma_weight_l1[i][j] = w->chroma_weight_l1[i][j];
2653 slice_param->chroma_offset_l1[i][j] = w->chroma_offset_l1[i][j];
2661 fill_RefPicList(GstVaapiDecoderH264 *decoder,
2662 GstVaapiSlice *slice, GstH264SliceHdr *slice_hdr)
2664 GstVaapiDecoderH264Private * const priv = &decoder->priv;
2665 VASliceParameterBufferH264 * const slice_param = slice->param;
2666 guint i, num_ref_lists = 0;
2668 slice_param->num_ref_idx_l0_active_minus1 = 0;
2669 slice_param->num_ref_idx_l1_active_minus1 = 0;
2671 if (GST_H264_IS_B_SLICE(slice_hdr))
2673 else if (GST_H264_IS_I_SLICE(slice_hdr))
2678 if (num_ref_lists < 1)
2681 slice_param->num_ref_idx_l0_active_minus1 =
2682 slice_hdr->num_ref_idx_l0_active_minus1;
2684 for (i = 0; i < priv->RefPicList0_count && priv->RefPicList0[i]; i++)
2685 vaapi_fill_picture(&slice_param->RefPicList0[i], priv->RefPicList0[i], 0);
2686 for (; i <= slice_param->num_ref_idx_l0_active_minus1; i++)
2687 vaapi_init_picture(&slice_param->RefPicList0[i]);
2689 if (num_ref_lists < 2)
2692 slice_param->num_ref_idx_l1_active_minus1 =
2693 slice_hdr->num_ref_idx_l1_active_minus1;
2695 for (i = 0; i < priv->RefPicList1_count && priv->RefPicList1[i]; i++)
2696 vaapi_fill_picture(&slice_param->RefPicList1[i], priv->RefPicList1[i], 0);
2697 for (; i <= slice_param->num_ref_idx_l1_active_minus1; i++)
2698 vaapi_init_picture(&slice_param->RefPicList1[i]);
2703 fill_slice(GstVaapiDecoderH264 *decoder,
2704 GstVaapiSlice *slice, GstH264SliceHdr *slice_hdr)
2706 VASliceParameterBufferH264 * const slice_param = slice->param;
2708 /* Fill in VASliceParameterBufferH264 */
2709 slice_param->slice_data_bit_offset = get_slice_data_bit_offset(slice_hdr);
2710 slice_param->first_mb_in_slice = slice_hdr->first_mb_in_slice;
2711 slice_param->slice_type = slice_hdr->type % 5;
2712 slice_param->direct_spatial_mv_pred_flag = slice_hdr->direct_spatial_mv_pred_flag;
2713 slice_param->cabac_init_idc = slice_hdr->cabac_init_idc;
2714 slice_param->slice_qp_delta = slice_hdr->slice_qp_delta;
2715 slice_param->disable_deblocking_filter_idc = slice_hdr->disable_deblocking_filter_idc;
2716 slice_param->slice_alpha_c0_offset_div2 = slice_hdr->slice_alpha_c0_offset_div2;
2717 slice_param->slice_beta_offset_div2 = slice_hdr->slice_beta_offset_div2;
2719 if (!fill_RefPicList(decoder, slice, slice_hdr))
2721 if (!fill_pred_weight_table(decoder, slice, slice_hdr))
2726 static GstVaapiDecoderStatus
2727 decode_slice(GstVaapiDecoderH264 *decoder, GstVaapiDecoderUnit *unit)
2729 GstVaapiDecoderH264Private * const priv = &decoder->priv;
2730 GstVaapiParserInfoH264 * const pi = unit->parsed_info;
2731 GstVaapiPictureH264 * const picture = priv->current_picture;
2732 GstH264SliceHdr * const slice_hdr = &pi->data.slice_hdr;
2733 GstVaapiSlice *slice;
2734 GstBuffer * const buffer =
2735 GST_VAAPI_DECODER_CODEC_FRAME(decoder)->input_buffer;
2736 GstMapInfo map_info;
2738 GST_DEBUG("slice (%u bytes)", pi->nalu.size);
2740 if (!priv->got_sps || !priv->got_pps) {
2741 GST_ERROR("not initialized yet");
2742 return GST_VAAPI_DECODER_STATUS_SUCCESS;
2745 if (!gst_buffer_map(buffer, &map_info, GST_MAP_READ)) {
2746 GST_ERROR("failed to map buffer");
2747 return GST_VAAPI_DECODER_STATUS_ERROR_UNKNOWN;
2750 slice = GST_VAAPI_SLICE_NEW(H264, decoder,
2751 (map_info.data + unit->offset + pi->nalu.offset), pi->nalu.size);
2752 gst_buffer_unmap(buffer, &map_info);
2754 GST_ERROR("failed to allocate slice");
2755 return GST_VAAPI_DECODER_STATUS_ERROR_ALLOCATION_FAILED;
2758 if (!fill_slice(decoder, slice, slice_hdr)) {
2759 gst_vaapi_mini_object_unref(GST_VAAPI_MINI_OBJECT(slice));
2760 return GST_VAAPI_DECODER_STATUS_ERROR_UNKNOWN;
2763 gst_vaapi_picture_add_slice(GST_VAAPI_PICTURE_CAST(picture), slice);
2764 picture->last_slice_hdr = slice_hdr;
2765 return GST_VAAPI_DECODER_STATUS_SUCCESS;
2769 scan_for_start_code(GstAdapter *adapter, guint ofs, guint size, guint32 *scp)
2771 return (gint)gst_adapter_masked_scan_uint32_peek(adapter,
2772 0xffffff00, 0x00000100,
2777 static GstVaapiDecoderStatus
2778 decode_unit(GstVaapiDecoderH264 *decoder, GstVaapiDecoderUnit *unit)
2780 GstVaapiParserInfoH264 * const pi = unit->parsed_info;
2781 GstVaapiDecoderStatus status;
2783 switch (pi->nalu.type) {
2784 case GST_H264_NAL_SLICE_IDR:
2785 /* fall-through. IDR specifics are handled in init_picture() */
2786 case GST_H264_NAL_SLICE:
2787 status = decode_slice(decoder, unit);
2789 case GST_H264_NAL_SEQ_END:
2790 case GST_H264_NAL_STREAM_END:
2791 status = decode_sequence_end(decoder);
2793 case GST_H264_NAL_SEI:
2794 status = GST_VAAPI_DECODER_STATUS_SUCCESS;
2797 GST_WARNING("unsupported NAL unit type %d", pi->nalu.type);
2798 status = GST_VAAPI_DECODER_STATUS_ERROR_BITSTREAM_PARSER;
2804 static GstVaapiDecoderStatus
2805 gst_vaapi_decoder_h264_decode_codec_data(GstVaapiDecoder *base_decoder,
2806 const guchar *buf, guint buf_size)
2808 GstVaapiDecoderH264 * const decoder =
2809 GST_VAAPI_DECODER_H264_CAST(base_decoder);
2810 GstVaapiDecoderH264Private * const priv = &decoder->priv;
2811 GstVaapiDecoderStatus status;
2812 GstVaapiDecoderUnit unit;
2813 GstVaapiParserInfoH264 pi;
2814 GstH264ParserResult result;
2815 guint i, ofs, num_sps, num_pps;
2817 unit.parsed_info = π
2820 return GST_VAAPI_DECODER_STATUS_ERROR_NO_DATA;
2823 GST_ERROR("failed to decode codec-data, not in avcC format");
2824 return GST_VAAPI_DECODER_STATUS_ERROR_BITSTREAM_PARSER;
2827 priv->nal_length_size = (buf[4] & 0x03) + 1;
2829 num_sps = buf[5] & 0x1f;
2832 for (i = 0; i < num_sps; i++) {
2833 result = gst_h264_parser_identify_nalu_avc(
2835 buf, ofs, buf_size, 2,
2838 if (result != GST_H264_PARSER_OK)
2839 return get_status(result);
2841 status = parse_sps(decoder, &unit);
2842 if (status != GST_VAAPI_DECODER_STATUS_SUCCESS)
2844 ofs = pi.nalu.offset + pi.nalu.size;
2850 for (i = 0; i < num_pps; i++) {
2851 result = gst_h264_parser_identify_nalu_avc(
2853 buf, ofs, buf_size, 2,
2856 if (result != GST_H264_PARSER_OK)
2857 return get_status(result);
2859 status = parse_pps(decoder, &unit);
2860 if (status != GST_VAAPI_DECODER_STATUS_SUCCESS)
2862 ofs = pi.nalu.offset + pi.nalu.size;
2865 priv->is_avcC = TRUE;
2866 return GST_VAAPI_DECODER_STATUS_SUCCESS;
2869 static GstVaapiDecoderStatus
2870 ensure_decoder(GstVaapiDecoderH264 *decoder)
2872 GstVaapiDecoderH264Private * const priv = &decoder->priv;
2873 GstVaapiDecoderStatus status;
2875 if (!priv->is_opened) {
2876 priv->is_opened = gst_vaapi_decoder_h264_open(decoder);
2877 if (!priv->is_opened)
2878 return GST_VAAPI_DECODER_STATUS_ERROR_UNSUPPORTED_CODEC;
2880 status = gst_vaapi_decoder_decode_codec_data(
2881 GST_VAAPI_DECODER_CAST(decoder));
2882 if (status != GST_VAAPI_DECODER_STATUS_SUCCESS)
2885 return GST_VAAPI_DECODER_STATUS_SUCCESS;
2888 static GstVaapiDecoderStatus
2889 gst_vaapi_decoder_h264_parse(GstVaapiDecoder *base_decoder,
2890 GstAdapter *adapter, gboolean at_eos, GstVaapiDecoderUnit *unit)
2892 GstVaapiDecoderH264 * const decoder =
2893 GST_VAAPI_DECODER_H264_CAST(base_decoder);
2894 GstVaapiDecoderH264Private * const priv = &decoder->priv;
2895 GstVaapiParserState * const ps = GST_VAAPI_PARSER_STATE(base_decoder);
2896 GstVaapiParserInfoH264 *pi;
2897 GstVaapiDecoderStatus status;
2898 GstH264ParserResult result;
2900 guint i, size, buf_size, nalu_size, flags;
2904 status = ensure_decoder(decoder);
2905 if (status != GST_VAAPI_DECODER_STATUS_SUCCESS)
2908 size = gst_adapter_available(adapter);
2910 if (priv->is_avcC) {
2911 if (size < priv->nal_length_size)
2912 return GST_VAAPI_DECODER_STATUS_ERROR_NO_DATA;
2914 buf = (guchar *)&start_code;
2915 g_assert(priv->nal_length_size <= sizeof(start_code));
2916 gst_adapter_copy(adapter, buf, 0, priv->nal_length_size);
2919 for (i = 0; i < priv->nal_length_size; i++)
2920 nalu_size = (nalu_size << 8) | buf[i];
2922 buf_size = priv->nal_length_size + nalu_size;
2923 if (size < buf_size)
2924 return GST_VAAPI_DECODER_STATUS_ERROR_NO_DATA;
2928 return GST_VAAPI_DECODER_STATUS_ERROR_NO_DATA;
2930 ofs = scan_for_start_code(adapter, 0, size, NULL);
2932 return GST_VAAPI_DECODER_STATUS_ERROR_NO_DATA;
2935 gst_adapter_flush(adapter, ofs);
2939 ofs2 = ps->input_offset2 - ofs - 4;
2943 ofs = G_UNLIKELY(size < ofs2 + 4) ? -1 :
2944 scan_for_start_code(adapter, ofs2, size - ofs2, NULL);
2946 // Assume the whole NAL unit is present if end-of-stream
2948 ps->input_offset2 = size;
2949 return GST_VAAPI_DECODER_STATUS_ERROR_NO_DATA;
2955 ps->input_offset2 = 0;
2957 buf = (guchar *)gst_adapter_map(adapter, buf_size);
2959 return GST_VAAPI_DECODER_STATUS_ERROR_NO_DATA;
2961 unit->size = buf_size;
2963 pi = gst_vaapi_parser_info_h264_new();
2965 return GST_VAAPI_DECODER_STATUS_ERROR_ALLOCATION_FAILED;
2967 gst_vaapi_decoder_unit_set_parsed_info(unit,
2968 pi, (GDestroyNotify)gst_vaapi_mini_object_unref);
2971 result = gst_h264_parser_identify_nalu_avc(priv->parser,
2972 buf, 0, buf_size, priv->nal_length_size, &pi->nalu);
2974 result = gst_h264_parser_identify_nalu_unchecked(priv->parser,
2975 buf, 0, buf_size, &pi->nalu);
2976 status = get_status(result);
2977 if (status != GST_VAAPI_DECODER_STATUS_SUCCESS)
2980 switch (pi->nalu.type) {
2981 case GST_H264_NAL_SPS:
2982 status = parse_sps(decoder, unit);
2984 case GST_H264_NAL_PPS:
2985 status = parse_pps(decoder, unit);
2987 case GST_H264_NAL_SEI:
2988 status = parse_sei(decoder, unit);
2990 case GST_H264_NAL_SLICE_IDR:
2991 case GST_H264_NAL_SLICE:
2992 status = parse_slice(decoder, unit);
2995 status = GST_VAAPI_DECODER_STATUS_SUCCESS;
2998 if (status != GST_VAAPI_DECODER_STATUS_SUCCESS)
3002 switch (pi->nalu.type) {
3003 case GST_H264_NAL_AU_DELIMITER:
3004 flags |= GST_VAAPI_DECODER_UNIT_FLAG_FRAME_START;
3006 case GST_H264_NAL_FILLER_DATA:
3007 flags |= GST_VAAPI_DECODER_UNIT_FLAG_SKIP;
3009 case GST_H264_NAL_STREAM_END:
3010 flags |= GST_VAAPI_DECODER_UNIT_FLAG_STREAM_END;
3012 case GST_H264_NAL_SEQ_END:
3013 flags |= GST_VAAPI_DECODER_UNIT_FLAG_FRAME_END;
3015 case GST_H264_NAL_SPS:
3016 case GST_H264_NAL_PPS:
3017 flags |= GST_VAAPI_DECODER_UNIT_FLAG_SKIP;
3019 case GST_H264_NAL_SEI:
3020 flags |= GST_VAAPI_DECODER_UNIT_FLAG_FRAME_START;
3022 case GST_H264_NAL_SLICE_IDR:
3023 case GST_H264_NAL_SLICE:
3024 flags |= GST_VAAPI_DECODER_UNIT_FLAG_SLICE;
3025 if (is_new_picture(pi, priv->prev_slice_pi))
3026 flags |= GST_VAAPI_DECODER_UNIT_FLAG_FRAME_START;
3027 gst_vaapi_parser_info_h264_replace(&priv->prev_slice_pi, pi);
3030 if (pi->nalu.type >= 14 && pi->nalu.type <= 18)
3031 flags |= GST_VAAPI_DECODER_UNIT_FLAG_FRAME_START;
3034 GST_VAAPI_DECODER_UNIT_FLAG_SET(unit, flags);
3036 pi->nalu.data = NULL;
3037 return GST_VAAPI_DECODER_STATUS_SUCCESS;
3040 static GstVaapiDecoderStatus
3041 gst_vaapi_decoder_h264_decode(GstVaapiDecoder *base_decoder,
3042 GstVaapiDecoderUnit *unit)
3044 GstVaapiDecoderH264 * const decoder =
3045 GST_VAAPI_DECODER_H264_CAST(base_decoder);
3046 GstVaapiDecoderStatus status;
3048 status = ensure_decoder(decoder);
3049 if (status != GST_VAAPI_DECODER_STATUS_SUCCESS)
3051 return decode_unit(decoder, unit);
3054 static GstVaapiDecoderStatus
3055 gst_vaapi_decoder_h264_start_frame(GstVaapiDecoder *base_decoder,
3056 GstVaapiDecoderUnit *unit)
3058 GstVaapiDecoderH264 * const decoder =
3059 GST_VAAPI_DECODER_H264_CAST(base_decoder);
3061 return decode_picture(decoder, unit);
3064 static GstVaapiDecoderStatus
3065 gst_vaapi_decoder_h264_end_frame(GstVaapiDecoder *base_decoder)
3067 GstVaapiDecoderH264 * const decoder =
3068 GST_VAAPI_DECODER_H264_CAST(base_decoder);
3070 return decode_current_picture(decoder);
3073 static GstVaapiDecoderStatus
3074 gst_vaapi_decoder_h264_flush(GstVaapiDecoder *base_decoder)
3076 GstVaapiDecoderH264 * const decoder =
3077 GST_VAAPI_DECODER_H264_CAST(base_decoder);
3080 return GST_VAAPI_DECODER_STATUS_SUCCESS;
3084 gst_vaapi_decoder_h264_class_init(GstVaapiDecoderH264Class *klass)
3086 GstVaapiMiniObjectClass * const object_class =
3087 GST_VAAPI_MINI_OBJECT_CLASS(klass);
3088 GstVaapiDecoderClass * const decoder_class = GST_VAAPI_DECODER_CLASS(klass);
3090 object_class->size = sizeof(GstVaapiDecoderH264);
3091 object_class->finalize = (GDestroyNotify)gst_vaapi_decoder_finalize;
3093 decoder_class->create = gst_vaapi_decoder_h264_create;
3094 decoder_class->destroy = gst_vaapi_decoder_h264_destroy;
3095 decoder_class->parse = gst_vaapi_decoder_h264_parse;
3096 decoder_class->decode = gst_vaapi_decoder_h264_decode;
3097 decoder_class->start_frame = gst_vaapi_decoder_h264_start_frame;
3098 decoder_class->end_frame = gst_vaapi_decoder_h264_end_frame;
3099 decoder_class->flush = gst_vaapi_decoder_h264_flush;
3101 decoder_class->decode_codec_data =
3102 gst_vaapi_decoder_h264_decode_codec_data;
3105 static inline const GstVaapiDecoderClass *
3106 gst_vaapi_decoder_h264_class(void)
3108 static GstVaapiDecoderH264Class g_class;
3109 static gsize g_class_init = FALSE;
3111 if (g_once_init_enter(&g_class_init)) {
3112 gst_vaapi_decoder_h264_class_init(&g_class);
3113 g_once_init_leave(&g_class_init, TRUE);
3115 return GST_VAAPI_DECODER_CLASS(&g_class);
3119 * gst_vaapi_decoder_h264_new:
3120 * @display: a #GstVaapiDisplay
3121 * @caps: a #GstCaps holding codec information
3123 * Creates a new #GstVaapiDecoder for MPEG-2 decoding. The @caps can
3124 * hold extra information like codec-data and pictured coded size.
3126 * Return value: the newly allocated #GstVaapiDecoder object
3129 gst_vaapi_decoder_h264_new(GstVaapiDisplay *display, GstCaps *caps)
3131 return gst_vaapi_decoder_new(gst_vaapi_decoder_h264_class(), display, caps);