Snap for 10750748 from 41d5a03355a8d00064790ce83b793e69e8e0832d to mainline-cellbroadcast-release
Change-Id: Ia01ac7ac5914462d662e6f32ee9172f39189ae70
diff --git a/camera/ndk/include/camera/NdkCameraMetadataTags.h b/camera/ndk/include/camera/NdkCameraMetadataTags.h
index af00e55..4a589bc 100644
--- a/camera/ndk/include/camera/NdkCameraMetadataTags.h
+++ b/camera/ndk/include/camera/NdkCameraMetadataTags.h
@@ -584,6 +584,13 @@
* <p>Only constrains auto-exposure (AE) algorithm, not
* manual control of ACAMERA_SENSOR_EXPOSURE_TIME and
* ACAMERA_SENSOR_FRAME_DURATION.</p>
+ * <p>To start a CaptureSession with a target FPS range different from the
+ * capture request template's default value, the application
+ * is strongly recommended to call
+ * {@link ACameraDevice_createCaptureSessionWithSessionParameters }
+ * with the target fps range before creating the capture session. The aeTargetFpsRange is
+ * typically a session parameter. Specifying it at session creation time helps avoid
+ * session reconfiguration delays in cases like 60fps or high speed recording.</p>
*
* @see ACAMERA_SENSOR_EXPOSURE_TIME
* @see ACAMERA_SENSOR_FRAME_DURATION
@@ -1128,6 +1135,12 @@
* ACAMERA_CONTROL_VIDEO_STABILIZATION_MODE field will return
* OFF if the recording output is not stabilized, or if there are no output
* Surface types that can be stabilized.</p>
+ * <p>The application is strongly recommended to call
+ * {@link ACameraDevice_createCaptureSessionWithSessionParameters }
+ * with the desired video stabilization mode before creating the capture session.
+ * Video stabilization mode is a session parameter on many devices. Specifying
+ * it at session creation time helps avoid reconfiguration delay caused by difference
+ * between the default value and the first CaptureRequest.</p>
* <p>If a camera device supports both this mode and OIS
* (ACAMERA_LENS_OPTICAL_STABILIZATION_MODE), turning both modes on may
* produce undesirable interaction, so it is recommended not to enable
diff --git a/media/codec2/components/aac/C2SoftAacEnc.cpp b/media/codec2/components/aac/C2SoftAacEnc.cpp
index d865ab2..721a12a 100644
--- a/media/codec2/components/aac/C2SoftAacEnc.cpp
+++ b/media/codec2/components/aac/C2SoftAacEnc.cpp
@@ -69,7 +69,7 @@
addParameter(
DefineParam(mChannelCount, C2_PARAMKEY_CHANNEL_COUNT)
.withDefault(new C2StreamChannelCountInfo::input(0u, 1))
- .withFields({C2F(mChannelCount, value).inRange(1, 6)})
+ .withFields({C2F(mChannelCount, value).inRange(1, kMaxChannelCount)})
.withSetter(Setter<decltype(*mChannelCount)>::StrictValueWithNoDeps)
.build());
@@ -198,10 +198,17 @@
}
c2_status_t C2SoftAacEnc::onFlush_sm() {
+ if (mAACEncoder != nullptr) {
+ /* encoder's internal input buffer needs to be reset during flush */
+ if (AACENC_OK != aacEncoder_SetParam(mAACEncoder, AACENC_CONTROL_STATE, AACENC_INIT_ALL)) {
+ ALOGE("Failed to reset AAC encoder");
+ }
+ }
mSentCodecSpecificData = false;
mInputSize = 0u;
mNextFrameTimestampUs.reset();
mLastFrameEndTimestampUs.reset();
+ mRemainderLen = 0;
return C2_OK;
}
@@ -562,6 +569,11 @@
inBufferSize[0] -= outargs.numInSamples * sizeof(int16_t);
inargs.numInSamples -= outargs.numInSamples;
}
+ } else {
+ // In case of error in encode call, discard remaining input bytes.
+ inBuffer[0] = nullptr;
+ inBufferSize[0] = 0;
+ inargs.numInSamples = 0;
}
ALOGV("encoderErr = %d mInputSize = %zu "
"inargs.numInSamples = %d, mNextFrameTimestampUs = %lld",
@@ -597,10 +609,19 @@
&outBufDesc,
&inargs,
&outargs);
+
+ // after flush, discard remaining input bytes.
+ inBuffer[0] = nullptr;
inBufferSize[0] = 0;
}
if (inBufferSize[0] > 0) {
+ if (inBufferSize[0] > kRemainderBufSize) {
+ ALOGE("Remaining bytes %d greater than remainder buffer size %zu", inBufferSize[0],
+ kRemainderBufSize);
+ work->result = C2_CORRUPTED;
+ return;
+ }
for (size_t i = 0; i < inBufferSize[0]; ++i) {
mRemainder[i] = static_cast<uint8_t *>(inBuffer[0])[i];
}
diff --git a/media/codec2/components/aac/C2SoftAacEnc.h b/media/codec2/components/aac/C2SoftAacEnc.h
index 9a28280..c79526c 100644
--- a/media/codec2/components/aac/C2SoftAacEnc.h
+++ b/media/codec2/components/aac/C2SoftAacEnc.h
@@ -47,6 +47,9 @@
const std::shared_ptr<C2BlockPool> &pool) override;
private:
+ static constexpr size_t kMaxChannelCount = 6;
+ static constexpr size_t kRemainderBufSize = kMaxChannelCount * sizeof(int16_t);
+
std::shared_ptr<IntfImpl> mIntf;
HANDLE_AACENCODER mAACEncoder;
@@ -63,7 +66,7 @@
std::atomic_uint64_t mOutIndex;
// We support max 6 channels
- uint8_t mRemainder[6 * sizeof(int16_t)];
+ uint8_t mRemainder[kRemainderBufSize];
size_t mRemainderLen;
status_t initEncoder();
diff --git a/media/codec2/components/gav1/C2SoftGav1Dec.cpp b/media/codec2/components/gav1/C2SoftGav1Dec.cpp
index 3e4247b..d9c5d29 100644
--- a/media/codec2/components/gav1/C2SoftGav1Dec.cpp
+++ b/media/codec2/components/gav1/C2SoftGav1Dec.cpp
@@ -773,6 +773,14 @@
return false;
}
+ if (buffer->bitdepth > 10) {
+ ALOGE("bitdepth %d is not supported", buffer->bitdepth);
+ mSignalledError = true;
+ work->workletsProcessed = 1u;
+ work->result = C2_CORRUPTED;
+ return false;
+ }
+
const int width = buffer->displayed_width[0];
const int height = buffer->displayed_height[0];
if (width != mWidth || height != mHeight) {
diff --git a/media/codec2/sfplugin/CCodecBufferChannel.cpp b/media/codec2/sfplugin/CCodecBufferChannel.cpp
index d72d228..feca03d 100644
--- a/media/codec2/sfplugin/CCodecBufferChannel.cpp
+++ b/media/codec2/sfplugin/CCodecBufferChannel.cpp
@@ -67,6 +67,7 @@
using hardware::hidl_vec;
using hardware::fromHeap;
using hardware::HidlMemory;
+using server_configurable_flags::GetServerConfigurableFlag;
using namespace hardware::cas::V1_0;
using namespace hardware::cas::native::V1_0;
@@ -82,6 +83,11 @@
// than making it non-blocking. Do not change this value.
const static size_t kDequeueTimeoutNs = 0;
+static bool areRenderMetricsEnabled() {
+ std::string v = GetServerConfigurableFlag("media_native", "render_metrics_enabled", "false");
+ return v == "true";
+}
+
} // namespace
CCodecBufferChannel::QueueGuard::QueueGuard(
@@ -148,6 +154,7 @@
mCCodecCallback(callback),
mFrameIndex(0u),
mFirstValidFrameIndex(0u),
+ mAreRenderMetricsEnabled(areRenderMetricsEnabled()),
mIsSurfaceToDisplay(false),
mHasPresentFenceTimes(false),
mRenderingDepth(3u),
@@ -174,8 +181,7 @@
Mutexed<BlockPools>::Locked pools(mBlockPools);
pools->outputPoolId = C2BlockPool::BASIC_LINEAR;
}
- std::string value = server_configurable_flags::GetServerConfigurableFlag(
- "media_native", "ccodec_rendering_depth", "3");
+ std::string value = GetServerConfigurableFlag("media_native", "ccodec_rendering_depth", "3");
android::base::ParseInt(value, &mRenderingDepth);
mOutputSurface.lock()->maxDequeueBuffers = kSmoothnessFactor + mRenderingDepth;
}
@@ -996,7 +1002,7 @@
int64_t mediaTimeUs = 0;
(void)buffer->meta()->findInt64("timeUs", &mediaTimeUs);
- if (mIsSurfaceToDisplay) {
+ if (mAreRenderMetricsEnabled && mIsSurfaceToDisplay) {
trackReleasedFrame(qbo, mediaTimeUs, timestampNs);
processRenderedFrames(qbo.frameTimestamps);
} else {
diff --git a/media/codec2/sfplugin/CCodecBufferChannel.h b/media/codec2/sfplugin/CCodecBufferChannel.h
index 2d87aa9..41f5ae2 100644
--- a/media/codec2/sfplugin/CCodecBufferChannel.h
+++ b/media/codec2/sfplugin/CCodecBufferChannel.h
@@ -334,6 +334,7 @@
sp<MemoryDealer> makeMemoryDealer(size_t heapSize);
std::deque<TrackedFrame> mTrackedFrames;
+ bool mAreRenderMetricsEnabled;
bool mIsSurfaceToDisplay;
bool mHasPresentFenceTimes;
diff --git a/media/codec2/sfplugin/utils/Codec2CommonUtils.cpp b/media/codec2/sfplugin/utils/Codec2CommonUtils.cpp
index f428fce..43533fd 100644
--- a/media/codec2/sfplugin/utils/Codec2CommonUtils.cpp
+++ b/media/codec2/sfplugin/utils/Codec2CommonUtils.cpp
@@ -31,11 +31,19 @@
namespace android {
-bool isAtLeastT() {
+
+static bool isAtLeast(int version, const char *codeName) {
char deviceCodeName[PROP_VALUE_MAX];
__system_property_get("ro.build.version.codename", deviceCodeName);
- return android_get_device_api_level() >= __ANDROID_API_T__ ||
- !strcmp(deviceCodeName, "Tiramisu");
+ return android_get_device_api_level() >= version || !strcmp(deviceCodeName, codeName);
+}
+
+bool isAtLeastT() {
+ return isAtLeast(__ANDROID_API_T__, "Tiramisu");
+}
+
+bool isAtLeastU() {
+ return isAtLeast(__ANDROID_API_U__, "UpsideDownCake");
}
static bool isP010Allowed() {
@@ -127,10 +135,16 @@
.rfu0 = 0,
.rfu1 = 0,
};
-
- return AHardwareBuffer_isSupported(&consumableForDisplayOrGpu)
- && AHardwareBuffer_isSupported(&consumableForHwEncoder)
- && AHardwareBuffer_isSupported(&consumableForSwEncoder);
+ // Some devices running versions prior to Android U aren't guaranteed to advertise support
+ // for some color formats when the consumer is an encoder. Hence limit these checks to
+ // Android U and beyond.
+ if (isAtLeastU()) {
+ return AHardwareBuffer_isSupported(&consumableForDisplayOrGpu)
+ && AHardwareBuffer_isSupported(&consumableForHwEncoder)
+ && AHardwareBuffer_isSupported(&consumableForSwEncoder);
+ } else {
+ return AHardwareBuffer_isSupported(&consumableForDisplayOrGpu);
+ }
}
} // namespace android
diff --git a/media/codec2/sfplugin/utils/Codec2CommonUtils.h b/media/codec2/sfplugin/utils/Codec2CommonUtils.h
index 98dd65b..9bb52bd 100644
--- a/media/codec2/sfplugin/utils/Codec2CommonUtils.h
+++ b/media/codec2/sfplugin/utils/Codec2CommonUtils.h
@@ -23,6 +23,8 @@
bool isAtLeastT();
+bool isAtLeastU();
+
bool isVendorApiOrFirstApiAtLeastT();
/**
diff --git a/media/libstagefright/MediaCodec.cpp b/media/libstagefright/MediaCodec.cpp
index e0ebc11..2970aab 100644
--- a/media/libstagefright/MediaCodec.cpp
+++ b/media/libstagefright/MediaCodec.cpp
@@ -92,6 +92,7 @@
using aidl::android::media::IResourceManagerClient;
using aidl::android::media::IResourceManagerService;
using aidl::android::media::ClientInfoParcel;
+using server_configurable_flags::GetServerConfigurableFlag;
using FreezeEvent = VideoRenderQualityTracker::FreezeEvent;
using JudderEvent = VideoRenderQualityTracker::JudderEvent;
@@ -282,6 +283,11 @@
return (err == NO_MEMORY);
}
+static bool areRenderMetricsEnabled() {
+ std::string v = GetServerConfigurableFlag("media_native", "render_metrics_enabled", "false");
+ return v == "true";
+}
+
static const int kMaxRetry = 2;
static const int kMaxReclaimWaitTimeInUs = 500000; // 0.5s
static const int kNumBuffersAlign = 16;
@@ -1025,9 +1031,10 @@
mHavePendingInputBuffers(false),
mCpuBoostRequested(false),
mIsSurfaceToDisplay(false),
+ mAreRenderMetricsEnabled(areRenderMetricsEnabled()),
mVideoRenderQualityTracker(
VideoRenderQualityTracker::Configuration::getFromServerConfigurableFlags(
- server_configurable_flags::GetServerConfigurableFlag)),
+ GetServerConfigurableFlag)),
mLatencyUnknown(0),
mBytesEncoded(0),
mEarliestEncodedPtsUs(INT64_MAX),
@@ -6044,7 +6051,7 @@
// If rendering to the screen, then schedule a time in the future to poll to see if this
// frame was ever rendered to seed onFrameRendered callbacks.
- if (mIsSurfaceToDisplay) {
+ if (mAreRenderMetricsEnabled && mIsSurfaceToDisplay) {
if (mediaTimeUs != INT64_MIN) {
noRenderTime ? mVideoRenderQualityTracker.onFrameReleased(mediaTimeUs)
: mVideoRenderQualityTracker.onFrameReleased(mediaTimeUs,
diff --git a/media/libstagefright/VideoRenderQualityTracker.cpp b/media/libstagefright/VideoRenderQualityTracker.cpp
index 4f12a37..fbd8577 100644
--- a/media/libstagefright/VideoRenderQualityTracker.cpp
+++ b/media/libstagefright/VideoRenderQualityTracker.cpp
@@ -154,7 +154,7 @@
}
VideoRenderQualityTracker::Configuration::Configuration() {
- enabled = true;
+ enabled = false;
// Assume that the app is skipping frames because it's detected that the frame couldn't be
// rendered in time.
diff --git a/media/libstagefright/include/media/stagefright/MediaCodec.h b/media/libstagefright/include/media/stagefright/MediaCodec.h
index 52d7d3d..163408d 100644
--- a/media/libstagefright/include/media/stagefright/MediaCodec.h
+++ b/media/libstagefright/include/media/stagefright/MediaCodec.h
@@ -572,6 +572,7 @@
sp<ALooper> mCryptoLooper;
bool mIsSurfaceToDisplay;
+ bool mAreRenderMetricsEnabled;
PlaybackDurationAccumulator mPlaybackDurationAccumulator;
VideoRenderQualityTracker mVideoRenderQualityTracker;
diff --git a/media/mtp/MtpFfsHandle.cpp b/media/mtp/MtpFfsHandle.cpp
index 2ffd775..ef8c9aa 100644
--- a/media/mtp/MtpFfsHandle.cpp
+++ b/media/mtp/MtpFfsHandle.cpp
@@ -297,6 +297,10 @@
}
void MtpFfsHandle::close() {
+ auto timeout = std::chrono::seconds(2);
+ std::unique_lock lk(m);
+ cv.wait_for(lk, timeout ,[this]{return child_threads==0;});
+
io_destroy(mCtx);
closeEndpoints();
closeConfig();
@@ -669,6 +673,11 @@
char *temp = new char[me.length];
memcpy(temp, me.data, me.length);
me.data = temp;
+
+ std::unique_lock lk(m);
+ child_threads++;
+ lk.unlock();
+
std::thread t([this, me]() { return this->doSendEvent(me); });
t.detach();
return 0;
@@ -680,6 +689,11 @@
if (static_cast<unsigned>(ret) != length)
PLOG(ERROR) << "Mtp error sending event thread!";
delete[] reinterpret_cast<char*>(me.data);
+
+ std::unique_lock lk(m);
+ child_threads--;
+ lk.unlock();
+ cv.notify_one();
}
} // namespace android
diff --git a/media/mtp/MtpFfsHandle.h b/media/mtp/MtpFfsHandle.h
index e552e03..51cdef0 100644
--- a/media/mtp/MtpFfsHandle.h
+++ b/media/mtp/MtpFfsHandle.h
@@ -60,6 +60,10 @@
bool mCanceled;
bool mBatchCancel;
+ std::mutex m;
+ std::condition_variable cv;
+ std::atomic<int> child_threads{0};
+
android::base::unique_fd mControl;
// "in" from the host's perspective => sink for mtp server
android::base::unique_fd mBulkIn;
diff --git a/media/mtp/MtpPacket.cpp b/media/mtp/MtpPacket.cpp
index f069a83..5faaac2 100644
--- a/media/mtp/MtpPacket.cpp
+++ b/media/mtp/MtpPacket.cpp
@@ -92,24 +92,46 @@
}
uint16_t MtpPacket::getUInt16(int offset) const {
- return ((uint16_t)mBuffer[offset + 1] << 8) | (uint16_t)mBuffer[offset];
+ if ((unsigned long)(offset+2) <= mBufferSize) {
+ return ((uint16_t)mBuffer[offset + 1] << 8) | (uint16_t)mBuffer[offset];
+ }
+ else {
+ ALOGE("offset for buffer read is greater than buffer size!");
+ abort();
+ }
}
uint32_t MtpPacket::getUInt32(int offset) const {
- return ((uint32_t)mBuffer[offset + 3] << 24) | ((uint32_t)mBuffer[offset + 2] << 16) |
- ((uint32_t)mBuffer[offset + 1] << 8) | (uint32_t)mBuffer[offset];
+ if ((unsigned long)(offset+4) <= mBufferSize) {
+ return ((uint32_t)mBuffer[offset + 3] << 24) | ((uint32_t)mBuffer[offset + 2] << 16) |
+ ((uint32_t)mBuffer[offset + 1] << 8) | (uint32_t)mBuffer[offset];
+ }
+ else {
+ ALOGE("offset for buffer read is greater than buffer size!");
+ abort();
+ }
}
void MtpPacket::putUInt16(int offset, uint16_t value) {
- mBuffer[offset++] = (uint8_t)(value & 0xFF);
- mBuffer[offset++] = (uint8_t)((value >> 8) & 0xFF);
+ if ((unsigned long)(offset+2) <= mBufferSize) {
+ mBuffer[offset++] = (uint8_t)(value & 0xFF);
+ mBuffer[offset++] = (uint8_t)((value >> 8) & 0xFF);
+ }
+ else {
+ ALOGE("offset for buffer write is greater than buffer size!");
+ }
}
void MtpPacket::putUInt32(int offset, uint32_t value) {
- mBuffer[offset++] = (uint8_t)(value & 0xFF);
- mBuffer[offset++] = (uint8_t)((value >> 8) & 0xFF);
- mBuffer[offset++] = (uint8_t)((value >> 16) & 0xFF);
- mBuffer[offset++] = (uint8_t)((value >> 24) & 0xFF);
+ if ((unsigned long)(offset+4) <= mBufferSize) {
+ mBuffer[offset++] = (uint8_t)(value & 0xFF);
+ mBuffer[offset++] = (uint8_t)((value >> 8) & 0xFF);
+ mBuffer[offset++] = (uint8_t)((value >> 16) & 0xFF);
+ mBuffer[offset++] = (uint8_t)((value >> 24) & 0xFF);
+ }
+ else {
+ ALOGE("offset for buffer write is greater than buffer size!");
+ }
}
uint16_t MtpPacket::getContainerCode() const {