Merge "Enable support for audio HAL V7 in the framework" into sc-dev
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/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/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/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 42933e6..712f8fc 100644
--- a/media/libmediatranscoding/transcoder/benchmark/MediaTranscoderBenchmark.cpp
+++ b/media/libmediatranscoding/transcoder/benchmark/MediaTranscoderBenchmark.cpp
@@ -316,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.
@@ -339,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/services/audiopolicy/service/AudioPolicyInterfaceImpl.cpp b/services/audiopolicy/service/AudioPolicyInterfaceImpl.cpp
index 0ab63cf..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) {
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/TunerFilter.cpp b/services/tuner/TunerFilter.cpp
index edfc291..456a2c1 100644
--- a/services/tuner/TunerFilter.cpp
+++ b/services/tuner/TunerFilter.cpp
@@ -25,6 +25,8 @@
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(
@@ -209,6 +211,99 @@
/////////////// 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) {
@@ -225,6 +320,27 @@
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());
}
@@ -235,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) {
- 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 2f10435..422a12a 100644
--- a/services/tuner/TunerFilter.h
+++ b/services/tuner/TunerFilter.h
@@ -20,26 +20,48 @@
#include <aidl/android/media/tv/tuner/BnTunerFilter.h>
#include <aidl/android/media/tv/tuner/ITunerFilterCallback.h>
#include <aidlcommonsupport/NativeHandle.h>
-#include <android/hardware/tv/tuner/1.1/IFilter.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 {
@@ -65,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/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/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;
+}