[MPlayer-cvslog] r34273 - in trunk: Changelog libmpdemux/demux_audio.c
ib
subversion at mplayerhq.hu
Thu Oct 27 22:09:09 CEST 2011
Author: ib
Date: Thu Oct 27 22:09:09 2011
New Revision: 34273
Log:
Fix wrong runtime and average bitrate for VBR (variable bitrate) MP3.
Do so by determining the number of frames from the Xing/Info/VBRI
headers and by calculation a correct duration which leads to an
reasonable average bytes per seconds.
Modified:
trunk/Changelog
trunk/libmpdemux/demux_audio.c
Modified: trunk/Changelog
==============================================================================
--- trunk/Changelog Thu Oct 27 21:58:42 2011 (r34272)
+++ trunk/Changelog Thu Oct 27 22:09:09 2011 (r34273)
@@ -8,6 +8,7 @@ MPlayer (1.0)
Demuxers:
* experimental support for using binary Quicktime codecs with -demuxer lavf.
+ * correct runtime and average bitrate for VBR (variable bitrate) MP3
Filters:
* delogo: allow to change the rectangle based on the time.
Modified: trunk/libmpdemux/demux_audio.c
==============================================================================
--- trunk/libmpdemux/demux_audio.c Thu Oct 27 21:58:42 2011 (r34272)
+++ trunk/libmpdemux/demux_audio.c Thu Oct 27 22:09:09 2011 (r34273)
@@ -260,6 +260,69 @@ get_flac_metadata (demuxer_t* demuxer)
}
#endif
+/**
+ * @brief Determine the number of frames of a file encoded with
+ * variable bitrate mode (VBR).
+ *
+ * @param s stream to be read
+ * @param off offset in stream to start reading from
+ *
+ * @return 0 (error or no variable bitrate mode) or number of frames
+ */
+static unsigned int mp3_vbr_frames(stream_t *s, off_t off) {
+ static const int xing_offset[2][2] = {{32, 17}, {17, 9}};
+ unsigned int data;
+ unsigned char hdr[4];
+ int framesize, chans, spf, layer;
+
+ if ((s->flags & MP_STREAM_SEEK) == MP_STREAM_SEEK) {
+
+ if (!stream_seek(s, off)) return 0;
+
+ data = stream_read_dword(s);
+ hdr[0] = data >> 24;
+ hdr[1] = data >> 16;
+ hdr[2] = data >> 8;
+ hdr[3] = data;
+
+ if (!mp_check_mp3_header(data)) return 0;
+
+ framesize = mp_get_mp3_header(hdr, &chans, NULL, &spf, &layer, NULL);
+
+ if (framesize == -1 || layer != 3) return 0;
+
+ /* Xing / Info (at variable position: 32, 17 or 9 bytes after header) */
+
+ if (!stream_skip(s, xing_offset[spf < 1152][chans == 1])) return 0;
+
+ data = stream_read_dword(s);
+
+ if (data == MKBETAG('X','i','n','g') || data == MKBETAG('I','n','f','o')) {
+ data = stream_read_dword(s);
+
+ if (data & 0x1) // frames field is present
+ return stream_read_dword(s); // frames
+ }
+
+ /* VBRI (at fixed position: 32 bytes after header) */
+
+ if (!stream_seek(s, off + 4 + 32)) return 0;
+
+ data = stream_read_dword(s);
+
+ if (data == MKBETAG('V','B','R','I')) {
+ data = stream_read_word(s);
+
+ if (data == 1) { // check version
+ if (!stream_skip(s, 8)) return 0; // skip delay, quality and bytes
+ return stream_read_dword(s); // frames
+ }
+ }
+ }
+
+ return 0;
+}
+
static int demux_audio_open(demuxer_t* demuxer) {
stream_t *s;
sh_audio_t* sh_audio;
@@ -269,6 +332,7 @@ static int demux_audio_open(demuxer_t* d
// mp3_hdrs list is sorted first by next_frame_pos and then by frame_pos
mp3_hdr_t *mp3_hdrs = NULL, *mp3_found = NULL;
da_priv_t* priv;
+ double duration;
s = demuxer->stream;
@@ -345,7 +409,7 @@ static int demux_audio_open(demuxer_t* d
sh_audio->wf->nBlockAlign = mp3_found->mpa_spf;
sh_audio->wf->wBitsPerSample = 16;
sh_audio->wf->cbSize = 0;
- sh_audio->i_bps = sh_audio->wf->nAvgBytesPerSec;
+ duration = (double) mp3_vbr_frames(s, demuxer->movi_start) * mp3_found->mpa_spf / mp3_found->mp3_freq;
free(mp3_found);
mp3_found = NULL;
if(s->end_pos && (s->flags & MP_STREAM_SEEK) == MP_STREAM_SEEK) {
@@ -381,6 +445,8 @@ static int demux_audio_open(demuxer_t* d
demux_info_add(demuxer,"Genre",genres[g]);
}
}
+ if (duration && demuxer->movi_end && demuxer->movi_end > demuxer->movi_start) sh_audio->wf->nAvgBytesPerSec = (demuxer->movi_end - demuxer->movi_start) / duration;
+ sh_audio->i_bps = sh_audio->wf->nAvgBytesPerSec;
break;
case WAV: {
unsigned int chunk_type;
More information about the MPlayer-cvslog
mailing list