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.
26 #include "gsth265decoder.h"
28 GST_DEBUG_CATEGORY (gst_h265_decoder_debug);
29 #define GST_CAT_DEFAULT gst_h265_decoder_debug
33 GST_H265_DECODER_FORMAT_NONE,
34 GST_H265_DECODER_FORMAT_HVC1,
35 GST_H265_DECODER_FORMAT_HEV1,
36 GST_H265_DECODER_FORMAT_BYTE
37 } GstH265DecoderFormat;
41 GST_H265_DECODER_ALIGN_NONE,
42 GST_H265_DECODER_ALIGN_NAL,
43 GST_H265_DECODER_ALIGN_AU
44 } GstH265DecoderAlign;
46 struct _GstH265DecoderPrivate
50 /* input codec_data, if any */
51 GstBuffer *codec_data;
52 guint nal_length_size;
55 GstH265DecoderFormat in_format;
56 GstH265DecoderAlign align;
57 GstH265Parser *parser;
59 GstFlowReturn last_ret;
61 /* vps/sps/pps of the current slice */
62 const GstH265VPS *active_vps;
63 const GstH265SPS *active_sps;
64 const GstH265PPS *active_pps;
66 guint32 SpsMaxLatencyPictures;
67 gint32 WpOffsetHalfRangeC;
69 /* Picture currently being processed/decoded */
70 GstH265Picture *current_picture;
71 GstVideoCodecFrame *current_frame;
73 /* Slice (slice header + nalu) currently being processed/decodec */
74 GstH265Slice current_slice;
75 GstH265Slice prev_slice;
76 GstH265Slice prev_independent_slice;
78 gint32 poc; // PicOrderCntVal
79 gint32 poc_msb; // PicOrderCntMsb
80 gint32 poc_lsb; // pic_order_cnt_lsb (from slice_header())
81 gint32 prev_poc_msb; // prevPicOrderCntMsb
82 gint32 prev_poc_lsb; // prevPicOrderCntLsb
83 gint32 prev_tid0pic_poc_lsb;
84 gint32 prev_tid0pic_poc_msb;
85 gint32 PocStCurrBefore[16];
86 gint32 PocStCurrAfter[16];
91 /* PicOrderCount of the previously outputted frame */
94 gboolean associated_irap_NoRaslOutputFlag;
95 gboolean new_bitstream;
96 gboolean prev_nal_is_eos;
99 #define parent_class gst_h265_decoder_parent_class
100 G_DEFINE_ABSTRACT_TYPE_WITH_CODE (GstH265Decoder, gst_h265_decoder,
101 GST_TYPE_VIDEO_DECODER,
102 G_ADD_PRIVATE (GstH265Decoder);
103 GST_DEBUG_CATEGORY_INIT (gst_h265_decoder_debug, "h265decoder", 0,
104 "H.265 Video Decoder"));
106 static gboolean gst_h265_decoder_start (GstVideoDecoder * decoder);
107 static gboolean gst_h265_decoder_stop (GstVideoDecoder * decoder);
108 static gboolean gst_h265_decoder_set_format (GstVideoDecoder * decoder,
109 GstVideoCodecState * state);
110 static GstFlowReturn gst_h265_decoder_finish (GstVideoDecoder * decoder);
111 static gboolean gst_h265_decoder_flush (GstVideoDecoder * decoder);
112 static GstFlowReturn gst_h265_decoder_drain (GstVideoDecoder * decoder);
113 static GstFlowReturn gst_h265_decoder_handle_frame (GstVideoDecoder * decoder,
114 GstVideoCodecFrame * frame);
116 static gboolean gst_h265_decoder_finish_current_picture (GstH265Decoder * self);
117 static void gst_h265_decoder_clear_dpb (GstH265Decoder * self);
119 gst_h265_decoder_output_all_remaining_pics (GstH265Decoder * self);
120 static gboolean gst_h265_decoder_start_current_picture (GstH265Decoder * self);
123 gst_h265_decoder_class_init (GstH265DecoderClass * klass)
125 GstVideoDecoderClass *decoder_class = GST_VIDEO_DECODER_CLASS (klass);
127 decoder_class->start = GST_DEBUG_FUNCPTR (gst_h265_decoder_start);
128 decoder_class->stop = GST_DEBUG_FUNCPTR (gst_h265_decoder_stop);
129 decoder_class->set_format = GST_DEBUG_FUNCPTR (gst_h265_decoder_set_format);
130 decoder_class->finish = GST_DEBUG_FUNCPTR (gst_h265_decoder_finish);
131 decoder_class->flush = GST_DEBUG_FUNCPTR (gst_h265_decoder_flush);
132 decoder_class->drain = GST_DEBUG_FUNCPTR (gst_h265_decoder_drain);
133 decoder_class->handle_frame =
134 GST_DEBUG_FUNCPTR (gst_h265_decoder_handle_frame);
138 gst_h265_decoder_init (GstH265Decoder * self)
140 gst_video_decoder_set_packetized (GST_VIDEO_DECODER (self), TRUE);
142 self->priv = gst_h265_decoder_get_instance_private (self);
146 gst_h265_decoder_start (GstVideoDecoder * decoder)
148 GstH265Decoder *self = GST_H265_DECODER (decoder);
149 GstH265DecoderPrivate *priv = self->priv;
151 priv->parser = gst_h265_parser_new ();
152 priv->dpb = gst_h265_dpb_new ();
153 priv->new_bitstream = TRUE;
154 priv->prev_nal_is_eos = FALSE;
160 gst_h265_decoder_stop (GstVideoDecoder * decoder)
162 GstH265Decoder *self = GST_H265_DECODER (decoder);
163 GstH265DecoderPrivate *priv = self->priv;
165 if (self->input_state) {
166 gst_video_codec_state_unref (self->input_state);
167 self->input_state = NULL;
170 gst_clear_buffer (&priv->codec_data);
173 gst_h265_parser_free (priv->parser);
178 gst_h265_dpb_free (priv->dpb);
186 gst_h265_decoder_parse_vps (GstH265Decoder * self, GstH265NalUnit * nalu)
188 GstH265DecoderPrivate *priv = self->priv;
190 GstH265ParserResult pres;
193 pres = gst_h265_parser_parse_vps (priv->parser, nalu, &vps);
194 if (pres != GST_H265_PARSER_OK) {
195 GST_WARNING_OBJECT (self, "Failed to parse VPS, result %d", pres);
199 GST_LOG_OBJECT (self, "VPS parsed");
205 gst_h265_decoder_process_sps (GstH265Decoder * self, GstH265SPS * sps)
207 GstH265DecoderPrivate *priv = self->priv;
209 gint prev_max_dpb_size;
211 const gint MaxDpbPicBuf = 6;
212 gint PicSizeInSamplesY;
213 guint high_precision_offsets_enabled_flag = 0;
217 MaxLumaPS = 35651584;
218 PicSizeInSamplesY = sps->width * sps->height;
219 if (PicSizeInSamplesY <= (MaxLumaPS >> 2))
220 max_dpb_size = MaxDpbPicBuf * 4;
221 else if (PicSizeInSamplesY <= (MaxLumaPS >> 1))
222 max_dpb_size = MaxDpbPicBuf * 2;
223 else if (PicSizeInSamplesY <= ((3 * MaxLumaPS) >> 2))
224 max_dpb_size = (MaxDpbPicBuf * 4) / 3;
226 max_dpb_size = MaxDpbPicBuf;
228 max_dpb_size = MIN (max_dpb_size, 16);
230 prev_max_dpb_size = gst_h265_dpb_get_max_num_pics (priv->dpb);
231 if (priv->width != sps->width || priv->height != sps->height ||
232 prev_max_dpb_size != max_dpb_size) {
233 GstH265DecoderClass *klass = GST_H265_DECODER_GET_CLASS (self);
235 GST_DEBUG_OBJECT (self,
236 "SPS updated, resolution: %dx%d -> %dx%d, dpb size: %d -> %d",
237 priv->width, priv->height, sps->width, sps->height,
238 prev_max_dpb_size, max_dpb_size);
240 g_assert (klass->new_sequence);
242 if (!klass->new_sequence (self, sps)) {
243 GST_ERROR_OBJECT (self, "subclass does not want accept new sequence");
247 priv->width = sps->width;
248 priv->height = sps->height;
250 gst_h265_dpb_set_max_num_pics (priv->dpb, max_dpb_size);
253 if (sps->max_latency_increase_plus1[sps->max_sub_layers_minus1]) {
254 priv->SpsMaxLatencyPictures =
255 sps->max_num_reorder_pics[sps->max_sub_layers_minus1] +
256 sps->max_latency_increase_plus1[sps->max_sub_layers_minus1] - 1;
259 /* Calculate WpOffsetHalfRangeC: (7-34)
260 * FIXME: We don't have parser API for sps_range_extension, so
261 * assuming high_precision_offsets_enabled_flag as zero */
262 bitdepthC = sps->bit_depth_chroma_minus8 + 8;
263 priv->WpOffsetHalfRangeC =
264 1 << (high_precision_offsets_enabled_flag ? (bitdepthC - 1) : 7);
266 GST_DEBUG_OBJECT (self, "Set DPB max size %d", max_dpb_size);
272 gst_h265_decoder_parse_sps (GstH265Decoder * self, GstH265NalUnit * nalu)
274 GstH265DecoderPrivate *priv = self->priv;
276 GstH265ParserResult pres;
279 pres = gst_h265_parser_parse_sps (priv->parser, nalu, &sps, TRUE);
280 if (pres != GST_H265_PARSER_OK) {
281 GST_WARNING_OBJECT (self, "Failed to parse SPS, result %d", pres);
285 GST_LOG_OBJECT (self, "SPS parsed");
287 if (!gst_h265_decoder_process_sps (self, &sps))
294 gst_h265_decoder_parse_pps (GstH265Decoder * self, GstH265NalUnit * nalu)
296 GstH265DecoderPrivate *priv = self->priv;
298 GstH265ParserResult pres;
300 pres = gst_h265_parser_parse_pps (priv->parser, nalu, &pps);
301 if (pres != GST_H265_PARSER_OK) {
302 GST_WARNING_OBJECT (self, "Failed to parse PPS, result %d", pres);
306 GST_LOG_OBJECT (self, "PPS parsed");
312 gst_h265_decoder_decode_slice (GstH265Decoder * self)
314 GstH265DecoderClass *klass = GST_H265_DECODER_GET_CLASS (self);
315 GstH265DecoderPrivate *priv = self->priv;
316 GstH265Slice *slice = &priv->current_slice;
317 GstH265Picture *picture = priv->current_picture;
320 GST_ERROR_OBJECT (self, "No current picture");
324 g_assert (klass->decode_slice);
326 return klass->decode_slice (self, picture, slice);
330 gst_h265_decoder_preprocess_slice (GstH265Decoder * self, GstH265Slice * slice)
332 GstH265DecoderPrivate *priv = self->priv;
333 const GstH265SliceHdr *slice_hdr = &slice->header;
334 const GstH265NalUnit *nalu = &slice->nalu;
336 if (priv->current_picture && slice_hdr->first_slice_segment_in_pic_flag) {
337 GST_WARNING_OBJECT (self,
338 "Current picture is not finished but slice header has "
339 "first_slice_segment_in_pic_flag");
343 if (IS_IDR (nalu->type)) {
344 GST_DEBUG_OBJECT (self, "IDR nalu, clear dpb");
345 gst_h265_decoder_drain (GST_VIDEO_DECODER (self));
352 gst_h265_decoder_parse_slice (GstH265Decoder * self, GstH265NalUnit * nalu,
355 GstH265DecoderPrivate *priv = self->priv;
356 GstH265ParserResult pres = GST_H265_PARSER_OK;
358 memset (&priv->current_slice, 0, sizeof (GstH265Slice));
360 pres = gst_h265_parser_parse_slice_hdr (priv->parser, nalu,
361 &priv->current_slice.header);
363 if (pres != GST_H265_PARSER_OK) {
364 GST_ERROR_OBJECT (self, "Failed to parse slice header, ret %d", pres);
365 memset (&priv->current_slice, 0, sizeof (GstH265Slice));
370 priv->current_slice.nalu = *nalu;
372 if (!gst_h265_decoder_preprocess_slice (self, &priv->current_slice))
375 priv->active_pps = priv->current_slice.header.pps;
376 priv->active_sps = priv->active_pps->sps;
378 if (!priv->current_picture) {
379 GstH265DecoderClass *klass = GST_H265_DECODER_GET_CLASS (self);
380 GstH265Picture *picture;
383 picture = gst_h265_picture_new ();
386 if (klass->new_picture)
387 ret = klass->new_picture (self, picture);
390 GST_ERROR_OBJECT (self, "subclass does not want accept new picture");
391 gst_h265_picture_unref (picture);
395 priv->current_picture = picture;
396 gst_video_codec_frame_set_user_data (priv->current_frame,
397 gst_h265_picture_ref (priv->current_picture),
398 (GDestroyNotify) gst_h265_picture_unref);
400 if (!gst_h265_decoder_start_current_picture (self)) {
401 GST_ERROR_OBJECT (self, "start picture failed");
405 /* this picture was dropped */
406 if (!priv->current_picture)
410 return gst_h265_decoder_decode_slice (self);
414 gst_h265_decoder_decode_nal (GstH265Decoder * self, GstH265NalUnit * nalu,
417 GstH265DecoderPrivate *priv = self->priv;
420 GST_LOG_OBJECT (self, "Parsed nal type: %d, offset %d, size %d",
421 nalu->type, nalu->offset, nalu->size);
423 switch (nalu->type) {
424 case GST_H265_NAL_VPS:
425 ret = gst_h265_decoder_parse_vps (self, nalu);
427 case GST_H265_NAL_SPS:
428 ret = gst_h265_decoder_parse_sps (self, nalu);
430 case GST_H265_NAL_PPS:
431 ret = gst_h265_decoder_parse_pps (self, nalu);
433 case GST_H265_NAL_SLICE_TRAIL_N:
434 case GST_H265_NAL_SLICE_TRAIL_R:
435 case GST_H265_NAL_SLICE_TSA_N:
436 case GST_H265_NAL_SLICE_TSA_R:
437 case GST_H265_NAL_SLICE_STSA_N:
438 case GST_H265_NAL_SLICE_STSA_R:
439 case GST_H265_NAL_SLICE_RADL_N:
440 case GST_H265_NAL_SLICE_RADL_R:
441 case GST_H265_NAL_SLICE_RASL_N:
442 case GST_H265_NAL_SLICE_RASL_R:
443 case GST_H265_NAL_SLICE_BLA_W_LP:
444 case GST_H265_NAL_SLICE_BLA_W_RADL:
445 case GST_H265_NAL_SLICE_BLA_N_LP:
446 case GST_H265_NAL_SLICE_IDR_W_RADL:
447 case GST_H265_NAL_SLICE_IDR_N_LP:
448 case GST_H265_NAL_SLICE_CRA_NUT:
449 ret = gst_h265_decoder_parse_slice (self, nalu, pts);
450 priv->new_bitstream = FALSE;
451 priv->prev_nal_is_eos = FALSE;
453 case GST_H265_NAL_EOB:
454 gst_h265_decoder_drain (GST_VIDEO_DECODER (self));
455 priv->new_bitstream = TRUE;
457 case GST_H265_NAL_EOS:
458 gst_h265_decoder_drain (GST_VIDEO_DECODER (self));
459 priv->prev_nal_is_eos = TRUE;
469 gst_h265_decoder_format_from_caps (GstH265Decoder * self, GstCaps * caps,
470 GstH265DecoderFormat * format, GstH265DecoderAlign * align)
473 *format = GST_H265_DECODER_FORMAT_NONE;
476 *align = GST_H265_DECODER_ALIGN_NONE;
478 if (!gst_caps_is_fixed (caps)) {
479 GST_WARNING_OBJECT (self, "Caps wasn't fixed");
483 GST_DEBUG_OBJECT (self, "parsing caps: %" GST_PTR_FORMAT, caps);
485 if (caps && gst_caps_get_size (caps) > 0) {
486 GstStructure *s = gst_caps_get_structure (caps, 0);
487 const gchar *str = NULL;
490 if ((str = gst_structure_get_string (s, "stream-format"))) {
491 if (strcmp (str, "hvc1") == 0)
492 *format = GST_H265_DECODER_FORMAT_HVC1;
493 else if (strcmp (str, "hev1") == 0)
494 *format = GST_H265_DECODER_FORMAT_HEV1;
495 else if (strcmp (str, "byte-stream") == 0)
496 *format = GST_H265_DECODER_FORMAT_BYTE;
501 if ((str = gst_structure_get_string (s, "alignment"))) {
502 if (strcmp (str, "au") == 0)
503 *align = GST_H265_DECODER_ALIGN_AU;
504 else if (strcmp (str, "nal") == 0)
505 *align = GST_H265_DECODER_ALIGN_NAL;
512 gst_h265_decoder_parse_codec_data (GstH265Decoder * self, const guint8 * data,
515 GstH265DecoderPrivate *priv = self->priv;
516 guint num_nal_arrays;
518 guint num_nals, i, j;
519 GstH265ParserResult pres;
522 /* parse the hvcC data */
524 GST_WARNING_OBJECT (self, "hvcC too small");
528 /* wrong hvcC version */
529 if (data[0] != 0 && data[0] != 1) {
533 priv->nal_length_size = (data[21] & 0x03) + 1;
534 GST_DEBUG_OBJECT (self, "nal length size %u", priv->nal_length_size);
536 num_nal_arrays = data[22];
539 for (i = 0; i < num_nal_arrays; i++) {
540 if (off + 3 >= size) {
541 GST_WARNING_OBJECT (self, "hvcC too small");
545 num_nals = GST_READ_UINT16_BE (data + off + 1);
547 for (j = 0; j < num_nals; j++) {
548 pres = gst_h265_parser_identify_nalu_hevc (priv->parser,
549 data, off, size, 2, &nalu);
551 if (pres != GST_H265_PARSER_OK) {
552 GST_WARNING_OBJECT (self, "hvcC too small");
557 case GST_H265_NAL_VPS:
558 gst_h265_decoder_parse_vps (self, &nalu);
560 case GST_H265_NAL_SPS:
561 gst_h265_decoder_parse_sps (self, &nalu);
563 case GST_H265_NAL_PPS:
564 gst_h265_decoder_parse_pps (self, &nalu);
570 off = nalu.offset + nalu.size;
578 gst_h265_decoder_set_format (GstVideoDecoder * decoder,
579 GstVideoCodecState * state)
581 GstH265Decoder *self = GST_H265_DECODER (decoder);
582 GstH265DecoderPrivate *priv = self->priv;
584 GST_DEBUG_OBJECT (decoder, "Set format");
586 if (self->input_state)
587 gst_video_codec_state_unref (self->input_state);
589 self->input_state = gst_video_codec_state_ref (state);
593 const GValue *codec_data_value;
594 GstH265DecoderFormat format;
595 GstH265DecoderAlign align;
597 gst_h265_decoder_format_from_caps (self, state->caps, &format, &align);
599 str = gst_caps_get_structure (state->caps, 0);
600 codec_data_value = gst_structure_get_value (str, "codec_data");
602 if (GST_VALUE_HOLDS_BUFFER (codec_data_value)) {
603 gst_buffer_replace (&priv->codec_data,
604 gst_value_get_buffer (codec_data_value));
606 gst_buffer_replace (&priv->codec_data, NULL);
609 if (format == GST_H265_DECODER_FORMAT_NONE) {
610 /* codec_data implies packetized */
611 if (codec_data_value != NULL) {
612 GST_WARNING_OBJECT (self,
613 "video/x-h265 caps with codec_data but no stream-format=hev1 or hvc1");
614 format = GST_H265_DECODER_FORMAT_HEV1;
616 /* otherwise assume bytestream input */
617 GST_WARNING_OBJECT (self,
618 "video/x-h265 caps without codec_data or stream-format");
619 format = GST_H265_DECODER_FORMAT_BYTE;
623 if (format == GST_H265_DECODER_FORMAT_HEV1 ||
624 format == GST_H265_DECODER_FORMAT_HVC1) {
625 if (codec_data_value == NULL) {
626 /* Try it with size 4 anyway */
627 priv->nal_length_size = 4;
628 GST_WARNING_OBJECT (self,
629 "packetized format without codec data, assuming nal length size is 4");
632 /* AVC implies alignment=au */
633 if (align == GST_H265_DECODER_ALIGN_NONE)
634 align = GST_H265_DECODER_ALIGN_AU;
637 if (format == GST_H265_DECODER_FORMAT_BYTE) {
638 if (codec_data_value != NULL) {
639 GST_WARNING_OBJECT (self, "bytestream with codec data");
643 priv->in_format = format;
647 if (priv->codec_data) {
650 gst_buffer_map (priv->codec_data, &map, GST_MAP_READ);
651 gst_h265_decoder_parse_codec_data (self, map.data, map.size);
652 gst_buffer_unmap (priv->codec_data, &map);
659 gst_h265_decoder_flush (GstVideoDecoder * decoder)
661 GstH265Decoder *self = GST_H265_DECODER (decoder);
663 gst_h265_decoder_clear_dpb (self);
669 gst_h265_decoder_drain (GstVideoDecoder * decoder)
671 GstH265Decoder *self = GST_H265_DECODER (decoder);
672 GstH265DecoderPrivate *priv = self->priv;
674 priv->last_ret = GST_FLOW_OK;
675 gst_h265_decoder_output_all_remaining_pics (self);
676 gst_h265_decoder_clear_dpb (self);
678 return priv->last_ret;
682 gst_h265_decoder_finish (GstVideoDecoder * decoder)
684 return gst_h265_decoder_drain (decoder);
688 gst_h265_decoder_fill_picture_from_slice (GstH265Decoder * self,
689 const GstH265Slice * slice, GstH265Picture * picture)
691 GstH265DecoderPrivate *priv = self->priv;
692 const GstH265SliceHdr *slice_hdr = &slice->header;
693 const GstH265NalUnit *nalu = &slice->nalu;
695 if (nalu->type >= GST_H265_NAL_SLICE_BLA_W_LP &&
696 nalu->type <= GST_H265_NAL_SLICE_CRA_NUT)
697 picture->RapPicFlag = TRUE;
699 /* FIXME: Use SEI header values */
700 picture->field = GST_H265_PICTURE_FIELD_FRAME;
702 /* NoRaslOutputFlag == 1 if the current picture is
705 * 3) a CRA picture that is the first access unit in the bitstream
706 * 4) first picture that follows an end of sequence NAL unit in decoding order
707 * 5) has HandleCraAsBlaFlag == 1 (set by external means, so not considering )
709 if (IS_IDR (nalu->type) || IS_BLA (nalu->type) ||
710 (IS_CRA (nalu->type) && priv->new_bitstream) || priv->prev_nal_is_eos) {
711 picture->NoRaslOutputFlag = TRUE;
714 if (IS_IRAP (nalu->type)) {
715 picture->IntraPicFlag = TRUE;
716 priv->associated_irap_NoRaslOutputFlag = picture->NoRaslOutputFlag;
719 if (IS_RASL (nalu->type) && priv->associated_irap_NoRaslOutputFlag) {
720 picture->output_flag = FALSE;
722 picture->output_flag = slice_hdr->pic_output_flag;
728 #define RSV_VCL_N10 10
729 #define RSV_VCL_N12 12
730 #define RSV_VCL_N14 14
733 nal_is_ref (guint8 nal_type)
735 gboolean ret = FALSE;
737 case GST_H265_NAL_SLICE_TRAIL_N:
738 case GST_H265_NAL_SLICE_TSA_N:
739 case GST_H265_NAL_SLICE_STSA_N:
740 case GST_H265_NAL_SLICE_RADL_N:
741 case GST_H265_NAL_SLICE_RASL_N:
755 gst_h265_decoder_calculate_poc (GstH265Decoder * self,
756 const GstH265Slice * slice, GstH265Picture * picture)
758 GstH265DecoderPrivate *priv = self->priv;
759 const GstH265SliceHdr *slice_hdr = &slice->header;
760 const GstH265NalUnit *nalu = &slice->nalu;
761 const GstH265SPS *sps = priv->active_sps;
762 gint32 MaxPicOrderCntLsb = 1 << (sps->log2_max_pic_order_cnt_lsb_minus4 + 4);
764 GST_DEBUG_OBJECT (self, "decode PicOrderCntVal");
766 priv->prev_poc_lsb = priv->poc_lsb;
767 priv->prev_poc_msb = priv->poc_msb;
769 if (!(IS_IRAP (nalu->type) && picture->NoRaslOutputFlag)) {
770 priv->prev_poc_lsb = priv->prev_tid0pic_poc_lsb;
771 priv->prev_poc_msb = priv->prev_tid0pic_poc_msb;
774 /* Finding PicOrderCntMsb */
775 if (IS_IRAP (nalu->type) && picture->NoRaslOutputFlag)
779 if ((slice_hdr->pic_order_cnt_lsb < priv->prev_poc_lsb) &&
780 ((priv->prev_poc_lsb - slice_hdr->pic_order_cnt_lsb) >=
781 (MaxPicOrderCntLsb / 2)))
782 priv->poc_msb = priv->prev_poc_msb + MaxPicOrderCntLsb;
784 else if ((slice_hdr->pic_order_cnt_lsb > priv->prev_poc_lsb) &&
785 ((slice_hdr->pic_order_cnt_lsb - priv->prev_poc_lsb) >
786 (MaxPicOrderCntLsb / 2)))
787 priv->poc_msb = priv->prev_poc_msb - MaxPicOrderCntLsb;
790 priv->poc_msb = priv->prev_poc_msb;
794 priv->poc = picture->pic_order_cnt =
795 priv->poc_msb + slice_hdr->pic_order_cnt_lsb;
796 priv->poc_lsb = picture->pic_order_cnt_lsb = slice_hdr->pic_order_cnt_lsb;
798 if (IS_IDR (nalu->type)) {
799 picture->pic_order_cnt = 0;
800 picture->pic_order_cnt_lsb = 0;
803 priv->prev_poc_lsb = 0;
804 priv->prev_poc_msb = 0;
805 priv->prev_tid0pic_poc_lsb = 0;
806 priv->prev_tid0pic_poc_msb = 0;
809 GST_DEBUG_OBJECT (self,
810 "PicOrderCntVal %d, (lsb %d)", picture->pic_order_cnt,
811 picture->pic_order_cnt_lsb);
813 if (nalu->temporal_id_plus1 == 1 && !IS_RASL (nalu->type) &&
814 !IS_RADL (nalu->type) && nal_is_ref (nalu->type)) {
815 priv->prev_tid0pic_poc_lsb = slice_hdr->pic_order_cnt_lsb;
816 priv->prev_tid0pic_poc_msb = priv->poc_msb;
823 gst_h265_decoder_init_current_picture (GstH265Decoder * self)
825 GstH265DecoderPrivate *priv = self->priv;
827 if (!gst_h265_decoder_fill_picture_from_slice (self, &priv->current_slice,
828 priv->current_picture)) {
832 if (!gst_h265_decoder_calculate_poc (self,
833 &priv->current_slice, priv->current_picture))
840 has_entry_in_rps (GstH265Picture * dpb_pic,
841 GstH265Picture ** rps_list, guint rps_list_length)
845 if (!dpb_pic || !rps_list || !rps_list_length)
848 for (i = 0; i < rps_list_length; i++) {
849 if (rps_list[i] && rps_list[i]->pic_order_cnt == dpb_pic->pic_order_cnt)
856 gst_h265_decoder_derive_and_mark_rps (GstH265Decoder * self,
857 GstH265Picture * picture, gint32 * CurrDeltaPocMsbPresentFlag,
858 gint32 * FollDeltaPocMsbPresentFlag)
860 GstH265DecoderPrivate *priv = self->priv;
864 for (i = 0; i < 16; i++) {
865 gst_h265_picture_replace (&self->RefPicSetLtCurr[i], NULL);
866 gst_h265_picture_replace (&self->RefPicSetLtFoll[i], NULL);
867 gst_h265_picture_replace (&self->RefPicSetStCurrBefore[i], NULL);
868 gst_h265_picture_replace (&self->RefPicSetStCurrAfter[i], NULL);
869 gst_h265_picture_replace (&self->RefPicSetStFoll[i], NULL);
873 for (i = 0; i < self->NumPocLtCurr; i++) {
874 if (!CurrDeltaPocMsbPresentFlag[i]) {
875 self->RefPicSetLtCurr[i] =
876 gst_h265_dpb_get_ref_by_poc_lsb (priv->dpb, priv->PocLtCurr[i]);
878 self->RefPicSetLtCurr[i] =
879 gst_h265_dpb_get_ref_by_poc (priv->dpb, priv->PocLtCurr[i]);
883 for (i = 0; i < self->NumPocLtFoll; i++) {
884 if (!FollDeltaPocMsbPresentFlag[i]) {
885 self->RefPicSetLtFoll[i] =
886 gst_h265_dpb_get_ref_by_poc_lsb (priv->dpb, priv->PocLtFoll[i]);
888 self->RefPicSetLtFoll[i] =
889 gst_h265_dpb_get_ref_by_poc (priv->dpb, priv->PocLtFoll[i]);
893 /* Mark all ref pics in RefPicSetLtCurr and RefPicSetLtFol as long_term_refs */
894 for (i = 0; i < self->NumPocLtCurr; i++) {
895 if (self->RefPicSetLtCurr[i]) {
896 self->RefPicSetLtCurr[i]->ref = TRUE;
897 self->RefPicSetLtCurr[i]->long_term = TRUE;
901 for (i = 0; i < self->NumPocLtFoll; i++) {
902 if (self->RefPicSetLtFoll[i]) {
903 self->RefPicSetLtFoll[i]->ref = TRUE;
904 self->RefPicSetLtFoll[i]->long_term = TRUE;
909 for (i = 0; i < self->NumPocStCurrBefore; i++) {
910 self->RefPicSetStCurrBefore[i] =
911 gst_h265_dpb_get_short_ref_by_poc (priv->dpb, priv->PocStCurrBefore[i]);
914 for (i = 0; i < self->NumPocStCurrAfter; i++) {
915 self->RefPicSetStCurrAfter[i] =
916 gst_h265_dpb_get_short_ref_by_poc (priv->dpb, priv->PocStCurrAfter[i]);
919 for (i = 0; i < self->NumPocStFoll; i++) {
920 self->RefPicSetStFoll[i] =
921 gst_h265_dpb_get_short_ref_by_poc (priv->dpb, priv->PocStFoll[i]);
924 /* Mark all dpb pics not beloging to RefPicSet*[] as unused for ref */
925 dpb_array = gst_h265_dpb_get_pictures_all (priv->dpb);
926 for (i = 0; i < dpb_array->len; i++) {
927 GstH265Picture *dpb_pic = g_array_index (dpb_array, GstH265Picture *, i);
930 !has_entry_in_rps (dpb_pic, self->RefPicSetLtCurr, self->NumPocLtCurr)
931 && !has_entry_in_rps (dpb_pic, self->RefPicSetLtFoll,
933 && !has_entry_in_rps (dpb_pic, self->RefPicSetStCurrAfter,
934 self->NumPocStCurrAfter)
935 && !has_entry_in_rps (dpb_pic, self->RefPicSetStCurrBefore,
936 self->NumPocStCurrBefore)
937 && !has_entry_in_rps (dpb_pic, self->RefPicSetStFoll,
938 self->NumPocStFoll)) {
939 GST_LOG_OBJECT (self, "Mark Picture %p (poc %d) as non-ref", dpb_pic,
940 dpb_pic->pic_order_cnt);
941 dpb_pic->ref = FALSE;
942 dpb_pic->long_term = FALSE;
946 g_array_unref (dpb_array);
950 gst_h265_decoder_prepare_rps (GstH265Decoder * self, const GstH265Slice * slice,
951 GstH265Picture * picture)
953 GstH265DecoderPrivate *priv = self->priv;
954 gint32 CurrDeltaPocMsbPresentFlag[16] = { 0, };
955 gint32 FollDeltaPocMsbPresentFlag[16] = { 0, };
956 const GstH265SliceHdr *slice_hdr = &slice->header;
957 const GstH265NalUnit *nalu = &slice->nalu;
958 const GstH265SPS *sps = priv->active_sps;
959 guint32 MaxPicOrderCntLsb = 1 << (sps->log2_max_pic_order_cnt_lsb_minus4 + 4);
962 /* if it is an irap pic, set all ref pics in dpb as unused for ref */
963 if (IS_IRAP (nalu->type) && picture->NoRaslOutputFlag) {
964 GST_DEBUG_OBJECT (self, "Mark all pictures in DPB as non-ref");
965 gst_h265_dpb_mark_all_non_ref (priv->dpb);
968 /* Reset everything for IDR */
969 if (IS_IDR (nalu->type)) {
970 memset (priv->PocStCurrBefore, 0, sizeof (priv->PocStCurrBefore));
971 memset (priv->PocStCurrAfter, 0, sizeof (priv->PocStCurrAfter));
972 memset (priv->PocStFoll, 0, sizeof (priv->PocStFoll));
973 memset (priv->PocLtCurr, 0, sizeof (priv->PocLtCurr));
974 memset (priv->PocLtFoll, 0, sizeof (priv->PocLtFoll));
975 self->NumPocStCurrBefore = self->NumPocStCurrAfter = self->NumPocStFoll = 0;
976 self->NumPocLtCurr = self->NumPocLtFoll = 0;
978 const GstH265ShortTermRefPicSet *stRefPic = NULL;
979 gint32 num_lt_pics, pocLt;
980 gint32 PocLsbLt[16] = { 0, };
981 gint32 UsedByCurrPicLt[16] = { 0, };
982 gint32 DeltaPocMsbCycleLt[16] = { 0, };
983 gint numtotalcurr = 0;
985 /* this is based on CurrRpsIdx described in spec */
986 if (!slice_hdr->short_term_ref_pic_set_sps_flag)
987 stRefPic = &slice_hdr->short_term_ref_pic_sets;
988 else if (sps->num_short_term_ref_pic_sets)
990 &sps->short_term_ref_pic_set[slice_hdr->short_term_ref_pic_set_idx];
992 g_assert (stRefPic != NULL);
994 GST_LOG_OBJECT (self,
995 "NumDeltaPocs: %d, NumNegativePics: %d, NumPositivePics %d",
996 stRefPic->NumDeltaPocs, stRefPic->NumNegativePics,
997 stRefPic->NumPositivePics);
999 for (i = 0, j = 0, k = 0; i < stRefPic->NumNegativePics; i++) {
1000 if (stRefPic->UsedByCurrPicS0[i]) {
1001 priv->PocStCurrBefore[j++] =
1002 picture->pic_order_cnt + stRefPic->DeltaPocS0[i];
1005 priv->PocStFoll[k++] = picture->pic_order_cnt + stRefPic->DeltaPocS0[i];
1007 self->NumPocStCurrBefore = j;
1008 for (i = 0, j = 0; i < stRefPic->NumPositivePics; i++) {
1009 if (stRefPic->UsedByCurrPicS1[i]) {
1010 priv->PocStCurrAfter[j++] =
1011 picture->pic_order_cnt + stRefPic->DeltaPocS1[i];
1014 priv->PocStFoll[k++] = picture->pic_order_cnt + stRefPic->DeltaPocS1[i];
1016 self->NumPocStCurrAfter = j;
1017 self->NumPocStFoll = k;
1018 num_lt_pics = slice_hdr->num_long_term_sps + slice_hdr->num_long_term_pics;
1019 /* The variables PocLsbLt[i] and UsedByCurrPicLt[i] are derived as follows: */
1020 for (i = 0; i < num_lt_pics; i++) {
1021 if (i < slice_hdr->num_long_term_sps) {
1022 PocLsbLt[i] = sps->lt_ref_pic_poc_lsb_sps[slice_hdr->lt_idx_sps[i]];
1023 UsedByCurrPicLt[i] =
1024 sps->used_by_curr_pic_lt_sps_flag[slice_hdr->lt_idx_sps[i]];
1026 PocLsbLt[i] = slice_hdr->poc_lsb_lt[i];
1027 UsedByCurrPicLt[i] = slice_hdr->used_by_curr_pic_lt_flag[i];
1029 if (UsedByCurrPicLt[i])
1033 self->NumPocTotalCurr = numtotalcurr;
1035 /* The variable DeltaPocMsbCycleLt[i] is derived as follows: (7-38) */
1036 for (i = 0; i < num_lt_pics; i++) {
1037 if (i == 0 || i == slice_hdr->num_long_term_sps)
1038 DeltaPocMsbCycleLt[i] = slice_hdr->delta_poc_msb_cycle_lt[i];
1040 DeltaPocMsbCycleLt[i] =
1041 slice_hdr->delta_poc_msb_cycle_lt[i] + DeltaPocMsbCycleLt[i - 1];
1045 for (i = 0, j = 0, k = 0; i < num_lt_pics; i++) {
1046 pocLt = PocLsbLt[i];
1047 if (slice_hdr->delta_poc_msb_present_flag[i])
1049 picture->pic_order_cnt - DeltaPocMsbCycleLt[i] * MaxPicOrderCntLsb -
1050 slice_hdr->pic_order_cnt_lsb;
1051 if (UsedByCurrPicLt[i]) {
1052 priv->PocLtCurr[j] = pocLt;
1053 CurrDeltaPocMsbPresentFlag[j++] =
1054 slice_hdr->delta_poc_msb_present_flag[i];
1056 priv->PocLtFoll[k] = pocLt;
1057 FollDeltaPocMsbPresentFlag[k++] =
1058 slice_hdr->delta_poc_msb_present_flag[i];
1061 self->NumPocLtCurr = j;
1062 self->NumPocLtFoll = k;
1065 GST_LOG_OBJECT (self, "NumPocStCurrBefore: %d", self->NumPocStCurrBefore);
1066 GST_LOG_OBJECT (self, "NumPocStCurrAfter: %d", self->NumPocStCurrAfter);
1067 GST_LOG_OBJECT (self, "NumPocStFoll: %d", self->NumPocStFoll);
1068 GST_LOG_OBJECT (self, "NumPocLtCurr: %d", self->NumPocLtCurr);
1069 GST_LOG_OBJECT (self, "NumPocLtFoll: %d", self->NumPocLtFoll);
1070 GST_LOG_OBJECT (self, "NumPocTotalCurr: %d", self->NumPocTotalCurr);
1072 /* the derivation process for the RPS and the picture marking */
1073 gst_h265_decoder_derive_and_mark_rps (self, picture,
1074 CurrDeltaPocMsbPresentFlag, FollDeltaPocMsbPresentFlag);
1080 gst_h265_decoder_clear_dpb (GstH265Decoder * self)
1082 GstH265DecoderPrivate *priv = self->priv;
1084 gst_h265_dpb_clear (priv->dpb);
1085 priv->last_output_poc = -1;
1089 gst_h265_decoder_do_output_picture (GstH265Decoder * self,
1090 GstH265Picture * picture)
1092 GstH265DecoderPrivate *priv = self->priv;
1093 GstH265DecoderClass *klass;
1095 picture->outputted = TRUE;
1097 if (picture->pic_order_cnt < priv->last_output_poc) {
1098 GST_WARNING_OBJECT (self,
1099 "Outputting out of order %d -> %d, likely a broken stream",
1100 priv->last_output_poc, picture->pic_order_cnt);
1103 priv->last_output_poc = picture->pic_order_cnt;
1105 klass = GST_H265_DECODER_GET_CLASS (self);
1107 if (klass->output_picture)
1108 priv->last_ret = klass->output_picture (self, picture);
1112 poc_asc_compare (const GstH265Picture * a, const GstH265Picture * b)
1114 return a->pic_order_cnt > b->pic_order_cnt;
1118 gst_h265_decoder_output_all_remaining_pics (GstH265Decoder * self)
1120 GstH265DecoderPrivate *priv = self->priv;
1121 GList *to_output = NULL;
1124 gst_h265_dpb_get_pictures_not_outputted (priv->dpb, &to_output);
1126 to_output = g_list_sort (to_output, (GCompareFunc) poc_asc_compare);
1128 for (iter = to_output; iter; iter = g_list_next (iter)) {
1129 GstH265Picture *picture = (GstH265Picture *) iter->data;
1131 GST_LOG_OBJECT (self, "Output picture %p (poc %d)", picture,
1132 picture->pic_order_cnt);
1133 gst_h265_decoder_do_output_picture (self, picture);
1137 g_list_free_full (to_output, (GDestroyNotify) gst_h265_picture_unref);
1144 gst_h265_decoder_dpb_init (GstH265Decoder * self, const GstH265Slice * slice,
1145 GstH265Picture * picture)
1147 GstH265DecoderPrivate *priv = self->priv;
1148 const GstH265SliceHdr *slice_hdr = &slice->header;
1149 const GstH265NalUnit *nalu = &slice->nalu;
1151 if (IS_IRAP (nalu->type) && picture->NoRaslOutputFlag && !priv->new_bitstream) {
1152 if (nalu->type == GST_H265_NAL_SLICE_CRA_NUT)
1153 picture->NoOutputOfPriorPicsFlag = TRUE;
1155 picture->NoOutputOfPriorPicsFlag =
1156 slice_hdr->no_output_of_prior_pics_flag;
1158 if (picture->NoOutputOfPriorPicsFlag) {
1159 GST_DEBUG_OBJECT (self, "Clear dpb");
1160 gst_h265_decoder_drain (GST_VIDEO_DECODER (self));
1168 gst_h265_decoder_start_current_picture (GstH265Decoder * self)
1170 GstH265DecoderClass *klass;
1171 GstH265DecoderPrivate *priv = self->priv;
1172 gboolean ret = TRUE;
1174 g_assert (priv->current_picture != NULL);
1175 g_assert (priv->active_sps != NULL);
1176 g_assert (priv->active_pps != NULL);
1178 if (!gst_h265_decoder_init_current_picture (self))
1181 /* Drop all RASL pictures having NoRaslOutputFlag is TRUE for the
1182 * associated IRAP picture */
1183 if (IS_RASL (priv->current_slice.nalu.type) &&
1184 priv->associated_irap_NoRaslOutputFlag) {
1185 GST_DEBUG_OBJECT (self, "Drop current picture");
1186 gst_h265_picture_replace (&priv->current_picture, NULL);
1190 gst_h265_decoder_prepare_rps (self, &priv->current_slice,
1191 priv->current_picture);
1193 gst_h265_decoder_dpb_init (self, &priv->current_slice, priv->current_picture);
1195 klass = GST_H265_DECODER_GET_CLASS (self);
1196 if (klass->start_picture)
1197 ret = klass->start_picture (self, priv->current_picture,
1198 &priv->current_slice, priv->dpb);
1201 GST_ERROR_OBJECT (self, "subclass does not want to start picture");
1209 gst_h265_decoder_finish_picture (GstH265Decoder * self,
1210 GstH265Picture * picture)
1212 GstH265DecoderPrivate *priv = self->priv;
1213 const GstH265SPS *sps = priv->active_sps;
1214 GList *not_outputted = NULL;
1215 guint num_remaining;
1217 #ifndef GST_DISABLE_GST_DEBUG
1221 /* Remove unused (for reference or later output) pictures from DPB, marking
1223 gst_h265_dpb_delete_unused (priv->dpb);
1225 GST_LOG_OBJECT (self,
1226 "Finishing picture %p (poc %d), entries in DPB %d",
1227 picture, picture->pic_order_cnt, gst_h265_dpb_get_size (priv->dpb));
1229 /* The ownership of pic will either be transferred to DPB - if the picture is
1230 * still needed (for output and/or reference) - or we will release it
1231 * immediately if we manage to output it here and won't have to store it for
1232 * future reference */
1234 /* Get all pictures that haven't been outputted yet */
1235 gst_h265_dpb_get_pictures_not_outputted (priv->dpb, ¬_outputted);
1238 for (iter = not_outputted; iter; iter = g_list_next (iter)) {
1239 GstH265Picture *other = GST_H265_PICTURE (iter->data);
1241 if (!other->outputted)
1242 other->pic_latency_cnt++;
1245 if (picture->output_flag) {
1246 picture->outputted = FALSE;
1247 picture->pic_latency_cnt = 0;
1249 picture->outputted = TRUE;
1252 /* set pic as short_term_ref */
1253 picture->ref = TRUE;
1254 picture->long_term = FALSE;
1256 /* Include the one we've just decoded */
1257 not_outputted = g_list_append (not_outputted, picture);
1260 #ifndef GST_DISABLE_GST_DEBUG
1261 GST_TRACE_OBJECT (self, "Before sorting not outputted list");
1263 for (iter = not_outputted; iter; iter = g_list_next (iter)) {
1264 GstH265Picture *tmp = (GstH265Picture *) iter->data;
1266 GST_TRACE_OBJECT (self,
1267 "\t%dth picture %p (poc %d)", i, tmp, tmp->pic_order_cnt);
1272 /* Sort in output order */
1273 not_outputted = g_list_sort (not_outputted, (GCompareFunc) poc_asc_compare);
1275 #ifndef GST_DISABLE_GST_DEBUG
1276 GST_TRACE_OBJECT (self,
1277 "After sorting not outputted list in poc ascending order");
1279 for (iter = not_outputted; iter; iter = g_list_next (iter)) {
1280 GstH265Picture *tmp = (GstH265Picture *) iter->data;
1282 GST_TRACE_OBJECT (self,
1283 "\t%dth picture %p (poc %d)", i, tmp, tmp->pic_order_cnt);
1288 /* Try to output as many pictures as we can. A picture can be output,
1289 * if the number of decoded and not yet outputted pictures that would remain
1290 * in DPB afterwards would at least be equal to max_num_reorder_frames.
1291 * If the outputted picture is not a reference picture, it doesn't have
1292 * to remain in the DPB and can be removed */
1293 iter = not_outputted;
1294 num_remaining = g_list_length (not_outputted);
1296 while (num_remaining > sps->max_num_reorder_pics[sps->max_sub_layers_minus1]
1297 || (num_remaining &&
1298 sps->max_latency_increase_plus1[sps->max_sub_layers_minus1] &&
1299 !GST_H265_PICTURE (iter->data)->outputted &&
1300 GST_H265_PICTURE (iter->data)->pic_latency_cnt >=
1301 priv->SpsMaxLatencyPictures)) {
1302 GstH265Picture *to_output = GST_H265_PICTURE (iter->data);
1304 GST_LOG_OBJECT (self,
1305 "Output picture %p (poc %d)", to_output, to_output->pic_order_cnt);
1306 gst_h265_decoder_do_output_picture (self, to_output);
1307 if (!to_output->ref) {
1308 /* Current picture hasn't been inserted into DPB yet, so don't remove it
1309 * if we managed to output it immediately */
1310 gint outputted_poc = to_output->pic_order_cnt;
1311 if (outputted_poc != picture->pic_order_cnt) {
1312 GST_LOG_OBJECT (self, "Delete picture %p (poc %d) from DPB",
1313 to_output, to_output->pic_order_cnt);
1314 gst_h265_dpb_delete_by_poc (priv->dpb, outputted_poc);
1318 iter = g_list_next (iter);
1322 /* If we haven't managed to output the picture that we just decoded, or if
1323 * it's a reference picture, we have to store it in DPB */
1324 if (!picture->outputted || picture->ref) {
1325 if (gst_h265_dpb_is_full (priv->dpb)) {
1326 /* If we haven't managed to output anything to free up space in DPB
1327 * to store this picture, it's an error in the stream */
1328 GST_WARNING_OBJECT (self, "Could not free up space in DPB");
1332 GST_TRACE_OBJECT (self,
1333 "Put picture %p (outputted %d, ref %d, poc %d) to dpb",
1334 picture, picture->outputted, picture->ref, picture->pic_order_cnt);
1335 gst_h265_dpb_add (priv->dpb, gst_h265_picture_ref (picture));
1339 g_list_free_full (not_outputted, (GDestroyNotify) gst_h265_picture_unref);
1345 gst_h265_decoder_finish_current_picture (GstH265Decoder * self)
1347 GstH265DecoderPrivate *priv = self->priv;
1348 GstH265DecoderClass *klass;
1349 gboolean ret = TRUE;
1351 if (!priv->current_picture)
1354 klass = GST_H265_DECODER_GET_CLASS (self);
1356 if (klass->end_picture)
1357 ret = klass->end_picture (self, priv->current_picture);
1359 /* finish picture takes ownership of the picture */
1360 ret = gst_h265_decoder_finish_picture (self, priv->current_picture);
1361 priv->current_picture = NULL;
1364 GST_ERROR_OBJECT (self, "Failed to finish picture");
1371 static GstFlowReturn
1372 gst_h265_decoder_handle_frame (GstVideoDecoder * decoder,
1373 GstVideoCodecFrame * frame)
1375 GstH265Decoder *self = GST_H265_DECODER (decoder);
1376 GstH265DecoderPrivate *priv = self->priv;
1377 GstBuffer *in_buf = frame->input_buffer;
1378 GstH265NalUnit nalu;
1379 GstH265ParserResult pres;
1381 gboolean decode_ret = TRUE;
1383 GST_LOG_OBJECT (self,
1384 "handle frame, PTS: %" GST_TIME_FORMAT ", DTS: %"
1385 GST_TIME_FORMAT, GST_TIME_ARGS (GST_BUFFER_PTS (in_buf)),
1386 GST_TIME_ARGS (GST_BUFFER_DTS (in_buf)));
1388 priv->current_frame = frame;
1389 priv->last_ret = GST_FLOW_OK;
1391 gst_buffer_map (in_buf, &map, GST_MAP_READ);
1392 if (priv->in_format == GST_H265_DECODER_FORMAT_HVC1 ||
1393 priv->in_format == GST_H265_DECODER_FORMAT_HEV1) {
1394 pres = gst_h265_parser_identify_nalu_hevc (priv->parser,
1395 map.data, 0, map.size, priv->nal_length_size, &nalu);
1397 while (pres == GST_H265_PARSER_OK && decode_ret) {
1398 decode_ret = gst_h265_decoder_decode_nal (self,
1399 &nalu, GST_BUFFER_PTS (in_buf));
1401 pres = gst_h265_parser_identify_nalu_hevc (priv->parser,
1402 map.data, nalu.offset + nalu.size, map.size, priv->nal_length_size,
1406 pres = gst_h265_parser_identify_nalu (priv->parser,
1407 map.data, 0, map.size, &nalu);
1409 if (pres == GST_H265_PARSER_NO_NAL_END)
1410 pres = GST_H265_PARSER_OK;
1412 while (pres == GST_H265_PARSER_OK && decode_ret) {
1413 decode_ret = gst_h265_decoder_decode_nal (self,
1414 &nalu, GST_BUFFER_PTS (in_buf));
1416 pres = gst_h265_parser_identify_nalu (priv->parser,
1417 map.data, nalu.offset + nalu.size, map.size, &nalu);
1419 if (pres == GST_H265_PARSER_NO_NAL_END)
1420 pres = GST_H265_PARSER_OK;
1424 gst_buffer_unmap (in_buf, &map);
1425 priv->current_frame = NULL;
1428 GST_VIDEO_DECODER_ERROR (self, 1, STREAM, DECODE,
1429 ("Failed to decode data"), (NULL), priv->last_ret);
1430 gst_video_decoder_drop_frame (decoder, frame);
1432 gst_h265_picture_clear (&priv->current_picture);
1434 return priv->last_ret;
1437 gst_h265_decoder_finish_current_picture (self);
1438 gst_video_codec_frame_unref (frame);
1440 return priv->last_ret;