• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /* ------------------------------------------------------------------
2  * Copyright (C) 1998-2009 PacketVideo
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
13  * express or implied.
14  * See the License for the specific language governing permissions
15  * and limitations under the License.
16  * -------------------------------------------------------------------
17  */
18 /**
19 * @file pvmf_sync_util.cpp
20 * @brief Utility class to synchronize processing of media data to a specified clock.
21 */
22 
23 #ifndef PVMF_SYNC_UTIL_H_INCLUDED
24 #include "pvmf_sync_util.h"
25 #endif
26 
27 //set this to 1 to disable AV sync and frame dropping.
28 //this option is used for performance testing but must be "0" in production code.
29 #define DISABLE_AV_SYNC  0
30 
PvmfSyncUtil()31 OSCL_EXPORT_REF PvmfSyncUtil::PvmfSyncUtil() :
32         iClock(NULL),
33         iFrameStepClock(NULL),
34         iEarlyMargin(DEFAULT_EARLY_MARGIN),
35         iLateMargin(DEFAULT_LATE_MARGIN),
36         iSkipMediaData(false),
37         iResumeTimestamp(0),
38         iRenderSkippedData(false)
39 {
40     iLogger = PVLogger::GetLoggerObject("PvmfSyncUtil");
41 }
42 
SetClock(PVMFMediaClock * aClock)43 OSCL_EXPORT_REF PVMFStatus PvmfSyncUtil::SetClock(PVMFMediaClock* aClock)
44 {
45     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
46                     (0, "PvmfSyncUtil::SetClockAndTimebase: aClock=0x%x", aClock));
47 
48     iClock = aClock;
49 
50     return PVMFSuccess;
51 }
52 
SetFrameStepClock(PVMFMediaClock * aClock)53 OSCL_EXPORT_REF PVMFStatus PvmfSyncUtil::SetFrameStepClock(PVMFMediaClock* aClock)
54 {
55     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
56                     (0, "PvmfSyncUtil::SetClockAndTimebase: SetFrameStepClock=0x%x", aClock));
57 
58     iFrameStepClock = aClock;
59 
60     return PVMFSuccess;
61 }
62 
SetMargins(int32 aEarlyMargin,int32 aLateMargin)63 OSCL_EXPORT_REF PVMFStatus PvmfSyncUtil::SetMargins(int32 aEarlyMargin, int32 aLateMargin)
64 {
65     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
66                     (0, "PvmfSyncUtil::SetMargins: aEarlyMargin=%d, aLateMargin=%d", aEarlyMargin, aLateMargin));
67 
68     iEarlyMargin = aEarlyMargin;
69     iLateMargin = aLateMargin;
70     return PVMFSuccess;
71 }
72 
SyncMediaData(PVMFTimestamp aDataTimestamp,uint32 aDuration,uint32 & aMillisecondsEarly)73 OSCL_EXPORT_REF PvmfSyncStatus PvmfSyncUtil::SyncMediaData(PVMFTimestamp aDataTimestamp, uint32 aDuration, uint32& aMillisecondsEarly)
74 {
75 #if DISABLE_AV_SYNC
76     iClock = NULL;
77 #endif
78 
79     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
80                     (0, "PvmfSyncUtil::SyncMediaData: aDataTimestamp=%d aDuration=%d", aDataTimestamp, aDuration));
81 
82     // TEMPORARY UNTIL DESIGN DEALING WITH DATA WITHOUT TIMESTAMP IS IMPLEMENTED
83     if (aDataTimestamp == 0xFFFFFFFF)
84     {
85         // 0xFFFFFFFF is a special value meaning no timestamp. Change to time 0
86         PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
87                         (0, "PvmfSyncUtil::SyncMediaData: aDataTimestamp is 0xFFFFFFFF so changing it to 0"));
88         aDataTimestamp = 0;
89     }
90     // END TEMPORARY
91 
92     if (iSkipMediaData)
93     {
94         if ((aDataTimestamp + aDuration) >= iResumeTimestamp)
95         {
96             PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_DEBUG,
97                             (0, "PvmfSyncUtil::SyncMediaData: SkipMediaData complete"));
98             iSkipMediaData = false;
99             return PVMF_SYNC_SKIP_COMPLETE;
100         }
101         else
102         {
103             if (iRenderSkippedData)
104             {
105                 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_DEBUG,
106                                 (0, "PvmfSyncUtil::SyncMediaData: Render skipped data"));
107                 return PVMF_SYNC_SKIPPED_RENDER;
108             }
109             else
110             {
111                 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_DEBUG,
112                                 (0, "PvmfSyncUtil::SyncMediaData: Drop skipped data"));
113                 //return the skip interval
114                 aMillisecondsEarly = (iResumeTimestamp - aDataTimestamp);
115                 return PVMF_SYNC_SKIPPED;
116             }
117         }
118     }
119     else if (!iClock)
120     {
121         // No clock to synchronize to. Process data ASAP.
122         PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_DEBUG,
123                         (0, "PvmfSyncUtil::SyncMediaData: No clock available"));
124         return PVMF_SYNC_ON_TIME;
125     }
126 
127     // Get current playback clock time
128     uint32 currentTime = 0;
129     bool overflow = false;
130     iClock->GetCurrentTime32(currentTime, overflow, PVMF_MEDIA_CLOCK_MSEC);
131 
132     // Check if in sync
133     if (currentTime > (uint32)iLateMargin)
134     {
135         // Normal case
136         // In sync if beginning or tail end of data is within the sync window
137         if ((aDataTimestamp >= (currentTime - iLateMargin) && aDataTimestamp <= (currentTime + iEarlyMargin)) ||
138                 ((aDataTimestamp + aDuration) >= (currentTime - iLateMargin) && (aDataTimestamp + aDuration) <= (currentTime + iEarlyMargin)))
139         {
140             PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_DEBUG,
141                             (0, "PvmfSyncUtil::SyncMediaData: In Sync Clock(%d), TS(%d)", currentTime, aDataTimestamp));
142             return PVMF_SYNC_ON_TIME;
143         }
144     }
145     else
146     {
147         // Special case when clock less than the late margin (to avoid substracting from 0 with unsigned int)
148         // In sync if beginning is within the sync window
149         if (aDataTimestamp <= (currentTime + iEarlyMargin))
150         {
151             PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_DEBUG,
152                             (0, "PvmfSyncUtil::SyncMediaData: In Sync Clock(%d), TS(%d)", currentTime, aDataTimestamp));
153             return PVMF_SYNC_ON_TIME;
154         }
155     }
156 
157     // Early if the beginning of the data is before
158     // sync window
159     if (aDataTimestamp > (currentTime + iEarlyMargin))
160     {
161         PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_DEBUG,
162                         (0, "PvmfSyncUtil::SyncMediaData: Early data  Clock(%d), TS(%d) Dur(%d)", currentTime, aDataTimestamp, aDuration));
163         aMillisecondsEarly = (aDataTimestamp - currentTime - iEarlyMargin);
164         return PVMF_SYNC_EARLY;
165     }
166     else
167     {
168         // Late for all other cases
169         PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_DEBUG,
170                         (0, "PvmfSyncUtil::SyncMediaData: Late data  Clock(%d), TS(%d) Dur(%d)", currentTime, aDataTimestamp, aDuration));
171         //return the lateness amount
172         aMillisecondsEarly = ((currentTime + iEarlyMargin) - aDataTimestamp);
173         return PVMF_SYNC_LATE; // Late frame
174     }
175 }
176 
SkipMediaData(PVMFTimestamp aResumeTimestamp,bool aRenderSkippedData)177 OSCL_EXPORT_REF PVMFStatus PvmfSyncUtil::SkipMediaData(PVMFTimestamp aResumeTimestamp, bool aRenderSkippedData)
178 {
179     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_DEBUG,
180                     (0, "PvmfSyncUtil::SkipMediaData: Resume(%d), Render(%d)", aResumeTimestamp, aRenderSkippedData));
181     iSkipMediaData = true;
182     iResumeTimestamp = aResumeTimestamp;
183     iRenderSkippedData = aRenderSkippedData;
184     return PVMFSuccess;
185 }
186 
CancelSkipMediaData()187 OSCL_EXPORT_REF void PvmfSyncUtil::CancelSkipMediaData()
188 {
189     iSkipMediaData = false;
190 }
191 
192 
193 
194 
195 
196 
197 
198