summaryrefslogtreecommitdiffstats
path: root/content/browser
diff options
context:
space:
mode:
Diffstat (limited to 'content/browser')
-rw-r--r--content/browser/renderer_host/media/video_capture_controller.cc92
-rw-r--r--content/browser/renderer_host/media/video_capture_controller.h8
-rw-r--r--content/browser/renderer_host/media/video_capture_manager_unittest.cc5
-rw-r--r--content/browser/renderer_host/media/web_contents_video_capture_device.cc16
-rw-r--r--content/browser/renderer_host/media/web_contents_video_capture_device_unittest.cc9
5 files changed, 97 insertions, 33 deletions
diff --git a/content/browser/renderer_host/media/video_capture_controller.cc b/content/browser/renderer_host/media/video_capture_controller.cc
index b503293..fc18af4 100644
--- a/content/browser/renderer_host/media/video_capture_controller.cc
+++ b/content/browser/renderer_host/media/video_capture_controller.cc
@@ -20,6 +20,39 @@
#include "third_party/libyuv/include/libyuv.h"
#endif
+namespace {
+
+void ResetBufferYV12(uint8* buffer, int width, int height) {
+ int y_size = width * height;
+ memset(buffer, 0, y_size);
+ buffer += y_size;
+ memset(buffer, 128, y_size / 2);
+}
+
+// TODO(wjia): Support stride.
+void RotatePackedYV12Frame(
+ const uint8* src,
+ uint8* dest_yplane,
+ uint8* dest_uplane,
+ uint8* dest_vplane,
+ int width,
+ int height,
+ int rotation,
+ bool flip_vert,
+ bool flip_horiz) {
+ media::RotatePlaneByPixels(
+ src, dest_yplane, width, height, rotation, flip_vert, flip_horiz);
+ int y_size = width * height;
+ src += y_size;
+ media::RotatePlaneByPixels(
+ src, dest_uplane, width/2, height/2, rotation, flip_vert, flip_horiz);
+ src += y_size/4;
+ media::RotatePlaneByPixels(
+ src, dest_vplane, width/2, height/2, rotation, flip_vert, flip_horiz);
+}
+
+} // namespace
+
namespace content {
// The number of DIBs VideoCaptureController allocate.
@@ -58,6 +91,7 @@ struct VideoCaptureController::ControllerClient {
struct VideoCaptureController::SharedDIB {
SharedDIB(base::SharedMemory* ptr)
: shared_memory(ptr),
+ rotation(0),
references(0) {
}
@@ -66,6 +100,8 @@ struct VideoCaptureController::SharedDIB {
// The memory created to be shared with renderer processes.
scoped_ptr<base::SharedMemory> shared_memory;
+ int rotation;
+
// Number of renderer processes which hold this shared memory.
// renderer process is represented by VidoeCaptureHost.
int references;
@@ -250,7 +286,8 @@ void VideoCaptureController::ReturnBuffer(
bool VideoCaptureController::ReserveSharedMemory(int* buffer_id_out,
uint8** yplane,
uint8** uplane,
- uint8** vplane) {
+ uint8** vplane,
+ int rotation) {
int buffer_id = 0;
base::SharedMemory* dib = NULL;
{
@@ -263,6 +300,11 @@ bool VideoCaptureController::ReserveSharedMemory(int* buffer_id_out,
// renderer side.
dib_it->second->references = -1;
dib = dib_it->second->shared_memory.get();
+ if (rotation != dib_it->second->rotation) {
+ ResetBufferYV12(static_cast<uint8*>(dib->memory()),
+ frame_info_.width, frame_info_.height);
+ dib_it->second->rotation = rotation;
+ }
break;
}
}
@@ -284,42 +326,46 @@ bool VideoCaptureController::ReserveSharedMemory(int* buffer_id_out,
// Implements VideoCaptureDevice::EventHandler.
// OnIncomingCapturedFrame is called the thread running the capture device.
// I.e.- DirectShow thread on windows and v4l2_thread on Linux.
-void VideoCaptureController::OnIncomingCapturedFrame(const uint8* data,
- int length,
- base::Time timestamp) {
+void VideoCaptureController::OnIncomingCapturedFrame(
+ const uint8* data,
+ int length,
+ base::Time timestamp,
+ int rotation,
+ bool flip_vert,
+ bool flip_horiz) {
+ DCHECK (frame_info_.color == media::VideoCaptureCapability::kI420 ||
+ frame_info_.color == media::VideoCaptureCapability::kYV12 ||
+ (rotation == 0 && !flip_vert && !flip_horiz));
+
int buffer_id = 0;
uint8* yplane = NULL;
uint8* uplane = NULL;
uint8* vplane = NULL;
- if (!ReserveSharedMemory(&buffer_id, &yplane, &uplane, &vplane))
+ if (!ReserveSharedMemory(&buffer_id, &yplane, &uplane, &vplane, rotation))
return;
// Do color conversion from the camera format to I420.
switch (frame_info_.color) {
case media::VideoCaptureCapability::kColorUnknown: // Color format not set.
break;
- case media::VideoCaptureCapability::kI420: {
+ case media::VideoCaptureCapability::kI420:
DCHECK(!chopped_width_ && !chopped_height_);
- memcpy(yplane, data, (frame_info_.width * frame_info_.height * 3) / 2);
+ RotatePackedYV12Frame(
+ data, yplane, uplane, vplane, frame_info_.width, frame_info_.height,
+ rotation, flip_vert, flip_horiz);
break;
- }
- case media::VideoCaptureCapability::kYV12: {
+ case media::VideoCaptureCapability::kYV12:
DCHECK(!chopped_width_ && !chopped_height_);
- const uint8* ptr = data;
- memcpy(yplane, ptr, (frame_info_.width * frame_info_.height));
- ptr += frame_info_.width * frame_info_.height;
- memcpy(vplane, ptr, (frame_info_.width * frame_info_.height) >> 2);
- ptr += (frame_info_.width * frame_info_.height) >> 2;
- memcpy(uplane, ptr, (frame_info_.width * frame_info_.height) >> 2);
+ RotatePackedYV12Frame(
+ data, yplane, vplane, uplane, frame_info_.width, frame_info_.height,
+ rotation, flip_vert, flip_horiz);
break;
- }
- case media::VideoCaptureCapability::kNV21: {
+ case media::VideoCaptureCapability::kNV21:
DCHECK(!chopped_width_ && !chopped_height_);
media::ConvertNV21ToYUV(data, yplane, uplane, vplane, frame_info_.width,
frame_info_.height);
break;
- }
- case media::VideoCaptureCapability::kYUY2: {
+ case media::VideoCaptureCapability::kYUY2:
DCHECK(!chopped_width_ && !chopped_height_);
if (frame_info_.width * frame_info_.height * 2 != length) {
// If |length| of |data| does not match the expected width and height
@@ -330,7 +376,6 @@ void VideoCaptureController::OnIncomingCapturedFrame(const uint8* data,
media::ConvertYUY2ToYUV(data, yplane, uplane, vplane, frame_info_.width,
frame_info_.height);
break;
- }
case media::VideoCaptureCapability::kRGB24: {
int ystride = frame_info_.width;
int uvstride = frame_info_.width / 2;
@@ -347,13 +392,12 @@ void VideoCaptureController::OnIncomingCapturedFrame(const uint8* data,
rgb_stride, ystride, uvstride);
break;
}
- case media::VideoCaptureCapability::kARGB: {
+ case media::VideoCaptureCapability::kARGB:
media::ConvertRGB32ToYUV(data, yplane, uplane, vplane, frame_info_.width,
frame_info_.height,
(frame_info_.width + chopped_width_) * 4,
frame_info_.width, frame_info_.width / 2);
break;
- }
#if !defined(OS_IOS) && !defined(OS_ANDROID)
case media::VideoCaptureCapability::kMJPEG: {
int yplane_stride = frame_info_.width;
@@ -398,7 +442,7 @@ void VideoCaptureController::OnIncomingCapturedVideoFrame(
uint8* yplane = NULL;
uint8* uplane = NULL;
uint8* vplane = NULL;
- if (!ReserveSharedMemory(&buffer_id, &yplane, &uplane, &vplane))
+ if (!ReserveSharedMemory(&buffer_id, &yplane, &uplane, &vplane, 0))
return;
scoped_refptr<media::VideoFrame> target_as_frame(
@@ -553,6 +597,8 @@ void VideoCaptureController::DoFrameInfoOnIOThread() {
frames_created = false;
break;
}
+ ResetBufferYV12(static_cast<uint8*>(shared_memory->memory()),
+ frame_info_.width, frame_info_.height);
SharedDIB* dib = new SharedDIB(shared_memory.release());
owned_dibs_.insert(std::make_pair(i, dib));
}
diff --git a/content/browser/renderer_host/media/video_capture_controller.h b/content/browser/renderer_host/media/video_capture_controller.h
index 3f7594a..b220c16 100644
--- a/content/browser/renderer_host/media/video_capture_controller.h
+++ b/content/browser/renderer_host/media/video_capture_controller.h
@@ -67,7 +67,10 @@ class CONTENT_EXPORT VideoCaptureController
// Implement media::VideoCaptureDevice::EventHandler.
virtual void OnIncomingCapturedFrame(const uint8* data,
int length,
- base::Time timestamp) OVERRIDE;
+ base::Time timestamp,
+ int rotation,
+ bool flip_vert,
+ bool flip_horiz) OVERRIDE;
virtual void OnIncomingCapturedVideoFrame(media::VideoFrame* frame,
base::Time timestamp) OVERRIDE;
virtual void OnError() OVERRIDE;
@@ -119,7 +122,8 @@ class CONTENT_EXPORT VideoCaptureController
bool ReserveSharedMemory(int* buffer_id_out,
uint8** yplane,
uint8** uplane,
- uint8** vplane);
+ uint8** vplane,
+ int rotation);
// Lock to protect free_dibs_ and owned_dibs_.
base::Lock lock_;
diff --git a/content/browser/renderer_host/media/video_capture_manager_unittest.cc b/content/browser/renderer_host/media/video_capture_manager_unittest.cc
index 1901cfc..917df1e 100644
--- a/content/browser/renderer_host/media/video_capture_manager_unittest.cc
+++ b/content/browser/renderer_host/media/video_capture_manager_unittest.cc
@@ -49,7 +49,10 @@ class MockFrameObserver : public media::VideoCaptureDevice::EventHandler {
const media::VideoCaptureCapability& info) OVERRIDE {}
virtual void OnIncomingCapturedFrame(const uint8* data,
int length,
- base::Time timestamp) OVERRIDE {}
+ base::Time timestamp,
+ int rotation,
+ bool flip_vert,
+ bool flip_horiz) OVERRIDE {}
virtual void OnIncomingCapturedVideoFrame(media::VideoFrame* frame,
base::Time timestamp) OVERRIDE {}
};
diff --git a/content/browser/renderer_host/media/web_contents_video_capture_device.cc b/content/browser/renderer_host/media/web_contents_video_capture_device.cc
index e478c93..bddc311 100644
--- a/content/browser/renderer_host/media/web_contents_video_capture_device.cc
+++ b/content/browser/renderer_host/media/web_contents_video_capture_device.cc
@@ -252,8 +252,12 @@ class SynchronizedConsumer {
void OnFrameInfo(const media::VideoCaptureCapability& info);
void OnError();
- void OnIncomingCapturedFrame(const uint8* pixels, int size,
- const base::Time& timestamp);
+ void OnIncomingCapturedFrame(const uint8* pixels,
+ int size,
+ const base::Time& timestamp,
+ int rotation,
+ bool flip_vert,
+ bool flip_horiz);
void OnIncomingCapturedVideoFrame(
const scoped_refptr<media::VideoFrame>& video_frame,
const base::Time& timestamp);
@@ -524,10 +528,12 @@ void SynchronizedConsumer::OnError() {
}
void SynchronizedConsumer::OnIncomingCapturedFrame(
- const uint8* pixels, int size, const base::Time& timestamp) {
+ const uint8* pixels, int size, const base::Time& timestamp,
+ int rotation, bool flip_vert, bool flip_horiz) {
base::AutoLock guard(consumer_lock_);
if (wrapped_consumer_) {
- wrapped_consumer_->OnIncomingCapturedFrame(pixels, size, timestamp);
+ wrapped_consumer_->OnIncomingCapturedFrame(pixels, size, timestamp,
+ rotation, flip_vert, flip_horiz);
}
}
@@ -586,7 +592,7 @@ void VideoFrameDeliverer::DeliverOnDeliverThread(
consumer_->OnIncomingCapturedFrame(
static_cast<const uint8*>(frame_buffer.getPixels()),
frame_buffer.getSize(),
- frame_timestamp);
+ frame_timestamp, 0, false, false);
ChronicleFrameDelivery(frame_number);
diff --git a/content/browser/renderer_host/media/web_contents_video_capture_device_unittest.cc b/content/browser/renderer_host/media/web_contents_video_capture_device_unittest.cc
index 6d74199..2abc251 100644
--- a/content/browser/renderer_host/media/web_contents_video_capture_device_unittest.cc
+++ b/content/browser/renderer_host/media/web_contents_video_capture_device_unittest.cc
@@ -296,8 +296,13 @@ class StubConsumer : public media::VideoCaptureDevice::EventHandler {
}
}
- virtual void OnIncomingCapturedFrame(const uint8* data, int length,
- base::Time timestamp) OVERRIDE {
+ virtual void OnIncomingCapturedFrame(
+ const uint8* data,
+ int length,
+ base::Time timestamp,
+ int rotation,
+ bool flip_vert,
+ bool flip_horiz) OVERRIDE {
DCHECK(data);
static const int kNumPixels = kTestWidth * kTestHeight;
EXPECT_EQ(kNumPixels * kBytesPerPixel, length);