blob: 0ace1e2b933d6c4555401698fcc544f7c279569b [file] [log] [blame]
niklase@google.com470e71d2011-07-07 08:21:25 +00001/*
stefan@webrtc.org439be292012-02-16 14:45:37 +00002 * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
niklase@google.com470e71d2011-07-07 08:21:25 +00003 *
4 * Use of this source code is governed by a BSD-style license
5 * that can be found in the LICENSE file in the root of the source
6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree.
9 */
10
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +000011#include "video_engine/vie_codec_impl.h"
niklase@google.com470e71d2011-07-07 08:21:25 +000012
mflodman@webrtc.orgd6ec3862012-10-25 11:30:29 +000013#include <list>
14
mflodman@webrtc.org9ba151b2012-06-21 10:02:13 +000015#include "engine_configurations.h" // NOLINT
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +000016#include "modules/video_coding/main/interface/video_coding.h"
mflodman@webrtc.org4aee6b62012-12-14 14:02:10 +000017#include "system_wrappers/interface/logging.h"
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +000018#include "system_wrappers/interface/trace.h"
mflodman@webrtc.orga4863db2011-12-22 08:51:52 +000019#include "video_engine/include/vie_errors.h"
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +000020#include "video_engine/vie_capturer.h"
21#include "video_engine/vie_channel.h"
22#include "video_engine/vie_channel_manager.h"
23#include "video_engine/vie_defines.h"
24#include "video_engine/vie_encoder.h"
25#include "video_engine/vie_impl.h"
26#include "video_engine/vie_input_manager.h"
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +000027#include "video_engine/vie_shared_data.h"
niklase@google.com470e71d2011-07-07 08:21:25 +000028
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +000029namespace webrtc {
niklase@google.com470e71d2011-07-07 08:21:25 +000030
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +000031ViECodec* ViECodec::GetInterface(VideoEngine* video_engine) {
niklase@google.com470e71d2011-07-07 08:21:25 +000032#ifdef WEBRTC_VIDEO_ENGINE_CODEC_API
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +000033 if (!video_engine) {
niklase@google.com470e71d2011-07-07 08:21:25 +000034 return NULL;
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +000035 }
36 VideoEngineImpl* vie_impl = reinterpret_cast<VideoEngineImpl*>(video_engine);
37 ViECodecImpl* vie_codec_impl = vie_impl;
38 // Increase ref count.
39 (*vie_codec_impl)++;
40 return vie_codec_impl;
41#else
42 return NULL;
niklase@google.com470e71d2011-07-07 08:21:25 +000043#endif
44}
45
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +000046int ViECodecImpl::Release() {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +000047 WEBRTC_TRACE(kTraceApiCall, kTraceVideo, shared_data_->instance_id(),
niklase@google.com470e71d2011-07-07 08:21:25 +000048 "ViECodecImpl::Release()");
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +000049 // Decrease ref count.
50 (*this)--;
niklase@google.com470e71d2011-07-07 08:21:25 +000051
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +000052 WebRtc_Word32 ref_count = GetCount();
53 if (ref_count < 0) {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +000054 WEBRTC_TRACE(kTraceWarning, kTraceVideo, shared_data_->instance_id(),
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +000055 "ViECodec released too many times");
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +000056 shared_data_->SetLastError(kViEAPIDoesNotExist);
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +000057 return -1;
58 }
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +000059 WEBRTC_TRACE(kTraceInfo, kTraceVideo, shared_data_->instance_id(),
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +000060 "ViECodec reference count: %d", ref_count);
61 return ref_count;
niklase@google.com470e71d2011-07-07 08:21:25 +000062}
63
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +000064ViECodecImpl::ViECodecImpl(ViESharedData* shared_data)
65 : shared_data_(shared_data) {
66 WEBRTC_TRACE(kTraceMemory, kTraceVideo, shared_data_->instance_id(),
niklase@google.com470e71d2011-07-07 08:21:25 +000067 "ViECodecImpl::ViECodecImpl() Ctor");
68}
69
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +000070ViECodecImpl::~ViECodecImpl() {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +000071 WEBRTC_TRACE(kTraceMemory, kTraceVideo, shared_data_->instance_id(),
niklase@google.com470e71d2011-07-07 08:21:25 +000072 "ViECodecImpl::~ViECodecImpl() Dtor");
73}
74
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +000075int ViECodecImpl::NumberOfCodecs() const {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +000076 WEBRTC_TRACE(kTraceApiCall, kTraceVideo, ViEId(shared_data_->instance_id()),
77 "%s", __FUNCTION__);
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +000078 // +2 because of FEC(RED and ULPFEC)
79 return static_cast<int>((VideoCodingModule::NumberOfCodecs() + 2));
niklase@google.com470e71d2011-07-07 08:21:25 +000080}
81
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +000082int ViECodecImpl::GetCodec(const unsigned char list_number,
83 VideoCodec& video_codec) const {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +000084 WEBRTC_TRACE(kTraceApiCall, kTraceVideo, ViEId(shared_data_->instance_id()),
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +000085 "%s(list_number: %d, codec_type: %d)", __FUNCTION__,
86 list_number, video_codec.codecType);
87 if (list_number == VideoCodingModule::NumberOfCodecs()) {
88 memset(&video_codec, 0, sizeof(VideoCodec));
mflodman@webrtc.org9ba151b2012-06-21 10:02:13 +000089 strncpy(video_codec.plName, "red", 3);
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +000090 video_codec.codecType = kVideoCodecRED;
91 video_codec.plType = VCM_RED_PAYLOAD_TYPE;
92 } else if (list_number == VideoCodingModule::NumberOfCodecs() + 1) {
93 memset(&video_codec, 0, sizeof(VideoCodec));
mflodman@webrtc.org9ba151b2012-06-21 10:02:13 +000094 strncpy(video_codec.plName, "ulpfec", 6);
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +000095 video_codec.codecType = kVideoCodecULPFEC;
96 video_codec.plType = VCM_ULPFEC_PAYLOAD_TYPE;
97 } else if (VideoCodingModule::Codec(list_number, &video_codec) != VCM_OK) {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +000098 WEBRTC_TRACE(kTraceApiCall, kTraceVideo, ViEId(shared_data_->instance_id()),
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +000099 "%s: Could not get codec for list_number: %u", __FUNCTION__,
100 list_number);
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000101 shared_data_->SetLastError(kViECodecInvalidArgument);
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000102 return -1;
103 }
104 return 0;
niklase@google.com470e71d2011-07-07 08:21:25 +0000105}
106
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000107int ViECodecImpl::SetSendCodec(const int video_channel,
108 const VideoCodec& video_codec) {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000109 WEBRTC_TRACE(kTraceApiCall, kTraceVideo,
mflodman@webrtc.org9ba151b2012-06-21 10:02:13 +0000110 ViEId(shared_data_->instance_id(), video_channel),
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000111 "%s(video_channel: %d, codec_type: %d)", __FUNCTION__,
112 video_channel, video_codec.codecType);
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000113 WEBRTC_TRACE(kTraceInfo, kTraceVideo,
114 ViEId(shared_data_->instance_id(), video_channel),
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000115 "%s: codec: %d, pl_type: %d, width: %d, height: %d, bitrate: %d"
mflodman@webrtc.org9c0aedc2012-01-03 13:46:49 +0000116 "maxBr: %d, min_br: %d, frame_rate: %d, qpMax: %u,"
117 "numberOfSimulcastStreams: %u )", __FUNCTION__,
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000118 video_codec.codecType, video_codec.plType, video_codec.width,
119 video_codec.height, video_codec.startBitrate,
120 video_codec.maxBitrate, video_codec.minBitrate,
mflodman@webrtc.org9c0aedc2012-01-03 13:46:49 +0000121 video_codec.maxFramerate, video_codec.qpMax,
122 video_codec.numberOfSimulcastStreams);
123 if (video_codec.codecType == kVideoCodecVP8) {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000124 WEBRTC_TRACE(kTraceInfo, kTraceVideo,
125 ViEId(shared_data_->instance_id(), video_channel),
mflodman@webrtc.org9c0aedc2012-01-03 13:46:49 +0000126 "pictureLossIndicationOn: %d, feedbackModeOn: %d, "
mikhal@webrtc.orge07c6612013-01-31 16:37:13 +0000127 "complexity: %d, resilience: %d, numberOfTemporalLayers: %u"
128 "keyFrameInterval %d",
mflodman@webrtc.org9c0aedc2012-01-03 13:46:49 +0000129 video_codec.codecSpecific.VP8.pictureLossIndicationOn,
130 video_codec.codecSpecific.VP8.feedbackModeOn,
131 video_codec.codecSpecific.VP8.complexity,
132 video_codec.codecSpecific.VP8.resilience,
mikhal@webrtc.orge07c6612013-01-31 16:37:13 +0000133 video_codec.codecSpecific.VP8.numberOfTemporalLayers,
134 video_codec.codecSpecific.VP8.keyFrameInterval);
mflodman@webrtc.org9c0aedc2012-01-03 13:46:49 +0000135 }
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000136 if (!CodecValid(video_codec)) {
137 // Error logged.
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000138 shared_data_->SetLastError(kViECodecInvalidCodec);
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000139 return -1;
140 }
stefan@webrtc.org791eec72011-10-11 07:53:43 +0000141
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000142 ViEChannelManagerScoped cs(*(shared_data_->channel_manager()));
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000143 ViEChannel* vie_channel = cs.Channel(video_channel);
144 if (!vie_channel) {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000145 WEBRTC_TRACE(kTraceError, kTraceVideo,
146 ViEId(shared_data_->instance_id(), video_channel),
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000147 "%s: No channel %d", __FUNCTION__, video_channel);
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000148 shared_data_->SetLastError(kViECodecInvalidChannelId);
stefan@webrtc.org791eec72011-10-11 07:53:43 +0000149 return -1;
150 }
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000151
mflodman@webrtc.org9ec883e2012-03-05 17:12:41 +0000152 ViEEncoder* vie_encoder = cs.Encoder(video_channel);
153 assert(vie_encoder);
154 if (vie_encoder->Owner() != video_channel) {
155 WEBRTC_TRACE(kTraceError, kTraceVideo,
156 ViEId(shared_data_->instance_id(), video_channel),
157 "%s: Receive only channel %d", __FUNCTION__, video_channel);
158 shared_data_->SetLastError(kViECodecReceiveOnlyChannel);
159 return -1;
160 }
161
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000162 // Set a max_bitrate if the user hasn't set one.
163 VideoCodec video_codec_internal;
164 memcpy(&video_codec_internal, &video_codec, sizeof(VideoCodec));
165 if (video_codec_internal.maxBitrate == 0) {
166 // Max is one bit per pixel.
167 video_codec_internal.maxBitrate = (video_codec_internal.width *
168 video_codec_internal.height *
169 video_codec_internal.maxFramerate)
170 / 1000;
171 if (video_codec_internal.startBitrate > video_codec_internal.maxBitrate) {
172 // Don't limit the set start bitrate.
173 video_codec_internal.maxBitrate = video_codec_internal.startBitrate;
174 }
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000175 WEBRTC_TRACE(kTraceInfo, kTraceVideo,
176 ViEId(shared_data_->instance_id(), video_channel),
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000177 "%s: New max bitrate set to %d kbps", __FUNCTION__,
178 video_codec_internal.maxBitrate);
179 }
180
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000181 VideoCodec encoder;
mflodman@webrtc.orgf5e99db2012-06-27 09:49:37 +0000182 vie_encoder->GetEncoder(&encoder);
mflodman@webrtc.org9ec883e2012-03-05 17:12:41 +0000183
mflodman@webrtc.org9c0aedc2012-01-03 13:46:49 +0000184 // Make sure to generate a new SSRC if the codec type and/or resolution has
185 // changed. This won't have any effect if the user has set an SSRC.
186 bool new_rtp_stream = false;
stefan@webrtc.org4e8eaba2012-08-20 14:29:52 +0000187 if (encoder.codecType != video_codec_internal.codecType) {
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000188 new_rtp_stream = true;
189 }
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000190
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000191 ViEInputManagerScoped is(*(shared_data_->input_manager()));
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000192 ViEFrameProviderBase* frame_provider = NULL;
193
194 // Stop the media flow while reconfiguring.
195 vie_encoder->Pause();
196
197 // Check if we have a frame provider that is a camera and can provide this
198 // codec for us.
199 bool use_capture_device_as_encoder = false;
200 frame_provider = is.FrameProvider(vie_encoder);
201 if (frame_provider) {
202 if (frame_provider->Id() >= kViECaptureIdBase &&
203 frame_provider->Id() <= kViECaptureIdMax) {
204 ViECapturer* vie_capture = static_cast<ViECapturer*>(frame_provider);
205 // Try to get preencoded. Nothing to do if it is not supported.
206 if (vie_capture && vie_capture->PreEncodeToViEEncoder(
207 video_codec_internal,
208 *vie_encoder,
209 video_channel) == 0) {
210 use_capture_device_as_encoder = true;
211 }
212 }
213 }
214
215 // Update the encoder settings if we are not using a capture device capable
216 // of this codec.
217 if (!use_capture_device_as_encoder &&
218 vie_encoder->SetEncoder(video_codec_internal) != 0) {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000219 WEBRTC_TRACE(kTraceError, kTraceVideo,
220 ViEId(shared_data_->instance_id(), video_channel),
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000221 "%s: Could not change encoder for channel %d", __FUNCTION__,
222 video_channel);
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000223 shared_data_->SetLastError(kViECodecUnknownError);
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000224 return -1;
225 }
226
mflodman@webrtc.org9c0aedc2012-01-03 13:46:49 +0000227 // Give the channel(s) the new information.
228 ChannelList channels;
229 cs.ChannelsUsingViEEncoder(video_channel, &channels);
230 for (ChannelList::iterator it = channels.begin(); it != channels.end();
231 ++it) {
232 bool ret = true;
233 if ((*it)->SetSendCodec(video_codec_internal, new_rtp_stream) != 0) {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000234 WEBRTC_TRACE(kTraceError, kTraceVideo,
235 ViEId(shared_data_->instance_id(), video_channel),
mflodman@webrtc.org9c0aedc2012-01-03 13:46:49 +0000236 "%s: Could not set send codec for channel %d", __FUNCTION__,
237 video_channel);
238 ret = false;
239 }
240 if (!ret) {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000241 shared_data_->SetLastError(kViECodecUnknownError);
mflodman@webrtc.org9c0aedc2012-01-03 13:46:49 +0000242 return -1;
243 }
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000244 }
245
mflodman@webrtc.orgd6ec3862012-10-25 11:30:29 +0000246 // TODO(mflodman) Break out this part in GetLocalSsrcList().
247 // Update all SSRCs to ViEEncoder.
248 std::list<unsigned int> ssrcs;
249 if (video_codec_internal.numberOfSimulcastStreams == 0) {
250 unsigned int ssrc = 0;
251 if (vie_channel->GetLocalSSRC(0, &ssrc) != 0) {
252 WEBRTC_TRACE(kTraceError, kTraceVideo,
253 ViEId(shared_data_->instance_id(), video_channel),
254 "%s: Could not get ssrc", __FUNCTION__);
255 }
256 ssrcs.push_back(ssrc);
257 } else {
258 for (int idx = 0; idx < video_codec_internal.numberOfSimulcastStreams;
259 ++idx) {
260 unsigned int ssrc = 0;
261 if (vie_channel->GetLocalSSRC(idx, &ssrc) != 0) {
262 WEBRTC_TRACE(kTraceError, kTraceVideo,
263 ViEId(shared_data_->instance_id(), video_channel),
264 "%s: Could not get ssrc for idx %d", __FUNCTION__, idx);
265 }
266 ssrcs.push_back(ssrc);
267 }
268 }
269 vie_encoder->SetSsrcs(ssrcs);
270 shared_data_->channel_manager()->UpdateSsrcs(video_channel, ssrcs);
271
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000272 // Update the protection mode, we might be switching NACK/FEC.
273 vie_encoder->UpdateProtectionMethod();
274
275 // Get new best format for frame provider.
276 if (frame_provider) {
277 frame_provider->FrameCallbackChanged();
278 }
279 // Restart the media flow
280 if (new_rtp_stream) {
281 // Stream settings changed, make sure we get a key frame.
282 vie_encoder->SendKeyFrame();
283 }
284 vie_encoder->Restart();
285 return 0;
stefan@webrtc.org791eec72011-10-11 07:53:43 +0000286}
287
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000288int ViECodecImpl::GetSendCodec(const int video_channel,
289 VideoCodec& video_codec) const {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000290 WEBRTC_TRACE(kTraceApiCall, kTraceVideo,
291 ViEId(shared_data_->instance_id(), video_channel),
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000292 "%s(video_channel: %d)", __FUNCTION__, video_channel);
niklase@google.com470e71d2011-07-07 08:21:25 +0000293
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000294 ViEChannelManagerScoped cs(*(shared_data_->channel_manager()));
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000295 ViEEncoder* vie_encoder = cs.Encoder(video_channel);
296 if (!vie_encoder) {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000297 WEBRTC_TRACE(kTraceError, kTraceVideo,
298 ViEId(shared_data_->instance_id(), video_channel),
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000299 "%s: No encoder for channel %d", __FUNCTION__, video_channel);
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000300 shared_data_->SetLastError(kViECodecInvalidChannelId);
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000301 return -1;
302 }
mflodman@webrtc.orgf5e99db2012-06-27 09:49:37 +0000303 return vie_encoder->GetEncoder(&video_codec);
niklase@google.com470e71d2011-07-07 08:21:25 +0000304}
305
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000306int ViECodecImpl::SetReceiveCodec(const int video_channel,
307 const VideoCodec& video_codec) {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000308 WEBRTC_TRACE(kTraceApiCall, kTraceVideo,
309 ViEId(shared_data_->instance_id(), video_channel),
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000310 "%s(video_channel: %d, codec_type: %d)", __FUNCTION__,
311 video_channel, video_codec.codecType);
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000312 WEBRTC_TRACE(kTraceInfo, kTraceVideo,
313 ViEId(shared_data_->instance_id(), video_channel),
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000314 "%s: codec: %d, pl_type: %d, width: %d, height: %d, bitrate: %d,"
315 "maxBr: %d, min_br: %d, frame_rate: %d", __FUNCTION__,
316 video_codec.codecType, video_codec.plType, video_codec.width,
317 video_codec.height, video_codec.startBitrate,
318 video_codec.maxBitrate, video_codec.minBitrate,
319 video_codec.maxFramerate);
niklase@google.com470e71d2011-07-07 08:21:25 +0000320
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000321 if (CodecValid(video_codec) == false) {
322 // Error logged.
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000323 shared_data_->SetLastError(kViECodecInvalidCodec);
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000324 return -1;
325 }
326
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000327 ViEChannelManagerScoped cs(*(shared_data_->channel_manager()));
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000328 ViEChannel* vie_channel = cs.Channel(video_channel);
329 if (!vie_channel) {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000330 WEBRTC_TRACE(kTraceError, kTraceVideo,
331 ViEId(shared_data_->instance_id(), video_channel),
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000332 "%s: No channel %d", __FUNCTION__, video_channel);
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000333 shared_data_->SetLastError(kViECodecInvalidChannelId);
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000334 return -1;
335 }
336
337 if (vie_channel->SetReceiveCodec(video_codec) != 0) {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000338 WEBRTC_TRACE(kTraceError, kTraceVideo,
339 ViEId(shared_data_->instance_id(), video_channel),
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000340 "%s: Could not set receive codec for channel %d",
341 __FUNCTION__, video_channel);
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000342 shared_data_->SetLastError(kViECodecUnknownError);
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000343 return -1;
344 }
345 return 0;
346}
347
348int ViECodecImpl::GetReceiveCodec(const int video_channel,
349 VideoCodec& video_codec) const {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000350 WEBRTC_TRACE(kTraceApiCall, kTraceVideo,
351 ViEId(shared_data_->instance_id(), video_channel),
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000352 "%s(video_channel: %d, codec_type: %d)", __FUNCTION__,
353 video_channel, video_codec.codecType);
354
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000355 ViEChannelManagerScoped cs(*(shared_data_->channel_manager()));
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000356 ViEChannel* vie_channel = cs.Channel(video_channel);
357 if (!vie_channel) {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000358 WEBRTC_TRACE(kTraceError, kTraceVideo,
359 ViEId(shared_data_->instance_id(), video_channel),
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000360 "%s: No channel %d", __FUNCTION__, video_channel);
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000361 shared_data_->SetLastError(kViECodecInvalidChannelId);
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000362 return -1;
363 }
364
mflodman@webrtc.orgf5e99db2012-06-27 09:49:37 +0000365 if (vie_channel->GetReceiveCodec(&video_codec) != 0) {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000366 shared_data_->SetLastError(kViECodecUnknownError);
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000367 return -1;
368 }
369 return 0;
370}
371
372int ViECodecImpl::GetCodecConfigParameters(
373 const int video_channel,
374 unsigned char config_parameters[kConfigParameterSize],
375 unsigned char& config_parameters_size) const {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000376 WEBRTC_TRACE(kTraceApiCall, kTraceVideo,
377 ViEId(shared_data_->instance_id(), video_channel),
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000378 "%s(video_channel: %d)", __FUNCTION__, video_channel);
379
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000380 ViEChannelManagerScoped cs(*(shared_data_->channel_manager()));
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000381 ViEEncoder* vie_encoder = cs.Encoder(video_channel);
382 if (!vie_encoder) {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000383 WEBRTC_TRACE(kTraceError, kTraceVideo,
384 ViEId(shared_data_->instance_id(), video_channel),
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000385 "%s: No encoder for channel %d", __FUNCTION__, video_channel);
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000386 shared_data_->SetLastError(kViECodecInvalidChannelId);
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000387 return -1;
388 }
389
390 if (vie_encoder->GetCodecConfigParameters(config_parameters,
391 config_parameters_size) != 0) {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000392 shared_data_->SetLastError(kViECodecUnknownError);
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000393 return -1;
394 }
395 return 0;
396}
397
398int ViECodecImpl::SetImageScaleStatus(const int video_channel,
399 const bool enable) {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000400 WEBRTC_TRACE(kTraceApiCall, kTraceVideo,
401 ViEId(shared_data_->instance_id(), video_channel),
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000402 "%s(video_channel: %d, enable: %d)", __FUNCTION__, video_channel,
403 enable);
404
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000405 ViEChannelManagerScoped cs(*(shared_data_->channel_manager()));
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000406 ViEEncoder* vie_encoder = cs.Encoder(video_channel);
407 if (!vie_encoder) {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000408 WEBRTC_TRACE(kTraceError, kTraceVideo,
409 ViEId(shared_data_->instance_id(), video_channel),
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000410 "%s: No channel %d", __FUNCTION__, video_channel);
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000411 shared_data_->SetLastError(kViECodecInvalidChannelId);
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000412 return -1;
413 }
414
415 if (vie_encoder->ScaleInputImage(enable) != 0) {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000416 shared_data_->SetLastError(kViECodecUnknownError);
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000417 return -1;
418 }
419 return 0;
420}
421
422int ViECodecImpl::GetSendCodecStastistics(const int video_channel,
423 unsigned int& key_frames,
424 unsigned int& delta_frames) const {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000425 WEBRTC_TRACE(kTraceApiCall, kTraceVideo,
426 ViEId(shared_data_->instance_id(), video_channel),
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000427 "%s(video_channel %d)", __FUNCTION__, video_channel);
428
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000429 ViEChannelManagerScoped cs(*(shared_data_->channel_manager()));
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000430 ViEEncoder* vie_encoder = cs.Encoder(video_channel);
431 if (!vie_encoder) {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000432 WEBRTC_TRACE(kTraceError, kTraceVideo,
433 ViEId(shared_data_->instance_id(), video_channel),
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000434 "%s: No send codec for channel %d", __FUNCTION__,
435 video_channel);
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000436 shared_data_->SetLastError(kViECodecInvalidChannelId);
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000437 return -1;
438 }
439
mflodman@webrtc.orgf5e99db2012-06-27 09:49:37 +0000440 if (vie_encoder->SendCodecStatistics(&key_frames, &delta_frames) != 0) {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000441 shared_data_->SetLastError(kViECodecUnknownError);
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000442 return -1;
443 }
444 return 0;
445}
446
447int ViECodecImpl::GetReceiveCodecStastistics(const int video_channel,
448 unsigned int& key_frames,
449 unsigned int& delta_frames) const {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000450 WEBRTC_TRACE(kTraceApiCall, kTraceVideo,
451 ViEId(shared_data_->instance_id(), video_channel),
mflodman@webrtc.org4aee6b62012-12-14 14:02:10 +0000452 "%s(video_channel: %d)", __FUNCTION__,
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000453 video_channel);
454
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000455 ViEChannelManagerScoped cs(*(shared_data_->channel_manager()));
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000456 ViEChannel* vie_channel = cs.Channel(video_channel);
457 if (!vie_channel) {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000458 WEBRTC_TRACE(kTraceError, kTraceVideo,
459 ViEId(shared_data_->instance_id(), video_channel),
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000460 "%s: No channel %d", __FUNCTION__, video_channel);
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000461 shared_data_->SetLastError(kViECodecInvalidChannelId);
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000462 return -1;
463 }
mflodman@webrtc.orgf5e99db2012-06-27 09:49:37 +0000464 if (vie_channel->ReceiveCodecStatistics(&key_frames, &delta_frames) != 0) {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000465 shared_data_->SetLastError(kViECodecUnknownError);
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000466 return -1;
467 }
468 return 0;
469}
470
mflodman@webrtc.org4aee6b62012-12-14 14:02:10 +0000471int ViECodecImpl::GetReceiveSideDelay(const int video_channel,
472 int* delay_ms) const {
473 WEBRTC_TRACE(kTraceApiCall, kTraceVideo,
474 ViEId(shared_data_->instance_id(), video_channel),
475 "%s(video_channel: %d)", __FUNCTION__, video_channel);
476 if (delay_ms == NULL) {
477 LOG_F(LS_ERROR) << "NULL pointer argument.";
478 return -1;
479 }
480
481 ViEChannelManagerScoped cs(*(shared_data_->channel_manager()));
482 ViEChannel* vie_channel = cs.Channel(video_channel);
483 if (!vie_channel) {
484 WEBRTC_TRACE(kTraceError, kTraceVideo,
485 ViEId(shared_data_->instance_id(), video_channel),
486 "%s: No channel %d", __FUNCTION__, video_channel);
487 shared_data_->SetLastError(kViECodecInvalidChannelId);
488 return -1;
489 }
490 *delay_ms = vie_channel->ReceiveDelay();
491 if (*delay_ms < 0) {
492 return -1;
493 }
494 return 0;
495}
496
497
stefan@webrtc.org439be292012-02-16 14:45:37 +0000498int ViECodecImpl::GetCodecTargetBitrate(const int video_channel,
499 unsigned int* bitrate) const {
500 WEBRTC_TRACE(kTraceApiCall, kTraceVideo,
501 ViEId(shared_data_->instance_id(), video_channel),
502 "%s(video_channel: %d, codec_type: %d)", __FUNCTION__,
503 video_channel);
504
505 ViEChannelManagerScoped cs(*(shared_data_->channel_manager()));
506 ViEEncoder* vie_encoder = cs.Encoder(video_channel);
507 if (!vie_encoder) {
508 WEBRTC_TRACE(kTraceError, kTraceVideo,
509 ViEId(shared_data_->instance_id(), video_channel),
510 "%s: No send codec for channel %d", __FUNCTION__,
511 video_channel);
512 shared_data_->SetLastError(kViECodecInvalidChannelId);
513 return -1;
514 }
515 return vie_encoder->CodecTargetBitrate(static_cast<WebRtc_UWord32*>(bitrate));
516}
517
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000518unsigned int ViECodecImpl::GetDiscardedPackets(const int video_channel) const {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000519 WEBRTC_TRACE(kTraceApiCall, kTraceVideo,
520 ViEId(shared_data_->instance_id(), video_channel),
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000521 "%s(video_channel: %d, codec_type: %d)", __FUNCTION__,
522 video_channel);
523
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000524 ViEChannelManagerScoped cs(*(shared_data_->channel_manager()));
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000525 ViEChannel* vie_channel = cs.Channel(video_channel);
526 if (!vie_channel) {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000527 WEBRTC_TRACE(kTraceError, kTraceVideo,
528 ViEId(shared_data_->instance_id(), video_channel),
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000529 "%s: No channel %d", __FUNCTION__, video_channel);
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000530 shared_data_->SetLastError(kViECodecInvalidChannelId);
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000531 return -1;
532 }
533 return vie_channel->DiscardedPackets();
534}
535
536int ViECodecImpl::SetKeyFrameRequestCallbackStatus(const int video_channel,
537 const bool enable) {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000538 WEBRTC_TRACE(kTraceApiCall, kTraceVideo,
539 ViEId(shared_data_->instance_id(), video_channel),
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000540 "%s(video_channel: %d)", __FUNCTION__, video_channel);
541
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000542 ViEChannelManagerScoped cs(*(shared_data_->channel_manager()));
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000543 ViEChannel* vie_channel = cs.Channel(video_channel);
544 if (!vie_channel) {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000545 WEBRTC_TRACE(kTraceError, kTraceVideo,
546 ViEId(shared_data_->instance_id(), video_channel),
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000547 "%s: No channel %d", __FUNCTION__, video_channel);
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000548 shared_data_->SetLastError(kViECodecInvalidChannelId);
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000549 return -1;
550 }
551 if (vie_channel->EnableKeyFrameRequestCallback(enable) != 0) {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000552 shared_data_->SetLastError(kViECodecUnknownError);
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000553 return -1;
554 }
555 return 0;
556}
557
558int ViECodecImpl::SetSignalKeyPacketLossStatus(const int video_channel,
niklase@google.com470e71d2011-07-07 08:21:25 +0000559 const bool enable,
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000560 const bool only_key_frames) {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000561 WEBRTC_TRACE(kTraceApiCall, kTraceVideo,
562 ViEId(shared_data_->instance_id(), video_channel),
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000563 "%s(video_channel: %d, enable: %d, only_key_frames: %d)",
564 __FUNCTION__, video_channel, enable);
niklase@google.com470e71d2011-07-07 08:21:25 +0000565
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000566 ViEChannelManagerScoped cs(*(shared_data_->channel_manager()));
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000567 ViEChannel* vie_channel = cs.Channel(video_channel);
568 if (!vie_channel) {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000569 WEBRTC_TRACE(kTraceError, kTraceVideo,
570 ViEId(shared_data_->instance_id(), video_channel),
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000571 "%s: No channel %d", __FUNCTION__, video_channel);
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000572 shared_data_->SetLastError(kViECodecInvalidChannelId);
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000573 return -1;
574 }
575 if (vie_channel->SetSignalPacketLossStatus(enable, only_key_frames) != 0) {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000576 shared_data_->SetLastError(kViECodecUnknownError);
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000577 return -1;
578 }
579 return 0;
niklase@google.com470e71d2011-07-07 08:21:25 +0000580}
581
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000582int ViECodecImpl::RegisterEncoderObserver(const int video_channel,
583 ViEEncoderObserver& observer) {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000584 WEBRTC_TRACE(kTraceApiCall, kTraceVideo, ViEId(shared_data_->instance_id()),
585 "%s", __FUNCTION__);
niklase@google.com470e71d2011-07-07 08:21:25 +0000586
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000587 ViEChannelManagerScoped cs(*(shared_data_->channel_manager()));
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000588 ViEEncoder* vie_encoder = cs.Encoder(video_channel);
589 if (!vie_encoder) {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000590 WEBRTC_TRACE(kTraceError, kTraceVideo,
591 ViEId(shared_data_->instance_id(), video_channel),
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000592 "%s: No encoder for channel %d", __FUNCTION__, video_channel);
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000593 shared_data_->SetLastError(kViECodecInvalidChannelId);
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000594 return -1;
595 }
596 if (vie_encoder->RegisterCodecObserver(&observer) != 0) {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000597 WEBRTC_TRACE(kTraceError, kTraceVideo,
598 ViEId(shared_data_->instance_id(), video_channel),
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000599 "%s: Could not register codec observer at channel",
600 __FUNCTION__);
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000601 shared_data_->SetLastError(kViECodecObserverAlreadyRegistered);
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000602 return -1;
603 }
604 return 0;
niklase@google.com470e71d2011-07-07 08:21:25 +0000605}
606
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000607int ViECodecImpl::DeregisterEncoderObserver(const int video_channel) {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000608 WEBRTC_TRACE(kTraceApiCall, kTraceVideo, ViEId(shared_data_->instance_id()),
609 "%s", __FUNCTION__);
niklase@google.com470e71d2011-07-07 08:21:25 +0000610
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000611 ViEChannelManagerScoped cs(*(shared_data_->channel_manager()));
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000612 ViEEncoder* vie_encoder = cs.Encoder(video_channel);
613 if (!vie_encoder) {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000614 WEBRTC_TRACE(kTraceError, kTraceVideo,
615 ViEId(shared_data_->instance_id(), video_channel),
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000616 "%s: No encoder for channel %d", __FUNCTION__, video_channel);
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000617 shared_data_->SetLastError(kViECodecInvalidChannelId);
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000618 return -1;
619 }
620 if (vie_encoder->RegisterCodecObserver(NULL) != 0) {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000621 shared_data_->SetLastError(kViECodecObserverNotRegistered);
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000622 return -1;
623 }
624 return 0;
niklase@google.com470e71d2011-07-07 08:21:25 +0000625}
626
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000627int ViECodecImpl::RegisterDecoderObserver(const int video_channel,
628 ViEDecoderObserver& observer) {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000629 WEBRTC_TRACE(kTraceApiCall, kTraceVideo, ViEId(shared_data_->instance_id()),
630 "%s", __FUNCTION__);
niklase@google.com470e71d2011-07-07 08:21:25 +0000631
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000632 ViEChannelManagerScoped cs(*(shared_data_->channel_manager()));
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000633 ViEChannel* vie_channel = cs.Channel(video_channel);
634 if (!vie_channel) {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000635 WEBRTC_TRACE(kTraceError, kTraceVideo,
636 ViEId(shared_data_->instance_id(), video_channel),
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000637 "%s: No channel %d", __FUNCTION__, video_channel);
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000638 shared_data_->SetLastError(kViECodecInvalidChannelId);
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000639 return -1;
640 }
641 if (vie_channel->RegisterCodecObserver(&observer) != 0) {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000642 WEBRTC_TRACE(kTraceError, kTraceVideo,
643 ViEId(shared_data_->instance_id(), video_channel),
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000644 "%s: Could not register codec observer at channel",
645 __FUNCTION__);
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000646 shared_data_->SetLastError(kViECodecObserverAlreadyRegistered);
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000647 return -1;
648 }
649 return 0;
niklase@google.com470e71d2011-07-07 08:21:25 +0000650}
651
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000652int ViECodecImpl::DeregisterDecoderObserver(const int video_channel) {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000653 WEBRTC_TRACE(kTraceApiCall, kTraceVideo,
654 ViEId(shared_data_->instance_id()), "%s",
niklase@google.com470e71d2011-07-07 08:21:25 +0000655 __FUNCTION__);
656
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000657 ViEChannelManagerScoped cs(*(shared_data_->channel_manager()));
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000658 ViEChannel* vie_channel = cs.Channel(video_channel);
659 if (!vie_channel) {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000660 WEBRTC_TRACE(kTraceError, kTraceVideo,
661 ViEId(shared_data_->instance_id(), video_channel),
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000662 "%s: No channel %d", __FUNCTION__, video_channel);
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000663 shared_data_->SetLastError(kViECodecInvalidChannelId);
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000664 return -1;
665 }
666 if (vie_channel->RegisterCodecObserver(NULL) != 0) {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000667 shared_data_->SetLastError(kViECodecObserverNotRegistered);
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000668 return -1;
669 }
670 return 0;
niklase@google.com470e71d2011-07-07 08:21:25 +0000671}
672
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000673int ViECodecImpl::SendKeyFrame(const int video_channel) {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000674 WEBRTC_TRACE(kTraceApiCall, kTraceVideo, ViEId(shared_data_->instance_id()),
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000675 "%s(video_channel: %d)", __FUNCTION__, video_channel);
niklase@google.com470e71d2011-07-07 08:21:25 +0000676
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000677 ViEChannelManagerScoped cs(*(shared_data_->channel_manager()));
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000678 ViEEncoder* vie_encoder = cs.Encoder(video_channel);
679 if (!vie_encoder) {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000680 WEBRTC_TRACE(kTraceError, kTraceVideo,
681 ViEId(shared_data_->instance_id(), video_channel),
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000682 "%s: No channel %d", __FUNCTION__, video_channel);
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000683 shared_data_->SetLastError(kViECodecInvalidChannelId);
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000684 return -1;
685 }
686 if (vie_encoder->SendKeyFrame() != 0) {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000687 shared_data_->SetLastError(kViECodecUnknownError);
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000688 return -1;
689 }
690 return 0;
niklase@google.com470e71d2011-07-07 08:21:25 +0000691}
692
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000693int ViECodecImpl::WaitForFirstKeyFrame(const int video_channel,
694 const bool wait) {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000695 WEBRTC_TRACE(kTraceApiCall, kTraceVideo,
696 ViEId(shared_data_->instance_id()),
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000697 "%s(video_channel: %d, wait: %d)", __FUNCTION__, video_channel,
niklase@google.com470e71d2011-07-07 08:21:25 +0000698 wait);
699
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000700 ViEChannelManagerScoped cs(*(shared_data_->channel_manager()));
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000701 ViEChannel* vie_channel = cs.Channel(video_channel);
702 if (!vie_channel) {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000703 WEBRTC_TRACE(kTraceError, kTraceVideo,
704 ViEId(shared_data_->instance_id(), video_channel),
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000705 "%s: No channel %d", __FUNCTION__, video_channel);
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000706 shared_data_->SetLastError(kViECodecInvalidChannelId);
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000707 return -1;
708 }
709 if (vie_channel->WaitForKeyFrame(wait) != 0) {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000710 shared_data_->SetLastError(kViECodecUnknownError);
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000711 return -1;
712 }
713 return 0;
niklase@google.com470e71d2011-07-07 08:21:25 +0000714}
715
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000716bool ViECodecImpl::CodecValid(const VideoCodec& video_codec) {
717 // Check pl_name matches codec_type.
718 if (video_codec.codecType == kVideoCodecRED) {
niklase@google.com470e71d2011-07-07 08:21:25 +0000719#if defined(WIN32)
mflodman@webrtc.org1fe2ada2011-12-21 12:23:15 +0000720 if (_strnicmp(video_codec.plName, "red", 3) == 0) {
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000721#else
722 if (strncasecmp(video_codec.plName, "red", 3) == 0) {
niklase@google.com470e71d2011-07-07 08:21:25 +0000723#endif
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000724 // We only care about the type and name for red.
725 return true;
niklase@google.com470e71d2011-07-07 08:21:25 +0000726 }
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000727 WEBRTC_TRACE(kTraceError, kTraceVideo, -1,
728 "Codec type doesn't match pl_name", video_codec.plType);
729 return false;
730 } else if (video_codec.codecType == kVideoCodecULPFEC) {
niklase@google.com470e71d2011-07-07 08:21:25 +0000731#if defined(WIN32)
mflodman@webrtc.org1fe2ada2011-12-21 12:23:15 +0000732 if (_strnicmp(video_codec.plName, "ULPFEC", 6) == 0) {
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000733#else
734 if (strncasecmp(video_codec.plName, "ULPFEC", 6) == 0) {
niklase@google.com470e71d2011-07-07 08:21:25 +0000735#endif
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000736 // We only care about the type and name for ULPFEC.
737 return true;
niklase@google.com470e71d2011-07-07 08:21:25 +0000738 }
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000739 WEBRTC_TRACE(kTraceError, kTraceVideo, -1,
740 "Codec type doesn't match pl_name", video_codec.plType);
741 return false;
pwestin@webrtc.org56210572012-01-17 12:45:47 +0000742 } else if ((video_codec.codecType == kVideoCodecVP8 &&
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000743 strncmp(video_codec.plName, "VP8", 4) == 0) ||
744 (video_codec.codecType == kVideoCodecI420 &&
pwestin@webrtc.org56210572012-01-17 12:45:47 +0000745 strncmp(video_codec.plName, "I420", 4) == 0)) {
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000746 // OK.
747 } else {
748 WEBRTC_TRACE(kTraceError, kTraceVideo, -1,
749 "Codec type doesn't match pl_name", video_codec.plType);
750 return false;
751 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000752
braveyao@webrtc.org49273ff2013-01-14 01:52:26 +0000753 if (video_codec.plType == 0 || video_codec.plType > 127) {
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000754 WEBRTC_TRACE(kTraceError, kTraceVideo, -1,
755 "Invalid codec payload type: %d", video_codec.plType);
756 return false;
757 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000758
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000759 if (video_codec.width > kViEMaxCodecWidth ||
760 video_codec.height > kViEMaxCodecHeight) {
761 WEBRTC_TRACE(kTraceError, kTraceVideo, -1, "Invalid codec size: %u x %u",
762 video_codec.width, video_codec.height);
763 return false;
764 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000765
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000766 if (video_codec.startBitrate < kViEMinCodecBitrate) {
767 WEBRTC_TRACE(kTraceError, kTraceVideo, -1, "Invalid start_bitrate: %u",
768 video_codec.startBitrate);
769 return false;
770 }
771 if (video_codec.minBitrate < kViEMinCodecBitrate) {
772 WEBRTC_TRACE(kTraceError, kTraceVideo, -1, "Invalid min_bitrate: %u",
773 video_codec.minBitrate);
774 return false;
775 }
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000776 return true;
niklase@google.com470e71d2011-07-07 08:21:25 +0000777}
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000778
779} // namespace webrtc