Merge "Connect the sensor privacy feature to the camera service" into sc-dev
diff --git a/apex/Android.bp b/apex/Android.bp
index bf91bf7..d8a0b91 100644
--- a/apex/Android.bp
+++ b/apex/Android.bp
@@ -15,7 +15,10 @@
apex_defaults {
name: "com.android.media-defaults",
updatable: true,
- java_libs: ["updatable-media"],
+ java_libs: [
+ "updatable-media",
+ "service-media-s",
+ ],
multilib: {
first: {
// Extractor process runs only with the primary ABI.
diff --git a/camera/ndk/Android.bp b/camera/ndk/Android.bp
index 3cf94d0..5e1e43e 100644
--- a/camera/ndk/Android.bp
+++ b/camera/ndk/Android.bp
@@ -62,7 +62,7 @@
],
cflags: [
"-fvisibility=hidden",
- "-DEXPORT=__attribute__ ((visibility (\"default\")))",
+ "-DEXPORT=__attribute__((visibility(\"default\")))",
"-Wall",
"-Wextra",
"-Werror",
diff --git a/drm/mediadrm/plugins/clearkey/hidl/CryptoPlugin.cpp b/drm/mediadrm/plugins/clearkey/hidl/CryptoPlugin.cpp
index 1495703..d278633 100644
--- a/drm/mediadrm/plugins/clearkey/hidl/CryptoPlugin.cpp
+++ b/drm/mediadrm/plugins/clearkey/hidl/CryptoPlugin.cpp
@@ -119,7 +119,11 @@
return Void();
}
- if (source.offset + offset + source.size > sourceBase->getSize()) {
+ size_t totalSize = 0;
+ if (__builtin_add_overflow(source.offset, offset, &totalSize) ||
+ __builtin_add_overflow(totalSize, source.size, &totalSize) ||
+ totalSize > sourceBase->getSize()) {
+ android_errorWriteLog(0x534e4554, "176496160");
_hidl_cb(Status_V1_2::ERROR_DRM_CANNOT_HANDLE, 0, "invalid buffer size");
return Void();
}
diff --git a/media/codec2/core/include/C2Config.h b/media/codec2/core/include/C2Config.h
index 38f7389..752140a 100644
--- a/media/codec2/core/include/C2Config.h
+++ b/media/codec2/core/include/C2Config.h
@@ -151,6 +151,7 @@
/* protected content */
kParamIndexSecureMode,
+ kParamIndexEncryptedBuffer, // info-buffer, used with SM_READ_PROTECTED_WITH_ENCRYPTED
// deprecated
kParamIndexDelayRequest = kParamIndexDelay | C2Param::CoreIndex::IS_REQUEST_FLAG,
@@ -221,6 +222,7 @@
kParamIndexDrcEffectType, // drc, enum
kParamIndexDrcOutputLoudness, // drc, float (dBFS)
kParamIndexDrcAlbumMode, // drc, enum
+ kParamIndexAudioFrameSize, // int
/* ============================== platform-defined parameters ============================== */
@@ -1144,6 +1146,8 @@
C2ENUM(C2Config::secure_mode_t, uint32_t,
SM_UNPROTECTED, ///< no content protection
SM_READ_PROTECTED, ///< input and output buffers shall be protected from reading
+ /// both read protected and readable encrypted buffers are used
+ SM_READ_PROTECTED_WITH_ENCRYPTED,
)
typedef C2GlobalParam<C2Tuning, C2SimpleValueStruct<C2Config::secure_mode_t>, kParamIndexSecureMode>
@@ -1969,9 +1973,20 @@
/**
* DRC output loudness in dBFS. Retrieved during decoding
*/
- typedef C2StreamParam<C2Info, C2FloatValue, kParamIndexDrcOutputLoudness>
+typedef C2StreamParam<C2Info, C2FloatValue, kParamIndexDrcOutputLoudness>
C2StreamDrcOutputLoudnessTuning;
- constexpr char C2_PARAMKEY_DRC_OUTPUT_LOUDNESS[] = "output.drc.output-loudness";
+constexpr char C2_PARAMKEY_DRC_OUTPUT_LOUDNESS[] = "output.drc.output-loudness";
+
+/**
+ * Audio frame size in samples.
+ *
+ * Audio encoders can expose this parameter to signal the desired audio frame
+ * size that corresponds to a single coded access unit.
+ * Default value is 0, meaning that the encoder accepts input buffers of any size.
+ */
+typedef C2StreamParam<C2Info, C2Uint32Value, kParamIndexAudioFrameSize>
+ C2StreamAudioFrameSizeInfo;
+constexpr char C2_PARAMKEY_AUDIO_FRAME_SIZE[] = "raw.audio-frame-size";
/* --------------------------------------- AAC components --------------------------------------- */
diff --git a/media/codec2/hidl/1.0/utils/types.cpp b/media/codec2/hidl/1.0/utils/types.cpp
index 1f0c856..72f7c43 100644
--- a/media/codec2/hidl/1.0/utils/types.cpp
+++ b/media/codec2/hidl/1.0/utils/types.cpp
@@ -895,13 +895,12 @@
BufferPoolSender* bufferPoolSender,
std::list<BaseBlock>* baseBlocks,
std::map<const void*, uint32_t>* baseBlockIndices) {
- // TODO: C2InfoBuffer is not implemented.
- (void)d;
- (void)s;
- (void)bufferPoolSender;
- (void)baseBlocks;
- (void)baseBlockIndices;
- LOG(INFO) << "InfoBuffer not implemented.";
+ d->index = static_cast<ParamIndex>(s.index());
+ Buffer& dBuffer = d->buffer;
+ if (!objcpy(&dBuffer, s.data(), bufferPoolSender, baseBlocks, baseBlockIndices)) {
+ LOG(ERROR) << "Invalid C2InfoBuffer::data";
+ return false;
+ }
return true;
}
@@ -1336,6 +1335,68 @@
return true;
}
+// InfoBuffer -> C2InfoBuffer
+bool objcpy(std::vector<C2InfoBuffer> *d, const InfoBuffer& s,
+ const std::vector<C2BaseBlock>& baseBlocks) {
+
+ // Currently, a non-null C2InfoBufer must contain exactly 1 block.
+ if (s.buffer.blocks.size() == 0) {
+ return true;
+ } else if (s.buffer.blocks.size() != 1) {
+ LOG(ERROR) << "Invalid InfoBuffer::Buffer "
+ "Currently, a C2InfoBuffer must contain exactly 1 block.";
+ return false;
+ }
+
+ const Block &sBlock = s.buffer.blocks[0];
+ if (sBlock.index >= baseBlocks.size()) {
+ LOG(ERROR) << "Invalid InfoBuffer::Buffer::blocks[0].index: "
+ "Array index out of range.";
+ return false;
+ }
+ const C2BaseBlock &baseBlock = baseBlocks[sBlock.index];
+
+ // Parse meta.
+ std::vector<C2Param*> sBlockMeta;
+ if (!parseParamsBlob(&sBlockMeta, sBlock.meta)) {
+ LOG(ERROR) << "Invalid InfoBuffer::Buffer::blocks[0].meta.";
+ return false;
+ }
+
+ // Copy fence.
+ C2Fence dFence;
+ if (!objcpy(&dFence, sBlock.fence)) {
+ LOG(ERROR) << "Invalid InfoBuffer::Buffer::blocks[0].fence.";
+ return false;
+ }
+
+ // Construct a block.
+ switch (baseBlock.type) {
+ case C2BaseBlock::LINEAR:
+ if (sBlockMeta.size() == 1 && sBlockMeta[0] != nullptr &&
+ sBlockMeta[0]->size() == sizeof(C2Hidl_RangeInfo)) {
+ C2Hidl_RangeInfo *rangeInfo =
+ reinterpret_cast<C2Hidl_RangeInfo*>(sBlockMeta[0]);
+ d->emplace_back(C2InfoBuffer::CreateLinearBuffer(
+ s.index,
+ baseBlock.linear->share(
+ rangeInfo->offset, rangeInfo->length, dFence)));
+ return true;
+ }
+ LOG(ERROR) << "Invalid Meta for C2BaseBlock::Linear InfoBuffer.";
+ break;
+ case C2BaseBlock::GRAPHIC:
+ // It's not used now
+ LOG(ERROR) << "Non-Used C2BaseBlock::type for InfoBuffer.";
+ break;
+ default:
+ LOG(ERROR) << "Invalid C2BaseBlock::type for InfoBuffer.";
+ break;
+ }
+
+ return false;
+}
+
// FrameData -> C2FrameData
bool objcpy(C2FrameData* d, const FrameData& s,
const std::vector<C2BaseBlock>& baseBlocks) {
@@ -1370,8 +1431,18 @@
}
}
- // TODO: Implement this once C2InfoBuffer has constructors.
d->infoBuffers.clear();
+ if (s.infoBuffers.size() == 0) {
+ // InfoBuffer is optional
+ return true;
+ }
+ d->infoBuffers.reserve(s.infoBuffers.size());
+ for (const InfoBuffer &sInfoBuffer: s.infoBuffers) {
+ if (!objcpy(&(d->infoBuffers), sInfoBuffer, baseBlocks)) {
+ LOG(ERROR) << "Invalid Framedata::infoBuffers.";
+ return false;
+ }
+ }
return true;
}
diff --git a/media/codec2/sfplugin/CCodecBufferChannel.cpp b/media/codec2/sfplugin/CCodecBufferChannel.cpp
index 96af7cb..813d85b 100644
--- a/media/codec2/sfplugin/CCodecBufferChannel.cpp
+++ b/media/codec2/sfplugin/CCodecBufferChannel.cpp
@@ -143,7 +143,8 @@
mFrameIndex(0u),
mFirstValidFrameIndex(0u),
mMetaMode(MODE_NONE),
- mInputMetEos(false) {
+ mInputMetEos(false),
+ mSendEncryptedInfoBuffer(false) {
mOutputSurface.lock()->maxDequeueBuffers = kSmoothnessFactor + kRenderingDepth;
{
Mutexed<Input>::Locked input(mInput);
@@ -192,7 +193,10 @@
return mInputSurface->signalEndOfInputStream();
}
-status_t CCodecBufferChannel::queueInputBufferInternal(sp<MediaCodecBuffer> buffer) {
+status_t CCodecBufferChannel::queueInputBufferInternal(
+ sp<MediaCodecBuffer> buffer,
+ std::shared_ptr<C2LinearBlock> encryptedBlock,
+ size_t blockSize) {
int64_t timeUs;
CHECK(buffer->meta()->findInt64("timeUs", &timeUs));
@@ -258,6 +262,11 @@
output->rotation[queuedFrameIndex] = rotation;
}
work->input.buffers.push_back(c2buffer);
+ if (encryptedBlock) {
+ work->input.infoBuffers.emplace_back(C2InfoBuffer::CreateLinearBuffer(
+ kParamIndexEncryptedBuffer,
+ encryptedBlock->share(0, blockSize, C2Fence())));
+ }
queuedBuffers.push_back(c2buffer);
} else if (eos) {
flags |= C2FrameData::FLAG_END_OF_STREAM;
@@ -526,6 +535,40 @@
}
sp<EncryptedLinearBlockBuffer> encryptedBuffer((EncryptedLinearBlockBuffer *)buffer.get());
+ std::shared_ptr<C2LinearBlock> block;
+ size_t allocSize = buffer->size();
+ size_t bufferSize = 0;
+ c2_status_t blockRes = C2_OK;
+ bool copied = false;
+ if (mSendEncryptedInfoBuffer) {
+ static const C2MemoryUsage kDefaultReadWriteUsage{
+ C2MemoryUsage::CPU_READ, C2MemoryUsage::CPU_WRITE};
+ constexpr int kAllocGranule0 = 1024 * 64;
+ constexpr int kAllocGranule1 = 1024 * 1024;
+ std::shared_ptr<C2BlockPool> pool = mBlockPools.lock()->inputPool;
+ // round up encrypted sizes to limit fragmentation and encourage buffer reuse
+ if (allocSize <= kAllocGranule1) {
+ bufferSize = align(allocSize, kAllocGranule0);
+ } else {
+ bufferSize = align(allocSize, kAllocGranule1);
+ }
+ blockRes = pool->fetchLinearBlock(
+ bufferSize, kDefaultReadWriteUsage, &block);
+
+ if (blockRes == C2_OK) {
+ C2WriteView view = block->map().get();
+ if (view.error() == C2_OK && view.size() == bufferSize) {
+ copied = true;
+ // TODO: only copy clear sections
+ memcpy(view.data(), buffer->data(), allocSize);
+ }
+ }
+ }
+
+ if (!copied) {
+ block.reset();
+ }
+
ssize_t result = -1;
ssize_t codecDataOffset = 0;
if (numSubSamples == 1
@@ -617,7 +660,8 @@
}
buffer->setRange(codecDataOffset, result - codecDataOffset);
- return queueInputBufferInternal(buffer);
+
+ return queueInputBufferInternal(buffer, block, bufferSize);
}
void CCodecBufferChannel::feedInputBufferIfAvailable() {
@@ -907,6 +951,7 @@
C2PortActualDelayTuning::input inputDelay(0);
C2PortActualDelayTuning::output outputDelay(0);
C2ActualPipelineDelayTuning pipelineDelay(0);
+ C2SecureModeTuning secureMode(C2Config::SM_UNPROTECTED);
c2_status_t err = mComponent->query(
{
@@ -917,6 +962,7 @@
&inputDelay,
&pipelineDelay,
&outputDelay,
+ &secureMode,
},
{},
C2_DONT_BLOCK,
@@ -939,6 +985,9 @@
// TODO: get this from input format
bool secure = mComponent->getName().find(".secure") != std::string::npos;
+ // secure mode is a static parameter (shall not change in the executing state)
+ mSendEncryptedInfoBuffer = secureMode.value == C2Config::SM_READ_PROTECTED_WITH_ENCRYPTED;
+
std::shared_ptr<C2AllocatorStore> allocatorStore = GetCodec2PlatformAllocatorStore();
int poolMask = GetCodec2PoolMask();
C2PlatformAllocatorStore::id_t preferredLinearId = GetPreferredLinearAllocatorId(poolMask);
diff --git a/media/codec2/sfplugin/CCodecBufferChannel.h b/media/codec2/sfplugin/CCodecBufferChannel.h
index 1ef21aa..4dc418a 100644
--- a/media/codec2/sfplugin/CCodecBufferChannel.h
+++ b/media/codec2/sfplugin/CCodecBufferChannel.h
@@ -238,7 +238,9 @@
void feedInputBufferIfAvailable();
void feedInputBufferIfAvailableInternal();
- status_t queueInputBufferInternal(sp<MediaCodecBuffer> buffer);
+ status_t queueInputBufferInternal(sp<MediaCodecBuffer> buffer,
+ std::shared_ptr<C2LinearBlock> encryptedBlock = nullptr,
+ size_t blockSize = 0);
bool handleWork(
std::unique_ptr<C2Work> work, const sp<AMessage> &outputFormat,
const C2StreamInitDataInfo::output *initData);
@@ -316,6 +318,7 @@
inline bool hasCryptoOrDescrambler() {
return mCrypto != nullptr || mDescrambler != nullptr;
}
+ std::atomic_bool mSendEncryptedInfoBuffer;
};
// Conversion of a c2_status_t value to a status_t value may depend on the
diff --git a/media/extractors/aac/AACExtractor.cpp b/media/extractors/aac/AACExtractor.cpp
index 8f60f6b..2fc4584 100644
--- a/media/extractors/aac/AACExtractor.cpp
+++ b/media/extractors/aac/AACExtractor.cpp
@@ -18,6 +18,8 @@
#define LOG_TAG "AACExtractor"
#include <utils/Log.h>
+#include <inttypes.h>
+
#include "AACExtractor.h"
#include <media/MediaExtractorPluginApi.h>
#include <media/stagefright/foundation/ABuffer.h>
@@ -277,7 +279,22 @@
ReadOptions::SeekMode mode;
if (options && options->getSeekTo(&seekTimeUs, &mode)) {
if (mFrameDurationUs > 0) {
- int64_t seekFrame = seekTimeUs / mFrameDurationUs;
+ int64_t seekFrame = 0;
+ switch(mode & 0x7) {
+ case ReadOptions::SEEK_NEXT_SYNC:
+ // "at or after"
+ seekFrame = (seekTimeUs + mFrameDurationUs - 1) / mFrameDurationUs;
+ break;
+ case ReadOptions::SEEK_CLOSEST_SYNC:
+ case ReadOptions::SEEK_CLOSEST:
+ seekFrame = (seekTimeUs + mFrameDurationUs/2) / mFrameDurationUs;
+ break;
+ case ReadOptions::SEEK_PREVIOUS_SYNC:
+ default:
+ // 'at or before'
+ seekFrame = seekTimeUs / mFrameDurationUs;
+ break;
+ }
if (seekFrame < 0 || seekFrame >= (int64_t)mOffsetVector.size()) {
android_errorWriteLog(0x534e4554, "70239507");
return AMEDIA_ERROR_MALFORMED;
diff --git a/media/extractors/amr/AMRExtractor.cpp b/media/extractors/amr/AMRExtractor.cpp
index 26431a4..e26ff0a 100644
--- a/media/extractors/amr/AMRExtractor.cpp
+++ b/media/extractors/amr/AMRExtractor.cpp
@@ -18,6 +18,8 @@
#define LOG_TAG "AMRExtractor"
#include <utils/Log.h>
+#include <inttypes.h>
+
#include "AMRExtractor.h"
#include <media/stagefright/foundation/ADebug.h>
@@ -283,8 +285,22 @@
ReadOptions::SeekMode mode;
if (mOffsetTableLength > 0 && options && options->getSeekTo(&seekTimeUs, &mode)) {
size_t size;
- int64_t seekFrame = seekTimeUs / 20000LL; // 20ms per frame.
- mCurrentTimeUs = seekFrame * 20000LL;
+ const int64_t frameDurationUs = 20000LL; // 20ms per frame.
+ int64_t seekFrame = 0;
+ switch(mode & 0x7) {
+ case ReadOptions::SEEK_NEXT_SYNC:
+ seekFrame = (seekTimeUs + frameDurationUs - 1) / frameDurationUs;
+ break;
+ case ReadOptions::SEEK_CLOSEST_SYNC:
+ case ReadOptions::SEEK_CLOSEST:
+ seekFrame = (seekTimeUs + frameDurationUs/2) / frameDurationUs;
+ break;
+ case ReadOptions::SEEK_PREVIOUS_SYNC:
+ default:
+ seekFrame = seekTimeUs / frameDurationUs;
+ break;
+ }
+ mCurrentTimeUs = seekFrame * frameDurationUs;
size_t index = seekFrame < 0 ? 0 : seekFrame / 50;
if (index >= mOffsetTableLength) {
diff --git a/media/extractors/tests/ExtractorUnitTest.cpp b/media/extractors/tests/ExtractorUnitTest.cpp
index d91fffa..84ec1f2 100644
--- a/media/extractors/tests/ExtractorUnitTest.cpp
+++ b/media/extractors/tests/ExtractorUnitTest.cpp
@@ -18,6 +18,8 @@
#define LOG_TAG "ExtractorUnitTest"
#include <utils/Log.h>
+#include <inttypes.h>
+
#include <datasource/FileSource.h>
#include <media/stagefright/MediaBufferGroup.h>
#include <media/stagefright/MediaCodecConstants.h>
@@ -503,7 +505,7 @@
&trackSampleRate));
ASSERT_EQ(exChannelCount, trackChannelCount) << "ChannelCount not as expected";
ASSERT_EQ(exSampleRate, trackSampleRate) << "SampleRate not as expected";
- } else {
+ } else if (!strncmp(extractorMime, "video/", 6)) {
int32_t exWidth, exHeight;
int32_t trackWidth, trackHeight;
ASSERT_TRUE(AMediaFormat_getInt32(extractorFormat, AMEDIAFORMAT_KEY_WIDTH, &exWidth));
@@ -512,6 +514,8 @@
ASSERT_TRUE(AMediaFormat_getInt32(trackFormat, AMEDIAFORMAT_KEY_HEIGHT, &trackHeight));
ASSERT_EQ(exWidth, trackWidth) << "Width not as expected";
ASSERT_EQ(exHeight, trackHeight) << "Height not as expected";
+ } else {
+ ALOGV("non a/v track");
}
status = cTrack->stop(track);
ASSERT_EQ(OK, status) << "Failed to stop the track";
@@ -568,8 +572,9 @@
TEST_P(ExtractorFunctionalityTest, SeekTest) {
if (mDisableTest) return;
- ALOGV("Validates %s Extractor behaviour for different seek modes", mContainer.c_str());
string inputFileName = gEnv->getRes() + get<1>(GetParam());
+ ALOGV("Validates %s Extractor behaviour for different seek modes filename %s",
+ mContainer.c_str(), inputFileName.c_str());
int32_t status = setDataSource(inputFileName);
ASSERT_EQ(status, 0) << "SetDataSource failed for" << mContainer << "extractor";
@@ -680,7 +685,8 @@
if (seekIdx >= seekablePointsSize) seekIdx = seekablePointsSize - 1;
int64_t seekToTimeStamp = seekablePoints[seekIdx];
- if (seekablePointsSize > 1) {
+ if (seekIdx > 1) {
+ // pick a time just earlier than this seek point
int64_t prevTimeStamp = seekablePoints[seekIdx - 1];
seekToTimeStamp = seekToTimeStamp - ((seekToTimeStamp - prevTimeStamp) >> 3);
}
@@ -711,11 +717,7 @@
// CMediaTrackReadOptions::SEEK is 8. Using mask 0111b to get true modes
switch (mode & 0x7) {
case CMediaTrackReadOptions::SEEK_PREVIOUS_SYNC:
- if (seekablePointsSize == 1) {
- EXPECT_EQ(timeStamp, seekablePoints[seekIdx]);
- } else {
- EXPECT_EQ(timeStamp, seekablePoints[seekIdx - 1]);
- }
+ EXPECT_EQ(timeStamp, seekablePoints[seekIdx > 0 ? (seekIdx - 1) : 0]);
break;
case CMediaTrackReadOptions::SEEK_NEXT_SYNC:
case CMediaTrackReadOptions::SEEK_CLOSEST_SYNC:
@@ -743,8 +745,9 @@
// TODO(b/155630778): Enable test for wav extractors
if (mExtractorName == WAV) return;
- ALOGV("Validates %s Extractor behaviour for invalid seek points", mContainer.c_str());
string inputFileName = gEnv->getRes() + get<1>(GetParam());
+ ALOGV("Validates %s Extractor behaviour for invalid seek points, filename %s",
+ mContainer.c_str(), inputFileName.c_str());
int32_t status = setDataSource(inputFileName);
ASSERT_EQ(status, 0) << "SetDataSource failed for" << mContainer << "extractor";
@@ -832,8 +835,9 @@
// TODO(b/155626946): Enable test for MPEG2 TS/PS extractors
if (mExtractorName == MPEG2TS || mExtractorName == MPEG2PS) return;
- ALOGV("Validates %s Extractor behaviour for invalid tracks", mContainer.c_str());
string inputFileName = gEnv->getRes() + get<1>(GetParam());
+ ALOGV("Validates %s Extractor behaviour for invalid tracks - file %s",
+ mContainer.c_str(), inputFileName.c_str());
int32_t status = setDataSource(inputFileName);
ASSERT_EQ(status, 0) << "SetDataSource failed for" << mContainer << "extractor";
@@ -872,13 +876,17 @@
TEST_P(ConfigParamTest, ConfigParamValidation) {
if (mDisableTest) return;
+ const int trackNumber = 0;
+
string container = GetParam().first;
- ALOGV("Validates %s Extractor for input's file properties", container.c_str());
string inputFileName = gEnv->getRes();
inputID inputFileId = GetParam().second;
configFormat configParam;
getFileProperties(inputFileId, inputFileName, configParam);
+ ALOGV("Validates %s Extractor for input's file properties, file %s",
+ container.c_str(), inputFileName.c_str());
+
int32_t status = setDataSource(inputFileName);
ASSERT_EQ(status, 0) << "SetDataSource failed for " << container << "extractor";
@@ -888,7 +896,7 @@
int32_t numTracks = mExtractor->countTracks();
ASSERT_GT(numTracks, 0) << "Extractor didn't find any track for the given clip";
- MediaTrackHelper *track = mExtractor->getTrack(0);
+ MediaTrackHelper *track = mExtractor->getTrack(trackNumber);
ASSERT_NE(track, nullptr) << "Failed to get track for index 0";
AMediaFormat *trackFormat = AMediaFormat_new();
@@ -910,7 +918,7 @@
AMediaFormat_getInt32(trackFormat, AMEDIAFORMAT_KEY_SAMPLE_RATE, &trackSampleRate));
ASSERT_EQ(configParam.sampleRate, trackSampleRate) << "SampleRate not as expected";
ASSERT_EQ(configParam.channelCount, trackChannelCount) << "ChannelCount not as expected";
- } else {
+ } else if (!strncmp(trackMime, "video/", 6)) {
int32_t trackWidth, trackHeight;
ASSERT_TRUE(AMediaFormat_getInt32(trackFormat, AMEDIAFORMAT_KEY_WIDTH, &trackWidth));
ASSERT_TRUE(AMediaFormat_getInt32(trackFormat, AMEDIAFORMAT_KEY_HEIGHT, &trackHeight));
diff --git a/media/libaudioclient/AudioSystem.cpp b/media/libaudioclient/AudioSystem.cpp
index 5ce5974..14578d6 100644
--- a/media/libaudioclient/AudioSystem.cpp
+++ b/media/libaudioclient/AudioSystem.cpp
@@ -980,12 +980,14 @@
legacy2aidl_audio_config_t_AudioConfig(*config));
int32_t flagsAidl = VALUE_OR_RETURN_STATUS(
legacy2aidl_audio_output_flags_t_int32_t_mask(flags));
+ int32_t selectedDeviceIdAidl = VALUE_OR_RETURN_STATUS(
+ legacy2aidl_audio_port_handle_t_int32_t(*selectedDeviceId));
media::GetOutputForAttrResponse responseAidl;
RETURN_STATUS_IF_ERROR(statusTFromBinderStatus(
aps->getOutputForAttr(attrAidl, sessionAidl, pidAidl, uidAidl, configAidl, flagsAidl,
- &responseAidl)));
+ selectedDeviceIdAidl, &responseAidl)));
*output = VALUE_OR_RETURN_STATUS(
aidl2legacy_int32_t_audio_io_handle_t(responseAidl.output));
@@ -1077,12 +1079,15 @@
media::AudioConfigBase configAidl = VALUE_OR_RETURN_STATUS(
legacy2aidl_audio_config_base_t_AudioConfigBase(*config));
int32_t flagsAidl = VALUE_OR_RETURN_STATUS(legacy2aidl_audio_input_flags_t_int32_t_mask(flags));
+ int32_t selectedDeviceIdAidl = VALUE_OR_RETURN_STATUS(
+ legacy2aidl_audio_port_handle_t_int32_t(*selectedDeviceId));
media::GetInputForAttrResponse response;
RETURN_STATUS_IF_ERROR(statusTFromBinderStatus(
aps->getInputForAttr(attrAidl, inputAidl, riidAidl, sessionAidl, pidAidl, uidAidl,
- opPackageNameAidl, configAidl, flagsAidl, &response)));
+ opPackageNameAidl, configAidl, flagsAidl, selectedDeviceIdAidl,
+ &response)));
*input = VALUE_OR_RETURN_STATUS(aidl2legacy_int32_t_audio_io_handle_t(response.input));
*selectedDeviceId = VALUE_OR_RETURN_STATUS(
diff --git a/media/libaudioclient/aidl/android/media/IAudioPolicyService.aidl b/media/libaudioclient/aidl/android/media/IAudioPolicyService.aidl
index f3a086d..75dfc36 100644
--- a/media/libaudioclient/aidl/android/media/IAudioPolicyService.aidl
+++ b/media/libaudioclient/aidl/android/media/IAudioPolicyService.aidl
@@ -83,7 +83,8 @@
int /* pid_t */ pid,
int /* uid_t */ uid,
in AudioConfig config,
- int /* Bitmask, indexed by AudioOutputFlags */ flags);
+ int /* Bitmask, indexed by AudioOutputFlags */ flags,
+ int /* audio_port_handle_t */ selectedDeviceId);
void startOutput(int /* audio_port_handle_t */ portId);
@@ -99,7 +100,9 @@
int /* uid_t */ uid,
@utf8InCpp String opPackageName,
in AudioConfigBase config,
- int /* Bitmask, indexed by AudioInputFlags */ flags);
+ int /* Bitmask, indexed by AudioInputFlags */ flags,
+ int /* audio_port_handle_t */ selectedDeviceId);
+
void startInput(int /* audio_port_handle_t */ portId);
diff --git a/media/libaudiohal/Android.bp b/media/libaudiohal/Android.bp
index d9a7804..6b1b90a 100644
--- a/media/libaudiohal/Android.bp
+++ b/media/libaudiohal/Android.bp
@@ -14,11 +14,10 @@
],
required: [
- "libaudiohal@2.0",
"libaudiohal@4.0",
"libaudiohal@5.0",
"libaudiohal@6.0",
-// "libaudiohal@7.0",
+ "libaudiohal@7.0",
],
shared_libs: [
diff --git a/media/libaudiohal/FactoryHalHidl.cpp b/media/libaudiohal/FactoryHalHidl.cpp
index 7228b22..e420d07 100644
--- a/media/libaudiohal/FactoryHalHidl.cpp
+++ b/media/libaudiohal/FactoryHalHidl.cpp
@@ -35,7 +35,6 @@
"6.0",
"5.0",
"4.0",
- "2.0",
nullptr
};
diff --git a/media/libaudiohal/impl/Android.bp b/media/libaudiohal/impl/Android.bp
index fe47881..3727404 100644
--- a/media/libaudiohal/impl/Android.bp
+++ b/media/libaudiohal/impl/Android.bp
@@ -54,29 +54,15 @@
}
cc_library_shared {
- name: "libaudiohal@2.0",
- defaults: ["libaudiohal_default"],
- shared_libs: [
- "android.hardware.audio.common@2.0",
- "android.hardware.audio.common@2.0-util",
- "android.hardware.audio.effect@2.0",
- "android.hardware.audio@2.0",
- ],
- cflags: [
- "-DMAJOR_VERSION=2",
- "-DMINOR_VERSION=0",
- "-include common/all-versions/VersionMacro.h",
- ]
-}
-
-cc_library_shared {
name: "libaudiohal@4.0",
defaults: ["libaudiohal_default"],
shared_libs: [
"android.hardware.audio.common@4.0",
"android.hardware.audio.common@4.0-util",
"android.hardware.audio.effect@4.0",
+ "android.hardware.audio.effect@4.0-util",
"android.hardware.audio@4.0",
+ "android.hardware.audio@4.0-util",
],
cflags: [
"-DMAJOR_VERSION=4",
@@ -92,7 +78,9 @@
"android.hardware.audio.common@5.0",
"android.hardware.audio.common@5.0-util",
"android.hardware.audio.effect@5.0",
+ "android.hardware.audio.effect@5.0-util",
"android.hardware.audio@5.0",
+ "android.hardware.audio@5.0-util",
],
cflags: [
"-DMAJOR_VERSION=5",
@@ -108,7 +96,9 @@
"android.hardware.audio.common@6.0",
"android.hardware.audio.common@6.0-util",
"android.hardware.audio.effect@6.0",
+ "android.hardware.audio.effect@6.0-util",
"android.hardware.audio@6.0",
+ "android.hardware.audio@6.0-util",
],
cflags: [
"-DMAJOR_VERSION=6",
@@ -118,14 +108,15 @@
}
cc_library_shared {
- enabled: false,
name: "libaudiohal@7.0",
defaults: ["libaudiohal_default"],
shared_libs: [
"android.hardware.audio.common@7.0",
"android.hardware.audio.common@7.0-util",
"android.hardware.audio.effect@7.0",
+ "android.hardware.audio.effect@7.0-util",
"android.hardware.audio@7.0",
+ "android.hardware.audio@7.0-util",
],
cflags: [
"-DMAJOR_VERSION=7",
@@ -133,4 +124,3 @@
"-include common/all-versions/VersionMacro.h",
]
}
-
diff --git a/media/libaudiohal/impl/ConversionHelperHidl.cpp b/media/libaudiohal/impl/ConversionHelperHidl.cpp
index 2927936..32eaa31 100644
--- a/media/libaudiohal/impl/ConversionHelperHidl.cpp
+++ b/media/libaudiohal/impl/ConversionHelperHidl.cpp
@@ -120,129 +120,5 @@
ALOGE("%s %p %s: %s (from rpc)", mClassName, this, funcName, description);
}
-#if MAJOR_VERSION >= 4
-// TODO: Use the same implementation in the hal when it moves to a util library.
-static std::string deviceAddressToHal(const DeviceAddress& address) {
- // HAL assumes that the address is NUL-terminated.
- char halAddress[AUDIO_DEVICE_MAX_ADDRESS_LEN];
- memset(halAddress, 0, sizeof(halAddress));
- audio_devices_t halDevice = static_cast<audio_devices_t>(address.device);
- if (getAudioDeviceOutAllA2dpSet().count(halDevice) > 0 ||
- halDevice == AUDIO_DEVICE_IN_BLUETOOTH_A2DP) {
- snprintf(halAddress, sizeof(halAddress), "%02X:%02X:%02X:%02X:%02X:%02X",
- address.address.mac[0], address.address.mac[1], address.address.mac[2],
- address.address.mac[3], address.address.mac[4], address.address.mac[5]);
- } else if (halDevice == AUDIO_DEVICE_OUT_IP || halDevice == AUDIO_DEVICE_IN_IP) {
- snprintf(halAddress, sizeof(halAddress), "%d.%d.%d.%d", address.address.ipv4[0],
- address.address.ipv4[1], address.address.ipv4[2], address.address.ipv4[3]);
- } else if (getAudioDeviceOutAllUsbSet().count(halDevice) > 0 ||
- getAudioDeviceInAllUsbSet().count(halDevice) > 0) {
- snprintf(halAddress, sizeof(halAddress), "card=%d;device=%d", address.address.alsa.card,
- address.address.alsa.device);
- } else if (halDevice == AUDIO_DEVICE_OUT_BUS || halDevice == AUDIO_DEVICE_IN_BUS) {
- snprintf(halAddress, sizeof(halAddress), "%s", address.busAddress.c_str());
- } else if (halDevice == AUDIO_DEVICE_OUT_REMOTE_SUBMIX ||
- halDevice == AUDIO_DEVICE_IN_REMOTE_SUBMIX) {
- snprintf(halAddress, sizeof(halAddress), "%s", address.rSubmixAddress.c_str());
- } else {
- snprintf(halAddress, sizeof(halAddress), "%s", address.busAddress.c_str());
- }
- return halAddress;
-}
-
-//local conversion helpers
-
-static audio_microphone_channel_mapping_t channelMappingToHal(AudioMicrophoneChannelMapping mapping) {
- switch (mapping) {
- case AudioMicrophoneChannelMapping::UNUSED:
- return AUDIO_MICROPHONE_CHANNEL_MAPPING_UNUSED;
- case AudioMicrophoneChannelMapping::DIRECT:
- return AUDIO_MICROPHONE_CHANNEL_MAPPING_DIRECT;
- case AudioMicrophoneChannelMapping::PROCESSED:
- return AUDIO_MICROPHONE_CHANNEL_MAPPING_PROCESSED;
- default:
- LOG_ALWAYS_FATAL("Unknown channelMappingToHal conversion %d", mapping);
- }
-}
-
-static audio_microphone_location_t locationToHal(AudioMicrophoneLocation location) {
- switch (location) {
- case AudioMicrophoneLocation::UNKNOWN:
- return AUDIO_MICROPHONE_LOCATION_UNKNOWN;
- case AudioMicrophoneLocation::MAINBODY:
- return AUDIO_MICROPHONE_LOCATION_MAINBODY;
- case AudioMicrophoneLocation::MAINBODY_MOVABLE:
- return AUDIO_MICROPHONE_LOCATION_MAINBODY_MOVABLE;
- case AudioMicrophoneLocation::PERIPHERAL:
- return AUDIO_MICROPHONE_LOCATION_PERIPHERAL;
- default:
- LOG_ALWAYS_FATAL("Unknown locationToHal conversion %d", location);
- }
-}
-static audio_microphone_directionality_t directionalityToHal(AudioMicrophoneDirectionality dir) {
- switch (dir) {
- case AudioMicrophoneDirectionality::UNKNOWN:
- return AUDIO_MICROPHONE_DIRECTIONALITY_UNKNOWN;
- case AudioMicrophoneDirectionality::OMNI:
- return AUDIO_MICROPHONE_DIRECTIONALITY_OMNI;
- case AudioMicrophoneDirectionality::BI_DIRECTIONAL:
- return AUDIO_MICROPHONE_DIRECTIONALITY_BI_DIRECTIONAL;
- case AudioMicrophoneDirectionality::CARDIOID:
- return AUDIO_MICROPHONE_DIRECTIONALITY_CARDIOID;
- case AudioMicrophoneDirectionality::HYPER_CARDIOID:
- return AUDIO_MICROPHONE_DIRECTIONALITY_HYPER_CARDIOID;
- case AudioMicrophoneDirectionality::SUPER_CARDIOID:
- return AUDIO_MICROPHONE_DIRECTIONALITY_SUPER_CARDIOID;
- default:
- LOG_ALWAYS_FATAL("Unknown directionalityToHal conversion %d", dir);
- }
-}
-
-void microphoneInfoToHal(const MicrophoneInfo& src,
- audio_microphone_characteristic_t *pDst) {
- if (pDst != NULL) {
- snprintf(pDst->device_id, sizeof(pDst->device_id),
- "%s", src.deviceId.c_str());
- pDst->device = static_cast<audio_devices_t>(src.deviceAddress.device);
- snprintf(pDst->address, sizeof(pDst->address),
- "%s", deviceAddressToHal(src.deviceAddress).c_str());
- if (src.channelMapping.size() > AUDIO_CHANNEL_COUNT_MAX) {
- ALOGW("microphoneInfoToStruct found %zu channelMapping elements. Max expected is %d",
- src.channelMapping.size(), AUDIO_CHANNEL_COUNT_MAX);
- }
- size_t ch;
- for (ch = 0; ch < src.channelMapping.size() && ch < AUDIO_CHANNEL_COUNT_MAX; ch++) {
- pDst->channel_mapping[ch] = channelMappingToHal(src.channelMapping[ch]);
- }
- for (; ch < AUDIO_CHANNEL_COUNT_MAX; ch++) {
- pDst->channel_mapping[ch] = AUDIO_MICROPHONE_CHANNEL_MAPPING_UNUSED;
- }
- pDst->location = locationToHal(src.location);
- pDst->group = (audio_microphone_group_t)src.group;
- pDst->index_in_the_group = (unsigned int)src.indexInTheGroup;
- pDst->sensitivity = src.sensitivity;
- pDst->max_spl = src.maxSpl;
- pDst->min_spl = src.minSpl;
- pDst->directionality = directionalityToHal(src.directionality);
- pDst->num_frequency_responses = (unsigned int)src.frequencyResponse.size();
- if (pDst->num_frequency_responses > AUDIO_MICROPHONE_MAX_FREQUENCY_RESPONSES) {
- ALOGW("microphoneInfoToStruct found %d frequency responses. Max expected is %d",
- pDst->num_frequency_responses, AUDIO_MICROPHONE_MAX_FREQUENCY_RESPONSES);
- pDst->num_frequency_responses = AUDIO_MICROPHONE_MAX_FREQUENCY_RESPONSES;
- }
- for (size_t k = 0; k < pDst->num_frequency_responses; k++) {
- pDst->frequency_responses[0][k] = src.frequencyResponse[k].frequency;
- pDst->frequency_responses[1][k] = src.frequencyResponse[k].level;
- }
- pDst->geometric_location.x = src.position.x;
- pDst->geometric_location.y = src.position.y;
- pDst->geometric_location.z = src.position.z;
- pDst->orientation.x = src.orientation.x;
- pDst->orientation.y = src.orientation.y;
- pDst->orientation.z = src.orientation.z;
- }
-}
-#endif
-
} // namespace CPP_VERSION
} // namespace android
diff --git a/media/libaudiohal/impl/ConversionHelperHidl.h b/media/libaudiohal/impl/ConversionHelperHidl.h
index fb3bb9d..59122c7 100644
--- a/media/libaudiohal/impl/ConversionHelperHidl.h
+++ b/media/libaudiohal/impl/ConversionHelperHidl.h
@@ -82,12 +82,6 @@
void emitError(const char* funcName, const char* description);
};
-#if MAJOR_VERSION >= 4
-using ::android::hardware::audio::CPP_VERSION::MicrophoneInfo;
-void microphoneInfoToHal(const MicrophoneInfo& src,
- audio_microphone_characteristic_t *pDst);
-#endif
-
} // namespace CPP_VERSION
} // namespace android
diff --git a/media/libaudiohal/impl/DeviceHalHidl.cpp b/media/libaudiohal/impl/DeviceHalHidl.cpp
index 0108816..a8fbe58 100644
--- a/media/libaudiohal/impl/DeviceHalHidl.cpp
+++ b/media/libaudiohal/impl/DeviceHalHidl.cpp
@@ -19,22 +19,24 @@
#define LOG_TAG "DeviceHalHidl"
//#define LOG_NDEBUG 0
-#include PATH(android/hardware/audio/FILE_VERSION/IPrimaryDevice.h)
#include <cutils/native_handle.h>
#include <hwbinder/IPCThreadState.h>
#include <media/AudioContainers.h>
#include <utils/Log.h>
+#include PATH(android/hardware/audio/FILE_VERSION/IPrimaryDevice.h)
+#include <HidlUtils.h>
#include <common/all-versions/VersionUtils.h>
+#include <util/CoreUtils.h>
#include "DeviceHalHidl.h"
#include "EffectHalHidl.h"
-#include "HidlUtils.h"
+#include "ParameterUtils.h"
#include "StreamHalHidl.h"
-#include "VersionUtils.h"
using ::android::hardware::audio::common::CPP_VERSION::implementation::HidlUtils;
using ::android::hardware::audio::common::utils::EnumBitfield;
+using ::android::hardware::audio::CPP_VERSION::implementation::CoreUtils;
using ::android::hardware::hidl_string;
using ::android::hardware::hidl_vec;
@@ -46,50 +48,6 @@
using EffectHalHidl = ::android::effect::CPP_VERSION::EffectHalHidl;
-namespace {
-
-using ::android::hardware::audio::common::CPP_VERSION::AudioPort;
-using ::android::hardware::audio::common::CPP_VERSION::AudioPortConfig;
-
-status_t deviceAddressFromHal(
- audio_devices_t device, const char* halAddress, DeviceAddress* address) {
- address->device = AudioDevice(device);
-
- if (halAddress == nullptr || strnlen(halAddress, AUDIO_DEVICE_MAX_ADDRESS_LEN) == 0) {
- return OK;
- }
- if (getAudioDeviceOutAllA2dpSet().count(device) > 0
- || device == AUDIO_DEVICE_IN_BLUETOOTH_A2DP) {
- int status = sscanf(halAddress,
- "%hhX:%hhX:%hhX:%hhX:%hhX:%hhX",
- &address->address.mac[0], &address->address.mac[1], &address->address.mac[2],
- &address->address.mac[3], &address->address.mac[4], &address->address.mac[5]);
- return status == 6 ? OK : BAD_VALUE;
- } else if (device == AUDIO_DEVICE_OUT_IP || device == AUDIO_DEVICE_IN_IP) {
- int status = sscanf(halAddress,
- "%hhu.%hhu.%hhu.%hhu",
- &address->address.ipv4[0], &address->address.ipv4[1],
- &address->address.ipv4[2], &address->address.ipv4[3]);
- return status == 4 ? OK : BAD_VALUE;
- } else if (getAudioDeviceOutAllUsbSet().count(device) > 0
- || getAudioDeviceInAllUsbSet().count(device) > 0) {
- int status = sscanf(halAddress,
- "card=%d;device=%d",
- &address->address.alsa.card, &address->address.alsa.device);
- return status == 2 ? OK : BAD_VALUE;
- } else if (device == AUDIO_DEVICE_OUT_BUS || device == AUDIO_DEVICE_IN_BUS) {
- address->busAddress = halAddress;
- return OK;
- } else if (device == AUDIO_DEVICE_OUT_REMOTE_SUBMIX
- || device == AUDIO_DEVICE_IN_REMOTE_SUBMIX) {
- address->rSubmixAddress = halAddress;
- return OK;
- }
- return OK;
-}
-
-} // namespace
-
DeviceHalHidl::DeviceHalHidl(const sp<IDevice>& device)
: ConversionHelperHidl("Device"), mDevice(device),
mPrimaryDevice(IPrimaryDevice::castFrom(device)) {
@@ -237,16 +195,22 @@
sp<StreamOutHalInterface> *outStream) {
if (mDevice == 0) return NO_INIT;
DeviceAddress hidlDevice;
- status_t status = deviceAddressFromHal(deviceType, address, &hidlDevice);
- if (status != OK) return status;
+ if (status_t status = CoreUtils::deviceAddressFromHal(deviceType, address, &hidlDevice);
+ status != OK) {
+ return status;
+ }
AudioConfig hidlConfig;
- HidlUtils::audioConfigFromHal(*config, false /*isInput*/, &hidlConfig);
+ if (status_t status = HidlUtils::audioConfigFromHal(*config, false /*isInput*/, &hidlConfig);
+ status != OK) {
+ return status;
+ }
+ CoreUtils::AudioOutputFlags hidlFlags;
+ if (status_t status = CoreUtils::audioOutputFlagsFromHal(flags, &hidlFlags); status != OK) {
+ return status;
+ }
Result retval = Result::NOT_INITIALIZED;
Return<void> ret = mDevice->openOutputStream(
- handle,
- hidlDevice,
- hidlConfig,
- EnumBitfield<AudioOutputFlag>(flags),
+ handle, hidlDevice, hidlConfig, hidlFlags,
#if MAJOR_VERSION >= 4
{} /* metadata */,
#endif
@@ -272,17 +236,30 @@
sp<StreamInHalInterface> *inStream) {
if (mDevice == 0) return NO_INIT;
DeviceAddress hidlDevice;
- status_t status = deviceAddressFromHal(devices, address, &hidlDevice);
- if (status != OK) return status;
+ if (status_t status = CoreUtils::deviceAddressFromHal(devices, address, &hidlDevice);
+ status != OK) {
+ return status;
+ }
AudioConfig hidlConfig;
- HidlUtils::audioConfigFromHal(*config, true /*isInput*/, &hidlConfig);
+ if (status_t status = HidlUtils::audioConfigFromHal(*config, true /*isInput*/, &hidlConfig);
+ status != OK) {
+ return status;
+ }
+ CoreUtils::AudioInputFlags hidlFlags;
+ if (status_t status = CoreUtils::audioInputFlagsFromHal(flags, &hidlFlags); status != OK) {
+ return status;
+ }
Result retval = Result::NOT_INITIALIZED;
#if MAJOR_VERSION == 2
auto sinkMetadata = AudioSource(source);
#elif MAJOR_VERSION >= 4
// TODO: correctly propagate the tracks sources and volume
// for now, only send the main source at 1dbfs
- SinkMetadata sinkMetadata = {{{ .source = AudioSource(source), .gain = 1 }}};
+ AudioSource hidlSource;
+ if (status_t status = HidlUtils::audioSourceFromHal(source, &hidlSource); status != OK) {
+ return status;
+ }
+ SinkMetadata sinkMetadata = {{{ .source = std::move(hidlSource), .gain = 1 }}};
#endif
#if MAJOR_VERSION < 5
(void)outputDevice;
@@ -290,8 +267,10 @@
#else
if (outputDevice != AUDIO_DEVICE_NONE) {
DeviceAddress hidlOutputDevice;
- status = deviceAddressFromHal(outputDevice, outputDeviceAddress, &hidlOutputDevice);
- if (status != OK) return status;
+ if (status_t status = CoreUtils::deviceAddressFromHal(
+ outputDevice, outputDeviceAddress, &hidlOutputDevice); status != OK) {
+ return status;
+ }
sinkMetadata.tracks[0].destination.device(std::move(hidlOutputDevice));
}
#endif
@@ -300,11 +279,7 @@
flags = static_cast<audio_input_flags_t>(flags & ~AUDIO_INPUT_FLAG_DIRECT);
#endif
Return<void> ret = mDevice->openInputStream(
- handle,
- hidlDevice,
- hidlConfig,
- EnumBitfield<AudioInputFlag>(flags),
- sinkMetadata,
+ handle, hidlDevice, hidlConfig, hidlFlags, sinkMetadata,
[&](Result r, const sp<IStreamIn>& result, const AudioConfig& suggestedConfig) {
retval = r;
if (retval == Result::OK) {
@@ -441,7 +416,7 @@
for (size_t k = 0; k < micArrayHal.size(); k++) {
audio_microphone_characteristic_t dst;
//convert
- microphoneInfoToHal(micArrayHal[k], &dst);
+ (void)CoreUtils::microphoneInfoToHal(micArrayHal[k], &dst);
media::MicrophoneInfo microphone = media::MicrophoneInfo(dst);
microphonesInfo->push_back(microphone);
}
diff --git a/media/libaudiohal/impl/EffectHalHidl.cpp b/media/libaudiohal/impl/EffectHalHidl.cpp
index 506feb8..c589a48 100644
--- a/media/libaudiohal/impl/EffectHalHidl.cpp
+++ b/media/libaudiohal/impl/EffectHalHidl.cpp
@@ -23,12 +23,13 @@
#include <media/EffectsFactoryApi.h>
#include <utils/Log.h>
+#include <util/EffectUtils.h>
+
#include "EffectBufferHalHidl.h"
#include "EffectHalHidl.h"
-#include "UuidUtils.h"
-using ::android::hardware::audio::common::CPP_VERSION::implementation::UuidUtils;
using ::android::hardware::audio::common::utils::EnumBitfield;
+using ::android::hardware::audio::effect::CPP_VERSION::implementation::EffectUtils;
using ::android::hardware::hidl_vec;
using ::android::hardware::MQDescriptorSync;
using ::android::hardware::Return;
@@ -42,6 +43,10 @@
EffectHalHidl::EffectHalHidl(const sp<IEffect>& effect, uint64_t effectId)
: mEffect(effect), mEffectId(effectId), mBuffersChanged(true), mEfGroup(nullptr) {
+ effect_descriptor_t halDescriptor{};
+ if (EffectHalHidl::getDescriptor(&halDescriptor) == NO_ERROR) {
+ mIsInput = (halDescriptor.flags & EFFECT_FLAG_TYPE_PRE_PROC) == EFFECT_FLAG_TYPE_PRE_PROC;
+ }
}
EffectHalHidl::~EffectHalHidl() {
@@ -56,59 +61,6 @@
}
// static
-void EffectHalHidl::effectDescriptorToHal(
- const EffectDescriptor& descriptor, effect_descriptor_t* halDescriptor) {
- UuidUtils::uuidToHal(descriptor.type, &halDescriptor->type);
- UuidUtils::uuidToHal(descriptor.uuid, &halDescriptor->uuid);
- halDescriptor->flags = static_cast<uint32_t>(descriptor.flags);
- halDescriptor->cpuLoad = descriptor.cpuLoad;
- halDescriptor->memoryUsage = descriptor.memoryUsage;
- memcpy(halDescriptor->name, descriptor.name.data(), descriptor.name.size());
- memcpy(halDescriptor->implementor,
- descriptor.implementor.data(), descriptor.implementor.size());
-}
-
-// TODO(mnaganov): These buffer conversion functions should be shared with Effect wrapper
-// via HidlUtils. Move them there when hardware/interfaces will get un-frozen again.
-
-// static
-void EffectHalHidl::effectBufferConfigFromHal(
- const buffer_config_t& halConfig, EffectBufferConfig* config) {
- config->samplingRateHz = halConfig.samplingRate;
- config->channels = EnumBitfield<AudioChannelMask>(halConfig.channels);
- config->format = AudioFormat(halConfig.format);
- config->accessMode = EffectBufferAccess(halConfig.accessMode);
- config->mask = EnumBitfield<EffectConfigParameters>(halConfig.mask);
-}
-
-// static
-void EffectHalHidl::effectBufferConfigToHal(
- const EffectBufferConfig& config, buffer_config_t* halConfig) {
- halConfig->buffer.frameCount = 0;
- halConfig->buffer.raw = NULL;
- halConfig->samplingRate = config.samplingRateHz;
- halConfig->channels = static_cast<uint32_t>(config.channels);
- halConfig->bufferProvider.cookie = NULL;
- halConfig->bufferProvider.getBuffer = NULL;
- halConfig->bufferProvider.releaseBuffer = NULL;
- halConfig->format = static_cast<uint8_t>(config.format);
- halConfig->accessMode = static_cast<uint8_t>(config.accessMode);
- halConfig->mask = static_cast<uint8_t>(config.mask);
-}
-
-// static
-void EffectHalHidl::effectConfigFromHal(const effect_config_t& halConfig, EffectConfig* config) {
- effectBufferConfigFromHal(halConfig.inputCfg, &config->inputCfg);
- effectBufferConfigFromHal(halConfig.outputCfg, &config->outputCfg);
-}
-
-// static
-void EffectHalHidl::effectConfigToHal(const EffectConfig& config, effect_config_t* halConfig) {
- effectBufferConfigToHal(config.inputCfg, &halConfig->inputCfg);
- effectBufferConfigToHal(config.outputCfg, &halConfig->outputCfg);
-}
-
-// static
status_t EffectHalHidl::analyzeResult(const Result& result) {
switch (result) {
case Result::OK: return OK;
@@ -269,7 +221,7 @@
[&](Result r, const EffectDescriptor& result) {
retval = r;
if (retval == Result::OK) {
- effectDescriptorToHal(result, pDescriptor);
+ EffectUtils::effectDescriptorToHal(result, pDescriptor);
}
});
return ret.isOk() ? analyzeResult(retval) : FAILED_TRANSACTION;
@@ -301,14 +253,16 @@
ret = mEffect->getConfig([&] (Result r, const EffectConfig &hidlConfig) {
result = analyzeResult(r);
if (r == Result::OK) {
- effectConfigToHal(hidlConfig, static_cast<effect_config_t*>(pReplyData));
+ EffectUtils::effectConfigToHal(
+ hidlConfig, static_cast<effect_config_t*>(pReplyData));
}
});
} else {
ret = mEffect->getConfigReverse([&] (Result r, const EffectConfig &hidlConfig) {
result = analyzeResult(r);
if (r == Result::OK) {
- effectConfigToHal(hidlConfig, static_cast<effect_config_t*>(pReplyData));
+ EffectUtils::effectConfigToHal(
+ hidlConfig, static_cast<effect_config_t*>(pReplyData));
}
});
}
@@ -332,7 +286,7 @@
ALOGE("Buffer provider callbacks are not supported");
}
EffectConfig hidlConfig;
- effectConfigFromHal(*halConfig, &hidlConfig);
+ EffectUtils::effectConfigFromHal(*halConfig, mIsInput, &hidlConfig);
Return<Result> ret = cmdCode == EFFECT_CMD_SET_CONFIG ?
mEffect->setConfig(hidlConfig, nullptr, nullptr) :
mEffect->setConfigReverse(hidlConfig, nullptr, nullptr);
diff --git a/media/libaudiohal/impl/EffectHalHidl.h b/media/libaudiohal/impl/EffectHalHidl.h
index 1f238c0..8e46638 100644
--- a/media/libaudiohal/impl/EffectHalHidl.h
+++ b/media/libaudiohal/impl/EffectHalHidl.h
@@ -65,9 +65,6 @@
uint64_t effectId() const { return mEffectId; }
- static void effectDescriptorToHal(
- const EffectDescriptor& descriptor, effect_descriptor_t* halDescriptor);
-
private:
friend class EffectsFactoryHalHidl;
typedef MessageQueue<Result, hardware::kSynchronizedReadWrite> StatusMQ;
@@ -79,14 +76,9 @@
bool mBuffersChanged;
std::unique_ptr<StatusMQ> mStatusMQ;
EventFlag* mEfGroup;
+ bool mIsInput = false;
static status_t analyzeResult(const Result& result);
- static void effectBufferConfigFromHal(
- const buffer_config_t& halConfig, EffectBufferConfig* config);
- static void effectBufferConfigToHal(
- const EffectBufferConfig& config, buffer_config_t* halConfig);
- static void effectConfigFromHal(const effect_config_t& halConfig, EffectConfig* config);
- static void effectConfigToHal(const EffectConfig& config, effect_config_t* halConfig);
// Can not be constructed directly by clients.
EffectHalHidl(const sp<IEffect>& effect, uint64_t effectId);
diff --git a/media/libaudiohal/impl/EffectsFactoryHalHidl.cpp b/media/libaudiohal/impl/EffectsFactoryHalHidl.cpp
index 35ac332..9c4363c 100644
--- a/media/libaudiohal/impl/EffectsFactoryHalHidl.cpp
+++ b/media/libaudiohal/impl/EffectsFactoryHalHidl.cpp
@@ -19,13 +19,16 @@
#include <cutils/native_handle.h>
+#include <UuidUtils.h>
+#include <util/EffectUtils.h>
+
#include "ConversionHelperHidl.h"
#include "EffectBufferHalHidl.h"
#include "EffectHalHidl.h"
#include "EffectsFactoryHalHidl.h"
-#include "UuidUtils.h"
using ::android::hardware::audio::common::CPP_VERSION::implementation::UuidUtils;
+using ::android::hardware::audio::effect::CPP_VERSION::implementation::EffectUtils;
using ::android::hardware::Return;
namespace android {
@@ -76,7 +79,7 @@
if (queryResult != OK) return queryResult;
}
if (index >= mLastDescriptors.size()) return NAME_NOT_FOUND;
- EffectHalHidl::effectDescriptorToHal(mLastDescriptors[index], pDescriptor);
+ EffectUtils::effectDescriptorToHal(mLastDescriptors[index], pDescriptor);
return OK;
}
@@ -91,7 +94,7 @@
[&](Result r, const EffectDescriptor& result) {
retval = r;
if (retval == Result::OK) {
- EffectHalHidl::effectDescriptorToHal(result, pDescriptor);
+ EffectUtils::effectDescriptorToHal(result, pDescriptor);
}
});
if (ret.isOk()) {
diff --git a/media/libaudiohal/impl/VersionUtils.h b/media/libaudiohal/impl/ParameterUtils.h
similarity index 91%
rename from media/libaudiohal/impl/VersionUtils.h
rename to media/libaudiohal/impl/ParameterUtils.h
index eb0a42a..9cab72e 100644
--- a/media/libaudiohal/impl/VersionUtils.h
+++ b/media/libaudiohal/impl/ParameterUtils.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2018 The Android Open Source Project
+ * Copyright (C) 2021 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.
@@ -14,8 +14,7 @@
* limitations under the License.
*/
-#ifndef ANDROID_HARDWARE_VERSION_UTILS_H
-#define ANDROID_HARDWARE_VERSION_UTILS_H
+#pragma once
#include PATH(android/hardware/audio/FILE_VERSION/types.h)
#include <hidl/HidlSupport.h>
@@ -59,5 +58,3 @@
} // namespace utils
} // namespace CPP_VERSION
} // namespace android
-
-#endif // ANDROID_HARDWARE_VERSION_UTILS_H
diff --git a/media/libaudiohal/impl/StreamHalHidl.cpp b/media/libaudiohal/impl/StreamHalHidl.cpp
index 097bd12..2a3e2b6 100644
--- a/media/libaudiohal/impl/StreamHalHidl.cpp
+++ b/media/libaudiohal/impl/StreamHalHidl.cpp
@@ -17,18 +17,23 @@
#define LOG_TAG "StreamHalHidl"
//#define LOG_NDEBUG 0
-#include PATH(android/hardware/audio/FILE_VERSION/IStreamOutCallback.h)
+#include <android/hidl/manager/1.0/IServiceManager.h>
#include <hwbinder/IPCThreadState.h>
#include <media/AudioParameter.h>
#include <mediautils/SchedulingPolicyService.h>
#include <utils/Log.h>
+#include PATH(android/hardware/audio/FILE_VERSION/IStreamOutCallback.h)
+#include <HidlUtils.h>
+#include <util/CoreUtils.h>
+
#include "DeviceHalHidl.h"
#include "EffectHalHidl.h"
-#include "HidlUtils.h"
+#include "ParameterUtils.h"
#include "StreamHalHidl.h"
-#include "VersionUtils.h"
+using ::android::hardware::audio::common::CPP_VERSION::implementation::HidlUtils;
+using ::android::hardware::audio::CPP_VERSION::implementation::CoreUtils;
using ::android::hardware::MQDescriptorSync;
using ::android::hardware::Return;
using ::android::hardware::Void;
@@ -50,14 +55,11 @@
// Instrument audio signal power logging.
// Note: This assumes channel mask, format, and sample rate do not change after creation.
- if (mStream != nullptr /* && mStreamPowerLog.isUserDebugOrEngBuild() */) {
- // Obtain audio properties (see StreamHalHidl::getAudioProperties() below).
- Return<void> ret = mStream->getAudioProperties(
- [&](auto sr, auto m, auto f) {
- mStreamPowerLog.init(sr,
- static_cast<audio_channel_mask_t>(m),
- static_cast<audio_format_t>(f));
- });
+ audio_config_base_t config = AUDIO_CONFIG_BASE_INITIALIZER;
+ if (/* mStreamPowerLog.isUserDebugOrEngBuild() && */
+ StreamHalHidl::getAudioProperties(
+ &config.sample_rate, &config.channel_mask, &config.format) == NO_ERROR) {
+ mStreamPowerLog.init(config.sample_rate, config.channel_mask, config.format);
}
}
@@ -67,9 +69,12 @@
hardware::IPCThreadState::self()->flushCommands();
}
+// Note: this method will be removed
status_t StreamHalHidl::getSampleRate(uint32_t *rate) {
- if (!mStream) return NO_INIT;
- return processReturn("getSampleRate", mStream->getSampleRate(), rate);
+ audio_config_base_t config = AUDIO_CONFIG_BASE_INITIALIZER;
+ status_t status = getAudioProperties(&config.sample_rate, &config.channel_mask, &config.format);
+ *rate = config.sample_rate;
+ return status;
}
status_t StreamHalHidl::getBufferSize(size_t *size) {
@@ -81,19 +86,26 @@
return status;
}
+// Note: this method will be removed
status_t StreamHalHidl::getChannelMask(audio_channel_mask_t *mask) {
- if (!mStream) return NO_INIT;
- return processReturn("getChannelMask", mStream->getChannelMask(), mask);
+ audio_config_base_t config = AUDIO_CONFIG_BASE_INITIALIZER;
+ status_t status = getAudioProperties(&config.sample_rate, &config.channel_mask, &config.format);
+ *mask = config.channel_mask;
+ return status;
}
+// Note: this method will be removed
status_t StreamHalHidl::getFormat(audio_format_t *format) {
- if (!mStream) return NO_INIT;
- return processReturn("getFormat", mStream->getFormat(), format);
+ audio_config_base_t config = AUDIO_CONFIG_BASE_INITIALIZER;
+ status_t status = getAudioProperties(&config.sample_rate, &config.channel_mask, &config.format);
+ *format = config.format;
+ return status;
}
status_t StreamHalHidl::getAudioProperties(
uint32_t *sampleRate, audio_channel_mask_t *mask, audio_format_t *format) {
if (!mStream) return NO_INIT;
+#if MAJOR_VERSION <= 6
Return<void> ret = mStream->getAudioProperties(
[&](uint32_t sr, auto m, auto f) {
*sampleRate = sr;
@@ -101,6 +113,26 @@
*format = static_cast<audio_format_t>(f);
});
return processReturn("getAudioProperties", ret);
+#else
+ Result retval;
+ status_t conversionStatus = BAD_VALUE;
+ audio_config_base_t halConfig = AUDIO_CONFIG_BASE_INITIALIZER;
+ Return<void> ret = mStream->getAudioProperties(
+ [&](Result r, const AudioConfigBase& config) {
+ retval = r;
+ if (retval == Result::OK) {
+ conversionStatus = HidlUtils::audioConfigBaseToHal(config, &halConfig);
+ }
+ });
+ if (status_t status = processReturn("getAudioProperties", ret, retval); status == NO_ERROR) {
+ *sampleRate = halConfig.sample_rate;
+ *mask = halConfig.channel_mask;
+ *format = halConfig.format;
+ return conversionStatus;
+ } else {
+ return status;
+ }
+#endif
}
status_t StreamHalHidl::setParameters(const String8& kvPairs) {
@@ -228,6 +260,24 @@
return getBufferSize(size);
}
+status_t StreamHalHidl::getHalPid(pid_t *pid) {
+ using ::android::hidl::base::V1_0::DebugInfo;
+ using ::android::hidl::manager::V1_0::IServiceManager;
+
+ DebugInfo debugInfo;
+ auto ret = mStream->getDebugInfo([&] (const auto &info) {
+ debugInfo = info;
+ });
+ if (!ret.isOk()) {
+ return INVALID_OPERATION;
+ }
+ if (debugInfo.pid != (int)IServiceManager::PidConstant::NO_PID) {
+ *pid = debugInfo.pid;
+ return NO_ERROR;
+ }
+ return NAME_NOT_FOUND;
+}
+
bool StreamHalHidl::requestHalThreadPriority(pid_t threadPid, pid_t threadId) {
if (mHalThreadPriority == HAL_THREAD_PRIORITY_DEFAULT) {
return true;
@@ -454,7 +504,7 @@
const CommandMQ::Descriptor& commandMQ,
const DataMQ::Descriptor& dataMQ,
const StatusMQ::Descriptor& statusMQ,
- const ThreadInfo& halThreadInfo) {
+ const auto& halThreadInfo) {
retval = r;
if (retval == Result::OK) {
tempCommandMQ.reset(new CommandMQ(commandMQ));
@@ -463,8 +513,12 @@
if (tempDataMQ->isValid() && tempDataMQ->getEventFlagWord()) {
EventFlag::createEventFlag(tempDataMQ->getEventFlagWord(), &mEfGroup);
}
+#if MAJOR_VERSION <= 6
halThreadPid = halThreadInfo.pid;
halThreadTid = halThreadInfo.tid;
+#else
+ halThreadTid = halThreadInfo;
+#endif
}
});
if (!ret.isOk() || retval != Result::OK) {
@@ -485,6 +539,11 @@
ALOGE_IF(!mEfGroup, "Event flag creation for writing failed");
return NO_INIT;
}
+#if MAJOR_VERSION >= 7
+ if (status_t status = getHalPid(&halThreadPid); status != NO_ERROR) {
+ return status;
+ }
+#endif
requestHalThreadPriority(halThreadPid, halThreadTid);
mCommandMQ = std::move(tempCommandMQ);
@@ -598,40 +657,15 @@
return INVALID_OPERATION;
}
#elif MAJOR_VERSION >= 4
-/** Transform a standard collection to an HIDL vector. */
-template <class Values, class ElementConverter>
-static auto transformToHidlVec(const Values& values, ElementConverter converter) {
- hidl_vec<decltype(converter(*values.begin()))> result{values.size()};
- using namespace std;
- transform(begin(values), end(values), begin(result), converter);
- return result;
-}
-
status_t StreamOutHalHidl::updateSourceMetadata(
const StreamOutHalInterface::SourceMetadata& sourceMetadata) {
- CPP_VERSION::SourceMetadata halMetadata = {
- .tracks = transformToHidlVec(sourceMetadata.tracks,
- [](const playback_track_metadata_v7& metadata) -> PlaybackTrackMetadata {
- PlaybackTrackMetadata halTrackMetadata = {
- .usage=static_cast<AudioUsage>(metadata.base.usage),
- .contentType=static_cast<AudioContentType>(metadata.base.content_type),
- .gain=metadata.base.gain,
- };
-#if MAJOR_VERSION >= 7
- HidlUtils::audioChannelMaskFromHal(metadata.channel_mask, false /*isInput*/,
- &halTrackMetadata.channelMask);
-
- std::istringstream tags{metadata.tags};
- std::string tag;
- while (std::getline(tags, tag, HidlUtils::sAudioTagSeparator)) {
- if (!tag.empty()) {
- halTrackMetadata.tags.push_back(tag);
- }
- }
-#endif
- return halTrackMetadata;
- })};
- return processReturn("updateSourceMetadata", mStream->updateSourceMetadata(halMetadata));
+ CPP_VERSION::SourceMetadata hidlMetadata;
+ if (status_t status = CoreUtils::sourceMetadataFromHalV7(
+ sourceMetadata.tracks, true /*ignoreNonVendorTags*/, &hidlMetadata);
+ status != OK) {
+ return status;
+ }
+ return processReturn("updateSourceMetadata", mStream->updateSourceMetadata(hidlMetadata));
}
#endif
@@ -902,7 +936,7 @@
const CommandMQ::Descriptor& commandMQ,
const DataMQ::Descriptor& dataMQ,
const StatusMQ::Descriptor& statusMQ,
- const ThreadInfo& halThreadInfo) {
+ const auto& halThreadInfo) {
retval = r;
if (retval == Result::OK) {
tempCommandMQ.reset(new CommandMQ(commandMQ));
@@ -911,8 +945,12 @@
if (tempDataMQ->isValid() && tempDataMQ->getEventFlagWord()) {
EventFlag::createEventFlag(tempDataMQ->getEventFlagWord(), &mEfGroup);
}
+#if MAJOR_VERSION <= 6
halThreadPid = halThreadInfo.pid;
halThreadTid = halThreadInfo.tid;
+#else
+ halThreadTid = halThreadInfo;
+#endif
}
});
if (!ret.isOk() || retval != Result::OK) {
@@ -933,6 +971,11 @@
ALOGE_IF(!mEfGroup, "Event flag creation for reading failed");
return NO_INIT;
}
+#if MAJOR_VERSION >= 7
+ if (status_t status = getHalPid(&halThreadPid); status != NO_ERROR) {
+ return status;
+ }
+#endif
requestHalThreadPriority(halThreadPid, halThreadTid);
mCommandMQ = std::move(tempCommandMQ);
@@ -995,7 +1038,7 @@
for (size_t k = 0; k < micArrayHal.size(); k++) {
audio_microphone_characteristic_t dst;
// convert
- microphoneInfoToHal(micArrayHal[k], &dst);
+ (void)CoreUtils::microphoneInfoToHal(micArrayHal[k], &dst);
media::MicrophoneInfo microphone = media::MicrophoneInfo(dst);
microphonesInfo->push_back(microphone);
}
@@ -1005,27 +1048,13 @@
status_t StreamInHalHidl::updateSinkMetadata(const
StreamInHalInterface::SinkMetadata& sinkMetadata) {
- CPP_VERSION::SinkMetadata halMetadata = {
- .tracks = transformToHidlVec(sinkMetadata.tracks,
- [](const record_track_metadata_v7& metadata) -> RecordTrackMetadata {
- RecordTrackMetadata halTrackMetadata = {
- .source=static_cast<AudioSource>(metadata.base.source),
- .gain=metadata.base.gain,
- };
-#if MAJOR_VERSION >= 7
- HidlUtils::audioChannelMaskFromHal(metadata.channel_mask, true /*isInput*/,
- &halTrackMetadata.channelMask);
- std::istringstream tags{metadata.tags};
- std::string tag;
- while (std::getline(tags, tag, HidlUtils::sAudioTagSeparator)) {
- if (!tag.empty()) {
- halTrackMetadata.tags.push_back(tag);
- }
- }
-#endif
- return halTrackMetadata;
- })};
- return processReturn("updateSinkMetadata", mStream->updateSinkMetadata(halMetadata));
+ CPP_VERSION::SinkMetadata hidlMetadata;
+ if (status_t status = CoreUtils::sinkMetadataFromHalV7(
+ sinkMetadata.tracks, true /*ignoreNonVendorTags*/, &hidlMetadata);
+ status != OK) {
+ return status;
+ }
+ return processReturn("updateSinkMetadata", mStream->updateSinkMetadata(hidlMetadata));
}
#endif
diff --git a/media/libaudiohal/impl/StreamHalHidl.h b/media/libaudiohal/impl/StreamHalHidl.h
index 7dfc78f..c6db6d6 100644
--- a/media/libaudiohal/impl/StreamHalHidl.h
+++ b/media/libaudiohal/impl/StreamHalHidl.h
@@ -105,6 +105,8 @@
status_t getCachedBufferSize(size_t *size);
+ status_t getHalPid(pid_t *pid);
+
bool requestHalThreadPriority(pid_t threadPid, pid_t threadId);
// mStreamPowerLog is used for audio signal power logging.
diff --git a/media/libaudiohal/impl/StreamHalLocal.cpp b/media/libaudiohal/impl/StreamHalLocal.cpp
index a3f2fb4..e89b288 100644
--- a/media/libaudiohal/impl/StreamHalLocal.cpp
+++ b/media/libaudiohal/impl/StreamHalLocal.cpp
@@ -22,8 +22,8 @@
#include <utils/Log.h>
#include "DeviceHalLocal.h"
+#include "ParameterUtils.h"
#include "StreamHalLocal.h"
-#include "VersionUtils.h"
namespace android {
namespace CPP_VERSION {
@@ -258,7 +258,7 @@
#if MAJOR_VERSION >= 7
void StreamOutHalLocal::doUpdateSourceMetadataV7(const SourceMetadata& sourceMetadata) {
- const source_metadata_t metadata {
+ const source_metadata_v7_t metadata {
.track_count = sourceMetadata.tracks.size(),
// const cast is fine as it is in a const structure
.tracks = const_cast<playback_track_metadata_v7*>(sourceMetadata.tracks.data()),
@@ -274,7 +274,7 @@
}
doUpdateSourceMetadata(sourceMetadata);
#else
- if (mDevice->version() < AUDIO_DEVICE_API_VERSION_3_2)
+ if (mDevice->version() < AUDIO_DEVICE_API_VERSION_3_2) {
if (mStream->update_source_metadata == nullptr) {
return INVALID_OPERATION;
}
@@ -446,13 +446,12 @@
status_t StreamInHalLocal::updateSinkMetadata(const SinkMetadata& sinkMetadata) {
#if MAJOR_VERSION < 7
-
if (mStream->update_sink_metadata == nullptr) {
return INVALID_OPERATION; // not supported by the HAL
}
doUpdateSinkMetadata(sinkMetadata);
#else
- if (mDevice->version() < AUDIO_DEVICE_API_VERSION_3_2)
+ if (mDevice->version() < AUDIO_DEVICE_API_VERSION_3_2) {
if (mStream->update_sink_metadata == nullptr) {
return INVALID_OPERATION; // not supported by the HAL
}
diff --git a/media/libaudiohal/include/media/audiohal/StreamHalInterface.h b/media/libaudiohal/include/media/audiohal/StreamHalInterface.h
index 097e9a2..b47f536 100644
--- a/media/libaudiohal/include/media/audiohal/StreamHalInterface.h
+++ b/media/libaudiohal/include/media/audiohal/StreamHalInterface.h
@@ -31,18 +31,22 @@
class StreamHalInterface : public virtual RefBase
{
public:
+ // TODO(mnaganov): Remove
// Return the sampling rate in Hz - eg. 44100.
virtual status_t getSampleRate(uint32_t *rate) = 0;
// Return size of input/output buffer in bytes for this stream - eg. 4800.
virtual status_t getBufferSize(size_t *size) = 0;
+ // TODO(mnaganov): Remove
// Return the channel mask.
virtual status_t getChannelMask(audio_channel_mask_t *mask) = 0;
+ // TODO(mnaganov): Remove
// Return the audio format - e.g. AUDIO_FORMAT_PCM_16_BIT.
virtual status_t getFormat(audio_format_t *format) = 0;
+ // TODO(mnaganov): Change to use audio_config_base_t
// Convenience method.
virtual status_t getAudioProperties(
uint32_t *sampleRate, audio_channel_mask_t *mask, audio_format_t *format) = 0;
diff --git a/media/libmediahelper/tests/typeconverter_tests.cpp b/media/libmediahelper/tests/typeconverter_tests.cpp
index d7bfb89..181d636 100644
--- a/media/libmediahelper/tests/typeconverter_tests.cpp
+++ b/media/libmediahelper/tests/typeconverter_tests.cpp
@@ -182,8 +182,9 @@
audio_format_t format;
EXPECT_TRUE(FormatConverter::fromString(stringVal, format))
<< "Conversion of \"" << stringVal << "\" failed";
- EXPECT_TRUE(audio_is_valid_format(format))
- << "Converted format \"" << stringVal << "\" is invalid";
+ EXPECT_EQ(enumVal != xsd::AudioFormat::AUDIO_FORMAT_DEFAULT,
+ audio_is_valid_format(format))
+ << "Validity of \"" << stringVal << "\" is not as expected";
EXPECT_EQ(stringVal, toString(format));
}
}
diff --git a/media/libmediametrics/Android.bp b/media/libmediametrics/Android.bp
index c2e1dc9..3dfd850 100644
--- a/media/libmediametrics/Android.bp
+++ b/media/libmediametrics/Android.bp
@@ -7,7 +7,6 @@
name: "libmediametrics",
srcs: [
- "IMediaMetricsService.cpp",
"MediaMetricsItem.cpp",
"MediaMetrics.cpp",
],
@@ -17,6 +16,7 @@
"libcutils",
"liblog",
"libutils",
+ "mediametricsservice-aidl-unstable-cpp",
],
export_include_dirs: ["include"],
@@ -58,3 +58,21 @@
"//frameworks/base/media/jni",
],
}
+
+aidl_interface {
+ name: "mediametricsservice-aidl",
+ unstable: true,
+ local_include_dir: "aidl",
+ vendor_available: true,
+ srcs: [
+ "aidl/android/media/IMediaMetricsService.aidl",
+ ],
+ double_loadable: true,
+ backend: {
+ cpp: {
+ apex_available: [
+ "//apex_available:platform",
+ ],
+ },
+ },
+}
diff --git a/media/libmediametrics/MediaMetricsItem.cpp b/media/libmediametrics/MediaMetricsItem.cpp
index 7cdbe5f..f4371fd 100644
--- a/media/libmediametrics/MediaMetricsItem.cpp
+++ b/media/libmediametrics/MediaMetricsItem.cpp
@@ -31,8 +31,9 @@
#include <utils/SortedVector.h>
#include <utils/threads.h>
+#include <android/media/BnMediaMetricsService.h> // for direct Binder access
+#include <android/media/IMediaMetricsService.h>
#include <binder/IServiceManager.h>
-#include <media/IMediaMetricsService.h>
#include <media/MediaMetricsItem.h>
#include <private/android_filesystem_config.h>
@@ -278,17 +279,18 @@
// calls the appropriate daemon
bool mediametrics::Item::selfrecord() {
ALOGD_IF(DEBUG_API, "%s: delivering %s", __func__, this->toString().c_str());
- sp<IMediaMetricsService> svc = getService();
- if (svc != NULL) {
- status_t status = svc->submit(this);
- if (status != NO_ERROR) {
- ALOGW("%s: failed to record: %s", __func__, this->toString().c_str());
- return false;
- }
- return true;
- } else {
+
+ char *str;
+ size_t size;
+ status_t status = writeToByteString(&str, &size);
+ if (status == NO_ERROR) {
+ status = submitBuffer(str, size);
+ }
+ if (status != NO_ERROR) {
+ ALOGW("%s: failed to record: %s", __func__, this->toString().c_str());
return false;
}
+ return true;
}
//static
@@ -327,7 +329,7 @@
static sp<MediaMetricsDeathNotifier> sNotifier;
// static
-sp<IMediaMetricsService> BaseItem::sMediaMetricsService;
+sp<media::IMediaMetricsService> BaseItem::sMediaMetricsService;
static std::mutex sServiceMutex;
static int sRemainingBindAttempts = SVC_TRIES;
@@ -339,29 +341,67 @@
}
// static
-bool BaseItem::submitBuffer(const char *buffer, size_t size) {
-/*
- mediametrics::Item item;
- status_t status = item.readFromByteString(buffer, size);
- ALOGD("%s: status:%d, size:%zu, item:%s", __func__, status, size, item.toString().c_str());
- return item.selfrecord();
- */
-
+status_t BaseItem::submitBuffer(const char *buffer, size_t size) {
ALOGD_IF(DEBUG_API, "%s: delivering %zu bytes", __func__, size);
- sp<IMediaMetricsService> svc = getService();
- if (svc != nullptr) {
- const status_t status = svc->submitBuffer(buffer, size);
- if (status != NO_ERROR) {
- ALOGW("%s: failed(%d) to record: %zu bytes", __func__, status, size);
- return false;
- }
- return true;
+
+ // Validate size
+ if (size > std::numeric_limits<int32_t>::max()) return BAD_VALUE;
+
+ // Do we have the service available?
+ sp<media::IMediaMetricsService> svc = getService();
+ if (svc == nullptr) return NO_INIT;
+
+ ::android::status_t status = NO_ERROR;
+ if constexpr (/* DISABLES CODE */ (false)) {
+ // THIS PATH IS FOR REFERENCE ONLY.
+ // It is compiled so that any changes to IMediaMetricsService::submitBuffer()
+ // will lead here. If this code is changed, the else branch must
+ // be changed as well.
+ //
+ // Use the AIDL calling interface - this is a bit slower as a byte vector must be
+ // constructed. As the call is one-way, the only a transaction error occurs.
+ status = svc->submitBuffer({buffer, buffer + size}).transactionError();
+ } else {
+ // Use the Binder calling interface - this direct implementation avoids
+ // malloc/copy/free for the vector and reduces the overhead for logging.
+ // We based this off of the AIDL generated file:
+ // out/soong/.intermediates/frameworks/av/media/libmediametrics/mediametricsservice-aidl-unstable-cpp-source/gen/android/media/IMediaMetricsService.cpp
+ // TODO: Create an AIDL C++ back end optimized form of vector writing.
+ ::android::Parcel _aidl_data;
+ ::android::Parcel _aidl_reply; // we don't care about this as it is one-way.
+
+ status = _aidl_data.writeInterfaceToken(svc->getInterfaceDescriptor());
+ if (status != ::android::OK) goto _aidl_error;
+
+ status = _aidl_data.writeInt32(static_cast<int32_t>(size));
+ if (status != ::android::OK) goto _aidl_error;
+
+ status = _aidl_data.write(buffer, static_cast<int32_t>(size));
+ if (status != ::android::OK) goto _aidl_error;
+
+ status = ::android::IInterface::asBinder(svc)->transact(
+ ::android::media::BnMediaMetricsService::TRANSACTION_submitBuffer,
+ _aidl_data, &_aidl_reply, ::android::IBinder::FLAG_ONEWAY);
+
+ // AIDL permits setting a default implementation for additional functionality.
+ // See go/aog/713984. This is not used here.
+ // if (status == ::android::UNKNOWN_TRANSACTION
+ // && ::android::media::IMediaMetricsService::getDefaultImpl()) {
+ // status = ::android::media::IMediaMetricsService::getDefaultImpl()
+ // ->submitBuffer(immutableByteVectorFromBuffer(buffer, size))
+ // .transactionError();
+ // }
}
- return false;
+
+ if (status == NO_ERROR) return NO_ERROR;
+
+ _aidl_error:
+ ALOGW("%s: failed(%d) to record: %zu bytes", __func__, status, size);
+ return status;
}
//static
-sp<IMediaMetricsService> BaseItem::getService() {
+sp<media::IMediaMetricsService> BaseItem::getService() {
static const char *servicename = "media.metrics";
static const bool enabled = isEnabled(); // singleton initialized
@@ -379,7 +419,7 @@
if (sm != nullptr) {
sp<IBinder> binder = sm->getService(String16(servicename));
if (binder != nullptr) {
- sMediaMetricsService = interface_cast<IMediaMetricsService>(binder);
+ sMediaMetricsService = interface_cast<media::IMediaMetricsService>(binder);
sNotifier = new MediaMetricsDeathNotifier();
binder->linkToDeath(sNotifier);
} else {
diff --git a/media/libmediametrics/aidl/android/media/IMediaMetricsService.aidl b/media/libmediametrics/aidl/android/media/IMediaMetricsService.aidl
new file mode 100644
index 0000000..b14962d
--- /dev/null
+++ b/media/libmediametrics/aidl/android/media/IMediaMetricsService.aidl
@@ -0,0 +1,26 @@
+/*
+ * Copyright (C) 2021 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.
+ */
+
+package android.media;
+
+/**
+ * MediaMetrics service interface
+ *
+ * {@hide}
+ */
+interface IMediaMetricsService {
+ oneway void submitBuffer(in byte[] buffer);
+}
diff --git a/media/libmediametrics/include/media/IMediaMetricsService.h b/media/libmediametrics/include/media/IMediaMetricsService.h
deleted file mode 100644
index d6871ec..0000000
--- a/media/libmediametrics/include/media/IMediaMetricsService.h
+++ /dev/null
@@ -1,73 +0,0 @@
-/*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef ANDROID_IMEDIAANALYTICSSERVICE_H
-#define ANDROID_IMEDIAANALYTICSSERVICE_H
-
-#include <utils/String8.h>
-#include <binder/IInterface.h>
-#include <binder/Parcel.h>
-
-#include <sys/types.h>
-#include <utils/Errors.h>
-#include <utils/Log.h>
-#include <utils/RefBase.h>
-#include <utils/List.h>
-
-#include <binder/IServiceManager.h>
-
-#include <media/MediaMetricsItem.h>
-
-namespace android {
-
-class IMediaMetricsService: public IInterface
-{
-public:
- DECLARE_META_INTERFACE(MediaMetricsService);
-
- /**
- * Submits the indicated record to the mediaanalytics service, where
- * it will be merged (if appropriate) with incomplete records that
- * share the same key and sessionID.
- *
- * \param item the item to submit.
- * \return status which is negative if an error is detected (some errors
- may be silent and return 0 - success).
- */
- virtual status_t submit(mediametrics::Item *item) = 0;
-
- virtual status_t submitBuffer(const char *buffer, size_t length) = 0;
-};
-
-// ----------------------------------------------------------------------------
-
-class BnMediaMetricsService: public BnInterface<IMediaMetricsService>
-{
-public:
- status_t onTransact(uint32_t code,
- const Parcel& data,
- Parcel* reply,
- uint32_t flags = 0) override;
-
-protected:
- // Internal call where release is true if the service is to delete the item.
- virtual status_t submitInternal(
- mediametrics::Item *item, bool release) = 0;
-};
-
-}; // namespace android
-
-#endif // ANDROID_IMEDIASTATISTICSSERVICE_H
diff --git a/media/libmediametrics/include/media/MediaMetricsItem.h b/media/libmediametrics/include/media/MediaMetricsItem.h
index 303343f..428992c 100644
--- a/media/libmediametrics/include/media/MediaMetricsItem.h
+++ b/media/libmediametrics/include/media/MediaMetricsItem.h
@@ -32,7 +32,8 @@
namespace android {
-class IMediaMetricsService;
+namespace media { class IMediaMetricsService; }
+
class Parcel;
/*
@@ -239,7 +240,10 @@
public:
// are we collecting metrics data
static bool isEnabled();
- static sp<IMediaMetricsService> getService();
+ // returns the MediaMetrics service if active.
+ static sp<media::IMediaMetricsService> getService();
+ // submits a raw buffer directly to the MediaMetrics service - this is highly optimized.
+ static status_t submitBuffer(const char *buffer, size_t len);
protected:
static constexpr const char * const EnabledProperty = "media.metrics.enabled";
@@ -247,10 +251,9 @@
static const int EnabledProperty_default = 1;
// let's reuse a binder connection
- static sp<IMediaMetricsService> sMediaMetricsService;
+ static sp<media::IMediaMetricsService> sMediaMetricsService;
static void dropInstance();
- static bool submitBuffer(const char *buffer, size_t len);
template <typename T>
struct is_item_type {
@@ -573,7 +576,7 @@
bool record() {
return updateHeader()
- && BaseItem::submitBuffer(getBuffer(), getLength());
+ && BaseItem::submitBuffer(getBuffer(), getLength()) == OK;
}
bool isValid () const {
diff --git a/media/libmediatranscoding/transcoder/VideoTrackTranscoder.cpp b/media/libmediatranscoding/transcoder/VideoTrackTranscoder.cpp
index e3c0b05..994695f 100644
--- a/media/libmediatranscoding/transcoder/VideoTrackTranscoder.cpp
+++ b/media/libmediatranscoding/transcoder/VideoTrackTranscoder.cpp
@@ -238,7 +238,12 @@
int32_t operatingRate = getDefaultOperatingRate(encoderFormat);
if (operatingRate != -1) {
- SetDefaultFormatValueInt32(AMEDIAFORMAT_KEY_OPERATING_RATE, encoderFormat, operatingRate);
+ float tmpf;
+ int32_t tmpi;
+ if (!AMediaFormat_getFloat(encoderFormat, AMEDIAFORMAT_KEY_OPERATING_RATE, &tmpf) &&
+ !AMediaFormat_getInt32(encoderFormat, AMEDIAFORMAT_KEY_OPERATING_RATE, &tmpi)) {
+ AMediaFormat_setInt32(encoderFormat, AMEDIAFORMAT_KEY_OPERATING_RATE, operatingRate);
+ }
}
SetDefaultFormatValueInt32(AMEDIAFORMAT_KEY_PRIORITY, encoderFormat, kDefaultCodecPriority);
@@ -260,8 +265,8 @@
return AMEDIA_ERROR_INVALID_PARAMETER;
}
- // TODO: replace __ANDROID_API_FUTURE__with 31 when it's official (b/178144708)
- #define __TRANSCODING_MIN_API__ __ANDROID_API_FUTURE__
+// TODO: replace __ANDROID_API_FUTURE__with 31 when it's official (b/178144708)
+#define __TRANSCODING_MIN_API__ __ANDROID_API_FUTURE__
AMediaCodec* encoder;
if (__builtin_available(android __TRANSCODING_MIN_API__, *)) {
diff --git a/media/libmediatranscoding/transcoder/benchmark/AndroidTestTemplate.xml b/media/libmediatranscoding/transcoder/benchmark/AndroidTestTemplate.xml
index 64085d8..683f07b 100644
--- a/media/libmediatranscoding/transcoder/benchmark/AndroidTestTemplate.xml
+++ b/media/libmediatranscoding/transcoder/benchmark/AndroidTestTemplate.xml
@@ -19,7 +19,7 @@
<option name="cleanup" value="false" />
<option name="push-file" key="{MODULE}" value="/data/local/tmp/{MODULE}" />
<option name="push-file"
- key="https://storage.googleapis.com/android_media/frameworks/av/media/libmediatranscoding/transcoder/benchmark/TranscodingBenchmark-1.1.zip?unzip=true"
+ key="https://storage.googleapis.com/android_media/frameworks/av/media/libmediatranscoding/transcoder/benchmark/TranscodingBenchmark-1.2.zip?unzip=true"
value="/data/local/tmp/TranscodingBenchmark/" />
</target_preparer>
diff --git a/media/libmediatranscoding/transcoder/benchmark/MediaTranscoderBenchmark.cpp b/media/libmediatranscoding/transcoder/benchmark/MediaTranscoderBenchmark.cpp
index e0b2050..712f8fc 100644
--- a/media/libmediatranscoding/transcoder/benchmark/MediaTranscoderBenchmark.cpp
+++ b/media/libmediatranscoding/transcoder/benchmark/MediaTranscoderBenchmark.cpp
@@ -33,6 +33,7 @@
#include <binder/ProcessState.h>
#include <fcntl.h>
#include <media/MediaTranscoder.h>
+#include <media/NdkCommon.h>
#include <iostream>
@@ -87,6 +88,7 @@
AMediaFormat* videoFormat = AMediaFormat_new();
AMediaFormat_setInt32(videoFormat, AMEDIAFORMAT_KEY_BIT_RATE, kVideoBitRate);
+ AMediaFormat_setString(videoFormat, AMEDIAFORMAT_KEY_MIME, AMEDIA_MIMETYPE_VIDEO_AVC);
return videoFormat;
}
@@ -222,7 +224,7 @@
}
static void SetMaxOperatingRate(AMediaFormat* format) {
- AMediaFormat_setFloat(format, AMEDIAFORMAT_KEY_OPERATING_RATE, INT32_MAX);
+ AMediaFormat_setInt32(format, AMEDIAFORMAT_KEY_OPERATING_RATE, INT32_MAX);
AMediaFormat_setInt32(format, AMEDIAFORMAT_KEY_PRIORITY, 1);
}
@@ -314,6 +316,174 @@
false /* includeAudio */, false /* transcodeVideo */);
}
+//---------------------------- Codecs, Resolutions, Bitrate ---------------------------------------
+static void SetMimeBitrate(AMediaFormat* format, std::string mime, int32_t bitrate) {
+ AMediaFormat_setString(format, AMEDIAFORMAT_KEY_MIME, mime.c_str());
+ AMediaFormat_setInt32(format, AMEDIAFORMAT_KEY_BIT_RATE, bitrate);
+}
+
+static void BM_1920x1080_Avc22Mbps2Avc12Mbps(benchmark::State& state) {
+ TranscodeMediaFile(state, "tx_bm_1920_1080_30fps_h264_22Mbps.mp4",
+ "tx_bm_1920_1080_30fps_h264_22Mbps_transcoded_h264_12Mbps.mp4",
+ false /* includeAudio */, true /* transcodeVideo */,
+ [mime = "video/avc", bitrate = 12000000](AMediaFormat* dstFormat) {
+ SetMimeBitrate(dstFormat, mime, bitrate);
+ });
+}
+
+static void BM_1920x1080_Avc15Mbps2Avc8Mbps(benchmark::State& state) {
+ TranscodeMediaFile(state, "tx_bm_1920_1080_30fps_h264_15Mbps.mp4",
+ "tx_bm_1920_1080_30fps_h264_15Mbps_transcoded_h264_8Mbps.mp4",
+ false /* includeAudio */, true /* transcodeVideo */,
+ [mime = "video/avc", bitrate = 8000000](AMediaFormat* dstFormat) {
+ SetMimeBitrate(dstFormat, mime, bitrate);
+ });
+}
+
+static void BM_1920x1080_Avc15Mbps2AvcPassthrough(benchmark::State& state) {
+ TranscodeMediaFile(state, "tx_bm_1920_1080_30fps_h264_15Mbps.mp4",
+ "tx_bm_1920_1080_30fps_h264_15Mbps_passthrough_V.mp4",
+ false /* includeAudio */, false /* transcodeVideo */);
+}
+
+static void BM_1920x1080_Avc15MbpsAac2Avc8Mbps(benchmark::State& state) {
+ TranscodeMediaFile(state, "tx_bm_1920_1080_30fps_h264_15Mbps_aac.mp4",
+ "tx_bm_1920_1080_30fps_h264_15Mbps_aac_transcoded_h264_8Mbps.mp4",
+ false /* includeAudio */, true /* transcodeVideo */,
+ [mime = "video/avc", bitrate = 8000000](AMediaFormat* dstFormat) {
+ SetMimeBitrate(dstFormat, mime, bitrate);
+ });
+}
+
+static void BM_1920x1080_Avc15MbpsAac2Avc8MbpsAac(benchmark::State& state) {
+ TranscodeMediaFile(state, "tx_bm_1920_1080_30fps_h264_15Mbps_aac.mp4",
+ "tx_bm_1920_1080_30fps_h264_15Mbps_aac_transcoded_h264_8Mbps_aac.mp4",
+ true /* includeAudio */, true /* transcodeVideo */,
+ [mime = "video/avc", bitrate = 8000000](AMediaFormat* dstFormat) {
+ SetMimeBitrate(dstFormat, mime, bitrate);
+ });
+}
+
+static void BM_1920x1080_Avc15MbpsAac2AvcPassthrough(benchmark::State& state) {
+ TranscodeMediaFile(state, "tx_bm_1920_1080_30fps_h264_15Mbps_aac.mp4",
+ "tx_bm_1920_1080_30fps_h264_15Mbps_aac_passthrough_V.mp4",
+ false /* includeAudio */, false /* transcodeVideo */);
+}
+
+static void BM_1920x1080_Avc15MbpsAac2AvcAacPassthrough(benchmark::State& state) {
+ TranscodeMediaFile(state, "tx_bm_1920_1080_30fps_h264_15Mbps_aac.mp4",
+ "tx_bm_1920_1080_30fps_h264_15Mbps_aac_passthrough_AV.mp4",
+ true /* includeAudio */, false /* transcodeVideo */);
+}
+
+static void BM_1920x1080_Hevc17Mbps2Hevc8Mbps(benchmark::State& state) {
+ TranscodeMediaFile(state, "tx_bm_1920_1080_30fps_hevc_17Mbps.mp4",
+ "tx_bm_1920_1080_30fps_hevc_17Mbps_transcoded_hevc_8Mbps.mp4",
+ false /* includeAudio */, true /* transcodeVideo */,
+ [mime = "video/hevc", bitrate = 8000000](AMediaFormat* dstFormat) {
+ SetMimeBitrate(dstFormat, mime, bitrate);
+ });
+}
+
+static void BM_1920x1080_Hevc17Mbps2Avc12Mbps(benchmark::State& state) {
+ TranscodeMediaFile(state, "tx_bm_1920_1080_30fps_hevc_17Mbps.mp4",
+ "tx_bm_1920_1080_30fps_hevc_17Mbps_transcoded_h264_12Mbps.mp4",
+ false /* includeAudio */, true /* transcodeVideo */,
+ [mime = "video/avc", bitrate = 12000000](AMediaFormat* dstFormat) {
+ SetMimeBitrate(dstFormat, mime, bitrate);
+ });
+}
+
+static void BM_1920x1080_60fps_Hevc28Mbps2Avc15Mbps(benchmark::State& state) {
+ TranscodeMediaFile(state, "tx_bm_1920_1080_60fps_hevc_28Mbps.mp4",
+ "tx_bm_1920_1080_60fps_hevc_28Mbps_transcoded_h264_15Mbps.mp4",
+ false /* includeAudio */, true /* transcodeVideo */,
+ [mime = "video/avc", bitrate = 15000000](AMediaFormat* dstFormat) {
+ SetMimeBitrate(dstFormat, mime, bitrate);
+ });
+}
+
+static void BM_1280x720_Avc10Mbps2Avc4Mbps(benchmark::State& state) {
+ TranscodeMediaFile(state, "tx_bm_1280_720_30fps_h264_10Mbps.mp4",
+ "tx_bm_1280_720_30fps_h264_10Mbps_transcoded_h264_4Mbps.mp4",
+ false /* includeAudio */, true /* transcodeVideo */,
+ [mime = "video/avc", bitrate = 4000000](AMediaFormat* dstFormat) {
+ SetMimeBitrate(dstFormat, mime, bitrate);
+ });
+}
+
+static void BM_1280x720_Avc10Mbps2AvcPassthrough(benchmark::State& state) {
+ TranscodeMediaFile(state, "tx_bm_1280_720_30fps_h264_10Mbps.mp4",
+ "tx_bm_1280_720_30fps_h264_10Mbps_passthrough_V.mp4",
+ false /* includeAudio */, false /* transcodeVideo */);
+}
+
+static void BM_1280x720_Avc10MbpsAac2Avc4Mbps(benchmark::State& state) {
+ TranscodeMediaFile(state, "tx_bm_1280_720_30fps_h264_10Mbps_aac.mp4",
+ "tx_bm_1280_720_30fps_h264_10Mbps_aac_transcoded_h264_4Mbps.mp4",
+ false /* includeAudio */, true /* transcodeVideo */,
+ [mime = "video/avc", bitrate = 4000000](AMediaFormat* dstFormat) {
+ SetMimeBitrate(dstFormat, mime, bitrate);
+ });
+}
+
+static void BM_1280x720_Avc10MbpsAac2Avc4MbpsAac(benchmark::State& state) {
+ TranscodeMediaFile(state, "tx_bm_1280_720_30fps_h264_10Mbps_aac.mp4",
+ "tx_bm_1280_720_30fps_h264_10Mbps_aac_transcoded_h264_4Mbps_aac.mp4",
+ true /* includeAudio */, true /* transcodeVideo */,
+ [mime = "video/avc", bitrate = 4000000](AMediaFormat* dstFormat) {
+ SetMimeBitrate(dstFormat, mime, bitrate);
+ });
+}
+
+static void BM_1280x720_Avc10MbpsAac2AvcPassthrough(benchmark::State& state) {
+ TranscodeMediaFile(state, "tx_bm_1280_720_30fps_h264_10Mbps_aac.mp4",
+ "tx_bm_1280_720_30fps_h264_10Mbps_aac_passthrough_V.mp4",
+ false /* includeAudio */, false /* transcodeVideo */);
+}
+
+static void BM_1280x720_Avc10MbpsAac2AvcAacPassthrough(benchmark::State& state) {
+ TranscodeMediaFile(state, "tx_bm_1280_720_30fps_h264_10Mbps_aac.mp4",
+ "tx_bm_1280_720_30fps_h264_10Mbps_aac_passthrough_AV.mp4",
+ true /* includeAudio */, false /* transcodeVideo */);
+}
+
+static void BM_1280x720_Hevc8Mbps2Avc4Mbps(benchmark::State& state) {
+ TranscodeMediaFile(state, "tx_bm_1280_720_30fps_hevc_8Mbps.mp4",
+ "tx_bm_1280_720_30fps_hevc_8Mbps_transcoded_h264_4Mbps.mp4",
+ false /* includeAudio */, true /* transcodeVideo */,
+ [mime = "video/avc", bitrate = 4000000](AMediaFormat* dstFormat) {
+ SetMimeBitrate(dstFormat, mime, bitrate);
+ });
+}
+
+static void BM_1080x1920_Avc15Mbps2Avc8Mbps(benchmark::State& state) {
+ TranscodeMediaFile(state, "tx_bm_1080_1920_30fps_h264_15Mbps.mp4",
+ "tx_bm_1080_1920_30fps_h264_15Mbps_transcoded_h264_8Mbps.mp4",
+ false /* includeAudio */, true /* transcodeVideo */,
+ [mime = "video/avc", bitrate = 8000000](AMediaFormat* dstFormat) {
+ SetMimeBitrate(dstFormat, mime, bitrate);
+ });
+}
+
+static void BM_720x1280_Avc10Mbps2Avc4Mbps(benchmark::State& state) {
+ TranscodeMediaFile(state, "tx_bm_720_1280_30fps_h264_10Mbps.mp4",
+ "tx_bm_720_1280_30fps_h264_10Mbps_transcoded_h264_4Mbps.mp4",
+ false /* includeAudio */, true /* transcodeVideo */,
+ [mime = "video/avc", bitrate = 4000000](AMediaFormat* dstFormat) {
+ SetMimeBitrate(dstFormat, mime, bitrate);
+ });
+}
+
+static void BM_3840x2160_Hevc42Mbps2Avc20Mbps(benchmark::State& state) {
+ TranscodeMediaFile(state, "tx_bm_3840_2160_30fps_hevc_42Mbps.mp4",
+ "tx_bm_3840_2160_30fps_hevc_42Mbps_transcoded_h264_4Mbps.mp4",
+ false /* includeAudio */, true /* transcodeVideo */,
+ [mime = "video/avc", bitrate = 20000000](AMediaFormat* dstFormat) {
+ SetMimeBitrate(dstFormat, mime, bitrate);
+ });
+}
+
//-------------------------------- Benchmark Registration ------------------------------------------
// Benchmark registration wrapper for transcoding.
@@ -337,6 +507,30 @@
TRANSCODER_BENCHMARK(BM_TranscodeAudioVideoPassthrough);
TRANSCODER_BENCHMARK(BM_TranscodeVideoPassthrough);
+TRANSCODER_BENCHMARK(BM_1920x1080_Avc22Mbps2Avc12Mbps);
+TRANSCODER_BENCHMARK(BM_1920x1080_Avc15Mbps2Avc8Mbps);
+TRANSCODER_BENCHMARK(BM_1920x1080_Avc15Mbps2AvcPassthrough);
+TRANSCODER_BENCHMARK(BM_1920x1080_Avc15MbpsAac2Avc8Mbps);
+TRANSCODER_BENCHMARK(BM_1920x1080_Avc15MbpsAac2Avc8MbpsAac);
+TRANSCODER_BENCHMARK(BM_1920x1080_Avc15MbpsAac2AvcPassthrough);
+TRANSCODER_BENCHMARK(BM_1920x1080_Avc15MbpsAac2AvcAacPassthrough);
+TRANSCODER_BENCHMARK(BM_1920x1080_Hevc17Mbps2Hevc8Mbps);
+TRANSCODER_BENCHMARK(BM_1920x1080_Hevc17Mbps2Avc12Mbps);
+TRANSCODER_BENCHMARK(BM_1920x1080_60fps_Hevc28Mbps2Avc15Mbps);
+
+TRANSCODER_BENCHMARK(BM_1280x720_Avc10Mbps2Avc4Mbps);
+TRANSCODER_BENCHMARK(BM_1280x720_Avc10Mbps2AvcPassthrough);
+TRANSCODER_BENCHMARK(BM_1280x720_Avc10MbpsAac2Avc4Mbps);
+TRANSCODER_BENCHMARK(BM_1280x720_Avc10MbpsAac2Avc4MbpsAac);
+TRANSCODER_BENCHMARK(BM_1280x720_Avc10MbpsAac2AvcPassthrough);
+TRANSCODER_BENCHMARK(BM_1280x720_Avc10MbpsAac2AvcAacPassthrough);
+TRANSCODER_BENCHMARK(BM_1280x720_Hevc8Mbps2Avc4Mbps);
+
+TRANSCODER_BENCHMARK(BM_1080x1920_Avc15Mbps2Avc8Mbps);
+TRANSCODER_BENCHMARK(BM_720x1280_Avc10Mbps2Avc4Mbps);
+
+TRANSCODER_BENCHMARK(BM_3840x2160_Hevc42Mbps2Avc20Mbps);
+
class CustomCsvReporter : public benchmark::BenchmarkReporter {
public:
CustomCsvReporter() : mPrintedHeader(false) {}
diff --git a/media/libmediatranscoding/transcoder/tests/AndroidTestTemplate.xml b/media/libmediatranscoding/transcoder/tests/AndroidTestTemplate.xml
index 6d781cd..e40a507 100644
--- a/media/libmediatranscoding/transcoder/tests/AndroidTestTemplate.xml
+++ b/media/libmediatranscoding/transcoder/tests/AndroidTestTemplate.xml
@@ -24,6 +24,7 @@
<test class="com.android.tradefed.testtype.GTest" >
<option name="native-test-device-path" value="/data/local/tmp" />
<option name="module-name" value="{MODULE}" />
+ <option name="native-test-timeout" value="10m" />
</test>
</configuration>
diff --git a/services/audioflinger/Threads.cpp b/services/audioflinger/Threads.cpp
index 1f5b8d2..eaf0d10 100644
--- a/services/audioflinger/Threads.cpp
+++ b/services/audioflinger/Threads.cpp
@@ -2961,7 +2961,10 @@
auto backInserter = std::back_inserter(metadata.tracks);
for (const sp<Track> &track : mActiveTracks) {
// No track is invalid as this is called after prepareTrack_l in the same critical section
- track->copyMetadataTo(backInserter);
+ // Do not forward metadata for PatchTrack with unspecified stream type
+ if (track->streamType() != AUDIO_STREAM_PATCH) {
+ track->copyMetadataTo(backInserter);
+ }
}
sendMetadataToBackend_l(metadata);
}
@@ -8101,6 +8104,10 @@
}
StreamInHalInterface::SinkMetadata metadata;
for (const sp<RecordTrack> &track : mActiveTracks) {
+ // Do not forward PatchRecord metadata to audio HAL
+ if (track->isPatchTrack()) {
+ continue;
+ }
// No track is invalid as this is called after prepareTrack_l in the same critical section
record_track_metadata_v7_t trackMetadata;
trackMetadata.base = {
diff --git a/services/audiopolicy/service/AudioPolicyInterfaceImpl.cpp b/services/audiopolicy/service/AudioPolicyInterfaceImpl.cpp
index fed88a4..caf7309 100644
--- a/services/audiopolicy/service/AudioPolicyInterfaceImpl.cpp
+++ b/services/audiopolicy/service/AudioPolicyInterfaceImpl.cpp
@@ -280,6 +280,7 @@
int32_t uidAidl,
const media::AudioConfig& configAidl,
int32_t flagsAidl,
+ int32_t selectedDeviceIdAidl,
media::GetOutputForAttrResponse* _aidl_return)
{
audio_attributes_t attr = VALUE_OR_RETURN_BINDER_STATUS(
@@ -293,8 +294,10 @@
aidl2legacy_AudioConfig_audio_config_t(configAidl));
audio_output_flags_t flags = VALUE_OR_RETURN_BINDER_STATUS(
aidl2legacy_int32_t_audio_output_flags_t_mask(flagsAidl));
+ audio_port_handle_t selectedDeviceId = VALUE_OR_RETURN_BINDER_STATUS(
+ aidl2legacy_int32_t_audio_port_handle_t(selectedDeviceIdAidl));
+
audio_io_handle_t output;
- audio_port_handle_t selectedDeviceId;
audio_port_handle_t portId;
std::vector<audio_io_handle_t> secondaryOutputs;
@@ -504,6 +507,7 @@
const std::string& opPackageNameAidl,
const media::AudioConfigBase& configAidl,
int32_t flagsAidl,
+ int32_t selectedDeviceIdAidl,
media::GetInputForAttrResponse* _aidl_return) {
audio_attributes_t attr = VALUE_OR_RETURN_BINDER_STATUS(
aidl2legacy_AudioAttributesInternal_audio_attributes_t(attrAidl));
@@ -521,7 +525,9 @@
aidl2legacy_AudioConfigBase_audio_config_base_t(configAidl));
audio_input_flags_t flags = VALUE_OR_RETURN_BINDER_STATUS(
aidl2legacy_int32_t_audio_input_flags_t_mask(flagsAidl));
- audio_port_handle_t selectedDeviceId;
+ audio_port_handle_t selectedDeviceId = VALUE_OR_RETURN_BINDER_STATUS(
+ aidl2legacy_int32_t_audio_port_handle_t(selectedDeviceIdAidl));
+
audio_port_handle_t portId;
if (mAudioPolicyManager == NULL) {
@@ -590,7 +596,14 @@
bool canCaptureHotword = captureHotwordAllowed(opPackageName, pid, uid);
if ((inputSource == AUDIO_SOURCE_HOTWORD) && !canCaptureHotword) {
- return binderStatusFromStatusT(BAD_VALUE);
+ return binderStatusFromStatusT(PERMISSION_DENIED);
+ }
+
+ if (((flags & AUDIO_INPUT_FLAG_HW_HOTWORD) != 0)
+ && !canCaptureHotword) {
+ ALOGE("%s: permission denied: hotword mode not allowed"
+ " for uid %d pid %d", __func__, uid, pid);
+ return binderStatusFromStatusT(PERMISSION_DENIED);
}
sp<AudioPolicyEffects>audioPolicyEffects;
diff --git a/services/audiopolicy/service/AudioPolicyService.h b/services/audiopolicy/service/AudioPolicyService.h
index c22ed9b..72d8f28 100644
--- a/services/audiopolicy/service/AudioPolicyService.h
+++ b/services/audiopolicy/service/AudioPolicyService.h
@@ -81,7 +81,7 @@
binder::Status getOutput(media::AudioStreamType stream, int32_t* _aidl_return) override;
binder::Status getOutputForAttr(const media::AudioAttributesInternal& attr, int32_t session,
int32_t pid, int32_t uid, const media::AudioConfig& config,
- int32_t flags,
+ int32_t flags, int32_t selectedDeviceId,
media::GetOutputForAttrResponse* _aidl_return) override;
binder::Status startOutput(int32_t portId) override;
binder::Status stopOutput(int32_t portId) override;
@@ -90,6 +90,7 @@
int32_t riid, int32_t session, int32_t pid, int32_t uid,
const std::string& opPackageName,
const media::AudioConfigBase& config, int32_t flags,
+ int32_t selectedDeviceId,
media::GetInputForAttrResponse* _aidl_return) override;
binder::Status startInput(int32_t portId) override;
binder::Status stopInput(int32_t portId) override;
diff --git a/services/mediametrics/Android.bp b/services/mediametrics/Android.bp
index 3bb70f1..b64f726 100644
--- a/services/mediametrics/Android.bp
+++ b/services/mediametrics/Android.bp
@@ -100,6 +100,7 @@
"libmediametricsservice",
"libmediautils",
"libutils",
+ "mediametricsservice-aidl-unstable-cpp",
],
header_libs: [
"libaudioutils_headers",
@@ -142,6 +143,7 @@
},
shared_libs: [
+ "mediametricsservice-aidl-unstable-cpp",
"libbase", // android logging
"libbinder",
"libcutils",
diff --git a/services/mediametrics/MediaMetricsService.cpp b/services/mediametrics/MediaMetricsService.cpp
index bf6e428..9d380ec 100644
--- a/services/mediametrics/MediaMetricsService.cpp
+++ b/services/mediametrics/MediaMetricsService.cpp
@@ -25,6 +25,7 @@
#include <android/content/pm/IPackageManagerNative.h> // package info
#include <audio_utils/clock.h> // clock conversions
#include <binder/IPCThreadState.h> // get calling uid
+#include <binder/IServiceManager.h> // checkCallingPermission
#include <cutils/properties.h> // for property_get
#include <mediautils/MemoryLeakTrackUtil.h>
#include <memunreachable/memunreachable.h>
diff --git a/services/mediametrics/MediaMetricsService.h b/services/mediametrics/MediaMetricsService.h
index 792b7f0..bcae397 100644
--- a/services/mediametrics/MediaMetricsService.h
+++ b/services/mediametrics/MediaMetricsService.h
@@ -24,7 +24,7 @@
// IMediaMetricsService must include Vector, String16, Errors
#include <android-base/thread_annotations.h>
-#include <media/IMediaMetricsService.h>
+#include <android/media/BnMediaMetricsService.h>
#include <mediautils/ServiceUtilities.h>
#include <utils/String8.h>
@@ -32,12 +32,18 @@
namespace android {
-class MediaMetricsService : public BnMediaMetricsService
+class MediaMetricsService : public media::BnMediaMetricsService
{
public:
MediaMetricsService();
~MediaMetricsService() override;
+ // AIDL interface
+ binder::Status submitBuffer(const std::vector<uint8_t>& buffer) override {
+ status_t status = submitBuffer((char *)buffer.data(), buffer.size());
+ return binder::Status::fromStatusT(status);
+ }
+
/**
* Submits the indicated record to the mediaanalytics service.
*
@@ -45,11 +51,11 @@
* \return status failure, which is negative on binder transaction failure.
* As the transaction is one-way, remote failures will not be reported.
*/
- status_t submit(mediametrics::Item *item) override {
+ status_t submit(mediametrics::Item *item) {
return submitInternal(item, false /* release */);
}
- status_t submitBuffer(const char *buffer, size_t length) override {
+ status_t submitBuffer(const char *buffer, size_t length) {
mediametrics::Item *item = new mediametrics::Item();
return item->readFromByteString(buffer, length)
?: submitInternal(item, true /* release */);
@@ -81,7 +87,7 @@
// Internal call where release is true if ownership of item is transferred
// to the service (that is, the service will eventually delete the item).
- status_t submitInternal(mediametrics::Item *item, bool release) override;
+ status_t submitInternal(mediametrics::Item *item, bool release);
private:
void processExpirations();
diff --git a/services/mediametrics/fuzzer/Android.bp b/services/mediametrics/fuzzer/Android.bp
index df4c867..6ac9d20 100644
--- a/services/mediametrics/fuzzer/Android.bp
+++ b/services/mediametrics/fuzzer/Android.bp
@@ -43,6 +43,7 @@
"libstagefright",
"libstatslog",
"libutils",
+ "mediametricsservice-aidl-unstable-cpp",
],
include_dirs: [
diff --git a/services/mediametrics/tests/Android.bp b/services/mediametrics/tests/Android.bp
index c2e0759..94112b0 100644
--- a/services/mediametrics/tests/Android.bp
+++ b/services/mediametrics/tests/Android.bp
@@ -19,6 +19,7 @@
"libmediametricsservice",
"libmediautils",
"libutils",
+ "mediametricsservice-aidl-unstable-cpp",
],
header_libs: [
diff --git a/services/tuner/TunerDemux.cpp b/services/tuner/TunerDemux.cpp
index 0e0cd3b..1f8b70d 100644
--- a/services/tuner/TunerDemux.cpp
+++ b/services/tuner/TunerDemux.cpp
@@ -124,4 +124,17 @@
*_aidl_return = ::ndk::SharedRefBase::make<TunerDvr>(hidlDvr, dvrType);
return Status::ok();
}
+
+Status TunerDemux::close() {
+ if (mDemux == nullptr) {
+ ALOGE("IDemux is not initialized.");
+ return Status::fromServiceSpecificError(static_cast<int32_t>(Result::UNAVAILABLE));
+ }
+
+ Result res = mDemux->close();
+ if (res != Result::SUCCESS) {
+ return Status::fromServiceSpecificError(static_cast<int32_t>(res));
+ }
+ return Status::ok();
+}
} // namespace android
diff --git a/services/tuner/TunerDemux.h b/services/tuner/TunerDemux.h
index 675bb7c..594fd66 100644
--- a/services/tuner/TunerDemux.h
+++ b/services/tuner/TunerDemux.h
@@ -47,6 +47,7 @@
Status openDvr(
int dvbType, int bufferSize, const shared_ptr<ITunerDvrCallback>& cb,
shared_ptr<ITunerDvr>* _aidl_return) override;
+ Status close() override;
private:
sp<IDemux> mDemux;
diff --git a/services/tuner/TunerFilter.cpp b/services/tuner/TunerFilter.cpp
index 722d36d..456a2c1 100644
--- a/services/tuner/TunerFilter.cpp
+++ b/services/tuner/TunerFilter.cpp
@@ -16,16 +16,21 @@
#define LOG_TAG "TunerFilter"
-#include <aidlcommonsupport/NativeHandle.h>
#include "TunerFilter.h"
+using ::android::hardware::hidl_handle;
+using ::android::hardware::tv::tuner::V1_0::DemuxFilterMainType;
using ::android::hardware::tv::tuner::V1_0::DemuxFilterSettings;
+using ::android::hardware::tv::tuner::V1_0::DemuxMmtpFilterType;
using ::android::hardware::tv::tuner::V1_0::DemuxTsFilterSettings;
+using ::android::hardware::tv::tuner::V1_0::DemuxTsFilterType;
using ::android::hardware::tv::tuner::V1_0::Result;
+using ::android::hardware::tv::tuner::V1_1::Constant;
namespace android {
-TunerFilter::TunerFilter(sp<IFilter> filter, sp<IFilterCallback> callback) {
+TunerFilter::TunerFilter(
+ sp<IFilter> filter, sp<IFilterCallback> callback) {
mFilter = filter;
mFilter_1_1 = ::android::hardware::tv::tuner::V1_1::IFilter::castFrom(filter);
mFilterCallback = callback;
@@ -103,6 +108,7 @@
break;
}
}
+ halSettings.ts(ts);
break;
}
}
@@ -113,6 +119,44 @@
return Status::ok();
}
+Status TunerFilter::getAvSharedHandleInfo(TunerFilterSharedHandleInfo* _aidl_return) {
+ if (mFilter_1_1 == nullptr) {
+ ALOGE("IFilter_1_1 is not initialized");
+ return Status::fromServiceSpecificError(static_cast<int32_t>(Result::UNAVAILABLE));
+ }
+
+ Result res;
+ mFilter_1_1->getAvSharedHandle([&](Result r, hidl_handle avMemory, uint64_t avMemSize) {
+ res = r;
+ if (res == Result::SUCCESS) {
+ TunerFilterSharedHandleInfo info{
+ .handle = dupToAidl(hidl_handle(avMemory.getNativeHandle())),
+ .size = static_cast<int64_t>(avMemSize),
+ };
+ *_aidl_return = std::move(info);
+ } else {
+ _aidl_return = NULL;
+ }
+ });
+
+ return Status::fromServiceSpecificError(static_cast<int32_t>(res));
+}
+
+Status TunerFilter::releaseAvHandle(
+ const ::aidl::android::hardware::common::NativeHandle& handle, int64_t avDataId) {
+ if (mFilter == nullptr) {
+ ALOGE("IFilter is not initialized");
+ return Status::fromServiceSpecificError(static_cast<int32_t>(Result::UNAVAILABLE));
+ }
+
+ Result res = mFilter->releaseAvHandle(hidl_handle(makeFromAidl(handle)), avDataId);
+ if (res != Result::SUCCESS) {
+ return Status::fromServiceSpecificError(static_cast<int32_t>(res));
+ }
+ return Status::ok();
+}
+
+
Status TunerFilter::start() {
if (mFilter == nullptr) {
ALOGE("IFilter is not initialized");
@@ -149,12 +193,117 @@
return Status::ok();
}
+Status TunerFilter::close() {
+ if (mFilter == nullptr) {
+ ALOGE("IFilter is not initialized");
+ return Status::fromServiceSpecificError(static_cast<int32_t>(Result::UNAVAILABLE));
+ }
+ Result res = mFilter->close();
+ if (res != Result::SUCCESS) {
+ return Status::fromServiceSpecificError(static_cast<int32_t>(res));
+ }
+ return Status::ok();
+}
+
sp<IFilter> TunerFilter::getHalFilter() {
return mFilter;
}
/////////////// FilterCallback ///////////////////////
+Return<void> TunerFilter::FilterCallback::onFilterStatus(DemuxFilterStatus status) {
+ if (mTunerFilterCallback != NULL) {
+ mTunerFilterCallback->onFilterStatus((int)status);
+ }
+ return Void();
+}
+
+Return<void> TunerFilter::FilterCallback::onFilterEvent(const DemuxFilterEvent& filterEvent) {
+ std::vector<DemuxFilterEventExt::Event> emptyEventsExt;
+ DemuxFilterEventExt emptyFilterEventExt {
+ .events = emptyEventsExt,
+ };
+ onFilterEvent_1_1(filterEvent, emptyFilterEventExt);
+ return Void();
+}
+
+Return<void> TunerFilter::FilterCallback::onFilterEvent_1_1(const DemuxFilterEvent& filterEvent,
+ const DemuxFilterEventExt& filterEventExt) {
+ if (mTunerFilterCallback != NULL) {
+ std::vector<DemuxFilterEvent::Event> events = filterEvent.events;
+ std::vector<DemuxFilterEventExt::Event> eventsExt = filterEventExt.events;
+ std::vector<TunerFilterEvent> tunerEvent;
+
+ getAidlFilterEvent(events, eventsExt, tunerEvent);
+ mTunerFilterCallback->onFilterEvent(tunerEvent);
+ }
+ return Void();
+}
+
+/////////////// FilterCallback Helper Methods ///////////////////////
+
+void TunerFilter::FilterCallback::getAidlFilterEvent(std::vector<DemuxFilterEvent::Event>& events,
+ std::vector<DemuxFilterEventExt::Event>& eventsExt,
+ std::vector<TunerFilterEvent>& tunerEvent) {
+ if (events.empty() && !eventsExt.empty()) {
+ auto eventExt = eventsExt[0];
+ switch (eventExt.getDiscriminator()) {
+ case DemuxFilterEventExt::Event::hidl_discriminator::monitorEvent: {
+ getMonitorEvent(eventsExt, tunerEvent);
+ break;
+ }
+ case DemuxFilterEventExt::Event::hidl_discriminator::startId: {
+ getRestartEvent(eventsExt, tunerEvent);
+ break;
+ }
+ default: {
+ break;
+ }
+ }
+ }
+
+ if (!events.empty()) {
+ auto event = events[0];
+ switch (event.getDiscriminator()) {
+ case DemuxFilterEvent::Event::hidl_discriminator::media: {
+ getMediaEvent(events, tunerEvent);
+ break;
+ }
+ case DemuxFilterEvent::Event::hidl_discriminator::section: {
+ getSectionEvent(events, tunerEvent);
+ break;
+ }
+ case DemuxFilterEvent::Event::hidl_discriminator::pes: {
+ getPesEvent(events, tunerEvent);
+ break;
+ }
+ case DemuxFilterEvent::Event::hidl_discriminator::tsRecord: {
+ getTsRecordEvent(events, eventsExt, tunerEvent);
+ break;
+ }
+ case DemuxFilterEvent::Event::hidl_discriminator::mmtpRecord: {
+ getMmtpRecordEvent(events, eventsExt, tunerEvent);
+ break;
+ }
+ case DemuxFilterEvent::Event::hidl_discriminator::download: {
+ getDownloadEvent(events, tunerEvent);
+ break;
+ }
+ case DemuxFilterEvent::Event::hidl_discriminator::ipPayload: {
+ getIpPayloadEvent(events, tunerEvent);
+ break;
+ }
+ case DemuxFilterEvent::Event::hidl_discriminator::temi: {
+ getTemiEvent(events, tunerEvent);
+ break;
+ }
+ default: {
+ break;
+ }
+ }
+ }
+}
+
void TunerFilter::FilterCallback::getMediaEvent(
std::vector<DemuxFilterEvent::Event>& events, std::vector<TunerFilterEvent>& res) {
for (DemuxFilterEvent::Event e : events) {
@@ -164,13 +313,34 @@
tunerMedia.streamId = static_cast<int>(mediaEvent.streamId);
tunerMedia.isPtsPresent = mediaEvent.isPtsPresent;
tunerMedia.pts = static_cast<long>(mediaEvent.pts);
- tunerMedia.dataLength = static_cast<long>(mediaEvent.dataLength);
- tunerMedia.offset = static_cast<long>(mediaEvent.offset);
+ tunerMedia.dataLength = static_cast<int>(mediaEvent.dataLength);
+ tunerMedia.offset = static_cast<int>(mediaEvent.offset);
tunerMedia.isSecureMemory = mediaEvent.isSecureMemory;
tunerMedia.avDataId = static_cast<long>(mediaEvent.avDataId);
tunerMedia.mpuSequenceNumber = static_cast<int>(mediaEvent.mpuSequenceNumber);
tunerMedia.isPesPrivateData = mediaEvent.isPesPrivateData;
+ if (mediaEvent.extraMetaData.getDiscriminator() ==
+ DemuxFilterMediaEvent::ExtraMetaData::hidl_discriminator::audio) {
+ tunerMedia.isAudioExtraMetaData = true;
+ tunerMedia.audio = {
+ .adFade = static_cast<int8_t>(
+ mediaEvent.extraMetaData.audio().adFade),
+ .adPan = static_cast<int8_t>(
+ mediaEvent.extraMetaData.audio().adPan),
+ .versionTextTag = static_cast<int8_t>(
+ mediaEvent.extraMetaData.audio().versionTextTag),
+ .adGainCenter = static_cast<int8_t>(
+ mediaEvent.extraMetaData.audio().adGainCenter),
+ .adGainFront = static_cast<int8_t>(
+ mediaEvent.extraMetaData.audio().adGainFront),
+ .adGainSurround = static_cast<int8_t>(
+ mediaEvent.extraMetaData.audio().adGainSurround),
+ };
+ } else {
+ tunerMedia.isAudioExtraMetaData = false;
+ }
+
if (mediaEvent.avMemory.getNativeHandle() != nullptr) {
tunerMedia.avMemory = dupToAidl(mediaEvent.avMemory.getNativeHandle());
}
@@ -181,30 +351,188 @@
}
}
-Return<void> TunerFilter::FilterCallback::onFilterStatus(DemuxFilterStatus status) {
- mTunerFilterCallback->onFilterStatus((int)status);
- return Void();
+void TunerFilter::FilterCallback::getSectionEvent(
+ std::vector<DemuxFilterEvent::Event>& events, std::vector<TunerFilterEvent>& res) {
+ for (DemuxFilterEvent::Event e : events) {
+ DemuxFilterSectionEvent sectionEvent = e.section();
+ TunerFilterSectionEvent tunerSection;
+
+ tunerSection.tableId = static_cast<char>(sectionEvent.tableId);
+ tunerSection.version = static_cast<char>(sectionEvent.version);
+ tunerSection.sectionNum = static_cast<char>(sectionEvent.sectionNum);
+ tunerSection.dataLength = static_cast<char>(sectionEvent.dataLength);
+
+ TunerFilterEvent tunerEvent;
+ tunerEvent.set<TunerFilterEvent::section>(std::move(tunerSection));
+ res.push_back(std::move(tunerEvent));
+ }
}
-Return<void> TunerFilter::FilterCallback::onFilterEvent(const DemuxFilterEvent& filterEvent) {
- ALOGD("FilterCallback::onFilterEvent");
- std::vector<DemuxFilterEvent::Event> events = filterEvent.events;
- std::vector<TunerFilterEvent> tunerEvent;
+void TunerFilter::FilterCallback::getPesEvent(
+ std::vector<DemuxFilterEvent::Event>& events, std::vector<TunerFilterEvent>& res) {
+ for (DemuxFilterEvent::Event e : events) {
+ DemuxFilterPesEvent pesEvent = e.pes();
+ TunerFilterPesEvent tunerPes;
- if (!events.empty()) {
- DemuxFilterEvent::Event event = events[0];
- switch (event.getDiscriminator()) {
- case DemuxFilterEvent::Event::hidl_discriminator::media: {
- getMediaEvent(events, tunerEvent);
- break;
- }
- default: {
- break;
- }
+ tunerPes.streamId = static_cast<char>(pesEvent.streamId);
+ tunerPes.dataLength = static_cast<int>(pesEvent.dataLength);
+ tunerPes.mpuSequenceNumber = static_cast<int>(pesEvent.mpuSequenceNumber);
+
+ TunerFilterEvent tunerEvent;
+ tunerEvent.set<TunerFilterEvent::pes>(std::move(tunerPes));
+ res.push_back(std::move(tunerEvent));
+ }
+}
+
+void TunerFilter::FilterCallback::getTsRecordEvent(std::vector<DemuxFilterEvent::Event>& events,
+ std::vector<DemuxFilterEventExt::Event>& eventsExt, std::vector<TunerFilterEvent>& res) {
+ for (int i = 0; i < events.size(); i++) {
+ TunerFilterTsRecordEvent tunerTsRecord;
+ DemuxFilterTsRecordEvent tsRecordEvent = events[i].tsRecord();
+
+ TunerFilterScIndexMask scIndexMask;
+ if (tsRecordEvent.scIndexMask.getDiscriminator()
+ == DemuxFilterTsRecordEvent::ScIndexMask::hidl_discriminator::sc) {
+ scIndexMask.set<TunerFilterScIndexMask::sc>(
+ static_cast<int>(tsRecordEvent.scIndexMask.sc()));
+ } else if (tsRecordEvent.scIndexMask.getDiscriminator()
+ == DemuxFilterTsRecordEvent::ScIndexMask::hidl_discriminator::scHevc) {
+ scIndexMask.set<TunerFilterScIndexMask::scHevc>(
+ static_cast<int>(tsRecordEvent.scIndexMask.scHevc()));
+ }
+
+ if (tsRecordEvent.pid.getDiscriminator() == DemuxPid::hidl_discriminator::tPid) {
+ tunerTsRecord.pid = static_cast<char>(tsRecordEvent.pid.tPid());
+ } else {
+ tunerTsRecord.pid = static_cast<char>(Constant::INVALID_TS_PID);
+ }
+
+ tunerTsRecord.scIndexMask = scIndexMask;
+ tunerTsRecord.tsIndexMask = static_cast<int>(tsRecordEvent.tsIndexMask);
+ tunerTsRecord.byteNumber = static_cast<long>(tsRecordEvent.byteNumber);
+
+ if (eventsExt.size() > i && eventsExt[i].getDiscriminator() ==
+ DemuxFilterEventExt::Event::hidl_discriminator::tsRecord) {
+ tunerTsRecord.isExtended = true;
+ tunerTsRecord.pts = static_cast<long>(eventsExt[i].tsRecord().pts);
+ tunerTsRecord.firstMbInSlice = static_cast<int>(eventsExt[i].tsRecord().firstMbInSlice);
+ } else {
+ tunerTsRecord.isExtended = false;
+ }
+
+ TunerFilterEvent tunerEvent;
+ tunerEvent.set<TunerFilterEvent::tsRecord>(std::move(tunerTsRecord));
+ res.push_back(std::move(tunerEvent));
+ }
+}
+
+void TunerFilter::FilterCallback::getMmtpRecordEvent(std::vector<DemuxFilterEvent::Event>& events,
+ std::vector<DemuxFilterEventExt::Event>& eventsExt, std::vector<TunerFilterEvent>& res) {
+ for (int i = 0; i < events.size(); i++) {
+ TunerFilterMmtpRecordEvent tunerMmtpRecord;
+ DemuxFilterMmtpRecordEvent mmtpRecordEvent = events[i].mmtpRecord();
+
+ tunerMmtpRecord.scHevcIndexMask = static_cast<int>(mmtpRecordEvent.scHevcIndexMask);
+ tunerMmtpRecord.byteNumber = static_cast<long>(mmtpRecordEvent.byteNumber);
+
+ if (eventsExt.size() > i && eventsExt[i].getDiscriminator() ==
+ DemuxFilterEventExt::Event::hidl_discriminator::mmtpRecord) {
+ tunerMmtpRecord.isExtended = true;
+ tunerMmtpRecord.pts = static_cast<long>(eventsExt[i].mmtpRecord().pts);
+ tunerMmtpRecord.mpuSequenceNumber =
+ static_cast<int>(eventsExt[i].mmtpRecord().mpuSequenceNumber);
+ tunerMmtpRecord.firstMbInSlice =
+ static_cast<int>(eventsExt[i].mmtpRecord().firstMbInSlice);
+ tunerMmtpRecord.tsIndexMask = static_cast<int>(eventsExt[i].mmtpRecord().tsIndexMask);
+ } else {
+ tunerMmtpRecord.isExtended = false;
+ }
+
+ TunerFilterEvent tunerEvent;
+ tunerEvent.set<TunerFilterEvent::mmtpRecord>(std::move(tunerMmtpRecord));
+ res.push_back(std::move(tunerEvent));
+ }
+}
+
+void TunerFilter::FilterCallback::getDownloadEvent(
+ std::vector<DemuxFilterEvent::Event>& events, std::vector<TunerFilterEvent>& res) {
+ for (DemuxFilterEvent::Event e : events) {
+ DemuxFilterDownloadEvent downloadEvent = e.download();
+ TunerFilterDownloadEvent tunerDownload;
+
+ tunerDownload.itemId = static_cast<int>(downloadEvent.itemId);
+ tunerDownload.itemFragmentIndex = static_cast<int>(downloadEvent.itemFragmentIndex);
+ tunerDownload.mpuSequenceNumber = static_cast<int>(downloadEvent.mpuSequenceNumber);
+ tunerDownload.lastItemFragmentIndex = static_cast<int>(downloadEvent.lastItemFragmentIndex);
+ tunerDownload.dataLength = static_cast<char>(downloadEvent.dataLength);
+
+ TunerFilterEvent tunerEvent;
+ tunerEvent.set<TunerFilterEvent::download>(std::move(tunerDownload));
+ res.push_back(std::move(tunerEvent));
+ }
+}
+
+void TunerFilter::FilterCallback::getIpPayloadEvent(
+ std::vector<DemuxFilterEvent::Event>& events, std::vector<TunerFilterEvent>& res) {
+ for (DemuxFilterEvent::Event e : events) {
+ DemuxFilterIpPayloadEvent ipPayloadEvent = e.ipPayload();
+ TunerFilterIpPayloadEvent tunerIpPayload;
+
+ tunerIpPayload.dataLength = static_cast<char>(ipPayloadEvent.dataLength);
+
+ TunerFilterEvent tunerEvent;
+ tunerEvent.set<TunerFilterEvent::ipPayload>(std::move(tunerIpPayload));
+ res.push_back(std::move(tunerEvent));
+ }
+}
+
+void TunerFilter::FilterCallback::getTemiEvent(
+ std::vector<DemuxFilterEvent::Event>& events, std::vector<TunerFilterEvent>& res) {
+ for (DemuxFilterEvent::Event e : events) {
+ DemuxFilterTemiEvent temiEvent = e.temi();
+ TunerFilterTemiEvent tunerTemi;
+
+ tunerTemi.pts = static_cast<long>(temiEvent.pts);
+ tunerTemi.descrTag = static_cast<int8_t>(temiEvent.descrTag);
+ std::vector<uint8_t> descrData = temiEvent.descrData;
+ tunerTemi.descrData.resize(descrData.size());
+ copy(descrData.begin(), descrData.end(), tunerTemi.descrData.begin());
+
+ TunerFilterEvent tunerEvent;
+ tunerEvent.set<TunerFilterEvent::temi>(std::move(tunerTemi));
+ res.push_back(std::move(tunerEvent));
+ }
+}
+
+void TunerFilter::FilterCallback::getMonitorEvent(
+ std::vector<DemuxFilterEventExt::Event>& eventsExt, std::vector<TunerFilterEvent>& res) {
+ DemuxFilterMonitorEvent monitorEvent = eventsExt[0].monitorEvent();
+ TunerFilterMonitorEvent tunerMonitor;
+
+ switch (monitorEvent.getDiscriminator()) {
+ case DemuxFilterMonitorEvent::hidl_discriminator::scramblingStatus: {
+ tunerMonitor.set<TunerFilterMonitorEvent::scramblingStatus>(
+ static_cast<int>(monitorEvent.scramblingStatus()));
+ break;
+ }
+ case DemuxFilterMonitorEvent::hidl_discriminator::cid: {
+ tunerMonitor.set<TunerFilterMonitorEvent::cid>(static_cast<int>(monitorEvent.cid()));
+ break;
+ }
+ default: {
+ break;
}
}
- mTunerFilterCallback->onFilterEvent(&tunerEvent);
- return Void();
+
+ TunerFilterEvent tunerEvent;
+ tunerEvent.set<TunerFilterEvent::monitor>(std::move(tunerMonitor));
+ res.push_back(std::move(tunerEvent));
}
+void TunerFilter::FilterCallback::getRestartEvent(
+ std::vector<DemuxFilterEventExt::Event>& eventsExt, std::vector<TunerFilterEvent>& res) {
+ TunerFilterEvent tunerEvent;
+ tunerEvent.set<TunerFilterEvent::startId>(static_cast<int>(eventsExt[0].startId()));
+ res.push_back(std::move(tunerEvent));
+}
} // namespace android
diff --git a/services/tuner/TunerFilter.h b/services/tuner/TunerFilter.h
index 7f5838c..422a12a 100644
--- a/services/tuner/TunerFilter.h
+++ b/services/tuner/TunerFilter.h
@@ -19,26 +19,49 @@
#include <aidl/android/media/tv/tuner/BnTunerFilter.h>
#include <aidl/android/media/tv/tuner/ITunerFilterCallback.h>
-#include <android/hardware/tv/tuner/1.1/IFilter.h>
+#include <aidlcommonsupport/NativeHandle.h>
#include <android/hardware/tv/tuner/1.0/ITuner.h>
+#include <android/hardware/tv/tuner/1.1/IFilter.h>
+#include <android/hardware/tv/tuner/1.1/IFilterCallback.h>
+#include <android/hardware/tv/tuner/1.1/types.h>
#include <media/stagefright/foundation/ADebug.h>
using Status = ::ndk::ScopedAStatus;
using ::aidl::android::media::tv::tuner::BnTunerFilter;
using ::aidl::android::media::tv::tuner::ITunerFilterCallback;
using ::aidl::android::media::tv::tuner::TunerFilterConfiguration;
+using ::aidl::android::media::tv::tuner::TunerFilterDownloadEvent;
+using ::aidl::android::media::tv::tuner::TunerFilterIpPayloadEvent;
using ::aidl::android::media::tv::tuner::TunerFilterEvent;
using ::aidl::android::media::tv::tuner::TunerFilterMediaEvent;
+using ::aidl::android::media::tv::tuner::TunerFilterMmtpRecordEvent;
+using ::aidl::android::media::tv::tuner::TunerFilterMonitorEvent;
+using ::aidl::android::media::tv::tuner::TunerFilterPesEvent;
+using ::aidl::android::media::tv::tuner::TunerFilterScIndexMask;
+using ::aidl::android::media::tv::tuner::TunerFilterSectionEvent;
+using ::aidl::android::media::tv::tuner::TunerFilterSharedHandleInfo;
using ::aidl::android::media::tv::tuner::TunerFilterSettings;
+using ::aidl::android::media::tv::tuner::TunerFilterTemiEvent;
+using ::aidl::android::media::tv::tuner::TunerFilterTsRecordEvent;
using ::android::hardware::Return;
using ::android::hardware::Void;
using ::android::hardware::tv::tuner::V1_0::DemuxFilterAvSettings;
+using ::android::hardware::tv::tuner::V1_0::DemuxFilterDownloadEvent;
+using ::android::hardware::tv::tuner::V1_0::DemuxFilterIpPayloadEvent;
using ::android::hardware::tv::tuner::V1_0::DemuxFilterEvent;
using ::android::hardware::tv::tuner::V1_0::DemuxFilterMediaEvent;
+using ::android::hardware::tv::tuner::V1_0::DemuxFilterMmtpRecordEvent;
+using ::android::hardware::tv::tuner::V1_0::DemuxFilterPesEvent;
+using ::android::hardware::tv::tuner::V1_0::DemuxFilterSectionEvent;
using ::android::hardware::tv::tuner::V1_0::DemuxFilterStatus;
+using ::android::hardware::tv::tuner::V1_0::DemuxFilterTemiEvent;
+using ::android::hardware::tv::tuner::V1_0::DemuxFilterTsRecordEvent;
+using ::android::hardware::tv::tuner::V1_0::DemuxPid;
using ::android::hardware::tv::tuner::V1_0::IFilter;
-using ::android::hardware::tv::tuner::V1_0::IFilterCallback;
-
+using ::android::hardware::tv::tuner::V1_1::DemuxFilterEventExt;
+using ::android::hardware::tv::tuner::V1_1::DemuxFilterMonitorEvent;
+using ::android::hardware::tv::tuner::V1_1::DemuxFilterTsRecordEventExt;
+using ::android::hardware::tv::tuner::V1_1::IFilterCallback;
namespace android {
@@ -50,9 +73,13 @@
Status getId(int32_t* _aidl_return) override;
Status getId64Bit(int64_t* _aidl_return) override;
Status configure(const TunerFilterConfiguration& config) override;
+ Status getAvSharedHandleInfo(TunerFilterSharedHandleInfo* _aidl_return) override;
+ Status releaseAvHandle(const ::aidl::android::hardware::common::NativeHandle& handle,
+ int64_t avDataId) override;
Status start() override;
Status stop() override;
Status flush() override;
+ Status close() override;
sp<IFilter> getHalFilter();
struct FilterCallback : public IFilterCallback {
@@ -60,9 +87,40 @@
: mTunerFilterCallback(tunerFilterCallback) {};
virtual Return<void> onFilterEvent(const DemuxFilterEvent& filterEvent);
+ virtual Return<void> onFilterEvent_1_1(const DemuxFilterEvent& filterEvent,
+ const DemuxFilterEventExt& filterEventExt);
virtual Return<void> onFilterStatus(DemuxFilterStatus status);
+
+ void getAidlFilterEvent(std::vector<DemuxFilterEvent::Event>& events,
+ std::vector<DemuxFilterEventExt::Event>& eventsExt,
+ std::vector<TunerFilterEvent>& tunerEvent);
+
void getMediaEvent(
std::vector<DemuxFilterEvent::Event>& events, std::vector<TunerFilterEvent>& res);
+ void getSectionEvent(
+ std::vector<DemuxFilterEvent::Event>& events, std::vector<TunerFilterEvent>& res);
+ void getPesEvent(
+ std::vector<DemuxFilterEvent::Event>& events, std::vector<TunerFilterEvent>& res);
+ void getTsRecordEvent(
+ std::vector<DemuxFilterEvent::Event>& events,
+ std::vector<DemuxFilterEventExt::Event>& eventsExt,
+ std::vector<TunerFilterEvent>& res);
+ void getMmtpRecordEvent(
+ std::vector<DemuxFilterEvent::Event>& events,
+ std::vector<DemuxFilterEventExt::Event>& eventsExt,
+ std::vector<TunerFilterEvent>& res);
+ void getDownloadEvent(
+ std::vector<DemuxFilterEvent::Event>& events, std::vector<TunerFilterEvent>& res);
+ void getIpPayloadEvent(
+ std::vector<DemuxFilterEvent::Event>& events, std::vector<TunerFilterEvent>& res);
+ void getTemiEvent(
+ std::vector<DemuxFilterEvent::Event>& events, std::vector<TunerFilterEvent>& res);
+ void getMonitorEvent(
+ std::vector<DemuxFilterEventExt::Event>& eventsExt,
+ std::vector<TunerFilterEvent>& res);
+ void getRestartEvent(
+ std::vector<DemuxFilterEventExt::Event>& eventsExt,
+ std::vector<TunerFilterEvent>& res);
std::shared_ptr<ITunerFilterCallback> mTunerFilterCallback;
};
diff --git a/services/tuner/TunerFrontend.cpp b/services/tuner/TunerFrontend.cpp
index e92489d..bb8b07d 100644
--- a/services/tuner/TunerFrontend.cpp
+++ b/services/tuner/TunerFrontend.cpp
@@ -66,7 +66,6 @@
using ::android::hardware::tv::tuner::V1_0::FrontendIsdbtSettings;
using ::android::hardware::tv::tuner::V1_0::FrontendScanAtsc3PlpInfo;
using ::android::hardware::tv::tuner::V1_0::FrontendScanType;
-using ::android::hardware::tv::tuner::V1_0::FrontendSettings;;
using ::android::hardware::tv::tuner::V1_0::Result;
using ::android::hardware::tv::tuner::V1_1::FrontendModulation;
@@ -80,6 +79,7 @@
TunerFrontend::~TunerFrontend() {
mFrontend = NULL;
+ mFrontend_1_1 = NULL;
mId = -1;
}
@@ -103,12 +103,33 @@
return Status::fromServiceSpecificError(static_cast<int32_t>(status));
}
-Status TunerFrontend::tune(const TunerFrontendSettings& /*settings*/) {
- return Status::ok();
+Status TunerFrontend::tune(const TunerFrontendSettings& settings) {
+ if (mFrontend == NULL) {
+ ALOGD("IFrontend is not initialized");
+ return Status::fromServiceSpecificError(static_cast<int32_t>(Result::UNAVAILABLE));
+ }
+
+ FrontendSettings frontendSettings = getHidlFrontendSettings(settings);
+ Result status = mFrontend->tune(frontendSettings);
+ if (status == Result::SUCCESS) {
+ return Status::ok();
+ }
+
+ return Status::fromServiceSpecificError(static_cast<int32_t>(status));
}
Status TunerFrontend::stopTune() {
- return Status::ok();
+ if (mFrontend == NULL) {
+ ALOGD("IFrontend is not initialized");
+ return Status::fromServiceSpecificError(static_cast<int32_t>(Result::UNAVAILABLE));
+ }
+
+ Result status = mFrontend->stopTune();
+ if (status == Result::SUCCESS) {
+ return Status::ok();
+ }
+
+ return Status::fromServiceSpecificError(static_cast<int32_t>(status));
}
Status TunerFrontend::scan(const TunerFrontendSettings& settings, int frontendScanType) {
@@ -117,165 +138,7 @@
return Status::fromServiceSpecificError(static_cast<int32_t>(Result::UNAVAILABLE));
}
- // TODO: extend TunerFrontendSettings to use 1.1 types
- FrontendSettings frontendSettings;
- switch (settings.getTag()) {
- case TunerFrontendSettings::analog:
- frontendSettings.analog({
- .frequency = static_cast<uint32_t>(
- settings.get<TunerFrontendSettings::analog>().frequency),
- .type = static_cast<FrontendAnalogType>(
- settings.get<TunerFrontendSettings::analog>().signalType),
- .sifStandard = static_cast<FrontendAnalogSifStandard>(
- settings.get<TunerFrontendSettings::analog>().sifStandard),
- });
- break;
- case TunerFrontendSettings::atsc:
- frontendSettings.atsc({
- .frequency = static_cast<uint32_t>(
- settings.get<TunerFrontendSettings::atsc>().frequency),
- .modulation = static_cast<FrontendAtscModulation>(
- settings.get<TunerFrontendSettings::atsc>().modulation),
- });
- break;
- case TunerFrontendSettings::atsc3:
- frontendSettings.atsc3({
- .frequency = static_cast<uint32_t>(
- settings.get<TunerFrontendSettings::atsc3>().frequency),
- .bandwidth = static_cast<FrontendAtsc3Bandwidth>(
- settings.get<TunerFrontendSettings::atsc3>().bandwidth),
- .demodOutputFormat = static_cast<FrontendAtsc3DemodOutputFormat>(
- settings.get<TunerFrontendSettings::atsc3>().demodOutputFormat),
- .plpSettings = getAtsc3PlpSettings(settings.get<TunerFrontendSettings::atsc3>()),
- });
- break;
- case TunerFrontendSettings::cable:
- frontendSettings.dvbc({
- .frequency = static_cast<uint32_t>(
- settings.get<TunerFrontendSettings::cable>().frequency),
- .modulation = static_cast<FrontendDvbcModulation>(
- settings.get<TunerFrontendSettings::cable>().modulation),
- .fec = static_cast<FrontendInnerFec>(
- settings.get<TunerFrontendSettings::cable>().innerFec),
- .symbolRate = static_cast<uint32_t>(
- settings.get<TunerFrontendSettings::cable>().symbolRate),
- .outerFec = static_cast<FrontendDvbcOuterFec>(
- settings.get<TunerFrontendSettings::cable>().outerFec),
- .annex = static_cast<FrontendDvbcAnnex>(
- settings.get<TunerFrontendSettings::cable>().annex),
- .spectralInversion = static_cast<FrontendDvbcSpectralInversion>(
- settings.get<TunerFrontendSettings::cable>().spectralInversion),
- });
- break;
- case TunerFrontendSettings::dvbs:
- frontendSettings.dvbs({
- .frequency = static_cast<uint32_t>(
- settings.get<TunerFrontendSettings::dvbs>().frequency),
- .modulation = static_cast<FrontendDvbsModulation>(
- settings.get<TunerFrontendSettings::dvbs>().modulation),
- .coderate = getDvbsCodeRate(
- settings.get<TunerFrontendSettings::dvbs>().codeRate),
- .symbolRate = static_cast<uint32_t>(
- settings.get<TunerFrontendSettings::dvbs>().symbolRate),
- .rolloff = static_cast<FrontendDvbsRolloff>(
- settings.get<TunerFrontendSettings::dvbs>().rolloff),
- .pilot = static_cast<FrontendDvbsPilot>(
- settings.get<TunerFrontendSettings::dvbs>().pilot),
- .inputStreamId = static_cast<uint32_t>(
- settings.get<TunerFrontendSettings::dvbs>().inputStreamId),
- .standard = static_cast<FrontendDvbsStandard>(
- settings.get<TunerFrontendSettings::dvbs>().standard),
- .vcmMode = static_cast<FrontendDvbsVcmMode>(
- settings.get<TunerFrontendSettings::dvbs>().vcm),
- });
- break;
- case TunerFrontendSettings::dvbt:
- frontendSettings.dvbt({
- .frequency = static_cast<uint32_t>(
- settings.get<TunerFrontendSettings::dvbt>().frequency),
- .transmissionMode = static_cast<FrontendDvbtTransmissionMode>(
- settings.get<TunerFrontendSettings::dvbt>().transmissionMode),
- .bandwidth = static_cast<FrontendDvbtBandwidth>(
- settings.get<TunerFrontendSettings::dvbt>().bandwidth),
- .constellation = static_cast<FrontendDvbtConstellation>(
- settings.get<TunerFrontendSettings::dvbt>().constellation),
- .hierarchy = static_cast<FrontendDvbtHierarchy>(
- settings.get<TunerFrontendSettings::dvbt>().hierarchy),
- .hpCoderate = static_cast<FrontendDvbtCoderate>(
- settings.get<TunerFrontendSettings::dvbt>().hpCodeRate),
- .lpCoderate = static_cast<FrontendDvbtCoderate>(
- settings.get<TunerFrontendSettings::dvbt>().lpCodeRate),
- .guardInterval = static_cast<FrontendDvbtGuardInterval>(
- settings.get<TunerFrontendSettings::dvbt>().guardInterval),
- .isHighPriority = settings.get<TunerFrontendSettings::dvbt>().isHighPriority,
- .standard = static_cast<FrontendDvbtStandard>(
- settings.get<TunerFrontendSettings::dvbt>().standard),
- .isMiso = settings.get<TunerFrontendSettings::dvbt>().isMiso,
- .plpMode = static_cast<FrontendDvbtPlpMode>(
- settings.get<TunerFrontendSettings::dvbt>().plpMode),
- .plpId = static_cast<uint8_t>(
- settings.get<TunerFrontendSettings::dvbt>().plpId),
- .plpGroupId = static_cast<uint8_t>(
- settings.get<TunerFrontendSettings::dvbt>().plpGroupId),
- });
- break;
- case TunerFrontendSettings::isdbs:
- frontendSettings.isdbs({
- .frequency = static_cast<uint32_t>(
- settings.get<TunerFrontendSettings::isdbs>().frequency),
- .streamId = static_cast<uint16_t>(
- settings.get<TunerFrontendSettings::isdbs>().streamId),
- .streamIdType = static_cast<FrontendIsdbsStreamIdType>(
- settings.get<TunerFrontendSettings::isdbs>().streamIdType),
- .modulation = static_cast<FrontendIsdbsModulation>(
- settings.get<TunerFrontendSettings::isdbs>().modulation),
- .coderate = static_cast<FrontendIsdbsCoderate>(
- settings.get<TunerFrontendSettings::isdbs>().codeRate),
- .symbolRate = static_cast<uint32_t>(
- settings.get<TunerFrontendSettings::isdbs>().symbolRate),
- .rolloff = static_cast<FrontendIsdbsRolloff>(
- settings.get<TunerFrontendSettings::isdbs>().rolloff),
- });
- break;
- case TunerFrontendSettings::isdbs3:
- frontendSettings.isdbs3({
- .frequency = static_cast<uint32_t>(
- settings.get<TunerFrontendSettings::isdbs3>().frequency),
- .streamId = static_cast<uint16_t>(
- settings.get<TunerFrontendSettings::isdbs3>().streamId),
- .streamIdType = static_cast<FrontendIsdbsStreamIdType>(
- settings.get<TunerFrontendSettings::isdbs3>().streamIdType),
- .modulation = static_cast<FrontendIsdbs3Modulation>(
- settings.get<TunerFrontendSettings::isdbs3>().modulation),
- .coderate = static_cast<FrontendIsdbs3Coderate>(
- settings.get<TunerFrontendSettings::isdbs3>().codeRate),
- .symbolRate = static_cast<uint32_t>(
- settings.get<TunerFrontendSettings::isdbs3>().symbolRate),
- .rolloff = static_cast<FrontendIsdbs3Rolloff>(
- settings.get<TunerFrontendSettings::isdbs3>().rolloff),
- });
- break;
- case TunerFrontendSettings::isdbt:
- frontendSettings.isdbt({
- .frequency = static_cast<uint32_t>(
- settings.get<TunerFrontendSettings::isdbt>().frequency),
- .modulation = static_cast<FrontendIsdbtModulation>(
- settings.get<TunerFrontendSettings::isdbt>().modulation),
- .bandwidth = static_cast<FrontendIsdbtBandwidth>(
- settings.get<TunerFrontendSettings::isdbt>().bandwidth),
- .mode = static_cast<FrontendIsdbtMode>(
- settings.get<TunerFrontendSettings::isdbt>().mode),
- .coderate = static_cast<FrontendIsdbtCoderate>(
- settings.get<TunerFrontendSettings::isdbt>().codeRate),
- .guardInterval = static_cast<FrontendIsdbtGuardInterval>(
- settings.get<TunerFrontendSettings::isdbt>().guardInterval),
- .serviceAreaId = static_cast<uint32_t>(
- settings.get<TunerFrontendSettings::isdbt>().serviceAreaId),
- });
- break;
- default:
- break;
- }
+ FrontendSettings frontendSettings = getHidlFrontendSettings(settings);
Result status = mFrontend->scan(
frontendSettings, static_cast<FrontendScanType>(frontendScanType));
if (status == Result::SUCCESS) {
@@ -286,7 +149,17 @@
}
Status TunerFrontend::stopScan() {
- return Status::ok();
+ if (mFrontend == NULL) {
+ ALOGD("IFrontend is not initialized");
+ return Status::fromServiceSpecificError(static_cast<int32_t>(Result::UNAVAILABLE));
+ }
+
+ Result status = mFrontend->stopScan();
+ if (status == Result::SUCCESS) {
+ return Status::ok();
+ }
+
+ return Status::fromServiceSpecificError(static_cast<int32_t>(status));
}
Status TunerFrontend::setLnb(int /*lnbHandle*/) {
@@ -298,7 +171,17 @@
}
Status TunerFrontend::close() {
- return Status::ok();
+ if (mFrontend == NULL) {
+ ALOGD("IFrontend is not initialized");
+ return Status::fromServiceSpecificError(static_cast<int32_t>(Result::UNAVAILABLE));
+ }
+
+ Result status = mFrontend->close();
+ if (status == Result::SUCCESS) {
+ return Status::ok();
+ }
+
+ return Status::fromServiceSpecificError(static_cast<int32_t>(status));
}
Status TunerFrontend::getStatus(const vector<int32_t>& /*statusTypes*/,
@@ -500,4 +383,167 @@
};
return coderate;
}
+
+FrontendSettings TunerFrontend::getHidlFrontendSettings(const TunerFrontendSettings& settings) {
+ // TODO: extend TunerFrontendSettings to use 1.1 types
+ FrontendSettings frontendSettings;
+ switch (settings.getTag()) {
+ case TunerFrontendSettings::analog:
+ frontendSettings.analog({
+ .frequency = static_cast<uint32_t>(
+ settings.get<TunerFrontendSettings::analog>().frequency),
+ .type = static_cast<FrontendAnalogType>(
+ settings.get<TunerFrontendSettings::analog>().signalType),
+ .sifStandard = static_cast<FrontendAnalogSifStandard>(
+ settings.get<TunerFrontendSettings::analog>().sifStandard),
+ });
+ break;
+ case TunerFrontendSettings::atsc:
+ frontendSettings.atsc({
+ .frequency = static_cast<uint32_t>(
+ settings.get<TunerFrontendSettings::atsc>().frequency),
+ .modulation = static_cast<FrontendAtscModulation>(
+ settings.get<TunerFrontendSettings::atsc>().modulation),
+ });
+ break;
+ case TunerFrontendSettings::atsc3:
+ frontendSettings.atsc3({
+ .frequency = static_cast<uint32_t>(
+ settings.get<TunerFrontendSettings::atsc3>().frequency),
+ .bandwidth = static_cast<FrontendAtsc3Bandwidth>(
+ settings.get<TunerFrontendSettings::atsc3>().bandwidth),
+ .demodOutputFormat = static_cast<FrontendAtsc3DemodOutputFormat>(
+ settings.get<TunerFrontendSettings::atsc3>().demodOutputFormat),
+ .plpSettings = getAtsc3PlpSettings(settings.get<TunerFrontendSettings::atsc3>()),
+ });
+ break;
+ case TunerFrontendSettings::cable:
+ frontendSettings.dvbc({
+ .frequency = static_cast<uint32_t>(
+ settings.get<TunerFrontendSettings::cable>().frequency),
+ .modulation = static_cast<FrontendDvbcModulation>(
+ settings.get<TunerFrontendSettings::cable>().modulation),
+ .fec = static_cast<FrontendInnerFec>(
+ settings.get<TunerFrontendSettings::cable>().innerFec),
+ .symbolRate = static_cast<uint32_t>(
+ settings.get<TunerFrontendSettings::cable>().symbolRate),
+ .outerFec = static_cast<FrontendDvbcOuterFec>(
+ settings.get<TunerFrontendSettings::cable>().outerFec),
+ .annex = static_cast<FrontendDvbcAnnex>(
+ settings.get<TunerFrontendSettings::cable>().annex),
+ .spectralInversion = static_cast<FrontendDvbcSpectralInversion>(
+ settings.get<TunerFrontendSettings::cable>().spectralInversion),
+ });
+ break;
+ case TunerFrontendSettings::dvbs:
+ frontendSettings.dvbs({
+ .frequency = static_cast<uint32_t>(
+ settings.get<TunerFrontendSettings::dvbs>().frequency),
+ .modulation = static_cast<FrontendDvbsModulation>(
+ settings.get<TunerFrontendSettings::dvbs>().modulation),
+ .coderate = getDvbsCodeRate(
+ settings.get<TunerFrontendSettings::dvbs>().codeRate),
+ .symbolRate = static_cast<uint32_t>(
+ settings.get<TunerFrontendSettings::dvbs>().symbolRate),
+ .rolloff = static_cast<FrontendDvbsRolloff>(
+ settings.get<TunerFrontendSettings::dvbs>().rolloff),
+ .pilot = static_cast<FrontendDvbsPilot>(
+ settings.get<TunerFrontendSettings::dvbs>().pilot),
+ .inputStreamId = static_cast<uint32_t>(
+ settings.get<TunerFrontendSettings::dvbs>().inputStreamId),
+ .standard = static_cast<FrontendDvbsStandard>(
+ settings.get<TunerFrontendSettings::dvbs>().standard),
+ .vcmMode = static_cast<FrontendDvbsVcmMode>(
+ settings.get<TunerFrontendSettings::dvbs>().vcm),
+ });
+ break;
+ case TunerFrontendSettings::dvbt:
+ frontendSettings.dvbt({
+ .frequency = static_cast<uint32_t>(
+ settings.get<TunerFrontendSettings::dvbt>().frequency),
+ .transmissionMode = static_cast<FrontendDvbtTransmissionMode>(
+ settings.get<TunerFrontendSettings::dvbt>().transmissionMode),
+ .bandwidth = static_cast<FrontendDvbtBandwidth>(
+ settings.get<TunerFrontendSettings::dvbt>().bandwidth),
+ .constellation = static_cast<FrontendDvbtConstellation>(
+ settings.get<TunerFrontendSettings::dvbt>().constellation),
+ .hierarchy = static_cast<FrontendDvbtHierarchy>(
+ settings.get<TunerFrontendSettings::dvbt>().hierarchy),
+ .hpCoderate = static_cast<FrontendDvbtCoderate>(
+ settings.get<TunerFrontendSettings::dvbt>().hpCodeRate),
+ .lpCoderate = static_cast<FrontendDvbtCoderate>(
+ settings.get<TunerFrontendSettings::dvbt>().lpCodeRate),
+ .guardInterval = static_cast<FrontendDvbtGuardInterval>(
+ settings.get<TunerFrontendSettings::dvbt>().guardInterval),
+ .isHighPriority = settings.get<TunerFrontendSettings::dvbt>().isHighPriority,
+ .standard = static_cast<FrontendDvbtStandard>(
+ settings.get<TunerFrontendSettings::dvbt>().standard),
+ .isMiso = settings.get<TunerFrontendSettings::dvbt>().isMiso,
+ .plpMode = static_cast<FrontendDvbtPlpMode>(
+ settings.get<TunerFrontendSettings::dvbt>().plpMode),
+ .plpId = static_cast<uint8_t>(
+ settings.get<TunerFrontendSettings::dvbt>().plpId),
+ .plpGroupId = static_cast<uint8_t>(
+ settings.get<TunerFrontendSettings::dvbt>().plpGroupId),
+ });
+ break;
+ case TunerFrontendSettings::isdbs:
+ frontendSettings.isdbs({
+ .frequency = static_cast<uint32_t>(
+ settings.get<TunerFrontendSettings::isdbs>().frequency),
+ .streamId = static_cast<uint16_t>(
+ settings.get<TunerFrontendSettings::isdbs>().streamId),
+ .streamIdType = static_cast<FrontendIsdbsStreamIdType>(
+ settings.get<TunerFrontendSettings::isdbs>().streamIdType),
+ .modulation = static_cast<FrontendIsdbsModulation>(
+ settings.get<TunerFrontendSettings::isdbs>().modulation),
+ .coderate = static_cast<FrontendIsdbsCoderate>(
+ settings.get<TunerFrontendSettings::isdbs>().codeRate),
+ .symbolRate = static_cast<uint32_t>(
+ settings.get<TunerFrontendSettings::isdbs>().symbolRate),
+ .rolloff = static_cast<FrontendIsdbsRolloff>(
+ settings.get<TunerFrontendSettings::isdbs>().rolloff),
+ });
+ break;
+ case TunerFrontendSettings::isdbs3:
+ frontendSettings.isdbs3({
+ .frequency = static_cast<uint32_t>(
+ settings.get<TunerFrontendSettings::isdbs3>().frequency),
+ .streamId = static_cast<uint16_t>(
+ settings.get<TunerFrontendSettings::isdbs3>().streamId),
+ .streamIdType = static_cast<FrontendIsdbsStreamIdType>(
+ settings.get<TunerFrontendSettings::isdbs3>().streamIdType),
+ .modulation = static_cast<FrontendIsdbs3Modulation>(
+ settings.get<TunerFrontendSettings::isdbs3>().modulation),
+ .coderate = static_cast<FrontendIsdbs3Coderate>(
+ settings.get<TunerFrontendSettings::isdbs3>().codeRate),
+ .symbolRate = static_cast<uint32_t>(
+ settings.get<TunerFrontendSettings::isdbs3>().symbolRate),
+ .rolloff = static_cast<FrontendIsdbs3Rolloff>(
+ settings.get<TunerFrontendSettings::isdbs3>().rolloff),
+ });
+ break;
+ case TunerFrontendSettings::isdbt:
+ frontendSettings.isdbt({
+ .frequency = static_cast<uint32_t>(
+ settings.get<TunerFrontendSettings::isdbt>().frequency),
+ .modulation = static_cast<FrontendIsdbtModulation>(
+ settings.get<TunerFrontendSettings::isdbt>().modulation),
+ .bandwidth = static_cast<FrontendIsdbtBandwidth>(
+ settings.get<TunerFrontendSettings::isdbt>().bandwidth),
+ .mode = static_cast<FrontendIsdbtMode>(
+ settings.get<TunerFrontendSettings::isdbt>().mode),
+ .coderate = static_cast<FrontendIsdbtCoderate>(
+ settings.get<TunerFrontendSettings::isdbt>().codeRate),
+ .guardInterval = static_cast<FrontendIsdbtGuardInterval>(
+ settings.get<TunerFrontendSettings::isdbt>().guardInterval),
+ .serviceAreaId = static_cast<uint32_t>(
+ settings.get<TunerFrontendSettings::isdbt>().serviceAreaId),
+ });
+ break;
+ default:
+ break;
+ }
+ return frontendSettings;
+}
} // namespace android
diff --git a/services/tuner/TunerFrontend.h b/services/tuner/TunerFrontend.h
index 99cdcdf..431022d 100644
--- a/services/tuner/TunerFrontend.h
+++ b/services/tuner/TunerFrontend.h
@@ -41,6 +41,7 @@
using ::android::hardware::tv::tuner::V1_0::FrontendId;
using ::android::hardware::tv::tuner::V1_0::FrontendScanMessage;
using ::android::hardware::tv::tuner::V1_0::FrontendScanMessageType;
+using ::android::hardware::tv::tuner::V1_0::FrontendSettings;;
using ::android::hardware::tv::tuner::V1_0::IFrontend;
using ::android::hardware::tv::tuner::V1_1::IFrontendCallback;
using ::android::hardware::tv::tuner::V1_1::FrontendScanMessageExt1_1;
@@ -85,6 +86,7 @@
hidl_vec<FrontendAtsc3PlpSettings> getAtsc3PlpSettings(
const TunerFrontendAtsc3Settings& settings);
FrontendDvbsCodeRate getDvbsCodeRate(const TunerFrontendDvbsCodeRate& codeRate);
+ FrontendSettings getHidlFrontendSettings(const TunerFrontendSettings& settings);
int mId;
sp<IFrontend> mFrontend;
diff --git a/services/tuner/aidl/android/media/tv/tuner/ITunerDemux.aidl b/services/tuner/aidl/android/media/tv/tuner/ITunerDemux.aidl
index f6de618..fa2c1ff 100644
--- a/services/tuner/aidl/android/media/tv/tuner/ITunerDemux.aidl
+++ b/services/tuner/aidl/android/media/tv/tuner/ITunerDemux.aidl
@@ -44,4 +44,9 @@
* Open a DVR (Digital Video Record) instance in the demux.
*/
ITunerDvr openDvr(in int dvbType, in int bufferSize, in ITunerDvrCallback cb);
+
+ /**
+ * Releases the ITunerDemux instance.
+ */
+ void close();
}
diff --git a/services/tuner/aidl/android/media/tv/tuner/ITunerFilter.aidl b/services/tuner/aidl/android/media/tv/tuner/ITunerFilter.aidl
index 37166aa..1d5544f 100644
--- a/services/tuner/aidl/android/media/tv/tuner/ITunerFilter.aidl
+++ b/services/tuner/aidl/android/media/tv/tuner/ITunerFilter.aidl
@@ -16,7 +16,9 @@
package android.media.tv.tuner;
+import android.hardware.common.NativeHandle;
import android.media.tv.tuner.TunerFilterConfiguration;
+import android.media.tv.tuner.TunerFilterSharedHandleInfo;
/**
* Tuner Filter interface handles tuner related operations.
@@ -40,6 +42,16 @@
void configure(in TunerFilterConfiguration config);
/**
+ * Get the a/v shared memory handle
+ */
+ TunerFilterSharedHandleInfo getAvSharedHandleInfo();
+
+ /**
+ * Release the handle reported by the HAL for AV memory.
+ */
+ void releaseAvHandle(in NativeHandle handle, in long avDataId);
+
+ /**
* Start the filter.
*/
void start();
@@ -53,4 +65,9 @@
* Flush the filter.
*/
void flush();
+
+ /**
+ * Close the filter.
+ */
+ void close();
}
diff --git a/services/tuner/aidl/android/media/tv/tuner/ITunerFilterCallback.aidl b/services/tuner/aidl/android/media/tv/tuner/ITunerFilterCallback.aidl
index f9f86ac..e7a52a7 100644
--- a/services/tuner/aidl/android/media/tv/tuner/ITunerFilterCallback.aidl
+++ b/services/tuner/aidl/android/media/tv/tuner/ITunerFilterCallback.aidl
@@ -32,5 +32,5 @@
/**
* Notify the client that a new filter event happened.
*/
- void onFilterEvent(out TunerFilterEvent[] filterEvent);
+ void onFilterEvent(in TunerFilterEvent[] filterEvent);
}
diff --git a/services/tuner/aidl/android/media/tv/tuner/TunerAudioExtraMetaData.aidl b/services/tuner/aidl/android/media/tv/tuner/TunerAudioExtraMetaData.aidl
new file mode 100644
index 0000000..d3e4735
--- /dev/null
+++ b/services/tuner/aidl/android/media/tv/tuner/TunerAudioExtraMetaData.aidl
@@ -0,0 +1,36 @@
+/**
+ * Copyright 2021, 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.
+ */
+
+package android.media.tv.tuner;
+
+/**
+ * Extra Meta Data from AD (Audio Descriptor) according to ETSI TS 101 154 V2.1.1.
+ *
+ * {@hide}
+ */
+parcelable TunerAudioExtraMetaData {
+ byte adFade;
+
+ byte adPan;
+
+ byte versionTextTag;
+
+ byte adGainCenter;
+
+ byte adGainFront;
+
+ byte adGainSurround;
+}
diff --git a/services/tuner/aidl/android/media/tv/tuner/TunerFilterDownloadEvent.aidl b/services/tuner/aidl/android/media/tv/tuner/TunerFilterDownloadEvent.aidl
new file mode 100644
index 0000000..b971dd3
--- /dev/null
+++ b/services/tuner/aidl/android/media/tv/tuner/TunerFilterDownloadEvent.aidl
@@ -0,0 +1,40 @@
+/**
+ * Copyright 2021, 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.
+ */
+
+package android.media.tv.tuner;
+
+/**
+ * Filter Event for Download data.
+ *
+ * {@hide}
+ */
+parcelable TunerFilterDownloadEvent {
+ int itemId;
+
+ /**
+ * MPU sequence number of filtered data (only for MMTP)
+ */
+ int mpuSequenceNumber;
+
+ int itemFragmentIndex;
+
+ int lastItemFragmentIndex;
+
+ /**
+ * Data size in bytes of filtered data
+ */
+ char dataLength;
+}
diff --git a/services/tuner/aidl/android/media/tv/tuner/TunerFilterEvent.aidl b/services/tuner/aidl/android/media/tv/tuner/TunerFilterEvent.aidl
index ad95112..1305510 100644
--- a/services/tuner/aidl/android/media/tv/tuner/TunerFilterEvent.aidl
+++ b/services/tuner/aidl/android/media/tv/tuner/TunerFilterEvent.aidl
@@ -16,7 +16,15 @@
package android.media.tv.tuner;
+import android.media.tv.tuner.TunerFilterDownloadEvent;
+import android.media.tv.tuner.TunerFilterIpPayloadEvent;
import android.media.tv.tuner.TunerFilterMediaEvent;
+import android.media.tv.tuner.TunerFilterMmtpRecordEvent;
+import android.media.tv.tuner.TunerFilterMonitorEvent;
+import android.media.tv.tuner.TunerFilterPesEvent;
+import android.media.tv.tuner.TunerFilterSectionEvent;
+import android.media.tv.tuner.TunerFilterTemiEvent;
+import android.media.tv.tuner.TunerFilterTsRecordEvent;
/**
* Filter events.
@@ -25,4 +33,22 @@
*/
union TunerFilterEvent {
TunerFilterMediaEvent media;
+
+ TunerFilterSectionEvent section;
+
+ TunerFilterPesEvent pes;
+
+ TunerFilterTsRecordEvent tsRecord;
+
+ TunerFilterMmtpRecordEvent mmtpRecord;
+
+ TunerFilterDownloadEvent download;
+
+ TunerFilterIpPayloadEvent ipPayload;
+
+ TunerFilterTemiEvent temi;
+
+ TunerFilterMonitorEvent monitor;
+
+ int startId;
}
diff --git a/services/tuner/aidl/android/media/tv/tuner/TunerFilterIpPayloadEvent.aidl b/services/tuner/aidl/android/media/tv/tuner/TunerFilterIpPayloadEvent.aidl
new file mode 100644
index 0000000..d5bda93
--- /dev/null
+++ b/services/tuner/aidl/android/media/tv/tuner/TunerFilterIpPayloadEvent.aidl
@@ -0,0 +1,29 @@
+/**
+ * Copyright 2021, 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.
+ */
+
+package android.media.tv.tuner;
+
+/**
+ * Filter Event for IP payload data.
+ *
+ * {@hide}
+ */
+parcelable TunerFilterIpPayloadEvent {
+ /**
+ * Data size in bytes of ip data
+ */
+ char dataLength;
+}
diff --git a/services/tuner/aidl/android/media/tv/tuner/TunerFilterMediaEvent.aidl b/services/tuner/aidl/android/media/tv/tuner/TunerFilterMediaEvent.aidl
index 486a15c..5842c0d 100644
--- a/services/tuner/aidl/android/media/tv/tuner/TunerFilterMediaEvent.aidl
+++ b/services/tuner/aidl/android/media/tv/tuner/TunerFilterMediaEvent.aidl
@@ -17,6 +17,7 @@
package android.media.tv.tuner;
import android.hardware.common.NativeHandle;
+import android.media.tv.tuner.TunerAudioExtraMetaData;
/**
* Filter Event for Audio or Video Filter.
@@ -71,5 +72,13 @@
boolean isPesPrivateData;
- // TODO: add ExtraMetaData
+ /**
+ * If TunerAudioExtraMetaData field is valid or not
+ */
+ boolean isAudioExtraMetaData;
+
+ /**
+ * Only valid when isAudioExtraMetaData is true
+ */
+ TunerAudioExtraMetaData audio;
}
diff --git a/services/tuner/aidl/android/media/tv/tuner/TunerFilterMmtpRecordEvent.aidl b/services/tuner/aidl/android/media/tv/tuner/TunerFilterMmtpRecordEvent.aidl
new file mode 100644
index 0000000..dfbb9e2
--- /dev/null
+++ b/services/tuner/aidl/android/media/tv/tuner/TunerFilterMmtpRecordEvent.aidl
@@ -0,0 +1,57 @@
+/**
+ * Copyright 2021, 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.
+ */
+
+package android.media.tv.tuner;
+
+/**
+ * Filter Event for MMTP Record Filter.
+ *
+ * {@hide}
+ */
+parcelable TunerFilterMmtpRecordEvent {
+ int scHevcIndexMask;
+
+ /**
+ * Byte number from beginning of the filter's output
+ */
+ long byteNumber;
+
+ /**
+ * If the current event contains extended information or not
+ */
+ boolean isExtended;
+
+ /**
+ * The Presentation Time Stamp(PTS) for the audio or video frame. It is based on 90KHz
+ * and has the same format as the PTS in ISO/IEC 13818-1.
+ */
+ long pts;
+
+ /**
+ * MPU sequence number of the filtered data. This is only used for MMTP.
+ */
+ int mpuSequenceNumber;
+
+ /**
+ * Specifies the address of the first macroblock in the slice defined in ITU-T Rec. H.264.
+ */
+ int firstMbInSlice;
+
+ /**
+ * TS index mask.
+ */
+ int tsIndexMask;
+}
diff --git a/services/tuner/aidl/android/media/tv/tuner/TunerFilterMonitorEvent.aidl b/services/tuner/aidl/android/media/tv/tuner/TunerFilterMonitorEvent.aidl
new file mode 100644
index 0000000..31ab5e6
--- /dev/null
+++ b/services/tuner/aidl/android/media/tv/tuner/TunerFilterMonitorEvent.aidl
@@ -0,0 +1,34 @@
+/**
+ * Copyright 2021, 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.
+ */
+
+package android.media.tv.tuner;
+
+/**
+ * Filter monitor events.
+ *
+ * {@hide}
+ */
+union TunerFilterMonitorEvent {
+ /**
+ * New scrambling status.
+ */
+ int scramblingStatus;
+
+ /**
+ * New cid for the IP filter.
+ */
+ int cid;
+}
diff --git a/services/tuner/aidl/android/media/tv/tuner/TunerFilterPesEvent.aidl b/services/tuner/aidl/android/media/tv/tuner/TunerFilterPesEvent.aidl
new file mode 100644
index 0000000..f7ee286
--- /dev/null
+++ b/services/tuner/aidl/android/media/tv/tuner/TunerFilterPesEvent.aidl
@@ -0,0 +1,36 @@
+/**
+ * Copyright 2021, 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.
+ */
+
+package android.media.tv.tuner;
+
+/**
+ * Filter Event for PES Filter.
+ *
+ * {@hide}
+ */
+parcelable TunerFilterPesEvent {
+ char streamId;
+
+ /**
+ * Data size in bytes of PES data
+ */
+ int dataLength;
+
+ /**
+ * MPU sequence number of filtered data
+ */
+ int mpuSequenceNumber;
+}
diff --git a/services/tuner/aidl/android/media/tv/tuner/TunerFilterScIndexMask.aidl b/services/tuner/aidl/android/media/tv/tuner/TunerFilterScIndexMask.aidl
new file mode 100644
index 0000000..ed37fce
--- /dev/null
+++ b/services/tuner/aidl/android/media/tv/tuner/TunerFilterScIndexMask.aidl
@@ -0,0 +1,28 @@
+/**
+ * Copyright 2021, 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.
+ */
+
+package android.media.tv.tuner;
+
+/**
+ * Filter SC Index Mask
+ *
+ * {@hide}
+ */
+union TunerFilterScIndexMask {
+ int sc;
+
+ int scHevc;
+}
diff --git a/services/tuner/aidl/android/media/tv/tuner/TunerFilterSectionEvent.aidl b/services/tuner/aidl/android/media/tv/tuner/TunerFilterSectionEvent.aidl
new file mode 100644
index 0000000..5f20926
--- /dev/null
+++ b/services/tuner/aidl/android/media/tv/tuner/TunerFilterSectionEvent.aidl
@@ -0,0 +1,44 @@
+/**
+ * Copyright 2021, 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.
+ */
+
+package android.media.tv.tuner;
+
+/**
+ * Filter Event for Section Filter.
+ *
+ * {@hide}
+ */
+parcelable TunerFilterSectionEvent {
+ /**
+ * Table ID of filtered data
+ */
+ char tableId;
+
+ /**
+ * Version number of filtered data
+ */
+ char version;
+
+ /**
+ * Section number of filtered data
+ */
+ char sectionNum;
+
+ /**
+ * Data size in bytes of filtered data
+ */
+ char dataLength;
+}
diff --git a/services/tuner/aidl/android/media/tv/tuner/TunerFilterSharedHandleInfo.aidl b/services/tuner/aidl/android/media/tv/tuner/TunerFilterSharedHandleInfo.aidl
new file mode 100644
index 0000000..122dfc3
--- /dev/null
+++ b/services/tuner/aidl/android/media/tv/tuner/TunerFilterSharedHandleInfo.aidl
@@ -0,0 +1,29 @@
+/**
+ * Copyright 2021, 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.
+ */
+
+package android.media.tv.tuner;
+
+import android.hardware.common.NativeHandle;
+
+/**
+ * Filter Shared Handle Information.
+ *
+ * {@hide}
+ */
+parcelable TunerFilterSharedHandleInfo {
+ NativeHandle handle;
+ long size;
+}
\ No newline at end of file
diff --git a/services/tuner/aidl/android/media/tv/tuner/TunerFilterTemiEvent.aidl b/services/tuner/aidl/android/media/tv/tuner/TunerFilterTemiEvent.aidl
new file mode 100644
index 0000000..4c4e993
--- /dev/null
+++ b/services/tuner/aidl/android/media/tv/tuner/TunerFilterTemiEvent.aidl
@@ -0,0 +1,40 @@
+/**
+ * Copyright 2021, 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.
+ */
+
+package android.media.tv.tuner;
+
+/**
+ * Filter Event for Timed External Media Information (TEMI) data.
+ *
+ * {@hide}
+ */
+parcelable TunerFilterTemiEvent {
+ /**
+ * Presentation Time Stamp for audio or video frame. It based on 90KHz has
+ * the same format as PTS (Presentation Time Stamp) in ISO/IEC 13818-1.
+ */
+ long pts;
+
+ /**
+ * TEMI Descriptor Tag
+ */
+ byte descrTag;
+
+ /**
+ * TEMI Descriptor
+ */
+ byte[] descrData;
+}
diff --git a/services/tuner/aidl/android/media/tv/tuner/TunerFilterTsRecordEvent.aidl b/services/tuner/aidl/android/media/tv/tuner/TunerFilterTsRecordEvent.aidl
new file mode 100644
index 0000000..c52a749
--- /dev/null
+++ b/services/tuner/aidl/android/media/tv/tuner/TunerFilterTsRecordEvent.aidl
@@ -0,0 +1,56 @@
+/**
+ * Copyright 2021, 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.
+ */
+
+package android.media.tv.tuner;
+
+import android.media.tv.tuner.TunerFilterScIndexMask;
+
+/**
+ * Filter Event for TS Record Filter.
+ *
+ * {@hide}
+ */
+parcelable TunerFilterTsRecordEvent {
+ char pid;
+
+ int tsIndexMask;
+
+ /**
+ * Indexes of record output
+ */
+ TunerFilterScIndexMask scIndexMask;
+
+ /**
+ * Byte number from beginning of the filter's output
+ */
+ long byteNumber;
+
+ /**
+ * If the current event contains extended information or not
+ */
+ boolean isExtended;
+
+ /**
+ * The Presentation Time Stamp(PTS) for the audio or video frame. It is based on 90KHz
+ * and has the same format as the PTS in ISO/IEC 13818-1.
+ */
+ long pts;
+
+ /**
+ * Specifies the address of the first macroblock in the slice defined in ITU-T Rec. H.264.
+ */
+ int firstMbInSlice;
+}