stagefright: MetadataRetriever API to specify mime and color format
- Allow setDataSource() to specify mime. In case of HEIF decoding
request from skia, we don't want to sniff any other format other
than mp4.
- Allow getFrameAtTime() to specify dst color format.
bug: 64077740
Test: cts-tradefed run cts-dev --module CtsMediaTestCases --compatibility:module-arg CtsMediaTestCases:include-annotation:android.platform.test.annotations.RequiresDevice
Change-Id: I471f41c28a2252417c4b3331dcfd4bd00a24408a
diff --git a/cmds/stagefright/stagefright.cpp b/cmds/stagefright/stagefright.cpp
index d7c2e87..d70282b 100644
--- a/cmds/stagefright/stagefright.cpp
+++ b/cmds/stagefright/stagefright.cpp
@@ -870,7 +870,9 @@
sp<IMemory> mem =
retriever->getFrameAtTime(-1,
- MediaSource::ReadOptions::SEEK_PREVIOUS_SYNC);
+ MediaSource::ReadOptions::SEEK_PREVIOUS_SYNC,
+ HAL_PIXEL_FORMAT_RGB_565,
+ false /*metaOnly*/);
if (mem != NULL) {
failed = false;
diff --git a/media/libmedia/IMediaMetadataRetriever.cpp b/media/libmedia/IMediaMetadataRetriever.cpp
index 7058ee8..5ea2e8b 100644
--- a/media/libmedia/IMediaMetadataRetriever.cpp
+++ b/media/libmedia/IMediaMetadataRetriever.cpp
@@ -127,22 +127,32 @@
return reply.readInt32();
}
- status_t setDataSource(const sp<IDataSource>& source)
+ status_t setDataSource(const sp<IDataSource>& source, const char *mime)
{
Parcel data, reply;
data.writeInterfaceToken(IMediaMetadataRetriever::getInterfaceDescriptor());
data.writeStrongBinder(IInterface::asBinder(source));
+
+ if (mime != NULL) {
+ data.writeInt32(1);
+ data.writeCString(mime);
+ } else {
+ data.writeInt32(0);
+ }
remote()->transact(SET_DATA_SOURCE_CALLBACK, data, &reply);
return reply.readInt32();
}
- sp<IMemory> getFrameAtTime(int64_t timeUs, int option)
+ sp<IMemory> getFrameAtTime(int64_t timeUs, int option, int colorFormat, bool metaOnly)
{
- ALOGV("getTimeAtTime: time(%" PRId64 " us) and option(%d)", timeUs, option);
+ ALOGV("getTimeAtTime: time(%" PRId64 " us), option(%d), colorFormat(%d) metaOnly(%d)",
+ timeUs, option, colorFormat, metaOnly);
Parcel data, reply;
data.writeInterfaceToken(IMediaMetadataRetriever::getInterfaceDescriptor());
data.writeInt64(timeUs);
data.writeInt32(option);
+ data.writeInt32(colorFormat);
+ data.writeInt32(metaOnly);
#ifndef DISABLE_GROUP_SCHEDULE_HACK
sendSchedPolicy(data);
#endif
@@ -258,7 +268,12 @@
if (source == NULL) {
reply->writeInt32(BAD_VALUE);
} else {
- reply->writeInt32(setDataSource(source));
+ int32_t hasMime = data.readInt32();
+ const char *mime = NULL;
+ if (hasMime) {
+ mime = data.readCString();
+ }
+ reply->writeInt32(setDataSource(source, mime));
}
return NO_ERROR;
} break;
@@ -266,11 +281,14 @@
CHECK_INTERFACE(IMediaMetadataRetriever, data, reply);
int64_t timeUs = data.readInt64();
int option = data.readInt32();
- ALOGV("getTimeAtTime: time(%" PRId64 " us) and option(%d)", timeUs, option);
+ int colorFormat = data.readInt32();
+ bool metaOnly = (data.readInt32() != 0);
+ ALOGV("getTimeAtTime: time(%" PRId64 " us), option(%d), colorFormat(%d), metaOnly(%d)",
+ timeUs, option, colorFormat, metaOnly);
#ifndef DISABLE_GROUP_SCHEDULE_HACK
setSchedPolicy(data);
#endif
- sp<IMemory> bitmap = getFrameAtTime(timeUs, option);
+ sp<IMemory> bitmap = getFrameAtTime(timeUs, option, colorFormat, metaOnly);
if (bitmap != 0) { // Don't send NULL across the binder interface
reply->writeInt32(NO_ERROR);
reply->writeStrongBinder(IInterface::asBinder(bitmap));
diff --git a/media/libmedia/include/media/IMediaMetadataRetriever.h b/media/libmedia/include/media/IMediaMetadataRetriever.h
index c90f254..ea95161 100644
--- a/media/libmedia/include/media/IMediaMetadataRetriever.h
+++ b/media/libmedia/include/media/IMediaMetadataRetriever.h
@@ -19,13 +19,12 @@
#define ANDROID_IMEDIAMETADATARETRIEVER_H
#include <binder/IInterface.h>
-#include <binder/Parcel.h>
#include <binder/IMemory.h>
#include <utils/KeyedVector.h>
#include <utils/RefBase.h>
namespace android {
-
+class Parcel;
class IDataSource;
struct IMediaHTTPService;
@@ -41,8 +40,10 @@
const KeyedVector<String8, String8> *headers = NULL) = 0;
virtual status_t setDataSource(int fd, int64_t offset, int64_t length) = 0;
- virtual status_t setDataSource(const sp<IDataSource>& dataSource) = 0;
- virtual sp<IMemory> getFrameAtTime(int64_t timeUs, int option) = 0;
+ virtual status_t setDataSource(
+ const sp<IDataSource>& dataSource, const char *mime) = 0;
+ virtual sp<IMemory> getFrameAtTime(
+ int64_t timeUs, int option, int colorFormat, bool metaOnly) = 0;
virtual sp<IMemory> extractAlbumArt() = 0;
virtual const char* extractMetadata(int keyCode) = 0;
};
diff --git a/media/libmedia/include/media/MediaMetadataRetrieverInterface.h b/media/libmedia/include/media/MediaMetadataRetrieverInterface.h
index a5e1350..257002d 100644
--- a/media/libmedia/include/media/MediaMetadataRetrieverInterface.h
+++ b/media/libmedia/include/media/MediaMetadataRetrieverInterface.h
@@ -41,8 +41,9 @@
const KeyedVector<String8, String8> *headers = NULL) = 0;
virtual status_t setDataSource(int fd, int64_t offset, int64_t length) = 0;
- virtual status_t setDataSource(const sp<DataSource>& source) = 0;
- virtual VideoFrame* getFrameAtTime(int64_t timeUs, int option) = 0;
+ virtual status_t setDataSource(const sp<DataSource>& source, const char *mime) = 0;
+ virtual VideoFrame* getFrameAtTime(
+ int64_t timeUs, int option, int colorFormat, bool metaOnly) = 0;
virtual MediaAlbumArt* extractAlbumArt() = 0;
virtual const char* extractMetadata(int keyCode) = 0;
};
@@ -54,7 +55,9 @@
MediaMetadataRetrieverInterface() {}
virtual ~MediaMetadataRetrieverInterface() {}
- virtual VideoFrame* getFrameAtTime(int64_t /*timeUs*/, int /*option*/) { return NULL; }
+ virtual VideoFrame* getFrameAtTime(
+ int64_t /*timeUs*/, int /*option*/, int /*colorFormat*/, bool /*metaOnly*/)
+ { return NULL; }
virtual MediaAlbumArt* extractAlbumArt() { return NULL; }
virtual const char* extractMetadata(int /*keyCode*/) { return NULL; }
};
diff --git a/media/libmedia/include/media/mediametadataretriever.h b/media/libmedia/include/media/mediametadataretriever.h
index 8ed07ee..aa2c868 100644
--- a/media/libmedia/include/media/mediametadataretriever.h
+++ b/media/libmedia/include/media/mediametadataretriever.h
@@ -76,8 +76,10 @@
const KeyedVector<String8, String8> *headers = NULL);
status_t setDataSource(int fd, int64_t offset, int64_t length);
- status_t setDataSource(const sp<IDataSource>& dataSource);
- sp<IMemory> getFrameAtTime(int64_t timeUs, int option);
+ status_t setDataSource(
+ const sp<IDataSource>& dataSource, const char *mime = NULL);
+ sp<IMemory> getFrameAtTime(int64_t timeUs, int option,
+ int colorFormat = 0, bool metaOnly = false);
sp<IMemory> extractAlbumArt();
const char* extractMetadata(int keyCode);
diff --git a/media/libmedia/mediametadataretriever.cpp b/media/libmedia/mediametadataretriever.cpp
index 08a9e6a..7d27d57 100644
--- a/media/libmedia/mediametadataretriever.cpp
+++ b/media/libmedia/mediametadataretriever.cpp
@@ -130,7 +130,7 @@
}
status_t MediaMetadataRetriever::setDataSource(
- const sp<IDataSource>& dataSource)
+ const sp<IDataSource>& dataSource, const char *mime)
{
ALOGV("setDataSource(IDataSource)");
Mutex::Autolock _l(mLock);
@@ -138,18 +138,20 @@
ALOGE("retriever is not initialized");
return INVALID_OPERATION;
}
- return mRetriever->setDataSource(dataSource);
+ return mRetriever->setDataSource(dataSource, mime);
}
-sp<IMemory> MediaMetadataRetriever::getFrameAtTime(int64_t timeUs, int option)
+sp<IMemory> MediaMetadataRetriever::getFrameAtTime(
+ int64_t timeUs, int option, int colorFormat, bool metaOnly)
{
- ALOGV("getFrameAtTime: time(%" PRId64 " us) option(%d)", timeUs, option);
+ ALOGV("getFrameAtTime: time(%" PRId64 " us) option(%d) colorFormat(%d) metaOnly(%d)",
+ timeUs, option, colorFormat, metaOnly);
Mutex::Autolock _l(mLock);
if (mRetriever == 0) {
ALOGE("retriever is not initialized");
return NULL;
}
- return mRetriever->getFrameAtTime(timeUs, option);
+ return mRetriever->getFrameAtTime(timeUs, option, colorFormat, metaOnly);
}
const char* MediaMetadataRetriever::extractMetadata(int keyCode)
diff --git a/media/libmediaplayerservice/MetadataRetrieverClient.cpp b/media/libmediaplayerservice/MetadataRetrieverClient.cpp
index 793f476..47c5aaf 100644
--- a/media/libmediaplayerservice/MetadataRetrieverClient.cpp
+++ b/media/libmediaplayerservice/MetadataRetrieverClient.cpp
@@ -175,7 +175,7 @@
}
status_t MetadataRetrieverClient::setDataSource(
- const sp<IDataSource>& source)
+ const sp<IDataSource>& source, const char *mime)
{
ALOGV("setDataSource(IDataSource)");
Mutex::Autolock lock(mLock);
@@ -186,16 +186,18 @@
ALOGV("player type = %d", playerType);
sp<MediaMetadataRetrieverBase> p = createRetriever(playerType);
if (p == NULL) return NO_INIT;
- status_t ret = p->setDataSource(dataSource);
+ status_t ret = p->setDataSource(dataSource, mime);
if (ret == NO_ERROR) mRetriever = p;
return ret;
}
Mutex MetadataRetrieverClient::sLock;
-sp<IMemory> MetadataRetrieverClient::getFrameAtTime(int64_t timeUs, int option)
+sp<IMemory> MetadataRetrieverClient::getFrameAtTime(
+ int64_t timeUs, int option, int colorFormat, bool metaOnly)
{
- ALOGV("getFrameAtTime: time(%lld us) option(%d)", (long long)timeUs, option);
+ ALOGV("getFrameAtTime: time(%lld us) option(%d) colorFormat(%d), metaOnly(%d)",
+ (long long)timeUs, option, colorFormat, metaOnly);
Mutex::Autolock lock(mLock);
Mutex::Autolock glock(sLock);
mThumbnail.clear();
@@ -203,7 +205,8 @@
ALOGE("retriever is not initialized");
return NULL;
}
- VideoFrame *frame = mRetriever->getFrameAtTime(timeUs, option);
+ VideoFrame *frame = mRetriever->getFrameAtTime(
+ timeUs, option, colorFormat, metaOnly);
if (frame == NULL) {
ALOGE("failed to capture a video frame");
return NULL;
diff --git a/media/libmediaplayerservice/MetadataRetrieverClient.h b/media/libmediaplayerservice/MetadataRetrieverClient.h
index fe7547c..c78cd4b 100644
--- a/media/libmediaplayerservice/MetadataRetrieverClient.h
+++ b/media/libmediaplayerservice/MetadataRetrieverClient.h
@@ -49,8 +49,9 @@
const KeyedVector<String8, String8> *headers);
virtual status_t setDataSource(int fd, int64_t offset, int64_t length);
- virtual status_t setDataSource(const sp<IDataSource>& source);
- virtual sp<IMemory> getFrameAtTime(int64_t timeUs, int option);
+ virtual status_t setDataSource(const sp<IDataSource>& source, const char *mime);
+ virtual sp<IMemory> getFrameAtTime(
+ int64_t timeUs, int option, int colorFormat, bool metaOnly);
virtual sp<IMemory> extractAlbumArt();
virtual const char* extractMetadata(int keyCode);
diff --git a/media/libstagefright/StagefrightMediaScanner.cpp b/media/libstagefright/StagefrightMediaScanner.cpp
index f0c27ac..4ff2bfe 100644
--- a/media/libstagefright/StagefrightMediaScanner.cpp
+++ b/media/libstagefright/StagefrightMediaScanner.cpp
@@ -85,7 +85,8 @@
status_t status;
if (fd < 0) {
// couldn't open it locally, maybe the media server can?
- status = mRetriever->setDataSource(NULL /* httpService */, path);
+ sp<IMediaHTTPService> nullService;
+ status = mRetriever->setDataSource(nullService, path);
} else {
status = mRetriever->setDataSource(fd, 0, 0x7ffffffffffffffL);
close(fd);
diff --git a/media/libstagefright/StagefrightMetadataRetriever.cpp b/media/libstagefright/StagefrightMetadataRetriever.cpp
index 57af772..0281563 100644
--- a/media/libstagefright/StagefrightMetadataRetriever.cpp
+++ b/media/libstagefright/StagefrightMetadataRetriever.cpp
@@ -121,12 +121,12 @@
}
status_t StagefrightMetadataRetriever::setDataSource(
- const sp<DataSource>& source) {
+ const sp<DataSource>& source, const char *mime) {
ALOGV("setDataSource(DataSource)");
clearMetadata();
mSource = source;
- mExtractor = MediaExtractor::Create(mSource);
+ mExtractor = MediaExtractor::Create(mSource, mime);
if (mExtractor == NULL) {
ALOGE("Failed to instantiate a MediaExtractor.");
@@ -142,7 +142,9 @@
const sp<MetaData> &trackMeta,
const sp<IMediaSource> &source,
int64_t frameTimeUs,
- int seekMode) {
+ int seekMode,
+ int /*colorFormat*/,
+ bool /*metaOnly*/) {
sp<MetaData> format = source->getFormat();
@@ -463,9 +465,10 @@
}
VideoFrame *StagefrightMetadataRetriever::getFrameAtTime(
- int64_t timeUs, int option) {
+ int64_t timeUs, int option, int colorFormat, bool metaOnly) {
- ALOGV("getFrameAtTime: %" PRId64 " us option: %d", timeUs, option);
+ ALOGV("getFrameAtTime: %" PRId64 " us option: %d colorFormat: %d, metaOnly: %d",
+ timeUs, option, colorFormat, metaOnly);
if (mExtractor.get() == NULL) {
ALOGV("no extractor.");
@@ -533,8 +536,8 @@
for (size_t i = 0; i < matchingCodecs.size(); ++i) {
const AString &componentName = matchingCodecs[i];
- VideoFrame *frame =
- extractVideoFrame(componentName, trackMeta, source, timeUs, option);
+ VideoFrame *frame = extractVideoFrame(
+ componentName, trackMeta, source, timeUs, option, colorFormat, metaOnly);
if (frame != NULL) {
return frame;
diff --git a/media/libstagefright/include/StagefrightMetadataRetriever.h b/media/libstagefright/include/StagefrightMetadataRetriever.h
index b7ac718..277eb3e 100644
--- a/media/libstagefright/include/StagefrightMetadataRetriever.h
+++ b/media/libstagefright/include/StagefrightMetadataRetriever.h
@@ -38,9 +38,9 @@
const KeyedVector<String8, String8> *headers);
virtual status_t setDataSource(int fd, int64_t offset, int64_t length);
- virtual status_t setDataSource(const sp<DataSource>& source);
+ virtual status_t setDataSource(const sp<DataSource>& source, const char *mime);
- virtual VideoFrame *getFrameAtTime(int64_t timeUs, int option);
+ virtual VideoFrame *getFrameAtTime(int64_t timeUs, int option, int colorFormat, bool metaOnly);
virtual MediaAlbumArt *extractAlbumArt();
virtual const char *extractMetadata(int keyCode);