From 23bb84c868cf7039fa39754cc821e87702b5687c Mon Sep 17 00:00:00 2001 From: Haakon Sporsheim Date: Mon, 23 Jun 2014 08:46:37 +0200 Subject: vpxdec: request a sync point on decoder errors Part-of: --- ext/vpx/gstvp8dec.c | 9 +++++++++ ext/vpx/gstvp9dec.c | 9 +++++++++ ext/vpx/gstvpxdec.c | 23 +++++++++++++++++++++-- ext/vpx/gstvpxdec.h | 5 +++++ 4 files changed, 44 insertions(+), 2 deletions(-) (limited to 'ext/vpx') diff --git a/ext/vpx/gstvp8dec.c b/ext/vpx/gstvp8dec.c index 8aea6aced..65ed836ca 100644 --- a/ext/vpx/gstvp8dec.c +++ b/ext/vpx/gstvp8dec.c @@ -59,6 +59,7 @@ static void gst_vp8_dec_set_default_format (GstVPXDec * dec, GstVideoFormat fmt, int width, int height); static void gst_vp8_dec_handle_resolution_change (GstVPXDec * dec, vpx_image_t * img, GstVideoFormat fmt); +static gboolean gst_vp8_dec_get_needs_sync_point (GstVPXDec * dec); static GstStaticPadTemplate gst_vp8_dec_sink_template = GST_STATIC_PAD_TEMPLATE ("sink", @@ -103,6 +104,8 @@ gst_vp8_dec_class_init (GstVP8DecClass * klass) GST_DEBUG_FUNCPTR (gst_vp8_dec_set_default_format); vpx_class->handle_resolution_change = GST_DEBUG_FUNCPTR (gst_vp8_dec_handle_resolution_change); + vpx_class->get_needs_sync_point = + GST_DEBUG_FUNCPTR (gst_vp8_dec_get_needs_sync_point); GST_DEBUG_CATEGORY_INIT (gst_vp8dec_debug, "vp8dec", 0, "VP8 Decoder"); } @@ -153,4 +156,10 @@ gst_vp8_dec_handle_resolution_change (GstVPXDec * dec, vpx_image_t * img, } } +static gboolean +gst_vp8_dec_get_needs_sync_point (GstVPXDec * dec) +{ + return FALSE; +} + #endif /* HAVE_VP8_DECODER */ diff --git a/ext/vpx/gstvp9dec.c b/ext/vpx/gstvp9dec.c index 8687d1dad..a80ef917d 100644 --- a/ext/vpx/gstvp9dec.c +++ b/ext/vpx/gstvp9dec.c @@ -61,6 +61,7 @@ static gboolean gst_vp9_dec_get_valid_format (GstVPXDec * dec, vpx_image_t * img, GstVideoFormat * fmt); static void gst_vp9_dec_handle_resolution_change (GstVPXDec * dec, vpx_image_t * img, GstVideoFormat fmt); +static gboolean gst_vp9_dec_get_needs_sync_point (GstVPXDec * dec); static GstStaticPadTemplate gst_vp9_dec_sink_template = GST_STATIC_PAD_TEMPLATE ("sink", @@ -107,6 +108,8 @@ gst_vp9_dec_class_init (GstVP9DecClass * klass) GST_DEBUG_FUNCPTR (gst_vp9_dec_get_valid_format); vpx_class->handle_resolution_change = GST_DEBUG_FUNCPTR (gst_vp9_dec_handle_resolution_change); + vpx_class->get_needs_sync_point = + GST_DEBUG_FUNCPTR (gst_vp9_dec_get_needs_sync_point); GST_DEBUG_CATEGORY_INIT (gst_vp9dec_debug, "vp9dec", 0, "VP9 Decoder"); } @@ -223,4 +226,10 @@ gst_vp9_dec_handle_resolution_change (GstVPXDec * dec, vpx_image_t * img, } } +static gboolean +gst_vp9_dec_get_needs_sync_point (GstVPXDec * dec) +{ + return TRUE; +} + #endif /* HAVE_VP9_DECODER */ diff --git a/ext/vpx/gstvpxdec.c b/ext/vpx/gstvpxdec.c index e92aa85c7..19a24870c 100644 --- a/ext/vpx/gstvpxdec.c +++ b/ext/vpx/gstvpxdec.c @@ -197,6 +197,7 @@ static void gst_vpx_dec_init (GstVPXDec * gst_vpx_dec) { GstVideoDecoder *decoder = (GstVideoDecoder *) gst_vpx_dec; + GstVPXDecClass *vpxclass = GST_VPX_DEC_GET_CLASS (gst_vpx_dec); GST_DEBUG_OBJECT (gst_vpx_dec, "gst_vpx_dec_init"); gst_video_decoder_set_packetized (decoder, TRUE); @@ -205,6 +206,11 @@ gst_vpx_dec_init (GstVPXDec * gst_vpx_dec) gst_vpx_dec->deblocking_level = DEFAULT_DEBLOCKING_LEVEL; gst_vpx_dec->noise_level = DEFAULT_NOISE_LEVEL; + if (vpxclass->get_needs_sync_point) { + gst_video_decoder_set_needs_sync_point (GST_VIDEO_DECODER (gst_vpx_dec), + vpxclass->get_needs_sync_point (gst_vpx_dec)); + } + gst_video_decoder_set_needs_format (decoder, TRUE); gst_video_decoder_set_use_default_pad_acceptcaps (decoder, TRUE); GST_PAD_SET_ACCEPT_TEMPLATE (GST_VIDEO_DECODER_SINK_PAD (decoder)); @@ -581,12 +587,12 @@ gst_vpx_dec_open_codec (GstVPXDec * dec, GstVideoCodecFrame * frame) gst_buffer_unmap (frame->input_buffer, &minfo); if (status != VPX_CODEC_OK) { - GST_WARNING_OBJECT (dec, "VPX preprocessing error: %s", + GST_INFO_OBJECT (dec, "VPX preprocessing error: %s", gst_vpx_error_name (status)); return GST_FLOW_CUSTOM_SUCCESS_1; } if (!stream_info.is_kf) { - GST_WARNING_OBJECT (dec, "No keyframe, skipping"); + GST_INFO_OBJECT (dec, "No keyframe, skipping"); return GST_FLOW_CUSTOM_SUCCESS_1; } if (stream_info.w == 0 || stream_info.h == 0) { @@ -672,6 +678,12 @@ gst_vpx_dec_handle_frame (GstVideoDecoder * decoder, GstVideoCodecFrame * frame) if (!dec->decoder_inited) { ret = vpxclass->open_codec (dec, frame); if (ret == GST_FLOW_CUSTOM_SUCCESS_1) { + GstVideoDecoderRequestSyncPointFlags flags = 0; + + if (gst_video_decoder_get_needs_sync_point (decoder)) + flags |= GST_VIDEO_DECODER_REQUEST_SYNC_POINT_DISCARD_INPUT; + + gst_video_decoder_request_sync_point (decoder, frame, flags); gst_video_decoder_drop_frame (decoder, frame); return GST_FLOW_OK; } else if (ret != GST_FLOW_OK) { @@ -701,8 +713,15 @@ gst_vpx_dec_handle_frame (GstVideoDecoder * decoder, GstVideoCodecFrame * frame) gst_buffer_unmap (frame->input_buffer, &minfo); if (status) { + GstVideoDecoderRequestSyncPointFlags flags = 0; + GST_VIDEO_DECODER_ERROR (decoder, 1, LIBRARY, ENCODE, ("Failed to decode frame"), ("%s", gst_vpx_error_name (status)), ret); + + if (gst_video_decoder_get_needs_sync_point (decoder)) + flags |= GST_VIDEO_DECODER_REQUEST_SYNC_POINT_DISCARD_INPUT; + + gst_video_decoder_request_sync_point (decoder, frame, flags); gst_video_codec_frame_unref (frame); return ret; } diff --git a/ext/vpx/gstvpxdec.h b/ext/vpx/gstvpxdec.h index 36b3c272e..35ea4289b 100644 --- a/ext/vpx/gstvpxdec.h +++ b/ext/vpx/gstvpxdec.h @@ -102,6 +102,11 @@ struct _GstVPXDecClass void (*handle_resolution_change) (GstVPXDec *dec, vpx_image_t *img, GstVideoFormat fmt); /*virtual function to check valid format*/ gboolean (*get_frame_format)(GstVPXDec *dec, vpx_image_t *img, GstVideoFormat* fmt); + /* virtual function to check whether the decoder can handle data + * before receiving a sync_point, either at the start of after a + * decoding error + */ + gboolean (*get_needs_sync_point)(GstVPXDec *dec); }; GType gst_vpx_dec_get_type (void); -- cgit v1.2.1