1b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org/*
2b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org *  Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
3b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org *
4b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org *  Use of this source code is governed by a BSD-style license
5b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org *  that can be found in the LICENSE file in the root of the source
6b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org *  tree. An additional intellectual property rights grant can be found
7b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org *  in the file PATENTS.  All contributing project authors may
8b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org *  be found in the AUTHORS file in the root of the source tree.
9b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org */
10b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
11281cff8cd679728fe395f7f0203c05e763c0c789pbos@webrtc.org#include "webrtc/video_engine/vie_base_impl.h"
12b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
13b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org#include <sstream>
14b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org#include <string>
15dadfc9ef4ac1a324bf670703c2e9e3a38d64e522mflodman@webrtc.org#include <utility>
16b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
17281cff8cd679728fe395f7f0203c05e763c0c789pbos@webrtc.org#include "webrtc/engine_configurations.h"
18281cff8cd679728fe395f7f0203c05e763c0c789pbos@webrtc.org#include "webrtc/modules/rtp_rtcp/interface/rtp_rtcp.h"
19281cff8cd679728fe395f7f0203c05e763c0c789pbos@webrtc.org#include "webrtc/modules/video_coding/main/interface/video_coding.h"
20281cff8cd679728fe395f7f0203c05e763c0c789pbos@webrtc.org#include "webrtc/modules/video_processing/main/interface/video_processing.h"
2107e96da4b4ae3ba9e722128fc650f6b10ff663f5andrew@webrtc.org#include "webrtc/modules/video_render/include/video_render.h"
22281cff8cd679728fe395f7f0203c05e763c0c789pbos@webrtc.org#include "webrtc/system_wrappers/interface/critical_section_wrapper.h"
23022615bd918aec7671968ad2b873d1487365980cmflodman@webrtc.org#include "webrtc/system_wrappers/interface/logging.h"
24281cff8cd679728fe395f7f0203c05e763c0c789pbos@webrtc.org#include "webrtc/video_engine/include/vie_errors.h"
25bf76ae2bdfc0b4e8e875f6cce1c85d4d66357bebmflodman@webrtc.org#include "webrtc/video_engine/vie_capturer.h"
26281cff8cd679728fe395f7f0203c05e763c0c789pbos@webrtc.org#include "webrtc/video_engine/vie_channel.h"
27281cff8cd679728fe395f7f0203c05e763c0c789pbos@webrtc.org#include "webrtc/video_engine/vie_channel_manager.h"
28281cff8cd679728fe395f7f0203c05e763c0c789pbos@webrtc.org#include "webrtc/video_engine/vie_defines.h"
29281cff8cd679728fe395f7f0203c05e763c0c789pbos@webrtc.org#include "webrtc/video_engine/vie_encoder.h"
30281cff8cd679728fe395f7f0203c05e763c0c789pbos@webrtc.org#include "webrtc/video_engine/vie_impl.h"
31281cff8cd679728fe395f7f0203c05e763c0c789pbos@webrtc.org#include "webrtc/video_engine/vie_input_manager.h"
32281cff8cd679728fe395f7f0203c05e763c0c789pbos@webrtc.org#include "webrtc/video_engine/vie_shared_data.h"
33b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
34b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgnamespace webrtc {
35b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
36b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgViEBase* ViEBase::GetInterface(VideoEngine* video_engine) {
37b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  if (!video_engine) {
38b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    return NULL;
39b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  }
407ab726855f2ceb9ff6365e3240668d58f45e6761andrew@webrtc.org  VideoEngineImpl* vie_impl = static_cast<VideoEngineImpl*>(video_engine);
41b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  ViEBaseImpl* vie_base_impl = vie_impl;
42b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  (*vie_base_impl)++;  // Increase ref count.
43b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
44b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  return vie_base_impl;
45b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
46b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
47b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgint ViEBaseImpl::Release() {
48b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  (*this)--;  // Decrease ref count.
49b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
5067879bc2e69d7907b7ceb92135a34f77fe643e7fpbos@webrtc.org  int32_t ref_count = GetCount();
51b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  if (ref_count < 0) {
52022615bd918aec7671968ad2b873d1487365980cmflodman@webrtc.org    LOG(LS_WARNING) << "ViEBase released too many times.";
53b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    return -1;
54b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  }
55b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  return ref_count;
56b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
57b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
58ac6d919eec548c708588f29923f617a17283c7e2andresp@webrtc.orgViEBaseImpl::ViEBaseImpl(const Config& config)
59022615bd918aec7671968ad2b873d1487365980cmflodman@webrtc.org    : shared_data_(config) {}
60b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
61022615bd918aec7671968ad2b873d1487365980cmflodman@webrtc.orgViEBaseImpl::~ViEBaseImpl() {}
62b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
63b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgint ViEBaseImpl::Init() {
64b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  return 0;
65b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
66b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
67b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgint ViEBaseImpl::SetVoiceEngine(VoiceEngine* voice_engine) {
68022615bd918aec7671968ad2b873d1487365980cmflodman@webrtc.org  LOG_F(LS_INFO) << "SetVoiceEngine";
69b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  if (shared_data_.channel_manager()->SetVoiceEngine(voice_engine) != 0) {
70b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    shared_data_.SetLastError(kViEBaseVoEFailure);
71b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    return -1;
72b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  }
73b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  return 0;
74b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
75b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
76bf76ae2bdfc0b4e8e875f6cce1c85d4d66357bebmflodman@webrtc.orgint ViEBaseImpl::RegisterCpuOveruseObserver(int video_channel,
77bf76ae2bdfc0b4e8e875f6cce1c85d4d66357bebmflodman@webrtc.org                                            CpuOveruseObserver* observer) {
78022615bd918aec7671968ad2b873d1487365980cmflodman@webrtc.org  LOG_F(LS_INFO) << "RegisterCpuOveruseObserver on channel " << video_channel;
79bf76ae2bdfc0b4e8e875f6cce1c85d4d66357bebmflodman@webrtc.org  ViEChannelManagerScoped cs(*(shared_data_.channel_manager()));
80bf76ae2bdfc0b4e8e875f6cce1c85d4d66357bebmflodman@webrtc.org  ViEChannel* vie_channel = cs.Channel(video_channel);
81bf76ae2bdfc0b4e8e875f6cce1c85d4d66357bebmflodman@webrtc.org  if (!vie_channel) {
82bf76ae2bdfc0b4e8e875f6cce1c85d4d66357bebmflodman@webrtc.org    shared_data_.SetLastError(kViEBaseInvalidChannelId);
83bf76ae2bdfc0b4e8e875f6cce1c85d4d66357bebmflodman@webrtc.org    return -1;
84bf76ae2bdfc0b4e8e875f6cce1c85d4d66357bebmflodman@webrtc.org  }
85bf76ae2bdfc0b4e8e875f6cce1c85d4d66357bebmflodman@webrtc.org  ViEEncoder* vie_encoder = cs.Encoder(video_channel);
86bf76ae2bdfc0b4e8e875f6cce1c85d4d66357bebmflodman@webrtc.org  assert(vie_encoder);
87bf76ae2bdfc0b4e8e875f6cce1c85d4d66357bebmflodman@webrtc.org
88bf76ae2bdfc0b4e8e875f6cce1c85d4d66357bebmflodman@webrtc.org  ViEInputManagerScoped is(*(shared_data_.input_manager()));
89bf76ae2bdfc0b4e8e875f6cce1c85d4d66357bebmflodman@webrtc.org  ViEFrameProviderBase* provider = is.FrameProvider(vie_encoder);
90bf76ae2bdfc0b4e8e875f6cce1c85d4d66357bebmflodman@webrtc.org  if (provider) {
91bf76ae2bdfc0b4e8e875f6cce1c85d4d66357bebmflodman@webrtc.org    ViECapturer* capturer = is.Capture(provider->Id());
92bf76ae2bdfc0b4e8e875f6cce1c85d4d66357bebmflodman@webrtc.org    assert(capturer);
93bf76ae2bdfc0b4e8e875f6cce1c85d4d66357bebmflodman@webrtc.org    capturer->RegisterCpuOveruseObserver(observer);
94bf76ae2bdfc0b4e8e875f6cce1c85d4d66357bebmflodman@webrtc.org  }
95bf76ae2bdfc0b4e8e875f6cce1c85d4d66357bebmflodman@webrtc.org
96bf76ae2bdfc0b4e8e875f6cce1c85d4d66357bebmflodman@webrtc.org  shared_data_.overuse_observers()->insert(
97bf76ae2bdfc0b4e8e875f6cce1c85d4d66357bebmflodman@webrtc.org      std::pair<int, CpuOveruseObserver*>(video_channel, observer));
98bf76ae2bdfc0b4e8e875f6cce1c85d4d66357bebmflodman@webrtc.org  return 0;
99bf76ae2bdfc0b4e8e875f6cce1c85d4d66357bebmflodman@webrtc.org}
100bf76ae2bdfc0b4e8e875f6cce1c85d4d66357bebmflodman@webrtc.org
1019da327cad743253030f65939c316d009bb48d8e1asapersson@webrtc.orgint ViEBaseImpl::SetCpuOveruseOptions(int video_channel,
1029da327cad743253030f65939c316d009bb48d8e1asapersson@webrtc.org                                      const CpuOveruseOptions& options) {
1039da327cad743253030f65939c316d009bb48d8e1asapersson@webrtc.org  ViEChannelManagerScoped cs(*(shared_data_.channel_manager()));
1049da327cad743253030f65939c316d009bb48d8e1asapersson@webrtc.org  ViEChannel* vie_channel = cs.Channel(video_channel);
1059da327cad743253030f65939c316d009bb48d8e1asapersson@webrtc.org  if (!vie_channel) {
1069da327cad743253030f65939c316d009bb48d8e1asapersson@webrtc.org    shared_data_.SetLastError(kViEBaseInvalidChannelId);
1079da327cad743253030f65939c316d009bb48d8e1asapersson@webrtc.org    return -1;
1089da327cad743253030f65939c316d009bb48d8e1asapersson@webrtc.org  }
1099da327cad743253030f65939c316d009bb48d8e1asapersson@webrtc.org  ViEEncoder* vie_encoder = cs.Encoder(video_channel);
1109da327cad743253030f65939c316d009bb48d8e1asapersson@webrtc.org  assert(vie_encoder);
1119da327cad743253030f65939c316d009bb48d8e1asapersson@webrtc.org
1129da327cad743253030f65939c316d009bb48d8e1asapersson@webrtc.org  ViEInputManagerScoped is(*(shared_data_.input_manager()));
1139da327cad743253030f65939c316d009bb48d8e1asapersson@webrtc.org  ViEFrameProviderBase* provider = is.FrameProvider(vie_encoder);
1149da327cad743253030f65939c316d009bb48d8e1asapersson@webrtc.org  if (provider) {
1159da327cad743253030f65939c316d009bb48d8e1asapersson@webrtc.org    ViECapturer* capturer = is.Capture(provider->Id());
1169da327cad743253030f65939c316d009bb48d8e1asapersson@webrtc.org    if (capturer) {
1179da327cad743253030f65939c316d009bb48d8e1asapersson@webrtc.org      capturer->SetCpuOveruseOptions(options);
1189da327cad743253030f65939c316d009bb48d8e1asapersson@webrtc.org      return 0;
1199da327cad743253030f65939c316d009bb48d8e1asapersson@webrtc.org    }
1209da327cad743253030f65939c316d009bb48d8e1asapersson@webrtc.org  }
1219da327cad743253030f65939c316d009bb48d8e1asapersson@webrtc.org  return -1;
1229da327cad743253030f65939c316d009bb48d8e1asapersson@webrtc.org}
1239da327cad743253030f65939c316d009bb48d8e1asapersson@webrtc.org
124dd4f8664a1759e8a3a0329e8aebe6e872d371f20asapersson@webrtc.orgint ViEBaseImpl::CpuOveruseMeasures(int video_channel,
125dd4f8664a1759e8a3a0329e8aebe6e872d371f20asapersson@webrtc.org                                    int* capture_jitter_ms,
126f1630b1f53156a9723ae5431f2fb1e54786593b9asapersson@webrtc.org                                    int* avg_encode_time_ms,
127f1630b1f53156a9723ae5431f2fb1e54786593b9asapersson@webrtc.org                                    int* encode_usage_percent,
128f1630b1f53156a9723ae5431f2fb1e54786593b9asapersson@webrtc.org                                    int* capture_queue_delay_ms_per_s) {
1294747585bba09508c7475bf1e5f70a0b981175d9fasapersson@webrtc.org  ViEChannelManagerScoped cs(*(shared_data_.channel_manager()));
1304747585bba09508c7475bf1e5f70a0b981175d9fasapersson@webrtc.org  ViEChannel* vie_channel = cs.Channel(video_channel);
1314747585bba09508c7475bf1e5f70a0b981175d9fasapersson@webrtc.org  if (!vie_channel) {
1324747585bba09508c7475bf1e5f70a0b981175d9fasapersson@webrtc.org    shared_data_.SetLastError(kViEBaseInvalidChannelId);
1334747585bba09508c7475bf1e5f70a0b981175d9fasapersson@webrtc.org    return -1;
1344747585bba09508c7475bf1e5f70a0b981175d9fasapersson@webrtc.org  }
1354747585bba09508c7475bf1e5f70a0b981175d9fasapersson@webrtc.org  ViEEncoder* vie_encoder = cs.Encoder(video_channel);
1364747585bba09508c7475bf1e5f70a0b981175d9fasapersson@webrtc.org  assert(vie_encoder);
1374747585bba09508c7475bf1e5f70a0b981175d9fasapersson@webrtc.org
1384747585bba09508c7475bf1e5f70a0b981175d9fasapersson@webrtc.org  ViEInputManagerScoped is(*(shared_data_.input_manager()));
1394747585bba09508c7475bf1e5f70a0b981175d9fasapersson@webrtc.org  ViEFrameProviderBase* provider = is.FrameProvider(vie_encoder);
1404747585bba09508c7475bf1e5f70a0b981175d9fasapersson@webrtc.org  if (provider) {
1414747585bba09508c7475bf1e5f70a0b981175d9fasapersson@webrtc.org    ViECapturer* capturer = is.Capture(provider->Id());
1424747585bba09508c7475bf1e5f70a0b981175d9fasapersson@webrtc.org    if (capturer) {
1434e95436d6302be2854cd5b3e7baa3c4f563e4901asapersson@webrtc.org      CpuOveruseMetrics metrics;
1444e95436d6302be2854cd5b3e7baa3c4f563e4901asapersson@webrtc.org      capturer->GetCpuOveruseMetrics(&metrics);
1454e95436d6302be2854cd5b3e7baa3c4f563e4901asapersson@webrtc.org      *capture_jitter_ms = metrics.capture_jitter_ms;
1464e95436d6302be2854cd5b3e7baa3c4f563e4901asapersson@webrtc.org      *avg_encode_time_ms = metrics.avg_encode_time_ms;
1474e95436d6302be2854cd5b3e7baa3c4f563e4901asapersson@webrtc.org      *encode_usage_percent = metrics.encode_usage_percent;
1484e95436d6302be2854cd5b3e7baa3c4f563e4901asapersson@webrtc.org      *capture_queue_delay_ms_per_s = metrics.capture_queue_delay_ms_per_s;
1494e95436d6302be2854cd5b3e7baa3c4f563e4901asapersson@webrtc.org      return 0;
1504e95436d6302be2854cd5b3e7baa3c4f563e4901asapersson@webrtc.org    }
1514e95436d6302be2854cd5b3e7baa3c4f563e4901asapersson@webrtc.org  }
1524e95436d6302be2854cd5b3e7baa3c4f563e4901asapersson@webrtc.org  return -1;
1534e95436d6302be2854cd5b3e7baa3c4f563e4901asapersson@webrtc.org}
1544e95436d6302be2854cd5b3e7baa3c4f563e4901asapersson@webrtc.org
1554e95436d6302be2854cd5b3e7baa3c4f563e4901asapersson@webrtc.orgint ViEBaseImpl::GetCpuOveruseMetrics(int video_channel,
1564e95436d6302be2854cd5b3e7baa3c4f563e4901asapersson@webrtc.org                                      CpuOveruseMetrics* metrics) {
1574e95436d6302be2854cd5b3e7baa3c4f563e4901asapersson@webrtc.org  ViEChannelManagerScoped cs(*(shared_data_.channel_manager()));
1584e95436d6302be2854cd5b3e7baa3c4f563e4901asapersson@webrtc.org  ViEChannel* vie_channel = cs.Channel(video_channel);
1594e95436d6302be2854cd5b3e7baa3c4f563e4901asapersson@webrtc.org  if (!vie_channel) {
1604e95436d6302be2854cd5b3e7baa3c4f563e4901asapersson@webrtc.org    shared_data_.SetLastError(kViEBaseInvalidChannelId);
1614e95436d6302be2854cd5b3e7baa3c4f563e4901asapersson@webrtc.org    return -1;
1624e95436d6302be2854cd5b3e7baa3c4f563e4901asapersson@webrtc.org  }
1634e95436d6302be2854cd5b3e7baa3c4f563e4901asapersson@webrtc.org  ViEEncoder* vie_encoder = cs.Encoder(video_channel);
1644e95436d6302be2854cd5b3e7baa3c4f563e4901asapersson@webrtc.org  assert(vie_encoder);
1654e95436d6302be2854cd5b3e7baa3c4f563e4901asapersson@webrtc.org
1664e95436d6302be2854cd5b3e7baa3c4f563e4901asapersson@webrtc.org  ViEInputManagerScoped is(*(shared_data_.input_manager()));
1674e95436d6302be2854cd5b3e7baa3c4f563e4901asapersson@webrtc.org  ViEFrameProviderBase* provider = is.FrameProvider(vie_encoder);
1684e95436d6302be2854cd5b3e7baa3c4f563e4901asapersson@webrtc.org  if (provider) {
1694e95436d6302be2854cd5b3e7baa3c4f563e4901asapersson@webrtc.org    ViECapturer* capturer = is.Capture(provider->Id());
1704e95436d6302be2854cd5b3e7baa3c4f563e4901asapersson@webrtc.org    if (capturer) {
1714e95436d6302be2854cd5b3e7baa3c4f563e4901asapersson@webrtc.org      capturer->GetCpuOveruseMetrics(metrics);
1724747585bba09508c7475bf1e5f70a0b981175d9fasapersson@webrtc.org      return 0;
1734747585bba09508c7475bf1e5f70a0b981175d9fasapersson@webrtc.org    }
1744747585bba09508c7475bf1e5f70a0b981175d9fasapersson@webrtc.org  }
1754747585bba09508c7475bf1e5f70a0b981175d9fasapersson@webrtc.org  return -1;
1764747585bba09508c7475bf1e5f70a0b981175d9fasapersson@webrtc.org}
1774747585bba09508c7475bf1e5f70a0b981175d9fasapersson@webrtc.org
178b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgint ViEBaseImpl::CreateChannel(int& video_channel) {  // NOLINT
179d2f95a8b894344de70a531ebcd3c2b7dfab12e27henrik.lundin@webrtc.org  return CreateChannel(video_channel, static_cast<const Config*>(NULL));
180d2f95a8b894344de70a531ebcd3c2b7dfab12e27henrik.lundin@webrtc.org}
181d2f95a8b894344de70a531ebcd3c2b7dfab12e27henrik.lundin@webrtc.org
182d2f95a8b894344de70a531ebcd3c2b7dfab12e27henrik.lundin@webrtc.orgint ViEBaseImpl::CreateChannel(int& video_channel,  // NOLINT
183d2f95a8b894344de70a531ebcd3c2b7dfab12e27henrik.lundin@webrtc.org                               const Config* config) {
184d2f95a8b894344de70a531ebcd3c2b7dfab12e27henrik.lundin@webrtc.org  if (shared_data_.channel_manager()->CreateChannel(&video_channel,
185d2f95a8b894344de70a531ebcd3c2b7dfab12e27henrik.lundin@webrtc.org                                                    config) == -1) {
186b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    video_channel = -1;
187b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    shared_data_.SetLastError(kViEBaseChannelCreationFailed);
188b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    return -1;
189b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  }
190022615bd918aec7671968ad2b873d1487365980cmflodman@webrtc.org  LOG(LS_INFO) << "Video channel created: " << video_channel;
191b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  return 0;
192b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
193b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
194b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgint ViEBaseImpl::CreateChannel(int& video_channel,  // NOLINT
195b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org                               int original_channel) {
196b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  return CreateChannel(video_channel, original_channel, true);
197b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
198b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
199b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgint ViEBaseImpl::CreateReceiveChannel(int& video_channel,  // NOLINT
200b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org                                      int original_channel) {
201b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  return CreateChannel(video_channel, original_channel, false);
202b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
203b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
204b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgint ViEBaseImpl::DeleteChannel(const int video_channel) {
205b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  {
206b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    ViEChannelManagerScoped cs(*(shared_data_.channel_manager()));
207b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    ViEChannel* vie_channel = cs.Channel(video_channel);
208b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    if (!vie_channel) {
209b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org      shared_data_.SetLastError(kViEBaseInvalidChannelId);
210b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org      return -1;
211b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    }
212b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
213b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    // Deregister the ViEEncoder if no other channel is using it.
214b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    ViEEncoder* vie_encoder = cs.Encoder(video_channel);
215b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    if (cs.ChannelUsingViEEncoder(video_channel) == false) {
216b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org      ViEInputManagerScoped is(*(shared_data_.input_manager()));
217b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org      ViEFrameProviderBase* provider = is.FrameProvider(vie_encoder);
218b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org      if (provider) {
219b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        provider->DeregisterFrameCallback(vie_encoder);
220b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org      }
221b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    }
222b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  }
223b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
224b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  if (shared_data_.channel_manager()->DeleteChannel(video_channel) == -1) {
225b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    shared_data_.SetLastError(kViEBaseUnknownError);
226b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    return -1;
227b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  }
228022615bd918aec7671968ad2b873d1487365980cmflodman@webrtc.org  LOG(LS_INFO) << "Channel deleted " << video_channel;
229b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  return 0;
230b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
231b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
232b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgint ViEBaseImpl::ConnectAudioChannel(const int video_channel,
233b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org                                     const int audio_channel) {
234022615bd918aec7671968ad2b873d1487365980cmflodman@webrtc.org  LOG_F(LS_INFO) << "ConnectAudioChannel, video channel " << video_channel
235022615bd918aec7671968ad2b873d1487365980cmflodman@webrtc.org                 << ", audio channel " << audio_channel;
236b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  ViEChannelManagerScoped cs(*(shared_data_.channel_manager()));
237b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  if (!cs.Channel(video_channel)) {
238b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    shared_data_.SetLastError(kViEBaseInvalidChannelId);
239b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    return -1;
240b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  }
241b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
242b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  if (shared_data_.channel_manager()->ConnectVoiceChannel(video_channel,
243b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org                                                          audio_channel) != 0) {
244b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    shared_data_.SetLastError(kViEBaseVoEFailure);
245b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    return -1;
246b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  }
247b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  return 0;
248b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
249b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
250b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgint ViEBaseImpl::DisconnectAudioChannel(const int video_channel) {
251022615bd918aec7671968ad2b873d1487365980cmflodman@webrtc.org  LOG_F(LS_INFO) << "DisconnectAudioChannel " << video_channel;
252b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  ViEChannelManagerScoped cs(*(shared_data_.channel_manager()));
253b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  if (!cs.Channel(video_channel)) {
254b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    shared_data_.SetLastError(kViEBaseInvalidChannelId);
255b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    return -1;
256b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  }
257b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
258b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  if (shared_data_.channel_manager()->DisconnectVoiceChannel(
259b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org      video_channel) != 0) {
260b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    shared_data_.SetLastError(kViEBaseVoEFailure);
261b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    return -1;
262b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  }
263b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  return 0;
264b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
265b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
266b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgint ViEBaseImpl::StartSend(const int video_channel) {
267022615bd918aec7671968ad2b873d1487365980cmflodman@webrtc.org  LOG_F(LS_INFO) << "StartSend: " << video_channel;
268b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  ViEChannelManagerScoped cs(*(shared_data_.channel_manager()));
269b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  ViEChannel* vie_channel = cs.Channel(video_channel);
270b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  if (!vie_channel) {
271b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    shared_data_.SetLastError(kViEBaseInvalidChannelId);
272b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    return -1;
273b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  }
274b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
275b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  ViEEncoder* vie_encoder = cs.Encoder(video_channel);
276b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  assert(vie_encoder != NULL);
277b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  if (vie_encoder->Owner() != video_channel) {
278022615bd918aec7671968ad2b873d1487365980cmflodman@webrtc.org    LOG_F(LS_ERROR) <<  "Can't start send on a receive only channel.";
279b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    shared_data_.SetLastError(kViEBaseReceiveOnlyChannel);
280b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    return -1;
281b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  }
282b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
283b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  // Pause and trigger a key frame.
284b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  vie_encoder->Pause();
28567879bc2e69d7907b7ceb92135a34f77fe643e7fpbos@webrtc.org  int32_t error = vie_channel->StartSend();
286b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  if (error != 0) {
287b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    vie_encoder->Restart();
288b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    if (error == kViEBaseAlreadySending) {
289b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org      shared_data_.SetLastError(kViEBaseAlreadySending);
290b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    }
291022615bd918aec7671968ad2b873d1487365980cmflodman@webrtc.org    LOG_F(LS_ERROR) << "Could not start sending " << video_channel;
292b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    shared_data_.SetLastError(kViEBaseUnknownError);
293b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    return -1;
294b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  }
295b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  vie_encoder->SendKeyFrame();
296b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  vie_encoder->Restart();
297b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  return 0;
298b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
299b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
300b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgint ViEBaseImpl::StopSend(const int video_channel) {
301022615bd918aec7671968ad2b873d1487365980cmflodman@webrtc.org  LOG_F(LS_INFO) << "StopSend " << video_channel;
302b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
303b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  ViEChannelManagerScoped cs(*(shared_data_.channel_manager()));
304b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  ViEChannel* vie_channel = cs.Channel(video_channel);
305b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  if (!vie_channel) {
306b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    shared_data_.SetLastError(kViEBaseInvalidChannelId);
307b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    return -1;
308b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  }
309b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
31067879bc2e69d7907b7ceb92135a34f77fe643e7fpbos@webrtc.org  int32_t error = vie_channel->StopSend();
311b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  if (error != 0) {
312b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    if (error == kViEBaseNotSending) {
313b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org      shared_data_.SetLastError(kViEBaseNotSending);
314b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    } else {
315022615bd918aec7671968ad2b873d1487365980cmflodman@webrtc.org      LOG_F(LS_ERROR) << "Could not stop sending " << video_channel;
316b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org      shared_data_.SetLastError(kViEBaseUnknownError);
317b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    }
318b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    return -1;
319b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  }
320b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  return 0;
321b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
322b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
323b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgint ViEBaseImpl::StartReceive(const int video_channel) {
324022615bd918aec7671968ad2b873d1487365980cmflodman@webrtc.org  LOG_F(LS_INFO) << "StartReceive " << video_channel;
325b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
326b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  ViEChannelManagerScoped cs(*(shared_data_.channel_manager()));
327b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  ViEChannel* vie_channel = cs.Channel(video_channel);
328b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  if (!vie_channel) {
329b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    shared_data_.SetLastError(kViEBaseInvalidChannelId);
330b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    return -1;
331b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  }
332b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  if (vie_channel->StartReceive() != 0) {
333b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    shared_data_.SetLastError(kViEBaseUnknownError);
334b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    return -1;
335b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  }
336b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  return 0;
337b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
338b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
339b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgint ViEBaseImpl::StopReceive(const int video_channel) {
340022615bd918aec7671968ad2b873d1487365980cmflodman@webrtc.org  LOG_F(LS_INFO) << "StopReceive " << video_channel;
341b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  ViEChannelManagerScoped cs(*(shared_data_.channel_manager()));
342b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  ViEChannel* vie_channel = cs.Channel(video_channel);
343b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  if (!vie_channel) {
344b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    shared_data_.SetLastError(kViEBaseInvalidChannelId);
345b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    return -1;
346b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  }
347b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  if (vie_channel->StopReceive() != 0) {
348b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    shared_data_.SetLastError(kViEBaseUnknownError);
349b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    return -1;
350b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  }
351b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  return 0;
352b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
353b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
354b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgint ViEBaseImpl::GetVersion(char version[1024]) {
355b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  assert(kViEVersionMaxMessageSize == 1024);
356b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  if (!version) {
357b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    shared_data_.SetLastError(kViEBaseInvalidArgument);
358b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    return -1;
359b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  }
360b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
361b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  // Add WebRTC Version.
362b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  std::stringstream version_stream;
363dc1a607dbfec1e251d3e9d45add0dcb8223036d1tnakamura@webrtc.org  version_stream << "VideoEngine 3.54.0" << std::endl;
364b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
365b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  // Add build info.
366c7d736366468e04cd818fd74ee4844b954012614andrew@webrtc.org  version_stream << "Build: " << BUILDINFO << std::endl;
367b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
368b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  int version_length = version_stream.tellp();
369b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  assert(version_length < 1024);
370b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  memcpy(version, version_stream.str().c_str(), version_length);
371b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  version[version_length] = '\0';
372b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  return 0;
373b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
374b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
375b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgint ViEBaseImpl::LastError() {
376b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  return shared_data_.LastErrorInternal();
377b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
378b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
379b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgint ViEBaseImpl::CreateChannel(int& video_channel,  // NOLINT
380b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org                               int original_channel, bool sender) {
381b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  ViEChannelManagerScoped cs(*(shared_data_.channel_manager()));
382b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  if (!cs.Channel(original_channel)) {
383b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    shared_data_.SetLastError(kViEBaseInvalidChannelId);
384b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    return -1;
385b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  }
386b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
387b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  if (shared_data_.channel_manager()->CreateChannel(&video_channel,
388b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org                                                    original_channel,
389b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org                                                    sender) == -1) {
390b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    video_channel = -1;
391b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    shared_data_.SetLastError(kViEBaseChannelCreationFailed);
392b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    return -1;
393b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  }
394022615bd918aec7671968ad2b873d1487365980cmflodman@webrtc.org  LOG_F(LS_INFO) << "VideoChannel created: " << video_channel
395022615bd918aec7671968ad2b873d1487365980cmflodman@webrtc.org                 << ", base channel " << original_channel
396022615bd918aec7671968ad2b873d1487365980cmflodman@webrtc.org                 << ", is send channel : " << sender;
397b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  return 0;
398b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
399b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
400b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}  // namespace webrtc
401