Commit 67edf766 authored by hclam's avatar hclam Committed by Commit bot

Clarify resolution change behaviors of video capture devices

There's no functional change in this CL.

I clarified the behavior of resolution changes for video capture devices
by using an enum to describe resolution change policy instead of a
simple boolean.

BUG=388355

Review URL: https://codereview.chromium.org/541163002

Cr-Commit-Position: refs/heads/master@{#294714}
parent 9502c644
......@@ -155,7 +155,8 @@ void ThreadSafeCaptureOracle::UpdateCaptureSize(const gfx::Size& source_size) {
// If this is the first call to UpdateCaptureSize(), or the receiver supports
// variable resolution, then determine the capture size by treating the
// requested width and height as maxima.
if (!capture_size_updated_ || params_.allow_resolution_change) {
if (!capture_size_updated_ || params_.resolution_change_policy ==
media::RESOLUTION_POLICY_DYNAMIC_WITHIN_LIMIT) {
// The capture resolution should not exceed the source frame size.
// In other words it should downscale the image but not upscale it.
if (source_size.width() > params_.requested_format.frame_size.width() ||
......
......@@ -315,7 +315,8 @@ void DesktopCaptureDevice::Core::RefreshCaptureFormat(
output_frame_.reset();
if (previous_frame_size_.is_empty() ||
requested_params_.allow_resolution_change) {
requested_params_.resolution_change_policy ==
media::RESOLUTION_POLICY_DYNAMIC_WITHIN_LIMIT) {
// If this is the first frame, or the receiver supports variable resolution
// then determine the output size by treating the requested width & height
// as maxima.
......
......@@ -115,7 +115,6 @@ TEST_F(DesktopCaptureDeviceAuraTest, StartAndStop) {
capture_params.requested_format.frame_size.SetSize(640, 480);
capture_params.requested_format.frame_rate = kFrameRate;
capture_params.requested_format.pixel_format = media::PIXEL_FORMAT_I420;
capture_params.allow_resolution_change = false;
capture_device->AllocateAndStart(
capture_params, client.PassAs<media::VideoCaptureDevice::Client>());
capture_device->StopAndDeAllocate();
......
......@@ -172,7 +172,6 @@ TEST_F(DesktopCaptureDeviceTest, MAYBE_Capture) {
capture_params.requested_format.frame_size.SetSize(640, 480);
capture_params.requested_format.frame_rate = kFrameRate;
capture_params.requested_format.pixel_format = media::PIXEL_FORMAT_I420;
capture_params.allow_resolution_change = false;
capture_device_->AllocateAndStart(
capture_params, client.PassAs<media::VideoCaptureDevice::Client>());
EXPECT_TRUE(done_event.TimedWait(TestTimeouts::action_max_timeout()));
......@@ -209,7 +208,6 @@ TEST_F(DesktopCaptureDeviceTest, ScreenResolutionChangeConstantResolution) {
kTestFrameHeight1);
capture_params.requested_format.frame_rate = kFrameRate;
capture_params.requested_format.pixel_format = media::PIXEL_FORMAT_I420;
capture_params.allow_resolution_change = false;
capture_device_->AllocateAndStart(
capture_params, client.PassAs<media::VideoCaptureDevice::Client>());
......@@ -251,7 +249,6 @@ TEST_F(DesktopCaptureDeviceTest, ScreenResolutionChangeVariableResolution) {
kTestFrameHeight2);
capture_params.requested_format.frame_rate = kFrameRate;
capture_params.requested_format.pixel_format = media::PIXEL_FORMAT_I420;
capture_params.allow_resolution_change = false;
capture_device_->AllocateAndStart(
capture_params, client.PassAs<media::VideoCaptureDevice::Client>());
......
......@@ -644,7 +644,6 @@ TEST_F(WebContentsVideoCaptureDeviceTest, InvalidInitialWebContentsError) {
capture_params.requested_format.frame_size.SetSize(kTestWidth, kTestHeight);
capture_params.requested_format.frame_rate = kTestFramesPerSecond;
capture_params.requested_format.pixel_format = media::PIXEL_FORMAT_I420;
capture_params.allow_resolution_change = false;
device()->AllocateAndStart(capture_params, client_observer()->PassClient());
ASSERT_NO_FATAL_FAILURE(client_observer()->WaitForError());
device()->StopAndDeAllocate();
......@@ -662,7 +661,6 @@ TEST_F(WebContentsVideoCaptureDeviceTest, WebContentsDestroyed) {
capture_params.requested_format.frame_size.SetSize(kTestWidth, kTestHeight);
capture_params.requested_format.frame_rate = kTestFramesPerSecond;
capture_params.requested_format.pixel_format = media::PIXEL_FORMAT_I420;
capture_params.allow_resolution_change = false;
device()->AllocateAndStart(capture_params, client_observer()->PassClient());
// Do one capture to prove
source()->SetSolidColor(SK_ColorRED);
......@@ -690,7 +688,6 @@ TEST_F(WebContentsVideoCaptureDeviceTest,
capture_params.requested_format.frame_size.SetSize(kTestWidth, kTestHeight);
capture_params.requested_format.frame_rate = kTestFramesPerSecond;
capture_params.requested_format.pixel_format = media::PIXEL_FORMAT_I420;
capture_params.allow_resolution_change = false;
device()->AllocateAndStart(capture_params, client_observer()->PassClient());
// Make a point of not running the UI messageloop here.
......@@ -712,7 +709,6 @@ TEST_F(WebContentsVideoCaptureDeviceTest, StopWithRendererWorkToDo) {
capture_params.requested_format.frame_size.SetSize(kTestWidth, kTestHeight);
capture_params.requested_format.frame_rate = kTestFramesPerSecond;
capture_params.requested_format.pixel_format = media::PIXEL_FORMAT_I420;
capture_params.allow_resolution_change = false;
device()->AllocateAndStart(capture_params, client_observer()->PassClient());
base::RunLoop().RunUntilIdle();
......@@ -732,7 +728,6 @@ TEST_F(WebContentsVideoCaptureDeviceTest, DeviceRestart) {
capture_params.requested_format.frame_size.SetSize(kTestWidth, kTestHeight);
capture_params.requested_format.frame_rate = kTestFramesPerSecond;
capture_params.requested_format.pixel_format = media::PIXEL_FORMAT_I420;
capture_params.allow_resolution_change = false;
device()->AllocateAndStart(capture_params, client_observer()->PassClient());
base::RunLoop().RunUntilIdle();
source()->SetSolidColor(SK_ColorRED);
......@@ -771,7 +766,6 @@ TEST_F(WebContentsVideoCaptureDeviceTest, GoesThroughAllTheMotions) {
capture_params.requested_format.frame_size.SetSize(kTestWidth, kTestHeight);
capture_params.requested_format.frame_rate = kTestFramesPerSecond;
capture_params.requested_format.pixel_format = media::PIXEL_FORMAT_I420;
capture_params.allow_resolution_change = false;
device()->AllocateAndStart(capture_params, client_observer()->PassClient());
for (int i = 0; i < 6; i++) {
......@@ -822,7 +816,6 @@ TEST_F(WebContentsVideoCaptureDeviceTest, RejectsInvalidAllocateParams) {
capture_params.requested_format.frame_size.SetSize(1280, 720);
capture_params.requested_format.frame_rate = -2;
capture_params.requested_format.pixel_format = media::PIXEL_FORMAT_I420;
capture_params.allow_resolution_change = false;
BrowserThread::PostTask(
BrowserThread::UI,
FROM_HERE,
......@@ -844,7 +837,6 @@ TEST_F(WebContentsVideoCaptureDeviceTest, BadFramesGoodFrames) {
capture_params.requested_format.frame_size.SetSize(kTestWidth, kTestHeight);
capture_params.requested_format.frame_rate = kTestFramesPerSecond;
capture_params.requested_format.pixel_format = media::PIXEL_FORMAT_I420;
capture_params.allow_resolution_change = false;
// 1x1 is too small to process; we intend for this to result in an error.
source()->SetCopyResultSize(1, 1);
source()->SetSolidColor(SK_ColorRED);
......
......@@ -221,9 +221,11 @@ void VideoCaptureHost::OnStartCapture(int device_id,
DVLOG(1) << "VideoCaptureHost::OnStartCapture:"
<< " session_id=" << session_id
<< ", device_id=" << device_id
<< ", format=" << params.requested_format.frame_size.ToString()
<< ", format=" << params.requested_format.ToString()
<< "@" << params.requested_format.frame_rate
<< " (" << (params.allow_resolution_change ? "variable" : "constant")
<< " (" << (params.resolution_change_policy ==
media::RESOLUTION_POLICY_DYNAMIC_WITHIN_LIMIT ?
"variable" : "constant")
<< ")";
VideoCaptureControllerID controller_id(device_id);
if (entries_.find(controller_id) != entries_.end()) {
......
......@@ -17,9 +17,12 @@
IPC_ENUM_TRAITS_MAX_VALUE(content::VideoCaptureState,
content::VIDEO_CAPTURE_STATE_LAST)
IPC_ENUM_TRAITS_MAX_VALUE(media::ResolutionChangePolicy,
media::RESOLUTION_POLICY_LAST)
IPC_STRUCT_TRAITS_BEGIN(media::VideoCaptureParams)
IPC_STRUCT_TRAITS_MEMBER(requested_format)
IPC_STRUCT_TRAITS_MEMBER(allow_resolution_change)
IPC_STRUCT_TRAITS_MEMBER(resolution_change_policy)
IPC_STRUCT_TRAITS_END()
// TODO(nick): device_id in these messages is basically just a route_id. We
......
......@@ -104,7 +104,8 @@ TEST_F(MediaStreamVideoCapturerSourceTest, TabCaptureAllowResolutionChange) {
InitWithDeviceInfo(device_info);
EXPECT_CALL(mock_delegate(), StartCapture(
testing::Field(&media::VideoCaptureParams::allow_resolution_change, true),
testing::Field(&media::VideoCaptureParams::resolution_change_policy,
media::RESOLUTION_POLICY_DYNAMIC_WITHIN_LIMIT),
testing::_,
testing::_)).Times(1);
blink::WebMediaStreamTrack track = StartSource();
......@@ -119,7 +120,8 @@ TEST_F(MediaStreamVideoCapturerSourceTest,
InitWithDeviceInfo(device_info);
EXPECT_CALL(mock_delegate(), StartCapture(
testing::Field(&media::VideoCaptureParams::allow_resolution_change, true),
testing::Field(&media::VideoCaptureParams::resolution_change_policy,
media::RESOLUTION_POLICY_DYNAMIC_WITHIN_LIMIT),
testing::_,
testing::_)).Times(1);
blink::WebMediaStreamTrack track = StartSource();
......
......@@ -237,7 +237,8 @@ void MediaStreamVideoCapturerSource::StartSourceImpl(
new_params.requested_format = format;
if (device_info().device.type == MEDIA_TAB_VIDEO_CAPTURE ||
device_info().device.type == MEDIA_DESKTOP_VIDEO_CAPTURE) {
new_params.allow_resolution_change = true;
new_params.resolution_change_policy =
media::RESOLUTION_POLICY_DYNAMIC_WITHIN_LIMIT;
}
delegate_->StartCapture(
new_params,
......
......@@ -103,8 +103,8 @@ void VideoCaptureImpl::StartCapture(
clients_[client_id] = client_info;
// TODO(sheu): Allowing resolution change will require that all
// outstanding clients of a capture session support resolution change.
DCHECK_EQ(params_.allow_resolution_change,
params.allow_resolution_change);
DCHECK_EQ(params_.resolution_change_policy,
params.resolution_change_policy);
} else if (state_ == VIDEO_CAPTURE_STATE_STOPPING) {
clients_pending_on_restart_[client_id] = client_info;
DVLOG(1) << "StartCapture: Got new resolution "
......
......@@ -357,7 +357,6 @@ void PepperVideoCaptureHost::SetRequestedInfo(
gfx::Size(device_info.width, device_info.height),
frames_per_second,
media::PIXEL_FORMAT_I420);
video_capture_params_.allow_resolution_change = false;
}
void PepperVideoCaptureHost::DetachPlatformVideoCapture() {
......
......@@ -134,7 +134,6 @@ TEST_F(FakeVideoCaptureDeviceTest, Capture) {
capture_params.requested_format.frame_size.SetSize(640, 480);
capture_params.requested_format.frame_rate = 30;
capture_params.requested_format.pixel_format = PIXEL_FORMAT_I420;
capture_params.allow_resolution_change = false;
device->AllocateAndStart(capture_params, client_.PassAs<Client>());
WaitForCapturedFrame();
EXPECT_EQ(last_format().frame_size.width(), 640);
......@@ -177,7 +176,8 @@ TEST_F(FakeVideoCaptureDeviceTest, DISABLED_CaptureVariableResolution) {
capture_params.requested_format.frame_size.SetSize(640, 480);
capture_params.requested_format.frame_rate = 30;
capture_params.requested_format.pixel_format = PIXEL_FORMAT_I420;
capture_params.allow_resolution_change = true;
capture_params.resolution_change_policy =
RESOLUTION_POLICY_DYNAMIC_WITHIN_LIMIT;
ASSERT_GT(static_cast<int>(names->size()), 0);
......
......@@ -232,7 +232,6 @@ TEST_F(VideoCaptureDeviceTest, OpenInvalidDevice) {
capture_params.requested_format.frame_size.SetSize(640, 480);
capture_params.requested_format.frame_rate = 30;
capture_params.requested_format.pixel_format = PIXEL_FORMAT_I420;
capture_params.allow_resolution_change = false;
device->AllocateAndStart(capture_params, client_.PassAs<Client>());
device->StopAndDeAllocate();
}
......@@ -258,7 +257,6 @@ TEST_F(VideoCaptureDeviceTest, CaptureVGA) {
capture_params.requested_format.frame_size.SetSize(640, 480);
capture_params.requested_format.frame_rate = 30;
capture_params.requested_format.pixel_format = PIXEL_FORMAT_I420;
capture_params.allow_resolution_change = false;
device->AllocateAndStart(capture_params, client_.PassAs<Client>());
// Get captured video frames.
WaitForCapturedFrame();
......@@ -285,7 +283,6 @@ TEST_F(VideoCaptureDeviceTest, Capture720p) {
capture_params.requested_format.frame_size.SetSize(1280, 720);
capture_params.requested_format.frame_rate = 30;
capture_params.requested_format.pixel_format = PIXEL_FORMAT_I420;
capture_params.allow_resolution_change = false;
device->AllocateAndStart(capture_params, client_.PassAs<Client>());
// Get captured video frames.
WaitForCapturedFrame();
......@@ -309,7 +306,6 @@ TEST_F(VideoCaptureDeviceTest, MAYBE_AllocateBadSize) {
capture_params.requested_format.frame_size.SetSize(637, 472);
capture_params.requested_format.frame_rate = 35;
capture_params.requested_format.pixel_format = PIXEL_FORMAT_I420;
capture_params.allow_resolution_change = false;
device->AllocateAndStart(capture_params, client_.PassAs<Client>());
WaitForCapturedFrame();
device->StopAndDeAllocate();
......@@ -339,7 +335,6 @@ TEST_F(VideoCaptureDeviceTest, ReAllocateCamera) {
capture_params.requested_format.frame_size = resolution;
capture_params.requested_format.frame_rate = 30;
capture_params.requested_format.pixel_format = PIXEL_FORMAT_I420;
capture_params.allow_resolution_change = false;
device->AllocateAndStart(capture_params, client_.PassAs<Client>());
device->StopAndDeAllocate();
}
......@@ -349,7 +344,6 @@ TEST_F(VideoCaptureDeviceTest, ReAllocateCamera) {
capture_params.requested_format.frame_size.SetSize(320, 240);
capture_params.requested_format.frame_rate = 30;
capture_params.requested_format.pixel_format = PIXEL_FORMAT_I420;
capture_params.allow_resolution_change = false;
ResetWithNewClient();
scoped_ptr<VideoCaptureDevice> device(
......@@ -380,7 +374,6 @@ TEST_F(VideoCaptureDeviceTest, DeAllocateCameraWhileRunning) {
capture_params.requested_format.frame_size.SetSize(640, 480);
capture_params.requested_format.frame_rate = 30;
capture_params.requested_format.pixel_format = PIXEL_FORMAT_I420;
capture_params.allow_resolution_change = false;
device->AllocateAndStart(capture_params, client_.PassAs<Client>());
// Get captured video frames.
WaitForCapturedFrame();
......@@ -409,7 +402,6 @@ TEST_F(VideoCaptureDeviceTest, MAYBE_CaptureMjpeg) {
capture_params.requested_format.frame_size.SetSize(1280, 720);
capture_params.requested_format.frame_rate = 30;
capture_params.requested_format.pixel_format = PIXEL_FORMAT_MJPEG;
capture_params.allow_resolution_change = false;
device->AllocateAndStart(capture_params, client_.PassAs<Client>());
// Get captured video frames.
WaitForCapturedFrame();
......
......@@ -67,6 +67,6 @@ std::string VideoCaptureFormat::PixelFormatToString(VideoPixelFormat format) {
return "";
}
VideoCaptureParams::VideoCaptureParams() : allow_resolution_change(false) {}
VideoCaptureParams::VideoCaptureParams()
: resolution_change_policy(RESOLUTION_POLICY_FIXED) {}
} // namespace media
......@@ -31,6 +31,23 @@ enum VideoPixelFormat {
PIXEL_FORMAT_MAX,
};
// Policies for capture devices that has source content with dynamic resolution.
enum ResolutionChangePolicy {
// Capture device outputs a fixed resolution all the time. The resolution of
// the first frame is the resolution for all frames.
// It is implementation specific for the capture device to scale, letter-box
// and pillar-box. The only gurantee is that resolution will never change.
RESOLUTION_POLICY_FIXED,
// Capture device outputs frames with dynamic resolution. The width and height
// will not exceed the maximum dimensions specified. The typical scenario is
// the frames will have the same aspect ratio as the original content and
// scaled down to fit inside the limit.
RESOLUTION_POLICY_DYNAMIC_WITHIN_LIMIT,
RESOLUTION_POLICY_LAST,
};
// Some drivers use rational time per frame instead of float frame rate, this
// constant k is used to convert between both: A fps -> [k/k*A] seconds/frame.
const int kFrameRatePrecision = 10000;
......@@ -71,8 +88,8 @@ class MEDIA_EXPORT VideoCaptureParams {
// Requests a resolution and format at which the capture will occur.
VideoCaptureFormat requested_format;
// Allow mid-capture resolution change.
bool allow_resolution_change;
// Policy for resolution change.
ResolutionChangePolicy resolution_change_policy;
};
} // namespace media
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment