baseparse: remove is_seekable vmethod and use a set_seek instead

Seekability, like duration, etc is unlikely to change (frequently), and
the default assumption covers most cases, so let subclass set when needed.
At the same time, allow subclass to indicate if it has seek-metadata (table)
available, and possibly have it provide an average bitrate.
This commit is contained in:
Mark Nauwelaerts 2010-09-17 18:24:22 +02:00 committed by Tim-Philipp Müller
parent 10611c2826
commit 0198d6320b
3 changed files with 55 additions and 49 deletions

View file

@ -95,8 +95,6 @@ gboolean gst_aacparse_convert (GstBaseParse * parse,
GstFormat src_format,
gint64 src_value, GstFormat dest_format, gint64 * dest_value);
gboolean gst_aacparse_is_seekable (GstBaseParse * parse);
gint gst_aacparse_get_frame_overhead (GstBaseParse * parse, GstBuffer * buffer);
gboolean gst_aacparse_event (GstBaseParse * parse, GstEvent * event);
@ -158,7 +156,6 @@ gst_aacparse_class_init (GstAacParseClass * klass)
parse_class->start = GST_DEBUG_FUNCPTR (gst_aacparse_start);
parse_class->stop = GST_DEBUG_FUNCPTR (gst_aacparse_stop);
parse_class->set_sink_caps = GST_DEBUG_FUNCPTR (gst_aacparse_sink_setcaps);
parse_class->is_seekable = GST_DEBUG_FUNCPTR (gst_aacparse_is_seekable);
parse_class->parse_frame = GST_DEBUG_FUNCPTR (gst_aacparse_parse_frame);
parse_class->check_valid_frame =
GST_DEBUG_FUNCPTR (gst_aacparse_check_valid_frame);
@ -492,6 +489,10 @@ gst_aacparse_detect_stream (GstAacParse * aacparse,
aacparse->header_type = DSPAAC_HEADER_ADIF;
aacparse->mpegversion = 4;
/* no way to seek this */
gst_base_parse_set_seek (GST_BASE_PARSE (aacparse),
GST_BASE_PARSE_SEEK_NONE, 0);
/* Skip the "ADIF" bytes */
adif = data + i + 4;
@ -688,27 +689,6 @@ gst_aacparse_stop (GstBaseParse * parse)
}
/**
* gst_aacparse_is_seekable:
* @parse: #GstBaseParse.
*
* Implementation of "is_seekable" vmethod in #GstBaseParse class.
*
* Returns: TRUE if the current stream is seekable.
*/
gboolean
gst_aacparse_is_seekable (GstBaseParse * parse)
{
GstAacParse *aacparse;
aacparse = GST_AACPARSE (parse);
GST_DEBUG_OBJECT (aacparse, "IS_SEEKABLE: %d",
aacparse->header_type != DSPAAC_HEADER_ADIF);
/* Not seekable if ADIF header is found */
return (aacparse->header_type != DSPAAC_HEADER_ADIF);
}
/**
* gst_aacparse_get_frame_overhead:
* @parse: #GstBaseParse.

View file

@ -218,6 +218,8 @@ struct _GstBaseParsePrivate
gboolean passthrough;
guint fps_num, fps_den;
guint update_interval;
guint bitrate;
GstBaseParseSeekable seekable;
gboolean discont;
gboolean flushing;
@ -307,8 +309,6 @@ static gboolean gst_base_parse_sink_eventfunc (GstBaseParse * parse,
static gboolean gst_base_parse_src_eventfunc (GstBaseParse * parse,
GstEvent * event);
static gboolean gst_base_parse_is_seekable (GstBaseParse * parse);
static void gst_base_parse_drain (GstBaseParse * parse);
static void gst_base_parse_post_bitrates (GstBaseParse * parse,
@ -359,7 +359,6 @@ gst_base_parse_class_init (GstBaseParseClass * klass)
klass->check_valid_frame = gst_base_parse_check_frame;
klass->parse_frame = gst_base_parse_parse_frame;
klass->src_event = gst_base_parse_src_eventfunc;
klass->is_seekable = gst_base_parse_is_seekable;
klass->convert = gst_base_parse_convert_default;
GST_DEBUG_CATEGORY_INIT (gst_base_parse_debug, "baseparse", 0,
@ -752,7 +751,7 @@ gst_base_parse_src_eventfunc (GstBaseParse * parse, GstEvent * event)
switch (GST_EVENT_TYPE (event)) {
case GST_EVENT_SEEK:
{
if (bclass->is_seekable (parse)) {
if (parse->priv->seekable > GST_BASE_PARSE_SEEK_NONE) {
handled = gst_base_parse_handle_seek (parse, event);
}
break;
@ -764,20 +763,6 @@ gst_base_parse_src_eventfunc (GstBaseParse * parse, GstEvent * event)
}
/**
* gst_base_parse_is_seekable:
* @parse: #GstBaseParse.
*
* Default handler for is_seekable.
*
* Returns: Always TRUE.
*/
static gboolean
gst_base_parse_is_seekable (GstBaseParse * parse)
{
return TRUE;
}
/**
* gst_base_parse_convert_default:
* @parse: #GstBaseParse.
@ -965,6 +950,11 @@ gst_base_parse_update_bitrates (GstBaseParse * parse, GstBuffer * buffer)
return;
}
/* override if subclass provided bitrate, e.g. metadata based */
if (parse->priv->bitrate) {
parse->priv->avg_bitrate = parse->priv->bitrate;
}
frame_bitrate = (8 * data_len * GST_SECOND) / frame_dur;
if (frame_bitrate < parse->priv->min_bitrate) {
@ -1628,6 +1618,8 @@ gst_base_parse_activate (GstBaseParse * parse, gboolean active)
parse->priv->update_interval = 0;
parse->priv->fps_num = parse->priv->fps_den = 0;
parse->priv->frame_duration = GST_CLOCK_TIME_NONE;
parse->priv->seekable = GST_BASE_PARSE_SEEK_DEFAULT;
parse->priv->bitrate = 0;
parse->priv->framecount = 0;
parse->priv->bytecount = 0;
parse->priv->acc_duration = 0;
@ -1773,6 +1765,27 @@ gst_base_parse_set_duration (GstBaseParse * parse,
GST_BASE_PARSE_UNLOCK (parse);
}
/**
* gst_base_parse_set_seek:
* @parse: #GstBaseParse.
* @seek: #GstBaseParseSeekable.
* @abitrate: average bitrate.
*
* Sets whether and how the media is seekable (in time).
* Also optionally provides average bitrate detected in media (if non-zero),
* e.g. based on metadata, as it will be posted to the application.
*
* By default, announced average bitrate is estimated, and seekability is assumed
* possible based on estimated bitrate.
*/
void
gst_base_parse_set_seek (GstBaseParse * parse,
GstBaseParseSeekable seek, guint bitrate)
{
parse->priv->seekable = seek;
parse->priv->bitrate = bitrate;
}
/**
* gst_base_parse_set_min_frame_size:
@ -2038,7 +2051,8 @@ gst_base_parse_query (GstPad * pad, GstQuery * query)
res = gst_pad_query_default (pad, query);
/* we may be able to help if in TIME */
if (fmt == GST_FORMAT_TIME && klass->is_seekable (parse)) {
if (fmt == GST_FORMAT_TIME &&
parse->priv->seekable > GST_BASE_PARSE_SEEK_NONE) {
gst_query_parse_seeking (query, &fmt, &seekable, NULL, NULL);
/* already OK if upstream takes care */
GST_LOG_OBJECT (parse, "upstream handled %d, seekable %d",

View file

@ -130,6 +130,21 @@ G_BEGIN_DECLS
*/
#define GST_BASE_PARSE_UNLOCK(obj) g_mutex_unlock (GST_BASE_PARSE_CAST (obj)->parse_lock)
/**
* GstBaseParseSeekable:
* @GST_BASE_PARSE_SEEK_NONE: No seeking possible.
* GST_BASE_PARSE_SEEK_DEFAULT: Default seeking possible using estimated bitrate.
* GST_BASE_PARSE_SEEK_TABLE: Additional metadata provides more accurate seeking.
*
* Indicates what level (of quality) of seeking is possible.
*/
typedef enum _GstBaseParseSeekable {
GST_BASE_PARSE_SEEK_NONE,
GST_BASE_PARSE_SEEK_DEFAULT,
GST_BASE_PARSE_SEEK_TABLE
} GstBaseParseSeekable;
typedef struct _GstBaseParse GstBaseParse;
typedef struct _GstBaseParseClass GstBaseParseClass;
typedef struct _GstBaseParsePrivate GstBaseParsePrivate;
@ -196,10 +211,6 @@ struct _GstBaseParse {
* @src_event: Optional.
* Event handler on the source pad. Should return TRUE
* if the event was handled and can be dropped.
* @is_seekable: Optional.
* Subclass can override this if it wants to control the
* seekability of the stream. Otherwise the element assumes
* that stream is always seekable.
*
* @get_frame_overhead: Finds the metadata overhead for the given frame. This
* is used to enable more accurate bitrate computations.
@ -256,8 +267,6 @@ struct _GstBaseParseClass {
gboolean (*src_event) (GstBaseParse *parse,
GstEvent *event);
gboolean (*is_seekable) (GstBaseParse *parse);
gint (*get_frame_overhead) (GstBaseParse *parse,
GstBuffer *buf);
@ -278,6 +287,9 @@ void gst_base_parse_set_duration (GstBaseParse *parse,
GstFormat fmt,
gint64 duration);
void gst_base_parse_set_seek (GstBaseParse * parse,
GstBaseParseSeekable seek, guint bitrate);
void gst_base_parse_set_min_frame_size (GstBaseParse *parse,
guint min_size);
void gst_base_parse_set_passthrough (GstBaseParse * parse, gboolean passthrough);