Merge "Add 3D rotation to View"
diff --git a/media/libstagefright/MPEG4Writer.cpp b/media/libstagefright/MPEG4Writer.cpp
index 20fbc05..c860c5c 100644
--- a/media/libstagefright/MPEG4Writer.cpp
+++ b/media/libstagefright/MPEG4Writer.cpp
@@ -1377,91 +1377,6 @@
 
             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 @@
                   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 @@
                   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 @@
 
                       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
diff --git a/media/libstagefright/codecs/avc/enc/AVCEncoder.cpp b/media/libstagefright/codecs/avc/enc/AVCEncoder.cpp
index d5eb156..18320cf 100644
--- a/media/libstagefright/codecs/avc/enc/AVCEncoder.cpp
+++ b/media/libstagefright/codecs/avc/enc/AVCEncoder.cpp
@@ -337,14 +337,18 @@
 
     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 @@
         } 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: