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