webrtcvideocapturer.cc revision 39f2b0c870c59dbc37d4f4d8cdb5fff7a7ae5b81
15f93d0a140515e3b8cdd1b9a4c6f5871144e5deejlmiller@webrtc.org/* 25f93d0a140515e3b8cdd1b9a4c6f5871144e5deejlmiller@webrtc.org * libjingle 35f93d0a140515e3b8cdd1b9a4c6f5871144e5deejlmiller@webrtc.org * Copyright 2011 Google Inc. 45f93d0a140515e3b8cdd1b9a4c6f5871144e5deejlmiller@webrtc.org * 55f93d0a140515e3b8cdd1b9a4c6f5871144e5deejlmiller@webrtc.org * Redistribution and use in source and binary forms, with or without 65f93d0a140515e3b8cdd1b9a4c6f5871144e5deejlmiller@webrtc.org * modification, are permitted provided that the following conditions are met: 75f93d0a140515e3b8cdd1b9a4c6f5871144e5deejlmiller@webrtc.org * 85f93d0a140515e3b8cdd1b9a4c6f5871144e5deejlmiller@webrtc.org * 1. Redistributions of source code must retain the above copyright notice, 95f93d0a140515e3b8cdd1b9a4c6f5871144e5deejlmiller@webrtc.org * this list of conditions and the following disclaimer. 105f93d0a140515e3b8cdd1b9a4c6f5871144e5deejlmiller@webrtc.org * 2. Redistributions in binary form must reproduce the above copyright notice, 115f93d0a140515e3b8cdd1b9a4c6f5871144e5deejlmiller@webrtc.org * this list of conditions and the following disclaimer in the documentation 125f93d0a140515e3b8cdd1b9a4c6f5871144e5deejlmiller@webrtc.org * and/or other materials provided with the distribution. 135f93d0a140515e3b8cdd1b9a4c6f5871144e5deejlmiller@webrtc.org * 3. The name of the author may not be used to endorse or promote products 145f93d0a140515e3b8cdd1b9a4c6f5871144e5deejlmiller@webrtc.org * derived from this software without specific prior written permission. 155f93d0a140515e3b8cdd1b9a4c6f5871144e5deejlmiller@webrtc.org * 165f93d0a140515e3b8cdd1b9a4c6f5871144e5deejlmiller@webrtc.org * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED 175f93d0a140515e3b8cdd1b9a4c6f5871144e5deejlmiller@webrtc.org * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 185f93d0a140515e3b8cdd1b9a4c6f5871144e5deejlmiller@webrtc.org * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO 195f93d0a140515e3b8cdd1b9a4c6f5871144e5deejlmiller@webrtc.org * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 205f93d0a140515e3b8cdd1b9a4c6f5871144e5deejlmiller@webrtc.org * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 215f93d0a140515e3b8cdd1b9a4c6f5871144e5deejlmiller@webrtc.org * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 225f93d0a140515e3b8cdd1b9a4c6f5871144e5deejlmiller@webrtc.org * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 235f93d0a140515e3b8cdd1b9a4c6f5871144e5deejlmiller@webrtc.org * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 245f93d0a140515e3b8cdd1b9a4c6f5871144e5deejlmiller@webrtc.org * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 255f93d0a140515e3b8cdd1b9a4c6f5871144e5deejlmiller@webrtc.org * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 265f93d0a140515e3b8cdd1b9a4c6f5871144e5deejlmiller@webrtc.org */ 2728e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org 2828e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org#include "talk/media/webrtc/webrtcvideocapturer.h" 2928e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org 3028e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org#ifdef HAVE_CONFIG_H 3128e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org#include <config.h> 3228e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org#endif 3328e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org 3428e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org#ifdef HAVE_WEBRTC_VIDEO 35a09a99950ec40aef6421e4ba35eee7196b7a6e68buildbot@webrtc.org#include "talk/media/webrtc/webrtcvideoframe.h" 36a09a99950ec40aef6421e4ba35eee7196b7a6e68buildbot@webrtc.org#include "talk/media/webrtc/webrtcvideoframefactory.h" 37e07710cc91b3dccd7fea7df3d99c304f419babdatommi@webrtc.org#include "webrtc/base/bind.h" 38e07710cc91b3dccd7fea7df3d99c304f419babdatommi@webrtc.org#include "webrtc/base/checks.h" 39d4e598d57aed714a599444a7eab5e8fdde52a950buildbot@webrtc.org#include "webrtc/base/criticalsection.h" 40d4e598d57aed714a599444a7eab5e8fdde52a950buildbot@webrtc.org#include "webrtc/base/logging.h" 414591fbd09f9cb6e83433c49a12dd8524c2806502pkasting@chromium.org#include "webrtc/base/safe_conversions.h" 42d4e598d57aed714a599444a7eab5e8fdde52a950buildbot@webrtc.org#include "webrtc/base/thread.h" 43d4e598d57aed714a599444a7eab5e8fdde52a950buildbot@webrtc.org#include "webrtc/base/timeutils.h" 4428e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org 45d4e598d57aed714a599444a7eab5e8fdde52a950buildbot@webrtc.org#include "webrtc/base/win32.h" // Need this to #include the impl files. 4628e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org#include "webrtc/modules/video_capture/include/video_capture_factory.h" 4764c1e8cda5cb4db85c5c296bf2f6a8181af7de9dGuo-wei Shieh#include "webrtc/system_wrappers/interface/field_trial.h" 4828e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org 4928e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.orgnamespace cricket { 5028e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org 5128e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.orgstruct kVideoFourCCEntry { 5228e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org uint32 fourcc; 5328e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org webrtc::RawVideoType webrtc_type; 5428e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org}; 5528e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org 5628e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org// This indicates our format preferences and defines a mapping between 5728e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org// webrtc::RawVideoType (from video_capture_defines.h) to our FOURCCs. 5828e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.orgstatic kVideoFourCCEntry kSupportedFourCCs[] = { 5928e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org { FOURCC_I420, webrtc::kVideoI420 }, // 12 bpp, no conversion. 6028e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org { FOURCC_YV12, webrtc::kVideoYV12 }, // 12 bpp, no conversion. 6128e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org { FOURCC_YUY2, webrtc::kVideoYUY2 }, // 16 bpp, fast conversion. 6228e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org { FOURCC_UYVY, webrtc::kVideoUYVY }, // 16 bpp, fast conversion. 63fa5fcd671de2f6db6249c3cdd2908f4fc39d84a0buildbot@webrtc.org { FOURCC_NV12, webrtc::kVideoNV12 }, // 12 bpp, fast conversion. 64fa5fcd671de2f6db6249c3cdd2908f4fc39d84a0buildbot@webrtc.org { FOURCC_NV21, webrtc::kVideoNV21 }, // 12 bpp, fast conversion. 6528e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org { FOURCC_MJPG, webrtc::kVideoMJPEG }, // compressed, slow conversion. 6628e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org { FOURCC_ARGB, webrtc::kVideoARGB }, // 32 bpp, slow conversion. 6728e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org { FOURCC_24BG, webrtc::kVideoRGB24 }, // 24 bpp, slow conversion. 6828e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org}; 6928e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org 7028e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.orgclass WebRtcVcmFactory : public WebRtcVcmFactoryInterface { 7128e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org public: 7228e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org virtual webrtc::VideoCaptureModule* Create(int id, const char* device) { 7328e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org return webrtc::VideoCaptureFactory::Create(id, device); 7428e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org } 7528e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org virtual webrtc::VideoCaptureModule::DeviceInfo* CreateDeviceInfo(int id) { 7628e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org return webrtc::VideoCaptureFactory::CreateDeviceInfo(id); 7728e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org } 7828e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org virtual void DestroyDeviceInfo(webrtc::VideoCaptureModule::DeviceInfo* info) { 7928e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org delete info; 8028e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org } 8128e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org}; 8228e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org 8328e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.orgstatic bool CapabilityToFormat(const webrtc::VideoCaptureCapability& cap, 8428e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org VideoFormat* format) { 8528e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org uint32 fourcc = 0; 8628e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org for (size_t i = 0; i < ARRAY_SIZE(kSupportedFourCCs); ++i) { 8728e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org if (kSupportedFourCCs[i].webrtc_type == cap.rawType) { 8828e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org fourcc = kSupportedFourCCs[i].fourcc; 8928e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org break; 9028e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org } 9128e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org } 9228e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org if (fourcc == 0) { 9328e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org return false; 9428e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org } 9528e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org 9628e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org format->fourcc = fourcc; 9728e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org format->width = cap.width; 9828e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org format->height = cap.height; 9928e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org format->interval = VideoFormat::FpsToInterval(cap.maxFPS); 10028e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org return true; 10128e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org} 10228e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org 10328e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.orgstatic bool FormatToCapability(const VideoFormat& format, 10428e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org webrtc::VideoCaptureCapability* cap) { 10528e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org webrtc::RawVideoType webrtc_type = webrtc::kVideoUnknown; 10628e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org for (size_t i = 0; i < ARRAY_SIZE(kSupportedFourCCs); ++i) { 10728e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org if (kSupportedFourCCs[i].fourcc == format.fourcc) { 10828e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org webrtc_type = kSupportedFourCCs[i].webrtc_type; 10928e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org break; 11028e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org } 11128e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org } 11228e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org if (webrtc_type == webrtc::kVideoUnknown) { 11328e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org return false; 11428e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org } 11528e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org 11628e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org cap->width = format.width; 11728e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org cap->height = format.height; 11828e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org cap->maxFPS = VideoFormat::IntervalToFps(format.interval); 11928e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org cap->expectedCaptureDelay = 0; 12028e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org cap->rawType = webrtc_type; 12128e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org cap->codecType = webrtc::kVideoCodecUnknown; 12228e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org cap->interlaced = false; 12328e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org return true; 12428e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org} 12528e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org 12628e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org/////////////////////////////////////////////////////////////////////////// 12728e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org// Implementation of class WebRtcVideoCapturer 12828e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org/////////////////////////////////////////////////////////////////////////// 12928e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org 13028e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.orgWebRtcVideoCapturer::WebRtcVideoCapturer() 13128e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org : factory_(new WebRtcVcmFactory), 13228e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org module_(NULL), 133e07710cc91b3dccd7fea7df3d99c304f419babdatommi@webrtc.org captured_frames_(0), 134e07710cc91b3dccd7fea7df3d99c304f419babdatommi@webrtc.org start_thread_(nullptr) { 1354f0d401faecf5d8a4c82e6e2223651ef13ad8e31buildbot@webrtc.org set_frame_factory(new WebRtcVideoFrameFactory()); 13628e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org} 13728e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org 13828e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.orgWebRtcVideoCapturer::WebRtcVideoCapturer(WebRtcVcmFactoryInterface* factory) 13928e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org : factory_(factory), 14028e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org module_(NULL), 141e07710cc91b3dccd7fea7df3d99c304f419babdatommi@webrtc.org captured_frames_(0), 142e07710cc91b3dccd7fea7df3d99c304f419babdatommi@webrtc.org start_thread_(nullptr) { 1434f0d401faecf5d8a4c82e6e2223651ef13ad8e31buildbot@webrtc.org set_frame_factory(new WebRtcVideoFrameFactory()); 14428e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org} 14528e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org 14628e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.orgWebRtcVideoCapturer::~WebRtcVideoCapturer() { 14728e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org if (module_) { 14828e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org module_->Release(); 14928e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org } 15028e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org} 15128e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org 15228e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.orgbool WebRtcVideoCapturer::Init(const Device& device) { 153e07710cc91b3dccd7fea7df3d99c304f419babdatommi@webrtc.org DCHECK(!start_thread_); 15428e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org if (module_) { 15528e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org LOG(LS_ERROR) << "The capturer is already initialized"; 15628e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org return false; 15728e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org } 15828e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org 15928e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org webrtc::VideoCaptureModule::DeviceInfo* info = factory_->CreateDeviceInfo(0); 16028e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org if (!info) { 16128e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org return false; 16228e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org } 16328e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org 16428e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org // Find the desired camera, by name. 16528e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org // In the future, comparing IDs will be more robust. 16628e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org // TODO(juberti): Figure what's needed to allow this. 16728e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org int num_cams = info->NumberOfDevices(); 16828e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org char vcm_id[256] = ""; 16928e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org bool found = false; 17028e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org for (int index = 0; index < num_cams; ++index) { 17128e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org char vcm_name[256]; 17228e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org if (info->GetDeviceName(index, vcm_name, ARRAY_SIZE(vcm_name), 17328e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org vcm_id, ARRAY_SIZE(vcm_id)) != -1) { 17428e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org if (device.name == reinterpret_cast<char*>(vcm_name)) { 17528e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org found = true; 17628e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org break; 17728e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org } 17828e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org } 17928e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org } 18028e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org if (!found) { 18128e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org LOG(LS_WARNING) << "Failed to find capturer for id: " << device.id; 18228e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org factory_->DestroyDeviceInfo(info); 18328e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org return false; 18428e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org } 18528e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org 18628e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org // Enumerate the supported formats. 18728e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org // TODO(juberti): Find out why this starts/stops the camera... 18828e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org std::vector<VideoFormat> supported; 18928e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org int32_t num_caps = info->NumberOfCapabilities(vcm_id); 19028e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org for (int32_t i = 0; i < num_caps; ++i) { 19128e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org webrtc::VideoCaptureCapability cap; 19228e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org if (info->GetCapability(vcm_id, i, cap) != -1) { 19328e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org VideoFormat format; 19428e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org if (CapabilityToFormat(cap, &format)) { 19528e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org supported.push_back(format); 19628e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org } else { 19728e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org LOG(LS_WARNING) << "Ignoring unsupported WebRTC capture format " 19828e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org << cap.rawType; 19928e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org } 20028e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org } 20128e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org } 20228e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org factory_->DestroyDeviceInfo(info); 20339f2b0c870c59dbc37d4f4d8cdb5fff7a7ae5b81Yuriy Shevchuk 20428e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org if (supported.empty()) { 20528e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org LOG(LS_ERROR) << "Failed to find usable formats for id: " << device.id; 20628e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org return false; 20728e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org } 20839f2b0c870c59dbc37d4f4d8cdb5fff7a7ae5b81Yuriy Shevchuk 20928e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org module_ = factory_->Create(0, vcm_id); 21028e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org if (!module_) { 21128e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org LOG(LS_ERROR) << "Failed to create capturer for id: " << device.id; 21228e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org return false; 21328e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org } 21428e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org 21528e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org // It is safe to change member attributes now. 21628e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org module_->AddRef(); 21728e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org SetId(device.id); 21828e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org SetSupportedFormats(supported); 2191226e926e6104322d9b99026b98f515cb4d40fd4guoweis@webrtc.org 2201226e926e6104322d9b99026b98f515cb4d40fd4guoweis@webrtc.org // Ensure these 2 have the same value. 2211226e926e6104322d9b99026b98f515cb4d40fd4guoweis@webrtc.org SetApplyRotation(module_->GetApplyRotation()); 2221226e926e6104322d9b99026b98f515cb4d40fd4guoweis@webrtc.org 22328e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org return true; 22428e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org} 22528e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org 22628e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.orgbool WebRtcVideoCapturer::Init(webrtc::VideoCaptureModule* module) { 227e07710cc91b3dccd7fea7df3d99c304f419babdatommi@webrtc.org DCHECK(!start_thread_); 22828e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org if (module_) { 22928e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org LOG(LS_ERROR) << "The capturer is already initialized"; 23028e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org return false; 23128e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org } 23228e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org if (!module) { 23328e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org LOG(LS_ERROR) << "Invalid VCM supplied"; 23428e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org return false; 23528e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org } 23628e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org // TODO(juberti): Set id and formats. 23728e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org (module_ = module)->AddRef(); 23828e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org return true; 23928e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org} 24028e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org 24128e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.orgbool WebRtcVideoCapturer::GetBestCaptureFormat(const VideoFormat& desired, 24228e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org VideoFormat* best_format) { 24328e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org if (!best_format) { 24428e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org return false; 24528e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org } 24628e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org 24728e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org if (!VideoCapturer::GetBestCaptureFormat(desired, best_format)) { 24828e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org // We maybe using a manually injected VCM which doesn't support enum. 24928e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org // Use the desired format as the best format. 25028e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org best_format->width = desired.width; 25128e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org best_format->height = desired.height; 25228e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org best_format->fourcc = FOURCC_I420; 25328e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org best_format->interval = desired.interval; 25428e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org LOG(LS_INFO) << "Failed to find best capture format," 25528e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org << " fall back to the requested format " 25628e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org << best_format->ToString(); 25728e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org } 25828e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org return true; 25928e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org} 2601226e926e6104322d9b99026b98f515cb4d40fd4guoweis@webrtc.orgbool WebRtcVideoCapturer::SetApplyRotation(bool enable) { 26164c1e8cda5cb4db85c5c296bf2f6a8181af7de9dGuo-wei Shieh // Can't take lock here as this will cause deadlock with 26264c1e8cda5cb4db85c5c296bf2f6a8181af7de9dGuo-wei Shieh // OnIncomingCapturedFrame. In fact, the whole method, including methods it 26364c1e8cda5cb4db85c5c296bf2f6a8181af7de9dGuo-wei Shieh // calls, can't take lock. 264d3ddc1b69e9cdfd7c6d38ab02b8d8ab891d30fd1Fredrik Solenberg DCHECK(module_); 2651226e926e6104322d9b99026b98f515cb4d40fd4guoweis@webrtc.org 26664c1e8cda5cb4db85c5c296bf2f6a8181af7de9dGuo-wei Shieh const std::string group_name = 26764c1e8cda5cb4db85c5c296bf2f6a8181af7de9dGuo-wei Shieh webrtc::field_trial::FindFullName("WebRTC-CVO"); 26864c1e8cda5cb4db85c5c296bf2f6a8181af7de9dGuo-wei Shieh 26964c1e8cda5cb4db85c5c296bf2f6a8181af7de9dGuo-wei Shieh if (group_name == "Disabled") { 27064c1e8cda5cb4db85c5c296bf2f6a8181af7de9dGuo-wei Shieh return true; 27164c1e8cda5cb4db85c5c296bf2f6a8181af7de9dGuo-wei Shieh } 27264c1e8cda5cb4db85c5c296bf2f6a8181af7de9dGuo-wei Shieh 2731226e926e6104322d9b99026b98f515cb4d40fd4guoweis@webrtc.org if (!VideoCapturer::SetApplyRotation(enable)) { 2741226e926e6104322d9b99026b98f515cb4d40fd4guoweis@webrtc.org return false; 2751226e926e6104322d9b99026b98f515cb4d40fd4guoweis@webrtc.org } 2761226e926e6104322d9b99026b98f515cb4d40fd4guoweis@webrtc.org return module_->SetApplyRotation(enable); 2771226e926e6104322d9b99026b98f515cb4d40fd4guoweis@webrtc.org} 27828e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org 27928e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.orgCaptureState WebRtcVideoCapturer::Start(const VideoFormat& capture_format) { 28028e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org if (!module_) { 28128e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org LOG(LS_ERROR) << "The capturer has not been initialized"; 28228e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org return CS_NO_DEVICE; 28328e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org } 28428e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org 285d4e598d57aed714a599444a7eab5e8fdde52a950buildbot@webrtc.org rtc::CritScope cs(&critical_section_stopping_); 28628e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org if (IsRunning()) { 28728e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org LOG(LS_ERROR) << "The capturer is already running"; 28828e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org return CS_FAILED; 28928e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org } 29028e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org 291e07710cc91b3dccd7fea7df3d99c304f419babdatommi@webrtc.org DCHECK(!start_thread_); 292e07710cc91b3dccd7fea7df3d99c304f419babdatommi@webrtc.org 293e07710cc91b3dccd7fea7df3d99c304f419babdatommi@webrtc.org start_thread_ = rtc::Thread::Current(); 294e07710cc91b3dccd7fea7df3d99c304f419babdatommi@webrtc.org 29528e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org SetCaptureFormat(&capture_format); 29628e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org 29728e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org webrtc::VideoCaptureCapability cap; 29828e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org if (!FormatToCapability(capture_format, &cap)) { 29928e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org LOG(LS_ERROR) << "Invalid capture format specified"; 30028e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org return CS_FAILED; 30128e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org } 30228e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org 30328e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org std::string camera_id(GetId()); 304d4e598d57aed714a599444a7eab5e8fdde52a950buildbot@webrtc.org uint32 start = rtc::Time(); 3057433a088d2e97993266b66c102b0866aa90b4424mallinath@webrtc.org module_->RegisterCaptureDataCallback(*this); 3067433a088d2e97993266b66c102b0866aa90b4424mallinath@webrtc.org if (module_->StartCapture(cap) != 0) { 30728e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org LOG(LS_ERROR) << "Camera '" << camera_id << "' failed to start"; 308e07710cc91b3dccd7fea7df3d99c304f419babdatommi@webrtc.org start_thread_ = nullptr; 30928e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org return CS_FAILED; 31028e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org } 31128e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org 31228e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org LOG(LS_INFO) << "Camera '" << camera_id << "' started with format " 31328e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org << capture_format.ToString() << ", elapsed time " 314d4e598d57aed714a599444a7eab5e8fdde52a950buildbot@webrtc.org << rtc::TimeSince(start) << " ms"; 31528e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org 31628e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org captured_frames_ = 0; 31728e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org SetCaptureState(CS_RUNNING); 31828e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org return CS_STARTING; 31928e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org} 32028e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org 321f6d6ed0c66457170be3f3b2bc214cd7141e441a4wu@webrtc.org// Critical section blocks Stop from shutting down during callbacks from capture 322f6d6ed0c66457170be3f3b2bc214cd7141e441a4wu@webrtc.org// thread to OnIncomingCapturedFrame. Note that the crit is try-locked in 323f6d6ed0c66457170be3f3b2bc214cd7141e441a4wu@webrtc.org// OnFrameCaptured, as the lock ordering between this and the system component 324f6d6ed0c66457170be3f3b2bc214cd7141e441a4wu@webrtc.org// controlling the camera is reversed: system frame -> OnIncomingCapturedFrame; 325f6d6ed0c66457170be3f3b2bc214cd7141e441a4wu@webrtc.org// Stop -> system stop camera). 32628e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.orgvoid WebRtcVideoCapturer::Stop() { 327d4e598d57aed714a599444a7eab5e8fdde52a950buildbot@webrtc.org rtc::CritScope cs(&critical_section_stopping_); 32828e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org if (IsRunning()) { 329e07710cc91b3dccd7fea7df3d99c304f419babdatommi@webrtc.org DCHECK(start_thread_); 330d4e598d57aed714a599444a7eab5e8fdde52a950buildbot@webrtc.org rtc::Thread::Current()->Clear(this); 33128e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org module_->StopCapture(); 33228e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org module_->DeRegisterCaptureDataCallback(); 33328e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org 33428e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org // TODO(juberti): Determine if the VCM exposes any drop stats we can use. 33528e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org double drop_ratio = 0.0; 33628e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org std::string camera_id(GetId()); 33728e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org LOG(LS_INFO) << "Camera '" << camera_id << "' stopped after capturing " 33828e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org << captured_frames_ << " frames and dropping " 33928e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org << drop_ratio << "%"; 34028e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org } 34128e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org SetCaptureFormat(NULL); 342e07710cc91b3dccd7fea7df3d99c304f419babdatommi@webrtc.org start_thread_ = nullptr; 34328e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org} 34428e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org 34528e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.orgbool WebRtcVideoCapturer::IsRunning() { 34628e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org return (module_ != NULL && module_->CaptureStarted()); 34728e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org} 34828e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org 34928e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.orgbool WebRtcVideoCapturer::GetPreferredFourccs( 35028e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org std::vector<uint32>* fourccs) { 35128e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org if (!fourccs) { 35228e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org return false; 35328e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org } 35428e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org 35528e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org fourccs->clear(); 35628e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org for (size_t i = 0; i < ARRAY_SIZE(kSupportedFourCCs); ++i) { 35728e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org fourccs->push_back(kSupportedFourCCs[i].fourcc); 35828e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org } 35928e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org return true; 36028e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org} 36128e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org 362af612d5e0769571544952cbe55e675748afa9bddperkj@webrtc.orgvoid WebRtcVideoCapturer::OnIncomingCapturedFrame( 363af612d5e0769571544952cbe55e675748afa9bddperkj@webrtc.org const int32_t id, 364af612d5e0769571544952cbe55e675748afa9bddperkj@webrtc.org const webrtc::I420VideoFrame& sample) { 365f6d6ed0c66457170be3f3b2bc214cd7141e441a4wu@webrtc.org // This would be a normal CritScope, except that it's possible that: 366f6d6ed0c66457170be3f3b2bc214cd7141e441a4wu@webrtc.org // (1) whatever system component producing this frame has taken a lock, and 367f6d6ed0c66457170be3f3b2bc214cd7141e441a4wu@webrtc.org // (2) Stop() probably calls back into that system component, which may take 368f6d6ed0c66457170be3f3b2bc214cd7141e441a4wu@webrtc.org // the same lock. Due to the reversed order, we have to try-lock in order to 369f6d6ed0c66457170be3f3b2bc214cd7141e441a4wu@webrtc.org // avoid a potential deadlock. Besides, if we can't enter because we're 370f6d6ed0c66457170be3f3b2bc214cd7141e441a4wu@webrtc.org // stopping, we may as well drop the frame. 371d4e598d57aed714a599444a7eab5e8fdde52a950buildbot@webrtc.org rtc::TryCritScope cs(&critical_section_stopping_); 372f6d6ed0c66457170be3f3b2bc214cd7141e441a4wu@webrtc.org if (!cs.locked() || !IsRunning()) { 373f6d6ed0c66457170be3f3b2bc214cd7141e441a4wu@webrtc.org // Capturer has been stopped or is in the process of stopping. 374f6d6ed0c66457170be3f3b2bc214cd7141e441a4wu@webrtc.org return; 375f6d6ed0c66457170be3f3b2bc214cd7141e441a4wu@webrtc.org } 37628e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org 37728e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org ++captured_frames_; 37828e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org // Log the size and pixel aspect ratio of the first captured frame. 37928e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org if (1 == captured_frames_) { 38028e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org LOG(LS_INFO) << "Captured frame size " 3812056ee3e3c7683ae4b2c4b12da99c3105c4f46a9magjed@webrtc.org << sample.width() << "x" << sample.height() 38228e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org << ". Expected format " << GetCaptureFormat()->ToString(); 38328e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org } 38428e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org 385e07710cc91b3dccd7fea7df3d99c304f419babdatommi@webrtc.org if (start_thread_->IsCurrent()) { 3862056ee3e3c7683ae4b2c4b12da99c3105c4f46a9magjed@webrtc.org SignalFrameCapturedOnStartThread(&sample); 387e07710cc91b3dccd7fea7df3d99c304f419babdatommi@webrtc.org } else { 388e07710cc91b3dccd7fea7df3d99c304f419babdatommi@webrtc.org // This currently happens on with at least VideoCaptureModuleV4L2 and 389e07710cc91b3dccd7fea7df3d99c304f419babdatommi@webrtc.org // possibly other implementations of WebRTC's VideoCaptureModule. 390e07710cc91b3dccd7fea7df3d99c304f419babdatommi@webrtc.org // In order to maintain the threading contract with the upper layers and 391e07710cc91b3dccd7fea7df3d99c304f419babdatommi@webrtc.org // consistency with other capturers such as in Chrome, we need to do a 392e07710cc91b3dccd7fea7df3d99c304f419babdatommi@webrtc.org // thread hop. 393e07710cc91b3dccd7fea7df3d99c304f419babdatommi@webrtc.org start_thread_->Invoke<void>( 394e07710cc91b3dccd7fea7df3d99c304f419babdatommi@webrtc.org rtc::Bind(&WebRtcVideoCapturer::SignalFrameCapturedOnStartThread, 3952056ee3e3c7683ae4b2c4b12da99c3105c4f46a9magjed@webrtc.org this, &sample)); 396e07710cc91b3dccd7fea7df3d99c304f419babdatommi@webrtc.org } 39728e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org} 39828e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org 39928e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.orgvoid WebRtcVideoCapturer::OnCaptureDelayChanged(const int32_t id, 40028e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org const int32_t delay) { 40128e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org LOG(LS_INFO) << "Capture delay changed to " << delay << " ms"; 40228e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org} 40328e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org 404e07710cc91b3dccd7fea7df3d99c304f419babdatommi@webrtc.orgvoid WebRtcVideoCapturer::SignalFrameCapturedOnStartThread( 405af612d5e0769571544952cbe55e675748afa9bddperkj@webrtc.org const webrtc::I420VideoFrame* frame) { 406e07710cc91b3dccd7fea7df3d99c304f419babdatommi@webrtc.org DCHECK(start_thread_->IsCurrent()); 407e07710cc91b3dccd7fea7df3d99c304f419babdatommi@webrtc.org // Signal down stream components on captured frame. 408e07710cc91b3dccd7fea7df3d99c304f419babdatommi@webrtc.org // The CapturedFrame class doesn't support planes. We have to ExtractBuffer 409e07710cc91b3dccd7fea7df3d99c304f419babdatommi@webrtc.org // to one block for it. 410e07710cc91b3dccd7fea7df3d99c304f419babdatommi@webrtc.org size_t length = 411e07710cc91b3dccd7fea7df3d99c304f419babdatommi@webrtc.org webrtc::CalcBufferSize(webrtc::kI420, frame->width(), frame->height()); 412e07710cc91b3dccd7fea7df3d99c304f419babdatommi@webrtc.org capture_buffer_.resize(length); 413e07710cc91b3dccd7fea7df3d99c304f419babdatommi@webrtc.org // TODO(magjed): Refactor the WebRtcCapturedFrame to avoid memory copy or 414e07710cc91b3dccd7fea7df3d99c304f419babdatommi@webrtc.org // take over ownership of the buffer held by |frame| if that's possible. 415e07710cc91b3dccd7fea7df3d99c304f419babdatommi@webrtc.org webrtc::ExtractBuffer(*frame, length, &capture_buffer_[0]); 416e07710cc91b3dccd7fea7df3d99c304f419babdatommi@webrtc.org WebRtcCapturedFrame webrtc_frame(*frame, &capture_buffer_[0], length); 417e07710cc91b3dccd7fea7df3d99c304f419babdatommi@webrtc.org SignalFrameCaptured(this, &webrtc_frame); 418e07710cc91b3dccd7fea7df3d99c304f419babdatommi@webrtc.org} 419e07710cc91b3dccd7fea7df3d99c304f419babdatommi@webrtc.org 42028e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org// WebRtcCapturedFrame 42128e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.orgWebRtcCapturedFrame::WebRtcCapturedFrame(const webrtc::I420VideoFrame& sample, 42228e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org void* buffer, 4234591fbd09f9cb6e83433c49a12dd8524c2806502pkasting@chromium.org size_t length) { 42428e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org width = sample.width(); 42528e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org height = sample.height(); 42628e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org fourcc = FOURCC_I420; 42728e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org // TODO(hellner): Support pixel aspect ratio (for OSX). 42828e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org pixel_width = 1; 42928e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org pixel_height = 1; 43028e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org // Convert units from VideoFrame RenderTimeMs to CapturedFrame (nanoseconds). 431d4e598d57aed714a599444a7eab5e8fdde52a950buildbot@webrtc.org elapsed_time = sample.render_time_ms() * rtc::kNumNanosecsPerMillisec; 43228e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org time_stamp = elapsed_time; 4334591fbd09f9cb6e83433c49a12dd8524c2806502pkasting@chromium.org data_size = rtc::checked_cast<uint32>(length); 43428e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org data = buffer; 4351226e926e6104322d9b99026b98f515cb4d40fd4guoweis@webrtc.org rotation = sample.rotation(); 43628e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org} 43728e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org 43828e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org} // namespace cricket 43928e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org 44028e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org#endif // HAVE_WEBRTC_VIDEO 441