decoder_synchro.c
上传用户:kjfoods
上传日期:2020-07-06
资源大小:29949k
文件大小:21k
源码类别:

midi

开发平台:

Unix_Linux

  1. /*****************************************************************************
  2.  * decoder_synchro.c : frame dropping routines
  3.  *****************************************************************************
  4.  * Copyright (C) 1999-2005 the VideoLAN team
  5.  * $Id: 9652d2e1ecb60da2ee66897df01acdc0de125c89 $
  6.  *
  7.  * Authors: Christophe Massiot <massiot@via.ecp.fr>
  8.  *          Samuel Hocevar <sam@via.ecp.fr>
  9.  *          Jean-Marc Dressler <polux@via.ecp.fr>
  10.  *
  11.  * This program is free software; you can redistribute it and/or modify
  12.  * it under the terms of the GNU General Public License as published by
  13.  * the Free Software Foundation; either version 2 of the License, or
  14.  * (at your option) any later version.
  15.  *
  16.  * This program is distributed in the hope that it will be useful,
  17.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  18.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  19.  * GNU General Public License for more details.
  20.  *
  21.  * You should have received a copy of the GNU General Public License
  22.  * along with this program; if not, write to the Free Software
  23.  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
  24.  *****************************************************************************/
  25. /*
  26.  * DISCUSSION : How to Write an efficient Frame-Dropping Algorithm
  27.  * ==========
  28.  *
  29.  * This implementation is based on mathematical and statistical
  30.  * developments. Older implementations used an enslavement, considering
  31.  * that if we're late when reading an I picture, we will decode one frame
  32.  * less. It had a tendancy to derive, and wasn't responsive enough, which
  33.  * would have caused trouble with the stream control stuff.
  34.  *
  35.  * 1. Structure of a picture stream
  36.  *    =============================
  37.  * Between 2 I's, we have for instance :
  38.  *    I   B   P   B   P   B   P   B   P   B   P   B   I
  39.  *    t0  t1  t2  t3  t4  t5  t6  t7  t8  t9  t10 t11 t12
  40.  * Please bear in mind that B's and IP's will be inverted when displaying
  41.  * (decoding order != presentation order). Thus, t1 < t0.
  42.  *
  43.  * 2. Definitions
  44.  *    ===========
  45.  * t[0..12]     : Presentation timestamps of pictures 0..12.
  46.  * t            : Current timestamp, at the moment of the decoding.
  47.  * T            : Picture period, T = 1/frame_rate.
  48.  * tau[I,P,B]   : Mean time to decode an [I,P,B] picture.
  49.  * tauYUV       : Mean time to render a picture (given by the video_output).
  50.  * tau´[I,P,B] = 2 * tau[I,P,B] + tauYUV
  51.  *              : Mean time + typical difference (estimated to tau/2, that
  52.  *                needs to be confirmed) + render time.
  53.  * DELTA        : A given error margin.
  54.  *
  55.  * 3. General considerations
  56.  *    ======================
  57.  * We define three types of machines :
  58.  *      14T > tauI : machines capable of decoding all I pictures
  59.  *      2T > tauP  : machines capable of decoding all P pictures
  60.  *      T > tauB   : machines capable of decoding all B pictures
  61.  *
  62.  * 4. Decoding of an I picture
  63.  *    ========================
  64.  * On fast machines, we decode all I's.
  65.  * Otherwise :
  66.  * We can decode an I picture if we simply have enough time to decode it
  67.  * before displaying :
  68.  *      t0 - t > tau´I + DELTA
  69.  *
  70.  * 5. Decoding of a P picture
  71.  *    =======================
  72.  * On fast machines, we decode all P's.
  73.  * Otherwise :
  74.  * First criterion : have time to decode it.
  75.  *      t2 - t > tau´P + DELTA
  76.  *
  77.  * Second criterion : it shouldn't prevent us from displaying the forthcoming
  78.  * I picture, which is more important.
  79.  *      t12 - t > tau´P + tau´I + DELTA
  80.  *
  81.  * 6. Decoding of a B picture
  82.  *    =======================
  83.  * On fast machines, we decode all B's. Otherwise :
  84.  *      t1 - t > tau´B + DELTA
  85.  * Since the next displayed I or P is already decoded, we don't have to
  86.  * worry about it.
  87.  *
  88.  * I hope you will have a pleasant flight and do not forget your life
  89.  * jacket.
  90.  *                                                  --Meuuh (2000-12-29)
  91.  */
  92. /*****************************************************************************
  93.  * Preamble
  94.  *****************************************************************************/
  95. #ifdef HAVE_CONFIG_H
  96. # include "config.h"
  97. #endif
  98. #include <vlc_common.h>
  99. #include <vlc_input.h>
  100. #include <vlc_codec.h>
  101. #include <vlc_codec_synchro.h>
  102. /*
  103.  * Local prototypes
  104.  */
  105. #define MAX_PIC_AVERAGE         8
  106. struct decoder_synchro_t
  107. {
  108.     /* */
  109.     decoder_t       *p_dec;
  110.     /* */
  111.     int             i_frame_rate;
  112.     bool      b_no_skip;
  113.     bool      b_quiet;
  114.     /* date of the beginning of the decoding of the current picture */
  115.     mtime_t         decoding_start;
  116.     /* stream properties */
  117.     unsigned int    i_n_p, i_n_b;
  118.     /* decoding values */
  119.     mtime_t         p_tau[4];                  /* average decoding durations */
  120.     unsigned int    pi_meaningful[4];            /* number of durations read */
  121.     /* render_time filled by SynchroChoose() */
  122.     int i_render_time;
  123.     /* stream context */
  124.     int             i_nb_ref;                /* Number of reference pictures */
  125.     int             i_dec_nb_ref;      /* Number of reference pictures we'll *
  126.                                         * have if we decode the current pic  */
  127.     int             i_trash_nb_ref;    /* Number of reference pictures we'll *
  128.                                         * have if we trash the current pic   */
  129.     unsigned int    i_eta_p, i_eta_b;
  130.     mtime_t         backward_pts, current_pts;
  131.     int             i_current_period;   /* period to add to the next picture */
  132.     int             i_backward_period;  /* period to add after the next
  133.                                          * reference picture
  134.                                          * (backward_period * period / 2) */
  135.     /* statistics */
  136.     unsigned int    i_trashed_pic, i_not_chosen_pic, i_pic;
  137. };
  138. /* Error margins */
  139. #define DELTA                   (int)(0.075*CLOCK_FREQ)
  140. #define MAX_VALID_TAU           (int)(0.3*CLOCK_FREQ)
  141. #define DEFAULT_NB_P            5
  142. #define DEFAULT_NB_B            1
  143. /*****************************************************************************
  144.  * decoder_SynchroInit : You know what ?
  145.  *****************************************************************************/
  146. decoder_synchro_t * decoder_SynchroInit( decoder_t *p_dec, int i_frame_rate )
  147. {
  148.     decoder_synchro_t * p_synchro = calloc( 1, sizeof(*p_synchro) );
  149.     if( !p_synchro )
  150.         return NULL;
  151.     p_synchro->p_dec = p_dec;
  152.     p_synchro->b_no_skip = !config_GetInt( p_dec, "skip-frames" );
  153.     p_synchro->b_quiet = config_GetInt( p_dec, "quiet-synchro" );
  154.     /* We use a fake stream pattern, which is often right. */
  155.     p_synchro->i_n_p = p_synchro->i_eta_p = DEFAULT_NB_P;
  156.     p_synchro->i_n_b = p_synchro->i_eta_b = DEFAULT_NB_B;
  157.     memset( p_synchro->p_tau, 0, 4 * sizeof(mtime_t) );
  158.     memset( p_synchro->pi_meaningful, 0, 4 * sizeof(unsigned int) );
  159.     p_synchro->i_nb_ref = 0;
  160.     p_synchro->i_trash_nb_ref = p_synchro->i_dec_nb_ref = 0;
  161.     p_synchro->current_pts = 1,
  162.     p_synchro->backward_pts = 0;
  163.     p_synchro->i_current_period = p_synchro->i_backward_period = 0;
  164.     p_synchro->i_trashed_pic = p_synchro->i_not_chosen_pic =
  165.         p_synchro->i_pic = 0;
  166.     p_synchro->i_frame_rate = i_frame_rate;
  167.     return p_synchro;
  168. }
  169. /*****************************************************************************
  170.  * decoder_SynchroRelease : You know what ?
  171.  *****************************************************************************/
  172. void decoder_SynchroRelease( decoder_synchro_t * p_synchro )
  173. {
  174.     free( p_synchro );
  175. }
  176. /*****************************************************************************
  177.  * decoder_SynchroReset : Reset the reference picture counter
  178.  *****************************************************************************/
  179. void decoder_SynchroReset( decoder_synchro_t * p_synchro )
  180. {
  181.     p_synchro->i_nb_ref = 0;
  182.     p_synchro->i_trash_nb_ref = p_synchro->i_dec_nb_ref = 0;
  183. }
  184. /*****************************************************************************
  185.  * decoder_SynchroChoose : Decide whether we will decode a picture or not
  186.  *****************************************************************************/
  187. bool decoder_SynchroChoose( decoder_synchro_t * p_synchro, int i_coding_type,
  188.                                int i_render_time, bool b_low_delay )
  189. {
  190. #define TAU_PRIME( coding_type )    (p_synchro->p_tau[(coding_type)] 
  191.                                     + (p_synchro->p_tau[(coding_type)] >> 1) 
  192.                                     + p_synchro->i_render_time)
  193. #define S (*p_synchro)
  194.     mtime_t         now, period;
  195.     mtime_t         pts = 0;
  196.     bool      b_decode = 0;
  197.     int       i_current_rate;
  198.     if ( p_synchro->b_no_skip )
  199.         return 1;
  200.     i_current_rate = decoder_GetDisplayRate( p_synchro->p_dec );
  201.     now = mdate();
  202.     period = 1000000 * 1001 / p_synchro->i_frame_rate
  203.                      * i_current_rate / INPUT_RATE_DEFAULT;
  204.     p_synchro->i_render_time = i_render_time;
  205.     switch( i_coding_type )
  206.     {
  207.     case I_CODING_TYPE:
  208.         if( b_low_delay )
  209.         {
  210.             pts = decoder_GetDisplayDate( p_synchro->p_dec, S.current_pts );
  211.         }
  212.         else if( S.backward_pts )
  213.         {
  214.             pts = decoder_GetDisplayDate( p_synchro->p_dec, S.backward_pts );
  215.         }
  216.         else
  217.         {
  218.             /* displaying order : B B P B B I
  219.              *                      ^       ^
  220.              *                      |       +- current picture
  221.              *                      +- current PTS
  222.              */
  223.             pts = decoder_GetDisplayDate( p_synchro->p_dec, S.current_pts ) + period * (S.i_n_b + 2);
  224.         }
  225.         if( (1 + S.i_n_p * (S.i_n_b + 1)) * period > S.p_tau[I_CODING_TYPE] )
  226.         {
  227.             b_decode = 1;
  228.         }
  229.         else
  230.         {
  231.             b_decode = (pts - now) > (TAU_PRIME(I_CODING_TYPE) + DELTA);
  232.         }
  233.         if( pts <= VLC_TS_INVALID )
  234.             b_decode = 1;
  235.         if( !b_decode && !p_synchro->b_quiet )
  236.         {
  237.             msg_Warn( p_synchro->p_dec,
  238.                       "synchro trashing I (%"PRId64")", pts - now );
  239.         }
  240.         break;
  241.     case P_CODING_TYPE:
  242.         if( b_low_delay )
  243.         {
  244.             pts = decoder_GetDisplayDate( p_synchro->p_dec, S.current_pts );
  245.         }
  246.         else if( S.backward_pts )
  247.         {
  248.             pts = decoder_GetDisplayDate( p_synchro->p_dec, S.backward_pts );
  249.         }
  250.         else
  251.         {
  252.             pts = decoder_GetDisplayDate( p_synchro->p_dec, S.current_pts + period * (S.i_n_b + 1) );
  253.         }
  254.         if( p_synchro->i_nb_ref < 1 )
  255.         {
  256.             b_decode = 0;
  257.         }
  258.         else if( (1 + S.i_n_p * (S.i_n_b + 1)) * period >
  259.                 S.p_tau[I_CODING_TYPE] )
  260.         {
  261.             if( (S.i_n_b + 1) * period > S.p_tau[P_CODING_TYPE] )
  262.             {
  263.                 /* Security in case we're _really_ late */
  264.                 b_decode = (pts - now > 0);
  265.             }
  266.             else
  267.             {
  268.                 b_decode = (pts - now) > (TAU_PRIME(P_CODING_TYPE) + DELTA);
  269.                 /* next I */
  270.                 b_decode &= (pts - now
  271.                               + period
  272.                           * ( (S.i_n_p - S.i_eta_p) * (1 + S.i_n_b) - 1 ))
  273.                             > (TAU_PRIME(P_CODING_TYPE)
  274.                                 + TAU_PRIME(I_CODING_TYPE) + DELTA);
  275.             }
  276.         }
  277.         else
  278.         {
  279.             b_decode = 0;
  280.         }
  281.         if( p_synchro->i_nb_ref >= 1 && pts <= VLC_TS_INVALID )
  282.             b_decode = 1;
  283.         break;
  284.     case B_CODING_TYPE:
  285.         pts = decoder_GetDisplayDate( p_synchro->p_dec, S.current_pts );
  286.         if( p_synchro->i_nb_ref < 2 )
  287.         {
  288.             b_decode = 0;
  289.         }
  290.         else if( (S.i_n_b + 1) * period > S.p_tau[P_CODING_TYPE] )
  291.         {
  292.             b_decode = (pts - now) > (TAU_PRIME(B_CODING_TYPE) + DELTA);
  293.         }
  294.         else
  295.         {
  296.             b_decode = 0;
  297.         }
  298.         if( p_synchro->i_nb_ref >= 2 && pts <= VLC_TS_INVALID )
  299.             b_decode = 1;
  300.         break;
  301.     }
  302.     if( !b_decode )
  303.     {
  304.         S.i_not_chosen_pic++;
  305.     }
  306.     return( b_decode );
  307. #undef S
  308. #undef TAU_PRIME
  309. }
  310. /*****************************************************************************
  311.  * decoder_SynchroTrash : Update counters when we trash a picture
  312.  *****************************************************************************/
  313. void decoder_SynchroTrash( decoder_synchro_t * p_synchro )
  314. {
  315.     p_synchro->i_trashed_pic++;
  316.     p_synchro->i_nb_ref = p_synchro->i_trash_nb_ref;
  317. }
  318. /*****************************************************************************
  319.  * decoder_SynchroDecode : Update timers when we decide to decode a picture
  320.  *****************************************************************************/
  321. void decoder_SynchroDecode( decoder_synchro_t * p_synchro )
  322. {
  323.     p_synchro->decoding_start = mdate();
  324.     p_synchro->i_nb_ref = p_synchro->i_dec_nb_ref;
  325. }
  326. /*****************************************************************************
  327.  * decoder_SynchroEnd : Called when the image is totally decoded
  328.  *****************************************************************************/
  329. void decoder_SynchroEnd( decoder_synchro_t * p_synchro, int i_coding_type,
  330.                       bool b_garbage )
  331. {
  332.     mtime_t     tau;
  333.     if( !b_garbage )
  334.     {
  335.         tau = mdate() - p_synchro->decoding_start;
  336.         /* If duration too high, something happened (pause ?), so don't
  337.          * take it into account. */
  338.         if( tau < 3 * p_synchro->p_tau[i_coding_type]
  339.              || ( !p_synchro->pi_meaningful[i_coding_type]
  340.                    && tau < MAX_VALID_TAU ) )
  341.         {
  342.             /* Mean with average tau, to ensure stability. */
  343.             p_synchro->p_tau[i_coding_type] =
  344.                 (p_synchro->pi_meaningful[i_coding_type]
  345.                  * p_synchro->p_tau[i_coding_type] + tau)
  346.                 / (p_synchro->pi_meaningful[i_coding_type] + 1);
  347.             if( p_synchro->pi_meaningful[i_coding_type] < MAX_PIC_AVERAGE )
  348.             {
  349.                 p_synchro->pi_meaningful[i_coding_type]++;
  350.             }
  351.         }
  352.     }
  353. }
  354. /*****************************************************************************
  355.  * decoder_SynchroDate : When an image has been decoded, ask for its date
  356.  *****************************************************************************/
  357. mtime_t decoder_SynchroDate( decoder_synchro_t * p_synchro )
  358. {
  359.     /* No need to lock, since PTS are only used by the video parser. */
  360.     return p_synchro->current_pts;
  361. }
  362. /*****************************************************************************
  363.  * decoder_SynchroNewPicture: Update stream structure and PTS
  364.  *****************************************************************************/
  365. void decoder_SynchroNewPicture( decoder_synchro_t * p_synchro, int i_coding_type,
  366.                                 int i_repeat_field, mtime_t next_pts,
  367.                                 mtime_t next_dts, bool b_low_delay )
  368. {
  369.     mtime_t         period = 1000000 * 1001 / p_synchro->i_frame_rate;
  370. #if 0
  371.     mtime_t         now = mdate();
  372. #endif
  373.     switch( i_coding_type )
  374.     {
  375.     case I_CODING_TYPE:
  376.         if( p_synchro->i_eta_p
  377.              && p_synchro->i_eta_p != p_synchro->i_n_p )
  378.         {
  379. #if 0
  380.             if( !p_synchro->b_quiet )
  381.                 msg_Dbg( p_synchro->p_dec,
  382.                          "stream periodicity changed from P[%d] to P[%d]",
  383.                          p_synchro->i_n_p, p_synchro->i_eta_p );
  384. #endif
  385.             p_synchro->i_n_p = p_synchro->i_eta_p;
  386.         }
  387.         p_synchro->i_eta_p = p_synchro->i_eta_b = 0;
  388.         p_synchro->i_trash_nb_ref = 0;
  389.         if( p_synchro->i_nb_ref < 2 )
  390.             p_synchro->i_dec_nb_ref = p_synchro->i_nb_ref + 1;
  391.         else
  392.             p_synchro->i_dec_nb_ref = p_synchro->i_nb_ref;
  393. #if 0
  394.         if( !p_synchro->b_quiet )
  395.             msg_Dbg( p_synchro->p_dec, "I(%"PRId64") P(%"PRId64")[%d] B(%"PRId64")"
  396.                   "[%d] YUV(%"PRId64") : trashed %d:%d/%d",
  397.                   p_synchro->p_tau[I_CODING_TYPE],
  398.                   p_synchro->p_tau[P_CODING_TYPE],
  399.                   p_synchro->i_n_p,
  400.                   p_synchro->p_tau[B_CODING_TYPE],
  401.                   p_synchro->i_n_b,
  402.                   p_synchro->i_render_time,
  403.                   p_synchro->i_not_chosen_pic,
  404.                   p_synchro->i_trashed_pic -
  405.                   p_synchro->i_not_chosen_pic,
  406.                   p_synchro->i_pic );
  407.         p_synchro->i_trashed_pic = p_synchro->i_not_chosen_pic
  408.             = p_synchro->i_pic = 0;
  409. #else
  410.         if( p_synchro->i_pic >= 100 )
  411.         {
  412.             if( !p_synchro->b_quiet && p_synchro->i_trashed_pic != 0 )
  413.                 msg_Dbg( p_synchro->p_dec, "decoded %d/%d pictures",
  414.                          p_synchro->i_pic
  415.                            - p_synchro->i_trashed_pic,
  416.                          p_synchro->i_pic );
  417.             p_synchro->i_trashed_pic = p_synchro->i_not_chosen_pic
  418.                 = p_synchro->i_pic = 0;
  419.         }
  420. #endif
  421.         break;
  422.     case P_CODING_TYPE:
  423.         p_synchro->i_eta_p++;
  424.         if( p_synchro->i_eta_b
  425.              && p_synchro->i_eta_b != p_synchro->i_n_b )
  426.         {
  427. #if 0
  428.             if( !p_synchro->b_quiet )
  429.                 msg_Dbg( p_synchro->p_dec,
  430.                          "stream periodicity changed from B[%d] to B[%d]",
  431.                          p_synchro->i_n_b, p_synchro->i_eta_b );
  432. #endif
  433.             p_synchro->i_n_b = p_synchro->i_eta_b;
  434.         }
  435.         p_synchro->i_eta_b = 0;
  436.         p_synchro->i_dec_nb_ref = 2;
  437.         p_synchro->i_trash_nb_ref = 0;
  438.         break;
  439.     case B_CODING_TYPE:
  440.         p_synchro->i_eta_b++;
  441.         p_synchro->i_dec_nb_ref = p_synchro->i_trash_nb_ref
  442.             = p_synchro->i_nb_ref;
  443.         break;
  444.     }
  445.     p_synchro->current_pts += p_synchro->i_current_period
  446.                                         * (period >> 1);
  447. #define PTS_THRESHOLD   (period >> 2)
  448.     if( i_coding_type == B_CODING_TYPE || b_low_delay )
  449.     {
  450.         /* A video frame can be displayed 1, 2 or 3 times, according to
  451.          * repeat_first_field, top_field_first, progressive_sequence and
  452.          * progressive_frame. */
  453.         p_synchro->i_current_period = i_repeat_field;
  454.         if( next_pts )
  455.         {
  456.             if( (next_pts - p_synchro->current_pts
  457.                     > PTS_THRESHOLD
  458.                   || p_synchro->current_pts - next_pts
  459.                     > PTS_THRESHOLD) && !p_synchro->b_quiet )
  460.             {
  461.                 msg_Warn( p_synchro->p_dec, "decoder synchro warning: pts != "
  462.                           "current_date (%"PRId64")",
  463.                           p_synchro->current_pts
  464.                               - next_pts );
  465.             }
  466.             p_synchro->current_pts = next_pts;
  467.         }
  468.     }
  469.     else
  470.     {
  471.         p_synchro->i_current_period = p_synchro->i_backward_period;
  472.         p_synchro->i_backward_period = i_repeat_field;
  473.         if( p_synchro->backward_pts )
  474.         {
  475.             if( next_dts &&
  476.                 (next_dts - p_synchro->backward_pts
  477.                     > PTS_THRESHOLD
  478.                   || p_synchro->backward_pts - next_dts
  479.                     > PTS_THRESHOLD) && !p_synchro->b_quiet )
  480.             {
  481.                 msg_Warn( p_synchro->p_dec, "backward_pts != dts (%"PRId64")",
  482.                            next_dts
  483.                                - p_synchro->backward_pts );
  484.             }
  485.             if( (p_synchro->backward_pts - p_synchro->current_pts
  486.                     > PTS_THRESHOLD
  487.                   || p_synchro->current_pts - p_synchro->backward_pts
  488.                     > PTS_THRESHOLD) && !p_synchro->b_quiet )
  489.             {
  490.                 msg_Warn( p_synchro->p_dec,
  491.                           "backward_pts != current_pts (%"PRId64")",
  492.                           p_synchro->current_pts
  493.                               - p_synchro->backward_pts );
  494.             }
  495.             p_synchro->current_pts = p_synchro->backward_pts;
  496.             p_synchro->backward_pts = 0;
  497.         }
  498.         else if( next_dts )
  499.         {
  500.             if( (next_dts - p_synchro->current_pts
  501.                     > PTS_THRESHOLD
  502.                   || p_synchro->current_pts - next_dts
  503.                     > PTS_THRESHOLD) && !p_synchro->b_quiet )
  504.             {
  505.                 msg_Warn( p_synchro->p_dec, "dts != current_pts (%"PRId64")",
  506.                           p_synchro->current_pts
  507.                               - next_dts );
  508.             }
  509.             /* By definition of a DTS. */
  510.             p_synchro->current_pts = next_dts;
  511.             next_dts = 0;
  512.         }
  513.         if( next_pts )
  514.         {
  515.             /* Store the PTS for the next time we have to date an I picture. */
  516.             p_synchro->backward_pts = next_pts;
  517.             next_pts = 0;
  518.         }
  519.     }
  520. #undef PTS_THRESHOLD
  521. #if 0
  522.     /* Removed for incompatibility with slow motion */
  523.     if( p_synchro->current_pts + DEFAULT_PTS_DELAY < now )
  524.     {
  525.         /* We cannot be _that_ late, something must have happened, reinit
  526.          * the dates. */
  527.         if( !p_synchro->b_quiet )
  528.             msg_Warn( p_synchro->p_dec, "PTS << now (%"PRId64"), resetting",
  529.                       now - p_synchro->current_pts - DEFAULT_PTS_DELAY );
  530.         p_synchro->current_pts = now + DEFAULT_PTS_DELAY;
  531.     }
  532.     if( p_synchro->backward_pts
  533.          && p_synchro->backward_pts + DEFAULT_PTS_DELAY < now )
  534.     {
  535.         /* The same. */
  536.         p_synchro->backward_pts = 0;
  537.     }
  538. #endif
  539.     p_synchro->i_pic++;
  540. }