Skip to content

Commit b411579

Browse files
committed
Fix Xing seeking when TOC[0] == 0
A file purchased from the Amazon mp3 store had two 0 entries at the start of the TOC (presumably because there was a lot of silence at the beginning, which compresses well), which made TOC based seeking think the TOC was not valid. b/6170518 Change-Id: Ie7135b4af06ebb925f63a374be780cf3a9404347
1 parent 467ec7e commit b411579

File tree

2 files changed

+15
-10
lines changed

2 files changed

+15
-10
lines changed

media/libstagefright/XINGSeeker.cpp

Lines changed: 13 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ namespace android {
2424
static bool parse_xing_header(
2525
const sp<DataSource> &source, off64_t first_frame_pos,
2626
int32_t *frame_number = NULL, int32_t *byte_number = NULL,
27-
unsigned char *table_of_contents = NULL,
27+
unsigned char *table_of_contents = NULL, bool *toc_is_valid = NULL,
2828
int32_t *quality_indicator = NULL, int64_t *duration = NULL);
2929

3030
// static
@@ -36,7 +36,7 @@ sp<XINGSeeker> XINGSeeker::CreateFromSource(
3636

3737
if (!parse_xing_header(
3838
source, first_frame_pos,
39-
NULL, &seeker->mSizeBytes, seeker->mTableOfContents,
39+
NULL, &seeker->mSizeBytes, seeker->mTOC, &seeker->mTOCValid,
4040
NULL, &seeker->mDurationUs)) {
4141
return NULL;
4242
}
@@ -60,7 +60,7 @@ bool XINGSeeker::getDuration(int64_t *durationUs) {
6060
}
6161

6262
bool XINGSeeker::getOffsetForTime(int64_t *timeUs, off64_t *pos) {
63-
if (mSizeBytes == 0 || mTableOfContents[0] <= 0 || mDurationUs < 0) {
63+
if (mSizeBytes == 0 || !mTOCValid || mDurationUs < 0) {
6464
return false;
6565
}
6666

@@ -76,10 +76,10 @@ bool XINGSeeker::getOffsetForTime(int64_t *timeUs, off64_t *pos) {
7676
if ( a == 0 ) {
7777
fa = 0.0f;
7878
} else {
79-
fa = (float)mTableOfContents[a-1];
79+
fa = (float)mTOC[a-1];
8080
}
8181
if ( a < 99 ) {
82-
fb = (float)mTableOfContents[a];
82+
fb = (float)mTOC[a];
8383
} else {
8484
fb = 256.0f;
8585
}
@@ -94,16 +94,17 @@ bool XINGSeeker::getOffsetForTime(int64_t *timeUs, off64_t *pos) {
9494
static bool parse_xing_header(
9595
const sp<DataSource> &source, off64_t first_frame_pos,
9696
int32_t *frame_number, int32_t *byte_number,
97-
unsigned char *table_of_contents, int32_t *quality_indicator,
97+
unsigned char *table_of_contents, bool *toc_valid,
98+
int32_t *quality_indicator,
9899
int64_t *duration) {
99100
if (frame_number) {
100101
*frame_number = 0;
101102
}
102103
if (byte_number) {
103104
*byte_number = 0;
104105
}
105-
if (table_of_contents) {
106-
table_of_contents[0] = 0;
106+
if (toc_valid) {
107+
*toc_valid = false;
107108
}
108109
if (quality_indicator) {
109110
*quality_indicator = 0;
@@ -199,10 +200,13 @@ static bool parse_xing_header(
199200
offset += 4;
200201
}
201202
if (flags & 0x0004) { // TOC field is present
202-
if (table_of_contents) {
203+
if (table_of_contents) {
203204
if (source->readAt(offset + 1, table_of_contents, 99) < 99) {
204205
return false;
205206
}
207+
if (toc_valid) {
208+
*toc_valid = true;
209+
}
206210
}
207211
offset += 100;
208212
}

media/libstagefright/include/XINGSeeker.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,8 @@ struct XINGSeeker : public MP3Seeker {
3737
int32_t mSizeBytes;
3838

3939
// TOC entries in XING header. Skip the first one since it's always 0.
40-
unsigned char mTableOfContents[99];
40+
unsigned char mTOC[99];
41+
bool mTOCValid;
4142

4243
XINGSeeker();
4344

0 commit comments

Comments
 (0)