1b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org/*
2b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org *  Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
3b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org *
4b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org *  Use of this source code is governed by a BSD-style license
5b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org *  that can be found in the LICENSE file in the root of the source
6b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org *  tree. An additional intellectual property rights grant can be found
7b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org *  in the file PATENTS.  All contributing project authors may
8b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org *  be found in the AUTHORS file in the root of the source tree.
9b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org */
10b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
11281cff8cd679728fe395f7f0203c05e763c0c789pbos@webrtc.org#include "webrtc/video_engine/vie_codec_impl.h"
12b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
13b6d9cfc6347e490751e142ba5fb89e4a975ed442mflodman@webrtc.org#include <list>
14b6d9cfc6347e490751e142ba5fb89e4a975ed442mflodman@webrtc.org
15281cff8cd679728fe395f7f0203c05e763c0c789pbos@webrtc.org#include "webrtc/engine_configurations.h"
16281cff8cd679728fe395f7f0203c05e763c0c789pbos@webrtc.org#include "webrtc/modules/video_coding/main/interface/video_coding.h"
17281cff8cd679728fe395f7f0203c05e763c0c789pbos@webrtc.org#include "webrtc/system_wrappers/interface/logging.h"
18281cff8cd679728fe395f7f0203c05e763c0c789pbos@webrtc.org#include "webrtc/video_engine/include/vie_errors.h"
19281cff8cd679728fe395f7f0203c05e763c0c789pbos@webrtc.org#include "webrtc/video_engine/vie_capturer.h"
20281cff8cd679728fe395f7f0203c05e763c0c789pbos@webrtc.org#include "webrtc/video_engine/vie_channel.h"
21281cff8cd679728fe395f7f0203c05e763c0c789pbos@webrtc.org#include "webrtc/video_engine/vie_channel_manager.h"
22281cff8cd679728fe395f7f0203c05e763c0c789pbos@webrtc.org#include "webrtc/video_engine/vie_defines.h"
23281cff8cd679728fe395f7f0203c05e763c0c789pbos@webrtc.org#include "webrtc/video_engine/vie_encoder.h"
24281cff8cd679728fe395f7f0203c05e763c0c789pbos@webrtc.org#include "webrtc/video_engine/vie_impl.h"
25281cff8cd679728fe395f7f0203c05e763c0c789pbos@webrtc.org#include "webrtc/video_engine/vie_input_manager.h"
26281cff8cd679728fe395f7f0203c05e763c0c789pbos@webrtc.org#include "webrtc/video_engine/vie_shared_data.h"
27b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
28b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgnamespace webrtc {
29b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
30022615bd918aec7671968ad2b873d1487365980cmflodman@webrtc.orgstatic void LogCodec(const VideoCodec& codec) {
31022615bd918aec7671968ad2b873d1487365980cmflodman@webrtc.org  LOG(LS_INFO) << "CodecType " << codec.codecType
321d95c5aecd0a4924f39f24834fb06d06e61f181easapersson@webrtc.org               << ", pl_type " << static_cast<int>(codec.plType)
33022615bd918aec7671968ad2b873d1487365980cmflodman@webrtc.org               << ", resolution " << codec.width
34022615bd918aec7671968ad2b873d1487365980cmflodman@webrtc.org               << " x " << codec.height
35022615bd918aec7671968ad2b873d1487365980cmflodman@webrtc.org               << ", start br " << codec.startBitrate
36022615bd918aec7671968ad2b873d1487365980cmflodman@webrtc.org               << ", min br " << codec.minBitrate
37022615bd918aec7671968ad2b873d1487365980cmflodman@webrtc.org               << ", max br " << codec.maxBitrate
381d95c5aecd0a4924f39f24834fb06d06e61f181easapersson@webrtc.org               << ", max fps " << static_cast<int>(codec.maxFramerate)
39022615bd918aec7671968ad2b873d1487365980cmflodman@webrtc.org               << ", max qp " << codec.qpMax
40022615bd918aec7671968ad2b873d1487365980cmflodman@webrtc.org               << ", number of streams "
411d95c5aecd0a4924f39f24834fb06d06e61f181easapersson@webrtc.org               << static_cast<int>(codec.numberOfSimulcastStreams);
42022615bd918aec7671968ad2b873d1487365980cmflodman@webrtc.org  if (codec.codecType == kVideoCodecVP8) {
43022615bd918aec7671968ad2b873d1487365980cmflodman@webrtc.org    LOG(LS_INFO) << "VP8 specific settings";
441d95c5aecd0a4924f39f24834fb06d06e61f181easapersson@webrtc.org    LOG(LS_INFO) << "pictureLossIndicationOn "
45022615bd918aec7671968ad2b873d1487365980cmflodman@webrtc.org                 << codec.codecSpecific.VP8.pictureLossIndicationOn
46022615bd918aec7671968ad2b873d1487365980cmflodman@webrtc.org                 << ", feedbackModeOn "
47022615bd918aec7671968ad2b873d1487365980cmflodman@webrtc.org                 << codec.codecSpecific.VP8.feedbackModeOn
48022615bd918aec7671968ad2b873d1487365980cmflodman@webrtc.org                 << ", complexity "
49022615bd918aec7671968ad2b873d1487365980cmflodman@webrtc.org                 << codec.codecSpecific.VP8.complexity
50022615bd918aec7671968ad2b873d1487365980cmflodman@webrtc.org                 << ", resilience "
51022615bd918aec7671968ad2b873d1487365980cmflodman@webrtc.org                 << codec.codecSpecific.VP8.resilience
521d95c5aecd0a4924f39f24834fb06d06e61f181easapersson@webrtc.org                 << ", numberOfTemporalLayers "
531d95c5aecd0a4924f39f24834fb06d06e61f181easapersson@webrtc.org                 << static_cast<int>(
541d95c5aecd0a4924f39f24834fb06d06e61f181easapersson@webrtc.org                     codec.codecSpecific.VP8.numberOfTemporalLayers)
55022615bd918aec7671968ad2b873d1487365980cmflodman@webrtc.org                 << ", keyFrameinterval "
56022615bd918aec7671968ad2b873d1487365980cmflodman@webrtc.org                 << codec.codecSpecific.VP8.keyFrameInterval;
57022615bd918aec7671968ad2b873d1487365980cmflodman@webrtc.org    for (int idx = 0; idx < codec.numberOfSimulcastStreams; ++idx) {
58022615bd918aec7671968ad2b873d1487365980cmflodman@webrtc.org      LOG(LS_INFO) << "Stream " << codec.simulcastStream[idx].width
59022615bd918aec7671968ad2b873d1487365980cmflodman@webrtc.org                   << " x " << codec.simulcastStream[idx].height;
60022615bd918aec7671968ad2b873d1487365980cmflodman@webrtc.org      LOG(LS_INFO) << "Temporal layers "
611d95c5aecd0a4924f39f24834fb06d06e61f181easapersson@webrtc.org                   << static_cast<int>(
621d95c5aecd0a4924f39f24834fb06d06e61f181easapersson@webrtc.org                       codec.simulcastStream[idx].numberOfTemporalLayers)
63022615bd918aec7671968ad2b873d1487365980cmflodman@webrtc.org                   << ", min br "
64022615bd918aec7671968ad2b873d1487365980cmflodman@webrtc.org                   << codec.simulcastStream[idx].minBitrate
65022615bd918aec7671968ad2b873d1487365980cmflodman@webrtc.org                   << ", target br "
66022615bd918aec7671968ad2b873d1487365980cmflodman@webrtc.org                   << codec.simulcastStream[idx].targetBitrate
67022615bd918aec7671968ad2b873d1487365980cmflodman@webrtc.org                   << ", max br "
68022615bd918aec7671968ad2b873d1487365980cmflodman@webrtc.org                   << codec.simulcastStream[idx].maxBitrate
69022615bd918aec7671968ad2b873d1487365980cmflodman@webrtc.org                   << ", qp max "
70022615bd918aec7671968ad2b873d1487365980cmflodman@webrtc.org                   << codec.simulcastStream[idx].qpMax;
71022615bd918aec7671968ad2b873d1487365980cmflodman@webrtc.org    }
72022615bd918aec7671968ad2b873d1487365980cmflodman@webrtc.org  }
73022615bd918aec7671968ad2b873d1487365980cmflodman@webrtc.org}
74022615bd918aec7671968ad2b873d1487365980cmflodman@webrtc.org
75022615bd918aec7671968ad2b873d1487365980cmflodman@webrtc.org
76b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgViECodec* ViECodec::GetInterface(VideoEngine* video_engine) {
77b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org#ifdef WEBRTC_VIDEO_ENGINE_CODEC_API
78b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  if (!video_engine) {
79b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    return NULL;
80b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  }
817ab726855f2ceb9ff6365e3240668d58f45e6761andrew@webrtc.org  VideoEngineImpl* vie_impl = static_cast<VideoEngineImpl*>(video_engine);
82b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  ViECodecImpl* vie_codec_impl = vie_impl;
83b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  // Increase ref count.
84b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  (*vie_codec_impl)++;
85b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  return vie_codec_impl;
86b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org#else
87b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  return NULL;
88b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org#endif
89b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
90b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
91b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgint ViECodecImpl::Release() {
92022615bd918aec7671968ad2b873d1487365980cmflodman@webrtc.org  LOG(LS_INFO) << "ViECodec::Release.";
93b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  // Decrease ref count.
94b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  (*this)--;
95b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
9667879bc2e69d7907b7ceb92135a34f77fe643e7fpbos@webrtc.org  int32_t ref_count = GetCount();
97b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  if (ref_count < 0) {
98022615bd918aec7671968ad2b873d1487365980cmflodman@webrtc.org    LOG(LS_WARNING) << "ViECodec released too many times.";
99b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    shared_data_->SetLastError(kViEAPIDoesNotExist);
100b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    return -1;
101b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  }
102b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  return ref_count;
103b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
104b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
105b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgViECodecImpl::ViECodecImpl(ViESharedData* shared_data)
106b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    : shared_data_(shared_data) {
107b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
108b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
109b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgViECodecImpl::~ViECodecImpl() {
110b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
111b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
112b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgint ViECodecImpl::NumberOfCodecs() const {
113b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  // +2 because of FEC(RED and ULPFEC)
114b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  return static_cast<int>((VideoCodingModule::NumberOfCodecs() + 2));
115b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
116b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
117b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgint ViECodecImpl::GetCodec(const unsigned char list_number,
118b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org                           VideoCodec& video_codec) const {
119b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  if (list_number == VideoCodingModule::NumberOfCodecs()) {
120b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    memset(&video_codec, 0, sizeof(VideoCodec));
121bea854aac01d4a950a0062892d2205c37b15cc40mflodman@webrtc.org    strcpy(video_codec.plName, "red");
122b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    video_codec.codecType = kVideoCodecRED;
123b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    video_codec.plType = VCM_RED_PAYLOAD_TYPE;
124b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  } else if (list_number == VideoCodingModule::NumberOfCodecs() + 1) {
125b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    memset(&video_codec, 0, sizeof(VideoCodec));
126bea854aac01d4a950a0062892d2205c37b15cc40mflodman@webrtc.org    strcpy(video_codec.plName, "ulpfec");
127b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    video_codec.codecType = kVideoCodecULPFEC;
128b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    video_codec.plType = VCM_ULPFEC_PAYLOAD_TYPE;
129b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  } else if (VideoCodingModule::Codec(list_number, &video_codec) != VCM_OK) {
130b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    shared_data_->SetLastError(kViECodecInvalidArgument);
131b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    return -1;
132b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  }
133b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  return 0;
134b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
135b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
136b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgint ViECodecImpl::SetSendCodec(const int video_channel,
137b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org                               const VideoCodec& video_codec) {
138022615bd918aec7671968ad2b873d1487365980cmflodman@webrtc.org  LOG(LS_INFO) << "SetSendCodec for channel " << video_channel;
139022615bd918aec7671968ad2b873d1487365980cmflodman@webrtc.org  LogCodec(video_codec);
140b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  if (!CodecValid(video_codec)) {
141b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    // Error logged.
142b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    shared_data_->SetLastError(kViECodecInvalidCodec);
143b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    return -1;
144b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  }
145b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
146b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  ViEChannelManagerScoped cs(*(shared_data_->channel_manager()));
147b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  ViEChannel* vie_channel = cs.Channel(video_channel);
148b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  if (!vie_channel) {
149b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    shared_data_->SetLastError(kViECodecInvalidChannelId);
150b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    return -1;
151b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  }
152b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
153b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  ViEEncoder* vie_encoder = cs.Encoder(video_channel);
154b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  assert(vie_encoder);
155b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  if (vie_encoder->Owner() != video_channel) {
156022615bd918aec7671968ad2b873d1487365980cmflodman@webrtc.org    LOG_F(LS_ERROR) << "Receive only channel.";
157b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    shared_data_->SetLastError(kViECodecReceiveOnlyChannel);
158b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    return -1;
159b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  }
160b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  // Set a max_bitrate if the user hasn't set one.
161b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  VideoCodec video_codec_internal;
162b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  memcpy(&video_codec_internal, &video_codec, sizeof(VideoCodec));
163b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  if (video_codec_internal.maxBitrate == 0) {
164b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    // Max is one bit per pixel.
165b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    video_codec_internal.maxBitrate = (video_codec_internal.width *
166b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org                                       video_codec_internal.height *
167b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org                                       video_codec_internal.maxFramerate)
168b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org                                       / 1000;
169022615bd918aec7671968ad2b873d1487365980cmflodman@webrtc.org    LOG(LS_INFO) << "New max bitrate set " << video_codec_internal.maxBitrate;
170b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  }
171b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
172543520819967835da38d529690df36b608bc9970mflodman@webrtc.org  if (video_codec_internal.startBitrate < video_codec_internal.minBitrate) {
173543520819967835da38d529690df36b608bc9970mflodman@webrtc.org    video_codec_internal.startBitrate = video_codec_internal.minBitrate;
174543520819967835da38d529690df36b608bc9970mflodman@webrtc.org  }
175a9a7327cd1bb55cb05ab28a12e265ffefc1b5da4mflodman@webrtc.org  if (video_codec_internal.startBitrate > video_codec_internal.maxBitrate) {
176a9a7327cd1bb55cb05ab28a12e265ffefc1b5da4mflodman@webrtc.org    video_codec_internal.startBitrate = video_codec_internal.maxBitrate;
177a9a7327cd1bb55cb05ab28a12e265ffefc1b5da4mflodman@webrtc.org  }
178a9a7327cd1bb55cb05ab28a12e265ffefc1b5da4mflodman@webrtc.org
179b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  VideoCodec encoder;
180b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  vie_encoder->GetEncoder(&encoder);
181b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
182b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  // Make sure to generate a new SSRC if the codec type and/or resolution has
183b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  // changed. This won't have any effect if the user has set an SSRC.
184b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  bool new_rtp_stream = false;
185b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  if (encoder.codecType != video_codec_internal.codecType) {
186b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    new_rtp_stream = true;
187b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  }
188b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
189b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  ViEInputManagerScoped is(*(shared_data_->input_manager()));
190b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
191b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  // Stop the media flow while reconfiguring.
192b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  vie_encoder->Pause();
193b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
194a18c6e5b2811221b60e3d7e72516aa20927e13ddmflodman@webrtc.org  if (vie_encoder->SetEncoder(video_codec_internal) != 0) {
195b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    shared_data_->SetLastError(kViECodecUnknownError);
196b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    return -1;
197b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  }
198b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
199b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  // Give the channel(s) the new information.
200b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  ChannelList channels;
201b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  cs.ChannelsUsingViEEncoder(video_channel, &channels);
202b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  for (ChannelList::iterator it = channels.begin(); it != channels.end();
203b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org       ++it) {
204b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    bool ret = true;
205b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    if ((*it)->SetSendCodec(video_codec_internal, new_rtp_stream) != 0) {
206b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org      ret = false;
207b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    }
208b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    if (!ret) {
209b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org      shared_data_->SetLastError(kViECodecUnknownError);
210b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org      return -1;
211b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    }
212b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  }
213b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
214b6d9cfc6347e490751e142ba5fb89e4a975ed442mflodman@webrtc.org  // TODO(mflodman) Break out this part in GetLocalSsrcList().
215b6d9cfc6347e490751e142ba5fb89e4a975ed442mflodman@webrtc.org  // Update all SSRCs to ViEEncoder.
216b6d9cfc6347e490751e142ba5fb89e4a975ed442mflodman@webrtc.org  std::list<unsigned int> ssrcs;
217b6d9cfc6347e490751e142ba5fb89e4a975ed442mflodman@webrtc.org  if (video_codec_internal.numberOfSimulcastStreams == 0) {
218b6d9cfc6347e490751e142ba5fb89e4a975ed442mflodman@webrtc.org    unsigned int ssrc = 0;
219b6d9cfc6347e490751e142ba5fb89e4a975ed442mflodman@webrtc.org    if (vie_channel->GetLocalSSRC(0, &ssrc) != 0) {
220022615bd918aec7671968ad2b873d1487365980cmflodman@webrtc.org      LOG_F(LS_ERROR) << "Could not get ssrc.";
221b6d9cfc6347e490751e142ba5fb89e4a975ed442mflodman@webrtc.org    }
222b6d9cfc6347e490751e142ba5fb89e4a975ed442mflodman@webrtc.org    ssrcs.push_back(ssrc);
223b6d9cfc6347e490751e142ba5fb89e4a975ed442mflodman@webrtc.org  } else {
224b6d9cfc6347e490751e142ba5fb89e4a975ed442mflodman@webrtc.org    for (int idx = 0; idx < video_codec_internal.numberOfSimulcastStreams;
225b6d9cfc6347e490751e142ba5fb89e4a975ed442mflodman@webrtc.org         ++idx) {
226b6d9cfc6347e490751e142ba5fb89e4a975ed442mflodman@webrtc.org      unsigned int ssrc = 0;
227b6d9cfc6347e490751e142ba5fb89e4a975ed442mflodman@webrtc.org      if (vie_channel->GetLocalSSRC(idx, &ssrc) != 0) {
228022615bd918aec7671968ad2b873d1487365980cmflodman@webrtc.org        LOG_F(LS_ERROR) << "Could not get ssrc for stream " << idx;
229b6d9cfc6347e490751e142ba5fb89e4a975ed442mflodman@webrtc.org      }
230b6d9cfc6347e490751e142ba5fb89e4a975ed442mflodman@webrtc.org      ssrcs.push_back(ssrc);
231b6d9cfc6347e490751e142ba5fb89e4a975ed442mflodman@webrtc.org    }
232b6d9cfc6347e490751e142ba5fb89e4a975ed442mflodman@webrtc.org  }
233b6d9cfc6347e490751e142ba5fb89e4a975ed442mflodman@webrtc.org  vie_encoder->SetSsrcs(ssrcs);
234b6d9cfc6347e490751e142ba5fb89e4a975ed442mflodman@webrtc.org  shared_data_->channel_manager()->UpdateSsrcs(video_channel, ssrcs);
235b6d9cfc6347e490751e142ba5fb89e4a975ed442mflodman@webrtc.org
236b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  // Update the protection mode, we might be switching NACK/FEC.
2377fc75bbb65cc1cd99fdf45d9fce44bcce1396dfawu@webrtc.org  vie_encoder->UpdateProtectionMethod(vie_encoder->nack_enabled());
238b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
239b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  // Get new best format for frame provider.
2408704595e8820b9c3692dad8a8d8ff7b220b32455pbos@webrtc.org  ViEFrameProviderBase* frame_provider = is.FrameProvider(vie_encoder);
241b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  if (frame_provider) {
242b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    frame_provider->FrameCallbackChanged();
243b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  }
244b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  // Restart the media flow
245b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  if (new_rtp_stream) {
246b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    // Stream settings changed, make sure we get a key frame.
247b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    vie_encoder->SendKeyFrame();
248b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  }
249b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  vie_encoder->Restart();
250b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  return 0;
251b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
252b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
253b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgint ViECodecImpl::GetSendCodec(const int video_channel,
254b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org                               VideoCodec& video_codec) const {
255b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  ViEChannelManagerScoped cs(*(shared_data_->channel_manager()));
256b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  ViEEncoder* vie_encoder = cs.Encoder(video_channel);
257b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  if (!vie_encoder) {
258b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    shared_data_->SetLastError(kViECodecInvalidChannelId);
259b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    return -1;
260b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  }
261b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  return vie_encoder->GetEncoder(&video_codec);
262b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
263b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
264b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgint ViECodecImpl::SetReceiveCodec(const int video_channel,
265b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org                                  const VideoCodec& video_codec) {
266022615bd918aec7671968ad2b873d1487365980cmflodman@webrtc.org  LOG(LS_INFO) << "SetReceiveCodec for channel " << video_channel;
267022615bd918aec7671968ad2b873d1487365980cmflodman@webrtc.org  LOG(LS_INFO) << "Codec type " << video_codec.codecType
268022615bd918aec7671968ad2b873d1487365980cmflodman@webrtc.org               << ", payload type " << video_codec.plType;
269b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
270b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  if (CodecValid(video_codec) == false) {
271b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    shared_data_->SetLastError(kViECodecInvalidCodec);
272b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    return -1;
273b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  }
274b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
275b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  ViEChannelManagerScoped cs(*(shared_data_->channel_manager()));
276b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  ViEChannel* vie_channel = cs.Channel(video_channel);
277b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  if (!vie_channel) {
278b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    shared_data_->SetLastError(kViECodecInvalidChannelId);
279b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    return -1;
280b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  }
281b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
282b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  if (vie_channel->SetReceiveCodec(video_codec) != 0) {
283b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    shared_data_->SetLastError(kViECodecUnknownError);
284b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    return -1;
285b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  }
286b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  return 0;
287b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
288b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
289b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgint ViECodecImpl::GetReceiveCodec(const int video_channel,
290b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org                                  VideoCodec& video_codec) const {
291b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  ViEChannelManagerScoped cs(*(shared_data_->channel_manager()));
292b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  ViEChannel* vie_channel = cs.Channel(video_channel);
293b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  if (!vie_channel) {
294b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    shared_data_->SetLastError(kViECodecInvalidChannelId);
295b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    return -1;
296b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  }
297b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
298b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  if (vie_channel->GetReceiveCodec(&video_codec) != 0) {
299b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    shared_data_->SetLastError(kViECodecUnknownError);
300b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    return -1;
301b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  }
302b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  return 0;
303b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
304b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
305b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgint ViECodecImpl::GetCodecConfigParameters(
306b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  const int video_channel,
307b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  unsigned char config_parameters[kConfigParameterSize],
308b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  unsigned char& config_parameters_size) const {
309022615bd918aec7671968ad2b873d1487365980cmflodman@webrtc.org  LOG(LS_INFO) << "GetCodecConfigParameters " << video_channel;
310b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
311b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  ViEChannelManagerScoped cs(*(shared_data_->channel_manager()));
312b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  ViEEncoder* vie_encoder = cs.Encoder(video_channel);
313b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  if (!vie_encoder) {
314b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    shared_data_->SetLastError(kViECodecInvalidChannelId);
315b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    return -1;
316b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  }
317b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
318b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  if (vie_encoder->GetCodecConfigParameters(config_parameters,
319b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org                                            config_parameters_size) != 0) {
320b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    shared_data_->SetLastError(kViECodecUnknownError);
321b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    return -1;
322b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  }
323b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  return 0;
324b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
325b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
326b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgint ViECodecImpl::SetImageScaleStatus(const int video_channel,
327b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org                                      const bool enable) {
328022615bd918aec7671968ad2b873d1487365980cmflodman@webrtc.org  LOG(LS_INFO) << "SetImageScaleStates for channel " << video_channel
329022615bd918aec7671968ad2b873d1487365980cmflodman@webrtc.org               << ", enable: " << enable;
330b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
331b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  ViEChannelManagerScoped cs(*(shared_data_->channel_manager()));
332b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  ViEEncoder* vie_encoder = cs.Encoder(video_channel);
333b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  if (!vie_encoder) {
334b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    shared_data_->SetLastError(kViECodecInvalidChannelId);
335b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    return -1;
336b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  }
337b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
338b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  if (vie_encoder->ScaleInputImage(enable) != 0) {
339b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    shared_data_->SetLastError(kViECodecUnknownError);
340b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    return -1;
341b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  }
342b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  return 0;
343b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
344b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
345b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgint ViECodecImpl::GetSendCodecStastistics(const int video_channel,
346b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org                                          unsigned int& key_frames,
347b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org                                          unsigned int& delta_frames) const {
348b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  ViEChannelManagerScoped cs(*(shared_data_->channel_manager()));
349b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  ViEEncoder* vie_encoder = cs.Encoder(video_channel);
350b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  if (!vie_encoder) {
351b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    shared_data_->SetLastError(kViECodecInvalidChannelId);
352b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    return -1;
353b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  }
354b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
355b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  if (vie_encoder->SendCodecStatistics(&key_frames, &delta_frames) != 0) {
356b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    shared_data_->SetLastError(kViECodecUnknownError);
357b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    return -1;
358b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  }
359b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  return 0;
360b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
361b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
362b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgint ViECodecImpl::GetReceiveCodecStastistics(const int video_channel,
363b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org                                             unsigned int& key_frames,
364b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org                                             unsigned int& delta_frames) const {
365b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  ViEChannelManagerScoped cs(*(shared_data_->channel_manager()));
366b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  ViEChannel* vie_channel = cs.Channel(video_channel);
367b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  if (!vie_channel) {
368b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    shared_data_->SetLastError(kViECodecInvalidChannelId);
369b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    return -1;
370b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  }
371b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  if (vie_channel->ReceiveCodecStatistics(&key_frames, &delta_frames) != 0) {
372b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    shared_data_->SetLastError(kViECodecUnknownError);
373b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    return -1;
374b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  }
375b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  return 0;
376b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
377b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
378f314c80eb667406101dbc5810fda799f67030a0fmflodman@webrtc.orgint ViECodecImpl::GetReceiveSideDelay(const int video_channel,
379f314c80eb667406101dbc5810fda799f67030a0fmflodman@webrtc.org                                      int* delay_ms) const {
380022615bd918aec7671968ad2b873d1487365980cmflodman@webrtc.org  assert(delay_ms != NULL);
381f314c80eb667406101dbc5810fda799f67030a0fmflodman@webrtc.org
382f314c80eb667406101dbc5810fda799f67030a0fmflodman@webrtc.org  ViEChannelManagerScoped cs(*(shared_data_->channel_manager()));
383f314c80eb667406101dbc5810fda799f67030a0fmflodman@webrtc.org  ViEChannel* vie_channel = cs.Channel(video_channel);
384f314c80eb667406101dbc5810fda799f67030a0fmflodman@webrtc.org  if (!vie_channel) {
385f314c80eb667406101dbc5810fda799f67030a0fmflodman@webrtc.org    shared_data_->SetLastError(kViECodecInvalidChannelId);
386f314c80eb667406101dbc5810fda799f67030a0fmflodman@webrtc.org    return -1;
387f314c80eb667406101dbc5810fda799f67030a0fmflodman@webrtc.org  }
388f314c80eb667406101dbc5810fda799f67030a0fmflodman@webrtc.org  *delay_ms = vie_channel->ReceiveDelay();
389f314c80eb667406101dbc5810fda799f67030a0fmflodman@webrtc.org  if (*delay_ms < 0) {
390f314c80eb667406101dbc5810fda799f67030a0fmflodman@webrtc.org    return -1;
391f314c80eb667406101dbc5810fda799f67030a0fmflodman@webrtc.org  }
392f314c80eb667406101dbc5810fda799f67030a0fmflodman@webrtc.org  return 0;
393f314c80eb667406101dbc5810fda799f67030a0fmflodman@webrtc.org}
394f314c80eb667406101dbc5810fda799f67030a0fmflodman@webrtc.org
395f314c80eb667406101dbc5810fda799f67030a0fmflodman@webrtc.org
396b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgint ViECodecImpl::GetCodecTargetBitrate(const int video_channel,
397b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org                                        unsigned int* bitrate) const {
398b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  ViEChannelManagerScoped cs(*(shared_data_->channel_manager()));
399b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  ViEEncoder* vie_encoder = cs.Encoder(video_channel);
400b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  if (!vie_encoder) {
401b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    shared_data_->SetLastError(kViECodecInvalidChannelId);
402b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    return -1;
403b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  }
40467879bc2e69d7907b7ceb92135a34f77fe643e7fpbos@webrtc.org  return vie_encoder->CodecTargetBitrate(static_cast<uint32_t*>(bitrate));
405b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
406b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
407b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgunsigned int ViECodecImpl::GetDiscardedPackets(const int video_channel) const {
408b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  ViEChannelManagerScoped cs(*(shared_data_->channel_manager()));
409b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  ViEChannel* vie_channel = cs.Channel(video_channel);
410b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  if (!vie_channel) {
411b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    shared_data_->SetLastError(kViECodecInvalidChannelId);
412b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    return -1;
413b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  }
414b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  return vie_channel->DiscardedPackets();
415b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
416b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
417b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgint ViECodecImpl::SetKeyFrameRequestCallbackStatus(const int video_channel,
418b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org                                                   const bool enable) {
419022615bd918aec7671968ad2b873d1487365980cmflodman@webrtc.org  LOG(LS_INFO) << "SetKeyFrameRequestCallbackStatus for " << video_channel
420022615bd918aec7671968ad2b873d1487365980cmflodman@webrtc.org               << ", enacle " << enable;
421b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
422b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  ViEChannelManagerScoped cs(*(shared_data_->channel_manager()));
423b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  ViEChannel* vie_channel = cs.Channel(video_channel);
424b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  if (!vie_channel) {
425b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    shared_data_->SetLastError(kViECodecInvalidChannelId);
426b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    return -1;
427b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  }
428b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  if (vie_channel->EnableKeyFrameRequestCallback(enable) != 0) {
429b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    shared_data_->SetLastError(kViECodecUnknownError);
430b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    return -1;
431b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  }
432b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  return 0;
433b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
434b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
435b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgint ViECodecImpl::SetSignalKeyPacketLossStatus(const int video_channel,
436b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org                                               const bool enable,
437b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org                                               const bool only_key_frames) {
438022615bd918aec7671968ad2b873d1487365980cmflodman@webrtc.org  LOG(LS_INFO) << "SetSignalKeyPacketLossStatus for " << video_channel
439022615bd918aec7671968ad2b873d1487365980cmflodman@webrtc.org               << "enable, " << enable
440022615bd918aec7671968ad2b873d1487365980cmflodman@webrtc.org               << ", only key frames " << only_key_frames;
441b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
442b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  ViEChannelManagerScoped cs(*(shared_data_->channel_manager()));
443b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  ViEChannel* vie_channel = cs.Channel(video_channel);
444b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  if (!vie_channel) {
445b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    shared_data_->SetLastError(kViECodecInvalidChannelId);
446b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    return -1;
447b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  }
448b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  if (vie_channel->SetSignalPacketLossStatus(enable, only_key_frames) != 0) {
449b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    shared_data_->SetLastError(kViECodecUnknownError);
450b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    return -1;
451b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  }
452b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  return 0;
453b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
454b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
455b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgint ViECodecImpl::RegisterEncoderObserver(const int video_channel,
456b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org                                          ViEEncoderObserver& observer) {
457022615bd918aec7671968ad2b873d1487365980cmflodman@webrtc.org  LOG(LS_INFO) << "RegisterEncoderObserver for channel " << video_channel;
458b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
459b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  ViEChannelManagerScoped cs(*(shared_data_->channel_manager()));
460b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  ViEEncoder* vie_encoder = cs.Encoder(video_channel);
461b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  if (!vie_encoder) {
462b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    shared_data_->SetLastError(kViECodecInvalidChannelId);
463b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    return -1;
464b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  }
465b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  if (vie_encoder->RegisterCodecObserver(&observer) != 0) {
466b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    shared_data_->SetLastError(kViECodecObserverAlreadyRegistered);
467b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    return -1;
468b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  }
469b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  return 0;
470b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
471b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
472b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgint ViECodecImpl::DeregisterEncoderObserver(const int video_channel) {
473022615bd918aec7671968ad2b873d1487365980cmflodman@webrtc.org  LOG(LS_INFO) << "DeregisterEncoderObserver for channel " << video_channel;
474b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
475b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  ViEChannelManagerScoped cs(*(shared_data_->channel_manager()));
476b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  ViEEncoder* vie_encoder = cs.Encoder(video_channel);
477b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  if (!vie_encoder) {
478b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    shared_data_->SetLastError(kViECodecInvalidChannelId);
479b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    return -1;
480b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  }
481b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  if (vie_encoder->RegisterCodecObserver(NULL) != 0) {
482b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    shared_data_->SetLastError(kViECodecObserverNotRegistered);
483b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    return -1;
484b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  }
485b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  return 0;
486b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
487b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
488b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgint ViECodecImpl::RegisterDecoderObserver(const int video_channel,
489b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org                                          ViEDecoderObserver& observer) {
490022615bd918aec7671968ad2b873d1487365980cmflodman@webrtc.org  LOG(LS_INFO) << "RegisterDecoderObserver for channel " << video_channel;
491b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
492b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  ViEChannelManagerScoped cs(*(shared_data_->channel_manager()));
493b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  ViEChannel* vie_channel = cs.Channel(video_channel);
494b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  if (!vie_channel) {
495b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    shared_data_->SetLastError(kViECodecInvalidChannelId);
496b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    return -1;
497b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  }
498b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  if (vie_channel->RegisterCodecObserver(&observer) != 0) {
499b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    shared_data_->SetLastError(kViECodecObserverAlreadyRegistered);
500b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    return -1;
501b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  }
502b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  return 0;
503b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
504b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
505b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgint ViECodecImpl::DeregisterDecoderObserver(const int video_channel) {
506022615bd918aec7671968ad2b873d1487365980cmflodman@webrtc.org  LOG(LS_INFO) << "DeregisterDecodeObserver for channel " << video_channel;
507b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
508b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  ViEChannelManagerScoped cs(*(shared_data_->channel_manager()));
509b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  ViEChannel* vie_channel = cs.Channel(video_channel);
510b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  if (!vie_channel) {
511b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    shared_data_->SetLastError(kViECodecInvalidChannelId);
512b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    return -1;
513b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  }
514b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  if (vie_channel->RegisterCodecObserver(NULL) != 0) {
515b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    shared_data_->SetLastError(kViECodecObserverNotRegistered);
516b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    return -1;
517b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  }
518b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  return 0;
519b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
520b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
521b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgint ViECodecImpl::SendKeyFrame(const int video_channel) {
522022615bd918aec7671968ad2b873d1487365980cmflodman@webrtc.org  LOG(LS_INFO) << "SendKeyFrame on channel " << video_channel;
523b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
524b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  ViEChannelManagerScoped cs(*(shared_data_->channel_manager()));
525b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  ViEEncoder* vie_encoder = cs.Encoder(video_channel);
526b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  if (!vie_encoder) {
527b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    shared_data_->SetLastError(kViECodecInvalidChannelId);
528b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    return -1;
529b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  }
530b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  if (vie_encoder->SendKeyFrame() != 0) {
531b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    shared_data_->SetLastError(kViECodecUnknownError);
532b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    return -1;
533b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  }
534b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  return 0;
535b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
536b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
537b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgint ViECodecImpl::WaitForFirstKeyFrame(const int video_channel,
538b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org                                       const bool wait) {
539022615bd918aec7671968ad2b873d1487365980cmflodman@webrtc.org  LOG(LS_INFO) << "WaitForFirstKeyFrame for channel " << video_channel
540022615bd918aec7671968ad2b873d1487365980cmflodman@webrtc.org               << ", wait " << wait;
541b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
542b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  ViEChannelManagerScoped cs(*(shared_data_->channel_manager()));
543b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  ViEChannel* vie_channel = cs.Channel(video_channel);
544b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  if (!vie_channel) {
545b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    shared_data_->SetLastError(kViECodecInvalidChannelId);
546b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    return -1;
547b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  }
548b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  if (vie_channel->WaitForKeyFrame(wait) != 0) {
549b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    shared_data_->SetLastError(kViECodecUnknownError);
550b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    return -1;
551b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  }
552b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  return 0;
553b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
554b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
5550291c803da147cf113e829562f281479be8f2c11mflodman@webrtc.orgint ViECodecImpl::StartDebugRecording(int video_channel,
5560291c803da147cf113e829562f281479be8f2c11mflodman@webrtc.org                                      const char* file_name_utf8) {
557022615bd918aec7671968ad2b873d1487365980cmflodman@webrtc.org  LOG(LS_INFO) << "StartDebugRecording for channel " << video_channel;
5580291c803da147cf113e829562f281479be8f2c11mflodman@webrtc.org  ViEChannelManagerScoped cs(*(shared_data_->channel_manager()));
5590291c803da147cf113e829562f281479be8f2c11mflodman@webrtc.org  ViEEncoder* vie_encoder = cs.Encoder(video_channel);
5600291c803da147cf113e829562f281479be8f2c11mflodman@webrtc.org  if (!vie_encoder) {
5610291c803da147cf113e829562f281479be8f2c11mflodman@webrtc.org    return -1;
5620291c803da147cf113e829562f281479be8f2c11mflodman@webrtc.org  }
5630291c803da147cf113e829562f281479be8f2c11mflodman@webrtc.org  return vie_encoder->StartDebugRecording(file_name_utf8);
5640291c803da147cf113e829562f281479be8f2c11mflodman@webrtc.org}
5650291c803da147cf113e829562f281479be8f2c11mflodman@webrtc.org
5660291c803da147cf113e829562f281479be8f2c11mflodman@webrtc.orgint ViECodecImpl::StopDebugRecording(int video_channel) {
567022615bd918aec7671968ad2b873d1487365980cmflodman@webrtc.org  LOG(LS_INFO) << "StopDebugRecording for channel " << video_channel;
5680291c803da147cf113e829562f281479be8f2c11mflodman@webrtc.org  ViEChannelManagerScoped cs(*(shared_data_->channel_manager()));
5690291c803da147cf113e829562f281479be8f2c11mflodman@webrtc.org  ViEEncoder* vie_encoder = cs.Encoder(video_channel);
5700291c803da147cf113e829562f281479be8f2c11mflodman@webrtc.org  if (!vie_encoder) {
5710291c803da147cf113e829562f281479be8f2c11mflodman@webrtc.org    return -1;
5720291c803da147cf113e829562f281479be8f2c11mflodman@webrtc.org  }
5730291c803da147cf113e829562f281479be8f2c11mflodman@webrtc.org  return vie_encoder->StopDebugRecording();
5740291c803da147cf113e829562f281479be8f2c11mflodman@webrtc.org}
5750291c803da147cf113e829562f281479be8f2c11mflodman@webrtc.org
5764590177aa3346a742e8f71c8bcc5b81618d21919henrik.lundin@webrtc.orgvoid ViECodecImpl::SuspendBelowMinBitrate(int video_channel) {
577022615bd918aec7671968ad2b873d1487365980cmflodman@webrtc.org  LOG(LS_INFO) << "SuspendBelowMinBitrate for channel " << video_channel;
57839079d1ee84faab899c8af92bce984c20e60fd29henrik.lundin@webrtc.org  ViEChannelManagerScoped cs(*(shared_data_->channel_manager()));
57939079d1ee84faab899c8af92bce984c20e60fd29henrik.lundin@webrtc.org  ViEEncoder* vie_encoder = cs.Encoder(video_channel);
58039079d1ee84faab899c8af92bce984c20e60fd29henrik.lundin@webrtc.org  if (!vie_encoder) {
58139079d1ee84faab899c8af92bce984c20e60fd29henrik.lundin@webrtc.org    return;
58239079d1ee84faab899c8af92bce984c20e60fd29henrik.lundin@webrtc.org  }
583b9f1eb8f2950c45d8dad97183ceb30c7f04d6f8chenrik.lundin@webrtc.org  vie_encoder->SuspendBelowMinBitrate();
584b9f1eb8f2950c45d8dad97183ceb30c7f04d6f8chenrik.lundin@webrtc.org  ViEChannel* vie_channel = cs.Channel(video_channel);
585b9f1eb8f2950c45d8dad97183ceb30c7f04d6f8chenrik.lundin@webrtc.org  if (!vie_channel) {
586b9f1eb8f2950c45d8dad97183ceb30c7f04d6f8chenrik.lundin@webrtc.org    return;
587b9f1eb8f2950c45d8dad97183ceb30c7f04d6f8chenrik.lundin@webrtc.org  }
588b9f1eb8f2950c45d8dad97183ceb30c7f04d6f8chenrik.lundin@webrtc.org  // Must enable pacing when enabling SuspendBelowMinBitrate. Otherwise, no
589b9f1eb8f2950c45d8dad97183ceb30c7f04d6f8chenrik.lundin@webrtc.org  // padding will be sent when the video is suspended so the video will be
590b9f1eb8f2950c45d8dad97183ceb30c7f04d6f8chenrik.lundin@webrtc.org  // unable to recover.
591b9f1eb8f2950c45d8dad97183ceb30c7f04d6f8chenrik.lundin@webrtc.org  vie_channel->SetTransmissionSmoothingStatus(true);
59239079d1ee84faab899c8af92bce984c20e60fd29henrik.lundin@webrtc.org}
59339079d1ee84faab899c8af92bce984c20e60fd29henrik.lundin@webrtc.org
594ee234be7908840221b78e6489d42ea792d4ce87dstefan@webrtc.orgbool ViECodecImpl::GetSendSideDelay(int video_channel, int* avg_delay_ms,
595ee234be7908840221b78e6489d42ea792d4ce87dstefan@webrtc.org                                   int* max_delay_ms) const {
596ee234be7908840221b78e6489d42ea792d4ce87dstefan@webrtc.org  ViEChannelManagerScoped cs(*(shared_data_->channel_manager()));
597ee234be7908840221b78e6489d42ea792d4ce87dstefan@webrtc.org  ViEChannel* vie_channel = cs.Channel(video_channel);
598ee234be7908840221b78e6489d42ea792d4ce87dstefan@webrtc.org  if (!vie_channel) {
599ee234be7908840221b78e6489d42ea792d4ce87dstefan@webrtc.org    shared_data_->SetLastError(kViECodecInvalidChannelId);
600ee234be7908840221b78e6489d42ea792d4ce87dstefan@webrtc.org    return false;
601ee234be7908840221b78e6489d42ea792d4ce87dstefan@webrtc.org  }
602ee234be7908840221b78e6489d42ea792d4ce87dstefan@webrtc.org  return vie_channel->GetSendSideDelay(avg_delay_ms, max_delay_ms);
603ee234be7908840221b78e6489d42ea792d4ce87dstefan@webrtc.org}
604ee234be7908840221b78e6489d42ea792d4ce87dstefan@webrtc.org
605b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgbool ViECodecImpl::CodecValid(const VideoCodec& video_codec) {
606b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  // Check pl_name matches codec_type.
607b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  if (video_codec.codecType == kVideoCodecRED) {
608b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org#if defined(WIN32)
609b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    if (_strnicmp(video_codec.plName, "red", 3) == 0) {
610b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org#else
611b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    if (strncasecmp(video_codec.plName, "red", 3) == 0) {
612b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org#endif
613b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org      // We only care about the type and name for red.
614b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org      return true;
615b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    }
616022615bd918aec7671968ad2b873d1487365980cmflodman@webrtc.org    LOG_F(LS_ERROR) << "Invalid RED configuration.";
617b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    return false;
618b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  } else if (video_codec.codecType == kVideoCodecULPFEC) {
619b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org#if defined(WIN32)
620b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    if (_strnicmp(video_codec.plName, "ULPFEC", 6) == 0) {
621b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org#else
622b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    if (strncasecmp(video_codec.plName, "ULPFEC", 6) == 0) {
623b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org#endif
624b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org      // We only care about the type and name for ULPFEC.
625b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org      return true;
626b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    }
627022615bd918aec7671968ad2b873d1487365980cmflodman@webrtc.org    LOG_F(LS_ERROR) << "Invalid ULPFEC configuration.";
628b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    return false;
629b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  } else if ((video_codec.codecType == kVideoCodecVP8 &&
630e3339fcb0795bf0e6fbf148133c8b79bcecc5edepbos@webrtc.org              strncmp(video_codec.plName, "VP8", 4) == 0) ||
631e3339fcb0795bf0e6fbf148133c8b79bcecc5edepbos@webrtc.org             (video_codec.codecType == kVideoCodecI420 &&
6322ed1cd9e2a299a7858e21c332bcf6dfb27c4f037pbos@webrtc.org              strncmp(video_codec.plName, "I420", 4) == 0)) {
633b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    // OK.
6342ed1cd9e2a299a7858e21c332bcf6dfb27c4f037pbos@webrtc.org  } else if (video_codec.codecType != kVideoCodecGeneric) {
635022615bd918aec7671968ad2b873d1487365980cmflodman@webrtc.org    LOG(LS_ERROR) << "Codec type and name mismatch.";
636b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    return false;
637b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  }
638b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
639e7a9bd4c296a9cfce583aa82d567b973a86717b9braveyao@webrtc.org  if (video_codec.plType == 0 || video_codec.plType > 127) {
640022615bd918aec7671968ad2b873d1487365980cmflodman@webrtc.org    LOG(LS_ERROR) << "Invalif payload type: " << video_codec.plType;
641b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    return false;
642b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  }
643b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
644b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  if (video_codec.width > kViEMaxCodecWidth ||
645b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org      video_codec.height > kViEMaxCodecHeight) {
646022615bd918aec7671968ad2b873d1487365980cmflodman@webrtc.org    LOG(LS_ERROR) << "Invalid codec resolution " << video_codec.width
647022615bd918aec7671968ad2b873d1487365980cmflodman@webrtc.org                  << " x " << video_codec.height;
648b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    return false;
649b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  }
650b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
651b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  if (video_codec.startBitrate < kViEMinCodecBitrate) {
652022615bd918aec7671968ad2b873d1487365980cmflodman@webrtc.org    LOG(LS_ERROR) << "Invalid start bitrate.";
653b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    return false;
654b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  }
655b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  if (video_codec.minBitrate < kViEMinCodecBitrate) {
656022615bd918aec7671968ad2b873d1487365980cmflodman@webrtc.org    LOG(LS_ERROR) << "Invalid min bitrate.";
657b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    return false;
658b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  }
659b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  return true;
660b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
661b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
662b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}  // namespace webrtc
663