Merge "AML: Replace ParceledListSlice"
diff --git a/apex/Android.bp b/apex/Android.bp
index eee26ae..05cc2c5 100644
--- a/apex/Android.bp
+++ b/apex/Android.bp
@@ -21,7 +21,11 @@
"libamrextractor",
"libflacextractor",
"libmidiextractor",
+ "libmkvextractor",
"libmp3extractor",
+ "libmp4extractor",
+ "libmpeg2extractor",
+ "liboggextractor",
"libwavextractor",
],
key: "com.android.media.key",
diff --git a/camera/ndk/impl/ACameraDevice.cpp b/camera/ndk/impl/ACameraDevice.cpp
index 00da54e..657d41f 100644
--- a/camera/ndk/impl/ACameraDevice.cpp
+++ b/camera/ndk/impl/ACameraDevice.cpp
@@ -633,7 +633,7 @@
}
std::set<std::pair<ANativeWindow*, OutputConfiguration>> outputSet;
- for (auto outConfig : outputs->mOutputs) {
+ for (const auto& outConfig : outputs->mOutputs) {
ANativeWindow* anw = outConfig.mWindow;
sp<IGraphicBufferProducer> iGBP(nullptr);
ret = getIGBPfromAnw(anw, iGBP);
@@ -706,7 +706,7 @@
}
// add new streams
- for (auto outputPair : addSet) {
+ for (const auto& outputPair : addSet) {
int streamId;
remoteRet = mRemote->createStream(outputPair.second, &streamId);
if (!remoteRet.isOk()) {
@@ -839,7 +839,7 @@
const auto& gbps = outputPairIt->second.second.getGraphicBufferProducers();
for (const auto& outGbp : gbps) {
- for (auto surface : request->mSurfaceList) {
+ for (const auto& surface : request->mSurfaceList) {
if (surface->getIGraphicBufferProducer() == outGbp) {
ANativeWindow* anw = static_cast<ANativeWindow*>(surface.get());
ALOGV("Camera %s Lost output buffer for ANW %p frame %" PRId64,
diff --git a/cmds/stagefright/Android.mk b/cmds/stagefright/Android.mk
index c7619af..7a10302 100644
--- a/cmds/stagefright/Android.mk
+++ b/cmds/stagefright/Android.mk
@@ -191,7 +191,6 @@
LOCAL_MODULE:= mediafilter
LOCAL_SANITIZE := cfi
-LOCAL_SANITIZE_DIAG := cfi
include $(BUILD_EXECUTABLE)
diff --git a/drm/libmediadrm/Android.bp b/drm/libmediadrm/Android.bp
index 94f9e02..41d1833 100644
--- a/drm/libmediadrm/Android.bp
+++ b/drm/libmediadrm/Android.bp
@@ -73,7 +73,6 @@
// Suppress unused parameter and no error options. These cause problems
// with the when using the map type in a proto definition.
"-Wno-unused-parameter",
- "-Wno-error",
],
}
@@ -106,7 +105,6 @@
// Suppress unused parameter and no error options. These cause problems
// when using the map type in a proto definition.
"-Wno-unused-parameter",
- "-Wno-error",
],
}
diff --git a/drm/libmediadrm/tests/Android.bp b/drm/libmediadrm/tests/Android.bp
index dcd59b7..9e0115e 100644
--- a/drm/libmediadrm/tests/Android.bp
+++ b/drm/libmediadrm/tests/Android.bp
@@ -34,7 +34,6 @@
// Suppress unused parameter and no error options. These cause problems
// when using the map type in a proto definition.
"-Wno-unused-parameter",
- "-Wno-error",
]
}
diff --git a/include/media/MediaExtractorPluginHelper.h b/include/media/MediaExtractorPluginHelper.h
index 292ec93..705aa81 100644
--- a/include/media/MediaExtractorPluginHelper.h
+++ b/include/media/MediaExtractorPluginHelper.h
@@ -183,32 +183,32 @@
mBuffer = buf;
}
- ~MediaBufferHelperV3() {}
+ virtual ~MediaBufferHelperV3() {}
- void release() {
+ virtual void release() {
mBuffer->release(mBuffer->handle);
}
- void* data() {
+ virtual void* data() {
return mBuffer->data(mBuffer->handle);
}
- size_t size() {
+ virtual size_t size() {
return mBuffer->size(mBuffer->handle);
}
- size_t range_offset() {
+ virtual size_t range_offset() {
return mBuffer->range_offset(mBuffer->handle);
}
- size_t range_length() {
+ virtual size_t range_length() {
return mBuffer->range_length(mBuffer->handle);
}
- void set_range(size_t offset, size_t length) {
+ virtual void set_range(size_t offset, size_t length) {
mBuffer->set_range(mBuffer->handle, offset, length);
}
- AMediaFormat *meta_data() {
+ virtual AMediaFormat *meta_data() {
return mBuffer->meta_data(mBuffer->handle);
}
};
diff --git a/media/bufferpool/2.0/AccessorImpl.cpp b/media/bufferpool/2.0/AccessorImpl.cpp
index 2c734ac..5260909 100644
--- a/media/bufferpool/2.0/AccessorImpl.cpp
+++ b/media/bufferpool/2.0/AccessorImpl.cpp
@@ -253,9 +253,21 @@
}
void Accessor::Impl::handleInvalidateAck() {
- std::lock_guard<std::mutex> lock(mBufferPool.mMutex);
- mBufferPool.processStatusMessages();
- mBufferPool.mInvalidation.onHandleAck();
+ std::map<ConnectionId, const sp<IObserver>> observers;
+ uint32_t invalidationId;
+ {
+ std::lock_guard<std::mutex> lock(mBufferPool.mMutex);
+ mBufferPool.processStatusMessages();
+ mBufferPool.mInvalidation.onHandleAck(&observers, &invalidationId);
+ }
+ // Do not hold lock for send invalidations
+ for (auto it = observers.begin(); it != observers.end(); ++it) {
+ const sp<IObserver> observer = it->second;
+ if (observer) {
+ Return<void> transResult = observer->onMessage(it->first, invalidationId);
+ (void) transResult;
+ }
+ }
}
bool Accessor::Impl::isValid() {
@@ -365,19 +377,21 @@
sInvalidator->addAccessor(mId, impl);
}
-void Accessor::Impl::BufferPool::Invalidation::onHandleAck() {
+void Accessor::Impl::BufferPool::Invalidation::onHandleAck(
+ std::map<ConnectionId, const sp<IObserver>> *observers,
+ uint32_t *invalidationId) {
if (mInvalidationId != 0) {
+ *invalidationId = mInvalidationId;
std::set<int> deads;
for (auto it = mAcks.begin(); it != mAcks.end(); ++it) {
if (it->second != mInvalidationId) {
const sp<IObserver> observer = mObservers[it->first];
if (observer) {
- ALOGV("connection %lld call observer (%u: %u)",
+ observers->emplace(it->first, observer);
+ ALOGV("connection %lld will call observer (%u: %u)",
(long long)it->first, it->second, mInvalidationId);
- Return<void> transResult = observer->onMessage(it->first, mInvalidationId);
- (void) transResult;
- // N.B: ignore possibility of onMessage oneway call being
- // lost.
+ // N.B: onMessage will be called later. ignore possibility of
+ // onMessage# oneway call being lost.
it->second = mInvalidationId;
} else {
ALOGV("bufferpool2 observer died %lld", (long long)it->first);
diff --git a/media/bufferpool/2.0/AccessorImpl.h b/media/bufferpool/2.0/AccessorImpl.h
index b3faa96..eea72b9 100644
--- a/media/bufferpool/2.0/AccessorImpl.h
+++ b/media/bufferpool/2.0/AccessorImpl.h
@@ -158,7 +158,9 @@
BufferInvalidationChannel &channel,
const std::shared_ptr<Accessor::Impl> &impl);
- void onHandleAck();
+ void onHandleAck(
+ std::map<ConnectionId, const sp<IObserver>> *observers,
+ uint32_t *invalidationId);
} mInvalidation;
/// Buffer pool statistics which tracks allocation and transfer statistics.
struct Stats {
diff --git a/media/codec2/hidl/1.0/vts/audio/VtsHidlC2V1_0TargetAudioDecTest.cpp b/media/codec2/hidl/1.0/vts/audio/VtsHidlC2V1_0TargetAudioDecTest.cpp
index 6fd9200..1e87f38 100644
--- a/media/codec2/hidl/1.0/vts/audio/VtsHidlC2V1_0TargetAudioDecTest.cpp
+++ b/media/codec2/hidl/1.0/vts/audio/VtsHidlC2V1_0TargetAudioDecTest.cpp
@@ -156,63 +156,31 @@
// callback function to process onWorkDone received by Listener
void handleWorkDone(std::list<std::unique_ptr<C2Work>>& workItems) {
for (std::unique_ptr<C2Work>& work : workItems) {
- // handle configuration changes in work done
- if (!work->worklets.empty() &&
- (work->worklets.front()->output.configUpdate.size() != 0)) {
- ALOGV("Config Update");
- std::vector<std::unique_ptr<C2Param>> updates =
- std::move(work->worklets.front()->output.configUpdate);
- std::vector<C2Param*> configParam;
- std::vector<std::unique_ptr<C2SettingResult>> failures;
- for (size_t i = 0; i < updates.size(); ++i) {
- C2Param* param = updates[i].get();
- if ((param->index() == C2StreamSampleRateInfo::output::PARAM_TYPE) ||
- (param->index() == C2StreamChannelCountInfo::output::PARAM_TYPE)) {
- configParam.push_back(param);
+ if (!work->worklets.empty()) {
+ // For decoder components current timestamp always exceeds
+ // previous timestamp
+ bool codecConfig = ((work->worklets.front()->output.flags &
+ C2FrameData::FLAG_CODEC_CONFIG) != 0);
+ if (!codecConfig &&
+ !work->worklets.front()->output.buffers.empty()) {
+ EXPECT_GE(work->worklets.front()->output.ordinal.timestamp.peeku(),
+ mTimestampUs);
+ mTimestampUs =
+ work->worklets.front()->output.ordinal.timestamp.peeku();
+ uint32_t rangeLength =
+ work->worklets.front()->output.buffers[0]->data()
+ .linearBlocks().front().map().get().capacity();
+ //List of timestamp values and output size to calculate timestamp
+ if (mTimestampDevTest) {
+ outputMetaData meta = {mTimestampUs, rangeLength};
+ oBufferMetaData.push_back(meta);
}
}
- mComponent->config(configParam, C2_DONT_BLOCK, &failures);
- ASSERT_EQ(failures.size(), 0u);
- }
- mFramesReceived++;
- mEos = (work->worklets.front()->output.flags &
- C2FrameData::FLAG_END_OF_STREAM) != 0;
- auto frameIndexIt =
- std::find(mFlushedIndices.begin(), mFlushedIndices.end(),
- work->input.ordinal.frameIndex.peeku());
- ALOGV("WorkDone: frameID received %d",
- (int)work->worklets.front()->output.ordinal.frameIndex.peeku());
-
- // For decoder components current timestamp always exceeds
- // previous timestamp
- bool codecConfig = ((work->worklets.front()->output.flags &
- C2FrameData::FLAG_CODEC_CONFIG) != 0);
- if (!codecConfig &&
- !work->worklets.front()->output.buffers.empty()) {
- EXPECT_GE(work->worklets.front()->output.ordinal.timestamp.peeku(),
- mTimestampUs);
- mTimestampUs =
- work->worklets.front()->output.ordinal.timestamp.peeku();
- uint32_t rangeLength =
- work->worklets.front()->output.buffers[0]->data()
- .linearBlocks().front().map().get().capacity();
- //List of timestamp values and output size to calculate timestamp
- if (mTimestampDevTest) {
- outputMetaData meta = {mTimestampUs, rangeLength};
- oBufferMetaData.push_back(meta);
- }
- }
-
- work->input.buffers.clear();
- work->worklets.clear();
- {
- typedef std::unique_lock<std::mutex> ULock;
- ULock l(mQueueLock);
- mWorkQueue.push_back(std::move(work));
- if (!mFlushedIndices.empty()) {
- mFlushedIndices.erase(frameIndexIt);
- }
- mQueueCondition.notify_all();
+ bool mCsd = false;
+ workDone(mComponent, work, mFlushedIndices, mQueueLock,
+ mQueueCondition, mWorkQueue, mEos, mCsd,
+ mFramesReceived);
+ (void)mCsd;
}
}
}
@@ -418,11 +386,11 @@
}
}
-void decodeNFrames(const std::shared_ptr<android::Codec2Client::Component> &component,
- std::mutex &queueLock, std::condition_variable &queueCondition,
- std::list<std::unique_ptr<C2Work>> &workQueue,
- std::list<uint64_t> &flushedIndices,
- std::shared_ptr<C2BlockPool> &linearPool,
+void decodeNFrames(const std::shared_ptr<android::Codec2Client::Component>& component,
+ std::mutex &queueLock, std::condition_variable& queueCondition,
+ std::list<std::unique_ptr<C2Work>>& workQueue,
+ std::list<uint64_t>& flushedIndices,
+ std::shared_ptr<C2BlockPool>& linearPool,
std::ifstream& eleStream,
android::Vector<FrameInfo>* Info,
int offset, int range, bool signalEOS = true) {
@@ -462,34 +430,37 @@
}
int size = (*Info)[frameID].bytesCount;
char* data = (char*)malloc(size);
+ ASSERT_NE(data, nullptr);
eleStream.read(data, size);
ASSERT_EQ(eleStream.gcount(), size);
- std::shared_ptr<C2LinearBlock> block;
- ASSERT_EQ(C2_OK,
- linearPool->fetchLinearBlock(
- size, {C2MemoryUsage::CPU_READ, C2MemoryUsage::CPU_WRITE},
- &block));
- ASSERT_TRUE(block);
-
- // Write View
- C2WriteView view = block->map().get();
- if (view.error() != C2_OK) {
- fprintf(stderr, "C2LinearBlock::map() failed : %d", view.error());
- break;
- }
- ASSERT_EQ((size_t)size, view.capacity());
- ASSERT_EQ(0u, view.offset());
- ASSERT_EQ((size_t)size, view.size());
-
- memcpy(view.base(), data, size);
-
work->input.buffers.clear();
- work->input.buffers.emplace_back(new LinearBuffer(block));
+ if (size) {
+ std::shared_ptr<C2LinearBlock> block;
+ ASSERT_EQ(C2_OK,
+ linearPool->fetchLinearBlock(
+ size, {C2MemoryUsage::CPU_READ, C2MemoryUsage::CPU_WRITE},
+ &block));
+ ASSERT_TRUE(block);
+
+ // Write View
+ C2WriteView view = block->map().get();
+ if (view.error() != C2_OK) {
+ fprintf(stderr, "C2LinearBlock::map() failed : %d", view.error());
+ break;
+ }
+ ASSERT_EQ((size_t)size, view.capacity());
+ ASSERT_EQ(0u, view.offset());
+ ASSERT_EQ((size_t)size, view.size());
+
+ memcpy(view.base(), data, size);
+
+ work->input.buffers.emplace_back(new LinearBuffer(block));
+ free(data);
+ }
work->worklets.clear();
work->worklets.emplace_back(new C2Worklet);
- free(data);
std::list<std::unique_ptr<C2Work>> items;
items.push_back(std::move(work));
@@ -502,29 +473,6 @@
}
}
-void waitOnInputConsumption(std::mutex& queueLock,
- std::condition_variable& queueCondition,
- std::list<std::unique_ptr<C2Work>>& workQueue,
- size_t bufferCount = MAX_INPUT_BUFFERS) {
- typedef std::unique_lock<std::mutex> ULock;
- uint32_t queueSize;
- uint32_t maxRetry = 0;
- {
- ULock l(queueLock);
- queueSize = workQueue.size();
- }
- while ((maxRetry < MAX_RETRY) && (queueSize < bufferCount)) {
- ULock l(queueLock);
- if (queueSize != workQueue.size()) {
- queueSize = workQueue.size();
- maxRetry = 0;
- } else {
- queueCondition.wait_for(l, TIME_OUT);
- maxRetry++;
- }
- }
-}
-
TEST_F(Codec2AudioDecHidlTest, validateCompName) {
if (mDisableTest) return;
ALOGV("Checks if the given component is a valid audio component");
@@ -718,7 +666,6 @@
ASSERT_EQ(mComponent->queue(&items), C2_OK);
{
- typedef std::unique_lock<std::mutex> ULock;
ULock l(mQueueLock);
if (mWorkQueue.size() != MAX_INPUT_BUFFERS) {
mQueueCondition.wait_for(l, TIME_OUT);
@@ -729,46 +676,6 @@
ASSERT_EQ(mComponent->stop(), C2_OK);
}
-TEST_F(Codec2AudioDecHidlTest, EmptyBufferTest) {
- description("Tests empty input buffer");
- if (mDisableTest) return;
- typedef std::unique_lock<std::mutex> ULock;
- ASSERT_EQ(mComponent->start(), C2_OK);
- std::unique_ptr<C2Work> work;
- // Prepare C2Work
- {
- ULock l(mQueueLock);
- if (!mWorkQueue.empty()) {
- work.swap(mWorkQueue.front());
- mWorkQueue.pop_front();
- } else {
- ASSERT_TRUE(false) << "mWorkQueue Empty at the start of test";
- }
- }
- ASSERT_NE(work, nullptr);
-
- work->input.flags = (C2FrameData::flags_t)0;
- work->input.ordinal.timestamp = 0;
- work->input.ordinal.frameIndex = 0;
- work->input.buffers.clear();
- work->worklets.clear();
- work->worklets.emplace_back(new C2Worklet);
-
- std::list<std::unique_ptr<C2Work>> items;
- items.push_back(std::move(work));
- ASSERT_EQ(mComponent->queue(&items), C2_OK);
-
- {
- typedef std::unique_lock<std::mutex> ULock;
- ULock l(mQueueLock);
- if (mWorkQueue.size() != MAX_INPUT_BUFFERS) {
- mQueueCondition.wait_for(l, TIME_OUT);
- }
- }
- ASSERT_EQ(mWorkQueue.size(), (size_t)MAX_INPUT_BUFFERS);
- ASSERT_EQ(mComponent->stop(), C2_OK);
-}
-
TEST_F(Codec2AudioDecHidlTest, FlushTest) {
description("Tests Flush calls");
if (mDisableTest) return;
@@ -891,6 +798,72 @@
ASSERT_EQ(mComponent->stop(), C2_OK);
}
+TEST_F(Codec2AudioDecHidlTest, DecodeTestEmptyBuffersInserted) {
+ description("Decode with multiple empty input frames");
+ if (mDisableTest) return;
+
+ ASSERT_EQ(mComponent->start(), C2_OK);
+
+ char mURL[512], info[512];
+ std::ifstream eleStream, eleInfo;
+
+ strcpy(mURL, gEnv->getRes().c_str());
+ strcpy(info, gEnv->getRes().c_str());
+ GetURLForComponent(mCompName, mURL, info);
+
+ eleInfo.open(info);
+ ASSERT_EQ(eleInfo.is_open(), true) << mURL << " - file not found";
+ android::Vector<FrameInfo> Info;
+ int bytesCount = 0;
+ uint32_t frameId = 0;
+ uint32_t flags = 0;
+ uint32_t timestamp = 0;
+ bool codecConfig = false;
+ // This test introduces empty CSD after every 20th frame
+ // and empty input frames at an interval of 5 frames.
+ while (1) {
+ if (!(frameId % 5)) {
+ if (!(frameId % 20)) flags = 32;
+ else flags = 0;
+ bytesCount = 0;
+ } else {
+ if (!(eleInfo >> bytesCount)) break;
+ eleInfo >> flags;
+ eleInfo >> timestamp;
+ codecConfig = flags ?
+ ((1 << (flags - 1)) & C2FrameData::FLAG_CODEC_CONFIG) != 0 : 0;
+ }
+ Info.push_back({bytesCount, flags, timestamp});
+ frameId++;
+ }
+ eleInfo.close();
+
+ ALOGV("mURL : %s", mURL);
+ eleStream.open(mURL, std::ifstream::binary);
+ ASSERT_EQ(eleStream.is_open(), true);
+ ASSERT_NO_FATAL_FAILURE(decodeNFrames(
+ mComponent, mQueueLock, mQueueCondition, mWorkQueue, mFlushedIndices,
+ mLinearPool, eleStream, &Info, 0, (int)Info.size()));
+
+ // blocking call to ensures application to Wait till all the inputs are
+ // consumed
+ if (!mEos) {
+ ALOGV("Waiting for input consumption");
+ ASSERT_NO_FATAL_FAILURE(
+ waitOnInputConsumption(mQueueLock, mQueueCondition, mWorkQueue));
+ }
+
+ eleStream.close();
+ if (mFramesReceived != Info.size()) {
+ ALOGE("Input buffer count and Output buffer count mismatch");
+ ALOGV("framesReceived : %d inputFrames : %zu", mFramesReceived,
+ Info.size());
+ ASSERT_TRUE(false);
+ }
+
+ ASSERT_EQ(mComponent->stop(), C2_OK);
+}
+
} // anonymous namespace
int main(int argc, char** argv) {
diff --git a/media/codec2/hidl/1.0/vts/audio/VtsHidlC2V1_0TargetAudioEncTest.cpp b/media/codec2/hidl/1.0/vts/audio/VtsHidlC2V1_0TargetAudioEncTest.cpp
index 4f86aad..5d66ee5 100644
--- a/media/codec2/hidl/1.0/vts/audio/VtsHidlC2V1_0TargetAudioEncTest.cpp
+++ b/media/codec2/hidl/1.0/vts/audio/VtsHidlC2V1_0TargetAudioEncTest.cpp
@@ -96,6 +96,7 @@
const StringToName kStringToName[] = {
{"aac", aac},
{"flac", flac},
+ {"opus", opus},
{"amrnb", amrnb},
{"amrwb", amrwb},
};
@@ -135,45 +136,17 @@
// callback function to process onWorkDone received by Listener
void handleWorkDone(std::list<std::unique_ptr<C2Work>>& workItems) {
for (std::unique_ptr<C2Work>& work : workItems) {
- // handle configuration changes in work done
- if (!work->worklets.empty() &&
- (work->worklets.front()->output.configUpdate.size() != 0)) {
- ALOGV("Config Update");
- std::vector<std::unique_ptr<C2Param>> updates =
- std::move(work->worklets.front()->output.configUpdate);
- std::vector<C2Param*> configParam;
- std::vector<std::unique_ptr<C2SettingResult>> failures;
- for (size_t i = 0; i < updates.size(); ++i) {
- C2Param* param = updates[i].get();
- if (param->index() == C2StreamCsdInfo::output::PARAM_TYPE) {
- mCsd = true;
- }
- }
- }
- mFramesReceived++;
- mEos = (work->worklets.front()->output.flags &
- C2FrameData::FLAG_END_OF_STREAM) != 0;
- auto frameIndexIt =
- std::find(mFlushedIndices.begin(), mFlushedIndices.end(),
- work->input.ordinal.frameIndex.peeku());
- ALOGV("WorkDone: frameID received %d",
- (int)work->worklets.front()->output.ordinal.frameIndex.peeku());
- work->input.buffers.clear();
- work->worklets.clear();
- {
- typedef std::unique_lock<std::mutex> ULock;
- ULock l(mQueueLock);
- mWorkQueue.push_back(std::move(work));
- if (!mFlushedIndices.empty()) {
- mFlushedIndices.erase(frameIndexIt);
- }
- mQueueCondition.notify_all();
+ if (!work->worklets.empty()) {
+ workDone(mComponent, work, mFlushedIndices, mQueueLock,
+ mQueueCondition, mWorkQueue, mEos, mCsd,
+ mFramesReceived);
}
}
}
enum standardComp {
aac,
flac,
+ opus,
amrnb,
amrwb,
unknown_comp,
@@ -275,6 +248,8 @@
"bbb_raw_1ch_16khz_s16le.raw"},
{Codec2AudioEncHidlTest::standardComp::flac,
"bbb_raw_2ch_48khz_s16le.raw"},
+ {Codec2AudioEncHidlTest::standardComp::opus,
+ "bbb_raw_2ch_48khz_s16le.raw"},
};
for (size_t i = 0; i < sizeof(kCompToURL) / sizeof(kCompToURL[0]); ++i) {
@@ -285,11 +260,11 @@
}
}
-void encodeNFrames(const std::shared_ptr<android::Codec2Client::Component> &component,
- std::mutex &queueLock, std::condition_variable &queueCondition,
- std::list<std::unique_ptr<C2Work>> &workQueue,
- std::list<uint64_t> &flushedIndices,
- std::shared_ptr<C2BlockPool> &linearPool,
+void encodeNFrames(const std::shared_ptr<android::Codec2Client::Component>& component,
+ std::mutex &queueLock, std::condition_variable& queueCondition,
+ std::list<std::unique_ptr<C2Work>>& workQueue,
+ std::list<uint64_t>& flushedIndices,
+ std::shared_ptr<C2BlockPool>& linearPool,
std::ifstream& eleStream, uint32_t nFrames,
int32_t samplesPerFrame, int32_t nChannels,
int32_t nSampleRate, bool flushed = false,
@@ -334,6 +309,7 @@
flushedIndices.emplace_back(frameID);
}
char* data = (char*)malloc(bytesCount);
+ ASSERT_NE(data, nullptr);
eleStream.read(data, bytesCount);
ASSERT_EQ(eleStream.gcount(), bytesCount);
std::shared_ptr<C2LinearBlock> block;
@@ -372,29 +348,6 @@
}
}
-void waitOnInputConsumption(std::mutex& queueLock,
- std::condition_variable& queueCondition,
- std::list<std::unique_ptr<C2Work>>& workQueue,
- size_t bufferCount = MAX_INPUT_BUFFERS) {
- typedef std::unique_lock<std::mutex> ULock;
- uint32_t queueSize;
- uint32_t maxRetry = 0;
- {
- ULock l(queueLock);
- queueSize = workQueue.size();
- }
- while ((maxRetry < MAX_RETRY) && (queueSize < bufferCount)) {
- ULock l(queueLock);
- if (queueSize != workQueue.size()) {
- queueSize = workQueue.size();
- maxRetry = 0;
- } else {
- queueCondition.wait_for(l, TIME_OUT);
- maxRetry++;
- }
- }
-}
-
TEST_F(Codec2AudioEncHidlTest, validateCompName) {
if (mDisableTest) return;
ALOGV("Checks if the given component is a valid audio component");
@@ -425,6 +378,11 @@
nSampleRate = 48000;
samplesPerFrame = 1152;
break;
+ case opus:
+ nChannels = 2;
+ nSampleRate = 48000;
+ samplesPerFrame = 960;
+ break;
case amrnb:
nChannels = 1;
nSampleRate = 8000;
@@ -458,7 +416,7 @@
ALOGE("framesReceived : %d inputFrames : %u", mFramesReceived, numFrames);
ASSERT_TRUE(false);
}
- if ((mCompName == flac || mCompName == aac)) {
+ if ((mCompName == flac || mCompName == opus || mCompName == aac)) {
if (!mCsd) {
ALOGE("CSD buffer missing");
ASSERT_TRUE(false);
@@ -508,46 +466,6 @@
ASSERT_EQ(mComponent->stop(), C2_OK);
}
-TEST_F(Codec2AudioEncHidlTest, EmptyBufferTest) {
- description("Tests empty input buffer");
- if (mDisableTest) return;
- ASSERT_EQ(mComponent->start(), C2_OK);
-
- typedef std::unique_lock<std::mutex> ULock;
- std::unique_ptr<C2Work> work;
- {
- ULock l(mQueueLock);
- if (!mWorkQueue.empty()) {
- work.swap(mWorkQueue.front());
- mWorkQueue.pop_front();
- } else {
- ALOGE("mWorkQueue Empty is not expected at the start of the test");
- ASSERT_TRUE(false);
- }
- }
- ASSERT_NE(work, nullptr);
- work->input.flags = (C2FrameData::flags_t)0;
- work->input.ordinal.timestamp = 0;
- work->input.ordinal.frameIndex = 0;
- work->input.buffers.clear();
- work->worklets.clear();
- work->worklets.emplace_back(new C2Worklet);
-
- std::list<std::unique_ptr<C2Work>> items;
- items.push_back(std::move(work));
- ASSERT_EQ(mComponent->queue(&items), C2_OK);
- uint32_t queueSize;
- {
- ULock l(mQueueLock);
- queueSize = mWorkQueue.size();
- if (queueSize < MAX_INPUT_BUFFERS) {
- mQueueCondition.wait_for(l, TIME_OUT);
- }
- }
- ASSERT_EQ(mWorkQueue.size(), (uint32_t)MAX_INPUT_BUFFERS);
- ASSERT_EQ(mComponent->stop(), C2_OK);
-}
-
TEST_F(Codec2AudioEncHidlTest, FlushTest) {
description("Test Request for flush");
if (mDisableTest) return;
@@ -574,6 +492,11 @@
nSampleRate = 48000;
samplesPerFrame = 1152;
break;
+ case opus:
+ nChannels = 2;
+ nSampleRate = 48000;
+ samplesPerFrame = 960;
+ break;
case amrnb:
nChannels = 1;
nSampleRate = 8000;
diff --git a/media/codec2/hidl/1.0/vts/audio/media_c2_audio_hidl_test_common.h b/media/codec2/hidl/1.0/vts/audio/media_c2_audio_hidl_test_common.h
index 89eb69e..4d773ce 100644
--- a/media/codec2/hidl/1.0/vts/audio/media_c2_audio_hidl_test_common.h
+++ b/media/codec2/hidl/1.0/vts/audio/media_c2_audio_hidl_test_common.h
@@ -17,8 +17,5 @@
#ifndef MEDIA_C2_AUDIO_HIDL_TEST_COMMON_H
#define MEDIA_C2_AUDIO_HIDL_TEST_COMMON_H
-#define MAX_RETRY 20
-#define TIME_OUT 200ms
-#define MAX_INPUT_BUFFERS 8
#endif // MEDIA_C2_AUDIO_HIDL_TEST_COMMON_H
diff --git a/media/codec2/hidl/1.0/vts/common/media_c2_hidl_test_common.cpp b/media/codec2/hidl/1.0/vts/common/media_c2_hidl_test_common.cpp
index fdccdbb..64a458c 100644
--- a/media/codec2/hidl/1.0/vts/common/media_c2_hidl_test_common.cpp
+++ b/media/codec2/hidl/1.0/vts/common/media_c2_hidl_test_common.cpp
@@ -14,39 +14,115 @@
* limitations under the License.
*/
+// #define LOG_NDEBUG 0
#define LOG_TAG "media_c2_hidl_test_common"
#include <stdio.h>
#include "media_c2_hidl_test_common.h"
-using ::android::hardware::media::c2::V1_0::FieldSupportedValues;
-void dumpFSV(const FieldSupportedValues& sv) {
- ALOGD("Dumping FSV data");
- using namespace std;
- if (sv.type == FieldSupportedValues::Type::EMPTY) {
- ALOGD("FSV Value is Empty");
- }
- if (sv.type == FieldSupportedValues::Type::RANGE) {
- ALOGD("Dumping FSV range");
- cout << ".range(" << sv.range.min;
- if (sv.range.step != 0) {
- cout << ":" << sv.range.step;
+// Test the codecs for NullBuffer, Empty Input Buffer with(out) flags set
+void testInputBuffer(
+ const std::shared_ptr<android::Codec2Client::Component>& component,
+ std::mutex& queueLock, std::list<std::unique_ptr<C2Work>>& workQueue,
+ uint32_t flags, bool isNullBuffer) {
+ std::unique_ptr<C2Work> work;
+ {
+ typedef std::unique_lock<std::mutex> ULock;
+ ULock l(queueLock);
+ if (!workQueue.empty()) {
+ work.swap(workQueue.front());
+ workQueue.pop_front();
+ } else {
+ ASSERT_TRUE(false) << "workQueue Empty at the start of test";
}
- if (sv.range.num != 1 || sv.range.denom != 1) {
- cout << ":" << sv.range.num << "/" << sv.range.denom;
- }
- cout << " " << sv.range.max << ")";
}
- if (sv.values.size()) {
- ALOGD("Dumping FSV value");
- cout << (sv.type == FieldSupportedValues::Type::FLAGS ? ".flags("
- : ".list(");
- const char* sep = "";
- for (const auto& p : sv.values) {
- cout << sep << p;
- sep = ",";
- }
- cout << ")";
+ ASSERT_NE(work, nullptr);
+
+ work->input.flags = (C2FrameData::flags_t)flags;
+ work->input.ordinal.timestamp = 0;
+ work->input.ordinal.frameIndex = 0;
+ work->input.buffers.clear();
+ if (isNullBuffer) {
+ work->input.buffers.emplace_back(nullptr);
}
- cout << endl;
+ work->worklets.clear();
+ work->worklets.emplace_back(new C2Worklet);
+
+ std::list<std::unique_ptr<C2Work>> items;
+ items.push_back(std::move(work));
+ ASSERT_EQ(component->queue(&items), C2_OK);
}
+
+// Wait for all the inputs to be consumed by the plugin.
+void waitOnInputConsumption(std::mutex& queueLock,
+ std::condition_variable& queueCondition,
+ std::list<std::unique_ptr<C2Work>>& workQueue,
+ size_t bufferCount) {
+ typedef std::unique_lock<std::mutex> ULock;
+ uint32_t queueSize;
+ uint32_t maxRetry = 0;
+ {
+ ULock l(queueLock);
+ queueSize = workQueue.size();
+ }
+ while ((maxRetry < MAX_RETRY) && (queueSize < bufferCount)) {
+ ULock l(queueLock);
+ if (queueSize != workQueue.size()) {
+ queueSize = workQueue.size();
+ maxRetry = 0;
+ } else {
+ queueCondition.wait_for(l, TIME_OUT);
+ maxRetry++;
+ }
+ }
+}
+
+// process onWorkDone received by Listener
+void workDone(
+ const std::shared_ptr<android::Codec2Client::Component>& component,
+ std::unique_ptr<C2Work>& work, std::list<uint64_t>& flushedIndices,
+ std::mutex& queueLock, std::condition_variable& queueCondition,
+ std::list<std::unique_ptr<C2Work>>& workQueue, bool& eos, bool& csd,
+ uint32_t& framesReceived) {
+ // handle configuration changes in work done
+ if (work->worklets.front()->output.configUpdate.size() != 0) {
+ ALOGV("Config Update");
+ std::vector<std::unique_ptr<C2Param>> updates =
+ std::move(work->worklets.front()->output.configUpdate);
+ std::vector<C2Param*> configParam;
+ std::vector<std::unique_ptr<C2SettingResult>> failures;
+ for (size_t i = 0; i < updates.size(); ++i) {
+ C2Param* param = updates[i].get();
+ if (param->index() == C2StreamCsdInfo::output::PARAM_TYPE) {
+ csd = true;
+ } else if ((param->index() ==
+ C2StreamSampleRateInfo::output::PARAM_TYPE) ||
+ (param->index() ==
+ C2StreamChannelCountInfo::output::PARAM_TYPE) ||
+ (param->index() ==
+ C2VideoSizeStreamInfo::output::PARAM_TYPE)) {
+ configParam.push_back(param);
+ }
+ }
+ component->config(configParam, C2_DONT_BLOCK, &failures);
+ ASSERT_EQ(failures.size(), 0u);
+ }
+ framesReceived++;
+ eos = (work->worklets.front()->output.flags &
+ C2FrameData::FLAG_END_OF_STREAM) != 0;
+ auto frameIndexIt = std::find(flushedIndices.begin(), flushedIndices.end(),
+ work->input.ordinal.frameIndex.peeku());
+ ALOGV("WorkDone: frameID received %d",
+ (int)work->worklets.front()->output.ordinal.frameIndex.peeku());
+ work->input.buffers.clear();
+ work->worklets.clear();
+ {
+ typedef std::unique_lock<std::mutex> ULock;
+ ULock l(queueLock);
+ workQueue.push_back(std::move(work));
+ if (!flushedIndices.empty()) {
+ flushedIndices.erase(frameIndexIt);
+ }
+ queueCondition.notify_all();
+ }
+}
\ No newline at end of file
diff --git a/media/codec2/hidl/1.0/vts/common/media_c2_hidl_test_common.h b/media/codec2/hidl/1.0/vts/common/media_c2_hidl_test_common.h
index f765baa..a688530 100644
--- a/media/codec2/hidl/1.0/vts/common/media_c2_hidl_test_common.h
+++ b/media/codec2/hidl/1.0/vts/common/media_c2_hidl_test_common.h
@@ -22,6 +22,7 @@
#include <android/hardware/media/c2/1.0/types.h>
#include <C2Component.h>
+#include <C2Config.h>
#include <getopt.h>
#include <hidl/HidlSupport.h>
#include <media/stagefright/foundation/ALooper.h>
@@ -38,6 +39,10 @@
#include <VtsHalHidlTargetTestEnvBase.h>
+#define MAX_RETRY 20
+#define TIME_OUT 400ms
+#define MAX_INPUT_BUFFERS 8
+
/*
* Handle Callback functions onWorkDone(), onTripped(),
* onError(), onDeath(), onFramesRendered()
@@ -176,5 +181,21 @@
/*
* common functions declarations
*/
-void dumpFSV(const FieldSupportedValues& sv);
+void testInputBuffer(
+ const std::shared_ptr<android::Codec2Client::Component>& component,
+ std::mutex& queueLock, std::list<std::unique_ptr<C2Work>>& workQueue,
+ uint32_t flags, bool isNullBuffer);
+
+void waitOnInputConsumption(std::mutex& queueLock,
+ std::condition_variable& queueCondition,
+ std::list<std::unique_ptr<C2Work>>& workQueue,
+ size_t bufferCount = MAX_INPUT_BUFFERS);
+
+void workDone(
+ const std::shared_ptr<android::Codec2Client::Component>& component,
+ std::unique_ptr<C2Work>& work, std::list<uint64_t>& flushedIndices,
+ std::mutex& queueLock, std::condition_variable& queueCondition,
+ std::list<std::unique_ptr<C2Work>>& workQueue, bool& eos, bool& csd,
+ uint32_t& framesReceived);
+
#endif // MEDIA_C2_HIDL_TEST_COMMON_H
diff --git a/media/codec2/hidl/1.0/vts/component/VtsHidlC2V1_0TargetComponentTest.cpp b/media/codec2/hidl/1.0/vts/component/VtsHidlC2V1_0TargetComponentTest.cpp
index b7fb655..ec803d7 100644
--- a/media/codec2/hidl/1.0/vts/component/VtsHidlC2V1_0TargetComponentTest.cpp
+++ b/media/codec2/hidl/1.0/vts/component/VtsHidlC2V1_0TargetComponentTest.cpp
@@ -38,14 +38,21 @@
public:
virtual void SetUp() override {
Super::SetUp();
+ mEos = false;
mClient = android::Codec2Client::CreateFromService(
gEnv->getInstance().c_str());
ASSERT_NE(mClient, nullptr);
- mListener.reset(new CodecListener());
+ mListener.reset(new CodecListener(
+ [this](std::list<std::unique_ptr<C2Work>>& workItems) {
+ handleWorkDone(workItems);
+ }));
ASSERT_NE(mListener, nullptr);
mClient->createComponent(gEnv->getComponent().c_str(), mListener,
&mComponent);
ASSERT_NE(mComponent, nullptr);
+ for (int i = 0; i < MAX_INPUT_BUFFERS; ++i) {
+ mWorkQueue.emplace_back(new C2Work);
+ }
}
virtual void TearDown() override {
@@ -59,6 +66,23 @@
}
Super::TearDown();
}
+ // callback function to process onWorkDone received by Listener
+ void handleWorkDone(std::list<std::unique_ptr<C2Work>>& workItems) {
+ for (std::unique_ptr<C2Work>& work : workItems) {
+ if (!work->worklets.empty()) {
+ bool mCsd = false;
+ uint32_t mFramesReceived = 0;
+ std::list<uint64_t> mFlushedIndices;
+ workDone(mComponent, work, mFlushedIndices, mQueueLock, mQueueCondition,
+ mWorkQueue, mEos, mCsd, mFramesReceived);
+ }
+ }
+ }
+
+ bool mEos;
+ std::mutex mQueueLock;
+ std::condition_variable mQueueCondition;
+ std::list<std::unique_ptr<C2Work>> mWorkQueue;
std::shared_ptr<android::Codec2Client> mClient;
std::shared_ptr<android::Codec2Client::Listener> mListener;
@@ -135,8 +159,6 @@
ALOGV("Multiple Start Stop and Reset Test");
c2_status_t err = C2_OK;
-#define MAX_RETRY 16
-
for (size_t i = 0; i < MAX_RETRY; i++) {
err = mComponent->start();
ASSERT_EQ(err, C2_OK);
@@ -184,13 +206,44 @@
ASSERT_EQ(err, C2_OK);
ASSERT_EQ(failures.size(), 0u);
-#define MAX_RETRY 16
for (size_t i = 0; i < MAX_RETRY; i++) {
err = mComponent->release();
ASSERT_EQ(err, C2_OK);
}
}
+class Codec2ComponentInputTests : public Codec2ComponentHidlTest,
+ public ::testing::WithParamInterface<std::pair<uint32_t, bool> > {
+};
+
+TEST_P(Codec2ComponentInputTests, InputBufferTest) {
+ description("Tests for different inputs");
+
+ uint32_t flags = GetParam().first;
+ bool isNullBuffer = GetParam().second;
+ if (isNullBuffer) ALOGD("Testing for null input buffer with flag : %u", flags);
+ else ALOGD("Testing for empty input buffer with flag : %u", flags);
+ mEos = false;
+ ASSERT_EQ(mComponent->start(), C2_OK);
+ ASSERT_NO_FATAL_FAILURE(testInputBuffer(
+ mComponent, mQueueLock, mWorkQueue, flags, isNullBuffer));
+
+ ALOGD("Waiting for input consumption");
+ ASSERT_NO_FATAL_FAILURE(
+ waitOnInputConsumption(mQueueLock, mQueueCondition, mWorkQueue));
+
+ if (flags == C2FrameData::FLAG_END_OF_STREAM) ASSERT_EQ(mEos, true);
+ ASSERT_EQ(mComponent->stop(), C2_OK);
+ ASSERT_EQ(mComponent->reset(), C2_OK);
+}
+
+INSTANTIATE_TEST_CASE_P(NonStdInputs, Codec2ComponentInputTests, ::testing::Values(
+ std::make_pair(0, true),
+ std::make_pair(C2FrameData::FLAG_END_OF_STREAM, true),
+ std::make_pair(0, false),
+ std::make_pair(C2FrameData::FLAG_CODEC_CONFIG, false),
+ std::make_pair(C2FrameData::FLAG_END_OF_STREAM, false)));
+
} // anonymous namespace
// TODO: Add test for Invalid work,
diff --git a/media/codec2/hidl/1.0/vts/res/bbb_av1_176_144.av1 b/media/codec2/hidl/1.0/vts/res/bbb_av1_176_144.av1
new file mode 100644
index 0000000..1d67af9
--- /dev/null
+++ b/media/codec2/hidl/1.0/vts/res/bbb_av1_176_144.av1
Binary files differ
diff --git a/media/codec2/hidl/1.0/vts/res/bbb_av1_176_144.info b/media/codec2/hidl/1.0/vts/res/bbb_av1_176_144.info
new file mode 100644
index 0000000..cc51168
--- /dev/null
+++ b/media/codec2/hidl/1.0/vts/res/bbb_av1_176_144.info
@@ -0,0 +1,300 @@
+6027 1 0
+6879 0 33000
+5 0 66000
+532 0 100000
+5 0 133000
+2458 0 166000
+5 0 200000
+475 0 233000
+5 0 266000
+1262 0 300000
+5 0 333000
+554 0 366000
+27 0 400000
+6971 0 433000
+5 0 466000
+601 0 500000
+5 0 533000
+3276 0 566000
+5 0 600000
+658 0 633000
+5 0 666000
+1680 0 700000
+5 0 733000
+610 0 766000
+24 0 800000
+6728 0 833000
+5 0 866000
+764 0 900000
+5 0 933000
+2656 0 966000
+5 0 1000000
+462 0 1033000
+5 0 1066000
+1459 0 1100000
+5 0 1133000
+608 0 1166000
+24 0 1200000
+7038 0 1233000
+5 0 1266000
+721 0 1300000
+5 0 1333000
+3102 0 1366000
+5 0 1400000
+752 0 1433000
+5 0 1466000
+1815 0 1500000
+5 0 1533000
+755 0 1566000
+25 0 1600000
+7657 0 1633000
+5 0 1666000
+852 0 1700000
+5 0 1733000
+3537 0 1766000
+5 0 1800000
+673 0 1833000
+5 0 1866000
+1774 0 1900000
+5 0 1933000
+554 0 1966000
+24 0 2000000
+8028 0 2033000
+5 0 2066000
+715 0 2100000
+5 0 2133000
+3395 0 2166000
+5 0 2200000
+736 0 2233000
+5 0 2266000
+1759 0 2300000
+5 0 2333000
+605 0 2366000
+23 0 2400000
+7651 0 2433000
+5 0 2466000
+619 0 2500000
+5 0 2533000
+2788 0 2566000
+5 0 2600000
+556 0 2633000
+5 0 2666000
+1335 0 2700000
+5 0 2733000
+521 0 2766000
+24 0 2800000
+2274 0 2833000
+676 0 2866000
+25 0 2900000
+6224 0 2933000
+5798 0 2966000
+5 0 3000000
+448 0 3033000
+5 0 3066000
+1950 0 3100000
+5 0 3133000
+386 0 3166000
+5 0 3200000
+1218 0 3233000
+5 0 3266000
+1316 0 3300000
+5 0 3333000
+580 0 3366000
+26 0 3400000
+6673 0 3433000
+5 0 3466000
+473 0 3500000
+5 0 3533000
+2467 0 3566000
+5 0 3600000
+429 0 3633000
+5 0 3666000
+1420 0 3700000
+5 0 3733000
+583 0 3766000
+29 0 3800000
+8492 0 3833000
+5 0 3866000
+720 0 3900000
+5 0 3933000
+3635 0 3966000
+5 0 4000000
+621 0 4033000
+5 0 4066000
+1969 0 4100000
+5 0 4133000
+49 0 4166000
+25 0 4200000
+7416 0 4233000
+5 0 4266000
+947 0 4300000
+5 0 4333000
+3713 0 4366000
+5 0 4400000
+714 0 4433000
+5 0 4466000
+2003 0 4500000
+5 0 4533000
+750 0 4566000
+25 0 4600000
+8470 0 4633000
+5 0 4666000
+737 0 4700000
+5 0 4733000
+4094 0 4766000
+5 0 4800000
+1019 0 4833000
+5 0 4866000
+2160 0 4900000
+5 0 4933000
+828 0 4966000
+24 0 5000000
+9282 0 5033000
+5 0 5066000
+655 0 5100000
+5 0 5133000
+3491 0 5166000
+5 0 5200000
+651 0 5233000
+5 0 5266000
+1906 0 5300000
+5 0 5333000
+662 0 5366000
+24 0 5400000
+9724 0 5433000
+5 0 5466000
+617 0 5500000
+5 0 5533000
+3145 0 5566000
+5 0 5600000
+578 0 5633000
+5 0 5666000
+1592 0 5700000
+5 0 5733000
+569 0 5766000
+25 0 5800000
+10015 0 5833000
+5 0 5866000
+609 0 5900000
+5 0 5933000
+3618 0 5966000
+5 0 6000000
+734 0 6033000
+5 0 6066000
+1748 0 6100000
+5 0 6133000
+550 0 6166000
+24 0 6200000
+8806 0 6233000
+5 0 6266000
+498 0 6300000
+5 0 6333000
+2913 0 6366000
+5 0 6400000
+597 0 6433000
+5 0 6466000
+1235 0 6500000
+5 0 6533000
+362 0 6566000
+24 0 6600000
+6592 0 6633000
+5 0 6666000
+468 0 6700000
+5 0 6733000
+1920 0 6766000
+5 0 6800000
+419 0 6833000
+5 0 6866000
+843 0 6900000
+5 0 6933000
+237 0 6966000
+24 0 7000000
+2687 0 7033000
+5 0 7066000
+399 0 7100000
+5 0 7133000
+200 0 7166000
+143 0 7200000
+25 0 7233000
+12603 0 7266000
+1139 0 7300000
+5 0 7333000
+56 0 7366000
+5 0 7400000
+273 0 7433000
+5 0 7466000
+48 0 7500000
+5 0 7533000
+102 0 7566000
+5 0 7600000
+39 0 7633000
+24 0 7666000
+3635 0 7700000
+5 0 7733000
+46 0 7766000
+5 0 7800000
+647 0 7833000
+5 0 7866000
+61 0 7900000
+5 0 7933000
+824 0 7966000
+5 0 8000000
+691 0 8033000
+27 0 8066000
+4573 0 8100000
+5 0 8133000
+473 0 8166000
+5 0 8200000
+1637 0 8233000
+5 0 8266000
+451 0 8300000
+5 0 8333000
+969 0 8366000
+5 0 8400000
+234 0 8433000
+24 0 8466000
+3361 0 8500000
+5 0 8533000
+168 0 8566000
+5 0 8600000
+662 0 8633000
+5 0 8666000
+129 0 8700000
+5 0 8733000
+443 0 8766000
+5 0 8800000
+183 0 8833000
+23 0 8866000
+2769 0 8900000
+5 0 8933000
+182 0 8966000
+5 0 9000000
+890 0 9033000
+5 0 9066000
+171 0 9100000
+5 0 9133000
+599 0 9166000
+5 0 9200000
+236 0 9233000
+23 0 9266000
+2316 0 9300000
+5 0 9333000
+333 0 9366000
+5 0 9400000
+759 0 9433000
+5 0 9466000
+210 0 9500000
+5 0 9533000
+324 0 9566000
+5 0 9600000
+98 0 9633000
+23 0 9666000
+1107 0 9700000
+5 0 9733000
+42 0 9766000
+5 0 9800000
+145 0 9833000
+5 0 9866000
+109 0 9900000
+89 0 9933000
+24 0 9966000
\ No newline at end of file
diff --git a/media/codec2/hidl/1.0/vts/res/bbb_av1_640_360.av1 b/media/codec2/hidl/1.0/vts/res/bbb_av1_640_360.av1
new file mode 100644
index 0000000..529bace
--- /dev/null
+++ b/media/codec2/hidl/1.0/vts/res/bbb_av1_640_360.av1
Binary files differ
diff --git a/media/codec2/hidl/1.0/vts/res/bbb_av1_640_360.info b/media/codec2/hidl/1.0/vts/res/bbb_av1_640_360.info
new file mode 100644
index 0000000..fca7833
--- /dev/null
+++ b/media/codec2/hidl/1.0/vts/res/bbb_av1_640_360.info
@@ -0,0 +1,167 @@
+12571 1 0
+9881 0 33000
+5 0 66000
+544 0 100000
+5 0 133000
+2642 0 166000
+5 0 200000
+531 0 233000
+5 0 266000
+1359 0 300000
+5 0 333000
+551 0 366000
+28 0 400000
+10791 0 433000
+5 0 466000
+655 0 500000
+5 0 533000
+3769 0 566000
+5 0 600000
+711 0 633000
+5 0 666000
+2004 0 700000
+5 0 733000
+657 0 766000
+26 0 800000
+8969 0 833000
+5 0 866000
+630 0 900000
+5 0 933000
+2787 0 966000
+5 0 1000000
+404 0 1033000
+5 0 1066000
+1518 0 1100000
+5 0 1133000
+493 0 1166000
+26 0 1200000
+9900 0 1233000
+5 0 1266000
+620 0 1300000
+5 0 1333000
+3072 0 1366000
+5 0 1400000
+668 0 1433000
+5 0 1466000
+1821 0 1500000
+5 0 1533000
+682 0 1566000
+26 0 1600000
+9560 0 1633000
+5 0 1666000
+667 0 1700000
+5 0 1733000
+3249 0 1766000
+5 0 1800000
+589 0 1833000
+5 0 1866000
+1816 0 1900000
+5 0 1933000
+548 0 1966000
+26 0 2000000
+9916 0 2033000
+5 0 2066000
+628 0 2100000
+5 0 2133000
+3034 0 2166000
+5 0 2200000
+590 0 2233000
+5 0 2266000
+1581 0 2300000
+5 0 2333000
+524 0 2366000
+26 0 2400000
+8182 0 2433000
+5 0 2466000
+552 0 2500000
+5 0 2533000
+2412 0 2566000
+5 0 2600000
+489 0 2633000
+5 0 2666000
+1227 0 2700000
+5 0 2733000
+432 0 2766000
+26 0 2800000
+2017 0 2833000
+516 0 2866000
+26 0 2900000
+16619 0 2933000
+6710 0 2966000
+5 0 3000000
+425 0 3033000
+5 0 3066000
+1964 0 3100000
+5 0 3133000
+386 0 3166000
+5 0 3200000
+1129 0 3233000
+5 0 3266000
+1156 0 3300000
+5 0 3333000
+486 0 3366000
+28 0 3400000
+10304 0 3433000
+5 0 3466000
+412 0 3500000
+5 0 3533000
+2608 0 3566000
+5 0 3600000
+397 0 3633000
+5 0 3666000
+1514 0 3700000
+5 0 3733000
+533 0 3766000
+26 0 3800000
+11698 0 3833000
+5 0 3866000
+542 0 3900000
+5 0 3933000
+3334 0 3966000
+5 0 4000000
+547 0 4033000
+5 0 4066000
+1809 0 4100000
+5 0 4133000
+55 0 4166000
+26 0 4200000
+9496 0 4233000
+5 0 4266000
+658 0 4300000
+5 0 4333000
+3232 0 4366000
+5 0 4400000
+600 0 4433000
+5 0 4466000
+1766 0 4500000
+5 0 4533000
+550 0 4566000
+25 0 4600000
+9951 0 4633000
+5 0 4666000
+624 0 4700000
+5 0 4733000
+3617 0 4766000
+5 0 4800000
+644 0 4833000
+5 0 4866000
+1841 0 4900000
+5 0 4933000
+649 0 4966000
+25 0 5000000
+9901 0 5033000
+5 0 5066000
+515 0 5100000
+5 0 5133000
+2814 0 5166000
+5 0 5200000
+511 0 5233000
+5 0 5266000
+1521 0 5300000
+5 0 5333000
+509 0 5366000
+26 0 5400000
+10579 0 5433000
+5 0 5466000
+575 0 5500000
+5 0 5533000
\ No newline at end of file
diff --git a/media/codec2/hidl/1.0/vts/video/VtsHidlC2V1_0TargetVideoDecTest.cpp b/media/codec2/hidl/1.0/vts/video/VtsHidlC2V1_0TargetVideoDecTest.cpp
index 8420cab..9a42d72 100644
--- a/media/codec2/hidl/1.0/vts/video/VtsHidlC2V1_0TargetVideoDecTest.cpp
+++ b/media/codec2/hidl/1.0/vts/video/VtsHidlC2V1_0TargetVideoDecTest.cpp
@@ -101,7 +101,7 @@
const StringToName kStringToName[] = {
{"h263", h263}, {"avc", avc}, {"mpeg2", mpeg2}, {"mpeg4", mpeg4},
- {"hevc", hevc}, {"vp8", vp8}, {"vp9", vp9},
+ {"hevc", hevc}, {"vp8", vp8}, {"vp9", vp9}, {"av1", av1},
};
const size_t kNumStringToName =
@@ -142,79 +142,48 @@
// callback function to process onWorkDone received by Listener
void handleWorkDone(std::list<std::unique_ptr<C2Work>>& workItems) {
for (std::unique_ptr<C2Work>& work : workItems) {
- // handle configuration changes in work done
- if (!work->worklets.empty() &&
- (work->worklets.front()->output.configUpdate.size() != 0)) {
- ALOGV("Config Update");
- std::vector<std::unique_ptr<C2Param>> updates =
- std::move(work->worklets.front()->output.configUpdate);
- std::vector<C2Param*> configParam;
- std::vector<std::unique_ptr<C2SettingResult>> failures;
- for (size_t i = 0; i < updates.size(); ++i) {
- C2Param* param = updates[i].get();
- if (param->index() ==
- C2VideoSizeStreamInfo::output::PARAM_TYPE) {
- ALOGV("Received C2VideoSizeStreamInfo");
- configParam.push_back(param);
- }
- }
- mComponent->config(configParam, C2_DONT_BLOCK, &failures);
- ASSERT_EQ(failures.size(), 0u);
- }
+ if (!work->worklets.empty()) {
+ // For decoder components current timestamp always exceeds
+ // previous timestamp
+ typedef std::unique_lock<std::mutex> ULock;
+ bool codecConfig = ((work->worklets.front()->output.flags &
+ C2FrameData::FLAG_CODEC_CONFIG) != 0);
+ if (!codecConfig &&
+ !work->worklets.front()->output.buffers.empty()) {
+ EXPECT_GE(
+ (work->worklets.front()->output.ordinal.timestamp.peeku()),
+ mTimestampUs);
+ mTimestampUs =
+ work->worklets.front()->output.ordinal.timestamp.peeku();
- mFramesReceived++;
- mEos = (work->worklets.front()->output.flags &
- C2FrameData::FLAG_END_OF_STREAM) != 0;
- auto frameIndexIt =
- std::find(mFlushedIndices.begin(), mFlushedIndices.end(),
- work->input.ordinal.frameIndex.peeku());
-
- // For decoder components current timestamp always exceeds
- // previous timestamp
- typedef std::unique_lock<std::mutex> ULock;
- bool codecConfig = ((work->worklets.front()->output.flags &
- C2FrameData::FLAG_CODEC_CONFIG) != 0);
- if (!codecConfig &&
- !work->worklets.front()->output.buffers.empty()) {
- EXPECT_GE(
- (work->worklets.front()->output.ordinal.timestamp.peeku()),
- mTimestampUs);
- mTimestampUs =
- work->worklets.front()->output.ordinal.timestamp.peeku();
-
- ULock l(mQueueLock);
- if (mTimestampDevTest) {
- bool tsHit = false;
- std::list<uint64_t>::iterator it = mTimestampUslist.begin();
- while (it != mTimestampUslist.end()) {
- if (*it == mTimestampUs) {
- mTimestampUslist.erase(it);
- tsHit = true;
- break;
+ ULock l(mQueueLock);
+ if (mTimestampDevTest) {
+ bool tsHit = false;
+ std::list<uint64_t>::iterator it = mTimestampUslist.begin();
+ while (it != mTimestampUslist.end()) {
+ if (*it == mTimestampUs) {
+ mTimestampUslist.erase(it);
+ tsHit = true;
+ break;
+ }
+ it++;
}
- it++;
- }
- if (tsHit == false) {
- if (mTimestampUslist.empty() == false) {
- EXPECT_EQ(tsHit, true)
- << "TimeStamp not recognized";
- } else {
- std::cout << "[ INFO ] Received non-zero "
- "output / TimeStamp not recognized \n";
+ if (tsHit == false) {
+ if (mTimestampUslist.empty() == false) {
+ EXPECT_EQ(tsHit, true)
+ << "TimeStamp not recognized";
+ } else {
+ std::cout << "[ INFO ] Received non-zero "
+ "output / TimeStamp not recognized \n";
+ }
}
}
}
- }
-
- work->input.buffers.clear();
- work->worklets.clear();
- {
- ULock l(mQueueLock);
- mWorkQueue.push_back(std::move(work));
- if (!mFlushedIndices.empty()) {
- mFlushedIndices.erase(frameIndexIt);
- }
- mQueueCondition.notify_all();
+ bool mCsd;
+ workDone(mComponent, work, mFlushedIndices, mQueueLock,
+ mQueueCondition, mWorkQueue, mEos, mCsd,
+ mFramesReceived);
+ (void)mCsd;
}
}
}
@@ -227,6 +196,7 @@
hevc,
vp8,
vp9,
+ av1,
unknown_comp,
};
@@ -341,6 +311,11 @@
"bbb_vp9_640x360_1600kbps_30fps.vp9"},
{"bbb_vp9_176x144_285kbps_60fps.info",
"bbb_vp9_640x360_1600kbps_30fps.info"}},
+ {Codec2VideoDecHidlTest::standardComp::av1,
+ {"bbb_av1_640_360.av1",
+ "bbb_av1_176_144.av1"},
+ {"bbb_av1_640_360.info",
+ "bbb_av1_176_144.info"}},
};
for (size_t i = 0; i < sizeof(kCompToURL) / sizeof(kCompToURL[0]); ++i) {
@@ -352,11 +327,11 @@
}
}
-void decodeNFrames(const std::shared_ptr<android::Codec2Client::Component> &component,
- std::mutex &queueLock, std::condition_variable &queueCondition,
- std::list<std::unique_ptr<C2Work>> &workQueue,
- std::list<uint64_t> &flushedIndices,
- std::shared_ptr<C2BlockPool> &linearPool,
+void decodeNFrames(const std::shared_ptr<android::Codec2Client::Component>& component,
+ std::mutex &queueLock, std::condition_variable& queueCondition,
+ std::list<std::unique_ptr<C2Work>>& workQueue,
+ std::list<uint64_t>& flushedIndices,
+ std::shared_ptr<C2BlockPool>& linearPool,
std::ifstream& eleStream,
android::Vector<FrameInfo>* Info,
int offset, int range, bool signalEOS = true) {
@@ -397,35 +372,37 @@
int size = (*Info)[frameID].bytesCount;
char* data = (char*)malloc(size);
+ ASSERT_NE(data, nullptr);
eleStream.read(data, size);
ASSERT_EQ(eleStream.gcount(), size);
- std::shared_ptr<C2LinearBlock> block;
- ASSERT_EQ(C2_OK,
- linearPool->fetchLinearBlock(
- size, {C2MemoryUsage::CPU_READ, C2MemoryUsage::CPU_WRITE},
- &block));
- ASSERT_TRUE(block);
-
- // Write View
- C2WriteView view = block->map().get();
- if (view.error() != C2_OK) {
- fprintf(stderr, "C2LinearBlock::map() failed : %d", view.error());
- break;
- }
- ASSERT_EQ((size_t)size, view.capacity());
- ASSERT_EQ(0u, view.offset());
- ASSERT_EQ((size_t)size, view.size());
-
- memcpy(view.base(), data, size);
-
work->input.buffers.clear();
- work->input.buffers.emplace_back(new LinearBuffer(block));
+ if (size) {
+ std::shared_ptr<C2LinearBlock> block;
+ ASSERT_EQ(C2_OK,
+ linearPool->fetchLinearBlock(
+ size, {C2MemoryUsage::CPU_READ, C2MemoryUsage::CPU_WRITE},
+ &block));
+ ASSERT_TRUE(block);
+
+ // Write View
+ C2WriteView view = block->map().get();
+ if (view.error() != C2_OK) {
+ fprintf(stderr, "C2LinearBlock::map() failed : %d", view.error());
+ break;
+ }
+ ASSERT_EQ((size_t)size, view.capacity());
+ ASSERT_EQ(0u, view.offset());
+ ASSERT_EQ((size_t)size, view.size());
+
+ memcpy(view.base(), data, size);
+
+ work->input.buffers.emplace_back(new LinearBuffer(block));
+ free(data);
+ }
work->worklets.clear();
work->worklets.emplace_back(new C2Worklet);
- free(data);
-
std::list<std::unique_ptr<C2Work>> items;
items.push_back(std::move(work));
@@ -437,29 +414,6 @@
}
}
-void waitOnInputConsumption(std::mutex& queueLock,
- std::condition_variable& queueCondition,
- std::list<std::unique_ptr<C2Work>>& workQueue,
- size_t bufferCount = MAX_INPUT_BUFFERS) {
- typedef std::unique_lock<std::mutex> ULock;
- uint32_t queueSize;
- uint32_t maxRetry = 0;
- {
- ULock l(queueLock);
- queueSize = workQueue.size();
- }
- while ((maxRetry < MAX_RETRY) && (queueSize < bufferCount)) {
- ULock l(queueLock);
- if (queueSize != workQueue.size()) {
- queueSize = workQueue.size();
- maxRetry = 0;
- } else {
- queueCondition.wait_for(l, TIME_OUT);
- maxRetry++;
- }
- }
-}
-
TEST_F(Codec2VideoDecHidlTest, validateCompName) {
if (mDisableTest) return;
ALOGV("Checks if the given component is a valid video component");
@@ -678,8 +632,8 @@
EXPECT_GE(mFramesReceived, 1U);
ASSERT_EQ(mEos, true);
ASSERT_EQ(mComponent->stop(), C2_OK);
- ASSERT_EQ(mComponent->release(), C2_OK);
}
+ ASSERT_EQ(mComponent->release(), C2_OK);
}
TEST_F(Codec2VideoDecHidlTest, EOSTest) {
@@ -712,7 +666,6 @@
ASSERT_EQ(mComponent->queue(&items), C2_OK);
{
- typedef std::unique_lock<std::mutex> ULock;
ULock l(mQueueLock);
if (mWorkQueue.size() != MAX_INPUT_BUFFERS) {
mQueueCondition.wait_for(l, TIME_OUT);
@@ -723,46 +676,6 @@
ASSERT_EQ(mComponent->stop(), C2_OK);
}
-TEST_F(Codec2VideoDecHidlTest, EmptyBufferTest) {
- description("Tests empty input buffer");
- if (mDisableTest) return;
- typedef std::unique_lock<std::mutex> ULock;
- ASSERT_EQ(mComponent->start(), C2_OK);
- std::unique_ptr<C2Work> work;
- // Prepare C2Work
- {
- ULock l(mQueueLock);
- if (!mWorkQueue.empty()) {
- work.swap(mWorkQueue.front());
- mWorkQueue.pop_front();
- } else {
- ASSERT_TRUE(false) << "mWorkQueue Empty at the start of test";
- }
- }
- ASSERT_NE(work, nullptr);
-
- work->input.flags = (C2FrameData::flags_t)0;
- work->input.ordinal.timestamp = 0;
- work->input.ordinal.frameIndex = 0;
- work->input.buffers.clear();
- work->worklets.clear();
- work->worklets.emplace_back(new C2Worklet);
-
- std::list<std::unique_ptr<C2Work>> items;
- items.push_back(std::move(work));
- ASSERT_EQ(mComponent->queue(&items), C2_OK);
-
- {
- typedef std::unique_lock<std::mutex> ULock;
- ULock l(mQueueLock);
- if (mWorkQueue.size() != MAX_INPUT_BUFFERS) {
- mQueueCondition.wait_for(l, TIME_OUT);
- }
- }
- ASSERT_EQ(mWorkQueue.size(), (size_t)MAX_INPUT_BUFFERS);
- ASSERT_EQ(mComponent->stop(), C2_OK);
-}
-
TEST_F(Codec2VideoDecHidlTest, FlushTest) {
description("Tests Flush calls");
if (mDisableTest) return;
@@ -874,6 +787,69 @@
ASSERT_EQ(mComponent->stop(), C2_OK);
}
+TEST_F(Codec2VideoDecHidlTest, DecodeTestEmptyBuffersInserted) {
+ description("Decode with multiple empty input frames");
+ if (mDisableTest) return;
+
+ char mURL[512], info[512];
+ std::ifstream eleStream, eleInfo;
+
+ strcpy(mURL, gEnv->getRes().c_str());
+ strcpy(info, gEnv->getRes().c_str());
+ GetURLForComponent(mCompName, mURL, info);
+
+ eleInfo.open(info);
+ ASSERT_EQ(eleInfo.is_open(), true) << mURL << " - file not found";
+ android::Vector<FrameInfo> Info;
+ int bytesCount = 0;
+ uint32_t frameId = 0;
+ uint32_t flags = 0;
+ uint32_t timestamp = 0;
+ bool codecConfig = false;
+ // This test introduces empty CSD after every 20th frame
+ // and empty input frames at an interval of 5 frames.
+ while (1) {
+ if (!(frameId % 5)) {
+ if (!(frameId % 20)) flags = 32;
+ else flags = 0;
+ bytesCount = 0;
+ } else {
+ if (!(eleInfo >> bytesCount)) break;
+ eleInfo >> flags;
+ eleInfo >> timestamp;
+ codecConfig = flags ?
+ ((1 << (flags - 1)) & C2FrameData::FLAG_CODEC_CONFIG) != 0 : 0;
+ }
+ Info.push_back({bytesCount, flags, timestamp});
+ frameId++;
+ }
+ eleInfo.close();
+
+ ASSERT_EQ(mComponent->start(), C2_OK);
+ ALOGV("mURL : %s", mURL);
+ eleStream.open(mURL, std::ifstream::binary);
+ ASSERT_EQ(eleStream.is_open(), true);
+ ASSERT_NO_FATAL_FAILURE(decodeNFrames(
+ mComponent, mQueueLock, mQueueCondition, mWorkQueue, mFlushedIndices,
+ mLinearPool, eleStream, &Info, 0, (int)Info.size()));
+
+ // blocking call to ensures application to Wait till all the inputs are
+ // consumed
+ if (!mEos) {
+ ALOGV("Waiting for input consumption");
+ ASSERT_NO_FATAL_FAILURE(
+ waitOnInputConsumption(mQueueLock, mQueueCondition, mWorkQueue));
+ }
+
+ eleStream.close();
+ if (mFramesReceived != Info.size()) {
+ ALOGE("Input buffer count and Output buffer count mismatch");
+ ALOGV("framesReceived : %d inputFrames : %zu", mFramesReceived,
+ Info.size());
+ ASSERT_TRUE(false);
+ }
+}
+
} // anonymous namespace
// TODO : Video specific configuration Test
diff --git a/media/codec2/hidl/1.0/vts/video/VtsHidlC2V1_0TargetVideoEncTest.cpp b/media/codec2/hidl/1.0/vts/video/VtsHidlC2V1_0TargetVideoEncTest.cpp
index 87b7902..8585c87 100644
--- a/media/codec2/hidl/1.0/vts/video/VtsHidlC2V1_0TargetVideoEncTest.cpp
+++ b/media/codec2/hidl/1.0/vts/video/VtsHidlC2V1_0TargetVideoEncTest.cpp
@@ -139,40 +139,11 @@
// callback function to process onWorkDone received by Listener
void handleWorkDone(std::list<std::unique_ptr<C2Work>>& workItems) {
for (std::unique_ptr<C2Work>& work : workItems) {
- // handle configuration changes in work done
- if (!work->worklets.empty() &&
- (work->worklets.front()->output.configUpdate.size() != 0)) {
- ALOGV("Config Update");
- std::vector<std::unique_ptr<C2Param>> updates =
- std::move(work->worklets.front()->output.configUpdate);
- std::vector<C2Param*> configParam;
- std::vector<std::unique_ptr<C2SettingResult>> failures;
- for (size_t i = 0; i < updates.size(); ++i) {
- C2Param* param = updates[i].get();
- if (param->index() == C2StreamCsdInfo::output::PARAM_TYPE) {
- mCsd = true;
- }
- }
- }
- mFramesReceived++;
- if (work->result != C2_OK) mFailedWorkReceived++;
- mEos = (work->worklets.front()->output.flags &
- C2FrameData::FLAG_END_OF_STREAM) != 0;
- auto frameIndexIt =
- std::find(mFlushedIndices.begin(), mFlushedIndices.end(),
- work->input.ordinal.frameIndex.peeku());
- ALOGV("WorkDone: frameID received %d",
- (int)work->worklets.front()->output.ordinal.frameIndex.peeku());
- work->input.buffers.clear();
- work->worklets.clear();
- {
- typedef std::unique_lock<std::mutex> ULock;
- ULock l(mQueueLock);
- mWorkQueue.push_back(std::move(work));
- if (!mFlushedIndices.empty()) {
- mFlushedIndices.erase(frameIndexIt);
- }
- mQueueCondition.notify_all();
+ if (!work->worklets.empty()) {
+ if (work->result != C2_OK) mFailedWorkReceived++;
+ workDone(mComponent, work, mFlushedIndices, mQueueLock,
+ mQueueCondition, mWorkQueue, mEos, mCsd,
+ mFramesReceived);
}
}
}
@@ -272,11 +243,11 @@
strcat(URL, "bbb_352x288_420p_30fps_32frames.yuv");
}
-void encodeNFrames(const std::shared_ptr<android::Codec2Client::Component> &component,
- std::mutex &queueLock, std::condition_variable &queueCondition,
- std::list<std::unique_ptr<C2Work>> &workQueue,
- std::list<uint64_t> &flushedIndices,
- std::shared_ptr<C2BlockPool> &graphicPool,
+void encodeNFrames(const std::shared_ptr<android::Codec2Client::Component>& component,
+ std::mutex &queueLock, std::condition_variable& queueCondition,
+ std::list<std::unique_ptr<C2Work>>& workQueue,
+ std::list<uint64_t>& flushedIndices,
+ std::shared_ptr<C2BlockPool>& graphicPool,
std::ifstream& eleStream, uint32_t frameID,
uint32_t nFrames, uint32_t nWidth, int32_t nHeight,
bool flushed = false,bool signalEOS = true) {
@@ -319,6 +290,7 @@
flushedIndices.emplace_back(frameID);
}
char* data = (char*)malloc(bytesCount);
+ ASSERT_NE(data, nullptr);
memset(data, 0, bytesCount);
if (eleStream.is_open()) {
eleStream.read(data, bytesCount);
@@ -365,30 +337,6 @@
}
}
-void waitOnInputConsumption(std::mutex &queueLock,
- std::condition_variable &queueCondition,
- std::list<std::unique_ptr<C2Work>> &workQueue,
- size_t bufferCount = MAX_INPUT_BUFFERS) {
- typedef std::unique_lock<std::mutex> ULock;
- uint32_t queueSize;
- int maxRetry = 0;
- {
- ULock l(queueLock);
- queueSize = workQueue.size();
- }
- while ((maxRetry < MAX_RETRY) && (queueSize < bufferCount)) {
- ULock l(queueLock);
- if (queueSize != workQueue.size()) {
- queueSize = workQueue.size();
- maxRetry = 0;
- } else {
- queueCondition.wait_for(l, TIME_OUT);
- maxRetry++;
- }
- }
-}
-
-
TEST_F(Codec2VideoEncHidlTest, validateCompName) {
if (mDisableTest) return;
ALOGV("Checks if the given component is a valid video component");
@@ -488,46 +436,6 @@
ASSERT_EQ(mComponent->stop(), C2_OK);
}
-TEST_F(Codec2VideoEncHidlTest, EmptyBufferTest) {
- description("Tests empty input buffer");
- if (mDisableTest) return;
- ASSERT_EQ(mComponent->start(), C2_OK);
-
- typedef std::unique_lock<std::mutex> ULock;
- std::unique_ptr<C2Work> work;
- {
- ULock l(mQueueLock);
- if (!mWorkQueue.empty()) {
- work.swap(mWorkQueue.front());
- mWorkQueue.pop_front();
- } else {
- ALOGE("mWorkQueue Empty is not expected at the start of the test");
- ASSERT_TRUE(false);
- }
- }
- ASSERT_NE(work, nullptr);
- work->input.flags = (C2FrameData::flags_t)0;
- work->input.ordinal.timestamp = 0;
- work->input.ordinal.frameIndex = 0;
- work->input.buffers.clear();
- work->worklets.clear();
- work->worklets.emplace_back(new C2Worklet);
-
- std::list<std::unique_ptr<C2Work>> items;
- items.push_back(std::move(work));
- ASSERT_EQ(mComponent->queue(&items), C2_OK);
- uint32_t queueSize;
- {
- ULock l(mQueueLock);
- queueSize = mWorkQueue.size();
- if (queueSize < MAX_INPUT_BUFFERS) {
- mQueueCondition.wait_for(l, TIME_OUT);
- }
- }
- ASSERT_EQ(mWorkQueue.size(), (uint32_t)MAX_INPUT_BUFFERS);
- ASSERT_EQ(mComponent->stop(), C2_OK);
-}
-
TEST_F(Codec2VideoEncHidlTest, FlushTest) {
description("Test Request for flush");
if (mDisableTest) return;
diff --git a/media/codec2/hidl/1.0/vts/video/media_c2_video_hidl_test_common.h b/media/codec2/hidl/1.0/vts/video/media_c2_video_hidl_test_common.h
index 1215b13..dd45557 100644
--- a/media/codec2/hidl/1.0/vts/video/media_c2_video_hidl_test_common.h
+++ b/media/codec2/hidl/1.0/vts/video/media_c2_video_hidl_test_common.h
@@ -17,9 +17,6 @@
#ifndef MEDIA_C2_VIDEO_HIDL_TEST_COMMON_H
#define MEDIA_C2_VIDEO_HIDL_TEST_COMMON_H
-#define MAX_RETRY 20
-#define TIME_OUT 400ms
-#define MAX_INPUT_BUFFERS 8
#define ENCODER_TIMESTAMP_INCREMENT 40000
#define ENC_NUM_FRAMES 32
#define ENC_DEFAULT_FRAME_WIDTH 352
diff --git a/media/extractors/mkv/Android.bp b/media/extractors/mkv/Android.bp
index 8d028e1..1744d3d 100644
--- a/media/extractors/mkv/Android.bp
+++ b/media/extractors/mkv/Android.bp
@@ -11,7 +11,6 @@
shared_libs: [
"liblog",
- "libmediaextractor",
"libmediandk",
],
diff --git a/media/extractors/mkv/MatroskaExtractor.cpp b/media/extractors/mkv/MatroskaExtractor.cpp
index 1fdac05..4a30740 100644
--- a/media/extractors/mkv/MatroskaExtractor.cpp
+++ b/media/extractors/mkv/MatroskaExtractor.cpp
@@ -29,10 +29,8 @@
#include <media/stagefright/foundation/ByteUtils.h>
#include <media/stagefright/foundation/ColorUtils.h>
#include <media/stagefright/foundation/hexdump.h>
-#include <media/stagefright/MediaBufferBase.h>
#include <media/stagefright/MediaDefs.h>
#include <media/stagefright/MediaErrors.h>
-#include <media/stagefright/MetaData.h>
#include <media/stagefright/MetaDataUtils.h>
#include <utils/String8.h>
@@ -127,7 +125,7 @@
BlockIterator &operator=(const BlockIterator &);
};
-struct MatroskaSource : public MediaTrackHelperV2 {
+struct MatroskaSource : public MediaTrackHelperV3 {
MatroskaSource(MatroskaExtractor *extractor, size_t index);
virtual media_status_t start();
@@ -136,7 +134,7 @@
virtual media_status_t getFormat(AMediaFormat *);
virtual media_status_t read(
- MediaBufferBase **buffer, const ReadOptions *options);
+ MediaBufferHelperV3 **buffer, const ReadOptions *options);
protected:
virtual ~MatroskaSource();
@@ -156,11 +154,11 @@
BlockIterator mBlockIter;
ssize_t mNALSizeLen; // for type AVC or HEVC
- List<MediaBufferBase *> mPendingFrames;
+ List<MediaBufferHelperV3 *> mPendingFrames;
status_t advance();
- status_t setWebmBlockCryptoInfo(MediaBufferBase *mbuf);
+ status_t setWebmBlockCryptoInfo(MediaBufferHelperV3 *mbuf);
media_status_t readBlock();
void clearPendingFrames();
@@ -265,6 +263,8 @@
return AMEDIA_ERROR_MALFORMED;
}
+ // allocate one small initial buffer, but leave plenty of room to grow
+ mBufferGroup->init(1 /* number of buffers */, 1024 /* buffer size */, 64 /* growth limit */);
mBlockIter.reset();
return AMEDIA_OK;
@@ -569,7 +569,7 @@
void MatroskaSource::clearPendingFrames() {
while (!mPendingFrames.empty()) {
- MediaBufferBase *frame = *mPendingFrames.begin();
+ MediaBufferHelperV3 *frame = *mPendingFrames.begin();
mPendingFrames.erase(mPendingFrames.begin());
frame->release();
@@ -577,7 +577,7 @@
}
}
-status_t MatroskaSource::setWebmBlockCryptoInfo(MediaBufferBase *mbuf) {
+status_t MatroskaSource::setWebmBlockCryptoInfo(MediaBufferHelperV3 *mbuf) {
if (mbuf->range_length() < 1 || mbuf->range_length() - 1 > INT32_MAX) {
// 1-byte signal
return ERROR_MALFORMED;
@@ -591,7 +591,7 @@
return ERROR_MALFORMED;
}
- MetaDataBase &meta = mbuf->meta_data();
+ AMediaFormat *meta = mbuf->meta_data();
if (encrypted) {
uint8_t ctrCounter[16] = { 0 };
const uint8_t *keyId;
@@ -599,9 +599,9 @@
AMediaFormat *trackMeta = mExtractor->mTracks.itemAt(mTrackIndex).mMeta;
AMediaFormat_getBuffer(trackMeta, AMEDIAFORMAT_KEY_CRYPTO_KEY,
(void**)&keyId, &keyIdSize);
- meta.setData(kKeyCryptoKey, 0, keyId, keyIdSize);
+ AMediaFormat_setBuffer(meta, AMEDIAFORMAT_KEY_CRYPTO_KEY, keyId, keyIdSize);
memcpy(ctrCounter, data + 1, 8);
- meta.setData(kKeyCryptoIV, 0, ctrCounter, 16);
+ AMediaFormat_setBuffer(meta, AMEDIAFORMAT_KEY_CRYPTO_IV, ctrCounter, 16);
if (partitioned) {
/* 0 1 2 3
* 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
@@ -654,8 +654,10 @@
}
uint32_t sizeofPlainSizes = sizeof(uint32_t) * plainSizes.size();
uint32_t sizeofEncryptedSizes = sizeof(uint32_t) * encryptedSizes.size();
- meta.setData(kKeyPlainSizes, 0, plainSizes.data(), sizeofPlainSizes);
- meta.setData(kKeyEncryptedSizes, 0, encryptedSizes.data(), sizeofEncryptedSizes);
+ AMediaFormat_setBuffer(meta, AMEDIAFORMAT_KEY_CRYPTO_PLAIN_SIZES,
+ plainSizes.data(), sizeofPlainSizes);
+ AMediaFormat_setBuffer(meta, AMEDIAFORMAT_KEY_CRYPTO_ENCRYPTED_SIZES,
+ encryptedSizes.data(), sizeofEncryptedSizes);
mbuf->set_range(frameOffset, mbuf->range_length() - frameOffset);
} else {
/*
@@ -675,8 +677,10 @@
*/
int32_t plainSizes[] = { 0 };
int32_t encryptedSizes[] = { static_cast<int32_t>(mbuf->range_length() - 9) };
- meta.setData(kKeyPlainSizes, 0, plainSizes, sizeof(plainSizes));
- meta.setData(kKeyEncryptedSizes, 0, encryptedSizes, sizeof(encryptedSizes));
+ AMediaFormat_setBuffer(meta, AMEDIAFORMAT_KEY_CRYPTO_PLAIN_SIZES,
+ plainSizes, sizeof(plainSizes));
+ AMediaFormat_setBuffer(meta, AMEDIAFORMAT_KEY_CRYPTO_ENCRYPTED_SIZES,
+ encryptedSizes, sizeof(encryptedSizes));
mbuf->set_range(9, mbuf->range_length() - 9);
}
} else {
@@ -693,8 +697,10 @@
*/
int32_t plainSizes[] = { static_cast<int32_t>(mbuf->range_length() - 1) };
int32_t encryptedSizes[] = { 0 };
- meta.setData(kKeyPlainSizes, 0, plainSizes, sizeof(plainSizes));
- meta.setData(kKeyEncryptedSizes, 0, encryptedSizes, sizeof(encryptedSizes));
+ AMediaFormat_setBuffer(meta, AMEDIAFORMAT_KEY_CRYPTO_PLAIN_SIZES,
+ plainSizes, sizeof(plainSizes));
+ AMediaFormat_setBuffer(meta, AMEDIAFORMAT_KEY_CRYPTO_ENCRYPTED_SIZES,
+ encryptedSizes, sizeof(encryptedSizes));
mbuf->set_range(1, mbuf->range_length() - 1);
}
@@ -721,14 +727,17 @@
}
len += trackInfo->mHeaderLen;
- MediaBufferBase *mbuf = MediaBufferBase::Create(len);
+ MediaBufferHelperV3 *mbuf;
+ mBufferGroup->acquire_buffer(&mbuf, false /* nonblocking */, len /* requested size */);
+ mbuf->set_range(0, len);
uint8_t *data = static_cast<uint8_t *>(mbuf->data());
if (trackInfo->mHeader) {
memcpy(data, trackInfo->mHeader, trackInfo->mHeaderLen);
}
- mbuf->meta_data().setInt64(kKeyTime, timeUs);
- mbuf->meta_data().setInt32(kKeyIsSyncFrame, block->IsKey());
+ AMediaFormat *meta = mbuf->meta_data();
+ AMediaFormat_setInt64(meta, AMEDIAFORMAT_KEY_TIME_US, timeUs);
+ AMediaFormat_setInt32(meta, AMEDIAFORMAT_KEY_IS_SYNC_FRAME, block->IsKey());
status_t err = frame.Read(mExtractor->mReader, data + trackInfo->mHeaderLen);
if (err == OK
@@ -754,7 +763,7 @@
}
media_status_t MatroskaSource::read(
- MediaBufferBase **out, const ReadOptions *options) {
+ MediaBufferHelperV3 **out, const ReadOptions *options) {
*out = NULL;
int64_t targetSampleTimeUs = -1ll;
@@ -790,13 +799,13 @@
}
}
- MediaBufferBase *frame = *mPendingFrames.begin();
+ MediaBufferHelperV3 *frame = *mPendingFrames.begin();
mPendingFrames.erase(mPendingFrames.begin());
if ((mType != AVC && mType != HEVC) || mNALSizeLen == 0) {
if (targetSampleTimeUs >= 0ll) {
- frame->meta_data().setInt64(
- kKeyTargetTime, targetSampleTimeUs);
+ AMediaFormat_setInt64(frame->meta_data(),
+ AMEDIAFORMAT_KEY_TARGET_TIME, targetSampleTimeUs);
}
*out = frame;
@@ -819,7 +828,7 @@
size_t srcSize = frame->range_length();
size_t dstSize = 0;
- MediaBufferBase *buffer = NULL;
+ MediaBufferHelperV3 *buffer = NULL;
uint8_t *dstPtr = NULL;
for (int32_t pass = 0; pass < 2; ++pass) {
@@ -879,16 +888,20 @@
// each 4-byte nal size with a 4-byte start code
buffer = frame;
} else {
- buffer = MediaBufferBase::Create(dstSize);
+ mBufferGroup->acquire_buffer(
+ &buffer, false /* nonblocking */, dstSize /* requested size */);
+ buffer->set_range(0, dstSize);
}
+ AMediaFormat *frameMeta = frame->meta_data();
int64_t timeUs;
- CHECK(frame->meta_data().findInt64(kKeyTime, &timeUs));
+ CHECK(AMediaFormat_getInt64(frameMeta, AMEDIAFORMAT_KEY_TIME_US, &timeUs));
int32_t isSync;
- CHECK(frame->meta_data().findInt32(kKeyIsSyncFrame, &isSync));
+ CHECK(AMediaFormat_getInt32(frameMeta, AMEDIAFORMAT_KEY_IS_SYNC_FRAME, &isSync));
- buffer->meta_data().setInt64(kKeyTime, timeUs);
- buffer->meta_data().setInt32(kKeyIsSyncFrame, isSync);
+ AMediaFormat *bufMeta = buffer->meta_data();
+ AMediaFormat_setInt64(bufMeta, AMEDIAFORMAT_KEY_TIME_US, timeUs);
+ AMediaFormat_setInt32(bufMeta, AMEDIAFORMAT_KEY_IS_SYNC_FRAME, isSync);
dstPtr = (uint8_t *)buffer->data();
}
@@ -900,8 +913,8 @@
}
if (targetSampleTimeUs >= 0ll) {
- buffer->meta_data().setInt64(
- kKeyTargetTime, targetSampleTimeUs);
+ AMediaFormat_setInt64(buffer->meta_data(),
+ AMEDIAFORMAT_KEY_TARGET_TIME, targetSampleTimeUs);
}
*out = buffer;
@@ -992,7 +1005,7 @@
return mTracks.size();
}
-MediaTrackHelperV2 *MatroskaExtractor::getTrack(size_t index) {
+MediaTrackHelperV3 *MatroskaExtractor::getTrack(size_t index) {
if (index >= mTracks.size()) {
return NULL;
}
@@ -1660,22 +1673,22 @@
__attribute__ ((visibility ("default")))
ExtractorDef GETEXTRACTORDEF() {
return {
- EXTRACTORDEF_VERSION_CURRENT,
+ EXTRACTORDEF_VERSION_CURRENT + 1,
UUID("abbedd92-38c4-4904-a4c1-b3f45f899980"),
1,
"Matroska Extractor",
{
- .v2 = [](
+ .v3 = [](
CDataSource *source,
float *confidence,
void **,
- FreeMetaFunc *) -> CreatorFuncV2 {
+ FreeMetaFunc *) -> CreatorFuncV3 {
DataSourceHelper helper(source);
if (SniffMatroska(&helper, confidence)) {
return [](
CDataSource *source,
- void *) -> CMediaExtractorV2* {
- return wrapV2(new MatroskaExtractor(new DataSourceHelper(source)));};
+ void *) -> CMediaExtractorV3* {
+ return wrapV3(new MatroskaExtractor(new DataSourceHelper(source)));};
}
return NULL;
}
diff --git a/media/extractors/mkv/MatroskaExtractor.h b/media/extractors/mkv/MatroskaExtractor.h
index 2fa8881..a09256a 100644
--- a/media/extractors/mkv/MatroskaExtractor.h
+++ b/media/extractors/mkv/MatroskaExtractor.h
@@ -35,12 +35,12 @@
struct DataSourceBaseReader;
struct MatroskaSource;
-struct MatroskaExtractor : public MediaExtractorPluginHelperV2 {
+struct MatroskaExtractor : public MediaExtractorPluginHelperV3 {
explicit MatroskaExtractor(DataSourceHelper *source);
virtual size_t countTracks();
- virtual MediaTrackHelperV2 *getTrack(size_t index);
+ virtual MediaTrackHelperV3 *getTrack(size_t index);
virtual media_status_t getTrackMetaData(AMediaFormat *meta, size_t index, uint32_t flags);
diff --git a/media/extractors/mp4/Android.bp b/media/extractors/mp4/Android.bp
index 91de353..1b308aa 100644
--- a/media/extractors/mp4/Android.bp
+++ b/media/extractors/mp4/Android.bp
@@ -15,7 +15,6 @@
shared_libs: [
"liblog",
- "libmediaextractor",
"libmediandk"
],
diff --git a/media/extractors/mp4/MPEG4Extractor.cpp b/media/extractors/mp4/MPEG4Extractor.cpp
index 52213bd..390ba43 100644
--- a/media/extractors/mp4/MPEG4Extractor.cpp
+++ b/media/extractors/mp4/MPEG4Extractor.cpp
@@ -44,10 +44,9 @@
#include <media/stagefright/foundation/ColorUtils.h>
#include <media/stagefright/foundation/avc_utils.h>
#include <media/stagefright/foundation/hexdump.h>
-#include <media/stagefright/MediaBufferBase.h>
#include <media/stagefright/MediaBufferGroup.h>
#include <media/stagefright/MediaDefs.h>
-#include <media/stagefright/MetaData.h>
+#include <media/stagefright/MetaDataBase.h>
#include <utils/String8.h>
#include <byteswap.h>
@@ -70,7 +69,7 @@
kMaxAtomSize = 64 * 1024 * 1024,
};
-class MPEG4Source : public MediaTrackHelperV2 {
+class MPEG4Source : public MediaTrackHelperV3 {
static const size_t kMaxPcmFrameSize = 8192;
public:
// Caller retains ownership of both "dataSource" and "sampleTable".
@@ -89,10 +88,10 @@
virtual media_status_t getFormat(AMediaFormat *);
- virtual media_status_t read(MediaBufferBase **buffer, const ReadOptions *options = NULL);
+ virtual media_status_t read(MediaBufferHelperV3 **buffer, const ReadOptions *options = NULL);
virtual bool supportNonblockingRead() { return true; }
virtual media_status_t fragmentedRead(
- MediaBufferBase **buffer, const ReadOptions *options = NULL);
+ MediaBufferHelperV3 **buffer, const ReadOptions *options = NULL);
virtual ~MPEG4Source();
@@ -137,9 +136,7 @@
bool mStarted;
- MediaBufferGroup *mGroup;
-
- MediaBufferBase *mBuffer;
+ MediaBufferHelperV3 *mBuffer;
uint8_t *mSrcBuffer;
@@ -1556,9 +1553,40 @@
return ERROR_IO;
}
- String8 mimeFormat((const char *)(buffer.get()), chunk_data_size);
- AMediaFormat_setString(mLastTrack->meta, AMEDIAFORMAT_KEY_MIME, mimeFormat.string());
+ // Prior to API 29, the metadata track was not compliant with ISO/IEC
+ // 14496-12-2015. This led to some ISO-compliant parsers failing to read the
+ // metatrack. As of API 29 and onwards, a change was made to metadata track to
+ // make it compliant with the standard. The workaround is to write the
+ // null-terminated mime_format string twice. This allows compliant parsers to
+ // read the missing reserved, data_reference_index, and content_encoding fields
+ // from the first mime_type string. The actual mime_format field would then be
+ // read correctly from the second string. The non-compliant Android frameworks
+ // from API 28 and earlier would still be able to read the mime_format correctly
+ // as it would only read the first null-terminated mime_format string. To enable
+ // reading metadata tracks generated from both the non-compliant and compliant
+ // formats, a check needs to be done to see which format is used.
+ int null_pos = 0;
+ const unsigned char *str = buffer.get();
+ while (null_pos < chunk_data_size) {
+ if (*(str + null_pos) == '\0') {
+ break;
+ }
+ ++null_pos;
+ }
+ if (null_pos == chunk_data_size - 1) {
+ // This is not a standard ompliant metadata track.
+ String8 mimeFormat((const char *)(buffer.get()), chunk_data_size);
+ AMediaFormat_setString(mLastTrack->meta,
+ AMEDIAFORMAT_KEY_MIME, mimeFormat.string());
+ } else {
+ // This is a standard compliant metadata track.
+ String8 contentEncoding((const char *)(buffer.get() + 8));
+ String8 mimeFormat((const char *)(buffer.get() + 8 + contentEncoding.size() + 1),
+ chunk_data_size - 8 - contentEncoding.size() - 1);
+ AMediaFormat_setString(mLastTrack->meta,
+ AMEDIAFORMAT_KEY_MIME, mimeFormat.string());
+ }
break;
}
@@ -3827,7 +3855,7 @@
}
}
-MediaTrackHelperV2 *MPEG4Extractor::getTrack(size_t index) {
+MediaTrackHelperV3 *MPEG4Extractor::getTrack(size_t index) {
status_t err;
if ((err = readMetaData()) != OK) {
return NULL;
@@ -4329,7 +4357,6 @@
mIsPcm(false),
mNALLengthSize(0),
mStarted(false),
- mGroup(NULL),
mBuffer(NULL),
mSrcBuffer(NULL),
mIsHeif(itemTable != NULL),
@@ -4458,12 +4485,10 @@
const size_t kInitialBuffers = 2;
const size_t kMaxBuffers = 8;
const size_t realMaxBuffers = min(kMaxBufferSize / max_size, kMaxBuffers);
- mGroup = new MediaBufferGroup(kInitialBuffers, max_size, realMaxBuffers);
+ mBufferGroup->init(kInitialBuffers, max_size, realMaxBuffers);
mSrcBuffer = new (std::nothrow) uint8_t[max_size];
if (mSrcBuffer == NULL) {
// file probably specified a bad max size
- delete mGroup;
- mGroup = NULL;
return AMEDIA_ERROR_MALFORMED;
}
@@ -4485,9 +4510,6 @@
delete[] mSrcBuffer;
mSrcBuffer = NULL;
- delete mGroup;
- mGroup = NULL;
-
mStarted = false;
mCurrentSampleIndex = 0;
@@ -5184,12 +5206,12 @@
}
media_status_t MPEG4Source::read(
- MediaBufferBase **out, const ReadOptions *options) {
+ MediaBufferHelperV3 **out, const ReadOptions *options) {
Mutex::Autolock autoLock(mLock);
CHECK(mStarted);
- if (options != nullptr && options->getNonBlocking() && !mGroup->has_buffers()) {
+ if (options != nullptr && options->getNonBlocking() && !mBufferGroup->has_buffers()) {
*out = nullptr;
return AMEDIA_ERROR_WOULD_BLOCK;
}
@@ -5338,7 +5360,7 @@
return AMEDIA_ERROR_UNKNOWN;
}
- err = mGroup->acquire_buffer(&mBuffer);
+ err = mBufferGroup->acquire_buffer(&mBuffer);
if (err != OK) {
CHECK(mBuffer == NULL);
@@ -5377,9 +5399,11 @@
return AMEDIA_ERROR_IO;
}
- mBuffer->meta_data().clear();
- mBuffer->meta_data().setInt64(kKeyTime, ((int64_t)cts * 1000000) / mTimescale);
- mBuffer->meta_data().setInt32(kKeyIsSyncFrame, 1);
+ AMediaFormat *meta = mBuffer->meta_data();
+ AMediaFormat_clear(meta);
+ AMediaFormat_setInt64(
+ meta, AMEDIAFORMAT_KEY_TIME_US, ((int64_t)cts * 1000000) / mTimescale);
+ AMediaFormat_setInt32(meta, AMEDIAFORMAT_KEY_IS_SYNC_FRAME, 1);
int32_t byteOrder;
AMediaFormat_getInt32(mFormat,
@@ -5410,19 +5434,20 @@
CHECK(mBuffer != NULL);
mBuffer->set_range(0, size);
- mBuffer->meta_data().clear();
- mBuffer->meta_data().setInt64(
- kKeyTime, ((int64_t)cts * 1000000) / mTimescale);
- mBuffer->meta_data().setInt64(
- kKeyDuration, ((int64_t)stts * 1000000) / mTimescale);
+ AMediaFormat *meta = mBuffer->meta_data();
+ AMediaFormat_clear(meta);
+ AMediaFormat_setInt64(
+ meta, AMEDIAFORMAT_KEY_TIME_US, ((int64_t)cts * 1000000) / mTimescale);
+ AMediaFormat_setInt64(
+ meta, AMEDIAFORMAT_KEY_DURATION, ((int64_t)stts * 1000000) / mTimescale);
if (targetSampleTimeUs >= 0) {
- mBuffer->meta_data().setInt64(
- kKeyTargetTime, targetSampleTimeUs);
+ AMediaFormat_setInt64(
+ meta, AMEDIAFORMAT_KEY_TARGET_TIME, targetSampleTimeUs);
}
if (isSyncSample) {
- mBuffer->meta_data().setInt32(kKeyIsSyncFrame, 1);
+ AMediaFormat_setInt32(meta, AMEDIAFORMAT_KEY_IS_SYNC_FRAME, 1);
}
++mCurrentSampleIndex;
@@ -5465,19 +5490,20 @@
}
mBuffer->set_range(0, dstOffset + size);
- mBuffer->meta_data().clear();
- mBuffer->meta_data().setInt64(
- kKeyTime, ((int64_t)cts * 1000000) / mTimescale);
- mBuffer->meta_data().setInt64(
- kKeyDuration, ((int64_t)stts * 1000000) / mTimescale);
+ AMediaFormat *meta = mBuffer->meta_data();
+ AMediaFormat_clear(meta);
+ AMediaFormat_setInt64(
+ meta, AMEDIAFORMAT_KEY_TIME_US, ((int64_t)cts * 1000000) / mTimescale);
+ AMediaFormat_setInt64(
+ meta, AMEDIAFORMAT_KEY_DURATION, ((int64_t)stts * 1000000) / mTimescale);
if (targetSampleTimeUs >= 0) {
- mBuffer->meta_data().setInt64(
- kKeyTargetTime, targetSampleTimeUs);
+ AMediaFormat_setInt64(
+ meta, AMEDIAFORMAT_KEY_TARGET_TIME, targetSampleTimeUs);
}
if (isSyncSample) {
- mBuffer->meta_data().setInt32(kKeyIsSyncFrame, 1);
+ AMediaFormat_setInt32(meta, AMEDIAFORMAT_KEY_IS_SYNC_FRAME, 1);
}
++mCurrentSampleIndex;
@@ -5545,31 +5571,32 @@
CHECK(mBuffer != NULL);
mBuffer->set_range(0, dstOffset);
- mBuffer->meta_data().clear();
- mBuffer->meta_data().setInt64(
- kKeyTime, ((int64_t)cts * 1000000) / mTimescale);
- mBuffer->meta_data().setInt64(
- kKeyDuration, ((int64_t)stts * 1000000) / mTimescale);
+ AMediaFormat *meta = mBuffer->meta_data();
+ AMediaFormat_clear(meta);
+ AMediaFormat_setInt64(
+ meta, AMEDIAFORMAT_KEY_TIME_US, ((int64_t)cts * 1000000) / mTimescale);
+ AMediaFormat_setInt64(
+ meta, AMEDIAFORMAT_KEY_DURATION, ((int64_t)stts * 1000000) / mTimescale);
if (targetSampleTimeUs >= 0) {
- mBuffer->meta_data().setInt64(
- kKeyTargetTime, targetSampleTimeUs);
+ AMediaFormat_setInt64(
+ meta, AMEDIAFORMAT_KEY_TARGET_TIME, targetSampleTimeUs);
}
if (mIsAVC) {
uint32_t layerId = FindAVCLayerId(
(const uint8_t *)mBuffer->data(), mBuffer->range_length());
- mBuffer->meta_data().setInt32(kKeyTemporalLayerId, layerId);
+ AMediaFormat_setInt32(meta, AMEDIAFORMAT_KEY_TEMPORAL_LAYER_ID, layerId);
} else if (mIsHEVC) {
int32_t layerId = parseHEVCLayerId(
(const uint8_t *)mBuffer->data(), mBuffer->range_length());
if (layerId >= 0) {
- mBuffer->meta_data().setInt32(kKeyTemporalLayerId, layerId);
+ AMediaFormat_setInt32(meta, AMEDIAFORMAT_KEY_TEMPORAL_LAYER_ID, layerId);
}
}
if (isSyncSample) {
- mBuffer->meta_data().setInt32(kKeyIsSyncFrame, 1);
+ AMediaFormat_setInt32(meta, AMEDIAFORMAT_KEY_IS_SYNC_FRAME, 1);
}
++mCurrentSampleIndex;
@@ -5582,7 +5609,7 @@
}
media_status_t MPEG4Source::fragmentedRead(
- MediaBufferBase **out, const ReadOptions *options) {
+ MediaBufferHelperV3 **out, const ReadOptions *options) {
ALOGV("MPEG4Source::fragmentedRead");
@@ -5685,7 +5712,7 @@
mCurrentTime += smpl->duration;
isSyncSample = (mCurrentSampleIndex == 0);
- status_t err = mGroup->acquire_buffer(&mBuffer);
+ status_t err = mBufferGroup->acquire_buffer(&mBuffer);
if (err != OK) {
CHECK(mBuffer == NULL);
@@ -5701,19 +5728,21 @@
}
const Sample *smpl = &mCurrentSamples[mCurrentSampleIndex];
- MetaDataBase &bufmeta = mBuffer->meta_data();
- bufmeta.clear();
+ AMediaFormat *bufmeta = mBuffer->meta_data();
+ AMediaFormat_clear(bufmeta);
if (smpl->encryptedsizes.size()) {
// store clear/encrypted lengths in metadata
- bufmeta.setData(kKeyPlainSizes, 0,
+ AMediaFormat_setBuffer(bufmeta, AMEDIAFORMAT_KEY_CRYPTO_PLAIN_SIZES,
smpl->clearsizes.array(), smpl->clearsizes.size() * 4);
- bufmeta.setData(kKeyEncryptedSizes, 0,
+ AMediaFormat_setBuffer(bufmeta, AMEDIAFORMAT_KEY_CRYPTO_ENCRYPTED_SIZES,
smpl->encryptedsizes.array(), smpl->encryptedsizes.size() * 4);
- bufmeta.setInt32(kKeyCryptoDefaultIVSize, mDefaultIVSize);
- bufmeta.setInt32(kKeyCryptoMode, mCryptoMode);
- bufmeta.setData(kKeyCryptoKey, 0, mCryptoKey, 16);
- bufmeta.setInt32(kKeyEncryptedByteBlock, mDefaultEncryptedByteBlock);
- bufmeta.setInt32(kKeySkipByteBlock, mDefaultSkipByteBlock);
+ AMediaFormat_setInt32(bufmeta, AMEDIAFORMAT_KEY_CRYPTO_DEFAULT_IV_SIZE, mDefaultIVSize);
+ AMediaFormat_setInt32(bufmeta, AMEDIAFORMAT_KEY_CRYPTO_MODE, mCryptoMode);
+ AMediaFormat_setBuffer(bufmeta, AMEDIAFORMAT_KEY_CRYPTO_KEY, mCryptoKey, 16);
+ AMediaFormat_setInt32(bufmeta,
+ AMEDIAFORMAT_KEY_CRYPTO_ENCRYPTED_BYTE_BLOCK, mDefaultEncryptedByteBlock);
+ AMediaFormat_setInt32(bufmeta,
+ AMEDIAFORMAT_KEY_CRYPTO_SKIP_BYTE_BLOCK, mDefaultSkipByteBlock);
void *iv = NULL;
size_t ivlength = 0;
@@ -5722,8 +5751,7 @@
iv = (void *) smpl->iv;
ivlength = 16; // use 16 or the actual size?
}
- bufmeta.setData(kKeyCryptoIV, 0, iv, ivlength);
-
+ AMediaFormat_setBuffer(bufmeta, AMEDIAFORMAT_KEY_CRYPTO_IV, iv, ivlength);
}
if (!mIsAVC && !mIsHEVC) {
@@ -5749,30 +5777,29 @@
CHECK(mBuffer != NULL);
mBuffer->set_range(0, size);
- mBuffer->meta_data().setInt64(
- kKeyTime, ((int64_t)cts * 1000000) / mTimescale);
- mBuffer->meta_data().setInt64(
- kKeyDuration, ((int64_t)smpl->duration * 1000000) / mTimescale);
+ AMediaFormat_setInt64(bufmeta,
+ AMEDIAFORMAT_KEY_TIME_US, ((int64_t)cts * 1000000) / mTimescale);
+ AMediaFormat_setInt64(bufmeta,
+ AMEDIAFORMAT_KEY_DURATION, ((int64_t)smpl->duration * 1000000) / mTimescale);
if (targetSampleTimeUs >= 0) {
- mBuffer->meta_data().setInt64(
- kKeyTargetTime, targetSampleTimeUs);
+ AMediaFormat_setInt64(bufmeta, AMEDIAFORMAT_KEY_TARGET_TIME, targetSampleTimeUs);
}
if (mIsAVC) {
uint32_t layerId = FindAVCLayerId(
(const uint8_t *)mBuffer->data(), mBuffer->range_length());
- mBuffer->meta_data().setInt32(kKeyTemporalLayerId, layerId);
+ AMediaFormat_setInt32(bufmeta, AMEDIAFORMAT_KEY_TEMPORAL_LAYER_ID, layerId);
} else if (mIsHEVC) {
int32_t layerId = parseHEVCLayerId(
(const uint8_t *)mBuffer->data(), mBuffer->range_length());
if (layerId >= 0) {
- mBuffer->meta_data().setInt32(kKeyTemporalLayerId, layerId);
+ AMediaFormat_setInt32(bufmeta, AMEDIAFORMAT_KEY_TEMPORAL_LAYER_ID, layerId);
}
}
if (isSyncSample) {
- mBuffer->meta_data().setInt32(kKeyIsSyncFrame, 1);
+ AMediaFormat_setInt32(bufmeta, AMEDIAFORMAT_KEY_IS_SYNC_FRAME, 1);
}
++mCurrentSampleIndex;
@@ -5864,18 +5891,18 @@
CHECK(mBuffer != NULL);
mBuffer->set_range(0, dstOffset);
- mBuffer->meta_data().setInt64(
- kKeyTime, ((int64_t)cts * 1000000) / mTimescale);
- mBuffer->meta_data().setInt64(
- kKeyDuration, ((int64_t)smpl->duration * 1000000) / mTimescale);
+ AMediaFormat *bufmeta = mBuffer->meta_data();
+ AMediaFormat_setInt64(bufmeta,
+ AMEDIAFORMAT_KEY_TIME_US, ((int64_t)cts * 1000000) / mTimescale);
+ AMediaFormat_setInt64(bufmeta,
+ AMEDIAFORMAT_KEY_DURATION, ((int64_t)smpl->duration * 1000000) / mTimescale);
if (targetSampleTimeUs >= 0) {
- mBuffer->meta_data().setInt64(
- kKeyTargetTime, targetSampleTimeUs);
+ AMediaFormat_setInt64(bufmeta, AMEDIAFORMAT_KEY_TARGET_TIME, targetSampleTimeUs);
}
if (isSyncSample) {
- mBuffer->meta_data().setInt32(kKeyIsSyncFrame, 1);
+ AMediaFormat_setInt32(bufmeta, AMEDIAFORMAT_KEY_IS_SYNC_FRAME, 1);
}
++mCurrentSampleIndex;
@@ -6075,11 +6102,11 @@
return true;
}
-static CMediaExtractorV2* CreateExtractor(CDataSource *source, void *) {
- return wrapV2(new MPEG4Extractor(new DataSourceHelper(source)));
+static CMediaExtractorV3* CreateExtractor(CDataSource *source, void *) {
+ return wrapV3(new MPEG4Extractor(new DataSourceHelper(source)));
}
-static CreatorFuncV2 Sniff(
+static CreatorFuncV3 Sniff(
CDataSource *source, float *confidence, void **,
FreeMetaFunc *) {
DataSourceHelper helper(source);
@@ -6100,11 +6127,11 @@
__attribute__ ((visibility ("default")))
ExtractorDef GETEXTRACTORDEF() {
return {
- EXTRACTORDEF_VERSION_CURRENT,
+ EXTRACTORDEF_VERSION_CURRENT + 1,
UUID("27575c67-4417-4c54-8d3d-8e626985a164"),
2, // version
"MP4 Extractor",
- { .v2 = Sniff }
+ { .v3 = Sniff }
};
}
diff --git a/media/extractors/mp4/MPEG4Extractor.h b/media/extractors/mp4/MPEG4Extractor.h
index 56b641d..a9a4635 100644
--- a/media/extractors/mp4/MPEG4Extractor.h
+++ b/media/extractors/mp4/MPEG4Extractor.h
@@ -53,12 +53,12 @@
uint32_t default_sample_flags;
};
-class MPEG4Extractor : public MediaExtractorPluginHelperV2 {
+class MPEG4Extractor : public MediaExtractorPluginHelperV3 {
public:
explicit MPEG4Extractor(DataSourceHelper *source, const char *mime = NULL);
virtual size_t countTracks();
- virtual MediaTrackHelperV2 *getTrack(size_t index);
+ virtual MediaTrackHelperV3 *getTrack(size_t index);
virtual media_status_t getTrackMetaData(AMediaFormat *meta, size_t index, uint32_t flags);
virtual media_status_t getMetaData(AMediaFormat *meta);
diff --git a/media/extractors/mpeg2/Android.bp b/media/extractors/mpeg2/Android.bp
index 38c86eb..b816093 100644
--- a/media/extractors/mpeg2/Android.bp
+++ b/media/extractors/mpeg2/Android.bp
@@ -15,14 +15,11 @@
"android.hardware.cas@1.0",
"android.hardware.cas.native@1.0",
"android.hidl.token@1.0-utils",
- "libbinder",
- "libcrypto",
- "libcutils",
- "libhidlallocatorutils",
+ "android.hidl.allocator@1.0",
+ "libhidlmemory",
"libhidlbase",
"liblog",
- "libmediaextractor",
- "libstagefright_foundation",
+ "libmediandk",
],
header_libs: [
@@ -30,8 +27,13 @@
],
static_libs: [
+ "libcrypto",
+ "libstagefright_foundation",
"libstagefright_mpeg2support",
+ "libmediaextractor",
"libutils",
+ "libstagefright",
+ "libstagefright_esds",
],
name: "libmpeg2extractor",
diff --git a/media/extractors/mpeg2/ExtractorBundle.cpp b/media/extractors/mpeg2/ExtractorBundle.cpp
index 366aa59..c10a797 100644
--- a/media/extractors/mpeg2/ExtractorBundle.cpp
+++ b/media/extractors/mpeg2/ExtractorBundle.cpp
@@ -31,27 +31,27 @@
__attribute__ ((visibility ("default")))
ExtractorDef GETEXTRACTORDEF() {
return {
- EXTRACTORDEF_VERSION,
+ EXTRACTORDEF_VERSION_CURRENT + 1,
UUID("3d1dcfeb-e40a-436d-a574-c2438a555e5f"),
1,
"MPEG2-PS/TS Extractor",
{
- [](
+ .v3 = [](
CDataSource *source,
float *confidence,
void **,
- FreeMetaFunc *) -> CreatorFunc {
+ FreeMetaFunc *) -> CreatorFuncV3 {
DataSourceHelper helper(source);
if (SniffMPEG2TS(&helper, confidence)) {
return [](
CDataSource *source,
- void *) -> CMediaExtractor* {
- return wrap(new MPEG2TSExtractor(new DataSourceHelper(source)));};
+ void *) -> CMediaExtractorV3* {
+ return wrapV3(new MPEG2TSExtractor(new DataSourceHelper(source)));};
} else if (SniffMPEG2PS(&helper, confidence)) {
return [](
CDataSource *source,
- void *) -> CMediaExtractor* {
- return wrap(new MPEG2PSExtractor(new DataSourceHelper(source)));};
+ void *) -> CMediaExtractorV3* {
+ return wrapV3(new MPEG2PSExtractor(new DataSourceHelper(source)));};
}
return NULL;
}
diff --git a/media/extractors/mpeg2/MPEG2PSExtractor.cpp b/media/extractors/mpeg2/MPEG2PSExtractor.cpp
index fc13d2c..b60fc4e 100644
--- a/media/extractors/mpeg2/MPEG2PSExtractor.cpp
+++ b/media/extractors/mpeg2/MPEG2PSExtractor.cpp
@@ -33,22 +33,23 @@
#include <media/stagefright/MediaDefs.h>
#include <media/stagefright/MediaErrors.h>
#include <media/stagefright/MetaData.h>
+#include <media/stagefright/Utils.h>
#include <utils/String8.h>
#include <inttypes.h>
namespace android {
-struct MPEG2PSExtractor::Track : public MediaTrackHelper, public RefBase {
+struct MPEG2PSExtractor::Track : public MediaTrackHelperV3 {
Track(MPEG2PSExtractor *extractor,
unsigned stream_id, unsigned stream_type);
- virtual status_t start();
- virtual status_t stop();
- virtual status_t getFormat(MetaDataBase &);
+ virtual media_status_t start();
+ virtual media_status_t stop();
+ virtual media_status_t getFormat(AMediaFormat *);
- virtual status_t read(
- MediaBufferBase **buffer, const ReadOptions *options);
+ virtual media_status_t read(
+ MediaBufferHelperV3 **buffer, const ReadOptions *options);
protected:
virtual ~Track();
@@ -71,22 +72,22 @@
DISALLOW_EVIL_CONSTRUCTORS(Track);
};
-struct MPEG2PSExtractor::WrappedTrack : public MediaTrackHelper {
- WrappedTrack(MPEG2PSExtractor *extractor, const sp<Track> &track);
+struct MPEG2PSExtractor::WrappedTrack : public MediaTrackHelperV3 {
+ WrappedTrack(MPEG2PSExtractor *extractor, Track *track);
- virtual status_t start();
- virtual status_t stop();
- virtual status_t getFormat(MetaDataBase &);
+ virtual media_status_t start();
+ virtual media_status_t stop();
+ virtual media_status_t getFormat(AMediaFormat *);
- virtual status_t read(
- MediaBufferBase **buffer, const ReadOptions *options);
+ virtual media_status_t read(
+ MediaBufferHelperV3 **buffer, const ReadOptions *options);
protected:
virtual ~WrappedTrack();
private:
MPEG2PSExtractor *mExtractor;
- sp<MPEG2PSExtractor::Track> mTrack;
+ MPEG2PSExtractor::Track *mTrack;
DISALLOW_EVIL_CONSTRUCTORS(WrappedTrack);
};
@@ -107,13 +108,14 @@
}
// Remove all tracks that were unable to determine their format.
- MetaDataBase meta;
+ AMediaFormat *meta = AMediaFormat_new();
for (size_t i = mTracks.size(); i > 0;) {
i--;
- if (mTracks.valueAt(i)->getFormat(meta) != OK) {
+ if (mTracks.valueAt(i)->getFormat(meta) != AMEDIA_OK) {
mTracks.removeItemsAt(i);
}
}
+ AMediaFormat_delete(meta);
mScanning = false;
}
@@ -126,7 +128,7 @@
return mTracks.size();
}
-MediaTrackHelper *MPEG2PSExtractor::getTrack(size_t index) {
+MediaTrackHelperV3 *MPEG2PSExtractor::getTrack(size_t index) {
if (index >= mTracks.size()) {
return NULL;
}
@@ -134,20 +136,20 @@
return new WrappedTrack(this, mTracks.valueAt(index));
}
-status_t MPEG2PSExtractor::getTrackMetaData(
- MetaDataBase &meta,
+media_status_t MPEG2PSExtractor::getTrackMetaData(
+ AMediaFormat *meta,
size_t index, uint32_t /* flags */) {
if (index >= mTracks.size()) {
- return UNKNOWN_ERROR;
+ return AMEDIA_ERROR_UNKNOWN;
}
return mTracks.valueAt(index)->getFormat(meta);
}
-status_t MPEG2PSExtractor::getMetaData(MetaDataBase &meta) {
- meta.setCString(kKeyMIMEType, MEDIA_MIMETYPE_CONTAINER_MPEG2PS);
+media_status_t MPEG2PSExtractor::getMetaData(AMediaFormat *meta) {
+ AMediaFormat_setString(meta, AMEDIAFORMAT_KEY_MIME, MEDIA_MIMETYPE_CONTAINER_MPEG2PS);
- return OK;
+ return AMEDIA_OK;
}
uint32_t MPEG2PSExtractor::flags() const {
@@ -635,42 +637,55 @@
mQueue = NULL;
}
-status_t MPEG2PSExtractor::Track::start() {
+media_status_t MPEG2PSExtractor::Track::start() {
if (mSource == NULL) {
- return NO_INIT;
+ return AMEDIA_ERROR_UNKNOWN;
}
- return mSource->start(NULL); // AnotherPacketSource::start doesn't use its argument
+ // initialize with one small buffer, but allow growth
+ mBufferGroup->init(1 /* one buffer */, 256 /* buffer size */, 64 /* max number of buffers */);
+
+ if (mSource->start(NULL) == OK) { // AnotherPacketSource::start doesn't use its argument
+ return AMEDIA_OK;
+ }
+ return AMEDIA_ERROR_UNKNOWN;
}
-status_t MPEG2PSExtractor::Track::stop() {
+media_status_t MPEG2PSExtractor::Track::stop() {
if (mSource == NULL) {
- return NO_INIT;
+ return AMEDIA_ERROR_UNKNOWN;
}
- return mSource->stop();
+ if (mSource->stop() == OK) {
+ return AMEDIA_OK;
+ }
+ return AMEDIA_ERROR_UNKNOWN;
}
-status_t MPEG2PSExtractor::Track::getFormat(MetaDataBase &meta) {
+void copyAMessageToAMediaFormat(AMediaFormat *format, sp<AMessage> msg);
+
+media_status_t MPEG2PSExtractor::Track::getFormat(AMediaFormat *meta) {
if (mSource == NULL) {
- return NO_INIT;
+ return AMEDIA_ERROR_UNKNOWN;
}
sp<MetaData> sourceMeta = mSource->getFormat();
- meta = *sourceMeta;
- return OK;
+ sp<AMessage> msg;
+ convertMetaDataToMessage(sourceMeta, &msg);
+ copyAMessageToAMediaFormat(meta, msg);
+ return AMEDIA_OK;
}
-status_t MPEG2PSExtractor::Track::read(
- MediaBufferBase **buffer, const ReadOptions *options) {
+media_status_t MPEG2PSExtractor::Track::read(
+ MediaBufferHelperV3 **buffer, const ReadOptions *options) {
if (mSource == NULL) {
- return NO_INIT;
+ return AMEDIA_ERROR_UNKNOWN;
}
status_t finalResult;
while (!mSource->hasBufferAvailable(&finalResult)) {
if (finalResult != OK) {
- return ERROR_END_OF_STREAM;
+ return AMEDIA_ERROR_END_OF_STREAM;
}
status_t err = mExtractor->feedMore();
@@ -680,7 +695,46 @@
}
}
- return mSource->read(buffer, (MediaSource::ReadOptions*)options);
+ MediaBufferBase *mbuf;
+ mSource->read(&mbuf, (MediaTrack::ReadOptions*) options);
+ size_t length = mbuf->range_length();
+ MediaBufferHelperV3 *outbuf;
+ mBufferGroup->acquire_buffer(&outbuf, false, length);
+ memcpy(outbuf->data(), mbuf->data(), length);
+ outbuf->set_range(0, length);
+ *buffer = outbuf;
+ MetaDataBase &inMeta = mbuf->meta_data();
+ AMediaFormat *outMeta = outbuf->meta_data();
+ int64_t val64;
+ if (inMeta.findInt64(kKeyTime, &val64)) {
+ AMediaFormat_setInt64(outMeta, AMEDIAFORMAT_KEY_TIME_US, val64);
+ }
+ int32_t val32;
+ if (inMeta.findInt32(kKeyIsSyncFrame, &val32)) {
+ AMediaFormat_setInt32(outMeta, AMEDIAFORMAT_KEY_IS_SYNC_FRAME, val32);
+ }
+ if (inMeta.findInt32(kKeyCryptoMode, &val32)) {
+ AMediaFormat_setInt32(outMeta, AMEDIAFORMAT_KEY_CRYPTO_MODE, val32);
+ }
+ uint32_t bufType;
+ const void *bufData;
+ size_t bufSize;
+ if (inMeta.findData(kKeyCryptoIV, &bufType, &bufData, &bufSize)) {
+ AMediaFormat_setBuffer(outMeta, AMEDIAFORMAT_KEY_CRYPTO_IV, bufData, bufSize);
+ }
+ if (inMeta.findData(kKeyCryptoKey, &bufType, &bufData, &bufSize)) {
+ AMediaFormat_setBuffer(outMeta, AMEDIAFORMAT_KEY_CRYPTO_KEY, bufData, bufSize);
+ }
+ if (inMeta.findData(kKeyPlainSizes, &bufType, &bufData, &bufSize)) {
+ AMediaFormat_setBuffer(outMeta, AMEDIAFORMAT_KEY_CRYPTO_PLAIN_SIZES, bufData, bufSize);
+ }
+ if (inMeta.findData(kKeyEncryptedSizes, &bufType, &bufData, &bufSize)) {
+ AMediaFormat_setBuffer(outMeta, AMEDIAFORMAT_KEY_CRYPTO_ENCRYPTED_SIZES, bufData, bufSize);
+ }
+ if (inMeta.findData(kKeySEI, &bufType, &bufData, &bufSize)) {
+ AMediaFormat_setBuffer(outMeta, AMEDIAFORMAT_KEY_SEI, bufData, bufSize);
+ }
+ return AMEDIA_OK;
}
status_t MPEG2PSExtractor::Track::appendPESData(
@@ -726,7 +780,7 @@
////////////////////////////////////////////////////////////////////////////////
MPEG2PSExtractor::WrappedTrack::WrappedTrack(
- MPEG2PSExtractor *extractor, const sp<Track> &track)
+ MPEG2PSExtractor *extractor, Track *track)
: mExtractor(extractor),
mTrack(track) {
}
@@ -734,20 +788,20 @@
MPEG2PSExtractor::WrappedTrack::~WrappedTrack() {
}
-status_t MPEG2PSExtractor::WrappedTrack::start() {
+media_status_t MPEG2PSExtractor::WrappedTrack::start() {
return mTrack->start();
}
-status_t MPEG2PSExtractor::WrappedTrack::stop() {
+media_status_t MPEG2PSExtractor::WrappedTrack::stop() {
return mTrack->stop();
}
-status_t MPEG2PSExtractor::WrappedTrack::getFormat(MetaDataBase &meta) {
+media_status_t MPEG2PSExtractor::WrappedTrack::getFormat(AMediaFormat *meta) {
return mTrack->getFormat(meta);
}
-status_t MPEG2PSExtractor::WrappedTrack::read(
- MediaBufferBase **buffer, const ReadOptions *options) {
+media_status_t MPEG2PSExtractor::WrappedTrack::read(
+ MediaBufferHelperV3 **buffer, const ReadOptions *options) {
return mTrack->read(buffer, options);
}
diff --git a/media/extractors/mpeg2/MPEG2PSExtractor.h b/media/extractors/mpeg2/MPEG2PSExtractor.h
index c4082ef..d251688 100644
--- a/media/extractors/mpeg2/MPEG2PSExtractor.h
+++ b/media/extractors/mpeg2/MPEG2PSExtractor.h
@@ -32,14 +32,14 @@
struct Track;
class String8;
-struct MPEG2PSExtractor : public MediaExtractorPluginHelper {
+struct MPEG2PSExtractor : public MediaExtractorPluginHelperV3 {
explicit MPEG2PSExtractor(DataSourceHelper *source);
virtual size_t countTracks();
- virtual MediaTrackHelper *getTrack(size_t index);
- virtual status_t getTrackMetaData(MetaDataBase& meta, size_t index, uint32_t flags);
+ virtual MediaTrackHelperV3 *getTrack(size_t index);
+ virtual media_status_t getTrackMetaData(AMediaFormat *meta, size_t index, uint32_t flags);
- virtual status_t getMetaData(MetaDataBase& meta);
+ virtual media_status_t getMetaData(AMediaFormat *meta);
virtual uint32_t flags() const;
virtual const char * name() { return "MPEG2PSExtractor"; }
@@ -57,7 +57,7 @@
off64_t mOffset;
status_t mFinalResult;
sp<ABuffer> mBuffer;
- KeyedVector<unsigned, sp<Track> > mTracks;
+ KeyedVector<unsigned, Track* > mTracks;
bool mScanning;
bool mProgramStreamMapValid;
diff --git a/media/extractors/mpeg2/MPEG2TSExtractor.cpp b/media/extractors/mpeg2/MPEG2TSExtractor.cpp
index 605b13a..fc066ee 100644
--- a/media/extractors/mpeg2/MPEG2TSExtractor.cpp
+++ b/media/extractors/mpeg2/MPEG2TSExtractor.cpp
@@ -34,6 +34,7 @@
#include <media/stagefright/MediaDefs.h>
#include <media/stagefright/MediaErrors.h>
#include <media/stagefright/MetaData.h>
+#include <media/stagefright/Utils.h>
#include <utils/String8.h>
#include "mpeg2ts/AnotherPacketSource.h"
@@ -50,19 +51,19 @@
static const int kMaxDurationReadSize = 250000LL;
static const int kMaxDurationRetry = 6;
-struct MPEG2TSSource : public MediaTrackHelper {
+struct MPEG2TSSource : public MediaTrackHelperV3 {
MPEG2TSSource(
MPEG2TSExtractor *extractor,
const sp<AnotherPacketSource> &impl,
bool doesSeek);
virtual ~MPEG2TSSource();
- virtual status_t start();
- virtual status_t stop();
- virtual status_t getFormat(MetaDataBase &);
+ virtual media_status_t start();
+ virtual media_status_t stop();
+ virtual media_status_t getFormat(AMediaFormat *);
- virtual status_t read(
- MediaBufferBase **buffer, const ReadOptions *options = NULL);
+ virtual media_status_t read(
+ MediaBufferHelperV3 **buffer, const ReadOptions *options = NULL);
private:
MPEG2TSExtractor *mExtractor;
@@ -87,22 +88,84 @@
MPEG2TSSource::~MPEG2TSSource() {
}
-status_t MPEG2TSSource::start() {
- return mImpl->start(NULL); // AnotherPacketSource::start() doesn't use its argument
+media_status_t MPEG2TSSource::start() {
+ // initialize with one small buffer, but allow growth
+ mBufferGroup->init(1 /* one buffer */, 256 /* buffer size */, 64 /* max number of buffers */);
+
+ if (!mImpl->start(NULL)) { // AnotherPacketSource::start() doesn't use its argument
+ return AMEDIA_OK;
+ }
+ return AMEDIA_ERROR_UNKNOWN;
}
-status_t MPEG2TSSource::stop() {
- return mImpl->stop();
+media_status_t MPEG2TSSource::stop() {
+ if (!mImpl->stop()) {
+ return AMEDIA_OK;
+ }
+ return AMEDIA_ERROR_UNKNOWN;
}
-status_t MPEG2TSSource::getFormat(MetaDataBase &meta) {
+void copyAMessageToAMediaFormat(AMediaFormat *format, sp<AMessage> msg) {
+ size_t numEntries = msg->countEntries();
+ for (size_t i = 0; i < numEntries; i++) {
+ AMessage::Type type;
+ const char *name = msg->getEntryNameAt(i, &type);
+ AMessage::ItemData id = msg->getEntryAt(i);
+
+ switch (type) {
+ case AMessage::kTypeInt32:
+ int32_t val32;
+ if (id.find(&val32)) {
+ AMediaFormat_setInt32(format, name, val32);
+ }
+ break;
+ case AMessage::kTypeInt64:
+ int64_t val64;
+ if (id.find(&val64)) {
+ AMediaFormat_setInt64(format, name, val64);
+ }
+ break;
+ case AMessage::kTypeFloat:
+ float valfloat;
+ if (id.find(&valfloat)) {
+ AMediaFormat_setFloat(format, name, valfloat);
+ }
+ break;
+ case AMessage::kTypeDouble:
+ double valdouble;
+ if (id.find(&valdouble)) {
+ AMediaFormat_setDouble(format, name, valdouble);
+ }
+ break;
+ case AMessage::kTypeString:
+ if (AString s; id.find(&s)) {
+ AMediaFormat_setString(format, name, s.c_str());
+ }
+ break;
+ case AMessage::kTypeBuffer:
+ {
+ sp<ABuffer> buffer;
+ if (id.find(&buffer)) {
+ AMediaFormat_setBuffer(format, name, buffer->data(), buffer->size());
+ }
+ break;
+ }
+ default:
+ ALOGW("ignoring unsupported type %d '%s'", type, name);
+ }
+ }
+}
+
+media_status_t MPEG2TSSource::getFormat(AMediaFormat *meta) {
sp<MetaData> implMeta = mImpl->getFormat();
- meta = *implMeta;
- return OK;
+ sp<AMessage> msg;
+ convertMetaDataToMessage(implMeta, &msg);
+ copyAMessageToAMediaFormat(meta, msg);
+ return AMEDIA_OK;
}
-status_t MPEG2TSSource::read(
- MediaBufferBase **out, const ReadOptions *options) {
+media_status_t MPEG2TSSource::read(
+ MediaBufferHelperV3 **out, const ReadOptions *options) {
*out = NULL;
int64_t seekTimeUs;
@@ -110,16 +173,59 @@
if (mDoesSeek && options && options->getSeekTo(&seekTimeUs, &seekMode)) {
// seek is needed
status_t err = mExtractor->seek(seekTimeUs, (ReadOptions::SeekMode)seekMode);
- if (err != OK) {
- return err;
+ if (err == ERROR_END_OF_STREAM) {
+ return AMEDIA_ERROR_END_OF_STREAM;
+ } else if (err != OK) {
+ return AMEDIA_ERROR_UNKNOWN;
}
}
if (mExtractor->feedUntilBufferAvailable(mImpl) != OK) {
- return ERROR_END_OF_STREAM;
+ return AMEDIA_ERROR_END_OF_STREAM;
}
- return mImpl->read(out, (MediaSource::ReadOptions*) options);
+ MediaBufferBase *mbuf;
+ mImpl->read(&mbuf, (MediaTrack::ReadOptions*) options);
+ size_t length = mbuf->range_length();
+ MediaBufferHelperV3 *outbuf;
+ mBufferGroup->acquire_buffer(&outbuf, false, length);
+ memcpy(outbuf->data(), mbuf->data(), length);
+ outbuf->set_range(0, length);
+ *out = outbuf;
+ MetaDataBase &inMeta = mbuf->meta_data();
+ AMediaFormat *outMeta = outbuf->meta_data();
+ AMediaFormat_clear(outMeta);
+ int64_t val64;
+ if (inMeta.findInt64(kKeyTime, &val64)) {
+ AMediaFormat_setInt64(outMeta, AMEDIAFORMAT_KEY_TIME_US, val64);
+ }
+ int32_t val32;
+ if (inMeta.findInt32(kKeyIsSyncFrame, &val32)) {
+ AMediaFormat_setInt32(outMeta, AMEDIAFORMAT_KEY_IS_SYNC_FRAME, val32);
+ }
+ if (inMeta.findInt32(kKeyCryptoMode, &val32)) {
+ AMediaFormat_setInt32(outMeta, AMEDIAFORMAT_KEY_CRYPTO_MODE, val32);
+ }
+ uint32_t bufType;
+ const void *bufData;
+ size_t bufSize;
+ if (inMeta.findData(kKeyCryptoIV, &bufType, &bufData, &bufSize)) {
+ AMediaFormat_setBuffer(outMeta, AMEDIAFORMAT_KEY_CRYPTO_IV, bufData, bufSize);
+ }
+ if (inMeta.findData(kKeyCryptoKey, &bufType, &bufData, &bufSize)) {
+ AMediaFormat_setBuffer(outMeta, AMEDIAFORMAT_KEY_CRYPTO_KEY, bufData, bufSize);
+ }
+ if (inMeta.findData(kKeyPlainSizes, &bufType, &bufData, &bufSize)) {
+ AMediaFormat_setBuffer(outMeta, AMEDIAFORMAT_KEY_CRYPTO_PLAIN_SIZES, bufData, bufSize);
+ }
+ if (inMeta.findData(kKeyEncryptedSizes, &bufType, &bufData, &bufSize)) {
+ AMediaFormat_setBuffer(outMeta, AMEDIAFORMAT_KEY_CRYPTO_ENCRYPTED_SIZES, bufData, bufSize);
+ }
+ if (inMeta.findData(kKeySEI, &bufType, &bufData, &bufSize)) {
+ AMediaFormat_setBuffer(outMeta, AMEDIAFORMAT_KEY_SEI, bufData, bufSize);
+ }
+
+ return AMEDIA_OK;
}
////////////////////////////////////////////////////////////////////////////////
@@ -140,7 +246,7 @@
return mSourceImpls.size();
}
-MediaTrackHelper *MPEG2TSExtractor::getTrack(size_t index) {
+MediaTrackHelperV3 *MPEG2TSExtractor::getTrack(size_t index) {
if (index >= mSourceImpls.size()) {
return NULL;
}
@@ -151,22 +257,23 @@
(mSeekSyncPoints == &mSyncPoints.editItemAt(index)));
}
-status_t MPEG2TSExtractor::getTrackMetaData(
- MetaDataBase &meta,
+media_status_t MPEG2TSExtractor::getTrackMetaData(
+ AMediaFormat *meta,
size_t index, uint32_t /* flags */) {
sp<MetaData> implMeta = index < mSourceImpls.size()
? mSourceImpls.editItemAt(index)->getFormat() : NULL;
if (implMeta == NULL) {
- return UNKNOWN_ERROR;
+ return AMEDIA_ERROR_UNKNOWN;
}
- meta = *implMeta;
- return OK;
+ sp<AMessage> msg = new AMessage;
+ convertMetaDataToMessage(implMeta, &msg);
+ copyAMessageToAMediaFormat(meta, msg);
+ return AMEDIA_OK;
}
-status_t MPEG2TSExtractor::getMetaData(MetaDataBase &meta) {
- meta.setCString(kKeyMIMEType, MEDIA_MIMETYPE_CONTAINER_MPEG2TS);
-
- return OK;
+media_status_t MPEG2TSExtractor::getMetaData(AMediaFormat *meta) {
+ AMediaFormat_setString(meta, AMEDIAFORMAT_KEY_MIME, MEDIA_MIMETYPE_CONTAINER_MPEG2TS);
+ return AMEDIA_OK;
}
//static
@@ -177,7 +284,7 @@
|| !strcasecmp(MEDIA_MIMETYPE_AUDIO_SCRAMBLED, mime));
}
-status_t MPEG2TSExtractor::setMediaCas(const uint8_t* casToken, size_t size) {
+media_status_t MPEG2TSExtractor::setMediaCas(const uint8_t* casToken, size_t size) {
HalToken halToken;
halToken.setToExternal((uint8_t*)casToken, size);
sp<ICas> cas = ICas::castFrom(retrieveHalInterface(halToken));
@@ -187,8 +294,9 @@
if (err == OK) {
ALOGI("All tracks now have descramblers");
init();
+ return AMEDIA_OK;
}
- return err;
+ return AMEDIA_ERROR_UNKNOWN;
}
void MPEG2TSExtractor::addSource(const sp<AnotherPacketSource> &impl) {
@@ -494,7 +602,7 @@
}
status_t MPEG2TSExtractor::seek(int64_t seekTimeUs,
- const MediaTrackHelper::ReadOptions::SeekMode &seekMode) {
+ const MediaTrackHelperV3::ReadOptions::SeekMode &seekMode) {
if (mSeekSyncPoints == NULL || mSeekSyncPoints->isEmpty()) {
ALOGW("No sync point to seek to.");
// ... and therefore we have nothing useful to do here.
@@ -515,18 +623,18 @@
}
switch (seekMode) {
- case MediaTrackHelper::ReadOptions::SEEK_NEXT_SYNC:
+ case MediaTrackHelperV3::ReadOptions::SEEK_NEXT_SYNC:
if (index == mSeekSyncPoints->size()) {
ALOGW("Next sync not found; starting from the latest sync.");
--index;
}
break;
- case MediaTrackHelper::ReadOptions::SEEK_CLOSEST_SYNC:
- case MediaTrackHelper::ReadOptions::SEEK_CLOSEST:
+ case MediaTrackHelperV3::ReadOptions::SEEK_CLOSEST_SYNC:
+ case MediaTrackHelperV3::ReadOptions::SEEK_CLOSEST:
ALOGW("seekMode not supported: %d; falling back to PREVIOUS_SYNC",
seekMode);
FALLTHROUGH_INTENDED;
- case MediaTrackHelper::ReadOptions::SEEK_PREVIOUS_SYNC:
+ case MediaTrackHelperV3::ReadOptions::SEEK_PREVIOUS_SYNC:
if (index == 0) {
ALOGW("Previous sync not found; starting from the earliest "
"sync.");
diff --git a/media/extractors/mpeg2/MPEG2TSExtractor.h b/media/extractors/mpeg2/MPEG2TSExtractor.h
index 4013442..aed17bb 100644
--- a/media/extractors/mpeg2/MPEG2TSExtractor.h
+++ b/media/extractors/mpeg2/MPEG2TSExtractor.h
@@ -38,16 +38,16 @@
struct MPEG2TSSource;
class String8;
-struct MPEG2TSExtractor : public MediaExtractorPluginHelper {
+struct MPEG2TSExtractor : public MediaExtractorPluginHelperV3 {
explicit MPEG2TSExtractor(DataSourceHelper *source);
virtual size_t countTracks();
- virtual MediaTrackHelper *getTrack(size_t index);
- virtual status_t getTrackMetaData(MetaDataBase &meta, size_t index, uint32_t flags);
+ virtual MediaTrackHelperV3 *getTrack(size_t index);
+ virtual media_status_t getTrackMetaData(AMediaFormat *meta, size_t index, uint32_t flags);
- virtual status_t getMetaData(MetaDataBase& meta);
+ virtual media_status_t getMetaData(AMediaFormat *meta);
- virtual status_t setMediaCas(const uint8_t* /*casToken*/, size_t /*size*/) override;
+ virtual media_status_t setMediaCas(const uint8_t* /*casToken*/, size_t /*size*/) override;
virtual uint32_t flags() const;
virtual const char * name() { return "MPEG2TSExtractor"; }
@@ -90,7 +90,7 @@
// the data has syntax error during parsing, etc.
status_t feedMore(bool isInit = false);
status_t seek(int64_t seekTimeUs,
- const MediaTrackHelper::ReadOptions::SeekMode& seekMode);
+ const MediaTrackHelperV3::ReadOptions::SeekMode& seekMode);
status_t queueDiscontinuityForSeek(int64_t actualSeekTimeUs);
status_t seekBeyond(int64_t seekTimeUs);
diff --git a/media/extractors/ogg/Android.bp b/media/extractors/ogg/Android.bp
index b28877d..604ec59 100644
--- a/media/extractors/ogg/Android.bp
+++ b/media/extractors/ogg/Android.bp
@@ -13,7 +13,6 @@
shared_libs: [
"liblog",
- "libmediaextractor",
"libmediandk",
],
diff --git a/media/extractors/ogg/OggExtractor.cpp b/media/extractors/ogg/OggExtractor.cpp
index cc2c792..29fe2b1 100644
--- a/media/extractors/ogg/OggExtractor.cpp
+++ b/media/extractors/ogg/OggExtractor.cpp
@@ -28,11 +28,8 @@
#include <media/stagefright/foundation/ADebug.h>
#include <media/stagefright/foundation/base64.h>
#include <media/stagefright/foundation/ByteUtils.h>
-#include <media/stagefright/MediaBufferBase.h>
-#include <media/stagefright/MediaBufferGroup.h>
#include <media/stagefright/MediaDefs.h>
#include <media/stagefright/MediaErrors.h>
-#include <media/stagefright/MetaDataBase.h>
#include <media/stagefright/MetaDataUtils.h>
#include <system/audio.h>
#include <utils/String8.h>
@@ -48,7 +45,7 @@
namespace android {
-struct OggSource : public MediaTrackHelperV2 {
+struct OggSource : public MediaTrackHelperV3 {
explicit OggSource(OggExtractor *extractor);
virtual media_status_t getFormat(AMediaFormat *);
@@ -57,7 +54,7 @@
virtual media_status_t stop();
virtual media_status_t read(
- MediaBufferBase **buffer, const ReadOptions *options = NULL);
+ MediaBufferHelperV3 **buffer, const ReadOptions *options = NULL);
protected:
virtual ~OggSource();
@@ -85,7 +82,7 @@
status_t seekToTime(int64_t timeUs);
status_t seekToOffset(off64_t offset);
- virtual media_status_t readNextPacket(MediaBufferBase **buffer) = 0;
+ virtual media_status_t readNextPacket(MediaBufferHelperV3 **buffer) = 0;
status_t init();
@@ -93,6 +90,9 @@
return AMediaFormat_copy(meta, mFileMeta);
}
+ void setBufferGroup(MediaBufferGroupHelperV3 *group) {
+ mBufferGroup = group;
+ }
protected:
struct Page {
uint64_t mGranulePosition;
@@ -110,6 +110,7 @@
int64_t mTimeUs;
};
+ MediaBufferGroupHelperV3 *mBufferGroup;
DataSourceHelper *mSource;
off64_t mOffset;
Page mCurrentPage;
@@ -148,7 +149,7 @@
// 1 - bitstream identification header
// 3 - comment header
// 5 - codec setup header (Vorbis only)
- virtual media_status_t verifyHeader(MediaBufferBase *buffer, uint8_t type) = 0;
+ virtual media_status_t verifyHeader(MediaBufferHelperV3 *buffer, uint8_t type) = 0;
// Read the next ogg packet from the underlying data source; optionally
// calculate the timestamp for the output packet whilst pretending
@@ -156,9 +157,9 @@
//
// *buffer is NULL'ed out immediately upon entry, and if successful a new buffer is allocated;
// clients are responsible for releasing the original buffer.
- media_status_t _readNextPacket(MediaBufferBase **buffer, bool calcVorbisTimestamp);
+ media_status_t _readNextPacket(MediaBufferHelperV3 **buffer, bool calcVorbisTimestamp);
- int32_t getPacketBlockSize(MediaBufferBase *buffer);
+ int32_t getPacketBlockSize(MediaBufferHelperV3 *buffer);
void parseFileMetaData();
@@ -182,7 +183,7 @@
virtual uint64_t approxBitrate() const;
- virtual media_status_t readNextPacket(MediaBufferBase **buffer) {
+ virtual media_status_t readNextPacket(MediaBufferHelperV3 **buffer) {
return _readNextPacket(buffer, /* calcVorbisTimestamp = */ true);
}
@@ -194,7 +195,7 @@
return granulePos * 1000000ll / mVi.rate;
}
- virtual media_status_t verifyHeader(MediaBufferBase *buffer, uint8_t type);
+ virtual media_status_t verifyHeader(MediaBufferHelperV3 *buffer, uint8_t type);
};
struct MyOpusExtractor : public MyOggExtractor {
@@ -212,16 +213,16 @@
return 0;
}
- virtual media_status_t readNextPacket(MediaBufferBase **buffer);
+ virtual media_status_t readNextPacket(MediaBufferHelperV3 **buffer);
protected:
virtual int64_t getTimeUsOfGranule(uint64_t granulePos) const;
- virtual media_status_t verifyHeader(MediaBufferBase *buffer, uint8_t type);
+ virtual media_status_t verifyHeader(MediaBufferHelperV3 *buffer, uint8_t type);
private:
- media_status_t verifyOpusHeader(MediaBufferBase *buffer);
- media_status_t verifyOpusComments(MediaBufferBase *buffer);
- uint32_t getNumSamplesInPacket(MediaBufferBase *buffer) const;
+ media_status_t verifyOpusHeader(MediaBufferHelperV3 *buffer);
+ media_status_t verifyOpusComments(MediaBufferHelperV3 *buffer);
+ uint32_t getNumSamplesInPacket(MediaBufferHelperV3 *buffer) const;
uint8_t mChannelCount;
uint16_t mCodecDelay;
@@ -249,7 +250,9 @@
if (mStarted) {
return AMEDIA_ERROR_INVALID_OPERATION;
}
-
+ // initialize buffer group with a single small buffer, but a generous upper limit
+ mBufferGroup->init(1 /* number of buffers */, 128 /* size */, 64 /* max number of buffers */);
+ mExtractor->mImpl->setBufferGroup(mBufferGroup);
mStarted = true;
return AMEDIA_OK;
@@ -262,7 +265,7 @@
}
media_status_t OggSource::read(
- MediaBufferBase **out, const ReadOptions *options) {
+ MediaBufferHelperV3 **out, const ReadOptions *options) {
*out = NULL;
int64_t seekTimeUs;
@@ -274,26 +277,27 @@
}
}
- MediaBufferBase *packet;
+ MediaBufferHelperV3 *packet;
media_status_t err = mExtractor->mImpl->readNextPacket(&packet);
if (err != AMEDIA_OK) {
return err;
}
+ AMediaFormat *meta = packet->meta_data();
#if 0
int64_t timeUs;
- if (packet->meta_data().findInt64(kKeyTime, &timeUs)) {
+ if (AMediaFormat_findInt64(meta, AMEDIAFORMAT_KEY_TIME_US, timeStampUs)) {
ALOGI("found time = %lld us", timeUs);
} else {
ALOGI("NO time");
}
#endif
- packet->meta_data().setInt32(kKeyIsSyncFrame, 1);
+ AMediaFormat_setInt32(meta, AMEDIAFORMAT_KEY_IS_SYNC_FRAME, 1);
*out = packet;
-
+ ALOGV("returning buffer %p", packet);
return AMEDIA_OK;
}
@@ -304,7 +308,8 @@
const char *mimeType,
size_t numHeaders,
int64_t seekPreRollUs)
- : mSource(source),
+ : mBufferGroup(NULL),
+ mSource(source),
mOffset(0),
mCurGranulePosition(0),
mPrevGranulePosition(0),
@@ -573,13 +578,13 @@
return sizeof(header) + page->mNumSegments + totalSize;
}
-media_status_t MyOpusExtractor::readNextPacket(MediaBufferBase **out) {
+media_status_t MyOpusExtractor::readNextPacket(MediaBufferHelperV3 **out) {
if (mOffset <= mFirstDataOffset && mStartGranulePosition < 0) {
// The first sample might not start at time 0; find out where by subtracting
// the number of samples on the first page from the granule position
// (position of last complete sample) of the first page. This happens
// the first time before we attempt to read a packet from the first page.
- MediaBufferBase *mBuf;
+ MediaBufferHelperV3 *mBuf;
uint32_t numSamples = 0;
uint64_t curGranulePosition = 0;
while (true) {
@@ -617,24 +622,25 @@
int32_t currentPageSamples;
// Calculate timestamps by accumulating durations starting from the first sample of a page;
// We assume that we only seek to page boundaries.
- if ((*out)->meta_data().findInt32(kKeyValidSamples, ¤tPageSamples)) {
+ AMediaFormat *meta = (*out)->meta_data();
+ if (AMediaFormat_getInt32(meta, AMEDIAFORMAT_KEY_VALID_SAMPLES, ¤tPageSamples)) {
// first packet in page
if (mOffset == mFirstDataOffset) {
currentPageSamples -= mStartGranulePosition;
- (*out)->meta_data().setInt32(kKeyValidSamples, currentPageSamples);
+ AMediaFormat_setInt32(meta, AMEDIAFORMAT_KEY_VALID_SAMPLES, currentPageSamples);
}
mCurGranulePosition = mCurrentPage.mGranulePosition - currentPageSamples;
}
int64_t timeUs = getTimeUsOfGranule(mCurGranulePosition);
- (*out)->meta_data().setInt64(kKeyTime, timeUs);
+ AMediaFormat_setInt64(meta, AMEDIAFORMAT_KEY_TIME_US, timeUs);
uint32_t frames = getNumSamplesInPacket(*out);
mCurGranulePosition += frames;
return AMEDIA_OK;
}
-uint32_t MyOpusExtractor::getNumSamplesInPacket(MediaBufferBase *buffer) const {
+uint32_t MyOpusExtractor::getNumSamplesInPacket(MediaBufferHelperV3 *buffer) const {
if (buffer == NULL || buffer->range_length() < 1) {
return 0;
}
@@ -680,10 +686,66 @@
return numSamples;
}
-media_status_t MyOggExtractor::_readNextPacket(MediaBufferBase **out, bool calcVorbisTimestamp) {
+/*
+ * basic mediabuffer implementation used during initial parsing of the
+ * header packets, which happens before we have a buffer group
+ */
+class StandAloneMediaBuffer : public MediaBufferHelperV3 {
+private:
+ void *mData;
+ size_t mSize;
+ size_t mOffset;
+ size_t mLength;
+ AMediaFormat *mFormat;
+public:
+ StandAloneMediaBuffer(size_t size) : MediaBufferHelperV3(NULL) {
+ mSize = size;
+ mData = malloc(mSize);
+ mOffset = 0;
+ mLength = mSize;
+ mFormat = AMediaFormat_new();
+ ALOGV("created standalone media buffer %p of size %zu", this, mSize);
+ }
+
+ ~StandAloneMediaBuffer() override {
+ free(mData);
+ AMediaFormat_delete(mFormat);
+ ALOGV("deleted standalone media buffer %p of size %zu", this, mSize);
+ }
+
+ void release() override {
+ delete this;
+ }
+
+ void* data() override {
+ return mData;
+ }
+
+ size_t size() override {
+ return mSize;
+ }
+
+ size_t range_offset() override {
+ return mOffset;
+ }
+
+ size_t range_length() override {
+ return mLength;
+ }
+
+ void set_range(size_t offset, size_t length) override {
+ mOffset = offset;
+ mLength = length;
+ }
+ AMediaFormat *meta_data() override {
+ return mFormat;
+ }
+};
+
+media_status_t MyOggExtractor::_readNextPacket(MediaBufferHelperV3 **out, bool calcVorbisTimestamp) {
*out = NULL;
- MediaBufferBase *buffer = NULL;
+ MediaBufferHelperV3 *buffer = NULL;
int64_t timeUs = -1;
for (;;) {
@@ -719,7 +781,13 @@
ALOGE("b/36592202");
return AMEDIA_ERROR_MALFORMED;
}
- MediaBufferBase *tmp = MediaBufferBase::Create(fullSize);
+ MediaBufferHelperV3 *tmp;
+ if (mBufferGroup) {
+ mBufferGroup->acquire_buffer(&tmp, false, fullSize);
+ ALOGV("acquired buffer %p from group", tmp);
+ } else {
+ tmp = new StandAloneMediaBuffer(fullSize);
+ }
if (tmp == NULL) {
if (buffer != NULL) {
buffer->release();
@@ -727,6 +795,7 @@
ALOGE("b/36592202");
return AMEDIA_ERROR_MALFORMED;
}
+ AMediaFormat_clear(tmp->meta_data());
if (buffer != NULL) {
memcpy(tmp->data(), buffer->data(), buffer->range_length());
tmp->set_range(0, buffer->range_length());
@@ -756,8 +825,9 @@
// We've just read the entire packet.
if (mFirstPacketInPage) {
- buffer->meta_data().setInt32(
- kKeyValidSamples, mCurrentPageSamples);
+ AMediaFormat *meta = buffer->meta_data();
+ AMediaFormat_setInt32(
+ meta, AMEDIAFORMAT_KEY_VALID_SAMPLES, mCurrentPageSamples);
mFirstPacketInPage = false;
}
@@ -778,7 +848,8 @@
mCurrentPage.mPrevPacketPos += actualBlockSize / 2;
mCurrentPage.mPrevPacketSize = curBlockSize;
}
- buffer->meta_data().setInt64(kKeyTime, timeUs);
+ AMediaFormat *meta = buffer->meta_data();
+ AMediaFormat_setInt64(meta, AMEDIAFORMAT_KEY_TIME_US, timeUs);
}
*out = buffer;
@@ -824,11 +895,13 @@
// is already complete.
if (timeUs >= 0) {
- buffer->meta_data().setInt64(kKeyTime, timeUs);
+ AMediaFormat *meta = buffer->meta_data();
+ AMediaFormat_setInt64(meta, AMEDIAFORMAT_KEY_TIME_US, timeUs);
}
- buffer->meta_data().setInt32(
- kKeyValidSamples, mCurrentPageSamples);
+ AMediaFormat *meta = buffer->meta_data();
+ AMediaFormat_setInt32(
+ meta, AMEDIAFORMAT_KEY_VALID_SAMPLES, mCurrentPageSamples);
mFirstPacketInPage = false;
*out = buffer;
@@ -843,7 +916,7 @@
AMediaFormat_setString(mMeta, AMEDIAFORMAT_KEY_MIME, mMimeType);
media_status_t err;
- MediaBufferBase *packet;
+ MediaBufferHelperV3 *packet;
for (size_t i = 0; i < mNumHeaders; ++i) {
// ignore timestamp for configuration packets
if ((err = _readNextPacket(&packet, /* calcVorbisTimestamp = */ false)) != AMEDIA_OK) {
@@ -920,7 +993,7 @@
}
}
-int32_t MyOggExtractor::getPacketBlockSize(MediaBufferBase *buffer) {
+int32_t MyOggExtractor::getPacketBlockSize(MediaBufferHelperV3 *buffer) {
const uint8_t *data =
(const uint8_t *)buffer->data() + buffer->range_offset();
@@ -960,7 +1033,7 @@
return pcmSamplePosition * 1000000ll / kOpusSampleRate;
}
-media_status_t MyOpusExtractor::verifyHeader(MediaBufferBase *buffer, uint8_t type) {
+media_status_t MyOpusExtractor::verifyHeader(MediaBufferHelperV3 *buffer, uint8_t type) {
switch (type) {
// there are actually no header types defined in the Opus spec; we choose 1 and 3 to mean
// header and comments such that we can share code with MyVorbisExtractor.
@@ -973,7 +1046,7 @@
}
}
-media_status_t MyOpusExtractor::verifyOpusHeader(MediaBufferBase *buffer) {
+media_status_t MyOpusExtractor::verifyOpusHeader(MediaBufferHelperV3 *buffer) {
const size_t kOpusHeaderSize = 19;
const uint8_t *data =
(const uint8_t *)buffer->data() + buffer->range_offset();
@@ -1001,7 +1074,7 @@
return AMEDIA_OK;
}
-media_status_t MyOpusExtractor::verifyOpusComments(MediaBufferBase *buffer) {
+media_status_t MyOpusExtractor::verifyOpusComments(MediaBufferHelperV3 *buffer) {
// add artificial framing bit so we can reuse _vorbis_unpack_comment
int32_t commentSize = buffer->range_length() + 1;
auto tmp = heapbuffer<uint8_t>(commentSize);
@@ -1094,7 +1167,7 @@
}
media_status_t MyVorbisExtractor::verifyHeader(
- MediaBufferBase *buffer, uint8_t type) {
+ MediaBufferHelperV3 *buffer, uint8_t type) {
const uint8_t *data =
(const uint8_t *)buffer->data() + buffer->range_offset();
@@ -1262,7 +1335,7 @@
return mInitCheck != OK ? 0 : 1;
}
-MediaTrackHelperV2 *OggExtractor::getTrack(size_t index) {
+MediaTrackHelperV3 *OggExtractor::getTrack(size_t index) {
if (index >= 1) {
return NULL;
}
@@ -1284,13 +1357,13 @@
return mImpl->getFileMetaData(meta);
}
-static CMediaExtractorV2* CreateExtractor(
+static CMediaExtractorV3* CreateExtractor(
CDataSource *source,
void *) {
- return wrapV2(new OggExtractor(new DataSourceHelper(source)));
+ return wrapV3(new OggExtractor(new DataSourceHelper(source)));
}
-static CreatorFuncV2 Sniff(
+static CreatorFuncV3 Sniff(
CDataSource *source,
float *confidence,
void **,
@@ -1311,11 +1384,11 @@
__attribute__ ((visibility ("default")))
ExtractorDef GETEXTRACTORDEF() {
return {
- EXTRACTORDEF_VERSION_CURRENT,
+ EXTRACTORDEF_VERSION_CURRENT + 1,
UUID("8cc5cd06-f772-495e-8a62-cba9649374e9"),
1, // version
"Ogg Extractor",
- { .v2 = Sniff }
+ { .v3 = Sniff }
};
}
diff --git a/media/extractors/ogg/OggExtractor.h b/media/extractors/ogg/OggExtractor.h
index cd674f3..97506ad 100644
--- a/media/extractors/ogg/OggExtractor.h
+++ b/media/extractors/ogg/OggExtractor.h
@@ -31,11 +31,11 @@
struct MyOggExtractor;
struct OggSource;
-struct OggExtractor : public MediaExtractorPluginHelperV2 {
+struct OggExtractor : public MediaExtractorPluginHelperV3 {
explicit OggExtractor(DataSourceHelper *source);
virtual size_t countTracks();
- virtual MediaTrackHelperV2 *getTrack(size_t index);
+ virtual MediaTrackHelperV3 *getTrack(size_t index);
virtual media_status_t getTrackMetaData(AMediaFormat *meta, size_t index, uint32_t flags);
virtual media_status_t getMetaData(AMediaFormat *meta);
diff --git a/media/libaaudio/src/client/AudioStreamInternalCapture.cpp b/media/libaaudio/src/client/AudioStreamInternalCapture.cpp
index 4a0e6da..58ef7b1 100644
--- a/media/libaaudio/src/client/AudioStreamInternalCapture.cpp
+++ b/media/libaaudio/src/client/AudioStreamInternalCapture.cpp
@@ -258,7 +258,7 @@
callbackResult = maybeCallDataCallback(mCallbackBuffer, mCallbackFrames);
if (callbackResult == AAUDIO_CALLBACK_RESULT_STOP) {
- ALOGD("callback returned AAUDIO_CALLBACK_RESULT_STOP");
+ ALOGD("%s(): callback returned AAUDIO_CALLBACK_RESULT_STOP", __func__);
break;
}
}
diff --git a/media/libaaudio/src/client/AudioStreamInternalPlay.cpp b/media/libaaudio/src/client/AudioStreamInternalPlay.cpp
index 2ae37a5..9af47b2 100644
--- a/media/libaaudio/src/client/AudioStreamInternalPlay.cpp
+++ b/media/libaaudio/src/client/AudioStreamInternalPlay.cpp
@@ -293,7 +293,7 @@
break;
}
} else if (callbackResult == AAUDIO_CALLBACK_RESULT_STOP) {
- ALOGV("%s(): callback returned AAUDIO_CALLBACK_RESULT_STOP", __func__);
+ ALOGD("%s(): callback returned AAUDIO_CALLBACK_RESULT_STOP", __func__);
break;
}
}
diff --git a/media/libaaudio/tests/Android.bp b/media/libaaudio/tests/Android.bp
index 319467e..cb243a0 100644
--- a/media/libaaudio/tests/Android.bp
+++ b/media/libaaudio/tests/Android.bp
@@ -184,3 +184,15 @@
"libutils",
],
}
+
+cc_test {
+ name: "test_return_stop",
+ defaults: ["libaaudio_tests_defaults"],
+ srcs: ["test_return_stop.cpp"],
+ shared_libs: [
+ "libaaudio",
+ "libbinder",
+ "libcutils",
+ "libutils",
+ ],
+}
diff --git a/media/libaaudio/tests/test_return_stop.cpp b/media/libaaudio/tests/test_return_stop.cpp
new file mode 100644
index 0000000..9a9e00c
--- /dev/null
+++ b/media/libaaudio/tests/test_return_stop.cpp
@@ -0,0 +1,282 @@
+/*
+ * Copyright (C) 2018 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * Return stop from the callback.
+ * Expect the callback to cease.
+ * Check the logcat for bad behavior.
+ */
+
+#include <stdio.h>
+#include <thread>
+#include <unistd.h>
+
+#include <aaudio/AAudio.h>
+
+#define DEFAULT_TIMEOUT_NANOS ((int64_t)1000000000)
+#define STOP_AT_MSEC 1000
+#define LOOP_DURATION_MSEC 4000
+#define SLEEP_DURATION_MSEC 200
+
+static void s_myErrorCallbackProc(
+ AAudioStream *stream,
+ void *userData,
+ aaudio_result_t error);
+
+struct AudioEngine {
+ AAudioStreamBuilder *builder = nullptr;
+ AAudioStream *stream = nullptr;
+ std::thread *thread = nullptr;
+ int32_t stopAtFrame = 0;
+ bool stopped = false;
+ // These counters are read and written by the callback and the main thread.
+ std::atomic<int32_t> framesRead{};
+ std::atomic<int32_t> startingFramesRead{};
+ std::atomic<int32_t> framesCalled{};
+ std::atomic<int32_t> callbackCount{};
+ std::atomic<int32_t> callbackCountAfterStop{};
+
+ void reset() {
+ framesRead.store(0);
+ startingFramesRead.store(0);
+ framesCalled.store(0);
+ callbackCount.store(0);
+ callbackCountAfterStop.store(0);
+ stopped = false;
+ }
+};
+
+// Callback function that fills the audio output buffer.
+static aaudio_data_callback_result_t s_myDataCallbackProc(
+ AAudioStream *stream,
+ void *userData,
+ void *audioData,
+ int32_t numFrames
+) {
+ (void) audioData;
+ (void) numFrames;
+ AudioEngine *engine = (struct AudioEngine *)userData;
+ engine->callbackCount++;
+ if (engine->stopped) {
+ engine->callbackCountAfterStop++;
+ }
+
+ engine->framesRead = (int32_t)AAudioStream_getFramesRead(stream);
+ if (engine->startingFramesRead == 0) {
+ engine->startingFramesRead.store(engine->framesRead.load());
+ }
+ engine->framesCalled += numFrames;
+ if (engine->framesCalled >= engine->stopAtFrame) {
+ engine->stopped = true;
+ return AAUDIO_CALLBACK_RESULT_STOP;
+ } else {
+ return AAUDIO_CALLBACK_RESULT_CONTINUE;
+ }
+}
+
+static aaudio_result_t s_OpenAudioStream(struct AudioEngine *engine,
+ aaudio_direction_t direction,
+ aaudio_sharing_mode_t sharingMode,
+ aaudio_performance_mode_t perfMode) {
+ // Use an AAudioStreamBuilder to contain requested parameters.
+ aaudio_result_t result = AAudio_createStreamBuilder(&engine->builder);
+ if (result != AAUDIO_OK) {
+ printf("AAudio_createStreamBuilder returned %s",
+ AAudio_convertResultToText(result));
+ return result;
+ }
+
+ // Request stream properties.
+ AAudioStreamBuilder_setFormat(engine->builder, AAUDIO_FORMAT_PCM_FLOAT);
+ AAudioStreamBuilder_setPerformanceMode(engine->builder, perfMode);
+ AAudioStreamBuilder_setSharingMode(engine->builder, sharingMode);
+ AAudioStreamBuilder_setDirection(engine->builder, direction);
+ AAudioStreamBuilder_setDataCallback(engine->builder, s_myDataCallbackProc, engine);
+ AAudioStreamBuilder_setErrorCallback(engine->builder, s_myErrorCallbackProc, engine);
+
+ // Create an AAudioStream using the Builder.
+ result = AAudioStreamBuilder_openStream(engine->builder, &engine->stream);
+ if (result != AAUDIO_OK) {
+ printf("AAudioStreamBuilder_openStream returned %s",
+ AAudio_convertResultToText(result));
+ return result;
+ }
+
+ return result;
+}
+
+static aaudio_result_t s_CloseAudioStream(struct AudioEngine *engine) {
+ aaudio_result_t result = AAUDIO_OK;
+ if (engine->stream != nullptr) {
+ result = AAudioStream_close(engine->stream);
+ if (result != AAUDIO_OK) {
+ printf("AAudioStream_close returned %s\n",
+ AAudio_convertResultToText(result));
+ }
+ engine->stream = nullptr;
+ }
+ AAudioStreamBuilder_delete(engine->builder);
+ engine->builder = nullptr;
+ return result;
+}
+
+static void s_myErrorCallbackProc(
+ AAudioStream *stream __unused,
+ void *userData __unused,
+ aaudio_result_t error) {
+ printf("%s() - error = %d\n", __func__, error);
+}
+
+void usage() {
+ printf("test_return_stop [-i] [-x] [-n] [-c]\n");
+ printf(" -i direction INPUT, otherwise OUTPUT\n");
+ printf(" -x sharing mode EXCLUSIVE, otherwise SHARED\n");
+ printf(" -n performance mode NONE, otherwise LOW_LATENCY\n");
+ printf(" -c always return CONTINUE from callback, not STOP\n");
+}
+
+int main(int argc, char **argv) {
+ (void) argc;
+ (void) argv;
+ struct AudioEngine engine;
+ aaudio_sharing_mode_t sharingMode = AAUDIO_SHARING_MODE_SHARED;
+ aaudio_performance_mode_t perfMode = AAUDIO_PERFORMANCE_MODE_LOW_LATENCY;
+ aaudio_direction_t direction = AAUDIO_DIRECTION_OUTPUT;
+ aaudio_result_t result = AAUDIO_OK;
+ bool alwaysContinue = false;
+ int errorCount = 0;
+ int callbackResult = EXIT_SUCCESS;
+
+ // Make printf print immediately so that debug info is not stuck
+ // in a buffer if we hang or crash.
+ setvbuf(stdout, nullptr, _IONBF, (size_t) 0);
+
+ printf("Test Return Stop V1.0\n");
+ printf("Wait for a few seconds.\n");
+ printf("You should see callbackCount and framesRead stop advancing\n");
+ printf("when callbackCount reaches %d msec\n", STOP_AT_MSEC);
+ printf("\n");
+
+ for (int i = 1; i < argc; i++) {
+ const char *arg = argv[i];
+ if (arg[0] == '-') {
+ char option = arg[1];
+ switch (option) {
+ case 'c':
+ alwaysContinue = true;
+ break;
+ case 'i':
+ direction = AAUDIO_DIRECTION_INPUT;
+ break;
+ case 'n':
+ perfMode = AAUDIO_PERFORMANCE_MODE_NONE;
+ break;
+ case 'x':
+ sharingMode = AAUDIO_SHARING_MODE_EXCLUSIVE;
+ break;
+ default:
+ usage();
+ exit(EXIT_FAILURE);
+ break;
+ }
+ } else {
+ usage();
+ exit(EXIT_FAILURE);
+ break;
+ }
+ }
+
+ result = s_OpenAudioStream(&engine, direction, sharingMode, perfMode);
+ if (result != AAUDIO_OK) {
+ printf("s_OpenAudioStream returned %s",
+ AAudio_convertResultToText(result));
+ errorCount++;
+ }
+
+ int32_t framesPerBurst = AAudioStream_getFramesPerBurst(engine.stream);
+ // Check to see what kind of stream we actually got.
+ int32_t deviceId = AAudioStream_getDeviceId(engine.stream);
+ aaudio_performance_mode_t actualPerfMode = AAudioStream_getPerformanceMode(engine.stream);
+ printf("-------- opened: deviceId = %3d, framesPerBurst = %3d, perfMode = %d\n",
+ deviceId, framesPerBurst, actualPerfMode);
+
+ // Calculate how many callbacks needed.
+ if (alwaysContinue) {
+ engine.stopAtFrame = INT32_MAX;
+ } else {
+ int32_t sampleRate = AAudioStream_getSampleRate(engine.stream);
+ engine.stopAtFrame = STOP_AT_MSEC * sampleRate / 1000;
+ }
+
+ for (int loops = 0; loops < 2 && result == AAUDIO_OK; loops++) {
+ engine.reset();
+
+ // Start stream.
+ result = AAudioStream_requestStart(engine.stream);
+ printf("AAudioStream_requestStart() returned %d >>>>>>>>>>>>>>>>>>>>>>\n", result);
+ if (result != AAUDIO_OK) {
+ errorCount++;
+ break;
+ }
+
+ if (result == AAUDIO_OK) {
+ const int watchLoops = LOOP_DURATION_MSEC / SLEEP_DURATION_MSEC;
+ for (int i = watchLoops; i > 0; i--) {
+ printf("playing silence #%02d, framesRead = %7d, framesWritten = %7d,"
+ " framesCalled = %6d, callbackCount = %4d\n",
+ i,
+ (int32_t) AAudioStream_getFramesRead(engine.stream),
+ (int32_t) AAudioStream_getFramesWritten(engine.stream),
+ engine.framesCalled.load(),
+ engine.callbackCount.load()
+ );
+ usleep(SLEEP_DURATION_MSEC * 1000);
+ }
+ }
+
+ if (engine.stopAtFrame != INT32_MAX) {
+ callbackResult = (engine.callbackCountAfterStop == 0) ? EXIT_SUCCESS
+ : EXIT_FAILURE;
+ if (callbackResult) {
+ printf("ERROR - Callback count after STOP = %d\n",
+ engine.callbackCountAfterStop.load());
+ errorCount++;
+ }
+ }
+
+ if (engine.startingFramesRead.load() == engine.framesRead.load()) {
+ printf("ERROR - framesRead did not advance across callbacks\n");
+ errorCount++;
+ }
+
+ result = AAudioStream_requestStop(engine.stream);
+ printf("AAudioStream_requestStop() returned %d <<<<<<<<<<<<<<<<<<<<<\n", result);
+ if (result != AAUDIO_OK) {
+ errorCount++;
+ }
+ usleep(SLEEP_DURATION_MSEC * 1000);
+ printf("getFramesRead() = %d, getFramesWritten() = %d\n",
+ (int32_t) AAudioStream_getFramesRead(engine.stream),
+ (int32_t) AAudioStream_getFramesWritten(engine.stream));
+ }
+
+ s_CloseAudioStream(&engine);
+
+ printf("aaudio result = %d = %s\n", result, AAudio_convertResultToText(result));
+ printf("test %s\n", errorCount ? "FAILED" : "PASSED");
+
+ return errorCount ? EXIT_FAILURE : EXIT_SUCCESS;
+}
diff --git a/media/libaudiohal/EffectsFactoryHalInterface.cpp b/media/libaudiohal/EffectsFactoryHalInterface.cpp
index e21c235..bd3ef61 100644
--- a/media/libaudiohal/EffectsFactoryHalInterface.cpp
+++ b/media/libaudiohal/EffectsFactoryHalInterface.cpp
@@ -25,13 +25,13 @@
// static
sp<EffectsFactoryHalInterface> EffectsFactoryHalInterface::create() {
if (hardware::audio::effect::V5_0::IEffectsFactory::getService() != nullptr) {
- return V5_0::createEffectsFactoryHal();
+ return effect::V5_0::createEffectsFactoryHal();
}
if (hardware::audio::effect::V4_0::IEffectsFactory::getService() != nullptr) {
- return V4_0::createEffectsFactoryHal();
+ return effect::V4_0::createEffectsFactoryHal();
}
if (hardware::audio::effect::V2_0::IEffectsFactory::getService() != nullptr) {
- return V2_0::createEffectsFactoryHal();
+ return effect::V2_0::createEffectsFactoryHal();
}
return nullptr;
}
diff --git a/media/libaudiohal/HalDeathHandlerHidl.cpp b/media/libaudiohal/HalDeathHandlerHidl.cpp
index 1e3ab58..6e33523 100644
--- a/media/libaudiohal/HalDeathHandlerHidl.cpp
+++ b/media/libaudiohal/HalDeathHandlerHidl.cpp
@@ -54,7 +54,7 @@
handler.second();
}
ALOGE("HAL server crashed, audio server is restarting");
- exit(1);
+ _exit(1); // Avoid calling atexit handlers, as this code runs on a thread from RPC threadpool.
}
} // namespace android
diff --git a/media/libaudiohal/impl/ConversionHelperHidl.cpp b/media/libaudiohal/impl/ConversionHelperHidl.cpp
index 9747859..9f8a520 100644
--- a/media/libaudiohal/impl/ConversionHelperHidl.cpp
+++ b/media/libaudiohal/impl/ConversionHelperHidl.cpp
@@ -22,19 +22,12 @@
#include "ConversionHelperHidl.h"
-using ::android::hardware::audio::CPP_VERSION::Result;
-
-#if MAJOR_VERSION >= 4
-using ::android::hardware::audio::CPP_VERSION::AudioMicrophoneChannelMapping;
-using ::android::hardware::audio::CPP_VERSION::AudioMicrophoneDirectionality;
-using ::android::hardware::audio::CPP_VERSION::AudioMicrophoneLocation;
-using ::android::hardware::audio::CPP_VERSION::DeviceAddress;
-using ::android::hardware::audio::CPP_VERSION::MicrophoneInfo;
-#endif
-
namespace android {
namespace CPP_VERSION {
+using namespace ::android::hardware::audio::common::CPP_VERSION;
+using namespace ::android::hardware::audio::CPP_VERSION;
+
// static
status_t ConversionHelperHidl::keysFromHal(const String8& keys, hidl_vec<hidl_string> *hidlKeys) {
AudioParameter halKeys(keys);
diff --git a/media/libaudiohal/impl/EffectBufferHalHidl.cpp b/media/libaudiohal/impl/EffectBufferHalHidl.cpp
index 6ef4e8a..5367972 100644
--- a/media/libaudiohal/impl/EffectBufferHalHidl.cpp
+++ b/media/libaudiohal/impl/EffectBufferHalHidl.cpp
@@ -30,6 +30,7 @@
using ::android::hidl::allocator::V1_0::IAllocator;
namespace android {
+namespace effect {
namespace CPP_VERSION {
// static
@@ -142,5 +143,6 @@
memcpy(mExternalData, mAudioBuffer.raw, size);
}
+} // namespace effect
} // namespace CPP_VERSION
} // namespace android
diff --git a/media/libaudiohal/impl/EffectBufferHalHidl.h b/media/libaudiohal/impl/EffectBufferHalHidl.h
index 0c99a02..4826813 100644
--- a/media/libaudiohal/impl/EffectBufferHalHidl.h
+++ b/media/libaudiohal/impl/EffectBufferHalHidl.h
@@ -23,13 +23,15 @@
#include <media/audiohal/EffectBufferHalInterface.h>
#include <system/audio_effect.h>
-using android::hardware::audio::effect::CPP_VERSION::AudioBuffer;
using android::hardware::hidl_memory;
using android::hidl::memory::V1_0::IMemory;
namespace android {
+namespace effect {
namespace CPP_VERSION {
+using namespace ::android::hardware::audio::effect::CPP_VERSION;
+
class EffectBufferHalHidl : public EffectBufferHalInterface
{
public:
@@ -73,6 +75,7 @@
};
} // namespace CPP_VERSION
+} // namespace effect
} // namespace android
#endif // ANDROID_HARDWARE_EFFECT_BUFFER_HAL_HIDL_H
diff --git a/media/libaudiohal/impl/EffectHalHidl.cpp b/media/libaudiohal/impl/EffectHalHidl.cpp
index df79b95..b0597b3 100644
--- a/media/libaudiohal/impl/EffectHalHidl.cpp
+++ b/media/libaudiohal/impl/EffectHalHidl.cpp
@@ -26,11 +26,6 @@
#include "EffectHalHidl.h"
#include "HidlUtils.h"
-using ::android::hardware::audio::effect::CPP_VERSION::AudioBuffer;
-using ::android::hardware::audio::effect::CPP_VERSION::EffectBufferAccess;
-using ::android::hardware::audio::effect::CPP_VERSION::EffectConfigParameters;
-using ::android::hardware::audio::effect::CPP_VERSION::MessageQueueFlagBits;
-using ::android::hardware::audio::effect::CPP_VERSION::Result;
using ::android::hardware::audio::common::CPP_VERSION::implementation::HidlUtils;
using ::android::hardware::audio::common::utils::EnumBitfield;
using ::android::hardware::hidl_vec;
@@ -38,9 +33,11 @@
using ::android::hardware::Return;
namespace android {
+namespace effect {
namespace CPP_VERSION {
using namespace ::android::hardware::audio::common::CPP_VERSION;
+using namespace ::android::hardware::audio::effect::CPP_VERSION;
EffectHalHidl::EffectHalHidl(const sp<IEffect>& effect, uint64_t effectId)
: mEffect(effect), mEffectId(effectId), mBuffersChanged(true), mEfGroup(nullptr) {
@@ -338,4 +335,5 @@
}
} // namespace CPP_VERSION
+} // namespace effect
} // namespace android
diff --git a/media/libaudiohal/impl/EffectHalHidl.h b/media/libaudiohal/impl/EffectHalHidl.h
index cd447ff..9d9f707 100644
--- a/media/libaudiohal/impl/EffectHalHidl.h
+++ b/media/libaudiohal/impl/EffectHalHidl.h
@@ -23,17 +23,15 @@
#include <fmq/MessageQueue.h>
#include <system/audio_effect.h>
-using ::android::hardware::audio::effect::CPP_VERSION::EffectBufferConfig;
-using ::android::hardware::audio::effect::CPP_VERSION::EffectConfig;
-using ::android::hardware::audio::effect::CPP_VERSION::EffectDescriptor;
-using ::android::hardware::audio::effect::CPP_VERSION::IEffect;
-using EffectResult = ::android::hardware::audio::effect::CPP_VERSION::Result;
using ::android::hardware::EventFlag;
using ::android::hardware::MessageQueue;
namespace android {
+namespace effect {
namespace CPP_VERSION {
+using namespace ::android::hardware::audio::effect::CPP_VERSION;
+
class EffectHalHidl : public EffectHalInterface
{
public:
@@ -70,7 +68,7 @@
private:
friend class EffectsFactoryHalHidl;
- typedef MessageQueue<EffectResult, hardware::kSynchronizedReadWrite> StatusMQ;
+ typedef MessageQueue<Result, hardware::kSynchronizedReadWrite> StatusMQ;
sp<IEffect> mEffect;
const uint64_t mEffectId;
@@ -80,7 +78,7 @@
std::unique_ptr<StatusMQ> mStatusMQ;
EventFlag* mEfGroup;
- static status_t analyzeResult(const EffectResult& result);
+ static status_t analyzeResult(const Result& result);
static void effectBufferConfigFromHal(
const buffer_config_t& halConfig, EffectBufferConfig* config);
static void effectBufferConfigToHal(
@@ -105,6 +103,7 @@
};
} // namespace CPP_VERSION
+} // namespace effect
} // namespace android
#endif // ANDROID_HARDWARE_EFFECT_HAL_HIDL_H
diff --git a/media/libaudiohal/impl/EffectsFactoryHalHidl.cpp b/media/libaudiohal/impl/EffectsFactoryHalHidl.cpp
index 7fea466..7fd6bde 100644
--- a/media/libaudiohal/impl/EffectsFactoryHalHidl.cpp
+++ b/media/libaudiohal/impl/EffectsFactoryHalHidl.cpp
@@ -26,14 +26,14 @@
#include "HidlUtils.h"
using ::android::hardware::audio::common::CPP_VERSION::implementation::HidlUtils;
-using ::android::hardware::audio::effect::CPP_VERSION::IEffect;
-using ::android::hardware::audio::effect::CPP_VERSION::Result;
using ::android::hardware::Return;
namespace android {
+namespace effect {
namespace CPP_VERSION {
using namespace ::android::hardware::audio::common::CPP_VERSION;
+using namespace ::android::hardware::audio::effect::CPP_VERSION;
EffectsFactoryHalHidl::EffectsFactoryHalHidl() : ConversionHelperHidl("EffectsFactory") {
mEffectsFactory = IEffectsFactory::getService();
@@ -145,6 +145,6 @@
return EffectBufferHalHidl::mirror(external, size, buffer);
}
-
} // namespace CPP_VERSION
+} // namespace effect
} // namespace android
diff --git a/media/libaudiohal/impl/EffectsFactoryHalHidl.h b/media/libaudiohal/impl/EffectsFactoryHalHidl.h
index 7027153..01178ff 100644
--- a/media/libaudiohal/impl/EffectsFactoryHalHidl.h
+++ b/media/libaudiohal/impl/EffectsFactoryHalHidl.h
@@ -24,11 +24,12 @@
#include "ConversionHelperHidl.h"
namespace android {
+namespace effect {
namespace CPP_VERSION {
-using ::android::hardware::audio::effect::CPP_VERSION::EffectDescriptor;
-using ::android::hardware::audio::effect::CPP_VERSION::IEffectsFactory;
using ::android::hardware::hidl_vec;
+using ::android::CPP_VERSION::ConversionHelperHidl;
+using namespace ::android::hardware::audio::effect::CPP_VERSION;
class EffectsFactoryHalHidl : public EffectsFactoryHalInterface, public ConversionHelperHidl
{
@@ -70,6 +71,7 @@
}
} // namespace CPP_VERSION
+} // namespace effect
} // namespace android
#endif // ANDROID_HARDWARE_EFFECTS_FACTORY_HAL_HIDL_H
diff --git a/media/libaudiohal/impl/StreamHalHidl.cpp b/media/libaudiohal/impl/StreamHalHidl.cpp
index 9765f1e..c12b362 100644
--- a/media/libaudiohal/impl/StreamHalHidl.cpp
+++ b/media/libaudiohal/impl/StreamHalHidl.cpp
@@ -35,6 +35,7 @@
namespace android {
namespace CPP_VERSION {
+using EffectHalHidl = ::android::effect::CPP_VERSION::EffectHalHidl;
using ReadCommand = ::android::hardware::audio::CPP_VERSION::IStreamIn::ReadCommand;
using namespace ::android::hardware::audio::common::CPP_VERSION;
diff --git a/media/libaudiohal/impl/include/libaudiohal/FactoryHalHidl.h b/media/libaudiohal/impl/include/libaudiohal/FactoryHalHidl.h
index 1d912a0..c7319d0 100644
--- a/media/libaudiohal/impl/include/libaudiohal/FactoryHalHidl.h
+++ b/media/libaudiohal/impl/include/libaudiohal/FactoryHalHidl.h
@@ -25,18 +25,29 @@
namespace android {
+namespace effect {
namespace V2_0 {
sp<EffectsFactoryHalInterface> createEffectsFactoryHal();
-sp<DevicesFactoryHalInterface> createDevicesFactoryHal();
} // namespace V2_0
namespace V4_0 {
sp<EffectsFactoryHalInterface> createEffectsFactoryHal();
-sp<DevicesFactoryHalInterface> createDevicesFactoryHal();
} // namespace V4_0
namespace V5_0 {
sp<EffectsFactoryHalInterface> createEffectsFactoryHal();
+} // namespace V5_0
+} // namespace effect
+
+namespace V2_0 {
+sp<DevicesFactoryHalInterface> createDevicesFactoryHal();
+} // namespace V2_0
+
+namespace V4_0 {
+sp<DevicesFactoryHalInterface> createDevicesFactoryHal();
+} // namespace V4_0
+
+namespace V5_0 {
sp<DevicesFactoryHalInterface> createDevicesFactoryHal();
} // namespace V5_0
diff --git a/media/libaudioprocessing/Android.bp b/media/libaudioprocessing/Android.bp
new file mode 100644
index 0000000..817fb0b
--- /dev/null
+++ b/media/libaudioprocessing/Android.bp
@@ -0,0 +1,54 @@
+cc_defaults {
+ name: "libaudioprocessing_defaults",
+
+ export_include_dirs: ["include"],
+
+ shared_libs: [
+ "libaudiohal",
+ "libaudioutils",
+ "libcutils",
+ "liblog",
+ "libnbaio",
+ "libnblog",
+ "libsonic",
+ "libutils",
+ ],
+
+ cflags: [
+ "-Werror",
+ "-Wall",
+
+ // uncomment to disable NEON on architectures that actually do support NEON, for benchmarking
+ // "-DUSE_NEON=false",
+ ],
+}
+
+cc_library_shared {
+ name: "libaudioprocessing",
+ defaults: ["libaudioprocessing_defaults"],
+
+ srcs: [
+ "BufferProviders.cpp",
+ "RecordBufferConverter.cpp",
+ ],
+ whole_static_libs: ["libaudioprocessing_arm"],
+}
+
+cc_library_static {
+ name: "libaudioprocessing_arm",
+ defaults: ["libaudioprocessing_defaults"],
+
+ srcs: [
+ "AudioMixer.cpp",
+ "AudioResampler.cpp",
+ "AudioResamplerCubic.cpp",
+ "AudioResamplerSinc.cpp",
+ "AudioResamplerDyn.cpp",
+ ],
+
+ arch: {
+ arm: {
+ instruction_set: "arm",
+ },
+ },
+}
diff --git a/media/libaudioprocessing/Android.mk b/media/libaudioprocessing/Android.mk
deleted file mode 100644
index da1ecc2..0000000
--- a/media/libaudioprocessing/Android.mk
+++ /dev/null
@@ -1,40 +0,0 @@
-LOCAL_PATH := $(call my-dir)
-
-include $(CLEAR_VARS)
-
-LOCAL_SRC_FILES := \
- AudioMixer.cpp.arm \
- AudioResampler.cpp.arm \
- AudioResamplerCubic.cpp.arm \
- AudioResamplerSinc.cpp.arm \
- AudioResamplerDyn.cpp.arm \
- BufferProviders.cpp \
- RecordBufferConverter.cpp \
-
-LOCAL_C_INCLUDES := \
- $(TOP) \
- $(call include-path-for, audio-utils) \
- $(LOCAL_PATH)/include \
-
-LOCAL_EXPORT_C_INCLUDE_DIRS := $(LOCAL_PATH)/include
-
-LOCAL_SHARED_LIBRARIES := \
- libaudiohal \
- libaudioutils \
- libcutils \
- liblog \
- libnbaio \
- libnblog \
- libsonic \
- libutils \
-
-LOCAL_MODULE := libaudioprocessing
-
-LOCAL_CFLAGS := -Werror -Wall
-
-# uncomment to disable NEON on architectures that actually do support NEON, for benchmarking
-#LOCAL_CFLAGS += -DUSE_NEON=false
-
-include $(BUILD_SHARED_LIBRARY)
-
-include $(call all-makefiles-under,$(LOCAL_PATH))
diff --git a/media/libaudioprocessing/BufferProviders.cpp b/media/libaudioprocessing/BufferProviders.cpp
index a1a1a0d..b764ccb 100644
--- a/media/libaudioprocessing/BufferProviders.cpp
+++ b/media/libaudioprocessing/BufferProviders.cpp
@@ -17,10 +17,12 @@
#define LOG_TAG "BufferProvider"
//#define LOG_NDEBUG 0
+#include <algorithm>
+
#include <audio_utils/primitives.h>
#include <audio_utils/format.h>
#include <audio_utils/channels.h>
-#include <external/sonic/sonic.h>
+#include <sonic.h>
#include <media/audiohal/EffectBufferHalInterface.h>
#include <media/audiohal/EffectHalInterface.h>
#include <media/audiohal/EffectsFactoryHalInterface.h>
@@ -36,13 +38,6 @@
namespace android {
// ----------------------------------------------------------------------------
-
-template <typename T>
-static inline T min(const T& a, const T& b)
-{
- return a < b ? a : b;
-}
-
CopyBufferProvider::CopyBufferProvider(size_t inputFrameSize,
size_t outputFrameSize, size_t bufferFrameCount) :
mInputFrameSize(inputFrameSize),
@@ -100,8 +95,8 @@
mConsumed = 0;
}
ALOG_ASSERT(mConsumed < mBuffer.frameCount);
- size_t count = min(mLocalBufferFrameCount, mBuffer.frameCount - mConsumed);
- count = min(count, pBuffer->frameCount);
+ size_t count = std::min(mLocalBufferFrameCount, mBuffer.frameCount - mConsumed);
+ count = std::min(count, pBuffer->frameCount);
pBuffer->raw = mLocalBufferData;
pBuffer->frameCount = count;
copyFrames(pBuffer->raw, (uint8_t*)mBuffer.raw + mConsumed * mInputFrameSize,
@@ -491,7 +486,7 @@
}
// time-stretch the data
- dstAvailable = min(mLocalBufferFrameCount - mRemaining, outputDesired);
+ dstAvailable = std::min(mLocalBufferFrameCount - mRemaining, outputDesired);
size_t srcAvailable = mBuffer.frameCount;
processFrames((uint8_t*)mLocalBufferData + mRemaining * mFrameSize, &dstAvailable,
mBuffer.raw, &srcAvailable);
@@ -589,7 +584,7 @@
} else {
// cyclically repeat the source.
for (size_t count = 0; count < *dstFrames; count += *srcFrames) {
- size_t remaining = min(*srcFrames, *dstFrames - count);
+ size_t remaining = std::min(*srcFrames, *dstFrames - count);
memcpy((uint8_t*)dstBuffer + mFrameSize * count,
srcBuffer, mFrameSize * remaining);
}
@@ -657,9 +652,9 @@
audio_format_t format, size_t inChannelCount, size_t outChannelCount,
audio_format_t contractedFormat, size_t contractedFrameCount, void* contractedBuffer) :
CopyBufferProvider(
- audio_bytes_per_frame(inChannelCount, format),
- audio_bytes_per_frame(outChannelCount, format),
- 0 /*bufferFrameCount*/),
+ audio_bytes_per_frame(std::max(inChannelCount, outChannelCount), format),
+ audio_bytes_per_frame(std::max(inChannelCount, outChannelCount), format),
+ contractedFrameCount),
mFormat(format),
mInChannelCount(inChannelCount),
mOutChannelCount(outChannelCount),
diff --git a/media/libaudioprocessing/audio-resampler/Android.bp b/media/libaudioprocessing/audio-resampler/Android.bp
new file mode 100644
index 0000000..dc70310
--- /dev/null
+++ b/media/libaudioprocessing/audio-resampler/Android.bp
@@ -0,0 +1,15 @@
+cc_library_shared {
+ name: "libaudio-resampler",
+
+ srcs: ["AudioResamplerCoefficients.cpp"],
+
+ shared_libs: [
+ "libutils",
+ "liblog",
+ ],
+
+ cflags: [
+ "-Werror",
+ "-Wall",
+ ],
+}
diff --git a/media/libaudioprocessing/audio-resampler/Android.mk b/media/libaudioprocessing/audio-resampler/Android.mk
deleted file mode 100644
index bb2807c..0000000
--- a/media/libaudioprocessing/audio-resampler/Android.mk
+++ /dev/null
@@ -1,16 +0,0 @@
-LOCAL_PATH := $(call my-dir)
-
-include $(CLEAR_VARS)
-
-LOCAL_SRC_FILES := \
- AudioResamplerCoefficients.cpp
-
-LOCAL_MODULE := libaudio-resampler
-
-LOCAL_MODULE_TAGS := optional
-
-LOCAL_SHARED_LIBRARIES := libutils liblog
-
-LOCAL_CFLAGS += -Werror -Wall
-
-include $(BUILD_SHARED_LIBRARY)
diff --git a/media/libaudioprocessing/tests/Android.bp b/media/libaudioprocessing/tests/Android.bp
new file mode 100644
index 0000000..811c16b
--- /dev/null
+++ b/media/libaudioprocessing/tests/Android.bp
@@ -0,0 +1,51 @@
+// Build the unit tests for libaudioprocessing
+
+cc_defaults {
+ name: "libaudioprocessing_test_defaults",
+
+ header_libs: ["libbase_headers"],
+ shared_libs: [
+ "libaudioutils",
+ "libaudioprocessing",
+ "libcutils",
+ "liblog",
+ "libutils",
+ ],
+
+ cflags: [
+ "-Werror",
+ "-Wall",
+ ],
+}
+
+//
+// resampler unit test
+//
+cc_test {
+ name: "resampler_tests",
+ defaults: ["libaudioprocessing_test_defaults"],
+
+ srcs: ["resampler_tests.cpp"],
+}
+
+//
+// audio mixer test tool
+//
+cc_binary {
+ name: "test-mixer",
+ defaults: ["libaudioprocessing_test_defaults"],
+
+ srcs: ["test-mixer.cpp"],
+ static_libs: ["libsndfile"],
+}
+
+//
+// build audio resampler test tool
+//
+cc_binary {
+ name: "test-resampler",
+ defaults: ["libaudioprocessing_test_defaults"],
+
+ srcs: ["test-resampler.cpp"],
+ static_libs: ["libsndfile"],
+}
diff --git a/media/libaudioprocessing/tests/Android.mk b/media/libaudioprocessing/tests/Android.mk
deleted file mode 100644
index 31ffbdc..0000000
--- a/media/libaudioprocessing/tests/Android.mk
+++ /dev/null
@@ -1,93 +0,0 @@
-# Build the unit tests for libaudioprocessing
-
-LOCAL_PATH := $(call my-dir)
-
-#
-# resampler unit test
-#
-include $(CLEAR_VARS)
-
-LOCAL_SHARED_LIBRARIES := \
- libaudioutils \
- libaudioprocessing \
- libcutils \
- liblog \
- libutils \
-
-LOCAL_C_INCLUDES := \
- $(call include-path-for, audio-utils) \
-
-LOCAL_SRC_FILES := \
- resampler_tests.cpp
-
-LOCAL_HEADER_LIBRARIES := libbase_headers
-
-LOCAL_MODULE := resampler_tests
-
-LOCAL_MODULE_TAGS := tests
-
-LOCAL_CFLAGS := -Werror -Wall
-
-include $(BUILD_NATIVE_TEST)
-
-#
-# audio mixer test tool
-#
-include $(CLEAR_VARS)
-
-LOCAL_SRC_FILES := \
- test-mixer.cpp \
-
-LOCAL_C_INCLUDES := \
- $(call include-path-for, audio-utils) \
-
-LOCAL_STATIC_LIBRARIES := \
- libsndfile \
-
-LOCAL_SHARED_LIBRARIES := \
- libaudioprocessing \
- libaudioutils \
- libcutils \
- liblog \
- libutils \
-
-LOCAL_HEADER_LIBRARIES := libbase_headers
-
-LOCAL_MODULE := test-mixer
-
-LOCAL_MODULE_TAGS := optional
-
-LOCAL_CFLAGS := -Werror -Wall
-
-include $(BUILD_EXECUTABLE)
-
-#
-# build audio resampler test tool
-#
-include $(CLEAR_VARS)
-
-LOCAL_SRC_FILES := \
- test-resampler.cpp \
-
-LOCAL_C_INCLUDES := \
- $(call include-path-for, audio-utils) \
-
-LOCAL_STATIC_LIBRARIES := \
- libsndfile \
-
-LOCAL_SHARED_LIBRARIES := \
- libaudioprocessing \
- libaudioutils \
- libcutils \
- liblog \
- libutils \
-
-LOCAL_HEADER_LIBRARIES := libbase_headers
-
-LOCAL_MODULE := test-resampler
-
-LOCAL_MODULE_TAGS := optional
-
-LOCAL_CFLAGS := -Werror -Wall
-
-include $(BUILD_EXECUTABLE)
diff --git a/media/libeffects/config/src/EffectsConfig.cpp b/media/libeffects/config/src/EffectsConfig.cpp
index 351b1ee..76b4adc 100644
--- a/media/libeffects/config/src/EffectsConfig.cpp
+++ b/media/libeffects/config/src/EffectsConfig.cpp
@@ -305,7 +305,7 @@
return parseWithPath(path);
}
- for (std::string location : DEFAULT_LOCATIONS) {
+ for (const std::string& location : DEFAULT_LOCATIONS) {
std::string defaultPath = location + '/' + DEFAULT_NAME;
if (access(defaultPath.c_str(), R_OK) != 0) {
continue;
diff --git a/media/libeffects/lvm/lib/Bass/lib/LVDBE.h b/media/libeffects/lvm/lib/Bass/lib/LVDBE.h
index a1fa79a..cc066b0 100644
--- a/media/libeffects/lvm/lib/Bass/lib/LVDBE.h
+++ b/media/libeffects/lvm/lib/Bass/lib/LVDBE.h
@@ -199,8 +199,10 @@
#define LVDBE_CAP_FS_44100 128
#define LVDBE_CAP_FS_48000 256
#if defined(BUILD_FLOAT) && defined(HIGHER_FS)
-#define LVDBE_CAP_FS_96000 512
-#define LVDBE_CAP_FS_192000 1024
+#define LVDBE_CAP_FS_88200 512
+#define LVDBE_CAP_FS_96000 1024
+#define LVDBE_CAP_FS_176400 2048
+#define LVDBE_CAP_FS_192000 4096
#endif
typedef enum
@@ -215,8 +217,10 @@
LVDBE_FS_44100 = 7,
LVDBE_FS_48000 = 8,
#if defined(BUILD_FLOAT) && defined(HIGHER_FS)
- LVDBE_FS_96000 = 9,
- LVDBE_FS_192000 = 10,
+ LVDBE_FS_88200 = 9,
+ LVDBE_FS_96000 = 10,
+ LVDBE_FS_176400 = 11,
+ LVDBE_FS_192000 = 12,
#endif
LVDBE_FS_MAX = LVM_MAXINT_32
} LVDBE_Fs_en;
diff --git a/media/libeffects/lvm/lib/Bass/src/LVDBE_Coeffs.h b/media/libeffects/lvm/lib/Bass/src/LVDBE_Coeffs.h
index 4ecaf14..8f058e8 100644
--- a/media/libeffects/lvm/lib/Bass/src/LVDBE_Coeffs.h
+++ b/media/libeffects/lvm/lib/Bass/src/LVDBE_Coeffs.h
@@ -580,12 +580,24 @@
#define HPF_Fs48000_Fc55_B2 0.989882f
#ifdef HIGHER_FS
+#define HPF_Fs88200_Fc55_A0 0.985818f
+#define HPF_Fs88200_Fc55_A1 (-1.971636f)
+#define HPF_Fs88200_Fc55_A2 0.985818f
+#define HPF_Fs88200_Fc55_B1 (-1.994466f)
+#define HPF_Fs88200_Fc55_B2 0.994481f
+
#define HPF_Fs96000_Fc55_A0 0.986040f
#define HPF_Fs96000_Fc55_A1 (-1.972080f)
#define HPF_Fs96000_Fc55_A2 0.986040f
#define HPF_Fs96000_Fc55_B1 (-1.994915f)
#define HPF_Fs96000_Fc55_B2 0.994928f
+#define HPF_Fs176400_Fc55_A0 0.987183f
+#define HPF_Fs176400_Fc55_A1 (-1.974366f)
+#define HPF_Fs176400_Fc55_A2 0.987183f
+#define HPF_Fs176400_Fc55_B1 (-1.997233f)
+#define HPF_Fs176400_Fc55_B2 0.997237f
+
#define HPF_Fs192000_Fc55_A0 0.987294f
#define HPF_Fs192000_Fc55_A1 (-1.974588f)
#define HPF_Fs192000_Fc55_A2 0.987294f
@@ -642,12 +654,24 @@
#define HPF_Fs48000_Fc66_B2 0.987871f
#ifdef HIGHER_FS
+#define HPF_Fs88200_Fc66_A0 0.985273f
+#define HPF_Fs88200_Fc66_A1 (-1.970546f)
+#define HPF_Fs88200_Fc66_A2 0.985273f
+#define HPF_Fs88200_Fc66_B1 (-1.993359f)
+#define HPF_Fs88200_Fc66_B2 0.993381f
+
#define HPF_Fs96000_Fc66_A0 0.985539f
#define HPF_Fs96000_Fc66_A1 (-1.971077f)
#define HPF_Fs96000_Fc66_A2 0.985539f
#define HPF_Fs96000_Fc66_B1 (-1.993898f)
#define HPF_Fs96000_Fc66_B2 0.993917f
+#define HPF_Fs176400_Fc66_A0 0.986910f
+#define HPF_Fs176400_Fc66_A1 (-1.973820f)
+#define HPF_Fs176400_Fc66_A2 0.986910f
+#define HPF_Fs176400_Fc66_B1 (-1.996679f)
+#define HPF_Fs176400_Fc66_B2 0.996685f
+
#define HPF_Fs192000_Fc66_A0 0.987043f
#define HPF_Fs192000_Fc66_A1 (-1.974086f)
#define HPF_Fs192000_Fc66_A2 0.987043f
@@ -703,12 +727,24 @@
#define HPF_Fs48000_Fc78_B2 0.985681f
#ifdef HIGHER_FS
+#define HPF_Fs88200_Fc78_A0 0.984678f
+#define HPF_Fs88200_Fc78_A1 (-1.969356f)
+#define HPF_Fs88200_Fc78_A2 0.984678f
+#define HPF_Fs88200_Fc78_B1 (-1.992151f)
+#define HPF_Fs88200_Fc78_B2 0.992182f
+
#define HPF_Fs96000_Fc78_A0 0.984992f
#define HPF_Fs96000_Fc78_A1 (-1.969984f)
#define HPF_Fs96000_Fc78_A2 0.984992f
#define HPF_Fs96000_Fc78_B1 (-1.992789f)
#define HPF_Fs96000_Fc78_B2 0.992815f
+#define HPF_Fs176400_Fc78_A0 0.986612f
+#define HPF_Fs176400_Fc78_A1 (-1.973224f)
+#define HPF_Fs176400_Fc78_A2 0.986612f
+#define HPF_Fs176400_Fc78_B1 (-1.996076f)
+#define HPF_Fs176400_Fc78_B2 0.996083f
+
#define HPF_Fs192000_Fc78_A0 0.986769f
#define HPF_Fs192000_Fc78_A1 (-1.973539f)
#define HPF_Fs192000_Fc78_A2 0.986769f
@@ -764,12 +800,24 @@
#define HPF_Fs48000_Fc90_B2 0.983497f
#ifdef HIGHER_FS
+#define HPF_Fs88200_Fc90_A0 0.984084f
+#define HPF_Fs88200_Fc90_A1 (-1.968168f)
+#define HPF_Fs88200_Fc90_A2 0.984084f
+#define HPF_Fs88200_Fc90_B1 (-1.990944f)
+#define HPF_Fs88200_Fc90_B2 0.990985f
+
#define HPF_Fs96000_Fc90_A0 0.984446f
#define HPF_Fs96000_Fc90_A1 (-1.968892f)
#define HPF_Fs96000_Fc90_A2 0.984446f
#define HPF_Fs96000_Fc90_B1 (-1.991680f)
#define HPF_Fs96000_Fc90_B2 0.991714f
+#define HPF_Fs176400_Fc90_A0 0.986314f
+#define HPF_Fs176400_Fc90_A1 (-1.972629f)
+#define HPF_Fs176400_Fc90_A2 0.986314f
+#define HPF_Fs176400_Fc90_B1 (-1.995472f)
+#define HPF_Fs176400_Fc90_B2 0.995482f
+
#define HPF_Fs192000_Fc90_A0 0.986496f
#define HPF_Fs192000_Fc90_A1 (-1.972992f)
#define HPF_Fs192000_Fc90_A2 0.986496f
@@ -831,12 +879,24 @@
#define BPF_Fs48000_Fc55_B2 0.996875f
#ifdef HIGHER_FS
+#define BPF_Fs88200_Fc55_A0 0.000831f
+#define BPF_Fs88200_Fc55_A1 0.000000f
+#define BPF_Fs88200_Fc55_A2 (-0.000831f)
+#define BPF_Fs88200_Fc55_B1 (-1.998321f)
+#define BPF_Fs88200_Fc55_B2 0.998338f
+
#define BPF_Fs96000_Fc55_A0 0.000762f
#define BPF_Fs96000_Fc55_A1 0.000000f
#define BPF_Fs96000_Fc55_A2 (-0.000762f)
#define BPF_Fs96000_Fc55_B1 (-1.998461f)
#define BPF_Fs96000_Fc55_B2 0.998477f
+#define BPF_Fs176400_Fc55_A0 0.000416f
+#define BPF_Fs176400_Fc55_A1 0.000000f
+#define BPF_Fs176400_Fc55_A2 (-0.000416f)
+#define BPF_Fs176400_Fc55_B1 (-1.999164f)
+#define BPF_Fs176400_Fc55_B2 0.999169f
+
#define BPF_Fs192000_Fc55_A0 0.000381f
#define BPF_Fs192000_Fc55_A1 0.000000f
#define BPF_Fs192000_Fc55_A2 (-0.000381f)
@@ -892,12 +952,24 @@
#define BPF_Fs48000_Fc66_B2 0.995690f
#ifdef HIGHER_FS
+#define BPF_Fs88200_Fc66_A0 0.001146f
+#define BPF_Fs88200_Fc66_A1 0.000000f
+#define BPF_Fs88200_Fc66_A2 (-0.001146f)
+#define BPF_Fs88200_Fc66_B1 (-1.997684f)
+#define BPF_Fs88200_Fc66_B2 0.997708f
+
#define BPF_Fs96000_Fc66_A0 0.001055f
#define BPF_Fs96000_Fc66_A1 0.000000f
#define BPF_Fs96000_Fc66_A2 (-0.001055f)
#define BPF_Fs96000_Fc66_B1 (-1.997868f)
#define BPF_Fs96000_Fc66_B2 0.997891f
+#define BPF_Fs176400_Fc66_A0 0.000573f
+#define BPF_Fs176400_Fc66_A1 0.000000f
+#define BPF_Fs176400_Fc66_A2 (-0.000573f)
+#define BPF_Fs176400_Fc66_B1 (-1.998847f)
+#define BPF_Fs176400_Fc66_B2 0.998853f
+
#define BPF_Fs192000_Fc66_A0 0.000528f
#define BPF_Fs192000_Fc66_A1 0.000000f
#define BPF_Fs192000_Fc66_A2 (-0.000528f)
@@ -953,12 +1025,24 @@
#define BPF_Fs48000_Fc78_B2 0.993639f
#ifdef HIGHER_FS
+#define BPF_Fs88200_Fc78_A0 0.001693f
+#define BPF_Fs88200_Fc78_A1 0.000000f
+#define BPF_Fs88200_Fc78_A2 (-0.001693f)
+#define BPF_Fs88200_Fc78_B1 (-1.996582f)
+#define BPF_Fs88200_Fc78_B2 0.996615f
+
#define BPF_Fs96000_Fc78_A0 0.001555f
#define BPF_Fs96000_Fc78_A1 0.000000f
#define BPF_Fs96000_Fc78_A2 (-0.0015555f)
#define BPF_Fs96000_Fc78_B1 (-1.996860f)
#define BPF_Fs96000_Fc78_B2 0.996891f
+#define BPF_Fs176400_Fc78_A0 0.000847f
+#define BPF_Fs176400_Fc78_A1 0.000000f
+#define BPF_Fs176400_Fc78_A2 (-0.000847f)
+#define BPF_Fs176400_Fc78_B1 (-1.998298f)
+#define BPF_Fs176400_Fc78_B2 0.998306f
+
#define BPF_Fs192000_Fc78_A0 0.000778f
#define BPF_Fs192000_Fc78_A1 0.000000f
#define BPF_Fs192000_Fc78_A2 (-0.000778f)
@@ -1014,12 +1098,24 @@
#define BPF_Fs48000_Fc90_B2 0.992177f
#ifdef HIGHER_FS
+#define BPF_Fs88200_Fc90_A0 0.002083f
+#define BPF_Fs88200_Fc90_A1 0.000000f
+#define BPF_Fs88200_Fc90_A2 (-0.002083f)
+#define BPF_Fs88200_Fc90_B1 (-1.995791f)
+#define BPF_Fs88200_Fc90_B2 0.995835f
+
#define BPF_Fs96000_Fc90_A0 0.001913f
#define BPF_Fs96000_Fc90_A1 0.000000f
#define BPF_Fs96000_Fc90_A2 (-0.001913f)
#define BPF_Fs96000_Fc90_B1 (-1.996134f)
#define BPF_Fs96000_Fc90_B2 0.996174f
+#define BPF_Fs176400_Fc90_A0 0.001042f
+#define BPF_Fs176400_Fc90_A1 0.000000f
+#define BPF_Fs176400_Fc90_A2 (-0.001042f)
+#define BPF_Fs176400_Fc90_B1 (-1.997904f)
+#define BPF_Fs176400_Fc90_B2 0.997915f
+
#define BPF_Fs192000_Fc90_A0 0.000958f
#define BPF_Fs192000_Fc90_A1 0.000000f
#define BPF_Fs192000_Fc90_A2 (-0.000958f)
@@ -1045,7 +1141,9 @@
#define AGC_ATTACK_Fs48000 0.971628f
#ifdef HIGHER_FS
+#define AGC_ATTACK_Fs88200 0.984458f
#define AGC_ATTACK_Fs96000 0.985712f
+#define AGC_ATTACK_Fs176400 0.992199f
#define AGC_ATTACK_Fs192000 0.992830f
#endif
@@ -1062,7 +1160,9 @@
#define AGC_DECAY_Fs48000 0.000007f
#ifdef HIGHER_FS
+#define AGC_DECAY_Fs88200 0.0000038f
#define AGC_DECAY_FS96000 0.0000035f
+#define AGC_DECAY_Fs176400 0.00000188f
#define AGC_DECAY_FS192000 0.00000175f
#endif
@@ -1125,7 +1225,9 @@
#define VOL_TC_Fs44100 0.004525f
#define VOL_TC_Fs48000 0.004158f
#ifdef HIGHER_FS
+#define VOL_TC_Fs88200 0.002263f
#define VOL_TC_Fs96000 0.002079f
+#define VOL_TC_Fs176400 0.001131f
#define VOL_TC_Fs192000 0.001039f
#endif
#define MIX_TC_Fs8000 29365 /* Floating point value 0.896151 */
@@ -1138,9 +1240,13 @@
#define MIX_TC_Fs44100 32097 /* Floating point value 0.979515 */
#define MIX_TC_Fs48000 32150 /* Floating point value 0.981150 */
#ifdef HIGHER_FS
+/* Floating point value 0.989704 */
+#define MIX_TC_Fs88200 32430
#define MIX_TC_Fs96000 32456 /* Floating point value 0.990530 */
+/* Floating point value 0.994838 */
+#define MIX_TC_Fs176400 32598
#define MIX_TC_Fs192000 32611 /* Floating point value 0.992524 */
#endif
#endif /*BUILD_FLOAT*/
-#endif
\ No newline at end of file
+#endif
diff --git a/media/libeffects/lvm/lib/Bass/src/LVDBE_Tables.c b/media/libeffects/lvm/lib/Bass/src/LVDBE_Tables.c
index c4a9b14..a2ce404 100644
--- a/media/libeffects/lvm/lib/Bass/src/LVDBE_Tables.c
+++ b/media/libeffects/lvm/lib/Bass/src/LVDBE_Tables.c
@@ -88,11 +88,21 @@
-HPF_Fs48000_Fc55_B2,
-HPF_Fs48000_Fc55_B1},
#ifdef HIGHER_FS
+ {HPF_Fs88200_Fc55_A2, /* 88kS/s coefficients */
+ HPF_Fs88200_Fc55_A1,
+ HPF_Fs88200_Fc55_A0,
+ -HPF_Fs88200_Fc55_B2,
+ -HPF_Fs88200_Fc55_B1},
{HPF_Fs96000_Fc55_A2, /* 96kS/s coefficients */
HPF_Fs96000_Fc55_A1,
HPF_Fs96000_Fc55_A0,
-HPF_Fs96000_Fc55_B2,
-HPF_Fs96000_Fc55_B1},
+ {HPF_Fs176400_Fc55_A2, /* 176kS/s coefficients */
+ HPF_Fs176400_Fc55_A1,
+ HPF_Fs176400_Fc55_A0,
+ -HPF_Fs176400_Fc55_B2,
+ -HPF_Fs176400_Fc55_B1},
{HPF_Fs192000_Fc55_A2, /* 192kS/s coefficients */
HPF_Fs192000_Fc55_A1,
HPF_Fs192000_Fc55_A0,
@@ -147,11 +157,21 @@
-HPF_Fs48000_Fc66_B2,
-HPF_Fs48000_Fc66_B1},
#ifdef HIGHER_FS
+ {HPF_Fs88200_Fc66_A2, /* 88kS/s coefficients */
+ HPF_Fs88200_Fc66_A1,
+ HPF_Fs88200_Fc66_A0,
+ -HPF_Fs88200_Fc66_B2,
+ -HPF_Fs88200_Fc66_B1},
{HPF_Fs96000_Fc66_A2, /* 96kS/s coefficients */
HPF_Fs96000_Fc66_A1,
HPF_Fs96000_Fc66_A0,
-HPF_Fs96000_Fc66_B2,
-HPF_Fs96000_Fc66_B1},
+ {HPF_Fs176400_Fc66_A2, /* 176kS/s coefficients */
+ HPF_Fs176400_Fc66_A1,
+ HPF_Fs176400_Fc66_A0,
+ -HPF_Fs176400_Fc66_B2,
+ -HPF_Fs176400_Fc66_B1},
{HPF_Fs192000_Fc66_A2, /* 192kS/s coefficients */
HPF_Fs192000_Fc66_A1,
HPF_Fs192000_Fc66_A0,
@@ -207,11 +227,21 @@
-HPF_Fs48000_Fc78_B2,
-HPF_Fs48000_Fc78_B1},
#ifdef HIGHER_FS
+ {HPF_Fs88200_Fc78_A2, /* 88kS/s coefficients */
+ HPF_Fs88200_Fc78_A1,
+ HPF_Fs88200_Fc78_A0,
+ -HPF_Fs88200_Fc78_B2,
+ -HPF_Fs88200_Fc78_B1},
{HPF_Fs96000_Fc78_A2, /* 96kS/s coefficients */
HPF_Fs96000_Fc78_A1,
HPF_Fs96000_Fc78_A0,
-HPF_Fs96000_Fc78_B2,
-HPF_Fs96000_Fc78_B1},
+ {HPF_Fs176400_Fc78_A2, /* 176kS/s coefficients */
+ HPF_Fs176400_Fc78_A1,
+ HPF_Fs176400_Fc78_A0,
+ -HPF_Fs176400_Fc78_B2,
+ -HPF_Fs176400_Fc78_B1},
{HPF_Fs192000_Fc78_A2, /* 192kS/s coefficients */
HPF_Fs192000_Fc78_A1,
HPF_Fs192000_Fc78_A0,
@@ -269,11 +299,21 @@
#ifdef HIGHER_FS
,
+ {HPF_Fs88200_Fc90_A2, /* 88kS/s coefficients */
+ HPF_Fs88200_Fc90_A1,
+ HPF_Fs88200_Fc90_A0,
+ -HPF_Fs88200_Fc90_B2,
+ -HPF_Fs88200_Fc90_B1},
{HPF_Fs96000_Fc90_A2, /* 96kS/s coefficients */
HPF_Fs96000_Fc90_A1,
HPF_Fs96000_Fc90_A0,
-HPF_Fs96000_Fc90_B2,
-HPF_Fs96000_Fc90_B1},
+ {HPF_Fs176400_Fc90_A2, /* 176kS/s coefficients */
+ HPF_Fs176400_Fc90_A1,
+ HPF_Fs176400_Fc90_A0,
+ -HPF_Fs176400_Fc90_B2,
+ -HPF_Fs176400_Fc90_B1},
{HPF_Fs192000_Fc90_A2, /* 192kS/s coefficients */
HPF_Fs192000_Fc90_A1,
HPF_Fs192000_Fc90_A0,
@@ -320,9 +360,15 @@
-BPF_Fs48000_Fc55_B2,
-BPF_Fs48000_Fc55_B1},
#ifdef HIGHER_FS
+ {BPF_Fs88200_Fc55_A0, /* 88kS/s coefficients */
+ -BPF_Fs88200_Fc55_B2,
+ -BPF_Fs88200_Fc55_B1},
{BPF_Fs96000_Fc55_A0, /* 96kS/s coefficients */
-BPF_Fs96000_Fc55_B2,
-BPF_Fs96000_Fc55_B1},
+ {BPF_Fs176400_Fc55_A0, /* 176kS/s coefficients */
+ -BPF_Fs176400_Fc55_B2,
+ -BPF_Fs176400_Fc55_B1},
{BPF_Fs192000_Fc55_A0, /* 192kS/s coefficients */
-BPF_Fs192000_Fc55_B2,
-BPF_Fs192000_Fc55_B1},
@@ -357,9 +403,15 @@
-BPF_Fs48000_Fc66_B2,
-BPF_Fs48000_Fc66_B1},
#ifdef HIGHER_FS
+ {BPF_Fs88200_Fc66_A0, /* 88kS/s coefficients */
+ -BPF_Fs88200_Fc66_B2,
+ -BPF_Fs88200_Fc66_B1},
{BPF_Fs96000_Fc66_A0, /* 96kS/s coefficients */
-BPF_Fs96000_Fc66_B2,
-BPF_Fs96000_Fc66_B1},
+ {BPF_Fs176400_Fc66_A0, /* 176kS/s coefficients */
+ -BPF_Fs176400_Fc66_B2,
+ -BPF_Fs176400_Fc66_B1},
{BPF_Fs192000_Fc66_A0, /* 192kS/s coefficients */
-BPF_Fs192000_Fc66_B2,
-BPF_Fs192000_Fc66_B1},
@@ -394,9 +446,15 @@
-BPF_Fs48000_Fc78_B2,
-BPF_Fs48000_Fc78_B1},
#ifdef HIGHER_FS
+ {BPF_Fs88200_Fc66_A0, /* 88kS/s coefficients */
+ -BPF_Fs88200_Fc66_B2,
+ -BPF_Fs88200_Fc66_B1},
{BPF_Fs96000_Fc78_A0, /* 96kS/s coefficients */
-BPF_Fs96000_Fc78_B2,
-BPF_Fs96000_Fc78_B1},
+ {BPF_Fs176400_Fc66_A0, /* 176kS/s coefficients */
+ -BPF_Fs176400_Fc66_B2,
+ -BPF_Fs176400_Fc66_B1},
{BPF_Fs192000_Fc78_A0, /* 192kS/s coefficients */
-BPF_Fs192000_Fc78_B2,
-BPF_Fs192000_Fc78_B1},
@@ -432,9 +490,15 @@
-BPF_Fs48000_Fc90_B1}
#ifdef HIGHER_FS
,
+ {BPF_Fs88200_Fc90_A0, /* 88kS/s coefficients */
+ -BPF_Fs88200_Fc90_B2,
+ -BPF_Fs88200_Fc90_B1},
{BPF_Fs96000_Fc90_A0, /* 96kS/s coefficients */
-BPF_Fs96000_Fc90_B2,
-BPF_Fs96000_Fc90_B1},
+ {BPF_Fs176400_Fc90_A0, /* 176kS/s coefficients */
+ -BPF_Fs176400_Fc90_B2,
+ -BPF_Fs176400_Fc90_B1},
{BPF_Fs192000_Fc90_A0, /* 192kS/s coefficients */
-BPF_Fs192000_Fc90_B2,
-BPF_Fs192000_Fc90_B1}
@@ -466,7 +530,9 @@
AGC_ATTACK_Fs44100,
AGC_ATTACK_Fs48000
#ifdef HIGHER_FS
+ ,AGC_ATTACK_Fs88200
,AGC_ATTACK_Fs96000
+ ,AGC_ATTACK_Fs176400
,AGC_ATTACK_Fs192000
#endif
@@ -488,7 +554,9 @@
AGC_DECAY_Fs44100,
AGC_DECAY_Fs48000
#ifdef HIGHER_FS
+ ,AGC_DECAY_Fs88200
,AGC_DECAY_FS96000
+ ,AGC_DECAY_Fs176400
,AGC_DECAY_FS192000
#endif
@@ -583,7 +651,9 @@
VOL_TC_Fs44100,
VOL_TC_Fs48000
#ifdef HIGHER_FS
+ ,VOL_TC_Fs88200
,VOL_TC_Fs96000
+ ,VOL_TC_Fs176400
,VOL_TC_Fs192000
#endif
};
@@ -602,7 +672,9 @@
MIX_TC_Fs44100,
MIX_TC_Fs48000
#ifdef HIGHER_FS
+ ,MIX_TC_Fs88200
,MIX_TC_Fs96000
+ ,MIX_TC_Fs176400
,MIX_TC_Fs192000
#endif
diff --git a/media/libeffects/lvm/lib/Bundle/src/LVM_Coeffs.h b/media/libeffects/lvm/lib/Bundle/src/LVM_Coeffs.h
index 8c04847..bab4049 100644
--- a/media/libeffects/lvm/lib/Bundle/src/LVM_Coeffs.h
+++ b/media/libeffects/lvm/lib/Bundle/src/LVM_Coeffs.h
@@ -487,6 +487,97 @@
#define HPF_Fs48000_Gain15_B2 0.000000
#ifdef HIGHER_FS
+/* Coefficients for sample rate 88200 */
+/* Gain = 1.000000 dB */
+#define HPF_Fs88200_Gain1_A0 1.094374f
+#define HPF_Fs88200_Gain1_A1 (-0.641256f)
+#define HPF_Fs88200_Gain1_A2 0.000000f
+#define HPF_Fs88200_Gain1_B1 (-0.546882f)
+#define HPF_Fs88200_Gain1_B2 0.000000f
+/* Gain = 2.000000 dB */
+#define HPF_Fs88200_Gain2_A0 1.200264f
+#define HPF_Fs88200_Gain2_A1 (-0.747146f)
+#define HPF_Fs88200_Gain2_A2 0.000000f
+#define HPF_Fs88200_Gain2_B1 (-0.546882f)
+#define HPF_Fs88200_Gain2_B2 0.000000f
+/* Gain = 3.000000 dB */
+#define HPF_Fs88200_Gain3_A0 1.319074f
+#define HPF_Fs88200_Gain3_A1 (-0.865956f)
+#define HPF_Fs88200_Gain3_A2 0.000000f
+#define HPF_Fs88200_Gain3_B1 (-0.546882f)
+#define HPF_Fs88200_Gain3_B2 0.000000f
+/* Gain = 4.000000 dB */
+#define HPF_Fs88200_Gain4_A0 1.452380f
+#define HPF_Fs88200_Gain4_A1 (-0.999263f)
+#define HPF_Fs88200_Gain4_A2 0.000000f
+#define HPF_Fs88200_Gain4_B1 (-0.546882f)
+#define HPF_Fs88200_Gain4_B2 0.000000f
+/* Gain = 5.000000 dB */
+#define HPF_Fs88200_Gain5_A0 1.601953f
+#define HPF_Fs88200_Gain5_A1 (-1.148836f)
+#define HPF_Fs88200_Gain5_A2 0.000000f
+#define HPF_Fs88200_Gain5_B1 (-0.546882f)
+#define HPF_Fs88200_Gain5_B2 0.000000f
+/* Gain = 6.000000 dB */
+#define HPF_Fs88200_Gain6_A0 1.769777f
+#define HPF_Fs88200_Gain6_A1 (-1.316659f)
+#define HPF_Fs88200_Gain6_A2 0.000000f
+#define HPF_Fs88200_Gain6_B1 (-0.546882f)
+#define HPF_Fs88200_Gain6_B2 0.000000f
+/* Gain = 7.000000 dB */
+#define HPF_Fs88200_Gain7_A0 1.958078f
+#define HPF_Fs88200_Gain7_A1 (-1.504960f)
+#define HPF_Fs88200_Gain7_A2 0.000000f
+#define HPF_Fs88200_Gain7_B1 (-0.546882f)
+#define HPF_Fs88200_Gain7_B2 0.000000f
+/* Gain = 8.000000 dB */
+#define HPF_Fs88200_Gain8_A0 2.169355f
+#define HPF_Fs88200_Gain8_A1 (-1.716238f)
+#define HPF_Fs88200_Gain8_A2 0.000000f
+#define HPF_Fs88200_Gain8_B1 (-0.546882f)
+#define HPF_Fs88200_Gain8_B2 0.000000f
+/* Gain = 9.000000 dB */
+#define HPF_Fs88200_Gain9_A0 2.406412f
+#define HPF_Fs88200_Gain9_A1 (-1.953295f)
+#define HPF_Fs88200_Gain9_A2 0.000000f
+#define HPF_Fs88200_Gain9_B1 (-0.546882f)
+#define HPF_Fs88200_Gain9_B2 0.000000f
+/* Gain = 10.000000 dB */
+#define HPF_Fs88200_Gain10_A0 2.672395f
+#define HPF_Fs88200_Gain10_A1 (-2.219277f)
+#define HPF_Fs88200_Gain10_A2 0.000000f
+#define HPF_Fs88200_Gain10_B1 (-0.546882f)
+#define HPF_Fs88200_Gain10_B2 0.000000f
+/* Gain = 11.000000 dB */
+#define HPF_Fs88200_Gain11_A0 2.970832f
+#define HPF_Fs88200_Gain11_A1 (-2.517714f)
+#define HPF_Fs88200_Gain11_A2 0.000000f
+#define HPF_Fs88200_Gain11_B1 (-0.546882f)
+#define HPF_Fs88200_Gain11_B2 0.000000f
+/* Gain = 12.000000 dB */
+#define HPF_Fs88200_Gain12_A0 3.305684f
+#define HPF_Fs88200_Gain12_A1 (-2.852566f)
+#define HPF_Fs88200_Gain12_A2 0.000000f
+#define HPF_Fs88200_Gain12_B1 (-0.546882f)
+#define HPF_Fs88200_Gain12_B2 0.000000f
+/* Gain = 13.000000 dB */
+#define HPF_Fs88200_Gain13_A0 3.681394f
+#define HPF_Fs88200_Gain13_A1 (-3.228276f)
+#define HPF_Fs88200_Gain13_A2 0.000000f
+#define HPF_Fs88200_Gain13_B1 (-0.546882f)
+#define HPF_Fs88200_Gain13_B2 0.000000f
+/* Gain = 14.000000 dB */
+#define HPF_Fs88200_Gain14_A0 4.102947f
+#define HPF_Fs88200_Gain14_A1 (-3.649830f)
+#define HPF_Fs88200_Gain14_A2 0.000000f
+#define HPF_Fs88200_Gain14_B1 (-0.546882f)
+#define HPF_Fs88200_Gain14_B2 0.000000f
+/* Gain = 15.000000 dB */
+#define HPF_Fs88200_Gain15_A0 4.575938f
+#define HPF_Fs88200_Gain15_A1 (-4.122820f)
+#define HPF_Fs88200_Gain15_A2 0.000000f
+#define HPF_Fs88200_Gain15_B1 (-0.546882f)
+#define HPF_Fs88200_Gain15_B2 0.000000f
/* Coefficients for sample rate 96000Hz */
/* Gain = 1.000000 dB */
@@ -580,6 +671,98 @@
#define HPF_Fs96000_Gain15_B1 (-0.577350)
#define HPF_Fs96000_Gain15_B2 0.000000
+/* Coefficients for sample rate 176400 */
+/* Gain = 1.000000 dB */
+#define HPF_Fs176400_Gain1_A0 1.106711f
+#define HPF_Fs176400_Gain1_A1 (-0.855807f)
+#define HPF_Fs176400_Gain1_A2 0.000000f
+#define HPF_Fs176400_Gain1_B1 (-0.749096f)
+#define HPF_Fs176400_Gain1_B2 0.000000f
+/* Gain = 2.000000 dB */
+#define HPF_Fs176400_Gain2_A0 1.226443f
+#define HPF_Fs176400_Gain2_A1 (-0.975539f)
+#define HPF_Fs176400_Gain2_A2 0.000000f
+#define HPF_Fs176400_Gain2_B1 (-0.749096f)
+#define HPF_Fs176400_Gain2_B2 0.000000f
+/* Gain = 3.000000 dB */
+#define HPF_Fs176400_Gain3_A0 1.360784f
+#define HPF_Fs176400_Gain3_A1 (-1.109880f)
+#define HPF_Fs176400_Gain3_A2 0.000000f
+#define HPF_Fs176400_Gain3_B1 (-0.749096f)
+#define HPF_Fs176400_Gain3_B2 0.000000f
+/* Gain = 4.000000 dB */
+#define HPF_Fs176400_Gain4_A0 1.511517f
+#define HPF_Fs176400_Gain4_A1 (-1.260613f)
+#define HPF_Fs176400_Gain4_A2 0.000000f
+#define HPF_Fs176400_Gain4_B1 (-0.749096f)
+#define HPF_Fs176400_Gain4_B2 0.000000f
+/* Gain = 5.000000 dB */
+#define HPF_Fs176400_Gain5_A0 1.680643f
+#define HPF_Fs176400_Gain5_A1 (-1.429739f)
+#define HPF_Fs176400_Gain5_A2 0.000000f
+#define HPF_Fs176400_Gain5_B1 (-0.749096f)
+#define HPF_Fs176400_Gain5_B2 0.000000f
+/* Gain = 6.000000 dB */
+#define HPF_Fs176400_Gain6_A0 1.870405f
+#define HPF_Fs176400_Gain6_A1 (-1.619501f)
+#define HPF_Fs176400_Gain6_A2 0.000000f
+#define HPF_Fs176400_Gain6_B1 (-0.749096f)
+#define HPF_Fs176400_Gain6_B2 0.000000f
+/* Gain = 7.000000 dB */
+#define HPF_Fs176400_Gain7_A0 2.083321f
+#define HPF_Fs176400_Gain7_A1 (-1.832417f)
+#define HPF_Fs176400_Gain7_A2 0.000000f
+#define HPF_Fs176400_Gain7_B1 (-0.749096f)
+#define HPF_Fs176400_Gain7_B2 0.000000f
+/* Gain = 8.000000 dB */
+#define HPF_Fs176400_Gain8_A0 2.322217f
+#define HPF_Fs176400_Gain8_A1 (-2.071313f)
+#define HPF_Fs176400_Gain8_A2 0.000000f
+#define HPF_Fs176400_Gain8_B1 (-0.749096f)
+#define HPF_Fs176400_Gain8_B2 0.000000f
+/* Gain = 9.000000 dB */
+#define HPF_Fs176400_Gain9_A0 2.590263f
+#define HPF_Fs176400_Gain9_A1 (-2.339359f)
+#define HPF_Fs176400_Gain9_A2 0.000000f
+#define HPF_Fs176400_Gain9_B1 (-0.749096f)
+#define HPF_Fs176400_Gain9_B2 0.000000f
+/* Gain = 10.000000 dB */
+#define HPF_Fs176400_Gain10_A0 2.891016f
+#define HPF_Fs176400_Gain10_A1 (-2.640112f)
+#define HPF_Fs176400_Gain10_A2 0.000000f
+#define HPF_Fs176400_Gain10_B1 (-0.749096f)
+#define HPF_Fs176400_Gain10_B2 0.000000f
+/* Gain = 11.000000 dB */
+#define HPF_Fs176400_Gain11_A0 3.228465f
+#define HPF_Fs176400_Gain11_A1 (-2.977561f)
+#define HPF_Fs176400_Gain11_A2 0.000000f
+#define HPF_Fs176400_Gain11_B1 (-0.749096f)
+#define HPF_Fs176400_Gain11_B2 0.000000f
+/* Gain = 12.000000 dB */
+#define HPF_Fs176400_Gain12_A0 3.607090f
+#define HPF_Fs176400_Gain12_A1 (-3.356186f)
+#define HPF_Fs176400_Gain12_A2 0.000000f
+#define HPF_Fs176400_Gain12_B1 (-0.749096f)
+#define HPF_Fs176400_Gain12_B2 0.000000f
+/* Gain = 13.000000 dB */
+#define HPF_Fs176400_Gain13_A0 4.031914f
+#define HPF_Fs176400_Gain13_A1 (-3.781010f)
+#define HPF_Fs176400_Gain13_A2 0.000000f
+#define HPF_Fs176400_Gain13_B1 (-0.749096f)
+#define HPF_Fs176400_Gain13_B2 0.000000f
+/* Gain = 14.000000 dB */
+#define HPF_Fs176400_Gain14_A0 4.508575f
+#define HPF_Fs176400_Gain14_A1 (-4.257671f)
+#define HPF_Fs176400_Gain14_A2 0.000000f
+#define HPF_Fs176400_Gain14_B1 (-0.749096f)
+#define HPF_Fs176400_Gain14_B2 0.000000f
+/* Gain = 15.000000 dB */
+#define HPF_Fs176400_Gain15_A0 5.043397f
+#define HPF_Fs176400_Gain15_A1 (-4.792493f)
+#define HPF_Fs176400_Gain15_A2 0.000000f
+#define HPF_Fs176400_Gain15_B1 (-0.749096f)
+#define HPF_Fs176400_Gain15_B2 0.000000f
+
/* Coefficients for sample rate 192000Hz */
/* Gain = 1.000000 dB */
#define HPF_Fs192000_Gain1_A0 1.107823
@@ -1216,4 +1399,4 @@
#endif
-#endif
\ No newline at end of file
+#endif
diff --git a/media/libeffects/lvm/lib/Bundle/src/LVM_Control.c b/media/libeffects/lvm/lib/Bundle/src/LVM_Control.c
index 7b85f23..62b4c73 100644
--- a/media/libeffects/lvm/lib/Bundle/src/LVM_Control.c
+++ b/media/libeffects/lvm/lib/Bundle/src/LVM_Control.c
@@ -71,7 +71,8 @@
((pParams->SampleRate != LVM_FS_8000) && (pParams->SampleRate != LVM_FS_11025) && (pParams->SampleRate != LVM_FS_12000) &&
(pParams->SampleRate != LVM_FS_16000) && (pParams->SampleRate != LVM_FS_22050) && (pParams->SampleRate != LVM_FS_24000) &&
(pParams->SampleRate != LVM_FS_32000) && (pParams->SampleRate != LVM_FS_44100) && (pParams->SampleRate != LVM_FS_48000) &&
- (pParams->SampleRate != LVM_FS_96000) && (pParams->SampleRate != LVM_FS_192000)) ||
+ (pParams->SampleRate != LVM_FS_88200) && (pParams->SampleRate != LVM_FS_96000) &&
+ (pParams->SampleRate != LVM_FS_176400) && (pParams->SampleRate != LVM_FS_192000)) ||
#else
((pParams->SampleRate != LVM_FS_8000) && (pParams->SampleRate != LVM_FS_11025) && (pParams->SampleRate != LVM_FS_12000) &&
(pParams->SampleRate != LVM_FS_16000) && (pParams->SampleRate != LVM_FS_22050) && (pParams->SampleRate != LVM_FS_24000) &&
diff --git a/media/libeffects/lvm/lib/Bundle/src/LVM_Init.c b/media/libeffects/lvm/lib/Bundle/src/LVM_Init.c
index ade329b..0669a81 100644
--- a/media/libeffects/lvm/lib/Bundle/src/LVM_Init.c
+++ b/media/libeffects/lvm/lib/Bundle/src/LVM_Init.c
@@ -233,7 +233,13 @@
* Set the capabilities
*/
#if defined(BUILD_FLOAT) && defined(HIGHER_FS)
- DBE_Capabilities.SampleRate = LVDBE_CAP_FS_8000 | LVDBE_CAP_FS_11025 | LVDBE_CAP_FS_12000 | LVDBE_CAP_FS_16000 | LVDBE_CAP_FS_22050 | LVDBE_CAP_FS_24000 | LVDBE_CAP_FS_32000 | LVDBE_CAP_FS_44100 | LVDBE_CAP_FS_48000 | LVDBE_CAP_FS_96000 | LVDBE_CAP_FS_192000;
+ DBE_Capabilities.SampleRate = LVDBE_CAP_FS_8000 | LVDBE_CAP_FS_11025 |
+ LVDBE_CAP_FS_12000 | LVDBE_CAP_FS_16000 |
+ LVDBE_CAP_FS_22050 | LVDBE_CAP_FS_24000 |
+ LVDBE_CAP_FS_32000 | LVDBE_CAP_FS_44100 |
+ LVDBE_CAP_FS_48000 | LVDBE_CAP_FS_88200 |
+ LVDBE_CAP_FS_96000 | LVDBE_CAP_FS_176400 |
+ LVDBE_CAP_FS_192000;
#else
DBE_Capabilities.SampleRate = LVDBE_CAP_FS_8000 | LVDBE_CAP_FS_11025 | LVDBE_CAP_FS_12000 | LVDBE_CAP_FS_16000 | LVDBE_CAP_FS_22050 | LVDBE_CAP_FS_24000 | LVDBE_CAP_FS_32000 | LVDBE_CAP_FS_44100 | LVDBE_CAP_FS_48000;
#endif
@@ -270,7 +276,13 @@
* Set the capabilities
*/
#if defined(BUILD_FLOAT) && defined(HIGHER_FS)
- EQNB_Capabilities.SampleRate = LVEQNB_CAP_FS_8000 | LVEQNB_CAP_FS_11025 | LVEQNB_CAP_FS_12000 | LVEQNB_CAP_FS_16000 | LVEQNB_CAP_FS_22050 | LVEQNB_CAP_FS_24000 | LVEQNB_CAP_FS_32000 | LVEQNB_CAP_FS_44100 | LVEQNB_CAP_FS_48000 | LVEQNB_CAP_FS_96000 | LVEQNB_CAP_FS_192000;
+ EQNB_Capabilities.SampleRate = LVEQNB_CAP_FS_8000 | LVEQNB_CAP_FS_11025 |
+ LVEQNB_CAP_FS_12000 | LVEQNB_CAP_FS_16000 |
+ LVEQNB_CAP_FS_22050 | LVEQNB_CAP_FS_24000 |
+ LVEQNB_CAP_FS_32000 | LVEQNB_CAP_FS_44100 |
+ LVEQNB_CAP_FS_48000 | LVEQNB_CAP_FS_88200 |
+ LVEQNB_CAP_FS_96000 | LVEQNB_CAP_FS_176400 |
+ LVEQNB_CAP_FS_192000;
#else
EQNB_Capabilities.SampleRate = LVEQNB_CAP_FS_8000 | LVEQNB_CAP_FS_11025 | LVEQNB_CAP_FS_12000 | LVEQNB_CAP_FS_16000 | LVEQNB_CAP_FS_22050 | LVEQNB_CAP_FS_24000 | LVEQNB_CAP_FS_32000 | LVEQNB_CAP_FS_44100 | LVEQNB_CAP_FS_48000;
#endif
@@ -747,7 +759,13 @@
* Set the initialisation capabilities
*/
#if defined(BUILD_FLOAT) && defined(HIGHER_FS)
- DBE_Capabilities.SampleRate = LVDBE_CAP_FS_8000 | LVDBE_CAP_FS_11025 | LVDBE_CAP_FS_12000 | LVDBE_CAP_FS_16000 | LVDBE_CAP_FS_22050 | LVDBE_CAP_FS_24000 | LVDBE_CAP_FS_32000 | LVDBE_CAP_FS_44100 | LVDBE_CAP_FS_48000 | LVDBE_CAP_FS_96000 | LVDBE_CAP_FS_192000;
+ DBE_Capabilities.SampleRate = LVDBE_CAP_FS_8000 | LVDBE_CAP_FS_11025 |
+ LVDBE_CAP_FS_12000 | LVDBE_CAP_FS_16000 |
+ LVDBE_CAP_FS_22050 | LVDBE_CAP_FS_24000 |
+ LVDBE_CAP_FS_32000 | LVDBE_CAP_FS_44100 |
+ LVDBE_CAP_FS_48000 | LVDBE_CAP_FS_88200 |
+ LVDBE_CAP_FS_96000 | LVDBE_CAP_FS_176400 |
+ LVDBE_CAP_FS_192000;
#else
DBE_Capabilities.SampleRate = LVDBE_CAP_FS_8000 | LVDBE_CAP_FS_11025 | LVDBE_CAP_FS_12000 | LVDBE_CAP_FS_16000 | LVDBE_CAP_FS_22050 | LVDBE_CAP_FS_24000 | LVDBE_CAP_FS_32000 | LVDBE_CAP_FS_44100 | LVDBE_CAP_FS_48000;
#endif
@@ -805,7 +823,13 @@
* Set the initialisation capabilities
*/
#if defined(BUILD_FLOAT) && defined(HIGHER_FS)
- EQNB_Capabilities.SampleRate = LVEQNB_CAP_FS_8000 | LVEQNB_CAP_FS_11025 | LVEQNB_CAP_FS_12000 | LVEQNB_CAP_FS_16000 | LVEQNB_CAP_FS_22050 | LVEQNB_CAP_FS_24000 | LVEQNB_CAP_FS_32000 | LVEQNB_CAP_FS_44100 | LVEQNB_CAP_FS_48000 | LVEQNB_CAP_FS_96000 | LVEQNB_CAP_FS_192000;
+ EQNB_Capabilities.SampleRate = LVEQNB_CAP_FS_8000 | LVEQNB_CAP_FS_11025 |
+ LVEQNB_CAP_FS_12000 | LVEQNB_CAP_FS_16000 |
+ LVEQNB_CAP_FS_22050 | LVEQNB_CAP_FS_24000 |
+ LVEQNB_CAP_FS_32000 | LVEQNB_CAP_FS_44100 |
+ LVEQNB_CAP_FS_48000 | LVEQNB_CAP_FS_88200 |
+ LVEQNB_CAP_FS_96000 | LVEQNB_CAP_FS_176400 |
+ LVEQNB_CAP_FS_192000;
#else
EQNB_Capabilities.SampleRate = LVEQNB_CAP_FS_8000 | LVEQNB_CAP_FS_11025 | LVEQNB_CAP_FS_12000 | LVEQNB_CAP_FS_16000 | LVEQNB_CAP_FS_22050 | LVEQNB_CAP_FS_24000 | LVEQNB_CAP_FS_32000 | LVEQNB_CAP_FS_44100 | LVEQNB_CAP_FS_48000;
#endif
diff --git a/media/libeffects/lvm/lib/Bundle/src/LVM_Tables.c b/media/libeffects/lvm/lib/Bundle/src/LVM_Tables.c
index 199ddde..a5356d2 100644
--- a/media/libeffects/lvm/lib/Bundle/src/LVM_Tables.c
+++ b/media/libeffects/lvm/lib/Bundle/src/LVM_Tables.c
@@ -269,6 +269,53 @@
-HPF_Fs48000_Gain15_B1}
#ifdef HIGHER_FS
,
+ /* 88kHz Sampling rate */
+ {HPF_Fs88200_Gain1_A1, /* Gain Setting 1 */
+ HPF_Fs88200_Gain1_A0,
+ -HPF_Fs88200_Gain1_B1},
+ {HPF_Fs88200_Gain2_A1, /* Gain Setting 2 */
+ HPF_Fs88200_Gain2_A0,
+ -HPF_Fs88200_Gain2_B1},
+ {HPF_Fs88200_Gain3_A1, /* Gain Setting 3 */
+ HPF_Fs88200_Gain3_A0,
+ -HPF_Fs88200_Gain3_B1},
+ {HPF_Fs88200_Gain4_A1, /* Gain Setting 4 */
+ HPF_Fs88200_Gain4_A0,
+ -HPF_Fs88200_Gain4_B1},
+ {HPF_Fs88200_Gain5_A1, /* Gain Setting 5 */
+ HPF_Fs88200_Gain5_A0,
+ -HPF_Fs88200_Gain5_B1},
+ {HPF_Fs88200_Gain6_A1, /* Gain Setting 6 */
+ HPF_Fs88200_Gain6_A0,
+ -HPF_Fs88200_Gain6_B1},
+ {HPF_Fs88200_Gain7_A1, /* Gain Setting 7 */
+ HPF_Fs88200_Gain7_A0,
+ -HPF_Fs88200_Gain7_B1},
+ {HPF_Fs88200_Gain8_A1, /* Gain Setting 8 */
+ HPF_Fs88200_Gain8_A0,
+ -HPF_Fs88200_Gain8_B1},
+ {HPF_Fs88200_Gain9_A1, /* Gain Setting 9 */
+ HPF_Fs88200_Gain9_A0,
+ -HPF_Fs88200_Gain9_B1},
+ {HPF_Fs88200_Gain10_A1, /* Gain Setting 10 */
+ HPF_Fs88200_Gain10_A0,
+ -HPF_Fs88200_Gain10_B1},
+ {HPF_Fs88200_Gain11_A1, /* Gain Setting 11 */
+ HPF_Fs88200_Gain11_A0,
+ -HPF_Fs88200_Gain11_B1},
+ {HPF_Fs88200_Gain12_A1, /* Gain Setting 12 */
+ HPF_Fs88200_Gain12_A0,
+ -HPF_Fs88200_Gain12_B1},
+ {HPF_Fs88200_Gain13_A1, /* Gain Setting 13 */
+ HPF_Fs88200_Gain13_A0,
+ -HPF_Fs88200_Gain13_B1},
+ {HPF_Fs88200_Gain14_A1, /* Gain Setting 14 */
+ HPF_Fs88200_Gain14_A0,
+ -HPF_Fs88200_Gain14_B1},
+ {HPF_Fs88200_Gain15_A1, /* Gain Setting 15 */
+ HPF_Fs88200_Gain15_A0,
+ -HPF_Fs88200_Gain15_B1},
+
/* 96kHz sampling rate */
{HPF_Fs96000_Gain1_A1, /* Gain setting 1 */
HPF_Fs96000_Gain1_A0,
@@ -316,6 +363,53 @@
HPF_Fs96000_Gain15_A0,
-HPF_Fs96000_Gain15_B1},
+ /* 176kHz Sampling rate */
+ {HPF_Fs176400_Gain1_A1, /* Gain Setting 1 */
+ HPF_Fs176400_Gain1_A0,
+ -HPF_Fs176400_Gain1_B1},
+ {HPF_Fs176400_Gain2_A1, /* Gain Setting 2 */
+ HPF_Fs176400_Gain2_A0,
+ -HPF_Fs176400_Gain2_B1},
+ {HPF_Fs176400_Gain3_A1, /* Gain Setting 3 */
+ HPF_Fs176400_Gain3_A0,
+ -HPF_Fs176400_Gain3_B1},
+ {HPF_Fs176400_Gain4_A1, /* Gain Setting 4 */
+ HPF_Fs176400_Gain4_A0,
+ -HPF_Fs176400_Gain4_B1},
+ {HPF_Fs176400_Gain5_A1, /* Gain Setting 5 */
+ HPF_Fs176400_Gain5_A0,
+ -HPF_Fs176400_Gain5_B1},
+ {HPF_Fs176400_Gain6_A1, /* Gain Setting 6 */
+ HPF_Fs176400_Gain6_A0,
+ -HPF_Fs176400_Gain6_B1},
+ {HPF_Fs176400_Gain7_A1, /* Gain Setting 7 */
+ HPF_Fs176400_Gain7_A0,
+ -HPF_Fs176400_Gain7_B1},
+ {HPF_Fs176400_Gain8_A1, /* Gain Setting 8 */
+ HPF_Fs176400_Gain8_A0,
+ -HPF_Fs176400_Gain8_B1},
+ {HPF_Fs176400_Gain9_A1, /* Gain Setting 9 */
+ HPF_Fs176400_Gain9_A0,
+ -HPF_Fs176400_Gain9_B1},
+ {HPF_Fs176400_Gain10_A1, /* Gain Setting 10 */
+ HPF_Fs176400_Gain10_A0,
+ -HPF_Fs176400_Gain10_B1},
+ {HPF_Fs176400_Gain11_A1, /* Gain Setting 11 */
+ HPF_Fs176400_Gain11_A0,
+ -HPF_Fs176400_Gain11_B1},
+ {HPF_Fs176400_Gain12_A1, /* Gain Setting 12 */
+ HPF_Fs176400_Gain12_A0,
+ -HPF_Fs176400_Gain12_B1},
+ {HPF_Fs176400_Gain13_A1, /* Gain Setting 13 */
+ HPF_Fs176400_Gain13_A0,
+ -HPF_Fs176400_Gain13_B1},
+ {HPF_Fs176400_Gain14_A1, /* Gain Setting 14 */
+ HPF_Fs176400_Gain14_A0,
+ -HPF_Fs176400_Gain14_B1},
+ {HPF_Fs176400_Gain15_A1, /* Gain Setting 15 */
+ HPF_Fs176400_Gain15_A0,
+ -HPF_Fs176400_Gain15_B1},
+
/* 192kHz sampling rate */
{HPF_Fs192000_Gain1_A1, /* Gain setting 1 */
HPF_Fs192000_Gain1_A0,
diff --git a/media/libeffects/lvm/lib/Common/lib/LVM_Types.h b/media/libeffects/lvm/lib/Common/lib/LVM_Types.h
index 303b62d..59586e0 100644
--- a/media/libeffects/lvm/lib/Common/lib/LVM_Types.h
+++ b/media/libeffects/lvm/lib/Common/lib/LVM_Types.h
@@ -169,8 +169,10 @@
LVM_FS_44100 = 7,
LVM_FS_48000 = 8,
#ifdef HIGHER_FS
- LVM_FS_96000 = 9,
- LVM_FS_192000 = 10,
+ LVM_FS_88200 = 9,
+ LVM_FS_96000 = 10,
+ LVM_FS_176400 = 11,
+ LVM_FS_192000 = 12,
#endif
LVM_FS_INVALID = LVM_MAXENUM-1,
LVM_FS_DUMMY = LVM_MAXENUM
diff --git a/media/libeffects/lvm/lib/Eq/lib/LVEQNB.h b/media/libeffects/lvm/lib/Eq/lib/LVEQNB.h
index e7fdbf6..385dbcf 100644
--- a/media/libeffects/lvm/lib/Eq/lib/LVEQNB.h
+++ b/media/libeffects/lvm/lib/Eq/lib/LVEQNB.h
@@ -201,8 +201,10 @@
#define LVEQNB_CAP_FS_44100 128
#define LVEQNB_CAP_FS_48000 256
#if defined(BUILD_FLOAT) && defined(HIGHER_FS)
-#define LVEQNB_CAP_FS_96000 512
-#define LVEQNB_CAP_FS_192000 1024
+#define LVEQNB_CAP_FS_88200 512
+#define LVEQNB_CAP_FS_96000 1024
+#define LVEQNB_CAP_FS_176400 2048
+#define LVEQNB_CAP_FS_192000 4096
#endif
typedef enum
@@ -217,8 +219,10 @@
LVEQNB_FS_44100 = 7,
LVEQNB_FS_48000 = 8,
#ifdef HIGHER_FS
- LVEQNB_FS_96000 = 9,
- LVEQNB_FS_192000 = 10,
+ LVEQNB_FS_88200 = 9,
+ LVEQNB_FS_96000 = 10,
+ LVEQNB_FS_176400 = 11,
+ LVEQNB_FS_192000 = 12,
#endif
LVEQNB_FS_MAX = LVM_MAXINT_32
} LVEQNB_Fs_en;
diff --git a/media/libeffects/lvm/lib/Eq/src/LVEQNB_Coeffs.h b/media/libeffects/lvm/lib/Eq/src/LVEQNB_Coeffs.h
index 42ea46f..755141e 100644
--- a/media/libeffects/lvm/lib/Eq/src/LVEQNB_Coeffs.h
+++ b/media/libeffects/lvm/lib/Eq/src/LVEQNB_Coeffs.h
@@ -109,7 +109,9 @@
#define LVEQNB_2PiOn_48000 0.000131f
#ifdef HIGHER_FS
+#define LVEQNB_2PiOn_88200 0.000071f
#define LVEQNB_2PiOn_96000 0.000065f
+#define LVEQNB_2PiOn_176400 0.000036f
#define LVEQNB_2PiOn_192000 0.000033f
#endif
diff --git a/media/libeffects/lvm/lib/Eq/src/LVEQNB_Tables.c b/media/libeffects/lvm/lib/Eq/src/LVEQNB_Tables.c
index 563181c..453c42d 100644
--- a/media/libeffects/lvm/lib/Eq/src/LVEQNB_Tables.c
+++ b/media/libeffects/lvm/lib/Eq/src/LVEQNB_Tables.c
@@ -46,7 +46,9 @@
32000,
44100,
48000,
+ 88200,
96000,
+ 176400,
192000
};
#else
@@ -82,7 +84,9 @@
LVEQNB_2PiOn_44100,
LVEQNB_2PiOn_48000
#ifdef HIGHER_FS
+ ,LVEQNB_2PiOn_88200
,LVEQNB_2PiOn_96000
+ ,LVEQNB_2PiOn_176400
,LVEQNB_2PiOn_192000
#endif
};
@@ -249,30 +253,4 @@
16586, /* a2 */
-44}; /* a3 */
-/************************************************************************************/
-/* */
-/* Bypass mixer time constants (100ms) */
-/* */
-/************************************************************************************/
-#define LVEQNB_MIX_TC_Fs8000 32580 /* Floating point value 0.994262695 */
-#define LVEQNB_MIX_TC_Fs11025 32632 /* Floating point value 0.995849609 */
-#define LVEQNB_MIX_TC_Fs12000 32643 /* Floating point value 0.996185303 */
-#define LVEQNB_MIX_TC_Fs16000 32674 /* Floating point value 0.997131348 */
-#define LVEQNB_MIX_TC_Fs22050 32700 /* Floating point value 0.997924805 */
-#define LVEQNB_MIX_TC_Fs24000 32705 /* Floating point value 0.998077393 */
-#define LVEQNB_MIX_TC_Fs32000 32721 /* Floating point value 0.998565674 */
-#define LVEQNB_MIX_TC_Fs44100 32734 /* Floating point value 0.998962402 */
-#define LVEQNB_MIX_TC_Fs48000 32737 /* Floating point value 0.999053955 */
-
-
-const LVM_INT16 LVEQNB_MixerTCTable[] = {
- LVEQNB_MIX_TC_Fs8000,
- LVEQNB_MIX_TC_Fs11025,
- LVEQNB_MIX_TC_Fs12000,
- LVEQNB_MIX_TC_Fs16000,
- LVEQNB_MIX_TC_Fs22050,
- LVEQNB_MIX_TC_Fs24000,
- LVEQNB_MIX_TC_Fs32000,
- LVEQNB_MIX_TC_Fs44100,
- LVEQNB_MIX_TC_Fs48000};
diff --git a/media/libeffects/lvm/lib/Reverb/src/LVREV_Private.h b/media/libeffects/lvm/lib/Reverb/src/LVREV_Private.h
index ff7475e..c915ac0 100644
--- a/media/libeffects/lvm/lib/Reverb/src/LVREV_Private.h
+++ b/media/libeffects/lvm/lib/Reverb/src/LVREV_Private.h
@@ -123,7 +123,7 @@
#ifndef HIGHER_FS
#define LVREV_NUM_FS 9 /* Number of supported sample rates */
#else
-#define LVREV_NUM_FS 11 /* Number of supported sample rates */
+#define LVREV_NUM_FS 13 /* Number of supported sample rates */
#endif
#define LVREV_MAXBLKSIZE_LIMIT 64 /* Maximum block size low limit */
diff --git a/media/libeffects/lvm/lib/Reverb/src/LVREV_SetControlParameters.c b/media/libeffects/lvm/lib/Reverb/src/LVREV_SetControlParameters.c
index 8c7807f..dfed28e 100644
--- a/media/libeffects/lvm/lib/Reverb/src/LVREV_SetControlParameters.c
+++ b/media/libeffects/lvm/lib/Reverb/src/LVREV_SetControlParameters.c
@@ -68,7 +68,8 @@
(pNewParams->SampleRate != LVM_FS_44100) &&
(pNewParams->SampleRate != LVM_FS_48000)
#ifdef HIGHER_FS
- && (pNewParams->SampleRate != LVM_FS_96000) && (pNewParams->SampleRate != LVM_FS_192000)
+ && (pNewParams->SampleRate != LVM_FS_88200) && (pNewParams->SampleRate != LVM_FS_96000)
+ && (pNewParams->SampleRate != LVM_FS_176400) && (pNewParams->SampleRate != LVM_FS_192000)
#endif
)
#ifdef SUPPORT_MC
diff --git a/media/libeffects/lvm/lib/Reverb/src/LVREV_Tables.c b/media/libeffects/lvm/lib/Reverb/src/LVREV_Tables.c
index b3edc60..1058740 100644
--- a/media/libeffects/lvm/lib/Reverb/src/LVREV_Tables.c
+++ b/media/libeffects/lvm/lib/Reverb/src/LVREV_Tables.c
@@ -52,7 +52,9 @@
32000,
44100,
48000,
+ 88200,
96000,
+ 176400,
192000
};
#endif
diff --git a/media/libeffects/lvm/lib/SpectrumAnalyzer/src/LVPSA_Private.h b/media/libeffects/lvm/lib/SpectrumAnalyzer/src/LVPSA_Private.h
index a750bb0..ee07e2e 100644
--- a/media/libeffects/lvm/lib/SpectrumAnalyzer/src/LVPSA_Private.h
+++ b/media/libeffects/lvm/lib/SpectrumAnalyzer/src/LVPSA_Private.h
@@ -46,7 +46,7 @@
#ifndef HIGHER_FS
#define LVPSA_NR_SUPPORTED_RATE 9 /* From 8000Hz to 48000Hz*/
#else
-#define LVPSA_NR_SUPPORTED_RATE 11 /* From 8000Hz to 192000Hz*/
+#define LVPSA_NR_SUPPORTED_RATE 13 /* From 8000Hz to 192000Hz*/
#endif
#define LVPSA_NR_SUPPORTED_SPEED 3 /* LOW, MEDIUM, HIGH */
diff --git a/media/libeffects/lvm/lib/SpectrumAnalyzer/src/LVPSA_Tables.c b/media/libeffects/lvm/lib/SpectrumAnalyzer/src/LVPSA_Tables.c
index 1287503..f8af496 100644
--- a/media/libeffects/lvm/lib/SpectrumAnalyzer/src/LVPSA_Tables.c
+++ b/media/libeffects/lvm/lib/SpectrumAnalyzer/src/LVPSA_Tables.c
@@ -54,7 +54,9 @@
32000,
44100,
48000,
+ 88200,
96000,
+ 176400,
192000}; /* 192kS/s */
#endif
@@ -78,7 +80,9 @@
48696,
44739
#ifdef HIGHER_FS
+ ,24348
,22369
+ ,12174
,11185 /* 192kS/s */
#endif
};
@@ -105,7 +109,9 @@
882,
960
#ifdef HIGHER_FS
+ ,1764
,1920
+ ,3528
,3840 /* 192kS/s */
#endif
};
@@ -128,7 +134,9 @@
30, /* 44100 S/s */
32 /* 48000 S/s */
#ifdef HIGHER_FS
+ ,60 /* 88200 S/s */
,64 /* 96000 S/s */
+ ,120 /* 176400 S/s */
,128 /*192000 S/s */
#endif
};
@@ -153,7 +161,9 @@
4781,
4392
#ifdef HIGHER_FS
+ ,2390
,2196
+ ,1195
,1098 /* 192kS/s */
#endif
};
@@ -169,7 +179,9 @@
0.1459089f,
0.1340372f
#ifdef HIGHER_FS
+ ,0.0729476f
,0.0670186f
+ ,0.0364738f
,0.0335093f /* 192kS/s */
#endif
};
@@ -352,7 +364,9 @@
/* 48kS/s */
{-0.9932638457976282f,0.0066249934025109f},
#ifdef HIGHER_FS
+ {-0.9931269618682563f,0.0067592649720609f},
{-0.9932638457976282f,0.0066249934025109f},
+ {-0.9931269618682563f,0.0067592649720609f},
{-0.9932638457976282f,0.0066249934025109f},
#endif
/* 8kS/s */ /* LVPSA_SPEED_MEDIUM */
@@ -368,7 +382,9 @@
/* 48kS/s */
{-0.9540119562298059f,0.0445343819446862f},
#ifdef HIGHER_FS
+ {-0.9531011912040412f,0.0453995238058269f},
{-0.9540119562298059f,0.0445343819446862f},
+ {-0.9531011912040412f,0.0453995238058269f},
{-0.9540119562298059f,0.0445343819446862f},
#endif
/* 8kS/s */ /* LVPSA_SPEED_HIGH */
@@ -383,7 +399,9 @@
/* 48kS/s */
{-0.7274807319045067f,0.2356666540727019f}
#ifdef HIGHER_FS
+ ,{-0.7229706319049001f,0.2388987224549055f}
,{-0.7274807319045067f,0.2356666540727019f}
+ ,{-0.7229706319049001f,0.2388987224549055f}
,{-0.7274807319045067f,0.2356666540727019f}
#endif
};
diff --git a/media/libeffects/lvm/lib/StereoWidening/src/LVCS_Headphone_Coeffs.h b/media/libeffects/lvm/lib/StereoWidening/src/LVCS_Headphone_Coeffs.h
index 0c2fe53..e45d81f 100644
--- a/media/libeffects/lvm/lib/StereoWidening/src/LVCS_Headphone_Coeffs.h
+++ b/media/libeffects/lvm/lib/StereoWidening/src/LVCS_Headphone_Coeffs.h
@@ -152,6 +152,24 @@
#define CS_SIDE_48000_SCALE 14
#ifdef HIGHER_FS
+/* Coefficients for 88200Hz sample rate.
+ * The filter coefficients are obtained by carrying out
+ * state-space analysis using the coefficients available
+ * for 44100Hz.
+ */
+#define CS_MIDDLE_88200_A0 0.233846f
+#define CS_MIDDLE_88200_A1 (-0.232657f)
+#define CS_MIDDLE_88200_A2 0.000000f
+#define CS_MIDDLE_88200_B1 (-0.992747f)
+#define CS_MIDDLE_88200_B2 0.000000f
+#define CS_MIDDLE_88200_SCALE 15
+#define CS_SIDE_88200_A0 0.231541f
+#define CS_SIDE_88200_A1 (-0.289586f)
+#define CS_SIDE_88200_A2 0.058045f
+#define CS_SIDE_88200_B1 (-1.765300f)
+#define CS_SIDE_88200_B2 0.769816f
+#define CS_SIDE_88200_SCALE 14
+
/* Stereo Enhancer coefficients for 96000Hz sample rate, scaled with 0.165*/
/* high pass filter with cutoff frequency 102.18 Hz*/
#define CS_MIDDLE_96000_A0 0.235532
@@ -160,13 +178,33 @@
#define CS_MIDDLE_96000_B1 (-0.993334)
#define CS_MIDDLE_96000_B2 0.000000
#define CS_MIDDLE_96000_SCALE 15
-/* bandpass filter with fc1 270 and fc2 3703, designed using 2nd order butterworth */
-#define CS_SIDE_96000_A0 0.016727
-#define CS_SIDE_96000_A1 0.000000
-#define CS_SIDE_96000_A2 (-0.016727)
-#define CS_SIDE_96000_B1 (-1.793372)
-#define CS_SIDE_96000_B2 0.797236
-#define CS_SIDE_96000_SCALE 14
+/* Coefficients calculated using tf2ss and ss2tf functions based on
+ * coefficients available for 48000Hz sampling frequency
+ */
+#define CS_SIDE_96000_A0 0.224326f
+#define CS_SIDE_96000_A1 (-0.294937f)
+#define CS_SIDE_96000_A2 0.070611f
+#define CS_SIDE_96000_B1 (-1.792166f)
+#define CS_SIDE_96000_B2 0.795830f
+#define CS_SIDE_96000_SCALE 14
+
+/* Stereo Enhancer coefficients for 176400Hz sample rate.
+ * The filter coefficients are obtained by carrying out
+ * state-space analysis using the coefficients available
+ * for 44100Hz.
+ */
+#define CS_MIDDLE_176400_A0 0.233973f
+#define CS_MIDDLE_176400_A1 (-0.233378f)
+#define CS_MIDDLE_176400_A2 0.000000f
+#define CS_MIDDLE_176400_B1 (-0.996367f)
+#define CS_MIDDLE_176400_B2 0.000000f
+#define CS_MIDDLE_176400_SCALE 15
+#define CS_SIDE_176400_A0 0.199836f
+#define CS_SIDE_176400_A1 (-0.307544f)
+#define CS_SIDE_176400_A2 0.107708f
+#define CS_SIDE_176400_B1 (-1.876572f)
+#define CS_SIDE_176400_B2 0.877771f
+#define CS_SIDE_176400_SCALE 14
/* Stereo Enhancer coefficients for 192000Hz sample rate, scaled with 0.1689*/
#define CS_MIDDLE_192000_A0 0.241219
@@ -175,13 +213,15 @@
#define CS_MIDDLE_192000_B1 (-0.996661)
#define CS_MIDDLE_192000_B2 0.000000
#define CS_MIDDLE_192000_SCALE 15
-/* bandpass filter with fc1 270 and fc2 3703, designed using 2nd order butterworth */
-#define CS_SIDE_192000_A0 0.008991
-#define CS_SIDE_192000_A1 (-0.000000)
-#define CS_SIDE_192000_A2 (-0.008991)
-#define CS_SIDE_192000_B1 (-1.892509)
-#define CS_SIDE_192000_B2 0.893524
-#define CS_SIDE_192000_SCALE 14
+/* Coefficients calculated using tf2ss and ss2tf functions based on
+ * coefficients available for 48000Hz sampling frequency
+ */
+#define CS_SIDE_192000_A0 0.196039f
+#define CS_SIDE_192000_A1 (-0.311027f)
+#define CS_SIDE_192000_A2 0.114988f
+#define CS_SIDE_192000_B1 (-1.891380f)
+#define CS_SIDE_192000_B2 0.8923460f
+#define CS_SIDE_192000_SCALE 14
#endif
/************************************************************************************/
@@ -199,7 +239,13 @@
#define LVCS_STEREODELAY_CS_24KHZ 279 /* Sample rate 24kS/s */
#define LVCS_STEREODELAY_CS_32KHZ 372 /* Sample rate 32kS/s */
#define LVCS_STEREODELAY_CS_44KHZ 512 /* Sample rate 44kS/s */
+// TODO: this should linearly scale by frequency but is limited to 512 frames until
+// we ensure enough buffer size has been allocated.
#define LVCS_STEREODELAY_CS_48KHZ 512 /* Sample rate 48kS/s */
+#define LVCS_STEREODELAY_CS_88KHZ 512 /* Sample rate 88.2kS/s */
+#define LVCS_STEREODELAY_CS_96KHZ 512 /* Sample rate 96kS/s */
+#define LVCS_STEREODELAY_CS_176KHZ 512 /* Sample rate 176.4kS/s */
+#define LVCS_STEREODELAY_CS_192KHZ 512 /* Sample rate 196kS/s */
/* Reverb coefficients for 8000 Hz sample rate, scaled with 1.038030 */
#define CS_REVERB_8000_A0 0.667271
@@ -275,6 +321,14 @@
#define CS_REVERB_48000_SCALE 14
#ifdef HIGHER_FS
+/* Reverb coefficients for 88200Hz sample rate, scaled with 0.8 */
+/* Band pass filter with fc1=500 and fc2=8000 */
+#define CS_REVERB_88200_A0 0.171901f
+#define CS_REVERB_88200_A1 0.000000f
+#define CS_REVERB_88200_A2 (-0.171901f)
+#define CS_REVERB_88200_B1 (-1.553948f)
+#define CS_REVERB_88200_B2 (0.570248f)
+#define CS_REVERB_88200_SCALE 14
/* Reverb coefficients for 96000Hz sample rate, scaled with 0.8 */
/* Band pass filter with fc1=500 and fc2=8000*/
#define CS_REVERB_96000_A0 0.1602488
@@ -284,6 +338,14 @@
#define CS_REVERB_96000_B2 0.599377
#define CS_REVERB_96000_SCALE 14
+/* Reverb coefficients for 176400Hz sample rate, scaled with 0.8 */
+/* Band pass filter with fc1=500 and fc2=8000 */
+#define CS_REVERB_176400_A0 0.094763f
+#define CS_REVERB_176400_A1 0.000000f
+#define CS_REVERB_176400_A2 (-0.094763f)
+#define CS_REVERB_176400_B1 (-1.758593f)
+#define CS_REVERB_176400_B2 (0.763091f)
+#define CS_REVERB_176400_SCALE 14
/* Reverb coefficients for 192000Hz sample rate, scaled with 0.8 */
/* Band pass filter with fc1=500 and fc2=8000*/
#define CS_REVERB_192000_A0 0.0878369
@@ -446,6 +508,24 @@
#ifdef HIGHER_FS
+/* Equaliser coefficients for 88200Hz sample rate.
+ * The filter coefficients are obtained by carrying out
+ * state-space analysis using the coefficients available
+ * for 44100Hz.
+ */
+#define CS_EQUALISER_88200_A0 1.771899f
+#define CS_EQUALISER_88200_A1 (-2.930762f)
+#define CS_EQUALISER_88200_A2 1.172175f
+#define CS_EQUALISER_88200_B1 (-1.438349f)
+#define CS_EQUALISER_88200_B2 0.442520f
+#define CS_EQUALISER_88200_SCALE 13
+#define CSEX_EQUALISER_88200_A0 2.675241f
+#define CSEX_EQUALISER_88200_A1 (-4.466154f)
+#define CSEX_EQUALISER_88200_A2 1.810305f
+#define CSEX_EQUALISER_88200_B1 (-0.925350f)
+#define CSEX_EQUALISER_88200_B2 (-0.066616f)
+#define CSEX_EQUALISER_88200_SCALE 13
+
#define CS_EQUALISER_96000_A0 1.784497
#define CS_EQUALISER_96000_A1 (-3.001435)
#define CS_EQUALISER_96000_A2 1.228422
@@ -458,6 +538,23 @@
#define CSEX_EQUALISER_96000_B1 (-0.971718)
#define CSEX_EQUALISER_96000_B2 (-0.021216)
#define CSEX_EQUALISER_96000_SCALE 13
+/* Equaliser coefficients for 176400Hz sample rate.
+ * The filter coefficients are obtained by carrying out
+ * state-space analysis using the coefficients available
+ * for 44100Hz.
+ */
+#define CS_EQUALISER_176400_A0 1.883440f
+#define CS_EQUALISER_176400_A1 (-3.414272f)
+#define CS_EQUALISER_176400_A2 1.534702f
+#define CS_EQUALISER_176400_B1 (-1.674614f)
+#define CS_EQUALISER_176400_B2 0.675827f
+#define CS_EQUALISER_176400_SCALE 13
+#define CSEX_EQUALISER_176400_A0 3.355068f
+#define CSEX_EQUALISER_176400_A1 (-6.112578f)
+#define CSEX_EQUALISER_176400_A2 2.764135f
+#define CSEX_EQUALISER_176400_B1 (-1.268533f)
+#define CSEX_EQUALISER_176400_B2 0.271277f
+#define CSEX_EQUALISER_176400_SCALE 13
#define CS_EQUALISER_192000_A0 1.889582
#define CS_EQUALISER_192000_A1 (-3.456140)
diff --git a/media/libeffects/lvm/lib/StereoWidening/src/LVCS_Tables.c b/media/libeffects/lvm/lib/StereoWidening/src/LVCS_Tables.c
index 0765764..a1fb48f 100644
--- a/media/libeffects/lvm/lib/StereoWidening/src/LVCS_Tables.c
+++ b/media/libeffects/lvm/lib/StereoWidening/src/LVCS_Tables.c
@@ -74,10 +74,18 @@
(LVM_UINT16 )CS_MIDDLE_48000_SCALE}
#ifdef HIGHER_FS
,
+ {CS_MIDDLE_88200_A0, /* 88kS/s coefficients */
+ CS_MIDDLE_88200_A1,
+ CS_MIDDLE_88200_B1,
+ (LVM_UINT16)CS_MIDDLE_88200_SCALE},
{CS_MIDDLE_96000_A0, /* 96kS/s coefficients */
CS_MIDDLE_96000_A1,
CS_MIDDLE_96000_B1,
(LVM_UINT16 )CS_MIDDLE_96000_SCALE},
+ {CS_MIDDLE_176400_A0, /* 176kS/s coefficients */
+ CS_MIDDLE_176400_A1,
+ CS_MIDDLE_176400_B1,
+ (LVM_UINT16)CS_MIDDLE_176400_SCALE},
{CS_MIDDLE_192000_A0, /* 192kS/s coefficients */
CS_MIDDLE_192000_A1,
CS_MIDDLE_192000_B1,
@@ -144,12 +152,24 @@
(LVM_UINT16 )CS_SIDE_48000_SCALE}
#ifdef HIGHER_FS
,
+ {CS_SIDE_88200_A0, /* 88kS/s coefficients */
+ CS_SIDE_88200_A1,
+ CS_SIDE_88200_A2,
+ CS_SIDE_88200_B1,
+ CS_SIDE_88200_B2,
+ (LVM_UINT16)CS_SIDE_88200_SCALE},
{CS_SIDE_96000_A0, /* 96kS/s coefficients */
CS_SIDE_96000_A1,
CS_SIDE_96000_A2,
CS_SIDE_96000_B1,
CS_SIDE_96000_B2,
(LVM_UINT16 )CS_SIDE_96000_SCALE},
+ {CS_SIDE_176400_A0, /*176kS/s coefficients */
+ CS_SIDE_176400_A1,
+ CS_SIDE_176400_A2,
+ CS_SIDE_176400_B1,
+ CS_SIDE_176400_B2,
+ (LVM_UINT16)CS_SIDE_176400_SCALE},
{CS_SIDE_192000_A0, /* 192kS/s coefficients */
CS_SIDE_192000_A1,
CS_SIDE_192000_A2,
@@ -223,12 +243,24 @@
CS_EQUALISER_48000_B2,
(LVM_UINT16 )CS_EQUALISER_48000_SCALE},
#ifdef HIGHER_FS
+ {CS_EQUALISER_88200_A0, /* 88kS/s coeffieients */
+ CS_EQUALISER_88200_A1,
+ CS_EQUALISER_88200_A2,
+ CS_EQUALISER_88200_B1,
+ CS_EQUALISER_88200_B2,
+ (LVM_UINT16)CS_EQUALISER_88200_SCALE},
{CS_EQUALISER_96000_A0, /* 96kS/s coefficients */
CS_EQUALISER_96000_A1,
CS_EQUALISER_96000_A2,
CS_EQUALISER_96000_B1,
CS_EQUALISER_96000_B2,
(LVM_UINT16 )CS_EQUALISER_96000_SCALE},
+ {CS_EQUALISER_176400_A0, /* 176kS/s coefficients */
+ CS_EQUALISER_176400_A1,
+ CS_EQUALISER_176400_A2,
+ CS_EQUALISER_176400_B1,
+ CS_EQUALISER_176400_B2,
+ (LVM_UINT16)CS_EQUALISER_176400_SCALE},
{CS_EQUALISER_192000_A0, /* 192kS/s coefficients */
CS_EQUALISER_192000_A1,
CS_EQUALISER_192000_A2,
@@ -294,12 +326,24 @@
(LVM_UINT16 )CSEX_EQUALISER_48000_SCALE}
#ifdef HIGHER_FS
,
+ {CSEX_EQUALISER_88200_A0, /* 88kS/s coefficients */
+ CSEX_EQUALISER_88200_A1,
+ CSEX_EQUALISER_88200_A2,
+ CSEX_EQUALISER_88200_B1,
+ CSEX_EQUALISER_88200_B2,
+ (LVM_UINT16)CSEX_EQUALISER_88200_SCALE},
{CSEX_EQUALISER_96000_A0, /* 96kS/s coefficients */
CSEX_EQUALISER_96000_A1,
CSEX_EQUALISER_96000_A2,
CSEX_EQUALISER_96000_B1,
CSEX_EQUALISER_96000_B2,
(LVM_UINT16 )CSEX_EQUALISER_96000_SCALE},
+ {CSEX_EQUALISER_176400_A0, /* 176kS/s coefficients */
+ CSEX_EQUALISER_176400_A1,
+ CSEX_EQUALISER_176400_A2,
+ CSEX_EQUALISER_176400_B1,
+ CSEX_EQUALISER_176400_B2,
+ (LVM_UINT16)CSEX_EQUALISER_176400_SCALE},
{CSEX_EQUALISER_192000_A0, /* 192kS/s coefficients */
CSEX_EQUALISER_192000_A1,
CSEX_EQUALISER_192000_A2,
@@ -326,7 +370,12 @@
LVCS_STEREODELAY_CS_24KHZ,
LVCS_STEREODELAY_CS_32KHZ,
LVCS_STEREODELAY_CS_44KHZ,
- LVCS_STEREODELAY_CS_48KHZ};
+ LVCS_STEREODELAY_CS_48KHZ,
+ LVCS_STEREODELAY_CS_88KHZ,
+ LVCS_STEREODELAY_CS_96KHZ,
+ LVCS_STEREODELAY_CS_176KHZ,
+ LVCS_STEREODELAY_CS_192KHZ,
+};
/************************************************************************************/
/* */
@@ -392,12 +441,24 @@
(LVM_UINT16 )CS_REVERB_48000_SCALE}
#ifdef HIGHER_FS
,
+ {CS_REVERB_88200_A0, /* 88kS/s coefficients */
+ CS_REVERB_88200_A1,
+ CS_REVERB_88200_A2,
+ CS_REVERB_88200_B1,
+ CS_REVERB_88200_B2,
+ (LVM_UINT16)CS_REVERB_88200_SCALE},
{CS_REVERB_96000_A0, /* 96kS/s coefficients */
CS_REVERB_96000_A1,
CS_REVERB_96000_A2,
CS_REVERB_96000_B1,
CS_REVERB_96000_B2,
(LVM_UINT16 )CS_REVERB_96000_SCALE},
+ {CS_REVERB_176400_A0, /* 176kS/s coefficients */
+ CS_REVERB_176400_A1,
+ CS_REVERB_176400_A2,
+ CS_REVERB_176400_B1,
+ CS_REVERB_176400_B2,
+ (LVM_UINT16)CS_REVERB_176400_SCALE},
{CS_REVERB_192000_A0, /* 192kS/s coefficients */
CS_REVERB_192000_A1,
CS_REVERB_192000_A2,
@@ -509,12 +570,14 @@
#define LVCS_VOL_TC_Fs44100 32734 /* Floating point value 0.998962402 */
#define LVCS_VOL_TC_Fs48000 32737 /* Floating point value 0.999053955 */
#if defined(BUILD_FLOAT) && defined(HIGHER_FS)
+#define LVCS_VOL_TC_Fs88200 32751 /* Floating point value 0.999481066 */
#define LVCS_VOL_TC_Fs96000 32751 /* Floating point value 0.999511703 */ /* Todo @ need to re check this value*/
+#define LVCS_VOL_TC_Fs176400 32759 /* Floating point value 0.999740499 */
#define LVCS_VOL_TC_Fs192000 32763 /* Floating point value 0.999877925 */ /* Todo @ need to re check this value*/
#endif
#if defined(BUILD_FLOAT) && defined(HIGHER_FS)
-const LVM_INT16 LVCS_VolumeTCTable[11] = {LVCS_VOL_TC_Fs8000,
+const LVM_INT16 LVCS_VolumeTCTable[13] = {LVCS_VOL_TC_Fs8000,
LVCS_VOL_TC_Fs11025,
LVCS_VOL_TC_Fs12000,
LVCS_VOL_TC_Fs16000,
@@ -523,7 +586,9 @@
LVCS_VOL_TC_Fs32000,
LVCS_VOL_TC_Fs44100,
LVCS_VOL_TC_Fs48000,
+ LVCS_VOL_TC_Fs88200,
LVCS_VOL_TC_Fs96000,
+ LVCS_VOL_TC_Fs176400,
LVCS_VOL_TC_Fs192000
};
#else
@@ -545,7 +610,7 @@
/* */
/************************************************************************************/
#if defined(BUILD_FLOAT) && defined(HIGHER_FS)
-const LVM_INT32 LVCS_SampleRateTable[11] = {8000,
+const LVM_INT32 LVCS_SampleRateTable[13] = {8000,
11025,
12000,
16000,
@@ -554,7 +619,9 @@
32000,
44100,
48000,
+ 88200,
96000,
+ 176400,
192000
};
#else
diff --git a/media/libeffects/lvm/tests/lvmtest.cpp b/media/libeffects/lvm/tests/lvmtest.cpp
index 01c5955..99551cc 100644
--- a/media/libeffects/lvm/tests/lvmtest.cpp
+++ b/media/libeffects/lvm/tests/lvmtest.cpp
@@ -447,19 +447,69 @@
lvmConfigParams_t *plvmConfigParams,
LVM_ControlParams_t *params) {
LVM_ReturnStatus_en LvmStatus = LVM_SUCCESS; /* Function call status */
- LVM_EQNB_BandDef_t BandDefs[MAX_NUM_BANDS]; /* Equaliser band definitions */
- int eqPresetLevel = plvmConfigParams->eqPresetLevel;
- int nrChannels = plvmConfigParams->nrChannels;
- params->NrChannels = nrChannels;
/* Set the initial process parameters */
/* General parameters */
params->OperatingMode = LVM_MODE_ON;
- params->SampleRate = LVM_FS_44100;
- params->SourceFormat = LVM_STEREO;
params->SpeakerType = LVM_HEADPHONES;
- pContext->pBundledContext->SampleRate = LVM_FS_44100;
+ const int nrChannels = plvmConfigParams->nrChannels;
+ params->NrChannels = nrChannels;
+ if (nrChannels == 1) {
+ params->SourceFormat = LVM_MONO;
+ } else if (nrChannels == 2) {
+ params->SourceFormat = LVM_STEREO;
+ } else if (nrChannels > 2 && nrChannels <= 8) { // FCC_2 FCC_8
+ params->SourceFormat = LVM_MULTICHANNEL;
+ } else {
+ return -EINVAL;
+ }
+
+ LVM_Fs_en sampleRate;
+ switch (plvmConfigParams->samplingFreq) {
+ case 8000:
+ sampleRate = LVM_FS_8000;
+ break;
+ case 11025:
+ sampleRate = LVM_FS_11025;
+ break;
+ case 12000:
+ sampleRate = LVM_FS_12000;
+ break;
+ case 16000:
+ sampleRate = LVM_FS_16000;
+ break;
+ case 22050:
+ sampleRate = LVM_FS_22050;
+ break;
+ case 24000:
+ sampleRate = LVM_FS_24000;
+ break;
+ case 32000:
+ sampleRate = LVM_FS_32000;
+ break;
+ case 44100:
+ sampleRate = LVM_FS_44100;
+ break;
+ case 48000:
+ sampleRate = LVM_FS_48000;
+ break;
+ case 88200:
+ sampleRate = LVM_FS_88200;
+ break;
+ case 96000:
+ sampleRate = LVM_FS_96000;
+ break;
+ case 176400:
+ sampleRate = LVM_FS_176400;
+ break;
+ case 192000:
+ sampleRate = LVM_FS_192000;
+ break;
+ default:
+ return -EINVAL;
+ }
+ params->SampleRate = sampleRate;
/* Concert Sound parameters */
params->VirtualizerOperatingMode = plvmConfigParams->csEnable;
@@ -468,14 +518,17 @@
params->CS_EffectLevel = LVM_CS_EFFECT_NONE;
/* N-Band Equaliser parameters */
- params->EQNB_OperatingMode = plvmConfigParams->eqEnable;
- params->pEQNB_BandDefinition = &BandDefs[0];
+ const int eqPresetLevel = plvmConfigParams->eqPresetLevel;
+ LVM_EQNB_BandDef_t BandDefs[MAX_NUM_BANDS]; /* Equaliser band definitions */
for (int i = 0; i < FIVEBAND_NUMBANDS; i++) {
BandDefs[i].Frequency = EQNB_5BandPresetsFrequencies[i];
BandDefs[i].QFactor = EQNB_5BandPresetsQFactors[i];
BandDefs[i].Gain =
EQNB_5BandSoftPresets[(FIVEBAND_NUMBANDS * eqPresetLevel) + i];
}
+ params->EQNB_OperatingMode = plvmConfigParams->eqEnable;
+ // Caution: raw pointer to stack data, stored in instance by LVM_SetControlParameters.
+ params->pEQNB_BandDefinition = &BandDefs[0];
/* Volume Control parameters */
params->VC_EffectLevel = 0;
@@ -490,16 +543,6 @@
/* Bass Enhancement parameters */
params->BE_OperatingMode = plvmConfigParams->bassEnable;
- if (nrChannels == 1) {
- params->SourceFormat = LVM_MONO;
- }
- if (nrChannels == 2) {
- params->SourceFormat = LVM_STEREO;
- }
- if ((nrChannels > 2) && (nrChannels <= 8)) {
- params->SourceFormat = LVM_MULTICHANNEL;
- }
-
/* Activate the initial settings */
LvmStatus =
LVM_SetControlParameters(pContext->pBundledContext->hInstance, params);
@@ -613,7 +656,9 @@
samplingFreq != 12000 && samplingFreq != 16000 &&
samplingFreq != 22050 && samplingFreq != 24000 &&
samplingFreq != 32000 && samplingFreq != 44100 &&
- samplingFreq != 48000 && samplingFreq != 96000) {
+ samplingFreq != 48000 && samplingFreq != 88200 &&
+ samplingFreq != 96000 && samplingFreq != 176400 &&
+ samplingFreq != 192000) {
ALOGE("\nError: Unsupported Sampling Frequency : %d\n", samplingFreq);
return -1;
}
diff --git a/media/libeffects/lvm/wrapper/Bundle/EffectBundle.cpp b/media/libeffects/lvm/wrapper/Bundle/EffectBundle.cpp
index 09e9964..b5860de 100644
--- a/media/libeffects/lvm/wrapper/Bundle/EffectBundle.cpp
+++ b/media/libeffects/lvm/wrapper/Bundle/EffectBundle.cpp
@@ -1275,10 +1275,18 @@
pContext->pBundledContext->SamplesPerSecond = 48000 * NrChannels;
break;
#if defined(BUILD_FLOAT) && defined(HIGHER_FS)
+ case 88200:
+ SampleRate = LVM_FS_88200;
+ pContext->pBundledContext->SamplesPerSecond = 88200 * NrChannels;
+ break;
case 96000:
SampleRate = LVM_FS_96000;
pContext->pBundledContext->SamplesPerSecond = 96000 * NrChannels;
break;
+ case 176400:
+ SampleRate = LVM_FS_176400;
+ pContext->pBundledContext->SamplesPerSecond = 176400 * NrChannels;
+ break;
case 192000:
SampleRate = LVM_FS_192000;
pContext->pBundledContext->SamplesPerSecond = 192000 * NrChannels;
diff --git a/media/libeffects/lvm/wrapper/Reverb/EffectReverb.cpp b/media/libeffects/lvm/wrapper/Reverb/EffectReverb.cpp
index d558169..602f607 100644
--- a/media/libeffects/lvm/wrapper/Reverb/EffectReverb.cpp
+++ b/media/libeffects/lvm/wrapper/Reverb/EffectReverb.cpp
@@ -675,9 +675,15 @@
SampleRate = LVM_FS_48000;
break;
#if defined(BUILD_FLOAT) && defined(HIGHER_FS)
+ case 88200:
+ SampleRate = LVM_FS_88200;
+ break;
case 96000:
SampleRate = LVM_FS_96000;
break;
+ case 176400:
+ SampleRate = LVM_FS_176400;
+ break;
case 192000:
SampleRate = LVM_FS_192000;
break;
diff --git a/media/libmedia/TypeConverter.cpp b/media/libmedia/TypeConverter.cpp
index fb861d7..b5a7172 100644
--- a/media/libmedia/TypeConverter.cpp
+++ b/media/libmedia/TypeConverter.cpp
@@ -285,6 +285,7 @@
template <>
const StreamTypeConverter::Table StreamTypeConverter::mTable[] = {
+ MAKE_STRING_FROM_ENUM(AUDIO_STREAM_DEFAULT),
MAKE_STRING_FROM_ENUM(AUDIO_STREAM_VOICE_CALL),
MAKE_STRING_FROM_ENUM(AUDIO_STREAM_SYSTEM),
MAKE_STRING_FROM_ENUM(AUDIO_STREAM_RING),
@@ -361,6 +362,22 @@
TERMINATOR
};
+template <>
+const AudioFlagConverter::Table AudioFlagConverter::mTable[] = {
+ MAKE_STRING_FROM_ENUM(AUDIO_FLAG_NONE),
+ MAKE_STRING_FROM_ENUM(AUDIO_FLAG_AUDIBILITY_ENFORCED),
+ MAKE_STRING_FROM_ENUM(AUDIO_FLAG_SECURE),
+ MAKE_STRING_FROM_ENUM(AUDIO_FLAG_SCO),
+ MAKE_STRING_FROM_ENUM(AUDIO_FLAG_BEACON),
+ MAKE_STRING_FROM_ENUM(AUDIO_FLAG_HW_AV_SYNC),
+ MAKE_STRING_FROM_ENUM(AUDIO_FLAG_HW_HOTWORD),
+ MAKE_STRING_FROM_ENUM(AUDIO_FLAG_BYPASS_INTERRUPTION_POLICY),
+ MAKE_STRING_FROM_ENUM(AUDIO_FLAG_BYPASS_MUTE),
+ MAKE_STRING_FROM_ENUM(AUDIO_FLAG_LOW_LATENCY),
+ MAKE_STRING_FROM_ENUM(AUDIO_FLAG_DEEP_BUFFER),
+ TERMINATOR
+};
+
template class TypeConverter<OutputDeviceTraits>;
template class TypeConverter<InputDeviceTraits>;
template class TypeConverter<OutputFlagTraits>;
@@ -374,6 +391,7 @@
template class TypeConverter<AudioModeTraits>;
template class TypeConverter<UsageTraits>;
template class TypeConverter<SourceTraits>;
+template class TypeConverter<AudioFlagTraits>;
bool deviceFromString(const std::string& literalDevice, audio_devices_t& device) {
return InputDeviceConverter::fromString(literalDevice, device) ||
diff --git a/media/libmedia/include/media/TypeConverter.h b/media/libmedia/include/media/TypeConverter.h
index 86f0d4c..418e09c 100644
--- a/media/libmedia/include/media/TypeConverter.h
+++ b/media/libmedia/include/media/TypeConverter.h
@@ -20,6 +20,7 @@
#include <string>
#include <string.h>
+#include <vector>
#include <system/audio.h>
#include <utils/Log.h>
#include <utils/Vector.h>
@@ -30,77 +31,55 @@
namespace android {
-struct SampleRateTraits
-{
- typedef uint32_t Type;
- typedef SortedVector<Type> Collection;
-};
-struct DeviceTraits
-{
- typedef audio_devices_t Type;
- typedef Vector<Type> Collection;
-};
-struct OutputDeviceTraits : public DeviceTraits {};
-struct InputDeviceTraits : public DeviceTraits {};
-struct OutputFlagTraits
-{
- typedef audio_output_flags_t Type;
- typedef Vector<Type> Collection;
-};
-struct InputFlagTraits
-{
- typedef audio_input_flags_t Type;
- typedef Vector<Type> Collection;
-};
-struct FormatTraits
-{
- typedef audio_format_t Type;
- typedef Vector<Type> Collection;
-};
-struct ChannelTraits
-{
- typedef audio_channel_mask_t Type;
- typedef SortedVector<Type> Collection;
-};
-struct OutputChannelTraits : public ChannelTraits {};
-struct InputChannelTraits : public ChannelTraits {};
-struct ChannelIndexTraits : public ChannelTraits {};
-struct GainModeTraits
-{
- typedef audio_gain_mode_t Type;
- typedef Vector<Type> Collection;
-};
-struct StreamTraits
-{
- typedef audio_stream_type_t Type;
- typedef Vector<Type> Collection;
-};
-struct AudioModeTraits
-{
- typedef audio_mode_t Type;
- typedef Vector<Type> Collection;
-};
-struct AudioContentTraits
-{
- typedef audio_content_type_t Type;
- typedef Vector<Type> Collection;
-};
-struct UsageTraits
-{
- typedef audio_usage_t Type;
- typedef Vector<Type> Collection;
-};
-struct SourceTraits
-{
- typedef audio_source_t Type;
- typedef Vector<Type> Collection;
-};
template <typename T>
struct DefaultTraits
{
typedef T Type;
- typedef Vector<Type> Collection;
+ typedef std::vector<Type> Collection;
+ static void add(Collection &collection, Type value)
+ {
+ collection.push_back(value);
+ }
};
+template <typename T>
+struct VectorTraits
+{
+ typedef T Type;
+ typedef Vector<Type> Collection;
+ static void add(Collection &collection, Type value)
+ {
+ collection.add(value);
+ }
+};
+template <typename T>
+struct SortedVectorTraits
+{
+ typedef T Type;
+ typedef SortedVector<Type> Collection;
+ static void add(Collection &collection, Type value)
+ {
+ collection.add(value);
+ }
+};
+
+using SampleRateTraits = SortedVectorTraits<uint32_t>;
+using DeviceTraits = DefaultTraits<audio_devices_t>;
+struct OutputDeviceTraits : public DeviceTraits {};
+struct InputDeviceTraits : public DeviceTraits {};
+using ChannelTraits = SortedVectorTraits<audio_channel_mask_t>;
+struct OutputChannelTraits : public ChannelTraits {};
+struct InputChannelTraits : public ChannelTraits {};
+struct ChannelIndexTraits : public ChannelTraits {};
+using InputFlagTraits = DefaultTraits<audio_input_flags_t>;
+using OutputFlagTraits = DefaultTraits<audio_output_flags_t>;
+using FormatTraits = VectorTraits<audio_format_t>;
+using GainModeTraits = DefaultTraits<audio_gain_mode_t>;
+using StreamTraits = DefaultTraits<audio_stream_type_t>;
+using AudioModeTraits = DefaultTraits<audio_mode_t>;
+using AudioContentTraits = DefaultTraits<audio_content_type_t>;
+using UsageTraits = DefaultTraits<audio_usage_t>;
+using SourceTraits = DefaultTraits<audio_source_t>;
+struct AudioFlagTraits : public DefaultTraits<audio_flags_mask_t> {};
template <class Traits>
static void collectionFromString(const std::string &str, typename Traits::Collection &collection,
@@ -110,7 +89,7 @@
for (const char *cstr = strtok(literal, del); cstr != NULL; cstr = strtok(NULL, del)) {
typename Traits::Type value;
if (utilities::convertTo<std::string, typename Traits::Type >(cstr, value)) {
- collection.add(value);
+ Traits::add(collection, value);
}
}
free(literal);
@@ -181,7 +160,7 @@
for (const char *cstr = strtok(literal, del); cstr != NULL; cstr = strtok(NULL, del)) {
typename Traits::Type value;
if (fromString(cstr, value)) {
- collection.add(value);
+ Traits::add(collection, value);
}
}
free(literal);
@@ -234,6 +213,7 @@
typedef TypeConverter<AudioContentTraits> AudioContentTypeConverter;
typedef TypeConverter<UsageTraits> UsageTypeConverter;
typedef TypeConverter<SourceTraits> SourceTypeConverter;
+typedef TypeConverter<AudioFlagTraits> AudioFlagConverter;
template<> const OutputDeviceConverter::Table OutputDeviceConverter::mTable[];
template<> const InputDeviceConverter::Table InputDeviceConverter::mTable[];
@@ -249,6 +229,7 @@
template<> const AudioContentTypeConverter::Table AudioContentTypeConverter::mTable[];
template<> const UsageTypeConverter::Table UsageTypeConverter::mTable[];
template<> const SourceTypeConverter::Table SourceTypeConverter::mTable[];
+template<> const AudioFlagConverter::Table AudioFlagConverter::mTable[];
bool deviceFromString(const std::string& literalDevice, audio_devices_t& device);
@@ -274,6 +255,69 @@
OutputChannelTraits::Collection outputChannelMasksFromString(
const std::string &outChannels, const char *del = AudioParameter::valueListSeparator);
+static inline std::string toString(audio_usage_t usage)
+{
+ std::string usageLiteral;
+ if (!android::UsageTypeConverter::toString(usage, usageLiteral)) {
+ ALOGV("failed to convert usage: %d", usage);
+ return "AUDIO_USAGE_UNKNOWN";
+ }
+ return usageLiteral;
+}
+
+static inline std::string toString(audio_content_type_t content)
+{
+ std::string contentLiteral;
+ if (!android::AudioContentTypeConverter::toString(content, contentLiteral)) {
+ ALOGV("failed to convert content type: %d", content);
+ return "AUDIO_CONTENT_TYPE_UNKNOWN";
+ }
+ return contentLiteral;
+}
+
+static inline std::string toString(audio_stream_type_t stream)
+{
+ std::string streamLiteral;
+ if (!android::StreamTypeConverter::toString(stream, streamLiteral)) {
+ ALOGV("failed to convert stream: %d", stream);
+ return "AUDIO_STREAM_DEFAULT";
+ }
+ return streamLiteral;
+}
+
+static inline std::string toString(audio_source_t source)
+{
+ std::string sourceLiteral;
+ if (!android::SourceTypeConverter::toString(source, sourceLiteral)) {
+ ALOGV("failed to convert source: %d", source);
+ return "AUDIO_SOURCE_DEFAULT";
+ }
+ return sourceLiteral;
+}
+
+static inline std::string toString(const audio_attributes_t &attributes)
+{
+ std::ostringstream result;
+ result << "{ Content type: " << toString(attributes.content_type)
+ << " Usage: " << toString(attributes.usage)
+ << " Source: " << toString(attributes.source)
+ << " Flags: " << attributes.flags
+ << " Tags: " << attributes.tags
+ << " }";
+
+ return result.str();
+}
+
+static inline std::string toString(audio_mode_t mode)
+{
+ std::string modeLiteral;
+ if (!android::AudioModeConverter::toString(mode, modeLiteral)) {
+ ALOGV("failed to convert mode: %d", mode);
+ return "AUDIO_MODE_INVALID";
+ }
+ return modeLiteral;
+}
+
}; // namespace android
#endif /*ANDROID_TYPE_CONVERTER_H_*/
diff --git a/media/libmediaextractor/Android.bp b/media/libmediaextractor/Android.bp
index 6f2b35f..1aa1e13 100644
--- a/media/libmediaextractor/Android.bp
+++ b/media/libmediaextractor/Android.bp
@@ -14,6 +14,15 @@
"-Wall",
],
+ static: {
+ cflags: [
+ "-Wno-multichar",
+ "-Werror",
+ "-Wall",
+ "-DNO_IMEMORY",
+ ],
+ },
+
shared_libs: [
"libbinder",
"libstagefright_foundation",
diff --git a/media/libmediaextractor/MediaBuffer.cpp b/media/libmediaextractor/MediaBuffer.cpp
index 26d0bd4..bab3a03 100644
--- a/media/libmediaextractor/MediaBuffer.cpp
+++ b/media/libmediaextractor/MediaBuffer.cpp
@@ -51,9 +51,12 @@
mRangeLength(size),
mOwnsData(true),
mMetaData(new MetaDataBase) {
+#ifndef NO_IMEMORY
if (size < kSharedMemThreshold
|| std::atomic_load_explicit(&mUseSharedMemory, std::memory_order_seq_cst) == 0) {
+#endif
mData = malloc(size);
+#ifndef NO_IMEMORY
} else {
ALOGV("creating memoryDealer");
sp<MemoryDealer> memoryDealer =
@@ -71,6 +74,7 @@
ALOGV("Allocated shared mem buffer of size %zu @ %p", size, mData);
}
}
+#endif
}
MediaBuffer::MediaBuffer(const sp<ABuffer> &buffer)
diff --git a/media/libmediaextractor/MediaBufferGroup.cpp b/media/libmediaextractor/MediaBufferGroup.cpp
index 4e6beca..e88ed5a 100644
--- a/media/libmediaextractor/MediaBufferGroup.cpp
+++ b/media/libmediaextractor/MediaBufferGroup.cpp
@@ -62,6 +62,7 @@
mInternal->mGrowthLimit = buffers;
}
+#ifndef NO_IMEMORY
if (buffer_size >= kSharedMemoryThreshold) {
ALOGD("creating MemoryDealer");
// Using a single MemoryDealer is efficient for a group of shared memory objects.
@@ -84,6 +85,9 @@
}
return;
}
+#else
+ (void)kSharedMemoryThreshold;
+#endif
// Non-shared memory allocation.
for (size_t i = 0; i < buffers; ++i) {
diff --git a/media/libmediaextractor/include/media/stagefright/MediaBuffer.h b/media/libmediaextractor/include/media/stagefright/MediaBuffer.h
index 5b362a4..ace63ae 100644
--- a/media/libmediaextractor/include/media/stagefright/MediaBuffer.h
+++ b/media/libmediaextractor/include/media/stagefright/MediaBuffer.h
@@ -46,12 +46,13 @@
explicit MediaBuffer(size_t size);
explicit MediaBuffer(const sp<ABuffer> &buffer);
-
+#ifndef NO_IMEMORY
MediaBuffer(const sp<IMemory> &mem) :
MediaBuffer((uint8_t *)mem->pointer() + sizeof(SharedControl), mem->size()) {
// delegate and override mMemory
mMemory = mem;
}
+#endif
// If MediaBufferGroup is set, decrement the local reference count;
// if the local reference count drops to 0, return the buffer to the
@@ -92,17 +93,26 @@
}
virtual int remoteRefcount() const {
+#ifndef NO_IMEMORY
if (mMemory.get() == nullptr || mMemory->pointer() == nullptr) return 0;
int32_t remoteRefcount =
reinterpret_cast<SharedControl *>(mMemory->pointer())->getRemoteRefcount();
// Sanity check so that remoteRefCount() is non-negative.
return remoteRefcount >= 0 ? remoteRefcount : 0; // do not allow corrupted data.
+#else
+ return 0;
+#endif
}
// returns old value
int addRemoteRefcount(int32_t value) {
+#ifndef NO_IMEMORY
if (mMemory.get() == nullptr || mMemory->pointer() == nullptr) return 0;
return reinterpret_cast<SharedControl *>(mMemory->pointer())->addRemoteRefcount(value);
+#else
+ (void) value;
+ return 0;
+#endif
}
bool isDeadObject() const {
@@ -110,8 +120,13 @@
}
static bool isDeadObject(const sp<IMemory> &memory) {
+#ifndef NO_IMEMORY
if (memory.get() == nullptr || memory->pointer() == nullptr) return false;
return reinterpret_cast<SharedControl *>(memory->pointer())->isDeadObject();
+#else
+ (void) memory;
+ return false;
+#endif
}
// Sticky on enabling of shared memory MediaBuffers. By default we don't use
@@ -204,7 +219,11 @@
};
inline SharedControl *getSharedControl() const {
+#ifndef NO_IMEMORY
return reinterpret_cast<SharedControl *>(mMemory->pointer());
+#else
+ return nullptr;
+#endif
}
};
diff --git a/media/libmediaextractor/include/media/stagefright/MediaBufferBase.h b/media/libmediaextractor/include/media/stagefright/MediaBufferBase.h
index eb49f4c..3682368 100644
--- a/media/libmediaextractor/include/media/stagefright/MediaBufferBase.h
+++ b/media/libmediaextractor/include/media/stagefright/MediaBufferBase.h
@@ -96,6 +96,14 @@
return ((MediaBufferBase*)handle)->size();
};
+ mWrapper->range_offset = [](void *handle) -> size_t {
+ return ((MediaBufferBase*)handle)->range_offset();
+ };
+
+ mWrapper->range_length = [](void *handle) -> size_t {
+ return ((MediaBufferBase*)handle)->range_length();
+ };
+
mWrapper->set_range = [](void *handle, size_t offset, size_t length) -> void {
return ((MediaBufferBase*)handle)->set_range(offset, length);
};
diff --git a/media/libmediaplayer2/include/mediaplayer2/mediaplayer2.h b/media/libmediaplayer2/include/mediaplayer2/mediaplayer2.h
index c7cd7d2..a945ffd 100644
--- a/media/libmediaplayer2/include/mediaplayer2/mediaplayer2.h
+++ b/media/libmediaplayer2/include/mediaplayer2/mediaplayer2.h
@@ -86,7 +86,7 @@
MediaPlayer2SeekMode mode = MediaPlayer2SeekMode::SEEK_PREVIOUS_SYNC);
status_t notifyAt(int64_t mediaTimeUs);
status_t getCurrentPosition(int64_t *msec);
- status_t getDuration(int64_t *msec);
+ status_t getDuration(int64_t srcId, int64_t *msec);
status_t reset();
status_t setAudioStreamType(audio_stream_type_t type);
status_t getAudioStreamType(audio_stream_type_t *type);
diff --git a/media/libmediaplayer2/mediaplayer2.cpp b/media/libmediaplayer2/mediaplayer2.cpp
index 2ae5a8c..f432059 100644
--- a/media/libmediaplayer2/mediaplayer2.cpp
+++ b/media/libmediaplayer2/mediaplayer2.cpp
@@ -718,8 +718,15 @@
return ret;
}
-status_t MediaPlayer2::getDuration(int64_t *msec) {
+status_t MediaPlayer2::getDuration(int64_t srcId, int64_t *msec) {
Mutex::Autolock _l(mLock);
+ // TODO: cache duration for currentSrcId and nextSrcId, and return correct
+ // value for nextSrcId.
+ if (srcId != mSrcId) {
+ *msec = -1;
+ return OK;
+ }
+
ALOGV("getDuration_l");
bool isValidState = (mCurrentState & (MEDIA_PLAYER2_PREPARED | MEDIA_PLAYER2_STARTED |
MEDIA_PLAYER2_PAUSED | MEDIA_PLAYER2_PLAYBACK_COMPLETE));
diff --git a/media/libmediaplayer2/nuplayer2/NuPlayer2.cpp b/media/libmediaplayer2/nuplayer2/NuPlayer2.cpp
index 81ffbc7..080d923 100644
--- a/media/libmediaplayer2/nuplayer2/NuPlayer2.cpp
+++ b/media/libmediaplayer2/nuplayer2/NuPlayer2.cpp
@@ -791,9 +791,13 @@
sp<AReplyToken> replyID;
CHECK(msg->senderAwaitsResponse(&replyID));
+ int64_t srcId;
+ CHECK(msg->findInt64("srcId", (int64_t*)&srcId));
+
PlayerMessage* reply;
CHECK(msg->findPointer("reply", (void**)&reply));
+ // TODO: use correct source info based on srcId.
size_t inbandTracks = 0;
if (mCurrentSourceInfo.mSource != NULL) {
inbandTracks = mCurrentSourceInfo.mSource->getTrackCount();
@@ -824,10 +828,14 @@
case kWhatGetSelectedTrack:
{
+ int64_t srcId;
+ CHECK(msg->findInt64("srcId", (int64_t*)&srcId));
+
int32_t type32;
CHECK(msg->findInt32("type", (int32_t*)&type32));
media_track_type type = (media_track_type)type32;
+ // TODO: use correct source info based on srcId.
size_t inbandTracks = 0;
status_t err = INVALID_OPERATION;
ssize_t selectedTrack = -1;
@@ -863,15 +871,18 @@
sp<AReplyToken> replyID;
CHECK(msg->senderAwaitsResponse(&replyID));
+ int64_t srcId;
size_t trackIndex;
int32_t select;
int64_t timeUs;
+ CHECK(msg->findInt64("srcId", (int64_t*)&srcId));
CHECK(msg->findSize("trackIndex", &trackIndex));
CHECK(msg->findInt32("select", &select));
CHECK(msg->findInt64("timeUs", &timeUs));
status_t err = INVALID_OPERATION;
+ // TODO: use correct source info based on srcId.
size_t inbandTracks = 0;
if (mCurrentSourceInfo.mSource != NULL) {
inbandTracks = mCurrentSourceInfo.mSource->getTrackCount();
@@ -2324,8 +2335,9 @@
return OK;
}
-status_t NuPlayer2::getTrackInfo(PlayerMessage* reply) const {
+status_t NuPlayer2::getTrackInfo(int64_t srcId, PlayerMessage* reply) const {
sp<AMessage> msg = new AMessage(kWhatGetTrackInfo, this);
+ msg->setInt64("srcId", srcId);
msg->setPointer("reply", reply);
sp<AMessage> response;
@@ -2333,9 +2345,10 @@
return err;
}
-status_t NuPlayer2::getSelectedTrack(int32_t type, PlayerMessage* reply) const {
+status_t NuPlayer2::getSelectedTrack(int64_t srcId, int32_t type, PlayerMessage* reply) const {
sp<AMessage> msg = new AMessage(kWhatGetSelectedTrack, this);
msg->setPointer("reply", reply);
+ msg->setInt64("srcId", srcId);
msg->setInt32("type", type);
sp<AMessage> response;
@@ -2346,8 +2359,9 @@
return err;
}
-status_t NuPlayer2::selectTrack(size_t trackIndex, bool select, int64_t timeUs) {
+status_t NuPlayer2::selectTrack(int64_t srcId, size_t trackIndex, bool select, int64_t timeUs) {
sp<AMessage> msg = new AMessage(kWhatSelectTrack, this);
+ msg->setInt64("srcId", srcId);
msg->setSize("trackIndex", trackIndex);
msg->setInt32("select", select);
msg->setInt64("timeUs", timeUs);
diff --git a/media/libmediaplayer2/nuplayer2/NuPlayer2.h b/media/libmediaplayer2/nuplayer2/NuPlayer2.h
index e9b5f11..fdc128f 100644
--- a/media/libmediaplayer2/nuplayer2/NuPlayer2.h
+++ b/media/libmediaplayer2/nuplayer2/NuPlayer2.h
@@ -82,9 +82,9 @@
void rewind();
status_t setVideoScalingMode(int32_t mode);
- status_t getTrackInfo(PlayerMessage* reply) const;
- status_t getSelectedTrack(int32_t type, PlayerMessage* reply) const;
- status_t selectTrack(size_t trackIndex, bool select, int64_t timeUs);
+ status_t getTrackInfo(int64_t srcId, PlayerMessage* reply) const;
+ status_t getSelectedTrack(int64_t srcId, int32_t type, PlayerMessage* reply) const;
+ status_t selectTrack(int64_t srcId, size_t trackIndex, bool select, int64_t timeUs);
status_t getCurrentPosition(int64_t *mediaUs);
void getStats(Vector<sp<AMessage> > *mTrackStats);
diff --git a/media/libmediaplayer2/nuplayer2/NuPlayer2Driver.cpp b/media/libmediaplayer2/nuplayer2/NuPlayer2Driver.cpp
index 56d708a..2dab2dd 100644
--- a/media/libmediaplayer2/nuplayer2/NuPlayer2Driver.cpp
+++ b/media/libmediaplayer2/nuplayer2/NuPlayer2Driver.cpp
@@ -603,28 +603,33 @@
case MEDIA_PLAYER2_INVOKE_ID_GET_TRACK_INFO:
{
- return mPlayer->getTrackInfo(response);
+ int64_t srcId = (it++)->int64_value();
+ return mPlayer->getTrackInfo(srcId, response);
}
case MEDIA_PLAYER2_INVOKE_ID_SELECT_TRACK:
{
+ int64_t srcId = (it++)->int64_value();
int trackIndex = (it++)->int32_value();
int64_t msec = 0;
// getCurrentPosition should always return OK
getCurrentPosition(&msec);
- return mPlayer->selectTrack(trackIndex, true /* select */, msec * 1000LL);
+ return mPlayer->selectTrack(srcId, trackIndex, true /* select */, msec * 1000LL);
}
case MEDIA_PLAYER2_INVOKE_ID_UNSELECT_TRACK:
{
+ int64_t srcId = (it++)->int64_value();
int trackIndex = (it++)->int32_value();
- return mPlayer->selectTrack(trackIndex, false /* select */, 0xdeadbeef /* not used */);
+ return mPlayer->selectTrack(
+ srcId, trackIndex, false /* select */, 0xdeadbeef /* not used */);
}
case MEDIA_PLAYER2_INVOKE_ID_GET_SELECTED_TRACK:
{
+ int64_t srcId = (it++)->int64_value();
int32_t type = (it++)->int32_value();
- return mPlayer->getSelectedTrack(type, response);
+ return mPlayer->getSelectedTrack(srcId, type, response);
}
default:
diff --git a/media/libstagefright/Android.bp b/media/libstagefright/Android.bp
index 9aea88a..dec5d3b 100644
--- a/media/libstagefright/Android.bp
+++ b/media/libstagefright/Android.bp
@@ -77,7 +77,7 @@
},
}
-cc_library_shared {
+cc_library {
name: "libstagefright",
srcs: [
diff --git a/media/libstagefright/MPEG4Writer.cpp b/media/libstagefright/MPEG4Writer.cpp
index 6ff3d78..a48466a 100644
--- a/media/libstagefright/MPEG4Writer.cpp
+++ b/media/libstagefright/MPEG4Writer.cpp
@@ -3674,6 +3674,29 @@
TRESPASS();
}
mOwner->beginBox(fourcc); // TextMetaDataSampleEntry
+
+ // HACK to make the metadata track compliant with the ISO standard.
+ //
+ // Metadata track is added from API 26 and the original implementation does not
+ // fully followed the TextMetaDataSampleEntry specified in ISO/IEC 14496-12-2015
+ // in that only the mime_format is written out. content_encoding and
+ // data_reference_index have not been written out. This leads to the failure
+ // when some MP4 parser tries to parse the metadata track according to the
+ // standard. The hack here will make the metadata track compliant with the
+ // standard while still maintaining backwards compatibility. This would enable
+ // Android versions before API 29 to be able to read out the standard compliant
+ // Metadata track generated with Android API 29 and upward. The trick is based
+ // on the fact that the Metadata track must start with prefix “application/” and
+ // those missing fields are not used in Android's Metadata track. By writting
+ // out the mime_format twice, the first mime_format will be used to fill out the
+ // missing reserved, data_reference_index and content encoding fields. On the
+ // parser side, the extracter before API 29 will read out the first mime_format
+ // correctly and drop the second mime_format. The extractor from API 29 will
+ // check if the reserved, data_reference_index and content encoding are filled
+ // with “application” to detect if this is a standard compliant metadata track
+ // and read out the data accordingly.
+ mOwner->writeCString(mime);
+
mOwner->writeCString(mime); // metadata mime_format
mOwner->endBox(); // mett
}
diff --git a/media/libstagefright/MediaTrack.cpp b/media/libstagefright/MediaTrack.cpp
index 6c0f989..1e49f6a 100644
--- a/media/libstagefright/MediaTrack.cpp
+++ b/media/libstagefright/MediaTrack.cpp
@@ -16,6 +16,7 @@
#include <mutex>
+#include <media/stagefright/foundation/ABuffer.h>
#include <media/stagefright/foundation/AMessage.h>
#include <media/stagefright/Utils.h>
@@ -216,10 +217,58 @@
if (format->mFormat->findInt64("timeUs", &val64)) {
meta.setInt64(kKeyTime, val64);
}
+ if (format->mFormat->findInt64("duration", &val64)) {
+ meta.setInt64(kKeyDuration, val64);
+ }
+ if (format->mFormat->findInt64("target-time", &val64)) {
+ meta.setInt64(kKeyTargetTime, val64);
+ }
int32_t val32;
if (format->mFormat->findInt32("is-sync-frame", &val32)) {
meta.setInt32(kKeyIsSyncFrame, val32);
}
+ if (format->mFormat->findInt32("temporal-layer-id", &val32)) {
+ meta.setInt32(kKeyTemporalLayerId, val32);
+ }
+ if (format->mFormat->findInt32("temporal-layer-count", &val32)) {
+ meta.setInt32(kKeyTemporalLayerCount, val32);
+ }
+ if (format->mFormat->findInt32("crypto-default-iv-size", &val32)) {
+ meta.setInt32(kKeyCryptoDefaultIVSize, val32);
+ }
+ if (format->mFormat->findInt32("crypto-mode", &val32)) {
+ meta.setInt32(kKeyCryptoMode, val32);
+ }
+ if (format->mFormat->findInt32("crypto-encrypted-byte-block", &val32)) {
+ meta.setInt32(kKeyEncryptedByteBlock, val32);
+ }
+ if (format->mFormat->findInt32("crypto-skip-byte-block", &val32)) {
+ meta.setInt32(kKeySkipByteBlock, val32);
+ }
+ if (format->mFormat->findInt32("valid-samples", &val32)) {
+ meta.setInt32(kKeyValidSamples, val32);
+ }
+ sp<ABuffer> valbuf;
+ if (format->mFormat->findBuffer("crypto-plain-sizes", &valbuf)) {
+ meta.setData(kKeyPlainSizes,
+ MetaDataBase::Type::TYPE_NONE, valbuf->data(), valbuf->size());
+ }
+ if (format->mFormat->findBuffer("crypto-encrypted-sizes", &valbuf)) {
+ meta.setData(kKeyEncryptedSizes,
+ MetaDataBase::Type::TYPE_NONE, valbuf->data(), valbuf->size());
+ }
+ if (format->mFormat->findBuffer("crypto-key", &valbuf)) {
+ meta.setData(kKeyCryptoKey,
+ MetaDataBase::Type::TYPE_NONE, valbuf->data(), valbuf->size());
+ }
+ if (format->mFormat->findBuffer("crypto-iv", &valbuf)) {
+ meta.setData(kKeyCryptoIV,
+ MetaDataBase::Type::TYPE_NONE, valbuf->data(), valbuf->size());
+ }
+ if (format->mFormat->findBuffer("sei", &valbuf)) {
+ meta.setData(kKeySEI,
+ MetaDataBase::Type::TYPE_NONE, valbuf->data(), valbuf->size());
+ }
} else {
*buffer = nullptr;
}
diff --git a/media/libstagefright/Utils.cpp b/media/libstagefright/Utils.cpp
index 670b607..8f2427e 100644
--- a/media/libstagefright/Utils.cpp
+++ b/media/libstagefright/Utils.cpp
@@ -598,7 +598,10 @@
{
{ "exif-offset", kKeyExifOffset },
{ "exif-size", kKeyExifSize },
+ { "target-time", kKeyTargetTime },
{ "thumbnail-time", kKeyThumbnailTime },
+ { "timeUs", kKeyTime },
+ { "durationUs", kKeyDuration },
}
};
@@ -610,12 +613,14 @@
{ "crypto-default-iv-size", kKeyCryptoDefaultIVSize },
{ "crypto-encrypted-byte-block", kKeyEncryptedByteBlock },
{ "crypto-skip-byte-block", kKeySkipByteBlock },
+ { "frame-count", kKeyFrameCount },
{ "max-bitrate", kKeyMaxBitRate },
{ "pcm-big-endian", kKeyPcmBigEndian },
{ "temporal-layer-count", kKeyTemporalLayerCount },
+ { "temporal-layer-id", kKeyTemporalLayerId },
{ "thumbnail-width", kKeyThumbnailWidth },
{ "thumbnail-height", kKeyThumbnailHeight },
- { "frame-count", kKeyFrameCount },
+ { "valid-samples", kKeyValidSamples },
}
};
@@ -626,7 +631,10 @@
{ "pssh", kKeyPssh },
{ "crypto-iv", kKeyCryptoIV },
{ "crypto-key", kKeyCryptoKey },
+ { "crypto-encrypted-sizes", kKeyEncryptedSizes },
+ { "crypto-plain-sizes", kKeyPlainSizes },
{ "icc-profile", kKeyIccProfile },
+ { "sei", kKeySEI },
{ "text-format-data", kKeyTextFormatData },
}
};
diff --git a/media/libstagefright/httplive/Android.bp b/media/libstagefright/httplive/Android.bp
index 78d410a..c4a072b 100644
--- a/media/libstagefright/httplive/Android.bp
+++ b/media/libstagefright/httplive/Android.bp
@@ -29,7 +29,6 @@
shared_libs: [
"liblog",
- "libbinder",
"libcrypto",
"libcutils",
"libmedia",
@@ -38,10 +37,11 @@
"libstagefright",
"libstagefright_foundation",
"libutils",
- "libhidlallocatorutils",
"libhidlbase",
+ "libhidlmemory",
"android.hardware.cas@1.0",
"android.hardware.cas.native@1.0",
+ "android.hidl.allocator@1.0",
],
header_libs: [
diff --git a/media/libstagefright/mpeg2ts/ATSParser.cpp b/media/libstagefright/mpeg2ts/ATSParser.cpp
index 590131e..e9baa1a 100644
--- a/media/libstagefright/mpeg2ts/ATSParser.cpp
+++ b/media/libstagefright/mpeg2ts/ATSParser.cpp
@@ -23,10 +23,10 @@
#include "ESQueue.h"
#include <android/hardware/cas/native/1.0/IDescrambler.h>
-#include <binder/IMemory.h>
-#include <binder/MemoryDealer.h>
+#include <android/hidl/allocator/1.0/IAllocator.h>
+#include <android/hidl/memory/1.0/IMemory.h>
#include <cutils/native_handle.h>
-#include <hidlmemory/FrameworkUtils.h>
+#include <hidlmemory/mapping.h>
#include <media/cas/DescramblerAPI.h>
#include <media/stagefright/foundation/ABitReader.h>
#include <media/stagefright/foundation/ABuffer.h>
@@ -46,12 +46,13 @@
#include <inttypes.h>
namespace android {
-using hardware::fromHeap;
using hardware::hidl_string;
using hardware::hidl_vec;
-using hardware::HidlMemory;
+using hardware::hidl_memory;
using namespace hardware::cas::V1_0;
using namespace hardware::cas::native::V1_0;
+typedef hidl::allocator::V1_0::IAllocator TAllocator;
+typedef hidl::memory::V1_0::IMemory TMemory;
// I want the expression "y" evaluated even if verbose logging is off.
#define MY_LOGV(x, y) \
@@ -208,9 +209,8 @@
bool mScrambled;
bool mSampleEncrypted;
sp<AMessage> mSampleAesKeyItem;
- sp<IMemory> mMem;
- sp<MemoryDealer> mDealer;
- sp<HidlMemory> mHidlMemory;
+ sp<TMemory> mHidlMemory;
+ sp<TAllocator> mHidlAllocator;
hardware::cas::native::V1_0::SharedBuffer mDescramblerSrcBuffer;
sp<ABuffer> mDescrambledBuffer;
List<SubSampleInfo> mSubSamples;
@@ -975,16 +975,43 @@
mBuffer == NULL ? 0 : mBuffer->capacity(), neededSize, mScrambled);
sp<ABuffer> newBuffer, newScrambledBuffer;
- sp<IMemory> newMem;
- sp<MemoryDealer> newDealer;
+ sp<TMemory> newMem;
if (mScrambled) {
- size_t alignment = MemoryDealer::getAllocationAlignment();
- neededSize = (neededSize + (alignment - 1)) & ~(alignment - 1);
- // Align to multiples of 64K.
- neededSize = (neededSize + 65535) & ~65535;
- newDealer = new MemoryDealer(neededSize, "ATSParser");
- newMem = newDealer->allocate(neededSize);
- newScrambledBuffer = new ABuffer(newMem->pointer(), newMem->size());
+ if (mHidlAllocator == nullptr) {
+ mHidlAllocator = TAllocator::getService("ashmem");
+ if (mHidlAllocator == nullptr) {
+ ALOGE("[stream %d] can't get hidl allocator", mElementaryPID);
+ return false;
+ }
+ }
+
+ hidl_memory hidlMemToken;
+ bool success;
+ auto transStatus = mHidlAllocator->allocate(
+ neededSize,
+ [&success, &hidlMemToken](
+ bool s,
+ hidl_memory const& m) {
+ success = s;
+ hidlMemToken = m;
+ });
+
+ if (!transStatus.isOk()) {
+ ALOGE("[stream %d] hidl allocator failed at the transport: %s",
+ mElementaryPID, transStatus.description().c_str());
+ return false;
+ }
+ if (!success) {
+ ALOGE("[stream %d] hidl allocator failed", mElementaryPID);
+ return false;
+ }
+ newMem = mapMemory(hidlMemToken);
+ if (newMem == nullptr || newMem->getPointer() == nullptr) {
+ ALOGE("[stream %d] hidl failed to map memory", mElementaryPID);
+ return false;
+ }
+
+ newScrambledBuffer = new ABuffer(newMem->getPointer(), newMem->getSize());
if (mDescrambledBuffer != NULL) {
memcpy(newScrambledBuffer->data(),
@@ -993,24 +1020,15 @@
} else {
newScrambledBuffer->setRange(0, 0);
}
- mMem = newMem;
- mDealer = newDealer;
+ mHidlMemory = newMem;
mDescrambledBuffer = newScrambledBuffer;
- ssize_t offset;
- size_t size;
- sp<IMemoryHeap> heap = newMem->getMemory(&offset, &size);
- if (heap == NULL) {
- return false;
- }
+ mDescramblerSrcBuffer.heapBase = hidlMemToken;
+ mDescramblerSrcBuffer.offset = 0ULL;
+ mDescramblerSrcBuffer.size = (uint64_t)neededSize;
- mHidlMemory = fromHeap(heap);
- mDescramblerSrcBuffer.heapBase = *mHidlMemory;
- mDescramblerSrcBuffer.offset = (uint64_t) offset;
- mDescramblerSrcBuffer.size = (uint64_t) size;
-
- ALOGD("[stream %d] created shared buffer for descrambling, offset %zd, size %zu",
- mElementaryPID, offset, size);
+ ALOGD("[stream %d] created shared buffer for descrambling, size %zu",
+ mElementaryPID, neededSize);
} else {
// Align to multiples of 64K.
neededSize = (neededSize + 65535) & ~65535;
@@ -1498,7 +1516,7 @@
return UNKNOWN_ERROR;
}
- if (mDescrambledBuffer == NULL || mMem == NULL) {
+ if (mDescrambledBuffer == NULL || mHidlMemory == NULL) {
ALOGE("received scrambled packets without shared memory!");
return UNKNOWN_ERROR;
diff --git a/media/libstagefright/mpeg2ts/Android.bp b/media/libstagefright/mpeg2ts/Android.bp
index e516cf1..a507b91 100644
--- a/media/libstagefright/mpeg2ts/Android.bp
+++ b/media/libstagefright/mpeg2ts/Android.bp
@@ -30,9 +30,10 @@
shared_libs: [
"libcrypto",
"libmedia",
- "libhidlallocatorutils",
+ "libhidlmemory",
"android.hardware.cas.native@1.0",
"android.hidl.memory@1.0",
+ "android.hidl.allocator@1.0",
],
header_libs: [
diff --git a/media/ndk/NdkMediaFormat.cpp b/media/ndk/NdkMediaFormat.cpp
index e0af80d..92d3aef 100644
--- a/media/ndk/NdkMediaFormat.cpp
+++ b/media/ndk/NdkMediaFormat.cpp
@@ -294,9 +294,11 @@
EXPORT const char* AMEDIAFORMAT_KEY_COMPOSER = "composer";
EXPORT const char* AMEDIAFORMAT_KEY_CRYPTO_DEFAULT_IV_SIZE = "crypto-default-iv-size";
EXPORT const char* AMEDIAFORMAT_KEY_CRYPTO_ENCRYPTED_BYTE_BLOCK = "crypto-encrypted-byte-block";
+EXPORT const char* AMEDIAFORMAT_KEY_CRYPTO_ENCRYPTED_SIZES = "crypto-encrypted-sizes";
EXPORT const char* AMEDIAFORMAT_KEY_CRYPTO_IV = "crypto-iv";
EXPORT const char* AMEDIAFORMAT_KEY_CRYPTO_KEY = "crypto-key";
EXPORT const char* AMEDIAFORMAT_KEY_CRYPTO_MODE = "crypto-mode";
+EXPORT const char* AMEDIAFORMAT_KEY_CRYPTO_PLAIN_SIZES = "crypto-encrypted-sizes";
EXPORT const char* AMEDIAFORMAT_KEY_CRYPTO_SKIP_BYTE_BLOCK = "crypto-skip-byte-block";
EXPORT const char* AMEDIAFORMAT_KEY_CSD = "csd";
EXPORT const char* AMEDIAFORMAT_KEY_CSD_0 = "csd-0";
@@ -361,6 +363,7 @@
EXPORT const char* AMEDIAFORMAT_KEY_SEI = "sei";
EXPORT const char* AMEDIAFORMAT_KEY_SLICE_HEIGHT = "slice-height";
EXPORT const char* AMEDIAFORMAT_KEY_STRIDE = "stride";
+EXPORT const char* AMEDIAFORMAT_KEY_TARGET_TIME = "target-time";
EXPORT const char* AMEDIAFORMAT_KEY_TEMPORAL_LAYER_COUNT = "temporal-layer-count";
EXPORT const char* AMEDIAFORMAT_KEY_TEMPORAL_LAYER_ID = "temporal-layer-id";
EXPORT const char* AMEDIAFORMAT_KEY_TEMPORAL_LAYERING = "ts-schema";
@@ -374,6 +377,7 @@
EXPORT const char* AMEDIAFORMAT_KEY_TITLE = "title";
EXPORT const char* AMEDIAFORMAT_KEY_TRACK_ID = "track-id";
EXPORT const char* AMEDIAFORMAT_KEY_TRACK_INDEX = "track-index";
+EXPORT const char* AMEDIAFORMAT_KEY_VALID_SAMPLES = "valid-samples";
EXPORT const char* AMEDIAFORMAT_KEY_WIDTH = "width";
EXPORT const char* AMEDIAFORMAT_KEY_YEAR = "year";
diff --git a/media/ndk/include/media/NdkMediaFormat.h b/media/ndk/include/media/NdkMediaFormat.h
index 2cd1d04..2551228 100644
--- a/media/ndk/include/media/NdkMediaFormat.h
+++ b/media/ndk/include/media/NdkMediaFormat.h
@@ -190,9 +190,11 @@
extern const char* AMEDIAFORMAT_KEY_COMPOSER __INTRODUCED_IN(29);
extern const char* AMEDIAFORMAT_KEY_CRYPTO_DEFAULT_IV_SIZE __INTRODUCED_IN(29);
extern const char* AMEDIAFORMAT_KEY_CRYPTO_ENCRYPTED_BYTE_BLOCK __INTRODUCED_IN(29);
+extern const char* AMEDIAFORMAT_KEY_CRYPTO_ENCRYPTED_SIZES __INTRODUCED_IN(29);
extern const char* AMEDIAFORMAT_KEY_CRYPTO_IV __INTRODUCED_IN(29);
extern const char* AMEDIAFORMAT_KEY_CRYPTO_KEY __INTRODUCED_IN(29);
extern const char* AMEDIAFORMAT_KEY_CRYPTO_MODE __INTRODUCED_IN(29);
+extern const char* AMEDIAFORMAT_KEY_CRYPTO_PLAIN_SIZES __INTRODUCED_IN(29);
extern const char* AMEDIAFORMAT_KEY_CRYPTO_SKIP_BYTE_BLOCK __INTRODUCED_IN(29);
extern const char* AMEDIAFORMAT_KEY_CSD_AVC __INTRODUCED_IN(29);
extern const char* AMEDIAFORMAT_KEY_CSD_HEVC __INTRODUCED_IN(29);
@@ -217,12 +219,14 @@
extern const char* AMEDIAFORMAT_KEY_PSSH __INTRODUCED_IN(29);
extern const char* AMEDIAFORMAT_KEY_SAR_HEIGHT __INTRODUCED_IN(29);
extern const char* AMEDIAFORMAT_KEY_SAR_WIDTH __INTRODUCED_IN(29);
+extern const char* AMEDIAFORMAT_KEY_TARGET_TIME __INTRODUCED_IN(29);
extern const char* AMEDIAFORMAT_KEY_TEMPORAL_LAYER_COUNT __INTRODUCED_IN(29);
extern const char* AMEDIAFORMAT_KEY_TEXT_FORMAT_DATA __INTRODUCED_IN(29);
extern const char* AMEDIAFORMAT_KEY_THUMBNAIL_HEIGHT __INTRODUCED_IN(29);
extern const char* AMEDIAFORMAT_KEY_THUMBNAIL_TIME __INTRODUCED_IN(29);
extern const char* AMEDIAFORMAT_KEY_THUMBNAIL_WIDTH __INTRODUCED_IN(29);
extern const char* AMEDIAFORMAT_KEY_TITLE __INTRODUCED_IN(29);
+extern const char* AMEDIAFORMAT_KEY_VALID_SAMPLES __INTRODUCED_IN(29);
extern const char* AMEDIAFORMAT_KEY_YEAR __INTRODUCED_IN(29);
#endif /* __ANDROID_API__ >= 29 */
diff --git a/media/ndk/libmediandk.map.txt b/media/ndk/libmediandk.map.txt
index 3567899..c50084e 100644
--- a/media/ndk/libmediandk.map.txt
+++ b/media/ndk/libmediandk.map.txt
@@ -58,9 +58,11 @@
AMEDIAFORMAT_KEY_COMPOSER; # var introduced=29
AMEDIAFORMAT_KEY_CRYPTO_DEFAULT_IV_SIZE; # var introduced=29
AMEDIAFORMAT_KEY_CRYPTO_ENCRYPTED_BYTE_BLOCK; # var introduced=29
+ AMEDIAFORMAT_KEY_CRYPTO_ENCRYPTED_SIZES; # var introduced=29
AMEDIAFORMAT_KEY_CRYPTO_IV; # var introduced=29
AMEDIAFORMAT_KEY_CRYPTO_KEY; # var introduced=29
AMEDIAFORMAT_KEY_CRYPTO_MODE; # var introduced=29
+ AMEDIAFORMAT_KEY_CRYPTO_PLAIN_SIZES; # var introduced=29
AMEDIAFORMAT_KEY_CRYPTO_SKIP_BYTE_BLOCK; # var introduced=29
AMEDIAFORMAT_KEY_CSD; # var introduced=28
AMEDIAFORMAT_KEY_CSD_0; # var introduced=28
@@ -124,6 +126,7 @@
AMEDIAFORMAT_KEY_SEI; # var introduced=28
AMEDIAFORMAT_KEY_SLICE_HEIGHT; # var introduced=28
AMEDIAFORMAT_KEY_STRIDE; # var introduced=21
+ AMEDIAFORMAT_KEY_TARGET_TIME; # var introduced=29
AMEDIAFORMAT_KEY_TEMPORAL_LAYER_COUNT; # var introduced=29
AMEDIAFORMAT_KEY_TEMPORAL_LAYER_ID; # var introduced=28
AMEDIAFORMAT_KEY_TEMPORAL_LAYERING; # var introduced=28
@@ -137,6 +140,7 @@
AMEDIAFORMAT_KEY_TIME_US; # var introduced=28
AMEDIAFORMAT_KEY_TRACK_INDEX; # var introduced=28
AMEDIAFORMAT_KEY_TRACK_ID; # var introduced=28
+ AMEDIAFORMAT_KEY_VALID_SAMPLES; # var introduced=29
AMEDIAFORMAT_KEY_WIDTH; # var introduced=21
AMEDIAFORMAT_KEY_YEAR; # var introduced=29
AMediaCodecActionCode_isRecoverable; # introduced=28
diff --git a/packages/MediaComponents/apex/java/android/media/MediaMetadata.java b/packages/MediaComponents/apex/java/android/media/MediaMetadata.java
index 33e6916..adfd20b 100644
--- a/packages/MediaComponents/apex/java/android/media/MediaMetadata.java
+++ b/packages/MediaComponents/apex/java/android/media/MediaMetadata.java
@@ -422,9 +422,7 @@
}
private MediaMetadata(Parcel in) {
- //TODO(b/119789387): Resolve hidden API usage: Bundle#setDefusable
- //mBundle = Bundle.setDefusable(in.readBundle(), true);
- mBundle = new Bundle(); //TODO:remove this.
+ mBundle = in.readBundle();
}
/**
diff --git a/packages/MediaComponents/apex/java/android/media/session/ISession.aidl b/packages/MediaComponents/apex/java/android/media/session/ISession.aidl
index c5b376c..14b1c64 100644
--- a/packages/MediaComponents/apex/java/android/media/session/ISession.aidl
+++ b/packages/MediaComponents/apex/java/android/media/session/ISession.aidl
@@ -39,7 +39,7 @@
void destroy();
// These commands are for the TransportPerformer
- void setMetadata(in MediaMetadata metadata);
+ void setMetadata(in MediaMetadata metadata, long duration, String metadataDescription);
void setPlaybackState(in PlaybackState state);
void setQueue(in MediaParceledListSlice queue);
void setQueueTitle(CharSequence title);
diff --git a/packages/MediaComponents/apex/java/android/media/session/MediaSession.java b/packages/MediaComponents/apex/java/android/media/session/MediaSession.java
index e5eff95..943843d 100644
--- a/packages/MediaComponents/apex/java/android/media/session/MediaSession.java
+++ b/packages/MediaComponents/apex/java/android/media/session/MediaSession.java
@@ -30,6 +30,7 @@
import android.media.MediaParceledListSlice;
import android.media.Rating;
import android.media.VolumeProvider;
+import android.media.session.MediaSessionManager.RemoteUserInfo;
import android.net.Uri;
import android.os.Bundle;
import android.os.Handler;
@@ -40,7 +41,6 @@
import android.os.RemoteException;
import android.os.ResultReceiver;
import android.os.UserHandle;
-import android.media.session.MediaSessionManager.RemoteUserInfo;
import android.service.media.MediaBrowserService;
import android.text.TextUtils;
import android.util.Log;
@@ -439,11 +439,21 @@
* @see android.media.MediaMetadata.Builder#putBitmap
*/
public void setMetadata(@Nullable MediaMetadata metadata) {
+ long duration = -1;
+ int fields = 0;
+ MediaDescription description = null;
if (metadata != null) {
metadata = (new MediaMetadata.Builder(metadata, mMaxBitmapSize)).build();
+ if (metadata.containsKey(MediaMetadata.METADATA_KEY_DURATION)) {
+ duration = metadata.getLong(MediaMetadata.METADATA_KEY_DURATION);
+ }
+ fields = metadata.size();
+ description = metadata.getDescription();
}
+ String metadataDescription = "size=" + fields + ", description=" + description;
+
try {
- mBinder.setMetadata(metadata);
+ mBinder.setMetadata(metadata, duration, metadataDescription);
} catch (RemoteException e) {
Log.wtf(TAG, "Dead object in setPlaybackState.", e);
}
diff --git a/services/audiopolicy/Android.mk b/services/audiopolicy/Android.mk
index 02ab8ad..bfa1b5e 100644
--- a/services/audiopolicy/Android.mk
+++ b/services/audiopolicy/Android.mk
@@ -25,7 +25,11 @@
libmedia_helper \
libmediametrics \
libmediautils \
- libeffectsconfig
+ libeffectsconfig \
+ libsensorprivacy
+
+LOCAL_EXPORT_SHARED_LIBRARY_HEADERS := \
+ libsensorprivacy
LOCAL_STATIC_LIBRARIES := \
libaudiopolicycomponents
diff --git a/services/audiopolicy/common/managerdefinitions/include/AudioPort.h b/services/audiopolicy/common/managerdefinitions/include/AudioPort.h
index ebb9352..bb9cad8 100644
--- a/services/audiopolicy/common/managerdefinitions/include/AudioPort.h
+++ b/services/audiopolicy/common/managerdefinitions/include/AudioPort.h
@@ -116,6 +116,7 @@
audio_module_handle_t getModuleHandle() const;
uint32_t getModuleVersionMajor() const;
const char *getModuleName() const;
+ sp<HwModule> getModule() const { return mModule; }
bool useInputChannelMask() const
{
@@ -137,12 +138,12 @@
void log(const char* indent) const;
AudioGainCollection mGains; // gain controllers
- sp<HwModule> mModule; // audio HW module exposing this I/O stream
private:
void pickChannelMask(audio_channel_mask_t &channelMask, const ChannelsVector &channelMasks) const;
void pickSamplingRate(uint32_t &rate,const SampleRateVector &samplingRates) const;
+ sp<HwModule> mModule; // audio HW module exposing this I/O stream
String8 mName;
audio_port_type_t mType;
audio_port_role_t mRole;
diff --git a/services/audiopolicy/common/managerdefinitions/include/AudioRoute.h b/services/audiopolicy/common/managerdefinitions/include/AudioRoute.h
index 330f1d4..0357ff4 100644
--- a/services/audiopolicy/common/managerdefinitions/include/AudioRoute.h
+++ b/services/audiopolicy/common/managerdefinitions/include/AudioRoute.h
@@ -46,6 +46,19 @@
audio_route_type_t getType() const { return mType; }
+ /**
+ * @brief supportsPatch checks if an audio patch is supported by a Route declared in
+ * the audio_policy_configuration.xml file.
+ * If the patch is supported natively by an AudioHAL (which supports of course Routing API 3.0),
+ * audiopolicy will not request AudioFlinger to use a software bridge to realize a patch
+ * between 2 ports.
+ * @param srcPort (aka the source) to be considered
+ * @param dstPort (aka the sink) to be considered
+ * @return true if the audio route supports the connection between the sink and the source,
+ * false otherwise
+ */
+ bool supportsPatch(const sp<AudioPort> &srcPort, const sp<AudioPort> &dstPort) const;
+
void dump(String8 *dst, int spaces) const;
private:
diff --git a/services/audiopolicy/common/managerdefinitions/include/DeviceDescriptor.h b/services/audiopolicy/common/managerdefinitions/include/DeviceDescriptor.h
index 6f99bf3..d02123c 100644
--- a/services/audiopolicy/common/managerdefinitions/include/DeviceDescriptor.h
+++ b/services/audiopolicy/common/managerdefinitions/include/DeviceDescriptor.h
@@ -39,6 +39,8 @@
virtual const String8 getTagName() const { return mTagName; }
audio_devices_t type() const { return mDeviceType; }
+ String8 address() const { return mAddress; }
+ void setAddress(const String8 &address) { mAddress = address; }
const FormatVector& encodedFormats() const { return mEncodedFormats; }
@@ -57,39 +59,113 @@
audio_port_handle_t getId() const;
void dump(String8 *dst, int spaces, int index, bool verbose = true) const;
void log() const;
-
- String8 mAddress;
+ std::string toString() const;
private:
+ String8 mAddress{""};
String8 mTagName; // Unique human readable identifier for a device port found in conf file.
audio_devices_t mDeviceType;
FormatVector mEncodedFormats;
- audio_port_handle_t mId;
-
-friend class DeviceVector;
+ audio_port_handle_t mId = AUDIO_PORT_HANDLE_NONE;
};
class DeviceVector : public SortedVector<sp<DeviceDescriptor> >
{
public:
DeviceVector() : SortedVector(), mDeviceTypes(AUDIO_DEVICE_NONE) {}
+ explicit DeviceVector(const sp<DeviceDescriptor>& item) : DeviceVector()
+ {
+ add(item);
+ }
ssize_t add(const sp<DeviceDescriptor>& item);
void add(const DeviceVector &devices);
ssize_t remove(const sp<DeviceDescriptor>& item);
+ void remove(const DeviceVector &devices);
ssize_t indexOf(const sp<DeviceDescriptor>& item) const;
audio_devices_t types() const { return mDeviceTypes; }
// If 'address' is empty, a device with a non-empty address may be returned
// if there is no device with the specified 'type' and empty address.
- sp<DeviceDescriptor> getDevice(audio_devices_t type, const String8 &address) const;
+ sp<DeviceDescriptor> getDevice(audio_devices_t type, const String8 &address = {}) const;
DeviceVector getDevicesFromTypeMask(audio_devices_t types) const;
+
+ /**
+ * @brief getDeviceFromId
+ * @param id of the DeviceDescriptor to seach (aka Port handle).
+ * @return DeviceDescriptor associated to port id if found, nullptr otherwise. If the id is
+ * equal to AUDIO_PORT_HANDLE_NONE, it also returns a nullptr.
+ */
sp<DeviceDescriptor> getDeviceFromId(audio_port_handle_t id) const;
sp<DeviceDescriptor> getDeviceFromTagName(const String8 &tagName) const;
DeviceVector getDevicesFromHwModule(audio_module_handle_t moduleHandle) const;
audio_devices_t getDeviceTypesFromHwModule(audio_module_handle_t moduleHandle) const;
+ bool contains(const sp<DeviceDescriptor>& item) const { return indexOf(item) >= 0; }
+
+ /**
+ * @brief containsAtLeastOne
+ * @param devices vector of devices to check against.
+ * @return true if the DeviceVector contains at list one of the devices from the given vector.
+ */
+ bool containsAtLeastOne(const DeviceVector &devices) const;
+
+ /**
+ * @brief containsAllDevices
+ * @param devices vector of devices to check against.
+ * @return true if the DeviceVector contains all the devices from the given vector
+ */
+ bool containsAllDevices(const DeviceVector &devices) const;
+
+ /**
+ * @brief filter the devices supported by this collection against another collection
+ * @param devices to filter against
+ * @return
+ */
+ DeviceVector filter(const DeviceVector &devices) const;
+
+ /**
+ * @brief merge two vectors. As SortedVector Implementation is buggy (it does not check the size
+ * of the destination vector, only of the source, it provides a safe implementation
+ * @param devices source device vector to merge with
+ * @return size of the merged vector.
+ */
+ ssize_t merge(const DeviceVector &devices)
+ {
+ if (isEmpty()) {
+ add(devices);
+ return size();
+ }
+ return SortedVector::merge(devices);
+ }
+
+ /**
+ * @brief operator == DeviceVector are equals if all the DeviceDescriptor can be found (aka
+ * DeviceDescriptor with same type and address) and the vector has same size.
+ * @param right DeviceVector to compare to.
+ * @return true if right contains the same device and has the same size.
+ */
+ bool operator==(const DeviceVector &right) const
+ {
+ if (size() != right.size()) {
+ return false;
+ }
+ for (const auto &device : *this) {
+ if (right.indexOf(device) < 0) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ bool operator!=(const DeviceVector &right) const
+ {
+ return !operator==(right);
+ }
+
+ std::string toString() const;
+
void dump(String8 *dst, const String8 &tag, int spaces = 0, bool verbose = true) const;
private:
diff --git a/services/audiopolicy/common/managerdefinitions/include/HwModule.h b/services/audiopolicy/common/managerdefinitions/include/HwModule.h
index 6560431..2b57fa9 100644
--- a/services/audiopolicy/common/managerdefinitions/include/HwModule.h
+++ b/services/audiopolicy/common/managerdefinitions/include/HwModule.h
@@ -81,6 +81,17 @@
return mPorts.findByTagName(tagName);
}
+ /**
+ * @brief supportsPatch checks if an audio patch between 2 ports beloging to this HwModule
+ * is supported by a HwModule. The ports and the route shall be declared in the
+ * audio_policy_configuration.xml file.
+ * @param srcPort (aka the source) to be considered
+ * @param dstPort (aka the sink) to be considered
+ * @return true if the HwModule supports the connection between the sink and the source,
+ * false otherwise
+ */
+ bool supportsPatch(const sp<AudioPort> &srcPort, const sp<AudioPort> &dstPort) const;
+
// TODO remove from here (split serialization)
void dump(String8 *dst) const;
diff --git a/services/audiopolicy/common/managerdefinitions/include/IOProfile.h b/services/audiopolicy/common/managerdefinitions/include/IOProfile.h
index 8ff8238..ca6ca56 100644
--- a/services/audiopolicy/common/managerdefinitions/include/IOProfile.h
+++ b/services/audiopolicy/common/managerdefinitions/include/IOProfile.h
@@ -88,7 +88,7 @@
bool supportDeviceAddress(const String8 &address) const
{
- return mSupportedDevices[0]->mAddress == address;
+ return mSupportedDevices[0]->address() == address;
}
// chose first device present in mSupportedDevices also part of deviceType
diff --git a/services/audiopolicy/common/managerdefinitions/include/TypeConverter.h b/services/audiopolicy/common/managerdefinitions/include/TypeConverter.h
index 63c19d1..6b0476c 100644
--- a/services/audiopolicy/common/managerdefinitions/include/TypeConverter.h
+++ b/services/audiopolicy/common/managerdefinitions/include/TypeConverter.h
@@ -23,26 +23,10 @@
namespace android {
-struct DeviceCategoryTraits
-{
- typedef device_category Type;
- typedef Vector<Type> Collection;
-};
-struct MixTypeTraits
-{
- typedef int32_t Type;
- typedef Vector<Type> Collection;
-};
-struct RouteFlagTraits
-{
- typedef uint32_t Type;
- typedef Vector<Type> Collection;
-};
-struct RuleTraits
-{
- typedef uint32_t Type;
- typedef Vector<Type> Collection;
-};
+struct RuleTraits : public DefaultTraits<uint32_t> {};
+using DeviceCategoryTraits = DefaultTraits<device_category>;
+struct MixTypeTraits : public DefaultTraits<int32_t> {};
+struct RouteFlagTraits : public DefaultTraits<uint32_t> {};
typedef TypeConverter<DeviceCategoryTraits> DeviceCategoryConverter;
typedef TypeConverter<MixTypeTraits> MixTypeConverter;
diff --git a/services/audiopolicy/common/managerdefinitions/src/AudioOutputDescriptor.cpp b/services/audiopolicy/common/managerdefinitions/src/AudioOutputDescriptor.cpp
index 4ce6b08..97504ab 100644
--- a/services/audiopolicy/common/managerdefinitions/src/AudioOutputDescriptor.cpp
+++ b/services/audiopolicy/common/managerdefinitions/src/AudioOutputDescriptor.cpp
@@ -698,8 +698,8 @@
sp<SwAudioOutputDescriptor> primaryOutput = getPrimaryOutput();
if ((primaryOutput != NULL) && (primaryOutput->mProfile != NULL)
- && (primaryOutput->mProfile->mModule != NULL)) {
- sp<HwModule> primaryHwModule = primaryOutput->mProfile->mModule;
+ && (primaryOutput->mProfile->getModule() != NULL)) {
+ sp<HwModule> primaryHwModule = primaryOutput->mProfile->getModule();
Vector <sp<IOProfile>> primaryHwModuleOutputProfiles =
primaryHwModule->getOutputProfiles();
for (size_t i = 0; i < primaryHwModuleOutputProfiles.size(); i++) {
diff --git a/services/audiopolicy/common/managerdefinitions/src/AudioRoute.cpp b/services/audiopolicy/common/managerdefinitions/src/AudioRoute.cpp
index c1fe5b0..79f0919 100644
--- a/services/audiopolicy/common/managerdefinitions/src/AudioRoute.cpp
+++ b/services/audiopolicy/common/managerdefinitions/src/AudioRoute.cpp
@@ -37,4 +37,19 @@
dst->append("\n");
}
+bool AudioRoute::supportsPatch(const sp<AudioPort> &srcPort, const sp<AudioPort> &dstPort) const
+{
+ if (mSink == 0 || dstPort == 0 || dstPort != mSink) {
+ return false;
+ }
+ ALOGV("%s: sinks %s matching", __FUNCTION__, mSink->getTagName().string());
+ for (const auto &sourcePort : mSources) {
+ if (sourcePort == srcPort) {
+ ALOGV("%s: sources %s matching", __FUNCTION__, sourcePort->getTagName().string());
+ return true;
+ }
+ }
+ return false;
+}
+
}
diff --git a/services/audiopolicy/common/managerdefinitions/src/DeviceDescriptor.cpp b/services/audiopolicy/common/managerdefinitions/src/DeviceDescriptor.cpp
index 9e5f944..04cbcd1 100644
--- a/services/audiopolicy/common/managerdefinitions/src/DeviceDescriptor.cpp
+++ b/services/audiopolicy/common/managerdefinitions/src/DeviceDescriptor.cpp
@@ -35,7 +35,7 @@
AudioPort(String8(""), AUDIO_PORT_TYPE_DEVICE,
audio_is_output_device(type) ? AUDIO_PORT_ROLE_SINK :
AUDIO_PORT_ROLE_SOURCE),
- mAddress(""), mTagName(tagName), mDeviceType(type), mEncodedFormats(encodedFormats), mId(0)
+ mTagName(tagName), mDeviceType(type), mEncodedFormats(encodedFormats)
{
if (type == AUDIO_DEVICE_IN_REMOTE_SUBMIX || type == AUDIO_DEVICE_OUT_REMOTE_SUBMIX ) {
mAddress = String8("0");
@@ -132,6 +132,13 @@
return ret;
}
+void DeviceVector::remove(const DeviceVector &devices)
+{
+ for (const auto& device : devices) {
+ remove(device);
+ }
+}
+
DeviceVector DeviceVector::getDevicesFromHwModule(audio_module_handle_t moduleHandle) const
{
DeviceVector devices;
@@ -159,9 +166,9 @@
sp<DeviceDescriptor> device;
for (size_t i = 0; i < size(); i++) {
if (itemAt(i)->type() == type) {
- if (address == "" || itemAt(i)->mAddress == address) {
+ if (address == "" || itemAt(i)->address() == address) {
device = itemAt(i);
- if (itemAt(i)->mAddress == address) {
+ if (itemAt(i)->address() == address) {
break;
}
}
@@ -174,9 +181,11 @@
sp<DeviceDescriptor> DeviceVector::getDeviceFromId(audio_port_handle_t id) const
{
- for (const auto& device : *this) {
- if (device->getId() == id) {
- return device;
+ if (id != AUDIO_PORT_HANDLE_NONE) {
+ for (const auto& device : *this) {
+ if (device->getId() == id) {
+ return device;
+ }
}
}
return nullptr;
@@ -188,8 +197,8 @@
bool isOutput = audio_is_output_devices(type);
type &= ~AUDIO_DEVICE_BIT_IN;
for (size_t i = 0; (i < size()) && (type != AUDIO_DEVICE_NONE); i++) {
- bool curIsOutput = audio_is_output_devices(itemAt(i)->mDeviceType);
- audio_devices_t curType = itemAt(i)->mDeviceType & ~AUDIO_DEVICE_BIT_IN;
+ bool curIsOutput = audio_is_output_devices(itemAt(i)->type());
+ audio_devices_t curType = itemAt(i)->type() & ~AUDIO_DEVICE_BIT_IN;
if ((isOutput == curIsOutput) && ((type & curType) != 0)) {
devices.add(itemAt(i));
type &= ~curType;
@@ -251,8 +260,7 @@
// without the test?
// This has been demonstrated to NOT be true (at start up)
// ALOG_ASSERT(mModule != NULL);
- dstConfig->ext.device.hw_module =
- mModule != 0 ? mModule->getHandle() : AUDIO_MODULE_HANDLE_NONE;
+ dstConfig->ext.device.hw_module = getModuleHandle();
(void)audio_utils_strlcpy_zerofill(dstConfig->ext.device.address, mAddress.string());
}
@@ -263,7 +271,7 @@
port->id = mId;
toAudioPortConfig(&port->active_config);
port->ext.device.type = mDeviceType;
- port->ext.device.hw_module = mModule->getHandle();
+ port->ext.device.hw_module = getModuleHandle();
(void)audio_utils_strlcpy_zerofill(port->ext.device.address, mAddress.string());
}
@@ -294,6 +302,49 @@
AudioPort::dump(dst, spaces, verbose);
}
+std::string DeviceDescriptor::toString() const
+{
+ std::stringstream sstream;
+ sstream << "type:0x" << std::hex << type() << ",@:" << mAddress;
+ return sstream.str();
+}
+
+std::string DeviceVector::toString() const
+{
+ if (isEmpty()) {
+ return {"AUDIO_DEVICE_NONE"};
+ }
+ std::string result = {"{"};
+ for (const auto &device : *this) {
+ if (device != *begin()) {
+ result += ";";
+ }
+ result += device->toString();
+ }
+ return result + "}";
+}
+
+DeviceVector DeviceVector::filter(const DeviceVector &devices) const
+{
+ DeviceVector filteredDevices;
+ for (const auto &device : *this) {
+ if (devices.contains(device)) {
+ filteredDevices.add(device);
+ }
+ }
+ return filteredDevices;
+}
+
+bool DeviceVector::containsAtLeastOne(const DeviceVector &devices) const
+{
+ return !filter(devices).isEmpty();
+}
+
+bool DeviceVector::containsAllDevices(const DeviceVector &devices) const
+{
+ return filter(devices).size() == devices.size();
+}
+
void DeviceDescriptor::log() const
{
std::string device;
diff --git a/services/audiopolicy/common/managerdefinitions/src/HwModule.cpp b/services/audiopolicy/common/managerdefinitions/src/HwModule.cpp
index 92bc595..80af88d 100644
--- a/services/audiopolicy/common/managerdefinitions/src/HwModule.cpp
+++ b/services/audiopolicy/common/managerdefinitions/src/HwModule.cpp
@@ -51,7 +51,7 @@
config->sample_rate));
sp<DeviceDescriptor> devDesc = new DeviceDescriptor(device);
- devDesc->mAddress = address;
+ devDesc->setAddress(address);
profile->addSupportedDevice(devDesc);
return addOutputProfile(profile);
@@ -113,7 +113,7 @@
config->sample_rate));
sp<DeviceDescriptor> devDesc = new DeviceDescriptor(device);
- devDesc->mAddress = address;
+ devDesc->setAddress(address);
profile->addSupportedDevice(devDesc);
ALOGV("addInputProfile() name %s rate %d mask 0x%08x",
@@ -218,6 +218,15 @@
mHandle = handle;
}
+bool HwModule::supportsPatch(const sp<AudioPort> &srcPort, const sp<AudioPort> &dstPort) const {
+ for (const auto &route : mRoutes) {
+ if (route->supportsPatch(srcPort, dstPort)) {
+ return true;
+ }
+ }
+ return false;
+}
+
void HwModule::dump(String8 *dst) const
{
dst->appendFormat(" - name: %s\n", getName());
@@ -287,7 +296,7 @@
sp<DeviceDescriptor> devDesc = new DeviceDescriptor(device);
devDesc->setName(String8(device_name));
- devDesc->mAddress = address;
+ devDesc->setAddress(address);
return devDesc;
}
diff --git a/services/audiopolicy/common/managerdefinitions/src/Serializer.cpp b/services/audiopolicy/common/managerdefinitions/src/Serializer.cpp
index 179a678..1154654 100644
--- a/services/audiopolicy/common/managerdefinitions/src/Serializer.cpp
+++ b/services/audiopolicy/common/managerdefinitions/src/Serializer.cpp
@@ -516,7 +516,7 @@
std::string address = getXmlAttribute(cur, Attributes::address);
if (!address.empty()) {
ALOGV("%s: address=%s for %s", __func__, address.c_str(), name.c_str());
- deviceDesc->mAddress = String8(address.c_str());
+ deviceDesc->setAddress(String8(address.c_str()));
}
AudioProfileTraits::Collection profiles;
@@ -535,7 +535,7 @@
return Status::fromStatusT(status);
}
ALOGV("%s: adding device tag %s type %08x address %s", __func__,
- deviceDesc->getName().string(), type, deviceDesc->mAddress.string());
+ deviceDesc->getName().string(), type, deviceDesc->address().string());
return deviceDesc;
}
@@ -742,7 +742,7 @@
}
ALOGV("%s: %s=%s",
__func__, tag, reinterpret_cast<const char*>(pointDefinition.get()));
- Vector<int32_t> point;
+ std::vector<int32_t> point;
collectionFromString<DefaultTraits<int32_t>>(
reinterpret_cast<const char*>(pointDefinition.get()), point, ",");
if (point.size() != 2) {
diff --git a/services/audiopolicy/managerdefault/AudioPolicyManager.cpp b/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
index f07b797..64a2b8a 100644
--- a/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
+++ b/services/audiopolicy/managerdefault/AudioPolicyManager.cpp
@@ -149,13 +149,13 @@
// Before checking outputs, broadcast connect event to allow HAL to retrieve dynamic
// parameters on newly connected devices (instead of opening the outputs...)
- broadcastDeviceConnectionState(device, state, devDesc->mAddress);
+ broadcastDeviceConnectionState(device, state, devDesc->address());
- if (checkOutputsForDevice(devDesc, state, outputs, devDesc->mAddress) != NO_ERROR) {
+ if (checkOutputsForDevice(devDesc, state, outputs, devDesc->address()) != NO_ERROR) {
mAvailableOutputDevices.remove(devDesc);
broadcastDeviceConnectionState(device, AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE,
- devDesc->mAddress);
+ devDesc->address());
return INVALID_OPERATION;
}
// Propagate device availability to Engine
@@ -178,12 +178,12 @@
ALOGV("setDeviceConnectionState() disconnecting output device %x", device);
// Send Disconnect to HALs
- broadcastDeviceConnectionState(device, state, devDesc->mAddress);
+ broadcastDeviceConnectionState(device, state, devDesc->address());
// remove device from available output devices
mAvailableOutputDevices.remove(devDesc);
- checkOutputsForDevice(devDesc, state, outputs, devDesc->mAddress);
+ checkOutputsForDevice(devDesc, state, outputs, devDesc->address());
// Propagate device availability to Engine
mEngine->setDeviceConnectionState(devDesc, state);
@@ -265,11 +265,11 @@
// Before checking intputs, broadcast connect event to allow HAL to retrieve dynamic
// parameters on newly connected devices (instead of opening the inputs...)
- broadcastDeviceConnectionState(device, state, devDesc->mAddress);
+ broadcastDeviceConnectionState(device, state, devDesc->address());
- if (checkInputsForDevice(devDesc, state, inputs, devDesc->mAddress) != NO_ERROR) {
+ if (checkInputsForDevice(devDesc, state, inputs, devDesc->address()) != NO_ERROR) {
broadcastDeviceConnectionState(device, AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE,
- devDesc->mAddress);
+ devDesc->address());
return INVALID_OPERATION;
}
@@ -294,9 +294,9 @@
ALOGV("setDeviceConnectionState() disconnecting input device %x", device);
// Set Disconnect to HALs
- broadcastDeviceConnectionState(device, state, devDesc->mAddress);
+ broadcastDeviceConnectionState(device, state, devDesc->address());
- checkInputsForDevice(devDesc, state, inputs, devDesc->mAddress);
+ checkInputsForDevice(devDesc, state, inputs, devDesc->address());
mAvailableInputDevices.remove(devDesc);
// Propagate device availability to Engine
@@ -780,17 +780,39 @@
return output;
}
-status_t AudioPolicyManager::getOutputForAttr(const audio_attributes_t *attr,
- audio_io_handle_t *output,
- audio_session_t session,
- audio_stream_type_t *stream,
- uid_t uid,
- const audio_config_t *config,
- audio_output_flags_t *flags,
- audio_port_handle_t *selectedDeviceId,
- audio_port_handle_t *portId)
+status_t AudioPolicyManager::getAudioAttributes(audio_attributes_t *dstAttr,
+ const audio_attributes_t *srcAttr,
+ audio_stream_type_t srcStream)
{
- audio_attributes_t attributes;
+ if (srcAttr != NULL) {
+ if (!isValidAttributes(srcAttr)) {
+ ALOGE("%s invalid attributes: usage=%d content=%d flags=0x%x tags=[%s]",
+ __func__,
+ srcAttr->usage, srcAttr->content_type, srcAttr->flags,
+ srcAttr->tags);
+ return BAD_VALUE;
+ }
+ *dstAttr = *srcAttr;
+ } else {
+ if (srcStream < AUDIO_STREAM_MIN || srcStream >= AUDIO_STREAM_PUBLIC_CNT) {
+ ALOGE("%s: invalid stream type", __func__);
+ return BAD_VALUE;
+ }
+ stream_type_to_audio_attributes(srcStream, dstAttr);
+ }
+ return NO_ERROR;
+}
+
+status_t AudioPolicyManager::getOutputForAttrInt(audio_attributes_t *resultAttr,
+ audio_io_handle_t *output,
+ audio_session_t session,
+ const audio_attributes_t *attr,
+ audio_stream_type_t *stream,
+ uid_t uid,
+ const audio_config_t *config,
+ audio_output_flags_t *flags,
+ audio_port_handle_t *selectedDeviceId)
+{
DeviceVector outputDevices;
routing_strategy strategy;
audio_devices_t device;
@@ -798,35 +820,20 @@
audio_devices_t msdDevice =
getModuleDeviceTypes(mAvailableOutputDevices, AUDIO_HARDWARE_MODULE_ID_MSD);
- // The supplied portId must be AUDIO_PORT_HANDLE_NONE
- if (*portId != AUDIO_PORT_HANDLE_NONE) {
- return INVALID_OPERATION;
+ status_t status = getAudioAttributes(resultAttr, attr, *stream);
+ if (status != NO_ERROR) {
+ return status;
}
- if (attr != NULL) {
- if (!isValidAttributes(attr)) {
- ALOGE("getOutputForAttr() invalid attributes: usage=%d content=%d flags=0x%x tags=[%s]",
- attr->usage, attr->content_type, attr->flags,
- attr->tags);
- return BAD_VALUE;
- }
- attributes = *attr;
- } else {
- if (*stream < AUDIO_STREAM_MIN || *stream >= AUDIO_STREAM_PUBLIC_CNT) {
- ALOGE("getOutputForAttr(): invalid stream type");
- return BAD_VALUE;
- }
- stream_type_to_audio_attributes(*stream, &attributes);
- }
-
- ALOGV("getOutputForAttr() usage=%d, content=%d, tag=%s flags=%08x"
+ ALOGV("%s usage=%d, content=%d, tag=%s flags=%08x"
" session %d selectedDeviceId %d",
- attributes.usage, attributes.content_type, attributes.tags, attributes.flags,
+ __func__,
+ resultAttr->usage, resultAttr->content_type, resultAttr->tags, resultAttr->flags,
session, requestedDeviceId);
- *stream = streamTypefromAttributesInt(&attributes);
+ *stream = streamTypefromAttributesInt(resultAttr);
- strategy = getStrategyForAttr(&attributes);
+ strategy = getStrategyForAttr(resultAttr);
// First check for explicit routing (eg. setPreferredDevice)
if (requestedDeviceId != AUDIO_PORT_HANDLE_NONE) {
@@ -836,30 +843,30 @@
} else {
// If no explict route, is there a matching dynamic policy that applies?
sp<SwAudioOutputDescriptor> desc;
- if (mPolicyMixes.getOutputForAttr(attributes, uid, desc) == NO_ERROR) {
+ if (mPolicyMixes.getOutputForAttr(*resultAttr, uid, desc) == NO_ERROR) {
ALOG_ASSERT(desc != 0, "Invalid desc returned by getOutputForAttr");
if (!audio_has_proportional_frames(config->format)) {
return BAD_VALUE;
}
- *stream = streamTypefromAttributesInt(&attributes);
+ *stream = streamTypefromAttributesInt(resultAttr);
*output = desc->mIoHandle;
AudioMix *mix = desc->mPolicyMix;
sp<DeviceDescriptor> deviceDesc =
mAvailableOutputDevices.getDevice(mix->mDeviceType, mix->mDeviceAddress);
*selectedDeviceId = deviceDesc != 0 ? deviceDesc->getId() : AUDIO_PORT_HANDLE_NONE;
- ALOGV("getOutputForAttr() returns output %d", *output);
- goto exit;
+ ALOGV("%s returns output %d", __func__, *output);
+ return NO_ERROR;
}
// Virtual sources must always be dynamicaly or explicitly routed
- if (attributes.usage == AUDIO_USAGE_VIRTUAL_SOURCE) {
- ALOGW("getOutputForAttr() no policy mix found for usage AUDIO_USAGE_VIRTUAL_SOURCE");
+ if (resultAttr->usage == AUDIO_USAGE_VIRTUAL_SOURCE) {
+ ALOGW("%s no policy mix found for usage AUDIO_USAGE_VIRTUAL_SOURCE", __func__);
return BAD_VALUE;
}
device = getDeviceForStrategy(strategy, false /*fromCache*/);
}
- if ((attributes.flags & AUDIO_FLAG_HW_AV_SYNC) != 0) {
+ if ((resultAttr->flags & AUDIO_FLAG_HW_AV_SYNC) != 0) {
*flags = (audio_output_flags_t)(*flags | AUDIO_OUTPUT_FLAG_HW_AV_SYNC);
}
@@ -869,7 +876,7 @@
// to getOutputForDevice.
// TODO: Remove check of AUDIO_STREAM_MUSIC once migration is completed on the app side.
if (device == AUDIO_DEVICE_OUT_TELEPHONY_TX &&
- (*stream == AUDIO_STREAM_MUSIC || attributes.usage == AUDIO_USAGE_VOICE_COMMUNICATION) &&
+ (*stream == AUDIO_STREAM_MUSIC || resultAttr->usage == AUDIO_USAGE_VOICE_COMMUNICATION) &&
audio_is_linear_pcm(config->format) &&
isInCall()) {
if (requestedDeviceId != AUDIO_PORT_HANDLE_NONE) {
@@ -880,9 +887,9 @@
}
}
- ALOGV("getOutputForAttr() device 0x%x, sampling rate %d, format %#x, channel mask %#x, "
+ ALOGV("%s device 0x%x, sampling rate %d, format %#x, channel mask %#x, "
"flags %#x",
- device, config->sample_rate, config->format, config->channel_mask, *flags);
+ __func__, device, config->sample_rate, config->format, config->channel_mask, *flags);
*output = AUDIO_IO_HANDLE_NONE;
if (msdDevice != AUDIO_DEVICE_NONE) {
@@ -903,25 +910,50 @@
}
outputDevices = mAvailableOutputDevices.getDevicesFromTypeMask(device);
- *selectedDeviceId = outputDevices.size() > 0 ? outputDevices.itemAt(0)->getId()
- : AUDIO_PORT_HANDLE_NONE;
+ *selectedDeviceId = getFirstDeviceId(outputDevices);
-exit:
+ ALOGV("%s returns output %d selectedDeviceId %d", __func__, *output, *selectedDeviceId);
+
+ return NO_ERROR;
+}
+
+status_t AudioPolicyManager::getOutputForAttr(const audio_attributes_t *attr,
+ audio_io_handle_t *output,
+ audio_session_t session,
+ audio_stream_type_t *stream,
+ uid_t uid,
+ const audio_config_t *config,
+ audio_output_flags_t *flags,
+ audio_port_handle_t *selectedDeviceId,
+ audio_port_handle_t *portId)
+{
+ // The supplied portId must be AUDIO_PORT_HANDLE_NONE
+ if (*portId != AUDIO_PORT_HANDLE_NONE) {
+ return INVALID_OPERATION;
+ }
+ const audio_port_handle_t requestedDeviceId = *selectedDeviceId;
+ audio_attributes_t resultAttr;
+ status_t status = getOutputForAttrInt(&resultAttr, output, session, attr, stream, uid,
+ config, flags, selectedDeviceId);
+ if (status != NO_ERROR) {
+ return status;
+ }
+
audio_config_base_t clientConfig = {.sample_rate = config->sample_rate,
.format = config->format,
.channel_mask = config->channel_mask };
*portId = AudioPort::getNextUniqueId();
sp<TrackClientDescriptor> clientDesc =
- new TrackClientDescriptor(*portId, uid, session, attributes, clientConfig,
+ new TrackClientDescriptor(*portId, uid, session, resultAttr, clientConfig,
requestedDeviceId, *stream,
- getStrategyForAttr(&attributes),
+ getStrategyForAttr(&resultAttr),
*flags);
sp<SwAudioOutputDescriptor> outputDesc = mOutputs.valueFor(*output);
outputDesc->addClient(clientDesc);
- ALOGV(" getOutputForAttr() returns output %d selectedDeviceId %d for port ID %d",
- *output, *selectedDeviceId, *portId);
+ ALOGV("%s returns output %d selectedDeviceId %d for port ID %d",
+ __func__, *output, requestedDeviceId, *portId);
return NO_ERROR;
}
@@ -1020,8 +1052,7 @@
new SwAudioOutputDescriptor(profile, mpClientInterface);
DeviceVector outputDevices = mAvailableOutputDevices.getDevicesFromTypeMask(device);
- String8 address = outputDevices.size() > 0 ? outputDevices.itemAt(0)->mAddress
- : String8("");
+ String8 address = getFirstDeviceAddress(outputDevices);
// MSD patch may be using the only output stream that can service this request. Release
// MSD patch to prioritize this request over any active output on MSD.
@@ -1722,10 +1753,7 @@
}
// Explicit routing?
- sp<DeviceDescriptor> deviceDesc;
- if (*selectedDeviceId != AUDIO_PORT_HANDLE_NONE) {
- deviceDesc = mAvailableInputDevices.getDeviceFromId(*selectedDeviceId);
- }
+ sp<DeviceDescriptor> deviceDesc = mAvailableInputDevices.getDeviceFromId(*selectedDeviceId);
// special case for mmap capture: if an input IO handle is specified, we reuse this input if
// possible
@@ -1831,8 +1859,7 @@
exit:
inputDevices = mAvailableInputDevices.getDevicesFromTypeMask(device);
- *selectedDeviceId = inputDevices.size() > 0 ? inputDevices.itemAt(0)->getId()
- : AUDIO_PORT_HANDLE_NONE;
+ *selectedDeviceId = getFirstDeviceId(inputDevices);
isSoundTrigger = inputSource == AUDIO_SOURCE_HOTWORD &&
mSoundTriggerSessions.indexOfKey(session) > 0;
@@ -1963,7 +1990,7 @@
if (address == "") {
DeviceVector inputDevices = mAvailableInputDevices.getDevicesFromTypeMask(device);
// the inputs vector must be of size >= 1, but we don't want to crash here
- address = inputDevices.size() > 0 ? inputDevices.itemAt(0)->mAddress : String8("");
+ address = getFirstDeviceAddress(inputDevices);
}
status_t status = inputDesc->open(&lConfig, device, address,
@@ -2930,7 +2957,7 @@
}
if (!outputDesc->mProfile->isCompatibleProfile(devDesc->type(),
- devDesc->mAddress,
+ devDesc->address(),
patch->sources[0].sample_rate,
NULL, // updatedSamplingRate
patch->sources[0].format,
@@ -2987,7 +3014,7 @@
}
if (!inputDesc->mProfile->isCompatibleProfile(devDesc->type(),
- devDesc->mAddress,
+ devDesc->address(),
patch->sinks[0].sample_rate,
NULL, /*updatedSampleRate*/
patch->sinks[0].format,
@@ -3050,8 +3077,10 @@
// create a software bridge in PatchPanel if:
// - source and sink devices are on different HW modules OR
// - audio HAL version is < 3.0
+ // - audio HAL version is >= 3.0 but no route has been declared between devices
if (!srcDeviceDesc->hasSameHwModuleAs(sinkDeviceDesc) ||
- (srcDeviceDesc->mModule->getHalVersionMajor() < 3)) {
+ (srcDeviceDesc->getModuleVersionMajor() < 3) ||
+ !srcDeviceDesc->getModule()->supportsPatch(srcDeviceDesc, sinkDeviceDesc)) {
// support only one sink device for now to simplify output selection logic
if (patch->num_sinks > 1) {
return INVALID_OPERATION;
@@ -3395,16 +3424,25 @@
audio_patch_handle_t afPatchHandle = AUDIO_PATCH_HANDLE_NONE;
- if (srcDeviceDesc->getAudioPort()->mModule->getHandle() ==
- sinkDeviceDesc->getAudioPort()->mModule->getHandle() &&
- srcDeviceDesc->getAudioPort()->mModule->getHalVersionMajor() >= 3 &&
+ if (srcDeviceDesc->hasSameHwModuleAs(sinkDeviceDesc) &&
+ srcDeviceDesc->getModuleVersionMajor() >= 3 &&
+ sinkDeviceDesc->getModule()->supportsPatch(srcDeviceDesc, sinkDeviceDesc) &&
srcDeviceDesc->getAudioPort()->mGains.size() > 0) {
- ALOGV("%s AUDIO_DEVICE_API_VERSION_3_0", __FUNCTION__);
+ ALOGV("%s Device to Device route supported by >=3.0 HAL", __FUNCTION__);
+ // TODO: may explicitly specify whether we should use HW or SW patch
// create patch between src device and output device
// create Hwoutput and add to mHwOutputs
} else {
- SortedVector<audio_io_handle_t> outputs = getOutputsForDevice(sinkDevice, mOutputs);
- audio_io_handle_t output = selectOutput(outputs);
+ audio_attributes_t resultAttr;
+ audio_io_handle_t output = AUDIO_IO_HANDLE_NONE;
+ audio_config_t config = AUDIO_CONFIG_INITIALIZER;
+ config.sample_rate = sourceDesc->config().sample_rate;
+ config.channel_mask = sourceDesc->config().channel_mask;
+ config.format = sourceDesc->config().format;
+ audio_output_flags_t flags = AUDIO_OUTPUT_FLAG_NONE;
+ audio_port_handle_t selectedDeviceId = AUDIO_PORT_HANDLE_NONE;
+ getOutputForAttrInt(&resultAttr, &output, AUDIO_SESSION_NONE,
+ &attributes, &stream, sourceDesc->uid(), &config, &flags, &selectedDeviceId);
if (output == AUDIO_IO_HANDLE_NONE) {
ALOGV("%s no output for device %08x", __FUNCTION__, sinkDevice);
return INVALID_OPERATION;
@@ -3437,6 +3475,13 @@
__FUNCTION__, status);
return INVALID_OPERATION;
}
+
+ if (outputDesc->getClient(sourceDesc->portId()) != nullptr) {
+ ALOGW("%s source portId has already been attached to outputDesc", __func__);
+ return INVALID_OPERATION;
+ }
+ outputDesc->addClient(sourceDesc);
+
uint32_t delayMs = 0;
status = startSource(outputDesc, sourceDesc, &delayMs);
@@ -3615,7 +3660,7 @@
AUDIO_DEVICE_OUT_HDMI);
for (size_t i = 0; i < hdmiOutputDevices.size(); i++) {
// Simulate reconnection to update enabled surround sound formats.
- String8 address = hdmiOutputDevices[i]->mAddress;
+ String8 address = hdmiOutputDevices[i]->address();
String8 name = hdmiOutputDevices[i]->getName();
status_t status = setDeviceConnectionStateInt(AUDIO_DEVICE_OUT_HDMI,
AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE,
@@ -3635,7 +3680,7 @@
AUDIO_DEVICE_IN_HDMI);
for (size_t i = 0; i < hdmiInputDevices.size(); i++) {
// Simulate reconnection to update enabled surround sound formats.
- String8 address = hdmiInputDevices[i]->mAddress;
+ String8 address = hdmiInputDevices[i]->address();
String8 name = hdmiInputDevices[i]->getName();
status_t status = setDeviceConnectionStateInt(AUDIO_DEVICE_IN_HDMI,
AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE,
@@ -3893,8 +3938,7 @@
const DeviceVector &supportedDevices = outProfile->getSupportedDevices();
const DeviceVector &devicesForType = supportedDevices.getDevicesFromTypeMask(
profileType);
- String8 address = devicesForType.size() > 0 ? devicesForType.itemAt(0)->mAddress
- : String8("");
+ String8 address = getFirstDeviceAddress(devicesForType);
audio_io_handle_t output = AUDIO_IO_HANDLE_NONE;
status_t status = outputDesc->open(nullptr, profileType, address,
AUDIO_STREAM_DEFAULT, AUDIO_OUTPUT_FLAG_NONE, &output);
@@ -3948,8 +3992,7 @@
DeviceVector inputDevices = mAvailableInputDevices.getDevicesFromTypeMask(profileType);
// the inputs vector must be of size >= 1, but we don't want to crash here
- String8 address = inputDevices.size() > 0 ? inputDevices.itemAt(0)->mAddress
- : String8("");
+ String8 address = getFirstDeviceAddress(inputDevices);
ALOGV(" for input device 0x%x using address %s", profileType, address.string());
ALOGE_IF(inputDevices.size() == 0, "Input device list is empty!");
@@ -4011,11 +4054,11 @@
}
// If microphones address is empty, set it according to device type
for (size_t i = 0; i < mAvailableInputDevices.size(); i++) {
- if (mAvailableInputDevices[i]->mAddress.isEmpty()) {
+ if (mAvailableInputDevices[i]->address().isEmpty()) {
if (mAvailableInputDevices[i]->type() == AUDIO_DEVICE_IN_BUILTIN_MIC) {
- mAvailableInputDevices[i]->mAddress = String8(AUDIO_BOTTOM_MICROPHONE_ADDRESS);
+ mAvailableInputDevices[i]->address() = String8(AUDIO_BOTTOM_MICROPHONE_ADDRESS);
} else if (mAvailableInputDevices[i]->type() == AUDIO_DEVICE_IN_BACK_MIC) {
- mAvailableInputDevices[i]->mAddress = String8(AUDIO_BACK_MICROPHONE_ADDRESS);
+ mAvailableInputDevices[i]->address() = String8(AUDIO_BACK_MICROPHONE_ADDRESS);
}
}
}
@@ -5184,8 +5227,9 @@
if (!deviceList.isEmpty()) {
PatchBuilder patchBuilder;
patchBuilder.addSource(outputDesc);
- for (size_t i = 0; i < deviceList.size() && i < AUDIO_PATCH_PORTS_MAX; i++) {
- patchBuilder.addSink(deviceList.itemAt(i));
+ ALOG_ASSERT(deviceList.size() <= AUDIO_PATCH_PORTS_MAX, "Too many sink ports");
+ for (const auto &device : deviceList) {
+ patchBuilder.addSink(device);
}
installPatch(__func__, patchHandle, outputDesc.get(), patchBuilder.patch(), delayMs);
}
diff --git a/services/audiopolicy/managerdefault/AudioPolicyManager.h b/services/audiopolicy/managerdefault/AudioPolicyManager.h
index d0708b8..86993d4 100644
--- a/services/audiopolicy/managerdefault/AudioPolicyManager.h
+++ b/services/audiopolicy/managerdefault/AudioPolicyManager.h
@@ -519,6 +519,19 @@
return mAvailableInputDevices.getDeviceTypesFromHwModule(
mPrimaryOutput->getModuleHandle());
}
+ /**
+ * @brief getFirstDeviceId of the Device Vector
+ * @return if the collection is not empty, it returns the first device Id,
+ * otherwise AUDIO_PORT_HANDLE_NONE
+ */
+ audio_port_handle_t getFirstDeviceId(const DeviceVector &devices) const
+ {
+ return (devices.size() > 0) ? devices.itemAt(0)->getId() : AUDIO_PORT_HANDLE_NONE;
+ }
+ String8 getFirstDeviceAddress(const DeviceVector &devices) const
+ {
+ return (devices.size() > 0) ? devices.itemAt(0)->address() : String8("");
+ }
uint32_t updateCallRouting(audio_devices_t rxDevice, uint32_t delayMs = 0);
sp<AudioPatch> createTelephonyPatch(bool isRx, audio_devices_t device, uint32_t delayMs);
@@ -661,6 +674,21 @@
const String8& address /*in*/,
SortedVector<audio_io_handle_t>& outputs /*out*/);
uint32_t curAudioPortGeneration() const { return mAudioPortGeneration; }
+ // internal method, get audio_attributes_t from either a source audio_attributes_t
+ // or audio_stream_type_t, respectively.
+ status_t getAudioAttributes(audio_attributes_t *dstAttr,
+ const audio_attributes_t *srcAttr,
+ audio_stream_type_t srcStream);
+ // internal method, called by getOutputForAttr() and connectAudioSource.
+ status_t getOutputForAttrInt(audio_attributes_t *resultAttr,
+ audio_io_handle_t *output,
+ audio_session_t session,
+ const audio_attributes_t *attr,
+ audio_stream_type_t *stream,
+ uid_t uid,
+ const audio_config_t *config,
+ audio_output_flags_t *flags,
+ audio_port_handle_t *selectedDeviceId);
// internal method to return the output handle for the given device and format
audio_io_handle_t getOutputForDevice(
audio_devices_t device,
diff --git a/services/audiopolicy/service/AudioPolicyService.cpp b/services/audiopolicy/service/AudioPolicyService.cpp
index ee5d6ff..f233971 100644
--- a/services/audiopolicy/service/AudioPolicyService.cpp
+++ b/services/audiopolicy/service/AudioPolicyService.cpp
@@ -38,6 +38,7 @@
#include <media/AudioEffect.h>
#include <media/AudioParameter.h>
#include <mediautils/ServiceUtilities.h>
+#include <sensorprivacy/SensorPrivacyManager.h>
#include <system/audio.h>
#include <system/audio_policy.h>
@@ -84,6 +85,9 @@
mUidPolicy = new UidPolicy(this);
mUidPolicy->registerSelf();
+
+ mSensorPrivacyPolicy = new SensorPrivacyPolicy(this);
+ mSensorPrivacyPolicy->registerSelf();
}
AudioPolicyService::~AudioPolicyService()
@@ -99,6 +103,9 @@
mUidPolicy->unregisterSelf();
mUidPolicy.clear();
+
+ mSensorPrivacyPolicy->unregisterSelf();
+ mSensorPrivacyPolicy.clear();
}
// A notification client is always registered by AudioSystem when the client process
@@ -375,6 +382,12 @@
bool isAssistantOnTop = false;
bool isSensitiveActive = false;
+ // if Sensor Privacy is enabled then all recordings should be silenced.
+ if (mSensorPrivacyPolicy->isSensorPrivacyEnabled()) {
+ silenceAllRecordings_l();
+ return;
+ }
+
for (size_t i =0; i < mAudioRecordClients.size(); i++) {
sp<AudioRecordClient> current = mAudioRecordClients[i];
if (!current->active) continue;
@@ -445,6 +458,13 @@
}
}
+void AudioPolicyService::silenceAllRecordings_l() {
+ for (size_t i = 0; i < mAudioRecordClients.size(); i++) {
+ sp<AudioRecordClient> current = mAudioRecordClients[i];
+ setAppState_l(current->uid, APP_STATE_IDLE);
+ }
+}
+
/* static */
app_state_t AudioPolicyService::apmStatFromAmState(int amState) {
switch (amState) {
@@ -858,6 +878,31 @@
return it != mA11yUids.end();
}
+// ----------- AudioPolicyService::SensorPrivacyService implementation ----------
+void AudioPolicyService::SensorPrivacyPolicy::registerSelf() {
+ SensorPrivacyManager spm;
+ mSensorPrivacyEnabled = spm.isSensorPrivacyEnabled();
+ spm.addSensorPrivacyListener(this);
+}
+
+void AudioPolicyService::SensorPrivacyPolicy::unregisterSelf() {
+ SensorPrivacyManager spm;
+ spm.removeSensorPrivacyListener(this);
+}
+
+bool AudioPolicyService::SensorPrivacyPolicy::isSensorPrivacyEnabled() {
+ return mSensorPrivacyEnabled;
+}
+
+binder::Status AudioPolicyService::SensorPrivacyPolicy::onSensorPrivacyChanged(bool enabled) {
+ mSensorPrivacyEnabled = enabled;
+ sp<AudioPolicyService> service = mService.promote();
+ if (service != nullptr) {
+ service->updateUidStates();
+ }
+ return binder::Status::ok();
+}
+
// ----------- AudioPolicyService::AudioCommandThread implementation ----------
AudioPolicyService::AudioCommandThread::AudioCommandThread(String8 name,
diff --git a/services/audiopolicy/service/AudioPolicyService.h b/services/audiopolicy/service/AudioPolicyService.h
index 23c3daa..45d37dc 100644
--- a/services/audiopolicy/service/AudioPolicyService.h
+++ b/services/audiopolicy/service/AudioPolicyService.h
@@ -33,6 +33,7 @@
#include <media/AudioPolicy.h>
#include "AudioPolicyEffects.h"
#include "managerdefault/AudioPolicyManager.h"
+#include <android/hardware/BnSensorPrivacyListener.h>
#include <unordered_map>
@@ -279,6 +280,8 @@
void updateUidStates();
void updateUidStates_l();
+ void silenceAllRecordings_l();
+
static bool isPrivacySensitive(audio_source_t source);
// If recording we need to make sure the UID is allowed to do that. If the UID is idle
@@ -334,6 +337,27 @@
std::vector<uid_t> mA11yUids;
};
+ // If sensor privacy is enabled then all apps, including those that are active, should be
+ // prevented from recording. This is handled similar to idle UIDs, any app that attempts
+ // to record while sensor privacy is enabled will receive buffers with zeros. As soon as
+ // sensor privacy is disabled active apps will receive the expected data when recording.
+ class SensorPrivacyPolicy : public hardware::BnSensorPrivacyListener {
+ public:
+ explicit SensorPrivacyPolicy(wp<AudioPolicyService> service)
+ : mService(service) {}
+
+ void registerSelf();
+ void unregisterSelf();
+
+ bool isSensorPrivacyEnabled();
+
+ binder::Status onSensorPrivacyChanged(bool enabled);
+
+ private:
+ wp<AudioPolicyService> mService;
+ std::atomic_bool mSensorPrivacyEnabled;
+ };
+
// Thread used to send audio config commands to audio flinger
// For audio config commands, it is necessary because audio flinger requires that the calling
// process (user) has permission to modify audio settings.
@@ -718,6 +742,8 @@
audio_mode_t mPhoneState;
sp<UidPolicy> mUidPolicy;
+ sp<SensorPrivacyPolicy> mSensorPrivacyPolicy;
+
DefaultKeyedVector< audio_port_handle_t, sp<AudioRecordClient> > mAudioRecordClients;
DefaultKeyedVector< audio_port_handle_t, sp<AudioPlaybackClient> > mAudioPlaybackClients;
};
diff --git a/services/camera/libcameraservice/api2/CameraDeviceClient.cpp b/services/camera/libcameraservice/api2/CameraDeviceClient.cpp
index c1a4c11..46fbc3e 100644
--- a/services/camera/libcameraservice/api2/CameraDeviceClient.cpp
+++ b/services/camera/libcameraservice/api2/CameraDeviceClient.cpp
@@ -256,7 +256,7 @@
Vector<int32_t> outputStreamIds;
std::vector<std::string> requestedPhysicalIds;
if (request.mSurfaceList.size() > 0) {
- for (sp<Surface> surface : request.mSurfaceList) {
+ for (const sp<Surface>& surface : request.mSurfaceList) {
if (surface == 0) continue;
int32_t streamId;
diff --git a/services/camera/libcameraservice/device3/Camera3Device.cpp b/services/camera/libcameraservice/device3/Camera3Device.cpp
index 856af13..12fbf82 100644
--- a/services/camera/libcameraservice/device3/Camera3Device.cpp
+++ b/services/camera/libcameraservice/device3/Camera3Device.cpp
@@ -175,7 +175,7 @@
session->interfaceChain([](
::android::hardware::hidl_vec<::android::hardware::hidl_string> interfaceChain) {
ALOGV("Session interface chain:");
- for (auto iface : interfaceChain) {
+ for (const auto& iface : interfaceChain) {
ALOGV(" %s", iface.c_str());
}
});
diff --git a/services/mediacodec/Android.mk b/services/mediacodec/Android.mk
index 789548d..3b6dc80 100644
--- a/services/mediacodec/Android.mk
+++ b/services/mediacodec/Android.mk
@@ -108,6 +108,7 @@
LOCAL_MODULE := mediaswcodec
LOCAL_INIT_RC := mediaswcodec.rc
LOCAL_32_BIT_ONLY := true
+LOCAL_SANITIZE := scudo
sanitizer_runtime_libraries :=
llndk_libraries :=
diff --git a/services/mediacodec/main_swcodecservice.cpp b/services/mediacodec/main_swcodecservice.cpp
index 386abb2..79fea25 100644
--- a/services/mediacodec/main_swcodecservice.cpp
+++ b/services/mediacodec/main_swcodecservice.cpp
@@ -37,6 +37,12 @@
static const char kVendorSeccompPolicyPath[] =
"/vendor/etc/seccomp_policy/mediacodec.policy";
+// Disable Scudo's mismatch allocation check, as it is being triggered
+// by some third party code.
+extern "C" const char *__scudo_default_options() {
+ return "DeallocationTypeMismatch=false";
+}
+
int main(int argc __unused, char** /*argv*/)
{
LOG(INFO) << "media swcodec service starting";
diff --git a/services/mediaextractor/Android.mk b/services/mediaextractor/Android.mk
index 7c9c727..e31eadc 100644
--- a/services/mediaextractor/Android.mk
+++ b/services/mediaextractor/Android.mk
@@ -38,13 +38,6 @@
LOCAL_REQUIRED_MODULES_x86 := crash_dump.policy mediaextractor.policy
LOCAL_REQUIRED_MODULES_x86_64 := crash_dump.policy mediaextractor.policy
-# extractor libraries
-LOCAL_REQUIRED_MODULES += \
- libmkvextractor \
- libmp4extractor \
- libmpeg2extractor \
- liboggextractor \
-
LOCAL_SRC_FILES := main_extractorservice.cpp
LOCAL_SHARED_LIBRARIES := libmedia libmediaextractorservice libbinder libutils \
liblog libbase libicuuc libavservices_minijail
diff --git a/services/oboeservice/AAudioEndpointManager.cpp b/services/oboeservice/AAudioEndpointManager.cpp
index cca1895..a1fc0ea 100644
--- a/services/oboeservice/AAudioEndpointManager.cpp
+++ b/services/oboeservice/AAudioEndpointManager.cpp
@@ -108,7 +108,7 @@
const AAudioStreamConfiguration &configuration) {
sp<AAudioServiceEndpoint> endpoint;
mExclusiveSearchCount++;
- for (const auto ep : mExclusiveStreams) {
+ for (const auto& ep : mExclusiveStreams) {
if (ep->matches(configuration)) {
mExclusiveFoundCount++;
endpoint = ep;
@@ -126,7 +126,7 @@
const AAudioStreamConfiguration &configuration) {
sp<AAudioServiceEndpointShared> endpoint;
mSharedSearchCount++;
- for (const auto ep : mSharedStreams) {
+ for (const auto& ep : mSharedStreams) {
if (ep->matches(configuration)) {
mSharedFoundCount++;
endpoint = ep;
diff --git a/services/oboeservice/AAudioServiceEndpoint.cpp b/services/oboeservice/AAudioServiceEndpoint.cpp
index 539735a..4dfb62a 100644
--- a/services/oboeservice/AAudioServiceEndpoint.cpp
+++ b/services/oboeservice/AAudioServiceEndpoint.cpp
@@ -65,7 +65,7 @@
result << " Connected: " << mConnected.load() << "\n";
result << " Registered Streams:" << "\n";
result << AAudioServiceStreamShared::dumpHeader() << "\n";
- for (const auto stream : mRegisteredStreams) {
+ for (const auto& stream : mRegisteredStreams) {
result << stream->dump() << "\n";
}
@@ -78,7 +78,7 @@
// @return true if stream found
bool AAudioServiceEndpoint::isStreamRegistered(audio_port_handle_t portHandle) {
std::lock_guard<std::mutex> lock(mLockStreams);
- for (const auto stream : mRegisteredStreams) {
+ for (const auto& stream : mRegisteredStreams) {
if (stream->getPortHandle() == portHandle) {
return true;
}
@@ -89,7 +89,7 @@
void AAudioServiceEndpoint::disconnectRegisteredStreams() {
std::lock_guard<std::mutex> lock(mLockStreams);
mConnected.store(false);
- for (const auto stream : mRegisteredStreams) {
+ for (const auto& stream : mRegisteredStreams) {
ALOGD("disconnectRegisteredStreams() stop and disconnect %p", stream.get());
stream->stop();
stream->disconnect();
diff --git a/services/oboeservice/AAudioServiceEndpointCapture.cpp b/services/oboeservice/AAudioServiceEndpointCapture.cpp
index 7ae7f1b..37d105b 100644
--- a/services/oboeservice/AAudioServiceEndpointCapture.cpp
+++ b/services/oboeservice/AAudioServiceEndpointCapture.cpp
@@ -81,9 +81,10 @@
{ // brackets are for lock_guard
std::lock_guard <std::mutex> lock(mLockStreams);
- for (const auto clientStream : mRegisteredStreams) {
- if (clientStream->isRunning()) {
+ for (const auto& clientStream : mRegisteredStreams) {
+ if (clientStream->isRunning() && !clientStream->isSuspended()) {
int64_t clientFramesWritten = 0;
+
sp<AAudioServiceStreamShared> streamShared =
static_cast<AAudioServiceStreamShared *>(clientStream.get());
diff --git a/services/oboeservice/AAudioServiceEndpointMMAP.cpp b/services/oboeservice/AAudioServiceEndpointMMAP.cpp
index e4dbee1..6c28083 100644
--- a/services/oboeservice/AAudioServiceEndpointMMAP.cpp
+++ b/services/oboeservice/AAudioServiceEndpointMMAP.cpp
@@ -371,7 +371,7 @@
float volume = values[0];
ALOGD("%s(%p) volume[0] = %f", __func__, this, volume);
std::lock_guard<std::mutex> lock(mLockStreams);
- for(const auto stream : mRegisteredStreams) {
+ for(const auto& stream : mRegisteredStreams) {
stream->onVolumeChanged(volume);
}
};
diff --git a/services/oboeservice/AAudioServiceEndpointPlay.cpp b/services/oboeservice/AAudioServiceEndpointPlay.cpp
index 923a1a4..1e1c552 100644
--- a/services/oboeservice/AAudioServiceEndpointPlay.cpp
+++ b/services/oboeservice/AAudioServiceEndpointPlay.cpp
@@ -80,10 +80,14 @@
int64_t mmapFramesWritten = getStreamInternal()->getFramesWritten();
std::lock_guard <std::mutex> lock(mLockStreams);
- for (const auto clientStream : mRegisteredStreams) {
+ for (const auto& clientStream : mRegisteredStreams) {
int64_t clientFramesRead = 0;
bool allowUnderflow = true;
+ if (clientStream->isSuspended()) {
+ continue; // dead stream
+ }
+
aaudio_stream_state_t state = clientStream->getState();
if (state == AAUDIO_STREAM_STATE_STOPPING) {
allowUnderflow = false; // just read what is already in the FIFO
diff --git a/services/oboeservice/AAudioServiceStreamBase.cpp b/services/oboeservice/AAudioServiceStreamBase.cpp
index 354b36a..defbb7b 100644
--- a/services/oboeservice/AAudioServiceStreamBase.cpp
+++ b/services/oboeservice/AAudioServiceStreamBase.cpp
@@ -179,6 +179,7 @@
}
setFlowing(false);
+ setSuspended(false);
// Start with fresh presentation timestamps.
mAtomicTimestamp.clear();
@@ -345,7 +346,9 @@
}
int32_t count = mUpMessageQueue->getFifoBuffer()->write(command, 1);
if (count != 1) {
- ALOGE("%s(): Queue full. Did client die? %s", __func__, getTypeText());
+ ALOGW("%s(): Queue full. Did client stop? Suspending stream. what = %u, %s",
+ __func__, command->what, getTypeText());
+ setSuspended(true);
return AAUDIO_ERROR_WOULD_BLOCK;
} else {
return AAUDIO_OK;
diff --git a/services/oboeservice/AAudioServiceStreamBase.h b/services/oboeservice/AAudioServiceStreamBase.h
index a1815d0..7904b25 100644
--- a/services/oboeservice/AAudioServiceStreamBase.h
+++ b/services/oboeservice/AAudioServiceStreamBase.h
@@ -204,6 +204,20 @@
}
/**
+ * Set false when the stream should not longer be processed.
+ * This may be caused by a message queue overflow.
+ * Set true when stream is started.
+ * @param suspended
+ */
+ void setSuspended(bool suspended) {
+ mSuspended = suspended;
+ }
+
+ bool isSuspended() const {
+ return mSuspended;
+ }
+
+ /**
* Atomically increment the number of active references to the stream by AAudioService.
*
* This is called under a global lock in AAudioStreamTracker.
@@ -304,7 +318,12 @@
// This is modified under a global lock in AAudioStreamTracker.
int32_t mCallingCount = 0;
+ // This indicates that a stream that is being referenced by a binder call needs to closed.
std::atomic<bool> mCloseNeeded{false};
+
+ // This indicate that a running stream should not be processed because of an error,
+ // for example a full message queue. Note that this atomic is unrelated to mCloseNeeded.
+ std::atomic<bool> mSuspended{false};
};
} /* namespace aaudio */