Merge "Extract embedded cover art (aka poster frame) in mp4 files"
diff --git a/cmds/stagefright/stagefright.cpp b/cmds/stagefright/stagefright.cpp
index a875c3a..01262fa 100644
--- a/cmds/stagefright/stagefright.cpp
+++ b/cmds/stagefright/stagefright.cpp
@@ -695,12 +695,14 @@
         for (int k = 0; k < argc; ++k) {
             const char *filename = argv[k];
 
+            bool failed = true;
             CHECK_EQ(retriever->setDataSource(filename), (status_t)OK);
             sp<IMemory> mem =
                     retriever->getFrameAtTime(-1,
                                     MediaSource::ReadOptions::SEEK_PREVIOUS_SYNC);
 
             if (mem != NULL) {
+                failed = false;
                 printf("getFrameAtTime(%s) => OK\n", filename);
 
                 VideoFrame *frame = (VideoFrame *)mem->pointer();
@@ -715,16 +717,21 @@
                             "/sdcard/out.jpg", bitmap,
                             SkImageEncoder::kJPEG_Type,
                             SkImageEncoder::kDefaultQuality));
-            } else {
+            }
+
+            {
                 mem = retriever->extractAlbumArt();
 
                 if (mem != NULL) {
+                    failed = false;
                     printf("extractAlbumArt(%s) => OK\n", filename);
-                } else {
-                    printf("both getFrameAtTime and extractAlbumArt "
-                           "failed on file '%s'.\n", filename);
                 }
             }
+
+            if (failed) {
+                printf("both getFrameAtTime and extractAlbumArt "
+                    "failed on file '%s'.\n", filename);
+            }
         }
 
         return 0;
diff --git a/media/libstagefright/MPEG4Extractor.cpp b/media/libstagefright/MPEG4Extractor.cpp
index 98ac044..5fe511f 100644
--- a/media/libstagefright/MPEG4Extractor.cpp
+++ b/media/libstagefright/MPEG4Extractor.cpp
@@ -653,6 +653,7 @@
     off64_t chunk_data_size = *offset + chunk_size - data_offset;
 
     if (chunk_type != FOURCC('c', 'p', 'r', 't')
+            && chunk_type != FOURCC('c', 'o', 'v', 'r')
             && mPath.size() == 5 && underMetaDataPath(mPath)) {
         off64_t stop_offset = *offset + chunk_size;
         *offset = data_offset;
@@ -1331,6 +1332,29 @@
             break;
         }
 
+        case FOURCC('c', 'o', 'v', 'r'):
+        {
+            if (mFileMetaData != NULL) {
+                LOGV("chunk_data_size = %lld and data_offset = %lld",
+                        chunk_data_size, data_offset);
+                uint8_t *buffer = new uint8_t[chunk_data_size + 1];
+                if (mDataSource->readAt(
+                    data_offset, buffer, chunk_data_size) != (ssize_t)chunk_data_size) {
+                    delete[] buffer;
+                    buffer = NULL;
+
+                    return ERROR_IO;
+                }
+                const int kSkipBytesOfDataBox = 16;
+                mFileMetaData->setData(
+                    kKeyAlbumArt, MetaData::TYPE_NONE,
+                    buffer + kSkipBytesOfDataBox, chunk_data_size - kSkipBytesOfDataBox);
+            }
+
+            *offset += chunk_size;
+            break;
+        }
+
         default:
         {
             *offset += chunk_size;
diff --git a/media/libstagefright/StagefrightMetadataRetriever.cpp b/media/libstagefright/StagefrightMetadataRetriever.cpp
index 4c3dc47..de3957b 100644
--- a/media/libstagefright/StagefrightMetadataRetriever.cpp
+++ b/media/libstagefright/StagefrightMetadataRetriever.cpp
@@ -317,6 +317,17 @@
         return NULL;
     }
 
+    const void *data;
+    uint32_t type;
+    size_t dataSize;
+    if (mExtractor->getMetaData()->findData(kKeyAlbumArt, &type, &data, &dataSize)
+            && mAlbumArt == NULL) {
+        mAlbumArt = new MediaAlbumArt;
+        mAlbumArt->mSize = dataSize;
+        mAlbumArt->mData = new uint8_t[dataSize];
+        memcpy(mAlbumArt->mData, data, dataSize);
+    }
+
     VideoFrame *frame =
         extractVideoFrameWithCodecFlags(
                 &mClient, trackMeta, source, OMXCodec::kPreferSoftwareCodecs,
@@ -408,7 +419,8 @@
     const void *data;
     uint32_t type;
     size_t dataSize;
-    if (meta->findData(kKeyAlbumArt, &type, &data, &dataSize)) {
+    if (meta->findData(kKeyAlbumArt, &type, &data, &dataSize)
+            && mAlbumArt == NULL) {
         mAlbumArt = new MediaAlbumArt;
         mAlbumArt->mSize = dataSize;
         mAlbumArt->mData = new uint8_t[dataSize];