blob: 3ae15c70e4000fbadc53dccaa791a63239ed3ecd [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, "
127 "complexity: %d, resilience: %d, numberOfTemporalLayers: %u",
128 video_codec.codecSpecific.VP8.pictureLossIndicationOn,
129 video_codec.codecSpecific.VP8.feedbackModeOn,
130 video_codec.codecSpecific.VP8.complexity,
131 video_codec.codecSpecific.VP8.resilience,
132 video_codec.codecSpecific.VP8.numberOfTemporalLayers);
133 }
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000134 if (!CodecValid(video_codec)) {
135 // Error logged.
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000136 shared_data_->SetLastError(kViECodecInvalidCodec);
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000137 return -1;
138 }
stefan@webrtc.org791eec72011-10-11 07:53:43 +0000139
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000140 ViEChannelManagerScoped cs(*(shared_data_->channel_manager()));
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000141 ViEChannel* vie_channel = cs.Channel(video_channel);
142 if (!vie_channel) {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000143 WEBRTC_TRACE(kTraceError, kTraceVideo,
144 ViEId(shared_data_->instance_id(), video_channel),
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000145 "%s: No channel %d", __FUNCTION__, video_channel);
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000146 shared_data_->SetLastError(kViECodecInvalidChannelId);
stefan@webrtc.org791eec72011-10-11 07:53:43 +0000147 return -1;
148 }
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000149
mflodman@webrtc.org9ec883e2012-03-05 17:12:41 +0000150 ViEEncoder* vie_encoder = cs.Encoder(video_channel);
151 assert(vie_encoder);
152 if (vie_encoder->Owner() != video_channel) {
153 WEBRTC_TRACE(kTraceError, kTraceVideo,
154 ViEId(shared_data_->instance_id(), video_channel),
155 "%s: Receive only channel %d", __FUNCTION__, video_channel);
156 shared_data_->SetLastError(kViECodecReceiveOnlyChannel);
157 return -1;
158 }
159
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000160 // Set a max_bitrate if the user hasn't set one.
161 VideoCodec video_codec_internal;
162 memcpy(&video_codec_internal, &video_codec, sizeof(VideoCodec));
163 if (video_codec_internal.maxBitrate == 0) {
164 // Max is one bit per pixel.
165 video_codec_internal.maxBitrate = (video_codec_internal.width *
166 video_codec_internal.height *
167 video_codec_internal.maxFramerate)
168 / 1000;
169 if (video_codec_internal.startBitrate > video_codec_internal.maxBitrate) {
170 // Don't limit the set start bitrate.
171 video_codec_internal.maxBitrate = video_codec_internal.startBitrate;
172 }
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000173 WEBRTC_TRACE(kTraceInfo, kTraceVideo,
174 ViEId(shared_data_->instance_id(), video_channel),
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000175 "%s: New max bitrate set to %d kbps", __FUNCTION__,
176 video_codec_internal.maxBitrate);
177 }
178
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000179 VideoCodec encoder;
mflodman@webrtc.orgf5e99db2012-06-27 09:49:37 +0000180 vie_encoder->GetEncoder(&encoder);
mflodman@webrtc.org9ec883e2012-03-05 17:12:41 +0000181
mflodman@webrtc.org9c0aedc2012-01-03 13:46:49 +0000182 // Make sure to generate a new SSRC if the codec type and/or resolution has
183 // changed. This won't have any effect if the user has set an SSRC.
184 bool new_rtp_stream = false;
stefan@webrtc.org4e8eaba2012-08-20 14:29:52 +0000185 if (encoder.codecType != video_codec_internal.codecType) {
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000186 new_rtp_stream = true;
187 }
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000188
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000189 ViEInputManagerScoped is(*(shared_data_->input_manager()));
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000190 ViEFrameProviderBase* frame_provider = NULL;
191
192 // Stop the media flow while reconfiguring.
193 vie_encoder->Pause();
194
195 // Check if we have a frame provider that is a camera and can provide this
196 // codec for us.
197 bool use_capture_device_as_encoder = false;
198 frame_provider = is.FrameProvider(vie_encoder);
199 if (frame_provider) {
200 if (frame_provider->Id() >= kViECaptureIdBase &&
201 frame_provider->Id() <= kViECaptureIdMax) {
202 ViECapturer* vie_capture = static_cast<ViECapturer*>(frame_provider);
203 // Try to get preencoded. Nothing to do if it is not supported.
204 if (vie_capture && vie_capture->PreEncodeToViEEncoder(
205 video_codec_internal,
206 *vie_encoder,
207 video_channel) == 0) {
208 use_capture_device_as_encoder = true;
209 }
210 }
211 }
212
213 // Update the encoder settings if we are not using a capture device capable
214 // of this codec.
215 if (!use_capture_device_as_encoder &&
216 vie_encoder->SetEncoder(video_codec_internal) != 0) {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000217 WEBRTC_TRACE(kTraceError, kTraceVideo,
218 ViEId(shared_data_->instance_id(), video_channel),
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000219 "%s: Could not change encoder for channel %d", __FUNCTION__,
220 video_channel);
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000221 shared_data_->SetLastError(kViECodecUnknownError);
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000222 return -1;
223 }
224
mflodman@webrtc.org9c0aedc2012-01-03 13:46:49 +0000225 // Give the channel(s) the new information.
226 ChannelList channels;
227 cs.ChannelsUsingViEEncoder(video_channel, &channels);
228 for (ChannelList::iterator it = channels.begin(); it != channels.end();
229 ++it) {
230 bool ret = true;
231 if ((*it)->SetSendCodec(video_codec_internal, new_rtp_stream) != 0) {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000232 WEBRTC_TRACE(kTraceError, kTraceVideo,
233 ViEId(shared_data_->instance_id(), video_channel),
mflodman@webrtc.org9c0aedc2012-01-03 13:46:49 +0000234 "%s: Could not set send codec for channel %d", __FUNCTION__,
235 video_channel);
236 ret = false;
237 }
238 if (!ret) {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000239 shared_data_->SetLastError(kViECodecUnknownError);
mflodman@webrtc.org9c0aedc2012-01-03 13:46:49 +0000240 return -1;
241 }
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000242 }
243
mflodman@webrtc.orgd6ec3862012-10-25 11:30:29 +0000244 // TODO(mflodman) Break out this part in GetLocalSsrcList().
245 // Update all SSRCs to ViEEncoder.
246 std::list<unsigned int> ssrcs;
247 if (video_codec_internal.numberOfSimulcastStreams == 0) {
248 unsigned int ssrc = 0;
249 if (vie_channel->GetLocalSSRC(0, &ssrc) != 0) {
250 WEBRTC_TRACE(kTraceError, kTraceVideo,
251 ViEId(shared_data_->instance_id(), video_channel),
252 "%s: Could not get ssrc", __FUNCTION__);
253 }
254 ssrcs.push_back(ssrc);
255 } else {
256 for (int idx = 0; idx < video_codec_internal.numberOfSimulcastStreams;
257 ++idx) {
258 unsigned int ssrc = 0;
259 if (vie_channel->GetLocalSSRC(idx, &ssrc) != 0) {
260 WEBRTC_TRACE(kTraceError, kTraceVideo,
261 ViEId(shared_data_->instance_id(), video_channel),
262 "%s: Could not get ssrc for idx %d", __FUNCTION__, idx);
263 }
264 ssrcs.push_back(ssrc);
265 }
266 }
267 vie_encoder->SetSsrcs(ssrcs);
268 shared_data_->channel_manager()->UpdateSsrcs(video_channel, ssrcs);
269
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000270 // Update the protection mode, we might be switching NACK/FEC.
271 vie_encoder->UpdateProtectionMethod();
272
273 // Get new best format for frame provider.
274 if (frame_provider) {
275 frame_provider->FrameCallbackChanged();
276 }
277 // Restart the media flow
278 if (new_rtp_stream) {
279 // Stream settings changed, make sure we get a key frame.
280 vie_encoder->SendKeyFrame();
281 }
282 vie_encoder->Restart();
283 return 0;
stefan@webrtc.org791eec72011-10-11 07:53:43 +0000284}
285
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000286int ViECodecImpl::GetSendCodec(const int video_channel,
287 VideoCodec& video_codec) const {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000288 WEBRTC_TRACE(kTraceApiCall, kTraceVideo,
289 ViEId(shared_data_->instance_id(), video_channel),
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000290 "%s(video_channel: %d)", __FUNCTION__, video_channel);
niklase@google.com470e71d2011-07-07 08:21:25 +0000291
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000292 ViEChannelManagerScoped cs(*(shared_data_->channel_manager()));
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000293 ViEEncoder* vie_encoder = cs.Encoder(video_channel);
294 if (!vie_encoder) {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000295 WEBRTC_TRACE(kTraceError, kTraceVideo,
296 ViEId(shared_data_->instance_id(), video_channel),
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000297 "%s: No encoder for channel %d", __FUNCTION__, video_channel);
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000298 shared_data_->SetLastError(kViECodecInvalidChannelId);
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000299 return -1;
300 }
mflodman@webrtc.orgf5e99db2012-06-27 09:49:37 +0000301 return vie_encoder->GetEncoder(&video_codec);
niklase@google.com470e71d2011-07-07 08:21:25 +0000302}
303
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000304int ViECodecImpl::SetReceiveCodec(const int video_channel,
305 const VideoCodec& video_codec) {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000306 WEBRTC_TRACE(kTraceApiCall, kTraceVideo,
307 ViEId(shared_data_->instance_id(), video_channel),
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000308 "%s(video_channel: %d, codec_type: %d)", __FUNCTION__,
309 video_channel, video_codec.codecType);
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000310 WEBRTC_TRACE(kTraceInfo, kTraceVideo,
311 ViEId(shared_data_->instance_id(), video_channel),
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000312 "%s: codec: %d, pl_type: %d, width: %d, height: %d, bitrate: %d,"
313 "maxBr: %d, min_br: %d, frame_rate: %d", __FUNCTION__,
314 video_codec.codecType, video_codec.plType, video_codec.width,
315 video_codec.height, video_codec.startBitrate,
316 video_codec.maxBitrate, video_codec.minBitrate,
317 video_codec.maxFramerate);
niklase@google.com470e71d2011-07-07 08:21:25 +0000318
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000319 if (CodecValid(video_codec) == false) {
320 // Error logged.
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000321 shared_data_->SetLastError(kViECodecInvalidCodec);
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000322 return -1;
323 }
324
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000325 ViEChannelManagerScoped cs(*(shared_data_->channel_manager()));
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000326 ViEChannel* vie_channel = cs.Channel(video_channel);
327 if (!vie_channel) {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000328 WEBRTC_TRACE(kTraceError, kTraceVideo,
329 ViEId(shared_data_->instance_id(), video_channel),
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000330 "%s: No channel %d", __FUNCTION__, video_channel);
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000331 shared_data_->SetLastError(kViECodecInvalidChannelId);
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000332 return -1;
333 }
334
335 if (vie_channel->SetReceiveCodec(video_codec) != 0) {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000336 WEBRTC_TRACE(kTraceError, kTraceVideo,
337 ViEId(shared_data_->instance_id(), video_channel),
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000338 "%s: Could not set receive codec for channel %d",
339 __FUNCTION__, video_channel);
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000340 shared_data_->SetLastError(kViECodecUnknownError);
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000341 return -1;
342 }
343 return 0;
344}
345
346int ViECodecImpl::GetReceiveCodec(const int video_channel,
347 VideoCodec& video_codec) const {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000348 WEBRTC_TRACE(kTraceApiCall, kTraceVideo,
349 ViEId(shared_data_->instance_id(), video_channel),
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000350 "%s(video_channel: %d, codec_type: %d)", __FUNCTION__,
351 video_channel, video_codec.codecType);
352
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000353 ViEChannelManagerScoped cs(*(shared_data_->channel_manager()));
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000354 ViEChannel* vie_channel = cs.Channel(video_channel);
355 if (!vie_channel) {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000356 WEBRTC_TRACE(kTraceError, kTraceVideo,
357 ViEId(shared_data_->instance_id(), video_channel),
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000358 "%s: No channel %d", __FUNCTION__, video_channel);
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000359 shared_data_->SetLastError(kViECodecInvalidChannelId);
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000360 return -1;
361 }
362
mflodman@webrtc.orgf5e99db2012-06-27 09:49:37 +0000363 if (vie_channel->GetReceiveCodec(&video_codec) != 0) {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000364 shared_data_->SetLastError(kViECodecUnknownError);
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000365 return -1;
366 }
367 return 0;
368}
369
370int ViECodecImpl::GetCodecConfigParameters(
371 const int video_channel,
372 unsigned char config_parameters[kConfigParameterSize],
373 unsigned char& config_parameters_size) const {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000374 WEBRTC_TRACE(kTraceApiCall, kTraceVideo,
375 ViEId(shared_data_->instance_id(), video_channel),
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000376 "%s(video_channel: %d)", __FUNCTION__, video_channel);
377
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000378 ViEChannelManagerScoped cs(*(shared_data_->channel_manager()));
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000379 ViEEncoder* vie_encoder = cs.Encoder(video_channel);
380 if (!vie_encoder) {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000381 WEBRTC_TRACE(kTraceError, kTraceVideo,
382 ViEId(shared_data_->instance_id(), video_channel),
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000383 "%s: No encoder for channel %d", __FUNCTION__, video_channel);
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000384 shared_data_->SetLastError(kViECodecInvalidChannelId);
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000385 return -1;
386 }
387
388 if (vie_encoder->GetCodecConfigParameters(config_parameters,
389 config_parameters_size) != 0) {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000390 shared_data_->SetLastError(kViECodecUnknownError);
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000391 return -1;
392 }
393 return 0;
394}
395
396int ViECodecImpl::SetImageScaleStatus(const int video_channel,
397 const bool enable) {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000398 WEBRTC_TRACE(kTraceApiCall, kTraceVideo,
399 ViEId(shared_data_->instance_id(), video_channel),
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000400 "%s(video_channel: %d, enable: %d)", __FUNCTION__, video_channel,
401 enable);
402
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000403 ViEChannelManagerScoped cs(*(shared_data_->channel_manager()));
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000404 ViEEncoder* vie_encoder = cs.Encoder(video_channel);
405 if (!vie_encoder) {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000406 WEBRTC_TRACE(kTraceError, kTraceVideo,
407 ViEId(shared_data_->instance_id(), video_channel),
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000408 "%s: No channel %d", __FUNCTION__, video_channel);
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000409 shared_data_->SetLastError(kViECodecInvalidChannelId);
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000410 return -1;
411 }
412
413 if (vie_encoder->ScaleInputImage(enable) != 0) {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000414 shared_data_->SetLastError(kViECodecUnknownError);
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000415 return -1;
416 }
417 return 0;
418}
419
420int ViECodecImpl::GetSendCodecStastistics(const int video_channel,
421 unsigned int& key_frames,
422 unsigned int& delta_frames) const {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000423 WEBRTC_TRACE(kTraceApiCall, kTraceVideo,
424 ViEId(shared_data_->instance_id(), video_channel),
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000425 "%s(video_channel %d)", __FUNCTION__, video_channel);
426
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000427 ViEChannelManagerScoped cs(*(shared_data_->channel_manager()));
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000428 ViEEncoder* vie_encoder = cs.Encoder(video_channel);
429 if (!vie_encoder) {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000430 WEBRTC_TRACE(kTraceError, kTraceVideo,
431 ViEId(shared_data_->instance_id(), video_channel),
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000432 "%s: No send codec for channel %d", __FUNCTION__,
433 video_channel);
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000434 shared_data_->SetLastError(kViECodecInvalidChannelId);
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000435 return -1;
436 }
437
mflodman@webrtc.orgf5e99db2012-06-27 09:49:37 +0000438 if (vie_encoder->SendCodecStatistics(&key_frames, &delta_frames) != 0) {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000439 shared_data_->SetLastError(kViECodecUnknownError);
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000440 return -1;
441 }
442 return 0;
443}
444
445int ViECodecImpl::GetReceiveCodecStastistics(const int video_channel,
446 unsigned int& key_frames,
447 unsigned int& delta_frames) const {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000448 WEBRTC_TRACE(kTraceApiCall, kTraceVideo,
449 ViEId(shared_data_->instance_id(), video_channel),
mflodman@webrtc.org4aee6b62012-12-14 14:02:10 +0000450 "%s(video_channel: %d)", __FUNCTION__,
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000451 video_channel);
452
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000453 ViEChannelManagerScoped cs(*(shared_data_->channel_manager()));
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000454 ViEChannel* vie_channel = cs.Channel(video_channel);
455 if (!vie_channel) {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000456 WEBRTC_TRACE(kTraceError, kTraceVideo,
457 ViEId(shared_data_->instance_id(), video_channel),
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000458 "%s: No channel %d", __FUNCTION__, video_channel);
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000459 shared_data_->SetLastError(kViECodecInvalidChannelId);
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000460 return -1;
461 }
mflodman@webrtc.orgf5e99db2012-06-27 09:49:37 +0000462 if (vie_channel->ReceiveCodecStatistics(&key_frames, &delta_frames) != 0) {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000463 shared_data_->SetLastError(kViECodecUnknownError);
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000464 return -1;
465 }
466 return 0;
467}
468
mflodman@webrtc.org4aee6b62012-12-14 14:02:10 +0000469int ViECodecImpl::GetReceiveSideDelay(const int video_channel,
470 int* delay_ms) const {
471 WEBRTC_TRACE(kTraceApiCall, kTraceVideo,
472 ViEId(shared_data_->instance_id(), video_channel),
473 "%s(video_channel: %d)", __FUNCTION__, video_channel);
474 if (delay_ms == NULL) {
475 LOG_F(LS_ERROR) << "NULL pointer argument.";
476 return -1;
477 }
478
479 ViEChannelManagerScoped cs(*(shared_data_->channel_manager()));
480 ViEChannel* vie_channel = cs.Channel(video_channel);
481 if (!vie_channel) {
482 WEBRTC_TRACE(kTraceError, kTraceVideo,
483 ViEId(shared_data_->instance_id(), video_channel),
484 "%s: No channel %d", __FUNCTION__, video_channel);
485 shared_data_->SetLastError(kViECodecInvalidChannelId);
486 return -1;
487 }
488 *delay_ms = vie_channel->ReceiveDelay();
489 if (*delay_ms < 0) {
490 return -1;
491 }
492 return 0;
493}
494
495
stefan@webrtc.org439be292012-02-16 14:45:37 +0000496int ViECodecImpl::GetCodecTargetBitrate(const int video_channel,
497 unsigned int* bitrate) const {
498 WEBRTC_TRACE(kTraceApiCall, kTraceVideo,
499 ViEId(shared_data_->instance_id(), video_channel),
500 "%s(video_channel: %d, codec_type: %d)", __FUNCTION__,
501 video_channel);
502
503 ViEChannelManagerScoped cs(*(shared_data_->channel_manager()));
504 ViEEncoder* vie_encoder = cs.Encoder(video_channel);
505 if (!vie_encoder) {
506 WEBRTC_TRACE(kTraceError, kTraceVideo,
507 ViEId(shared_data_->instance_id(), video_channel),
508 "%s: No send codec for channel %d", __FUNCTION__,
509 video_channel);
510 shared_data_->SetLastError(kViECodecInvalidChannelId);
511 return -1;
512 }
513 return vie_encoder->CodecTargetBitrate(static_cast<WebRtc_UWord32*>(bitrate));
514}
515
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000516unsigned int ViECodecImpl::GetDiscardedPackets(const int video_channel) const {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000517 WEBRTC_TRACE(kTraceApiCall, kTraceVideo,
518 ViEId(shared_data_->instance_id(), video_channel),
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000519 "%s(video_channel: %d, codec_type: %d)", __FUNCTION__,
520 video_channel);
521
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000522 ViEChannelManagerScoped cs(*(shared_data_->channel_manager()));
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000523 ViEChannel* vie_channel = cs.Channel(video_channel);
524 if (!vie_channel) {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000525 WEBRTC_TRACE(kTraceError, kTraceVideo,
526 ViEId(shared_data_->instance_id(), video_channel),
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000527 "%s: No channel %d", __FUNCTION__, video_channel);
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000528 shared_data_->SetLastError(kViECodecInvalidChannelId);
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000529 return -1;
530 }
531 return vie_channel->DiscardedPackets();
532}
533
534int ViECodecImpl::SetKeyFrameRequestCallbackStatus(const int video_channel,
535 const bool enable) {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000536 WEBRTC_TRACE(kTraceApiCall, kTraceVideo,
537 ViEId(shared_data_->instance_id(), video_channel),
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000538 "%s(video_channel: %d)", __FUNCTION__, video_channel);
539
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000540 ViEChannelManagerScoped cs(*(shared_data_->channel_manager()));
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000541 ViEChannel* vie_channel = cs.Channel(video_channel);
542 if (!vie_channel) {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000543 WEBRTC_TRACE(kTraceError, kTraceVideo,
544 ViEId(shared_data_->instance_id(), video_channel),
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000545 "%s: No channel %d", __FUNCTION__, video_channel);
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000546 shared_data_->SetLastError(kViECodecInvalidChannelId);
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000547 return -1;
548 }
549 if (vie_channel->EnableKeyFrameRequestCallback(enable) != 0) {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000550 shared_data_->SetLastError(kViECodecUnknownError);
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000551 return -1;
552 }
553 return 0;
554}
555
556int ViECodecImpl::SetSignalKeyPacketLossStatus(const int video_channel,
niklase@google.com470e71d2011-07-07 08:21:25 +0000557 const bool enable,
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000558 const bool only_key_frames) {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000559 WEBRTC_TRACE(kTraceApiCall, kTraceVideo,
560 ViEId(shared_data_->instance_id(), video_channel),
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000561 "%s(video_channel: %d, enable: %d, only_key_frames: %d)",
562 __FUNCTION__, video_channel, enable);
niklase@google.com470e71d2011-07-07 08:21:25 +0000563
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000564 ViEChannelManagerScoped cs(*(shared_data_->channel_manager()));
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000565 ViEChannel* vie_channel = cs.Channel(video_channel);
566 if (!vie_channel) {
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: No channel %d", __FUNCTION__, video_channel);
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000570 shared_data_->SetLastError(kViECodecInvalidChannelId);
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000571 return -1;
572 }
573 if (vie_channel->SetSignalPacketLossStatus(enable, only_key_frames) != 0) {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000574 shared_data_->SetLastError(kViECodecUnknownError);
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000575 return -1;
576 }
577 return 0;
niklase@google.com470e71d2011-07-07 08:21:25 +0000578}
579
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000580int ViECodecImpl::RegisterEncoderObserver(const int video_channel,
581 ViEEncoderObserver& observer) {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000582 WEBRTC_TRACE(kTraceApiCall, kTraceVideo, ViEId(shared_data_->instance_id()),
583 "%s", __FUNCTION__);
niklase@google.com470e71d2011-07-07 08:21:25 +0000584
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000585 ViEChannelManagerScoped cs(*(shared_data_->channel_manager()));
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000586 ViEEncoder* vie_encoder = cs.Encoder(video_channel);
587 if (!vie_encoder) {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000588 WEBRTC_TRACE(kTraceError, kTraceVideo,
589 ViEId(shared_data_->instance_id(), video_channel),
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000590 "%s: No encoder for channel %d", __FUNCTION__, video_channel);
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000591 shared_data_->SetLastError(kViECodecInvalidChannelId);
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000592 return -1;
593 }
594 if (vie_encoder->RegisterCodecObserver(&observer) != 0) {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000595 WEBRTC_TRACE(kTraceError, kTraceVideo,
596 ViEId(shared_data_->instance_id(), video_channel),
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000597 "%s: Could not register codec observer at channel",
598 __FUNCTION__);
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000599 shared_data_->SetLastError(kViECodecObserverAlreadyRegistered);
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000600 return -1;
601 }
602 return 0;
niklase@google.com470e71d2011-07-07 08:21:25 +0000603}
604
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000605int ViECodecImpl::DeregisterEncoderObserver(const int video_channel) {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000606 WEBRTC_TRACE(kTraceApiCall, kTraceVideo, ViEId(shared_data_->instance_id()),
607 "%s", __FUNCTION__);
niklase@google.com470e71d2011-07-07 08:21:25 +0000608
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000609 ViEChannelManagerScoped cs(*(shared_data_->channel_manager()));
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000610 ViEEncoder* vie_encoder = cs.Encoder(video_channel);
611 if (!vie_encoder) {
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: No encoder for channel %d", __FUNCTION__, video_channel);
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000615 shared_data_->SetLastError(kViECodecInvalidChannelId);
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000616 return -1;
617 }
618 if (vie_encoder->RegisterCodecObserver(NULL) != 0) {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000619 shared_data_->SetLastError(kViECodecObserverNotRegistered);
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000620 return -1;
621 }
622 return 0;
niklase@google.com470e71d2011-07-07 08:21:25 +0000623}
624
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000625int ViECodecImpl::RegisterDecoderObserver(const int video_channel,
626 ViEDecoderObserver& observer) {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000627 WEBRTC_TRACE(kTraceApiCall, kTraceVideo, ViEId(shared_data_->instance_id()),
628 "%s", __FUNCTION__);
niklase@google.com470e71d2011-07-07 08:21:25 +0000629
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000630 ViEChannelManagerScoped cs(*(shared_data_->channel_manager()));
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000631 ViEChannel* vie_channel = cs.Channel(video_channel);
632 if (!vie_channel) {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000633 WEBRTC_TRACE(kTraceError, kTraceVideo,
634 ViEId(shared_data_->instance_id(), video_channel),
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000635 "%s: No channel %d", __FUNCTION__, video_channel);
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000636 shared_data_->SetLastError(kViECodecInvalidChannelId);
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000637 return -1;
638 }
639 if (vie_channel->RegisterCodecObserver(&observer) != 0) {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000640 WEBRTC_TRACE(kTraceError, kTraceVideo,
641 ViEId(shared_data_->instance_id(), video_channel),
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000642 "%s: Could not register codec observer at channel",
643 __FUNCTION__);
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000644 shared_data_->SetLastError(kViECodecObserverAlreadyRegistered);
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000645 return -1;
646 }
647 return 0;
niklase@google.com470e71d2011-07-07 08:21:25 +0000648}
649
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000650int ViECodecImpl::DeregisterDecoderObserver(const int video_channel) {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000651 WEBRTC_TRACE(kTraceApiCall, kTraceVideo,
652 ViEId(shared_data_->instance_id()), "%s",
niklase@google.com470e71d2011-07-07 08:21:25 +0000653 __FUNCTION__);
654
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000655 ViEChannelManagerScoped cs(*(shared_data_->channel_manager()));
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000656 ViEChannel* vie_channel = cs.Channel(video_channel);
657 if (!vie_channel) {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000658 WEBRTC_TRACE(kTraceError, kTraceVideo,
659 ViEId(shared_data_->instance_id(), video_channel),
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000660 "%s: No channel %d", __FUNCTION__, video_channel);
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000661 shared_data_->SetLastError(kViECodecInvalidChannelId);
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000662 return -1;
663 }
664 if (vie_channel->RegisterCodecObserver(NULL) != 0) {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000665 shared_data_->SetLastError(kViECodecObserverNotRegistered);
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000666 return -1;
667 }
668 return 0;
niklase@google.com470e71d2011-07-07 08:21:25 +0000669}
670
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000671int ViECodecImpl::SendKeyFrame(const int video_channel) {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000672 WEBRTC_TRACE(kTraceApiCall, kTraceVideo, ViEId(shared_data_->instance_id()),
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000673 "%s(video_channel: %d)", __FUNCTION__, video_channel);
niklase@google.com470e71d2011-07-07 08:21:25 +0000674
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000675 ViEChannelManagerScoped cs(*(shared_data_->channel_manager()));
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000676 ViEEncoder* vie_encoder = cs.Encoder(video_channel);
677 if (!vie_encoder) {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000678 WEBRTC_TRACE(kTraceError, kTraceVideo,
679 ViEId(shared_data_->instance_id(), video_channel),
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000680 "%s: No channel %d", __FUNCTION__, video_channel);
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000681 shared_data_->SetLastError(kViECodecInvalidChannelId);
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000682 return -1;
683 }
684 if (vie_encoder->SendKeyFrame() != 0) {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000685 shared_data_->SetLastError(kViECodecUnknownError);
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000686 return -1;
687 }
688 return 0;
niklase@google.com470e71d2011-07-07 08:21:25 +0000689}
690
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000691int ViECodecImpl::WaitForFirstKeyFrame(const int video_channel,
692 const bool wait) {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000693 WEBRTC_TRACE(kTraceApiCall, kTraceVideo,
694 ViEId(shared_data_->instance_id()),
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000695 "%s(video_channel: %d, wait: %d)", __FUNCTION__, video_channel,
niklase@google.com470e71d2011-07-07 08:21:25 +0000696 wait);
697
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000698 ViEChannelManagerScoped cs(*(shared_data_->channel_manager()));
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000699 ViEChannel* vie_channel = cs.Channel(video_channel);
700 if (!vie_channel) {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000701 WEBRTC_TRACE(kTraceError, kTraceVideo,
702 ViEId(shared_data_->instance_id(), video_channel),
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000703 "%s: No channel %d", __FUNCTION__, video_channel);
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000704 shared_data_->SetLastError(kViECodecInvalidChannelId);
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000705 return -1;
706 }
707 if (vie_channel->WaitForKeyFrame(wait) != 0) {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000708 shared_data_->SetLastError(kViECodecUnknownError);
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000709 return -1;
710 }
711 return 0;
niklase@google.com470e71d2011-07-07 08:21:25 +0000712}
713
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000714bool ViECodecImpl::CodecValid(const VideoCodec& video_codec) {
715 // Check pl_name matches codec_type.
716 if (video_codec.codecType == kVideoCodecRED) {
niklase@google.com470e71d2011-07-07 08:21:25 +0000717#if defined(WIN32)
mflodman@webrtc.org1fe2ada2011-12-21 12:23:15 +0000718 if (_strnicmp(video_codec.plName, "red", 3) == 0) {
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000719#else
720 if (strncasecmp(video_codec.plName, "red", 3) == 0) {
niklase@google.com470e71d2011-07-07 08:21:25 +0000721#endif
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000722 // We only care about the type and name for red.
723 return true;
niklase@google.com470e71d2011-07-07 08:21:25 +0000724 }
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000725 WEBRTC_TRACE(kTraceError, kTraceVideo, -1,
726 "Codec type doesn't match pl_name", video_codec.plType);
727 return false;
728 } else if (video_codec.codecType == kVideoCodecULPFEC) {
niklase@google.com470e71d2011-07-07 08:21:25 +0000729#if defined(WIN32)
mflodman@webrtc.org1fe2ada2011-12-21 12:23:15 +0000730 if (_strnicmp(video_codec.plName, "ULPFEC", 6) == 0) {
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000731#else
732 if (strncasecmp(video_codec.plName, "ULPFEC", 6) == 0) {
niklase@google.com470e71d2011-07-07 08:21:25 +0000733#endif
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000734 // We only care about the type and name for ULPFEC.
735 return true;
niklase@google.com470e71d2011-07-07 08:21:25 +0000736 }
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000737 WEBRTC_TRACE(kTraceError, kTraceVideo, -1,
738 "Codec type doesn't match pl_name", video_codec.plType);
739 return false;
pwestin@webrtc.org56210572012-01-17 12:45:47 +0000740 } else if ((video_codec.codecType == kVideoCodecVP8 &&
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000741 strncmp(video_codec.plName, "VP8", 4) == 0) ||
742 (video_codec.codecType == kVideoCodecI420 &&
pwestin@webrtc.org56210572012-01-17 12:45:47 +0000743 strncmp(video_codec.plName, "I420", 4) == 0)) {
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000744 // OK.
745 } else {
746 WEBRTC_TRACE(kTraceError, kTraceVideo, -1,
747 "Codec type doesn't match pl_name", video_codec.plType);
748 return false;
749 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000750
braveyao@webrtc.org49273ff2013-01-14 01:52:26 +0000751 if (video_codec.plType == 0 || video_codec.plType > 127) {
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000752 WEBRTC_TRACE(kTraceError, kTraceVideo, -1,
753 "Invalid codec payload type: %d", video_codec.plType);
754 return false;
755 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000756
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000757 if (video_codec.width > kViEMaxCodecWidth ||
758 video_codec.height > kViEMaxCodecHeight) {
759 WEBRTC_TRACE(kTraceError, kTraceVideo, -1, "Invalid codec size: %u x %u",
760 video_codec.width, video_codec.height);
761 return false;
762 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000763
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000764 if (video_codec.startBitrate < kViEMinCodecBitrate) {
765 WEBRTC_TRACE(kTraceError, kTraceVideo, -1, "Invalid start_bitrate: %u",
766 video_codec.startBitrate);
767 return false;
768 }
769 if (video_codec.minBitrate < kViEMinCodecBitrate) {
770 WEBRTC_TRACE(kTraceError, kTraceVideo, -1, "Invalid min_bitrate: %u",
771 video_codec.minBitrate);
772 return false;
773 }
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000774 return true;
niklase@google.com470e71d2011-07-07 08:21:25 +0000775}
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000776
777} // namespace webrtc