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