128e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org/* 228e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org * libjingle 35f93d0a140515e3b8cdd1b9a4c6f5871144e5deejlmiller@webrtc.org * Copyright 2012 Google Inc. 428e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org * 528e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org * Redistribution and use in source and binary forms, with or without 628e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org * modification, are permitted provided that the following conditions are met: 728e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org * 828e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org * 1. Redistributions of source code must retain the above copyright notice, 928e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org * this list of conditions and the following disclaimer. 1028e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org * 2. Redistributions in binary form must reproduce the above copyright notice, 1128e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org * this list of conditions and the following disclaimer in the documentation 1228e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org * and/or other materials provided with the distribution. 1328e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org * 3. The name of the author may not be used to endorse or promote products 1428e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org * derived from this software without specific prior written permission. 1528e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org * 1628e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED 1728e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 1828e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO 1928e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 2028e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 2128e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 2228e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 2328e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 2428e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 2528e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 2628e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org */ 2728e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org 28967bfff54d00f176a554bf9f955f14dde99f7bb9wu@webrtc.org#include "talk/app/webrtc/videosource.h" 2928e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org 3028e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org#include <vector> 313472dcd7b07f8e8fa4b0ac72a3821e4581e41ebbglaznev@webrtc.org#include <cstdlib> 3228e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org 3328e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org#include "talk/app/webrtc/mediaconstraintsinterface.h" 3428e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org#include "talk/session/media/channelmanager.h" 355237aaf243d29732f59557361b7a993c0a18cf0etfarina#include "webrtc/base/arraysize.h" 3628e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org 3728e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.orgusing cricket::CaptureState; 3828e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.orgusing webrtc::MediaConstraintsInterface; 3928e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.orgusing webrtc::MediaSourceInterface; 4028e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org 4128e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.orgnamespace { 4228e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org 4328e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.orgconst double kRoundingTruncation = 0.0005; 4428e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org 4528e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.orgenum { 4628e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org MSG_VIDEOCAPTURESTATECONNECT, 4728e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org MSG_VIDEOCAPTURESTATEDISCONNECT, 4828e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org MSG_VIDEOCAPTURESTATECHANGE, 4928e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org}; 5028e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org 5128e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org// Default resolution. If no constraint is specified, this is the resolution we 5228e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org// will use. 53967bfff54d00f176a554bf9f955f14dde99f7bb9wu@webrtc.orgstatic const cricket::VideoFormatPod kDefaultFormat = 5428e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org {640, 480, FPS_TO_INTERVAL(30), cricket::FOURCC_ANY}; 5528e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org 5628e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org// List of formats used if the camera doesn't support capability enumeration. 5728e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.orgstatic const cricket::VideoFormatPod kVideoFormats[] = { 5828e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org {1920, 1080, FPS_TO_INTERVAL(30), cricket::FOURCC_ANY}, 5928e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org {1280, 720, FPS_TO_INTERVAL(30), cricket::FOURCC_ANY}, 6028e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org {960, 720, FPS_TO_INTERVAL(30), cricket::FOURCC_ANY}, 6128e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org {640, 360, FPS_TO_INTERVAL(30), cricket::FOURCC_ANY}, 6228e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org {640, 480, FPS_TO_INTERVAL(30), cricket::FOURCC_ANY}, 6328e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org {320, 240, FPS_TO_INTERVAL(30), cricket::FOURCC_ANY}, 6428e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org {320, 180, FPS_TO_INTERVAL(30), cricket::FOURCC_ANY} 6528e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org}; 6628e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org 6728e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.orgMediaSourceInterface::SourceState 6828e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.orgGetReadyState(cricket::CaptureState state) { 6928e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org switch (state) { 7028e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org case cricket::CS_STARTING: 7128e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org return MediaSourceInterface::kInitializing; 7228e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org case cricket::CS_RUNNING: 7328e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org return MediaSourceInterface::kLive; 7428e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org case cricket::CS_FAILED: 7528e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org case cricket::CS_NO_DEVICE: 7628e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org case cricket::CS_STOPPED: 7728e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org return MediaSourceInterface::kEnded; 7828e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org case cricket::CS_PAUSED: 7928e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org return MediaSourceInterface::kMuted; 8028e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org default: 8128e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org ASSERT(false && "GetReadyState unknown state"); 8228e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org } 8328e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org return MediaSourceInterface::kEnded; 8428e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org} 8528e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org 8628e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.orgvoid SetUpperLimit(int new_limit, int* original_limit) { 8728e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org if (*original_limit < 0 || new_limit < *original_limit) 8828e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org *original_limit = new_limit; 8928e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org} 9028e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org 9128e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org// Updates |format_upper_limit| from |constraint|. 9228e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org// If constraint.maxFoo is smaller than format_upper_limit.foo, 9328e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org// set format_upper_limit.foo to constraint.maxFoo. 9428e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.orgvoid SetUpperLimitFromConstraint( 9528e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org const MediaConstraintsInterface::Constraint& constraint, 9628e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org cricket::VideoFormat* format_upper_limit) { 9728e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org if (constraint.key == MediaConstraintsInterface::kMaxWidth) { 98d4e598d57aed714a599444a7eab5e8fdde52a950buildbot@webrtc.org int value = rtc::FromString<int>(constraint.value); 9928e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org SetUpperLimit(value, &(format_upper_limit->width)); 10028e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org } else if (constraint.key == MediaConstraintsInterface::kMaxHeight) { 101d4e598d57aed714a599444a7eab5e8fdde52a950buildbot@webrtc.org int value = rtc::FromString<int>(constraint.value); 10228e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org SetUpperLimit(value, &(format_upper_limit->height)); 10328e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org } 10428e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org} 10528e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org 10628e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org// Fills |format_out| with the max width and height allowed by |constraints|. 10728e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.orgvoid FromConstraintsForScreencast( 10828e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org const MediaConstraintsInterface::Constraints& constraints, 10928e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org cricket::VideoFormat* format_out) { 11028e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org typedef MediaConstraintsInterface::Constraints::const_iterator 11128e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org ConstraintsIterator; 11228e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org 11328e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org cricket::VideoFormat upper_limit(-1, -1, 0, 0); 11428e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org for (ConstraintsIterator constraints_it = constraints.begin(); 11528e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org constraints_it != constraints.end(); ++constraints_it) 11628e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org SetUpperLimitFromConstraint(*constraints_it, &upper_limit); 11728e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org 11828e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org if (upper_limit.width >= 0) 11928e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org format_out->width = upper_limit.width; 12028e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org if (upper_limit.height >= 0) 12128e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org format_out->height = upper_limit.height; 12228e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org} 12328e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org 12428e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org// Returns true if |constraint| is fulfilled. |format_out| can differ from 12528e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org// |format_in| if the format is changed by the constraint. Ie - the frame rate 12628e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org// can be changed by setting maxFrameRate. 12728e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.orgbool NewFormatWithConstraints( 12828e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org const MediaConstraintsInterface::Constraint& constraint, 12928e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org const cricket::VideoFormat& format_in, 13028e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org bool mandatory, 13128e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org cricket::VideoFormat* format_out) { 13228e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org ASSERT(format_out != NULL); 13328e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org *format_out = format_in; 13428e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org 13528e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org if (constraint.key == MediaConstraintsInterface::kMinWidth) { 136d4e598d57aed714a599444a7eab5e8fdde52a950buildbot@webrtc.org int value = rtc::FromString<int>(constraint.value); 13728e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org return (value <= format_in.width); 13828e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org } else if (constraint.key == MediaConstraintsInterface::kMaxWidth) { 139d4e598d57aed714a599444a7eab5e8fdde52a950buildbot@webrtc.org int value = rtc::FromString<int>(constraint.value); 14028e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org return (value >= format_in.width); 14128e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org } else if (constraint.key == MediaConstraintsInterface::kMinHeight) { 142d4e598d57aed714a599444a7eab5e8fdde52a950buildbot@webrtc.org int value = rtc::FromString<int>(constraint.value); 14328e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org return (value <= format_in.height); 14428e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org } else if (constraint.key == MediaConstraintsInterface::kMaxHeight) { 145d4e598d57aed714a599444a7eab5e8fdde52a950buildbot@webrtc.org int value = rtc::FromString<int>(constraint.value); 14628e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org return (value >= format_in.height); 14728e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org } else if (constraint.key == MediaConstraintsInterface::kMinFrameRate) { 148d4e598d57aed714a599444a7eab5e8fdde52a950buildbot@webrtc.org int value = rtc::FromString<int>(constraint.value); 14928e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org return (value <= cricket::VideoFormat::IntervalToFps(format_in.interval)); 15028e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org } else if (constraint.key == MediaConstraintsInterface::kMaxFrameRate) { 151d4e598d57aed714a599444a7eab5e8fdde52a950buildbot@webrtc.org int value = rtc::FromString<int>(constraint.value); 15228e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org if (value == 0) { 15328e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org if (mandatory) { 15428e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org // TODO(ronghuawu): Convert the constraint value to float when sub-1fps 15528e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org // is supported by the capturer. 15628e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org return false; 15728e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org } else { 15828e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org value = 1; 15928e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org } 16028e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org } 1616ec1f921b1186127467393dc82c0a786e0de4e2bMagnus Jedvert if (value <= cricket::VideoFormat::IntervalToFps(format_in.interval)) 16228e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org format_out->interval = cricket::VideoFormat::FpsToInterval(value); 1636ec1f921b1186127467393dc82c0a786e0de4e2bMagnus Jedvert return true; 16428e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org } else if (constraint.key == MediaConstraintsInterface::kMinAspectRatio) { 165d4e598d57aed714a599444a7eab5e8fdde52a950buildbot@webrtc.org double value = rtc::FromString<double>(constraint.value); 16628e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org // The aspect ratio in |constraint.value| has been converted to a string and 16728e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org // back to a double, so it may have a rounding error. 16828e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org // E.g if the value 1/3 is converted to a string, the string will not have 16928e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org // infinite length. 17028e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org // We add a margin of 0.0005 which is high enough to detect the same aspect 17128e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org // ratio but small enough to avoid matching wrong aspect ratios. 17228e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org double ratio = static_cast<double>(format_in.width) / format_in.height; 17328e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org return (value <= ratio + kRoundingTruncation); 17428e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org } else if (constraint.key == MediaConstraintsInterface::kMaxAspectRatio) { 175d4e598d57aed714a599444a7eab5e8fdde52a950buildbot@webrtc.org double value = rtc::FromString<double>(constraint.value); 17628e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org double ratio = static_cast<double>(format_in.width) / format_in.height; 17728e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org // Subtract 0.0005 to avoid rounding problems. Same as above. 17828e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org const double kRoundingTruncation = 0.0005; 17928e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org return (value >= ratio - kRoundingTruncation); 18081ddc78536585cb960699ed6e3c1a698645deb1ebuildbot@webrtc.org } else if (constraint.key == MediaConstraintsInterface::kNoiseReduction) { 18128e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org // These are actually options, not constraints, so they can be satisfied 18228e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org // regardless of the format. 18328e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org return true; 18428e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org } 18528e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org LOG(LS_WARNING) << "Found unknown MediaStream constraint. Name:" 18628e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org << constraint.key << " Value:" << constraint.value; 18728e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org return false; 18828e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org} 18928e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org 19028e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org// Removes cricket::VideoFormats from |formats| that don't meet |constraint|. 19128e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.orgvoid FilterFormatsByConstraint( 19228e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org const MediaConstraintsInterface::Constraint& constraint, 19328e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org bool mandatory, 19428e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org std::vector<cricket::VideoFormat>* formats) { 19528e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org std::vector<cricket::VideoFormat>::iterator format_it = 19628e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org formats->begin(); 19728e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org while (format_it != formats->end()) { 19828e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org // Modify the format_it to fulfill the constraint if possible. 19928e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org // Delete it otherwise. 20028e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org if (!NewFormatWithConstraints(constraint, (*format_it), 20128e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org mandatory, &(*format_it))) { 20228e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org format_it = formats->erase(format_it); 20328e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org } else { 20428e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org ++format_it; 20528e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org } 20628e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org } 20728e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org} 20828e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org 20928e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org// Returns a vector of cricket::VideoFormat that best match |constraints|. 21028e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.orgstd::vector<cricket::VideoFormat> FilterFormats( 21128e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org const MediaConstraintsInterface::Constraints& mandatory, 21228e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org const MediaConstraintsInterface::Constraints& optional, 21328e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org const std::vector<cricket::VideoFormat>& supported_formats) { 21428e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org typedef MediaConstraintsInterface::Constraints::const_iterator 21528e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org ConstraintsIterator; 21628e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org std::vector<cricket::VideoFormat> candidates = supported_formats; 21728e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org 21828e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org for (ConstraintsIterator constraints_it = mandatory.begin(); 21928e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org constraints_it != mandatory.end(); ++constraints_it) 22028e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org FilterFormatsByConstraint(*constraints_it, true, &candidates); 22128e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org 22228e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org if (candidates.size() == 0) 22328e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org return candidates; 22428e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org 22528e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org // Ok - all mandatory checked and we still have a candidate. 22628e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org // Let's try filtering using the optional constraints. 22728e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org for (ConstraintsIterator constraints_it = optional.begin(); 22828e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org constraints_it != optional.end(); ++constraints_it) { 22928e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org std::vector<cricket::VideoFormat> current_candidates = candidates; 23028e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org FilterFormatsByConstraint(*constraints_it, false, ¤t_candidates); 23128e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org if (current_candidates.size() > 0) { 23228e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org candidates = current_candidates; 23328e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org } 23428e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org } 23528e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org 23628e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org // We have done as good as we can to filter the supported resolutions. 23728e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org return candidates; 23828e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org} 23928e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org 24028e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org// Find the format that best matches the default video size. 24128e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org// Constraints are optional and since the performance of a video call 24228e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org// might be bad due to bitrate limitations, CPU, and camera performance, 24328e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org// it is better to select a resolution that is as close as possible to our 24428e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org// default and still meets the contraints. 24528e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.orgconst cricket::VideoFormat& GetBestCaptureFormat( 24628e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org const std::vector<cricket::VideoFormat>& formats) { 24728e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org ASSERT(formats.size() > 0); 24828e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org 249967bfff54d00f176a554bf9f955f14dde99f7bb9wu@webrtc.org int default_area = kDefaultFormat.width * kDefaultFormat.height; 25028e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org 25128e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org std::vector<cricket::VideoFormat>::const_iterator it = formats.begin(); 25228e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org std::vector<cricket::VideoFormat>::const_iterator best_it = formats.begin(); 2533472dcd7b07f8e8fa4b0ac72a3821e4581e41ebbglaznev@webrtc.org int best_diff_area = std::abs(default_area - it->width * it->height); 2540c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boström int64_t best_diff_interval = kDefaultFormat.interval; 25528e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org for (; it != formats.end(); ++it) { 2563472dcd7b07f8e8fa4b0ac72a3821e4581e41ebbglaznev@webrtc.org int diff_area = std::abs(default_area - it->width * it->height); 2570c4e06b4c6107a1b94f764e279e4fb4161e905b0Peter Boström int64_t diff_interval = std::abs(kDefaultFormat.interval - it->interval); 2583472dcd7b07f8e8fa4b0ac72a3821e4581e41ebbglaznev@webrtc.org if (diff_area < best_diff_area || 2593472dcd7b07f8e8fa4b0ac72a3821e4581e41ebbglaznev@webrtc.org (diff_area == best_diff_area && diff_interval < best_diff_interval)) { 2603472dcd7b07f8e8fa4b0ac72a3821e4581e41ebbglaznev@webrtc.org best_diff_area = diff_area; 2613472dcd7b07f8e8fa4b0ac72a3821e4581e41ebbglaznev@webrtc.org best_diff_interval = diff_interval; 26228e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org best_it = it; 26328e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org } 26428e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org } 26528e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org return *best_it; 26628e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org} 26728e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org 26828e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org// Set |option| to the highest-priority value of |key| in the constraints. 26928e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org// Return false if the key is mandatory, and the value is invalid. 27028e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.orgbool ExtractOption(const MediaConstraintsInterface* all_constraints, 271102c6a61bc0b42dc0956d013530fc0213b7e881bkwiberg const std::string& key, 272be57983f4bd875c39a229bab5112b32dad004057Karl Wiberg rtc::Optional<bool>* option) { 27328e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org size_t mandatory = 0; 27428e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org bool value; 27528e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org if (FindConstraint(all_constraints, key, &value, &mandatory)) { 276be57983f4bd875c39a229bab5112b32dad004057Karl Wiberg *option = rtc::Optional<bool>(value); 27728e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org return true; 27828e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org } 27928e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org 28028e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org return mandatory == 0; 28128e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org} 28228e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org 28328e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org// Search |all_constraints| for known video options. Apply all options that are 28428e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org// found with valid values, and return false if any mandatory video option was 28528e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org// found with an invalid value. 28628e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.orgbool ExtractVideoOptions(const MediaConstraintsInterface* all_constraints, 28728e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org cricket::VideoOptions* options) { 28828e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org bool all_valid = true; 28928e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org 29028e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org all_valid &= ExtractOption(all_constraints, 29128e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org MediaConstraintsInterface::kNoiseReduction, 29228e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org &(options->video_noise_reduction)); 29328e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org 29428e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org return all_valid; 29528e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org} 29628e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org 297967bfff54d00f176a554bf9f955f14dde99f7bb9wu@webrtc.orgclass FrameInputWrapper : public cricket::VideoRenderer { 298967bfff54d00f176a554bf9f955f14dde99f7bb9wu@webrtc.org public: 299967bfff54d00f176a554bf9f955f14dde99f7bb9wu@webrtc.org explicit FrameInputWrapper(cricket::VideoCapturer* capturer) 300967bfff54d00f176a554bf9f955f14dde99f7bb9wu@webrtc.org : capturer_(capturer) { 301967bfff54d00f176a554bf9f955f14dde99f7bb9wu@webrtc.org ASSERT(capturer_ != NULL); 302967bfff54d00f176a554bf9f955f14dde99f7bb9wu@webrtc.org } 303967bfff54d00f176a554bf9f955f14dde99f7bb9wu@webrtc.org 304967bfff54d00f176a554bf9f955f14dde99f7bb9wu@webrtc.org virtual ~FrameInputWrapper() {} 305967bfff54d00f176a554bf9f955f14dde99f7bb9wu@webrtc.org 306967bfff54d00f176a554bf9f955f14dde99f7bb9wu@webrtc.org // VideoRenderer implementation. 30714665ff7d4024d07e58622f498b23fd980001871kjellander@webrtc.org bool RenderFrame(const cricket::VideoFrame* frame) override { 308967bfff54d00f176a554bf9f955f14dde99f7bb9wu@webrtc.org if (!capturer_->IsRunning()) { 309967bfff54d00f176a554bf9f955f14dde99f7bb9wu@webrtc.org return true; 310967bfff54d00f176a554bf9f955f14dde99f7bb9wu@webrtc.org } 311967bfff54d00f176a554bf9f955f14dde99f7bb9wu@webrtc.org 312967bfff54d00f176a554bf9f955f14dde99f7bb9wu@webrtc.org // This signal will be made on media engine render thread. The clients 313967bfff54d00f176a554bf9f955f14dde99f7bb9wu@webrtc.org // of this signal should have no assumptions on what thread this signal 314967bfff54d00f176a554bf9f955f14dde99f7bb9wu@webrtc.org // come from. 315967bfff54d00f176a554bf9f955f14dde99f7bb9wu@webrtc.org capturer_->SignalVideoFrame(capturer_, frame); 316967bfff54d00f176a554bf9f955f14dde99f7bb9wu@webrtc.org return true; 317967bfff54d00f176a554bf9f955f14dde99f7bb9wu@webrtc.org } 318967bfff54d00f176a554bf9f955f14dde99f7bb9wu@webrtc.org 319967bfff54d00f176a554bf9f955f14dde99f7bb9wu@webrtc.org private: 320967bfff54d00f176a554bf9f955f14dde99f7bb9wu@webrtc.org cricket::VideoCapturer* capturer_; 321967bfff54d00f176a554bf9f955f14dde99f7bb9wu@webrtc.org 3223c089d751ede283e21e186885eaf705c3257ccd2henrikg RTC_DISALLOW_COPY_AND_ASSIGN(FrameInputWrapper); 323967bfff54d00f176a554bf9f955f14dde99f7bb9wu@webrtc.org}; 324967bfff54d00f176a554bf9f955f14dde99f7bb9wu@webrtc.org 32528e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org} // anonymous namespace 32628e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org 32728e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.orgnamespace webrtc { 32828e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org 329d4e598d57aed714a599444a7eab5e8fdde52a950buildbot@webrtc.orgrtc::scoped_refptr<VideoSource> VideoSource::Create( 33028e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org cricket::ChannelManager* channel_manager, 33128e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org cricket::VideoCapturer* capturer, 3326eca7e3c371383020095ba346e1ac70f38a8c0fdtommi const webrtc::MediaConstraintsInterface* constraints, 3336eca7e3c371383020095ba346e1ac70f38a8c0fdtommi bool remote) { 33428e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org ASSERT(channel_manager != NULL); 33528e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org ASSERT(capturer != NULL); 3366eca7e3c371383020095ba346e1ac70f38a8c0fdtommi rtc::scoped_refptr<VideoSource> source(new rtc::RefCountedObject<VideoSource>( 3376eca7e3c371383020095ba346e1ac70f38a8c0fdtommi channel_manager, capturer, remote)); 33828e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org source->Initialize(constraints); 33928e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org return source; 34028e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org} 34128e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org 342967bfff54d00f176a554bf9f955f14dde99f7bb9wu@webrtc.orgVideoSource::VideoSource(cricket::ChannelManager* channel_manager, 3436eca7e3c371383020095ba346e1ac70f38a8c0fdtommi cricket::VideoCapturer* capturer, 3446eca7e3c371383020095ba346e1ac70f38a8c0fdtommi bool remote) 34528e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org : channel_manager_(channel_manager), 34628e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org video_capturer_(capturer), 3476eca7e3c371383020095ba346e1ac70f38a8c0fdtommi state_(kInitializing), 3486eca7e3c371383020095ba346e1ac70f38a8c0fdtommi remote_(remote) { 34928e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org channel_manager_->SignalVideoCaptureStateChange.connect( 350967bfff54d00f176a554bf9f955f14dde99f7bb9wu@webrtc.org this, &VideoSource::OnStateChange); 35128e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org} 35228e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org 353967bfff54d00f176a554bf9f955f14dde99f7bb9wu@webrtc.orgVideoSource::~VideoSource() { 35428e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org channel_manager_->StopVideoCapture(video_capturer_.get(), format_); 35528e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org channel_manager_->SignalVideoCaptureStateChange.disconnect(this); 35628e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org} 35728e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org 358967bfff54d00f176a554bf9f955f14dde99f7bb9wu@webrtc.orgvoid VideoSource::Initialize( 35928e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org const webrtc::MediaConstraintsInterface* constraints) { 36028e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org 3611e64263b90022e914ca314f434b81ed4d3ce5b46hbos@webrtc.org std::vector<cricket::VideoFormat> formats = 3621e64263b90022e914ca314f434b81ed4d3ce5b46hbos@webrtc.org channel_manager_->GetSupportedFormats(video_capturer_.get()); 3631e64263b90022e914ca314f434b81ed4d3ce5b46hbos@webrtc.org if (formats.empty()) { 3641e64263b90022e914ca314f434b81ed4d3ce5b46hbos@webrtc.org if (video_capturer_->IsScreencast()) { 3651e64263b90022e914ca314f434b81ed4d3ce5b46hbos@webrtc.org // The screen capturer can accept any resolution and we will derive the 3661e64263b90022e914ca314f434b81ed4d3ce5b46hbos@webrtc.org // format from the constraints if any. 3671e64263b90022e914ca314f434b81ed4d3ce5b46hbos@webrtc.org // Note that this only affects tab capturing, not desktop capturing, 3681e64263b90022e914ca314f434b81ed4d3ce5b46hbos@webrtc.org // since the desktop capturer does not respect the VideoFormat passed in. 3691e64263b90022e914ca314f434b81ed4d3ce5b46hbos@webrtc.org formats.push_back(cricket::VideoFormat(kDefaultFormat)); 3701e64263b90022e914ca314f434b81ed4d3ce5b46hbos@webrtc.org } else { 3711e64263b90022e914ca314f434b81ed4d3ce5b46hbos@webrtc.org // The VideoCapturer implementation doesn't support capability 3721e64263b90022e914ca314f434b81ed4d3ce5b46hbos@webrtc.org // enumeration. We need to guess what the camera supports. 3735237aaf243d29732f59557361b7a993c0a18cf0etfarina for (int i = 0; i < arraysize(kVideoFormats); ++i) { 3741e64263b90022e914ca314f434b81ed4d3ce5b46hbos@webrtc.org formats.push_back(cricket::VideoFormat(kVideoFormats[i])); 3751e64263b90022e914ca314f434b81ed4d3ce5b46hbos@webrtc.org } 37628e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org } 37728e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org } 37828e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org 37928e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org if (constraints) { 38028e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org MediaConstraintsInterface::Constraints mandatory_constraints = 38128e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org constraints->GetMandatory(); 38228e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org MediaConstraintsInterface::Constraints optional_constraints; 38328e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org optional_constraints = constraints->GetOptional(); 38428e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org 38528e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org if (video_capturer_->IsScreencast()) { 38628e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org // Use the maxWidth and maxHeight allowed by constraints for screencast. 38728e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org FromConstraintsForScreencast(mandatory_constraints, &(formats[0])); 38828e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org } 38928e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org 39028e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org formats = FilterFormats(mandatory_constraints, optional_constraints, 39128e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org formats); 39228e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org } 39328e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org 39428e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org if (formats.size() == 0) { 39528e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org LOG(LS_WARNING) << "Failed to find a suitable video format."; 39628e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org SetState(kEnded); 39728e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org return; 39828e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org } 39928e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org 40028e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org cricket::VideoOptions options; 40128e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org if (!ExtractVideoOptions(constraints, &options)) { 40228e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org LOG(LS_WARNING) << "Could not satisfy mandatory options."; 40328e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org SetState(kEnded); 40428e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org return; 40528e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org } 40628e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org options_.SetAll(options); 40728e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org 40828e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org format_ = GetBestCaptureFormat(formats); 40928e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org // Start the camera with our best guess. 41028e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org // TODO(perkj): Should we try again with another format it it turns out that 41128e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org // the camera doesn't produce frames with the correct format? Or will 41228e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org // cricket::VideCapturer be able to re-scale / crop to the requested 41328e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org // resolution? 41428e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org if (!channel_manager_->StartVideoCapture(video_capturer_.get(), format_)) { 41528e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org SetState(kEnded); 41628e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org return; 41728e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org } 41828e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org // Initialize hasn't succeeded until a successful state change has occurred. 41928e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org} 42028e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org 421967bfff54d00f176a554bf9f955f14dde99f7bb9wu@webrtc.orgcricket::VideoRenderer* VideoSource::FrameInput() { 422967bfff54d00f176a554bf9f955f14dde99f7bb9wu@webrtc.org // Defer creation of frame_input_ until it's needed, e.g. the local video 423967bfff54d00f176a554bf9f955f14dde99f7bb9wu@webrtc.org // sources will never need it. 424967bfff54d00f176a554bf9f955f14dde99f7bb9wu@webrtc.org if (!frame_input_) { 425967bfff54d00f176a554bf9f955f14dde99f7bb9wu@webrtc.org frame_input_.reset(new FrameInputWrapper(video_capturer_.get())); 426967bfff54d00f176a554bf9f955f14dde99f7bb9wu@webrtc.org } 427967bfff54d00f176a554bf9f955f14dde99f7bb9wu@webrtc.org return frame_input_.get(); 428967bfff54d00f176a554bf9f955f14dde99f7bb9wu@webrtc.org} 429967bfff54d00f176a554bf9f955f14dde99f7bb9wu@webrtc.org 4308f605e89113ccdd02a5d68edf8e7a048ab0fdaffperkj@webrtc.orgvoid VideoSource::Stop() { 4318f605e89113ccdd02a5d68edf8e7a048ab0fdaffperkj@webrtc.org channel_manager_->StopVideoCapture(video_capturer_.get(), format_); 4328f605e89113ccdd02a5d68edf8e7a048ab0fdaffperkj@webrtc.org} 4338f605e89113ccdd02a5d68edf8e7a048ab0fdaffperkj@webrtc.org 4348f605e89113ccdd02a5d68edf8e7a048ab0fdaffperkj@webrtc.orgvoid VideoSource::Restart() { 4358f605e89113ccdd02a5d68edf8e7a048ab0fdaffperkj@webrtc.org if (!channel_manager_->StartVideoCapture(video_capturer_.get(), format_)) { 4368f605e89113ccdd02a5d68edf8e7a048ab0fdaffperkj@webrtc.org SetState(kEnded); 4378f605e89113ccdd02a5d68edf8e7a048ab0fdaffperkj@webrtc.org return; 4388f605e89113ccdd02a5d68edf8e7a048ab0fdaffperkj@webrtc.org } 4398f605e89113ccdd02a5d68edf8e7a048ab0fdaffperkj@webrtc.org for(cricket::VideoRenderer* sink : sinks_) { 4408f605e89113ccdd02a5d68edf8e7a048ab0fdaffperkj@webrtc.org channel_manager_->AddVideoRenderer(video_capturer_.get(), sink); 4418f605e89113ccdd02a5d68edf8e7a048ab0fdaffperkj@webrtc.org } 4428f605e89113ccdd02a5d68edf8e7a048ab0fdaffperkj@webrtc.org} 4438f605e89113ccdd02a5d68edf8e7a048ab0fdaffperkj@webrtc.org 444967bfff54d00f176a554bf9f955f14dde99f7bb9wu@webrtc.orgvoid VideoSource::AddSink(cricket::VideoRenderer* output) { 4458f605e89113ccdd02a5d68edf8e7a048ab0fdaffperkj@webrtc.org sinks_.push_back(output); 44628e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org channel_manager_->AddVideoRenderer(video_capturer_.get(), output); 44728e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org} 44828e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org 449967bfff54d00f176a554bf9f955f14dde99f7bb9wu@webrtc.orgvoid VideoSource::RemoveSink(cricket::VideoRenderer* output) { 4508f605e89113ccdd02a5d68edf8e7a048ab0fdaffperkj@webrtc.org sinks_.remove(output); 45128e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org channel_manager_->RemoveVideoRenderer(video_capturer_.get(), output); 45228e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org} 45328e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org 45428e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org// OnStateChange listens to the ChannelManager::SignalVideoCaptureStateChange. 45528e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org// This signal is triggered for all video capturers. Not only the one we are 45628e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org// interested in. 457967bfff54d00f176a554bf9f955f14dde99f7bb9wu@webrtc.orgvoid VideoSource::OnStateChange(cricket::VideoCapturer* capturer, 45828e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org cricket::CaptureState capture_state) { 45928e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org if (capturer == video_capturer_.get()) { 46028e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org SetState(GetReadyState(capture_state)); 46128e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org } 46228e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org} 46328e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org 464967bfff54d00f176a554bf9f955f14dde99f7bb9wu@webrtc.orgvoid VideoSource::SetState(SourceState new_state) { 4654dd7a653b5011495f4c805461bad33405c1fb1b8phoglund // TODO(hbos): Temporarily disabled VERIFY due to webrtc:4776. 4664dd7a653b5011495f4c805461bad33405c1fb1b8phoglund // if (VERIFY(state_ != new_state)) { 4674dd7a653b5011495f4c805461bad33405c1fb1b8phoglund if (state_ != new_state) { 46828e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org state_ = new_state; 46928e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org FireOnChanged(); 47028e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org } 47128e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org} 47228e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org 47328e20752806a492f5a6a5d343c02f9556f39b1cdhenrike@webrtc.org} // namespace webrtc 474