codecs: h265decoder: Use GstFlowReturn everywhere

boolean return value is not sufficient for representing the reason
of error in most cases. For instance, any errors around new_sequence()
would mean negotiation error, not just *ERROR*.
And some subclasses will allocate buffer/memory/surface on new_picture()
but it could be failed because of expected error, likely flushing

Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/1019>
This commit is contained in:
Seungha Yang 2021-09-21 00:23:13 +09:00 committed by Nicolas Dufresne
parent 05496df0d1
commit 5b405d1585
5 changed files with 229 additions and 189 deletions

View file

@ -69,7 +69,6 @@ struct _GstH265DecoderPrivate
GstH265DecoderAlign align; GstH265DecoderAlign align;
GstH265Parser *parser; GstH265Parser *parser;
GstH265Dpb *dpb; GstH265Dpb *dpb;
GstFlowReturn last_ret;
/* 0: frame or field-pair interlaced stream /* 0: frame or field-pair interlaced stream
* 1: alternating, single field interlaced stream. * 1: alternating, single field interlaced stream.
@ -126,6 +125,11 @@ struct _GstH265DecoderPrivate
GArray *ref_pic_list1; GArray *ref_pic_list1;
}; };
#define UPDATE_FLOW_RETURN(ret,new_ret) G_STMT_START { \
if (*(ret) == GST_FLOW_OK) \
*(ret) = new_ret; \
} G_STMT_END
#define parent_class gst_h265_decoder_parent_class #define parent_class gst_h265_decoder_parent_class
G_DEFINE_ABSTRACT_TYPE_WITH_CODE (GstH265Decoder, gst_h265_decoder, G_DEFINE_ABSTRACT_TYPE_WITH_CODE (GstH265Decoder, gst_h265_decoder,
GST_TYPE_VIDEO_DECODER, GST_TYPE_VIDEO_DECODER,
@ -145,11 +149,13 @@ static GstFlowReturn gst_h265_decoder_drain (GstVideoDecoder * decoder);
static GstFlowReturn gst_h265_decoder_handle_frame (GstVideoDecoder * decoder, static GstFlowReturn gst_h265_decoder_handle_frame (GstVideoDecoder * decoder,
GstVideoCodecFrame * frame); GstVideoCodecFrame * frame);
static gboolean gst_h265_decoder_finish_current_picture (GstH265Decoder * self); static void gst_h265_decoder_finish_current_picture (GstH265Decoder * self,
GstFlowReturn * ret);
static void gst_h265_decoder_clear_ref_pic_sets (GstH265Decoder * self); static void gst_h265_decoder_clear_ref_pic_sets (GstH265Decoder * self);
static void gst_h265_decoder_clear_dpb (GstH265Decoder * self, gboolean flush); static void gst_h265_decoder_clear_dpb (GstH265Decoder * self, gboolean flush);
static gboolean gst_h265_decoder_drain_internal (GstH265Decoder * self); static GstFlowReturn gst_h265_decoder_drain_internal (GstH265Decoder * self);
static gboolean gst_h265_decoder_start_current_picture (GstH265Decoder * self); static GstFlowReturn
gst_h265_decoder_start_current_picture (GstH265Decoder * self);
static void static void
gst_h265_decoder_class_init (GstH265DecoderClass * klass) gst_h265_decoder_class_init (GstH265DecoderClass * klass)
@ -243,23 +249,22 @@ gst_h265_decoder_stop (GstVideoDecoder * decoder)
return TRUE; return TRUE;
} }
static gboolean static GstFlowReturn
gst_h265_decoder_parse_vps (GstH265Decoder * self, GstH265NalUnit * nalu) gst_h265_decoder_parse_vps (GstH265Decoder * self, GstH265NalUnit * nalu)
{ {
GstH265DecoderPrivate *priv = self->priv; GstH265DecoderPrivate *priv = self->priv;
GstH265VPS vps; GstH265VPS vps;
GstH265ParserResult pres; GstH265ParserResult pres;
gboolean ret = TRUE;
pres = gst_h265_parser_parse_vps (priv->parser, nalu, &vps); pres = gst_h265_parser_parse_vps (priv->parser, nalu, &vps);
if (pres != GST_H265_PARSER_OK) { if (pres != GST_H265_PARSER_OK) {
GST_WARNING_OBJECT (self, "Failed to parse VPS, result %d", pres); GST_WARNING_OBJECT (self, "Failed to parse VPS, result %d", pres);
return FALSE; return GST_FLOW_ERROR;
} }
GST_LOG_OBJECT (self, "VPS parsed"); GST_LOG_OBJECT (self, "VPS parsed");
return ret; return GST_FLOW_OK;
} }
static gboolean static gboolean
@ -281,7 +286,7 @@ gst_h265_decoder_is_crop_rect_changed (GstH265Decoder * self, GstH265SPS * sps)
return FALSE; return FALSE;
} }
static gboolean static GstFlowReturn
gst_h265_decoder_process_sps (GstH265Decoder * self, GstH265SPS * sps) gst_h265_decoder_process_sps (GstH265Decoder * self, GstH265SPS * sps)
{ {
GstH265DecoderPrivate *priv = self->priv; GstH265DecoderPrivate *priv = self->priv;
@ -293,6 +298,7 @@ gst_h265_decoder_process_sps (GstH265Decoder * self, GstH265SPS * sps)
guint8 field_seq_flag = 0; guint8 field_seq_flag = 0;
guint8 progressive_source_flag = 0; guint8 progressive_source_flag = 0;
guint8 interlaced_source_flag = 0; guint8 interlaced_source_flag = 0;
GstFlowReturn ret = GST_FLOW_OK;
/* A.4.1 */ /* A.4.1 */
MaxLumaPS = 35651584; MaxLumaPS = 35651584;
@ -334,9 +340,10 @@ gst_h265_decoder_process_sps (GstH265Decoder * self, GstH265SPS * sps)
g_assert (klass->new_sequence); g_assert (klass->new_sequence);
if (!klass->new_sequence (self, sps, max_dpb_size)) { ret = klass->new_sequence (self, sps, max_dpb_size);
GST_ERROR_OBJECT (self, "subclass does not want accept new sequence"); if (ret != GST_FLOW_OK) {
return FALSE; GST_WARNING_OBJECT (self, "subclass does not want accept new sequence");
return ret;
} }
priv->width = sps->width; priv->width = sps->width;
@ -361,38 +368,38 @@ gst_h265_decoder_process_sps (GstH265Decoder * self, GstH265SPS * sps)
GST_DEBUG_OBJECT (self, "Set DPB max size %d", max_dpb_size); GST_DEBUG_OBJECT (self, "Set DPB max size %d", max_dpb_size);
return TRUE; return GST_FLOW_OK;
} }
static gboolean static GstFlowReturn
gst_h265_decoder_parse_sps (GstH265Decoder * self, GstH265NalUnit * nalu) gst_h265_decoder_parse_sps (GstH265Decoder * self, GstH265NalUnit * nalu)
{ {
GstH265DecoderPrivate *priv = self->priv; GstH265DecoderPrivate *priv = self->priv;
GstH265SPS sps; GstH265SPS sps;
GstH265ParserResult pres; GstH265ParserResult pres;
gboolean ret; GstFlowReturn ret = GST_FLOW_OK;
pres = gst_h265_parse_sps (priv->parser, nalu, &sps, TRUE); pres = gst_h265_parse_sps (priv->parser, nalu, &sps, TRUE);
if (pres != GST_H265_PARSER_OK) { if (pres != GST_H265_PARSER_OK) {
GST_WARNING_OBJECT (self, "Failed to parse SPS, result %d", pres); GST_WARNING_OBJECT (self, "Failed to parse SPS, result %d", pres);
return FALSE; return GST_FLOW_ERROR;
} }
GST_LOG_OBJECT (self, "SPS parsed"); GST_LOG_OBJECT (self, "SPS parsed");
ret = gst_h265_decoder_process_sps (self, &sps); ret = gst_h265_decoder_process_sps (self, &sps);
if (!ret) { if (ret != GST_FLOW_OK) {
GST_WARNING_OBJECT (self, "Failed to process SPS"); GST_WARNING_OBJECT (self, "Failed to process SPS");
} else if (gst_h265_parser_update_sps (priv->parser, } else if (gst_h265_parser_update_sps (priv->parser,
&sps) != GST_H265_PARSER_OK) { &sps) != GST_H265_PARSER_OK) {
GST_WARNING_OBJECT (self, "Failed to update SPS"); GST_WARNING_OBJECT (self, "Failed to update SPS");
ret = FALSE; ret = GST_FLOW_ERROR;
} }
return ret; return ret;
} }
static gboolean static GstFlowReturn
gst_h265_decoder_parse_pps (GstH265Decoder * self, GstH265NalUnit * nalu) gst_h265_decoder_parse_pps (GstH265Decoder * self, GstH265NalUnit * nalu)
{ {
GstH265DecoderPrivate *priv = self->priv; GstH265DecoderPrivate *priv = self->priv;
@ -402,15 +409,15 @@ gst_h265_decoder_parse_pps (GstH265Decoder * self, GstH265NalUnit * nalu)
pres = gst_h265_parser_parse_pps (priv->parser, nalu, &pps); pres = gst_h265_parser_parse_pps (priv->parser, nalu, &pps);
if (pres != GST_H265_PARSER_OK) { if (pres != GST_H265_PARSER_OK) {
GST_WARNING_OBJECT (self, "Failed to parse PPS, result %d", pres); GST_WARNING_OBJECT (self, "Failed to parse PPS, result %d", pres);
return FALSE; return GST_FLOW_ERROR;
} }
GST_LOG_OBJECT (self, "PPS parsed"); GST_LOG_OBJECT (self, "PPS parsed");
return TRUE; return GST_FLOW_OK;
} }
static gboolean static GstFlowReturn
gst_h265_decoder_parse_sei (GstH265Decoder * self, GstH265NalUnit * nalu) gst_h265_decoder_parse_sei (GstH265Decoder * self, GstH265NalUnit * nalu)
{ {
GstH265DecoderPrivate *priv = self->priv; GstH265DecoderPrivate *priv = self->priv;
@ -425,7 +432,7 @@ gst_h265_decoder_parse_sei (GstH265Decoder * self, GstH265NalUnit * nalu)
/* XXX: Ignore error from SEI parsing, it might be malformed bitstream, /* XXX: Ignore error from SEI parsing, it might be malformed bitstream,
* or our fault. But shouldn't be critical */ * or our fault. But shouldn't be critical */
g_clear_pointer (&messages, g_array_unref); g_clear_pointer (&messages, g_array_unref);
return TRUE; return GST_FLOW_OK;
} }
for (i = 0; i < messages->len; i++) { for (i = 0; i < messages->len; i++) {
@ -450,7 +457,7 @@ gst_h265_decoder_parse_sei (GstH265Decoder * self, GstH265NalUnit * nalu)
g_array_free (messages, TRUE); g_array_free (messages, TRUE);
GST_LOG_OBJECT (self, "SEI parsed"); GST_LOG_OBJECT (self, "SEI parsed");
return TRUE; return GST_FLOW_OK;
} }
static void static void
@ -573,7 +580,7 @@ gst_h265_decoder_process_ref_pic_lists (GstH265Decoder * self,
g_array_set_size (tmp_refs, 0); g_array_set_size (tmp_refs, 0);
} }
static gboolean static GstFlowReturn
gst_h265_decoder_decode_slice (GstH265Decoder * self) gst_h265_decoder_decode_slice (GstH265Decoder * self)
{ {
GstH265DecoderClass *klass = GST_H265_DECODER_GET_CLASS (self); GstH265DecoderClass *klass = GST_H265_DECODER_GET_CLASS (self);
@ -582,11 +589,11 @@ gst_h265_decoder_decode_slice (GstH265Decoder * self)
GstH265Picture *picture = priv->current_picture; GstH265Picture *picture = priv->current_picture;
GArray *l0 = NULL; GArray *l0 = NULL;
GArray *l1 = NULL; GArray *l1 = NULL;
gboolean ret; GstFlowReturn ret = GST_FLOW_OK;
if (!picture) { if (!picture) {
GST_ERROR_OBJECT (self, "No current picture"); GST_ERROR_OBJECT (self, "No current picture");
return FALSE; return GST_FLOW_ERROR;
} }
g_assert (klass->decode_slice); g_assert (klass->decode_slice);
@ -607,7 +614,7 @@ gst_h265_decoder_decode_slice (GstH265Decoder * self)
return ret; return ret;
} }
static gboolean static GstFlowReturn
gst_h265_decoder_preprocess_slice (GstH265Decoder * self, GstH265Slice * slice) gst_h265_decoder_preprocess_slice (GstH265Decoder * self, GstH265Slice * slice)
{ {
GstH265DecoderPrivate *priv = self->priv; GstH265DecoderPrivate *priv = self->priv;
@ -617,18 +624,19 @@ gst_h265_decoder_preprocess_slice (GstH265Decoder * self, GstH265Slice * slice)
GST_WARNING_OBJECT (self, GST_WARNING_OBJECT (self,
"Current picture is not finished but slice header has " "Current picture is not finished but slice header has "
"first_slice_segment_in_pic_flag"); "first_slice_segment_in_pic_flag");
return FALSE; return GST_FLOW_ERROR;
} }
return TRUE; return GST_FLOW_OK;
} }
static gboolean static GstFlowReturn
gst_h265_decoder_parse_slice (GstH265Decoder * self, GstH265NalUnit * nalu, gst_h265_decoder_parse_slice (GstH265Decoder * self, GstH265NalUnit * nalu,
GstClockTime pts) GstClockTime pts)
{ {
GstH265DecoderPrivate *priv = self->priv; GstH265DecoderPrivate *priv = self->priv;
GstH265ParserResult pres = GST_H265_PARSER_OK; GstH265ParserResult pres = GST_H265_PARSER_OK;
GstFlowReturn ret = GST_FLOW_OK;
memset (&priv->current_slice, 0, sizeof (GstH265Slice)); memset (&priv->current_slice, 0, sizeof (GstH265Slice));
@ -639,7 +647,7 @@ gst_h265_decoder_parse_slice (GstH265Decoder * self, GstH265NalUnit * nalu,
GST_ERROR_OBJECT (self, "Failed to parse slice header, ret %d", pres); GST_ERROR_OBJECT (self, "Failed to parse slice header, ret %d", pres);
memset (&priv->current_slice, 0, sizeof (GstH265Slice)); memset (&priv->current_slice, 0, sizeof (GstH265Slice));
return FALSE; return GST_FLOW_ERROR;
} }
priv->current_slice.nalu = *nalu; priv->current_slice.nalu = *nalu;
@ -656,8 +664,9 @@ gst_h265_decoder_parse_slice (GstH265Decoder * self, GstH265NalUnit * nalu,
memset (&priv->prev_independent_slice.nalu, 0, sizeof (GstH265NalUnit)); memset (&priv->prev_independent_slice.nalu, 0, sizeof (GstH265NalUnit));
} }
if (!gst_h265_decoder_preprocess_slice (self, &priv->current_slice)) ret = gst_h265_decoder_preprocess_slice (self, &priv->current_slice);
return FALSE; if (ret != GST_FLOW_OK)
return ret;
priv->active_pps = priv->current_slice.header.pps; priv->active_pps = priv->current_slice.header.pps;
priv->active_sps = priv->active_pps->sps; priv->active_sps = priv->active_pps->sps;
@ -667,32 +676,34 @@ gst_h265_decoder_parse_slice (GstH265Decoder * self, GstH265NalUnit * nalu,
GstH265Picture *picture; GstH265Picture *picture;
gboolean ret = TRUE; gboolean ret = TRUE;
g_assert (priv->current_frame);
picture = gst_h265_picture_new (); picture = gst_h265_picture_new ();
picture->pts = pts; picture->pts = pts;
/* This allows accessing the frame from the picture. */ /* This allows accessing the frame from the picture. */
picture->system_frame_number = priv->current_frame->system_frame_number; picture->system_frame_number = priv->current_frame->system_frame_number;
priv->current_picture = picture; priv->current_picture = picture;
g_assert (priv->current_frame);
if (klass->new_picture) if (klass->new_picture)
ret = klass->new_picture (self, priv->current_frame, picture); ret = klass->new_picture (self, priv->current_frame, picture);
if (!ret) { if (ret != GST_FLOW_OK) {
GST_ERROR_OBJECT (self, "subclass does not want accept new picture"); GST_WARNING_OBJECT (self, "subclass does not want accept new picture");
priv->current_picture = NULL; priv->current_picture = NULL;
gst_h265_picture_unref (picture); gst_h265_picture_unref (picture);
return FALSE; return ret;
} }
if (!gst_h265_decoder_start_current_picture (self)) { ret = gst_h265_decoder_start_current_picture (self);
GST_ERROR_OBJECT (self, "start picture failed"); if (ret != GST_FLOW_OK) {
return FALSE; GST_WARNING_OBJECT (self, "start picture failed");
return ret;
} }
/* this picture was dropped */ /* this picture was dropped */
if (!priv->current_picture) if (!priv->current_picture)
return TRUE; return GST_FLOW_OK;
} }
return gst_h265_decoder_decode_slice (self); return gst_h265_decoder_decode_slice (self);
@ -703,7 +714,7 @@ gst_h265_decoder_decode_nal (GstH265Decoder * self, GstH265NalUnit * nalu,
GstClockTime pts) GstClockTime pts)
{ {
GstH265DecoderPrivate *priv = self->priv; GstH265DecoderPrivate *priv = self->priv;
gboolean ret = TRUE; GstFlowReturn ret = GST_FLOW_OK;
GST_LOG_OBJECT (self, "Parsed nal type: %d, offset %d, size %d", GST_LOG_OBJECT (self, "Parsed nal type: %d, offset %d, size %d",
nalu->type, nalu->offset, nalu->size); nalu->type, nalu->offset, nalu->size);
@ -798,7 +809,7 @@ gst_h265_decoder_format_from_caps (GstH265Decoder * self, GstCaps * caps,
} }
} }
static gboolean static GstFlowReturn
gst_h265_decoder_parse_codec_data (GstH265Decoder * self, const guint8 * data, gst_h265_decoder_parse_codec_data (GstH265Decoder * self, const guint8 * data,
gsize size) gsize size)
{ {
@ -808,16 +819,17 @@ gst_h265_decoder_parse_codec_data (GstH265Decoder * self, const guint8 * data,
guint num_nals, i, j; guint num_nals, i, j;
GstH265ParserResult pres; GstH265ParserResult pres;
GstH265NalUnit nalu; GstH265NalUnit nalu;
GstFlowReturn ret = GST_FLOW_OK;
/* parse the hvcC data */ /* parse the hvcC data */
if (size < 23) { if (size < 23) {
GST_WARNING_OBJECT (self, "hvcC too small"); GST_WARNING_OBJECT (self, "hvcC too small");
return FALSE; return GST_FLOW_ERROR;
} }
/* wrong hvcC version */ /* wrong hvcC version */
if (data[0] != 0 && data[0] != 1) { if (data[0] != 0 && data[0] != 1) {
return FALSE; return GST_FLOW_ERROR;
} }
priv->nal_length_size = (data[21] & 0x03) + 1; priv->nal_length_size = (data[21] & 0x03) + 1;
@ -829,7 +841,7 @@ gst_h265_decoder_parse_codec_data (GstH265Decoder * self, const guint8 * data,
for (i = 0; i < num_nal_arrays; i++) { for (i = 0; i < num_nal_arrays; i++) {
if (off + 3 >= size) { if (off + 3 >= size) {
GST_WARNING_OBJECT (self, "hvcC too small"); GST_WARNING_OBJECT (self, "hvcC too small");
return FALSE; return GST_FLOW_ERROR;
} }
num_nals = GST_READ_UINT16_BE (data + off + 1); num_nals = GST_READ_UINT16_BE (data + off + 1);
@ -840,26 +852,29 @@ gst_h265_decoder_parse_codec_data (GstH265Decoder * self, const guint8 * data,
if (pres != GST_H265_PARSER_OK) { if (pres != GST_H265_PARSER_OK) {
GST_WARNING_OBJECT (self, "hvcC too small"); GST_WARNING_OBJECT (self, "hvcC too small");
return FALSE; return GST_FLOW_ERROR;
} }
switch (nalu.type) { switch (nalu.type) {
case GST_H265_NAL_VPS: case GST_H265_NAL_VPS:
if (!gst_h265_decoder_parse_vps (self, &nalu)) { ret = gst_h265_decoder_parse_vps (self, &nalu);
if (ret != GST_FLOW_OK) {
GST_WARNING_OBJECT (self, "Failed to parse VPS"); GST_WARNING_OBJECT (self, "Failed to parse VPS");
return FALSE; return ret;
} }
break; break;
case GST_H265_NAL_SPS: case GST_H265_NAL_SPS:
if (!gst_h265_decoder_parse_sps (self, &nalu)) { ret = gst_h265_decoder_parse_sps (self, &nalu);
if (ret != GST_FLOW_OK) {
GST_WARNING_OBJECT (self, "Failed to parse SPS"); GST_WARNING_OBJECT (self, "Failed to parse SPS");
return FALSE; return ret;
} }
break; break;
case GST_H265_NAL_PPS: case GST_H265_NAL_PPS:
if (!gst_h265_decoder_parse_pps (self, &nalu)) { ret = gst_h265_decoder_parse_pps (self, &nalu);
if (ret != GST_FLOW_OK) {
GST_WARNING_OBJECT (self, "Failed to parse PPS"); GST_WARNING_OBJECT (self, "Failed to parse PPS");
return FALSE; return ret;
} }
break; break;
default: default:
@ -870,7 +885,7 @@ gst_h265_decoder_parse_codec_data (GstH265Decoder * self, const guint8 * data,
} }
} }
return TRUE; return GST_FLOW_OK;
} }
static gboolean static gboolean
@ -947,7 +962,8 @@ gst_h265_decoder_set_format (GstVideoDecoder * decoder,
GstMapInfo map; GstMapInfo map;
gst_buffer_map (priv->codec_data, &map, GST_MAP_READ); gst_buffer_map (priv->codec_data, &map, GST_MAP_READ);
if (!gst_h265_decoder_parse_codec_data (self, map.data, map.size)) { if (gst_h265_decoder_parse_codec_data (self, map.data, map.size) !=
GST_FLOW_OK) {
/* keep going without error. /* keep going without error.
* Probably inband SPS/PPS might be valid data */ * Probably inband SPS/PPS might be valid data */
GST_WARNING_OBJECT (self, "Failed to handle codec data"); GST_WARNING_OBJECT (self, "Failed to handle codec data");
@ -972,13 +988,9 @@ static GstFlowReturn
gst_h265_decoder_drain (GstVideoDecoder * decoder) gst_h265_decoder_drain (GstVideoDecoder * decoder)
{ {
GstH265Decoder *self = GST_H265_DECODER (decoder); GstH265Decoder *self = GST_H265_DECODER (decoder);
GstH265DecoderPrivate *priv = self->priv;
priv->last_ret = GST_FLOW_OK;
/* dpb will be cleared by this method */ /* dpb will be cleared by this method */
gst_h265_decoder_drain_internal (self); return gst_h265_decoder_drain_internal (self);
return priv->last_ret;
} }
static GstFlowReturn static GstFlowReturn
@ -1453,11 +1465,14 @@ gst_h265_decoder_prepare_rps (GstH265Decoder * self, const GstH265Slice * slice,
static void static void
gst_h265_decoder_do_output_picture (GstH265Decoder * self, gst_h265_decoder_do_output_picture (GstH265Decoder * self,
GstH265Picture * picture) GstH265Picture * picture, GstFlowReturn * ret)
{ {
GstH265DecoderPrivate *priv = self->priv; GstH265DecoderPrivate *priv = self->priv;
GstH265DecoderClass *klass; GstH265DecoderClass *klass;
GstVideoCodecFrame *frame = NULL; GstVideoCodecFrame *frame = NULL;
GstFlowReturn flow_ret = GST_FLOW_OK;
g_assert (ret != NULL);
GST_LOG_OBJECT (self, "Output picture %p (poc %d)", picture, GST_LOG_OBJECT (self, "Output picture %p (poc %d)", picture,
picture->pic_order_cnt); picture->pic_order_cnt);
@ -1477,7 +1492,7 @@ gst_h265_decoder_do_output_picture (GstH265Decoder * self,
GST_ERROR_OBJECT (self, GST_ERROR_OBJECT (self,
"No available codec frame with frame number %d", "No available codec frame with frame number %d",
picture->system_frame_number); picture->system_frame_number);
priv->last_ret = GST_FLOW_ERROR; UPDATE_FLOW_RETURN (ret, GST_FLOW_ERROR);
gst_h265_picture_unref (picture); gst_h265_picture_unref (picture);
return; return;
@ -1486,7 +1501,9 @@ gst_h265_decoder_do_output_picture (GstH265Decoder * self,
klass = GST_H265_DECODER_GET_CLASS (self); klass = GST_H265_DECODER_GET_CLASS (self);
g_assert (klass->output_picture); g_assert (klass->output_picture);
priv->last_ret = klass->output_picture (self, frame, picture); flow_ret = klass->output_picture (self, frame, picture);
UPDATE_FLOW_RETURN (ret, flow_ret);
} }
static void static void
@ -1513,23 +1530,24 @@ gst_h265_decoder_clear_dpb (GstH265Decoder * self, gboolean flush)
priv->last_output_poc = G_MININT32; priv->last_output_poc = G_MININT32;
} }
static gboolean static GstFlowReturn
gst_h265_decoder_drain_internal (GstH265Decoder * self) gst_h265_decoder_drain_internal (GstH265Decoder * self)
{ {
GstH265DecoderPrivate *priv = self->priv; GstH265DecoderPrivate *priv = self->priv;
GstH265Picture *picture; GstH265Picture *picture;
GstFlowReturn ret = GST_FLOW_OK;
while ((picture = gst_h265_dpb_bump (priv->dpb, TRUE)) != NULL) while ((picture = gst_h265_dpb_bump (priv->dpb, TRUE)) != NULL)
gst_h265_decoder_do_output_picture (self, picture); gst_h265_decoder_do_output_picture (self, picture, &ret);
gst_h265_dpb_clear (priv->dpb); gst_h265_dpb_clear (priv->dpb);
priv->last_output_poc = G_MININT32; priv->last_output_poc = G_MININT32;
return TRUE; return ret;
} }
/* C.5.2.2 */ /* C.5.2.2 */
static gboolean static GstFlowReturn
gst_h265_decoder_dpb_init (GstH265Decoder * self, const GstH265Slice * slice, gst_h265_decoder_dpb_init (GstH265Decoder * self, const GstH265Slice * slice,
GstH265Picture * picture) GstH265Picture * picture)
{ {
@ -1538,6 +1556,7 @@ gst_h265_decoder_dpb_init (GstH265Decoder * self, const GstH265Slice * slice,
const GstH265NalUnit *nalu = &slice->nalu; const GstH265NalUnit *nalu = &slice->nalu;
const GstH265SPS *sps = priv->active_sps; const GstH265SPS *sps = priv->active_sps;
GstH265Picture *to_output; GstH265Picture *to_output;
GstFlowReturn ret = GST_FLOW_OK;
/* C 3.2 */ /* C 3.2 */
if (GST_H265_IS_NAL_TYPE_IRAP (nalu->type) && picture->NoRaslOutputFlag if (GST_H265_IS_NAL_TYPE_IRAP (nalu->type) && picture->NoRaslOutputFlag
@ -1554,7 +1573,7 @@ gst_h265_decoder_dpb_init (GstH265Decoder * self, const GstH265Slice * slice,
} else { } else {
gst_h265_dpb_delete_unused (priv->dpb); gst_h265_dpb_delete_unused (priv->dpb);
while ((to_output = gst_h265_dpb_bump (priv->dpb, FALSE)) != NULL) while ((to_output = gst_h265_dpb_bump (priv->dpb, FALSE)) != NULL)
gst_h265_decoder_do_output_picture (self, to_output); gst_h265_decoder_do_output_picture (self, to_output, &ret);
if (gst_h265_dpb_get_size (priv->dpb) > 0) { if (gst_h265_dpb_get_size (priv->dpb) > 0) {
GST_WARNING_OBJECT (self, "IDR or BLA frame failed to clear the dpb, " GST_WARNING_OBJECT (self, "IDR or BLA frame failed to clear the dpb, "
@ -1579,26 +1598,26 @@ gst_h265_decoder_dpb_init (GstH265Decoder * self, const GstH265Slice * slice,
break; break;
} }
gst_h265_decoder_do_output_picture (self, to_output); gst_h265_decoder_do_output_picture (self, to_output, &ret);
} }
} }
return TRUE; return ret;
} }
static gboolean static GstFlowReturn
gst_h265_decoder_start_current_picture (GstH265Decoder * self) gst_h265_decoder_start_current_picture (GstH265Decoder * self)
{ {
GstH265DecoderClass *klass; GstH265DecoderClass *klass;
GstH265DecoderPrivate *priv = self->priv; GstH265DecoderPrivate *priv = self->priv;
gboolean ret = TRUE; GstFlowReturn ret = GST_FLOW_OK;
g_assert (priv->current_picture != NULL); g_assert (priv->current_picture != NULL);
g_assert (priv->active_sps != NULL); g_assert (priv->active_sps != NULL);
g_assert (priv->active_pps != NULL); g_assert (priv->active_pps != NULL);
if (!gst_h265_decoder_init_current_picture (self)) if (!gst_h265_decoder_init_current_picture (self))
return FALSE; return GST_FLOW_ERROR;
/* Drop all RASL pictures having NoRaslOutputFlag is TRUE for the /* Drop all RASL pictures having NoRaslOutputFlag is TRUE for the
* associated IRAP picture */ * associated IRAP picture */
@ -1606,35 +1625,43 @@ gst_h265_decoder_start_current_picture (GstH265Decoder * self)
priv->associated_irap_NoRaslOutputFlag) { priv->associated_irap_NoRaslOutputFlag) {
GST_DEBUG_OBJECT (self, "Drop current picture"); GST_DEBUG_OBJECT (self, "Drop current picture");
gst_h265_picture_replace (&priv->current_picture, NULL); gst_h265_picture_replace (&priv->current_picture, NULL);
return TRUE; return GST_FLOW_OK;
} }
gst_h265_decoder_prepare_rps (self, &priv->current_slice, gst_h265_decoder_prepare_rps (self, &priv->current_slice,
priv->current_picture); priv->current_picture);
gst_h265_decoder_dpb_init (self, &priv->current_slice, priv->current_picture); ret = gst_h265_decoder_dpb_init (self,
&priv->current_slice, priv->current_picture);
if (ret != GST_FLOW_OK) {
GST_WARNING_OBJECT (self, "Failed to init dpb");
return ret;
}
klass = GST_H265_DECODER_GET_CLASS (self); klass = GST_H265_DECODER_GET_CLASS (self);
if (klass->start_picture) if (klass->start_picture) {
ret = klass->start_picture (self, priv->current_picture, ret = klass->start_picture (self, priv->current_picture,
&priv->current_slice, priv->dpb); &priv->current_slice, priv->dpb);
if (!ret) { if (ret != GST_FLOW_OK) {
GST_ERROR_OBJECT (self, "subclass does not want to start picture"); GST_WARNING_OBJECT (self, "subclass does not want to start picture");
return FALSE; return ret;
}
} }
return TRUE; return GST_FLOW_OK;
} }
static gboolean static void
gst_h265_decoder_finish_picture (GstH265Decoder * self, gst_h265_decoder_finish_picture (GstH265Decoder * self,
GstH265Picture * picture) GstH265Picture * picture, GstFlowReturn * ret)
{ {
GstVideoDecoder *decoder = GST_VIDEO_DECODER (self); GstVideoDecoder *decoder = GST_VIDEO_DECODER (self);
GstH265DecoderPrivate *priv = self->priv; GstH265DecoderPrivate *priv = self->priv;
const GstH265SPS *sps = priv->active_sps; const GstH265SPS *sps = priv->active_sps;
g_assert (ret != NULL);
GST_LOG_OBJECT (self, GST_LOG_OBJECT (self,
"Finishing picture %p (poc %d), entries in DPB %d", "Finishing picture %p (poc %d), entries in DPB %d",
picture, picture->pic_order_cnt, gst_h265_dpb_get_size (priv->dpb)); picture, picture->pic_order_cnt, gst_h265_dpb_get_size (priv->dpb));
@ -1667,37 +1694,40 @@ gst_h265_decoder_finish_picture (GstH265Decoder * self,
break; break;
} }
gst_h265_decoder_do_output_picture (self, to_output); gst_h265_decoder_do_output_picture (self, to_output, ret);
} }
return TRUE;
} }
static gboolean static void
gst_h265_decoder_finish_current_picture (GstH265Decoder * self) gst_h265_decoder_finish_current_picture (GstH265Decoder * self,
GstFlowReturn * ret)
{ {
GstH265DecoderPrivate *priv = self->priv; GstH265DecoderPrivate *priv = self->priv;
GstH265DecoderClass *klass; GstH265DecoderClass *klass;
gboolean ret = TRUE; GstFlowReturn flow_ret = GST_FLOW_OK;
g_assert (ret != NULL);
if (!priv->current_picture) if (!priv->current_picture)
return TRUE; return;
klass = GST_H265_DECODER_GET_CLASS (self); klass = GST_H265_DECODER_GET_CLASS (self);
if (klass->end_picture) if (klass->end_picture) {
ret = klass->end_picture (self, priv->current_picture); flow_ret = klass->end_picture (self, priv->current_picture);
if (flow_ret != GST_FLOW_OK) {
GST_WARNING_OBJECT (self, "End picture failed");
/* finish picture takes ownership of the picture */ /* continue to empty dpb */
ret = gst_h265_decoder_finish_picture (self, priv->current_picture); UPDATE_FLOW_RETURN (ret, flow_ret);
priv->current_picture = NULL; }
if (!ret) {
GST_ERROR_OBJECT (self, "Failed to finish picture");
return FALSE;
} }
return TRUE; /* finish picture takes ownership of the picture */
gst_h265_decoder_finish_picture (self, priv->current_picture, &flow_ret);
priv->current_picture = NULL;
UPDATE_FLOW_RETURN (ret, flow_ret);
} }
static void static void
@ -1721,7 +1751,7 @@ gst_h265_decoder_handle_frame (GstVideoDecoder * decoder,
GstH265NalUnit nalu; GstH265NalUnit nalu;
GstH265ParserResult pres; GstH265ParserResult pres;
GstMapInfo map; GstMapInfo map;
gboolean decode_ret = TRUE; GstFlowReturn decode_ret = GST_FLOW_OK;
GST_LOG_OBJECT (self, GST_LOG_OBJECT (self,
"handle frame, PTS: %" GST_TIME_FORMAT ", DTS: %" "handle frame, PTS: %" GST_TIME_FORMAT ", DTS: %"
@ -1729,7 +1759,6 @@ gst_h265_decoder_handle_frame (GstVideoDecoder * decoder,
GST_TIME_ARGS (GST_BUFFER_DTS (in_buf))); GST_TIME_ARGS (GST_BUFFER_DTS (in_buf)));
priv->current_frame = frame; priv->current_frame = frame;
priv->last_ret = GST_FLOW_OK;
gst_h265_decoder_reset_frame_state (self); gst_h265_decoder_reset_frame_state (self);
@ -1744,7 +1773,7 @@ gst_h265_decoder_handle_frame (GstVideoDecoder * decoder,
pres = gst_h265_parser_identify_nalu_hevc (priv->parser, pres = gst_h265_parser_identify_nalu_hevc (priv->parser,
map.data, 0, map.size, priv->nal_length_size, &nalu); map.data, 0, map.size, priv->nal_length_size, &nalu);
while (pres == GST_H265_PARSER_OK && decode_ret) { while (pres == GST_H265_PARSER_OK && decode_ret == GST_FLOW_OK) {
decode_ret = gst_h265_decoder_decode_nal (self, decode_ret = gst_h265_decoder_decode_nal (self,
&nalu, GST_BUFFER_PTS (in_buf)); &nalu, GST_BUFFER_PTS (in_buf));
@ -1759,7 +1788,7 @@ gst_h265_decoder_handle_frame (GstVideoDecoder * decoder,
if (pres == GST_H265_PARSER_NO_NAL_END) if (pres == GST_H265_PARSER_NO_NAL_END)
pres = GST_H265_PARSER_OK; pres = GST_H265_PARSER_OK;
while (pres == GST_H265_PARSER_OK && decode_ret) { while (pres == GST_H265_PARSER_OK && decode_ret == GST_FLOW_OK) {
decode_ret = gst_h265_decoder_decode_nal (self, decode_ret = gst_h265_decoder_decode_nal (self,
&nalu, GST_BUFFER_PTS (in_buf)); &nalu, GST_BUFFER_PTS (in_buf));
@ -1774,25 +1803,30 @@ gst_h265_decoder_handle_frame (GstVideoDecoder * decoder,
gst_buffer_unmap (in_buf, &map); gst_buffer_unmap (in_buf, &map);
priv->current_frame = NULL; priv->current_frame = NULL;
if (!decode_ret) { if (decode_ret != GST_FLOW_OK) {
GST_VIDEO_DECODER_ERROR (self, 1, STREAM, DECODE, GST_VIDEO_DECODER_ERROR (self, 1, STREAM, DECODE,
("Failed to decode data"), (NULL), priv->last_ret); ("Failed to decode data"), (NULL), decode_ret);
gst_video_decoder_drop_frame (decoder, frame); gst_video_decoder_drop_frame (decoder, frame);
gst_h265_picture_clear (&priv->current_picture); gst_h265_picture_clear (&priv->current_picture);
return priv->last_ret; return decode_ret;
} }
if (priv->current_picture) { if (priv->current_picture) {
gst_h265_decoder_finish_current_picture (self); gst_h265_decoder_finish_current_picture (self, &decode_ret);
gst_video_codec_frame_unref (frame); gst_video_codec_frame_unref (frame);
} else { } else {
/* This picture was dropped */ /* This picture was dropped */
gst_video_decoder_release_frame (decoder, frame); gst_video_decoder_release_frame (decoder, frame);
} }
return priv->last_ret; if (decode_ret != GST_FLOW_OK) {
GST_VIDEO_DECODER_ERROR (self, 1, STREAM, DECODE,
("Failed to decode data"), (NULL), decode_ret);
}
return decode_ret;
} }
/** /**

View file

@ -94,7 +94,7 @@ struct _GstH265DecoderClass
{ {
GstVideoDecoderClass parent_class; GstVideoDecoderClass parent_class;
gboolean (*new_sequence) (GstH265Decoder * decoder, GstFlowReturn (*new_sequence) (GstH265Decoder * decoder,
const GstH265SPS * sps, const GstH265SPS * sps,
gint max_dpb_size); gint max_dpb_size);
/** /**
@ -103,22 +103,22 @@ struct _GstH265DecoderClass
* @frame: (transfer none): a #GstVideoCodecFrame * @frame: (transfer none): a #GstVideoCodecFrame
* @picture: (transfer none): a #GstH265Picture * @picture: (transfer none): a #GstH265Picture
*/ */
gboolean (*new_picture) (GstH265Decoder * decoder, GstFlowReturn (*new_picture) (GstH265Decoder * decoder,
GstVideoCodecFrame * frame, GstVideoCodecFrame * frame,
GstH265Picture * picture); GstH265Picture * picture);
gboolean (*start_picture) (GstH265Decoder * decoder, GstFlowReturn (*start_picture) (GstH265Decoder * decoder,
GstH265Picture * picture, GstH265Picture * picture,
GstH265Slice * slice, GstH265Slice * slice,
GstH265Dpb * dpb); GstH265Dpb * dpb);
gboolean (*decode_slice) (GstH265Decoder * decoder, GstFlowReturn (*decode_slice) (GstH265Decoder * decoder,
GstH265Picture * picture, GstH265Picture * picture,
GstH265Slice * slice, GstH265Slice * slice,
GArray * ref_pic_list0, GArray * ref_pic_list0,
GArray * ref_pic_list1); GArray * ref_pic_list1);
gboolean (*end_picture) (GstH265Decoder * decoder, GstFlowReturn (*end_picture) (GstH265Decoder * decoder,
GstH265Picture * picture); GstH265Picture * picture);
/** /**
* GstH265Decoder:output_picture: * GstH265Decoder:output_picture:

View file

@ -113,19 +113,19 @@ static gboolean gst_d3d11_h265_dec_sink_event (GstVideoDecoder * decoder,
GstEvent * event); GstEvent * event);
/* GstH265Decoder */ /* GstH265Decoder */
static gboolean gst_d3d11_h265_dec_new_sequence (GstH265Decoder * decoder, static GstFlowReturn gst_d3d11_h265_dec_new_sequence (GstH265Decoder * decoder,
const GstH265SPS * sps, gint max_dpb_size); const GstH265SPS * sps, gint max_dpb_size);
static gboolean gst_d3d11_h265_dec_new_picture (GstH265Decoder * decoder, static GstFlowReturn gst_d3d11_h265_dec_new_picture (GstH265Decoder * decoder,
GstVideoCodecFrame * cframe, GstH265Picture * picture); GstVideoCodecFrame * cframe, GstH265Picture * picture);
static GstFlowReturn gst_d3d11_h265_dec_output_picture (GstH265Decoder * static GstFlowReturn gst_d3d11_h265_dec_start_picture (GstH265Decoder * decoder,
decoder, GstVideoCodecFrame * frame, GstH265Picture * picture);
static gboolean gst_d3d11_h265_dec_start_picture (GstH265Decoder * decoder,
GstH265Picture * picture, GstH265Slice * slice, GstH265Dpb * dpb); GstH265Picture * picture, GstH265Slice * slice, GstH265Dpb * dpb);
static gboolean gst_d3d11_h265_dec_decode_slice (GstH265Decoder * decoder, static GstFlowReturn gst_d3d11_h265_dec_decode_slice (GstH265Decoder * decoder,
GstH265Picture * picture, GstH265Slice * slice, GstH265Picture * picture, GstH265Slice * slice,
GArray * ref_pic_list0, GArray * ref_pic_list1); GArray * ref_pic_list0, GArray * ref_pic_list1);
static gboolean gst_d3d11_h265_dec_end_picture (GstH265Decoder * decoder, static GstFlowReturn gst_d3d11_h265_dec_end_picture (GstH265Decoder * decoder,
GstH265Picture * picture); GstH265Picture * picture);
static GstFlowReturn gst_d3d11_h265_dec_output_picture (GstH265Decoder *
decoder, GstVideoCodecFrame * frame, GstH265Picture * picture);
static void static void
gst_d3d11_h265_dec_class_init (GstD3D11H265DecClass * klass, gpointer data) gst_d3d11_h265_dec_class_init (GstD3D11H265DecClass * klass, gpointer data)
@ -159,14 +159,14 @@ gst_d3d11_h265_dec_class_init (GstD3D11H265DecClass * klass, gpointer data)
GST_DEBUG_FUNCPTR (gst_d3d11_h265_dec_new_sequence); GST_DEBUG_FUNCPTR (gst_d3d11_h265_dec_new_sequence);
h265decoder_class->new_picture = h265decoder_class->new_picture =
GST_DEBUG_FUNCPTR (gst_d3d11_h265_dec_new_picture); GST_DEBUG_FUNCPTR (gst_d3d11_h265_dec_new_picture);
h265decoder_class->output_picture =
GST_DEBUG_FUNCPTR (gst_d3d11_h265_dec_output_picture);
h265decoder_class->start_picture = h265decoder_class->start_picture =
GST_DEBUG_FUNCPTR (gst_d3d11_h265_dec_start_picture); GST_DEBUG_FUNCPTR (gst_d3d11_h265_dec_start_picture);
h265decoder_class->decode_slice = h265decoder_class->decode_slice =
GST_DEBUG_FUNCPTR (gst_d3d11_h265_dec_decode_slice); GST_DEBUG_FUNCPTR (gst_d3d11_h265_dec_decode_slice);
h265decoder_class->end_picture = h265decoder_class->end_picture =
GST_DEBUG_FUNCPTR (gst_d3d11_h265_dec_end_picture); GST_DEBUG_FUNCPTR (gst_d3d11_h265_dec_end_picture);
h265decoder_class->output_picture =
GST_DEBUG_FUNCPTR (gst_d3d11_h265_dec_output_picture);
} }
static void static void
@ -316,7 +316,7 @@ gst_d3d11_h265_dec_sink_event (GstVideoDecoder * decoder, GstEvent * event)
return GST_VIDEO_DECODER_CLASS (parent_class)->sink_event (decoder, event); return GST_VIDEO_DECODER_CLASS (parent_class)->sink_event (decoder, event);
} }
static gboolean static GstFlowReturn
gst_d3d11_h265_dec_new_sequence (GstH265Decoder * decoder, gst_d3d11_h265_dec_new_sequence (GstH265Decoder * decoder,
const GstH265SPS * sps, gint max_dpb_size) const GstH265SPS * sps, gint max_dpb_size)
{ {
@ -399,7 +399,7 @@ gst_d3d11_h265_dec_new_sequence (GstH265Decoder * decoder,
if (inner->out_format == GST_VIDEO_FORMAT_UNKNOWN) { if (inner->out_format == GST_VIDEO_FORMAT_UNKNOWN) {
GST_ERROR_OBJECT (self, "Could not support bitdepth/chroma format"); GST_ERROR_OBJECT (self, "Could not support bitdepth/chroma format");
return FALSE; return GST_FLOW_NOT_NEGOTIATED;
} }
gst_video_info_set_format (&info, gst_video_info_set_format (&info,
@ -412,19 +412,19 @@ gst_d3d11_h265_dec_new_sequence (GstH265Decoder * decoder,
/* Additional 4 views margin for zero-copy rendering */ /* Additional 4 views margin for zero-copy rendering */
max_dpb_size + 4)) { max_dpb_size + 4)) {
GST_ERROR_OBJECT (self, "Failed to create decoder"); GST_ERROR_OBJECT (self, "Failed to create decoder");
return FALSE; return GST_FLOW_NOT_NEGOTIATED;
} }
if (!gst_video_decoder_negotiate (GST_VIDEO_DECODER (self))) { if (!gst_video_decoder_negotiate (GST_VIDEO_DECODER (self))) {
GST_ERROR_OBJECT (self, "Failed to negotiate with downstream"); GST_ERROR_OBJECT (self, "Failed to negotiate with downstream");
return FALSE; return GST_FLOW_NOT_NEGOTIATED;
} }
} }
return TRUE; return GST_FLOW_OK;
} }
static gboolean static GstFlowReturn
gst_d3d11_h265_dec_new_picture (GstH265Decoder * decoder, gst_d3d11_h265_dec_new_picture (GstH265Decoder * decoder,
GstVideoCodecFrame * cframe, GstH265Picture * picture) GstVideoCodecFrame * cframe, GstH265Picture * picture)
{ {
@ -436,7 +436,7 @@ gst_d3d11_h265_dec_new_picture (GstH265Decoder * decoder,
GST_VIDEO_DECODER (decoder)); GST_VIDEO_DECODER (decoder));
if (!view_buffer) { if (!view_buffer) {
GST_DEBUG_OBJECT (self, "No available output view buffer"); GST_DEBUG_OBJECT (self, "No available output view buffer");
return FALSE; return GST_FLOW_FLUSHING;
} }
GST_LOG_OBJECT (self, "New output view buffer %" GST_PTR_FORMAT, view_buffer); GST_LOG_OBJECT (self, "New output view buffer %" GST_PTR_FORMAT, view_buffer);
@ -446,7 +446,7 @@ gst_d3d11_h265_dec_new_picture (GstH265Decoder * decoder,
GST_LOG_OBJECT (self, "New h265picture %p", picture); GST_LOG_OBJECT (self, "New h265picture %p", picture);
return TRUE; return GST_FLOW_OK;
} }
static void static void
@ -652,7 +652,7 @@ init_pic_params (DXVA_PicParams_HEVC * params)
} }
} }
static gboolean static GstFlowReturn
gst_d3d11_h265_dec_start_picture (GstH265Decoder * decoder, gst_d3d11_h265_dec_start_picture (GstH265Decoder * decoder,
GstH265Picture * picture, GstH265Slice * slice, GstH265Dpb * dpb) GstH265Picture * picture, GstH265Slice * slice, GstH265Dpb * dpb)
{ {
@ -675,7 +675,7 @@ gst_d3d11_h265_dec_start_picture (GstH265Decoder * decoder,
&view_id); &view_id);
if (!view) { if (!view) {
GST_ERROR_OBJECT (self, "current picture does not have output view handle"); GST_ERROR_OBJECT (self, "current picture does not have output view handle");
return FALSE; return GST_FLOW_ERROR;
} }
init_pic_params (pic_params); init_pic_params (pic_params);
@ -815,10 +815,10 @@ gst_d3d11_h265_dec_start_picture (GstH265Decoder * decoder,
inner->slice_list.resize (0); inner->slice_list.resize (0);
inner->bitstream_buffer.resize (0); inner->bitstream_buffer.resize (0);
return TRUE; return GST_FLOW_OK;
} }
static gboolean static GstFlowReturn
gst_d3d11_h265_dec_decode_slice (GstH265Decoder * decoder, gst_d3d11_h265_dec_decode_slice (GstH265Decoder * decoder,
GstH265Picture * picture, GstH265Slice * slice, GstH265Picture * picture, GstH265Slice * slice,
GArray * ref_pic_list0, GArray * ref_pic_list1) GArray * ref_pic_list0, GArray * ref_pic_list1)
@ -846,10 +846,10 @@ gst_d3d11_h265_dec_decode_slice (GstH265Decoder * decoder,
memcpy (&inner->bitstream_buffer[0] + pos + start_code_size, memcpy (&inner->bitstream_buffer[0] + pos + start_code_size,
slice->nalu.data + slice->nalu.offset, slice->nalu.size); slice->nalu.data + slice->nalu.offset, slice->nalu.size);
return TRUE; return GST_FLOW_OK;
} }
static gboolean static GstFlowReturn
gst_d3d11_h265_dec_end_picture (GstH265Decoder * decoder, gst_d3d11_h265_dec_end_picture (GstH265Decoder * decoder,
GstH265Picture * picture) GstH265Picture * picture)
{ {
@ -866,14 +866,14 @@ gst_d3d11_h265_dec_end_picture (GstH265Decoder * decoder,
if (inner->bitstream_buffer.empty () || inner->slice_list.empty ()) { if (inner->bitstream_buffer.empty () || inner->slice_list.empty ()) {
GST_ERROR_OBJECT (self, "No bitstream buffer to submit"); GST_ERROR_OBJECT (self, "No bitstream buffer to submit");
return FALSE; return GST_FLOW_ERROR;
} }
view = gst_d3d11_h265_dec_get_output_view_from_picture (self, picture, view = gst_d3d11_h265_dec_get_output_view_from_picture (self, picture,
&view_id); &view_id);
if (!view) { if (!view) {
GST_ERROR_OBJECT (self, "current picture does not have output view handle"); GST_ERROR_OBJECT (self, "current picture does not have output view handle");
return FALSE; return GST_FLOW_ERROR;
} }
memset (&input_args, 0, sizeof (GstD3D11DecodeInputStreamArgs)); memset (&input_args, 0, sizeof (GstD3D11DecodeInputStreamArgs));
@ -906,8 +906,10 @@ gst_d3d11_h265_dec_end_picture (GstH265Decoder * decoder,
input_args.inverse_quantization_matrix_size = sizeof (DXVA_Qmatrix_HEVC); input_args.inverse_quantization_matrix_size = sizeof (DXVA_Qmatrix_HEVC);
} }
return gst_d3d11_decoder_decode_frame (inner->d3d11_decoder, if (!gst_d3d11_decoder_decode_frame (inner->d3d11_decoder, view, &input_args))
view, &input_args); return GST_FLOW_ERROR;
return GST_FLOW_OK;
} }
static GstFlowReturn static GstFlowReturn

View file

@ -134,18 +134,18 @@ static gboolean gst_nv_h265_dec_src_query (GstVideoDecoder * decoder,
GstQuery * query); GstQuery * query);
/* GstH265Decoder */ /* GstH265Decoder */
static gboolean gst_nv_h265_dec_new_sequence (GstH265Decoder * decoder, static GstFlowReturn gst_nv_h265_dec_new_sequence (GstH265Decoder * decoder,
const GstH265SPS * sps, gint max_dpb_size); const GstH265SPS * sps, gint max_dpb_size);
static gboolean gst_nv_h265_dec_new_picture (GstH265Decoder * decoder, static GstFlowReturn gst_nv_h265_dec_new_picture (GstH265Decoder * decoder,
GstVideoCodecFrame * frame, GstH265Picture * picture); GstVideoCodecFrame * frame, GstH265Picture * picture);
static GstFlowReturn gst_nv_h265_dec_output_picture (GstH265Decoder * static GstFlowReturn gst_nv_h265_dec_output_picture (GstH265Decoder *
decoder, GstVideoCodecFrame * frame, GstH265Picture * picture); decoder, GstVideoCodecFrame * frame, GstH265Picture * picture);
static gboolean gst_nv_h265_dec_start_picture (GstH265Decoder * decoder, static GstFlowReturn gst_nv_h265_dec_start_picture (GstH265Decoder * decoder,
GstH265Picture * picture, GstH265Slice * slice, GstH265Dpb * dpb); GstH265Picture * picture, GstH265Slice * slice, GstH265Dpb * dpb);
static gboolean gst_nv_h265_dec_decode_slice (GstH265Decoder * decoder, static GstFlowReturn gst_nv_h265_dec_decode_slice (GstH265Decoder * decoder,
GstH265Picture * picture, GstH265Slice * slice, GstH265Picture * picture, GstH265Slice * slice,
GArray * ref_pic_list0, GArray * ref_pic_list1); GArray * ref_pic_list0, GArray * ref_pic_list1);
static gboolean gst_nv_h265_dec_end_picture (GstH265Decoder * decoder, static GstFlowReturn gst_nv_h265_dec_end_picture (GstH265Decoder * decoder,
GstH265Picture * picture); GstH265Picture * picture);
static void static void
@ -316,7 +316,7 @@ gst_nv_h265_dec_src_query (GstVideoDecoder * decoder, GstQuery * query)
return GST_VIDEO_DECODER_CLASS (parent_class)->src_query (decoder, query); return GST_VIDEO_DECODER_CLASS (parent_class)->src_query (decoder, query);
} }
static gboolean static GstFlowReturn
gst_nv_h265_dec_new_sequence (GstH265Decoder * decoder, const GstH265SPS * sps, gst_nv_h265_dec_new_sequence (GstH265Decoder * decoder, const GstH265SPS * sps,
gint max_dpb_size) gint max_dpb_size)
{ {
@ -377,7 +377,7 @@ gst_nv_h265_dec_new_sequence (GstH265Decoder * decoder, const GstH265SPS * sps,
if (out_format == GST_VIDEO_FORMAT_UNKNOWN) { if (out_format == GST_VIDEO_FORMAT_UNKNOWN) {
GST_ERROR_OBJECT (self, "Could not support bitdepth/chroma format"); GST_ERROR_OBJECT (self, "Could not support bitdepth/chroma format");
return FALSE; return GST_FLOW_NOT_NEGOTIATED;
} }
gst_video_info_set_format (&info, out_format, self->width, self->height); gst_video_info_set_format (&info, out_format, self->width, self->height);
@ -387,12 +387,12 @@ gst_nv_h265_dec_new_sequence (GstH265Decoder * decoder, const GstH265SPS * sps,
/* Additional 2 buffers for margin */ /* Additional 2 buffers for margin */
max_dpb_size + 2)) { max_dpb_size + 2)) {
GST_ERROR_OBJECT (self, "Failed to configure decoder"); GST_ERROR_OBJECT (self, "Failed to configure decoder");
return FALSE; return GST_FLOW_NOT_NEGOTIATED;
} }
if (!gst_video_decoder_negotiate (GST_VIDEO_DECODER (self))) { if (!gst_video_decoder_negotiate (GST_VIDEO_DECODER (self))) {
GST_ERROR_OBJECT (self, "Failed to negotiate with downstream"); GST_ERROR_OBJECT (self, "Failed to negotiate with downstream");
return FALSE; return GST_FLOW_NOT_NEGOTIATED;
} }
self->last_sps = NULL; self->last_sps = NULL;
@ -400,10 +400,10 @@ gst_nv_h265_dec_new_sequence (GstH265Decoder * decoder, const GstH265SPS * sps,
memset (&self->params, 0, sizeof (CUVIDPICPARAMS)); memset (&self->params, 0, sizeof (CUVIDPICPARAMS));
} }
return TRUE; return GST_FLOW_OK;
} }
static gboolean static GstFlowReturn
gst_nv_h265_dec_new_picture (GstH265Decoder * decoder, gst_nv_h265_dec_new_picture (GstH265Decoder * decoder,
GstVideoCodecFrame * cframe, GstH265Picture * picture) GstVideoCodecFrame * cframe, GstH265Picture * picture)
{ {
@ -413,7 +413,7 @@ gst_nv_h265_dec_new_picture (GstH265Decoder * decoder,
frame = gst_nv_decoder_new_frame (self->decoder); frame = gst_nv_decoder_new_frame (self->decoder);
if (!frame) { if (!frame) {
GST_ERROR_OBJECT (self, "No available decoder frame"); GST_ERROR_OBJECT (self, "No available decoder frame");
return FALSE; return GST_FLOW_ERROR;
} }
GST_LOG_OBJECT (self, "New decoder frame %p (index %d)", frame, frame->index); GST_LOG_OBJECT (self, "New decoder frame %p (index %d)", frame, frame->index);
@ -421,7 +421,7 @@ gst_nv_h265_dec_new_picture (GstH265Decoder * decoder,
gst_h265_picture_set_user_data (picture, gst_h265_picture_set_user_data (picture,
frame, (GDestroyNotify) gst_nv_decoder_frame_unref); frame, (GDestroyNotify) gst_nv_decoder_frame_unref);
return TRUE; return GST_FLOW_OK;
} }
static GstFlowReturn static GstFlowReturn
@ -642,7 +642,7 @@ gst_nv_h265_dec_reset_bitstream_params (GstNvH265Dec * self)
self->params.pSliceDataOffsets = NULL; self->params.pSliceDataOffsets = NULL;
} }
static gboolean static GstFlowReturn
gst_nv_h265_dec_start_picture (GstH265Decoder * decoder, gst_nv_h265_dec_start_picture (GstH265Decoder * decoder,
GstH265Picture * picture, GstH265Slice * slice, GstH265Dpb * dpb) GstH265Picture * picture, GstH265Slice * slice, GstH265Dpb * dpb)
{ {
@ -668,15 +668,15 @@ gst_nv_h265_dec_start_picture (GstH265Decoder * decoder,
G_STATIC_ASSERT (sizeof (scaling_list->scaling_lists_32x32) == G_STATIC_ASSERT (sizeof (scaling_list->scaling_lists_32x32) ==
sizeof (h265_params->ScalingList32x32)); sizeof (h265_params->ScalingList32x32));
g_return_val_if_fail (slice_header->pps != NULL, FALSE); g_return_val_if_fail (slice_header->pps != NULL, GST_FLOW_ERROR);
g_return_val_if_fail (slice_header->pps->sps != NULL, FALSE); g_return_val_if_fail (slice_header->pps->sps != NULL, GST_FLOW_ERROR);
frame = gst_nv_h265_dec_get_decoder_frame_from_picture (self, picture); frame = gst_nv_h265_dec_get_decoder_frame_from_picture (self, picture);
if (!frame) { if (!frame) {
GST_ERROR_OBJECT (self, GST_ERROR_OBJECT (self,
"Couldn't get decoder frame frame picture %p", picture); "Couldn't get decoder frame frame picture %p", picture);
return FALSE; return GST_FLOW_ERROR;
} }
gst_nv_h265_dec_reset_bitstream_params (self); gst_nv_h265_dec_reset_bitstream_params (self);
@ -702,7 +702,7 @@ gst_nv_h265_dec_start_picture (GstH265Decoder * decoder,
gst_nv_h265_dec_picture_params_from_sps (self, sps, h265_params); gst_nv_h265_dec_picture_params_from_sps (self, sps, h265_params);
if (!gst_nv_h265_dec_picture_params_from_pps (self, pps, h265_params)) { if (!gst_nv_h265_dec_picture_params_from_pps (self, pps, h265_params)) {
GST_ERROR_OBJECT (self, "Couldn't copy pps"); GST_ERROR_OBJECT (self, "Couldn't copy pps");
return FALSE; return GST_FLOW_ERROR;
} }
self->last_sps = sps; self->last_sps = sps;
self->last_pps = pps; self->last_pps = pps;
@ -710,7 +710,7 @@ gst_nv_h265_dec_start_picture (GstH265Decoder * decoder,
GST_DEBUG_OBJECT (self, "Update params from PPS"); GST_DEBUG_OBJECT (self, "Update params from PPS");
if (!gst_nv_h265_dec_picture_params_from_pps (self, pps, h265_params)) { if (!gst_nv_h265_dec_picture_params_from_pps (self, pps, h265_params)) {
GST_ERROR_OBJECT (self, "Couldn't copy pps"); GST_ERROR_OBJECT (self, "Couldn't copy pps");
return FALSE; return GST_FLOW_ERROR;
} }
self->last_pps = pps; self->last_pps = pps;
} else { } else {
@ -721,18 +721,18 @@ gst_nv_h265_dec_start_picture (GstH265Decoder * decoder,
if (decoder->NumPocStCurrBefore > if (decoder->NumPocStCurrBefore >
G_N_ELEMENTS (h265_params->RefPicSetStCurrBefore)) { G_N_ELEMENTS (h265_params->RefPicSetStCurrBefore)) {
GST_ERROR_OBJECT (self, "Too many RefPicSetStCurrBefore"); GST_ERROR_OBJECT (self, "Too many RefPicSetStCurrBefore");
return FALSE; return GST_FLOW_ERROR;
} }
if (decoder->NumPocStCurrAfter > if (decoder->NumPocStCurrAfter >
G_N_ELEMENTS (h265_params->RefPicSetStCurrAfter)) { G_N_ELEMENTS (h265_params->RefPicSetStCurrAfter)) {
GST_ERROR_OBJECT (self, "Too many RefPicSetStCurrAfter"); GST_ERROR_OBJECT (self, "Too many RefPicSetStCurrAfter");
return FALSE; return GST_FLOW_ERROR;
} }
if (decoder->NumPocLtCurr > G_N_ELEMENTS (h265_params->RefPicSetLtCurr)) { if (decoder->NumPocLtCurr > G_N_ELEMENTS (h265_params->RefPicSetLtCurr)) {
GST_ERROR_OBJECT (self, "Too many RefPicSetLtCurr"); GST_ERROR_OBJECT (self, "Too many RefPicSetLtCurr");
return FALSE; return GST_FLOW_ERROR;
} }
/* Fill ref list */ /* Fill ref list */
@ -759,7 +759,7 @@ gst_nv_h265_dec_start_picture (GstH265Decoder * decoder,
if (num_ref_pic >= G_N_ELEMENTS (h265_params->RefPicIdx)) { if (num_ref_pic >= G_N_ELEMENTS (h265_params->RefPicIdx)) {
GST_ERROR_OBJECT (self, "Too many reference frames"); GST_ERROR_OBJECT (self, "Too many reference frames");
return FALSE; return GST_FLOW_ERROR;
} }
other_frame = gst_nv_h265_dec_get_decoder_frame_from_picture (self, other); other_frame = gst_nv_h265_dec_get_decoder_frame_from_picture (self, other);
@ -784,7 +784,7 @@ gst_nv_h265_dec_start_picture (GstH265Decoder * decoder,
if (!decoder->RefPicSetStCurrBefore[i]) { if (!decoder->RefPicSetStCurrBefore[i]) {
GST_ERROR_OBJECT (self, "Empty RefPicSetStCurrBefore[%d]", i); GST_ERROR_OBJECT (self, "Empty RefPicSetStCurrBefore[%d]", i);
return FALSE; return GST_FLOW_ERROR;
} }
other = decoder->RefPicSetStCurrBefore[i]; other = decoder->RefPicSetStCurrBefore[i];
@ -802,7 +802,7 @@ gst_nv_h265_dec_start_picture (GstH265Decoder * decoder,
if (!decoder->RefPicSetStCurrAfter[i]) { if (!decoder->RefPicSetStCurrAfter[i]) {
GST_ERROR_OBJECT (self, "Empty RefPicSetStCurrAfter[%d]", i); GST_ERROR_OBJECT (self, "Empty RefPicSetStCurrAfter[%d]", i);
return FALSE; return GST_FLOW_ERROR;
} }
other = decoder->RefPicSetStCurrAfter[i]; other = decoder->RefPicSetStCurrAfter[i];
@ -820,7 +820,7 @@ gst_nv_h265_dec_start_picture (GstH265Decoder * decoder,
if (!decoder->RefPicSetLtCurr[i]) { if (!decoder->RefPicSetLtCurr[i]) {
GST_ERROR_OBJECT (self, "Empty RefPicSetLtCurr[%d]", i); GST_ERROR_OBJECT (self, "Empty RefPicSetLtCurr[%d]", i);
return FALSE; return GST_FLOW_ERROR;
} }
other = decoder->RefPicSetLtCurr[i]; other = decoder->RefPicSetLtCurr[i];
@ -861,10 +861,10 @@ gst_nv_h265_dec_start_picture (GstH265Decoder * decoder,
scaling_list->scaling_list_dc_coef_minus8_32x32[i] + 8; scaling_list->scaling_list_dc_coef_minus8_32x32[i] + 8;
} }
return TRUE; return GST_FLOW_OK;
} }
static gboolean static GstFlowReturn
gst_nv_h265_dec_decode_slice (GstH265Decoder * decoder, gst_nv_h265_dec_decode_slice (GstH265Decoder * decoder,
GstH265Picture * picture, GstH265Slice * slice, GstH265Picture * picture, GstH265Slice * slice,
GArray * ref_pic_list0, GArray * ref_pic_list1) GArray * ref_pic_list0, GArray * ref_pic_list1)
@ -898,10 +898,10 @@ gst_nv_h265_dec_decode_slice (GstH265Decoder * decoder,
slice->nalu.data + slice->nalu.offset, slice->nalu.size); slice->nalu.data + slice->nalu.offset, slice->nalu.size);
self->bitstream_buffer_offset = new_size; self->bitstream_buffer_offset = new_size;
return TRUE; return GST_FLOW_OK;
} }
static gboolean static GstFlowReturn
gst_nv_h265_dec_end_picture (GstH265Decoder * decoder, GstH265Picture * picture) gst_nv_h265_dec_end_picture (GstH265Decoder * decoder, GstH265Picture * picture)
{ {
GstNvH265Dec *self = GST_NV_H265_DEC (decoder); GstNvH265Dec *self = GST_NV_H265_DEC (decoder);
@ -918,10 +918,12 @@ gst_nv_h265_dec_end_picture (GstH265Decoder * decoder, GstH265Picture * picture)
ret = gst_nv_decoder_decode_picture (self->decoder, &self->params); ret = gst_nv_decoder_decode_picture (self->decoder, &self->params);
if (!ret) if (!ret) {
GST_ERROR_OBJECT (self, "Failed to decode picture"); GST_ERROR_OBJECT (self, "Failed to decode picture");
return GST_FLOW_ERROR;
}
return ret; return GST_FLOW_OK;
} }
typedef struct typedef struct

View file

@ -475,7 +475,7 @@ _get_slice_data_byte_offset (GstH265SliceHdr * slice_hdr,
return nal_header_bytes + (slice_hdr->header_size + 7) / 8 - epb_count; return nal_header_bytes + (slice_hdr->header_size + 7) / 8 - epb_count;
} }
static gboolean static GstFlowReturn
gst_va_h265_dec_decode_slice (GstH265Decoder * decoder, gst_va_h265_dec_decode_slice (GstH265Decoder * decoder,
GstH265Picture * picture, GstH265Slice * slice, GArray * ref_pic_list0, GstH265Picture * picture, GstH265Slice * slice, GArray * ref_pic_list0,
GArray * ref_pic_list1) GArray * ref_pic_list1)
@ -491,7 +491,7 @@ gst_va_h265_dec_decode_slice (GstH265Decoder * decoder,
if (!_submit_previous_slice (base, va_pic)) { if (!_submit_previous_slice (base, va_pic)) {
_replace_previous_slice (self, NULL, 0); _replace_previous_slice (self, NULL, 0);
GST_ERROR_OBJECT (base, "Failed to submit previous slice buffers"); GST_ERROR_OBJECT (base, "Failed to submit previous slice buffers");
return FALSE; return GST_FLOW_ERROR;
} }
slice_param = &self->prev_slice.param; slice_param = &self->prev_slice.param;
@ -559,7 +559,7 @@ gst_va_h265_dec_decode_slice (GstH265Decoder * decoder,
_replace_previous_slice (self, slice->nalu.data + slice->nalu.offset, _replace_previous_slice (self, slice->nalu.data + slice->nalu.offset,
slice->nalu.size); slice->nalu.size);
return TRUE; return GST_FLOW_OK;
} }
static void static void
@ -649,7 +649,7 @@ _fill_screen_content_ext_parameter (GstVaH265Dec * decoder,
} }
} }
static gboolean static GstFlowReturn
gst_va_h265_dec_start_picture (GstH265Decoder * decoder, gst_va_h265_dec_start_picture (GstH265Decoder * decoder,
GstH265Picture * picture, GstH265Slice * slice, GstH265Dpb * dpb) GstH265Picture * picture, GstH265Slice * slice, GstH265Dpb * dpb)
{ {
@ -798,7 +798,7 @@ gst_va_h265_dec_start_picture (GstH265Decoder * decoder,
sizeof (*pic_param) : sizeof (pic_param->base); sizeof (*pic_param) : sizeof (pic_param->base);
if (!gst_va_decoder_add_param_buffer (base->decoder, va_pic, if (!gst_va_decoder_add_param_buffer (base->decoder, va_pic,
VAPictureParameterBufferType, pic_param, pic_param_size)) VAPictureParameterBufferType, pic_param, pic_param_size))
return FALSE; return GST_FLOW_ERROR;
if (pps->scaling_list_data_present_flag || if (pps->scaling_list_data_present_flag ||
(sps->scaling_list_enabled_flag (sps->scaling_list_enabled_flag
@ -836,14 +836,16 @@ gst_va_h265_dec_start_picture (GstH265Decoder * decoder,
iq_matrix.ScalingListDC32x32[i] = iq_matrix.ScalingListDC32x32[i] =
scaling_list->scaling_list_dc_coef_minus8_32x32[i] + 8; scaling_list->scaling_list_dc_coef_minus8_32x32[i] + 8;
return gst_va_decoder_add_param_buffer (base->decoder, va_pic, if (!gst_va_decoder_add_param_buffer (base->decoder, va_pic,
VAIQMatrixBufferType, &iq_matrix, sizeof (iq_matrix)); VAIQMatrixBufferType, &iq_matrix, sizeof (iq_matrix))) {
return GST_FLOW_ERROR;
}
} }
return TRUE; return GST_FLOW_OK;
} }
static gboolean static GstFlowReturn
gst_va_h265_dec_new_picture (GstH265Decoder * decoder, gst_va_h265_dec_new_picture (GstH265Decoder * decoder,
GstVideoCodecFrame * frame, GstH265Picture * picture) GstVideoCodecFrame * frame, GstH265Picture * picture)
{ {
@ -869,14 +871,14 @@ gst_va_h265_dec_new_picture (GstH265Decoder * decoder,
GST_LOG_OBJECT (self, "New va decode picture %p - %#x", pic, GST_LOG_OBJECT (self, "New va decode picture %p - %#x", pic,
gst_va_decode_picture_get_surface (pic)); gst_va_decode_picture_get_surface (pic));
return TRUE; return GST_FLOW_OK;
error: error:
{ {
GST_WARNING_OBJECT (self, GST_WARNING_OBJECT (self,
"Failed to allocated output buffer, return %s", "Failed to allocated output buffer, return %s",
gst_flow_get_name (self->last_ret)); gst_flow_get_name (self->last_ret));
return FALSE; return self->last_ret;
} }
} }
@ -1033,7 +1035,7 @@ _get_profile (GstVaH265Dec * self, const GstH265SPS * sps, gint max_dpb_size)
return VAProfileNone; return VAProfileNone;
} }
static gboolean static GstFlowReturn
gst_va_h265_dec_new_sequence (GstH265Decoder * decoder, const GstH265SPS * sps, gst_va_h265_dec_new_sequence (GstH265Decoder * decoder, const GstH265SPS * sps,
gint max_dpb_size) gint max_dpb_size)
{ {
@ -1064,12 +1066,12 @@ gst_va_h265_dec_new_sequence (GstH265Decoder * decoder, const GstH265SPS * sps,
profile = _get_profile (self, sps, max_dpb_size); profile = _get_profile (self, sps, max_dpb_size);
if (profile == VAProfileNone) if (profile == VAProfileNone)
return FALSE; return GST_FLOW_NOT_NEGOTIATED;
rt_format = _get_rtformat (self, sps->bit_depth_luma_minus8 + 8, rt_format = _get_rtformat (self, sps->bit_depth_luma_minus8 + 8,
sps->bit_depth_chroma_minus8 + 8, sps->chroma_format_idc); sps->bit_depth_chroma_minus8 + 8, sps->chroma_format_idc);
if (rt_format == 0) if (rt_format == 0)
return FALSE; return GST_FLOW_NOT_NEGOTIATED;
if (!gst_va_decoder_config_is_equal (base->decoder, profile, if (!gst_va_decoder_config_is_equal (base->decoder, profile,
rt_format, sps->width, sps->height)) { rt_format, sps->width, sps->height)) {
@ -1120,7 +1122,7 @@ gst_va_h265_dec_new_sequence (GstH265Decoder * decoder, const GstH265SPS * sps,
self->need_negotiation = TRUE; self->need_negotiation = TRUE;
if (!gst_video_decoder_negotiate (GST_VIDEO_DECODER (self))) { if (!gst_video_decoder_negotiate (GST_VIDEO_DECODER (self))) {
GST_ERROR_OBJECT (self, "Failed to negotiate with downstream"); GST_ERROR_OBJECT (self, "Failed to negotiate with downstream");
return FALSE; return GST_FLOW_NOT_NEGOTIATED;
} }
} }
@ -1135,7 +1137,7 @@ gst_va_h265_dec_new_sequence (GstH265Decoder * decoder, const GstH265SPS * sps,
1 << (high_precision_offsets_enabled_flag ? (bitdepthC - 1) : 7); 1 << (high_precision_offsets_enabled_flag ? (bitdepthC - 1) : 7);
} }
return TRUE; return GST_FLOW_OK;
} }
static GstCaps * static GstCaps *