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

Commit 2b05ca30 authored by zhongli.wang's avatar zhongli.wang Committed by android-build-merger
Browse files

Merge "Fix no sound with FDR-AX100 recorded 4k video" am: 1984ca70

am: 88ab23b3

Change-Id: If081a864902872becae6662e5c63dcefdcbe9ac8
parents e9214d9d 88ab23b3
Loading
Loading
Loading
Loading
+104 −21
Original line number Diff line number Diff line
@@ -66,6 +66,8 @@ enum {
    kMaxAtomSize = 64 * 1024 * 1024,
};

static const size_t  kMaxPcmFrameSize = 8192;

class MPEG4Source : public MediaTrack {
public:
    // Caller retains ownership of both "dataSource" and "sampleTable".
@@ -125,6 +127,7 @@ private:

    bool mIsAVC;
    bool mIsHEVC;
    bool mIsPcm;
    size_t mNALLengthSize;

    bool mStarted;
@@ -324,6 +327,11 @@ static const char *FourCC2MIME(uint32_t fourcc) {
        case FOURCC('h', 'v', 'c', '1'):
        case FOURCC('h', 'e', 'v', '1'):
            return MEDIA_MIMETYPE_VIDEO_HEVC;

        case FOURCC('t', 'w', 'o', 's'):
        case FOURCC('s', 'o', 'w', 't'):
            return MEDIA_MIMETYPE_AUDIO_RAW;

        default:
            ALOGW("Unknown fourcc: %c%c%c%c",
                   (fourcc >> 24) & 0xff,
@@ -1480,6 +1488,8 @@ status_t MPEG4Extractor::parseChunk(off64_t *offset, int depth) {
        case FOURCC('e', 'n', 'c', 'a'):
        case FOURCC('s', 'a', 'm', 'r'):
        case FOURCC('s', 'a', 'w', 'b'):
        case FOURCC('t', 'w', 'o', 's'):
        case FOURCC('s', 'o', 'w', 't'):
        {
            if (mIsQT && chunk_type == FOURCC('m', 'p', '4', 'a')
                    && depth >= 1 && mPath[depth - 1] == FOURCC('w', 'a', 'v', 'e')) {
@@ -1549,6 +1559,13 @@ status_t MPEG4Extractor::parseChunk(off64_t *offset, int depth) {
                // if the chunk type is enca, we'll get the type from the frma box later
                mLastTrack->meta.setCString(kKeyMIMEType, FourCC2MIME(chunk_type));
                AdjustChannelsAndRate(chunk_type, &num_channels, &sample_rate);

                if (!strcasecmp(MEDIA_MIMETYPE_AUDIO_RAW, FourCC2MIME(chunk_type))) {
                    mLastTrack->meta.setInt32(kKeyBitsPerSample, sample_size);
                    if (chunk_type == FOURCC('t', 'w', 'o', 's')) {
                        mLastTrack->meta.setInt32(kKeyPcmBigEndian, 1);
                    }
                }
            }
            ALOGV("*** coding='%s' %d channels, size %d, rate %d\n",
                   chunk, num_channels, sample_size, sample_rate);
@@ -3864,6 +3881,7 @@ MPEG4Source::MPEG4Source(
      mCurrentSampleInfoOffsets(NULL),
      mIsAVC(false),
      mIsHEVC(false),
      mIsPcm(false),
      mNALLengthSize(0),
      mStarted(false),
      mGroup(NULL),
@@ -3925,6 +3943,27 @@ MPEG4Source::MPEG4Source(
        mNALLengthSize = 1 + (ptr[14 + 7] & 3);
    }

    mIsPcm = !strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_RAW);

    if (mIsPcm) {
        int32_t numChannels = 0;
        int32_t bitsPerSample = 0;
        CHECK(mFormat.findInt32(kKeyBitsPerSample, &bitsPerSample));
        CHECK(mFormat.findInt32(kKeyChannelCount, &numChannels));

        int32_t bytesPerSample = bitsPerSample >> 3;
        int32_t pcmSampleSize = bytesPerSample * numChannels;

        size_t maxSampleSize;
        status_t err = mSampleTable->getMaxSampleSize(&maxSampleSize);
        if (err != OK || maxSampleSize != static_cast<size_t>(pcmSampleSize) || bitsPerSample != 16) {
            // Not supported
            mIsPcm = false;
        } else {
            mFormat.setInt32(kKeyMaxInputSize, pcmSampleSize * kMaxPcmFrameSize);
        }
    }

    CHECK(format.findInt32(kKeyTrackID, &mTrackId));

}
@@ -4839,6 +4878,49 @@ status_t MPEG4Source::read(

    if ((!mIsAVC && !mIsHEVC) || mWantsNALFragments) {
        if (newBuffer) {
            if (mIsPcm) {
                // The twos' PCM block reader assumes that all samples has the same size.

                uint32_t samplesToRead = mSampleTable->getLastSampleIndexInChunk()
                                                      - mCurrentSampleIndex + 1;
                if (samplesToRead > kMaxPcmFrameSize) {
                    samplesToRead = kMaxPcmFrameSize;
                }

                ALOGV("Reading %d PCM frames of size %zu at index %d to stop of chunk at %d",
                      samplesToRead, size, mCurrentSampleIndex,
                      mSampleTable->getLastSampleIndexInChunk());

                size_t totalSize = samplesToRead * size;
                uint8_t* buf = (uint8_t *)mBuffer->data();
                ssize_t bytesRead = mDataSource->readAt(offset, buf, totalSize);
                if (bytesRead < (ssize_t)totalSize) {
                    mBuffer->release();
                    mBuffer = NULL;

                    return ERROR_IO;
                }

                mBuffer->meta_data().clear();
                mBuffer->meta_data().setInt64(kKeyTime, ((int64_t)cts * 1000000) / mTimescale);
                mBuffer->meta_data().setInt32(kKeyIsSyncFrame, 1);

                int32_t byteOrder;
                mFormat.findInt32(kKeyPcmBigEndian, &byteOrder);

                if (byteOrder == 1) {
                    // Big-endian -> little-endian
                    uint16_t *dstData = (uint16_t *)buf;
                    uint16_t *srcData = (uint16_t *)buf;

                    for (size_t j = 0; j < bytesRead / sizeof(uint16_t); j++) {
                         dstData[j] = ntohs(srcData[j]);
                    }
                }

                mCurrentSampleIndex += samplesToRead;
                mBuffer->set_range(0, totalSize);
            } else {
                ssize_t num_bytes_read =
                    mDataSource->readAt(offset, (uint8_t *)mBuffer->data(), size);

@@ -4868,6 +4950,7 @@ status_t MPEG4Source::read(

                ++mCurrentSampleIndex;
            }
        }

        if (!mIsAVC && !mIsHEVC) {
            *out = mBuffer;
+5 −0
Original line number Diff line number Diff line
@@ -36,6 +36,11 @@ struct SampleIterator {
    uint32_t getSampleTime() const { return mCurrentSampleTime; }
    uint32_t getSampleDuration() const { return mCurrentSampleDuration; }

    uint32_t getLastSampleIndexInChunk() const {
        return mCurrentSampleIndex + mSamplesPerChunk -
                ((mCurrentSampleIndex - mFirstChunkSampleIndex) % mSamplesPerChunk) - 1;
    }

    status_t getSampleSizeDirect(
            uint32_t sampleIndex, size_t *size);

+5 −0
Original line number Diff line number Diff line
@@ -946,6 +946,11 @@ status_t SampleTable::getSampleSize_l(
            sampleIndex, sampleSize);
}

uint32_t SampleTable::getLastSampleIndexInChunk() {
    Mutex::Autolock autoLock(mLock);
    return mSampleIterator->getLastSampleIndexInChunk();
}

status_t SampleTable::getMetaDataForSample(
        uint32_t sampleIndex,
        off64_t *offset,
+3 −0
Original line number Diff line number Diff line
@@ -69,6 +69,9 @@ public:
            bool *isSyncSample = NULL,
            uint32_t *sampleDuration = NULL);

    // call only after getMetaDataForSample has been called successfully.
    uint32_t getLastSampleIndexInChunk();

    enum {
        kFlagBefore,
        kFlagAfter,
+3 −0
Original line number Diff line number Diff line
@@ -53,6 +53,7 @@ enum {
    kKeyFrameRate         = 'frmR',  // int32_t (video frame rate fps)
    kKeyBitRate           = 'brte',  // int32_t (bps)
    kKeyMaxBitRate        = 'mxBr',  // int32_t (bps)
    kKeyBitsPerSample     = 'bits',  // int32_t (bits per sample)
    kKeyStreamHeader      = 'stHd',  // raw data
    kKeyESDS              = 'esds',  // raw data
    kKeyAACProfile        = 'aacp',  // int32_t
@@ -225,6 +226,8 @@ enum {
    kKeyExifOffset       = 'exof', // int64_t, Exif data offset
    kKeyExifSize         = 'exsz', // int64_t, Exif data size
    kKeyIsExif           = 'exif', // bool (int32_t) buffer contains exif data block

    kKeyPcmBigEndian     = 'pcmb', // bool (int32_t)
};

enum {