Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 7194b0f1 authored by Ján Sebechlebský's avatar Ján Sebechlebský Committed by Android (Google) Code Review
Browse files

Merge "Pick largest resolution for input surface" into main

parents a7eb5ff7 39129f8f
Loading
Loading
Loading
Loading
+5 −0
Original line number Diff line number Diff line
@@ -283,6 +283,11 @@ ndk::ScopedAStatus VirtualCameraDevice::isStreamCombinationSupported(

bool VirtualCameraDevice::isStreamCombinationSupported(
    const StreamConfiguration& streamConfiguration) const {
  if (streamConfiguration.streams.empty()) {
    ALOGE("%s: Querying empty configuration", __func__);
    return false;
  }

  for (const Stream& stream : streamConfiguration.streams) {
    ALOGV("%s: Configuration queried: %s", __func__, stream.toString().c_str());

+11 −2
Original line number Diff line number Diff line
@@ -18,6 +18,7 @@
#define LOG_TAG "VirtualCameraSession"
#include "VirtualCameraSession.h"

#include <algorithm>
#include <atomic>
#include <chrono>
#include <cstddef>
@@ -150,6 +151,13 @@ HalStream getHalStream(const Stream& stream) {
  return halStream;
}

Stream getHighestResolutionStream(const std::vector<Stream>& streams) {
  return *(std::max_element(streams.begin(), streams.end(),
                            [](const Stream& a, const Stream& b) {
                              return a.width * a.height < b.width * b.height;
                            }));
}

}  // namespace

VirtualCameraSession::VirtualCameraSession(
@@ -233,8 +241,9 @@ ndk::ScopedAStatus VirtualCameraSession::configureStreams(
      }
    }

    inputWidth = streams[0].width;
    inputHeight = streams[0].height;
    Stream maxResStream = getHighestResolutionStream(streams);
    inputWidth = maxResStream.width;
    inputHeight = maxResStream.height;
    if (mRenderThread == nullptr) {
      // If there's no client callback, start camera in test mode.
      const bool testMode = mVirtualCameraClientCallback == nullptr;
+50 −26
Original line number Diff line number Diff line
@@ -37,10 +37,13 @@ namespace companion {
namespace virtualcamera {
namespace {

constexpr int kWidth = 640;
constexpr int kHeight = 480;
constexpr int kVgaWidth = 640;
constexpr int kVgaHeight = 480;
constexpr int kSvgaWidth = 800;
constexpr int kSvgaHeight = 600;
constexpr int kMaxFps = 30;
constexpr int kStreamId = 0;
constexpr int kSecondStreamId = 1;
constexpr int kCameraId = 42;

using ::aidl::android::companion::virtualcamera::BnVirtualCameraCallback;
@@ -109,10 +112,16 @@ class VirtualCameraSessionTest : public ::testing::Test {
    mMockVirtualCameraClientCallback =
        ndk::SharedRefBase::make<MockVirtualCameraCallback>();
    mVirtualCameraDevice = ndk::SharedRefBase::make<VirtualCameraDevice>(
        kCameraId, VirtualCameraConfiguration{
        kCameraId,
        VirtualCameraConfiguration{
            .supportedStreamConfigs = {SupportedStreamConfiguration{
                           .width = kWidth,
                           .height = kHeight,
                                           .width = kVgaWidth,
                                           .height = kVgaHeight,
                                           .pixelFormat = Format::YUV_420_888,
                                           .maxFps = kMaxFps},
                                       SupportedStreamConfiguration{
                                           .width = kSvgaWidth,
                                           .height = kSvgaHeight,
                                           .pixelFormat = Format::YUV_420_888,
                                           .maxFps = kMaxFps}},
            .virtualCameraCallback = nullptr,
@@ -154,18 +163,22 @@ TEST_F(VirtualCameraSessionTest, ConfigureTriggersClientConfigureCallback) {
  PixelFormat format = PixelFormat::YCBCR_420_888;
  StreamConfiguration streamConfiguration;
  streamConfiguration.streams = {
      createStream(kStreamId, kWidth, kHeight, format)};
      createStream(kStreamId, kVgaWidth, kVgaHeight, format),
      createStream(kSecondStreamId, kSvgaWidth, kSvgaHeight, format)};
  std::vector<HalStream> halStreams;
  EXPECT_CALL(
      *mMockVirtualCameraClientCallback,
      onStreamConfigured(kStreamId, _, kWidth, kHeight, Format::YUV_420_888));

  // Expect highest resolution to be picked for the client input.
  EXPECT_CALL(*mMockVirtualCameraClientCallback,
              onStreamConfigured(kStreamId, _, kSvgaWidth, kSvgaHeight,
                                 Format::YUV_420_888));

  ASSERT_TRUE(
      mVirtualCameraSession->configureStreams(streamConfiguration, &halStreams)
          .isOk());

  EXPECT_THAT(halStreams, SizeIs(streamConfiguration.streams.size()));
  EXPECT_THAT(mVirtualCameraSession->getStreamIds(), ElementsAre(0));
  EXPECT_THAT(mVirtualCameraSession->getStreamIds(),
              ElementsAre(kStreamId, kSecondStreamId));
}

TEST_F(VirtualCameraSessionTest, SecondConfigureDropsUnreferencedStreams) {
@@ -173,18 +186,18 @@ TEST_F(VirtualCameraSessionTest, SecondConfigureDropsUnreferencedStreams) {
  StreamConfiguration streamConfiguration;
  std::vector<HalStream> halStreams;

  streamConfiguration.streams = {createStream(0, kWidth, kHeight, format),
                                 createStream(1, kWidth, kHeight, format),
                                 createStream(2, kWidth, kHeight, format)};
  streamConfiguration.streams = {createStream(0, kVgaWidth, kVgaHeight, format),
                                 createStream(1, kVgaWidth, kVgaHeight, format),
                                 createStream(2, kVgaWidth, kVgaHeight, format)};
  ASSERT_TRUE(
      mVirtualCameraSession->configureStreams(streamConfiguration, &halStreams)
          .isOk());

  EXPECT_THAT(mVirtualCameraSession->getStreamIds(), ElementsAre(0, 1, 2));

  streamConfiguration.streams = {createStream(0, kWidth, kHeight, format),
                                 createStream(2, kWidth, kHeight, format),
                                 createStream(3, kWidth, kHeight, format)};
  streamConfiguration.streams = {createStream(0, kVgaWidth, kVgaHeight, format),
                                 createStream(2, kVgaWidth, kVgaHeight, format),
                                 createStream(3, kVgaWidth, kVgaHeight, format)};
  ASSERT_TRUE(
      mVirtualCameraSession->configureStreams(streamConfiguration, &halStreams)
          .isOk());
@@ -209,8 +222,8 @@ TEST_F(VirtualCameraSessionTest, FlushBeforeConfigure) {

TEST_F(VirtualCameraSessionTest, onProcessCaptureRequestTriggersClientCallback) {
  StreamConfiguration streamConfiguration;
  streamConfiguration.streams = {
      createStream(kStreamId, kWidth, kHeight, PixelFormat::YCBCR_420_888)};
  streamConfiguration.streams = {createStream(kStreamId, kVgaWidth, kVgaHeight,
                                              PixelFormat::YCBCR_420_888)};
  std::vector<CaptureRequest> requests(1);
  requests[0].frameNumber = 42;
  requests[0].settings = *(
@@ -234,8 +247,8 @@ TEST_F(VirtualCameraSessionTest, onProcessCaptureRequestTriggersClientCallback)

TEST_F(VirtualCameraSessionTest, configureAfterCameraRelease) {
  StreamConfiguration streamConfiguration;
  streamConfiguration.streams = {
      createStream(kStreamId, kWidth, kHeight, PixelFormat::YCBCR_420_888)};
  streamConfiguration.streams = {createStream(kStreamId, kVgaWidth, kVgaHeight,
                                              PixelFormat::YCBCR_420_888)};
  std::vector<HalStream> halStreams;

  // Release virtual camera.
@@ -248,6 +261,17 @@ TEST_F(VirtualCameraSessionTest, configureAfterCameraRelease) {
      Eq(static_cast<int32_t>(Status::CAMERA_DISCONNECTED)));
}

TEST_F(VirtualCameraSessionTest, ConfigureWithEmptyStreams) {
  StreamConfiguration streamConfiguration;
  std::vector<HalStream> halStreams;

  // Expect configuration attempt returns CAMERA_DISCONNECTED service specific code.
  EXPECT_THAT(
      mVirtualCameraSession->configureStreams(streamConfiguration, &halStreams)
          .getServiceSpecificError(),
      Eq(static_cast<int32_t>(Status::ILLEGAL_ARGUMENT)));
}

}  // namespace
}  // namespace virtualcamera
}  // namespace companion