baseparse: use _set_frame_props to configure frame lead_in and lead_out

... provided a corresponding decoder with sufficient leading and following
frames to carry out full decoding for a particular segment.
This commit is contained in:
Mark Nauwelaerts 2010-09-22 15:07:09 +02:00 committed by Tim-Philipp Müller
parent f218b984cc
commit 589c455ccb
5 changed files with 41 additions and 14 deletions

View file

@ -465,7 +465,7 @@ gst_aacparse_detect_stream (GstAacParse * aacparse,
aacparse->channels = ((data[2] & 0x01) << 2) | ((data[3] & 0xc0) >> 6);
gst_base_parse_set_frame_props (GST_BASE_PARSE (aacparse),
aacparse->sample_rate, 1024);
aacparse->sample_rate, 1024, 2, 2);
GST_DEBUG ("ADTS: samplerate %d, channels %d, objtype %d",
aacparse->sample_rate, aacparse->channels, aacparse->object_type);

View file

@ -465,7 +465,7 @@ gst_ac3_parse_parse_frame (GstBaseParse * parse, GstBuffer * buf)
ac3parse->sample_rate = rate;
ac3parse->channels = chans;
gst_base_parse_set_frame_props (parse, rate, 256 * blocks);
gst_base_parse_set_frame_props (parse, rate, 256 * blocks, 2, 2);
}
return GST_FLOW_OK;

View file

@ -237,7 +237,7 @@ gst_amrparse_sink_setcaps (GstBaseParse * parse, GstCaps * caps)
}
amrparse->need_header = FALSE;
gst_base_parse_set_frame_props (GST_BASE_PARSE (amrparse), 50, 1);
gst_base_parse_set_frame_props (GST_BASE_PARSE (amrparse), 50, 1, 2, 2);
gst_amrparse_set_src_caps (amrparse);
return TRUE;
}
@ -306,7 +306,7 @@ gst_amrparse_check_valid_frame (GstBaseParse * parse,
if (dsize >= AMR_MIME_HEADER_SIZE &&
gst_amrparse_parse_header (amrparse, data, skipsize)) {
amrparse->need_header = FALSE;
gst_base_parse_set_frame_props (GST_BASE_PARSE (amrparse), 50, 1);
gst_base_parse_set_frame_props (GST_BASE_PARSE (amrparse), 50, 1, 2, 2);
} else {
GST_WARNING ("media doesn't look like a AMR format");
}

View file

@ -219,6 +219,8 @@ struct _GstBaseParsePrivate
guint fps_num, fps_den;
guint update_interval;
guint bitrate;
guint lead_in, lead_out;
GstClockTime lead_in_ts, lead_out_ts;
GstBaseParseSeekable seekable;
gboolean discont;
@ -478,6 +480,8 @@ gst_base_parse_reset (GstBaseParse * parse)
parse->priv->update_interval = 50;
parse->priv->fps_num = parse->priv->fps_den = 0;
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;
@ -1475,14 +1479,15 @@ gst_base_parse_push_buffer (GstBaseParse * parse, GstBuffer * buffer)
if (ret == GST_BASE_PARSE_FLOW_CLIP) {
if (GST_BUFFER_TIMESTAMP_IS_VALID (buffer) &&
GST_CLOCK_TIME_IS_VALID (parse->segment.stop) &&
GST_BUFFER_TIMESTAMP (buffer) > parse->segment.stop) {
GST_BUFFER_TIMESTAMP (buffer) >
parse->segment.stop + parse->priv->lead_out_ts) {
GST_LOG_OBJECT (parse, "Dropped frame, after segment");
ret = GST_FLOW_UNEXPECTED;
} 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 (buffer)
< parse->segment.start) {
GST_BUFFER_TIMESTAMP (buffer) + GST_BUFFER_DURATION (buffer) +
parse->priv->lead_in_ts < parse->segment.start) {
GST_LOG_OBJECT (parse, "Dropped frame, before segment");
ret = GST_BASE_PARSE_FLOW_DROPPED;
} else {
@ -2205,13 +2210,18 @@ gst_base_parse_set_passthrough (GstBaseParse * parse, gboolean passthrough)
* @parse: the #GstBaseParse to set
* @fps_num: frames per second (numerator).
* @fps_den: frames per second (denominator).
* @lead_in: frames needed before a segment for subsequent decode
* @lead_out: frames needed after a segment
*
* If frames per second is configured, parser can take care of buffer duration
* and timestamping.
* and timestamping. When performing segment clipping, or seeking to a specific
* location, a corresponding decoder might need an initial @lead_in and a
* following @lead_out number of frames to ensure the desired segment is
* entirely filled upon decoding.
*/
void
gst_base_parse_set_frame_props (GstBaseParse * parse, guint fps_num,
guint fps_den)
guint fps_den, guint lead_in, guint lead_out)
{
g_return_if_fail (parse != NULL);
@ -2223,13 +2233,24 @@ gst_base_parse_set_frame_props (GstBaseParse * parse, guint fps_num,
fps_num, fps_den);
fps_num = fps_den = 0;
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;
} else {
parse->priv->frame_duration =
gst_util_uint64_scale (GST_SECOND, parse->priv->fps_den,
parse->priv->fps_num);
gst_util_uint64_scale (GST_SECOND, fps_den, fps_num);
parse->priv->lead_in = lead_in;
parse->priv->lead_out = lead_out;
parse->priv->lead_in_ts =
gst_util_uint64_scale (GST_SECOND, fps_den * lead_in, fps_num);
parse->priv->lead_out_ts =
gst_util_uint64_scale (GST_SECOND, fps_den * lead_out, fps_num);
}
GST_LOG_OBJECT (parse, "set fps: %d/%d => duration: %" G_GINT64_FORMAT " ms",
fps_num, fps_den, parse->priv->frame_duration / GST_MSECOND);
GST_LOG_OBJECT (parse, "set lead in: %d frames = %" G_GUINT64_FORMAT " ms, "
"lead out: %d frames = %" G_GUINT64_FORMAT " ms",
lead_in, parse->priv->lead_in_ts / GST_MSECOND,
lead_out, parse->priv->lead_out_ts / GST_MSECOND);
GST_BASE_PARSE_UNLOCK (parse);
}
@ -2598,8 +2619,14 @@ gst_base_parse_handle_seek (GstBaseParse * parse, GstEvent * event)
accurate = TRUE;
}
if (accurate) {
seekpos = gst_base_parse_find_offset (parse, seeksegment.last_stop, TRUE,
&start_ts);
GstClockTime startpos = seeksegment.last_stop;
/* accurate requested, so ... seek a bit before target */
if (startpos < parse->priv->lead_in_ts)
startpos = 0;
else
startpos -= parse->priv->lead_in_ts;
seekpos = gst_base_parse_find_offset (parse, startpos, TRUE, &start_ts);
seekstop = gst_base_parse_find_offset (parse, seeksegment.stop, FALSE,
NULL);
} else {

View file

@ -294,7 +294,7 @@ void gst_base_parse_set_min_frame_size (GstBaseParse *parse,
void gst_base_parse_set_passthrough (GstBaseParse * parse, gboolean passthrough);
void gst_base_parse_set_frame_props (GstBaseParse * parse, guint fps_num,
guint fps_den);
guint fps_den, guint lead_in, guint lead_out);
gboolean gst_base_parse_get_sync (GstBaseParse * parse);