webrtcvideocapturer.cc revision 4591fbd09f9cb6e83433c49a12dd8524c2806502
128e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org// libjingle
228e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org// Copyright 2011 Google Inc.
328e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org//
428e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org// Redistribution and use in source and binary forms, with or without
528e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org// modification, are permitted provided that the following conditions are met:
628e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org//
728e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org//  1. Redistributions of source code must retain the above copyright notice,
828e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org//     this list of conditions and the following disclaimer.
928e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org//  2. Redistributions in binary form must reproduce the above copyright notice,
1028e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org//     this list of conditions and the following disclaimer in the documentation
1128e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org//     and/or other materials provided with the distribution.
1228e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org//  3. The name of the author may not be used to endorse or promote products
1328e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org//     derived from this software without specific prior written permission.
1428e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org//
1528e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org// THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
1628e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org// WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
1728e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
1828e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org// EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
1928e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
2028e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
2128e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org// OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
2228e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org// WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
2328e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org// OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
2428e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org// ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
2528e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org//
2628e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org// Implementation of class WebRtcVideoCapturer.
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"
37d4e598d57aed714a599444a7eab5e8fdde52a950buildbot@webrtc.org#include "webrtc/base/criticalsection.h"
38d4e598d57aed714a599444a7eab5e8fdde52a950buildbot@webrtc.org#include "webrtc/base/logging.h"
394591fbd09f9cb6e83433c49a12dd8524c2806502pkasting@chromium.org#include "webrtc/base/safe_conversions.h"
40d4e598d57aed714a599444a7eab5e8fdde52a950buildbot@webrtc.org#include "webrtc/base/thread.h"
41d4e598d57aed714a599444a7eab5e8fdde52a950buildbot@webrtc.org#include "webrtc/base/timeutils.h"
4228e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org
43d4e598d57aed714a599444a7eab5e8fdde52a950buildbot@webrtc.org#include "webrtc/base/win32.h"  // Need this to #include the impl files.
4428e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org#include "webrtc/modules/video_capture/include/video_capture_factory.h"
4528e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org
4628e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.orgnamespace cricket {
4728e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org
4828e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.orgstruct kVideoFourCCEntry {
4928e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  uint32 fourcc;
5028e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  webrtc::RawVideoType webrtc_type;
5128e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org};
5228e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org
5328e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org// This indicates our format preferences and defines a mapping between
5428e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org// webrtc::RawVideoType (from video_capture_defines.h) to our FOURCCs.
5528e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.orgstatic kVideoFourCCEntry kSupportedFourCCs[] = {
5628e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  { FOURCC_I420, webrtc::kVideoI420 },   // 12 bpp, no conversion.
5728e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  { FOURCC_YV12, webrtc::kVideoYV12 },   // 12 bpp, no conversion.
5828e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  { FOURCC_YUY2, webrtc::kVideoYUY2 },   // 16 bpp, fast conversion.
5928e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  { FOURCC_UYVY, webrtc::kVideoUYVY },   // 16 bpp, fast conversion.
60fa5fcd671de2f6db6249c3cdd2908f4fc39d84a0buildbot@webrtc.org  { FOURCC_NV12, webrtc::kVideoNV12 },   // 12 bpp, fast conversion.
61fa5fcd671de2f6db6249c3cdd2908f4fc39d84a0buildbot@webrtc.org  { FOURCC_NV21, webrtc::kVideoNV21 },   // 12 bpp, fast conversion.
6228e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  { FOURCC_MJPG, webrtc::kVideoMJPEG },  // compressed, slow conversion.
6328e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  { FOURCC_ARGB, webrtc::kVideoARGB },   // 32 bpp, slow conversion.
6428e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  { FOURCC_24BG, webrtc::kVideoRGB24 },  // 24 bpp, slow conversion.
6528e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org};
6628e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org
6728e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.orgclass WebRtcVcmFactory : public WebRtcVcmFactoryInterface {
6828e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org public:
6928e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  virtual webrtc::VideoCaptureModule* Create(int id, const char* device) {
7028e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    return webrtc::VideoCaptureFactory::Create(id, device);
7128e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  }
7228e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  virtual webrtc::VideoCaptureModule::DeviceInfo* CreateDeviceInfo(int id) {
7328e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    return webrtc::VideoCaptureFactory::CreateDeviceInfo(id);
7428e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  }
7528e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  virtual void DestroyDeviceInfo(webrtc::VideoCaptureModule::DeviceInfo* info) {
7628e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    delete info;
7728e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  }
7828e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org};
7928e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org
8028e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.orgstatic bool CapabilityToFormat(const webrtc::VideoCaptureCapability& cap,
8128e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org                               VideoFormat* format) {
8228e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  uint32 fourcc = 0;
8328e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  for (size_t i = 0; i < ARRAY_SIZE(kSupportedFourCCs); ++i) {
8428e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    if (kSupportedFourCCs[i].webrtc_type == cap.rawType) {
8528e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org      fourcc = kSupportedFourCCs[i].fourcc;
8628e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org      break;
8728e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    }
8828e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  }
8928e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  if (fourcc == 0) {
9028e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    return false;
9128e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  }
9228e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org
9328e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  format->fourcc = fourcc;
9428e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  format->width = cap.width;
9528e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  format->height = cap.height;
9628e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  format->interval = VideoFormat::FpsToInterval(cap.maxFPS);
9728e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  return true;
9828e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org}
9928e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org
10028e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.orgstatic bool FormatToCapability(const VideoFormat& format,
10128e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org                               webrtc::VideoCaptureCapability* cap) {
10228e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  webrtc::RawVideoType webrtc_type = webrtc::kVideoUnknown;
10328e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  for (size_t i = 0; i < ARRAY_SIZE(kSupportedFourCCs); ++i) {
10428e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    if (kSupportedFourCCs[i].fourcc == format.fourcc) {
10528e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org      webrtc_type = kSupportedFourCCs[i].webrtc_type;
10628e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org      break;
10728e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    }
10828e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  }
10928e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  if (webrtc_type == webrtc::kVideoUnknown) {
11028e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    return false;
11128e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  }
11228e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org
11328e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  cap->width = format.width;
11428e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  cap->height = format.height;
11528e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  cap->maxFPS = VideoFormat::IntervalToFps(format.interval);
11628e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  cap->expectedCaptureDelay = 0;
11728e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  cap->rawType = webrtc_type;
11828e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  cap->codecType = webrtc::kVideoCodecUnknown;
11928e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  cap->interlaced = false;
12028e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  return true;
12128e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org}
12228e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org
12328e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org///////////////////////////////////////////////////////////////////////////
12428e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org// Implementation of class WebRtcVideoCapturer
12528e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org///////////////////////////////////////////////////////////////////////////
12628e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org
12728e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.orgWebRtcVideoCapturer::WebRtcVideoCapturer()
12828e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    : factory_(new WebRtcVcmFactory),
12928e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org      module_(NULL),
13028e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org      captured_frames_(0) {
1314f0d401faecf5d8a4c82e6e2223651ef13ad8e31buildbot@webrtc.org  set_frame_factory(new WebRtcVideoFrameFactory());
13228e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org}
13328e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org
13428e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.orgWebRtcVideoCapturer::WebRtcVideoCapturer(WebRtcVcmFactoryInterface* factory)
13528e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    : factory_(factory),
13628e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org      module_(NULL),
13728e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org      captured_frames_(0) {
1384f0d401faecf5d8a4c82e6e2223651ef13ad8e31buildbot@webrtc.org  set_frame_factory(new WebRtcVideoFrameFactory());
13928e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org}
14028e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org
14128e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.orgWebRtcVideoCapturer::~WebRtcVideoCapturer() {
14228e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  if (module_) {
14328e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    module_->Release();
14428e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  }
14528e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org}
14628e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org
14728e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.orgbool WebRtcVideoCapturer::Init(const Device& device) {
14828e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  if (module_) {
14928e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    LOG(LS_ERROR) << "The capturer is already initialized";
15028e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    return false;
15128e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  }
15228e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org
15328e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  webrtc::VideoCaptureModule::DeviceInfo* info = factory_->CreateDeviceInfo(0);
15428e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  if (!info) {
15528e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    return false;
15628e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  }
15728e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org
15828e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  // Find the desired camera, by name.
15928e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  // In the future, comparing IDs will be more robust.
16028e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  // TODO(juberti): Figure what's needed to allow this.
16128e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  int num_cams = info->NumberOfDevices();
16228e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  char vcm_id[256] = "";
16328e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  bool found = false;
16428e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  for (int index = 0; index < num_cams; ++index) {
16528e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    char vcm_name[256];
16628e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    if (info->GetDeviceName(index, vcm_name, ARRAY_SIZE(vcm_name),
16728e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org                            vcm_id, ARRAY_SIZE(vcm_id)) != -1) {
16828e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org      if (device.name == reinterpret_cast<char*>(vcm_name)) {
16928e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org        found = true;
17028e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org        break;
17128e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org      }
17228e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    }
17328e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  }
17428e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  if (!found) {
17528e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    LOG(LS_WARNING) << "Failed to find capturer for id: " << device.id;
17628e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    factory_->DestroyDeviceInfo(info);
17728e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    return false;
17828e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  }
17928e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org
18028e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  // Enumerate the supported formats.
18128e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  // TODO(juberti): Find out why this starts/stops the camera...
18228e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  std::vector<VideoFormat> supported;
18328e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  int32_t num_caps = info->NumberOfCapabilities(vcm_id);
18428e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  for (int32_t i = 0; i < num_caps; ++i) {
18528e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    webrtc::VideoCaptureCapability cap;
18628e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    if (info->GetCapability(vcm_id, i, cap) != -1) {
18728e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org      VideoFormat format;
18828e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org      if (CapabilityToFormat(cap, &format)) {
18928e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org        supported.push_back(format);
19028e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org      } else {
19128e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org        LOG(LS_WARNING) << "Ignoring unsupported WebRTC capture format "
19228e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org                        << cap.rawType;
19328e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org      }
19428e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    }
19528e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  }
19628e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  factory_->DestroyDeviceInfo(info);
197d3d6bce9edfb708aee93518e9d5a4a222a35a935henrike@webrtc.org// TODO(fischman): Remove the following check
198d3d6bce9edfb708aee93518e9d5a4a222a35a935henrike@webrtc.org// when capabilities for iOS are implemented
199d3d6bce9edfb708aee93518e9d5a4a222a35a935henrike@webrtc.org// https://code.google.com/p/webrtc/issues/detail?id=2968
200d3d6bce9edfb708aee93518e9d5a4a222a35a935henrike@webrtc.org#if !defined(IOS)
20128e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  if (supported.empty()) {
20228e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    LOG(LS_ERROR) << "Failed to find usable formats for id: " << device.id;
20328e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    return false;
20428e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  }
205d3d6bce9edfb708aee93518e9d5a4a222a35a935henrike@webrtc.org#endif
20628e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  module_ = factory_->Create(0, vcm_id);
20728e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  if (!module_) {
20828e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    LOG(LS_ERROR) << "Failed to create capturer for id: " << device.id;
20928e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    return false;
21028e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  }
21128e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org
21228e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  // It is safe to change member attributes now.
21328e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  module_->AddRef();
21428e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  SetId(device.id);
21528e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  SetSupportedFormats(supported);
21628e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  return true;
21728e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org}
21828e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org
21928e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.orgbool WebRtcVideoCapturer::Init(webrtc::VideoCaptureModule* module) {
22028e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  if (module_) {
22128e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    LOG(LS_ERROR) << "The capturer is already initialized";
22228e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    return false;
22328e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  }
22428e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  if (!module) {
22528e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    LOG(LS_ERROR) << "Invalid VCM supplied";
22628e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    return false;
22728e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  }
22828e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  // TODO(juberti): Set id and formats.
22928e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  (module_ = module)->AddRef();
23028e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  return true;
23128e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org}
23228e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org
23328e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.orgbool WebRtcVideoCapturer::GetBestCaptureFormat(const VideoFormat& desired,
23428e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org                                               VideoFormat* best_format) {
23528e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  if (!best_format) {
23628e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    return false;
23728e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  }
23828e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org
23928e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  if (!VideoCapturer::GetBestCaptureFormat(desired, best_format)) {
24028e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    // We maybe using a manually injected VCM which doesn't support enum.
24128e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    // Use the desired format as the best format.
24228e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    best_format->width = desired.width;
24328e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    best_format->height = desired.height;
24428e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    best_format->fourcc = FOURCC_I420;
24528e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    best_format->interval = desired.interval;
24628e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    LOG(LS_INFO) << "Failed to find best capture format,"
24728e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org                 << " fall back to the requested format "
24828e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org                 << best_format->ToString();
24928e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  }
25028e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  return true;
25128e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org}
25228e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org
25328e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.orgCaptureState WebRtcVideoCapturer::Start(const VideoFormat& capture_format) {
25428e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  if (!module_) {
25528e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    LOG(LS_ERROR) << "The capturer has not been initialized";
25628e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    return CS_NO_DEVICE;
25728e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  }
25828e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org
259d4e598d57aed714a599444a7eab5e8fdde52a950buildbot@webrtc.org  rtc::CritScope cs(&critical_section_stopping_);
26028e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  // TODO(hellner): weird to return failure when it is in fact actually running.
26128e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  if (IsRunning()) {
26228e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    LOG(LS_ERROR) << "The capturer is already running";
26328e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    return CS_FAILED;
26428e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  }
26528e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org
26628e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  SetCaptureFormat(&capture_format);
26728e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org
26828e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  webrtc::VideoCaptureCapability cap;
26928e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  if (!FormatToCapability(capture_format, &cap)) {
27028e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    LOG(LS_ERROR) << "Invalid capture format specified";
27128e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    return CS_FAILED;
27228e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  }
27328e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org
27428e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  std::string camera_id(GetId());
275d4e598d57aed714a599444a7eab5e8fdde52a950buildbot@webrtc.org  uint32 start = rtc::Time();
2767433a088d2e97993266b66c102b0866aa90b4424mallinath@webrtc.org  module_->RegisterCaptureDataCallback(*this);
2777433a088d2e97993266b66c102b0866aa90b4424mallinath@webrtc.org  if (module_->StartCapture(cap) != 0) {
27828e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    LOG(LS_ERROR) << "Camera '" << camera_id << "' failed to start";
27928e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    return CS_FAILED;
28028e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  }
28128e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org
28228e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  LOG(LS_INFO) << "Camera '" << camera_id << "' started with format "
28328e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org               << capture_format.ToString() << ", elapsed time "
284d4e598d57aed714a599444a7eab5e8fdde52a950buildbot@webrtc.org               << rtc::TimeSince(start) << " ms";
28528e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org
28628e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  captured_frames_ = 0;
28728e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  SetCaptureState(CS_RUNNING);
28828e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  return CS_STARTING;
28928e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org}
29028e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org
291f6d6ed0c66457170be3f3b2bc214cd7141e441a4wu@webrtc.org// Critical section blocks Stop from shutting down during callbacks from capture
292f6d6ed0c66457170be3f3b2bc214cd7141e441a4wu@webrtc.org// thread to OnIncomingCapturedFrame. Note that the crit is try-locked in
293f6d6ed0c66457170be3f3b2bc214cd7141e441a4wu@webrtc.org// OnFrameCaptured, as the lock ordering between this and the system component
294f6d6ed0c66457170be3f3b2bc214cd7141e441a4wu@webrtc.org// controlling the camera is reversed: system frame -> OnIncomingCapturedFrame;
295f6d6ed0c66457170be3f3b2bc214cd7141e441a4wu@webrtc.org// Stop -> system stop camera).
29628e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.orgvoid WebRtcVideoCapturer::Stop() {
297d4e598d57aed714a599444a7eab5e8fdde52a950buildbot@webrtc.org  rtc::CritScope cs(&critical_section_stopping_);
29828e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  if (IsRunning()) {
299d4e598d57aed714a599444a7eab5e8fdde52a950buildbot@webrtc.org    rtc::Thread::Current()->Clear(this);
30028e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    module_->StopCapture();
30128e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    module_->DeRegisterCaptureDataCallback();
30228e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org
30328e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    // TODO(juberti): Determine if the VCM exposes any drop stats we can use.
30428e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    double drop_ratio = 0.0;
30528e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    std::string camera_id(GetId());
30628e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    LOG(LS_INFO) << "Camera '" << camera_id << "' stopped after capturing "
30728e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org                 << captured_frames_ << " frames and dropping "
30828e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org                 << drop_ratio << "%";
30928e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  }
31028e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  SetCaptureFormat(NULL);
31128e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org}
31228e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org
31328e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.orgbool WebRtcVideoCapturer::IsRunning() {
31428e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  return (module_ != NULL && module_->CaptureStarted());
31528e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org}
31628e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org
31728e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.orgbool WebRtcVideoCapturer::GetPreferredFourccs(
31828e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    std::vector<uint32>* fourccs) {
31928e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  if (!fourccs) {
32028e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    return false;
32128e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  }
32228e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org
32328e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  fourccs->clear();
32428e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  for (size_t i = 0; i < ARRAY_SIZE(kSupportedFourCCs); ++i) {
32528e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    fourccs->push_back(kSupportedFourCCs[i].fourcc);
32628e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  }
32728e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  return true;
32828e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org}
32928e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org
33028e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.orgvoid WebRtcVideoCapturer::OnIncomingCapturedFrame(const int32_t id,
33128e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    webrtc::I420VideoFrame& sample) {
332f6d6ed0c66457170be3f3b2bc214cd7141e441a4wu@webrtc.org  // This would be a normal CritScope, except that it's possible that:
333f6d6ed0c66457170be3f3b2bc214cd7141e441a4wu@webrtc.org  // (1) whatever system component producing this frame has taken a lock, and
334f6d6ed0c66457170be3f3b2bc214cd7141e441a4wu@webrtc.org  // (2) Stop() probably calls back into that system component, which may take
335f6d6ed0c66457170be3f3b2bc214cd7141e441a4wu@webrtc.org  // the same lock. Due to the reversed order, we have to try-lock in order to
336f6d6ed0c66457170be3f3b2bc214cd7141e441a4wu@webrtc.org  // avoid a potential deadlock. Besides, if we can't enter because we're
337f6d6ed0c66457170be3f3b2bc214cd7141e441a4wu@webrtc.org  // stopping, we may as well drop the frame.
338d4e598d57aed714a599444a7eab5e8fdde52a950buildbot@webrtc.org  rtc::TryCritScope cs(&critical_section_stopping_);
339f6d6ed0c66457170be3f3b2bc214cd7141e441a4wu@webrtc.org  if (!cs.locked() || !IsRunning()) {
340f6d6ed0c66457170be3f3b2bc214cd7141e441a4wu@webrtc.org    // Capturer has been stopped or is in the process of stopping.
341f6d6ed0c66457170be3f3b2bc214cd7141e441a4wu@webrtc.org    return;
342f6d6ed0c66457170be3f3b2bc214cd7141e441a4wu@webrtc.org  }
34328e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org
34428e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  ++captured_frames_;
34528e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  // Log the size and pixel aspect ratio of the first captured frame.
34628e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  if (1 == captured_frames_) {
34728e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org    LOG(LS_INFO) << "Captured frame size "
34828e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org                 << sample.width() << "x" << sample.height()
34928e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org                 << ". Expected format " << GetCaptureFormat()->ToString();
35028e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  }
35128e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org
35228e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  // Signal down stream components on captured frame.
35328e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  // The CapturedFrame class doesn't support planes. We have to ExtractBuffer
35428e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  // to one block for it.
3554591fbd09f9cb6e83433c49a12dd8524c2806502pkasting@chromium.org  size_t length =
3564591fbd09f9cb6e83433c49a12dd8524c2806502pkasting@chromium.org      webrtc::CalcBufferSize(webrtc::kI420, sample.width(), sample.height());
35716d6254e8c6c865ca65cc943e03fa635dc5c6a63wu@webrtc.org  capture_buffer_.resize(length);
35816d6254e8c6c865ca65cc943e03fa635dc5c6a63wu@webrtc.org  // TODO(ronghuawu): Refactor the WebRtcCapturedFrame to avoid memory copy.
35916d6254e8c6c865ca65cc943e03fa635dc5c6a63wu@webrtc.org  webrtc::ExtractBuffer(sample, length, &capture_buffer_[0]);
36016d6254e8c6c865ca65cc943e03fa635dc5c6a63wu@webrtc.org  WebRtcCapturedFrame frame(sample, &capture_buffer_[0], length);
36128e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  SignalFrameCaptured(this, &frame);
36228e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org}
36328e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org
36428e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.orgvoid WebRtcVideoCapturer::OnCaptureDelayChanged(const int32_t id,
36528e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org                                                const int32_t delay) {
36628e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  LOG(LS_INFO) << "Capture delay changed to " << delay << " ms";
36728e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org}
36828e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org
36928e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org// WebRtcCapturedFrame
37028e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.orgWebRtcCapturedFrame::WebRtcCapturedFrame(const webrtc::I420VideoFrame& sample,
37128e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org                                         void* buffer,
3724591fbd09f9cb6e83433c49a12dd8524c2806502pkasting@chromium.org                                         size_t length) {
37328e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  width = sample.width();
37428e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  height = sample.height();
37528e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  fourcc = FOURCC_I420;
37628e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  // TODO(hellner): Support pixel aspect ratio (for OSX).
37728e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  pixel_width = 1;
37828e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  pixel_height = 1;
37928e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  // Convert units from VideoFrame RenderTimeMs to CapturedFrame (nanoseconds).
380d4e598d57aed714a599444a7eab5e8fdde52a950buildbot@webrtc.org  elapsed_time = sample.render_time_ms() * rtc::kNumNanosecsPerMillisec;
38128e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  time_stamp = elapsed_time;
3824591fbd09f9cb6e83433c49a12dd8524c2806502pkasting@chromium.org  data_size = rtc::checked_cast<uint32>(length);
38328e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org  data = buffer;
38428e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org}
38528e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org
38628e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org}  // namespace cricket
38728e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org
38828e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org#endif  // HAVE_WEBRTC_VIDEO
389