mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-12-28 03:00:35 +00:00
mpegaudioparse: Use a constant bit rate to convert between time and bytes if possible.
This should result in no worse accuracy than the base parse element, and may result in better accuracy. In particular, the number of bytes processed at any given point, as accumulated by baseparse, can be only accurate to (1 / # of frames) bytes per second, and if we try to seek immediately after pausing the pipeline to a large offset, this small inaccuracy can propagate to something noticeable. The use case that prompted this patch is a 45-minute MPEG-1 layer 3 file, which has a constant bit rate but no seek tables. Trying to seek the pipeline immediately after pauisng it, without the ACCURATE flag, to a location 41 minutes in, yields a location that is, even with <https://gitlab.freedesktop.org/gstreamer/gstreamer/merge_requests/374>, still audibly incorrect. This patch yields a much closer position, no longer audibly incorrect, and likely within a frame of the most correct position.
This commit is contained in:
parent
56e5243f03
commit
71bb53a648
2 changed files with 21 additions and 0 deletions
|
@ -199,6 +199,7 @@ gst_mpeg_audio_parse_reset (GstMpegAudioParse * mp3parse)
|
|||
mp3parse->freerate = 0;
|
||||
|
||||
mp3parse->hdr_bitrate = 0;
|
||||
mp3parse->bitrate_is_constant = TRUE;
|
||||
|
||||
mp3parse->xing_flags = 0;
|
||||
mp3parse->xing_bitrate = 0;
|
||||
|
@ -755,6 +756,9 @@ gst_mpeg_audio_parse_handle_frame (GstBaseParse * parse,
|
|||
(version == 1) ? 10 : 30, 2);
|
||||
}
|
||||
|
||||
if (mp3parse->hdr_bitrate && mp3parse->hdr_bitrate != bitrate) {
|
||||
mp3parse->bitrate_is_constant = FALSE;
|
||||
}
|
||||
mp3parse->hdr_bitrate = bitrate;
|
||||
|
||||
/* For first frame; check for seek tables and output a codec tag */
|
||||
|
@ -1227,6 +1231,14 @@ gst_mpeg_audio_parse_time_to_bytepos (GstMpegAudioParse * mp3parse,
|
|||
return TRUE;
|
||||
}
|
||||
|
||||
/* If we have had a constant bit rate (so far), use it directly, as it
|
||||
* may give slightly more accurate results than the base class. */
|
||||
if (mp3parse->bitrate_is_constant && mp3parse->hdr_bitrate) {
|
||||
*bytepos = gst_util_uint64_scale (ts, mp3parse->hdr_bitrate,
|
||||
8 * GST_SECOND);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
@ -1292,6 +1304,14 @@ gst_mpeg_audio_parse_bytepos_to_time (GstMpegAudioParse * mp3parse,
|
|||
return TRUE;
|
||||
}
|
||||
|
||||
/* If we have had a constant bit rate (so far), use it directly, as it
|
||||
* may give slightly more accurate results than the base class. */
|
||||
if (mp3parse->bitrate_is_constant && mp3parse->hdr_bitrate) {
|
||||
*ts = gst_util_uint64_scale (bytepos, 8 * GST_SECOND,
|
||||
mp3parse->hdr_bitrate);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
|
|
@ -69,6 +69,7 @@ struct _GstMpegAudioParse {
|
|||
|
||||
/* Bitrate from non-vbr headers */
|
||||
guint32 hdr_bitrate;
|
||||
gboolean bitrate_is_constant;
|
||||
|
||||
/* Xing info */
|
||||
guint32 xing_flags;
|
||||
|
|
Loading…
Reference in a new issue