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; }
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; }