Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit ca2273a4 authored by Shalaj Jain's avatar Shalaj Jain Committed by Steve Kondik
Browse files

libstagefright: Fix AV sync issues

- Add edit list support for video playback.

Change-Id: I67cb9026255ddfe2d946a6e5972705b1b0c8a527
CRs-Fixed: 362885
parent 1b09ce9b
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -123,6 +123,8 @@ enum {

    kKeyValidSamples      = 'valD',  // int32_t

    kKeyEditOffset        = 'edof',  // bool (int64_t)

    kKeyIsUnreadable      = 'unre',  // bool (int32_t)

    // An indication that a video buffer has been rendered.
+9 −0
Original line number Diff line number Diff line
@@ -2088,6 +2088,15 @@ void AwesomePlayer::onVideoEvent() {
    {
        Mutex::Autolock autoLock(mMiscStateLock);
        mVideoTimeUs = timeUs;

        int64_t decodingTime = timeUs;
        int64_t mEditTime = 0;
        mVideoTrack->getFormat( )->findInt64( kKeyEditOffset, &mEditTime );
        decodingTime += mEditTime;
        timeUs = decodingTime;

        mVideoTimeUs = timeUs;

    }

    SeekType wasSeeking = mSeeking;
+99 −2
Original line number Diff line number Diff line
@@ -848,6 +848,7 @@ status_t MPEG4Extractor::parseChunk(off64_t *offset, int depth) {
        case FOURCC('i', 'l', 's', 't'):
        case FOURCC('s', 'i', 'n', 'f'):
        case FOURCC('s', 'c', 'h', 'i'):
        case FOURCC('e', 'd', 't', 's'):
        {
            if (chunk_type == FOURCC('s', 't', 'b', 'l')) {
                ALOGV("sampleTable chunk is %d bytes long.", (size_t)chunk_size);
@@ -1041,6 +1042,93 @@ status_t MPEG4Extractor::parseChunk(off64_t *offset, int depth) {
                return ERROR_IO;
            }
            mPssh.push_back(pssh);
        }

        case FOURCC('e', 'l', 's', 't' ):
        {
            if (chunk_data_size < 4){
                return ERROR_MALFORMED;
            }

            uint8_t version;
            if (mDataSource->readAt(data_offset, &version, 1) < 1){
                return ERROR_IO;
            }

            uint8_t buffer[8];
            if (mDataSource->readAt(data_offset,
                buffer,
                sizeof(buffer)) < (ssize_t)sizeof(buffer)) {
                return ERROR_IO;
            }

            uint32_t entry_count = U32_AT(&buffer[4]);
            int64_t timeUs = 0;

            if( version == 1 ){
                uint8_t buffer[8 + entry_count * 20];
                if (mDataSource->readAt(data_offset,
                    buffer,
                    sizeof(buffer)) < (ssize_t)sizeof(buffer)) {
                    return ERROR_IO;
                }

                int64_t mvhdTimeScale = 0;
                mFileMetaData->findInt64( kKeyEditOffset, &mvhdTimeScale );

                uint64_t segment_duration[entry_count];
                int64_t media_time[entry_count];
                for (uint32_t i = 0; i < entry_count; i++ ){
                    segment_duration[i] = U64_AT(&buffer[8 + i * 20]);
                    media_time[i] = U64_AT(&buffer[8 + 8 + i * 20]);

                    if( media_time[i] == -1 ){
                        if( mvhdTimeScale != 0 ){
                            int64_t editTime = (int64_t)(segment_duration[i] * 1000000 )/mvhdTimeScale;
                            mLastTrack->meta->setInt64( kKeyEditOffset, editTime );
                            if (mLastTrack->meta->findInt64(kKeyDuration,&timeUs))
                            {
                                mLastTrack->meta->setInt64(kKeyDuration,(editTime + timeUs));
                            }
                        }
                    }
                }

                int16_t media_rate_integer;
                int16_t media_rate_fraction = 0;
            }
            else { //version == 0
                uint8_t buffer[8 + entry_count * 12];
                if (mDataSource->readAt(data_offset,
                    buffer,
                    sizeof(buffer)) < (ssize_t)sizeof(buffer)) {
                    return ERROR_IO;
                }

                uint32_t segment_duration[entry_count];
                int32_t media_time[entry_count];

                int32_t mvhdTimeScale = 0;
                mFileMetaData->findInt32( kKeyEditOffset, &mvhdTimeScale );

                for (uint32_t i = 0; i < entry_count; i++ ){
                    segment_duration[i] = U32_AT(&buffer[8 + i * 12]);
                    media_time[i] = U32_AT(&buffer[8 + 4 + i * 20]);

                    if( media_time[i] == -1 ){
                        if( mvhdTimeScale != 0 ){
                            int64_t editTime = (int64_t)(segment_duration[i] * 1000000 )/mvhdTimeScale;
                            mLastTrack->meta->setInt64( kKeyEditOffset, editTime );
                            if (mLastTrack->meta->findInt64(kKeyDuration,&timeUs))
                            {
                                mLastTrack->meta->setInt64(kKeyDuration,(editTime + timeUs));
                            }
                        }
                    }
                }
                int16_t media_rate_integer;
                int16_t media_rate_fraction = 0;
            }

            *offset += chunk_size;
            break;
@@ -1100,6 +1188,11 @@ status_t MPEG4Extractor::parseChunk(off64_t *offset, int depth) {
            }
            mLastTrack->meta->setInt64(
                    kKeyDuration, (duration * 1000000) / mLastTrack->timescale);
            int64_t timeUs = 0;
            if (mLastTrack->meta->findInt64( kKeyEditOffset, &timeUs))
            {
                mLastTrack->meta->setInt64(kKeyDuration,(duration * 1000000) / mLastTrack->timescale + timeUs);
            }

            uint8_t lang[2];
            off64_t lang_offset;
@@ -1621,11 +1714,11 @@ status_t MPEG4Extractor::parseChunk(off64_t *offset, int depth) {

        case FOURCC('m', 'v', 'h', 'd'):
        {
            if (chunk_data_size < 12) {
            if (chunk_data_size < 12) { //increase to 16?
                return ERROR_MALFORMED;
            }

            uint8_t header[12];
            uint8_t header[16];
            if (mDataSource->readAt(
                        data_offset, header, sizeof(header))
                    < (ssize_t)sizeof(header)) {
@@ -1635,10 +1728,14 @@ status_t MPEG4Extractor::parseChunk(off64_t *offset, int depth) {
            int64_t creationTime;
            if (header[0] == 1) {
                creationTime = U64_AT(&header[4]);
                mFileMetaData->setInt64(kKeyEditOffset, 0 );
            } else if (header[0] != 0) {
                return ERROR_MALFORMED;
            } else {
                creationTime = U32_AT(&header[4]);
                int32_t mvTimeScale = U32_AT(&header[12]);

                mFileMetaData->setInt32(kKeyEditOffset, mvTimeScale );
            }

            String8 s;