source: svn/newcon3bcm2_21bu/magnum/commonutils/xdm/bxdm_pp_vtsm.c

Last change on this file was 76, checked in by megakiss, 10 years ago

1W 대기전력을 만족시키기 위하여 POWEROFF시 튜너를 Standby 상태로 함

  • Property svn:executable set to *
File size: 27.5 KB
Line 
1/***************************************************************************
2 *     Copyright (c) 2003-2012, Broadcom Corporation
3 *     All Rights Reserved
4 *     Confidential Property of Broadcom Corporation
5 *
6 *  THIS SOFTWARE MAY ONLY BE USED SUBJECT TO AN EXECUTED SOFTWARE LICENSE
7 *  AGREEMENT  BETWEEN THE USER AND BROADCOM.  YOU HAVE NO RIGHT TO USE OR
8 *  EXPLOIT THIS MATERIAL EXCEPT SUBJECT TO THE TERMS OF SUCH AN AGREEMENT.
9 *
10 * $brcm_Workfile: bxdm_pp_vtsm.c $
11 * $brcm_Revision: Hydra_Software_Devel/10 $
12 * $brcm_Date: 3/24/12 10:39p $
13 *
14 * [File Description:]
15 *
16 * Revision History:
17 *
18 * $brcm_Log: /magnum/commonutils/xdm/bxdm_pp_vtsm.c $
19 *
20 * Hydra_Software_Devel/10   3/24/12 10:39p btosi
21 * SW7425-2656: fix for frame advance
22 *
23 * Hydra_Software_Devel/9   3/22/12 8:42a btosi
24 * SW7425-2656: when paused during a flush, prevent the next picture from
25 * being displayed until unpaused
26 *
27 * Hydra_Software_Devel/8   2/16/12 9:29a btosi
28 * SW7425-2255: bind the PTS offset to the picture when it is selected for
29 * display
30 *
31 * Hydra_Software_Devel/7   2/3/12 3:04p btosi
32 * SW7425-1264: fixed a problem with virtual PTS values when playing in
33 * reverse
34 *
35 * Hydra_Software_Devel/6   10/27/11 10:22a btosi
36 * SW7425-1264: interpolated the virtual STC/PTS in reverse when the SW
37 * STC is running in reverse
38 *
39 * Hydra_Software_Devel/5   12/21/10 4:24p delkert
40 * SW7405-5043: Split STC stored in local state into two parts: STC from
41 * decoder and STC after JTI adjustment
42 *
43 * Hydra_Software_Devel/4   9/23/10 3:09p btosi
44 * SW7405-4736: add support for a XDM instance ID to help debug multi-
45 * channel issues
46 *
47 * Hydra_Software_Devel/3   8/11/10 10:09a btosi
48 * SW7405-4736: added PPB index to debug messages
49 *
50 * Hydra_Software_Devel/2   3/23/10 10:51a nilesh
51 * SW7405-4072: Fixed issue with frame advance occurring continuously
52 *
53 * Hydra_Software_Devel/1   2/16/10 10:52a nilesh
54 * SW7405-2993: Initial XDM version
55 *
56 ***************************************************************************/
57
58#include "bstd.h"
59#include "bdbg.h"                /* Dbglib */
60
61#include "bxdm_pp.h"
62#include "bxdm_pp_priv.h"
63#include "bxdm_pp_qm.h"
64#include "bxdm_pp_fp.h"
65#include "bxdm_pp_vtsm.h"
66
67BDBG_MODULE(BXDM_PPVTSM);
68
69const char BXDM_PictureProvider_P_DISPMGR_VTSM_NODE[]="DMVTSM:\t""$brcm_Revision: Hydra_Software_Devel/10 $";
70
71void BXDM_PPVTSM_P_VirtualStcSet(
72   BXDM_PictureProvider_Handle hXdmPP,
73   BXDM_PictureProvider_P_LocalState* pLocalState
74   )
75{
76   BDBG_ENTER(BXDM_PictureProvider_P_VirtualStcSet);
77
78   /* If we've selected the current picture using TSM, we set the
79    * virtual STC (vSTC) to be equal to the actual STC so that we
80    * can have smooth transitions from TSM --> VSYNC
81    * mode. (e.g. when bVsyncModeOnPcrDiscontinuity is enabled) */
82
83   /* PR52803: We don't want the vSTC to track the STC if it is
84    * invalid */
85   if (hXdmPP->stDMState.stChannel.stSelectedPicture.bValidated
86       && (BXDM_PictureProvider_DisplayMode_eTSM == hXdmPP->stDMState.stChannel.stSelectedPicture.stPicParms.stTSM.stDynamic.eSelectionMode)
87       && (true == hXdmPP->stDMConfig.bSTCValid)
88      )
89   {
90      /* The actual STC = PCRoffset + STCsnapshot */
91      BXDM_PPQM_P_GetCookedPcrOffset(
92         hXdmPP,
93         &(hXdmPP->stDMState.stChannel.stSelectedPicture),
94         &(hXdmPP->stDMState.stDecode.stVTSM.stVirtualSTC.uiWhole)
95         );
96
97      hXdmPP->stDMState.stDecode.stVTSM.stVirtualSTC.uiWhole += pLocalState->uiAdjustedStc;
98      hXdmPP->stDMState.stDecode.stVTSM.stVirtualSTC.uiFractional = 0;
99   }
100
101   BDBG_LEAVE(BXDM_PictureProvider_P_VirtualStcSet);
102   return;
103}
104
105void BXDM_PPVTSM_P_VirtualStcIncrement(
106   BXDM_PictureProvider_Handle hXdmPP,
107   BXDM_PictureProvider_P_LocalState* pLocalState
108   )
109{
110   bool bInterpolateInReverse;
111   
112   /* Virtual TSM - Setting the virtual STC (vSTC) */
113   BDBG_ENTER(BXDM_PPVTSM_P_VirtualStcIncrement);
114
115   /* PR52803: If the STC is validated or we're in VSYNC display mode,
116    * then we can exit trick mode transition */
117   if ( ( true == hXdmPP->stDMState.stDecode.stVTSM.bTrickModeTransition ) /* We're in a trick mode transition */
118        && ( ( true == hXdmPP->stDMConfig.bSTCValid ) /* The STC is valid */
119             || ( BXDM_PictureProvider_DisplayMode_eVirtualTSM == pLocalState->eDisplayMode ) /* We're in VSYNC display mode */
120             || ( BXDM_PICTUREPROVIDER_NORMAL_PLAYBACK_RATE != pLocalState->uiSlowMotionRate ) /* We've entered into another trick mode */
121           )
122      )
123   {
124      BXVD_DBG_MSG(hXdmPP, ("%x: Exiting trick mode transition (stc: %x)",
125                                 hXdmPP->stDMState.stDecode.stDebug.uiVsyncCount,
126                                 pLocalState->uiAdjustedStc));
127      hXdmPP->stDMState.stDecode.stVTSM.bTrickModeTransition = false;
128   }
129
130   /* SW7425-1264: if the "physical" STC is running in reverse, interpolate the virtual STC in
131    * reverse as well.
132    */
133   bInterpolateInReverse = ( true == hXdmPP->stDMConfig.stClockOverride.bEnableClockOverride );
134   bInterpolateInReverse &= ( hXdmPP->stDMConfig.stClockOverride.iStcDelta < 0 );
135
136   /* If in CRC mode
137    * - use the delta PTS for the selected picture to increment the virtual STC
138    * else
139    * - use the delta STC to increment the virtual STC
140    * (The delta STC is based on the display rate)
141    */
142   if ( true == hXdmPP->stDMConfig.bCRCMode )
143   {
144      if ( true == hXdmPP->stDMState.stChannel.stSelectedPicture.bValidated )
145      {
146         pLocalState->stSTCDelta = hXdmPP->stDMState.stChannel.stSelectedPicture.stPicParms.stTSM.stStatic.stPTSDelta;
147      }
148      else
149      {
150         pLocalState->stSTCDelta.uiWhole = 0;
151         pLocalState->stSTCDelta.uiFractional = 0;
152      }
153   }
154
155#if 0
156   BKNI_Printf("[eClockRate = %d, eMonitorRefreshRate = %d] --> deltaSTC=(%d, %d)\n",
157               pLocalState->eClockRate, hXdmPP->stDMState.stDecode.eMonitorRefreshRate,
158               pLocalState->stSTCDelta.uiWhole,
159               pLocalState->stSTCDelta.uiFractional);
160#endif
161
162   /* If the selected picture is not valid (i.e. on start-up) then we
163    * always set PTS initialized to FALSE so that we reassign PTS
164    * until we have a valid picture displayed */
165   if ( !hXdmPP->stDMState.stChannel.stSelectedPicture.bValidated )
166   {
167      hXdmPP->stDMState.stDecode.stVTSM.bVirtualPTSInitialized = false;
168      BXVD_DBG_MSG(hXdmPP,("%x: vPTS Reset (Invalid)",
169                                hXdmPP->stDMState.stDecode.stDebug.uiVsyncCount));
170   }
171
172   /* Handle decoder trick modes */
173   if ( true == hXdmPP->stDMState.stDecode.stVTSM.bTrickModeTransition )
174   {
175      /* PR52803: Don't increment vSTC when in a trick mode
176       * transition */
177      pLocalState->stEffectiveSTCDelta[BXDM_PictureProvider_DisplayMode_eVirtualTSM].uiWhole = 0;
178      pLocalState->stEffectiveSTCDelta[BXDM_PictureProvider_DisplayMode_eVirtualTSM].uiFractional = 0;
179   }
180   else if ( pLocalState->uiSlowMotionRate )
181   {
182      /* We are not paused, so we can increment the vSTC on this
183       * VSYNC */
184      if ( BXDM_PICTUREPROVIDER_NORMAL_PLAYBACK_RATE != pLocalState->uiSlowMotionRate )
185      {
186         /* We're not in normal playback. Multiply the deltaSTC by
187          * the playback rate, before adding it to the vSTC */
188         BXDM_PPFP_P_FixPtFractionalMul(
189            &pLocalState->stSTCDelta,
190            pLocalState->uiSlowMotionRate,
191            BXDM_PICTUREPROVIDER_NORMAL_PLAYBACK_RATE,
192            &pLocalState->stSTCDelta);
193      }
194
195      pLocalState->stEffectiveSTCDelta[BXDM_PictureProvider_DisplayMode_eVirtualTSM] = pLocalState->stSTCDelta;
196
197      /* Increment the vSTC by delta STC (which already has taken
198       * slow motion into account) */
199
200      if ( true == bInterpolateInReverse )
201      {
202         BXDM_PPFP_P_FixPtSub(
203            &(hXdmPP->stDMState.stDecode.stVTSM.stVirtualSTC),
204            &pLocalState->stSTCDelta,
205            &(hXdmPP->stDMState.stDecode.stVTSM.stVirtualSTC)
206            );
207      }
208      else
209      {
210         BXDM_PPFP_P_FixPtAdd(
211            &(hXdmPP->stDMState.stDecode.stVTSM.stVirtualSTC),
212            &pLocalState->stSTCDelta,
213            &(hXdmPP->stDMState.stDecode.stVTSM.stVirtualSTC)
214            );
215      }
216
217   }
218   else
219   {
220      pLocalState->stEffectiveSTCDelta[BXDM_PictureProvider_DisplayMode_eVirtualTSM].uiWhole = 0;
221      pLocalState->stEffectiveSTCDelta[BXDM_PictureProvider_DisplayMode_eVirtualTSM].uiFractional = 0;
222
223      /* We're paused, so we only increment the STC if we need to
224       * handle a frame advance request */
225
226      /* PR51720: Frame advance is now performed by doing one field
227       * advance per vsync until we get to the next frame */
228      if ( BXDM_PictureProvider_FrameAdvanceMode_eFrameByField == hXdmPP->stDMConfig.eFrameAdvanceMode )
229      {
230         /* We ADD to the existing frame advance count (vs setting it)
231          * to ensure we handle FRAME advance requests while in the
232          * middle of honoring a previous one */
233         if ( 0 == hXdmPP->stDMConfig.uiFrameAdvanceByFieldCount )
234         {
235            hXdmPP->stDMConfig.uiFrameAdvanceByFieldCount += hXdmPP->stDMState.stChannel.stSelectedPicture.stPicParms.stTSM.stStatic.uiNumElements - hXdmPP->stDMState.stChannel.stSelectedPicture.stPicParms.stDisplay.stDynamic.uiSelectedElement;
236         }
237         else
238         {
239            BXVD_DBG_WRN(hXdmPP,("%x: Prior Frame Advance was not finished, yet.  Frame may not advance properly on 3:2 content", hXdmPP->stDMState.stDecode.stDebug.uiVsyncCount));
240            hXdmPP->stDMConfig.uiFrameAdvanceByFieldCount += hXdmPP->stDMState.stChannel.stSelectedPicture.stPicParms.stTSM.stStatic.uiNumElements;
241         }
242      }
243
244      if ( hXdmPP->stDMConfig.eFrameAdvanceMode != BXDM_PictureProvider_FrameAdvanceMode_eOff )
245      {
246         hXdmPP->stDMState.stDecode.stVTSM.eFrameAdvanceMode = hXdmPP->stDMConfig.eFrameAdvanceMode;
247         hXdmPP->stDMConfig.eFrameAdvanceMode = BXDM_PictureProvider_FrameAdvanceMode_eOff;
248
249         if ( true == hXdmPP->stDMState.stChannel.bPostFlushDecode )
250         {
251            /* SW7425-2656:  If this is the first picture after a "flush" and the system is paused,
252             * we want to hold off displaying the picture until the system is unpaused or a
253             * "frame advance" command is issued.  The second case is handled here by clearing
254             * "bPostFlushDecode" flag.  Clearing this flag prevents vPTS from being
255             * reset in BXDM_PPVTSM_P_VirtualPtsInterpolate.
256             */
257            hXdmPP->stDMState.stChannel.bPostFlushDecode = false;
258
259            BXVD_DBG_MSG(hXdmPP,("%x: [%01x.xxx] clear bPostFlushDecode due to frame advance",
260                                hXdmPP->stDMState.stDecode.stDebug.uiVsyncCount,
261                                hXdmPP->stDMConfig.uiInstanceID & 0xF
262                                ));
263
264         }
265
266      }
267
268      /* Handle frame advance */
269      switch ( hXdmPP->stDMState.stDecode.stVTSM.eFrameAdvanceMode )
270      {
271         case BXDM_PictureProvider_FrameAdvanceMode_eField:
272            /* We're doing a FIELD advance, so we need to increment
273             * the vSTC by one field time, which is deltaPTS */
274            BXVD_DBG_MSG(hXdmPP,("%x: Frame Advance: Field", hXdmPP->stDMState.stDecode.stDebug.uiVsyncCount));
275
276            if ( true == bInterpolateInReverse )
277            {
278               BXDM_PPFP_P_FixPtSub(
279                  &(hXdmPP->stDMState.stDecode.stVTSM.stVirtualSTC),
280                  &(hXdmPP->stDMState.stChannel.stSelectedPicture.stPicParms.stTSM.stStatic.stPTSDelta),
281                  &(hXdmPP->stDMState.stDecode.stVTSM.stVirtualSTC)
282                  );
283            }
284            else
285            {
286               BXDM_PPFP_P_FixPtAdd(
287                  &(hXdmPP->stDMState.stDecode.stVTSM.stVirtualSTC),
288                  &(hXdmPP->stDMState.stChannel.stSelectedPicture.stPicParms.stTSM.stStatic.stPTSDelta),
289                  &(hXdmPP->stDMState.stDecode.stVTSM.stVirtualSTC)
290                  );
291            }
292
293            /* Frame advance is a one-shot request, so we reset it to
294             * disabled when we've honored the request */
295            hXdmPP->stDMState.stDecode.stVTSM.eFrameAdvanceMode = BXDM_PictureProvider_FrameAdvanceMode_eOff;
296
297            break;
298
299         case BXDM_PictureProvider_FrameAdvanceMode_eFrame:
300            /* We're doing a FRAME advance, so we need to set the
301             * vSTC to the vPTS of the NEXT PPB */
302            BXVD_DBG_MSG(hXdmPP,("%x: Frame Advance: Frame", hXdmPP->stDMState.stDecode.stDebug.uiVsyncCount));
303            hXdmPP->stDMState.stDecode.stVTSM.stVirtualSTC = hXdmPP->stDMState.stChannel.stSelectedPicture.stPicParms.stTSM.stStatic.stPTSOfNextPPB[BXDM_PictureProvider_P_PTSIndex_eVirtual];
304
305            /* We need to account for the current field inversion
306             * correct offset to ensure the next frame is actually
307             * selected by TSM */
308            if ( true == bInterpolateInReverse )
309            {
310               BXDM_PPFP_P_FixPtSub(
311                  &(hXdmPP->stDMState.stDecode.stVTSM.stVirtualSTC),
312                  &(hXdmPP->stDMState.stDecode.stFieldInversionCorrectionPTSOffset),
313                  &(hXdmPP->stDMState.stDecode.stVTSM.stVirtualSTC)
314                  );
315            }
316            else
317            {
318               BXDM_PPFP_P_FixPtAdd(
319                  &(hXdmPP->stDMState.stDecode.stVTSM.stVirtualSTC),
320                  &(hXdmPP->stDMState.stDecode.stFieldInversionCorrectionPTSOffset),
321                  &(hXdmPP->stDMState.stDecode.stVTSM.stVirtualSTC)
322                  );
323            }
324
325            /* Frame advance is a one-shot request, so we reset it to
326             * disabled when we've honored the request */
327            hXdmPP->stDMState.stDecode.stVTSM.eFrameAdvanceMode = BXDM_PictureProvider_FrameAdvanceMode_eOff;
328
329            break;
330
331         case BXDM_PictureProvider_FrameAdvanceMode_eFrameByField:
332            /* We're doing a FRAME advance by fields, so we need to do
333             * field advances until we get to the next frame */
334            BXVD_DBG_MSG(hXdmPP,("%x: Frame Advance: Frame by Field[%d]",
335                                      hXdmPP->stDMState.stDecode.stDebug.uiVsyncCount,
336                                      hXdmPP->stDMConfig.uiFrameAdvanceByFieldCount
337                                 ));
338
339            if ( hXdmPP->stDMConfig.uiFrameAdvanceByFieldCount > 0 )
340            {
341               if ( true == bInterpolateInReverse )
342               {
343                  BXDM_PPFP_P_FixPtSub(
344                     &(hXdmPP->stDMState.stDecode.stVTSM.stVirtualSTC),
345                     &(hXdmPP->stDMState.stChannel.stSelectedPicture.stPicParms.stTSM.stStatic.stPTSDelta),
346                     &(hXdmPP->stDMState.stDecode.stVTSM.stVirtualSTC)
347                     );
348               }
349               else
350               {
351                  BXDM_PPFP_P_FixPtAdd(
352                     &(hXdmPP->stDMState.stDecode.stVTSM.stVirtualSTC),
353                     &(hXdmPP->stDMState.stChannel.stSelectedPicture.stPicParms.stTSM.stStatic.stPTSDelta),
354                     &(hXdmPP->stDMState.stDecode.stVTSM.stVirtualSTC)
355                     );
356               }
357
358               hXdmPP->stDMConfig.uiFrameAdvanceByFieldCount--;
359            }
360
361            if ( 0 == hXdmPP->stDMConfig.uiFrameAdvanceByFieldCount )
362            {
363               hXdmPP->stDMState.stDecode.stVTSM.eFrameAdvanceMode = BXDM_PictureProvider_FrameAdvanceMode_eOff;
364            }
365            break;
366
367         default:
368            break;
369      }
370   }
371
372   BDBG_LEAVE(BXDM_PPVTSM_P_VirtualStcIncrement);
373   return;
374}
375
376void BXDM_PPVTSM_P_VirtualPtsInterpolate(
377   BXDM_PictureProvider_Handle hXdmPP,
378   BXDM_PictureProvider_P_LocalState* pLocalState,
379   BXDM_PictureProvider_P_Picture_Context* pstPicture,
380   BXDM_PictureProvider_P_Picture_Context* pstPrevPicture,
381   BXDM_PictureProvider_P_Picture_Context* pstSelectedPicture
382   )
383{
384   BXDM_PPFP_P_DataType stVirtualPTSTemp;
385   BXDM_PPFP_P_DataType stVirtualPTSOfNextPPB;
386   uint32_t i;
387   bool bInterpolateInReverse;
388
389   BDBG_ENTER(BXDM_PPVTSM_P_VirtualPtsInterpolate);
390
391   BSTD_UNUSED( pLocalState );
392
393   /* Virtual TSM */
394
395   /* Re-initialize vPTS if the currently selected picture did not
396    * pass TSM */
397
398   /* PR52803: We don't want to do a vPTS reset if we're in a trick
399    * mode transition to prevent the next picture from being displayed
400    * too early if entering back into a trick mode.
401    * E.g. pause->play->pause */
402   if ( ( BXDM_PictureProvider_TSMResult_ePass != pstPrevPicture->stPicParms.stTSM.stDynamic.eTsmResult )
403        && ( false == hXdmPP->stDMState.stDecode.stVTSM.bTrickModeTransition )
404      )
405   {
406      hXdmPP->stDMState.stDecode.stVTSM.bVirtualPTSInitialized = false;
407      BXVD_DBG_MSG(hXdmPP,("%x: [%01x.%03x] vPTS Reset (TSM Failure: %d)",
408                                hXdmPP->stDMState.stDecode.stDebug.uiVsyncCount,
409                                hXdmPP->stDMConfig.uiInstanceID & 0xF,
410                                pstPicture->stPicParms.uiPPBIndex & 0xFFF,
411                                pstPrevPicture->stPicParms.stTSM.stDynamic.eTsmResult));
412   }
413
414   /* We interpolate the vPTS from the previous PPB */
415   if ( (pstPicture->stPicParms.stTSM.stDynamic.eSelectionMode == BXDM_PictureProvider_DisplayMode_eTSM)
416        && ( false == pstPrevPicture->bValidated ) )
417   {
418      /* If we're in TSM mode and the previous picture is invalid, we
419       * set the vPTS of the next PPB based on the CURRENT picture's
420       * ACTUAL interpolated PTS.  This causes the vPTS to track
421       * actual PTS when in TSM mode so that we can have a seamless
422       * transition from TSM --> VSYNC mode */
423      BXDM_PPQM_P_GetPredictedPtsWithFrac(pstPicture,
424                                          BXDM_PictureProvider_P_PTSIndex_eActual,
425                                          &stVirtualPTSOfNextPPB);
426
427      /* We need to add the JRC jitter offset so that the vPTS tracks the de-jittered PTS values */
428      stVirtualPTSOfNextPPB.uiWhole += pstPicture->stPicParms.stTSM.stStatic.iPTSJitterCorrection;
429
430      /* Since we're setting the vPTS based on an actual PTS, we
431       * indicate that the vPTS has been initialized */
432      hXdmPP->stDMState.stDecode.stVTSM.bVirtualPTSInitialized= true;
433   }
434   else
435   {
436      if (pstPicture->stPicParms.stTSM.stDynamic.eSelectionMode == BXDM_PictureProvider_DisplayMode_eTSM)
437      {
438         /* If we're in TSM mode, we set the vPTS of the next PPB based
439          * on the previous picture's ACTUAL interpolated PPB */
440         BXDM_PPQM_P_GetPredictedPtsWithFrac(pstPrevPicture,
441                                             BXDM_PictureProvider_P_PTSIndex_eActual,
442                                             &stVirtualPTSTemp);
443
444         /* We need to add the JRC jitter offset so that the vPTS tracks the de-jittered PTS values */
445         stVirtualPTSTemp.uiWhole += pstPrevPicture->stPicParms.stTSM.stStatic.iPTSJitterCorrection;
446
447         hXdmPP->stDMState.stDecode.stVTSM.bVirtualPTSInitialized = true;
448      }
449      else
450      {
451         /* If we're in VSYNC mode, we set the vPTS of the next PPB based
452          * on the previous picture's VIRTUAL interpolated PPB */
453         BXDM_PPQM_P_GetPredictedPtsWithFrac(pstPrevPicture,
454                                             BXDM_PictureProvider_P_PTSIndex_eVirtual,
455                                             &stVirtualPTSTemp);
456
457         /* Handle vPTS skew */
458         /* Detect and correct for PTS skew in vTSM mode.  Skew can occur
459          * when the delivery queue runs dry for one or more vsyncs and
460          * the interpolated PTS for the NEXT PPB is no longer accurate.
461          * The queue can run dry for multiple reasons...errors in the
462          * stream, a stream wrap, etc. In such a case, without this
463          * logic, subsequent PPBs would always have been evaluated as
464          * LATE because the interpolated vPTS would be far behind the
465          * vSTC */
466
467         /* PR52803: We don't want to do vPTS skew detection when in a
468          * trick mode transition to prevent the next picture from
469          * being displayed too early if entering back into a trick
470          * mode.  E.g. pause->play->pause */
471         if ( ( hXdmPP->stDMState.stDecode.stVTSM.bVirtualPTSInitialized )
472              && ( false == hXdmPP->stDMState.stDecode.stVTSM.bTrickModeTransition )
473            )
474         {
475            uint32_t uiStcPtsDifference = 0;
476            /* PR57049: We use the dStcPts when last displayed (vs the evaluated) one
477             * because the evaluated one has been updated already before we started
478             * evaluating this picture */
479            if ( pstSelectedPicture->stPicParms.stTSM.stDynamic.iStcPtsDifferenceDisplayed > 0 )
480            {
481               uiStcPtsDifference = (uint32_t) pstSelectedPicture->stPicParms.stTSM.stDynamic.iStcPtsDifferenceDisplayed;
482            }
483
484            if ( uiStcPtsDifference >= ( pstSelectedPicture->stPicParms.stTSM.stStatic.stPTSDelta.uiWhole +
485                                         ( pstSelectedPicture->stPicParms.stTSM.stStatic.stPTSDelta.uiFractional ? 1 : 0 ) ) )
486            {
487               hXdmPP->stDMState.stDecode.stVTSM.bVirtualPTSInitialized = false;
488               BXVD_DBG_MSG(hXdmPP,("%x: [%01x.%03x] vPTS Reset (vPTS Skew Detected: %d)",
489                                         hXdmPP->stDMState.stDecode.stDebug.uiVsyncCount,
490                                         hXdmPP->stDMConfig.uiInstanceID & 0xF,
491                                         pstPicture->stPicParms.uiPPBIndex & 0xFFF,
492                                         uiStcPtsDifference));
493            }
494         }
495
496         /* We need to override the predicted virtualPTS for this PPB */
497         if ( false == hXdmPP->stDMState.stDecode.stVTSM.bVirtualPTSInitialized)
498         {
499            /* We've just entered into VSYNC mode, so we need to set the
500             * vPTS to a default starting value equal to the starting
501             * vSTC value.  Also, When in vTSM mode, make sure we don't
502             * assign a stale PTS value for this PPB, so we need to
503             * assign this PPB the larger of the current STC or the
504             * interpolated PTS */
505
506            stVirtualPTSTemp = hXdmPP->stDMState.stDecode.stVTSM.stVirtualSTC;
507
508            /* SW7425-2656:  If this is the first picture after a "flush" and the system is paused,
509             * we don't want to display this picture until the system is unpaused or a "frame advance"
510             * command is issued.  This is achieved by setting the vPTS to be larger than the vSTC. 
511             * The value doesn't matter since the vPTS will be reset again once the system is unpaused.
512             *
513             * "hold last picture" is implicit with the "flush"; by forcing this picture to be a
514             * little early, the picture that was being displayed will continue to be displayed.
515             *
516             * In contrast to the behavior after a "flush", if the system is paused prior to calling BXVD_StartDecode
517             * in the normal manner, the first picture will be displayed.
518             */
519            if ( ( true == hXdmPP->stDMState.stChannel.bPostFlushDecode )
520                 && ( 0 == pLocalState->uiSlowMotionRate )
521                 && ( 1 == pstPicture->stPicParms.uiPPBIndex )
522               )
523            {
524               /* The amount added doesn't matter. */
525               stVirtualPTSTemp.uiWhole += 10;
526
527               BXVD_DBG_MSG(hXdmPP,("%x: [%01x.%03x] set vPTS for 1st picture with system paused: vStc:%08x vPTS:%08x",
528                                         hXdmPP->stDMState.stDecode.stDebug.uiVsyncCount,
529                                         hXdmPP->stDMConfig.uiInstanceID & 0xF,
530                                         pstPicture->stPicParms.uiPPBIndex & 0xFFF,
531                                         hXdmPP->stDMState.stDecode.stVTSM.stVirtualSTC.uiWhole,
532                                         stVirtualPTSTemp.uiWhole
533                                         ));
534            }
535            else
536            {
537               uint32_t uiPtsOffset;
538         
539               /* SW7425-2255: once a picture has been selected for display, use the
540                * offset bound to the picture.
541                */
542               BXDM_PPQM_P_GetPtsOffset( hXdmPP, pstPicture, &uiPtsOffset );
543
544               /* Subtract the PTS offset */
545               stVirtualPTSTemp.uiWhole -= uiPtsOffset;
546
547               /* Subtract the field inversion correction offset */
548               BXDM_PPFP_P_FixPtSub(
549                  &stVirtualPTSTemp,
550                  &hXdmPP->stDMState.stDecode.stFieldInversionCorrectionPTSOffset,
551                  &stVirtualPTSTemp);
552            }
553
554            hXdmPP->stDMState.stDecode.stVTSM.bVirtualPTSInitialized = true;
555
556         }  /* end of if ( false == hXdmPP->stDMState.stDecode.stVTSM.bVirtualPTSInitialized ) */
557
558      }
559
560      /* SW7425-1264: if the "physical" STC is running in reverse, interpolate the virtual PTS's in
561       * reverse as well.
562       */
563      bInterpolateInReverse = ( true == hXdmPP->stDMConfig.stClockOverride.bEnableClockOverride );
564      bInterpolateInReverse &= ( hXdmPP->stDMConfig.stClockOverride.iStcDelta < 0 );
565
566      /* Set the PTS for each element in the PPB */
567      stVirtualPTSOfNextPPB = stVirtualPTSTemp;
568      for (i = 0; i < pstPicture->stPicParms.stTSM.stStatic.uiNumElements; i++)
569      {
570
571         BXDM_PPQM_P_SetPtsWithFrac(pstPicture, BXDM_PictureProvider_P_PTSIndex_eVirtual, i, stVirtualPTSTemp);
572
573#if 0
574         BKNI_Printf("vPTS[%d]: %08x\n", i, stVirtualPTSTemp.uiWhole);
575#endif
576
577         if ( true == bInterpolateInReverse )
578         {
579            BXDM_PPFP_P_FixPtSub(
580               &stVirtualPTSTemp,
581               &(pstPicture->stPicParms.stTSM.stStatic.stPTSDelta),
582               &stVirtualPTSTemp
583               );
584
585            /* Calculate the next PPB's virtual PTS */
586            BXDM_PPFP_P_FixPtSub(
587               &stVirtualPTSOfNextPPB,
588               &(pstPicture->stPicParms.stTSM.stStatic.stPTSDelta),
589               &stVirtualPTSOfNextPPB
590               );
591         }
592         else
593         {
594            BXDM_PPFP_P_FixPtAdd(
595               &stVirtualPTSTemp,
596               &(pstPicture->stPicParms.stTSM.stStatic.stPTSDelta),
597               &stVirtualPTSTemp
598               );
599
600            /* Calculate the next PPB's virtual PTS */
601            BXDM_PPFP_P_FixPtAdd(
602               &stVirtualPTSOfNextPPB,
603               &(pstPicture->stPicParms.stTSM.stStatic.stPTSDelta),
604               &stVirtualPTSOfNextPPB
605               );
606         }
607
608      }
609
610#if 0
611      BKNI_Printf("vPTSPredicted: %d\n", stVirtualPTSOfNextPPB.uiWhole);
612#endif
613   }
614
615   BXDM_PPQM_P_SetPredictedPtsWithFrac(pstPicture, BXDM_PictureProvider_P_PTSIndex_eVirtual, stVirtualPTSOfNextPPB);
616
617   BDBG_LEAVE(BXDM_PPVTSM_P_VirtualPtsInterpolate);
618   return;
619} /* end of BXDM_PPVTSM_P_VirtualPtsInterpolate() */
620
621void BXDM_PPVTSM_P_VirtualStcGet(
622   const BXDM_PictureProvider_Handle hXdmPP,
623   uint32_t* puiStc
624   )
625{
626   bool bInterpolateInReverse;
627
628   *puiStc = hXdmPP->stDMState.stDecode.stVTSM.stVirtualSTC.uiWhole;
629
630   /* SW7425-1264: only round the virtual STC up if the "physical" STC is
631    * running in the forward direction.
632    */
633   bInterpolateInReverse = ( true == hXdmPP->stDMConfig.stClockOverride.bEnableClockOverride );
634   bInterpolateInReverse &= ( hXdmPP->stDMConfig.stClockOverride.iStcDelta < 0 );
635
636   if ( 0 != hXdmPP->stDMState.stDecode.stVTSM.stVirtualSTC.uiFractional
637        && false == bInterpolateInReverse
638      )
639       
640   {
641      (*puiStc)++;
642   }
643
644   return;
645} /* end of BXDM_PPVTSM_P_VirtualStcGet() */
646
647void BXDM_PPVTSM_P_ClipTimeTrickModeTransitionHandler(
648   BXDM_PictureProvider_Handle hXdmPP,
649   BXDM_PictureProvider_P_LocalState * pLocalState
650   )
651{
652   BSTD_UNUSED(pLocalState);
653
654   BXVD_DBG_MSG(hXdmPP, ("%x: Entering trick mode transition (stc: %x)",
655                              hXdmPP->stDMState.stDecode.stDebug.uiVsyncCount,
656                              pLocalState->uiAdjustedStc));
657   hXdmPP->stDMState.stDecode.stVTSM.bTrickModeTransition = true;
658}
Note: See TracBrowser for help on using the repository browser.