Merge "MediaCodec: add CodecErrorLog" into udc-dev
diff --git a/apex/TEST_MAPPING b/apex/TEST_MAPPING
index 4b7c019..bb4f089 100644
--- a/apex/TEST_MAPPING
+++ b/apex/TEST_MAPPING
@@ -7,16 +7,16 @@
"presubmit": [
// The following tests validate codec and drm path.
{
- "name": "GtsMediaTestCases",
+ "name": "WvtsDeviceTestCases",
"options" : [
{
"include-annotation": "android.platform.test.annotations.Presubmit"
},
{
- "include-filter": "com.google.android.media.gts.WidevineGenericOpsTests"
+ "include-filter": "com.google.android.media.wvts.WidevineGenericOpsTests"
},
{
- "include-filter": "com.google.android.media.gts.WidevineH264PlaybackTests"
+ "include-filter": "com.google.android.media.wvts.WidevineH264PlaybackTests"
}
]
}
diff --git a/drm/TEST_MAPPING b/drm/TEST_MAPPING
index b2d4d6e..a9b4b2a 100644
--- a/drm/TEST_MAPPING
+++ b/drm/TEST_MAPPING
@@ -2,16 +2,16 @@
"presubmit": [
// The following tests validate codec and drm path.
{
- "name": "GtsMediaTestCases",
+ "name": "WvtsDeviceTestCases",
"options" : [
{
"include-annotation": "android.platform.test.annotations.Presubmit"
},
{
- "include-filter": "com.google.android.media.gts.WidevineGenericOpsTests"
+ "include-filter": "com.google.android.media.wvts.WidevineGenericOpsTests"
},
{
- "include-filter": "com.google.android.media.gts.WidevineH264PlaybackTests"
+ "include-filter": "com.google.android.media.wvts.WidevineH264PlaybackTests"
}
]
}
diff --git a/drm/libmediadrm/TEST_MAPPING b/drm/libmediadrm/TEST_MAPPING
index bc15879..8d7be22 100644
--- a/drm/libmediadrm/TEST_MAPPING
+++ b/drm/libmediadrm/TEST_MAPPING
@@ -1,19 +1,19 @@
{
"presubmit": [
{
- "name": "GtsMediaTestCases",
+ "name": "WvtsDeviceTestCases",
"options" : [
{
"include-annotation": "android.platform.test.annotations.Presubmit"
},
{
- "include-filter": "com.google.android.media.gts.WidevineGenericOpsTests"
+ "include-filter": "com.google.android.media.wvts.WidevineGenericOpsTests"
},
{
- "include-filter": "com.google.android.media.gts.MediaDrmTest"
+ "include-filter": "com.google.android.media.wvts.MediaDrmTest"
},
{
- "include-filter": "com.google.android.media.gts.WidevineDashPolicyTests"
+ "include-filter": "com.google.android.media.wvts.WidevineDashPolicyTests"
}
]
}
diff --git a/include/drm/TEST_MAPPING b/include/drm/TEST_MAPPING
index 74fa50d..8595f12 100644
--- a/include/drm/TEST_MAPPING
+++ b/include/drm/TEST_MAPPING
@@ -1,16 +1,16 @@
{
"presubmit": [
{
- "name": "GtsMediaTestCases",
+ "name": "WvtsDeviceTestCases",
"options" : [
{
"include-annotation": "android.platform.test.annotations.Presubmit"
},
{
- "include-filter": "com.google.android.media.gts.WidevineGenericOpsTests"
+ "include-filter": "com.google.android.media.wvts.WidevineGenericOpsTests"
},
{
- "include-filter": "com.google.android.media.gts.WidevineH264PlaybackTests"
+ "include-filter": "com.google.android.media.wvts.WidevineH264PlaybackTests"
}
]
}
diff --git a/media/TEST_MAPPING b/media/TEST_MAPPING
index 9e51cff..5b1bd91 100644
--- a/media/TEST_MAPPING
+++ b/media/TEST_MAPPING
@@ -21,16 +21,16 @@
],
"presubmit": [
{
- "name": "GtsMediaTestCases",
+ "name": "WvtsDeviceTestCases",
"options" : [
{
"include-annotation": "android.platform.test.annotations.Presubmit"
},
{
- "include-filter": "com.google.android.media.gts.WidevineGenericOpsTests"
+ "include-filter": "com.google.android.media.wvts.WidevineGenericOpsTests"
},
{
- "include-filter": "com.google.android.media.gts.WidevineH264PlaybackTests"
+ "include-filter": "com.google.android.media.wvts.WidevineH264PlaybackTests"
}
],
"file_patterns": ["(?i)drm|crypto"]
diff --git a/media/codec2/sfplugin/CCodecBufferChannel.cpp b/media/codec2/sfplugin/CCodecBufferChannel.cpp
index e800ccd..d2df4f3 100644
--- a/media/codec2/sfplugin/CCodecBufferChannel.cpp
+++ b/media/codec2/sfplugin/CCodecBufferChannel.cpp
@@ -426,7 +426,8 @@
size_t offset,
const CryptoPlugin::SubSample *subSamples,
size_t numSubSamples,
- const sp<MediaCodecBuffer> &buffer) {
+ const sp<MediaCodecBuffer> &buffer,
+ AString* errorDetailMsg) {
static const C2MemoryUsage kSecureUsage{C2MemoryUsage::READ_PROTECTED, 0};
static const C2MemoryUsage kDefaultReadWriteUsage{
C2MemoryUsage::CPU_READ, C2MemoryUsage::CPU_WRITE};
@@ -456,7 +457,6 @@
ssize_t result = -1;
ssize_t codecDataOffset = 0;
if (mCrypto) {
- AString errorDetailMsg;
int32_t heapSeqNum = getHeapSeqNum(memory);
hardware::drm::V1_0::SharedBuffer src{(uint32_t)heapSeqNum, offset, size};
hardware::drm::V1_0::DestinationBuffer dst;
@@ -470,7 +470,7 @@
}
result = mCrypto->decrypt(
key, iv, mode, pattern, src, 0, subSamples, numSubSamples,
- dst, &errorDetailMsg);
+ dst, errorDetailMsg);
if (result < 0) {
ALOGI("[%s] attachEncryptedBuffer: decrypt failed: result = %zd", mName, result);
return result;
@@ -515,7 +515,9 @@
result = (ssize_t)_bytesWritten;
detailedError = _detailedError;
});
-
+ if (errorDetailMsg) {
+ errorDetailMsg->setTo(detailedError.c_str(), detailedError.size());
+ }
if (!returnVoid.isOk() || status != CasStatus::OK || result < 0) {
ALOGI("[%s] descramble failed, trans=%s, status=%d, result=%zd",
mName, returnVoid.description().c_str(), status, result);
diff --git a/media/codec2/sfplugin/CCodecBufferChannel.h b/media/codec2/sfplugin/CCodecBufferChannel.h
index e2e55b9..20dca2b 100644
--- a/media/codec2/sfplugin/CCodecBufferChannel.h
+++ b/media/codec2/sfplugin/CCodecBufferChannel.h
@@ -86,7 +86,8 @@
size_t offset,
const CryptoPlugin::SubSample *subSamples,
size_t numSubSamples,
- const sp<MediaCodecBuffer> &buffer) override;
+ const sp<MediaCodecBuffer> &buffer,
+ AString* errorDetailMsg) override;
virtual status_t renderOutputBuffer(
const sp<MediaCodecBuffer> &buffer, int64_t timestampNs) override;
virtual void pollForRenderedBuffers() override;
diff --git a/media/codec2/vndk/C2Store.cpp b/media/codec2/vndk/C2Store.cpp
index d7a9764..f6f97da 100644
--- a/media/codec2/vndk/C2Store.cpp
+++ b/media/codec2/vndk/C2Store.cpp
@@ -15,7 +15,7 @@
*/
#define LOG_TAG "C2Store"
-#define LOG_NDEBUG 0
+// #define LOG_NDEBUG 0
#include <utils/Log.h>
#include <C2AllocatorBlob.h>
diff --git a/media/libstagefright/ACodecBufferChannel.cpp b/media/libstagefright/ACodecBufferChannel.cpp
index 57f26d0..8f2bed2 100644
--- a/media/libstagefright/ACodecBufferChannel.cpp
+++ b/media/libstagefright/ACodecBufferChannel.cpp
@@ -347,7 +347,8 @@
size_t offset,
const CryptoPlugin::SubSample *subSamples,
size_t numSubSamples,
- const sp<MediaCodecBuffer> &buffer) {
+ const sp<MediaCodecBuffer> &buffer,
+ AString* errorDetailMsg) {
std::shared_ptr<const std::vector<const BufferInfo>> array(
std::atomic_load(&mInputBuffers));
BufferInfoIterator it = findClientBuffer(array, buffer);
@@ -371,7 +372,6 @@
ssize_t result = -1;
ssize_t codecDataOffset = 0;
if (mCrypto != NULL) {
- AString errorDetailMsg;
hardware::drm::V1_0::DestinationBuffer destination;
if (secure) {
destination.type = DrmBufferType::NATIVE_HANDLE;
@@ -387,7 +387,7 @@
result = mCrypto->decrypt(key, iv, mode, pattern,
source, it->mClientBuffer->offset(),
- subSamples, numSubSamples, destination, &errorDetailMsg);
+ subSamples, numSubSamples, destination, errorDetailMsg);
if (result < 0) {
return result;
@@ -441,7 +441,9 @@
result = (ssize_t)_bytesWritten;
detailedError = _detailedError;
});
-
+ if (errorDetailMsg) {
+ errorDetailMsg->setTo(detailedError.c_str(), detailedError.size());
+ }
if (!returnVoid.isOk() || status != Status::OK || result < 0) {
ALOGE("descramble failed, trans=%s, status=%d, result=%zd",
returnVoid.description().c_str(), status, result);
diff --git a/media/libstagefright/CryptoAsync.cpp b/media/libstagefright/CryptoAsync.cpp
index 32fd3be..8b5c8ed 100644
--- a/media/libstagefright/CryptoAsync.cpp
+++ b/media/libstagefright/CryptoAsync.cpp
@@ -153,7 +153,7 @@
// attach buffer
err = channel->attachEncryptedBuffer(
memory, secure, key, iv, mode, pattern,
- offset, subSamples, numSubSamples, buffer);
+ offset, subSamples, numSubSamples, buffer, &errorDetailMsg);
// a generic error
auto handleError = [this, &err, &msg]() {
diff --git a/media/libstagefright/MediaCodec.cpp b/media/libstagefright/MediaCodec.cpp
index d822000..c9287e5 100644
--- a/media/libstagefright/MediaCodec.cpp
+++ b/media/libstagefright/MediaCodec.cpp
@@ -4332,11 +4332,10 @@
mFlags |= kFlagUseBlockModel;
}
if (flags & CONFIGURE_FLAG_USE_CRYPTO_ASYNC) {
- // silently disable crytoasync with blockmodel
- if (!(mFlags & kFlagUseBlockModel)) {
- mFlags |= kFlagUseCryptoAsync;
- } else {
- ALOGW("CrytoAsync not yet enabled for block model, falling back to normal");
+ mFlags |= kFlagUseCryptoAsync;
+ if ((mFlags & kFlagUseBlockModel)) {
+ ALOGW("CrytoAsync not yet enabled for block model,\
+ falling back to normal");
}
}
}
@@ -4366,17 +4365,23 @@
mBufferChannel->setDescrambler(mDescrambler);
if ((mFlags & kFlagUseCryptoAsync) &&
mCrypto && (mDomain == DOMAIN_VIDEO)) {
- mCryptoAsync = new CryptoAsync(mBufferChannel);
- mCryptoAsync->setCallback(
- std::make_unique<CryptoAsyncCallback>(new AMessage(kWhatCodecNotify, this)));
- mCryptoLooper = new ALooper();
- mCryptoLooper->setName("CryptoAsyncLooper");
- mCryptoLooper->registerHandler(mCryptoAsync);
- status_t err = mCryptoLooper->start();
- if (err != OK) {
- ALOGE("Crypto Looper failed to start");
- mCryptoAsync = nullptr;
- mCryptoLooper = nullptr;
+ // set kFlagUseCryptoAsync but do-not use this for block model
+ // this is to propagate the error in onCryptoError()
+ // TODO (b/274628160): Enable Use of CONFIG_FLAG_USE_CRYPTO_ASYNC
+ // with CONFIGURE_FLAG_USE_BLOCK_MODEL)
+ if (!(mFlags & kFlagUseBlockModel)) {
+ mCryptoAsync = new CryptoAsync(mBufferChannel);
+ mCryptoAsync->setCallback(
+ std::make_unique<CryptoAsyncCallback>(new AMessage(kWhatCodecNotify, this)));
+ mCryptoLooper = new ALooper();
+ mCryptoLooper->setName("CryptoAsyncLooper");
+ mCryptoLooper->registerHandler(mCryptoAsync);
+ status_t err = mCryptoLooper->start();
+ if (err != OK) {
+ ALOGE("Crypto Looper failed to start");
+ mCryptoAsync = nullptr;
+ mCryptoLooper = nullptr;
+ }
}
}
@@ -5621,9 +5626,24 @@
if (c2Buffer) {
err = mBufferChannel->attachBuffer(c2Buffer, buffer);
} else if (memory) {
+ AString errorDetailMsg;
err = mBufferChannel->attachEncryptedBuffer(
memory, (mFlags & kFlagIsSecure), key, iv, mode, pattern,
- offset, subSamples, numSubSamples, buffer);
+ offset, subSamples, numSubSamples, buffer, &errorDetailMsg);
+ if (err != OK && hasCryptoOrDescrambler()
+ && (mFlags & kFlagUseCryptoAsync)) {
+ // create error detail
+ AString errorDetailMsg;
+ sp<AMessage> cryptoErrorInfo = new AMessage();
+ buildCryptoInfoAMessage(cryptoErrorInfo, CryptoAsync::kActionDecrypt);
+ cryptoErrorInfo->setInt32("err", err);
+ cryptoErrorInfo->setInt32("actionCode", ACTION_CODE_FATAL);
+ cryptoErrorInfo->setString("errorDetail", errorDetailMsg);
+ onCryptoError(cryptoErrorInfo);
+ // we want cryptoError to be in the callback
+ // but Codec IllegalStateException to be triggered.
+ err = INVALID_OPERATION;
+ }
} else {
mErrorLog.log(LOG_TAG, "Fatal error: invalid queue request without a buffer");
err = UNKNOWN_ERROR;
diff --git a/media/libstagefright/include/ACodecBufferChannel.h b/media/libstagefright/include/ACodecBufferChannel.h
index f3b0600..903280f 100644
--- a/media/libstagefright/include/ACodecBufferChannel.h
+++ b/media/libstagefright/include/ACodecBufferChannel.h
@@ -94,7 +94,8 @@
size_t offset,
const CryptoPlugin::SubSample *subSamples,
size_t numSubSamples,
- const sp<MediaCodecBuffer> &buffer) override;
+ const sp<MediaCodecBuffer> &buffer,
+ AString* errorDetailMsg) override;
virtual status_t renderOutputBuffer(
const sp<MediaCodecBuffer> &buffer, int64_t timestampNs) override;
virtual void pollForRenderedBuffers() override;
diff --git a/media/libstagefright/include/media/stagefright/CodecBase.h b/media/libstagefright/include/media/stagefright/CodecBase.h
index aa02151..916d41e 100644
--- a/media/libstagefright/include/media/stagefright/CodecBase.h
+++ b/media/libstagefright/include/media/stagefright/CodecBase.h
@@ -385,7 +385,8 @@
size_t offset,
const CryptoPlugin::SubSample *subSamples,
size_t numSubSamples,
- const sp<MediaCodecBuffer> &buffer) {
+ const sp<MediaCodecBuffer> &buffer,
+ AString* errorDetailMsg) {
(void)memory;
(void)secure;
(void)key;
@@ -396,6 +397,7 @@
(void)subSamples;
(void)numSubSamples;
(void)buffer;
+ (void)errorDetailMsg;
return -ENOSYS;
}
/**
diff --git a/media/libstagefright/tests/mediacodec/MediaCodecTest.cpp b/media/libstagefright/tests/mediacodec/MediaCodecTest.cpp
index ecdaac5..71ddbe5 100644
--- a/media/libstagefright/tests/mediacodec/MediaCodecTest.cpp
+++ b/media/libstagefright/tests/mediacodec/MediaCodecTest.cpp
@@ -62,7 +62,8 @@
size_t offset,
const CryptoPlugin::SubSample *subSamples,
size_t numSubSamples,
- const sp<MediaCodecBuffer> &buffer),
+ const sp<MediaCodecBuffer> &buffer,
+ AString* errorDetailMsg),
(override));
MOCK_METHOD(status_t, renderOutputBuffer,
(const sp<MediaCodecBuffer> &buffer, int64_t timestampNs),
diff --git a/services/audioflinger/Effects.cpp b/services/audioflinger/Effects.cpp
index 4904638..19e4151 100644
--- a/services/audioflinger/Effects.cpp
+++ b/services/audioflinger/Effects.cpp
@@ -570,7 +570,6 @@
mMaxDisableWaitCnt(1), // set by configure(), should be >= 1
mDisableWaitCnt(0), // set by process() and updateState()
mOffloaded(false),
- mAddedToHal(false),
mIsOutput(false)
#ifdef FLOAT_EFFECT_CHAIN
, mSupportsFloat(false)
@@ -1104,12 +1103,12 @@
{
if ((mDescriptor.flags & EFFECT_FLAG_TYPE_MASK) == EFFECT_FLAG_TYPE_PRE_PROC ||
(mDescriptor.flags & EFFECT_FLAG_TYPE_MASK) == EFFECT_FLAG_TYPE_POST_PROC) {
- if (mAddedToHal) {
+ if (mCurrentHalStream == getCallback()->io()) {
return;
}
(void)getCallback()->addEffectToHal(mEffectInterface);
- mAddedToHal = true;
+ mCurrentHalStream = getCallback()->io();
}
}
@@ -1205,12 +1204,11 @@
{
if ((mDescriptor.flags & EFFECT_FLAG_TYPE_MASK) == EFFECT_FLAG_TYPE_PRE_PROC ||
(mDescriptor.flags & EFFECT_FLAG_TYPE_MASK) == EFFECT_FLAG_TYPE_POST_PROC) {
- if (!mAddedToHal) {
- return NO_ERROR;
+ if (mCurrentHalStream != getCallback()->io()) {
+ return (mCurrentHalStream == AUDIO_IO_HANDLE_NONE) ? NO_ERROR : INVALID_OPERATION;
}
-
getCallback()->removeEffectFromHal(mEffectInterface);
- mAddedToHal = false;
+ mCurrentHalStream = AUDIO_IO_HANDLE_NONE;
}
return NO_ERROR;
}
diff --git a/services/audioflinger/Effects.h b/services/audioflinger/Effects.h
index 13e10d0..885d3e5 100644
--- a/services/audioflinger/Effects.h
+++ b/services/audioflinger/Effects.h
@@ -319,7 +319,8 @@
// sending disable command.
uint32_t mDisableWaitCnt; // current process() calls count during disable period.
bool mOffloaded; // effect is currently offloaded to the audio DSP
- bool mAddedToHal; // effect has been added to the audio HAL
+ // effect has been added to this HAL input stream
+ audio_io_handle_t mCurrentHalStream = AUDIO_IO_HANDLE_NONE;
bool mIsOutput; // direction of the AF thread
#ifdef FLOAT_EFFECT_CHAIN
diff --git a/services/audiopolicy/common/managerdefinitions/src/AudioPolicyMix.cpp b/services/audiopolicy/common/managerdefinitions/src/AudioPolicyMix.cpp
index ba5a6a7..4cfdaad 100644
--- a/services/audiopolicy/common/managerdefinitions/src/AudioPolicyMix.cpp
+++ b/services/audiopolicy/common/managerdefinitions/src/AudioPolicyMix.cpp
@@ -278,17 +278,6 @@
mixesDisallowsRequestedDevice = true;
}
- if (!primaryOutputMix && (flags & AUDIO_OUTPUT_FLAG_MMAP_NOIRQ)) {
- // AAudio does not support MMAP_NO_IRQ loopback render, and there is no way with
- // the current MmapStreamInterface::start to reject a specific client added to a shared
- // mmap stream.
- // As a result all MMAP_NOIRQ requests have to be rejected when an loopback render
- // policy is present. That ensures no shared mmap stream is used when an loopback
- // render policy is registered.
- ALOGD("%s: Rejecting MMAP_NOIRQ request due to LOOPBACK|RENDER mix present.", __func__);
- return INVALID_OPERATION;
- }
-
if (primaryOutputMix && primaryMix != nullptr) {
ALOGV("%s: Skiping %zu: Primary output already found", __func__, i);
continue; // Primary output already found
@@ -299,6 +288,13 @@
continue; // skip the mix
}
+ if (flags & AUDIO_OUTPUT_FLAG_MMAP_NOIRQ) {
+ // AAudio MMAP_NOIRQ streams cannot be routed using dynamic audio policy.
+ ALOGD("%s: Rejecting MMAP_NOIRQ request matched to dynamic audio policy mix.",
+ __func__);
+ return INVALID_OPERATION;
+ }
+
if (mixDevice != nullptr && mixDevice->equals(requestedDevice)) {
ALOGV("%s: Mix %zu: requested device mathches", __func__, i);
mixesDisallowsRequestedDevice = false;
diff --git a/services/audiopolicy/tests/audiopolicymanager_tests.cpp b/services/audiopolicy/tests/audiopolicymanager_tests.cpp
index 583ec1c..412ab19 100644
--- a/services/audiopolicy/tests/audiopolicymanager_tests.cpp
+++ b/services/audiopolicy/tests/audiopolicymanager_tests.cpp
@@ -82,6 +82,14 @@
return criterion;
}
+// TODO b/182392769: use attribution source util
+AttributionSourceState createAttributionSourceState(uid_t uid) {
+ AttributionSourceState attributionSourceState;
+ attributionSourceState.uid = uid;
+ attributionSourceState.token = sp<BBinder>::make();
+ return attributionSourceState;
+}
+
} // namespace
TEST(AudioPolicyManagerTestInit, EngineFailure) {
@@ -271,10 +279,7 @@
AudioPolicyInterface::output_type_t outputType;
bool isSpatialized;
bool isBitPerfectInternal;
- // TODO b/182392769: use attribution source util
- AttributionSourceState attributionSource = AttributionSourceState();
- attributionSource.uid = uid;
- attributionSource.token = sp<BBinder>::make();
+ AttributionSourceState attributionSource = createAttributionSourceState(uid);
ASSERT_EQ(OK, mManager->getOutputForAttr(
&attr, output, session, &stream, attributionSource, &config, &flags,
selectedDeviceId, portId, {}, &outputType, &isSpatialized,
@@ -302,10 +307,7 @@
if (!portId) portId = &localPortId;
*portId = AUDIO_PORT_HANDLE_NONE;
AudioPolicyInterface::input_type_t inputType;
- // TODO b/182392769: use attribution source util
- AttributionSourceState attributionSource = AttributionSourceState();
- attributionSource.uid = 0;
- attributionSource.token = sp<BBinder>::make();
+ AttributionSourceState attributionSource = createAttributionSourceState(/*uid=*/ 0);
ASSERT_EQ(OK, mManager->getInputForAttr(
&attr, &input, riid, session, attributionSource, &config, flags,
selectedDeviceId, &inputType, portId));
@@ -1859,6 +1861,82 @@
/*expected_match=*/ false)
.withSessionId(TEST_SESSION_ID).withUsage(AUDIO_USAGE_MEDIA)));
+struct DPMmapTestParam {
+ DPMmapTestParam(int mixRouteFlags, audio_devices_t deviceType, const std::string& deviceAddress)
+ : mixRouteFlags(mixRouteFlags), deviceType(deviceType), deviceAddress(deviceAddress) {}
+
+ int mixRouteFlags;
+ audio_devices_t deviceType;
+ std::string deviceAddress;
+};
+
+class AudioPolicyManagerTestMMapPlaybackRerouting
+ : public AudioPolicyManagerTestDynamicPolicy,
+ public ::testing::WithParamInterface<DPMmapTestParam> {
+ protected:
+ void SetUp() override {
+ AudioPolicyManagerTestDynamicPolicy::SetUp();
+ audioConfig = AUDIO_CONFIG_INITIALIZER;
+ audioConfig.channel_mask = AUDIO_CHANNEL_OUT_STEREO;
+ audioConfig.format = AUDIO_FORMAT_PCM_16_BIT;
+ audioConfig.sample_rate = k48000SamplingRate;
+ }
+
+ audio_config_t audioConfig;
+ audio_io_handle_t mOutput;
+ audio_stream_type_t mStream = AUDIO_STREAM_DEFAULT;
+ audio_port_handle_t mSelectedDeviceId = AUDIO_PORT_HANDLE_NONE;
+ audio_port_handle_t mPortId;
+ AudioPolicyInterface::output_type_t mOutputType;
+ audio_attributes_t attr = AUDIO_ATTRIBUTES_INITIALIZER;
+ bool mIsSpatialized;
+ bool mIsBitPerfect;
+};
+
+TEST_P(AudioPolicyManagerTestMMapPlaybackRerouting, MmapPlaybackStreamMatchingDapMixFails) {
+ // Add mix matching the test uid.
+ const int testUid = 12345;
+ const auto param = GetParam();
+ status_t ret = addPolicyMix(MIX_TYPE_PLAYERS, param.mixRouteFlags, param.deviceType,
+ param.deviceAddress, audioConfig, {createUidCriterion(testUid)});
+ ASSERT_EQ(NO_ERROR, ret);
+
+ // Geting output for matching uid and mmap-ed stream should fail.
+ audio_output_flags_t outputFlags = AUDIO_OUTPUT_FLAG_MMAP_NOIRQ;
+ ASSERT_EQ(INVALID_OPERATION,
+ mManager->getOutputForAttr(&attr, &mOutput, AUDIO_SESSION_NONE, &mStream,
+ createAttributionSourceState(testUid), &audioConfig,
+ &outputFlags, &mSelectedDeviceId, &mPortId, {},
+ &mOutputType, &mIsSpatialized, &mIsBitPerfect));
+}
+
+TEST_P(AudioPolicyManagerTestMMapPlaybackRerouting, NonMmapPlaybackStreamMatchingDapMixSucceeds) {
+ // Add mix matching the test uid.
+ const int testUid = 12345;
+ const auto param = GetParam();
+ status_t ret = addPolicyMix(MIX_TYPE_PLAYERS, param.mixRouteFlags, param.deviceType,
+ param.deviceAddress, audioConfig, {createUidCriterion(testUid)});
+ ASSERT_EQ(NO_ERROR, ret);
+
+ // Geting output for matching uid should succeed for non-mmaped stream.
+ audio_output_flags_t outputFlags = AUDIO_OUTPUT_FLAG_NONE;
+ ASSERT_EQ(NO_ERROR,
+ mManager->getOutputForAttr(&attr, &mOutput, AUDIO_SESSION_NONE, &mStream,
+ createAttributionSourceState(testUid), &audioConfig,
+ &outputFlags, &mSelectedDeviceId, &mPortId, {},
+ &mOutputType, &mIsSpatialized, &mIsBitPerfect));
+}
+
+INSTANTIATE_TEST_SUITE_P(
+ MmapPlaybackRerouting, AudioPolicyManagerTestMMapPlaybackRerouting,
+ testing::Values(DPMmapTestParam(MIX_ROUTE_FLAG_LOOP_BACK, AUDIO_DEVICE_OUT_REMOTE_SUBMIX,
+ /*deviceAddress=*/"remote_submix_media"),
+ DPMmapTestParam(MIX_ROUTE_FLAG_LOOP_BACK_AND_RENDER,
+ AUDIO_DEVICE_OUT_REMOTE_SUBMIX,
+ /*deviceAddress=*/"remote_submix_media"),
+ DPMmapTestParam(MIX_ROUTE_FLAG_RENDER, AUDIO_DEVICE_OUT_SPEAKER,
+ /*deviceAddress=*/"")));
+
class AudioPolicyManagerTestDPMixRecordInjection : public AudioPolicyManagerTestDynamicPolicy,
public testing::WithParamInterface<DPTestParam> {
protected:
diff --git a/services/camera/libcameraservice/aidl/AidlCameraDeviceUser.cpp b/services/camera/libcameraservice/aidl/AidlCameraDeviceUser.cpp
index b9f1224..402f8a2 100644
--- a/services/camera/libcameraservice/aidl/AidlCameraDeviceUser.cpp
+++ b/services/camera/libcameraservice/aidl/AidlCameraDeviceUser.cpp
@@ -19,6 +19,7 @@
#include "AidlCameraDeviceUser.h"
#include <aidl/AidlUtils.h>
#include <aidl/android/frameworks/cameraservice/device/CaptureMetadataInfo.h>
+#include <android-base/properties.h>
namespace android::frameworks::cameraservice::device::implementation {
@@ -35,7 +36,7 @@
using ::android::hardware::cameraservice::utils::conversion::aidl::cloneToAidl;
using ::android::hardware::cameraservice::utils::conversion::aidl::convertFromAidl;
using ::android::hardware::cameraservice::utils::conversion::aidl::convertToAidl;
-using ::android::hardware::cameraservice::utils::conversion::aidl::convertToAidl;
+using ::android::hardware::cameraservice::utils::conversion::aidl::filterVndkKeys;
using ::ndk::ScopedAStatus;
namespace {
@@ -55,6 +56,7 @@
AidlCameraDeviceUser::AidlCameraDeviceUser(const sp<UICameraDeviceUser>& deviceRemote):
mDeviceRemote(deviceRemote) {
mInitSuccess = initDevice();
+ mVndkVersion = base::GetIntProperty("ro.vndk.version", __ANDROID_API_FUTURE__);
}
bool AidlCameraDeviceUser::initDevice() {
@@ -171,6 +173,13 @@
ALOGE("%s: Failed to create default request: %s", __FUNCTION__, ret.toString8().string());
return fromUStatus(ret);
}
+
+ if (filterVndkKeys(mVndkVersion, metadata, /*isStatic*/false) != OK) {
+ ALOGE("%s: Unable to filter vndk metadata keys for version %d",
+ __FUNCTION__, mVndkVersion);
+ return fromSStatus(SStatus::UNKNOWN_ERROR);
+ }
+
const camera_metadata_t* rawMetadata = metadata.getAndLock();
cloneToAidl(rawMetadata, _aidl_return);
metadata.unlock(rawMetadata);
diff --git a/services/camera/libcameraservice/aidl/AidlCameraDeviceUser.h b/services/camera/libcameraservice/aidl/AidlCameraDeviceUser.h
index afff197..8014951 100644
--- a/services/camera/libcameraservice/aidl/AidlCameraDeviceUser.h
+++ b/services/camera/libcameraservice/aidl/AidlCameraDeviceUser.h
@@ -109,6 +109,7 @@
std::shared_ptr<CaptureResultMetadataQueue> mCaptureResultMetadataQueue = nullptr;
bool mInitSuccess = false;
int32_t mRequestId = REQUEST_ID_NONE;
+ int mVndkVersion = -1;
};
} // namespace android::frameworks::cameraservice::device::implementation
diff --git a/services/camera/libcameraservice/api2/CameraDeviceClient.cpp b/services/camera/libcameraservice/api2/CameraDeviceClient.cpp
index 216c9be..55b0f03 100644
--- a/services/camera/libcameraservice/api2/CameraDeviceClient.cpp
+++ b/services/camera/libcameraservice/api2/CameraDeviceClient.cpp
@@ -956,7 +956,8 @@
camera3::DepthCompositeStream::isDepthCompositeStream(surfaces[0]);
bool isHeicCompositeStream = camera3::HeicCompositeStream::isHeicCompositeStream(surfaces[0]);
bool isJpegRCompositeStream =
- camera3::JpegRCompositeStream::isJpegRCompositeStream(surfaces[0]);
+ camera3::JpegRCompositeStream::isJpegRCompositeStream(surfaces[0]) &&
+ !mDevice->supportNativeJpegR();
if (isDepthCompositeStream || isHeicCompositeStream || isJpegRCompositeStream) {
sp<CompositeStream> compositeStream;
if (isDepthCompositeStream) {
@@ -1841,7 +1842,8 @@
sp<Surface> s = new Surface(gbp, false /*controlledByApp*/);
isCompositeStream = camera3::DepthCompositeStream::isDepthCompositeStream(s) ||
camera3::HeicCompositeStream::isHeicCompositeStream(s) ||
- camera3::JpegRCompositeStream::isJpegRCompositeStream(s);
+ (camera3::JpegRCompositeStream::isJpegRCompositeStream(s) &&
+ !mDevice->supportNativeJpegR());
if (isCompositeStream) {
auto compositeIdx = mCompositeStreamMap.indexOfKey(IInterface::asBinder(gbp));
if (compositeIdx == NAME_NOT_FOUND) {
diff --git a/services/camera/libcameraservice/common/CameraDeviceBase.h b/services/camera/libcameraservice/common/CameraDeviceBase.h
index 6f15653..fd80cc5 100644
--- a/services/camera/libcameraservice/common/CameraDeviceBase.h
+++ b/services/camera/libcameraservice/common/CameraDeviceBase.h
@@ -113,6 +113,8 @@
*/
virtual const CameraMetadata& infoPhysical(const String8& physicalId) const = 0;
+ virtual bool supportNativeJpegR() const { return false; };
+
struct PhysicalCameraSettings {
std::string cameraId;
CameraMetadata metadata;
diff --git a/services/camera/libcameraservice/common/CameraProviderManager.cpp b/services/camera/libcameraservice/common/CameraProviderManager.cpp
index d2d1e38..f7e02a8 100644
--- a/services/camera/libcameraservice/common/CameraProviderManager.cpp
+++ b/services/camera/libcameraservice/common/CameraProviderManager.cpp
@@ -316,6 +316,18 @@
return deviceInfo->supportNativeZoomRatio();
}
+bool CameraProviderManager::supportNativeJpegR(const std::string &id) const {
+ std::lock_guard<std::mutex> lock(mInterfaceMutex);
+ return supportNativeJpegRLocked(id);
+}
+
+bool CameraProviderManager::supportNativeJpegRLocked(const std::string &id) const {
+ auto deviceInfo = findDeviceInfoLocked(id);
+ if (deviceInfo == nullptr) return false;
+
+ return deviceInfo->supportNativeJpegR();
+}
+
status_t CameraProviderManager::getResourceCost(const std::string &id,
CameraResourceCost* cost) const {
std::lock_guard<std::mutex> lock(mInterfaceMutex);
@@ -1108,7 +1120,7 @@
}
status_t CameraProviderManager::ProviderInfo::DeviceInfo3::deriveJpegRTags(bool maxResolution) {
- if (kFrameworkJpegRDisabled) {
+ if (kFrameworkJpegRDisabled || mSupportsNativeJpegR) {
return OK;
}
diff --git a/services/camera/libcameraservice/common/CameraProviderManager.h b/services/camera/libcameraservice/common/CameraProviderManager.h
index aab6fd5..ce4129c 100644
--- a/services/camera/libcameraservice/common/CameraProviderManager.h
+++ b/services/camera/libcameraservice/common/CameraProviderManager.h
@@ -248,6 +248,11 @@
bool supportNativeZoomRatio(const std::string &id) const;
/**
+ * Return true if the camera device has native Jpeg/R support.
+ */
+ bool supportNativeJpegR(const std::string &id) const;
+
+ /**
* Return the resource cost of this camera device
*/
status_t getResourceCost(const std::string &id,
@@ -568,6 +573,7 @@
bool hasFlashUnit() const { return mHasFlashUnit; }
bool supportNativeZoomRatio() const { return mSupportNativeZoomRatio; }
+ bool supportNativeJpegR() const { return mSupportsNativeJpegR; }
virtual status_t setTorchMode(bool enabled) = 0;
virtual status_t turnOnTorchWithStrengthLevel(int32_t torchStrength) = 0;
virtual status_t getTorchStrengthLevel(int32_t *torchStrength) = 0;
@@ -609,13 +615,14 @@
mParentProvider(parentProvider), mTorchStrengthLevel(0),
mTorchMaximumStrengthLevel(0), mTorchDefaultStrengthLevel(0),
mHasFlashUnit(false), mSupportNativeZoomRatio(false),
- mPublicCameraIds(publicCameraIds) {}
+ mPublicCameraIds(publicCameraIds), mSupportsNativeJpegR(false) {}
virtual ~DeviceInfo() {}
protected:
bool mHasFlashUnit; // const after constructor
bool mSupportNativeZoomRatio; // const after constructor
const std::vector<std::string>& mPublicCameraIds;
+ bool mSupportsNativeJpegR;
};
std::vector<std::unique_ptr<DeviceInfo>> mDevices;
std::unordered_set<std::string> mUniqueCameraIds;
@@ -804,6 +811,8 @@
// No guarantees on the order of traversal
ProviderInfo::DeviceInfo* findDeviceInfoLocked(const std::string& id) const;
+ bool supportNativeJpegRLocked(const std::string &id) const;
+
// Map external providers to USB devices in order to handle USB hotplug
// events for lazy HALs
std::pair<std::vector<std::string>, sp<ProviderInfo>>
diff --git a/services/camera/libcameraservice/common/aidl/AidlProviderInfo.cpp b/services/camera/libcameraservice/common/aidl/AidlProviderInfo.cpp
index 1351703..64098ea 100644
--- a/services/camera/libcameraservice/common/aidl/AidlProviderInfo.cpp
+++ b/services/camera/libcameraservice/common/aidl/AidlProviderInfo.cpp
@@ -483,6 +483,9 @@
}
}
+ mSupportsNativeJpegR = mCameraCharacteristics.exists(
+ ANDROID_JPEGR_AVAILABLE_JPEG_R_STREAM_CONFIGURATIONS);
+
mSystemCameraKind = getSystemCameraKind();
status_t res = fixupMonochromeTags();
@@ -732,8 +735,8 @@
camera::device::StreamConfiguration streamConfiguration;
bool earlyExit = false;
auto bRes = SessionConfigurationUtils::convertToHALStreamCombination(configuration,
- String8(mId.c_str()), mCameraCharacteristics, getMetadata, mPhysicalIds,
- streamConfiguration, overrideForPerfClass, &earlyExit);
+ String8(mId.c_str()), mCameraCharacteristics, mSupportsNativeJpegR, getMetadata,
+ mPhysicalIds, streamConfiguration, overrideForPerfClass, &earlyExit);
if (!bRes.isOk()) {
return UNKNOWN_ERROR;
@@ -798,7 +801,8 @@
bStatus =
SessionConfigurationUtils::convertToHALStreamCombination(
cameraIdAndSessionConfig.mSessionConfiguration,
- String8(cameraId.c_str()), deviceInfo, getMetadata,
+ String8(cameraId.c_str()), deviceInfo,
+ mManager->supportNativeJpegRLocked(cameraId), getMetadata,
physicalCameraIds, streamConfiguration,
overrideForPerfClass, &shouldExit);
if (!bStatus.isOk()) {
diff --git a/services/camera/libcameraservice/device3/Camera3Device.cpp b/services/camera/libcameraservice/device3/Camera3Device.cpp
index 1da0743..836b1bb 100644
--- a/services/camera/libcameraservice/device3/Camera3Device.cpp
+++ b/services/camera/libcameraservice/device3/Camera3Device.cpp
@@ -53,6 +53,7 @@
#include <android/hardware/camera2/ICameraDeviceUser.h>
#include "CameraService.h"
+#include "aidl/android/hardware/graphics/common/Dataspace.h"
#include "aidl/AidlUtils.h"
#include "device3/Camera3Device.h"
#include "device3/Camera3FakeStream.h"
@@ -80,6 +81,7 @@
mLegacyClient(legacyClient),
mOperatingMode(NO_MODE),
mIsConstrainedHighSpeedConfiguration(false),
+ mSupportNativeJpegR(false),
mStatus(STATUS_UNINITIALIZED),
mStatusWaiters(0),
mUsePartialResult(false),
@@ -2465,7 +2467,10 @@
if (outputStream->format == HAL_PIXEL_FORMAT_BLOB) {
size_t k = i + ((mInputStream != nullptr) ? 1 : 0); // Input stream if present should
// always occupy the initial entry.
- if (outputStream->data_space == HAL_DATASPACE_V0_JFIF) {
+ if ((outputStream->data_space == HAL_DATASPACE_V0_JFIF) ||
+ (outputStream->data_space ==
+ static_cast<android_dataspace_t>(
+ aidl::android::hardware::graphics::common::Dataspace::JPEG_R))) {
bufferSizes[k] = static_cast<uint32_t>(
getJpegBufferSize(infoPhysical(String8(outputStream->physical_camera_id)),
outputStream->width, outputStream->height));
diff --git a/services/camera/libcameraservice/device3/Camera3Device.h b/services/camera/libcameraservice/device3/Camera3Device.h
index f3ffed2..e045b98 100644
--- a/services/camera/libcameraservice/device3/Camera3Device.h
+++ b/services/camera/libcameraservice/device3/Camera3Device.h
@@ -119,6 +119,7 @@
status_t dumpWatchedEventsToVector(std::vector<std::string> &out) override;
const CameraMetadata& info() const override;
const CameraMetadata& infoPhysical(const String8& physicalId) const override;
+ bool supportNativeJpegR() const override { return mSupportNativeJpegR; };
// Capture and setStreamingRequest will configure streams if currently in
// idle state
@@ -543,6 +544,7 @@
CameraMetadata mDeviceInfo;
bool mSupportNativeZoomRatio;
+ bool mSupportNativeJpegR;
std::unordered_map<std::string, CameraMetadata> mPhysicalDeviceInfoMap;
CameraMetadata mRequestTemplateCache[CAMERA_TEMPLATE_COUNT];
diff --git a/services/camera/libcameraservice/device3/Camera3OutputStream.cpp b/services/camera/libcameraservice/device3/Camera3OutputStream.cpp
index 58db57a..beef0da 100644
--- a/services/camera/libcameraservice/device3/Camera3OutputStream.cpp
+++ b/services/camera/libcameraservice/device3/Camera3OutputStream.cpp
@@ -24,6 +24,7 @@
#include <aidl/android/hardware/camera/device/CameraBlob.h>
#include <aidl/android/hardware/camera/device/CameraBlobId.h>
+#include "aidl/android/hardware/graphics/common/Dataspace.h"
#include <android-base/unique_fd.h>
#include <cutils/properties.h>
@@ -456,7 +457,10 @@
mTraceFirstBuffer = false;
}
// Fix CameraBlob id type discrepancy between HIDL and AIDL, details : http://b/229688810
- if (getFormat() == HAL_PIXEL_FORMAT_BLOB && getDataSpace() == HAL_DATASPACE_V0_JFIF) {
+ if (getFormat() == HAL_PIXEL_FORMAT_BLOB && (getDataSpace() == HAL_DATASPACE_V0_JFIF ||
+ (getDataSpace() ==
+ static_cast<android_dataspace_t>(
+ aidl::android::hardware::graphics::common::Dataspace::JPEG_R)))) {
if (mIPCTransport == IPCTransport::HIDL) {
fixUpHidlJpegBlobHeader(anwBuffer, anwReleaseFence);
}
diff --git a/services/camera/libcameraservice/device3/Camera3OutputUtils.cpp b/services/camera/libcameraservice/device3/Camera3OutputUtils.cpp
index 738c314..f742a6d 100644
--- a/services/camera/libcameraservice/device3/Camera3OutputUtils.cpp
+++ b/services/camera/libcameraservice/device3/Camera3OutputUtils.cpp
@@ -639,9 +639,24 @@
if (deviceInfo != states.physicalDeviceInfoMap.end()) {
auto orientation = deviceInfo->second.find(ANDROID_SENSOR_ORIENTATION);
if (orientation.count > 0) {
+ int32_t transform;
ret = CameraUtils::getRotationTransform(deviceInfo->second,
- OutputConfiguration::MIRROR_MODE_AUTO, &request.transform);
- if (ret != OK) {
+ OutputConfiguration::MIRROR_MODE_AUTO, &transform);
+ if (ret == OK) {
+ // It is possible for camera providers to return the capture
+ // results after the processed frames. In such scenario, we will
+ // not be able to set the output transformation before the frames
+ // return back to the consumer for the current capture request
+ // but we could still try and configure it for any future requests
+ // that are still in flight. The assumption is that the physical
+ // device id remains the same for the duration of the pending queue.
+ for (size_t i = 0; i < states.inflightMap.size(); i++) {
+ auto &r = states.inflightMap.editValueAt(i);
+ if (r.requestTimeNs >= request.requestTimeNs) {
+ r.transform = transform;
+ }
+ }
+ } else {
ALOGE("%s: Failed to calculate current stream transformation: %s "
"(%d)", __FUNCTION__, strerror(-ret), ret);
}
diff --git a/services/camera/libcameraservice/device3/aidl/AidlCamera3Device.cpp b/services/camera/libcameraservice/device3/aidl/AidlCamera3Device.cpp
index 7924eb5..3b1eba3 100644
--- a/services/camera/libcameraservice/device3/aidl/AidlCamera3Device.cpp
+++ b/services/camera/libcameraservice/device3/aidl/AidlCamera3Device.cpp
@@ -205,6 +205,7 @@
return res;
}
mSupportNativeZoomRatio = manager->supportNativeZoomRatio(mId.string());
+ mSupportNativeJpegR = manager->supportNativeJpegR(mId.string());
std::vector<std::string> physicalCameraIds;
bool isLogical = manager->isLogicalCamera(mId.string(), &physicalCameraIds);
diff --git a/services/camera/libcameraservice/hidl/HidlCameraDeviceUser.cpp b/services/camera/libcameraservice/hidl/HidlCameraDeviceUser.cpp
index 26e813a..0f7f127 100644
--- a/services/camera/libcameraservice/hidl/HidlCameraDeviceUser.cpp
+++ b/services/camera/libcameraservice/hidl/HidlCameraDeviceUser.cpp
@@ -19,10 +19,12 @@
#include <gui/Surface.h>
#include <gui/bufferqueue/1.0/H2BGraphicBufferProducer.h>
+#include <aidl/AidlUtils.h>
#include <hidl/AidlCameraDeviceCallbacks.h>
#include <hidl/HidlCameraDeviceUser.h>
#include <hidl/Utils.h>
#include <android/hardware/camera/device/3.2/types.h>
+#include <android-base/properties.h>
namespace android {
namespace frameworks {
@@ -31,6 +33,7 @@
namespace V2_1 {
namespace implementation {
+using hardware::cameraservice::utils::conversion::aidl::filterVndkKeys;
using hardware::cameraservice::utils::conversion::convertToHidl;
using hardware::cameraservice::utils::conversion::convertFromHidl;
using hardware::cameraservice::utils::conversion::B2HStatus;
@@ -55,6 +58,7 @@
const sp<hardware::camera2::ICameraDeviceUser> &deviceRemote)
: mDeviceRemote(deviceRemote) {
mInitSuccess = initDevice();
+ mVndkVersion = base::GetIntProperty("ro.vndk.version", __ANDROID_API_FUTURE__);
}
bool HidlCameraDeviceUser::initDevice() {
@@ -235,8 +239,16 @@
android::CameraMetadata cameraMetadata;
binder::Status ret = mDeviceRemote->createDefaultRequest(convertFromHidl(templateId),
&cameraMetadata);
- HStatus hStatus = B2HStatus(ret);
+
HCameraMetadata hidlMetadata;
+ if (filterVndkKeys(mVndkVersion, cameraMetadata, /*isStatic*/false) != OK) {
+ ALOGE("%s: Unable to filter vndk metadata keys for version %d",
+ __FUNCTION__, mVndkVersion);
+ _hidl_cb(HStatus::UNKNOWN_ERROR, hidlMetadata);
+ return Void();
+ }
+
+ HStatus hStatus = B2HStatus(ret);
const camera_metadata_t *rawMetadata = cameraMetadata.getAndLock();
convertToHidl(rawMetadata, &hidlMetadata);
_hidl_cb(hStatus, hidlMetadata);
diff --git a/services/camera/libcameraservice/hidl/HidlCameraDeviceUser.h b/services/camera/libcameraservice/hidl/HidlCameraDeviceUser.h
index 0e2ab3d..a653ca2 100644
--- a/services/camera/libcameraservice/hidl/HidlCameraDeviceUser.h
+++ b/services/camera/libcameraservice/hidl/HidlCameraDeviceUser.h
@@ -127,6 +127,7 @@
std::shared_ptr<CaptureResultMetadataQueue> mCaptureResultMetadataQueue = nullptr;
bool mInitSuccess = false;
int32_t mRequestId = REQUEST_ID_NONE;
+ int mVndkVersion = -1;
};
} // implementation
diff --git a/services/camera/libcameraservice/utils/SessionConfigurationUtils.cpp b/services/camera/libcameraservice/utils/SessionConfigurationUtils.cpp
index a00b0be..c1a4fa0 100644
--- a/services/camera/libcameraservice/utils/SessionConfigurationUtils.cpp
+++ b/services/camera/libcameraservice/utils/SessionConfigurationUtils.cpp
@@ -380,6 +380,23 @@
}
}
+bool dataSpaceFromColorSpace(android_dataspace *dataSpace, int32_t colorSpace) {
+ switch (colorSpace) {
+ case ANDROID_REQUEST_AVAILABLE_COLOR_SPACE_PROFILES_MAP_SRGB:
+ *dataSpace = HAL_DATASPACE_V0_SRGB;
+ return true;
+ case ANDROID_REQUEST_AVAILABLE_COLOR_SPACE_PROFILES_MAP_DISPLAY_P3:
+ *dataSpace = HAL_DATASPACE_DISPLAY_P3;
+ return true;
+ case ANDROID_REQUEST_AVAILABLE_COLOR_SPACE_PROFILES_MAP_BT2020_HLG:
+ *(reinterpret_cast<int32_t*>(dataSpace)) = HAL_DATASPACE_BT2020_HLG;
+ return true;
+ default:
+ ALOGE("%s: Unsupported color space %d", __FUNCTION__, colorSpace);
+ return false;
+ }
+}
+
bool isStreamUseCaseSupported(int64_t streamUseCase,
const CameraMetadata &deviceInfo) {
camera_metadata_ro_entry_t availableStreamUseCases =
@@ -472,6 +489,16 @@
return STATUS_ERROR(CameraService::ERROR_INVALID_OPERATION, msg.string());
}
+ if (colorSpace != ANDROID_REQUEST_AVAILABLE_COLOR_SPACE_PROFILES_MAP_UNSPECIFIED &&
+ format != HAL_PIXEL_FORMAT_BLOB) {
+ if (!dataSpaceFromColorSpace(&dataSpace, colorSpace)) {
+ String8 msg = String8::format("Camera %s: color space %d not supported, failed to "
+ "convert to data space", logicalCameraId.string(), colorSpace);
+ ALOGE("%s: %s", __FUNCTION__, msg.string());
+ return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT, msg.string());
+ }
+ }
+
// FIXME: remove this override since the default format should be
// IMPLEMENTATION_DEFINED. b/9487482 & b/35317944
if ((format >= HAL_PIXEL_FORMAT_RGBA_8888 && format <= HAL_PIXEL_FORMAT_BGRA_8888) &&
@@ -645,7 +672,7 @@
binder::Status
convertToHALStreamCombination(
const SessionConfiguration& sessionConfiguration,
- const String8 &logicalCameraId, const CameraMetadata &deviceInfo,
+ const String8 &logicalCameraId, const CameraMetadata &deviceInfo, bool supportNativeJpegR,
metadataGetter getMetadata, const std::vector<std::string> &physicalCameraIds,
aidl::android::hardware::camera::device::StreamConfiguration &streamConfiguration,
bool overrideForPerfClass, bool *earlyExit) {
@@ -789,7 +816,8 @@
bool isHeicCompositeStream =
camera3::HeicCompositeStream::isHeicCompositeStream(surface);
bool isJpegRCompositeStream =
- camera3::JpegRCompositeStream::isJpegRCompositeStream(surface);
+ camera3::JpegRCompositeStream::isJpegRCompositeStream(surface) &&
+ !supportNativeJpegR;
if (isDepthCompositeStream || isHeicCompositeStream || isJpegRCompositeStream) {
// We need to take in to account that composite streams can have
// additional internal camera streams.
diff --git a/services/camera/libcameraservice/utils/SessionConfigurationUtils.h b/services/camera/libcameraservice/utils/SessionConfigurationUtils.h
index 2e35de0..d27144e 100644
--- a/services/camera/libcameraservice/utils/SessionConfigurationUtils.h
+++ b/services/camera/libcameraservice/utils/SessionConfigurationUtils.h
@@ -115,6 +115,8 @@
bool isColorSpaceSupported(int32_t colorSpace, int32_t format, android_dataspace dataSpace,
int64_t dynamicRangeProfile, const CameraMetadata& staticMeta);
+bool dataSpaceFromColorSpace(android_dataspace *dataSpace, int32_t colorSpace);
+
bool isStreamUseCaseSupported(int64_t streamUseCase, const CameraMetadata &deviceInfo);
void mapStreamInfo(const OutputStreamInfo &streamInfo,
@@ -136,7 +138,7 @@
binder::Status
convertToHALStreamCombination(
const SessionConfiguration& sessionConfiguration,
- const String8 &logicalCameraId, const CameraMetadata &deviceInfo,
+ const String8 &logicalCameraId, const CameraMetadata &deviceInfo, bool supportNativeJpegR,
metadataGetter getMetadata, const std::vector<std::string> &physicalCameraIds,
aidl::android::hardware::camera::device::StreamConfiguration &streamConfiguration,
bool overrideForPerfClass, bool *earlyExit);
diff --git a/services/camera/libcameraservice/utils/SessionConfigurationUtilsHidl.cpp b/services/camera/libcameraservice/utils/SessionConfigurationUtilsHidl.cpp
index 5444f2a..d960024 100644
--- a/services/camera/libcameraservice/utils/SessionConfigurationUtilsHidl.cpp
+++ b/services/camera/libcameraservice/utils/SessionConfigurationUtilsHidl.cpp
@@ -111,8 +111,8 @@
bool overrideForPerfClass, bool *earlyExit) {
aidl::android::hardware::camera::device::StreamConfiguration aidlStreamConfiguration;
auto ret = convertToHALStreamCombination(sessionConfiguration, logicalCameraId, deviceInfo,
- getMetadata, physicalCameraIds, aidlStreamConfiguration, overrideForPerfClass,
- earlyExit);
+ false /*supportNativeJpegR*/, getMetadata, physicalCameraIds, aidlStreamConfiguration,
+ overrideForPerfClass, earlyExit);
if (!ret.isOk()) {
return ret;
}