Commit 79288ba0 authored by emircan's avatar emircan Committed by Commit bot

Refactored pixel format resize operations in media/video/capture into a...

Refactored pixel format resize operations in  media/video/capture into a function called VideoCaptureFormat::GetSizeForVideoPixelFormat().

BUG=

TEST=VideoCaptureDeviceTest.* in media_unittests pass.

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

Cr-Commit-Position: refs/heads/master@{#315175}
parent f43ab9ce
...@@ -469,6 +469,10 @@ void VideoCaptureController::VideoCaptureDeviceClient::OnIncomingCapturedData( ...@@ -469,6 +469,10 @@ void VideoCaptureController::VideoCaptureDeviceClient::OnIncomingCapturedData(
NOTREACHED(); NOTREACHED();
} }
// The input |length| can be greater than the required buffer size because of
// paddings and/or alignments, but it cannot be less.
DCHECK_GE(static_cast<size_t>(length), frame_format.ImageAllocationSize());
if (libyuv::ConvertToI420(data, if (libyuv::ConvertToI420(data,
length, length,
yplane, yplane,
......
...@@ -10,6 +10,7 @@ ...@@ -10,6 +10,7 @@
#include "base/memory/scoped_ptr.h" #include "base/memory/scoped_ptr.h"
#include "base/strings/string_number_conversions.h" #include "base/strings/string_number_conversions.h"
#include "base/strings/string_piece.h" #include "base/strings/string_piece.h"
#include "media/video/capture/video_capture_types.h"
namespace media { namespace media {
static const int kY4MHeaderMaxSize = 200; static const int kY4MHeaderMaxSize = 200;
...@@ -169,10 +170,10 @@ void FileVideoCaptureDevice::StopAndDeAllocate() { ...@@ -169,10 +170,10 @@ void FileVideoCaptureDevice::StopAndDeAllocate() {
capture_thread_.Stop(); capture_thread_.Stop();
} }
int FileVideoCaptureDevice::CalculateFrameSize() { int FileVideoCaptureDevice::CalculateFrameSize() const {
DCHECK_EQ(capture_format_.pixel_format, PIXEL_FORMAT_I420); DCHECK_EQ(capture_format_.pixel_format, PIXEL_FORMAT_I420);
DCHECK_EQ(capture_thread_.message_loop(), base::MessageLoop::current()); DCHECK_EQ(capture_thread_.message_loop(), base::MessageLoop::current());
return capture_format_.frame_size.GetArea() * 12 / 8; return capture_format_.ImageAllocationSize();
} }
void FileVideoCaptureDevice::OnAllocateAndStart( void FileVideoCaptureDevice::OnAllocateAndStart(
......
...@@ -43,7 +43,7 @@ class MEDIA_EXPORT FileVideoCaptureDevice : public VideoCaptureDevice { ...@@ -43,7 +43,7 @@ class MEDIA_EXPORT FileVideoCaptureDevice : public VideoCaptureDevice {
private: private:
// Returns size in bytes of an I420 frame, not including possible paddings, // Returns size in bytes of an I420 frame, not including possible paddings,
// defined by |capture_format_|. // defined by |capture_format_|.
int CalculateFrameSize(); int CalculateFrameSize() const;
// Called on the |capture_thread_|. // Called on the |capture_thread_|.
void OnAllocateAndStart(const VideoCaptureParams& params, void OnAllocateAndStart(const VideoCaptureParams& params,
......
...@@ -269,6 +269,8 @@ TEST_F(VideoCaptureDeviceTest, CaptureVGA) { ...@@ -269,6 +269,8 @@ TEST_F(VideoCaptureDeviceTest, CaptureVGA) {
WaitForCapturedFrame(); WaitForCapturedFrame();
EXPECT_EQ(last_format().frame_size.width(), 640); EXPECT_EQ(last_format().frame_size.width(), 640);
EXPECT_EQ(last_format().frame_size.height(), 480); EXPECT_EQ(last_format().frame_size.height(), 480);
EXPECT_EQ(static_cast<size_t>(640 * 480 * 3 / 2),
last_format().ImageAllocationSize());
device->StopAndDeAllocate(); device->StopAndDeAllocate();
} }
...@@ -293,6 +295,10 @@ TEST_F(VideoCaptureDeviceTest, Capture720p) { ...@@ -293,6 +295,10 @@ TEST_F(VideoCaptureDeviceTest, Capture720p) {
device->AllocateAndStart(capture_params, client_.Pass()); device->AllocateAndStart(capture_params, client_.Pass());
// Get captured video frames. // Get captured video frames.
WaitForCapturedFrame(); WaitForCapturedFrame();
EXPECT_EQ(last_format().frame_size.width(), 1280);
EXPECT_EQ(last_format().frame_size.height(), 720);
EXPECT_EQ(static_cast<size_t>(1280 * 720 * 3 / 2),
last_format().ImageAllocationSize());
device->StopAndDeAllocate(); device->StopAndDeAllocate();
} }
...@@ -318,6 +324,8 @@ TEST_F(VideoCaptureDeviceTest, MAYBE_AllocateBadSize) { ...@@ -318,6 +324,8 @@ TEST_F(VideoCaptureDeviceTest, MAYBE_AllocateBadSize) {
device->StopAndDeAllocate(); device->StopAndDeAllocate();
EXPECT_EQ(last_format().frame_size.width(), 640); EXPECT_EQ(last_format().frame_size.width(), 640);
EXPECT_EQ(last_format().frame_size.height(), 480); EXPECT_EQ(last_format().frame_size.height(), 480);
EXPECT_EQ(static_cast<size_t>(640 * 480 * 3 / 2),
last_format().ImageAllocationSize());
} }
// Cause hangs on Windows Debug. http://crbug.com/417824 // Cause hangs on Windows Debug. http://crbug.com/417824
...@@ -422,6 +430,8 @@ TEST_F(VideoCaptureDeviceTest, MAYBE_CaptureMjpeg) { ...@@ -422,6 +430,8 @@ TEST_F(VideoCaptureDeviceTest, MAYBE_CaptureMjpeg) {
// Verify we get MJPEG from the device. Not all devices can capture 1280x720 // Verify we get MJPEG from the device. Not all devices can capture 1280x720
// @ 30 fps, so we don't care about the exact resolution we get. // @ 30 fps, so we don't care about the exact resolution we get.
EXPECT_EQ(last_format().pixel_format, PIXEL_FORMAT_MJPEG); EXPECT_EQ(last_format().pixel_format, PIXEL_FORMAT_MJPEG);
EXPECT_GE(static_cast<size_t>(1280 * 720),
last_format().ImageAllocationSize());
device->StopAndDeAllocate(); device->StopAndDeAllocate();
} }
......
...@@ -31,6 +31,36 @@ bool VideoCaptureFormat::IsValid() const { ...@@ -31,6 +31,36 @@ bool VideoCaptureFormat::IsValid() const {
(pixel_format < PIXEL_FORMAT_MAX); (pixel_format < PIXEL_FORMAT_MAX);
} }
size_t VideoCaptureFormat::ImageAllocationSize() const {
size_t result_frame_size = frame_size.GetArea();
switch (pixel_format) {
case PIXEL_FORMAT_I420:
case PIXEL_FORMAT_YV12:
case PIXEL_FORMAT_NV12:
case PIXEL_FORMAT_NV21:
result_frame_size = result_frame_size * 3 / 2;
break;
case PIXEL_FORMAT_UYVY:
case PIXEL_FORMAT_YUY2:
result_frame_size *= 2;
break;
case PIXEL_FORMAT_RGB24:
result_frame_size *= 3;
break;
case PIXEL_FORMAT_ARGB:
result_frame_size *= 4;
break;
case PIXEL_FORMAT_MJPEG:
case PIXEL_FORMAT_TEXTURE:
result_frame_size = 0;
break;
default: // Sizes for the rest of the formats are unknown.
NOTREACHED() << "Unknown pixel format provided.";
break;
}
return result_frame_size;
}
std::string VideoCaptureFormat::ToString() const { std::string VideoCaptureFormat::ToString() const {
return base::StringPrintf("resolution: %s, fps: %.3f, pixel format: %s", return base::StringPrintf("resolution: %s, fps: %.3f, pixel format: %s",
frame_size.ToString().c_str(), frame_size.ToString().c_str(),
......
...@@ -67,6 +67,10 @@ class MEDIA_EXPORT VideoCaptureFormat { ...@@ -67,6 +67,10 @@ class MEDIA_EXPORT VideoCaptureFormat {
std::string ToString() const; std::string ToString() const;
static std::string PixelFormatToString(VideoPixelFormat format); static std::string PixelFormatToString(VideoPixelFormat format);
// Returns the required buffer size to hold an image of a given
// VideoCaptureFormat with no padding and tightly packed.
size_t ImageAllocationSize() const;
// Checks that all values are in the expected range. All limits are specified // Checks that all values are in the expected range. All limits are specified
// in media::Limits. // in media::Limits.
bool IsValid() const; bool IsValid() const;
......
...@@ -69,8 +69,7 @@ bool SinkInputPin::GetValidMediaType(int index, AM_MEDIA_TYPE* media_type) { ...@@ -69,8 +69,7 @@ bool SinkInputPin::GetValidMediaType(int index, AM_MEDIA_TYPE* media_type) {
pvi->bmiHeader.biBitCount = 12; // bit per pixel pvi->bmiHeader.biBitCount = 12; // bit per pixel
pvi->bmiHeader.biWidth = requested_format_.frame_size.width(); pvi->bmiHeader.biWidth = requested_format_.frame_size.width();
pvi->bmiHeader.biHeight = requested_format_.frame_size.height(); pvi->bmiHeader.biHeight = requested_format_.frame_size.height();
pvi->bmiHeader.biSizeImage = pvi->bmiHeader.biSizeImage = requested_format_.ImageAllocationSize();
requested_format_.frame_size.GetArea() * 3 / 2;
media_type->subtype = kMediaSubTypeI420; media_type->subtype = kMediaSubTypeI420;
break; break;
} }
...@@ -79,7 +78,7 @@ bool SinkInputPin::GetValidMediaType(int index, AM_MEDIA_TYPE* media_type) { ...@@ -79,7 +78,7 @@ bool SinkInputPin::GetValidMediaType(int index, AM_MEDIA_TYPE* media_type) {
pvi->bmiHeader.biBitCount = 16; pvi->bmiHeader.biBitCount = 16;
pvi->bmiHeader.biWidth = requested_format_.frame_size.width(); pvi->bmiHeader.biWidth = requested_format_.frame_size.width();
pvi->bmiHeader.biHeight = requested_format_.frame_size.height(); pvi->bmiHeader.biHeight = requested_format_.frame_size.height();
pvi->bmiHeader.biSizeImage = requested_format_.frame_size.GetArea() * 2; pvi->bmiHeader.biSizeImage = requested_format_.ImageAllocationSize();
media_type->subtype = MEDIASUBTYPE_YUY2; media_type->subtype = MEDIASUBTYPE_YUY2;
break; break;
} }
...@@ -88,7 +87,7 @@ bool SinkInputPin::GetValidMediaType(int index, AM_MEDIA_TYPE* media_type) { ...@@ -88,7 +87,7 @@ bool SinkInputPin::GetValidMediaType(int index, AM_MEDIA_TYPE* media_type) {
pvi->bmiHeader.biBitCount = 24; pvi->bmiHeader.biBitCount = 24;
pvi->bmiHeader.biWidth = requested_format_.frame_size.width(); pvi->bmiHeader.biWidth = requested_format_.frame_size.width();
pvi->bmiHeader.biHeight = requested_format_.frame_size.height(); pvi->bmiHeader.biHeight = requested_format_.frame_size.height();
pvi->bmiHeader.biSizeImage = requested_format_.frame_size.GetArea() * 3; pvi->bmiHeader.biSizeImage = requested_format_.ImageAllocationSize();
media_type->subtype = MEDIASUBTYPE_RGB24; media_type->subtype = MEDIASUBTYPE_RGB24;
break; break;
} }
......
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