Merge changes from topic "c2hal_vts_0307"
* changes:
codec2: VTS add support for Empty EOS in AudioDectest
codec2: VTS fix Master test for multiple IComponent services
codec2: VTS add support for nSamplesPerFrame in AudioEnctest
codec2: VTS add support for Empty EOS in VideoEnctest
codec2: VTS add support for Empty EOS in VideoDectest
codec2: VTS add support for Empty EOS in AudioEnctest
VTS: Fix DecodeTest For Audio Decoders.
diff --git a/apex/Android.bp b/apex/Android.bp
index f182856..0a9551d 100644
--- a/apex/Android.bp
+++ b/apex/Android.bp
@@ -65,8 +65,13 @@
apex_defaults {
name: "com.android.media.swcodec-defaults",
- native_shared_libs: [
- "libmedia_codecserviceregistrant",
+ binaries: [
+ "mediaswcodec",
+ ],
+ prebuilts: [
+ "com.android.media.swcodec-mediaswcodec.rc",
+ "com.android.media.swcodec-ld.config.txt",
+ "mediaswcodec.policy",
],
use_vendor: true,
key: "com.android.media.swcodec.key",
@@ -76,6 +81,20 @@
androidManifest: ":com.android.media.swcodec-androidManifest",
}
+prebuilt_etc {
+ name: "com.android.media.swcodec-mediaswcodec.rc",
+ src: "mediaswcodec.rc",
+ filename: "init.rc",
+ installable: false,
+}
+
+prebuilt_etc {
+ name: "com.android.media.swcodec-ld.config.txt",
+ src: "ld.config.txt",
+ filename: "ld.config.txt",
+ installable: false,
+}
+
apex {
name: "com.android.media.swcodec",
manifest: "manifest_codec.json",
diff --git a/apex/ld.config.txt b/apex/ld.config.txt
new file mode 100644
index 0000000..a3e96c4
--- /dev/null
+++ b/apex/ld.config.txt
@@ -0,0 +1,74 @@
+# Copyright (C) 2019 The Android Open Source Project
+#
+# Bionic loader config file for the media swcodec APEX.
+#
+# There are no versioned APEX paths here - this APEX module does not support
+# having several versions mounted.
+
+dir.swcodec = /apex/com.android.media.swcodec/bin/
+
+[swcodec]
+additional.namespaces = platform
+
+###############################################################################
+# "default" namespace
+#
+# This namespace is for the binaries and libraries on the swcodec APEX.
+###############################################################################
+
+namespace.default.isolated = true
+namespace.default.visible = true
+
+namespace.default.search.paths = /apex/com.android.media.swcodec/${LIB}
+namespace.default.asan.search.paths = /apex/com.android.media.swcodec/${LIB}
+
+# Keep the below in sync with "sphal" namespace in system's /etc/ld.config.txt
+# Codec2 has dependencies on some SP-hals (eg. android.hardware.graphics.mapper@2.0)
+# These are dlopen'ed by libvndksupport.so.
+namespace.default.search.paths += /odm/${LIB}
+namespace.default.search.paths += /vendor/${LIB}
+
+namespace.default.permitted.paths = /odm/${LIB}
+namespace.default.permitted.paths += /vendor/${LIB}
+namespace.default.permitted.paths += /vendor/${LIB}/hw
+namespace.default.permitted.paths += /system/vendor/${LIB}
+
+namespace.default.asan.search.paths += /data/asan/odm/${LIB}
+namespace.default.asan.search.paths += /odm/${LIB}
+namespace.default.asan.search.paths += /data/asan/vendor/${LIB}
+namespace.default.asan.search.paths += /vendor/${LIB}
+
+namespace.default.asan.permitted.paths = /data/asan/odm/${LIB}
+namespace.default.asan.permitted.paths += /odm/${LIB}
+namespace.default.asan.permitted.paths += /data/asan/vendor/${LIB}
+namespace.default.asan.permitted.paths += /vendor/${LIB}
+
+namespace.default.links = platform
+
+# TODO: replace the following when apex has a way to auto-generate this list
+# namespace.default.link.platform.shared_libs = %LLNDK_LIBRARIES%
+# namespace.default.link.platform.shared_libs += %SANITIZER_RUNTIME_LIBRARIES%
+namespace.default.link.platform.shared_libs = libEGL.so:libGLESv1_CM.so:libGLESv2.so:libGLESv3.so:libRS.so:libandroid_net.so:libc.so:libclang_rt.asan-aarch64-android.so:libclang_rt.asan-arm-android.so:libclang_rt.hwasan-aarch64-android.so:libclang_rt.asan-i686-android.so:libclang_rt.asan-x86_64-android.so:libdl.so:libft2.so:liblog.so:libm.so:libmediandk.so:libnativewindow.so:libneuralnetworks.so:libsync.so:libvndksupport.so:libvulkan.so
+
+###############################################################################
+# "platform" namespace
+#
+# This namespace is for linking to LLNDK and ASAN libraries on the system.
+###############################################################################
+
+namespace.platform.isolated = true
+
+namespace.platform.search.paths = /system/${LIB}
+namespace.platform.asan.search.paths = /data/asan/system/${LIB}
+
+# /system/lib/libc.so, etc are symlinks to /bionic/lib/libc.so, etc.
+# Add /bionic/lib to the permitted paths because linker uses realpath(3)
+# to check the accessibility of the lib. We could add this to search.paths
+# instead but that makes the resolution of bionic libs be dependent on
+# the order of /system/lib and /bionic/lib in search.paths. If /bionic/lib
+# is after /system/lib, then /bionic/lib is never tried because libc.so
+# is always found in /system/lib but fails to pass the accessibility test
+# because of its realpath. It's better to not depend on the ordering if
+# possible.
+namespace.platform.permitted.paths = /bionic/${LIB}
+namespace.platform.asan.permitted.paths = /bionic/${LIB}
diff --git a/apex/mediaswcodec.rc b/apex/mediaswcodec.rc
new file mode 100644
index 0000000..d17481b
--- /dev/null
+++ b/apex/mediaswcodec.rc
@@ -0,0 +1,7 @@
+service media.swcodec /apex/com.android.media.swcodec/bin/mediaswcodec
+ class main
+ user mediacodec
+ group camera drmrpc mediadrm
+ override
+ ioprio rt 4
+ writepid /dev/cpuset/foreground/tasks
diff --git a/camera/ndk/impl/ACameraMetadata.cpp b/camera/ndk/impl/ACameraMetadata.cpp
index 359eaed..d832deb 100644
--- a/camera/ndk/impl/ACameraMetadata.cpp
+++ b/camera/ndk/impl/ACameraMetadata.cpp
@@ -215,7 +215,7 @@
const int STREAM_HEIGHT_OFFSET = 2;
const int STREAM_IS_INPUT_OFFSET = 3;
camera_metadata_entry entry = mData.find(ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS);
- if (entry.count == 0 || entry.count % 4 || entry.type != TYPE_INT32) {
+ if (entry.count > 0 && (entry.count % 4 || entry.type != TYPE_INT32)) {
ALOGE("%s: malformed available stream configuration key! count %zu, type %d",
__FUNCTION__, entry.count, entry.type);
return;
@@ -243,9 +243,17 @@
filteredStreamConfigs.push_back(isInput);
}
- mData.update(ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS, filteredStreamConfigs);
+ if (filteredStreamConfigs.size() > 0) {
+ mData.update(ANDROID_SCALER_AVAILABLE_STREAM_CONFIGURATIONS, filteredStreamConfigs);
+ }
entry = mData.find(ANDROID_DEPTH_AVAILABLE_DEPTH_STREAM_CONFIGURATIONS);
+ if (entry.count > 0 && (entry.count % 4 || entry.type != TYPE_INT32)) {
+ ALOGE("%s: malformed available depth stream configuration key! count %zu, type %d",
+ __FUNCTION__, entry.count, entry.type);
+ return;
+ }
+
Vector<int32_t> filteredDepthStreamConfigs;
filteredDepthStreamConfigs.setCapacity(entry.count);
@@ -270,7 +278,11 @@
filteredDepthStreamConfigs.push_back(height);
filteredDepthStreamConfigs.push_back(isInput);
}
- mData.update(ANDROID_DEPTH_AVAILABLE_DEPTH_STREAM_CONFIGURATIONS, filteredDepthStreamConfigs);
+
+ if (filteredDepthStreamConfigs.size() > 0) {
+ mData.update(ANDROID_DEPTH_AVAILABLE_DEPTH_STREAM_CONFIGURATIONS,
+ filteredDepthStreamConfigs);
+ }
entry = mData.find(ANDROID_HEIC_AVAILABLE_HEIC_STREAM_CONFIGURATIONS);
Vector<int32_t> filteredHeicStreamConfigs;
diff --git a/drm/mediadrm/plugins/clearkey/hidl/CryptoPlugin.cpp b/drm/mediadrm/plugins/clearkey/hidl/CryptoPlugin.cpp
index fc0cceb..23a35e5 100644
--- a/drm/mediadrm/plugins/clearkey/hidl/CryptoPlugin.cpp
+++ b/drm/mediadrm/plugins/clearkey/hidl/CryptoPlugin.cpp
@@ -135,7 +135,7 @@
}
if (destBuffer.offset + destBuffer.size > destBase->getSize()) {
- _hidl_cb(Status_V1_2::ERROR_DRM_CANNOT_HANDLE, 0, "invalid buffer size");
+ _hidl_cb(Status_V1_2::ERROR_DRM_FRAME_TOO_LARGE, 0, "invalid buffer size");
return Void();
}
destPtr = static_cast<void *>(base + destination.nonsecureMemory.offset);
diff --git a/media/extractors/mp4/MPEG4Extractor.cpp b/media/extractors/mp4/MPEG4Extractor.cpp
index 9f27528..93f34a8 100755
--- a/media/extractors/mp4/MPEG4Extractor.cpp
+++ b/media/extractors/mp4/MPEG4Extractor.cpp
@@ -1487,8 +1487,13 @@
}
}
if (duration != 0 && mLastTrack->timescale != 0) {
- AMediaFormat_setInt64(mLastTrack->meta, AMEDIAFORMAT_KEY_DURATION,
- (duration * 1000000) / mLastTrack->timescale);
+ long double durationUs = ((long double)duration * 1000000) / mLastTrack->timescale;
+ if (durationUs < 0 || durationUs > INT64_MAX) {
+ ALOGE("cannot represent %lld * 1000000 / %lld in 64 bits",
+ (long long) duration, (long long) mLastTrack->timescale);
+ return ERROR_MALFORMED;
+ }
+ AMediaFormat_setInt64(mLastTrack->meta, AMEDIAFORMAT_KEY_DURATION, durationUs);
}
uint8_t lang[2];
@@ -5402,7 +5407,7 @@
break;
}
if( mode != ReadOptions::SEEK_FRAME_INDEX) {
- seekTimeUs += ((int64_t)mElstShiftStartTicks * 1000000) / mTimescale;
+ seekTimeUs += ((long double)mElstShiftStartTicks * 1000000) / mTimescale;
}
uint32_t sampleIndex;
@@ -5550,7 +5555,7 @@
AMediaFormat *meta = mBuffer->meta_data();
AMediaFormat_clear(meta);
AMediaFormat_setInt64(
- meta, AMEDIAFORMAT_KEY_TIME_US, ((int64_t)cts * 1000000) / mTimescale);
+ meta, AMEDIAFORMAT_KEY_TIME_US, ((long double)cts * 1000000) / mTimescale);
AMediaFormat_setInt32(meta, AMEDIAFORMAT_KEY_IS_SYNC_FRAME, 1);
int32_t byteOrder;
@@ -5585,9 +5590,9 @@
AMediaFormat *meta = mBuffer->meta_data();
AMediaFormat_clear(meta);
AMediaFormat_setInt64(
- meta, AMEDIAFORMAT_KEY_TIME_US, ((int64_t)cts * 1000000) / mTimescale);
+ meta, AMEDIAFORMAT_KEY_TIME_US, ((long double)cts * 1000000) / mTimescale);
AMediaFormat_setInt64(
- meta, AMEDIAFORMAT_KEY_DURATION, ((int64_t)stts * 1000000) / mTimescale);
+ meta, AMEDIAFORMAT_KEY_DURATION, ((long double)stts * 1000000) / mTimescale);
if (targetSampleTimeUs >= 0) {
AMediaFormat_setInt64(
@@ -5641,9 +5646,9 @@
AMediaFormat *meta = mBuffer->meta_data();
AMediaFormat_clear(meta);
AMediaFormat_setInt64(
- meta, AMEDIAFORMAT_KEY_TIME_US, ((int64_t)cts * 1000000) / mTimescale);
+ meta, AMEDIAFORMAT_KEY_TIME_US, ((long double)cts * 1000000) / mTimescale);
AMediaFormat_setInt64(
- meta, AMEDIAFORMAT_KEY_DURATION, ((int64_t)stts * 1000000) / mTimescale);
+ meta, AMEDIAFORMAT_KEY_DURATION, ((long double)stts * 1000000) / mTimescale);
if (targetSampleTimeUs >= 0) {
AMediaFormat_setInt64(
@@ -5722,9 +5727,9 @@
AMediaFormat *meta = mBuffer->meta_data();
AMediaFormat_clear(meta);
AMediaFormat_setInt64(
- meta, AMEDIAFORMAT_KEY_TIME_US, ((int64_t)cts * 1000000) / mTimescale);
+ meta, AMEDIAFORMAT_KEY_TIME_US, ((long double)cts * 1000000) / mTimescale);
AMediaFormat_setInt64(
- meta, AMEDIAFORMAT_KEY_DURATION, ((int64_t)stts * 1000000) / mTimescale);
+ meta, AMEDIAFORMAT_KEY_DURATION, ((long double)stts * 1000000) / mTimescale);
if (targetSampleTimeUs >= 0) {
AMediaFormat_setInt64(
@@ -5771,7 +5776,7 @@
ReadOptions::SeekMode mode;
if (options && options->getSeekTo(&seekTimeUs, &mode)) {
- seekTimeUs += ((int64_t)mElstShiftStartTicks * 1000000) / mTimescale;
+ seekTimeUs += ((long double)mElstShiftStartTicks * 1000000) / mTimescale;
ALOGV("shifted seekTimeUs :%" PRId64 ", mElstShiftStartTicks:%" PRId32, seekTimeUs,
mElstShiftStartTicks);
@@ -5932,9 +5937,9 @@
CHECK(mBuffer != NULL);
mBuffer->set_range(0, size);
AMediaFormat_setInt64(bufmeta,
- AMEDIAFORMAT_KEY_TIME_US, ((int64_t)cts * 1000000) / mTimescale);
+ AMEDIAFORMAT_KEY_TIME_US, ((long double)cts * 1000000) / mTimescale);
AMediaFormat_setInt64(bufmeta,
- AMEDIAFORMAT_KEY_DURATION, ((int64_t)smpl->duration * 1000000) / mTimescale);
+ AMEDIAFORMAT_KEY_DURATION, ((long double)smpl->duration * 1000000) / mTimescale);
if (targetSampleTimeUs >= 0) {
AMediaFormat_setInt64(bufmeta, AMEDIAFORMAT_KEY_TARGET_TIME, targetSampleTimeUs);
@@ -6047,9 +6052,9 @@
AMediaFormat *bufmeta = mBuffer->meta_data();
AMediaFormat_setInt64(bufmeta,
- AMEDIAFORMAT_KEY_TIME_US, ((int64_t)cts * 1000000) / mTimescale);
+ AMEDIAFORMAT_KEY_TIME_US, ((long double)cts * 1000000) / mTimescale);
AMediaFormat_setInt64(bufmeta,
- AMEDIAFORMAT_KEY_DURATION, ((int64_t)smpl->duration * 1000000) / mTimescale);
+ AMEDIAFORMAT_KEY_DURATION, ((long double)smpl->duration * 1000000) / mTimescale);
if (targetSampleTimeUs >= 0) {
AMediaFormat_setInt64(bufmeta, AMEDIAFORMAT_KEY_TARGET_TIME, targetSampleTimeUs);
diff --git a/media/libstagefright/VideoFrameScheduler2.cpp b/media/libstagefright/VideoFrameScheduler2.cpp
index fc76904..23671f2 100644
--- a/media/libstagefright/VideoFrameScheduler2.cpp
+++ b/media/libstagefright/VideoFrameScheduler2.cpp
@@ -160,13 +160,13 @@
mPhase = (long) (atan2(sampleAvgY, sampleAvgX) / scale);
}
-static void frameCallback(long frameTimeNanos, void* data) {
+static void frameCallback(int64_t frameTimeNanos, void* data) {
if (data == NULL) {
return;
}
sp<VsyncTracker> vsyncTracker(static_cast<VsyncTracker*>(data));
vsyncTracker->addSample(frameTimeNanos);
- AChoreographer_postFrameCallback(AChoreographer_getInstance(),
+ AChoreographer_postFrameCallback64(AChoreographer_getInstance(),
frameCallback, static_cast<void*>(vsyncTracker.get()));
}
@@ -247,7 +247,7 @@
if (AChoreographer_getInstance() == NULL) {
return NO_INIT;
}
- AChoreographer_postFrameCallback(AChoreographer_getInstance(), frameCallback, mData);
+ AChoreographer_postFrameCallback64(AChoreographer_getInstance(), frameCallback, mData);
return OK;
}
diff --git a/media/libstagefright/rtsp/APacketSource.cpp b/media/libstagefright/rtsp/APacketSource.cpp
index b964bc0..1aa8a20 100644
--- a/media/libstagefright/rtsp/APacketSource.cpp
+++ b/media/libstagefright/rtsp/APacketSource.cpp
@@ -376,8 +376,8 @@
ALOGI("VOL dimensions = %dx%d", *width, *height);
size_t len1 = config->size() + GetSizeWidth(config->size()) + 1;
- size_t len2 = len1 + GetSizeWidth(len1) + 1 + 13;
- size_t len3 = len2 + GetSizeWidth(len2) + 1 + 3;
+ size_t len2 = len1 + GetSizeWidth(len1 + 13) + 1 + 13;
+ size_t len3 = len2 + GetSizeWidth(len2 + 3) + 1 + 3;
sp<ABuffer> csd = new ABuffer(len3);
uint8_t *dst = csd->data();
diff --git a/services/OWNERS b/services/OWNERS
index d5d00da..66a4bcb 100644
--- a/services/OWNERS
+++ b/services/OWNERS
@@ -1,4 +1,7 @@
+chz@google.com
elaurent@google.com
+essick@google.com
etalvala@google.com
gkasten@google.com
hunga@google.com
+marcone@google.com
diff --git a/services/audioflinger/AudioFlinger.cpp b/services/audioflinger/AudioFlinger.cpp
index 4033247..213c9c3 100644
--- a/services/audioflinger/AudioFlinger.cpp
+++ b/services/audioflinger/AudioFlinger.cpp
@@ -836,8 +836,10 @@
}
teePatches.push_back({patchRecord, patchTrack});
secondaryThread->addPatchTrack(patchTrack);
- patchTrack->setPeerProxy(patchRecord.get());
- patchRecord->setPeerProxy(patchTrack.get());
+ // In case the downstream patchTrack on the secondaryThread temporarily outlives
+ // our created track, ensure the corresponding patchRecord is still alive.
+ patchTrack->setPeerProxy(patchRecord, true /* holdReference */);
+ patchRecord->setPeerProxy(patchTrack, false /* holdReference */);
}
track->setTeePatches(std::move(teePatches));
}
diff --git a/services/audioflinger/PatchPanel.cpp b/services/audioflinger/PatchPanel.cpp
index 676a575..13243b8 100644
--- a/services/audioflinger/PatchPanel.cpp
+++ b/services/audioflinger/PatchPanel.cpp
@@ -527,8 +527,8 @@
}
// tie playback and record tracks together
- mRecord.setTrackAndPeer(tempRecordTrack, tempPatchTrack.get());
- mPlayback.setTrackAndPeer(tempPatchTrack, tempRecordTrack.get());
+ mRecord.setTrackAndPeer(tempRecordTrack, tempPatchTrack);
+ mPlayback.setTrackAndPeer(tempPatchTrack, tempRecordTrack);
// start capture and playback
mRecord.track()->start(AudioSystem::SYNC_EVENT_NONE, AUDIO_SESSION_NONE);
@@ -543,6 +543,7 @@
__func__, mRecord.handle(), mPlayback.handle());
mRecord.stopTrack();
mPlayback.stopTrack();
+ mRecord.track()->clearPeerProxy(); // mRecord stop is synchronous. Break PeerProxy sp<> cycle.
mRecord.closeConnections(panel);
mPlayback.closeConnections(panel);
}
diff --git a/services/audioflinger/PatchPanel.h b/services/audioflinger/PatchPanel.h
index 612855f..aba2cc2 100644
--- a/services/audioflinger/PatchPanel.h
+++ b/services/audioflinger/PatchPanel.h
@@ -122,11 +122,11 @@
mThread = thread;
mCloseThread = closeThread;
}
- void setTrackAndPeer(const sp<TrackType>& track,
- ThreadBase::PatchProxyBufferProvider *peer) {
+ template <typename T>
+ void setTrackAndPeer(const sp<TrackType>& track, const sp<T> &peer) {
mTrack = track;
mThread->addPatchTrack(mTrack);
- mTrack->setPeerProxy(peer);
+ mTrack->setPeerProxy(peer, true /* holdReference */);
}
void stopTrack() { if (mTrack) mTrack->stop(); }
diff --git a/services/audioflinger/Threads.cpp b/services/audioflinger/Threads.cpp
index f4a31ed..49f74a2 100644
--- a/services/audioflinger/Threads.cpp
+++ b/services/audioflinger/Threads.cpp
@@ -7683,6 +7683,8 @@
// note that threadLoop may still be processing the track at this point [without lock]
recordTrack->mState = TrackBase::PAUSING;
+ // NOTE: Waiting here is important to keep stop synchronous.
+ // This is needed for proper patchRecord peer release.
while (recordTrack->mState == TrackBase::PAUSING && !recordTrack->isInvalid()) {
mWaitWorkCV.broadcast(); // signal thread to stop
mStartStopCond.wait(mLock);
diff --git a/services/audioflinger/TrackBase.h b/services/audioflinger/TrackBase.h
index 0ba0ab4..e23173f 100644
--- a/services/audioflinger/TrackBase.h
+++ b/services/audioflinger/TrackBase.h
@@ -337,10 +337,19 @@
PatchTrackBase(sp<ClientProxy> proxy, const ThreadBase& thread,
const Timeout& timeout);
void setPeerTimeout(std::chrono::nanoseconds timeout);
- void setPeerProxy(PatchProxyBufferProvider *proxy) { mPeerProxy = proxy; }
+ template <typename T>
+ void setPeerProxy(const sp<T> &proxy, bool holdReference) {
+ mPeerReferenceHold = holdReference ? proxy : nullptr;
+ mPeerProxy = proxy.get();
+ }
+ void clearPeerProxy() {
+ mPeerReferenceHold.clear();
+ mPeerProxy = nullptr;
+ }
protected:
const sp<ClientProxy> mProxy;
+ sp<RefBase> mPeerReferenceHold; // keeps mPeerProxy alive during access.
PatchProxyBufferProvider* mPeerProxy = nullptr;
struct timespec mPeerTimeout{};
diff --git a/services/audioflinger/Tracks.cpp b/services/audioflinger/Tracks.cpp
index ad78a45..5a43696 100644
--- a/services/audioflinger/Tracks.cpp
+++ b/services/audioflinger/Tracks.cpp
@@ -1723,6 +1723,7 @@
AudioFlinger::PlaybackThread::PatchTrack::~PatchTrack()
{
+ ALOGV("%s(%d)", __func__, mId);
}
status_t AudioFlinger::PlaybackThread::PatchTrack::start(AudioSystem::sync_event_t event,
@@ -2193,6 +2194,7 @@
AudioFlinger::RecordThread::PatchRecord::~PatchRecord()
{
+ ALOGV("%s(%d)", __func__, mId);
}
// AudioBufferProvider interface
diff --git a/services/camera/libcameraservice/device3/Camera3BufferManager.cpp b/services/camera/libcameraservice/device3/Camera3BufferManager.cpp
index 8c8b97a..d6bf83e 100644
--- a/services/camera/libcameraservice/device3/Camera3BufferManager.cpp
+++ b/services/camera/libcameraservice/device3/Camera3BufferManager.cpp
@@ -237,7 +237,7 @@
}
status_t Camera3BufferManager::getBufferForStream(int streamId, int streamSetId,
- sp<GraphicBuffer>* gb, int* fenceFd) {
+ sp<GraphicBuffer>* gb, int* fenceFd, bool noFreeBufferAtConsumer) {
ATRACE_CALL();
Mutex::Autolock l(mLock);
@@ -253,14 +253,19 @@
StreamSet &streamSet = mStreamSetMap.editValueFor(streamSetId);
BufferCountMap& handOutBufferCounts = streamSet.handoutBufferCountMap;
size_t& bufferCount = handOutBufferCounts.editValueFor(streamId);
+ BufferCountMap& attachedBufferCounts = streamSet.attachedBufferCountMap;
+ size_t& attachedBufferCount = attachedBufferCounts.editValueFor(streamId);
+
+ if (noFreeBufferAtConsumer) {
+ attachedBufferCount = bufferCount;
+ }
+
if (bufferCount >= streamSet.maxAllowedBufferCount) {
ALOGE("%s: bufferCount (%zu) exceeds the max allowed buffer count (%zu) of this stream set",
__FUNCTION__, bufferCount, streamSet.maxAllowedBufferCount);
return INVALID_OPERATION;
}
- BufferCountMap& attachedBufferCounts = streamSet.attachedBufferCountMap;
- size_t& attachedBufferCount = attachedBufferCounts.editValueFor(streamId);
if (attachedBufferCount > bufferCount) {
// We've already attached more buffers to this stream than we currently have
// outstanding, so have the stream just use an already-attached buffer
diff --git a/services/camera/libcameraservice/device3/Camera3BufferManager.h b/services/camera/libcameraservice/device3/Camera3BufferManager.h
index 025062e..f0de1c1 100644
--- a/services/camera/libcameraservice/device3/Camera3BufferManager.h
+++ b/services/camera/libcameraservice/device3/Camera3BufferManager.h
@@ -112,6 +112,10 @@
*
* After this call, the client takes over the ownership of this buffer if it is not freed.
*
+ * Sometimes free buffers are discarded from consumer side and the dequeueBuffer call returns
+ * TIMED_OUT, in this case calling getBufferForStream again with noFreeBufferAtConsumer set to
+ * true will notify buffer manager to update its states and also tries to allocate a new buffer.
+ *
* Return values:
*
* OK: Getting buffer for this stream was successful.
@@ -122,7 +126,9 @@
* to this buffer manager before.
* NO_MEMORY: Unable to allocate a buffer for this stream at this time.
*/
- status_t getBufferForStream(int streamId, int streamSetId, sp<GraphicBuffer>* gb, int* fenceFd);
+ status_t getBufferForStream(
+ int streamId, int streamSetId, sp<GraphicBuffer>* gb, int* fenceFd,
+ bool noFreeBufferAtConsumer = false);
/**
* This method notifies the manager that a buffer has been released by the consumer.
diff --git a/services/camera/libcameraservice/device3/Camera3OutputStream.cpp b/services/camera/libcameraservice/device3/Camera3OutputStream.cpp
index 8cd575d..baba856 100644
--- a/services/camera/libcameraservice/device3/Camera3OutputStream.cpp
+++ b/services/camera/libcameraservice/device3/Camera3OutputStream.cpp
@@ -359,7 +359,18 @@
// Set dequeueBuffer/attachBuffer timeout if the consumer is not hw composer or hw texture.
// We need skip these cases as timeout will disable the non-blocking (async) mode.
if (!(isConsumedByHWComposer() || isConsumedByHWTexture())) {
- mConsumer->setDequeueTimeout(kDequeueBufferTimeout);
+ if (mUseBufferManager) {
+ // When buffer manager is handling the buffer, we should have available buffers in
+ // buffer queue before we calls into dequeueBuffer because buffer manager is tracking
+ // free buffers.
+ // There are however some consumer side feature (ImageReader::discardFreeBuffers) that
+ // can discard free buffers without notifying buffer manager. We want the timeout to
+ // happen immediately here so buffer manager can try to update its internal state and
+ // try to allocate a buffer instead of waiting.
+ mConsumer->setDequeueTimeout(0);
+ } else {
+ mConsumer->setDequeueTimeout(kDequeueBufferTimeout);
+ }
}
return OK;
@@ -526,6 +537,8 @@
if (res != OK) {
ALOGE("%s: Stream %d: Can't attach the output buffer to this surface: %s (%d)",
__FUNCTION__, mId, strerror(-res), res);
+
+ checkRetAndSetAbandonedLocked(res);
return res;
}
gotBufferFromManager = true;
@@ -562,35 +575,70 @@
mDequeueBufferLatency.add(dequeueStart, dequeueEnd);
mLock.lock();
- if (res != OK) {
+
+ if (mUseBufferManager && res == TIMED_OUT) {
+ checkRemovedBuffersLocked();
+
+ sp<GraphicBuffer> gb;
+ res = mBufferManager->getBufferForStream(
+ getId(), getStreamSetId(), &gb, fenceFd, /*noFreeBuffer*/true);
+
+ if (res == OK) {
+ // Attach this buffer to the bufferQueue: the buffer will be in dequeue state after
+ // a successful return.
+ *anb = gb.get();
+ res = mConsumer->attachBuffer(*anb);
+ gotBufferFromManager = true;
+ ALOGV("Stream %d: Attached new buffer", getId());
+
+ if (res != OK) {
+ ALOGE("%s: Stream %d: Can't attach the output buffer to this surface: %s (%d)",
+ __FUNCTION__, mId, strerror(-res), res);
+
+ checkRetAndSetAbandonedLocked(res);
+ return res;
+ }
+ } else {
+ ALOGE("%s: Stream %d: Can't get next output buffer from buffer manager:"
+ " %s (%d)", __FUNCTION__, mId, strerror(-res), res);
+ return res;
+ }
+ } else if (res != OK) {
ALOGE("%s: Stream %d: Can't dequeue next output buffer: %s (%d)",
__FUNCTION__, mId, strerror(-res), res);
- // Only transition to STATE_ABANDONED from STATE_CONFIGURED. (If it is STATE_PREPARING,
- // let prepareNextBuffer handle the error.)
- if ((res == NO_INIT || res == DEAD_OBJECT) && mState == STATE_CONFIGURED) {
- mState = STATE_ABANDONED;
- }
-
+ checkRetAndSetAbandonedLocked(res);
return res;
}
}
if (res == OK) {
- std::vector<sp<GraphicBuffer>> removedBuffers;
- res = mConsumer->getAndFlushRemovedBuffers(&removedBuffers);
- if (res == OK) {
- onBuffersRemovedLocked(removedBuffers);
-
- if (mUseBufferManager && removedBuffers.size() > 0) {
- mBufferManager->onBuffersRemoved(getId(), getStreamSetId(), removedBuffers.size());
- }
- }
+ checkRemovedBuffersLocked();
}
return res;
}
+void Camera3OutputStream::checkRemovedBuffersLocked(bool notifyBufferManager) {
+ std::vector<sp<GraphicBuffer>> removedBuffers;
+ status_t res = mConsumer->getAndFlushRemovedBuffers(&removedBuffers);
+ if (res == OK) {
+ onBuffersRemovedLocked(removedBuffers);
+
+ if (notifyBufferManager && mUseBufferManager && removedBuffers.size() > 0) {
+ mBufferManager->onBuffersRemoved(getId(), getStreamSetId(), removedBuffers.size());
+ }
+ }
+}
+
+void Camera3OutputStream::checkRetAndSetAbandonedLocked(status_t res) {
+ // Only transition to STATE_ABANDONED from STATE_CONFIGURED. (If it is
+ // STATE_PREPARING, let prepareNextBuffer handle the error.)
+ if ((res == NO_INIT || res == DEAD_OBJECT) && mState == STATE_CONFIGURED) {
+ mState = STATE_ABANDONED;
+ }
+}
+
status_t Camera3OutputStream::disconnectLocked() {
status_t res;
@@ -803,11 +851,8 @@
}
}
- std::vector<sp<GraphicBuffer>> removedBuffers;
- res = mConsumer->getAndFlushRemovedBuffers(&removedBuffers);
- if (res == OK) {
- onBuffersRemovedLocked(removedBuffers);
- }
+ // Here we assume detachBuffer is called by buffer manager so it doesn't need to be notified
+ checkRemovedBuffersLocked(/*notifyBufferManager*/false);
return res;
}
diff --git a/services/camera/libcameraservice/device3/Camera3OutputStream.h b/services/camera/libcameraservice/device3/Camera3OutputStream.h
index 2128da2..30fc2f7 100644
--- a/services/camera/libcameraservice/device3/Camera3OutputStream.h
+++ b/services/camera/libcameraservice/device3/Camera3OutputStream.h
@@ -309,6 +309,13 @@
*/
void onBuffersRemovedLocked(const std::vector<sp<GraphicBuffer>>&);
status_t detachBufferLocked(sp<GraphicBuffer>* buffer, int* fenceFd);
+ // Call this after each dequeueBuffer/attachBuffer/detachNextBuffer call to get update on
+ // removed buffers. Set notifyBufferManager to false when the call is initiated by buffer
+ // manager so buffer manager doesn't need to be notified.
+ void checkRemovedBuffersLocked(bool notifyBufferManager = true);
+
+ // Check return status of IGBP calls and set abandoned state accordingly
+ void checkRetAndSetAbandonedLocked(status_t res);
static const int32_t kDequeueLatencyBinSize = 5; // in ms
CameraLatencyHistogram mDequeueBufferLatency;
diff --git a/services/mediacodec/Android.bp b/services/mediacodec/Android.bp
new file mode 100644
index 0000000..25c36fa
--- /dev/null
+++ b/services/mediacodec/Android.bp
@@ -0,0 +1,62 @@
+cc_binary {
+ name: "mediaswcodec",
+ vendor_available: true,
+
+ srcs: [
+ "main_swcodecservice.cpp",
+ ],
+
+ shared_libs: [
+ "libavservices_minijail",
+ "libbase",
+ "libhidltransport",
+ "libhwbinder",
+ "liblog",
+ "libmedia_codecserviceregistrant",
+ ],
+
+ target: {
+ vendor: {
+ exclude_shared_libs: ["libavservices_minijail"],
+ shared_libs: ["libavservices_minijail_vendor"],
+ },
+ },
+
+ header_libs: [
+ "libmedia_headers",
+ ],
+
+ init_rc: ["mediaswcodec.rc"],
+
+ required: ["mediaswcodec.policy"],
+
+ cflags: [
+ "-Werror",
+ "-Wall",
+ "-Wno-error=deprecated-declarations",
+ ],
+
+ sanitize: {
+ scudo: true,
+ },
+}
+
+prebuilt_etc {
+ name: "mediaswcodec.policy",
+ sub_dir: "seccomp_policy",
+ arch: {
+ arm: {
+ src: "seccomp_policy/mediaswcodec-arm.policy",
+ },
+ arm64: {
+ src: "seccomp_policy/mediaswcodec-arm64.policy",
+ },
+ x86: {
+ src: "seccomp_policy/mediacodec-x86.policy",
+ },
+ x86_64: {
+ src: "seccomp_policy/mediacodec-x86.policy",
+ },
+ },
+ required: ["crash_dump.policy"],
+}
diff --git a/services/mediacodec/Android.mk b/services/mediacodec/Android.mk
index f78c671..9cc19a3 100644
--- a/services/mediacodec/Android.mk
+++ b/services/mediacodec/Android.mk
@@ -27,8 +27,8 @@
include $(CLEAR_VARS)
# seccomp is not required for coverage build.
ifneq ($(NATIVE_COVERAGE),true)
-LOCAL_REQUIRED_MODULES_arm := crash_dump.policy mediacodec.policy
-LOCAL_REQUIRED_MODULES_x86 := crash_dump.policy mediacodec.policy
+LOCAL_REQUIRED_MODULES_arm := mediacodec.policy
+LOCAL_REQUIRED_MODULES_x86 := mediacodec.policy
endif
LOCAL_SRC_FILES := main_codecservice.cpp
LOCAL_SHARED_LIBRARIES := \
@@ -65,74 +65,13 @@
####################################################################
-# service executable
-include $(CLEAR_VARS)
-# seccomp is not required for coverage build.
-ifneq ($(NATIVE_COVERAGE),true)
-LOCAL_REQUIRED_MODULES_arm := crash_dump.policy mediaswcodec.policy
-LOCAL_REQUIRED_MODULES_arm64 := crash_dump.policy mediaswcodec.policy
-LOCAL_REQUIRED_MODULES_x86 := crash_dump.policy mediaswcodec.policy
-LOCAL_REQUIRED_MODULES_x86_64 := crash_dump.policy mediaswcodec.policy
-endif
-
-LOCAL_SRC_FILES := \
- main_swcodecservice.cpp \
- MediaCodecUpdateService.cpp \
-
-sanitizer_runtime_libraries := $(call normalize-path-list,$(addsuffix .so,\
- $(ADDRESS_SANITIZER_RUNTIME_LIBRARY) \
- $(UBSAN_RUNTIME_LIBRARY) \
- $(TSAN_RUNTIME_LIBRARY) \
- $(2ND_ADDRESS_SANITIZER_RUNTIME_LIBRARY) \
- $(2ND_UBSAN_RUNTIME_LIBRARY) \
- $(2ND_TSAN_RUNTIME_LIBRARY)))
-
-# $(info Sanitizer: $(sanitizer_runtime_libraries))
-
-llndk_libraries := $(call normalize-path-list,$(addsuffix .so,\
- $(LLNDK_LIBRARIES)))
-
-# $(info LLNDK: $(llndk_libraries))
-
-LOCAL_CFLAGS := -DLINKED_LIBRARIES='"$(sanitizer_runtime_libraries):$(llndk_libraries)"'
-
-LOCAL_SHARED_LIBRARIES := \
- libavservices_minijail \
- libbase \
- libbinder \
- libcutils \
- libhidltransport \
- libhwbinder \
- liblog \
- libmedia \
- libutils \
- libziparchive \
-
-LOCAL_HEADER_LIBRARIES := \
- libnativeloader-dummy-headers \
-
-LOCAL_MODULE := mediaswcodec
-LOCAL_INIT_RC := mediaswcodec.rc
-LOCAL_SANITIZE := scudo
-ifeq ($(TARGET_ARCH), $(filter $(TARGET_ARCH), x86_64 arm64))
- LOCAL_MULTILIB := both
- LOCAL_MODULE_STEM_32 := $(LOCAL_MODULE)32
- LOCAL_MODULE_STEM_64 := $(LOCAL_MODULE)
-endif
-
-sanitizer_runtime_libraries :=
-llndk_libraries :=
-
-include $(BUILD_EXECUTABLE)
-
-####################################################################
-
# service seccomp policy
ifeq ($(TARGET_ARCH), $(filter $(TARGET_ARCH), x86 x86_64 arm arm64))
include $(CLEAR_VARS)
LOCAL_MODULE := mediacodec.policy
LOCAL_MODULE_CLASS := ETC
LOCAL_MODULE_PATH := $(TARGET_OUT)/etc/seccomp_policy
+LOCAL_REQUIRED_MODULES := crash_dump.policy
# mediacodec runs in 32-bit combatibility mode. For 64 bit architectures,
# use the 32 bit policy
ifdef TARGET_2ND_ARCH
@@ -149,14 +88,5 @@
####################################################################
-# sw service seccomp policy
-ifeq ($(TARGET_ARCH), $(filter $(TARGET_ARCH), x86 x86_64 arm arm64))
-include $(CLEAR_VARS)
-LOCAL_MODULE := mediaswcodec.policy
-LOCAL_MODULE_CLASS := ETC
-LOCAL_MODULE_PATH := $(TARGET_OUT)/etc/seccomp_policy
-LOCAL_SRC_FILES := seccomp_policy/mediaswcodec-$(TARGET_ARCH).policy
-include $(BUILD_PREBUILT)
-endif
include $(call all-makefiles-under, $(LOCAL_PATH))
diff --git a/services/mediacodec/MediaCodecUpdateService.cpp b/services/mediacodec/MediaCodecUpdateService.cpp
deleted file mode 100644
index 50ccbce..0000000
--- a/services/mediacodec/MediaCodecUpdateService.cpp
+++ /dev/null
@@ -1,79 +0,0 @@
-/*
- * Copyright 2018 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_TAG "MediaCodecUpdateService"
-//#define LOG_NDEBUG 0
-
-#include <android/dlext.h>
-#include <dlfcn.h>
-#include <media/CodecServiceRegistrant.h>
-#include <nativeloader/dlext_namespaces.h>
-#include <utils/Log.h>
-#include <utils/String8.h>
-
-#include "MediaCodecUpdateService.h"
-
-namespace android {
-
-void loadFromApex(const char *libDirPath) {
- ALOGV("loadFromApex: path=%s", libDirPath);
-
- String8 libPath = String8(libDirPath) + "/libmedia_codecserviceregistrant.so";
-
- android_namespace_t *codecNs = android_create_namespace("codecs",
- nullptr, // ld_library_path
- libDirPath,
- ANDROID_NAMESPACE_TYPE_ISOLATED,
- nullptr, // permitted_when_isolated_path
- nullptr); // parent
-
- if (codecNs == nullptr) {
- ALOGE("Failed to create codec namespace");
- return;
- }
-
- String8 linked_libraries(LINKED_LIBRARIES);
- if (!android_link_namespaces(codecNs, nullptr, linked_libraries.c_str())) {
- ALOGE("Failed to link namespace");
- return;
- }
-
- const android_dlextinfo dlextinfo = {
- .flags = ANDROID_DLEXT_USE_NAMESPACE,
- .library_namespace = codecNs,
- };
-
- void *registrantLib = android_dlopen_ext(
- libPath.string(),
- RTLD_NOW | RTLD_LOCAL, &dlextinfo);
-
- if (registrantLib == nullptr) {
- ALOGE("Failed to load lib from archive: %s", dlerror());
- }
-
- RegisterCodecServicesFunc registerCodecServices =
- reinterpret_cast<RegisterCodecServicesFunc>(
- dlsym(registrantLib, "RegisterCodecServices"));
-
- if (registerCodecServices == nullptr) {
- ALOGE("Cannot register codec services -- corrupted library.");
- return;
- }
-
- registerCodecServices();
-}
-
-} // namespace android
diff --git a/services/mediacodec/MediaCodecUpdateService.h b/services/mediacodec/MediaCodecUpdateService.h
deleted file mode 100644
index 09d6dbe..0000000
--- a/services/mediacodec/MediaCodecUpdateService.h
+++ /dev/null
@@ -1,26 +0,0 @@
-/*
- * Copyright 2018 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_MEDIA_CODEC_UPDATE_SERVICE_H
-#define ANDROID_MEDIA_CODEC_UPDATE_SERVICE_H
-
-namespace android {
-
-void loadFromApex(const char *libDirPath);
-
-} // namespace android
-
-#endif // ANDROID_MEDIA_CODEC_UPDATE_SERVICE_H
diff --git a/services/mediacodec/main_swcodecservice.cpp b/services/mediacodec/main_swcodecservice.cpp
index 05b5695..c44be28 100644
--- a/services/mediacodec/main_swcodecservice.cpp
+++ b/services/mediacodec/main_swcodecservice.cpp
@@ -19,24 +19,26 @@
// from LOCAL_C_INCLUDES
#include "minijail.h"
-
#include <hidl/HidlTransportSupport.h>
-#include "MediaCodecUpdateService.h"
-
using namespace android;
+// kSystemSeccompPolicyPath points to the policy for the swcodecs themselves and
+// is part of the updates. kVendorSeccompPolicyPath points to any additional
+// policies that the vendor may need for the device.
static const char kSystemSeccompPolicyPath[] =
- "/system/etc/seccomp_policy/mediaswcodec.policy";
+ "/apex/com.android.media.swcodec/etc/seccomp_policy/mediaswcodec.policy";
static const char kVendorSeccompPolicyPath[] =
"/vendor/etc/seccomp_policy/mediaswcodec.policy";
// Disable Scudo's mismatch allocation check, as it is being triggered
// by some third party code.
extern "C" const char *__scudo_default_options() {
- return "DeallocationTypeMismatch=false";
+ return "DeallocationTypeMismatch=false";
}
+extern "C" void RegisterCodecServices();
+
int main(int argc __unused, char** /*argv*/)
{
LOG(INFO) << "media swcodec service starting";
@@ -45,11 +47,7 @@
::android::hardware::configureRpcThreadpool(64, false);
-#ifdef __LP64__
- loadFromApex("/apex/com.android.media.swcodec/lib64");
-#else
- loadFromApex("/apex/com.android.media.swcodec/lib");
-#endif
+ RegisterCodecServices();
::android::hardware::joinRpcThreadpool();
}