Merge "Merge Android10 QPR1 into AOSP master"

This commit is contained in:
Treehugger Robot 2019-12-03 23:14:56 +00:00 committed by Gerrit Code Review
commit 249b9509db
9 changed files with 508 additions and 254 deletions

View file

@ -153,7 +153,7 @@ std::unique_ptr<VehiclePropValue> createOfferingMessage(const VmsOffers& offers)
std::unique_ptr<VehiclePropValue> createAvailabilityRequest();
// Creates a VehiclePropValue containing a message of type
// VmsMessageType.AVAILABILITY_REQUEST.
// VmsMessageType.SUBSCRIPTIONS_REQUEST.
std::unique_ptr<VehiclePropValue> createSubscriptionsRequest();
// Creates a VehiclePropValue containing a message of type VmsMessageType.DATA.
@ -202,21 +202,21 @@ int32_t parsePublisherIdResponse(const VehiclePropValue& publisher_id_response);
// Returns true if the new sequence number is greater than the last seen
// sequence number.
bool isSequenceNumberNewer(const VehiclePropValue& subscription_change,
bool isSequenceNumberNewer(const VehiclePropValue& subscriptions_state,
const int last_seen_sequence_number);
// Returns sequence number of the message.
int32_t getSequenceNumberForSubscriptionsState(const VehiclePropValue& subscription_change);
int32_t getSequenceNumberForSubscriptionsState(const VehiclePropValue& subscriptions_state);
// Takes a subscription change message and returns the layers that have active
// Takes a subscriptions state message and returns the layers that have active
// subscriptions of the layers that are offered by your HAL client/publisher.
//
// A publisher can use this function when receiving a subscription change message
// to determine which layers to publish data on.
// A publisher can use this function when receiving a subscriptions response or subscriptions
// change message to determine which layers to publish data on.
// The caller of this function can optionally decide to not consume these layers
// if the subscription change has the sequence number less than the last seen
// sequence number.
std::vector<VmsLayer> getSubscribedLayers(const VehiclePropValue& subscription_change,
std::vector<VmsLayer> getSubscribedLayers(const VehiclePropValue& subscriptions_state,
const VmsOffers& offers);
// Takes an availability change message and returns true if the parsed message implies that

View file

@ -194,32 +194,35 @@ int32_t parsePublisherIdResponse(const VehiclePropValue& publisher_id_response)
return -1;
}
bool isSequenceNumberNewer(const VehiclePropValue& subscription_change,
bool isSequenceNumberNewer(const VehiclePropValue& subscriptions_state,
const int last_seen_sequence_number) {
return (isValidVmsMessage(subscription_change) &&
parseMessageType(subscription_change) == VmsMessageType::SUBSCRIPTIONS_CHANGE &&
subscription_change.value.int32Values.size() > kSubscriptionStateSequenceNumberIndex &&
subscription_change.value.int32Values[kSubscriptionStateSequenceNumberIndex] >
return (isValidVmsMessage(subscriptions_state) &&
(parseMessageType(subscriptions_state) == VmsMessageType::SUBSCRIPTIONS_CHANGE ||
parseMessageType(subscriptions_state) == VmsMessageType::SUBSCRIPTIONS_RESPONSE) &&
subscriptions_state.value.int32Values.size() > kSubscriptionStateSequenceNumberIndex &&
subscriptions_state.value.int32Values[kSubscriptionStateSequenceNumberIndex] >
last_seen_sequence_number);
}
int32_t getSequenceNumberForSubscriptionsState(const VehiclePropValue& subscription_change) {
if (isValidVmsMessage(subscription_change) &&
parseMessageType(subscription_change) == VmsMessageType::SUBSCRIPTIONS_CHANGE &&
subscription_change.value.int32Values.size() > kSubscriptionStateSequenceNumberIndex) {
return subscription_change.value.int32Values[kSubscriptionStateSequenceNumberIndex];
int32_t getSequenceNumberForSubscriptionsState(const VehiclePropValue& subscriptions_state) {
if (isValidVmsMessage(subscriptions_state) &&
(parseMessageType(subscriptions_state) == VmsMessageType::SUBSCRIPTIONS_CHANGE ||
parseMessageType(subscriptions_state) == VmsMessageType::SUBSCRIPTIONS_RESPONSE) &&
subscriptions_state.value.int32Values.size() > kSubscriptionStateSequenceNumberIndex) {
return subscriptions_state.value.int32Values[kSubscriptionStateSequenceNumberIndex];
}
return -1;
}
std::vector<VmsLayer> getSubscribedLayers(const VehiclePropValue& subscription_change,
std::vector<VmsLayer> getSubscribedLayers(const VehiclePropValue& subscriptions_state,
const VmsOffers& offers) {
if (isValidVmsMessage(subscription_change) &&
parseMessageType(subscription_change) == VmsMessageType::SUBSCRIPTIONS_CHANGE &&
subscription_change.value.int32Values.size() > kSubscriptionStateSequenceNumberIndex) {
const int32_t num_of_layers = subscription_change.value.int32Values[toInt(
if (isValidVmsMessage(subscriptions_state) &&
(parseMessageType(subscriptions_state) == VmsMessageType::SUBSCRIPTIONS_CHANGE ||
parseMessageType(subscriptions_state) == VmsMessageType::SUBSCRIPTIONS_RESPONSE) &&
subscriptions_state.value.int32Values.size() > kSubscriptionStateSequenceNumberIndex) {
const int32_t num_of_layers = subscriptions_state.value.int32Values[toInt(
VmsSubscriptionsStateIntegerValuesIndex::NUMBER_OF_LAYERS)];
const int32_t num_of_associated_layers = subscription_change.value.int32Values[toInt(
const int32_t num_of_associated_layers = subscriptions_state.value.int32Values[toInt(
VmsSubscriptionsStateIntegerValuesIndex ::NUMBER_OF_ASSOCIATED_LAYERS)];
std::unordered_set<VmsLayer, VmsLayer::VmsLayerHashFunction> offered_layers;
@ -231,9 +234,9 @@ std::vector<VmsLayer> getSubscribedLayers(const VehiclePropValue& subscription_c
int current_index = toInt(VmsSubscriptionsStateIntegerValuesIndex::SUBSCRIPTIONS_START);
// Add all subscribed layers which are offered by the current publisher.
for (int i = 0; i < num_of_layers; i++) {
VmsLayer layer = VmsLayer(subscription_change.value.int32Values[current_index],
subscription_change.value.int32Values[current_index + 1],
subscription_change.value.int32Values[current_index + 2]);
VmsLayer layer = VmsLayer(subscriptions_state.value.int32Values[current_index],
subscriptions_state.value.int32Values[current_index + 1],
subscriptions_state.value.int32Values[current_index + 2]);
if (offered_layers.find(layer) != offered_layers.end()) {
subscribed_layers.push_back(layer);
}
@ -243,15 +246,15 @@ std::vector<VmsLayer> getSubscribedLayers(const VehiclePropValue& subscription_c
// For this, we need to check if the associated layer has a publisher ID which is
// same as that of the current publisher.
for (int i = 0; i < num_of_associated_layers; i++) {
VmsLayer layer = VmsLayer(subscription_change.value.int32Values[current_index],
subscription_change.value.int32Values[current_index + 1],
subscription_change.value.int32Values[current_index + 2]);
VmsLayer layer = VmsLayer(subscriptions_state.value.int32Values[current_index],
subscriptions_state.value.int32Values[current_index + 1],
subscriptions_state.value.int32Values[current_index + 2]);
current_index += kLayerSize;
if (offered_layers.find(layer) != offered_layers.end()) {
int32_t num_of_publisher_ids = subscription_change.value.int32Values[current_index];
int32_t num_of_publisher_ids = subscriptions_state.value.int32Values[current_index];
current_index++;
for (int j = 0; j < num_of_publisher_ids; j++) {
if (subscription_change.value.int32Values[current_index] ==
if (subscriptions_state.value.int32Values[current_index] ==
offers.publisher_id) {
subscribed_layers.push_back(layer);
}

View file

@ -214,57 +214,82 @@ TEST(VmsUtilsTest, invalidPublisherIdResponse) {
EXPECT_EQ(parsePublisherIdResponse(*message), -1);
}
TEST(VmsUtilsTest, validSequenceNumberForSubscriptionsState) {
TEST(VmsUtilsTest, validSequenceNumberForSubscriptionsChange) {
auto message = createBaseVmsMessage(2);
message->value.int32Values =
hidl_vec<int32_t>{toInt(VmsMessageType::SUBSCRIPTIONS_CHANGE), 1234};
EXPECT_EQ(getSequenceNumberForSubscriptionsState(*message), 1234);
}
TEST(VmsUtilsTest, validSequenceNumberForSubscriptionsResponse) {
auto message = createBaseVmsMessage(2);
message->value.int32Values =
hidl_vec<int32_t>{toInt(VmsMessageType::SUBSCRIPTIONS_RESPONSE), 1234};
EXPECT_EQ(getSequenceNumberForSubscriptionsState(*message), 1234);
}
TEST(VmsUtilsTest, invalidSubscriptionsState) {
auto message = createBaseVmsMessage(1);
EXPECT_EQ(getSequenceNumberForSubscriptionsState(*message), -1);
}
TEST(VmsUtilsTest, newSequenceNumberForExistingSmallerNumber) {
TEST(VmsUtilsTest, newSequenceNumberForExistingSmallerNumberForChange) {
auto message = createBaseVmsMessage(2);
message->value.int32Values =
hidl_vec<int32_t>{toInt(VmsMessageType::SUBSCRIPTIONS_CHANGE), 1234};
EXPECT_TRUE(isSequenceNumberNewer(*message, 1233));
}
TEST(VmsUtilsTest, newSequenceNumberForExistingGreaterNumber) {
TEST(VmsUtilsTest, newSequenceNumberForExistingSmallerNumberForResponse) {
auto message = createBaseVmsMessage(2);
message->value.int32Values =
hidl_vec<int32_t>{toInt(VmsMessageType::SUBSCRIPTIONS_RESPONSE), 1234};
EXPECT_TRUE(isSequenceNumberNewer(*message, 1233));
}
TEST(VmsUtilsTest, newSequenceNumberForExistingGreaterNumberForChange) {
auto message = createBaseVmsMessage(2);
message->value.int32Values =
hidl_vec<int32_t>{toInt(VmsMessageType::SUBSCRIPTIONS_CHANGE), 1234};
EXPECT_FALSE(isSequenceNumberNewer(*message, 1235));
}
TEST(VmsUtilsTest, newSequenceNumberForSameNumber) {
TEST(VmsUtilsTest, newSequenceNumberForExistingGreaterNumberForResponse) {
auto message = createBaseVmsMessage(2);
message->value.int32Values =
hidl_vec<int32_t>{toInt(VmsMessageType::SUBSCRIPTIONS_RESPONSE), 1234};
EXPECT_FALSE(isSequenceNumberNewer(*message, 1235));
}
TEST(VmsUtilsTest, newSequenceNumberForSameNumberForChange) {
auto message = createBaseVmsMessage(2);
message->value.int32Values =
hidl_vec<int32_t>{toInt(VmsMessageType::SUBSCRIPTIONS_CHANGE), 1234};
EXPECT_FALSE(isSequenceNumberNewer(*message, 1234));
}
TEST(VmsUtilsTest, subscribedLayers) {
TEST(VmsUtilsTest, newSequenceNumberForSameNumberForResponse) {
auto message = createBaseVmsMessage(2);
message->value.int32Values =
hidl_vec<int32_t>{toInt(VmsMessageType::SUBSCRIPTIONS_RESPONSE), 1234};
EXPECT_FALSE(isSequenceNumberNewer(*message, 1234));
}
void testSubscribedLayers(VmsMessageType type) {
VmsOffers offers = {123,
{VmsLayerOffering(VmsLayer(1, 0, 1), {VmsLayer(4, 1, 1)}),
VmsLayerOffering(VmsLayer(2, 0, 1))}};
auto message = createBaseVmsMessage(2);
message->value.int32Values = hidl_vec<int32_t>{toInt(VmsMessageType::SUBSCRIPTIONS_CHANGE),
message->value.int32Values = hidl_vec<int32_t>{toInt(type),
1234, // sequence number
2, // number of layers
1, // number of associated layers
1, // layer 1
0,
1,
0, 1,
4, // layer 2
1,
1,
1, 1,
2, // associated layer
0,
1,
0, 1,
2, // number of publisher IDs
111, // publisher IDs
123};
@ -275,10 +300,18 @@ TEST(VmsUtilsTest, subscribedLayers) {
EXPECT_EQ(result.at(1), VmsLayer(2, 0, 1));
}
TEST(VmsUtilsTest, subscribedLayersWithDifferentSubtype) {
TEST(VmsUtilsTest, subscribedLayersForChange) {
testSubscribedLayers(VmsMessageType::SUBSCRIPTIONS_CHANGE);
}
TEST(VmsUtilsTest, subscribedLayersForResponse) {
testSubscribedLayers(VmsMessageType::SUBSCRIPTIONS_RESPONSE);
}
void testSubscribedLayersWithDifferentSubtype(VmsMessageType type) {
VmsOffers offers = {123, {VmsLayerOffering(VmsLayer(1, 0, 1))}};
auto message = createBaseVmsMessage(2);
message->value.int32Values = hidl_vec<int32_t>{toInt(VmsMessageType::SUBSCRIPTIONS_CHANGE),
message->value.int32Values = hidl_vec<int32_t>{toInt(type),
1234, // sequence number
1, // number of layers
0, // number of associated layers
@ -289,36 +322,58 @@ TEST(VmsUtilsTest, subscribedLayersWithDifferentSubtype) {
EXPECT_TRUE(getSubscribedLayers(*message, offers).empty());
}
TEST(VmsUtilsTest, subscribedLayersWithDifferentVersion) {
TEST(VmsUtilsTest, subscribedLayersWithDifferentSubtypeForChange) {
testSubscribedLayersWithDifferentSubtype(VmsMessageType::SUBSCRIPTIONS_CHANGE);
}
TEST(VmsUtilsTest, subscribedLayersWithDifferentSubtypeForResponse) {
testSubscribedLayersWithDifferentSubtype(VmsMessageType::SUBSCRIPTIONS_RESPONSE);
}
void subscribedLayersWithDifferentVersion(VmsMessageType type) {
VmsOffers offers = {123, {VmsLayerOffering(VmsLayer(1, 0, 1))}};
auto message = createBaseVmsMessage(2);
message->value.int32Values = hidl_vec<int32_t>{toInt(VmsMessageType::SUBSCRIPTIONS_CHANGE),
1234, // sequence number
1, // number of layers
0, // number of associated layers
1, // layer 1
0,
2}; // different version
message->value.int32Values = hidl_vec<int32_t>{toInt(type),
1234, // sequence number
1, // number of layers
0, // number of associated layers
1, // layer 1
0, 2}; // different version
EXPECT_TRUE(isValidVmsMessage(*message));
EXPECT_TRUE(getSubscribedLayers(*message, offers).empty());
}
TEST(VmsUtilsTest, subscribedLayersWithDifferentPublisherId) {
TEST(VmsUtilsTest, subscribedLayersWithDifferentVersionForChange) {
subscribedLayersWithDifferentVersion(VmsMessageType::SUBSCRIPTIONS_CHANGE);
}
TEST(VmsUtilsTest, subscribedLayersWithDifferentVersionForResponse) {
subscribedLayersWithDifferentVersion(VmsMessageType::SUBSCRIPTIONS_RESPONSE);
}
void subscribedLayersWithDifferentPublisherId(VmsMessageType type) {
VmsOffers offers = {123, {VmsLayerOffering(VmsLayer(1, 0, 1))}};
auto message = createBaseVmsMessage(2);
message->value.int32Values = hidl_vec<int32_t>{toInt(VmsMessageType::SUBSCRIPTIONS_CHANGE),
message->value.int32Values = hidl_vec<int32_t>{toInt(type),
1234, // sequence number
0, // number of layers
1, // number of associated layers
1, // associated layer 1
0,
1,
0, 1,
1, // number of publisher IDs
234}; // publisher ID 1
EXPECT_TRUE(isValidVmsMessage(*message));
EXPECT_TRUE(getSubscribedLayers(*message, offers).empty());
}
TEST(VmsUtilsTest, subscribedLayersWithDifferentPublisherIdForChange) {
subscribedLayersWithDifferentPublisherId(VmsMessageType::SUBSCRIPTIONS_CHANGE);
}
TEST(VmsUtilsTest, subscribedLayersWithDifferentPublisherIdForResponse) {
subscribedLayersWithDifferentPublisherId(VmsMessageType::SUBSCRIPTIONS_RESPONSE);
}
TEST(VmsUtilsTest, serviceNewlyStarted) {
auto message = createBaseVmsMessage(2);
message->value.int32Values = hidl_vec<int32_t>{toInt(VmsMessageType::AVAILABILITY_CHANGE), 0};

View file

@ -101,11 +101,20 @@ namespace implementation {
std::unique_ptr<android::CryptoPlugin::SubSample[]> legacySubSamples =
std::make_unique<android::CryptoPlugin::SubSample[]>(subSamples.size());
size_t destSize = 0;
for (size_t i = 0; i < subSamples.size(); i++) {
legacySubSamples[i].mNumBytesOfClearData
= subSamples[i].numBytesOfClearData;
legacySubSamples[i].mNumBytesOfEncryptedData
= subSamples[i].numBytesOfEncryptedData;
uint32_t numBytesOfClearData = subSamples[i].numBytesOfClearData;
legacySubSamples[i].mNumBytesOfClearData = numBytesOfClearData;
uint32_t numBytesOfEncryptedData = subSamples[i].numBytesOfEncryptedData;
legacySubSamples[i].mNumBytesOfEncryptedData = numBytesOfEncryptedData;
if (__builtin_add_overflow(destSize, numBytesOfClearData, &destSize)) {
_hidl_cb(Status::BAD_VALUE, 0, "subsample clear size overflow");
return Void();
}
if (__builtin_add_overflow(destSize, numBytesOfEncryptedData, &destSize)) {
_hidl_cb(Status::BAD_VALUE, 0, "subsample encrypted size overflow");
return Void();
}
}
AString detailMessage;
@ -137,11 +146,24 @@ namespace implementation {
_hidl_cb(Status::ERROR_DRM_CANNOT_HANDLE, 0, "invalid buffer size");
return Void();
}
if (destSize > destBuffer.size) {
_hidl_cb(Status::BAD_VALUE, 0, "subsample sum too large");
return Void();
}
destPtr = static_cast<void *>(base + destination.nonsecureMemory.offset);
} else if (destination.type == BufferType::NATIVE_HANDLE) {
if (!secure) {
_hidl_cb(Status::BAD_VALUE, 0, "native handle destination must be secure");
return Void();
}
native_handle_t *handle = const_cast<native_handle_t *>(
destination.secureMemory.getNativeHandle());
destPtr = static_cast<void *>(handle);
} else {
_hidl_cb(Status::BAD_VALUE, 0, "invalid destination type");
return Void();
}
ssize_t result = mLegacyPlugin->decrypt(secure, keyId.data(), iv.data(),
legacyMode, legacyPattern, srcPtr, legacySubSamples.get(),

View file

@ -18,17 +18,17 @@ This folder includes test fixtures associated with testing audio encoder and dec
usage:
VtsHalMediaOmxV1\_0TargetAudioDecTest -I default -C <comp name> -R audio_decoder.<comp class> -P /sdcard/media/
VtsHalMediaOmxV1\_0TargetAudioDecTest -I default -C <comp name> -R audio_decoder.<comp class> -P /data/local/tmp/media/
VtsHalMediaOmxV1\_0TargetAudioEncTest -I default -C <comp name> -R audio_encoder.<comp class> -P /sdcard/media/
VtsHalMediaOmxV1\_0TargetAudioEncTest -I default -C <comp name> -R audio_encoder.<comp class> -P /data/local/tmp/media/
#### video :
This folder includes test fixtures associated with testing video encoder and decoder components such as simple encoding of a raw clip or decoding of an elementary stream, end of stream test, timestamp deviations test, flush test and so on. These tests are aimed towards testing the plugin that connects the component to the omx core.
usage:
VtsHalMediaOmxV1\_0TargetVideoDecTest -I default -C <comp name> -R video_decoder.<comp class> -P /sdcard/media/
VtsHalMediaOmxV1\_0TargetVideoDecTest -I default -C <comp name> -R video_decoder.<comp class> -P /data/local/tmp/media/
VtsHalMediaOmxV1\_0TargetVideoEncTest -I default -C <comp name> -R video_encoder.<comp class> -P /sdcard/media/
VtsHalMediaOmxV1\_0TargetVideoEncTest -I default -C <comp name> -R video_encoder.<comp class> -P /data/local/tmp/media/
While tesing audio/video encoder, decoder components, test fixtures require input files. These input are files are present in the folder 'res'. Before running the tests all the files in 'res' have to be placed in '/media/sdcard/' or a path of your choice and this path needs to be provided as an argument to the test application
While tesing audio/video encoder, decoder components, test fixtures require input files. These input are files are present in the folder 'res'. Before running the tests all the files in 'res' have to be placed in '/data/local/tmp/media' or a path of your choice and this path needs to be provided as an argument to the test application

View file

@ -29,6 +29,21 @@ cc_library_static {
"android.hidl.memory@1.0",
"android.hardware.media.omx@1.0",
"android.hardware.graphics.allocator@2.0",
"android.hardware.graphics.allocator@3.0",
"android.hardware.graphics.common@1.0",
"android.hardware.graphics.common@1.1",
"android.hardware.graphics.common@1.2",
"android.hardware.graphics.mapper@2.0",
"android.hardware.graphics.mapper@3.0",
],
export_static_lib_headers: [
"android.hardware.graphics.allocator@2.0",
"android.hardware.graphics.allocator@3.0",
"android.hardware.graphics.common@1.0",
"android.hardware.graphics.common@1.1",
"android.hardware.graphics.common@1.2",
"android.hardware.graphics.mapper@2.0",
"android.hardware.graphics.mapper@3.0",
],
}
@ -40,7 +55,12 @@ cc_defaults {
static_libs: [
"VtsHalMediaOmxV1_0CommonUtil",
"android.hardware.graphics.allocator@2.0",
"android.hardware.graphics.allocator@3.0",
"android.hardware.graphics.common@1.0",
"android.hardware.graphics.common@1.1",
"android.hardware.graphics.common@1.2",
"android.hardware.graphics.mapper@2.0",
"android.hardware.graphics.mapper@3.0",
"android.hardware.graphics.bufferqueue@1.0",
"android.hardware.graphics.common@1.0",
"android.hardware.media.omx@1.0",

View file

@ -22,8 +22,11 @@
#include <android-base/logging.h>
#include <android/hardware/graphics/allocator/2.0/IAllocator.h>
#include <android/hardware/graphics/allocator/3.0/IAllocator.h>
#include <android/hardware/graphics/mapper/2.0/IMapper.h>
#include <android/hardware/graphics/mapper/2.0/types.h>
#include <android/hardware/graphics/mapper/3.0/IMapper.h>
#include <android/hardware/graphics/mapper/3.0/types.h>
#include <android/hardware/media/omx/1.0/IOmx.h>
#include <android/hardware/media/omx/1.0/IOmxNode.h>
#include <android/hardware/media/omx/1.0/IOmxObserver.h>
@ -31,7 +34,9 @@
#include <android/hidl/allocator/1.0/IAllocator.h>
#include <android/hidl/memory/1.0/IMapper.h>
#include <android/hidl/memory/1.0/IMemory.h>
#include <cutils/atomic.h>
#include <atomic>
#include <variant>
using ::android::hardware::graphics::common::V1_0::BufferUsage;
using ::android::hardware::graphics::common::V1_0::PixelFormat;
@ -195,67 +200,104 @@ void allocateGraphicBuffers(sp<IOmxNode> omxNode, OMX_U32 portIndex,
BufferInfo* buffer, uint32_t nFrameWidth,
uint32_t nFrameHeight, int32_t* nStride,
int format) {
android::hardware::media::omx::V1_0::Status status;
sp<android::hardware::graphics::allocator::V2_0::IAllocator> allocator =
android::hardware::graphics::allocator::V2_0::IAllocator::getService();
ASSERT_NE(nullptr, allocator.get());
struct AllocatorV2 : public GrallocV2 {
sp<IAllocator> mAllocator;
sp<IMapper> mMapper;
AllocatorV2(sp<IAllocator>&& allocator, sp<IMapper>&& mapper)
: mAllocator{std::move(allocator)}, mMapper{std::move(mapper)} {}
AllocatorV2() = default;
};
struct AllocatorV3 : public GrallocV3 {
sp<IAllocator> mAllocator;
sp<IMapper> mMapper;
AllocatorV3(sp<IAllocator>&& allocator, sp<IMapper>&& mapper)
: mAllocator{std::move(allocator)}, mMapper{std::move(mapper)} {}
AllocatorV3() = default;
};
std::variant<AllocatorV2, AllocatorV3> grallocVar;
sp<android::hardware::graphics::mapper::V2_0::IMapper> mapper =
android::hardware::graphics::mapper::V2_0::IMapper::getService();
ASSERT_NE(mapper.get(), nullptr);
sp<android::hardware::graphics::mapper::V2_0::IMapper> mapper2{};
sp<android::hardware::graphics::mapper::V3_0::IMapper> mapper3{};
sp<android::hardware::graphics::allocator::V2_0::IAllocator> allocator2{};
sp<android::hardware::graphics::allocator::V3_0::IAllocator> allocator3 =
android::hardware::graphics::allocator::V3_0::IAllocator::getService();
if (allocator3) {
mapper3 =
android::hardware::graphics::mapper::V3_0::IMapper::getService();
ASSERT_NE(nullptr, mapper3.get());
grallocVar.emplace<AllocatorV3>(std::move(allocator3), std::move(mapper3));
} else {
allocator2 =
android::hardware::graphics::allocator::V2_0::IAllocator::getService();
ASSERT_NE(nullptr, allocator2.get());
mapper2 =
android::hardware::graphics::mapper::V2_0::IMapper::getService();
ASSERT_NE(nullptr, allocator2.get());
grallocVar.emplace<AllocatorV2>(std::move(allocator2), std::move(mapper2));
}
android::hardware::graphics::mapper::V2_0::IMapper::BufferDescriptorInfo
descriptorInfo;
uint32_t usage;
descriptorInfo.width = nFrameWidth;
descriptorInfo.height = nFrameHeight;
descriptorInfo.layerCount = 1;
descriptorInfo.format = static_cast<PixelFormat>(format);
descriptorInfo.usage = static_cast<uint64_t>(BufferUsage::CPU_READ_OFTEN);
omxNode->getGraphicBufferUsage(
android::hardware::media::omx::V1_0::Status status{};
uint64_t usage{};
ASSERT_TRUE(omxNode->getGraphicBufferUsage(
portIndex,
[&status, &usage](android::hardware::media::omx::V1_0::Status _s,
uint32_t _n1) {
status = _s;
usage = _n1;
});
if (status == android::hardware::media::omx::V1_0::Status::OK) {
descriptorInfo.usage |= usage;
}
}).isOk());
ASSERT_EQ(status, android::hardware::media::omx::V1_0::Status::OK);
::android::hardware::hidl_vec<uint32_t> descriptor;
android::hardware::graphics::mapper::V2_0::Error error;
mapper->createDescriptor(
descriptorInfo, [&error, &descriptor](
android::hardware::graphics::mapper::V2_0::Error _s,
::android::hardware::hidl_vec<uint32_t> _n1) {
error = _s;
descriptor = _n1;
});
ASSERT_EQ(error, android::hardware::graphics::mapper::V2_0::Error::NONE);
static std::atomic_int32_t bufferIdCounter{0};
static volatile int32_t nextId = 0;
uint64_t id = static_cast<uint64_t>(getpid()) << 32;
allocator->allocate(
descriptor, 1,
[&](android::hardware::graphics::mapper::V2_0::Error _s, uint32_t _n1,
const ::android::hardware::hidl_vec<
::android::hardware::hidl_handle>& _n2) {
ASSERT_EQ(android::hardware::graphics::mapper::V2_0::Error::NONE,
_s);
*nStride = _n1;
buffer->omxBuffer.nativeHandle = _n2[0];
buffer->omxBuffer.attr.anwBuffer.width = nFrameWidth;
buffer->omxBuffer.attr.anwBuffer.height = nFrameHeight;
buffer->omxBuffer.attr.anwBuffer.stride = _n1;
buffer->omxBuffer.attr.anwBuffer.format = descriptorInfo.format;
buffer->omxBuffer.attr.anwBuffer.usage = descriptorInfo.usage;
buffer->omxBuffer.attr.anwBuffer.layerCount =
descriptorInfo.layerCount;
buffer->omxBuffer.attr.anwBuffer.id =
id | static_cast<uint32_t>(android_atomic_inc(&nextId));
});
std::visit([buffer, nFrameWidth, nFrameHeight, format, usage, nStride](auto&& gralloc) {
using Gralloc = std::remove_reference_t<decltype(gralloc)>;
using Descriptor = typename Gralloc::Descriptor;
using DescriptorInfo = typename Gralloc::DescriptorInfo;
using Error = typename Gralloc::Error;
using Format = typename Gralloc::Format;
using Usage = typename Gralloc::Usage;
Error error{};
Descriptor descriptor{};
DescriptorInfo descriptorInfo{};
descriptorInfo.width = nFrameWidth;
descriptorInfo.height = nFrameHeight;
descriptorInfo.layerCount = 1;
descriptorInfo.format = static_cast<Format>(format);
descriptorInfo.usage = usage | Usage(BufferUsage::CPU_READ_OFTEN);
gralloc.mMapper->createDescriptor(descriptorInfo,
[&error, &descriptor](
Error _s,
const Descriptor& _n1) {
error = _s;
descriptor = _n1;
});
ASSERT_EQ(error, Error::NONE);
gralloc.mAllocator->allocate(
descriptor, 1,
[&](Error _s, uint32_t _n1,
const ::android::hardware::hidl_vec<
::android::hardware::hidl_handle>& _n2) {
ASSERT_EQ(Error::NONE, _s);
*nStride = _n1;
buffer->omxBuffer.nativeHandle = _n2[0];
buffer->omxBuffer.attr.anwBuffer.width = nFrameWidth;
buffer->omxBuffer.attr.anwBuffer.height = nFrameHeight;
buffer->omxBuffer.attr.anwBuffer.stride = _n1;
buffer->omxBuffer.attr.anwBuffer.format =
static_cast<PixelFormat>(descriptorInfo.format);
buffer->omxBuffer.attr.anwBuffer.usage =
static_cast<uint32_t>(descriptorInfo.usage);
buffer->omxBuffer.attr.anwBuffer.layerCount =
descriptorInfo.layerCount;
buffer->omxBuffer.attr.anwBuffer.id =
(static_cast<uint64_t>(getpid()) << 32) |
bufferIdCounter.fetch_add(1, std::memory_order_relaxed);
});
}, grallocVar);
}
// allocate buffers needed on a component port

View file

@ -22,6 +22,16 @@
#endif
#include <getopt.h>
#include <android/hardware/graphics/allocator/2.0/IAllocator.h>
#include <android/hardware/graphics/allocator/3.0/IAllocator.h>
#include <android/hardware/graphics/common/1.0/types.h>
#include <android/hardware/graphics/common/1.1/types.h>
#include <android/hardware/graphics/common/1.2/types.h>
#include <android/hardware/graphics/mapper/2.0/IMapper.h>
#include <android/hardware/graphics/mapper/2.0/types.h>
#include <android/hardware/graphics/mapper/3.0/IMapper.h>
#include <android/hardware/graphics/mapper/3.0/types.h>
#include <media/stagefright/foundation/ALooper.h>
#include <utils/Condition.h>
#include <utils/List.h>
@ -288,6 +298,36 @@ Return<android::hardware::media::omx::V1_0::Status> setPortConfig(
/*
* common functions declarations
*/
struct GrallocV2 {
using Format = android::hardware::graphics::common::V1_0::PixelFormat;
using Usage = android::hardware::hidl_bitfield<
android::hardware::graphics::common::V1_0::BufferUsage>;
using IAllocator = android::hardware::graphics::allocator::V2_0::IAllocator;
using IMapper = android::hardware::graphics::mapper::V2_0::IMapper;
using Error = android::hardware::graphics::mapper::V2_0::Error;
using Descriptor = android::hardware::graphics::mapper::V2_0::BufferDescriptor;
using YCbCrLayout = android::hardware::graphics::mapper::V2_0::YCbCrLayout;
using DescriptorInfo = IMapper::BufferDescriptorInfo;
using Rect = IMapper::Rect;
};
struct GrallocV3 {
using Format = android::hardware::graphics::common::V1_2::PixelFormat;
using Usage = android::hardware::hidl_bitfield<
android::hardware::graphics::common::V1_2::BufferUsage>;
using IAllocator = android::hardware::graphics::allocator::V3_0::IAllocator;
using IMapper = android::hardware::graphics::mapper::V3_0::IMapper;
using Error = android::hardware::graphics::mapper::V3_0::Error;
using Descriptor = android::hardware::graphics::mapper::V3_0::BufferDescriptor;
using YCbCrLayout = android::hardware::graphics::mapper::V3_0::YCbCrLayout;
using DescriptorInfo = IMapper::BufferDescriptorInfo;
using Rect = IMapper::Rect;
};
Return<android::hardware::media::omx::V1_0::Status> setRole(
sp<IOmxNode> omxNode, const char* role);
@ -368,7 +408,7 @@ class ComponentTestEnvironment : public ::testing::VtsHalHidlTargetTestEnvBase {
public:
virtual void registerTestServices() override { registerTestService<IOmx>(); }
ComponentTestEnvironment() : res("/sdcard/media/") {}
ComponentTestEnvironment() : res("/data/local/tmp/media/") {}
void setComponent(const char* _component) { component = _component; }

View file

@ -63,6 +63,7 @@ using ::android::sp;
#include <media_video_hidl_test_common.h>
#include <system/window.h>
#include <fstream>
#include <variant>
static ComponentTestEnvironment* gEnv = nullptr;
@ -364,6 +365,61 @@ Return<void> DummyBufferSource::onInputBufferEmptied(
return Void();
};
// Variant of mappers
struct MapperV2 : public GrallocV2 {
sp<IMapper> mMapper;
MapperV2(sp<IMapper>&& mapper): mMapper{std::move(mapper)} {}
MapperV2() = default;
android::hardware::Return<void> lock(
void* buffer,
Usage usage,
const Rect& rect,
const android::hardware::hidl_handle& handle,
Error* error,
void** data) {
return mMapper->lock(buffer, usage, rect, handle,
[error, data](Error e, void* d) {
*error = e;
*data = d;
});
}
};
struct MapperV3 : public GrallocV3 {
sp<IMapper> mMapper;
MapperV3(sp<IMapper>&& mapper): mMapper{std::move(mapper)} {}
MapperV3() = default;
android::hardware::Return<void> lock(
void* buffer,
Usage usage,
const Rect& rect,
const android::hardware::hidl_handle& handle,
Error* error,
void** data) {
return mMapper->lock(buffer, usage, rect, handle,
[error, data](Error e, void* d, int32_t, int32_t) {
*error = e;
*data = d;
});
}
};
using MapperVar = std::variant<MapperV2, MapperV3>;
// Initializes the MapperVar by trying services of different versions.
bool initialize(MapperVar& mapperVar) {
sp<android::hardware::graphics::mapper::V3_0::IMapper> mapper3 =
android::hardware::graphics::mapper::V3_0::IMapper::getService();
if (mapper3) {
mapperVar.emplace<MapperV3>(std::move(mapper3));
return true;
}
sp<android::hardware::graphics::mapper::V2_0::IMapper> mapper2 =
android::hardware::graphics::mapper::V2_0::IMapper::getService();
if (mapper2) {
mapperVar.emplace<MapperV2>(std::move(mapper2));
return true;
}
return false;
}
// request VOP refresh
void requestIDR(sp<IOmxNode> omxNode, OMX_U32 portIndex) {
android::hardware::media::omx::V1_0::Status status;
@ -574,150 +630,166 @@ void waitOnInputConsumption(sp<IOmxNode> omxNode, sp<CodecObserver> observer,
int colorFormatConversion(BufferInfo* buffer, void* buff, PixelFormat format,
std::ifstream& eleStream) {
sp<android::hardware::graphics::mapper::V2_0::IMapper> mapper =
android::hardware::graphics::mapper::V2_0::IMapper::getService();
EXPECT_NE(mapper.get(), nullptr);
if (mapper.get() == nullptr) return 1;
android::hardware::hidl_handle fence;
android::hardware::graphics::mapper::V2_0::IMapper::Rect rect;
android::hardware::graphics::mapper::V2_0::YCbCrLayout ycbcrLayout;
android::hardware::graphics::mapper::V2_0::Error error;
rect.left = 0;
rect.top = 0;
rect.width = buffer->omxBuffer.attr.anwBuffer.width;
rect.height = buffer->omxBuffer.attr.anwBuffer.height;
if (format == PixelFormat::YV12 || format == PixelFormat::YCRCB_420_SP ||
format == PixelFormat::YCBCR_420_888) {
mapper->lockYCbCr(
buff, buffer->omxBuffer.attr.anwBuffer.usage, rect, fence,
[&](android::hardware::graphics::mapper::V2_0::Error _e,
android::hardware::graphics::mapper::V2_0::YCbCrLayout _n1) {
error = _e;
ycbcrLayout = _n1;
});
EXPECT_EQ(error,
android::hardware::graphics::mapper::V2_0::Error::NONE);
if (error != android::hardware::graphics::mapper::V2_0::Error::NONE)
return 1;
int size = ((rect.width * rect.height * 3) >> 1);
char* img = new char[size];
if (img == nullptr) return 1;
eleStream.read(img, size);
if (eleStream.gcount() != size) {
delete[] img;
return 1;
}
char* imgTmp = img;
char* ipBuffer = static_cast<char*>(ycbcrLayout.y);
for (size_t y = rect.height; y > 0; --y) {
memcpy(ipBuffer, imgTmp, rect.width);
ipBuffer += ycbcrLayout.yStride;
imgTmp += rect.width;
}
if (format == PixelFormat::YV12)
EXPECT_EQ(ycbcrLayout.chromaStep, 1U);
else if (format == PixelFormat::YCRCB_420_SP)
EXPECT_EQ(ycbcrLayout.chromaStep, 2U);
ipBuffer = static_cast<char*>(ycbcrLayout.cb);
for (size_t y = rect.height >> 1; y > 0; --y) {
for (int32_t x = 0; x < (rect.width >> 1); ++x) {
ipBuffer[ycbcrLayout.chromaStep * x] = *imgTmp++;
}
ipBuffer += ycbcrLayout.cStride;
}
ipBuffer = static_cast<char*>(ycbcrLayout.cr);
for (size_t y = rect.height >> 1; y > 0; --y) {
for (int32_t x = 0; x < (rect.width >> 1); ++x) {
ipBuffer[ycbcrLayout.chromaStep * x] = *imgTmp++;
}
ipBuffer += ycbcrLayout.cStride;
}
delete[] img;
mapper->unlock(buff,
[&](android::hardware::graphics::mapper::V2_0::Error _e,
android::hardware::hidl_handle _n1) {
error = _e;
fence = _n1;
});
EXPECT_EQ(error,
android::hardware::graphics::mapper::V2_0::Error::NONE);
if (error != android::hardware::graphics::mapper::V2_0::Error::NONE)
return 1;
} else {
void* data;
mapper->lock(buff, buffer->omxBuffer.attr.anwBuffer.usage, rect, fence,
[&](android::hardware::graphics::mapper::V2_0::Error _e,
void* _n1) {
error = _e;
data = _n1;
});
EXPECT_EQ(error,
android::hardware::graphics::mapper::V2_0::Error::NONE);
if (error != android::hardware::graphics::mapper::V2_0::Error::NONE)
return 1;
if (format == PixelFormat::BGRA_8888) {
char* ipBuffer = static_cast<char*>(data);
for (size_t y = rect.height; y > 0; --y) {
eleStream.read(ipBuffer, rect.width * 4);
if (eleStream.gcount() != rect.width * 4) return 1;
ipBuffer += buffer->omxBuffer.attr.anwBuffer.stride * 4;
}
} else {
EXPECT_TRUE(false) << "un expected pixel format";
return 1;
}
mapper->unlock(buff,
[&](android::hardware::graphics::mapper::V2_0::Error _e,
android::hardware::hidl_handle _n1) {
error = _e;
fence = _n1;
});
EXPECT_EQ(error,
android::hardware::graphics::mapper::V2_0::Error::NONE);
if (error != android::hardware::graphics::mapper::V2_0::Error::NONE)
return 1;
MapperVar mapperVar;
if (!initialize(mapperVar)) {
EXPECT_TRUE(false) << "failed to obtain mapper service";
return 1;
}
return 0;
return std::visit([buffer, buff, format, &eleStream](auto&& mapper) -> int {
using Gralloc = std::remove_reference_t<decltype(mapper)>;
using Error = typename Gralloc::Error;
using Rect = typename Gralloc::Rect;
using Usage = typename Gralloc::Usage;
using YCbCrLayout = typename Gralloc::YCbCrLayout;
android::hardware::hidl_handle fence;
Rect rect;
YCbCrLayout ycbcrLayout;
Error error;
rect.left = 0;
rect.top = 0;
rect.width = buffer->omxBuffer.attr.anwBuffer.width;
rect.height = buffer->omxBuffer.attr.anwBuffer.height;
if (format == PixelFormat::YV12 || format == PixelFormat::YCRCB_420_SP ||
format == PixelFormat::YCBCR_420_888) {
mapper.mMapper->lockYCbCr(
buff,
static_cast<Usage>(
buffer->omxBuffer.attr.anwBuffer.usage),
rect,
fence,
[&](Error _e,
const YCbCrLayout& _n1) {
error = _e;
ycbcrLayout = _n1;
});
EXPECT_EQ(error, Error::NONE);
if (error != Error::NONE)
return 1;
int size = ((rect.width * rect.height * 3) >> 1);
char* img = new char[size];
if (img == nullptr) return 1;
eleStream.read(img, size);
if (eleStream.gcount() != size) {
delete[] img;
return 1;
}
char* imgTmp = img;
char* ipBuffer = static_cast<char*>(ycbcrLayout.y);
for (size_t y = rect.height; y > 0; --y) {
memcpy(ipBuffer, imgTmp, rect.width);
ipBuffer += ycbcrLayout.yStride;
imgTmp += rect.width;
}
if (format == PixelFormat::YV12)
EXPECT_EQ(ycbcrLayout.chromaStep, 1U);
else if (format == PixelFormat::YCRCB_420_SP)
EXPECT_EQ(ycbcrLayout.chromaStep, 2U);
ipBuffer = static_cast<char*>(ycbcrLayout.cb);
for (size_t y = rect.height >> 1; y > 0; --y) {
for (int32_t x = 0; x < (rect.width >> 1); ++x) {
ipBuffer[ycbcrLayout.chromaStep * x] = *imgTmp++;
}
ipBuffer += ycbcrLayout.cStride;
}
ipBuffer = static_cast<char*>(ycbcrLayout.cr);
for (size_t y = rect.height >> 1; y > 0; --y) {
for (int32_t x = 0; x < (rect.width >> 1); ++x) {
ipBuffer[ycbcrLayout.chromaStep * x] = *imgTmp++;
}
ipBuffer += ycbcrLayout.cStride;
}
delete[] img;
mapper.mMapper->unlock(buff,
[&](Error _e,
const android::hardware::hidl_handle& _n1) {
error = _e;
fence = _n1;
});
EXPECT_EQ(error, Error::NONE);
if (error != Error::NONE)
return 1;
} else {
void* data;
mapper.lock(
buff,
buffer->omxBuffer.attr.anwBuffer.usage,
rect,
fence,
&error,
&data);
EXPECT_EQ(error, Error::NONE);
if (error != Error::NONE)
return 1;
if (format == PixelFormat::BGRA_8888) {
char* ipBuffer = static_cast<char*>(data);
for (size_t y = rect.height; y > 0; --y) {
eleStream.read(ipBuffer, rect.width * 4);
if (eleStream.gcount() != rect.width * 4) return 1;
ipBuffer += buffer->omxBuffer.attr.anwBuffer.stride * 4;
}
} else {
EXPECT_TRUE(false) << "un expected pixel format";
return 1;
}
mapper.mMapper->unlock(
buff,
[&](Error _e, const android::hardware::hidl_handle& _n1) {
error = _e;
fence = _n1;
});
EXPECT_EQ(error, Error::NONE);
if (error != Error::NONE)
return 1;
}
return 0;
}, mapperVar);
}
int fillGraphicBuffer(BufferInfo* buffer, PixelFormat format,
std::ifstream& eleStream) {
sp<android::hardware::graphics::mapper::V2_0::IMapper> mapper =
android::hardware::graphics::mapper::V2_0::IMapper::getService();
EXPECT_NE(mapper.get(), nullptr);
if (mapper.get() == nullptr) return 1;
void* buff = nullptr;
android::hardware::graphics::mapper::V2_0::Error error;
mapper->importBuffer(
buffer->omxBuffer.nativeHandle,
[&](android::hardware::graphics::mapper::V2_0::Error _e, void* _n1) {
error = _e;
buff = _n1;
});
EXPECT_EQ(error, android::hardware::graphics::mapper::V2_0::Error::NONE);
if (error != android::hardware::graphics::mapper::V2_0::Error::NONE)
MapperVar mapperVar;
if (!initialize(mapperVar)) {
EXPECT_TRUE(false) << "failed to obtain mapper service";
return 1;
}
if (colorFormatConversion(buffer, buff, format, eleStream)) return 1;
return std::visit([buffer, format, &eleStream](auto&& mapper) -> int {
using Gralloc = std::remove_reference_t<decltype(mapper)>;
using Error = typename Gralloc::Error;
error = mapper->freeBuffer(buff);
EXPECT_EQ(error, android::hardware::graphics::mapper::V2_0::Error::NONE);
if (error != android::hardware::graphics::mapper::V2_0::Error::NONE)
return 1;
void* buff = nullptr;
Error error;
mapper.mMapper->importBuffer(
buffer->omxBuffer.nativeHandle,
[&](Error _e, void* _n1) {
error = _e;
buff = _n1;
});
EXPECT_EQ(error, Error::NONE);
if (error != Error::NONE)
return 1;
return 0;
if (colorFormatConversion(buffer, buff, format, eleStream)) return 1;
error = mapper.mMapper->freeBuffer(buff);
EXPECT_EQ(error, Error::NONE);
if (error != Error::NONE)
return 1;
return 0;
}, mapperVar);
}
int dispatchGraphicBuffer(sp<IOmxNode> omxNode,