source: svn/newcon3bcm2_21bu/magnum/commonutils/xdm/bxdm_pp_jrc.c @ 74

Last change on this file since 74 was 74, checked in by phkim, 10 years ago
  1. phkim
  2. zasc
  3. 변경 내용
    • CT_ChMapUpdatePMTAC3AudioDescriptor 메모리 leak 버그 수정
  • Property svn:executable set to *
File size: 13.3 KB
Line 
1/***************************************************************************
2 *     Copyright (c) 2003-2011, 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_jrc.c $
11 * $brcm_Revision: Hydra_Software_Devel/3 $
12 * $brcm_Date: 4/29/11 9:30a $
13 *
14 * [File Description:]
15 *
16 * Revision History:
17 *
18 * $brcm_Log: /magnum/commonutils/xdm/bxdm_pp_jrc.c $
19 *
20 * Hydra_Software_Devel/3   4/29/11 9:30a nilesh
21 * SWDTV-5937: Fixed compilation warning in release mode
22 *
23 * Hydra_Software_Devel/2   4/28/11 2:01p nilesh
24 * SWDTV-5937,SW7405-5057: Converted to using BXDM_PP_Fix33 fixed point
25 * library.  Fixed JRC stability when frame rate has a fractional (e.g.
26 * 29.97).
27 *
28 * Hydra_Software_Devel/1   2/16/10 10:51a nilesh
29 * SW7405-2993: Initial XDM version
30 *
31 ***************************************************************************/
32
33#include "bstd.h"
34#include "bkni.h"
35#include "bdbg.h"
36#include "berr.h"
37#include "bxdm_pp_jrc.h"
38#include "bxdm_pp_fix33.h"
39
40#if BXDM_PPJRC_P_DUMP
41#include <stdio.h>
42#endif
43
44BDBG_MODULE(BXDM_PPJRC);
45
46const char BXDM_PictureProvider_P_DISPMGR_JRC_NODE[]="DMJRC:\t""$brcm_Revision: Hydra_Software_Devel/3 $";
47
48/* The jitter correction (JRC) module corrects jitter in incoming values
49 * by using a linear best fit algorithm.  The module uses the expected delta
50 * to facilitate the fitting.  An estimated PTS value is calculated using the
51 * initial PTS sample.  An average bias is calculated by computing the difference
52 * between the estimated PTS and the actual PTS.  The average bias is then added
53 * to the estimated PTS and used as the corrected PTS.
54 *
55 * Mathematically, the algorithm can be described as:
56 * (Based on work by Richard Lee - rrlee@broadcom.com)
57 *
58 * D == precise differences between PTS (a.k.a frame time)
59 * P[n] == nth delivered PTS (+/- 1 ms)
60 * T[n] == nth interpolated PTS
61 *      = P[0] + n*D
62 * E[n] == nth bias between actual and interpolated PTS
63 *      = P[n] - T[n]
64 * B[n] == nth average bias
65 *      = avg(E[n] ... E[0])
66 * C[n] == nth correct PTS
67 *      = T[n] + B[n]
68 */
69
70typedef struct BXDM_PPJRC_P_Context
71{
72   BXDM_PPJRC_P_Settings stSettings;
73
74   bool bSeeded;
75
76   uint32_t uiBiasCount;
77   uint32_t uiBiasIndex;
78   BXDM_PP_Fix33_t *afixBias;
79   BXDM_PP_Fix33_t fixCumulativeBias;
80
81   BXDM_PP_Fix33_t fixPreviousActualValueP;
82   BXDM_PP_Fix33_t fixPreviousCorrectedValueC;
83   BXDM_PP_Fix33_t fixDeltaStep;
84   uint32_t uiStepCount;
85
86   BXDM_PP_Fix33_t fixExpectedValueT;
87
88   uint32_t uiTotalCount;
89#if BXDM_PPJRC_P_DUMP
90   FILE *fDump;
91#endif
92} BXDM_PPJRC_P_Context;
93
94static const BXDM_PPJRC_P_Settings s_stJrcDefaultSettings =
95{
96 120, /* Samples */
97 1,  /* Lower Threshold */
98 45  /* Upper Threshold */
99};
100
101BERR_Code BXDM_PPJRC_P_GetDefaultSettings(
102   BXDM_PPJRC_P_Settings *pstJrcSettings
103   )
104{
105   BDBG_ENTER(BXDM_PPJRC_P_GetDefaultSettings);
106
107   BDBG_ASSERT(pstJrcSettings);
108
109   *pstJrcSettings = s_stJrcDefaultSettings;
110
111   BDBG_LEAVE(BXDM_PPJRC_P_GetDefaultSettings);
112
113   return BERR_TRACE(BERR_SUCCESS);
114}
115
116/* Create the XVD JRC Handle */
117BERR_Code BXDM_PPJRC_P_Create(
118   BXDM_PPJRC_P_Handle *phJrc,
119   const BXDM_PPJRC_P_Settings *pJrcSettings
120   )
121{
122   BXDM_PPJRC_P_Context *pJrcHandle = NULL;
123
124   BDBG_ENTER(BXDM_PPJRC_P_Create);
125
126   BDBG_ASSERT(phJrc);
127   BDBG_ASSERT(pJrcSettings);
128   BDBG_ASSERT(pJrcSettings->uiQueueDepth);
129
130   /* Set handle to NULL in case the allocation fails */
131   *phJrc = NULL;
132
133   /* Allocate JRC Handle */
134   pJrcHandle = (BXDM_PPJRC_P_Context *) BKNI_Malloc(sizeof(BXDM_PPJRC_P_Context));
135   if (!pJrcHandle)
136   {
137      return BERR_TRACE(BERR_OUT_OF_SYSTEM_MEMORY);
138   }
139
140   /* Zero out the newly allocated context */
141   BKNI_Memset((void*)pJrcHandle, 0, sizeof(BXDM_PPJRC_P_Context));
142
143   /* Allocate value queue */
144   pJrcHandle->stSettings = *pJrcSettings;
145
146   pJrcHandle->afixBias = (BXDM_PP_Fix33_t *) BKNI_Malloc(sizeof(BXDM_PP_Fix33_t) * pJrcHandle->stSettings.uiQueueDepth);
147   if (!pJrcHandle->afixBias)
148   {
149      BXDM_PPJRC_P_Destroy(pJrcHandle);
150      return BERR_TRACE(BERR_OUT_OF_SYSTEM_MEMORY);
151   }
152   BKNI_Memset((void*)pJrcHandle->afixBias, 0, (sizeof(BXDM_PP_Fix33_t) * pJrcHandle->stSettings.uiQueueDepth));
153
154   *phJrc = pJrcHandle;
155
156   BDBG_LEAVE(BXDM_PPJRC_P_Create);
157
158   return BERR_TRACE(BERR_SUCCESS);
159}
160
161/* Destroy the XVD JRC Handle */
162BERR_Code BXDM_PPJRC_P_Destroy(
163   BXDM_PPJRC_P_Handle hJrc
164   )
165{
166   BDBG_ENTER(BXDM_PPJRC_P_Destroy);
167
168   BDBG_ASSERT(hJrc);
169
170#if BXDM_P_PPJRC_DUMP
171   if ( NULL != hJrc->fDump )
172   {
173      fclose(hJrc->fDump);
174      hJrc->fDump = NULL;
175   }
176#endif
177
178   if ( hJrc->afixBias )
179   {
180      BKNI_Free(hJrc->afixBias);
181      hJrc->afixBias = NULL;
182   }
183
184   BKNI_Free(hJrc);
185
186   BDBG_LEAVE(BXDM_PPJRC_P_Destroy);
187
188   return BERR_TRACE(BERR_SUCCESS);
189}
190
191BERR_Code BXDM_PPJRC_P_Reset(
192   BXDM_PPJRC_P_Handle hJrc
193   )
194{
195   BDBG_ENTER(BXDM_PPJRC_P_Reset);
196
197   BDBG_ASSERT(hJrc);
198
199   hJrc->bSeeded = false;
200
201   hJrc->uiBiasCount = 0;
202   hJrc->uiBiasIndex = 0;
203   BKNI_Memset((void*)hJrc->afixBias, 0, (sizeof(BXDM_PP_Fix33_t) * hJrc->stSettings.uiQueueDepth));
204   hJrc->fixCumulativeBias = 0;
205
206   hJrc->uiTotalCount = 0;
207
208   BDBG_LEAVE(BXDM_PPJRC_P_Reset);
209
210   return BERR_TRACE(BERR_SUCCESS);
211}
212
213BERR_Code BXDM_PPJRC_P_AddValue(
214   BXDM_PPJRC_P_Handle hJrc,
215   uint32_t uiCurrentValue,
216   const BXDM_PPFP_P_DataType *pstExpectedDelta,
217   uint32_t uiStepCount,
218   uint32_t *puiJitterCorrectedValue
219   )
220{
221   BXDM_PP_Fix33_t fixExpectedDeltaD;
222
223   BXDM_PP_Fix33_t fixActualValueP;
224   BXDM_PP_Fix33_t fixCorrectedValueC;
225   BXDM_PP_Fix33_t fixCorrection;
226
227   BXDM_PP_Fix33_t fixBiasE = 0;
228   BXDM_PP_Fix33_t fixAverageBiasB = 0;
229
230   BDBG_ENTER(BXDM_PPJRC_P_AddValue);
231   BDBG_ASSERT(hJrc);
232   BDBG_ASSERT(pstExpectedDelta);
233
234   {
235      BXDM_PP_Fix33_t fixExpectedDeltaStep = BXDM_PP_Fix33_from_mixedfraction(
236            pstExpectedDelta->uiWhole,
237            pstExpectedDelta->uiFractional,
238            BXDM_PictureProvider_P_FixedPoint_FractionalOverflow
239            );
240
241      if ( fixExpectedDeltaStep != hJrc->fixDeltaStep )
242      {
243         BDBG_MSG(("RESET - Delta Changed (%llx --> %llx)",
244                  hJrc->fixDeltaStep,
245                  fixExpectedDeltaStep
246                  ));
247         BXDM_PPJRC_P_Reset(hJrc);
248         hJrc->fixDeltaStep = fixExpectedDeltaStep;
249      }
250   }
251
252   /* Store original value as fixed point (P[n]) */
253   fixActualValueP = BXDM_PP_Fix33_from_uint32(uiCurrentValue);
254
255   /* Compute Delta Value Expected (D = DeltaStep * StepCount)*/
256   fixExpectedDeltaD= BXDM_PP_Fix33_mulu(hJrc->fixDeltaStep, hJrc->uiStepCount);
257
258   /* Compute interpolated PTS (T[n] = P[0] + n*D) */
259   if ( false == hJrc->bSeeded )
260   {
261      hJrc->fixExpectedValueT = fixActualValueP;
262      hJrc->bSeeded = true;
263   }
264   else
265   {
266      hJrc->fixExpectedValueT = BXDM_PP_Fix33_add( hJrc->fixExpectedValueT, fixExpectedDeltaD );
267   }
268
269   /* Compute the error bias (E[n] = P[n] - T[n]) */
270   fixBiasE = BXDM_PP_Fix33_sub(fixActualValueP, hJrc->fixExpectedValueT);
271
272   if ( !( ( BXDM_PP_Fix33_to_int32(fixBiasE) <= (int32_t) hJrc->stSettings.uiJitterUpperThreshold )
273             && ( BXDM_PP_Fix33_to_int32(fixBiasE) >= -(int32_t)hJrc->stSettings.uiJitterUpperThreshold ) )
274           )
275   {
276      BXDM_PPJRC_P_Reset(hJrc);
277      BDBG_MSG(("RESET[0] - Beyond Jitter Threshold (%d)", BXDM_PP_Fix33_to_int32(fixBiasE)));
278      fixCorrectedValueC = fixActualValueP;
279   }
280   else
281   {
282      fixCorrectedValueC = hJrc->fixExpectedValueT;
283   }
284
285   /* Compute the average bias (B[n] = avg(E[n] ... E[0]))*/
286   if ( hJrc->uiBiasCount < hJrc->stSettings.uiQueueDepth )
287   {
288      /* Increment Bias Count */
289      hJrc->uiBiasCount++;
290   }
291   else
292   {
293      /* Subtract oldest value from running sum */
294      hJrc->fixCumulativeBias = BXDM_PP_Fix33_sub(hJrc->fixCumulativeBias, hJrc->afixBias[hJrc->uiBiasIndex]);
295   }
296
297   hJrc->afixBias[hJrc->uiBiasIndex] = fixBiasE ;
298
299   /* Update running sum */
300   hJrc->fixCumulativeBias = BXDM_PP_Fix33_add(hJrc->fixCumulativeBias, hJrc->afixBias[hJrc->uiBiasIndex]);
301
302   /* Increment Bias index */
303   hJrc->uiBiasIndex++;
304   if ( hJrc->uiBiasIndex >= hJrc->stSettings.uiQueueDepth )
305   {
306      hJrc->uiBiasIndex = 0;
307   }
308
309   /* Adjust corrected value by the Average Bias */
310   if ( hJrc->uiBiasCount > 0 )
311   {
312      fixAverageBiasB = BXDM_PP_Fix33_divu(hJrc->fixCumulativeBias, hJrc->uiBiasCount);
313      fixCorrectedValueC = BXDM_PP_Fix33_add(fixCorrectedValueC, fixAverageBiasB);
314   }
315
316   /* Compute the overall correction (CorrectedValue - ActualValue) */
317   fixCorrection = BXDM_PP_Fix33_sub(fixCorrectedValueC, fixActualValueP);
318
319   if ( ( BXDM_PP_Fix33_to_int32(fixCorrection) <= (int32_t) hJrc->stSettings.uiJitterLowerThreshold )
320        && ( BXDM_PP_Fix33_to_int32(fixCorrection) >= -(int32_t) hJrc->stSettings.uiJitterLowerThreshold )
321      )
322   {
323      fixCorrectedValueC = fixActualValueP;
324      fixCorrection = 0;
325   }
326   else if ( !( ( BXDM_PP_Fix33_to_int32(fixCorrection) <= (int32_t) hJrc->stSettings.uiJitterUpperThreshold )
327                && ( BXDM_PP_Fix33_to_int32(fixCorrection) >= -(int32_t)hJrc->stSettings.uiJitterUpperThreshold ) )
328           )
329   {
330      BXDM_PPJRC_P_Reset(hJrc);
331      BDBG_MSG(("RESET[1] - Beyond Jitter Threshold (%d %llx)", BXDM_PP_Fix33_to_int32(fixCorrection), fixCorrection));
332      fixCorrectedValueC = fixActualValueP;
333      fixAverageBiasB = 0;
334      fixCorrection = 0;
335   }
336
337   hJrc->uiTotalCount++;
338
339   {
340#if BDBG_DEBUG_BUILD
341      BXDM_PP_Fix33_t fixActualDelta = BXDM_PP_Fix33_sub(fixActualValueP, hJrc->fixPreviousActualValueP);
342      BXDM_PP_Fix33_t fixActualDeltaError = BXDM_PP_Fix33_sub(fixActualDelta, fixExpectedDeltaD);
343      BXDM_PP_Fix33_t fixCorrectedDelta = BXDM_PP_Fix33_sub(fixCorrectedValueC, hJrc->fixPreviousCorrectedValueC);
344#endif
345
346      BDBG_MSG(("%03d: (Pn:%08x (dPn:%08x edPn:%08x err:%3d)) (Tn:%08x En:%3d) (Bn:%3d) --> (Cn:%08x (dCn:%08x (%3d))",
347               hJrc->uiTotalCount % 1000,
348               BXDM_PP_Fix33_to_uint32(fixActualValueP),
349               BXDM_PP_Fix33_to_uint32(fixActualDelta),
350               BXDM_PP_Fix33_to_uint32(fixExpectedDeltaD),
351               BXDM_PP_Fix33_to_int32(fixActualDeltaError),
352               BXDM_PP_Fix33_to_uint32(hJrc->fixExpectedValueT),
353               BXDM_PP_Fix33_to_int32(fixBiasE),
354               BXDM_PP_Fix33_to_int32(fixAverageBiasB),
355               BXDM_PP_Fix33_to_uint32(fixCorrectedValueC),
356               BXDM_PP_Fix33_to_uint32(fixCorrectedDelta),
357               BXDM_PP_Fix33_to_int32(fixCorrection)
358               ));
359
360#if BXDM_PPJRC_P_DUMP
361      {
362         if ( NULL == hJrc->fDump )
363         {
364            hJrc->fDump = fopen("BXDM_PPJRC.csv", "wb");
365
366            if ( NULL != hJrc->fDump )
367            {
368               fprintf(hJrc->fDump,"Pn,dPn,edPn,err,Tn,En,Bn,Cn,dCn,corr\n");
369            }
370         }
371
372         if ( NULL != hJrc->fDump )
373         {
374            fprintf(hJrc->fDump, "%u,%u,%u,%d,%u,%u,%d,%u,%u,%d\n",
375                     BXDM_PP_Fix33_to_uint32(fixActualValueP),
376                     BXDM_PP_Fix33_to_uint32(fixActualDelta),
377                     BXDM_PP_Fix33_to_uint32(fixExpectedDeltaD),
378                     BXDM_PP_Fix33_to_int32(fixActualDeltaError),
379                     BXDM_PP_Fix33_to_uint32(hJrc->fixExpectedValueT),
380                     BXDM_PP_Fix33_to_int32(fixBiasE),
381                     BXDM_PP_Fix33_to_int32(fixAverageBiasB),
382                     BXDM_PP_Fix33_to_uint32(fixCorrectedValueC),
383                     BXDM_PP_Fix33_to_uint32(fixCorrectedDelta),
384                     BXDM_PP_Fix33_to_int32(fixCorrection)
385                    );
386         }
387      }
388#endif
389   }
390
391   hJrc->fixPreviousCorrectedValueC = fixCorrectedValueC;
392   hJrc->fixPreviousActualValueP = fixActualValueP;
393   hJrc->uiStepCount = uiStepCount;
394   *puiJitterCorrectedValue = BXDM_PP_Fix33_to_uint32(fixCorrectedValueC);
395
396   BDBG_LEAVE(BXDM_PPJRC_P_AddValue);
397
398   return BERR_TRACE(BERR_SUCCESS);
399}
400
401BERR_Code BXDM_PPJRC_P_GetLowerThreshold(
402   BXDM_PPJRC_P_Handle hJrc,
403   uint32_t *puiLowerThreshold
404   )
405{
406   BDBG_ENTER(BXDM_PPJRC_P_GetLowerThreshold);
407   BDBG_ASSERT(hJrc);
408   BDBG_ASSERT(puiLowerThreshold);
409
410   *puiLowerThreshold = hJrc->stSettings.uiJitterLowerThreshold;
411
412   BDBG_LEAVE(BXDM_PPJRC_P_GetLowerThreshold);
413   return BERR_TRACE(BERR_SUCCESS);
414}
415
416BERR_Code BXDM_PPJRC_P_SetLowerThreshold(
417   BXDM_PPJRC_P_Handle hJrc,
418   uint32_t uiLowerThreshold
419   )
420{
421   BDBG_ENTER(BXDM_PPJRC_P_SetLowerThreshold);
422   BDBG_ASSERT(hJrc);
423
424   hJrc->stSettings.uiJitterLowerThreshold = uiLowerThreshold;
425
426   BDBG_LEAVE(BXDM_PPJRC_P_SetLowerThreshold);
427   return BERR_TRACE(BERR_SUCCESS);
428}
429
430BERR_Code BXDM_PPJRC_P_GetUpperThreshold(
431   BXDM_PPJRC_P_Handle hJrc,
432   uint32_t *puiUpperThreshold
433   )
434{
435   BDBG_ENTER(BXDM_PPJRC_P_GetUpperThreshold);
436   BDBG_ASSERT(hJrc);
437   BDBG_ASSERT(puiUpperThreshold);
438
439   *puiUpperThreshold = hJrc->stSettings.uiJitterUpperThreshold;
440
441   BDBG_LEAVE(BXDM_PPJRC_P_GetUpperThreshold);
442   return BERR_TRACE(BERR_SUCCESS);
443}
444
445BERR_Code BXDM_PPJRC_P_SetUpperThreshold(
446   BXDM_PPJRC_P_Handle hJrc,
447   uint32_t uiUpperThreshold
448   )
449{
450   BDBG_ENTER(BXDM_PPJRC_P_SetUpperThreshold);
451   BDBG_ASSERT(hJrc);
452
453   hJrc->stSettings.uiJitterUpperThreshold = uiUpperThreshold;
454
455   BDBG_LEAVE(BXDM_PPJRC_P_SetUpperThreshold);
456   return BERR_TRACE(BERR_SUCCESS);
457}
Note: See TracBrowser for help on using the repository browser.