Discussion:
Wrong Length
gt
2011-05-30 09:56:07 UTC
Permalink
Hello list,

Today i noticed cmus displaying wrong length for tracks of a particular
album.

Here's a file from the album:
http://www.mediafire.com/?innox7aoojywck5

This file's actual length is 04:02m, while cmus is reporting it as
10:08m.

I confirmed the file length with mplayer, vlc, and mediainfo.
Johannes Weißl
2011-05-30 12:16:15 UTC
Permalink
Hi gt,
Post by gt
Today i noticed cmus displaying wrong length for tracks of a
particular album.
This file's actual length is 04:02m, while cmus is reporting it as
10:08m.
I confirmed the file length with mplayer, vlc, and mediainfo.
You are right, cmus displays the wrong duration... the function
xing_parse() is called at a position 2 bytes off ("ng" instead of
"Xing"). I will investigate it! Thanks for reporting!


Johannes
Johannes Weißl
2011-05-30 23:58:33 UTC
Permalink
from madplay
---
nomad.c | 28 +++++++++++++++++++---------
1 files changed, 19 insertions(+), 9 deletions(-)

diff --git a/nomad.c b/nomad.c
index e23eafe..b13b0c8 100644
--- a/nomad.c
+++ b/nomad.c
@@ -45,6 +45,9 @@
/* the number of samples of silence the decoder inserts at start */
#define DECODERDELAY 529

+#define XING_MAGIC (('X' << 24) | ('i' << 16) | ('n' << 8) | 'g')
+#define INFO_MAGIC (('I' << 24) | ('n' << 16) | ('f' << 8) | 'o')
+
struct seek_idx_entry {
off_t offset;
mad_timer_t timer;
@@ -218,6 +221,7 @@ static int parse_lame(struct nomad *nomad, struct mad_bitptr ptr, int bitlen)
static int xing_parse(struct nomad *nomad)
{
struct mad_bitptr ptr = nomad->stream.anc_ptr;
+ struct mad_bitptr start = ptr;
int oldbitlen = nomad->stream.anc_bitlen;
int bitlen = nomad->stream.anc_bitlen;
int bitsleft;
@@ -228,16 +232,22 @@ static int xing_parse(struct nomad *nomad)
if (bitlen < 64)
return -1;
xing_id = mad_bit_read(&ptr, 32);
- switch (xing_id) {
- case (('X' << 24) | ('i' << 16) | ('n' << 8) | 'g'):
- nomad->xing.is_info = 0;
- break;
- case (('I' << 24) | ('n' << 16) | ('f' << 8) | 'o'):
- nomad->xing.is_info = 1;
- break;
- default:
- return -1;
+ if (xing_id != XING_MAGIC && xing_id != INFO_MAGIC) {
+ /*
+ * Due to an unfortunate historical accident, a Xing VBR tag
+ * may be misplaced in a stream with CRC protection. We check
+ * for this by assuming the tag began two octets prior and the
+ * high bits of the following flags field are always zero.
+ */
+ if (xing_id != ((XING_MAGIC << 16) & 0xffffffffL) &&
+ xing_id != ((INFO_MAGIC << 16) & 0xffffffffL))
+ return -1;
+ xing_id >>= 16;
+ ptr = start;
+ mad_bit_skip(&ptr, 16);
+ bitlen += 16;
}
+ nomad->xing.is_info = ((xing_id & 0x0000ffffL) == (INFO_MAGIC & 0x0000ffffL));
nomad->xing.flags = mad_bit_read(&ptr, 32);
bitlen -= 64;
if (nomad->xing.flags & XING_FRAMES) {
--
1.7.5.3
Gregory Petrosyan
2011-05-31 20:28:30 UTC
Permalink
Post by Johannes Weißl
from madplay
---
nomad.c | 28 +++++++++++++++++++---------
1 files changed, 19 insertions(+), 9 deletions(-)
Thanks, merged to maint and master! gt, can you please double-check that
everything is OK now?

Gregory
gt
2011-06-01 06:18:00 UTC
Permalink
Post by Gregory Petrosyan
Post by Johannes Weißl
from madplay
---
nomad.c | 28 +++++++++++++++++++---------
1 files changed, 19 insertions(+), 9 deletions(-)
Thanks, merged to maint and master! gt, can you please double-check that
everything is OK now?
Gregory
Yes, the times are showing correctly now. Thanks.

Loading...