10e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org/* 20e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org * libjingle 30e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org * Copyright 2004 Google Inc. 40e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org * 50e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org * Redistribution and use in source and binary forms, with or without 60e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org * modification, are permitted provided that the following conditions are met: 70e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org * 80e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org * 1. Redistributions of source code must retain the above copyright notice, 90e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org * this list of conditions and the following disclaimer. 100e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org * 2. Redistributions in binary form must reproduce the above copyright notice, 110e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org * this list of conditions and the following disclaimer in the documentation 120e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org * and/or other materials provided with the distribution. 130e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org * 3. The name of the author may not be used to endorse or promote products 140e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org * derived from this software without specific prior written permission. 150e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org * 160e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED 170e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 180e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO 190e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 200e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 210e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 220e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 230e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 240e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 250e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 260e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org */ 270e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 280e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org#include "talk/media/base/codec.h" 290e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 300e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org#include <algorithm> 310e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org#include <sstream> 320e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 332a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org#include "webrtc/base/common.h" 342a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org#include "webrtc/base/logging.h" 352a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org#include "webrtc/base/stringencode.h" 362a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org#include "webrtc/base/stringutils.h" 370e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 380e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgnamespace cricket { 390e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 400e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgstatic const int kMaxStaticPayloadId = 95; 41daf1d14b6fd8a1d962ae9b238172c4bc327f3776wu@webrtc.orgconst int kMaxPayloadId = 127; 420e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 430e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgbool FeedbackParam::operator==(const FeedbackParam& other) const { 440e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org return _stricmp(other.id().c_str(), id().c_str()) == 0 && 450e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org _stricmp(other.param().c_str(), param().c_str()) == 0; 460e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org} 470e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 480e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgbool FeedbackParams::operator==(const FeedbackParams& other) const { 490e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org return params_ == other.params_; 500e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org} 510e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 520e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgbool FeedbackParams::Has(const FeedbackParam& param) const { 530e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org return std::find(params_.begin(), params_.end(), param) != params_.end(); 540e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org} 550e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 560e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgvoid FeedbackParams::Add(const FeedbackParam& param) { 570e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org if (param.id().empty()) { 580e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org return; 590e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 600e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org if (Has(param)) { 610e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org // Param already in |this|. 620e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org return; 630e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 640e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org params_.push_back(param); 650e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org ASSERT(!HasDuplicateEntries()); 660e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org} 670e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 680e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgvoid FeedbackParams::Intersect(const FeedbackParams& from) { 690e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org std::vector<FeedbackParam>::iterator iter_to = params_.begin(); 700e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org while (iter_to != params_.end()) { 710e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org if (!from.Has(*iter_to)) { 720e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org iter_to = params_.erase(iter_to); 730e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } else { 740e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org ++iter_to; 750e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 760e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 770e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org} 780e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 790e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgbool FeedbackParams::HasDuplicateEntries() const { 800e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org for (std::vector<FeedbackParam>::const_iterator iter = params_.begin(); 810e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org iter != params_.end(); ++iter) { 820e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org for (std::vector<FeedbackParam>::const_iterator found = iter + 1; 830e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org found != params_.end(); ++found) { 840e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org if (*found == *iter) { 850e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org return true; 860e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 870e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 880e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org } 890e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org return false; 900e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org} 910e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 920e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgbool Codec::Matches(const Codec& codec) const { 930e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org // Match the codec id/name based on the typical static/dynamic name rules. 940e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org // Matching is case-insensitive. 950e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org return (codec.id <= kMaxStaticPayloadId) ? 960e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org (id == codec.id) : (_stricmp(name.c_str(), codec.name.c_str()) == 0); 970e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org} 980e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 990e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgbool Codec::GetParam(const std::string& name, std::string* out) const { 1000e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org CodecParameterMap::const_iterator iter = params.find(name); 1010e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org if (iter == params.end()) 1020e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org return false; 1030e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org *out = iter->second; 1040e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org return true; 1050e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org} 1060e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 1070e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgbool Codec::GetParam(const std::string& name, int* out) const { 1080e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org CodecParameterMap::const_iterator iter = params.find(name); 1090e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org if (iter == params.end()) 1100e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org return false; 1112a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org return rtc::FromString(iter->second, out); 1120e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org} 1130e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 1140e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgvoid Codec::SetParam(const std::string& name, const std::string& value) { 1150e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org params[name] = value; 1160e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org} 1170e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 1180e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgvoid Codec::SetParam(const std::string& name, int value) { 1192a86ce22ccc387dfa6f8a98ce3eba5c1e6f9e538buildbot@webrtc.org params[name] = rtc::ToString(value); 1200e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org} 1210e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 122621454260f22dfe3709f870c53df5c72e2417607buildbot@webrtc.orgbool Codec::RemoveParam(const std::string& name) { 123621454260f22dfe3709f870c53df5c72e2417607buildbot@webrtc.org return params.erase(name) == 1; 124621454260f22dfe3709f870c53df5c72e2417607buildbot@webrtc.org} 125621454260f22dfe3709f870c53df5c72e2417607buildbot@webrtc.org 1260e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgvoid Codec::AddFeedbackParam(const FeedbackParam& param) { 1270e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org feedback_params.Add(param); 1280e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org} 1290e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 1300e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgbool Codec::HasFeedbackParam(const FeedbackParam& param) const { 1310e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org return feedback_params.Has(param); 1320e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org} 1330e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 1340e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgvoid Codec::IntersectFeedbackParams(const Codec& other) { 1350e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org feedback_params.Intersect(other.feedback_params); 1360e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org} 1370e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 1380e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgbool AudioCodec::Matches(const AudioCodec& codec) const { 1390e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org // If a nonzero clockrate is specified, it must match the actual clockrate. 1400e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org // If a nonzero bitrate is specified, it must match the actual bitrate, 1410e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org // unless the codec is VBR (0), where we just force the supplied value. 1420e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org // The number of channels must match exactly, with the exception 1430e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org // that channels=0 is treated synonymously as channels=1, per RFC 1440e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org // 4566 section 6: " [The channels] parameter is OPTIONAL and may be 1450e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org // omitted if the number of channels is one." 1460e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org // Preference is ignored. 1470e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org // TODO(juberti): Treat a zero clockrate as 8000Hz, the RTP default clockrate. 1480e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org return Codec::Matches(codec) && 1490e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org ((codec.clockrate == 0 /*&& clockrate == 8000*/) || 1500e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org clockrate == codec.clockrate) && 1510e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org (codec.bitrate == 0 || bitrate <= 0 || bitrate == codec.bitrate) && 1520e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org ((codec.channels < 2 && channels < 2) || channels == codec.channels); 1530e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org} 1540e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 1550e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgstd::string AudioCodec::ToString() const { 1560e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org std::ostringstream os; 1570e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org os << "AudioCodec[" << id << ":" << name << ":" << clockrate << ":" << bitrate 1580e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org << ":" << channels << ":" << preference << "]"; 1590e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org return os.str(); 1600e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org} 1610e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 1620e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgstd::string VideoCodec::ToString() const { 1630e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org std::ostringstream os; 1640e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org os << "VideoCodec[" << id << ":" << name << ":" << width << ":" << height 1650e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org << ":" << framerate << ":" << preference << "]"; 1660e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org return os.str(); 1670e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org} 1680e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 16987e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.orgVideoCodec VideoCodec::CreateRtxCodec(int rtx_payload_type, 17087e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org int associated_payload_type) { 17187e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org VideoCodec rtx_codec(rtx_payload_type, kRtxCodecName, 0, 0, 0, 0); 17287e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org rtx_codec.SetParam(kCodecParamAssociatedPayloadType, associated_payload_type); 17387e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org return rtx_codec; 17487e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org} 17587e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org 17687e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.orgVideoCodec::CodecType VideoCodec::GetCodecType() const { 17787e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org const char* payload_name = name.c_str(); 17887e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org if (_stricmp(payload_name, kRedCodecName) == 0) { 17987e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org return CODEC_RED; 18087e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org } 18187e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org if (_stricmp(payload_name, kUlpfecCodecName) == 0) { 18287e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org return CODEC_ULPFEC; 18387e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org } 18487e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org if (_stricmp(payload_name, kRtxCodecName) == 0) { 18587e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org return CODEC_RTX; 18687e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org } 18787e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org 18887e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org return CODEC_VIDEO; 18987e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org} 19087e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org 19187e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.orgbool VideoCodec::ValidateCodecFormat() const { 19287e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org if (id < 0 || id > 127) { 19387e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org LOG(LS_ERROR) << "Codec with invalid payload type: " << ToString(); 19487e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org return false; 19587e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org } 19687e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org if (GetCodecType() != CODEC_VIDEO) { 19787e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org return true; 19887e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org } 19987e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org 20087e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org // Video validation from here on. 20187e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org 20287e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org if (width <= 0 || height <= 0) { 20387e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org LOG(LS_ERROR) << "Codec with invalid dimensions: " << ToString(); 20487e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org return false; 20587e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org } 20687e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org int min_bitrate = -1; 20787e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org int max_bitrate = -1; 20887e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org if (GetParam(kCodecParamMinBitrate, &min_bitrate) && 20987e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org GetParam(kCodecParamMaxBitrate, &max_bitrate)) { 21087e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org if (max_bitrate < min_bitrate) { 21187e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org LOG(LS_ERROR) << "Codec with max < min bitrate: " << ToString(); 21287e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org return false; 21387e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org } 21487e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org } 21587e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org return true; 21687e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org} 21787e1f97b7bf06f8554aa27adae4357f81cff3e6bpbos@webrtc.org 2180e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.orgstd::string DataCodec::ToString() const { 2190e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org std::ostringstream os; 2200e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org os << "DataCodec[" << id << ":" << name << "]"; 2210e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org return os.str(); 2220e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org} 2230e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org 2240e118e7129884fbea117e78d6f2068139a414dbhenrike@webrtc.org} // namespace cricket 225