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