2 * gstvaapidecoder_h264.c - H.264 decoder
4 * Copyright (C) 2011-2012 Intel Corporation
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public License
8 * as published by the Free Software Foundation; either version 2.1
9 * of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free
18 * Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
19 * Boston, MA 02110-1301 USA
23 * SECTION:gstvaapidecoder_h264
24 * @short_description: H.264 decoder
29 #include <gst/base/gstadapter.h>
30 #include <gst/codecparsers/gsth264parser.h>
31 #include "gstvaapidecoder_h264.h"
32 #include "gstvaapidecoder_objects.h"
33 #include "gstvaapidecoder_priv.h"
34 #include "gstvaapidisplay_priv.h"
35 #include "gstvaapiobject_priv.h"
38 #include "gstvaapidebug.h"
40 /* Defined to 1 if strict ordering of DPB is needed. Only useful for debug */
41 #define USE_STRICT_DPB_ORDERING 0
43 typedef struct _GstVaapiPictureH264 GstVaapiPictureH264;
44 typedef struct _GstVaapiPictureH264Class GstVaapiPictureH264Class;
45 typedef struct _GstVaapiSliceH264 GstVaapiSliceH264;
46 typedef struct _GstVaapiSliceH264Class GstVaapiSliceH264Class;
48 /* ------------------------------------------------------------------------- */
49 /* --- H.264 Pictures --- */
50 /* ------------------------------------------------------------------------- */
52 #define GST_VAAPI_TYPE_PICTURE_H264 \
53 (gst_vaapi_picture_h264_get_type())
55 #define GST_VAAPI_PICTURE_H264_CAST(obj) \
56 ((GstVaapiPictureH264 *)(obj))
58 #define GST_VAAPI_PICTURE_H264(obj) \
59 (G_TYPE_CHECK_INSTANCE_CAST((obj), \
60 GST_VAAPI_TYPE_PICTURE_H264, \
63 #define GST_VAAPI_PICTURE_H264_CLASS(klass) \
64 (G_TYPE_CHECK_CLASS_CAST((klass), \
65 GST_VAAPI_TYPE_PICTURE_H264, \
66 GstVaapiPictureH264Class))
68 #define GST_VAAPI_IS_PICTURE_H264(obj) \
69 (G_TYPE_CHECK_INSTANCE_TYPE((obj), GST_VAAPI_TYPE_PICTURE_H264))
71 #define GST_VAAPI_IS_PICTURE_H264_CLASS(klass) \
72 (G_TYPE_CHECK_CLASS_TYPE((klass), GST_VAAPI_TYPE_PICTURE_H264))
74 #define GST_VAAPI_PICTURE_H264_GET_CLASS(obj) \
75 (G_TYPE_INSTANCE_GET_CLASS((obj), \
76 GST_VAAPI_TYPE_PICTURE_H264, \
77 GstVaapiPictureH264Class))
80 * Extended picture flags:
82 * @GST_VAAPI_PICTURE_FLAG_IDR: flag that specifies an IDR picture
83 * @GST_VAAPI_PICTURE_FLAG_SHORT_TERM_REFERENCE: flag that specifies
84 * "used for short-term reference"
85 * @GST_VAAPI_PICTURE_FLAG_LONG_TERM_REFERENCE: flag that specifies
86 * "used for long-term reference"
87 * @GST_VAAPI_PICTURE_FLAGS_REFERENCE: mask covering any kind of
88 * reference picture (short-term reference or long-term reference)
91 GST_VAAPI_PICTURE_FLAG_IDR = (GST_VAAPI_PICTURE_FLAG_LAST << 0),
93 GST_VAAPI_PICTURE_FLAG_SHORT_TERM_REFERENCE = (
94 GST_VAAPI_PICTURE_FLAG_REFERENCE),
95 GST_VAAPI_PICTURE_FLAG_LONG_TERM_REFERENCE = (
96 GST_VAAPI_PICTURE_FLAG_REFERENCE | (GST_VAAPI_PICTURE_FLAG_LAST << 1)),
97 GST_VAAPI_PICTURE_FLAGS_REFERENCE = (
98 GST_VAAPI_PICTURE_FLAG_SHORT_TERM_REFERENCE |
99 GST_VAAPI_PICTURE_FLAG_LONG_TERM_REFERENCE),
102 #define GST_VAAPI_PICTURE_IS_IDR(picture) \
103 (GST_VAAPI_PICTURE_FLAG_IS_SET(picture, GST_VAAPI_PICTURE_FLAG_IDR))
105 #define GST_VAAPI_PICTURE_IS_SHORT_TERM_REFERENCE(picture) \
106 ((GST_VAAPI_PICTURE_FLAGS(picture) & \
107 GST_VAAPI_PICTURE_FLAGS_REFERENCE) == \
108 GST_VAAPI_PICTURE_FLAG_SHORT_TERM_REFERENCE)
110 #define GST_VAAPI_PICTURE_IS_LONG_TERM_REFERENCE(picture) \
111 ((GST_VAAPI_PICTURE_FLAGS(picture) & \
112 GST_VAAPI_PICTURE_FLAGS_REFERENCE) == \
113 GST_VAAPI_PICTURE_FLAG_LONG_TERM_REFERENCE)
115 struct _GstVaapiPictureH264 {
116 GstVaapiPicture base;
120 gint32 frame_num; // Original frame_num from slice_header()
121 gint32 frame_num_wrap; // Temporary for ref pic marking: FrameNumWrap
122 gint32 long_term_frame_idx; // Temporary for ref pic marking: LongTermFrameIdx
123 gint32 pic_num; // Temporary for ref pic marking: PicNum
124 gint32 long_term_pic_num; // Temporary for ref pic marking: LongTermPicNum
125 guint output_flag : 1;
126 guint output_needed : 1;
129 struct _GstVaapiPictureH264Class {
131 GstVaapiPictureClass parent_class;
134 GST_VAAPI_CODEC_DEFINE_TYPE(GstVaapiPictureH264,
135 gst_vaapi_picture_h264,
136 GST_VAAPI_TYPE_PICTURE)
139 gst_vaapi_picture_h264_destroy(GstVaapiPictureH264 *decoder)
144 gst_vaapi_picture_h264_create(
145 GstVaapiPictureH264 *picture,
146 const GstVaapiCodecObjectConstructorArgs *args
153 gst_vaapi_picture_h264_init(GstVaapiPictureH264 *picture)
155 VAPictureH264 *va_pic;
157 va_pic = &picture->info;
159 va_pic->TopFieldOrderCnt = 0;
160 va_pic->BottomFieldOrderCnt = 0;
163 picture->output_needed = FALSE;
166 static inline GstVaapiPictureH264 *
167 gst_vaapi_picture_h264_new(GstVaapiDecoderH264 *decoder)
169 GstVaapiCodecObject *object;
171 g_return_val_if_fail(GST_VAAPI_IS_DECODER(decoder), NULL);
173 object = gst_vaapi_codec_object_new(
174 GST_VAAPI_TYPE_PICTURE_H264,
175 GST_VAAPI_CODEC_BASE(decoder),
176 NULL, sizeof(VAPictureParameterBufferH264),
181 return GST_VAAPI_PICTURE_H264_CAST(object);
184 static inline GstVaapiSliceH264 *
185 gst_vaapi_picture_h264_get_last_slice(GstVaapiPictureH264 *picture)
187 g_return_val_if_fail(GST_VAAPI_IS_PICTURE_H264(picture), NULL);
189 if (G_UNLIKELY(picture->base.slices->len < 1))
191 return g_ptr_array_index(picture->base.slices,
192 picture->base.slices->len - 1);
195 /* ------------------------------------------------------------------------- */
197 /* ------------------------------------------------------------------------- */
199 #define GST_VAAPI_TYPE_SLICE_H264 \
200 (gst_vaapi_slice_h264_get_type())
202 #define GST_VAAPI_SLICE_H264_CAST(obj) \
203 ((GstVaapiSliceH264 *)(obj))
205 #define GST_VAAPI_SLICE_H264(obj) \
206 (G_TYPE_CHECK_INSTANCE_CAST((obj), \
207 GST_VAAPI_TYPE_SLICE_H264, \
210 #define GST_VAAPI_SLICE_H264_CLASS(klass) \
211 (G_TYPE_CHECK_CLASS_CAST((klass), \
212 GST_VAAPI_TYPE_SLICE_H264, \
213 GstVaapiSliceH264Class))
215 #define GST_VAAPI_IS_SLICE_H264(obj) \
216 (G_TYPE_CHECK_INSTANCE_TYPE((obj), GST_VAAPI_TYPE_SLICE_H264))
218 #define GST_VAAPI_IS_SLICE_H264_CLASS(klass) \
219 (G_TYPE_CHECK_CLASS_TYPE((klass), GST_VAAPI_TYPE_SLICE_H264))
221 #define GST_VAAPI_SLICE_H264_GET_CLASS(obj) \
222 (G_TYPE_INSTANCE_GET_CLASS((obj), \
223 GST_VAAPI_TYPE_SLICE_H264, \
224 GstVaapiSliceH264Class))
226 struct _GstVaapiSliceH264 {
228 GstH264SliceHdr slice_hdr; // parsed slice_header()
231 struct _GstVaapiSliceH264Class {
233 GstVaapiSliceClass parent_class;
236 GST_VAAPI_CODEC_DEFINE_TYPE(GstVaapiSliceH264,
237 gst_vaapi_slice_h264,
238 GST_VAAPI_TYPE_SLICE)
241 gst_vaapi_slice_h264_destroy(GstVaapiSliceH264 *slice)
246 gst_vaapi_slice_h264_create(
247 GstVaapiSliceH264 *slice,
248 const GstVaapiCodecObjectConstructorArgs *args
255 gst_vaapi_slice_h264_init(GstVaapiSliceH264 *slice)
259 static inline GstVaapiSliceH264 *
260 gst_vaapi_slice_h264_new(
261 GstVaapiDecoderH264 *decoder,
266 GstVaapiCodecObject *object;
268 g_return_val_if_fail(GST_VAAPI_IS_DECODER(decoder), NULL);
270 object = gst_vaapi_codec_object_new(
271 GST_VAAPI_TYPE_SLICE_H264,
272 GST_VAAPI_CODEC_BASE(decoder),
273 NULL, sizeof(VASliceParameterBufferH264),
278 return GST_VAAPI_SLICE_H264_CAST(object);
281 /* ------------------------------------------------------------------------- */
282 /* --- H.264 Decoder --- */
283 /* ------------------------------------------------------------------------- */
285 G_DEFINE_TYPE(GstVaapiDecoderH264,
286 gst_vaapi_decoder_h264,
287 GST_VAAPI_TYPE_DECODER)
289 #define GST_VAAPI_DECODER_H264_GET_PRIVATE(obj) \
290 (G_TYPE_INSTANCE_GET_PRIVATE((obj), \
291 GST_VAAPI_TYPE_DECODER_H264, \
292 GstVaapiDecoderH264Private))
294 // Used for field_poc[]
296 #define BOTTOM_FIELD 1
298 struct _GstVaapiDecoderH264Private {
300 GstH264NalParser *parser;
301 /* Last decoded SPS. May not be the last activated one. Just here because
302 it may not fit stack memory allocation in decode_sps() */
304 /* Last decoded PPS. May not be the last activated one. Just here because
305 it may not fit stack memory allocation in decode_pps() */
307 GstVaapiPictureH264 *current_picture;
308 GstVaapiPictureH264 *dpb[16];
311 GstVaapiProfile profile;
312 GstVaapiEntrypoint entrypoint;
313 GstVaapiChromaType chroma_type;
314 GstVaapiPictureH264 *short_ref[32];
315 guint short_ref_count;
316 GstVaapiPictureH264 *long_ref[32];
317 guint long_ref_count;
318 GstVaapiPictureH264 *RefPicList0[32];
319 guint RefPicList0_count;
320 GstVaapiPictureH264 *RefPicList1[32];
321 guint RefPicList1_count;
322 guint nal_length_size;
325 gint32 field_poc[2]; // 0:TopFieldOrderCnt / 1:BottomFieldOrderCnt
326 gint32 poc_msb; // PicOrderCntMsb
327 gint32 poc_lsb; // pic_order_cnt_lsb (from slice_header())
328 gint32 prev_poc_msb; // prevPicOrderCntMsb
329 gint32 prev_poc_lsb; // prevPicOrderCntLsb
330 gint32 frame_num_offset; // FrameNumOffset
331 gint32 frame_num; // frame_num (from slice_header())
332 gint32 prev_frame_num; // prevFrameNum
333 gboolean prev_pic_has_mmco5; // prevMmco5Pic
334 gboolean prev_pic_structure; // previous picture structure
335 guint is_constructed : 1;
338 guint has_context : 1;
342 decode_picture_end(GstVaapiDecoderH264 *decoder, GstVaapiPictureH264 *picture);
346 GstVaapiDecoderH264 *decoder,
347 GstVaapiPictureH264 **pictures,
351 /* Get number of reference frames to use */
353 get_max_dec_frame_buffering(GstH264SPS *sps)
355 guint max_dec_frame_buffering, MaxDpbMbs, PicSizeMbs;
357 /* Table A-1 - Level limits */
358 switch (sps->level_idc) {
359 case 10: MaxDpbMbs = 396; break;
360 case 11: MaxDpbMbs = 900; break;
361 case 12: MaxDpbMbs = 2376; break;
362 case 13: MaxDpbMbs = 2376; break;
363 case 20: MaxDpbMbs = 2376; break;
364 case 21: MaxDpbMbs = 4752; break;
365 case 22: MaxDpbMbs = 8100; break;
366 case 30: MaxDpbMbs = 8100; break;
367 case 31: MaxDpbMbs = 18000; break;
368 case 32: MaxDpbMbs = 20480; break;
369 case 40: MaxDpbMbs = 32768; break;
370 case 41: MaxDpbMbs = 32768; break;
371 case 42: MaxDpbMbs = 34816; break;
372 case 50: MaxDpbMbs = 110400; break;
373 case 51: MaxDpbMbs = 184320; break;
375 g_assert(0 && "unhandled level");
379 PicSizeMbs = ((sps->pic_width_in_mbs_minus1 + 1) *
380 (sps->pic_height_in_map_units_minus1 + 1) *
381 (sps->frame_mbs_only_flag ? 1 : 2));
382 max_dec_frame_buffering = MaxDpbMbs / PicSizeMbs;
385 if (sps->vui_parameters_present_flag) {
386 GstH264VUIParams * const vui_params = &sps->vui_parameters;
387 if (vui_params->bitstream_restriction_flag)
388 max_dec_frame_buffering = vui_params->max_dec_frame_buffering;
390 switch (sps->profile_idc) {
391 case 44: // CAVLC 4:4:4 Intra profile
392 case 86: // Scalable High profile
393 case 100: // High profile
394 case 110: // High 10 profile
395 case 122: // High 4:2:2 profile
396 case 244: // High 4:4:4 Predictive profile
397 if (sps->constraint_set3_flag)
398 max_dec_frame_buffering = 0;
404 if (max_dec_frame_buffering > 16)
405 max_dec_frame_buffering = 16;
406 else if (max_dec_frame_buffering < sps->num_ref_frames)
407 max_dec_frame_buffering = sps->num_ref_frames;
408 return MAX(1, max_dec_frame_buffering);
412 dpb_remove_index(GstVaapiDecoderH264 *decoder, guint index)
414 GstVaapiDecoderH264Private * const priv = decoder->priv;
415 guint i, num_pictures = --priv->dpb_count;
417 if (USE_STRICT_DPB_ORDERING) {
418 for (i = index; i < num_pictures; i++)
419 gst_vaapi_picture_replace(&priv->dpb[i], priv->dpb[i + 1]);
421 else if (index != num_pictures)
422 gst_vaapi_picture_replace(&priv->dpb[index], priv->dpb[num_pictures]);
423 gst_vaapi_picture_replace(&priv->dpb[num_pictures], NULL);
426 static inline gboolean
427 dpb_output(GstVaapiDecoderH264 *decoder, GstVaapiPictureH264 *picture)
429 /* XXX: update cropping rectangle */
430 picture->output_needed = FALSE;
431 return gst_vaapi_picture_output(GST_VAAPI_PICTURE_CAST(picture));
435 dpb_bump(GstVaapiDecoderH264 *decoder)
437 GstVaapiDecoderH264Private * const priv = decoder->priv;
438 guint i, lowest_poc_index;
441 for (i = 0; i < priv->dpb_count; i++) {
442 if (priv->dpb[i]->output_needed)
445 if (i == priv->dpb_count)
448 lowest_poc_index = i++;
449 for (; i < priv->dpb_count; i++) {
450 GstVaapiPictureH264 * const picture = priv->dpb[i];
451 if (picture->output_needed && picture->poc < priv->dpb[lowest_poc_index]->poc)
452 lowest_poc_index = i;
455 success = dpb_output(decoder, priv->dpb[lowest_poc_index]);
456 if (!GST_VAAPI_PICTURE_IS_REFERENCE(priv->dpb[lowest_poc_index]))
457 dpb_remove_index(decoder, lowest_poc_index);
462 dpb_flush(GstVaapiDecoderH264 *decoder)
464 GstVaapiDecoderH264Private * const priv = decoder->priv;
466 while (dpb_bump(decoder))
468 clear_references(decoder, priv->dpb, &priv->dpb_count);
472 dpb_add(GstVaapiDecoderH264 *decoder, GstVaapiPictureH264 *picture)
474 GstVaapiDecoderH264Private * const priv = decoder->priv;
477 // Remove all unused pictures
478 if (GST_VAAPI_PICTURE_IS_IDR(picture))
482 while (i < priv->dpb_count) {
483 GstVaapiPictureH264 * const picture = priv->dpb[i];
484 if (!picture->output_needed &&
485 !GST_VAAPI_PICTURE_IS_REFERENCE(picture))
486 dpb_remove_index(decoder, i);
492 // C.4.5.1 - Storage and marking of a reference decoded picture into the DPB
493 if (GST_VAAPI_PICTURE_IS_REFERENCE(picture)) {
494 while (priv->dpb_count == priv->dpb_size) {
495 if (!dpb_bump(decoder))
498 gst_vaapi_picture_replace(&priv->dpb[priv->dpb_count++], picture);
499 if (picture->output_flag)
500 picture->output_needed = TRUE;
503 // C.4.5.2 - Storage and marking of a non-reference decoded picture into the DPB
505 if (!picture->output_flag)
507 while (priv->dpb_count == priv->dpb_size) {
508 for (i = 0; i < priv->dpb_count; i++) {
509 if (priv->dpb[i]->output_needed &&
510 priv->dpb[i]->poc < picture->poc)
513 if (i == priv->dpb_count)
514 return dpb_output(decoder, picture);
515 if (!dpb_bump(decoder))
518 gst_vaapi_picture_replace(&priv->dpb[priv->dpb_count++], picture);
519 picture->output_needed = TRUE;
525 dpb_reset(GstVaapiDecoderH264 *decoder, GstH264SPS *sps)
527 GstVaapiDecoderH264Private * const priv = decoder->priv;
529 priv->dpb_size = get_max_dec_frame_buffering(sps);
530 GST_DEBUG("DPB size %u", priv->dpb_size);
533 static GstVaapiDecoderStatus
534 get_status(GstH264ParserResult result)
536 GstVaapiDecoderStatus status;
539 case GST_H264_PARSER_OK:
540 status = GST_VAAPI_DECODER_STATUS_SUCCESS;
542 case GST_H264_PARSER_NO_NAL_END:
543 status = GST_VAAPI_DECODER_STATUS_ERROR_NO_DATA;
545 case GST_H264_PARSER_ERROR:
546 status = GST_VAAPI_DECODER_STATUS_ERROR_BITSTREAM_PARSER;
549 status = GST_VAAPI_DECODER_STATUS_ERROR_UNKNOWN;
556 gst_vaapi_decoder_h264_close(GstVaapiDecoderH264 *decoder)
558 GstVaapiDecoderH264Private * const priv = decoder->priv;
560 gst_vaapi_picture_replace(&priv->current_picture, NULL);
561 clear_references(decoder, priv->short_ref, &priv->short_ref_count);
562 clear_references(decoder, priv->long_ref, &priv->long_ref_count );
563 clear_references(decoder, priv->dpb, &priv->dpb_count );
566 gst_h264_nal_parser_free(priv->parser);
571 gst_adapter_clear(priv->adapter);
572 g_object_unref(priv->adapter);
573 priv->adapter = NULL;
578 gst_vaapi_decoder_h264_open(GstVaapiDecoderH264 *decoder, GstBuffer *buffer)
580 GstVaapiDecoderH264Private * const priv = decoder->priv;
582 gst_vaapi_decoder_h264_close(decoder);
584 priv->adapter = gst_adapter_new();
588 priv->parser = gst_h264_nal_parser_new();
595 gst_vaapi_decoder_h264_destroy(GstVaapiDecoderH264 *decoder)
597 gst_vaapi_decoder_h264_close(decoder);
601 gst_vaapi_decoder_h264_create(GstVaapiDecoderH264 *decoder)
603 if (!GST_VAAPI_DECODER_CODEC(decoder))
609 h264_get_profile(GstH264SPS *sps)
613 switch (sps->profile_idc) {
615 profile = GST_VAAPI_PROFILE_H264_BASELINE;
618 profile = GST_VAAPI_PROFILE_H264_MAIN;
621 profile = GST_VAAPI_PROFILE_H264_HIGH;
628 h264_get_chroma_type(GstH264SPS *sps)
630 guint chroma_type = 0;
632 switch (sps->chroma_format_idc) {
634 chroma_type = GST_VAAPI_CHROMA_TYPE_YUV420;
637 chroma_type = GST_VAAPI_CHROMA_TYPE_YUV422;
640 if (!sps->separate_colour_plane_flag)
641 chroma_type = GST_VAAPI_CHROMA_TYPE_YUV444;
647 static GstVaapiProfile
648 get_profile(GstVaapiDecoderH264 *decoder, GstH264SPS *sps)
650 GstVaapiDecoderH264Private * const priv = decoder->priv;
651 GstVaapiDisplay * const display = GST_VAAPI_DECODER_DISPLAY(decoder);
652 GstVaapiProfile profile, profiles[2];
653 guint i, n_profiles = 0;
655 profile = h264_get_profile(sps);
657 return GST_VAAPI_PROFILE_UNKNOWN;
659 profiles[n_profiles++] = profile;
661 case GST_VAAPI_PROFILE_H264_MAIN:
662 profiles[n_profiles++] = GST_VAAPI_PROFILE_H264_HIGH;
668 /* If the preferred profile (profiles[0]) matches one that we already
669 found, then just return it now instead of searching for it again */
670 if (profiles[0] == priv->profile)
671 return priv->profile;
673 for (i = 0; i < n_profiles; i++) {
674 if (gst_vaapi_display_has_decoder(display, profiles[i], priv->entrypoint))
677 return GST_VAAPI_PROFILE_UNKNOWN;
680 static GstVaapiDecoderStatus
681 ensure_context(GstVaapiDecoderH264 *decoder, GstH264SPS *sps)
683 GstVaapiDecoder * const base_decoder = GST_VAAPI_DECODER_CAST(decoder);
684 GstVaapiDecoderH264Private * const priv = decoder->priv;
685 GstVaapiContextInfo info;
686 GstVaapiProfile profile;
687 GstVaapiChromaType chroma_type;
688 gboolean reset_context = FALSE;
690 profile = get_profile(decoder, sps);
692 GST_ERROR("unsupported profile_idc %u", sps->profile_idc);
693 return GST_VAAPI_DECODER_STATUS_ERROR_UNSUPPORTED_PROFILE;
696 if (priv->profile != profile) {
697 GST_DEBUG("profile changed");
698 reset_context = TRUE;
699 priv->profile = profile;
702 chroma_type = h264_get_chroma_type(sps);
703 if (!chroma_type || chroma_type != GST_VAAPI_CHROMA_TYPE_YUV420) {
704 GST_ERROR("unsupported chroma_format_idc %u", sps->chroma_format_idc);
705 return GST_VAAPI_DECODER_STATUS_ERROR_UNSUPPORTED_CHROMA_FORMAT;
708 if (priv->chroma_type != chroma_type) {
709 GST_DEBUG("chroma format changed");
710 reset_context = TRUE;
711 priv->chroma_type = chroma_type;
714 if (priv->width != sps->width || priv->height != sps->height) {
715 GST_DEBUG("size changed");
716 reset_context = TRUE;
717 priv->width = sps->width;
718 priv->height = sps->height;
721 gst_vaapi_decoder_set_pixel_aspect_ratio(
723 sps->vui_parameters.par_n,
724 sps->vui_parameters.par_d
727 if (!reset_context && priv->has_context)
728 return GST_VAAPI_DECODER_STATUS_SUCCESS;
730 info.profile = priv->profile;
731 info.entrypoint = priv->entrypoint;
732 info.width = priv->width;
733 info.height = priv->height;
734 info.ref_frames = get_max_dec_frame_buffering(sps);
736 if (!gst_vaapi_decoder_ensure_context(GST_VAAPI_DECODER(decoder), &info))
737 return GST_VAAPI_DECODER_STATUS_ERROR_UNKNOWN;
738 priv->has_context = TRUE;
741 dpb_reset(decoder, sps);
742 return GST_VAAPI_DECODER_STATUS_SUCCESS;
746 fill_iq_matrix_4x4(VAIQMatrixBufferH264 *iq_matrix, const GstH264PPS *pps)
748 const guint8 (* const ScalingList4x4)[6][16] = &pps->scaling_lists_4x4;
751 /* There are always 6 4x4 scaling lists */
752 g_assert(G_N_ELEMENTS(iq_matrix->ScalingList4x4) == 6);
753 g_assert(G_N_ELEMENTS(iq_matrix->ScalingList4x4[0]) == 16);
755 if (sizeof(iq_matrix->ScalingList4x4[0][0]) == 1)
756 memcpy(iq_matrix->ScalingList4x4, *ScalingList4x4,
757 sizeof(iq_matrix->ScalingList4x4));
759 for (i = 0; i < G_N_ELEMENTS(iq_matrix->ScalingList4x4); i++) {
760 for (j = 0; j < G_N_ELEMENTS(iq_matrix->ScalingList4x4[i]); j++)
761 iq_matrix->ScalingList4x4[i][j] = (*ScalingList4x4)[i][j];
767 fill_iq_matrix_8x8(VAIQMatrixBufferH264 *iq_matrix, const GstH264PPS *pps)
769 const guint8 (* const ScalingList8x8)[6][64] = &pps->scaling_lists_8x8;
770 const GstH264SPS * const sps = pps->sequence;
773 /* If chroma_format_idc != 3, there are up to 2 8x8 scaling lists */
774 if (!pps->transform_8x8_mode_flag)
777 g_assert(G_N_ELEMENTS(iq_matrix->ScalingList8x8) >= 2);
778 g_assert(G_N_ELEMENTS(iq_matrix->ScalingList8x8[0]) == 64);
780 if (sizeof(iq_matrix->ScalingList8x8[0][0]) == 1)
781 memcpy(iq_matrix->ScalingList8x8, *ScalingList8x8,
782 sizeof(iq_matrix->ScalingList8x8));
784 n = (sps->chroma_format_idc != 3) ? 2 : 6;
785 for (i = 0; i < n; i++) {
786 for (j = 0; j < G_N_ELEMENTS(iq_matrix->ScalingList8x8[i]); j++)
787 iq_matrix->ScalingList8x8[i][j] = (*ScalingList8x8)[i][j];
792 static GstVaapiDecoderStatus
793 ensure_quant_matrix(GstVaapiDecoderH264 *decoder, GstVaapiPictureH264 *picture)
795 GstVaapiPicture * const base_picture = &picture->base;
796 GstH264PPS * const pps = picture->pps;
797 GstH264SPS * const sps = pps->sequence;
798 VAIQMatrixBufferH264 *iq_matrix;
800 base_picture->iq_matrix = GST_VAAPI_IQ_MATRIX_NEW(H264, decoder);
801 if (!base_picture->iq_matrix) {
802 GST_ERROR("failed to allocate IQ matrix");
803 return GST_VAAPI_DECODER_STATUS_ERROR_ALLOCATION_FAILED;
805 iq_matrix = base_picture->iq_matrix->param;
807 /* XXX: we can only support 4:2:0 or 4:2:2 since ScalingLists8x8[]
808 is not large enough to hold lists for 4:4:4 */
809 if (sps->chroma_format_idc == 3)
810 return GST_VAAPI_DECODER_STATUS_ERROR_UNSUPPORTED_CHROMA_FORMAT;
812 fill_iq_matrix_4x4(iq_matrix, pps);
813 fill_iq_matrix_8x8(iq_matrix, pps);
815 return GST_VAAPI_DECODER_STATUS_SUCCESS;
818 static GstVaapiDecoderStatus
819 decode_current_picture(GstVaapiDecoderH264 *decoder)
821 GstVaapiDecoderH264Private * const priv = decoder->priv;
822 GstVaapiPictureH264 * const picture = priv->current_picture;
823 GstVaapiDecoderStatus status;
826 return GST_VAAPI_DECODER_STATUS_SUCCESS;
828 status = ensure_context(decoder, picture->pps->sequence);
829 if (status != GST_VAAPI_DECODER_STATUS_SUCCESS)
832 if (!decode_picture_end(decoder, picture))
834 if (!gst_vaapi_picture_decode(GST_VAAPI_PICTURE_CAST(picture)))
836 gst_vaapi_picture_replace(&priv->current_picture, NULL);
837 return GST_VAAPI_DECODER_STATUS_SUCCESS;
840 gst_vaapi_picture_replace(&priv->current_picture, NULL);
841 return GST_VAAPI_DECODER_STATUS_ERROR_UNKNOWN;
844 static GstVaapiDecoderStatus
845 decode_sps(GstVaapiDecoderH264 *decoder, GstH264NalUnit *nalu)
847 GstVaapiDecoderH264Private * const priv = decoder->priv;
848 GstH264SPS * const sps = &priv->last_sps;
849 GstH264ParserResult result;
851 GST_DEBUG("decode SPS");
853 memset(sps, 0, sizeof(*sps));
854 result = gst_h264_parser_parse_sps(priv->parser, nalu, sps, TRUE);
855 if (result != GST_H264_PARSER_OK)
856 return get_status(result);
858 return GST_VAAPI_DECODER_STATUS_SUCCESS;
861 static GstVaapiDecoderStatus
862 decode_pps(GstVaapiDecoderH264 *decoder, GstH264NalUnit *nalu)
864 GstVaapiDecoderH264Private * const priv = decoder->priv;
865 GstH264PPS * const pps = &priv->last_pps;
866 GstH264ParserResult result;
868 GST_DEBUG("decode PPS");
870 memset(pps, 0, sizeof(*pps));
871 result = gst_h264_parser_parse_pps(priv->parser, nalu, pps);
872 if (result != GST_H264_PARSER_OK)
873 return get_status(result);
875 return GST_VAAPI_DECODER_STATUS_SUCCESS;
878 static GstVaapiDecoderStatus
879 decode_sei(GstVaapiDecoderH264 *decoder, GstH264NalUnit *nalu)
881 GstVaapiDecoderH264Private * const priv = decoder->priv;
882 GstH264SEIMessage sei;
883 GstH264ParserResult result;
885 GST_DEBUG("decode SEI");
887 memset(&sei, 0, sizeof(sei));
888 result = gst_h264_parser_parse_sei(priv->parser, nalu, &sei);
889 if (result != GST_H264_PARSER_OK) {
890 GST_WARNING("failed to decode SEI, payload type:%d", sei.payloadType);
891 return get_status(result);
894 return GST_VAAPI_DECODER_STATUS_SUCCESS;
897 static GstVaapiDecoderStatus
898 decode_sequence_end(GstVaapiDecoderH264 *decoder)
900 GstVaapiDecoderStatus status;
902 GST_DEBUG("decode sequence-end");
904 status = decode_current_picture(decoder);
905 if (status != GST_VAAPI_DECODER_STATUS_SUCCESS)
909 return GST_VAAPI_DECODER_STATUS_END_OF_STREAM;
912 /* 8.2.1.1 - Decoding process for picture order count type 0 */
915 GstVaapiDecoderH264 *decoder,
916 GstVaapiPictureH264 *picture,
917 GstH264SliceHdr *slice_hdr
920 GstVaapiDecoderH264Private * const priv = decoder->priv;
921 GstH264PPS * const pps = slice_hdr->pps;
922 GstH264SPS * const sps = pps->sequence;
923 const gint32 MaxPicOrderCntLsb = 1 << (sps->log2_max_pic_order_cnt_lsb_minus4 + 4);
926 GST_DEBUG("decode picture order count type 0");
928 if (GST_VAAPI_PICTURE_IS_IDR(picture)) {
929 priv->prev_poc_msb = 0;
930 priv->prev_poc_lsb = 0;
932 else if (priv->prev_pic_has_mmco5) {
933 priv->prev_poc_msb = 0;
935 (priv->prev_pic_structure == GST_VAAPI_PICTURE_STRUCTURE_BOTTOM_FIELD ?
936 0 : priv->field_poc[TOP_FIELD]);
939 priv->prev_poc_msb = priv->poc_msb;
940 priv->prev_poc_lsb = priv->poc_lsb;
944 priv->poc_lsb = slice_hdr->pic_order_cnt_lsb;
945 if (priv->poc_lsb < priv->prev_poc_lsb &&
946 (priv->prev_poc_lsb - priv->poc_lsb) >= (MaxPicOrderCntLsb / 2))
947 priv->poc_msb = priv->prev_poc_msb + MaxPicOrderCntLsb;
948 else if (priv->poc_lsb > priv->prev_poc_lsb &&
949 (priv->poc_lsb - priv->prev_poc_lsb) > (MaxPicOrderCntLsb / 2))
950 priv->poc_msb = priv->prev_poc_msb - MaxPicOrderCntLsb;
952 priv->poc_msb = priv->prev_poc_msb;
954 temp_poc = priv->poc_msb + priv->poc_lsb;
955 switch (picture->base.structure) {
956 case GST_VAAPI_PICTURE_STRUCTURE_FRAME:
958 priv->field_poc[TOP_FIELD] = temp_poc;
959 priv->field_poc[BOTTOM_FIELD] = temp_poc +
960 slice_hdr->delta_pic_order_cnt_bottom;
962 case GST_VAAPI_PICTURE_STRUCTURE_TOP_FIELD:
964 priv->field_poc[TOP_FIELD] = temp_poc;
966 case GST_VAAPI_PICTURE_STRUCTURE_BOTTOM_FIELD:
968 priv->field_poc[BOTTOM_FIELD] = temp_poc;
973 /* 8.2.1.2 - Decoding process for picture order count type 1 */
976 GstVaapiDecoderH264 *decoder,
977 GstVaapiPictureH264 *picture,
978 GstH264SliceHdr *slice_hdr
981 GstVaapiDecoderH264Private * const priv = decoder->priv;
982 GstH264PPS * const pps = slice_hdr->pps;
983 GstH264SPS * const sps = pps->sequence;
984 const gint32 MaxFrameNum = 1 << (sps->log2_max_frame_num_minus4 + 4);
985 gint32 prev_frame_num_offset, abs_frame_num, expected_poc;
988 GST_DEBUG("decode picture order count type 1");
990 if (priv->prev_pic_has_mmco5)
991 prev_frame_num_offset = 0;
993 prev_frame_num_offset = priv->frame_num_offset;
996 if (GST_VAAPI_PICTURE_IS_IDR(picture))
997 priv->frame_num_offset = 0;
998 else if (priv->prev_frame_num > priv->frame_num)
999 priv->frame_num_offset = prev_frame_num_offset + MaxFrameNum;
1001 priv->frame_num_offset = prev_frame_num_offset;
1004 if (sps->num_ref_frames_in_pic_order_cnt_cycle != 0)
1005 abs_frame_num = priv->frame_num_offset + priv->frame_num;
1008 if (!GST_VAAPI_PICTURE_IS_REFERENCE(picture) && abs_frame_num > 0)
1009 abs_frame_num = abs_frame_num - 1;
1011 if (abs_frame_num > 0) {
1012 gint32 expected_delta_per_poc_cycle;
1013 gint32 poc_cycle_cnt, frame_num_in_poc_cycle;
1015 expected_delta_per_poc_cycle = 0;
1016 for (i = 0; i < sps->num_ref_frames_in_pic_order_cnt_cycle; i++)
1017 expected_delta_per_poc_cycle += sps->offset_for_ref_frame[i];
1020 poc_cycle_cnt = (abs_frame_num - 1) /
1021 sps->num_ref_frames_in_pic_order_cnt_cycle;
1022 frame_num_in_poc_cycle = (abs_frame_num - 1) %
1023 sps->num_ref_frames_in_pic_order_cnt_cycle;
1026 expected_poc = poc_cycle_cnt * expected_delta_per_poc_cycle;
1027 for (i = 0; i <= frame_num_in_poc_cycle; i++)
1028 expected_poc += sps->offset_for_ref_frame[i];
1032 if (!GST_VAAPI_PICTURE_IS_REFERENCE(picture))
1033 expected_poc += sps->offset_for_non_ref_pic;
1036 switch (picture->base.structure) {
1037 case GST_VAAPI_PICTURE_STRUCTURE_FRAME:
1038 priv->field_poc[TOP_FIELD] = expected_poc +
1039 slice_hdr->delta_pic_order_cnt[0];
1040 priv->field_poc[BOTTOM_FIELD] = priv->field_poc[TOP_FIELD] +
1041 sps->offset_for_top_to_bottom_field +
1042 slice_hdr->delta_pic_order_cnt[1];
1044 case GST_VAAPI_PICTURE_STRUCTURE_TOP_FIELD:
1045 priv->field_poc[TOP_FIELD] = expected_poc +
1046 slice_hdr->delta_pic_order_cnt[0];
1048 case GST_VAAPI_PICTURE_STRUCTURE_BOTTOM_FIELD:
1049 priv->field_poc[BOTTOM_FIELD] = expected_poc +
1050 sps->offset_for_top_to_bottom_field +
1051 slice_hdr->delta_pic_order_cnt[0];
1056 /* 8.2.1.3 - Decoding process for picture order count type 2 */
1059 GstVaapiDecoderH264 *decoder,
1060 GstVaapiPictureH264 *picture,
1061 GstH264SliceHdr *slice_hdr
1064 GstVaapiDecoderH264Private * const priv = decoder->priv;
1065 GstH264PPS * const pps = slice_hdr->pps;
1066 GstH264SPS * const sps = pps->sequence;
1067 const gint32 MaxFrameNum = 1 << (sps->log2_max_frame_num_minus4 + 4);
1068 gint32 prev_frame_num_offset, temp_poc;
1070 GST_DEBUG("decode picture order count type 2");
1072 if (priv->prev_pic_has_mmco5)
1073 prev_frame_num_offset = 0;
1075 prev_frame_num_offset = priv->frame_num_offset;
1078 if (GST_VAAPI_PICTURE_IS_IDR(picture))
1079 priv->frame_num_offset = 0;
1080 else if (priv->prev_frame_num > priv->frame_num)
1081 priv->frame_num_offset = prev_frame_num_offset + MaxFrameNum;
1083 priv->frame_num_offset = prev_frame_num_offset;
1086 if (GST_VAAPI_PICTURE_IS_IDR(picture))
1088 else if (!GST_VAAPI_PICTURE_IS_REFERENCE(picture))
1089 temp_poc = 2 * (priv->frame_num_offset + priv->frame_num) - 1;
1091 temp_poc = 2 * (priv->frame_num_offset + priv->frame_num);
1094 if (picture->base.structure != GST_VAAPI_PICTURE_STRUCTURE_BOTTOM_FIELD)
1095 priv->field_poc[TOP_FIELD] = temp_poc;
1096 if (picture->base.structure != GST_VAAPI_PICTURE_STRUCTURE_TOP_FIELD)
1097 priv->field_poc[BOTTOM_FIELD] = temp_poc;
1100 /* 8.2.1 - Decoding process for picture order count */
1103 GstVaapiDecoderH264 *decoder,
1104 GstVaapiPictureH264 *picture,
1105 GstH264SliceHdr *slice_hdr
1108 GstVaapiDecoderH264Private * const priv = decoder->priv;
1109 VAPictureH264 * const pic = &picture->info;
1110 GstH264PPS * const pps = slice_hdr->pps;
1111 GstH264SPS * const sps = pps->sequence;
1113 switch (sps->pic_order_cnt_type) {
1115 init_picture_poc_0(decoder, picture, slice_hdr);
1118 init_picture_poc_1(decoder, picture, slice_hdr);
1121 init_picture_poc_2(decoder, picture, slice_hdr);
1125 if (picture->base.structure != GST_VAAPI_PICTURE_STRUCTURE_BOTTOM_FIELD)
1126 pic->TopFieldOrderCnt = priv->field_poc[TOP_FIELD];
1127 if (picture->base.structure != GST_VAAPI_PICTURE_STRUCTURE_TOP_FIELD)
1128 pic->BottomFieldOrderCnt = priv->field_poc[BOTTOM_FIELD];
1129 picture->poc = MIN(pic->TopFieldOrderCnt, pic->BottomFieldOrderCnt);
1133 compare_picture_pic_num_dec(const void *a, const void *b)
1135 const GstVaapiPictureH264 * const picA = *(GstVaapiPictureH264 **)a;
1136 const GstVaapiPictureH264 * const picB = *(GstVaapiPictureH264 **)b;
1138 return picB->pic_num - picA->pic_num;
1142 compare_picture_long_term_pic_num_inc(const void *a, const void *b)
1144 const GstVaapiPictureH264 * const picA = *(GstVaapiPictureH264 **)a;
1145 const GstVaapiPictureH264 * const picB = *(GstVaapiPictureH264 **)b;
1147 return picA->long_term_pic_num - picB->long_term_pic_num;
1151 compare_picture_poc_dec(const void *a, const void *b)
1153 const GstVaapiPictureH264 * const picA = *(GstVaapiPictureH264 **)a;
1154 const GstVaapiPictureH264 * const picB = *(GstVaapiPictureH264 **)b;
1156 return picB->poc - picA->poc;
1160 compare_picture_poc_inc(const void *a, const void *b)
1162 const GstVaapiPictureH264 * const picA = *(GstVaapiPictureH264 **)a;
1163 const GstVaapiPictureH264 * const picB = *(GstVaapiPictureH264 **)b;
1165 return picA->poc - picB->poc;
1169 compare_picture_frame_num_wrap_dec(const void *a, const void *b)
1171 const GstVaapiPictureH264 * const picA = *(GstVaapiPictureH264 **)a;
1172 const GstVaapiPictureH264 * const picB = *(GstVaapiPictureH264 **)b;
1174 return picB->frame_num_wrap - picA->frame_num_wrap;
1178 compare_picture_long_term_frame_idx_inc(const void *a, const void *b)
1180 const GstVaapiPictureH264 * const picA = *(GstVaapiPictureH264 **)a;
1181 const GstVaapiPictureH264 * const picB = *(GstVaapiPictureH264 **)b;
1183 return picA->long_term_frame_idx - picB->long_term_frame_idx;
1186 /* 8.2.4.1 - Decoding process for picture numbers */
1188 init_picture_refs_pic_num(
1189 GstVaapiDecoderH264 *decoder,
1190 GstVaapiPictureH264 *picture,
1191 GstH264SliceHdr *slice_hdr
1194 GstVaapiDecoderH264Private * const priv = decoder->priv;
1195 GstH264PPS * const pps = slice_hdr->pps;
1196 GstH264SPS * const sps = pps->sequence;
1197 const gint32 MaxFrameNum = 1 << (sps->log2_max_frame_num_minus4 + 4);
1200 GST_DEBUG("decode picture numbers");
1202 for (i = 0; i < priv->short_ref_count; i++) {
1203 GstVaapiPictureH264 * const pic = priv->short_ref[i];
1206 if (pic->frame_num > priv->frame_num)
1207 pic->frame_num_wrap = pic->frame_num - MaxFrameNum;
1209 pic->frame_num_wrap = pic->frame_num;
1211 // (8-28, 8-30, 8-31)
1212 if (GST_VAAPI_PICTURE_IS_FRAME(picture))
1213 pic->pic_num = pic->frame_num_wrap;
1215 if (pic->base.structure == picture->base.structure)
1216 pic->pic_num = 2 * pic->frame_num_wrap + 1;
1218 pic->pic_num = 2 * pic->frame_num_wrap;
1222 for (i = 0; i < priv->long_ref_count; i++) {
1223 GstVaapiPictureH264 * const pic = priv->long_ref[i];
1225 // (8-29, 8-32, 8-33)
1226 if (GST_VAAPI_PICTURE_IS_FRAME(picture))
1227 pic->long_term_pic_num = pic->long_term_frame_idx;
1229 if (pic->base.structure == picture->base.structure)
1230 pic->long_term_pic_num = 2 * pic->long_term_frame_idx + 1;
1232 pic->long_term_pic_num = 2 * pic->long_term_frame_idx;
1237 #define SORT_REF_LIST(list, n, compare_func) \
1238 qsort(list, n, sizeof(*(list)), compare_picture_##compare_func)
1241 init_picture_refs_p_slice(
1242 GstVaapiDecoderH264 *decoder,
1243 GstVaapiPictureH264 *picture,
1244 GstH264SliceHdr *slice_hdr
1247 GstVaapiDecoderH264Private * const priv = decoder->priv;
1248 GstVaapiPictureH264 **ref_list;
1251 GST_DEBUG("decode reference picture list for P and SP slices");
1253 if (GST_VAAPI_PICTURE_IS_FRAME(picture)) {
1254 /* 8.2.4.2.1 - P and SP slices in frames */
1255 if (priv->short_ref_count > 0) {
1256 ref_list = priv->RefPicList0;
1257 for (i = 0; i < priv->short_ref_count; i++)
1258 ref_list[i] = priv->short_ref[i];
1259 SORT_REF_LIST(ref_list, i, pic_num_dec);
1260 priv->RefPicList0_count += i;
1263 if (priv->long_ref_count > 0) {
1264 ref_list = &priv->RefPicList0[priv->RefPicList0_count];
1265 for (i = 0; i < priv->long_ref_count; i++)
1266 ref_list[i] = priv->long_ref[i];
1267 SORT_REF_LIST(ref_list, i, long_term_pic_num_inc);
1268 priv->RefPicList0_count += i;
1272 /* 8.2.4.2.2 - P and SP slices in fields */
1273 GstVaapiPictureH264 *short_ref[32];
1274 guint short_ref_count = 0;
1275 GstVaapiPictureH264 *long_ref[32];
1276 guint long_ref_count = 0;
1278 // XXX: handle second field if current field is marked as
1279 // "used for short-term reference"
1280 if (priv->short_ref_count > 0) {
1281 for (i = 0; i < priv->short_ref_count; i++)
1282 short_ref[i] = priv->short_ref[i];
1283 SORT_REF_LIST(short_ref, i, frame_num_wrap_dec);
1284 short_ref_count = i;
1287 // XXX: handle second field if current field is marked as
1288 // "used for long-term reference"
1289 if (priv->long_ref_count > 0) {
1290 for (i = 0; i < priv->long_ref_count; i++)
1291 long_ref[i] = priv->long_ref[i];
1292 SORT_REF_LIST(long_ref, i, long_term_frame_idx_inc);
1296 // XXX: handle 8.2.4.2.5
1301 init_picture_refs_b_slice(
1302 GstVaapiDecoderH264 *decoder,
1303 GstVaapiPictureH264 *picture,
1304 GstH264SliceHdr *slice_hdr
1307 GstVaapiDecoderH264Private * const priv = decoder->priv;
1308 GstVaapiPictureH264 **ref_list;
1311 GST_DEBUG("decode reference picture list for B slices");
1313 if (GST_VAAPI_PICTURE_IS_FRAME(picture)) {
1314 /* 8.2.4.2.3 - B slices in frames */
1317 if (priv->short_ref_count > 0) {
1318 // 1. Short-term references
1319 ref_list = priv->RefPicList0;
1320 for (n = 0, i = 0; i < priv->short_ref_count; i++) {
1321 if (priv->short_ref[i]->poc < picture->poc)
1322 ref_list[n++] = priv->short_ref[i];
1324 SORT_REF_LIST(ref_list, n, poc_dec);
1325 priv->RefPicList0_count += n;
1327 ref_list = &priv->RefPicList0[priv->RefPicList0_count];
1328 for (n = 0, i = 0; i < priv->short_ref_count; i++) {
1329 if (priv->short_ref[i]->poc >= picture->poc)
1330 ref_list[n++] = priv->short_ref[i];
1332 SORT_REF_LIST(ref_list, n, poc_inc);
1333 priv->RefPicList0_count += n;
1336 if (priv->long_ref_count > 0) {
1337 // 2. Long-term references
1338 ref_list = &priv->RefPicList0[priv->RefPicList0_count];
1339 for (n = 0, i = 0; i < priv->long_ref_count; i++)
1340 ref_list[n++] = priv->long_ref[i];
1341 SORT_REF_LIST(ref_list, n, long_term_pic_num_inc);
1342 priv->RefPicList0_count += n;
1346 if (priv->short_ref_count > 0) {
1347 // 1. Short-term references
1348 ref_list = priv->RefPicList1;
1349 for (n = 0, i = 0; i < priv->short_ref_count; i++) {
1350 if (priv->short_ref[i]->poc > picture->poc)
1351 ref_list[n++] = priv->short_ref[i];
1353 SORT_REF_LIST(ref_list, n, poc_inc);
1354 priv->RefPicList1_count += n;
1356 ref_list = &priv->RefPicList1[priv->RefPicList1_count];
1357 for (n = 0, i = 0; i < priv->short_ref_count; i++) {
1358 if (priv->short_ref[i]->poc <= picture->poc)
1359 ref_list[n++] = priv->short_ref[i];
1361 SORT_REF_LIST(ref_list, n, poc_dec);
1362 priv->RefPicList1_count += n;
1365 if (priv->long_ref_count > 0) {
1366 // 2. Long-term references
1367 ref_list = &priv->RefPicList1[priv->RefPicList1_count];
1368 for (n = 0, i = 0; i < priv->long_ref_count; i++)
1369 ref_list[n++] = priv->long_ref[i];
1370 SORT_REF_LIST(ref_list, n, long_term_pic_num_inc);
1371 priv->RefPicList1_count += n;
1375 /* 8.2.4.2.4 - B slices in fields */
1376 GstVaapiPictureH264 *short_ref0[32];
1377 guint short_ref0_count = 0;
1378 GstVaapiPictureH264 *short_ref1[32];
1379 guint short_ref1_count = 0;
1380 GstVaapiPictureH264 *long_ref[32];
1381 guint long_ref_count = 0;
1383 /* refFrameList0ShortTerm */
1384 if (priv->short_ref_count > 0) {
1385 ref_list = short_ref0;
1386 for (n = 0, i = 0; i < priv->short_ref_count; i++) {
1387 if (priv->short_ref[i]->poc <= picture->poc)
1388 ref_list[n++] = priv->short_ref[i];
1390 SORT_REF_LIST(ref_list, n, poc_dec);
1391 short_ref0_count += n;
1393 ref_list = &short_ref0[short_ref0_count];
1394 for (n = 0, i = 0; i < priv->short_ref_count; i++) {
1395 if (priv->short_ref[i]->poc > picture->poc)
1396 ref_list[n++] = priv->short_ref[i];
1398 SORT_REF_LIST(ref_list, n, poc_inc);
1399 short_ref0_count += n;
1402 /* refFrameList1ShortTerm */
1403 if (priv->short_ref_count > 0) {
1404 ref_list = short_ref1;
1405 for (n = 0, i = 0; i < priv->short_ref_count; i++) {
1406 if (priv->short_ref[i]->poc > picture->poc)
1407 ref_list[n++] = priv->short_ref[i];
1409 SORT_REF_LIST(ref_list, n, poc_inc);
1410 short_ref1_count += n;
1412 ref_list = &short_ref1[short_ref1_count];
1413 for (n = 0, i = 0; i < priv->short_ref_count; i++) {
1414 if (priv->short_ref[i]->poc <= picture->poc)
1415 ref_list[n++] = priv->short_ref[i];
1417 SORT_REF_LIST(ref_list, n, poc_dec);
1418 short_ref1_count += n;
1421 /* refFrameListLongTerm */
1422 if (priv->long_ref_count > 0) {
1423 for (i = 0; i < priv->long_ref_count; i++)
1424 long_ref[i] = priv->long_ref[i];
1425 SORT_REF_LIST(long_ref, i, long_term_frame_idx_inc);
1429 // XXX: handle 8.2.4.2.5
1432 /* Check whether RefPicList1 is identical to RefPicList0, then
1433 swap if necessary */
1434 if (priv->RefPicList1_count > 1 &&
1435 priv->RefPicList1_count == priv->RefPicList0_count &&
1436 memcmp(priv->RefPicList0, priv->RefPicList1,
1437 priv->RefPicList0_count * sizeof(priv->RefPicList0[0])) == 0) {
1438 GstVaapiPictureH264 * const tmp = priv->RefPicList1[0];
1439 priv->RefPicList1[0] = priv->RefPicList1[1];
1440 priv->RefPicList1[1] = tmp;
1444 #undef SORT_REF_LIST
1448 GstVaapiDecoderH264 *decoder,
1449 GstVaapiPictureH264 **pictures,
1450 guint *picture_count
1453 const guint num_pictures = *picture_count;
1456 for (i = 0; i < num_pictures; i++)
1457 gst_vaapi_picture_replace(&pictures[i], NULL);
1462 remove_reference_at(
1463 GstVaapiDecoderH264 *decoder,
1464 GstVaapiPictureH264 **pictures,
1465 guint *picture_count,
1469 guint num_pictures = *picture_count;
1470 GstVaapiPictureH264 *picture;
1472 g_return_val_if_fail(index < num_pictures, FALSE);
1474 picture = pictures[index];
1475 GST_VAAPI_PICTURE_FLAG_UNSET(picture, GST_VAAPI_PICTURE_FLAGS_REFERENCE);
1477 if (index != --num_pictures)
1478 gst_vaapi_picture_replace(&pictures[index], pictures[num_pictures]);
1479 gst_vaapi_picture_replace(&pictures[num_pictures], NULL);
1480 *picture_count = num_pictures;
1485 find_short_term_reference(GstVaapiDecoderH264 *decoder, gint32 pic_num)
1487 GstVaapiDecoderH264Private * const priv = decoder->priv;
1490 for (i = 0; i < priv->short_ref_count; i++) {
1491 if (priv->short_ref[i]->pic_num == pic_num)
1494 GST_ERROR("found no short-term reference picture with PicNum = %d",
1500 find_long_term_reference(GstVaapiDecoderH264 *decoder, gint32 long_term_pic_num)
1502 GstVaapiDecoderH264Private * const priv = decoder->priv;
1505 for (i = 0; i < priv->long_ref_count; i++) {
1506 if (priv->long_ref[i]->long_term_pic_num == long_term_pic_num)
1509 GST_ERROR("found no long-term reference picture with LongTermPicNum = %d",
1515 exec_picture_refs_modification_1(
1516 GstVaapiDecoderH264 *decoder,
1517 GstVaapiPictureH264 *picture,
1518 GstH264SliceHdr *slice_hdr,
1522 GstVaapiDecoderH264Private * const priv = decoder->priv;
1523 GstH264PPS * const pps = slice_hdr->pps;
1524 GstH264SPS * const sps = pps->sequence;
1525 GstH264RefPicListModification *ref_pic_list_modification;
1526 guint num_ref_pic_list_modifications;
1527 GstVaapiPictureH264 **ref_list;
1528 guint *ref_list_count_ptr, ref_list_count, ref_list_idx = 0;
1529 guint i, j, n, num_refs;
1531 gint32 MaxPicNum, CurrPicNum, picNumPred;
1533 GST_DEBUG("modification process of reference picture list %u", list);
1536 ref_pic_list_modification = slice_hdr->ref_pic_list_modification_l0;
1537 num_ref_pic_list_modifications = slice_hdr->n_ref_pic_list_modification_l0;
1538 ref_list = priv->RefPicList0;
1539 ref_list_count_ptr = &priv->RefPicList0_count;
1540 num_refs = slice_hdr->num_ref_idx_l0_active_minus1 + 1;
1543 ref_pic_list_modification = slice_hdr->ref_pic_list_modification_l1;
1544 num_ref_pic_list_modifications = slice_hdr->n_ref_pic_list_modification_l1;
1545 ref_list = priv->RefPicList1;
1546 ref_list_count_ptr = &priv->RefPicList1_count;
1547 num_refs = slice_hdr->num_ref_idx_l1_active_minus1 + 1;
1549 ref_list_count = *ref_list_count_ptr;
1551 if (!GST_VAAPI_PICTURE_IS_FRAME(picture)) {
1552 MaxPicNum = 1 << (sps->log2_max_frame_num_minus4 + 5); // 2 * MaxFrameNum
1553 CurrPicNum = 2 * slice_hdr->frame_num + 1; // 2 * frame_num + 1
1556 MaxPicNum = 1 << (sps->log2_max_frame_num_minus4 + 4); // MaxFrameNum
1557 CurrPicNum = slice_hdr->frame_num; // frame_num
1560 picNumPred = CurrPicNum;
1562 for (i = 0; i < num_ref_pic_list_modifications; i++) {
1563 GstH264RefPicListModification * const l = &ref_pic_list_modification[i];
1564 if (l->modification_of_pic_nums_idc == 3)
1567 /* 8.2.4.3.1 - Short-term reference pictures */
1568 if (l->modification_of_pic_nums_idc == 0 || l->modification_of_pic_nums_idc == 1) {
1569 gint32 abs_diff_pic_num = l->value.abs_diff_pic_num_minus1 + 1;
1570 gint32 picNum, picNumNoWrap;
1573 if (l->modification_of_pic_nums_idc == 0) {
1574 picNumNoWrap = picNumPred - abs_diff_pic_num;
1575 if (picNumNoWrap < 0)
1576 picNumNoWrap += MaxPicNum;
1581 picNumNoWrap = picNumPred + abs_diff_pic_num;
1582 if (picNumNoWrap >= MaxPicNum)
1583 picNumNoWrap -= MaxPicNum;
1585 picNumPred = picNumNoWrap;
1588 picNum = picNumNoWrap;
1589 if (picNum > CurrPicNum)
1590 picNum -= MaxPicNum;
1593 for (j = num_refs; j > ref_list_idx; j--)
1594 ref_list[j] = ref_list[j - 1];
1595 found_ref_idx = find_short_term_reference(decoder, picNum);
1596 ref_list[ref_list_idx++] =
1597 found_ref_idx >= 0 ? priv->short_ref[found_ref_idx] : NULL;
1599 for (j = ref_list_idx; j <= num_refs; j++) {
1604 GST_VAAPI_PICTURE_IS_SHORT_TERM_REFERENCE(ref_list[j]) ?
1605 ref_list[j]->pic_num : MaxPicNum;
1606 if (PicNumF != picNum)
1607 ref_list[n++] = ref_list[j];
1611 /* 8.2.4.3.2 - Long-term reference pictures */
1614 for (j = num_refs; j > ref_list_idx; j--)
1615 ref_list[j] = ref_list[j - 1];
1617 find_long_term_reference(decoder, l->value.long_term_pic_num);
1618 ref_list[ref_list_idx++] =
1619 found_ref_idx >= 0 ? priv->long_ref[found_ref_idx] : NULL;
1621 for (j = ref_list_idx; j <= num_refs; j++) {
1622 gint32 LongTermPicNumF;
1626 GST_VAAPI_PICTURE_IS_LONG_TERM_REFERENCE(ref_list[j]) ?
1627 ref_list[j]->long_term_pic_num : INT_MAX;
1628 if (LongTermPicNumF != l->value.long_term_pic_num)
1629 ref_list[n++] = ref_list[j];
1635 for (i = 0; i < num_refs; i++)
1637 GST_ERROR("list %u entry %u is empty", list, i);
1639 *ref_list_count_ptr = num_refs;
1642 /* 8.2.4.3 - Modification process for reference picture lists */
1644 exec_picture_refs_modification(
1645 GstVaapiDecoderH264 *decoder,
1646 GstVaapiPictureH264 *picture,
1647 GstH264SliceHdr *slice_hdr
1650 GST_DEBUG("execute ref_pic_list_modification()");
1653 if (!GST_H264_IS_I_SLICE(slice_hdr) && !GST_H264_IS_SI_SLICE(slice_hdr) &&
1654 slice_hdr->ref_pic_list_modification_flag_l0)
1655 exec_picture_refs_modification_1(decoder, picture, slice_hdr, 0);
1658 if (GST_H264_IS_B_SLICE(slice_hdr) &&
1659 slice_hdr->ref_pic_list_modification_flag_l1)
1660 exec_picture_refs_modification_1(decoder, picture, slice_hdr, 1);
1665 GstVaapiDecoderH264 *decoder,
1666 GstVaapiPictureH264 *picture,
1667 GstH264SliceHdr *slice_hdr
1670 GstVaapiDecoderH264Private * const priv = decoder->priv;
1671 GstVaapiPicture * const base_picture = &picture->base;
1674 init_picture_refs_pic_num(decoder, picture, slice_hdr);
1676 priv->RefPicList0_count = 0;
1677 priv->RefPicList1_count = 0;
1679 switch (base_picture->type) {
1680 case GST_VAAPI_PICTURE_TYPE_P:
1681 case GST_VAAPI_PICTURE_TYPE_SP:
1682 init_picture_refs_p_slice(decoder, picture, slice_hdr);
1684 case GST_VAAPI_PICTURE_TYPE_B:
1685 init_picture_refs_b_slice(decoder, picture, slice_hdr);
1691 exec_picture_refs_modification(decoder, picture, slice_hdr);
1693 switch (base_picture->type) {
1694 case GST_VAAPI_PICTURE_TYPE_B:
1695 num_refs = 1 + slice_hdr->num_ref_idx_l1_active_minus1;
1696 for (i = priv->RefPicList1_count; i < num_refs; i++)
1697 priv->RefPicList1[i] = NULL;
1698 priv->RefPicList1_count = num_refs;
1701 case GST_VAAPI_PICTURE_TYPE_P:
1702 case GST_VAAPI_PICTURE_TYPE_SP:
1703 num_refs = 1 + slice_hdr->num_ref_idx_l0_active_minus1;
1704 for (i = priv->RefPicList0_count; i < num_refs; i++)
1705 priv->RefPicList0[i] = NULL;
1706 priv->RefPicList0_count = num_refs;
1716 GstVaapiDecoderH264 *decoder,
1717 GstVaapiPictureH264 *picture,
1718 GstH264SliceHdr *slice_hdr,
1719 GstH264NalUnit *nalu
1722 GstVaapiDecoderH264Private * const priv = decoder->priv;
1723 GstVaapiPicture * const base_picture = &picture->base;
1725 priv->prev_frame_num = priv->frame_num;
1726 priv->frame_num = slice_hdr->frame_num;
1727 picture->frame_num = priv->frame_num;
1728 picture->frame_num_wrap = priv->frame_num;
1729 picture->output_flag = TRUE; /* XXX: conformant to Annex A only */
1730 base_picture->pts = gst_adapter_prev_timestamp(priv->adapter, NULL);
1732 /* Reset decoder state for IDR pictures */
1733 if (nalu->type == GST_H264_NAL_SLICE_IDR) {
1735 GST_VAAPI_PICTURE_FLAG_SET(picture, GST_VAAPI_PICTURE_FLAG_IDR);
1736 clear_references(decoder, priv->short_ref, &priv->short_ref_count);
1737 clear_references(decoder, priv->long_ref, &priv->long_ref_count );
1740 /* Initialize slice type */
1741 switch (slice_hdr->type % 5) {
1742 case GST_H264_P_SLICE:
1743 base_picture->type = GST_VAAPI_PICTURE_TYPE_P;
1745 case GST_H264_B_SLICE:
1746 base_picture->type = GST_VAAPI_PICTURE_TYPE_B;
1748 case GST_H264_I_SLICE:
1749 base_picture->type = GST_VAAPI_PICTURE_TYPE_I;
1751 case GST_H264_SP_SLICE:
1752 base_picture->type = GST_VAAPI_PICTURE_TYPE_SP;
1754 case GST_H264_SI_SLICE:
1755 base_picture->type = GST_VAAPI_PICTURE_TYPE_SI;
1759 /* Initialize picture structure */
1760 if (!slice_hdr->field_pic_flag)
1761 base_picture->structure = GST_VAAPI_PICTURE_STRUCTURE_FRAME;
1762 else if (!slice_hdr->bottom_field_flag)
1763 base_picture->structure = GST_VAAPI_PICTURE_STRUCTURE_TOP_FIELD;
1765 base_picture->structure = GST_VAAPI_PICTURE_STRUCTURE_BOTTOM_FIELD;
1767 if (nalu->ref_idc) {
1768 GstH264DecRefPicMarking * const dec_ref_pic_marking =
1769 &slice_hdr->dec_ref_pic_marking;
1771 if (GST_VAAPI_PICTURE_IS_IDR(picture) &&
1772 dec_ref_pic_marking->long_term_reference_flag)
1773 GST_VAAPI_PICTURE_FLAG_SET(picture,
1774 GST_VAAPI_PICTURE_FLAG_LONG_TERM_REFERENCE);
1776 GST_VAAPI_PICTURE_FLAG_SET(picture,
1777 GST_VAAPI_PICTURE_FLAG_SHORT_TERM_REFERENCE);
1780 init_picture_poc(decoder, picture, slice_hdr);
1781 if (!init_picture_refs(decoder, picture, slice_hdr)) {
1782 GST_ERROR("failed to initialize references");
1788 /* 8.2.5.3 - Sliding window decoded reference picture marking process */
1790 exec_ref_pic_marking_sliding_window(GstVaapiDecoderH264 *decoder)
1792 GstVaapiDecoderH264Private * const priv = decoder->priv;
1793 GstH264PPS * const pps = priv->current_picture->pps;
1794 GstH264SPS * const sps = pps->sequence;
1795 guint i, max_num_ref_frames, lowest_frame_num_index;
1796 gint32 lowest_frame_num;
1798 GST_DEBUG("reference picture marking process (sliding window)");
1800 max_num_ref_frames = sps->num_ref_frames;
1801 if (max_num_ref_frames == 0)
1802 max_num_ref_frames = 1;
1804 if (priv->short_ref_count + priv->long_ref_count < max_num_ref_frames)
1806 if (priv->short_ref_count < 1)
1809 lowest_frame_num = priv->short_ref[0]->frame_num_wrap;
1810 lowest_frame_num_index = 0;
1811 for (i = 1; i < priv->short_ref_count; i++) {
1812 if (priv->short_ref[i]->frame_num_wrap < lowest_frame_num) {
1813 lowest_frame_num = priv->short_ref[i]->frame_num_wrap;
1814 lowest_frame_num_index = i;
1818 remove_reference_at(
1820 priv->short_ref, &priv->short_ref_count,
1821 lowest_frame_num_index
1826 static inline gint32
1827 get_picNumX(GstVaapiPictureH264 *picture, GstH264RefPicMarking *ref_pic_marking)
1831 if (GST_VAAPI_PICTURE_IS_FRAME(picture))
1832 pic_num = picture->frame_num_wrap;
1834 pic_num = 2 * picture->frame_num_wrap + 1;
1835 pic_num -= ref_pic_marking->difference_of_pic_nums_minus1 + 1;
1839 /* 8.2.5.4.1. Mark-term reference picture as "unused for reference" */
1841 exec_ref_pic_marking_adaptive_mmco_1(
1842 GstVaapiDecoderH264 *decoder,
1843 GstVaapiPictureH264 *picture,
1844 GstH264RefPicMarking *ref_pic_marking
1847 GstVaapiDecoderH264Private * const priv = decoder->priv;
1850 picNumX = get_picNumX(picture, ref_pic_marking);
1851 i = find_short_term_reference(decoder, picNumX);
1854 remove_reference_at(decoder, priv->short_ref, &priv->short_ref_count, i);
1857 /* 8.2.5.4.2. Mark long-term reference picture as "unused for reference" */
1859 exec_ref_pic_marking_adaptive_mmco_2(
1860 GstVaapiDecoderH264 *decoder,
1861 GstVaapiPictureH264 *picture,
1862 GstH264RefPicMarking *ref_pic_marking
1865 GstVaapiDecoderH264Private * const priv = decoder->priv;
1868 i = find_long_term_reference(decoder, ref_pic_marking->long_term_pic_num);
1871 remove_reference_at(decoder, priv->long_ref, &priv->long_ref_count, i);
1874 /* 8.2.5.4.3. Assign LongTermFrameIdx to a short-term reference picture */
1876 exec_ref_pic_marking_adaptive_mmco_3(
1877 GstVaapiDecoderH264 *decoder,
1878 GstVaapiPictureH264 *picture,
1879 GstH264RefPicMarking *ref_pic_marking
1882 GstVaapiDecoderH264Private * const priv = decoder->priv;
1885 for (i = 0; i < priv->long_ref_count; i++) {
1886 if (priv->long_ref[i]->long_term_frame_idx == ref_pic_marking->long_term_frame_idx)
1889 if (i != priv->long_ref_count)
1890 remove_reference_at(decoder, priv->long_ref, &priv->long_ref_count, i);
1892 picNumX = get_picNumX(picture, ref_pic_marking);
1893 i = find_short_term_reference(decoder, picNumX);
1897 picture = gst_vaapi_picture_ref(priv->short_ref[i]);
1898 remove_reference_at(decoder, priv->short_ref, &priv->short_ref_count, i);
1899 gst_vaapi_picture_replace(&priv->long_ref[priv->long_ref_count++], picture);
1900 gst_vaapi_picture_unref(picture);
1902 picture->long_term_frame_idx = ref_pic_marking->long_term_frame_idx;
1903 GST_VAAPI_PICTURE_FLAG_SET(picture,
1904 GST_VAAPI_PICTURE_FLAG_LONG_TERM_REFERENCE);
1907 /* 8.2.5.4.4. Mark pictures with LongTermFramIdx > max_long_term_frame_idx
1908 * as "unused for reference" */
1910 exec_ref_pic_marking_adaptive_mmco_4(
1911 GstVaapiDecoderH264 *decoder,
1912 GstVaapiPictureH264 *picture,
1913 GstH264RefPicMarking *ref_pic_marking
1916 GstVaapiDecoderH264Private * const priv = decoder->priv;
1917 gint32 i, long_term_frame_idx;
1919 long_term_frame_idx = ref_pic_marking->max_long_term_frame_idx_plus1 - 1;
1921 for (i = 0; i < priv->long_ref_count; i++) {
1922 if (priv->long_ref[i]->long_term_frame_idx <= long_term_frame_idx)
1924 remove_reference_at(decoder, priv->long_ref, &priv->long_ref_count, i);
1929 /* 8.2.5.4.5. Mark all reference pictures as "unused for reference" */
1931 exec_ref_pic_marking_adaptive_mmco_5(
1932 GstVaapiDecoderH264 *decoder,
1933 GstVaapiPictureH264 *picture,
1934 GstH264RefPicMarking *ref_pic_marking
1937 GstVaapiDecoderH264Private * const priv = decoder->priv;
1938 VAPictureH264 * const pic = &picture->info;
1940 clear_references(decoder, priv->short_ref, &priv->short_ref_count);
1941 clear_references(decoder, priv->long_ref, &priv->long_ref_count );
1944 priv->prev_pic_has_mmco5 = TRUE;
1946 /* The picture shall be inferred to have had frame_num equal to 0 (7.4.3) */
1947 priv->frame_num = 0;
1948 priv->frame_num_offset = 0;
1949 picture->frame_num = 0;
1951 /* Update TopFieldOrderCnt and BottomFieldOrderCnt (8.2.1) */
1952 if (picture->base.structure != GST_VAAPI_PICTURE_STRUCTURE_BOTTOM_FIELD)
1953 pic->TopFieldOrderCnt -= picture->poc;
1954 if (picture->base.structure != GST_VAAPI_PICTURE_STRUCTURE_TOP_FIELD)
1955 pic->BottomFieldOrderCnt -= picture->poc;
1959 /* 8.2.5.4.6. Assign a long-term frame index to the current picture */
1961 exec_ref_pic_marking_adaptive_mmco_6(
1962 GstVaapiDecoderH264 *decoder,
1963 GstVaapiPictureH264 *picture,
1964 GstH264RefPicMarking *ref_pic_marking
1967 picture->long_term_frame_idx = ref_pic_marking->long_term_frame_idx;
1968 GST_VAAPI_PICTURE_FLAG_SET(picture,
1969 GST_VAAPI_PICTURE_FLAG_LONG_TERM_REFERENCE);
1972 /* 8.2.5.4. Adaptive memory control decoded reference picture marking process */
1974 exec_ref_pic_marking_adaptive(
1975 GstVaapiDecoderH264 *decoder,
1976 GstVaapiPictureH264 *picture,
1977 GstH264DecRefPicMarking *dec_ref_pic_marking
1982 GST_DEBUG("reference picture marking process (adaptive memory control)");
1984 typedef void (*exec_ref_pic_marking_adaptive_mmco_func)(
1985 GstVaapiDecoderH264 *decoder,
1986 GstVaapiPictureH264 *picture,
1987 GstH264RefPicMarking *ref_pic_marking
1990 static const exec_ref_pic_marking_adaptive_mmco_func mmco_funcs[] = {
1992 exec_ref_pic_marking_adaptive_mmco_1,
1993 exec_ref_pic_marking_adaptive_mmco_2,
1994 exec_ref_pic_marking_adaptive_mmco_3,
1995 exec_ref_pic_marking_adaptive_mmco_4,
1996 exec_ref_pic_marking_adaptive_mmco_5,
1997 exec_ref_pic_marking_adaptive_mmco_6,
2000 for (i = 0; i < dec_ref_pic_marking->n_ref_pic_marking; i++) {
2001 GstH264RefPicMarking * const ref_pic_marking =
2002 &dec_ref_pic_marking->ref_pic_marking[i];
2004 const guint mmco = ref_pic_marking->memory_management_control_operation;
2005 if (mmco < G_N_ELEMENTS(mmco_funcs) && mmco_funcs[mmco])
2006 mmco_funcs[mmco](decoder, picture, ref_pic_marking);
2008 GST_ERROR("unhandled MMCO %u", mmco);
2015 /* 8.2.5 - Execute reference picture marking process */
2017 exec_ref_pic_marking(GstVaapiDecoderH264 *decoder, GstVaapiPictureH264 *picture)
2019 GstVaapiDecoderH264Private * const priv = decoder->priv;
2020 GstVaapiPictureH264 **picture_ptr;
2022 priv->prev_pic_has_mmco5 = FALSE;
2023 priv->prev_pic_structure = picture->base.structure;
2025 if (!GST_VAAPI_PICTURE_IS_REFERENCE(picture))
2028 if (!GST_VAAPI_PICTURE_IS_IDR(picture)) {
2029 GstVaapiSliceH264 * const slice =
2030 gst_vaapi_picture_h264_get_last_slice(picture);
2031 GstH264DecRefPicMarking * const dec_ref_pic_marking =
2032 &slice->slice_hdr.dec_ref_pic_marking;
2033 if (dec_ref_pic_marking->adaptive_ref_pic_marking_mode_flag) {
2034 if (!exec_ref_pic_marking_adaptive(decoder, picture, dec_ref_pic_marking))
2038 if (!exec_ref_pic_marking_sliding_window(decoder))
2043 if (GST_VAAPI_PICTURE_IS_LONG_TERM_REFERENCE(picture))
2044 picture_ptr = &priv->long_ref[priv->long_ref_count++];
2046 picture_ptr = &priv->short_ref[priv->short_ref_count++];
2047 gst_vaapi_picture_replace(picture_ptr, picture);
2052 vaapi_init_picture(VAPictureH264 *pic)
2054 pic->picture_id = VA_INVALID_ID;
2056 pic->flags = VA_PICTURE_H264_INVALID;
2057 pic->TopFieldOrderCnt = 0;
2058 pic->BottomFieldOrderCnt = 0;
2062 vaapi_fill_picture(VAPictureH264 *pic, GstVaapiPictureH264 *picture)
2064 pic->picture_id = picture->base.surface_id;
2067 if (GST_VAAPI_PICTURE_IS_LONG_TERM_REFERENCE(picture)) {
2068 pic->flags |= VA_PICTURE_H264_LONG_TERM_REFERENCE;
2069 pic->frame_idx = picture->long_term_frame_idx;
2072 if (GST_VAAPI_PICTURE_IS_SHORT_TERM_REFERENCE(picture))
2073 pic->flags |= VA_PICTURE_H264_SHORT_TERM_REFERENCE;
2074 pic->frame_idx = picture->frame_num;
2077 switch (picture->base.structure) {
2078 case GST_VAAPI_PICTURE_STRUCTURE_FRAME:
2079 pic->TopFieldOrderCnt = picture->info.TopFieldOrderCnt;
2080 pic->BottomFieldOrderCnt = picture->info.BottomFieldOrderCnt;
2082 case GST_VAAPI_PICTURE_STRUCTURE_TOP_FIELD:
2083 pic->flags |= VA_PICTURE_H264_TOP_FIELD;
2084 pic->TopFieldOrderCnt = picture->info.BottomFieldOrderCnt;
2085 pic->BottomFieldOrderCnt = 0;
2087 case GST_VAAPI_PICTURE_STRUCTURE_BOTTOM_FIELD:
2088 pic->flags |= VA_PICTURE_H264_BOTTOM_FIELD;
2089 pic->BottomFieldOrderCnt = picture->info.BottomFieldOrderCnt;
2090 pic->TopFieldOrderCnt = 0;
2097 GstVaapiDecoderH264 *decoder,
2098 GstVaapiPictureH264 *picture,
2099 GstH264SliceHdr *slice_hdr,
2100 GstH264NalUnit *nalu
2103 GstVaapiDecoderH264Private * const priv = decoder->priv;
2104 GstVaapiPicture * const base_picture = &picture->base;
2105 GstH264PPS * const pps = picture->pps;
2106 GstH264SPS * const sps = pps->sequence;
2107 VAPictureParameterBufferH264 * const pic_param = base_picture->param;
2110 /* Fill in VAPictureParameterBufferH264 */
2111 vaapi_fill_picture(&pic_param->CurrPic, picture);
2112 for (i = 0, n = 0; i < priv->short_ref_count; i++, n++)
2113 vaapi_fill_picture(&pic_param->ReferenceFrames[n], priv->short_ref[i]);
2114 for (i = 0; i < priv->long_ref_count; i++, n++)
2115 vaapi_fill_picture(&pic_param->ReferenceFrames[n], priv->long_ref[i]);
2116 for (; n < G_N_ELEMENTS(pic_param->ReferenceFrames); n++)
2117 vaapi_init_picture(&pic_param->ReferenceFrames[n]);
2119 #define COPY_FIELD(s, f) \
2120 pic_param->f = (s)->f
2122 #define COPY_BFM(a, s, f) \
2123 pic_param->a.bits.f = (s)->f
2125 pic_param->picture_width_in_mbs_minus1 = ((priv->width + 15) >> 4) - 1;
2126 pic_param->picture_height_in_mbs_minus1 = ((priv->height + 15) >> 4) - 1;
2127 pic_param->frame_num = priv->frame_num;
2129 COPY_FIELD(sps, bit_depth_luma_minus8);
2130 COPY_FIELD(sps, bit_depth_chroma_minus8);
2131 COPY_FIELD(sps, num_ref_frames);
2132 COPY_FIELD(pps, num_slice_groups_minus1);
2133 COPY_FIELD(pps, slice_group_map_type);
2134 COPY_FIELD(pps, slice_group_change_rate_minus1);
2135 COPY_FIELD(pps, pic_init_qp_minus26);
2136 COPY_FIELD(pps, pic_init_qs_minus26);
2137 COPY_FIELD(pps, chroma_qp_index_offset);
2138 COPY_FIELD(pps, second_chroma_qp_index_offset);
2140 pic_param->seq_fields.value = 0; /* reset all bits */
2141 pic_param->seq_fields.bits.residual_colour_transform_flag = sps->separate_colour_plane_flag;
2142 pic_param->seq_fields.bits.MinLumaBiPredSize8x8 = sps->level_idc >= 31; /* A.3.3.2 */
2144 COPY_BFM(seq_fields, sps, chroma_format_idc);
2145 COPY_BFM(seq_fields, sps, gaps_in_frame_num_value_allowed_flag);
2146 COPY_BFM(seq_fields, sps, frame_mbs_only_flag);
2147 COPY_BFM(seq_fields, sps, mb_adaptive_frame_field_flag);
2148 COPY_BFM(seq_fields, sps, direct_8x8_inference_flag);
2149 COPY_BFM(seq_fields, sps, log2_max_frame_num_minus4);
2150 COPY_BFM(seq_fields, sps, pic_order_cnt_type);
2151 COPY_BFM(seq_fields, sps, log2_max_pic_order_cnt_lsb_minus4);
2152 COPY_BFM(seq_fields, sps, delta_pic_order_always_zero_flag);
2154 pic_param->pic_fields.value = 0; /* reset all bits */
2155 pic_param->pic_fields.bits.field_pic_flag = slice_hdr->field_pic_flag;
2156 pic_param->pic_fields.bits.reference_pic_flag = GST_VAAPI_PICTURE_IS_REFERENCE(picture);
2158 COPY_BFM(pic_fields, pps, entropy_coding_mode_flag);
2159 COPY_BFM(pic_fields, pps, weighted_pred_flag);
2160 COPY_BFM(pic_fields, pps, weighted_bipred_idc);
2161 COPY_BFM(pic_fields, pps, transform_8x8_mode_flag);
2162 COPY_BFM(pic_fields, pps, constrained_intra_pred_flag);
2163 COPY_BFM(pic_fields, pps, pic_order_present_flag);
2164 COPY_BFM(pic_fields, pps, deblocking_filter_control_present_flag);
2165 COPY_BFM(pic_fields, pps, redundant_pic_cnt_present_flag);
2169 /* Detection of the first VCL NAL unit of a primary coded picture (7.4.1.2.4) */
2172 GstVaapiDecoderH264 *decoder,
2173 GstH264NalUnit *nalu,
2174 GstH264SliceHdr *slice_hdr
2177 GstVaapiDecoderH264Private * const priv = decoder->priv;
2178 GstH264PPS * const pps = slice_hdr->pps;
2179 GstH264SPS * const sps = pps->sequence;
2180 GstVaapiSliceH264 *slice;
2181 GstH264SliceHdr *prev_slice_hdr;
2183 if (!priv->current_picture)
2186 slice = gst_vaapi_picture_h264_get_last_slice(priv->current_picture);
2189 prev_slice_hdr = &slice->slice_hdr;
2191 #define CHECK_EXPR(expr, field_name) do { \
2193 GST_DEBUG(field_name " differs in value"); \
2198 #define CHECK_VALUE(new_slice_hdr, old_slice_hdr, field) \
2199 CHECK_EXPR(((new_slice_hdr)->field == (old_slice_hdr)->field), #field)
2201 /* frame_num differs in value, regardless of inferred values to 0 */
2202 CHECK_VALUE(slice_hdr, prev_slice_hdr, frame_num);
2204 /* pic_parameter_set_id differs in value */
2205 CHECK_VALUE(slice_hdr, prev_slice_hdr, pps);
2207 /* field_pic_flag differs in value */
2208 CHECK_VALUE(slice_hdr, prev_slice_hdr, field_pic_flag);
2210 /* bottom_field_flag is present in both and differs in value */
2211 if (slice_hdr->field_pic_flag && prev_slice_hdr->field_pic_flag)
2212 CHECK_VALUE(slice_hdr, prev_slice_hdr, bottom_field_flag);
2214 /* nal_ref_idc differs in value with one of the nal_ref_idc values is 0 */
2215 CHECK_EXPR(((GST_VAAPI_PICTURE_IS_REFERENCE(priv->current_picture) ^
2216 (nalu->ref_idc != 0)) == 0), "nal_ref_idc");
2218 /* POC type is 0 for both and either pic_order_cnt_lsb differs in
2219 value or delta_pic_order_cnt_bottom differs in value */
2220 if (sps->pic_order_cnt_type == 0) {
2221 CHECK_VALUE(slice_hdr, prev_slice_hdr, pic_order_cnt_lsb);
2222 if (pps->pic_order_present_flag && !slice_hdr->field_pic_flag)
2223 CHECK_VALUE(slice_hdr, prev_slice_hdr, delta_pic_order_cnt_bottom);
2226 /* POC type is 1 for both and either delta_pic_order_cnt[0]
2227 differs in value or delta_pic_order_cnt[1] differs in value */
2228 else if (sps->pic_order_cnt_type == 1) {
2229 CHECK_VALUE(slice_hdr, prev_slice_hdr, delta_pic_order_cnt[0]);
2230 CHECK_VALUE(slice_hdr, prev_slice_hdr, delta_pic_order_cnt[1]);
2233 /* IdrPicFlag differs in value */
2234 CHECK_EXPR(((GST_VAAPI_PICTURE_IS_IDR(priv->current_picture) ^
2235 (nalu->type == GST_H264_NAL_SLICE_IDR)) == 0), "IdrPicFlag");
2237 /* IdrPicFlag is equal to 1 for both and idr_pic_id differs in value */
2238 if (GST_VAAPI_PICTURE_IS_IDR(priv->current_picture))
2239 CHECK_VALUE(slice_hdr, prev_slice_hdr, idr_pic_id);
2246 static GstVaapiDecoderStatus
2247 decode_picture(GstVaapiDecoderH264 *decoder, GstH264NalUnit *nalu, GstH264SliceHdr *slice_hdr)
2249 GstVaapiDecoderH264Private * const priv = decoder->priv;
2250 GstVaapiPictureH264 *picture;
2251 GstVaapiDecoderStatus status;
2252 GstH264PPS * const pps = slice_hdr->pps;
2253 GstH264SPS * const sps = pps->sequence;
2255 status = decode_current_picture(decoder);
2256 if (status != GST_VAAPI_DECODER_STATUS_SUCCESS)
2259 status = ensure_context(decoder, sps);
2260 if (status != GST_VAAPI_DECODER_STATUS_SUCCESS)
2263 picture = gst_vaapi_picture_h264_new(decoder);
2265 GST_ERROR("failed to allocate picture");
2266 return GST_VAAPI_DECODER_STATUS_ERROR_ALLOCATION_FAILED;
2268 priv->current_picture = picture;
2272 status = ensure_quant_matrix(decoder, picture);
2273 if (status != GST_VAAPI_DECODER_STATUS_SUCCESS) {
2274 GST_ERROR("failed to reset quantizer matrix");
2278 if (!init_picture(decoder, picture, slice_hdr, nalu))
2279 return GST_VAAPI_DECODER_STATUS_ERROR_UNKNOWN;
2280 if (!fill_picture(decoder, picture, slice_hdr, nalu))
2281 return GST_VAAPI_DECODER_STATUS_ERROR_UNKNOWN;
2282 return GST_VAAPI_DECODER_STATUS_SUCCESS;
2286 decode_picture_end(GstVaapiDecoderH264 *decoder, GstVaapiPictureH264 *picture)
2288 if (!exec_ref_pic_marking(decoder, picture))
2290 if (!dpb_add(decoder, picture))
2296 get_slice_data_bit_offset(GstH264SliceHdr *slice_hdr, GstH264NalUnit *nalu)
2300 epb_count = slice_hdr->n_emulation_prevention_bytes;
2301 return 8 /* nal_unit_type */ + slice_hdr->header_size - epb_count * 8;
2305 fill_pred_weight_table(GstVaapiDecoderH264 *decoder, GstVaapiSliceH264 *slice)
2307 GstH264SliceHdr * const slice_hdr = &slice->slice_hdr;
2308 GstH264PPS * const pps = slice_hdr->pps;
2309 GstH264SPS * const sps = pps->sequence;
2310 GstH264PredWeightTable * const w = &slice_hdr->pred_weight_table;
2311 VASliceParameterBufferH264 * const slice_param = slice->base.param;
2312 guint num_weight_tables = 0;
2315 if (pps->weighted_pred_flag &&
2316 (GST_H264_IS_P_SLICE(slice_hdr) || GST_H264_IS_SP_SLICE(slice_hdr)))
2317 num_weight_tables = 1;
2318 else if (pps->weighted_bipred_idc == 1 && GST_H264_IS_B_SLICE(slice_hdr))
2319 num_weight_tables = 2;
2321 num_weight_tables = 0;
2323 slice_param->luma_log2_weight_denom = w->luma_log2_weight_denom;
2324 slice_param->chroma_log2_weight_denom = w->chroma_log2_weight_denom;
2325 slice_param->luma_weight_l0_flag = 0;
2326 slice_param->chroma_weight_l0_flag = 0;
2327 slice_param->luma_weight_l1_flag = 0;
2328 slice_param->chroma_weight_l1_flag = 0;
2330 if (num_weight_tables < 1)
2333 slice_param->luma_weight_l0_flag = 1;
2334 for (i = 0; i <= slice_param->num_ref_idx_l0_active_minus1; i++) {
2335 slice_param->luma_weight_l0[i] = w->luma_weight_l0[i];
2336 slice_param->luma_offset_l0[i] = w->luma_offset_l0[i];
2339 slice_param->chroma_weight_l0_flag = sps->chroma_array_type != 0;
2340 if (slice_param->chroma_weight_l0_flag) {
2341 for (i = 0; i <= slice_param->num_ref_idx_l0_active_minus1; i++) {
2342 for (j = 0; j < 2; j++) {
2343 slice_param->chroma_weight_l0[i][j] = w->chroma_weight_l0[i][j];
2344 slice_param->chroma_offset_l0[i][j] = w->chroma_offset_l0[i][j];
2349 if (num_weight_tables < 2)
2352 slice_param->luma_weight_l1_flag = 1;
2353 for (i = 0; i <= slice_param->num_ref_idx_l1_active_minus1; i++) {
2354 slice_param->luma_weight_l1[i] = w->luma_weight_l1[i];
2355 slice_param->luma_offset_l1[i] = w->luma_offset_l1[i];
2358 slice_param->chroma_weight_l1_flag = sps->chroma_array_type != 0;
2359 if (slice_param->chroma_weight_l1_flag) {
2360 for (i = 0; i <= slice_param->num_ref_idx_l1_active_minus1; i++) {
2361 for (j = 0; j < 2; j++) {
2362 slice_param->chroma_weight_l1[i][j] = w->chroma_weight_l1[i][j];
2363 slice_param->chroma_offset_l1[i][j] = w->chroma_offset_l1[i][j];
2371 fill_RefPicList(GstVaapiDecoderH264 *decoder, GstVaapiSliceH264 *slice)
2373 GstVaapiDecoderH264Private * const priv = decoder->priv;
2374 GstH264SliceHdr * const slice_hdr = &slice->slice_hdr;
2375 VASliceParameterBufferH264 * const slice_param = slice->base.param;
2376 guint i, num_ref_lists = 0;
2378 slice_param->num_ref_idx_l0_active_minus1 = 0;
2379 slice_param->num_ref_idx_l1_active_minus1 = 0;
2381 if (GST_H264_IS_B_SLICE(slice_hdr))
2383 else if (GST_H264_IS_I_SLICE(slice_hdr))
2388 if (num_ref_lists < 1)
2391 slice_param->num_ref_idx_l0_active_minus1 =
2392 slice_hdr->num_ref_idx_l0_active_minus1;
2394 for (i = 0; i < priv->RefPicList0_count && priv->RefPicList0[i]; i++)
2395 vaapi_fill_picture(&slice_param->RefPicList0[i], priv->RefPicList0[i]);
2396 for (; i <= slice_param->num_ref_idx_l0_active_minus1; i++)
2397 vaapi_init_picture(&slice_param->RefPicList0[i]);
2399 if (num_ref_lists < 2)
2402 slice_param->num_ref_idx_l1_active_minus1 =
2403 slice_hdr->num_ref_idx_l1_active_minus1;
2405 for (i = 0; i < priv->RefPicList1_count && priv->RefPicList1[i]; i++)
2406 vaapi_fill_picture(&slice_param->RefPicList1[i], priv->RefPicList1[i]);
2407 for (; i <= slice_param->num_ref_idx_l1_active_minus1; i++)
2408 vaapi_init_picture(&slice_param->RefPicList1[i]);
2414 GstVaapiDecoderH264 *decoder,
2415 GstVaapiSliceH264 *slice,
2416 GstH264NalUnit *nalu
2419 GstH264SliceHdr * const slice_hdr = &slice->slice_hdr;
2420 VASliceParameterBufferH264 * const slice_param = slice->base.param;
2422 /* Fill in VASliceParameterBufferH264 */
2423 slice_param->slice_data_bit_offset = get_slice_data_bit_offset(slice_hdr, nalu);
2424 slice_param->first_mb_in_slice = slice_hdr->first_mb_in_slice;
2425 slice_param->slice_type = slice_hdr->type % 5;
2426 slice_param->direct_spatial_mv_pred_flag = slice_hdr->direct_spatial_mv_pred_flag;
2427 slice_param->cabac_init_idc = slice_hdr->cabac_init_idc;
2428 slice_param->slice_qp_delta = slice_hdr->slice_qp_delta;
2429 slice_param->disable_deblocking_filter_idc = slice_hdr->disable_deblocking_filter_idc;
2430 slice_param->slice_alpha_c0_offset_div2 = slice_hdr->slice_alpha_c0_offset_div2;
2431 slice_param->slice_beta_offset_div2 = slice_hdr->slice_beta_offset_div2;
2433 if (!fill_RefPicList(decoder, slice))
2435 if (!fill_pred_weight_table(decoder, slice))
2440 static GstVaapiDecoderStatus
2441 decode_slice(GstVaapiDecoderH264 *decoder, GstH264NalUnit *nalu)
2443 GstVaapiDecoderH264Private * const priv = decoder->priv;
2444 GstVaapiDecoderStatus status;
2445 GstVaapiPictureH264 *picture;
2446 GstVaapiSliceH264 *slice = NULL;
2447 GstH264SliceHdr *slice_hdr;
2448 GstH264ParserResult result;
2450 GST_DEBUG("slice (%u bytes)", nalu->size);
2452 slice = gst_vaapi_slice_h264_new(
2454 nalu->data + nalu->offset,
2458 GST_ERROR("failed to allocate slice");
2459 return GST_VAAPI_DECODER_STATUS_ERROR_ALLOCATION_FAILED;
2462 slice_hdr = &slice->slice_hdr;
2463 memset(slice_hdr, 0, sizeof(*slice_hdr));
2464 result = gst_h264_parser_parse_slice_hdr(priv->parser, nalu, slice_hdr, TRUE, TRUE);
2465 if (result != GST_H264_PARSER_OK) {
2466 status = get_status(result);
2470 if (is_new_picture(decoder, nalu, slice_hdr)) {
2471 status = decode_picture(decoder, nalu, slice_hdr);
2472 if (status != GST_VAAPI_DECODER_STATUS_SUCCESS)
2475 picture = priv->current_picture;
2477 if (!fill_slice(decoder, slice, nalu)) {
2478 status = GST_VAAPI_DECODER_STATUS_ERROR_UNKNOWN;
2481 gst_vaapi_picture_add_slice(
2482 GST_VAAPI_PICTURE_CAST(picture),
2483 GST_VAAPI_SLICE_CAST(slice)
2485 return GST_VAAPI_DECODER_STATUS_SUCCESS;
2489 gst_mini_object_unref(GST_MINI_OBJECT(slice));
2494 scan_for_start_code(GstAdapter *adapter, guint ofs, guint size, guint32 *scp)
2496 return (gint)gst_adapter_masked_scan_uint32_peek(adapter,
2497 0xffffff00, 0x00000100,
2502 static GstVaapiDecoderStatus
2503 decode_nalu(GstVaapiDecoderH264 *decoder, GstH264NalUnit *nalu)
2505 GstVaapiDecoderStatus status;
2507 switch (nalu->type) {
2508 case GST_H264_NAL_SLICE_IDR:
2509 /* fall-through. IDR specifics are handled in init_picture() */
2510 case GST_H264_NAL_SLICE:
2511 status = decode_slice(decoder, nalu);
2513 case GST_H264_NAL_SPS:
2514 status = decode_sps(decoder, nalu);
2516 case GST_H264_NAL_PPS:
2517 status = decode_pps(decoder, nalu);
2519 case GST_H264_NAL_SEI:
2520 status = decode_sei(decoder, nalu);
2522 case GST_H264_NAL_SEQ_END:
2523 status = decode_sequence_end(decoder);
2525 case GST_H264_NAL_AU_DELIMITER:
2526 /* skip all Access Unit NALs */
2527 status = GST_VAAPI_DECODER_STATUS_SUCCESS;
2529 case GST_H264_NAL_FILLER_DATA:
2530 /* skip all Filler Data NALs */
2531 status = GST_VAAPI_DECODER_STATUS_SUCCESS;
2534 GST_WARNING("unsupported NAL unit type %d", nalu->type);
2535 status = GST_VAAPI_DECODER_STATUS_ERROR_BITSTREAM_PARSER;
2541 static GstVaapiDecoderStatus
2542 decode_buffer(GstVaapiDecoderH264 *decoder, GstBuffer *buffer)
2544 GstVaapiDecoderH264Private * const priv = decoder->priv;
2545 GstVaapiDecoderStatus status;
2546 GstH264ParserResult result;
2547 GstH264NalUnit nalu;
2550 guint i, buf_size, nalu_size, size;
2554 buf = GST_BUFFER_DATA(buffer);
2555 buf_size = GST_BUFFER_SIZE(buffer);
2556 is_eos = GST_BUFFER_IS_EOS(buffer);
2557 if (buf && buf_size > 0)
2558 gst_adapter_push(priv->adapter, gst_buffer_ref(buffer));
2560 size = gst_adapter_available(priv->adapter);
2563 status = GST_VAAPI_DECODER_STATUS_SUCCESS;
2567 status = gst_vaapi_decoder_check_status(GST_VAAPI_DECODER(decoder));
2568 if (status != GST_VAAPI_DECODER_STATUS_SUCCESS)
2571 status = GST_VAAPI_DECODER_STATUS_ERROR_NO_DATA;
2573 if (size < priv->nal_length_size)
2575 buf = gst_adapter_peek(priv->adapter, priv->nal_length_size);
2578 for (i = 0; i < priv->nal_length_size; i++)
2579 nalu_size = (nalu_size << 8) | buf[i];
2581 buf_size = priv->nal_length_size + nalu_size;
2582 if (size < buf_size)
2584 buffer = gst_adapter_take_buffer(priv->adapter, buf_size);
2587 buf = GST_BUFFER_DATA(buffer);
2588 buf_size = GST_BUFFER_SIZE(buffer);
2590 result = gst_h264_parser_identify_nalu_avc(
2592 buf, 0, buf_size, priv->nal_length_size,
2599 ofs = scan_for_start_code(priv->adapter, 0, size, &start_code);
2602 gst_adapter_flush(priv->adapter, ofs);
2605 ofs = G_UNLIKELY(size < 8) ? -1 :
2606 scan_for_start_code(priv->adapter, 4, size - 4, NULL);
2608 // Assume the whole NAL unit is present if end-of-stream
2613 buffer = gst_adapter_take_buffer(priv->adapter, ofs);
2616 buf = GST_BUFFER_DATA(buffer);
2617 buf_size = GST_BUFFER_SIZE(buffer);
2619 result = gst_h264_parser_identify_nalu_unchecked(
2625 status = get_status(result);
2626 if (status == GST_VAAPI_DECODER_STATUS_SUCCESS)
2627 status = decode_nalu(decoder, &nalu);
2628 gst_buffer_unref(buffer);
2629 } while (status == GST_VAAPI_DECODER_STATUS_SUCCESS);
2631 if (is_eos && (status == GST_VAAPI_DECODER_STATUS_SUCCESS ||
2632 status == GST_VAAPI_DECODER_STATUS_ERROR_NO_DATA))
2633 status = decode_sequence_end(decoder);
2637 static GstVaapiDecoderStatus
2638 decode_codec_data(GstVaapiDecoderH264 *decoder, GstBuffer *buffer)
2640 GstVaapiDecoderH264Private * const priv = decoder->priv;
2641 GstVaapiDecoderStatus status;
2642 GstH264NalUnit nalu;
2643 GstH264ParserResult result;
2646 guint i, ofs, num_sps, num_pps;
2648 buf = GST_BUFFER_DATA(buffer);
2649 buf_size = GST_BUFFER_SIZE(buffer);
2650 if (!buf || buf_size == 0)
2651 return GST_VAAPI_DECODER_STATUS_SUCCESS;
2654 return GST_VAAPI_DECODER_STATUS_ERROR_NO_DATA;
2657 GST_ERROR("failed to decode codec-data, not in avcC format");
2658 return GST_VAAPI_DECODER_STATUS_ERROR_BITSTREAM_PARSER;
2661 priv->nal_length_size = (buf[4] & 0x03) + 1;
2663 num_sps = buf[5] & 0x1f;
2666 for (i = 0; i < num_sps; i++) {
2667 result = gst_h264_parser_identify_nalu_avc(
2669 buf, ofs, buf_size, 2,
2672 if (result != GST_H264_PARSER_OK)
2673 return get_status(result);
2675 status = decode_sps(decoder, &nalu);
2676 if (status != GST_VAAPI_DECODER_STATUS_SUCCESS)
2678 ofs = nalu.offset + nalu.size;
2684 for (i = 0; i < num_pps; i++) {
2685 result = gst_h264_parser_identify_nalu_avc(
2687 buf, ofs, buf_size, 2,
2690 if (result != GST_H264_PARSER_OK)
2691 return get_status(result);
2693 status = decode_pps(decoder, &nalu);
2694 if (status != GST_VAAPI_DECODER_STATUS_SUCCESS)
2696 ofs = nalu.offset + nalu.size;
2699 priv->is_avc = TRUE;
2703 GstVaapiDecoderStatus
2704 gst_vaapi_decoder_h264_decode(GstVaapiDecoder *base, GstBuffer *buffer)
2706 GstVaapiDecoderH264 * const decoder = GST_VAAPI_DECODER_H264(base);
2707 GstVaapiDecoderH264Private * const priv = decoder->priv;
2708 GstVaapiDecoderStatus status;
2709 GstBuffer *codec_data;
2711 g_return_val_if_fail(priv->is_constructed,
2712 GST_VAAPI_DECODER_STATUS_ERROR_INIT_FAILED);
2714 if (!priv->is_opened) {
2715 priv->is_opened = gst_vaapi_decoder_h264_open(decoder, buffer);
2716 if (!priv->is_opened)
2717 return GST_VAAPI_DECODER_STATUS_ERROR_UNSUPPORTED_CODEC;
2719 codec_data = GST_VAAPI_DECODER_CODEC_DATA(decoder);
2721 status = decode_codec_data(decoder, codec_data);
2722 if (status != GST_VAAPI_DECODER_STATUS_SUCCESS)
2726 return decode_buffer(decoder, buffer);
2730 gst_vaapi_decoder_h264_finalize(GObject *object)
2732 GstVaapiDecoderH264 * const decoder = GST_VAAPI_DECODER_H264(object);
2734 gst_vaapi_decoder_h264_destroy(decoder);
2736 G_OBJECT_CLASS(gst_vaapi_decoder_h264_parent_class)->finalize(object);
2740 gst_vaapi_decoder_h264_constructed(GObject *object)
2742 GstVaapiDecoderH264 * const decoder = GST_VAAPI_DECODER_H264(object);
2743 GstVaapiDecoderH264Private * const priv = decoder->priv;
2744 GObjectClass *parent_class;
2746 parent_class = G_OBJECT_CLASS(gst_vaapi_decoder_h264_parent_class);
2747 if (parent_class->constructed)
2748 parent_class->constructed(object);
2750 priv->is_constructed = gst_vaapi_decoder_h264_create(decoder);
2754 gst_vaapi_decoder_h264_class_init(GstVaapiDecoderH264Class *klass)
2756 GObjectClass * const object_class = G_OBJECT_CLASS(klass);
2757 GstVaapiDecoderClass * const decoder_class = GST_VAAPI_DECODER_CLASS(klass);
2759 g_type_class_add_private(klass, sizeof(GstVaapiDecoderH264Private));
2761 object_class->finalize = gst_vaapi_decoder_h264_finalize;
2762 object_class->constructed = gst_vaapi_decoder_h264_constructed;
2764 decoder_class->decode = gst_vaapi_decoder_h264_decode;
2768 gst_vaapi_decoder_h264_init(GstVaapiDecoderH264 *decoder)
2770 GstVaapiDecoderH264Private *priv;
2772 priv = GST_VAAPI_DECODER_H264_GET_PRIVATE(decoder);
2773 decoder->priv = priv;
2774 priv->parser = NULL;
2775 priv->current_picture = NULL;
2776 priv->dpb_count = 0;
2778 priv->profile = GST_VAAPI_PROFILE_UNKNOWN;
2779 priv->entrypoint = GST_VAAPI_ENTRYPOINT_VLD;
2780 priv->chroma_type = GST_VAAPI_CHROMA_TYPE_YUV420;
2781 priv->short_ref_count = 0;
2782 priv->long_ref_count = 0;
2783 priv->RefPicList0_count = 0;
2784 priv->RefPicList1_count = 0;
2785 priv->nal_length_size = 0;
2788 priv->adapter = NULL;
2789 priv->field_poc[0] = 0;
2790 priv->field_poc[1] = 0;
2793 priv->prev_poc_msb = 0;
2794 priv->prev_poc_lsb = 0;
2795 priv->frame_num_offset = 0;
2796 priv->frame_num = 0;
2797 priv->prev_frame_num = 0;
2798 priv->prev_pic_has_mmco5 = FALSE;
2799 priv->prev_pic_structure = GST_VAAPI_PICTURE_STRUCTURE_FRAME;
2800 priv->is_constructed = FALSE;
2801 priv->is_opened = FALSE;
2802 priv->is_avc = FALSE;
2803 priv->has_context = FALSE;
2805 memset(priv->dpb, 0, sizeof(priv->dpb));
2806 memset(priv->short_ref, 0, sizeof(priv->short_ref));
2807 memset(priv->long_ref, 0, sizeof(priv->long_ref));
2808 memset(priv->RefPicList0, 0, sizeof(priv->RefPicList0));
2809 memset(priv->RefPicList1, 0, sizeof(priv->RefPicList1));
2813 * gst_vaapi_decoder_h264_new:
2814 * @display: a #GstVaapiDisplay
2815 * @caps: a #GstCaps holding codec information
2817 * Creates a new #GstVaapiDecoder for MPEG-2 decoding. The @caps can
2818 * hold extra information like codec-data and pictured coded size.
2820 * Return value: the newly allocated #GstVaapiDecoder object
2823 gst_vaapi_decoder_h264_new(GstVaapiDisplay *display, GstCaps *caps)
2825 GstVaapiDecoderH264 *decoder;
2827 g_return_val_if_fail(GST_VAAPI_IS_DISPLAY(display), NULL);
2828 g_return_val_if_fail(GST_IS_CAPS(caps), NULL);
2830 decoder = g_object_new(
2831 GST_VAAPI_TYPE_DECODER_H264,
2836 if (!decoder->priv->is_constructed) {
2837 g_object_unref(decoder);
2840 return GST_VAAPI_DECODER_CAST(decoder);