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/voice_engine/voe_video_sync_impl.h"
12
13#include "webrtc/system_wrappers/interface/critical_section_wrapper.h"
14#include "webrtc/system_wrappers/interface/trace.h"
15#include "webrtc/voice_engine/channel.h"
16#include "webrtc/voice_engine/include/voe_errors.h"
17#include "webrtc/voice_engine/voice_engine_impl.h"
18
19namespace webrtc {
20
21VoEVideoSync* VoEVideoSync::GetInterface(VoiceEngine* voiceEngine)
22{
23#ifndef WEBRTC_VOICE_ENGINE_VIDEO_SYNC_API
24    return NULL;
25#else
26    if (NULL == voiceEngine)
27    {
28        return NULL;
29    }
30    VoiceEngineImpl* s = static_cast<VoiceEngineImpl*>(voiceEngine);
31    s->AddRef();
32    return s;
33#endif
34}
35
36#ifdef WEBRTC_VOICE_ENGINE_VIDEO_SYNC_API
37
38VoEVideoSyncImpl::VoEVideoSyncImpl(voe::SharedData* shared) : _shared(shared)
39{
40    WEBRTC_TRACE(kTraceMemory, kTraceVoice, VoEId(_shared->instance_id(), -1),
41                 "VoEVideoSyncImpl::VoEVideoSyncImpl() - ctor");
42}
43
44VoEVideoSyncImpl::~VoEVideoSyncImpl()
45{
46    WEBRTC_TRACE(kTraceMemory, kTraceVoice, VoEId(_shared->instance_id(), -1),
47                 "VoEVideoSyncImpl::~VoEVideoSyncImpl() - dtor");
48}
49
50int VoEVideoSyncImpl::GetPlayoutTimestamp(int channel, unsigned int& timestamp)
51{
52    WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_shared->instance_id(), -1),
53                 "GetPlayoutTimestamp(channel=%d, timestamp=?)", channel);
54
55    if (!_shared->statistics().Initialized())
56    {
57        _shared->SetLastError(VE_NOT_INITED, kTraceError);
58        return -1;
59    }
60    voe::ChannelOwner ch = _shared->channel_manager().GetChannel(channel);
61    voe::Channel* channel_ptr = ch.channel();
62    if (channel_ptr == NULL)
63    {
64        _shared->SetLastError(VE_CHANNEL_NOT_VALID, kTraceError,
65            "GetPlayoutTimestamp() failed to locate channel");
66        return -1;
67    }
68    return channel_ptr->GetPlayoutTimestamp(timestamp);
69}
70
71int VoEVideoSyncImpl::SetInitTimestamp(int channel,
72                                       unsigned int timestamp)
73{
74    WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_shared->instance_id(), -1),
75                 "SetInitTimestamp(channel=%d, timestamp=%lu)",
76                 channel, timestamp);
77
78    if (!_shared->statistics().Initialized())
79    {
80        _shared->SetLastError(VE_NOT_INITED, kTraceError);
81        return -1;
82    }
83    voe::ChannelOwner ch = _shared->channel_manager().GetChannel(channel);
84    voe::Channel* channelPtr = ch.channel();
85    if (channelPtr == NULL)
86    {
87        _shared->SetLastError(VE_CHANNEL_NOT_VALID, kTraceError,
88            "SetInitTimestamp() failed to locate channel");
89        return -1;
90    }
91    return channelPtr->SetInitTimestamp(timestamp);
92}
93
94int VoEVideoSyncImpl::SetInitSequenceNumber(int channel,
95                                            short sequenceNumber)
96{
97    WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_shared->instance_id(), -1),
98                 "SetInitSequenceNumber(channel=%d, sequenceNumber=%hd)",
99                 channel, sequenceNumber);
100
101    if (!_shared->statistics().Initialized())
102    {
103        _shared->SetLastError(VE_NOT_INITED, kTraceError);
104        return -1;
105    }
106    voe::ChannelOwner ch = _shared->channel_manager().GetChannel(channel);
107    voe::Channel* channelPtr = ch.channel();
108    if (channelPtr == NULL)
109    {
110        _shared->SetLastError(VE_CHANNEL_NOT_VALID, kTraceError,
111            "SetInitSequenceNumber() failed to locate channel");
112        return -1;
113    }
114    return channelPtr->SetInitSequenceNumber(sequenceNumber);
115}
116
117int VoEVideoSyncImpl::SetMinimumPlayoutDelay(int channel,int delayMs)
118{
119    WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_shared->instance_id(), -1),
120                 "SetMinimumPlayoutDelay(channel=%d, delayMs=%d)",
121                 channel, delayMs);
122
123    if (!_shared->statistics().Initialized())
124    {
125        _shared->SetLastError(VE_NOT_INITED, kTraceError);
126        return -1;
127    }
128    voe::ChannelOwner ch = _shared->channel_manager().GetChannel(channel);
129    voe::Channel* channelPtr = ch.channel();
130    if (channelPtr == NULL)
131    {
132        _shared->SetLastError(VE_CHANNEL_NOT_VALID, kTraceError,
133            "SetMinimumPlayoutDelay() failed to locate channel");
134        return -1;
135    }
136    return channelPtr->SetMinimumPlayoutDelay(delayMs);
137}
138
139int VoEVideoSyncImpl::SetInitialPlayoutDelay(int channel, int delay_ms)
140{
141    WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_shared->instance_id(), -1),
142                 "SetInitialPlayoutDelay(channel=%d, delay_ms=%d)",
143                 channel, delay_ms);
144
145    if (!_shared->statistics().Initialized())
146    {
147        _shared->SetLastError(VE_NOT_INITED, kTraceError);
148        return -1;
149    }
150    voe::ChannelOwner ch = _shared->channel_manager().GetChannel(channel);
151    voe::Channel* channelPtr = ch.channel();
152    if (channelPtr == NULL)
153    {
154        _shared->SetLastError(VE_CHANNEL_NOT_VALID, kTraceError,
155            "SetInitialPlayoutDelay() failed to locate channel");
156        return -1;
157    }
158    return channelPtr->SetInitialPlayoutDelay(delay_ms);
159}
160
161int VoEVideoSyncImpl::GetDelayEstimate(int channel,
162                                       int* jitter_buffer_delay_ms,
163                                       int* playout_buffer_delay_ms) {
164  WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_shared->instance_id(), -1),
165               "GetDelayEstimate(channel=%d, delayMs=?)", channel);
166
167  if (!_shared->statistics().Initialized()) {
168    _shared->SetLastError(VE_NOT_INITED, kTraceError);
169    return -1;
170  }
171  voe::ChannelOwner ch = _shared->channel_manager().GetChannel(channel);
172  voe::Channel* channelPtr = ch.channel();
173  if (channelPtr == NULL) {
174    _shared->SetLastError(VE_CHANNEL_NOT_VALID, kTraceError,
175                          "GetDelayEstimate() failed to locate channel");
176    return -1;
177  }
178  if (!channelPtr->GetDelayEstimate(jitter_buffer_delay_ms,
179                                    playout_buffer_delay_ms)) {
180    return -1;
181  }
182  return 0;
183}
184
185int VoEVideoSyncImpl::GetPlayoutBufferSize(int& bufferMs)
186{
187    WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_shared->instance_id(), -1),
188               "GetPlayoutBufferSize(bufferMs=?)");
189
190    if (!_shared->statistics().Initialized())
191    {
192        _shared->SetLastError(VE_NOT_INITED, kTraceError);
193        return -1;
194    }
195    AudioDeviceModule::BufferType type
196        (AudioDeviceModule::kFixedBufferSize);
197    uint16_t sizeMS(0);
198    if (_shared->audio_device()->PlayoutBuffer(&type, &sizeMS) != 0)
199    {
200        _shared->SetLastError(VE_AUDIO_DEVICE_MODULE_ERROR, kTraceError,
201            "GetPlayoutBufferSize() failed to read buffer size");
202        return -1;
203    }
204    bufferMs = sizeMS;
205    WEBRTC_TRACE(kTraceStateInfo, kTraceVoice,
206        VoEId(_shared->instance_id(), -1),
207        "GetPlayoutBufferSize() => bufferMs=%d", bufferMs);
208    return 0;
209}
210
211int VoEVideoSyncImpl::GetRtpRtcp(int channel, RtpRtcp** rtpRtcpModule,
212                                 RtpReceiver** rtp_receiver)
213{
214    WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_shared->instance_id(), -1),
215                 "GetRtpRtcp(channel=%i)", channel);
216
217    if (!_shared->statistics().Initialized())
218    {
219        _shared->SetLastError(VE_NOT_INITED, kTraceError);
220        return -1;
221    }
222    voe::ChannelOwner ch = _shared->channel_manager().GetChannel(channel);
223    voe::Channel* channelPtr = ch.channel();
224    if (channelPtr == NULL)
225    {
226        _shared->SetLastError(VE_CHANNEL_NOT_VALID, kTraceError,
227            "GetPlayoutTimestamp() failed to locate channel");
228        return -1;
229    }
230    return channelPtr->GetRtpRtcp(rtpRtcpModule, rtp_receiver);
231}
232
233int VoEVideoSyncImpl::GetLeastRequiredDelayMs(int channel) const {
234  WEBRTC_TRACE(kTraceApiCall, kTraceVoice, VoEId(_shared->instance_id(), -1),
235               "GetLeastRequiredDelayMS(channel=%d)", channel);
236
237  if (!_shared->statistics().Initialized()) {
238    _shared->SetLastError(VE_NOT_INITED, kTraceError);
239    return -1;
240  }
241  voe::ChannelOwner ch = _shared->channel_manager().GetChannel(channel);
242  voe::Channel* channel_ptr = ch.channel();
243  if (channel_ptr == NULL) {
244    _shared->SetLastError(VE_CHANNEL_NOT_VALID, kTraceError,
245                          "GetLeastRequiredDelayMs() failed to locate channel");
246    return -1;
247  }
248  return channel_ptr->least_required_delay_ms();
249}
250
251#endif  // #ifdef WEBRTC_VOICE_ENGINE_VIDEO_SYNC_API
252
253}  // namespace webrtc
254