Pass VP9 Codec Specific Data from the Container

WebM container now has a provision to specify the VP9 Profile
and Level information in the container. Pass it to the Decoder as
Codec-Specific-Data. The software VP9 decoder will merely ignore
it.

Bug: 28152818
Bug: 28380207
Bug: 25684127

Change-Id: I77e2dc333093a346df6671e5f8d6d918ed45f7fb
diff --git a/include/media/stagefright/MetaData.h b/include/media/stagefright/MetaData.h
index 4f7426d..ba375a2 100644
--- a/include/media/stagefright/MetaData.h
+++ b/include/media/stagefright/MetaData.h
@@ -62,6 +62,7 @@
     kKeyOpusHeader        = 'ohdr',  // raw data
     kKeyOpusCodecDelay    = 'ocod',  // uint64_t (codec delay in ns)
     kKeyOpusSeekPreRoll   = 'ospr',  // uint64_t (seek preroll in ns)
+    kKeyVp9CodecPrivate   = 'vp9p',  // raw data (vp9 csd information)
     kKeyWantsNALFragments = 'NALf',
     kKeyIsSyncFrame       = 'sync',  // int32_t (bool)
     kKeyIsCodecConfig     = 'conf',  // int32_t (bool)
diff --git a/media/libstagefright/Utils.cpp b/media/libstagefright/Utils.cpp
index 448f8aa..3e1badf 100644
--- a/media/libstagefright/Utils.cpp
+++ b/media/libstagefright/Utils.cpp
@@ -527,6 +527,16 @@
         buffer->meta()->setInt32("csd", true);
         buffer->meta()->setInt64("timeUs", 0);
         msg->setBuffer("csd-2", buffer);
+    } else if (meta->findData(kKeyVp9CodecPrivate, &type, &data, &size)) {
+        sp<ABuffer> buffer = new (std::nothrow) ABuffer(size);
+        if (buffer.get() == NULL || buffer->base() == NULL) {
+            return NO_MEMORY;
+        }
+        memcpy(buffer->data(), data, size);
+
+        buffer->meta()->setInt32("csd", true);
+        buffer->meta()->setInt64("timeUs", 0);
+        msg->setBuffer("csd-0", buffer);
     }
 
     // TODO expose "crypto-key"/kKeyCryptoKey through public api
diff --git a/media/libstagefright/codecs/on2/dec/SoftVPX.cpp b/media/libstagefright/codecs/on2/dec/SoftVPX.cpp
index 2a56ed5..ba1f263 100644
--- a/media/libstagefright/codecs/on2/dec/SoftVPX.cpp
+++ b/media/libstagefright/codecs/on2/dec/SoftVPX.cpp
@@ -228,6 +228,17 @@
 
         BufferInfo *inInfo = *inQueue.begin();
         OMX_BUFFERHEADERTYPE *inHeader = inInfo->mHeader;
+
+        // Software VP9 Decoder does not need the Codec Specific Data (CSD)
+        // (specified in http://www.webmproject.org/vp9/profiles/). Ignore it if
+        // it was passed.
+        if (inHeader->nFlags & OMX_BUFFERFLAG_CODECCONFIG) {
+            inQueue.erase(inQueue.begin());
+            inInfo->mOwnedByUs = false;
+            notifyEmptyBufferDone(inHeader);
+            continue;
+        }
+
         mTimeStamps[mTimeStampIdx] = inHeader->nTimeStamp;
 
         if (inHeader->nFlags & OMX_BUFFERFLAG_EOS) {
diff --git a/media/libstagefright/matroska/MatroskaExtractor.cpp b/media/libstagefright/matroska/MatroskaExtractor.cpp
index 861bdc5..434be86 100644
--- a/media/libstagefright/matroska/MatroskaExtractor.cpp
+++ b/media/libstagefright/matroska/MatroskaExtractor.cpp
@@ -1113,6 +1113,13 @@
                     meta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_VP8);
                 } else if (!strcmp("V_VP9", codecID)) {
                     meta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_VIDEO_VP9);
+                    if (codecPrivateSize > 0) {
+                      // 'csd-0' for VP9 is the Blob of Codec Private data as
+                      // specified in http://www.webmproject.org/vp9/profiles/.
+                      meta->setData(
+                              kKeyVp9CodecPrivate, 0, codecPrivate,
+                              codecPrivateSize);
+                    }
                 } else {
                     ALOGW("%s is not supported.", codecID);
                     continue;