2 * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
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.
11 #include "video_engine/vie_sync_module.h"
13 #include "modules/rtp_rtcp/interface/rtp_rtcp.h"
14 #include "modules/video_coding/main/interface/video_coding.h"
15 #include "system_wrappers/interface/critical_section_wrapper.h"
16 #include "system_wrappers/interface/trace.h"
17 #include "video_engine/stream_synchronization.h"
18 #include "voice_engine/include/voe_video_sync.h"
22 enum { kSyncInterval
= 1000};
24 ViESyncModule::ViESyncModule(const int32_t channel_id
, VideoCodingModule
* vcm
)
25 : data_cs_(CriticalSectionWrapper::CreateCriticalSection()),
26 channel_id_(channel_id
),
28 video_rtcp_module_(NULL
),
30 voe_sync_interface_(NULL
),
31 last_sync_time_(TickTime::Now()),
35 ViESyncModule::~ViESyncModule() {
38 int ViESyncModule::ConfigureSync(int voe_channel_id
,
39 VoEVideoSync
* voe_sync_interface
,
40 RtpRtcp
* video_rtcp_module
) {
41 CriticalSectionScoped
cs(data_cs_
.get());
42 voe_channel_id_
= voe_channel_id
;
43 voe_sync_interface_
= voe_sync_interface
;
44 video_rtcp_module_
= video_rtcp_module
;
45 sync_
.reset(new StreamSynchronization(voe_channel_id
, channel_id_
));
47 if (!voe_sync_interface
) {
49 if (voe_channel_id
>= 0) {
50 // Trying to set a voice channel but no interface exist.
58 int ViESyncModule::VoiceChannel() {
59 return voe_channel_id_
;
62 WebRtc_Word32
ViESyncModule::TimeUntilNextProcess() {
63 return static_cast<WebRtc_Word32
>(kSyncInterval
-
64 (TickTime::Now() - last_sync_time_
).Milliseconds());
67 WebRtc_Word32
ViESyncModule::Process() {
68 CriticalSectionScoped
cs(data_cs_
.get());
69 last_sync_time_
= TickTime::Now();
71 int total_video_delay_target_ms
= vcm_
->Delay();
72 WEBRTC_TRACE(webrtc::kTraceInfo
, webrtc::kTraceVideo
, channel_id_
,
73 "Video delay (JB + decoder) is %d ms",
74 total_video_delay_target_ms
);
76 if (voe_channel_id_
== -1) {
79 assert(video_rtcp_module_
&& voe_sync_interface_
);
82 int current_audio_delay_ms
= 0;
83 if (voe_sync_interface_
->GetDelayEstimate(voe_channel_id_
,
84 current_audio_delay_ms
) != 0) {
85 // Could not get VoE delay value, probably not a valid channel Id.
86 WEBRTC_TRACE(webrtc::kTraceStream
, webrtc::kTraceVideo
, channel_id_
,
87 "%s: VE_GetDelayEstimate error for voice_channel %d",
88 __FUNCTION__
, total_video_delay_target_ms
, voe_channel_id_
);
92 // VoiceEngine report delay estimates even when not started, ignore if the
93 // reported value is lower than 40 ms.
94 if (current_audio_delay_ms
< 40) {
95 WEBRTC_TRACE(webrtc::kTraceInfo
, webrtc::kTraceVideo
, channel_id_
,
96 "A/V Sync: Audio delay < 40, skipping.");
100 RtpRtcp
* voice_rtcp_module
= NULL
;
101 if (0 != voe_sync_interface_
->GetRtpRtcp(voe_channel_id_
,
102 voice_rtcp_module
)) {
105 assert(voice_rtcp_module
);
107 StreamSynchronization::Measurements video
;
108 if (0 != video_rtcp_module_
->RemoteNTP(&video
.received_ntp_secs
,
109 &video
.received_ntp_frac
,
110 &video
.rtcp_arrivaltime_secs
,
111 &video
.rtcp_arrivaltime_frac
)) {
112 // Failed to get video NTP.
116 StreamSynchronization::Measurements audio
;
117 if (0 != voice_rtcp_module
->RemoteNTP(&audio
.received_ntp_secs
,
118 &audio
.received_ntp_frac
,
119 &audio
.rtcp_arrivaltime_secs
,
120 &audio
.rtcp_arrivaltime_frac
)) {
121 // Failed to get audio NTP.
124 int extra_audio_delay_ms
= 0;
125 if (sync_
->ComputeDelays(audio
, current_audio_delay_ms
, &extra_audio_delay_ms
,
126 video
, &total_video_delay_target_ms
) != 0) {
129 // Set the extra audio delay.synchronization
130 if (voe_sync_interface_
->SetMinimumPlayoutDelay(
131 voe_channel_id_
, extra_audio_delay_ms
) == -1) {
132 WEBRTC_TRACE(webrtc::kTraceDebug
, webrtc::kTraceVideo
, channel_id_
,
133 "Error setting voice delay");
135 vcm_
->SetMinimumPlayoutDelay(total_video_delay_target_ms
);
136 WEBRTC_TRACE(webrtc::kTraceInfo
, webrtc::kTraceVideo
, channel_id_
,
137 "New Video delay target is: %d", total_video_delay_target_ms
);
141 } // namespace webrtc