Expose bitDepth to MediaMetadataRetriever
Bug: b/217378477
Test:
Change-Id: I16dabdf9aaabf341a9cebb1624e464155196a5a8
diff --git a/include/private/media/VideoFrame.h b/include/private/media/VideoFrame.h
index 16e794a..97e0b1d 100644
--- a/include/private/media/VideoFrame.h
+++ b/include/private/media/VideoFrame.h
@@ -38,13 +38,13 @@
VideoFrame(uint32_t width, uint32_t height,
uint32_t displayWidth, uint32_t displayHeight,
uint32_t tileWidth, uint32_t tileHeight,
- uint32_t angle, uint32_t bpp, bool hasData, size_t iccSize):
+ uint32_t angle, uint32_t bpp, uint32_t bitDepth, bool hasData, size_t iccSize):
mWidth(width), mHeight(height),
mDisplayWidth(displayWidth), mDisplayHeight(displayHeight),
mTileWidth(tileWidth), mTileHeight(tileHeight), mDurationUs(0),
mRotationAngle(angle), mBytesPerPixel(bpp), mRowBytes(bpp * width),
mSize(hasData ? (bpp * width * height) : 0),
- mIccSize(iccSize), mReserved(0) {
+ mIccSize(iccSize), mBitDepth(bitDepth) {
}
void init(const VideoFrame& copy, const void* iccData, size_t iccSize) {
@@ -84,7 +84,7 @@
uint32_t mRowBytes; // Number of bytes per row before rotation
uint32_t mSize; // Number of bytes of frame data
uint32_t mIccSize; // Number of bytes of ICC data
- uint32_t mReserved; // (padding to make mData 64-bit aligned)
+ uint32_t mBitDepth; // number of bits per R / G / B channel
};
}; // namespace android
diff --git a/media/libheif/HeifDecoderImpl.cpp b/media/libheif/HeifDecoderImpl.cpp
index 041b427..923f5c1 100644
--- a/media/libheif/HeifDecoderImpl.cpp
+++ b/media/libheif/HeifDecoderImpl.cpp
@@ -47,6 +47,7 @@
info->mRotationAngle = videoFrame->mRotationAngle;
info->mBytesPerPixel = videoFrame->mBytesPerPixel;
info->mDurationUs = videoFrame->mDurationUs;
+ info->mBitDepth = videoFrame->mBitDepth;
if (videoFrame->mIccSize > 0) {
info->mIccData.assign(
videoFrame->getFlattenedIccData(),
@@ -377,13 +378,14 @@
// issue (e.g. by copying).
VideoFrame* videoFrame = static_cast<VideoFrame*>(sharedMem->unsecurePointer());
- ALOGV("Image dimension %dx%d, display %dx%d, angle %d, iccSize %d",
+ ALOGV("Image dimension %dx%d, display %dx%d, angle %d, iccSize %d, bitDepth %d",
videoFrame->mWidth,
videoFrame->mHeight,
videoFrame->mDisplayWidth,
videoFrame->mDisplayHeight,
videoFrame->mRotationAngle,
- videoFrame->mIccSize);
+ videoFrame->mIccSize,
+ videoFrame->mBitDepth);
initFrameInfo(&mImageInfo, videoFrame);
@@ -729,4 +731,13 @@
return (mCurScanline > oldScanline) ? (mCurScanline - oldScanline) : 0;
}
+uint32_t HeifDecoderImpl::getColorDepth() {
+ HeifFrameInfo* info = &mImageInfo;
+ if (info != nullptr) {
+ return mImageInfo.mBitDepth;
+ } else {
+ return 0;
+ }
+}
+
} // namespace android
diff --git a/media/libheif/HeifDecoderImpl.h b/media/libheif/HeifDecoderImpl.h
index 2b9c710..86a8628 100644
--- a/media/libheif/HeifDecoderImpl.h
+++ b/media/libheif/HeifDecoderImpl.h
@@ -54,6 +54,8 @@
size_t skipScanlines(size_t count) override;
+ uint32_t getColorDepth() override;
+
private:
struct DecodeThread;
diff --git a/media/libheif/include/HeifDecoderAPI.h b/media/libheif/include/HeifDecoderAPI.h
index fa51aef..56f4765 100644
--- a/media/libheif/include/HeifDecoderAPI.h
+++ b/media/libheif/include/HeifDecoderAPI.h
@@ -46,7 +46,8 @@
uint32_t mHeight;
int32_t mRotationAngle; // Rotation angle, clockwise, should be multiple of 90
uint32_t mBytesPerPixel; // Number of bytes for one pixel
- int64_t mDurationUs; // Duration of the frame in us
+ int64_t mDurationUs; // Duration of the frame in us
+ uint32_t mBitDepth; // Number of bits of R/G/B channel
std::vector<uint8_t> mIccData; // ICC data array
};
@@ -162,6 +163,11 @@
*/
virtual size_t skipScanlines(size_t count) = 0;
+ /*
+ * Returns color depth of R/G/B channel.
+ */
+ virtual uint32_t getColorDepth() = 0;
+
private:
HeifDecoder(const HeifFrameInfo&) = delete;
HeifDecoder& operator=(const HeifFrameInfo&) = delete;
diff --git a/media/libmediaplayerservice/StagefrightMetadataRetriever.cpp b/media/libmediaplayerservice/StagefrightMetadataRetriever.cpp
index 609298f..55b1ed7 100644
--- a/media/libmediaplayerservice/StagefrightMetadataRetriever.cpp
+++ b/media/libmediaplayerservice/StagefrightMetadataRetriever.cpp
@@ -28,6 +28,7 @@
#include <datasource/PlayerServiceDataSourceFactory.h>
#include <datasource/PlayerServiceFileSource.h>
#include <media/IMediaHTTPService.h>
+#include <media/stagefright/MediaCodecConstants.h>
#include <media/stagefright/foundation/ADebug.h>
#include <media/stagefright/foundation/AMessage.h>
#include <media/stagefright/MediaCodecList.h>
@@ -194,17 +195,6 @@
return NULL;
}
- if (metaOnly) {
- return FrameDecoder::getMetadataOnly(trackMeta, colorFormat, thumbnail);
- }
-
- sp<IMediaSource> source = mExtractor->getTrack(i);
-
- if (source.get() == NULL) {
- ALOGE("unable to instantiate image track.");
- return NULL;
- }
-
const char *mime;
bool isHeif = false;
if (!trackMeta->findCString(kKeyMIMEType, &mime)) {
@@ -223,16 +213,47 @@
trackMeta->setCString(kKeyMIMEType, mime);
}
- bool preferhw = property_get_bool(
- "media.stagefright.thumbnail.prefer_hw_codecs", false);
- uint32_t flags = preferhw ? 0 : MediaCodecList::kPreferSoftwareCodecs;
- Vector<AString> matchingCodecs;
sp<AMessage> format = new AMessage;
status_t err = convertMetaDataToMessage(trackMeta, &format);
if (err != OK) {
format = NULL;
}
+ uint32_t bitDepth = 8;
+ if (!strcasecmp(mime, MEDIA_MIMETYPE_VIDEO_HEVC)) {
+ int32_t profile;
+ if (format->findInt32("profile", &profile)) {
+ if (HEVCProfileMain10 == profile || HEVCProfileMain10HDR10 == profile ||
+ HEVCProfileMain10HDR10Plus == profile) {
+ bitDepth = 10;
+ }
+ }
+ } else if (!strcasecmp(mime, MEDIA_MIMETYPE_VIDEO_AV1)) {
+ int32_t profile;
+ if (format->findInt32("profile", &profile)) {
+ if (AV1ProfileMain10 == profile || AV1ProfileMain10HDR10 == profile ||
+ AV1ProfileMain10HDR10Plus == profile) {
+ bitDepth = 10;
+ }
+ }
+ }
+
+ if (metaOnly) {
+ return FrameDecoder::getMetadataOnly(trackMeta, colorFormat, thumbnail, bitDepth);
+ }
+
+ sp<IMediaSource> source = mExtractor->getTrack(i);
+
+ if (source.get() == NULL) {
+ ALOGE("unable to instantiate image track.");
+ return NULL;
+ }
+
+ bool preferhw = property_get_bool(
+ "media.stagefright.thumbnail.prefer_hw_codecs", false);
+ uint32_t flags = preferhw ? 0 : MediaCodecList::kPreferSoftwareCodecs;
+ Vector<AString> matchingCodecs;
+
// If decoding thumbnail check decoder supports thumbnail dimensions instead
int32_t thumbHeight, thumbWidth;
if (thumbnail && format != NULL
diff --git a/media/libstagefright/FrameDecoder.cpp b/media/libstagefright/FrameDecoder.cpp
index 5da32c9..10a1ee4 100644
--- a/media/libstagefright/FrameDecoder.cpp
+++ b/media/libstagefright/FrameDecoder.cpp
@@ -50,7 +50,7 @@
sp<IMemory> allocVideoFrame(const sp<MetaData>& trackMeta,
int32_t width, int32_t height, int32_t tileWidth, int32_t tileHeight,
- int32_t dstBpp, bool allocRotated, bool metaOnly) {
+ int32_t dstBpp, uint32_t bitDepth, bool allocRotated, bool metaOnly) {
int32_t rotationAngle;
if (!trackMeta->findInt32(kKeyRotation, &rotationAngle)) {
rotationAngle = 0; // By default, no rotation
@@ -105,7 +105,7 @@
}
VideoFrame frame(width, height, displayWidth, displayHeight,
- tileWidth, tileHeight, rotationAngle, dstBpp, !metaOnly, iccSize);
+ tileWidth, tileHeight, rotationAngle, dstBpp, bitDepth, !metaOnly, iccSize);
size_t size = frame.getFlattenedSize();
sp<MemoryHeapBase> heap = new MemoryHeapBase(size, 0, "MetadataRetrieverClient");
@@ -126,15 +126,15 @@
sp<IMemory> allocVideoFrame(const sp<MetaData>& trackMeta,
int32_t width, int32_t height, int32_t tileWidth, int32_t tileHeight,
- int32_t dstBpp, bool allocRotated = false) {
- return allocVideoFrame(trackMeta, width, height, tileWidth, tileHeight, dstBpp,
+ int32_t dstBpp, uint8_t bitDepth, bool allocRotated = false) {
+ return allocVideoFrame(trackMeta, width, height, tileWidth, tileHeight, dstBpp, bitDepth,
allocRotated, false /*metaOnly*/);
}
sp<IMemory> allocMetaFrame(const sp<MetaData>& trackMeta,
int32_t width, int32_t height, int32_t tileWidth, int32_t tileHeight,
- int32_t dstBpp) {
- return allocVideoFrame(trackMeta, width, height, tileWidth, tileHeight, dstBpp,
+ int32_t dstBpp, uint8_t bitDepth) {
+ return allocVideoFrame(trackMeta, width, height, tileWidth, tileHeight, dstBpp, bitDepth,
false /*allocRotated*/, true /*metaOnly*/);
}
@@ -211,7 +211,7 @@
//static
sp<IMemory> FrameDecoder::getMetadataOnly(
- const sp<MetaData> &trackMeta, int colorFormat, bool thumbnail) {
+ const sp<MetaData> &trackMeta, int colorFormat, bool thumbnail, uint32_t bitDepth) {
OMX_COLOR_FORMATTYPE dstFormat;
ui::PixelFormat captureFormat;
int32_t dstBpp;
@@ -235,7 +235,8 @@
}
}
- sp<IMemory> metaMem = allocMetaFrame(trackMeta, width, height, tileWidth, tileHeight, dstBpp);
+ sp<IMemory> metaMem =
+ allocMetaFrame(trackMeta, width, height, tileWidth, tileHeight, dstBpp, bitDepth);
// try to fill sequence meta's duration based on average frame rate,
// default to 33ms if frame rate is unavailable.
@@ -534,7 +535,6 @@
if (dstFormat() == COLOR_Format32bitABGR2101010) {
videoFormat->setInt32("color-format", COLOR_FormatYUVP010);
} else {
- // TODO: Use Flexible color instead
videoFormat->setInt32("color-format", OMX_COLOR_FormatYUV420Planar);
}
@@ -649,6 +649,11 @@
height = slice_height;
}
+ uint32_t bitDepth = 8;
+ if (COLOR_FormatYUVP010 == srcFormat) {
+ bitDepth = 10;
+ }
+
if (mFrame == NULL) {
sp<IMemory> frameMem = allocVideoFrame(
trackMeta(),
@@ -657,6 +662,7 @@
0,
0,
dstBpp(),
+ bitDepth,
mCaptureLayer != nullptr /*allocRotated*/);
if (frameMem == nullptr) {
return NO_MEMORY;
@@ -851,7 +857,6 @@
if (dstFormat() == COLOR_Format32bitABGR2101010) {
videoFormat->setInt32("color-format", COLOR_FormatYUVP010);
} else {
- // TODO: Use Flexible color instead
videoFormat->setInt32("color-format", OMX_COLOR_FormatYUV420Planar);
}
@@ -922,9 +927,17 @@
return ERROR_MALFORMED;
}
+ int32_t srcFormat;
+ CHECK(outputFormat->findInt32("color-format", &srcFormat));
+
+ uint32_t bitDepth = 8;
+ if (COLOR_FormatYUVP010 == srcFormat) {
+ bitDepth = 10;
+ }
+
if (mFrame == NULL) {
sp<IMemory> frameMem = allocVideoFrame(
- trackMeta(), mWidth, mHeight, mTileWidth, mTileHeight, dstBpp());
+ trackMeta(), mWidth, mHeight, mTileWidth, mTileHeight, dstBpp(), bitDepth);
if (frameMem == nullptr) {
return NO_MEMORY;
@@ -935,9 +948,6 @@
setFrame(frameMem);
}
- int32_t srcFormat;
- CHECK(outputFormat->findInt32("color-format", &srcFormat));
-
ColorConverter converter((OMX_COLOR_FORMATTYPE)srcFormat, dstFormat());
uint32_t standard, range, transfer;
diff --git a/media/libstagefright/include/FrameDecoder.h b/media/libstagefright/include/FrameDecoder.h
index d59e4f5..e417324 100644
--- a/media/libstagefright/include/FrameDecoder.h
+++ b/media/libstagefright/include/FrameDecoder.h
@@ -50,7 +50,8 @@
sp<IMemory> extractFrame(FrameRect *rect = NULL);
static sp<IMemory> getMetadataOnly(
- const sp<MetaData> &trackMeta, int colorFormat, bool thumbnail = false);
+ const sp<MetaData> &trackMeta, int colorFormat,
+ bool thumbnail = false, uint32_t bitDepth = 0);
protected:
virtual ~FrameDecoder();