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_external_codec_impl.h"
12
13#include "webrtc/engine_configurations.h"
14#include "webrtc/system_wrappers/interface/logging.h"
15#include "webrtc/video_engine/include/vie_errors.h"
16#include "webrtc/video_engine/vie_channel.h"
17#include "webrtc/video_engine/vie_channel_manager.h"
18#include "webrtc/video_engine/vie_encoder.h"
19#include "webrtc/video_engine/vie_impl.h"
20#include "webrtc/video_engine/vie_shared_data.h"
21
22namespace webrtc {
23
24ViEExternalCodec* ViEExternalCodec::GetInterface(VideoEngine* video_engine) {
25#ifdef WEBRTC_VIDEO_ENGINE_EXTERNAL_CODEC_API
26  if (video_engine == NULL) {
27    return NULL;
28  }
29  VideoEngineImpl* vie_impl = static_cast<VideoEngineImpl*>(video_engine);
30  ViEExternalCodecImpl* vie_external_codec_impl = vie_impl;
31  // Increase ref count.
32  (*vie_external_codec_impl)++;
33  return vie_external_codec_impl;
34#else
35  return NULL;
36#endif
37}
38
39int ViEExternalCodecImpl::Release() {
40  // Decrease ref count.
41  (*this)--;
42
43  int32_t ref_count = GetCount();
44  if (ref_count < 0) {
45    LOG(LS_WARNING) << "ViEExternalCodec released too many times.";
46    shared_data_->SetLastError(kViEAPIDoesNotExist);
47    return -1;
48  }
49  return ref_count;
50}
51
52ViEExternalCodecImpl::ViEExternalCodecImpl(ViESharedData* shared_data)
53    : shared_data_(shared_data) {
54}
55
56ViEExternalCodecImpl::~ViEExternalCodecImpl() {
57}
58
59int ViEExternalCodecImpl::RegisterExternalSendCodec(const int video_channel,
60                                                    const unsigned char pl_type,
61                                                    VideoEncoder* encoder,
62                                                    bool internal_source) {
63  assert(encoder != NULL);
64  LOG(LS_INFO) << "Register external encoder for channel " << video_channel
65               << ", pl_type " << static_cast<int>(pl_type)
66               << ", internal_source " << internal_source;
67
68  ViEChannelManagerScoped cs(*(shared_data_->channel_manager()));
69  ViEEncoder* vie_encoder = cs.Encoder(video_channel);
70  if (!vie_encoder) {
71    shared_data_->SetLastError(kViECodecInvalidArgument);
72    return -1;
73  }
74  if (vie_encoder->RegisterExternalEncoder(encoder, pl_type,
75                                           internal_source) != 0) {
76    shared_data_->SetLastError(kViECodecUnknownError);
77    return -1;
78  }
79  return 0;
80}
81
82int ViEExternalCodecImpl::DeRegisterExternalSendCodec(
83  const int video_channel, const unsigned char pl_type) {
84  LOG(LS_INFO) << "Deregister external encoder for channel " << video_channel;
85
86  ViEChannelManagerScoped cs(*(shared_data_->channel_manager()));
87  ViEEncoder* vie_encoder = cs.Encoder(video_channel);
88  if (!vie_encoder) {
89    shared_data_->SetLastError(kViECodecInvalidArgument);
90    return -1;
91  }
92
93  if (vie_encoder->DeRegisterExternalEncoder(pl_type) != 0) {
94    shared_data_->SetLastError(kViECodecUnknownError);
95    return -1;
96  }
97  return 0;
98}
99
100int ViEExternalCodecImpl::RegisterExternalReceiveCodec(
101    const int video_channel,
102    const unsigned int pl_type,
103    VideoDecoder* decoder,
104    bool decoder_render,
105    int render_delay) {
106  LOG(LS_INFO) << "Register exrernal decoder for channel " << video_channel
107               << ", pl_type " << pl_type
108               << ", decoder_render " << decoder_render
109               << ", render_delay " << render_delay;
110  assert(decoder != NULL);
111
112  ViEChannelManagerScoped cs(*(shared_data_->channel_manager()));
113  ViEChannel* vie_channel = cs.Channel(video_channel);
114  if (!vie_channel) {
115    shared_data_->SetLastError(kViECodecInvalidArgument);
116    return -1;
117  }
118
119  if (vie_channel->RegisterExternalDecoder(pl_type, decoder, decoder_render,
120                                           render_delay) != 0) {
121    shared_data_->SetLastError(kViECodecUnknownError);
122    return -1;
123  }
124  return 0;
125}
126
127int ViEExternalCodecImpl::DeRegisterExternalReceiveCodec(
128    const int video_channel, const unsigned char pl_type) {
129  LOG(LS_INFO) << "DeRegisterExternalReceiveCodec for channel " << video_channel
130               << ", pl_type " << pl_type;
131
132  ViEChannelManagerScoped cs(*(shared_data_->channel_manager()));
133  ViEChannel* vie_channel = cs.Channel(video_channel);
134  if (!vie_channel) {
135    shared_data_->SetLastError(kViECodecInvalidArgument);
136    return -1;
137  }
138  if (vie_channel->DeRegisterExternalDecoder(pl_type) != 0) {
139    shared_data_->SetLastError(kViECodecUnknownError);
140    return -1;
141  }
142  return 0;
143}
144
145}  // namespace webrtc
146