blob: 7d2d95d27d25db72193a95649258e6ff2ead2096 [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
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +000011#include "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
mflodman@webrtc.org9ba151b2012-06-21 10:02:13 +000015#include "engine_configurations.h" // NOLINT
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +000016#include "modules/video_coding/main/interface/video_coding.h"
mflodman@webrtc.org4aee6b62012-12-14 14:02:10 +000017#include "system_wrappers/interface/logging.h"
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +000018#include "system_wrappers/interface/trace.h"
mflodman@webrtc.orga4863db2011-12-22 08:51:52 +000019#include "video_engine/include/vie_errors.h"
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +000020#include "video_engine/vie_capturer.h"
21#include "video_engine/vie_channel.h"
22#include "video_engine/vie_channel_manager.h"
23#include "video_engine/vie_defines.h"
24#include "video_engine/vie_encoder.h"
25#include "video_engine/vie_impl.h"
26#include "video_engine/vie_input_manager.h"
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +000027#include "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 }
36 VideoEngineImpl* vie_impl = reinterpret_cast<VideoEngineImpl*>(video_engine);
37 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
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +000052 WebRtc_Word32 ref_count = GetCount();
53 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.org9ba151b2012-06-21 10:02:13 +000089 strncpy(video_codec.plName, "red", 3);
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.org9ba151b2012-06-21 10:02:13 +000094 strncpy(video_codec.plName, "ulpfec", 6);
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
196 // Check if we have a frame provider that is a camera and can provide this
197 // codec for us.
198 bool use_capture_device_as_encoder = false;
199 frame_provider = is.FrameProvider(vie_encoder);
200 if (frame_provider) {
201 if (frame_provider->Id() >= kViECaptureIdBase &&
202 frame_provider->Id() <= kViECaptureIdMax) {
203 ViECapturer* vie_capture = static_cast<ViECapturer*>(frame_provider);
204 // Try to get preencoded. Nothing to do if it is not supported.
205 if (vie_capture && vie_capture->PreEncodeToViEEncoder(
206 video_codec_internal,
207 *vie_encoder,
208 video_channel) == 0) {
209 use_capture_device_as_encoder = true;
210 }
211 }
212 }
213
214 // Update the encoder settings if we are not using a capture device capable
215 // of this codec.
216 if (!use_capture_device_as_encoder &&
217 vie_encoder->SetEncoder(video_codec_internal) != 0) {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000218 WEBRTC_TRACE(kTraceError, kTraceVideo,
219 ViEId(shared_data_->instance_id(), video_channel),
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000220 "%s: Could not change encoder for channel %d", __FUNCTION__,
221 video_channel);
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000222 shared_data_->SetLastError(kViECodecUnknownError);
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000223 return -1;
224 }
225
mflodman@webrtc.org9c0aedc2012-01-03 13:46:49 +0000226 // Give the channel(s) the new information.
227 ChannelList channels;
228 cs.ChannelsUsingViEEncoder(video_channel, &channels);
229 for (ChannelList::iterator it = channels.begin(); it != channels.end();
230 ++it) {
231 bool ret = true;
232 if ((*it)->SetSendCodec(video_codec_internal, new_rtp_stream) != 0) {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000233 WEBRTC_TRACE(kTraceError, kTraceVideo,
234 ViEId(shared_data_->instance_id(), video_channel),
mflodman@webrtc.org9c0aedc2012-01-03 13:46:49 +0000235 "%s: Could not set send codec for channel %d", __FUNCTION__,
236 video_channel);
237 ret = false;
238 }
239 if (!ret) {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000240 shared_data_->SetLastError(kViECodecUnknownError);
mflodman@webrtc.org9c0aedc2012-01-03 13:46:49 +0000241 return -1;
242 }
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000243 }
244
mflodman@webrtc.orgd6ec3862012-10-25 11:30:29 +0000245 // TODO(mflodman) Break out this part in GetLocalSsrcList().
246 // Update all SSRCs to ViEEncoder.
247 std::list<unsigned int> ssrcs;
248 if (video_codec_internal.numberOfSimulcastStreams == 0) {
249 unsigned int ssrc = 0;
250 if (vie_channel->GetLocalSSRC(0, &ssrc) != 0) {
251 WEBRTC_TRACE(kTraceError, kTraceVideo,
252 ViEId(shared_data_->instance_id(), video_channel),
253 "%s: Could not get ssrc", __FUNCTION__);
254 }
255 ssrcs.push_back(ssrc);
256 } else {
257 for (int idx = 0; idx < video_codec_internal.numberOfSimulcastStreams;
258 ++idx) {
259 unsigned int ssrc = 0;
260 if (vie_channel->GetLocalSSRC(idx, &ssrc) != 0) {
261 WEBRTC_TRACE(kTraceError, kTraceVideo,
262 ViEId(shared_data_->instance_id(), video_channel),
263 "%s: Could not get ssrc for idx %d", __FUNCTION__, idx);
264 }
265 ssrcs.push_back(ssrc);
266 }
267 }
268 vie_encoder->SetSsrcs(ssrcs);
269 shared_data_->channel_manager()->UpdateSsrcs(video_channel, ssrcs);
270
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000271 // Update the protection mode, we might be switching NACK/FEC.
272 vie_encoder->UpdateProtectionMethod();
273
274 // Get new best format for frame provider.
275 if (frame_provider) {
276 frame_provider->FrameCallbackChanged();
277 }
278 // Restart the media flow
279 if (new_rtp_stream) {
280 // Stream settings changed, make sure we get a key frame.
281 vie_encoder->SendKeyFrame();
282 }
283 vie_encoder->Restart();
284 return 0;
stefan@webrtc.org791eec72011-10-11 07:53:43 +0000285}
286
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000287int ViECodecImpl::GetSendCodec(const int video_channel,
288 VideoCodec& video_codec) const {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000289 WEBRTC_TRACE(kTraceApiCall, kTraceVideo,
290 ViEId(shared_data_->instance_id(), video_channel),
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000291 "%s(video_channel: %d)", __FUNCTION__, video_channel);
niklase@google.com470e71d2011-07-07 08:21:25 +0000292
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000293 ViEChannelManagerScoped cs(*(shared_data_->channel_manager()));
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000294 ViEEncoder* vie_encoder = cs.Encoder(video_channel);
295 if (!vie_encoder) {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000296 WEBRTC_TRACE(kTraceError, kTraceVideo,
297 ViEId(shared_data_->instance_id(), video_channel),
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000298 "%s: No encoder for channel %d", __FUNCTION__, video_channel);
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000299 shared_data_->SetLastError(kViECodecInvalidChannelId);
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000300 return -1;
301 }
mflodman@webrtc.orgf5e99db2012-06-27 09:49:37 +0000302 return vie_encoder->GetEncoder(&video_codec);
niklase@google.com470e71d2011-07-07 08:21:25 +0000303}
304
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000305int ViECodecImpl::SetReceiveCodec(const int video_channel,
306 const VideoCodec& video_codec) {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000307 WEBRTC_TRACE(kTraceApiCall, kTraceVideo,
308 ViEId(shared_data_->instance_id(), video_channel),
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000309 "%s(video_channel: %d, codec_type: %d)", __FUNCTION__,
310 video_channel, video_codec.codecType);
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000311 WEBRTC_TRACE(kTraceInfo, kTraceVideo,
312 ViEId(shared_data_->instance_id(), video_channel),
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000313 "%s: codec: %d, pl_type: %d, width: %d, height: %d, bitrate: %d,"
314 "maxBr: %d, min_br: %d, frame_rate: %d", __FUNCTION__,
315 video_codec.codecType, video_codec.plType, video_codec.width,
316 video_codec.height, video_codec.startBitrate,
317 video_codec.maxBitrate, video_codec.minBitrate,
318 video_codec.maxFramerate);
niklase@google.com470e71d2011-07-07 08:21:25 +0000319
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000320 if (CodecValid(video_codec) == false) {
321 // Error logged.
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000322 shared_data_->SetLastError(kViECodecInvalidCodec);
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000323 return -1;
324 }
325
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000326 ViEChannelManagerScoped cs(*(shared_data_->channel_manager()));
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000327 ViEChannel* vie_channel = cs.Channel(video_channel);
328 if (!vie_channel) {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000329 WEBRTC_TRACE(kTraceError, kTraceVideo,
330 ViEId(shared_data_->instance_id(), video_channel),
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000331 "%s: No channel %d", __FUNCTION__, video_channel);
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000332 shared_data_->SetLastError(kViECodecInvalidChannelId);
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000333 return -1;
334 }
335
336 if (vie_channel->SetReceiveCodec(video_codec) != 0) {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000337 WEBRTC_TRACE(kTraceError, kTraceVideo,
338 ViEId(shared_data_->instance_id(), video_channel),
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000339 "%s: Could not set receive codec for channel %d",
340 __FUNCTION__, video_channel);
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000341 shared_data_->SetLastError(kViECodecUnknownError);
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000342 return -1;
343 }
344 return 0;
345}
346
347int ViECodecImpl::GetReceiveCodec(const int video_channel,
348 VideoCodec& video_codec) const {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000349 WEBRTC_TRACE(kTraceApiCall, kTraceVideo,
350 ViEId(shared_data_->instance_id(), video_channel),
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000351 "%s(video_channel: %d, codec_type: %d)", __FUNCTION__,
352 video_channel, video_codec.codecType);
353
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000354 ViEChannelManagerScoped cs(*(shared_data_->channel_manager()));
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000355 ViEChannel* vie_channel = cs.Channel(video_channel);
356 if (!vie_channel) {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000357 WEBRTC_TRACE(kTraceError, kTraceVideo,
358 ViEId(shared_data_->instance_id(), video_channel),
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000359 "%s: No channel %d", __FUNCTION__, video_channel);
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000360 shared_data_->SetLastError(kViECodecInvalidChannelId);
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000361 return -1;
362 }
363
mflodman@webrtc.orgf5e99db2012-06-27 09:49:37 +0000364 if (vie_channel->GetReceiveCodec(&video_codec) != 0) {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000365 shared_data_->SetLastError(kViECodecUnknownError);
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000366 return -1;
367 }
368 return 0;
369}
370
371int ViECodecImpl::GetCodecConfigParameters(
372 const int video_channel,
373 unsigned char config_parameters[kConfigParameterSize],
374 unsigned char& config_parameters_size) const {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000375 WEBRTC_TRACE(kTraceApiCall, kTraceVideo,
376 ViEId(shared_data_->instance_id(), video_channel),
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000377 "%s(video_channel: %d)", __FUNCTION__, video_channel);
378
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000379 ViEChannelManagerScoped cs(*(shared_data_->channel_manager()));
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000380 ViEEncoder* vie_encoder = cs.Encoder(video_channel);
381 if (!vie_encoder) {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000382 WEBRTC_TRACE(kTraceError, kTraceVideo,
383 ViEId(shared_data_->instance_id(), video_channel),
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000384 "%s: No encoder for channel %d", __FUNCTION__, video_channel);
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000385 shared_data_->SetLastError(kViECodecInvalidChannelId);
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000386 return -1;
387 }
388
389 if (vie_encoder->GetCodecConfigParameters(config_parameters,
390 config_parameters_size) != 0) {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000391 shared_data_->SetLastError(kViECodecUnknownError);
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000392 return -1;
393 }
394 return 0;
395}
396
397int ViECodecImpl::SetImageScaleStatus(const int video_channel,
398 const bool enable) {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000399 WEBRTC_TRACE(kTraceApiCall, kTraceVideo,
400 ViEId(shared_data_->instance_id(), video_channel),
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000401 "%s(video_channel: %d, enable: %d)", __FUNCTION__, video_channel,
402 enable);
403
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000404 ViEChannelManagerScoped cs(*(shared_data_->channel_manager()));
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000405 ViEEncoder* vie_encoder = cs.Encoder(video_channel);
406 if (!vie_encoder) {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000407 WEBRTC_TRACE(kTraceError, kTraceVideo,
408 ViEId(shared_data_->instance_id(), video_channel),
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000409 "%s: No channel %d", __FUNCTION__, video_channel);
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000410 shared_data_->SetLastError(kViECodecInvalidChannelId);
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000411 return -1;
412 }
413
414 if (vie_encoder->ScaleInputImage(enable) != 0) {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000415 shared_data_->SetLastError(kViECodecUnknownError);
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000416 return -1;
417 }
418 return 0;
419}
420
421int ViECodecImpl::GetSendCodecStastistics(const int video_channel,
422 unsigned int& key_frames,
423 unsigned int& delta_frames) const {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000424 WEBRTC_TRACE(kTraceApiCall, kTraceVideo,
425 ViEId(shared_data_->instance_id(), video_channel),
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000426 "%s(video_channel %d)", __FUNCTION__, video_channel);
427
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000428 ViEChannelManagerScoped cs(*(shared_data_->channel_manager()));
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000429 ViEEncoder* vie_encoder = cs.Encoder(video_channel);
430 if (!vie_encoder) {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000431 WEBRTC_TRACE(kTraceError, kTraceVideo,
432 ViEId(shared_data_->instance_id(), video_channel),
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000433 "%s: No send codec for channel %d", __FUNCTION__,
434 video_channel);
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000435 shared_data_->SetLastError(kViECodecInvalidChannelId);
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000436 return -1;
437 }
438
mflodman@webrtc.orgf5e99db2012-06-27 09:49:37 +0000439 if (vie_encoder->SendCodecStatistics(&key_frames, &delta_frames) != 0) {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000440 shared_data_->SetLastError(kViECodecUnknownError);
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000441 return -1;
442 }
443 return 0;
444}
445
446int ViECodecImpl::GetReceiveCodecStastistics(const int video_channel,
447 unsigned int& key_frames,
448 unsigned int& delta_frames) const {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000449 WEBRTC_TRACE(kTraceApiCall, kTraceVideo,
450 ViEId(shared_data_->instance_id(), video_channel),
mflodman@webrtc.org4aee6b62012-12-14 14:02:10 +0000451 "%s(video_channel: %d)", __FUNCTION__,
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000452 video_channel);
453
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000454 ViEChannelManagerScoped cs(*(shared_data_->channel_manager()));
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000455 ViEChannel* vie_channel = cs.Channel(video_channel);
456 if (!vie_channel) {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000457 WEBRTC_TRACE(kTraceError, kTraceVideo,
458 ViEId(shared_data_->instance_id(), video_channel),
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000459 "%s: No channel %d", __FUNCTION__, video_channel);
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000460 shared_data_->SetLastError(kViECodecInvalidChannelId);
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000461 return -1;
462 }
mflodman@webrtc.orgf5e99db2012-06-27 09:49:37 +0000463 if (vie_channel->ReceiveCodecStatistics(&key_frames, &delta_frames) != 0) {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000464 shared_data_->SetLastError(kViECodecUnknownError);
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000465 return -1;
466 }
467 return 0;
468}
469
mflodman@webrtc.org4aee6b62012-12-14 14:02:10 +0000470int ViECodecImpl::GetReceiveSideDelay(const int video_channel,
471 int* delay_ms) const {
472 WEBRTC_TRACE(kTraceApiCall, kTraceVideo,
473 ViEId(shared_data_->instance_id(), video_channel),
474 "%s(video_channel: %d)", __FUNCTION__, video_channel);
475 if (delay_ms == NULL) {
476 LOG_F(LS_ERROR) << "NULL pointer argument.";
477 return -1;
478 }
479
480 ViEChannelManagerScoped cs(*(shared_data_->channel_manager()));
481 ViEChannel* vie_channel = cs.Channel(video_channel);
482 if (!vie_channel) {
483 WEBRTC_TRACE(kTraceError, kTraceVideo,
484 ViEId(shared_data_->instance_id(), video_channel),
485 "%s: No channel %d", __FUNCTION__, video_channel);
486 shared_data_->SetLastError(kViECodecInvalidChannelId);
487 return -1;
488 }
489 *delay_ms = vie_channel->ReceiveDelay();
490 if (*delay_ms < 0) {
491 return -1;
492 }
493 return 0;
494}
495
496
stefan@webrtc.org439be292012-02-16 14:45:37 +0000497int ViECodecImpl::GetCodecTargetBitrate(const int video_channel,
498 unsigned int* bitrate) const {
499 WEBRTC_TRACE(kTraceApiCall, kTraceVideo,
500 ViEId(shared_data_->instance_id(), video_channel),
501 "%s(video_channel: %d, codec_type: %d)", __FUNCTION__,
502 video_channel);
503
504 ViEChannelManagerScoped cs(*(shared_data_->channel_manager()));
505 ViEEncoder* vie_encoder = cs.Encoder(video_channel);
506 if (!vie_encoder) {
507 WEBRTC_TRACE(kTraceError, kTraceVideo,
508 ViEId(shared_data_->instance_id(), video_channel),
509 "%s: No send codec for channel %d", __FUNCTION__,
510 video_channel);
511 shared_data_->SetLastError(kViECodecInvalidChannelId);
512 return -1;
513 }
514 return vie_encoder->CodecTargetBitrate(static_cast<WebRtc_UWord32*>(bitrate));
515}
516
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000517unsigned int ViECodecImpl::GetDiscardedPackets(const int video_channel) const {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000518 WEBRTC_TRACE(kTraceApiCall, kTraceVideo,
519 ViEId(shared_data_->instance_id(), video_channel),
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000520 "%s(video_channel: %d, codec_type: %d)", __FUNCTION__,
521 video_channel);
522
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000523 ViEChannelManagerScoped cs(*(shared_data_->channel_manager()));
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000524 ViEChannel* vie_channel = cs.Channel(video_channel);
525 if (!vie_channel) {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000526 WEBRTC_TRACE(kTraceError, kTraceVideo,
527 ViEId(shared_data_->instance_id(), video_channel),
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000528 "%s: No channel %d", __FUNCTION__, video_channel);
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000529 shared_data_->SetLastError(kViECodecInvalidChannelId);
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000530 return -1;
531 }
532 return vie_channel->DiscardedPackets();
533}
534
535int ViECodecImpl::SetKeyFrameRequestCallbackStatus(const int video_channel,
536 const bool enable) {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000537 WEBRTC_TRACE(kTraceApiCall, kTraceVideo,
538 ViEId(shared_data_->instance_id(), video_channel),
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000539 "%s(video_channel: %d)", __FUNCTION__, video_channel);
540
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000541 ViEChannelManagerScoped cs(*(shared_data_->channel_manager()));
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000542 ViEChannel* vie_channel = cs.Channel(video_channel);
543 if (!vie_channel) {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000544 WEBRTC_TRACE(kTraceError, kTraceVideo,
545 ViEId(shared_data_->instance_id(), video_channel),
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000546 "%s: No channel %d", __FUNCTION__, video_channel);
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000547 shared_data_->SetLastError(kViECodecInvalidChannelId);
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000548 return -1;
549 }
550 if (vie_channel->EnableKeyFrameRequestCallback(enable) != 0) {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000551 shared_data_->SetLastError(kViECodecUnknownError);
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000552 return -1;
553 }
554 return 0;
555}
556
557int ViECodecImpl::SetSignalKeyPacketLossStatus(const int video_channel,
niklase@google.com470e71d2011-07-07 08:21:25 +0000558 const bool enable,
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000559 const bool only_key_frames) {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000560 WEBRTC_TRACE(kTraceApiCall, kTraceVideo,
561 ViEId(shared_data_->instance_id(), video_channel),
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000562 "%s(video_channel: %d, enable: %d, only_key_frames: %d)",
563 __FUNCTION__, video_channel, enable);
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 ViEChannel* vie_channel = cs.Channel(video_channel);
567 if (!vie_channel) {
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 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_channel->SetSignalPacketLossStatus(enable, only_key_frames) != 0) {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000575 shared_data_->SetLastError(kViECodecUnknownError);
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000576 return -1;
577 }
578 return 0;
niklase@google.com470e71d2011-07-07 08:21:25 +0000579}
580
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000581int ViECodecImpl::RegisterEncoderObserver(const int video_channel,
582 ViEEncoderObserver& observer) {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000583 WEBRTC_TRACE(kTraceApiCall, kTraceVideo, ViEId(shared_data_->instance_id()),
584 "%s", __FUNCTION__);
niklase@google.com470e71d2011-07-07 08:21:25 +0000585
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000586 ViEChannelManagerScoped cs(*(shared_data_->channel_manager()));
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000587 ViEEncoder* vie_encoder = cs.Encoder(video_channel);
588 if (!vie_encoder) {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000589 WEBRTC_TRACE(kTraceError, kTraceVideo,
590 ViEId(shared_data_->instance_id(), video_channel),
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000591 "%s: No encoder for channel %d", __FUNCTION__, video_channel);
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000592 shared_data_->SetLastError(kViECodecInvalidChannelId);
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000593 return -1;
594 }
595 if (vie_encoder->RegisterCodecObserver(&observer) != 0) {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000596 WEBRTC_TRACE(kTraceError, kTraceVideo,
597 ViEId(shared_data_->instance_id(), video_channel),
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000598 "%s: Could not register codec observer at channel",
599 __FUNCTION__);
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000600 shared_data_->SetLastError(kViECodecObserverAlreadyRegistered);
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000601 return -1;
602 }
603 return 0;
niklase@google.com470e71d2011-07-07 08:21:25 +0000604}
605
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000606int ViECodecImpl::DeregisterEncoderObserver(const int video_channel) {
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 ViEEncoder* vie_encoder = cs.Encoder(video_channel);
612 if (!vie_encoder) {
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 encoder for 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_encoder->RegisterCodecObserver(NULL) != 0) {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000620 shared_data_->SetLastError(kViECodecObserverNotRegistered);
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000621 return -1;
622 }
623 return 0;
niklase@google.com470e71d2011-07-07 08:21:25 +0000624}
625
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000626int ViECodecImpl::RegisterDecoderObserver(const int video_channel,
627 ViEDecoderObserver& observer) {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000628 WEBRTC_TRACE(kTraceApiCall, kTraceVideo, ViEId(shared_data_->instance_id()),
629 "%s", __FUNCTION__);
niklase@google.com470e71d2011-07-07 08:21:25 +0000630
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000631 ViEChannelManagerScoped cs(*(shared_data_->channel_manager()));
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000632 ViEChannel* vie_channel = cs.Channel(video_channel);
633 if (!vie_channel) {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000634 WEBRTC_TRACE(kTraceError, kTraceVideo,
635 ViEId(shared_data_->instance_id(), video_channel),
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000636 "%s: No channel %d", __FUNCTION__, video_channel);
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000637 shared_data_->SetLastError(kViECodecInvalidChannelId);
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000638 return -1;
639 }
640 if (vie_channel->RegisterCodecObserver(&observer) != 0) {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000641 WEBRTC_TRACE(kTraceError, kTraceVideo,
642 ViEId(shared_data_->instance_id(), video_channel),
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000643 "%s: Could not register codec observer at channel",
644 __FUNCTION__);
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000645 shared_data_->SetLastError(kViECodecObserverAlreadyRegistered);
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::DeregisterDecoderObserver(const int video_channel) {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000652 WEBRTC_TRACE(kTraceApiCall, kTraceVideo,
653 ViEId(shared_data_->instance_id()), "%s",
niklase@google.com470e71d2011-07-07 08:21:25 +0000654 __FUNCTION__);
655
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000656 ViEChannelManagerScoped cs(*(shared_data_->channel_manager()));
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000657 ViEChannel* vie_channel = cs.Channel(video_channel);
658 if (!vie_channel) {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000659 WEBRTC_TRACE(kTraceError, kTraceVideo,
660 ViEId(shared_data_->instance_id(), video_channel),
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000661 "%s: No channel %d", __FUNCTION__, video_channel);
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000662 shared_data_->SetLastError(kViECodecInvalidChannelId);
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000663 return -1;
664 }
665 if (vie_channel->RegisterCodecObserver(NULL) != 0) {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000666 shared_data_->SetLastError(kViECodecObserverNotRegistered);
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000667 return -1;
668 }
669 return 0;
niklase@google.com470e71d2011-07-07 08:21:25 +0000670}
671
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000672int ViECodecImpl::SendKeyFrame(const int video_channel) {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000673 WEBRTC_TRACE(kTraceApiCall, kTraceVideo, ViEId(shared_data_->instance_id()),
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000674 "%s(video_channel: %d)", __FUNCTION__, video_channel);
niklase@google.com470e71d2011-07-07 08:21:25 +0000675
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000676 ViEChannelManagerScoped cs(*(shared_data_->channel_manager()));
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000677 ViEEncoder* vie_encoder = cs.Encoder(video_channel);
678 if (!vie_encoder) {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000679 WEBRTC_TRACE(kTraceError, kTraceVideo,
680 ViEId(shared_data_->instance_id(), video_channel),
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000681 "%s: No channel %d", __FUNCTION__, video_channel);
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000682 shared_data_->SetLastError(kViECodecInvalidChannelId);
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000683 return -1;
684 }
685 if (vie_encoder->SendKeyFrame() != 0) {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000686 shared_data_->SetLastError(kViECodecUnknownError);
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000687 return -1;
688 }
689 return 0;
niklase@google.com470e71d2011-07-07 08:21:25 +0000690}
691
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000692int ViECodecImpl::WaitForFirstKeyFrame(const int video_channel,
693 const bool wait) {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000694 WEBRTC_TRACE(kTraceApiCall, kTraceVideo,
695 ViEId(shared_data_->instance_id()),
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000696 "%s(video_channel: %d, wait: %d)", __FUNCTION__, video_channel,
niklase@google.com470e71d2011-07-07 08:21:25 +0000697 wait);
698
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000699 ViEChannelManagerScoped cs(*(shared_data_->channel_manager()));
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000700 ViEChannel* vie_channel = cs.Channel(video_channel);
701 if (!vie_channel) {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000702 WEBRTC_TRACE(kTraceError, kTraceVideo,
703 ViEId(shared_data_->instance_id(), video_channel),
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000704 "%s: No channel %d", __FUNCTION__, video_channel);
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000705 shared_data_->SetLastError(kViECodecInvalidChannelId);
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000706 return -1;
707 }
708 if (vie_channel->WaitForKeyFrame(wait) != 0) {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000709 shared_data_->SetLastError(kViECodecUnknownError);
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000710 return -1;
711 }
712 return 0;
niklase@google.com470e71d2011-07-07 08:21:25 +0000713}
714
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000715bool ViECodecImpl::CodecValid(const VideoCodec& video_codec) {
716 // Check pl_name matches codec_type.
717 if (video_codec.codecType == kVideoCodecRED) {
niklase@google.com470e71d2011-07-07 08:21:25 +0000718#if defined(WIN32)
mflodman@webrtc.org1fe2ada2011-12-21 12:23:15 +0000719 if (_strnicmp(video_codec.plName, "red", 3) == 0) {
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000720#else
721 if (strncasecmp(video_codec.plName, "red", 3) == 0) {
niklase@google.com470e71d2011-07-07 08:21:25 +0000722#endif
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000723 // We only care about the type and name for red.
724 return true;
niklase@google.com470e71d2011-07-07 08:21:25 +0000725 }
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 } else if (video_codec.codecType == kVideoCodecULPFEC) {
niklase@google.com470e71d2011-07-07 08:21:25 +0000730#if defined(WIN32)
mflodman@webrtc.org1fe2ada2011-12-21 12:23:15 +0000731 if (_strnicmp(video_codec.plName, "ULPFEC", 6) == 0) {
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000732#else
733 if (strncasecmp(video_codec.plName, "ULPFEC", 6) == 0) {
niklase@google.com470e71d2011-07-07 08:21:25 +0000734#endif
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000735 // We only care about the type and name for ULPFEC.
736 return true;
niklase@google.com470e71d2011-07-07 08:21:25 +0000737 }
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000738 WEBRTC_TRACE(kTraceError, kTraceVideo, -1,
739 "Codec type doesn't match pl_name", video_codec.plType);
740 return false;
pwestin@webrtc.org56210572012-01-17 12:45:47 +0000741 } else if ((video_codec.codecType == kVideoCodecVP8 &&
pbos@webrtc.org8911ce42013-03-18 16:39:03 +0000742 strncmp(video_codec.plName, "VP8", 4) == 0) ||
743 (video_codec.codecType == kVideoCodecI420 &&
pbos@webrtc.orgb5bf54c2013-04-05 13:27:38 +0000744 strncmp(video_codec.plName, "I420", 4) == 0)) {
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000745 // OK.
pbos@webrtc.orgb5bf54c2013-04-05 13:27:38 +0000746 } else if (video_codec.codecType != kVideoCodecGeneric) {
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000747 WEBRTC_TRACE(kTraceError, kTraceVideo, -1,
748 "Codec type doesn't match pl_name", video_codec.plType);
749 return false;
750 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000751
braveyao@webrtc.org49273ff2013-01-14 01:52:26 +0000752 if (video_codec.plType == 0 || video_codec.plType > 127) {
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000753 WEBRTC_TRACE(kTraceError, kTraceVideo, -1,
754 "Invalid codec payload type: %d", video_codec.plType);
755 return false;
756 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000757
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000758 if (video_codec.width > kViEMaxCodecWidth ||
759 video_codec.height > kViEMaxCodecHeight) {
760 WEBRTC_TRACE(kTraceError, kTraceVideo, -1, "Invalid codec size: %u x %u",
761 video_codec.width, video_codec.height);
762 return false;
763 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000764
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000765 if (video_codec.startBitrate < kViEMinCodecBitrate) {
766 WEBRTC_TRACE(kTraceError, kTraceVideo, -1, "Invalid start_bitrate: %u",
767 video_codec.startBitrate);
768 return false;
769 }
770 if (video_codec.minBitrate < kViEMinCodecBitrate) {
771 WEBRTC_TRACE(kTraceError, kTraceVideo, -1, "Invalid min_bitrate: %u",
772 video_codec.minBitrate);
773 return false;
774 }
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000775 return true;
niklase@google.com470e71d2011-07-07 08:21:25 +0000776}
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000777
778} // namespace webrtc