Merge "Fix divide by zero exception with default sampleRate of 0" into nyc-dev
diff --git a/include/media/stagefright/ACodec.h b/include/media/stagefright/ACodec.h
index 2365323..bc11da2 100644
--- a/include/media/stagefright/ACodec.h
+++ b/include/media/stagefright/ACodec.h
@@ -25,6 +25,7 @@
#include <media/stagefright/foundation/AHierarchicalStateMachine.h>
#include <media/stagefright/CodecBase.h>
#include <media/stagefright/FrameRenderTracker.h>
+#include <media/stagefright/MediaDefs.h>
#include <media/stagefright/SkipCutBuffer.h>
#include <utils/NativeHandle.h>
#include <OMX_Audio.h>
@@ -36,6 +37,7 @@
struct ABuffer;
struct MemoryDealer;
struct DescribeColorFormat2Params;
+struct DataConverter;
struct ACodec : public AHierarchicalStateMachine, public CodecBase {
ACodec();
@@ -188,8 +190,11 @@
Status mStatus;
unsigned mDequeuedAt;
- sp<ABuffer> mData;
- sp<RefBase> mMemRef;
+ sp<ABuffer> mData; // the client's buffer; if not using data conversion, this is the
+ // codec buffer; otherwise, it is allocated separately
+ sp<RefBase> mMemRef; // and a reference to the IMemory, so it does not go away
+ sp<ABuffer> mCodecData; // the codec's buffer
+ sp<RefBase> mCodecRef; // and a reference to the IMemory
sp<GraphicBuffer> mGraphicBuffer;
sp<NativeHandle> mNativeHandle;
int mFenceFd;
@@ -248,6 +253,9 @@
sp<AMessage> mConfigFormat;
sp<AMessage> mInputFormat;
sp<AMessage> mOutputFormat;
+
+ // Initial output format + configuration params that is reused as the base for all subsequent
+ // format updates. This will equal to mOutputFormat until the first actual frame is received.
sp<AMessage> mBaseOutputFormat;
FrameRenderTracker mRenderTracker; // render information for buffers rendered by ACodec
@@ -280,6 +288,7 @@
bool mLegacyAdaptiveExperiment;
int32_t mMetadataBuffersToSubmit;
size_t mNumUndequeuedBuffers;
+ sp<DataConverter> mConverter[2];
int64_t mRepeatFrameDelayUs;
int64_t mMaxPtsGapUs;
@@ -441,7 +450,8 @@
bool encoder, int32_t numChannels, int32_t sampleRate, int32_t compressionLevel);
status_t setupRawAudioFormat(
- OMX_U32 portIndex, int32_t sampleRate, int32_t numChannels);
+ OMX_U32 portIndex, int32_t sampleRate, int32_t numChannels,
+ AudioEncoding encoding = kAudioEncodingPcm16bit);
status_t setPriority(int32_t priority);
status_t setOperatingRate(float rateFloat, bool isVideo);
diff --git a/include/ndk/NdkMediaCodec.h b/include/ndk/NdkMediaCodec.h
index c6035bd..fcb3a99 100644
--- a/include/ndk/NdkMediaCodec.h
+++ b/include/ndk/NdkMediaCodec.h
@@ -178,7 +178,9 @@
typedef enum {
AMEDIACODECRYPTOINFO_MODE_CLEAR = 0,
- AMEDIACODECRYPTOINFO_MODE_AES_CTR = 1
+ AMEDIACODECRYPTOINFO_MODE_AES_CTR = 1,
+ AMEDIACODECRYPTOINFO_MODE_AES_WV = 2,
+ AMEDIACODECRYPTOINFO_MODE_AES_CBC = 3
} cryptoinfo_mode_t;
typedef struct {
diff --git a/media/audioserver/Android.mk b/media/audioserver/Android.mk
index b4a2e0f..5ce1798 100644
--- a/media/audioserver/Android.mk
+++ b/media/audioserver/Android.mk
@@ -54,4 +54,6 @@
LOCAL_INIT_RC := audioserver.rc
+LOCAL_CFLAGS := -Werror -Wall
+
include $(BUILD_EXECUTABLE)
diff --git a/media/audioserver/main_audioserver.cpp b/media/audioserver/main_audioserver.cpp
index 698da1f..4a7a988 100644
--- a/media/audioserver/main_audioserver.cpp
+++ b/media/audioserver/main_audioserver.cpp
@@ -56,6 +56,7 @@
sp<ProcessState> proc(ProcessState::self());
MediaLogService::instantiate();
ProcessState::self()->startThreadPool();
+ IPCThreadState::self()->joinThreadPool();
for (;;) {
siginfo_t info;
int ret = waitid(P_PID, childPid, &info, WEXITED | WSTOPPED | WCONTINUED);
diff --git a/media/libcpustats/Android.mk b/media/libcpustats/Android.mk
index ee283a6..57fe527 100644
--- a/media/libcpustats/Android.mk
+++ b/media/libcpustats/Android.mk
@@ -8,6 +8,6 @@
LOCAL_MODULE := libcpustats
-LOCAL_CFLAGS := -std=gnu++11 -Werror
+LOCAL_CFLAGS := -std=gnu++11 -Werror -Wall
include $(BUILD_STATIC_LIBRARY)
diff --git a/media/libmedia/mediaplayer.cpp b/media/libmedia/mediaplayer.cpp
index 53b6df6..25c9fb1 100644
--- a/media/libmedia/mediaplayer.cpp
+++ b/media/libmedia/mediaplayer.cpp
@@ -207,7 +207,7 @@
ALOGV("invoke %zu", request.dataSize());
return mPlayer->invoke(request, reply);
}
- ALOGE("invoke failed: wrong state %X", mCurrentState);
+ ALOGE("invoke failed: wrong state %X, mPlayer(%p)", mCurrentState, mPlayer.get());
return INVALID_OPERATION;
}
@@ -252,7 +252,7 @@
mCurrentState = MEDIA_PLAYER_PREPARING;
return mPlayer->prepareAsync();
}
- ALOGE("prepareAsync called in state %d", mCurrentState);
+ ALOGE("prepareAsync called in state %d, mPlayer(%p)", mCurrentState, mPlayer.get());
return INVALID_OPERATION;
}
@@ -318,7 +318,7 @@
}
}
} else {
- ALOGE("start called in state %d", mCurrentState);
+ ALOGE("start called in state %d, mPlayer(%p)", mCurrentState, mPlayer.get());
ret = INVALID_OPERATION;
}
@@ -342,7 +342,7 @@
}
return ret;
}
- ALOGE("stop called in state %d", mCurrentState);
+ ALOGE("stop called in state %d, mPlayer(%p)", mCurrentState, mPlayer.get());
return INVALID_OPERATION;
}
@@ -361,7 +361,7 @@
}
return ret;
}
- ALOGE("pause called in state %d", mCurrentState);
+ ALOGE("pause called in state %d, mPlayer(%p)", mCurrentState, mPlayer.get());
return INVALID_OPERATION;
}
@@ -484,7 +484,8 @@
}
return ret;
}
- ALOGE("Attempt to call getDuration without a valid mediaplayer");
+ ALOGE("Attempt to call getDuration in wrong state: mPlayer=%p, mCurrentState=%u",
+ mPlayer.get(), mCurrentState);
return INVALID_OPERATION;
}
@@ -691,7 +692,7 @@
if (mPlayer == 0 ||
(mCurrentState & MEDIA_PLAYER_IDLE) ||
(mCurrentState == MEDIA_PLAYER_STATE_ERROR )) {
- ALOGE("attachAuxEffect called in state %d", mCurrentState);
+ ALOGE("attachAuxEffect called in state %d, mPlayer(%p)", mCurrentState, mPlayer.get());
return INVALID_OPERATION;
}
diff --git a/media/libmediaplayerservice/nuplayer/NuPlayerDriver.cpp b/media/libmediaplayerservice/nuplayer/NuPlayerDriver.cpp
index 332fef6..06bb53d 100644
--- a/media/libmediaplayerservice/nuplayer/NuPlayerDriver.cpp
+++ b/media/libmediaplayerservice/nuplayer/NuPlayerDriver.cpp
@@ -45,8 +45,7 @@
mPlayerFlags(0),
mAtEOS(false),
mLooping(false),
- mAutoLoop(false),
- mStartupSeekTimeUs(-1) {
+ mAutoLoop(false) {
ALOGV("NuPlayerDriver(%p)", this);
mLooper->setName("NuPlayerDriver Looper");
@@ -261,25 +260,11 @@
case STATE_PAUSED:
case STATE_STOPPED_AND_PREPARED:
- {
- if (mAtEOS && mStartupSeekTimeUs < 0) {
- mStartupSeekTimeUs = 0;
- mPositionUs = -1;
- }
-
- // fall through
- }
-
case STATE_PREPARED:
{
- mAtEOS = false;
mPlayer->start();
- if (mStartupSeekTimeUs >= 0) {
- mPlayer->seekToAsync(mStartupSeekTimeUs);
- mStartupSeekTimeUs = -1;
- }
- break;
+ // fall through
}
case STATE_RUNNING:
@@ -330,6 +315,7 @@
}
status_t NuPlayerDriver::pause() {
+ ALOGD("pause(%p)", this);
// The NuPlayerRenderer may get flushed if pause for long enough, e.g. the pause timeout tear
// down for audio offload mode. If that happens, the NuPlayerRenderer will no longer know the
// current position. So similar to seekTo, update |mPositionUs| to the pause position by calling
@@ -400,8 +386,6 @@
case STATE_PREPARED:
case STATE_STOPPED_AND_PREPARED:
case STATE_PAUSED:
- mStartupSeekTimeUs = seekTimeUs;
- // fall through.
case STATE_RUNNING:
{
mAtEOS = false;
@@ -502,7 +486,6 @@
mDurationUs = -1;
mPositionUs = -1;
- mStartupSeekTimeUs = -1;
mLooping = false;
return OK;
diff --git a/media/libmediaplayerservice/nuplayer/NuPlayerDriver.h b/media/libmediaplayerservice/nuplayer/NuPlayerDriver.h
index d009fd7..d5b4ba1 100644
--- a/media/libmediaplayerservice/nuplayer/NuPlayerDriver.h
+++ b/media/libmediaplayerservice/nuplayer/NuPlayerDriver.h
@@ -122,8 +122,6 @@
bool mLooping;
bool mAutoLoop;
- int64_t mStartupSeekTimeUs;
-
status_t prepare_l();
void notifyListener_l(int msg, int ext1 = 0, int ext2 = 0, const Parcel *in = NULL);
diff --git a/media/libmediaplayerservice/nuplayer/NuPlayerStreamListener.cpp b/media/libmediaplayerservice/nuplayer/NuPlayerStreamListener.cpp
index f53afbd..ee70306 100644
--- a/media/libmediaplayerservice/nuplayer/NuPlayerStreamListener.cpp
+++ b/media/libmediaplayerservice/nuplayer/NuPlayerStreamListener.cpp
@@ -144,8 +144,17 @@
copy = size;
}
+ if (entry->mIndex >= mBuffers.size()) {
+ return ERROR_MALFORMED;
+ }
+
+ sp<IMemory> mem = mBuffers.editItemAt(entry->mIndex);
+ if (mem == NULL || mem->size() < copy || mem->size() - copy < entry->mOffset) {
+ return ERROR_MALFORMED;
+ }
+
memcpy(data,
- (const uint8_t *)mBuffers.editItemAt(entry->mIndex)->pointer()
+ (const uint8_t *)mem->pointer()
+ entry->mOffset,
copy);
diff --git a/media/libnbaio/Android.mk b/media/libnbaio/Android.mk
index 16c5040..e2f416b 100644
--- a/media/libnbaio/Android.mk
+++ b/media/libnbaio/Android.mk
@@ -20,9 +20,6 @@
#LOCAL_C_INCLUDES += path/to/libsndfile/src
#LOCAL_STATIC_LIBRARIES += libsndfile
-# uncomment for systrace
-# LOCAL_CFLAGS += -DATRACE_TAG=ATRACE_TAG_AUDIO
-
LOCAL_MODULE := libnbaio
LOCAL_SHARED_LIBRARIES := \
@@ -34,4 +31,6 @@
LOCAL_C_INCLUDES := $(call include-path-for, audio-utils)
+LOCAL_CFLAGS := -Werror -Wall
+
include $(BUILD_SHARED_LIBRARY)
diff --git a/media/libstagefright/ACodec.cpp b/media/libstagefright/ACodec.cpp
index e8f75a4..87625d5 100644
--- a/media/libstagefright/ACodec.cpp
+++ b/media/libstagefright/ACodec.cpp
@@ -52,6 +52,7 @@
#include <OMX_AsString.h>
#include "include/avc_utils.h"
+#include "include/DataConverter.h"
#include "omx/OMXUtils.h"
namespace android {
@@ -114,6 +115,13 @@
DISALLOW_EVIL_CONSTRUCTORS(MessageList);
};
+static sp<DataConverter> getCopyConverter() {
+ static pthread_once_t once = PTHREAD_ONCE_INIT; // const-inited
+ static sp<DataConverter> sCopyConverter; // zero-inited
+ pthread_once(&once, [](){ sCopyConverter = new DataConverter(); });
+ return sCopyConverter;
+}
+
struct CodecObserver : public BnOMXObserver {
CodecObserver() {}
@@ -505,6 +513,7 @@
mOutputMetadataType(kMetadataBufferTypeInvalid),
mLegacyAdaptiveExperiment(false),
mMetadataBuffersToSubmit(0),
+ mNumUndequeuedBuffers(0),
mRepeatFrameDelayUs(-1ll),
mMaxPtsGapUs(-1ll),
mMaxFps(-1),
@@ -781,7 +790,7 @@
if (err == OK) {
MetadataBufferType type =
portIndex == kPortIndexOutput ? mOutputMetadataType : mInputMetadataType;
- int32_t bufSize = def.nBufferSize;
+ size_t bufSize = def.nBufferSize;
if (type == kMetadataBufferTypeGrallocSource) {
bufSize = sizeof(VideoGrallocMetadata);
} else if (type == kMetadataBufferTypeANWBuffer) {
@@ -792,33 +801,47 @@
// metadata size as we prefer to generate native source metadata, but component
// may require gralloc source. For camera source, allocate at least enough
// size for native metadata buffers.
- int32_t allottedSize = bufSize;
+ size_t allottedSize = bufSize;
if (portIndex == kPortIndexInput && type >= kMetadataBufferTypeGrallocSource) {
bufSize = max(sizeof(VideoGrallocMetadata), sizeof(VideoNativeMetadata));
} else if (portIndex == kPortIndexInput && type == kMetadataBufferTypeCameraSource) {
- bufSize = max(bufSize, (int32_t)sizeof(VideoNativeMetadata));
+ bufSize = max(bufSize, sizeof(VideoNativeMetadata));
+ }
+
+ size_t conversionBufferSize = 0;
+
+ sp<DataConverter> converter = mConverter[portIndex];
+ if (converter != NULL) {
+ // here we assume sane conversions of max 4:1, so result fits in int32
+ if (portIndex == kPortIndexInput) {
+ conversionBufferSize = converter->sourceSize(bufSize);
+ } else {
+ conversionBufferSize = converter->targetSize(bufSize);
+ }
}
size_t alignment = MemoryDealer::getAllocationAlignment();
- ALOGV("[%s] Allocating %u buffers of size %d/%d (from %u using %s) on %s port",
+ ALOGV("[%s] Allocating %u buffers of size %zu/%zu (from %u using %s) on %s port",
mComponentName.c_str(),
def.nBufferCountActual, bufSize, allottedSize, def.nBufferSize, asString(type),
portIndex == kPortIndexInput ? "input" : "output");
- if (bufSize == 0 || bufSize > kMaxCodecBufferSize) {
+ // verify buffer sizes to avoid overflow in align()
+ if (bufSize == 0 || max(bufSize, conversionBufferSize) > kMaxCodecBufferSize) {
ALOGE("b/22885421");
return NO_MEMORY;
}
// don't modify bufSize as OMX may not expect it to increase after negotiation
size_t alignedSize = align(bufSize, alignment);
- if (def.nBufferCountActual > SIZE_MAX / alignedSize) {
+ size_t alignedConvSize = align(conversionBufferSize, alignment);
+ if (def.nBufferCountActual > SIZE_MAX / (alignedSize + alignedConvSize)) {
ALOGE("b/22885421");
return NO_MEMORY;
}
- size_t totalSize = def.nBufferCountActual * alignedSize;
+ size_t totalSize = def.nBufferCountActual * (alignedSize + alignedConvSize);
mDealer[portIndex] = new MemoryDealer(totalSize, "ACodec");
for (OMX_U32 i = 0; i < def.nBufferCountActual && err == OK; ++i) {
@@ -857,6 +880,7 @@
// because Widevine source only receives these base addresses.
info.mData = new ABuffer(ptr != NULL ? ptr : (void *)native_handle, bufSize);
info.mNativeHandle = NativeHandle::create(native_handle, true /* ownsHandle */);
+ info.mCodecData = info.mData;
} else if (mQuirks & requiresAllocateBufferBit) {
err = mOMX->allocateBufferWithBackup(
mNode, portIndex, mem, &info.mBufferID, allottedSize);
@@ -865,11 +889,27 @@
}
if (mem != NULL) {
- info.mData = new ABuffer(mem->pointer(), bufSize);
+ info.mCodecData = new ABuffer(mem->pointer(), bufSize);
+ info.mCodecRef = mem;
+
if (type == kMetadataBufferTypeANWBuffer) {
((VideoNativeMetadata *)mem->pointer())->nFenceFd = -1;
}
- info.mMemRef = mem;
+
+ // if we require conversion, allocate conversion buffer for client use;
+ // otherwise, reuse codec buffer
+ if (mConverter[portIndex] != NULL) {
+ CHECK_GT(conversionBufferSize, (size_t)0);
+ mem = mDealer[portIndex]->allocate(conversionBufferSize);
+ if (mem == NULL|| mem->pointer() == NULL) {
+ return NO_MEMORY;
+ }
+ info.mData = new ABuffer(mem->pointer(), conversionBufferSize);
+ info.mMemRef = mem;
+ } else {
+ info.mData = info.mCodecData;
+ info.mMemRef = info.mCodecRef;
+ }
}
mBuffers[portIndex].push(info);
@@ -1062,6 +1102,7 @@
info.mIsReadFence = false;
info.mRenderInfo = NULL;
info.mData = new ABuffer(NULL /* data */, bufferSize /* capacity */);
+ info.mCodecData = info.mData;
info.mGraphicBuffer = graphicBuffer;
mBuffers[kPortIndexOutput].push(info);
@@ -1146,11 +1187,13 @@
((VideoNativeMetadata *)mem->pointer())->nFenceFd = -1;
}
info.mData = new ABuffer(mem->pointer(), mem->size());
+ info.mMemRef = mem;
+ info.mCodecData = info.mData;
+ info.mCodecRef = mem;
// we use useBuffer for metadata regardless of quirks
err = mOMX->useBuffer(
mNode, kPortIndexOutput, mem, &info.mBufferID, mem->size());
- info.mMemRef = mem;
mBuffers[kPortIndexOutput].push(info);
ALOGV("[%s] allocated meta buffer with ID %u (pointer = %p)",
@@ -1944,6 +1987,10 @@
}
}
+ AudioEncoding pcmEncoding = kAudioEncodingPcm16bit;
+ (void)msg->findInt32("pcm-encoding", (int32_t*)&pcmEncoding);
+ // invalid encodings will default to PCM-16bit in setupRawAudioFormat.
+
if (video) {
// determine need for software renderer
bool usingSwRenderer = false;
@@ -2148,7 +2195,7 @@
|| !msg->findInt32("sample-rate", &sampleRate)) {
err = INVALID_OPERATION;
} else {
- err = setupRawAudioFormat(kPortIndexInput, sampleRate, numChannels);
+ err = setupRawAudioFormat(kPortIndexInput, sampleRate, numChannels, pcmEncoding);
}
} else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AC3)) {
int32_t numChannels;
@@ -2210,6 +2257,7 @@
err = setOperatingRate(rateFloat, video);
}
+ // NOTE: both mBaseOutputFormat and mOutputFormat are outputFormat to signal first frame.
mBaseOutputFormat = outputFormat;
// trigger a kWhatOutputFormatChanged msg on first buffer
mLastOutputFormat.clear();
@@ -2222,6 +2270,25 @@
mOutputFormat = outputFormat;
}
}
+
+ // create data converters if needed
+ if (!video && err == OK) {
+ AudioEncoding codecPcmEncoding = kAudioEncodingPcm16bit;
+ if (encoder) {
+ (void)mInputFormat->findInt32("pcm-encoding", (int32_t*)&codecPcmEncoding);
+ mConverter[kPortIndexInput] = AudioConverter::Create(pcmEncoding, codecPcmEncoding);
+ if (mConverter[kPortIndexInput] != NULL) {
+ mInputFormat->setInt32("pcm-encoding", pcmEncoding);
+ }
+ } else {
+ (void)mOutputFormat->findInt32("pcm-encoding", (int32_t*)&codecPcmEncoding);
+ mConverter[kPortIndexOutput] = AudioConverter::Create(codecPcmEncoding, pcmEncoding);
+ if (mConverter[kPortIndexOutput] != NULL) {
+ mOutputFormat->setInt32("pcm-encoding", pcmEncoding);
+ }
+ }
+ }
+
return err;
}
@@ -2772,7 +2839,7 @@
}
status_t ACodec::setupRawAudioFormat(
- OMX_U32 portIndex, int32_t sampleRate, int32_t numChannels) {
+ OMX_U32 portIndex, int32_t sampleRate, int32_t numChannels, AudioEncoding encoding) {
OMX_PARAM_PORTDEFINITIONTYPE def;
InitOMXParams(&def);
def.nPortIndex = portIndex;
@@ -2805,9 +2872,23 @@
}
pcmParams.nChannels = numChannels;
- pcmParams.eNumData = OMX_NumericalDataSigned;
+ switch (encoding) {
+ case kAudioEncodingPcm8bit:
+ pcmParams.eNumData = OMX_NumericalDataUnsigned;
+ pcmParams.nBitPerSample = 8;
+ break;
+ case kAudioEncodingPcmFloat:
+ pcmParams.eNumData = OMX_NumericalDataFloat;
+ pcmParams.nBitPerSample = 32;
+ break;
+ case kAudioEncodingPcm16bit:
+ pcmParams.eNumData = OMX_NumericalDataSigned;
+ pcmParams.nBitPerSample = 16;
+ break;
+ default:
+ return BAD_VALUE;
+ }
pcmParams.bInterleaved = OMX_TRUE;
- pcmParams.nBitPerSample = 16;
pcmParams.nSamplingRate = sampleRate;
pcmParams.ePCMMode = OMX_AUDIO_PCMModeLinear;
@@ -2815,8 +2896,17 @@
return OMX_ErrorNone;
}
- return mOMX->setParameter(
+ err = mOMX->setParameter(
mNode, OMX_IndexParamAudioPcm, &pcmParams, sizeof(pcmParams));
+ // if we could not set up raw format to non-16-bit, try with 16-bit
+ // NOTE: we will also verify this via readback, in case codec ignores these fields
+ if (err != OK && encoding != kAudioEncodingPcm16bit) {
+ pcmParams.eNumData = OMX_NumericalDataSigned;
+ pcmParams.nBitPerSample = 16;
+ err = mOMX->setParameter(
+ mNode, OMX_IndexParamAudioPcm, &pcmParams, sizeof(pcmParams));
+ }
+ return err;
}
status_t ACodec::configureTunneledVideoPlayback(
@@ -3857,6 +3947,13 @@
h264type.eLevel = static_cast<OMX_VIDEO_AVCLEVELTYPE>(level);
}
+ // XXX
+ if (h264type.eProfile != OMX_VIDEO_AVCProfileBaseline) {
+ ALOGW("Use baseline profile instead of %d for AVC recording",
+ h264type.eProfile);
+ h264type.eProfile = OMX_VIDEO_AVCProfileBaseline;
+ }
+
if (h264type.eProfile == OMX_VIDEO_AVCProfileBaseline) {
h264type.nSliceHeaderSpacing = 0;
h264type.bUseHadamard = OMX_TRUE;
@@ -3874,23 +3971,6 @@
h264type.bDirect8x8Inference = OMX_FALSE;
h264type.bDirectSpatialTemporal = OMX_FALSE;
h264type.nCabacInitIdc = 0;
- } else if (h264type.eProfile == OMX_VIDEO_AVCProfileMain ||
- h264type.eProfile == OMX_VIDEO_AVCProfileHigh) {
- h264type.nSliceHeaderSpacing = 0;
- h264type.bUseHadamard = OMX_TRUE;
- h264type.nRefFrames = 2;
- h264type.nBFrames = 1;
- h264type.nPFrames = setPFramesSpacing(iFrameInterval, frameRate);
- h264type.nAllowedPictureTypes =
- OMX_VIDEO_PictureTypeI | OMX_VIDEO_PictureTypeP | OMX_VIDEO_PictureTypeB;
- h264type.nRefIdx10ActiveMinus1 = 0;
- h264type.nRefIdx11ActiveMinus1 = 0;
- h264type.bEntropyCodingCABAC = OMX_TRUE;
- h264type.bWeightedPPrediction = OMX_TRUE;
- h264type.bconstIpred = OMX_TRUE;
- h264type.bDirect8x8Inference = OMX_TRUE;
- h264type.bDirectSpatialTemporal = OMX_TRUE;
- h264type.nCabacInitIdc = 1;
}
if (h264type.nBFrames != 0) {
@@ -4653,22 +4733,33 @@
if (params.nChannels <= 0
|| (params.nChannels != 1 && !params.bInterleaved)
- || params.nBitPerSample != 16u
- || params.eNumData != OMX_NumericalDataSigned
|| params.ePCMMode != OMX_AUDIO_PCMModeLinear) {
- ALOGE("unsupported PCM port: %u channels%s, %u-bit, %s(%d), %s(%d) mode ",
+ ALOGE("unsupported PCM port: %u channels%s, %u-bit",
params.nChannels,
params.bInterleaved ? " interleaved" : "",
- params.nBitPerSample,
- asString(params.eNumData), params.eNumData,
- asString(params.ePCMMode), params.ePCMMode);
+ params.nBitPerSample);
return FAILED_TRANSACTION;
}
notify->setString("mime", MEDIA_MIMETYPE_AUDIO_RAW);
notify->setInt32("channel-count", params.nChannels);
notify->setInt32("sample-rate", params.nSamplingRate);
- notify->setInt32("pcm-encoding", kAudioEncodingPcm16bit);
+
+ AudioEncoding encoding = kAudioEncodingPcm16bit;
+ if (params.eNumData == OMX_NumericalDataUnsigned
+ && params.nBitPerSample == 8u) {
+ encoding = kAudioEncodingPcm8bit;
+ } else if (params.eNumData == OMX_NumericalDataFloat
+ && params.nBitPerSample == 32u) {
+ encoding = kAudioEncodingPcmFloat;
+ } else if (params.nBitPerSample != 16u
+ || params.eNumData != OMX_NumericalDataSigned) {
+ ALOGE("unsupported PCM port: %s(%d), %s(%d) mode ",
+ asString(params.eNumData), params.eNumData,
+ asString(params.ePCMMode), params.ePCMMode);
+ return FAILED_TRANSACTION;
+ }
+ notify->setInt32("pcm-encoding", encoding);
if (mChannelMaskPresent) {
notify->setInt32("channel-mask", mChannelMask);
@@ -4929,7 +5020,7 @@
}
void ACodec::onOutputFormatChanged() {
- // store new output format
+ // store new output format, at the same time mark that this is no longer the first frame
mOutputFormat = mBaseOutputFormat->dup();
if (getPortFormat(kPortIndexOutput, mOutputFormat) != OK) {
@@ -4937,6 +5028,18 @@
return;
}
+ if (!mIsVideo && !mIsEncoder) {
+ AudioEncoding pcmEncoding = kAudioEncodingPcm16bit;
+ (void)mConfigFormat->findInt32("pcm-encoding", (int32_t*)&pcmEncoding);
+ AudioEncoding codecPcmEncoding = kAudioEncodingPcm16bit;
+ (void)mOutputFormat->findInt32("pcm-encoding", (int32_t*)&pcmEncoding);
+
+ mConverter[kPortIndexOutput] = AudioConverter::Create(codecPcmEncoding, pcmEncoding);
+ if (mConverter[kPortIndexOutput] != NULL) {
+ mOutputFormat->setInt32("pcm-encoding", pcmEncoding);
+ }
+ }
+
if (mTunneled) {
sendFormatChange();
}
@@ -5464,20 +5567,21 @@
flags |= OMX_BUFFERFLAG_EOS;
}
- if (buffer != info->mData) {
+ if (buffer != info->mCodecData) {
ALOGV("[%s] Needs to copy input data for buffer %u. (%p != %p)",
mCodec->mComponentName.c_str(),
bufferID,
- buffer.get(), info->mData.get());
+ buffer.get(), info->mCodecData.get());
- if (buffer->size() > info->mData->capacity()) {
- ALOGE("data size (%zu) is greated than buffer capacity (%zu)",
- buffer->size(), // this is the data received
- info->mData->capacity()); // this is out buffer size
- mCodec->signalError(OMX_ErrorUndefined, FAILED_TRANSACTION);
+ sp<DataConverter> converter = mCodec->mConverter[kPortIndexInput];
+ if (converter == NULL) {
+ converter = getCopyConverter();
+ }
+ status_t err = converter->convert(buffer, info->mCodecData);
+ if (err != OK) {
+ mCodec->signalError(OMX_ErrorUndefined, err);
return;
}
- memcpy(info->mData->data(), buffer->data(), buffer->size());
}
if (flags & OMX_BUFFERFLAG_CODECCONFIG) {
@@ -5520,7 +5624,7 @@
mCodec->mNode,
bufferID,
0,
- buffer->size(),
+ info->mCodecData->size(),
flags,
timeUs,
info->mFenceFd);
@@ -5699,6 +5803,10 @@
new AMessage(kWhatOutputBufferDrained, mCodec);
if (mCodec->mOutputFormat != mCodec->mLastOutputFormat && rangeLength > 0) {
+ // pretend that output format has changed on the first frame (we used to do this)
+ if (mCodec->mBaseOutputFormat == mCodec->mOutputFormat) {
+ mCodec->onOutputFormatChanged();
+ }
mCodec->addKeyFormatChangesToRenderBufferNotification(reply);
mCodec->sendFormatChange();
}
@@ -5722,8 +5830,17 @@
info->mData->meta()->setPointer("handle", handle);
info->mData->meta()->setInt32("rangeOffset", rangeOffset);
info->mData->meta()->setInt32("rangeLength", rangeLength);
- } else {
+ } else if (info->mData == info->mCodecData) {
info->mData->setRange(rangeOffset, rangeLength);
+ } else {
+ info->mCodecData->setRange(rangeOffset, rangeLength);
+ // in this case we know that mConverter is not null
+ status_t err = mCodec->mConverter[kPortIndexOutput]->convert(
+ info->mCodecData, info->mData);
+ if (err != OK) {
+ mCodec->signalError(OMX_ErrorUndefined, makeNoSideEffectStatus(err));
+ return true;
+ }
}
#if 0
if (mCodec->mNativeWindow == NULL) {
@@ -5939,6 +6056,8 @@
mCodec->mFlags = 0;
mCodec->mInputMetadataType = kMetadataBufferTypeInvalid;
mCodec->mOutputMetadataType = kMetadataBufferTypeInvalid;
+ mCodec->mConverter[0].clear();
+ mCodec->mConverter[1].clear();
mCodec->mComponentName.clear();
}
diff --git a/media/libstagefright/Android.mk b/media/libstagefright/Android.mk
index 557971d..2445842 100644
--- a/media/libstagefright/Android.mk
+++ b/media/libstagefright/Android.mk
@@ -14,6 +14,7 @@
CameraSource.cpp \
CameraSourceTimeLapse.cpp \
CodecBase.cpp \
+ DataConverter.cpp \
DataSource.cpp \
DataURISource.cpp \
DRMExtractor.cpp \
diff --git a/media/libstagefright/DataConverter.cpp b/media/libstagefright/DataConverter.cpp
new file mode 100644
index 0000000..aea47f3
--- /dev/null
+++ b/media/libstagefright/DataConverter.cpp
@@ -0,0 +1,123 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+//#define LOG_NDEBUG 0
+#define LOG_TAG "DataConverter"
+
+#include "include/DataConverter.h"
+
+#include <audio_utils/primitives.h>
+
+#include <media/stagefright/foundation/ABuffer.h>
+#include <media/stagefright/foundation/ADebug.h>
+#include <media/stagefright/foundation/AUtils.h>
+
+namespace android {
+
+status_t DataConverter::convert(const sp<ABuffer> &source, sp<ABuffer> &target) {
+ CHECK(source->base() != target->base());
+ size_t size = targetSize(source->size());
+ status_t err = OK;
+ if (size > target->capacity()) {
+ ALOGE("data size (%zu) is greater than buffer capacity (%zu)",
+ size, // this is the data received/to be converted
+ target->capacity()); // this is out buffer size
+ err = FAILED_TRANSACTION;
+ } else {
+ err = safeConvert(source, target);
+ }
+ target->setRange(0, err == OK ? size : 0);
+ return err;
+}
+
+status_t DataConverter::safeConvert(const sp<ABuffer> &source, sp<ABuffer> &target) {
+ memcpy(target->base(), source->data(), source->size());
+ return OK;
+}
+
+size_t DataConverter::sourceSize(size_t targetSize) {
+ return targetSize;
+}
+
+size_t DataConverter::targetSize(size_t sourceSize) {
+ return sourceSize;
+}
+
+DataConverter::~DataConverter() { }
+
+
+size_t SampleConverterBase::sourceSize(size_t targetSize) {
+ size_t numSamples = targetSize / mTargetSampleSize;
+ if (numSamples > SIZE_MAX / mSourceSampleSize) {
+ ALOGW("limiting source size due to overflow (%zu*%zu/%zu)",
+ targetSize, mSourceSampleSize, mTargetSampleSize);
+ return SIZE_MAX;
+ }
+ return numSamples * mSourceSampleSize;
+}
+
+size_t SampleConverterBase::targetSize(size_t sourceSize) {
+ // we round up on conversion
+ size_t numSamples = divUp(sourceSize, (size_t)mSourceSampleSize);
+ if (numSamples > SIZE_MAX / mTargetSampleSize) {
+ ALOGW("limiting target size due to overflow (%zu*%zu/%zu)",
+ sourceSize, mTargetSampleSize, mSourceSampleSize);
+ return SIZE_MAX;
+ }
+ return numSamples * mTargetSampleSize;
+}
+
+
+static size_t getAudioSampleSize(AudioEncoding e) {
+ switch (e) {
+ case kAudioEncodingPcm16bit: return 2;
+ case kAudioEncodingPcm8bit: return 1;
+ case kAudioEncodingPcmFloat: return 4;
+ default: return 0;
+ }
+}
+
+
+// static
+AudioConverter* AudioConverter::Create(AudioEncoding source, AudioEncoding target) {
+ uint32_t sourceSampleSize = getAudioSampleSize(source);
+ uint32_t targetSampleSize = getAudioSampleSize(target);
+ if (sourceSampleSize && targetSampleSize && sourceSampleSize != targetSampleSize) {
+ return new AudioConverter(source, sourceSampleSize, target, targetSampleSize);
+ }
+ return NULL;
+}
+
+status_t AudioConverter::safeConvert(const sp<ABuffer> &src, sp<ABuffer> &tgt) {
+ if (mTo == kAudioEncodingPcm8bit && mFrom == kAudioEncodingPcm16bit) {
+ memcpy_to_u8_from_i16((uint8_t*)tgt->base(), (const int16_t*)src->data(), src->size() / 2);
+ } else if (mTo == kAudioEncodingPcm8bit && mFrom == kAudioEncodingPcmFloat) {
+ memcpy_to_u8_from_float((uint8_t*)tgt->base(), (const float*)src->data(), src->size() / 4);
+ } else if (mTo == kAudioEncodingPcm16bit && mFrom == kAudioEncodingPcm8bit) {
+ memcpy_to_i16_from_u8((int16_t*)tgt->base(), (const uint8_t*)src->data(), src->size());
+ } else if (mTo == kAudioEncodingPcm16bit && mFrom == kAudioEncodingPcmFloat) {
+ memcpy_to_i16_from_float((int16_t*)tgt->base(), (const float*)src->data(), src->size() / 4);
+ } else if (mTo == kAudioEncodingPcmFloat && mFrom == kAudioEncodingPcm8bit) {
+ memcpy_to_float_from_u8((float*)tgt->base(), (const uint8_t*)src->data(), src->size());
+ } else if (mTo == kAudioEncodingPcmFloat && mFrom == kAudioEncodingPcm16bit) {
+ memcpy_to_float_from_i16((float*)tgt->base(), (const int16_t*)src->data(), src->size() / 2);
+ } else {
+ return INVALID_OPERATION;
+ }
+ return OK;
+}
+
+} // namespace android
diff --git a/media/libstagefright/MPEG4Extractor.cpp b/media/libstagefright/MPEG4Extractor.cpp
index 322eab9..f5549e4 100644
--- a/media/libstagefright/MPEG4Extractor.cpp
+++ b/media/libstagefright/MPEG4Extractor.cpp
@@ -756,13 +756,22 @@
}
// Given a time in seconds since Jan 1 1904, produce a human-readable string.
-static void convertTimeToDate(int64_t time_1904, String8 *s) {
- time_t time_1970 = time_1904 - (((66 * 365 + 17) * 24) * 3600);
+static bool convertTimeToDate(int64_t time_1904, String8 *s) {
+ // delta between mpeg4 time and unix epoch time
+ static const int64_t delta = (((66 * 365 + 17) * 24) * 3600);
+ if (time_1904 < INT64_MIN + delta) {
+ return false;
+ }
+ time_t time_1970 = time_1904 - delta;
char tmp[32];
- strftime(tmp, sizeof(tmp), "%Y%m%dT%H%M%S.000Z", gmtime(&time_1970));
-
- s->setTo(tmp);
+ struct tm* tm = gmtime(&time_1970);
+ if (tm != NULL &&
+ strftime(tmp, sizeof(tmp), "%Y%m%dT%H%M%S.000Z", tm) > 0) {
+ s->setTo(tmp);
+ return true;
+ }
+ return false;
}
status_t MPEG4Extractor::parseChunk(off64_t *offset, int depth) {
@@ -1880,14 +1889,15 @@
}
duration = d32;
}
- if (duration != 0 && mHeaderTimescale != 0) {
+ if (duration != 0 && mHeaderTimescale != 0 && duration < UINT64_MAX / 1000000) {
mFileMetaData->setInt64(kKeyDuration, duration * 1000000 / mHeaderTimescale);
}
String8 s;
- convertTimeToDate(creationTime, &s);
+ if (convertTimeToDate(creationTime, &s)) {
+ mFileMetaData->setCString(kKeyDate, s.string());
+ }
- mFileMetaData->setCString(kKeyDate, s.string());
break;
}
diff --git a/media/libstagefright/SampleTable.cpp b/media/libstagefright/SampleTable.cpp
index f5d9ec7..495e187 100644
--- a/media/libstagefright/SampleTable.cpp
+++ b/media/libstagefright/SampleTable.cpp
@@ -298,6 +298,7 @@
mDefaultSampleSize = U32_AT(&header[4]);
mNumSampleSizes = U32_AT(&header[8]);
if (mNumSampleSizes > (UINT32_MAX - 12) / 16) {
+ ALOGE("b/23247055, mNumSampleSizes(%u)", mNumSampleSizes);
return ERROR_MALFORMED;
}
@@ -532,6 +533,8 @@
Mutex::Autolock autoLock(mLock);
if (mSampleTimeEntries != NULL || mNumSampleSizes == 0) {
+ ALOGE("b/23247055, mNumSampleSizes(%u), mSampleTimeEntries(%p)",
+ mNumSampleSizes, mSampleTimeEntries);
return;
}
diff --git a/media/libstagefright/Utils.cpp b/media/libstagefright/Utils.cpp
index a034368..dc4acda 100644
--- a/media/libstagefright/Utils.cpp
+++ b/media/libstagefright/Utils.cpp
@@ -232,7 +232,7 @@
int32_t isADTS;
if (meta->findInt32(kKeyIsADTS, &isADTS)) {
- msg->setInt32("is-adts", true);
+ msg->setInt32("is-adts", isADTS);
}
int32_t aacProfile = -1;
diff --git a/media/libstagefright/VideoFrameScheduler.cpp b/media/libstagefright/VideoFrameScheduler.cpp
index 5564926..03226c7 100644
--- a/media/libstagefright/VideoFrameScheduler.cpp
+++ b/media/libstagefright/VideoFrameScheduler.cpp
@@ -156,12 +156,12 @@
lastTime = time;
}
- int64_t div = numSamplesToUse * sumXX - sumX * sumX;
+ int64_t div = (int64_t)numSamplesToUse * sumXX - sumX * sumX;
if (div == 0) {
return false;
}
- int64_t a_nom = numSamplesToUse * sumXY - sumX * sumY;
+ int64_t a_nom = (int64_t)numSamplesToUse * sumXY - sumX * sumY;
int64_t b_nom = sumXX * sumY - sumX * sumXY;
*a = divRound(a_nom, div);
*b = divRound(b_nom, div);
@@ -437,10 +437,10 @@
(renderTime + mTimeCorrection + videoPeriod * i - mVsyncTime) % mVsyncPeriod;
edgeRemainder += (videoPeriod * i) % mVsyncPeriod;
}
- mTimeCorrection += mVsyncPeriod / 2 - offset / N;
+ mTimeCorrection += mVsyncPeriod / 2 - offset / (nsecs_t)N;
renderTime += mTimeCorrection;
nsecs_t correctionLimit = mVsyncPeriod * 3 / 5;
- edgeRemainder = abs(edgeRemainder / N - mVsyncPeriod / 2);
+ edgeRemainder = abs(edgeRemainder / (nsecs_t)N - mVsyncPeriod / 2);
if (edgeRemainder <= mVsyncPeriod / 3) {
correctionLimit /= 2;
}
diff --git a/media/libstagefright/codecs/amrnb/dec/SoftAMR.cpp b/media/libstagefright/codecs/amrnb/dec/SoftAMR.cpp
index ac19ee3..be22098 100644
--- a/media/libstagefright/codecs/amrnb/dec/SoftAMR.cpp
+++ b/media/libstagefright/codecs/amrnb/dec/SoftAMR.cpp
@@ -306,6 +306,13 @@
BufferInfo *inInfo = *inQueue.begin();
OMX_BUFFERHEADERTYPE *inHeader = inInfo->mHeader;
+ if (inHeader->nFilledLen == 0) {
+ inInfo->mOwnedByUs = false;
+ inQueue.erase(inQueue.begin());
+ notifyEmptyBufferDone(inHeader);
+ continue;
+ }
+
BufferInfo *outInfo = *outQueue.begin();
OMX_BUFFERHEADERTYPE *outHeader = outInfo->mHeader;
@@ -332,6 +339,26 @@
int32_t numBytesRead;
if (mMode == MODE_NARROW) {
+ if (outHeader->nAllocLen < kNumSamplesPerFrameNB * sizeof(int16_t)) {
+ ALOGE("b/27662364: NB expected output buffer %zu bytes vs %u",
+ kNumSamplesPerFrameNB * sizeof(int16_t), outHeader->nAllocLen);
+ android_errorWriteLog(0x534e4554, "27662364");
+ notify(OMX_EventError, OMX_ErrorOverflow, 0, NULL);
+ mSignalledError = true;
+ return;
+ }
+
+ int16 mode = ((inputPtr[0] >> 3) & 0x0f);
+ // for WMF since MIME_IETF is used when calling AMRDecode.
+ size_t frameSize = WmfDecBytesPerFrame[mode] + 1;
+
+ if (inHeader->nFilledLen < frameSize) {
+ ALOGE("b/27662364: expected %zu bytes vs %u", frameSize, inHeader->nFilledLen);
+ notify(OMX_EventError, OMX_ErrorStreamCorrupt, 0, NULL);
+ mSignalledError = true;
+ return;
+ }
+
numBytesRead =
AMRDecode(mState,
(Frame_Type_3GPP)((inputPtr[0] >> 3) & 0x0f),
@@ -359,6 +386,15 @@
return;
}
} else {
+ if (outHeader->nAllocLen < kNumSamplesPerFrameWB * sizeof(int16_t)) {
+ ALOGE("b/27662364: WB expected output buffer %zu bytes vs %u",
+ kNumSamplesPerFrameWB * sizeof(int16_t), outHeader->nAllocLen);
+ android_errorWriteLog(0x534e4554, "27662364");
+ notify(OMX_EventError, OMX_ErrorOverflow, 0, NULL);
+ mSignalledError = true;
+ return;
+ }
+
int16 mode = ((inputPtr[0] >> 3) & 0x0f);
if (mode >= 10 && mode <= 13) {
@@ -372,7 +408,12 @@
}
size_t frameSize = getFrameSize(mode);
- CHECK_GE(inHeader->nFilledLen, frameSize);
+ if (inHeader->nFilledLen < frameSize) {
+ ALOGE("b/27662364: expected %zu bytes vs %u", frameSize, inHeader->nFilledLen);
+ notify(OMX_EventError, OMX_ErrorStreamCorrupt, 0, NULL);
+ mSignalledError = true;
+ return;
+ }
int16_t *outPtr = (int16_t *)outHeader->pBuffer;
diff --git a/media/libstagefright/codecs/amrnb/dec/src/amrdecode.h b/media/libstagefright/codecs/amrnb/dec/src/amrdecode.h
index 0988e17f..f224fb6 100644
--- a/media/libstagefright/codecs/amrnb/dec/src/amrdecode.h
+++ b/media/libstagefright/codecs/amrnb/dec/src/amrdecode.h
@@ -104,7 +104,6 @@
; INCLUDES
----------------------------------------------------------------------------*/
#include "typedef.h"
-#include "mode.h"
#include "frame_type_3gpp.h"
/*--------------------------------------------------------------------------*/
diff --git a/media/libstagefright/codecs/amrnb/dec/src/gsmamr_dec.h b/media/libstagefright/codecs/amrnb/dec/src/gsmamr_dec.h
index 8f54ee8..dc64d67 100644
--- a/media/libstagefright/codecs/amrnb/dec/src/gsmamr_dec.h
+++ b/media/libstagefright/codecs/amrnb/dec/src/gsmamr_dec.h
@@ -87,6 +87,7 @@
#include "gsm_amr_typedefs.h"
#include "frame_type_3gpp.h"
+#include "amrdecode.h"
/*--------------------------------------------------------------------------*/
#ifdef __cplusplus
@@ -136,19 +137,6 @@
Word8 *id);
/*
- * AMRDecode steps into the part of the library that decodes the raw data
- * speech bits for the decoding process. It returns the address offset of
- * the next frame to be decoded.
- */
- Word16 AMRDecode(
- void *state_data,
- enum Frame_Type_3GPP frame_type,
- UWord8 *speech_bits_ptr,
- Word16 *raw_pcm_buffer,
- Word16 input_format
- );
-
- /*
* This function resets the state memory used by the GSM AMR decoder. This
* function returns zero. It will return negative one if there is an error.
*/
diff --git a/media/libstagefright/codecs/on2/enc/SoftVPXEncoder.cpp b/media/libstagefright/codecs/on2/enc/SoftVPXEncoder.cpp
index a354690..5edfbb5 100644
--- a/media/libstagefright/codecs/on2/enc/SoftVPXEncoder.cpp
+++ b/media/libstagefright/codecs/on2/enc/SoftVPXEncoder.cpp
@@ -734,9 +734,10 @@
const uint8_t *source =
inputBufferHeader->pBuffer + inputBufferHeader->nOffset;
+ size_t frameSize = mWidth * mHeight * 3 / 2;
if (mInputDataIsMeta) {
source = extractGraphicBuffer(
- mConversionBuffer, mWidth * mHeight * 3 / 2,
+ mConversionBuffer, frameSize,
source, inputBufferHeader->nFilledLen,
mWidth, mHeight);
if (source == NULL) {
@@ -744,11 +745,21 @@
notify(OMX_EventError, OMX_ErrorUndefined, 0, 0);
return;
}
- } else if (mColorFormat == OMX_COLOR_FormatYUV420SemiPlanar) {
- ConvertYUV420SemiPlanarToYUV420Planar(
- source, mConversionBuffer, mWidth, mHeight);
+ } else {
+ if (inputBufferHeader->nFilledLen < frameSize) {
+ android_errorWriteLog(0x534e4554, "27569635");
+ notify(OMX_EventError, OMX_ErrorUndefined, 0, 0);
+ return;
+ } else if (inputBufferHeader->nFilledLen > frameSize) {
+ ALOGW("Input buffer contains too many pixels");
+ }
- source = mConversionBuffer;
+ if (mColorFormat == OMX_COLOR_FormatYUV420SemiPlanar) {
+ ConvertYUV420SemiPlanarToYUV420Planar(
+ source, mConversionBuffer, mWidth, mHeight);
+
+ source = mConversionBuffer;
+ }
}
vpx_image_t raw_frame;
vpx_img_wrap(&raw_frame, VPX_IMG_FMT_I420, mWidth, mHeight,
@@ -810,9 +821,14 @@
outputBufferHeader->nTimeStamp = encoded_packet->data.frame.pts;
outputBufferHeader->nFlags = 0;
if (encoded_packet->data.frame.flags & VPX_FRAME_IS_KEY)
- outputBufferHeader->nFlags |= OMX_BUFFERFLAG_SYNCFRAME;
+ outputBufferHeader->nFlags |= OMX_BUFFERFLAG_SYNCFRAME;
outputBufferHeader->nOffset = 0;
outputBufferHeader->nFilledLen = encoded_packet->data.frame.sz;
+ if (outputBufferHeader->nFilledLen > outputBufferHeader->nAllocLen) {
+ android_errorWriteLog(0x534e4554, "27569635");
+ notify(OMX_EventError, OMX_ErrorUndefined, 0, 0);
+ return;
+ }
memcpy(outputBufferHeader->pBuffer,
encoded_packet->data.frame.buf,
encoded_packet->data.frame.sz);
diff --git a/media/libstagefright/codecs/raw/SoftRaw.cpp b/media/libstagefright/codecs/raw/SoftRaw.cpp
index c4e0659..acb2b37 100644
--- a/media/libstagefright/codecs/raw/SoftRaw.cpp
+++ b/media/libstagefright/codecs/raw/SoftRaw.cpp
@@ -42,7 +42,9 @@
: SimpleSoftOMXComponent(name, callbacks, appData, component),
mSignalledError(false),
mChannelCount(2),
- mSampleRate(44100) {
+ mSampleRate(44100),
+ mNumericalData(OMX_NumericalDataSigned),
+ mBitsPerSample(16) {
initPorts();
CHECK_EQ(initDecoder(), (status_t)OK);
}
@@ -111,10 +113,10 @@
return OMX_ErrorUndefined;
}
- pcmParams->eNumData = OMX_NumericalDataSigned;
+ pcmParams->eNumData = (OMX_NUMERICALDATATYPE)mNumericalData;
pcmParams->eEndian = OMX_EndianBig;
pcmParams->bInterleaved = OMX_TRUE;
- pcmParams->nBitPerSample = 16;
+ pcmParams->nBitPerSample = mBitsPerSample;
pcmParams->ePCMMode = OMX_AUDIO_PCMModeLinear;
pcmParams->eChannelMapping[0] = OMX_AUDIO_ChannelLF;
pcmParams->eChannelMapping[1] = OMX_AUDIO_ChannelRF;
@@ -166,6 +168,8 @@
mChannelCount = pcmParams->nChannels;
mSampleRate = pcmParams->nSamplingRate;
+ mNumericalData = pcmParams->eNumData;
+ mBitsPerSample = pcmParams->nBitPerSample;
return OMX_ErrorNone;
}
diff --git a/media/libstagefright/codecs/raw/SoftRaw.h b/media/libstagefright/codecs/raw/SoftRaw.h
index 015c4a3..80906b4 100644
--- a/media/libstagefright/codecs/raw/SoftRaw.h
+++ b/media/libstagefright/codecs/raw/SoftRaw.h
@@ -50,6 +50,8 @@
int32_t mChannelCount;
int32_t mSampleRate;
+ int32_t mNumericalData;
+ int32_t mBitsPerSample;
void initPorts();
status_t initDecoder();
diff --git a/media/libstagefright/include/DataConverter.h b/media/libstagefright/include/DataConverter.h
new file mode 100644
index 0000000..8d67921
--- /dev/null
+++ b/media/libstagefright/include/DataConverter.h
@@ -0,0 +1,79 @@
+/*
+ * Copyright (C) 2016 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 STAGEFRIGHT_DATACONVERTER_H_
+#define STAGEFRIGHT_DATACONVERTER_H_
+
+#include <utils/Errors.h>
+#include <utils/RefBase.h>
+
+#include <media/stagefright/MediaDefs.h>
+
+namespace android {
+
+struct ABuffer;
+
+// DataConverter base class, defaults to memcpy
+struct DataConverter : public RefBase {
+ virtual size_t sourceSize(size_t targetSize); // will clamp to SIZE_MAX
+ virtual size_t targetSize(size_t sourceSize); // will clamp to SIZE_MAX
+
+ status_t convert(const sp<ABuffer> &source, sp<ABuffer> &target);
+ virtual ~DataConverter();
+
+protected:
+ virtual status_t safeConvert(const sp<ABuffer> &source, sp<ABuffer> &target);
+};
+
+// SampleConverterBase uses a ratio to calculate the source and target sizes
+// based on source and target sample sizes.
+struct SampleConverterBase : public DataConverter {
+ virtual size_t sourceSize(size_t targetSize);
+ virtual size_t targetSize(size_t sourceSize);
+
+protected:
+ virtual status_t safeConvert(const sp<ABuffer> &source, sp<ABuffer> &target) = 0;
+
+ // sourceSize = sourceSampleSize / targetSampleSize * targetSize
+ SampleConverterBase(uint32_t sourceSampleSize, uint32_t targetSampleSize)
+ : mSourceSampleSize(sourceSampleSize),
+ mTargetSampleSize(targetSampleSize) { }
+ size_t mSourceSampleSize;
+ size_t mTargetSampleSize;
+};
+
+// AudioConverter converts between audio PCM formats
+struct AudioConverter : public SampleConverterBase {
+ // return nullptr if conversion is not needed or not supported
+ static AudioConverter *Create(AudioEncoding source, AudioEncoding target);
+
+protected:
+ virtual status_t safeConvert(const sp<ABuffer> &src, sp<ABuffer> &tgt);
+
+private:
+ AudioConverter(
+ AudioEncoding source, size_t sourceSample,
+ AudioEncoding target, size_t targetSample)
+ : SampleConverterBase(sourceSample, targetSample),
+ mFrom(source),
+ mTo(target) { }
+ AudioEncoding mFrom;
+ AudioEncoding mTo;
+};
+
+} // namespace android
+
+#endif
diff --git a/media/libstagefright/include/MPEG2TSExtractor.h b/media/libstagefright/include/MPEG2TSExtractor.h
index e5c24ca..34b9606 100644
--- a/media/libstagefright/include/MPEG2TSExtractor.h
+++ b/media/libstagefright/include/MPEG2TSExtractor.h
@@ -25,6 +25,8 @@
#include <utils/KeyedVector.h>
#include <utils/Vector.h>
+#include "mpeg2ts/ATSParser.h"
+
namespace android {
struct AMessage;
@@ -55,6 +57,10 @@
sp<ATSParser> mParser;
+ // Used to remember SyncEvent occurred in feedMore() when called from init(),
+ // because init() needs to update |mSourceImpls| before adding SyncPoint.
+ ATSParser::SyncEvent mLastSyncEvent;
+
Vector<sp<AnotherPacketSource> > mSourceImpls;
Vector<KeyedVector<int64_t, off64_t> > mSyncPoints;
@@ -65,7 +71,14 @@
off64_t mOffset;
void init();
- status_t feedMore();
+ // Try to feed more data from source to parser.
+ // |isInit| means this function is called inside init(). This is a signal to
+ // save SyncEvent so that init() can add SyncPoint after it updates |mSourceImpls|.
+ // This function returns OK if expected amount of data is fed from DataSource to
+ // parser and is successfully parsed. Otherwise, various error codes could be
+ // returned, e.g., ERROR_END_OF_STREAM, or no data availalbe from DataSource, or
+ // the data has syntax error during parsing, etc.
+ status_t feedMore(bool isInit = false);
status_t seek(int64_t seekTimeUs,
const MediaSource::ReadOptions::SeekMode& seekMode);
status_t queueDiscontinuityForSeek(int64_t actualSeekTimeUs);
@@ -73,6 +86,9 @@
status_t feedUntilBufferAvailable(const sp<AnotherPacketSource> &impl);
+ // Add a SynPoint derived from |event|.
+ void addSyncPoint_l(const ATSParser::SyncEvent &event);
+
DISALLOW_EVIL_CONSTRUCTORS(MPEG2TSExtractor);
};
diff --git a/media/libstagefright/mpeg2ts/ATSParser.cpp b/media/libstagefright/mpeg2ts/ATSParser.cpp
index 2790a0e..fb43a38 100644
--- a/media/libstagefright/mpeg2ts/ATSParser.cpp
+++ b/media/libstagefright/mpeg2ts/ATSParser.cpp
@@ -122,7 +122,7 @@
void setPID(unsigned pid) { mElementaryPID = pid; }
// Parse the payload and set event when PES with a sync frame is detected.
- // This method knows when a PES starts; so record mPesStartOffset in that
+ // This method knows when a PES starts; so record mPesStartOffsets in that
// case.
status_t parse(
unsigned continuity_counter,
@@ -157,7 +157,7 @@
bool mEOSReached;
uint64_t mPrevPTS;
- off64_t mPesStartOffset;
+ List<off64_t> mPesStartOffsets;
ElementaryStreamQueue *mQueue;
@@ -205,16 +205,19 @@
};
ATSParser::SyncEvent::SyncEvent(off64_t offset)
- : mInit(false), mOffset(offset), mTimeUs(0) {}
+ : mHasReturnedData(false), mOffset(offset), mTimeUs(0) {}
void ATSParser::SyncEvent::init(off64_t offset, const sp<MediaSource> &source,
int64_t timeUs) {
- mInit = true;
+ mHasReturnedData = true;
mOffset = offset;
mMediaSource = source;
mTimeUs = timeUs;
}
+void ATSParser::SyncEvent::reset() {
+ mHasReturnedData = false;
+}
////////////////////////////////////////////////////////////////////////////////
ATSParser::Program::Program(
@@ -661,6 +664,7 @@
ALOGI("discontinuity on stream pid 0x%04x", mElementaryPID);
mPayloadStarted = false;
+ mPesStartOffsets.clear();
mBuffer->setRange(0, 0);
mExpectedContinuityCounter = -1;
@@ -697,7 +701,7 @@
}
mPayloadStarted = true;
- mPesStartOffset = offset;
+ mPesStartOffsets.push_back(offset);
}
if (!mPayloadStarted) {
@@ -772,6 +776,7 @@
}
mPayloadStarted = false;
+ mPesStartOffsets.clear();
mEOSReached = false;
mBuffer->setRange(0, 0);
@@ -1105,7 +1110,9 @@
int64_t timeUs;
if (accessUnit->meta()->findInt64("timeUs", &timeUs)) {
found = true;
- event->init(mPesStartOffset, mSource, timeUs);
+ off64_t pesStartOffset = *mPesStartOffsets.begin();
+ event->init(pesStartOffset, mSource, timeUs);
+ mPesStartOffsets.erase(mPesStartOffsets.begin());
}
}
}
diff --git a/media/libstagefright/mpeg2ts/ATSParser.h b/media/libstagefright/mpeg2ts/ATSParser.h
index 430a8d5..fb03cd6 100644
--- a/media/libstagefright/mpeg2ts/ATSParser.h
+++ b/media/libstagefright/mpeg2ts/ATSParser.h
@@ -69,16 +69,18 @@
void init(off64_t offset, const sp<MediaSource> &source,
int64_t timeUs);
- bool isInit() { return mInit; }
- off64_t getOffset() { return mOffset; }
- const sp<MediaSource> &getMediaSource() { return mMediaSource; }
- int64_t getTimeUs() { return mTimeUs; }
+ bool hasReturnedData() const { return mHasReturnedData; }
+ void reset();
+ off64_t getOffset() const { return mOffset; }
+ const sp<MediaSource> &getMediaSource() const { return mMediaSource; }
+ int64_t getTimeUs() const { return mTimeUs; }
private:
- bool mInit;
+ bool mHasReturnedData;
/*
- * mInit == false: the current offset
- * mInit == true: the start offset of sync payload
+ * mHasReturnedData == false: the current offset (or undefined if the returned data
+ has been invalidated via reset())
+ * mHasReturnedData == true: the start offset of sync payload
*/
off64_t mOffset;
/* The media source object for this event. */
diff --git a/media/libstagefright/mpeg2ts/MPEG2TSExtractor.cpp b/media/libstagefright/mpeg2ts/MPEG2TSExtractor.cpp
index 0b456c3..fb5e079 100644
--- a/media/libstagefright/mpeg2ts/MPEG2TSExtractor.cpp
+++ b/media/libstagefright/mpeg2ts/MPEG2TSExtractor.cpp
@@ -112,6 +112,7 @@
MPEG2TSExtractor::MPEG2TSExtractor(const sp<DataSource> &source)
: mDataSource(source),
mParser(new ATSParser),
+ mLastSyncEvent(0),
mOffset(0) {
init();
}
@@ -149,8 +150,10 @@
bool haveVideo = false;
int64_t startTime = ALooper::GetNowUs();
- while (feedMore() == OK) {
+ while (feedMore(true /* isInit */) == OK) {
if (haveAudio && haveVideo) {
+ addSyncPoint_l(mLastSyncEvent);
+ mLastSyncEvent.reset();
break;
}
if (!haveVideo) {
@@ -181,6 +184,9 @@
}
}
+ addSyncPoint_l(mLastSyncEvent);
+ mLastSyncEvent.reset();
+
// Wait only for 2 seconds to detect audio/video streams.
if (ALooper::GetNowUs() - startTime > 2000000ll) {
break;
@@ -245,7 +251,7 @@
haveAudio, haveVideo, ALooper::GetNowUs() - startTime);
}
-status_t MPEG2TSExtractor::feedMore() {
+status_t MPEG2TSExtractor::feedMore(bool isInit) {
Mutex::Autolock autoLock(mLock);
uint8_t packet[kTSPacketSize];
@@ -261,29 +267,41 @@
ATSParser::SyncEvent event(mOffset);
mOffset += n;
status_t err = mParser->feedTSPacket(packet, kTSPacketSize, &event);
- if (event.isInit()) {
- for (size_t i = 0; i < mSourceImpls.size(); ++i) {
- if (mSourceImpls[i].get() == event.getMediaSource().get()) {
- KeyedVector<int64_t, off64_t> *syncPoints = &mSyncPoints.editItemAt(i);
- syncPoints->add(event.getTimeUs(), event.getOffset());
- // We're keeping the size of the sync points at most 5mb per a track.
- size_t size = syncPoints->size();
- if (size >= 327680) {
- int64_t firstTimeUs = syncPoints->keyAt(0);
- int64_t lastTimeUs = syncPoints->keyAt(size - 1);
- if (event.getTimeUs() - firstTimeUs > lastTimeUs - event.getTimeUs()) {
- syncPoints->removeItemsAt(0, 4096);
- } else {
- syncPoints->removeItemsAt(size - 4096, 4096);
- }
- }
- break;
- }
+ if (event.hasReturnedData()) {
+ if (isInit) {
+ mLastSyncEvent = event;
+ } else {
+ addSyncPoint_l(event);
}
}
return err;
}
+void MPEG2TSExtractor::addSyncPoint_l(const ATSParser::SyncEvent &event) {
+ if (!event.hasReturnedData()) {
+ return;
+ }
+
+ for (size_t i = 0; i < mSourceImpls.size(); ++i) {
+ if (mSourceImpls[i].get() == event.getMediaSource().get()) {
+ KeyedVector<int64_t, off64_t> *syncPoints = &mSyncPoints.editItemAt(i);
+ syncPoints->add(event.getTimeUs(), event.getOffset());
+ // We're keeping the size of the sync points at most 5mb per a track.
+ size_t size = syncPoints->size();
+ if (size >= 327680) {
+ int64_t firstTimeUs = syncPoints->keyAt(0);
+ int64_t lastTimeUs = syncPoints->keyAt(size - 1);
+ if (event.getTimeUs() - firstTimeUs > lastTimeUs - event.getTimeUs()) {
+ syncPoints->removeItemsAt(0, 4096);
+ } else {
+ syncPoints->removeItemsAt(size - 4096, 4096);
+ }
+ }
+ break;
+ }
+ }
+}
+
uint32_t MPEG2TSExtractor::flags() const {
return CAN_PAUSE | CAN_SEEK_BACKWARD | CAN_SEEK_FORWARD;
}
diff --git a/media/mtp/MtpDevice.cpp b/media/mtp/MtpDevice.cpp
index a398aca..d2a93a7 100644
--- a/media/mtp/MtpDevice.cpp
+++ b/media/mtp/MtpDevice.cpp
@@ -679,11 +679,6 @@
return false;
}
- if (mData.getContainerType() == MTP_CONTAINER_TYPE_RESPONSE) {
- mResponse.copyFrom(mData);
- return mResponse.getResponseCode() == MTP_RESPONSE_OK ? 0 : -1;
- }
-
// If object size 0 byte, the remote device can reply response packet
// without sending any data packets.
if (mData.getContainerType() == MTP_CONTAINER_TYPE_RESPONSE) {
diff --git a/services/audioflinger/Android.mk b/services/audioflinger/Android.mk
index 0112e56..6700f6e 100644
--- a/services/audioflinger/Android.mk
+++ b/services/audioflinger/Android.mk
@@ -80,6 +80,8 @@
LOCAL_CFLAGS += -fvisibility=hidden
+LOCAL_CFLAGS += -Werror -Wall
+
include $(BUILD_SHARED_LIBRARY)
#
@@ -108,6 +110,8 @@
LOCAL_MODULE_TAGS := optional
+LOCAL_CFLAGS := -Werror -Wall
+
include $(BUILD_EXECUTABLE)
include $(CLEAR_VARS)
@@ -128,6 +132,8 @@
LOCAL_MODULE := libaudioresampler
+LOCAL_CFLAGS := -Werror -Wall
+
# uncomment to disable NEON on architectures that actually do support NEON, for benchmarking
#LOCAL_CFLAGS += -DUSE_NEON=false
diff --git a/services/audioflinger/audio-resampler/Android.mk b/services/audioflinger/audio-resampler/Android.mk
index ba37b19..bb2807c 100644
--- a/services/audioflinger/audio-resampler/Android.mk
+++ b/services/audioflinger/audio-resampler/Android.mk
@@ -11,4 +11,6 @@
LOCAL_SHARED_LIBRARIES := libutils liblog
+LOCAL_CFLAGS += -Werror -Wall
+
include $(BUILD_SHARED_LIBRARY)
diff --git a/services/audioflinger/tests/Android.mk b/services/audioflinger/tests/Android.mk
index 6182de0..3505e0f 100644
--- a/services/audioflinger/tests/Android.mk
+++ b/services/audioflinger/tests/Android.mk
@@ -23,6 +23,8 @@
LOCAL_MODULE := resampler_tests
LOCAL_MODULE_TAGS := tests
+LOCAL_CFLAGS := -Werror -Wall
+
include $(BUILD_NATIVE_TEST)
#
@@ -61,4 +63,6 @@
LOCAL_CXX_STL := libc++
+LOCAL_CFLAGS := -Werror -Wall
+
include $(BUILD_EXECUTABLE)
diff --git a/services/audiopolicy/enginedefault/src/Engine.cpp b/services/audiopolicy/enginedefault/src/Engine.cpp
index f8ba3f2..f2224fd 100755
--- a/services/audiopolicy/enginedefault/src/Engine.cpp
+++ b/services/audiopolicy/enginedefault/src/Engine.cpp
@@ -231,20 +231,20 @@
audio_devices_t Engine::getDeviceForStrategy(routing_strategy strategy) const
{
- const DeviceVector &availableOutputDevices = mApmObserver->getAvailableOutputDevices();
- const DeviceVector &availableInputDevices = mApmObserver->getAvailableInputDevices();
+ DeviceVector availableOutputDevices = mApmObserver->getAvailableOutputDevices();
+ DeviceVector availableInputDevices = mApmObserver->getAvailableInputDevices();
const SwAudioOutputCollection &outputs = mApmObserver->getOutputs();
- return getDeviceForStrategyInt(strategy, (DeviceVector&)availableOutputDevices,
+ return getDeviceForStrategyInt(strategy, availableOutputDevices,
availableInputDevices, outputs);
}
audio_devices_t Engine::getDeviceForStrategyInt(routing_strategy strategy,
- DeviceVector &availableOutputDevices,
- const DeviceVector &availableInputDevices,
+ DeviceVector availableOutputDevices,
+ DeviceVector availableInputDevices,
const SwAudioOutputCollection &outputs) const
{
uint32_t device = AUDIO_DEVICE_NONE;
diff --git a/services/audiopolicy/enginedefault/src/Engine.h b/services/audiopolicy/enginedefault/src/Engine.h
index ed93d1c..606ad28 100755
--- a/services/audiopolicy/enginedefault/src/Engine.h
+++ b/services/audiopolicy/enginedefault/src/Engine.h
@@ -126,8 +126,8 @@
routing_strategy getStrategyForUsage(audio_usage_t usage);
audio_devices_t getDeviceForStrategy(routing_strategy strategy) const;
audio_devices_t getDeviceForStrategyInt(routing_strategy strategy,
- DeviceVector &availableOutputDevices,
- const DeviceVector &availableInputDevices,
+ DeviceVector availableOutputDevices,
+ DeviceVector availableInputDevices,
const SwAudioOutputCollection &outputs) const;
audio_devices_t getDeviceForInputSource(audio_source_t inputSource) const;
audio_mode_t mPhoneState; /**< current phone state. */
diff --git a/services/camera/libcameraservice/CameraService.cpp b/services/camera/libcameraservice/CameraService.cpp
index af8fc74..0c88dad 100644
--- a/services/camera/libcameraservice/CameraService.cpp
+++ b/services/camera/libcameraservice/CameraService.cpp
@@ -912,7 +912,8 @@
}
Status CameraService::validateConnectLocked(const String8& cameraId,
- const String8& clientName8, /*inout*/int& clientUid, /*inout*/int& clientPid) const {
+ const String8& clientName8, /*inout*/int& clientUid, /*inout*/int& clientPid,
+ /*out*/int& originalClientPid) const {
int callingPid = getCallingPid();
int callingUid = getCallingUid();
@@ -954,6 +955,7 @@
// Only use passed in clientPid to check permission. Use calling PID as the client PID that's
// connected to camera service directly.
+ originalClientPid = clientPid;
clientPid = callingPid;
if (!mModule) {
diff --git a/services/camera/libcameraservice/CameraService.h b/services/camera/libcameraservice/CameraService.h
index ab93218..11b1351 100644
--- a/services/camera/libcameraservice/CameraService.h
+++ b/services/camera/libcameraservice/CameraService.h
@@ -488,8 +488,14 @@
virtual void onFirstRef();
// Check if we can connect, before we acquire the service lock.
+ // The returned originalClientPid is the PID of the original process that wants to connect to
+ // camera.
+ // The returned clientPid is the PID of the client that directly connects to camera.
+ // originalClientPid and clientPid are usually the same except when the application uses
+ // mediaserver to connect to camera (using MediaRecorder to connect to camera). In that case,
+ // clientPid is the PID of mediaserver and originalClientPid is the PID of the application.
binder::Status validateConnectLocked(const String8& cameraId, const String8& clientName8,
- /*inout*/int& clientUid, /*inout*/int& clientPid) const;
+ /*inout*/int& clientUid, /*inout*/int& clientPid, /*out*/int& originalClientPid) const;
// Handle active client evictions, and update service state.
// Only call with with mServiceLock held.
@@ -819,6 +825,8 @@
String8 clientName8(clientPackageName);
+ int originalClientPid = 0;
+
ALOGI("CameraService::connect call (PID %d \"%s\", camera ID %s) for HAL version %s and "
"Camera API version %d", clientPid, clientName8.string(), cameraId.string(),
(halVersion == -1) ? "default" : std::to_string(halVersion).c_str(),
@@ -840,7 +848,7 @@
// Enforce client permissions and do basic sanity checks
if(!(ret = validateConnectLocked(cameraId, clientName8,
- /*inout*/clientUid, /*inout*/clientPid)).isOk()) {
+ /*inout*/clientUid, /*inout*/clientPid, /*out*/originalClientPid)).isOk()) {
return ret;
}
@@ -857,7 +865,7 @@
sp<BasicClient> clientTmp = nullptr;
std::shared_ptr<resource_policy::ClientDescriptor<String8, sp<BasicClient>>> partial;
- if ((err = handleEvictionsLocked(cameraId, clientPid, effectiveApiLevel,
+ if ((err = handleEvictionsLocked(cameraId, originalClientPid, effectiveApiLevel,
IInterface::asBinder(cameraCb), clientName8, /*out*/&clientTmp,
/*out*/&partial)) != NO_ERROR) {
switch (err) {
diff --git a/services/medialog/Android.mk b/services/medialog/Android.mk
index 411f80f..88f98cf 100644
--- a/services/medialog/Android.mk
+++ b/services/medialog/Android.mk
@@ -12,4 +12,6 @@
LOCAL_C_INCLUDES := $(call include-path-for, audio-utils)
+LOCAL_CFLAGS := -Werror -Wall
+
include $(BUILD_SHARED_LIBRARY)
diff --git a/services/mediaresourcemanager/ResourceManagerService.cpp b/services/mediaresourcemanager/ResourceManagerService.cpp
index e1235b8..64534bf 100644
--- a/services/mediaresourcemanager/ResourceManagerService.cpp
+++ b/services/mediaresourcemanager/ResourceManagerService.cpp
@@ -96,8 +96,11 @@
if (binder != NULL) {
sp<IMediaResourceMonitor> service = interface_cast<IMediaResourceMonitor>(binder);
for (size_t i = 0; i < resources.size(); ++i) {
- service->notifyResourceGranted(pid, String16(asString(resources[i].mType)),
- String16(asString(resources[i].mSubType)), resources[i].mValue);
+ if (resources[i].mSubType == MediaResource::kAudioCodec) {
+ service->notifyResourceGranted(pid, IMediaResourceMonitor::TYPE_AUDIO_CODEC);
+ } else if (resources[i].mSubType == MediaResource::kVideoCodec) {
+ service->notifyResourceGranted(pid, IMediaResourceMonitor::TYPE_VIDEO_CODEC);
+ }
}
}
}