blob: 94e4d7cadde6b1ff5c523e67890fb85ef7fa8170 [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
pbos@webrtc.orgf5d4cb12013-05-17 13:44:48 +000011#include "webrtc/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
pbos@webrtc.orgf5d4cb12013-05-17 13:44:48 +000015#include "webrtc/engine_configurations.h"
16#include "webrtc/modules/video_coding/main/interface/video_coding.h"
17#include "webrtc/system_wrappers/interface/logging.h"
18#include "webrtc/system_wrappers/interface/trace.h"
19#include "webrtc/video_engine/include/vie_errors.h"
20#include "webrtc/video_engine/vie_capturer.h"
21#include "webrtc/video_engine/vie_channel.h"
22#include "webrtc/video_engine/vie_channel_manager.h"
23#include "webrtc/video_engine/vie_defines.h"
24#include "webrtc/video_engine/vie_encoder.h"
25#include "webrtc/video_engine/vie_impl.h"
26#include "webrtc/video_engine/vie_input_manager.h"
27#include "webrtc/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 }
andrew@webrtc.orgd72262d2013-05-09 02:12:07 +000036 VideoEngineImpl* vie_impl = static_cast<VideoEngineImpl*>(video_engine);
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +000037 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
pbos@webrtc.orgb238d122013-04-09 13:41:51 +000052 int32_t ref_count = GetCount();
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +000053 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()),
pbos@webrtc.org65a1f2c2013-07-02 13:02:14 +000085 "%s(list_number: %d)", __FUNCTION__, list_number);
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +000086 if (list_number == VideoCodingModule::NumberOfCodecs()) {
87 memset(&video_codec, 0, sizeof(VideoCodec));
mflodman@webrtc.orgaeff4f32013-04-22 12:41:57 +000088 strcpy(video_codec.plName, "red");
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.orgaeff4f32013-04-22 12:41:57 +000093 strcpy(video_codec.plName, "ulpfec");
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, "
mikhal@webrtc.orge07c6612013-01-31 16:37:13 +0000126 "complexity: %d, resilience: %d, numberOfTemporalLayers: %u"
127 "keyFrameInterval %d",
mflodman@webrtc.org9c0aedc2012-01-03 13:46:49 +0000128 video_codec.codecSpecific.VP8.pictureLossIndicationOn,
129 video_codec.codecSpecific.VP8.feedbackModeOn,
130 video_codec.codecSpecific.VP8.complexity,
131 video_codec.codecSpecific.VP8.resilience,
mikhal@webrtc.orge07c6612013-01-31 16:37:13 +0000132 video_codec.codecSpecific.VP8.numberOfTemporalLayers,
133 video_codec.codecSpecific.VP8.keyFrameInterval);
mflodman@webrtc.org9c0aedc2012-01-03 13:46:49 +0000134 }
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000135 if (!CodecValid(video_codec)) {
136 // Error logged.
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000137 shared_data_->SetLastError(kViECodecInvalidCodec);
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000138 return -1;
139 }
stefan@webrtc.org791eec72011-10-11 07:53:43 +0000140
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000141 ViEChannelManagerScoped cs(*(shared_data_->channel_manager()));
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000142 ViEChannel* vie_channel = cs.Channel(video_channel);
143 if (!vie_channel) {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000144 WEBRTC_TRACE(kTraceError, kTraceVideo,
145 ViEId(shared_data_->instance_id(), video_channel),
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000146 "%s: No channel %d", __FUNCTION__, video_channel);
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000147 shared_data_->SetLastError(kViECodecInvalidChannelId);
stefan@webrtc.org791eec72011-10-11 07:53:43 +0000148 return -1;
149 }
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000150
mflodman@webrtc.org9ec883e2012-03-05 17:12:41 +0000151 ViEEncoder* vie_encoder = cs.Encoder(video_channel);
152 assert(vie_encoder);
153 if (vie_encoder->Owner() != video_channel) {
154 WEBRTC_TRACE(kTraceError, kTraceVideo,
155 ViEId(shared_data_->instance_id(), video_channel),
156 "%s: Receive only channel %d", __FUNCTION__, video_channel);
157 shared_data_->SetLastError(kViECodecReceiveOnlyChannel);
158 return -1;
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
191 // Stop the media flow while reconfiguring.
192 vie_encoder->Pause();
193
mflodman@webrtc.org3ba883f2013-06-07 13:57:57 +0000194 if (vie_encoder->SetEncoder(video_codec_internal) != 0) {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000195 WEBRTC_TRACE(kTraceError, kTraceVideo,
196 ViEId(shared_data_->instance_id(), video_channel),
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000197 "%s: Could not change encoder for channel %d", __FUNCTION__,
198 video_channel);
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000199 shared_data_->SetLastError(kViECodecUnknownError);
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000200 return -1;
201 }
202
mflodman@webrtc.org9c0aedc2012-01-03 13:46:49 +0000203 // Give the channel(s) the new information.
204 ChannelList channels;
205 cs.ChannelsUsingViEEncoder(video_channel, &channels);
206 for (ChannelList::iterator it = channels.begin(); it != channels.end();
207 ++it) {
208 bool ret = true;
209 if ((*it)->SetSendCodec(video_codec_internal, new_rtp_stream) != 0) {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000210 WEBRTC_TRACE(kTraceError, kTraceVideo,
211 ViEId(shared_data_->instance_id(), video_channel),
mflodman@webrtc.org9c0aedc2012-01-03 13:46:49 +0000212 "%s: Could not set send codec for channel %d", __FUNCTION__,
213 video_channel);
214 ret = false;
215 }
216 if (!ret) {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000217 shared_data_->SetLastError(kViECodecUnknownError);
mflodman@webrtc.org9c0aedc2012-01-03 13:46:49 +0000218 return -1;
219 }
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000220 }
221
mflodman@webrtc.orgd6ec3862012-10-25 11:30:29 +0000222 // TODO(mflodman) Break out this part in GetLocalSsrcList().
223 // Update all SSRCs to ViEEncoder.
224 std::list<unsigned int> ssrcs;
225 if (video_codec_internal.numberOfSimulcastStreams == 0) {
226 unsigned int ssrc = 0;
227 if (vie_channel->GetLocalSSRC(0, &ssrc) != 0) {
228 WEBRTC_TRACE(kTraceError, kTraceVideo,
229 ViEId(shared_data_->instance_id(), video_channel),
230 "%s: Could not get ssrc", __FUNCTION__);
231 }
232 ssrcs.push_back(ssrc);
233 } else {
234 for (int idx = 0; idx < video_codec_internal.numberOfSimulcastStreams;
235 ++idx) {
236 unsigned int ssrc = 0;
237 if (vie_channel->GetLocalSSRC(idx, &ssrc) != 0) {
238 WEBRTC_TRACE(kTraceError, kTraceVideo,
239 ViEId(shared_data_->instance_id(), video_channel),
240 "%s: Could not get ssrc for idx %d", __FUNCTION__, idx);
241 }
242 ssrcs.push_back(ssrc);
243 }
244 }
245 vie_encoder->SetSsrcs(ssrcs);
246 shared_data_->channel_manager()->UpdateSsrcs(video_channel, ssrcs);
247
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000248 // Update the protection mode, we might be switching NACK/FEC.
wu@webrtc.org822fbd82013-08-15 23:38:54 +0000249 vie_encoder->UpdateProtectionMethod(vie_encoder->nack_enabled());
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000250
251 // Get new best format for frame provider.
pbos@webrtc.org735a7c82013-08-05 09:03:03 +0000252 ViEFrameProviderBase* frame_provider = is.FrameProvider(vie_encoder);
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000253 if (frame_provider) {
254 frame_provider->FrameCallbackChanged();
255 }
256 // Restart the media flow
257 if (new_rtp_stream) {
258 // Stream settings changed, make sure we get a key frame.
259 vie_encoder->SendKeyFrame();
260 }
261 vie_encoder->Restart();
262 return 0;
stefan@webrtc.org791eec72011-10-11 07:53:43 +0000263}
264
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000265int ViECodecImpl::GetSendCodec(const int video_channel,
266 VideoCodec& video_codec) const {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000267 WEBRTC_TRACE(kTraceApiCall, kTraceVideo,
268 ViEId(shared_data_->instance_id(), video_channel),
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000269 "%s(video_channel: %d)", __FUNCTION__, video_channel);
niklase@google.com470e71d2011-07-07 08:21:25 +0000270
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000271 ViEChannelManagerScoped cs(*(shared_data_->channel_manager()));
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000272 ViEEncoder* vie_encoder = cs.Encoder(video_channel);
273 if (!vie_encoder) {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000274 WEBRTC_TRACE(kTraceError, kTraceVideo,
275 ViEId(shared_data_->instance_id(), video_channel),
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000276 "%s: No encoder for channel %d", __FUNCTION__, video_channel);
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000277 shared_data_->SetLastError(kViECodecInvalidChannelId);
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000278 return -1;
279 }
mflodman@webrtc.orgf5e99db2012-06-27 09:49:37 +0000280 return vie_encoder->GetEncoder(&video_codec);
niklase@google.com470e71d2011-07-07 08:21:25 +0000281}
282
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000283int ViECodecImpl::SetReceiveCodec(const int video_channel,
284 const VideoCodec& video_codec) {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000285 WEBRTC_TRACE(kTraceApiCall, kTraceVideo,
286 ViEId(shared_data_->instance_id(), video_channel),
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000287 "%s(video_channel: %d, codec_type: %d)", __FUNCTION__,
288 video_channel, video_codec.codecType);
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000289 WEBRTC_TRACE(kTraceInfo, kTraceVideo,
290 ViEId(shared_data_->instance_id(), video_channel),
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000291 "%s: codec: %d, pl_type: %d, width: %d, height: %d, bitrate: %d,"
292 "maxBr: %d, min_br: %d, frame_rate: %d", __FUNCTION__,
293 video_codec.codecType, video_codec.plType, video_codec.width,
294 video_codec.height, video_codec.startBitrate,
295 video_codec.maxBitrate, video_codec.minBitrate,
296 video_codec.maxFramerate);
niklase@google.com470e71d2011-07-07 08:21:25 +0000297
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000298 if (CodecValid(video_codec) == false) {
299 // Error logged.
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000300 shared_data_->SetLastError(kViECodecInvalidCodec);
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000301 return -1;
302 }
303
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000304 ViEChannelManagerScoped cs(*(shared_data_->channel_manager()));
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000305 ViEChannel* vie_channel = cs.Channel(video_channel);
306 if (!vie_channel) {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000307 WEBRTC_TRACE(kTraceError, kTraceVideo,
308 ViEId(shared_data_->instance_id(), video_channel),
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000309 "%s: No channel %d", __FUNCTION__, video_channel);
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000310 shared_data_->SetLastError(kViECodecInvalidChannelId);
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000311 return -1;
312 }
313
314 if (vie_channel->SetReceiveCodec(video_codec) != 0) {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000315 WEBRTC_TRACE(kTraceError, kTraceVideo,
316 ViEId(shared_data_->instance_id(), video_channel),
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000317 "%s: Could not set receive codec for channel %d",
318 __FUNCTION__, video_channel);
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000319 shared_data_->SetLastError(kViECodecUnknownError);
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000320 return -1;
321 }
322 return 0;
323}
324
325int ViECodecImpl::GetReceiveCodec(const int video_channel,
326 VideoCodec& video_codec) const {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000327 WEBRTC_TRACE(kTraceApiCall, kTraceVideo,
328 ViEId(shared_data_->instance_id(), video_channel),
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000329 "%s(video_channel: %d, codec_type: %d)", __FUNCTION__,
330 video_channel, video_codec.codecType);
331
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000332 ViEChannelManagerScoped cs(*(shared_data_->channel_manager()));
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000333 ViEChannel* vie_channel = cs.Channel(video_channel);
334 if (!vie_channel) {
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: No channel %d", __FUNCTION__, video_channel);
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000338 shared_data_->SetLastError(kViECodecInvalidChannelId);
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000339 return -1;
340 }
341
mflodman@webrtc.orgf5e99db2012-06-27 09:49:37 +0000342 if (vie_channel->GetReceiveCodec(&video_codec) != 0) {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000343 shared_data_->SetLastError(kViECodecUnknownError);
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000344 return -1;
345 }
346 return 0;
347}
348
349int ViECodecImpl::GetCodecConfigParameters(
350 const int video_channel,
351 unsigned char config_parameters[kConfigParameterSize],
352 unsigned char& config_parameters_size) const {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000353 WEBRTC_TRACE(kTraceApiCall, kTraceVideo,
354 ViEId(shared_data_->instance_id(), video_channel),
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000355 "%s(video_channel: %d)", __FUNCTION__, video_channel);
356
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000357 ViEChannelManagerScoped cs(*(shared_data_->channel_manager()));
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000358 ViEEncoder* vie_encoder = cs.Encoder(video_channel);
359 if (!vie_encoder) {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000360 WEBRTC_TRACE(kTraceError, kTraceVideo,
361 ViEId(shared_data_->instance_id(), video_channel),
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000362 "%s: No encoder for channel %d", __FUNCTION__, video_channel);
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000363 shared_data_->SetLastError(kViECodecInvalidChannelId);
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000364 return -1;
365 }
366
367 if (vie_encoder->GetCodecConfigParameters(config_parameters,
368 config_parameters_size) != 0) {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000369 shared_data_->SetLastError(kViECodecUnknownError);
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000370 return -1;
371 }
372 return 0;
373}
374
375int ViECodecImpl::SetImageScaleStatus(const int video_channel,
376 const bool enable) {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000377 WEBRTC_TRACE(kTraceApiCall, kTraceVideo,
378 ViEId(shared_data_->instance_id(), video_channel),
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000379 "%s(video_channel: %d, enable: %d)", __FUNCTION__, video_channel,
380 enable);
381
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000382 ViEChannelManagerScoped cs(*(shared_data_->channel_manager()));
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000383 ViEEncoder* vie_encoder = cs.Encoder(video_channel);
384 if (!vie_encoder) {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000385 WEBRTC_TRACE(kTraceError, kTraceVideo,
386 ViEId(shared_data_->instance_id(), video_channel),
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000387 "%s: No channel %d", __FUNCTION__, video_channel);
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000388 shared_data_->SetLastError(kViECodecInvalidChannelId);
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000389 return -1;
390 }
391
392 if (vie_encoder->ScaleInputImage(enable) != 0) {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000393 shared_data_->SetLastError(kViECodecUnknownError);
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000394 return -1;
395 }
396 return 0;
397}
398
399int ViECodecImpl::GetSendCodecStastistics(const int video_channel,
400 unsigned int& key_frames,
401 unsigned int& delta_frames) const {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000402 WEBRTC_TRACE(kTraceApiCall, kTraceVideo,
403 ViEId(shared_data_->instance_id(), video_channel),
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000404 "%s(video_channel %d)", __FUNCTION__, video_channel);
405
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000406 ViEChannelManagerScoped cs(*(shared_data_->channel_manager()));
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000407 ViEEncoder* vie_encoder = cs.Encoder(video_channel);
408 if (!vie_encoder) {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000409 WEBRTC_TRACE(kTraceError, kTraceVideo,
410 ViEId(shared_data_->instance_id(), video_channel),
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000411 "%s: No send codec for channel %d", __FUNCTION__,
412 video_channel);
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000413 shared_data_->SetLastError(kViECodecInvalidChannelId);
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000414 return -1;
415 }
416
mflodman@webrtc.orgf5e99db2012-06-27 09:49:37 +0000417 if (vie_encoder->SendCodecStatistics(&key_frames, &delta_frames) != 0) {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000418 shared_data_->SetLastError(kViECodecUnknownError);
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000419 return -1;
420 }
421 return 0;
422}
423
424int ViECodecImpl::GetReceiveCodecStastistics(const int video_channel,
425 unsigned int& key_frames,
426 unsigned int& delta_frames) const {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000427 WEBRTC_TRACE(kTraceApiCall, kTraceVideo,
428 ViEId(shared_data_->instance_id(), video_channel),
mflodman@webrtc.org4aee6b62012-12-14 14:02:10 +0000429 "%s(video_channel: %d)", __FUNCTION__,
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000430 video_channel);
431
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000432 ViEChannelManagerScoped cs(*(shared_data_->channel_manager()));
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000433 ViEChannel* vie_channel = cs.Channel(video_channel);
434 if (!vie_channel) {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000435 WEBRTC_TRACE(kTraceError, kTraceVideo,
436 ViEId(shared_data_->instance_id(), video_channel),
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000437 "%s: No channel %d", __FUNCTION__, video_channel);
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000438 shared_data_->SetLastError(kViECodecInvalidChannelId);
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000439 return -1;
440 }
mflodman@webrtc.orgf5e99db2012-06-27 09:49:37 +0000441 if (vie_channel->ReceiveCodecStatistics(&key_frames, &delta_frames) != 0) {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000442 shared_data_->SetLastError(kViECodecUnknownError);
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000443 return -1;
444 }
445 return 0;
446}
447
mflodman@webrtc.org4aee6b62012-12-14 14:02:10 +0000448int ViECodecImpl::GetReceiveSideDelay(const int video_channel,
449 int* delay_ms) const {
450 WEBRTC_TRACE(kTraceApiCall, kTraceVideo,
451 ViEId(shared_data_->instance_id(), video_channel),
452 "%s(video_channel: %d)", __FUNCTION__, video_channel);
453 if (delay_ms == NULL) {
454 LOG_F(LS_ERROR) << "NULL pointer argument.";
455 return -1;
456 }
457
458 ViEChannelManagerScoped cs(*(shared_data_->channel_manager()));
459 ViEChannel* vie_channel = cs.Channel(video_channel);
460 if (!vie_channel) {
461 WEBRTC_TRACE(kTraceError, kTraceVideo,
462 ViEId(shared_data_->instance_id(), video_channel),
463 "%s: No channel %d", __FUNCTION__, video_channel);
464 shared_data_->SetLastError(kViECodecInvalidChannelId);
465 return -1;
466 }
467 *delay_ms = vie_channel->ReceiveDelay();
468 if (*delay_ms < 0) {
469 return -1;
470 }
471 return 0;
472}
473
474
stefan@webrtc.org439be292012-02-16 14:45:37 +0000475int ViECodecImpl::GetCodecTargetBitrate(const int video_channel,
476 unsigned int* bitrate) const {
477 WEBRTC_TRACE(kTraceApiCall, kTraceVideo,
478 ViEId(shared_data_->instance_id(), video_channel),
479 "%s(video_channel: %d, codec_type: %d)", __FUNCTION__,
480 video_channel);
481
482 ViEChannelManagerScoped cs(*(shared_data_->channel_manager()));
483 ViEEncoder* vie_encoder = cs.Encoder(video_channel);
484 if (!vie_encoder) {
485 WEBRTC_TRACE(kTraceError, kTraceVideo,
486 ViEId(shared_data_->instance_id(), video_channel),
487 "%s: No send codec for channel %d", __FUNCTION__,
488 video_channel);
489 shared_data_->SetLastError(kViECodecInvalidChannelId);
490 return -1;
491 }
pbos@webrtc.orgb238d122013-04-09 13:41:51 +0000492 return vie_encoder->CodecTargetBitrate(static_cast<uint32_t*>(bitrate));
stefan@webrtc.org439be292012-02-16 14:45:37 +0000493}
494
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000495unsigned int ViECodecImpl::GetDiscardedPackets(const int video_channel) const {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000496 WEBRTC_TRACE(kTraceApiCall, kTraceVideo,
497 ViEId(shared_data_->instance_id(), video_channel),
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000498 "%s(video_channel: %d, codec_type: %d)", __FUNCTION__,
499 video_channel);
500
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000501 ViEChannelManagerScoped cs(*(shared_data_->channel_manager()));
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000502 ViEChannel* vie_channel = cs.Channel(video_channel);
503 if (!vie_channel) {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000504 WEBRTC_TRACE(kTraceError, kTraceVideo,
505 ViEId(shared_data_->instance_id(), video_channel),
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000506 "%s: No channel %d", __FUNCTION__, video_channel);
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000507 shared_data_->SetLastError(kViECodecInvalidChannelId);
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000508 return -1;
509 }
510 return vie_channel->DiscardedPackets();
511}
512
513int ViECodecImpl::SetKeyFrameRequestCallbackStatus(const int video_channel,
514 const bool enable) {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000515 WEBRTC_TRACE(kTraceApiCall, kTraceVideo,
516 ViEId(shared_data_->instance_id(), video_channel),
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000517 "%s(video_channel: %d)", __FUNCTION__, video_channel);
518
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000519 ViEChannelManagerScoped cs(*(shared_data_->channel_manager()));
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000520 ViEChannel* vie_channel = cs.Channel(video_channel);
521 if (!vie_channel) {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000522 WEBRTC_TRACE(kTraceError, kTraceVideo,
523 ViEId(shared_data_->instance_id(), video_channel),
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000524 "%s: No channel %d", __FUNCTION__, video_channel);
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000525 shared_data_->SetLastError(kViECodecInvalidChannelId);
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000526 return -1;
527 }
528 if (vie_channel->EnableKeyFrameRequestCallback(enable) != 0) {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000529 shared_data_->SetLastError(kViECodecUnknownError);
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000530 return -1;
531 }
532 return 0;
533}
534
535int ViECodecImpl::SetSignalKeyPacketLossStatus(const int video_channel,
niklase@google.com470e71d2011-07-07 08:21:25 +0000536 const bool enable,
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000537 const bool only_key_frames) {
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, enable: %d, only_key_frames: %d)",
541 __FUNCTION__, video_channel, enable);
niklase@google.com470e71d2011-07-07 08:21:25 +0000542
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000543 ViEChannelManagerScoped cs(*(shared_data_->channel_manager()));
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000544 ViEChannel* vie_channel = cs.Channel(video_channel);
545 if (!vie_channel) {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000546 WEBRTC_TRACE(kTraceError, kTraceVideo,
547 ViEId(shared_data_->instance_id(), video_channel),
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000548 "%s: No channel %d", __FUNCTION__, video_channel);
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000549 shared_data_->SetLastError(kViECodecInvalidChannelId);
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000550 return -1;
551 }
552 if (vie_channel->SetSignalPacketLossStatus(enable, only_key_frames) != 0) {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000553 shared_data_->SetLastError(kViECodecUnknownError);
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000554 return -1;
555 }
556 return 0;
niklase@google.com470e71d2011-07-07 08:21:25 +0000557}
558
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000559int ViECodecImpl::RegisterEncoderObserver(const int video_channel,
560 ViEEncoderObserver& observer) {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000561 WEBRTC_TRACE(kTraceApiCall, kTraceVideo, ViEId(shared_data_->instance_id()),
562 "%s", __FUNCTION__);
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 ViEEncoder* vie_encoder = cs.Encoder(video_channel);
566 if (!vie_encoder) {
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 encoder for 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_encoder->RegisterCodecObserver(&observer) != 0) {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000574 WEBRTC_TRACE(kTraceError, kTraceVideo,
575 ViEId(shared_data_->instance_id(), video_channel),
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000576 "%s: Could not register codec observer at channel",
577 __FUNCTION__);
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000578 shared_data_->SetLastError(kViECodecObserverAlreadyRegistered);
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000579 return -1;
580 }
581 return 0;
niklase@google.com470e71d2011-07-07 08:21:25 +0000582}
583
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000584int ViECodecImpl::DeregisterEncoderObserver(const int video_channel) {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000585 WEBRTC_TRACE(kTraceApiCall, kTraceVideo, ViEId(shared_data_->instance_id()),
586 "%s", __FUNCTION__);
niklase@google.com470e71d2011-07-07 08:21:25 +0000587
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000588 ViEChannelManagerScoped cs(*(shared_data_->channel_manager()));
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000589 ViEEncoder* vie_encoder = cs.Encoder(video_channel);
590 if (!vie_encoder) {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000591 WEBRTC_TRACE(kTraceError, kTraceVideo,
592 ViEId(shared_data_->instance_id(), video_channel),
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000593 "%s: No encoder for channel %d", __FUNCTION__, video_channel);
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000594 shared_data_->SetLastError(kViECodecInvalidChannelId);
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000595 return -1;
596 }
597 if (vie_encoder->RegisterCodecObserver(NULL) != 0) {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000598 shared_data_->SetLastError(kViECodecObserverNotRegistered);
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000599 return -1;
600 }
601 return 0;
niklase@google.com470e71d2011-07-07 08:21:25 +0000602}
603
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000604int ViECodecImpl::RegisterDecoderObserver(const int video_channel,
605 ViEDecoderObserver& observer) {
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 ViEChannel* vie_channel = cs.Channel(video_channel);
611 if (!vie_channel) {
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 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_channel->RegisterCodecObserver(&observer) != 0) {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000619 WEBRTC_TRACE(kTraceError, kTraceVideo,
620 ViEId(shared_data_->instance_id(), video_channel),
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000621 "%s: Could not register codec observer at channel",
622 __FUNCTION__);
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000623 shared_data_->SetLastError(kViECodecObserverAlreadyRegistered);
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000624 return -1;
625 }
626 return 0;
niklase@google.com470e71d2011-07-07 08:21:25 +0000627}
628
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000629int ViECodecImpl::DeregisterDecoderObserver(const int video_channel) {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000630 WEBRTC_TRACE(kTraceApiCall, kTraceVideo,
631 ViEId(shared_data_->instance_id()), "%s",
niklase@google.com470e71d2011-07-07 08:21:25 +0000632 __FUNCTION__);
633
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000634 ViEChannelManagerScoped cs(*(shared_data_->channel_manager()));
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000635 ViEChannel* vie_channel = cs.Channel(video_channel);
636 if (!vie_channel) {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000637 WEBRTC_TRACE(kTraceError, kTraceVideo,
638 ViEId(shared_data_->instance_id(), video_channel),
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000639 "%s: No channel %d", __FUNCTION__, video_channel);
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000640 shared_data_->SetLastError(kViECodecInvalidChannelId);
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000641 return -1;
642 }
643 if (vie_channel->RegisterCodecObserver(NULL) != 0) {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000644 shared_data_->SetLastError(kViECodecObserverNotRegistered);
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::SendKeyFrame(const int video_channel) {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000651 WEBRTC_TRACE(kTraceApiCall, kTraceVideo, ViEId(shared_data_->instance_id()),
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000652 "%s(video_channel: %d)", __FUNCTION__, video_channel);
niklase@google.com470e71d2011-07-07 08:21:25 +0000653
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000654 ViEChannelManagerScoped cs(*(shared_data_->channel_manager()));
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000655 ViEEncoder* vie_encoder = cs.Encoder(video_channel);
656 if (!vie_encoder) {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000657 WEBRTC_TRACE(kTraceError, kTraceVideo,
658 ViEId(shared_data_->instance_id(), video_channel),
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000659 "%s: No channel %d", __FUNCTION__, video_channel);
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000660 shared_data_->SetLastError(kViECodecInvalidChannelId);
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000661 return -1;
662 }
663 if (vie_encoder->SendKeyFrame() != 0) {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000664 shared_data_->SetLastError(kViECodecUnknownError);
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000665 return -1;
666 }
667 return 0;
niklase@google.com470e71d2011-07-07 08:21:25 +0000668}
669
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000670int ViECodecImpl::WaitForFirstKeyFrame(const int video_channel,
671 const bool wait) {
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000672 WEBRTC_TRACE(kTraceApiCall, kTraceVideo,
673 ViEId(shared_data_->instance_id()),
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000674 "%s(video_channel: %d, wait: %d)", __FUNCTION__, video_channel,
niklase@google.com470e71d2011-07-07 08:21:25 +0000675 wait);
676
mflodman@webrtc.orgb11424b2012-01-25 13:42:03 +0000677 ViEChannelManagerScoped cs(*(shared_data_->channel_manager()));
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000678 ViEChannel* vie_channel = cs.Channel(video_channel);
679 if (!vie_channel) {
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_channel->WaitForKeyFrame(wait) != 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.org1c986e72013-06-26 09:12:49 +0000693int ViECodecImpl::StartDebugRecording(int video_channel,
694 const char* file_name_utf8) {
695 ViEChannelManagerScoped cs(*(shared_data_->channel_manager()));
696 ViEEncoder* vie_encoder = cs.Encoder(video_channel);
697 if (!vie_encoder) {
698 WEBRTC_TRACE(kTraceError, kTraceVideo,
699 ViEId(shared_data_->instance_id(), video_channel),
700 "%s: No encoder %d", __FUNCTION__, video_channel);
701 return -1;
702 }
703 return vie_encoder->StartDebugRecording(file_name_utf8);
704}
705
706int ViECodecImpl::StopDebugRecording(int video_channel) {
707 ViEChannelManagerScoped cs(*(shared_data_->channel_manager()));
708 ViEEncoder* vie_encoder = cs.Encoder(video_channel);
709 if (!vie_encoder) {
710 WEBRTC_TRACE(kTraceError, kTraceVideo,
711 ViEId(shared_data_->instance_id(), video_channel),
712 "%s: No encoder %d", __FUNCTION__, video_channel);
713 return -1;
714 }
715 return vie_encoder->StopDebugRecording();
716}
717
henrik.lundin@webrtc.orgce8e0932013-11-18 12:18:43 +0000718void ViECodecImpl::SuspendBelowMinBitrate(int video_channel) {
henrik.lundin@webrtc.org7ea4f242013-10-02 13:34:26 +0000719 ViEChannelManagerScoped cs(*(shared_data_->channel_manager()));
720 ViEEncoder* vie_encoder = cs.Encoder(video_channel);
721 if (!vie_encoder) {
722 WEBRTC_TRACE(kTraceError, kTraceVideo,
723 ViEId(shared_data_->instance_id(), video_channel),
724 "%s: No encoder %d", __FUNCTION__, video_channel);
725 return;
726 }
henrik.lundin@webrtc.orgce8e0932013-11-18 12:18:43 +0000727 return vie_encoder->SuspendBelowMinBitrate();
henrik.lundin@webrtc.org7ea4f242013-10-02 13:34:26 +0000728}
729
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000730bool ViECodecImpl::CodecValid(const VideoCodec& video_codec) {
731 // Check pl_name matches codec_type.
732 if (video_codec.codecType == kVideoCodecRED) {
niklase@google.com470e71d2011-07-07 08:21:25 +0000733#if defined(WIN32)
mflodman@webrtc.org1fe2ada2011-12-21 12:23:15 +0000734 if (_strnicmp(video_codec.plName, "red", 3) == 0) {
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000735#else
736 if (strncasecmp(video_codec.plName, "red", 3) == 0) {
niklase@google.com470e71d2011-07-07 08:21:25 +0000737#endif
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000738 // We only care about the type and name for red.
739 return true;
niklase@google.com470e71d2011-07-07 08:21:25 +0000740 }
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000741 WEBRTC_TRACE(kTraceError, kTraceVideo, -1,
742 "Codec type doesn't match pl_name", video_codec.plType);
743 return false;
744 } else if (video_codec.codecType == kVideoCodecULPFEC) {
niklase@google.com470e71d2011-07-07 08:21:25 +0000745#if defined(WIN32)
mflodman@webrtc.org1fe2ada2011-12-21 12:23:15 +0000746 if (_strnicmp(video_codec.plName, "ULPFEC", 6) == 0) {
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000747#else
748 if (strncasecmp(video_codec.plName, "ULPFEC", 6) == 0) {
niklase@google.com470e71d2011-07-07 08:21:25 +0000749#endif
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000750 // We only care about the type and name for ULPFEC.
751 return true;
niklase@google.com470e71d2011-07-07 08:21:25 +0000752 }
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000753 WEBRTC_TRACE(kTraceError, kTraceVideo, -1,
754 "Codec type doesn't match pl_name", video_codec.plType);
755 return false;
pwestin@webrtc.org56210572012-01-17 12:45:47 +0000756 } else if ((video_codec.codecType == kVideoCodecVP8 &&
pbos@webrtc.org8911ce42013-03-18 16:39:03 +0000757 strncmp(video_codec.plName, "VP8", 4) == 0) ||
758 (video_codec.codecType == kVideoCodecI420 &&
pbos@webrtc.orgb5bf54c2013-04-05 13:27:38 +0000759 strncmp(video_codec.plName, "I420", 4) == 0)) {
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000760 // OK.
pbos@webrtc.orgb5bf54c2013-04-05 13:27:38 +0000761 } else if (video_codec.codecType != kVideoCodecGeneric) {
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000762 WEBRTC_TRACE(kTraceError, kTraceVideo, -1,
763 "Codec type doesn't match pl_name", video_codec.plType);
764 return false;
765 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000766
braveyao@webrtc.org49273ff2013-01-14 01:52:26 +0000767 if (video_codec.plType == 0 || video_codec.plType > 127) {
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000768 WEBRTC_TRACE(kTraceError, kTraceVideo, -1,
769 "Invalid codec payload type: %d", video_codec.plType);
770 return false;
771 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000772
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000773 if (video_codec.width > kViEMaxCodecWidth ||
774 video_codec.height > kViEMaxCodecHeight) {
775 WEBRTC_TRACE(kTraceError, kTraceVideo, -1, "Invalid codec size: %u x %u",
776 video_codec.width, video_codec.height);
777 return false;
778 }
niklase@google.com470e71d2011-07-07 08:21:25 +0000779
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000780 if (video_codec.startBitrate < kViEMinCodecBitrate) {
781 WEBRTC_TRACE(kTraceError, kTraceVideo, -1, "Invalid start_bitrate: %u",
782 video_codec.startBitrate);
783 return false;
784 }
785 if (video_codec.minBitrate < kViEMinCodecBitrate) {
786 WEBRTC_TRACE(kTraceError, kTraceVideo, -1, "Invalid min_bitrate: %u",
787 video_codec.minBitrate);
788 return false;
789 }
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000790 return true;
niklase@google.com470e71d2011-07-07 08:21:25 +0000791}
mflodman@webrtc.orgc12686c2011-12-21 09:29:28 +0000792
793} // namespace webrtc