@@ -117,14 +117,12 @@ status_t AVIExtractor::AVISource::read(
117117 }
118118 }
119119
120- int64_t timeUs =
121- (mSampleIndex * 1000000ll * mTrack .mRate ) / mTrack .mScale ;
122-
123120 off64_t offset;
124121 size_t size;
125122 bool isKey;
123+ int64_t timeUs;
126124 status_t err = mExtractor ->getSampleInfo (
127- mTrackIndex , mSampleIndex , &offset, &size, &isKey);
125+ mTrackIndex , mSampleIndex , &offset, &size, &isKey, &timeUs );
128126
129127 ++mSampleIndex ;
130128
@@ -396,6 +394,8 @@ status_t AVIExtractor::parseStreamHeader(off64_t offset, size_t size) {
396394 uint32_t rate = U32LE_AT (&data[20 ]);
397395 uint32_t scale = U32LE_AT (&data[24 ]);
398396
397+ uint32_t sampleSize = U32LE_AT (&data[44 ]);
398+
399399 const char *mime = NULL ;
400400 Track::Kind kind = Track::OTHER;
401401
@@ -427,6 +427,7 @@ status_t AVIExtractor::parseStreamHeader(off64_t offset, size_t size) {
427427 track->mMeta = meta;
428428 track->mRate = rate;
429429 track->mScale = scale;
430+ track->mBytesPerSample = sampleSize;
430431 track->mKind = kind;
431432 track->mNumSyncSamples = 0 ;
432433 track->mThumbnailSampleSize = 0 ;
@@ -612,11 +613,12 @@ status_t AVIExtractor::parseIndex(off64_t offset, size_t size) {
612613 off64_t offset;
613614 size_t size;
614615 bool isKey;
615- status_t err = getSampleInfo (0 , 0 , &offset, &size, &isKey);
616+ int64_t timeUs;
617+ status_t err = getSampleInfo (0 , 0 , &offset, &size, &isKey, &timeUs);
616618
617619 if (err != OK) {
618620 mOffsetsAreAbsolute = !mOffsetsAreAbsolute ;
619- err = getSampleInfo (0 , 0 , &offset, &size, &isKey);
621+ err = getSampleInfo (0 , 0 , &offset, &size, &isKey, &timeUs );
620622
621623 if (err != OK) {
622624 return err;
@@ -630,8 +632,9 @@ status_t AVIExtractor::parseIndex(off64_t offset, size_t size) {
630632 for (size_t i = 0 ; i < mTracks .size (); ++i) {
631633 Track *track = &mTracks .editItemAt (i);
632634
633- int64_t durationUs =
634- (track->mSamples .size () * 1000000ll * track->mRate ) / track->mScale ;
635+ int64_t durationUs;
636+ CHECK_EQ ((status_t )OK,
637+ getSampleTime (i, track->mSamples .size () - 1 , &durationUs));
635638
636639 LOGV (" track %d duration = %.2f secs" , i, durationUs / 1E6 );
637640
@@ -645,9 +648,10 @@ status_t AVIExtractor::parseIndex(off64_t offset, size_t size) {
645648
646649 if (!strncasecmp (" video/" , mime.c_str (), 6 )
647650 && track->mThumbnailSampleIndex >= 0 ) {
648- int64_t thumbnailTimeUs =
649- (track->mThumbnailSampleIndex * 1000000ll * track->mRate )
650- / track->mScale ;
651+ int64_t thumbnailTimeUs;
652+ CHECK_EQ ((status_t )OK,
653+ getSampleTime (i, track->mThumbnailSampleIndex ,
654+ &thumbnailTimeUs));
651655
652656 track->mMeta ->setInt64 (kKeyThumbnailTime , thumbnailTimeUs);
653657
@@ -659,6 +663,21 @@ status_t AVIExtractor::parseIndex(off64_t offset, size_t size) {
659663 }
660664 }
661665 }
666+
667+ if (track->mBytesPerSample != 0 ) {
668+ // Assume all chunks are the same size for now.
669+
670+ off64_t offset;
671+ size_t size;
672+ bool isKey;
673+ int64_t sampleTimeUs;
674+ CHECK_EQ ((status_t )OK,
675+ getSampleInfo (
676+ i, 0 ,
677+ &offset, &size, &isKey, &sampleTimeUs));
678+
679+ track->mRate *= size / track->mBytesPerSample ;
680+ }
662681 }
663682
664683 mFoundIndex = true ;
@@ -720,7 +739,9 @@ status_t AVIExtractor::addMPEG4CodecSpecificData(size_t trackIndex) {
720739 off64_t offset;
721740 size_t size;
722741 bool isKey;
723- status_t err = getSampleInfo (trackIndex, 0 , &offset, &size, &isKey);
742+ int64_t timeUs;
743+ status_t err =
744+ getSampleInfo (trackIndex, 0 , &offset, &size, &isKey, &timeUs);
724745
725746 if (err != OK) {
726747 return err;
@@ -762,7 +783,8 @@ status_t AVIExtractor::addMPEG4CodecSpecificData(size_t trackIndex) {
762783
763784status_t AVIExtractor::getSampleInfo (
764785 size_t trackIndex, size_t sampleIndex,
765- off64_t *offset, size_t *size, bool *isKey) {
786+ off64_t *offset, size_t *size, bool *isKey,
787+ int64_t *sampleTimeUs) {
766788 if (trackIndex >= mTracks .size ()) {
767789 return -ERANGE;
768790 }
@@ -801,9 +823,20 @@ status_t AVIExtractor::getSampleInfo(
801823
802824 *isKey = info.mIsKey ;
803825
826+ *sampleTimeUs = (sampleIndex * 1000000ll * track.mRate ) / track.mScale ;
827+
804828 return OK;
805829}
806830
831+ status_t AVIExtractor::getSampleTime (
832+ size_t trackIndex, size_t sampleIndex, int64_t *sampleTimeUs) {
833+ off64_t offset;
834+ size_t size;
835+ bool isKey;
836+ return getSampleInfo (
837+ trackIndex, sampleIndex, &offset, &size, &isKey, sampleTimeUs);
838+ }
839+
807840status_t AVIExtractor::getSampleIndexAtTime (
808841 size_t trackIndex,
809842 int64_t timeUs, MediaSource::ReadOptions::SeekMode mode,
0 commit comments