hdr10+: parameter passing for OMX
Add hdr10+ parameter passing to OMX. Metadata is sent to
OMX component via setConfig(). Available output metadata is
notified via onEvent(), and then retrieved via getConfig().
Hdr10+ metadata pass through is added to soft VP9 for testing.
bug: 118507186
test: Locally built DecoderTest in cts that sends
setParameters with input frames when decoding VP9.
Verify the metadata is received on expected output.
Change-Id: I9bb87581a3036f9ae3cc881cbfe1a3c99c8f78b3
diff --git a/media/libmediaextractor/include/media/stagefright/MetaDataBase.h b/media/libmediaextractor/include/media/stagefright/MetaDataBase.h
index 9f2deda..b99c14c 100644
--- a/media/libmediaextractor/include/media/stagefright/MetaDataBase.h
+++ b/media/libmediaextractor/include/media/stagefright/MetaDataBase.h
@@ -199,6 +199,7 @@
// HDR related
kKeyHdrStaticInfo = 'hdrS', // HDRStaticInfo
+ kKeyHdr10PlusInfo = 'hdrD', // raw data
// color aspects
kKeyColorRange = 'cRng', // int32_t, color range, value defined by ColorAspects.Range
diff --git a/media/libstagefright/ACodec.cpp b/media/libstagefright/ACodec.cpp
index 114f492..6ad0417 100644
--- a/media/libstagefright/ACodec.cpp
+++ b/media/libstagefright/ACodec.cpp
@@ -576,6 +576,7 @@
mTunneled(false),
mDescribeColorAspectsIndex((OMX_INDEXTYPE)0),
mDescribeHDRStaticInfoIndex((OMX_INDEXTYPE)0),
+ mDescribeHDR10PlusInfoIndex((OMX_INDEXTYPE)0),
mStateGeneration(0),
mVendorExtensionsStatus(kExtensionsUnchecked) {
memset(&mLastHDRStaticInfo, 0, sizeof(mLastHDRStaticInfo));
@@ -3765,8 +3766,17 @@
"OMX.google.android.index.describeHDRStaticInfo", &mDescribeHDRStaticInfoIndex);
if (err != OK) {
mDescribeHDRStaticInfoIndex = (OMX_INDEXTYPE)0;
+ return err;
}
- return err;
+
+ err = mOMXNode->getExtensionIndex(
+ "OMX.google.android.index.describeHDR10PlusInfo", &mDescribeHDR10PlusInfoIndex);
+ if (err != OK) {
+ mDescribeHDR10PlusInfoIndex = (OMX_INDEXTYPE)0;
+ return err;
+ }
+
+ return OK;
}
status_t ACodec::setHDRStaticInfo(const DescribeHDRStaticInfoParams ¶ms) {
@@ -5397,6 +5407,70 @@
return getVendorParameters(portIndex, notify);
}
+DescribeHDR10PlusInfoParams* ACodec::getHDR10PlusInfo(size_t paramSizeUsed) {
+ if (mDescribeHDR10PlusInfoIndex == 0) {
+ ALOGE("getHDR10PlusInfo: does not support DescribeHDR10PlusInfoParams");
+ return nullptr;
+ }
+
+ size_t newSize = sizeof(DescribeHDR10PlusInfoParams) - 1 +
+ ((paramSizeUsed > 0) ? paramSizeUsed : 512);
+ if (mHdr10PlusScratchBuffer == nullptr
+ || newSize > mHdr10PlusScratchBuffer->size()) {
+ mHdr10PlusScratchBuffer = new ABuffer(newSize);
+ }
+ DescribeHDR10PlusInfoParams *config =
+ (DescribeHDR10PlusInfoParams *)mHdr10PlusScratchBuffer->data();
+ InitOMXParams(config);
+ config->nSize = mHdr10PlusScratchBuffer->size();
+ config->nPortIndex = 1;
+ size_t paramSize = config->nSize - sizeof(DescribeHDR10PlusInfoParams) + 1;
+ config->nParamSize = paramSize;
+ config->nParamSizeUsed = 0;
+ status_t err = mOMXNode->getConfig(
+ (OMX_INDEXTYPE)mDescribeHDR10PlusInfoIndex,
+ config, config->nSize);
+ if (err != OK) {
+ ALOGE("failed to get DescribeHDR10PlusInfoParams (err %d)", err);
+ return nullptr;
+ }
+ if (config->nParamSize != paramSize) {
+ ALOGE("DescribeHDR10PlusInfoParams alters nParamSize: %u vs %zu",
+ config->nParamSize, paramSize);
+ return nullptr;
+ }
+ if (paramSizeUsed > 0 && config->nParamSizeUsed != paramSizeUsed) {
+ ALOGE("DescribeHDR10PlusInfoParams returns wrong nParamSizeUsed: %u vs %zu",
+ config->nParamSizeUsed, paramSizeUsed);
+ return nullptr;
+ }
+ return config;
+}
+
+void ACodec::onConfigUpdate(OMX_INDEXTYPE configIndex) {
+ if (mDescribeHDR10PlusInfoIndex == 0
+ || configIndex != mDescribeHDR10PlusInfoIndex) {
+ // mDescribeHDR10PlusInfoIndex is the only update we recognize now
+ return;
+ }
+
+ DescribeHDR10PlusInfoParams *config = getHDR10PlusInfo();
+ if (config == nullptr) {
+ return;
+ }
+ if (config->nParamSizeUsed > config->nParamSize) {
+ // try again with the size specified
+ config = getHDR10PlusInfo(config->nParamSizeUsed);
+ if (config == nullptr) {
+ return;
+ }
+ }
+
+ mOutputFormat = mOutputFormat->dup(); // trigger an output format changed event
+ mOutputFormat->setBuffer("hdr10-plus-info",
+ ABuffer::CreateAsCopy(config->nValue, config->nParamSizeUsed));
+}
+
void ACodec::onDataSpaceChanged(android_dataspace dataSpace, const ColorAspects &aspects) {
// aspects are normally communicated in ColorAspects
int32_t range, standard, transfer;
@@ -6337,6 +6411,15 @@
}
}
+ sp<ABuffer> hdr10PlusInfo;
+ if (buffer->format()->findBuffer("hdr10-plus-info", &hdr10PlusInfo)
+ && hdr10PlusInfo != nullptr && hdr10PlusInfo->size() > 0
+ && hdr10PlusInfo != mCodec->mLastHdr10PlusBuffer) {
+ native_window_set_buffers_hdr10_plus_metadata(mCodec->mNativeWindow.get(),
+ hdr10PlusInfo->size(), hdr10PlusInfo->data());
+ mCodec->mLastHdr10PlusBuffer = hdr10PlusInfo;
+ }
+
// save buffers sent to the surface so we can get render time when they return
int64_t mediaTimeUs = -1;
buffer->meta()->findInt64("timeUs", &mediaTimeUs);
@@ -7475,12 +7558,45 @@
}
}
+ sp<ABuffer> hdr10PlusInfo;
+ if (params->findBuffer("hdr10-plus-info", &hdr10PlusInfo)
+ && hdr10PlusInfo != nullptr && hdr10PlusInfo->size() > 0) {
+ (void)setHdr10PlusInfo(hdr10PlusInfo);
+ }
+
// Ignore errors as failure is expected for codecs that aren't video encoders.
(void)configureTemporalLayers(params, false /* inConfigure */, mOutputFormat);
return setVendorParameters(params);
}
+status_t ACodec::setHdr10PlusInfo(const sp<ABuffer> &hdr10PlusInfo) {
+ if (mDescribeHDR10PlusInfoIndex == 0) {
+ ALOGE("setHdr10PlusInfo: does not support DescribeHDR10PlusInfoParams");
+ return ERROR_UNSUPPORTED;
+ }
+ size_t newSize = sizeof(DescribeHDR10PlusInfoParams) + hdr10PlusInfo->size() - 1;
+ if (mHdr10PlusScratchBuffer == nullptr ||
+ newSize > mHdr10PlusScratchBuffer->size()) {
+ mHdr10PlusScratchBuffer = new ABuffer(newSize);
+ }
+ DescribeHDR10PlusInfoParams *config =
+ (DescribeHDR10PlusInfoParams *)mHdr10PlusScratchBuffer->data();
+ InitOMXParams(config);
+ config->nPortIndex = 0;
+ config->nSize = newSize;
+ config->nParamSize = hdr10PlusInfo->size();
+ config->nParamSizeUsed = hdr10PlusInfo->size();
+ memcpy(config->nValue, hdr10PlusInfo->data(), hdr10PlusInfo->size());
+ status_t err = mOMXNode->setConfig(
+ (OMX_INDEXTYPE)mDescribeHDR10PlusInfoIndex,
+ config, config->nSize);
+ if (err != OK) {
+ ALOGE("failed to set DescribeHDR10PlusInfoParams (err %d)", err);
+ }
+ return OK;
+}
+
// Removes trailing tags matching |tag| from |key| (e.g. a settings name). |minLength| specifies
// the minimum number of characters to keep in |key| (even if it has trailing tags).
// (Used to remove trailing 'value' tags in settings names, e.g. to normalize
@@ -7902,6 +8018,15 @@
return true;
}
+ case OMX_EventConfigUpdate:
+ {
+ CHECK_EQ(data1, (OMX_U32)kPortIndexOutput);
+
+ mCodec->onConfigUpdate((OMX_INDEXTYPE)data2);
+
+ return true;
+ }
+
case OMX_EventBufferFlag:
{
return true;
diff --git a/media/libstagefright/MediaCodec.cpp b/media/libstagefright/MediaCodec.cpp
index 70064ea..bd9e2bb 100644
--- a/media/libstagefright/MediaCodec.cpp
+++ b/media/libstagefright/MediaCodec.cpp
@@ -2197,6 +2197,13 @@
}
}
+ sp<ABuffer> hdr10PlusInfo;
+ if (mOutputFormat->findBuffer("hdr10-plus-info", &hdr10PlusInfo)
+ && hdr10PlusInfo != nullptr && hdr10PlusInfo->size() > 0) {
+ native_window_set_buffers_hdr10_plus_metadata(mSurface.get(),
+ hdr10PlusInfo->size(), hdr10PlusInfo->data());
+ }
+
if (mime.startsWithIgnoreCase("video/")) {
mSoftRenderer = new SoftwareRenderer(mSurface, mRotationDegrees);
}
diff --git a/media/libstagefright/Utils.cpp b/media/libstagefright/Utils.cpp
index cfa9fd9..3af4944 100644
--- a/media/libstagefright/Utils.cpp
+++ b/media/libstagefright/Utils.cpp
@@ -119,7 +119,8 @@
}
// if user/container supplied HDR static info without transfer set, assume true
- if (format->contains("hdr-static-info") && !format->contains("color-transfer")) {
+ if ((format->contains("hdr-static-info") || format->contains("hdr10-plus-info"))
+ && !format->contains("color-transfer")) {
return true;
}
// otherwise, verify that an HDR transfer function is set
@@ -876,6 +877,16 @@
ColorUtils::setHDRStaticInfoIntoFormat(*(HDRStaticInfo*)data, msg);
}
+ if (meta->findData(kKeyHdr10PlusInfo, &type, &data, &size)
+ && size > 0) {
+ sp<ABuffer> buffer = new (std::nothrow) ABuffer(size);
+ if (buffer.get() == NULL || buffer->base() == NULL) {
+ return NO_MEMORY;
+ }
+ memcpy(buffer->data(), data, size);
+ msg->setBuffer("hdr10-plus-info", buffer);
+ }
+
convertMetaDataToMessageColorAspects(meta, msg);
} else if (!strncasecmp("audio/", mime, 6)) {
int32_t numChannels, sampleRate;
@@ -1624,6 +1635,12 @@
}
}
+ sp<ABuffer> hdr10PlusInfo;
+ if (msg->findBuffer("hdr10-plus-info", &hdr10PlusInfo)) {
+ meta->setData(kKeyHdr10PlusInfo, 0,
+ hdr10PlusInfo->data(), hdr10PlusInfo->size());
+ }
+
convertMessageToMetaDataColorAspects(msg, meta);
AString tsSchema;
diff --git a/media/libstagefright/codecs/avcenc/SoftAVCEnc.cpp b/media/libstagefright/codecs/avcenc/SoftAVCEnc.cpp
index 379d41e..e0f2683 100644
--- a/media/libstagefright/codecs/avcenc/SoftAVCEnc.cpp
+++ b/media/libstagefright/codecs/avcenc/SoftAVCEnc.cpp
@@ -1058,8 +1058,8 @@
}
}
-OMX_ERRORTYPE SoftAVC::setConfig(
- OMX_INDEXTYPE index, const OMX_PTR _params) {
+OMX_ERRORTYPE SoftAVC::internalSetConfig(
+ OMX_INDEXTYPE index, const OMX_PTR _params, bool *frameConfig) {
switch ((int)index) {
case OMX_IndexConfigVideoIntraVOPRefresh:
{
@@ -1125,7 +1125,7 @@
}
default:
- return SimpleSoftOMXComponent::setConfig(index, _params);
+ return SimpleSoftOMXComponent::internalSetConfig(index, _params, frameConfig);
}
}
diff --git a/media/libstagefright/codecs/avcenc/SoftAVCEnc.h b/media/libstagefright/codecs/avcenc/SoftAVCEnc.h
index a43cdf1..8253b7d 100644
--- a/media/libstagefright/codecs/avcenc/SoftAVCEnc.h
+++ b/media/libstagefright/codecs/avcenc/SoftAVCEnc.h
@@ -219,8 +219,8 @@
OMX_ERRORTYPE internalSetBitrateParams(
const OMX_VIDEO_PARAM_BITRATETYPE *bitrate);
- OMX_ERRORTYPE setConfig(
- OMX_INDEXTYPE index, const OMX_PTR _params);
+ OMX_ERRORTYPE internalSetConfig(
+ OMX_INDEXTYPE index, const OMX_PTR _params, bool *frameConfig);
OMX_ERRORTYPE getConfig(
OMX_INDEXTYPE index, const OMX_PTR _params);
diff --git a/media/libstagefright/codecs/on2/dec/SoftVPX.cpp b/media/libstagefright/codecs/on2/dec/SoftVPX.cpp
index 8d5f3e7..0f2ff17 100644
--- a/media/libstagefright/codecs/on2/dec/SoftVPX.cpp
+++ b/media/libstagefright/codecs/on2/dec/SoftVPX.cpp
@@ -33,6 +33,7 @@
{ OMX_VIDEO_VP9Profile0, OMX_VIDEO_VP9Level5 },
{ OMX_VIDEO_VP9Profile2, OMX_VIDEO_VP9Level5 },
{ OMX_VIDEO_VP9Profile2HDR, OMX_VIDEO_VP9Level5 },
+ { OMX_VIDEO_VP9Profile2HDR10Plus, OMX_VIDEO_VP9Level5 },
};
SoftVPX::SoftVPX(
@@ -84,6 +85,10 @@
return true;
}
+bool SoftVPX::supportDescribeHdr10PlusInfo() {
+ return true;
+}
+
status_t SoftVPX::initDecoder() {
mCtx = new vpx_codec_ctx_t;
vpx_codec_err_t vpx_err;
@@ -167,7 +172,12 @@
outHeader->nOffset = 0;
outHeader->nFlags = 0;
outHeader->nFilledLen = (outputBufferWidth() * outputBufferHeight() * bpp * 3) / 2;
- outHeader->nTimeStamp = *(OMX_TICKS *)mImg->user_priv;
+ PrivInfo *privInfo = (PrivInfo *)mImg->user_priv;
+ outHeader->nTimeStamp = privInfo->mTimeStamp;
+ if (privInfo->mHdr10PlusInfo != nullptr) {
+ queueOutputFrameConfig(privInfo->mHdr10PlusInfo);
+ }
+
if (outputBufferSafe(outHeader)) {
uint8_t *dst = outHeader->pBuffer;
const uint8_t *srcY = (const uint8_t *)mImg->planes[VPX_PLANE_Y];
@@ -275,7 +285,13 @@
}
}
- mTimeStamps[mTimeStampIdx] = inHeader->nTimeStamp;
+ mPrivInfo[mTimeStampIdx].mTimeStamp = inHeader->nTimeStamp;
+
+ if (inInfo->mFrameConfig) {
+ mPrivInfo[mTimeStampIdx].mHdr10PlusInfo = dequeueInputFrameConfig();
+ } else {
+ mPrivInfo[mTimeStampIdx].mHdr10PlusInfo.clear();
+ }
if (inHeader->nFlags & OMX_BUFFERFLAG_EOS) {
mEOSStatus = INPUT_EOS_SEEN;
@@ -285,7 +301,7 @@
if (inHeader->nFilledLen > 0) {
vpx_codec_err_t err = vpx_codec_decode(
(vpx_codec_ctx_t *)mCtx, inHeader->pBuffer + inHeader->nOffset,
- inHeader->nFilledLen, &mTimeStamps[mTimeStampIdx], 0);
+ inHeader->nFilledLen, &mPrivInfo[mTimeStampIdx], 0);
if (err == VPX_CODEC_OK) {
inInfo->mOwnedByUs = false;
inQueue.erase(inQueue.begin());
diff --git a/media/libstagefright/codecs/on2/dec/SoftVPX.h b/media/libstagefright/codecs/on2/dec/SoftVPX.h
index b62b526..0aa8e9c 100644
--- a/media/libstagefright/codecs/on2/dec/SoftVPX.h
+++ b/media/libstagefright/codecs/on2/dec/SoftVPX.h
@@ -26,6 +26,8 @@
namespace android {
+struct ABuffer;
+
struct SoftVPX : public SoftVideoDecoderOMXComponent {
SoftVPX(const char *name,
const char *componentRole,
@@ -41,6 +43,7 @@
virtual void onPortFlushCompleted(OMX_U32 portIndex);
virtual void onReset();
virtual bool supportDescribeHdrStaticInfo();
+ virtual bool supportDescribeHdr10PlusInfo();
private:
enum {
@@ -60,7 +63,11 @@
void *mCtx;
bool mFrameParallelMode; // Frame parallel is only supported by VP9 decoder.
- OMX_TICKS mTimeStamps[kNumBuffers];
+ struct PrivInfo {
+ OMX_TICKS mTimeStamp;
+ sp<ABuffer> mHdr10PlusInfo;
+ };
+ PrivInfo mPrivInfo[kNumBuffers];
uint8_t mTimeStampIdx;
vpx_image_t *mImg;
diff --git a/media/libstagefright/codecs/on2/enc/SoftVPXEncoder.cpp b/media/libstagefright/codecs/on2/enc/SoftVPXEncoder.cpp
index 2dfba13..d0cb071 100644
--- a/media/libstagefright/codecs/on2/enc/SoftVPXEncoder.cpp
+++ b/media/libstagefright/codecs/on2/enc/SoftVPXEncoder.cpp
@@ -401,8 +401,8 @@
}
}
-OMX_ERRORTYPE SoftVPXEncoder::setConfig(
- OMX_INDEXTYPE index, const OMX_PTR _params) {
+OMX_ERRORTYPE SoftVPXEncoder::internalSetConfig(
+ OMX_INDEXTYPE index, const OMX_PTR _params, bool *frameConfig) {
switch (index) {
case OMX_IndexConfigVideoIntraVOPRefresh:
{
@@ -442,7 +442,7 @@
}
default:
- return SimpleSoftOMXComponent::setConfig(index, _params);
+ return SimpleSoftOMXComponent::internalSetConfig(index, _params, frameConfig);
}
}
diff --git a/media/libstagefright/codecs/on2/enc/SoftVPXEncoder.h b/media/libstagefright/codecs/on2/enc/SoftVPXEncoder.h
index dd86d36..263d134 100644
--- a/media/libstagefright/codecs/on2/enc/SoftVPXEncoder.h
+++ b/media/libstagefright/codecs/on2/enc/SoftVPXEncoder.h
@@ -84,8 +84,8 @@
virtual OMX_ERRORTYPE internalSetParameter(
OMX_INDEXTYPE index, const OMX_PTR param);
- virtual OMX_ERRORTYPE setConfig(
- OMX_INDEXTYPE index, const OMX_PTR params);
+ virtual OMX_ERRORTYPE internalSetConfig(
+ OMX_INDEXTYPE index, const OMX_PTR params, bool *frameConfig);
// OMX callback when buffers available
// Note that both an input and output buffer
diff --git a/media/libstagefright/include/media/stagefright/ACodec.h b/media/libstagefright/include/media/stagefright/ACodec.h
index 80125d4..9b2853e 100644
--- a/media/libstagefright/include/media/stagefright/ACodec.h
+++ b/media/libstagefright/include/media/stagefright/ACodec.h
@@ -237,6 +237,8 @@
android_native_rect_t mLastNativeWindowCrop;
int32_t mLastNativeWindowDataSpace;
HDRStaticInfo mLastHDRStaticInfo;
+ sp<ABuffer> mHdr10PlusScratchBuffer;
+ sp<ABuffer> mLastHdr10PlusBuffer;
sp<AMessage> mConfigFormat;
sp<AMessage> mInputFormat;
sp<AMessage> mOutputFormat;
@@ -290,6 +292,7 @@
OMX_INDEXTYPE mDescribeColorAspectsIndex;
OMX_INDEXTYPE mDescribeHDRStaticInfoIndex;
+ OMX_INDEXTYPE mDescribeHDR10PlusInfoIndex;
std::shared_ptr<ACodecBufferChannel> mBufferChannel;
@@ -424,6 +427,11 @@
// unspecified values.
void onDataSpaceChanged(android_dataspace dataSpace, const ColorAspects &aspects);
+ // notifies the codec that the config with |configIndex| has changed, the value
+ // can be queried by OMX getConfig, and the config should be applied to the next
+ // output buffer notified after this callback.
+ void onConfigUpdate(OMX_INDEXTYPE configIndex);
+
// gets index or sets it to 0 on error. Returns error from codec.
status_t initDescribeHDRStaticInfoIndex();
@@ -435,12 +443,22 @@
// sets |params|. Returns the codec error.
status_t setHDRStaticInfo(const DescribeHDRStaticInfoParams ¶ms);
+ // sets |hdr10PlusInfo|. Returns the codec error.
+ status_t setHdr10PlusInfo(const sp<ABuffer> &hdr10PlusInfo);
+
// gets |params|. Returns the codec error.
status_t getHDRStaticInfo(DescribeHDRStaticInfoParams ¶ms);
// gets HDR static information for the video encoder/decoder port and sets them into |format|.
status_t getHDRStaticInfoForVideoCodec(OMX_U32 portIndex, sp<AMessage> &format);
+ // gets DescribeHDR10PlusInfoParams params. If |paramSizeUsed| is zero, it's
+ // possible that the returned DescribeHDR10PlusInfoParams only has the
+ // nParamSizeUsed field updated, because the size of the storage is insufficient.
+ // In this case, getHDR10PlusInfo() should be called again with |paramSizeUsed|
+ // specified to the previous returned value.
+ DescribeHDR10PlusInfoParams* getHDR10PlusInfo(size_t paramSizeUsed = 0);
+
typedef struct drcParams {
int32_t drcCut;
int32_t drcBoost;
diff --git a/media/libstagefright/omx/SimpleSoftOMXComponent.cpp b/media/libstagefright/omx/SimpleSoftOMXComponent.cpp
index 55afe04..ddb459f 100644
--- a/media/libstagefright/omx/SimpleSoftOMXComponent.cpp
+++ b/media/libstagefright/omx/SimpleSoftOMXComponent.cpp
@@ -34,7 +34,8 @@
mLooper(new ALooper),
mHandler(new AHandlerReflector<SimpleSoftOMXComponent>(this)),
mState(OMX_StateLoaded),
- mTargetState(OMX_StateLoaded) {
+ mTargetState(OMX_StateLoaded),
+ mFrameConfig(false) {
mLooper->setName(name);
mLooper->registerHandler(mHandler);
@@ -204,6 +205,21 @@
}
}
+OMX_ERRORTYPE SimpleSoftOMXComponent::internalSetConfig(
+ OMX_INDEXTYPE index, const OMX_PTR params, bool *frameConfig) {
+ return OMX_ErrorUndefined;
+}
+
+OMX_ERRORTYPE SimpleSoftOMXComponent::setConfig(
+ OMX_INDEXTYPE index, const OMX_PTR params) {
+ bool frameConfig = mFrameConfig;
+ OMX_ERRORTYPE err = internalSetConfig(index, params, &frameConfig);
+ if (err == OMX_ErrorNone) {
+ mFrameConfig = frameConfig;
+ }
+ return err;
+}
+
OMX_ERRORTYPE SimpleSoftOMXComponent::useBuffer(
OMX_BUFFERHEADERTYPE **header,
OMX_U32 portIndex,
@@ -336,6 +352,10 @@
OMX_BUFFERHEADERTYPE *buffer) {
sp<AMessage> msg = new AMessage(kWhatEmptyThisBuffer, mHandler);
msg->setPointer("header", buffer);
+ if (mFrameConfig) {
+ msg->setInt32("frame-config", mFrameConfig);
+ mFrameConfig = false;
+ }
msg->post();
return OMX_ErrorNone;
@@ -378,6 +398,10 @@
{
OMX_BUFFERHEADERTYPE *header;
CHECK(msg->findPointer("header", (void **)&header));
+ int32_t frameConfig;
+ if (!msg->findInt32("frame-config", &frameConfig)) {
+ frameConfig = 0;
+ }
CHECK(mState == OMX_StateExecuting && mTargetState == mState);
@@ -393,6 +417,7 @@
CHECK(!buffer->mOwnedByUs);
buffer->mOwnedByUs = true;
+ buffer->mFrameConfig = (bool)frameConfig;
CHECK((msgType == kWhatEmptyThisBuffer
&& port->mDef.eDir == OMX_DirInput)
diff --git a/media/libstagefright/omx/SoftVideoDecoderOMXComponent.cpp b/media/libstagefright/omx/SoftVideoDecoderOMXComponent.cpp
index f9f7ec2..e853da9 100644
--- a/media/libstagefright/omx/SoftVideoDecoderOMXComponent.cpp
+++ b/media/libstagefright/omx/SoftVideoDecoderOMXComponent.cpp
@@ -602,13 +602,40 @@
return OMX_ErrorNone;
}
+ case kDescribeHdr10PlusInfoIndex:
+ {
+ if (!supportDescribeHdr10PlusInfo()) {
+ return OMX_ErrorUnsupportedIndex;
+ }
+
+ if (mHdr10PlusOutputs.size() > 0) {
+ auto it = mHdr10PlusOutputs.begin();
+
+ auto info = (*it).get();
+
+ DescribeHDR10PlusInfoParams* outParams =
+ (DescribeHDR10PlusInfoParams *)params;
+
+ outParams->nParamSizeUsed = info->size();
+
+ // If the buffer provided by the client does not have enough
+ // storage, return the size only and do not remove the param yet.
+ if (outParams->nParamSize >= info->size()) {
+ memcpy(outParams->nValue, info->data(), info->size());
+ mHdr10PlusOutputs.erase(it);
+ }
+ return OMX_ErrorNone;
+ }
+ return OMX_ErrorUnderflow;
+ }
+
default:
return OMX_ErrorUnsupportedIndex;
}
}
-OMX_ERRORTYPE SoftVideoDecoderOMXComponent::setConfig(
- OMX_INDEXTYPE index, const OMX_PTR params){
+OMX_ERRORTYPE SoftVideoDecoderOMXComponent::internalSetConfig(
+ OMX_INDEXTYPE index, const OMX_PTR params, bool *frameConfig){
switch ((int)index) {
case kDescribeColorAspectsIndex:
{
@@ -658,11 +685,55 @@
return OMX_ErrorNone;
}
+ case kDescribeHdr10PlusInfoIndex:
+ {
+ if (!supportDescribeHdr10PlusInfo()) {
+ return OMX_ErrorUnsupportedIndex;
+ }
+
+ const DescribeHDR10PlusInfoParams* inParams =
+ (DescribeHDR10PlusInfoParams *)params;
+
+ if (*frameConfig) {
+ // This is a request to append to the current frame config set.
+ // For now, we only support kDescribeHdr10PlusInfoIndex, which
+ // we simply replace with the last set value.
+ if (mHdr10PlusInputs.size() > 0) {
+ *(--mHdr10PlusInputs.end()) = ABuffer::CreateAsCopy(
+ inParams->nValue, inParams->nParamSizeUsed);
+ } else {
+ ALOGW("Ignoring kDescribeHdr10PlusInfoIndex: append to "
+ "frame config while no frame config is present");
+ }
+ } else {
+ // This is a frame config, setting *frameConfig to true so that
+ // the client marks the next queued input frame to apply it.
+ *frameConfig = true;
+ mHdr10PlusInputs.push_back(ABuffer::CreateAsCopy(
+ inParams->nValue, inParams->nParamSizeUsed));
+ }
+ return OMX_ErrorNone;
+ }
+
default:
return OMX_ErrorUnsupportedIndex;
}
}
+sp<ABuffer> SoftVideoDecoderOMXComponent::dequeueInputFrameConfig() {
+ auto it = mHdr10PlusInputs.begin();
+ sp<ABuffer> info = *it;
+ mHdr10PlusInputs.erase(it);
+ return info;
+}
+
+void SoftVideoDecoderOMXComponent::queueOutputFrameConfig(const sp<ABuffer> &info) {
+ mHdr10PlusOutputs.push_back(info);
+ notify(OMX_EventConfigUpdate,
+ kOutputPortIndex,
+ kDescribeHdr10PlusInfoIndex,
+ NULL);
+}
OMX_ERRORTYPE SoftVideoDecoderOMXComponent::getExtensionIndex(
const char *name, OMX_INDEXTYPE *index) {
@@ -677,6 +748,10 @@
&& supportDescribeHdrStaticInfo()) {
*(int32_t*)index = kDescribeHdrStaticInfoIndex;
return OMX_ErrorNone;
+ } else if (!strcmp(name, "OMX.google.android.index.describeHDR10PlusInfo")
+ && supportDescribeHdr10PlusInfo()) {
+ *(int32_t*)index = kDescribeHdr10PlusInfoIndex;
+ return OMX_ErrorNone;
}
return SimpleSoftOMXComponent::getExtensionIndex(name, index);
@@ -694,6 +769,10 @@
return false;
}
+bool SoftVideoDecoderOMXComponent::supportDescribeHdr10PlusInfo() {
+ return false;
+}
+
void SoftVideoDecoderOMXComponent::onReset() {
mOutputPortSettingsChange = NONE;
}
diff --git a/media/libstagefright/omx/include/media/stagefright/omx/SimpleSoftOMXComponent.h b/media/libstagefright/omx/include/media/stagefright/omx/SimpleSoftOMXComponent.h
index 1d1f2bd..6bbedda 100644
--- a/media/libstagefright/omx/include/media/stagefright/omx/SimpleSoftOMXComponent.h
+++ b/media/libstagefright/omx/include/media/stagefright/omx/SimpleSoftOMXComponent.h
@@ -20,6 +20,7 @@
#include "SoftOMXComponent.h"
+#include <atomic>
#include <media/stagefright/foundation/AHandlerReflector.h>
#include <utils/RefBase.h>
#include <utils/threads.h>
@@ -28,6 +29,7 @@
namespace android {
struct ALooper;
+struct ABuffer;
struct CodecProfileLevel {
OMX_U32 mProfile;
@@ -49,6 +51,7 @@
struct BufferInfo {
OMX_BUFFERHEADERTYPE *mHeader;
bool mOwnedByUs;
+ bool mFrameConfig;
};
struct PortInfo {
@@ -76,6 +79,9 @@
virtual OMX_ERRORTYPE internalSetParameter(
OMX_INDEXTYPE index, const OMX_PTR params);
+ virtual OMX_ERRORTYPE internalSetConfig(
+ OMX_INDEXTYPE index, const OMX_PTR params, bool *frameConfig);
+
virtual void onQueueFilled(OMX_U32 portIndex);
List<BufferInfo *> &getPortQueue(OMX_U32 portIndex);
@@ -101,6 +107,7 @@
OMX_STATETYPE mTargetState;
Vector<PortInfo> mPorts;
+ std::atomic_bool mFrameConfig;
bool isSetParameterAllowed(
OMX_INDEXTYPE index, const OMX_PTR params) const;
@@ -114,6 +121,9 @@
virtual OMX_ERRORTYPE setParameter(
OMX_INDEXTYPE index, const OMX_PTR params);
+ virtual OMX_ERRORTYPE setConfig(
+ OMX_INDEXTYPE index, const OMX_PTR params);
+
virtual OMX_ERRORTYPE useBuffer(
OMX_BUFFERHEADERTYPE **buffer,
OMX_U32 portIndex,
diff --git a/media/libstagefright/omx/include/media/stagefright/omx/SoftVideoDecoderOMXComponent.h b/media/libstagefright/omx/include/media/stagefright/omx/SoftVideoDecoderOMXComponent.h
index 56fc691..3b381ce 100644
--- a/media/libstagefright/omx/include/media/stagefright/omx/SoftVideoDecoderOMXComponent.h
+++ b/media/libstagefright/omx/include/media/stagefright/omx/SoftVideoDecoderOMXComponent.h
@@ -20,6 +20,7 @@
#include "SimpleSoftOMXComponent.h"
+#include <media/stagefright/foundation/ABuffer.h>
#include <media/stagefright/foundation/AHandlerReflector.h>
#include <media/stagefright/foundation/ColorUtils.h>
#include <media/IOMX.h>
@@ -28,6 +29,7 @@
#include <utils/RefBase.h>
#include <utils/threads.h>
#include <utils/Vector.h>
+#include <utils/List.h>
namespace android {
@@ -48,6 +50,7 @@
enum {
kDescribeColorAspectsIndex = kPrepareForAdaptivePlaybackIndex + 1,
kDescribeHdrStaticInfoIndex = kPrepareForAdaptivePlaybackIndex + 2,
+ kDescribeHdr10PlusInfoIndex = kPrepareForAdaptivePlaybackIndex + 3,
};
enum {
@@ -68,8 +71,8 @@
virtual OMX_ERRORTYPE getConfig(
OMX_INDEXTYPE index, OMX_PTR params);
- virtual OMX_ERRORTYPE setConfig(
- OMX_INDEXTYPE index, const OMX_PTR params);
+ virtual OMX_ERRORTYPE internalSetConfig(
+ OMX_INDEXTYPE index, const OMX_PTR params, bool *frameConfig);
virtual OMX_ERRORTYPE getExtensionIndex(
const char *name, OMX_INDEXTYPE *index);
@@ -80,6 +83,8 @@
virtual bool supportDescribeHdrStaticInfo();
+ virtual bool supportDescribeHdr10PlusInfo();
+
// This function sets both minimum buffer count and actual buffer count of
// input port to be |numInputBuffers|. It will also set both minimum buffer
// count and actual buffer count of output port to be |numOutputBuffers|.
@@ -166,6 +171,9 @@
// Helper function to dump the ColorAspects.
void dumpColorAspects(const ColorAspects &colorAspects);
+ sp<ABuffer> dequeueInputFrameConfig();
+ void queueOutputFrameConfig(const sp<ABuffer> &info);
+
private:
uint32_t mMinInputBufferSize;
uint32_t mMinCompressionRatio;
@@ -174,6 +182,9 @@
OMX_VIDEO_CODINGTYPE mCodingType;
const CodecProfileLevel *mProfileLevels;
size_t mNumProfileLevels;
+ typedef List<sp<ABuffer> > Hdr10PlusInfoList;
+ Hdr10PlusInfoList mHdr10PlusInputs;
+ Hdr10PlusInfoList mHdr10PlusOutputs;
DISALLOW_EVIL_CONSTRUCTORS(SoftVideoDecoderOMXComponent);
};