Merge "Cannot play a mov file with alac audio" into qt-dev
diff --git a/media/codec2/components/opus/C2SoftOpusEnc.cpp b/media/codec2/components/opus/C2SoftOpusEnc.cpp
index 384d58b..70d1965 100644
--- a/media/codec2/components/opus/C2SoftOpusEnc.cpp
+++ b/media/codec2/components/opus/C2SoftOpusEnc.cpp
@@ -471,11 +471,11 @@
         uint8_t* outPtr = wView.data() + mBytesEncoded;
         int encodedBytes =
             opus_multistream_encode(mEncoder, mInputBufferPcm16,
-                                    mNumSamplesPerFrame, outPtr, kMaxPayload);
+                                    mNumSamplesPerFrame, outPtr, kMaxPayload - mBytesEncoded);
         ALOGV("encoded %i Opus bytes from %zu PCM bytes", encodedBytes,
               processSize);
 
-        if (encodedBytes < 0 || encodedBytes > kMaxPayload) {
+        if (encodedBytes < 0 || encodedBytes > (kMaxPayload - mBytesEncoded)) {
             ALOGE("opus_encode failed, encodedBytes : %d", encodedBytes);
             mSignalledError = true;
             work->result = C2_CORRUPTED;
diff --git a/media/codec2/components/opus/C2SoftOpusEnc.h b/media/codec2/components/opus/C2SoftOpusEnc.h
index 69e5240..2b4d8f2 100644
--- a/media/codec2/components/opus/C2SoftOpusEnc.h
+++ b/media/codec2/components/opus/C2SoftOpusEnc.h
@@ -47,7 +47,9 @@
 private:
     /* OPUS_FRAMESIZE_20_MS */
     const int kFrameSize = 960;
-    const int kMaxPayload = 4000;
+    const int kMaxSampleRate = 48000;
+    const int kMinSampleRate = 8000;
+    const int kMaxPayload = (4000 * kMaxSampleRate) / kMinSampleRate;
     const int kMaxNumChannels = 8;
 
     std::shared_ptr<IntfImpl> mIntf;
diff --git a/media/codec2/sfplugin/Codec2Buffer.cpp b/media/codec2/sfplugin/Codec2Buffer.cpp
index c20ca73..702ad6f 100644
--- a/media/codec2/sfplugin/Codec2Buffer.cpp
+++ b/media/codec2/sfplugin/Codec2Buffer.cpp
@@ -201,9 +201,10 @@
      * \param colorFormat desired SDK color format for the MediaImage (if this is a flexible format,
      *        an attempt is made to simply represent the graphic view as a flexible SDK format
      *        without a memcpy)
+     * \param copy whether the converter is used for copy or not
      */
     GraphicView2MediaImageConverter(
-            const C2GraphicView &view, int32_t colorFormat)
+            const C2GraphicView &view, int32_t colorFormat, bool copy)
         : mInitCheck(NO_INIT),
           mView(view),
           mWidth(view.width()),
@@ -255,41 +256,44 @@
                 }
                 switch (mColorFormat) {
                     case COLOR_FormatYUV420Flexible:
-                    {  // try to map directly. check if the planes are near one another
-                        const uint8_t *minPtr = mView.data()[0];
-                        const uint8_t *maxPtr = mView.data()[0];
-                        int32_t planeSize = 0;
-                        for (uint32_t i = 0; i < layout.numPlanes; ++i) {
-                            const C2PlaneInfo &plane = layout.planes[i];
-                            ssize_t minOffset = plane.minOffset(mWidth, mHeight);
-                            ssize_t maxOffset = plane.maxOffset(mWidth, mHeight);
-                            if (minPtr > mView.data()[i] + minOffset) {
-                                minPtr = mView.data()[i] + minOffset;
-                            }
-                            if (maxPtr < mView.data()[i] + maxOffset) {
-                                maxPtr = mView.data()[i] + maxOffset;
-                            }
-                            planeSize += std::abs(plane.rowInc) * align(mHeight, 64)
-                                    / plane.rowSampling / plane.colSampling * divUp(mAllocatedDepth, 8u);
-                        }
-
-                        if ((maxPtr - minPtr + 1) <= planeSize) {
-                            // FIXME: this is risky as reading/writing data out of bound results in
-                            //        an undefined behavior, but gralloc does assume a contiguous
-                            //        mapping
+                        if (!copy) {
+                            // try to map directly. check if the planes are near one another
+                            const uint8_t *minPtr = mView.data()[0];
+                            const uint8_t *maxPtr = mView.data()[0];
+                            int32_t planeSize = 0;
                             for (uint32_t i = 0; i < layout.numPlanes; ++i) {
                                 const C2PlaneInfo &plane = layout.planes[i];
-                                mediaImage->mPlane[i].mOffset = mView.data()[i] - minPtr;
-                                mediaImage->mPlane[i].mColInc = plane.colInc;
-                                mediaImage->mPlane[i].mRowInc = plane.rowInc;
-                                mediaImage->mPlane[i].mHorizSubsampling = plane.colSampling;
-                                mediaImage->mPlane[i].mVertSubsampling = plane.rowSampling;
+                                ssize_t minOffset = plane.minOffset(mWidth, mHeight);
+                                ssize_t maxOffset = plane.maxOffset(mWidth, mHeight);
+                                if (minPtr > mView.data()[i] + minOffset) {
+                                    minPtr = mView.data()[i] + minOffset;
+                                }
+                                if (maxPtr < mView.data()[i] + maxOffset) {
+                                    maxPtr = mView.data()[i] + maxOffset;
+                                }
+                                planeSize += std::abs(plane.rowInc) * align(mHeight, 64)
+                                        / plane.rowSampling / plane.colSampling
+                                        * divUp(mAllocatedDepth, 8u);
                             }
-                            mWrapped = new ABuffer(const_cast<uint8_t *>(minPtr), maxPtr - minPtr + 1);
-                            break;
+
+                            if ((maxPtr - minPtr + 1) <= planeSize) {
+                                // FIXME: this is risky as reading/writing data out of bound results
+                                //        in an undefined behavior, but gralloc does assume a
+                                //        contiguous mapping
+                                for (uint32_t i = 0; i < layout.numPlanes; ++i) {
+                                    const C2PlaneInfo &plane = layout.planes[i];
+                                    mediaImage->mPlane[i].mOffset = mView.data()[i] - minPtr;
+                                    mediaImage->mPlane[i].mColInc = plane.colInc;
+                                    mediaImage->mPlane[i].mRowInc = plane.rowInc;
+                                    mediaImage->mPlane[i].mHorizSubsampling = plane.colSampling;
+                                    mediaImage->mPlane[i].mVertSubsampling = plane.rowSampling;
+                                }
+                                mWrapped = new ABuffer(const_cast<uint8_t *>(minPtr),
+                                                       maxPtr - minPtr + 1);
+                                break;
+                            }
                         }
-                    }
-                    [[fallthrough]];
+                        [[fallthrough]];
 
                     case COLOR_FormatYUV420Planar:
                     case COLOR_FormatYUV420PackedPlanar:
@@ -503,7 +507,7 @@
     int32_t colorFormat = COLOR_FormatYUV420Flexible;
     (void)format->findInt32("color-format", &colorFormat);
 
-    GraphicView2MediaImageConverter converter(view, colorFormat);
+    GraphicView2MediaImageConverter converter(view, colorFormat, false /* copy */);
     if (converter.initCheck() != OK) {
         ALOGD("Converter init failed: %d", converter.initCheck());
         return nullptr;
@@ -615,7 +619,7 @@
     int32_t colorFormat = COLOR_FormatYUV420Flexible;
     (void)format->findInt32("color-format", &colorFormat);
 
-    GraphicView2MediaImageConverter converter(*view, colorFormat);
+    GraphicView2MediaImageConverter converter(*view, colorFormat, false /* copy */);
     if (converter.initCheck() != OK) {
         ALOGD("Converter init failed: %d", converter.initCheck());
         return nullptr;
@@ -708,7 +712,7 @@
     const_cast<ConstGraphicBlockBuffer *>(this)->format()->findInt32("color-format", &colorFormat);
 
     GraphicView2MediaImageConverter converter(
-            buffer->data().graphicBlocks()[0].map().get(), colorFormat);
+            buffer->data().graphicBlocks()[0].map().get(), colorFormat, true /* copy */);
     if (converter.initCheck() != OK) {
         ALOGD("ConstGraphicBlockBuffer::canCopy: converter init failed: %d", converter.initCheck());
         return false;
@@ -730,7 +734,7 @@
     format()->findInt32("color-format", &colorFormat);
 
     GraphicView2MediaImageConverter converter(
-            buffer->data().graphicBlocks()[0].map().get(), colorFormat);
+            buffer->data().graphicBlocks()[0].map().get(), colorFormat, true /* copy */);
     if (converter.initCheck() != OK) {
         ALOGD("ConstGraphicBlockBuffer::copy: converter init failed: %d", converter.initCheck());
         return false;
diff --git a/media/codec2/sfplugin/utils/Codec2BufferUtils.cpp b/media/codec2/sfplugin/utils/Codec2BufferUtils.cpp
index 1e884ef..bf2a07e 100644
--- a/media/codec2/sfplugin/utils/Codec2BufferUtils.cpp
+++ b/media/codec2/sfplugin/utils/Codec2BufferUtils.cpp
@@ -137,14 +137,14 @@
         int32_t dst_stride_v = img->mPlane[2].mRowInc;
         if (IsNV12(view) && IsI420(img)) {
             if (!libyuv::NV12ToI420(src_y, src_stride_y, src_u, src_stride_u, dst_y, dst_stride_y,
-                                    dst_u, dst_stride_u, dst_v, dst_stride_v, view.width(),
-                                    view.height())) {
+                                    dst_u, dst_stride_u, dst_v, dst_stride_v, view.crop().width,
+                                    view.crop().height)) {
                 return OK;
             }
         } else {
             if (!libyuv::I420ToNV12(src_y, src_stride_y, src_u, src_stride_u, src_v, src_stride_v,
-                                    dst_y, dst_stride_y, dst_u, dst_stride_u, view.width(),
-                                    view.height())) {
+                                    dst_y, dst_stride_y, dst_u, dst_stride_u, view.crop().width,
+                                    view.crop().height)) {
                 return OK;
             }
         }
diff --git a/media/extractors/mkv/MatroskaExtractor.cpp b/media/extractors/mkv/MatroskaExtractor.cpp
index b1eb301..23022e4 100644
--- a/media/extractors/mkv/MatroskaExtractor.cpp
+++ b/media/extractors/mkv/MatroskaExtractor.cpp
@@ -2109,8 +2109,10 @@
 
                 if (!strcmp("A_AAC", codecID)) {
                     AMediaFormat_setString(meta, AMEDIAFORMAT_KEY_MIME, MEDIA_MIMETYPE_AUDIO_AAC);
-                    CHECK(codecPrivateSize >= 2);
-
+                    if (codecPrivateSize < 2) {
+                        ALOGW("Incomplete AAC Codec Info %zu byte", codecPrivateSize);
+                        continue;
+                    }
                     addESDSFromCodecPrivate(
                             meta, true, codecPrivate, codecPrivateSize);
                 } else if (!strcmp("A_VORBIS", codecID)) {
diff --git a/media/libstagefright/httplive/HTTPDownloader.cpp b/media/libstagefright/httplive/HTTPDownloader.cpp
index 59265fe..c7e92cd 100644
--- a/media/libstagefright/httplive/HTTPDownloader.cpp
+++ b/media/libstagefright/httplive/HTTPDownloader.cpp
@@ -157,6 +157,12 @@
                  buffer->size() + bufferRemaining);
 
             sp<ABuffer> copy = new ABuffer(buffer->size() + bufferRemaining);
+            if (copy->data() == NULL) {
+                android_errorWriteLog(0x534e4554, "68399439");
+                ALOGE("not enough memory to download: requesting %zu + %zu",
+                        buffer->size(), bufferRemaining);
+                return NO_MEMORY;
+            }
             memcpy(copy->data(), buffer->data(), buffer->size());
             copy->setRange(0, buffer->size());