Merge "Support .avi tracks that have a sample size of 1, i.e. samples != chunks"
This commit is contained in:
committed by
Android (Google) Code Review
commit
bf208ec91e
@@ -117,14 +117,12 @@ status_t AVIExtractor::AVISource::read(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int64_t timeUs =
|
|
||||||
(mSampleIndex * 1000000ll * mTrack.mRate) / mTrack.mScale;
|
|
||||||
|
|
||||||
off64_t offset;
|
off64_t offset;
|
||||||
size_t size;
|
size_t size;
|
||||||
bool isKey;
|
bool isKey;
|
||||||
|
int64_t timeUs;
|
||||||
status_t err = mExtractor->getSampleInfo(
|
status_t err = mExtractor->getSampleInfo(
|
||||||
mTrackIndex, mSampleIndex, &offset, &size, &isKey);
|
mTrackIndex, mSampleIndex, &offset, &size, &isKey, &timeUs);
|
||||||
|
|
||||||
++mSampleIndex;
|
++mSampleIndex;
|
||||||
|
|
||||||
@@ -396,6 +394,8 @@ status_t AVIExtractor::parseStreamHeader(off64_t offset, size_t size) {
|
|||||||
uint32_t rate = U32LE_AT(&data[20]);
|
uint32_t rate = U32LE_AT(&data[20]);
|
||||||
uint32_t scale = U32LE_AT(&data[24]);
|
uint32_t scale = U32LE_AT(&data[24]);
|
||||||
|
|
||||||
|
uint32_t sampleSize = U32LE_AT(&data[44]);
|
||||||
|
|
||||||
const char *mime = NULL;
|
const char *mime = NULL;
|
||||||
Track::Kind kind = Track::OTHER;
|
Track::Kind kind = Track::OTHER;
|
||||||
|
|
||||||
@@ -427,6 +427,7 @@ status_t AVIExtractor::parseStreamHeader(off64_t offset, size_t size) {
|
|||||||
track->mMeta = meta;
|
track->mMeta = meta;
|
||||||
track->mRate = rate;
|
track->mRate = rate;
|
||||||
track->mScale = scale;
|
track->mScale = scale;
|
||||||
|
track->mBytesPerSample = sampleSize;
|
||||||
track->mKind = kind;
|
track->mKind = kind;
|
||||||
track->mNumSyncSamples = 0;
|
track->mNumSyncSamples = 0;
|
||||||
track->mThumbnailSampleSize = 0;
|
track->mThumbnailSampleSize = 0;
|
||||||
@@ -612,11 +613,12 @@ status_t AVIExtractor::parseIndex(off64_t offset, size_t size) {
|
|||||||
off64_t offset;
|
off64_t offset;
|
||||||
size_t size;
|
size_t size;
|
||||||
bool isKey;
|
bool isKey;
|
||||||
status_t err = getSampleInfo(0, 0, &offset, &size, &isKey);
|
int64_t timeUs;
|
||||||
|
status_t err = getSampleInfo(0, 0, &offset, &size, &isKey, &timeUs);
|
||||||
|
|
||||||
if (err != OK) {
|
if (err != OK) {
|
||||||
mOffsetsAreAbsolute = !mOffsetsAreAbsolute;
|
mOffsetsAreAbsolute = !mOffsetsAreAbsolute;
|
||||||
err = getSampleInfo(0, 0, &offset, &size, &isKey);
|
err = getSampleInfo(0, 0, &offset, &size, &isKey, &timeUs);
|
||||||
|
|
||||||
if (err != OK) {
|
if (err != OK) {
|
||||||
return err;
|
return err;
|
||||||
@@ -630,8 +632,9 @@ status_t AVIExtractor::parseIndex(off64_t offset, size_t size) {
|
|||||||
for (size_t i = 0; i < mTracks.size(); ++i) {
|
for (size_t i = 0; i < mTracks.size(); ++i) {
|
||||||
Track *track = &mTracks.editItemAt(i);
|
Track *track = &mTracks.editItemAt(i);
|
||||||
|
|
||||||
int64_t durationUs =
|
int64_t durationUs;
|
||||||
(track->mSamples.size() * 1000000ll * track->mRate) / track->mScale;
|
CHECK_EQ((status_t)OK,
|
||||||
|
getSampleTime(i, track->mSamples.size() - 1, &durationUs));
|
||||||
|
|
||||||
LOGV("track %d duration = %.2f secs", i, durationUs / 1E6);
|
LOGV("track %d duration = %.2f secs", i, durationUs / 1E6);
|
||||||
|
|
||||||
@@ -645,9 +648,10 @@ status_t AVIExtractor::parseIndex(off64_t offset, size_t size) {
|
|||||||
|
|
||||||
if (!strncasecmp("video/", mime.c_str(), 6)
|
if (!strncasecmp("video/", mime.c_str(), 6)
|
||||||
&& track->mThumbnailSampleIndex >= 0) {
|
&& track->mThumbnailSampleIndex >= 0) {
|
||||||
int64_t thumbnailTimeUs =
|
int64_t thumbnailTimeUs;
|
||||||
(track->mThumbnailSampleIndex * 1000000ll * track->mRate)
|
CHECK_EQ((status_t)OK,
|
||||||
/ track->mScale;
|
getSampleTime(i, track->mThumbnailSampleIndex,
|
||||||
|
&thumbnailTimeUs));
|
||||||
|
|
||||||
track->mMeta->setInt64(kKeyThumbnailTime, thumbnailTimeUs);
|
track->mMeta->setInt64(kKeyThumbnailTime, thumbnailTimeUs);
|
||||||
|
|
||||||
@@ -659,6 +663,21 @@ status_t AVIExtractor::parseIndex(off64_t offset, size_t size) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (track->mBytesPerSample != 0) {
|
||||||
|
// Assume all chunks are the same size for now.
|
||||||
|
|
||||||
|
off64_t offset;
|
||||||
|
size_t size;
|
||||||
|
bool isKey;
|
||||||
|
int64_t sampleTimeUs;
|
||||||
|
CHECK_EQ((status_t)OK,
|
||||||
|
getSampleInfo(
|
||||||
|
i, 0,
|
||||||
|
&offset, &size, &isKey, &sampleTimeUs));
|
||||||
|
|
||||||
|
track->mRate *= size / track->mBytesPerSample;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
mFoundIndex = true;
|
mFoundIndex = true;
|
||||||
@@ -720,7 +739,9 @@ status_t AVIExtractor::addMPEG4CodecSpecificData(size_t trackIndex) {
|
|||||||
off64_t offset;
|
off64_t offset;
|
||||||
size_t size;
|
size_t size;
|
||||||
bool isKey;
|
bool isKey;
|
||||||
status_t err = getSampleInfo(trackIndex, 0, &offset, &size, &isKey);
|
int64_t timeUs;
|
||||||
|
status_t err =
|
||||||
|
getSampleInfo(trackIndex, 0, &offset, &size, &isKey, &timeUs);
|
||||||
|
|
||||||
if (err != OK) {
|
if (err != OK) {
|
||||||
return err;
|
return err;
|
||||||
@@ -762,7 +783,8 @@ status_t AVIExtractor::addMPEG4CodecSpecificData(size_t trackIndex) {
|
|||||||
|
|
||||||
status_t AVIExtractor::getSampleInfo(
|
status_t AVIExtractor::getSampleInfo(
|
||||||
size_t trackIndex, size_t sampleIndex,
|
size_t trackIndex, size_t sampleIndex,
|
||||||
off64_t *offset, size_t *size, bool *isKey) {
|
off64_t *offset, size_t *size, bool *isKey,
|
||||||
|
int64_t *sampleTimeUs) {
|
||||||
if (trackIndex >= mTracks.size()) {
|
if (trackIndex >= mTracks.size()) {
|
||||||
return -ERANGE;
|
return -ERANGE;
|
||||||
}
|
}
|
||||||
@@ -801,9 +823,20 @@ status_t AVIExtractor::getSampleInfo(
|
|||||||
|
|
||||||
*isKey = info.mIsKey;
|
*isKey = info.mIsKey;
|
||||||
|
|
||||||
|
*sampleTimeUs = (sampleIndex * 1000000ll * track.mRate) / track.mScale;
|
||||||
|
|
||||||
return OK;
|
return OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
status_t AVIExtractor::getSampleTime(
|
||||||
|
size_t trackIndex, size_t sampleIndex, int64_t *sampleTimeUs) {
|
||||||
|
off64_t offset;
|
||||||
|
size_t size;
|
||||||
|
bool isKey;
|
||||||
|
return getSampleInfo(
|
||||||
|
trackIndex, sampleIndex, &offset, &size, &isKey, sampleTimeUs);
|
||||||
|
}
|
||||||
|
|
||||||
status_t AVIExtractor::getSampleIndexAtTime(
|
status_t AVIExtractor::getSampleIndexAtTime(
|
||||||
size_t trackIndex,
|
size_t trackIndex,
|
||||||
int64_t timeUs, MediaSource::ReadOptions::SeekMode mode,
|
int64_t timeUs, MediaSource::ReadOptions::SeekMode mode,
|
||||||
|
|||||||
@@ -54,6 +54,11 @@ private:
|
|||||||
uint32_t mRate;
|
uint32_t mRate;
|
||||||
uint32_t mScale;
|
uint32_t mScale;
|
||||||
|
|
||||||
|
// If bytes per sample == 0, each chunk represents a single sample,
|
||||||
|
// otherwise each chunk should me a multiple of bytes-per-sample in
|
||||||
|
// size.
|
||||||
|
uint32_t mBytesPerSample;
|
||||||
|
|
||||||
enum Kind {
|
enum Kind {
|
||||||
AUDIO,
|
AUDIO,
|
||||||
VIDEO,
|
VIDEO,
|
||||||
@@ -84,7 +89,11 @@ private:
|
|||||||
|
|
||||||
status_t getSampleInfo(
|
status_t getSampleInfo(
|
||||||
size_t trackIndex, size_t sampleIndex,
|
size_t trackIndex, size_t sampleIndex,
|
||||||
off64_t *offset, size_t *size, bool *isKey);
|
off64_t *offset, size_t *size, bool *isKey,
|
||||||
|
int64_t *sampleTimeUs);
|
||||||
|
|
||||||
|
status_t getSampleTime(
|
||||||
|
size_t trackIndex, size_t sampleIndex, int64_t *sampleTimeUs);
|
||||||
|
|
||||||
status_t getSampleIndexAtTime(
|
status_t getSampleIndexAtTime(
|
||||||
size_t trackIndex,
|
size_t trackIndex,
|
||||||
|
|||||||
Reference in New Issue
Block a user