sp<MetaData> setMPEG4Format(AVCodecContext *avctx)
{
    ALOGV("MPEG4");

    sp<ABuffer> csd = new ABuffer(avctx->extradata_size);
    memcpy(csd->data(), avctx->extradata, avctx->extradata_size);
    sp<ABuffer> esds = MakeMPEGVideoESDS(csd);

    sp<MetaData> meta = new MetaData;
    meta->setData(kKeyESDS, kTypeESDS, esds->data(), esds->size());
    meta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_MPEG4);

    return meta;
}
Пример #2
0
status_t ESExtractor::Track::dequeueAccessUnitMPEGVideo(sp<ABuffer> &mAccessUnit) {
    const uint8_t *data = mExtractor->mBuffer->data();
    size_t size = mExtractor->mBuffer->size();
    bool sawPictureStart = false;
    int pprevStartCode = -1;
    int prevStartCode = -1;
    int currentStartCode = -1;

    size_t offset = 0;
    size_t lastGOPOff = -1;

    while (offset + 3 < size) {
        if (U24_AT(data + offset) != 0x000001) {
            ++offset;
            continue;
        }
        pprevStartCode = prevStartCode;
        prevStartCode = currentStartCode;
        currentStartCode = data[offset + 3];
        ALOGV("pprevStartCode:0x%x,prevStartCode:0x%x,currentStartCode:0x%x,offset:%d",pprevStartCode,prevStartCode,currentStartCode,offset);

        if (currentStartCode == 0xb3 && mQueueFormat == NULL) {
            memmove(mExtractor->mBuffer->data(), mExtractor->mBuffer->data() + offset, size - offset);
            size -= offset;
            offset = 0;
            mExtractor->mBuffer->setRange(0, size);
        }

        if ((prevStartCode == 0xb3 && currentStartCode != 0xb5)
                || (pprevStartCode == 0xb3 && prevStartCode == 0xb5)) {
            // seqHeader without/with extension

            if (mQueueFormat == NULL) {
                CHECK_GE(size, 7u);

                unsigned width =
                    (data[4] << 4) | data[5] >> 4;

                unsigned height =
                    ((data[5] & 0x0f) << 8) | data[6];
                
                mQueueFormat = new MetaData;
                mQueueFormat->setCString(kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_MPEG2);
                mQueueFormat->setInt32(kKeyWidth, (int32_t)width);
                mQueueFormat->setInt32(kKeyHeight, (int32_t)height);

                ALOGI("found MPEG2 video codec config (%d x %d)", width, height);

                sp<ABuffer> csd = new ABuffer(offset);
                memcpy(csd->data(), data, offset);

                memmove(mExtractor->mBuffer->data(),
                        mExtractor->mBuffer->data() + offset,
                        mExtractor->mBuffer->size() - offset);

                mExtractor->mBuffer->setRange(0, mExtractor->mBuffer->size() - offset);
                size -= offset;
                offset = 0;

                sp<ABuffer> esds = MakeMPEGVideoESDS(csd);
                mQueueFormat->setData(kKeyESDS, kTypeESDS, esds->data(), esds->size());
                ALOGV("dequeueAccessUnitMPEGVideo:get mQueueFormat,return GETFORMATDONE");
                return GETFORMATDONE;
            }
        }

        if (mQueueFormat != NULL && (currentStartCode == 0x00 || (sawPictureStart && currentStartCode == 0xB7))) { //ALPS00473447
            // Picture start
            ALOGV("dequeueAccessUnitMPEGVideo:Picture start");
            if (!sawPictureStart) {
                sawPictureStart = true;
            } else {
                mAccessUnit = new ABuffer(offset);
                memcpy(mAccessUnit->data(), data, offset);

                memmove(mExtractor->mBuffer->data(),
                        mExtractor->mBuffer->data() + offset,
                        mExtractor->mBuffer->size() - offset);

                mExtractor->mBuffer->setRange(0, mExtractor->mBuffer->size() - offset);

                offset = 0;
                mAccessUnit->meta()->setInt32("invt", (int32_t)true);
                mAccessUnit->meta()->setInt64("timeUs", 0);
                ALOGV("dequeueAccessUnitMPEGVideo:return OPCONTINUE");
                return GETAUDONE;
            }
        }
        ++offset;
    }