From f10ea31211c836d78382c7d9bd613704182a76d1 Mon Sep 17 00:00:00 2001 From: "wu@webrtc.org" Date: Fri, 14 Oct 2011 17:16:04 +0000 Subject: [PATCH] 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 --- .../main/interface/video_capture_defines.h | 29 +++++ .../main/source/video_capture_impl.cc | 118 +++++++++++++----- .../main/source/video_capture_impl.h | 7 ++ .../main/test/testAPI/Logger.cpp | 2 +- .../main/test/testAPI/Renderer.cpp | 1 + .../main/test/testAPI/testCameraEncoder.cpp | 13 +- .../main/test/testAPI/testCameraEncoder.h | 2 +- .../main/test/testAPI/testExternalCapture.cpp | 18 ++- .../main/test/testAPI/testExternalCapture.h | 2 +- .../test/testAPI/testPlatformDependent.cpp | 31 +++-- .../main/test/testAPI/testPlatformDependent.h | 2 +- src/video_engine/main/interface/vie_capture.h | 31 +++++ src/video_engine/main/source/vie_capturer.cc | 28 +++++ src/video_engine/main/source/vie_capturer.h | 7 +- 14 files changed, 237 insertions(+), 54 deletions(-) diff --git a/src/modules/video_capture/main/interface/video_capture_defines.h b/src/modules/video_capture/main/interface/video_capture_defines.h index e5582536f..2a3408be9 100644 --- a/src/modules/video_capture/main/interface/video_capture_defines.h +++ b/src/modules/video_capture/main/interface/video_capture_defines.h @@ -84,6 +84,33 @@ enum VideoCaptureAlarm Cleared = 1 }; +// VideoFrameI420 doesn't take the ownership of the buffer. +// It's mostly used to group the parameters for external capture. +struct VideoFrameI420 +{ + VideoFrameI420() { + y_plane = NULL; + u_plane = NULL; + v_plane = NULL; + y_pitch = 0; + u_pitch = 0; + v_pitch = 0; + width = 0; + height = 0; + } + + unsigned char* y_plane; + unsigned char* u_plane; + unsigned char* v_plane; + + int y_pitch; + int u_pitch; + int v_pitch; + + unsigned short width; + unsigned short height; +}; + /* External Capture interface. Returned by Create and implemented by the capture module. */ @@ -94,6 +121,8 @@ public: WebRtc_Word32 videoFrameLength, const VideoCaptureCapability& frameInfo, WebRtc_Word64 captureTime = 0) = 0; + virtual WebRtc_Word32 IncomingFrameI420(const VideoFrameI420& video_frame, + WebRtc_Word64 captureTime = 0) = 0; protected: ~VideoCaptureExternal() {} }; 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 c7690bbfb..ba4f99479 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 @@ WebRtc_Word32 VideoCaptureImpl::CaptureDelay() 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 @@ WebRtc_Word32 VideoCaptureImpl::IncomingFrame(WebRtc_UWord8* videoFrame, 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 @@ WebRtc_Word32 VideoCaptureImpl::IncomingFrame(WebRtc_UWord8* videoFrame, } } - 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 @@ WebRtc_Word32 VideoCaptureImpl::IncomingFrame(WebRtc_UWord8* videoFrame, } 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) diff --git a/src/modules/video_capture/main/source/video_capture_impl.h b/src/modules/video_capture/main/source/video_capture_impl.h index 21251d489..b751a77a1 100644 --- a/src/modules/video_capture/main/source/video_capture_impl.h +++ b/src/modules/video_capture/main/source/video_capture_impl.h @@ -95,6 +95,10 @@ public: WebRtc_Word32 videoFrameLength, const VideoCaptureCapability& frameInfo, WebRtc_Word64 captureTime = 0); + virtual WebRtc_Word32 IncomingFrameI420( + const VideoFrameI420& video_frame, + WebRtc_Word64 captureTime = 0); + // Platform dependent virtual WebRtc_Word32 StartCapture(const VideoCaptureCapability& capability) { @@ -120,6 +124,9 @@ protected: private: void UpdateFrameCount(); WebRtc_UWord32 CalculateFrameRate(const TickTime& now); + WebRtc_Word32 DeliverCapturedFrame( + VideoFrame& captureFrame, WebRtc_Word32 width, WebRtc_Word32 height, + WebRtc_Word64 capture_time, VideoCodecType codec_type); CriticalSectionWrapper& _callBackCs; diff --git a/src/modules/video_capture/main/test/testAPI/Logger.cpp b/src/modules/video_capture/main/test/testAPI/Logger.cpp index 8f32ec40c..4c5b120dd 100644 --- a/src/modules/video_capture/main/test/testAPI/Logger.cpp +++ b/src/modules/video_capture/main/test/testAPI/Logger.cpp @@ -30,7 +30,7 @@ Logger::~Logger(void) } void Logger::Print(char* msg) { - printf(msg); + printf("%s\n",msg); if (_logFile.Open()) { _logFile.WriteText(msg); diff --git a/src/modules/video_capture/main/test/testAPI/Renderer.cpp b/src/modules/video_capture/main/test/testAPI/Renderer.cpp index 3fd878fdb..7e815e5d7 100644 --- a/src/modules/video_capture/main/test/testAPI/Renderer.cpp +++ b/src/modules/video_capture/main/test/testAPI/Renderer.cpp @@ -227,6 +227,7 @@ void Renderer::SetRenderWindow(jobject renderWindow) int WebRtcCreateWindow(HWND &hwndMain,int winNum, int width, int height) { + return 0; } void SetWindowPos(HWND &hwndMain, int x, int y, int width, int height, bool onTop) { diff --git a/src/modules/video_capture/main/test/testAPI/testCameraEncoder.cpp b/src/modules/video_capture/main/test/testAPI/testCameraEncoder.cpp index 998d26594..d0ddf357e 100644 --- a/src/modules/video_capture/main/test/testAPI/testCameraEncoder.cpp +++ b/src/modules/video_capture/main/test/testAPI/testCameraEncoder.cpp @@ -32,7 +32,7 @@ testCameraEncoder::testCameraEncoder(void) Trace::CreateTrace(); Trace::SetLevelFilter(webrtc::kTraceAll); Trace::SetTraceFile("testCameraEncoder.txt"); - _captureInfo=VideoCaptureModule::CreateDeviceInfo(5); + _captureInfo=VideoCaptureFactory::CreateDeviceInfo(5); #ifdef RENDER_PREVIEW _renderer=NULL; _videoCoding=webrtc::VideoCodingModule::Createwebrtc::VideoCodingModule(5); @@ -91,7 +91,8 @@ int testCameraEncoder::DoTest() WebRtc_UWord8 productId[256]; _captureInfo->GetDeviceName(i,name,256,uniqueID,256,productId,256); - _captureModule= VideoCaptureModule::Create(0,uniqueID); + _captureModule= VideoCaptureFactory::Create(0,uniqueID); + _captureModule->AddRef(); _captureModule->RegisterCaptureDataCallback(*this); VideoCaptureCapability capability; @@ -113,7 +114,7 @@ int testCameraEncoder::DoTest() } } - VideoCaptureModule::Destroy(_captureModule); + _captureModule->Release(); } return 0; } @@ -226,8 +227,10 @@ void testCameraEncoder::OnIncomingCapturedFrame(const WebRtc_Word32 id, { _captureSettings.incomingFrames++; _captureSettings.noOfBytes+=videoFrame.Length(); - assert(videoFrame.Height()==_captureSettings.capability.height); - assert(videoFrame.Width()==_captureSettings.capability.width); + int height = static_cast(videoFrame.Height()); + int width = static_cast(videoFrame.Width()); + assert(height==_captureSettings.capability.height); + assert(width==_captureSettings.capability.width); assert(videoFrame.RenderTimeMs()>=(TickTime::MillisecondTimestamp()-30)); // RenderTimstamp should be the time now if((videoFrame.RenderTimeMs()>_captureSettings.lastRenderTimeMS +(1000*1.2)/_captureSettings.capability.maxFPS diff --git a/src/modules/video_capture/main/test/testAPI/testCameraEncoder.h b/src/modules/video_capture/main/test/testAPI/testCameraEncoder.h index bcbed840c..3a5c4391c 100644 --- a/src/modules/video_capture/main/test/testAPI/testCameraEncoder.h +++ b/src/modules/video_capture/main/test/testAPI/testCameraEncoder.h @@ -10,7 +10,7 @@ #pragma once -#include "video_capture.h" +#include "video_capture_factory.h" //#define RENDER_PREVIEW diff --git a/src/modules/video_capture/main/test/testAPI/testExternalCapture.cpp b/src/modules/video_capture/main/test/testAPI/testExternalCapture.cpp index d44e32f3b..e10e0758a 100644 --- a/src/modules/video_capture/main/test/testAPI/testExternalCapture.cpp +++ b/src/modules/video_capture/main/test/testAPI/testExternalCapture.cpp @@ -29,7 +29,8 @@ static int testExternalCaptureResult = 0; void testExternalCapture::CreateInterface() { - _captureModule = VideoCaptureModule::Create(1, _captureInteface); + _captureModule = VideoCaptureFactory::Create(1, _captureInteface); + _captureModule->AddRef(); } testExternalCapture::testExternalCapture(void) : _captureInteface(NULL), _captureModule(NULL) @@ -51,7 +52,7 @@ int testExternalCapture::CompareFrames(const VideoFrame& frame1, testExternalCapture::~testExternalCapture(void) { - VideoCaptureModule::Destroy(_captureModule); + _captureModule->Release(); } void testExternalCapture::OnIncomingCapturedFrame( @@ -114,6 +115,19 @@ int testExternalCapture::DoTest() frameInfo,0)==0); CompareFrames(_testFrame, _resultFrame); + printf(" testing the IncomingFrameI420 interface.\n"); + VideoFrameI420 frame_i420; + frame_i420.width = width; + frame_i420.height = height; + frame_i420.y_plane = _testFrame.Buffer(); + frame_i420.u_plane = frame_i420.y_plane + (width * height); + frame_i420.v_plane = frame_i420.u_plane + ((width * height) >> 2); + frame_i420.y_pitch = width; + frame_i420.u_pitch = width / 2; + frame_i420.v_pitch = width / 2; + assert(_captureInteface->IncomingFrameI420(frame_i420, 0) == 0); + CompareFrames(_testFrame, _resultFrame); + printf(" testing local frame rate callback and no picture alarm.\n"); WebRtc_Word64 testTime = 3; diff --git a/src/modules/video_capture/main/test/testAPI/testExternalCapture.h b/src/modules/video_capture/main/test/testAPI/testExternalCapture.h index 6e2ea6f64..8549b1f71 100644 --- a/src/modules/video_capture/main/test/testAPI/testExternalCapture.h +++ b/src/modules/video_capture/main/test/testAPI/testExternalCapture.h @@ -12,7 +12,7 @@ #define WEBRTC_MODULES_VIDEO_CAPTURE_MAIN_TEST_TESTAPI_TESTEXTERNALCAPTURE_H_ #include "testDefines.h" -#include "video_capture.h" +#include "video_capture_factory.h" namespace webrtc { diff --git a/src/modules/video_capture/main/test/testAPI/testPlatformDependent.cpp b/src/modules/video_capture/main/test/testAPI/testPlatformDependent.cpp index dd5cf09f7..b49b58d27 100644 --- a/src/modules/video_capture/main/test/testAPI/testPlatformDependent.cpp +++ b/src/modules/video_capture/main/test/testAPI/testPlatformDependent.cpp @@ -41,7 +41,7 @@ testPlatformDependent::testPlatformDependent(void) : Trace::CreateTrace(); Trace::SetLevelFilter(webrtc::kTraceAll); Trace::SetTraceFile("testPlatformDependent.txt"); - _captureInfo = VideoCaptureModule::CreateDeviceInfo(5); + _captureInfo = VideoCaptureFactory::CreateDeviceInfo(5); #ifdef RENDER_PREVIEW memset(_renderer, 0, sizeof(_renderer)); #endif @@ -125,8 +125,10 @@ void testPlatformDependent::VerifyResultFrame(const WebRtc_Word32 settingID, { found = true; - assert(videoFrame.Height()==_captureSettings[i].capability.height); - assert(videoFrame.Width()==_captureSettings[i].capability.width); + int height = static_cast(videoFrame.Height()); + int width = static_cast(videoFrame.Width()); + assert(height==_captureSettings[i].capability.height); + assert(width==_captureSettings[i].capability.width); assert(videoFrame.RenderTimeMs()>=TickTime::MillisecondTimestamp()-30); // RenderTimstamp should be the time now if ((videoFrame.RenderTimeMs() > _captureSettings[i].lastRenderTimeMS + (1000 * 1.1) @@ -172,8 +174,9 @@ WebRtc_Word32 testPlatformDependent::testCreateDelete( #endif _captureSettings[0].startTime = TickTime::MillisecondTimestamp(); _captureSettings[0].initStartTime = TickTime::MillisecondTimestamp(); - _captureSettings[0].captureModule = VideoCaptureModule::Create(0, - uniqueID); + _captureSettings[0].captureModule = + VideoCaptureFactory::Create(0, uniqueID); + _captureSettings[0].captureModule->AddRef(); assert(!_captureSettings[0].captureModule->CaptureStarted()); assert(_captureSettings[0].captureModule); // Test that it is created assert(!_captureSettings[0].captureModule->RegisterCaptureDataCallback(*this)); @@ -202,7 +205,7 @@ WebRtc_Word32 testPlatformDependent::testCreateDelete( assert(_captureSettings[0].captureModule->StopCapture()==0); assert(!_captureSettings[0].captureModule->CaptureStarted()); - VideoCaptureModule::Destroy(_captureSettings[0].captureModule); + _captureSettings[0].captureModule->Release(); _captureSettings[0].stopStopTime = TickTime::MillisecondTimestamp(); assert((_captureSettings[0].incomingFrames >= 5)); // Make sure at least 5 frames has been captured @@ -219,8 +222,9 @@ WebRtc_Word32 testPlatformDependent::testCapabilities( #ifndef WEBRTC_MAC LOG("\n\nTesting capture capabilities\n"); - _captureSettings[0].captureModule = VideoCaptureModule::Create(0, uniqueID); + _captureSettings[0].captureModule = VideoCaptureFactory::Create(0, uniqueID); assert(_captureSettings[0].captureModule); // Test that it is created + _captureSettings[0].captureModule->AddRef(); assert(!_captureSettings[0].captureModule->RegisterCaptureDataCallback(*this)); @@ -271,7 +275,7 @@ WebRtc_Word32 testPlatformDependent::testCapabilities( EvaluateTestResult(_captureSettings[0]); } assert(oneValidCap); // Make sure the camera support at least one capability - VideoCaptureModule::Destroy(_captureSettings[0].captureModule); + _captureSettings[0].captureModule->Release(); _captureSettings[0].ResetAll(); return testPlatformDependentResult; #else @@ -301,7 +305,8 @@ WebRtc_Word32 testPlatformDependent::testMultipleCameras() WebRtc_UWord8* name = _captureSettings[i].captureName; LOG("\n\n Found capture device %u\n name %s\n unique name %s\n" ,(unsigned int) i,(char*) name, (char*)id); - _captureSettings[i].captureModule = VideoCaptureModule::Create(i, id); + _captureSettings[i].captureModule = VideoCaptureFactory::Create(i, id); + _captureSettings[i].captureModule->AddRef(); assert(_captureSettings[i].captureModule); // Test that it is created assert(!_captureSettings[i].captureModule->RegisterCaptureDataCallback(*this)); @@ -326,7 +331,7 @@ WebRtc_Word32 testPlatformDependent::testMultipleCameras() _captureSettings[i].captureModule->StopCapture(); EvaluateTestResult(_captureSettings[i]); - VideoCaptureModule::Destroy(_captureSettings[i].captureModule); + _captureSettings[i].captureModule->Release(); _captureSettings[i].ResetAll(); } return testPlatformDependentResult; @@ -344,7 +349,9 @@ WebRtc_Word32 testPlatformDependent::testRotation(const WebRtc_UWord8* uniqueID) { LOG("\n\nTesting capture Rotation\n"); - _captureSettings[0].captureModule = VideoCaptureModule::Create(0, uniqueID); + _captureSettings[0].captureModule = + VideoCaptureFactory::Create(0, uniqueID); + _captureSettings[0].captureModule->AddRef(); assert(_captureSettings[0].captureModule); // Test that it is created assert(!_captureSettings[0].captureModule->RegisterCaptureDataCallback(*this)); @@ -411,7 +418,7 @@ WebRtc_Word32 testPlatformDependent::testRotation(const WebRtc_UWord8* uniqueID) EvaluateTestResult(_captureSettings[0]); - VideoCaptureModule::Destroy(_captureSettings[0].captureModule); + _captureSettings[0].captureModule->Release(); _captureSettings[0].ResetAll(); return testPlatformDependentResult; diff --git a/src/modules/video_capture/main/test/testAPI/testPlatformDependent.h b/src/modules/video_capture/main/test/testAPI/testPlatformDependent.h index 8c513ed6d..04d15dbe9 100644 --- a/src/modules/video_capture/main/test/testAPI/testPlatformDependent.h +++ b/src/modules/video_capture/main/test/testAPI/testPlatformDependent.h @@ -12,7 +12,7 @@ #include "testDefines.h" -#include "video_capture.h" +#include "video_capture_factory.h" #include "Logger.h" //#define RENDER_PREVIEW //Does not work properly on Linux diff --git a/src/video_engine/main/interface/vie_capture.h b/src/video_engine/main/interface/vie_capture.h index 7bd71d32c..8ed47c929 100644 --- a/src/video_engine/main/interface/vie_capture.h +++ b/src/video_engine/main/interface/vie_capture.h @@ -73,6 +73,31 @@ enum RotateCapturedFrame RotateCapturedFrame_270 = 270 }; +struct ViEVideoFrameI420 +{ + ViEVideoFrameI420() { + y_plane = NULL; + u_plane = NULL; + v_plane = NULL; + y_pitch = 0; + u_pitch = 0; + v_pitch = 0; + width = 0; + height = 0; + } + + unsigned char* y_plane; + unsigned char* u_plane; + unsigned char* v_plane; + + int y_pitch; + int u_pitch; + int v_pitch; + + unsigned short width; + unsigned short height; +}; + // This class declares an abstract interface to be used when using an external // capture device. The user implemented derived class is registered using // AllocateExternalCaptureDevice and is released using ReleaseCaptureDevice. @@ -89,6 +114,12 @@ public: unsigned short width, unsigned short height, RawVideoType videoType, unsigned long long captureTime = 0) = 0; + + // This method is specifically for delivering a new captured I420 frame to + // VideoEngine. + virtual int IncomingFrameI420( + const ViEVideoFrameI420& video_frame, + unsigned long long captureTime = 0) = 0; }; // ---------------------------------------------------------------------------- diff --git a/src/video_engine/main/source/vie_capturer.cc b/src/video_engine/main/source/vie_capturer.cc index 55dd27b49..adf52fe73 100644 --- a/src/video_engine/main/source/vie_capturer.cc +++ b/src/video_engine/main/source/vie_capturer.cc @@ -409,6 +409,34 @@ int ViECapturer::IncomingFrame(unsigned char* videoFrame, return _externalCaptureModule->IncomingFrame(videoFrame, videoFrameLength, capability, captureTime); } + +// This method is specifically for delivering a new captured I420 frame to +// VideoEngine. +int ViECapturer::IncomingFrameI420( + const ViEVideoFrameI420& video_frame, + unsigned long long captureTime) { + WEBRTC_TRACE(webrtc::kTraceInfo, webrtc::kTraceVideo, + ViEId(_engineId, _captureId), + "%ExternalCapture::IncomingFrame width %d, height %d, captureTime %u", + video_frame.width, video_frame.height, captureTime); + + if (!_externalCaptureModule) { + return -1; + } + + VideoFrameI420 frame; + frame.width = video_frame.width; + frame.height = video_frame.height; + frame.y_plane = video_frame.y_plane; + frame.u_plane = video_frame.u_plane; + frame.v_plane = video_frame.v_plane; + frame.y_pitch = video_frame.y_pitch; + frame.u_pitch = video_frame.u_pitch; + frame.v_pitch = video_frame.v_pitch; + + return _externalCaptureModule->IncomingFrameI420(frame, captureTime); +} + // ---------------------------------------------------------------------------- // OnIncomingCapturedFrame // diff --git a/src/video_engine/main/source/vie_capturer.h b/src/video_engine/main/source/vie_capturer.h index c681dc9d7..5a61d4db4 100644 --- a/src/video_engine/main/source/vie_capturer.h +++ b/src/video_engine/main/source/vie_capturer.h @@ -69,7 +69,12 @@ public: RawVideoType videoType, unsigned long long captureTime = 0); - // Use this capture device as encoder. Returns 0 if the codec is supported by this capture device. + virtual int IncomingFrameI420( + const ViEVideoFrameI420& video_frame, + unsigned long long captureTime = 0); + + // Use this capture device as encoder. + // Returns 0 if the codec is supported by this capture device. virtual WebRtc_Word32 PreEncodeToViEEncoder(const VideoCodec& codec, ViEEncoder& vieEncoder, WebRtc_Word32 vieEncoderId);