Merge "Only check the codec specific data when the output buffer contains kKeyIsCodecConfig in MP4 writer" into gingerbread
This commit is contained in:
@@ -1377,91 +1377,6 @@ void MPEG4Writer::Track::threadEntry() {
|
|||||||
|
|
||||||
mGotAllCodecSpecificData = true;
|
mGotAllCodecSpecificData = true;
|
||||||
continue;
|
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
|
// Make a deep copy of the MediaBuffer and Metadata and release
|
||||||
@@ -1962,6 +1877,8 @@ void MPEG4Writer::Track::writeTrackHeader(
|
|||||||
mOwner->writeInt32(samplerate << 16);
|
mOwner->writeInt32(samplerate << 16);
|
||||||
if (!strcasecmp(MEDIA_MIMETYPE_AUDIO_AAC, mime)) {
|
if (!strcasecmp(MEDIA_MIMETYPE_AUDIO_AAC, mime)) {
|
||||||
mOwner->beginBox("esds");
|
mOwner->beginBox("esds");
|
||||||
|
CHECK(mCodecSpecificData);
|
||||||
|
CHECK(mCodecSpecificDataSize > 0);
|
||||||
|
|
||||||
mOwner->writeInt32(0); // version=0, flags=0
|
mOwner->writeInt32(0); // version=0, flags=0
|
||||||
mOwner->writeInt8(0x03); // ES_DescrTag
|
mOwner->writeInt8(0x03); // ES_DescrTag
|
||||||
@@ -2039,6 +1956,8 @@ void MPEG4Writer::Track::writeTrackHeader(
|
|||||||
mOwner->writeInt16(0x18); // depth
|
mOwner->writeInt16(0x18); // depth
|
||||||
mOwner->writeInt16(-1); // predefined
|
mOwner->writeInt16(-1); // predefined
|
||||||
|
|
||||||
|
CHECK(mCodecSpecificData);
|
||||||
|
CHECK(mCodecSpecificDataSize > 0);
|
||||||
CHECK(23 + mCodecSpecificDataSize < 128);
|
CHECK(23 + mCodecSpecificDataSize < 128);
|
||||||
|
|
||||||
if (!strcasecmp(MEDIA_MIMETYPE_VIDEO_MPEG4, mime)) {
|
if (!strcasecmp(MEDIA_MIMETYPE_VIDEO_MPEG4, mime)) {
|
||||||
@@ -2086,6 +2005,8 @@ void MPEG4Writer::Track::writeTrackHeader(
|
|||||||
|
|
||||||
mOwner->endBox(); // d263
|
mOwner->endBox(); // d263
|
||||||
} else if (!strcasecmp(MEDIA_MIMETYPE_VIDEO_AVC, mime)) {
|
} else if (!strcasecmp(MEDIA_MIMETYPE_VIDEO_AVC, mime)) {
|
||||||
|
CHECK(mCodecSpecificData);
|
||||||
|
CHECK(mCodecSpecificDataSize > 0);
|
||||||
mOwner->beginBox("avcC");
|
mOwner->beginBox("avcC");
|
||||||
mOwner->write(mCodecSpecificData, mCodecSpecificDataSize);
|
mOwner->write(mCodecSpecificData, mCodecSpecificDataSize);
|
||||||
mOwner->endBox(); // avcC
|
mOwner->endBox(); // avcC
|
||||||
|
|||||||
@@ -337,14 +337,18 @@ status_t AVCEncoder::read(
|
|||||||
|
|
||||||
MediaBuffer *outputBuffer;
|
MediaBuffer *outputBuffer;
|
||||||
CHECK_EQ(OK, mGroup->acquire_buffer(&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;
|
int32_t type;
|
||||||
AVCEnc_Status encoderStatus = AVCENC_SUCCESS;
|
AVCEnc_Status encoderStatus = AVCENC_SUCCESS;
|
||||||
|
|
||||||
// Return SPS and PPS for the first two buffers
|
// Combine SPS and PPS and place them in the very first output buffer
|
||||||
if (!mSpsPpsHeaderReceived) {
|
// 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);
|
encoderStatus = PVAVCEncodeNAL(mHandle, outPtr, &dataLength, &type);
|
||||||
if (encoderStatus == AVCENC_WRONG_STATE) {
|
if (encoderStatus == AVCENC_WRONG_STATE) {
|
||||||
mSpsPpsHeaderReceived = true;
|
mSpsPpsHeaderReceived = true;
|
||||||
@@ -352,11 +356,22 @@ status_t AVCEncoder::read(
|
|||||||
} else {
|
} else {
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case AVC_NALTYPE_SPS:
|
case AVC_NALTYPE_SPS:
|
||||||
case AVC_NALTYPE_PPS:
|
|
||||||
LOGV("%s received",
|
|
||||||
(type == AVC_NALTYPE_SPS)? "SPS": "PPS");
|
|
||||||
++mNumInputFrames;
|
++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;
|
*out = outputBuffer;
|
||||||
return OK;
|
return OK;
|
||||||
default:
|
default:
|
||||||
|
|||||||
Reference in New Issue
Block a user