Merge "audio HAL wrapper: createAudioPatch handle reuse"
diff --git a/camera/Android.bp b/camera/Android.bp
index 2800595..b288bcf 100644
--- a/camera/Android.bp
+++ b/camera/Android.bp
@@ -86,6 +86,7 @@
"aidl/android/hardware/camera2/ICameraDeviceCallbacks.aidl",
"aidl/android/hardware/camera2/ICameraDeviceUser.aidl",
],
+ path: "aidl",
}
// Extra AIDL files that are used by framework.jar but not libcamera_client
@@ -96,4 +97,5 @@
"aidl/android/hardware/ICamera.aidl",
"aidl/android/hardware/ICameraClient.aidl",
],
+ path: "aidl",
}
diff --git a/camera/ndk/ndk_vendor/impl/ACameraDevice.cpp b/camera/ndk/ndk_vendor/impl/ACameraDevice.cpp
index 529c167..a43d707 100644
--- a/camera/ndk/ndk_vendor/impl/ACameraDevice.cpp
+++ b/camera/ndk/ndk_vendor/impl/ACameraDevice.cpp
@@ -31,6 +31,17 @@
#include "ACameraCaptureSession.inc"
+#define CHECK_TRANSACTION_AND_RET(remoteRet, status, callName) \
+ if (!remoteRet.isOk()) { \
+ ALOGE("%s: Transaction error during %s call %s", __FUNCTION__, callName, \
+ remoteRet.description().c_str()); \
+ return ACAMERA_ERROR_UNKNOWN; \
+ } \
+ if (status != Status::NO_ERROR) { \
+ ALOGE("%s: %s call failed", __FUNCTION__, callName); \
+ return utils::convertFromHidl(status); \
+ }
+
using namespace android;
namespace android {
@@ -151,7 +162,7 @@
return ACAMERA_ERROR_CAMERA_DISCONNECTED;
}
CameraMetadata rawRequest;
- Status status = Status::NO_ERROR;
+ Status status = Status::UNKNOWN_ERROR;
auto remoteRet = mRemote->createDefaultRequest(
utils::convertToHidl(templateId),
[&status, &rawRequest](auto s, const hidl_vec<uint8_t> &metadata) {
@@ -161,14 +172,7 @@
ALOGE("%s: Couldn't create default request", __FUNCTION__);
}
});
- if (!remoteRet.isOk()) {
- ALOGE("%s: Transaction error while trying to create default request %s", __FUNCTION__,
- remoteRet.description().c_str());
- return ACAMERA_ERROR_UNKNOWN;
- }
- if (status != Status::NO_ERROR) {
- return utils::convertFromHidl(status);
- }
+ CHECK_TRANSACTION_AND_RET(remoteRet, status, "createDefaultRequest()")
ACaptureRequest* outReq = new ACaptureRequest();
outReq->settings = new ACameraMetadata(rawRequest.release(), ACameraMetadata::ACM_REQUEST);
if (physicalCameraIdList != nullptr) {
@@ -243,20 +247,15 @@
}
bool configSupported = false;
- Status status = Status::NO_ERROR;
+ Status status = Status::UNKNOWN_ERROR;
auto remoteRet = mRemote->isSessionConfigurationSupported(sessionConfig,
[&status, &configSupported](auto s, auto supported) {
status = s;
configSupported = supported;
});
- if (status == Status::INVALID_OPERATION) {
- return ACAMERA_ERROR_UNSUPPORTED_OPERATION;
- } else if (!remoteRet.isOk()) {
- return ACAMERA_ERROR_UNKNOWN;
- } else {
- return configSupported ? ACAMERA_OK : ACAMERA_ERROR_STREAM_CONFIGURE_FAIL;
- }
+ CHECK_TRANSACTION_AND_RET(remoteRet, status, "isSessionConfigurationSupported()");
+ return configSupported ? ACAMERA_OK : ACAMERA_ERROR_STREAM_CONFIGURE_FAIL;
}
static void addMetadataToPhysicalCameraSettings(const CameraMetadata *metadata,
@@ -525,16 +524,13 @@
mRepeatingSequenceId = REQUEST_ID_NONE;
int64_t lastFrameNumber;
- Status status = Status::NO_ERROR;
+ Status status = Status::UNKNOWN_ERROR;
auto remoteRet = mRemote->cancelRepeatingRequest(
[&status, &lastFrameNumber](Status s, auto frameNumber) {
status = s;
lastFrameNumber = frameNumber;
});
- if (!remoteRet.isOk() || status != Status::NO_ERROR) {
- ALOGE("%s: Unable to cancel active repeating request", __FUNCTION__);
- return utils::convertFromHidl(status);
- }
+ CHECK_TRANSACTION_AND_RET(remoteRet, status, "cancelRepeatingRequest()");
checkRepeatingSequenceCompleteLocked(repeatingSequenceId, lastFrameNumber);
}
return ACAMERA_OK;
@@ -582,15 +578,12 @@
}
int64_t lastFrameNumber;
- Status status;
+ Status status = Status::UNKNOWN_ERROR;
auto remoteRet = mRemote->flush([&status, &lastFrameNumber](auto s, auto frameNumber) {
status = s;
lastFrameNumber = frameNumber;
});
- if (!remoteRet.isOk() || status != Status::NO_ERROR) {
- ALOGE("%s: Abort captures failed", __FUNCTION__);
- return utils::convertFromHidl(status);
- }
+ CHECK_TRANSACTION_AND_RET(remoteRet, status, "flush()")
if (mRepeatingSequenceId != REQUEST_ID_NONE) {
checkRepeatingSequenceCompleteLocked(mRepeatingSequenceId, lastFrameNumber);
}
@@ -611,10 +604,7 @@
}
auto remoteRet = mRemote->waitUntilIdle();
- if (!remoteRet.isOk()) {
- ALOGE("%s: Transaction waitUntilIdle failed", __FUNCTION__);
- return utils::convertFromHidl(remoteRet);
- }
+ CHECK_TRANSACTION_AND_RET(remoteRet, remoteRet, "waitUntilIdle()")
return ACAMERA_OK;
}
@@ -689,34 +679,25 @@
mIdle = true;
auto remoteRet = mRemote->beginConfigure();
- if (!remoteRet.isOk()|| remoteRet != Status::NO_ERROR) {
- ALOGE("Camera device %s begin configure failed", getId());
- return utils::convertFromHidl(remoteRet);
- }
+ CHECK_TRANSACTION_AND_RET(remoteRet, remoteRet, "beginConfigure()")
// delete to-be-deleted streams
for (auto streamId : deleteList) {
remoteRet = mRemote->deleteStream(streamId);
- if (!remoteRet.isOk() || remoteRet != Status::NO_ERROR) {
- ALOGE("Camera device %s failed to remove stream %d", getId(), streamId);
- return utils::convertFromHidl(remoteRet);
- }
+ CHECK_TRANSACTION_AND_RET(remoteRet, remoteRet, "deleteStream()")
mConfiguredOutputs.erase(streamId);
}
// add new streams
for (auto outputPair : addSet) {
int streamId;
- Status status;
+ Status status = Status::UNKNOWN_ERROR;
auto ret = mRemote->createStream(outputPair.second,
[&status, &streamId](Status s, auto stream_id) {
status = s;
streamId = stream_id;
});
- if (!remoteRet.isOk() || status != Status::NO_ERROR) {
- ALOGE("Camera device %s failed to create stream", getId());
- return utils::convertFromHidl(status);
- }
+ CHECK_TRANSACTION_AND_RET(ret, status, "createStream()")
mConfiguredOutputs.insert(std::make_pair(streamId, outputPair));
}
@@ -729,11 +710,8 @@
params.unlock(params_metadata);
}
remoteRet = mRemote->endConfigure(StreamConfigurationMode::NORMAL_MODE, hidlParams);
- if (!remoteRet.isOk()) {
- ALOGE("Transaction error: endConfigure failed %s", remoteRet.description().c_str());
- }
-
- return utils::convertFromHidl(remoteRet);
+ CHECK_TRANSACTION_AND_RET(remoteRet, remoteRet, "endConfigure()")
+ return ACAMERA_OK;
}
void
diff --git a/media/codec2/components/opus/C2SoftOpusEnc.cpp b/media/codec2/components/opus/C2SoftOpusEnc.cpp
index 384d58b..70d1965 100644
--- a/media/codec2/components/opus/C2SoftOpusEnc.cpp
+++ b/media/codec2/components/opus/C2SoftOpusEnc.cpp
@@ -471,11 +471,11 @@
uint8_t* outPtr = wView.data() + mBytesEncoded;
int encodedBytes =
opus_multistream_encode(mEncoder, mInputBufferPcm16,
- mNumSamplesPerFrame, outPtr, kMaxPayload);
+ mNumSamplesPerFrame, outPtr, kMaxPayload - mBytesEncoded);
ALOGV("encoded %i Opus bytes from %zu PCM bytes", encodedBytes,
processSize);
- if (encodedBytes < 0 || encodedBytes > kMaxPayload) {
+ if (encodedBytes < 0 || encodedBytes > (kMaxPayload - mBytesEncoded)) {
ALOGE("opus_encode failed, encodedBytes : %d", encodedBytes);
mSignalledError = true;
work->result = C2_CORRUPTED;
diff --git a/media/codec2/components/opus/C2SoftOpusEnc.h b/media/codec2/components/opus/C2SoftOpusEnc.h
index 69e5240..2b4d8f2 100644
--- a/media/codec2/components/opus/C2SoftOpusEnc.h
+++ b/media/codec2/components/opus/C2SoftOpusEnc.h
@@ -47,7 +47,9 @@
private:
/* OPUS_FRAMESIZE_20_MS */
const int kFrameSize = 960;
- const int kMaxPayload = 4000;
+ const int kMaxSampleRate = 48000;
+ const int kMinSampleRate = 8000;
+ const int kMaxPayload = (4000 * kMaxSampleRate) / kMinSampleRate;
const int kMaxNumChannels = 8;
std::shared_ptr<IntfImpl> mIntf;
diff --git a/media/codec2/sfplugin/CCodecConfig.cpp b/media/codec2/sfplugin/CCodecConfig.cpp
index 077a91f..1cfdc19 100644
--- a/media/codec2/sfplugin/CCodecConfig.cpp
+++ b/media/codec2/sfplugin/CCodecConfig.cpp
@@ -508,7 +508,7 @@
.limitTo(D::ENCODER & D::VIDEO));
// convert to timestamp base
add(ConfigMapper(KEY_I_FRAME_INTERVAL, C2_PARAMKEY_SYNC_FRAME_INTERVAL, "value")
- .withMapper([](C2Value v) -> C2Value {
+ .withMappers([](C2Value v) -> C2Value {
// convert from i32 to float
int32_t i32Value;
float fpValue;
@@ -518,6 +518,12 @@
return int64_t(c2_min(1000000 * fpValue + 0.5, (double)INT64_MAX));
}
return C2Value();
+ }, [](C2Value v) -> C2Value {
+ int64_t i64;
+ if (v.get(&i64)) {
+ return float(i64) / 1000000;
+ }
+ return C2Value();
}));
// remove when codecs switch to proper coding.gop (add support for calculating gop)
deprecated(ConfigMapper("i-frame-period", "coding.gop", "intra-period")
@@ -711,7 +717,7 @@
// convert to dBFS and add default
add(ConfigMapper(KEY_AAC_DRC_TARGET_REFERENCE_LEVEL, C2_PARAMKEY_DRC_TARGET_REFERENCE_LEVEL, "value")
- .limitTo(D::AUDIO & D::DECODER)
+ .limitTo(D::AUDIO & D::DECODER & D::CONFIG)
.withMapper([](C2Value v) -> C2Value {
int32_t value;
if (!v.get(&value) || value < 0) {
@@ -722,7 +728,7 @@
// convert to 0-1 (%) and add default
add(ConfigMapper(KEY_AAC_DRC_ATTENUATION_FACTOR, C2_PARAMKEY_DRC_ATTENUATION_FACTOR, "value")
- .limitTo(D::AUDIO & D::DECODER)
+ .limitTo(D::AUDIO & D::DECODER & D::CONFIG)
.withMapper([](C2Value v) -> C2Value {
int32_t value;
if (!v.get(&value) || value < 0) {
@@ -733,7 +739,7 @@
// convert to 0-1 (%) and add default
add(ConfigMapper(KEY_AAC_DRC_BOOST_FACTOR, C2_PARAMKEY_DRC_BOOST_FACTOR, "value")
- .limitTo(D::AUDIO & D::DECODER)
+ .limitTo(D::AUDIO & D::DECODER & D::CONFIG)
.withMapper([](C2Value v) -> C2Value {
int32_t value;
if (!v.get(&value) || value < 0) {
@@ -744,7 +750,7 @@
// convert to compression type and add default
add(ConfigMapper(KEY_AAC_DRC_HEAVY_COMPRESSION, C2_PARAMKEY_DRC_COMPRESSION_MODE, "value")
- .limitTo(D::AUDIO & D::DECODER)
+ .limitTo(D::AUDIO & D::DECODER & D::CONFIG)
.withMapper([](C2Value v) -> C2Value {
int32_t value;
if (!v.get(&value) || value < 0) {
@@ -755,7 +761,7 @@
// convert to dBFS and add default
add(ConfigMapper(KEY_AAC_ENCODED_TARGET_LEVEL, C2_PARAMKEY_DRC_ENCODED_TARGET_LEVEL, "value")
- .limitTo(D::AUDIO & D::DECODER)
+ .limitTo(D::AUDIO & D::DECODER & D::CONFIG)
.withMapper([](C2Value v) -> C2Value {
int32_t value;
if (!v.get(&value) || value < 0) {
@@ -766,7 +772,7 @@
// convert to effect type (these map to SDK values) and add default
add(ConfigMapper(KEY_AAC_DRC_EFFECT_TYPE, C2_PARAMKEY_DRC_EFFECT_TYPE, "value")
- .limitTo(D::AUDIO & D::DECODER)
+ .limitTo(D::AUDIO & D::DECODER & D::CONFIG)
.withMapper([](C2Value v) -> C2Value {
int32_t value;
if (!v.get(&value) || value < -1 || value > 8) {
diff --git a/media/codec2/sfplugin/Codec2Buffer.cpp b/media/codec2/sfplugin/Codec2Buffer.cpp
index c20ca73..702ad6f 100644
--- a/media/codec2/sfplugin/Codec2Buffer.cpp
+++ b/media/codec2/sfplugin/Codec2Buffer.cpp
@@ -201,9 +201,10 @@
* \param colorFormat desired SDK color format for the MediaImage (if this is a flexible format,
* an attempt is made to simply represent the graphic view as a flexible SDK format
* without a memcpy)
+ * \param copy whether the converter is used for copy or not
*/
GraphicView2MediaImageConverter(
- const C2GraphicView &view, int32_t colorFormat)
+ const C2GraphicView &view, int32_t colorFormat, bool copy)
: mInitCheck(NO_INIT),
mView(view),
mWidth(view.width()),
@@ -255,41 +256,44 @@
}
switch (mColorFormat) {
case COLOR_FormatYUV420Flexible:
- { // try to map directly. check if the planes are near one another
- const uint8_t *minPtr = mView.data()[0];
- const uint8_t *maxPtr = mView.data()[0];
- int32_t planeSize = 0;
- for (uint32_t i = 0; i < layout.numPlanes; ++i) {
- const C2PlaneInfo &plane = layout.planes[i];
- ssize_t minOffset = plane.minOffset(mWidth, mHeight);
- ssize_t maxOffset = plane.maxOffset(mWidth, mHeight);
- if (minPtr > mView.data()[i] + minOffset) {
- minPtr = mView.data()[i] + minOffset;
- }
- if (maxPtr < mView.data()[i] + maxOffset) {
- maxPtr = mView.data()[i] + maxOffset;
- }
- planeSize += std::abs(plane.rowInc) * align(mHeight, 64)
- / plane.rowSampling / plane.colSampling * divUp(mAllocatedDepth, 8u);
- }
-
- if ((maxPtr - minPtr + 1) <= planeSize) {
- // FIXME: this is risky as reading/writing data out of bound results in
- // an undefined behavior, but gralloc does assume a contiguous
- // mapping
+ if (!copy) {
+ // try to map directly. check if the planes are near one another
+ const uint8_t *minPtr = mView.data()[0];
+ const uint8_t *maxPtr = mView.data()[0];
+ int32_t planeSize = 0;
for (uint32_t i = 0; i < layout.numPlanes; ++i) {
const C2PlaneInfo &plane = layout.planes[i];
- mediaImage->mPlane[i].mOffset = mView.data()[i] - minPtr;
- mediaImage->mPlane[i].mColInc = plane.colInc;
- mediaImage->mPlane[i].mRowInc = plane.rowInc;
- mediaImage->mPlane[i].mHorizSubsampling = plane.colSampling;
- mediaImage->mPlane[i].mVertSubsampling = plane.rowSampling;
+ ssize_t minOffset = plane.minOffset(mWidth, mHeight);
+ ssize_t maxOffset = plane.maxOffset(mWidth, mHeight);
+ if (minPtr > mView.data()[i] + minOffset) {
+ minPtr = mView.data()[i] + minOffset;
+ }
+ if (maxPtr < mView.data()[i] + maxOffset) {
+ maxPtr = mView.data()[i] + maxOffset;
+ }
+ planeSize += std::abs(plane.rowInc) * align(mHeight, 64)
+ / plane.rowSampling / plane.colSampling
+ * divUp(mAllocatedDepth, 8u);
}
- mWrapped = new ABuffer(const_cast<uint8_t *>(minPtr), maxPtr - minPtr + 1);
- break;
+
+ if ((maxPtr - minPtr + 1) <= planeSize) {
+ // FIXME: this is risky as reading/writing data out of bound results
+ // in an undefined behavior, but gralloc does assume a
+ // contiguous mapping
+ for (uint32_t i = 0; i < layout.numPlanes; ++i) {
+ const C2PlaneInfo &plane = layout.planes[i];
+ mediaImage->mPlane[i].mOffset = mView.data()[i] - minPtr;
+ mediaImage->mPlane[i].mColInc = plane.colInc;
+ mediaImage->mPlane[i].mRowInc = plane.rowInc;
+ mediaImage->mPlane[i].mHorizSubsampling = plane.colSampling;
+ mediaImage->mPlane[i].mVertSubsampling = plane.rowSampling;
+ }
+ mWrapped = new ABuffer(const_cast<uint8_t *>(minPtr),
+ maxPtr - minPtr + 1);
+ break;
+ }
}
- }
- [[fallthrough]];
+ [[fallthrough]];
case COLOR_FormatYUV420Planar:
case COLOR_FormatYUV420PackedPlanar:
@@ -503,7 +507,7 @@
int32_t colorFormat = COLOR_FormatYUV420Flexible;
(void)format->findInt32("color-format", &colorFormat);
- GraphicView2MediaImageConverter converter(view, colorFormat);
+ GraphicView2MediaImageConverter converter(view, colorFormat, false /* copy */);
if (converter.initCheck() != OK) {
ALOGD("Converter init failed: %d", converter.initCheck());
return nullptr;
@@ -615,7 +619,7 @@
int32_t colorFormat = COLOR_FormatYUV420Flexible;
(void)format->findInt32("color-format", &colorFormat);
- GraphicView2MediaImageConverter converter(*view, colorFormat);
+ GraphicView2MediaImageConverter converter(*view, colorFormat, false /* copy */);
if (converter.initCheck() != OK) {
ALOGD("Converter init failed: %d", converter.initCheck());
return nullptr;
@@ -708,7 +712,7 @@
const_cast<ConstGraphicBlockBuffer *>(this)->format()->findInt32("color-format", &colorFormat);
GraphicView2MediaImageConverter converter(
- buffer->data().graphicBlocks()[0].map().get(), colorFormat);
+ buffer->data().graphicBlocks()[0].map().get(), colorFormat, true /* copy */);
if (converter.initCheck() != OK) {
ALOGD("ConstGraphicBlockBuffer::canCopy: converter init failed: %d", converter.initCheck());
return false;
@@ -730,7 +734,7 @@
format()->findInt32("color-format", &colorFormat);
GraphicView2MediaImageConverter converter(
- buffer->data().graphicBlocks()[0].map().get(), colorFormat);
+ buffer->data().graphicBlocks()[0].map().get(), colorFormat, true /* copy */);
if (converter.initCheck() != OK) {
ALOGD("ConstGraphicBlockBuffer::copy: converter init failed: %d", converter.initCheck());
return false;
diff --git a/media/codec2/sfplugin/utils/Codec2BufferUtils.cpp b/media/codec2/sfplugin/utils/Codec2BufferUtils.cpp
index 1e884ef..bf2a07e 100644
--- a/media/codec2/sfplugin/utils/Codec2BufferUtils.cpp
+++ b/media/codec2/sfplugin/utils/Codec2BufferUtils.cpp
@@ -137,14 +137,14 @@
int32_t dst_stride_v = img->mPlane[2].mRowInc;
if (IsNV12(view) && IsI420(img)) {
if (!libyuv::NV12ToI420(src_y, src_stride_y, src_u, src_stride_u, dst_y, dst_stride_y,
- dst_u, dst_stride_u, dst_v, dst_stride_v, view.width(),
- view.height())) {
+ dst_u, dst_stride_u, dst_v, dst_stride_v, view.crop().width,
+ view.crop().height)) {
return OK;
}
} else {
if (!libyuv::I420ToNV12(src_y, src_stride_y, src_u, src_stride_u, src_v, src_stride_v,
- dst_y, dst_stride_y, dst_u, dst_stride_u, view.width(),
- view.height())) {
+ dst_y, dst_stride_y, dst_u, dst_stride_u, view.crop().width,
+ view.crop().height)) {
return OK;
}
}
diff --git a/media/extractors/mkv/MatroskaExtractor.cpp b/media/extractors/mkv/MatroskaExtractor.cpp
index b1eb301..23022e4 100644
--- a/media/extractors/mkv/MatroskaExtractor.cpp
+++ b/media/extractors/mkv/MatroskaExtractor.cpp
@@ -2109,8 +2109,10 @@
if (!strcmp("A_AAC", codecID)) {
AMediaFormat_setString(meta, AMEDIAFORMAT_KEY_MIME, MEDIA_MIMETYPE_AUDIO_AAC);
- CHECK(codecPrivateSize >= 2);
-
+ if (codecPrivateSize < 2) {
+ ALOGW("Incomplete AAC Codec Info %zu byte", codecPrivateSize);
+ continue;
+ }
addESDSFromCodecPrivate(
meta, true, codecPrivate, codecPrivateSize);
} else if (!strcmp("A_VORBIS", codecID)) {
diff --git a/media/extractors/mp4/MPEG4Extractor.cpp b/media/extractors/mp4/MPEG4Extractor.cpp
index 89a36a8..8004e75 100755
--- a/media/extractors/mp4/MPEG4Extractor.cpp
+++ b/media/extractors/mp4/MPEG4Extractor.cpp
@@ -1197,45 +1197,16 @@
AMEDIAFORMAT_KEY_SAMPLE_RATE, sample_rate);
}
- // If format type is 'alac', it is necessary to get the parameters
- // from a alac atom spreading behind the frma atom.
- // See 'external/alac/ALACMagicCookieDescription.txt'.
- if (original_fourcc == FOURCC("alac")) {
- // Store ALAC magic cookie (decoder needs it).
- uint8_t alacInfo[12];
- data_offset = *offset;
- if (mDataSource->readAt(
- data_offset, alacInfo, sizeof(alacInfo)) < (ssize_t)sizeof(alacInfo)) {
- return ERROR_IO;
+ if (!mIsQT && original_fourcc == FOURCC("alac")) {
+ off64_t tmpOffset = *offset;
+ status_t err = parseALACSampleEntry(&tmpOffset);
+ if (err != OK) {
+ ALOGE("parseALACSampleEntry err:%d Line:%d", err, __LINE__);
+ return err;
}
- uint32_t size = U32_AT(&alacInfo[0]);
- if ((size != ALAC_SPECIFIC_INFO_SIZE) ||
- (U32_AT(&alacInfo[4]) != FOURCC("alac")) ||
- (U32_AT(&alacInfo[8]) != 0)) {
- return ERROR_MALFORMED;
- }
-
- data_offset += sizeof(alacInfo);
- uint8_t cookie[size - sizeof(alacInfo)];
- if (mDataSource->readAt(
- data_offset, cookie, sizeof(cookie)) < (ssize_t)sizeof(cookie)) {
- return ERROR_IO;
- }
-
- uint8_t bitsPerSample = cookie[5];
- AMediaFormat_setInt32(mLastTrack->meta,
- AMEDIAFORMAT_KEY_BITS_PER_SAMPLE, bitsPerSample);
- AMediaFormat_setInt32(mLastTrack->meta,
- AMEDIAFORMAT_KEY_CHANNEL_COUNT, cookie[9]);
- AMediaFormat_setInt32(mLastTrack->meta,
- AMEDIAFORMAT_KEY_SAMPLE_RATE, U32_AT(&cookie[20]));
- AMediaFormat_setBuffer(mLastTrack->meta,
- AMEDIAFORMAT_KEY_CSD_0, cookie, sizeof(cookie));
-
- // Add the size of ALAC Specific Info (36 bytes) and terminator
- // atom (8 bytes).
- *offset += (size + 8);
+ *offset = tmpOffset + 8;
}
+
break;
}
@@ -1653,7 +1624,18 @@
case 0x6D730055: // "ms U" mp3 audio
{
if (mIsQT && depth >= 1 && mPath[depth - 1] == FOURCC("wave")) {
+
+ if (chunk_type == FOURCC("alac")) {
+ off64_t offsetTmp = *offset;
+ status_t err = parseALACSampleEntry(&offsetTmp);
+ if (err != OK) {
+ ALOGE("parseALACSampleEntry err:%d Line:%d", err, __LINE__);
+ return err;
+ }
+ }
+
// Ignore all atoms embedded in QT wave atom
+ ALOGV("Ignore all atoms embedded in QT wave atom");
*offset += chunk_size;
break;
}
@@ -1792,39 +1774,14 @@
CHECK_EQ(*offset, stop_offset);
}
- if (chunk_type == FOURCC("alac")) {
-
- // See 'external/alac/ALACMagicCookieDescription.txt for the detail'.
- // Store ALAC magic cookie (decoder needs it).
- uint8_t alacInfo[12];
+ if (!mIsQT && chunk_type == FOURCC("alac")) {
data_offset += sizeof(buffer);
- if (mDataSource->readAt(
- data_offset, alacInfo, sizeof(alacInfo)) < (ssize_t)sizeof(alacInfo)) {
- return ERROR_IO;
- }
- uint32_t size = U32_AT(&alacInfo[0]);
- if ((size != ALAC_SPECIFIC_INFO_SIZE) ||
- (U32_AT(&alacInfo[4]) != FOURCC("alac")) ||
- (U32_AT(&alacInfo[8]) != 0)) {
- return ERROR_MALFORMED;
- }
- data_offset += sizeof(alacInfo);
- uint8_t cookie[size - sizeof(alacInfo)];
- if (mDataSource->readAt(
- data_offset, cookie, sizeof(cookie)) < (ssize_t)sizeof(cookie)) {
- return ERROR_IO;
- }
- uint8_t bitsPerSample = cookie[5];
- AMediaFormat_setInt32(mLastTrack->meta,
- AMEDIAFORMAT_KEY_BITS_PER_SAMPLE, bitsPerSample);
- AMediaFormat_setInt32(mLastTrack->meta,
- AMEDIAFORMAT_KEY_CHANNEL_COUNT, cookie[9]);
- AMediaFormat_setInt32(mLastTrack->meta,
- AMEDIAFORMAT_KEY_SAMPLE_RATE, U32_AT(&cookie[20]));
- AMediaFormat_setBuffer(mLastTrack->meta,
- AMEDIAFORMAT_KEY_CSD_0, cookie, sizeof(cookie));
- data_offset += sizeof(cookie);
+ status_t err = parseALACSampleEntry(&data_offset);
+ if (err != OK) {
+ ALOGE("parseALACSampleEntry err:%d Line:%d", err, __LINE__);
+ return err;
+ }
*offset = data_offset;
CHECK_EQ(*offset, stop_offset);
}
@@ -3289,6 +3246,45 @@
return OK;
}
+status_t MPEG4Extractor::parseALACSampleEntry(off64_t *offset) {
+ // See 'external/alac/ALACMagicCookieDescription.txt for the detail'.
+ // Store ALAC magic cookie (decoder needs it).
+ uint8_t alacInfo[12];
+ off64_t data_offset = *offset;
+
+ if (mDataSource->readAt(
+ data_offset, alacInfo, sizeof(alacInfo)) < (ssize_t)sizeof(alacInfo)) {
+ return ERROR_IO;
+ }
+ uint32_t size = U32_AT(&alacInfo[0]);
+ if ((size != ALAC_SPECIFIC_INFO_SIZE) ||
+ (U32_AT(&alacInfo[4]) != FOURCC("alac")) ||
+ (U32_AT(&alacInfo[8]) != 0)) {
+ ALOGV("Size:%u, U32_AT(&alacInfo[4]):%u, U32_AT(&alacInfo[8]):%u",
+ size, U32_AT(&alacInfo[4]), U32_AT(&alacInfo[8]));
+ return ERROR_MALFORMED;
+ }
+ data_offset += sizeof(alacInfo);
+ uint8_t cookie[size - sizeof(alacInfo)];
+ if (mDataSource->readAt(
+ data_offset, cookie, sizeof(cookie)) < (ssize_t)sizeof(cookie)) {
+ return ERROR_IO;
+ }
+
+ uint8_t bitsPerSample = cookie[5];
+ AMediaFormat_setInt32(mLastTrack->meta,
+ AMEDIAFORMAT_KEY_BITS_PER_SAMPLE, bitsPerSample);
+ AMediaFormat_setInt32(mLastTrack->meta,
+ AMEDIAFORMAT_KEY_CHANNEL_COUNT, cookie[9]);
+ AMediaFormat_setInt32(mLastTrack->meta,
+ AMEDIAFORMAT_KEY_SAMPLE_RATE, U32_AT(&cookie[20]));
+ AMediaFormat_setBuffer(mLastTrack->meta,
+ AMEDIAFORMAT_KEY_CSD_0, cookie, sizeof(cookie));
+ data_offset += sizeof(cookie);
+ *offset = data_offset;
+ return OK;
+}
+
status_t MPEG4Extractor::parseSegmentIndex(off64_t offset, size_t size) {
ALOGV("MPEG4Extractor::parseSegmentIndex");
diff --git a/media/extractors/mp4/MPEG4Extractor.h b/media/extractors/mp4/MPEG4Extractor.h
index e10bf8a..fcddbb8 100644
--- a/media/extractors/mp4/MPEG4Extractor.h
+++ b/media/extractors/mp4/MPEG4Extractor.h
@@ -179,6 +179,7 @@
status_t parseAC3SpecificBox(off64_t offset);
status_t parseEAC3SpecificBox(off64_t offset);
status_t parseAC4SpecificBox(off64_t offset);
+ status_t parseALACSampleEntry(off64_t *offset);
void adjustRawDefaultFrameSize();
MPEG4Extractor(const MPEG4Extractor &);
diff --git a/media/libaudioclient/Android.bp b/media/libaudioclient/Android.bp
index 03bd6ce..c516d20 100644
--- a/media/libaudioclient/Android.bp
+++ b/media/libaudioclient/Android.bp
@@ -42,7 +42,7 @@
// AIDL files for audioclient interfaces
// The headers for these interfaces will be available to any modules that
// include libaudioclient, at the path "aidl/package/path/BnFoo.h"
- "aidl/android/media/IAudioRecord.aidl",
+ ":libaudioclient_aidl_private",
":libaudioclient_aidl",
"AudioEffect.cpp",
@@ -110,4 +110,15 @@
srcs: [
"aidl/android/media/IPlayer.aidl",
],
+ path: "aidl",
+}
+
+// Used to strip the "aidl/" from the path, so the build system can predict the
+// output filename.
+filegroup {
+ name: "libaudioclient_aidl_private",
+ srcs: [
+ "aidl/android/media/IAudioRecord.aidl",
+ ],
+ path: "aidl",
}
diff --git a/media/libmedia/Android.bp b/media/libmedia/Android.bp
index 1d33590..d141287 100644
--- a/media/libmedia/Android.bp
+++ b/media/libmedia/Android.bp
@@ -47,6 +47,15 @@
clang: true,
}
+filegroup {
+ name: "libmedia_omx_aidl",
+ srcs: [
+ "aidl/android/IGraphicBufferSource.aidl",
+ "aidl/android/IOMXBufferSource.aidl",
+ ],
+ path: "aidl",
+}
+
cc_library_shared {
name: "libmedia_omx",
vendor_available: true,
@@ -56,8 +65,7 @@
double_loadable: true,
srcs: [
- "aidl/android/IGraphicBufferSource.aidl",
- "aidl/android/IOMXBufferSource.aidl",
+ ":libmedia_omx_aidl",
"IMediaCodecList.cpp",
"IOMX.cpp",
diff --git a/media/libmediaplayerservice/nuplayer/GenericSource.cpp b/media/libmediaplayerservice/nuplayer/GenericSource.cpp
index 5a58aa0..5c77e41 100644
--- a/media/libmediaplayerservice/nuplayer/GenericSource.cpp
+++ b/media/libmediaplayerservice/nuplayer/GenericSource.cpp
@@ -90,8 +90,11 @@
ALOGV("resetDataSource");
mHTTPService.clear();
- mHttpSource.clear();
- mDisconnected = false;
+ {
+ Mutex::Autolock _l_d(mDisconnectLock);
+ mHttpSource.clear();
+ mDisconnected = false;
+ }
mUri.clear();
mUriHeaders.clear();
mSources.clear();
@@ -152,7 +155,10 @@
ALOGV("setDataSource (source: %p)", source.get());
resetDataSource();
- mDataSource = source;
+ {
+ Mutex::Autolock _l_d(mDisconnectLock);
+ mDataSource = source;
+ }
return OK;
}
@@ -163,8 +169,12 @@
status_t NuPlayer::GenericSource::initFromDataSource() {
sp<IMediaExtractor> extractor;
- CHECK(mDataSource != NULL);
- sp<DataSource> dataSource = mDataSource;
+ sp<DataSource> dataSource;
+ {
+ Mutex::Autolock _l_d(mDisconnectLock);
+ dataSource = mDataSource;
+ }
+ CHECK(dataSource != NULL);
mLock.unlock();
// This might take long time if data source is not reliable.
@@ -359,6 +369,7 @@
}
void NuPlayer::GenericSource::onPrepareAsync() {
+ mDisconnectLock.lock();
ALOGV("onPrepareAsync: mDataSource: %d", (mDataSource != NULL));
// delayed data source creation
@@ -372,20 +383,30 @@
String8 contentType;
if (!strncasecmp("http://", uri, 7) || !strncasecmp("https://", uri, 8)) {
- mHttpSource = DataSourceFactory::CreateMediaHTTP(mHTTPService);
- if (mHttpSource == NULL) {
+ sp<DataSource> httpSource;
+ mDisconnectLock.unlock();
+ httpSource = DataSourceFactory::CreateMediaHTTP(mHTTPService);
+ if (httpSource == NULL) {
ALOGE("Failed to create http source!");
notifyPreparedAndCleanup(UNKNOWN_ERROR);
+ mDisconnectLock.lock();
return;
}
+ mDisconnectLock.lock();
+
+ if (!mDisconnected) {
+ mHttpSource = httpSource;
+ }
}
mLock.unlock();
+ mDisconnectLock.unlock();
// This might take long time if connection has some issue.
sp<DataSource> dataSource = DataSourceFactory::CreateFromURI(
mHTTPService, uri, &mUriHeaders, &contentType,
static_cast<HTTPBase *>(mHttpSource.get()));
mLock.lock();
+ mDisconnectLock.lock();
if (!mDisconnected) {
mDataSource = dataSource;
}
@@ -437,6 +458,8 @@
mCachedSource = static_cast<NuCachedSource2 *>(mDataSource.get());
}
+ mDisconnectLock.unlock();
+
// For cached streaming cases, we need to wait for enough
// buffering before reporting prepared.
mIsStreaming = (mCachedSource != NULL);
@@ -503,9 +526,13 @@
void NuPlayer::GenericSource::notifyPreparedAndCleanup(status_t err) {
if (err != OK) {
- mDataSource.clear();
+ {
+ Mutex::Autolock _l_d(mDisconnectLock);
+ mDataSource.clear();
+ mHttpSource.clear();
+ }
+
mCachedSource.clear();
- mHttpSource.clear();
mBitrate = -1;
mPrevBufferPercentage = -1;
@@ -547,7 +574,7 @@
void NuPlayer::GenericSource::disconnect() {
sp<DataSource> dataSource, httpSource;
{
- Mutex::Autolock _l(mLock);
+ Mutex::Autolock _l_d(mDisconnectLock);
dataSource = mDataSource;
httpSource = mHttpSource;
mDisconnected = true;
diff --git a/media/libmediaplayerservice/nuplayer/GenericSource.h b/media/libmediaplayerservice/nuplayer/GenericSource.h
index 065cac1..4d1905d 100644
--- a/media/libmediaplayerservice/nuplayer/GenericSource.h
+++ b/media/libmediaplayerservice/nuplayer/GenericSource.h
@@ -170,6 +170,7 @@
sp<ABuffer> mGlobalTimedText;
mutable Mutex mLock;
+ mutable Mutex mDisconnectLock; // Protects mDataSource, mHttpSource and mDisconnected
sp<ALooper> mLooper;
diff --git a/media/libstagefright/codecs/vorbis/dec/SoftVorbis.cpp b/media/libstagefright/codecs/vorbis/dec/SoftVorbis.cpp
index 76a400c..8d0ea3a 100644
--- a/media/libstagefright/codecs/vorbis/dec/SoftVorbis.cpp
+++ b/media/libstagefright/codecs/vorbis/dec/SoftVorbis.cpp
@@ -572,16 +572,17 @@
}
void SoftVorbis::onPortFlushCompleted(OMX_U32 portIndex) {
- if (portIndex == 0 && mState != NULL) {
- // Make sure that the next buffer output does not still
- // depend on fragments from the last one decoded.
-
+ if (portIndex == 0) {
mInputBufferCount = 0;
mNumFramesOutput = 0;
mSawInputEos = false;
mSignalledOutputEos = false;
mNumFramesLeftOnPage = -1;
- vorbis_dsp_restart(mState);
+ if (mState != NULL) {
+ // Make sure that the next buffer output does not still
+ // depend on fragments from the last one decoded.
+ vorbis_dsp_restart(mState);
+ }
}
}
@@ -603,6 +604,7 @@
mSawInputEos = false;
mSignalledOutputEos = false;
mSignalledError = false;
+ mNumFramesLeftOnPage = -1;
mOutputPortSettingsChange = NONE;
}
diff --git a/media/libstagefright/httplive/HTTPDownloader.cpp b/media/libstagefright/httplive/HTTPDownloader.cpp
index 59265fe..c7e92cd 100644
--- a/media/libstagefright/httplive/HTTPDownloader.cpp
+++ b/media/libstagefright/httplive/HTTPDownloader.cpp
@@ -157,6 +157,12 @@
buffer->size() + bufferRemaining);
sp<ABuffer> copy = new ABuffer(buffer->size() + bufferRemaining);
+ if (copy->data() == NULL) {
+ android_errorWriteLog(0x534e4554, "68399439");
+ ALOGE("not enough memory to download: requesting %zu + %zu",
+ buffer->size(), bufferRemaining);
+ return NO_MEMORY;
+ }
memcpy(copy->data(), buffer->data(), buffer->size());
copy->setRange(0, buffer->size());
diff --git a/services/audiopolicy/common/managerdefinitions/src/AudioPolicyMix.cpp b/services/audiopolicy/common/managerdefinitions/src/AudioPolicyMix.cpp
index dca84c0..c42923a 100644
--- a/services/audiopolicy/common/managerdefinitions/src/AudioPolicyMix.cpp
+++ b/services/audiopolicy/common/managerdefinitions/src/AudioPolicyMix.cpp
@@ -120,8 +120,9 @@
ALOGV("getAudioPolicyMix() for dev=0x%x addr=%s", deviceType, address.string());
for (ssize_t i = 0; i < size(); i++) {
- if (itemAt(i)->mDeviceType == deviceType
- && itemAt(i)->mDeviceAddress.compare(address) == 0) {
+ // Workaround: when an in audio policy is registered, it opens an output
+ // that tries to find the audio policy, thus the device must be ignored.
+ if (itemAt(i)->mDeviceAddress.compare(address) == 0) {
policyMix = itemAt(i);
ALOGV("getAudioPolicyMix: found mix %zu match (devType=0x%x addr=%s)",
i, deviceType, address.string());
diff --git a/services/camera/libcameraservice/Android.bp b/services/camera/libcameraservice/Android.bp
index 7ec0e4c..1c1f5e6 100644
--- a/services/camera/libcameraservice/Android.bp
+++ b/services/camera/libcameraservice/Android.bp
@@ -70,6 +70,7 @@
],
shared_libs: [
+ "libbase",
"libdl",
"libexif",
"libui",
diff --git a/services/camera/libcameraservice/CameraService.cpp b/services/camera/libcameraservice/CameraService.cpp
index a87ebdf..3e62102 100644
--- a/services/camera/libcameraservice/CameraService.cpp
+++ b/services/camera/libcameraservice/CameraService.cpp
@@ -33,6 +33,7 @@
#include <android-base/macros.h>
#include <android-base/parseint.h>
+#include <android-base/stringprintf.h>
#include <binder/ActivityManager.h>
#include <binder/AppOpsManager.h>
#include <binder/IPCThreadState.h>
@@ -81,6 +82,7 @@
namespace android {
+using base::StringPrintf;
using binder::Status;
using frameworks::cameraservice::service::V2_0::implementation::HidlCameraService;
using hardware::ICamera;
@@ -2366,6 +2368,13 @@
}
mClientPackageName = packages[0];
}
+ if (hardware::IPCThreadState::self()->isServingCall()) {
+ std::string vendorClient =
+ StringPrintf("vendor.client.pid<%d>", CameraThreadState::getCallingPid());
+ mClientPackageName = String16(vendorClient.c_str());
+ } else {
+ mAppOpsManager = std::make_unique<AppOpsManager>();
+ }
}
CameraService::BasicClient::~BasicClient() {
@@ -2381,8 +2390,7 @@
mDisconnected = true;
sCameraService->removeByClient(this);
- sCameraService->logDisconnected(mCameraIdStr, mClientPid,
- String8(mClientPackageName));
+ sCameraService->logDisconnected(mCameraIdStr, mClientPid, String8(mClientPackageName));
sCameraService->mCameraProviderManager->removeRef(CameraProviderManager::DeviceMode::CAMERA,
mCameraIdStr.c_str());
@@ -2432,31 +2440,31 @@
status_t CameraService::BasicClient::startCameraOps() {
ATRACE_CALL();
- int32_t res;
- // Notify app ops that the camera is not available
- mOpsCallback = new OpsCallback(this);
-
{
ALOGV("%s: Start camera ops, package name = %s, client UID = %d",
__FUNCTION__, String8(mClientPackageName).string(), mClientUid);
}
+ if (mAppOpsManager != nullptr) {
+ // Notify app ops that the camera is not available
+ mOpsCallback = new OpsCallback(this);
+ int32_t res;
+ mAppOpsManager->startWatchingMode(AppOpsManager::OP_CAMERA,
+ mClientPackageName, mOpsCallback);
+ res = mAppOpsManager->startOpNoThrow(AppOpsManager::OP_CAMERA,
+ mClientUid, mClientPackageName, /*startIfModeDefault*/ false);
- mAppOpsManager.startWatchingMode(AppOpsManager::OP_CAMERA,
- mClientPackageName, mOpsCallback);
- res = mAppOpsManager.startOpNoThrow(AppOpsManager::OP_CAMERA,
- mClientUid, mClientPackageName, /*startIfModeDefault*/ false);
+ if (res == AppOpsManager::MODE_ERRORED) {
+ ALOGI("Camera %s: Access for \"%s\" has been revoked",
+ mCameraIdStr.string(), String8(mClientPackageName).string());
+ return PERMISSION_DENIED;
+ }
- if (res == AppOpsManager::MODE_ERRORED) {
- ALOGI("Camera %s: Access for \"%s\" has been revoked",
- mCameraIdStr.string(), String8(mClientPackageName).string());
- return PERMISSION_DENIED;
- }
-
- if (res == AppOpsManager::MODE_IGNORED) {
- ALOGI("Camera %s: Access for \"%s\" has been restricted",
- mCameraIdStr.string(), String8(mClientPackageName).string());
- // Return the same error as for device policy manager rejection
- return -EACCES;
+ if (res == AppOpsManager::MODE_IGNORED) {
+ ALOGI("Camera %s: Access for \"%s\" has been restricted",
+ mCameraIdStr.string(), String8(mClientPackageName).string());
+ // Return the same error as for device policy manager rejection
+ return -EACCES;
+ }
}
mOpsActive = true;
@@ -2483,10 +2491,11 @@
// Check if startCameraOps succeeded, and if so, finish the camera op
if (mOpsActive) {
// Notify app ops that the camera is available again
- mAppOpsManager.finishOp(AppOpsManager::OP_CAMERA, mClientUid,
- mClientPackageName);
- mOpsActive = false;
-
+ if (mAppOpsManager != nullptr) {
+ mAppOpsManager->finishOp(AppOpsManager::OP_CAMERA, mClientUid,
+ mClientPackageName);
+ mOpsActive = false;
+ }
// This function is called when a client disconnects. This should
// release the camera, but actually only if it was in a proper
// functional state, i.e. with status NOT_AVAILABLE
@@ -2506,8 +2515,8 @@
mCameraIdStr, mCameraFacing, mClientPackageName, apiLevel);
}
// Always stop watching, even if no camera op is active
- if (mOpsCallback != NULL) {
- mAppOpsManager.stopWatchingMode(mOpsCallback);
+ if (mOpsCallback != nullptr && mAppOpsManager != nullptr) {
+ mAppOpsManager->stopWatchingMode(mOpsCallback);
}
mOpsCallback.clear();
@@ -2516,19 +2525,18 @@
return OK;
}
-void CameraService::BasicClient::opChanged(int32_t op, const String16& packageName) {
+void CameraService::BasicClient::opChanged(int32_t op, const String16&) {
ATRACE_CALL();
-
- String8 name(packageName);
- String8 myName(mClientPackageName);
-
+ if (mAppOpsManager == nullptr) {
+ return;
+ }
if (op != AppOpsManager::OP_CAMERA) {
ALOGW("Unexpected app ops notification received: %d", op);
return;
}
int32_t res;
- res = mAppOpsManager.checkOp(AppOpsManager::OP_CAMERA,
+ res = mAppOpsManager->checkOp(AppOpsManager::OP_CAMERA,
mClientUid, mClientPackageName);
ALOGV("checkOp returns: %d, %s ", res,
res == AppOpsManager::MODE_ALLOWED ? "ALLOWED" :
@@ -2538,7 +2546,7 @@
if (res != AppOpsManager::MODE_ALLOWED) {
ALOGI("Camera %s: Access for \"%s\" revoked", mCameraIdStr.string(),
- myName.string());
+ String8(mClientPackageName).string());
block();
}
}
diff --git a/services/camera/libcameraservice/CameraService.h b/services/camera/libcameraservice/CameraService.h
index b8cec2c..065157d 100644
--- a/services/camera/libcameraservice/CameraService.h
+++ b/services/camera/libcameraservice/CameraService.h
@@ -293,7 +293,7 @@
status_t finishCameraOps();
private:
- AppOpsManager mAppOpsManager;
+ std::unique_ptr<AppOpsManager> mAppOpsManager = nullptr;
class OpsCallback : public BnAppOpsCallback {
public:
diff --git a/services/camera/libcameraservice/device3/Camera3Device.cpp b/services/camera/libcameraservice/device3/Camera3Device.cpp
index 00f0d86..9771f9e 100644
--- a/services/camera/libcameraservice/device3/Camera3Device.cpp
+++ b/services/camera/libcameraservice/device3/Camera3Device.cpp
@@ -2876,7 +2876,8 @@
config.streams = streams.editArray();
// Do the HAL configuration; will potentially touch stream
- // max_buffers, usage, priv fields.
+ // max_buffers, usage, and priv fields, as well as data_space and format
+ // fields for IMPLEMENTATION_DEFINED formats.
const camera_metadata_t *sessionBuffer = sessionParams.getAndLock();
res = mInterface->configureStreams(sessionBuffer, &config, bufferSizes);
@@ -4202,10 +4203,19 @@
dst3_2.streamType = streamType;
dst3_2.width = src->width;
dst3_2.height = src->height;
- dst3_2.format = mapToPixelFormat(src->format);
dst3_2.usage = mapToConsumerUsage(cam3stream->getUsage());
- dst3_2.dataSpace = mapToHidlDataspace(src->data_space);
dst3_2.rotation = mapToStreamRotation((camera3_stream_rotation_t) src->rotation);
+ // For HidlSession version 3.5 or newer, the format and dataSpace sent
+ // to HAL are original, not the overriden ones.
+ if (mHidlSession_3_5 != nullptr) {
+ dst3_2.format = mapToPixelFormat(cam3stream->isFormatOverridden() ?
+ cam3stream->getOriginalFormat() : src->format);
+ dst3_2.dataSpace = mapToHidlDataspace(cam3stream->isDataSpaceOverridden() ?
+ cam3stream->getOriginalDataSpace() : src->data_space);
+ } else {
+ dst3_2.format = mapToPixelFormat(src->format);
+ dst3_2.dataSpace = mapToHidlDataspace(src->data_space);
+ }
dst3_4.v3_2 = dst3_2;
dst3_4.bufferSize = bufferSizes[i];
if (src->physical_camera_id != nullptr) {
@@ -4266,7 +4276,7 @@
return OK;
};
- // See if we have v3.4 or v3.3 HAL
+ // See which version of HAL we have
if (mHidlSession_3_5 != nullptr) {
ALOGV("%s: v3.5 device found", __FUNCTION__);
device::V3_5::StreamConfiguration requestedConfiguration3_5;
@@ -4281,7 +4291,6 @@
} else if (mHidlSession_3_4 != nullptr) {
// We do; use v3.4 for the call
ALOGV("%s: v3.4 device found", __FUNCTION__);
- device::V3_4::HalStreamConfiguration finalConfiguration3_4;
auto err = mHidlSession_3_4->configureStreams_3_4(
requestedConfiguration3_4, configStream34Cb);
res = postprocConfigStream34(err);
@@ -4352,12 +4361,12 @@
device::V3_3::HalStream &src = finalConfiguration.streams[realIdx];
Camera3Stream* dstStream = Camera3Stream::cast(dst);
- dstStream->setFormatOverride(false);
- dstStream->setDataSpaceOverride(false);
int overrideFormat = mapToFrameworkFormat(src.v3_2.overrideFormat);
android_dataspace overrideDataSpace = mapToFrameworkDataspace(src.overrideDataSpace);
if (dst->format != HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED) {
+ dstStream->setFormatOverride(false);
+ dstStream->setDataSpaceOverride(false);
if (dst->format != overrideFormat) {
ALOGE("%s: Stream %d: Format override not allowed for format 0x%x", __FUNCTION__,
streamId, dst->format);
@@ -4367,10 +4376,13 @@
streamId, dst->format);
}
} else {
- dstStream->setFormatOverride((dst->format != overrideFormat) ? true : false);
- dstStream->setDataSpaceOverride((dst->data_space != overrideDataSpace) ? true : false);
-
+ bool needFormatOverride =
+ requestedConfiguration3_2.streams[i].format != src.v3_2.overrideFormat;
+ bool needDataspaceOverride =
+ requestedConfiguration3_2.streams[i].dataSpace != src.overrideDataSpace;
// Override allowed with IMPLEMENTATION_DEFINED
+ dstStream->setFormatOverride(needFormatOverride);
+ dstStream->setDataSpaceOverride(needDataspaceOverride);
dst->format = overrideFormat;
dst->data_space = overrideDataSpace;
}
diff --git a/services/camera/libcameraservice/device3/Camera3SharedOutputStream.cpp b/services/camera/libcameraservice/device3/Camera3SharedOutputStream.cpp
index e3b74d7..86b45cb 100644
--- a/services/camera/libcameraservice/device3/Camera3SharedOutputStream.cpp
+++ b/services/camera/libcameraservice/device3/Camera3SharedOutputStream.cpp
@@ -55,7 +55,7 @@
mStreamSplitter = new Camera3StreamSplitter(mUseHalBufManager);
- uint64_t usage;
+ uint64_t usage = 0;
getEndpointUsage(&usage);
std::unordered_map<size_t, sp<Surface>> initialSurfaces;
diff --git a/services/camera/libcameraservice/device3/Camera3Stream.cpp b/services/camera/libcameraservice/device3/Camera3Stream.cpp
index d73a2f9..2df084b 100644
--- a/services/camera/libcameraservice/device3/Camera3Stream.cpp
+++ b/services/camera/libcameraservice/device3/Camera3Stream.cpp
@@ -60,6 +60,8 @@
mUsage(0),
mOldUsage(0),
mOldMaxBuffers(0),
+ mOldFormat(-1),
+ mOldDataSpace(HAL_DATASPACE_UNKNOWN),
mPrepared(false),
mPrepareBlockRequest(true),
mPreparedBufferIdx(0),
@@ -67,6 +69,8 @@
mBufferLimitLatency(kBufferLimitLatencyBinSize),
mFormatOverridden(false),
mOriginalFormat(-1),
+ mDataSpaceOverridden(false),
+ mOriginalDataSpace(HAL_DATASPACE_UNKNOWN),
mPhysicalCameraId(physicalCameraId),
mLastTimestamp(0) {
@@ -121,7 +125,9 @@
void Camera3Stream::setFormatOverride(bool formatOverridden) {
mFormatOverridden = formatOverridden;
- if (formatOverridden) mOriginalFormat = camera3_stream::format;
+ if (formatOverridden && mOriginalFormat == -1) {
+ mOriginalFormat = camera3_stream::format;
+ }
}
bool Camera3Stream::isFormatOverridden() const {
@@ -134,7 +140,9 @@
void Camera3Stream::setDataSpaceOverride(bool dataSpaceOverridden) {
mDataSpaceOverridden = dataSpaceOverridden;
- if (dataSpaceOverridden) mOriginalDataSpace = camera3_stream::data_space;
+ if (dataSpaceOverridden && mOriginalDataSpace == HAL_DATASPACE_UNKNOWN) {
+ mOriginalDataSpace = camera3_stream::data_space;
+ }
}
bool Camera3Stream::isDataSpaceOverridden() const {
@@ -250,6 +258,8 @@
mOldUsage = mUsage;
mOldMaxBuffers = camera3_stream::max_buffers;
+ mOldFormat = camera3_stream::format;
+ mOldDataSpace = camera3_stream::data_space;
res = getEndpointUsage(&mUsage);
if (res != OK) {
@@ -324,7 +334,9 @@
// so. As documented in hardware/camera3.h:configure_streams().
if (mState == STATE_IN_RECONFIG &&
mOldUsage == mUsage &&
- mOldMaxBuffers == camera3_stream::max_buffers && !mDataSpaceOverridden) {
+ mOldMaxBuffers == camera3_stream::max_buffers &&
+ mOldDataSpace == camera3_stream::data_space &&
+ mOldFormat == camera3_stream::format) {
mState = STATE_CONFIGURED;
return OK;
}
diff --git a/services/camera/libcameraservice/device3/Camera3Stream.h b/services/camera/libcameraservice/device3/Camera3Stream.h
index c916fe8..533318f 100644
--- a/services/camera/libcameraservice/device3/Camera3Stream.h
+++ b/services/camera/libcameraservice/device3/Camera3Stream.h
@@ -540,8 +540,12 @@
uint64_t mUsage;
private:
+ // Previously configured stream properties (post HAL override)
uint64_t mOldUsage;
uint32_t mOldMaxBuffers;
+ int mOldFormat;
+ android_dataspace mOldDataSpace;
+
Condition mOutputBufferReturnedSignal;
Condition mInputBufferReturnedSignal;
static const nsecs_t kWaitForBufferDuration = 3000000000LL; // 3000 ms