baseparse: replace set_seek() with _set_average_bitrate() and FLAG_SYNCABLE

This makes more sense conceptually, since the bitrate may be used
to estimate a seek position if there's no seek table or just for
duration reporting/estimation if we can't seek. Also, even if the
format is not syncable, we could still seek by pushing data from the
start and using the segment to make downstream clip.

https://bugzilla.gnome.org/show_bug.cgi?id=518857
This commit is contained in:
Tim-Philipp Müller 2011-03-31 14:48:47 +01:00
parent de16d5adb3
commit 4709a26473
2 changed files with 28 additions and 38 deletions

View file

@ -233,7 +233,6 @@ struct _GstBaseParsePrivate
guint bitrate;
guint lead_in, lead_out;
GstClockTime lead_in_ts, lead_out_ts;
GstBaseParseSeekable seekable;
gboolean discont;
gboolean flushing;
@ -397,6 +396,8 @@ static GstFlowReturn gst_base_parse_locate_time (GstBaseParse * parse,
static GstFlowReturn gst_base_parse_process_fragment (GstBaseParse * parse,
gboolean push_only);
static gboolean gst_base_parse_is_seekable (GstBaseParse * parse);
static void
gst_base_parse_clear_queues (GstBaseParse * parse)
{
@ -587,7 +588,6 @@ gst_base_parse_reset (GstBaseParse * parse)
parse->priv->frame_duration = GST_CLOCK_TIME_NONE;
parse->priv->lead_in = parse->priv->lead_out = 0;
parse->priv->lead_in_ts = parse->priv->lead_out_ts = 0;
parse->priv->seekable = GST_BASE_PARSE_SEEK_DEFAULT;
parse->priv->bitrate = 0;
parse->priv->framecount = 0;
parse->priv->bytecount = 0;
@ -596,7 +596,7 @@ gst_base_parse_reset (GstBaseParse * parse)
parse->priv->first_frame_offset = -1;
parse->priv->estimated_duration = -1;
parse->priv->next_ts = 0;
parse->priv->format_flags = 0;
parse->priv->format_flags = GST_BASE_PARSE_FORMAT_FLAG_SYNCABLE;
parse->priv->post_min_bitrate = TRUE;
parse->priv->post_avg_bitrate = TRUE;
parse->priv->post_max_bitrate = TRUE;
@ -1006,6 +1006,13 @@ gst_base_parse_src_event (GstPad * pad, GstEvent * event)
return ret;
}
static gboolean
gst_base_parse_is_seekable (GstBaseParse * parse)
{
/* FIXME: could do more here, e.g. check index or just send data from 0
* in pull mode and let decoder/sink clip */
return (parse->priv->format_flags & GST_BASE_PARSE_FORMAT_FLAG_SYNCABLE);
}
/**
* gst_base_parse_src_eventfunc:
@ -1024,7 +1031,7 @@ gst_base_parse_src_eventfunc (GstBaseParse * parse, GstEvent * event)
switch (GST_EVENT_TYPE (event)) {
case GST_EVENT_SEEK:
{
if (parse->priv->seekable > GST_BASE_PARSE_SEEK_NONE) {
if (gst_base_parse_is_seekable (parse)) {
handled = gst_base_parse_handle_seek (parse, event);
}
break;
@ -2776,28 +2783,25 @@ exit:
}
/**
* gst_base_parse_set_seek:
* gst_base_parse_set_average_bitrate:
* @parse: #GstBaseParse.
* @seek: #GstBaseParseSeekable.
* @abitrate: average bitrate.
* @abitrate: average bitrate in bits/second
*
* Sets whether and how the media is seekable (in time).
* Also optionally provides average bitrate detected in media (if non-zero),
* Optionally sets the 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.
* By default, announced average bitrate is estimated. The average bitrate
* is used to estimate the total duration of the stream and to estimate
* a seek position, if there's no index and #GST_BASE_PARSE_FORMAT_FLAG_SYNCABLE
* is set.
*/
void
gst_base_parse_set_seek (GstBaseParse * parse,
GstBaseParseSeekable seek, guint bitrate)
gst_base_parse_set_average_bitrate (GstBaseParse * parse, guint bitrate)
{
parse->priv->seekable = seek;
parse->priv->bitrate = bitrate;
GST_DEBUG_OBJECT (parse, "seek %d, bitrate %d", seek, bitrate);
GST_DEBUG_OBJECT (parse, "bitrate %u", bitrate);
}
/**
* gst_base_parse_set_min_frame_size:
* @parse: #GstBaseParse.
@ -3019,8 +3023,7 @@ 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 &&
parse->priv->seekable > GST_BASE_PARSE_SEEK_NONE) {
if (fmt == GST_FORMAT_TIME && gst_base_parse_is_seekable (parse)) {
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

@ -141,7 +141,7 @@ typedef struct {
/**
* GstBaseParseFormatFlags:
* @GST_BASE_PARSE_FORMAT_FLAG_NONE: default setting
* @GST_BASE_PARSE_FORMAT_FLAG_NONE: no flags active
* @GST_BASE_PARSE_FORMAT_FLAG_PASSTHROUGH: nature of format or configuration
* does not allow (much) parsing, so parser should operate in passthrough mode
* (which only applies operating in pull mode). That is, incoming buffers
@ -152,6 +152,9 @@ typedef struct {
* @GST_BASE_PARSE_FORMAT_FLAG_HAS_TIME: frames carry timing info which subclass
* can (generally) parse and provide. In particular, intrinsic time
* (rather than estimated) can be obtained following a seek.
* @GST_BASE_PARSE_FORMAT_FLAG_SYNCABLE: frame starts can be identified. This
* set by default, and determines whether seeking based on bitrate averages
* is possible for a format/stream.
*
* Since: 0.10.x
*/
@ -159,24 +162,9 @@ typedef enum {
GST_BASE_PARSE_FORMAT_FLAG_NONE = 0,
GST_BASE_PARSE_FORMAT_FLAG_PASSTHROUGH = (1 << 0),
GST_BASE_PARSE_FORMAT_FLAG_HAS_TIME = (1 << 1),
GST_BASE_PARSE_FORMAT_FLAG_SYNCABLE = (1 << 2)
} GstBaseParseFormatFlags;
/**
* 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.
*
* Since: 0.10.x
*/
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;
@ -291,9 +279,8 @@ void gst_base_parse_set_duration (GstBaseParse * parse,
gint64 duration,
gint interval);
void gst_base_parse_set_seek (GstBaseParse * parse,
GstBaseParseSeekable seek,
guint bitrate);
void gst_base_parse_set_average_bitrate (GstBaseParse * parse,
guint bitrate);
void gst_base_parse_set_min_frame_size (GstBaseParse * parse,
guint min_size);