2 * gstvaapidecoder_h264.c - H.264 decoder
4 * Copyright (C) 2011-2013 Intel Corporation
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public License
8 * as published by the Free Software Foundation; either version 2.1
9 * of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free
18 * Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
19 * Boston, MA 02110-1301 USA
23 * SECTION:gstvaapidecoder_h264
24 * @short_description: H.264 decoder
29 #include <gst/base/gstadapter.h>
30 #include <gst/codecparsers/gsth264parser.h>
31 #include "gstvaapidecoder_h264.h"
32 #include "gstvaapidecoder_objects.h"
33 #include "gstvaapidecoder_priv.h"
34 #include "gstvaapidisplay_priv.h"
35 #include "gstvaapiobject_priv.h"
38 #include "gstvaapidebug.h"
40 /* Defined to 1 if strict ordering of DPB is needed. Only useful for debug */
41 #define USE_STRICT_DPB_ORDERING 0
43 typedef struct _GstVaapiFrameStore GstVaapiFrameStore;
44 typedef struct _GstVaapiFrameStoreClass GstVaapiFrameStoreClass;
45 typedef struct _GstVaapiParserInfoH264 GstVaapiParserInfoH264;
46 typedef struct _GstVaapiPictureH264 GstVaapiPictureH264;
48 // Used for field_poc[]
50 #define BOTTOM_FIELD 1
52 /* ------------------------------------------------------------------------- */
53 /* --- H.264 Parser Info --- */
54 /* ------------------------------------------------------------------------- */
56 #define GST_VAAPI_PARSER_INFO_H264(obj) \
57 ((GstVaapiParserInfoH264 *)(obj))
59 struct _GstVaapiParserInfoH264 {
64 GstH264SliceHdr slice_hdr;
68 static inline const GstVaapiMiniObjectClass *
69 gst_vaapi_parser_info_h264_class(void)
71 static const GstVaapiMiniObjectClass GstVaapiParserInfoH264Class = {
72 sizeof(GstVaapiParserInfoH264),
75 return &GstVaapiParserInfoH264Class;
78 static inline GstVaapiParserInfoH264 *
79 gst_vaapi_parser_info_h264_new(void)
81 return (GstVaapiParserInfoH264 *)
82 gst_vaapi_mini_object_new(gst_vaapi_parser_info_h264_class());
85 #define gst_vaapi_parser_info_h264_ref(pi) \
86 gst_vaapi_mini_object_ref(GST_VAAPI_MINI_OBJECT(pi))
88 #define gst_vaapi_parser_info_h264_unref(pi) \
89 gst_vaapi_mini_object_unref(GST_VAAPI_MINI_OBJECT(pi))
91 #define gst_vaapi_parser_info_h264_replace(old_pi_ptr, new_pi) \
92 gst_vaapi_mini_object_replace((GstVaapiMiniObject **)(old_pi_ptr), \
93 (GstVaapiMiniObject *)(new_pi))
95 /* ------------------------------------------------------------------------- */
96 /* --- H.264 Pictures --- */
97 /* ------------------------------------------------------------------------- */
100 * Extended picture flags:
102 * @GST_VAAPI_PICTURE_FLAG_IDR: flag that specifies an IDR picture
103 * @GST_VAAPI_PICTURE_FLAG_SHORT_TERM_REFERENCE: flag that specifies
104 * "used for short-term reference"
105 * @GST_VAAPI_PICTURE_FLAG_LONG_TERM_REFERENCE: flag that specifies
106 * "used for long-term reference"
107 * @GST_VAAPI_PICTURE_FLAGS_REFERENCE: mask covering any kind of
108 * reference picture (short-term reference or long-term reference)
111 GST_VAAPI_PICTURE_FLAG_IDR = (GST_VAAPI_PICTURE_FLAG_LAST << 0),
113 GST_VAAPI_PICTURE_FLAG_SHORT_TERM_REFERENCE = (
114 GST_VAAPI_PICTURE_FLAG_REFERENCE),
115 GST_VAAPI_PICTURE_FLAG_LONG_TERM_REFERENCE = (
116 GST_VAAPI_PICTURE_FLAG_REFERENCE | (GST_VAAPI_PICTURE_FLAG_LAST << 1)),
117 GST_VAAPI_PICTURE_FLAGS_REFERENCE = (
118 GST_VAAPI_PICTURE_FLAG_SHORT_TERM_REFERENCE |
119 GST_VAAPI_PICTURE_FLAG_LONG_TERM_REFERENCE),
122 #define GST_VAAPI_PICTURE_IS_IDR(picture) \
123 (GST_VAAPI_PICTURE_FLAG_IS_SET(picture, GST_VAAPI_PICTURE_FLAG_IDR))
125 #define GST_VAAPI_PICTURE_IS_SHORT_TERM_REFERENCE(picture) \
126 ((GST_VAAPI_PICTURE_FLAGS(picture) & \
127 GST_VAAPI_PICTURE_FLAGS_REFERENCE) == \
128 GST_VAAPI_PICTURE_FLAG_SHORT_TERM_REFERENCE)
130 #define GST_VAAPI_PICTURE_IS_LONG_TERM_REFERENCE(picture) \
131 ((GST_VAAPI_PICTURE_FLAGS(picture) & \
132 GST_VAAPI_PICTURE_FLAGS_REFERENCE) == \
133 GST_VAAPI_PICTURE_FLAG_LONG_TERM_REFERENCE)
135 struct _GstVaapiPictureH264 {
136 GstVaapiPicture base;
138 GstH264SliceHdr *last_slice_hdr;
141 gint32 frame_num; // Original frame_num from slice_header()
142 gint32 frame_num_wrap; // Temporary for ref pic marking: FrameNumWrap
143 gint32 long_term_frame_idx; // Temporary for ref pic marking: LongTermFrameIdx
144 gint32 pic_num; // Temporary for ref pic marking: PicNum
145 gint32 long_term_pic_num; // Temporary for ref pic marking: LongTermPicNum
146 GstVaapiPictureH264 *other_field; // Temporary for ref pic marking: other field in the same frame store
147 guint output_flag : 1;
148 guint output_needed : 1;
151 GST_VAAPI_CODEC_DEFINE_TYPE(GstVaapiPictureH264, gst_vaapi_picture_h264);
154 gst_vaapi_picture_h264_destroy(GstVaapiPictureH264 *picture)
156 gst_vaapi_picture_destroy(GST_VAAPI_PICTURE(picture));
160 gst_vaapi_picture_h264_create(
161 GstVaapiPictureH264 *picture,
162 const GstVaapiCodecObjectConstructorArgs *args
165 if (!gst_vaapi_picture_create(GST_VAAPI_PICTURE(picture), args))
168 picture->field_poc[0] = G_MAXINT32;
169 picture->field_poc[1] = G_MAXINT32;
170 picture->output_needed = FALSE;
174 static inline GstVaapiPictureH264 *
175 gst_vaapi_picture_h264_new(GstVaapiDecoderH264 *decoder)
177 return (GstVaapiPictureH264 *)gst_vaapi_codec_object_new(
178 &GstVaapiPictureH264Class,
179 GST_VAAPI_CODEC_BASE(decoder),
180 NULL, sizeof(VAPictureParameterBufferH264),
186 gst_vaapi_picture_h264_set_reference(
187 GstVaapiPictureH264 *picture,
188 guint reference_flags,
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 g_return_val_if_fail(picture, NULL);
208 return (GstVaapiPictureH264 *)gst_vaapi_picture_new_field(&picture->base);
211 /* ------------------------------------------------------------------------- */
212 /* --- Frame Buffers (DPB) --- */
213 /* ------------------------------------------------------------------------- */
215 struct _GstVaapiFrameStore {
217 GstVaapiMiniObject parent_instance;
220 GstVaapiPictureH264 *buffers[2];
226 gst_vaapi_frame_store_finalize(gpointer object)
228 GstVaapiFrameStore * const fs = object;
231 for (i = 0; i < fs->num_buffers; i++)
232 gst_vaapi_picture_replace(&fs->buffers[i], NULL);
235 static GstVaapiFrameStore *
236 gst_vaapi_frame_store_new(GstVaapiPictureH264 *picture)
238 GstVaapiFrameStore *fs;
240 static const GstVaapiMiniObjectClass GstVaapiFrameStoreClass = {
241 sizeof(GstVaapiFrameStore),
242 gst_vaapi_frame_store_finalize
245 fs = (GstVaapiFrameStore *)
246 gst_vaapi_mini_object_new(&GstVaapiFrameStoreClass);
250 fs->structure = picture->structure;
251 fs->buffers[0] = gst_vaapi_picture_ref(picture);
252 fs->buffers[1] = NULL;
254 fs->output_needed = picture->output_needed;
259 gst_vaapi_frame_store_add(GstVaapiFrameStore *fs, GstVaapiPictureH264 *picture)
263 g_return_val_if_fail(fs->num_buffers == 1, FALSE);
264 g_return_val_if_fail(!GST_VAAPI_PICTURE_IS_FRAME(picture), FALSE);
265 g_return_val_if_fail(!GST_VAAPI_PICTURE_IS_FIRST_FIELD(picture), FALSE);
267 gst_vaapi_picture_replace(&fs->buffers[fs->num_buffers++], picture);
268 if (picture->output_flag) {
269 picture->output_needed = TRUE;
273 fs->structure = GST_VAAPI_PICTURE_STRUCTURE_FRAME;
275 field = picture->structure == GST_VAAPI_PICTURE_STRUCTURE_TOP_FIELD ?
276 TOP_FIELD : BOTTOM_FIELD;
277 g_return_val_if_fail(fs->buffers[0]->field_poc[field] == G_MAXINT32, FALSE);
278 fs->buffers[0]->field_poc[field] = picture->field_poc[field];
279 g_return_val_if_fail(picture->field_poc[!field] == G_MAXINT32, FALSE);
280 picture->field_poc[!field] = fs->buffers[0]->field_poc[!field];
285 gst_vaapi_frame_store_split_fields(GstVaapiFrameStore *fs)
287 GstVaapiPictureH264 * const first_field = fs->buffers[0];
288 GstVaapiPictureH264 *second_field;
290 g_return_val_if_fail(fs->num_buffers == 1, FALSE);
292 first_field->base.structure = GST_VAAPI_PICTURE_STRUCTURE_TOP_FIELD;
293 GST_VAAPI_PICTURE_FLAG_SET(first_field, GST_VAAPI_PICTURE_FLAG_INTERLACED);
295 second_field = gst_vaapi_picture_h264_new_field(first_field);
298 gst_vaapi_picture_replace(&fs->buffers[fs->num_buffers++], second_field);
299 gst_vaapi_picture_unref(second_field);
301 second_field->frame_num = first_field->frame_num;
302 second_field->field_poc[0] = first_field->field_poc[0];
303 second_field->field_poc[1] = first_field->field_poc[1];
304 second_field->output_flag = first_field->output_flag;
305 if (second_field->output_flag) {
306 second_field->output_needed = TRUE;
312 static inline gboolean
313 gst_vaapi_frame_store_has_frame(GstVaapiFrameStore *fs)
315 return fs->structure == GST_VAAPI_PICTURE_STRUCTURE_FRAME;
318 static inline gboolean
319 gst_vaapi_frame_store_has_reference(GstVaapiFrameStore *fs)
323 for (i = 0; i < fs->num_buffers; i++) {
324 if (GST_VAAPI_PICTURE_IS_REFERENCE(fs->buffers[i]))
330 #define gst_vaapi_frame_store_ref(fs) \
331 gst_vaapi_mini_object_ref(GST_VAAPI_MINI_OBJECT(fs))
333 #define gst_vaapi_frame_store_unref(fs) \
334 gst_vaapi_mini_object_unref(GST_VAAPI_MINI_OBJECT(fs))
336 #define gst_vaapi_frame_store_replace(old_fs_p, new_fs) \
337 gst_vaapi_mini_object_replace((GstVaapiMiniObject **)(old_fs_p), \
338 (GstVaapiMiniObject *)(new_fs))
340 /* ------------------------------------------------------------------------- */
341 /* --- H.264 Decoder --- */
342 /* ------------------------------------------------------------------------- */
344 G_DEFINE_TYPE(GstVaapiDecoderH264,
345 gst_vaapi_decoder_h264,
346 GST_VAAPI_TYPE_DECODER)
348 #define GST_VAAPI_DECODER_H264_CAST(decoder) \
349 ((GstVaapiDecoderH264 *)(decoder))
351 #define GST_VAAPI_DECODER_H264_GET_PRIVATE(obj) \
352 (G_TYPE_INSTANCE_GET_PRIVATE((obj), \
353 GST_VAAPI_TYPE_DECODER_H264, \
354 GstVaapiDecoderH264Private))
356 struct _GstVaapiDecoderH264Private {
357 GstH264NalParser *parser;
358 GstVaapiPictureH264 *current_picture;
359 GstVaapiParserInfoH264 *prev_slice_pi;
360 GstVaapiFrameStore *prev_frame;
361 GstVaapiFrameStore *dpb[16];
364 GstVaapiProfile profile;
365 GstVaapiEntrypoint entrypoint;
366 GstVaapiChromaType chroma_type;
367 GstVaapiPictureH264 *short_ref[32];
368 guint short_ref_count;
369 GstVaapiPictureH264 *long_ref[32];
370 guint long_ref_count;
371 GstVaapiPictureH264 *RefPicList0[32];
372 guint RefPicList0_count;
373 GstVaapiPictureH264 *RefPicList1[32];
374 guint RefPicList1_count;
375 guint nal_length_size;
378 gint32 field_poc[2]; // 0:TopFieldOrderCnt / 1:BottomFieldOrderCnt
379 gint32 poc_msb; // PicOrderCntMsb
380 gint32 poc_lsb; // pic_order_cnt_lsb (from slice_header())
381 gint32 prev_poc_msb; // prevPicOrderCntMsb
382 gint32 prev_poc_lsb; // prevPicOrderCntLsb
383 gint32 frame_num_offset; // FrameNumOffset
384 gint32 frame_num; // frame_num (from slice_header())
385 gint32 prev_frame_num; // prevFrameNum
386 gboolean prev_pic_has_mmco5; // prevMmco5Pic
387 gboolean prev_pic_structure; // previous picture structure
388 guint is_constructed : 1;
393 guint has_context : 1;
394 guint progressive_sequence : 1;
398 exec_ref_pic_marking(GstVaapiDecoderH264 *decoder, GstVaapiPictureH264 *picture);
400 /* Get number of reference frames to use */
402 get_max_dec_frame_buffering(GstH264SPS *sps)
404 guint max_dec_frame_buffering, MaxDpbMbs, PicSizeMbs;
406 /* Table A-1 - Level limits */
407 switch (sps->level_idc) {
408 case 10: MaxDpbMbs = 396; break;
409 case 11: MaxDpbMbs = 900; break;
410 case 12: MaxDpbMbs = 2376; break;
411 case 13: MaxDpbMbs = 2376; break;
412 case 20: MaxDpbMbs = 2376; break;
413 case 21: MaxDpbMbs = 4752; break;
414 case 22: MaxDpbMbs = 8100; break;
415 case 30: MaxDpbMbs = 8100; break;
416 case 31: MaxDpbMbs = 18000; break;
417 case 32: MaxDpbMbs = 20480; break;
418 case 40: MaxDpbMbs = 32768; break;
419 case 41: MaxDpbMbs = 32768; break;
420 case 42: MaxDpbMbs = 34816; break;
421 case 50: MaxDpbMbs = 110400; break;
422 case 51: MaxDpbMbs = 184320; break;
424 g_assert(0 && "unhandled level");
428 PicSizeMbs = ((sps->pic_width_in_mbs_minus1 + 1) *
429 (sps->pic_height_in_map_units_minus1 + 1) *
430 (sps->frame_mbs_only_flag ? 1 : 2));
431 max_dec_frame_buffering = MaxDpbMbs / PicSizeMbs;
434 if (sps->vui_parameters_present_flag) {
435 GstH264VUIParams * const vui_params = &sps->vui_parameters;
436 if (vui_params->bitstream_restriction_flag)
437 max_dec_frame_buffering = vui_params->max_dec_frame_buffering;
439 switch (sps->profile_idc) {
440 case 44: // CAVLC 4:4:4 Intra profile
441 case GST_H264_PROFILE_SCALABLE_HIGH:
442 case GST_H264_PROFILE_HIGH:
443 case GST_H264_PROFILE_HIGH10:
444 case GST_H264_PROFILE_HIGH_422:
445 case GST_H264_PROFILE_HIGH_444:
446 if (sps->constraint_set3_flag)
447 max_dec_frame_buffering = 0;
453 if (max_dec_frame_buffering > 16)
454 max_dec_frame_buffering = 16;
455 else if (max_dec_frame_buffering < sps->num_ref_frames)
456 max_dec_frame_buffering = sps->num_ref_frames;
457 return MAX(1, max_dec_frame_buffering);
461 array_remove_index_fast(void *array, guint *array_length_ptr, guint index)
463 gpointer * const entries = array;
464 guint num_entries = *array_length_ptr;
466 g_return_if_fail(index < num_entries);
468 if (index != --num_entries)
469 entries[index] = entries[num_entries];
470 entries[num_entries] = NULL;
471 *array_length_ptr = num_entries;
476 array_remove_index(void *array, guint *array_length_ptr, guint index)
478 array_remove_index_fast(array, array_length_ptr, index);
482 array_remove_index(void *array, guint *array_length_ptr, guint index)
484 gpointer * const entries = array;
485 const guint num_entries = *array_length_ptr - 1;
488 g_return_if_fail(index <= num_entries);
490 for (i = index; i < num_entries; i++)
491 entries[i] = entries[i + 1];
492 entries[num_entries] = NULL;
493 *array_length_ptr = num_entries;
497 #define ARRAY_REMOVE_INDEX(array, index) \
498 array_remove_index(array, &array##_count, index)
501 dpb_remove_index(GstVaapiDecoderH264 *decoder, guint index)
503 GstVaapiDecoderH264Private * const priv = decoder->priv;
504 guint i, num_frames = --priv->dpb_count;
506 if (USE_STRICT_DPB_ORDERING) {
507 for (i = index; i < num_frames; i++)
508 gst_vaapi_frame_store_replace(&priv->dpb[i], priv->dpb[i + 1]);
510 else if (index != num_frames)
511 gst_vaapi_frame_store_replace(&priv->dpb[index], priv->dpb[num_frames]);
512 gst_vaapi_frame_store_replace(&priv->dpb[num_frames], NULL);
517 GstVaapiDecoderH264 *decoder,
518 GstVaapiFrameStore *fs,
519 GstVaapiPictureH264 *picture
522 picture->output_needed = FALSE;
525 if (--fs->output_needed > 0)
527 picture = fs->buffers[0];
530 /* XXX: update cropping rectangle */
531 return gst_vaapi_picture_output(GST_VAAPI_PICTURE_CAST(picture));
535 dpb_evict(GstVaapiDecoderH264 *decoder, GstVaapiPictureH264 *picture, guint i)
537 GstVaapiFrameStore * const fs = decoder->priv->dpb[i];
539 if (!fs->output_needed && !gst_vaapi_frame_store_has_reference(fs))
540 dpb_remove_index(decoder, i);
544 dpb_bump(GstVaapiDecoderH264 *decoder)
546 GstVaapiDecoderH264Private * const priv = decoder->priv;
547 GstVaapiPictureH264 *found_picture = NULL;
548 guint i, j, found_index;
551 for (i = 0; i < priv->dpb_count; i++) {
552 GstVaapiFrameStore * const fs = priv->dpb[i];
553 if (!fs->output_needed)
555 for (j = 0; j < fs->num_buffers; j++) {
556 GstVaapiPictureH264 * const picture = fs->buffers[j];
557 if (!picture->output_needed)
559 if (!found_picture || found_picture->base.poc > picture->base.poc)
560 found_picture = picture, found_index = i;
566 success = dpb_output(decoder, priv->dpb[found_index], found_picture);
567 dpb_evict(decoder, found_picture, found_index);
572 dpb_clear(GstVaapiDecoderH264 *decoder)
574 GstVaapiDecoderH264Private * const priv = decoder->priv;
577 for (i = 0; i < priv->dpb_count; i++)
578 gst_vaapi_frame_store_replace(&priv->dpb[i], NULL);
581 gst_vaapi_frame_store_replace(&priv->prev_frame, NULL);
585 dpb_flush(GstVaapiDecoderH264 *decoder)
587 while (dpb_bump(decoder))
593 dpb_add(GstVaapiDecoderH264 *decoder, GstVaapiPictureH264 *picture)
595 GstVaapiDecoderH264Private * const priv = decoder->priv;
596 GstVaapiFrameStore *fs;
599 // Remove all unused pictures
600 if (!GST_VAAPI_PICTURE_IS_IDR(picture)) {
602 while (i < priv->dpb_count) {
603 GstVaapiFrameStore * const fs = priv->dpb[i];
604 if (!fs->output_needed && !gst_vaapi_frame_store_has_reference(fs))
605 dpb_remove_index(decoder, i);
611 // Check if picture is the second field and the first field is still in DPB
612 fs = priv->prev_frame;
613 if (fs && !gst_vaapi_frame_store_has_frame(fs))
614 return gst_vaapi_frame_store_add(fs, picture);
616 // Create new frame store, and split fields if necessary
617 fs = gst_vaapi_frame_store_new(picture);
620 gst_vaapi_frame_store_replace(&priv->prev_frame, fs);
621 gst_vaapi_frame_store_unref(fs);
623 if (!priv->progressive_sequence && gst_vaapi_frame_store_has_frame(fs)) {
624 if (!gst_vaapi_frame_store_split_fields(fs))
628 // C.4.5.1 - Storage and marking of a reference decoded picture into the DPB
629 if (GST_VAAPI_PICTURE_IS_REFERENCE(picture)) {
630 while (priv->dpb_count == priv->dpb_size) {
631 if (!dpb_bump(decoder))
634 gst_vaapi_frame_store_replace(&priv->dpb[priv->dpb_count++], fs);
635 if (picture->output_flag) {
636 picture->output_needed = TRUE;
641 // C.4.5.2 - Storage and marking of a non-reference decoded picture into the DPB
643 if (!picture->output_flag)
645 while (priv->dpb_count == priv->dpb_size) {
646 gboolean found_picture = FALSE;
647 for (i = 0; !found_picture && i < priv->dpb_count; i++) {
648 GstVaapiFrameStore * const fs = priv->dpb[i];
649 if (!fs->output_needed)
651 for (j = 0; !found_picture && j < fs->num_buffers; j++)
652 found_picture = fs->buffers[j]->output_needed &&
653 fs->buffers[j]->base.poc < picture->base.poc;
656 return dpb_output(decoder, NULL, picture);
657 if (!dpb_bump(decoder))
660 gst_vaapi_frame_store_replace(&priv->dpb[priv->dpb_count++], fs);
661 picture->output_needed = TRUE;
668 dpb_reset(GstVaapiDecoderH264 *decoder, GstH264SPS *sps)
670 GstVaapiDecoderH264Private * const priv = decoder->priv;
672 priv->dpb_size = get_max_dec_frame_buffering(sps);
673 GST_DEBUG("DPB size %u", priv->dpb_size);
676 static GstVaapiDecoderStatus
677 get_status(GstH264ParserResult result)
679 GstVaapiDecoderStatus status;
682 case GST_H264_PARSER_OK:
683 status = GST_VAAPI_DECODER_STATUS_SUCCESS;
685 case GST_H264_PARSER_NO_NAL_END:
686 status = GST_VAAPI_DECODER_STATUS_ERROR_NO_DATA;
688 case GST_H264_PARSER_ERROR:
689 status = GST_VAAPI_DECODER_STATUS_ERROR_BITSTREAM_PARSER;
692 status = GST_VAAPI_DECODER_STATUS_ERROR_UNKNOWN;
699 gst_vaapi_decoder_h264_close(GstVaapiDecoderH264 *decoder)
701 GstVaapiDecoderH264Private * const priv = decoder->priv;
703 gst_vaapi_picture_replace(&priv->current_picture, NULL);
704 gst_vaapi_parser_info_h264_replace(&priv->prev_slice_pi, NULL);
709 gst_h264_nal_parser_free(priv->parser);
715 gst_vaapi_decoder_h264_open(GstVaapiDecoderH264 *decoder)
717 GstVaapiDecoderH264Private * const priv = decoder->priv;
719 gst_vaapi_decoder_h264_close(decoder);
721 priv->parser = gst_h264_nal_parser_new();
728 gst_vaapi_decoder_h264_destroy(GstVaapiDecoderH264 *decoder)
730 gst_vaapi_decoder_h264_close(decoder);
734 gst_vaapi_decoder_h264_create(GstVaapiDecoderH264 *decoder)
736 if (!GST_VAAPI_DECODER_CODEC(decoder))
742 h264_get_profile(GstH264SPS *sps)
746 switch (sps->profile_idc) {
747 case GST_H264_PROFILE_BASELINE:
748 profile = GST_VAAPI_PROFILE_H264_BASELINE;
750 case GST_H264_PROFILE_MAIN:
751 profile = GST_VAAPI_PROFILE_H264_MAIN;
753 case GST_H264_PROFILE_HIGH:
754 profile = GST_VAAPI_PROFILE_H264_HIGH;
761 h264_get_chroma_type(GstH264SPS *sps)
763 guint chroma_type = 0;
765 switch (sps->chroma_format_idc) {
767 chroma_type = GST_VAAPI_CHROMA_TYPE_YUV420;
770 chroma_type = GST_VAAPI_CHROMA_TYPE_YUV422;
773 if (!sps->separate_colour_plane_flag)
774 chroma_type = GST_VAAPI_CHROMA_TYPE_YUV444;
780 static GstVaapiProfile
781 get_profile(GstVaapiDecoderH264 *decoder, GstH264SPS *sps)
783 GstVaapiDecoderH264Private * const priv = decoder->priv;
784 GstVaapiDisplay * const display = GST_VAAPI_DECODER_DISPLAY(decoder);
785 GstVaapiProfile profile, profiles[2];
786 guint i, n_profiles = 0;
788 profile = h264_get_profile(sps);
790 return GST_VAAPI_PROFILE_UNKNOWN;
792 profiles[n_profiles++] = profile;
794 case GST_VAAPI_PROFILE_H264_MAIN:
795 profiles[n_profiles++] = GST_VAAPI_PROFILE_H264_HIGH;
801 /* If the preferred profile (profiles[0]) matches one that we already
802 found, then just return it now instead of searching for it again */
803 if (profiles[0] == priv->profile)
804 return priv->profile;
806 for (i = 0; i < n_profiles; i++) {
807 if (gst_vaapi_display_has_decoder(display, profiles[i], priv->entrypoint))
810 return GST_VAAPI_PROFILE_UNKNOWN;
813 static GstVaapiDecoderStatus
814 ensure_context(GstVaapiDecoderH264 *decoder, GstH264SPS *sps)
816 GstVaapiDecoder * const base_decoder = GST_VAAPI_DECODER_CAST(decoder);
817 GstVaapiDecoderH264Private * const priv = decoder->priv;
818 GstVaapiContextInfo info;
819 GstVaapiProfile profile;
820 GstVaapiChromaType chroma_type;
821 gboolean reset_context = FALSE;
822 guint mb_width, mb_height;
824 profile = get_profile(decoder, sps);
826 GST_ERROR("unsupported profile_idc %u", sps->profile_idc);
827 return GST_VAAPI_DECODER_STATUS_ERROR_UNSUPPORTED_PROFILE;
830 if (priv->profile != profile) {
831 GST_DEBUG("profile changed");
832 reset_context = TRUE;
833 priv->profile = profile;
836 chroma_type = h264_get_chroma_type(sps);
837 if (!chroma_type || chroma_type != GST_VAAPI_CHROMA_TYPE_YUV420) {
838 GST_ERROR("unsupported chroma_format_idc %u", sps->chroma_format_idc);
839 return GST_VAAPI_DECODER_STATUS_ERROR_UNSUPPORTED_CHROMA_FORMAT;
842 if (priv->chroma_type != chroma_type) {
843 GST_DEBUG("chroma format changed");
844 reset_context = TRUE;
845 priv->chroma_type = chroma_type;
848 mb_width = sps->pic_width_in_mbs_minus1 + 1;
849 mb_height = (sps->pic_height_in_map_units_minus1 + 1) <<
850 !sps->frame_mbs_only_flag;
851 if (priv->mb_width != mb_width || priv->mb_height != mb_height) {
852 GST_DEBUG("size changed");
853 reset_context = TRUE;
854 priv->mb_width = mb_width;
855 priv->mb_height = mb_height;
858 priv->progressive_sequence = sps->frame_mbs_only_flag;
860 /* XXX: we only output complete frames for now */
861 gst_vaapi_decoder_set_interlaced(base_decoder, !priv->progressive_sequence);
864 gst_vaapi_decoder_set_pixel_aspect_ratio(
866 sps->vui_parameters.par_n,
867 sps->vui_parameters.par_d
870 if (!reset_context && priv->has_context)
871 return GST_VAAPI_DECODER_STATUS_SUCCESS;
873 /* XXX: fix surface size when cropping is implemented */
874 info.profile = priv->profile;
875 info.entrypoint = priv->entrypoint;
876 info.width = sps->width;
877 info.height = sps->height;
878 info.ref_frames = get_max_dec_frame_buffering(sps);
880 if (!gst_vaapi_decoder_ensure_context(GST_VAAPI_DECODER(decoder), &info))
881 return GST_VAAPI_DECODER_STATUS_ERROR_UNKNOWN;
882 priv->has_context = TRUE;
885 dpb_reset(decoder, sps);
886 return GST_VAAPI_DECODER_STATUS_SUCCESS;
890 fill_iq_matrix_4x4(VAIQMatrixBufferH264 *iq_matrix, const GstH264PPS *pps)
892 const guint8 (* const ScalingList4x4)[6][16] = &pps->scaling_lists_4x4;
895 /* There are always 6 4x4 scaling lists */
896 g_assert(G_N_ELEMENTS(iq_matrix->ScalingList4x4) == 6);
897 g_assert(G_N_ELEMENTS(iq_matrix->ScalingList4x4[0]) == 16);
899 if (sizeof(iq_matrix->ScalingList4x4[0][0]) == 1)
900 memcpy(iq_matrix->ScalingList4x4, *ScalingList4x4,
901 sizeof(iq_matrix->ScalingList4x4));
903 for (i = 0; i < G_N_ELEMENTS(iq_matrix->ScalingList4x4); i++) {
904 for (j = 0; j < G_N_ELEMENTS(iq_matrix->ScalingList4x4[i]); j++)
905 iq_matrix->ScalingList4x4[i][j] = (*ScalingList4x4)[i][j];
911 fill_iq_matrix_8x8(VAIQMatrixBufferH264 *iq_matrix, const GstH264PPS *pps)
913 const guint8 (* const ScalingList8x8)[6][64] = &pps->scaling_lists_8x8;
914 const GstH264SPS * const sps = pps->sequence;
917 /* If chroma_format_idc != 3, there are up to 2 8x8 scaling lists */
918 if (!pps->transform_8x8_mode_flag)
921 g_assert(G_N_ELEMENTS(iq_matrix->ScalingList8x8) >= 2);
922 g_assert(G_N_ELEMENTS(iq_matrix->ScalingList8x8[0]) == 64);
924 if (sizeof(iq_matrix->ScalingList8x8[0][0]) == 1)
925 memcpy(iq_matrix->ScalingList8x8, *ScalingList8x8,
926 sizeof(iq_matrix->ScalingList8x8));
928 n = (sps->chroma_format_idc != 3) ? 2 : 6;
929 for (i = 0; i < n; i++) {
930 for (j = 0; j < G_N_ELEMENTS(iq_matrix->ScalingList8x8[i]); j++)
931 iq_matrix->ScalingList8x8[i][j] = (*ScalingList8x8)[i][j];
936 static GstVaapiDecoderStatus
937 ensure_quant_matrix(GstVaapiDecoderH264 *decoder, GstVaapiPictureH264 *picture)
939 GstVaapiPicture * const base_picture = &picture->base;
940 GstH264PPS * const pps = picture->pps;
941 GstH264SPS * const sps = pps->sequence;
942 VAIQMatrixBufferH264 *iq_matrix;
944 base_picture->iq_matrix = GST_VAAPI_IQ_MATRIX_NEW(H264, decoder);
945 if (!base_picture->iq_matrix) {
946 GST_ERROR("failed to allocate IQ matrix");
947 return GST_VAAPI_DECODER_STATUS_ERROR_ALLOCATION_FAILED;
949 iq_matrix = base_picture->iq_matrix->param;
951 /* XXX: we can only support 4:2:0 or 4:2:2 since ScalingLists8x8[]
952 is not large enough to hold lists for 4:4:4 */
953 if (sps->chroma_format_idc == 3)
954 return GST_VAAPI_DECODER_STATUS_ERROR_UNSUPPORTED_CHROMA_FORMAT;
956 fill_iq_matrix_4x4(iq_matrix, pps);
957 fill_iq_matrix_8x8(iq_matrix, pps);
959 return GST_VAAPI_DECODER_STATUS_SUCCESS;
962 static GstVaapiDecoderStatus
963 decode_current_picture(GstVaapiDecoderH264 *decoder)
965 GstVaapiDecoderH264Private * const priv = decoder->priv;
966 GstVaapiPictureH264 * const picture = priv->current_picture;
969 return GST_VAAPI_DECODER_STATUS_SUCCESS;
971 if (!exec_ref_pic_marking(decoder, picture))
973 if (!dpb_add(decoder, picture))
975 if (!gst_vaapi_picture_decode(GST_VAAPI_PICTURE_CAST(picture)))
977 if (priv->prev_frame && gst_vaapi_frame_store_has_frame(priv->prev_frame))
978 gst_vaapi_picture_replace(&priv->current_picture, NULL);
979 return GST_VAAPI_DECODER_STATUS_SUCCESS;
982 /* XXX: fix for cases where first field failed to be decoded */
983 gst_vaapi_picture_replace(&priv->current_picture, NULL);
984 return GST_VAAPI_DECODER_STATUS_ERROR_UNKNOWN;
987 static GstVaapiDecoderStatus
988 parse_sps(GstVaapiDecoderH264 *decoder, GstVaapiDecoderUnit *unit)
990 GstVaapiDecoderH264Private * const priv = decoder->priv;
991 GstVaapiParserInfoH264 * const pi = unit->parsed_info;
992 GstH264SPS * const sps = &pi->data.sps;
993 GstH264ParserResult result;
995 GST_DEBUG("parse SPS");
997 /* Variables that don't have inferred values per the H.264
998 standard but that should get a default value anyway */
999 sps->log2_max_pic_order_cnt_lsb_minus4 = 0;
1001 result = gst_h264_parser_parse_sps(priv->parser, &pi->nalu, sps, TRUE);
1002 if (result != GST_H264_PARSER_OK)
1003 return get_status(result);
1005 priv->got_sps = TRUE;
1006 return GST_VAAPI_DECODER_STATUS_SUCCESS;
1009 static GstVaapiDecoderStatus
1010 parse_pps(GstVaapiDecoderH264 *decoder, GstVaapiDecoderUnit *unit)
1012 GstVaapiDecoderH264Private * const priv = decoder->priv;
1013 GstVaapiParserInfoH264 * const pi = unit->parsed_info;
1014 GstH264PPS * const pps = &pi->data.pps;
1015 GstH264ParserResult result;
1017 GST_DEBUG("parse PPS");
1019 /* Variables that don't have inferred values per the H.264
1020 standard but that should get a default value anyway */
1021 pps->slice_group_map_type = 0;
1022 pps->slice_group_change_rate_minus1 = 0;
1024 result = gst_h264_parser_parse_pps(priv->parser, &pi->nalu, pps);
1025 if (result != GST_H264_PARSER_OK)
1026 return get_status(result);
1028 priv->got_pps = TRUE;
1029 return GST_VAAPI_DECODER_STATUS_SUCCESS;
1032 static GstVaapiDecoderStatus
1033 parse_sei(GstVaapiDecoderH264 *decoder, GstVaapiDecoderUnit *unit)
1035 GstVaapiDecoderH264Private * const priv = decoder->priv;
1036 GstVaapiParserInfoH264 * const pi = unit->parsed_info;
1037 GstH264SEIMessage sei;
1038 GstH264ParserResult result;
1040 GST_DEBUG("parse SEI");
1042 memset(&sei, 0, sizeof(sei));
1043 result = gst_h264_parser_parse_sei(priv->parser, &pi->nalu, &sei);
1044 if (result != GST_H264_PARSER_OK) {
1045 GST_WARNING("failed to parse SEI, payload type:%d", sei.payloadType);
1046 return get_status(result);
1049 return GST_VAAPI_DECODER_STATUS_SUCCESS;
1052 static GstVaapiDecoderStatus
1053 parse_slice(GstVaapiDecoderH264 *decoder, GstVaapiDecoderUnit *unit)
1055 GstVaapiDecoderH264Private * const priv = decoder->priv;
1056 GstVaapiParserInfoH264 * const pi = unit->parsed_info;
1057 GstH264SliceHdr * const slice_hdr = &pi->data.slice_hdr;
1058 GstH264ParserResult result;
1060 GST_DEBUG("parse slice");
1062 /* Variables that don't have inferred values per the H.264
1063 standard but that should get a default value anyway */
1064 slice_hdr->cabac_init_idc = 0;
1065 slice_hdr->direct_spatial_mv_pred_flag = 0;
1067 result = gst_h264_parser_parse_slice_hdr(priv->parser, &pi->nalu,
1068 slice_hdr, TRUE, TRUE);
1069 if (result != GST_H264_PARSER_OK)
1070 return get_status(result);
1072 return GST_VAAPI_DECODER_STATUS_SUCCESS;
1075 static GstVaapiDecoderStatus
1076 decode_sequence_end(GstVaapiDecoderH264 *decoder)
1078 GstVaapiDecoderStatus status;
1080 GST_DEBUG("decode sequence-end");
1082 status = decode_current_picture(decoder);
1083 if (status != GST_VAAPI_DECODER_STATUS_SUCCESS)
1087 return GST_VAAPI_DECODER_STATUS_SUCCESS;
1090 /* 8.2.1.1 - Decoding process for picture order count type 0 */
1093 GstVaapiDecoderH264 *decoder,
1094 GstVaapiPictureH264 *picture,
1095 GstH264SliceHdr *slice_hdr
1098 GstVaapiDecoderH264Private * const priv = decoder->priv;
1099 GstH264PPS * const pps = slice_hdr->pps;
1100 GstH264SPS * const sps = pps->sequence;
1101 const gint32 MaxPicOrderCntLsb = 1 << (sps->log2_max_pic_order_cnt_lsb_minus4 + 4);
1104 GST_DEBUG("decode picture order count type 0");
1106 if (GST_VAAPI_PICTURE_IS_IDR(picture)) {
1107 priv->prev_poc_msb = 0;
1108 priv->prev_poc_lsb = 0;
1110 else if (priv->prev_pic_has_mmco5) {
1111 priv->prev_poc_msb = 0;
1112 priv->prev_poc_lsb =
1113 (priv->prev_pic_structure == GST_VAAPI_PICTURE_STRUCTURE_BOTTOM_FIELD ?
1114 0 : priv->field_poc[TOP_FIELD]);
1117 priv->prev_poc_msb = priv->poc_msb;
1118 priv->prev_poc_lsb = priv->poc_lsb;
1122 priv->poc_lsb = slice_hdr->pic_order_cnt_lsb;
1123 if (priv->poc_lsb < priv->prev_poc_lsb &&
1124 (priv->prev_poc_lsb - priv->poc_lsb) >= (MaxPicOrderCntLsb / 2))
1125 priv->poc_msb = priv->prev_poc_msb + MaxPicOrderCntLsb;
1126 else if (priv->poc_lsb > priv->prev_poc_lsb &&
1127 (priv->poc_lsb - priv->prev_poc_lsb) > (MaxPicOrderCntLsb / 2))
1128 priv->poc_msb = priv->prev_poc_msb - MaxPicOrderCntLsb;
1130 priv->poc_msb = priv->prev_poc_msb;
1132 temp_poc = priv->poc_msb + priv->poc_lsb;
1133 switch (picture->structure) {
1134 case GST_VAAPI_PICTURE_STRUCTURE_FRAME:
1136 priv->field_poc[TOP_FIELD] = temp_poc;
1137 priv->field_poc[BOTTOM_FIELD] = temp_poc +
1138 slice_hdr->delta_pic_order_cnt_bottom;
1140 case GST_VAAPI_PICTURE_STRUCTURE_TOP_FIELD:
1142 priv->field_poc[TOP_FIELD] = temp_poc;
1144 case GST_VAAPI_PICTURE_STRUCTURE_BOTTOM_FIELD:
1146 priv->field_poc[BOTTOM_FIELD] = temp_poc;
1151 /* 8.2.1.2 - Decoding process for picture order count type 1 */
1154 GstVaapiDecoderH264 *decoder,
1155 GstVaapiPictureH264 *picture,
1156 GstH264SliceHdr *slice_hdr
1159 GstVaapiDecoderH264Private * const priv = decoder->priv;
1160 GstH264PPS * const pps = slice_hdr->pps;
1161 GstH264SPS * const sps = pps->sequence;
1162 const gint32 MaxFrameNum = 1 << (sps->log2_max_frame_num_minus4 + 4);
1163 gint32 prev_frame_num_offset, abs_frame_num, expected_poc;
1166 GST_DEBUG("decode picture order count type 1");
1168 if (priv->prev_pic_has_mmco5)
1169 prev_frame_num_offset = 0;
1171 prev_frame_num_offset = priv->frame_num_offset;
1174 if (GST_VAAPI_PICTURE_IS_IDR(picture))
1175 priv->frame_num_offset = 0;
1176 else if (priv->prev_frame_num > priv->frame_num)
1177 priv->frame_num_offset = prev_frame_num_offset + MaxFrameNum;
1179 priv->frame_num_offset = prev_frame_num_offset;
1182 if (sps->num_ref_frames_in_pic_order_cnt_cycle != 0)
1183 abs_frame_num = priv->frame_num_offset + priv->frame_num;
1186 if (!GST_VAAPI_PICTURE_IS_REFERENCE(picture) && abs_frame_num > 0)
1187 abs_frame_num = abs_frame_num - 1;
1189 if (abs_frame_num > 0) {
1190 gint32 expected_delta_per_poc_cycle;
1191 gint32 poc_cycle_cnt, frame_num_in_poc_cycle;
1193 expected_delta_per_poc_cycle = 0;
1194 for (i = 0; i < sps->num_ref_frames_in_pic_order_cnt_cycle; i++)
1195 expected_delta_per_poc_cycle += sps->offset_for_ref_frame[i];
1198 poc_cycle_cnt = (abs_frame_num - 1) /
1199 sps->num_ref_frames_in_pic_order_cnt_cycle;
1200 frame_num_in_poc_cycle = (abs_frame_num - 1) %
1201 sps->num_ref_frames_in_pic_order_cnt_cycle;
1204 expected_poc = poc_cycle_cnt * expected_delta_per_poc_cycle;
1205 for (i = 0; i <= frame_num_in_poc_cycle; i++)
1206 expected_poc += sps->offset_for_ref_frame[i];
1210 if (!GST_VAAPI_PICTURE_IS_REFERENCE(picture))
1211 expected_poc += sps->offset_for_non_ref_pic;
1214 switch (picture->structure) {
1215 case GST_VAAPI_PICTURE_STRUCTURE_FRAME:
1216 priv->field_poc[TOP_FIELD] = expected_poc +
1217 slice_hdr->delta_pic_order_cnt[0];
1218 priv->field_poc[BOTTOM_FIELD] = priv->field_poc[TOP_FIELD] +
1219 sps->offset_for_top_to_bottom_field +
1220 slice_hdr->delta_pic_order_cnt[1];
1222 case GST_VAAPI_PICTURE_STRUCTURE_TOP_FIELD:
1223 priv->field_poc[TOP_FIELD] = expected_poc +
1224 slice_hdr->delta_pic_order_cnt[0];
1226 case GST_VAAPI_PICTURE_STRUCTURE_BOTTOM_FIELD:
1227 priv->field_poc[BOTTOM_FIELD] = expected_poc +
1228 sps->offset_for_top_to_bottom_field +
1229 slice_hdr->delta_pic_order_cnt[0];
1234 /* 8.2.1.3 - Decoding process for picture order count type 2 */
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 MaxFrameNum = 1 << (sps->log2_max_frame_num_minus4 + 4);
1246 gint32 prev_frame_num_offset, temp_poc;
1248 GST_DEBUG("decode picture order count type 2");
1250 if (priv->prev_pic_has_mmco5)
1251 prev_frame_num_offset = 0;
1253 prev_frame_num_offset = priv->frame_num_offset;
1256 if (GST_VAAPI_PICTURE_IS_IDR(picture))
1257 priv->frame_num_offset = 0;
1258 else if (priv->prev_frame_num > priv->frame_num)
1259 priv->frame_num_offset = prev_frame_num_offset + MaxFrameNum;
1261 priv->frame_num_offset = prev_frame_num_offset;
1264 if (GST_VAAPI_PICTURE_IS_IDR(picture))
1266 else if (!GST_VAAPI_PICTURE_IS_REFERENCE(picture))
1267 temp_poc = 2 * (priv->frame_num_offset + priv->frame_num) - 1;
1269 temp_poc = 2 * (priv->frame_num_offset + priv->frame_num);
1272 if (picture->structure != GST_VAAPI_PICTURE_STRUCTURE_BOTTOM_FIELD)
1273 priv->field_poc[TOP_FIELD] = temp_poc;
1274 if (picture->structure != GST_VAAPI_PICTURE_STRUCTURE_TOP_FIELD)
1275 priv->field_poc[BOTTOM_FIELD] = temp_poc;
1278 /* 8.2.1 - Decoding process for picture order count */
1281 GstVaapiDecoderH264 *decoder,
1282 GstVaapiPictureH264 *picture,
1283 GstH264SliceHdr *slice_hdr
1286 GstVaapiDecoderH264Private * const priv = decoder->priv;
1287 GstH264PPS * const pps = slice_hdr->pps;
1288 GstH264SPS * const sps = pps->sequence;
1290 switch (sps->pic_order_cnt_type) {
1292 init_picture_poc_0(decoder, picture, slice_hdr);
1295 init_picture_poc_1(decoder, picture, slice_hdr);
1298 init_picture_poc_2(decoder, picture, slice_hdr);
1302 if (picture->structure != GST_VAAPI_PICTURE_STRUCTURE_BOTTOM_FIELD)
1303 picture->field_poc[TOP_FIELD] = priv->field_poc[TOP_FIELD];
1304 if (picture->structure != GST_VAAPI_PICTURE_STRUCTURE_TOP_FIELD)
1305 picture->field_poc[BOTTOM_FIELD] = priv->field_poc[BOTTOM_FIELD];
1306 picture->base.poc = MIN(picture->field_poc[0], picture->field_poc[1]);
1310 compare_picture_pic_num_dec(const void *a, const void *b)
1312 const GstVaapiPictureH264 * const picA = *(GstVaapiPictureH264 **)a;
1313 const GstVaapiPictureH264 * const picB = *(GstVaapiPictureH264 **)b;
1315 return picB->pic_num - picA->pic_num;
1319 compare_picture_long_term_pic_num_inc(const void *a, const void *b)
1321 const GstVaapiPictureH264 * const picA = *(GstVaapiPictureH264 **)a;
1322 const GstVaapiPictureH264 * const picB = *(GstVaapiPictureH264 **)b;
1324 return picA->long_term_pic_num - picB->long_term_pic_num;
1328 compare_picture_poc_dec(const void *a, const void *b)
1330 const GstVaapiPictureH264 * const picA = *(GstVaapiPictureH264 **)a;
1331 const GstVaapiPictureH264 * const picB = *(GstVaapiPictureH264 **)b;
1333 return picB->base.poc - picA->base.poc;
1337 compare_picture_poc_inc(const void *a, const void *b)
1339 const GstVaapiPictureH264 * const picA = *(GstVaapiPictureH264 **)a;
1340 const GstVaapiPictureH264 * const picB = *(GstVaapiPictureH264 **)b;
1342 return picA->base.poc - picB->base.poc;
1346 compare_picture_frame_num_wrap_dec(const void *a, const void *b)
1348 const GstVaapiPictureH264 * const picA = *(GstVaapiPictureH264 **)a;
1349 const GstVaapiPictureH264 * const picB = *(GstVaapiPictureH264 **)b;
1351 return picB->frame_num_wrap - picA->frame_num_wrap;
1355 compare_picture_long_term_frame_idx_inc(const void *a, const void *b)
1357 const GstVaapiPictureH264 * const picA = *(GstVaapiPictureH264 **)a;
1358 const GstVaapiPictureH264 * const picB = *(GstVaapiPictureH264 **)b;
1360 return picA->long_term_frame_idx - picB->long_term_frame_idx;
1363 /* 8.2.4.1 - Decoding process for picture numbers */
1365 init_picture_refs_pic_num(
1366 GstVaapiDecoderH264 *decoder,
1367 GstVaapiPictureH264 *picture,
1368 GstH264SliceHdr *slice_hdr
1371 GstVaapiDecoderH264Private * const priv = decoder->priv;
1372 GstH264PPS * const pps = slice_hdr->pps;
1373 GstH264SPS * const sps = pps->sequence;
1374 const gint32 MaxFrameNum = 1 << (sps->log2_max_frame_num_minus4 + 4);
1377 GST_DEBUG("decode picture numbers");
1379 for (i = 0; i < priv->short_ref_count; i++) {
1380 GstVaapiPictureH264 * const pic = priv->short_ref[i];
1383 if (pic->frame_num > priv->frame_num)
1384 pic->frame_num_wrap = pic->frame_num - MaxFrameNum;
1386 pic->frame_num_wrap = pic->frame_num;
1388 // (8-28, 8-30, 8-31)
1389 if (GST_VAAPI_PICTURE_IS_FRAME(picture))
1390 pic->pic_num = pic->frame_num_wrap;
1392 if (pic->structure == picture->structure)
1393 pic->pic_num = 2 * pic->frame_num_wrap + 1;
1395 pic->pic_num = 2 * pic->frame_num_wrap;
1399 for (i = 0; i < priv->long_ref_count; i++) {
1400 GstVaapiPictureH264 * const pic = priv->long_ref[i];
1402 // (8-29, 8-32, 8-33)
1403 if (GST_VAAPI_PICTURE_IS_FRAME(picture))
1404 pic->long_term_pic_num = pic->long_term_frame_idx;
1406 if (pic->structure == picture->structure)
1407 pic->long_term_pic_num = 2 * pic->long_term_frame_idx + 1;
1409 pic->long_term_pic_num = 2 * pic->long_term_frame_idx;
1414 #define SORT_REF_LIST(list, n, compare_func) \
1415 qsort(list, n, sizeof(*(list)), compare_picture_##compare_func)
1418 init_picture_refs_fields_1(
1419 guint picture_structure,
1420 GstVaapiPictureH264 *RefPicList[32],
1421 guint *RefPicList_count,
1422 GstVaapiPictureH264 *ref_list[32],
1423 guint ref_list_count
1430 n = *RefPicList_count;
1433 for (; i < ref_list_count; i++) {
1434 if (ref_list[i]->structure == picture_structure) {
1435 RefPicList[n++] = ref_list[i++];
1439 for (; j < ref_list_count; j++) {
1440 if (ref_list[j]->structure != picture_structure) {
1441 RefPicList[n++] = ref_list[j++];
1445 } while (i < ref_list_count || j < ref_list_count);
1446 *RefPicList_count = n;
1450 init_picture_refs_fields(
1451 GstVaapiPictureH264 *picture,
1452 GstVaapiPictureH264 *RefPicList[32],
1453 guint *RefPicList_count,
1454 GstVaapiPictureH264 *short_ref[32],
1455 guint short_ref_count,
1456 GstVaapiPictureH264 *long_ref[32],
1457 guint long_ref_count
1462 /* 8.2.4.2.5 - reference picture lists in fields */
1463 init_picture_refs_fields_1(picture->structure, RefPicList, &n,
1464 short_ref, short_ref_count);
1465 init_picture_refs_fields_1(picture->structure, RefPicList, &n,
1466 long_ref, long_ref_count);
1467 *RefPicList_count = n;
1471 init_picture_refs_p_slice(
1472 GstVaapiDecoderH264 *decoder,
1473 GstVaapiPictureH264 *picture,
1474 GstH264SliceHdr *slice_hdr
1477 GstVaapiDecoderH264Private * const priv = decoder->priv;
1478 GstVaapiPictureH264 **ref_list;
1481 GST_DEBUG("decode reference picture list for P and SP slices");
1483 if (GST_VAAPI_PICTURE_IS_FRAME(picture)) {
1484 /* 8.2.4.2.1 - P and SP slices in frames */
1485 if (priv->short_ref_count > 0) {
1486 ref_list = priv->RefPicList0;
1487 for (i = 0; i < priv->short_ref_count; i++)
1488 ref_list[i] = priv->short_ref[i];
1489 SORT_REF_LIST(ref_list, i, pic_num_dec);
1490 priv->RefPicList0_count += i;
1493 if (priv->long_ref_count > 0) {
1494 ref_list = &priv->RefPicList0[priv->RefPicList0_count];
1495 for (i = 0; i < priv->long_ref_count; i++)
1496 ref_list[i] = priv->long_ref[i];
1497 SORT_REF_LIST(ref_list, i, long_term_pic_num_inc);
1498 priv->RefPicList0_count += i;
1502 /* 8.2.4.2.2 - P and SP slices in fields */
1503 GstVaapiPictureH264 *short_ref[32];
1504 guint short_ref_count = 0;
1505 GstVaapiPictureH264 *long_ref[32];
1506 guint long_ref_count = 0;
1508 if (priv->short_ref_count > 0) {
1509 for (i = 0; i < priv->short_ref_count; i++)
1510 short_ref[i] = priv->short_ref[i];
1511 SORT_REF_LIST(short_ref, i, frame_num_wrap_dec);
1512 short_ref_count = i;
1515 if (priv->long_ref_count > 0) {
1516 for (i = 0; i < priv->long_ref_count; i++)
1517 long_ref[i] = priv->long_ref[i];
1518 SORT_REF_LIST(long_ref, i, long_term_frame_idx_inc);
1522 init_picture_refs_fields(
1524 priv->RefPicList0, &priv->RefPicList0_count,
1525 short_ref, short_ref_count,
1526 long_ref, long_ref_count
1532 init_picture_refs_b_slice(
1533 GstVaapiDecoderH264 *decoder,
1534 GstVaapiPictureH264 *picture,
1535 GstH264SliceHdr *slice_hdr
1538 GstVaapiDecoderH264Private * const priv = decoder->priv;
1539 GstVaapiPictureH264 **ref_list;
1542 GST_DEBUG("decode reference picture list for B slices");
1544 if (GST_VAAPI_PICTURE_IS_FRAME(picture)) {
1545 /* 8.2.4.2.3 - B slices in frames */
1548 if (priv->short_ref_count > 0) {
1549 // 1. Short-term references
1550 ref_list = priv->RefPicList0;
1551 for (n = 0, i = 0; i < priv->short_ref_count; i++) {
1552 if (priv->short_ref[i]->base.poc < picture->base.poc)
1553 ref_list[n++] = priv->short_ref[i];
1555 SORT_REF_LIST(ref_list, n, poc_dec);
1556 priv->RefPicList0_count += n;
1558 ref_list = &priv->RefPicList0[priv->RefPicList0_count];
1559 for (n = 0, i = 0; i < priv->short_ref_count; i++) {
1560 if (priv->short_ref[i]->base.poc >= picture->base.poc)
1561 ref_list[n++] = priv->short_ref[i];
1563 SORT_REF_LIST(ref_list, n, poc_inc);
1564 priv->RefPicList0_count += n;
1567 if (priv->long_ref_count > 0) {
1568 // 2. Long-term references
1569 ref_list = &priv->RefPicList0[priv->RefPicList0_count];
1570 for (n = 0, i = 0; i < priv->long_ref_count; i++)
1571 ref_list[n++] = priv->long_ref[i];
1572 SORT_REF_LIST(ref_list, n, long_term_pic_num_inc);
1573 priv->RefPicList0_count += n;
1577 if (priv->short_ref_count > 0) {
1578 // 1. Short-term references
1579 ref_list = priv->RefPicList1;
1580 for (n = 0, i = 0; i < priv->short_ref_count; i++) {
1581 if (priv->short_ref[i]->base.poc > picture->base.poc)
1582 ref_list[n++] = priv->short_ref[i];
1584 SORT_REF_LIST(ref_list, n, poc_inc);
1585 priv->RefPicList1_count += n;
1587 ref_list = &priv->RefPicList1[priv->RefPicList1_count];
1588 for (n = 0, i = 0; i < priv->short_ref_count; i++) {
1589 if (priv->short_ref[i]->base.poc <= picture->base.poc)
1590 ref_list[n++] = priv->short_ref[i];
1592 SORT_REF_LIST(ref_list, n, poc_dec);
1593 priv->RefPicList1_count += n;
1596 if (priv->long_ref_count > 0) {
1597 // 2. Long-term references
1598 ref_list = &priv->RefPicList1[priv->RefPicList1_count];
1599 for (n = 0, i = 0; i < priv->long_ref_count; i++)
1600 ref_list[n++] = priv->long_ref[i];
1601 SORT_REF_LIST(ref_list, n, long_term_pic_num_inc);
1602 priv->RefPicList1_count += n;
1606 /* 8.2.4.2.4 - B slices in fields */
1607 GstVaapiPictureH264 *short_ref0[32];
1608 guint short_ref0_count = 0;
1609 GstVaapiPictureH264 *short_ref1[32];
1610 guint short_ref1_count = 0;
1611 GstVaapiPictureH264 *long_ref[32];
1612 guint long_ref_count = 0;
1614 /* refFrameList0ShortTerm */
1615 if (priv->short_ref_count > 0) {
1616 ref_list = short_ref0;
1617 for (n = 0, i = 0; i < priv->short_ref_count; i++) {
1618 if (priv->short_ref[i]->base.poc <= picture->base.poc)
1619 ref_list[n++] = priv->short_ref[i];
1621 SORT_REF_LIST(ref_list, n, poc_dec);
1622 short_ref0_count += n;
1624 ref_list = &short_ref0[short_ref0_count];
1625 for (n = 0, i = 0; i < priv->short_ref_count; i++) {
1626 if (priv->short_ref[i]->base.poc > picture->base.poc)
1627 ref_list[n++] = priv->short_ref[i];
1629 SORT_REF_LIST(ref_list, n, poc_inc);
1630 short_ref0_count += n;
1633 /* refFrameList1ShortTerm */
1634 if (priv->short_ref_count > 0) {
1635 ref_list = short_ref1;
1636 for (n = 0, i = 0; i < priv->short_ref_count; i++) {
1637 if (priv->short_ref[i]->base.poc > picture->base.poc)
1638 ref_list[n++] = priv->short_ref[i];
1640 SORT_REF_LIST(ref_list, n, poc_inc);
1641 short_ref1_count += n;
1643 ref_list = &short_ref1[short_ref1_count];
1644 for (n = 0, i = 0; i < priv->short_ref_count; i++) {
1645 if (priv->short_ref[i]->base.poc <= picture->base.poc)
1646 ref_list[n++] = priv->short_ref[i];
1648 SORT_REF_LIST(ref_list, n, poc_dec);
1649 short_ref1_count += n;
1652 /* refFrameListLongTerm */
1653 if (priv->long_ref_count > 0) {
1654 for (i = 0; i < priv->long_ref_count; i++)
1655 long_ref[i] = priv->long_ref[i];
1656 SORT_REF_LIST(long_ref, i, long_term_frame_idx_inc);
1660 init_picture_refs_fields(
1662 priv->RefPicList0, &priv->RefPicList0_count,
1663 short_ref0, short_ref0_count,
1664 long_ref, long_ref_count
1667 init_picture_refs_fields(
1669 priv->RefPicList1, &priv->RefPicList1_count,
1670 short_ref1, short_ref1_count,
1671 long_ref, long_ref_count
1675 /* Check whether RefPicList1 is identical to RefPicList0, then
1676 swap if necessary */
1677 if (priv->RefPicList1_count > 1 &&
1678 priv->RefPicList1_count == priv->RefPicList0_count &&
1679 memcmp(priv->RefPicList0, priv->RefPicList1,
1680 priv->RefPicList0_count * sizeof(priv->RefPicList0[0])) == 0) {
1681 GstVaapiPictureH264 * const tmp = priv->RefPicList1[0];
1682 priv->RefPicList1[0] = priv->RefPicList1[1];
1683 priv->RefPicList1[1] = tmp;
1687 #undef SORT_REF_LIST
1690 find_short_term_reference(GstVaapiDecoderH264 *decoder, gint32 pic_num)
1692 GstVaapiDecoderH264Private * const priv = decoder->priv;
1695 for (i = 0; i < priv->short_ref_count; i++) {
1696 if (priv->short_ref[i]->pic_num == pic_num)
1699 GST_ERROR("found no short-term reference picture with PicNum = %d",
1705 find_long_term_reference(GstVaapiDecoderH264 *decoder, gint32 long_term_pic_num)
1707 GstVaapiDecoderH264Private * const priv = decoder->priv;
1710 for (i = 0; i < priv->long_ref_count; i++) {
1711 if (priv->long_ref[i]->long_term_pic_num == long_term_pic_num)
1714 GST_ERROR("found no long-term reference picture with LongTermPicNum = %d",
1720 exec_picture_refs_modification_1(
1721 GstVaapiDecoderH264 *decoder,
1722 GstVaapiPictureH264 *picture,
1723 GstH264SliceHdr *slice_hdr,
1727 GstVaapiDecoderH264Private * const priv = decoder->priv;
1728 GstH264PPS * const pps = slice_hdr->pps;
1729 GstH264SPS * const sps = pps->sequence;
1730 GstH264RefPicListModification *ref_pic_list_modification;
1731 guint num_ref_pic_list_modifications;
1732 GstVaapiPictureH264 **ref_list;
1733 guint *ref_list_count_ptr, ref_list_count, ref_list_idx = 0;
1734 guint i, j, n, num_refs;
1736 gint32 MaxPicNum, CurrPicNum, picNumPred;
1738 GST_DEBUG("modification process of reference picture list %u", list);
1741 ref_pic_list_modification = slice_hdr->ref_pic_list_modification_l0;
1742 num_ref_pic_list_modifications = slice_hdr->n_ref_pic_list_modification_l0;
1743 ref_list = priv->RefPicList0;
1744 ref_list_count_ptr = &priv->RefPicList0_count;
1745 num_refs = slice_hdr->num_ref_idx_l0_active_minus1 + 1;
1748 ref_pic_list_modification = slice_hdr->ref_pic_list_modification_l1;
1749 num_ref_pic_list_modifications = slice_hdr->n_ref_pic_list_modification_l1;
1750 ref_list = priv->RefPicList1;
1751 ref_list_count_ptr = &priv->RefPicList1_count;
1752 num_refs = slice_hdr->num_ref_idx_l1_active_minus1 + 1;
1754 ref_list_count = *ref_list_count_ptr;
1756 if (!GST_VAAPI_PICTURE_IS_FRAME(picture)) {
1757 MaxPicNum = 1 << (sps->log2_max_frame_num_minus4 + 5); // 2 * MaxFrameNum
1758 CurrPicNum = 2 * slice_hdr->frame_num + 1; // 2 * frame_num + 1
1761 MaxPicNum = 1 << (sps->log2_max_frame_num_minus4 + 4); // MaxFrameNum
1762 CurrPicNum = slice_hdr->frame_num; // frame_num
1765 picNumPred = CurrPicNum;
1767 for (i = 0; i < num_ref_pic_list_modifications; i++) {
1768 GstH264RefPicListModification * const l = &ref_pic_list_modification[i];
1769 if (l->modification_of_pic_nums_idc == 3)
1772 /* 8.2.4.3.1 - Short-term reference pictures */
1773 if (l->modification_of_pic_nums_idc == 0 || l->modification_of_pic_nums_idc == 1) {
1774 gint32 abs_diff_pic_num = l->value.abs_diff_pic_num_minus1 + 1;
1775 gint32 picNum, picNumNoWrap;
1778 if (l->modification_of_pic_nums_idc == 0) {
1779 picNumNoWrap = picNumPred - abs_diff_pic_num;
1780 if (picNumNoWrap < 0)
1781 picNumNoWrap += MaxPicNum;
1786 picNumNoWrap = picNumPred + abs_diff_pic_num;
1787 if (picNumNoWrap >= MaxPicNum)
1788 picNumNoWrap -= MaxPicNum;
1790 picNumPred = picNumNoWrap;
1793 picNum = picNumNoWrap;
1794 if (picNum > CurrPicNum)
1795 picNum -= MaxPicNum;
1798 for (j = num_refs; j > ref_list_idx; j--)
1799 ref_list[j] = ref_list[j - 1];
1800 found_ref_idx = find_short_term_reference(decoder, picNum);
1801 ref_list[ref_list_idx++] =
1802 found_ref_idx >= 0 ? priv->short_ref[found_ref_idx] : NULL;
1804 for (j = ref_list_idx; j <= num_refs; j++) {
1809 GST_VAAPI_PICTURE_IS_SHORT_TERM_REFERENCE(ref_list[j]) ?
1810 ref_list[j]->pic_num : MaxPicNum;
1811 if (PicNumF != picNum)
1812 ref_list[n++] = ref_list[j];
1816 /* 8.2.4.3.2 - Long-term reference pictures */
1819 for (j = num_refs; j > ref_list_idx; j--)
1820 ref_list[j] = ref_list[j - 1];
1822 find_long_term_reference(decoder, l->value.long_term_pic_num);
1823 ref_list[ref_list_idx++] =
1824 found_ref_idx >= 0 ? priv->long_ref[found_ref_idx] : NULL;
1826 for (j = ref_list_idx; j <= num_refs; j++) {
1827 gint32 LongTermPicNumF;
1831 GST_VAAPI_PICTURE_IS_LONG_TERM_REFERENCE(ref_list[j]) ?
1832 ref_list[j]->long_term_pic_num : INT_MAX;
1833 if (LongTermPicNumF != l->value.long_term_pic_num)
1834 ref_list[n++] = ref_list[j];
1840 for (i = 0; i < num_refs; i++)
1842 GST_ERROR("list %u entry %u is empty", list, i);
1844 *ref_list_count_ptr = num_refs;
1847 /* 8.2.4.3 - Modification process for reference picture lists */
1849 exec_picture_refs_modification(
1850 GstVaapiDecoderH264 *decoder,
1851 GstVaapiPictureH264 *picture,
1852 GstH264SliceHdr *slice_hdr
1855 GST_DEBUG("execute ref_pic_list_modification()");
1858 if (!GST_H264_IS_I_SLICE(slice_hdr) && !GST_H264_IS_SI_SLICE(slice_hdr) &&
1859 slice_hdr->ref_pic_list_modification_flag_l0)
1860 exec_picture_refs_modification_1(decoder, picture, slice_hdr, 0);
1863 if (GST_H264_IS_B_SLICE(slice_hdr) &&
1864 slice_hdr->ref_pic_list_modification_flag_l1)
1865 exec_picture_refs_modification_1(decoder, picture, slice_hdr, 1);
1869 init_picture_ref_lists(GstVaapiDecoderH264 *decoder)
1871 GstVaapiDecoderH264Private * const priv = decoder->priv;
1872 guint i, j, short_ref_count, long_ref_count;
1874 short_ref_count = 0;
1876 if (GST_VAAPI_PICTURE_IS_FRAME(priv->current_picture)) {
1877 for (i = 0; i < priv->dpb_count; i++) {
1878 GstVaapiFrameStore * const fs = priv->dpb[i];
1879 GstVaapiPictureH264 *picture;
1880 if (!gst_vaapi_frame_store_has_frame(fs))
1882 picture = fs->buffers[0];
1883 if (GST_VAAPI_PICTURE_IS_SHORT_TERM_REFERENCE(picture))
1884 priv->short_ref[short_ref_count++] = picture;
1885 else if (GST_VAAPI_PICTURE_IS_LONG_TERM_REFERENCE(picture))
1886 priv->long_ref[long_ref_count++] = picture;
1887 picture->structure = GST_VAAPI_PICTURE_STRUCTURE_FRAME;
1888 picture->other_field = fs->buffers[1];
1892 for (i = 0; i < priv->dpb_count; i++) {
1893 GstVaapiFrameStore * const fs = priv->dpb[i];
1894 for (j = 0; j < fs->num_buffers; j++) {
1895 GstVaapiPictureH264 * const picture = fs->buffers[j];
1896 if (GST_VAAPI_PICTURE_IS_SHORT_TERM_REFERENCE(picture))
1897 priv->short_ref[short_ref_count++] = picture;
1898 else if (GST_VAAPI_PICTURE_IS_LONG_TERM_REFERENCE(picture))
1899 priv->long_ref[long_ref_count++] = picture;
1900 picture->structure = picture->base.structure;
1901 picture->other_field = fs->buffers[j ^ 1];
1906 for (i = short_ref_count; i < priv->short_ref_count; i++)
1907 priv->short_ref[i] = NULL;
1908 priv->short_ref_count = short_ref_count;
1910 for (i = long_ref_count; i < priv->long_ref_count; i++)
1911 priv->long_ref[i] = NULL;
1912 priv->long_ref_count = long_ref_count;
1917 GstVaapiDecoderH264 *decoder,
1918 GstVaapiPictureH264 *picture,
1919 GstH264SliceHdr *slice_hdr
1922 GstVaapiDecoderH264Private * const priv = decoder->priv;
1923 GstVaapiPicture * const base_picture = &picture->base;
1926 init_picture_ref_lists(decoder);
1927 init_picture_refs_pic_num(decoder, picture, slice_hdr);
1929 priv->RefPicList0_count = 0;
1930 priv->RefPicList1_count = 0;
1932 switch (base_picture->type) {
1933 case GST_VAAPI_PICTURE_TYPE_P:
1934 case GST_VAAPI_PICTURE_TYPE_SP:
1935 init_picture_refs_p_slice(decoder, picture, slice_hdr);
1937 case GST_VAAPI_PICTURE_TYPE_B:
1938 init_picture_refs_b_slice(decoder, picture, slice_hdr);
1944 exec_picture_refs_modification(decoder, picture, slice_hdr);
1946 switch (base_picture->type) {
1947 case GST_VAAPI_PICTURE_TYPE_B:
1948 num_refs = 1 + slice_hdr->num_ref_idx_l1_active_minus1;
1949 for (i = priv->RefPicList1_count; i < num_refs; i++)
1950 priv->RefPicList1[i] = NULL;
1951 priv->RefPicList1_count = num_refs;
1954 case GST_VAAPI_PICTURE_TYPE_P:
1955 case GST_VAAPI_PICTURE_TYPE_SP:
1956 num_refs = 1 + slice_hdr->num_ref_idx_l0_active_minus1;
1957 for (i = priv->RefPicList0_count; i < num_refs; i++)
1958 priv->RefPicList0[i] = NULL;
1959 priv->RefPicList0_count = num_refs;
1968 GstVaapiDecoderH264 *decoder,
1969 GstVaapiPictureH264 *picture, GstVaapiParserInfoH264 *pi)
1971 GstVaapiDecoderH264Private * const priv = decoder->priv;
1972 GstVaapiPicture * const base_picture = &picture->base;
1973 GstH264SliceHdr * const slice_hdr = &pi->data.slice_hdr;
1975 priv->prev_frame_num = priv->frame_num;
1976 priv->frame_num = slice_hdr->frame_num;
1977 picture->frame_num = priv->frame_num;
1978 picture->frame_num_wrap = priv->frame_num;
1979 picture->output_flag = TRUE; /* XXX: conformant to Annex A only */
1980 base_picture->pts = GST_VAAPI_DECODER_CODEC_FRAME(decoder)->pts;
1982 /* Reset decoder state for IDR pictures */
1983 if (pi->nalu.type == GST_H264_NAL_SLICE_IDR) {
1985 GST_VAAPI_PICTURE_FLAG_SET(picture, GST_VAAPI_PICTURE_FLAG_IDR);
1989 /* Initialize slice type */
1990 switch (slice_hdr->type % 5) {
1991 case GST_H264_P_SLICE:
1992 base_picture->type = GST_VAAPI_PICTURE_TYPE_P;
1994 case GST_H264_B_SLICE:
1995 base_picture->type = GST_VAAPI_PICTURE_TYPE_B;
1997 case GST_H264_I_SLICE:
1998 base_picture->type = GST_VAAPI_PICTURE_TYPE_I;
2000 case GST_H264_SP_SLICE:
2001 base_picture->type = GST_VAAPI_PICTURE_TYPE_SP;
2003 case GST_H264_SI_SLICE:
2004 base_picture->type = GST_VAAPI_PICTURE_TYPE_SI;
2008 /* Initialize picture structure */
2009 if (!slice_hdr->field_pic_flag)
2010 base_picture->structure = GST_VAAPI_PICTURE_STRUCTURE_FRAME;
2012 GST_VAAPI_PICTURE_FLAG_SET(picture, GST_VAAPI_PICTURE_FLAG_INTERLACED);
2013 if (!slice_hdr->bottom_field_flag)
2014 base_picture->structure = GST_VAAPI_PICTURE_STRUCTURE_TOP_FIELD;
2016 base_picture->structure = GST_VAAPI_PICTURE_STRUCTURE_BOTTOM_FIELD;
2018 picture->structure = base_picture->structure;
2020 /* Initialize reference flags */
2021 if (pi->nalu.ref_idc) {
2022 GstH264DecRefPicMarking * const dec_ref_pic_marking =
2023 &slice_hdr->dec_ref_pic_marking;
2025 if (GST_VAAPI_PICTURE_IS_IDR(picture) &&
2026 dec_ref_pic_marking->long_term_reference_flag)
2027 GST_VAAPI_PICTURE_FLAG_SET(picture,
2028 GST_VAAPI_PICTURE_FLAG_LONG_TERM_REFERENCE);
2030 GST_VAAPI_PICTURE_FLAG_SET(picture,
2031 GST_VAAPI_PICTURE_FLAG_SHORT_TERM_REFERENCE);
2034 init_picture_poc(decoder, picture, slice_hdr);
2035 init_picture_refs(decoder, picture, slice_hdr);
2039 /* 8.2.5.3 - Sliding window decoded reference picture marking process */
2041 exec_ref_pic_marking_sliding_window(GstVaapiDecoderH264 *decoder)
2043 GstVaapiDecoderH264Private * const priv = decoder->priv;
2044 GstH264PPS * const pps = priv->current_picture->pps;
2045 GstH264SPS * const sps = pps->sequence;
2046 GstVaapiPictureH264 *ref_picture;
2047 guint i, m, max_num_ref_frames;
2049 GST_DEBUG("reference picture marking process (sliding window)");
2051 if (!GST_VAAPI_PICTURE_IS_FIRST_FIELD(priv->current_picture))
2054 max_num_ref_frames = sps->num_ref_frames;
2055 if (max_num_ref_frames == 0)
2056 max_num_ref_frames = 1;
2057 if (!GST_VAAPI_PICTURE_IS_FRAME(priv->current_picture))
2058 max_num_ref_frames <<= 1;
2060 if (priv->short_ref_count + priv->long_ref_count < max_num_ref_frames)
2062 if (priv->short_ref_count < 1)
2065 for (m = 0, i = 1; i < priv->short_ref_count; i++) {
2066 GstVaapiPictureH264 * const picture = priv->short_ref[i];
2067 if (picture->frame_num_wrap < priv->short_ref[m]->frame_num_wrap)
2071 ref_picture = priv->short_ref[m];
2072 gst_vaapi_picture_h264_set_reference(ref_picture, 0, TRUE);
2073 ARRAY_REMOVE_INDEX(priv->short_ref, m);
2075 /* Both fields need to be marked as "unused for reference", so
2076 remove the other field from the short_ref[] list as well */
2077 if (!GST_VAAPI_PICTURE_IS_FRAME(priv->current_picture) && ref_picture->other_field) {
2078 for (i = 0; i < priv->short_ref_count; i++) {
2079 if (priv->short_ref[i] == ref_picture->other_field) {
2080 ARRAY_REMOVE_INDEX(priv->short_ref, i);
2088 static inline gint32
2089 get_picNumX(GstVaapiPictureH264 *picture, GstH264RefPicMarking *ref_pic_marking)
2093 if (GST_VAAPI_PICTURE_IS_FRAME(picture))
2094 pic_num = picture->frame_num_wrap;
2096 pic_num = 2 * picture->frame_num_wrap + 1;
2097 pic_num -= ref_pic_marking->difference_of_pic_nums_minus1 + 1;
2101 /* 8.2.5.4.1. Mark short-term reference picture as "unused for reference" */
2103 exec_ref_pic_marking_adaptive_mmco_1(
2104 GstVaapiDecoderH264 *decoder,
2105 GstVaapiPictureH264 *picture,
2106 GstH264RefPicMarking *ref_pic_marking
2109 GstVaapiDecoderH264Private * const priv = decoder->priv;
2112 picNumX = get_picNumX(picture, ref_pic_marking);
2113 i = find_short_term_reference(decoder, picNumX);
2117 gst_vaapi_picture_h264_set_reference(priv->short_ref[i], 0,
2118 GST_VAAPI_PICTURE_IS_FRAME(picture));
2119 ARRAY_REMOVE_INDEX(priv->short_ref, i);
2122 /* 8.2.5.4.2. Mark long-term reference picture as "unused for reference" */
2124 exec_ref_pic_marking_adaptive_mmco_2(
2125 GstVaapiDecoderH264 *decoder,
2126 GstVaapiPictureH264 *picture,
2127 GstH264RefPicMarking *ref_pic_marking
2130 GstVaapiDecoderH264Private * const priv = decoder->priv;
2133 i = find_long_term_reference(decoder, ref_pic_marking->long_term_pic_num);
2137 gst_vaapi_picture_h264_set_reference(priv->long_ref[i], 0,
2138 GST_VAAPI_PICTURE_IS_FRAME(picture));
2139 ARRAY_REMOVE_INDEX(priv->long_ref, i);
2142 /* 8.2.5.4.3. Assign LongTermFrameIdx to a short-term reference picture */
2144 exec_ref_pic_marking_adaptive_mmco_3(
2145 GstVaapiDecoderH264 *decoder,
2146 GstVaapiPictureH264 *picture,
2147 GstH264RefPicMarking *ref_pic_marking
2150 GstVaapiDecoderH264Private * const priv = decoder->priv;
2151 GstVaapiPictureH264 *ref_picture;
2154 for (i = 0; i < priv->long_ref_count; i++) {
2155 if (priv->long_ref[i]->long_term_frame_idx == ref_pic_marking->long_term_frame_idx)
2158 if (i != priv->long_ref_count) {
2159 gst_vaapi_picture_h264_set_reference(priv->long_ref[i], 0, TRUE);
2160 ARRAY_REMOVE_INDEX(priv->long_ref, i);
2163 picNumX = get_picNumX(picture, ref_pic_marking);
2164 i = find_short_term_reference(decoder, picNumX);
2168 ref_picture = priv->short_ref[i];
2169 ARRAY_REMOVE_INDEX(priv->short_ref, i);
2170 priv->long_ref[priv->long_ref_count++] = ref_picture;
2172 ref_picture->long_term_frame_idx = ref_pic_marking->long_term_frame_idx;
2173 gst_vaapi_picture_h264_set_reference(ref_picture,
2174 GST_VAAPI_PICTURE_FLAG_LONG_TERM_REFERENCE,
2175 GST_VAAPI_PICTURE_IS_FRAME(picture));
2178 /* 8.2.5.4.4. Mark pictures with LongTermFramIdx > max_long_term_frame_idx
2179 * as "unused for reference" */
2181 exec_ref_pic_marking_adaptive_mmco_4(
2182 GstVaapiDecoderH264 *decoder,
2183 GstVaapiPictureH264 *picture,
2184 GstH264RefPicMarking *ref_pic_marking
2187 GstVaapiDecoderH264Private * const priv = decoder->priv;
2188 gint32 i, long_term_frame_idx;
2190 long_term_frame_idx = ref_pic_marking->max_long_term_frame_idx_plus1 - 1;
2192 for (i = 0; i < priv->long_ref_count; i++) {
2193 if (priv->long_ref[i]->long_term_frame_idx <= long_term_frame_idx)
2195 gst_vaapi_picture_h264_set_reference(priv->long_ref[i], 0, FALSE);
2196 ARRAY_REMOVE_INDEX(priv->long_ref, i);
2201 /* 8.2.5.4.5. Mark all reference pictures as "unused for reference" */
2203 exec_ref_pic_marking_adaptive_mmco_5(
2204 GstVaapiDecoderH264 *decoder,
2205 GstVaapiPictureH264 *picture,
2206 GstH264RefPicMarking *ref_pic_marking
2209 GstVaapiDecoderH264Private * const priv = decoder->priv;
2213 priv->prev_pic_has_mmco5 = TRUE;
2215 /* The picture shall be inferred to have had frame_num equal to 0 (7.4.3) */
2216 priv->frame_num = 0;
2217 priv->frame_num_offset = 0;
2218 picture->frame_num = 0;
2220 /* Update TopFieldOrderCnt and BottomFieldOrderCnt (8.2.1) */
2221 if (picture->structure != GST_VAAPI_PICTURE_STRUCTURE_BOTTOM_FIELD)
2222 picture->field_poc[TOP_FIELD] -= picture->base.poc;
2223 if (picture->structure != GST_VAAPI_PICTURE_STRUCTURE_TOP_FIELD)
2224 picture->field_poc[BOTTOM_FIELD] -= picture->base.poc;
2225 picture->base.poc = 0;
2228 /* 8.2.5.4.6. Assign a long-term frame index to the current picture */
2230 exec_ref_pic_marking_adaptive_mmco_6(
2231 GstVaapiDecoderH264 *decoder,
2232 GstVaapiPictureH264 *picture,
2233 GstH264RefPicMarking *ref_pic_marking
2236 picture->long_term_frame_idx = ref_pic_marking->long_term_frame_idx;
2237 gst_vaapi_picture_h264_set_reference(picture,
2238 GST_VAAPI_PICTURE_FLAG_LONG_TERM_REFERENCE, FALSE);
2241 /* 8.2.5.4. Adaptive memory control decoded reference picture marking process */
2243 exec_ref_pic_marking_adaptive(
2244 GstVaapiDecoderH264 *decoder,
2245 GstVaapiPictureH264 *picture,
2246 GstH264DecRefPicMarking *dec_ref_pic_marking
2251 GST_DEBUG("reference picture marking process (adaptive memory control)");
2253 typedef void (*exec_ref_pic_marking_adaptive_mmco_func)(
2254 GstVaapiDecoderH264 *decoder,
2255 GstVaapiPictureH264 *picture,
2256 GstH264RefPicMarking *ref_pic_marking
2259 static const exec_ref_pic_marking_adaptive_mmco_func mmco_funcs[] = {
2261 exec_ref_pic_marking_adaptive_mmco_1,
2262 exec_ref_pic_marking_adaptive_mmco_2,
2263 exec_ref_pic_marking_adaptive_mmco_3,
2264 exec_ref_pic_marking_adaptive_mmco_4,
2265 exec_ref_pic_marking_adaptive_mmco_5,
2266 exec_ref_pic_marking_adaptive_mmco_6,
2269 for (i = 0; i < dec_ref_pic_marking->n_ref_pic_marking; i++) {
2270 GstH264RefPicMarking * const ref_pic_marking =
2271 &dec_ref_pic_marking->ref_pic_marking[i];
2273 const guint mmco = ref_pic_marking->memory_management_control_operation;
2274 if (mmco < G_N_ELEMENTS(mmco_funcs) && mmco_funcs[mmco])
2275 mmco_funcs[mmco](decoder, picture, ref_pic_marking);
2277 GST_ERROR("unhandled MMCO %u", mmco);
2284 /* 8.2.5 - Execute reference picture marking process */
2286 exec_ref_pic_marking(GstVaapiDecoderH264 *decoder, GstVaapiPictureH264 *picture)
2288 GstVaapiDecoderH264Private * const priv = decoder->priv;
2290 priv->prev_pic_has_mmco5 = FALSE;
2291 priv->prev_pic_structure = picture->structure;
2293 if (!GST_VAAPI_PICTURE_IS_REFERENCE(picture))
2296 if (!GST_VAAPI_PICTURE_IS_IDR(picture)) {
2297 GstH264DecRefPicMarking * const dec_ref_pic_marking =
2298 &picture->last_slice_hdr->dec_ref_pic_marking;
2299 if (dec_ref_pic_marking->adaptive_ref_pic_marking_mode_flag) {
2300 if (!exec_ref_pic_marking_adaptive(decoder, picture, dec_ref_pic_marking))
2304 if (!exec_ref_pic_marking_sliding_window(decoder))
2312 vaapi_init_picture(VAPictureH264 *pic)
2314 pic->picture_id = VA_INVALID_ID;
2316 pic->flags = VA_PICTURE_H264_INVALID;
2317 pic->TopFieldOrderCnt = 0;
2318 pic->BottomFieldOrderCnt = 0;
2322 vaapi_fill_picture(VAPictureH264 *pic, GstVaapiPictureH264 *picture,
2323 guint picture_structure)
2325 if (!picture_structure)
2326 picture_structure = picture->structure;
2328 pic->picture_id = picture->base.surface_id;
2331 if (GST_VAAPI_PICTURE_IS_LONG_TERM_REFERENCE(picture)) {
2332 pic->flags |= VA_PICTURE_H264_LONG_TERM_REFERENCE;
2333 pic->frame_idx = picture->long_term_frame_idx;
2336 if (GST_VAAPI_PICTURE_IS_SHORT_TERM_REFERENCE(picture))
2337 pic->flags |= VA_PICTURE_H264_SHORT_TERM_REFERENCE;
2338 pic->frame_idx = picture->frame_num;
2341 switch (picture_structure) {
2342 case GST_VAAPI_PICTURE_STRUCTURE_FRAME:
2343 pic->TopFieldOrderCnt = picture->field_poc[TOP_FIELD];
2344 pic->BottomFieldOrderCnt = picture->field_poc[BOTTOM_FIELD];
2346 case GST_VAAPI_PICTURE_STRUCTURE_TOP_FIELD:
2347 pic->flags |= VA_PICTURE_H264_TOP_FIELD;
2348 pic->TopFieldOrderCnt = picture->field_poc[TOP_FIELD];
2349 pic->BottomFieldOrderCnt = 0;
2351 case GST_VAAPI_PICTURE_STRUCTURE_BOTTOM_FIELD:
2352 pic->flags |= VA_PICTURE_H264_BOTTOM_FIELD;
2353 pic->BottomFieldOrderCnt = picture->field_poc[BOTTOM_FIELD];
2354 pic->TopFieldOrderCnt = 0;
2360 fill_picture(GstVaapiDecoderH264 *decoder,
2361 GstVaapiPictureH264 *picture, GstVaapiParserInfoH264 *pi)
2363 GstVaapiDecoderH264Private * const priv = decoder->priv;
2364 GstVaapiPicture * const base_picture = &picture->base;
2365 GstH264SliceHdr * const slice_hdr = &pi->data.slice_hdr;
2366 GstH264PPS * const pps = picture->pps;
2367 GstH264SPS * const sps = pps->sequence;
2368 VAPictureParameterBufferH264 * const pic_param = base_picture->param;
2371 /* Fill in VAPictureParameterBufferH264 */
2372 vaapi_fill_picture(&pic_param->CurrPic, picture, 0);
2374 for (i = 0, n = 0; i < priv->dpb_count; i++) {
2375 GstVaapiFrameStore * const fs = priv->dpb[i];
2376 if (gst_vaapi_frame_store_has_reference(fs))
2377 vaapi_fill_picture(&pic_param->ReferenceFrames[n++],
2378 fs->buffers[0], fs->structure);
2380 for (; n < G_N_ELEMENTS(pic_param->ReferenceFrames); n++)
2381 vaapi_init_picture(&pic_param->ReferenceFrames[n]);
2383 #define COPY_FIELD(s, f) \
2384 pic_param->f = (s)->f
2386 #define COPY_BFM(a, s, f) \
2387 pic_param->a.bits.f = (s)->f
2389 pic_param->picture_width_in_mbs_minus1 = priv->mb_width - 1;
2390 pic_param->picture_height_in_mbs_minus1 = priv->mb_height - 1;
2391 pic_param->frame_num = priv->frame_num;
2393 COPY_FIELD(sps, bit_depth_luma_minus8);
2394 COPY_FIELD(sps, bit_depth_chroma_minus8);
2395 COPY_FIELD(sps, num_ref_frames);
2396 COPY_FIELD(pps, num_slice_groups_minus1);
2397 COPY_FIELD(pps, slice_group_map_type);
2398 COPY_FIELD(pps, slice_group_change_rate_minus1);
2399 COPY_FIELD(pps, pic_init_qp_minus26);
2400 COPY_FIELD(pps, pic_init_qs_minus26);
2401 COPY_FIELD(pps, chroma_qp_index_offset);
2402 COPY_FIELD(pps, second_chroma_qp_index_offset);
2404 pic_param->seq_fields.value = 0; /* reset all bits */
2405 pic_param->seq_fields.bits.residual_colour_transform_flag = sps->separate_colour_plane_flag;
2406 pic_param->seq_fields.bits.MinLumaBiPredSize8x8 = sps->level_idc >= 31; /* A.3.3.2 */
2408 COPY_BFM(seq_fields, sps, chroma_format_idc);
2409 COPY_BFM(seq_fields, sps, gaps_in_frame_num_value_allowed_flag);
2410 COPY_BFM(seq_fields, sps, frame_mbs_only_flag);
2411 COPY_BFM(seq_fields, sps, mb_adaptive_frame_field_flag);
2412 COPY_BFM(seq_fields, sps, direct_8x8_inference_flag);
2413 COPY_BFM(seq_fields, sps, log2_max_frame_num_minus4);
2414 COPY_BFM(seq_fields, sps, pic_order_cnt_type);
2415 COPY_BFM(seq_fields, sps, log2_max_pic_order_cnt_lsb_minus4);
2416 COPY_BFM(seq_fields, sps, delta_pic_order_always_zero_flag);
2418 pic_param->pic_fields.value = 0; /* reset all bits */
2419 pic_param->pic_fields.bits.field_pic_flag = slice_hdr->field_pic_flag;
2420 pic_param->pic_fields.bits.reference_pic_flag = GST_VAAPI_PICTURE_IS_REFERENCE(picture);
2422 COPY_BFM(pic_fields, pps, entropy_coding_mode_flag);
2423 COPY_BFM(pic_fields, pps, weighted_pred_flag);
2424 COPY_BFM(pic_fields, pps, weighted_bipred_idc);
2425 COPY_BFM(pic_fields, pps, transform_8x8_mode_flag);
2426 COPY_BFM(pic_fields, pps, constrained_intra_pred_flag);
2427 COPY_BFM(pic_fields, pps, pic_order_present_flag);
2428 COPY_BFM(pic_fields, pps, deblocking_filter_control_present_flag);
2429 COPY_BFM(pic_fields, pps, redundant_pic_cnt_present_flag);
2433 /* Detection of the first VCL NAL unit of a primary coded picture (7.4.1.2.4) */
2435 is_new_picture(GstVaapiParserInfoH264 *pi, GstVaapiParserInfoH264 *prev_pi)
2437 GstH264SliceHdr * const slice_hdr = &pi->data.slice_hdr;
2438 GstH264PPS * const pps = slice_hdr->pps;
2439 GstH264SPS * const sps = pps->sequence;
2440 GstH264SliceHdr *prev_slice_hdr;
2444 prev_slice_hdr = &prev_pi->data.slice_hdr;
2446 #define CHECK_EXPR(expr, field_name) do { \
2448 GST_DEBUG(field_name " differs in value"); \
2453 #define CHECK_VALUE(new_slice_hdr, old_slice_hdr, field) \
2454 CHECK_EXPR(((new_slice_hdr)->field == (old_slice_hdr)->field), #field)
2456 /* frame_num differs in value, regardless of inferred values to 0 */
2457 CHECK_VALUE(slice_hdr, prev_slice_hdr, frame_num);
2459 /* pic_parameter_set_id differs in value */
2460 CHECK_VALUE(slice_hdr, prev_slice_hdr, pps);
2462 /* field_pic_flag differs in value */
2463 CHECK_VALUE(slice_hdr, prev_slice_hdr, field_pic_flag);
2465 /* bottom_field_flag is present in both and differs in value */
2466 if (slice_hdr->field_pic_flag && prev_slice_hdr->field_pic_flag)
2467 CHECK_VALUE(slice_hdr, prev_slice_hdr, bottom_field_flag);
2469 /* nal_ref_idc differs in value with one of the nal_ref_idc values is 0 */
2470 CHECK_EXPR((pi->nalu.ref_idc != 0) ==
2471 (prev_pi->nalu.ref_idc != 0), "nal_ref_idc");
2473 /* POC type is 0 for both and either pic_order_cnt_lsb differs in
2474 value or delta_pic_order_cnt_bottom differs in value */
2475 if (sps->pic_order_cnt_type == 0) {
2476 CHECK_VALUE(slice_hdr, prev_slice_hdr, pic_order_cnt_lsb);
2477 if (pps->pic_order_present_flag && !slice_hdr->field_pic_flag)
2478 CHECK_VALUE(slice_hdr, prev_slice_hdr, delta_pic_order_cnt_bottom);
2481 /* POC type is 1 for both and either delta_pic_order_cnt[0]
2482 differs in value or delta_pic_order_cnt[1] differs in value */
2483 else if (sps->pic_order_cnt_type == 1) {
2484 CHECK_VALUE(slice_hdr, prev_slice_hdr, delta_pic_order_cnt[0]);
2485 CHECK_VALUE(slice_hdr, prev_slice_hdr, delta_pic_order_cnt[1]);
2488 /* IdrPicFlag differs in value */
2489 CHECK_VALUE(&pi->nalu, &prev_pi->nalu, idr_pic_flag);
2491 /* IdrPicFlag is equal to 1 for both and idr_pic_id differs in value */
2492 if (pi->nalu.idr_pic_flag)
2493 CHECK_VALUE(slice_hdr, prev_slice_hdr, idr_pic_id);
2500 static GstVaapiDecoderStatus
2501 decode_picture(GstVaapiDecoderH264 *decoder, GstVaapiDecoderUnit *unit)
2503 GstVaapiDecoderH264Private * const priv = decoder->priv;
2504 GstVaapiParserInfoH264 * const pi = unit->parsed_info;
2505 GstH264SliceHdr * const slice_hdr = &pi->data.slice_hdr;
2506 GstH264PPS * const pps = slice_hdr->pps;
2507 GstH264SPS * const sps = pps->sequence;
2508 GstVaapiPictureH264 *picture;
2509 GstVaapiDecoderStatus status;
2511 status = ensure_context(decoder, sps);
2512 if (status != GST_VAAPI_DECODER_STATUS_SUCCESS)
2515 if (priv->current_picture) {
2516 /* Re-use current picture where the first field was decoded */
2517 picture = gst_vaapi_picture_h264_new_field(priv->current_picture);
2519 GST_ERROR("failed to allocate field picture");
2520 return GST_VAAPI_DECODER_STATUS_ERROR_ALLOCATION_FAILED;
2524 /* Create new picture */
2525 picture = gst_vaapi_picture_h264_new(decoder);
2527 GST_ERROR("failed to allocate picture");
2528 return GST_VAAPI_DECODER_STATUS_ERROR_ALLOCATION_FAILED;
2531 gst_vaapi_picture_replace(&priv->current_picture, picture);
2532 gst_vaapi_picture_unref(picture);
2536 status = ensure_quant_matrix(decoder, picture);
2537 if (status != GST_VAAPI_DECODER_STATUS_SUCCESS) {
2538 GST_ERROR("failed to reset quantizer matrix");
2542 if (!init_picture(decoder, picture, pi))
2543 return GST_VAAPI_DECODER_STATUS_ERROR_UNKNOWN;
2544 if (!fill_picture(decoder, picture, pi))
2545 return GST_VAAPI_DECODER_STATUS_ERROR_UNKNOWN;
2546 return GST_VAAPI_DECODER_STATUS_SUCCESS;
2550 get_slice_data_bit_offset(GstH264SliceHdr *slice_hdr)
2554 epb_count = slice_hdr->n_emulation_prevention_bytes;
2555 return 8 /* nal_unit_type */ + slice_hdr->header_size - epb_count * 8;
2559 fill_pred_weight_table(GstVaapiDecoderH264 *decoder,
2560 GstVaapiSlice *slice, GstH264SliceHdr *slice_hdr)
2562 VASliceParameterBufferH264 * const slice_param = slice->param;
2563 GstH264PPS * const pps = slice_hdr->pps;
2564 GstH264SPS * const sps = pps->sequence;
2565 GstH264PredWeightTable * const w = &slice_hdr->pred_weight_table;
2566 guint num_weight_tables = 0;
2569 if (pps->weighted_pred_flag &&
2570 (GST_H264_IS_P_SLICE(slice_hdr) || GST_H264_IS_SP_SLICE(slice_hdr)))
2571 num_weight_tables = 1;
2572 else if (pps->weighted_bipred_idc == 1 && GST_H264_IS_B_SLICE(slice_hdr))
2573 num_weight_tables = 2;
2575 num_weight_tables = 0;
2577 slice_param->luma_log2_weight_denom = 0;
2578 slice_param->chroma_log2_weight_denom = 0;
2579 slice_param->luma_weight_l0_flag = 0;
2580 slice_param->chroma_weight_l0_flag = 0;
2581 slice_param->luma_weight_l1_flag = 0;
2582 slice_param->chroma_weight_l1_flag = 0;
2584 if (num_weight_tables < 1)
2587 slice_param->luma_log2_weight_denom = w->luma_log2_weight_denom;
2588 slice_param->chroma_log2_weight_denom = w->chroma_log2_weight_denom;
2590 slice_param->luma_weight_l0_flag = 1;
2591 for (i = 0; i <= slice_param->num_ref_idx_l0_active_minus1; i++) {
2592 slice_param->luma_weight_l0[i] = w->luma_weight_l0[i];
2593 slice_param->luma_offset_l0[i] = w->luma_offset_l0[i];
2596 slice_param->chroma_weight_l0_flag = sps->chroma_array_type != 0;
2597 if (slice_param->chroma_weight_l0_flag) {
2598 for (i = 0; i <= slice_param->num_ref_idx_l0_active_minus1; i++) {
2599 for (j = 0; j < 2; j++) {
2600 slice_param->chroma_weight_l0[i][j] = w->chroma_weight_l0[i][j];
2601 slice_param->chroma_offset_l0[i][j] = w->chroma_offset_l0[i][j];
2606 if (num_weight_tables < 2)
2609 slice_param->luma_weight_l1_flag = 1;
2610 for (i = 0; i <= slice_param->num_ref_idx_l1_active_minus1; i++) {
2611 slice_param->luma_weight_l1[i] = w->luma_weight_l1[i];
2612 slice_param->luma_offset_l1[i] = w->luma_offset_l1[i];
2615 slice_param->chroma_weight_l1_flag = sps->chroma_array_type != 0;
2616 if (slice_param->chroma_weight_l1_flag) {
2617 for (i = 0; i <= slice_param->num_ref_idx_l1_active_minus1; i++) {
2618 for (j = 0; j < 2; j++) {
2619 slice_param->chroma_weight_l1[i][j] = w->chroma_weight_l1[i][j];
2620 slice_param->chroma_offset_l1[i][j] = w->chroma_offset_l1[i][j];
2628 fill_RefPicList(GstVaapiDecoderH264 *decoder,
2629 GstVaapiSlice *slice, GstH264SliceHdr *slice_hdr)
2631 GstVaapiDecoderH264Private * const priv = decoder->priv;
2632 VASliceParameterBufferH264 * const slice_param = slice->param;
2633 guint i, num_ref_lists = 0;
2635 slice_param->num_ref_idx_l0_active_minus1 = 0;
2636 slice_param->num_ref_idx_l1_active_minus1 = 0;
2638 if (GST_H264_IS_B_SLICE(slice_hdr))
2640 else if (GST_H264_IS_I_SLICE(slice_hdr))
2645 if (num_ref_lists < 1)
2648 slice_param->num_ref_idx_l0_active_minus1 =
2649 slice_hdr->num_ref_idx_l0_active_minus1;
2651 for (i = 0; i < priv->RefPicList0_count && priv->RefPicList0[i]; i++)
2652 vaapi_fill_picture(&slice_param->RefPicList0[i], priv->RefPicList0[i], 0);
2653 for (; i <= slice_param->num_ref_idx_l0_active_minus1; i++)
2654 vaapi_init_picture(&slice_param->RefPicList0[i]);
2656 if (num_ref_lists < 2)
2659 slice_param->num_ref_idx_l1_active_minus1 =
2660 slice_hdr->num_ref_idx_l1_active_minus1;
2662 for (i = 0; i < priv->RefPicList1_count && priv->RefPicList1[i]; i++)
2663 vaapi_fill_picture(&slice_param->RefPicList1[i], priv->RefPicList1[i], 0);
2664 for (; i <= slice_param->num_ref_idx_l1_active_minus1; i++)
2665 vaapi_init_picture(&slice_param->RefPicList1[i]);
2670 fill_slice(GstVaapiDecoderH264 *decoder,
2671 GstVaapiSlice *slice, GstH264SliceHdr *slice_hdr)
2673 VASliceParameterBufferH264 * const slice_param = slice->param;
2675 /* Fill in VASliceParameterBufferH264 */
2676 slice_param->slice_data_bit_offset = get_slice_data_bit_offset(slice_hdr);
2677 slice_param->first_mb_in_slice = slice_hdr->first_mb_in_slice;
2678 slice_param->slice_type = slice_hdr->type % 5;
2679 slice_param->direct_spatial_mv_pred_flag = slice_hdr->direct_spatial_mv_pred_flag;
2680 slice_param->cabac_init_idc = slice_hdr->cabac_init_idc;
2681 slice_param->slice_qp_delta = slice_hdr->slice_qp_delta;
2682 slice_param->disable_deblocking_filter_idc = slice_hdr->disable_deblocking_filter_idc;
2683 slice_param->slice_alpha_c0_offset_div2 = slice_hdr->slice_alpha_c0_offset_div2;
2684 slice_param->slice_beta_offset_div2 = slice_hdr->slice_beta_offset_div2;
2686 if (!fill_RefPicList(decoder, slice, slice_hdr))
2688 if (!fill_pred_weight_table(decoder, slice, slice_hdr))
2693 static GstVaapiDecoderStatus
2694 decode_slice(GstVaapiDecoderH264 *decoder, GstVaapiDecoderUnit *unit)
2696 GstVaapiDecoderH264Private * const priv = decoder->priv;
2697 GstVaapiParserInfoH264 * const pi = unit->parsed_info;
2698 GstVaapiPictureH264 * const picture = priv->current_picture;
2699 GstH264SliceHdr * const slice_hdr = &pi->data.slice_hdr;
2700 GstVaapiSlice *slice;
2701 GstBuffer * const buffer =
2702 GST_VAAPI_DECODER_CODEC_FRAME(decoder)->input_buffer;
2704 GST_DEBUG("slice (%u bytes)", pi->nalu.size);
2706 if (!priv->got_sps || !priv->got_pps) {
2707 GST_ERROR("not initialized yet");
2708 return GST_VAAPI_DECODER_STATUS_SUCCESS;
2711 slice = GST_VAAPI_SLICE_NEW(H264, decoder,
2712 (GST_BUFFER_DATA(buffer) + unit->offset + pi->nalu.offset),
2715 GST_ERROR("failed to allocate slice");
2716 return GST_VAAPI_DECODER_STATUS_ERROR_ALLOCATION_FAILED;
2719 if (!fill_slice(decoder, slice, slice_hdr)) {
2720 gst_vaapi_mini_object_unref(GST_VAAPI_MINI_OBJECT(slice));
2721 return GST_VAAPI_DECODER_STATUS_ERROR_UNKNOWN;
2724 gst_vaapi_picture_add_slice(GST_VAAPI_PICTURE_CAST(picture), slice);
2725 picture->last_slice_hdr = slice_hdr;
2726 return GST_VAAPI_DECODER_STATUS_SUCCESS;
2730 scan_for_start_code(GstAdapter *adapter, guint ofs, guint size, guint32 *scp)
2732 return (gint)gst_adapter_masked_scan_uint32_peek(adapter,
2733 0xffffff00, 0x00000100,
2738 static GstVaapiDecoderStatus
2739 decode_unit(GstVaapiDecoderH264 *decoder, GstVaapiDecoderUnit *unit)
2741 GstVaapiParserInfoH264 * const pi = unit->parsed_info;
2742 GstVaapiDecoderStatus status;
2744 switch (pi->nalu.type) {
2745 case GST_H264_NAL_SLICE_IDR:
2746 /* fall-through. IDR specifics are handled in init_picture() */
2747 case GST_H264_NAL_SLICE:
2748 status = decode_slice(decoder, unit);
2750 case GST_H264_NAL_SEQ_END:
2751 case GST_H264_NAL_STREAM_END:
2752 status = decode_sequence_end(decoder);
2754 case GST_H264_NAL_SEI:
2755 status = GST_VAAPI_DECODER_STATUS_SUCCESS;
2758 GST_WARNING("unsupported NAL unit type %d", pi->nalu.type);
2759 status = GST_VAAPI_DECODER_STATUS_ERROR_BITSTREAM_PARSER;
2765 static GstVaapiDecoderStatus
2766 gst_vaapi_decoder_h264_decode_codec_data(GstVaapiDecoder *base_decoder,
2767 const guchar *buf, guint buf_size)
2769 GstVaapiDecoderH264 * const decoder =
2770 GST_VAAPI_DECODER_H264_CAST(base_decoder);
2771 GstVaapiDecoderH264Private * const priv = decoder->priv;
2772 GstVaapiDecoderStatus status;
2773 GstVaapiDecoderUnit unit;
2774 GstVaapiParserInfoH264 pi;
2775 GstH264ParserResult result;
2776 guint i, ofs, num_sps, num_pps;
2778 unit.parsed_info = π
2781 return GST_VAAPI_DECODER_STATUS_ERROR_NO_DATA;
2784 GST_ERROR("failed to decode codec-data, not in avcC format");
2785 return GST_VAAPI_DECODER_STATUS_ERROR_BITSTREAM_PARSER;
2788 priv->nal_length_size = (buf[4] & 0x03) + 1;
2790 num_sps = buf[5] & 0x1f;
2793 for (i = 0; i < num_sps; i++) {
2794 result = gst_h264_parser_identify_nalu_avc(
2796 buf, ofs, buf_size, 2,
2799 if (result != GST_H264_PARSER_OK)
2800 return get_status(result);
2802 status = parse_sps(decoder, &unit);
2803 if (status != GST_VAAPI_DECODER_STATUS_SUCCESS)
2805 ofs = pi.nalu.offset + pi.nalu.size;
2811 for (i = 0; i < num_pps; i++) {
2812 result = gst_h264_parser_identify_nalu_avc(
2814 buf, ofs, buf_size, 2,
2817 if (result != GST_H264_PARSER_OK)
2818 return get_status(result);
2820 status = parse_pps(decoder, &unit);
2821 if (status != GST_VAAPI_DECODER_STATUS_SUCCESS)
2823 ofs = pi.nalu.offset + pi.nalu.size;
2826 priv->is_avcC = TRUE;
2827 return GST_VAAPI_DECODER_STATUS_SUCCESS;
2830 static GstVaapiDecoderStatus
2831 ensure_decoder(GstVaapiDecoderH264 *decoder)
2833 GstVaapiDecoderH264Private * const priv = decoder->priv;
2834 GstVaapiDecoderStatus status;
2836 g_return_val_if_fail(priv->is_constructed,
2837 GST_VAAPI_DECODER_STATUS_ERROR_INIT_FAILED);
2839 if (!priv->is_opened) {
2840 priv->is_opened = gst_vaapi_decoder_h264_open(decoder);
2841 if (!priv->is_opened)
2842 return GST_VAAPI_DECODER_STATUS_ERROR_UNSUPPORTED_CODEC;
2844 status = gst_vaapi_decoder_decode_codec_data(
2845 GST_VAAPI_DECODER_CAST(decoder));
2846 if (status != GST_VAAPI_DECODER_STATUS_SUCCESS)
2849 return GST_VAAPI_DECODER_STATUS_SUCCESS;
2852 static GstVaapiDecoderStatus
2853 gst_vaapi_decoder_h264_parse(GstVaapiDecoder *base_decoder,
2854 GstAdapter *adapter, gboolean at_eos, GstVaapiDecoderUnit *unit)
2856 GstVaapiDecoderH264 * const decoder =
2857 GST_VAAPI_DECODER_H264_CAST(base_decoder);
2858 GstVaapiDecoderH264Private * const priv = decoder->priv;
2859 GstVaapiParserState * const ps = GST_VAAPI_PARSER_STATE(base_decoder);
2860 GstVaapiParserInfoH264 *pi;
2861 GstVaapiDecoderStatus status;
2862 GstH264ParserResult result;
2864 guint i, size, buf_size, nalu_size, flags;
2868 status = ensure_decoder(decoder);
2869 if (status != GST_VAAPI_DECODER_STATUS_SUCCESS)
2872 size = gst_adapter_available(adapter);
2874 if (priv->is_avcC) {
2875 if (size < priv->nal_length_size)
2876 return GST_VAAPI_DECODER_STATUS_ERROR_NO_DATA;
2878 buf = (guchar *)&start_code;
2879 g_assert(priv->nal_length_size <= sizeof(start_code));
2880 gst_adapter_copy(adapter, buf, 0, priv->nal_length_size);
2883 for (i = 0; i < priv->nal_length_size; i++)
2884 nalu_size = (nalu_size << 8) | buf[i];
2886 buf_size = priv->nal_length_size + nalu_size;
2887 if (size < buf_size)
2888 return GST_VAAPI_DECODER_STATUS_ERROR_NO_DATA;
2892 return GST_VAAPI_DECODER_STATUS_ERROR_NO_DATA;
2894 ofs = scan_for_start_code(adapter, 0, size, NULL);
2896 return GST_VAAPI_DECODER_STATUS_ERROR_NO_DATA;
2899 gst_adapter_flush(adapter, ofs);
2903 ofs2 = ps->input_offset2 - ofs - 4;
2907 ofs = G_UNLIKELY(size < ofs2 + 4) ? -1 :
2908 scan_for_start_code(adapter, ofs2, size - ofs2, NULL);
2910 // Assume the whole NAL unit is present if end-of-stream
2912 ps->input_offset2 = size;
2913 return GST_VAAPI_DECODER_STATUS_ERROR_NO_DATA;
2919 ps->input_offset2 = 0;
2921 buf = (guchar *)gst_adapter_peek(adapter, buf_size);
2923 return GST_VAAPI_DECODER_STATUS_ERROR_NO_DATA;
2925 unit->size = buf_size;
2927 pi = gst_vaapi_parser_info_h264_new();
2929 return GST_VAAPI_DECODER_STATUS_ERROR_ALLOCATION_FAILED;
2931 gst_vaapi_decoder_unit_set_parsed_info(unit,
2932 pi, (GDestroyNotify)gst_vaapi_mini_object_unref);
2935 result = gst_h264_parser_identify_nalu_avc(priv->parser,
2936 buf, 0, buf_size, priv->nal_length_size, &pi->nalu);
2938 result = gst_h264_parser_identify_nalu_unchecked(priv->parser,
2939 buf, 0, buf_size, &pi->nalu);
2940 status = get_status(result);
2941 if (status != GST_VAAPI_DECODER_STATUS_SUCCESS)
2944 switch (pi->nalu.type) {
2945 case GST_H264_NAL_SPS:
2946 status = parse_sps(decoder, unit);
2948 case GST_H264_NAL_PPS:
2949 status = parse_pps(decoder, unit);
2951 case GST_H264_NAL_SEI:
2952 status = parse_sei(decoder, unit);
2954 case GST_H264_NAL_SLICE_IDR:
2955 case GST_H264_NAL_SLICE:
2956 status = parse_slice(decoder, unit);
2959 status = GST_VAAPI_DECODER_STATUS_SUCCESS;
2962 if (status != GST_VAAPI_DECODER_STATUS_SUCCESS)
2966 switch (pi->nalu.type) {
2967 case GST_H264_NAL_AU_DELIMITER:
2968 flags |= GST_VAAPI_DECODER_UNIT_FLAG_FRAME_START;
2970 case GST_H264_NAL_FILLER_DATA:
2971 flags |= GST_VAAPI_DECODER_UNIT_FLAG_SKIP;
2973 case GST_H264_NAL_STREAM_END:
2974 flags |= GST_VAAPI_DECODER_UNIT_FLAG_STREAM_END;
2976 case GST_H264_NAL_SEQ_END:
2977 flags |= GST_VAAPI_DECODER_UNIT_FLAG_FRAME_END;
2979 case GST_H264_NAL_SPS:
2980 case GST_H264_NAL_PPS:
2981 flags |= GST_VAAPI_DECODER_UNIT_FLAG_SKIP;
2983 case GST_H264_NAL_SEI:
2984 flags |= GST_VAAPI_DECODER_UNIT_FLAG_FRAME_START;
2986 case GST_H264_NAL_SLICE_IDR:
2987 case GST_H264_NAL_SLICE:
2988 flags |= GST_VAAPI_DECODER_UNIT_FLAG_SLICE;
2989 if (is_new_picture(pi, priv->prev_slice_pi))
2990 flags |= GST_VAAPI_DECODER_UNIT_FLAG_FRAME_START;
2991 gst_vaapi_parser_info_h264_replace(&priv->prev_slice_pi, pi);
2994 if (pi->nalu.type >= 14 && pi->nalu.type <= 18)
2995 flags |= GST_VAAPI_DECODER_UNIT_FLAG_FRAME_START;
2998 GST_VAAPI_DECODER_UNIT_FLAG_SET(unit, flags);
3000 pi->nalu.data = NULL;
3001 return GST_VAAPI_DECODER_STATUS_SUCCESS;
3004 static GstVaapiDecoderStatus
3005 gst_vaapi_decoder_h264_decode(GstVaapiDecoder *base_decoder,
3006 GstVaapiDecoderUnit *unit)
3008 GstVaapiDecoderH264 * const decoder =
3009 GST_VAAPI_DECODER_H264_CAST(base_decoder);
3010 GstVaapiDecoderStatus status;
3012 status = ensure_decoder(decoder);
3013 if (status != GST_VAAPI_DECODER_STATUS_SUCCESS)
3015 return decode_unit(decoder, unit);
3018 static GstVaapiDecoderStatus
3019 gst_vaapi_decoder_h264_start_frame(GstVaapiDecoder *base_decoder,
3020 GstVaapiDecoderUnit *unit)
3022 GstVaapiDecoderH264 * const decoder =
3023 GST_VAAPI_DECODER_H264_CAST(base_decoder);
3025 return decode_picture(decoder, unit);
3028 static GstVaapiDecoderStatus
3029 gst_vaapi_decoder_h264_end_frame(GstVaapiDecoder *base_decoder)
3031 GstVaapiDecoderH264 * const decoder =
3032 GST_VAAPI_DECODER_H264_CAST(base_decoder);
3034 return decode_current_picture(decoder);
3037 static GstVaapiDecoderStatus
3038 gst_vaapi_decoder_h264_flush(GstVaapiDecoder *base_decoder)
3040 GstVaapiDecoderH264 * const decoder =
3041 GST_VAAPI_DECODER_H264_CAST(base_decoder);
3044 return GST_VAAPI_DECODER_STATUS_SUCCESS;
3048 gst_vaapi_decoder_h264_finalize(GObject *object)
3050 GstVaapiDecoderH264 * const decoder = GST_VAAPI_DECODER_H264_CAST(object);
3052 gst_vaapi_decoder_h264_destroy(decoder);
3054 G_OBJECT_CLASS(gst_vaapi_decoder_h264_parent_class)->finalize(object);
3058 gst_vaapi_decoder_h264_constructed(GObject *object)
3060 GstVaapiDecoderH264 * const decoder = GST_VAAPI_DECODER_H264_CAST(object);
3061 GstVaapiDecoderH264Private * const priv = decoder->priv;
3062 GObjectClass *parent_class;
3064 parent_class = G_OBJECT_CLASS(gst_vaapi_decoder_h264_parent_class);
3065 if (parent_class->constructed)
3066 parent_class->constructed(object);
3068 priv->is_constructed = gst_vaapi_decoder_h264_create(decoder);
3072 gst_vaapi_decoder_h264_class_init(GstVaapiDecoderH264Class *klass)
3074 GObjectClass * const object_class = G_OBJECT_CLASS(klass);
3075 GstVaapiDecoderClass * const decoder_class = GST_VAAPI_DECODER_CLASS(klass);
3077 g_type_class_add_private(klass, sizeof(GstVaapiDecoderH264Private));
3079 object_class->finalize = gst_vaapi_decoder_h264_finalize;
3080 object_class->constructed = gst_vaapi_decoder_h264_constructed;
3082 decoder_class->parse = gst_vaapi_decoder_h264_parse;
3083 decoder_class->decode = gst_vaapi_decoder_h264_decode;
3084 decoder_class->start_frame = gst_vaapi_decoder_h264_start_frame;
3085 decoder_class->end_frame = gst_vaapi_decoder_h264_end_frame;
3086 decoder_class->flush = gst_vaapi_decoder_h264_flush;
3088 decoder_class->decode_codec_data =
3089 gst_vaapi_decoder_h264_decode_codec_data;
3093 gst_vaapi_decoder_h264_init(GstVaapiDecoderH264 *decoder)
3095 GstVaapiDecoderH264Private *priv;
3097 priv = GST_VAAPI_DECODER_H264_GET_PRIVATE(decoder);
3098 decoder->priv = priv;
3099 priv->profile = GST_VAAPI_PROFILE_UNKNOWN;
3100 priv->entrypoint = GST_VAAPI_ENTRYPOINT_VLD;
3101 priv->chroma_type = GST_VAAPI_CHROMA_TYPE_YUV420;
3102 priv->prev_pic_structure = GST_VAAPI_PICTURE_STRUCTURE_FRAME;
3103 priv->progressive_sequence = TRUE;
3107 * gst_vaapi_decoder_h264_new:
3108 * @display: a #GstVaapiDisplay
3109 * @caps: a #GstCaps holding codec information
3111 * Creates a new #GstVaapiDecoder for MPEG-2 decoding. The @caps can
3112 * hold extra information like codec-data and pictured coded size.
3114 * Return value: the newly allocated #GstVaapiDecoder object
3117 gst_vaapi_decoder_h264_new(GstVaapiDisplay *display, GstCaps *caps)
3119 GstVaapiDecoderH264 *decoder;
3121 g_return_val_if_fail(GST_VAAPI_IS_DISPLAY(display), NULL);
3122 g_return_val_if_fail(GST_IS_CAPS(caps), NULL);
3124 decoder = g_object_new(
3125 GST_VAAPI_TYPE_DECODER_H264,
3130 if (!decoder->priv->is_constructed) {
3131 g_object_unref(decoder);
3134 return GST_VAAPI_DECODER_CAST(decoder);