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

Commit 18b4adfd authored by Chong Zhang's avatar Chong Zhang
Browse files

Extract and write pasp box

Handle pasp box in extractor and muxer.

Do not write pasp box [1:1] if the track format doesn't specify it,
since the pasp box setting will override the sar in bitstream.

bug: 158240484
bug: 154734285
test:
MediaTranscoder, MediaTranscodingService unit tests
cts tests:
MediaExtractorTest
MediaMuxerTest
MediaMetadataRetrieverTest
MediaRecorderTest

Change-Id: I1a7100458f91f8c56fff554164777ffbcf30d49e
parent 425f5edb
Loading
Loading
Loading
Loading
+35 −0
Original line number Diff line number Diff line
@@ -2879,6 +2879,21 @@ status_t MPEG4Extractor::parseChunk(off64_t *offset, int depth) {
            break;
        }

        case FOURCC("pasp"):
        {
            *offset += chunk_size;
            // this must be in a VisualSampleEntry box under the Sample Description Box ('stsd')
            // ignore otherwise
            if (depth >= 2 && mPath[depth - 2] == FOURCC("stsd")) {
                status_t err = parsePaspBox(data_offset, chunk_data_size);
                if (err != OK) {
                    return err;
                }
            }

            break;
        }

        case FOURCC("titl"):
        case FOURCC("perf"):
        case FOURCC("auth"):
@@ -4050,6 +4065,26 @@ status_t MPEG4Extractor::parseColorInfo(off64_t offset, size_t size) {
    return OK;
}

status_t MPEG4Extractor::parsePaspBox(off64_t offset, size_t size) {
    if (size < 8 || size == SIZE_MAX || mLastTrack == NULL) {
        return ERROR_MALFORMED;
    }

    uint32_t data[2]; // hSpacing, vSpacing
    if (mDataSource->readAt(offset, data, 8) < 8) {
        return ERROR_IO;
    }
    uint32_t hSpacing = ntohl(data[0]);
    uint32_t vSpacing = ntohl(data[1]);

    if (hSpacing != 0 && vSpacing != 0) {
        AMediaFormat_setInt32(mLastTrack->meta, AMEDIAFORMAT_KEY_SAR_WIDTH, hSpacing);
        AMediaFormat_setInt32(mLastTrack->meta, AMEDIAFORMAT_KEY_SAR_HEIGHT, vSpacing);
    }

    return OK;
}

status_t MPEG4Extractor::parse3GPPMetaData(off64_t offset, size_t size, int depth) {
    if (size < 4 || size == SIZE_MAX) {
        return ERROR_MALFORMED;
+1 −0
Original line number Diff line number Diff line
@@ -160,6 +160,7 @@ private:
    status_t parseChunk(off64_t *offset, int depth);
    status_t parseITunesMetaData(off64_t offset, size_t size);
    status_t parseColorInfo(off64_t offset, size_t size);
    status_t parsePaspBox(off64_t offset, size_t size);
    status_t parse3GPPMetaData(off64_t offset, size_t size, int depth);
    void parseID3v2MetaData(off64_t offset, uint64_t size);
    status_t parseQTMetaKey(off64_t data_offset, size_t data_size);
+12 −4
Original line number Diff line number Diff line
@@ -4687,11 +4687,19 @@ void MPEG4Writer::Track::writeD263Box() {

// This is useful if the pixel is not square
void MPEG4Writer::Track::writePaspBox() {
    // Do not write 'pasp' box unless the track format specifies it.
    // According to ISO/IEC 14496-12 (ISO base media file format), 'pasp' box
    // is optional. If present, it overrides the SAR from the video CSD. Only
    // set it if the track format specifically requests that.
    int32_t hSpacing, vSpacing;
    if (mMeta->findInt32(kKeySARWidth, &hSpacing) && (hSpacing > 0)
            && mMeta->findInt32(kKeySARHeight, &vSpacing) && (vSpacing > 0)) {
        mOwner->beginBox("pasp");
    mOwner->writeInt32(1 << 16);  // hspacing
    mOwner->writeInt32(1 << 16);  // vspacing
        mOwner->writeInt32(hSpacing);  // hspacing
        mOwner->writeInt32(vSpacing);  // vspacing
        mOwner->endBox();  // pasp
    }
}

int64_t MPEG4Writer::Track::getStartTimeOffsetTimeUs() const {
    int64_t trackStartTimeOffsetUs = 0;