Merge "CCodecBufferChannel: Resolve race condition around mComponent" into main
diff --git a/drm/drmserver/Android.bp b/drm/drmserver/Android.bp
index 81c2003..cee44b9 100644
--- a/drm/drmserver/Android.bp
+++ b/drm/drmserver/Android.bp
@@ -78,9 +78,6 @@
"libselinux",
"libstagefright_foundation",
],
- whole_static_libs: [
- "libc++fs",
- ],
cflags: [
"-Wall",
@@ -127,7 +124,6 @@
],
static_libs: [
- "libc++fs",
"libmediautils",
"liblog",
"libdrmframeworkcommon",
diff --git a/drm/libdrmframework/plugins/passthru/Android.bp b/drm/libdrmframework/plugins/passthru/Android.bp
index 0a6cd47..6ac7188 100644
--- a/drm/libdrmframework/plugins/passthru/Android.bp
+++ b/drm/libdrmframework/plugins/passthru/Android.bp
@@ -45,9 +45,6 @@
"libdl",
"libdrmframeworkcommon",
],
- whole_static_libs: [
- "libc++fs",
- ],
local_include_dirs: ["include"],
diff --git a/media/aconfig/codec_fwk.aconfig b/media/aconfig/codec_fwk.aconfig
index 14540b7..b5c7edf 100644
--- a/media/aconfig/codec_fwk.aconfig
+++ b/media/aconfig/codec_fwk.aconfig
@@ -13,6 +13,14 @@
}
flag {
+ name: "apv_support"
+ is_exported: true
+ namespace: "codec_fwk"
+ description: "Feature flag for Android support for APV Content"
+ bug: "375464302"
+}
+
+flag {
name: "codec_buffer_state_cleanup"
namespace: "codec_fwk"
description: "Bugfix flag for more buffer state cleanup in MediaCodec"
@@ -103,6 +111,14 @@
}
flag {
+ name: "p210_format_support"
+ is_exported: true
+ namespace: "codec_fwk"
+ description: "Feature flag for Android support for P210 YCbCr format"
+ bug: "368395888"
+}
+
+flag {
name: "region_of_interest"
is_exported: true
namespace: "codec_fwk"
diff --git a/media/codec2/sfplugin/CCodecBufferChannel.cpp b/media/codec2/sfplugin/CCodecBufferChannel.cpp
index e254af1..e2b28dc 100644
--- a/media/codec2/sfplugin/CCodecBufferChannel.cpp
+++ b/media/codec2/sfplugin/CCodecBufferChannel.cpp
@@ -41,6 +41,7 @@
#include <android/sysprop/MediaProperties.sysprop.h>
#include <android-base/parseint.h>
#include <android-base/properties.h>
+#include <android-base/no_destructor.h>
#include <android-base/stringprintf.h>
#include <binder/MemoryBase.h>
#include <binder/MemoryDealer.h>
@@ -115,6 +116,109 @@
});
}
+class SurfaceCallbackHandler {
+public:
+ enum callback_type_t {
+ ON_BUFFER_RELEASED = 0,
+ ON_BUFFER_ATTACHED
+ };
+
+ void post(callback_type_t callback,
+ std::shared_ptr<Codec2Client::Component> component,
+ uint32_t generation) {
+ if (!component) {
+ ALOGW("surface callback psoted for invalid component");
+ }
+ std::shared_ptr<SurfaceCallbackItem> item =
+ std::make_shared<SurfaceCallbackItem>(callback, component, generation);
+ std::unique_lock<std::mutex> lock(mMutex);
+ mItems.emplace_back(std::move(item));
+ mCv.notify_one();
+ }
+
+ ~SurfaceCallbackHandler() {
+ {
+ std::unique_lock<std::mutex> lock(mMutex);
+ mDone = true;
+ mCv.notify_all();
+ }
+ if (mThread.joinable()) {
+ mThread.join();
+ }
+ }
+
+ static SurfaceCallbackHandler& GetInstance() {
+ static base::NoDestructor<SurfaceCallbackHandler> sSurfaceCallbackHandler{};
+ return *sSurfaceCallbackHandler;
+ }
+
+private:
+ struct SurfaceCallbackItem {
+ callback_type_t mCallback;
+ std::weak_ptr<Codec2Client::Component> mComp;
+ uint32_t mGeneration;
+
+ SurfaceCallbackItem(
+ callback_type_t callback,
+ std::shared_ptr<Codec2Client::Component> comp,
+ uint32_t generation)
+ : mCallback(callback), mComp(comp), mGeneration(generation) {}
+ };
+
+ SurfaceCallbackHandler() { mThread = std::thread(&SurfaceCallbackHandler::run, this); }
+
+ void run() {
+ std::unique_lock<std::mutex> lock(mMutex);
+ while (!mDone) {
+ while (!mItems.empty()) {
+ std::deque<std::shared_ptr<SurfaceCallbackItem>> items = std::move(mItems);
+ mItems.clear();
+ lock.unlock();
+ handle(items);
+ lock.lock();
+ }
+ mCv.wait(lock);
+ }
+ }
+
+ void handle(std::deque<std::shared_ptr<SurfaceCallbackItem>> &items) {
+ while (!items.empty()) {
+ std::shared_ptr<SurfaceCallbackItem> item = items.front();
+ items.pop_front();
+ switch (item->mCallback) {
+ case ON_BUFFER_RELEASED: {
+ std::shared_ptr<Codec2Client::Component> comp = item->mComp.lock();;
+ if (comp) {
+ comp->onBufferReleasedFromOutputSurface(item->mGeneration);
+ }
+ break;
+ }
+ case ON_BUFFER_ATTACHED: {
+ std::shared_ptr<Codec2Client::Component> comp = item->mComp.lock();
+ if (comp) {
+ comp->onBufferAttachedToOutputSurface(item->mGeneration);
+ }
+ break;
+ }
+ default:
+ ALOGE("Non defined surface callback message");
+ break;
+ }
+ }
+ }
+
+ std::thread mThread;
+ bool mDone = false;
+ std::deque<std::shared_ptr<SurfaceCallbackItem>> mItems;
+ std::mutex mMutex;
+ std::condition_variable mCv;
+
+
+ friend class base::NoDestructor<SurfaceCallbackHandler>;
+
+ DISALLOW_EVIL_CONSTRUCTORS(SurfaceCallbackHandler);
+};
+
} // namespace
CCodecBufferChannel::QueueGuard::QueueGuard(
@@ -1503,7 +1607,8 @@
// during this interface being executed.
std::shared_ptr<Codec2Client::Component> comp = std::atomic_load(&mComponent);
if (comp) {
- comp->onBufferReleasedFromOutputSurface(generation);
+ SurfaceCallbackHandler::GetInstance().post(
+ SurfaceCallbackHandler::ON_BUFFER_RELEASED, comp, generation);
}
}
@@ -1514,7 +1619,8 @@
// during this interface being executed.
std::shared_ptr<Codec2Client::Component> comp = std::atomic_load(&mComponent);
if (comp) {
- comp->onBufferAttachedToOutputSurface(generation);
+ SurfaceCallbackHandler::GetInstance().post(
+ SurfaceCallbackHandler::ON_BUFFER_ATTACHED, comp, generation);
}
}
@@ -1801,6 +1907,7 @@
outputSurface = output->surface ?
output->surface->getIGraphicBufferProducer() : nullptr;
if (outputSurface) {
+ (void)SurfaceCallbackHandler::GetInstance();
output->surface->setMaxDequeuedBufferCount(output->maxDequeueBuffers);
}
outputGeneration = output->generation;
@@ -2731,6 +2838,7 @@
oldSurface = outputSurface->surface;
}
if (newSurface) {
+ (void)SurfaceCallbackHandler::GetInstance();
newSurface->setScalingMode(NATIVE_WINDOW_SCALING_MODE_SCALE_TO_WINDOW);
newSurface->setDequeueTimeout(kDequeueTimeoutNs);
newSurface->setMaxDequeuedBufferCount(maxDequeueCount);
diff --git a/media/janitors/media_solutions_OWNERS b/media/janitors/media_solutions_OWNERS
index 17bc7dd..3243726 100644
--- a/media/janitors/media_solutions_OWNERS
+++ b/media/janitors/media_solutions_OWNERS
@@ -1,22 +1,18 @@
# Bug component: 1344
# go/android-fwk-media-solutions for info on areas of ownership.
-# MediaRouter and native mirroring only:
-adadukin@google.com
-aquilescanta@google.com
-bishoygendy@google.com
-ivanbuper@google.com
-
-# MediaMuxer, MediaRecorder, and seamless transcoding only:
andrewlewis@google.com
-claincly@google.com
-
-# Everything in go/android-fwk-media-solutions not covered above:
bachinger@google.com
-christosts@google.com
+claincly@google.com
ibaker@google.com
+ivanbuper@google.com
jbibik@google.com
michaelkatz@google.com
rohks@google.com
+sheenachhabra@google.com
+simakova@google.com
tianyifeng@google.com
tonihei@google.com
+
+# MediaRouter and native mirroring only:
+aquilescanta@google.com
diff --git a/media/libaudiohal/impl/StreamHalAidl.cpp b/media/libaudiohal/impl/StreamHalAidl.cpp
index c4e4ae8..0d65f8c 100644
--- a/media/libaudiohal/impl/StreamHalAidl.cpp
+++ b/media/libaudiohal/impl/StreamHalAidl.cpp
@@ -367,8 +367,12 @@
if (!mStream) return NO_INIT;
StreamDescriptor::Reply reply;
RETURN_STATUS_IF_ERROR(updateCountersIfNeeded(&reply, statePositions));
- *frames = std::max<int64_t>(0, reply.observable.frames);
- *timestamp = std::max<int64_t>(0, reply.observable.timeNs);
+ if (reply.observable.frames == StreamDescriptor::Position::UNKNOWN ||
+ reply.observable.timeNs == StreamDescriptor::Position::UNKNOWN) {
+ return INVALID_OPERATION;
+ }
+ *frames = reply.observable.frames;
+ *timestamp = reply.observable.timeNs;
return OK;
}
@@ -377,8 +381,12 @@
if (!mStream) return NO_INIT;
StreamDescriptor::Reply reply;
RETURN_STATUS_IF_ERROR(updateCountersIfNeeded(&reply));
- *frames = std::max<int64_t>(0, reply.hardware.frames);
- *timestamp = std::max<int64_t>(0, reply.hardware.timeNs);
+ if (reply.hardware.frames == StreamDescriptor::Position::UNKNOWN ||
+ reply.hardware.timeNs == StreamDescriptor::Position::UNKNOWN) {
+ return INVALID_OPERATION;
+ }
+ *frames = reply.hardware.frames;
+ *timestamp = reply.hardware.timeNs;
return OK;
}
@@ -387,7 +395,10 @@
if (!mStream) return NO_INIT;
StreamDescriptor::Reply reply;
RETURN_STATUS_IF_ERROR(updateCountersIfNeeded(&reply));
- *frames = std::max<int32_t>(0, reply.xrunFrames);
+ if (reply.xrunFrames == StreamDescriptor::Position::UNKNOWN) {
+ return INVALID_OPERATION;
+ }
+ *frames = reply.xrunFrames;
return OK;
}
@@ -577,7 +588,9 @@
// For compatibility with HIDL behavior, apply a "soft" position reset
// after receiving the "drain ready" callback.
std::lock_guard l(mLock);
- mStatePositions.framesAtFlushOrDrain = mLastReply.observable.frames;
+ if (mLastReply.observable.frames != StreamDescriptor::Position::UNKNOWN) {
+ mStatePositions.framesAtFlushOrDrain = mLastReply.observable.frames;
+ }
} else {
AUGMENT_LOG(W, "unexpected onDrainReady in the state %s", toString(state).c_str());
}
@@ -670,7 +683,8 @@
}
mLastReply = *reply;
mLastReplyExpirationNs = uptimeNanos() + mLastReplyLifeTimeNs;
- if (!mIsInput && reply->status == STATUS_OK) {
+ if (!mIsInput && reply->status == STATUS_OK &&
+ reply->observable.frames != StreamDescriptor::Position::UNKNOWN) {
if (command.getTag() == StreamDescriptor::Command::standby &&
reply->state == StreamDescriptor::State::STANDBY) {
mStatePositions.framesAtStandby = reply->observable.frames;
diff --git a/media/libmedia/AudioCapabilities.cpp b/media/libmedia/AudioCapabilities.cpp
index e8cf517..1a92307 100644
--- a/media/libmedia/AudioCapabilities.cpp
+++ b/media/libmedia/AudioCapabilities.cpp
@@ -26,7 +26,7 @@
namespace android {
-const Range<int>& AudioCapabilities::getBitrateRange() const {
+const Range<int32_t>& AudioCapabilities::getBitrateRange() const {
return mBitrateRange;
}
@@ -86,7 +86,7 @@
}
void AudioCapabilities::initWithPlatformLimits() {
- mBitrateRange = Range<int>(0, INT_MAX);
+ mBitrateRange = Range<int>(0, INT32_MAX);
mInputChannelRanges.push_back(Range<int>(1, MAX_INPUT_CHANNEL_COUNT));
const int minSampleRate = base::GetIntProperty("ro.mediacodec.min_sample_rate", 7350);
@@ -94,30 +94,31 @@
mSampleRateRanges.push_back(Range<int>(minSampleRate, maxSampleRate));
}
-bool AudioCapabilities::supports(int sampleRate, int inputChannels) {
+bool AudioCapabilities::supports(std::optional<int> sampleRate,
+ std::optional<int> inputChannels) {
// channels and sample rates are checked orthogonally
- if (inputChannels != 0
+ if (inputChannels
&& !std::any_of(mInputChannelRanges.begin(), mInputChannelRanges.end(),
- [inputChannels](const Range<int> &a) { return a.contains(inputChannels); })) {
+ [inputChannels](const Range<int> &a) { return a.contains(inputChannels.value()); })) {
return false;
}
- if (sampleRate != 0
+ if (sampleRate
&& !std::any_of(mSampleRateRanges.begin(), mSampleRateRanges.end(),
- [sampleRate](const Range<int> &a) { return a.contains(sampleRate); })) {
+ [sampleRate](const Range<int> &a) { return a.contains(sampleRate.value()); })) {
return false;
}
return true;
}
bool AudioCapabilities::isSampleRateSupported(int sampleRate) {
- return supports(sampleRate, 0);
+ return supports(std::make_optional<int>(sampleRate), std::nullopt);
}
void AudioCapabilities::limitSampleRates(std::vector<int> rates) {
std::vector<Range<int>> sampleRateRanges;
std::sort(rates.begin(), rates.end());
for (int rate : rates) {
- if (supports(rate, 0 /* channels */)) {
+ if (supports(std::make_optional<int>(rate), std::nullopt /* channels */)) {
sampleRateRanges.push_back(Range<int>(rate, rate));
}
}
@@ -280,7 +281,7 @@
void AudioCapabilities::applyLimits(
const std::vector<Range<int>> &inputChannels,
- const std::optional<Range<int>> &bitRates) {
+ const std::optional<Range<int32_t>> &bitRates) {
// clamp & make a local copy
std::vector<Range<int>> inputChannelsCopy(inputChannels.size());
for (int i = 0; i < inputChannels.size(); i++) {
@@ -301,7 +302,7 @@
void AudioCapabilities::parseFromInfo(const sp<AMessage> &format) {
int maxInputChannels = MAX_INPUT_CHANNEL_COUNT;
std::vector<Range<int>> channels = { Range<int>(1, maxInputChannels) };
- std::optional<Range<int>> bitRates = POSITIVE_INTEGERS;
+ std::optional<Range<int32_t>> bitRates = POSITIVE_INT32;
AString rateAString;
if (format->findString("sample-rate-ranges", &rateAString)) {
@@ -348,7 +349,7 @@
}
if (format->findString("bitrate-range", &valueStr)) {
- std::optional<Range<int>> parsedBitrate = ParseIntRange(valueStr.c_str());
+ std::optional<Range<int32_t>> parsedBitrate = ParseIntRange(valueStr.c_str());
if (parsedBitrate) {
bitRates = bitRates.value().intersect(parsedBitrate.value());
}
@@ -372,10 +373,12 @@
}
bool AudioCapabilities::supportsFormat(const sp<AMessage> &format) {
- int32_t sampleRate;
- format->findInt32(KEY_SAMPLE_RATE, &sampleRate);
- int32_t channels;
- format->findInt32(KEY_CHANNEL_COUNT, &channels);
+ int32_t sampleRateValue;
+ std::optional<int> sampleRate = format->findInt32(KEY_SAMPLE_RATE, &sampleRateValue)
+ ? std::make_optional<int>(sampleRateValue) : std::nullopt;
+ int32_t channelsValue;
+ std::optional<int> channels = format->findInt32(KEY_CHANNEL_COUNT, &channelsValue)
+ ? std::make_optional<int>(channelsValue) : std::nullopt;
if (!supports(sampleRate, channels)) {
return false;
diff --git a/media/libmedia/CodecCapabilities.cpp b/media/libmedia/CodecCapabilities.cpp
index 5bed1c4..87eb4bc 100644
--- a/media/libmedia/CodecCapabilities.cpp
+++ b/media/libmedia/CodecCapabilities.cpp
@@ -25,7 +25,7 @@
namespace android {
-bool CodecCapabilities::SupportsBitrate(Range<int> bitrateRange,
+bool CodecCapabilities::SupportsBitrate(Range<int32_t> bitrateRange,
const sp<AMessage> &format) {
// consider max bitrate over average bitrate for support
int32_t maxBitrate = 0;
diff --git a/media/libmedia/include/media/AudioCapabilities.h b/media/libmedia/include/media/AudioCapabilities.h
index 2bc3335..d2bd9d7 100644
--- a/media/libmedia/include/media/AudioCapabilities.h
+++ b/media/libmedia/include/media/AudioCapabilities.h
@@ -37,7 +37,7 @@
/**
* Returns the range of supported bitrates in bits/second.
*/
- const Range<int>& getBitrateRange() const;
+ const Range<int32_t>& getBitrateRange() const;
/**
* Returns the array of supported sample rates if the codec
@@ -110,7 +110,7 @@
std::string mMediaType;
std::vector<ProfileLevel> mProfileLevels;
- Range<int> mBitrateRange;
+ Range<int32_t> mBitrateRange;
std::vector<int> mSampleRates;
std::vector<Range<int>> mSampleRateRanges;
@@ -121,13 +121,13 @@
void init(std::string mediaType, std::vector<ProfileLevel> profLevs,
const sp<AMessage> &format);
void initWithPlatformLimits();
- bool supports(int sampleRate, int inputChannels);
+ bool supports(std::optional<int> sampleRate, std::optional<int> inputChannels);
void limitSampleRates(std::vector<int> rates);
void createDiscreteSampleRates();
void limitSampleRates(std::vector<Range<int>> rateRanges);
void applyLevelLimits();
void applyLimits(const std::vector<Range<int>> &inputChannels,
- const std::optional<Range<int>> &bitRates);
+ const std::optional<Range<int32_t>> &bitRates);
void parseFromInfo(const sp<AMessage> &format);
friend struct CodecCapabilities;
diff --git a/media/libmedia/include/media/CodecCapabilities.h b/media/libmedia/include/media/CodecCapabilities.h
index 9d1c4ea..570c8b5 100644
--- a/media/libmedia/include/media/CodecCapabilities.h
+++ b/media/libmedia/include/media/CodecCapabilities.h
@@ -34,7 +34,7 @@
struct CodecCapabilities {
- static bool SupportsBitrate(Range<int> bitrateRange,
+ static bool SupportsBitrate(Range<int32_t> bitrateRange,
const sp<AMessage> &format);
/**
diff --git a/media/libmedia/include/media/CodecCapabilitiesUtils.h b/media/libmedia/include/media/CodecCapabilitiesUtils.h
index 2bf822a..89a452c 100644
--- a/media/libmedia/include/media/CodecCapabilitiesUtils.h
+++ b/media/libmedia/include/media/CodecCapabilitiesUtils.h
@@ -118,7 +118,7 @@
T upper_;
};
-static const Range<int> POSITIVE_INTEGERS = Range<int>(1, INT_MAX);
+static const Range<int32_t> POSITIVE_INT32 = Range<int32_t>(1, INT32_MAX);
// found stuff that is not supported by framework (=> this should not happen)
constexpr int ERROR_CAPABILITIES_UNRECOGNIZED = (1 << 0);
diff --git a/media/libmedia/tests/codeccapabilities/CodecCapabilitiesTest.cpp b/media/libmedia/tests/codeccapabilities/CodecCapabilitiesTest.cpp
index 89c9739..02e43a4 100644
--- a/media/libmedia/tests/codeccapabilities/CodecCapabilitiesTest.cpp
+++ b/media/libmedia/tests/codeccapabilities/CodecCapabilitiesTest.cpp
@@ -64,7 +64,7 @@
};
TEST_F(AudioCapsAacTest, AudioCaps_Aac_Bitrate) {
- const Range<int>& bitrateRange = audioCaps->getBitrateRange();
+ const Range<int32_t>& bitrateRange = audioCaps->getBitrateRange();
EXPECT_EQ(bitrateRange.lower(), 8000) << "bitrate range1 does not match. lower: "
<< bitrateRange.lower();
EXPECT_EQ(bitrateRange.upper(), 510000) << "bitrate range1 does not match. upper: "
@@ -114,7 +114,7 @@
};
TEST_F(AudioCapsRawTest, AudioCaps_Raw_Bitrate) {
- const Range<int>& bitrateRange = audioCaps->getBitrateRange();
+ const Range<int32_t>& bitrateRange = audioCaps->getBitrateRange();
EXPECT_EQ(bitrateRange.lower(), 1);
EXPECT_EQ(bitrateRange.upper(), 10000000);
}
diff --git a/services/audioflinger/RecordTracks.h b/services/audioflinger/RecordTracks.h
index 3de9968..83cd024 100644
--- a/services/audioflinger/RecordTracks.h
+++ b/services/audioflinger/RecordTracks.h
@@ -73,7 +73,7 @@
bool isDirect() const final
{ return (mFlags & AUDIO_INPUT_FLAG_DIRECT) != 0; }
- void setSilenced(bool silenced) final { if (!isPatchTrack()) mSilenced = silenced; }
+ void setSilenced(bool silenced) final;
bool isSilenced() const final { return mSilenced; }
status_t getActiveMicrophones(
diff --git a/services/audioflinger/Threads.cpp b/services/audioflinger/Threads.cpp
index 147a5d6..b7c0bb3 100644
--- a/services/audioflinger/Threads.cpp
+++ b/services/audioflinger/Threads.cpp
@@ -7731,6 +7731,7 @@
ssize_t DuplicatingThread::threadLoop_write()
{
+ ATRACE_BEGIN("write");
for (size_t i = 0; i < outputTracks.size(); i++) {
const ssize_t actualWritten = outputTracks[i]->write(mSinkBuffer, writeFrames);
@@ -7749,6 +7750,7 @@
// TODO: Report correction for the other output tracks and show in the dump.
}
+ ATRACE_END();
if (mStandby) {
mThreadMetrics.logBeginInterval();
mThreadSnapshot.onBegin();
diff --git a/services/audioflinger/Tracks.cpp b/services/audioflinger/Tracks.cpp
index f5f11cc..3d4e771 100644
--- a/services/audioflinger/Tracks.cpp
+++ b/services/audioflinger/Tracks.cpp
@@ -3136,6 +3136,14 @@
*backInserter++ = metadata;
}
+void RecordTrack::setSilenced(bool silenced) {
+ if (!isPatchTrack() && mSilenced != silenced) {
+ mSilenced = silenced;
+ ALOGD("%s: track with port id: %d, (%s)", __func__, mPortId,
+ mSilenced ? "silenced" : "unsilenced");
+ }
+}
+
// ----------------------------------------------------------------------------
#undef LOG_TAG
#define LOG_TAG "AF::PatchRecord"