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);
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);
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;
}
-/**
- * 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.
gboolean passthrough;
guint fps_num, fps_den;
guint update_interval;
+ guint bitrate;
+ GstBaseParseSeekable seekable;
gboolean discont;
gboolean flushing;
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,
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,
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;
}
-/**
- * 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.
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) {
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;
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:
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",
*/
#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;
* @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.
gboolean (*src_event) (GstBaseParse *parse,
GstEvent *event);
- gboolean (*is_seekable) (GstBaseParse *parse);
-
gint (*get_frame_overhead) (GstBaseParse *parse,
GstBuffer *buf);
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);