blob: cd8babafac448a80341a70fe02c217f179cba09c [file] [log] [blame]
niklase@google.com470e71d2011-07-07 08:21:25 +00001/*
stefan@webrtc.org439be292012-02-16 14:45:37 +00002 * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
niklase@google.com470e71d2011-07-07 08:21:25 +00003 *
4 * Use of this source code is governed by a BSD-style license
5 * that can be found in the LICENSE file in the root of the source
6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree.
9 */
10
pbos@webrtc.orgf5d4cb12013-05-17 13:44:48 +000011#include "webrtc/video_engine/vie_codec_impl.h"
niklase@google.com470e71d2011-07-07 08:21:25 +000012
mflodman@webrtc.orgd6ec3862012-10-25 11:30:29 +000013#include <list>
14
pbos@webrtc.orgf5d4cb12013-05-17 13:44:48 +000015#include "webrtc/engine_configurations.h"
16#include "webrtc/modules/video_coding/main/interface/video_coding.h"
17#include "webrtc/system_wrappers/interface/logging.h"
18#include "webrtc/system_wrappers/interface/trace.h"
19#include "webrtc/video_engine/include/vie_errors.h"
20#include "webrtc/video_engine/vie_capturer.h"
21#include "webrtc/video_engine/vie_channel.h"
22#include "webrtc/video_engine/vie_channel_manager.h"
23#include "webrtc/video_engine/vie_defines.h"
24#include "webrtc/video_engine/vie_encoder.h"
25#include "webrtc/video_engine/vie_impl.h"
26#include "webrtc/video_engine/vie_input_manager.h"
27#include "webrtc/video_engine/vie_shared_data.h"
niklase@google.com470e71d2011-07-07 08:21:25 +000028
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +000029namespace webrtc {
niklase@google.com470e71d2011-07-07 08:21:25 +000030
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +000031ViECodec* ViECodec::GetInterface(VideoEngine* video_engine) {
niklase@google.com470e71d2011-07-07 08:21:25 +000032#ifdef WEBRTC_VIDEO_ENGINE_CODEC_API
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +000033 if (!video_engine) {
niklase@google.com470e71d2011-07-07 08:21:25 +000034 return NULL;
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +000035 }
andrew@webrtc.orgd72262d2013-05-09 02:12:07 +000036 VideoEngineImpl* vie_impl = static_cast<VideoEngineImpl*>(video_engine);
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +000037 ViECodecImpl* vie_codec_impl = vie_impl;
38 // Increase ref count.
39 (*vie_codec_impl)++;
40 return vie_codec_impl;
41#else
42 return NULL;
niklase@google.com470e71d2011-07-07 08:21:25 +000043#endif
44}
45
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +000046int ViECodecImpl::Release() {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +000047 WEBRTC_TRACE(kTraceApiCall, kTraceVideo, shared_data_->instance_id(),
niklase@google.com470e71d2011-07-07 08:21:25 +000048 "ViECodecImpl::Release()");
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +000049 // Decrease ref count.
50 (*this)--;
niklase@google.com470e71d2011-07-07 08:21:25 +000051
pbos@webrtc.orgb238d122013-04-09 13:41:51 +000052 int32_t ref_count = GetCount();
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +000053 if (ref_count < 0) {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +000054 WEBRTC_TRACE(kTraceWarning, kTraceVideo, shared_data_->instance_id(),
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +000055 "ViECodec released too many times");
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +000056 shared_data_->SetLastError(kViEAPIDoesNotExist);
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +000057 return -1;
58 }
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +000059 WEBRTC_TRACE(kTraceInfo, kTraceVideo, shared_data_->instance_id(),
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +000060 "ViECodec reference count: %d", ref_count);
61 return ref_count;
niklase@google.com470e71d2011-07-07 08:21:25 +000062}
63
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +000064ViECodecImpl::ViECodecImpl(ViESharedData* shared_data)
65 : shared_data_(shared_data) {
66 WEBRTC_TRACE(kTraceMemory, kTraceVideo, shared_data_->instance_id(),
niklase@google.com470e71d2011-07-07 08:21:25 +000067 "ViECodecImpl::ViECodecImpl() Ctor");
68}
69
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +000070ViECodecImpl::~ViECodecImpl() {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +000071 WEBRTC_TRACE(kTraceMemory, kTraceVideo, shared_data_->instance_id(),
niklase@google.com470e71d2011-07-07 08:21:25 +000072 "ViECodecImpl::~ViECodecImpl() Dtor");
73}
74
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +000075int ViECodecImpl::NumberOfCodecs() const {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +000076 WEBRTC_TRACE(kTraceApiCall, kTraceVideo, ViEId(shared_data_->instance_id()),
77 "%s", __FUNCTION__);
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +000078 // +2 because of FEC(RED and ULPFEC)
79 return static_cast<int>((VideoCodingModule::NumberOfCodecs() + 2));
niklase@google.com470e71d2011-07-07 08:21:25 +000080}
81
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +000082int ViECodecImpl::GetCodec(const unsigned char list_number,
83 VideoCodec& video_codec) const {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +000084 WEBRTC_TRACE(kTraceApiCall, kTraceVideo, ViEId(shared_data_->instance_id()),
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +000085 "%s(list_number: %d, codec_type: %d)", __FUNCTION__,
86 list_number, video_codec.codecType);
87 if (list_number == VideoCodingModule::NumberOfCodecs()) {
88 memset(&video_codec, 0, sizeof(VideoCodec));
mflodman@webrtc.orgaeff4f32013-04-22 12:41:57 +000089 strcpy(video_codec.plName, "red");
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +000090 video_codec.codecType = kVideoCodecRED;
91 video_codec.plType = VCM_RED_PAYLOAD_TYPE;
92 } else if (list_number == VideoCodingModule::NumberOfCodecs() + 1) {
93 memset(&video_codec, 0, sizeof(VideoCodec));
mflodman@webrtc.orgaeff4f32013-04-22 12:41:57 +000094 strcpy(video_codec.plName, "ulpfec");
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +000095 video_codec.codecType = kVideoCodecULPFEC;
96 video_codec.plType = VCM_ULPFEC_PAYLOAD_TYPE;
97 } else if (VideoCodingModule::Codec(list_number, &video_codec) != VCM_OK) {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +000098 WEBRTC_TRACE(kTraceApiCall, kTraceVideo, ViEId(shared_data_->instance_id()),
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +000099 "%s: Could not get codec for list_number: %u", __FUNCTION__,
100 list_number);
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000101 shared_data_->SetLastError(kViECodecInvalidArgument);
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000102 return -1;
103 }
104 return 0;
niklase@google.com470e71d2011-07-07 08:21:25 +0000105}
106
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000107int ViECodecImpl::SetSendCodec(const int video_channel,
108 const VideoCodec& video_codec) {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000109 WEBRTC_TRACE(kTraceApiCall, kTraceVideo,
mflodman@webrtc.org9ba151b2012-06-21 10:02:13 +0000110 ViEId(shared_data_->instance_id(), video_channel),
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000111 "%s(video_channel: %d, codec_type: %d)", __FUNCTION__,
112 video_channel, video_codec.codecType);
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000113 WEBRTC_TRACE(kTraceInfo, kTraceVideo,
114 ViEId(shared_data_->instance_id(), video_channel),
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000115 "%s: codec: %d, pl_type: %d, width: %d, height: %d, bitrate: %d"
mflodman@webrtc.org9c0aedc2012-01-03 13:46:49 +0000116 "maxBr: %d, min_br: %d, frame_rate: %d, qpMax: %u,"
117 "numberOfSimulcastStreams: %u )", __FUNCTION__,
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000118 video_codec.codecType, video_codec.plType, video_codec.width,
119 video_codec.height, video_codec.startBitrate,
120 video_codec.maxBitrate, video_codec.minBitrate,
mflodman@webrtc.org9c0aedc2012-01-03 13:46:49 +0000121 video_codec.maxFramerate, video_codec.qpMax,
122 video_codec.numberOfSimulcastStreams);
123 if (video_codec.codecType == kVideoCodecVP8) {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000124 WEBRTC_TRACE(kTraceInfo, kTraceVideo,
125 ViEId(shared_data_->instance_id(), video_channel),
mflodman@webrtc.org9c0aedc2012-01-03 13:46:49 +0000126 "pictureLossIndicationOn: %d, feedbackModeOn: %d, "
mikhal@webrtc.orge07c6612013-01-31 16:37:13 +0000127 "complexity: %d, resilience: %d, numberOfTemporalLayers: %u"
128 "keyFrameInterval %d",
mflodman@webrtc.org9c0aedc2012-01-03 13:46:49 +0000129 video_codec.codecSpecific.VP8.pictureLossIndicationOn,
130 video_codec.codecSpecific.VP8.feedbackModeOn,
131 video_codec.codecSpecific.VP8.complexity,
132 video_codec.codecSpecific.VP8.resilience,
mikhal@webrtc.orge07c6612013-01-31 16:37:13 +0000133 video_codec.codecSpecific.VP8.numberOfTemporalLayers,
134 video_codec.codecSpecific.VP8.keyFrameInterval);
mflodman@webrtc.org9c0aedc2012-01-03 13:46:49 +0000135 }
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000136 if (!CodecValid(video_codec)) {
137 // Error logged.
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000138 shared_data_->SetLastError(kViECodecInvalidCodec);
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000139 return -1;
140 }
stefan@webrtc.org791eec72011-10-11 07:53:43 +0000141
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000142 ViEChannelManagerScoped cs(*(shared_data_->channel_manager()));
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000143 ViEChannel* vie_channel = cs.Channel(video_channel);
144 if (!vie_channel) {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000145 WEBRTC_TRACE(kTraceError, kTraceVideo,
146 ViEId(shared_data_->instance_id(), video_channel),
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000147 "%s: No channel %d", __FUNCTION__, video_channel);
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000148 shared_data_->SetLastError(kViECodecInvalidChannelId);
stefan@webrtc.org791eec72011-10-11 07:53:43 +0000149 return -1;
150 }
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000151
mflodman@webrtc.org9ec883e2012-03-05 17:12:41 +0000152 ViEEncoder* vie_encoder = cs.Encoder(video_channel);
153 assert(vie_encoder);
154 if (vie_encoder->Owner() != video_channel) {
155 WEBRTC_TRACE(kTraceError, kTraceVideo,
156 ViEId(shared_data_->instance_id(), video_channel),
157 "%s: Receive only channel %d", __FUNCTION__, video_channel);
158 shared_data_->SetLastError(kViECodecReceiveOnlyChannel);
159 return -1;
160 }
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000161 // Set a max_bitrate if the user hasn't set one.
162 VideoCodec video_codec_internal;
163 memcpy(&video_codec_internal, &video_codec, sizeof(VideoCodec));
164 if (video_codec_internal.maxBitrate == 0) {
165 // Max is one bit per pixel.
166 video_codec_internal.maxBitrate = (video_codec_internal.width *
167 video_codec_internal.height *
168 video_codec_internal.maxFramerate)
169 / 1000;
170 if (video_codec_internal.startBitrate > video_codec_internal.maxBitrate) {
171 // Don't limit the set start bitrate.
172 video_codec_internal.maxBitrate = video_codec_internal.startBitrate;
173 }
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000174 WEBRTC_TRACE(kTraceInfo, kTraceVideo,
175 ViEId(shared_data_->instance_id(), video_channel),
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000176 "%s: New max bitrate set to %d kbps", __FUNCTION__,
177 video_codec_internal.maxBitrate);
178 }
179
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000180 VideoCodec encoder;
mflodman@webrtc.orgf5e99db2012-06-27 09:49:37 +0000181 vie_encoder->GetEncoder(&encoder);
mflodman@webrtc.org9ec883e2012-03-05 17:12:41 +0000182
mflodman@webrtc.org9c0aedc2012-01-03 13:46:49 +0000183 // Make sure to generate a new SSRC if the codec type and/or resolution has
184 // changed. This won't have any effect if the user has set an SSRC.
185 bool new_rtp_stream = false;
stefan@webrtc.org4e8eaba2012-08-20 14:29:52 +0000186 if (encoder.codecType != video_codec_internal.codecType) {
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000187 new_rtp_stream = true;
188 }
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000189
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000190 ViEInputManagerScoped is(*(shared_data_->input_manager()));
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000191 ViEFrameProviderBase* frame_provider = NULL;
192
193 // Stop the media flow while reconfiguring.
194 vie_encoder->Pause();
195
mflodman@webrtc.org3ba883f2013-06-07 13:57:57 +0000196 if (vie_encoder->SetEncoder(video_codec_internal) != 0) {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000197 WEBRTC_TRACE(kTraceError, kTraceVideo,
198 ViEId(shared_data_->instance_id(), video_channel),
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000199 "%s: Could not change encoder for channel %d", __FUNCTION__,
200 video_channel);
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000201 shared_data_->SetLastError(kViECodecUnknownError);
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000202 return -1;
203 }
204
mflodman@webrtc.org9c0aedc2012-01-03 13:46:49 +0000205 // Give the channel(s) the new information.
206 ChannelList channels;
207 cs.ChannelsUsingViEEncoder(video_channel, &channels);
208 for (ChannelList::iterator it = channels.begin(); it != channels.end();
209 ++it) {
210 bool ret = true;
211 if ((*it)->SetSendCodec(video_codec_internal, new_rtp_stream) != 0) {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000212 WEBRTC_TRACE(kTraceError, kTraceVideo,
213 ViEId(shared_data_->instance_id(), video_channel),
mflodman@webrtc.org9c0aedc2012-01-03 13:46:49 +0000214 "%s: Could not set send codec for channel %d", __FUNCTION__,
215 video_channel);
216 ret = false;
217 }
218 if (!ret) {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000219 shared_data_->SetLastError(kViECodecUnknownError);
mflodman@webrtc.org9c0aedc2012-01-03 13:46:49 +0000220 return -1;
221 }
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000222 }
223
mflodman@webrtc.orgd6ec3862012-10-25 11:30:29 +0000224 // TODO(mflodman) Break out this part in GetLocalSsrcList().
225 // Update all SSRCs to ViEEncoder.
226 std::list<unsigned int> ssrcs;
227 if (video_codec_internal.numberOfSimulcastStreams == 0) {
228 unsigned int ssrc = 0;
229 if (vie_channel->GetLocalSSRC(0, &ssrc) != 0) {
230 WEBRTC_TRACE(kTraceError, kTraceVideo,
231 ViEId(shared_data_->instance_id(), video_channel),
232 "%s: Could not get ssrc", __FUNCTION__);
233 }
234 ssrcs.push_back(ssrc);
235 } else {
236 for (int idx = 0; idx < video_codec_internal.numberOfSimulcastStreams;
237 ++idx) {
238 unsigned int ssrc = 0;
239 if (vie_channel->GetLocalSSRC(idx, &ssrc) != 0) {
240 WEBRTC_TRACE(kTraceError, kTraceVideo,
241 ViEId(shared_data_->instance_id(), video_channel),
242 "%s: Could not get ssrc for idx %d", __FUNCTION__, idx);
243 }
244 ssrcs.push_back(ssrc);
245 }
246 }
247 vie_encoder->SetSsrcs(ssrcs);
248 shared_data_->channel_manager()->UpdateSsrcs(video_channel, ssrcs);
249
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000250 // Update the protection mode, we might be switching NACK/FEC.
251 vie_encoder->UpdateProtectionMethod();
252
253 // Get new best format for frame provider.
254 if (frame_provider) {
255 frame_provider->FrameCallbackChanged();
256 }
257 // Restart the media flow
258 if (new_rtp_stream) {
259 // Stream settings changed, make sure we get a key frame.
260 vie_encoder->SendKeyFrame();
261 }
262 vie_encoder->Restart();
263 return 0;
stefan@webrtc.org791eec72011-10-11 07:53:43 +0000264}
265
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000266int ViECodecImpl::GetSendCodec(const int video_channel,
267 VideoCodec& video_codec) const {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000268 WEBRTC_TRACE(kTraceApiCall, kTraceVideo,
269 ViEId(shared_data_->instance_id(), video_channel),
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000270 "%s(video_channel: %d)", __FUNCTION__, video_channel);
niklase@google.com470e71d2011-07-07 08:21:25 +0000271
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000272 ViEChannelManagerScoped cs(*(shared_data_->channel_manager()));
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000273 ViEEncoder* vie_encoder = cs.Encoder(video_channel);
274 if (!vie_encoder) {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000275 WEBRTC_TRACE(kTraceError, kTraceVideo,
276 ViEId(shared_data_->instance_id(), video_channel),
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000277 "%s: No encoder for channel %d", __FUNCTION__, video_channel);
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000278 shared_data_->SetLastError(kViECodecInvalidChannelId);
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000279 return -1;
280 }
mflodman@webrtc.orgf5e99db2012-06-27 09:49:37 +0000281 return vie_encoder->GetEncoder(&video_codec);
niklase@google.com470e71d2011-07-07 08:21:25 +0000282}
283
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000284int ViECodecImpl::SetReceiveCodec(const int video_channel,
285 const VideoCodec& video_codec) {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000286 WEBRTC_TRACE(kTraceApiCall, kTraceVideo,
287 ViEId(shared_data_->instance_id(), video_channel),
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000288 "%s(video_channel: %d, codec_type: %d)", __FUNCTION__,
289 video_channel, video_codec.codecType);
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000290 WEBRTC_TRACE(kTraceInfo, kTraceVideo,
291 ViEId(shared_data_->instance_id(), video_channel),
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000292 "%s: codec: %d, pl_type: %d, width: %d, height: %d, bitrate: %d,"
293 "maxBr: %d, min_br: %d, frame_rate: %d", __FUNCTION__,
294 video_codec.codecType, video_codec.plType, video_codec.width,
295 video_codec.height, video_codec.startBitrate,
296 video_codec.maxBitrate, video_codec.minBitrate,
297 video_codec.maxFramerate);
niklase@google.com470e71d2011-07-07 08:21:25 +0000298
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000299 if (CodecValid(video_codec) == false) {
300 // Error logged.
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000301 shared_data_->SetLastError(kViECodecInvalidCodec);
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000302 return -1;
303 }
304
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000305 ViEChannelManagerScoped cs(*(shared_data_->channel_manager()));
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000306 ViEChannel* vie_channel = cs.Channel(video_channel);
307 if (!vie_channel) {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000308 WEBRTC_TRACE(kTraceError, kTraceVideo,
309 ViEId(shared_data_->instance_id(), video_channel),
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000310 "%s: No channel %d", __FUNCTION__, video_channel);
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000311 shared_data_->SetLastError(kViECodecInvalidChannelId);
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000312 return -1;
313 }
314
315 if (vie_channel->SetReceiveCodec(video_codec) != 0) {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000316 WEBRTC_TRACE(kTraceError, kTraceVideo,
317 ViEId(shared_data_->instance_id(), video_channel),
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000318 "%s: Could not set receive codec for channel %d",
319 __FUNCTION__, video_channel);
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000320 shared_data_->SetLastError(kViECodecUnknownError);
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000321 return -1;
322 }
323 return 0;
324}
325
326int ViECodecImpl::GetReceiveCodec(const int video_channel,
327 VideoCodec& video_codec) const {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000328 WEBRTC_TRACE(kTraceApiCall, kTraceVideo,
329 ViEId(shared_data_->instance_id(), video_channel),
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000330 "%s(video_channel: %d, codec_type: %d)", __FUNCTION__,
331 video_channel, video_codec.codecType);
332
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000333 ViEChannelManagerScoped cs(*(shared_data_->channel_manager()));
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000334 ViEChannel* vie_channel = cs.Channel(video_channel);
335 if (!vie_channel) {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000336 WEBRTC_TRACE(kTraceError, kTraceVideo,
337 ViEId(shared_data_->instance_id(), video_channel),
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000338 "%s: No channel %d", __FUNCTION__, video_channel);
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000339 shared_data_->SetLastError(kViECodecInvalidChannelId);
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000340 return -1;
341 }
342
mflodman@webrtc.orgf5e99db2012-06-27 09:49:37 +0000343 if (vie_channel->GetReceiveCodec(&video_codec) != 0) {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000344 shared_data_->SetLastError(kViECodecUnknownError);
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000345 return -1;
346 }
347 return 0;
348}
349
350int ViECodecImpl::GetCodecConfigParameters(
351 const int video_channel,
352 unsigned char config_parameters[kConfigParameterSize],
353 unsigned char& config_parameters_size) const {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000354 WEBRTC_TRACE(kTraceApiCall, kTraceVideo,
355 ViEId(shared_data_->instance_id(), video_channel),
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000356 "%s(video_channel: %d)", __FUNCTION__, video_channel);
357
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000358 ViEChannelManagerScoped cs(*(shared_data_->channel_manager()));
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000359 ViEEncoder* vie_encoder = cs.Encoder(video_channel);
360 if (!vie_encoder) {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000361 WEBRTC_TRACE(kTraceError, kTraceVideo,
362 ViEId(shared_data_->instance_id(), video_channel),
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000363 "%s: No encoder for channel %d", __FUNCTION__, video_channel);
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000364 shared_data_->SetLastError(kViECodecInvalidChannelId);
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000365 return -1;
366 }
367
368 if (vie_encoder->GetCodecConfigParameters(config_parameters,
369 config_parameters_size) != 0) {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000370 shared_data_->SetLastError(kViECodecUnknownError);
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000371 return -1;
372 }
373 return 0;
374}
375
376int ViECodecImpl::SetImageScaleStatus(const int video_channel,
377 const bool enable) {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000378 WEBRTC_TRACE(kTraceApiCall, kTraceVideo,
379 ViEId(shared_data_->instance_id(), video_channel),
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000380 "%s(video_channel: %d, enable: %d)", __FUNCTION__, video_channel,
381 enable);
382
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000383 ViEChannelManagerScoped cs(*(shared_data_->channel_manager()));
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000384 ViEEncoder* vie_encoder = cs.Encoder(video_channel);
385 if (!vie_encoder) {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000386 WEBRTC_TRACE(kTraceError, kTraceVideo,
387 ViEId(shared_data_->instance_id(), video_channel),
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000388 "%s: No channel %d", __FUNCTION__, video_channel);
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000389 shared_data_->SetLastError(kViECodecInvalidChannelId);
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000390 return -1;
391 }
392
393 if (vie_encoder->ScaleInputImage(enable) != 0) {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000394 shared_data_->SetLastError(kViECodecUnknownError);
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000395 return -1;
396 }
397 return 0;
398}
399
400int ViECodecImpl::GetSendCodecStastistics(const int video_channel,
401 unsigned int& key_frames,
402 unsigned int& delta_frames) const {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000403 WEBRTC_TRACE(kTraceApiCall, kTraceVideo,
404 ViEId(shared_data_->instance_id(), video_channel),
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000405 "%s(video_channel %d)", __FUNCTION__, video_channel);
406
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000407 ViEChannelManagerScoped cs(*(shared_data_->channel_manager()));
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000408 ViEEncoder* vie_encoder = cs.Encoder(video_channel);
409 if (!vie_encoder) {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000410 WEBRTC_TRACE(kTraceError, kTraceVideo,
411 ViEId(shared_data_->instance_id(), video_channel),
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000412 "%s: No send codec for channel %d", __FUNCTION__,
413 video_channel);
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000414 shared_data_->SetLastError(kViECodecInvalidChannelId);
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000415 return -1;
416 }
417
mflodman@webrtc.orgf5e99db2012-06-27 09:49:37 +0000418 if (vie_encoder->SendCodecStatistics(&key_frames, &delta_frames) != 0) {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000419 shared_data_->SetLastError(kViECodecUnknownError);
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000420 return -1;
421 }
422 return 0;
423}
424
425int ViECodecImpl::GetReceiveCodecStastistics(const int video_channel,
426 unsigned int& key_frames,
427 unsigned int& delta_frames) const {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000428 WEBRTC_TRACE(kTraceApiCall, kTraceVideo,
429 ViEId(shared_data_->instance_id(), video_channel),
mflodman@webrtc.org4aee6b62012-12-14 14:02:10 +0000430 "%s(video_channel: %d)", __FUNCTION__,
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000431 video_channel);
432
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000433 ViEChannelManagerScoped cs(*(shared_data_->channel_manager()));
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000434 ViEChannel* vie_channel = cs.Channel(video_channel);
435 if (!vie_channel) {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000436 WEBRTC_TRACE(kTraceError, kTraceVideo,
437 ViEId(shared_data_->instance_id(), video_channel),
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000438 "%s: No channel %d", __FUNCTION__, video_channel);
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000439 shared_data_->SetLastError(kViECodecInvalidChannelId);
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000440 return -1;
441 }
mflodman@webrtc.orgf5e99db2012-06-27 09:49:37 +0000442 if (vie_channel->ReceiveCodecStatistics(&key_frames, &delta_frames) != 0) {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000443 shared_data_->SetLastError(kViECodecUnknownError);
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000444 return -1;
445 }
446 return 0;
447}
448
mflodman@webrtc.org4aee6b62012-12-14 14:02:10 +0000449int ViECodecImpl::GetReceiveSideDelay(const int video_channel,
450 int* delay_ms) const {
451 WEBRTC_TRACE(kTraceApiCall, kTraceVideo,
452 ViEId(shared_data_->instance_id(), video_channel),
453 "%s(video_channel: %d)", __FUNCTION__, video_channel);
454 if (delay_ms == NULL) {
455 LOG_F(LS_ERROR) << "NULL pointer argument.";
456 return -1;
457 }
458
459 ViEChannelManagerScoped cs(*(shared_data_->channel_manager()));
460 ViEChannel* vie_channel = cs.Channel(video_channel);
461 if (!vie_channel) {
462 WEBRTC_TRACE(kTraceError, kTraceVideo,
463 ViEId(shared_data_->instance_id(), video_channel),
464 "%s: No channel %d", __FUNCTION__, video_channel);
465 shared_data_->SetLastError(kViECodecInvalidChannelId);
466 return -1;
467 }
468 *delay_ms = vie_channel->ReceiveDelay();
469 if (*delay_ms < 0) {
470 return -1;
471 }
472 return 0;
473}
474
475
stefan@webrtc.org439be292012-02-16 14:45:37 +0000476int ViECodecImpl::GetCodecTargetBitrate(const int video_channel,
477 unsigned int* bitrate) const {
478 WEBRTC_TRACE(kTraceApiCall, kTraceVideo,
479 ViEId(shared_data_->instance_id(), video_channel),
480 "%s(video_channel: %d, codec_type: %d)", __FUNCTION__,
481 video_channel);
482
483 ViEChannelManagerScoped cs(*(shared_data_->channel_manager()));
484 ViEEncoder* vie_encoder = cs.Encoder(video_channel);
485 if (!vie_encoder) {
486 WEBRTC_TRACE(kTraceError, kTraceVideo,
487 ViEId(shared_data_->instance_id(), video_channel),
488 "%s: No send codec for channel %d", __FUNCTION__,
489 video_channel);
490 shared_data_->SetLastError(kViECodecInvalidChannelId);
491 return -1;
492 }
pbos@webrtc.orgb238d122013-04-09 13:41:51 +0000493 return vie_encoder->CodecTargetBitrate(static_cast<uint32_t*>(bitrate));
stefan@webrtc.org439be292012-02-16 14:45:37 +0000494}
495
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000496unsigned int ViECodecImpl::GetDiscardedPackets(const int video_channel) const {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000497 WEBRTC_TRACE(kTraceApiCall, kTraceVideo,
498 ViEId(shared_data_->instance_id(), video_channel),
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000499 "%s(video_channel: %d, codec_type: %d)", __FUNCTION__,
500 video_channel);
501
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000502 ViEChannelManagerScoped cs(*(shared_data_->channel_manager()));
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000503 ViEChannel* vie_channel = cs.Channel(video_channel);
504 if (!vie_channel) {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000505 WEBRTC_TRACE(kTraceError, kTraceVideo,
506 ViEId(shared_data_->instance_id(), video_channel),
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000507 "%s: No channel %d", __FUNCTION__, video_channel);
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000508 shared_data_->SetLastError(kViECodecInvalidChannelId);
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000509 return -1;
510 }
511 return vie_channel->DiscardedPackets();
512}
513
514int ViECodecImpl::SetKeyFrameRequestCallbackStatus(const int video_channel,
515 const bool enable) {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000516 WEBRTC_TRACE(kTraceApiCall, kTraceVideo,
517 ViEId(shared_data_->instance_id(), video_channel),
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000518 "%s(video_channel: %d)", __FUNCTION__, video_channel);
519
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000520 ViEChannelManagerScoped cs(*(shared_data_->channel_manager()));
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000521 ViEChannel* vie_channel = cs.Channel(video_channel);
522 if (!vie_channel) {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000523 WEBRTC_TRACE(kTraceError, kTraceVideo,
524 ViEId(shared_data_->instance_id(), video_channel),
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000525 "%s: No channel %d", __FUNCTION__, video_channel);
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000526 shared_data_->SetLastError(kViECodecInvalidChannelId);
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000527 return -1;
528 }
529 if (vie_channel->EnableKeyFrameRequestCallback(enable) != 0) {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000530 shared_data_->SetLastError(kViECodecUnknownError);
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000531 return -1;
532 }
533 return 0;
534}
535
536int ViECodecImpl::SetSignalKeyPacketLossStatus(const int video_channel,
niklase@google.com470e71d2011-07-07 08:21:25 +0000537 const bool enable,
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000538 const bool only_key_frames) {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000539 WEBRTC_TRACE(kTraceApiCall, kTraceVideo,
540 ViEId(shared_data_->instance_id(), video_channel),
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000541 "%s(video_channel: %d, enable: %d, only_key_frames: %d)",
542 __FUNCTION__, video_channel, enable);
niklase@google.com470e71d2011-07-07 08:21:25 +0000543
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000544 ViEChannelManagerScoped cs(*(shared_data_->channel_manager()));
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000545 ViEChannel* vie_channel = cs.Channel(video_channel);
546 if (!vie_channel) {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000547 WEBRTC_TRACE(kTraceError, kTraceVideo,
548 ViEId(shared_data_->instance_id(), video_channel),
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000549 "%s: No channel %d", __FUNCTION__, video_channel);
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000550 shared_data_->SetLastError(kViECodecInvalidChannelId);
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000551 return -1;
552 }
553 if (vie_channel->SetSignalPacketLossStatus(enable, only_key_frames) != 0) {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000554 shared_data_->SetLastError(kViECodecUnknownError);
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000555 return -1;
556 }
557 return 0;
niklase@google.com470e71d2011-07-07 08:21:25 +0000558}
559
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000560int ViECodecImpl::RegisterEncoderObserver(const int video_channel,
561 ViEEncoderObserver& observer) {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000562 WEBRTC_TRACE(kTraceApiCall, kTraceVideo, ViEId(shared_data_->instance_id()),
563 "%s", __FUNCTION__);
niklase@google.com470e71d2011-07-07 08:21:25 +0000564
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000565 ViEChannelManagerScoped cs(*(shared_data_->channel_manager()));
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000566 ViEEncoder* vie_encoder = cs.Encoder(video_channel);
567 if (!vie_encoder) {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000568 WEBRTC_TRACE(kTraceError, kTraceVideo,
569 ViEId(shared_data_->instance_id(), video_channel),
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000570 "%s: No encoder for channel %d", __FUNCTION__, video_channel);
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000571 shared_data_->SetLastError(kViECodecInvalidChannelId);
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000572 return -1;
573 }
574 if (vie_encoder->RegisterCodecObserver(&observer) != 0) {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000575 WEBRTC_TRACE(kTraceError, kTraceVideo,
576 ViEId(shared_data_->instance_id(), video_channel),
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000577 "%s: Could not register codec observer at channel",
578 __FUNCTION__);
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000579 shared_data_->SetLastError(kViECodecObserverAlreadyRegistered);
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000580 return -1;
581 }
582 return 0;
niklase@google.com470e71d2011-07-07 08:21:25 +0000583}
584
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000585int ViECodecImpl::DeregisterEncoderObserver(const int video_channel) {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000586 WEBRTC_TRACE(kTraceApiCall, kTraceVideo, ViEId(shared_data_->instance_id()),
587 "%s", __FUNCTION__);
niklase@google.com470e71d2011-07-07 08:21:25 +0000588
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000589 ViEChannelManagerScoped cs(*(shared_data_->channel_manager()));
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000590 ViEEncoder* vie_encoder = cs.Encoder(video_channel);
591 if (!vie_encoder) {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000592 WEBRTC_TRACE(kTraceError, kTraceVideo,
593 ViEId(shared_data_->instance_id(), video_channel),
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000594 "%s: No encoder for channel %d", __FUNCTION__, video_channel);
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000595 shared_data_->SetLastError(kViECodecInvalidChannelId);
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000596 return -1;
597 }
598 if (vie_encoder->RegisterCodecObserver(NULL) != 0) {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000599 shared_data_->SetLastError(kViECodecObserverNotRegistered);
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000600 return -1;
601 }
602 return 0;
niklase@google.com470e71d2011-07-07 08:21:25 +0000603}
604
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000605int ViECodecImpl::RegisterDecoderObserver(const int video_channel,
606 ViEDecoderObserver& observer) {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000607 WEBRTC_TRACE(kTraceApiCall, kTraceVideo, ViEId(shared_data_->instance_id()),
608 "%s", __FUNCTION__);
niklase@google.com470e71d2011-07-07 08:21:25 +0000609
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000610 ViEChannelManagerScoped cs(*(shared_data_->channel_manager()));
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000611 ViEChannel* vie_channel = cs.Channel(video_channel);
612 if (!vie_channel) {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000613 WEBRTC_TRACE(kTraceError, kTraceVideo,
614 ViEId(shared_data_->instance_id(), video_channel),
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000615 "%s: No channel %d", __FUNCTION__, video_channel);
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000616 shared_data_->SetLastError(kViECodecInvalidChannelId);
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000617 return -1;
618 }
619 if (vie_channel->RegisterCodecObserver(&observer) != 0) {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000620 WEBRTC_TRACE(kTraceError, kTraceVideo,
621 ViEId(shared_data_->instance_id(), video_channel),
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000622 "%s: Could not register codec observer at channel",
623 __FUNCTION__);
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000624 shared_data_->SetLastError(kViECodecObserverAlreadyRegistered);
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000625 return -1;
626 }
627 return 0;
niklase@google.com470e71d2011-07-07 08:21:25 +0000628}
629
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000630int ViECodecImpl::DeregisterDecoderObserver(const int video_channel) {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000631 WEBRTC_TRACE(kTraceApiCall, kTraceVideo,
632 ViEId(shared_data_->instance_id()), "%s",
niklase@google.com470e71d2011-07-07 08:21:25 +0000633 __FUNCTION__);
634
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000635 ViEChannelManagerScoped cs(*(shared_data_->channel_manager()));
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000636 ViEChannel* vie_channel = cs.Channel(video_channel);
637 if (!vie_channel) {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000638 WEBRTC_TRACE(kTraceError, kTraceVideo,
639 ViEId(shared_data_->instance_id(), video_channel),
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000640 "%s: No channel %d", __FUNCTION__, video_channel);
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000641 shared_data_->SetLastError(kViECodecInvalidChannelId);
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000642 return -1;
643 }
644 if (vie_channel->RegisterCodecObserver(NULL) != 0) {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000645 shared_data_->SetLastError(kViECodecObserverNotRegistered);
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000646 return -1;
647 }
648 return 0;
niklase@google.com470e71d2011-07-07 08:21:25 +0000649}
650
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000651int ViECodecImpl::SendKeyFrame(const int video_channel) {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000652 WEBRTC_TRACE(kTraceApiCall, kTraceVideo, ViEId(shared_data_->instance_id()),
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000653 "%s(video_channel: %d)", __FUNCTION__, video_channel);
niklase@google.com470e71d2011-07-07 08:21:25 +0000654
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000655 ViEChannelManagerScoped cs(*(shared_data_->channel_manager()));
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000656 ViEEncoder* vie_encoder = cs.Encoder(video_channel);
657 if (!vie_encoder) {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000658 WEBRTC_TRACE(kTraceError, kTraceVideo,
659 ViEId(shared_data_->instance_id(), video_channel),
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000660 "%s: No channel %d", __FUNCTION__, video_channel);
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000661 shared_data_->SetLastError(kViECodecInvalidChannelId);
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000662 return -1;
663 }
664 if (vie_encoder->SendKeyFrame() != 0) {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000665 shared_data_->SetLastError(kViECodecUnknownError);
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000666 return -1;
667 }
668 return 0;
niklase@google.com470e71d2011-07-07 08:21:25 +0000669}
670
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000671int ViECodecImpl::WaitForFirstKeyFrame(const int video_channel,
672 const bool wait) {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000673 WEBRTC_TRACE(kTraceApiCall, kTraceVideo,
674 ViEId(shared_data_->instance_id()),
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000675 "%s(video_channel: %d, wait: %d)", __FUNCTION__, video_channel,
niklase@google.com470e71d2011-07-07 08:21:25 +0000676 wait);
677
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000678 ViEChannelManagerScoped cs(*(shared_data_->channel_manager()));
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000679 ViEChannel* vie_channel = cs.Channel(video_channel);
680 if (!vie_channel) {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000681 WEBRTC_TRACE(kTraceError, kTraceVideo,
682 ViEId(shared_data_->instance_id(), video_channel),
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000683 "%s: No channel %d", __FUNCTION__, video_channel);
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000684 shared_data_->SetLastError(kViECodecInvalidChannelId);
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000685 return -1;
686 }
687 if (vie_channel->WaitForKeyFrame(wait) != 0) {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000688 shared_data_->SetLastError(kViECodecUnknownError);
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000689 return -1;
690 }
691 return 0;
niklase@google.com470e71d2011-07-07 08:21:25 +0000692}
693
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000694bool ViECodecImpl::CodecValid(const VideoCodec& video_codec) {
695 // Check pl_name matches codec_type.
696 if (video_codec.codecType == kVideoCodecRED) {
niklase@google.com470e71d2011-07-07 08:21:25 +0000697#if defined(WIN32)
mflodman@webrtc.org1fe2ada2011-12-21 12:23:15 +0000698 if (_strnicmp(video_codec.plName, "red", 3) == 0) {
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000699#else
700 if (strncasecmp(video_codec.plName, "red", 3) == 0) {
niklase@google.com470e71d2011-07-07 08:21:25 +0000701#endif
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000702 // We only care about the type and name for red.
703 return true;
niklase@google.com470e71d2011-07-07 08:21:25 +0000704 }
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000705 WEBRTC_TRACE(kTraceError, kTraceVideo, -1,
706 "Codec type doesn't match pl_name", video_codec.plType);
707 return false;
708 } else if (video_codec.codecType == kVideoCodecULPFEC) {
niklase@google.com470e71d2011-07-07 08:21:25 +0000709#if defined(WIN32)
mflodman@webrtc.org1fe2ada2011-12-21 12:23:15 +0000710 if (_strnicmp(video_codec.plName, "ULPFEC", 6) == 0) {
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000711#else
712 if (strncasecmp(video_codec.plName, "ULPFEC", 6) == 0) {
niklase@google.com470e71d2011-07-07 08:21:25 +0000713#endif
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000714 // We only care about the type and name for ULPFEC.
715 return true;
niklase@google.com470e71d2011-07-07 08:21:25 +0000716 }
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000717 WEBRTC_TRACE(kTraceError, kTraceVideo, -1,
718 "Codec type doesn't match pl_name", video_codec.plType);
719 return false;
pwestin@webrtc.org56210572012-01-17 12:45:47 +0000720 } else if ((video_codec.codecType == kVideoCodecVP8 &&
pbos@webrtc.org8911ce42013-03-18 16:39:03 +0000721 strncmp(video_codec.plName, "VP8", 4) == 0) ||
722 (video_codec.codecType == kVideoCodecI420 &&
pbos@webrtc.orgb5bf54c2013-04-05 13:27:38 +0000723 strncmp(video_codec.plName, "I420", 4) == 0)) {
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000724 // OK.
pbos@webrtc.orgb5bf54c2013-04-05 13:27:38 +0000725 } else if (video_codec.codecType != kVideoCodecGeneric) {
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000726 WEBRTC_TRACE(kTraceError, kTraceVideo, -1,
727 "Codec type doesn't match pl_name", video_codec.plType);
728 return false;
729 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000730
braveyao@webrtc.org49273ff2013-01-14 01:52:26 +0000731 if (video_codec.plType == 0 || video_codec.plType > 127) {
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000732 WEBRTC_TRACE(kTraceError, kTraceVideo, -1,
733 "Invalid codec payload type: %d", video_codec.plType);
734 return false;
735 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000736
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000737 if (video_codec.width > kViEMaxCodecWidth ||
738 video_codec.height > kViEMaxCodecHeight) {
739 WEBRTC_TRACE(kTraceError, kTraceVideo, -1, "Invalid codec size: %u x %u",
740 video_codec.width, video_codec.height);
741 return false;
742 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000743
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000744 if (video_codec.startBitrate < kViEMinCodecBitrate) {
745 WEBRTC_TRACE(kTraceError, kTraceVideo, -1, "Invalid start_bitrate: %u",
746 video_codec.startBitrate);
747 return false;
748 }
749 if (video_codec.minBitrate < kViEMinCodecBitrate) {
750 WEBRTC_TRACE(kTraceError, kTraceVideo, -1, "Invalid min_bitrate: %u",
751 video_codec.minBitrate);
752 return false;
753 }
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000754 return true;
niklase@google.com470e71d2011-07-07 08:21:25 +0000755}
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000756
757} // namespace webrtc