gst/flacparse/gstbaseparse.*: Provide a vfunc for the subclass to decide whether a frame is inside the segment or not...
Original commit message from CVS: * gst/flacparse/gstbaseparse.c: (gst_base_parse_class_init), (gst_base_parse_push_buffer), (gst_base_parse_update_upstream_durations), (gst_base_parse_convert), (gst_base_parse_frame_in_segment): * gst/flacparse/gstbaseparse.h: Provide a vfunc for the subclass to decide whether a frame is inside the segment or not and add a default implementation. Fix approximate bitrate calculations.
This commit is contained in:
parent
5bd9d5cd17
commit
3070e9bdec
12
ChangeLog
12
ChangeLog
@ -1,3 +1,15 @@
|
|||||||
|
2008-09-30 Sebastian Dröge <sebastian.droege@collabora.co.uk>
|
||||||
|
|
||||||
|
* gst/flacparse/gstbaseparse.c: (gst_base_parse_class_init),
|
||||||
|
(gst_base_parse_push_buffer),
|
||||||
|
(gst_base_parse_update_upstream_durations),
|
||||||
|
(gst_base_parse_convert), (gst_base_parse_frame_in_segment):
|
||||||
|
* gst/flacparse/gstbaseparse.h:
|
||||||
|
Provide a vfunc for the subclass to decide whether a frame is inside
|
||||||
|
the segment or not and add a default implementation.
|
||||||
|
|
||||||
|
Fix approximate bitrate calculations.
|
||||||
|
|
||||||
2008-09-30 Sebastian Dröge <sebastian.droege@collabora.co.uk>
|
2008-09-30 Sebastian Dröge <sebastian.droege@collabora.co.uk>
|
||||||
|
|
||||||
* gst/flacparse/gstbaseparse.c: (gst_base_parse_class_init),
|
* gst/flacparse/gstbaseparse.c: (gst_base_parse_class_init),
|
||||||
|
@ -163,7 +163,6 @@
|
|||||||
* - In push mode provide a queue of adapter-"queued" buffers for upstream
|
* - In push mode provide a queue of adapter-"queued" buffers for upstream
|
||||||
* buffer metadata
|
* buffer metadata
|
||||||
* - Handle upstream timestamps
|
* - Handle upstream timestamps
|
||||||
* - Let subclass decide if frames outside the segment should be dropped
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifdef HAVE_CONFIG_H
|
#ifdef HAVE_CONFIG_H
|
||||||
@ -286,6 +285,10 @@ static gboolean
|
|||||||
gst_base_parse_convert (GstBaseParse * parse, GstFormat src_format,
|
gst_base_parse_convert (GstBaseParse * parse, GstFormat src_format,
|
||||||
gint64 src_value, GstFormat dest_format, gint64 * dest_value);
|
gint64 src_value, GstFormat dest_format, gint64 * dest_value);
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
gst_base_parse_frame_in_segment (GstBaseParse * parse, GstBuffer * buffer,
|
||||||
|
GstSegment * segment);
|
||||||
|
|
||||||
static void gst_base_parse_drain (GstBaseParse * parse);
|
static void gst_base_parse_drain (GstBaseParse * parse);
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -352,8 +355,7 @@ gst_base_parse_class_init (GstBaseParseClass * klass)
|
|||||||
gobject_class->finalize = GST_DEBUG_FUNCPTR (gst_base_parse_finalize);
|
gobject_class->finalize = GST_DEBUG_FUNCPTR (gst_base_parse_finalize);
|
||||||
|
|
||||||
/* Default handlers */
|
/* Default handlers */
|
||||||
klass->check_valid_frame = NULL;
|
klass->frame_in_segment = gst_base_parse_frame_in_segment;
|
||||||
klass->parse_frame = NULL;
|
|
||||||
klass->event = gst_base_parse_sink_eventfunc;
|
klass->event = gst_base_parse_sink_eventfunc;
|
||||||
klass->src_event = gst_base_parse_src_eventfunc;
|
klass->src_event = gst_base_parse_src_eventfunc;
|
||||||
klass->is_seekable = gst_base_parse_is_seekable;
|
klass->is_seekable = gst_base_parse_is_seekable;
|
||||||
@ -694,6 +696,7 @@ gst_base_parse_push_buffer (GstBaseParse * parse, GstBuffer * buffer)
|
|||||||
{
|
{
|
||||||
GstClockTime last_stop = GST_CLOCK_TIME_NONE;
|
GstClockTime last_stop = GST_CLOCK_TIME_NONE;
|
||||||
GstFlowReturn ret = GST_FLOW_OK;
|
GstFlowReturn ret = GST_FLOW_OK;
|
||||||
|
GstBaseParseClass *klass = GST_BASE_PARSE_GET_CLASS (parse);
|
||||||
|
|
||||||
g_return_val_if_fail (GST_PAD_CAPS (parse->srcpad), GST_FLOW_ERROR);
|
g_return_val_if_fail (GST_PAD_CAPS (parse->srcpad), GST_FLOW_ERROR);
|
||||||
|
|
||||||
@ -736,19 +739,8 @@ gst_base_parse_push_buffer (GstBaseParse * parse, GstBuffer * buffer)
|
|||||||
|
|
||||||
/* TODO: Add to seek table */
|
/* TODO: Add to seek table */
|
||||||
|
|
||||||
if (GST_BUFFER_TIMESTAMP_IS_VALID (buffer) &&
|
if (!klass->frame_in_segment (parse, buffer, &parse->segment)) {
|
||||||
GST_CLOCK_TIME_IS_VALID (parse->segment.stop) &&
|
GST_LOG_OBJECT (parse, "Dropped frame, outside configured segment");
|
||||||
GST_BUFFER_TIMESTAMP (buffer) > parse->segment.stop) {
|
|
||||||
GST_LOG_OBJECT (parse, "Dropped frame, after segment");
|
|
||||||
gst_buffer_unref (buffer);
|
|
||||||
} else if (GST_BUFFER_TIMESTAMP_IS_VALID (buffer) &&
|
|
||||||
GST_BUFFER_DURATION_IS_VALID (buffer) &&
|
|
||||||
GST_CLOCK_TIME_IS_VALID (parse->segment.start) &&
|
|
||||||
GST_BUFFER_TIMESTAMP (buffer) + GST_BUFFER_DURATION_IS_VALID (buffer)
|
|
||||||
< parse->segment.start) {
|
|
||||||
/* FIXME: subclass needs way to override the start as downstream might
|
|
||||||
* need frames before for proper decoding */
|
|
||||||
GST_LOG_OBJECT (parse, "Dropped frame, before segment");
|
|
||||||
gst_buffer_unref (buffer);
|
gst_buffer_unref (buffer);
|
||||||
} else {
|
} else {
|
||||||
guint size = GST_BUFFER_SIZE (buffer);
|
guint size = GST_BUFFER_SIZE (buffer);
|
||||||
@ -766,35 +758,38 @@ gst_base_parse_push_buffer (GstBaseParse * parse, GstBuffer * buffer)
|
|||||||
if (parse->priv->upstream_size && (!parse->priv->upstream_duration
|
if (parse->priv->upstream_size && (!parse->priv->upstream_duration
|
||||||
&& parse->priv->duration == -1)) {
|
&& parse->priv->duration == -1)) {
|
||||||
parse->priv->avg_bitrate =
|
parse->priv->avg_bitrate =
|
||||||
gst_util_uint64_scale (parse->priv->offset, 8,
|
gst_util_uint64_scale (parse->priv->offset, 8 * GST_SECOND,
|
||||||
parse->segment.last_stop);
|
parse->segment.last_stop);
|
||||||
GST_DEBUG_OBJECT (parse, "Approximate average bitrate: %" G_GUINT64_FORMAT,
|
GST_DEBUG_OBJECT (parse,
|
||||||
|
"Approximate average bitrate: %" G_GUINT64_FORMAT " bps",
|
||||||
parse->priv->avg_bitrate);
|
parse->priv->avg_bitrate);
|
||||||
parse->priv->estimated_duration =
|
parse->priv->estimated_duration =
|
||||||
gst_util_uint64_scale (parse->priv->avg_bitrate,
|
gst_util_uint64_scale (parse->priv->upstream_size, 8 * GST_SECOND,
|
||||||
parse->priv->upstream_size, 8);
|
parse->priv->avg_bitrate);
|
||||||
GST_DEBUG_OBJECT (parse, "Estimated duration: %" GST_TIME_FORMAT,
|
GST_DEBUG_OBJECT (parse, "Estimated duration: %" GST_TIME_FORMAT,
|
||||||
parse->priv->estimated_duration);
|
parse->priv->estimated_duration);
|
||||||
} else if (!parse->priv->upstream_size && parse->priv->upstream_duration) {
|
} else if (!parse->priv->upstream_size && parse->priv->upstream_duration) {
|
||||||
parse->priv->avg_bitrate =
|
parse->priv->avg_bitrate =
|
||||||
gst_util_uint64_scale (parse->priv->offset, 8,
|
gst_util_uint64_scale (parse->priv->offset, 8 * GST_SECOND,
|
||||||
parse->segment.last_stop);
|
parse->segment.last_stop);
|
||||||
GST_DEBUG_OBJECT (parse, "Approximate average bitrate: %" G_GUINT64_FORMAT,
|
GST_DEBUG_OBJECT (parse,
|
||||||
|
"Approximate average bitrate: %" G_GUINT64_FORMAT " bps",
|
||||||
parse->priv->avg_bitrate);
|
parse->priv->avg_bitrate);
|
||||||
parse->priv->estimated_size =
|
parse->priv->estimated_size =
|
||||||
gst_util_uint64_scale (parse->priv->upstream_duration,
|
gst_util_uint64_scale (parse->priv->upstream_duration,
|
||||||
parse->priv->avg_bitrate, 8);
|
parse->priv->avg_bitrate, 8 * GST_SECOND);
|
||||||
GST_DEBUG_OBJECT (parse, "Estimated size: %" G_GUINT64_FORMAT,
|
GST_DEBUG_OBJECT (parse, "Estimated size: %" G_GUINT64_FORMAT,
|
||||||
parse->priv->estimated_size);
|
parse->priv->estimated_size);
|
||||||
} else if (!parse->priv->upstream_size && parse->priv->duration != -1) {
|
} else if (!parse->priv->upstream_size && parse->priv->duration != -1) {
|
||||||
parse->priv->avg_bitrate =
|
parse->priv->avg_bitrate =
|
||||||
gst_util_uint64_scale (parse->priv->offset, 8,
|
gst_util_uint64_scale (parse->priv->offset, 8 * GST_SECOND,
|
||||||
parse->segment.last_stop);
|
parse->segment.last_stop);
|
||||||
GST_DEBUG_OBJECT (parse, "Approximate average bitrate: %" G_GUINT64_FORMAT,
|
GST_DEBUG_OBJECT (parse,
|
||||||
|
"Approximate average bitrate: %" G_GUINT64_FORMAT " bps",
|
||||||
parse->priv->avg_bitrate);
|
parse->priv->avg_bitrate);
|
||||||
parse->priv->estimated_size =
|
parse->priv->estimated_size =
|
||||||
gst_util_uint64_scale (parse->priv->duration, parse->priv->avg_bitrate,
|
gst_util_uint64_scale (parse->priv->duration, parse->priv->avg_bitrate,
|
||||||
8);
|
8 * GST_SECOND);
|
||||||
GST_DEBUG_OBJECT (parse, "Estimated size: %" G_GUINT64_FORMAT,
|
GST_DEBUG_OBJECT (parse, "Estimated size: %" G_GUINT64_FORMAT,
|
||||||
parse->priv->estimated_size);
|
parse->priv->estimated_size);
|
||||||
}
|
}
|
||||||
@ -912,15 +907,17 @@ gst_base_parse_update_upstream_durations (GstBaseParse * parse)
|
|||||||
|
|
||||||
if (parse->priv->upstream_size && parse->priv->upstream_duration) {
|
if (parse->priv->upstream_size && parse->priv->upstream_duration) {
|
||||||
parse->priv->avg_bitrate =
|
parse->priv->avg_bitrate =
|
||||||
gst_util_uint64_scale (parse->priv->upstream_duration, 8,
|
gst_util_uint64_scale (parse->priv->upstream_size, 8 * GST_SECOND,
|
||||||
parse->priv->upstream_size);
|
parse->priv->upstream_duration);
|
||||||
GST_DEBUG_OBJECT (parse, "Approximate average bitrate: %" G_GUINT64_FORMAT,
|
GST_DEBUG_OBJECT (parse,
|
||||||
|
"Approximate average bitrate: %" G_GUINT64_FORMAT " bps",
|
||||||
parse->priv->avg_bitrate);
|
parse->priv->avg_bitrate);
|
||||||
} else if (parse->priv->upstream_size && parse->priv->duration != -1) {
|
} else if (parse->priv->upstream_size && parse->priv->duration != -1) {
|
||||||
parse->priv->avg_bitrate =
|
parse->priv->avg_bitrate =
|
||||||
gst_util_uint64_scale (parse->priv->duration, 8,
|
gst_util_uint64_scale (parse->priv->upstream_size, 8 * GST_SECOND,
|
||||||
parse->priv->upstream_size);
|
parse->priv->duration);
|
||||||
GST_DEBUG_OBJECT (parse, "Approximate average bitrate: %" G_GUINT64_FORMAT,
|
GST_DEBUG_OBJECT (parse,
|
||||||
|
"Approximate average bitrate: %" G_GUINT64_FORMAT " bps",
|
||||||
parse->priv->avg_bitrate);
|
parse->priv->avg_bitrate);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1422,12 +1419,14 @@ gst_base_parse_convert (GstBaseParse * parse, GstFormat src_format,
|
|||||||
if (parse->priv->avg_bitrate && src_format == GST_FORMAT_BYTES
|
if (parse->priv->avg_bitrate && src_format == GST_FORMAT_BYTES
|
||||||
&& dest_format == GST_FORMAT_TIME) {
|
&& dest_format == GST_FORMAT_TIME) {
|
||||||
*dest_value =
|
*dest_value =
|
||||||
gst_util_uint64_scale (src_value, 8, parse->priv->avg_bitrate);
|
gst_util_uint64_scale (src_value, 8 * GST_SECOND,
|
||||||
|
parse->priv->avg_bitrate);
|
||||||
res = TRUE;
|
res = TRUE;
|
||||||
} else if (parse->priv->avg_bitrate && src_format == GST_FORMAT_TIME
|
} else if (parse->priv->avg_bitrate && src_format == GST_FORMAT_TIME
|
||||||
&& dest_format == GST_FORMAT_BYTES) {
|
&& dest_format == GST_FORMAT_BYTES) {
|
||||||
*dest_value =
|
*dest_value =
|
||||||
gst_util_uint64_scale (src_value, parse->priv->avg_bitrate, 8);
|
gst_util_uint64_scale (src_value, parse->priv->avg_bitrate,
|
||||||
|
8 * GST_SECOND);
|
||||||
res = TRUE;
|
res = TRUE;
|
||||||
} else {
|
} else {
|
||||||
res = FALSE;
|
res = FALSE;
|
||||||
@ -1667,6 +1666,24 @@ gst_base_parse_query (GstPad * pad, GstQuery * query)
|
|||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
gst_base_parse_frame_in_segment (GstBaseParse * parse, GstBuffer * buffer,
|
||||||
|
GstSegment * segment)
|
||||||
|
{
|
||||||
|
if (GST_BUFFER_TIMESTAMP_IS_VALID (buffer) &&
|
||||||
|
GST_CLOCK_TIME_IS_VALID (segment->stop) &&
|
||||||
|
GST_BUFFER_TIMESTAMP (buffer) > segment->stop) {
|
||||||
|
return FALSE;
|
||||||
|
} else if (GST_BUFFER_TIMESTAMP_IS_VALID (buffer) &&
|
||||||
|
GST_BUFFER_DURATION_IS_VALID (buffer) &&
|
||||||
|
GST_CLOCK_TIME_IS_VALID (segment->start) &&
|
||||||
|
GST_BUFFER_TIMESTAMP (buffer) + GST_BUFFER_DURATION_IS_VALID (buffer)
|
||||||
|
< segment->start) {
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* gst_base_parse_handle_seek:
|
* gst_base_parse_handle_seek:
|
||||||
|
@ -151,6 +151,8 @@ struct _GstBaseParse {
|
|||||||
* set the buffer timestamp, duration, caps and possibly
|
* set the buffer timestamp, duration, caps and possibly
|
||||||
* other necessary metadata. This is called with srcpad's
|
* other necessary metadata. This is called with srcpad's
|
||||||
* STREAM_LOCK held.
|
* STREAM_LOCK held.
|
||||||
|
* @frame_in_segment: Optional. Check if the given frame is contained in the
|
||||||
|
* given segment.
|
||||||
* @convert: Optional.
|
* @convert: Optional.
|
||||||
* Convert between formats.
|
* Convert between formats.
|
||||||
* @find_frame: Optional.
|
* @find_frame: Optional.
|
||||||
@ -197,6 +199,10 @@ struct _GstBaseParseClass {
|
|||||||
GstFlowReturn (*parse_frame) (GstBaseParse *parse,
|
GstFlowReturn (*parse_frame) (GstBaseParse *parse,
|
||||||
GstBuffer *buffer);
|
GstBuffer *buffer);
|
||||||
|
|
||||||
|
gboolean (*frame_in_segment) (GstBaseParse *parse,
|
||||||
|
GstBuffer *buffer,
|
||||||
|
GstSegment *segment);
|
||||||
|
|
||||||
gboolean (*convert) (GstBaseParse * parse,
|
gboolean (*convert) (GstBaseParse * parse,
|
||||||
GstFormat src_format,
|
GstFormat src_format,
|
||||||
gint64 src_value,
|
gint64 src_value,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user