Merge "NuPlayer: Fix ANR while resetting RTSP playback" into qt-dev
diff --git a/camera/ndk/ndk_vendor/impl/ACameraDevice.cpp b/camera/ndk/ndk_vendor/impl/ACameraDevice.cpp
index b18c897..1fdff40 100644
--- a/camera/ndk/ndk_vendor/impl/ACameraDevice.cpp
+++ b/camera/ndk/ndk_vendor/impl/ACameraDevice.cpp
@@ -87,7 +87,7 @@
__FUNCTION__, strerror(-err), err);
setCameraDeviceErrorLocked(ACAMERA_ERROR_CAMERA_DEVICE);
}
- mHandler = new CallbackHandler();
+ mHandler = new CallbackHandler(id);
mCbLooper->registerHandler(mHandler);
const CameraMetadata& metadata = mChars->getInternalData();
@@ -918,6 +918,8 @@
return;
}
+CameraDevice::CallbackHandler::CallbackHandler(const char *id) : mId(id) { }
+
void CameraDevice::CallbackHandler::onMessageReceived(
const sp<AMessage> &msg) {
switch (msg->what()) {
@@ -1012,9 +1014,9 @@
return;
}
sp<ACameraCaptureSession> session(static_cast<ACameraCaptureSession*>(obj.get()));
- ACameraDevice* device = session->getDevice();
mCachedSessions.push(session);
sp<CaptureRequest> requestSp = nullptr;
+ const char *id_cstr = mId.c_str();
switch (msg->what()) {
case kWhatCaptureStart:
case kWhatCaptureResult:
@@ -1063,7 +1065,7 @@
ALOGE("%s: Cannot find timestamp!", __FUNCTION__);
return;
}
- ACaptureRequest* request = allocateACaptureRequest(requestSp, device->getId());
+ ACaptureRequest* request = allocateACaptureRequest(requestSp, id_cstr);
(*onStart)(context, session.get(), request, timestamp);
freeACaptureRequest(request);
break;
@@ -1086,7 +1088,7 @@
return;
}
sp<ACameraMetadata> result(static_cast<ACameraMetadata*>(obj.get()));
- ACaptureRequest* request = allocateACaptureRequest(requestSp, device->getId());
+ ACaptureRequest* request = allocateACaptureRequest(requestSp, id_cstr);
(*onResult)(context, session.get(), request, result.get());
freeACaptureRequest(request);
break;
@@ -1139,7 +1141,7 @@
physicalMetadataCopyPtrs.push_back(physicalMetadataCopy[i].get());
}
- ACaptureRequest* request = allocateACaptureRequest(requestSp, device->getId());
+ ACaptureRequest* request = allocateACaptureRequest(requestSp, id_cstr);
(*onResult)(context, session.get(), request, result.get(),
physicalResultInfo.size(), physicalCameraIdPtrs.data(),
physicalMetadataCopyPtrs.data());
@@ -1168,7 +1170,7 @@
static_cast<CameraCaptureFailure*>(obj.get()));
ACameraCaptureFailure* failure =
static_cast<ACameraCaptureFailure*>(failureSp.get());
- ACaptureRequest* request = allocateACaptureRequest(requestSp, device->getId());
+ ACaptureRequest* request = allocateACaptureRequest(requestSp, id_cstr);
(*onFail)(context, session.get(), request, failure);
freeACaptureRequest(request);
break;
@@ -1201,7 +1203,7 @@
failure.physicalCameraId = nullptr;
}
failure.captureFailure = *failureSp;
- ACaptureRequest* request = allocateACaptureRequest(requestSp, device->getId());
+ ACaptureRequest* request = allocateACaptureRequest(requestSp, id_cstr);
(*onFail)(context, session.get(), request, &failure);
freeACaptureRequest(request);
break;
@@ -1278,7 +1280,7 @@
return;
}
- ACaptureRequest* request = allocateACaptureRequest(requestSp, device->getId());
+ ACaptureRequest* request = allocateACaptureRequest(requestSp, id_cstr);
(*onBufferLost)(context, session.get(), request, anw, frameNumber);
freeACaptureRequest(request);
break;
diff --git a/camera/ndk/ndk_vendor/impl/ACameraDevice.h b/camera/ndk/ndk_vendor/impl/ACameraDevice.h
index 7036017..829b084 100644
--- a/camera/ndk/ndk_vendor/impl/ACameraDevice.h
+++ b/camera/ndk/ndk_vendor/impl/ACameraDevice.h
@@ -266,9 +266,11 @@
class CallbackHandler : public AHandler {
public:
+ explicit CallbackHandler(const char *id);
void onMessageReceived(const sp<AMessage> &msg) override;
private:
+ std::string mId;
// This handler will cache all capture session sp until kWhatCleanUpSessions
// is processed. This is used to guarantee the last session reference is always
// being removed in callback thread without holding camera device lock
diff --git a/media/codec2/components/vorbis/C2SoftVorbisDec.cpp b/media/codec2/components/vorbis/C2SoftVorbisDec.cpp
index e7393ee..e3bafd3 100644
--- a/media/codec2/components/vorbis/C2SoftVorbisDec.cpp
+++ b/media/codec2/components/vorbis/C2SoftVorbisDec.cpp
@@ -270,7 +270,8 @@
const uint8_t *data = rView.data() + inOffset;
int32_t numChannels = mVi->channels;
int32_t samplingRate = mVi->rate;
- if (inSize > 7 && !memcmp(&data[1], "vorbis", 6)) {
+ /* Decode vorbis headers only once */
+ if (inSize > 7 && !memcmp(&data[1], "vorbis", 6) && (!mInfoUnpacked || !mBooksUnpacked)) {
if ((data[0] != 1) && (data[0] != 5)) {
ALOGE("unexpected type received %d", data[0]);
mSignalledError = true;
diff --git a/media/codec2/hidl/1.0/utils/Android.bp b/media/codec2/hidl/1.0/utils/Android.bp
index b2a5fee..b73f0c8 100644
--- a/media/codec2/hidl/1.0/utils/Android.bp
+++ b/media/codec2/hidl/1.0/utils/Android.bp
@@ -99,6 +99,7 @@
export_shared_lib_headers: [
"android.hardware.media.c2@1.0",
"libcodec2",
+ "libcodec2_vndk",
"libhidlbase",
"libstagefright_bufferpool@2.0",
"libui",
diff --git a/media/codec2/hidl/client/Android.bp b/media/codec2/hidl/client/Android.bp
index a174008..6038a40 100644
--- a/media/codec2/hidl/client/Android.bp
+++ b/media/codec2/hidl/client/Android.bp
@@ -31,6 +31,7 @@
export_shared_lib_headers: [
"libcodec2",
"libcodec2_hidl_client@1.0",
+ "libcodec2_vndk",
],
}
diff --git a/media/codec2/hidl/client/client.cpp b/media/codec2/hidl/client/client.cpp
index 53adbbc..6aca4a3 100644
--- a/media/codec2/hidl/client/client.cpp
+++ b/media/codec2/hidl/client/client.cpp
@@ -75,82 +75,11 @@
// c2_status_t value that corresponds to hwbinder transaction failure.
constexpr c2_status_t C2_TRANSACTION_FAILED = C2_CORRUPTED;
-// Returns the list of IComponentStore service names that are available on the
-// device. This list is specified at the build time in manifest files.
-// Note: A software service will have "_software" as a suffix.
-std::vector<std::string> const& getServiceNames() {
- static std::vector<std::string> sServiceNames{[]() {
- using ::android::hardware::media::c2::V1_0::IComponentStore;
- using ::android::hidl::manager::V1_2::IServiceManager;
-
- while (true) {
- sp<IServiceManager> serviceManager = IServiceManager::getService();
- CHECK(serviceManager) << "Hardware service manager is not running.";
-
- // There are three categories of services based on names.
- std::vector<std::string> defaultNames; // Prefixed with "default"
- std::vector<std::string> vendorNames; // Prefixed with "vendor"
- std::vector<std::string> otherNames; // Others
- Return<void> transResult;
- transResult = serviceManager->listManifestByInterface(
- IComponentStore::descriptor,
- [&defaultNames, &vendorNames, &otherNames](
- hidl_vec<hidl_string> const& instanceNames) {
- for (hidl_string const& instanceName : instanceNames) {
- char const* name = instanceName.c_str();
- if (strncmp(name, "default", 7) == 0) {
- defaultNames.emplace_back(name);
- } else if (strncmp(name, "vendor", 6) == 0) {
- vendorNames.emplace_back(name);
- } else {
- otherNames.emplace_back(name);
- }
- }
- });
- if (transResult.isOk()) {
- // Sort service names in each category.
- std::sort(defaultNames.begin(), defaultNames.end());
- std::sort(vendorNames.begin(), vendorNames.end());
- std::sort(otherNames.begin(), otherNames.end());
-
- // Concatenate the three lists in this order: default, vendor,
- // other.
- std::vector<std::string>& names = defaultNames;
- names.reserve(names.size() + vendorNames.size() + otherNames.size());
- names.insert(names.end(),
- std::make_move_iterator(vendorNames.begin()),
- std::make_move_iterator(vendorNames.end()));
- names.insert(names.end(),
- std::make_move_iterator(otherNames.begin()),
- std::make_move_iterator(otherNames.end()));
-
- // Summarize to logcat.
- if (names.empty()) {
- LOG(INFO) << "No Codec2 services declared in the manifest.";
- } else {
- std::stringstream stringOutput;
- stringOutput << "Available Codec2 services:";
- for (std::string const& name : names) {
- stringOutput << " \"" << name << "\"";
- }
- LOG(INFO) << stringOutput.str();
- }
-
- return names;
- }
- LOG(ERROR) << "Could not retrieve the list of service instances of "
- << IComponentStore::descriptor
- << ". Retrying...";
- }
- }()};
- return sServiceNames;
-}
-
-// Searches for a name in getServiceNames() and returns the index found. If the
+// Searches for a name in GetServiceNames() and returns the index found. If the
// name is not found, the returned index will be equal to
-// getServiceNames().size().
+// GetServiceNames().size().
size_t getServiceIndex(char const* name) {
- std::vector<std::string> const& names = getServiceNames();
+ std::vector<std::string> const& names = Codec2Client::GetServiceNames();
size_t i = 0;
for (; i < names.size(); ++i) {
if (name == names[i]) {
@@ -175,17 +104,14 @@
std::vector<C2Component::Traits> mTraits;
std::once_flag mTraitsInitializationFlag;
- // The index of the service. This is based on getServiceNames().
+ // The index of the service. This is based on GetServiceNames().
size_t mIndex;
- // A "valid" cache object must have its mIndex set with init().
- bool mValid{false};
// Called by s() exactly once to initialize the cache. The index must be a
- // valid index into the vector returned by getServiceNames(). Calling
+ // valid index into the vector returned by GetServiceNames(). Calling
// init(index) will associate the cache to the service with name
- // getServiceNames()[index].
+ // GetServiceNames()[index].
void init(size_t index) {
mIndex = index;
- mValid = true;
}
public:
@@ -195,7 +121,6 @@
// If the service is unavailable but listed in the manifest, this function
// will block indefinitely.
std::shared_ptr<Codec2Client> getClient() {
- CHECK(mValid) << "Uninitialized cache";
std::scoped_lock lock{mClientMutex};
if (!mClient) {
mClient = Codec2Client::_CreateFromIndex(mIndex);
@@ -208,7 +133,6 @@
//
// Note: This function is called only by ForAllServices().
void invalidate() {
- CHECK(mValid) << "Uninitialized cache";
std::scoped_lock lock{mClientMutex};
mClient = nullptr;
}
@@ -216,7 +140,6 @@
// Returns a list of traits for components supported by the service. This
// list is cached.
std::vector<C2Component::Traits> const& getTraits() {
- CHECK(mValid) << "Uninitialized cache";
std::call_once(mTraitsInitializationFlag, [this]() {
bool success{false};
// Spin until _listComponents() is successful.
@@ -229,7 +152,7 @@
using namespace std::chrono_literals;
static constexpr auto kServiceRetryPeriod = 5s;
LOG(INFO) << "Failed to retrieve component traits from service "
- "\"" << getServiceNames()[mIndex] << "\". "
+ "\"" << GetServiceNames()[mIndex] << "\". "
"Retrying...";
std::this_thread::sleep_for(kServiceRetryPeriod);
}
@@ -240,7 +163,7 @@
// List() returns the list of all caches.
static std::vector<Cache>& List() {
static std::vector<Cache> sCaches{[]() {
- size_t numServices = getServiceNames().size();
+ size_t numServices = GetServiceNames().size();
std::vector<Cache> caches(numServices);
for (size_t i = 0; i < numServices; ++i) {
caches[i].init(i);
@@ -610,8 +533,12 @@
}
}
+sp<Codec2Client::Base> const& Codec2Client::getBase() const {
+ return mBase;
+}
+
std::string const& Codec2Client::getServiceName() const {
- return getServiceNames()[mServiceIndex];
+ return GetServiceNames()[mServiceIndex];
}
c2_status_t Codec2Client::createComponent(
@@ -807,15 +734,94 @@
return std::make_shared<SimpleParamReflector>(mBase);
};
+std::vector<std::string> const& Codec2Client::GetServiceNames() {
+ static std::vector<std::string> sServiceNames{[]() {
+ using ::android::hardware::media::c2::V1_0::IComponentStore;
+ using ::android::hidl::manager::V1_2::IServiceManager;
+
+ while (true) {
+ sp<IServiceManager> serviceManager = IServiceManager::getService();
+ CHECK(serviceManager) << "Hardware service manager is not running.";
+
+ // There are three categories of services based on names.
+ std::vector<std::string> defaultNames; // Prefixed with "default"
+ std::vector<std::string> vendorNames; // Prefixed with "vendor"
+ std::vector<std::string> otherNames; // Others
+ Return<void> transResult;
+ transResult = serviceManager->listManifestByInterface(
+ IComponentStore::descriptor,
+ [&defaultNames, &vendorNames, &otherNames](
+ hidl_vec<hidl_string> const& instanceNames) {
+ for (hidl_string const& instanceName : instanceNames) {
+ char const* name = instanceName.c_str();
+ if (strncmp(name, "default", 7) == 0) {
+ defaultNames.emplace_back(name);
+ } else if (strncmp(name, "vendor", 6) == 0) {
+ vendorNames.emplace_back(name);
+ } else {
+ otherNames.emplace_back(name);
+ }
+ }
+ });
+ if (transResult.isOk()) {
+ // Sort service names in each category.
+ std::sort(defaultNames.begin(), defaultNames.end());
+ std::sort(vendorNames.begin(), vendorNames.end());
+ std::sort(otherNames.begin(), otherNames.end());
+
+ // Concatenate the three lists in this order: default, vendor,
+ // other.
+ std::vector<std::string>& names = defaultNames;
+ names.reserve(names.size() + vendorNames.size() + otherNames.size());
+ names.insert(names.end(),
+ std::make_move_iterator(vendorNames.begin()),
+ std::make_move_iterator(vendorNames.end()));
+ names.insert(names.end(),
+ std::make_move_iterator(otherNames.begin()),
+ std::make_move_iterator(otherNames.end()));
+
+ // Summarize to logcat.
+ if (names.empty()) {
+ LOG(INFO) << "No Codec2 services declared in the manifest.";
+ } else {
+ std::stringstream stringOutput;
+ stringOutput << "Available Codec2 services:";
+ for (std::string const& name : names) {
+ stringOutput << " \"" << name << "\"";
+ }
+ LOG(INFO) << stringOutput.str();
+ }
+
+ return names;
+ }
+ LOG(ERROR) << "Could not retrieve the list of service instances of "
+ << IComponentStore::descriptor
+ << ". Retrying...";
+ }
+ }()};
+ return sServiceNames;
+}
+
std::shared_ptr<Codec2Client> Codec2Client::CreateFromService(
const char* name) {
size_t index = getServiceIndex(name);
- return index == getServiceNames().size() ?
+ return index == GetServiceNames().size() ?
nullptr : _CreateFromIndex(index);
}
+std::vector<std::shared_ptr<Codec2Client>> Codec2Client::
+ CreateFromAllServices() {
+ std::vector<std::shared_ptr<Codec2Client>> clients(
+ GetServiceNames().size());
+ for (size_t i = GetServiceNames().size(); i > 0; ) {
+ --i;
+ clients[i] = _CreateFromIndex(i);
+ }
+ return clients;
+}
+
std::shared_ptr<Codec2Client> Codec2Client::_CreateFromIndex(size_t index) {
- std::string const& name = getServiceNames()[index];
+ std::string const& name = GetServiceNames()[index];
LOG(INFO) << "Creating a Codec2 client to service \"" << name << "\"";
sp<Base> baseStore = Base::getService(name);
CHECK(baseStore) << "Codec2 service \"" << name << "\""
@@ -958,17 +964,17 @@
if (inputSurfaceSetting == 0) {
return nullptr;
}
- size_t index = getServiceNames().size();
+ size_t index = GetServiceNames().size();
if (serviceName) {
index = getServiceIndex(serviceName);
- if (index == getServiceNames().size()) {
+ if (index == GetServiceNames().size()) {
LOG(DEBUG) << "CreateInputSurface -- invalid service name: \""
<< serviceName << "\"";
}
}
std::shared_ptr<Codec2Client::InputSurface> inputSurface;
- if (index != getServiceNames().size()) {
+ if (index != GetServiceNames().size()) {
std::shared_ptr<Codec2Client> client = Cache::List()[index].getClient();
if (client->createInputSurface(&inputSurface) == C2_OK) {
return inputSurface;
diff --git a/media/codec2/hidl/client/include/codec2/hidl/client.h b/media/codec2/hidl/client/include/codec2/hidl/client.h
index 1851752..03db515 100644
--- a/media/codec2/hidl/client/include/codec2/hidl/client.h
+++ b/media/codec2/hidl/client/include/codec2/hidl/client.h
@@ -143,6 +143,8 @@
typedef Codec2Client Store;
+ sp<Base> const& getBase() const;
+
std::string const& getServiceName() const;
c2_status_t createComponent(
@@ -165,8 +167,17 @@
std::shared_ptr<C2ParamReflector> getParamReflector();
+ // Returns the list of IComponentStore service names that are available on
+ // the device. This list is specified at the build time in manifest files.
+ // Note: A software service will have "_software" as a suffix.
+ static std::vector<std::string> const& GetServiceNames();
+
+ // Create a service with a given service name.
static std::shared_ptr<Codec2Client> CreateFromService(char const* name);
+ // Get clients to all services.
+ static std::vector<std::shared_ptr<Codec2Client>> CreateFromAllServices();
+
// Try to create a component with a given name from all known
// IComponentStore services.
static std::shared_ptr<Component> CreateComponentByName(
diff --git a/media/extractors/wav/WAVExtractor.cpp b/media/extractors/wav/WAVExtractor.cpp
index 020951b..8b539c2ff 100644
--- a/media/extractors/wav/WAVExtractor.cpp
+++ b/media/extractors/wav/WAVExtractor.cpp
@@ -461,7 +461,7 @@
}
// maxBytesToRead may be reduced so that in-place data conversion will fit in buffer size.
- const size_t bufferSize = buffer->size();
+ const size_t bufferSize = std::min(buffer->size(), kMaxFrameSize);
size_t maxBytesToRead;
if (mOutputFloat) { // destination is float at 4 bytes per sample, source may be less.
maxBytesToRead = (mBitsPerSample / 8) * (bufferSize / 4);
diff --git a/media/libaudioclient/AudioTrack.cpp b/media/libaudioclient/AudioTrack.cpp
index 8d1f511..bd48f56 100644
--- a/media/libaudioclient/AudioTrack.cpp
+++ b/media/libaudioclient/AudioTrack.cpp
@@ -605,7 +605,10 @@
mInUnderrun = false;
mPreviousTimestampValid = false;
mTimestampStartupGlitchReported = false;
- mRetrogradeMotionReported = false;
+ mTimestampRetrogradePositionReported = false;
+ mTimestampRetrogradeTimeReported = false;
+ mTimestampStallReported = false;
+ mTimestampStaleTimeReported = false;
mPreviousLocation = ExtendedTimestamp::LOCATION_INVALID;
mStartTs.mPosition = 0;
mUnderrunCountOffset = 0;
@@ -656,7 +659,10 @@
mPosition = 0;
mPreviousTimestampValid = false;
mTimestampStartupGlitchReported = false;
- mRetrogradeMotionReported = false;
+ mTimestampRetrogradePositionReported = false;
+ mTimestampRetrogradeTimeReported = false;
+ mTimestampStallReported = false;
+ mTimestampStaleTimeReported = false;
mPreviousLocation = ExtendedTimestamp::LOCATION_INVALID;
if (!isOffloadedOrDirect_l()
@@ -2607,9 +2613,14 @@
// A better start time is now. The retrograde check ensures
// timestamp monotonicity.
const int64_t nowNs = systemTime();
- ALOGD("%s(%d) device stall, using current time %lld",
- __func__, mPortId, (long long)nowNs);
+ if (!mTimestampStallReported) {
+ ALOGD("%s(%d): device stall time corrected using current time %lld",
+ __func__, mPortId, (long long)nowNs);
+ mTimestampStallReported = true;
+ }
timestamp.mTime = convertNsToTimespec(nowNs);
+ } else {
+ mTimestampStallReported = false;
}
}
@@ -2762,12 +2773,17 @@
const int64_t lagNs = int64_t(mAfLatency * 1000000LL);
const int64_t limitNs = mStartNs - lagNs;
if (currentTimeNanos < limitNs) {
- ALOGD("%s(%d): correcting timestamp time for pause, "
- "currentTimeNanos: %lld < limitNs: %lld < mStartNs: %lld",
- __func__, mPortId,
- (long long)currentTimeNanos, (long long)limitNs, (long long)mStartNs);
+ if (!mTimestampStaleTimeReported) {
+ ALOGD("%s(%d): stale timestamp time corrected, "
+ "currentTimeNanos: %lld < limitNs: %lld < mStartNs: %lld",
+ __func__, mPortId,
+ (long long)currentTimeNanos, (long long)limitNs, (long long)mStartNs);
+ mTimestampStaleTimeReported = true;
+ }
timestamp.mTime = convertNsToTimespec(limitNs);
currentTimeNanos = limitNs;
+ } else {
+ mTimestampStaleTimeReported = false;
}
// previousTimestampValid is set to false when starting after a stop or flush.
@@ -2777,11 +2793,15 @@
// retrograde check
if (currentTimeNanos < previousTimeNanos) {
- ALOGW("%s(%d): retrograde timestamp time corrected, %lld < %lld",
- __func__, mPortId,
- (long long)currentTimeNanos, (long long)previousTimeNanos);
+ if (!mTimestampRetrogradeTimeReported) {
+ ALOGW("%s(%d): retrograde timestamp time corrected, %lld < %lld",
+ __func__, mPortId,
+ (long long)currentTimeNanos, (long long)previousTimeNanos);
+ mTimestampRetrogradeTimeReported = true;
+ }
timestamp.mTime = mPreviousTimestamp.mTime;
- // currentTimeNanos not used below.
+ } else {
+ mTimestampRetrogradeTimeReported = false;
}
// Looking at signed delta will work even when the timestamps
@@ -2790,16 +2810,16 @@
- mPreviousTimestamp.mPosition).signedValue();
if (deltaPosition < 0) {
// Only report once per position instead of spamming the log.
- if (!mRetrogradeMotionReported) {
+ if (!mTimestampRetrogradePositionReported) {
ALOGW("%s(%d): retrograde timestamp position corrected, %d = %u - %u",
__func__, mPortId,
deltaPosition,
timestamp.mPosition,
mPreviousTimestamp.mPosition);
- mRetrogradeMotionReported = true;
+ mTimestampRetrogradePositionReported = true;
}
} else {
- mRetrogradeMotionReported = false;
+ mTimestampRetrogradePositionReported = false;
}
if (deltaPosition < 0) {
timestamp.mPosition = mPreviousTimestamp.mPosition;
diff --git a/media/libaudioclient/include/media/AudioTrack.h b/media/libaudioclient/include/media/AudioTrack.h
index 3926ead..df5eabc 100644
--- a/media/libaudioclient/include/media/AudioTrack.h
+++ b/media/libaudioclient/include/media/AudioTrack.h
@@ -1151,8 +1151,11 @@
// AudioTracks.
bool mPreviousTimestampValid;// true if mPreviousTimestamp is valid
- bool mTimestampStartupGlitchReported; // reduce log spam
- bool mRetrogradeMotionReported; // reduce log spam
+ bool mTimestampStartupGlitchReported; // reduce log spam
+ bool mTimestampRetrogradePositionReported; // reduce log spam
+ bool mTimestampRetrogradeTimeReported; // reduce log spam
+ bool mTimestampStallReported; // reduce log spam
+ bool mTimestampStaleTimeReported; // reduce log spam
AudioTimestamp mPreviousTimestamp; // used to detect retrograde motion
ExtendedTimestamp::Location mPreviousLocation; // location used for previous timestamp
diff --git a/media/libeffects/lvm/lib/Bundle/src/LVM_Buffers.c b/media/libeffects/lvm/lib/Bundle/src/LVM_Buffers.c
index 37272e3..bdca5e3 100644
--- a/media/libeffects/lvm/lib/Bundle/src/LVM_Buffers.c
+++ b/media/libeffects/lvm/lib/Bundle/src/LVM_Buffers.c
@@ -1128,6 +1128,11 @@
LVM_Instance_t *pInstance = (LVM_Instance_t *)hInstance;
#ifdef SUPPORT_MC
LVM_INT16 NumChannels = pInstance->NrChannels;
+ if (NumChannels == 1)
+ {
+ /* Mono input is processed as stereo by LVM module */
+ NumChannels = 2;
+ }
#undef NrFrames
#define NrFrames (*pNumSamples) // alias for clarity
#else
diff --git a/media/libeffects/lvm/tests/build_and_run_all_unit_tests.sh b/media/libeffects/lvm/tests/build_and_run_all_unit_tests.sh
index 5079634..a97acc9 100755
--- a/media/libeffects/lvm/tests/build_and_run_all_unit_tests.sh
+++ b/media/libeffects/lvm/tests/build_and_run_all_unit_tests.sh
@@ -24,9 +24,32 @@
echo "testing lvm"
adb shell mkdir -p $testdir
adb push $ANDROID_BUILD_TOP/cts/tests/tests/media/res/raw/sinesweepraw.raw $testdir
-adb push $OUT/testcases/lvmtest/arm64/lvmtest $testdir
adb push $OUT/testcases/snr/arm64/snr $testdir
+E_VAL=1
+if [ -z "$1" ]
+then
+ cmds=("adb push $OUT/testcases/lvmtest/arm64/lvmtest $testdir"
+ "adb push $OUT/testcases/lvmtest/arm/lvmtest $testdir"
+ )
+elif [ "$1" == "32" ]
+then
+ cmds="adb push $OUT/testcases/lvmtest/arm/lvmtest $testdir"
+elif [ "$1" == "64" ]
+then
+ cmds="adb push $OUT/testcases/lvmtest/arm64/lvmtest $testdir"
+else
+ echo ""
+ echo "Invalid \"val\""
+ echo "Usage:"
+ echo " "$0" [val]"
+ echo " where, val can be either 32 or 64."
+ echo ""
+ echo " If val is not specified then both 32 bit and 64 bit binaries"
+ echo " are tested."
+ exit $E_VAL
+fi
+
flags_arr=(
"-csE"
"-eqE"
@@ -61,42 +84,45 @@
# run multichannel effects at different configs, saving only the stereo channel
# pair.
error_count=0
-for flags in "${flags_arr[@]}"
+for cmd in "${cmds[@]}"
do
- for fs in ${fs_arr[*]}
+ $cmd
+ for flags in "${flags_arr[@]}"
do
- for chMask in {0..22}
+ for fs in ${fs_arr[*]}
do
- adb shell $testdir/lvmtest -i:$testdir/sinesweepraw.raw \
- -o:$testdir/sinesweep_$((chMask))_$((fs)).raw -chMask:$chMask -fs:$fs $flags
+ for chMask in {0..22}
+ do
+ adb shell $testdir/lvmtest -i:$testdir/sinesweepraw.raw \
+ -o:$testdir/sinesweep_$((chMask))_$((fs)).raw -chMask:$chMask -fs:$fs $flags
- shell_ret=$?
- if [ $shell_ret -ne 0 ]; then
- echo "error: $shell_ret"
- ((++error_count))
- fi
+ shell_ret=$?
+ if [ $shell_ret -ne 0 ]; then
+ echo "error: $shell_ret"
+ ((++error_count))
+ fi
- # two channel files should be identical to higher channel
- # computation (first 2 channels).
- # Do not compare cases where -bE is in flags (due to mono computation)
- if [[ $flags != *"-bE"* ]] && [[ "$chMask" -gt 1 ]]
- then
- adb shell cmp $testdir/sinesweep_1_$((fs)).raw \
- $testdir/sinesweep_$((chMask))_$((fs)).raw
- elif [[ $flags == *"-bE"* ]] && [[ "$chMask" -gt 1 ]]
- then
- adb shell $testdir/snr $testdir/sinesweep_1_$((fs)).raw \
- $testdir/sinesweep_$((chMask))_$((fs)).raw -thr:90.308998
- fi
+ # two channel files should be identical to higher channel
+ # computation (first 2 channels).
+ # Do not compare cases where -bE is in flags (due to mono computation)
+ if [[ $flags != *"-bE"* ]] && [[ "$chMask" -gt 1 ]]
+ then
+ adb shell cmp $testdir/sinesweep_1_$((fs)).raw \
+ $testdir/sinesweep_$((chMask))_$((fs)).raw
+ elif [[ $flags == *"-bE"* ]] && [[ "$chMask" -gt 1 ]]
+ then
+ adb shell $testdir/snr $testdir/sinesweep_1_$((fs)).raw \
+ $testdir/sinesweep_$((chMask))_$((fs)).raw -thr:90.308998
+ fi
- # both cmp and snr return EXIT_FAILURE on mismatch.
- shell_ret=$?
- if [ $shell_ret -ne 0 ]; then
- echo "error: $shell_ret"
- ((++error_count))
- fi
-
+ # both cmp and snr return EXIT_FAILURE on mismatch.
+ shell_ret=$?
+ if [ $shell_ret -ne 0 ]; then
+ echo "error: $shell_ret"
+ ((++error_count))
+ fi
+ done
done
done
done
diff --git a/media/libmediaplayerservice/Android.bp b/media/libmediaplayerservice/Android.bp
index 0776172..6709585 100644
--- a/media/libmediaplayerservice/Android.bp
+++ b/media/libmediaplayerservice/Android.bp
@@ -2,6 +2,7 @@
srcs: [
"ActivityManager.cpp",
+ "DeathNotifier.cpp",
"MediaPlayerFactory.cpp",
"MediaPlayerService.cpp",
"MediaRecorderClient.cpp",
@@ -17,6 +18,7 @@
"libaudioclient",
"libbinder",
"libcamera_client",
+ "libcodec2_client",
"libcrypto",
"libcutils",
"libdl",
diff --git a/media/libmediaplayerservice/DeathNotifier.cpp b/media/libmediaplayerservice/DeathNotifier.cpp
new file mode 100644
index 0000000..d13bdf5
--- /dev/null
+++ b/media/libmediaplayerservice/DeathNotifier.cpp
@@ -0,0 +1,80 @@
+/*
+ * Copyright 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+//#define LOG_NDEBUG 0
+#define LOG_TAG "MediaPlayerService-DeathNotifier"
+#include <android-base/logging.h>
+
+#include "DeathNotifier.h"
+
+namespace android {
+
+class DeathNotifier::DeathRecipient :
+ public IBinder::DeathRecipient,
+ public hardware::hidl_death_recipient {
+public:
+ using Notify = DeathNotifier::Notify;
+
+ DeathRecipient(Notify const& notify): mNotify{notify} {
+ }
+
+ virtual void binderDied(wp<IBinder> const&) override {
+ mNotify();
+ }
+
+ virtual void serviceDied(uint64_t, wp<HBase> const&) override {
+ mNotify();
+ }
+
+private:
+ Notify mNotify;
+};
+
+DeathNotifier::DeathNotifier(sp<IBinder> const& service, Notify const& notify)
+ : mService{std::in_place_index<1>, service},
+ mDeathRecipient{new DeathRecipient(notify)} {
+ service->linkToDeath(mDeathRecipient);
+}
+
+DeathNotifier::DeathNotifier(sp<HBase> const& service, Notify const& notify)
+ : mService{std::in_place_index<2>, service},
+ mDeathRecipient{new DeathRecipient(notify)} {
+ service->linkToDeath(mDeathRecipient, 0);
+}
+
+DeathNotifier::DeathNotifier(DeathNotifier&& other)
+ : mService{other.mService}, mDeathRecipient{other.mDeathRecipient} {
+ other.mService.emplace<0>();
+ other.mDeathRecipient = nullptr;
+}
+
+DeathNotifier::~DeathNotifier() {
+ switch (mService.index()) {
+ case 0:
+ break;
+ case 1:
+ std::get<1>(mService)->unlinkToDeath(mDeathRecipient);
+ break;
+ case 2:
+ std::get<2>(mService)->unlinkToDeath(mDeathRecipient);
+ break;
+ default:
+ CHECK(false) << "Corrupted service type during destruction.";
+ }
+}
+
+} // namespace android
+
diff --git a/media/libmediaplayerservice/DeathNotifier.h b/media/libmediaplayerservice/DeathNotifier.h
new file mode 100644
index 0000000..7bc2611
--- /dev/null
+++ b/media/libmediaplayerservice/DeathNotifier.h
@@ -0,0 +1,48 @@
+/*
+ * Copyright 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ANDROID_MEDIASERVICE_DEATHNOTIFIER_H
+#define ANDROID_MEDIASERVICE_DEATHNOTIFIER_H
+
+#include <android/hidl/base/1.0/IBase.h>
+#include <binder/Binder.h>
+#include <hidl/HidlSupport.h>
+
+#include <variant>
+
+namespace android {
+
+class DeathNotifier {
+public:
+ using HBase = hidl::base::V1_0::IBase;
+ using Notify = std::function<void()>;
+
+ DeathNotifier(sp<IBinder> const& service, Notify const& notify);
+ DeathNotifier(sp<HBase> const& service, Notify const& notify);
+ DeathNotifier(DeathNotifier&& other);
+ ~DeathNotifier();
+
+private:
+ std::variant<std::monostate, sp<IBinder>, sp<HBase>> mService;
+
+ class DeathRecipient;
+ sp<DeathRecipient> mDeathRecipient;
+};
+
+} // namespace android
+
+#endif // ANDROID_MEDIASERVICE_DEATHNOTIFIER_H
+
diff --git a/media/libmediaplayerservice/DeathRecipient.h b/media/libmediaplayerservice/DeathRecipient.h
new file mode 100644
index 0000000..bf5ae5c
--- /dev/null
+++ b/media/libmediaplayerservice/DeathRecipient.h
@@ -0,0 +1,59 @@
+/*
+ * Copyright 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ANDROID_MEDIASERVICE_DEATHRECIPIENT_H
+#define ANDROID_MEDIASERVICE_DEATHRECIPIENT_H
+
+#include <binder/binder.h>
+#include <hidl/HidlSupport.h>
+
+#include <variant>
+
+class DeathNotifier :
+ public IBinder::DeathRecipient,
+ public ::android::hardware::hidl_death_recipient {
+public:
+ using Service = std::variant<
+ sp<IBinder> const&,
+ sp<android::hidl::base::V1_0::IBase> const&>;
+
+ DeathNotifier(std::variant<sp<IBinder> const&,
+ const sp<IBinder>& service,
+ const sp<MediaPlayerBase>& listener,
+ int which,
+ const std::string& name);
+ DeathNotifier(
+ const sp<android::hidl::base::V1_0::IBase>& hService,
+ const sp<MediaPlayerBase>& listener,
+ int which,
+ const std::string& name);
+ virtual ~DeathNotifier() = default;
+ virtual void binderDied(const wp<IBinder>& who);
+ virtual void serviceDied(
+ uint64_t cookie,
+ const wp<::android::hidl::base::V1_0::IBase>& who);
+ void unlinkToDeath();
+
+private:
+ sp<IBinder> mService;
+ sp<android::hidl::base::V1_0::IBase> mHService; // HIDL service
+ wp<MediaPlayerBase> mListener;
+ int mWhich;
+ std::string mName;
+};
+
+#endif // ANDROID_MEDIASERVICE_DEATHRECIPIENT_H
+
diff --git a/media/libmediaplayerservice/MediaPlayerService.cpp b/media/libmediaplayerservice/MediaPlayerService.cpp
index 5061024..dfd3933 100644
--- a/media/libmediaplayerservice/MediaPlayerService.cpp
+++ b/media/libmediaplayerservice/MediaPlayerService.cpp
@@ -34,7 +34,7 @@
#include <utils/misc.h>
-#include <android/hardware/media/omx/1.0/IOmxStore.h>
+#include <android/hardware/media/omx/1.0/IOmx.h>
#include <android/hardware/media/c2/1.0/IComponentStore.h>
#include <binder/IPCThreadState.h>
#include <binder/IServiceManager.h>
@@ -47,6 +47,7 @@
#include <utils/Timers.h>
#include <utils/Vector.h>
+#include <codec2/hidl/client.h>
#include <media/IMediaHTTPService.h>
#include <media/IRemoteDisplay.h>
#include <media/IRemoteDisplayClient.h>
@@ -591,7 +592,6 @@
if (mAudioAttributes != NULL) {
free(mAudioAttributes);
}
- clearDeathNotifiers_l();
mAudioDeviceUpdatedListener.clear();
}
@@ -647,59 +647,6 @@
return p;
}
-MediaPlayerService::Client::ServiceDeathNotifier::ServiceDeathNotifier(
- const sp<IBinder>& service,
- const sp<MediaPlayerBase>& listener,
- int which) {
- mService = service;
- mHService = nullptr;
- mListener = listener;
- mWhich = which;
-}
-
-MediaPlayerService::Client::ServiceDeathNotifier::ServiceDeathNotifier(
- const sp<android::hidl::base::V1_0::IBase>& hService,
- const sp<MediaPlayerBase>& listener,
- int which) {
- mService = nullptr;
- mHService = hService;
- mListener = listener;
- mWhich = which;
-}
-
-MediaPlayerService::Client::ServiceDeathNotifier::~ServiceDeathNotifier() {
-}
-
-void MediaPlayerService::Client::ServiceDeathNotifier::binderDied(const wp<IBinder>& /*who*/) {
- sp<MediaPlayerBase> listener = mListener.promote();
- if (listener != NULL) {
- listener->sendEvent(MEDIA_ERROR, MEDIA_ERROR_SERVER_DIED, mWhich);
- } else {
- ALOGW("listener for process %d death is gone", mWhich);
- }
-}
-
-void MediaPlayerService::Client::ServiceDeathNotifier::serviceDied(
- uint64_t /* cookie */,
- const wp<::android::hidl::base::V1_0::IBase>& /* who */) {
- sp<MediaPlayerBase> listener = mListener.promote();
- if (listener != NULL) {
- listener->sendEvent(MEDIA_ERROR, MEDIA_ERROR_SERVER_DIED, mWhich);
- } else {
- ALOGW("listener for process %d death is gone", mWhich);
- }
-}
-
-void MediaPlayerService::Client::ServiceDeathNotifier::unlinkToDeath() {
- if (mService != nullptr) {
- mService->unlinkToDeath(this);
- mService = nullptr;
- } else if (mHService != nullptr) {
- mHService->unlinkToDeath(this);
- mHService = nullptr;
- }
-}
-
void MediaPlayerService::Client::AudioDeviceUpdatedNotifier::onAudioDeviceUpdate(
audio_io_handle_t audioIo,
audio_port_handle_t deviceId) {
@@ -711,19 +658,6 @@
}
}
-void MediaPlayerService::Client::clearDeathNotifiers_l() {
- if (mExtractorDeathListener != nullptr) {
- mExtractorDeathListener->unlinkToDeath();
- mExtractorDeathListener = nullptr;
- }
- for (const sp<ServiceDeathNotifier>& codecDeathListener : mCodecDeathListeners) {
- if (codecDeathListener != nullptr) {
- codecDeathListener->unlinkToDeath();
- }
- }
- mCodecDeathListeners.clear();
-}
-
sp<MediaPlayerBase> MediaPlayerService::Client::setDataSource_pre(
player_type playerType)
{
@@ -735,66 +669,83 @@
return p;
}
+ std::vector<DeathNotifier> deathNotifiers;
+
+ // Listen to death of media.extractor service
sp<IServiceManager> sm = defaultServiceManager();
sp<IBinder> binder = sm->getService(String16("media.extractor"));
if (binder == NULL) {
ALOGE("extractor service not available");
return NULL;
}
- sp<ServiceDeathNotifier> extractorDeathListener =
- new ServiceDeathNotifier(binder, p, MEDIAEXTRACTOR_PROCESS_DEATH);
- binder->linkToDeath(extractorDeathListener);
+ deathNotifiers.emplace_back(
+ binder, [l = wp<MediaPlayerBase>(p)]() {
+ sp<MediaPlayerBase> listener = l.promote();
+ if (listener) {
+ ALOGI("media.extractor died. Sending death notification.");
+ listener->sendEvent(MEDIA_ERROR, MEDIA_ERROR_SERVER_DIED,
+ MEDIAEXTRACTOR_PROCESS_DEATH);
+ } else {
+ ALOGW("media.extractor died without a death handler.");
+ }
+ });
- std::vector<sp<ServiceDeathNotifier>> codecDeathListeners;
{
using ::android::hidl::base::V1_0::IBase;
- // Listen to OMX's IOmxStore/default
+ // Listen to death of OMX service
{
- sp<IBase> store = ::android::hardware::media::omx::V1_0::
- IOmxStore::getService();
- if (store == nullptr) {
+ sp<IBase> base = ::android::hardware::media::omx::V1_0::
+ IOmx::getService();
+ if (base == nullptr) {
ALOGD("OMX service is not available");
} else {
- sp<ServiceDeathNotifier> codecDeathListener =
- new ServiceDeathNotifier(store, p, MEDIACODEC_PROCESS_DEATH);
- store->linkToDeath(codecDeathListener, 0);
- codecDeathListeners.emplace_back(codecDeathListener);
+ deathNotifiers.emplace_back(
+ base, [l = wp<MediaPlayerBase>(p)]() {
+ sp<MediaPlayerBase> listener = l.promote();
+ if (listener) {
+ ALOGI("OMX service died. "
+ "Sending death notification.");
+ listener->sendEvent(
+ MEDIA_ERROR, MEDIA_ERROR_SERVER_DIED,
+ MEDIACODEC_PROCESS_DEATH);
+ } else {
+ ALOGW("OMX service died without a death handler.");
+ }
+ });
}
}
- // Listen to Codec2's IComponentStore/software
- // TODO: Listen to all Codec2 services.
+ // Listen to death of Codec2 services
{
- sp<IBase> store = ::android::hardware::media::c2::V1_0::
- IComponentStore::getService();
- if (store == nullptr) {
- ALOGD("Codec2 system service is not available");
- } else {
- sp<ServiceDeathNotifier> codecDeathListener =
- new ServiceDeathNotifier(store, p, MEDIACODEC_PROCESS_DEATH);
- store->linkToDeath(codecDeathListener, 0);
- codecDeathListeners.emplace_back(codecDeathListener);
- }
-
- store = ::android::hardware::media::c2::V1_0::
- IComponentStore::getService("software");
- if (store == nullptr) {
- ALOGD("Codec2 swcodec service is not available");
- } else {
- sp<ServiceDeathNotifier> codecDeathListener =
- new ServiceDeathNotifier(store, p, MEDIACODEC_PROCESS_DEATH);
- store->linkToDeath(codecDeathListener, 0);
- codecDeathListeners.emplace_back(codecDeathListener);
+ for (std::shared_ptr<Codec2Client> const& client :
+ Codec2Client::CreateFromAllServices()) {
+ sp<IBase> base = client->getBase();
+ deathNotifiers.emplace_back(
+ base, [l = wp<MediaPlayerBase>(p),
+ name = std::string(client->getServiceName())]() {
+ sp<MediaPlayerBase> listener = l.promote();
+ if (listener) {
+ ALOGI("Codec2 service \"%s\" died. "
+ "Sending death notification.",
+ name.c_str());
+ listener->sendEvent(
+ MEDIA_ERROR, MEDIA_ERROR_SERVER_DIED,
+ MEDIACODEC_PROCESS_DEATH);
+ } else {
+ ALOGW("Codec2 service \"%s\" died "
+ "without a death handler.",
+ name.c_str());
+ }
+ });
}
}
}
Mutex::Autolock lock(mLock);
- clearDeathNotifiers_l();
- mExtractorDeathListener = extractorDeathListener;
- mCodecDeathListeners.swap(codecDeathListeners);
+ mDeathNotifiers.clear();
+ mDeathNotifiers.swap(deathNotifiers);
mAudioDeviceUpdatedListener = new AudioDeviceUpdatedNotifier(p);
if (!p->hardwareOutput()) {
diff --git a/media/libmediaplayerservice/MediaPlayerService.h b/media/libmediaplayerservice/MediaPlayerService.h
index 26bfa71..49688ce 100644
--- a/media/libmediaplayerservice/MediaPlayerService.h
+++ b/media/libmediaplayerservice/MediaPlayerService.h
@@ -30,8 +30,6 @@
#include <media/Metadata.h>
#include <media/stagefright/foundation/ABase.h>
-#include <hidl/HidlSupport.h>
-
#include <system/audio.h>
namespace android {
@@ -39,6 +37,7 @@
struct AudioPlaybackRate;
class AudioTrack;
struct AVSyncSettings;
+class DeathNotifier;
class IDataSource;
class IMediaRecorder;
class IMediaMetadataRetriever;
@@ -388,33 +387,6 @@
virtual status_t enableAudioDeviceCallback(bool enabled);
private:
- class ServiceDeathNotifier:
- public IBinder::DeathRecipient,
- public ::android::hardware::hidl_death_recipient
- {
- public:
- ServiceDeathNotifier(
- const sp<IBinder>& service,
- const sp<MediaPlayerBase>& listener,
- int which);
- ServiceDeathNotifier(
- const sp<android::hidl::base::V1_0::IBase>& hService,
- const sp<MediaPlayerBase>& listener,
- int which);
- virtual ~ServiceDeathNotifier();
- virtual void binderDied(const wp<IBinder>& who);
- virtual void serviceDied(
- uint64_t cookie,
- const wp<::android::hidl::base::V1_0::IBase>& who);
- void unlinkToDeath();
-
- private:
- int mWhich;
- sp<IBinder> mService;
- sp<android::hidl::base::V1_0::IBase> mHService; // HIDL service
- wp<MediaPlayerBase> mListener;
- };
-
class AudioDeviceUpdatedNotifier: public AudioSystem::AudioDeviceCallback
{
public:
@@ -430,8 +402,6 @@
wp<MediaPlayerBase> mListener;
};
- void clearDeathNotifiers_l();
-
friend class MediaPlayerService;
Client( const sp<MediaPlayerService>& service,
pid_t pid,
@@ -506,8 +476,7 @@
// getMetadata clears this set.
media::Metadata::Filter mMetadataUpdated; // protected by mLock
- sp<ServiceDeathNotifier> mExtractorDeathListener;
- std::vector<sp<ServiceDeathNotifier>> mCodecDeathListeners;
+ std::vector<DeathNotifier> mDeathNotifiers;
sp<AudioDeviceUpdatedNotifier> mAudioDeviceUpdatedListener;
#if CALLBACK_ANTAGONIZER
Antagonizer* mAntagonizer;
diff --git a/media/libmediaplayerservice/MediaRecorderClient.cpp b/media/libmediaplayerservice/MediaRecorderClient.cpp
index 9f4265b..703da4b 100644
--- a/media/libmediaplayerservice/MediaRecorderClient.cpp
+++ b/media/libmediaplayerservice/MediaRecorderClient.cpp
@@ -18,27 +18,28 @@
#define LOG_TAG "MediaRecorderService"
#include <utils/Log.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <dirent.h>
-#include <unistd.h>
-#include <string.h>
-#include <cutils/atomic.h>
-#include <cutils/properties.h> // for property_get
+#include "MediaRecorderClient.h"
+#include "MediaPlayerService.h"
+#include "StagefrightRecorder.h"
+
+#include <android/hardware/media/omx/1.0/IOmx.h>
+#include <android/hardware/media/c2/1.0/IComponentStore.h>
#include <binder/IPCThreadState.h>
#include <binder/IServiceManager.h>
#include <binder/MemoryHeapBase.h>
#include <binder/MemoryBase.h>
-
+#include <codec2/hidl/client.h>
+#include <cutils/atomic.h>
+#include <cutils/properties.h> // for property_get
+#include <gui/IGraphicBufferProducer.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <system/audio.h>
#include <utils/String16.h>
-#include <system/audio.h>
-
-#include "MediaRecorderClient.h"
-#include "MediaPlayerService.h"
-
-#include "StagefrightRecorder.h"
-#include <gui/IGraphicBufferProducer.h>
+#include <dirent.h>
+#include <unistd.h>
+#include <string.h>
namespace android {
@@ -339,7 +340,7 @@
wp<MediaRecorderClient> client(this);
mMediaPlayerService->removeMediaRecorderClient(client);
}
- clearDeathNotifiers_l();
+ mDeathNotifiers.clear();
return NO_ERROR;
}
@@ -358,59 +359,6 @@
release();
}
-MediaRecorderClient::ServiceDeathNotifier::ServiceDeathNotifier(
- const sp<IBinder>& service,
- const sp<IMediaRecorderClient>& listener,
- int which) {
- mService = service;
- mOmx = nullptr;
- mListener = listener;
- mWhich = which;
-}
-
-MediaRecorderClient::ServiceDeathNotifier::ServiceDeathNotifier(
- const sp<IOmx>& omx,
- const sp<IMediaRecorderClient>& listener,
- int which) {
- mService = nullptr;
- mOmx = omx;
- mListener = listener;
- mWhich = which;
-}
-
-MediaRecorderClient::ServiceDeathNotifier::~ServiceDeathNotifier() {
-}
-
-void MediaRecorderClient::ServiceDeathNotifier::binderDied(const wp<IBinder>& /*who*/) {
- sp<IMediaRecorderClient> listener = mListener.promote();
- if (listener != NULL) {
- listener->notify(MEDIA_ERROR, MEDIA_ERROR_SERVER_DIED, mWhich);
- } else {
- ALOGW("listener for process %d death is gone", mWhich);
- }
-}
-
-void MediaRecorderClient::ServiceDeathNotifier::serviceDied(
- uint64_t /* cookie */,
- const wp<::android::hidl::base::V1_0::IBase>& /* who */) {
- sp<IMediaRecorderClient> listener = mListener.promote();
- if (listener != NULL) {
- listener->notify(MEDIA_ERROR, MEDIA_ERROR_SERVER_DIED, mWhich);
- } else {
- ALOGW("listener for process %d death is gone", mWhich);
- }
-}
-
-void MediaRecorderClient::ServiceDeathNotifier::unlinkToDeath() {
- if (mService != nullptr) {
- mService->unlinkToDeath(this);
- mService = nullptr;
- } else if (mOmx != nullptr) {
- mOmx->unlinkToDeath(this);
- mOmx = nullptr;
- }
-}
-
MediaRecorderClient::AudioDeviceUpdatedNotifier::AudioDeviceUpdatedNotifier(
const sp<IMediaRecorderClient>& listener) {
mListener = listener;
@@ -430,22 +378,11 @@
}
}
-void MediaRecorderClient::clearDeathNotifiers_l() {
- if (mCameraDeathListener != nullptr) {
- mCameraDeathListener->unlinkToDeath();
- mCameraDeathListener = nullptr;
- }
- if (mCodecDeathListener != nullptr) {
- mCodecDeathListener->unlinkToDeath();
- mCodecDeathListener = nullptr;
- }
-}
-
status_t MediaRecorderClient::setListener(const sp<IMediaRecorderClient>& listener)
{
ALOGV("setListener");
Mutex::Autolock lock(mLock);
- clearDeathNotifiers_l();
+ mDeathNotifiers.clear();
if (mRecorder == NULL) {
ALOGE("recorder is not initialized");
return NO_INIT;
@@ -463,20 +400,73 @@
// If the device does not have a camera, do not create a death listener for it.
if (binder != NULL) {
sCameraVerified = true;
- mCameraDeathListener = new ServiceDeathNotifier(binder, listener,
- MediaPlayerService::CAMERA_PROCESS_DEATH);
- binder->linkToDeath(mCameraDeathListener);
+ mDeathNotifiers.emplace_back(
+ binder, [l = wp<IMediaRecorderClient>(listener)](){
+ sp<IMediaRecorderClient> listener = l.promote();
+ if (listener) {
+ ALOGV("media.camera service died. "
+ "Sending death notification.");
+ listener->notify(
+ MEDIA_ERROR, MEDIA_ERROR_SERVER_DIED,
+ MediaPlayerService::CAMERA_PROCESS_DEATH);
+ } else {
+ ALOGW("media.camera service died without a death handler.");
+ }
+ });
}
sCameraChecked = true;
- sp<IOmx> omx = IOmx::getService();
- if (omx == nullptr) {
- ALOGE("IOmx service is not available");
- return NO_INIT;
+ {
+ using ::android::hidl::base::V1_0::IBase;
+
+ // Listen to OMX's IOmxStore/default
+ {
+ sp<IBase> base = ::android::hardware::media::omx::V1_0::
+ IOmx::getService();
+ if (base == nullptr) {
+ ALOGD("OMX service is not available");
+ } else {
+ mDeathNotifiers.emplace_back(
+ base, [l = wp<IMediaRecorderClient>(listener)](){
+ sp<IMediaRecorderClient> listener = l.promote();
+ if (listener) {
+ ALOGV("OMX service died. "
+ "Sending death notification.");
+ listener->notify(
+ MEDIA_ERROR, MEDIA_ERROR_SERVER_DIED,
+ MediaPlayerService::MEDIACODEC_PROCESS_DEATH);
+ } else {
+ ALOGW("OMX service died without a death handler.");
+ }
+ });
+ }
+ }
+
+ // Listen to Codec2's IComponentStore instances
+ {
+ for (std::shared_ptr<Codec2Client> const& client :
+ Codec2Client::CreateFromAllServices()) {
+ sp<IBase> base = client->getBase();
+ mDeathNotifiers.emplace_back(
+ base, [l = wp<IMediaRecorderClient>(listener),
+ name = std::string(client->getServiceName())]() {
+ sp<IMediaRecorderClient> listener = l.promote();
+ if (listener) {
+ ALOGV("Codec2 service \"%s\" died. "
+ "Sending death notification",
+ name.c_str());
+ listener->notify(
+ MEDIA_ERROR, MEDIA_ERROR_SERVER_DIED,
+ MediaPlayerService::MEDIACODEC_PROCESS_DEATH);
+ } else {
+ ALOGW("Codec2 service \"%s\" died "
+ "without a death handler",
+ name.c_str());
+ }
+ });
+ }
+ }
}
- mCodecDeathListener = new ServiceDeathNotifier(omx, listener,
- MediaPlayerService::MEDIACODEC_PROCESS_DEATH);
- omx->linkToDeath(mCodecDeathListener, 0);
mAudioDeviceUpdatedNotifier = new AudioDeviceUpdatedNotifier(listener);
mRecorder->setAudioDeviceCallback(mAudioDeviceUpdatedNotifier);
diff --git a/media/libmediaplayerservice/MediaRecorderClient.h b/media/libmediaplayerservice/MediaRecorderClient.h
index e698819..9e0f877 100644
--- a/media/libmediaplayerservice/MediaRecorderClient.h
+++ b/media/libmediaplayerservice/MediaRecorderClient.h
@@ -18,10 +18,12 @@
#ifndef ANDROID_MEDIARECORDERCLIENT_H
#define ANDROID_MEDIARECORDERCLIENT_H
+#include "DeathNotifier.h"
+
#include <media/AudioSystem.h>
#include <media/IMediaRecorder.h>
-#include <android/hardware/media/omx/1.0/IOmx.h>
+#include <vector>
namespace android {
@@ -31,34 +33,6 @@
class MediaRecorderClient : public BnMediaRecorder
{
- typedef ::android::hardware::media::omx::V1_0::IOmx IOmx;
-
- class ServiceDeathNotifier :
- public IBinder::DeathRecipient,
- public ::android::hardware::hidl_death_recipient
- {
- public:
- ServiceDeathNotifier(
- const sp<IBinder>& service,
- const sp<IMediaRecorderClient>& listener,
- int which);
- ServiceDeathNotifier(
- const sp<IOmx>& omx,
- const sp<IMediaRecorderClient>& listener,
- int which);
- virtual ~ServiceDeathNotifier();
- virtual void binderDied(const wp<IBinder>& who);
- virtual void serviceDied(
- uint64_t cookie,
- const wp<::android::hidl::base::V1_0::IBase>& who);
- void unlinkToDeath();
- private:
- int mWhich;
- sp<IBinder> mService;
- sp<IOmx> mOmx;
- wp<IMediaRecorderClient> mListener;
- };
-
class AudioDeviceUpdatedNotifier: public AudioSystem::AudioDeviceCallback
{
public:
@@ -71,8 +45,6 @@
wp<IMediaRecorderClient> mListener;
};
- void clearDeathNotifiers_l();
-
public:
virtual status_t setCamera(const sp<hardware::ICamera>& camera,
const sp<ICameraRecordingProxy>& proxy);
@@ -122,8 +94,7 @@
const String16& opPackageName);
virtual ~MediaRecorderClient();
- sp<ServiceDeathNotifier> mCameraDeathListener;
- sp<ServiceDeathNotifier> mCodecDeathListener;
+ std::vector<DeathNotifier> mDeathNotifiers;
sp<AudioDeviceUpdatedNotifier> mAudioDeviceUpdatedNotifier;
pid_t mPid;
diff --git a/services/audioflinger/Threads.cpp b/services/audioflinger/Threads.cpp
index 59ced26..711a6dd 100644
--- a/services/audioflinger/Threads.cpp
+++ b/services/audioflinger/Threads.cpp
@@ -7454,8 +7454,10 @@
// we formerly checked for a callback handler (non-0 tid),
// but that is no longer required for TRANSFER_OBTAIN mode
//
- // frame count is not specified, or is exactly the pipe depth
- ((frameCount == 0) || (frameCount == mPipeFramesP2)) &&
+ // Frame count is not specified (0), or is less than or equal the pipe depth.
+ // It is OK to provide a higher capacity than requested.
+ // We will force it to mPipeFramesP2 below.
+ (frameCount <= mPipeFramesP2) &&
// PCM data
audio_is_linear_pcm(format) &&
// hardware format
diff --git a/services/audiopolicy/enginedefault/src/Engine.cpp b/services/audiopolicy/enginedefault/src/Engine.cpp
index 4135f01..04170ac 100644
--- a/services/audiopolicy/enginedefault/src/Engine.cpp
+++ b/services/audiopolicy/enginedefault/src/Engine.cpp
@@ -506,7 +506,9 @@
const DeviceVector availableInputDevices = getApmObserver()->getAvailableInputDevices();
const SwAudioOutputCollection &outputs = getApmObserver()->getOutputs();
audio_devices_t availableDeviceTypes = availableInputDevices.types() & ~AUDIO_DEVICE_BIT_IN;
-
+ sp<AudioOutputDescriptor> primaryOutput = outputs.getPrimaryOutput();
+ audio_devices_t availablePrimaryDeviceTypes = availableInputDevices.getDeviceTypesFromHwModule(
+ primaryOutput->getModuleHandle()) & ~AUDIO_DEVICE_BIT_IN;
uint32_t device = AUDIO_DEVICE_NONE;
// when a call is active, force device selection to match source VOICE_COMMUNICATION
@@ -528,13 +530,6 @@
}
switch (inputSource) {
- case AUDIO_SOURCE_VOICE_UPLINK:
- if (availableDeviceTypes & AUDIO_DEVICE_IN_VOICE_CALL) {
- device = AUDIO_DEVICE_IN_VOICE_CALL;
- break;
- }
- break;
-
case AUDIO_SOURCE_DEFAULT:
case AUDIO_SOURCE_MIC:
if (availableDeviceTypes & AUDIO_DEVICE_IN_BLUETOOTH_A2DP) {
@@ -558,9 +553,7 @@
// to voice call path.
if ((getPhoneState() == AUDIO_MODE_IN_CALL) &&
(availableOutputDevices.types() & AUDIO_DEVICE_OUT_TELEPHONY_TX) == 0) {
- sp<AudioOutputDescriptor> primaryOutput = outputs.getPrimaryOutput();
- availableDeviceTypes = availableInputDevices.getDeviceTypesFromHwModule(
- primaryOutput->getModuleHandle()) & ~AUDIO_DEVICE_BIT_IN;
+ availableDeviceTypes = availablePrimaryDeviceTypes;
}
switch (getForceUse(AUDIO_POLICY_FORCE_FOR_COMMUNICATION)) {
@@ -597,6 +590,9 @@
case AUDIO_SOURCE_VOICE_RECOGNITION:
case AUDIO_SOURCE_UNPROCESSED:
case AUDIO_SOURCE_HOTWORD:
+ if (inputSource == AUDIO_SOURCE_HOTWORD) {
+ availableDeviceTypes = availablePrimaryDeviceTypes;
+ }
if (getForceUse(AUDIO_POLICY_FORCE_FOR_RECORD) == AUDIO_POLICY_FORCE_BT_SCO &&
availableDeviceTypes & AUDIO_DEVICE_IN_BLUETOOTH_SCO_HEADSET) {
device = AUDIO_DEVICE_IN_BLUETOOTH_SCO_HEADSET;
@@ -622,6 +618,7 @@
break;
case AUDIO_SOURCE_VOICE_DOWNLINK:
case AUDIO_SOURCE_VOICE_CALL:
+ case AUDIO_SOURCE_VOICE_UPLINK:
if (availableDeviceTypes & AUDIO_DEVICE_IN_VOICE_CALL) {
device = AUDIO_DEVICE_IN_VOICE_CALL;
}
diff --git a/services/audiopolicy/managerdefault/AudioPolicyManager.cpp b/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
index 6bd64d6..7011ef7 100644
--- a/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
+++ b/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
@@ -273,8 +273,6 @@
// handle input devices
if (audio_is_input_device(deviceType)) {
- SortedVector <audio_io_handle_t> inputs;
-
ssize_t index = mAvailableInputDevices.indexOf(device);
switch (state)
{
@@ -284,11 +282,18 @@
ALOGW("%s() device already connected: %s", __func__, device->toString().c_str());
return INVALID_OPERATION;
}
+
+ if (mAvailableInputDevices.add(device) < 0) {
+ return NO_MEMORY;
+ }
+
// Before checking intputs, broadcast connect event to allow HAL to retrieve dynamic
// parameters on newly connected devices (instead of opening the inputs...)
broadcastDeviceConnectionState(device, state);
- if (checkInputsForDevice(device, state, inputs) != NO_ERROR) {
+ if (checkInputsForDevice(device, state) != NO_ERROR) {
+ mAvailableInputDevices.remove(device);
+
broadcastDeviceConnectionState(device, AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE);
mHwModules.cleanUpForDevice(device);
@@ -296,9 +301,6 @@
return INVALID_OPERATION;
}
- if (mAvailableInputDevices.add(device) < 0) {
- return NO_MEMORY;
- }
} break;
// handle input device disconnection
@@ -313,8 +315,9 @@
// Set Disconnect to HALs
broadcastDeviceConnectionState(device, state);
- checkInputsForDevice(device, state, inputs);
mAvailableInputDevices.remove(device);
+
+ checkInputsForDevice(device, state);
} break;
default:
@@ -325,7 +328,7 @@
// Propagate device availability to Engine
setEngineDeviceConnectionState(device, state);
- closeAllInputs();
+ checkCloseInputs();
// As the input device list can impact the output device selection, update
// getDeviceForStrategy() cache
updateDevicesAndOutputs();
@@ -2342,9 +2345,39 @@
releaseInput(portId);
}
-void AudioPolicyManager::closeAllInputs() {
- while (mInputs.size() != 0) {
- closeInput(mInputs.keyAt(0));
+void AudioPolicyManager::checkCloseInputs() {
+ // After connecting or disconnecting an input device, close input if:
+ // - it has no client (was just opened to check profile) OR
+ // - none of its supported devices are connected anymore OR
+ // - one of its clients cannot be routed to one of its supported
+ // devices anymore. Otherwise update device selection
+ std::vector<audio_io_handle_t> inputsToClose;
+ for (size_t i = 0; i < mInputs.size(); i++) {
+ const sp<AudioInputDescriptor> input = mInputs.valueAt(i);
+ if (input->clientsList().size() == 0
+ || !mAvailableInputDevices.containsAtLeastOne(input->supportedDevices())) {
+ inputsToClose.push_back(mInputs.keyAt(i));
+ } else {
+ bool close = false;
+ for (const auto& client : input->clientsList()) {
+ sp<DeviceDescriptor> device =
+ mEngine->getInputDeviceForAttributes(client->attributes());
+ if (!input->supportedDevices().contains(device)) {
+ close = true;
+ break;
+ }
+ }
+ if (close) {
+ inputsToClose.push_back(mInputs.keyAt(i));
+ } else {
+ setInputDevice(input->mIoHandle, getNewInputDevice(input));
+ }
+ }
+ }
+
+ for (const audio_io_handle_t handle : inputsToClose) {
+ ALOGV("%s closing input %d", __func__, handle);
+ closeInput(handle);
}
}
@@ -4684,8 +4717,7 @@
}
status_t AudioPolicyManager::checkInputsForDevice(const sp<DeviceDescriptor>& device,
- audio_policy_dev_state_t state,
- SortedVector<audio_io_handle_t>& inputs)
+ audio_policy_dev_state_t state)
{
sp<AudioInputDescriptor> desc;
@@ -4695,16 +4727,7 @@
}
if (state == AUDIO_POLICY_DEVICE_STATE_AVAILABLE) {
- // first list already open inputs that can be routed to this device
- for (size_t input_index = 0; input_index < mInputs.size(); input_index++) {
- desc = mInputs.valueAt(input_index);
- if (desc->mProfile->supportsDeviceTypes(device->type())) {
- ALOGV("checkInputsForDevice(): adding opened input %d", mInputs.keyAt(input_index));
- inputs.add(mInputs.keyAt(input_index));
- }
- }
-
- // then look for input profiles that can be routed to this device
+ // look for input profiles that can be routed to this device
SortedVector< sp<IOProfile> > profiles;
for (const auto& hwModule : mHwModules) {
for (size_t profile_index = 0;
@@ -4720,8 +4743,9 @@
}
}
- if (profiles.isEmpty() && inputs.isEmpty()) {
- ALOGW("%s: No input available for device %s", __func__, device->toString().c_str());
+ if (profiles.isEmpty()) {
+ ALOGW("%s: No input profile available for device %s",
+ __func__, device->toString().c_str());
return BAD_VALUE;
}
@@ -4774,7 +4798,7 @@
input = AUDIO_IO_HANDLE_NONE;
}
- if (input != 0) {
+ if (input != AUDIO_IO_HANDLE_NONE) {
addInput(input, desc);
}
} // endif input != 0
@@ -4785,7 +4809,6 @@
profiles.removeAt(profile_index);
profile_index--;
} else {
- inputs.add(input);
if (audio_device_is_digital(device->type())) {
device->importAudioPort(profile);
}
@@ -4799,15 +4822,6 @@
}
} else {
// Disconnect
- // check if one opened input is not needed any more after disconnecting one device
- for (size_t input_index = 0; input_index < mInputs.size(); input_index++) {
- desc = mInputs.valueAt(input_index);
- if (!mAvailableInputDevices.containsAtLeastOne(desc->supportedDevices())) {
- ALOGV("checkInputsForDevice(): disconnecting adding input %d",
- mInputs.keyAt(input_index));
- inputs.add(mInputs.keyAt(input_index));
- }
- }
// Clear any profiles associated with the disconnected device.
for (const auto& hwModule : mHwModules) {
for (size_t profile_index = 0;
diff --git a/services/audiopolicy/managerdefault/AudioPolicyManager.h b/services/audiopolicy/managerdefault/AudioPolicyManager.h
index 3376965..8ca06e7 100644
--- a/services/audiopolicy/managerdefault/AudioPolicyManager.h
+++ b/services/audiopolicy/managerdefault/AudioPolicyManager.h
@@ -142,7 +142,7 @@
// indicates to the audio policy manager that the input stops being used.
virtual status_t stopInput(audio_port_handle_t portId);
virtual void releaseInput(audio_port_handle_t portId);
- virtual void closeAllInputs();
+ virtual void checkCloseInputs();
/**
* @brief initStreamVolume: even if the engine volume files provides min and max, keep this
* api for compatibility reason.
@@ -486,8 +486,7 @@
SortedVector<audio_io_handle_t>& outputs);
status_t checkInputsForDevice(const sp<DeviceDescriptor>& device,
- audio_policy_dev_state_t state,
- SortedVector<audio_io_handle_t>& inputs);
+ audio_policy_dev_state_t state);
// close an output and its companion duplicating output.
void closeOutput(audio_io_handle_t output);
diff --git a/services/camera/libcameraservice/CameraService.cpp b/services/camera/libcameraservice/CameraService.cpp
index a1cb8ee..fc6d6be 100644
--- a/services/camera/libcameraservice/CameraService.cpp
+++ b/services/camera/libcameraservice/CameraService.cpp
@@ -1638,6 +1638,11 @@
}
}
+ int clientPid = CameraThreadState::getCallingPid();
+ const char *id_cstr = id.c_str();
+ const char *torchState = enabled ? "on" : "off";
+ ALOGI("Torch for camera id %s turned %s for client PID %d", id_cstr, torchState, clientPid);
+ logTorchEvent(id_cstr, torchState , clientPid);
return Status::ok();
}
@@ -2122,6 +2127,12 @@
cameraId, clientPackage, clientPid, reason));
}
+void CameraService::logTorchEvent(const char* cameraId, const char *torchState, int clientPid) {
+ // Log torch event
+ logEvent(String8::format("Torch for camera id %s turned %s for client PID %d", cameraId,
+ torchState, clientPid));
+}
+
void CameraService::logUserSwitch(const std::set<userid_t>& oldUserIds,
const std::set<userid_t>& newUserIds) {
String8 newUsers = toString(newUserIds);
diff --git a/services/camera/libcameraservice/CameraService.h b/services/camera/libcameraservice/CameraService.h
index a8c2606..b8cec2c 100644
--- a/services/camera/libcameraservice/CameraService.h
+++ b/services/camera/libcameraservice/CameraService.h
@@ -748,6 +748,11 @@
const char* reason);
/**
+ * Add an event log message when a client calls setTorchMode succesfully.
+ */
+ void logTorchEvent(const char* cameraId, const char *torchState, int clientPid);
+
+ /**
* Add an event log message that the current device user has been switched.
*/
void logUserSwitch(const std::set<userid_t>& oldUserIds,