Merge "Only check the codec specific data when the output buffer contains kKeyIsCodecConfig in MP4 writer" into gingerbread

This commit is contained in:
James Dong
2010-08-10 10:41:29 -07:00
committed by Android (Google) Code Review
2 changed files with 29 additions and 93 deletions

View File

@@ -1377,91 +1377,6 @@ void MPEG4Writer::Track::threadEntry() {
mGotAllCodecSpecificData = true;
continue;
} else if (!mGotAllCodecSpecificData &&
count == 1 && mIsMPEG4 && mCodecSpecificData == NULL) {
// The TI mpeg4 encoder does not properly set the
// codec-specific-data flag.
const uint8_t *data =
(const uint8_t *)buffer->data() + buffer->range_offset();
const size_t size = buffer->range_length();
size_t offset = 0;
while (offset + 3 < size) {
if (data[offset] == 0x00 && data[offset + 1] == 0x00
&& data[offset + 2] == 0x01 && data[offset + 3] == 0xb6) {
break;
}
++offset;
}
// CHECK(offset + 3 < size);
if (offset + 3 >= size) {
// XXX assume the entire first chunk of data is the codec specific
// data.
offset = size;
}
mCodecSpecificDataSize = offset;
mCodecSpecificData = malloc(offset);
memcpy(mCodecSpecificData, data, offset);
buffer->set_range(buffer->range_offset() + offset, size - offset);
if (size == offset) {
buffer->release();
buffer = NULL;
continue;
}
mGotAllCodecSpecificData = true;
} else if (!mGotAllCodecSpecificData && mIsAvc && count < 3) {
// The TI video encoder does not flag codec specific data
// as such and also splits up SPS and PPS across two buffers.
const uint8_t *data =
(const uint8_t *)buffer->data() + buffer->range_offset();
size_t size = buffer->range_length();
CHECK(count == 2 || mCodecSpecificData == NULL);
size_t offset = mCodecSpecificDataSize;
mCodecSpecificDataSize += size + 4;
mCodecSpecificData =
realloc(mCodecSpecificData, mCodecSpecificDataSize);
memcpy((uint8_t *)mCodecSpecificData + offset,
"\x00\x00\x00\x01", 4);
memcpy((uint8_t *)mCodecSpecificData + offset + 4, data, size);
buffer->release();
buffer = NULL;
if (count == 2) {
void *tmp = mCodecSpecificData;
size = mCodecSpecificDataSize;
mCodecSpecificData = NULL;
mCodecSpecificDataSize = 0;
status_t err = makeAVCCodecSpecificData(
(const uint8_t *)tmp, size);
free(tmp);
tmp = NULL;
CHECK_EQ(OK, err);
mGotAllCodecSpecificData = true;
}
continue;
}
if (!mGotAllCodecSpecificData) {
mGotAllCodecSpecificData = true;
}
// Make a deep copy of the MediaBuffer and Metadata and release
@@ -1962,6 +1877,8 @@ void MPEG4Writer::Track::writeTrackHeader(
mOwner->writeInt32(samplerate << 16);
if (!strcasecmp(MEDIA_MIMETYPE_AUDIO_AAC, mime)) {
mOwner->beginBox("esds");
CHECK(mCodecSpecificData);
CHECK(mCodecSpecificDataSize > 0);
mOwner->writeInt32(0); // version=0, flags=0
mOwner->writeInt8(0x03); // ES_DescrTag
@@ -2039,6 +1956,8 @@ void MPEG4Writer::Track::writeTrackHeader(
mOwner->writeInt16(0x18); // depth
mOwner->writeInt16(-1); // predefined
CHECK(mCodecSpecificData);
CHECK(mCodecSpecificDataSize > 0);
CHECK(23 + mCodecSpecificDataSize < 128);
if (!strcasecmp(MEDIA_MIMETYPE_VIDEO_MPEG4, mime)) {
@@ -2086,6 +2005,8 @@ void MPEG4Writer::Track::writeTrackHeader(
mOwner->endBox(); // d263
} else if (!strcasecmp(MEDIA_MIMETYPE_VIDEO_AVC, mime)) {
CHECK(mCodecSpecificData);
CHECK(mCodecSpecificDataSize > 0);
mOwner->beginBox("avcC");
mOwner->write(mCodecSpecificData, mCodecSpecificDataSize);
mOwner->endBox(); // avcC

View File

@@ -337,14 +337,18 @@ status_t AVCEncoder::read(
MediaBuffer *outputBuffer;
CHECK_EQ(OK, mGroup->acquire_buffer(&outputBuffer));
uint8_t *outPtr = (uint8_t *) outputBuffer->data();
uint32_t dataLength = outputBuffer->size();
// Add 4 bytes for the start code 0x00000001
uint8_t *outPtr = (uint8_t *) outputBuffer->data() + 4;
uint32_t dataLength = outputBuffer->size() - 4;
int32_t type;
AVCEnc_Status encoderStatus = AVCENC_SUCCESS;
// Return SPS and PPS for the first two buffers
if (!mSpsPpsHeaderReceived) {
// Combine SPS and PPS and place them in the very first output buffer
// SPS and PPS are separated by start code 0x00000001
// Assume that we have exactly one SPS and exactly one PPS.
while (!mSpsPpsHeaderReceived && mNumInputFrames <= 0) {
encoderStatus = PVAVCEncodeNAL(mHandle, outPtr, &dataLength, &type);
if (encoderStatus == AVCENC_WRONG_STATE) {
mSpsPpsHeaderReceived = true;
@@ -352,11 +356,22 @@ status_t AVCEncoder::read(
} else {
switch (type) {
case AVC_NALTYPE_SPS:
case AVC_NALTYPE_PPS:
LOGV("%s received",
(type == AVC_NALTYPE_SPS)? "SPS": "PPS");
++mNumInputFrames;
outputBuffer->set_range(0, dataLength);
memcpy(outputBuffer->data(), "\x00\x00\x00\x01", 4);
outputBuffer->set_range(0, dataLength + 4);
outPtr += (dataLength + 4); // 4 bytes for next start code
dataLength = outputBuffer->size() -
(outputBuffer->range_length() + 4);
break;
case AVC_NALTYPE_PPS:
++mNumInputFrames;
memcpy(((uint8_t *) outputBuffer->data()) +
outputBuffer->range_length(),
"\x00\x00\x00\x01", 4);
outputBuffer->set_range(0,
dataLength + outputBuffer->range_length() + 4);
outputBuffer->meta_data()->setInt32(kKeyIsCodecConfig, 1);
outputBuffer->meta_data()->setInt64(kKeyTime, 0);
*out = outputBuffer;
return OK;
default: