2 * Copyright (C) 2015 Intel Corporation
3 * Author: Sreerenj Balachandran <sreerenj.balachandran@intel.com>
4 * Copyright (C) 2019 Seungha Yang <seungha.yang@navercorp.com>
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.
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.
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.
22 * SECTION:gsth265decoder
23 * @title: GstH265Decoder
24 * @short_description: Base class to implement stateless H.265 decoders
33 #include <gst/base/base.h>
34 #include "gsth265decoder.h"
36 GST_DEBUG_CATEGORY (gst_h265_decoder_debug);
37 #define GST_CAT_DEFAULT gst_h265_decoder_debug
41 GST_H265_DECODER_FORMAT_NONE,
42 GST_H265_DECODER_FORMAT_HVC1,
43 GST_H265_DECODER_FORMAT_HEV1,
44 GST_H265_DECODER_FORMAT_BYTE
45 } GstH265DecoderFormat;
49 GST_H265_DECODER_ALIGN_NONE,
50 GST_H265_DECODER_ALIGN_NAL,
51 GST_H265_DECODER_ALIGN_AU
52 } GstH265DecoderAlign;
54 struct _GstH265DecoderPrivate
58 guint8 conformance_window_flag;
60 gint crop_rect_height;
64 guint nal_length_size;
67 GstH265DecoderFormat in_format;
68 GstH265DecoderAlign align;
69 GstH265Parser *parser;
72 /* 0: frame or field-pair interlaced stream
73 * 1: alternating, single field interlaced stream.
74 * When equal to 1, picture timing SEI shall be present in every AU */
75 guint8 field_seq_flag;
76 guint8 progressive_source_flag;
77 guint8 interlaced_source_flag;
79 /* Updated/cleared per handle_frame() by using picture timeing SEI */
80 GstH265SEIPicStructType cur_pic_struct;
81 guint8 cur_source_scan_type;
82 guint8 cur_duplicate_flag;
84 gboolean no_output_of_prior_pics_flag;
86 /* vps/sps/pps of the current slice */
87 const GstH265VPS *active_vps;
88 const GstH265SPS *active_sps;
89 const GstH265PPS *active_pps;
91 guint32 SpsMaxLatencyPictures;
93 /* Picture currently being processed/decoded */
94 GstH265Picture *current_picture;
95 GstVideoCodecFrame *current_frame;
97 /* Slice (slice header + nalu) currently being processed/decoded */
98 GstH265Slice current_slice;
99 GstH265Slice prev_slice;
100 GstH265Slice prev_independent_slice;
102 gint32 poc; // PicOrderCntVal
103 gint32 poc_msb; // PicOrderCntMsb
104 gint32 poc_lsb; // pic_order_cnt_lsb (from slice_header())
105 gint32 prev_poc_msb; // prevPicOrderCntMsb
106 gint32 prev_poc_lsb; // prevPicOrderCntLsb
107 gint32 prev_tid0pic_poc_lsb;
108 gint32 prev_tid0pic_poc_msb;
109 gint32 PocStCurrBefore[16];
110 gint32 PocStCurrAfter[16];
111 gint32 PocStFoll[16];
112 gint32 PocLtCurr[16];
113 gint32 PocLtFoll[16];
115 /* PicOrderCount of the previously outputted frame */
116 gint last_output_poc;
118 gboolean associated_irap_NoRaslOutputFlag;
119 gboolean new_bitstream;
120 gboolean prev_nal_is_eos;
122 /* Reference picture lists, constructed for each slice */
123 gboolean process_ref_pic_lists;
124 GArray *ref_pic_list_tmp;
125 GArray *ref_pic_list0;
126 GArray *ref_pic_list1;
130 /* Split packetized data into actual nal chunks (for malformed stream) */
133 /* For delayed output */
134 guint preferred_output_delay;
136 GstQueueArray *output_queue;
147 } GstH265DecoderNalUnit;
152 GstVideoCodecFrame *frame;
153 GstH265Picture *picture;
155 GstH265Decoder *self;
156 } GstH265DecoderOutputFrame;
158 #define UPDATE_FLOW_RETURN(ret,new_ret) G_STMT_START { \
159 if (*(ret) == GST_FLOW_OK) \
163 #define parent_class gst_h265_decoder_parent_class
164 G_DEFINE_ABSTRACT_TYPE_WITH_CODE (GstH265Decoder, gst_h265_decoder,
165 GST_TYPE_VIDEO_DECODER,
166 G_ADD_PRIVATE (GstH265Decoder);
167 GST_DEBUG_CATEGORY_INIT (gst_h265_decoder_debug, "h265decoder", 0,
168 "H.265 Video Decoder"));
170 static void gst_h265_decoder_finalize (GObject * object);
172 static gboolean gst_h265_decoder_start (GstVideoDecoder * decoder);
173 static gboolean gst_h265_decoder_stop (GstVideoDecoder * decoder);
174 static gboolean gst_h265_decoder_set_format (GstVideoDecoder * decoder,
175 GstVideoCodecState * state);
176 static GstFlowReturn gst_h265_decoder_finish (GstVideoDecoder * decoder);
177 static gboolean gst_h265_decoder_flush (GstVideoDecoder * decoder);
178 static GstFlowReturn gst_h265_decoder_drain (GstVideoDecoder * decoder);
179 static GstFlowReturn gst_h265_decoder_handle_frame (GstVideoDecoder * decoder,
180 GstVideoCodecFrame * frame);
182 static void gst_h265_decoder_finish_current_picture (GstH265Decoder * self,
183 GstFlowReturn * ret);
184 static void gst_h265_decoder_clear_ref_pic_sets (GstH265Decoder * self);
185 static void gst_h265_decoder_clear_dpb (GstH265Decoder * self, gboolean flush);
186 static GstFlowReturn gst_h265_decoder_drain_internal (GstH265Decoder * self);
188 gst_h265_decoder_start_current_picture (GstH265Decoder * self);
189 static void gst_h265_decoder_clear_nalu (GstH265DecoderNalUnit * nalu);
191 gst_h265_decoder_clear_output_frame (GstH265DecoderOutputFrame * output_frame);
194 gst_h265_decoder_class_init (GstH265DecoderClass * klass)
196 GstVideoDecoderClass *decoder_class = GST_VIDEO_DECODER_CLASS (klass);
197 GObjectClass *object_class = G_OBJECT_CLASS (klass);
199 object_class->finalize = GST_DEBUG_FUNCPTR (gst_h265_decoder_finalize);
201 decoder_class->start = GST_DEBUG_FUNCPTR (gst_h265_decoder_start);
202 decoder_class->stop = GST_DEBUG_FUNCPTR (gst_h265_decoder_stop);
203 decoder_class->set_format = GST_DEBUG_FUNCPTR (gst_h265_decoder_set_format);
204 decoder_class->finish = GST_DEBUG_FUNCPTR (gst_h265_decoder_finish);
205 decoder_class->flush = GST_DEBUG_FUNCPTR (gst_h265_decoder_flush);
206 decoder_class->drain = GST_DEBUG_FUNCPTR (gst_h265_decoder_drain);
207 decoder_class->handle_frame =
208 GST_DEBUG_FUNCPTR (gst_h265_decoder_handle_frame);
212 gst_h265_decoder_init (GstH265Decoder * self)
214 GstH265DecoderPrivate *priv;
216 gst_video_decoder_set_packetized (GST_VIDEO_DECODER (self), TRUE);
218 self->priv = priv = gst_h265_decoder_get_instance_private (self);
220 priv->last_output_poc = G_MININT32;
222 priv->ref_pic_list_tmp = g_array_sized_new (FALSE, TRUE,
223 sizeof (GstH265Picture *), 32);
224 priv->ref_pic_list0 = g_array_sized_new (FALSE, TRUE,
225 sizeof (GstH265Picture *), 32);
226 priv->ref_pic_list1 = g_array_sized_new (FALSE, TRUE,
227 sizeof (GstH265Picture *), 32);
228 priv->nalu = g_array_sized_new (FALSE, TRUE, sizeof (GstH265DecoderNalUnit),
230 priv->split_nalu = g_array_new (FALSE, FALSE, sizeof (GstH265NalUnit));
231 g_array_set_clear_func (priv->nalu,
232 (GDestroyNotify) gst_h265_decoder_clear_nalu);
234 gst_queue_array_new_for_struct (sizeof (GstH265DecoderOutputFrame), 1);
235 gst_queue_array_set_clear_func (priv->output_queue,
236 (GDestroyNotify) gst_h265_decoder_clear_output_frame);
240 gst_h265_decoder_finalize (GObject * object)
242 GstH265Decoder *self = GST_H265_DECODER (object);
243 GstH265DecoderPrivate *priv = self->priv;
245 g_array_unref (priv->ref_pic_list_tmp);
246 g_array_unref (priv->ref_pic_list0);
247 g_array_unref (priv->ref_pic_list1);
248 g_array_unref (priv->nalu);
249 g_array_unref (priv->split_nalu);
250 gst_queue_array_free (priv->output_queue);
252 G_OBJECT_CLASS (parent_class)->finalize (object);
256 gst_h265_decoder_start (GstVideoDecoder * decoder)
258 GstH265Decoder *self = GST_H265_DECODER (decoder);
259 GstH265DecoderPrivate *priv = self->priv;
261 priv->parser = gst_h265_parser_new ();
262 priv->dpb = gst_h265_dpb_new ();
263 priv->new_bitstream = TRUE;
264 priv->prev_nal_is_eos = FALSE;
270 gst_h265_decoder_stop (GstVideoDecoder * decoder)
272 GstH265Decoder *self = GST_H265_DECODER (decoder);
273 GstH265DecoderPrivate *priv = self->priv;
275 if (self->input_state) {
276 gst_video_codec_state_unref (self->input_state);
277 self->input_state = NULL;
281 gst_h265_parser_free (priv->parser);
286 gst_h265_dpb_free (priv->dpb);
290 gst_h265_decoder_clear_ref_pic_sets (self);
296 gst_h265_decoder_clear_output_frame (GstH265DecoderOutputFrame * output_frame)
301 if (output_frame->frame) {
302 gst_video_decoder_release_frame (GST_VIDEO_DECODER (output_frame->self),
303 output_frame->frame);
304 output_frame->frame = NULL;
307 gst_clear_h265_picture (&output_frame->picture);
311 gst_h265_decoder_is_crop_rect_changed (GstH265Decoder * self, GstH265SPS * sps)
313 GstH265DecoderPrivate *priv = self->priv;
315 if (priv->conformance_window_flag != sps->conformance_window_flag)
317 if (priv->crop_rect_width != sps->crop_rect_width)
319 if (priv->crop_rect_height != sps->crop_rect_height)
321 if (priv->crop_rect_x != sps->crop_rect_x)
323 if (priv->crop_rect_y != sps->crop_rect_y)
330 gst_h265_decoder_drain_output_queue (GstH265Decoder * self, guint num,
333 GstH265DecoderPrivate *priv = self->priv;
334 GstH265DecoderClass *klass = GST_H265_DECODER_GET_CLASS (self);
336 g_assert (klass->output_picture);
337 g_assert (ret != NULL);
339 while (gst_queue_array_get_length (priv->output_queue) > num) {
340 GstH265DecoderOutputFrame *output_frame = (GstH265DecoderOutputFrame *)
341 gst_queue_array_pop_head_struct (priv->output_queue);
342 GstFlowReturn flow_ret = klass->output_picture (self, output_frame->frame,
343 output_frame->picture);
345 UPDATE_FLOW_RETURN (ret, flow_ret);
350 gst_h265_decoder_set_latency (GstH265Decoder * self, const GstH265SPS * sps,
353 GstH265DecoderPrivate *priv = self->priv;
355 GstClockTime min, max;
356 GstStructure *structure;
357 gint fps_d = 1, fps_n = 0;
360 caps = gst_pad_get_current_caps (GST_VIDEO_DECODER_SRC_PAD (self));
364 structure = gst_caps_get_structure (caps, 0);
365 if (gst_structure_get_fraction (structure, "framerate", &fps_n, &fps_d)) {
367 /* variable framerate: see if we have a max-framerate */
368 gst_structure_get_fraction (structure, "max-framerate", &fps_n, &fps_d);
371 gst_caps_unref (caps);
373 /* if no fps or variable, then 25/1 */
379 /* Minimum possible latency could be calculated based on C.5.2.3
380 * 1) # of pictures (marked as "needed for output") in DPB > sps_max_num_reorder_pics
381 * - We will assume all pictures in DPB are marked as "needed for output"
382 * 2) sps_max_latency_increase_plus1 != 0 and
383 * PicLatencyCount >= SpsMaxLatencyPictures
384 * - SpsMaxLatencyPictures is equal to
385 * "sps_max_num_reorder_pics + sps_max_latency_increase_plus1 - 1"
386 * and PicLatencyCount of each picture in DPB is increased by 1 per
387 * decoding loop. Note that PicLatencyCount of the currently decoded
388 * picture is zero. So, in case that all pictures in DPB are marked as
389 * "needed for output", Only condition 1) will have an effect
390 * regardless of sps_max_latency_increase_plus1.
392 * For example, assume sps_max_num_reorder_pics is 2 and
393 * sps_max_latency_increase_plus1 is 1, then SpsMaxLatencyPictures is 2.
394 * For a picture in DPB to have PicLatencyCount >= SpsMaxLatencyPictures,
395 * there must be at least 3 pictures including current picture in DPB
396 * (current picture's PicLatencyCount is zero).
397 * This is already covered by the condition 1). So, this condition 2)
398 * will have effect only when there are pictures marked as
399 * "not needed for output" in DPB.
401 * Thus, we can take sps_max_num_reorder_pics as a min latency value
403 frames_delay = sps->max_num_reorder_pics[sps->max_sub_layers_minus1];
405 /* Consider output delay wanted by subclass */
406 frames_delay += priv->preferred_output_delay;
408 min = gst_util_uint64_scale_int (frames_delay * GST_SECOND, fps_d, fps_n);
409 max = gst_util_uint64_scale_int ((max_dpb_size + priv->preferred_output_delay)
410 * GST_SECOND, fps_d, fps_n);
412 GST_DEBUG_OBJECT (self,
413 "latency min %" GST_TIME_FORMAT " max %" GST_TIME_FORMAT
414 " min-frames-delay %d", GST_TIME_ARGS (min), GST_TIME_ARGS (max),
417 gst_video_decoder_set_latency (GST_VIDEO_DECODER (self), min, max);
421 gst_h265_decoder_process_sps (GstH265Decoder * self, GstH265SPS * sps)
423 GstH265DecoderPrivate *priv = self->priv;
425 gint prev_max_dpb_size;
427 const gint MaxDpbPicBuf = 6;
428 gint PicSizeInSamplesY;
429 guint8 field_seq_flag = 0;
430 guint8 progressive_source_flag = 0;
431 guint8 interlaced_source_flag = 0;
432 GstFlowReturn ret = GST_FLOW_OK;
435 MaxLumaPS = 35651584;
436 PicSizeInSamplesY = sps->width * sps->height;
437 if (PicSizeInSamplesY <= (MaxLumaPS >> 2))
438 max_dpb_size = MaxDpbPicBuf * 4;
439 else if (PicSizeInSamplesY <= (MaxLumaPS >> 1))
440 max_dpb_size = MaxDpbPicBuf * 2;
441 else if (PicSizeInSamplesY <= ((3 * MaxLumaPS) >> 2))
442 max_dpb_size = (MaxDpbPicBuf * 4) / 3;
444 max_dpb_size = MaxDpbPicBuf;
446 max_dpb_size = MIN (max_dpb_size, 16);
448 if (sps->vui_parameters_present_flag)
449 field_seq_flag = sps->vui_params.field_seq_flag;
451 progressive_source_flag = sps->profile_tier_level.progressive_source_flag;
452 interlaced_source_flag = sps->profile_tier_level.interlaced_source_flag;
454 prev_max_dpb_size = gst_h265_dpb_get_max_num_pics (priv->dpb);
455 if (priv->width != sps->width || priv->height != sps->height ||
456 prev_max_dpb_size != max_dpb_size ||
457 priv->field_seq_flag != field_seq_flag ||
458 priv->progressive_source_flag != progressive_source_flag ||
459 priv->interlaced_source_flag != interlaced_source_flag ||
460 gst_h265_decoder_is_crop_rect_changed (self, sps)) {
461 GstH265DecoderClass *klass = GST_H265_DECODER_GET_CLASS (self);
463 GST_DEBUG_OBJECT (self,
464 "SPS updated, resolution: %dx%d -> %dx%d, dpb size: %d -> %d, "
465 "field_seq_flag: %d -> %d, progressive_source_flag: %d -> %d, "
466 "interlaced_source_flag: %d -> %d",
467 priv->width, priv->height, sps->width, sps->height,
468 prev_max_dpb_size, max_dpb_size, priv->field_seq_flag, field_seq_flag,
469 priv->progressive_source_flag, progressive_source_flag,
470 priv->interlaced_source_flag, interlaced_source_flag);
472 if (priv->no_output_of_prior_pics_flag) {
473 gst_h265_decoder_drain_output_queue (self, 0, &ret);
474 gst_h265_decoder_clear_dpb (self, FALSE);
476 ret = gst_h265_decoder_drain_internal (self);
479 if (ret != GST_FLOW_OK)
482 if (klass->get_preferred_output_delay) {
483 priv->preferred_output_delay =
484 klass->get_preferred_output_delay (self, priv->is_live);
486 priv->preferred_output_delay = 0;
489 g_assert (klass->new_sequence);
490 ret = klass->new_sequence (self,
491 sps, max_dpb_size + priv->preferred_output_delay);
492 if (ret != GST_FLOW_OK) {
493 GST_WARNING_OBJECT (self, "subclass does not want accept new sequence");
497 priv->width = sps->width;
498 priv->height = sps->height;
499 priv->conformance_window_flag = sps->conformance_window_flag;
500 priv->crop_rect_width = sps->crop_rect_width;
501 priv->crop_rect_height = sps->crop_rect_height;
502 priv->crop_rect_x = sps->crop_rect_x;
503 priv->crop_rect_y = sps->crop_rect_y;
504 priv->field_seq_flag = field_seq_flag;
505 priv->progressive_source_flag = progressive_source_flag;
506 priv->interlaced_source_flag = interlaced_source_flag;
508 gst_h265_dpb_set_max_num_pics (priv->dpb, max_dpb_size);
509 gst_h265_decoder_set_latency (self, sps, max_dpb_size);
512 if (sps->max_latency_increase_plus1[sps->max_sub_layers_minus1]) {
513 priv->SpsMaxLatencyPictures =
514 sps->max_num_reorder_pics[sps->max_sub_layers_minus1] +
515 sps->max_latency_increase_plus1[sps->max_sub_layers_minus1] - 1;
518 GST_DEBUG_OBJECT (self, "Set DPB max size %d", max_dpb_size);
523 static GstH265ParserResult
524 gst_h265_decoder_parse_sei (GstH265Decoder * self, GstH265NalUnit * nalu)
526 GstH265DecoderPrivate *priv = self->priv;
527 GstH265ParserResult pres;
528 GArray *messages = NULL;
531 pres = gst_h265_parser_parse_sei (priv->parser, nalu, &messages);
532 if (pres != GST_H265_PARSER_OK) {
533 GST_WARNING_OBJECT (self, "Failed to parse SEI, result %d", pres);
535 /* XXX: Ignore error from SEI parsing, it might be malformed bitstream,
536 * or our fault. But shouldn't be critical */
537 g_clear_pointer (&messages, g_array_unref);
538 return GST_H265_PARSER_OK;
541 for (i = 0; i < messages->len; i++) {
542 GstH265SEIMessage *sei = &g_array_index (messages, GstH265SEIMessage, i);
544 switch (sei->payloadType) {
545 case GST_H265_SEI_PIC_TIMING:
546 priv->cur_pic_struct = sei->payload.pic_timing.pic_struct;
547 priv->cur_source_scan_type = sei->payload.pic_timing.source_scan_type;
548 priv->cur_duplicate_flag = sei->payload.pic_timing.duplicate_flag;
550 GST_TRACE_OBJECT (self,
551 "Picture Timing SEI, pic_struct: %d, source_scan_type: %d, "
552 "duplicate_flag: %d", priv->cur_pic_struct,
553 priv->cur_source_scan_type, priv->cur_duplicate_flag);
560 g_array_free (messages, TRUE);
561 GST_LOG_OBJECT (self, "SEI parsed");
563 return GST_H265_PARSER_OK;
567 gst_h265_decoder_process_ref_pic_lists (GstH265Decoder * self,
568 GstH265Picture * curr_pic, GstH265Slice * slice,
569 GArray ** ref_pic_list0, GArray ** ref_pic_list1)
571 GstH265DecoderPrivate *priv = self->priv;
572 GstH265RefPicListModification *ref_mod =
573 &slice->header.ref_pic_list_modification;
574 GstH265PPSSccExtensionParams *scc_ext =
575 &slice->header.pps->pps_scc_extension_params;
577 gint num_tmp_refs, i;
579 *ref_pic_list0 = priv->ref_pic_list0;
580 *ref_pic_list1 = priv->ref_pic_list1;
582 /* There is nothing to be done for I slices */
583 if (GST_H265_IS_I_SLICE (&slice->header))
586 /* Infinite loop prevention */
587 if (self->NumPocStCurrBefore == 0 && self->NumPocStCurrAfter == 0 &&
588 self->NumPocLtCurr == 0 && !scc_ext->pps_curr_pic_ref_enabled_flag) {
589 GST_WARNING_OBJECT (self,
590 "Expected references, got none, preventing infinite loop.");
594 /* 8.3.4 Deriving l0 */
595 tmp_refs = priv->ref_pic_list_tmp;
598 * Deriving l0 consists of appending in loop RefPicSetStCurrBefore,
599 * RefPicSetStCurrAfter and RefPicSetLtCurr until NumRpsCurrTempList0 item
603 /* NumRpsCurrTempList0 */
604 num_tmp_refs = MAX (slice->header.num_ref_idx_l0_active_minus1 + 1,
605 self->NumPicTotalCurr);
607 while (tmp_refs->len < num_tmp_refs) {
608 for (i = 0; i < self->NumPocStCurrBefore && tmp_refs->len < num_tmp_refs;
610 g_array_append_val (tmp_refs, self->RefPicSetStCurrBefore[i]);
611 for (i = 0; i < self->NumPocStCurrAfter && tmp_refs->len < num_tmp_refs;
613 g_array_append_val (tmp_refs, self->RefPicSetStCurrAfter[i]);
614 for (i = 0; i < self->NumPocLtCurr && tmp_refs->len < num_tmp_refs; i++)
615 g_array_append_val (tmp_refs, self->RefPicSetLtCurr[i]);
616 if (scc_ext->pps_curr_pic_ref_enabled_flag)
617 g_array_append_val (tmp_refs, curr_pic);
621 * If needed, apply the modification based on the lookup table found in the
622 * slice header (list_entry_l0).
624 for (i = 0; i <= slice->header.num_ref_idx_l0_active_minus1; i++) {
625 GstH265Picture **tmp = (GstH265Picture **) tmp_refs->data;
627 if (ref_mod->ref_pic_list_modification_flag_l0)
628 g_array_append_val (*ref_pic_list0, tmp[ref_mod->list_entry_l0[i]]);
630 g_array_append_val (*ref_pic_list0, tmp[i]);
633 if (scc_ext->pps_curr_pic_ref_enabled_flag &&
634 !ref_mod->ref_pic_list_modification_flag_l0 &&
635 num_tmp_refs > (slice->header.num_ref_idx_l0_active_minus1 + 1)) {
636 g_array_index (*ref_pic_list0, GstH265Picture *,
637 slice->header.num_ref_idx_l0_active_minus1) = curr_pic;
640 g_array_set_size (tmp_refs, 0);
642 /* For P slices we only need l0 */
643 if (GST_H265_IS_P_SLICE (&slice->header))
646 /* 8.3.4 Deriving l1 */
648 * Deriving l1 consists of appending in loop RefPicSetStCurrAfter,
649 * RefPicSetStCurrBefore and RefPicSetLtCurr until NumRpsCurrTempList1 items
653 /* NumRpsCurrTempList1 */
654 num_tmp_refs = MAX (slice->header.num_ref_idx_l1_active_minus1 + 1,
655 self->NumPicTotalCurr);
657 while (tmp_refs->len < num_tmp_refs) {
658 for (i = 0; i < self->NumPocStCurrAfter && tmp_refs->len < num_tmp_refs;
660 g_array_append_val (tmp_refs, self->RefPicSetStCurrAfter[i]);
661 for (i = 0; i < self->NumPocStCurrBefore && tmp_refs->len < num_tmp_refs;
663 g_array_append_val (tmp_refs, self->RefPicSetStCurrBefore[i]);
664 for (i = 0; i < self->NumPocLtCurr && tmp_refs->len < num_tmp_refs; i++)
665 g_array_append_val (tmp_refs, self->RefPicSetLtCurr[i]);
666 if (scc_ext->pps_curr_pic_ref_enabled_flag)
667 g_array_append_val (tmp_refs, curr_pic);
671 * If needed, apply the modification based on the lookup table found in the
672 * slice header (list_entry_l1).
674 for (i = 0; i <= slice->header.num_ref_idx_l1_active_minus1; i++) {
675 GstH265Picture **tmp = (GstH265Picture **) tmp_refs->data;
677 if (ref_mod->ref_pic_list_modification_flag_l1)
678 g_array_append_val (*ref_pic_list1, tmp[ref_mod->list_entry_l1[i]]);
680 g_array_append_val (*ref_pic_list1, tmp[i]);
683 g_array_set_size (tmp_refs, 0);
687 gst_h265_decoder_decode_slice (GstH265Decoder * self)
689 GstH265DecoderClass *klass = GST_H265_DECODER_GET_CLASS (self);
690 GstH265DecoderPrivate *priv = self->priv;
691 GstH265Slice *slice = &priv->current_slice;
692 GstH265Picture *picture = priv->current_picture;
695 GstFlowReturn ret = GST_FLOW_OK;
698 GST_ERROR_OBJECT (self, "No current picture");
699 return GST_FLOW_ERROR;
702 g_assert (klass->decode_slice);
704 if (priv->process_ref_pic_lists) {
705 l0 = priv->ref_pic_list0;
706 l1 = priv->ref_pic_list1;
707 gst_h265_decoder_process_ref_pic_lists (self, picture, slice, &l0, &l1);
710 ret = klass->decode_slice (self, picture, slice, l0, l1);
712 if (priv->process_ref_pic_lists) {
713 g_array_set_size (l0, 0);
714 g_array_set_size (l1, 0);
721 gst_h265_decoder_preprocess_slice (GstH265Decoder * self, GstH265Slice * slice)
723 GstH265DecoderPrivate *priv = self->priv;
724 const GstH265SliceHdr *slice_hdr = &slice->header;
726 if (priv->current_picture && slice_hdr->first_slice_segment_in_pic_flag) {
727 GST_WARNING_OBJECT (self,
728 "Current picture is not finished but slice header has "
729 "first_slice_segment_in_pic_flag");
730 return GST_FLOW_ERROR;
737 gst_h265_decoder_process_slice (GstH265Decoder * self, GstH265Slice * slice)
739 GstH265DecoderPrivate *priv = self->priv;
740 GstFlowReturn ret = GST_FLOW_OK;
742 priv->current_slice = *slice;
744 if (priv->current_slice.header.dependent_slice_segment_flag) {
745 GstH265SliceHdr *slice_hdr = &priv->current_slice.header;
746 GstH265SliceHdr *indep_slice_hdr = &priv->prev_independent_slice.header;
748 memcpy (&slice_hdr->type, &indep_slice_hdr->type,
749 G_STRUCT_OFFSET (GstH265SliceHdr, num_entry_point_offsets) -
750 G_STRUCT_OFFSET (GstH265SliceHdr, type));
752 priv->prev_independent_slice = priv->current_slice;
753 memset (&priv->prev_independent_slice.nalu, 0, sizeof (GstH265NalUnit));
756 ret = gst_h265_decoder_preprocess_slice (self, &priv->current_slice);
757 if (ret != GST_FLOW_OK)
760 priv->active_pps = priv->current_slice.header.pps;
761 priv->active_sps = priv->active_pps->sps;
763 if (!priv->current_picture) {
764 GstH265DecoderClass *klass = GST_H265_DECODER_GET_CLASS (self);
765 GstH265Picture *picture;
766 GstFlowReturn ret = GST_FLOW_OK;
768 g_assert (priv->current_frame);
770 picture = gst_h265_picture_new ();
771 /* This allows accessing the frame from the picture. */
772 picture->system_frame_number = priv->current_frame->system_frame_number;
774 priv->current_picture = picture;
776 if (klass->new_picture)
777 ret = klass->new_picture (self, priv->current_frame, picture);
779 if (ret != GST_FLOW_OK) {
780 GST_WARNING_OBJECT (self, "subclass does not want accept new picture");
781 priv->current_picture = NULL;
782 gst_h265_picture_unref (picture);
786 ret = gst_h265_decoder_start_current_picture (self);
787 if (ret != GST_FLOW_OK) {
788 GST_WARNING_OBJECT (self, "start picture failed");
792 /* this picture was dropped */
793 if (!priv->current_picture)
797 return gst_h265_decoder_decode_slice (self);
800 static GstH265ParserResult
801 gst_h265_decoder_parse_slice (GstH265Decoder * self, GstH265NalUnit * nalu)
803 GstH265DecoderPrivate *priv = self->priv;
804 GstH265ParserResult pres;
806 GstH265DecoderNalUnit decoder_nalu;
808 memset (&slice, 0, sizeof (GstH265Slice));
810 pres = gst_h265_parser_parse_slice_hdr (priv->parser, nalu, &slice.header);
811 if (pres != GST_H265_PARSER_OK)
814 /* NOTE: gst_h265_parser_parse_slice_hdr() allocates array
815 * GstH265SliceHdr::entry_point_offset_minus1 but we don't use it
816 * in this h265decoder baseclass at the moment
818 gst_h265_slice_hdr_free (&priv->current_slice.header);
821 if (nalu->type >= GST_H265_NAL_SLICE_BLA_W_LP &&
822 nalu->type <= GST_H265_NAL_SLICE_CRA_NUT) {
823 slice.rap_pic_flag = TRUE;
826 /* NoRaslOutputFlag == 1 if the current picture is
829 * 3) a CRA picture that is the first access unit in the bitstream
830 * 4) first picture that follows an end of sequence NAL unit in decoding order
831 * 5) has HandleCraAsBlaFlag == 1 (set by external means, so not considering )
833 if (GST_H265_IS_NAL_TYPE_IDR (nalu->type) ||
834 GST_H265_IS_NAL_TYPE_BLA (nalu->type) ||
835 (GST_H265_IS_NAL_TYPE_CRA (nalu->type) && priv->new_bitstream) ||
836 priv->prev_nal_is_eos) {
837 slice.no_rasl_output_flag = TRUE;
840 if (GST_H265_IS_NAL_TYPE_IRAP (nalu->type)) {
841 slice.intra_pic_flag = TRUE;
843 if (slice.no_rasl_output_flag && !priv->new_bitstream) {
845 slice.clear_dpb = TRUE;
846 if (nalu->type == GST_H265_NAL_SLICE_CRA_NUT) {
847 slice.no_output_of_prior_pics_flag = TRUE;
849 slice.no_output_of_prior_pics_flag =
850 slice.header.no_output_of_prior_pics_flag;
855 if (slice.no_output_of_prior_pics_flag)
856 priv->no_output_of_prior_pics_flag = TRUE;
858 decoder_nalu.unit.slice = slice;
859 decoder_nalu.is_slice = TRUE;
860 g_array_append_val (priv->nalu, decoder_nalu);
862 return GST_H265_PARSER_OK;
865 static GstH265ParserResult
866 gst_h265_decoder_parse_nalu (GstH265Decoder * self, GstH265NalUnit * nalu)
868 GstH265DecoderPrivate *priv = self->priv;
872 GstH265ParserResult ret = GST_H265_PARSER_OK;
873 GstH265DecoderNalUnit decoder_nalu;
875 GST_LOG_OBJECT (self, "Parsed nal type: %d, offset %d, size %d",
876 nalu->type, nalu->offset, nalu->size);
878 switch (nalu->type) {
879 case GST_H265_NAL_VPS:
880 ret = gst_h265_parser_parse_vps (priv->parser, nalu, &vps);
882 case GST_H265_NAL_SPS:
883 ret = gst_h265_parser_parse_sps (priv->parser, nalu, &sps, TRUE);
884 if (ret != GST_H265_PARSER_OK)
887 memset (&decoder_nalu, 0, sizeof (GstH265DecoderNalUnit));
888 decoder_nalu.unit.sps = sps;
889 g_array_append_val (priv->nalu, decoder_nalu);
891 case GST_H265_NAL_PPS:
892 ret = gst_h265_parser_parse_pps (priv->parser, nalu, &pps);
894 case GST_H265_NAL_PREFIX_SEI:
895 case GST_H265_NAL_SUFFIX_SEI:
896 ret = gst_h265_decoder_parse_sei (self, nalu);
898 case GST_H265_NAL_SLICE_TRAIL_N:
899 case GST_H265_NAL_SLICE_TRAIL_R:
900 case GST_H265_NAL_SLICE_TSA_N:
901 case GST_H265_NAL_SLICE_TSA_R:
902 case GST_H265_NAL_SLICE_STSA_N:
903 case GST_H265_NAL_SLICE_STSA_R:
904 case GST_H265_NAL_SLICE_RADL_N:
905 case GST_H265_NAL_SLICE_RADL_R:
906 case GST_H265_NAL_SLICE_RASL_N:
907 case GST_H265_NAL_SLICE_RASL_R:
908 case GST_H265_NAL_SLICE_BLA_W_LP:
909 case GST_H265_NAL_SLICE_BLA_W_RADL:
910 case GST_H265_NAL_SLICE_BLA_N_LP:
911 case GST_H265_NAL_SLICE_IDR_W_RADL:
912 case GST_H265_NAL_SLICE_IDR_N_LP:
913 case GST_H265_NAL_SLICE_CRA_NUT:
914 ret = gst_h265_decoder_parse_slice (self, nalu);
915 priv->new_bitstream = FALSE;
916 priv->prev_nal_is_eos = FALSE;
918 case GST_H265_NAL_EOB:
919 priv->new_bitstream = TRUE;
921 case GST_H265_NAL_EOS:
922 priv->prev_nal_is_eos = TRUE;
932 gst_h265_decoder_decode_nalu (GstH265Decoder * self,
933 GstH265DecoderNalUnit * nalu)
936 return gst_h265_decoder_process_sps (self, &nalu->unit.sps);
938 return gst_h265_decoder_process_slice (self, &nalu->unit.slice);
942 gst_h265_decoder_format_from_caps (GstH265Decoder * self, GstCaps * caps,
943 GstH265DecoderFormat * format, GstH265DecoderAlign * align)
946 *format = GST_H265_DECODER_FORMAT_NONE;
949 *align = GST_H265_DECODER_ALIGN_NONE;
951 if (!gst_caps_is_fixed (caps)) {
952 GST_WARNING_OBJECT (self, "Caps wasn't fixed");
956 GST_DEBUG_OBJECT (self, "parsing caps: %" GST_PTR_FORMAT, caps);
958 if (caps && gst_caps_get_size (caps) > 0) {
959 GstStructure *s = gst_caps_get_structure (caps, 0);
960 const gchar *str = NULL;
963 if ((str = gst_structure_get_string (s, "stream-format"))) {
964 if (strcmp (str, "hvc1") == 0)
965 *format = GST_H265_DECODER_FORMAT_HVC1;
966 else if (strcmp (str, "hev1") == 0)
967 *format = GST_H265_DECODER_FORMAT_HEV1;
968 else if (strcmp (str, "byte-stream") == 0)
969 *format = GST_H265_DECODER_FORMAT_BYTE;
974 if ((str = gst_structure_get_string (s, "alignment"))) {
975 if (strcmp (str, "au") == 0)
976 *align = GST_H265_DECODER_ALIGN_AU;
977 else if (strcmp (str, "nal") == 0)
978 *align = GST_H265_DECODER_ALIGN_NAL;
985 gst_h265_decoder_parse_codec_data (GstH265Decoder * self, const guint8 * data,
988 GstH265DecoderPrivate *priv = self->priv;
989 guint num_nal_arrays;
991 guint num_nals, i, j;
992 GstH265ParserResult pres;
994 GstFlowReturn ret = GST_FLOW_OK;
999 /* parse the hvcC data */
1001 GST_WARNING_OBJECT (self, "hvcC too small");
1002 return GST_FLOW_ERROR;
1005 /* wrong hvcC version */
1006 if (data[0] != 0 && data[0] != 1) {
1007 return GST_FLOW_ERROR;
1010 priv->nal_length_size = (data[21] & 0x03) + 1;
1011 GST_DEBUG_OBJECT (self, "nal length size %u", priv->nal_length_size);
1013 num_nal_arrays = data[22];
1016 for (i = 0; i < num_nal_arrays; i++) {
1017 if (off + 3 >= size) {
1018 GST_WARNING_OBJECT (self, "hvcC too small");
1019 return GST_FLOW_ERROR;
1022 num_nals = GST_READ_UINT16_BE (data + off + 1);
1024 for (j = 0; j < num_nals; j++) {
1025 pres = gst_h265_parser_identify_nalu_hevc (priv->parser,
1026 data, off, size, 2, &nalu);
1028 if (pres != GST_H265_PARSER_OK) {
1029 GST_WARNING_OBJECT (self, "hvcC too small");
1030 return GST_FLOW_ERROR;
1033 switch (nalu.type) {
1034 case GST_H265_NAL_VPS:
1035 pres = gst_h265_parser_parse_vps (priv->parser, &nalu, &vps);
1036 if (pres != GST_H265_PARSER_OK) {
1037 GST_WARNING_OBJECT (self, "Failed to parse VPS");
1038 return GST_FLOW_ERROR;
1041 case GST_H265_NAL_SPS:
1042 pres = gst_h265_parser_parse_sps (priv->parser, &nalu, &sps, TRUE);
1043 if (pres != GST_H265_PARSER_OK) {
1044 GST_WARNING_OBJECT (self, "Failed to parse SPS");
1045 return GST_FLOW_ERROR;
1048 ret = gst_h265_decoder_process_sps (self, &sps);
1049 if (ret != GST_FLOW_OK) {
1050 GST_WARNING_OBJECT (self, "Failed to process SPS");
1054 case GST_H265_NAL_PPS:
1055 pres = gst_h265_parser_parse_pps (priv->parser, &nalu, &pps);
1056 if (pres != GST_H265_PARSER_OK) {
1057 GST_WARNING_OBJECT (self, "Failed to parse PPS");
1058 return GST_FLOW_ERROR;
1065 off = nalu.offset + nalu.size;
1073 gst_h265_decoder_set_format (GstVideoDecoder * decoder,
1074 GstVideoCodecState * state)
1076 GstH265Decoder *self = GST_H265_DECODER (decoder);
1077 GstH265DecoderPrivate *priv = self->priv;
1080 GST_DEBUG_OBJECT (decoder, "Set format");
1082 if (self->input_state)
1083 gst_video_codec_state_unref (self->input_state);
1085 self->input_state = gst_video_codec_state_ref (state);
1087 priv->is_live = FALSE;
1088 query = gst_query_new_latency ();
1089 if (gst_pad_peer_query (GST_VIDEO_DECODER_SINK_PAD (self), query))
1090 gst_query_parse_latency (query, &priv->is_live, NULL, NULL);
1091 gst_query_unref (query);
1094 GstH265DecoderFormat format;
1095 GstH265DecoderAlign align;
1097 gst_h265_decoder_format_from_caps (self, state->caps, &format, &align);
1099 if (format == GST_H265_DECODER_FORMAT_NONE) {
1100 /* codec_data implies packetized */
1101 if (state->codec_data) {
1102 GST_WARNING_OBJECT (self,
1103 "video/x-h265 caps with codec_data but no stream-format=hev1 or hvc1");
1104 format = GST_H265_DECODER_FORMAT_HEV1;
1106 /* otherwise assume bytestream input */
1107 GST_WARNING_OBJECT (self,
1108 "video/x-h265 caps without codec_data or stream-format");
1109 format = GST_H265_DECODER_FORMAT_BYTE;
1113 if (format == GST_H265_DECODER_FORMAT_HEV1 ||
1114 format == GST_H265_DECODER_FORMAT_HVC1) {
1115 if (!state->codec_data) {
1116 /* Try it with size 4 anyway */
1117 priv->nal_length_size = 4;
1118 GST_WARNING_OBJECT (self,
1119 "packetized format without codec data, assuming nal length size is 4");
1122 /* AVC implies alignment=au */
1123 if (align == GST_H265_DECODER_ALIGN_NONE)
1124 align = GST_H265_DECODER_ALIGN_AU;
1127 if (format == GST_H265_DECODER_FORMAT_BYTE && state->codec_data)
1128 GST_WARNING_OBJECT (self, "bytestream with codec data");
1130 priv->in_format = format;
1131 priv->align = align;
1134 if (state->codec_data) {
1137 gst_buffer_map (state->codec_data, &map, GST_MAP_READ);
1138 if (gst_h265_decoder_parse_codec_data (self, map.data, map.size) !=
1140 /* keep going without error.
1141 * Probably inband SPS/PPS might be valid data */
1142 GST_WARNING_OBJECT (self, "Failed to handle codec data");
1144 gst_buffer_unmap (state->codec_data, &map);
1151 gst_h265_decoder_flush (GstVideoDecoder * decoder)
1153 GstH265Decoder *self = GST_H265_DECODER (decoder);
1155 gst_h265_decoder_clear_dpb (self, TRUE);
1160 static GstFlowReturn
1161 gst_h265_decoder_drain (GstVideoDecoder * decoder)
1163 GstH265Decoder *self = GST_H265_DECODER (decoder);
1165 /* dpb will be cleared by this method */
1166 return gst_h265_decoder_drain_internal (self);
1169 static GstFlowReturn
1170 gst_h265_decoder_finish (GstVideoDecoder * decoder)
1172 return gst_h265_decoder_drain (decoder);
1176 gst_h265_decoder_fill_picture_from_slice (GstH265Decoder * self,
1177 const GstH265Slice * slice, GstH265Picture * picture)
1179 GstH265DecoderPrivate *priv = self->priv;
1180 const GstH265SliceHdr *slice_hdr = &slice->header;
1181 const GstH265NalUnit *nalu = &slice->nalu;
1183 picture->RapPicFlag = slice->rap_pic_flag;
1184 picture->NoRaslOutputFlag = slice->no_rasl_output_flag;
1185 picture->IntraPicFlag = slice->intra_pic_flag;
1186 picture->NoOutputOfPriorPicsFlag = slice->no_output_of_prior_pics_flag;
1187 if (picture->IntraPicFlag) {
1188 priv->associated_irap_NoRaslOutputFlag = picture->NoRaslOutputFlag;
1191 if (GST_H265_IS_NAL_TYPE_RASL (nalu->type) &&
1192 priv->associated_irap_NoRaslOutputFlag) {
1193 picture->output_flag = FALSE;
1195 picture->output_flag = slice_hdr->pic_output_flag;
1201 #define RSV_VCL_N10 10
1202 #define RSV_VCL_N12 12
1203 #define RSV_VCL_N14 14
1206 nal_is_ref (guint8 nal_type)
1208 gboolean ret = FALSE;
1210 case GST_H265_NAL_SLICE_TRAIL_N:
1211 case GST_H265_NAL_SLICE_TSA_N:
1212 case GST_H265_NAL_SLICE_STSA_N:
1213 case GST_H265_NAL_SLICE_RADL_N:
1214 case GST_H265_NAL_SLICE_RASL_N:
1228 gst_h265_decoder_calculate_poc (GstH265Decoder * self,
1229 const GstH265Slice * slice, GstH265Picture * picture)
1231 GstH265DecoderPrivate *priv = self->priv;
1232 const GstH265SliceHdr *slice_hdr = &slice->header;
1233 const GstH265NalUnit *nalu = &slice->nalu;
1234 const GstH265SPS *sps = priv->active_sps;
1235 gint32 MaxPicOrderCntLsb = 1 << (sps->log2_max_pic_order_cnt_lsb_minus4 + 4);
1238 GST_DEBUG_OBJECT (self, "decode PicOrderCntVal");
1240 priv->prev_poc_lsb = priv->poc_lsb;
1241 priv->prev_poc_msb = priv->poc_msb;
1243 is_irap = GST_H265_IS_NAL_TYPE_IRAP (nalu->type);
1245 if (!(is_irap && picture->NoRaslOutputFlag)) {
1246 priv->prev_poc_lsb = priv->prev_tid0pic_poc_lsb;
1247 priv->prev_poc_msb = priv->prev_tid0pic_poc_msb;
1250 /* Finding PicOrderCntMsb */
1251 if (is_irap && picture->NoRaslOutputFlag) {
1255 if ((slice_hdr->pic_order_cnt_lsb < priv->prev_poc_lsb) &&
1256 ((priv->prev_poc_lsb - slice_hdr->pic_order_cnt_lsb) >=
1257 (MaxPicOrderCntLsb / 2)))
1258 priv->poc_msb = priv->prev_poc_msb + MaxPicOrderCntLsb;
1260 else if ((slice_hdr->pic_order_cnt_lsb > priv->prev_poc_lsb) &&
1261 ((slice_hdr->pic_order_cnt_lsb - priv->prev_poc_lsb) >
1262 (MaxPicOrderCntLsb / 2)))
1263 priv->poc_msb = priv->prev_poc_msb - MaxPicOrderCntLsb;
1266 priv->poc_msb = priv->prev_poc_msb;
1270 priv->poc = picture->pic_order_cnt =
1271 priv->poc_msb + slice_hdr->pic_order_cnt_lsb;
1272 priv->poc_lsb = picture->pic_order_cnt_lsb = slice_hdr->pic_order_cnt_lsb;
1274 if (GST_H265_IS_NAL_TYPE_IDR (nalu->type)) {
1275 picture->pic_order_cnt = 0;
1276 picture->pic_order_cnt_lsb = 0;
1279 priv->prev_poc_lsb = 0;
1280 priv->prev_poc_msb = 0;
1281 priv->prev_tid0pic_poc_lsb = 0;
1282 priv->prev_tid0pic_poc_msb = 0;
1285 GST_DEBUG_OBJECT (self,
1286 "PicOrderCntVal %d, (lsb %d)", picture->pic_order_cnt,
1287 picture->pic_order_cnt_lsb);
1289 if (nalu->temporal_id_plus1 == 1 && !GST_H265_IS_NAL_TYPE_RASL (nalu->type) &&
1290 !GST_H265_IS_NAL_TYPE_RADL (nalu->type) && nal_is_ref (nalu->type)) {
1291 priv->prev_tid0pic_poc_lsb = slice_hdr->pic_order_cnt_lsb;
1292 priv->prev_tid0pic_poc_msb = priv->poc_msb;
1299 gst_h265_decoder_set_buffer_flags (GstH265Decoder * self,
1300 GstH265Picture * picture)
1302 GstH265DecoderPrivate *priv = self->priv;
1304 switch (picture->pic_struct) {
1305 case GST_H265_SEI_PIC_STRUCT_FRAME:
1307 case GST_H265_SEI_PIC_STRUCT_TOP_FIELD:
1308 case GST_H265_SEI_PIC_STRUCT_TOP_PAIRED_PREVIOUS_BOTTOM:
1309 case GST_H265_SEI_PIC_STRUCT_TOP_PAIRED_NEXT_BOTTOM:
1310 if (!priv->field_seq_flag) {
1311 GST_FIXME_OBJECT (self,
1312 "top-field with field_seq_flag == 0, what does it mean?");
1314 picture->buffer_flags = GST_VIDEO_BUFFER_FLAG_TOP_FIELD;
1317 case GST_H265_SEI_PIC_STRUCT_BOTTOM_FIELD:
1318 case GST_H265_SEI_PIC_STRUCT_BOTTOM_PAIRED_PREVIOUS_TOP:
1319 case GST_H265_SEI_PIC_STRUCT_BOTTOM_PAIRED_NEXT_TOP:
1320 if (!priv->field_seq_flag) {
1321 GST_FIXME_OBJECT (self,
1322 "bottom-field with field_seq_flag == 0, what does it mean?");
1324 picture->buffer_flags = GST_VIDEO_BUFFER_FLAG_BOTTOM_FIELD;
1327 case GST_H265_SEI_PIC_STRUCT_TOP_BOTTOM:
1328 if (priv->field_seq_flag) {
1329 GST_FIXME_OBJECT (self,
1330 "TFF with field_seq_flag == 1, what does it mean?");
1332 picture->buffer_flags =
1333 GST_VIDEO_BUFFER_FLAG_INTERLACED | GST_VIDEO_BUFFER_FLAG_TFF;
1336 case GST_H265_SEI_PIC_STRUCT_BOTTOM_TOP:
1337 if (priv->field_seq_flag) {
1338 GST_FIXME_OBJECT (self,
1339 "BFF with field_seq_flag == 1, what does it mean?");
1341 picture->buffer_flags = GST_VIDEO_BUFFER_FLAG_INTERLACED;
1345 GST_FIXME_OBJECT (self, "Unhandled picture time SEI pic_struct %d",
1346 picture->pic_struct);
1354 gst_h265_decoder_init_current_picture (GstH265Decoder * self)
1356 GstH265DecoderPrivate *priv = self->priv;
1358 if (!gst_h265_decoder_fill_picture_from_slice (self, &priv->current_slice,
1359 priv->current_picture)) {
1363 if (!gst_h265_decoder_calculate_poc (self,
1364 &priv->current_slice, priv->current_picture))
1367 /* Use picture struct parsed from picture timing SEI */
1368 priv->current_picture->pic_struct = priv->cur_pic_struct;
1369 priv->current_picture->source_scan_type = priv->cur_source_scan_type;
1370 priv->current_picture->duplicate_flag = priv->cur_duplicate_flag;
1371 gst_h265_decoder_set_buffer_flags (self, priv->current_picture);
1377 has_entry_in_rps (GstH265Picture * dpb_pic,
1378 GstH265Picture ** rps_list, guint rps_list_length)
1382 if (!dpb_pic || !rps_list || !rps_list_length)
1385 for (i = 0; i < rps_list_length; i++) {
1386 if (rps_list[i] && rps_list[i]->pic_order_cnt == dpb_pic->pic_order_cnt)
1393 gst_h265_decoder_clear_ref_pic_sets (GstH265Decoder * self)
1397 for (i = 0; i < 16; i++) {
1398 gst_h265_picture_replace (&self->RefPicSetLtCurr[i], NULL);
1399 gst_h265_picture_replace (&self->RefPicSetLtFoll[i], NULL);
1400 gst_h265_picture_replace (&self->RefPicSetStCurrBefore[i], NULL);
1401 gst_h265_picture_replace (&self->RefPicSetStCurrAfter[i], NULL);
1402 gst_h265_picture_replace (&self->RefPicSetStFoll[i], NULL);
1407 gst_h265_decoder_derive_and_mark_rps (GstH265Decoder * self,
1408 GstH265Picture * picture, gint32 * CurrDeltaPocMsbPresentFlag,
1409 gint32 * FollDeltaPocMsbPresentFlag)
1411 GstH265DecoderPrivate *priv = self->priv;
1415 gst_h265_decoder_clear_ref_pic_sets (self);
1418 for (i = 0; i < self->NumPocLtCurr; i++) {
1419 if (!CurrDeltaPocMsbPresentFlag[i]) {
1420 self->RefPicSetLtCurr[i] =
1421 gst_h265_dpb_get_ref_by_poc_lsb (priv->dpb, priv->PocLtCurr[i]);
1423 self->RefPicSetLtCurr[i] =
1424 gst_h265_dpb_get_ref_by_poc (priv->dpb, priv->PocLtCurr[i]);
1428 for (i = 0; i < self->NumPocLtFoll; i++) {
1429 if (!FollDeltaPocMsbPresentFlag[i]) {
1430 self->RefPicSetLtFoll[i] =
1431 gst_h265_dpb_get_ref_by_poc_lsb (priv->dpb, priv->PocLtFoll[i]);
1433 self->RefPicSetLtFoll[i] =
1434 gst_h265_dpb_get_ref_by_poc (priv->dpb, priv->PocLtFoll[i]);
1438 /* Mark all ref pics in RefPicSetLtCurr and RefPicSetLtFol as long_term_refs */
1439 for (i = 0; i < self->NumPocLtCurr; i++) {
1440 if (self->RefPicSetLtCurr[i]) {
1441 self->RefPicSetLtCurr[i]->ref = TRUE;
1442 self->RefPicSetLtCurr[i]->long_term = TRUE;
1446 for (i = 0; i < self->NumPocLtFoll; i++) {
1447 if (self->RefPicSetLtFoll[i]) {
1448 self->RefPicSetLtFoll[i]->ref = TRUE;
1449 self->RefPicSetLtFoll[i]->long_term = TRUE;
1454 for (i = 0; i < self->NumPocStCurrBefore; i++) {
1455 self->RefPicSetStCurrBefore[i] =
1456 gst_h265_dpb_get_short_ref_by_poc (priv->dpb, priv->PocStCurrBefore[i]);
1459 for (i = 0; i < self->NumPocStCurrAfter; i++) {
1460 self->RefPicSetStCurrAfter[i] =
1461 gst_h265_dpb_get_short_ref_by_poc (priv->dpb, priv->PocStCurrAfter[i]);
1464 for (i = 0; i < self->NumPocStFoll; i++) {
1465 self->RefPicSetStFoll[i] =
1466 gst_h265_dpb_get_short_ref_by_poc (priv->dpb, priv->PocStFoll[i]);
1469 /* Mark all dpb pics not beloging to RefPicSet*[] as unused for ref */
1470 dpb_array = gst_h265_dpb_get_pictures_all (priv->dpb);
1471 for (i = 0; i < dpb_array->len; i++) {
1472 GstH265Picture *dpb_pic = g_array_index (dpb_array, GstH265Picture *, i);
1475 !has_entry_in_rps (dpb_pic, self->RefPicSetLtCurr, self->NumPocLtCurr)
1476 && !has_entry_in_rps (dpb_pic, self->RefPicSetLtFoll,
1478 && !has_entry_in_rps (dpb_pic, self->RefPicSetStCurrAfter,
1479 self->NumPocStCurrAfter)
1480 && !has_entry_in_rps (dpb_pic, self->RefPicSetStCurrBefore,
1481 self->NumPocStCurrBefore)
1482 && !has_entry_in_rps (dpb_pic, self->RefPicSetStFoll,
1483 self->NumPocStFoll)) {
1484 GST_LOG_OBJECT (self, "Mark Picture %p (poc %d) as non-ref", dpb_pic,
1485 dpb_pic->pic_order_cnt);
1486 dpb_pic->ref = FALSE;
1487 dpb_pic->long_term = FALSE;
1491 g_array_unref (dpb_array);
1495 gst_h265_decoder_prepare_rps (GstH265Decoder * self, const GstH265Slice * slice,
1496 GstH265Picture * picture)
1498 GstH265DecoderPrivate *priv = self->priv;
1499 gint32 CurrDeltaPocMsbPresentFlag[16] = { 0, };
1500 gint32 FollDeltaPocMsbPresentFlag[16] = { 0, };
1501 const GstH265SliceHdr *slice_hdr = &slice->header;
1502 const GstH265NalUnit *nalu = &slice->nalu;
1503 const GstH265SPS *sps = priv->active_sps;
1504 guint32 MaxPicOrderCntLsb = 1 << (sps->log2_max_pic_order_cnt_lsb_minus4 + 4);
1507 /* if it is an irap pic, set all ref pics in dpb as unused for ref */
1508 if (GST_H265_IS_NAL_TYPE_IRAP (nalu->type) && picture->NoRaslOutputFlag) {
1509 GST_DEBUG_OBJECT (self, "Mark all pictures in DPB as non-ref");
1510 gst_h265_dpb_mark_all_non_ref (priv->dpb);
1513 /* Reset everything for IDR */
1514 if (GST_H265_IS_NAL_TYPE_IDR (nalu->type)) {
1515 memset (priv->PocStCurrBefore, 0, sizeof (priv->PocStCurrBefore));
1516 memset (priv->PocStCurrAfter, 0, sizeof (priv->PocStCurrAfter));
1517 memset (priv->PocStFoll, 0, sizeof (priv->PocStFoll));
1518 memset (priv->PocLtCurr, 0, sizeof (priv->PocLtCurr));
1519 memset (priv->PocLtFoll, 0, sizeof (priv->PocLtFoll));
1520 self->NumPocStCurrBefore = self->NumPocStCurrAfter = self->NumPocStFoll = 0;
1521 self->NumPocLtCurr = self->NumPocLtFoll = 0;
1523 const GstH265ShortTermRefPicSet *stRefPic = NULL;
1524 gint32 num_lt_pics, pocLt;
1525 gint32 PocLsbLt[16] = { 0, };
1526 gint32 UsedByCurrPicLt[16] = { 0, };
1527 gint32 DeltaPocMsbCycleLt[16] = { 0, };
1528 gint numtotalcurr = 0;
1530 /* this is based on CurrRpsIdx described in spec */
1531 if (!slice_hdr->short_term_ref_pic_set_sps_flag)
1532 stRefPic = &slice_hdr->short_term_ref_pic_sets;
1533 else if (sps->num_short_term_ref_pic_sets)
1535 &sps->short_term_ref_pic_set[slice_hdr->short_term_ref_pic_set_idx];
1537 g_assert (stRefPic != NULL);
1539 GST_LOG_OBJECT (self,
1540 "NumDeltaPocs: %d, NumNegativePics: %d, NumPositivePics %d",
1541 stRefPic->NumDeltaPocs, stRefPic->NumNegativePics,
1542 stRefPic->NumPositivePics);
1544 for (i = 0, j = 0, k = 0; i < stRefPic->NumNegativePics; i++) {
1545 if (stRefPic->UsedByCurrPicS0[i]) {
1546 priv->PocStCurrBefore[j++] =
1547 picture->pic_order_cnt + stRefPic->DeltaPocS0[i];
1550 priv->PocStFoll[k++] = picture->pic_order_cnt + stRefPic->DeltaPocS0[i];
1552 self->NumPocStCurrBefore = j;
1553 for (i = 0, j = 0; i < stRefPic->NumPositivePics; i++) {
1554 if (stRefPic->UsedByCurrPicS1[i]) {
1555 priv->PocStCurrAfter[j++] =
1556 picture->pic_order_cnt + stRefPic->DeltaPocS1[i];
1559 priv->PocStFoll[k++] = picture->pic_order_cnt + stRefPic->DeltaPocS1[i];
1561 self->NumPocStCurrAfter = j;
1562 self->NumPocStFoll = k;
1563 num_lt_pics = slice_hdr->num_long_term_sps + slice_hdr->num_long_term_pics;
1564 /* The variables PocLsbLt[i] and UsedByCurrPicLt[i] are derived as follows: */
1565 for (i = 0; i < num_lt_pics; i++) {
1566 if (i < slice_hdr->num_long_term_sps) {
1567 PocLsbLt[i] = sps->lt_ref_pic_poc_lsb_sps[slice_hdr->lt_idx_sps[i]];
1568 UsedByCurrPicLt[i] =
1569 sps->used_by_curr_pic_lt_sps_flag[slice_hdr->lt_idx_sps[i]];
1571 PocLsbLt[i] = slice_hdr->poc_lsb_lt[i];
1572 UsedByCurrPicLt[i] = slice_hdr->used_by_curr_pic_lt_flag[i];
1574 if (UsedByCurrPicLt[i])
1578 self->NumPicTotalCurr = numtotalcurr;
1580 /* The variable DeltaPocMsbCycleLt[i] is derived as follows: (7-38) */
1581 for (i = 0; i < num_lt_pics; i++) {
1582 if (i == 0 || i == slice_hdr->num_long_term_sps)
1583 DeltaPocMsbCycleLt[i] = slice_hdr->delta_poc_msb_cycle_lt[i];
1585 DeltaPocMsbCycleLt[i] =
1586 slice_hdr->delta_poc_msb_cycle_lt[i] + DeltaPocMsbCycleLt[i - 1];
1590 for (i = 0, j = 0, k = 0; i < num_lt_pics; i++) {
1591 pocLt = PocLsbLt[i];
1592 if (slice_hdr->delta_poc_msb_present_flag[i])
1594 picture->pic_order_cnt - DeltaPocMsbCycleLt[i] * MaxPicOrderCntLsb -
1595 slice_hdr->pic_order_cnt_lsb;
1596 if (UsedByCurrPicLt[i]) {
1597 priv->PocLtCurr[j] = pocLt;
1598 CurrDeltaPocMsbPresentFlag[j++] =
1599 slice_hdr->delta_poc_msb_present_flag[i];
1601 priv->PocLtFoll[k] = pocLt;
1602 FollDeltaPocMsbPresentFlag[k++] =
1603 slice_hdr->delta_poc_msb_present_flag[i];
1606 self->NumPocLtCurr = j;
1607 self->NumPocLtFoll = k;
1610 GST_LOG_OBJECT (self, "NumPocStCurrBefore: %d", self->NumPocStCurrBefore);
1611 GST_LOG_OBJECT (self, "NumPocStCurrAfter: %d", self->NumPocStCurrAfter);
1612 GST_LOG_OBJECT (self, "NumPocStFoll: %d", self->NumPocStFoll);
1613 GST_LOG_OBJECT (self, "NumPocLtCurr: %d", self->NumPocLtCurr);
1614 GST_LOG_OBJECT (self, "NumPocLtFoll: %d", self->NumPocLtFoll);
1615 GST_LOG_OBJECT (self, "NumPicTotalCurr: %d", self->NumPicTotalCurr);
1617 /* the derivation process for the RPS and the picture marking */
1618 gst_h265_decoder_derive_and_mark_rps (self, picture,
1619 CurrDeltaPocMsbPresentFlag, FollDeltaPocMsbPresentFlag);
1625 gst_h265_decoder_do_output_picture (GstH265Decoder * self,
1626 GstH265Picture * picture, GstFlowReturn * ret)
1628 GstH265DecoderPrivate *priv = self->priv;
1629 GstVideoCodecFrame *frame = NULL;
1630 GstH265DecoderOutputFrame output_frame;
1631 GstFlowReturn flow_ret = GST_FLOW_OK;
1633 g_assert (ret != NULL);
1635 GST_LOG_OBJECT (self, "Output picture %p (poc %d)", picture,
1636 picture->pic_order_cnt);
1638 if (picture->pic_order_cnt < priv->last_output_poc) {
1639 GST_WARNING_OBJECT (self,
1640 "Outputting out of order %d -> %d, likely a broken stream",
1641 priv->last_output_poc, picture->pic_order_cnt);
1644 priv->last_output_poc = picture->pic_order_cnt;
1646 frame = gst_video_decoder_get_frame (GST_VIDEO_DECODER (self),
1647 picture->system_frame_number);
1650 GST_ERROR_OBJECT (self,
1651 "No available codec frame with frame number %d",
1652 picture->system_frame_number);
1653 UPDATE_FLOW_RETURN (ret, GST_FLOW_ERROR);
1655 gst_h265_picture_unref (picture);
1659 output_frame.frame = frame;
1660 output_frame.picture = picture;
1661 output_frame.self = self;
1662 gst_queue_array_push_tail_struct (priv->output_queue, &output_frame);
1664 gst_h265_decoder_drain_output_queue (self, priv->preferred_output_delay,
1666 UPDATE_FLOW_RETURN (ret, flow_ret);
1670 gst_h265_decoder_clear_dpb (GstH265Decoder * self, gboolean flush)
1672 GstVideoDecoder *decoder = GST_VIDEO_DECODER (self);
1673 GstH265DecoderPrivate *priv = self->priv;
1674 GstH265Picture *picture;
1676 /* If we are not flushing now, videodecoder baseclass will hold
1677 * GstVideoCodecFrame. Release frames manually */
1679 while ((picture = gst_h265_dpb_bump (priv->dpb, TRUE)) != NULL) {
1680 GstVideoCodecFrame *frame = gst_video_decoder_get_frame (decoder,
1681 picture->system_frame_number);
1684 gst_video_decoder_release_frame (decoder, frame);
1685 gst_h265_picture_unref (picture);
1689 gst_queue_array_clear (priv->output_queue);
1690 gst_h265_dpb_clear (priv->dpb);
1691 priv->last_output_poc = G_MININT32;
1694 static GstFlowReturn
1695 gst_h265_decoder_drain_internal (GstH265Decoder * self)
1697 GstH265DecoderPrivate *priv = self->priv;
1698 GstH265Picture *picture;
1699 GstFlowReturn ret = GST_FLOW_OK;
1701 while ((picture = gst_h265_dpb_bump (priv->dpb, TRUE)) != NULL)
1702 gst_h265_decoder_do_output_picture (self, picture, &ret);
1704 gst_h265_decoder_drain_output_queue (self, 0, &ret);
1706 gst_h265_dpb_clear (priv->dpb);
1707 priv->last_output_poc = G_MININT32;
1713 static GstFlowReturn
1714 gst_h265_decoder_dpb_init (GstH265Decoder * self, const GstH265Slice * slice,
1715 GstH265Picture * picture)
1717 GstH265DecoderPrivate *priv = self->priv;
1718 const GstH265SPS *sps = priv->active_sps;
1719 GstH265Picture *to_output;
1720 GstFlowReturn ret = GST_FLOW_OK;
1723 if (slice->clear_dpb) {
1724 if (picture->NoOutputOfPriorPicsFlag) {
1725 GST_DEBUG_OBJECT (self, "Clear dpb");
1726 gst_h265_decoder_drain_output_queue (self, 0, &ret);
1727 gst_h265_decoder_clear_dpb (self, FALSE);
1729 gst_h265_dpb_delete_unused (priv->dpb);
1730 while ((to_output = gst_h265_dpb_bump (priv->dpb, FALSE)) != NULL)
1731 gst_h265_decoder_do_output_picture (self, to_output, &ret);
1733 if (gst_h265_dpb_get_size (priv->dpb) > 0) {
1734 GST_WARNING_OBJECT (self, "IDR or BLA frame failed to clear the dpb, "
1735 "there are still %d pictures in the dpb, last output poc is %d",
1736 gst_h265_dpb_get_size (priv->dpb), priv->last_output_poc);
1738 priv->last_output_poc = G_MININT32;
1742 gst_h265_dpb_delete_unused (priv->dpb);
1743 while (gst_h265_dpb_needs_bump (priv->dpb,
1744 sps->max_num_reorder_pics[sps->max_sub_layers_minus1],
1745 priv->SpsMaxLatencyPictures,
1746 sps->max_dec_pic_buffering_minus1[sps->max_sub_layers_minus1] +
1748 to_output = gst_h265_dpb_bump (priv->dpb, FALSE);
1750 /* Something wrong... */
1752 GST_WARNING_OBJECT (self, "Bumping is needed but no picture to output");
1756 gst_h265_decoder_do_output_picture (self, to_output, &ret);
1763 static GstFlowReturn
1764 gst_h265_decoder_start_current_picture (GstH265Decoder * self)
1766 GstH265DecoderClass *klass;
1767 GstH265DecoderPrivate *priv = self->priv;
1768 GstFlowReturn ret = GST_FLOW_OK;
1770 g_assert (priv->current_picture != NULL);
1771 g_assert (priv->active_sps != NULL);
1772 g_assert (priv->active_pps != NULL);
1774 if (!gst_h265_decoder_init_current_picture (self))
1775 return GST_FLOW_ERROR;
1777 /* Drop all RASL pictures having NoRaslOutputFlag is TRUE for the
1778 * associated IRAP picture */
1779 if (GST_H265_IS_NAL_TYPE_RASL (priv->current_slice.nalu.type) &&
1780 priv->associated_irap_NoRaslOutputFlag) {
1781 GST_DEBUG_OBJECT (self, "Drop current picture");
1782 gst_h265_picture_replace (&priv->current_picture, NULL);
1786 gst_h265_decoder_prepare_rps (self, &priv->current_slice,
1787 priv->current_picture);
1789 ret = gst_h265_decoder_dpb_init (self,
1790 &priv->current_slice, priv->current_picture);
1791 if (ret != GST_FLOW_OK) {
1792 GST_WARNING_OBJECT (self, "Failed to init dpb");
1796 klass = GST_H265_DECODER_GET_CLASS (self);
1797 if (klass->start_picture) {
1798 ret = klass->start_picture (self, priv->current_picture,
1799 &priv->current_slice, priv->dpb);
1801 if (ret != GST_FLOW_OK) {
1802 GST_WARNING_OBJECT (self, "subclass does not want to start picture");
1811 gst_h265_decoder_finish_picture (GstH265Decoder * self,
1812 GstH265Picture * picture, GstFlowReturn * ret)
1814 GstVideoDecoder *decoder = GST_VIDEO_DECODER (self);
1815 GstH265DecoderPrivate *priv = self->priv;
1816 const GstH265SPS *sps = priv->active_sps;
1818 g_assert (ret != NULL);
1820 GST_LOG_OBJECT (self,
1821 "Finishing picture %p (poc %d), entries in DPB %d",
1822 picture, picture->pic_order_cnt, gst_h265_dpb_get_size (priv->dpb));
1824 gst_h265_dpb_delete_unused (priv->dpb);
1826 /* This picture is decode only, drop corresponding frame */
1827 if (!picture->output_flag) {
1828 GstVideoCodecFrame *frame = gst_video_decoder_get_frame (decoder,
1829 picture->system_frame_number);
1831 gst_video_decoder_release_frame (decoder, frame);
1834 /* gst_h265_dpb_add() will take care of pic_latency_cnt increment and
1835 * reference picture marking for this picture */
1836 gst_h265_dpb_add (priv->dpb, picture);
1838 /* NOTE: As per C.5.2.2, bumping by sps_max_dec_pic_buffering_minus1 is
1839 * applied only for the output and removal of pictures from the DPB before
1840 * the decoding of the current picture. So pass zero here */
1841 while (gst_h265_dpb_needs_bump (priv->dpb,
1842 sps->max_num_reorder_pics[sps->max_sub_layers_minus1],
1843 priv->SpsMaxLatencyPictures, 0)) {
1844 GstH265Picture *to_output = gst_h265_dpb_bump (priv->dpb, FALSE);
1846 /* Something wrong... */
1848 GST_WARNING_OBJECT (self, "Bumping is needed but no picture to output");
1852 gst_h265_decoder_do_output_picture (self, to_output, ret);
1857 gst_h265_decoder_finish_current_picture (GstH265Decoder * self,
1858 GstFlowReturn * ret)
1860 GstH265DecoderPrivate *priv = self->priv;
1861 GstH265DecoderClass *klass;
1862 GstFlowReturn flow_ret = GST_FLOW_OK;
1864 g_assert (ret != NULL);
1866 if (!priv->current_picture)
1869 klass = GST_H265_DECODER_GET_CLASS (self);
1871 if (klass->end_picture) {
1872 flow_ret = klass->end_picture (self, priv->current_picture);
1873 if (flow_ret != GST_FLOW_OK) {
1874 GST_WARNING_OBJECT (self, "End picture failed");
1876 /* continue to empty dpb */
1877 UPDATE_FLOW_RETURN (ret, flow_ret);
1881 /* finish picture takes ownership of the picture */
1882 gst_h265_decoder_finish_picture (self, priv->current_picture, &flow_ret);
1883 priv->current_picture = NULL;
1885 UPDATE_FLOW_RETURN (ret, flow_ret);
1889 gst_h265_decoder_reset_frame_state (GstH265Decoder * self)
1891 GstH265DecoderPrivate *priv = self->priv;
1893 /* Clear picture struct information */
1894 priv->cur_pic_struct = GST_H265_SEI_PIC_STRUCT_FRAME;
1895 priv->cur_source_scan_type = 2;
1896 priv->cur_duplicate_flag = 0;
1897 priv->no_output_of_prior_pics_flag = FALSE;
1898 priv->current_frame = NULL;
1899 g_array_set_size (priv->nalu, 0);
1902 static GstFlowReturn
1903 gst_h265_decoder_handle_frame (GstVideoDecoder * decoder,
1904 GstVideoCodecFrame * frame)
1906 GstH265Decoder *self = GST_H265_DECODER (decoder);
1907 GstH265DecoderPrivate *priv = self->priv;
1908 GstBuffer *in_buf = frame->input_buffer;
1909 GstH265NalUnit nalu;
1910 GstH265ParserResult pres;
1912 GstFlowReturn decode_ret = GST_FLOW_OK;
1915 GST_LOG_OBJECT (self,
1916 "handle frame, PTS: %" GST_TIME_FORMAT ", DTS: %"
1917 GST_TIME_FORMAT, GST_TIME_ARGS (GST_BUFFER_PTS (in_buf)),
1918 GST_TIME_ARGS (GST_BUFFER_DTS (in_buf)));
1920 gst_h265_decoder_reset_frame_state (self);
1922 priv->current_frame = frame;
1924 if (!gst_buffer_map (in_buf, &map, GST_MAP_READ)) {
1925 GST_ELEMENT_ERROR (self, RESOURCE, READ,
1926 ("Failed to map memory for reading"), (NULL));
1927 return GST_FLOW_ERROR;
1930 if (priv->in_format == GST_H265_DECODER_FORMAT_HVC1 ||
1931 priv->in_format == GST_H265_DECODER_FORMAT_HEV1) {
1936 pres = gst_h265_parser_identify_and_split_nalu_hevc (priv->parser,
1937 map.data, offset, map.size, priv->nal_length_size, priv->split_nalu,
1939 if (pres != GST_H265_PARSER_OK)
1942 for (i = 0; i < priv->split_nalu->len; i++) {
1943 GstH265NalUnit *nl =
1944 &g_array_index (priv->split_nalu, GstH265NalUnit, i);
1945 pres = gst_h265_decoder_parse_nalu (self, nl);
1946 if (pres != GST_H265_PARSER_OK)
1950 if (pres != GST_H265_PARSER_OK)
1954 } while (pres == GST_H265_PARSER_OK);
1956 pres = gst_h265_parser_identify_nalu (priv->parser,
1957 map.data, 0, map.size, &nalu);
1959 if (pres == GST_H265_PARSER_NO_NAL_END)
1960 pres = GST_H265_PARSER_OK;
1962 while (pres == GST_H265_PARSER_OK) {
1963 pres = gst_h265_decoder_parse_nalu (self, &nalu);
1964 if (pres != GST_H265_PARSER_OK)
1967 pres = gst_h265_parser_identify_nalu (priv->parser,
1968 map.data, nalu.offset + nalu.size, map.size, &nalu);
1969 if (pres == GST_H265_PARSER_NO_NAL_END)
1970 pres = GST_H265_PARSER_OK;
1974 for (i = 0; i < priv->nalu->len && decode_ret == GST_FLOW_OK; i++) {
1975 GstH265DecoderNalUnit *decoder_nalu =
1976 &g_array_index (priv->nalu, GstH265DecoderNalUnit, i);
1977 decode_ret = gst_h265_decoder_decode_nalu (self, decoder_nalu);
1980 gst_buffer_unmap (in_buf, &map);
1981 gst_h265_decoder_reset_frame_state (self);
1983 if (decode_ret != GST_FLOW_OK) {
1984 if (decode_ret == GST_FLOW_ERROR) {
1985 GST_VIDEO_DECODER_ERROR (self, 1, STREAM, DECODE,
1986 ("Failed to decode data"), (NULL), decode_ret);
1989 gst_video_decoder_drop_frame (decoder, frame);
1990 gst_clear_h265_picture (&priv->current_picture);
1995 if (priv->current_picture) {
1996 gst_h265_decoder_finish_current_picture (self, &decode_ret);
1997 gst_video_codec_frame_unref (frame);
1999 /* This picture was dropped */
2000 gst_video_decoder_release_frame (decoder, frame);
2003 if (decode_ret == GST_FLOW_ERROR) {
2004 GST_VIDEO_DECODER_ERROR (self, 1, STREAM, DECODE,
2005 ("Failed to decode data"), (NULL), decode_ret);
2012 gst_h265_decoder_clear_nalu (GstH265DecoderNalUnit * nalu)
2017 memset (nalu, 0, sizeof (GstH265DecoderNalUnit));
2021 * gst_h265_decoder_set_process_ref_pic_lists:
2022 * @decoder: a #GstH265Decoder
2023 * @process: whether subclass is requiring reference picture modification process
2025 * Called to en/disable reference picture modification process.
2030 gst_h265_decoder_set_process_ref_pic_lists (GstH265Decoder * decoder,
2033 decoder->priv->process_ref_pic_lists = process;
2037 * gst_h265_decoder_get_picture:
2038 * @decoder: a #GstH265Decoder
2039 * @system_frame_number: a target system frame number of #GstH265Picture
2041 * Retrive DPB and return a #GstH265Picture corresponding to
2042 * the @system_frame_number
2044 * Returns: (transfer full): a #GstH265Picture if successful, or %NULL otherwise
2049 gst_h265_decoder_get_picture (GstH265Decoder * decoder,
2050 guint32 system_frame_number)
2052 return gst_h265_dpb_get_picture (decoder->priv->dpb, system_frame_number);