• 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_data_queue.cpp
20  * @brief Utility class to synchronize processing of media data to a specified clock.
21  */
22 
23 #ifndef PVMF_SYNC_UTIL_DATA_QUEUE_H_INCLUDED
24 #include "pvmf_sync_util_data_queue.h"
25 #endif
26 #ifndef OSCL_ERROR_CODES_H_INCLUDED
27 #include "oscl_error_codes.h"
28 #endif
29 #include "pvmf_media_msg_format_ids.h"
30 
31 //set this to 1 to disable AV sync and frame dropping.
32 //this option is used for performance testing but must be "0" in production code.
33 #define DISABLE_AV_SYNC 0
34 
35 
36 #define LOGDATAPATH(x)  PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iDatapathLogger, PVLOGMSG_INFO, x);
37 
38 
39 #define LOGDIAGNOSTICS(m) PVLOGGER_LOGMSG(PVLOGMSG_INST_PROF,iDiagnosticsLogger,PVLOGMSG_INFO,m);
40 
41 
PvmfSyncUtilDataQueue(PvmfSyncUtilDataQueueObserver * aObserver,PvmfSyncUtil * aUtil,char * name)42 OSCL_EXPORT_REF PvmfSyncUtilDataQueue::PvmfSyncUtilDataQueue(PvmfSyncUtilDataQueueObserver* aObserver, PvmfSyncUtil* aUtil, char*name) :
43         iObserver(aObserver),
44         iSyncUtil(aUtil),
45         iDataQueue(DEFAULT_QUEUE_RESERVE_SIZE),
46         iDiagnosticsLogged(false),
47         iDropFrameCount(0)
48 {
49     iLogger = PVLogger::GetLoggerObject("PvmfSyncUtilDataQueue");
50     iDiagnosticsLogger = PVLogger::GetLoggerObject("pvplayerdiagnostics.syncutil");
51     iLateFrameDropEnable = true;
52     iClock = NULL;
53     iClockNotificationsInf = NULL;
54     iSyncFrameCount = iClockFrameCount = 0;
55     iClockOwner = false;
56     SetName(name);
57     iOsclErrorTrapImp = OsclErrorTrap::GetErrorTrapImp();
58 }
59 
60 
SetName(const char * name)61 OSCL_EXPORT_REF void PvmfSyncUtilDataQueue::SetName(const char*name)
62 {
63     if (name
64             && name[0] != '\0')
65     {
66         iName = name;
67         iDatapathLogger = PVLogger::GetLoggerObject("datapath");
68     }
69     else
70     {
71         iDatapathLogger = NULL;
72     }
73 }
74 
75 
~PvmfSyncUtilDataQueue()76 OSCL_EXPORT_REF PvmfSyncUtilDataQueue::~PvmfSyncUtilDataQueue()
77 {
78     LogDiagnostics();
79     Clear();
80 
81     //remove ourself as observer of clock.
82     if (iClockNotificationsInf && iClock)
83     {
84         iClockNotificationsInf->RemoveClockObserver(*this);
85         iClock->DestroyMediaClockNotificationsInterface(iClockNotificationsInf);
86     }
87 }
88 
PassClockToSyncUtil()89 void PvmfSyncUtilDataQueue::PassClockToSyncUtil()
90 {
91     if (!iSyncUtil)
92         return;
93 
94     //clock or timebase has been updated-- decide how to update
95     //the sync util clock.
96 
97     if (FrameSyncMode())
98     {
99         PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
100                         (0, "PvmfSyncUtil::PassClockToSyncUtil Enabling Clock in sync util"));
101         iSyncUtil->SetClock(iClock);
102     }
103     else
104     {
105         PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
106                         (0, "PvmfSyncUtil::PassClockToSyncUtil Disabling Clock in sync util"));
107         iSyncUtil->SetClock(NULL);
108     }
109 }
110 
ClockTimebaseUpdated()111 OSCL_EXPORT_REF void PvmfSyncUtilDataQueue::ClockTimebaseUpdated()
112 {
113     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
114                     (0, "PvmfSyncUtil::ClockTimebaseUpdated"));
115 
116     if (!iClock)
117         return;
118 
119     if (iClock->GetCountTimebase())
120     {
121         //Reset the frame step delta to zero.
122         iClock->GetCountTimebase()->GetCount(iClockFrameCount);
123         iSyncFrameCount = iClockFrameCount;
124     }
125 
126     //reset the sync util clock if needed
127     PassClockToSyncUtil();
128 
129     //wake up the observer since we might need to process data now.
130     if (iObserver)
131         iObserver->ScheduleProcessData(this, 0);
132 }
133 
ClockCountUpdated()134 OSCL_EXPORT_REF void PvmfSyncUtilDataQueue::ClockCountUpdated()
135 {
136     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
137                     (0, "PvmfSyncUtil::ClockCountUpdated"));
138 
139     if (iClock
140             && iClock->GetCountTimebase())
141     {
142         //read the new framecount
143         iClock->GetCountTimebase()->GetCount(iClockFrameCount);
144 
145         //wakeup the observer since we might need to process data now
146         if (iObserver)
147             iObserver->ScheduleProcessData(this, 0);
148     }
149 }
150 
NotificationsInterfaceDestroyed()151 OSCL_EXPORT_REF void PvmfSyncUtilDataQueue::NotificationsInterfaceDestroyed()
152 {
153     iClockNotificationsInf = NULL;
154 }
155 
ClockAdjusted()156 OSCL_EXPORT_REF void PvmfSyncUtilDataQueue::ClockAdjusted()
157 {
158     uint32 clktime;
159     uint32 tbtime;
160     bool overflow;
161     iClock->GetCurrentTime32(clktime, overflow, PVMF_MEDIA_CLOCK_MSEC, tbtime);
162     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
163                     (0, "PvmfSyncUtil::ClockAdjusted, new value %d", (uint32)clktime));
164 }
165 
SetClock(PVMFMediaClock * aClock)166 OSCL_EXPORT_REF PVMFStatus PvmfSyncUtilDataQueue::SetClock(PVMFMediaClock* aClock)
167 {
168     //set clock for 'sync always' mode.
169     return DoSetClock(aClock, true);
170 }
171 
SetClockForFrameStep(PVMFMediaClock * aClock)172 OSCL_EXPORT_REF PVMFStatus PvmfSyncUtilDataQueue::SetClockForFrameStep(PVMFMediaClock* aClock)
173 {
174     //set clock for 'sync only during frame step' mode.
175     return DoSetClock(aClock, false);
176 }
177 
DoSetClock(PVMFMediaClock * aClock,bool aSyncAlways)178 PVMFStatus PvmfSyncUtilDataQueue::DoSetClock(PVMFMediaClock* aClock, bool aSyncAlways)
179 {
180     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
181                     (0, "PvmfSyncUtil::DoSetClock, Clk 0x%x syncAlways %d", aClock, aSyncAlways));
182 
183     //remove ourself as observer of old clock, if any.
184     if (iClockNotificationsInf && iClock)
185     {
186         iClockNotificationsInf->RemoveClockObserver(*this);
187         iClock->DestroyMediaClockNotificationsInterface(iClockNotificationsInf);
188         iClockNotificationsInf = NULL;
189     }
190 
191     //save new clock.
192     iClock = aClock;
193 
194     if (iClock)
195     {
196         iClock->ConstructMediaClockNotificationsInterface(iClockNotificationsInf, *this);
197     }
198 
199     //set ourself as observer of new clock.
200     if (iClockNotificationsInf)
201     {
202         iClockNotificationsInf->SetClockObserver(*this);
203     }
204 
205     //make a note of initial clock timebase
206     ClockTimebaseUpdated();
207 
208     //aSyncAlways==true means we're the clock owner, so should do both
209     //sync and frame-step mode.
210     //aSyncAlways==false means the MIO component owns the clock, so it
211     //does sync mode and frame-step.  We need to sync logic during
212     //frame-stepping, since the MIO may not have sync capability.
213     iClockOwner = aSyncAlways;
214 
215     //pass new clock to sync util also.
216     PassClockToSyncUtil();
217 
218     return PVMFFailure;//no sync util!
219 }
220 
LogMediaMsgInfo(PVMFSharedMediaMsgPtr aMediaMsg,const char * msg)221 void PvmfSyncUtilDataQueue::LogMediaMsgInfo(PVMFSharedMediaMsgPtr aMediaMsg, const char* msg)
222 //log media msg info, description, and associated q-depth.
223 {
224     OSCL_UNUSED_ARG(aMediaMsg);
225     OSCL_UNUSED_ARG(msg);
226     if (!iDatapathLogger)
227     {
228         return;//unexpected call.
229     }
230 
231     LOGDATAPATH
232     ((0, "SYNC %s %s MediaMsg SeqNum %d, SId %d, TS %d, Dur %d, Q-depth %d/%d", iName.get_cstr()
233       , msg
234       , aMediaMsg->getSeqNum()
235       , aMediaMsg->getStreamID()
236       , aMediaMsg->getTimestamp()
237       , aMediaMsg->getDuration()
238       , iDataQueue.size()
239       , iDataQueue.capacity()
240      ));
241 }
242 
243 
LogMediaMsgInfo(PVMFSharedMediaMsgPtr aMediaMsg,const char * msg,uint32 time)244 void PvmfSyncUtilDataQueue::LogMediaMsgInfo(PVMFSharedMediaMsgPtr aMediaMsg, const char* msg, uint32 time)
245 //log media msg info, time value, description, and associated q-depth.
246 {
247     OSCL_UNUSED_ARG(aMediaMsg);
248     OSCL_UNUSED_ARG(msg);
249     OSCL_UNUSED_ARG(time);
250     if (!iDatapathLogger)
251     {
252         return;//unexpected call.
253     }
254 
255     LOGDATAPATH
256     ((0, "SYNC %s %s Msec %d MediaMsg SeqNum %d, SId %d, TS %d, Dur %d, Q-depth %d/%d", iName.get_cstr()
257       , msg
258       , time
259       , aMediaMsg->getSeqNum()
260       , aMediaMsg->getStreamID()
261       , aMediaMsg->getTimestamp()
262       , aMediaMsg->getDuration()
263       , iDataQueue.size()
264       , iDataQueue.capacity()
265      ));
266 }
267 
268 
ReserveDataQueue(uint32 aReserveSize)269 OSCL_EXPORT_REF PVMFStatus PvmfSyncUtilDataQueue::ReserveDataQueue(uint32 aReserveSize)
270 {
271     if (aReserveSize <= iDataQueue.capacity())
272     {
273         return PVMFSuccess;
274     }
275 
276     int32 err = OsclErrNone;
277     OSCL_TRY(err,
278              iDataQueue.reserve(aReserveSize);
279             );
280     OSCL_FIRST_CATCH_ANY(err,
281                          return PVMFErrNoMemory;
282                         );
283 
284     return PVMFSuccess;
285 }
286 
287 
QueueMediaData(PVMFSharedMediaMsgPtr aMediaMsg,uint32 * aDropped,uint32 * aSkipped,bool aFront)288 OSCL_EXPORT_REF PVMFStatus PvmfSyncUtilDataQueue::QueueMediaData(PVMFSharedMediaMsgPtr aMediaMsg, uint32* aDropped, uint32* aSkipped, bool aFront)
289 {
290     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PvmfSyncUtilDataQueue::QueueMediaData front %d", aFront));
291 
292     if (aDropped)
293     {
294         *aDropped = 0;
295     }
296     if (aSkipped)
297     {
298         *aSkipped = 0;
299     }
300 
301     int32 err = OsclErrNone;
302     if (aFront)
303     {
304         OSCL_TRY_NO_TLS(iOsclErrorTrapImp, err, iDataQueue.push_front(aMediaMsg););
305     }
306     else
307     {
308         OSCL_TRY_NO_TLS(iOsclErrorTrapImp, err, iDataQueue.push_back(aMediaMsg););
309     }
310     OSCL_FIRST_CATCH_ANY(err,
311                          PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_ERR,
312                                          (0, "PvmfSyncUtilDataQueue::QueueMediaData: Error - No Memory"));
313                          return PVMFErrNoMemory;
314                         );
315 
316     if (iDatapathLogger)
317     {
318         LogMediaMsgInfo(aMediaMsg, "Data Q'd");
319     }
320 
321     if (iDataQueue.size() == 1)
322     {
323         // Only schedule the next media data if the data queue was empty before the
324         // current media data was added.  Otherwise, the data will be scheduled
325         // later as the data queue is being processed.
326         PVMFStatus status = SynchronizeData(aDropped, aSkipped);
327         if (status == PVMFSuccess)
328         {
329             iObserver->ScheduleProcessData(this, 0);
330         }
331 
332         return status;
333     }
334     else
335     {
336         return PVMFSuccess;
337     }
338 }
339 
340 
SetLateFrameDropMode(bool aDropFrame)341 OSCL_EXPORT_REF void PvmfSyncUtilDataQueue::SetLateFrameDropMode(bool aDropFrame)
342 {
343     iLateFrameDropEnable = aDropFrame;
344 }
345 
346 
DequeueMediaData(PVMFSharedMediaMsgPtr & aMediaMsg,uint32 * aDropped,uint32 * aSkipped)347 OSCL_EXPORT_REF PVMFStatus PvmfSyncUtilDataQueue::DequeueMediaData(PVMFSharedMediaMsgPtr& aMediaMsg, uint32* aDropped, uint32* aSkipped)
348 {
349     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
350                     (0, "PvmfSyncUtilDataQueue::DequeueMediaData"));
351 
352     if (aDropped)
353     {
354         *aDropped = 0;
355     }
356     if (aSkipped)
357     {
358         *aSkipped = 0;
359     }
360 
361     switch (SynchronizeData(aDropped, aSkipped))
362     {
363         case PVMFSuccess:
364             //return current frame.
365             aMediaMsg = iDataQueue[0];
366             iDataQueue.erase(iDataQueue.begin());
367             //log to datapath
368             if (iDatapathLogger)
369             {
370                 LogMediaMsgInfo(aMediaMsg, "Data De-Q'd");
371             }
372 
373             return PVMFSuccess;
374 
375         case PVMFPending:
376             return PVMFPending;
377 
378         default:
379             return PVMFFailure;
380     }
381 }
382 
383 
SkipMediaData(PVMFTimestamp aResumeTimestamp,bool aRenderSkippedData)384 OSCL_EXPORT_REF PVMFStatus PvmfSyncUtilDataQueue::SkipMediaData(PVMFTimestamp aResumeTimestamp, bool aRenderSkippedData)
385 {
386     if (iSyncUtil->SkipMediaData(aResumeTimestamp, aRenderSkippedData) == PVMFSuccess)
387     {
388         return PVMFPending;
389     }
390     else
391     {
392         return PVMFFailure;
393     }
394 }
395 
396 
CancelSkipMediaData()397 OSCL_EXPORT_REF void PvmfSyncUtilDataQueue::CancelSkipMediaData()
398 {
399     iSyncUtil->CancelSkipMediaData();
400 }
401 
402 
Clear()403 OSCL_EXPORT_REF PVMFStatus PvmfSyncUtilDataQueue::Clear()
404 {
405     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
406                     (0, "PvmfSyncUtilDataQueue::Clear"));
407 
408     LogDiagnostics();
409 
410     while (!iDataQueue.empty())
411     {
412         PVMFSharedMediaMsgPtr msg = iDataQueue.front();
413         iDataQueue.erase(iDataQueue.begin());
414         if (iDatapathLogger)
415         {
416             LogMediaMsgInfo(msg, "Data Cleared");
417         }
418     }
419     return PVMFSuccess;
420 }
421 
FrameStepClkAdjust(PVMFTimestamp aTimestamp)422 void PvmfSyncUtilDataQueue::FrameStepClkAdjust(PVMFTimestamp aTimestamp)
423 {
424     //update the clock value for frame-step mode.
425 
426     //In normal playback, we'd be waiting until the clock and
427     //timestamp to match before releasing a frame.
428     //In frame-step mode, the clock is not advancing on its own, and we're
429     //releasing frames based on commands regardless of clock time.
430     //If we don't adjust the clock, the A/V will not stay sync'd, and we'll
431     //have trouble later when resuming normal playback.
432     //Therefore we explicitely set the clock time to the frame timestamp
433     //each time a frame is released due to a frame step command.
434 
435     //if the frame timestamp is ahead of the clock, update the
436     //clock to the timestamp.
437     uint32 clktime;
438     uint32 tbtime;
439     bool overflow = 0;
440     iClock->GetCurrentTime32(clktime, overflow, PVMF_MEDIA_CLOCK_MSEC, tbtime);
441     if (aTimestamp > (PVMFTimestamp)clktime)
442     {
443         uint32 adjtime = aTimestamp;
444         PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_DEBUG,
445                         (0, "PvmfSyncUtilDataQueue::FrameStepClkAdjust: from %d to %d", (uint32)clktime, (uint32)adjtime));
446         PVMFMediaClockAdjustTimeStatus ok = iClock->AdjustClockTime32(clktime, tbtime, adjtime, PVMF_MEDIA_CLOCK_MSEC, overflow);
447         if (PVMF_MEDIA_CLOCK_ADJUST_SUCCESS != ok)
448         {
449             PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_ERR,
450                             (0, "PvmfSyncUtilDataQueue::FrameStepClkAdjust: from %d to %d FAILED", (uint32)clktime, (uint32)adjtime));
451         }
452     }
453 }
454 
FrameStepMode()455 bool PvmfSyncUtilDataQueue::FrameStepMode()
456 {
457     //apply the frame-step logic only when the clock is in frame-step mode,
458     //and we're the clock owner.
459     return(iClockOwner
460            && iClock
461            && iClock->GetCountTimebase());
462 }
463 
FrameSyncMode()464 bool PvmfSyncUtilDataQueue::FrameSyncMode()
465 {
466     //apply frame sync logic when we are clock owner
467     // or else not clock owner but in frame-step mode.
468     return(iClockOwner
469            || (iClock && iClock->GetCountTimebase()));
470 }
471 
FrameStep()472 PVMFStatus PvmfSyncUtilDataQueue::FrameStep()
473 {
474     //Decide whether or not to release the next media msg in frame-step mode.
475 
476     //Dropped, skipped, and skipped-but-rendered frames have already been handled
477     //elsewhere.
478 
479     //release any media cmd ASAP, except EOS.
480     if (iDataQueue[0]->getFormatID() >= PVMF_MEDIA_CMD_FORMAT_IDS_START
481             && iDataQueue[0]->getFormatID() != PVMF_MEDIA_CMD_EOS_FORMAT_ID)
482     {
483         PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_DEBUG,
484                         (0, "PvmfSyncUtilDataQueue::FrameStep: Returning media cmd(id=%d)", iDataQueue[0]->getFormatID()));
485         return PVMFSuccess;
486     }
487 
488     //for media data or EOS cmd, release frames based on frame-step commands to
489     //the timebase.
490 
491     if (iSyncFrameCount != iClockFrameCount)
492     {
493         //release the frame now.
494 
495         PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_DEBUG,
496                         (0, "PvmfSyncUtilDataQueue::FrameStep: Release Frame Now TS %d", iDataQueue[0]->getTimestamp()));
497 
498         //Each time a frame is released, reduce the delta by 1, regardless
499         //of whether it's forward or backward stepping.
500         if (iSyncFrameCount < iClockFrameCount)
501         {
502             iSyncFrameCount++;
503         }
504         else
505         {
506             iSyncFrameCount--;
507         }
508 
509         //adjust the clock to the frame timestamp.
510         FrameStepClkAdjust(iDataQueue[0]->getTimestamp());
511 
512         return PVMFSuccess;
513     }
514     else
515     {
516         //wait on a frame-step command to the timebase
517 
518         PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_DEBUG,
519                         (0, "PvmfSyncUtilDataQueue::FrameStep: Wait for Frame Step Cmd"));
520 
521         return PVMFPending;
522     }
523 }
524 
SynchronizeData(uint32 * aDropped,uint32 * aSkipped)525 OSCL_EXPORT_REF PVMFStatus PvmfSyncUtilDataQueue::SynchronizeData(uint32*aDropped, uint32*aSkipped)
526 {
527     //This call evaluates the data queue.
528     //It returns PVMFSuccess if it has determined that the frame or media cmd
529     //on the top of the data queue should be sent downstream.
530 
531 
532     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
533                     (0, "PvmfSyncUtilDataQueue::SynchronizeData"));
534 
535     uint32 millisecondsEarly = 0;
536     while (!iDataQueue.empty())
537     {
538         uint32 duration = 0;
539         PVMFSharedMediaMsgPtr mediaMsg = iDataQueue[0];
540         /* Retrieve duration only for media msgs, not for media cmds (viz. EOS, Reconfig etc) */
541         if (mediaMsg->getFormatID() == PVMF_MEDIA_MSG_DATA_FORMAT_ID)
542         {
543             PVMFSharedMediaDataPtr mediaData;
544             convertToPVMFMediaData(mediaData, mediaMsg);
545             if (mediaData->getMarkerInfo() & PVMF_MEDIA_DATA_MARKER_INFO_DURATION_AVAILABLE_BIT)
546             {
547                 duration = mediaMsg->getDuration();
548             }
549         }
550 
551         if (mediaMsg->getFormatID() == PVMF_MEDIA_CMD_EOS_FORMAT_ID)
552         {
553             PVMFSharedMediaCmdPtr mediaCmd;
554             convertToPVMFMediaCmd(mediaCmd, mediaMsg);
555             duration = mediaCmd->getDuration();
556         }
557 
558         PvmfSyncStatus syncStatus =
559             iSyncUtil->SyncMediaData(iDataQueue[0]->getTimestamp(),
560                                      duration,
561                                      millisecondsEarly);
562         switch (syncStatus)
563         {
564             case PVMF_SYNC_ON_TIME:
565                 if (FrameStepMode())
566                 {
567                     //frame-step mode, on-time.  frame-step rules apply.
568                     return FrameStep();
569                 }
570                 else
571                 {
572                     //normal playback, on-time.   release the frame now.
573                     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_DEBUG,
574                                     (0, "PvmfSyncUtilDataQueue::SynchronizeData: On Time %d", iDataQueue[0]->getTimestamp()));
575                     return PVMFSuccess;
576                 }
577                 // break;   This statement was removed to avoid compiler warning for Unreachable Code
578 
579             case PVMF_SYNC_EARLY:
580                 // For media command, ignore the synchronization except for EOS media command
581                 // which cannot be processed earlier than the specified timestamp
582                 if (iDataQueue[0]->getFormatID() >= PVMF_MEDIA_CMD_FORMAT_IDS_START &&
583                         iDataQueue[0]->getFormatID() != PVMF_MEDIA_CMD_EOS_FORMAT_ID)
584                 {
585                     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_DEBUG,
586                                     (0, "PvmfSyncUtilDataQueue::SynchronizeData: Returning media cmd(id=%d) as being in sync,%s", iDataQueue[0]->getFormatID(), iName.get_cstr()));
587                     return PVMFSuccess;
588                 }
589                 else if (FrameStepMode())
590                 {
591                     //frame-step mode, early frame.  frame-step rules apply.
592                     return FrameStep();
593                 }
594                 else
595                 {
596                     //normal mode, early frame. Schedule re-processing after enough
597                     //time has elapsed to make the frame on-time.
598                     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_DEBUG,
599                                     (0, "PvmfSyncUtilDataQueue::SynchronizeData: Schedule to process TS %d %d ms later,%s", iDataQueue[0]->getTimestamp(), millisecondsEarly, iName.get_cstr()));
600                     if (iDatapathLogger)
601                     {
602                         LogMediaMsgInfo(iDataQueue[0], "Early Frame, Delay", millisecondsEarly);
603                     }
604                     iObserver->ScheduleProcessData(this, millisecondsEarly);
605                     return PVMFPending;
606                 }
607                 // break;   This statement was removed to avoid compiler warning for Unreachable Code
608 
609             case PVMF_SYNC_LATE:
610                 // For media command, ignore the synchronization
611                 if (iDataQueue[0]->getFormatID() >= PVMF_MEDIA_CMD_FORMAT_IDS_START)
612                 {
613                     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_DEBUG,
614                                     (0, "PvmfSyncUtilDataQueue::SynchronizeData: Returning media cmd(id=%d) as being in sync,%s", iDataQueue[0]->getFormatID(), iName.get_cstr()));
615                     return PVMFSuccess;
616                 }
617 #if(DISABLE_AV_SYNC)
618                 else if (true)
619                 {
620                     return PVMFSuccess;
621                 }
622 #endif
623                 else if (iLateFrameDropEnable)
624                 {
625                     //dropping late frames.
626                     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_DEBUG,
627                                     (0, "PvmfSyncUtilDataQueue::SynchronizeData: Drop late frame TS %d, Dur %d, delta %d, %s",
628                                      iDataQueue[0]->getTimestamp(), iDataQueue[0]->getDuration(), millisecondsEarly, iName.get_cstr()));
629                     PVMFSharedMediaMsgPtr msg = iDataQueue.front();
630                     iDataQueue.erase(iDataQueue.begin());
631                     if (iDatapathLogger)
632                     {
633                         LogMediaMsgInfo(msg, "Late Frame Dropped", millisecondsEarly);
634                     }
635                     if (aDropped)
636                     {
637                         (*aDropped)++;
638                         iDropFrameCount++;
639                     }
640                     //continue looping...
641                     break;
642                 }
643                 else if (FrameStepMode())
644                 {
645                     //frame step mode, late frame, not dropping frames.
646                     //frame-step rules apply.
647                     return FrameStep();
648                 }
649                 else
650                 {
651                     //normal mode, late frame, not dropping frames.  release this
652                     //frame ASAP.
653                     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_DEBUG,
654                                     (0, "PvmfSyncUtilDataQueue::SynchronizeData: Process late frame ASAP, TS %d,%s", iDataQueue[0]->getTimestamp(), iName.get_cstr()));
655                     return PVMFSuccess;
656                 }
657                 // break;   This statement was removed to avoid compiler warning for Unreachable Code
658 
659             case PVMF_SYNC_SKIPPED_RENDER:
660             {
661                 //this is a skipped frame, but we are rendering skipped frames.
662                 //release the frame ASAP.
663                 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_DEBUG,
664                                 (0, "PvmfSyncUtilDataQueue::SynchronizeData: Render Skipped Data TS %d", iDataQueue[0]->getTimestamp()));
665 
666                 PVMFSharedMediaMsgPtr mediaMsg = iDataQueue[0];
667                 if (mediaMsg->getFormatID() == PVMF_MEDIA_MSG_DATA_FORMAT_ID)
668                 {
669                     PVMFSharedMediaDataPtr mediaData;
670                     convertToPVMFMediaData(mediaData, mediaMsg);
671                     uint32 markerinfo = mediaData->getMarkerInfo();
672                     markerinfo |= PVMF_MEDIA_DATA_MARKER_INFO_NO_RENDER_BIT;
673                     mediaData->setMarkerInfo(markerinfo);
674                 }
675             }
676             return PVMFSuccess;
677 
678             case PVMF_SYNC_SKIPPED:
679                 // For media command, ignore the synchronization and release
680                 // the cmd. (why not drop it?)
681                 if (iDataQueue[0]->getFormatID() >= PVMF_MEDIA_CMD_FORMAT_IDS_START)
682                 {
683                     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_DEBUG,
684                                     (0, "PvmfSyncUtilDataQueue::SynchronizeData: Returning media cmd(id=%d) as being in sync,%s", iDataQueue[0]->getFormatID(), iName.get_cstr()));
685                     return PVMFSuccess;
686                 }
687                 //This is a skipped frame, and we are not rendering skipped frames.
688                 //Drop the frame.
689                 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_DEBUG,
690                                 (0, "PvmfSyncUtilDataQueue::SynchronizeData: Skipped frame TS %d Dur %d,%s",
691                                  iDataQueue[0]->getTimestamp(), iDataQueue[0]->getDuration(), iName.get_cstr()));
692                 {
693                     PVMFSharedMediaMsgPtr msg = iDataQueue.front();
694                     iDataQueue.erase(iDataQueue.begin());
695                     if (iDatapathLogger)
696                     {
697                         LogMediaMsgInfo(msg, "Frame Skipped", millisecondsEarly);
698                     }
699                 }
700                 if (aSkipped)
701                 {
702                     (*aSkipped)++;
703                 }
704                 //continue looping...
705                 break;
706 
707             case PVMF_SYNC_SKIP_COMPLETE:
708                 //Skipping is complete.  Notify observer, but hang onto the frame
709                 //to re-evaluate in next sync call.
710                 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_DEBUG,
711                                 (0, "PvmfSyncUtilDataQueue::SynchronizeData: Skip complete TS %d,%s", iDataQueue[0]->getTimestamp(), iName.get_cstr()));
712                 iObserver->SkipMediaDataComplete();
713                 return PVMFPending;
714         }
715     }
716 
717     //If we get here, the queue is now empty, and all data was dropped or skipped.
718     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_DEBUG,
719                     (0, "PvmfSyncUtilDataQueue::SynchronizeData: All data dropped or skipped,%s", iName.get_cstr()));
720     return PVMFFailure;
721 }
722 
LogDiagnostics()723 void PvmfSyncUtilDataQueue::LogDiagnostics()
724 {
725     if (iDiagnosticsLogged == false)
726     {
727         iDiagnosticsLogged = true;
728         LOGDIAGNOSTICS((0, "@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@"));
729         LOGDIAGNOSTICS((0, "TrackMimeType = %s", iName.get_cstr()));
730         LOGDIAGNOSTICS((0, "PvmfSyncUtilDataQueue - Num Frames Dropped=%d", iDropFrameCount));
731         iDropFrameCount = 0;
732     }
733 }
734 
735 
736 
737 
738 
739