GstH265DecoderAlign align;
GstH265Parser *parser;
GstH265Dpb *dpb;
- GstFlowReturn last_ret;
/* 0: frame or field-pair interlaced stream
* 1: alternating, single field interlaced stream.
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
G_DEFINE_ABSTRACT_TYPE_WITH_CODE (GstH265Decoder, gst_h265_decoder,
GST_TYPE_VIDEO_DECODER,
static GstFlowReturn gst_h265_decoder_handle_frame (GstVideoDecoder * decoder,
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_dpb (GstH265Decoder * self, gboolean flush);
-static gboolean gst_h265_decoder_drain_internal (GstH265Decoder * self);
-static gboolean gst_h265_decoder_start_current_picture (GstH265Decoder * self);
+static GstFlowReturn gst_h265_decoder_drain_internal (GstH265Decoder * self);
+static GstFlowReturn
+gst_h265_decoder_start_current_picture (GstH265Decoder * self);
static void
gst_h265_decoder_class_init (GstH265DecoderClass * klass)
return TRUE;
}
-static gboolean
+static GstFlowReturn
gst_h265_decoder_parse_vps (GstH265Decoder * self, GstH265NalUnit * nalu)
{
GstH265DecoderPrivate *priv = self->priv;
GstH265VPS vps;
GstH265ParserResult pres;
- gboolean ret = TRUE;
pres = gst_h265_parser_parse_vps (priv->parser, nalu, &vps);
if (pres != GST_H265_PARSER_OK) {
GST_WARNING_OBJECT (self, "Failed to parse VPS, result %d", pres);
- return FALSE;
+ return GST_FLOW_ERROR;
}
GST_LOG_OBJECT (self, "VPS parsed");
- return ret;
+ return GST_FLOW_OK;
}
static gboolean
return FALSE;
}
-static gboolean
+static GstFlowReturn
gst_h265_decoder_process_sps (GstH265Decoder * self, GstH265SPS * sps)
{
GstH265DecoderPrivate *priv = self->priv;
guint8 field_seq_flag = 0;
guint8 progressive_source_flag = 0;
guint8 interlaced_source_flag = 0;
+ GstFlowReturn ret = GST_FLOW_OK;
/* A.4.1 */
MaxLumaPS = 35651584;
g_assert (klass->new_sequence);
- if (!klass->new_sequence (self, sps, max_dpb_size)) {
- GST_ERROR_OBJECT (self, "subclass does not want accept new sequence");
- return FALSE;
+ ret = klass->new_sequence (self, sps, max_dpb_size);
+ if (ret != GST_FLOW_OK) {
+ GST_WARNING_OBJECT (self, "subclass does not want accept new sequence");
+ return ret;
}
priv->width = sps->width;
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)
{
GstH265DecoderPrivate *priv = self->priv;
GstH265SPS sps;
GstH265ParserResult pres;
- gboolean ret;
+ GstFlowReturn ret = GST_FLOW_OK;
pres = gst_h265_parse_sps (priv->parser, nalu, &sps, TRUE);
if (pres != GST_H265_PARSER_OK) {
GST_WARNING_OBJECT (self, "Failed to parse SPS, result %d", pres);
- return FALSE;
+ return GST_FLOW_ERROR;
}
GST_LOG_OBJECT (self, "SPS parsed");
ret = gst_h265_decoder_process_sps (self, &sps);
- if (!ret) {
+ if (ret != GST_FLOW_OK) {
GST_WARNING_OBJECT (self, "Failed to process SPS");
} else if (gst_h265_parser_update_sps (priv->parser,
&sps) != GST_H265_PARSER_OK) {
GST_WARNING_OBJECT (self, "Failed to update SPS");
- ret = FALSE;
+ ret = GST_FLOW_ERROR;
}
return ret;
}
-static gboolean
+static GstFlowReturn
gst_h265_decoder_parse_pps (GstH265Decoder * self, GstH265NalUnit * nalu)
{
GstH265DecoderPrivate *priv = self->priv;
pres = gst_h265_parser_parse_pps (priv->parser, nalu, &pps);
if (pres != GST_H265_PARSER_OK) {
GST_WARNING_OBJECT (self, "Failed to parse PPS, result %d", pres);
- return FALSE;
+ return GST_FLOW_ERROR;
}
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)
{
GstH265DecoderPrivate *priv = self->priv;
/* XXX: Ignore error from SEI parsing, it might be malformed bitstream,
* or our fault. But shouldn't be critical */
g_clear_pointer (&messages, g_array_unref);
- return TRUE;
+ return GST_FLOW_OK;
}
for (i = 0; i < messages->len; i++) {
g_array_free (messages, TRUE);
GST_LOG_OBJECT (self, "SEI parsed");
- return TRUE;
+ return GST_FLOW_OK;
}
static void
g_array_set_size (tmp_refs, 0);
}
-static gboolean
+static GstFlowReturn
gst_h265_decoder_decode_slice (GstH265Decoder * self)
{
GstH265DecoderClass *klass = GST_H265_DECODER_GET_CLASS (self);
GstH265Picture *picture = priv->current_picture;
GArray *l0 = NULL;
GArray *l1 = NULL;
- gboolean ret;
+ GstFlowReturn ret = GST_FLOW_OK;
if (!picture) {
GST_ERROR_OBJECT (self, "No current picture");
- return FALSE;
+ return GST_FLOW_ERROR;
}
g_assert (klass->decode_slice);
return ret;
}
-static gboolean
+static GstFlowReturn
gst_h265_decoder_preprocess_slice (GstH265Decoder * self, GstH265Slice * slice)
{
GstH265DecoderPrivate *priv = self->priv;
GST_WARNING_OBJECT (self,
"Current picture is not finished but slice header has "
"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,
GstClockTime pts)
{
GstH265DecoderPrivate *priv = self->priv;
GstH265ParserResult pres = GST_H265_PARSER_OK;
+ GstFlowReturn ret = GST_FLOW_OK;
memset (&priv->current_slice, 0, sizeof (GstH265Slice));
GST_ERROR_OBJECT (self, "Failed to parse slice header, ret %d", pres);
memset (&priv->current_slice, 0, sizeof (GstH265Slice));
- return FALSE;
+ return GST_FLOW_ERROR;
}
priv->current_slice.nalu = *nalu;
memset (&priv->prev_independent_slice.nalu, 0, sizeof (GstH265NalUnit));
}
- if (!gst_h265_decoder_preprocess_slice (self, &priv->current_slice))
- return FALSE;
+ ret = gst_h265_decoder_preprocess_slice (self, &priv->current_slice);
+ if (ret != GST_FLOW_OK)
+ return ret;
priv->active_pps = priv->current_slice.header.pps;
priv->active_sps = priv->active_pps->sps;
GstH265Picture *picture;
gboolean ret = TRUE;
+ g_assert (priv->current_frame);
+
picture = gst_h265_picture_new ();
picture->pts = pts;
/* This allows accessing the frame from the picture. */
picture->system_frame_number = priv->current_frame->system_frame_number;
priv->current_picture = picture;
- g_assert (priv->current_frame);
if (klass->new_picture)
ret = klass->new_picture (self, priv->current_frame, picture);
- if (!ret) {
- GST_ERROR_OBJECT (self, "subclass does not want accept new picture");
+ if (ret != GST_FLOW_OK) {
+ GST_WARNING_OBJECT (self, "subclass does not want accept new picture");
priv->current_picture = NULL;
gst_h265_picture_unref (picture);
- return FALSE;
+ return ret;
}
- if (!gst_h265_decoder_start_current_picture (self)) {
- GST_ERROR_OBJECT (self, "start picture failed");
- return FALSE;
+ ret = gst_h265_decoder_start_current_picture (self);
+ if (ret != GST_FLOW_OK) {
+ GST_WARNING_OBJECT (self, "start picture failed");
+ return ret;
}
/* this picture was dropped */
if (!priv->current_picture)
- return TRUE;
+ return GST_FLOW_OK;
}
return gst_h265_decoder_decode_slice (self);
GstClockTime pts)
{
GstH265DecoderPrivate *priv = self->priv;
- gboolean ret = TRUE;
+ GstFlowReturn ret = GST_FLOW_OK;
GST_LOG_OBJECT (self, "Parsed nal type: %d, offset %d, size %d",
nalu->type, nalu->offset, nalu->size);
}
}
-static gboolean
+static GstFlowReturn
gst_h265_decoder_parse_codec_data (GstH265Decoder * self, const guint8 * data,
gsize size)
{
guint num_nals, i, j;
GstH265ParserResult pres;
GstH265NalUnit nalu;
+ GstFlowReturn ret = GST_FLOW_OK;
/* parse the hvcC data */
if (size < 23) {
GST_WARNING_OBJECT (self, "hvcC too small");
- return FALSE;
+ return GST_FLOW_ERROR;
}
/* wrong hvcC version */
if (data[0] != 0 && data[0] != 1) {
- return FALSE;
+ return GST_FLOW_ERROR;
}
priv->nal_length_size = (data[21] & 0x03) + 1;
for (i = 0; i < num_nal_arrays; i++) {
if (off + 3 >= size) {
GST_WARNING_OBJECT (self, "hvcC too small");
- return FALSE;
+ return GST_FLOW_ERROR;
}
num_nals = GST_READ_UINT16_BE (data + off + 1);
if (pres != GST_H265_PARSER_OK) {
GST_WARNING_OBJECT (self, "hvcC too small");
- return FALSE;
+ return GST_FLOW_ERROR;
}
switch (nalu.type) {
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");
- return FALSE;
+ return ret;
}
break;
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");
- return FALSE;
+ return ret;
}
break;
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");
- return FALSE;
+ return ret;
}
break;
default:
}
}
- return TRUE;
+ return GST_FLOW_OK;
}
static gboolean
GstMapInfo map;
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.
* Probably inband SPS/PPS might be valid data */
GST_WARNING_OBJECT (self, "Failed to handle codec data");
gst_h265_decoder_drain (GstVideoDecoder * decoder)
{
GstH265Decoder *self = GST_H265_DECODER (decoder);
- GstH265DecoderPrivate *priv = self->priv;
- priv->last_ret = GST_FLOW_OK;
/* dpb will be cleared by this method */
- gst_h265_decoder_drain_internal (self);
-
- return priv->last_ret;
+ return gst_h265_decoder_drain_internal (self);
}
static GstFlowReturn
static void
gst_h265_decoder_do_output_picture (GstH265Decoder * self,
- GstH265Picture * picture)
+ GstH265Picture * picture, GstFlowReturn * ret)
{
GstH265DecoderPrivate *priv = self->priv;
GstH265DecoderClass *klass;
GstVideoCodecFrame *frame = NULL;
+ GstFlowReturn flow_ret = GST_FLOW_OK;
+
+ g_assert (ret != NULL);
GST_LOG_OBJECT (self, "Output picture %p (poc %d)", picture,
picture->pic_order_cnt);
GST_ERROR_OBJECT (self,
"No available codec frame with frame number %d",
picture->system_frame_number);
- priv->last_ret = GST_FLOW_ERROR;
+ UPDATE_FLOW_RETURN (ret, GST_FLOW_ERROR);
gst_h265_picture_unref (picture);
return;
klass = GST_H265_DECODER_GET_CLASS (self);
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
priv->last_output_poc = G_MININT32;
}
-static gboolean
+static GstFlowReturn
gst_h265_decoder_drain_internal (GstH265Decoder * self)
{
GstH265DecoderPrivate *priv = self->priv;
GstH265Picture *picture;
+ GstFlowReturn ret = GST_FLOW_OK;
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);
priv->last_output_poc = G_MININT32;
- return TRUE;
+ return ret;
}
/* C.5.2.2 */
-static gboolean
+static GstFlowReturn
gst_h265_decoder_dpb_init (GstH265Decoder * self, const GstH265Slice * slice,
GstH265Picture * picture)
{
const GstH265NalUnit *nalu = &slice->nalu;
const GstH265SPS *sps = priv->active_sps;
GstH265Picture *to_output;
+ GstFlowReturn ret = GST_FLOW_OK;
/* C 3.2 */
if (GST_H265_IS_NAL_TYPE_IRAP (nalu->type) && picture->NoRaslOutputFlag
} else {
gst_h265_dpb_delete_unused (priv->dpb);
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) {
GST_WARNING_OBJECT (self, "IDR or BLA frame failed to clear the dpb, "
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)
{
GstH265DecoderClass *klass;
GstH265DecoderPrivate *priv = self->priv;
- gboolean ret = TRUE;
+ GstFlowReturn ret = GST_FLOW_OK;
g_assert (priv->current_picture != NULL);
g_assert (priv->active_sps != NULL);
g_assert (priv->active_pps != NULL);
if (!gst_h265_decoder_init_current_picture (self))
- return FALSE;
+ return GST_FLOW_ERROR;
/* Drop all RASL pictures having NoRaslOutputFlag is TRUE for the
* associated IRAP picture */
priv->associated_irap_NoRaslOutputFlag) {
GST_DEBUG_OBJECT (self, "Drop current picture");
gst_h265_picture_replace (&priv->current_picture, NULL);
- return TRUE;
+ return GST_FLOW_OK;
}
gst_h265_decoder_prepare_rps (self, &priv->current_slice,
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);
- if (klass->start_picture)
+ if (klass->start_picture) {
ret = klass->start_picture (self, priv->current_picture,
&priv->current_slice, priv->dpb);
- if (!ret) {
- GST_ERROR_OBJECT (self, "subclass does not want to start picture");
- return FALSE;
+ if (ret != GST_FLOW_OK) {
+ GST_WARNING_OBJECT (self, "subclass does not want to start picture");
+ return ret;
+ }
}
- return TRUE;
+ return GST_FLOW_OK;
}
-static gboolean
+static void
gst_h265_decoder_finish_picture (GstH265Decoder * self,
- GstH265Picture * picture)
+ GstH265Picture * picture, GstFlowReturn * ret)
{
GstVideoDecoder *decoder = GST_VIDEO_DECODER (self);
GstH265DecoderPrivate *priv = self->priv;
const GstH265SPS *sps = priv->active_sps;
+ g_assert (ret != NULL);
+
GST_LOG_OBJECT (self,
"Finishing picture %p (poc %d), entries in DPB %d",
picture, picture->pic_order_cnt, gst_h265_dpb_get_size (priv->dpb));
break;
}
- gst_h265_decoder_do_output_picture (self, to_output);
+ gst_h265_decoder_do_output_picture (self, to_output, ret);
}
-
- return TRUE;
}
-static gboolean
-gst_h265_decoder_finish_current_picture (GstH265Decoder * self)
+static void
+gst_h265_decoder_finish_current_picture (GstH265Decoder * self,
+ GstFlowReturn * ret)
{
GstH265DecoderPrivate *priv = self->priv;
GstH265DecoderClass *klass;
- gboolean ret = TRUE;
+ GstFlowReturn flow_ret = GST_FLOW_OK;
+
+ g_assert (ret != NULL);
if (!priv->current_picture)
- return TRUE;
+ return;
klass = GST_H265_DECODER_GET_CLASS (self);
- if (klass->end_picture)
- ret = klass->end_picture (self, priv->current_picture);
+ if (klass->end_picture) {
+ flow_ret = klass->end_picture (self, priv->current_picture);
+ if (flow_ret != GST_FLOW_OK) {
+ GST_WARNING_OBJECT (self, "End picture failed");
+
+ /* continue to empty dpb */
+ UPDATE_FLOW_RETURN (ret, flow_ret);
+ }
+ }
/* finish picture takes ownership of the picture */
- ret = gst_h265_decoder_finish_picture (self, priv->current_picture);
+ gst_h265_decoder_finish_picture (self, priv->current_picture, &flow_ret);
priv->current_picture = NULL;
- if (!ret) {
- GST_ERROR_OBJECT (self, "Failed to finish picture");
- return FALSE;
- }
-
- return TRUE;
+ UPDATE_FLOW_RETURN (ret, flow_ret);
}
static void
GstH265NalUnit nalu;
GstH265ParserResult pres;
GstMapInfo map;
- gboolean decode_ret = TRUE;
+ GstFlowReturn decode_ret = GST_FLOW_OK;
GST_LOG_OBJECT (self,
"handle frame, PTS: %" GST_TIME_FORMAT ", DTS: %"
GST_TIME_ARGS (GST_BUFFER_DTS (in_buf)));
priv->current_frame = frame;
- priv->last_ret = GST_FLOW_OK;
gst_h265_decoder_reset_frame_state (self);
pres = gst_h265_parser_identify_nalu_hevc (priv->parser,
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,
&nalu, GST_BUFFER_PTS (in_buf));
if (pres == GST_H265_PARSER_NO_NAL_END)
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,
&nalu, GST_BUFFER_PTS (in_buf));
gst_buffer_unmap (in_buf, &map);
priv->current_frame = NULL;
- if (!decode_ret) {
+ if (decode_ret != GST_FLOW_OK) {
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_h265_picture_clear (&priv->current_picture);
- return priv->last_ret;
+ return decode_ret;
}
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);
} else {
/* This picture was dropped */
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;
}
/**
GstEvent * event);
/* 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);
-static gboolean gst_d3d11_h265_dec_new_picture (GstH265Decoder * decoder,
+static GstFlowReturn gst_d3d11_h265_dec_new_picture (GstH265Decoder * decoder,
GstVideoCodecFrame * cframe, GstH265Picture * picture);
-static GstFlowReturn gst_d3d11_h265_dec_output_picture (GstH265Decoder *
- decoder, GstVideoCodecFrame * frame, GstH265Picture * picture);
-static gboolean gst_d3d11_h265_dec_start_picture (GstH265Decoder * decoder,
+static GstFlowReturn gst_d3d11_h265_dec_start_picture (GstH265Decoder * decoder,
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,
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);
+static GstFlowReturn gst_d3d11_h265_dec_output_picture (GstH265Decoder *
+ decoder, GstVideoCodecFrame * frame, GstH265Picture * picture);
static void
gst_d3d11_h265_dec_class_init (GstD3D11H265DecClass * klass, gpointer data)
GST_DEBUG_FUNCPTR (gst_d3d11_h265_dec_new_sequence);
h265decoder_class->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 =
GST_DEBUG_FUNCPTR (gst_d3d11_h265_dec_start_picture);
h265decoder_class->decode_slice =
GST_DEBUG_FUNCPTR (gst_d3d11_h265_dec_decode_slice);
h265decoder_class->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
return GST_VIDEO_DECODER_CLASS (parent_class)->sink_event (decoder, event);
}
-static gboolean
+static GstFlowReturn
gst_d3d11_h265_dec_new_sequence (GstH265Decoder * decoder,
const GstH265SPS * sps, gint max_dpb_size)
{
if (inner->out_format == GST_VIDEO_FORMAT_UNKNOWN) {
GST_ERROR_OBJECT (self, "Could not support bitdepth/chroma format");
- return FALSE;
+ return GST_FLOW_NOT_NEGOTIATED;
}
gst_video_info_set_format (&info,
/* Additional 4 views margin for zero-copy rendering */
max_dpb_size + 4)) {
GST_ERROR_OBJECT (self, "Failed to create decoder");
- return FALSE;
+ return GST_FLOW_NOT_NEGOTIATED;
}
if (!gst_video_decoder_negotiate (GST_VIDEO_DECODER (self))) {
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,
GstVideoCodecFrame * cframe, GstH265Picture * picture)
{
GST_VIDEO_DECODER (decoder));
if (!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 h265picture %p", picture);
- return TRUE;
+ return GST_FLOW_OK;
}
static void
}
}
-static gboolean
+static GstFlowReturn
gst_d3d11_h265_dec_start_picture (GstH265Decoder * decoder,
GstH265Picture * picture, GstH265Slice * slice, GstH265Dpb * dpb)
{
&view_id);
if (!view) {
GST_ERROR_OBJECT (self, "current picture does not have output view handle");
- return FALSE;
+ return GST_FLOW_ERROR;
}
init_pic_params (pic_params);
inner->slice_list.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,
GstH265Picture * picture, GstH265Slice * slice,
GArray * ref_pic_list0, GArray * ref_pic_list1)
memcpy (&inner->bitstream_buffer[0] + pos + start_code_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,
GstH265Picture * picture)
{
if (inner->bitstream_buffer.empty () || inner->slice_list.empty ()) {
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_id);
if (!view) {
GST_ERROR_OBJECT (self, "current picture does not have output view handle");
- return FALSE;
+ return GST_FLOW_ERROR;
}
memset (&input_args, 0, sizeof (GstD3D11DecodeInputStreamArgs));
input_args.inverse_quantization_matrix_size = sizeof (DXVA_Qmatrix_HEVC);
}
- return gst_d3d11_decoder_decode_frame (inner->d3d11_decoder,
- view, &input_args);
+ if (!gst_d3d11_decoder_decode_frame (inner->d3d11_decoder, view, &input_args))
+ return GST_FLOW_ERROR;
+
+ return GST_FLOW_OK;
}
static GstFlowReturn
GstQuery * query);
/* 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);
-static gboolean gst_nv_h265_dec_new_picture (GstH265Decoder * decoder,
+static GstFlowReturn gst_nv_h265_dec_new_picture (GstH265Decoder * decoder,
GstVideoCodecFrame * frame, GstH265Picture * picture);
static GstFlowReturn gst_nv_h265_dec_output_picture (GstH265Decoder *
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);
-static gboolean gst_nv_h265_dec_decode_slice (GstH265Decoder * decoder,
+static GstFlowReturn gst_nv_h265_dec_decode_slice (GstH265Decoder * decoder,
GstH265Picture * picture, GstH265Slice * slice,
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);
static void
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,
gint max_dpb_size)
{
if (out_format == GST_VIDEO_FORMAT_UNKNOWN) {
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);
/* Additional 2 buffers for margin */
max_dpb_size + 2)) {
GST_ERROR_OBJECT (self, "Failed to configure decoder");
- return FALSE;
+ return GST_FLOW_NOT_NEGOTIATED;
}
if (!gst_video_decoder_negotiate (GST_VIDEO_DECODER (self))) {
GST_ERROR_OBJECT (self, "Failed to negotiate with downstream");
- return FALSE;
+ return GST_FLOW_NOT_NEGOTIATED;
}
self->last_sps = NULL;
memset (&self->params, 0, sizeof (CUVIDPICPARAMS));
}
- return TRUE;
+ return GST_FLOW_OK;
}
-static gboolean
+static GstFlowReturn
gst_nv_h265_dec_new_picture (GstH265Decoder * decoder,
GstVideoCodecFrame * cframe, GstH265Picture * picture)
{
frame = gst_nv_decoder_new_frame (self->decoder);
if (!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_h265_picture_set_user_data (picture,
frame, (GDestroyNotify) gst_nv_decoder_frame_unref);
- return TRUE;
+ return GST_FLOW_OK;
}
static GstFlowReturn
self->params.pSliceDataOffsets = NULL;
}
-static gboolean
+static GstFlowReturn
gst_nv_h265_dec_start_picture (GstH265Decoder * decoder,
GstH265Picture * picture, GstH265Slice * slice, GstH265Dpb * dpb)
{
G_STATIC_ASSERT (sizeof (scaling_list->scaling_lists_32x32) ==
sizeof (h265_params->ScalingList32x32));
- g_return_val_if_fail (slice_header->pps != NULL, FALSE);
- g_return_val_if_fail (slice_header->pps->sps != NULL, FALSE);
+ g_return_val_if_fail (slice_header->pps != NULL, GST_FLOW_ERROR);
+ 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);
if (!frame) {
GST_ERROR_OBJECT (self,
"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_picture_params_from_sps (self, sps, h265_params);
if (!gst_nv_h265_dec_picture_params_from_pps (self, pps, h265_params)) {
GST_ERROR_OBJECT (self, "Couldn't copy pps");
- return FALSE;
+ return GST_FLOW_ERROR;
}
self->last_sps = sps;
self->last_pps = pps;
GST_DEBUG_OBJECT (self, "Update params from PPS");
if (!gst_nv_h265_dec_picture_params_from_pps (self, pps, h265_params)) {
GST_ERROR_OBJECT (self, "Couldn't copy pps");
- return FALSE;
+ return GST_FLOW_ERROR;
}
self->last_pps = pps;
} else {
if (decoder->NumPocStCurrBefore >
G_N_ELEMENTS (h265_params->RefPicSetStCurrBefore)) {
GST_ERROR_OBJECT (self, "Too many RefPicSetStCurrBefore");
- return FALSE;
+ return GST_FLOW_ERROR;
}
if (decoder->NumPocStCurrAfter >
G_N_ELEMENTS (h265_params->RefPicSetStCurrAfter)) {
GST_ERROR_OBJECT (self, "Too many RefPicSetStCurrAfter");
- return FALSE;
+ return GST_FLOW_ERROR;
}
if (decoder->NumPocLtCurr > G_N_ELEMENTS (h265_params->RefPicSetLtCurr)) {
GST_ERROR_OBJECT (self, "Too many RefPicSetLtCurr");
- return FALSE;
+ return GST_FLOW_ERROR;
}
/* Fill ref list */
if (num_ref_pic >= G_N_ELEMENTS (h265_params->RefPicIdx)) {
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);
if (!decoder->RefPicSetStCurrBefore[i]) {
GST_ERROR_OBJECT (self, "Empty RefPicSetStCurrBefore[%d]", i);
- return FALSE;
+ return GST_FLOW_ERROR;
}
other = decoder->RefPicSetStCurrBefore[i];
if (!decoder->RefPicSetStCurrAfter[i]) {
GST_ERROR_OBJECT (self, "Empty RefPicSetStCurrAfter[%d]", i);
- return FALSE;
+ return GST_FLOW_ERROR;
}
other = decoder->RefPicSetStCurrAfter[i];
if (!decoder->RefPicSetLtCurr[i]) {
GST_ERROR_OBJECT (self, "Empty RefPicSetLtCurr[%d]", i);
- return FALSE;
+ return GST_FLOW_ERROR;
}
other = decoder->RefPicSetLtCurr[i];
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,
GstH265Picture * picture, GstH265Slice * slice,
GArray * ref_pic_list0, GArray * ref_pic_list1)
slice->nalu.data + slice->nalu.offset, slice->nalu.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)
{
GstNvH265Dec *self = GST_NV_H265_DEC (decoder);
ret = gst_nv_decoder_decode_picture (self->decoder, &self->params);
- if (!ret)
+ if (!ret) {
GST_ERROR_OBJECT (self, "Failed to decode picture");
+ return GST_FLOW_ERROR;
+ }
- return ret;
+ return GST_FLOW_OK;
}
typedef struct