Merge changes I9953dcec,I5bc7034e into rvc-dev
* changes:
Handles invalid requests to open EVS display
Add a command line option for the buffer format
diff --git a/evs/apps/default/ConfigManager.h b/evs/apps/default/ConfigManager.h
index 6acd83d..9c6d1a2 100644
--- a/evs/apps/default/ConfigManager.h
+++ b/evs/apps/default/ConfigManager.h
@@ -19,6 +19,8 @@
#include <vector>
#include <string>
+#include <system/graphics-base.h>
+
class ConfigManager {
public:
@@ -91,6 +93,12 @@
const DisplayInfo& getActiveDisplay() const { return mDisplays[mActiveDisplayId]; };
void useExternalMemory(bool flag) { mUseExternalMemory = flag; }
bool getUseExternalMemory() const { return mUseExternalMemory; }
+ void setExternalMemoryFormat(android_pixel_format_t format) {
+ mExternalMemoryFormat = format;
+ }
+ android_pixel_format_t getExternalMemoryFormat() const {
+ return mExternalMemoryFormat;
+ }
private:
// Camera information
@@ -103,6 +111,9 @@
// Memory management
bool mUseExternalMemory;
+ // Format of external memory
+ android_pixel_format_t mExternalMemoryFormat;
+
// Car body information (assumes front wheel steering and origin at center of rear axel)
// Note that units aren't specified and don't matter as long as all length units are consistent
// within the JSON file from which we parse. That is, if everything is in meters, that's fine.
diff --git a/evs/apps/default/RenderDirectView.cpp b/evs/apps/default/RenderDirectView.cpp
index 2938521..68b731e 100644
--- a/evs/apps/default/RenderDirectView.cpp
+++ b/evs/apps/default/RenderDirectView.cpp
@@ -116,7 +116,8 @@
mCameraDesc.v1.cameraId.c_str(),
foundCfg ? std::move(targetCfg) : nullptr,
sDisplay,
- mConfig.getUseExternalMemory()));
+ mConfig.getUseExternalMemory(),
+ mConfig.getExternalMemoryFormat()));
if (!mTexture) {
LOG(ERROR) << "Failed to set up video texture for " << mCameraDesc.v1.cameraId;
// TODO: For production use, we may actually want to fail in this case, but not yet...
diff --git a/evs/apps/default/StreamHandler.cpp b/evs/apps/default/StreamHandler.cpp
index b1cfd1f..d350af1 100644
--- a/evs/apps/default/StreamHandler.cpp
+++ b/evs/apps/default/StreamHandler.cpp
@@ -30,6 +30,7 @@
StreamHandler::StreamHandler(android::sp <IEvsCamera> pCamera,
uint32_t numBuffers,
bool useOwnBuffers,
+ android_pixel_format_t format,
int32_t width,
int32_t height)
: mCamera(pCamera),
@@ -46,7 +47,6 @@
const auto usage = GRALLOC_USAGE_HW_TEXTURE |
GRALLOC_USAGE_SW_READ_RARELY |
GRALLOC_USAGE_SW_WRITE_OFTEN;
- const auto format = HAL_PIXEL_FORMAT_RGBA_8888;
for (auto i = 0; i < numBuffers; ++i) {
unsigned pixelsPerLine;
android::status_t result = alloc.allocate(width,
@@ -64,10 +64,10 @@
BufferDesc_1_1 buf;
AHardwareBuffer_Desc* pDesc =
reinterpret_cast<AHardwareBuffer_Desc *>(&buf.buffer.description);
- pDesc->width = 640;
- pDesc->height = 360;
+ pDesc->width = width;
+ pDesc->height = height;
pDesc->layers = 1;
- pDesc->format = HAL_PIXEL_FORMAT_RGBA_8888;
+ pDesc->format = format;
pDesc->usage = GRALLOC_USAGE_HW_TEXTURE |
GRALLOC_USAGE_SW_READ_RARELY |
GRALLOC_USAGE_SW_WRITE_OFTEN;
diff --git a/evs/apps/default/StreamHandler.h b/evs/apps/default/StreamHandler.h
index f877c78..cb22b36 100644
--- a/evs/apps/default/StreamHandler.h
+++ b/evs/apps/default/StreamHandler.h
@@ -51,6 +51,7 @@
StreamHandler(android::sp <IEvsCamera> pCamera,
uint32_t numBuffers = 2,
bool useOwnBuffers = false,
+ android_pixel_format_t format = HAL_PIXEL_FORMAT_RGBA_8888,
int32_t width = 640,
int32_t height = 360);
void shutdown();
diff --git a/evs/apps/default/VideoTex.cpp b/evs/apps/default/VideoTex.cpp
index 94e734a..7491dfe 100644
--- a/evs/apps/default/VideoTex.cpp
+++ b/evs/apps/default/VideoTex.cpp
@@ -137,29 +137,39 @@
const char* evsCameraId,
std::unique_ptr<Stream> streamCfg,
EGLDisplay glDisplay,
- bool useExternalMemory) {
+ bool useExternalMemory,
+ android_pixel_format_t format) {
// Set up the camera to feed this texture
sp<IEvsCamera> pCamera = nullptr;
+ sp<StreamHandler> pStreamHandler = nullptr;
if (streamCfg != nullptr) {
pCamera = pEnum->openCamera_1_1(evsCameraId, *streamCfg);
+
+ // Initialize the stream that will help us update this texture's contents
+ pStreamHandler = new StreamHandler(pCamera,
+ 2, // number of buffers
+ useExternalMemory,
+ format,
+ streamCfg->width,
+ streamCfg->height);
} else {
pCamera =
IEvsCamera::castFrom(pEnum->openCamera(evsCameraId))
.withDefault(nullptr);
+
+ // Initialize the stream with the default resolution
+ pStreamHandler = new StreamHandler(pCamera,
+ 2, // number of buffers
+ useExternalMemory,
+ format);
}
- if (pCamera.get() == nullptr) {
+ if (pCamera == nullptr) {
LOG(ERROR) << "Failed to allocate new EVS Camera interface for " << evsCameraId;
return nullptr;
}
- // Initialize the stream that will help us update this texture's contents
- sp<StreamHandler> pStreamHandler = new StreamHandler(pCamera,
- 2, // number of buffers
- useExternalMemory,
- streamCfg->width,
- streamCfg->height);
- if (pStreamHandler.get() == nullptr) {
+ if (pStreamHandler == nullptr) {
LOG(ERROR) << "Failed to allocate FrameHandler";
return nullptr;
}
diff --git a/evs/apps/default/VideoTex.h b/evs/apps/default/VideoTex.h
index d884faa..097d086 100644
--- a/evs/apps/default/VideoTex.h
+++ b/evs/apps/default/VideoTex.h
@@ -16,6 +16,9 @@
#ifndef VIDEOTEX_H
#define VIDEOTEX_H
+#include "StreamHandler.h"
+#include "TexWrapper.h"
+
#include <EGL/egl.h>
#include <EGL/eglext.h>
#include <GLES2/gl2.h>
@@ -25,9 +28,7 @@
#include <android/hardware/automotive/evs/1.1/IEvsEnumerator.h>
#include <android/hardware/camera/device/3.2/ICameraDevice.h>
-
-#include "TexWrapper.h"
-#include "StreamHandler.h"
+#include <system/graphics-base.h>
using ::android::hardware::camera::device::V3_2::Stream;
using namespace ::android::hardware::automotive::evs::V1_1;
@@ -38,7 +39,8 @@
const char *evsCameraId,
std::unique_ptr<Stream> streamCfg,
EGLDisplay glDisplay,
- bool useExternalMemory);
+ bool useExternalMemory,
+ android_pixel_format_t format);
public:
VideoTex() = delete;
@@ -62,10 +64,13 @@
};
+// Creates a video texture to draw the camera preview. format is effective only
+// when useExternalMemory is true.
VideoTex* createVideoTexture(sp<IEvsEnumerator> pEnum,
const char * deviceName,
std::unique_ptr<Stream> streamCfg,
EGLDisplay glDisplay,
- bool useExternalMemory = false);
+ bool useExternalMemory = false,
+ android_pixel_format_t format = HAL_PIXEL_FORMAT_RGBA_8888);
#endif // VIDEOTEX_H
diff --git a/evs/apps/default/evs_app.cpp b/evs/apps/default/evs_app.cpp
index a968990..9f2f2c8 100644
--- a/evs/apps/default/evs_app.cpp
+++ b/evs/apps/default/evs_app.cpp
@@ -14,24 +14,25 @@
* limitations under the License.
*/
+#include "ConfigManager.h"
+#include "EvsStateControl.h"
+#include "EvsVehicleListener.h"
+
#include <stdio.h>
+#include <android/hardware/automotive/evs/1.1/IEvsDisplay.h>
+#include <android/hardware/automotive/evs/1.1/IEvsEnumerator.h>
+#include <android-base/logging.h>
+#include <android-base/macros.h> // arraysize
+#include <android-base/strings.h>
#include <hidl/HidlTransportSupport.h>
+#include <hwbinder/ProcessState.h>
#include <utils/Errors.h>
#include <utils/StrongPointer.h>
#include <utils/Log.h>
-#include "android-base/macros.h" // arraysize
-#include "android-base/logging.h"
-#include <android/hardware/automotive/evs/1.1/IEvsEnumerator.h>
-#include <android/hardware/automotive/evs/1.1/IEvsDisplay.h>
-
-#include <hwbinder/ProcessState.h>
-
-#include "EvsStateControl.h"
-#include "EvsVehicleListener.h"
-#include "ConfigManager.h"
+using android::base::EqualsIgnoreCase;
// libhidl:
using android::hardware::configureRpcThreadpool;
@@ -66,6 +67,24 @@
}
+static bool convertStringToFormat(const char* str, android_pixel_format_t* output) {
+ bool result = true;
+ if (EqualsIgnoreCase(str, "RGBA8888")) {
+ *output = HAL_PIXEL_FORMAT_RGBA_8888;
+ } else if (EqualsIgnoreCase(str, "YV12")) {
+ *output = HAL_PIXEL_FORMAT_YV12;
+ } else if (EqualsIgnoreCase(str, "NV21")) {
+ *output = HAL_PIXEL_FORMAT_YCrCb_420_SP;
+ } else if (EqualsIgnoreCase(str, "YUYV")) {
+ *output = HAL_PIXEL_FORMAT_YCBCR_422_I;
+ } else {
+ result = false;
+ }
+
+ return result;
+}
+
+
// Main entry point
int main(int argc, char** argv)
{
@@ -77,6 +96,7 @@
const char* evsServiceName = "default";
int displayId = 1;
bool useExternalMemory = false;
+ android_pixel_format_t extMemoryFormat = HAL_PIXEL_FORMAT_RGBA_8888;
for (int i=1; i< argc; i++) {
if (strcmp(argv[i], "--test") == 0) {
useVehicleHal = false;
@@ -90,6 +110,19 @@
displayId = std::stoi(argv[++i]);
} else if (strcmp(argv[i], "--extmem") == 0) {
useExternalMemory = true;
+ if (i + 1 >= argc) {
+ // use RGBA8888 by default
+ LOG(INFO) << "External buffer format is not set. "
+ << "RGBA8888 will be used.";
+ } else {
+ if (!convertStringToFormat(argv[i + 1], &extMemoryFormat)) {
+ LOG(WARNING) << "Color format string " << argv[i + 1]
+ << " is unknown or not supported. RGBA8888 will be used.";
+ } else {
+ // move the index
+ ++i;
+ }
+ }
} else {
printf("Ignoring unrecognized command line arg '%s'\n", argv[i]);
printHelp = true;
@@ -97,11 +130,23 @@
}
if (printHelp) {
printf("Options include:\n");
- printf(" --test Do not talk to Vehicle Hal, but simulate 'reverse' instead\n");
- printf(" --hw Bypass EvsManager by connecting directly to EvsEnumeratorHw\n");
- printf(" --mock Connect directly to EvsEnumeratorHw-Mock\n");
- printf(" --display Specify the display to use\n");
- printf(" --extmem Application allocates buffers to capture camera frames\n");
+ printf(" --test\n\tDo not talk to Vehicle Hal, but simulate 'reverse' instead\n");
+ printf(" --hw\n\tBypass EvsManager by connecting directly to EvsEnumeratorHw\n");
+ printf(" --mock\n\tConnect directly to EvsEnumeratorHw-Mock\n");
+ printf(" --display\n\tSpecify the display to use\n");
+ printf(" --extmem <format>\n\t"
+ "Application allocates buffers to capture camera frames. "
+ "Available format strings are (case insensitive):\n");
+ printf("\t\tRGBA8888: 4x8-bit RGBA format. This is the default format to be used "
+ "when no format is specified.\n");
+ printf("\t\tYV12: YUV420 planar format with a full resolution Y plane "
+ "followed by a V values, with U values last.\n");
+ printf("\t\tNV21: A biplanar format with a full resolution Y plane "
+ "followed by a single chrome plane with weaved V and U values.\n");
+ printf("\t\tYUYV: Packed format with a half horizontal chrome resolution. "
+ "Known as YUV4:2:2.\n");
+
+ return EXIT_FAILURE;
}
// Load our configuration information
@@ -140,6 +185,7 @@
}
config.setActiveDisplayId(displayId);
config.useExternalMemory(useExternalMemory);
+ config.setExternalMemoryFormat(extMemoryFormat);
// Connect to the Vehicle HAL so we can monitor state
sp<IVehicle> pVnet;
diff --git a/evs/manager/1.1/Enumerator.cpp b/evs/manager/1.1/Enumerator.cpp
index 8417828..8832db6 100644
--- a/evs/manager/1.1/Enumerator.cpp
+++ b/evs/manager/1.1/Enumerator.cpp
@@ -43,9 +43,13 @@
// Get an internal display identifier.
mHwEnumerator->getDisplayIdList(
[this](const auto& displayPorts) {
- if (displayPorts.size() > 0) {
- mInternalDisplayPort = displayPorts[0];
- } else {
+ for (auto& port : displayPorts) {
+ mDisplayPorts.push_back(port);
+ }
+
+ // The first element is the internal display
+ mInternalDisplayPort = mDisplayPorts.front();
+ if (mDisplayPorts.size() < 1) {
LOG(WARNING) << "No display is available to EVS service.";
}
}
@@ -444,6 +448,11 @@
return nullptr;
}
+ if (std::find(mDisplayPorts.begin(), mDisplayPorts.end(), id) == mDisplayPorts.end()) {
+ LOG(ERROR) << "No display is available on the port " << static_cast<int32_t>(id);
+ return nullptr;
+ }
+
// We simply keep track of the most recently opened display instance.
// In the underlying layers we expect that a new open will cause the previous
// object to be destroyed. This avoids any race conditions associated with
diff --git a/evs/manager/1.1/Enumerator.h b/evs/manager/1.1/Enumerator.h
index f23871e..81c971f 100644
--- a/evs/manager/1.1/Enumerator.h
+++ b/evs/manager/1.1/Enumerator.h
@@ -93,6 +93,9 @@
std::unordered_map<std::string,
CameraDesc> mCameraDevices;
+ // List of available physical display devices
+ std::list<uint8_t> mDisplayPorts;
+
// Display port the internal display is connected to.
uint8_t mInternalDisplayPort;
diff --git a/evs/sampleDriver/EvsEnumerator.cpp b/evs/sampleDriver/EvsEnumerator.cpp
index e108007..ef6009e 100644
--- a/evs/sampleDriver/EvsEnumerator.cpp
+++ b/evs/sampleDriver/EvsEnumerator.cpp
@@ -534,6 +534,12 @@
}
// Create a new display interface and return it
+ if (sDisplayPortList.find(port) == sDisplayPortList.end()) {
+ LOG(ERROR) << "No display is available on the port "
+ << static_cast<int32_t>(port);
+ return nullptr;
+ }
+
pActiveDisplay = new EvsGlDisplay(sDisplayProxy, sDisplayPortList[port]);
sActiveDisplay = pActiveDisplay;