blob: 27559d5f56822d700b24c5f4a5d7b2c06e8d5e09 [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"
17#include "system_wrappers/interface/trace.h"
mflodman@webrtc.orga4863db2011-12-22 08:51:52 +000018#include "video_engine/include/vie_errors.h"
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +000019#include "video_engine/vie_capturer.h"
20#include "video_engine/vie_channel.h"
21#include "video_engine/vie_channel_manager.h"
22#include "video_engine/vie_defines.h"
23#include "video_engine/vie_encoder.h"
24#include "video_engine/vie_impl.h"
25#include "video_engine/vie_input_manager.h"
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +000026#include "video_engine/vie_shared_data.h"
niklase@google.com470e71d2011-07-07 08:21:25 +000027
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +000028namespace webrtc {
niklase@google.com470e71d2011-07-07 08:21:25 +000029
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +000030ViECodec* ViECodec::GetInterface(VideoEngine* video_engine) {
niklase@google.com470e71d2011-07-07 08:21:25 +000031#ifdef WEBRTC_VIDEO_ENGINE_CODEC_API
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +000032 if (!video_engine) {
niklase@google.com470e71d2011-07-07 08:21:25 +000033 return NULL;
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +000034 }
35 VideoEngineImpl* vie_impl = reinterpret_cast<VideoEngineImpl*>(video_engine);
36 ViECodecImpl* vie_codec_impl = vie_impl;
37 // Increase ref count.
38 (*vie_codec_impl)++;
39 return vie_codec_impl;
40#else
41 return NULL;
niklase@google.com470e71d2011-07-07 08:21:25 +000042#endif
43}
44
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +000045int ViECodecImpl::Release() {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +000046 WEBRTC_TRACE(kTraceApiCall, kTraceVideo, shared_data_->instance_id(),
niklase@google.com470e71d2011-07-07 08:21:25 +000047 "ViECodecImpl::Release()");
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +000048 // Decrease ref count.
49 (*this)--;
niklase@google.com470e71d2011-07-07 08:21:25 +000050
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +000051 WebRtc_Word32 ref_count = GetCount();
52 if (ref_count < 0) {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +000053 WEBRTC_TRACE(kTraceWarning, kTraceVideo, shared_data_->instance_id(),
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +000054 "ViECodec released too many times");
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +000055 shared_data_->SetLastError(kViEAPIDoesNotExist);
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +000056 return -1;
57 }
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +000058 WEBRTC_TRACE(kTraceInfo, kTraceVideo, shared_data_->instance_id(),
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +000059 "ViECodec reference count: %d", ref_count);
60 return ref_count;
niklase@google.com470e71d2011-07-07 08:21:25 +000061}
62
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +000063ViECodecImpl::ViECodecImpl(ViESharedData* shared_data)
64 : shared_data_(shared_data) {
65 WEBRTC_TRACE(kTraceMemory, kTraceVideo, shared_data_->instance_id(),
niklase@google.com470e71d2011-07-07 08:21:25 +000066 "ViECodecImpl::ViECodecImpl() Ctor");
67}
68
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +000069ViECodecImpl::~ViECodecImpl() {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +000070 WEBRTC_TRACE(kTraceMemory, kTraceVideo, shared_data_->instance_id(),
niklase@google.com470e71d2011-07-07 08:21:25 +000071 "ViECodecImpl::~ViECodecImpl() Dtor");
72}
73
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +000074int ViECodecImpl::NumberOfCodecs() const {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +000075 WEBRTC_TRACE(kTraceApiCall, kTraceVideo, ViEId(shared_data_->instance_id()),
76 "%s", __FUNCTION__);
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +000077 // +2 because of FEC(RED and ULPFEC)
78 return static_cast<int>((VideoCodingModule::NumberOfCodecs() + 2));
niklase@google.com470e71d2011-07-07 08:21:25 +000079}
80
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +000081int ViECodecImpl::GetCodec(const unsigned char list_number,
82 VideoCodec& video_codec) const {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +000083 WEBRTC_TRACE(kTraceApiCall, kTraceVideo, ViEId(shared_data_->instance_id()),
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +000084 "%s(list_number: %d, codec_type: %d)", __FUNCTION__,
85 list_number, video_codec.codecType);
86 if (list_number == VideoCodingModule::NumberOfCodecs()) {
87 memset(&video_codec, 0, sizeof(VideoCodec));
mflodman@webrtc.org9ba151b2012-06-21 10:02:13 +000088 strncpy(video_codec.plName, "red", 3);
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +000089 video_codec.codecType = kVideoCodecRED;
90 video_codec.plType = VCM_RED_PAYLOAD_TYPE;
91 } else if (list_number == VideoCodingModule::NumberOfCodecs() + 1) {
92 memset(&video_codec, 0, sizeof(VideoCodec));
mflodman@webrtc.org9ba151b2012-06-21 10:02:13 +000093 strncpy(video_codec.plName, "ulpfec", 6);
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +000094 video_codec.codecType = kVideoCodecULPFEC;
95 video_codec.plType = VCM_ULPFEC_PAYLOAD_TYPE;
96 } else if (VideoCodingModule::Codec(list_number, &video_codec) != VCM_OK) {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +000097 WEBRTC_TRACE(kTraceApiCall, kTraceVideo, ViEId(shared_data_->instance_id()),
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +000098 "%s: Could not get codec for list_number: %u", __FUNCTION__,
99 list_number);
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000100 shared_data_->SetLastError(kViECodecInvalidArgument);
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000101 return -1;
102 }
103 return 0;
niklase@google.com470e71d2011-07-07 08:21:25 +0000104}
105
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000106int ViECodecImpl::SetSendCodec(const int video_channel,
107 const VideoCodec& video_codec) {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000108 WEBRTC_TRACE(kTraceApiCall, kTraceVideo,
mflodman@webrtc.org9ba151b2012-06-21 10:02:13 +0000109 ViEId(shared_data_->instance_id(), video_channel),
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000110 "%s(video_channel: %d, codec_type: %d)", __FUNCTION__,
111 video_channel, video_codec.codecType);
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000112 WEBRTC_TRACE(kTraceInfo, kTraceVideo,
113 ViEId(shared_data_->instance_id(), video_channel),
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000114 "%s: codec: %d, pl_type: %d, width: %d, height: %d, bitrate: %d"
mflodman@webrtc.org9c0aedc2012-01-03 13:46:49 +0000115 "maxBr: %d, min_br: %d, frame_rate: %d, qpMax: %u,"
116 "numberOfSimulcastStreams: %u )", __FUNCTION__,
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000117 video_codec.codecType, video_codec.plType, video_codec.width,
118 video_codec.height, video_codec.startBitrate,
119 video_codec.maxBitrate, video_codec.minBitrate,
mflodman@webrtc.org9c0aedc2012-01-03 13:46:49 +0000120 video_codec.maxFramerate, video_codec.qpMax,
121 video_codec.numberOfSimulcastStreams);
122 if (video_codec.codecType == kVideoCodecVP8) {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000123 WEBRTC_TRACE(kTraceInfo, kTraceVideo,
124 ViEId(shared_data_->instance_id(), video_channel),
mflodman@webrtc.org9c0aedc2012-01-03 13:46:49 +0000125 "pictureLossIndicationOn: %d, feedbackModeOn: %d, "
126 "complexity: %d, resilience: %d, numberOfTemporalLayers: %u",
127 video_codec.codecSpecific.VP8.pictureLossIndicationOn,
128 video_codec.codecSpecific.VP8.feedbackModeOn,
129 video_codec.codecSpecific.VP8.complexity,
130 video_codec.codecSpecific.VP8.resilience,
131 video_codec.codecSpecific.VP8.numberOfTemporalLayers);
132 }
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000133 if (!CodecValid(video_codec)) {
134 // Error logged.
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000135 shared_data_->SetLastError(kViECodecInvalidCodec);
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000136 return -1;
137 }
stefan@webrtc.org791eec72011-10-11 07:53:43 +0000138
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000139 ViEChannelManagerScoped cs(*(shared_data_->channel_manager()));
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000140 ViEChannel* vie_channel = cs.Channel(video_channel);
141 if (!vie_channel) {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000142 WEBRTC_TRACE(kTraceError, kTraceVideo,
143 ViEId(shared_data_->instance_id(), video_channel),
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000144 "%s: No channel %d", __FUNCTION__, video_channel);
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000145 shared_data_->SetLastError(kViECodecInvalidChannelId);
stefan@webrtc.org791eec72011-10-11 07:53:43 +0000146 return -1;
147 }
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000148
mflodman@webrtc.org9ec883e2012-03-05 17:12:41 +0000149 ViEEncoder* vie_encoder = cs.Encoder(video_channel);
150 assert(vie_encoder);
151 if (vie_encoder->Owner() != video_channel) {
152 WEBRTC_TRACE(kTraceError, kTraceVideo,
153 ViEId(shared_data_->instance_id(), video_channel),
154 "%s: Receive only channel %d", __FUNCTION__, video_channel);
155 shared_data_->SetLastError(kViECodecReceiveOnlyChannel);
156 return -1;
157 }
158
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000159 // Set a max_bitrate if the user hasn't set one.
160 VideoCodec video_codec_internal;
161 memcpy(&video_codec_internal, &video_codec, sizeof(VideoCodec));
162 if (video_codec_internal.maxBitrate == 0) {
163 // Max is one bit per pixel.
164 video_codec_internal.maxBitrate = (video_codec_internal.width *
165 video_codec_internal.height *
166 video_codec_internal.maxFramerate)
167 / 1000;
168 if (video_codec_internal.startBitrate > video_codec_internal.maxBitrate) {
169 // Don't limit the set start bitrate.
170 video_codec_internal.maxBitrate = video_codec_internal.startBitrate;
171 }
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000172 WEBRTC_TRACE(kTraceInfo, kTraceVideo,
173 ViEId(shared_data_->instance_id(), video_channel),
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000174 "%s: New max bitrate set to %d kbps", __FUNCTION__,
175 video_codec_internal.maxBitrate);
176 }
177
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000178 VideoCodec encoder;
mflodman@webrtc.orgf5e99db2012-06-27 09:49:37 +0000179 vie_encoder->GetEncoder(&encoder);
mflodman@webrtc.org9ec883e2012-03-05 17:12:41 +0000180
mflodman@webrtc.org9c0aedc2012-01-03 13:46:49 +0000181 // Make sure to generate a new SSRC if the codec type and/or resolution has
182 // changed. This won't have any effect if the user has set an SSRC.
183 bool new_rtp_stream = false;
stefan@webrtc.org4e8eaba2012-08-20 14:29:52 +0000184 if (encoder.codecType != video_codec_internal.codecType) {
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000185 new_rtp_stream = true;
186 }
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000187
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000188 ViEInputManagerScoped is(*(shared_data_->input_manager()));
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000189 ViEFrameProviderBase* frame_provider = NULL;
190
191 // Stop the media flow while reconfiguring.
192 vie_encoder->Pause();
193
194 // Check if we have a frame provider that is a camera and can provide this
195 // codec for us.
196 bool use_capture_device_as_encoder = false;
197 frame_provider = is.FrameProvider(vie_encoder);
198 if (frame_provider) {
199 if (frame_provider->Id() >= kViECaptureIdBase &&
200 frame_provider->Id() <= kViECaptureIdMax) {
201 ViECapturer* vie_capture = static_cast<ViECapturer*>(frame_provider);
202 // Try to get preencoded. Nothing to do if it is not supported.
203 if (vie_capture && vie_capture->PreEncodeToViEEncoder(
204 video_codec_internal,
205 *vie_encoder,
206 video_channel) == 0) {
207 use_capture_device_as_encoder = true;
208 }
209 }
210 }
211
212 // Update the encoder settings if we are not using a capture device capable
213 // of this codec.
214 if (!use_capture_device_as_encoder &&
215 vie_encoder->SetEncoder(video_codec_internal) != 0) {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000216 WEBRTC_TRACE(kTraceError, kTraceVideo,
217 ViEId(shared_data_->instance_id(), video_channel),
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000218 "%s: Could not change encoder for channel %d", __FUNCTION__,
219 video_channel);
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000220 shared_data_->SetLastError(kViECodecUnknownError);
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000221 return -1;
222 }
223
mflodman@webrtc.org9c0aedc2012-01-03 13:46:49 +0000224 // Give the channel(s) the new information.
225 ChannelList channels;
226 cs.ChannelsUsingViEEncoder(video_channel, &channels);
227 for (ChannelList::iterator it = channels.begin(); it != channels.end();
228 ++it) {
229 bool ret = true;
230 if ((*it)->SetSendCodec(video_codec_internal, new_rtp_stream) != 0) {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000231 WEBRTC_TRACE(kTraceError, kTraceVideo,
232 ViEId(shared_data_->instance_id(), video_channel),
mflodman@webrtc.org9c0aedc2012-01-03 13:46:49 +0000233 "%s: Could not set send codec for channel %d", __FUNCTION__,
234 video_channel);
235 ret = false;
236 }
237 if (!ret) {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000238 shared_data_->SetLastError(kViECodecUnknownError);
mflodman@webrtc.org9c0aedc2012-01-03 13:46:49 +0000239 return -1;
240 }
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000241 }
242
mflodman@webrtc.orgd6ec3862012-10-25 11:30:29 +0000243 // TODO(mflodman) Break out this part in GetLocalSsrcList().
244 // Update all SSRCs to ViEEncoder.
245 std::list<unsigned int> ssrcs;
246 if (video_codec_internal.numberOfSimulcastStreams == 0) {
247 unsigned int ssrc = 0;
248 if (vie_channel->GetLocalSSRC(0, &ssrc) != 0) {
249 WEBRTC_TRACE(kTraceError, kTraceVideo,
250 ViEId(shared_data_->instance_id(), video_channel),
251 "%s: Could not get ssrc", __FUNCTION__);
252 }
253 ssrcs.push_back(ssrc);
254 } else {
255 for (int idx = 0; idx < video_codec_internal.numberOfSimulcastStreams;
256 ++idx) {
257 unsigned int ssrc = 0;
258 if (vie_channel->GetLocalSSRC(idx, &ssrc) != 0) {
259 WEBRTC_TRACE(kTraceError, kTraceVideo,
260 ViEId(shared_data_->instance_id(), video_channel),
261 "%s: Could not get ssrc for idx %d", __FUNCTION__, idx);
262 }
263 ssrcs.push_back(ssrc);
264 }
265 }
266 vie_encoder->SetSsrcs(ssrcs);
267 shared_data_->channel_manager()->UpdateSsrcs(video_channel, ssrcs);
268
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000269 // Update the protection mode, we might be switching NACK/FEC.
270 vie_encoder->UpdateProtectionMethod();
271
272 // Get new best format for frame provider.
273 if (frame_provider) {
274 frame_provider->FrameCallbackChanged();
275 }
276 // Restart the media flow
277 if (new_rtp_stream) {
278 // Stream settings changed, make sure we get a key frame.
279 vie_encoder->SendKeyFrame();
280 }
281 vie_encoder->Restart();
282 return 0;
stefan@webrtc.org791eec72011-10-11 07:53:43 +0000283}
284
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000285int ViECodecImpl::GetSendCodec(const int video_channel,
286 VideoCodec& video_codec) const {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000287 WEBRTC_TRACE(kTraceApiCall, kTraceVideo,
288 ViEId(shared_data_->instance_id(), video_channel),
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000289 "%s(video_channel: %d)", __FUNCTION__, video_channel);
niklase@google.com470e71d2011-07-07 08:21:25 +0000290
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000291 ViEChannelManagerScoped cs(*(shared_data_->channel_manager()));
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000292 ViEEncoder* vie_encoder = cs.Encoder(video_channel);
293 if (!vie_encoder) {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000294 WEBRTC_TRACE(kTraceError, kTraceVideo,
295 ViEId(shared_data_->instance_id(), video_channel),
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000296 "%s: No encoder for channel %d", __FUNCTION__, video_channel);
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000297 shared_data_->SetLastError(kViECodecInvalidChannelId);
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000298 return -1;
299 }
mflodman@webrtc.orgf5e99db2012-06-27 09:49:37 +0000300 return vie_encoder->GetEncoder(&video_codec);
niklase@google.com470e71d2011-07-07 08:21:25 +0000301}
302
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000303int ViECodecImpl::SetReceiveCodec(const int video_channel,
304 const VideoCodec& video_codec) {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000305 WEBRTC_TRACE(kTraceApiCall, kTraceVideo,
306 ViEId(shared_data_->instance_id(), video_channel),
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000307 "%s(video_channel: %d, codec_type: %d)", __FUNCTION__,
308 video_channel, video_codec.codecType);
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000309 WEBRTC_TRACE(kTraceInfo, kTraceVideo,
310 ViEId(shared_data_->instance_id(), video_channel),
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000311 "%s: codec: %d, pl_type: %d, width: %d, height: %d, bitrate: %d,"
312 "maxBr: %d, min_br: %d, frame_rate: %d", __FUNCTION__,
313 video_codec.codecType, video_codec.plType, video_codec.width,
314 video_codec.height, video_codec.startBitrate,
315 video_codec.maxBitrate, video_codec.minBitrate,
316 video_codec.maxFramerate);
niklase@google.com470e71d2011-07-07 08:21:25 +0000317
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000318 if (CodecValid(video_codec) == false) {
319 // Error logged.
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000320 shared_data_->SetLastError(kViECodecInvalidCodec);
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000321 return -1;
322 }
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
334 if (vie_channel->SetReceiveCodec(video_codec) != 0) {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000335 WEBRTC_TRACE(kTraceError, kTraceVideo,
336 ViEId(shared_data_->instance_id(), video_channel),
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000337 "%s: Could not set receive codec for channel %d",
338 __FUNCTION__, video_channel);
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000339 shared_data_->SetLastError(kViECodecUnknownError);
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000340 return -1;
341 }
342 return 0;
343}
344
345int ViECodecImpl::GetReceiveCodec(const int video_channel,
346 VideoCodec& video_codec) const {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000347 WEBRTC_TRACE(kTraceApiCall, kTraceVideo,
348 ViEId(shared_data_->instance_id(), video_channel),
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000349 "%s(video_channel: %d, codec_type: %d)", __FUNCTION__,
350 video_channel, video_codec.codecType);
351
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000352 ViEChannelManagerScoped cs(*(shared_data_->channel_manager()));
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000353 ViEChannel* vie_channel = cs.Channel(video_channel);
354 if (!vie_channel) {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000355 WEBRTC_TRACE(kTraceError, kTraceVideo,
356 ViEId(shared_data_->instance_id(), video_channel),
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000357 "%s: No channel %d", __FUNCTION__, video_channel);
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000358 shared_data_->SetLastError(kViECodecInvalidChannelId);
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000359 return -1;
360 }
361
mflodman@webrtc.orgf5e99db2012-06-27 09:49:37 +0000362 if (vie_channel->GetReceiveCodec(&video_codec) != 0) {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000363 shared_data_->SetLastError(kViECodecUnknownError);
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000364 return -1;
365 }
366 return 0;
367}
368
369int ViECodecImpl::GetCodecConfigParameters(
370 const int video_channel,
371 unsigned char config_parameters[kConfigParameterSize],
372 unsigned char& config_parameters_size) const {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000373 WEBRTC_TRACE(kTraceApiCall, kTraceVideo,
374 ViEId(shared_data_->instance_id(), video_channel),
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000375 "%s(video_channel: %d)", __FUNCTION__, video_channel);
376
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000377 ViEChannelManagerScoped cs(*(shared_data_->channel_manager()));
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000378 ViEEncoder* vie_encoder = cs.Encoder(video_channel);
379 if (!vie_encoder) {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000380 WEBRTC_TRACE(kTraceError, kTraceVideo,
381 ViEId(shared_data_->instance_id(), video_channel),
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000382 "%s: No encoder for channel %d", __FUNCTION__, video_channel);
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000383 shared_data_->SetLastError(kViECodecInvalidChannelId);
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000384 return -1;
385 }
386
387 if (vie_encoder->GetCodecConfigParameters(config_parameters,
388 config_parameters_size) != 0) {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000389 shared_data_->SetLastError(kViECodecUnknownError);
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000390 return -1;
391 }
392 return 0;
393}
394
395int ViECodecImpl::SetImageScaleStatus(const int video_channel,
396 const bool enable) {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000397 WEBRTC_TRACE(kTraceApiCall, kTraceVideo,
398 ViEId(shared_data_->instance_id(), video_channel),
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000399 "%s(video_channel: %d, enable: %d)", __FUNCTION__, video_channel,
400 enable);
401
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000402 ViEChannelManagerScoped cs(*(shared_data_->channel_manager()));
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000403 ViEEncoder* vie_encoder = cs.Encoder(video_channel);
404 if (!vie_encoder) {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000405 WEBRTC_TRACE(kTraceError, kTraceVideo,
406 ViEId(shared_data_->instance_id(), video_channel),
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000407 "%s: No channel %d", __FUNCTION__, video_channel);
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000408 shared_data_->SetLastError(kViECodecInvalidChannelId);
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000409 return -1;
410 }
411
412 if (vie_encoder->ScaleInputImage(enable) != 0) {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000413 shared_data_->SetLastError(kViECodecUnknownError);
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000414 return -1;
415 }
416 return 0;
417}
418
419int ViECodecImpl::GetSendCodecStastistics(const int video_channel,
420 unsigned int& key_frames,
421 unsigned int& delta_frames) const {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000422 WEBRTC_TRACE(kTraceApiCall, kTraceVideo,
423 ViEId(shared_data_->instance_id(), video_channel),
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000424 "%s(video_channel %d)", __FUNCTION__, video_channel);
425
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000426 ViEChannelManagerScoped cs(*(shared_data_->channel_manager()));
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000427 ViEEncoder* vie_encoder = cs.Encoder(video_channel);
428 if (!vie_encoder) {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000429 WEBRTC_TRACE(kTraceError, kTraceVideo,
430 ViEId(shared_data_->instance_id(), video_channel),
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000431 "%s: No send codec for channel %d", __FUNCTION__,
432 video_channel);
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000433 shared_data_->SetLastError(kViECodecInvalidChannelId);
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000434 return -1;
435 }
436
mflodman@webrtc.orgf5e99db2012-06-27 09:49:37 +0000437 if (vie_encoder->SendCodecStatistics(&key_frames, &delta_frames) != 0) {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000438 shared_data_->SetLastError(kViECodecUnknownError);
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000439 return -1;
440 }
441 return 0;
442}
443
444int ViECodecImpl::GetReceiveCodecStastistics(const int video_channel,
445 unsigned int& key_frames,
446 unsigned int& delta_frames) const {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000447 WEBRTC_TRACE(kTraceApiCall, kTraceVideo,
448 ViEId(shared_data_->instance_id(), video_channel),
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000449 "%s(video_channel: %d, codec_type: %d)", __FUNCTION__,
450 video_channel);
451
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000452 ViEChannelManagerScoped cs(*(shared_data_->channel_manager()));
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000453 ViEChannel* vie_channel = cs.Channel(video_channel);
454 if (!vie_channel) {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000455 WEBRTC_TRACE(kTraceError, kTraceVideo,
456 ViEId(shared_data_->instance_id(), video_channel),
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000457 "%s: No channel %d", __FUNCTION__, video_channel);
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000458 shared_data_->SetLastError(kViECodecInvalidChannelId);
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000459 return -1;
460 }
mflodman@webrtc.orgf5e99db2012-06-27 09:49:37 +0000461 if (vie_channel->ReceiveCodecStatistics(&key_frames, &delta_frames) != 0) {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000462 shared_data_->SetLastError(kViECodecUnknownError);
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000463 return -1;
464 }
465 return 0;
466}
467
stefan@webrtc.org439be292012-02-16 14:45:37 +0000468int ViECodecImpl::GetCodecTargetBitrate(const int video_channel,
469 unsigned int* bitrate) const {
470 WEBRTC_TRACE(kTraceApiCall, kTraceVideo,
471 ViEId(shared_data_->instance_id(), video_channel),
472 "%s(video_channel: %d, codec_type: %d)", __FUNCTION__,
473 video_channel);
474
475 ViEChannelManagerScoped cs(*(shared_data_->channel_manager()));
476 ViEEncoder* vie_encoder = cs.Encoder(video_channel);
477 if (!vie_encoder) {
478 WEBRTC_TRACE(kTraceError, kTraceVideo,
479 ViEId(shared_data_->instance_id(), video_channel),
480 "%s: No send codec for channel %d", __FUNCTION__,
481 video_channel);
482 shared_data_->SetLastError(kViECodecInvalidChannelId);
483 return -1;
484 }
485 return vie_encoder->CodecTargetBitrate(static_cast<WebRtc_UWord32*>(bitrate));
486}
487
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000488unsigned int ViECodecImpl::GetDiscardedPackets(const int video_channel) const {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000489 WEBRTC_TRACE(kTraceApiCall, kTraceVideo,
490 ViEId(shared_data_->instance_id(), video_channel),
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000491 "%s(video_channel: %d, codec_type: %d)", __FUNCTION__,
492 video_channel);
493
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000494 ViEChannelManagerScoped cs(*(shared_data_->channel_manager()));
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000495 ViEChannel* vie_channel = cs.Channel(video_channel);
496 if (!vie_channel) {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000497 WEBRTC_TRACE(kTraceError, kTraceVideo,
498 ViEId(shared_data_->instance_id(), video_channel),
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000499 "%s: No channel %d", __FUNCTION__, video_channel);
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000500 shared_data_->SetLastError(kViECodecInvalidChannelId);
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000501 return -1;
502 }
503 return vie_channel->DiscardedPackets();
504}
505
506int ViECodecImpl::SetKeyFrameRequestCallbackStatus(const int video_channel,
507 const bool enable) {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000508 WEBRTC_TRACE(kTraceApiCall, kTraceVideo,
509 ViEId(shared_data_->instance_id(), video_channel),
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000510 "%s(video_channel: %d)", __FUNCTION__, video_channel);
511
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000512 ViEChannelManagerScoped cs(*(shared_data_->channel_manager()));
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000513 ViEChannel* vie_channel = cs.Channel(video_channel);
514 if (!vie_channel) {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000515 WEBRTC_TRACE(kTraceError, kTraceVideo,
516 ViEId(shared_data_->instance_id(), video_channel),
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000517 "%s: No channel %d", __FUNCTION__, video_channel);
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000518 shared_data_->SetLastError(kViECodecInvalidChannelId);
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000519 return -1;
520 }
521 if (vie_channel->EnableKeyFrameRequestCallback(enable) != 0) {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000522 shared_data_->SetLastError(kViECodecUnknownError);
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000523 return -1;
524 }
525 return 0;
526}
527
528int ViECodecImpl::SetSignalKeyPacketLossStatus(const int video_channel,
niklase@google.com470e71d2011-07-07 08:21:25 +0000529 const bool enable,
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000530 const bool only_key_frames) {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000531 WEBRTC_TRACE(kTraceApiCall, kTraceVideo,
532 ViEId(shared_data_->instance_id(), video_channel),
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000533 "%s(video_channel: %d, enable: %d, only_key_frames: %d)",
534 __FUNCTION__, video_channel, enable);
niklase@google.com470e71d2011-07-07 08:21:25 +0000535
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000536 ViEChannelManagerScoped cs(*(shared_data_->channel_manager()));
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000537 ViEChannel* vie_channel = cs.Channel(video_channel);
538 if (!vie_channel) {
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: No channel %d", __FUNCTION__, video_channel);
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000542 shared_data_->SetLastError(kViECodecInvalidChannelId);
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000543 return -1;
544 }
545 if (vie_channel->SetSignalPacketLossStatus(enable, only_key_frames) != 0) {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000546 shared_data_->SetLastError(kViECodecUnknownError);
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000547 return -1;
548 }
549 return 0;
niklase@google.com470e71d2011-07-07 08:21:25 +0000550}
551
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000552int ViECodecImpl::RegisterEncoderObserver(const int video_channel,
553 ViEEncoderObserver& observer) {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000554 WEBRTC_TRACE(kTraceApiCall, kTraceVideo, ViEId(shared_data_->instance_id()),
555 "%s", __FUNCTION__);
niklase@google.com470e71d2011-07-07 08:21:25 +0000556
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000557 ViEChannelManagerScoped cs(*(shared_data_->channel_manager()));
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000558 ViEEncoder* vie_encoder = cs.Encoder(video_channel);
559 if (!vie_encoder) {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000560 WEBRTC_TRACE(kTraceError, kTraceVideo,
561 ViEId(shared_data_->instance_id(), video_channel),
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000562 "%s: No encoder for channel %d", __FUNCTION__, video_channel);
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000563 shared_data_->SetLastError(kViECodecInvalidChannelId);
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000564 return -1;
565 }
566 if (vie_encoder->RegisterCodecObserver(&observer) != 0) {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000567 WEBRTC_TRACE(kTraceError, kTraceVideo,
568 ViEId(shared_data_->instance_id(), video_channel),
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000569 "%s: Could not register codec observer at channel",
570 __FUNCTION__);
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000571 shared_data_->SetLastError(kViECodecObserverAlreadyRegistered);
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000572 return -1;
573 }
574 return 0;
niklase@google.com470e71d2011-07-07 08:21:25 +0000575}
576
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000577int ViECodecImpl::DeregisterEncoderObserver(const int video_channel) {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000578 WEBRTC_TRACE(kTraceApiCall, kTraceVideo, ViEId(shared_data_->instance_id()),
579 "%s", __FUNCTION__);
niklase@google.com470e71d2011-07-07 08:21:25 +0000580
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000581 ViEChannelManagerScoped cs(*(shared_data_->channel_manager()));
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000582 ViEEncoder* vie_encoder = cs.Encoder(video_channel);
583 if (!vie_encoder) {
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: No encoder for channel %d", __FUNCTION__, video_channel);
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000587 shared_data_->SetLastError(kViECodecInvalidChannelId);
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000588 return -1;
589 }
590 if (vie_encoder->RegisterCodecObserver(NULL) != 0) {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000591 shared_data_->SetLastError(kViECodecObserverNotRegistered);
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000592 return -1;
593 }
594 return 0;
niklase@google.com470e71d2011-07-07 08:21:25 +0000595}
596
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000597int ViECodecImpl::RegisterDecoderObserver(const int video_channel,
598 ViEDecoderObserver& observer) {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000599 WEBRTC_TRACE(kTraceApiCall, kTraceVideo, ViEId(shared_data_->instance_id()),
600 "%s", __FUNCTION__);
niklase@google.com470e71d2011-07-07 08:21:25 +0000601
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000602 ViEChannelManagerScoped cs(*(shared_data_->channel_manager()));
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000603 ViEChannel* vie_channel = cs.Channel(video_channel);
604 if (!vie_channel) {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000605 WEBRTC_TRACE(kTraceError, kTraceVideo,
606 ViEId(shared_data_->instance_id(), video_channel),
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000607 "%s: No channel %d", __FUNCTION__, video_channel);
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000608 shared_data_->SetLastError(kViECodecInvalidChannelId);
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000609 return -1;
610 }
611 if (vie_channel->RegisterCodecObserver(&observer) != 0) {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000612 WEBRTC_TRACE(kTraceError, kTraceVideo,
613 ViEId(shared_data_->instance_id(), video_channel),
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000614 "%s: Could not register codec observer at channel",
615 __FUNCTION__);
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000616 shared_data_->SetLastError(kViECodecObserverAlreadyRegistered);
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000617 return -1;
618 }
619 return 0;
niklase@google.com470e71d2011-07-07 08:21:25 +0000620}
621
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000622int ViECodecImpl::DeregisterDecoderObserver(const int video_channel) {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000623 WEBRTC_TRACE(kTraceApiCall, kTraceVideo,
624 ViEId(shared_data_->instance_id()), "%s",
niklase@google.com470e71d2011-07-07 08:21:25 +0000625 __FUNCTION__);
626
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000627 ViEChannelManagerScoped cs(*(shared_data_->channel_manager()));
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000628 ViEChannel* vie_channel = cs.Channel(video_channel);
629 if (!vie_channel) {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000630 WEBRTC_TRACE(kTraceError, kTraceVideo,
631 ViEId(shared_data_->instance_id(), video_channel),
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000632 "%s: No channel %d", __FUNCTION__, video_channel);
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000633 shared_data_->SetLastError(kViECodecInvalidChannelId);
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000634 return -1;
635 }
636 if (vie_channel->RegisterCodecObserver(NULL) != 0) {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000637 shared_data_->SetLastError(kViECodecObserverNotRegistered);
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000638 return -1;
639 }
640 return 0;
niklase@google.com470e71d2011-07-07 08:21:25 +0000641}
642
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000643int ViECodecImpl::SendKeyFrame(const int video_channel) {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000644 WEBRTC_TRACE(kTraceApiCall, kTraceVideo, ViEId(shared_data_->instance_id()),
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000645 "%s(video_channel: %d)", __FUNCTION__, video_channel);
niklase@google.com470e71d2011-07-07 08:21:25 +0000646
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000647 ViEChannelManagerScoped cs(*(shared_data_->channel_manager()));
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000648 ViEEncoder* vie_encoder = cs.Encoder(video_channel);
649 if (!vie_encoder) {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000650 WEBRTC_TRACE(kTraceError, kTraceVideo,
651 ViEId(shared_data_->instance_id(), video_channel),
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000652 "%s: No channel %d", __FUNCTION__, video_channel);
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000653 shared_data_->SetLastError(kViECodecInvalidChannelId);
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000654 return -1;
655 }
656 if (vie_encoder->SendKeyFrame() != 0) {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000657 shared_data_->SetLastError(kViECodecUnknownError);
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000658 return -1;
659 }
660 return 0;
niklase@google.com470e71d2011-07-07 08:21:25 +0000661}
662
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000663int ViECodecImpl::WaitForFirstKeyFrame(const int video_channel,
664 const bool wait) {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000665 WEBRTC_TRACE(kTraceApiCall, kTraceVideo,
666 ViEId(shared_data_->instance_id()),
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000667 "%s(video_channel: %d, wait: %d)", __FUNCTION__, video_channel,
niklase@google.com470e71d2011-07-07 08:21:25 +0000668 wait);
669
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000670 ViEChannelManagerScoped cs(*(shared_data_->channel_manager()));
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000671 ViEChannel* vie_channel = cs.Channel(video_channel);
672 if (!vie_channel) {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000673 WEBRTC_TRACE(kTraceError, kTraceVideo,
674 ViEId(shared_data_->instance_id(), video_channel),
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000675 "%s: No channel %d", __FUNCTION__, video_channel);
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000676 shared_data_->SetLastError(kViECodecInvalidChannelId);
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000677 return -1;
678 }
679 if (vie_channel->WaitForKeyFrame(wait) != 0) {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000680 shared_data_->SetLastError(kViECodecUnknownError);
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000681 return -1;
682 }
683 return 0;
niklase@google.com470e71d2011-07-07 08:21:25 +0000684}
685
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000686bool ViECodecImpl::CodecValid(const VideoCodec& video_codec) {
687 // Check pl_name matches codec_type.
688 if (video_codec.codecType == kVideoCodecRED) {
niklase@google.com470e71d2011-07-07 08:21:25 +0000689#if defined(WIN32)
mflodman@webrtc.org1fe2ada2011-12-21 12:23:15 +0000690 if (_strnicmp(video_codec.plName, "red", 3) == 0) {
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000691#else
692 if (strncasecmp(video_codec.plName, "red", 3) == 0) {
niklase@google.com470e71d2011-07-07 08:21:25 +0000693#endif
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000694 // We only care about the type and name for red.
695 return true;
niklase@google.com470e71d2011-07-07 08:21:25 +0000696 }
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000697 WEBRTC_TRACE(kTraceError, kTraceVideo, -1,
698 "Codec type doesn't match pl_name", video_codec.plType);
699 return false;
700 } else if (video_codec.codecType == kVideoCodecULPFEC) {
niklase@google.com470e71d2011-07-07 08:21:25 +0000701#if defined(WIN32)
mflodman@webrtc.org1fe2ada2011-12-21 12:23:15 +0000702 if (_strnicmp(video_codec.plName, "ULPFEC", 6) == 0) {
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000703#else
704 if (strncasecmp(video_codec.plName, "ULPFEC", 6) == 0) {
niklase@google.com470e71d2011-07-07 08:21:25 +0000705#endif
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000706 // We only care about the type and name for ULPFEC.
707 return true;
niklase@google.com470e71d2011-07-07 08:21:25 +0000708 }
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000709 WEBRTC_TRACE(kTraceError, kTraceVideo, -1,
710 "Codec type doesn't match pl_name", video_codec.plType);
711 return false;
pwestin@webrtc.org56210572012-01-17 12:45:47 +0000712 } else if ((video_codec.codecType == kVideoCodecVP8 &&
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000713 strncmp(video_codec.plName, "VP8", 4) == 0) ||
714 (video_codec.codecType == kVideoCodecI420 &&
pwestin@webrtc.org56210572012-01-17 12:45:47 +0000715 strncmp(video_codec.plName, "I420", 4) == 0)) {
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000716 // OK.
717 } else {
718 WEBRTC_TRACE(kTraceError, kTraceVideo, -1,
719 "Codec type doesn't match pl_name", video_codec.plType);
720 return false;
721 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000722
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000723 if (video_codec.plType == 0 && video_codec.plType > 127) {
724 WEBRTC_TRACE(kTraceError, kTraceVideo, -1,
725 "Invalid codec payload type: %d", video_codec.plType);
726 return false;
727 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000728
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000729 if (video_codec.width > kViEMaxCodecWidth ||
730 video_codec.height > kViEMaxCodecHeight) {
731 WEBRTC_TRACE(kTraceError, kTraceVideo, -1, "Invalid codec size: %u x %u",
732 video_codec.width, video_codec.height);
733 return false;
734 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000735
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000736 if (video_codec.startBitrate < kViEMinCodecBitrate) {
737 WEBRTC_TRACE(kTraceError, kTraceVideo, -1, "Invalid start_bitrate: %u",
738 video_codec.startBitrate);
739 return false;
740 }
741 if (video_codec.minBitrate < kViEMinCodecBitrate) {
742 WEBRTC_TRACE(kTraceError, kTraceVideo, -1, "Invalid min_bitrate: %u",
743 video_codec.minBitrate);
744 return false;
745 }
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000746 return true;
niklase@google.com470e71d2011-07-07 08:21:25 +0000747}
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000748
749} // namespace webrtc