blob: dd4d37da2fca11ff9a661d157d0e3993ebae70a1 [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.org9ba151b2012-06-21 10:02:13 +000013#include "engine_configurations.h" // NOLINT
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +000014#include "modules/video_coding/main/interface/video_coding.h"
15#include "system_wrappers/interface/trace.h"
mflodman@webrtc.orga4863db2011-12-22 08:51:52 +000016#include "video_engine/include/vie_errors.h"
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +000017#include "video_engine/vie_capturer.h"
18#include "video_engine/vie_channel.h"
19#include "video_engine/vie_channel_manager.h"
20#include "video_engine/vie_defines.h"
21#include "video_engine/vie_encoder.h"
22#include "video_engine/vie_impl.h"
23#include "video_engine/vie_input_manager.h"
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +000024#include "video_engine/vie_shared_data.h"
niklase@google.com470e71d2011-07-07 08:21:25 +000025
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +000026namespace webrtc {
niklase@google.com470e71d2011-07-07 08:21:25 +000027
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +000028ViECodec* ViECodec::GetInterface(VideoEngine* video_engine) {
niklase@google.com470e71d2011-07-07 08:21:25 +000029#ifdef WEBRTC_VIDEO_ENGINE_CODEC_API
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +000030 if (!video_engine) {
niklase@google.com470e71d2011-07-07 08:21:25 +000031 return NULL;
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +000032 }
33 VideoEngineImpl* vie_impl = reinterpret_cast<VideoEngineImpl*>(video_engine);
34 ViECodecImpl* vie_codec_impl = vie_impl;
35 // Increase ref count.
36 (*vie_codec_impl)++;
37 return vie_codec_impl;
38#else
39 return NULL;
niklase@google.com470e71d2011-07-07 08:21:25 +000040#endif
41}
42
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +000043int ViECodecImpl::Release() {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +000044 WEBRTC_TRACE(kTraceApiCall, kTraceVideo, shared_data_->instance_id(),
niklase@google.com470e71d2011-07-07 08:21:25 +000045 "ViECodecImpl::Release()");
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +000046 // Decrease ref count.
47 (*this)--;
niklase@google.com470e71d2011-07-07 08:21:25 +000048
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +000049 WebRtc_Word32 ref_count = GetCount();
50 if (ref_count < 0) {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +000051 WEBRTC_TRACE(kTraceWarning, kTraceVideo, shared_data_->instance_id(),
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +000052 "ViECodec released too many times");
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +000053 shared_data_->SetLastError(kViEAPIDoesNotExist);
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +000054 return -1;
55 }
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +000056 WEBRTC_TRACE(kTraceInfo, kTraceVideo, shared_data_->instance_id(),
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +000057 "ViECodec reference count: %d", ref_count);
58 return ref_count;
niklase@google.com470e71d2011-07-07 08:21:25 +000059}
60
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +000061ViECodecImpl::ViECodecImpl(ViESharedData* shared_data)
62 : shared_data_(shared_data) {
63 WEBRTC_TRACE(kTraceMemory, kTraceVideo, shared_data_->instance_id(),
niklase@google.com470e71d2011-07-07 08:21:25 +000064 "ViECodecImpl::ViECodecImpl() Ctor");
65}
66
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +000067ViECodecImpl::~ViECodecImpl() {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +000068 WEBRTC_TRACE(kTraceMemory, kTraceVideo, shared_data_->instance_id(),
niklase@google.com470e71d2011-07-07 08:21:25 +000069 "ViECodecImpl::~ViECodecImpl() Dtor");
70}
71
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +000072int ViECodecImpl::NumberOfCodecs() const {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +000073 WEBRTC_TRACE(kTraceApiCall, kTraceVideo, ViEId(shared_data_->instance_id()),
74 "%s", __FUNCTION__);
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +000075 // +2 because of FEC(RED and ULPFEC)
76 return static_cast<int>((VideoCodingModule::NumberOfCodecs() + 2));
niklase@google.com470e71d2011-07-07 08:21:25 +000077}
78
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +000079int ViECodecImpl::GetCodec(const unsigned char list_number,
80 VideoCodec& video_codec) const {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +000081 WEBRTC_TRACE(kTraceApiCall, kTraceVideo, ViEId(shared_data_->instance_id()),
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +000082 "%s(list_number: %d, codec_type: %d)", __FUNCTION__,
83 list_number, video_codec.codecType);
84 if (list_number == VideoCodingModule::NumberOfCodecs()) {
85 memset(&video_codec, 0, sizeof(VideoCodec));
mflodman@webrtc.org9ba151b2012-06-21 10:02:13 +000086 strncpy(video_codec.plName, "red", 3);
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +000087 video_codec.codecType = kVideoCodecRED;
88 video_codec.plType = VCM_RED_PAYLOAD_TYPE;
89 } else if (list_number == VideoCodingModule::NumberOfCodecs() + 1) {
90 memset(&video_codec, 0, sizeof(VideoCodec));
mflodman@webrtc.org9ba151b2012-06-21 10:02:13 +000091 strncpy(video_codec.plName, "ulpfec", 6);
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +000092 video_codec.codecType = kVideoCodecULPFEC;
93 video_codec.plType = VCM_ULPFEC_PAYLOAD_TYPE;
94 } else if (VideoCodingModule::Codec(list_number, &video_codec) != VCM_OK) {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +000095 WEBRTC_TRACE(kTraceApiCall, kTraceVideo, ViEId(shared_data_->instance_id()),
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +000096 "%s: Could not get codec for list_number: %u", __FUNCTION__,
97 list_number);
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +000098 shared_data_->SetLastError(kViECodecInvalidArgument);
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +000099 return -1;
100 }
101 return 0;
niklase@google.com470e71d2011-07-07 08:21:25 +0000102}
103
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000104int ViECodecImpl::SetSendCodec(const int video_channel,
105 const VideoCodec& video_codec) {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000106 WEBRTC_TRACE(kTraceApiCall, kTraceVideo,
mflodman@webrtc.org9ba151b2012-06-21 10:02:13 +0000107 ViEId(shared_data_->instance_id(), video_channel),
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000108 "%s(video_channel: %d, codec_type: %d)", __FUNCTION__,
109 video_channel, video_codec.codecType);
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000110 WEBRTC_TRACE(kTraceInfo, kTraceVideo,
111 ViEId(shared_data_->instance_id(), video_channel),
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000112 "%s: codec: %d, pl_type: %d, width: %d, height: %d, bitrate: %d"
mflodman@webrtc.org9c0aedc2012-01-03 13:46:49 +0000113 "maxBr: %d, min_br: %d, frame_rate: %d, qpMax: %u,"
114 "numberOfSimulcastStreams: %u )", __FUNCTION__,
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000115 video_codec.codecType, video_codec.plType, video_codec.width,
116 video_codec.height, video_codec.startBitrate,
117 video_codec.maxBitrate, video_codec.minBitrate,
mflodman@webrtc.org9c0aedc2012-01-03 13:46:49 +0000118 video_codec.maxFramerate, video_codec.qpMax,
119 video_codec.numberOfSimulcastStreams);
120 if (video_codec.codecType == kVideoCodecVP8) {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000121 WEBRTC_TRACE(kTraceInfo, kTraceVideo,
122 ViEId(shared_data_->instance_id(), video_channel),
mflodman@webrtc.org9c0aedc2012-01-03 13:46:49 +0000123 "pictureLossIndicationOn: %d, feedbackModeOn: %d, "
124 "complexity: %d, resilience: %d, numberOfTemporalLayers: %u",
125 video_codec.codecSpecific.VP8.pictureLossIndicationOn,
126 video_codec.codecSpecific.VP8.feedbackModeOn,
127 video_codec.codecSpecific.VP8.complexity,
128 video_codec.codecSpecific.VP8.resilience,
129 video_codec.codecSpecific.VP8.numberOfTemporalLayers);
130 }
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000131 if (!CodecValid(video_codec)) {
132 // Error logged.
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000133 shared_data_->SetLastError(kViECodecInvalidCodec);
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000134 return -1;
135 }
stefan@webrtc.org791eec72011-10-11 07:53:43 +0000136
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000137 ViEChannelManagerScoped cs(*(shared_data_->channel_manager()));
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000138 ViEChannel* vie_channel = cs.Channel(video_channel);
139 if (!vie_channel) {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000140 WEBRTC_TRACE(kTraceError, kTraceVideo,
141 ViEId(shared_data_->instance_id(), video_channel),
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000142 "%s: No channel %d", __FUNCTION__, video_channel);
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000143 shared_data_->SetLastError(kViECodecInvalidChannelId);
stefan@webrtc.org791eec72011-10-11 07:53:43 +0000144 return -1;
145 }
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000146
mflodman@webrtc.org9ec883e2012-03-05 17:12:41 +0000147 ViEEncoder* vie_encoder = cs.Encoder(video_channel);
148 assert(vie_encoder);
149 if (vie_encoder->Owner() != video_channel) {
150 WEBRTC_TRACE(kTraceError, kTraceVideo,
151 ViEId(shared_data_->instance_id(), video_channel),
152 "%s: Receive only channel %d", __FUNCTION__, video_channel);
153 shared_data_->SetLastError(kViECodecReceiveOnlyChannel);
154 return -1;
155 }
156
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000157 // Set a max_bitrate if the user hasn't set one.
158 VideoCodec video_codec_internal;
159 memcpy(&video_codec_internal, &video_codec, sizeof(VideoCodec));
160 if (video_codec_internal.maxBitrate == 0) {
161 // Max is one bit per pixel.
162 video_codec_internal.maxBitrate = (video_codec_internal.width *
163 video_codec_internal.height *
164 video_codec_internal.maxFramerate)
165 / 1000;
166 if (video_codec_internal.startBitrate > video_codec_internal.maxBitrate) {
167 // Don't limit the set start bitrate.
168 video_codec_internal.maxBitrate = video_codec_internal.startBitrate;
169 }
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000170 WEBRTC_TRACE(kTraceInfo, kTraceVideo,
171 ViEId(shared_data_->instance_id(), video_channel),
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000172 "%s: New max bitrate set to %d kbps", __FUNCTION__,
173 video_codec_internal.maxBitrate);
174 }
175
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000176 VideoCodec encoder;
mflodman@webrtc.orgf5e99db2012-06-27 09:49:37 +0000177 vie_encoder->GetEncoder(&encoder);
mflodman@webrtc.org9ec883e2012-03-05 17:12:41 +0000178
mflodman@webrtc.org9c0aedc2012-01-03 13:46:49 +0000179 // Make sure to generate a new SSRC if the codec type and/or resolution has
180 // changed. This won't have any effect if the user has set an SSRC.
181 bool new_rtp_stream = false;
stefan@webrtc.org4e8eaba2012-08-20 14:29:52 +0000182 if (encoder.codecType != video_codec_internal.codecType) {
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000183 new_rtp_stream = true;
184 }
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000185
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000186 ViEInputManagerScoped is(*(shared_data_->input_manager()));
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000187 ViEFrameProviderBase* frame_provider = NULL;
188
189 // Stop the media flow while reconfiguring.
190 vie_encoder->Pause();
191
192 // Check if we have a frame provider that is a camera and can provide this
193 // codec for us.
194 bool use_capture_device_as_encoder = false;
195 frame_provider = is.FrameProvider(vie_encoder);
196 if (frame_provider) {
197 if (frame_provider->Id() >= kViECaptureIdBase &&
198 frame_provider->Id() <= kViECaptureIdMax) {
199 ViECapturer* vie_capture = static_cast<ViECapturer*>(frame_provider);
200 // Try to get preencoded. Nothing to do if it is not supported.
201 if (vie_capture && vie_capture->PreEncodeToViEEncoder(
202 video_codec_internal,
203 *vie_encoder,
204 video_channel) == 0) {
205 use_capture_device_as_encoder = true;
206 }
207 }
208 }
209
210 // Update the encoder settings if we are not using a capture device capable
211 // of this codec.
212 if (!use_capture_device_as_encoder &&
213 vie_encoder->SetEncoder(video_codec_internal) != 0) {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000214 WEBRTC_TRACE(kTraceError, kTraceVideo,
215 ViEId(shared_data_->instance_id(), video_channel),
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000216 "%s: Could not change encoder for channel %d", __FUNCTION__,
217 video_channel);
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000218 shared_data_->SetLastError(kViECodecUnknownError);
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000219 return -1;
220 }
221
mflodman@webrtc.org9c0aedc2012-01-03 13:46:49 +0000222 // Give the channel(s) the new information.
223 ChannelList channels;
224 cs.ChannelsUsingViEEncoder(video_channel, &channels);
225 for (ChannelList::iterator it = channels.begin(); it != channels.end();
226 ++it) {
227 bool ret = true;
228 if ((*it)->SetSendCodec(video_codec_internal, new_rtp_stream) != 0) {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000229 WEBRTC_TRACE(kTraceError, kTraceVideo,
230 ViEId(shared_data_->instance_id(), video_channel),
mflodman@webrtc.org9c0aedc2012-01-03 13:46:49 +0000231 "%s: Could not set send codec for channel %d", __FUNCTION__,
232 video_channel);
233 ret = false;
234 }
235 if (!ret) {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000236 shared_data_->SetLastError(kViECodecUnknownError);
mflodman@webrtc.org9c0aedc2012-01-03 13:46:49 +0000237 return -1;
238 }
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000239 }
240
241 // Update the protection mode, we might be switching NACK/FEC.
242 vie_encoder->UpdateProtectionMethod();
243
244 // Get new best format for frame provider.
245 if (frame_provider) {
246 frame_provider->FrameCallbackChanged();
247 }
248 // Restart the media flow
249 if (new_rtp_stream) {
250 // Stream settings changed, make sure we get a key frame.
251 vie_encoder->SendKeyFrame();
252 }
253 vie_encoder->Restart();
254 return 0;
stefan@webrtc.org791eec72011-10-11 07:53:43 +0000255}
256
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000257int ViECodecImpl::GetSendCodec(const int video_channel,
258 VideoCodec& video_codec) const {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000259 WEBRTC_TRACE(kTraceApiCall, kTraceVideo,
260 ViEId(shared_data_->instance_id(), video_channel),
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000261 "%s(video_channel: %d)", __FUNCTION__, video_channel);
niklase@google.com470e71d2011-07-07 08:21:25 +0000262
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000263 ViEChannelManagerScoped cs(*(shared_data_->channel_manager()));
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000264 ViEEncoder* vie_encoder = cs.Encoder(video_channel);
265 if (!vie_encoder) {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000266 WEBRTC_TRACE(kTraceError, kTraceVideo,
267 ViEId(shared_data_->instance_id(), video_channel),
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000268 "%s: No encoder for channel %d", __FUNCTION__, video_channel);
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000269 shared_data_->SetLastError(kViECodecInvalidChannelId);
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000270 return -1;
271 }
mflodman@webrtc.orgf5e99db2012-06-27 09:49:37 +0000272 return vie_encoder->GetEncoder(&video_codec);
niklase@google.com470e71d2011-07-07 08:21:25 +0000273}
274
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000275int ViECodecImpl::SetReceiveCodec(const int video_channel,
276 const VideoCodec& video_codec) {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000277 WEBRTC_TRACE(kTraceApiCall, kTraceVideo,
278 ViEId(shared_data_->instance_id(), video_channel),
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000279 "%s(video_channel: %d, codec_type: %d)", __FUNCTION__,
280 video_channel, video_codec.codecType);
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000281 WEBRTC_TRACE(kTraceInfo, kTraceVideo,
282 ViEId(shared_data_->instance_id(), video_channel),
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000283 "%s: codec: %d, pl_type: %d, width: %d, height: %d, bitrate: %d,"
284 "maxBr: %d, min_br: %d, frame_rate: %d", __FUNCTION__,
285 video_codec.codecType, video_codec.plType, video_codec.width,
286 video_codec.height, video_codec.startBitrate,
287 video_codec.maxBitrate, video_codec.minBitrate,
288 video_codec.maxFramerate);
niklase@google.com470e71d2011-07-07 08:21:25 +0000289
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000290 if (CodecValid(video_codec) == false) {
291 // Error logged.
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000292 shared_data_->SetLastError(kViECodecInvalidCodec);
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000293 return -1;
294 }
295
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000296 ViEChannelManagerScoped cs(*(shared_data_->channel_manager()));
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000297 ViEChannel* vie_channel = cs.Channel(video_channel);
298 if (!vie_channel) {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000299 WEBRTC_TRACE(kTraceError, kTraceVideo,
300 ViEId(shared_data_->instance_id(), video_channel),
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000301 "%s: No channel %d", __FUNCTION__, video_channel);
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000302 shared_data_->SetLastError(kViECodecInvalidChannelId);
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000303 return -1;
304 }
305
306 if (vie_channel->SetReceiveCodec(video_codec) != 0) {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000307 WEBRTC_TRACE(kTraceError, kTraceVideo,
308 ViEId(shared_data_->instance_id(), video_channel),
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000309 "%s: Could not set receive codec for channel %d",
310 __FUNCTION__, video_channel);
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000311 shared_data_->SetLastError(kViECodecUnknownError);
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000312 return -1;
313 }
314 return 0;
315}
316
317int ViECodecImpl::GetReceiveCodec(const int video_channel,
318 VideoCodec& video_codec) const {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000319 WEBRTC_TRACE(kTraceApiCall, kTraceVideo,
320 ViEId(shared_data_->instance_id(), video_channel),
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000321 "%s(video_channel: %d, codec_type: %d)", __FUNCTION__,
322 video_channel, video_codec.codecType);
323
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000324 ViEChannelManagerScoped cs(*(shared_data_->channel_manager()));
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000325 ViEChannel* vie_channel = cs.Channel(video_channel);
326 if (!vie_channel) {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000327 WEBRTC_TRACE(kTraceError, kTraceVideo,
328 ViEId(shared_data_->instance_id(), video_channel),
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000329 "%s: No channel %d", __FUNCTION__, video_channel);
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000330 shared_data_->SetLastError(kViECodecInvalidChannelId);
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000331 return -1;
332 }
333
mflodman@webrtc.orgf5e99db2012-06-27 09:49:37 +0000334 if (vie_channel->GetReceiveCodec(&video_codec) != 0) {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000335 shared_data_->SetLastError(kViECodecUnknownError);
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000336 return -1;
337 }
338 return 0;
339}
340
341int ViECodecImpl::GetCodecConfigParameters(
342 const int video_channel,
343 unsigned char config_parameters[kConfigParameterSize],
344 unsigned char& config_parameters_size) const {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000345 WEBRTC_TRACE(kTraceApiCall, kTraceVideo,
346 ViEId(shared_data_->instance_id(), video_channel),
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000347 "%s(video_channel: %d)", __FUNCTION__, video_channel);
348
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000349 ViEChannelManagerScoped cs(*(shared_data_->channel_manager()));
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000350 ViEEncoder* vie_encoder = cs.Encoder(video_channel);
351 if (!vie_encoder) {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000352 WEBRTC_TRACE(kTraceError, kTraceVideo,
353 ViEId(shared_data_->instance_id(), video_channel),
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000354 "%s: No encoder for channel %d", __FUNCTION__, video_channel);
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000355 shared_data_->SetLastError(kViECodecInvalidChannelId);
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000356 return -1;
357 }
358
359 if (vie_encoder->GetCodecConfigParameters(config_parameters,
360 config_parameters_size) != 0) {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000361 shared_data_->SetLastError(kViECodecUnknownError);
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000362 return -1;
363 }
364 return 0;
365}
366
367int ViECodecImpl::SetImageScaleStatus(const int video_channel,
368 const bool enable) {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000369 WEBRTC_TRACE(kTraceApiCall, kTraceVideo,
370 ViEId(shared_data_->instance_id(), video_channel),
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000371 "%s(video_channel: %d, enable: %d)", __FUNCTION__, video_channel,
372 enable);
373
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000374 ViEChannelManagerScoped cs(*(shared_data_->channel_manager()));
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000375 ViEEncoder* vie_encoder = cs.Encoder(video_channel);
376 if (!vie_encoder) {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000377 WEBRTC_TRACE(kTraceError, kTraceVideo,
378 ViEId(shared_data_->instance_id(), video_channel),
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000379 "%s: No channel %d", __FUNCTION__, video_channel);
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000380 shared_data_->SetLastError(kViECodecInvalidChannelId);
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000381 return -1;
382 }
383
384 if (vie_encoder->ScaleInputImage(enable) != 0) {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000385 shared_data_->SetLastError(kViECodecUnknownError);
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000386 return -1;
387 }
388 return 0;
389}
390
391int ViECodecImpl::GetSendCodecStastistics(const int video_channel,
392 unsigned int& key_frames,
393 unsigned int& delta_frames) const {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000394 WEBRTC_TRACE(kTraceApiCall, kTraceVideo,
395 ViEId(shared_data_->instance_id(), video_channel),
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000396 "%s(video_channel %d)", __FUNCTION__, video_channel);
397
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000398 ViEChannelManagerScoped cs(*(shared_data_->channel_manager()));
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000399 ViEEncoder* vie_encoder = cs.Encoder(video_channel);
400 if (!vie_encoder) {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000401 WEBRTC_TRACE(kTraceError, kTraceVideo,
402 ViEId(shared_data_->instance_id(), video_channel),
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000403 "%s: No send codec for channel %d", __FUNCTION__,
404 video_channel);
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000405 shared_data_->SetLastError(kViECodecInvalidChannelId);
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000406 return -1;
407 }
408
mflodman@webrtc.orgf5e99db2012-06-27 09:49:37 +0000409 if (vie_encoder->SendCodecStatistics(&key_frames, &delta_frames) != 0) {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000410 shared_data_->SetLastError(kViECodecUnknownError);
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000411 return -1;
412 }
413 return 0;
414}
415
416int ViECodecImpl::GetReceiveCodecStastistics(const int video_channel,
417 unsigned int& key_frames,
418 unsigned int& delta_frames) const {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000419 WEBRTC_TRACE(kTraceApiCall, kTraceVideo,
420 ViEId(shared_data_->instance_id(), video_channel),
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000421 "%s(video_channel: %d, codec_type: %d)", __FUNCTION__,
422 video_channel);
423
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000424 ViEChannelManagerScoped cs(*(shared_data_->channel_manager()));
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000425 ViEChannel* vie_channel = cs.Channel(video_channel);
426 if (!vie_channel) {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000427 WEBRTC_TRACE(kTraceError, kTraceVideo,
428 ViEId(shared_data_->instance_id(), video_channel),
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000429 "%s: No channel %d", __FUNCTION__, video_channel);
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000430 shared_data_->SetLastError(kViECodecInvalidChannelId);
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000431 return -1;
432 }
mflodman@webrtc.orgf5e99db2012-06-27 09:49:37 +0000433 if (vie_channel->ReceiveCodecStatistics(&key_frames, &delta_frames) != 0) {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000434 shared_data_->SetLastError(kViECodecUnknownError);
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000435 return -1;
436 }
437 return 0;
438}
439
stefan@webrtc.org439be292012-02-16 14:45:37 +0000440int ViECodecImpl::GetCodecTargetBitrate(const int video_channel,
441 unsigned int* bitrate) const {
442 WEBRTC_TRACE(kTraceApiCall, kTraceVideo,
443 ViEId(shared_data_->instance_id(), video_channel),
444 "%s(video_channel: %d, codec_type: %d)", __FUNCTION__,
445 video_channel);
446
447 ViEChannelManagerScoped cs(*(shared_data_->channel_manager()));
448 ViEEncoder* vie_encoder = cs.Encoder(video_channel);
449 if (!vie_encoder) {
450 WEBRTC_TRACE(kTraceError, kTraceVideo,
451 ViEId(shared_data_->instance_id(), video_channel),
452 "%s: No send codec for channel %d", __FUNCTION__,
453 video_channel);
454 shared_data_->SetLastError(kViECodecInvalidChannelId);
455 return -1;
456 }
457 return vie_encoder->CodecTargetBitrate(static_cast<WebRtc_UWord32*>(bitrate));
458}
459
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000460unsigned int ViECodecImpl::GetDiscardedPackets(const int video_channel) const {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000461 WEBRTC_TRACE(kTraceApiCall, kTraceVideo,
462 ViEId(shared_data_->instance_id(), video_channel),
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000463 "%s(video_channel: %d, codec_type: %d)", __FUNCTION__,
464 video_channel);
465
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000466 ViEChannelManagerScoped cs(*(shared_data_->channel_manager()));
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000467 ViEChannel* vie_channel = cs.Channel(video_channel);
468 if (!vie_channel) {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000469 WEBRTC_TRACE(kTraceError, kTraceVideo,
470 ViEId(shared_data_->instance_id(), video_channel),
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000471 "%s: No channel %d", __FUNCTION__, video_channel);
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000472 shared_data_->SetLastError(kViECodecInvalidChannelId);
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000473 return -1;
474 }
475 return vie_channel->DiscardedPackets();
476}
477
478int ViECodecImpl::SetKeyFrameRequestCallbackStatus(const int video_channel,
479 const bool enable) {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000480 WEBRTC_TRACE(kTraceApiCall, kTraceVideo,
481 ViEId(shared_data_->instance_id(), video_channel),
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000482 "%s(video_channel: %d)", __FUNCTION__, video_channel);
483
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000484 ViEChannelManagerScoped cs(*(shared_data_->channel_manager()));
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000485 ViEChannel* vie_channel = cs.Channel(video_channel);
486 if (!vie_channel) {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000487 WEBRTC_TRACE(kTraceError, kTraceVideo,
488 ViEId(shared_data_->instance_id(), video_channel),
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000489 "%s: No channel %d", __FUNCTION__, video_channel);
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000490 shared_data_->SetLastError(kViECodecInvalidChannelId);
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000491 return -1;
492 }
493 if (vie_channel->EnableKeyFrameRequestCallback(enable) != 0) {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000494 shared_data_->SetLastError(kViECodecUnknownError);
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000495 return -1;
496 }
497 return 0;
498}
499
500int ViECodecImpl::SetSignalKeyPacketLossStatus(const int video_channel,
niklase@google.com470e71d2011-07-07 08:21:25 +0000501 const bool enable,
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000502 const bool only_key_frames) {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000503 WEBRTC_TRACE(kTraceApiCall, kTraceVideo,
504 ViEId(shared_data_->instance_id(), video_channel),
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000505 "%s(video_channel: %d, enable: %d, only_key_frames: %d)",
506 __FUNCTION__, video_channel, enable);
niklase@google.com470e71d2011-07-07 08:21:25 +0000507
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000508 ViEChannelManagerScoped cs(*(shared_data_->channel_manager()));
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000509 ViEChannel* vie_channel = cs.Channel(video_channel);
510 if (!vie_channel) {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000511 WEBRTC_TRACE(kTraceError, kTraceVideo,
512 ViEId(shared_data_->instance_id(), video_channel),
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000513 "%s: No channel %d", __FUNCTION__, video_channel);
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000514 shared_data_->SetLastError(kViECodecInvalidChannelId);
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000515 return -1;
516 }
517 if (vie_channel->SetSignalPacketLossStatus(enable, only_key_frames) != 0) {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000518 shared_data_->SetLastError(kViECodecUnknownError);
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000519 return -1;
520 }
521 return 0;
niklase@google.com470e71d2011-07-07 08:21:25 +0000522}
523
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000524int ViECodecImpl::RegisterEncoderObserver(const int video_channel,
525 ViEEncoderObserver& observer) {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000526 WEBRTC_TRACE(kTraceApiCall, kTraceVideo, ViEId(shared_data_->instance_id()),
527 "%s", __FUNCTION__);
niklase@google.com470e71d2011-07-07 08:21:25 +0000528
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000529 ViEChannelManagerScoped cs(*(shared_data_->channel_manager()));
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000530 ViEEncoder* vie_encoder = cs.Encoder(video_channel);
531 if (!vie_encoder) {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000532 WEBRTC_TRACE(kTraceError, kTraceVideo,
533 ViEId(shared_data_->instance_id(), video_channel),
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000534 "%s: No encoder for channel %d", __FUNCTION__, video_channel);
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000535 shared_data_->SetLastError(kViECodecInvalidChannelId);
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000536 return -1;
537 }
538 if (vie_encoder->RegisterCodecObserver(&observer) != 0) {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000539 WEBRTC_TRACE(kTraceError, kTraceVideo,
540 ViEId(shared_data_->instance_id(), video_channel),
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000541 "%s: Could not register codec observer at channel",
542 __FUNCTION__);
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000543 shared_data_->SetLastError(kViECodecObserverAlreadyRegistered);
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000544 return -1;
545 }
546 return 0;
niklase@google.com470e71d2011-07-07 08:21:25 +0000547}
548
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000549int ViECodecImpl::DeregisterEncoderObserver(const int video_channel) {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000550 WEBRTC_TRACE(kTraceApiCall, kTraceVideo, ViEId(shared_data_->instance_id()),
551 "%s", __FUNCTION__);
niklase@google.com470e71d2011-07-07 08:21:25 +0000552
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000553 ViEChannelManagerScoped cs(*(shared_data_->channel_manager()));
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000554 ViEEncoder* vie_encoder = cs.Encoder(video_channel);
555 if (!vie_encoder) {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000556 WEBRTC_TRACE(kTraceError, kTraceVideo,
557 ViEId(shared_data_->instance_id(), video_channel),
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000558 "%s: No encoder for channel %d", __FUNCTION__, video_channel);
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000559 shared_data_->SetLastError(kViECodecInvalidChannelId);
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000560 return -1;
561 }
562 if (vie_encoder->RegisterCodecObserver(NULL) != 0) {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000563 shared_data_->SetLastError(kViECodecObserverNotRegistered);
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000564 return -1;
565 }
566 return 0;
niklase@google.com470e71d2011-07-07 08:21:25 +0000567}
568
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000569int ViECodecImpl::RegisterDecoderObserver(const int video_channel,
570 ViEDecoderObserver& observer) {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000571 WEBRTC_TRACE(kTraceApiCall, kTraceVideo, ViEId(shared_data_->instance_id()),
572 "%s", __FUNCTION__);
niklase@google.com470e71d2011-07-07 08:21:25 +0000573
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000574 ViEChannelManagerScoped cs(*(shared_data_->channel_manager()));
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000575 ViEChannel* vie_channel = cs.Channel(video_channel);
576 if (!vie_channel) {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000577 WEBRTC_TRACE(kTraceError, kTraceVideo,
578 ViEId(shared_data_->instance_id(), video_channel),
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000579 "%s: No channel %d", __FUNCTION__, video_channel);
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000580 shared_data_->SetLastError(kViECodecInvalidChannelId);
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000581 return -1;
582 }
583 if (vie_channel->RegisterCodecObserver(&observer) != 0) {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000584 WEBRTC_TRACE(kTraceError, kTraceVideo,
585 ViEId(shared_data_->instance_id(), video_channel),
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000586 "%s: Could not register codec observer at channel",
587 __FUNCTION__);
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000588 shared_data_->SetLastError(kViECodecObserverAlreadyRegistered);
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000589 return -1;
590 }
591 return 0;
niklase@google.com470e71d2011-07-07 08:21:25 +0000592}
593
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000594int ViECodecImpl::DeregisterDecoderObserver(const int video_channel) {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000595 WEBRTC_TRACE(kTraceApiCall, kTraceVideo,
596 ViEId(shared_data_->instance_id()), "%s",
niklase@google.com470e71d2011-07-07 08:21:25 +0000597 __FUNCTION__);
598
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000599 ViEChannelManagerScoped cs(*(shared_data_->channel_manager()));
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000600 ViEChannel* vie_channel = cs.Channel(video_channel);
601 if (!vie_channel) {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000602 WEBRTC_TRACE(kTraceError, kTraceVideo,
603 ViEId(shared_data_->instance_id(), video_channel),
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000604 "%s: No channel %d", __FUNCTION__, video_channel);
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000605 shared_data_->SetLastError(kViECodecInvalidChannelId);
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000606 return -1;
607 }
608 if (vie_channel->RegisterCodecObserver(NULL) != 0) {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000609 shared_data_->SetLastError(kViECodecObserverNotRegistered);
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000610 return -1;
611 }
612 return 0;
niklase@google.com470e71d2011-07-07 08:21:25 +0000613}
614
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000615int ViECodecImpl::SendKeyFrame(const int video_channel) {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000616 WEBRTC_TRACE(kTraceApiCall, kTraceVideo, ViEId(shared_data_->instance_id()),
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000617 "%s(video_channel: %d)", __FUNCTION__, video_channel);
niklase@google.com470e71d2011-07-07 08:21:25 +0000618
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000619 ViEChannelManagerScoped cs(*(shared_data_->channel_manager()));
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000620 ViEEncoder* vie_encoder = cs.Encoder(video_channel);
621 if (!vie_encoder) {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000622 WEBRTC_TRACE(kTraceError, kTraceVideo,
623 ViEId(shared_data_->instance_id(), video_channel),
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000624 "%s: No channel %d", __FUNCTION__, video_channel);
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000625 shared_data_->SetLastError(kViECodecInvalidChannelId);
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000626 return -1;
627 }
628 if (vie_encoder->SendKeyFrame() != 0) {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000629 shared_data_->SetLastError(kViECodecUnknownError);
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000630 return -1;
631 }
632 return 0;
niklase@google.com470e71d2011-07-07 08:21:25 +0000633}
634
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000635int ViECodecImpl::WaitForFirstKeyFrame(const int video_channel,
636 const bool wait) {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000637 WEBRTC_TRACE(kTraceApiCall, kTraceVideo,
638 ViEId(shared_data_->instance_id()),
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000639 "%s(video_channel: %d, wait: %d)", __FUNCTION__, video_channel,
niklase@google.com470e71d2011-07-07 08:21:25 +0000640 wait);
641
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000642 ViEChannelManagerScoped cs(*(shared_data_->channel_manager()));
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000643 ViEChannel* vie_channel = cs.Channel(video_channel);
644 if (!vie_channel) {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000645 WEBRTC_TRACE(kTraceError, kTraceVideo,
646 ViEId(shared_data_->instance_id(), video_channel),
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000647 "%s: No channel %d", __FUNCTION__, video_channel);
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000648 shared_data_->SetLastError(kViECodecInvalidChannelId);
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000649 return -1;
650 }
651 if (vie_channel->WaitForKeyFrame(wait) != 0) {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000652 shared_data_->SetLastError(kViECodecUnknownError);
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000653 return -1;
654 }
655 return 0;
niklase@google.com470e71d2011-07-07 08:21:25 +0000656}
657
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000658bool ViECodecImpl::CodecValid(const VideoCodec& video_codec) {
659 // Check pl_name matches codec_type.
660 if (video_codec.codecType == kVideoCodecRED) {
niklase@google.com470e71d2011-07-07 08:21:25 +0000661#if defined(WIN32)
mflodman@webrtc.org1fe2ada2011-12-21 12:23:15 +0000662 if (_strnicmp(video_codec.plName, "red", 3) == 0) {
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000663#else
664 if (strncasecmp(video_codec.plName, "red", 3) == 0) {
niklase@google.com470e71d2011-07-07 08:21:25 +0000665#endif
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000666 // We only care about the type and name for red.
667 return true;
niklase@google.com470e71d2011-07-07 08:21:25 +0000668 }
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000669 WEBRTC_TRACE(kTraceError, kTraceVideo, -1,
670 "Codec type doesn't match pl_name", video_codec.plType);
671 return false;
672 } else if (video_codec.codecType == kVideoCodecULPFEC) {
niklase@google.com470e71d2011-07-07 08:21:25 +0000673#if defined(WIN32)
mflodman@webrtc.org1fe2ada2011-12-21 12:23:15 +0000674 if (_strnicmp(video_codec.plName, "ULPFEC", 6) == 0) {
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000675#else
676 if (strncasecmp(video_codec.plName, "ULPFEC", 6) == 0) {
niklase@google.com470e71d2011-07-07 08:21:25 +0000677#endif
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000678 // We only care about the type and name for ULPFEC.
679 return true;
niklase@google.com470e71d2011-07-07 08:21:25 +0000680 }
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000681 WEBRTC_TRACE(kTraceError, kTraceVideo, -1,
682 "Codec type doesn't match pl_name", video_codec.plType);
683 return false;
pwestin@webrtc.org56210572012-01-17 12:45:47 +0000684 } else if ((video_codec.codecType == kVideoCodecVP8 &&
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000685 strncmp(video_codec.plName, "VP8", 4) == 0) ||
686 (video_codec.codecType == kVideoCodecI420 &&
pwestin@webrtc.org56210572012-01-17 12:45:47 +0000687 strncmp(video_codec.plName, "I420", 4) == 0)) {
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000688 // OK.
689 } else {
690 WEBRTC_TRACE(kTraceError, kTraceVideo, -1,
691 "Codec type doesn't match pl_name", video_codec.plType);
692 return false;
693 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000694
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000695 if (video_codec.plType == 0 && video_codec.plType > 127) {
696 WEBRTC_TRACE(kTraceError, kTraceVideo, -1,
697 "Invalid codec payload type: %d", video_codec.plType);
698 return false;
699 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000700
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000701 if (video_codec.width > kViEMaxCodecWidth ||
702 video_codec.height > kViEMaxCodecHeight) {
703 WEBRTC_TRACE(kTraceError, kTraceVideo, -1, "Invalid codec size: %u x %u",
704 video_codec.width, video_codec.height);
705 return false;
706 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000707
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000708 if (video_codec.startBitrate < kViEMinCodecBitrate) {
709 WEBRTC_TRACE(kTraceError, kTraceVideo, -1, "Invalid start_bitrate: %u",
710 video_codec.startBitrate);
711 return false;
712 }
713 if (video_codec.minBitrate < kViEMinCodecBitrate) {
714 WEBRTC_TRACE(kTraceError, kTraceVideo, -1, "Invalid min_bitrate: %u",
715 video_codec.minBitrate);
716 return false;
717 }
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000718 return true;
niklase@google.com470e71d2011-07-07 08:21:25 +0000719}
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000720
721} // namespace webrtc