mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-04-26 06:54:49 +00:00
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:
parent
de16d5adb3
commit
4709a26473
2 changed files with 28 additions and 38 deletions
|
@ -233,7 +233,6 @@ struct _GstBaseParsePrivate
|
||||||
guint bitrate;
|
guint bitrate;
|
||||||
guint lead_in, lead_out;
|
guint lead_in, lead_out;
|
||||||
GstClockTime lead_in_ts, lead_out_ts;
|
GstClockTime lead_in_ts, lead_out_ts;
|
||||||
GstBaseParseSeekable seekable;
|
|
||||||
|
|
||||||
gboolean discont;
|
gboolean discont;
|
||||||
gboolean flushing;
|
gboolean flushing;
|
||||||
|
@ -397,6 +396,8 @@ static GstFlowReturn gst_base_parse_locate_time (GstBaseParse * parse,
|
||||||
static GstFlowReturn gst_base_parse_process_fragment (GstBaseParse * parse,
|
static GstFlowReturn gst_base_parse_process_fragment (GstBaseParse * parse,
|
||||||
gboolean push_only);
|
gboolean push_only);
|
||||||
|
|
||||||
|
static gboolean gst_base_parse_is_seekable (GstBaseParse * parse);
|
||||||
|
|
||||||
static void
|
static void
|
||||||
gst_base_parse_clear_queues (GstBaseParse * parse)
|
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->frame_duration = GST_CLOCK_TIME_NONE;
|
||||||
parse->priv->lead_in = parse->priv->lead_out = 0;
|
parse->priv->lead_in = parse->priv->lead_out = 0;
|
||||||
parse->priv->lead_in_ts = parse->priv->lead_out_ts = 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->bitrate = 0;
|
||||||
parse->priv->framecount = 0;
|
parse->priv->framecount = 0;
|
||||||
parse->priv->bytecount = 0;
|
parse->priv->bytecount = 0;
|
||||||
|
@ -596,7 +596,7 @@ gst_base_parse_reset (GstBaseParse * parse)
|
||||||
parse->priv->first_frame_offset = -1;
|
parse->priv->first_frame_offset = -1;
|
||||||
parse->priv->estimated_duration = -1;
|
parse->priv->estimated_duration = -1;
|
||||||
parse->priv->next_ts = 0;
|
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_min_bitrate = TRUE;
|
||||||
parse->priv->post_avg_bitrate = TRUE;
|
parse->priv->post_avg_bitrate = TRUE;
|
||||||
parse->priv->post_max_bitrate = TRUE;
|
parse->priv->post_max_bitrate = TRUE;
|
||||||
|
@ -1006,6 +1006,13 @@ gst_base_parse_src_event (GstPad * pad, GstEvent * event)
|
||||||
return ret;
|
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:
|
* gst_base_parse_src_eventfunc:
|
||||||
|
@ -1024,7 +1031,7 @@ gst_base_parse_src_eventfunc (GstBaseParse * parse, GstEvent * event)
|
||||||
switch (GST_EVENT_TYPE (event)) {
|
switch (GST_EVENT_TYPE (event)) {
|
||||||
case GST_EVENT_SEEK:
|
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);
|
handled = gst_base_parse_handle_seek (parse, event);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -2776,28 +2783,25 @@ exit:
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* gst_base_parse_set_seek:
|
* gst_base_parse_set_average_bitrate:
|
||||||
* @parse: #GstBaseParse.
|
* @parse: #GstBaseParse.
|
||||||
* @seek: #GstBaseParseSeekable.
|
* @abitrate: average bitrate in bits/second
|
||||||
* @abitrate: average bitrate.
|
|
||||||
*
|
*
|
||||||
* Sets whether and how the media is seekable (in time).
|
* Optionally sets the average bitrate detected in media (if non-zero),
|
||||||
* Also optionally provides average bitrate detected in media (if non-zero),
|
|
||||||
* e.g. based on metadata, as it will be posted to the application.
|
* e.g. based on metadata, as it will be posted to the application.
|
||||||
*
|
*
|
||||||
* By default, announced average bitrate is estimated, and seekability is assumed
|
* By default, announced average bitrate is estimated. The average bitrate
|
||||||
* possible based on estimated 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
|
void
|
||||||
gst_base_parse_set_seek (GstBaseParse * parse,
|
gst_base_parse_set_average_bitrate (GstBaseParse * parse, guint bitrate)
|
||||||
GstBaseParseSeekable seek, guint bitrate)
|
|
||||||
{
|
{
|
||||||
parse->priv->seekable = seek;
|
|
||||||
parse->priv->bitrate = bitrate;
|
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:
|
* gst_base_parse_set_min_frame_size:
|
||||||
* @parse: #GstBaseParse.
|
* @parse: #GstBaseParse.
|
||||||
|
@ -3019,8 +3023,7 @@ gst_base_parse_query (GstPad * pad, GstQuery * query)
|
||||||
res = gst_pad_query_default (pad, query);
|
res = gst_pad_query_default (pad, query);
|
||||||
|
|
||||||
/* we may be able to help if in TIME */
|
/* we may be able to help if in TIME */
|
||||||
if (fmt == GST_FORMAT_TIME &&
|
if (fmt == GST_FORMAT_TIME && gst_base_parse_is_seekable (parse)) {
|
||||||
parse->priv->seekable > GST_BASE_PARSE_SEEK_NONE) {
|
|
||||||
gst_query_parse_seeking (query, &fmt, &seekable, NULL, NULL);
|
gst_query_parse_seeking (query, &fmt, &seekable, NULL, NULL);
|
||||||
/* already OK if upstream takes care */
|
/* already OK if upstream takes care */
|
||||||
GST_LOG_OBJECT (parse, "upstream handled %d, seekable %d",
|
GST_LOG_OBJECT (parse, "upstream handled %d, seekable %d",
|
||||||
|
|
|
@ -141,7 +141,7 @@ typedef struct {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* GstBaseParseFormatFlags:
|
* 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
|
* @GST_BASE_PARSE_FORMAT_FLAG_PASSTHROUGH: nature of format or configuration
|
||||||
* does not allow (much) parsing, so parser should operate in passthrough mode
|
* does not allow (much) parsing, so parser should operate in passthrough mode
|
||||||
* (which only applies operating in pull mode). That is, incoming buffers
|
* (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
|
* @GST_BASE_PARSE_FORMAT_FLAG_HAS_TIME: frames carry timing info which subclass
|
||||||
* can (generally) parse and provide. In particular, intrinsic time
|
* can (generally) parse and provide. In particular, intrinsic time
|
||||||
* (rather than estimated) can be obtained following a seek.
|
* (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
|
* Since: 0.10.x
|
||||||
*/
|
*/
|
||||||
|
@ -159,24 +162,9 @@ typedef enum {
|
||||||
GST_BASE_PARSE_FORMAT_FLAG_NONE = 0,
|
GST_BASE_PARSE_FORMAT_FLAG_NONE = 0,
|
||||||
GST_BASE_PARSE_FORMAT_FLAG_PASSTHROUGH = (1 << 0),
|
GST_BASE_PARSE_FORMAT_FLAG_PASSTHROUGH = (1 << 0),
|
||||||
GST_BASE_PARSE_FORMAT_FLAG_HAS_TIME = (1 << 1),
|
GST_BASE_PARSE_FORMAT_FLAG_HAS_TIME = (1 << 1),
|
||||||
|
GST_BASE_PARSE_FORMAT_FLAG_SYNCABLE = (1 << 2)
|
||||||
} GstBaseParseFormatFlags;
|
} 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 _GstBaseParse GstBaseParse;
|
||||||
typedef struct _GstBaseParseClass GstBaseParseClass;
|
typedef struct _GstBaseParseClass GstBaseParseClass;
|
||||||
typedef struct _GstBaseParsePrivate GstBaseParsePrivate;
|
typedef struct _GstBaseParsePrivate GstBaseParsePrivate;
|
||||||
|
@ -291,9 +279,8 @@ void gst_base_parse_set_duration (GstBaseParse * parse,
|
||||||
gint64 duration,
|
gint64 duration,
|
||||||
gint interval);
|
gint interval);
|
||||||
|
|
||||||
void gst_base_parse_set_seek (GstBaseParse * parse,
|
void gst_base_parse_set_average_bitrate (GstBaseParse * parse,
|
||||||
GstBaseParseSeekable seek,
|
guint bitrate);
|
||||||
guint bitrate);
|
|
||||||
|
|
||||||
void gst_base_parse_set_min_frame_size (GstBaseParse * parse,
|
void gst_base_parse_set_min_frame_size (GstBaseParse * parse,
|
||||||
guint min_size);
|
guint min_size);
|
||||||
|
|
Loading…
Reference in a new issue