Merge "audio policy: fix wrong ring volume after music stops." into sc-dev
diff --git a/camera/CaptureResult.cpp b/camera/CaptureResult.cpp
index 755051c..be47898 100644
--- a/camera/CaptureResult.cpp
+++ b/camera/CaptureResult.cpp
@@ -89,7 +89,7 @@
status_t PhysicalCaptureResultInfo::readFromParcel(const android::Parcel* parcel) {
status_t res;
- mPhysicalCameraId.remove(mPhysicalCameraId.size());
+ mPhysicalCameraId.setTo(u"");
mPhysicalCameraMetadata.clear();
if ((res = parcel->readString16(&mPhysicalCameraId)) != OK) {
diff --git a/media/codec2/hidl/1.0/vts/functional/video/VtsHalMediaC2V1_0TargetVideoEncTest.cpp b/media/codec2/hidl/1.0/vts/functional/video/VtsHalMediaC2V1_0TargetVideoEncTest.cpp
index dfd649d..c557de1 100644
--- a/media/codec2/hidl/1.0/vts/functional/video/VtsHalMediaC2V1_0TargetVideoEncTest.cpp
+++ b/media/codec2/hidl/1.0/vts/functional/video/VtsHalMediaC2V1_0TargetVideoEncTest.cpp
@@ -88,6 +88,16 @@
mTimestampUs = 0u;
mOutputSize = 0u;
mTimestampDevTest = false;
+ mWidth = ENC_DEFAULT_FRAME_WIDTH;
+ mHeight = ENC_DEFAULT_FRAME_HEIGHT;
+ mMaxWidth = 0;
+ mMaxHeight = 0;
+ mMinWidth = INT32_MAX;
+ mMinHeight = INT32_MAX;
+
+ ASSERT_EQ(getMaxMinResolutionSupported(mComponent), C2_OK);
+ mWidth = std::max(std::min(mWidth, mMaxWidth), mMinWidth);
+ mHeight = std::max(std::min(mHeight, mMaxHeight), mMinHeight);
C2SecureModeTuning secureModeTuning{};
mComponent->query({&secureModeTuning}, {}, C2_MAY_BLOCK, nullptr);
@@ -111,6 +121,8 @@
virtual void getParams() {}
bool setupConfigParam(int32_t nWidth, int32_t nHeight, int32_t nBFrame = 0);
+ c2_status_t getMaxMinResolutionSupported(
+ const std::shared_ptr<android::Codec2Client::Component>& component);
// callback function to process onWorkDone received by Listener
void handleWorkDone(std::list<std::unique_ptr<C2Work>>& workItems) {
@@ -181,6 +193,12 @@
uint32_t mFailedWorkReceived;
uint64_t mTimestampUs;
uint64_t mOutputSize;
+ int32_t mWidth;
+ int32_t mHeight;
+ int32_t mMaxWidth;
+ int32_t mMaxHeight;
+ int32_t mMinWidth;
+ int32_t mMinHeight;
std::list<uint64_t> mTimestampUslist;
std::list<uint64_t> mFlushedIndices;
@@ -271,6 +289,37 @@
strcat(URL, "bbb_352x288_420p_30fps_32frames.yuv");
}
+void fillByteBuffer(char* inputBuffer, char* mInputData, uint32_t nWidth, int32_t nHeight) {
+ int width, height, tileWidth, tileHeight;
+ int offset = 0, frmOffset = 0;
+ int numOfPlanes = 3;
+ for (int plane = 0; plane < numOfPlanes; plane++) {
+ if (plane == 0) {
+ width = nWidth;
+ height = nHeight;
+ tileWidth = ENC_DEFAULT_FRAME_WIDTH;
+ tileHeight = ENC_DEFAULT_FRAME_HEIGHT;
+ } else {
+ width = nWidth / 2;
+ tileWidth = ENC_DEFAULT_FRAME_WIDTH / 2;
+ height = nHeight / 2;
+ tileHeight = ENC_DEFAULT_FRAME_HEIGHT / 2;
+ }
+ for (int k = 0; k < height; k += tileHeight) {
+ int rowsToCopy = std::min(height - k, tileHeight);
+ for (int j = 0; j < rowsToCopy; j++) {
+ for (int i = 0; i < width; i += tileWidth) {
+ int colsToCopy = std::min(width - i, tileWidth);
+ memcpy(inputBuffer + (offset + (k + j) * width + i),
+ mInputData + (frmOffset + j * tileWidth), colsToCopy);
+ }
+ }
+ }
+ offset += width * height;
+ frmOffset += tileWidth * tileHeight;
+ }
+}
+
void encodeNFrames(const std::shared_ptr<android::Codec2Client::Component>& component,
std::mutex& queueLock, std::condition_variable& queueCondition,
std::list<std::unique_ptr<C2Work>>& workQueue,
@@ -314,12 +363,22 @@
ULock l(queueLock);
flushedIndices.emplace_back(frameID);
}
- char* data = (char*)malloc(bytesCount);
- ASSERT_NE(data, nullptr);
- memset(data, 0, bytesCount);
- if (eleStream.is_open()) {
- eleStream.read(data, bytesCount);
- ASSERT_EQ(eleStream.gcount(), bytesCount);
+ std::vector<uint8_t> buffer(bytesCount);
+ char* data = (char*)buffer.data();
+ if (nWidth != ENC_DEFAULT_FRAME_WIDTH || nHeight != ENC_DEFAULT_FRAME_HEIGHT) {
+ int defaultBytesCount = ENC_DEFAULT_FRAME_HEIGHT * ENC_DEFAULT_FRAME_WIDTH * 3 >> 1;
+ std::vector<uint8_t> srcBuffer(defaultBytesCount);
+ char* srcData = (char*)srcBuffer.data();
+ if (eleStream.is_open()) {
+ eleStream.read(srcData, defaultBytesCount);
+ ASSERT_EQ(eleStream.gcount(), defaultBytesCount);
+ }
+ fillByteBuffer(data, srcData, nWidth, nHeight);
+ } else {
+ if (eleStream.is_open()) {
+ eleStream.read(data, bytesCount);
+ ASSERT_EQ(eleStream.gcount(), bytesCount);
+ }
}
std::shared_ptr<C2GraphicBlock> block;
err = graphicPool->fetchGraphicBlock(nWidth, nHeight, HAL_PIXEL_FORMAT_YV12,
@@ -352,7 +411,6 @@
work->input.buffers.emplace_back(new GraphicBuffer(block));
work->worklets.clear();
work->worklets.emplace_back(new C2Worklet);
- free(data);
std::list<std::unique_ptr<C2Work>> items;
items.push_back(std::move(work));
@@ -381,13 +439,59 @@
}
};
+c2_status_t Codec2VideoEncHidlTestBase::getMaxMinResolutionSupported(
+ const std::shared_ptr<android::Codec2Client::Component>& component) {
+ std::unique_ptr<C2StreamPictureSizeInfo::input> param =
+ std::make_unique<C2StreamPictureSizeInfo::input>();
+ std::vector<C2FieldSupportedValuesQuery> validValueInfos = {
+ C2FieldSupportedValuesQuery::Current(
+ C2ParamField(param.get(), &C2StreamPictureSizeInfo::width)),
+ C2FieldSupportedValuesQuery::Current(
+ C2ParamField(param.get(), &C2StreamPictureSizeInfo::height))};
+ c2_status_t c2err = component->querySupportedValues(validValueInfos, C2_MAY_BLOCK);
+ if (c2err != C2_OK || validValueInfos.size() != 2u) {
+ ALOGE("querySupportedValues_vb failed for pictureSize");
+ return c2err;
+ }
+
+ const auto& c2FSVWidth = validValueInfos[0].values;
+ const auto& c2FSVHeight = validValueInfos[1].values;
+ switch (c2FSVWidth.type) {
+ case C2FieldSupportedValues::type_t::RANGE: {
+ const auto& widthRange = c2FSVWidth.range;
+ const auto& heightRange = c2FSVHeight.range;
+ mMaxWidth = (uint32_t)(widthRange.max).ref<uint32_t>();
+ mMaxHeight = (uint32_t)(heightRange.max).ref<uint32_t>();
+ mMinWidth = (uint32_t)(widthRange.min).ref<uint32_t>();
+ mMinHeight = (uint32_t)(heightRange.min).ref<uint32_t>();
+ break;
+ }
+ case C2FieldSupportedValues::type_t::VALUES: {
+ int32_t curr = 0;
+ for (const C2Value::Primitive& prim : c2FSVWidth.values) {
+ curr = (uint32_t)prim.ref<uint32_t>();
+ mMaxWidth = std::max(curr, mMaxWidth);
+ mMinWidth = std::min(curr, mMinWidth);
+ }
+ for (const C2Value::Primitive& prim : c2FSVHeight.values) {
+ curr = (uint32_t)prim.ref<uint32_t>();
+ mMaxHeight = std::max(curr, mMaxHeight);
+ mMinHeight = std::min(curr, mMinHeight);
+ }
+ break;
+ }
+ default:
+ ALOGE("Non supported data");
+ return C2_BAD_VALUE;
+ }
+ return C2_OK;
+}
+
TEST_P(Codec2VideoEncEncodeTest, EncodeTest) {
description("Encodes input file");
if (mDisableTest) GTEST_SKIP() << "Test is disabled";
char mURL[512];
- int32_t nWidth = ENC_DEFAULT_FRAME_WIDTH;
- int32_t nHeight = ENC_DEFAULT_FRAME_HEIGHT;
bool signalEOS = std::get<3>(GetParam());
// Send an empty frame to receive CSD data from encoder.
bool sendEmptyFirstFrame = std::get<3>(GetParam());
@@ -415,10 +519,6 @@
inputFrames--;
}
- if (!setupConfigParam(nWidth, nHeight, mConfigBPictures ? 1 : 0)) {
- std::cout << "[ WARN ] Test Skipped \n";
- return;
- }
std::vector<std::unique_ptr<C2Param>> inParams;
c2_status_t c2_status = mComponent->query({}, {C2StreamGopTuning::output::PARAM_TYPE},
C2_DONT_BLOCK, &inParams);
@@ -438,6 +538,9 @@
mConfigBPictures = false;
}
}
+ if (!setupConfigParam(mWidth, mHeight, mConfigBPictures ? 1 : 0)) {
+ ASSERT_TRUE(false) << "Failed while configuring height and width for " << mComponentName;
+ }
ASSERT_EQ(mComponent->start(), C2_OK);
@@ -447,7 +550,7 @@
}
ASSERT_NO_FATAL_FAILURE(encodeNFrames(mComponent, mQueueLock, mQueueCondition, mWorkQueue,
mFlushedIndices, mGraphicPool, eleStream, mDisableTest,
- inputFrames, ENC_NUM_FRAMES, nWidth, nHeight, false,
+ inputFrames, ENC_NUM_FRAMES, mWidth, mHeight, false,
signalEOS));
// mDisableTest will be set if buffer was not fetched properly.
// This may happen when resolution is not proper but config succeeded
@@ -538,14 +641,12 @@
if (mDisableTest) GTEST_SKIP() << "Test is disabled";
char mURL[512];
- int32_t nWidth = ENC_DEFAULT_FRAME_WIDTH;
- int32_t nHeight = ENC_DEFAULT_FRAME_HEIGHT;
+
strcpy(mURL, sResourceDir.c_str());
GetURLForComponent(mURL);
- if (!setupConfigParam(nWidth, nHeight)) {
- std::cout << "[ WARN ] Test Skipped \n";
- return;
+ if (!setupConfigParam(mWidth, mHeight)) {
+ ASSERT_TRUE(false) << "Failed while configuring height and width for " << mComponentName;
}
ASSERT_EQ(mComponent->start(), C2_OK);
@@ -567,7 +668,7 @@
ASSERT_NO_FATAL_FAILURE(encodeNFrames(mComponent, mQueueLock, mQueueCondition, mWorkQueue,
mFlushedIndices, mGraphicPool, eleStream, mDisableTest, 0,
- numFramesFlushed, nWidth, nHeight, false, false));
+ numFramesFlushed, mWidth, mHeight, false, false));
// mDisableTest will be set if buffer was not fetched properly.
// This may happen when resolution is not proper but config succeeded
// In this cases, we skip encoding the input stream
@@ -587,8 +688,8 @@
ASSERT_EQ(mWorkQueue.size(), MAX_INPUT_BUFFERS);
ASSERT_NO_FATAL_FAILURE(encodeNFrames(mComponent, mQueueLock, mQueueCondition, mWorkQueue,
mFlushedIndices, mGraphicPool, eleStream, mDisableTest,
- numFramesFlushed, numFrames - numFramesFlushed, nWidth,
- nHeight, true));
+ numFramesFlushed, numFrames - numFramesFlushed, mWidth,
+ mHeight, true));
eleStream.close();
// mDisableTest will be set if buffer was not fetched properly.
// This may happen when resolution is not proper but config succeeded
@@ -731,11 +832,8 @@
mFlushedIndices.clear();
- int32_t nWidth = ENC_DEFAULT_FRAME_WIDTH;
- int32_t nHeight = ENC_DEFAULT_FRAME_HEIGHT;
- if (!setupConfigParam(nWidth, nHeight)) {
- std::cout << "[ WARN ] Test Skipped \n";
- return;
+ if (!setupConfigParam(mWidth, mHeight)) {
+ ASSERT_TRUE(false) << "Failed while configuring height and width for " << mComponentName;
}
ASSERT_EQ(mComponent->start(), C2_OK);
@@ -756,8 +854,8 @@
ASSERT_NO_FATAL_FAILURE(encodeNFrames(mComponent, mQueueLock, mQueueCondition, mWorkQueue,
mFlushedIndices, mGraphicPool, eleStream,
- mDisableTest, inputFrameId, ENC_NUM_FRAMES, nWidth,
- nHeight, false, false));
+ mDisableTest, inputFrameId, ENC_NUM_FRAMES, mWidth,
+ mHeight, false, false));
// mDisableTest will be set if buffer was not fetched properly.
// This may happen when resolution is not proper but config succeeded
// In this cases, we skip encoding the input stream
diff --git a/media/codec2/sfplugin/CCodec.cpp b/media/codec2/sfplugin/CCodec.cpp
index 5789532..051e9cf 100644
--- a/media/codec2/sfplugin/CCodec.cpp
+++ b/media/codec2/sfplugin/CCodec.cpp
@@ -1500,13 +1500,11 @@
status_t err;
sp<IGraphicBufferProducer> bufferProducer;
- sp<AMessage> inputFormat;
sp<AMessage> outputFormat;
uint64_t usage = 0;
{
Mutexed<std::unique_ptr<Config>>::Locked configLocked(mConfig);
const std::unique_ptr<Config> &config = *configLocked;
- inputFormat = config->mInputFormat;
outputFormat = config->mOutputFormat;
usage = config->mISConfig ? config->mISConfig->mUsage : 0;
}
@@ -1542,6 +1540,14 @@
return;
}
+ // Formats can change after setupInputSurface
+ sp<AMessage> inputFormat;
+ {
+ Mutexed<std::unique_ptr<Config>>::Locked configLocked(mConfig);
+ const std::unique_ptr<Config> &config = *configLocked;
+ inputFormat = config->mInputFormat;
+ outputFormat = config->mOutputFormat;
+ }
mCallback->onInputSurfaceCreated(
inputFormat,
outputFormat,
@@ -1591,13 +1597,11 @@
}
void CCodec::setInputSurface(const sp<PersistentSurface> &surface) {
- sp<AMessage> inputFormat;
sp<AMessage> outputFormat;
uint64_t usage = 0;
{
Mutexed<std::unique_ptr<Config>>::Locked configLocked(mConfig);
const std::unique_ptr<Config> &config = *configLocked;
- inputFormat = config->mInputFormat;
outputFormat = config->mOutputFormat;
usage = config->mISConfig ? config->mISConfig->mUsage : 0;
}
@@ -1629,6 +1633,14 @@
mCallback->onInputSurfaceDeclined(UNKNOWN_ERROR);
return;
}
+ // Formats can change after setupInputSurface
+ sp<AMessage> inputFormat;
+ {
+ Mutexed<std::unique_ptr<Config>>::Locked configLocked(mConfig);
+ const std::unique_ptr<Config> &config = *configLocked;
+ inputFormat = config->mInputFormat;
+ outputFormat = config->mOutputFormat;
+ }
mCallback->onInputSurfaceAccepted(inputFormat, outputFormat);
}
@@ -2285,7 +2297,12 @@
}
}
if (config->mInputSurface) {
- config->mInputSurface->onInputBufferDone(work->input.ordinal.frameIndex);
+ if (work->worklets.empty()
+ || !work->worklets.back()
+ || (work->worklets.back()->output.flags
+ & C2FrameData::FLAG_INCOMPLETE) == 0) {
+ config->mInputSurface->onInputBufferDone(work->input.ordinal.frameIndex);
+ }
}
if (initDataWatcher.hasChanged()) {
initData = initDataWatcher.update();
diff --git a/services/camera/libcameraservice/CameraService.cpp b/services/camera/libcameraservice/CameraService.cpp
index 3e6a7c7..a0448b4 100644
--- a/services/camera/libcameraservice/CameraService.cpp
+++ b/services/camera/libcameraservice/CameraService.cpp
@@ -137,6 +137,9 @@
const String8 CameraService::kOfflineDevice("offline-");
+// Set to keep track of logged service error events.
+static std::set<String8> sServiceErrorEventSet;
+
CameraService::CameraService() :
mEventLog(DEFAULT_EVENT_LOG_LENGTH),
mNumberOfCameras(0),
@@ -197,6 +200,8 @@
if (res != OK) {
ALOGE("%s: Unable to initialize camera provider manager: %s (%d)",
__FUNCTION__, strerror(-res), res);
+ logServiceError(String8::format("Unable to initialize camera provider manager"),
+ ERROR_DISCONNECTED);
return res;
}
}
@@ -597,6 +602,7 @@
}
if (!mInitialized) {
+ logServiceError(String8::format("Camera subsystem is not available"),ERROR_DISCONNECTED);
return STATUS_ERROR(ERROR_DISCONNECTED,
"Camera subsystem is not available");
}
@@ -619,6 +625,8 @@
ret = STATUS_ERROR_FMT(ERROR_INVALID_OPERATION,
"Error retrieving camera info from device %d: %s (%d)", cameraId,
strerror(-err), err);
+ logServiceError(String8::format("Error retrieving camera info from device %d",cameraId),
+ ERROR_INVALID_OPERATION);
}
return ret;
@@ -656,6 +664,7 @@
if (!mInitialized) {
ALOGE("%s: Camera HAL couldn't be initialized", __FUNCTION__);
+ logServiceError(String8::format("Camera subsystem is not available"),ERROR_DISCONNECTED);
return STATUS_ERROR(ERROR_DISCONNECTED,
"Camera subsystem is not available");;
}
@@ -675,6 +684,8 @@
"characteristics for unknown device %s: %s (%d)", String8(cameraId).string(),
strerror(-res), res);
} else {
+ logServiceError(String8::format("Unable to retrieve camera characteristics for "
+ "device %s.", String8(cameraId).string()),ERROR_INVALID_OPERATION);
return STATUS_ERROR_FMT(ERROR_INVALID_OPERATION, "Unable to retrieve camera "
"characteristics for device %s: %s (%d)", String8(cameraId).string(),
strerror(-res), res);
@@ -1916,6 +1927,7 @@
errorCode = ERROR_INVALID_OPERATION;
}
ALOGE("%s: %s", __FUNCTION__, msg.string());
+ logServiceError(msg,errorCode);
return STATUS_ERROR(errorCode, msg.string());
}
@@ -2091,6 +2103,7 @@
if (!mInitialized) {
ALOGE("%s: Camera HAL couldn't be initialized", __FUNCTION__);
+ logServiceError(String8::format("Camera subsystem is not available"),ERROR_DISCONNECTED);
return STATUS_ERROR(ERROR_DISCONNECTED,
"Camera subsystem is not available");
}
@@ -2152,6 +2165,8 @@
mCameraProviderManager->isConcurrentSessionConfigurationSupported(
cameraIdsAndSessionConfigurations, isSupported);
if (res != OK) {
+ logServiceError(String8::format("Unable to query session configuration support"),
+ ERROR_INVALID_OPERATION);
return STATUS_ERROR_FMT(ERROR_INVALID_OPERATION, "Unable to query session configuration "
"support %s (%d)", strerror(-res), res);
}
@@ -2207,6 +2222,7 @@
if (ret != NO_ERROR) {
String8 msg = String8::format("Failed to initialize service listener: %s (%d)",
strerror(-ret), ret);
+ logServiceError(msg,ERROR_ILLEGAL_ARGUMENT);
ALOGE("%s: %s", __FUNCTION__, msg.string());
return STATUS_ERROR(ERROR_ILLEGAL_ARGUMENT, msg.string());
}
@@ -2591,7 +2607,15 @@
void CameraService::logEvent(const char* event) {
String8 curTime = getFormattedCurrentTime();
Mutex::Autolock l(mLogLock);
- mEventLog.add(String8::format("%s : %s", curTime.string(), event));
+ String8 msg = String8::format("%s : %s", curTime.string(), event);
+ // For service error events, print the msg only once.
+ if(!msg.contains("SERVICE ERROR")) {
+ mEventLog.add(msg);
+ } else if(sServiceErrorEventSet.find(msg) == sServiceErrorEventSet.end()) {
+ // Error event not added to the dumpsys log before
+ mEventLog.add(msg);
+ sServiceErrorEventSet.insert(msg);
+ }
}
void CameraService::logDisconnected(const char* cameraId, int clientPid,
diff --git a/services/oboeservice/AAudioServiceEndpointMMAP.cpp b/services/oboeservice/AAudioServiceEndpointMMAP.cpp
index 7294a58..b4efd1a 100644
--- a/services/oboeservice/AAudioServiceEndpointMMAP.cpp
+++ b/services/oboeservice/AAudioServiceEndpointMMAP.cpp
@@ -80,18 +80,23 @@
audio_format_t audioFormat = getFormat();
- // FLOAT is not directly supported by the HAL so ask for a 24-bit.
- bool isHighResRequested = audioFormat == AUDIO_FORMAT_PCM_FLOAT
- || audioFormat == AUDIO_FORMAT_PCM_32_BIT;
- if (isHighResRequested) {
+ // FLOAT is not directly supported by the HAL so ask for a 32-bit.
+ if (audioFormat == AUDIO_FORMAT_PCM_FLOAT) {
// TODO remove these logs when finished debugging.
- ALOGD("%s() change format from %d to 24_BIT_PACKED", __func__, audioFormat);
- audioFormat = AUDIO_FORMAT_PCM_24_BIT_PACKED;
+ ALOGD("%s() change format from %d to 32_BIT", __func__, audioFormat);
+ audioFormat = AUDIO_FORMAT_PCM_32_BIT;
}
result = openWithFormat(audioFormat);
if (result == AAUDIO_OK) return result;
+ if (result == AAUDIO_ERROR_UNAVAILABLE && audioFormat == AUDIO_FORMAT_PCM_32_BIT) {
+ ALOGD("%s() 32_BIT failed, perhaps due to format. Try again with 24_BIT_PACKED", __func__);
+ audioFormat = AUDIO_FORMAT_PCM_24_BIT_PACKED;
+ result = openWithFormat(audioFormat);
+ }
+ if (result == AAUDIO_OK) return result;
+
// TODO The HAL and AudioFlinger should be recommending a format if the open fails.
// But that recommendation is not propagating back from the HAL.
// So for now just try something very likely to work.