decoder: h264: skip SPS extension and auxiliary slice NALs.
[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     GstVaapiPicture * const base_picture = &picture->base;
2037     guint i, num_refs;
2038
2039     init_picture_ref_lists(decoder);
2040     init_picture_refs_pic_num(decoder, picture, slice_hdr);
2041
2042     priv->RefPicList0_count = 0;
2043     priv->RefPicList1_count = 0;
2044
2045     switch (base_picture->type) {
2046     case GST_VAAPI_PICTURE_TYPE_P:
2047     case GST_VAAPI_PICTURE_TYPE_SP:
2048         init_picture_refs_p_slice(decoder, picture, slice_hdr);
2049         break;
2050     case GST_VAAPI_PICTURE_TYPE_B:
2051         init_picture_refs_b_slice(decoder, picture, slice_hdr);
2052         break;
2053     default:
2054         break;
2055     }
2056
2057     exec_picture_refs_modification(decoder, picture, slice_hdr);
2058
2059     switch (base_picture->type) {
2060     case GST_VAAPI_PICTURE_TYPE_B:
2061         num_refs = 1 + slice_hdr->num_ref_idx_l1_active_minus1;
2062         for (i = priv->RefPicList1_count; i < num_refs; i++)
2063             priv->RefPicList1[i] = NULL;
2064         priv->RefPicList1_count = num_refs;
2065
2066         // fall-through
2067     case GST_VAAPI_PICTURE_TYPE_P:
2068     case GST_VAAPI_PICTURE_TYPE_SP:
2069         num_refs = 1 + slice_hdr->num_ref_idx_l0_active_minus1;
2070         for (i = priv->RefPicList0_count; i < num_refs; i++)
2071             priv->RefPicList0[i] = NULL;
2072         priv->RefPicList0_count = num_refs;
2073         break;
2074     default:
2075         break;
2076     }
2077 }
2078
2079 static gboolean
2080 init_picture(
2081     GstVaapiDecoderH264 *decoder,
2082     GstVaapiPictureH264 *picture, GstVaapiParserInfoH264 *pi)
2083 {
2084     GstVaapiDecoderH264Private * const priv = &decoder->priv;
2085     GstVaapiPicture * const base_picture = &picture->base;
2086     GstH264SliceHdr * const slice_hdr = &pi->data.slice_hdr;
2087
2088     priv->prev_frame_num        = priv->frame_num;
2089     priv->frame_num             = slice_hdr->frame_num;
2090     picture->frame_num          = priv->frame_num;
2091     picture->frame_num_wrap     = priv->frame_num;
2092     picture->output_flag        = TRUE; /* XXX: conformant to Annex A only */
2093     base_picture->pts           = GST_VAAPI_DECODER_CODEC_FRAME(decoder)->pts;
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 slice type */
2103     switch (slice_hdr->type % 5) {
2104     case GST_H264_P_SLICE:
2105         base_picture->type = GST_VAAPI_PICTURE_TYPE_P;
2106         break;
2107     case GST_H264_B_SLICE:
2108         base_picture->type = GST_VAAPI_PICTURE_TYPE_B;
2109         break;
2110     case GST_H264_I_SLICE:
2111         base_picture->type = GST_VAAPI_PICTURE_TYPE_I;
2112         break;
2113     case GST_H264_SP_SLICE:
2114         base_picture->type = GST_VAAPI_PICTURE_TYPE_SP;
2115         break;
2116     case GST_H264_SI_SLICE:
2117         base_picture->type = GST_VAAPI_PICTURE_TYPE_SI;
2118         break;
2119     }
2120
2121     /* Initialize picture structure */
2122     if (!slice_hdr->field_pic_flag)
2123         base_picture->structure = GST_VAAPI_PICTURE_STRUCTURE_FRAME;
2124     else {
2125         GST_VAAPI_PICTURE_FLAG_SET(picture, GST_VAAPI_PICTURE_FLAG_INTERLACED);
2126         if (!slice_hdr->bottom_field_flag)
2127             base_picture->structure = GST_VAAPI_PICTURE_STRUCTURE_TOP_FIELD;
2128         else
2129             base_picture->structure = GST_VAAPI_PICTURE_STRUCTURE_BOTTOM_FIELD;
2130     }
2131     picture->structure = base_picture->structure;
2132
2133     /* Initialize reference flags */
2134     if (pi->nalu.ref_idc) {
2135         GstH264DecRefPicMarking * const dec_ref_pic_marking =
2136             &slice_hdr->dec_ref_pic_marking;
2137
2138         if (GST_VAAPI_PICTURE_IS_IDR(picture) &&
2139             dec_ref_pic_marking->long_term_reference_flag)
2140             GST_VAAPI_PICTURE_FLAG_SET(picture,
2141                 GST_VAAPI_PICTURE_FLAG_LONG_TERM_REFERENCE);
2142         else
2143             GST_VAAPI_PICTURE_FLAG_SET(picture,
2144                 GST_VAAPI_PICTURE_FLAG_SHORT_TERM_REFERENCE);
2145     }
2146
2147     init_picture_poc(decoder, picture, slice_hdr);
2148     init_picture_refs(decoder, picture, slice_hdr);
2149     return TRUE;
2150 }
2151
2152 /* 8.2.5.3 - Sliding window decoded reference picture marking process */
2153 static gboolean
2154 exec_ref_pic_marking_sliding_window(GstVaapiDecoderH264 *decoder)
2155 {
2156     GstVaapiDecoderH264Private * const priv = &decoder->priv;
2157     GstH264SPS * const sps = get_sps(decoder);
2158     GstVaapiPictureH264 *ref_picture;
2159     guint i, m, max_num_ref_frames;
2160
2161     GST_DEBUG("reference picture marking process (sliding window)");
2162
2163     if (!GST_VAAPI_PICTURE_IS_FIRST_FIELD(priv->current_picture))
2164         return TRUE;
2165
2166     max_num_ref_frames = sps->num_ref_frames;
2167     if (max_num_ref_frames == 0)
2168         max_num_ref_frames = 1;
2169     if (!GST_VAAPI_PICTURE_IS_FRAME(priv->current_picture))
2170         max_num_ref_frames <<= 1;
2171
2172     if (priv->short_ref_count + priv->long_ref_count < max_num_ref_frames)
2173         return TRUE;
2174     if (priv->short_ref_count < 1)
2175         return FALSE;
2176
2177     for (m = 0, i = 1; i < priv->short_ref_count; i++) {
2178         GstVaapiPictureH264 * const picture = priv->short_ref[i];
2179         if (picture->frame_num_wrap < priv->short_ref[m]->frame_num_wrap)
2180             m = i;
2181     }
2182
2183     ref_picture = priv->short_ref[m];
2184     gst_vaapi_picture_h264_set_reference(ref_picture, 0, TRUE);
2185     ARRAY_REMOVE_INDEX(priv->short_ref, m);
2186
2187     /* Both fields need to be marked as "unused for reference", so
2188        remove the other field from the short_ref[] list as well */
2189     if (!GST_VAAPI_PICTURE_IS_FRAME(priv->current_picture) && ref_picture->other_field) {
2190         for (i = 0; i < priv->short_ref_count; i++) {
2191             if (priv->short_ref[i] == ref_picture->other_field) {
2192                 ARRAY_REMOVE_INDEX(priv->short_ref, i);
2193                 break;
2194             }
2195         }
2196     }
2197     return TRUE;
2198 }
2199
2200 static inline gint32
2201 get_picNumX(GstVaapiPictureH264 *picture, GstH264RefPicMarking *ref_pic_marking)
2202 {
2203     gint32 pic_num;
2204
2205     if (GST_VAAPI_PICTURE_IS_FRAME(picture))
2206         pic_num = picture->frame_num_wrap;
2207     else
2208         pic_num = 2 * picture->frame_num_wrap + 1;
2209     pic_num -= ref_pic_marking->difference_of_pic_nums_minus1 + 1;
2210     return pic_num;
2211 }
2212
2213 /* 8.2.5.4.1. Mark short-term reference picture as "unused for reference" */
2214 static void
2215 exec_ref_pic_marking_adaptive_mmco_1(
2216     GstVaapiDecoderH264  *decoder,
2217     GstVaapiPictureH264  *picture,
2218     GstH264RefPicMarking *ref_pic_marking
2219 )
2220 {
2221     GstVaapiDecoderH264Private * const priv = &decoder->priv;
2222     gint32 i, picNumX;
2223
2224     picNumX = get_picNumX(picture, ref_pic_marking);
2225     i = find_short_term_reference(decoder, picNumX);
2226     if (i < 0)
2227         return;
2228
2229     gst_vaapi_picture_h264_set_reference(priv->short_ref[i], 0,
2230         GST_VAAPI_PICTURE_IS_FRAME(picture));
2231     ARRAY_REMOVE_INDEX(priv->short_ref, i);
2232 }
2233
2234 /* 8.2.5.4.2. Mark long-term reference picture as "unused for reference" */
2235 static void
2236 exec_ref_pic_marking_adaptive_mmco_2(
2237     GstVaapiDecoderH264  *decoder,
2238     GstVaapiPictureH264  *picture,
2239     GstH264RefPicMarking *ref_pic_marking
2240 )
2241 {
2242     GstVaapiDecoderH264Private * const priv = &decoder->priv;
2243     gint32 i;
2244
2245     i = find_long_term_reference(decoder, ref_pic_marking->long_term_pic_num);
2246     if (i < 0)
2247         return;
2248
2249     gst_vaapi_picture_h264_set_reference(priv->long_ref[i], 0,
2250         GST_VAAPI_PICTURE_IS_FRAME(picture));
2251     ARRAY_REMOVE_INDEX(priv->long_ref, i);
2252 }
2253
2254 /* 8.2.5.4.3. Assign LongTermFrameIdx to a short-term reference picture */
2255 static void
2256 exec_ref_pic_marking_adaptive_mmco_3(
2257     GstVaapiDecoderH264  *decoder,
2258     GstVaapiPictureH264  *picture,
2259     GstH264RefPicMarking *ref_pic_marking
2260 )
2261 {
2262     GstVaapiDecoderH264Private * const priv = &decoder->priv;
2263     GstVaapiPictureH264 *ref_picture;
2264     gint32 i, picNumX;
2265
2266     for (i = 0; i < priv->long_ref_count; i++) {
2267         if (priv->long_ref[i]->long_term_frame_idx == ref_pic_marking->long_term_frame_idx)
2268             break;
2269     }
2270     if (i != priv->long_ref_count) {
2271         gst_vaapi_picture_h264_set_reference(priv->long_ref[i], 0, TRUE);
2272         ARRAY_REMOVE_INDEX(priv->long_ref, i);
2273     }
2274
2275     picNumX = get_picNumX(picture, ref_pic_marking);
2276     i = find_short_term_reference(decoder, picNumX);
2277     if (i < 0)
2278         return;
2279
2280     ref_picture = priv->short_ref[i];
2281     ARRAY_REMOVE_INDEX(priv->short_ref, i);
2282     priv->long_ref[priv->long_ref_count++] = ref_picture;
2283
2284     ref_picture->long_term_frame_idx = ref_pic_marking->long_term_frame_idx;
2285     gst_vaapi_picture_h264_set_reference(ref_picture,
2286         GST_VAAPI_PICTURE_FLAG_LONG_TERM_REFERENCE,
2287         GST_VAAPI_PICTURE_IS_FRAME(picture));
2288 }
2289
2290 /* 8.2.5.4.4. Mark pictures with LongTermFramIdx > max_long_term_frame_idx
2291  * as "unused for reference" */
2292 static void
2293 exec_ref_pic_marking_adaptive_mmco_4(
2294     GstVaapiDecoderH264  *decoder,
2295     GstVaapiPictureH264  *picture,
2296     GstH264RefPicMarking *ref_pic_marking
2297 )
2298 {
2299     GstVaapiDecoderH264Private * const priv = &decoder->priv;
2300     gint32 i, long_term_frame_idx;
2301
2302     long_term_frame_idx = ref_pic_marking->max_long_term_frame_idx_plus1 - 1;
2303
2304     for (i = 0; i < priv->long_ref_count; i++) {
2305         if (priv->long_ref[i]->long_term_frame_idx <= long_term_frame_idx)
2306             continue;
2307         gst_vaapi_picture_h264_set_reference(priv->long_ref[i], 0, FALSE);
2308         ARRAY_REMOVE_INDEX(priv->long_ref, i);
2309         i--;
2310     }
2311 }
2312
2313 /* 8.2.5.4.5. Mark all reference pictures as "unused for reference" */
2314 static void
2315 exec_ref_pic_marking_adaptive_mmco_5(
2316     GstVaapiDecoderH264  *decoder,
2317     GstVaapiPictureH264  *picture,
2318     GstH264RefPicMarking *ref_pic_marking
2319 )
2320 {
2321     GstVaapiDecoderH264Private * const priv = &decoder->priv;
2322
2323     dpb_flush(decoder);
2324
2325     priv->prev_pic_has_mmco5 = TRUE;
2326
2327     /* The picture shall be inferred to have had frame_num equal to 0 (7.4.3) */
2328     priv->frame_num = 0;
2329     priv->frame_num_offset = 0;
2330     picture->frame_num = 0;
2331
2332     /* Update TopFieldOrderCnt and BottomFieldOrderCnt (8.2.1) */
2333     if (picture->structure != GST_VAAPI_PICTURE_STRUCTURE_BOTTOM_FIELD)
2334         picture->field_poc[TOP_FIELD] -= picture->base.poc;
2335     if (picture->structure != GST_VAAPI_PICTURE_STRUCTURE_TOP_FIELD)
2336         picture->field_poc[BOTTOM_FIELD] -= picture->base.poc;
2337     picture->base.poc = 0;
2338 }
2339
2340 /* 8.2.5.4.6. Assign a long-term frame index to the current picture */
2341 static void
2342 exec_ref_pic_marking_adaptive_mmco_6(
2343     GstVaapiDecoderH264  *decoder,
2344     GstVaapiPictureH264  *picture,
2345     GstH264RefPicMarking *ref_pic_marking
2346 )
2347 {
2348     picture->long_term_frame_idx = ref_pic_marking->long_term_frame_idx;
2349     gst_vaapi_picture_h264_set_reference(picture,
2350         GST_VAAPI_PICTURE_FLAG_LONG_TERM_REFERENCE, FALSE);
2351 }
2352
2353 /* 8.2.5.4. Adaptive memory control decoded reference picture marking process */
2354 static gboolean
2355 exec_ref_pic_marking_adaptive(
2356     GstVaapiDecoderH264     *decoder,
2357     GstVaapiPictureH264     *picture,
2358     GstH264DecRefPicMarking *dec_ref_pic_marking
2359 )
2360 {
2361     guint i;
2362
2363     GST_DEBUG("reference picture marking process (adaptive memory control)");
2364
2365     typedef void (*exec_ref_pic_marking_adaptive_mmco_func)(
2366         GstVaapiDecoderH264  *decoder,
2367         GstVaapiPictureH264  *picture,
2368         GstH264RefPicMarking *ref_pic_marking
2369     );
2370
2371     static const exec_ref_pic_marking_adaptive_mmco_func mmco_funcs[] = {
2372         NULL,
2373         exec_ref_pic_marking_adaptive_mmco_1,
2374         exec_ref_pic_marking_adaptive_mmco_2,
2375         exec_ref_pic_marking_adaptive_mmco_3,
2376         exec_ref_pic_marking_adaptive_mmco_4,
2377         exec_ref_pic_marking_adaptive_mmco_5,
2378         exec_ref_pic_marking_adaptive_mmco_6,
2379     };
2380
2381     for (i = 0; i < dec_ref_pic_marking->n_ref_pic_marking; i++) {
2382         GstH264RefPicMarking * const ref_pic_marking =
2383             &dec_ref_pic_marking->ref_pic_marking[i];
2384
2385         const guint mmco = ref_pic_marking->memory_management_control_operation;
2386         if (mmco < G_N_ELEMENTS(mmco_funcs) && mmco_funcs[mmco])
2387             mmco_funcs[mmco](decoder, picture, ref_pic_marking);
2388         else {
2389             GST_ERROR("unhandled MMCO %u", mmco);
2390             return FALSE;
2391         }
2392     }
2393     return TRUE;
2394 }
2395
2396 /* 8.2.5 - Execute reference picture marking process */
2397 static gboolean
2398 exec_ref_pic_marking(GstVaapiDecoderH264 *decoder, GstVaapiPictureH264 *picture)
2399 {
2400     GstVaapiDecoderH264Private * const priv = &decoder->priv;
2401
2402     priv->prev_pic_has_mmco5 = FALSE;
2403     priv->prev_pic_structure = picture->structure;
2404
2405     if (!GST_VAAPI_PICTURE_IS_REFERENCE(picture))
2406         return TRUE;
2407
2408     if (!GST_VAAPI_PICTURE_IS_IDR(picture)) {
2409         GstH264DecRefPicMarking * const dec_ref_pic_marking =
2410             &picture->last_slice_hdr->dec_ref_pic_marking;
2411         if (dec_ref_pic_marking->adaptive_ref_pic_marking_mode_flag) {
2412             if (!exec_ref_pic_marking_adaptive(decoder, picture, dec_ref_pic_marking))
2413                 return FALSE;
2414         }
2415         else {
2416             if (!exec_ref_pic_marking_sliding_window(decoder))
2417                 return FALSE;
2418         }
2419     }
2420     return TRUE;
2421 }
2422
2423 static void
2424 vaapi_init_picture(VAPictureH264 *pic)
2425 {
2426     pic->picture_id           = VA_INVALID_ID;
2427     pic->frame_idx            = 0;
2428     pic->flags                = VA_PICTURE_H264_INVALID;
2429     pic->TopFieldOrderCnt     = 0;
2430     pic->BottomFieldOrderCnt  = 0;
2431 }
2432
2433 static void
2434 vaapi_fill_picture(VAPictureH264 *pic, GstVaapiPictureH264 *picture,
2435     guint picture_structure)
2436 {
2437     if (!picture_structure)
2438         picture_structure = picture->structure;
2439
2440     pic->picture_id = picture->base.surface_id;
2441     pic->flags = 0;
2442
2443     if (GST_VAAPI_PICTURE_IS_LONG_TERM_REFERENCE(picture)) {
2444         pic->flags |= VA_PICTURE_H264_LONG_TERM_REFERENCE;
2445         pic->frame_idx = picture->long_term_frame_idx;
2446     }
2447     else {
2448         if (GST_VAAPI_PICTURE_IS_SHORT_TERM_REFERENCE(picture))
2449             pic->flags |= VA_PICTURE_H264_SHORT_TERM_REFERENCE;
2450         pic->frame_idx = picture->frame_num;
2451     }
2452
2453     switch (picture_structure) {
2454     case GST_VAAPI_PICTURE_STRUCTURE_FRAME:
2455         pic->TopFieldOrderCnt = picture->field_poc[TOP_FIELD];
2456         pic->BottomFieldOrderCnt = picture->field_poc[BOTTOM_FIELD];
2457         break;
2458     case GST_VAAPI_PICTURE_STRUCTURE_TOP_FIELD:
2459         pic->flags |= VA_PICTURE_H264_TOP_FIELD;
2460         pic->TopFieldOrderCnt = picture->field_poc[TOP_FIELD];
2461         pic->BottomFieldOrderCnt = 0;
2462         break;
2463     case GST_VAAPI_PICTURE_STRUCTURE_BOTTOM_FIELD:
2464         pic->flags |= VA_PICTURE_H264_BOTTOM_FIELD;
2465         pic->BottomFieldOrderCnt = picture->field_poc[BOTTOM_FIELD];
2466         pic->TopFieldOrderCnt = 0;
2467         break;
2468     }
2469 }
2470
2471 static gboolean
2472 fill_picture(GstVaapiDecoderH264 *decoder, GstVaapiPictureH264 *picture)
2473 {
2474     GstVaapiDecoderH264Private * const priv = &decoder->priv;
2475     GstVaapiPicture * const base_picture = &picture->base;
2476     GstH264PPS * const pps = get_pps(decoder);
2477     GstH264SPS * const sps = get_sps(decoder);
2478     VAPictureParameterBufferH264 * const pic_param = base_picture->param;
2479     guint i, n;
2480
2481     /* Fill in VAPictureParameterBufferH264 */
2482     vaapi_fill_picture(&pic_param->CurrPic, picture, 0);
2483
2484     for (i = 0, n = 0; i < priv->dpb_count; i++) {
2485         GstVaapiFrameStore * const fs = priv->dpb[i];
2486         if (gst_vaapi_frame_store_has_reference(fs))
2487             vaapi_fill_picture(&pic_param->ReferenceFrames[n++],
2488                 fs->buffers[0], fs->structure);
2489     }
2490     for (; n < G_N_ELEMENTS(pic_param->ReferenceFrames); n++)
2491         vaapi_init_picture(&pic_param->ReferenceFrames[n]);
2492
2493 #define COPY_FIELD(s, f) \
2494     pic_param->f = (s)->f
2495
2496 #define COPY_BFM(a, s, f) \
2497     pic_param->a.bits.f = (s)->f
2498
2499     pic_param->picture_width_in_mbs_minus1  = priv->mb_width - 1;
2500     pic_param->picture_height_in_mbs_minus1 = priv->mb_height - 1;
2501     pic_param->frame_num                    = priv->frame_num;
2502
2503     COPY_FIELD(sps, bit_depth_luma_minus8);
2504     COPY_FIELD(sps, bit_depth_chroma_minus8);
2505     COPY_FIELD(sps, num_ref_frames);
2506     COPY_FIELD(pps, num_slice_groups_minus1);
2507     COPY_FIELD(pps, slice_group_map_type);
2508     COPY_FIELD(pps, slice_group_change_rate_minus1);
2509     COPY_FIELD(pps, pic_init_qp_minus26);
2510     COPY_FIELD(pps, pic_init_qs_minus26);
2511     COPY_FIELD(pps, chroma_qp_index_offset);
2512     COPY_FIELD(pps, second_chroma_qp_index_offset);
2513
2514     pic_param->seq_fields.value                                         = 0; /* reset all bits */
2515     pic_param->seq_fields.bits.residual_colour_transform_flag           = sps->separate_colour_plane_flag;
2516     pic_param->seq_fields.bits.MinLumaBiPredSize8x8                     = sps->level_idc >= 31; /* A.3.3.2 */
2517
2518     COPY_BFM(seq_fields, sps, chroma_format_idc);
2519     COPY_BFM(seq_fields, sps, gaps_in_frame_num_value_allowed_flag);
2520     COPY_BFM(seq_fields, sps, frame_mbs_only_flag); 
2521     COPY_BFM(seq_fields, sps, mb_adaptive_frame_field_flag); 
2522     COPY_BFM(seq_fields, sps, direct_8x8_inference_flag); 
2523     COPY_BFM(seq_fields, sps, log2_max_frame_num_minus4);
2524     COPY_BFM(seq_fields, sps, pic_order_cnt_type);
2525     COPY_BFM(seq_fields, sps, log2_max_pic_order_cnt_lsb_minus4);
2526     COPY_BFM(seq_fields, sps, delta_pic_order_always_zero_flag);
2527
2528     pic_param->pic_fields.value                                         = 0; /* reset all bits */
2529     pic_param->pic_fields.bits.field_pic_flag                           = GST_VAAPI_PICTURE_IS_INTERLACED(picture);
2530     pic_param->pic_fields.bits.reference_pic_flag                       = GST_VAAPI_PICTURE_IS_REFERENCE(picture);
2531
2532     COPY_BFM(pic_fields, pps, entropy_coding_mode_flag);
2533     COPY_BFM(pic_fields, pps, weighted_pred_flag);
2534     COPY_BFM(pic_fields, pps, weighted_bipred_idc);
2535     COPY_BFM(pic_fields, pps, transform_8x8_mode_flag);
2536     COPY_BFM(pic_fields, pps, constrained_intra_pred_flag);
2537     COPY_BFM(pic_fields, pps, pic_order_present_flag);
2538     COPY_BFM(pic_fields, pps, deblocking_filter_control_present_flag);
2539     COPY_BFM(pic_fields, pps, redundant_pic_cnt_present_flag);
2540     return TRUE;
2541 }
2542
2543 /* Detection of the first VCL NAL unit of a primary coded picture (7.4.1.2.4) */
2544 static gboolean
2545 is_new_picture(GstVaapiParserInfoH264 *pi, GstVaapiParserInfoH264 *prev_pi)
2546 {
2547     GstH264SliceHdr * const slice_hdr = &pi->data.slice_hdr;
2548     GstH264PPS * const pps = slice_hdr->pps;
2549     GstH264SPS * const sps = pps->sequence;
2550     GstH264SliceHdr *prev_slice_hdr;
2551
2552     if (!prev_pi)
2553         return TRUE;
2554     prev_slice_hdr = &prev_pi->data.slice_hdr;
2555
2556 #define CHECK_EXPR(expr, field_name) do {              \
2557         if (!(expr)) {                                 \
2558             GST_DEBUG(field_name " differs in value"); \
2559             return TRUE;                               \
2560         }                                              \
2561     } while (0)
2562
2563 #define CHECK_VALUE(new_slice_hdr, old_slice_hdr, field) \
2564     CHECK_EXPR(((new_slice_hdr)->field == (old_slice_hdr)->field), #field)
2565
2566     /* frame_num differs in value, regardless of inferred values to 0 */
2567     CHECK_VALUE(slice_hdr, prev_slice_hdr, frame_num);
2568
2569     /* pic_parameter_set_id differs in value */
2570     CHECK_VALUE(slice_hdr, prev_slice_hdr, pps);
2571
2572     /* field_pic_flag differs in value */
2573     CHECK_VALUE(slice_hdr, prev_slice_hdr, field_pic_flag);
2574
2575     /* bottom_field_flag is present in both and differs in value */
2576     if (slice_hdr->field_pic_flag && prev_slice_hdr->field_pic_flag)
2577         CHECK_VALUE(slice_hdr, prev_slice_hdr, bottom_field_flag);
2578
2579     /* nal_ref_idc differs in value with one of the nal_ref_idc values is 0 */
2580     CHECK_EXPR((pi->nalu.ref_idc != 0) ==
2581                (prev_pi->nalu.ref_idc != 0), "nal_ref_idc");
2582
2583     /* POC type is 0 for both and either pic_order_cnt_lsb differs in
2584        value or delta_pic_order_cnt_bottom differs in value */
2585     if (sps->pic_order_cnt_type == 0) {
2586         CHECK_VALUE(slice_hdr, prev_slice_hdr, pic_order_cnt_lsb);
2587         if (pps->pic_order_present_flag && !slice_hdr->field_pic_flag)
2588             CHECK_VALUE(slice_hdr, prev_slice_hdr, delta_pic_order_cnt_bottom);
2589     }
2590
2591     /* POC type is 1 for both and either delta_pic_order_cnt[0]
2592        differs in value or delta_pic_order_cnt[1] differs in value */
2593     else if (sps->pic_order_cnt_type == 1) {
2594         CHECK_VALUE(slice_hdr, prev_slice_hdr, delta_pic_order_cnt[0]);
2595         CHECK_VALUE(slice_hdr, prev_slice_hdr, delta_pic_order_cnt[1]);
2596     }
2597
2598     /* IdrPicFlag differs in value */
2599     CHECK_VALUE(&pi->nalu, &prev_pi->nalu, idr_pic_flag);
2600
2601     /* IdrPicFlag is equal to 1 for both and idr_pic_id differs in value */
2602     if (pi->nalu.idr_pic_flag)
2603         CHECK_VALUE(slice_hdr, prev_slice_hdr, idr_pic_id);
2604
2605 #undef CHECK_EXPR
2606 #undef CHECK_VALUE
2607     return FALSE;
2608 }
2609
2610 static GstVaapiDecoderStatus
2611 decode_picture(GstVaapiDecoderH264 *decoder, GstVaapiDecoderUnit *unit)
2612 {
2613     GstVaapiDecoderH264Private * const priv = &decoder->priv;
2614     GstVaapiParserInfoH264 * const pi = unit->parsed_info;
2615     GstH264SliceHdr * const slice_hdr = &pi->data.slice_hdr;
2616     GstH264PPS * const pps = ensure_pps(decoder, slice_hdr->pps);
2617     GstH264SPS * const sps = ensure_sps(decoder, slice_hdr->pps->sequence);
2618     GstVaapiPictureH264 *picture;
2619     GstVaapiDecoderStatus status;
2620
2621     g_return_val_if_fail(pps != NULL, GST_VAAPI_DECODER_STATUS_ERROR_UNKNOWN);
2622     g_return_val_if_fail(sps != NULL, GST_VAAPI_DECODER_STATUS_ERROR_UNKNOWN);
2623
2624     status = ensure_context(decoder, sps);
2625     if (status != GST_VAAPI_DECODER_STATUS_SUCCESS)
2626         return status;
2627
2628     priv->decoder_state = 0;
2629
2630     if (priv->current_picture) {
2631         /* Re-use current picture where the first field was decoded */
2632         picture = gst_vaapi_picture_h264_new_field(priv->current_picture);
2633         if (!picture) {
2634             GST_ERROR("failed to allocate field picture");
2635             return GST_VAAPI_DECODER_STATUS_ERROR_ALLOCATION_FAILED;
2636         }
2637     }
2638     else {
2639         /* Create new picture */
2640         picture = gst_vaapi_picture_h264_new(decoder);
2641         if (!picture) {
2642             GST_ERROR("failed to allocate picture");
2643             return GST_VAAPI_DECODER_STATUS_ERROR_ALLOCATION_FAILED;
2644         }
2645     }
2646     gst_vaapi_picture_replace(&priv->current_picture, picture);
2647     gst_vaapi_picture_unref(picture);
2648
2649     /* Update cropping rectangle */
2650     if (sps->frame_cropping_flag) {
2651         GstVaapiRectangle crop_rect;
2652         crop_rect.x = sps->crop_rect_x;
2653         crop_rect.y = sps->crop_rect_y;
2654         crop_rect.width = sps->crop_rect_width;
2655         crop_rect.height = sps->crop_rect_height;
2656         gst_vaapi_picture_set_crop_rect(&picture->base, &crop_rect);
2657     }
2658
2659     status = ensure_quant_matrix(decoder, picture);
2660     if (status != GST_VAAPI_DECODER_STATUS_SUCCESS) {
2661         GST_ERROR("failed to reset quantizer matrix");
2662         return status;
2663     }
2664
2665     if (!init_picture(decoder, picture, pi))
2666         return GST_VAAPI_DECODER_STATUS_ERROR_UNKNOWN;
2667     if (!fill_picture(decoder, picture))
2668         return GST_VAAPI_DECODER_STATUS_ERROR_UNKNOWN;
2669
2670     priv->decoder_state = pi->state;
2671     return GST_VAAPI_DECODER_STATUS_SUCCESS;
2672 }
2673
2674 static inline guint
2675 get_slice_data_bit_offset(GstH264SliceHdr *slice_hdr, guint nal_header_bytes)
2676 {
2677     guint epb_count;
2678
2679     epb_count = slice_hdr->n_emulation_prevention_bytes;
2680     return 8 * nal_header_bytes + slice_hdr->header_size - epb_count * 8;
2681 }
2682
2683 static gboolean
2684 fill_pred_weight_table(GstVaapiDecoderH264 *decoder,
2685     GstVaapiSlice *slice, GstH264SliceHdr *slice_hdr)
2686 {
2687     VASliceParameterBufferH264 * const slice_param = slice->param;
2688     GstH264PPS * const pps = get_pps(decoder);
2689     GstH264SPS * const sps = get_sps(decoder);
2690     GstH264PredWeightTable * const w = &slice_hdr->pred_weight_table;
2691     guint num_weight_tables = 0;
2692     gint i, j;
2693
2694     if (pps->weighted_pred_flag &&
2695         (GST_H264_IS_P_SLICE(slice_hdr) || GST_H264_IS_SP_SLICE(slice_hdr)))
2696         num_weight_tables = 1;
2697     else if (pps->weighted_bipred_idc == 1 && GST_H264_IS_B_SLICE(slice_hdr))
2698         num_weight_tables = 2;
2699     else
2700         num_weight_tables = 0;
2701
2702     slice_param->luma_log2_weight_denom   = 0;
2703     slice_param->chroma_log2_weight_denom = 0;
2704     slice_param->luma_weight_l0_flag      = 0;
2705     slice_param->chroma_weight_l0_flag    = 0;
2706     slice_param->luma_weight_l1_flag      = 0;
2707     slice_param->chroma_weight_l1_flag    = 0;
2708
2709     if (num_weight_tables < 1)
2710         return TRUE;
2711
2712     slice_param->luma_log2_weight_denom   = w->luma_log2_weight_denom;
2713     slice_param->chroma_log2_weight_denom = w->chroma_log2_weight_denom;
2714
2715     slice_param->luma_weight_l0_flag = 1;
2716     for (i = 0; i <= slice_param->num_ref_idx_l0_active_minus1; i++) {
2717         slice_param->luma_weight_l0[i] = w->luma_weight_l0[i];
2718         slice_param->luma_offset_l0[i] = w->luma_offset_l0[i];
2719     }
2720
2721     slice_param->chroma_weight_l0_flag = sps->chroma_array_type != 0;
2722     if (slice_param->chroma_weight_l0_flag) {
2723         for (i = 0; i <= slice_param->num_ref_idx_l0_active_minus1; i++) {
2724             for (j = 0; j < 2; j++) {
2725                 slice_param->chroma_weight_l0[i][j] = w->chroma_weight_l0[i][j];
2726                 slice_param->chroma_offset_l0[i][j] = w->chroma_offset_l0[i][j];
2727             }
2728         }
2729     }
2730
2731     if (num_weight_tables < 2)
2732         return TRUE;
2733
2734     slice_param->luma_weight_l1_flag = 1;
2735     for (i = 0; i <= slice_param->num_ref_idx_l1_active_minus1; i++) {
2736         slice_param->luma_weight_l1[i] = w->luma_weight_l1[i];
2737         slice_param->luma_offset_l1[i] = w->luma_offset_l1[i];
2738     }
2739
2740     slice_param->chroma_weight_l1_flag = sps->chroma_array_type != 0;
2741     if (slice_param->chroma_weight_l1_flag) {
2742         for (i = 0; i <= slice_param->num_ref_idx_l1_active_minus1; i++) {
2743             for (j = 0; j < 2; j++) {
2744                 slice_param->chroma_weight_l1[i][j] = w->chroma_weight_l1[i][j];
2745                 slice_param->chroma_offset_l1[i][j] = w->chroma_offset_l1[i][j];
2746             }
2747         }
2748     }
2749     return TRUE;
2750 }
2751
2752 static gboolean
2753 fill_RefPicList(GstVaapiDecoderH264 *decoder,
2754     GstVaapiSlice *slice, GstH264SliceHdr *slice_hdr)
2755 {
2756     GstVaapiDecoderH264Private * const priv = &decoder->priv;
2757     VASliceParameterBufferH264 * const slice_param = slice->param;
2758     guint i, num_ref_lists = 0;
2759
2760     slice_param->num_ref_idx_l0_active_minus1 = 0;
2761     slice_param->num_ref_idx_l1_active_minus1 = 0;
2762
2763     if (GST_H264_IS_B_SLICE(slice_hdr))
2764         num_ref_lists = 2;
2765     else if (GST_H264_IS_I_SLICE(slice_hdr))
2766         num_ref_lists = 0;
2767     else
2768         num_ref_lists = 1;
2769
2770     if (num_ref_lists < 1)
2771         return TRUE;
2772
2773     slice_param->num_ref_idx_l0_active_minus1 =
2774         slice_hdr->num_ref_idx_l0_active_minus1;
2775
2776     for (i = 0; i < priv->RefPicList0_count && priv->RefPicList0[i]; i++)
2777         vaapi_fill_picture(&slice_param->RefPicList0[i], priv->RefPicList0[i], 0);
2778     for (; i <= slice_param->num_ref_idx_l0_active_minus1; i++)
2779         vaapi_init_picture(&slice_param->RefPicList0[i]);
2780
2781     if (num_ref_lists < 2)
2782         return TRUE;
2783
2784     slice_param->num_ref_idx_l1_active_minus1 =
2785         slice_hdr->num_ref_idx_l1_active_minus1;
2786
2787     for (i = 0; i < priv->RefPicList1_count && priv->RefPicList1[i]; i++)
2788         vaapi_fill_picture(&slice_param->RefPicList1[i], priv->RefPicList1[i], 0);
2789     for (; i <= slice_param->num_ref_idx_l1_active_minus1; i++)
2790         vaapi_init_picture(&slice_param->RefPicList1[i]);
2791     return TRUE;
2792 }
2793
2794 static gboolean
2795 fill_slice(GstVaapiDecoderH264 *decoder,
2796     GstVaapiSlice *slice, GstVaapiParserInfoH264 *pi)
2797 {
2798     VASliceParameterBufferH264 * const slice_param = slice->param;
2799     GstH264SliceHdr * const slice_hdr = &pi->data.slice_hdr;
2800
2801     /* Fill in VASliceParameterBufferH264 */
2802     slice_param->slice_data_bit_offset =
2803         get_slice_data_bit_offset(slice_hdr, pi->nalu.header_bytes);
2804     slice_param->first_mb_in_slice              = slice_hdr->first_mb_in_slice;
2805     slice_param->slice_type                     = slice_hdr->type % 5;
2806     slice_param->direct_spatial_mv_pred_flag    = slice_hdr->direct_spatial_mv_pred_flag;
2807     slice_param->cabac_init_idc                 = slice_hdr->cabac_init_idc;
2808     slice_param->slice_qp_delta                 = slice_hdr->slice_qp_delta;
2809     slice_param->disable_deblocking_filter_idc  = slice_hdr->disable_deblocking_filter_idc;
2810     slice_param->slice_alpha_c0_offset_div2     = slice_hdr->slice_alpha_c0_offset_div2;
2811     slice_param->slice_beta_offset_div2         = slice_hdr->slice_beta_offset_div2;
2812
2813     if (!fill_RefPicList(decoder, slice, slice_hdr))
2814         return FALSE;
2815     if (!fill_pred_weight_table(decoder, slice, slice_hdr))
2816         return FALSE;
2817     return TRUE;
2818 }
2819
2820 static GstVaapiDecoderStatus
2821 decode_slice(GstVaapiDecoderH264 *decoder, GstVaapiDecoderUnit *unit)
2822 {
2823     GstVaapiDecoderH264Private * const priv = &decoder->priv;
2824     GstVaapiParserInfoH264 * const pi = unit->parsed_info;
2825     GstVaapiPictureH264 * const picture = priv->current_picture;
2826     GstH264SliceHdr * const slice_hdr = &pi->data.slice_hdr;
2827     GstVaapiSlice *slice;
2828     GstBuffer * const buffer =
2829         GST_VAAPI_DECODER_CODEC_FRAME(decoder)->input_buffer;
2830     GstMapInfo map_info;
2831
2832     GST_DEBUG("slice (%u bytes)", pi->nalu.size);
2833
2834     if (!is_valid_state(pi->state,
2835             GST_H264_VIDEO_STATE_VALID_PICTURE_HEADERS)) {
2836         GST_WARNING("failed to receive enough headers to decode slice");
2837         return GST_VAAPI_DECODER_STATUS_SUCCESS;
2838     }
2839
2840     if (!ensure_pps(decoder, slice_hdr->pps)) {
2841         GST_ERROR("failed to activate PPS");
2842         return GST_VAAPI_DECODER_STATUS_ERROR_UNKNOWN;
2843     }
2844
2845     if (!ensure_sps(decoder, slice_hdr->pps->sequence)) {
2846         GST_ERROR("failed to activate SPS");
2847         return GST_VAAPI_DECODER_STATUS_ERROR_UNKNOWN;
2848     }
2849
2850     if (!gst_buffer_map(buffer, &map_info, GST_MAP_READ)) {
2851         GST_ERROR("failed to map buffer");
2852         return GST_VAAPI_DECODER_STATUS_ERROR_UNKNOWN;
2853     }
2854
2855     slice = GST_VAAPI_SLICE_NEW(H264, decoder,
2856         (map_info.data + unit->offset + pi->nalu.offset), pi->nalu.size);
2857     gst_buffer_unmap(buffer, &map_info);
2858     if (!slice) {
2859         GST_ERROR("failed to allocate slice");
2860         return GST_VAAPI_DECODER_STATUS_ERROR_ALLOCATION_FAILED;
2861     }
2862
2863     if (!fill_slice(decoder, slice, pi)) {
2864         gst_vaapi_mini_object_unref(GST_VAAPI_MINI_OBJECT(slice));
2865         return GST_VAAPI_DECODER_STATUS_ERROR_UNKNOWN;
2866     }
2867
2868     gst_vaapi_picture_add_slice(GST_VAAPI_PICTURE_CAST(picture), slice);
2869     picture->last_slice_hdr = slice_hdr;
2870     priv->decoder_state |= GST_H264_VIDEO_STATE_GOT_SLICE;
2871     return GST_VAAPI_DECODER_STATUS_SUCCESS;
2872 }
2873
2874 static inline gint
2875 scan_for_start_code(GstAdapter *adapter, guint ofs, guint size, guint32 *scp)
2876 {
2877     return (gint)gst_adapter_masked_scan_uint32_peek(adapter,
2878                                                      0xffffff00, 0x00000100,
2879                                                      ofs, size,
2880                                                      scp);
2881 }
2882
2883 static GstVaapiDecoderStatus
2884 decode_unit(GstVaapiDecoderH264 *decoder, GstVaapiDecoderUnit *unit)
2885 {
2886     GstVaapiDecoderH264Private * const priv = &decoder->priv;
2887     GstVaapiParserInfoH264 * const pi = unit->parsed_info;
2888     GstVaapiDecoderStatus status;
2889
2890     priv->decoder_state |= pi->state;
2891     switch (pi->nalu.type) {
2892     case GST_H264_NAL_SPS:
2893         status = decode_sps(decoder, unit);
2894         break;
2895     case GST_H264_NAL_PPS:
2896         status = decode_pps(decoder, unit);
2897         break;
2898     case GST_H264_NAL_SLICE_IDR:
2899         /* fall-through. IDR specifics are handled in init_picture() */
2900     case GST_H264_NAL_SLICE:
2901         status = decode_slice(decoder, unit);
2902         break;
2903     case GST_H264_NAL_SEQ_END:
2904     case GST_H264_NAL_STREAM_END:
2905         status = decode_sequence_end(decoder);
2906         break;
2907     case GST_H264_NAL_SEI:
2908         status = GST_VAAPI_DECODER_STATUS_SUCCESS;
2909         break;
2910     default:
2911         GST_WARNING("unsupported NAL unit type %d", pi->nalu.type);
2912         status = GST_VAAPI_DECODER_STATUS_ERROR_BITSTREAM_PARSER;
2913         break;
2914     }
2915     return status;
2916 }
2917
2918 static GstVaapiDecoderStatus
2919 gst_vaapi_decoder_h264_decode_codec_data(GstVaapiDecoder *base_decoder,
2920     const guchar *buf, guint buf_size)
2921 {
2922     GstVaapiDecoderH264 * const decoder =
2923         GST_VAAPI_DECODER_H264_CAST(base_decoder);
2924     GstVaapiDecoderH264Private * const priv = &decoder->priv;
2925     GstVaapiDecoderStatus status;
2926     GstVaapiDecoderUnit unit;
2927     GstVaapiParserInfoH264 *pi = NULL;
2928     GstH264ParserResult result;
2929     guint i, ofs, num_sps, num_pps;
2930
2931     unit.parsed_info = NULL;
2932
2933     if (buf_size < 8)
2934         return GST_VAAPI_DECODER_STATUS_ERROR_NO_DATA;
2935
2936     if (buf[0] != 1) {
2937         GST_ERROR("failed to decode codec-data, not in avcC format");
2938         return GST_VAAPI_DECODER_STATUS_ERROR_BITSTREAM_PARSER;
2939     }
2940
2941     priv->nal_length_size = (buf[4] & 0x03) + 1;
2942
2943     num_sps = buf[5] & 0x1f;
2944     ofs = 6;
2945
2946     for (i = 0; i < num_sps; i++) {
2947         pi = gst_vaapi_parser_info_h264_new();
2948         if (!pi)
2949             return GST_VAAPI_DECODER_STATUS_ERROR_ALLOCATION_FAILED;
2950         unit.parsed_info = pi;
2951
2952         result = gst_h264_parser_identify_nalu_avc(
2953             priv->parser,
2954             buf, ofs, buf_size, 2,
2955             &pi->nalu
2956         );
2957         if (result != GST_H264_PARSER_OK) {
2958             status = get_status(result);
2959             goto cleanup;
2960         }
2961
2962         status = parse_sps(decoder, &unit);
2963         if (status != GST_VAAPI_DECODER_STATUS_SUCCESS)
2964             goto cleanup;
2965         ofs = pi->nalu.offset + pi->nalu.size;
2966
2967         status = decode_sps(decoder, &unit);
2968         if (status != GST_VAAPI_DECODER_STATUS_SUCCESS)
2969             goto cleanup;
2970         gst_vaapi_parser_info_h264_replace(&pi, NULL);
2971     }
2972
2973     num_pps = buf[ofs];
2974     ofs++;
2975
2976     for (i = 0; i < num_pps; i++) {
2977         pi = gst_vaapi_parser_info_h264_new();
2978         if (!pi)
2979             return GST_VAAPI_DECODER_STATUS_ERROR_ALLOCATION_FAILED;
2980         unit.parsed_info = pi;
2981
2982         result = gst_h264_parser_identify_nalu_avc(
2983             priv->parser,
2984             buf, ofs, buf_size, 2,
2985             &pi->nalu
2986         );
2987         if (result != GST_H264_PARSER_OK) {
2988             status = get_status(result);
2989             goto cleanup;
2990         }
2991
2992         status = parse_pps(decoder, &unit);
2993         if (status != GST_VAAPI_DECODER_STATUS_SUCCESS)
2994             goto cleanup;
2995         ofs = pi->nalu.offset + pi->nalu.size;
2996
2997         status = decode_pps(decoder, &unit);
2998         if (status != GST_VAAPI_DECODER_STATUS_SUCCESS)
2999             goto cleanup;
3000         gst_vaapi_parser_info_h264_replace(&pi, NULL);
3001     }
3002
3003     priv->is_avcC = TRUE;
3004     status = GST_VAAPI_DECODER_STATUS_SUCCESS;
3005
3006 cleanup:
3007     gst_vaapi_parser_info_h264_replace(&pi, NULL);
3008     return status;
3009 }
3010
3011 static GstVaapiDecoderStatus
3012 ensure_decoder(GstVaapiDecoderH264 *decoder)
3013 {
3014     GstVaapiDecoderH264Private * const priv = &decoder->priv;
3015     GstVaapiDecoderStatus status;
3016
3017     if (!priv->is_opened) {
3018         priv->is_opened = gst_vaapi_decoder_h264_open(decoder);
3019         if (!priv->is_opened)
3020             return GST_VAAPI_DECODER_STATUS_ERROR_UNSUPPORTED_CODEC;
3021
3022         status = gst_vaapi_decoder_decode_codec_data(
3023             GST_VAAPI_DECODER_CAST(decoder));
3024         if (status != GST_VAAPI_DECODER_STATUS_SUCCESS)
3025             return status;
3026     }
3027     return GST_VAAPI_DECODER_STATUS_SUCCESS;
3028 }
3029
3030 static GstVaapiDecoderStatus
3031 gst_vaapi_decoder_h264_parse(GstVaapiDecoder *base_decoder,
3032     GstAdapter *adapter, gboolean at_eos, GstVaapiDecoderUnit *unit)
3033 {
3034     GstVaapiDecoderH264 * const decoder =
3035         GST_VAAPI_DECODER_H264_CAST(base_decoder);
3036     GstVaapiDecoderH264Private * const priv = &decoder->priv;
3037     GstVaapiParserState * const ps = GST_VAAPI_PARSER_STATE(base_decoder);
3038     GstVaapiParserInfoH264 *pi;
3039     GstVaapiDecoderStatus status;
3040     GstH264ParserResult result;
3041     guchar *buf;
3042     guint i, size, buf_size, nalu_size, flags;
3043     guint32 start_code;
3044     gint ofs, ofs2;
3045
3046     status = ensure_decoder(decoder);
3047     if (status != GST_VAAPI_DECODER_STATUS_SUCCESS)
3048         return status;
3049
3050     size = gst_adapter_available(adapter);
3051
3052     if (priv->is_avcC) {
3053         if (size < priv->nal_length_size)
3054             return GST_VAAPI_DECODER_STATUS_ERROR_NO_DATA;
3055
3056         buf = (guchar *)&start_code;
3057         g_assert(priv->nal_length_size <= sizeof(start_code));
3058         gst_adapter_copy(adapter, buf, 0, priv->nal_length_size);
3059
3060         nalu_size = 0;
3061         for (i = 0; i < priv->nal_length_size; i++)
3062             nalu_size = (nalu_size << 8) | buf[i];
3063
3064         buf_size = priv->nal_length_size + nalu_size;
3065         if (size < buf_size)
3066             return GST_VAAPI_DECODER_STATUS_ERROR_NO_DATA;
3067     }
3068     else {
3069         if (size < 4)
3070             return GST_VAAPI_DECODER_STATUS_ERROR_NO_DATA;
3071
3072         ofs = scan_for_start_code(adapter, 0, size, NULL);
3073         if (ofs < 0)
3074             return GST_VAAPI_DECODER_STATUS_ERROR_NO_DATA;
3075
3076         if (ofs > 0) {
3077             gst_adapter_flush(adapter, ofs);
3078             size -= ofs;
3079         }
3080
3081         ofs2 = ps->input_offset2 - ofs - 4;
3082         if (ofs2 < 4)
3083             ofs2 = 4;
3084
3085         ofs = G_UNLIKELY(size < ofs2 + 4) ? -1 :
3086             scan_for_start_code(adapter, ofs2, size - ofs2, NULL);
3087         if (ofs < 0) {
3088             // Assume the whole NAL unit is present if end-of-stream
3089             if (!at_eos) {
3090                 ps->input_offset2 = size;
3091                 return GST_VAAPI_DECODER_STATUS_ERROR_NO_DATA;
3092             }
3093             ofs = size;
3094         }
3095         buf_size = ofs;
3096     }
3097     ps->input_offset2 = 0;
3098
3099     buf = (guchar *)gst_adapter_map(adapter, buf_size);
3100     if (!buf)
3101         return GST_VAAPI_DECODER_STATUS_ERROR_NO_DATA;
3102
3103     unit->size = buf_size;
3104
3105     pi = gst_vaapi_parser_info_h264_new();
3106     if (!pi)
3107         return GST_VAAPI_DECODER_STATUS_ERROR_ALLOCATION_FAILED;
3108
3109     gst_vaapi_decoder_unit_set_parsed_info(unit,
3110         pi, (GDestroyNotify)gst_vaapi_mini_object_unref);
3111
3112     if (priv->is_avcC)
3113         result = gst_h264_parser_identify_nalu_avc(priv->parser,
3114             buf, 0, buf_size, priv->nal_length_size, &pi->nalu);
3115     else
3116         result = gst_h264_parser_identify_nalu_unchecked(priv->parser,
3117             buf, 0, buf_size, &pi->nalu);
3118     status = get_status(result);
3119     if (status != GST_VAAPI_DECODER_STATUS_SUCCESS)
3120         return status;
3121
3122     switch (pi->nalu.type) {
3123     case GST_H264_NAL_SPS:
3124         status = parse_sps(decoder, unit);
3125         break;
3126     case GST_H264_NAL_PPS:
3127         status = parse_pps(decoder, unit);
3128         break;
3129     case GST_H264_NAL_SEI:
3130         status = parse_sei(decoder, unit);
3131         break;
3132     case GST_H264_NAL_SLICE_IDR:
3133     case GST_H264_NAL_SLICE:
3134         status = parse_slice(decoder, unit);
3135         break;
3136     default:
3137         status = GST_VAAPI_DECODER_STATUS_SUCCESS;
3138         break;
3139     }
3140     if (status != GST_VAAPI_DECODER_STATUS_SUCCESS)
3141         return status;
3142
3143     flags = 0;
3144     switch (pi->nalu.type) {
3145     case GST_H264_NAL_AU_DELIMITER:
3146         flags |= GST_VAAPI_DECODER_UNIT_FLAG_FRAME_START;
3147         /* fall-through */
3148     case GST_H264_NAL_FILLER_DATA:
3149         flags |= GST_VAAPI_DECODER_UNIT_FLAG_SKIP;
3150         break;
3151     case GST_H264_NAL_STREAM_END:
3152         flags |= GST_VAAPI_DECODER_UNIT_FLAG_STREAM_END;
3153         /* fall-through */
3154     case GST_H264_NAL_SEQ_END:
3155         flags |= GST_VAAPI_DECODER_UNIT_FLAG_FRAME_END;
3156         break;
3157     case GST_H264_NAL_SPS:
3158     case GST_H264_NAL_PPS:
3159     case GST_H264_NAL_SEI:
3160         flags |= GST_VAAPI_DECODER_UNIT_FLAG_FRAME_START;
3161         break;
3162     case GST_H264_NAL_SLICE_IDR:
3163     case GST_H264_NAL_SLICE:
3164         flags |= GST_VAAPI_DECODER_UNIT_FLAG_SLICE;
3165         if (is_new_picture(pi, priv->prev_slice_pi))
3166             flags |= GST_VAAPI_DECODER_UNIT_FLAG_FRAME_START;
3167         gst_vaapi_parser_info_h264_replace(&priv->prev_slice_pi, pi);
3168         break;
3169     case GST_H264_NAL_SPS_EXT:
3170     case GST_H264_NAL_SLICE_AUX:
3171         /* skip SPS extension and auxiliary slice for now */
3172         flags |= GST_VAAPI_DECODER_UNIT_FLAG_SKIP;
3173         break;
3174     default:
3175         if (pi->nalu.type >= 14 && pi->nalu.type <= 18)
3176             flags |= GST_VAAPI_DECODER_UNIT_FLAG_FRAME_START;
3177         break;
3178     }
3179     GST_VAAPI_DECODER_UNIT_FLAG_SET(unit, flags);
3180
3181     pi->nalu.data = NULL;
3182     pi->state = priv->parser_state;
3183     return GST_VAAPI_DECODER_STATUS_SUCCESS;
3184 }
3185
3186 static GstVaapiDecoderStatus
3187 gst_vaapi_decoder_h264_decode(GstVaapiDecoder *base_decoder,
3188     GstVaapiDecoderUnit *unit)
3189 {
3190     GstVaapiDecoderH264 * const decoder =
3191         GST_VAAPI_DECODER_H264_CAST(base_decoder);
3192     GstVaapiDecoderStatus status;
3193
3194     status = ensure_decoder(decoder);
3195     if (status != GST_VAAPI_DECODER_STATUS_SUCCESS)
3196         return status;
3197     return decode_unit(decoder, unit);
3198 }
3199
3200 static GstVaapiDecoderStatus
3201 gst_vaapi_decoder_h264_start_frame(GstVaapiDecoder *base_decoder,
3202     GstVaapiDecoderUnit *unit)
3203 {
3204     GstVaapiDecoderH264 * const decoder =
3205         GST_VAAPI_DECODER_H264_CAST(base_decoder);
3206
3207     return decode_picture(decoder, unit);
3208 }
3209
3210 static GstVaapiDecoderStatus
3211 gst_vaapi_decoder_h264_end_frame(GstVaapiDecoder *base_decoder)
3212 {
3213     GstVaapiDecoderH264 * const decoder =
3214         GST_VAAPI_DECODER_H264_CAST(base_decoder);
3215
3216     return decode_current_picture(decoder);
3217 }
3218
3219 static GstVaapiDecoderStatus
3220 gst_vaapi_decoder_h264_flush(GstVaapiDecoder *base_decoder)
3221 {
3222     GstVaapiDecoderH264 * const decoder =
3223         GST_VAAPI_DECODER_H264_CAST(base_decoder);
3224
3225     dpb_flush(decoder);
3226     return GST_VAAPI_DECODER_STATUS_SUCCESS;
3227 }
3228
3229 static void
3230 gst_vaapi_decoder_h264_class_init(GstVaapiDecoderH264Class *klass)
3231 {
3232     GstVaapiMiniObjectClass * const object_class =
3233         GST_VAAPI_MINI_OBJECT_CLASS(klass);
3234     GstVaapiDecoderClass * const decoder_class = GST_VAAPI_DECODER_CLASS(klass);
3235
3236     object_class->size          = sizeof(GstVaapiDecoderH264);
3237     object_class->finalize      = (GDestroyNotify)gst_vaapi_decoder_finalize;
3238
3239     decoder_class->create       = gst_vaapi_decoder_h264_create;
3240     decoder_class->destroy      = gst_vaapi_decoder_h264_destroy;
3241     decoder_class->parse        = gst_vaapi_decoder_h264_parse;
3242     decoder_class->decode       = gst_vaapi_decoder_h264_decode;
3243     decoder_class->start_frame  = gst_vaapi_decoder_h264_start_frame;
3244     decoder_class->end_frame    = gst_vaapi_decoder_h264_end_frame;
3245     decoder_class->flush        = gst_vaapi_decoder_h264_flush;
3246
3247     decoder_class->decode_codec_data =
3248         gst_vaapi_decoder_h264_decode_codec_data;
3249 }
3250
3251 static inline const GstVaapiDecoderClass *
3252 gst_vaapi_decoder_h264_class(void)
3253 {
3254     static GstVaapiDecoderH264Class g_class;
3255     static gsize g_class_init = FALSE;
3256
3257     if (g_once_init_enter(&g_class_init)) {
3258         gst_vaapi_decoder_h264_class_init(&g_class);
3259         g_once_init_leave(&g_class_init, TRUE);
3260     }
3261     return GST_VAAPI_DECODER_CLASS(&g_class);
3262 }
3263
3264 /**
3265  * gst_vaapi_decoder_h264_new:
3266  * @display: a #GstVaapiDisplay
3267  * @caps: a #GstCaps holding codec information
3268  *
3269  * Creates a new #GstVaapiDecoder for MPEG-2 decoding.  The @caps can
3270  * hold extra information like codec-data and pictured coded size.
3271  *
3272  * Return value: the newly allocated #GstVaapiDecoder object
3273  */
3274 GstVaapiDecoder *
3275 gst_vaapi_decoder_h264_new(GstVaapiDisplay *display, GstCaps *caps)
3276 {
3277     return gst_vaapi_decoder_new(gst_vaapi_decoder_h264_class(), display, caps);
3278 }