diff options
author | James Dong <jdong@google.com> | 2011-03-11 11:02:17 -0800 |
---|---|---|
committer | James Dong <jdong@google.com> | 2011-03-11 11:02:17 -0800 |
commit | 070b2e1a5c63b4f5421a0d222e975652e33795bb (patch) | |
tree | 73a6a3323c3e55ccae087a7ad9a2e09501236e7e | |
parent | 367f41f8f61126c2ab34a34cc676756a9fc23ac2 (diff) | |
download | frameworks_base-070b2e1a5c63b4f5421a0d222e975652e33795bb.zip frameworks_base-070b2e1a5c63b4f5421a0d222e975652e33795bb.tar.gz frameworks_base-070b2e1a5c63b4f5421a0d222e975652e33795bb.tar.bz2 |
MP3Extractor and MP3 decoder fixes - DO NOT MERGE
cherry-picked the following patches from HC branch:
o PV's mp3 decoder mistreated inputBufferCurrentLength in unit of bytes as in unit of bits
o Do not enforce the rule in MP3Extractor that all audio frames in an mp3 file must have the same mode
o When the temp buffer wraps around, the next read position should start
from what have been read to avoid reading the same remaining bytes in
the buffer again.
o Speed up MP3Extractor using cached reads
bug - 4083532
Change-Id: I7bbd2bd358fd5ee322287866cb8ee0c2bb217fea
-rw-r--r-- | media/libstagefright/MP3Extractor.cpp | 49 | ||||
-rw-r--r-- | media/libstagefright/codecs/mp3dec/src/pvmp3_decode_header.cpp | 6 |
2 files changed, 47 insertions, 8 deletions
diff --git a/media/libstagefright/MP3Extractor.cpp b/media/libstagefright/MP3Extractor.cpp index b15c720..ed14a4b 100644 --- a/media/libstagefright/MP3Extractor.cpp +++ b/media/libstagefright/MP3Extractor.cpp @@ -37,10 +37,10 @@ namespace android { // Everything must match except for -// protection, bitrate, padding, private bits, mode extension, +// protection, bitrate, padding, private bits, mode, mode extension, // copyright bit, original bit and emphasis. // Yes ... there are things that must indeed match... -static const uint32_t kMask = 0xfffe0cc0; +static const uint32_t kMask = 0xfffe0c00; static bool get_mp3_frame_size( uint32_t header, size_t *frame_size, @@ -344,22 +344,55 @@ static bool Resync( off_t pos = *inout_pos; bool valid = false; + + const size_t kMaxReadBytes = 1024; + const off_t kMaxBytesChecked = 128 * 1024; + uint8_t buf[kMaxReadBytes]; + ssize_t bytesToRead = kMaxReadBytes; + ssize_t totalBytesRead = 0; + ssize_t remainingBytes = 0; + bool reachEOS = false; + uint8_t *tmp = buf; + do { - if (pos >= *inout_pos + 128 * 1024) { + if (pos >= *inout_pos + kMaxBytesChecked) { // Don't scan forever. LOGV("giving up at offset %ld", pos); break; } - uint8_t tmp[4]; - if (source->readAt(pos, tmp, 4) != 4) { - break; + if (remainingBytes < 4) { + if (reachEOS) { + break; + } else { + memcpy(buf, tmp, remainingBytes); + bytesToRead = kMaxReadBytes - remainingBytes; + + /* + * The next read position should start from the end of + * the last buffer, and thus should include the remaining + * bytes in the buffer. + */ + totalBytesRead = source->readAt(pos + remainingBytes, + buf + remainingBytes, + bytesToRead); + if (totalBytesRead <= 0) { + break; + } + reachEOS = (totalBytesRead != bytesToRead); + totalBytesRead += remainingBytes; + remainingBytes = totalBytesRead; + tmp = buf; + continue; + } } uint32_t header = U32_AT(tmp); if (match_header != 0 && (header & kMask) != (match_header & kMask)) { ++pos; + ++tmp; + --remainingBytes; continue; } @@ -368,6 +401,8 @@ static bool Resync( if (!get_mp3_frame_size(header, &frame_size, &sample_rate, &num_channels, &bitrate)) { ++pos; + ++tmp; + --remainingBytes; continue; } @@ -417,6 +452,8 @@ static bool Resync( } ++pos; + ++tmp; + --remainingBytes; } while (!valid); return valid; diff --git a/media/libstagefright/codecs/mp3dec/src/pvmp3_decode_header.cpp b/media/libstagefright/codecs/mp3dec/src/pvmp3_decode_header.cpp index 8b0250a..d443b7c 100644 --- a/media/libstagefright/codecs/mp3dec/src/pvmp3_decode_header.cpp +++ b/media/libstagefright/codecs/mp3dec/src/pvmp3_decode_header.cpp @@ -121,9 +121,11 @@ ERROR_CODE pvmp3_decode_header(tmp3Bits *inputStream, uint32 temp; /* - * Verify that at least the header is complete + * Verify that at least the header is complete + * Note that SYNC_WORD_LNGTH is in unit of bits, but inputBufferCurrentLength + * is in unit of bytes. */ - if (inputStream->inputBufferCurrentLength < (SYNC_WORD_LNGTH + 21)) + if (inputStream->inputBufferCurrentLength < ((SYNC_WORD_LNGTH + 21) >> 3)) { return NO_ENOUGH_MAIN_DATA_ERROR; } |