Home | History | Annotate | Download | only in video_engine
      1 /*
      2  *  Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
      3  *
      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 
     11 #include "webrtc/video_engine/vie_base_impl.h"
     12 
     13 #include <sstream>
     14 #include <string>
     15 #include <utility>
     16 
     17 #include "webrtc/engine_configurations.h"
     18 #include "webrtc/modules/rtp_rtcp/interface/rtp_rtcp.h"
     19 #include "webrtc/modules/video_coding/main/interface/video_coding.h"
     20 #include "webrtc/modules/video_processing/main/interface/video_processing.h"
     21 #include "webrtc/modules/video_render/include/video_render.h"
     22 #include "webrtc/system_wrappers/interface/critical_section_wrapper.h"
     23 #include "webrtc/system_wrappers/interface/logging.h"
     24 #include "webrtc/video_engine/include/vie_errors.h"
     25 #include "webrtc/video_engine/vie_capturer.h"
     26 #include "webrtc/video_engine/vie_channel.h"
     27 #include "webrtc/video_engine/vie_channel_manager.h"
     28 #include "webrtc/video_engine/vie_defines.h"
     29 #include "webrtc/video_engine/vie_encoder.h"
     30 #include "webrtc/video_engine/vie_impl.h"
     31 #include "webrtc/video_engine/vie_input_manager.h"
     32 #include "webrtc/video_engine/vie_shared_data.h"
     33 
     34 namespace webrtc {
     35 
     36 ViEBase* ViEBase::GetInterface(VideoEngine* video_engine) {
     37   if (!video_engine) {
     38     return NULL;
     39   }
     40   VideoEngineImpl* vie_impl = static_cast<VideoEngineImpl*>(video_engine);
     41   ViEBaseImpl* vie_base_impl = vie_impl;
     42   (*vie_base_impl)++;  // Increase ref count.
     43 
     44   return vie_base_impl;
     45 }
     46 
     47 int ViEBaseImpl::Release() {
     48   (*this)--;  // Decrease ref count.
     49 
     50   int32_t ref_count = GetCount();
     51   if (ref_count < 0) {
     52     LOG(LS_WARNING) << "ViEBase released too many times.";
     53     return -1;
     54   }
     55   return ref_count;
     56 }
     57 
     58 ViEBaseImpl::ViEBaseImpl(const Config& config)
     59     : shared_data_(config) {}
     60 
     61 ViEBaseImpl::~ViEBaseImpl() {}
     62 
     63 int ViEBaseImpl::Init() {
     64   return 0;
     65 }
     66 
     67 int ViEBaseImpl::SetVoiceEngine(VoiceEngine* voice_engine) {
     68   LOG_F(LS_INFO) << "SetVoiceEngine";
     69   if (shared_data_.channel_manager()->SetVoiceEngine(voice_engine) != 0) {
     70     shared_data_.SetLastError(kViEBaseVoEFailure);
     71     return -1;
     72   }
     73   return 0;
     74 }
     75 
     76 int ViEBaseImpl::RegisterCpuOveruseObserver(int video_channel,
     77                                             CpuOveruseObserver* observer) {
     78   LOG_F(LS_INFO) << "RegisterCpuOveruseObserver on channel " << video_channel;
     79   ViEChannelManagerScoped cs(*(shared_data_.channel_manager()));
     80   ViEChannel* vie_channel = cs.Channel(video_channel);
     81   if (!vie_channel) {
     82     shared_data_.SetLastError(kViEBaseInvalidChannelId);
     83     return -1;
     84   }
     85   ViEEncoder* vie_encoder = cs.Encoder(video_channel);
     86   assert(vie_encoder);
     87 
     88   ViEInputManagerScoped is(*(shared_data_.input_manager()));
     89   ViEFrameProviderBase* provider = is.FrameProvider(vie_encoder);
     90   if (provider) {
     91     ViECapturer* capturer = is.Capture(provider->Id());
     92     assert(capturer);
     93     capturer->RegisterCpuOveruseObserver(observer);
     94   }
     95 
     96   shared_data_.overuse_observers()->insert(
     97       std::pair<int, CpuOveruseObserver*>(video_channel, observer));
     98   return 0;
     99 }
    100 
    101 int ViEBaseImpl::SetCpuOveruseOptions(int video_channel,
    102                                       const CpuOveruseOptions& options) {
    103   ViEChannelManagerScoped cs(*(shared_data_.channel_manager()));
    104   ViEChannel* vie_channel = cs.Channel(video_channel);
    105   if (!vie_channel) {
    106     shared_data_.SetLastError(kViEBaseInvalidChannelId);
    107     return -1;
    108   }
    109   ViEEncoder* vie_encoder = cs.Encoder(video_channel);
    110   assert(vie_encoder);
    111 
    112   ViEInputManagerScoped is(*(shared_data_.input_manager()));
    113   ViEFrameProviderBase* provider = is.FrameProvider(vie_encoder);
    114   if (provider) {
    115     ViECapturer* capturer = is.Capture(provider->Id());
    116     if (capturer) {
    117       capturer->SetCpuOveruseOptions(options);
    118       return 0;
    119     }
    120   }
    121   return -1;
    122 }
    123 
    124 int ViEBaseImpl::CpuOveruseMeasures(int video_channel,
    125                                     int* capture_jitter_ms,
    126                                     int* avg_encode_time_ms,
    127                                     int* encode_usage_percent,
    128                                     int* capture_queue_delay_ms_per_s) {
    129   ViEChannelManagerScoped cs(*(shared_data_.channel_manager()));
    130   ViEChannel* vie_channel = cs.Channel(video_channel);
    131   if (!vie_channel) {
    132     shared_data_.SetLastError(kViEBaseInvalidChannelId);
    133     return -1;
    134   }
    135   ViEEncoder* vie_encoder = cs.Encoder(video_channel);
    136   assert(vie_encoder);
    137 
    138   ViEInputManagerScoped is(*(shared_data_.input_manager()));
    139   ViEFrameProviderBase* provider = is.FrameProvider(vie_encoder);
    140   if (provider) {
    141     ViECapturer* capturer = is.Capture(provider->Id());
    142     if (capturer) {
    143       CpuOveruseMetrics metrics;
    144       capturer->GetCpuOveruseMetrics(&metrics);
    145       *capture_jitter_ms = metrics.capture_jitter_ms;
    146       *avg_encode_time_ms = metrics.avg_encode_time_ms;
    147       *encode_usage_percent = metrics.encode_usage_percent;
    148       *capture_queue_delay_ms_per_s = metrics.capture_queue_delay_ms_per_s;
    149       return 0;
    150     }
    151   }
    152   return -1;
    153 }
    154 
    155 int ViEBaseImpl::GetCpuOveruseMetrics(int video_channel,
    156                                       CpuOveruseMetrics* metrics) {
    157   ViEChannelManagerScoped cs(*(shared_data_.channel_manager()));
    158   ViEChannel* vie_channel = cs.Channel(video_channel);
    159   if (!vie_channel) {
    160     shared_data_.SetLastError(kViEBaseInvalidChannelId);
    161     return -1;
    162   }
    163   ViEEncoder* vie_encoder = cs.Encoder(video_channel);
    164   assert(vie_encoder);
    165 
    166   ViEInputManagerScoped is(*(shared_data_.input_manager()));
    167   ViEFrameProviderBase* provider = is.FrameProvider(vie_encoder);
    168   if (provider) {
    169     ViECapturer* capturer = is.Capture(provider->Id());
    170     if (capturer) {
    171       capturer->GetCpuOveruseMetrics(metrics);
    172       return 0;
    173     }
    174   }
    175   return -1;
    176 }
    177 
    178 int ViEBaseImpl::CreateChannel(int& video_channel) {  // NOLINT
    179   return CreateChannel(video_channel, static_cast<const Config*>(NULL));
    180 }
    181 
    182 int ViEBaseImpl::CreateChannel(int& video_channel,  // NOLINT
    183                                const Config* config) {
    184   if (shared_data_.channel_manager()->CreateChannel(&video_channel,
    185                                                     config) == -1) {
    186     video_channel = -1;
    187     shared_data_.SetLastError(kViEBaseChannelCreationFailed);
    188     return -1;
    189   }
    190   LOG(LS_INFO) << "Video channel created: " << video_channel;
    191   return 0;
    192 }
    193 
    194 int ViEBaseImpl::CreateChannel(int& video_channel,  // NOLINT
    195                                int original_channel) {
    196   return CreateChannel(video_channel, original_channel, true);
    197 }
    198 
    199 int ViEBaseImpl::CreateReceiveChannel(int& video_channel,  // NOLINT
    200                                       int original_channel) {
    201   return CreateChannel(video_channel, original_channel, false);
    202 }
    203 
    204 int ViEBaseImpl::DeleteChannel(const int video_channel) {
    205   {
    206     ViEChannelManagerScoped cs(*(shared_data_.channel_manager()));
    207     ViEChannel* vie_channel = cs.Channel(video_channel);
    208     if (!vie_channel) {
    209       shared_data_.SetLastError(kViEBaseInvalidChannelId);
    210       return -1;
    211     }
    212 
    213     // Deregister the ViEEncoder if no other channel is using it.
    214     ViEEncoder* vie_encoder = cs.Encoder(video_channel);
    215     if (cs.ChannelUsingViEEncoder(video_channel) == false) {
    216       ViEInputManagerScoped is(*(shared_data_.input_manager()));
    217       ViEFrameProviderBase* provider = is.FrameProvider(vie_encoder);
    218       if (provider) {
    219         provider->DeregisterFrameCallback(vie_encoder);
    220       }
    221     }
    222   }
    223 
    224   if (shared_data_.channel_manager()->DeleteChannel(video_channel) == -1) {
    225     shared_data_.SetLastError(kViEBaseUnknownError);
    226     return -1;
    227   }
    228   LOG(LS_INFO) << "Channel deleted " << video_channel;
    229   return 0;
    230 }
    231 
    232 int ViEBaseImpl::ConnectAudioChannel(const int video_channel,
    233                                      const int audio_channel) {
    234   LOG_F(LS_INFO) << "ConnectAudioChannel, video channel " << video_channel
    235                  << ", audio channel " << audio_channel;
    236   ViEChannelManagerScoped cs(*(shared_data_.channel_manager()));
    237   if (!cs.Channel(video_channel)) {
    238     shared_data_.SetLastError(kViEBaseInvalidChannelId);
    239     return -1;
    240   }
    241 
    242   if (shared_data_.channel_manager()->ConnectVoiceChannel(video_channel,
    243                                                           audio_channel) != 0) {
    244     shared_data_.SetLastError(kViEBaseVoEFailure);
    245     return -1;
    246   }
    247   return 0;
    248 }
    249 
    250 int ViEBaseImpl::DisconnectAudioChannel(const int video_channel) {
    251   LOG_F(LS_INFO) << "DisconnectAudioChannel " << video_channel;
    252   ViEChannelManagerScoped cs(*(shared_data_.channel_manager()));
    253   if (!cs.Channel(video_channel)) {
    254     shared_data_.SetLastError(kViEBaseInvalidChannelId);
    255     return -1;
    256   }
    257 
    258   if (shared_data_.channel_manager()->DisconnectVoiceChannel(
    259       video_channel) != 0) {
    260     shared_data_.SetLastError(kViEBaseVoEFailure);
    261     return -1;
    262   }
    263   return 0;
    264 }
    265 
    266 int ViEBaseImpl::StartSend(const int video_channel) {
    267   LOG_F(LS_INFO) << "StartSend: " << video_channel;
    268   ViEChannelManagerScoped cs(*(shared_data_.channel_manager()));
    269   ViEChannel* vie_channel = cs.Channel(video_channel);
    270   if (!vie_channel) {
    271     shared_data_.SetLastError(kViEBaseInvalidChannelId);
    272     return -1;
    273   }
    274 
    275   ViEEncoder* vie_encoder = cs.Encoder(video_channel);
    276   assert(vie_encoder != NULL);
    277   if (vie_encoder->Owner() != video_channel) {
    278     LOG_F(LS_ERROR) <<  "Can't start send on a receive only channel.";
    279     shared_data_.SetLastError(kViEBaseReceiveOnlyChannel);
    280     return -1;
    281   }
    282 
    283   // Pause and trigger a key frame.
    284   vie_encoder->Pause();
    285   int32_t error = vie_channel->StartSend();
    286   if (error != 0) {
    287     vie_encoder->Restart();
    288     if (error == kViEBaseAlreadySending) {
    289       shared_data_.SetLastError(kViEBaseAlreadySending);
    290     }
    291     LOG_F(LS_ERROR) << "Could not start sending " << video_channel;
    292     shared_data_.SetLastError(kViEBaseUnknownError);
    293     return -1;
    294   }
    295   vie_encoder->SendKeyFrame();
    296   vie_encoder->Restart();
    297   return 0;
    298 }
    299 
    300 int ViEBaseImpl::StopSend(const int video_channel) {
    301   LOG_F(LS_INFO) << "StopSend " << video_channel;
    302 
    303   ViEChannelManagerScoped cs(*(shared_data_.channel_manager()));
    304   ViEChannel* vie_channel = cs.Channel(video_channel);
    305   if (!vie_channel) {
    306     shared_data_.SetLastError(kViEBaseInvalidChannelId);
    307     return -1;
    308   }
    309 
    310   int32_t error = vie_channel->StopSend();
    311   if (error != 0) {
    312     if (error == kViEBaseNotSending) {
    313       shared_data_.SetLastError(kViEBaseNotSending);
    314     } else {
    315       LOG_F(LS_ERROR) << "Could not stop sending " << video_channel;
    316       shared_data_.SetLastError(kViEBaseUnknownError);
    317     }
    318     return -1;
    319   }
    320   return 0;
    321 }
    322 
    323 int ViEBaseImpl::StartReceive(const int video_channel) {
    324   LOG_F(LS_INFO) << "StartReceive " << video_channel;
    325 
    326   ViEChannelManagerScoped cs(*(shared_data_.channel_manager()));
    327   ViEChannel* vie_channel = cs.Channel(video_channel);
    328   if (!vie_channel) {
    329     shared_data_.SetLastError(kViEBaseInvalidChannelId);
    330     return -1;
    331   }
    332   if (vie_channel->StartReceive() != 0) {
    333     shared_data_.SetLastError(kViEBaseUnknownError);
    334     return -1;
    335   }
    336   return 0;
    337 }
    338 
    339 int ViEBaseImpl::StopReceive(const int video_channel) {
    340   LOG_F(LS_INFO) << "StopReceive " << video_channel;
    341   ViEChannelManagerScoped cs(*(shared_data_.channel_manager()));
    342   ViEChannel* vie_channel = cs.Channel(video_channel);
    343   if (!vie_channel) {
    344     shared_data_.SetLastError(kViEBaseInvalidChannelId);
    345     return -1;
    346   }
    347   if (vie_channel->StopReceive() != 0) {
    348     shared_data_.SetLastError(kViEBaseUnknownError);
    349     return -1;
    350   }
    351   return 0;
    352 }
    353 
    354 int ViEBaseImpl::GetVersion(char version[1024]) {
    355   assert(kViEVersionMaxMessageSize == 1024);
    356   if (!version) {
    357     shared_data_.SetLastError(kViEBaseInvalidArgument);
    358     return -1;
    359   }
    360 
    361   // Add WebRTC Version.
    362   std::stringstream version_stream;
    363   version_stream << "VideoEngine 3.54.0" << std::endl;
    364 
    365   // Add build info.
    366   version_stream << "Build: " << BUILDINFO << std::endl;
    367 
    368   int version_length = version_stream.tellp();
    369   assert(version_length < 1024);
    370   memcpy(version, version_stream.str().c_str(), version_length);
    371   version[version_length] = '\0';
    372   return 0;
    373 }
    374 
    375 int ViEBaseImpl::LastError() {
    376   return shared_data_.LastErrorInternal();
    377 }
    378 
    379 int ViEBaseImpl::CreateChannel(int& video_channel,  // NOLINT
    380                                int original_channel, bool sender) {
    381   ViEChannelManagerScoped cs(*(shared_data_.channel_manager()));
    382   if (!cs.Channel(original_channel)) {
    383     shared_data_.SetLastError(kViEBaseInvalidChannelId);
    384     return -1;
    385   }
    386 
    387   if (shared_data_.channel_manager()->CreateChannel(&video_channel,
    388                                                     original_channel,
    389                                                     sender) == -1) {
    390     video_channel = -1;
    391     shared_data_.SetLastError(kViEBaseChannelCreationFailed);
    392     return -1;
    393   }
    394   LOG_F(LS_INFO) << "VideoChannel created: " << video_channel
    395                  << ", base channel " << original_channel
    396                  << ", is send channel : " << sender;
    397   return 0;
    398 }
    399 
    400 }  // namespace webrtc
    401