summaryrefslogtreecommitdiffstats
path: root/content/browser/renderer_host/media/video_capture_controller.cc
diff options
context:
space:
mode:
Diffstat (limited to 'content/browser/renderer_host/media/video_capture_controller.cc')
-rw-r--r--content/browser/renderer_host/media/video_capture_controller.cc92
1 files changed, 69 insertions, 23 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));
}