Merge "Move hybrid interface from libbinder to libhidl/transport."
diff --git a/cmds/screenrecord/Android.mk b/cmds/screenrecord/Android.mk
index 6747e60..a3b1a34 100644
--- a/cmds/screenrecord/Android.mk
+++ b/cmds/screenrecord/Android.mk
@@ -34,6 +34,7 @@
$(TOP)/frameworks/native/include/media/openmax \
external/jpeg
+LOCAL_CFLAGS := -Werror -Wall
LOCAL_CFLAGS += -Wno-multichar
#LOCAL_CFLAGS += -UNDEBUG
diff --git a/cmds/screenrecord/Overlay.cpp b/cmds/screenrecord/Overlay.cpp
index aa800d8..17d7046 100644
--- a/cmds/screenrecord/Overlay.cpp
+++ b/cmds/screenrecord/Overlay.cpp
@@ -202,7 +202,6 @@
mGlConsumer->getTransformMatrix(texMatrix);
nsecs_t monotonicNsec = mGlConsumer->getTimestamp();
nsecs_t frameNumber = mGlConsumer->getFrameNumber();
- int64_t droppedFrames = 0;
if (mLastFrameNumber > 0) {
mTotalDroppedFrames += size_t(frameNumber - mLastFrameNumber) - 1;
diff --git a/cmds/screenrecord/screenrecord.cpp b/cmds/screenrecord/screenrecord.cpp
index 6097f01..de0167a 100644
--- a/cmds/screenrecord/screenrecord.cpp
+++ b/cmds/screenrecord/screenrecord.cpp
@@ -215,7 +215,6 @@
*/
static status_t setDisplayProjection(const sp<IBinder>& dpy,
const DisplayInfo& mainDpyInfo) {
- status_t err;
// Set the region of the layer stack we're interested in, which in our
// case is "all of it". If the app is rotated (so that the width of the
diff --git a/drm/libmediadrm/ICrypto.cpp b/drm/libmediadrm/ICrypto.cpp
index 10e6bc3..92c9548 100644
--- a/drm/libmediadrm/ICrypto.cpp
+++ b/drm/libmediadrm/ICrypto.cpp
@@ -149,7 +149,10 @@
ssize_t result = reply.readInt32();
if (isCryptoError(result)) {
- errorDetailMsg->setTo(reply.readCString());
+ AString msg = reply.readCString();
+ if (errorDetailMsg) {
+ *errorDetailMsg = msg;
+ }
}
return result;
@@ -235,17 +238,21 @@
size_t opaqueSize = data.readInt32();
void *opaqueData = NULL;
- if (opaqueSize > 0) {
- opaqueData = malloc(opaqueSize);
- data.read(opaqueData, opaqueSize);
+ const size_t kMaxOpaqueSize = 100 * 1024;
+ if (opaqueSize > kMaxOpaqueSize) {
+ return BAD_VALUE;
}
+ opaqueData = malloc(opaqueSize);
+ if (NULL == opaqueData) {
+ return NO_MEMORY;
+ }
+
+ data.read(opaqueData, opaqueSize);
reply->writeInt32(createPlugin(uuid, opaqueData, opaqueSize));
- if (opaqueData != NULL) {
- free(opaqueData);
- opaqueData = NULL;
- }
+ free(opaqueData);
+ opaqueData = NULL;
return OK;
}
diff --git a/drm/mediadrm/plugins/clearkey/DrmPlugin.cpp b/drm/mediadrm/plugins/clearkey/DrmPlugin.cpp
index 8356bcc..8cc5ee9 100644
--- a/drm/mediadrm/plugins/clearkey/DrmPlugin.cpp
+++ b/drm/mediadrm/plugins/clearkey/DrmPlugin.cpp
@@ -39,8 +39,9 @@
sp<Session> session = mSessionLibrary->findSession(sessionId);
if (session.get()) {
mSessionLibrary->destroySession(session);
+ return android::OK;
}
- return android::OK;
+ return android::ERROR_DRM_SESSION_NOT_OPENED;
}
status_t DrmPlugin::getKeyRequest(
diff --git a/drm/mediadrm/plugins/clearkey/SessionLibrary.cpp b/drm/mediadrm/plugins/clearkey/SessionLibrary.cpp
index 46d7f77..0419f97 100644
--- a/drm/mediadrm/plugins/clearkey/SessionLibrary.cpp
+++ b/drm/mediadrm/plugins/clearkey/SessionLibrary.cpp
@@ -43,7 +43,7 @@
return sSingleton;
}
-const sp<Session>& SessionLibrary::createSession() {
+sp<Session> SessionLibrary::createSession() {
Mutex::Autolock lock(mSessionsLock);
String8 sessionIdString = String8::format("%u", mNextSessionId);
@@ -57,9 +57,12 @@
return mSessions.valueFor(sessionId);
}
-const sp<Session>& SessionLibrary::findSession(
+sp<Session> SessionLibrary::findSession(
const Vector<uint8_t>& sessionId) {
Mutex::Autolock lock(mSessionsLock);
+ if (mSessions.indexOfKey(sessionId) < 0) {
+ return sp<Session>(NULL);
+ }
return mSessions.valueFor(sessionId);
}
diff --git a/drm/mediadrm/plugins/clearkey/SessionLibrary.h b/drm/mediadrm/plugins/clearkey/SessionLibrary.h
index 199ad64..6236fff 100644
--- a/drm/mediadrm/plugins/clearkey/SessionLibrary.h
+++ b/drm/mediadrm/plugins/clearkey/SessionLibrary.h
@@ -31,9 +31,9 @@
public:
static SessionLibrary* get();
- const android::sp<Session>& createSession();
+ android::sp<Session> createSession();
- const android::sp<Session>& findSession(
+ android::sp<Session> findSession(
const android::Vector<uint8_t>& sessionId);
void destroySession(const android::sp<Session>& session);
@@ -48,7 +48,7 @@
android::Mutex mSessionsLock;
uint32_t mNextSessionId;
- android::DefaultKeyedVector<android::Vector<uint8_t>, android::sp<Session> >
+ android::KeyedVector<android::Vector<uint8_t>, android::sp<Session> >
mSessions;
};
diff --git a/include/ndk/NdkImage.h b/include/ndk/NdkImage.h
index 15eae40..40c1699 100644
--- a/include/ndk/NdkImage.h
+++ b/include/ndk/NdkImage.h
@@ -646,7 +646,9 @@
* <li>{@link AMEDIA_ERROR_UNSUPPORTED} if pixel stride is undefined for the format of input
* image.</li>
* <li>{@link AMEDIA_ERROR_INVALID_OBJECT} if the {@link AImageReader} generated this
- * image has been deleted.</li></ul>
+ * image has been deleted.</li>
+ * <li>{@link AMEDIA_IMGREADER_CANNOT_LOCK_IMAGE} if the {@link AImage} cannot be locked
+ * for CPU access.</li></ul>
*/
media_status_t AImage_getPlanePixelStride(
const AImage* image, int planeIdx, /*out*/int32_t* pixelStride);
@@ -671,7 +673,9 @@
* <li>{@link AMEDIA_ERROR_UNSUPPORTED} if row stride is undefined for the format of input
* image.</li>
* <li>{@link AMEDIA_ERROR_INVALID_OBJECT} if the {@link AImageReader} generated this
- * image has been deleted.</li></ul>
+ * image has been deleted.</li>
+ * <li>{@link AMEDIA_IMGREADER_CANNOT_LOCK_IMAGE} if the {@link AImage} cannot be locked
+ * for CPU access.</li></ul>
*/
media_status_t AImage_getPlaneRowStride(
const AImage* image, int planeIdx, /*out*/int32_t* rowStride);
@@ -693,7 +697,9 @@
* <li>{@link AMEDIA_ERROR_INVALID_PARAMETER} if image, data or dataLength is NULL, or
* planeIdx is out of the range of [0, numOfPlanes - 1].</li>
* <li>{@link AMEDIA_ERROR_INVALID_OBJECT} if the {@link AImageReader} generated this
- * image has been deleted.</li></ul>
+ * image has been deleted.</li>
+ * <li>{@link AMEDIA_IMGREADER_CANNOT_LOCK_IMAGE} if the {@link AImage} cannot be locked
+ * for CPU access.</li></ul>
*/
media_status_t AImage_getPlaneData(
const AImage* image, int planeIdx,
diff --git a/include/ndk/NdkMediaError.h b/include/ndk/NdkMediaError.h
index fb00b1d..9709a6f 100644
--- a/include/ndk/NdkMediaError.h
+++ b/include/ndk/NdkMediaError.h
@@ -60,6 +60,9 @@
AMEDIA_IMGREADER_ERROR_BASE = -30000,
AMEDIA_IMGREADER_NO_BUFFER_AVAILABLE = AMEDIA_IMGREADER_ERROR_BASE - 1,
AMEDIA_IMGREADER_MAX_IMAGES_ACQUIRED = AMEDIA_IMGREADER_ERROR_BASE - 2,
+ AMEDIA_IMGREADER_CANNOT_LOCK_IMAGE = AMEDIA_IMGREADER_ERROR_BASE - 3,
+ AMEDIA_IMGREADER_CANNOT_UNLOCK_IMAGE = AMEDIA_IMGREADER_ERROR_BASE - 4,
+ AMEDIA_IMGREADER_IMAGE_NOT_LOCKED = AMEDIA_IMGREADER_ERROR_BASE - 5,
} media_status_t;
diff --git a/media/libaudioclient/AudioRecord.cpp b/media/libaudioclient/AudioRecord.cpp
index 4c1fbd7..6c7cdde 100644
--- a/media/libaudioclient/AudioRecord.cpp
+++ b/media/libaudioclient/AudioRecord.cpp
@@ -66,7 +66,8 @@
// ---------------------------------------------------------------------------
AudioRecord::AudioRecord(const String16 &opPackageName)
- : mActive(false), mStatus(NO_INIT), mOpPackageName(opPackageName), mSessionId(AUDIO_SESSION_ALLOCATE),
+ : mActive(false), mStatus(NO_INIT), mOpPackageName(opPackageName),
+ mSessionId(AUDIO_SESSION_ALLOCATE),
mPreviousPriority(ANDROID_PRIORITY_NORMAL), mPreviousSchedulingGroup(SP_DEFAULT),
mSelectedDeviceId(AUDIO_PORT_HANDLE_NONE), mPortId(AUDIO_PORT_HANDLE_NONE)
{
diff --git a/media/libaudioclient/AudioSystem.cpp b/media/libaudioclient/AudioSystem.cpp
index 1908f0e..5cd2789 100644
--- a/media/libaudioclient/AudioSystem.cpp
+++ b/media/libaudioclient/AudioSystem.cpp
@@ -554,7 +554,8 @@
"channel mask %#x frameCount %zu frameCountHAL %zu deviceId %d",
event == AUDIO_OUTPUT_CONFIG_CHANGED ? "output" : "input",
ioDesc->mIoHandle, ioDesc->mSamplingRate, ioDesc->mFormat,
- ioDesc->mChannelMask, ioDesc->mFrameCount, ioDesc->mFrameCountHAL, ioDesc->getDeviceId());
+ ioDesc->mChannelMask, ioDesc->mFrameCount, ioDesc->mFrameCountHAL,
+ ioDesc->getDeviceId());
} break;
}
diff --git a/media/libaudioclient/AudioTrack.cpp b/media/libaudioclient/AudioTrack.cpp
index f878be9..d590cb7 100644
--- a/media/libaudioclient/AudioTrack.cpp
+++ b/media/libaudioclient/AudioTrack.cpp
@@ -917,7 +917,8 @@
}
// Check resampler ratios are within bounds
- if ((uint64_t)effectiveRate > (uint64_t)mSampleRate * (uint64_t)AUDIO_RESAMPLER_DOWN_RATIO_MAX) {
+ if ((uint64_t)effectiveRate > (uint64_t)mSampleRate *
+ (uint64_t)AUDIO_RESAMPLER_DOWN_RATIO_MAX) {
ALOGV("setPlaybackRate(%f, %f) failed. Resample rate exceeds max accepted value",
playbackRate.mSpeed, playbackRate.mPitch);
return BAD_VALUE;
@@ -1274,9 +1275,10 @@
mFlags, mSelectedDeviceId, &mPortId);
if (status != NO_ERROR || output == AUDIO_IO_HANDLE_NONE) {
- ALOGE("Could not get audio output for session %d, stream type %d, usage %d, sample rate %u, format %#x,"
- " channel mask %#x, flags %#x",
- mSessionId, streamType, mAttributes.usage, mSampleRate, mFormat, mChannelMask, mFlags);
+ ALOGE("Could not get audio output for session %d, stream type %d, usage %d, sample rate %u,"
+ " format %#x, channel mask %#x, flags %#x",
+ mSessionId, streamType, mAttributes.usage, mSampleRate, mFormat, mChannelMask,
+ mFlags);
return BAD_VALUE;
}
{
diff --git a/media/libaudioclient/ToneGenerator.cpp b/media/libaudioclient/ToneGenerator.cpp
index 7a72237..9bc2594 100644
--- a/media/libaudioclient/ToneGenerator.cpp
+++ b/media/libaudioclient/ToneGenerator.cpp
@@ -1420,7 +1420,7 @@
// Instantiate a wave generator if ot already done for this frequency
if (mWaveGens.indexOfKey(frequency) == NAME_NOT_FOUND) {
ToneGenerator::WaveGenerator *lpWaveGen =
- new ToneGenerator::WaveGenerator((unsigned short)mSamplingRate,
+ new ToneGenerator::WaveGenerator(mSamplingRate,
frequency,
TONEGEN_GAIN/lNumWaves);
mWaveGens.add(frequency, lpWaveGen);
@@ -1544,7 +1544,7 @@
// none
//
////////////////////////////////////////////////////////////////////////////////
-ToneGenerator::WaveGenerator::WaveGenerator(unsigned short samplingRate,
+ToneGenerator::WaveGenerator::WaveGenerator(uint32_t samplingRate,
unsigned short frequency, float volume) {
double d0;
double F_div_Fs; // frequency / samplingRate
diff --git a/media/libaudioclient/include/ToneGenerator.h b/media/libaudioclient/include/ToneGenerator.h
index 9fd5f61..fc3d3ee 100644
--- a/media/libaudioclient/include/ToneGenerator.h
+++ b/media/libaudioclient/include/ToneGenerator.h
@@ -299,7 +299,7 @@
WAVEGEN_STOP // Stop wave on zero crossing
};
- WaveGenerator(unsigned short samplingRate, unsigned short frequency,
+ WaveGenerator(uint32_t samplingRate, unsigned short frequency,
float volume);
~WaveGenerator();
diff --git a/media/libaudiohal/ConversionHelperHidl.h b/media/libaudiohal/ConversionHelperHidl.h
index a991baf..c356f37 100644
--- a/media/libaudiohal/ConversionHelperHidl.h
+++ b/media/libaudiohal/ConversionHelperHidl.h
@@ -23,7 +23,6 @@
using ::android::hardware::audio::V2_0::ParameterValue;
using ::android::hardware::Return;
-using ::android::hardware::Status;
using ::android::hardware::hidl_string;
using ::android::hardware::hidl_vec;
diff --git a/media/libaudiohal/DevicesFactoryHalHidl.cpp b/media/libaudiohal/DevicesFactoryHalHidl.cpp
index 9cbe018..758a5805 100644
--- a/media/libaudiohal/DevicesFactoryHalHidl.cpp
+++ b/media/libaudiohal/DevicesFactoryHalHidl.cpp
@@ -30,7 +30,6 @@
using ::android::hardware::audio::V2_0::IDevice;
using ::android::hardware::audio::V2_0::Result;
using ::android::hardware::Return;
-using ::android::hardware::Status;
namespace android {
@@ -42,9 +41,11 @@
DevicesFactoryHalHidl::DevicesFactoryHalHidl() {
mDevicesFactory = IDevicesFactory::getService();
if (mDevicesFactory != 0) {
- // It is assumet that DevicesFactory is owned by AudioFlinger
+ // It is assumed that DevicesFactory is owned by AudioFlinger
// and thus have the same lifespan.
mDevicesFactory->linkToDeath(HalDeathHandler::getInstance(), 0 /*cookie*/);
+ } else {
+ LOG_ALWAYS_FATAL("Failed to obtain IDevicesFactory service");
}
}
diff --git a/media/libaudiohal/EffectBufferHalHidl.cpp b/media/libaudiohal/EffectBufferHalHidl.cpp
index ce581f2..d6a41a2 100644
--- a/media/libaudiohal/EffectBufferHalHidl.cpp
+++ b/media/libaudiohal/EffectBufferHalHidl.cpp
@@ -27,7 +27,6 @@
#include "EffectBufferHalHidl.h"
using ::android::hardware::Return;
-using ::android::hardware::Status;
using ::android::hidl::allocator::V1_0::IAllocator;
namespace android {
diff --git a/media/libaudiohal/EffectHalHidl.cpp b/media/libaudiohal/EffectHalHidl.cpp
index 539558d..0babfda 100644
--- a/media/libaudiohal/EffectHalHidl.cpp
+++ b/media/libaudiohal/EffectHalHidl.cpp
@@ -36,7 +36,6 @@
using ::android::hardware::hidl_vec;
using ::android::hardware::MQDescriptorSync;
using ::android::hardware::Return;
-using ::android::hardware::Status;
namespace android {
diff --git a/media/libaudiohal/EffectsFactoryHalHidl.cpp b/media/libaudiohal/EffectsFactoryHalHidl.cpp
index 950f9dc..f7dbb9c 100644
--- a/media/libaudiohal/EffectsFactoryHalHidl.cpp
+++ b/media/libaudiohal/EffectsFactoryHalHidl.cpp
@@ -29,7 +29,6 @@
using ::android::hardware::audio::effect::V2_0::IEffect;
using ::android::hardware::audio::effect::V2_0::Result;
using ::android::hardware::Return;
-using ::android::hardware::Status;
namespace android {
@@ -45,6 +44,7 @@
EffectsFactoryHalHidl::EffectsFactoryHalHidl() : ConversionHelperHidl("EffectsFactory") {
mEffectsFactory = IEffectsFactory::getService();
+ LOG_ALWAYS_FATAL_IF(mEffectsFactory == 0, "Failed to obtain IEffectsFactory service");
}
EffectsFactoryHalHidl::~EffectsFactoryHalHidl() {
diff --git a/media/libmedia/IHDCP.cpp b/media/libmedia/IHDCP.cpp
index 15ed579..a46017f 100644
--- a/media/libmedia/IHDCP.cpp
+++ b/media/libmedia/IHDCP.cpp
@@ -240,6 +240,8 @@
case HDCP_ENCRYPT:
{
+ CHECK_INTERFACE(IHDCP, data, reply);
+
size_t size = data.readInt32();
void *inData = NULL;
// watch out for overflow
@@ -313,6 +315,8 @@
case HDCP_DECRYPT:
{
+ CHECK_INTERFACE(IHDCP, data, reply);
+
size_t size = data.readInt32();
size_t bufSize = 2 * size;
diff --git a/media/libmediaplayerservice/nuplayer/GenericSource.cpp b/media/libmediaplayerservice/nuplayer/GenericSource.cpp
index c949080..8378d24 100644
--- a/media/libmediaplayerservice/nuplayer/GenericSource.cpp
+++ b/media/libmediaplayerservice/nuplayer/GenericSource.cpp
@@ -1916,7 +1916,7 @@
status_t NuPlayer::GenericSource::checkDrmInfo()
{
if (mFileMeta == NULL) {
- ALOGE("checkDrmInfo: No metadata");
+ ALOGI("checkDrmInfo: No metadata");
return OK; // letting the caller responds accordingly
}
diff --git a/media/libstagefright/AMRExtractor.cpp b/media/libstagefright/AMRExtractor.cpp
index 0e98db8..2892520 100644
--- a/media/libstagefright/AMRExtractor.cpp
+++ b/media/libstagefright/AMRExtractor.cpp
@@ -259,7 +259,7 @@
int64_t seekTimeUs;
ReadOptions::SeekMode mode;
- if (options && options->getSeekTo(&seekTimeUs, &mode)) {
+ if (mOffsetTableLength > 0 && options && options->getSeekTo(&seekTimeUs, &mode)) {
size_t size;
int64_t seekFrame = seekTimeUs / 20000ll; // 20ms per frame.
mCurrentTimeUs = seekFrame * 20000ll;
diff --git a/media/libstagefright/HevcUtils.cpp b/media/libstagefright/HevcUtils.cpp
index 718710a..7d463a9 100644
--- a/media/libstagefright/HevcUtils.cpp
+++ b/media/libstagefright/HevcUtils.cpp
@@ -45,16 +45,32 @@
}
status_t HevcParameterSets::addNalUnit(const uint8_t* data, size_t size) {
+ if (size < 1) {
+ ALOGE("empty NAL b/35467107");
+ return ERROR_MALFORMED;
+ }
uint8_t nalUnitType = (data[0] >> 1) & 0x3f;
status_t err = OK;
switch (nalUnitType) {
case 32: // VPS
+ if (size < 2) {
+ ALOGE("invalid NAL/VPS size b/35467107");
+ return ERROR_MALFORMED;
+ }
err = parseVps(data + 2, size - 2);
break;
case 33: // SPS
+ if (size < 2) {
+ ALOGE("invalid NAL/SPS size b/35467107");
+ return ERROR_MALFORMED;
+ }
err = parseSps(data + 2, size - 2);
break;
case 34: // PPS
+ if (size < 2) {
+ ALOGE("invalid NAL/PPS size b/35467107");
+ return ERROR_MALFORMED;
+ }
err = parsePps(data + 2, size - 2);
break;
case 39: // Prefix SEI
diff --git a/media/libstagefright/NuMediaExtractor.cpp b/media/libstagefright/NuMediaExtractor.cpp
index ea3ed28..e3ca516 100644
--- a/media/libstagefright/NuMediaExtractor.cpp
+++ b/media/libstagefright/NuMediaExtractor.cpp
@@ -615,7 +615,7 @@
}
off64_t size;
- if (mDurationUs >= 0 && mDataSource->getSize(&size) == OK) {
+ if (mDurationUs > 0 && mDataSource->getSize(&size) == OK) {
*bitrate = size * 8000000ll / mDurationUs; // in bits/sec
return true;
}
diff --git a/media/libstagefright/codecs/aacenc/SoftAACEncoder2.cpp b/media/libstagefright/codecs/aacenc/SoftAACEncoder2.cpp
index 5f516cb..44415e2 100644
--- a/media/libstagefright/codecs/aacenc/SoftAACEncoder2.cpp
+++ b/media/libstagefright/codecs/aacenc/SoftAACEncoder2.cpp
@@ -16,6 +16,7 @@
//#define LOG_NDEBUG 0
#define LOG_TAG "SoftAACEncoder2"
+#include <log/log.h>
#include <utils/Log.h>
#include "SoftAACEncoder2.h"
@@ -61,6 +62,7 @@
mSentCodecSpecificData(false),
mInputSize(0),
mInputFrame(NULL),
+ mAllocatedFrameSize(0),
mInputTimeUs(-1ll),
mSawInputEOS(false),
mSignalledError(false) {
@@ -510,6 +512,15 @@
BufferInfo *outInfo = *outQueue.begin();
OMX_BUFFERHEADERTYPE *outHeader = outInfo->mHeader;
+
+ if (outHeader->nOffset + encInfo.confSize > outHeader->nAllocLen) {
+ ALOGE("b/34617444");
+ android_errorWriteLog(0x534e4554,"34617444");
+ notify(OMX_EventError, OMX_ErrorUndefined, 0, NULL);
+ mSignalledError = true;
+ return;
+ }
+
outHeader->nFilledLen = encInfo.confSize;
outHeader->nFlags = OMX_BUFFERFLAG_CODECCONFIG;
@@ -556,6 +567,15 @@
if (mInputFrame == NULL) {
mInputFrame = new int16_t[numBytesPerInputFrame / sizeof(int16_t)];
+ mAllocatedFrameSize = numBytesPerInputFrame;
+ } else if (mAllocatedFrameSize != numBytesPerInputFrame) {
+ ALOGE("b/34621073: changed size from %d to %d",
+ (int)mAllocatedFrameSize, (int)numBytesPerInputFrame);
+ android_errorWriteLog(0x534e4554,"34621073");
+ delete mInputFrame;
+ mInputFrame = new int16_t[numBytesPerInputFrame / sizeof(int16_t)];
+ mAllocatedFrameSize = numBytesPerInputFrame;
+
}
if (mInputSize == 0) {
@@ -706,6 +726,7 @@
delete[] mInputFrame;
mInputFrame = NULL;
mInputSize = 0;
+ mAllocatedFrameSize = 0;
mSentCodecSpecificData = false;
mInputTimeUs = -1ll;
diff --git a/media/libstagefright/codecs/aacenc/SoftAACEncoder2.h b/media/libstagefright/codecs/aacenc/SoftAACEncoder2.h
index f1b81e1..123fd25 100644
--- a/media/libstagefright/codecs/aacenc/SoftAACEncoder2.h
+++ b/media/libstagefright/codecs/aacenc/SoftAACEncoder2.h
@@ -62,6 +62,7 @@
bool mSentCodecSpecificData;
size_t mInputSize;
int16_t *mInputFrame;
+ size_t mAllocatedFrameSize;
int64_t mInputTimeUs;
bool mSawInputEOS;
diff --git a/media/libstagefright/codecs/m4v_h263/dec/src/mb_motion_comp.cpp b/media/libstagefright/codecs/m4v_h263/dec/src/mb_motion_comp.cpp
index fbc7be1..877723d 100644
--- a/media/libstagefright/codecs/m4v_h263/dec/src/mb_motion_comp.cpp
+++ b/media/libstagefright/codecs/m4v_h263/dec/src/mb_motion_comp.cpp
@@ -15,6 +15,10 @@
* and limitations under the License.
* -------------------------------------------------------------------
*/
+
+#define LOG_TAG "m4v_h263"
+#include <log/log.h>
+
/*
------------------------------------------------------------------------------
INPUT AND OUTPUT DEFINITIONS
@@ -236,6 +240,11 @@
/* Pointer to previous luminance frame */
c_prev = prev->yChan;
+ if (!c_prev) {
+ ALOGE("b/35269635");
+ android_errorWriteLog(0x534e4554, "35269635");
+ return;
+ }
pred_block = video->mblock->pred_block;
@@ -574,7 +583,14 @@
/* zero motion compensation for previous frame */
/*mby*width + mbx;*/
- c_prev = prev->yChan + offset;
+ c_prev = prev->yChan;
+ if (!c_prev) {
+ ALOGE("b/35269635");
+ android_errorWriteLog(0x534e4554, "35269635");
+ return;
+ }
+ c_prev += offset;
+
/*by*width_uv + bx;*/
cu_prev = prev->uChan + (offset >> 2) + (xpos >> 2);
/*by*width_uv + bx;*/
diff --git a/media/libstagefright/codecs/m4v_h263/dec/src/pvdec_api.cpp b/media/libstagefright/codecs/m4v_h263/dec/src/pvdec_api.cpp
index c1720c6..8d5d071 100644
--- a/media/libstagefright/codecs/m4v_h263/dec/src/pvdec_api.cpp
+++ b/media/libstagefright/codecs/m4v_h263/dec/src/pvdec_api.cpp
@@ -15,6 +15,8 @@
* and limitations under the License.
* -------------------------------------------------------------------
*/
+#define LOG_TAG "pvdec_api"
+#include <log/log.h>
#include "mp4dec_lib.h"
#include "vlc_decode.h"
#include "bitstream.h"
@@ -1335,6 +1337,11 @@
}
}
+ if (!video->prevVop->yChan) {
+ ALOGE("b/35269635");
+ android_errorWriteLog(0x534e4554, "35269635");
+ return PV_FALSE;
+ }
oscl_memcpy(currVop->yChan, video->prevVop->yChan, (decCtrl->size*3) / 2);
video->prevVop = prevVop;
diff --git a/media/libstagefright/id3/ID3.cpp b/media/libstagefright/id3/ID3.cpp
index 9105084..8d1ad66 100644
--- a/media/libstagefright/id3/ID3.cpp
+++ b/media/libstagefright/id3/ID3.cpp
@@ -379,7 +379,7 @@
flags &= ~1;
}
- if (flags & 2) {
+ if ((flags & 2) && (dataSize >= 2)) {
// This file has "unsynchronization", so we have to replace occurrences
// of 0xff 0x00 with just 0xff in order to get the real data.
@@ -395,11 +395,15 @@
mData[writeOffset++] = mData[readOffset++];
}
// move the remaining data following this frame
- memmove(&mData[writeOffset], &mData[readOffset], oldSize - readOffset);
+ if (readOffset <= oldSize) {
+ memmove(&mData[writeOffset], &mData[readOffset], oldSize - readOffset);
+ } else {
+ ALOGE("b/34618607 (%zu %zu %zu %zu)", readOffset, writeOffset, oldSize, mSize);
+ android_errorWriteLog(0x534e4554, "34618607");
+ }
- flags &= ~2;
}
-
+ flags &= ~2;
if (flags != prevFlags || iTunesHack) {
WriteSyncsafeInteger(&mData[offset + 4], dataSize);
mData[offset + 8] = flags >> 8;
diff --git a/media/ndk/Android.mk b/media/ndk/Android.mk
index 74729e4..67b0ab1 100644
--- a/media/ndk/Android.mk
+++ b/media/ndk/Android.mk
@@ -34,9 +34,12 @@
LOCAL_C_INCLUDES := \
bionic/libc/private \
+ external/piex \
frameworks/base/core/jni \
+ frameworks/base/media/jni \
frameworks/av/include/ndk \
- system/media/camera/include
+ system/media/camera/include \
+ $(call include-path-for, libhardware)/hardware \
LOCAL_CFLAGS += -fvisibility=hidden -D EXPORT='__attribute__ ((visibility ("default")))'
@@ -45,7 +48,9 @@
LOCAL_SHARED_LIBRARIES := \
libbinder \
libmedia \
+ libmedia_jni \
libmediadrm \
+ libskia \
libstagefright \
libstagefright_foundation \
liblog \
diff --git a/media/ndk/NdkImage.cpp b/media/ndk/NdkImage.cpp
index 40900ad..6c9a644 100644
--- a/media/ndk/NdkImage.cpp
+++ b/media/ndk/NdkImage.cpp
@@ -22,6 +22,8 @@
#include "NdkImagePriv.h"
#include "NdkImageReaderPriv.h"
+#include <android_media_Utils.h>
+#include <android_runtime/android_hardware_HardwareBuffer.h>
#include <utils/Log.h>
#include "hardware/camera3.h"
@@ -29,11 +31,11 @@
#define ALIGN(x, mask) ( ((x) + (mask) - 1) & ~((mask) - 1) )
-AImage::AImage(AImageReader* reader, int32_t format,
- CpuConsumer::LockedBuffer* buffer, int64_t timestamp,
+AImage::AImage(AImageReader* reader, int32_t format, uint64_t usage,
+ BufferItem* buffer, int64_t timestamp,
int32_t width, int32_t height, int32_t numPlanes) :
- mReader(reader), mFormat(format),
- mBuffer(buffer), mTimestamp(timestamp),
+ mReader(reader), mFormat(format), mUsage(usage),
+ mBuffer(buffer), mLockedBuffer(nullptr), mTimestamp(timestamp),
mWidth(width), mHeight(height), mNumPlanes(numPlanes) {
}
@@ -66,6 +68,7 @@
// Should have been set to nullptr in releaseImageLocked
// Set to nullptr here for extra safety only
mBuffer = nullptr;
+ mLockedBuffer = nullptr;
mIsClosed = true;
}
@@ -169,8 +172,80 @@
return AMEDIA_OK;
}
+media_status_t AImage::lockImage() {
+ if (mBuffer == nullptr || mBuffer->mGraphicBuffer == nullptr) {
+ LOG_ALWAYS_FATAL("%s: AImage %p has no buffer.", __FUNCTION__, this);
+ return AMEDIA_ERROR_INVALID_OBJECT;
+ }
+
+ if ((mUsage & AHARDWAREBUFFER_USAGE0_CPU_READ_OFTEN) == 0) {
+ ALOGE("%s: AImage %p does not have any software read usage bits set, usage=%" PRIu64 "",
+ __FUNCTION__, this, mUsage);
+ return AMEDIA_IMGREADER_CANNOT_LOCK_IMAGE;
+ }
+
+ if (mLockedBuffer != nullptr) {
+ // Return immediately if the image has already been locked.
+ return AMEDIA_OK;
+ }
+
+ auto lockedBuffer = std::make_unique<CpuConsumer::LockedBuffer>();
+
+ uint64_t producerUsage;
+ uint64_t consumerUsage;
+ android_hardware_HardwareBuffer_convertToGrallocUsageBits(
+ &producerUsage, &consumerUsage, mUsage, 0);
+
+ status_t ret =
+ lockImageFromBuffer(mBuffer, consumerUsage, mBuffer->mFence->dup(), lockedBuffer.get());
+ if (ret != OK) {
+ ALOGE("%s: AImage %p failed to lock, error=%d", __FUNCTION__, this, ret);
+ return AMEDIA_IMGREADER_CANNOT_LOCK_IMAGE;
+ }
+
+ ALOGV("%s: Successfully locked the image %p.", __FUNCTION__, this);
+ mLockedBuffer = std::move(lockedBuffer);
+
+ return AMEDIA_OK;
+}
+
+media_status_t AImage::unlockImageIfLocked(int* fenceFd) {
+ if (fenceFd == nullptr) {
+ LOG_ALWAYS_FATAL("%s: fenceFd cannot be null.", __FUNCTION__);
+ return AMEDIA_ERROR_INVALID_PARAMETER;
+ }
+
+ if (mBuffer == nullptr || mBuffer->mGraphicBuffer == nullptr) {
+ LOG_ALWAYS_FATAL("%s: AImage %p has no buffer.", __FUNCTION__, this);
+ return AMEDIA_ERROR_INVALID_OBJECT;
+ }
+
+ if (mLockedBuffer == nullptr) {
+ // This image hasn't been locked yet, no need to unlock.
+ *fenceFd = -1;
+ return AMEDIA_OK;
+ }
+
+ // No fence by default.
+ int releaseFenceFd = -1;
+ status_t res = mBuffer->mGraphicBuffer->unlockAsync(&releaseFenceFd);
+ if (res != OK) {
+ ALOGE("%s unlock buffer failed on iamge %p.", __FUNCTION__, this);
+ *fenceFd = -1;
+ return AMEDIA_IMGREADER_CANNOT_UNLOCK_IMAGE;
+ }
+
+ *fenceFd = releaseFenceFd;
+ return AMEDIA_OK;
+}
+
media_status_t
AImage::getPlanePixelStride(int planeIdx, /*out*/int32_t* pixelStride) const {
+ if (mLockedBuffer == nullptr) {
+ ALOGE("%s: buffer not locked.", __FUNCTION__);
+ return AMEDIA_IMGREADER_IMAGE_NOT_LOCKED;
+ }
+
if (planeIdx < 0 || planeIdx >= mNumPlanes) {
ALOGE("Error: planeIdx %d out of bound [0,%d]",
planeIdx, mNumPlanes - 1);
@@ -183,10 +258,10 @@
ALOGE("%s: image %p has been closed!", __FUNCTION__, this);
return AMEDIA_ERROR_INVALID_OBJECT;
}
- int32_t fmt = mBuffer->flexFormat;
+ int32_t fmt = mLockedBuffer->flexFormat;
switch (fmt) {
case HAL_PIXEL_FORMAT_YCbCr_420_888:
- *pixelStride = (planeIdx == 0) ? 1 : mBuffer->chromaStep;
+ *pixelStride = (planeIdx == 0) ? 1 : mLockedBuffer->chromaStep;
return AMEDIA_OK;
case HAL_PIXEL_FORMAT_YCrCb_420_SP:
*pixelStride = (planeIdx == 0) ? 1 : 2;
@@ -226,6 +301,11 @@
media_status_t
AImage::getPlaneRowStride(int planeIdx, /*out*/int32_t* rowStride) const {
+ if (mLockedBuffer == nullptr) {
+ ALOGE("%s: buffer not locked.", __FUNCTION__);
+ return AMEDIA_IMGREADER_IMAGE_NOT_LOCKED;
+ }
+
if (planeIdx < 0 || planeIdx >= mNumPlanes) {
ALOGE("Error: planeIdx %d out of bound [0,%d]",
planeIdx, mNumPlanes - 1);
@@ -238,54 +318,58 @@
ALOGE("%s: image %p has been closed!", __FUNCTION__, this);
return AMEDIA_ERROR_INVALID_OBJECT;
}
- int32_t fmt = mBuffer->flexFormat;
+ int32_t fmt = mLockedBuffer->flexFormat;
switch (fmt) {
case HAL_PIXEL_FORMAT_YCbCr_420_888:
- *rowStride = (planeIdx == 0) ? mBuffer->stride : mBuffer->chromaStride;
+ *rowStride = (planeIdx == 0) ? mLockedBuffer->stride
+ : mLockedBuffer->chromaStride;
return AMEDIA_OK;
case HAL_PIXEL_FORMAT_YCrCb_420_SP:
- *rowStride = mBuffer->width;
+ *rowStride = mLockedBuffer->width;
return AMEDIA_OK;
case HAL_PIXEL_FORMAT_YV12:
- if (mBuffer->stride % 16) {
- ALOGE("Stride %d is not 16 pixel aligned!", mBuffer->stride);
+ if (mLockedBuffer->stride % 16) {
+ ALOGE("Stride %d is not 16 pixel aligned!", mLockedBuffer->stride);
return AMEDIA_ERROR_UNKNOWN;
}
- *rowStride = (planeIdx == 0) ? mBuffer->stride : ALIGN(mBuffer->stride / 2, 16);
+ *rowStride = (planeIdx == 0) ? mLockedBuffer->stride
+ : ALIGN(mLockedBuffer->stride / 2, 16);
return AMEDIA_OK;
case HAL_PIXEL_FORMAT_RAW10:
case HAL_PIXEL_FORMAT_RAW12:
// RAW10 and RAW12 are used for 10-bit and 12-bit raw data, they are single plane
- *rowStride = mBuffer->stride;
+ *rowStride = mLockedBuffer->stride;
return AMEDIA_OK;
case HAL_PIXEL_FORMAT_Y8:
- if (mBuffer->stride % 16) {
- ALOGE("Stride %d is not 16 pixel aligned!", mBuffer->stride);
+ if (mLockedBuffer->stride % 16) {
+ ALOGE("Stride %d is not 16 pixel aligned!",
+ mLockedBuffer->stride);
return AMEDIA_ERROR_UNKNOWN;
}
- *rowStride = mBuffer->stride;
+ *rowStride = mLockedBuffer->stride;
return AMEDIA_OK;
case HAL_PIXEL_FORMAT_Y16:
case HAL_PIXEL_FORMAT_RAW16:
// In native side, strides are specified in pixels, not in bytes.
// Single plane 16bpp bayer data. even width/height,
// row stride multiple of 16 pixels (32 bytes)
- if (mBuffer->stride % 16) {
- ALOGE("Stride %d is not 16 pixel aligned!", mBuffer->stride);
+ if (mLockedBuffer->stride % 16) {
+ ALOGE("Stride %d is not 16 pixel aligned!",
+ mLockedBuffer->stride);
return AMEDIA_ERROR_UNKNOWN;
}
- *rowStride = mBuffer->stride * 2;
+ *rowStride = mLockedBuffer->stride * 2;
return AMEDIA_OK;
case HAL_PIXEL_FORMAT_RGB_565:
- *rowStride = mBuffer->stride * 2;
+ *rowStride = mLockedBuffer->stride * 2;
return AMEDIA_OK;
case HAL_PIXEL_FORMAT_RGBA_8888:
case HAL_PIXEL_FORMAT_RGBX_8888:
- *rowStride = mBuffer->stride * 4;
+ *rowStride = mLockedBuffer->stride * 4;
return AMEDIA_OK;
case HAL_PIXEL_FORMAT_RGB_888:
// Single plane, 24bpp.
- *rowStride = mBuffer->stride * 3;
+ *rowStride = mLockedBuffer->stride * 3;
return AMEDIA_OK;
case HAL_PIXEL_FORMAT_BLOB:
case HAL_PIXEL_FORMAT_RAW_OPAQUE:
@@ -300,13 +384,13 @@
uint32_t
AImage::getJpegSize() const {
- if (mBuffer == nullptr) {
+ if (mLockedBuffer == nullptr) {
LOG_ALWAYS_FATAL("Error: buffer is null");
}
uint32_t size = 0;
- uint32_t width = mBuffer->width;
- uint8_t* jpegBuffer = mBuffer->data;
+ uint32_t width = mLockedBuffer->width;
+ uint8_t* jpegBuffer = mLockedBuffer->data;
// First check for JPEG transport header at the end of the buffer
uint8_t* header = jpegBuffer + (width - sizeof(struct camera3_jpeg_blob));
@@ -334,6 +418,11 @@
media_status_t
AImage::getPlaneData(int planeIdx,/*out*/uint8_t** data, /*out*/int* dataLength) const {
+ if (mLockedBuffer == nullptr) {
+ ALOGE("%s: buffer not locked.", __FUNCTION__);
+ return AMEDIA_IMGREADER_IMAGE_NOT_LOCKED;
+ }
+
if (planeIdx < 0 || planeIdx >= mNumPlanes) {
ALOGE("Error: planeIdx %d out of bound [0,%d]",
planeIdx, mNumPlanes - 1);
@@ -352,140 +441,154 @@
uint8_t* cr = nullptr;
uint8_t* pData = nullptr;
int bytesPerPixel = 0;
- int32_t fmt = mBuffer->flexFormat;
+ int32_t fmt = mLockedBuffer->flexFormat;
switch (fmt) {
case HAL_PIXEL_FORMAT_YCbCr_420_888:
- pData = (planeIdx == 0) ? mBuffer->data :
- (planeIdx == 1) ? mBuffer->dataCb : mBuffer->dataCr;
+ pData = (planeIdx == 0) ? mLockedBuffer->data
+ : (planeIdx == 1) ? mLockedBuffer->dataCb
+ : mLockedBuffer->dataCr;
// only map until last pixel
if (planeIdx == 0) {
- dataSize = mBuffer->stride * (mBuffer->height - 1) + mBuffer->width;
+ dataSize = mLockedBuffer->stride * (mLockedBuffer->height - 1) +
+ mLockedBuffer->width;
} else {
- dataSize = mBuffer->chromaStride * (mBuffer->height / 2 - 1) +
- mBuffer->chromaStep * (mBuffer->width / 2 - 1) + 1;
+ dataSize =
+ mLockedBuffer->chromaStride *
+ (mLockedBuffer->height / 2 - 1) +
+ mLockedBuffer->chromaStep * (mLockedBuffer->width / 2 - 1) +
+ 1;
}
break;
// NV21
case HAL_PIXEL_FORMAT_YCrCb_420_SP:
- cr = mBuffer->data + (mBuffer->stride * mBuffer->height);
+ cr = mLockedBuffer->data +
+ (mLockedBuffer->stride * mLockedBuffer->height);
cb = cr + 1;
// only map until last pixel
- ySize = mBuffer->width * (mBuffer->height - 1) + mBuffer->width;
- cSize = mBuffer->width * (mBuffer->height / 2 - 1) + mBuffer->width - 1;
-
- pData = (planeIdx == 0) ? mBuffer->data :
- (planeIdx == 1) ? cb : cr;
+ ySize = mLockedBuffer->width * (mLockedBuffer->height - 1) +
+ mLockedBuffer->width;
+ cSize = mLockedBuffer->width * (mLockedBuffer->height / 2 - 1) +
+ mLockedBuffer->width - 1;
+ pData = (planeIdx == 0) ? mLockedBuffer->data
+ : (planeIdx == 1) ? cb : cr;
dataSize = (planeIdx == 0) ? ySize : cSize;
break;
case HAL_PIXEL_FORMAT_YV12:
// Y and C stride need to be 16 pixel aligned.
- if (mBuffer->stride % 16) {
- ALOGE("Stride %d is not 16 pixel aligned!", mBuffer->stride);
+ if (mLockedBuffer->stride % 16) {
+ ALOGE("Stride %d is not 16 pixel aligned!",
+ mLockedBuffer->stride);
return AMEDIA_ERROR_UNKNOWN;
}
- ySize = mBuffer->stride * mBuffer->height;
- cStride = ALIGN(mBuffer->stride / 2, 16);
- cr = mBuffer->data + ySize;
- cSize = cStride * mBuffer->height / 2;
+ ySize = mLockedBuffer->stride * mLockedBuffer->height;
+ cStride = ALIGN(mLockedBuffer->stride / 2, 16);
+ cr = mLockedBuffer->data + ySize;
+ cSize = cStride * mLockedBuffer->height / 2;
cb = cr + cSize;
- pData = (planeIdx == 0) ? mBuffer->data :
- (planeIdx == 1) ? cb : cr;
+ pData = (planeIdx == 0) ? mLockedBuffer->data
+ : (planeIdx == 1) ? cb : cr;
dataSize = (planeIdx == 0) ? ySize : cSize;
break;
case HAL_PIXEL_FORMAT_Y8:
// Single plane, 8bpp.
- pData = mBuffer->data;
- dataSize = mBuffer->stride * mBuffer->height;
+ pData = mLockedBuffer->data;
+ dataSize = mLockedBuffer->stride * mLockedBuffer->height;
break;
case HAL_PIXEL_FORMAT_Y16:
bytesPerPixel = 2;
- pData = mBuffer->data;
- dataSize = mBuffer->stride * mBuffer->height * bytesPerPixel;
+ pData = mLockedBuffer->data;
+ dataSize =
+ mLockedBuffer->stride * mLockedBuffer->height * bytesPerPixel;
break;
case HAL_PIXEL_FORMAT_BLOB:
// Used for JPEG data, height must be 1, width == size, single plane.
- if (mBuffer->height != 1) {
- ALOGE("Jpeg should have height value one but got %d", mBuffer->height);
+ if (mLockedBuffer->height != 1) {
+ ALOGE("Jpeg should have height value one but got %d",
+ mLockedBuffer->height);
return AMEDIA_ERROR_UNKNOWN;
}
- pData = mBuffer->data;
+ pData = mLockedBuffer->data;
dataSize = getJpegSize();
break;
case HAL_PIXEL_FORMAT_RAW16:
// Single plane 16bpp bayer data.
bytesPerPixel = 2;
- pData = mBuffer->data;
- dataSize = mBuffer->stride * mBuffer->height * bytesPerPixel;
+ pData = mLockedBuffer->data;
+ dataSize =
+ mLockedBuffer->stride * mLockedBuffer->height * bytesPerPixel;
break;
case HAL_PIXEL_FORMAT_RAW_OPAQUE:
// Used for RAW_OPAQUE data, height must be 1, width == size, single plane.
- if (mBuffer->height != 1) {
- ALOGE("RAW_OPAQUE should have height value one but got %d", mBuffer->height);
+ if (mLockedBuffer->height != 1) {
+ ALOGE("RAW_OPAQUE should have height value one but got %d",
+ mLockedBuffer->height);
return AMEDIA_ERROR_UNKNOWN;
}
- pData = mBuffer->data;
- dataSize = mBuffer->width;
+ pData = mLockedBuffer->data;
+ dataSize = mLockedBuffer->width;
break;
case HAL_PIXEL_FORMAT_RAW10:
// Single plane 10bpp bayer data.
- if (mBuffer->width % 4) {
- ALOGE("Width is not multiple of 4 %d", mBuffer->width);
+ if (mLockedBuffer->width % 4) {
+ ALOGE("Width is not multiple of 4 %d", mLockedBuffer->width);
return AMEDIA_ERROR_UNKNOWN;
}
- if (mBuffer->height % 2) {
- ALOGE("Height is not multiple of 2 %d", mBuffer->height);
+ if (mLockedBuffer->height % 2) {
+ ALOGE("Height is not multiple of 2 %d", mLockedBuffer->height);
return AMEDIA_ERROR_UNKNOWN;
}
- if (mBuffer->stride < (mBuffer->width * 10 / 8)) {
+ if (mLockedBuffer->stride < (mLockedBuffer->width * 10 / 8)) {
ALOGE("stride (%d) should be at least %d",
- mBuffer->stride, mBuffer->width * 10 / 8);
+ mLockedBuffer->stride, mLockedBuffer->width * 10 / 8);
return AMEDIA_ERROR_UNKNOWN;
}
- pData = mBuffer->data;
- dataSize = mBuffer->stride * mBuffer->height;
+ pData = mLockedBuffer->data;
+ dataSize = mLockedBuffer->stride * mLockedBuffer->height;
break;
case HAL_PIXEL_FORMAT_RAW12:
// Single plane 10bpp bayer data.
- if (mBuffer->width % 4) {
- ALOGE("Width is not multiple of 4 %d", mBuffer->width);
+ if (mLockedBuffer->width % 4) {
+ ALOGE("Width is not multiple of 4 %d", mLockedBuffer->width);
return AMEDIA_ERROR_UNKNOWN;
}
- if (mBuffer->height % 2) {
- ALOGE("Height is not multiple of 2 %d", mBuffer->height);
+ if (mLockedBuffer->height % 2) {
+ ALOGE("Height is not multiple of 2 %d", mLockedBuffer->height);
return AMEDIA_ERROR_UNKNOWN;
}
- if (mBuffer->stride < (mBuffer->width * 12 / 8)) {
+ if (mLockedBuffer->stride < (mLockedBuffer->width * 12 / 8)) {
ALOGE("stride (%d) should be at least %d",
- mBuffer->stride, mBuffer->width * 12 / 8);
+ mLockedBuffer->stride, mLockedBuffer->width * 12 / 8);
return AMEDIA_ERROR_UNKNOWN;
}
- pData = mBuffer->data;
- dataSize = mBuffer->stride * mBuffer->height;
+ pData = mLockedBuffer->data;
+ dataSize = mLockedBuffer->stride * mLockedBuffer->height;
break;
case HAL_PIXEL_FORMAT_RGBA_8888:
case HAL_PIXEL_FORMAT_RGBX_8888:
// Single plane, 32bpp.
bytesPerPixel = 4;
- pData = mBuffer->data;
- dataSize = mBuffer->stride * mBuffer->height * bytesPerPixel;
+ pData = mLockedBuffer->data;
+ dataSize =
+ mLockedBuffer->stride * mLockedBuffer->height * bytesPerPixel;
break;
case HAL_PIXEL_FORMAT_RGB_565:
// Single plane, 16bpp.
bytesPerPixel = 2;
- pData = mBuffer->data;
- dataSize = mBuffer->stride * mBuffer->height * bytesPerPixel;
+ pData = mLockedBuffer->data;
+ dataSize =
+ mLockedBuffer->stride * mLockedBuffer->height * bytesPerPixel;
break;
case HAL_PIXEL_FORMAT_RGB_888:
// Single plane, 24bpp.
bytesPerPixel = 3;
- pData = mBuffer->data;
- dataSize = mBuffer->stride * mBuffer->height * bytesPerPixel;
+ pData = mLockedBuffer->data;
+ dataSize = mLockedBuffer->stride * mLockedBuffer->height * bytesPerPixel;
break;
default:
ALOGE("Pixel format: 0x%x is unsupported", fmt);
@@ -602,6 +705,12 @@
__FUNCTION__, image, pixelStride);
return AMEDIA_ERROR_INVALID_PARAMETER;
}
+ media_status_t ret = const_cast<AImage*>(image)->lockImage();
+ if (ret != AMEDIA_OK) {
+ ALOGE("%s: failed to lock buffer for CPU access. image %p, error=%d.",
+ __FUNCTION__, image, ret);
+ return ret;
+ }
return image->getPlanePixelStride(planeIdx, pixelStride);
}
@@ -614,6 +723,12 @@
__FUNCTION__, image, rowStride);
return AMEDIA_ERROR_INVALID_PARAMETER;
}
+ media_status_t ret = const_cast<AImage*>(image)->lockImage();
+ if (ret != AMEDIA_OK) {
+ ALOGE("%s: failed to lock buffer for CPU access. image %p, error=%d.",
+ __FUNCTION__, image, ret);
+ return ret;
+ }
return image->getPlaneRowStride(planeIdx, rowStride);
}
@@ -627,5 +742,11 @@
__FUNCTION__, image, data, dataLength);
return AMEDIA_ERROR_INVALID_PARAMETER;
}
+ media_status_t ret = const_cast<AImage*>(image)->lockImage();
+ if (ret != AMEDIA_OK) {
+ ALOGE("%s: failed to lock buffer for CPU access. image %p, error=%d.",
+ __FUNCTION__, image, ret);
+ return ret;
+ }
return image->getPlaneData(planeIdx, data, dataLength);
}
diff --git a/media/ndk/NdkImagePriv.h b/media/ndk/NdkImagePriv.h
index 89d2b7c..e01dcc7 100644
--- a/media/ndk/NdkImagePriv.h
+++ b/media/ndk/NdkImagePriv.h
@@ -21,6 +21,7 @@
#include <utils/Log.h>
#include <utils/StrongPointer.h>
+#include <gui/BufferItem.h>
#include <gui/CpuConsumer.h>
#include "NdkImageReaderPriv.h"
@@ -31,9 +32,9 @@
// TODO: this only supports ImageReader
struct AImage {
- AImage(AImageReader* reader, int32_t format,
- CpuConsumer::LockedBuffer* buffer, int64_t timestamp,
- int32_t width, int32_t height, int32_t numPlanes);
+ AImage(AImageReader* reader, int32_t format, uint64_t usage,
+ BufferItem* buffer, int64_t timestamp,
+ int32_t width, int32_t height, int32_t numPlanes);
// free all resources while keeping object alive. Caller must obtain reader lock
void close();
@@ -54,6 +55,9 @@
media_status_t getNumPlanes(/*out*/int32_t* numPlanes) const;
media_status_t getTimestamp(/*out*/int64_t* timestamp) const;
+ media_status_t lockImage();
+ media_status_t unlockImageIfLocked(/*out*/int* fenceFd);
+
media_status_t getPlanePixelStride(int planeIdx, /*out*/int32_t* pixelStride) const;
media_status_t getPlaneRowStride(int planeIdx, /*out*/int32_t* rowStride) const;
media_status_t getPlaneData(int planeIdx,/*out*/uint8_t** data, /*out*/int* dataLength) const;
@@ -69,7 +73,9 @@
// When reader is close, AImage will only accept close API call
wp<AImageReader> mReader;
const int32_t mFormat;
- CpuConsumer::LockedBuffer* mBuffer;
+ const uint64_t mUsage; // AHARDWAREBUFFER_USAGE0* flags.
+ BufferItem* mBuffer;
+ std::unique_ptr<CpuConsumer::LockedBuffer> mLockedBuffer;
const int64_t mTimestamp;
const int32_t mWidth;
const int32_t mHeight;
diff --git a/media/ndk/NdkImageReader.cpp b/media/ndk/NdkImageReader.cpp
index ab3829e..e580dae 100644
--- a/media/ndk/NdkImageReader.cpp
+++ b/media/ndk/NdkImageReader.cpp
@@ -24,7 +24,9 @@
#include <cutils/atomic.h>
#include <utils/Log.h>
+#include <android_media_Utils.h>
#include <android_runtime/android_view_Surface.h>
+#include <android_runtime/android_hardware_HardwareBuffer.h>
using namespace android;
@@ -36,6 +38,7 @@
}
}
+const int32_t AImageReader::kDefaultUsage = AHARDWAREBUFFER_USAGE0_CPU_READ_OFTEN;
const char* AImageReader::kCallbackFpKey = "Callback";
const char* AImageReader::kContextKey = "Context";
@@ -151,10 +154,18 @@
}
}
-AImageReader::AImageReader(int32_t width, int32_t height, int32_t format, int32_t maxImages) :
- mWidth(width), mHeight(height), mFormat(format), mMaxImages(maxImages),
- mNumPlanes(getNumPlanesForFormat(format)),
- mFrameListener(new FrameListener(this)) {}
+AImageReader::AImageReader(int32_t width,
+ int32_t height,
+ int32_t format,
+ uint64_t usage,
+ int32_t maxImages)
+ : mWidth(width),
+ mHeight(height),
+ mFormat(format),
+ mUsage(usage),
+ mMaxImages(maxImages),
+ mNumPlanes(getNumPlanesForFormat(format)),
+ mFrameListener(new FrameListener(this)) {}
media_status_t
AImageReader::init() {
@@ -162,42 +173,44 @@
mHalFormat = android_view_Surface_mapPublicFormatToHalFormat(publicFormat);
mHalDataSpace = android_view_Surface_mapPublicFormatToHalDataspace(publicFormat);
+ uint64_t producerUsage;
+ uint64_t consumerUsage;
+ android_hardware_HardwareBuffer_convertToGrallocUsageBits(
+ &producerUsage, &consumerUsage, mUsage, 0);
+
sp<IGraphicBufferProducer> gbProducer;
sp<IGraphicBufferConsumer> gbConsumer;
BufferQueue::createBufferQueue(&gbProducer, &gbConsumer);
- sp<CpuConsumer> cpuConsumer;
- String8 consumerName = String8::format("ImageReader-%dx%df%xm%d-%d-%d",
- mWidth, mHeight, mFormat, mMaxImages, getpid(),
- createProcessUniqueId());
+ String8 consumerName = String8::format(
+ "ImageReader-%dx%df%xu%" PRIu64 "m%d-%d-%d", mWidth, mHeight, mFormat, mUsage,
+ mMaxImages, getpid(), createProcessUniqueId());
- cpuConsumer = new CpuConsumer(gbConsumer, mMaxImages, /*controlledByApp*/true);
- if (cpuConsumer == nullptr) {
- ALOGE("Failed to allocate CpuConsumer");
+ mBufferItemConsumer =
+ new BufferItemConsumer(gbConsumer, consumerUsage, mMaxImages, /*controlledByApp*/ true);
+ if (mBufferItemConsumer == nullptr) {
+ ALOGE("Failed to allocate BufferItemConsumer");
return AMEDIA_ERROR_UNKNOWN;
}
- mCpuConsumer = cpuConsumer;
- mCpuConsumer->setName(consumerName);
mProducer = gbProducer;
-
- sp<ConsumerBase> consumer = cpuConsumer;
- consumer->setFrameAvailableListener(mFrameListener);
+ mBufferItemConsumer->setName(consumerName);
+ mBufferItemConsumer->setFrameAvailableListener(mFrameListener);
status_t res;
- res = cpuConsumer->setDefaultBufferSize(mWidth, mHeight);
+ res = mBufferItemConsumer->setDefaultBufferSize(mWidth, mHeight);
if (res != OK) {
- ALOGE("Failed to set CpuConsumer buffer size");
+ ALOGE("Failed to set BufferItemConsumer buffer size");
return AMEDIA_ERROR_UNKNOWN;
}
- res = cpuConsumer->setDefaultBufferFormat(mHalFormat);
+ res = mBufferItemConsumer->setDefaultBufferFormat(mHalFormat);
if (res != OK) {
- ALOGE("Failed to set CpuConsumer buffer format");
+ ALOGE("Failed to set BufferItemConsumer buffer format");
return AMEDIA_ERROR_UNKNOWN;
}
- res = cpuConsumer->setDefaultBufferDataSpace(mHalDataSpace);
+ res = mBufferItemConsumer->setDefaultBufferDataSpace(mHalDataSpace);
if (res != OK) {
- ALOGE("Failed to set CpuConsumer buffer dataSpace");
+ ALOGE("Failed to set BufferItemConsumer buffer dataSpace");
return AMEDIA_ERROR_UNKNOWN;
}
@@ -209,7 +222,7 @@
mWindow = static_cast<ANativeWindow*>(mSurface.get());
for (int i = 0; i < mMaxImages; i++) {
- CpuConsumer::LockedBuffer* buffer = new CpuConsumer::LockedBuffer;
+ BufferItem* buffer = new BufferItem;
mBuffers.push_back(buffer);
}
@@ -248,133 +261,136 @@
image->close();
}
- // Delete LockedBuffers
+ // Delete Buffer Items
for (auto it = mBuffers.begin();
it != mBuffers.end(); it++) {
delete *it;
}
- if (mCpuConsumer != nullptr) {
- mCpuConsumer->abandon();
- mCpuConsumer->setFrameAvailableListener(nullptr);
+ if (mBufferItemConsumer != nullptr) {
+ mBufferItemConsumer->abandon();
+ mBufferItemConsumer->setFrameAvailableListener(nullptr);
}
}
media_status_t
-AImageReader::acquireCpuConsumerImageLocked(/*out*/AImage** image) {
+AImageReader::acquireImageLocked(/*out*/AImage** image) {
*image = nullptr;
- CpuConsumer::LockedBuffer* buffer = getLockedBufferLocked();
+ BufferItem* buffer = getBufferItemLocked();
if (buffer == nullptr) {
ALOGW("Unable to acquire a lockedBuffer, very likely client tries to lock more than"
" maxImages buffers");
return AMEDIA_IMGREADER_MAX_IMAGES_ACQUIRED;
}
- status_t res = mCpuConsumer->lockNextBuffer(buffer);
+ status_t res = mBufferItemConsumer->acquireBuffer(buffer, 0);
if (res != NO_ERROR) {
- returnLockedBufferLocked(buffer);
- if (res != BAD_VALUE /*no buffers*/) {
- if (res == NOT_ENOUGH_DATA) {
+ returnBufferItemLocked(buffer);
+ if (res != BufferQueue::NO_BUFFER_AVAILABLE) {
+ if (res == INVALID_OPERATION) {
return AMEDIA_IMGREADER_MAX_IMAGES_ACQUIRED;
} else {
- ALOGE("%s Fail to lockNextBuffer with error: %d ",
- __FUNCTION__, res);
+ ALOGE("%s: Acquire image failed with some unknown error: %s (%d)",
+ __FUNCTION__, strerror(-res), res);
return AMEDIA_ERROR_UNKNOWN;
}
}
return AMEDIA_IMGREADER_NO_BUFFER_AVAILABLE;
}
- if (buffer->flexFormat == HAL_PIXEL_FORMAT_YCrCb_420_SP) {
- ALOGE("NV21 format is not supported by AImageReader");
- return AMEDIA_ERROR_UNSUPPORTED;
- }
+ const int bufferWidth = getBufferWidth(buffer);
+ const int bufferHeight = getBufferHeight(buffer);
+ const int bufferFmt = buffer->mGraphicBuffer->getPixelFormat();
- // Check if the left-top corner of the crop rect is origin, we currently assume this point is
- // zero, will revist this once this assumption turns out problematic.
- Point lt = buffer->crop.leftTop();
- if (lt.x != 0 || lt.y != 0) {
- ALOGE("crop left top corner [%d, %d] need to be at origin", lt.x, lt.y);
- return AMEDIA_ERROR_UNKNOWN;
- }
+ const int readerWidth = mWidth;
+ const int readerHeight = mHeight;
+ const int readerFmt = mHalFormat;
- // Check if the producer buffer configurations match what ImageReader configured.
- int outputWidth = getBufferWidth(buffer);
- int outputHeight = getBufferHeight(buffer);
-
- int readerFmt = mHalFormat;
- int readerWidth = mWidth;
- int readerHeight = mHeight;
-
- if ((buffer->format != HAL_PIXEL_FORMAT_BLOB) && (readerFmt != HAL_PIXEL_FORMAT_BLOB) &&
- (readerWidth != outputWidth || readerHeight != outputHeight)) {
- ALOGW("%s: Producer buffer size: %dx%d, doesn't match AImageReader configured size: %dx%d",
- __FUNCTION__, outputWidth, outputHeight, readerWidth, readerHeight);
- }
-
- int bufFmt = buffer->format;
- if (readerFmt == HAL_PIXEL_FORMAT_YCbCr_420_888) {
- bufFmt = buffer->flexFormat;
- }
-
- if (readerFmt != bufFmt) {
- if (readerFmt == HAL_PIXEL_FORMAT_YCbCr_420_888 && (bufFmt ==
- HAL_PIXEL_FORMAT_YCrCb_420_SP || bufFmt == HAL_PIXEL_FORMAT_YV12)) {
- // Special casing for when producer switches to a format compatible with flexible YUV
- // (HAL_PIXEL_FORMAT_YCbCr_420_888).
- mHalFormat = bufFmt;
- ALOGD("%s: Overriding buffer format YUV_420_888 to %x.", __FUNCTION__, bufFmt);
- } else {
- // Return the buffer to the queue.
- mCpuConsumer->unlockBuffer(*buffer);
- returnLockedBufferLocked(buffer);
-
- ALOGE("Producer output buffer format: 0x%x, ImageReader configured format: 0x%x",
- buffer->format, readerFmt);
-
+ // Check if the producer buffer configurations match what AImageReader configured. Add some
+ // extra checks for non-opaque formats.
+ if (!isFormatOpaque(readerFmt)) {
+ // Check if the left-top corner of the crop rect is origin, we currently assume this point
+ // is zero, will revisit this once this assumption turns out problematic.
+ Point lt = buffer->mCrop.leftTop();
+ if (lt.x != 0 || lt.y != 0) {
+ ALOGE("Crop left top corner [%d, %d] not at origin", lt.x, lt.y);
return AMEDIA_ERROR_UNKNOWN;
}
+
+ // Check if the producer buffer configurations match what ImageReader configured.
+ if ((bufferFmt != HAL_PIXEL_FORMAT_BLOB) && (readerFmt != HAL_PIXEL_FORMAT_BLOB) &&
+ (readerWidth != bufferWidth || readerHeight != bufferHeight)) {
+ ALOGW("%s: Buffer size: %dx%d, doesn't match AImageReader configured size: %dx%d",
+ __FUNCTION__, bufferWidth, bufferHeight, readerWidth, readerHeight);
+ }
+
+ if (readerFmt != bufferFmt) {
+ if (readerFmt == HAL_PIXEL_FORMAT_YCbCr_420_888 && isPossiblyYUV(bufferFmt)) {
+ // Special casing for when producer switches to a format compatible with flexible
+ // YUV.
+ mHalFormat = bufferFmt;
+ ALOGD("%s: Overriding buffer format YUV_420_888 to 0x%x.", __FUNCTION__, bufferFmt);
+ } else {
+ // Return the buffer to the queue. No need to provide fence, as this buffer wasn't
+ // used anywhere yet.
+ mBufferItemConsumer->releaseBuffer(*buffer);
+ returnBufferItemLocked(buffer);
+
+ ALOGE("%s: Output buffer format: 0x%x, ImageReader configured format: 0x%x",
+ __FUNCTION__, bufferFmt, readerFmt);
+
+ return AMEDIA_ERROR_UNKNOWN;
+ }
+ }
}
if (mHalFormat == HAL_PIXEL_FORMAT_BLOB) {
- *image = new AImage(this, mFormat, buffer, buffer->timestamp,
+ *image = new AImage(this, mFormat, mUsage, buffer, buffer->mTimestamp,
readerWidth, readerHeight, mNumPlanes);
} else {
- *image = new AImage(this, mFormat, buffer, buffer->timestamp,
- outputWidth, outputHeight, mNumPlanes);
+ *image = new AImage(this, mFormat, mUsage, buffer, buffer->mTimestamp,
+ bufferWidth, bufferHeight, mNumPlanes);
}
mAcquiredImages.push_back(*image);
return AMEDIA_OK;
}
-CpuConsumer::LockedBuffer*
-AImageReader::getLockedBufferLocked() {
+BufferItem*
+AImageReader::getBufferItemLocked() {
if (mBuffers.empty()) {
return nullptr;
}
- // Return a LockedBuffer pointer and remove it from the list
+ // Return a BufferItem pointer and remove it from the list
auto it = mBuffers.begin();
- CpuConsumer::LockedBuffer* buffer = *it;
+ BufferItem* buffer = *it;
mBuffers.erase(it);
return buffer;
}
void
-AImageReader::returnLockedBufferLocked(CpuConsumer::LockedBuffer* buffer) {
+AImageReader::returnBufferItemLocked(BufferItem* buffer) {
mBuffers.push_back(buffer);
}
void
AImageReader::releaseImageLocked(AImage* image) {
- CpuConsumer::LockedBuffer* buffer = image->mBuffer;
+ BufferItem* buffer = image->mBuffer;
if (buffer == nullptr) {
// This should not happen, but is not fatal
ALOGW("AImage %p has no buffer!", image);
return;
}
- mCpuConsumer->unlockBuffer(*buffer);
- returnLockedBufferLocked(buffer);
+ int fenceFd = -1;
+ media_status_t ret = image->unlockImageIfLocked(&fenceFd);
+ if (ret < 0) {
+ ALOGW("%s: AImage %p is cannot be unlocked.", __FUNCTION__, image);
+ return;
+ }
+
+ sp<Fence> releaseFence = fenceFd > 0 ? new Fence(fenceFd) : Fence::NO_FENCE;
+ mBufferItemConsumer->releaseBuffer(*buffer, releaseFence);
+ returnBufferItemLocked(buffer);
image->mBuffer = nullptr;
bool found = false;
@@ -395,29 +411,31 @@
}
int
-AImageReader::getBufferWidth(CpuConsumer::LockedBuffer* buffer) {
- if (buffer == nullptr) return -1;
+AImageReader::getBufferWidth(BufferItem* buffer) {
+ if (buffer == NULL) return -1;
- if (!buffer->crop.isEmpty()) {
- return buffer->crop.getWidth();
+ if (!buffer->mCrop.isEmpty()) {
+ return buffer->mCrop.getWidth();
}
- return buffer->width;
+
+ return buffer->mGraphicBuffer->getWidth();
}
int
-AImageReader::getBufferHeight(CpuConsumer::LockedBuffer* buffer) {
- if (buffer == nullptr) return -1;
+AImageReader::getBufferHeight(BufferItem* buffer) {
+ if (buffer == NULL) return -1;
- if (!buffer->crop.isEmpty()) {
- return buffer->crop.getHeight();
+ if (!buffer->mCrop.isEmpty()) {
+ return buffer->mCrop.getHeight();
}
- return buffer->height;
+
+ return buffer->mGraphicBuffer->getHeight();
}
media_status_t
AImageReader::acquireNextImage(/*out*/AImage** image) {
Mutex::Autolock _l(mLock);
- return acquireCpuConsumerImageLocked(image);
+ return acquireImageLocked(image);
}
media_status_t
@@ -429,12 +447,12 @@
*image = nullptr;
AImage* prevImage = nullptr;
AImage* nextImage = nullptr;
- media_status_t ret = acquireCpuConsumerImageLocked(&prevImage);
+ media_status_t ret = acquireImageLocked(&prevImage);
if (prevImage == nullptr) {
return ret;
}
for (;;) {
- ret = acquireCpuConsumerImageLocked(&nextImage);
+ ret = acquireImageLocked(&nextImage);
if (nextImage == nullptr) {
*image = prevImage;
return AMEDIA_OK;
@@ -464,6 +482,12 @@
return AMEDIA_ERROR_INVALID_PARAMETER;
}
+ if (maxImages > BufferQueueDefs::NUM_BUFFER_SLOTS) {
+ ALOGE("%s: max outstanding image count (%d) cannot be larget than %d.",
+ __FUNCTION__, maxImages, BufferQueueDefs::NUM_BUFFER_SLOTS);
+ return AMEDIA_ERROR_INVALID_PARAMETER;
+ }
+
if (!AImageReader::isSupportedFormat(format)) {
ALOGE("%s: format %d is not supported by AImageReader",
__FUNCTION__, format);
@@ -475,8 +499,10 @@
return AMEDIA_ERROR_INVALID_PARAMETER;
}
- //*reader = new AImageReader(width, height, format, maxImages);
- AImageReader* tmpReader = new AImageReader(width, height, format, maxImages);
+ // Set consumer usage to AHARDWAREBUFFER_USAGE0_CPU_READ_OFTEN by default so that
+ // AImageReader_new behaves as if it's backed by CpuConsumer.
+ AImageReader* tmpReader = new AImageReader(
+ width, height, format, AImageReader::kDefaultUsage, maxImages);
if (tmpReader == nullptr) {
ALOGE("%s: AImageReader allocation failed", __FUNCTION__);
return AMEDIA_ERROR_UNKNOWN;
@@ -565,7 +591,7 @@
media_status_t AImageReader_acquireNextImage(AImageReader* reader, /*out*/AImage** image) {
ALOGV("%s", __FUNCTION__);
if (reader == nullptr || image == nullptr) {
- ALOGE("%s: invalid argument. reader %p, maxImages %p",
+ ALOGE("%s: invalid argument. reader %p, image %p",
__FUNCTION__, reader, image);
return AMEDIA_ERROR_INVALID_PARAMETER;
}
@@ -576,7 +602,7 @@
media_status_t AImageReader_acquireLatestImage(AImageReader* reader, /*out*/AImage** image) {
ALOGV("%s", __FUNCTION__);
if (reader == nullptr || image == nullptr) {
- ALOGE("%s: invalid argument. reader %p, maxImages %p",
+ ALOGE("%s: invalid argument. reader %p, image %p",
__FUNCTION__, reader, image);
return AMEDIA_ERROR_INVALID_PARAMETER;
}
diff --git a/media/ndk/NdkImageReaderPriv.h b/media/ndk/NdkImageReaderPriv.h
index 8b540fa..8becb1d 100644
--- a/media/ndk/NdkImageReaderPriv.h
+++ b/media/ndk/NdkImageReaderPriv.h
@@ -25,7 +25,8 @@
#include <utils/Mutex.h>
#include <utils/StrongPointer.h>
-#include <gui/CpuConsumer.h>
+#include <gui/BufferItem.h>
+#include <gui/BufferItemConsumer.h>
#include <gui/Surface.h>
#include <media/stagefright/foundation/ALooper.h>
@@ -48,11 +49,16 @@
struct AImageReader : public RefBase {
public:
+ static const int32_t kDefaultUsage;
static bool isSupportedFormat(int32_t format);
static int getNumPlanesForFormat(int32_t format);
- AImageReader(int32_t width, int32_t height, int32_t format, int32_t maxImages);
+ AImageReader(int32_t width,
+ int32_t height,
+ int32_t format,
+ uint64_t usage,
+ int32_t maxImages);
~AImageReader();
// Inintialize AImageReader, uninitialized or failed to initialize AImageReader
@@ -68,22 +74,24 @@
int32_t getWidth() const { return mWidth; };
int32_t getHeight() const { return mHeight; };
int32_t getFormat() const { return mFormat; };
+ uint64_t getUsage() const { return mUsage; };
int32_t getMaxImages() const { return mMaxImages; };
-
private:
friend struct AImage; // for grabing reader lock
- media_status_t acquireCpuConsumerImageLocked(/*out*/AImage** image);
- CpuConsumer::LockedBuffer* getLockedBufferLocked();
- void returnLockedBufferLocked(CpuConsumer::LockedBuffer* buffer);
+ BufferItem* getBufferItemLocked();
+ void returnBufferItemLocked(BufferItem* buffer);
+
+ // Called by AImageReader_acquireXXX to acquire a Buffer and setup AImage.
+ media_status_t acquireImageLocked(/*out*/AImage** image);
// Called by AImage to close image
void releaseImageLocked(AImage* image);
- static int getBufferWidth(CpuConsumer::LockedBuffer* buffer);
- static int getBufferHeight(CpuConsumer::LockedBuffer* buffer);
+ static int getBufferWidth(BufferItem* buffer);
+ static int getBufferHeight(BufferItem* buffer);
media_status_t setImageListenerLocked(AImageReader_ImageListener* listener);
@@ -102,12 +110,15 @@
};
sp<CallbackHandler> mHandler;
sp<ALooper> mCbLooper; // Looper thread where callbacks actually happen on
+ List<BufferItem*> mBuffers;
- List<CpuConsumer::LockedBuffer*> mBuffers;
const int32_t mWidth;
const int32_t mHeight;
const int32_t mFormat;
+ const uint64_t mUsage;
const int32_t mMaxImages;
+
+ // TODO(jwcai) Seems completely unused in AImageReader class.
const int32_t mNumPlanes;
struct FrameListener : public ConsumerBase::FrameAvailableListener {
@@ -130,7 +141,7 @@
sp<IGraphicBufferProducer> mProducer;
sp<Surface> mSurface;
- sp<CpuConsumer> mCpuConsumer;
+ sp<BufferItemConsumer> mBufferItemConsumer;
sp<ANativeWindow> mWindow;
List<AImage*> mAcquiredImages;
diff --git a/services/audioflinger/AudioFlinger.cpp b/services/audioflinger/AudioFlinger.cpp
index c0918d4..7eb179a 100644
--- a/services/audioflinger/AudioFlinger.cpp
+++ b/services/audioflinger/AudioFlinger.cpp
@@ -292,7 +292,8 @@
sessionId,
&streamType, client.clientUid,
&fullConfig,
- (audio_output_flags_t)(AUDIO_OUTPUT_FLAG_MMAP_NOIRQ | AUDIO_OUTPUT_FLAG_DIRECT),
+ (audio_output_flags_t)(AUDIO_OUTPUT_FLAG_MMAP_NOIRQ |
+ AUDIO_OUTPUT_FLAG_DIRECT),
*deviceId, &portId);
} else {
ret = AudioSystem::getInputForAttr(attr, &io,
@@ -2017,7 +2018,8 @@
uint32_t *latencyMs,
audio_output_flags_t flags)
{
- ALOGI("openOutput() this %p, module %d Device %x, SamplingRate %d, Format %#08x, Channels %x, flags %x",
+ ALOGI("openOutput() this %p, module %d Device %x, SamplingRate %d, Format %#08x, Channels %x, "
+ "flags %x",
this, module,
(devices != NULL) ? *devices : 0,
config->sample_rate,
@@ -2115,13 +2117,13 @@
if (mPlaybackThreads.size()) {
PlaybackThread *dstThread = checkPlaybackThread_l(mPlaybackThreads.keyAt(0));
if (dstThread != NULL) {
- // audioflinger lock is held here so the acquisition order of thread locks does not
- // matter
+ // audioflinger lock is held so order of thread lock acquisition doesn't matter
Mutex::Autolock _dl(dstThread->mLock);
Mutex::Autolock _sl(playbackThread->mLock);
Vector< sp<EffectChain> > effectChains = playbackThread->getEffectChains_l();
for (size_t i = 0; i < effectChains.size(); i ++) {
- moveEffectChain_l(effectChains[i]->sessionId(), playbackThread.get(), dstThread, true);
+ moveEffectChain_l(effectChains[i]->sessionId(), playbackThread.get(),
+ dstThread, true);
}
}
}
@@ -2293,7 +2295,8 @@
inHwDev, inputStream,
primaryOutputDevice_l(), devices, mSystemReady);
mMmapThreads.add(*input, thread);
- ALOGV("openInput_l() created mmap capture thread: ID %d thread %p", *input, thread.get());
+ ALOGV("openInput_l() created mmap capture thread: ID %d thread %p", *input,
+ thread.get());
return thread;
} else {
#ifdef TEE_SINK
@@ -2399,7 +2402,7 @@
}
}
if (chain != 0) {
- // first check if a record thread is already opened with a client on the same session.
+ // first check if a record thread is already opened with a client on same session.
// This should only happen in case of overlap between one thread tear down and the
// creation of its replacement
size_t i;
@@ -2416,7 +2419,7 @@
break;
}
}
- // put the chain aside if we could not find a record thread with the same session id.
+ // put the chain aside if we could not find a record thread with the same session id
if (i == mRecordThreads.size()) {
putOrphanEffectChain_l(chain);
}
diff --git a/services/audioflinger/AudioFlinger.h b/services/audioflinger/AudioFlinger.h
index b79f09e..fca840b 100644
--- a/services/audioflinger/AudioFlinger.h
+++ b/services/audioflinger/AudioFlinger.h
@@ -593,7 +593,8 @@
virtual status_t createMmapBuffer(int32_t minSizeFrames,
struct audio_mmap_buffer_info *info);
virtual status_t getMmapPosition(struct audio_mmap_position *position);
- virtual status_t start(const MmapStreamInterface::Client& client, audio_port_handle_t *handle);
+ virtual status_t start(const MmapStreamInterface::Client& client,
+ audio_port_handle_t *handle);
virtual status_t stop(audio_port_handle_t handle);
virtual status_t standby();
diff --git a/services/audioflinger/FastMixer.cpp b/services/audioflinger/FastMixer.cpp
index 7182f32..103e7f8 100644
--- a/services/audioflinger/FastMixer.cpp
+++ b/services/audioflinger/FastMixer.cpp
@@ -37,7 +37,7 @@
#include <cpustats/ThreadCpuUsage.h>
#endif
#endif
-#include <audio_utils/conversion.h>
+#include <audio_utils/mono_blend.h>
#include <audio_utils/format.h>
#include <media/AudioMixer.h>
#include "FastMixer.h"
diff --git a/services/audioflinger/FastMixerState.cpp b/services/audioflinger/FastMixerState.cpp
index ad471fb..36d8eef 100644
--- a/services/audioflinger/FastMixerState.cpp
+++ b/services/audioflinger/FastMixerState.cpp
@@ -14,6 +14,9 @@
* limitations under the License.
*/
+#define LOG_TAG "FastMixerState"
+//#define LOG_NDEBUG 0
+
#include <cutils/properties.h>
#include "FastMixerState.h"
diff --git a/services/audioflinger/Threads.cpp b/services/audioflinger/Threads.cpp
index 14ff6ee..54e07c0 100644
--- a/services/audioflinger/Threads.cpp
+++ b/services/audioflinger/Threads.cpp
@@ -36,7 +36,7 @@
#include <private/media/AudioTrackShared.h>
#include <private/android_filesystem_config.h>
-#include <audio_utils/conversion.h>
+#include <audio_utils/mono_blend.h>
#include <audio_utils/primitives.h>
#include <audio_utils/format.h>
#include <audio_utils/minifloat.h>
@@ -5603,7 +5603,7 @@
ALOGV("OffloadThread: BUFFER TIMEOUT: remove(%d) from active list",
track->name());
tracksToRemove->add(track);
- // indicate to client process that the track was disabled because of underrun;
+ // tell client process that the track was disabled because of underrun;
// it will then automatically call start() when data is available
track->disable();
}
@@ -7219,7 +7219,8 @@
// Over-allocate beyond mRsmpInFramesP2 to permit a HAL read past end of buffer
mRsmpInFramesOA = mRsmpInFramesP2 + mFrameCount - 1;
(void)posix_memalign(&mRsmpInBuffer, 32, mRsmpInFramesOA * mFrameSize);
- memset(mRsmpInBuffer, 0, mRsmpInFramesOA * mFrameSize); // if posix_memalign fails, will segv here.
+ // if posix_memalign fails, will segv here.
+ memset(mRsmpInBuffer, 0, mRsmpInFramesOA * mFrameSize);
// AudioRecord mSampleRate and mChannelCount are constant due to AudioRecord API constraints.
// But if thread's mSampleRate or mChannelCount changes, how will that affect active tracks?
@@ -7463,7 +7464,8 @@
return mThread->getMmapPosition(position);
}
-status_t AudioFlinger::MmapThreadHandle::start(const MmapStreamInterface::Client& client, audio_port_handle_t *handle)
+status_t AudioFlinger::MmapThreadHandle::start(const MmapStreamInterface::Client& client,
+ audio_port_handle_t *handle)
{
if (mThread == 0) {
@@ -8073,8 +8075,8 @@
return BAD_VALUE;
}
if (isOutput() && ((desc->flags & EFFECT_FLAG_TYPE_MASK) == EFFECT_FLAG_TYPE_PRE_PROC)) {
- ALOGW("checkEffectCompatibility_l(): pre processing effect %s created on playback mmap thread",
- desc->name);
+ ALOGW("checkEffectCompatibility_l(): pre processing effect %s created on playback mmap "
+ "thread", desc->name);
return BAD_VALUE;
}
@@ -8306,7 +8308,8 @@
{
MmapThread::dumpInternals(fd, args);
- dprintf(fd, " Stream type: %d Stream volume: %f HAL volume: %f Stream mute %d\n", mStreamType, mStreamVolume, mHalVolFloat, mStreamMute);
+ dprintf(fd, " Stream type: %d Stream volume: %f HAL volume: %f Stream mute %d\n",
+ mStreamType, mStreamVolume, mHalVolFloat, mStreamMute);
dprintf(fd, " Master volume: %f Master mute %d\n", mMasterVolume, mMasterMute);
}
diff --git a/services/camera/libcameraservice/CameraService.cpp b/services/camera/libcameraservice/CameraService.cpp
index 702c92d..4318a11 100644
--- a/services/camera/libcameraservice/CameraService.cpp
+++ b/services/camera/libcameraservice/CameraService.cpp
@@ -423,20 +423,18 @@
// Remove cached shim parameters
state->setShimParams(CameraParameters());
- // Remove the client from the list of active clients
+ // Remove the client from the list of active clients, if there is one
clientToDisconnect = removeClientLocked(id);
+ }
+ // Disconnect client
+ if (clientToDisconnect.get() != nullptr) {
+ ALOGI("%s: Client for camera ID %s evicted due to device status change from HAL",
+ __FUNCTION__, id.string());
// Notify the client of disconnection
clientToDisconnect->notifyError(
hardware::camera2::ICameraDeviceCallbacks::ERROR_CAMERA_DISCONNECTED,
CaptureResultExtras{});
- }
-
- ALOGI("%s: Client for camera ID %s evicted due to device status change from HAL",
- __FUNCTION__, id.string());
-
- // Disconnect client
- if (clientToDisconnect.get() != nullptr) {
// Ensure not in binder RPC so client disconnect PID checks work correctly
LOG_ALWAYS_FATAL_IF(getCallingPid() != getpid(),
"onDeviceStatusChanged must be called from the camera service process!");
diff --git a/services/camera/libcameraservice/common/CameraProviderManager.cpp b/services/camera/libcameraservice/common/CameraProviderManager.cpp
index f6ad7d7..f8b2908 100644
--- a/services/camera/libcameraservice/common/CameraProviderManager.cpp
+++ b/services/camera/libcameraservice/common/CameraProviderManager.cpp
@@ -21,6 +21,7 @@
#include "CameraProviderManager.h"
#include <chrono>
+#include <inttypes.h>
#include <hidl/ServiceManagement.h>
namespace android {
@@ -65,7 +66,7 @@
}
// See if there's a passthrough HAL, but let's not complain if there's not
- addProvider(kLegacyProviderName, /*expected*/ false);
+ addProviderLocked(kLegacyProviderName, /*expected*/ false);
return OK;
}
@@ -194,14 +195,19 @@
for (auto& provider : mProviders) {
hardware::hidl_vec<VendorTagSection> vts;
Status status;
- provider->mInterface->getVendorTags(
+ hardware::Return<void> ret;
+ ret = provider->mInterface->getVendorTags(
[&](auto s, const auto& vendorTagSecs) {
status = s;
if (s == Status::OK) {
vts = vendorTagSecs;
}
});
-
+ if (!ret.isOk()) {
+ ALOGE("%s: Transaction error getting vendor tags from provider '%s': %s",
+ __FUNCTION__, provider->mProviderName.c_str(), ret.description().c_str());
+ return DEAD_OBJECT;
+ }
if (status != Status::OK) {
return mapToStatusT(status);
}
@@ -239,13 +245,19 @@
auto *deviceInfo3 = static_cast<ProviderInfo::DeviceInfo3*>(deviceInfo);
Status status;
- deviceInfo3->mInterface->open(callback, [&status, &session]
+ hardware::Return<void> ret;
+ ret = deviceInfo3->mInterface->open(callback, [&status, &session]
(Status s, const sp<device::V3_2::ICameraDeviceSession>& cameraSession) {
status = s;
if (status == Status::OK) {
*session = cameraSession;
}
});
+ if (!ret.isOk()) {
+ ALOGE("%s: Transaction error opening a session for camera device %s: %s",
+ __FUNCTION__, id.c_str(), ret.description().c_str());
+ return DEAD_OBJECT;
+ }
return mapToStatusT(status);
}
@@ -262,7 +274,12 @@
auto *deviceInfo1 = static_cast<ProviderInfo::DeviceInfo1*>(deviceInfo);
- Status status = deviceInfo1->mInterface->open(callback);
+ hardware::Return<Status> status = deviceInfo1->mInterface->open(callback);
+ if (!status.isOk()) {
+ ALOGE("%s: Transaction error opening a session for camera device %s: %s",
+ __FUNCTION__, id.c_str(), status.description().c_str());
+ return DEAD_OBJECT;
+ }
if (status == Status::OK) {
*session = deviceInfo1->mInterface;
}
@@ -276,7 +293,7 @@
bool /*preexisting*/) {
std::lock_guard<std::mutex> lock(mInterfaceMutex);
- addProvider(name);
+ addProviderLocked(name);
return hardware::Return<void>();
}
@@ -304,7 +321,7 @@
}
-status_t CameraProviderManager::addProvider(const std::string& newProvider, bool expected) {
+status_t CameraProviderManager::addProviderLocked(const std::string& newProvider, bool expected) {
for (const auto& providerInfo : mProviders) {
if (providerInfo->mProviderName == newProvider) {
ALOGW("%s: Camera provider HAL with name '%s' already registered", __FUNCTION__,
@@ -312,13 +329,14 @@
return ALREADY_EXISTS;
}
}
- sp<provider::V2_4::ICameraProvider> interface =
- mServiceProxy->getService(newProvider);
+
+ sp<provider::V2_4::ICameraProvider> interface;
+ interface = mServiceProxy->getService(newProvider);
if (interface == nullptr) {
- ALOGW("%s: Camera provider HAL '%s' is not actually available", __FUNCTION__,
- newProvider.c_str());
if (expected) {
+ ALOGE("%s: Camera provider HAL '%s' is not actually available", __FUNCTION__,
+ newProvider.c_str());
return BAD_VALUE;
} else {
return OK;
@@ -338,15 +356,39 @@
}
status_t CameraProviderManager::removeProvider(const std::string& provider) {
+ std::unique_lock<std::mutex> lock(mInterfaceMutex);
+ std::vector<String8> removedDeviceIds;
+ status_t res = NAME_NOT_FOUND;
for (auto it = mProviders.begin(); it != mProviders.end(); it++) {
if ((*it)->mProviderName == provider) {
+ removedDeviceIds.reserve((*it)->mDevices.size());
+ for (auto& deviceInfo : (*it)->mDevices) {
+ removedDeviceIds.push_back(String8(deviceInfo->mId.c_str()));
+ }
mProviders.erase(it);
- return OK;
+ res = OK;
+ break;
}
}
- ALOGW("%s: Camera provider HAL with name '%s' is not registered", __FUNCTION__,
- provider.c_str());
- return NAME_NOT_FOUND;
+ if (res != OK) {
+ ALOGW("%s: Camera provider HAL with name '%s' is not registered", __FUNCTION__,
+ provider.c_str());
+ } else {
+ // Inform camera service of loss of presence for all the devices from this provider,
+ // without lock held for reentrancy
+ sp<StatusListener> listener = getStatusListener();
+ if (listener != nullptr) {
+ lock.unlock();
+ for (auto& id : removedDeviceIds) {
+ listener->onDeviceStatusChanged(id, CameraDeviceStatus::NOT_PRESENT);
+ }
+ }
+ }
+ return res;
+}
+
+sp<CameraProviderManager::StatusListener> CameraProviderManager::getStatusListener() const {
+ return mListener.promote();
}
/**** Methods for ProviderInfo ****/
@@ -370,17 +412,31 @@
}
ALOGI("Connecting to new camera provider: %s, isRemote? %d",
mProviderName.c_str(), mInterface->isRemote());
- Status status = mInterface->setCallback(this);
+ hardware::Return<Status> status = mInterface->setCallback(this);
+ if (!status.isOk()) {
+ ALOGE("%s: Transaction error setting up callbacks with camera provider '%s': %s",
+ __FUNCTION__, mProviderName.c_str(), status.description().c_str());
+ return DEAD_OBJECT;
+ }
if (status != Status::OK) {
ALOGE("%s: Unable to register callbacks with camera provider '%s'",
__FUNCTION__, mProviderName.c_str());
return mapToStatusT(status);
}
- // TODO: Register for hw binder death notifications as well
+
+ hardware::Return<bool> linked = mInterface->linkToDeath(this, /*cookie*/ mId);
+ if (!linked.isOk()) {
+ ALOGE("%s: Transaction error in linking to camera provider '%s' death: %s",
+ __FUNCTION__, mProviderName.c_str(), linked.description().c_str());
+ return DEAD_OBJECT;
+ } else if (!linked) {
+ ALOGW("%s: Unable to link to provider '%s' death notifications",
+ __FUNCTION__, mProviderName.c_str());
+ }
// Get initial list of camera devices, if any
std::vector<std::string> devices;
- mInterface->getCameraIdList([&status, &devices](
+ hardware::Return<void> ret = mInterface->getCameraIdList([&status, &devices](
Status idStatus,
const hardware::hidl_vec<hardware::hidl_string>& cameraDeviceNames) {
status = idStatus;
@@ -389,18 +445,29 @@
devices.push_back(cameraDeviceNames[i]);
}
} });
-
+ if (!ret.isOk()) {
+ ALOGE("%s: Transaction error in getting camera ID list from provider '%s': %s",
+ __FUNCTION__, mProviderName.c_str(), linked.description().c_str());
+ return DEAD_OBJECT;
+ }
if (status != Status::OK) {
ALOGE("%s: Unable to query for camera devices from provider '%s'",
__FUNCTION__, mProviderName.c_str());
return mapToStatusT(status);
}
+ sp<StatusListener> listener = mManager->getStatusListener();
for (auto& device : devices) {
- status_t res = addDevice(device);
+ std::string id;
+ status_t res = addDevice(device,
+ hardware::camera::common::V1_0::CameraDeviceStatus::PRESENT, &id);
if (res != OK) {
ALOGE("%s: Unable to enumerate camera device '%s': %s (%d)",
__FUNCTION__, device.c_str(), strerror(-res), res);
+ continue;
+ }
+ if (listener != nullptr) {
+ listener->onDeviceStatusChanged(String8(id.c_str()), CameraDeviceStatus::PRESENT);
}
}
@@ -462,8 +529,9 @@
}
status_t CameraProviderManager::ProviderInfo::dump(int fd, const Vector<String16>&) const {
- dprintf(fd, "== Camera Provider HAL %s (v2.4) static info: %zu devices: ==\n",
- mProviderName.c_str(), mDevices.size());
+ dprintf(fd, "== Camera Provider HAL %s (v2.4, %s) static info: %zu devices: ==\n",
+ mProviderName.c_str(), mInterface->isRemote() ? "remote" : "passthrough",
+ mDevices.size());
for (auto& device : mDevices) {
dprintf(fd, "== Camera HAL device %s (v%d.%d) static information: ==\n", device->mName.c_str(),
@@ -512,7 +580,7 @@
sp<StatusListener> listener;
std::string id;
{
- std::lock_guard<std::mutex> lock(mManager->mStatusListenerMutex);
+ std::lock_guard<std::mutex> lock(mLock);
bool known = false;
for (auto& deviceInfo : mDevices) {
if (deviceInfo->mName == cameraDeviceName) {
@@ -534,7 +602,7 @@
}
addDevice(cameraDeviceName, newStatus, &id);
}
- listener = mManager->mListener.promote();
+ listener = mManager->getStatusListener();
}
// Call without lock held to allow reentrancy into provider manager
if (listener != nullptr) {
@@ -565,7 +633,7 @@
mProviderName.c_str(), cameraDeviceName.c_str(), newStatus);
return hardware::Void();
}
- listener = mManager->mListener.promote();
+ listener = mManager->getStatusListener();
}
// Call without lock held to allow reentrancy into provider manager
if (listener != nullptr) {
@@ -574,6 +642,16 @@
return hardware::Void();
}
+void CameraProviderManager::ProviderInfo::serviceDied(uint64_t cookie,
+ const wp<hidl::base::V1_0::IBase>& who) {
+ (void) who;
+ ALOGI("Camera provider '%s' has died; removing it", mProviderName.c_str());
+ if (cookie != mId) {
+ ALOGW("%s: Unexpected serviceDied cookie %" PRIu64 ", expected %" PRIu32,
+ __FUNCTION__, cookie, mId);
+ }
+ mManager->removeProvider(mProviderName);
+}
template<class DeviceInfoT>
std::unique_ptr<CameraProviderManager::ProviderInfo::DeviceInfo>
@@ -615,11 +693,17 @@
<device::V1_0::ICameraDevice>(const std::string &name) const {
Status status;
sp<device::V1_0::ICameraDevice> cameraInterface;
- mInterface->getCameraDeviceInterface_V1_x(name, [&status, &cameraInterface](
+ hardware::Return<void> ret;
+ ret = mInterface->getCameraDeviceInterface_V1_x(name, [&status, &cameraInterface](
Status s, sp<device::V1_0::ICameraDevice> interface) {
status = s;
cameraInterface = interface;
});
+ if (!ret.isOk()) {
+ ALOGE("%s: Transaction error trying to obtain interface for camera device %s: %s",
+ __FUNCTION__, name.c_str(), ret.description().c_str());
+ return nullptr;
+ }
if (status != Status::OK) {
ALOGE("%s: Unable to obtain interface for camera device %s: %s", __FUNCTION__,
name.c_str(), statusToString(status));
@@ -634,11 +718,17 @@
<device::V3_2::ICameraDevice>(const std::string &name) const {
Status status;
sp<device::V3_2::ICameraDevice> cameraInterface;
- mInterface->getCameraDeviceInterface_V3_x(name, [&status, &cameraInterface](
+ hardware::Return<void> ret;
+ ret = mInterface->getCameraDeviceInterface_V3_x(name, [&status, &cameraInterface](
Status s, sp<device::V3_2::ICameraDevice> interface) {
status = s;
cameraInterface = interface;
});
+ if (!ret.isOk()) {
+ ALOGE("%s: Transaction error trying to obtain interface for camera device %s: %s",
+ __FUNCTION__, name.c_str(), ret.description().c_str());
+ return nullptr;
+ }
if (status != Status::OK) {
ALOGE("%s: Unable to obtain interface for camera device %s: %s", __FUNCTION__,
name.c_str(), statusToString(status));
@@ -665,25 +755,37 @@
mInterface(interface) {
// Get default parameters and initialize flash unit availability
// Requires powering on the camera device
- Status status = mInterface->open(nullptr);
- if (status != Status::OK) {
- ALOGE("%s: Unable to open camera device %s to check for a flash unit: %s (%d)", __FUNCTION__,
- mId.c_str(), CameraProviderManager::statusToString(status), status);
+ hardware::Return<Status> status = mInterface->open(nullptr);
+ if (!status.isOk()) {
+ ALOGE("%s: Transaction error opening camera device %s to check for a flash unit: %s",
+ __FUNCTION__, mId.c_str(), status.description().c_str());
return;
}
- mInterface->getParameters([this](const hardware::hidl_string& parms) {
+ if (status != Status::OK) {
+ ALOGE("%s: Unable to open camera device %s to check for a flash unit: %s", __FUNCTION__,
+ mId.c_str(), CameraProviderManager::statusToString(status));
+ return;
+ }
+ hardware::Return<void> ret;
+ ret = mInterface->getParameters([this](const hardware::hidl_string& parms) {
mDefaultParameters.unflatten(String8(parms.c_str()));
});
-
+ if (!ret.isOk()) {
+ ALOGE("%s: Transaction error reading camera device %s params to check for a flash unit: %s",
+ __FUNCTION__, mId.c_str(), status.description().c_str());
+ return;
+ }
const char *flashMode =
mDefaultParameters.get(CameraParameters::KEY_SUPPORTED_FLASH_MODES);
if (flashMode && strstr(flashMode, CameraParameters::FLASH_MODE_TORCH)) {
mHasFlashUnit = true;
- } else {
- mHasFlashUnit = false;
}
- mInterface->close();
+ ret = mInterface->close();
+ if (!ret.isOk()) {
+ ALOGE("%s: Transaction error closing camera device %s after check for a flash unit: %s",
+ __FUNCTION__, mId.c_str(), status.description().c_str());
+ }
}
CameraProviderManager::ProviderInfo::DeviceInfo1::~DeviceInfo1() {}
@@ -698,10 +800,16 @@
Status status;
device::V1_0::CameraInfo cInfo;
- mInterface->getCameraInfo([&status, &cInfo](Status s, device::V1_0::CameraInfo camInfo) {
+ hardware::Return<void> ret;
+ ret = mInterface->getCameraInfo([&status, &cInfo](Status s, device::V1_0::CameraInfo camInfo) {
status = s;
cInfo = camInfo;
});
+ if (!ret.isOk()) {
+ ALOGE("%s: Transaction error reading camera info from device %s: %s",
+ __FUNCTION__, mId.c_str(), ret.description().c_str());
+ return DEAD_OBJECT;
+ }
if (status != Status::OK) {
return mapToStatusT(status);
}
@@ -716,7 +824,8 @@
info->facing = hardware::CAMERA_FACING_FRONT;
break;
default:
- ALOGW("%s: Unknown camera facing: %d", __FUNCTION__, cInfo.facing);
+ ALOGW("%s: Device %s: Unknown camera facing: %d",
+ __FUNCTION__, mId.c_str(), cInfo.facing);
info->facing = hardware::CAMERA_FACING_BACK;
}
info->orientation = cInfo.orientation;
@@ -733,7 +842,8 @@
mInterface(interface) {
// Get camera characteristics and initialize flash unit availability
Status status;
- mInterface->getCameraCharacteristics([&status, this](Status s,
+ hardware::Return<void> ret;
+ ret = mInterface->getCameraCharacteristics([&status, this](Status s,
device::V3_2::CameraMetadata metadata) {
status = s;
if (s == Status::OK) {
@@ -742,6 +852,12 @@
mCameraCharacteristics = buffer;
}
});
+ if (!ret.isOk()) {
+ ALOGE("%s: Transaction error getting camera characteristics for device %s"
+ " to check for a flash unit: %s", __FUNCTION__, mId.c_str(),
+ ret.description().c_str());
+ return;
+ }
if (status != Status::OK) {
ALOGE("%s: Unable to get camera characteristics for device %s: %s (%d)",
__FUNCTION__, mId.c_str(), CameraProviderManager::statusToString(status), status);
diff --git a/services/camera/libcameraservice/common/CameraProviderManager.h b/services/camera/libcameraservice/common/CameraProviderManager.h
index 5ae16cd..b1da831 100644
--- a/services/camera/libcameraservice/common/CameraProviderManager.h
+++ b/services/camera/libcameraservice/common/CameraProviderManager.h
@@ -226,7 +226,10 @@
static HardwareServiceInteractionProxy sHardwareServiceInteractionProxy;
- struct ProviderInfo : virtual public hardware::camera::provider::V2_4::ICameraProviderCallback {
+ struct ProviderInfo :
+ virtual public hardware::camera::provider::V2_4::ICameraProviderCallback,
+ virtual public hardware::hidl_death_recipient
+ {
const std::string mProviderName;
const sp<hardware::camera::provider::V2_4::ICameraProvider> mInterface;
@@ -254,6 +257,9 @@
const hardware::hidl_string& cameraDeviceName,
hardware::camera::common::V1_0::TorchModeStatus newStatus) override;
+ // hidl_death_recipient interface - this locks the parent mInterfaceMutex
+ virtual void serviceDied(uint64_t cookie, const wp<hidl::base::V1_0::IBase>& who) override;
+
// Basic device information, common to all camera devices
struct DeviceInfo {
const std::string mName; // Full instance name
@@ -327,6 +333,8 @@
std::string mType;
uint32_t mId;
+ std::mutex mLock;
+
CameraProviderManager *mManager;
// Templated method to instantiate the right kind of DeviceInfo and call the
@@ -357,8 +365,10 @@
hardware::hidl_version minVersion = hardware::hidl_version{0,0},
hardware::hidl_version maxVersion = hardware::hidl_version{1000,0}) const;
- status_t addProvider(const std::string& newProvider, bool expected = true);
+ status_t addProviderLocked(const std::string& newProvider, bool expected = true);
+
status_t removeProvider(const std::string& provider);
+ sp<StatusListener> getStatusListener() const;
bool isValidDeviceLocked(const std::string &id, uint16_t majorVersion) const;
diff --git a/services/radio/RadioHalHidl.h b/services/radio/RadioHalHidl.h
index 38e181a..f98420d 100644
--- a/services/radio/RadioHalHidl.h
+++ b/services/radio/RadioHalHidl.h
@@ -29,7 +29,6 @@
namespace android {
-using android::hardware::Status;
using android::hardware::Return;
using android::hardware::broadcastradio::V1_0::Result;
using android::hardware::broadcastradio::V1_0::IBroadcastRadio;