Use heif embedded thumbnail if available
Add plumbing to retieve the embedded thumbnail from
MPEG4Extractor/ItemTable.
bug: 74395267
Test: CTS MediaMetadataRetriever test; manual test of thumbnail
extraction by browsing new folders containing heif files in
Downloads app.
Change-Id: Ic49f6dfa47eddc229b9f4b0e1835d58df1dce9f8
diff --git a/media/extractors/mp4/ItemTable.cpp b/media/extractors/mp4/ItemTable.cpp
index 26b8251..a1f6e9a 100644
--- a/media/extractors/mp4/ItemTable.cpp
+++ b/media/extractors/mp4/ItemTable.cpp
@@ -1591,10 +1591,9 @@
ssize_t thumbItemIndex = mItemIdToItemMap.indexOfKey(masterImage.thumbnails[0]);
if (thumbItemIndex < 0) {
- ALOGW("%s: Thumbnail item id %d not found, use master instead",
- __FUNCTION__, masterImage.thumbnails[0]);
- *itemIndex = masterItemIndex;
- return OK;
+ // Do not return the master image in this case, fail it so that the
+ // thumbnail extraction code knows we really don't have it.
+ return INVALID_OPERATION;
}
*itemIndex = thumbItemIndex;
diff --git a/media/libmedia/IMediaMetadataRetriever.cpp b/media/libmedia/IMediaMetadataRetriever.cpp
index f725c97..214117b 100644
--- a/media/libmedia/IMediaMetadataRetriever.cpp
+++ b/media/libmedia/IMediaMetadataRetriever.cpp
@@ -166,15 +166,16 @@
return interface_cast<IMemory>(reply.readStrongBinder());
}
- sp<IMemory> getImageAtIndex(int index, int colorFormat, bool metaOnly)
+ sp<IMemory> getImageAtIndex(int index, int colorFormat, bool metaOnly, bool thumbnail)
{
- ALOGV("getImageAtIndex: index %d, colorFormat(%d) metaOnly(%d)",
- index, colorFormat, metaOnly);
+ ALOGV("getImageAtIndex: index %d, colorFormat(%d) metaOnly(%d) thumbnail(%d)",
+ index, colorFormat, metaOnly, thumbnail);
Parcel data, reply;
data.writeInterfaceToken(IMediaMetadataRetriever::getInterfaceDescriptor());
data.writeInt32(index);
data.writeInt32(colorFormat);
data.writeInt32(metaOnly);
+ data.writeInt32(thumbnail);
#ifndef DISABLE_GROUP_SCHEDULE_HACK
sendSchedPolicy(data);
#endif
@@ -356,12 +357,13 @@
int index = data.readInt32();
int colorFormat = data.readInt32();
bool metaOnly = (data.readInt32() != 0);
- ALOGV("getImageAtIndex: index(%d), colorFormat(%d), metaOnly(%d)",
- index, colorFormat, metaOnly);
+ bool thumbnail = (data.readInt32() != 0);
+ ALOGV("getImageAtIndex: index(%d), colorFormat(%d), metaOnly(%d), thumbnail(%d)",
+ index, colorFormat, metaOnly, thumbnail);
#ifndef DISABLE_GROUP_SCHEDULE_HACK
setSchedPolicy(data);
#endif
- sp<IMemory> bitmap = getImageAtIndex(index, colorFormat, metaOnly);
+ sp<IMemory> bitmap = getImageAtIndex(index, colorFormat, metaOnly, thumbnail);
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 5491535..1a04552 100644
--- a/media/libmedia/include/media/IMediaMetadataRetriever.h
+++ b/media/libmedia/include/media/IMediaMetadataRetriever.h
@@ -45,7 +45,7 @@
virtual sp<IMemory> getFrameAtTime(
int64_t timeUs, int option, int colorFormat, bool metaOnly) = 0;
virtual sp<IMemory> getImageAtIndex(
- int index, int colorFormat, bool metaOnly) = 0;
+ int index, int colorFormat, bool metaOnly, bool thumbnail) = 0;
virtual status_t getFrameAtIndex(
std::vector<sp<IMemory> > *frames,
int frameIndex, int numFrames, int colorFormat, bool metaOnly) = 0;
diff --git a/media/libmedia/include/media/MediaMetadataRetrieverInterface.h b/media/libmedia/include/media/MediaMetadataRetrieverInterface.h
index 116b548..c45a964 100644
--- a/media/libmedia/include/media/MediaMetadataRetrieverInterface.h
+++ b/media/libmedia/include/media/MediaMetadataRetrieverInterface.h
@@ -46,7 +46,7 @@
virtual VideoFrame* getFrameAtTime(
int64_t timeUs, int option, int colorFormat, bool metaOnly) = 0;
virtual VideoFrame* getImageAtIndex(
- int index, int colorFormat, bool metaOnly) = 0;
+ int index, int colorFormat, bool metaOnly, bool thumbnail) = 0;
virtual status_t getFrameAtIndex(
std::vector<VideoFrame*>* frames,
int frameIndex, int numFrames, int colorFormat, bool metaOnly) = 0;
@@ -65,7 +65,7 @@
int64_t /*timeUs*/, int /*option*/, int /*colorFormat*/, bool /*metaOnly*/)
{ return NULL; }
virtual VideoFrame* getImageAtIndex(
- int /*index*/, int /*colorFormat*/, bool /*metaOnly*/)
+ int /*index*/, int /*colorFormat*/, bool /*metaOnly*/, bool /*thumbnail*/)
{ return NULL; }
virtual status_t getFrameAtIndex(
std::vector<VideoFrame*>* /*frames*/,
diff --git a/media/libmedia/include/media/mediametadataretriever.h b/media/libmedia/include/media/mediametadataretriever.h
index 3511253..bd23161 100644
--- a/media/libmedia/include/media/mediametadataretriever.h
+++ b/media/libmedia/include/media/mediametadataretriever.h
@@ -88,7 +88,7 @@
sp<IMemory> getFrameAtTime(int64_t timeUs, int option,
int colorFormat = HAL_PIXEL_FORMAT_RGB_565, bool metaOnly = false);
sp<IMemory> getImageAtIndex(int index,
- int colorFormat = HAL_PIXEL_FORMAT_RGB_565, bool metaOnly = false);
+ int colorFormat = HAL_PIXEL_FORMAT_RGB_565, bool metaOnly = false, bool thumbnail = false);
status_t getFrameAtIndex(
std::vector<sp<IMemory> > *frames, int frameIndex, int numFrames = 1,
int colorFormat = HAL_PIXEL_FORMAT_RGB_565, bool metaOnly = false);
diff --git a/media/libmedia/mediametadataretriever.cpp b/media/libmedia/mediametadataretriever.cpp
index 6a4204b..c10a907 100644
--- a/media/libmedia/mediametadataretriever.cpp
+++ b/media/libmedia/mediametadataretriever.cpp
@@ -155,15 +155,15 @@
}
sp<IMemory> MediaMetadataRetriever::getImageAtIndex(
- int index, int colorFormat, bool metaOnly) {
- ALOGV("getImageAtIndex: index(%d) colorFormat(%d) metaOnly(%d)",
- index, colorFormat, metaOnly);
+ int index, int colorFormat, bool metaOnly, bool thumbnail) {
+ ALOGV("getImageAtIndex: index(%d) colorFormat(%d) metaOnly(%d) thumbnail(%d)",
+ index, colorFormat, metaOnly, thumbnail);
Mutex::Autolock _l(mLock);
if (mRetriever == 0) {
ALOGE("retriever is not initialized");
return NULL;
}
- return mRetriever->getImageAtIndex(index, colorFormat, metaOnly);
+ return mRetriever->getImageAtIndex(index, colorFormat, metaOnly, thumbnail);
}
status_t MediaMetadataRetriever::getFrameAtIndex(
diff --git a/media/libmediaplayerservice/MetadataRetrieverClient.cpp b/media/libmediaplayerservice/MetadataRetrieverClient.cpp
index 16ed530..3b3ac29 100644
--- a/media/libmediaplayerservice/MetadataRetrieverClient.cpp
+++ b/media/libmediaplayerservice/MetadataRetrieverClient.cpp
@@ -234,9 +234,9 @@
}
sp<IMemory> MetadataRetrieverClient::getImageAtIndex(
- int index, int colorFormat, bool metaOnly) {
- ALOGV("getFrameAtTime: index(%d) colorFormat(%d), metaOnly(%d)",
- index, colorFormat, metaOnly);
+ int index, int colorFormat, bool metaOnly, bool thumbnail) {
+ ALOGV("getFrameAtTime: index(%d) colorFormat(%d), metaOnly(%d) thumbnail(%d)",
+ index, colorFormat, metaOnly, thumbnail);
Mutex::Autolock lock(mLock);
Mutex::Autolock glock(sLock);
mThumbnail.clear();
@@ -244,7 +244,7 @@
ALOGE("retriever is not initialized");
return NULL;
}
- VideoFrame *frame = mRetriever->getImageAtIndex(index, colorFormat, metaOnly);
+ VideoFrame *frame = mRetriever->getImageAtIndex(index, colorFormat, metaOnly, thumbnail);
if (frame == NULL) {
ALOGE("failed to extract image");
return NULL;
diff --git a/media/libmediaplayerservice/MetadataRetrieverClient.h b/media/libmediaplayerservice/MetadataRetrieverClient.h
index f71891a..e774c8f 100644
--- a/media/libmediaplayerservice/MetadataRetrieverClient.h
+++ b/media/libmediaplayerservice/MetadataRetrieverClient.h
@@ -53,7 +53,7 @@
virtual sp<IMemory> getFrameAtTime(
int64_t timeUs, int option, int colorFormat, bool metaOnly);
virtual sp<IMemory> getImageAtIndex(
- int index, int colorFormat, bool metaOnly);
+ int index, int colorFormat, bool metaOnly, bool thumbnail);
virtual status_t getFrameAtIndex(
std::vector<sp<IMemory> > *frames,
int frameIndex, int numFrames, int colorFormat, bool metaOnly);
diff --git a/media/libstagefright/FrameDecoder.cpp b/media/libstagefright/FrameDecoder.cpp
index 3d0aad1..a00d13a 100644
--- a/media/libstagefright/FrameDecoder.cpp
+++ b/media/libstagefright/FrameDecoder.cpp
@@ -42,30 +42,30 @@
static const int64_t kBufferTimeOutUs = 30000ll; // 30 msec
static const size_t kRetryCount = 20; // must be >0
-VideoFrame *FrameDecoder::allocVideoFrame(
- int32_t width, int32_t height, bool metaOnly) {
+//static
+VideoFrame *allocVideoFrame(const sp<MetaData> &trackMeta,
+ int32_t width, int32_t height, int32_t dstBpp, bool metaOnly = false) {
int32_t rotationAngle;
- if (!mTrackMeta->findInt32(kKeyRotation, &rotationAngle)) {
+ if (!trackMeta->findInt32(kKeyRotation, &rotationAngle)) {
rotationAngle = 0; // By default, no rotation
}
-
uint32_t type;
const void *iccData;
size_t iccSize;
- if (!mTrackMeta->findData(kKeyIccProfile, &type, &iccData, &iccSize)){
+ if (!trackMeta->findData(kKeyIccProfile, &type, &iccData, &iccSize)){
iccData = NULL;
iccSize = 0;
}
int32_t sarWidth, sarHeight;
int32_t displayWidth, displayHeight;
- if (mTrackMeta->findInt32(kKeySARWidth, &sarWidth)
- && mTrackMeta->findInt32(kKeySARHeight, &sarHeight)
+ if (trackMeta->findInt32(kKeySARWidth, &sarWidth)
+ && trackMeta->findInt32(kKeySARHeight, &sarHeight)
&& sarHeight != 0) {
displayWidth = (width * sarWidth) / sarHeight;
displayHeight = height;
- } else if (mTrackMeta->findInt32(kKeyDisplayWidth, &displayWidth)
- && mTrackMeta->findInt32(kKeyDisplayHeight, &displayHeight)
+ } else if (trackMeta->findInt32(kKeyDisplayWidth, &displayWidth)
+ && trackMeta->findInt32(kKeyDisplayHeight, &displayHeight)
&& displayWidth > 0 && displayHeight > 0
&& width > 0 && height > 0) {
ALOGV("found display size %dx%d", displayWidth, displayHeight);
@@ -75,27 +75,66 @@
}
return new VideoFrame(width, height, displayWidth, displayHeight,
- rotationAngle, mDstBpp, !metaOnly, iccData, iccSize);
+ rotationAngle, dstBpp, !metaOnly, iccData, iccSize);
}
-bool FrameDecoder::setDstColorFormat(android_pixel_format_t colorFormat) {
+//static
+bool findThumbnailInfo(
+ const sp<MetaData> &trackMeta, int32_t *width, int32_t *height,
+ uint32_t *type = NULL, const void **data = NULL, size_t *size = NULL) {
+ uint32_t dummyType;
+ const void *dummyData;
+ size_t dummySize;
+ return trackMeta->findInt32(kKeyThumbnailWidth, width)
+ && trackMeta->findInt32(kKeyThumbnailHeight, height)
+ && trackMeta->findData(kKeyThumbnailHVCC,
+ type ?: &dummyType, data ?: &dummyData, size ?: &dummySize);
+}
+
+//static
+VideoFrame* FrameDecoder::getMetadataOnly(
+ const sp<MetaData> &trackMeta, int colorFormat, bool thumbnail) {
+ OMX_COLOR_FORMATTYPE dstFormat;
+ int32_t dstBpp;
+ if (!getDstColorFormat(
+ (android_pixel_format_t)colorFormat, &dstFormat, &dstBpp)) {
+ return NULL;
+ }
+
+ int32_t width, height;
+ if (thumbnail) {
+ if (!findThumbnailInfo(trackMeta, &width, &height)) {
+ return NULL;
+ }
+ } else {
+ CHECK(trackMeta->findInt32(kKeyWidth, &width));
+ CHECK(trackMeta->findInt32(kKeyHeight, &height));
+ }
+ return allocVideoFrame(trackMeta, width, height, dstBpp, true /*metaOnly*/);
+}
+
+//static
+bool FrameDecoder::getDstColorFormat(
+ android_pixel_format_t colorFormat,
+ OMX_COLOR_FORMATTYPE *dstFormat,
+ int32_t *dstBpp) {
switch (colorFormat) {
case HAL_PIXEL_FORMAT_RGB_565:
{
- mDstFormat = OMX_COLOR_Format16bitRGB565;
- mDstBpp = 2;
+ *dstFormat = OMX_COLOR_Format16bitRGB565;
+ *dstBpp = 2;
return true;
}
case HAL_PIXEL_FORMAT_RGBA_8888:
{
- mDstFormat = OMX_COLOR_Format32BitRGBA8888;
- mDstBpp = 4;
+ *dstFormat = OMX_COLOR_Format32BitRGBA8888;
+ *dstBpp = 4;
return true;
}
case HAL_PIXEL_FORMAT_BGRA_8888:
{
- mDstFormat = OMX_COLOR_Format32bitBGRA8888;
- mDstBpp = 4;
+ *dstFormat = OMX_COLOR_Format32bitBGRA8888;
+ *dstBpp = 4;
return true;
}
default:
@@ -108,18 +147,12 @@
}
VideoFrame* FrameDecoder::extractFrame(
- int64_t frameTimeUs, int option, int colorFormat, bool metaOnly) {
- if (!setDstColorFormat((android_pixel_format_t)colorFormat)) {
+ int64_t frameTimeUs, int option, int colorFormat) {
+ if (!getDstColorFormat(
+ (android_pixel_format_t)colorFormat, &mDstFormat, &mDstBpp)) {
return NULL;
}
- if (metaOnly) {
- int32_t width, height;
- CHECK(trackMeta()->findInt32(kKeyWidth, &width));
- CHECK(trackMeta()->findInt32(kKeyHeight, &height));
- return allocVideoFrame(width, height, true);
- }
-
status_t err = extractInternal(frameTimeUs, 1, option);
if (err != OK) {
return NULL;
@@ -131,7 +164,8 @@
status_t FrameDecoder::extractFrames(
int64_t frameTimeUs, size_t numFrames, int option, int colorFormat,
std::vector<VideoFrame*>* frames) {
- if (!setDstColorFormat((android_pixel_format_t)colorFormat)) {
+ if (!getDstColorFormat(
+ (android_pixel_format_t)colorFormat, &mDstFormat, &mDstBpp)) {
return ERROR_UNSUPPORTED;
}
@@ -435,9 +469,10 @@
}
VideoFrame *frame = allocVideoFrame(
+ trackMeta(),
(crop_right - crop_left + 1),
(crop_bottom - crop_top + 1),
- false /*metaOnly*/);
+ dstBpp());
addFrame(frame);
int32_t srcFormat;
@@ -466,28 +501,28 @@
int64_t frameTimeUs, size_t /*numFrames*/,
int /*seekMode*/, MediaSource::ReadOptions *options) {
sp<MetaData> overrideMeta;
+ mThumbnail = false;
if (frameTimeUs < 0) {
uint32_t type;
const void *data;
size_t size;
- int64_t thumbNailTime = 0;
- int32_t thumbnailWidth, thumbnailHeight;
+ int32_t thumbWidth, thumbHeight;
// if we have a stand-alone thumbnail, set up the override meta,
// and set seekTo time to -1.
- if (trackMeta()->findInt32(kKeyThumbnailWidth, &thumbnailWidth)
- && trackMeta()->findInt32(kKeyThumbnailHeight, &thumbnailHeight)
- && trackMeta()->findData(kKeyThumbnailHVCC, &type, &data, &size)){
- overrideMeta = new MetaData(*(trackMeta()));
- overrideMeta->remove(kKeyDisplayWidth);
- overrideMeta->remove(kKeyDisplayHeight);
- overrideMeta->setInt32(kKeyWidth, thumbnailWidth);
- overrideMeta->setInt32(kKeyHeight, thumbnailHeight);
- overrideMeta->setData(kKeyHVCC, type, data, size);
- thumbNailTime = -1ll;
- ALOGV("thumbnail: %dx%d", thumbnailWidth, thumbnailHeight);
+ if (!findThumbnailInfo(trackMeta(),
+ &thumbWidth, &thumbHeight, &type, &data, &size)) {
+ ALOGE("Thumbnail not available");
+ return NULL;
}
- options->setSeekTo(thumbNailTime);
+ overrideMeta = new MetaData(*(trackMeta()));
+ overrideMeta->remove(kKeyDisplayWidth);
+ overrideMeta->remove(kKeyDisplayHeight);
+ overrideMeta->setInt32(kKeyWidth, thumbWidth);
+ overrideMeta->setInt32(kKeyHeight, thumbHeight);
+ overrideMeta->setData(kKeyHVCC, type, data, size);
+ options->setSeekTo(-1);
+ mThumbnail = true;
} else {
options->setSeekTo(frameTimeUs);
}
@@ -552,11 +587,16 @@
CHECK(outputFormat->findInt32("height", &height));
int32_t imageWidth, imageHeight;
- CHECK(trackMeta()->findInt32(kKeyWidth, &imageWidth));
- CHECK(trackMeta()->findInt32(kKeyHeight, &imageHeight));
+ if (mThumbnail) {
+ CHECK(trackMeta()->findInt32(kKeyThumbnailWidth, &imageWidth));
+ CHECK(trackMeta()->findInt32(kKeyThumbnailHeight, &imageHeight));
+ } else {
+ CHECK(trackMeta()->findInt32(kKeyWidth, &imageWidth));
+ CHECK(trackMeta()->findInt32(kKeyHeight, &imageHeight));
+ }
if (mFrame == NULL) {
- mFrame = allocVideoFrame(imageWidth, imageHeight, false /*metaOnly*/);
+ mFrame = allocVideoFrame(trackMeta(), imageWidth, imageHeight, dstBpp());
addFrame(mFrame);
}
diff --git a/media/libstagefright/StagefrightMetadataRetriever.cpp b/media/libstagefright/StagefrightMetadataRetriever.cpp
index 179e0e6..e086bea 100644
--- a/media/libstagefright/StagefrightMetadataRetriever.cpp
+++ b/media/libstagefright/StagefrightMetadataRetriever.cpp
@@ -125,10 +125,10 @@
}
VideoFrame* StagefrightMetadataRetriever::getImageAtIndex(
- int index, int colorFormat, bool metaOnly) {
+ int index, int colorFormat, bool metaOnly, bool thumbnail) {
- ALOGV("getImageAtIndex: index: %d colorFormat: %d, metaOnly: %d",
- index, colorFormat, metaOnly);
+ ALOGV("getImageAtIndex: index(%d) colorFormat(%d) metaOnly(%d) thumbnail(%d)",
+ index, colorFormat, metaOnly, thumbnail);
if (mExtractor.get() == NULL) {
ALOGE("no extractor.");
@@ -163,6 +163,10 @@
sp<MetaData> trackMeta = mExtractor->getTrackMetaData(i);
+ if (metaOnly) {
+ return FrameDecoder::getMetadataOnly(trackMeta, colorFormat, thumbnail);
+ }
+
sp<IMediaSource> source = mExtractor->getTrack(i);
if (source.get() == NULL) {
@@ -190,7 +194,7 @@
const AString &componentName = matchingCodecs[i];
ImageDecoder decoder(componentName, trackMeta, source);
VideoFrame* frame = decoder.extractFrame(
- 0 /*frameTimeUs*/, 0 /*seekMode*/, colorFormat, metaOnly);
+ thumbnail ? -1 : 0 /*frameTimeUs*/, 0 /*seekMode*/, colorFormat);
if (frame != NULL) {
return frame;
@@ -265,6 +269,16 @@
sp<MetaData> trackMeta = mExtractor->getTrackMetaData(
i, MediaExtractor::kIncludeExtensiveMetaData);
+ if (metaOnly) {
+ if (outFrame != NULL) {
+ *outFrame = FrameDecoder::getMetadataOnly(trackMeta, colorFormat);
+ if (*outFrame != NULL) {
+ return OK;
+ }
+ }
+ return UNKNOWN_ERROR;
+ }
+
sp<IMediaSource> source = mExtractor->getTrack(i);
if (source.get() == NULL) {
@@ -294,8 +308,7 @@
const AString &componentName = matchingCodecs[i];
VideoFrameDecoder decoder(componentName, trackMeta, source);
if (outFrame != NULL) {
- *outFrame = decoder.extractFrame(
- timeUs, option, colorFormat, metaOnly);
+ *outFrame = decoder.extractFrame(timeUs, option, colorFormat);
if (*outFrame != NULL) {
return OK;
}
diff --git a/media/libstagefright/include/FrameDecoder.h b/media/libstagefright/include/FrameDecoder.h
index dfbe2cd..b67e928 100644
--- a/media/libstagefright/include/FrameDecoder.h
+++ b/media/libstagefright/include/FrameDecoder.h
@@ -44,11 +44,7 @@
mDstFormat(OMX_COLOR_Format16bitRGB565),
mDstBpp(2) {}
- VideoFrame* extractFrame(
- int64_t frameTimeUs,
- int option,
- int colorFormat,
- bool metaOnly);
+ VideoFrame* extractFrame(int64_t frameTimeUs, int option, int colorFormat);
status_t extractFrames(
int64_t frameTimeUs,
@@ -57,6 +53,9 @@
int colorFormat,
std::vector<VideoFrame*>* frames);
+ static VideoFrame* getMetadataOnly(
+ const sp<MetaData> &trackMeta, int colorFormat, bool thumbnail = false);
+
protected:
virtual ~FrameDecoder() {}
@@ -78,8 +77,6 @@
int64_t timeUs,
bool *done) = 0;
- VideoFrame *allocVideoFrame(int32_t width, int32_t height, bool metaOnly);
-
sp<MetaData> trackMeta() const { return mTrackMeta; }
OMX_COLOR_FORMATTYPE dstFormat() const { return mDstFormat; }
int32_t dstBpp() const { return mDstBpp; }
@@ -96,7 +93,11 @@
int32_t mDstBpp;
std::vector<std::unique_ptr<VideoFrame> > mFrames;
- bool setDstColorFormat(android_pixel_format_t colorFormat);
+ static bool getDstColorFormat(
+ android_pixel_format_t colorFormat,
+ OMX_COLOR_FORMATTYPE *dstFormat,
+ int32_t *dstBpp);
+
status_t extractInternal(int64_t frameTimeUs, size_t numFrames, int option);
DISALLOW_EVIL_CONSTRUCTORS(FrameDecoder);
@@ -147,7 +148,8 @@
const sp<MetaData> &trackMeta,
const sp<IMediaSource> &source) :
FrameDecoder(componentName, trackMeta, source),
- mFrame(NULL), mGridRows(1), mGridCols(1), mTilesDecoded(0) {}
+ mFrame(NULL), mGridRows(1), mGridCols(1),
+ mTilesDecoded(0), mThumbnail(false) {}
protected:
virtual sp<AMessage> onGetFormatAndSeekOptions(
@@ -173,6 +175,7 @@
int32_t mGridRows;
int32_t mGridCols;
int32_t mTilesDecoded;
+ bool mThumbnail;
};
} // namespace android
diff --git a/media/libstagefright/include/StagefrightMetadataRetriever.h b/media/libstagefright/include/StagefrightMetadataRetriever.h
index 58442fe..8443fbe 100644
--- a/media/libstagefright/include/StagefrightMetadataRetriever.h
+++ b/media/libstagefright/include/StagefrightMetadataRetriever.h
@@ -43,7 +43,7 @@
virtual VideoFrame* getFrameAtTime(
int64_t timeUs, int option, int colorFormat, bool metaOnly);
virtual VideoFrame* getImageAtIndex(
- int index, int colorFormat, bool metaOnly);
+ int index, int colorFormat, bool metaOnly, bool thumbnail);
virtual status_t getFrameAtIndex(
std::vector<VideoFrame*>* frames,
int frameIndex, int numFrames, int colorFormat, bool metaOnly);