• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /* GStreamer
2  * Copyright (C) 2015 Intel Corporation
3  *    Author: Sreerenj Balachandran <sreerenj.balachandran@intel.com>
4  * Copyright (C) 2019 Seungha Yang <seungha.yang@navercorp.com>
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Library General Public
8  * License as published by the Free Software Foundation; either
9  * version 2 of the License, or (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  * Library General Public License for more details.
15  *
16  * You should have received a copy of the GNU Library General Public
17  * License along with this library; if not, write to the
18  * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
19  * Boston, MA 02110-1301, USA.
20  */
21 /**
22  * SECTION:gsth265decoder
23  * @title: GstH265Decoder
24  * @short_description: Base class to implement stateless H.265 decoders
25  * @sources:
26  * - gsth265picture.h
27  */
28 
29 #ifdef HAVE_CONFIG_H
30 #include <config.h>
31 #endif
32 
33 #include "gsth265decoder.h"
34 
35 GST_DEBUG_CATEGORY (gst_h265_decoder_debug);
36 #define GST_CAT_DEFAULT gst_h265_decoder_debug
37 
38 typedef enum
39 {
40   GST_H265_DECODER_FORMAT_NONE,
41   GST_H265_DECODER_FORMAT_HVC1,
42   GST_H265_DECODER_FORMAT_HEV1,
43   GST_H265_DECODER_FORMAT_BYTE
44 } GstH265DecoderFormat;
45 
46 typedef enum
47 {
48   GST_H265_DECODER_ALIGN_NONE,
49   GST_H265_DECODER_ALIGN_NAL,
50   GST_H265_DECODER_ALIGN_AU
51 } GstH265DecoderAlign;
52 
53 struct _GstH265DecoderPrivate
54 {
55   gint width, height;
56 
57   guint8 conformance_window_flag;
58   gint crop_rect_width;
59   gint crop_rect_height;
60   gint crop_rect_x;
61   gint crop_rect_y;
62 
63   /* input codec_data, if any */
64   GstBuffer *codec_data;
65   guint nal_length_size;
66 
67   /* state */
68   GstH265DecoderFormat in_format;
69   GstH265DecoderAlign align;
70   GstH265Parser *parser;
71   GstH265Dpb *dpb;
72 
73   /* 0: frame or field-pair interlaced stream
74    * 1: alternating, single field interlaced stream.
75    * When equal to 1, picture timing SEI shall be present in every AU */
76   guint8 field_seq_flag;
77   guint8 progressive_source_flag;
78   guint8 interlaced_source_flag;
79 
80   /* Updated/cleared per handle_frame() by using picture timeing SEI */
81   GstH265SEIPicStructType cur_pic_struct;
82   guint8 cur_source_scan_type;
83   guint8 cur_duplicate_flag;
84 
85   /* vps/sps/pps of the current slice */
86   const GstH265VPS *active_vps;
87   const GstH265SPS *active_sps;
88   const GstH265PPS *active_pps;
89 
90   guint32 SpsMaxLatencyPictures;
91 
92   /* Picture currently being processed/decoded */
93   GstH265Picture *current_picture;
94   GstVideoCodecFrame *current_frame;
95 
96   /* Slice (slice header + nalu) currently being processed/decoded */
97   GstH265Slice current_slice;
98   GstH265Slice prev_slice;
99   GstH265Slice prev_independent_slice;
100 
101   gint32 poc;                   // PicOrderCntVal
102   gint32 poc_msb;               // PicOrderCntMsb
103   gint32 poc_lsb;               // pic_order_cnt_lsb (from slice_header())
104   gint32 prev_poc_msb;          // prevPicOrderCntMsb
105   gint32 prev_poc_lsb;          // prevPicOrderCntLsb
106   gint32 prev_tid0pic_poc_lsb;
107   gint32 prev_tid0pic_poc_msb;
108   gint32 PocStCurrBefore[16];
109   gint32 PocStCurrAfter[16];
110   gint32 PocStFoll[16];
111   gint32 PocLtCurr[16];
112   gint32 PocLtFoll[16];
113 
114   /* PicOrderCount of the previously outputted frame */
115   gint last_output_poc;
116 
117   gboolean associated_irap_NoRaslOutputFlag;
118   gboolean new_bitstream;
119   gboolean prev_nal_is_eos;
120 
121   /* Reference picture lists, constructed for each slice */
122   gboolean process_ref_pic_lists;
123   GArray *ref_pic_list_tmp;
124   GArray *ref_pic_list0;
125   GArray *ref_pic_list1;
126 };
127 
128 #define UPDATE_FLOW_RETURN(ret,new_ret) G_STMT_START { \
129   if (*(ret) == GST_FLOW_OK) \
130     *(ret) = new_ret; \
131 } G_STMT_END
132 
133 #define parent_class gst_h265_decoder_parent_class
134 G_DEFINE_ABSTRACT_TYPE_WITH_CODE (GstH265Decoder, gst_h265_decoder,
135     GST_TYPE_VIDEO_DECODER,
136     G_ADD_PRIVATE (GstH265Decoder);
137     GST_DEBUG_CATEGORY_INIT (gst_h265_decoder_debug, "h265decoder", 0,
138         "H.265 Video Decoder"));
139 
140 static void gst_h265_decoder_finalize (GObject * object);
141 
142 static gboolean gst_h265_decoder_start (GstVideoDecoder * decoder);
143 static gboolean gst_h265_decoder_stop (GstVideoDecoder * decoder);
144 static gboolean gst_h265_decoder_set_format (GstVideoDecoder * decoder,
145     GstVideoCodecState * state);
146 static GstFlowReturn gst_h265_decoder_finish (GstVideoDecoder * decoder);
147 static gboolean gst_h265_decoder_flush (GstVideoDecoder * decoder);
148 static GstFlowReturn gst_h265_decoder_drain (GstVideoDecoder * decoder);
149 static GstFlowReturn gst_h265_decoder_handle_frame (GstVideoDecoder * decoder,
150     GstVideoCodecFrame * frame);
151 
152 static void gst_h265_decoder_finish_current_picture (GstH265Decoder * self,
153     GstFlowReturn * ret);
154 static void gst_h265_decoder_clear_ref_pic_sets (GstH265Decoder * self);
155 static void gst_h265_decoder_clear_dpb (GstH265Decoder * self, gboolean flush);
156 static GstFlowReturn gst_h265_decoder_drain_internal (GstH265Decoder * self);
157 static GstFlowReturn
158 gst_h265_decoder_start_current_picture (GstH265Decoder * self);
159 
160 static void
gst_h265_decoder_class_init(GstH265DecoderClass * klass)161 gst_h265_decoder_class_init (GstH265DecoderClass * klass)
162 {
163   GstVideoDecoderClass *decoder_class = GST_VIDEO_DECODER_CLASS (klass);
164   GObjectClass *object_class = G_OBJECT_CLASS (klass);
165 
166   object_class->finalize = GST_DEBUG_FUNCPTR (gst_h265_decoder_finalize);
167 
168   decoder_class->start = GST_DEBUG_FUNCPTR (gst_h265_decoder_start);
169   decoder_class->stop = GST_DEBUG_FUNCPTR (gst_h265_decoder_stop);
170   decoder_class->set_format = GST_DEBUG_FUNCPTR (gst_h265_decoder_set_format);
171   decoder_class->finish = GST_DEBUG_FUNCPTR (gst_h265_decoder_finish);
172   decoder_class->flush = GST_DEBUG_FUNCPTR (gst_h265_decoder_flush);
173   decoder_class->drain = GST_DEBUG_FUNCPTR (gst_h265_decoder_drain);
174   decoder_class->handle_frame =
175       GST_DEBUG_FUNCPTR (gst_h265_decoder_handle_frame);
176 }
177 
178 static void
gst_h265_decoder_init(GstH265Decoder * self)179 gst_h265_decoder_init (GstH265Decoder * self)
180 {
181   GstH265DecoderPrivate *priv;
182 
183   gst_video_decoder_set_packetized (GST_VIDEO_DECODER (self), TRUE);
184 
185   self->priv = priv = gst_h265_decoder_get_instance_private (self);
186 
187   priv->last_output_poc = G_MININT32;
188 
189   priv->ref_pic_list_tmp = g_array_sized_new (FALSE, TRUE,
190       sizeof (GstH265Picture *), 32);
191   priv->ref_pic_list0 = g_array_sized_new (FALSE, TRUE,
192       sizeof (GstH265Picture *), 32);
193   priv->ref_pic_list1 = g_array_sized_new (FALSE, TRUE,
194       sizeof (GstH265Picture *), 32);
195 }
196 
197 static void
gst_h265_decoder_finalize(GObject * object)198 gst_h265_decoder_finalize (GObject * object)
199 {
200   GstH265Decoder *self = GST_H265_DECODER (object);
201   GstH265DecoderPrivate *priv = self->priv;
202 
203   g_array_unref (priv->ref_pic_list_tmp);
204   g_array_unref (priv->ref_pic_list0);
205   g_array_unref (priv->ref_pic_list1);
206 
207   G_OBJECT_CLASS (parent_class)->finalize (object);
208 }
209 
210 static gboolean
gst_h265_decoder_start(GstVideoDecoder * decoder)211 gst_h265_decoder_start (GstVideoDecoder * decoder)
212 {
213   GstH265Decoder *self = GST_H265_DECODER (decoder);
214   GstH265DecoderPrivate *priv = self->priv;
215 
216   priv->parser = gst_h265_parser_new ();
217   priv->dpb = gst_h265_dpb_new ();
218   priv->new_bitstream = TRUE;
219   priv->prev_nal_is_eos = FALSE;
220 
221   return TRUE;
222 }
223 
224 static gboolean
gst_h265_decoder_stop(GstVideoDecoder * decoder)225 gst_h265_decoder_stop (GstVideoDecoder * decoder)
226 {
227   GstH265Decoder *self = GST_H265_DECODER (decoder);
228   GstH265DecoderPrivate *priv = self->priv;
229 
230   if (self->input_state) {
231     gst_video_codec_state_unref (self->input_state);
232     self->input_state = NULL;
233   }
234 
235   gst_clear_buffer (&priv->codec_data);
236 
237   if (priv->parser) {
238     gst_h265_parser_free (priv->parser);
239     priv->parser = NULL;
240   }
241 
242   if (priv->dpb) {
243     gst_h265_dpb_free (priv->dpb);
244     priv->dpb = NULL;
245   }
246 
247   gst_h265_decoder_clear_ref_pic_sets (self);
248 
249   return TRUE;
250 }
251 
252 static GstFlowReturn
gst_h265_decoder_parse_vps(GstH265Decoder * self,GstH265NalUnit * nalu)253 gst_h265_decoder_parse_vps (GstH265Decoder * self, GstH265NalUnit * nalu)
254 {
255   GstH265DecoderPrivate *priv = self->priv;
256   GstH265VPS vps;
257   GstH265ParserResult pres;
258 
259   pres = gst_h265_parser_parse_vps (priv->parser, nalu, &vps);
260   if (pres != GST_H265_PARSER_OK) {
261     GST_WARNING_OBJECT (self, "Failed to parse VPS, result %d", pres);
262     return GST_FLOW_ERROR;
263   }
264 
265   GST_LOG_OBJECT (self, "VPS parsed");
266 
267   return GST_FLOW_OK;
268 }
269 
270 static gboolean
gst_h265_decoder_is_crop_rect_changed(GstH265Decoder * self,GstH265SPS * sps)271 gst_h265_decoder_is_crop_rect_changed (GstH265Decoder * self, GstH265SPS * sps)
272 {
273   GstH265DecoderPrivate *priv = self->priv;
274 
275   if (priv->conformance_window_flag != sps->conformance_window_flag)
276     return TRUE;
277   if (priv->crop_rect_width != sps->crop_rect_width)
278     return TRUE;
279   if (priv->crop_rect_height != sps->crop_rect_height)
280     return TRUE;
281   if (priv->crop_rect_x != sps->crop_rect_x)
282     return TRUE;
283   if (priv->crop_rect_y != sps->crop_rect_y)
284     return TRUE;
285 
286   return FALSE;
287 }
288 
289 static GstFlowReturn
gst_h265_decoder_process_sps(GstH265Decoder * self,GstH265SPS * sps)290 gst_h265_decoder_process_sps (GstH265Decoder * self, GstH265SPS * sps)
291 {
292   GstH265DecoderPrivate *priv = self->priv;
293   gint max_dpb_size;
294   gint prev_max_dpb_size;
295   gint MaxLumaPS;
296   const gint MaxDpbPicBuf = 6;
297   gint PicSizeInSamplesY;
298   guint8 field_seq_flag = 0;
299   guint8 progressive_source_flag = 0;
300   guint8 interlaced_source_flag = 0;
301   GstFlowReturn ret = GST_FLOW_OK;
302 
303   /* A.4.1 */
304   MaxLumaPS = 35651584;
305   PicSizeInSamplesY = sps->width * sps->height;
306   if (PicSizeInSamplesY <= (MaxLumaPS >> 2))
307     max_dpb_size = MaxDpbPicBuf * 4;
308   else if (PicSizeInSamplesY <= (MaxLumaPS >> 1))
309     max_dpb_size = MaxDpbPicBuf * 2;
310   else if (PicSizeInSamplesY <= ((3 * MaxLumaPS) >> 2))
311     max_dpb_size = (MaxDpbPicBuf * 4) / 3;
312   else
313     max_dpb_size = MaxDpbPicBuf;
314 
315   max_dpb_size = MIN (max_dpb_size, 16);
316 
317   if (sps->vui_parameters_present_flag)
318     field_seq_flag = sps->vui_params.field_seq_flag;
319 
320   progressive_source_flag = sps->profile_tier_level.progressive_source_flag;
321   interlaced_source_flag = sps->profile_tier_level.interlaced_source_flag;
322 
323   prev_max_dpb_size = gst_h265_dpb_get_max_num_pics (priv->dpb);
324   if (priv->width != sps->width || priv->height != sps->height ||
325       prev_max_dpb_size != max_dpb_size ||
326       priv->field_seq_flag != field_seq_flag ||
327       priv->progressive_source_flag != progressive_source_flag ||
328       priv->interlaced_source_flag != interlaced_source_flag ||
329       gst_h265_decoder_is_crop_rect_changed (self, sps)) {
330     GstH265DecoderClass *klass = GST_H265_DECODER_GET_CLASS (self);
331 
332     GST_DEBUG_OBJECT (self,
333         "SPS updated, resolution: %dx%d -> %dx%d, dpb size: %d -> %d, "
334         "field_seq_flag: %d -> %d, progressive_source_flag: %d -> %d, "
335         "interlaced_source_flag: %d -> %d",
336         priv->width, priv->height, sps->width, sps->height,
337         prev_max_dpb_size, max_dpb_size, priv->field_seq_flag, field_seq_flag,
338         priv->progressive_source_flag, progressive_source_flag,
339         priv->interlaced_source_flag, interlaced_source_flag);
340 
341     g_assert (klass->new_sequence);
342 
343     ret = klass->new_sequence (self, sps, max_dpb_size);
344     if (ret != GST_FLOW_OK) {
345       GST_WARNING_OBJECT (self, "subclass does not want accept new sequence");
346       return ret;
347     }
348 
349     priv->width = sps->width;
350     priv->height = sps->height;
351     priv->conformance_window_flag = sps->conformance_window_flag;
352     priv->crop_rect_width = sps->crop_rect_width;
353     priv->crop_rect_height = sps->crop_rect_height;
354     priv->crop_rect_x = sps->crop_rect_x;
355     priv->crop_rect_y = sps->crop_rect_y;
356     priv->field_seq_flag = field_seq_flag;
357     priv->progressive_source_flag = progressive_source_flag;
358     priv->interlaced_source_flag = interlaced_source_flag;
359 
360     gst_h265_dpb_set_max_num_pics (priv->dpb, max_dpb_size);
361   }
362 
363   if (sps->max_latency_increase_plus1[sps->max_sub_layers_minus1]) {
364     priv->SpsMaxLatencyPictures =
365         sps->max_num_reorder_pics[sps->max_sub_layers_minus1] +
366         sps->max_latency_increase_plus1[sps->max_sub_layers_minus1] - 1;
367   }
368 
369   GST_DEBUG_OBJECT (self, "Set DPB max size %d", max_dpb_size);
370 
371   return GST_FLOW_OK;
372 }
373 
374 static GstFlowReturn
gst_h265_decoder_parse_sps(GstH265Decoder * self,GstH265NalUnit * nalu)375 gst_h265_decoder_parse_sps (GstH265Decoder * self, GstH265NalUnit * nalu)
376 {
377   GstH265DecoderPrivate *priv = self->priv;
378   GstH265SPS sps;
379   GstH265ParserResult pres;
380   GstFlowReturn ret = GST_FLOW_OK;
381 
382   pres = gst_h265_parse_sps (priv->parser, nalu, &sps, TRUE);
383   if (pres != GST_H265_PARSER_OK) {
384     GST_WARNING_OBJECT (self, "Failed to parse SPS, result %d", pres);
385     return GST_FLOW_ERROR;
386   }
387 
388   GST_LOG_OBJECT (self, "SPS parsed");
389 
390   ret = gst_h265_decoder_process_sps (self, &sps);
391   if (ret != GST_FLOW_OK) {
392     GST_WARNING_OBJECT (self, "Failed to process SPS");
393   } else if (gst_h265_parser_update_sps (priv->parser,
394           &sps) != GST_H265_PARSER_OK) {
395     GST_WARNING_OBJECT (self, "Failed to update SPS");
396     ret = GST_FLOW_ERROR;
397   }
398 
399   return ret;
400 }
401 
402 static GstFlowReturn
gst_h265_decoder_parse_pps(GstH265Decoder * self,GstH265NalUnit * nalu)403 gst_h265_decoder_parse_pps (GstH265Decoder * self, GstH265NalUnit * nalu)
404 {
405   GstH265DecoderPrivate *priv = self->priv;
406   GstH265PPS pps;
407   GstH265ParserResult pres;
408 
409   pres = gst_h265_parser_parse_pps (priv->parser, nalu, &pps);
410   if (pres != GST_H265_PARSER_OK) {
411     GST_WARNING_OBJECT (self, "Failed to parse PPS, result %d", pres);
412     return GST_FLOW_ERROR;
413   }
414 
415   GST_LOG_OBJECT (self, "PPS parsed");
416 
417   return GST_FLOW_OK;
418 }
419 
420 static GstFlowReturn
gst_h265_decoder_parse_sei(GstH265Decoder * self,GstH265NalUnit * nalu)421 gst_h265_decoder_parse_sei (GstH265Decoder * self, GstH265NalUnit * nalu)
422 {
423   GstH265DecoderPrivate *priv = self->priv;
424   GstH265ParserResult pres;
425   GArray *messages = NULL;
426   guint i;
427 
428   pres = gst_h265_parser_parse_sei (priv->parser, nalu, &messages);
429   if (pres != GST_H265_PARSER_OK) {
430     GST_WARNING_OBJECT (self, "Failed to parse SEI, result %d", pres);
431 
432     /* XXX: Ignore error from SEI parsing, it might be malformed bitstream,
433      * or our fault. But shouldn't be critical  */
434     g_clear_pointer (&messages, g_array_unref);
435     return GST_FLOW_OK;
436   }
437 
438   for (i = 0; i < messages->len; i++) {
439     GstH265SEIMessage *sei = &g_array_index (messages, GstH265SEIMessage, i);
440 
441     switch (sei->payloadType) {
442       case GST_H265_SEI_PIC_TIMING:
443         priv->cur_pic_struct = sei->payload.pic_timing.pic_struct;
444         priv->cur_source_scan_type = sei->payload.pic_timing.source_scan_type;
445         priv->cur_duplicate_flag = sei->payload.pic_timing.duplicate_flag;
446 
447         GST_TRACE_OBJECT (self,
448             "Picture Timing SEI, pic_struct: %d, source_scan_type: %d, "
449             "duplicate_flag: %d", priv->cur_pic_struct,
450             priv->cur_source_scan_type, priv->cur_duplicate_flag);
451         break;
452       default:
453         break;
454     }
455   }
456 
457   g_array_free (messages, TRUE);
458   GST_LOG_OBJECT (self, "SEI parsed");
459 
460   return GST_FLOW_OK;
461 }
462 
463 static void
gst_h265_decoder_process_ref_pic_lists(GstH265Decoder * self,GstH265Picture * curr_pic,GstH265Slice * slice,GArray ** ref_pic_list0,GArray ** ref_pic_list1)464 gst_h265_decoder_process_ref_pic_lists (GstH265Decoder * self,
465     GstH265Picture * curr_pic, GstH265Slice * slice,
466     GArray ** ref_pic_list0, GArray ** ref_pic_list1)
467 {
468   GstH265DecoderPrivate *priv = self->priv;
469   GstH265RefPicListModification *ref_mod =
470       &slice->header.ref_pic_list_modification;
471   GstH265PPSSccExtensionParams *scc_ext =
472       &slice->header.pps->pps_scc_extension_params;
473   GArray *tmp_refs;
474   gint num_tmp_refs, i;
475 
476   *ref_pic_list0 = priv->ref_pic_list0;
477   *ref_pic_list1 = priv->ref_pic_list1;
478 
479   /* There is nothing to be done for I slices */
480   if (GST_H265_IS_I_SLICE (&slice->header))
481     return;
482 
483   /* Inifinit loop prevention */
484   if (self->NumPocStCurrBefore == 0 && self->NumPocStCurrAfter == 0 &&
485       self->NumPocLtCurr == 0 && !scc_ext->pps_curr_pic_ref_enabled_flag) {
486     GST_WARNING_OBJECT (self,
487         "Expected references, got none, preventing infinit loop.");
488     return;
489   }
490 
491   /* 8.3.4 Deriving l0 */
492   tmp_refs = priv->ref_pic_list_tmp;
493 
494   /* (8-8)
495    * Deriving l0 consist of appending in loop RefPicSetStCurrBefore,
496    * RefPicSetStCurrAfter and RefPicSetLtCurr until NumRpsCurrTempList0 item
497    * has been reached.
498    */
499 
500   /* NumRpsCurrTempList0 */
501   num_tmp_refs = MAX (slice->header.num_ref_idx_l0_active_minus1 + 1,
502       self->NumPicTotalCurr);
503 
504   while (tmp_refs->len < num_tmp_refs) {
505     for (i = 0; i < self->NumPocStCurrBefore && tmp_refs->len < num_tmp_refs;
506         i++)
507       g_array_append_val (tmp_refs, self->RefPicSetStCurrBefore[i]);
508     for (i = 0; i < self->NumPocStCurrAfter && tmp_refs->len < num_tmp_refs;
509         i++)
510       g_array_append_val (tmp_refs, self->RefPicSetStCurrAfter[i]);
511     for (i = 0; i < self->NumPocLtCurr && tmp_refs->len < num_tmp_refs; i++)
512       g_array_append_val (tmp_refs, self->RefPicSetLtCurr[i]);
513     if (scc_ext->pps_curr_pic_ref_enabled_flag)
514       g_array_append_val (tmp_refs, curr_pic);
515   }
516 
517   /* (8-9)
518    * If needed, apply the modificaiton base on the lookup table found in the
519    * slice header (list_entry_l0).
520    */
521   for (i = 0; i <= slice->header.num_ref_idx_l0_active_minus1; i++) {
522     GstH265Picture **tmp = (GstH265Picture **) tmp_refs->data;
523 
524     if (ref_mod->ref_pic_list_modification_flag_l0)
525       g_array_append_val (*ref_pic_list0, tmp[ref_mod->list_entry_l0[i]]);
526     else
527       g_array_append_val (*ref_pic_list0, tmp[i]);
528   }
529 
530   if (scc_ext->pps_curr_pic_ref_enabled_flag &&
531       !ref_mod->ref_pic_list_modification_flag_l0 &&
532       num_tmp_refs > (slice->header.num_ref_idx_l0_active_minus1 + 1)) {
533     g_array_index (*ref_pic_list0, GstH265Picture *,
534         slice->header.num_ref_idx_l0_active_minus1) = curr_pic;
535   }
536 
537   g_array_set_size (tmp_refs, 0);
538 
539   /* For P slices we only need l0 */
540   if (GST_H265_IS_P_SLICE (&slice->header))
541     return;
542 
543   /* 8.3.4 Deriving l1 */
544   /* (8-10)
545    * Deriving l1 consist of appending in loop RefPicSetStCurrAfter,
546    * RefPicSetStCurrBefore and RefPicSetLtCurr until NumRpsCurrTempList0 item
547    * has been reached.
548    */
549 
550   /* NumRpsCurrTempList1 */
551   num_tmp_refs = MAX (slice->header.num_ref_idx_l1_active_minus1 + 1,
552       self->NumPicTotalCurr);
553 
554   while (tmp_refs->len < num_tmp_refs) {
555     for (i = 0; i < self->NumPocStCurrAfter && tmp_refs->len < num_tmp_refs;
556         i++)
557       g_array_append_val (tmp_refs, self->RefPicSetStCurrAfter[i]);
558     for (i = 0; i < self->NumPocStCurrBefore && tmp_refs->len < num_tmp_refs;
559         i++)
560       g_array_append_val (tmp_refs, self->RefPicSetStCurrBefore[i]);
561     for (i = 0; i < self->NumPocLtCurr && tmp_refs->len < num_tmp_refs; i++)
562       g_array_append_val (tmp_refs, self->RefPicSetLtCurr[i]);
563     if (scc_ext->pps_curr_pic_ref_enabled_flag)
564       g_array_append_val (tmp_refs, curr_pic);
565   }
566 
567   /* (8-11)
568    * If needed, apply the modificaiton base on the lookup table found in the
569    * slice header (list_entry_l1).
570    */
571   for (i = 0; i <= slice->header.num_ref_idx_l1_active_minus1; i++) {
572     GstH265Picture **tmp = (GstH265Picture **) tmp_refs->data;
573 
574     if (ref_mod->ref_pic_list_modification_flag_l1)
575       g_array_append_val (*ref_pic_list1, tmp[ref_mod->list_entry_l1[i]]);
576     else
577       g_array_append_val (*ref_pic_list1, tmp[i]);
578   }
579 
580   g_array_set_size (tmp_refs, 0);
581 }
582 
583 static GstFlowReturn
gst_h265_decoder_decode_slice(GstH265Decoder * self)584 gst_h265_decoder_decode_slice (GstH265Decoder * self)
585 {
586   GstH265DecoderClass *klass = GST_H265_DECODER_GET_CLASS (self);
587   GstH265DecoderPrivate *priv = self->priv;
588   GstH265Slice *slice = &priv->current_slice;
589   GstH265Picture *picture = priv->current_picture;
590   GArray *l0 = NULL;
591   GArray *l1 = NULL;
592   GstFlowReturn ret = GST_FLOW_OK;
593 
594   if (!picture) {
595     GST_ERROR_OBJECT (self, "No current picture");
596     return GST_FLOW_ERROR;
597   }
598 
599   g_assert (klass->decode_slice);
600 
601   if (priv->process_ref_pic_lists) {
602     l0 = priv->ref_pic_list0;
603     l1 = priv->ref_pic_list1;
604     gst_h265_decoder_process_ref_pic_lists (self, picture, slice, &l0, &l1);
605   }
606 
607   ret = klass->decode_slice (self, picture, slice, l0, l1);
608 
609   if (priv->process_ref_pic_lists) {
610     g_array_set_size (l0, 0);
611     g_array_set_size (l1, 0);
612   }
613 
614   return ret;
615 }
616 
617 static GstFlowReturn
gst_h265_decoder_preprocess_slice(GstH265Decoder * self,GstH265Slice * slice)618 gst_h265_decoder_preprocess_slice (GstH265Decoder * self, GstH265Slice * slice)
619 {
620   GstH265DecoderPrivate *priv = self->priv;
621   const GstH265SliceHdr *slice_hdr = &slice->header;
622 
623   if (priv->current_picture && slice_hdr->first_slice_segment_in_pic_flag) {
624     GST_WARNING_OBJECT (self,
625         "Current picture is not finished but slice header has "
626         "first_slice_segment_in_pic_flag");
627     return GST_FLOW_ERROR;
628   }
629 
630   return GST_FLOW_OK;
631 }
632 
633 static GstFlowReturn
gst_h265_decoder_parse_slice(GstH265Decoder * self,GstH265NalUnit * nalu,GstClockTime pts)634 gst_h265_decoder_parse_slice (GstH265Decoder * self, GstH265NalUnit * nalu,
635     GstClockTime pts)
636 {
637   GstH265DecoderPrivate *priv = self->priv;
638   GstH265ParserResult pres = GST_H265_PARSER_OK;
639   GstFlowReturn ret = GST_FLOW_OK;
640 
641   memset (&priv->current_slice, 0, sizeof (GstH265Slice));
642 
643   pres = gst_h265_parser_parse_slice_hdr (priv->parser, nalu,
644       &priv->current_slice.header);
645 
646   if (pres != GST_H265_PARSER_OK) {
647     GST_ERROR_OBJECT (self, "Failed to parse slice header, ret %d", pres);
648     memset (&priv->current_slice, 0, sizeof (GstH265Slice));
649 
650     return GST_FLOW_ERROR;
651   }
652 
653   /* NOTE: gst_h265_parser_parse_slice_hdr() allocates array
654    * GstH265SliceHdr::entry_point_offset_minus1 but we don't use it
655    * in this h265decoder baseclass at the moment
656    */
657   gst_h265_slice_hdr_free (&priv->current_slice.header);
658 
659   priv->current_slice.nalu = *nalu;
660 
661   if (priv->current_slice.header.dependent_slice_segment_flag) {
662     GstH265SliceHdr *slice_hdr = &priv->current_slice.header;
663     GstH265SliceHdr *indep_slice_hdr = &priv->prev_independent_slice.header;
664 
665     memcpy (&slice_hdr->type, &indep_slice_hdr->type,
666         G_STRUCT_OFFSET (GstH265SliceHdr, num_entry_point_offsets) -
667         G_STRUCT_OFFSET (GstH265SliceHdr, type));
668   } else {
669     priv->prev_independent_slice = priv->current_slice;
670     memset (&priv->prev_independent_slice.nalu, 0, sizeof (GstH265NalUnit));
671   }
672 
673   ret = gst_h265_decoder_preprocess_slice (self, &priv->current_slice);
674   if (ret != GST_FLOW_OK)
675     return ret;
676 
677   priv->active_pps = priv->current_slice.header.pps;
678   priv->active_sps = priv->active_pps->sps;
679 
680   if (!priv->current_picture) {
681     GstH265DecoderClass *klass = GST_H265_DECODER_GET_CLASS (self);
682     GstH265Picture *picture;
683     GstFlowReturn ret = GST_FLOW_OK;
684 
685     g_assert (priv->current_frame);
686 
687     picture = gst_h265_picture_new ();
688     picture->pts = pts;
689     /* This allows accessing the frame from the picture. */
690     picture->system_frame_number = priv->current_frame->system_frame_number;
691 
692     priv->current_picture = picture;
693 
694     if (klass->new_picture)
695       ret = klass->new_picture (self, priv->current_frame, picture);
696 
697     if (ret != GST_FLOW_OK) {
698       GST_WARNING_OBJECT (self, "subclass does not want accept new picture");
699       priv->current_picture = NULL;
700       gst_h265_picture_unref (picture);
701       return ret;
702     }
703 
704     ret = gst_h265_decoder_start_current_picture (self);
705     if (ret != GST_FLOW_OK) {
706       GST_WARNING_OBJECT (self, "start picture failed");
707       return ret;
708     }
709 
710     /* this picture was dropped */
711     if (!priv->current_picture)
712       return GST_FLOW_OK;
713   }
714 
715   return gst_h265_decoder_decode_slice (self);
716 }
717 
718 static GstFlowReturn
gst_h265_decoder_decode_nal(GstH265Decoder * self,GstH265NalUnit * nalu,GstClockTime pts)719 gst_h265_decoder_decode_nal (GstH265Decoder * self, GstH265NalUnit * nalu,
720     GstClockTime pts)
721 {
722   GstH265DecoderPrivate *priv = self->priv;
723   GstFlowReturn ret = GST_FLOW_OK;
724 
725   GST_LOG_OBJECT (self, "Parsed nal type: %d, offset %d, size %d",
726       nalu->type, nalu->offset, nalu->size);
727 
728   switch (nalu->type) {
729     case GST_H265_NAL_VPS:
730       ret = gst_h265_decoder_parse_vps (self, nalu);
731       break;
732     case GST_H265_NAL_SPS:
733       ret = gst_h265_decoder_parse_sps (self, nalu);
734       break;
735     case GST_H265_NAL_PPS:
736       ret = gst_h265_decoder_parse_pps (self, nalu);
737       break;
738     case GST_H265_NAL_PREFIX_SEI:
739     case GST_H265_NAL_SUFFIX_SEI:
740       ret = gst_h265_decoder_parse_sei (self, nalu);
741       break;
742     case GST_H265_NAL_SLICE_TRAIL_N:
743     case GST_H265_NAL_SLICE_TRAIL_R:
744     case GST_H265_NAL_SLICE_TSA_N:
745     case GST_H265_NAL_SLICE_TSA_R:
746     case GST_H265_NAL_SLICE_STSA_N:
747     case GST_H265_NAL_SLICE_STSA_R:
748     case GST_H265_NAL_SLICE_RADL_N:
749     case GST_H265_NAL_SLICE_RADL_R:
750     case GST_H265_NAL_SLICE_RASL_N:
751     case GST_H265_NAL_SLICE_RASL_R:
752     case GST_H265_NAL_SLICE_BLA_W_LP:
753     case GST_H265_NAL_SLICE_BLA_W_RADL:
754     case GST_H265_NAL_SLICE_BLA_N_LP:
755     case GST_H265_NAL_SLICE_IDR_W_RADL:
756     case GST_H265_NAL_SLICE_IDR_N_LP:
757     case GST_H265_NAL_SLICE_CRA_NUT:
758       ret = gst_h265_decoder_parse_slice (self, nalu, pts);
759       priv->new_bitstream = FALSE;
760       priv->prev_nal_is_eos = FALSE;
761       break;
762     case GST_H265_NAL_EOB:
763       priv->new_bitstream = TRUE;
764       break;
765     case GST_H265_NAL_EOS:
766       priv->prev_nal_is_eos = TRUE;
767       break;
768     default:
769       break;
770   }
771 
772   return ret;
773 }
774 
775 static void
gst_h265_decoder_format_from_caps(GstH265Decoder * self,GstCaps * caps,GstH265DecoderFormat * format,GstH265DecoderAlign * align)776 gst_h265_decoder_format_from_caps (GstH265Decoder * self, GstCaps * caps,
777     GstH265DecoderFormat * format, GstH265DecoderAlign * align)
778 {
779   if (format)
780     *format = GST_H265_DECODER_FORMAT_NONE;
781 
782   if (align)
783     *align = GST_H265_DECODER_ALIGN_NONE;
784 
785   if (!gst_caps_is_fixed (caps)) {
786     GST_WARNING_OBJECT (self, "Caps wasn't fixed");
787     return;
788   }
789 
790   GST_DEBUG_OBJECT (self, "parsing caps: %" GST_PTR_FORMAT, caps);
791 
792   if (caps && gst_caps_get_size (caps) > 0) {
793     GstStructure *s = gst_caps_get_structure (caps, 0);
794     const gchar *str = NULL;
795 
796     if (format) {
797       if ((str = gst_structure_get_string (s, "stream-format"))) {
798         if (strcmp (str, "hvc1") == 0)
799           *format = GST_H265_DECODER_FORMAT_HVC1;
800         else if (strcmp (str, "hev1") == 0)
801           *format = GST_H265_DECODER_FORMAT_HEV1;
802         else if (strcmp (str, "byte-stream") == 0)
803           *format = GST_H265_DECODER_FORMAT_BYTE;
804       }
805     }
806 
807     if (align) {
808       if ((str = gst_structure_get_string (s, "alignment"))) {
809         if (strcmp (str, "au") == 0)
810           *align = GST_H265_DECODER_ALIGN_AU;
811         else if (strcmp (str, "nal") == 0)
812           *align = GST_H265_DECODER_ALIGN_NAL;
813       }
814     }
815   }
816 }
817 
818 static GstFlowReturn
gst_h265_decoder_parse_codec_data(GstH265Decoder * self,const guint8 * data,gsize size)819 gst_h265_decoder_parse_codec_data (GstH265Decoder * self, const guint8 * data,
820     gsize size)
821 {
822   GstH265DecoderPrivate *priv = self->priv;
823   guint num_nal_arrays;
824   guint off;
825   guint num_nals, i, j;
826   GstH265ParserResult pres;
827   GstH265NalUnit nalu;
828   GstFlowReturn ret = GST_FLOW_OK;
829 
830   /* parse the hvcC data */
831   if (size < 23) {
832     GST_WARNING_OBJECT (self, "hvcC too small");
833     return GST_FLOW_ERROR;
834   }
835 
836   /* wrong hvcC version */
837   if (data[0] != 0 && data[0] != 1) {
838     return GST_FLOW_ERROR;
839   }
840 
841   priv->nal_length_size = (data[21] & 0x03) + 1;
842   GST_DEBUG_OBJECT (self, "nal length size %u", priv->nal_length_size);
843 
844   num_nal_arrays = data[22];
845   off = 23;
846 
847   for (i = 0; i < num_nal_arrays; i++) {
848     if (off + 3 >= size) {
849       GST_WARNING_OBJECT (self, "hvcC too small");
850       return GST_FLOW_ERROR;
851     }
852 
853     num_nals = GST_READ_UINT16_BE (data + off + 1);
854     off += 3;
855     for (j = 0; j < num_nals; j++) {
856       pres = gst_h265_parser_identify_nalu_hevc (priv->parser,
857           data, off, size, 2, &nalu);
858 
859       if (pres != GST_H265_PARSER_OK) {
860         GST_WARNING_OBJECT (self, "hvcC too small");
861         return GST_FLOW_ERROR;
862       }
863 
864       switch (nalu.type) {
865         case GST_H265_NAL_VPS:
866           ret = gst_h265_decoder_parse_vps (self, &nalu);
867           if (ret != GST_FLOW_OK) {
868             GST_WARNING_OBJECT (self, "Failed to parse VPS");
869             return ret;
870           }
871           break;
872         case GST_H265_NAL_SPS:
873           ret = gst_h265_decoder_parse_sps (self, &nalu);
874           if (ret != GST_FLOW_OK) {
875             GST_WARNING_OBJECT (self, "Failed to parse SPS");
876             return ret;
877           }
878           break;
879         case GST_H265_NAL_PPS:
880           ret = gst_h265_decoder_parse_pps (self, &nalu);
881           if (ret != GST_FLOW_OK) {
882             GST_WARNING_OBJECT (self, "Failed to parse PPS");
883             return ret;
884           }
885           break;
886         default:
887           break;
888       }
889 
890       off = nalu.offset + nalu.size;
891     }
892   }
893 
894   return GST_FLOW_OK;
895 }
896 
897 static gboolean
gst_h265_decoder_set_format(GstVideoDecoder * decoder,GstVideoCodecState * state)898 gst_h265_decoder_set_format (GstVideoDecoder * decoder,
899     GstVideoCodecState * state)
900 {
901   GstH265Decoder *self = GST_H265_DECODER (decoder);
902   GstH265DecoderPrivate *priv = self->priv;
903 
904   GST_DEBUG_OBJECT (decoder, "Set format");
905 
906   if (self->input_state)
907     gst_video_codec_state_unref (self->input_state);
908 
909   self->input_state = gst_video_codec_state_ref (state);
910 
911   if (state->caps) {
912     GstStructure *str;
913     const GValue *codec_data_value;
914     GstH265DecoderFormat format;
915     GstH265DecoderAlign align;
916 
917     gst_h265_decoder_format_from_caps (self, state->caps, &format, &align);
918 
919     str = gst_caps_get_structure (state->caps, 0);
920     codec_data_value = gst_structure_get_value (str, "codec_data");
921 
922     if (GST_VALUE_HOLDS_BUFFER (codec_data_value)) {
923       gst_buffer_replace (&priv->codec_data,
924           gst_value_get_buffer (codec_data_value));
925     } else {
926       gst_buffer_replace (&priv->codec_data, NULL);
927     }
928 
929     if (format == GST_H265_DECODER_FORMAT_NONE) {
930       /* codec_data implies packetized */
931       if (codec_data_value != NULL) {
932         GST_WARNING_OBJECT (self,
933             "video/x-h265 caps with codec_data but no stream-format=hev1 or hvc1");
934         format = GST_H265_DECODER_FORMAT_HEV1;
935       } else {
936         /* otherwise assume bytestream input */
937         GST_WARNING_OBJECT (self,
938             "video/x-h265 caps without codec_data or stream-format");
939         format = GST_H265_DECODER_FORMAT_BYTE;
940       }
941     }
942 
943     if (format == GST_H265_DECODER_FORMAT_HEV1 ||
944         format == GST_H265_DECODER_FORMAT_HVC1) {
945       if (codec_data_value == NULL) {
946         /* Try it with size 4 anyway */
947         priv->nal_length_size = 4;
948         GST_WARNING_OBJECT (self,
949             "packetized format without codec data, assuming nal length size is 4");
950       }
951 
952       /* AVC implies alignment=au */
953       if (align == GST_H265_DECODER_ALIGN_NONE)
954         align = GST_H265_DECODER_ALIGN_AU;
955     }
956 
957     if (format == GST_H265_DECODER_FORMAT_BYTE) {
958       if (codec_data_value != NULL) {
959         GST_WARNING_OBJECT (self, "bytestream with codec data");
960       }
961     }
962 
963     priv->in_format = format;
964     priv->align = align;
965   }
966 
967   if (priv->codec_data) {
968     GstMapInfo map;
969 
970     gst_buffer_map (priv->codec_data, &map, GST_MAP_READ);
971     if (gst_h265_decoder_parse_codec_data (self, map.data, map.size) !=
972         GST_FLOW_OK) {
973       /* keep going without error.
974        * Probably inband SPS/PPS might be valid data */
975       GST_WARNING_OBJECT (self, "Failed to handle codec data");
976     }
977     gst_buffer_unmap (priv->codec_data, &map);
978   }
979 
980   return TRUE;
981 }
982 
983 static gboolean
gst_h265_decoder_flush(GstVideoDecoder * decoder)984 gst_h265_decoder_flush (GstVideoDecoder * decoder)
985 {
986   GstH265Decoder *self = GST_H265_DECODER (decoder);
987 
988   gst_h265_decoder_clear_dpb (self, TRUE);
989 
990   return TRUE;
991 }
992 
993 static GstFlowReturn
gst_h265_decoder_drain(GstVideoDecoder * decoder)994 gst_h265_decoder_drain (GstVideoDecoder * decoder)
995 {
996   GstH265Decoder *self = GST_H265_DECODER (decoder);
997 
998   /* dpb will be cleared by this method */
999   return gst_h265_decoder_drain_internal (self);
1000 }
1001 
1002 static GstFlowReturn
gst_h265_decoder_finish(GstVideoDecoder * decoder)1003 gst_h265_decoder_finish (GstVideoDecoder * decoder)
1004 {
1005   return gst_h265_decoder_drain (decoder);
1006 }
1007 
1008 static gboolean
gst_h265_decoder_fill_picture_from_slice(GstH265Decoder * self,const GstH265Slice * slice,GstH265Picture * picture)1009 gst_h265_decoder_fill_picture_from_slice (GstH265Decoder * self,
1010     const GstH265Slice * slice, GstH265Picture * picture)
1011 {
1012   GstH265DecoderPrivate *priv = self->priv;
1013   const GstH265SliceHdr *slice_hdr = &slice->header;
1014   const GstH265NalUnit *nalu = &slice->nalu;
1015 
1016   if (nalu->type >= GST_H265_NAL_SLICE_BLA_W_LP &&
1017       nalu->type <= GST_H265_NAL_SLICE_CRA_NUT)
1018     picture->RapPicFlag = TRUE;
1019 
1020   /* NoRaslOutputFlag == 1 if the current picture is
1021    * 1) an IDR picture
1022    * 2) a BLA picture
1023    * 3) a CRA picture that is the first access unit in the bitstream
1024    * 4) first picture that follows an end of sequence NAL unit in decoding order
1025    * 5) has HandleCraAsBlaFlag == 1 (set by external means, so not considering )
1026    */
1027   if (GST_H265_IS_NAL_TYPE_IDR (nalu->type) ||
1028       GST_H265_IS_NAL_TYPE_BLA (nalu->type) ||
1029       (GST_H265_IS_NAL_TYPE_CRA (nalu->type) && priv->new_bitstream) ||
1030       priv->prev_nal_is_eos) {
1031     picture->NoRaslOutputFlag = TRUE;
1032   }
1033 
1034   if (GST_H265_IS_NAL_TYPE_IRAP (nalu->type)) {
1035     picture->IntraPicFlag = TRUE;
1036     priv->associated_irap_NoRaslOutputFlag = picture->NoRaslOutputFlag;
1037   }
1038 
1039   if (GST_H265_IS_NAL_TYPE_RASL (nalu->type) &&
1040       priv->associated_irap_NoRaslOutputFlag) {
1041     picture->output_flag = FALSE;
1042   } else {
1043     picture->output_flag = slice_hdr->pic_output_flag;
1044   }
1045 
1046   return TRUE;
1047 }
1048 
1049 #define RSV_VCL_N10 10
1050 #define RSV_VCL_N12 12
1051 #define RSV_VCL_N14 14
1052 
1053 static gboolean
nal_is_ref(guint8 nal_type)1054 nal_is_ref (guint8 nal_type)
1055 {
1056   gboolean ret = FALSE;
1057   switch (nal_type) {
1058     case GST_H265_NAL_SLICE_TRAIL_N:
1059     case GST_H265_NAL_SLICE_TSA_N:
1060     case GST_H265_NAL_SLICE_STSA_N:
1061     case GST_H265_NAL_SLICE_RADL_N:
1062     case GST_H265_NAL_SLICE_RASL_N:
1063     case RSV_VCL_N10:
1064     case RSV_VCL_N12:
1065     case RSV_VCL_N14:
1066       ret = FALSE;
1067       break;
1068     default:
1069       ret = TRUE;
1070       break;
1071   }
1072   return ret;
1073 }
1074 
1075 static gboolean
gst_h265_decoder_calculate_poc(GstH265Decoder * self,const GstH265Slice * slice,GstH265Picture * picture)1076 gst_h265_decoder_calculate_poc (GstH265Decoder * self,
1077     const GstH265Slice * slice, GstH265Picture * picture)
1078 {
1079   GstH265DecoderPrivate *priv = self->priv;
1080   const GstH265SliceHdr *slice_hdr = &slice->header;
1081   const GstH265NalUnit *nalu = &slice->nalu;
1082   const GstH265SPS *sps = priv->active_sps;
1083   gint32 MaxPicOrderCntLsb = 1 << (sps->log2_max_pic_order_cnt_lsb_minus4 + 4);
1084   gboolean is_irap;
1085 
1086   GST_DEBUG_OBJECT (self, "decode PicOrderCntVal");
1087 
1088   priv->prev_poc_lsb = priv->poc_lsb;
1089   priv->prev_poc_msb = priv->poc_msb;
1090 
1091   is_irap = GST_H265_IS_NAL_TYPE_IRAP (nalu->type);
1092 
1093   if (!(is_irap && picture->NoRaslOutputFlag)) {
1094     priv->prev_poc_lsb = priv->prev_tid0pic_poc_lsb;
1095     priv->prev_poc_msb = priv->prev_tid0pic_poc_msb;
1096   }
1097 
1098   /* Finding PicOrderCntMsb */
1099   if (is_irap && picture->NoRaslOutputFlag) {
1100     priv->poc_msb = 0;
1101   } else {
1102     /* (8-1) */
1103     if ((slice_hdr->pic_order_cnt_lsb < priv->prev_poc_lsb) &&
1104         ((priv->prev_poc_lsb - slice_hdr->pic_order_cnt_lsb) >=
1105             (MaxPicOrderCntLsb / 2)))
1106       priv->poc_msb = priv->prev_poc_msb + MaxPicOrderCntLsb;
1107 
1108     else if ((slice_hdr->pic_order_cnt_lsb > priv->prev_poc_lsb) &&
1109         ((slice_hdr->pic_order_cnt_lsb - priv->prev_poc_lsb) >
1110             (MaxPicOrderCntLsb / 2)))
1111       priv->poc_msb = priv->prev_poc_msb - MaxPicOrderCntLsb;
1112 
1113     else
1114       priv->poc_msb = priv->prev_poc_msb;
1115   }
1116 
1117   /* (8-2) */
1118   priv->poc = picture->pic_order_cnt =
1119       priv->poc_msb + slice_hdr->pic_order_cnt_lsb;
1120   priv->poc_lsb = picture->pic_order_cnt_lsb = slice_hdr->pic_order_cnt_lsb;
1121 
1122   if (GST_H265_IS_NAL_TYPE_IDR (nalu->type)) {
1123     picture->pic_order_cnt = 0;
1124     picture->pic_order_cnt_lsb = 0;
1125     priv->poc_lsb = 0;
1126     priv->poc_msb = 0;
1127     priv->prev_poc_lsb = 0;
1128     priv->prev_poc_msb = 0;
1129     priv->prev_tid0pic_poc_lsb = 0;
1130     priv->prev_tid0pic_poc_msb = 0;
1131   }
1132 
1133   GST_DEBUG_OBJECT (self,
1134       "PicOrderCntVal %d, (lsb %d)", picture->pic_order_cnt,
1135       picture->pic_order_cnt_lsb);
1136 
1137   if (nalu->temporal_id_plus1 == 1 && !GST_H265_IS_NAL_TYPE_RASL (nalu->type) &&
1138       !GST_H265_IS_NAL_TYPE_RADL (nalu->type) && nal_is_ref (nalu->type)) {
1139     priv->prev_tid0pic_poc_lsb = slice_hdr->pic_order_cnt_lsb;
1140     priv->prev_tid0pic_poc_msb = priv->poc_msb;
1141   }
1142 
1143   return TRUE;
1144 }
1145 
1146 static gboolean
gst_h265_decoder_set_buffer_flags(GstH265Decoder * self,GstH265Picture * picture)1147 gst_h265_decoder_set_buffer_flags (GstH265Decoder * self,
1148     GstH265Picture * picture)
1149 {
1150   GstH265DecoderPrivate *priv = self->priv;
1151 
1152   switch (picture->pic_struct) {
1153     case GST_H265_SEI_PIC_STRUCT_FRAME:
1154       break;
1155     case GST_H265_SEI_PIC_STRUCT_TOP_FIELD:
1156     case GST_H265_SEI_PIC_STRUCT_TOP_PAIRED_PREVIOUS_BOTTOM:
1157     case GST_H265_SEI_PIC_STRUCT_TOP_PAIRED_NEXT_BOTTOM:
1158       if (!priv->field_seq_flag) {
1159         GST_FIXME_OBJECT (self,
1160             "top-field with field_seq_flag == 0, what does it mean?");
1161       } else {
1162         picture->buffer_flags = GST_VIDEO_BUFFER_FLAG_TOP_FIELD;
1163       }
1164       break;
1165     case GST_H265_SEI_PIC_STRUCT_BOTTOM_FIELD:
1166     case GST_H265_SEI_PIC_STRUCT_BOTTOM_PAIRED_PREVIOUS_TOP:
1167     case GST_H265_SEI_PIC_STRUCT_BOTTOM_PAIRED_NEXT_TOP:
1168       if (!priv->field_seq_flag) {
1169         GST_FIXME_OBJECT (self,
1170             "bottom-field with field_seq_flag == 0, what does it mean?");
1171       } else {
1172         picture->buffer_flags = GST_VIDEO_BUFFER_FLAG_BOTTOM_FIELD;
1173       }
1174       break;
1175     case GST_H265_SEI_PIC_STRUCT_TOP_BOTTOM:
1176       if (priv->field_seq_flag) {
1177         GST_FIXME_OBJECT (self,
1178             "TFF with field_seq_flag == 1, what does it mean?");
1179       } else {
1180         picture->buffer_flags =
1181             GST_VIDEO_BUFFER_FLAG_INTERLACED | GST_VIDEO_BUFFER_FLAG_TFF;
1182       }
1183       break;
1184     case GST_H265_SEI_PIC_STRUCT_BOTTOM_TOP:
1185       if (priv->field_seq_flag) {
1186         GST_FIXME_OBJECT (self,
1187             "BFF with field_seq_flag == 1, what does it mean?");
1188       } else {
1189         picture->buffer_flags = GST_VIDEO_BUFFER_FLAG_INTERLACED;
1190       }
1191       break;
1192     default:
1193       GST_FIXME_OBJECT (self, "Unhandled picture time SEI pic_struct %d",
1194           picture->pic_struct);
1195       break;
1196   }
1197 
1198   return TRUE;
1199 }
1200 
1201 static gboolean
gst_h265_decoder_init_current_picture(GstH265Decoder * self)1202 gst_h265_decoder_init_current_picture (GstH265Decoder * self)
1203 {
1204   GstH265DecoderPrivate *priv = self->priv;
1205 
1206   if (!gst_h265_decoder_fill_picture_from_slice (self, &priv->current_slice,
1207           priv->current_picture)) {
1208     return FALSE;
1209   }
1210 
1211   if (!gst_h265_decoder_calculate_poc (self,
1212           &priv->current_slice, priv->current_picture))
1213     return FALSE;
1214 
1215   /* Use picture struct parsed from picture timing SEI */
1216   priv->current_picture->pic_struct = priv->cur_pic_struct;
1217   priv->current_picture->source_scan_type = priv->cur_source_scan_type;
1218   priv->current_picture->duplicate_flag = priv->cur_duplicate_flag;
1219   gst_h265_decoder_set_buffer_flags (self, priv->current_picture);
1220 
1221   return TRUE;
1222 }
1223 
1224 static gboolean
has_entry_in_rps(GstH265Picture * dpb_pic,GstH265Picture ** rps_list,guint rps_list_length)1225 has_entry_in_rps (GstH265Picture * dpb_pic,
1226     GstH265Picture ** rps_list, guint rps_list_length)
1227 {
1228   guint i;
1229 
1230   if (!dpb_pic || !rps_list || !rps_list_length)
1231     return FALSE;
1232 
1233   for (i = 0; i < rps_list_length; i++) {
1234     if (rps_list[i] && rps_list[i]->pic_order_cnt == dpb_pic->pic_order_cnt)
1235       return TRUE;
1236   }
1237   return FALSE;
1238 }
1239 
1240 static void
gst_h265_decoder_clear_ref_pic_sets(GstH265Decoder * self)1241 gst_h265_decoder_clear_ref_pic_sets (GstH265Decoder * self)
1242 {
1243   guint i;
1244 
1245   for (i = 0; i < 16; i++) {
1246     gst_h265_picture_replace (&self->RefPicSetLtCurr[i], NULL);
1247     gst_h265_picture_replace (&self->RefPicSetLtFoll[i], NULL);
1248     gst_h265_picture_replace (&self->RefPicSetStCurrBefore[i], NULL);
1249     gst_h265_picture_replace (&self->RefPicSetStCurrAfter[i], NULL);
1250     gst_h265_picture_replace (&self->RefPicSetStFoll[i], NULL);
1251   }
1252 }
1253 
1254 static void
gst_h265_decoder_derive_and_mark_rps(GstH265Decoder * self,GstH265Picture * picture,gint32 * CurrDeltaPocMsbPresentFlag,gint32 * FollDeltaPocMsbPresentFlag)1255 gst_h265_decoder_derive_and_mark_rps (GstH265Decoder * self,
1256     GstH265Picture * picture, gint32 * CurrDeltaPocMsbPresentFlag,
1257     gint32 * FollDeltaPocMsbPresentFlag)
1258 {
1259   GstH265DecoderPrivate *priv = self->priv;
1260   guint i;
1261   GArray *dpb_array;
1262 
1263   gst_h265_decoder_clear_ref_pic_sets (self);
1264 
1265   /* (8-6) */
1266   for (i = 0; i < self->NumPocLtCurr; i++) {
1267     if (!CurrDeltaPocMsbPresentFlag[i]) {
1268       self->RefPicSetLtCurr[i] =
1269           gst_h265_dpb_get_ref_by_poc_lsb (priv->dpb, priv->PocLtCurr[i]);
1270     } else {
1271       self->RefPicSetLtCurr[i] =
1272           gst_h265_dpb_get_ref_by_poc (priv->dpb, priv->PocLtCurr[i]);
1273     }
1274   }
1275 
1276   for (i = 0; i < self->NumPocLtFoll; i++) {
1277     if (!FollDeltaPocMsbPresentFlag[i]) {
1278       self->RefPicSetLtFoll[i] =
1279           gst_h265_dpb_get_ref_by_poc_lsb (priv->dpb, priv->PocLtFoll[i]);
1280     } else {
1281       self->RefPicSetLtFoll[i] =
1282           gst_h265_dpb_get_ref_by_poc (priv->dpb, priv->PocLtFoll[i]);
1283     }
1284   }
1285 
1286   /* Mark all ref pics in RefPicSetLtCurr and RefPicSetLtFol as long_term_refs */
1287   for (i = 0; i < self->NumPocLtCurr; i++) {
1288     if (self->RefPicSetLtCurr[i]) {
1289       self->RefPicSetLtCurr[i]->ref = TRUE;
1290       self->RefPicSetLtCurr[i]->long_term = TRUE;
1291     }
1292   }
1293 
1294   for (i = 0; i < self->NumPocLtFoll; i++) {
1295     if (self->RefPicSetLtFoll[i]) {
1296       self->RefPicSetLtFoll[i]->ref = TRUE;
1297       self->RefPicSetLtFoll[i]->long_term = TRUE;
1298     }
1299   }
1300 
1301   /* (8-7) */
1302   for (i = 0; i < self->NumPocStCurrBefore; i++) {
1303     self->RefPicSetStCurrBefore[i] =
1304         gst_h265_dpb_get_short_ref_by_poc (priv->dpb, priv->PocStCurrBefore[i]);
1305   }
1306 
1307   for (i = 0; i < self->NumPocStCurrAfter; i++) {
1308     self->RefPicSetStCurrAfter[i] =
1309         gst_h265_dpb_get_short_ref_by_poc (priv->dpb, priv->PocStCurrAfter[i]);
1310   }
1311 
1312   for (i = 0; i < self->NumPocStFoll; i++) {
1313     self->RefPicSetStFoll[i] =
1314         gst_h265_dpb_get_short_ref_by_poc (priv->dpb, priv->PocStFoll[i]);
1315   }
1316 
1317   /* Mark all dpb pics not beloging to RefPicSet*[] as unused for ref */
1318   dpb_array = gst_h265_dpb_get_pictures_all (priv->dpb);
1319   for (i = 0; i < dpb_array->len; i++) {
1320     GstH265Picture *dpb_pic = g_array_index (dpb_array, GstH265Picture *, i);
1321 
1322     if (dpb_pic &&
1323         !has_entry_in_rps (dpb_pic, self->RefPicSetLtCurr, self->NumPocLtCurr)
1324         && !has_entry_in_rps (dpb_pic, self->RefPicSetLtFoll,
1325             self->NumPocLtFoll)
1326         && !has_entry_in_rps (dpb_pic, self->RefPicSetStCurrAfter,
1327             self->NumPocStCurrAfter)
1328         && !has_entry_in_rps (dpb_pic, self->RefPicSetStCurrBefore,
1329             self->NumPocStCurrBefore)
1330         && !has_entry_in_rps (dpb_pic, self->RefPicSetStFoll,
1331             self->NumPocStFoll)) {
1332       GST_LOG_OBJECT (self, "Mark Picture %p (poc %d) as non-ref", dpb_pic,
1333           dpb_pic->pic_order_cnt);
1334       dpb_pic->ref = FALSE;
1335       dpb_pic->long_term = FALSE;
1336     }
1337   }
1338 
1339   g_array_unref (dpb_array);
1340 }
1341 
1342 static gboolean
gst_h265_decoder_prepare_rps(GstH265Decoder * self,const GstH265Slice * slice,GstH265Picture * picture)1343 gst_h265_decoder_prepare_rps (GstH265Decoder * self, const GstH265Slice * slice,
1344     GstH265Picture * picture)
1345 {
1346   GstH265DecoderPrivate *priv = self->priv;
1347   gint32 CurrDeltaPocMsbPresentFlag[16] = { 0, };
1348   gint32 FollDeltaPocMsbPresentFlag[16] = { 0, };
1349   const GstH265SliceHdr *slice_hdr = &slice->header;
1350   const GstH265NalUnit *nalu = &slice->nalu;
1351   const GstH265SPS *sps = priv->active_sps;
1352   guint32 MaxPicOrderCntLsb = 1 << (sps->log2_max_pic_order_cnt_lsb_minus4 + 4);
1353   gint i, j, k;
1354 
1355   /* if it is an irap pic, set all ref pics in dpb as unused for ref */
1356   if (GST_H265_IS_NAL_TYPE_IRAP (nalu->type) && picture->NoRaslOutputFlag) {
1357     GST_DEBUG_OBJECT (self, "Mark all pictures in DPB as non-ref");
1358     gst_h265_dpb_mark_all_non_ref (priv->dpb);
1359   }
1360 
1361   /* Reset everything for IDR */
1362   if (GST_H265_IS_NAL_TYPE_IDR (nalu->type)) {
1363     memset (priv->PocStCurrBefore, 0, sizeof (priv->PocStCurrBefore));
1364     memset (priv->PocStCurrAfter, 0, sizeof (priv->PocStCurrAfter));
1365     memset (priv->PocStFoll, 0, sizeof (priv->PocStFoll));
1366     memset (priv->PocLtCurr, 0, sizeof (priv->PocLtCurr));
1367     memset (priv->PocLtFoll, 0, sizeof (priv->PocLtFoll));
1368     self->NumPocStCurrBefore = self->NumPocStCurrAfter = self->NumPocStFoll = 0;
1369     self->NumPocLtCurr = self->NumPocLtFoll = 0;
1370   } else {
1371     const GstH265ShortTermRefPicSet *stRefPic = NULL;
1372     gint32 num_lt_pics, pocLt;
1373     gint32 PocLsbLt[16] = { 0, };
1374     gint32 UsedByCurrPicLt[16] = { 0, };
1375     gint32 DeltaPocMsbCycleLt[16] = { 0, };
1376     gint numtotalcurr = 0;
1377 
1378     /* this is based on CurrRpsIdx described in spec */
1379     if (!slice_hdr->short_term_ref_pic_set_sps_flag)
1380       stRefPic = &slice_hdr->short_term_ref_pic_sets;
1381     else if (sps->num_short_term_ref_pic_sets)
1382       stRefPic =
1383           &sps->short_term_ref_pic_set[slice_hdr->short_term_ref_pic_set_idx];
1384 
1385     g_assert (stRefPic != NULL);
1386 
1387     GST_LOG_OBJECT (self,
1388         "NumDeltaPocs: %d, NumNegativePics: %d, NumPositivePics %d",
1389         stRefPic->NumDeltaPocs, stRefPic->NumNegativePics,
1390         stRefPic->NumPositivePics);
1391 
1392     for (i = 0, j = 0, k = 0; i < stRefPic->NumNegativePics; i++) {
1393       if (stRefPic->UsedByCurrPicS0[i]) {
1394         priv->PocStCurrBefore[j++] =
1395             picture->pic_order_cnt + stRefPic->DeltaPocS0[i];
1396         numtotalcurr++;
1397       } else
1398         priv->PocStFoll[k++] = picture->pic_order_cnt + stRefPic->DeltaPocS0[i];
1399     }
1400     self->NumPocStCurrBefore = j;
1401     for (i = 0, j = 0; i < stRefPic->NumPositivePics; i++) {
1402       if (stRefPic->UsedByCurrPicS1[i]) {
1403         priv->PocStCurrAfter[j++] =
1404             picture->pic_order_cnt + stRefPic->DeltaPocS1[i];
1405         numtotalcurr++;
1406       } else
1407         priv->PocStFoll[k++] = picture->pic_order_cnt + stRefPic->DeltaPocS1[i];
1408     }
1409     self->NumPocStCurrAfter = j;
1410     self->NumPocStFoll = k;
1411     num_lt_pics = slice_hdr->num_long_term_sps + slice_hdr->num_long_term_pics;
1412     /* The variables PocLsbLt[i] and UsedByCurrPicLt[i] are derived as follows: */
1413     for (i = 0; i < num_lt_pics; i++) {
1414       if (i < slice_hdr->num_long_term_sps) {
1415         PocLsbLt[i] = sps->lt_ref_pic_poc_lsb_sps[slice_hdr->lt_idx_sps[i]];
1416         UsedByCurrPicLt[i] =
1417             sps->used_by_curr_pic_lt_sps_flag[slice_hdr->lt_idx_sps[i]];
1418       } else {
1419         PocLsbLt[i] = slice_hdr->poc_lsb_lt[i];
1420         UsedByCurrPicLt[i] = slice_hdr->used_by_curr_pic_lt_flag[i];
1421       }
1422       if (UsedByCurrPicLt[i])
1423         numtotalcurr++;
1424     }
1425 
1426     self->NumPicTotalCurr = numtotalcurr;
1427 
1428     /* The variable DeltaPocMsbCycleLt[i] is derived as follows: (7-38) */
1429     for (i = 0; i < num_lt_pics; i++) {
1430       if (i == 0 || i == slice_hdr->num_long_term_sps)
1431         DeltaPocMsbCycleLt[i] = slice_hdr->delta_poc_msb_cycle_lt[i];
1432       else
1433         DeltaPocMsbCycleLt[i] =
1434             slice_hdr->delta_poc_msb_cycle_lt[i] + DeltaPocMsbCycleLt[i - 1];
1435     }
1436 
1437     /* (8-5) */
1438     for (i = 0, j = 0, k = 0; i < num_lt_pics; i++) {
1439       pocLt = PocLsbLt[i];
1440       if (slice_hdr->delta_poc_msb_present_flag[i])
1441         pocLt +=
1442             picture->pic_order_cnt - DeltaPocMsbCycleLt[i] * MaxPicOrderCntLsb -
1443             slice_hdr->pic_order_cnt_lsb;
1444       if (UsedByCurrPicLt[i]) {
1445         priv->PocLtCurr[j] = pocLt;
1446         CurrDeltaPocMsbPresentFlag[j++] =
1447             slice_hdr->delta_poc_msb_present_flag[i];
1448       } else {
1449         priv->PocLtFoll[k] = pocLt;
1450         FollDeltaPocMsbPresentFlag[k++] =
1451             slice_hdr->delta_poc_msb_present_flag[i];
1452       }
1453     }
1454     self->NumPocLtCurr = j;
1455     self->NumPocLtFoll = k;
1456   }
1457 
1458   GST_LOG_OBJECT (self, "NumPocStCurrBefore: %d", self->NumPocStCurrBefore);
1459   GST_LOG_OBJECT (self, "NumPocStCurrAfter:  %d", self->NumPocStCurrAfter);
1460   GST_LOG_OBJECT (self, "NumPocStFoll:       %d", self->NumPocStFoll);
1461   GST_LOG_OBJECT (self, "NumPocLtCurr:       %d", self->NumPocLtCurr);
1462   GST_LOG_OBJECT (self, "NumPocLtFoll:       %d", self->NumPocLtFoll);
1463   GST_LOG_OBJECT (self, "NumPicTotalCurr:    %d", self->NumPicTotalCurr);
1464 
1465   /* the derivation process for the RPS and the picture marking */
1466   gst_h265_decoder_derive_and_mark_rps (self, picture,
1467       CurrDeltaPocMsbPresentFlag, FollDeltaPocMsbPresentFlag);
1468 
1469   return TRUE;
1470 }
1471 
1472 static void
gst_h265_decoder_do_output_picture(GstH265Decoder * self,GstH265Picture * picture,GstFlowReturn * ret)1473 gst_h265_decoder_do_output_picture (GstH265Decoder * self,
1474     GstH265Picture * picture, GstFlowReturn * ret)
1475 {
1476   GstH265DecoderPrivate *priv = self->priv;
1477   GstH265DecoderClass *klass;
1478   GstVideoCodecFrame *frame = NULL;
1479   GstFlowReturn flow_ret = GST_FLOW_OK;
1480 
1481   g_assert (ret != NULL);
1482 
1483   GST_LOG_OBJECT (self, "Output picture %p (poc %d)", picture,
1484       picture->pic_order_cnt);
1485 
1486   if (picture->pic_order_cnt < priv->last_output_poc) {
1487     GST_WARNING_OBJECT (self,
1488         "Outputting out of order %d -> %d, likely a broken stream",
1489         priv->last_output_poc, picture->pic_order_cnt);
1490   }
1491 
1492   priv->last_output_poc = picture->pic_order_cnt;
1493 
1494   frame = gst_video_decoder_get_frame (GST_VIDEO_DECODER (self),
1495       picture->system_frame_number);
1496 
1497   if (!frame) {
1498     GST_ERROR_OBJECT (self,
1499         "No available codec frame with frame number %d",
1500         picture->system_frame_number);
1501     UPDATE_FLOW_RETURN (ret, GST_FLOW_ERROR);
1502 
1503     gst_h265_picture_unref (picture);
1504     return;
1505   }
1506 
1507   klass = GST_H265_DECODER_GET_CLASS (self);
1508 
1509   g_assert (klass->output_picture);
1510   flow_ret = klass->output_picture (self, frame, picture);
1511 
1512   UPDATE_FLOW_RETURN (ret, flow_ret);
1513 }
1514 
1515 static void
gst_h265_decoder_clear_dpb(GstH265Decoder * self,gboolean flush)1516 gst_h265_decoder_clear_dpb (GstH265Decoder * self, gboolean flush)
1517 {
1518   GstVideoDecoder *decoder = GST_VIDEO_DECODER (self);
1519   GstH265DecoderPrivate *priv = self->priv;
1520   GstH265Picture *picture;
1521 
1522   /* If we are not flushing now, videodecoder baseclass will hold
1523    * GstVideoCodecFrame. Release frames manually */
1524   if (!flush) {
1525     while ((picture = gst_h265_dpb_bump (priv->dpb, TRUE)) != NULL) {
1526       GstVideoCodecFrame *frame = gst_video_decoder_get_frame (decoder,
1527           picture->system_frame_number);
1528 
1529       if (frame)
1530         gst_video_decoder_release_frame (decoder, frame);
1531       gst_h265_picture_unref (picture);
1532     }
1533   }
1534 
1535   gst_h265_dpb_clear (priv->dpb);
1536   priv->last_output_poc = G_MININT32;
1537 }
1538 
1539 static GstFlowReturn
gst_h265_decoder_drain_internal(GstH265Decoder * self)1540 gst_h265_decoder_drain_internal (GstH265Decoder * self)
1541 {
1542   GstH265DecoderPrivate *priv = self->priv;
1543   GstH265Picture *picture;
1544   GstFlowReturn ret = GST_FLOW_OK;
1545 
1546   while ((picture = gst_h265_dpb_bump (priv->dpb, TRUE)) != NULL)
1547     gst_h265_decoder_do_output_picture (self, picture, &ret);
1548 
1549   gst_h265_dpb_clear (priv->dpb);
1550   priv->last_output_poc = G_MININT32;
1551 
1552   return ret;
1553 }
1554 
1555 /* C.5.2.2 */
1556 static GstFlowReturn
gst_h265_decoder_dpb_init(GstH265Decoder * self,const GstH265Slice * slice,GstH265Picture * picture)1557 gst_h265_decoder_dpb_init (GstH265Decoder * self, const GstH265Slice * slice,
1558     GstH265Picture * picture)
1559 {
1560   GstH265DecoderPrivate *priv = self->priv;
1561   const GstH265SliceHdr *slice_hdr = &slice->header;
1562   const GstH265NalUnit *nalu = &slice->nalu;
1563   const GstH265SPS *sps = priv->active_sps;
1564   GstH265Picture *to_output;
1565   GstFlowReturn ret = GST_FLOW_OK;
1566 
1567   /* C 3.2 */
1568   if (GST_H265_IS_NAL_TYPE_IRAP (nalu->type) && picture->NoRaslOutputFlag
1569       && !priv->new_bitstream) {
1570     if (nalu->type == GST_H265_NAL_SLICE_CRA_NUT)
1571       picture->NoOutputOfPriorPicsFlag = TRUE;
1572     else
1573       picture->NoOutputOfPriorPicsFlag =
1574           slice_hdr->no_output_of_prior_pics_flag;
1575 
1576     if (picture->NoOutputOfPriorPicsFlag) {
1577       GST_DEBUG_OBJECT (self, "Clear dpb");
1578       gst_h265_decoder_clear_dpb (self, FALSE);
1579     } else {
1580       gst_h265_dpb_delete_unused (priv->dpb);
1581       while ((to_output = gst_h265_dpb_bump (priv->dpb, FALSE)) != NULL)
1582         gst_h265_decoder_do_output_picture (self, to_output, &ret);
1583 
1584       if (gst_h265_dpb_get_size (priv->dpb) > 0) {
1585         GST_WARNING_OBJECT (self, "IDR or BLA frame failed to clear the dpb, "
1586             "there are still %d pictures in the dpb, last output poc is %d",
1587             gst_h265_dpb_get_size (priv->dpb), priv->last_output_poc);
1588       } else {
1589         priv->last_output_poc = G_MININT32;
1590       }
1591     }
1592   } else {
1593     gst_h265_dpb_delete_unused (priv->dpb);
1594     while (gst_h265_dpb_needs_bump (priv->dpb,
1595             sps->max_num_reorder_pics[sps->max_sub_layers_minus1],
1596             priv->SpsMaxLatencyPictures,
1597             sps->max_dec_pic_buffering_minus1[sps->max_sub_layers_minus1] +
1598             1)) {
1599       to_output = gst_h265_dpb_bump (priv->dpb, FALSE);
1600 
1601       /* Something wrong... */
1602       if (!to_output) {
1603         GST_WARNING_OBJECT (self, "Bumping is needed but no picture to output");
1604         break;
1605       }
1606 
1607       gst_h265_decoder_do_output_picture (self, to_output, &ret);
1608     }
1609   }
1610 
1611   return ret;
1612 }
1613 
1614 static GstFlowReturn
gst_h265_decoder_start_current_picture(GstH265Decoder * self)1615 gst_h265_decoder_start_current_picture (GstH265Decoder * self)
1616 {
1617   GstH265DecoderClass *klass;
1618   GstH265DecoderPrivate *priv = self->priv;
1619   GstFlowReturn ret = GST_FLOW_OK;
1620 
1621   g_assert (priv->current_picture != NULL);
1622   g_assert (priv->active_sps != NULL);
1623   g_assert (priv->active_pps != NULL);
1624 
1625   if (!gst_h265_decoder_init_current_picture (self))
1626     return GST_FLOW_ERROR;
1627 
1628   /* Drop all RASL pictures having NoRaslOutputFlag is TRUE for the
1629    * associated IRAP picture */
1630   if (GST_H265_IS_NAL_TYPE_RASL (priv->current_slice.nalu.type) &&
1631       priv->associated_irap_NoRaslOutputFlag) {
1632     GST_DEBUG_OBJECT (self, "Drop current picture");
1633     gst_h265_picture_replace (&priv->current_picture, NULL);
1634     return GST_FLOW_OK;
1635   }
1636 
1637   gst_h265_decoder_prepare_rps (self, &priv->current_slice,
1638       priv->current_picture);
1639 
1640   ret = gst_h265_decoder_dpb_init (self,
1641       &priv->current_slice, priv->current_picture);
1642   if (ret != GST_FLOW_OK) {
1643     GST_WARNING_OBJECT (self, "Failed to init dpb");
1644     return ret;
1645   }
1646 
1647   klass = GST_H265_DECODER_GET_CLASS (self);
1648   if (klass->start_picture) {
1649     ret = klass->start_picture (self, priv->current_picture,
1650         &priv->current_slice, priv->dpb);
1651 
1652     if (ret != GST_FLOW_OK) {
1653       GST_WARNING_OBJECT (self, "subclass does not want to start picture");
1654       return ret;
1655     }
1656   }
1657 
1658   return GST_FLOW_OK;
1659 }
1660 
1661 static void
gst_h265_decoder_finish_picture(GstH265Decoder * self,GstH265Picture * picture,GstFlowReturn * ret)1662 gst_h265_decoder_finish_picture (GstH265Decoder * self,
1663     GstH265Picture * picture, GstFlowReturn * ret)
1664 {
1665   GstVideoDecoder *decoder = GST_VIDEO_DECODER (self);
1666   GstH265DecoderPrivate *priv = self->priv;
1667   const GstH265SPS *sps = priv->active_sps;
1668 
1669   g_assert (ret != NULL);
1670 
1671   GST_LOG_OBJECT (self,
1672       "Finishing picture %p (poc %d), entries in DPB %d",
1673       picture, picture->pic_order_cnt, gst_h265_dpb_get_size (priv->dpb));
1674 
1675   gst_h265_dpb_delete_unused (priv->dpb);
1676 
1677   /* This picture is decode only, drop corresponding frame */
1678   if (!picture->output_flag) {
1679     GstVideoCodecFrame *frame = gst_video_decoder_get_frame (decoder,
1680         picture->system_frame_number);
1681 
1682     gst_video_decoder_release_frame (decoder, frame);
1683   }
1684 
1685   /* gst_h265_dpb_add() will take care of pic_latency_cnt increment and
1686    * reference picture marking for this picture */
1687   gst_h265_dpb_add (priv->dpb, picture);
1688 
1689   /* NOTE: As per C.5.2.2, bumping by sps_max_dec_pic_buffering_minus1 is
1690    * applied only for the output and removal of pictures from the DPB before
1691    * the decoding of the current picture. So pass zero here */
1692   while (gst_h265_dpb_needs_bump (priv->dpb,
1693           sps->max_num_reorder_pics[sps->max_sub_layers_minus1],
1694           priv->SpsMaxLatencyPictures, 0)) {
1695     GstH265Picture *to_output = gst_h265_dpb_bump (priv->dpb, FALSE);
1696 
1697     /* Something wrong... */
1698     if (!to_output) {
1699       GST_WARNING_OBJECT (self, "Bumping is needed but no picture to output");
1700       break;
1701     }
1702 
1703     gst_h265_decoder_do_output_picture (self, to_output, ret);
1704   }
1705 }
1706 
1707 static void
gst_h265_decoder_finish_current_picture(GstH265Decoder * self,GstFlowReturn * ret)1708 gst_h265_decoder_finish_current_picture (GstH265Decoder * self,
1709     GstFlowReturn * ret)
1710 {
1711   GstH265DecoderPrivate *priv = self->priv;
1712   GstH265DecoderClass *klass;
1713   GstFlowReturn flow_ret = GST_FLOW_OK;
1714 
1715   g_assert (ret != NULL);
1716 
1717   if (!priv->current_picture)
1718     return;
1719 
1720   klass = GST_H265_DECODER_GET_CLASS (self);
1721 
1722   if (klass->end_picture) {
1723     flow_ret = klass->end_picture (self, priv->current_picture);
1724     if (flow_ret != GST_FLOW_OK) {
1725       GST_WARNING_OBJECT (self, "End picture failed");
1726 
1727       /* continue to empty dpb */
1728       UPDATE_FLOW_RETURN (ret, flow_ret);
1729     }
1730   }
1731 
1732   /* finish picture takes ownership of the picture */
1733   gst_h265_decoder_finish_picture (self, priv->current_picture, &flow_ret);
1734   priv->current_picture = NULL;
1735 
1736   UPDATE_FLOW_RETURN (ret, flow_ret);
1737 }
1738 
1739 static void
gst_h265_decoder_reset_frame_state(GstH265Decoder * self)1740 gst_h265_decoder_reset_frame_state (GstH265Decoder * self)
1741 {
1742   GstH265DecoderPrivate *priv = self->priv;
1743 
1744   /* Clear picture struct information */
1745   priv->cur_pic_struct = GST_H265_SEI_PIC_STRUCT_FRAME;
1746   priv->cur_source_scan_type = 2;
1747   priv->cur_duplicate_flag = 0;
1748 }
1749 
1750 static GstFlowReturn
gst_h265_decoder_handle_frame(GstVideoDecoder * decoder,GstVideoCodecFrame * frame)1751 gst_h265_decoder_handle_frame (GstVideoDecoder * decoder,
1752     GstVideoCodecFrame * frame)
1753 {
1754   GstH265Decoder *self = GST_H265_DECODER (decoder);
1755   GstH265DecoderPrivate *priv = self->priv;
1756   GstBuffer *in_buf = frame->input_buffer;
1757   GstH265NalUnit nalu;
1758   GstH265ParserResult pres;
1759   GstMapInfo map;
1760   GstFlowReturn decode_ret = GST_FLOW_OK;
1761 
1762   GST_LOG_OBJECT (self,
1763       "handle frame, PTS: %" GST_TIME_FORMAT ", DTS: %"
1764       GST_TIME_FORMAT, GST_TIME_ARGS (GST_BUFFER_PTS (in_buf)),
1765       GST_TIME_ARGS (GST_BUFFER_DTS (in_buf)));
1766 
1767   priv->current_frame = frame;
1768 
1769   gst_h265_decoder_reset_frame_state (self);
1770 
1771   if (!gst_buffer_map (in_buf, &map, GST_MAP_READ)) {
1772     GST_ELEMENT_ERROR (self, RESOURCE, READ,
1773         ("Failed to map memory for reading"), (NULL));
1774     return GST_FLOW_ERROR;
1775   }
1776 
1777   if (priv->in_format == GST_H265_DECODER_FORMAT_HVC1 ||
1778       priv->in_format == GST_H265_DECODER_FORMAT_HEV1) {
1779     pres = gst_h265_parser_identify_nalu_hevc (priv->parser,
1780         map.data, 0, map.size, priv->nal_length_size, &nalu);
1781 
1782     while (pres == GST_H265_PARSER_OK && decode_ret == GST_FLOW_OK) {
1783       decode_ret = gst_h265_decoder_decode_nal (self,
1784           &nalu, GST_BUFFER_PTS (in_buf));
1785 
1786       pres = gst_h265_parser_identify_nalu_hevc (priv->parser,
1787           map.data, nalu.offset + nalu.size, map.size, priv->nal_length_size,
1788           &nalu);
1789     }
1790   } else {
1791     pres = gst_h265_parser_identify_nalu (priv->parser,
1792         map.data, 0, map.size, &nalu);
1793 
1794     if (pres == GST_H265_PARSER_NO_NAL_END)
1795       pres = GST_H265_PARSER_OK;
1796 
1797     while (pres == GST_H265_PARSER_OK && decode_ret == GST_FLOW_OK) {
1798       decode_ret = gst_h265_decoder_decode_nal (self,
1799           &nalu, GST_BUFFER_PTS (in_buf));
1800 
1801       pres = gst_h265_parser_identify_nalu (priv->parser,
1802           map.data, nalu.offset + nalu.size, map.size, &nalu);
1803 
1804       if (pres == GST_H265_PARSER_NO_NAL_END)
1805         pres = GST_H265_PARSER_OK;
1806     }
1807   }
1808 
1809   gst_buffer_unmap (in_buf, &map);
1810   priv->current_frame = NULL;
1811 
1812   if (decode_ret != GST_FLOW_OK) {
1813     if (decode_ret == GST_FLOW_ERROR) {
1814       GST_VIDEO_DECODER_ERROR (self, 1, STREAM, DECODE,
1815           ("Failed to decode data"), (NULL), decode_ret);
1816     }
1817 
1818     gst_video_decoder_drop_frame (decoder, frame);
1819     gst_h265_picture_clear (&priv->current_picture);
1820 
1821     return decode_ret;
1822   }
1823 
1824   if (priv->current_picture) {
1825     gst_h265_decoder_finish_current_picture (self, &decode_ret);
1826     gst_video_codec_frame_unref (frame);
1827   } else {
1828     /* This picture was dropped */
1829     gst_video_decoder_release_frame (decoder, frame);
1830   }
1831 
1832   if (decode_ret == GST_FLOW_ERROR) {
1833     GST_VIDEO_DECODER_ERROR (self, 1, STREAM, DECODE,
1834         ("Failed to decode data"), (NULL), decode_ret);
1835   }
1836 
1837   return decode_ret;
1838 }
1839 
1840 /**
1841  * gst_h265_decoder_set_process_ref_pic_lists:
1842  * @decoder: a #GstH265Decoder
1843  * @process: whether subclass is requiring reference picture modification process
1844  *
1845  * Called to en/disable reference picture modification process.
1846  *
1847  * Since: 1.20
1848  */
1849 void
gst_h265_decoder_set_process_ref_pic_lists(GstH265Decoder * decoder,gboolean process)1850 gst_h265_decoder_set_process_ref_pic_lists (GstH265Decoder * decoder,
1851     gboolean process)
1852 {
1853   decoder->priv->process_ref_pic_lists = process;
1854 }
1855 
1856 /**
1857  * gst_h265_decoder_get_picture:
1858  * @decoder: a #GstH265Decoder
1859  * @system_frame_number: a target system frame number of #GstH265Picture
1860  *
1861  * Retrive DPB and return a #GstH265Picture corresponding to
1862  * the @system_frame_number
1863  *
1864  * Returns: (transfer full): a #GstH265Picture if successful, or %NULL otherwise
1865  *
1866  * Since: 1.20
1867  */
1868 GstH265Picture *
gst_h265_decoder_get_picture(GstH265Decoder * decoder,guint32 system_frame_number)1869 gst_h265_decoder_get_picture (GstH265Decoder * decoder,
1870     guint32 system_frame_number)
1871 {
1872   return gst_h265_dpb_get_picture (decoder->priv->dpb, system_frame_number);
1873 }
1874