summaryrefslogtreecommitdiffstats
path: root/media
diff options
context:
space:
mode:
authorWolfgang Wiedmeyer <wolfgit@wiedmeyer.de>2015-12-21 14:32:55 +0100
committerWolfgang Wiedmeyer <wolfgit@wiedmeyer.de>2015-12-21 14:32:55 +0100
commit18a7135624cd16f57157a9761964f1ca088dae25 (patch)
tree106fdd622cb666296001d02f4ddb73247bc0fd29 /media
parent71f190911abde06d0e9efe604b81b160b81dde23 (diff)
parente9990d5c032e2a29de51e1a361df409f269194c2 (diff)
downloadframeworks_av-18a7135624cd16f57157a9761964f1ca088dae25.zip
frameworks_av-18a7135624cd16f57157a9761964f1ca088dae25.tar.gz
frameworks_av-18a7135624cd16f57157a9761964f1ca088dae25.tar.bz2
Merge remote-tracking branch 'github/cm-13.0' into replicant-6.0
Diffstat (limited to 'media')
-rw-r--r--media/libavextensions/Android.mk3
-rw-r--r--media/libavextensions/mediaplayerservice/AVNuUtils.cpp24
-rw-r--r--media/libmedia/AudioRecord.cpp6
-rw-r--r--media/libmedia/IMediaMetadataRetriever.cpp2
-rw-r--r--media/libmediaplayerservice/MediaPlayerService.cpp1
-rw-r--r--media/libmediaplayerservice/MetadataRetrieverClient.cpp3
-rw-r--r--media/libmediaplayerservice/nuplayer/GenericSource.cpp2
-rw-r--r--media/libmediaplayerservice/nuplayer/NuPlayer.cpp85
-rw-r--r--media/libmediaplayerservice/nuplayer/NuPlayer.h2
-rw-r--r--media/libmediaplayerservice/nuplayer/NuPlayerDecoder.cpp15
-rw-r--r--media/libmediaplayerservice/nuplayer/NuPlayerDecoder.h1
-rw-r--r--media/libmediaplayerservice/nuplayer/NuPlayerDecoderBase.cpp19
-rw-r--r--media/libmediaplayerservice/nuplayer/NuPlayerDecoderBase.h5
-rw-r--r--media/libmediaplayerservice/nuplayer/NuPlayerDecoderPassThrough.cpp2
-rw-r--r--media/libstagefright/ACodec.cpp5
-rw-r--r--media/libstagefright/AwesomePlayer.cpp1
-rw-r--r--media/libstagefright/OMXCodec.cpp3
-rw-r--r--media/libstagefright/SkipCutBuffer.cpp39
-rw-r--r--media/libstagefright/Utils.cpp2
19 files changed, 122 insertions, 98 deletions
diff --git a/media/libavextensions/Android.mk b/media/libavextensions/Android.mk
index 68c36d8..3370116 100644
--- a/media/libavextensions/Android.mk
+++ b/media/libavextensions/Android.mk
@@ -28,7 +28,6 @@ ifeq ($(strip $(AUDIO_FEATURE_ENABLED_FLAC_OFFLOAD)),true)
endif
LOCAL_MODULE:= libavextensions
-LOCAL_CFLAGS += -DLOG_NDEBUG=0
LOCAL_MODULE_TAGS := optional
@@ -57,7 +56,6 @@ ifeq ($(TARGET_ENABLE_QC_AV_ENHANCEMENTS),true)
endif
LOCAL_MODULE:= libavmediaextentions
-LOCAL_CFLAGS += -DLOG_NDEBUG=0
LOCAL_MODULE_TAGS := optional
@@ -96,7 +94,6 @@ ifeq ($(TARGET_BOARD_PLATFORM),msm8974)
endif
LOCAL_MODULE:= libavmediaserviceextensions
-LOCAL_CFLAGS += -DLOG_NDEBUG=0
LOCAL_MODULE_TAGS := optional
diff --git a/media/libavextensions/mediaplayerservice/AVNuUtils.cpp b/media/libavextensions/mediaplayerservice/AVNuUtils.cpp
index 3354d23..34abd0a 100644
--- a/media/libavextensions/mediaplayerservice/AVNuUtils.cpp
+++ b/media/libavextensions/mediaplayerservice/AVNuUtils.cpp
@@ -202,7 +202,8 @@ bool AVNuUtils::isVorbisFormat(const sp<MetaData> &) {
int AVNuUtils::updateAudioBitWidth(audio_format_t audioFormat,
const sp<AMessage> &format){
int bits = 16;
- if (audio_is_linear_pcm(audioFormat) || audio_is_offload_pcm(audioFormat)) {
+ if (format.get() &&
+ (audio_is_linear_pcm(audioFormat) || audio_is_offload_pcm(audioFormat))) {
bits = audio_bytes_per_sample(audioFormat) * 8;
format->setInt32("bits-per-sample", bits);
}
@@ -211,42 +212,45 @@ int AVNuUtils::updateAudioBitWidth(audio_format_t audioFormat,
audio_format_t AVNuUtils::getKeyPCMFormat(const sp<MetaData> &meta) {
audio_format_t pcmFormat = AUDIO_FORMAT_INVALID;
- meta->findInt32('pfmt', (int32_t *)&pcmFormat);
+ if (meta.get())
+ meta->findInt32('pfmt', (int32_t *)&pcmFormat);
return pcmFormat;
}
void AVNuUtils::setKeyPCMFormat(const sp<MetaData> &meta, audio_format_t audioFormat) {
- if (meta != NULL && audio_is_linear_pcm(audioFormat))
+ if (meta.get() && audio_is_linear_pcm(audioFormat))
meta->setInt32('pfmt', audioFormat);
}
audio_format_t AVNuUtils::getPCMFormat(const sp<AMessage> &format) {
audio_format_t pcmFormat = AUDIO_FORMAT_INVALID;
- format->findInt32("pcm-format", (int32_t *)&pcmFormat);
+ if (format.get())
+ format->findInt32("pcm-format", (int32_t *)&pcmFormat);
return pcmFormat;
}
void AVNuUtils::setPCMFormat(const sp<AMessage> &format, audio_format_t audioFormat) {
- if (audio_is_linear_pcm(audioFormat) || audio_is_offload_pcm(audioFormat))
+ if (format.get() &&
+ (audio_is_linear_pcm(audioFormat) || audio_is_offload_pcm(audioFormat)))
format->setInt32("pcm-format", audioFormat);
}
void AVNuUtils::setSourcePCMFormat(const sp<MetaData> &audioMeta) {
- if (!isRAWFormat(audioMeta))
+ if (!audioMeta.get() || !isRAWFormat(audioMeta))
return;
audio_format_t pcmFormat = getKeyPCMFormat(audioMeta);
- ALOGI("setSourcePCMFormat fmt=%x", pcmFormat);
- audioMeta->dumpToLog();
if (pcmFormat == AUDIO_FORMAT_INVALID) {
int32_t bits = 16;
if (audioMeta->findInt32(kKeyBitsPerSample, &bits)) {
if (bits == 8)
pcmFormat = AUDIO_FORMAT_PCM_8_BIT;
- if (bits == 24)
+ else if (bits == 24)
pcmFormat = AUDIO_FORMAT_PCM_32_BIT;
- if (bits == 32)
+ else if (bits == 32)
pcmFormat = AUDIO_FORMAT_PCM_FLOAT;
+ else
+ pcmFormat = AUDIO_FORMAT_PCM_16_BIT;
setKeyPCMFormat(audioMeta, pcmFormat);
}
}
diff --git a/media/libmedia/AudioRecord.cpp b/media/libmedia/AudioRecord.cpp
index 6dc52cd..66903b3 100644
--- a/media/libmedia/AudioRecord.cpp
+++ b/media/libmedia/AudioRecord.cpp
@@ -276,7 +276,11 @@ status_t AudioRecord::set(
mActive = false;
mUserData = user;
// TODO: add audio hardware input latency here
- mLatency = (1000*mFrameCount) / sampleRate;
+ if (mTransfer == TRANSFER_CALLBACK) {
+ mLatency = (1000*mNotificationFramesAct) / sampleRate;
+ } else {
+ mLatency = (1000*mFrameCount) / sampleRate;
+ }
mMarkerPosition = 0;
mMarkerReached = false;
mNewPosition = 0;
diff --git a/media/libmedia/IMediaMetadataRetriever.cpp b/media/libmedia/IMediaMetadataRetriever.cpp
index 9765f0d..dbf524e 100644
--- a/media/libmedia/IMediaMetadataRetriever.cpp
+++ b/media/libmedia/IMediaMetadataRetriever.cpp
@@ -240,7 +240,7 @@ status_t BnMediaMetadataRetriever::onTransact(
} break;
case SET_DATA_SOURCE_FD: {
CHECK_INTERFACE(IMediaMetadataRetriever, data, reply);
- int fd = dup(data.readFileDescriptor());
+ int fd = data.readFileDescriptor();
int64_t offset = data.readInt64();
int64_t length = data.readInt64();
reply->writeInt32(setDataSource(fd, offset, length));
diff --git a/media/libmediaplayerservice/MediaPlayerService.cpp b/media/libmediaplayerservice/MediaPlayerService.cpp
index de51b3c..da5bb9a 100644
--- a/media/libmediaplayerservice/MediaPlayerService.cpp
+++ b/media/libmediaplayerservice/MediaPlayerService.cpp
@@ -749,7 +749,6 @@ status_t MediaPlayerService::Client::setDataSource(int fd, int64_t offset, int64
if (offset >= sb.st_size) {
ALOGE("offset error");
- ::close(fd);
return UNKNOWN_ERROR;
}
if (offset + length > sb.st_size) {
diff --git a/media/libmediaplayerservice/MetadataRetrieverClient.cpp b/media/libmediaplayerservice/MetadataRetrieverClient.cpp
index 894a855..7bd99cc 100644
--- a/media/libmediaplayerservice/MetadataRetrieverClient.cpp
+++ b/media/libmediaplayerservice/MetadataRetrieverClient.cpp
@@ -149,7 +149,6 @@ status_t MetadataRetrieverClient::setDataSource(int fd, int64_t offset, int64_t
if (offset >= sb.st_size) {
ALOGE("offset (%" PRId64 ") bigger than file size (%" PRIu64 ")", offset, sb.st_size);
- ::close(fd);
return BAD_VALUE;
}
if (offset + length > sb.st_size) {
@@ -165,12 +164,10 @@ status_t MetadataRetrieverClient::setDataSource(int fd, int64_t offset, int64_t
ALOGV("player type = %d", playerType);
sp<MediaMetadataRetrieverBase> p = createRetriever(playerType);
if (p == NULL) {
- ::close(fd);
return NO_INIT;
}
status_t status = p->setDataSource(fd, offset, length);
if (status == NO_ERROR) mRetriever = p;
- ::close(fd);
return status;
}
diff --git a/media/libmediaplayerservice/nuplayer/GenericSource.cpp b/media/libmediaplayerservice/nuplayer/GenericSource.cpp
index 3ffb0f9..e380f0a 100644
--- a/media/libmediaplayerservice/nuplayer/GenericSource.cpp
+++ b/media/libmediaplayerservice/nuplayer/GenericSource.cpp
@@ -361,7 +361,7 @@ void NuPlayer::GenericSource::prepareAsync() {
if (mLooper == NULL) {
mLooper = new ALooper;
mLooper->setName("generic");
- mLooper->start();
+ mLooper->start(false, false, PRIORITY_AUDIO);
mLooper->registerHandler(this);
}
diff --git a/media/libmediaplayerservice/nuplayer/NuPlayer.cpp b/media/libmediaplayerservice/nuplayer/NuPlayer.cpp
index 622e58a..ee63a6e 100644
--- a/media/libmediaplayerservice/nuplayer/NuPlayer.cpp
+++ b/media/libmediaplayerservice/nuplayer/NuPlayer.cpp
@@ -1118,7 +1118,41 @@ void NuPlayer::onMessageReceived(const sp<AMessage> &msg) {
int32_t reason;
CHECK(msg->findInt32("reason", &reason));
ALOGV("Tear down audio with reason %d.", reason);
- performTearDown(msg);
+ mAudioDecoder->pause();
+ mAudioDecoder.clear();
+ ++mAudioDecoderGeneration;
+ bool needsToCreateAudioDecoder = true;
+ if (mFlushingAudio == FLUSHING_DECODER) {
+ mFlushComplete[1 /* audio */][1 /* isDecoder */] = true;
+ mFlushingAudio = FLUSHED;
+ finishFlushIfPossible();
+ } else if (mFlushingAudio == FLUSHING_DECODER_SHUTDOWN
+ || mFlushingAudio == SHUTTING_DOWN_DECODER) {
+ mFlushComplete[1 /* audio */][1 /* isDecoder */] = true;
+ mFlushingAudio = SHUT_DOWN;
+ finishFlushIfPossible();
+ needsToCreateAudioDecoder = false;
+ }
+ if (mRenderer == NULL) {
+ break;
+ }
+ closeAudioSink();
+ mRenderer->flush(
+ true /* audio */, false /* notifyComplete */);
+ if (mVideoDecoder != NULL) {
+ mRenderer->flush(
+ false /* audio */, false /* notifyComplete */);
+ }
+
+ int64_t positionUs;
+ if (!msg->findInt64("positionUs", &positionUs)) {
+ positionUs = mPreviousSeekTimeUs;
+ }
+ performSeek(positionUs);
+
+ if (reason == Renderer::kDueToError && needsToCreateAudioDecoder) {
+ instantiateDecoder(true /* audio */, &mAudioDecoder);
+ }
}
break;
}
@@ -1306,7 +1340,7 @@ void NuPlayer::onStart(int64_t startPositionUs) {
ALOGV("onStart");
sp<MetaData> audioMeta = mSource->getFormatMeta(true /* audio */);
AVNuUtils::get()->setSourcePCMFormat(audioMeta);
- audioMeta->dumpToLog();
+
audio_stream_type_t streamType = AUDIO_STREAM_MUSIC;
if (mAudioSink != NULL) {
streamType = mAudioSink->getAudioStreamType();
@@ -2409,53 +2443,6 @@ void NuPlayer::Source::onMessageReceived(const sp<AMessage> & /* msg */) {
TRESPASS();
}
-//
-// There is a flush from within the decoder's onFlush handling.
-// Without it, it is still possible that a buffer can be queueued
-// after NuPlayer issues a flush on the renderer's audio queue.
-//
-void NuPlayer::performTearDown(const sp<AMessage> &msg) {
- int32_t reason;
- CHECK(msg->findInt32("reason", &reason));
-
- if (mAudioDecoder != NULL) {
- switch (mFlushingAudio) {
- case NONE:
- case FLUSHING_DECODER:
- mDeferredActions.push_back(
- new FlushDecoderAction(FLUSH_CMD_SHUTDOWN /* audio */,
- FLUSH_CMD_NONE /* video */));
-
- if (reason == Renderer::kDueToError) {
- mDeferredActions.push_back(
- new InstantiateDecoderAction(true /* audio */, &mAudioDecoder));
- }
-
- int64_t positionUs;
- if (!msg->findInt64("positionUs", &positionUs)) {
- positionUs = mPreviousSeekTimeUs;
- }
- mDeferredActions.push_back(new SeekAction(positionUs));
- break;
- default:
- ALOGW("performTearDown while flushing audio in %d", mFlushingAudio);
- break;
- }
- }
-
- if (mRenderer != NULL) {
- closeAudioSink();
- // see comment at beginning of function
- mRenderer->flush(
- true /* audio */, false /* notifyComplete */);
- if (mVideoDecoder != NULL) {
- mRenderer->flush(
- false /* audio */, false /* notifyComplete */);
- }
- }
- processDeferredActions();
-}
-
bool NuPlayer::ifDecodedPCMOffload() {
return mOffloadDecodedPCM;
}
diff --git a/media/libmediaplayerservice/nuplayer/NuPlayer.h b/media/libmediaplayerservice/nuplayer/NuPlayer.h
index c093b0f..1c51c4b 100644
--- a/media/libmediaplayerservice/nuplayer/NuPlayer.h
+++ b/media/libmediaplayerservice/nuplayer/NuPlayer.h
@@ -283,8 +283,6 @@ protected:
void writeTrackInfo(Parcel* reply, const sp<AMessage> format) const;
- void performTearDown(const sp<AMessage> &msg);
-
DISALLOW_EVIL_CONSTRUCTORS(NuPlayer);
};
diff --git a/media/libmediaplayerservice/nuplayer/NuPlayerDecoder.cpp b/media/libmediaplayerservice/nuplayer/NuPlayerDecoder.cpp
index d23a9e2..c505096 100644
--- a/media/libmediaplayerservice/nuplayer/NuPlayerDecoder.cpp
+++ b/media/libmediaplayerservice/nuplayer/NuPlayerDecoder.cpp
@@ -73,7 +73,6 @@ NuPlayer::Decoder::Decoder(
mIsSecure(false),
mFormatChangePending(false),
mTimeChangePending(false),
- mPaused(true),
mResumePending(false),
mComponentName("decoder") {
mCodecLooper = new ALooper;
@@ -608,14 +607,6 @@ bool NuPlayer::Decoder::handleAnOutputBuffer(
reply->setSize("buffer-ix", index);
reply->setInt32("generation", mBufferGeneration);
- if ((flags & MediaCodec::BUFFER_FLAG_DATACORRUPT) &&
- AVNuUtils::get()->dropCorruptFrame()) {
- ALOGV("[%s] dropping corrupt buffer at time %lld as requested.",
- mComponentName.c_str(), (long long)timeUs);
- reply->post();
- return true;
- }
-
if (eos) {
ALOGI("[%s] saw output EOS", mIsAudio ? "audio" : "video");
@@ -631,6 +622,12 @@ bool NuPlayer::Decoder::handleAnOutputBuffer(
}
mSkipRenderingUntilMediaTimeUs = -1;
+ } else if ((flags & MediaCodec::BUFFER_FLAG_DATACORRUPT) &&
+ AVNuUtils::get()->dropCorruptFrame()) {
+ ALOGV("[%s] dropping corrupt buffer at time %lld as requested.",
+ mComponentName.c_str(), (long long)timeUs);
+ reply->post();
+ return true;
}
mNumFramesTotal += !mIsAudio;
diff --git a/media/libmediaplayerservice/nuplayer/NuPlayerDecoder.h b/media/libmediaplayerservice/nuplayer/NuPlayerDecoder.h
index 23c87ae..6e2b9d0 100644
--- a/media/libmediaplayerservice/nuplayer/NuPlayerDecoder.h
+++ b/media/libmediaplayerservice/nuplayer/NuPlayerDecoder.h
@@ -96,7 +96,6 @@ protected:
bool mFormatChangePending;
bool mTimeChangePending;
- bool mPaused;
bool mResumePending;
AString mComponentName;
diff --git a/media/libmediaplayerservice/nuplayer/NuPlayerDecoderBase.cpp b/media/libmediaplayerservice/nuplayer/NuPlayerDecoderBase.cpp
index 7e76842..04bb61c 100644
--- a/media/libmediaplayerservice/nuplayer/NuPlayerDecoderBase.cpp
+++ b/media/libmediaplayerservice/nuplayer/NuPlayerDecoderBase.cpp
@@ -31,6 +31,7 @@ namespace android {
NuPlayer::DecoderBase::DecoderBase(const sp<AMessage> &notify)
: mNotify(notify),
mBufferGeneration(0),
+ mPaused(false),
mStats(new AMessage),
mRequestInputBuffersPending(false) {
// Every decoder has its own looper because MediaCodec operations
@@ -83,6 +84,13 @@ void NuPlayer::DecoderBase::setRenderer(const sp<Renderer> &renderer) {
msg->post();
}
+void NuPlayer::DecoderBase::pause() {
+ sp<AMessage> msg = new AMessage(kWhatPause, this);
+
+ sp<AMessage> response;
+ PostAndAwaitResponse(msg, &response);
+}
+
status_t NuPlayer::DecoderBase::getInputBuffers(Vector<sp<ABuffer> > *buffers) const {
sp<AMessage> msg = new AMessage(kWhatGetInputBuffers, this);
msg->setPointer("buffers", buffers);
@@ -146,6 +154,17 @@ void NuPlayer::DecoderBase::onMessageReceived(const sp<AMessage> &msg) {
break;
}
+ case kWhatPause:
+ {
+ sp<AReplyToken> replyID;
+ CHECK(msg->senderAwaitsResponse(&replyID));
+
+ mPaused = true;
+
+ (new AMessage)->postReply(replyID);
+ break;
+ }
+
case kWhatGetInputBuffers:
{
sp<AReplyToken> replyID;
diff --git a/media/libmediaplayerservice/nuplayer/NuPlayerDecoderBase.h b/media/libmediaplayerservice/nuplayer/NuPlayerDecoderBase.h
index b0dc01d..a334ec5 100644
--- a/media/libmediaplayerservice/nuplayer/NuPlayerDecoderBase.h
+++ b/media/libmediaplayerservice/nuplayer/NuPlayerDecoderBase.h
@@ -36,6 +36,9 @@ struct NuPlayer::DecoderBase : public AHandler {
void init();
void setParameters(const sp<AMessage> &params);
+ // Synchronous call to ensure decoder will not request or send out data.
+ void pause();
+
void setRenderer(const sp<Renderer> &renderer);
virtual status_t setVideoSurface(const sp<Surface> &) { return INVALID_OPERATION; }
@@ -78,6 +81,7 @@ protected:
sp<AMessage> mNotify;
int32_t mBufferGeneration;
+ bool mPaused;
sp<AMessage> mStats;
private:
@@ -85,6 +89,7 @@ private:
kWhatConfigure = 'conf',
kWhatSetParameters = 'setP',
kWhatSetRenderer = 'setR',
+ kWhatPause = 'paus',
kWhatGetInputBuffers = 'gInB',
kWhatRequestInputBuffers = 'reqB',
kWhatFlush = 'flus',
diff --git a/media/libmediaplayerservice/nuplayer/NuPlayerDecoderPassThrough.cpp b/media/libmediaplayerservice/nuplayer/NuPlayerDecoderPassThrough.cpp
index 0b50d0d..b8b0505 100644
--- a/media/libmediaplayerservice/nuplayer/NuPlayerDecoderPassThrough.cpp
+++ b/media/libmediaplayerservice/nuplayer/NuPlayerDecoderPassThrough.cpp
@@ -48,7 +48,6 @@ NuPlayer::DecoderPassThrough::DecoderPassThrough(
// The offload read buffer size is 32 KB but 24 KB uses less power.
mAggregateBufferSizeBytes(24 * 1024),
mSkipRenderingUntilMediaTimeUs(-1ll),
- mPaused(false),
mReachedEOS(true),
mPendingAudioErr(OK),
mPendingBuffersToDrain(0),
@@ -224,6 +223,7 @@ sp<ABuffer> NuPlayer::DecoderPassThrough::aggregateBuffer(
} else {
// decided not to aggregate
aggregate = accessUnit;
+ setPcmFormat(aggregate->meta());
}
return aggregate;
diff --git a/media/libstagefright/ACodec.cpp b/media/libstagefright/ACodec.cpp
index 672e50a..c84601d 100644
--- a/media/libstagefright/ACodec.cpp
+++ b/media/libstagefright/ACodec.cpp
@@ -4566,16 +4566,13 @@ void ACodec::sendFormatChange(const sp<AMessage> &reply) {
(mEncoderDelay || mEncoderPadding)) {
int32_t channelCount;
CHECK(notify->findInt32("channel-count", &channelCount));
- size_t frameSize = channelCount * sizeof(int16_t);
if (mSkipCutBuffer != NULL) {
size_t prevbufsize = mSkipCutBuffer->size();
if (prevbufsize != 0) {
ALOGW("Replacing SkipCutBuffer holding %zu bytes", prevbufsize);
}
}
- mSkipCutBuffer = new SkipCutBuffer(
- mEncoderDelay * frameSize,
- mEncoderPadding * frameSize);
+ mSkipCutBuffer = new SkipCutBuffer(mEncoderDelay, mEncoderPadding, channelCount);
}
getVQZIPInfo(notify);
diff --git a/media/libstagefright/AwesomePlayer.cpp b/media/libstagefright/AwesomePlayer.cpp
index 5a43caf..933f241 100644
--- a/media/libstagefright/AwesomePlayer.cpp
+++ b/media/libstagefright/AwesomePlayer.cpp
@@ -344,6 +344,7 @@ status_t AwesomePlayer::setDataSource(
reset_l();
+ fd = dup(fd);
sp<DataSource> dataSource = new FileSource(fd, offset, length);
status_t err = dataSource->initCheck();
diff --git a/media/libstagefright/OMXCodec.cpp b/media/libstagefright/OMXCodec.cpp
index 6bd54f1..abe19a0 100644
--- a/media/libstagefright/OMXCodec.cpp
+++ b/media/libstagefright/OMXCodec.cpp
@@ -1760,14 +1760,13 @@ status_t OMXCodec::allocateBuffersOnPort(OMX_U32 portIndex) {
int32_t numchannels = 0;
if (delay + padding) {
if (mOutputFormat->findInt32(kKeyChannelCount, &numchannels)) {
- size_t frameSize = numchannels * sizeof(int16_t);
if (mSkipCutBuffer != NULL) {
size_t prevbuffersize = mSkipCutBuffer->size();
if (prevbuffersize != 0) {
ALOGW("Replacing SkipCutBuffer holding %zu bytes", prevbuffersize);
}
}
- mSkipCutBuffer = new SkipCutBuffer(delay * frameSize, padding * frameSize);
+ mSkipCutBuffer = new SkipCutBuffer(delay, padding, numchannels);
}
}
}
diff --git a/media/libstagefright/SkipCutBuffer.cpp b/media/libstagefright/SkipCutBuffer.cpp
index 1da1e5e..d30be88 100644
--- a/media/libstagefright/SkipCutBuffer.cpp
+++ b/media/libstagefright/SkipCutBuffer.cpp
@@ -24,21 +24,32 @@
namespace android {
-SkipCutBuffer::SkipCutBuffer(int32_t skip, int32_t cut) {
+SkipCutBuffer::SkipCutBuffer(size_t skip, size_t cut, size_t num16BitChannels) {
- if (skip < 0 || cut < 0 || cut > 64 * 1024) {
- ALOGW("out of range skip/cut: %d/%d, using passthrough instead", skip, cut);
- skip = 0;
- cut = 0;
+ mWriteHead = 0;
+ mReadHead = 0;
+ mCapacity = 0;
+ mCutBuffer = NULL;
+
+ if (num16BitChannels == 0 || num16BitChannels > INT32_MAX / 2) {
+ ALOGW("# channels out of range: %zu, using passthrough instead", num16BitChannels);
+ return;
}
+ size_t frameSize = num16BitChannels * 2;
+ if (skip > INT32_MAX / frameSize || cut > INT32_MAX / frameSize
+ || cut * frameSize > INT32_MAX - 4096) {
+ ALOGW("out of range skip/cut: %zu/%zu, using passthrough instead",
+ skip, cut);
+ return;
+ }
+ skip *= frameSize;
+ cut *= frameSize;
mFrontPadding = mSkip = skip;
mBackPadding = cut;
- mWriteHead = 0;
- mReadHead = 0;
mCapacity = cut + 4096;
- mCutBuffer = new char[mCapacity];
- ALOGV("skipcutbuffer %d %d %d", skip, cut, mCapacity);
+ mCutBuffer = new (std::nothrow) char[mCapacity];
+ ALOGV("skipcutbuffer %zu %zu %d", skip, cut, mCapacity);
}
SkipCutBuffer::~SkipCutBuffer() {
@@ -46,6 +57,11 @@ SkipCutBuffer::~SkipCutBuffer() {
}
void SkipCutBuffer::submit(MediaBuffer *buffer) {
+ if (mCutBuffer == NULL) {
+ // passthrough mode
+ return;
+ }
+
int32_t offset = buffer->range_offset();
int32_t buflen = buffer->range_length();
@@ -73,6 +89,11 @@ void SkipCutBuffer::submit(MediaBuffer *buffer) {
}
void SkipCutBuffer::submit(const sp<ABuffer>& buffer) {
+ if (mCutBuffer == NULL) {
+ // passthrough mode
+ return;
+ }
+
int32_t offset = buffer->offset();
int32_t buflen = buffer->size();
diff --git a/media/libstagefright/Utils.cpp b/media/libstagefright/Utils.cpp
index e9d585f..592510b 100644
--- a/media/libstagefright/Utils.cpp
+++ b/media/libstagefright/Utils.cpp
@@ -893,7 +893,7 @@ bool canOffloadStream(const sp<MetaData>& meta, bool hasVideo,
info.sample_rate = srate;
int32_t cmask = 0;
- if (!meta->findInt32(kKeyChannelMask, &cmask)) {
+ if (!meta->findInt32(kKeyChannelMask, &cmask) || 0 == cmask) {
ALOGV("track of type '%s' does not publish channel mask", mime);
// Try a channel count instead