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    }
722d4a80c05adffe07b48dc235475852450cd90568stefan@webrtc.org  } else if (codec.codecType == kVideoCodecH264) {
732d4a80c05adffe07b48dc235475852450cd90568stefan@webrtc.org    LOG(LS_INFO) << "H264 specific settings";
742d4a80c05adffe07b48dc235475852450cd90568stefan@webrtc.org    LOG(LS_INFO) << "profile: "
752d4a80c05adffe07b48dc235475852450cd90568stefan@webrtc.org                 <<  codec.codecSpecific.H264.profile
762d4a80c05adffe07b48dc235475852450cd90568stefan@webrtc.org                 << ", framedropping: "
772d4a80c05adffe07b48dc235475852450cd90568stefan@webrtc.org                 << codec.codecSpecific.H264.frameDroppingOn
782d4a80c05adffe07b48dc235475852450cd90568stefan@webrtc.org                 << ", keyFrameInterval: "
792d4a80c05adffe07b48dc235475852450cd90568stefan@webrtc.org                 << codec.codecSpecific.H264.keyFrameInterval
802d4a80c05adffe07b48dc235475852450cd90568stefan@webrtc.org                 << ", spslen: "
812d4a80c05adffe07b48dc235475852450cd90568stefan@webrtc.org                 << codec.codecSpecific.H264.spsLen
822d4a80c05adffe07b48dc235475852450cd90568stefan@webrtc.org                 << ", ppslen: "
832d4a80c05adffe07b48dc235475852450cd90568stefan@webrtc.org                 << codec.codecSpecific.H264.ppsLen;
84022615bd918aec7671968ad2b873d1487365980cmflodman@webrtc.org  }
85022615bd918aec7671968ad2b873d1487365980cmflodman@webrtc.org}
86022615bd918aec7671968ad2b873d1487365980cmflodman@webrtc.org
87022615bd918aec7671968ad2b873d1487365980cmflodman@webrtc.org
88b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgViECodec* ViECodec::GetInterface(VideoEngine* video_engine) {
89b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org#ifdef WEBRTC_VIDEO_ENGINE_CODEC_API
90b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  if (!video_engine) {
91b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    return NULL;
92b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  }
937ab726855f2ceb9ff6365e3240668d58f45e6761andrew@webrtc.org  VideoEngineImpl* vie_impl = static_cast<VideoEngineImpl*>(video_engine);
94b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  ViECodecImpl* vie_codec_impl = vie_impl;
95b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  // Increase ref count.
96b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  (*vie_codec_impl)++;
97b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  return vie_codec_impl;
98b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org#else
99b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  return NULL;
100b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org#endif
101b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
102b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
103b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgint ViECodecImpl::Release() {
104022615bd918aec7671968ad2b873d1487365980cmflodman@webrtc.org  LOG(LS_INFO) << "ViECodec::Release.";
105b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  // Decrease ref count.
106b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  (*this)--;
107b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
10867879bc2e69d7907b7ceb92135a34f77fe643e7fpbos@webrtc.org  int32_t ref_count = GetCount();
109b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  if (ref_count < 0) {
110022615bd918aec7671968ad2b873d1487365980cmflodman@webrtc.org    LOG(LS_WARNING) << "ViECodec released too many times.";
111b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    shared_data_->SetLastError(kViEAPIDoesNotExist);
112b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    return -1;
113b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  }
114b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  return ref_count;
115b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
116b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
117b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgViECodecImpl::ViECodecImpl(ViESharedData* shared_data)
118b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    : shared_data_(shared_data) {
119b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
120b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
121b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgViECodecImpl::~ViECodecImpl() {
122b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
123b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
124b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgint ViECodecImpl::NumberOfCodecs() const {
125b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  // +2 because of FEC(RED and ULPFEC)
126b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  return static_cast<int>((VideoCodingModule::NumberOfCodecs() + 2));
127b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
128b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
129b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgint ViECodecImpl::GetCodec(const unsigned char list_number,
130b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org                           VideoCodec& video_codec) const {
131b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  if (list_number == VideoCodingModule::NumberOfCodecs()) {
132b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    memset(&video_codec, 0, sizeof(VideoCodec));
133bea854aac01d4a950a0062892d2205c37b15cc40mflodman@webrtc.org    strcpy(video_codec.plName, "red");
134b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    video_codec.codecType = kVideoCodecRED;
135b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    video_codec.plType = VCM_RED_PAYLOAD_TYPE;
136b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  } else if (list_number == VideoCodingModule::NumberOfCodecs() + 1) {
137b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    memset(&video_codec, 0, sizeof(VideoCodec));
138bea854aac01d4a950a0062892d2205c37b15cc40mflodman@webrtc.org    strcpy(video_codec.plName, "ulpfec");
139b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    video_codec.codecType = kVideoCodecULPFEC;
140b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    video_codec.plType = VCM_ULPFEC_PAYLOAD_TYPE;
141b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  } else if (VideoCodingModule::Codec(list_number, &video_codec) != VCM_OK) {
142b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    shared_data_->SetLastError(kViECodecInvalidArgument);
143b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    return -1;
144b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  }
145b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  return 0;
146b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
147b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
148b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgint ViECodecImpl::SetSendCodec(const int video_channel,
149b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org                               const VideoCodec& video_codec) {
150022615bd918aec7671968ad2b873d1487365980cmflodman@webrtc.org  LOG(LS_INFO) << "SetSendCodec for channel " << video_channel;
151022615bd918aec7671968ad2b873d1487365980cmflodman@webrtc.org  LogCodec(video_codec);
152b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  if (!CodecValid(video_codec)) {
153b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    // Error logged.
154b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    shared_data_->SetLastError(kViECodecInvalidCodec);
155b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    return -1;
156b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  }
157b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
158b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  ViEChannelManagerScoped cs(*(shared_data_->channel_manager()));
159b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  ViEChannel* vie_channel = cs.Channel(video_channel);
160b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  if (!vie_channel) {
161b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    shared_data_->SetLastError(kViECodecInvalidChannelId);
162b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    return -1;
163b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  }
164b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
165b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  ViEEncoder* vie_encoder = cs.Encoder(video_channel);
166b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  assert(vie_encoder);
167b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  if (vie_encoder->Owner() != video_channel) {
168022615bd918aec7671968ad2b873d1487365980cmflodman@webrtc.org    LOG_F(LS_ERROR) << "Receive only channel.";
169b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    shared_data_->SetLastError(kViECodecReceiveOnlyChannel);
170b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    return -1;
171b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  }
172b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  // Set a max_bitrate if the user hasn't set one.
173b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  VideoCodec video_codec_internal;
174b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  memcpy(&video_codec_internal, &video_codec, sizeof(VideoCodec));
175b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  if (video_codec_internal.maxBitrate == 0) {
176b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    // Max is one bit per pixel.
177b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    video_codec_internal.maxBitrate = (video_codec_internal.width *
178b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org                                       video_codec_internal.height *
179b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org                                       video_codec_internal.maxFramerate)
180b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org                                       / 1000;
181022615bd918aec7671968ad2b873d1487365980cmflodman@webrtc.org    LOG(LS_INFO) << "New max bitrate set " << video_codec_internal.maxBitrate;
182b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  }
183b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
184543520819967835da38d529690df36b608bc9970mflodman@webrtc.org  if (video_codec_internal.startBitrate < video_codec_internal.minBitrate) {
185543520819967835da38d529690df36b608bc9970mflodman@webrtc.org    video_codec_internal.startBitrate = video_codec_internal.minBitrate;
186543520819967835da38d529690df36b608bc9970mflodman@webrtc.org  }
187a9a7327cd1bb55cb05ab28a12e265ffefc1b5da4mflodman@webrtc.org  if (video_codec_internal.startBitrate > video_codec_internal.maxBitrate) {
188a9a7327cd1bb55cb05ab28a12e265ffefc1b5da4mflodman@webrtc.org    video_codec_internal.startBitrate = video_codec_internal.maxBitrate;
189a9a7327cd1bb55cb05ab28a12e265ffefc1b5da4mflodman@webrtc.org  }
190a9a7327cd1bb55cb05ab28a12e265ffefc1b5da4mflodman@webrtc.org
191b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  VideoCodec encoder;
192b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  vie_encoder->GetEncoder(&encoder);
193b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
194b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  // Make sure to generate a new SSRC if the codec type and/or resolution has
195b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  // changed. This won't have any effect if the user has set an SSRC.
196b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  bool new_rtp_stream = false;
197b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  if (encoder.codecType != video_codec_internal.codecType) {
198b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    new_rtp_stream = true;
199b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  }
200b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
201b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  ViEInputManagerScoped is(*(shared_data_->input_manager()));
202b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
203b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  // Stop the media flow while reconfiguring.
204b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  vie_encoder->Pause();
205b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
206a18c6e5b2811221b60e3d7e72516aa20927e13ddmflodman@webrtc.org  if (vie_encoder->SetEncoder(video_codec_internal) != 0) {
207b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    shared_data_->SetLastError(kViECodecUnknownError);
208b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    return -1;
209b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  }
210b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
211b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  // Give the channel(s) the new information.
212b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  ChannelList channels;
213b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  cs.ChannelsUsingViEEncoder(video_channel, &channels);
214b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  for (ChannelList::iterator it = channels.begin(); it != channels.end();
215b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org       ++it) {
216b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    bool ret = true;
217b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    if ((*it)->SetSendCodec(video_codec_internal, new_rtp_stream) != 0) {
218b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org      ret = false;
219b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    }
220b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    if (!ret) {
221b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org      shared_data_->SetLastError(kViECodecUnknownError);
222b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org      return -1;
223b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    }
224b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  }
225b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
226b6d9cfc6347e490751e142ba5fb89e4a975ed442mflodman@webrtc.org  // TODO(mflodman) Break out this part in GetLocalSsrcList().
227b6d9cfc6347e490751e142ba5fb89e4a975ed442mflodman@webrtc.org  // Update all SSRCs to ViEEncoder.
228b6d9cfc6347e490751e142ba5fb89e4a975ed442mflodman@webrtc.org  std::list<unsigned int> ssrcs;
229b6d9cfc6347e490751e142ba5fb89e4a975ed442mflodman@webrtc.org  if (video_codec_internal.numberOfSimulcastStreams == 0) {
230b6d9cfc6347e490751e142ba5fb89e4a975ed442mflodman@webrtc.org    unsigned int ssrc = 0;
231b6d9cfc6347e490751e142ba5fb89e4a975ed442mflodman@webrtc.org    if (vie_channel->GetLocalSSRC(0, &ssrc) != 0) {
232022615bd918aec7671968ad2b873d1487365980cmflodman@webrtc.org      LOG_F(LS_ERROR) << "Could not get ssrc.";
233b6d9cfc6347e490751e142ba5fb89e4a975ed442mflodman@webrtc.org    }
234b6d9cfc6347e490751e142ba5fb89e4a975ed442mflodman@webrtc.org    ssrcs.push_back(ssrc);
235b6d9cfc6347e490751e142ba5fb89e4a975ed442mflodman@webrtc.org  } else {
236b6d9cfc6347e490751e142ba5fb89e4a975ed442mflodman@webrtc.org    for (int idx = 0; idx < video_codec_internal.numberOfSimulcastStreams;
237b6d9cfc6347e490751e142ba5fb89e4a975ed442mflodman@webrtc.org         ++idx) {
238b6d9cfc6347e490751e142ba5fb89e4a975ed442mflodman@webrtc.org      unsigned int ssrc = 0;
239b6d9cfc6347e490751e142ba5fb89e4a975ed442mflodman@webrtc.org      if (vie_channel->GetLocalSSRC(idx, &ssrc) != 0) {
240022615bd918aec7671968ad2b873d1487365980cmflodman@webrtc.org        LOG_F(LS_ERROR) << "Could not get ssrc for stream " << idx;
241b6d9cfc6347e490751e142ba5fb89e4a975ed442mflodman@webrtc.org      }
242b6d9cfc6347e490751e142ba5fb89e4a975ed442mflodman@webrtc.org      ssrcs.push_back(ssrc);
243b6d9cfc6347e490751e142ba5fb89e4a975ed442mflodman@webrtc.org    }
244b6d9cfc6347e490751e142ba5fb89e4a975ed442mflodman@webrtc.org  }
245b6d9cfc6347e490751e142ba5fb89e4a975ed442mflodman@webrtc.org  vie_encoder->SetSsrcs(ssrcs);
246b6d9cfc6347e490751e142ba5fb89e4a975ed442mflodman@webrtc.org  shared_data_->channel_manager()->UpdateSsrcs(video_channel, ssrcs);
247b6d9cfc6347e490751e142ba5fb89e4a975ed442mflodman@webrtc.org
248b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  // Update the protection mode, we might be switching NACK/FEC.
2497fc75bbb65cc1cd99fdf45d9fce44bcce1396dfawu@webrtc.org  vie_encoder->UpdateProtectionMethod(vie_encoder->nack_enabled());
250b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
251b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  // Get new best format for frame provider.
2528704595e8820b9c3692dad8a8d8ff7b220b32455pbos@webrtc.org  ViEFrameProviderBase* frame_provider = is.FrameProvider(vie_encoder);
253b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  if (frame_provider) {
254b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    frame_provider->FrameCallbackChanged();
255b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  }
256b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  // Restart the media flow
257b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  if (new_rtp_stream) {
258b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    // Stream settings changed, make sure we get a key frame.
259b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    vie_encoder->SendKeyFrame();
260b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  }
261b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  vie_encoder->Restart();
262b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  return 0;
263b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
264b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
265b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgint ViECodecImpl::GetSendCodec(const int video_channel,
266b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org                               VideoCodec& video_codec) const {
267b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  ViEChannelManagerScoped cs(*(shared_data_->channel_manager()));
268b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  ViEEncoder* vie_encoder = cs.Encoder(video_channel);
269b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  if (!vie_encoder) {
270b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    shared_data_->SetLastError(kViECodecInvalidChannelId);
271b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    return -1;
272b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  }
273b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  return vie_encoder->GetEncoder(&video_codec);
274b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
275b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
276b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgint ViECodecImpl::SetReceiveCodec(const int video_channel,
277b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org                                  const VideoCodec& video_codec) {
278022615bd918aec7671968ad2b873d1487365980cmflodman@webrtc.org  LOG(LS_INFO) << "SetReceiveCodec for channel " << video_channel;
279022615bd918aec7671968ad2b873d1487365980cmflodman@webrtc.org  LOG(LS_INFO) << "Codec type " << video_codec.codecType
280022615bd918aec7671968ad2b873d1487365980cmflodman@webrtc.org               << ", payload type " << video_codec.plType;
281b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
282b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  if (CodecValid(video_codec) == false) {
283b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    shared_data_->SetLastError(kViECodecInvalidCodec);
284b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    return -1;
285b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  }
286b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
287b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  ViEChannelManagerScoped cs(*(shared_data_->channel_manager()));
288b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  ViEChannel* vie_channel = cs.Channel(video_channel);
289b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  if (!vie_channel) {
290b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    shared_data_->SetLastError(kViECodecInvalidChannelId);
291b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    return -1;
292b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  }
293b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
294b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  if (vie_channel->SetReceiveCodec(video_codec) != 0) {
295b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    shared_data_->SetLastError(kViECodecUnknownError);
296b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    return -1;
297b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  }
298b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  return 0;
299b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
300b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
301b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgint ViECodecImpl::GetReceiveCodec(const int video_channel,
302b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org                                  VideoCodec& video_codec) const {
303b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  ViEChannelManagerScoped cs(*(shared_data_->channel_manager()));
304b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  ViEChannel* vie_channel = cs.Channel(video_channel);
305b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  if (!vie_channel) {
306b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    shared_data_->SetLastError(kViECodecInvalidChannelId);
307b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    return -1;
308b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  }
309b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
310b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  if (vie_channel->GetReceiveCodec(&video_codec) != 0) {
311b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    shared_data_->SetLastError(kViECodecUnknownError);
312b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    return -1;
313b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  }
314b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  return 0;
315b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
316b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
317b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgint ViECodecImpl::GetCodecConfigParameters(
318b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  const int video_channel,
319b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  unsigned char config_parameters[kConfigParameterSize],
320b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  unsigned char& config_parameters_size) const {
321022615bd918aec7671968ad2b873d1487365980cmflodman@webrtc.org  LOG(LS_INFO) << "GetCodecConfigParameters " << video_channel;
322b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
323b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  ViEChannelManagerScoped cs(*(shared_data_->channel_manager()));
324b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  ViEEncoder* vie_encoder = cs.Encoder(video_channel);
325b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  if (!vie_encoder) {
326b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    shared_data_->SetLastError(kViECodecInvalidChannelId);
327b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    return -1;
328b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  }
329b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
330b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  if (vie_encoder->GetCodecConfigParameters(config_parameters,
331b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org                                            config_parameters_size) != 0) {
332b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    shared_data_->SetLastError(kViECodecUnknownError);
333b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    return -1;
334b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  }
335b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  return 0;
336b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
337b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
338b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgint ViECodecImpl::SetImageScaleStatus(const int video_channel,
339b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org                                      const bool enable) {
340022615bd918aec7671968ad2b873d1487365980cmflodman@webrtc.org  LOG(LS_INFO) << "SetImageScaleStates for channel " << video_channel
341022615bd918aec7671968ad2b873d1487365980cmflodman@webrtc.org               << ", enable: " << enable;
342b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
343b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  ViEChannelManagerScoped cs(*(shared_data_->channel_manager()));
344b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  ViEEncoder* vie_encoder = cs.Encoder(video_channel);
345b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  if (!vie_encoder) {
346b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    shared_data_->SetLastError(kViECodecInvalidChannelId);
347b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    return -1;
348b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  }
349b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
350b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  if (vie_encoder->ScaleInputImage(enable) != 0) {
351b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    shared_data_->SetLastError(kViECodecUnknownError);
352b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    return -1;
353b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  }
354b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  return 0;
355b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
356b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
357b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgint ViECodecImpl::GetSendCodecStastistics(const int video_channel,
358b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org                                          unsigned int& key_frames,
359b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org                                          unsigned int& delta_frames) const {
360b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  ViEChannelManagerScoped cs(*(shared_data_->channel_manager()));
361b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  ViEEncoder* vie_encoder = cs.Encoder(video_channel);
362b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  if (!vie_encoder) {
363b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    shared_data_->SetLastError(kViECodecInvalidChannelId);
364b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    return -1;
365b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  }
366b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
367b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  if (vie_encoder->SendCodecStatistics(&key_frames, &delta_frames) != 0) {
368b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    shared_data_->SetLastError(kViECodecUnknownError);
369b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    return -1;
370b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  }
371b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  return 0;
372b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
373b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
374b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgint ViECodecImpl::GetReceiveCodecStastistics(const int video_channel,
375b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org                                             unsigned int& key_frames,
376b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org                                             unsigned int& delta_frames) const {
377b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  ViEChannelManagerScoped cs(*(shared_data_->channel_manager()));
378b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  ViEChannel* vie_channel = cs.Channel(video_channel);
379b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  if (!vie_channel) {
380b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    shared_data_->SetLastError(kViECodecInvalidChannelId);
381b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    return -1;
382b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  }
383b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  if (vie_channel->ReceiveCodecStatistics(&key_frames, &delta_frames) != 0) {
384b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    shared_data_->SetLastError(kViECodecUnknownError);
385b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    return -1;
386b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  }
387b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  return 0;
388b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
389b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
390f314c80eb667406101dbc5810fda799f67030a0fmflodman@webrtc.orgint ViECodecImpl::GetReceiveSideDelay(const int video_channel,
391f314c80eb667406101dbc5810fda799f67030a0fmflodman@webrtc.org                                      int* delay_ms) const {
392022615bd918aec7671968ad2b873d1487365980cmflodman@webrtc.org  assert(delay_ms != NULL);
393f314c80eb667406101dbc5810fda799f67030a0fmflodman@webrtc.org
394f314c80eb667406101dbc5810fda799f67030a0fmflodman@webrtc.org  ViEChannelManagerScoped cs(*(shared_data_->channel_manager()));
395f314c80eb667406101dbc5810fda799f67030a0fmflodman@webrtc.org  ViEChannel* vie_channel = cs.Channel(video_channel);
396f314c80eb667406101dbc5810fda799f67030a0fmflodman@webrtc.org  if (!vie_channel) {
397f314c80eb667406101dbc5810fda799f67030a0fmflodman@webrtc.org    shared_data_->SetLastError(kViECodecInvalidChannelId);
398f314c80eb667406101dbc5810fda799f67030a0fmflodman@webrtc.org    return -1;
399f314c80eb667406101dbc5810fda799f67030a0fmflodman@webrtc.org  }
400f314c80eb667406101dbc5810fda799f67030a0fmflodman@webrtc.org  *delay_ms = vie_channel->ReceiveDelay();
401f314c80eb667406101dbc5810fda799f67030a0fmflodman@webrtc.org  if (*delay_ms < 0) {
402f314c80eb667406101dbc5810fda799f67030a0fmflodman@webrtc.org    return -1;
403f314c80eb667406101dbc5810fda799f67030a0fmflodman@webrtc.org  }
404f314c80eb667406101dbc5810fda799f67030a0fmflodman@webrtc.org  return 0;
405f314c80eb667406101dbc5810fda799f67030a0fmflodman@webrtc.org}
406f314c80eb667406101dbc5810fda799f67030a0fmflodman@webrtc.org
407f314c80eb667406101dbc5810fda799f67030a0fmflodman@webrtc.org
408b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgint ViECodecImpl::GetCodecTargetBitrate(const int video_channel,
409b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org                                        unsigned int* bitrate) const {
410b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  ViEChannelManagerScoped cs(*(shared_data_->channel_manager()));
411b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  ViEEncoder* vie_encoder = cs.Encoder(video_channel);
412b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  if (!vie_encoder) {
413b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    shared_data_->SetLastError(kViECodecInvalidChannelId);
414b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    return -1;
415b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  }
41667879bc2e69d7907b7ceb92135a34f77fe643e7fpbos@webrtc.org  return vie_encoder->CodecTargetBitrate(static_cast<uint32_t*>(bitrate));
417b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
418b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
41966a45b1ce8380ffb3fffabebe1e49d1904c6bfc0asapersson@webrtc.orgint ViECodecImpl::GetNumDiscardedPackets(int video_channel) const {
420b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  ViEChannelManagerScoped cs(*(shared_data_->channel_manager()));
421b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  ViEChannel* vie_channel = cs.Channel(video_channel);
422b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  if (!vie_channel) {
423b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    shared_data_->SetLastError(kViECodecInvalidChannelId);
42466a45b1ce8380ffb3fffabebe1e49d1904c6bfc0asapersson@webrtc.org    return -1;
425b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  }
42666a45b1ce8380ffb3fffabebe1e49d1904c6bfc0asapersson@webrtc.org  return static_cast<int>(vie_channel->DiscardedPackets());
427b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
428b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
429b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgint ViECodecImpl::SetKeyFrameRequestCallbackStatus(const int video_channel,
430b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org                                                   const bool enable) {
431022615bd918aec7671968ad2b873d1487365980cmflodman@webrtc.org  LOG(LS_INFO) << "SetKeyFrameRequestCallbackStatus for " << video_channel
43266a45b1ce8380ffb3fffabebe1e49d1904c6bfc0asapersson@webrtc.org               << ", enable " << enable;
433b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
434b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  ViEChannelManagerScoped cs(*(shared_data_->channel_manager()));
435b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  ViEChannel* vie_channel = cs.Channel(video_channel);
436b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  if (!vie_channel) {
437b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    shared_data_->SetLastError(kViECodecInvalidChannelId);
438b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    return -1;
439b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  }
440b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  if (vie_channel->EnableKeyFrameRequestCallback(enable) != 0) {
441b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    shared_data_->SetLastError(kViECodecUnknownError);
442b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    return -1;
443b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  }
444b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  return 0;
445b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
446b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
447b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgint ViECodecImpl::SetSignalKeyPacketLossStatus(const int video_channel,
448b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org                                               const bool enable,
449b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org                                               const bool only_key_frames) {
450022615bd918aec7671968ad2b873d1487365980cmflodman@webrtc.org  LOG(LS_INFO) << "SetSignalKeyPacketLossStatus for " << video_channel
451022615bd918aec7671968ad2b873d1487365980cmflodman@webrtc.org               << "enable, " << enable
452022615bd918aec7671968ad2b873d1487365980cmflodman@webrtc.org               << ", only key frames " << only_key_frames;
453b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
454b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  ViEChannelManagerScoped cs(*(shared_data_->channel_manager()));
455b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  ViEChannel* vie_channel = cs.Channel(video_channel);
456b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  if (!vie_channel) {
457b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    shared_data_->SetLastError(kViECodecInvalidChannelId);
458b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    return -1;
459b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  }
460b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  if (vie_channel->SetSignalPacketLossStatus(enable, only_key_frames) != 0) {
461b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    shared_data_->SetLastError(kViECodecUnknownError);
462b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    return -1;
463b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  }
464b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  return 0;
465b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
466b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
467b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgint ViECodecImpl::RegisterEncoderObserver(const int video_channel,
468b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org                                          ViEEncoderObserver& observer) {
469022615bd918aec7671968ad2b873d1487365980cmflodman@webrtc.org  LOG(LS_INFO) << "RegisterEncoderObserver for channel " << video_channel;
470b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
471b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  ViEChannelManagerScoped cs(*(shared_data_->channel_manager()));
472b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  ViEEncoder* vie_encoder = cs.Encoder(video_channel);
473b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  if (!vie_encoder) {
474b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    shared_data_->SetLastError(kViECodecInvalidChannelId);
475b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    return -1;
476b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  }
477b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  if (vie_encoder->RegisterCodecObserver(&observer) != 0) {
478b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    shared_data_->SetLastError(kViECodecObserverAlreadyRegistered);
479b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    return -1;
480b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  }
481b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  return 0;
482b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
483b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
484b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgint ViECodecImpl::DeregisterEncoderObserver(const int video_channel) {
485022615bd918aec7671968ad2b873d1487365980cmflodman@webrtc.org  LOG(LS_INFO) << "DeregisterEncoderObserver for channel " << video_channel;
486b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
487b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  ViEChannelManagerScoped cs(*(shared_data_->channel_manager()));
488b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  ViEEncoder* vie_encoder = cs.Encoder(video_channel);
489b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  if (!vie_encoder) {
490b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    shared_data_->SetLastError(kViECodecInvalidChannelId);
491b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    return -1;
492b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  }
493b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  if (vie_encoder->RegisterCodecObserver(NULL) != 0) {
494b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    shared_data_->SetLastError(kViECodecObserverNotRegistered);
495b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    return -1;
496b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  }
497b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  return 0;
498b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
499b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
500b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgint ViECodecImpl::RegisterDecoderObserver(const int video_channel,
501b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org                                          ViEDecoderObserver& observer) {
502022615bd918aec7671968ad2b873d1487365980cmflodman@webrtc.org  LOG(LS_INFO) << "RegisterDecoderObserver for channel " << video_channel;
503b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
504b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  ViEChannelManagerScoped cs(*(shared_data_->channel_manager()));
505b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  ViEChannel* vie_channel = cs.Channel(video_channel);
506b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  if (!vie_channel) {
507b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    shared_data_->SetLastError(kViECodecInvalidChannelId);
508b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    return -1;
509b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  }
510b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  if (vie_channel->RegisterCodecObserver(&observer) != 0) {
511b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    shared_data_->SetLastError(kViECodecObserverAlreadyRegistered);
512b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    return -1;
513b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  }
514b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  return 0;
515b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
516b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
517b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgint ViECodecImpl::DeregisterDecoderObserver(const int video_channel) {
518022615bd918aec7671968ad2b873d1487365980cmflodman@webrtc.org  LOG(LS_INFO) << "DeregisterDecodeObserver for channel " << video_channel;
519b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
520b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  ViEChannelManagerScoped cs(*(shared_data_->channel_manager()));
521b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  ViEChannel* vie_channel = cs.Channel(video_channel);
522b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  if (!vie_channel) {
523b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    shared_data_->SetLastError(kViECodecInvalidChannelId);
524b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    return -1;
525b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  }
526b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  if (vie_channel->RegisterCodecObserver(NULL) != 0) {
527b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    shared_data_->SetLastError(kViECodecObserverNotRegistered);
528b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    return -1;
529b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  }
530b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  return 0;
531b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
532b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
533b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgint ViECodecImpl::SendKeyFrame(const int video_channel) {
534022615bd918aec7671968ad2b873d1487365980cmflodman@webrtc.org  LOG(LS_INFO) << "SendKeyFrame on channel " << video_channel;
535b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
536b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  ViEChannelManagerScoped cs(*(shared_data_->channel_manager()));
537b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  ViEEncoder* vie_encoder = cs.Encoder(video_channel);
538b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  if (!vie_encoder) {
539b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    shared_data_->SetLastError(kViECodecInvalidChannelId);
540b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    return -1;
541b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  }
542b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  if (vie_encoder->SendKeyFrame() != 0) {
543b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    shared_data_->SetLastError(kViECodecUnknownError);
544b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    return -1;
545b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  }
546b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  return 0;
547b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
548b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
549b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgint ViECodecImpl::WaitForFirstKeyFrame(const int video_channel,
550b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org                                       const bool wait) {
551022615bd918aec7671968ad2b873d1487365980cmflodman@webrtc.org  LOG(LS_INFO) << "WaitForFirstKeyFrame for channel " << video_channel
552022615bd918aec7671968ad2b873d1487365980cmflodman@webrtc.org               << ", wait " << wait;
553b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
554b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  ViEChannelManagerScoped cs(*(shared_data_->channel_manager()));
555b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  ViEChannel* vie_channel = cs.Channel(video_channel);
556b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  if (!vie_channel) {
557b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    shared_data_->SetLastError(kViECodecInvalidChannelId);
558b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    return -1;
559b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  }
560b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  if (vie_channel->WaitForKeyFrame(wait) != 0) {
561b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    shared_data_->SetLastError(kViECodecUnknownError);
562b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    return -1;
563b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  }
564b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  return 0;
565b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
566b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
5670291c803da147cf113e829562f281479be8f2c11mflodman@webrtc.orgint ViECodecImpl::StartDebugRecording(int video_channel,
5680291c803da147cf113e829562f281479be8f2c11mflodman@webrtc.org                                      const char* file_name_utf8) {
569022615bd918aec7671968ad2b873d1487365980cmflodman@webrtc.org  LOG(LS_INFO) << "StartDebugRecording for channel " << video_channel;
5700291c803da147cf113e829562f281479be8f2c11mflodman@webrtc.org  ViEChannelManagerScoped cs(*(shared_data_->channel_manager()));
5710291c803da147cf113e829562f281479be8f2c11mflodman@webrtc.org  ViEEncoder* vie_encoder = cs.Encoder(video_channel);
5720291c803da147cf113e829562f281479be8f2c11mflodman@webrtc.org  if (!vie_encoder) {
5730291c803da147cf113e829562f281479be8f2c11mflodman@webrtc.org    return -1;
5740291c803da147cf113e829562f281479be8f2c11mflodman@webrtc.org  }
5750291c803da147cf113e829562f281479be8f2c11mflodman@webrtc.org  return vie_encoder->StartDebugRecording(file_name_utf8);
5760291c803da147cf113e829562f281479be8f2c11mflodman@webrtc.org}
5770291c803da147cf113e829562f281479be8f2c11mflodman@webrtc.org
5780291c803da147cf113e829562f281479be8f2c11mflodman@webrtc.orgint ViECodecImpl::StopDebugRecording(int video_channel) {
579022615bd918aec7671968ad2b873d1487365980cmflodman@webrtc.org  LOG(LS_INFO) << "StopDebugRecording for channel " << video_channel;
5800291c803da147cf113e829562f281479be8f2c11mflodman@webrtc.org  ViEChannelManagerScoped cs(*(shared_data_->channel_manager()));
5810291c803da147cf113e829562f281479be8f2c11mflodman@webrtc.org  ViEEncoder* vie_encoder = cs.Encoder(video_channel);
5820291c803da147cf113e829562f281479be8f2c11mflodman@webrtc.org  if (!vie_encoder) {
5830291c803da147cf113e829562f281479be8f2c11mflodman@webrtc.org    return -1;
5840291c803da147cf113e829562f281479be8f2c11mflodman@webrtc.org  }
5850291c803da147cf113e829562f281479be8f2c11mflodman@webrtc.org  return vie_encoder->StopDebugRecording();
5860291c803da147cf113e829562f281479be8f2c11mflodman@webrtc.org}
5870291c803da147cf113e829562f281479be8f2c11mflodman@webrtc.org
5884590177aa3346a742e8f71c8bcc5b81618d21919henrik.lundin@webrtc.orgvoid ViECodecImpl::SuspendBelowMinBitrate(int video_channel) {
589022615bd918aec7671968ad2b873d1487365980cmflodman@webrtc.org  LOG(LS_INFO) << "SuspendBelowMinBitrate for channel " << video_channel;
59039079d1ee84faab899c8af92bce984c20e60fd29henrik.lundin@webrtc.org  ViEChannelManagerScoped cs(*(shared_data_->channel_manager()));
59139079d1ee84faab899c8af92bce984c20e60fd29henrik.lundin@webrtc.org  ViEEncoder* vie_encoder = cs.Encoder(video_channel);
59239079d1ee84faab899c8af92bce984c20e60fd29henrik.lundin@webrtc.org  if (!vie_encoder) {
59339079d1ee84faab899c8af92bce984c20e60fd29henrik.lundin@webrtc.org    return;
59439079d1ee84faab899c8af92bce984c20e60fd29henrik.lundin@webrtc.org  }
595b9f1eb8f2950c45d8dad97183ceb30c7f04d6f8chenrik.lundin@webrtc.org  vie_encoder->SuspendBelowMinBitrate();
596b9f1eb8f2950c45d8dad97183ceb30c7f04d6f8chenrik.lundin@webrtc.org  ViEChannel* vie_channel = cs.Channel(video_channel);
597b9f1eb8f2950c45d8dad97183ceb30c7f04d6f8chenrik.lundin@webrtc.org  if (!vie_channel) {
598b9f1eb8f2950c45d8dad97183ceb30c7f04d6f8chenrik.lundin@webrtc.org    return;
599b9f1eb8f2950c45d8dad97183ceb30c7f04d6f8chenrik.lundin@webrtc.org  }
600b9f1eb8f2950c45d8dad97183ceb30c7f04d6f8chenrik.lundin@webrtc.org  // Must enable pacing when enabling SuspendBelowMinBitrate. Otherwise, no
601b9f1eb8f2950c45d8dad97183ceb30c7f04d6f8chenrik.lundin@webrtc.org  // padding will be sent when the video is suspended so the video will be
602b9f1eb8f2950c45d8dad97183ceb30c7f04d6f8chenrik.lundin@webrtc.org  // unable to recover.
603b9f1eb8f2950c45d8dad97183ceb30c7f04d6f8chenrik.lundin@webrtc.org  vie_channel->SetTransmissionSmoothingStatus(true);
60439079d1ee84faab899c8af92bce984c20e60fd29henrik.lundin@webrtc.org}
60539079d1ee84faab899c8af92bce984c20e60fd29henrik.lundin@webrtc.org
606ee234be7908840221b78e6489d42ea792d4ce87dstefan@webrtc.orgbool ViECodecImpl::GetSendSideDelay(int video_channel, int* avg_delay_ms,
607ee234be7908840221b78e6489d42ea792d4ce87dstefan@webrtc.org                                   int* max_delay_ms) const {
608ee234be7908840221b78e6489d42ea792d4ce87dstefan@webrtc.org  ViEChannelManagerScoped cs(*(shared_data_->channel_manager()));
609ee234be7908840221b78e6489d42ea792d4ce87dstefan@webrtc.org  ViEChannel* vie_channel = cs.Channel(video_channel);
610ee234be7908840221b78e6489d42ea792d4ce87dstefan@webrtc.org  if (!vie_channel) {
611ee234be7908840221b78e6489d42ea792d4ce87dstefan@webrtc.org    shared_data_->SetLastError(kViECodecInvalidChannelId);
612ee234be7908840221b78e6489d42ea792d4ce87dstefan@webrtc.org    return false;
613ee234be7908840221b78e6489d42ea792d4ce87dstefan@webrtc.org  }
614ee234be7908840221b78e6489d42ea792d4ce87dstefan@webrtc.org  return vie_channel->GetSendSideDelay(avg_delay_ms, max_delay_ms);
615ee234be7908840221b78e6489d42ea792d4ce87dstefan@webrtc.org}
616ee234be7908840221b78e6489d42ea792d4ce87dstefan@webrtc.org
617b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgbool ViECodecImpl::CodecValid(const VideoCodec& video_codec) {
618b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  // Check pl_name matches codec_type.
619b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  if (video_codec.codecType == kVideoCodecRED) {
620b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org#if defined(WIN32)
621b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    if (_strnicmp(video_codec.plName, "red", 3) == 0) {
622b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org#else
623b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    if (strncasecmp(video_codec.plName, "red", 3) == 0) {
624b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org#endif
625b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org      // We only care about the type and name for red.
626b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org      return true;
627b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    }
628022615bd918aec7671968ad2b873d1487365980cmflodman@webrtc.org    LOG_F(LS_ERROR) << "Invalid RED configuration.";
629b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    return false;
630b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  } else if (video_codec.codecType == kVideoCodecULPFEC) {
631b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org#if defined(WIN32)
632b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    if (_strnicmp(video_codec.plName, "ULPFEC", 6) == 0) {
633b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org#else
634b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    if (strncasecmp(video_codec.plName, "ULPFEC", 6) == 0) {
635b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org#endif
636b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org      // We only care about the type and name for ULPFEC.
637b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org      return true;
638b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    }
639022615bd918aec7671968ad2b873d1487365980cmflodman@webrtc.org    LOG_F(LS_ERROR) << "Invalid ULPFEC configuration.";
640b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    return false;
641b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  } else if ((video_codec.codecType == kVideoCodecVP8 &&
642e3339fcb0795bf0e6fbf148133c8b79bcecc5edepbos@webrtc.org              strncmp(video_codec.plName, "VP8", 4) == 0) ||
643e3339fcb0795bf0e6fbf148133c8b79bcecc5edepbos@webrtc.org             (video_codec.codecType == kVideoCodecI420 &&
6442d4a80c05adffe07b48dc235475852450cd90568stefan@webrtc.org              strncmp(video_codec.plName, "I420", 4) == 0) ||
6452d4a80c05adffe07b48dc235475852450cd90568stefan@webrtc.org             (video_codec.codecType == kVideoCodecH264 &&
6462d4a80c05adffe07b48dc235475852450cd90568stefan@webrtc.org              strncmp(video_codec.plName, "H264", 4) == 0)) {
647b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    // OK.
6482ed1cd9e2a299a7858e21c332bcf6dfb27c4f037pbos@webrtc.org  } else if (video_codec.codecType != kVideoCodecGeneric) {
649022615bd918aec7671968ad2b873d1487365980cmflodman@webrtc.org    LOG(LS_ERROR) << "Codec type and name mismatch.";
650b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    return false;
651b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  }
652b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
653e7a9bd4c296a9cfce583aa82d567b973a86717b9braveyao@webrtc.org  if (video_codec.plType == 0 || video_codec.plType > 127) {
654022615bd918aec7671968ad2b873d1487365980cmflodman@webrtc.org    LOG(LS_ERROR) << "Invalif payload type: " << video_codec.plType;
655b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    return false;
656b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  }
657b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
658b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  if (video_codec.width > kViEMaxCodecWidth ||
659b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org      video_codec.height > kViEMaxCodecHeight) {
660022615bd918aec7671968ad2b873d1487365980cmflodman@webrtc.org    LOG(LS_ERROR) << "Invalid codec resolution " << video_codec.width
661022615bd918aec7671968ad2b873d1487365980cmflodman@webrtc.org                  << " x " << video_codec.height;
662b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    return false;
663b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  }
664b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
665b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  if (video_codec.startBitrate < kViEMinCodecBitrate) {
666022615bd918aec7671968ad2b873d1487365980cmflodman@webrtc.org    LOG(LS_ERROR) << "Invalid start bitrate.";
667b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    return false;
668b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  }
669b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  if (video_codec.minBitrate < kViEMinCodecBitrate) {
670022615bd918aec7671968ad2b873d1487365980cmflodman@webrtc.org    LOG(LS_ERROR) << "Invalid min bitrate.";
671b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    return false;
672b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  }
673b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  return true;
674b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
675b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
676b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}  // namespace webrtc
677