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

Commit 42ddfc94 authored by Andreas Huber's avatar Andreas Huber Committed by Android (Google) Code Review
Browse files

Merge "Return runtime errors instead of asserting in MPEG4 file format...

Merge "Return runtime errors instead of asserting in MPEG4 file format validation, also add more validation to ensure presence of codec specific data for avc, aac and mpeg4."
parents f82c7665 5ee0bce5
Loading
Loading
Loading
Loading
+85 −26
Original line number Diff line number Diff line
@@ -463,7 +463,10 @@ status_t MPEG4Extractor::parseChunk(off_t *offset, int depth) {
                return err;
            }
        }
        CHECK_EQ(*offset, stop_offset);

        if (*offset != stop_offset) {
            return ERROR_MALFORMED;
        }

        return OK;
    }
@@ -496,6 +499,23 @@ status_t MPEG4Extractor::parseChunk(off_t *offset, int depth) {
                }
            }

            if (chunk_type == FOURCC('t', 'r', 'a', 'k')) {
                Track *track = new Track;
                track->next = NULL;
                if (mLastTrack) {
                    mLastTrack->next = track;
                } else {
                    mFirstTrack = track;
                }
                mLastTrack = track;

                track->meta = new MetaData;
                track->includes_expensive_metadata = false;
                track->timescale = 0;
                track->sampleTable = new SampleTable(mDataSource);
                track->meta->setCString(kKeyMIMEType, "application/octet-stream");
            }

            off_t stop_offset = *offset + chunk_size;
            *offset = data_offset;
            while (*offset < stop_offset) {
@@ -504,9 +524,18 @@ status_t MPEG4Extractor::parseChunk(off_t *offset, int depth) {
                    return err;
                }
            }
            CHECK_EQ(*offset, stop_offset);

            if (chunk_type == FOURCC('m', 'o', 'o', 'v')) {
            if (*offset != stop_offset) {
                return ERROR_MALFORMED;
            }

            if (chunk_type == FOURCC('t', 'r', 'a', 'k')) {
                status_t err = verifyTrack(mLastTrack);

                if (err != OK) {
                    return err;
                }
            } else if (chunk_type == FOURCC('m', 'o', 'o', 'v')) {
                mHaveMetadata = true;

                return UNKNOWN_ERROR;  // Return a dummy error.
@@ -516,7 +545,9 @@ status_t MPEG4Extractor::parseChunk(off_t *offset, int depth) {

        case FOURCC('t', 'k', 'h', 'd'):
        {
            CHECK(chunk_data_size >= 4);
            if (chunk_data_size < 4) {
                return ERROR_MALFORMED;
            }

            uint8_t version;
            if (mDataSource->readAt(data_offset, &version, 1) < 1) {
@@ -562,21 +593,6 @@ status_t MPEG4Extractor::parseChunk(off_t *offset, int depth) {
                height = U32_AT(&buffer[80]);
            }

            Track *track = new Track;
            track->next = NULL;
            if (mLastTrack) {
                mLastTrack->next = track;
            } else {
                mFirstTrack = track;
            }
            mLastTrack = track;

            track->meta = new MetaData;
            track->includes_expensive_metadata = false;
            track->timescale = 0;
            track->sampleTable = new SampleTable(mDataSource);
            track->meta->setCString(kKeyMIMEType, "application/octet-stream");

            *offset += chunk_size;
            break;
        }
@@ -670,7 +686,10 @@ status_t MPEG4Extractor::parseChunk(off_t *offset, int depth) {
            }

            uint8_t buffer[8];
            CHECK(chunk_data_size >= (off_t)sizeof(buffer));
            if (chunk_data_size < (off_t)sizeof(buffer)) {
                return ERROR_MALFORMED;
            }

            if (mDataSource->readAt(
                        data_offset, buffer, 8) < 8) {
                return ERROR_IO;
@@ -696,7 +715,10 @@ status_t MPEG4Extractor::parseChunk(off_t *offset, int depth) {
                    return err;
                }
            }
            CHECK_EQ(*offset, stop_offset);

            if (*offset != stop_offset) {
                return ERROR_MALFORMED;
            }
            break;
        }

@@ -748,7 +770,10 @@ status_t MPEG4Extractor::parseChunk(off_t *offset, int depth) {
                    return err;
                }
            }
            CHECK_EQ(*offset, stop_offset);

            if (*offset != stop_offset) {
                return ERROR_MALFORMED;
            }
            break;
        }

@@ -792,7 +817,10 @@ status_t MPEG4Extractor::parseChunk(off_t *offset, int depth) {
                    return err;
                }
            }
            CHECK_EQ(*offset, stop_offset);

            if (*offset != stop_offset) {
                return ERROR_MALFORMED;
            }
            break;
        }

@@ -942,7 +970,10 @@ status_t MPEG4Extractor::parseChunk(off_t *offset, int depth) {
        case FOURCC('m', 'e', 't', 'a'):
        {
            uint8_t buffer[4];
            CHECK(chunk_data_size >= (off_t)sizeof(buffer));
            if (chunk_data_size < (off_t)sizeof(buffer)) {
                return ERROR_MALFORMED;
            }

            if (mDataSource->readAt(
                        data_offset, buffer, 4) < 4) {
                return ERROR_IO;
@@ -961,7 +992,10 @@ status_t MPEG4Extractor::parseChunk(off_t *offset, int depth) {
                    return err;
                }
            }
            CHECK_EQ(*offset, stop_offset);

            if (*offset != stop_offset) {
                return ERROR_MALFORMED;
            }
            break;
        }

@@ -995,8 +1029,9 @@ status_t MPEG4Extractor::parseChunk(off_t *offset, int depth) {
            int64_t creationTime;
            if (header[0] == 1) {
                creationTime = U64_AT(&header[4]);
            } else if (header[0] != 0) {
                return ERROR_MALFORMED;
            } else {
                CHECK_EQ(header[0], 0);
                creationTime = U32_AT(&header[4]);
            }

@@ -1174,6 +1209,30 @@ sp<MediaSource> MPEG4Extractor::getTrack(size_t index) {
            track->meta, mDataSource, track->timescale, track->sampleTable);
}

// static
status_t MPEG4Extractor::verifyTrack(Track *track) {
    const char *mime;
    CHECK(track->meta->findCString(kKeyMIMEType, &mime));

    uint32_t type;
    const void *data;
    size_t size;
    if (!strcasecmp(mime, MEDIA_MIMETYPE_VIDEO_AVC)) {
        if (!track->meta->findData(kKeyAVCC, &type, &data, &size)
                || type != kTypeAVCC) {
            return ERROR_MALFORMED;
        }
    } else if (!strcasecmp(mime, MEDIA_MIMETYPE_VIDEO_MPEG4)
            || !strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AAC)) {
        if (!track->meta->findData(kKeyESDS, &type, &data, &size)
                || type != kTypeESDS) {
            return ERROR_MALFORMED;
        }
    }

    return OK;
}

status_t MPEG4Extractor::updateAudioTrackInfoFromESDS_MPEG4Audio(
        const void *esds_data, size_t esds_size) {
    ESDS esds(esds_data, esds_size);
+2 −0
Original line number Diff line number Diff line
@@ -68,6 +68,8 @@ private:
    status_t updateAudioTrackInfoFromESDS_MPEG4Audio(
            const void *esds_data, size_t esds_size);

    static status_t verifyTrack(Track *track);

    MPEG4Extractor(const MPEG4Extractor &);
    MPEG4Extractor &operator=(const MPEG4Extractor &);
};