mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-11-18 07:47:17 +00:00
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:
parent
f218b984cc
commit
589c455ccb
5 changed files with 41 additions and 14 deletions
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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");
|
||||
}
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
Loading…
Reference in a new issue