Merge "APM: fix log spam from getDevicesForStrategyInt when booting devices." into udc-dev
diff --git a/media/libstagefright/Android.bp b/media/libstagefright/Android.bp
index ddc0f2f..569a25f 100644
--- a/media/libstagefright/Android.bp
+++ b/media/libstagefright/Android.bp
@@ -238,6 +238,7 @@
"CallbackMediaSource.cpp",
"CameraSource.cpp",
"CameraSourceTimeLapse.cpp",
+ "CodecErrorLog.cpp",
"CryptoAsync.cpp",
"FrameDecoder.cpp",
"HevcUtils.cpp",
diff --git a/media/libstagefright/CodecErrorLog.cpp b/media/libstagefright/CodecErrorLog.cpp
new file mode 100644
index 0000000..9785623
--- /dev/null
+++ b/media/libstagefright/CodecErrorLog.cpp
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+//#define LOG_NDEBUG 0
+#define LOG_TAG "CodecErrorLog"
+
+#include <log/log.h>
+#include <media/stagefright/CodecErrorLog.h>
+
+namespace android {
+
+void CodecErrorLog::log(const char *tag, const char *message) {
+ std::unique_lock lock(mLock);
+ ALOG(LOG_ERROR, tag, "%s", message);
+ mStream << message << std::endl;
+}
+
+void CodecErrorLog::log(const char *tag, const std::string &message) {
+ log(tag, message.c_str());
+}
+
+std::string CodecErrorLog::extract() {
+ std::unique_lock lock(mLock);
+ std::string msg = mStream.str();
+ mStream.str("");
+ return msg;
+}
+
+void CodecErrorLog::clear() {
+ std::unique_lock lock(mLock);
+ mStream.str("");
+}
+
+} // namespace android
diff --git a/media/libstagefright/MediaCodec.cpp b/media/libstagefright/MediaCodec.cpp
index 38df5d0..c9287e5 100644
--- a/media/libstagefright/MediaCodec.cpp
+++ b/media/libstagefright/MediaCodec.cpp
@@ -42,6 +42,7 @@
#include <android/binder_ibinder.h>
#include <android/binder_manager.h>
#include <android/dlext.h>
+#include <android-base/stringprintf.h>
#include <binder/IMemory.h>
#include <binder/IServiceManager.h>
#include <binder/MemoryDealer.h>
@@ -959,10 +960,12 @@
};
}
if (!mGetCodecInfo) {
- mGetCodecInfo = [](const AString &name, sp<MediaCodecInfo> *info) -> status_t {
+ mGetCodecInfo = [&log = mErrorLog](const AString &name,
+ sp<MediaCodecInfo> *info) -> status_t {
*info = nullptr;
const sp<IMediaCodecList> mcl = MediaCodecList::getInstance();
if (!mcl) {
+ log.log(LOG_TAG, "Fatal error: failed to initialize MediaCodecList");
return NO_INIT; // if called from Java should raise IOException
}
AString tmp = name;
@@ -977,6 +980,8 @@
*info = mcl->getCodecInfo(codecIdx);
return OK;
}
+ log.log(LOG_TAG, base::StringPrintf("Codec with name '%s' is not found on the device.",
+ name.c_str()));
return NAME_NOT_FOUND;
};
}
@@ -1032,6 +1037,7 @@
void MediaCodec::updateMediametrics() {
if (mMetricsHandle == 0) {
+ ALOGW("no metrics handle found");
return;
}
@@ -1727,6 +1733,8 @@
status_t MediaCodec::init(const AString &name) {
status_t err = mResourceManagerProxy->init();
if (err != OK) {
+ mErrorLog.log(LOG_TAG, base::StringPrintf(
+ "Fatal error: failed to initialize ResourceManager (err=%d)", err));
mCodec = NULL; // remove the codec
return err;
}
@@ -1746,11 +1754,14 @@
if (!name.startsWith("android.filter.")) {
err = mGetCodecInfo(name, &mCodecInfo);
if (err != OK) {
+ mErrorLog.log(LOG_TAG, base::StringPrintf(
+ "Getting codec info with name '%s' failed (err=%d)", name.c_str(), err));
mCodec = NULL; // remove the codec.
return err;
}
if (mCodecInfo == nullptr) {
- ALOGE("Getting codec info with name '%s' failed", name.c_str());
+ mErrorLog.log(LOG_TAG, base::StringPrintf(
+ "Getting codec info with name '%s' failed", name.c_str()));
return NAME_NOT_FOUND;
}
secureCodec = name.endsWith(".secure");
@@ -1773,7 +1784,8 @@
mCodec = mGetCodecBase(name, owner);
if (mCodec == NULL) {
- ALOGE("Getting codec base with name '%s' (owner='%s') failed", name.c_str(), owner);
+ mErrorLog.log(LOG_TAG, base::StringPrintf(
+ "Getting codec base with name '%s' (from '%s' HAL) failed", name.c_str(), owner));
return NAME_NOT_FOUND;
}
@@ -1785,7 +1797,7 @@
mCodecLooper->setName("CodecLooper");
err = mCodecLooper->start(false, false, ANDROID_PRIORITY_AUDIO);
if (OK != err) {
- ALOGE("Codec Looper failed to start");
+ mErrorLog.log(LOG_TAG, "Fatal error: codec looper failed to start");
return err;
}
}
@@ -1968,7 +1980,8 @@
// Prevent possible integer overflow in downstream code.
if (mWidth < 0 || mHeight < 0 ||
(uint64_t)mWidth * mHeight > (uint64_t)INT32_MAX / 4) {
- ALOGE("Invalid size(s), width=%d, height=%d", mWidth, mHeight);
+ mErrorLog.log(LOG_TAG, base::StringPrintf(
+ "Invalid size(s), width=%d, height=%d", mWidth, mHeight));
mediametrics_delete(nextMetricsHandle);
return BAD_VALUE;
}
@@ -3139,17 +3152,17 @@
sp<MediaCodecBuffer> *buffer, sp<AMessage> *format) {
// use mutex instead of a context switch
if (mReleasedByResourceManager) {
- ALOGE("getBufferAndFormat - resource already released");
+ mErrorLog.log(LOG_TAG, "resource already released");
return DEAD_OBJECT;
}
if (buffer == NULL) {
- ALOGE("getBufferAndFormat - null MediaCodecBuffer");
+ mErrorLog.log(LOG_TAG, "null buffer");
return INVALID_OPERATION;
}
if (format == NULL) {
- ALOGE("getBufferAndFormat - null AMessage");
+ mErrorLog.log(LOG_TAG, "null format");
return INVALID_OPERATION;
}
@@ -3157,7 +3170,9 @@
format->clear();
if (!isExecuting()) {
- ALOGE("getBufferAndFormat - not executing");
+ mErrorLog.log(LOG_TAG, base::StringPrintf(
+ "Invalid to call %s; only valid in Executing states",
+ apiStateString().c_str()));
return INVALID_OPERATION;
}
@@ -3169,6 +3184,7 @@
if (index >= buffers.size()) {
ALOGE("getBufferAndFormat - trying to get buffer with "
"bad index (index=%zu buffer_size=%zu)", index, buffers.size());
+ mErrorLog.log(LOG_TAG, base::StringPrintf("Bad index (index=%zu)", index));
return INVALID_OPERATION;
}
@@ -3176,6 +3192,7 @@
if (!info.mOwnedByClient) {
ALOGE("getBufferAndFormat - invalid operation "
"(the index %zu is not owned by client)", index);
+ mErrorLog.log(LOG_TAG, base::StringPrintf("index %zu is not owned by client", index));
return INVALID_OPERATION;
}
@@ -3303,6 +3320,7 @@
void MediaCodec::cancelPendingDequeueOperations() {
if (mFlags & kFlagDequeueInputPending) {
+ mErrorLog.log(LOG_TAG, "Pending dequeue input buffer request cancelled");
PostReplyWithError(mDequeueInputReplyID, INVALID_OPERATION);
++mDequeueInputTimeoutGeneration;
@@ -3311,6 +3329,7 @@
}
if (mFlags & kFlagDequeueOutputPending) {
+ mErrorLog.log(LOG_TAG, "Pending dequeue output buffer request cancelled");
PostReplyWithError(mDequeueOutputReplyID, INVALID_OPERATION);
++mDequeueOutputTimeoutGeneration;
@@ -3320,8 +3339,16 @@
}
bool MediaCodec::handleDequeueInputBuffer(const sp<AReplyToken> &replyID, bool newRequest) {
- if (!isExecuting() || (mFlags & kFlagIsAsync)
- || (newRequest && (mFlags & kFlagDequeueInputPending))) {
+ if (!isExecuting()) {
+ mErrorLog.log(LOG_TAG, base::StringPrintf(
+ "Invalid to call %s; only valid in executing state",
+ apiStateString().c_str()));
+ PostReplyWithError(replyID, INVALID_OPERATION);
+ } else if (mFlags & kFlagIsAsync) {
+ mErrorLog.log(LOG_TAG, "Invalid to call in async mode");
+ PostReplyWithError(replyID, INVALID_OPERATION);
+ } else if (newRequest && (mFlags & kFlagDequeueInputPending)) {
+ mErrorLog.log(LOG_TAG, "Invalid to call while another dequeue input request is pending");
PostReplyWithError(replyID, INVALID_OPERATION);
return true;
} else if (mFlags & kFlagStickyError) {
@@ -3345,8 +3372,16 @@
MediaCodec::DequeueOutputResult MediaCodec::handleDequeueOutputBuffer(
const sp<AReplyToken> &replyID, bool newRequest) {
- if (!isExecuting() || (mFlags & kFlagIsAsync)
- || (newRequest && (mFlags & kFlagDequeueOutputPending))) {
+ if (!isExecuting()) {
+ mErrorLog.log(LOG_TAG, base::StringPrintf(
+ "Invalid to call %s; only valid in executing state",
+ apiStateString().c_str()));
+ PostReplyWithError(replyID, INVALID_OPERATION);
+ } else if (mFlags & kFlagIsAsync) {
+ mErrorLog.log(LOG_TAG, "Invalid to call in async mode");
+ PostReplyWithError(replyID, INVALID_OPERATION);
+ } else if (newRequest && (mFlags & kFlagDequeueOutputPending)) {
+ mErrorLog.log(LOG_TAG, "Invalid to call while another dequeue output request is pending");
PostReplyWithError(replyID, INVALID_OPERATION);
} else if (mFlags & kFlagStickyError) {
PostReplyWithError(replyID, getStickyError());
@@ -4189,6 +4224,9 @@
// callback can't be set after codec is executing,
// or before it's initialized (as the callback
// will be cleared when it goes to INITIALIZED)
+ mErrorLog.log(LOG_TAG, base::StringPrintf(
+ "Invalid to call %s; only valid at Initialized state",
+ apiStateString().c_str()));
PostReplyWithError(replyID, INVALID_OPERATION);
break;
}
@@ -4220,6 +4258,9 @@
case kWhatConfigure:
{
if (mState != INITIALIZED) {
+ mErrorLog.log(LOG_TAG, base::StringPrintf(
+ "configure() is valid only at Initialized state; currently %s",
+ apiStateString().c_str()));
PostReplyWithError(msg, INVALID_OPERATION);
break;
}
@@ -4282,7 +4323,8 @@
if (flags & CONFIGURE_FLAG_USE_BLOCK_MODEL ||
flags & CONFIGURE_FLAG_USE_CRYPTO_ASYNC) {
if (!(mFlags & kFlagIsAsync)) {
- ALOGE("Error: configuration requires async operation");
+ mErrorLog.log(
+ LOG_TAG, "Block model is only valid with callback set (async mode)");
PostReplyWithError(replyID, INVALID_OPERATION);
break;
}
@@ -4385,9 +4427,13 @@
sp<Surface> surface = static_cast<Surface *>(obj.get());
if (mSurface == NULL) {
// do not support setting surface if it was not set
+ mErrorLog.log(LOG_TAG,
+ "Cannot set surface if the codec is not configured with "
+ "a surface already");
err = INVALID_OPERATION;
} else if (obj == NULL) {
// do not support unsetting surface
+ mErrorLog.log(LOG_TAG, "Unsetting surface is not supported");
err = BAD_VALUE;
} else {
err = connectToSurface(surface);
@@ -4418,6 +4464,9 @@
}
default:
+ mErrorLog.log(LOG_TAG, base::StringPrintf(
+ "setSurface() is valid only at Executing states; currently %s",
+ apiStateString().c_str()));
err = INVALID_OPERATION;
break;
}
@@ -4431,6 +4480,9 @@
{
// Must be configured, but can't have been started yet.
if (mState != CONFIGURED) {
+ mErrorLog.log(LOG_TAG, base::StringPrintf(
+ "setInputSurface() is valid only at Configured state; currently %s",
+ apiStateString().c_str()));
PostReplyWithError(msg, INVALID_OPERATION);
break;
}
@@ -4466,6 +4518,9 @@
PostReplyWithError(msg, OK);
break;
} else if (mState != CONFIGURED) {
+ mErrorLog.log(LOG_TAG, base::StringPrintf(
+ "start() is valid only at Configured state; currently %s",
+ apiStateString().c_str()));
PostReplyWithError(msg, INVALID_OPERATION);
break;
}
@@ -4545,6 +4600,7 @@
if (mFlags & kFlagIsAsync) {
onError(DEAD_OBJECT, ACTION_CODE_FATAL);
}
+ mErrorLog.log(LOG_TAG, "Released by resource manager");
mReleasedByResourceManager = true;
}
@@ -4581,6 +4637,7 @@
// the previous stop/release completes and then reply with OK.
status_t err = mState == targetState ? OK : INVALID_OPERATION;
response->setInt32("err", err);
+ // TODO: mErrorLog
if (err == OK && targetState == UNINITIALIZED) {
mComponentName.clear();
}
@@ -4689,13 +4746,13 @@
CHECK(msg->senderAwaitsResponse(&replyID));
if (mFlags & kFlagIsAsync) {
- ALOGE("dequeueInputBuffer can't be used in async mode");
+ mErrorLog.log(LOG_TAG, "dequeueInputBuffer can't be used in async mode");
PostReplyWithError(replyID, INVALID_OPERATION);
break;
}
if (mHaveInputSurface) {
- ALOGE("dequeueInputBuffer can't be used with input surface");
+ mErrorLog.log(LOG_TAG, "dequeueInputBuffer can't be used with input surface");
PostReplyWithError(replyID, INVALID_OPERATION);
break;
}
@@ -4750,6 +4807,9 @@
CHECK(msg->senderAwaitsResponse(&replyID));
if (!isExecuting()) {
+ mErrorLog.log(LOG_TAG, base::StringPrintf(
+ "queueInputBuffer() is valid only at Executing states; currently %s",
+ apiStateString().c_str()));
PostReplyWithError(replyID, INVALID_OPERATION);
break;
} else if (mFlags & kFlagStickyError) {
@@ -4777,7 +4837,7 @@
CHECK(msg->senderAwaitsResponse(&replyID));
if (mFlags & kFlagIsAsync) {
- ALOGE("dequeueOutputBuffer can't be used in async mode");
+ mErrorLog.log(LOG_TAG, "dequeueOutputBuffer can't be used in async mode");
PostReplyWithError(replyID, INVALID_OPERATION);
break;
}
@@ -4844,6 +4904,9 @@
CHECK(msg->senderAwaitsResponse(&replyID));
if (!isExecuting()) {
+ mErrorLog.log(LOG_TAG, base::StringPrintf(
+ "releaseOutputBuffer() is valid only at Executing states; currently %s",
+ apiStateString().c_str()));
PostReplyWithError(replyID, INVALID_OPERATION);
break;
} else if (mFlags & kFlagStickyError) {
@@ -4867,7 +4930,15 @@
case kWhatSignalEndOfInputStream:
{
- if (!isExecuting() || !mHaveInputSurface) {
+ if (!isExecuting()) {
+ mErrorLog.log(LOG_TAG, base::StringPrintf(
+ "signalEndOfInputStream() is valid only at Executing states; currently %s",
+ apiStateString().c_str()));
+ PostReplyWithError(msg, INVALID_OPERATION);
+ break;
+ } else if (!mHaveInputSurface) {
+ mErrorLog.log(
+ LOG_TAG, "signalEndOfInputStream() called without an input surface set");
PostReplyWithError(msg, INVALID_OPERATION);
break;
} else if (mFlags & kFlagStickyError) {
@@ -4891,7 +4962,14 @@
{
sp<AReplyToken> replyID;
CHECK(msg->senderAwaitsResponse(&replyID));
- if (!isExecuting() || (mFlags & kFlagIsAsync)) {
+ if (!isExecuting()) {
+ mErrorLog.log(LOG_TAG, base::StringPrintf(
+ "getInput/OutputBuffers() is valid only at Executing states; currently %s",
+ apiStateString().c_str()));
+ PostReplyWithError(replyID, INVALID_OPERATION);
+ break;
+ } else if (mFlags & kFlagIsAsync) {
+ mErrorLog.log(LOG_TAG, "getInput/OutputBuffers() is not supported with callbacks");
PostReplyWithError(replyID, INVALID_OPERATION);
break;
} else if (mFlags & kFlagStickyError) {
@@ -4924,6 +5002,9 @@
case kWhatFlush:
{
if (!isExecuting()) {
+ mErrorLog.log(LOG_TAG, base::StringPrintf(
+ "flush() is valid only at Executing states; currently %s",
+ apiStateString().c_str()));
PostReplyWithError(msg, INVALID_OPERATION);
break;
} else if (mFlags & kFlagStickyError) {
@@ -4967,10 +5048,17 @@
sp<AReplyToken> replyID;
CHECK(msg->senderAwaitsResponse(&replyID));
- if ((mState != CONFIGURED && mState != STARTING &&
- mState != STARTED && mState != FLUSHING &&
- mState != FLUSHED)
- || format == NULL) {
+ if (mState != CONFIGURED && mState != STARTING &&
+ mState != STARTED && mState != FLUSHING &&
+ mState != FLUSHED) {
+ mErrorLog.log(LOG_TAG, base::StringPrintf(
+ "getInput/OutputFormat() is valid at Executing states "
+ "and Configured state; currently %s",
+ apiStateString().c_str()));
+ PostReplyWithError(replyID, INVALID_OPERATION);
+ break;
+ } else if (format == NULL) {
+ mErrorLog.log(LOG_TAG, "Fatal error: format is not initialized");
PostReplyWithError(replyID, INVALID_OPERATION);
break;
} else if (mFlags & kFlagStickyError) {
@@ -5005,6 +5093,7 @@
CHECK(msg->senderAwaitsResponse(&replyID));
if (mComponentName.empty()) {
+ mErrorLog.log(LOG_TAG, "Fatal error: name is not set");
PostReplyWithError(replyID, INVALID_OPERATION);
break;
}
@@ -5172,7 +5261,7 @@
size_t i = 0;
for (;;) {
sp<ABuffer> csd;
- if (!format->findBuffer(AStringPrintf("csd-%u", i).c_str(), &csd)) {
+ if (!format->findBuffer(base::StringPrintf("csd-%zu", i).c_str(), &csd)) {
break;
}
if (csd->size() == 0) {
@@ -5207,7 +5296,7 @@
}
sDealer = new MemoryDealer(
newDealerCapacity,
- AStringPrintf("CSD(%dMB)", newDealerCapacity / 1048576).c_str());
+ base::StringPrintf("CSD(%zuMB)", newDealerCapacity / 1048576).c_str());
mem = sDealer->allocate(csd->size());
}
memcpy(mem->unsecurePointer(), csd->data(), csd->size());
@@ -5218,9 +5307,14 @@
FetchLinearBlock(csd->size(), {std::string{mComponentName.c_str()}});
C2WriteView view{block->map().get()};
if (view.error() != C2_OK) {
+ mErrorLog.log(LOG_TAG, "Fatal error: failed to allocate and map a block");
return -EINVAL;
}
if (csd->size() > view.capacity()) {
+ mErrorLog.log(LOG_TAG, base::StringPrintf(
+ "Fatal error: allocated block is too small "
+ "(csd size %zu; block cap %u)",
+ csd->size(), view.capacity()));
return -EINVAL;
}
memcpy(view.base(), csd->data(), csd->size());
@@ -5231,10 +5325,16 @@
const sp<MediaCodecBuffer> &codecInputData = info.mData;
if (csd->size() > codecInputData->capacity()) {
+ mErrorLog.log(LOG_TAG, base::StringPrintf(
+ "CSD is too large to fit in input buffer "
+ "(csd size %zu; buffer cap %zu)",
+ csd->size(), codecInputData->capacity()));
return -EINVAL;
}
if (codecInputData->data() == NULL) {
ALOGV("Input buffer %zu is not properly allocated", bufferIndex);
+ mErrorLog.log(LOG_TAG, base::StringPrintf(
+ "Fatal error: input buffer %zu is not properly allocated", bufferIndex));
return -EINVAL;
}
@@ -5287,6 +5387,7 @@
mActivityNotify.clear();
mCallback.clear();
+ mErrorLog.clear();
}
if (newState == UNINITIALIZED) {
@@ -5407,6 +5508,7 @@
if (!hasCryptoOrDescrambler()) {
ALOGE("[%s] queuing secure buffer without mCrypto or mDescrambler!",
mComponentName.c_str());
+ mErrorLog.log(LOG_TAG, "queuing secure buffer without mCrypto or mDescrambler!");
return -EINVAL;
}
CHECK(msg->findPointer("subSamples", (void **)&subSamples));
@@ -5429,12 +5531,21 @@
}
if (index >= mPortBuffers[kPortIndexInput].size()) {
+ mErrorLog.log(LOG_TAG, base::StringPrintf(
+ "index out of range (index=%zu)", mPortBuffers[kPortIndexInput].size()));
return -ERANGE;
}
BufferInfo *info = &mPortBuffers[kPortIndexInput][index];
sp<MediaCodecBuffer> buffer = info->mData;
- if (buffer == nullptr || !info->mOwnedByClient) {
+ if (buffer == nullptr) {
+ mErrorLog.log(LOG_TAG, base::StringPrintf(
+ "Fatal error: failed to fetch buffer for index %zu", index));
+ return -EACCES;
+ }
+ if (!info->mOwnedByClient) {
+ mErrorLog.log(LOG_TAG, base::StringPrintf(
+ "client does not own the buffer #%zu", index));
return -EACCES;
}
auto setInputBufferParams = [this, &buffer]
@@ -5534,6 +5645,7 @@
err = INVALID_OPERATION;
}
} else {
+ mErrorLog.log(LOG_TAG, "Fatal error: invalid queue request without a buffer");
err = UNKNOWN_ERROR;
}
if (err == OK && !buffer->asC2Buffer()
@@ -5554,12 +5666,17 @@
offset = buffer->offset();
size = buffer->size();
if (err != OK) {
- ALOGI("block model buffer attach failed: err = %s (%d)",
- StrMediaError(err).c_str(), err);
+ ALOGE("block model buffer attach failed: err = %s (%d)",
+ StrMediaError(err).c_str(), err);
return err;
}
}
+
if (offset + size > buffer->capacity()) {
+ mErrorLog.log(LOG_TAG, base::StringPrintf(
+ "buffer offset and size goes beyond the capacity: "
+ "offset=%zu, size=%zu, cap=%zu",
+ offset, size, buffer->capacity()));
return -EINVAL;
}
buffer->setRange(offset, size);
@@ -5643,8 +5760,8 @@
if (it->getRenderTimeNs() < 0) {
continue; // dropped frame from tracking
}
- msg->setInt64(AStringPrintf("%zu-media-time-us", index).c_str(), it->getMediaTimeUs());
- msg->setInt64(AStringPrintf("%zu-system-nano", index).c_str(), it->getRenderTimeNs());
+ msg->setInt64(base::StringPrintf("%zu-media-time-us", index).c_str(), it->getMediaTimeUs());
+ msg->setInt64(base::StringPrintf("%zu-system-nano", index).c_str(), it->getRenderTimeNs());
++index;
}
return index;
@@ -5660,16 +5777,28 @@
}
if (!isExecuting()) {
+ mErrorLog.log(LOG_TAG, base::StringPrintf(
+ "releaseOutputBuffer() is valid at Executing states; currently %s",
+ apiStateString().c_str()));
return -EINVAL;
}
if (index >= mPortBuffers[kPortIndexOutput].size()) {
+ mErrorLog.log(LOG_TAG, base::StringPrintf(
+ "index out of range (index=%zu)", mPortBuffers[kPortIndexOutput].size()));
return -ERANGE;
}
BufferInfo *info = &mPortBuffers[kPortIndexOutput][index];
- if (info->mData == nullptr || !info->mOwnedByClient) {
+ if (!info->mOwnedByClient) {
+ mErrorLog.log(LOG_TAG, base::StringPrintf(
+ "client does not own the buffer #%zu", index));
+ return -EACCES;
+ }
+ if (info->mData == nullptr) {
+ mErrorLog.log(LOG_TAG, base::StringPrintf(
+ "Fatal error: null buffer for index %zu", index));
return -EACCES;
}
@@ -5736,7 +5865,7 @@
status_t err = mBufferChannel->renderOutputBuffer(buffer, renderTimeNs);
if (err == NO_INIT) {
- ALOGE("rendering to non-initilized(obsolete) surface");
+ mErrorLog.log(LOG_TAG, "rendering to non-initialized(obsolete) surface");
return err;
}
if (err != OK) {
@@ -6019,12 +6148,14 @@
memcpy(csd->data() + 4, nalStart, nalSize);
mOutputFormat->setBuffer(
- AStringPrintf("csd-%u", csdIndex).c_str(), csd);
+ base::StringPrintf("csd-%u", csdIndex).c_str(), csd);
++csdIndex;
}
if (csdIndex != 2) {
+ mErrorLog.log(LOG_TAG, base::StringPrintf(
+ "codec config data contains %u NAL units; expected 2.", csdIndex));
return ERROR_MALFORMED;
}
} else {
@@ -6066,6 +6197,32 @@
mDeferredMessages.clear();
}
+std::string MediaCodec::apiStateString() {
+ const char *rval = NULL;
+ char rawbuffer[16]; // room for "%d"
+
+ switch (mState) {
+ case UNINITIALIZED:
+ rval = (mFlags & kFlagStickyError) ? "at Error state" : "at Released state";
+ break;
+ case INITIALIZING: rval = "while constructing"; break;
+ case INITIALIZED: rval = "at Uninitialized state"; break;
+ case CONFIGURING: rval = "during configure()"; break;
+ case CONFIGURED: rval = "at Configured state"; break;
+ case STARTING: rval = "during start()"; break;
+ case STARTED: rval = "at Running state"; break;
+ case FLUSHING: rval = "during flush()"; break;
+ case FLUSHED: rval = "at Flushed state"; break;
+ case STOPPING: rval = "during stop()"; break;
+ case RELEASING: rval = "during release()"; break;
+ default:
+ snprintf(rawbuffer, sizeof(rawbuffer), "at %d", mState);
+ rval = rawbuffer;
+ break;
+ }
+ return rval;
+}
+
std::string MediaCodec::stateString(State state) {
const char *rval = NULL;
char rawbuffer[16]; // room for "%d"
diff --git a/media/libstagefright/include/media/stagefright/CodecErrorLog.h b/media/libstagefright/include/media/stagefright/CodecErrorLog.h
new file mode 100644
index 0000000..673117a
--- /dev/null
+++ b/media/libstagefright/include/media/stagefright/CodecErrorLog.h
@@ -0,0 +1,64 @@
+/*
+ * Copyright 2023, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef CODEC_ERROR_LOG_H_
+
+#define CODEC_ERROR_LOG_H_
+
+#include <sstream>
+#include <string>
+
+#include <android-base/thread_annotations.h>
+
+#include <media/stagefright/foundation/AString.h>
+
+namespace android {
+
+/**
+ * CodecErrorLog gathers what happened during codec failures, and make them
+ * available to clients for debugging purpose.
+ */
+class CodecErrorLog {
+public:
+ CodecErrorLog() = default;
+
+ /**
+ * Log a line of message.
+ *
+ * \note the message should be readable to developers who may not be
+ * familiar with MediaCodec internals
+ */
+ void log(const char *tag, const char *message);
+ void log(const char *tag, const std::string &message);
+
+ /**
+ * Extract the accumulated log as string. This operation clears the log.
+ */
+ std::string extract();
+
+ /**
+ * Clears the previous log.
+ */
+ void clear();
+
+private:
+ mutable std::mutex mLock;
+ std::stringstream mStream GUARDED_BY(mLock);
+};
+
+} // namespace android
+
+#endif // CODEC_ERROR_LOG_H_
diff --git a/media/libstagefright/include/media/stagefright/MediaCodec.h b/media/libstagefright/include/media/stagefright/MediaCodec.h
index 77394d5..1cc281b 100644
--- a/media/libstagefright/include/media/stagefright/MediaCodec.h
+++ b/media/libstagefright/include/media/stagefright/MediaCodec.h
@@ -28,6 +28,7 @@
#include <media/MediaMetrics.h>
#include <media/MediaProfiles.h>
#include <media/stagefright/foundation/AHandler.h>
+#include <media/stagefright/CodecErrorLog.h>
#include <media/stagefright/FrameRenderTracker.h>
#include <utils/Vector.h>
@@ -303,6 +304,8 @@
T value;
};
+ inline CodecErrorLog &getErrorLog() { return mErrorLog; }
+
protected:
virtual ~MediaCodec();
virtual void onMessageReceived(const sp<AMessage> &msg);
@@ -327,6 +330,7 @@
RELEASING,
};
std::string stateString(State state);
+ std::string apiStateString();
enum {
kPortIndexInput = 0,
@@ -717,6 +721,8 @@
std::function<status_t(const AString &, sp<MediaCodecInfo> *)> mGetCodecInfo;
friend class MediaTestHelper;
+ CodecErrorLog mErrorLog;
+
DISALLOW_EVIL_CONSTRUCTORS(MediaCodec);
};
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/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/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/utils/SessionConfigurationUtils.cpp b/services/camera/libcameraservice/utils/SessionConfigurationUtils.cpp
index 5fc3de0..e25f972 100644
--- a/services/camera/libcameraservice/utils/SessionConfigurationUtils.cpp
+++ b/services/camera/libcameraservice/utils/SessionConfigurationUtils.cpp
@@ -161,8 +161,13 @@
getAppropriateModeTag(ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS, maxResolution);
const int32_t heicSizesTag =
getAppropriateModeTag(ANDROID_HEIC_AVAILABLE_HEIC_STREAM_CONFIGURATIONS, maxResolution);
+ const int32_t jpegRSizesTag = getAppropriateModeTag(
+ ANDROID_JPEGR_AVAILABLE_JPEG_R_STREAM_CONFIGURATIONS, maxResolution);
+ bool isJpegRDataSpace = (dataSpace == static_cast<android_dataspace_t>(
+ ::aidl::android::hardware::graphics::common::Dataspace::JPEG_R));
camera_metadata_ro_entry streamConfigs =
+ (isJpegRDataSpace) ? info.find(jpegRSizesTag) :
(dataSpace == HAL_DATASPACE_DEPTH) ? info.find(depthSizesTag) :
(dataSpace == static_cast<android_dataspace>(HAL_DATASPACE_HEIF)) ?
info.find(heicSizesTag) :
@@ -672,7 +677,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) {
@@ -816,7 +821,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 bfc321d..d27144e 100644
--- a/services/camera/libcameraservice/utils/SessionConfigurationUtils.h
+++ b/services/camera/libcameraservice/utils/SessionConfigurationUtils.h
@@ -138,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;
}