mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-02-02 20:42:30 +00:00
decoder: allow frames to be dropped.
If the decoder was not able to decode a frame because insufficient information was available, e.g. missing sequence or picture header, then allow the frame to be gracefully dropped without generating any error. It is also possible that a frame is not meant to be displayed but only used as a reference, so dropping that frame is also a valid operation since GstVideoDecoder base class has extra references to that GstVideoCodecFrame that needs to be released.
This commit is contained in:
parent
41dcd82e2f
commit
2305b0db46
2 changed files with 35 additions and 0 deletions
|
@ -48,6 +48,9 @@ enum {
|
|||
|
||||
static GParamSpec *g_properties[N_PROPERTIES] = { NULL, };
|
||||
|
||||
static void
|
||||
drop_frame(GstVaapiDecoder *decoder, GstVideoCodecFrame *frame);
|
||||
|
||||
static void
|
||||
parser_state_finalize(GstVaapiParserState *ps)
|
||||
{
|
||||
|
@ -246,6 +249,10 @@ do_decode_1(GstVaapiDecoder *decoder, GstVaapiDecoderFrame *frame)
|
|||
if (status != GST_VAAPI_DECODER_STATUS_SUCCESS)
|
||||
return status;
|
||||
}
|
||||
|
||||
/* Drop frame if there is no slice data unit in there */
|
||||
if (G_UNLIKELY(frame->units->len == 0))
|
||||
return GST_VAAPI_DECODER_STATUS_DROP_FRAME;
|
||||
return GST_VAAPI_DECODER_STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
|
@ -261,6 +268,13 @@ do_decode(GstVaapiDecoder *decoder, GstVideoCodecFrame *base_frame)
|
|||
gst_vaapi_decoder_frame_ref(frame);
|
||||
status = do_decode_1(decoder, frame);
|
||||
gst_vaapi_decoder_frame_unref(frame);
|
||||
|
||||
switch ((guint)status) {
|
||||
case GST_VAAPI_DECODER_STATUS_DROP_FRAME:
|
||||
drop_frame(decoder, base_frame);
|
||||
status = GST_VAAPI_DECODER_STATUS_SUCCESS;
|
||||
break;
|
||||
}
|
||||
return status;
|
||||
}
|
||||
|
||||
|
@ -351,6 +365,23 @@ decode_step(GstVaapiDecoder *decoder)
|
|||
return status;
|
||||
}
|
||||
|
||||
static void
|
||||
drop_frame(GstVaapiDecoder *decoder, GstVideoCodecFrame *frame)
|
||||
{
|
||||
GstVaapiDecoderPrivate * const priv = decoder->priv;
|
||||
|
||||
GST_DEBUG("drop frame %d", frame->system_frame_number);
|
||||
|
||||
/* no surface proxy */
|
||||
gst_video_codec_frame_set_user_data(frame, NULL, NULL);
|
||||
|
||||
frame->pts = GST_CLOCK_TIME_NONE;
|
||||
GST_VIDEO_CODEC_FRAME_FLAG_SET(frame,
|
||||
GST_VIDEO_CODEC_FRAME_FLAG_DECODE_ONLY);
|
||||
|
||||
g_queue_push_tail(priv->frames, gst_video_codec_frame_ref(frame));
|
||||
}
|
||||
|
||||
static inline void
|
||||
push_frame(GstVaapiDecoder *decoder, GstVideoCodecFrame *frame)
|
||||
{
|
||||
|
|
|
@ -145,6 +145,10 @@ G_BEGIN_DECLS
|
|||
GST_VAAPI_TYPE_DECODER, \
|
||||
GstVaapiDecoderPrivate))
|
||||
|
||||
typedef enum {
|
||||
GST_VAAPI_DECODER_STATUS_DROP_FRAME = -2
|
||||
} GstVaapiDecoderStatusPrivate;
|
||||
|
||||
typedef struct _GstVaapiParserState GstVaapiParserState;
|
||||
struct _GstVaapiParserState {
|
||||
GstVideoCodecFrame *current_frame;
|
||||
|
|
Loading…
Reference in a new issue