decoder: h264: fix long-term reference picture marking process.
[platform/upstream/gstreamer-vaapi.git] / gst-libs / gst / vaapi / gstvaapidecoder_h264.c
1 /*
2  *  gstvaapidecoder_h264.c - H.264 decoder
3  *
4  *  Copyright (C) 2011-2014 Intel Corporation
5  *    Author: Gwenole Beauchesne <gwenole.beauchesne@intel.com>
6  *
7  *  This library is free software; you can redistribute it and/or
8  *  modify it under the terms of the GNU Lesser General Public License
9  *  as published by the Free Software Foundation; either version 2.1
10  *  of the License, or (at your option) any later version.
11  *
12  *  This library is distributed in the hope that it will be useful,
13  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
14  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15  *  Lesser General Public License for more details.
16  *
17  *  You should have received a copy of the GNU Lesser General Public
18  *  License along with this library; if not, write to the Free
19  *  Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
20  *  Boston, MA 02110-1301 USA
21  */
22
23 /**
24  * SECTION:gstvaapidecoder_h264
25  * @short_description: H.264 decoder
26  */
27
28 #include "sysdeps.h"
29 #include <string.h>
30 #include <gst/base/gstadapter.h>
31 #include <gst/codecparsers/gsth264parser.h>
32 #include "gstvaapidecoder_h264.h"
33 #include "gstvaapidecoder_objects.h"
34 #include "gstvaapidecoder_priv.h"
35 #include "gstvaapidisplay_priv.h"
36 #include "gstvaapiobject_priv.h"
37 #include "gstvaapiutils_h264_priv.h"
38
39 #define DEBUG 1
40 #include "gstvaapidebug.h"
41
42 /* Defined to 1 if strict ordering of DPB is needed. Only useful for debug */
43 #define USE_STRICT_DPB_ORDERING 0
44
45 typedef struct _GstVaapiDecoderH264Private      GstVaapiDecoderH264Private;
46 typedef struct _GstVaapiDecoderH264Class        GstVaapiDecoderH264Class;
47 typedef struct _GstVaapiFrameStore              GstVaapiFrameStore;
48 typedef struct _GstVaapiFrameStoreClass         GstVaapiFrameStoreClass;
49 typedef struct _GstVaapiParserInfoH264          GstVaapiParserInfoH264;
50 typedef struct _GstVaapiPictureH264             GstVaapiPictureH264;
51
52 // Used for field_poc[]
53 #define TOP_FIELD       0
54 #define BOTTOM_FIELD    1
55
56 /* ------------------------------------------------------------------------- */
57 /* --- H.264 Parser Info                                                 --- */
58 /* ------------------------------------------------------------------------- */
59
60 #define GST_VAAPI_PARSER_INFO_H264(obj) \
61     ((GstVaapiParserInfoH264 *)(obj))
62
63 struct _GstVaapiParserInfoH264 {
64     GstVaapiMiniObject  parent_instance;
65     GstH264NalUnit      nalu;
66     union {
67         GstH264SPS      sps;
68         GstH264PPS      pps;
69         GArray         *sei;
70         GstH264SliceHdr slice_hdr;
71     }                   data;
72     guint               state;
73 };
74
75 static void
76 gst_vaapi_parser_info_h264_finalize(GstVaapiParserInfoH264 *pi)
77 {
78     switch (pi->nalu.type) {
79     case GST_H264_NAL_SEI:
80         if (pi->data.sei) {
81             g_array_unref(pi->data.sei);
82             pi->data.sei = NULL;
83         }
84         break;
85     }
86 }
87
88 static inline const GstVaapiMiniObjectClass *
89 gst_vaapi_parser_info_h264_class(void)
90 {
91     static const GstVaapiMiniObjectClass GstVaapiParserInfoH264Class = {
92         .size = sizeof(GstVaapiParserInfoH264),
93         .finalize = (GDestroyNotify)gst_vaapi_parser_info_h264_finalize
94     };
95     return &GstVaapiParserInfoH264Class;
96 }
97
98 static inline GstVaapiParserInfoH264 *
99 gst_vaapi_parser_info_h264_new(void)
100 {
101     return (GstVaapiParserInfoH264 *)
102         gst_vaapi_mini_object_new(gst_vaapi_parser_info_h264_class());
103 }
104
105 #define gst_vaapi_parser_info_h264_ref(pi) \
106     gst_vaapi_mini_object_ref(GST_VAAPI_MINI_OBJECT(pi))
107
108 #define gst_vaapi_parser_info_h264_unref(pi) \
109     gst_vaapi_mini_object_unref(GST_VAAPI_MINI_OBJECT(pi))
110
111 #define gst_vaapi_parser_info_h264_replace(old_pi_ptr, new_pi)          \
112     gst_vaapi_mini_object_replace((GstVaapiMiniObject **)(old_pi_ptr),  \
113         (GstVaapiMiniObject *)(new_pi))
114
115 /* ------------------------------------------------------------------------- */
116 /* --- H.264 Pictures                                                    --- */
117 /* ------------------------------------------------------------------------- */
118
119 /*
120  * Extended picture flags:
121  *
122  * @GST_VAAPI_PICTURE_FLAG_IDR: flag that specifies an IDR picture
123  * @GST_VAAPI_PICTURE_FLAG_SHORT_TERM_REFERENCE: flag that specifies
124  *     "used for short-term reference"
125  * @GST_VAAPI_PICTURE_FLAG_LONG_TERM_REFERENCE: flag that specifies
126  *     "used for long-term reference"
127  * @GST_VAAPI_PICTURE_FLAGS_REFERENCE: mask covering any kind of
128  *     reference picture (short-term reference or long-term reference)
129  */
130 enum {
131     GST_VAAPI_PICTURE_FLAG_IDR = (GST_VAAPI_PICTURE_FLAG_LAST << 0),
132
133     GST_VAAPI_PICTURE_FLAG_SHORT_TERM_REFERENCE = (
134         GST_VAAPI_PICTURE_FLAG_REFERENCE),
135     GST_VAAPI_PICTURE_FLAG_LONG_TERM_REFERENCE = (
136         GST_VAAPI_PICTURE_FLAG_REFERENCE | (GST_VAAPI_PICTURE_FLAG_LAST << 1)),
137     GST_VAAPI_PICTURE_FLAGS_REFERENCE = (
138         GST_VAAPI_PICTURE_FLAG_SHORT_TERM_REFERENCE |
139         GST_VAAPI_PICTURE_FLAG_LONG_TERM_REFERENCE),
140 };
141
142 #define GST_VAAPI_PICTURE_IS_IDR(picture) \
143     (GST_VAAPI_PICTURE_FLAG_IS_SET(picture, GST_VAAPI_PICTURE_FLAG_IDR))
144
145 #define GST_VAAPI_PICTURE_IS_SHORT_TERM_REFERENCE(picture)      \
146     ((GST_VAAPI_PICTURE_FLAGS(picture) &                        \
147       GST_VAAPI_PICTURE_FLAGS_REFERENCE) ==                     \
148      GST_VAAPI_PICTURE_FLAG_SHORT_TERM_REFERENCE)
149
150 #define GST_VAAPI_PICTURE_IS_LONG_TERM_REFERENCE(picture)       \
151     ((GST_VAAPI_PICTURE_FLAGS(picture) &                        \
152       GST_VAAPI_PICTURE_FLAGS_REFERENCE) ==                     \
153      GST_VAAPI_PICTURE_FLAG_LONG_TERM_REFERENCE)
154
155 struct _GstVaapiPictureH264 {
156     GstVaapiPicture             base;
157     GstH264SliceHdr            *last_slice_hdr;
158     guint                       structure;
159     gint32                      field_poc[2];
160     gint32                      frame_num;              // Original frame_num from slice_header()
161     gint32                      frame_num_wrap;         // Temporary for ref pic marking: FrameNumWrap
162     gint32                      long_term_frame_idx;    // Temporary for ref pic marking: LongTermFrameIdx
163     gint32                      pic_num;                // Temporary for ref pic marking: PicNum
164     gint32                      long_term_pic_num;      // Temporary for ref pic marking: LongTermPicNum
165     GstVaapiPictureH264        *other_field;            // Temporary for ref pic marking: other field in the same frame store
166     guint                       output_flag             : 1;
167     guint                       output_needed           : 1;
168 };
169
170 GST_VAAPI_CODEC_DEFINE_TYPE(GstVaapiPictureH264, gst_vaapi_picture_h264);
171
172 void
173 gst_vaapi_picture_h264_destroy(GstVaapiPictureH264 *picture)
174 {
175     gst_vaapi_picture_destroy(GST_VAAPI_PICTURE(picture));
176 }
177
178 gboolean
179 gst_vaapi_picture_h264_create(
180     GstVaapiPictureH264                      *picture,
181     const GstVaapiCodecObjectConstructorArgs *args
182 )
183 {
184     if (!gst_vaapi_picture_create(GST_VAAPI_PICTURE(picture), args))
185         return FALSE;
186
187     picture->field_poc[0]       = G_MAXINT32;
188     picture->field_poc[1]       = G_MAXINT32;
189     picture->output_needed      = FALSE;
190     return TRUE;
191 }
192
193 static inline GstVaapiPictureH264 *
194 gst_vaapi_picture_h264_new(GstVaapiDecoderH264 *decoder)
195 {
196     return (GstVaapiPictureH264 *)gst_vaapi_codec_object_new(
197         &GstVaapiPictureH264Class,
198         GST_VAAPI_CODEC_BASE(decoder),
199         NULL, sizeof(VAPictureParameterBufferH264),
200         NULL, 0,
201         0);
202 }
203
204 static inline void
205 gst_vaapi_picture_h264_set_reference(
206     GstVaapiPictureH264 *picture,
207     guint                reference_flags,
208     gboolean             other_field
209 )
210 {
211     if (!picture)
212         return;
213     GST_VAAPI_PICTURE_FLAG_UNSET(picture, GST_VAAPI_PICTURE_FLAGS_REFERENCE);
214     GST_VAAPI_PICTURE_FLAG_SET(picture, reference_flags);
215
216     if (!other_field || !(picture = picture->other_field))
217         return;
218     GST_VAAPI_PICTURE_FLAG_UNSET(picture, GST_VAAPI_PICTURE_FLAGS_REFERENCE);
219     GST_VAAPI_PICTURE_FLAG_SET(picture, reference_flags);
220 }
221
222 static inline GstVaapiPictureH264 *
223 gst_vaapi_picture_h264_new_field(GstVaapiPictureH264 *picture)
224 {
225     g_return_val_if_fail(picture, NULL);
226
227     return (GstVaapiPictureH264 *)gst_vaapi_picture_new_field(&picture->base);
228 }
229
230 /* ------------------------------------------------------------------------- */
231 /* --- Frame Buffers (DPB)                                               --- */
232 /* ------------------------------------------------------------------------- */
233
234 struct _GstVaapiFrameStore {
235     /*< private >*/
236     GstVaapiMiniObject          parent_instance;
237
238     guint                       structure;
239     GstVaapiPictureH264        *buffers[2];
240     guint                       num_buffers;
241     guint                       output_needed;
242 };
243
244 static void
245 gst_vaapi_frame_store_finalize(gpointer object)
246 {
247     GstVaapiFrameStore * const fs = object;
248     guint i;
249
250     for (i = 0; i < fs->num_buffers; i++)
251         gst_vaapi_picture_replace(&fs->buffers[i], NULL);
252 }
253
254 static GstVaapiFrameStore *
255 gst_vaapi_frame_store_new(GstVaapiPictureH264 *picture)
256 {
257     GstVaapiFrameStore *fs;
258
259     static const GstVaapiMiniObjectClass GstVaapiFrameStoreClass = {
260         sizeof(GstVaapiFrameStore),
261         gst_vaapi_frame_store_finalize
262     };
263
264     fs = (GstVaapiFrameStore *)
265         gst_vaapi_mini_object_new(&GstVaapiFrameStoreClass);
266     if (!fs)
267         return NULL;
268
269     fs->structure       = picture->structure;
270     fs->buffers[0]      = gst_vaapi_picture_ref(picture);
271     fs->buffers[1]      = NULL;
272     fs->num_buffers     = 1;
273     fs->output_needed   = picture->output_needed;
274     return fs;
275 }
276
277 static gboolean
278 gst_vaapi_frame_store_add(GstVaapiFrameStore *fs, GstVaapiPictureH264 *picture)
279 {
280     guint field;
281
282     g_return_val_if_fail(fs->num_buffers == 1, FALSE);
283     g_return_val_if_fail(!GST_VAAPI_PICTURE_IS_FRAME(picture), FALSE);
284     g_return_val_if_fail(!GST_VAAPI_PICTURE_IS_FIRST_FIELD(picture), FALSE);
285
286     gst_vaapi_picture_replace(&fs->buffers[fs->num_buffers++], picture);
287     if (picture->output_flag) {
288         picture->output_needed = TRUE;
289         fs->output_needed++;
290     }
291
292     fs->structure = GST_VAAPI_PICTURE_STRUCTURE_FRAME;
293
294     field = picture->structure == GST_VAAPI_PICTURE_STRUCTURE_TOP_FIELD ?
295         TOP_FIELD : BOTTOM_FIELD;
296     g_return_val_if_fail(fs->buffers[0]->field_poc[field] == G_MAXINT32, FALSE);
297     fs->buffers[0]->field_poc[field] = picture->field_poc[field];
298     g_return_val_if_fail(picture->field_poc[!field] == G_MAXINT32, FALSE);
299     picture->field_poc[!field] = fs->buffers[0]->field_poc[!field];
300     return TRUE;
301 }
302
303 static gboolean
304 gst_vaapi_frame_store_split_fields(GstVaapiFrameStore *fs)
305 {
306     GstVaapiPictureH264 * const first_field = fs->buffers[0];
307     GstVaapiPictureH264 *second_field;
308
309     g_return_val_if_fail(fs->num_buffers == 1, FALSE);
310
311     first_field->base.structure = GST_VAAPI_PICTURE_STRUCTURE_TOP_FIELD;
312     GST_VAAPI_PICTURE_FLAG_SET(first_field, GST_VAAPI_PICTURE_FLAG_INTERLACED);
313
314     second_field = gst_vaapi_picture_h264_new_field(first_field);
315     if (!second_field)
316         return FALSE;
317     gst_vaapi_picture_replace(&fs->buffers[fs->num_buffers++], second_field);
318     gst_vaapi_picture_unref(second_field);
319
320     second_field->frame_num    = first_field->frame_num;
321     second_field->field_poc[0] = first_field->field_poc[0];
322     second_field->field_poc[1] = first_field->field_poc[1];
323     second_field->output_flag  = first_field->output_flag;
324     if (second_field->output_flag) {
325         second_field->output_needed = TRUE;
326         fs->output_needed++;
327     }
328     return TRUE;
329 }
330
331 static inline gboolean
332 gst_vaapi_frame_store_has_frame(GstVaapiFrameStore *fs)
333 {
334     return fs->structure == GST_VAAPI_PICTURE_STRUCTURE_FRAME;
335 }
336
337 static inline gboolean
338 gst_vaapi_frame_store_has_reference(GstVaapiFrameStore *fs)
339 {
340     guint i;
341
342     for (i = 0; i < fs->num_buffers; i++) {
343         if (GST_VAAPI_PICTURE_IS_REFERENCE(fs->buffers[i]))
344             return TRUE;
345     }
346     return FALSE;
347 }
348
349 #define gst_vaapi_frame_store_ref(fs) \
350     gst_vaapi_mini_object_ref(GST_VAAPI_MINI_OBJECT(fs))
351
352 #define gst_vaapi_frame_store_unref(fs) \
353     gst_vaapi_mini_object_unref(GST_VAAPI_MINI_OBJECT(fs))
354
355 #define gst_vaapi_frame_store_replace(old_fs_p, new_fs)                 \
356     gst_vaapi_mini_object_replace((GstVaapiMiniObject **)(old_fs_p),    \
357         (GstVaapiMiniObject *)(new_fs))
358
359 /* ------------------------------------------------------------------------- */
360 /* --- H.264 Decoder                                                     --- */
361 /* ------------------------------------------------------------------------- */
362
363 #define GST_VAAPI_DECODER_H264_CAST(decoder) \
364     ((GstVaapiDecoderH264 *)(decoder))
365
366 typedef enum {
367     GST_H264_VIDEO_STATE_GOT_SPS        = 1 << 0,
368     GST_H264_VIDEO_STATE_GOT_PPS        = 1 << 1,
369     GST_H264_VIDEO_STATE_GOT_SLICE      = 1 << 2,
370
371     GST_H264_VIDEO_STATE_VALID_PICTURE_HEADERS = (
372         GST_H264_VIDEO_STATE_GOT_SPS |
373         GST_H264_VIDEO_STATE_GOT_PPS),
374     GST_H264_VIDEO_STATE_VALID_PICTURE = (
375         GST_H264_VIDEO_STATE_VALID_PICTURE_HEADERS |
376         GST_H264_VIDEO_STATE_GOT_SLICE)
377 } GstH264VideoState;
378
379 struct _GstVaapiDecoderH264Private {
380     GstH264NalParser           *parser;
381     guint                       parser_state;
382     guint                       decoder_state;
383     GstVaapiPictureH264        *current_picture;
384     GstVaapiParserInfoH264     *sps[GST_H264_MAX_SPS_COUNT];
385     GstVaapiParserInfoH264     *active_sps;
386     GstVaapiParserInfoH264     *pps[GST_H264_MAX_PPS_COUNT];
387     GstVaapiParserInfoH264     *active_pps;
388     GstVaapiParserInfoH264     *prev_slice_pi;
389     GstVaapiFrameStore         *prev_frame;
390     GstVaapiFrameStore         *dpb[16];
391     guint                       dpb_count;
392     guint                       dpb_size;
393     GstVaapiProfile             profile;
394     GstVaapiEntrypoint          entrypoint;
395     GstVaapiChromaType          chroma_type;
396     GstVaapiPictureH264        *short_ref[32];
397     guint                       short_ref_count;
398     GstVaapiPictureH264        *long_ref[32];
399     guint                       long_ref_count;
400     GstVaapiPictureH264        *RefPicList0[32];
401     guint                       RefPicList0_count;
402     GstVaapiPictureH264        *RefPicList1[32];
403     guint                       RefPicList1_count;
404     guint                       nal_length_size;
405     guint                       mb_width;
406     guint                       mb_height;
407     gint32                      field_poc[2];           // 0:TopFieldOrderCnt / 1:BottomFieldOrderCnt
408     gint32                      poc_msb;                // PicOrderCntMsb
409     gint32                      poc_lsb;                // pic_order_cnt_lsb (from slice_header())
410     gint32                      prev_poc_msb;           // prevPicOrderCntMsb
411     gint32                      prev_poc_lsb;           // prevPicOrderCntLsb
412     gint32                      frame_num_offset;       // FrameNumOffset
413     gint32                      frame_num;              // frame_num (from slice_header())
414     gint32                      prev_frame_num;         // prevFrameNum
415     gboolean                    prev_pic_has_mmco5;     // prevMmco5Pic
416     gboolean                    prev_pic_structure;     // previous picture structure
417     guint                       is_opened               : 1;
418     guint                       is_avcC                 : 1;
419     guint                       has_context             : 1;
420     guint                       progressive_sequence    : 1;
421 };
422
423 /**
424  * GstVaapiDecoderH264:
425  *
426  * A decoder based on H264.
427  */
428 struct _GstVaapiDecoderH264 {
429     /*< private >*/
430     GstVaapiDecoder             parent_instance;
431     GstVaapiDecoderH264Private  priv;
432 };
433
434 /**
435  * GstVaapiDecoderH264Class:
436  *
437  * A decoder class based on H264.
438  */
439 struct _GstVaapiDecoderH264Class {
440     /*< private >*/
441     GstVaapiDecoderClass parent_class;
442 };
443
444 static gboolean
445 exec_ref_pic_marking(GstVaapiDecoderH264 *decoder, GstVaapiPictureH264 *picture);
446
447 /* Get number of reference frames to use */
448 static guint
449 get_max_dec_frame_buffering(GstH264SPS *sps)
450 {
451     guint max_dec_frame_buffering, PicSizeMbs;
452     GstVaapiLevelH264 level;
453     const GstVaapiH264LevelLimits *level_limits;
454
455     /* Table A-1 - Level limits */
456     if (G_UNLIKELY(sps->level_idc == 11 && sps->constraint_set3_flag))
457         level = GST_VAAPI_LEVEL_H264_L1b;
458     else
459         level = gst_vaapi_utils_h264_get_level(sps->level_idc);
460     level_limits = gst_vaapi_utils_h264_get_level_limits(level);
461     if (!level_limits)
462         return 16;
463
464     PicSizeMbs = ((sps->pic_width_in_mbs_minus1 + 1) *
465                   (sps->pic_height_in_map_units_minus1 + 1) *
466                   (sps->frame_mbs_only_flag ? 1 : 2));
467     max_dec_frame_buffering = level_limits->MaxDpbMbs / PicSizeMbs;
468
469     /* VUI parameters */
470     if (sps->vui_parameters_present_flag) {
471         GstH264VUIParams * const vui_params = &sps->vui_parameters;
472         if (vui_params->bitstream_restriction_flag)
473             max_dec_frame_buffering = vui_params->max_dec_frame_buffering;
474         else {
475             switch (sps->profile_idc) {
476             case 44:  // CAVLC 4:4:4 Intra profile
477             case GST_H264_PROFILE_SCALABLE_HIGH:
478             case GST_H264_PROFILE_HIGH:
479             case GST_H264_PROFILE_HIGH10:
480             case GST_H264_PROFILE_HIGH_422:
481             case GST_H264_PROFILE_HIGH_444:
482                 if (sps->constraint_set3_flag)
483                     max_dec_frame_buffering = 0;
484                 break;
485             }
486         }
487     }
488
489     if (max_dec_frame_buffering > 16)
490         max_dec_frame_buffering = 16;
491     else if (max_dec_frame_buffering < sps->num_ref_frames)
492         max_dec_frame_buffering = sps->num_ref_frames;
493     return MAX(1, max_dec_frame_buffering);
494 }
495
496 static void
497 array_remove_index_fast(void *array, guint *array_length_ptr, guint index)
498 {
499     gpointer * const entries = array;
500     guint num_entries = *array_length_ptr;
501
502     g_return_if_fail(index < num_entries);
503
504     if (index != --num_entries)
505         entries[index] = entries[num_entries];
506     entries[num_entries] = NULL;
507     *array_length_ptr = num_entries;
508 }
509
510 #if 1
511 static inline void
512 array_remove_index(void *array, guint *array_length_ptr, guint index)
513 {
514     array_remove_index_fast(array, array_length_ptr, index);
515 }
516 #else
517 static void
518 array_remove_index(void *array, guint *array_length_ptr, guint index)
519 {
520     gpointer * const entries = array;
521     const guint num_entries = *array_length_ptr - 1;
522     guint i;
523
524     g_return_if_fail(index <= num_entries);
525
526     for (i = index; i < num_entries; i++)
527         entries[i] = entries[i + 1];
528     entries[num_entries] = NULL;
529     *array_length_ptr = num_entries;
530 }
531 #endif
532
533 #define ARRAY_REMOVE_INDEX(array, index) \
534     array_remove_index(array, &array##_count, index)
535
536 static void
537 dpb_remove_index(GstVaapiDecoderH264 *decoder, guint index)
538 {
539     GstVaapiDecoderH264Private * const priv = &decoder->priv;
540     guint i, num_frames = --priv->dpb_count;
541
542     if (USE_STRICT_DPB_ORDERING) {
543         for (i = index; i < num_frames; i++)
544             gst_vaapi_frame_store_replace(&priv->dpb[i], priv->dpb[i + 1]);
545     }
546     else if (index != num_frames)
547         gst_vaapi_frame_store_replace(&priv->dpb[index], priv->dpb[num_frames]);
548     gst_vaapi_frame_store_replace(&priv->dpb[num_frames], NULL);
549 }
550
551 static gboolean
552 dpb_output(
553     GstVaapiDecoderH264 *decoder,
554     GstVaapiFrameStore  *fs,
555     GstVaapiPictureH264 *picture
556 )
557 {
558     picture->output_needed = FALSE;
559
560     if (fs) {
561         if (--fs->output_needed > 0)
562             return TRUE;
563         picture = fs->buffers[0];
564     }
565     return gst_vaapi_picture_output(GST_VAAPI_PICTURE_CAST(picture));
566 }
567
568 static inline void
569 dpb_evict(GstVaapiDecoderH264 *decoder, GstVaapiPictureH264 *picture, guint i)
570 {
571     GstVaapiDecoderH264Private * const priv = &decoder->priv;
572     GstVaapiFrameStore * const fs = priv->dpb[i];
573
574     if (!fs->output_needed && !gst_vaapi_frame_store_has_reference(fs))
575         dpb_remove_index(decoder, i);
576 }
577
578 static gboolean
579 dpb_bump(GstVaapiDecoderH264 *decoder)
580 {
581     GstVaapiDecoderH264Private * const priv = &decoder->priv;
582     GstVaapiPictureH264 *found_picture = NULL;
583     guint i, j, found_index;
584     gboolean success;
585
586     for (i = 0; i < priv->dpb_count; i++) {
587         GstVaapiFrameStore * const fs = priv->dpb[i];
588         if (!fs->output_needed)
589             continue;
590         for (j = 0; j < fs->num_buffers; j++) {
591             GstVaapiPictureH264 * const picture = fs->buffers[j];
592             if (!picture->output_needed)
593                 continue;
594             if (!found_picture || found_picture->base.poc > picture->base.poc)
595                 found_picture = picture, found_index = i;
596         }
597     }
598     if (!found_picture)
599         return FALSE;
600
601     success = dpb_output(decoder, priv->dpb[found_index], found_picture);
602     dpb_evict(decoder, found_picture, found_index);
603     return success;
604 }
605
606 static void
607 dpb_clear(GstVaapiDecoderH264 *decoder)
608 {
609     GstVaapiDecoderH264Private * const priv = &decoder->priv;
610     guint i;
611
612     for (i = 0; i < priv->dpb_count; i++)
613         gst_vaapi_frame_store_replace(&priv->dpb[i], NULL);
614     priv->dpb_count = 0;
615
616     gst_vaapi_frame_store_replace(&priv->prev_frame, NULL);
617 }
618
619 static void
620 dpb_flush(GstVaapiDecoderH264 *decoder)
621 {
622     while (dpb_bump(decoder))
623         ;
624     dpb_clear(decoder);
625 }
626
627 static gboolean
628 dpb_add(GstVaapiDecoderH264 *decoder, GstVaapiPictureH264 *picture)
629 {
630     GstVaapiDecoderH264Private * const priv = &decoder->priv;
631     GstVaapiFrameStore *fs;
632     guint i, j;
633
634     // Remove all unused pictures
635     if (!GST_VAAPI_PICTURE_IS_IDR(picture)) {
636         i = 0;
637         while (i < priv->dpb_count) {
638             GstVaapiFrameStore * const fs = priv->dpb[i];
639             if (!fs->output_needed && !gst_vaapi_frame_store_has_reference(fs))
640                 dpb_remove_index(decoder, i);
641             else
642                 i++;
643         }
644     }
645
646     // Check if picture is the second field and the first field is still in DPB
647     fs = priv->prev_frame;
648     if (fs && !gst_vaapi_frame_store_has_frame(fs))
649         return gst_vaapi_frame_store_add(fs, picture);
650
651     // Create new frame store, and split fields if necessary
652     fs = gst_vaapi_frame_store_new(picture);
653     if (!fs)
654         return FALSE;
655     gst_vaapi_frame_store_replace(&priv->prev_frame, fs);
656     gst_vaapi_frame_store_unref(fs);
657
658     if (!priv->progressive_sequence && gst_vaapi_frame_store_has_frame(fs)) {
659         if (!gst_vaapi_frame_store_split_fields(fs))
660             return FALSE;
661     }
662
663     // C.4.5.1 - Storage and marking of a reference decoded picture into the DPB
664     if (GST_VAAPI_PICTURE_IS_REFERENCE(picture)) {
665         while (priv->dpb_count == priv->dpb_size) {
666             if (!dpb_bump(decoder))
667                 return FALSE;
668         }
669         gst_vaapi_frame_store_replace(&priv->dpb[priv->dpb_count++], fs);
670         if (picture->output_flag) {
671             picture->output_needed = TRUE;
672             fs->output_needed++;
673         }
674     }
675
676     // C.4.5.2 - Storage and marking of a non-reference decoded picture into the DPB
677     else {
678         if (!picture->output_flag)
679             return TRUE;
680         while (priv->dpb_count == priv->dpb_size) {
681             gboolean found_picture = FALSE;
682             for (i = 0; !found_picture && i < priv->dpb_count; i++) {
683                 GstVaapiFrameStore * const fs = priv->dpb[i];
684                 if (!fs->output_needed)
685                     continue;
686                 for (j = 0; !found_picture && j < fs->num_buffers; j++)
687                     found_picture = fs->buffers[j]->output_needed &&
688                         fs->buffers[j]->base.poc < picture->base.poc;
689             }
690             if (!found_picture)
691                 return dpb_output(decoder, NULL, picture);
692             if (!dpb_bump(decoder))
693                 return FALSE;
694         }
695         gst_vaapi_frame_store_replace(&priv->dpb[priv->dpb_count++], fs);
696         picture->output_needed = TRUE;
697         fs->output_needed++;
698     }
699     return TRUE;
700 }
701
702 static inline void
703 dpb_reset(GstVaapiDecoderH264 *decoder, GstH264SPS *sps)
704 {
705     GstVaapiDecoderH264Private * const priv = &decoder->priv;
706
707     priv->dpb_size = get_max_dec_frame_buffering(sps);
708     GST_DEBUG("DPB size %u", priv->dpb_size);
709 }
710
711 static GstVaapiDecoderStatus
712 get_status(GstH264ParserResult result)
713 {
714     GstVaapiDecoderStatus status;
715
716     switch (result) {
717     case GST_H264_PARSER_OK:
718         status = GST_VAAPI_DECODER_STATUS_SUCCESS;
719         break;
720     case GST_H264_PARSER_NO_NAL_END:
721         status = GST_VAAPI_DECODER_STATUS_ERROR_NO_DATA;
722         break;
723     case GST_H264_PARSER_ERROR:
724         status = GST_VAAPI_DECODER_STATUS_ERROR_BITSTREAM_PARSER;
725         break;
726     default:
727         status = GST_VAAPI_DECODER_STATUS_ERROR_UNKNOWN;
728         break;
729     }
730     return status;
731 }
732
733 static void
734 gst_vaapi_decoder_h264_close(GstVaapiDecoderH264 *decoder)
735 {
736     GstVaapiDecoderH264Private * const priv = &decoder->priv;
737
738     gst_vaapi_picture_replace(&priv->current_picture, NULL);
739     gst_vaapi_parser_info_h264_replace(&priv->prev_slice_pi, NULL);
740
741     dpb_clear(decoder);
742
743     if (priv->parser) {
744         gst_h264_nal_parser_free(priv->parser);
745         priv->parser = NULL;
746     }
747 }
748
749 static gboolean
750 gst_vaapi_decoder_h264_open(GstVaapiDecoderH264 *decoder)
751 {
752     GstVaapiDecoderH264Private * const priv = &decoder->priv;
753
754     gst_vaapi_decoder_h264_close(decoder);
755
756     priv->parser = gst_h264_nal_parser_new();
757     if (!priv->parser)
758         return FALSE;
759     return TRUE;
760 }
761
762 static void
763 gst_vaapi_decoder_h264_destroy(GstVaapiDecoder *base_decoder)
764 {
765     GstVaapiDecoderH264 * const decoder =
766         GST_VAAPI_DECODER_H264_CAST(base_decoder);
767     GstVaapiDecoderH264Private * const priv = &decoder->priv;
768     guint i;
769
770     gst_vaapi_decoder_h264_close(decoder);
771
772     for (i = 0; i < G_N_ELEMENTS(priv->pps); i++)
773         gst_vaapi_parser_info_h264_replace(&priv->pps[i], NULL);
774     gst_vaapi_parser_info_h264_replace(&priv->active_pps, NULL);
775
776     for (i = 0; i < G_N_ELEMENTS(priv->sps); i++)
777         gst_vaapi_parser_info_h264_replace(&priv->sps[i], NULL);
778     gst_vaapi_parser_info_h264_replace(&priv->active_sps, NULL);
779 }
780
781 static gboolean
782 gst_vaapi_decoder_h264_create(GstVaapiDecoder *base_decoder)
783 {
784     GstVaapiDecoderH264 * const decoder =
785         GST_VAAPI_DECODER_H264_CAST(base_decoder);
786     GstVaapiDecoderH264Private * const priv = &decoder->priv;
787
788     priv->profile               = GST_VAAPI_PROFILE_UNKNOWN;
789     priv->entrypoint            = GST_VAAPI_ENTRYPOINT_VLD;
790     priv->chroma_type           = GST_VAAPI_CHROMA_TYPE_YUV420;
791     priv->prev_pic_structure    = GST_VAAPI_PICTURE_STRUCTURE_FRAME;
792     priv->progressive_sequence  = TRUE;
793     return TRUE;
794 }
795
796 /* Activates the supplied PPS */
797 static GstH264PPS *
798 ensure_pps(GstVaapiDecoderH264 *decoder, GstH264PPS *pps)
799 {
800     GstVaapiDecoderH264Private * const priv = &decoder->priv;
801     GstVaapiParserInfoH264 * const pi = priv->pps[pps->id];
802
803     gst_vaapi_parser_info_h264_replace(&priv->active_pps, pi);
804     return pi ? &pi->data.pps : NULL;
805 }
806
807 /* Returns the active PPS */
808 static inline GstH264PPS *
809 get_pps(GstVaapiDecoderH264 *decoder)
810 {
811     GstVaapiParserInfoH264 * const pi = decoder->priv.active_pps;
812
813     return pi ? &pi->data.pps : NULL;
814 }
815
816 /* Activate the supplied SPS */
817 static GstH264SPS *
818 ensure_sps(GstVaapiDecoderH264 *decoder, GstH264SPS *sps)
819 {
820     GstVaapiDecoderH264Private * const priv = &decoder->priv;
821     GstVaapiParserInfoH264 * const pi = priv->sps[sps->id];
822
823     gst_vaapi_parser_info_h264_replace(&priv->active_sps, pi);
824     return pi ? &pi->data.sps : NULL;
825 }
826
827 /* Returns the active SPS */
828 static inline GstH264SPS *
829 get_sps(GstVaapiDecoderH264 *decoder)
830 {
831     GstVaapiParserInfoH264 * const pi = decoder->priv.active_sps;
832
833     return pi ? &pi->data.sps : NULL;
834 }
835
836 static void
837 fill_profiles(GstVaapiProfile profiles[16], guint *n_profiles_ptr,
838     GstVaapiProfile profile)
839 {
840     guint n_profiles = *n_profiles_ptr;
841
842     profiles[n_profiles++] = profile;
843     switch (profile) {
844     case GST_VAAPI_PROFILE_H264_MAIN:
845         profiles[n_profiles++] = GST_VAAPI_PROFILE_H264_HIGH;
846         break;
847     default:
848         break;
849     }
850     *n_profiles_ptr = n_profiles;
851 }
852
853 static GstVaapiProfile
854 get_profile(GstVaapiDecoderH264 *decoder, GstH264SPS *sps)
855 {
856     GstVaapiDecoderH264Private * const priv = &decoder->priv;
857     GstVaapiDisplay * const display = GST_VAAPI_DECODER_DISPLAY(decoder);
858     GstVaapiProfile profile, profiles[4];
859     guint i, n_profiles = 0;
860
861     profile = gst_vaapi_utils_h264_get_profile(sps->profile_idc);
862     if (!profile)
863         return GST_VAAPI_PROFILE_UNKNOWN;
864
865     fill_profiles(profiles, &n_profiles, profile);
866     switch (profile) {
867     case GST_VAAPI_PROFILE_H264_BASELINE:
868         if (sps->constraint_set1_flag) { // A.2.2 (main profile)
869             fill_profiles(profiles, &n_profiles,
870                 GST_VAAPI_PROFILE_H264_CONSTRAINED_BASELINE);
871             fill_profiles(profiles, &n_profiles,
872                 GST_VAAPI_PROFILE_H264_MAIN);
873         }
874         break;
875     case GST_VAAPI_PROFILE_H264_EXTENDED:
876         if (sps->constraint_set1_flag) { // A.2.2 (main profile)
877             fill_profiles(profiles, &n_profiles,
878                 GST_VAAPI_PROFILE_H264_MAIN);
879         }
880         break;
881     default:
882         break;
883     }
884
885     /* If the preferred profile (profiles[0]) matches one that we already
886        found, then just return it now instead of searching for it again */
887     if (profiles[0] == priv->profile)
888         return priv->profile;
889
890     for (i = 0; i < n_profiles; i++) {
891         if (gst_vaapi_display_has_decoder(display, profiles[i], priv->entrypoint))
892             return profiles[i];
893     }
894     return GST_VAAPI_PROFILE_UNKNOWN;
895 }
896
897 static GstVaapiDecoderStatus
898 ensure_context(GstVaapiDecoderH264 *decoder, GstH264SPS *sps)
899 {
900     GstVaapiDecoder * const base_decoder = GST_VAAPI_DECODER_CAST(decoder);
901     GstVaapiDecoderH264Private * const priv = &decoder->priv;
902     GstVaapiContextInfo info;
903     GstVaapiProfile profile;
904     GstVaapiChromaType chroma_type;
905     gboolean reset_context = FALSE;
906     guint mb_width, mb_height;
907
908     profile = get_profile(decoder, sps);
909     if (!profile) {
910         GST_ERROR("unsupported profile_idc %u", sps->profile_idc);
911         return GST_VAAPI_DECODER_STATUS_ERROR_UNSUPPORTED_PROFILE;
912     }
913
914     if (priv->profile != profile) {
915         GST_DEBUG("profile changed");
916         reset_context = TRUE;
917         priv->profile = profile;
918     }
919
920     chroma_type = gst_vaapi_utils_h264_get_chroma_type(sps->chroma_format_idc);
921     if (!chroma_type) {
922         GST_ERROR("unsupported chroma_format_idc %u", sps->chroma_format_idc);
923         return GST_VAAPI_DECODER_STATUS_ERROR_UNSUPPORTED_CHROMA_FORMAT;
924     }
925
926     if (priv->chroma_type != chroma_type) {
927         GST_DEBUG("chroma format changed");
928         reset_context     = TRUE;
929         priv->chroma_type = chroma_type;
930     }
931
932     mb_width  = sps->pic_width_in_mbs_minus1 + 1;
933     mb_height = (sps->pic_height_in_map_units_minus1 + 1) <<
934         !sps->frame_mbs_only_flag;
935     if (priv->mb_width != mb_width || priv->mb_height != mb_height) {
936         GST_DEBUG("size changed");
937         reset_context   = TRUE;
938         priv->mb_width  = mb_width;
939         priv->mb_height = mb_height;
940     }
941
942     priv->progressive_sequence = sps->frame_mbs_only_flag;
943 #if 0
944     /* XXX: we only output complete frames for now */
945     gst_vaapi_decoder_set_interlaced(base_decoder, !priv->progressive_sequence);
946 #endif
947
948     gst_vaapi_decoder_set_pixel_aspect_ratio(
949         base_decoder,
950         sps->vui_parameters.par_n,
951         sps->vui_parameters.par_d
952     );
953
954     if (!reset_context && priv->has_context)
955         return GST_VAAPI_DECODER_STATUS_SUCCESS;
956
957     /* XXX: fix surface size when cropping is implemented */
958     info.profile    = priv->profile;
959     info.entrypoint = priv->entrypoint;
960     info.chroma_type = GST_VAAPI_CHROMA_TYPE_YUV420;
961     info.width      = sps->width;
962     info.height     = sps->height;
963     info.ref_frames = get_max_dec_frame_buffering(sps);
964
965     if (!gst_vaapi_decoder_ensure_context(GST_VAAPI_DECODER(decoder), &info))
966         return GST_VAAPI_DECODER_STATUS_ERROR_UNKNOWN;
967     priv->has_context = TRUE;
968
969     /* Reset DPB */
970     dpb_reset(decoder, sps);
971     return GST_VAAPI_DECODER_STATUS_SUCCESS;
972 }
973
974 static void
975 fill_iq_matrix_4x4(VAIQMatrixBufferH264 *iq_matrix, const GstH264PPS *pps,
976     const GstH264SPS *sps)
977 {
978     guint i;
979
980     /* There are always 6 4x4 scaling lists */
981     g_assert(G_N_ELEMENTS(iq_matrix->ScalingList4x4) == 6);
982     g_assert(G_N_ELEMENTS(iq_matrix->ScalingList4x4[0]) == 16);
983
984     for (i = 0; i < G_N_ELEMENTS(iq_matrix->ScalingList4x4); i++)
985         gst_h264_video_quant_matrix_4x4_get_raster_from_zigzag(
986             iq_matrix->ScalingList4x4[i], pps->scaling_lists_4x4[i]);
987 }
988
989 static void
990 fill_iq_matrix_8x8(VAIQMatrixBufferH264 *iq_matrix, const GstH264PPS *pps,
991     const GstH264SPS *sps)
992 {
993     guint i, n;
994
995     /* If chroma_format_idc != 3, there are up to 2 8x8 scaling lists */
996     if (!pps->transform_8x8_mode_flag)
997         return;
998
999     g_assert(G_N_ELEMENTS(iq_matrix->ScalingList8x8) >= 2);
1000     g_assert(G_N_ELEMENTS(iq_matrix->ScalingList8x8[0]) == 64);
1001
1002     n = (sps->chroma_format_idc != 3) ? 2 : 6;
1003     for (i = 0; i < n; i++) {
1004         gst_h264_video_quant_matrix_8x8_get_raster_from_zigzag(
1005             iq_matrix->ScalingList8x8[i], pps->scaling_lists_8x8[i]);
1006     }
1007 }
1008
1009 static GstVaapiDecoderStatus
1010 ensure_quant_matrix(GstVaapiDecoderH264 *decoder, GstVaapiPictureH264 *picture)
1011 {
1012     GstVaapiPicture * const base_picture = &picture->base;
1013     GstH264PPS * const pps = get_pps(decoder);
1014     GstH264SPS * const sps = get_sps(decoder);
1015     VAIQMatrixBufferH264 *iq_matrix;
1016
1017     base_picture->iq_matrix = GST_VAAPI_IQ_MATRIX_NEW(H264, decoder);
1018     if (!base_picture->iq_matrix) {
1019         GST_ERROR("failed to allocate IQ matrix");
1020         return GST_VAAPI_DECODER_STATUS_ERROR_ALLOCATION_FAILED;
1021     }
1022     iq_matrix = base_picture->iq_matrix->param;
1023
1024     /* XXX: we can only support 4:2:0 or 4:2:2 since ScalingLists8x8[]
1025        is not large enough to hold lists for 4:4:4 */
1026     if (sps->chroma_format_idc == 3)
1027         return GST_VAAPI_DECODER_STATUS_ERROR_UNSUPPORTED_CHROMA_FORMAT;
1028
1029     fill_iq_matrix_4x4(iq_matrix, pps, sps);
1030     fill_iq_matrix_8x8(iq_matrix, pps, sps);
1031
1032     return GST_VAAPI_DECODER_STATUS_SUCCESS;
1033 }
1034
1035 static inline gboolean
1036 is_valid_state(guint state, guint ref_state)
1037 {
1038     return (state & ref_state) == ref_state;
1039 }
1040
1041 static GstVaapiDecoderStatus
1042 decode_current_picture(GstVaapiDecoderH264 *decoder)
1043 {
1044     GstVaapiDecoderH264Private * const priv = &decoder->priv;
1045     GstVaapiPictureH264 * const picture = priv->current_picture;
1046
1047     if (!is_valid_state(priv->decoder_state, GST_H264_VIDEO_STATE_VALID_PICTURE))
1048         goto drop_frame;
1049     priv->decoder_state = 0;
1050
1051     if (!picture)
1052         return GST_VAAPI_DECODER_STATUS_SUCCESS;
1053
1054     if (!exec_ref_pic_marking(decoder, picture))
1055         goto error;
1056     if (!dpb_add(decoder, picture))
1057         goto error;
1058     if (!gst_vaapi_picture_decode(GST_VAAPI_PICTURE_CAST(picture)))
1059         goto error;
1060     if (priv->prev_frame && gst_vaapi_frame_store_has_frame(priv->prev_frame))
1061         gst_vaapi_picture_replace(&priv->current_picture, NULL);
1062     return GST_VAAPI_DECODER_STATUS_SUCCESS;
1063
1064 error:
1065     /* XXX: fix for cases where first field failed to be decoded */
1066     gst_vaapi_picture_replace(&priv->current_picture, NULL);
1067     return GST_VAAPI_DECODER_STATUS_ERROR_UNKNOWN;
1068
1069 drop_frame:
1070     priv->decoder_state = 0;
1071     return GST_VAAPI_DECODER_STATUS_DROP_FRAME;
1072 }
1073
1074 static GstVaapiDecoderStatus
1075 parse_sps(GstVaapiDecoderH264 *decoder, GstVaapiDecoderUnit *unit)
1076 {
1077     GstVaapiDecoderH264Private * const priv = &decoder->priv;
1078     GstVaapiParserInfoH264 * const pi = unit->parsed_info;
1079     GstH264SPS * const sps = &pi->data.sps;
1080     GstH264ParserResult result;
1081
1082     GST_DEBUG("parse SPS");
1083
1084     priv->parser_state = 0;
1085
1086     /* Variables that don't have inferred values per the H.264
1087        standard but that should get a default value anyway */
1088     sps->log2_max_pic_order_cnt_lsb_minus4 = 0;
1089
1090     result = gst_h264_parser_parse_sps(priv->parser, &pi->nalu, sps, TRUE);
1091     if (result != GST_H264_PARSER_OK)
1092         return get_status(result);
1093
1094     priv->parser_state |= GST_H264_VIDEO_STATE_GOT_SPS;
1095     return GST_VAAPI_DECODER_STATUS_SUCCESS;
1096 }
1097
1098 static GstVaapiDecoderStatus
1099 parse_pps(GstVaapiDecoderH264 *decoder, GstVaapiDecoderUnit *unit)
1100 {
1101     GstVaapiDecoderH264Private * const priv = &decoder->priv;
1102     GstVaapiParserInfoH264 * const pi = unit->parsed_info;
1103     GstH264PPS * const pps = &pi->data.pps;
1104     GstH264ParserResult result;
1105
1106     GST_DEBUG("parse PPS");
1107
1108     priv->parser_state &= GST_H264_VIDEO_STATE_GOT_SPS;
1109
1110     /* Variables that don't have inferred values per the H.264
1111        standard but that should get a default value anyway */
1112     pps->slice_group_map_type = 0;
1113     pps->slice_group_change_rate_minus1 = 0;
1114
1115     result = gst_h264_parser_parse_pps(priv->parser, &pi->nalu, pps);
1116     if (result != GST_H264_PARSER_OK)
1117         return get_status(result);
1118
1119     priv->parser_state |= GST_H264_VIDEO_STATE_GOT_PPS;
1120     return GST_VAAPI_DECODER_STATUS_SUCCESS;
1121 }
1122
1123 static GstVaapiDecoderStatus
1124 parse_sei(GstVaapiDecoderH264 *decoder, GstVaapiDecoderUnit *unit)
1125 {
1126     GstVaapiDecoderH264Private * const priv = &decoder->priv;
1127     GstVaapiParserInfoH264 * const pi = unit->parsed_info;
1128     GArray ** const sei_ptr = &pi->data.sei;
1129     GstH264ParserResult result;
1130
1131     GST_DEBUG("parse SEI");
1132
1133     result = gst_h264_parser_parse_sei(priv->parser, &pi->nalu, sei_ptr);
1134     if (result != GST_H264_PARSER_OK) {
1135         GST_WARNING("failed to parse SEI messages");
1136         return get_status(result);
1137     }
1138     return GST_VAAPI_DECODER_STATUS_SUCCESS;
1139 }
1140
1141 static GstVaapiDecoderStatus
1142 parse_slice(GstVaapiDecoderH264 *decoder, GstVaapiDecoderUnit *unit)
1143 {
1144     GstVaapiDecoderH264Private * const priv = &decoder->priv;
1145     GstVaapiParserInfoH264 * const pi = unit->parsed_info;
1146     GstH264SliceHdr * const slice_hdr = &pi->data.slice_hdr;
1147     GstH264ParserResult result;
1148
1149     GST_DEBUG("parse slice");
1150
1151     priv->parser_state &= (GST_H264_VIDEO_STATE_GOT_SPS|
1152                            GST_H264_VIDEO_STATE_GOT_PPS);
1153
1154     /* Variables that don't have inferred values per the H.264
1155        standard but that should get a default value anyway */
1156     slice_hdr->cabac_init_idc = 0;
1157     slice_hdr->direct_spatial_mv_pred_flag = 0;
1158
1159     result = gst_h264_parser_parse_slice_hdr(priv->parser, &pi->nalu,
1160         slice_hdr, TRUE, TRUE);
1161     if (result != GST_H264_PARSER_OK)
1162         return get_status(result);
1163
1164     priv->parser_state |= GST_H264_VIDEO_STATE_GOT_SLICE;
1165     return GST_VAAPI_DECODER_STATUS_SUCCESS;
1166 }
1167
1168 static GstVaapiDecoderStatus
1169 decode_sps(GstVaapiDecoderH264 *decoder, GstVaapiDecoderUnit *unit)
1170 {
1171     GstVaapiDecoderH264Private * const priv = &decoder->priv;
1172     GstVaapiParserInfoH264 * const pi = unit->parsed_info;
1173     GstH264SPS * const sps = &pi->data.sps;
1174
1175     GST_DEBUG("decode SPS");
1176
1177     gst_vaapi_parser_info_h264_replace(&priv->sps[sps->id], pi);
1178     return GST_VAAPI_DECODER_STATUS_SUCCESS;
1179 }
1180
1181 static GstVaapiDecoderStatus
1182 decode_pps(GstVaapiDecoderH264 *decoder, GstVaapiDecoderUnit *unit)
1183 {
1184     GstVaapiDecoderH264Private * const priv = &decoder->priv;
1185     GstVaapiParserInfoH264 * const pi = unit->parsed_info;
1186     GstH264PPS * const pps = &pi->data.pps;
1187
1188     GST_DEBUG("decode PPS");
1189
1190     gst_vaapi_parser_info_h264_replace(&priv->pps[pps->id], pi);
1191     return GST_VAAPI_DECODER_STATUS_SUCCESS;
1192 }
1193
1194 static GstVaapiDecoderStatus
1195 decode_sequence_end(GstVaapiDecoderH264 *decoder)
1196 {
1197     GstVaapiDecoderStatus status;
1198
1199     GST_DEBUG("decode sequence-end");
1200
1201     status = decode_current_picture(decoder);
1202     if (status != GST_VAAPI_DECODER_STATUS_SUCCESS)
1203         return status;
1204
1205     dpb_flush(decoder);
1206     return GST_VAAPI_DECODER_STATUS_SUCCESS;
1207 }
1208
1209 /* 8.2.1.1 - Decoding process for picture order count type 0 */
1210 static void
1211 init_picture_poc_0(
1212     GstVaapiDecoderH264 *decoder,
1213     GstVaapiPictureH264 *picture,
1214     GstH264SliceHdr     *slice_hdr
1215 )
1216 {
1217     GstVaapiDecoderH264Private * const priv = &decoder->priv;
1218     GstH264SPS * const sps = get_sps(decoder);
1219     const gint32 MaxPicOrderCntLsb = 1 << (sps->log2_max_pic_order_cnt_lsb_minus4 + 4);
1220     gint32 temp_poc;
1221
1222     GST_DEBUG("decode picture order count type 0");
1223
1224     if (GST_VAAPI_PICTURE_IS_IDR(picture)) {
1225         priv->prev_poc_msb = 0;
1226         priv->prev_poc_lsb = 0;
1227     }
1228     else if (priv->prev_pic_has_mmco5) {
1229         priv->prev_poc_msb = 0;
1230         priv->prev_poc_lsb =
1231             (priv->prev_pic_structure == GST_VAAPI_PICTURE_STRUCTURE_BOTTOM_FIELD ?
1232              0 : priv->field_poc[TOP_FIELD]);
1233     }
1234     else {
1235         priv->prev_poc_msb = priv->poc_msb;
1236         priv->prev_poc_lsb = priv->poc_lsb;
1237     }
1238
1239     // (8-3)
1240     priv->poc_lsb = slice_hdr->pic_order_cnt_lsb;
1241     if (priv->poc_lsb < priv->prev_poc_lsb &&
1242         (priv->prev_poc_lsb - priv->poc_lsb) >= (MaxPicOrderCntLsb / 2))
1243         priv->poc_msb = priv->prev_poc_msb + MaxPicOrderCntLsb;
1244     else if (priv->poc_lsb > priv->prev_poc_lsb &&
1245              (priv->poc_lsb - priv->prev_poc_lsb) > (MaxPicOrderCntLsb / 2))
1246         priv->poc_msb = priv->prev_poc_msb - MaxPicOrderCntLsb;
1247     else
1248         priv->poc_msb = priv->prev_poc_msb;
1249
1250     temp_poc = priv->poc_msb + priv->poc_lsb;
1251     switch (picture->structure) {
1252     case GST_VAAPI_PICTURE_STRUCTURE_FRAME:
1253         // (8-4, 8-5)
1254         priv->field_poc[TOP_FIELD] = temp_poc;
1255         priv->field_poc[BOTTOM_FIELD] = temp_poc +
1256             slice_hdr->delta_pic_order_cnt_bottom;
1257         break;
1258     case GST_VAAPI_PICTURE_STRUCTURE_TOP_FIELD:
1259         // (8-4)
1260         priv->field_poc[TOP_FIELD] = temp_poc;
1261         break;
1262     case GST_VAAPI_PICTURE_STRUCTURE_BOTTOM_FIELD:
1263         // (8-5)
1264         priv->field_poc[BOTTOM_FIELD] = temp_poc;
1265         break;
1266     }
1267 }
1268
1269 /* 8.2.1.2 - Decoding process for picture order count type 1 */
1270 static void
1271 init_picture_poc_1(
1272     GstVaapiDecoderH264 *decoder,
1273     GstVaapiPictureH264 *picture,
1274     GstH264SliceHdr     *slice_hdr
1275 )
1276 {
1277     GstVaapiDecoderH264Private * const priv = &decoder->priv;
1278     GstH264SPS * const sps = get_sps(decoder);
1279     const gint32 MaxFrameNum = 1 << (sps->log2_max_frame_num_minus4 + 4);
1280     gint32 prev_frame_num_offset, abs_frame_num, expected_poc;
1281     guint i;
1282
1283     GST_DEBUG("decode picture order count type 1");
1284
1285     if (priv->prev_pic_has_mmco5)
1286         prev_frame_num_offset = 0;
1287     else
1288         prev_frame_num_offset = priv->frame_num_offset;
1289
1290     // (8-6)
1291     if (GST_VAAPI_PICTURE_IS_IDR(picture))
1292         priv->frame_num_offset = 0;
1293     else if (priv->prev_frame_num > priv->frame_num)
1294         priv->frame_num_offset = prev_frame_num_offset + MaxFrameNum;
1295     else
1296         priv->frame_num_offset = prev_frame_num_offset;
1297
1298     // (8-7)
1299     if (sps->num_ref_frames_in_pic_order_cnt_cycle != 0)
1300         abs_frame_num = priv->frame_num_offset + priv->frame_num;
1301     else
1302         abs_frame_num = 0;
1303     if (!GST_VAAPI_PICTURE_IS_REFERENCE(picture) && abs_frame_num > 0)
1304         abs_frame_num = abs_frame_num - 1;
1305
1306     if (abs_frame_num > 0) {
1307         gint32 expected_delta_per_poc_cycle;
1308         gint32 poc_cycle_cnt, frame_num_in_poc_cycle;
1309
1310         expected_delta_per_poc_cycle = 0;
1311         for (i = 0; i < sps->num_ref_frames_in_pic_order_cnt_cycle; i++)
1312             expected_delta_per_poc_cycle += sps->offset_for_ref_frame[i];
1313
1314         // (8-8)
1315         poc_cycle_cnt = (abs_frame_num - 1) /
1316             sps->num_ref_frames_in_pic_order_cnt_cycle;
1317         frame_num_in_poc_cycle = (abs_frame_num - 1) %
1318             sps->num_ref_frames_in_pic_order_cnt_cycle;
1319
1320         // (8-9)
1321         expected_poc = poc_cycle_cnt * expected_delta_per_poc_cycle;
1322         for (i = 0; i <= frame_num_in_poc_cycle; i++)
1323             expected_poc += sps->offset_for_ref_frame[i];
1324     }
1325     else
1326         expected_poc = 0;
1327     if (!GST_VAAPI_PICTURE_IS_REFERENCE(picture))
1328         expected_poc += sps->offset_for_non_ref_pic;
1329
1330     // (8-10)
1331     switch (picture->structure) {
1332     case GST_VAAPI_PICTURE_STRUCTURE_FRAME:
1333         priv->field_poc[TOP_FIELD] = expected_poc +
1334             slice_hdr->delta_pic_order_cnt[0];
1335         priv->field_poc[BOTTOM_FIELD] = priv->field_poc[TOP_FIELD] +
1336             sps->offset_for_top_to_bottom_field +
1337             slice_hdr->delta_pic_order_cnt[1];
1338         break;
1339     case GST_VAAPI_PICTURE_STRUCTURE_TOP_FIELD:
1340         priv->field_poc[TOP_FIELD] = expected_poc +
1341             slice_hdr->delta_pic_order_cnt[0];
1342         break;
1343     case GST_VAAPI_PICTURE_STRUCTURE_BOTTOM_FIELD:
1344         priv->field_poc[BOTTOM_FIELD] = expected_poc + 
1345             sps->offset_for_top_to_bottom_field +
1346             slice_hdr->delta_pic_order_cnt[0];
1347         break;
1348     }
1349 }
1350
1351 /* 8.2.1.3 - Decoding process for picture order count type 2 */
1352 static void
1353 init_picture_poc_2(
1354     GstVaapiDecoderH264 *decoder,
1355     GstVaapiPictureH264 *picture,
1356     GstH264SliceHdr     *slice_hdr
1357 )
1358 {
1359     GstVaapiDecoderH264Private * const priv = &decoder->priv;
1360     GstH264SPS * const sps = get_sps(decoder);
1361     const gint32 MaxFrameNum = 1 << (sps->log2_max_frame_num_minus4 + 4);
1362     gint32 prev_frame_num_offset, temp_poc;
1363
1364     GST_DEBUG("decode picture order count type 2");
1365
1366     if (priv->prev_pic_has_mmco5)
1367         prev_frame_num_offset = 0;
1368     else
1369         prev_frame_num_offset = priv->frame_num_offset;
1370
1371     // (8-11)
1372     if (GST_VAAPI_PICTURE_IS_IDR(picture))
1373         priv->frame_num_offset = 0;
1374     else if (priv->prev_frame_num > priv->frame_num)
1375         priv->frame_num_offset = prev_frame_num_offset + MaxFrameNum;
1376     else
1377         priv->frame_num_offset = prev_frame_num_offset;
1378
1379     // (8-12)
1380     if (GST_VAAPI_PICTURE_IS_IDR(picture))
1381         temp_poc = 0;
1382     else if (!GST_VAAPI_PICTURE_IS_REFERENCE(picture))
1383         temp_poc = 2 * (priv->frame_num_offset + priv->frame_num) - 1;
1384     else
1385         temp_poc = 2 * (priv->frame_num_offset + priv->frame_num);
1386
1387     // (8-13)
1388     if (picture->structure != GST_VAAPI_PICTURE_STRUCTURE_BOTTOM_FIELD)
1389         priv->field_poc[TOP_FIELD] = temp_poc;
1390     if (picture->structure != GST_VAAPI_PICTURE_STRUCTURE_TOP_FIELD)
1391         priv->field_poc[BOTTOM_FIELD] = temp_poc;
1392 }
1393
1394 /* 8.2.1 - Decoding process for picture order count */
1395 static void
1396 init_picture_poc(
1397     GstVaapiDecoderH264 *decoder,
1398     GstVaapiPictureH264 *picture,
1399     GstH264SliceHdr     *slice_hdr
1400 )
1401 {
1402     GstVaapiDecoderH264Private * const priv = &decoder->priv;
1403     GstH264SPS * const sps = get_sps(decoder);
1404
1405     switch (sps->pic_order_cnt_type) {
1406     case 0:
1407         init_picture_poc_0(decoder, picture, slice_hdr);
1408         break;
1409     case 1:
1410         init_picture_poc_1(decoder, picture, slice_hdr);
1411         break;
1412     case 2:
1413         init_picture_poc_2(decoder, picture, slice_hdr);
1414         break;
1415     }
1416
1417     if (picture->structure != GST_VAAPI_PICTURE_STRUCTURE_BOTTOM_FIELD)
1418         picture->field_poc[TOP_FIELD] = priv->field_poc[TOP_FIELD];
1419     if (picture->structure != GST_VAAPI_PICTURE_STRUCTURE_TOP_FIELD)
1420         picture->field_poc[BOTTOM_FIELD] = priv->field_poc[BOTTOM_FIELD];
1421     picture->base.poc = MIN(picture->field_poc[0], picture->field_poc[1]);
1422 }
1423
1424 static int
1425 compare_picture_pic_num_dec(const void *a, const void *b)
1426 {
1427     const GstVaapiPictureH264 * const picA = *(GstVaapiPictureH264 **)a;
1428     const GstVaapiPictureH264 * const picB = *(GstVaapiPictureH264 **)b;
1429
1430     return picB->pic_num - picA->pic_num;
1431 }
1432
1433 static int
1434 compare_picture_long_term_pic_num_inc(const void *a, const void *b)
1435 {
1436     const GstVaapiPictureH264 * const picA = *(GstVaapiPictureH264 **)a;
1437     const GstVaapiPictureH264 * const picB = *(GstVaapiPictureH264 **)b;
1438
1439     return picA->long_term_pic_num - picB->long_term_pic_num;
1440 }
1441
1442 static int
1443 compare_picture_poc_dec(const void *a, const void *b)
1444 {
1445     const GstVaapiPictureH264 * const picA = *(GstVaapiPictureH264 **)a;
1446     const GstVaapiPictureH264 * const picB = *(GstVaapiPictureH264 **)b;
1447
1448     return picB->base.poc - picA->base.poc;
1449 }
1450
1451 static int
1452 compare_picture_poc_inc(const void *a, const void *b)
1453 {
1454     const GstVaapiPictureH264 * const picA = *(GstVaapiPictureH264 **)a;
1455     const GstVaapiPictureH264 * const picB = *(GstVaapiPictureH264 **)b;
1456
1457     return picA->base.poc - picB->base.poc;
1458 }
1459
1460 static int
1461 compare_picture_frame_num_wrap_dec(const void *a, const void *b)
1462 {
1463     const GstVaapiPictureH264 * const picA = *(GstVaapiPictureH264 **)a;
1464     const GstVaapiPictureH264 * const picB = *(GstVaapiPictureH264 **)b;
1465
1466     return picB->frame_num_wrap - picA->frame_num_wrap;
1467 }
1468
1469 static int
1470 compare_picture_long_term_frame_idx_inc(const void *a, const void *b)
1471 {
1472     const GstVaapiPictureH264 * const picA = *(GstVaapiPictureH264 **)a;
1473     const GstVaapiPictureH264 * const picB = *(GstVaapiPictureH264 **)b;
1474
1475     return picA->long_term_frame_idx - picB->long_term_frame_idx;
1476 }
1477
1478 /* 8.2.4.1 - Decoding process for picture numbers */
1479 static void
1480 init_picture_refs_pic_num(
1481     GstVaapiDecoderH264 *decoder,
1482     GstVaapiPictureH264 *picture,
1483     GstH264SliceHdr     *slice_hdr
1484 )
1485 {
1486     GstVaapiDecoderH264Private * const priv = &decoder->priv;
1487     GstH264SPS * const sps = get_sps(decoder);
1488     const gint32 MaxFrameNum = 1 << (sps->log2_max_frame_num_minus4 + 4);
1489     guint i;
1490
1491     GST_DEBUG("decode picture numbers");
1492
1493     for (i = 0; i < priv->short_ref_count; i++) {
1494         GstVaapiPictureH264 * const pic = priv->short_ref[i];
1495
1496         // (8-27)
1497         if (pic->frame_num > priv->frame_num)
1498             pic->frame_num_wrap = pic->frame_num - MaxFrameNum;
1499         else
1500             pic->frame_num_wrap = pic->frame_num;
1501
1502         // (8-28, 8-30, 8-31)
1503         if (GST_VAAPI_PICTURE_IS_FRAME(picture))
1504             pic->pic_num = pic->frame_num_wrap;
1505         else {
1506             if (pic->structure == picture->structure)
1507                 pic->pic_num = 2 * pic->frame_num_wrap + 1;
1508             else
1509                 pic->pic_num = 2 * pic->frame_num_wrap;
1510         }
1511     }
1512
1513     for (i = 0; i < priv->long_ref_count; i++) {
1514         GstVaapiPictureH264 * const pic = priv->long_ref[i];
1515
1516         // (8-29, 8-32, 8-33)
1517         if (GST_VAAPI_PICTURE_IS_FRAME(picture))
1518             pic->long_term_pic_num = pic->long_term_frame_idx;
1519         else {
1520             if (pic->structure == picture->structure)
1521                 pic->long_term_pic_num = 2 * pic->long_term_frame_idx + 1;
1522             else
1523                 pic->long_term_pic_num = 2 * pic->long_term_frame_idx;
1524         }
1525     }
1526 }
1527
1528 #define SORT_REF_LIST(list, n, compare_func) \
1529     qsort(list, n, sizeof(*(list)), compare_picture_##compare_func)
1530
1531 static void
1532 init_picture_refs_fields_1(
1533     guint                picture_structure,
1534     GstVaapiPictureH264 *RefPicList[32],
1535     guint               *RefPicList_count,
1536     GstVaapiPictureH264 *ref_list[32],
1537     guint                ref_list_count
1538 )
1539 {
1540     guint i, j, n;
1541
1542     i = 0;
1543     j = 0;
1544     n = *RefPicList_count;
1545     do {
1546         g_assert(n < 32);
1547         for (; i < ref_list_count; i++) {
1548             if (ref_list[i]->structure == picture_structure) {
1549                 RefPicList[n++] = ref_list[i++];
1550                 break;
1551             }
1552         }
1553         for (; j < ref_list_count; j++) {
1554             if (ref_list[j]->structure != picture_structure) {
1555                 RefPicList[n++] = ref_list[j++];
1556                 break;
1557             }
1558         }
1559     } while (i < ref_list_count || j < ref_list_count);
1560     *RefPicList_count = n;
1561 }
1562
1563 static inline void
1564 init_picture_refs_fields(
1565     GstVaapiPictureH264 *picture,
1566     GstVaapiPictureH264 *RefPicList[32],
1567     guint               *RefPicList_count,
1568     GstVaapiPictureH264 *short_ref[32],
1569     guint                short_ref_count,
1570     GstVaapiPictureH264 *long_ref[32],
1571     guint                long_ref_count
1572 )
1573 {
1574     guint n = 0;
1575
1576     /* 8.2.4.2.5 - reference picture lists in fields */
1577     init_picture_refs_fields_1(picture->structure, RefPicList, &n,
1578         short_ref, short_ref_count);
1579     init_picture_refs_fields_1(picture->structure, RefPicList, &n,
1580         long_ref, long_ref_count);
1581     *RefPicList_count = n;
1582 }
1583
1584 static void
1585 init_picture_refs_p_slice(
1586     GstVaapiDecoderH264 *decoder,
1587     GstVaapiPictureH264 *picture,
1588     GstH264SliceHdr     *slice_hdr
1589 )
1590 {
1591     GstVaapiDecoderH264Private * const priv = &decoder->priv;
1592     GstVaapiPictureH264 **ref_list;
1593     guint i;
1594
1595     GST_DEBUG("decode reference picture list for P and SP slices");
1596
1597     if (GST_VAAPI_PICTURE_IS_FRAME(picture)) {
1598         /* 8.2.4.2.1 - P and SP slices in frames */
1599         if (priv->short_ref_count > 0) {
1600             ref_list = priv->RefPicList0;
1601             for (i = 0; i < priv->short_ref_count; i++)
1602                 ref_list[i] = priv->short_ref[i];
1603             SORT_REF_LIST(ref_list, i, pic_num_dec);
1604             priv->RefPicList0_count += i;
1605         }
1606
1607         if (priv->long_ref_count > 0) {
1608             ref_list = &priv->RefPicList0[priv->RefPicList0_count];
1609             for (i = 0; i < priv->long_ref_count; i++)
1610                 ref_list[i] = priv->long_ref[i];
1611             SORT_REF_LIST(ref_list, i, long_term_pic_num_inc);
1612             priv->RefPicList0_count += i;
1613         }
1614     }
1615     else {
1616         /* 8.2.4.2.2 - P and SP slices in fields */
1617         GstVaapiPictureH264 *short_ref[32];
1618         guint short_ref_count = 0;
1619         GstVaapiPictureH264 *long_ref[32];
1620         guint long_ref_count = 0;
1621
1622         if (priv->short_ref_count > 0) {
1623             for (i = 0; i < priv->short_ref_count; i++)
1624                 short_ref[i] = priv->short_ref[i];
1625             SORT_REF_LIST(short_ref, i, frame_num_wrap_dec);
1626             short_ref_count = i;
1627         }
1628
1629         if (priv->long_ref_count > 0) {
1630             for (i = 0; i < priv->long_ref_count; i++)
1631                 long_ref[i] = priv->long_ref[i];
1632             SORT_REF_LIST(long_ref, i, long_term_frame_idx_inc);
1633             long_ref_count = i;
1634         }
1635
1636         init_picture_refs_fields(
1637             picture,
1638             priv->RefPicList0, &priv->RefPicList0_count,
1639             short_ref,          short_ref_count,
1640             long_ref,           long_ref_count
1641         );
1642     }
1643 }
1644
1645 static void
1646 init_picture_refs_b_slice(
1647     GstVaapiDecoderH264 *decoder,
1648     GstVaapiPictureH264 *picture,
1649     GstH264SliceHdr     *slice_hdr
1650 )
1651 {
1652     GstVaapiDecoderH264Private * const priv = &decoder->priv;
1653     GstVaapiPictureH264 **ref_list;
1654     guint i, n;
1655
1656     GST_DEBUG("decode reference picture list for B slices");
1657
1658     if (GST_VAAPI_PICTURE_IS_FRAME(picture)) {
1659         /* 8.2.4.2.3 - B slices in frames */
1660
1661         /* RefPicList0 */
1662         if (priv->short_ref_count > 0) {
1663             // 1. Short-term references
1664             ref_list = priv->RefPicList0;
1665             for (n = 0, i = 0; i < priv->short_ref_count; i++) {
1666                 if (priv->short_ref[i]->base.poc < picture->base.poc)
1667                     ref_list[n++] = priv->short_ref[i];
1668             }
1669             SORT_REF_LIST(ref_list, n, poc_dec);
1670             priv->RefPicList0_count += n;
1671
1672             ref_list = &priv->RefPicList0[priv->RefPicList0_count];
1673             for (n = 0, i = 0; i < priv->short_ref_count; i++) {
1674                 if (priv->short_ref[i]->base.poc >= picture->base.poc)
1675                     ref_list[n++] = priv->short_ref[i];
1676             }
1677             SORT_REF_LIST(ref_list, n, poc_inc);
1678             priv->RefPicList0_count += n;
1679         }
1680
1681         if (priv->long_ref_count > 0) {
1682             // 2. Long-term references
1683             ref_list = &priv->RefPicList0[priv->RefPicList0_count];
1684             for (n = 0, i = 0; i < priv->long_ref_count; i++)
1685                 ref_list[n++] = priv->long_ref[i];
1686             SORT_REF_LIST(ref_list, n, long_term_pic_num_inc);
1687             priv->RefPicList0_count += n;
1688         }
1689
1690         /* RefPicList1 */
1691         if (priv->short_ref_count > 0) {
1692             // 1. Short-term references
1693             ref_list = priv->RefPicList1;
1694             for (n = 0, i = 0; i < priv->short_ref_count; i++) {
1695                 if (priv->short_ref[i]->base.poc > picture->base.poc)
1696                     ref_list[n++] = priv->short_ref[i];
1697             }
1698             SORT_REF_LIST(ref_list, n, poc_inc);
1699             priv->RefPicList1_count += n;
1700
1701             ref_list = &priv->RefPicList1[priv->RefPicList1_count];
1702             for (n = 0, i = 0; i < priv->short_ref_count; i++) {
1703                 if (priv->short_ref[i]->base.poc <= picture->base.poc)
1704                     ref_list[n++] = priv->short_ref[i];
1705             }
1706             SORT_REF_LIST(ref_list, n, poc_dec);
1707             priv->RefPicList1_count += n;
1708         }
1709
1710         if (priv->long_ref_count > 0) {
1711             // 2. Long-term references
1712             ref_list = &priv->RefPicList1[priv->RefPicList1_count];
1713             for (n = 0, i = 0; i < priv->long_ref_count; i++)
1714                 ref_list[n++] = priv->long_ref[i];
1715             SORT_REF_LIST(ref_list, n, long_term_pic_num_inc);
1716             priv->RefPicList1_count += n;
1717         }
1718     }
1719     else {
1720         /* 8.2.4.2.4 - B slices in fields */
1721         GstVaapiPictureH264 *short_ref0[32];
1722         guint short_ref0_count = 0;
1723         GstVaapiPictureH264 *short_ref1[32];
1724         guint short_ref1_count = 0;
1725         GstVaapiPictureH264 *long_ref[32];
1726         guint long_ref_count = 0;
1727
1728         /* refFrameList0ShortTerm */
1729         if (priv->short_ref_count > 0) {
1730             ref_list = short_ref0;
1731             for (n = 0, i = 0; i < priv->short_ref_count; i++) {
1732                 if (priv->short_ref[i]->base.poc <= picture->base.poc)
1733                     ref_list[n++] = priv->short_ref[i];
1734             }
1735             SORT_REF_LIST(ref_list, n, poc_dec);
1736             short_ref0_count += n;
1737
1738             ref_list = &short_ref0[short_ref0_count];
1739             for (n = 0, i = 0; i < priv->short_ref_count; i++) {
1740                 if (priv->short_ref[i]->base.poc > picture->base.poc)
1741                     ref_list[n++] = priv->short_ref[i];
1742             }
1743             SORT_REF_LIST(ref_list, n, poc_inc);
1744             short_ref0_count += n;
1745         }
1746
1747         /* refFrameList1ShortTerm */
1748         if (priv->short_ref_count > 0) {
1749             ref_list = short_ref1;
1750             for (n = 0, i = 0; i < priv->short_ref_count; i++) {
1751                 if (priv->short_ref[i]->base.poc > picture->base.poc)
1752                     ref_list[n++] = priv->short_ref[i];
1753             }
1754             SORT_REF_LIST(ref_list, n, poc_inc);
1755             short_ref1_count += n;
1756
1757             ref_list = &short_ref1[short_ref1_count];
1758             for (n = 0, i = 0; i < priv->short_ref_count; i++) {
1759                 if (priv->short_ref[i]->base.poc <= picture->base.poc)
1760                     ref_list[n++] = priv->short_ref[i];
1761             }
1762             SORT_REF_LIST(ref_list, n, poc_dec);
1763             short_ref1_count += n;
1764         }
1765
1766         /* refFrameListLongTerm */
1767         if (priv->long_ref_count > 0) {
1768             for (i = 0; i < priv->long_ref_count; i++)
1769                 long_ref[i] = priv->long_ref[i];
1770             SORT_REF_LIST(long_ref, i, long_term_frame_idx_inc);
1771             long_ref_count = i;
1772         }
1773
1774         init_picture_refs_fields(
1775             picture,
1776             priv->RefPicList0, &priv->RefPicList0_count,
1777             short_ref0,         short_ref0_count,
1778             long_ref,           long_ref_count
1779         );
1780
1781         init_picture_refs_fields(
1782             picture,
1783             priv->RefPicList1, &priv->RefPicList1_count,
1784             short_ref1,         short_ref1_count,
1785             long_ref,           long_ref_count
1786         );
1787    }
1788
1789     /* Check whether RefPicList1 is identical to RefPicList0, then
1790        swap if necessary */
1791     if (priv->RefPicList1_count > 1 &&
1792         priv->RefPicList1_count == priv->RefPicList0_count &&
1793         memcmp(priv->RefPicList0, priv->RefPicList1,
1794                priv->RefPicList0_count * sizeof(priv->RefPicList0[0])) == 0) {
1795         GstVaapiPictureH264 * const tmp = priv->RefPicList1[0];
1796         priv->RefPicList1[0] = priv->RefPicList1[1];
1797         priv->RefPicList1[1] = tmp;
1798     }
1799 }
1800
1801 #undef SORT_REF_LIST
1802
1803 static gint
1804 find_short_term_reference(GstVaapiDecoderH264 *decoder, gint32 pic_num)
1805 {
1806     GstVaapiDecoderH264Private * const priv = &decoder->priv;
1807     guint i;
1808
1809     for (i = 0; i < priv->short_ref_count; i++) {
1810         if (priv->short_ref[i]->pic_num == pic_num)
1811             return i;
1812     }
1813     GST_ERROR("found no short-term reference picture with PicNum = %d",
1814               pic_num);
1815     return -1;
1816 }
1817
1818 static gint
1819 find_long_term_reference(GstVaapiDecoderH264 *decoder, gint32 long_term_pic_num)
1820 {
1821     GstVaapiDecoderH264Private * const priv = &decoder->priv;
1822     guint i;
1823
1824     for (i = 0; i < priv->long_ref_count; i++) {
1825         if (priv->long_ref[i]->long_term_pic_num == long_term_pic_num)
1826             return i;
1827     }
1828     GST_ERROR("found no long-term reference picture with LongTermPicNum = %d",
1829               long_term_pic_num);
1830     return -1;
1831 }
1832
1833 static void
1834 exec_picture_refs_modification_1(
1835     GstVaapiDecoderH264           *decoder,
1836     GstVaapiPictureH264           *picture,
1837     GstH264SliceHdr               *slice_hdr,
1838     guint                          list
1839 )
1840 {
1841     GstVaapiDecoderH264Private * const priv = &decoder->priv;
1842     GstH264SPS * const sps = get_sps(decoder);
1843     GstH264RefPicListModification *ref_pic_list_modification;
1844     guint num_ref_pic_list_modifications;
1845     GstVaapiPictureH264 **ref_list;
1846     guint *ref_list_count_ptr, ref_list_count, ref_list_idx = 0;
1847     guint i, j, n, num_refs;
1848     gint found_ref_idx;
1849     gint32 MaxPicNum, CurrPicNum, picNumPred;
1850
1851     GST_DEBUG("modification process of reference picture list %u", list);
1852
1853     if (list == 0) {
1854         ref_pic_list_modification      = slice_hdr->ref_pic_list_modification_l0;
1855         num_ref_pic_list_modifications = slice_hdr->n_ref_pic_list_modification_l0;
1856         ref_list                       = priv->RefPicList0;
1857         ref_list_count_ptr             = &priv->RefPicList0_count;
1858         num_refs                       = slice_hdr->num_ref_idx_l0_active_minus1 + 1;
1859     }
1860     else {
1861         ref_pic_list_modification      = slice_hdr->ref_pic_list_modification_l1;
1862         num_ref_pic_list_modifications = slice_hdr->n_ref_pic_list_modification_l1;
1863         ref_list                       = priv->RefPicList1;
1864         ref_list_count_ptr             = &priv->RefPicList1_count;
1865         num_refs                       = slice_hdr->num_ref_idx_l1_active_minus1 + 1;
1866     }
1867     ref_list_count = *ref_list_count_ptr;
1868
1869     if (!GST_VAAPI_PICTURE_IS_FRAME(picture)) {
1870         MaxPicNum  = 1 << (sps->log2_max_frame_num_minus4 + 5); // 2 * MaxFrameNum
1871         CurrPicNum = 2 * slice_hdr->frame_num + 1;              // 2 * frame_num + 1
1872     }
1873     else {
1874         MaxPicNum  = 1 << (sps->log2_max_frame_num_minus4 + 4); // MaxFrameNum
1875         CurrPicNum = slice_hdr->frame_num;                      // frame_num
1876     }
1877
1878     picNumPred = CurrPicNum;
1879
1880     for (i = 0; i < num_ref_pic_list_modifications; i++) {
1881         GstH264RefPicListModification * const l = &ref_pic_list_modification[i];
1882         if (l->modification_of_pic_nums_idc == 3)
1883             break;
1884
1885         /* 8.2.4.3.1 - Short-term reference pictures */
1886         if (l->modification_of_pic_nums_idc == 0 || l->modification_of_pic_nums_idc == 1) {
1887             gint32 abs_diff_pic_num = l->value.abs_diff_pic_num_minus1 + 1;
1888             gint32 picNum, picNumNoWrap;
1889
1890             // (8-34)
1891             if (l->modification_of_pic_nums_idc == 0) {
1892                 picNumNoWrap = picNumPred - abs_diff_pic_num;
1893                 if (picNumNoWrap < 0)
1894                     picNumNoWrap += MaxPicNum;
1895             }
1896
1897             // (8-35)
1898             else {
1899                 picNumNoWrap = picNumPred + abs_diff_pic_num;
1900                 if (picNumNoWrap >= MaxPicNum)
1901                     picNumNoWrap -= MaxPicNum;
1902             }
1903             picNumPred = picNumNoWrap;
1904
1905             // (8-36)
1906             picNum = picNumNoWrap;
1907             if (picNum > CurrPicNum)
1908                 picNum -= MaxPicNum;
1909
1910             // (8-37)
1911             for (j = num_refs; j > ref_list_idx; j--)
1912                 ref_list[j] = ref_list[j - 1];
1913             found_ref_idx = find_short_term_reference(decoder, picNum);
1914             ref_list[ref_list_idx++] =
1915                 found_ref_idx >= 0 ? priv->short_ref[found_ref_idx] : NULL;
1916             n = ref_list_idx;
1917             for (j = ref_list_idx; j <= num_refs; j++) {
1918                 gint32 PicNumF;
1919                 if (!ref_list[j])
1920                     continue;
1921                 PicNumF =
1922                     GST_VAAPI_PICTURE_IS_SHORT_TERM_REFERENCE(ref_list[j]) ?
1923                     ref_list[j]->pic_num : MaxPicNum;
1924                 if (PicNumF != picNum)
1925                     ref_list[n++] = ref_list[j];
1926             }
1927         }
1928
1929         /* 8.2.4.3.2 - Long-term reference pictures */
1930         else {
1931
1932             for (j = num_refs; j > ref_list_idx; j--)
1933                 ref_list[j] = ref_list[j - 1];
1934             found_ref_idx =
1935                 find_long_term_reference(decoder, l->value.long_term_pic_num);
1936             ref_list[ref_list_idx++] =
1937                 found_ref_idx >= 0 ? priv->long_ref[found_ref_idx] : NULL;
1938             n = ref_list_idx;
1939             for (j = ref_list_idx; j <= num_refs; j++) {
1940                 gint32 LongTermPicNumF;
1941                 if (!ref_list[j])
1942                     continue;
1943                 LongTermPicNumF =
1944                     GST_VAAPI_PICTURE_IS_LONG_TERM_REFERENCE(ref_list[j]) ?
1945                     ref_list[j]->long_term_pic_num : INT_MAX;
1946                 if (LongTermPicNumF != l->value.long_term_pic_num)
1947                     ref_list[n++] = ref_list[j];
1948             }
1949         }
1950     }
1951
1952 #if DEBUG
1953     for (i = 0; i < num_refs; i++)
1954         if (!ref_list[i])
1955             GST_ERROR("list %u entry %u is empty", list, i);
1956 #endif
1957     *ref_list_count_ptr = num_refs;
1958 }
1959
1960 /* 8.2.4.3 - Modification process for reference picture lists */
1961 static void
1962 exec_picture_refs_modification(
1963     GstVaapiDecoderH264 *decoder,
1964     GstVaapiPictureH264 *picture,
1965     GstH264SliceHdr     *slice_hdr
1966 )
1967 {
1968     GST_DEBUG("execute ref_pic_list_modification()");
1969
1970     /* RefPicList0 */
1971     if (!GST_H264_IS_I_SLICE(slice_hdr) && !GST_H264_IS_SI_SLICE(slice_hdr) &&
1972         slice_hdr->ref_pic_list_modification_flag_l0)
1973         exec_picture_refs_modification_1(decoder, picture, slice_hdr, 0);
1974
1975     /* RefPicList1 */
1976     if (GST_H264_IS_B_SLICE(slice_hdr) &&
1977         slice_hdr->ref_pic_list_modification_flag_l1)
1978         exec_picture_refs_modification_1(decoder, picture, slice_hdr, 1);
1979 }
1980
1981 static void
1982 init_picture_ref_lists(GstVaapiDecoderH264 *decoder)
1983 {
1984     GstVaapiDecoderH264Private * const priv = &decoder->priv;
1985     guint i, j, short_ref_count, long_ref_count;
1986
1987     short_ref_count = 0;
1988     long_ref_count  = 0;
1989     if (GST_VAAPI_PICTURE_IS_FRAME(priv->current_picture)) {
1990         for (i = 0; i < priv->dpb_count; i++) {
1991             GstVaapiFrameStore * const fs = priv->dpb[i];
1992             GstVaapiPictureH264 *picture;
1993             if (!gst_vaapi_frame_store_has_frame(fs))
1994                 continue;
1995             picture = fs->buffers[0];
1996             if (GST_VAAPI_PICTURE_IS_SHORT_TERM_REFERENCE(picture))
1997                 priv->short_ref[short_ref_count++] = picture;
1998             else if (GST_VAAPI_PICTURE_IS_LONG_TERM_REFERENCE(picture))
1999                 priv->long_ref[long_ref_count++] = picture;
2000             picture->structure = GST_VAAPI_PICTURE_STRUCTURE_FRAME;
2001             picture->other_field = fs->buffers[1];
2002         }
2003     }
2004     else {
2005         for (i = 0; i < priv->dpb_count; i++) {
2006             GstVaapiFrameStore * const fs = priv->dpb[i];
2007             for (j = 0; j < fs->num_buffers; j++) {
2008                 GstVaapiPictureH264 * const picture = fs->buffers[j];
2009                 if (GST_VAAPI_PICTURE_IS_SHORT_TERM_REFERENCE(picture))
2010                     priv->short_ref[short_ref_count++] = picture;
2011                 else if (GST_VAAPI_PICTURE_IS_LONG_TERM_REFERENCE(picture))
2012                     priv->long_ref[long_ref_count++] = picture;
2013                 picture->structure = picture->base.structure;
2014                 picture->other_field = fs->buffers[j ^ 1];
2015             }
2016         }
2017     }
2018
2019     for (i = short_ref_count; i < priv->short_ref_count; i++)
2020         priv->short_ref[i] = NULL;
2021     priv->short_ref_count = short_ref_count;
2022
2023     for (i = long_ref_count; i < priv->long_ref_count; i++)
2024         priv->long_ref[i] = NULL;
2025     priv->long_ref_count = long_ref_count;
2026 }
2027
2028 static void
2029 init_picture_refs(
2030     GstVaapiDecoderH264 *decoder,
2031     GstVaapiPictureH264 *picture,
2032     GstH264SliceHdr     *slice_hdr
2033 )
2034 {
2035     GstVaapiDecoderH264Private * const priv = &decoder->priv;
2036     guint i, num_refs;
2037
2038     init_picture_ref_lists(decoder);
2039     init_picture_refs_pic_num(decoder, picture, slice_hdr);
2040
2041     priv->RefPicList0_count = 0;
2042     priv->RefPicList1_count = 0;
2043
2044     switch (slice_hdr->type % 5) {
2045     case GST_H264_P_SLICE:
2046     case GST_H264_SP_SLICE:
2047         init_picture_refs_p_slice(decoder, picture, slice_hdr);
2048         break;
2049     case GST_H264_B_SLICE:
2050         init_picture_refs_b_slice(decoder, picture, slice_hdr);
2051         break;
2052     default:
2053         break;
2054     }
2055
2056     exec_picture_refs_modification(decoder, picture, slice_hdr);
2057
2058     switch (slice_hdr->type % 5) {
2059     case GST_H264_B_SLICE:
2060         num_refs = 1 + slice_hdr->num_ref_idx_l1_active_minus1;
2061         for (i = priv->RefPicList1_count; i < num_refs; i++)
2062             priv->RefPicList1[i] = NULL;
2063         priv->RefPicList1_count = num_refs;
2064
2065         // fall-through
2066     case GST_H264_P_SLICE:
2067     case GST_H264_SP_SLICE:
2068         num_refs = 1 + slice_hdr->num_ref_idx_l0_active_minus1;
2069         for (i = priv->RefPicList0_count; i < num_refs; i++)
2070             priv->RefPicList0[i] = NULL;
2071         priv->RefPicList0_count = num_refs;
2072         break;
2073     default:
2074         break;
2075     }
2076 }
2077
2078 static gboolean
2079 init_picture(
2080     GstVaapiDecoderH264 *decoder,
2081     GstVaapiPictureH264 *picture, GstVaapiParserInfoH264 *pi)
2082 {
2083     GstVaapiDecoderH264Private * const priv = &decoder->priv;
2084     GstVaapiPicture * const base_picture = &picture->base;
2085     GstH264SliceHdr * const slice_hdr = &pi->data.slice_hdr;
2086
2087     priv->prev_frame_num        = priv->frame_num;
2088     priv->frame_num             = slice_hdr->frame_num;
2089     picture->frame_num          = priv->frame_num;
2090     picture->frame_num_wrap     = priv->frame_num;
2091     picture->output_flag        = TRUE; /* XXX: conformant to Annex A only */
2092     base_picture->pts           = GST_VAAPI_DECODER_CODEC_FRAME(decoder)->pts;
2093     base_picture->type          = GST_VAAPI_PICTURE_TYPE_NONE;
2094
2095     /* Reset decoder state for IDR pictures */
2096     if (pi->nalu.type == GST_H264_NAL_SLICE_IDR) {
2097         GST_DEBUG("<IDR>");
2098         GST_VAAPI_PICTURE_FLAG_SET(picture, GST_VAAPI_PICTURE_FLAG_IDR);
2099         dpb_flush(decoder);
2100     }
2101
2102     /* Initialize picture structure */
2103     if (!slice_hdr->field_pic_flag)
2104         base_picture->structure = GST_VAAPI_PICTURE_STRUCTURE_FRAME;
2105     else {
2106         GST_VAAPI_PICTURE_FLAG_SET(picture, GST_VAAPI_PICTURE_FLAG_INTERLACED);
2107         if (!slice_hdr->bottom_field_flag)
2108             base_picture->structure = GST_VAAPI_PICTURE_STRUCTURE_TOP_FIELD;
2109         else
2110             base_picture->structure = GST_VAAPI_PICTURE_STRUCTURE_BOTTOM_FIELD;
2111     }
2112     picture->structure = base_picture->structure;
2113
2114     /* Initialize reference flags */
2115     if (pi->nalu.ref_idc) {
2116         GstH264DecRefPicMarking * const dec_ref_pic_marking =
2117             &slice_hdr->dec_ref_pic_marking;
2118
2119         if (GST_VAAPI_PICTURE_IS_IDR(picture) &&
2120             dec_ref_pic_marking->long_term_reference_flag)
2121             GST_VAAPI_PICTURE_FLAG_SET(picture,
2122                 GST_VAAPI_PICTURE_FLAG_LONG_TERM_REFERENCE);
2123         else
2124             GST_VAAPI_PICTURE_FLAG_SET(picture,
2125                 GST_VAAPI_PICTURE_FLAG_SHORT_TERM_REFERENCE);
2126     }
2127
2128     init_picture_poc(decoder, picture, slice_hdr);
2129     return TRUE;
2130 }
2131
2132 /* 8.2.5.3 - Sliding window decoded reference picture marking process */
2133 static gboolean
2134 exec_ref_pic_marking_sliding_window(GstVaapiDecoderH264 *decoder)
2135 {
2136     GstVaapiDecoderH264Private * const priv = &decoder->priv;
2137     GstH264SPS * const sps = get_sps(decoder);
2138     GstVaapiPictureH264 *ref_picture;
2139     guint i, m, max_num_ref_frames;
2140
2141     GST_DEBUG("reference picture marking process (sliding window)");
2142
2143     if (!GST_VAAPI_PICTURE_IS_FIRST_FIELD(priv->current_picture))
2144         return TRUE;
2145
2146     max_num_ref_frames = sps->num_ref_frames;
2147     if (max_num_ref_frames == 0)
2148         max_num_ref_frames = 1;
2149     if (!GST_VAAPI_PICTURE_IS_FRAME(priv->current_picture))
2150         max_num_ref_frames <<= 1;
2151
2152     if (priv->short_ref_count + priv->long_ref_count < max_num_ref_frames)
2153         return TRUE;
2154     if (priv->short_ref_count < 1)
2155         return FALSE;
2156
2157     for (m = 0, i = 1; i < priv->short_ref_count; i++) {
2158         GstVaapiPictureH264 * const picture = priv->short_ref[i];
2159         if (picture->frame_num_wrap < priv->short_ref[m]->frame_num_wrap)
2160             m = i;
2161     }
2162
2163     ref_picture = priv->short_ref[m];
2164     gst_vaapi_picture_h264_set_reference(ref_picture, 0, TRUE);
2165     ARRAY_REMOVE_INDEX(priv->short_ref, m);
2166
2167     /* Both fields need to be marked as "unused for reference", so
2168        remove the other field from the short_ref[] list as well */
2169     if (!GST_VAAPI_PICTURE_IS_FRAME(priv->current_picture) && ref_picture->other_field) {
2170         for (i = 0; i < priv->short_ref_count; i++) {
2171             if (priv->short_ref[i] == ref_picture->other_field) {
2172                 ARRAY_REMOVE_INDEX(priv->short_ref, i);
2173                 break;
2174             }
2175         }
2176     }
2177     return TRUE;
2178 }
2179
2180 static inline gint32
2181 get_picNumX(GstVaapiPictureH264 *picture, GstH264RefPicMarking *ref_pic_marking)
2182 {
2183     gint32 pic_num;
2184
2185     if (GST_VAAPI_PICTURE_IS_FRAME(picture))
2186         pic_num = picture->frame_num_wrap;
2187     else
2188         pic_num = 2 * picture->frame_num_wrap + 1;
2189     pic_num -= ref_pic_marking->difference_of_pic_nums_minus1 + 1;
2190     return pic_num;
2191 }
2192
2193 /* 8.2.5.4.1. Mark short-term reference picture as "unused for reference" */
2194 static void
2195 exec_ref_pic_marking_adaptive_mmco_1(
2196     GstVaapiDecoderH264  *decoder,
2197     GstVaapiPictureH264  *picture,
2198     GstH264RefPicMarking *ref_pic_marking
2199 )
2200 {
2201     GstVaapiDecoderH264Private * const priv = &decoder->priv;
2202     gint32 i, picNumX;
2203
2204     picNumX = get_picNumX(picture, ref_pic_marking);
2205     i = find_short_term_reference(decoder, picNumX);
2206     if (i < 0)
2207         return;
2208
2209     gst_vaapi_picture_h264_set_reference(priv->short_ref[i], 0,
2210         GST_VAAPI_PICTURE_IS_FRAME(picture));
2211     ARRAY_REMOVE_INDEX(priv->short_ref, i);
2212 }
2213
2214 /* 8.2.5.4.2. Mark long-term reference picture as "unused for reference" */
2215 static void
2216 exec_ref_pic_marking_adaptive_mmco_2(
2217     GstVaapiDecoderH264  *decoder,
2218     GstVaapiPictureH264  *picture,
2219     GstH264RefPicMarking *ref_pic_marking
2220 )
2221 {
2222     GstVaapiDecoderH264Private * const priv = &decoder->priv;
2223     gint32 i;
2224
2225     i = find_long_term_reference(decoder, ref_pic_marking->long_term_pic_num);
2226     if (i < 0)
2227         return;
2228
2229     gst_vaapi_picture_h264_set_reference(priv->long_ref[i], 0,
2230         GST_VAAPI_PICTURE_IS_FRAME(picture));
2231     ARRAY_REMOVE_INDEX(priv->long_ref, i);
2232 }
2233
2234 /* 8.2.5.4.3. Assign LongTermFrameIdx to a short-term reference picture */
2235 static void
2236 exec_ref_pic_marking_adaptive_mmco_3(
2237     GstVaapiDecoderH264  *decoder,
2238     GstVaapiPictureH264  *picture,
2239     GstH264RefPicMarking *ref_pic_marking
2240 )
2241 {
2242     GstVaapiDecoderH264Private * const priv = &decoder->priv;
2243     GstVaapiPictureH264 *ref_picture;
2244     gint32 i, picNumX;
2245
2246     for (i = 0; i < priv->long_ref_count; i++) {
2247         if (priv->long_ref[i]->long_term_frame_idx == ref_pic_marking->long_term_frame_idx)
2248             break;
2249     }
2250     if (i != priv->long_ref_count) {
2251         gst_vaapi_picture_h264_set_reference(priv->long_ref[i], 0, TRUE);
2252         ARRAY_REMOVE_INDEX(priv->long_ref, i);
2253     }
2254
2255     picNumX = get_picNumX(picture, ref_pic_marking);
2256     i = find_short_term_reference(decoder, picNumX);
2257     if (i < 0)
2258         return;
2259
2260     ref_picture = priv->short_ref[i];
2261     ARRAY_REMOVE_INDEX(priv->short_ref, i);
2262     priv->long_ref[priv->long_ref_count++] = ref_picture;
2263
2264     ref_picture->long_term_frame_idx = ref_pic_marking->long_term_frame_idx;
2265     gst_vaapi_picture_h264_set_reference(ref_picture,
2266         GST_VAAPI_PICTURE_FLAG_LONG_TERM_REFERENCE,
2267         GST_VAAPI_PICTURE_IS_COMPLETE(picture));
2268 }
2269
2270 /* 8.2.5.4.4. Mark pictures with LongTermFramIdx > max_long_term_frame_idx
2271  * as "unused for reference" */
2272 static void
2273 exec_ref_pic_marking_adaptive_mmco_4(
2274     GstVaapiDecoderH264  *decoder,
2275     GstVaapiPictureH264  *picture,
2276     GstH264RefPicMarking *ref_pic_marking
2277 )
2278 {
2279     GstVaapiDecoderH264Private * const priv = &decoder->priv;
2280     gint32 i, long_term_frame_idx;
2281
2282     long_term_frame_idx = ref_pic_marking->max_long_term_frame_idx_plus1 - 1;
2283
2284     for (i = 0; i < priv->long_ref_count; i++) {
2285         if (priv->long_ref[i]->long_term_frame_idx <= long_term_frame_idx)
2286             continue;
2287         gst_vaapi_picture_h264_set_reference(priv->long_ref[i], 0, FALSE);
2288         ARRAY_REMOVE_INDEX(priv->long_ref, i);
2289         i--;
2290     }
2291 }
2292
2293 /* 8.2.5.4.5. Mark all reference pictures as "unused for reference" */
2294 static void
2295 exec_ref_pic_marking_adaptive_mmco_5(
2296     GstVaapiDecoderH264  *decoder,
2297     GstVaapiPictureH264  *picture,
2298     GstH264RefPicMarking *ref_pic_marking
2299 )
2300 {
2301     GstVaapiDecoderH264Private * const priv = &decoder->priv;
2302
2303     dpb_flush(decoder);
2304
2305     priv->prev_pic_has_mmco5 = TRUE;
2306
2307     /* The picture shall be inferred to have had frame_num equal to 0 (7.4.3) */
2308     priv->frame_num = 0;
2309     priv->frame_num_offset = 0;
2310     picture->frame_num = 0;
2311
2312     /* Update TopFieldOrderCnt and BottomFieldOrderCnt (8.2.1) */
2313     if (picture->structure != GST_VAAPI_PICTURE_STRUCTURE_BOTTOM_FIELD)
2314         picture->field_poc[TOP_FIELD] -= picture->base.poc;
2315     if (picture->structure != GST_VAAPI_PICTURE_STRUCTURE_TOP_FIELD)
2316         picture->field_poc[BOTTOM_FIELD] -= picture->base.poc;
2317     picture->base.poc = 0;
2318 }
2319
2320 /* 8.2.5.4.6. Assign a long-term frame index to the current picture */
2321 static void
2322 exec_ref_pic_marking_adaptive_mmco_6(
2323     GstVaapiDecoderH264  *decoder,
2324     GstVaapiPictureH264  *picture,
2325     GstH264RefPicMarking *ref_pic_marking
2326 )
2327 {
2328     GstVaapiDecoderH264Private * const priv = &decoder->priv;
2329     guint i;
2330
2331     for (i = 0; i < priv->long_ref_count; i++) {
2332         if (priv->long_ref[i]->long_term_frame_idx == ref_pic_marking->long_term_frame_idx)
2333             break;
2334     }
2335     if (i != priv->long_ref_count) {
2336         gst_vaapi_picture_h264_set_reference(priv->long_ref[i], 0, TRUE);
2337         ARRAY_REMOVE_INDEX(priv->long_ref, i);
2338     }
2339
2340     picture->long_term_frame_idx = ref_pic_marking->long_term_frame_idx;
2341     gst_vaapi_picture_h264_set_reference(picture,
2342         GST_VAAPI_PICTURE_FLAG_LONG_TERM_REFERENCE,
2343         GST_VAAPI_PICTURE_IS_COMPLETE(picture));
2344 }
2345
2346 /* 8.2.5.4. Adaptive memory control decoded reference picture marking process */
2347 static gboolean
2348 exec_ref_pic_marking_adaptive(
2349     GstVaapiDecoderH264     *decoder,
2350     GstVaapiPictureH264     *picture,
2351     GstH264DecRefPicMarking *dec_ref_pic_marking
2352 )
2353 {
2354     guint i;
2355
2356     GST_DEBUG("reference picture marking process (adaptive memory control)");
2357
2358     typedef void (*exec_ref_pic_marking_adaptive_mmco_func)(
2359         GstVaapiDecoderH264  *decoder,
2360         GstVaapiPictureH264  *picture,
2361         GstH264RefPicMarking *ref_pic_marking
2362     );
2363
2364     static const exec_ref_pic_marking_adaptive_mmco_func mmco_funcs[] = {
2365         NULL,
2366         exec_ref_pic_marking_adaptive_mmco_1,
2367         exec_ref_pic_marking_adaptive_mmco_2,
2368         exec_ref_pic_marking_adaptive_mmco_3,
2369         exec_ref_pic_marking_adaptive_mmco_4,
2370         exec_ref_pic_marking_adaptive_mmco_5,
2371         exec_ref_pic_marking_adaptive_mmco_6,
2372     };
2373
2374     for (i = 0; i < dec_ref_pic_marking->n_ref_pic_marking; i++) {
2375         GstH264RefPicMarking * const ref_pic_marking =
2376             &dec_ref_pic_marking->ref_pic_marking[i];
2377
2378         const guint mmco = ref_pic_marking->memory_management_control_operation;
2379         if (mmco < G_N_ELEMENTS(mmco_funcs) && mmco_funcs[mmco])
2380             mmco_funcs[mmco](decoder, picture, ref_pic_marking);
2381         else {
2382             GST_ERROR("unhandled MMCO %u", mmco);
2383             return FALSE;
2384         }
2385     }
2386     return TRUE;
2387 }
2388
2389 /* 8.2.5 - Execute reference picture marking process */
2390 static gboolean
2391 exec_ref_pic_marking(GstVaapiDecoderH264 *decoder, GstVaapiPictureH264 *picture)
2392 {
2393     GstVaapiDecoderH264Private * const priv = &decoder->priv;
2394
2395     priv->prev_pic_has_mmco5 = FALSE;
2396     priv->prev_pic_structure = picture->structure;
2397
2398     if (!GST_VAAPI_PICTURE_IS_REFERENCE(picture))
2399         return TRUE;
2400
2401     if (!GST_VAAPI_PICTURE_IS_IDR(picture)) {
2402         GstH264DecRefPicMarking * const dec_ref_pic_marking =
2403             &picture->last_slice_hdr->dec_ref_pic_marking;
2404         if (dec_ref_pic_marking->adaptive_ref_pic_marking_mode_flag) {
2405             if (!exec_ref_pic_marking_adaptive(decoder, picture, dec_ref_pic_marking))
2406                 return FALSE;
2407         }
2408         else {
2409             if (!exec_ref_pic_marking_sliding_window(decoder))
2410                 return FALSE;
2411         }
2412     }
2413     return TRUE;
2414 }
2415
2416 static void
2417 vaapi_init_picture(VAPictureH264 *pic)
2418 {
2419     pic->picture_id           = VA_INVALID_ID;
2420     pic->frame_idx            = 0;
2421     pic->flags                = VA_PICTURE_H264_INVALID;
2422     pic->TopFieldOrderCnt     = 0;
2423     pic->BottomFieldOrderCnt  = 0;
2424 }
2425
2426 static void
2427 vaapi_fill_picture(VAPictureH264 *pic, GstVaapiPictureH264 *picture,
2428     guint picture_structure)
2429 {
2430     if (!picture_structure)
2431         picture_structure = picture->structure;
2432
2433     pic->picture_id = picture->base.surface_id;
2434     pic->flags = 0;
2435
2436     if (GST_VAAPI_PICTURE_IS_LONG_TERM_REFERENCE(picture)) {
2437         pic->flags |= VA_PICTURE_H264_LONG_TERM_REFERENCE;
2438         pic->frame_idx = picture->long_term_frame_idx;
2439     }
2440     else {
2441         if (GST_VAAPI_PICTURE_IS_SHORT_TERM_REFERENCE(picture))
2442             pic->flags |= VA_PICTURE_H264_SHORT_TERM_REFERENCE;
2443         pic->frame_idx = picture->frame_num;
2444     }
2445
2446     switch (picture_structure) {
2447     case GST_VAAPI_PICTURE_STRUCTURE_FRAME:
2448         pic->TopFieldOrderCnt = picture->field_poc[TOP_FIELD];
2449         pic->BottomFieldOrderCnt = picture->field_poc[BOTTOM_FIELD];
2450         break;
2451     case GST_VAAPI_PICTURE_STRUCTURE_TOP_FIELD:
2452         pic->flags |= VA_PICTURE_H264_TOP_FIELD;
2453         pic->TopFieldOrderCnt = picture->field_poc[TOP_FIELD];
2454         pic->BottomFieldOrderCnt = 0;
2455         break;
2456     case GST_VAAPI_PICTURE_STRUCTURE_BOTTOM_FIELD:
2457         pic->flags |= VA_PICTURE_H264_BOTTOM_FIELD;
2458         pic->BottomFieldOrderCnt = picture->field_poc[BOTTOM_FIELD];
2459         pic->TopFieldOrderCnt = 0;
2460         break;
2461     }
2462 }
2463
2464 static gboolean
2465 fill_picture(GstVaapiDecoderH264 *decoder, GstVaapiPictureH264 *picture)
2466 {
2467     GstVaapiDecoderH264Private * const priv = &decoder->priv;
2468     GstVaapiPicture * const base_picture = &picture->base;
2469     GstH264PPS * const pps = get_pps(decoder);
2470     GstH264SPS * const sps = get_sps(decoder);
2471     VAPictureParameterBufferH264 * const pic_param = base_picture->param;
2472     guint i, n;
2473
2474     /* Fill in VAPictureParameterBufferH264 */
2475     vaapi_fill_picture(&pic_param->CurrPic, picture, 0);
2476
2477     for (i = 0, n = 0; i < priv->dpb_count; i++) {
2478         GstVaapiFrameStore * const fs = priv->dpb[i];
2479         if (gst_vaapi_frame_store_has_reference(fs))
2480             vaapi_fill_picture(&pic_param->ReferenceFrames[n++],
2481                 fs->buffers[0], fs->structure);
2482     }
2483     for (; n < G_N_ELEMENTS(pic_param->ReferenceFrames); n++)
2484         vaapi_init_picture(&pic_param->ReferenceFrames[n]);
2485
2486 #define COPY_FIELD(s, f) \
2487     pic_param->f = (s)->f
2488
2489 #define COPY_BFM(a, s, f) \
2490     pic_param->a.bits.f = (s)->f
2491
2492     pic_param->picture_width_in_mbs_minus1  = priv->mb_width - 1;
2493     pic_param->picture_height_in_mbs_minus1 = priv->mb_height - 1;
2494     pic_param->frame_num                    = priv->frame_num;
2495
2496     COPY_FIELD(sps, bit_depth_luma_minus8);
2497     COPY_FIELD(sps, bit_depth_chroma_minus8);
2498     COPY_FIELD(sps, num_ref_frames);
2499     COPY_FIELD(pps, num_slice_groups_minus1);
2500     COPY_FIELD(pps, slice_group_map_type);
2501     COPY_FIELD(pps, slice_group_change_rate_minus1);
2502     COPY_FIELD(pps, pic_init_qp_minus26);
2503     COPY_FIELD(pps, pic_init_qs_minus26);
2504     COPY_FIELD(pps, chroma_qp_index_offset);
2505     COPY_FIELD(pps, second_chroma_qp_index_offset);
2506
2507     pic_param->seq_fields.value                                         = 0; /* reset all bits */
2508     pic_param->seq_fields.bits.residual_colour_transform_flag           = sps->separate_colour_plane_flag;
2509     pic_param->seq_fields.bits.MinLumaBiPredSize8x8                     = sps->level_idc >= 31; /* A.3.3.2 */
2510
2511     COPY_BFM(seq_fields, sps, chroma_format_idc);
2512     COPY_BFM(seq_fields, sps, gaps_in_frame_num_value_allowed_flag);
2513     COPY_BFM(seq_fields, sps, frame_mbs_only_flag); 
2514     COPY_BFM(seq_fields, sps, mb_adaptive_frame_field_flag); 
2515     COPY_BFM(seq_fields, sps, direct_8x8_inference_flag); 
2516     COPY_BFM(seq_fields, sps, log2_max_frame_num_minus4);
2517     COPY_BFM(seq_fields, sps, pic_order_cnt_type);
2518     COPY_BFM(seq_fields, sps, log2_max_pic_order_cnt_lsb_minus4);
2519     COPY_BFM(seq_fields, sps, delta_pic_order_always_zero_flag);
2520
2521     pic_param->pic_fields.value                                         = 0; /* reset all bits */
2522     pic_param->pic_fields.bits.field_pic_flag                           = GST_VAAPI_PICTURE_IS_INTERLACED(picture);
2523     pic_param->pic_fields.bits.reference_pic_flag                       = GST_VAAPI_PICTURE_IS_REFERENCE(picture);
2524
2525     COPY_BFM(pic_fields, pps, entropy_coding_mode_flag);
2526     COPY_BFM(pic_fields, pps, weighted_pred_flag);
2527     COPY_BFM(pic_fields, pps, weighted_bipred_idc);
2528     COPY_BFM(pic_fields, pps, transform_8x8_mode_flag);
2529     COPY_BFM(pic_fields, pps, constrained_intra_pred_flag);
2530     COPY_BFM(pic_fields, pps, pic_order_present_flag);
2531     COPY_BFM(pic_fields, pps, deblocking_filter_control_present_flag);
2532     COPY_BFM(pic_fields, pps, redundant_pic_cnt_present_flag);
2533     return TRUE;
2534 }
2535
2536 /* Detection of the first VCL NAL unit of a primary coded picture (7.4.1.2.4) */
2537 static gboolean
2538 is_new_picture(GstVaapiParserInfoH264 *pi, GstVaapiParserInfoH264 *prev_pi)
2539 {
2540     GstH264SliceHdr * const slice_hdr = &pi->data.slice_hdr;
2541     GstH264PPS * const pps = slice_hdr->pps;
2542     GstH264SPS * const sps = pps->sequence;
2543     GstH264SliceHdr *prev_slice_hdr;
2544
2545     if (!prev_pi)
2546         return TRUE;
2547     prev_slice_hdr = &prev_pi->data.slice_hdr;
2548
2549 #define CHECK_EXPR(expr, field_name) do {              \
2550         if (!(expr)) {                                 \
2551             GST_DEBUG(field_name " differs in value"); \
2552             return TRUE;                               \
2553         }                                              \
2554     } while (0)
2555
2556 #define CHECK_VALUE(new_slice_hdr, old_slice_hdr, field) \
2557     CHECK_EXPR(((new_slice_hdr)->field == (old_slice_hdr)->field), #field)
2558
2559     /* frame_num differs in value, regardless of inferred values to 0 */
2560     CHECK_VALUE(slice_hdr, prev_slice_hdr, frame_num);
2561
2562     /* pic_parameter_set_id differs in value */
2563     CHECK_VALUE(slice_hdr, prev_slice_hdr, pps);
2564
2565     /* field_pic_flag differs in value */
2566     CHECK_VALUE(slice_hdr, prev_slice_hdr, field_pic_flag);
2567
2568     /* bottom_field_flag is present in both and differs in value */
2569     if (slice_hdr->field_pic_flag && prev_slice_hdr->field_pic_flag)
2570         CHECK_VALUE(slice_hdr, prev_slice_hdr, bottom_field_flag);
2571
2572     /* nal_ref_idc differs in value with one of the nal_ref_idc values is 0 */
2573     CHECK_EXPR((pi->nalu.ref_idc != 0) ==
2574                (prev_pi->nalu.ref_idc != 0), "nal_ref_idc");
2575
2576     /* POC type is 0 for both and either pic_order_cnt_lsb differs in
2577        value or delta_pic_order_cnt_bottom differs in value */
2578     if (sps->pic_order_cnt_type == 0) {
2579         CHECK_VALUE(slice_hdr, prev_slice_hdr, pic_order_cnt_lsb);
2580         if (pps->pic_order_present_flag && !slice_hdr->field_pic_flag)
2581             CHECK_VALUE(slice_hdr, prev_slice_hdr, delta_pic_order_cnt_bottom);
2582     }
2583
2584     /* POC type is 1 for both and either delta_pic_order_cnt[0]
2585        differs in value or delta_pic_order_cnt[1] differs in value */
2586     else if (sps->pic_order_cnt_type == 1) {
2587         CHECK_VALUE(slice_hdr, prev_slice_hdr, delta_pic_order_cnt[0]);
2588         CHECK_VALUE(slice_hdr, prev_slice_hdr, delta_pic_order_cnt[1]);
2589     }
2590
2591     /* IdrPicFlag differs in value */
2592     CHECK_VALUE(&pi->nalu, &prev_pi->nalu, idr_pic_flag);
2593
2594     /* IdrPicFlag is equal to 1 for both and idr_pic_id differs in value */
2595     if (pi->nalu.idr_pic_flag)
2596         CHECK_VALUE(slice_hdr, prev_slice_hdr, idr_pic_id);
2597
2598 #undef CHECK_EXPR
2599 #undef CHECK_VALUE
2600     return FALSE;
2601 }
2602
2603 static GstVaapiDecoderStatus
2604 decode_picture(GstVaapiDecoderH264 *decoder, GstVaapiDecoderUnit *unit)
2605 {
2606     GstVaapiDecoderH264Private * const priv = &decoder->priv;
2607     GstVaapiParserInfoH264 * const pi = unit->parsed_info;
2608     GstH264SliceHdr * const slice_hdr = &pi->data.slice_hdr;
2609     GstH264PPS * const pps = ensure_pps(decoder, slice_hdr->pps);
2610     GstH264SPS * const sps = ensure_sps(decoder, slice_hdr->pps->sequence);
2611     GstVaapiPictureH264 *picture;
2612     GstVaapiDecoderStatus status;
2613
2614     g_return_val_if_fail(pps != NULL, GST_VAAPI_DECODER_STATUS_ERROR_UNKNOWN);
2615     g_return_val_if_fail(sps != NULL, GST_VAAPI_DECODER_STATUS_ERROR_UNKNOWN);
2616
2617     status = ensure_context(decoder, sps);
2618     if (status != GST_VAAPI_DECODER_STATUS_SUCCESS)
2619         return status;
2620
2621     priv->decoder_state = 0;
2622
2623     if (priv->current_picture) {
2624         /* Re-use current picture where the first field was decoded */
2625         picture = gst_vaapi_picture_h264_new_field(priv->current_picture);
2626         if (!picture) {
2627             GST_ERROR("failed to allocate field picture");
2628             return GST_VAAPI_DECODER_STATUS_ERROR_ALLOCATION_FAILED;
2629         }
2630     }
2631     else {
2632         /* Create new picture */
2633         picture = gst_vaapi_picture_h264_new(decoder);
2634         if (!picture) {
2635             GST_ERROR("failed to allocate picture");
2636             return GST_VAAPI_DECODER_STATUS_ERROR_ALLOCATION_FAILED;
2637         }
2638     }
2639     gst_vaapi_picture_replace(&priv->current_picture, picture);
2640     gst_vaapi_picture_unref(picture);
2641
2642     /* Update cropping rectangle */
2643     if (sps->frame_cropping_flag) {
2644         GstVaapiRectangle crop_rect;
2645         crop_rect.x = sps->crop_rect_x;
2646         crop_rect.y = sps->crop_rect_y;
2647         crop_rect.width = sps->crop_rect_width;
2648         crop_rect.height = sps->crop_rect_height;
2649         gst_vaapi_picture_set_crop_rect(&picture->base, &crop_rect);
2650     }
2651
2652     status = ensure_quant_matrix(decoder, picture);
2653     if (status != GST_VAAPI_DECODER_STATUS_SUCCESS) {
2654         GST_ERROR("failed to reset quantizer matrix");
2655         return status;
2656     }
2657
2658     if (!init_picture(decoder, picture, pi))
2659         return GST_VAAPI_DECODER_STATUS_ERROR_UNKNOWN;
2660     if (!fill_picture(decoder, picture))
2661         return GST_VAAPI_DECODER_STATUS_ERROR_UNKNOWN;
2662
2663     priv->decoder_state = pi->state;
2664     return GST_VAAPI_DECODER_STATUS_SUCCESS;
2665 }
2666
2667 static inline guint
2668 get_slice_data_bit_offset(GstH264SliceHdr *slice_hdr, guint nal_header_bytes)
2669 {
2670     guint epb_count;
2671
2672     epb_count = slice_hdr->n_emulation_prevention_bytes;
2673     return 8 * nal_header_bytes + slice_hdr->header_size - epb_count * 8;
2674 }
2675
2676 static gboolean
2677 fill_pred_weight_table(GstVaapiDecoderH264 *decoder,
2678     GstVaapiSlice *slice, GstH264SliceHdr *slice_hdr)
2679 {
2680     VASliceParameterBufferH264 * const slice_param = slice->param;
2681     GstH264PPS * const pps = get_pps(decoder);
2682     GstH264SPS * const sps = get_sps(decoder);
2683     GstH264PredWeightTable * const w = &slice_hdr->pred_weight_table;
2684     guint num_weight_tables = 0;
2685     gint i, j;
2686
2687     if (pps->weighted_pred_flag &&
2688         (GST_H264_IS_P_SLICE(slice_hdr) || GST_H264_IS_SP_SLICE(slice_hdr)))
2689         num_weight_tables = 1;
2690     else if (pps->weighted_bipred_idc == 1 && GST_H264_IS_B_SLICE(slice_hdr))
2691         num_weight_tables = 2;
2692     else
2693         num_weight_tables = 0;
2694
2695     slice_param->luma_log2_weight_denom   = 0;
2696     slice_param->chroma_log2_weight_denom = 0;
2697     slice_param->luma_weight_l0_flag      = 0;
2698     slice_param->chroma_weight_l0_flag    = 0;
2699     slice_param->luma_weight_l1_flag      = 0;
2700     slice_param->chroma_weight_l1_flag    = 0;
2701
2702     if (num_weight_tables < 1)
2703         return TRUE;
2704
2705     slice_param->luma_log2_weight_denom   = w->luma_log2_weight_denom;
2706     slice_param->chroma_log2_weight_denom = w->chroma_log2_weight_denom;
2707
2708     slice_param->luma_weight_l0_flag = 1;
2709     for (i = 0; i <= slice_param->num_ref_idx_l0_active_minus1; i++) {
2710         slice_param->luma_weight_l0[i] = w->luma_weight_l0[i];
2711         slice_param->luma_offset_l0[i] = w->luma_offset_l0[i];
2712     }
2713
2714     slice_param->chroma_weight_l0_flag = sps->chroma_array_type != 0;
2715     if (slice_param->chroma_weight_l0_flag) {
2716         for (i = 0; i <= slice_param->num_ref_idx_l0_active_minus1; i++) {
2717             for (j = 0; j < 2; j++) {
2718                 slice_param->chroma_weight_l0[i][j] = w->chroma_weight_l0[i][j];
2719                 slice_param->chroma_offset_l0[i][j] = w->chroma_offset_l0[i][j];
2720             }
2721         }
2722     }
2723
2724     if (num_weight_tables < 2)
2725         return TRUE;
2726
2727     slice_param->luma_weight_l1_flag = 1;
2728     for (i = 0; i <= slice_param->num_ref_idx_l1_active_minus1; i++) {
2729         slice_param->luma_weight_l1[i] = w->luma_weight_l1[i];
2730         slice_param->luma_offset_l1[i] = w->luma_offset_l1[i];
2731     }
2732
2733     slice_param->chroma_weight_l1_flag = sps->chroma_array_type != 0;
2734     if (slice_param->chroma_weight_l1_flag) {
2735         for (i = 0; i <= slice_param->num_ref_idx_l1_active_minus1; i++) {
2736             for (j = 0; j < 2; j++) {
2737                 slice_param->chroma_weight_l1[i][j] = w->chroma_weight_l1[i][j];
2738                 slice_param->chroma_offset_l1[i][j] = w->chroma_offset_l1[i][j];
2739             }
2740         }
2741     }
2742     return TRUE;
2743 }
2744
2745 static gboolean
2746 fill_RefPicList(GstVaapiDecoderH264 *decoder,
2747     GstVaapiSlice *slice, GstH264SliceHdr *slice_hdr)
2748 {
2749     GstVaapiDecoderH264Private * const priv = &decoder->priv;
2750     VASliceParameterBufferH264 * const slice_param = slice->param;
2751     guint i, num_ref_lists = 0;
2752
2753     slice_param->num_ref_idx_l0_active_minus1 = 0;
2754     slice_param->num_ref_idx_l1_active_minus1 = 0;
2755
2756     if (GST_H264_IS_B_SLICE(slice_hdr))
2757         num_ref_lists = 2;
2758     else if (GST_H264_IS_I_SLICE(slice_hdr))
2759         num_ref_lists = 0;
2760     else
2761         num_ref_lists = 1;
2762
2763     if (num_ref_lists < 1)
2764         return TRUE;
2765
2766     slice_param->num_ref_idx_l0_active_minus1 =
2767         slice_hdr->num_ref_idx_l0_active_minus1;
2768
2769     for (i = 0; i < priv->RefPicList0_count && priv->RefPicList0[i]; i++)
2770         vaapi_fill_picture(&slice_param->RefPicList0[i], priv->RefPicList0[i], 0);
2771     for (; i <= slice_param->num_ref_idx_l0_active_minus1; i++)
2772         vaapi_init_picture(&slice_param->RefPicList0[i]);
2773
2774     if (num_ref_lists < 2)
2775         return TRUE;
2776
2777     slice_param->num_ref_idx_l1_active_minus1 =
2778         slice_hdr->num_ref_idx_l1_active_minus1;
2779
2780     for (i = 0; i < priv->RefPicList1_count && priv->RefPicList1[i]; i++)
2781         vaapi_fill_picture(&slice_param->RefPicList1[i], priv->RefPicList1[i], 0);
2782     for (; i <= slice_param->num_ref_idx_l1_active_minus1; i++)
2783         vaapi_init_picture(&slice_param->RefPicList1[i]);
2784     return TRUE;
2785 }
2786
2787 static gboolean
2788 fill_slice(GstVaapiDecoderH264 *decoder,
2789     GstVaapiSlice *slice, GstVaapiParserInfoH264 *pi)
2790 {
2791     VASliceParameterBufferH264 * const slice_param = slice->param;
2792     GstH264SliceHdr * const slice_hdr = &pi->data.slice_hdr;
2793
2794     /* Fill in VASliceParameterBufferH264 */
2795     slice_param->slice_data_bit_offset =
2796         get_slice_data_bit_offset(slice_hdr, pi->nalu.header_bytes);
2797     slice_param->first_mb_in_slice              = slice_hdr->first_mb_in_slice;
2798     slice_param->slice_type                     = slice_hdr->type % 5;
2799     slice_param->direct_spatial_mv_pred_flag    = slice_hdr->direct_spatial_mv_pred_flag;
2800     slice_param->cabac_init_idc                 = slice_hdr->cabac_init_idc;
2801     slice_param->slice_qp_delta                 = slice_hdr->slice_qp_delta;
2802     slice_param->disable_deblocking_filter_idc  = slice_hdr->disable_deblocking_filter_idc;
2803     slice_param->slice_alpha_c0_offset_div2     = slice_hdr->slice_alpha_c0_offset_div2;
2804     slice_param->slice_beta_offset_div2         = slice_hdr->slice_beta_offset_div2;
2805
2806     if (!fill_RefPicList(decoder, slice, slice_hdr))
2807         return FALSE;
2808     if (!fill_pred_weight_table(decoder, slice, slice_hdr))
2809         return FALSE;
2810     return TRUE;
2811 }
2812
2813 static GstVaapiDecoderStatus
2814 decode_slice(GstVaapiDecoderH264 *decoder, GstVaapiDecoderUnit *unit)
2815 {
2816     GstVaapiDecoderH264Private * const priv = &decoder->priv;
2817     GstVaapiParserInfoH264 * const pi = unit->parsed_info;
2818     GstVaapiPictureH264 * const picture = priv->current_picture;
2819     GstH264SliceHdr * const slice_hdr = &pi->data.slice_hdr;
2820     GstVaapiSlice *slice;
2821     GstBuffer * const buffer =
2822         GST_VAAPI_DECODER_CODEC_FRAME(decoder)->input_buffer;
2823     GstMapInfo map_info;
2824
2825     GST_DEBUG("slice (%u bytes)", pi->nalu.size);
2826
2827     if (!is_valid_state(pi->state,
2828             GST_H264_VIDEO_STATE_VALID_PICTURE_HEADERS)) {
2829         GST_WARNING("failed to receive enough headers to decode slice");
2830         return GST_VAAPI_DECODER_STATUS_SUCCESS;
2831     }
2832
2833     if (!ensure_pps(decoder, slice_hdr->pps)) {
2834         GST_ERROR("failed to activate PPS");
2835         return GST_VAAPI_DECODER_STATUS_ERROR_UNKNOWN;
2836     }
2837
2838     if (!ensure_sps(decoder, slice_hdr->pps->sequence)) {
2839         GST_ERROR("failed to activate SPS");
2840         return GST_VAAPI_DECODER_STATUS_ERROR_UNKNOWN;
2841     }
2842
2843     if (!gst_buffer_map(buffer, &map_info, GST_MAP_READ)) {
2844         GST_ERROR("failed to map buffer");
2845         return GST_VAAPI_DECODER_STATUS_ERROR_UNKNOWN;
2846     }
2847
2848     slice = GST_VAAPI_SLICE_NEW(H264, decoder,
2849         (map_info.data + unit->offset + pi->nalu.offset), pi->nalu.size);
2850     gst_buffer_unmap(buffer, &map_info);
2851     if (!slice) {
2852         GST_ERROR("failed to allocate slice");
2853         return GST_VAAPI_DECODER_STATUS_ERROR_ALLOCATION_FAILED;
2854     }
2855
2856     init_picture_refs(decoder, picture, slice_hdr);
2857     if (!fill_slice(decoder, slice, pi)) {
2858         gst_vaapi_mini_object_unref(GST_VAAPI_MINI_OBJECT(slice));
2859         return GST_VAAPI_DECODER_STATUS_ERROR_UNKNOWN;
2860     }
2861
2862     gst_vaapi_picture_add_slice(GST_VAAPI_PICTURE_CAST(picture), slice);
2863     picture->last_slice_hdr = slice_hdr;
2864     priv->decoder_state |= GST_H264_VIDEO_STATE_GOT_SLICE;
2865     return GST_VAAPI_DECODER_STATUS_SUCCESS;
2866 }
2867
2868 static inline gint
2869 scan_for_start_code(GstAdapter *adapter, guint ofs, guint size, guint32 *scp)
2870 {
2871     return (gint)gst_adapter_masked_scan_uint32_peek(adapter,
2872                                                      0xffffff00, 0x00000100,
2873                                                      ofs, size,
2874                                                      scp);
2875 }
2876
2877 static GstVaapiDecoderStatus
2878 decode_unit(GstVaapiDecoderH264 *decoder, GstVaapiDecoderUnit *unit)
2879 {
2880     GstVaapiDecoderH264Private * const priv = &decoder->priv;
2881     GstVaapiParserInfoH264 * const pi = unit->parsed_info;
2882     GstVaapiDecoderStatus status;
2883
2884     priv->decoder_state |= pi->state;
2885     switch (pi->nalu.type) {
2886     case GST_H264_NAL_SPS:
2887         status = decode_sps(decoder, unit);
2888         break;
2889     case GST_H264_NAL_PPS:
2890         status = decode_pps(decoder, unit);
2891         break;
2892     case GST_H264_NAL_SLICE_IDR:
2893         /* fall-through. IDR specifics are handled in init_picture() */
2894     case GST_H264_NAL_SLICE:
2895         status = decode_slice(decoder, unit);
2896         break;
2897     case GST_H264_NAL_SEQ_END:
2898     case GST_H264_NAL_STREAM_END:
2899         status = decode_sequence_end(decoder);
2900         break;
2901     case GST_H264_NAL_SEI:
2902         status = GST_VAAPI_DECODER_STATUS_SUCCESS;
2903         break;
2904     default:
2905         GST_WARNING("unsupported NAL unit type %d", pi->nalu.type);
2906         status = GST_VAAPI_DECODER_STATUS_ERROR_BITSTREAM_PARSER;
2907         break;
2908     }
2909     return status;
2910 }
2911
2912 static GstVaapiDecoderStatus
2913 gst_vaapi_decoder_h264_decode_codec_data(GstVaapiDecoder *base_decoder,
2914     const guchar *buf, guint buf_size)
2915 {
2916     GstVaapiDecoderH264 * const decoder =
2917         GST_VAAPI_DECODER_H264_CAST(base_decoder);
2918     GstVaapiDecoderH264Private * const priv = &decoder->priv;
2919     GstVaapiDecoderStatus status;
2920     GstVaapiDecoderUnit unit;
2921     GstVaapiParserInfoH264 *pi = NULL;
2922     GstH264ParserResult result;
2923     guint i, ofs, num_sps, num_pps;
2924
2925     unit.parsed_info = NULL;
2926
2927     if (buf_size < 8)
2928         return GST_VAAPI_DECODER_STATUS_ERROR_NO_DATA;
2929
2930     if (buf[0] != 1) {
2931         GST_ERROR("failed to decode codec-data, not in avcC format");
2932         return GST_VAAPI_DECODER_STATUS_ERROR_BITSTREAM_PARSER;
2933     }
2934
2935     priv->nal_length_size = (buf[4] & 0x03) + 1;
2936
2937     num_sps = buf[5] & 0x1f;
2938     ofs = 6;
2939
2940     for (i = 0; i < num_sps; i++) {
2941         pi = gst_vaapi_parser_info_h264_new();
2942         if (!pi)
2943             return GST_VAAPI_DECODER_STATUS_ERROR_ALLOCATION_FAILED;
2944         unit.parsed_info = pi;
2945
2946         result = gst_h264_parser_identify_nalu_avc(
2947             priv->parser,
2948             buf, ofs, buf_size, 2,
2949             &pi->nalu
2950         );
2951         if (result != GST_H264_PARSER_OK) {
2952             status = get_status(result);
2953             goto cleanup;
2954         }
2955
2956         status = parse_sps(decoder, &unit);
2957         if (status != GST_VAAPI_DECODER_STATUS_SUCCESS)
2958             goto cleanup;
2959         ofs = pi->nalu.offset + pi->nalu.size;
2960
2961         status = decode_sps(decoder, &unit);
2962         if (status != GST_VAAPI_DECODER_STATUS_SUCCESS)
2963             goto cleanup;
2964         gst_vaapi_parser_info_h264_replace(&pi, NULL);
2965     }
2966
2967     num_pps = buf[ofs];
2968     ofs++;
2969
2970     for (i = 0; i < num_pps; i++) {
2971         pi = gst_vaapi_parser_info_h264_new();
2972         if (!pi)
2973             return GST_VAAPI_DECODER_STATUS_ERROR_ALLOCATION_FAILED;
2974         unit.parsed_info = pi;
2975
2976         result = gst_h264_parser_identify_nalu_avc(
2977             priv->parser,
2978             buf, ofs, buf_size, 2,
2979             &pi->nalu
2980         );
2981         if (result != GST_H264_PARSER_OK) {
2982             status = get_status(result);
2983             goto cleanup;
2984         }
2985
2986         status = parse_pps(decoder, &unit);
2987         if (status != GST_VAAPI_DECODER_STATUS_SUCCESS)
2988             goto cleanup;
2989         ofs = pi->nalu.offset + pi->nalu.size;
2990
2991         status = decode_pps(decoder, &unit);
2992         if (status != GST_VAAPI_DECODER_STATUS_SUCCESS)
2993             goto cleanup;
2994         gst_vaapi_parser_info_h264_replace(&pi, NULL);
2995     }
2996
2997     priv->is_avcC = TRUE;
2998     status = GST_VAAPI_DECODER_STATUS_SUCCESS;
2999
3000 cleanup:
3001     gst_vaapi_parser_info_h264_replace(&pi, NULL);
3002     return status;
3003 }
3004
3005 static GstVaapiDecoderStatus
3006 ensure_decoder(GstVaapiDecoderH264 *decoder)
3007 {
3008     GstVaapiDecoderH264Private * const priv = &decoder->priv;
3009     GstVaapiDecoderStatus status;
3010
3011     if (!priv->is_opened) {
3012         priv->is_opened = gst_vaapi_decoder_h264_open(decoder);
3013         if (!priv->is_opened)
3014             return GST_VAAPI_DECODER_STATUS_ERROR_UNSUPPORTED_CODEC;
3015
3016         status = gst_vaapi_decoder_decode_codec_data(
3017             GST_VAAPI_DECODER_CAST(decoder));
3018         if (status != GST_VAAPI_DECODER_STATUS_SUCCESS)
3019             return status;
3020     }
3021     return GST_VAAPI_DECODER_STATUS_SUCCESS;
3022 }
3023
3024 static GstVaapiDecoderStatus
3025 gst_vaapi_decoder_h264_parse(GstVaapiDecoder *base_decoder,
3026     GstAdapter *adapter, gboolean at_eos, GstVaapiDecoderUnit *unit)
3027 {
3028     GstVaapiDecoderH264 * const decoder =
3029         GST_VAAPI_DECODER_H264_CAST(base_decoder);
3030     GstVaapiDecoderH264Private * const priv = &decoder->priv;
3031     GstVaapiParserState * const ps = GST_VAAPI_PARSER_STATE(base_decoder);
3032     GstVaapiParserInfoH264 *pi;
3033     GstVaapiDecoderStatus status;
3034     GstH264ParserResult result;
3035     guchar *buf;
3036     guint i, size, buf_size, nalu_size, flags;
3037     guint32 start_code;
3038     gint ofs, ofs2;
3039
3040     status = ensure_decoder(decoder);
3041     if (status != GST_VAAPI_DECODER_STATUS_SUCCESS)
3042         return status;
3043
3044     size = gst_adapter_available(adapter);
3045
3046     if (priv->is_avcC) {
3047         if (size < priv->nal_length_size)
3048             return GST_VAAPI_DECODER_STATUS_ERROR_NO_DATA;
3049
3050         buf = (guchar *)&start_code;
3051         g_assert(priv->nal_length_size <= sizeof(start_code));
3052         gst_adapter_copy(adapter, buf, 0, priv->nal_length_size);
3053
3054         nalu_size = 0;
3055         for (i = 0; i < priv->nal_length_size; i++)
3056             nalu_size = (nalu_size << 8) | buf[i];
3057
3058         buf_size = priv->nal_length_size + nalu_size;
3059         if (size < buf_size)
3060             return GST_VAAPI_DECODER_STATUS_ERROR_NO_DATA;
3061     }
3062     else {
3063         if (size < 4)
3064             return GST_VAAPI_DECODER_STATUS_ERROR_NO_DATA;
3065
3066         ofs = scan_for_start_code(adapter, 0, size, NULL);
3067         if (ofs < 0)
3068             return GST_VAAPI_DECODER_STATUS_ERROR_NO_DATA;
3069
3070         if (ofs > 0) {
3071             gst_adapter_flush(adapter, ofs);
3072             size -= ofs;
3073         }
3074
3075         ofs2 = ps->input_offset2 - ofs - 4;
3076         if (ofs2 < 4)
3077             ofs2 = 4;
3078
3079         ofs = G_UNLIKELY(size < ofs2 + 4) ? -1 :
3080             scan_for_start_code(adapter, ofs2, size - ofs2, NULL);
3081         if (ofs < 0) {
3082             // Assume the whole NAL unit is present if end-of-stream
3083             if (!at_eos) {
3084                 ps->input_offset2 = size;
3085                 return GST_VAAPI_DECODER_STATUS_ERROR_NO_DATA;
3086             }
3087             ofs = size;
3088         }
3089         buf_size = ofs;
3090     }
3091     ps->input_offset2 = 0;
3092
3093     buf = (guchar *)gst_adapter_map(adapter, buf_size);
3094     if (!buf)
3095         return GST_VAAPI_DECODER_STATUS_ERROR_NO_DATA;
3096
3097     unit->size = buf_size;
3098
3099     pi = gst_vaapi_parser_info_h264_new();
3100     if (!pi)
3101         return GST_VAAPI_DECODER_STATUS_ERROR_ALLOCATION_FAILED;
3102
3103     gst_vaapi_decoder_unit_set_parsed_info(unit,
3104         pi, (GDestroyNotify)gst_vaapi_mini_object_unref);
3105
3106     if (priv->is_avcC)
3107         result = gst_h264_parser_identify_nalu_avc(priv->parser,
3108             buf, 0, buf_size, priv->nal_length_size, &pi->nalu);
3109     else
3110         result = gst_h264_parser_identify_nalu_unchecked(priv->parser,
3111             buf, 0, buf_size, &pi->nalu);
3112     status = get_status(result);
3113     if (status != GST_VAAPI_DECODER_STATUS_SUCCESS)
3114         return status;
3115
3116     switch (pi->nalu.type) {
3117     case GST_H264_NAL_SPS:
3118         status = parse_sps(decoder, unit);
3119         break;
3120     case GST_H264_NAL_PPS:
3121         status = parse_pps(decoder, unit);
3122         break;
3123     case GST_H264_NAL_SEI:
3124         status = parse_sei(decoder, unit);
3125         break;
3126     case GST_H264_NAL_SLICE_IDR:
3127     case GST_H264_NAL_SLICE:
3128         status = parse_slice(decoder, unit);
3129         break;
3130     default:
3131         status = GST_VAAPI_DECODER_STATUS_SUCCESS;
3132         break;
3133     }
3134     if (status != GST_VAAPI_DECODER_STATUS_SUCCESS)
3135         return status;
3136
3137     flags = 0;
3138     switch (pi->nalu.type) {
3139     case GST_H264_NAL_AU_DELIMITER:
3140         flags |= GST_VAAPI_DECODER_UNIT_FLAG_FRAME_START;
3141         /* fall-through */
3142     case GST_H264_NAL_FILLER_DATA:
3143         flags |= GST_VAAPI_DECODER_UNIT_FLAG_SKIP;
3144         break;
3145     case GST_H264_NAL_STREAM_END:
3146         flags |= GST_VAAPI_DECODER_UNIT_FLAG_STREAM_END;
3147         /* fall-through */
3148     case GST_H264_NAL_SEQ_END:
3149         flags |= GST_VAAPI_DECODER_UNIT_FLAG_FRAME_END;
3150         break;
3151     case GST_H264_NAL_SPS:
3152     case GST_H264_NAL_PPS:
3153     case GST_H264_NAL_SEI:
3154         flags |= GST_VAAPI_DECODER_UNIT_FLAG_FRAME_START;
3155         break;
3156     case GST_H264_NAL_SLICE_IDR:
3157     case GST_H264_NAL_SLICE:
3158         flags |= GST_VAAPI_DECODER_UNIT_FLAG_SLICE;
3159         if (is_new_picture(pi, priv->prev_slice_pi))
3160             flags |= GST_VAAPI_DECODER_UNIT_FLAG_FRAME_START;
3161         gst_vaapi_parser_info_h264_replace(&priv->prev_slice_pi, pi);
3162         break;
3163     case GST_H264_NAL_SPS_EXT:
3164     case GST_H264_NAL_SLICE_AUX:
3165         /* skip SPS extension and auxiliary slice for now */
3166         flags |= GST_VAAPI_DECODER_UNIT_FLAG_SKIP;
3167         break;
3168     default:
3169         if (pi->nalu.type >= 14 && pi->nalu.type <= 18)
3170             flags |= GST_VAAPI_DECODER_UNIT_FLAG_FRAME_START;
3171         break;
3172     }
3173     GST_VAAPI_DECODER_UNIT_FLAG_SET(unit, flags);
3174
3175     pi->nalu.data = NULL;
3176     pi->state = priv->parser_state;
3177     return GST_VAAPI_DECODER_STATUS_SUCCESS;
3178 }
3179
3180 static GstVaapiDecoderStatus
3181 gst_vaapi_decoder_h264_decode(GstVaapiDecoder *base_decoder,
3182     GstVaapiDecoderUnit *unit)
3183 {
3184     GstVaapiDecoderH264 * const decoder =
3185         GST_VAAPI_DECODER_H264_CAST(base_decoder);
3186     GstVaapiDecoderStatus status;
3187
3188     status = ensure_decoder(decoder);
3189     if (status != GST_VAAPI_DECODER_STATUS_SUCCESS)
3190         return status;
3191     return decode_unit(decoder, unit);
3192 }
3193
3194 static GstVaapiDecoderStatus
3195 gst_vaapi_decoder_h264_start_frame(GstVaapiDecoder *base_decoder,
3196     GstVaapiDecoderUnit *unit)
3197 {
3198     GstVaapiDecoderH264 * const decoder =
3199         GST_VAAPI_DECODER_H264_CAST(base_decoder);
3200
3201     return decode_picture(decoder, unit);
3202 }
3203
3204 static GstVaapiDecoderStatus
3205 gst_vaapi_decoder_h264_end_frame(GstVaapiDecoder *base_decoder)
3206 {
3207     GstVaapiDecoderH264 * const decoder =
3208         GST_VAAPI_DECODER_H264_CAST(base_decoder);
3209
3210     return decode_current_picture(decoder);
3211 }
3212
3213 static GstVaapiDecoderStatus
3214 gst_vaapi_decoder_h264_flush(GstVaapiDecoder *base_decoder)
3215 {
3216     GstVaapiDecoderH264 * const decoder =
3217         GST_VAAPI_DECODER_H264_CAST(base_decoder);
3218
3219     dpb_flush(decoder);
3220     return GST_VAAPI_DECODER_STATUS_SUCCESS;
3221 }
3222
3223 static void
3224 gst_vaapi_decoder_h264_class_init(GstVaapiDecoderH264Class *klass)
3225 {
3226     GstVaapiMiniObjectClass * const object_class =
3227         GST_VAAPI_MINI_OBJECT_CLASS(klass);
3228     GstVaapiDecoderClass * const decoder_class = GST_VAAPI_DECODER_CLASS(klass);
3229
3230     object_class->size          = sizeof(GstVaapiDecoderH264);
3231     object_class->finalize      = (GDestroyNotify)gst_vaapi_decoder_finalize;
3232
3233     decoder_class->create       = gst_vaapi_decoder_h264_create;
3234     decoder_class->destroy      = gst_vaapi_decoder_h264_destroy;
3235     decoder_class->parse        = gst_vaapi_decoder_h264_parse;
3236     decoder_class->decode       = gst_vaapi_decoder_h264_decode;
3237     decoder_class->start_frame  = gst_vaapi_decoder_h264_start_frame;
3238     decoder_class->end_frame    = gst_vaapi_decoder_h264_end_frame;
3239     decoder_class->flush        = gst_vaapi_decoder_h264_flush;
3240
3241     decoder_class->decode_codec_data =
3242         gst_vaapi_decoder_h264_decode_codec_data;
3243 }
3244
3245 static inline const GstVaapiDecoderClass *
3246 gst_vaapi_decoder_h264_class(void)
3247 {
3248     static GstVaapiDecoderH264Class g_class;
3249     static gsize g_class_init = FALSE;
3250
3251     if (g_once_init_enter(&g_class_init)) {
3252         gst_vaapi_decoder_h264_class_init(&g_class);
3253         g_once_init_leave(&g_class_init, TRUE);
3254     }
3255     return GST_VAAPI_DECODER_CLASS(&g_class);
3256 }
3257
3258 /**
3259  * gst_vaapi_decoder_h264_new:
3260  * @display: a #GstVaapiDisplay
3261  * @caps: a #GstCaps holding codec information
3262  *
3263  * Creates a new #GstVaapiDecoder for MPEG-2 decoding.  The @caps can
3264  * hold extra information like codec-data and pictured coded size.
3265  *
3266  * Return value: the newly allocated #GstVaapiDecoder object
3267  */
3268 GstVaapiDecoder *
3269 gst_vaapi_decoder_h264_new(GstVaapiDisplay *display, GstCaps *caps)
3270 {
3271     return gst_vaapi_decoder_new(gst_vaapi_decoder_h264_class(), display, caps);
3272 }