From: Mark Nauwelaerts Date: Wed, 22 Sep 2010 13:07:09 +0000 (+0200) Subject: baseparse: use _set_frame_props to configure frame lead_in and lead_out X-Git-Tag: 1.19.3~509^2~7136^2~933 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=589c455ccb3b55e704b60a0dbfbc34941ca0893c;p=platform%2Fupstream%2Fgstreamer.git 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. --- diff --git a/gst/audioparsers/gstaacparse.c b/gst/audioparsers/gstaacparse.c index 62e79ba..146acb9 100644 --- a/gst/audioparsers/gstaacparse.c +++ b/gst/audioparsers/gstaacparse.c @@ -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); diff --git a/gst/audioparsers/gstac3parse.c b/gst/audioparsers/gstac3parse.c index 5a3913e..07fcd7d 100644 --- a/gst/audioparsers/gstac3parse.c +++ b/gst/audioparsers/gstac3parse.c @@ -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; diff --git a/gst/audioparsers/gstamrparse.c b/gst/audioparsers/gstamrparse.c index 1090708..aea6ec6 100644 --- a/gst/audioparsers/gstamrparse.c +++ b/gst/audioparsers/gstamrparse.c @@ -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"); } diff --git a/gst/audioparsers/gstbaseparse.c b/gst/audioparsers/gstbaseparse.c index c73d096..4f3699c 100644 --- a/gst/audioparsers/gstbaseparse.c +++ b/gst/audioparsers/gstbaseparse.c @@ -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 { diff --git a/gst/audioparsers/gstbaseparse.h b/gst/audioparsers/gstbaseparse.h index 8d913b1..27547a9 100644 --- a/gst/audioparsers/gstbaseparse.h +++ b/gst/audioparsers/gstbaseparse.h @@ -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);