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

Commit aa63a9a7 authored by Ayushi Khopkar's avatar Ayushi Khopkar
Browse files

Interleave buffers while sending to writer

Test: ./amrnb_writer_fuzzer
Test: ./amrwb_writer_fuzzer
Test: ./mpeg4_writer_fuzzer
Test: ./ogg_writer_fuzzer
Test: ./webm_writer_fuzzer
Bug: 173672210
Bug: 173672657
Bug: 173672212
Bug: 173672344

Change-Id: I5a08507459e4072f599468dc2f618b3b0175a961
parent d518e906
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -29,7 +29,7 @@ Fuzzer for writers supports the following parameters:

| Parameter| Valid Values| Configured Value|
|------------- |-------------| ----- |
| `mime` | 0. `audio/3gpp` 1. `audio/amr-wb` 2. `audio/vorbis` 3. `audio/opus` 4. `audio/mp4a-latm` 5. `video/avc` 6. `video/hevc` 7. `video/mp4v-es` 8. `video/3gpp` 9. `video/x-vnd.on2.vp8` 10. `video/x-vnd.on2.vp9` | All the bits of 2nd byte of data for first track and 11th byte of data for second track (if present) modulus 10 |
| `mime` | 0. `audio/3gpp` 1. `audio/amr-wb` 2. `audio/vorbis` 3. `audio/opus` 4. `audio/mp4a-latm` 5. `audio/mpeg` 6. `audio/mpeg-L1` 7. `audio/mpeg-L2` 8. `audio/midi` 9. `audio/qcelp` 10. `audio/g711-alaw` 11. `audio/g711-mlaw` 12. `audio/flac` 13. `audio/aac-adts` 14. `audio/gsm` 15. `audio/ac3` 16. `audio/eac3` 17. `audio/eac3-joc` 18. `audio/ac4` 19. `audio/scrambled` 20. `audio/alac` 21. `audio/x-ms-wma` 22. `audio/x-adpcm-ms` 23. `audio/x-adpcm-dvi-ima` 24. `video/avc` 25. `video/hevc` 26. `video/mp4v-es` 27. `video/3gpp` 28. `video/x-vnd.on2.vp8` 29. `video/x-vnd.on2.vp9` 30. `video/av01` 31. `video/mpeg2` 32. `video/dolby-vision` 33. `video/scrambled` 34. `video/divx` 35. `video/divx3` 36. `video/xvid` 37. `video/x-motion-jpeg` 38. `text/3gpp-tt` 39. `application/x-subrip` 40. `text/vtt` 41. `text/cea-608` 42. `text/cea-708` 43. `application/x-id3v4` | All the bits of 2nd byte of data for first track and 11th byte of data for second track and 20th byte of data for third track(if present) modulus 44 |
| `channel-count` | In the range `0 to INT32_MAX` | All the bits of 3rd byte to 6th bytes of data if first track is audio and 12th to 15th bytes of data if second track is audio |
| `sample-rate` | In the range `1 to INT32_MAX` | All the bits of 7th byte to 10th bytes of data if first track is audio and 16th to 19th bytes of data if second track is audio |
| `height` | In the range `0 to INT32_MAX` | All the bits of 3rd byte to 6th bytes of data if first track is video and 12th to 15th bytes of data if second track is video |
+58 −27
Original line number Diff line number Diff line
@@ -53,7 +53,7 @@ int32_t WriterFuzzerBase::BufferSource::getNumCsds(int32_t trackIndex) {
    return mNumCsds[trackIndex];
}

vector<FrameData> WriterFuzzerBase::BufferSource::getFrameList(int32_t trackIndex) {
vector<FrameData> &WriterFuzzerBase::BufferSource::getFrameList(int32_t trackIndex) {
    return mFrameList[trackIndex];
}

@@ -92,9 +92,8 @@ void WriterFuzzerBase::BufferSource::getFrameInfo() {
                } else {
                    break;
                }
                mFrameList[trackIndex].insert(
                    mFrameList[trackIndex].begin(),
                    FrameData{static_cast<int32_t>(bufferSize), flags, pts, framePtr});
                mFrameList[trackIndex].insert(mFrameList[trackIndex].begin(),
                                              FrameData{bufferSize, flags, pts, framePtr});
                bytesRemaining -= (frameSize + kMarkerSize + kMarkerSuffixSize);
                --mReadIndex;
            }
@@ -105,31 +104,36 @@ void WriterFuzzerBase::BufferSource::getFrameInfo() {
         * Scenario where input data does not contain the custom frame markers.
         * Hence feed the entire data as single frame.
         */
        mFrameList[0].emplace_back(
            FrameData{static_cast<int32_t>(mSize - readIndexStart), 0, 0, mData + readIndexStart});
        mFrameList[0].emplace_back(FrameData{mSize - readIndexStart, 0, 0, mData + readIndexStart});
    }
}
bool WriterFuzzerBase::BufferSource::getTrackInfo(int32_t trackIndex) {
    if (mSize <= mReadIndex + 2 * sizeof(int) + sizeof(uint8_t)) {
    if (mSize <= mReadIndex + sizeof(uint8_t)) {
        return false;
    }
    size_t mimeTypeIdx = mData[mReadIndex] % kSupportedMimeTypes;
    char *mime = (char *)supportedMimeTypes[mimeTypeIdx].c_str();
    mParams[trackIndex].mime = mime;
    ++mReadIndex;
    mReadIndex += sizeof(uint8_t);

    if (mSize > mReadIndex + 2 * sizeof(int32_t)) {
        if (!strncmp(mime, "audio/", 6)) {
        copy(mData + mReadIndex, mData + mReadIndex + sizeof(int),
            copy(mData + mReadIndex, mData + mReadIndex + sizeof(int32_t),
                 reinterpret_cast<char *>(&mParams[trackIndex].channelCount));
        copy(mData + mReadIndex + sizeof(int), mData + mReadIndex + 2 * sizeof(int),
            copy(mData + mReadIndex + sizeof(int32_t), mData + mReadIndex + 2 * sizeof(int32_t),
                 reinterpret_cast<char *>(&mParams[trackIndex].sampleRate));
    } else {
        copy(mData + mReadIndex, mData + mReadIndex + sizeof(int),
        } else if (!strncmp(mime, "video/", 6)) {
            copy(mData + mReadIndex, mData + mReadIndex + sizeof(int32_t),
                 reinterpret_cast<char *>(&mParams[trackIndex].height));
        copy(mData + mReadIndex + sizeof(int), mData + mReadIndex + 2 * sizeof(int),
            copy(mData + mReadIndex + sizeof(int32_t), mData + mReadIndex + 2 * sizeof(int32_t),
                 reinterpret_cast<char *>(&mParams[trackIndex].width));
        }
    mReadIndex += 2 * sizeof(int);
        mReadIndex += 2 * sizeof(int32_t);
    } else {
        if (strncmp(mime, "text/", 5) && strncmp(mime, "application/", 12)) {
            return false;
        }
    }
    return true;
}

@@ -173,7 +177,7 @@ void WriterFuzzerBase::addWriterSource(int32_t trackIndex) {
        }
        format->setInt32("channel-count", params.channelCount);
        format->setInt32("sample-rate", params.sampleRate);
    } else {
    } else if (!strncmp(params.mime, "video/", 6)) {
        format->setInt32("width", params.width);
        format->setInt32("height", params.height);
    }
@@ -193,11 +197,10 @@ void WriterFuzzerBase::start() {
    mWriter->start(mFileMeta.get());
}

void WriterFuzzerBase::sendBuffersToWriter(sp<MediaAdapter> &currentTrack, int32_t trackIndex) {
    int32_t numCsds = mBufferSource->getNumCsds(trackIndex);
void WriterFuzzerBase::sendBuffersToWriter(sp<MediaAdapter> &currentTrack, int32_t trackIndex,
                                           int32_t startFrameIndex, int32_t endFrameIndex) {
    vector<FrameData> bufferInfo = mBufferSource->getFrameList(trackIndex);
    int32_t range = bufferInfo.size();
    for (int idx = numCsds; idx < range; ++idx) {
    for (int idx = startFrameIndex; idx < endFrameIndex; ++idx) {
        sp<ABuffer> buffer = new ABuffer((void *)bufferInfo[idx].buf, bufferInfo[idx].size);
        MediaBuffer *mediaBuffer = new MediaBuffer(buffer);

@@ -209,7 +212,7 @@ void WriterFuzzerBase::sendBuffersToWriter(sp<MediaAdapter> &currentTrack, int32

        // Just set the kKeyDecodingTime as the presentation time for now.
        sampleMetaData.setInt64(kKeyDecodingTime, bufferInfo[idx].timeUs);
        if (bufferInfo[idx].flags == 1) {
        if (bufferInfo[idx].flags == SampleFlag::SYNC_FLAG) {
            sampleMetaData.setInt32(kKeyIsSyncFrame, true);
        }

@@ -218,6 +221,28 @@ void WriterFuzzerBase::sendBuffersToWriter(sp<MediaAdapter> &currentTrack, int32
    }
}

void WriterFuzzerBase::sendBuffersInterleave(int32_t numTracks, uint8_t numBuffersInterleave) {
    int32_t currentFrameIndex[numTracks], remainingNumFrames[numTracks], numTrackFramesDone;
    for (int32_t idx = 0; idx < numTracks; ++idx) {
        currentFrameIndex[idx] = mBufferSource->getNumCsds(idx);
        remainingNumFrames[idx] = mBufferSource->getFrameList(idx).size() - currentFrameIndex[idx];
    }
    do {
        numTrackFramesDone = numTracks;
        for (int32_t idx = 0; idx < numTracks; ++idx) {
            if (remainingNumFrames[idx] > 0) {
                int32_t numFramesInterleave =
                    min(remainingNumFrames[idx], static_cast<int32_t>(numBuffersInterleave));
                sendBuffersToWriter(mCurrentTrack[idx], idx, currentFrameIndex[idx],
                                    currentFrameIndex[idx] + numFramesInterleave);
                currentFrameIndex[idx] += numFramesInterleave;
                remainingNumFrames[idx] -= numFramesInterleave;
                --numTrackFramesDone;
            }
        }
    } while (numTrackFramesDone < numTracks);
}

void WriterFuzzerBase::initFileWriterAndProcessData(const uint8_t *data, size_t size) {
    if (!createOutputFile()) {
        return;
@@ -225,6 +250,14 @@ void WriterFuzzerBase::initFileWriterAndProcessData(const uint8_t *data, size_t
    if (!createWriter()) {
        return;
    }

    if (size < 1) {
        return;
    }
    uint8_t numBuffersInterleave = (data[0] == 0 ? 1 : data[0]);
    ++data;
    --size;

    mBufferSource = new BufferSource(data, size);
    if (!mBufferSource) {
        return;
@@ -246,9 +279,7 @@ void WriterFuzzerBase::initFileWriterAndProcessData(const uint8_t *data, size_t
            addWriterSource(idx);
        }
        start();
        for (int32_t idx = 0; idx < mNumTracks; ++idx) {
            sendBuffersToWriter(mCurrentTrack[idx], idx);
        }
        sendBuffersInterleave(mNumTracks, numBuffersInterleave);
        for (int32_t idx = 0; idx < mNumTracks; ++idx) {
            if (mCurrentTrack[idx]) {
                mCurrentTrack[idx]->stop();
+55 −12
Original line number Diff line number Diff line
@@ -34,7 +34,7 @@
using namespace std;

constexpr uint32_t kMimeSize = 128;
constexpr uint8_t kMaxTrackCount = 2;
constexpr uint8_t kMaxTrackCount = 3;
constexpr uint32_t kMaxCSDStrlen = 16;
constexpr uint32_t kCodecConfigFlag = 32;

@@ -49,25 +49,65 @@ struct ConfigFormat {
};

struct FrameData {
    int32_t size;
    size_t size;
    uint8_t flags;
    int64_t timeUs;
    const uint8_t* buf;
};

static string supportedMimeTypes[] = {
    "audio/3gpp",      "audio/amr-wb",        "audio/vorbis",        "audio/opus",
    "audio/mp4a-latm", "video/avc",           "video/hevc",          "video/mp4v-es",
    "video/3gpp",      "video/x-vnd.on2.vp8", "video/x-vnd.on2.vp9",
};

enum {
static string supportedMimeTypes[] = {"audio/3gpp",
                                      "audio/amr-wb",
                                      "audio/vorbis",
                                      "audio/opus",
                                      "audio/mp4a-latm",
                                      "audio/mpeg",
                                      "audio/mpeg-L1",
                                      "audio/mpeg-L2",
                                      "audio/midi",
                                      "audio/qcelp",
                                      "audio/g711-alaw",
                                      "audio/g711-mlaw",
                                      "audio/flac",
                                      "audio/aac-adts",
                                      "audio/gsm",
                                      "audio/ac3",
                                      "audio/eac3",
                                      "audio/eac3-joc",
                                      "audio/ac4",
                                      "audio/scrambled",
                                      "audio/alac",
                                      "audio/x-ms-wma",
                                      "audio/x-adpcm-ms",
                                      "audio/x-adpcm-dvi-ima",
                                      "video/avc",
                                      "video/hevc",
                                      "video/mp4v-es",
                                      "video/3gpp",
                                      "video/x-vnd.on2.vp8",
                                      "video/x-vnd.on2.vp9",
                                      "video/av01",
                                      "video/mpeg2",
                                      "video/dolby-vision",
                                      "video/scrambled",
                                      "video/divx",
                                      "video/divx3",
                                      "video/xvid",
                                      "video/x-motion-jpeg",
                                      "text/3gpp-tt",
                                      "application/x-subrip",
                                      "text/vtt",
                                      "text/cea-608",
                                      "text/cea-708",
                                      "application/x-id3v4"};

enum SampleFlag {
    DEFAULT_FLAG = 0,
    SYNC_FLAG = 1,
    ENCRYPTED_FLAG = 2,
};

static uint8_t flagTypes[] = {DEFAULT_FLAG, SYNC_FLAG, ENCRYPTED_FLAG};
static uint8_t flagTypes[] = {SampleFlag::DEFAULT_FLAG, SampleFlag::SYNC_FLAG,
                              SampleFlag::ENCRYPTED_FLAG};

class WriterFuzzerBase {
   public:
@@ -105,7 +145,10 @@ class WriterFuzzerBase {

    void start();

    void sendBuffersToWriter(sp<MediaAdapter>& currentTrack, int32_t trackIndex);
    void sendBuffersToWriter(sp<MediaAdapter>& currentTrack, int32_t trackIndex,
                             int32_t startFrameIndex, int32_t endFrameIndex);

    void sendBuffersInterleave(int32_t numTracks, uint8_t numBuffersInterleave);

    void initFileWriterAndProcessData(const uint8_t* data, size_t size);

@@ -126,7 +169,7 @@ class WriterFuzzerBase {
        void getFrameInfo();
        ConfigFormat getConfigFormat(int32_t trackIndex);
        int32_t getNumCsds(int32_t trackIndex);
        vector<FrameData> getFrameList(int32_t trackIndex);
        vector<FrameData>& getFrameList(int32_t trackIndex);

       private:
        bool isMarker() { return (memcmp(&mData[mReadIndex], kMarker, kMarkerSize) == 0); }