Merge "Enable extended precision PCM output in AudioFlinger"
diff --git a/cmds/stagefright/sf2.cpp b/cmds/stagefright/sf2.cpp
index 3c0c7ec..0f729a3 100644
--- a/cmds/stagefright/sf2.cpp
+++ b/cmds/stagefright/sf2.cpp
@@ -211,28 +211,28 @@
int32_t what;
CHECK(msg->findInt32("what", &what));
- if (what == ACodec::kWhatFillThisBuffer) {
+ if (what == CodecBase::kWhatFillThisBuffer) {
onFillThisBuffer(msg);
- } else if (what == ACodec::kWhatDrainThisBuffer) {
+ } else if (what == CodecBase::kWhatDrainThisBuffer) {
if ((mNumOutputBuffersReceived++ % 16) == 0) {
printf(".");
fflush(stdout);
}
onDrainThisBuffer(msg);
- } else if (what == ACodec::kWhatEOS
- || what == ACodec::kWhatError) {
- printf((what == ACodec::kWhatEOS) ? "$\n" : "E\n");
+ } else if (what == CodecBase::kWhatEOS
+ || what == CodecBase::kWhatError) {
+ printf((what == CodecBase::kWhatEOS) ? "$\n" : "E\n");
printStatistics();
(new AMessage(kWhatStop, id()))->post();
- } else if (what == ACodec::kWhatFlushCompleted) {
+ } else if (what == CodecBase::kWhatFlushCompleted) {
mSeekState = SEEK_FLUSH_COMPLETED;
mCodec->signalResume();
(new AMessage(kWhatSeek, id()))->post(5000000ll);
- } else if (what == ACodec::kWhatOutputFormatChanged) {
- } else if (what == ACodec::kWhatShutdownCompleted) {
+ } else if (what == CodecBase::kWhatOutputFormatChanged) {
+ } else if (what == CodecBase::kWhatShutdownCompleted) {
mDecodeLooper->unregisterHandler(mCodec->id());
if (mDecodeLooper != looper()) {
@@ -240,12 +240,6 @@
}
looper()->stop();
- } else if (what == ACodec::kWhatError) {
- ALOGE("something went wrong, codec reported an error.");
-
- printf("E\n");
-
- (new AMessage(kWhatStop, id()))->post();
}
break;
}
diff --git a/include/media/stagefright/ACodec.h b/include/media/stagefright/ACodec.h
index 84b6bab..142b7cb 100644
--- a/include/media/stagefright/ACodec.h
+++ b/include/media/stagefright/ACodec.h
@@ -22,6 +22,7 @@
#include <android/native_window.h>
#include <media/IOMX.h>
#include <media/stagefright/foundation/AHierarchicalStateMachine.h>
+#include <media/stagefright/CodecBase.h>
#include <media/stagefright/SkipCutBuffer.h>
#include <OMX_Audio.h>
@@ -32,42 +33,32 @@
struct ABuffer;
struct MemoryDealer;
-struct ACodec : public AHierarchicalStateMachine {
- enum {
- kWhatFillThisBuffer = 'fill',
- kWhatDrainThisBuffer = 'drai',
- kWhatEOS = 'eos ',
- kWhatShutdownCompleted = 'scom',
- kWhatFlushCompleted = 'fcom',
- kWhatOutputFormatChanged = 'outC',
- kWhatError = 'erro',
- kWhatComponentAllocated = 'cAll',
- kWhatComponentConfigured = 'cCon',
- kWhatInputSurfaceCreated = 'isfc',
- kWhatSignaledInputEOS = 'seos',
- kWhatBuffersAllocated = 'allc',
- kWhatOMXDied = 'OMXd',
- };
-
+struct ACodec : public AHierarchicalStateMachine, public CodecBase {
ACodec();
- void setNotificationMessage(const sp<AMessage> &msg);
+ virtual void setNotificationMessage(const sp<AMessage> &msg);
+
void initiateSetup(const sp<AMessage> &msg);
- void signalFlush();
- void signalResume();
- void initiateShutdown(bool keepComponentAllocated = false);
- void signalSetParameters(const sp<AMessage> &msg);
- void signalEndOfInputStream();
+ virtual void initiateAllocateComponent(const sp<AMessage> &msg);
+ virtual void initiateConfigureComponent(const sp<AMessage> &msg);
+ virtual void initiateCreateInputSurface();
+ virtual void initiateStart();
+ virtual void initiateShutdown(bool keepComponentAllocated = false);
- void initiateAllocateComponent(const sp<AMessage> &msg);
- void initiateConfigureComponent(const sp<AMessage> &msg);
- void initiateCreateInputSurface();
- void initiateStart();
+ virtual void signalFlush();
+ virtual void signalResume();
- void signalRequestIDRFrame();
+ virtual void signalSetParameters(const sp<AMessage> &msg);
+ virtual void signalEndOfInputStream();
+ virtual void signalRequestIDRFrame();
- struct PortDescription : public RefBase {
+ // AHierarchicalStateMachine implements the message handling
+ virtual void onMessageReceived(const sp<AMessage> &msg) {
+ handleMessage(msg);
+ }
+
+ struct PortDescription : public CodecBase::PortDescription {
size_t countBuffers();
IOMX::buffer_id bufferIDAt(size_t index) const;
sp<ABuffer> bufferAt(size_t index) const;
@@ -117,6 +108,7 @@
kWhatRequestIDRFrame = 'ridr',
kWhatSetParameters = 'setP',
kWhatSubmitOutputMetaDataBufferIfEOS = 'subm',
+ kWhatOMXDied = 'OMXd',
};
enum {
diff --git a/include/media/stagefright/CodecBase.h b/include/media/stagefright/CodecBase.h
new file mode 100644
index 0000000..1bf27a6
--- /dev/null
+++ b/include/media/stagefright/CodecBase.h
@@ -0,0 +1,88 @@
+/*
+ * Copyright (C) 2014 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 CODEC_BASE_H_
+
+#define CODEC_BASE_H_
+
+#include <stdint.h>
+#include <media/IOMX.h>
+
+#include <media/stagefright/foundation/AHandler.h>
+
+namespace android {
+
+struct ABuffer;
+
+struct CodecBase : public AHandler {
+ enum {
+ kWhatFillThisBuffer = 'fill',
+ kWhatDrainThisBuffer = 'drai',
+ kWhatEOS = 'eos ',
+ kWhatShutdownCompleted = 'scom',
+ kWhatFlushCompleted = 'fcom',
+ kWhatOutputFormatChanged = 'outC',
+ kWhatError = 'erro',
+ kWhatComponentAllocated = 'cAll',
+ kWhatComponentConfigured = 'cCon',
+ kWhatInputSurfaceCreated = 'isfc',
+ kWhatSignaledInputEOS = 'seos',
+ kWhatBuffersAllocated = 'allc',
+ };
+
+ virtual void setNotificationMessage(const sp<AMessage> &msg) = 0;
+
+ virtual void initiateAllocateComponent(const sp<AMessage> &msg) = 0;
+ virtual void initiateConfigureComponent(const sp<AMessage> &msg) = 0;
+ virtual void initiateCreateInputSurface() = 0;
+ virtual void initiateStart() = 0;
+ virtual void initiateShutdown(bool keepComponentAllocated = false) = 0;
+
+ // require an explicit message handler
+ virtual void onMessageReceived(const sp<AMessage> &msg) = 0;
+
+ virtual void signalFlush() = 0;
+ virtual void signalResume() = 0;
+
+ virtual void signalRequestIDRFrame() = 0;
+ virtual void signalSetParameters(const sp<AMessage> &msg) = 0;
+ virtual void signalEndOfInputStream() = 0;
+
+ struct PortDescription : public RefBase {
+ virtual size_t countBuffers() = 0;
+ virtual IOMX::buffer_id bufferIDAt(size_t index) const = 0;
+ virtual sp<ABuffer> bufferAt(size_t index) const = 0;
+
+ protected:
+ PortDescription();
+ virtual ~PortDescription();
+
+ private:
+ DISALLOW_EVIL_CONSTRUCTORS(PortDescription);
+ };
+
+protected:
+ CodecBase();
+ virtual ~CodecBase();
+
+private:
+ DISALLOW_EVIL_CONSTRUCTORS(CodecBase);
+};
+
+} // namespace android
+
+#endif // CODEC_BASE_H_
+
diff --git a/include/media/stagefright/MediaCodec.h b/include/media/stagefright/MediaCodec.h
index a1e32c9..3e6eefb 100644
--- a/include/media/stagefright/MediaCodec.h
+++ b/include/media/stagefright/MediaCodec.h
@@ -26,9 +26,9 @@
namespace android {
struct ABuffer;
-struct ACodec;
struct AMessage;
struct AString;
+struct CodecBase;
struct ICrypto;
struct SoftwareRenderer;
struct Surface;
@@ -195,7 +195,7 @@
State mState;
sp<ALooper> mLooper;
sp<ALooper> mCodecLooper;
- sp<ACodec> mCodec;
+ sp<CodecBase> mCodec;
AString mComponentName;
uint32_t mReplyID;
uint32_t mFlags;
diff --git a/include/media/stagefright/foundation/ABitReader.h b/include/media/stagefright/foundation/ABitReader.h
index 5510b12..c3bf0ff 100644
--- a/include/media/stagefright/foundation/ABitReader.h
+++ b/include/media/stagefright/foundation/ABitReader.h
@@ -25,8 +25,10 @@
namespace android {
-struct ABitReader {
+class ABitReader {
+public:
ABitReader(const uint8_t *data, size_t size);
+ virtual ~ABitReader();
uint32_t getBits(size_t n);
void skipBits(size_t n);
@@ -37,18 +39,32 @@
const uint8_t *data() const;
-private:
+protected:
const uint8_t *mData;
size_t mSize;
uint32_t mReservoir; // left-aligned bits
size_t mNumBitsLeft;
- void fillReservoir();
+ virtual void fillReservoir();
DISALLOW_EVIL_CONSTRUCTORS(ABitReader);
};
+class NALBitReader : public ABitReader {
+public:
+ NALBitReader(const uint8_t *data, size_t size);
+
+ bool atLeastNumBitsLeft(size_t n) const;
+
+private:
+ int32_t mNumZeros;
+
+ virtual void fillReservoir();
+
+ DISALLOW_EVIL_CONSTRUCTORS(NALBitReader);
+};
+
} // namespace android
#endif // A_BIT_READER_H_
diff --git a/include/media/stagefright/foundation/AHierarchicalStateMachine.h b/include/media/stagefright/foundation/AHierarchicalStateMachine.h
index d2e6b28..3bb7d75 100644
--- a/include/media/stagefright/foundation/AHierarchicalStateMachine.h
+++ b/include/media/stagefright/foundation/AHierarchicalStateMachine.h
@@ -43,13 +43,13 @@
DISALLOW_EVIL_CONSTRUCTORS(AState);
};
-struct AHierarchicalStateMachine : public AHandler {
+struct AHierarchicalStateMachine {
AHierarchicalStateMachine();
protected:
virtual ~AHierarchicalStateMachine();
- virtual void onMessageReceived(const sp<AMessage> &msg);
+ virtual void handleMessage(const sp<AMessage> &msg);
// Only to be called in response to a message.
void changeState(const sp<AState> &state);
diff --git a/include/media/stagefright/foundation/AString.h b/include/media/stagefright/foundation/AString.h
index 622028e..0edaa1c 100644
--- a/include/media/stagefright/foundation/AString.h
+++ b/include/media/stagefright/foundation/AString.h
@@ -77,6 +77,8 @@
bool startsWith(const char *prefix) const;
bool endsWith(const char *suffix) const;
+ bool startsWithIgnoreCase(const char *prefix) const;
+ bool endsWithIgnoreCase(const char *suffix) const;
void tolower();
diff --git a/media/libeffects/lvm/wrapper/Bundle/EffectBundle.cpp b/media/libeffects/lvm/wrapper/Bundle/EffectBundle.cpp
index 695767d..38ee82b 100644
--- a/media/libeffects/lvm/wrapper/Bundle/EffectBundle.cpp
+++ b/media/libeffects/lvm/wrapper/Bundle/EffectBundle.cpp
@@ -163,7 +163,7 @@
extern "C" int EffectCreate(const effect_uuid_t *uuid,
int32_t sessionId,
- int32_t ioId,
+ int32_t ioId __unused,
effect_handle_t *pHandle){
int ret = 0;
int sessionNo;
@@ -1360,7 +1360,7 @@
// pLow: lower band range
// pLow: upper band range
//----------------------------------------------------------------------------
-int32_t EqualizerGetBandFreqRange(EffectContext *pContext, int32_t band, uint32_t *pLow,
+int32_t EqualizerGetBandFreqRange(EffectContext *pContext __unused, int32_t band, uint32_t *pLow,
uint32_t *pHi){
*pLow = bandFreqRange[band][0];
*pHi = bandFreqRange[band][1];
@@ -1384,7 +1384,7 @@
// pLow: lower band range
// pLow: upper band range
//----------------------------------------------------------------------------
-int32_t EqualizerGetBand(EffectContext *pContext, uint32_t targetFreq){
+int32_t EqualizerGetBand(EffectContext *pContext __unused, uint32_t targetFreq){
int band = 0;
if(targetFreq < bandFreqRange[0][0]){
@@ -1884,7 +1884,6 @@
int status = 0;
int32_t *pParamTemp = (int32_t *)pParam;
int32_t param = *pParamTemp++;
- int32_t param2;
char *name;
//ALOGV("\tVirtualizer_getParameter start");
diff --git a/media/libmediaplayerservice/nuplayer/GenericSource.cpp b/media/libmediaplayerservice/nuplayer/GenericSource.cpp
index 5cf9238..388f77a 100644
--- a/media/libmediaplayerservice/nuplayer/GenericSource.cpp
+++ b/media/libmediaplayerservice/nuplayer/GenericSource.cpp
@@ -272,7 +272,9 @@
if (seeking) {
track->mPackets->queueDiscontinuity(
- ATSParser::DISCONTINUITY_SEEK, NULL);
+ ATSParser::DISCONTINUITY_SEEK,
+ NULL,
+ true /* discard */);
}
track->mPackets->queueAccessUnit(buffer);
@@ -280,7 +282,9 @@
} else if (err == INFO_FORMAT_CHANGED) {
#if 0
track->mPackets->queueDiscontinuity(
- ATSParser::DISCONTINUITY_FORMATCHANGE, NULL);
+ ATSParser::DISCONTINUITY_FORMATCHANGE,
+ NULL,
+ false /* discard */);
#endif
} else {
track->mPackets->signalEOS(err);
diff --git a/media/libmediaplayerservice/nuplayer/NuPlayerDecoder.cpp b/media/libmediaplayerservice/nuplayer/NuPlayerDecoder.cpp
index 5abfb71..dd73cc4 100644
--- a/media/libmediaplayerservice/nuplayer/NuPlayerDecoder.cpp
+++ b/media/libmediaplayerservice/nuplayer/NuPlayerDecoder.cpp
@@ -674,9 +674,9 @@
bool hasCC = false;
- ABitReader br(sei->data() + 1, sei->size() - 1);
+ NALBitReader br(sei->data() + 1, sei->size() - 1);
// sei_message()
- while (br.numBitsLeft() >= 16) { // at least 16-bit for sei_message()
+ while (br.atLeastNumBitsLeft(16)) { // at least 16-bit for sei_message()
uint32_t payload_type = 0;
size_t payload_size = 0;
uint8_t last_byte;
diff --git a/media/libmediaplayerservice/nuplayer/RTSPSource.cpp b/media/libmediaplayerservice/nuplayer/RTSPSource.cpp
index 94800ba..2338b23 100644
--- a/media/libmediaplayerservice/nuplayer/RTSPSource.cpp
+++ b/media/libmediaplayerservice/nuplayer/RTSPSource.cpp
@@ -505,7 +505,10 @@
TrackInfo *info = &mTracks.editItemAt(trackIndex);
sp<AnotherPacketSource> source = info->mSource;
if (source != NULL) {
- source->queueDiscontinuity(ATSParser::DISCONTINUITY_SEEK, NULL);
+ source->queueDiscontinuity(
+ ATSParser::DISCONTINUITY_SEEK,
+ NULL,
+ true /* discard */);
}
break;
diff --git a/media/libstagefright/ACodec.cpp b/media/libstagefright/ACodec.cpp
index 2a583d0..9c64d72 100644
--- a/media/libstagefright/ACodec.cpp
+++ b/media/libstagefright/ACodec.cpp
@@ -547,7 +547,7 @@
}
sp<AMessage> notify = mNotify->dup();
- notify->setInt32("what", ACodec::kWhatBuffersAllocated);
+ notify->setInt32("what", CodecBase::kWhatBuffersAllocated);
notify->setInt32("portIndex", portIndex);
@@ -3005,7 +3005,7 @@
void ACodec::signalError(OMX_ERRORTYPE error, status_t internalError) {
sp<AMessage> notify = mNotify->dup();
- notify->setInt32("what", ACodec::kWhatError);
+ notify->setInt32("what", CodecBase::kWhatError);
notify->setInt32("omx-error", error);
notify->setInt32("err", internalError);
notify->post();
@@ -3398,7 +3398,7 @@
CHECK_EQ((int)info->mStatus, (int)BufferInfo::OWNED_BY_US);
sp<AMessage> notify = mCodec->mNotify->dup();
- notify->setInt32("what", ACodec::kWhatFillThisBuffer);
+ notify->setInt32("what", CodecBase::kWhatFillThisBuffer);
notify->setInt32("buffer-id", info->mBufferID);
info->mData->meta()->clear();
@@ -3693,7 +3693,7 @@
info->mData->meta()->setInt64("timeUs", timeUs);
sp<AMessage> notify = mCodec->mNotify->dup();
- notify->setInt32("what", ACodec::kWhatDrainThisBuffer);
+ notify->setInt32("what", CodecBase::kWhatDrainThisBuffer);
notify->setInt32("buffer-id", info->mBufferID);
notify->setBuffer("buffer", info->mData);
notify->setInt32("flags", flags);
@@ -3710,7 +3710,7 @@
ALOGV("[%s] saw output EOS", mCodec->mComponentName.c_str());
sp<AMessage> notify = mCodec->mNotify->dup();
- notify->setInt32("what", ACodec::kWhatEOS);
+ notify->setInt32("what", CodecBase::kWhatEOS);
notify->setInt32("err", mCodec->mInputEOSResult);
notify->post();
@@ -3891,7 +3891,7 @@
"cannot keep component allocated on shutdown in Uninitialized state");
sp<AMessage> notify = mCodec->mNotify->dup();
- notify->setInt32("what", ACodec::kWhatShutdownCompleted);
+ notify->setInt32("what", CodecBase::kWhatShutdownCompleted);
notify->post();
handled = true;
@@ -3901,7 +3901,7 @@
case ACodec::kWhatFlush:
{
sp<AMessage> notify = mCodec->mNotify->dup();
- notify->setInt32("what", ACodec::kWhatFlushCompleted);
+ notify->setInt32("what", CodecBase::kWhatFlushCompleted);
notify->post();
handled = true;
@@ -4023,7 +4023,7 @@
{
sp<AMessage> notify = mCodec->mNotify->dup();
- notify->setInt32("what", ACodec::kWhatComponentAllocated);
+ notify->setInt32("what", CodecBase::kWhatComponentAllocated);
notify->setString("componentName", mCodec->mComponentName.c_str());
notify->post();
}
@@ -4073,7 +4073,7 @@
if (mCodec->mExplicitShutdown) {
sp<AMessage> notify = mCodec->mNotify->dup();
- notify->setInt32("what", ACodec::kWhatShutdownCompleted);
+ notify->setInt32("what", CodecBase::kWhatShutdownCompleted);
notify->post();
mCodec->mExplicitShutdown = false;
}
@@ -4120,7 +4120,7 @@
case ACodec::kWhatFlush:
{
sp<AMessage> notify = mCodec->mNotify->dup();
- notify->setInt32("what", ACodec::kWhatFlushCompleted);
+ notify->setInt32("what", CodecBase::kWhatFlushCompleted);
notify->post();
handled = true;
@@ -4169,7 +4169,7 @@
{
sp<AMessage> notify = mCodec->mNotify->dup();
- notify->setInt32("what", ACodec::kWhatComponentConfigured);
+ notify->setInt32("what", CodecBase::kWhatComponentConfigured);
notify->setMessage("input-format", mCodec->mInputFormat);
notify->setMessage("output-format", mCodec->mOutputFormat);
notify->post();
@@ -4183,7 +4183,7 @@
ALOGV("onCreateInputSurface");
sp<AMessage> notify = mCodec->mNotify->dup();
- notify->setInt32("what", ACodec::kWhatInputSurfaceCreated);
+ notify->setInt32("what", CodecBase::kWhatInputSurfaceCreated);
sp<IGraphicBufferProducer> bufferProducer;
status_t err;
@@ -4337,7 +4337,7 @@
{
// We haven't even started yet, so we're flushed alright...
sp<AMessage> notify = mCodec->mNotify->dup();
- notify->setInt32("what", ACodec::kWhatFlushCompleted);
+ notify->setInt32("what", CodecBase::kWhatFlushCompleted);
notify->post();
return true;
}
@@ -4398,7 +4398,7 @@
{
// We haven't even started yet, so we're flushed alright...
sp<AMessage> notify = mCodec->mNotify->dup();
- notify->setInt32("what", ACodec::kWhatFlushCompleted);
+ notify->setInt32("what", CodecBase::kWhatFlushCompleted);
notify->post();
return true;
@@ -4701,7 +4701,7 @@
void ACodec::onSignalEndOfInputStream() {
sp<AMessage> notify = mNotify->dup();
- notify->setInt32("what", ACodec::kWhatSignaledInputEOS);
+ notify->setInt32("what", CodecBase::kWhatSignaledInputEOS);
status_t err = mOMX->signalEndOfInputStream(mNode);
if (err != OK) {
@@ -5131,7 +5131,7 @@
mCodec->waitUntilAllPossibleNativeWindowBuffersAreReturnedToUs();
sp<AMessage> notify = mCodec->mNotify->dup();
- notify->setInt32("what", ACodec::kWhatFlushCompleted);
+ notify->setInt32("what", CodecBase::kWhatFlushCompleted);
notify->post();
mCodec->mPortEOS[kPortIndexInput] =
diff --git a/media/libstagefright/Android.mk b/media/libstagefright/Android.mk
index 11c5970..99c8e9f 100644
--- a/media/libstagefright/Android.mk
+++ b/media/libstagefright/Android.mk
@@ -15,6 +15,7 @@
CameraSource.cpp \
CameraSourceTimeLapse.cpp \
ClockEstimator.cpp \
+ CodecBase.cpp \
DataSource.cpp \
DataURISource.cpp \
DRMExtractor.cpp \
diff --git a/media/libstagefright/AwesomePlayer.cpp b/media/libstagefright/AwesomePlayer.cpp
index 63799e1..cd05c54 100644
--- a/media/libstagefright/AwesomePlayer.cpp
+++ b/media/libstagefright/AwesomePlayer.cpp
@@ -2949,6 +2949,7 @@
sp<IMediaHTTPService> savedHTTPService = mHTTPService;
+ bool wasLooping = mFlags & LOOPING;
// Reset and recreate
reset_l();
@@ -2967,6 +2968,9 @@
// a MEDIA_ERROR to the client and abort the prepare
mFlags |= PREPARE_CANCELLED;
}
+ if (wasLooping) {
+ mFlags |= LOOPING;
+ }
mAudioTearDown = true;
mIsAsyncPrepare = true;
diff --git a/media/libstagefright/CodecBase.cpp b/media/libstagefright/CodecBase.cpp
new file mode 100644
index 0000000..f729d4d
--- /dev/null
+++ b/media/libstagefright/CodecBase.cpp
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2014 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 "CodecBase"
+
+#include <inttypes.h>
+
+#include <media/stagefright/CodecBase.h>
+
+namespace android {
+
+CodecBase::CodecBase() {
+}
+
+CodecBase::~CodecBase() {
+}
+
+CodecBase::PortDescription::PortDescription() {
+}
+
+CodecBase::PortDescription::~PortDescription() {
+}
+
+} // namespace android
diff --git a/media/libstagefright/MediaCodec.cpp b/media/libstagefright/MediaCodec.cpp
index 14c8028..6e3d6f8 100644
--- a/media/libstagefright/MediaCodec.cpp
+++ b/media/libstagefright/MediaCodec.cpp
@@ -67,7 +67,7 @@
MediaCodec::MediaCodec(const sp<ALooper> &looper)
: mState(UNINITIALIZED),
mLooper(looper),
- mCodec(new ACodec),
+ mCodec(NULL),
mReplyID(0),
mFlags(0),
mSoftRenderer(NULL),
@@ -103,6 +103,7 @@
// quickly, violating the OpenMAX specs, until that is remedied
// we need to invest in an extra looper to free the main event
// queue.
+ mCodec = new ACodec;
bool needDedicatedLooper = false;
if (nameIsType && !strncasecmp(name, "video/", 6)) {
needDedicatedLooper = true;
@@ -541,7 +542,7 @@
CHECK(msg->findInt32("what", &what));
switch (what) {
- case ACodec::kWhatError:
+ case CodecBase::kWhatError:
{
int32_t omxError, internalError;
CHECK(msg->findInt32("omx-error", &omxError));
@@ -638,7 +639,7 @@
break;
}
- case ACodec::kWhatComponentAllocated:
+ case CodecBase::kWhatComponentAllocated:
{
CHECK_EQ(mState, INITIALIZING);
setState(INITIALIZED);
@@ -661,7 +662,7 @@
break;
}
- case ACodec::kWhatComponentConfigured:
+ case CodecBase::kWhatComponentConfigured:
{
CHECK_EQ(mState, CONFIGURING);
setState(CONFIGURED);
@@ -676,9 +677,9 @@
break;
}
- case ACodec::kWhatInputSurfaceCreated:
+ case CodecBase::kWhatInputSurfaceCreated:
{
- // response to ACodec::kWhatCreateInputSurface
+ // response to initiateCreateInputSurface()
status_t err = NO_ERROR;
sp<AMessage> response = new AMessage();
if (!msg->findInt32("err", &err)) {
@@ -694,9 +695,9 @@
break;
}
- case ACodec::kWhatSignaledInputEOS:
+ case CodecBase::kWhatSignaledInputEOS:
{
- // response to ACodec::kWhatSignalEndOfInputStream
+ // response to signalEndOfInputStream()
sp<AMessage> response = new AMessage();
status_t err;
if (msg->findInt32("err", &err)) {
@@ -707,7 +708,7 @@
}
- case ACodec::kWhatBuffersAllocated:
+ case CodecBase::kWhatBuffersAllocated:
{
int32_t portIndex;
CHECK(msg->findInt32("portIndex", &portIndex));
@@ -725,8 +726,8 @@
sp<RefBase> obj;
CHECK(msg->findObject("portDesc", &obj));
- sp<ACodec::PortDescription> portDesc =
- static_cast<ACodec::PortDescription *>(obj.get());
+ sp<CodecBase::PortDescription> portDesc =
+ static_cast<CodecBase::PortDescription *>(obj.get());
size_t numBuffers = portDesc->countBuffers();
@@ -759,7 +760,7 @@
break;
}
- case ACodec::kWhatOutputFormatChanged:
+ case CodecBase::kWhatOutputFormatChanged:
{
ALOGV("codec output format changed");
@@ -810,7 +811,7 @@
break;
}
- case ACodec::kWhatFillThisBuffer:
+ case CodecBase::kWhatFillThisBuffer:
{
/* size_t index = */updateBuffers(kPortIndexInput, msg);
@@ -857,7 +858,7 @@
break;
}
- case ACodec::kWhatDrainThisBuffer:
+ case CodecBase::kWhatDrainThisBuffer:
{
/* size_t index = */updateBuffers(kPortIndexOutput, msg);
@@ -908,14 +909,14 @@
break;
}
- case ACodec::kWhatEOS:
+ case CodecBase::kWhatEOS:
{
// We already notify the client of this by using the
// corresponding flag in "onOutputBufferReady".
break;
}
- case ACodec::kWhatShutdownCompleted:
+ case CodecBase::kWhatShutdownCompleted:
{
if (mState == STOPPING) {
setState(INITIALIZED);
@@ -928,7 +929,7 @@
break;
}
- case ACodec::kWhatFlushCompleted:
+ case CodecBase::kWhatFlushCompleted:
{
CHECK_EQ(mState, FLUSHING);
setState(STARTED);
diff --git a/media/libstagefright/codecs/m4v_h263/enc/SoftMPEG4Encoder.cpp b/media/libstagefright/codecs/m4v_h263/enc/SoftMPEG4Encoder.cpp
index e25709d..42c9956 100644
--- a/media/libstagefright/codecs/m4v_h263/enc/SoftMPEG4Encoder.cpp
+++ b/media/libstagefright/codecs/m4v_h263/enc/SoftMPEG4Encoder.cpp
@@ -721,7 +721,7 @@
vin.uChan = vin.yChan + vin.height * vin.pitch;
vin.vChan = vin.uChan + ((vin.height * vin.pitch) >> 2);
- unsigned long modTimeMs = 0;
+ ULong modTimeMs = 0;
int32_t nLayer = 0;
MP4HintTrack hintTrack;
if (!PVEncodeVideoFrame(mHandle, &vin, &vout,
diff --git a/media/libstagefright/codecs/m4v_h263/enc/include/mp4enc_api.h b/media/libstagefright/codecs/m4v_h263/enc/include/mp4enc_api.h
index a54fd8b..9451479 100644
--- a/media/libstagefright/codecs/m4v_h263/enc/include/mp4enc_api.h
+++ b/media/libstagefright/codecs/m4v_h263/enc/include/mp4enc_api.h
@@ -29,7 +29,7 @@
typedef unsigned short UShort;
typedef short Short;
typedef unsigned int Bool;
-typedef unsigned long ULong;
+typedef uint32_t ULong;
#define PV_CODEC_INIT 0
#define PV_CODEC_STOP 1
diff --git a/media/libstagefright/codecs/m4v_h263/enc/src/motion_comp.cpp b/media/libstagefright/codecs/m4v_h263/enc/src/motion_comp.cpp
index 06e8926..9a967c2 100644
--- a/media/libstagefright/codecs/m4v_h263/enc/src/motion_comp.cpp
+++ b/media/libstagefright/codecs/m4v_h263/enc/src/motion_comp.cpp
@@ -363,7 +363,7 @@
/* initialize offset to adjust pixel counter */
/* the next row; full-pel resolution */
- tmp = (ULong)prev & 0x3;
+ tmp = (uintptr_t)prev & 0x3;
if (tmp == 0) /* word-aligned */
{
@@ -466,7 +466,7 @@
/* Branch based on pixel location (half-pel or full-pel) for x and y */
rec -= 12; /* preset */
- tmp = (ULong)prev & 3;
+ tmp = (uintptr_t)prev & 3;
mask = 254;
mask |= (mask << 8);
mask |= (mask << 16); /* 0xFEFEFEFE */
@@ -791,7 +791,7 @@
/* Branch based on pixel location (half-pel or full-pel) for x and y */
rec -= 12; /* preset */
- tmp = (ULong)prev & 3;
+ tmp = (uintptr_t)prev & 3;
mask = 254;
mask |= (mask << 8);
mask |= (mask << 16); /* 0xFEFEFEFE */
@@ -1140,7 +1140,7 @@
mask |= (mask << 8);
mask |= (mask << 16); /* 0x3f3f3f3f */
- tmp = (ULong)prev & 3;
+ tmp = (uintptr_t)prev & 3;
rec -= 4; /* preset */
diff --git a/media/libstagefright/codecs/m4v_h263/enc/src/mp4def.h b/media/libstagefright/codecs/m4v_h263/enc/src/mp4def.h
index 0d5a3e8..2d44482 100644
--- a/media/libstagefright/codecs/m4v_h263/enc/src/mp4def.h
+++ b/media/libstagefright/codecs/m4v_h263/enc/src/mp4def.h
@@ -60,7 +60,7 @@
typedef short Short;
typedef short int SInt;
typedef unsigned int Bool;
-typedef unsigned long ULong;
+typedef uint32_t ULong;
typedef void Void;
#define PV_CODEC_INIT 0
diff --git a/media/libstagefright/foundation/ABitReader.cpp b/media/libstagefright/foundation/ABitReader.cpp
index 5499c32..beb5cc0 100644
--- a/media/libstagefright/foundation/ABitReader.cpp
+++ b/media/libstagefright/foundation/ABitReader.cpp
@@ -27,6 +27,9 @@
mNumBitsLeft(0) {
}
+ABitReader::~ABitReader() {
+}
+
void ABitReader::fillReservoir() {
CHECK_GT(mSize, 0u);
@@ -99,4 +102,69 @@
return mData - (mNumBitsLeft + 7) / 8;
}
+NALBitReader::NALBitReader(const uint8_t *data, size_t size)
+ : ABitReader(data, size),
+ mNumZeros(0) {
+}
+
+bool NALBitReader::atLeastNumBitsLeft(size_t n) const {
+ // check against raw size and reservoir bits first
+ size_t numBits = numBitsLeft();
+ if (n > numBits) {
+ return false;
+ }
+
+ ssize_t numBitsRemaining = n - mNumBitsLeft;
+
+ size_t size = mSize;
+ const uint8_t *data = mData;
+ int32_t numZeros = mNumZeros;
+ while (size > 0 && numBitsRemaining > 0) {
+ bool isEmulationPreventionByte = (numZeros >= 2 && *data == 3);
+
+ if (*data == 0) {
+ ++numZeros;
+ } else {
+ numZeros = 0;
+ }
+
+ if (!isEmulationPreventionByte) {
+ numBitsRemaining -= 8;
+ }
+
+ ++data;
+ --size;
+ }
+
+ return (numBitsRemaining <= 0);
+}
+
+void NALBitReader::fillReservoir() {
+ CHECK_GT(mSize, 0u);
+
+ mReservoir = 0;
+ size_t i = 0;
+ while (mSize > 0 && i < 4) {
+ bool isEmulationPreventionByte = (mNumZeros >= 2 && *mData == 3);
+
+ if (*mData == 0) {
+ ++mNumZeros;
+ } else {
+ mNumZeros = 0;
+ }
+
+ // skip emulation_prevention_three_byte
+ if (!isEmulationPreventionByte) {
+ mReservoir = (mReservoir << 8) | *mData;
+ ++i;
+ }
+
+ ++mData;
+ --mSize;
+ }
+
+ mNumBitsLeft = 8 * i;
+ mReservoir <<= 32 - mNumBitsLeft;
+}
+
} // namespace android
diff --git a/media/libstagefright/foundation/AHierarchicalStateMachine.cpp b/media/libstagefright/foundation/AHierarchicalStateMachine.cpp
index f7a00d8..5f7c70d 100644
--- a/media/libstagefright/foundation/AHierarchicalStateMachine.cpp
+++ b/media/libstagefright/foundation/AHierarchicalStateMachine.cpp
@@ -51,7 +51,7 @@
AHierarchicalStateMachine::~AHierarchicalStateMachine() {
}
-void AHierarchicalStateMachine::onMessageReceived(const sp<AMessage> &msg) {
+void AHierarchicalStateMachine::handleMessage(const sp<AMessage> &msg) {
sp<AState> save = mState;
sp<AState> cur = mState;
diff --git a/media/libstagefright/foundation/AString.cpp b/media/libstagefright/foundation/AString.cpp
index f2d501e..894f65c 100644
--- a/media/libstagefright/foundation/AString.cpp
+++ b/media/libstagefright/foundation/AString.cpp
@@ -328,6 +328,20 @@
return !strcmp(mData + mSize - suffixLen, suffix);
}
+bool AString::startsWithIgnoreCase(const char *prefix) const {
+ return !strncasecmp(mData, prefix, strlen(prefix));
+}
+
+bool AString::endsWithIgnoreCase(const char *suffix) const {
+ size_t suffixLen = strlen(suffix);
+
+ if (mSize < suffixLen) {
+ return false;
+ }
+
+ return !strcasecmp(mData + mSize - suffixLen, suffix);
+}
+
AString StringPrintf(const char *format, ...) {
va_list ap;
va_start(ap, format);
diff --git a/media/libstagefright/httplive/PlaylistFetcher.cpp b/media/libstagefright/httplive/PlaylistFetcher.cpp
index 2af0998..10437c9 100644
--- a/media/libstagefright/httplive/PlaylistFetcher.cpp
+++ b/media/libstagefright/httplive/PlaylistFetcher.cpp
@@ -588,7 +588,10 @@
void PlaylistFetcher::queueDiscontinuity(
ATSParser::DiscontinuityType type, const sp<AMessage> &extra) {
for (size_t i = 0; i < mPacketSources.size(); ++i) {
- mPacketSources.valueAt(i)->queueDiscontinuity(type, extra);
+ // do not discard buffer upon #EXT-X-DISCONTINUITY tag
+ // (seek will discard buffer by abandoning old fetchers)
+ mPacketSources.valueAt(i)->queueDiscontinuity(
+ type, extra, false /* discard */);
}
}
@@ -723,8 +726,7 @@
firstSeqNumberInPlaylist = 0;
}
- bool seekDiscontinuity = false;
- bool explicitDiscontinuity = false;
+ bool discontinuity = false;
const int32_t lastSeqNumberInPlaylist =
firstSeqNumberInPlaylist + (int32_t)mPlaylist->size() - 1;
@@ -792,7 +794,7 @@
if (mSeqNumber < firstSeqNumberInPlaylist) {
mSeqNumber = firstSeqNumberInPlaylist;
}
- explicitDiscontinuity = true;
+ discontinuity = true;
// fall through
} else {
@@ -817,7 +819,7 @@
int32_t val;
if (itemMeta->findInt32("discontinuity", &val) && val != 0) {
- explicitDiscontinuity = true;
+ discontinuity = true;
}
int64_t range_offset, range_length;
@@ -877,7 +879,7 @@
return;
}
- if (mStartup || seekDiscontinuity || explicitDiscontinuity) {
+ if (mStartup || discontinuity) {
// Signal discontinuity.
if (mPlaylist->isComplete() || mPlaylist->isEvent()) {
@@ -887,18 +889,14 @@
mNextPTSTimeUs = getSegmentStartTimeUs(mSeqNumber);
}
- if (seekDiscontinuity || explicitDiscontinuity) {
- ALOGI("queueing discontinuity (seek=%d, explicit=%d)",
- seekDiscontinuity, explicitDiscontinuity);
+ if (discontinuity) {
+ ALOGI("queueing discontinuity (explicit=%d)", discontinuity);
queueDiscontinuity(
- explicitDiscontinuity
- ? ATSParser::DISCONTINUITY_FORMATCHANGE
- : ATSParser::DISCONTINUITY_SEEK,
+ ATSParser::DISCONTINUITY_FORMATCHANGE,
NULL /* extra */);
- seekDiscontinuity = false;
- explicitDiscontinuity = false;
+ discontinuity = false;
}
}
diff --git a/media/libstagefright/mpeg2ts/ATSParser.cpp b/media/libstagefright/mpeg2ts/ATSParser.cpp
index 338e899..3d241e0 100644
--- a/media/libstagefright/mpeg2ts/ATSParser.cpp
+++ b/media/libstagefright/mpeg2ts/ATSParser.cpp
@@ -669,7 +669,7 @@
}
if (mSource != NULL) {
- mSource->queueDiscontinuity(type, extra);
+ mSource->queueDiscontinuity(type, extra, true);
}
}
diff --git a/media/libstagefright/mpeg2ts/AnotherPacketSource.cpp b/media/libstagefright/mpeg2ts/AnotherPacketSource.cpp
index 021b640..871824a 100644
--- a/media/libstagefright/mpeg2ts/AnotherPacketSource.cpp
+++ b/media/libstagefright/mpeg2ts/AnotherPacketSource.cpp
@@ -217,22 +217,25 @@
void AnotherPacketSource::queueDiscontinuity(
ATSParser::DiscontinuityType type,
- const sp<AMessage> &extra) {
+ const sp<AMessage> &extra,
+ bool discard) {
Mutex::Autolock autoLock(mLock);
- // Leave only discontinuities in the queue.
- List<sp<ABuffer> >::iterator it = mBuffers.begin();
- while (it != mBuffers.end()) {
- sp<ABuffer> oldBuffer = *it;
+ if (discard) {
+ // Leave only discontinuities in the queue.
+ List<sp<ABuffer> >::iterator it = mBuffers.begin();
+ while (it != mBuffers.end()) {
+ sp<ABuffer> oldBuffer = *it;
- int32_t oldDiscontinuityType;
- if (!oldBuffer->meta()->findInt32(
- "discontinuity", &oldDiscontinuityType)) {
- it = mBuffers.erase(it);
- continue;
+ int32_t oldDiscontinuityType;
+ if (!oldBuffer->meta()->findInt32(
+ "discontinuity", &oldDiscontinuityType)) {
+ it = mBuffers.erase(it);
+ continue;
+ }
+
+ ++it;
}
-
- ++it;
}
mEOSResult = OK;
diff --git a/media/libstagefright/mpeg2ts/AnotherPacketSource.h b/media/libstagefright/mpeg2ts/AnotherPacketSource.h
index 9b193a2..06c49bd 100644
--- a/media/libstagefright/mpeg2ts/AnotherPacketSource.h
+++ b/media/libstagefright/mpeg2ts/AnotherPacketSource.h
@@ -54,7 +54,9 @@
void queueAccessUnit(const sp<ABuffer> &buffer);
void queueDiscontinuity(
- ATSParser::DiscontinuityType type, const sp<AMessage> &extra);
+ ATSParser::DiscontinuityType type,
+ const sp<AMessage> &extra,
+ bool discard);
void signalEOS(status_t result);
diff --git a/services/audioflinger/AudioMixer.cpp b/services/audioflinger/AudioMixer.cpp
index af312c4..4dbbc43 100644
--- a/services/audioflinger/AudioMixer.cpp
+++ b/services/audioflinger/AudioMixer.cpp
@@ -763,21 +763,9 @@
quality = AudioResampler::DEFAULT_QUALITY;
}
- int bits;
- switch (mMixerInFormat) {
- case AUDIO_FORMAT_PCM_16_BIT:
- bits = 16;
- break;
- case AUDIO_FORMAT_PCM_FLOAT:
- bits = 32; // 32 bits to the AudioResampler::create() indicates float.
- break;
- default:
- LOG_ALWAYS_FATAL("Invalid mMixerInFormat: %#x", mMixerInFormat);
- break;
- }
ALOGVV("Creating resampler with %d bits\n", bits);
resampler = AudioResampler::create(
- bits,
+ mMixerInFormat,
// the resampler sees the number of channels after the downmixer, if any
(int) (downmixerBufferProvider != NULL ? MAX_NUM_CHANNELS : channelCount),
devSampleRate, quality);
diff --git a/services/audioflinger/AudioResampler.cpp b/services/audioflinger/AudioResampler.cpp
index b8a0357..38c9061 100644
--- a/services/audioflinger/AudioResampler.cpp
+++ b/services/audioflinger/AudioResampler.cpp
@@ -40,8 +40,8 @@
class AudioResamplerOrder1 : public AudioResampler {
public:
- AudioResamplerOrder1(int bitDepth, int inChannelCount, int32_t sampleRate) :
- AudioResampler(bitDepth, inChannelCount, sampleRate, LOW_QUALITY), mX0L(0), mX0R(0) {
+ AudioResamplerOrder1(int inChannelCount, int32_t sampleRate) :
+ AudioResampler(inChannelCount, sampleRate, LOW_QUALITY), mX0L(0), mX0R(0) {
}
virtual void resample(int32_t* out, size_t outFrameCount,
AudioBufferProvider* provider);
@@ -145,7 +145,7 @@
static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
static uint32_t currentMHz = 0;
-AudioResampler* AudioResampler::create(int bitDepth, int inChannelCount,
+AudioResampler* AudioResampler::create(audio_format_t format, int inChannelCount,
int32_t sampleRate, src_quality quality) {
bool atFinalQuality;
@@ -216,33 +216,40 @@
default:
case LOW_QUALITY:
ALOGV("Create linear Resampler");
- resampler = new AudioResamplerOrder1(bitDepth, inChannelCount, sampleRate);
+ LOG_ALWAYS_FATAL_IF(format != AUDIO_FORMAT_PCM_16_BIT);
+ resampler = new AudioResamplerOrder1(inChannelCount, sampleRate);
break;
case MED_QUALITY:
ALOGV("Create cubic Resampler");
- resampler = new AudioResamplerCubic(bitDepth, inChannelCount, sampleRate);
+ LOG_ALWAYS_FATAL_IF(format != AUDIO_FORMAT_PCM_16_BIT);
+ resampler = new AudioResamplerCubic(inChannelCount, sampleRate);
break;
case HIGH_QUALITY:
ALOGV("Create HIGH_QUALITY sinc Resampler");
- resampler = new AudioResamplerSinc(bitDepth, inChannelCount, sampleRate);
+ LOG_ALWAYS_FATAL_IF(format != AUDIO_FORMAT_PCM_16_BIT);
+ resampler = new AudioResamplerSinc(inChannelCount, sampleRate);
break;
case VERY_HIGH_QUALITY:
ALOGV("Create VERY_HIGH_QUALITY sinc Resampler = %d", quality);
- resampler = new AudioResamplerSinc(bitDepth, inChannelCount, sampleRate, quality);
+ LOG_ALWAYS_FATAL_IF(format != AUDIO_FORMAT_PCM_16_BIT);
+ resampler = new AudioResamplerSinc(inChannelCount, sampleRate, quality);
break;
case DYN_LOW_QUALITY:
case DYN_MED_QUALITY:
case DYN_HIGH_QUALITY:
ALOGV("Create dynamic Resampler = %d", quality);
- if (bitDepth == 32) { /* bitDepth == 32 signals float precision */
- resampler = new AudioResamplerDyn<float, float, float>(bitDepth, inChannelCount,
- sampleRate, quality);
- } else if (quality == DYN_HIGH_QUALITY) {
- resampler = new AudioResamplerDyn<int32_t, int16_t, int32_t>(bitDepth, inChannelCount,
+ if (format == AUDIO_FORMAT_PCM_FLOAT) {
+ resampler = new AudioResamplerDyn<float, float, float>(inChannelCount,
sampleRate, quality);
} else {
- resampler = new AudioResamplerDyn<int16_t, int16_t, int32_t>(bitDepth, inChannelCount,
- sampleRate, quality);
+ LOG_ALWAYS_FATAL_IF(format != AUDIO_FORMAT_PCM_16_BIT);
+ if (quality == DYN_HIGH_QUALITY) {
+ resampler = new AudioResamplerDyn<int32_t, int16_t, int32_t>(inChannelCount,
+ sampleRate, quality);
+ } else {
+ resampler = new AudioResamplerDyn<int16_t, int16_t, int32_t>(inChannelCount,
+ sampleRate, quality);
+ }
}
break;
}
@@ -252,18 +259,17 @@
return resampler;
}
-AudioResampler::AudioResampler(int bitDepth, int inChannelCount,
+AudioResampler::AudioResampler(int inChannelCount,
int32_t sampleRate, src_quality quality) :
- mBitDepth(bitDepth), mChannelCount(inChannelCount),
- mSampleRate(sampleRate), mInSampleRate(sampleRate), mInputIndex(0),
- mPhaseFraction(0), mLocalTimeFreq(0),
- mPTS(AudioBufferProvider::kInvalidPTS), mQuality(quality) {
- // sanity check on format
- if ((bitDepth != 16 && (quality < DYN_LOW_QUALITY || bitDepth != 32))
- || inChannelCount < 1
+ mChannelCount(inChannelCount),
+ mSampleRate(sampleRate), mInSampleRate(sampleRate), mInputIndex(0),
+ mPhaseFraction(0), mLocalTimeFreq(0),
+ mPTS(AudioBufferProvider::kInvalidPTS), mQuality(quality) {
+
+ if (inChannelCount < 1
|| inChannelCount > (quality < DYN_LOW_QUALITY ? 2 : 8)) {
- LOG_ALWAYS_FATAL("Unsupported sample format %d quality %d bits, %d channels",
- quality, bitDepth, inChannelCount);
+ LOG_ALWAYS_FATAL("Unsupported sample format %d quality %d channels",
+ quality, inChannelCount);
}
if (sampleRate <= 0) {
LOG_ALWAYS_FATAL("Unsupported sample rate %d Hz", sampleRate);
@@ -272,7 +278,6 @@
// initialize common members
mVolume[0] = mVolume[1] = 0;
mBuffer.frameCount = 0;
-
}
AudioResampler::~AudioResampler() {
diff --git a/services/audioflinger/AudioResampler.h b/services/audioflinger/AudioResampler.h
index b84567e..be747f6 100644
--- a/services/audioflinger/AudioResampler.h
+++ b/services/audioflinger/AudioResampler.h
@@ -22,6 +22,7 @@
#include <cutils/compiler.h>
#include <media/AudioBufferProvider.h>
+#include <system/audio.h>
namespace android {
// ----------------------------------------------------------------------------
@@ -46,7 +47,7 @@
DYN_HIGH_QUALITY=7,
};
- static AudioResampler* create(int bitDepth, int inChannelCount,
+ static AudioResampler* create(audio_format_t format, int inChannelCount,
int32_t sampleRate, src_quality quality=DEFAULT_QUALITY);
virtual ~AudioResampler();
@@ -86,7 +87,7 @@
// multiplier to calculate fixed point phase increment
static const double kPhaseMultiplier;
- AudioResampler(int bitDepth, int inChannelCount, int32_t sampleRate, src_quality quality);
+ AudioResampler(int inChannelCount, int32_t sampleRate, src_quality quality);
// prevent copying
AudioResampler(const AudioResampler&);
@@ -94,7 +95,6 @@
int64_t calculateOutputPTS(int outputFrameIndex);
- const int32_t mBitDepth;
const int32_t mChannelCount;
const int32_t mSampleRate;
int32_t mInSampleRate;
diff --git a/services/audioflinger/AudioResamplerCubic.h b/services/audioflinger/AudioResamplerCubic.h
index 203b933..b315da5 100644
--- a/services/audioflinger/AudioResamplerCubic.h
+++ b/services/audioflinger/AudioResamplerCubic.h
@@ -28,8 +28,8 @@
class AudioResamplerCubic : public AudioResampler {
public:
- AudioResamplerCubic(int bitDepth, int inChannelCount, int32_t sampleRate) :
- AudioResampler(bitDepth, inChannelCount, sampleRate, MED_QUALITY) {
+ AudioResamplerCubic(int inChannelCount, int32_t sampleRate) :
+ AudioResampler(inChannelCount, sampleRate, MED_QUALITY) {
}
virtual void resample(int32_t* out, size_t outFrameCount,
AudioBufferProvider* provider);
diff --git a/services/audioflinger/AudioResamplerDyn.cpp b/services/audioflinger/AudioResamplerDyn.cpp
index 7ca10c1..043c803 100644
--- a/services/audioflinger/AudioResamplerDyn.cpp
+++ b/services/audioflinger/AudioResamplerDyn.cpp
@@ -162,9 +162,9 @@
}
template<typename TC, typename TI, typename TO>
-AudioResamplerDyn<TC, TI, TO>::AudioResamplerDyn(int bitDepth,
+AudioResamplerDyn<TC, TI, TO>::AudioResamplerDyn(
int inChannelCount, int32_t sampleRate, src_quality quality)
- : AudioResampler(bitDepth, inChannelCount, sampleRate, quality),
+ : AudioResampler(inChannelCount, sampleRate, quality),
mResampleFunc(0), mFilterSampleRate(0), mFilterQuality(DEFAULT_QUALITY),
mCoefBuffer(NULL)
{
diff --git a/services/audioflinger/AudioResamplerDyn.h b/services/audioflinger/AudioResamplerDyn.h
index 3dced8a..3044bfb 100644
--- a/services/audioflinger/AudioResamplerDyn.h
+++ b/services/audioflinger/AudioResamplerDyn.h
@@ -41,7 +41,7 @@
template<typename TC, typename TI, typename TO>
class AudioResamplerDyn: public AudioResampler {
public:
- AudioResamplerDyn(int bitDepth, int inChannelCount,
+ AudioResamplerDyn(int inChannelCount,
int32_t sampleRate, src_quality quality);
virtual ~AudioResamplerDyn();
diff --git a/services/audioflinger/AudioResamplerSinc.cpp b/services/audioflinger/AudioResamplerSinc.cpp
index 35553ef..60ff88e 100644
--- a/services/audioflinger/AudioResamplerSinc.cpp
+++ b/services/audioflinger/AudioResamplerSinc.cpp
@@ -452,9 +452,9 @@
// ----------------------------------------------------------------------------
-AudioResamplerSinc::AudioResamplerSinc(int bitDepth,
+AudioResamplerSinc::AudioResamplerSinc(
int inChannelCount, int32_t sampleRate, src_quality quality)
- : AudioResampler(bitDepth, inChannelCount, sampleRate, quality),
+ : AudioResampler(inChannelCount, sampleRate, quality),
mState(0), mImpulse(0), mRingFull(0), mFirCoefs(0)
{
/*
diff --git a/services/audioflinger/AudioResamplerSinc.h b/services/audioflinger/AudioResamplerSinc.h
index 1ea4474..97ae3d0 100644
--- a/services/audioflinger/AudioResamplerSinc.h
+++ b/services/audioflinger/AudioResamplerSinc.h
@@ -34,7 +34,7 @@
class AudioResamplerSinc : public AudioResampler {
public:
- AudioResamplerSinc(int bitDepth, int inChannelCount, int32_t sampleRate,
+ AudioResamplerSinc(int inChannelCount, int32_t sampleRate,
src_quality quality = HIGH_QUALITY);
virtual ~AudioResamplerSinc();
diff --git a/services/audioflinger/Tracks.cpp b/services/audioflinger/Tracks.cpp
index 4fbb973..0ef9fe5 100644
--- a/services/audioflinger/Tracks.cpp
+++ b/services/audioflinger/Tracks.cpp
@@ -1895,7 +1895,8 @@
if (thread->mSampleRate != sampleRate && thread->mChannelCount <= FCC_2 &&
channelCount <= FCC_2) {
// sink SR
- mResampler = AudioResampler::create(16, thread->mChannelCount, sampleRate);
+ mResampler = AudioResampler::create(AUDIO_FORMAT_PCM_16_BIT,
+ thread->mChannelCount, sampleRate);
// source SR
mResampler->setSampleRate(thread->mSampleRate);
mResampler->setVolume(AudioMixer::UNITY_GAIN_INT, AudioMixer::UNITY_GAIN_INT);
diff --git a/services/audioflinger/test-resample.cpp b/services/audioflinger/test-resample.cpp
index e14b4ae..78c9927 100644
--- a/services/audioflinger/test-resample.cpp
+++ b/services/audioflinger/test-resample.cpp
@@ -14,8 +14,6 @@
* limitations under the License.
*/
-#include "AudioResampler.h"
-#include <media/AudioBufferProvider.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
@@ -30,6 +28,8 @@
#include <audio_utils/primitives.h>
#include <audio_utils/sndfile.h>
#include <utils/Vector.h>
+#include <media/AudioBufferProvider.h>
+#include "AudioResampler.h"
using namespace android;
@@ -329,7 +329,7 @@
printf("%zu input frames\n", input_frames);
}
- int bit_depth = useFloat ? 32 : 16;
+ audio_format_t format = useFloat ? AUDIO_FORMAT_PCM_FLOAT : AUDIO_FORMAT_PCM_16_BIT;
int output_channels = channels > 2 ? channels : 2; // output is at least stereo samples
size_t output_framesize = output_channels * (useFloat ? sizeof(float) : sizeof(int32_t));
size_t output_frames = ((int64_t) input_frames * output_freq) / input_freq;
@@ -342,7 +342,7 @@
//
// On fast devices, filters should be generated between 0.1ms - 1ms.
// (single threaded).
- AudioResampler* resampler = AudioResampler::create(bit_depth, channels,
+ AudioResampler* resampler = AudioResampler::create(format, channels,
8000, quality);
int looplimit = 100;
timespec start, end;
@@ -380,7 +380,7 @@
}
void* output_vaddr = malloc(output_size);
- AudioResampler* resampler = AudioResampler::create(bit_depth, channels,
+ AudioResampler* resampler = AudioResampler::create(format, channels,
output_freq, quality);
diff --git a/services/audioflinger/tests/resampler_tests.cpp b/services/audioflinger/tests/resampler_tests.cpp
index d76c376..987162c 100644
--- a/services/audioflinger/tests/resampler_tests.cpp
+++ b/services/audioflinger/tests/resampler_tests.cpp
@@ -69,7 +69,7 @@
unsigned inputFreq, unsigned outputFreq,
enum android::AudioResampler::src_quality quality)
{
- const int bits = useFloat ? 32 : 16;
+ const audio_format_t format = useFloat ? AUDIO_FORMAT_PCM_FLOAT : AUDIO_FORMAT_PCM_16_BIT;
// create the provider
std::vector<int> inputIncr;
SignalProvider provider;
@@ -92,7 +92,7 @@
const int volumePrecision = 12; /* typical unity gain */
android::AudioResampler* resampler;
- resampler = android::AudioResampler::create(bits, channels, outputFreq, quality);
+ resampler = android::AudioResampler::create(format, channels, outputFreq, quality);
resampler->setSampleRate(inputFreq);
resampler->setVolume(1 << volumePrecision, 1 << volumePrecision);
@@ -109,7 +109,7 @@
resampler->reset();
#else
delete resampler;
- resampler = android::AudioResampler::create(bits, channels, outputFreq, quality);
+ resampler = android::AudioResampler::create(format, channels, outputFreq, quality);
resampler->setSampleRate(inputFreq);
resampler->setVolume(1 << volumePrecision, 1 << volumePrecision);
#endif
@@ -174,7 +174,8 @@
const int volumePrecision = 12; /* typical unity gain */
android::AudioResampler* resampler;
- resampler = android::AudioResampler::create(16, channels, outputFreq, quality);
+ resampler = android::AudioResampler::create(AUDIO_FORMAT_PCM_16_BIT,
+ channels, outputFreq, quality);
resampler->setSampleRate(inputFreq);
resampler->setVolume(1 << volumePrecision, 1 << volumePrecision);
diff --git a/services/audiopolicy/AudioPolicyManager.cpp b/services/audiopolicy/AudioPolicyManager.cpp
index 95179b7..bb3bce8 100644
--- a/services/audiopolicy/AudioPolicyManager.cpp
+++ b/services/audiopolicy/AudioPolicyManager.cpp
@@ -101,6 +101,7 @@
STRING_TO_ENUM(AUDIO_DEVICE_IN_LINE),
STRING_TO_ENUM(AUDIO_DEVICE_IN_SPDIF),
STRING_TO_ENUM(AUDIO_DEVICE_IN_BLUETOOTH_A2DP),
+ STRING_TO_ENUM(AUDIO_DEVICE_IN_LOOPBACK),
};
const StringToEnum sFlagNameToEnumTable[] = {
@@ -4104,7 +4105,7 @@
const AudioPolicyManager::VolumeCurvePoint
AudioPolicyManager::sSpeakerMediaVolumeCurveDrc[AudioPolicyManager::VOLCNT] = {
- {1, -56.0f}, {20, -34.0f}, {86, -10.0f}, {100, 0.0f}
+ {1, -55.0f}, {20, -43.0f}, {86, -12.0f}, {100, 0.0f}
};
const AudioPolicyManager::VolumeCurvePoint
diff --git a/services/camera/libcameraservice/api1/client2/StreamingProcessor.cpp b/services/camera/libcameraservice/api1/client2/StreamingProcessor.cpp
index 99abced..911f55a 100644
--- a/services/camera/libcameraservice/api1/client2/StreamingProcessor.cpp
+++ b/services/camera/libcameraservice/api1/client2/StreamingProcessor.cpp
@@ -89,8 +89,26 @@
Mutex::Autolock m(mMutex);
if (mPreviewRequest.entryCount() == 0) {
- res = device->createDefaultRequest(CAMERA2_TEMPLATE_PREVIEW,
- &mPreviewRequest);
+ sp<Camera2Client> client = mClient.promote();
+ if (client == 0) {
+ ALOGE("%s: Camera %d: Client does not exist", __FUNCTION__, mId);
+ return INVALID_OPERATION;
+ }
+
+ // Use CAMERA3_TEMPLATE_ZERO_SHUTTER_LAG for ZSL streaming case.
+ if (client->getCameraDeviceVersion() >= CAMERA_DEVICE_API_VERSION_3_0) {
+ if (params.zslMode && !params.recordingHint) {
+ res = device->createDefaultRequest(CAMERA3_TEMPLATE_ZERO_SHUTTER_LAG,
+ &mPreviewRequest);
+ } else {
+ res = device->createDefaultRequest(CAMERA3_TEMPLATE_PREVIEW,
+ &mPreviewRequest);
+ }
+ } else {
+ res = device->createDefaultRequest(CAMERA2_TEMPLATE_PREVIEW,
+ &mPreviewRequest);
+ }
+
if (res != OK) {
ALOGE("%s: Camera %d: Unable to create default preview request: "
"%s (%d)", __FUNCTION__, mId, strerror(-res), res);
diff --git a/services/camera/libcameraservice/api1/client2/ZslProcessor3.cpp b/services/camera/libcameraservice/api1/client2/ZslProcessor3.cpp
index ae537e2..79f75a5 100644
--- a/services/camera/libcameraservice/api1/client2/ZslProcessor3.cpp
+++ b/services/camera/libcameraservice/api1/client2/ZslProcessor3.cpp
@@ -290,18 +290,45 @@
uint8_t requestType = ANDROID_REQUEST_TYPE_REPROCESS;
res = request.update(ANDROID_REQUEST_TYPE,
&requestType, 1);
+ if (res != OK) {
+ ALOGE("%s: Unable to update request type",
+ __FUNCTION__);
+ return INVALID_OPERATION;
+ }
+
int32_t inputStreams[1] =
{ mZslStreamId };
- if (res == OK) request.update(ANDROID_REQUEST_INPUT_STREAMS,
+ res = request.update(ANDROID_REQUEST_INPUT_STREAMS,
inputStreams, 1);
+ if (res != OK) {
+ ALOGE("%s: Unable to update request input streams",
+ __FUNCTION__);
+ return INVALID_OPERATION;
+ }
+
+ uint8_t captureIntent =
+ static_cast<uint8_t>(ANDROID_CONTROL_CAPTURE_INTENT_STILL_CAPTURE);
+ res = request.update(ANDROID_CONTROL_CAPTURE_INTENT,
+ &captureIntent, 1);
+ if (res != OK ) {
+ ALOGE("%s: Unable to update request capture intent",
+ __FUNCTION__);
+ return INVALID_OPERATION;
+ }
+
// TODO: Shouldn't we also update the latest preview frame?
int32_t outputStreams[1] =
{ client->getCaptureStreamId() };
- if (res == OK) request.update(ANDROID_REQUEST_OUTPUT_STREAMS,
+ res = request.update(ANDROID_REQUEST_OUTPUT_STREAMS,
outputStreams, 1);
+ if (res != OK) {
+ ALOGE("%s: Unable to update request output streams",
+ __FUNCTION__);
+ return INVALID_OPERATION;
+ }
+
res = request.update(ANDROID_REQUEST_ID,
&requestId, 1);
-
if (res != OK ) {
ALOGE("%s: Unable to update frame to a reprocess request",
__FUNCTION__);
diff --git a/services/camera/libcameraservice/common/CameraDeviceBase.h b/services/camera/libcameraservice/common/CameraDeviceBase.h
index 7597b10..c7bd886 100644
--- a/services/camera/libcameraservice/common/CameraDeviceBase.h
+++ b/services/camera/libcameraservice/common/CameraDeviceBase.h
@@ -26,6 +26,7 @@
#include <camera/camera2/ICameraDeviceCallbacks.h>
#include "hardware/camera2.h"
+#include "hardware/camera3.h"
#include "camera/CameraMetadata.h"
#include "camera/CaptureResult.h"
diff --git a/services/camera/libcameraservice/device3/Camera3Device.cpp b/services/camera/libcameraservice/device3/Camera3Device.cpp
index bbb1e1c..6ceb9d4 100644
--- a/services/camera/libcameraservice/device3/Camera3Device.cpp
+++ b/services/camera/libcameraservice/device3/Camera3Device.cpp
@@ -1929,11 +1929,11 @@
ALOGE("%s: RequestThread: Can't return input buffer for frame %d to"
" its stream:%s (%d)", __FUNCTION__,
frameNumber, strerror(-res), res);
- } else {
- ALOGW("%s: Input buffer should be NULL if there is no input"
- " buffer sent in the request",
- __FUNCTION__);
- }
+ }
+ } else {
+ ALOGW("%s: Input buffer should be NULL if there is no input"
+ " buffer sent in the request, skipping input buffer return.",
+ __FUNCTION__);
}
}
diff --git a/services/soundtrigger/SoundTriggerHwService.cpp b/services/soundtrigger/SoundTriggerHwService.cpp
index fa59388..747af79 100644
--- a/services/soundtrigger/SoundTriggerHwService.cpp
+++ b/services/soundtrigger/SoundTriggerHwService.cpp
@@ -377,7 +377,7 @@
}
status_t SoundTriggerHwService::Module::startRecognition(sound_model_handle_t handle,
- const sp<IMemory>& dataMemory)
+ const sp<IMemory>& dataMemory)
{
ALOGV("startRecognition() model handle %d", handle);
@@ -391,28 +391,25 @@
if (model == 0) {
return BAD_VALUE;
}
+ if ((dataMemory == 0) ||
+ (dataMemory->size() < sizeof(struct sound_trigger_recognition_config))) {
+ return BAD_VALUE;
+ }
if (model->mState == Model::STATE_ACTIVE) {
return INVALID_OPERATION;
}
model->mState = Model::STATE_ACTIVE;
- char *data = NULL;
- unsigned int data_size = 0;
- if (dataMemory != 0 && dataMemory->size() != 0) {
- data_size = (unsigned int)dataMemory->size();
- data = (char *)dataMemory->pointer();
- ALOGV("startRecognition() data size %d data %d - %d",
- data_size, data[0], data[data_size - 1]);
- }
+ struct sound_trigger_recognition_config *config =
+ (struct sound_trigger_recognition_config *)dataMemory->pointer();
//TODO: get capture handle and device from audio policy service
- audio_io_handle_t capture_handle = 0;
- return mHwDevice->start_recognition(mHwDevice, handle, capture_handle, AUDIO_DEVICE_NONE,
+ config->capture_handle = AUDIO_IO_HANDLE_NONE;
+ config->capture_device = AUDIO_DEVICE_NONE;
+ return mHwDevice->start_recognition(mHwDevice, handle, config,
SoundTriggerHwService::recognitionCallback,
- this,
- data_size,
- data);
+ this);
}
status_t SoundTriggerHwService::Module::stopRecognition(sound_model_handle_t handle)