diff --git a/gst-libs/gst/video/gstvideodecoder.c b/gst-libs/gst/video/gstvideodecoder.c index f4b41364cd..5e87b3c058 100644 --- a/gst-libs/gst/video/gstvideodecoder.c +++ b/gst-libs/gst/video/gstvideodecoder.c @@ -988,6 +988,12 @@ gst_video_decoder_drain_out (GstVideoDecoder * dec, gboolean at_eos) if (at_eos) { if (decoder_class->finish) ret = decoder_class->finish (dec); + } else { + if (decoder_class->drain) { + ret = decoder_class->drain (dec); + } else { + GST_FIXME_OBJECT (dec, "Sub-class should implement drain()"); + } } } else { /* Reverse playback mode */ @@ -2115,10 +2121,17 @@ gst_video_decoder_flush_parse (GstVideoDecoder * dec, gboolean at_eos) if (res != GST_FLOW_OK) goto done; - /* We need to tell the subclass to drain now */ - GST_DEBUG_OBJECT (dec, "Finishing"); - if (decoder_class->finish) + /* We need to tell the subclass to drain now. + * We prefer the drain vfunc, but for backward-compat + * we use a finish() vfunc if drain isn't implemented */ + if (decoder_class->drain) { + GST_DEBUG_OBJECT (dec, "Draining"); + res = decoder_class->drain (dec); + } else if (decoder_class->finish) { + GST_FIXME_OBJECT (dec, "Sub-class should implement drain(). " + "Calling finish() for backwards-compat"); res = decoder_class->finish (dec); + } if (res != GST_FLOW_OK) goto done; diff --git a/gst-libs/gst/video/gstvideodecoder.h b/gst-libs/gst/video/gstvideodecoder.h index 6e79497a5b..d9aa736216 100644 --- a/gst-libs/gst/video/gstvideodecoder.h +++ b/gst-libs/gst/video/gstvideodecoder.h @@ -215,8 +215,12 @@ struct _GstVideoDecoder * @handle_frame: Provides input data frame to subclass. * @finish: Optional. * Called to request subclass to dispatch any pending remaining - * data (e.g. at EOS or segment end). Sub-classes should be prepared - * to handle new data afterward, or seamless segment processing will break. + * data at EOS. Sub-classes can refuse to decode new data after. + * @drain: Optional. + * Called to request subclass to decode any data it can at this + * point, but that more data may arrive after. (e.g. at segment end). + * Sub-classes should be prepared to handle new data afterward, + * or seamless segment processing will break. Since: 1.6 * @sink_event: Optional. * Event handler on the sink pad. This function should return * TRUE if the event was handled and should be discarded @@ -320,9 +324,10 @@ struct _GstVideoDecoderClass GstCaps* (*getcaps) (GstVideoDecoder *decoder, GstCaps *filter); + GstFlowReturn (*drain) (GstVideoDecoder *decoder); /*< private >*/ - void *padding[GST_PADDING_LARGE-4]; + void *padding[GST_PADDING_LARGE-5]; }; GType gst_video_decoder_get_type (void);