mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-02-17 03:35:21 +00:00
vpxdec: request a sync point on decoder errors
Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-good/-/merge_requests/725>
This commit is contained in:
parent
5340de5c33
commit
23bb84c868
4 changed files with 44 additions and 2 deletions
|
@ -59,6 +59,7 @@ static void gst_vp8_dec_set_default_format (GstVPXDec * dec, GstVideoFormat fmt,
|
||||||
int width, int height);
|
int width, int height);
|
||||||
static void gst_vp8_dec_handle_resolution_change (GstVPXDec * dec,
|
static void gst_vp8_dec_handle_resolution_change (GstVPXDec * dec,
|
||||||
vpx_image_t * img, GstVideoFormat fmt);
|
vpx_image_t * img, GstVideoFormat fmt);
|
||||||
|
static gboolean gst_vp8_dec_get_needs_sync_point (GstVPXDec * dec);
|
||||||
|
|
||||||
static GstStaticPadTemplate gst_vp8_dec_sink_template =
|
static GstStaticPadTemplate gst_vp8_dec_sink_template =
|
||||||
GST_STATIC_PAD_TEMPLATE ("sink",
|
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);
|
GST_DEBUG_FUNCPTR (gst_vp8_dec_set_default_format);
|
||||||
vpx_class->handle_resolution_change =
|
vpx_class->handle_resolution_change =
|
||||||
GST_DEBUG_FUNCPTR (gst_vp8_dec_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");
|
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 */
|
#endif /* HAVE_VP8_DECODER */
|
||||||
|
|
|
@ -61,6 +61,7 @@ static gboolean gst_vp9_dec_get_valid_format (GstVPXDec * dec,
|
||||||
vpx_image_t * img, GstVideoFormat * fmt);
|
vpx_image_t * img, GstVideoFormat * fmt);
|
||||||
static void gst_vp9_dec_handle_resolution_change (GstVPXDec * dec,
|
static void gst_vp9_dec_handle_resolution_change (GstVPXDec * dec,
|
||||||
vpx_image_t * img, GstVideoFormat fmt);
|
vpx_image_t * img, GstVideoFormat fmt);
|
||||||
|
static gboolean gst_vp9_dec_get_needs_sync_point (GstVPXDec * dec);
|
||||||
|
|
||||||
static GstStaticPadTemplate gst_vp9_dec_sink_template =
|
static GstStaticPadTemplate gst_vp9_dec_sink_template =
|
||||||
GST_STATIC_PAD_TEMPLATE ("sink",
|
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);
|
GST_DEBUG_FUNCPTR (gst_vp9_dec_get_valid_format);
|
||||||
vpx_class->handle_resolution_change =
|
vpx_class->handle_resolution_change =
|
||||||
GST_DEBUG_FUNCPTR (gst_vp9_dec_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");
|
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 */
|
#endif /* HAVE_VP9_DECODER */
|
||||||
|
|
|
@ -197,6 +197,7 @@ static void
|
||||||
gst_vpx_dec_init (GstVPXDec * gst_vpx_dec)
|
gst_vpx_dec_init (GstVPXDec * gst_vpx_dec)
|
||||||
{
|
{
|
||||||
GstVideoDecoder *decoder = (GstVideoDecoder *) 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_DEBUG_OBJECT (gst_vpx_dec, "gst_vpx_dec_init");
|
||||||
gst_video_decoder_set_packetized (decoder, TRUE);
|
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->deblocking_level = DEFAULT_DEBLOCKING_LEVEL;
|
||||||
gst_vpx_dec->noise_level = DEFAULT_NOISE_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_needs_format (decoder, TRUE);
|
||||||
gst_video_decoder_set_use_default_pad_acceptcaps (decoder, TRUE);
|
gst_video_decoder_set_use_default_pad_acceptcaps (decoder, TRUE);
|
||||||
GST_PAD_SET_ACCEPT_TEMPLATE (GST_VIDEO_DECODER_SINK_PAD (decoder));
|
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);
|
gst_buffer_unmap (frame->input_buffer, &minfo);
|
||||||
|
|
||||||
if (status != VPX_CODEC_OK) {
|
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));
|
gst_vpx_error_name (status));
|
||||||
return GST_FLOW_CUSTOM_SUCCESS_1;
|
return GST_FLOW_CUSTOM_SUCCESS_1;
|
||||||
}
|
}
|
||||||
if (!stream_info.is_kf) {
|
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;
|
return GST_FLOW_CUSTOM_SUCCESS_1;
|
||||||
}
|
}
|
||||||
if (stream_info.w == 0 || stream_info.h == 0) {
|
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) {
|
if (!dec->decoder_inited) {
|
||||||
ret = vpxclass->open_codec (dec, frame);
|
ret = vpxclass->open_codec (dec, frame);
|
||||||
if (ret == GST_FLOW_CUSTOM_SUCCESS_1) {
|
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);
|
gst_video_decoder_drop_frame (decoder, frame);
|
||||||
return GST_FLOW_OK;
|
return GST_FLOW_OK;
|
||||||
} else if (ret != 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);
|
gst_buffer_unmap (frame->input_buffer, &minfo);
|
||||||
|
|
||||||
if (status) {
|
if (status) {
|
||||||
|
GstVideoDecoderRequestSyncPointFlags flags = 0;
|
||||||
|
|
||||||
GST_VIDEO_DECODER_ERROR (decoder, 1, LIBRARY, ENCODE,
|
GST_VIDEO_DECODER_ERROR (decoder, 1, LIBRARY, ENCODE,
|
||||||
("Failed to decode frame"), ("%s", gst_vpx_error_name (status)), ret);
|
("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);
|
gst_video_codec_frame_unref (frame);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
|
@ -102,6 +102,11 @@ struct _GstVPXDecClass
|
||||||
void (*handle_resolution_change) (GstVPXDec *dec, vpx_image_t *img, GstVideoFormat fmt);
|
void (*handle_resolution_change) (GstVPXDec *dec, vpx_image_t *img, GstVideoFormat fmt);
|
||||||
/*virtual function to check valid format*/
|
/*virtual function to check valid format*/
|
||||||
gboolean (*get_frame_format)(GstVPXDec *dec, vpx_image_t *img, GstVideoFormat* fmt);
|
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);
|
GType gst_vpx_dec_get_type (void);
|
||||||
|
|
Loading…
Reference in a new issue