[DO NOT MERGE] OMX VTS: Use GraphicBuffer utils from libui

Use GraphicBufferMapper and GraphicBufferAllocator for
gralloc buffers. This makes the tests independent of
gralloc version

Bug: 160355727
Test: atest VtsHalMediaOmxV1_0TargetMasterTest \
        VtsHalMediaOmxV1_0TargetComponentTest \
        VtsHalMediaOmxV1_0TargetAudioEncTest \
        VtsHalMediaOmxV1_0TargetAudioDecTest \
        VtsHalMediaOmxV1_0TargetVideoDecTest \
        VtsHalMediaOmxV1_0TargetVideoEncTest

Change-Id: If407ac3d8c0fadc55a8e57627121244a8d5155f8
This commit is contained in:
Manisha Jajoo 2020-07-15 19:11:26 +05:30 committed by Sungtak Lee
parent f0dfc4d624
commit 868c18341d
4 changed files with 125 additions and 353 deletions

View file

@ -22,28 +22,24 @@ cc_library_static {
export_header_lib_headers: ["media_plugin_headers"],
export_include_dirs: ["."],
shared_libs: [
"libui",
],
static_libs: [
"libgtest",
"libhidlmemory",
"android.hidl.allocator@1.0",
"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",
],
}
@ -54,15 +50,10 @@ cc_defaults {
// Link to these statically as they are not guaranteed to be on the device.
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",
"android.hardware.media@1.0",
"android.hidl.allocator@1.0",
@ -73,6 +64,7 @@ cc_defaults {
// TODO(b/64437680): Assume these libs are always available on the device.
shared_libs: [
"libui",
"libstagefright_foundation",
"libstagefright_omx_utils",
],

View file

@ -21,12 +21,6 @@
#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>
@ -199,42 +193,6 @@ void allocateGraphicBuffers(sp<IOmxNode> omxNode, OMX_U32 portIndex,
BufferInfo* buffer, uint32_t nFrameWidth,
uint32_t nFrameHeight, int32_t* nStride,
int format) {
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> 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::media::omx::V1_0::Status status{};
uint64_t usage{};
ASSERT_TRUE(omxNode->getGraphicBufferUsage(
@ -246,57 +204,27 @@ void allocateGraphicBuffers(sp<IOmxNode> omxNode, OMX_U32 portIndex,
}).isOk());
ASSERT_EQ(status, android::hardware::media::omx::V1_0::Status::OK);
uint32_t stride;
buffer_handle_t handle = nullptr;
android::GraphicBufferAllocator& allocator = android::GraphicBufferAllocator::get();
android::status_t error = allocator.allocate(
nFrameWidth, nFrameHeight, static_cast<android::PixelFormat>(format), 1,
usage | BufferUsage::CPU_READ_OFTEN, &handle, &stride, "omx_vts_common");
ASSERT_EQ(error, android::NO_ERROR);
ASSERT_NE(handle, nullptr);
*nStride = static_cast<int32_t>(stride);
buffer->omxBuffer.nativeHandle = handle;
buffer->omxBuffer.attr.anwBuffer.width = nFrameWidth;
buffer->omxBuffer.attr.anwBuffer.height = nFrameHeight;
buffer->omxBuffer.attr.anwBuffer.stride = stride;
buffer->omxBuffer.attr.anwBuffer.format = static_cast<PixelFormat>(format);
buffer->omxBuffer.attr.anwBuffer.usage = usage | BufferUsage::CPU_READ_OFTEN;
buffer->omxBuffer.attr.anwBuffer.layerCount = 1;
static std::atomic_int32_t bufferIdCounter{0};
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);
buffer->omxBuffer.attr.anwBuffer.id = (static_cast<uint64_t>(getpid()) << 32) |
bufferIdCounter.fetch_add(1, std::memory_order_relaxed);
}
// allocate buffers needed on a component port

View file

@ -22,16 +22,6 @@
#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 <gtest/gtest.h>
#include <hidl/ServiceManagement.h>
#include <media/stagefright/foundation/ALooper.h>
@ -46,6 +36,9 @@
#include <media/openmax/OMX_AudioExt.h>
#include <media/openmax/OMX_VideoExt.h>
#include <ui/GraphicBufferAllocator.h>
#include <ui/GraphicBufferMapper.h>
/* TIME OUTS (Wait time in dequeueMessage()) */
/* As component is switching states (loaded<->idle<->execute), dequeueMessage()
@ -312,35 +305,6 @@ 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 std::string& role);

View file

@ -23,8 +23,6 @@
#include <android/hardware/graphics/bufferqueue/1.0/IGraphicBufferProducer.h>
#include <android/hardware/graphics/bufferqueue/1.0/IProducerListener.h>
#include <android/hardware/graphics/mapper/2.0/IMapper.h>
#include <android/hardware/graphics/mapper/2.0/types.h>
#include <android/hardware/media/omx/1.0/IGraphicBufferSource.h>
#include <android/hardware/media/omx/1.0/IOmx.h>
#include <android/hardware/media/omx/1.0/IOmxBufferSource.h>
@ -364,61 +362,6 @@ 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;
@ -627,168 +570,113 @@ void waitOnInputConsumption(sp<IOmxNode> omxNode, sp<CodecObserver> observer,
}
}
int colorFormatConversion(BufferInfo* buffer, void* buff, PixelFormat format,
int colorFormatConversion(BufferInfo* buffer, buffer_handle_t buff, PixelFormat format,
std::ifstream& eleStream) {
MapperVar mapperVar;
if (!initialize(mapperVar)) {
EXPECT_TRUE(false) << "failed to obtain mapper service";
return 1;
android::GraphicBufferMapper& gbmapper = android::GraphicBufferMapper::get();
android::Rect rect(0, 0, buffer->omxBuffer.attr.anwBuffer.width,
buffer->omxBuffer.attr.anwBuffer.height);
android_ycbcr ycbcrLayout;
android::status_t error = android::NO_ERROR;
if (format == PixelFormat::YV12 || format == PixelFormat::YCRCB_420_SP ||
format == PixelFormat::YCBCR_420_888) {
error = gbmapper.lockYCbCr(buff, buffer->omxBuffer.attr.anwBuffer.usage, rect,
&ycbcrLayout);
EXPECT_EQ(error, android::NO_ERROR);
if (error != android::NO_ERROR) return 1;
int size = ((rect.getWidth() * rect.getHeight() * 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.getHeight(); y > 0; --y) {
memcpy(ipBuffer, imgTmp, rect.getWidth());
ipBuffer += ycbcrLayout.ystride;
imgTmp += rect.getWidth();
}
if (format == PixelFormat::YV12)
EXPECT_EQ(ycbcrLayout.chroma_step, 1U);
else if (format == PixelFormat::YCRCB_420_SP)
EXPECT_EQ(ycbcrLayout.chroma_step, 2U);
ipBuffer = static_cast<char*>(ycbcrLayout.cb);
for (size_t y = rect.getHeight() >> 1; y > 0; --y) {
for (int32_t x = 0; x < (rect.getWidth() >> 1); ++x) {
ipBuffer[ycbcrLayout.chroma_step * x] = *imgTmp++;
}
ipBuffer += ycbcrLayout.cstride;
}
ipBuffer = static_cast<char*>(ycbcrLayout.cr);
for (size_t y = rect.getHeight() >> 1; y > 0; --y) {
for (int32_t x = 0; x < (rect.getWidth() >> 1); ++x) {
ipBuffer[ycbcrLayout.chroma_step * x] = *imgTmp++;
}
ipBuffer += ycbcrLayout.cstride;
}
delete[] img;
error = gbmapper.unlock(buff);
EXPECT_EQ(error, android::NO_ERROR);
if (error != android::NO_ERROR) return 1;
} else {
void* data;
int32_t outBytesPerPixel;
int32_t outBytesPerStride;
error = gbmapper.lock(buff, buffer->omxBuffer.attr.anwBuffer.usage, rect, &data,
&outBytesPerPixel, &outBytesPerStride);
EXPECT_EQ(error, android::NO_ERROR);
if (error != android::NO_ERROR) return 1;
if (format == PixelFormat::BGRA_8888) {
char* ipBuffer = static_cast<char*>(data);
for (size_t y = rect.getHeight(); y > 0; --y) {
eleStream.read(ipBuffer, rect.getWidth() * 4);
if (eleStream.gcount() != rect.getWidth() * 4) return 1;
ipBuffer += buffer->omxBuffer.attr.anwBuffer.stride * 4;
}
} else {
EXPECT_TRUE(false) << "un expected pixel format";
return 1;
}
error = gbmapper.unlock(buff);
EXPECT_EQ(error, android::NO_ERROR);
if (error != android::NO_ERROR) return 1;
}
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);
return 0;
}
int fillGraphicBuffer(BufferInfo* buffer, PixelFormat format,
std::ifstream& eleStream) {
MapperVar mapperVar;
if (!initialize(mapperVar)) {
EXPECT_TRUE(false) << "failed to obtain mapper service";
return 1;
}
android::GraphicBufferMapper& gbmapper = android::GraphicBufferMapper::get();
buffer_handle_t buff;
android::status_t error = android::NO_ERROR;
gbmapper.importBuffer(
buffer->omxBuffer.nativeHandle, buffer->omxBuffer.attr.anwBuffer.width,
buffer->omxBuffer.attr.anwBuffer.height, buffer->omxBuffer.attr.anwBuffer.layerCount,
static_cast<android::PixelFormat>(format), buffer->omxBuffer.attr.anwBuffer.usage,
buffer->omxBuffer.attr.anwBuffer.stride, &buff);
EXPECT_EQ(error, android::NO_ERROR);
if (error != android::NO_ERROR) return 1;
return std::visit([buffer, format, &eleStream](auto&& mapper) -> int {
using Gralloc = std::remove_reference_t<decltype(mapper)>;
using Error = typename Gralloc::Error;
if (colorFormatConversion(buffer, buff, format, eleStream)) 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;
error = gbmapper.freeBuffer(buff);
EXPECT_EQ(error, android::NO_ERROR);
if (error != android::NO_ERROR) return 1;
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);
return 0;
}
int dispatchGraphicBuffer(sp<IOmxNode> omxNode,