Add IncomingFrameI420 to ViEExternalCapture interface to take captured video frame buffer as 3 planes.
Review URL: http://webrtc-codereview.appspot.com/219004
git-svn-id: http://webrtc.googlecode.com/svn/trunk@753 4adac7df-926f-26a2-2b94-8c16560cd09d
diff --git a/src/modules/video_capture/main/source/video_capture_impl.cc b/src/modules/video_capture/main/source/video_capture_impl.cc
index c7690bb..ba4f994 100644
--- a/src/modules/video_capture/main/source/video_capture_impl.cc
+++ b/src/modules/video_capture/main/source/video_capture_impl.cc
@@ -253,6 +253,40 @@
CriticalSectionScoped cs(_apiCs);
return _setCaptureDelay;
}
+
+WebRtc_Word32 VideoCaptureImpl::DeliverCapturedFrame(VideoFrame& captureFrame,
+ WebRtc_Word32 width, WebRtc_Word32 height, WebRtc_Word64 capture_time,
+ VideoCodecType codec_type) {
+ UpdateFrameCount();// frame count used for local frame rate callback.
+ _startImageFrameIntervall = 0; // prevent the start image to be displayed.
+
+ const bool callOnCaptureDelayChanged = _setCaptureDelay != _captureDelay;
+ // Capture delay changed
+ if (_setCaptureDelay != _captureDelay) {
+ _setCaptureDelay = _captureDelay;
+ }
+
+ // Set the capture time
+ if (capture_time != 0) {
+ captureFrame.SetRenderTime(capture_time);
+ }
+ else {
+ captureFrame.SetRenderTime(TickTime::MillisecondTimestamp());
+ }
+
+ captureFrame.SetHeight(height);
+ captureFrame.SetWidth(width);
+
+ if (_dataCallBack) {
+ if (callOnCaptureDelayChanged) {
+ _dataCallBack->OnCaptureDelayChanged(_id, _captureDelay);
+ }
+ _dataCallBack->OnIncomingCapturedFrame(_id, captureFrame, codec_type);
+ }
+
+ return 0;
+}
+
WebRtc_Word32 VideoCaptureImpl::IncomingFrame(WebRtc_UWord8* videoFrame,
WebRtc_Word32 videoFrameLength,
const VideoCaptureCapability& frameInfo,
@@ -269,10 +303,6 @@
const WebRtc_Word32 width = frameInfo.width;
const WebRtc_Word32 height = frameInfo.height;
- UpdateFrameCount();// frame count used for local frame rate callback.
-
- _startImageFrameIntervall = 0; // prevent the start image to be displayed.
-
if (frameInfo.codecType == kVideoCodecUnknown) // None encoded. Convert to I420.
{
const VideoType vpLibType = videocapturemodule::
@@ -318,33 +348,8 @@
}
}
- const bool callOnCaptureDelayChanged = _setCaptureDelay != _captureDelay;
- if (_setCaptureDelay != _captureDelay) // Capture delay changed
- {
- _setCaptureDelay = _captureDelay;
- }
+ DeliverCapturedFrame(_captureFrame, width, height, captureTime, frameInfo.codecType);
- // Set the capture time
- if (captureTime != 0)
- {
- _captureFrame.SetRenderTime(captureTime);
- }
- else
- {
- _captureFrame.SetRenderTime(TickTime::MillisecondTimestamp());
- }
-
- _captureFrame.SetHeight(height);
- _captureFrame.SetWidth(width);
-
- if (_dataCallBack)
- {
- if (callOnCaptureDelayChanged)
- {
- _dataCallBack->OnCaptureDelayChanged(_id, _captureDelay);
- }
- _dataCallBack->OnIncomingCapturedFrame(_id, _captureFrame, frameInfo.codecType);
- }
const WebRtc_UWord32 processTime =
(WebRtc_UWord32)(TickTime::Now() - startProcessTime).Milliseconds();
@@ -356,7 +361,60 @@
}
return 0;
+}
+WebRtc_Word32 VideoCaptureImpl::IncomingFrameI420(
+ const VideoFrameI420& video_frame, WebRtc_Word64 captureTime) {
+
+ CriticalSectionScoped cs(_callBackCs);
+
+ // Allocate I420 buffer
+ int frame_size = CalcBufferSize(kI420,
+ video_frame.width,
+ video_frame.height);
+ _captureFrame.VerifyAndAllocate(frame_size);
+ if (!_captureFrame.Buffer()) {
+ WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceVideoCapture, _id,
+ "Failed to allocate frame buffer.");
+ return -1;
+ }
+
+ // Copy planes to the _captureFrame
+ int y_width = video_frame.width;
+ int uv_width = video_frame.width / 2;
+ int y_rows = video_frame.height;
+ int uv_rows = video_frame.height / 2; // I420
+ unsigned char* current_pointer = _captureFrame.Buffer();
+ unsigned char* y_plane = video_frame.y_plane;
+ unsigned char* u_plane = video_frame.u_plane;
+ unsigned char* v_plane = video_frame.v_plane;
+ // Copy Y
+ for (int i = 0; i < y_rows; ++i) {
+ memcpy(current_pointer, y_plane, y_width);
+ current_pointer += video_frame.y_pitch;
+ y_plane += video_frame.y_pitch;
+ }
+ // Copy U
+ for (int i = 0; i < uv_rows; ++i) {
+ memcpy(current_pointer, u_plane, uv_width);
+ current_pointer += video_frame.u_pitch;
+ u_plane += video_frame.u_pitch;
+ }
+ // Copy V
+ for (int i = 0; i < uv_rows; ++i) {
+ memcpy(current_pointer, v_plane, uv_width);
+ current_pointer += video_frame.v_pitch;
+ v_plane += video_frame.v_pitch;
+ }
+ _captureFrame.SetLength(frame_size);
+
+ DeliverCapturedFrame(_captureFrame,
+ video_frame.width,
+ video_frame.height,
+ captureTime,
+ kVideoCodecUnknown);
+
+ return 0;
}
WebRtc_Word32 VideoCaptureImpl::SetCaptureRotation(VideoCaptureRotation rotation)