diff options
Diffstat (limited to 'content/browser/renderer_host/media/video_capture_controller.cc')
-rw-r--r-- | content/browser/renderer_host/media/video_capture_controller.cc | 92 |
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)); } |