⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 decoder_synchro.c

📁 VLC Player Source Code
💻 C
📖 第 1 页 / 共 2 页
字号:
/***************************************************************************** * decoder_synchro.c : frame dropping routines ***************************************************************************** * Copyright (C) 1999-2005 the VideoLAN team * $Id$ * * Authors: Christophe Massiot <massiot@via.ecp.fr> *          Samuel Hocevar <sam@via.ecp.fr> *          Jean-Marc Dressler <polux@via.ecp.fr> * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA. *****************************************************************************//* * DISCUSSION : How to Write an efficient Frame-Dropping Algorithm * ========== * * This implementation is based on mathematical and statistical * developments. Older implementations used an enslavement, considering * that if we're late when reading an I picture, we will decode one frame * less. It had a tendancy to derive, and wasn't responsive enough, which * would have caused trouble with the stream control stuff. * * 1. Structure of a picture stream *    ============================= * Between 2 I's, we have for instance : *    I   B   P   B   P   B   P   B   P   B   P   B   I *    t0  t1  t2  t3  t4  t5  t6  t7  t8  t9  t10 t11 t12 * Please bear in mind that B's and IP's will be inverted when displaying * (decoding order != presentation order). Thus, t1 < t0. * * 2. Definitions *    =========== * t[0..12]     : Presentation timestamps of pictures 0..12. * t            : Current timestamp, at the moment of the decoding. * T            : Picture period, T = 1/frame_rate. * tau[I,P,B]   : Mean time to decode an [I,P,B] picture. * tauYUV       : Mean time to render a picture (given by the video_output). * tau´[I,P,B] = 2 * tau[I,P,B] + tauYUV *              : Mean time + typical difference (estimated to tau/2, that *                needs to be confirmed) + render time. * DELTA        : A given error margin. * * 3. General considerations *    ====================== * We define three types of machines : *      14T > tauI : machines capable of decoding all I pictures *      2T > tauP  : machines capable of decoding all P pictures *      T > tauB   : machines capable of decoding all B pictures * * 4. Decoding of an I picture *    ======================== * On fast machines, we decode all I's. * Otherwise : * We can decode an I picture if we simply have enough time to decode it * before displaying : *      t0 - t > tau´I + DELTA * * 5. Decoding of a P picture *    ======================= * On fast machines, we decode all P's. * Otherwise : * First criterion : have time to decode it. *      t2 - t > tau´P + DELTA * * Second criterion : it shouldn't prevent us from displaying the forthcoming * I picture, which is more important. *      t12 - t > tau´P + tau´I + DELTA * * 6. Decoding of a B picture *    ======================= * On fast machines, we decode all B's. Otherwise : *      t1 - t > tau´B + DELTA * Since the next displayed I or P is already decoded, we don't have to * worry about it. * * I hope you will have a pleasant flight and do not forget your life * jacket. *                                                  --Meuuh (2000-12-29) *//***************************************************************************** * Preamble *****************************************************************************/#ifdef HAVE_CONFIG_H# include "config.h"#endif#include <vlc_common.h>#include <vlc_input.h>#include <vlc_codec.h>#include <vlc_codec_synchro.h>/* * Local prototypes */#define MAX_PIC_AVERAGE         8struct decoder_synchro_t{    /* */    decoder_t       *p_dec;    /* */    int             i_frame_rate;    int             i_current_rate;    bool      b_no_skip;    bool      b_quiet;    /* date of the beginning of the decoding of the current picture */    mtime_t         decoding_start;    /* stream properties */    unsigned int    i_n_p, i_n_b;    /* decoding values */    mtime_t         p_tau[4];                  /* average decoding durations */    unsigned int    pi_meaningful[4];            /* number of durations read */    /* render_time filled by SynchroChoose() */    int i_render_time;    /* stream context */    int             i_nb_ref;                /* Number of reference pictures */    int             i_dec_nb_ref;      /* Number of reference pictures we'll *                                        * have if we decode the current pic  */    int             i_trash_nb_ref;    /* Number of reference pictures we'll *                                        * have if we trash the current pic   */    unsigned int    i_eta_p, i_eta_b;    mtime_t         backward_pts, current_pts;    int             i_current_period;   /* period to add to the next picture */    int             i_backward_period;  /* period to add after the next                                         * reference picture                                         * (backward_period * period / 2) */    /* statistics */    unsigned int    i_trashed_pic, i_not_chosen_pic, i_pic;};/* Error margins */#define DELTA                   (int)(0.075*CLOCK_FREQ)#define MAX_VALID_TAU           (int)(0.3*CLOCK_FREQ)#define DEFAULT_NB_P            5#define DEFAULT_NB_B            1/***************************************************************************** * decoder_SynchroInit : You know what ? *****************************************************************************/decoder_synchro_t * decoder_SynchroInit( decoder_t *p_dec, int i_frame_rate ){    decoder_synchro_t * p_synchro = malloc( sizeof(*p_synchro) );    if ( p_synchro == NULL )        return NULL;    memset( p_synchro, 0, sizeof(*p_synchro) );    p_synchro->p_dec = p_dec;    p_synchro->b_no_skip = !config_GetInt( p_dec, "skip-frames" );    p_synchro->b_quiet = config_GetInt( p_dec, "quiet-synchro" );    /* We use a fake stream pattern, which is often right. */    p_synchro->i_n_p = p_synchro->i_eta_p = DEFAULT_NB_P;    p_synchro->i_n_b = p_synchro->i_eta_b = DEFAULT_NB_B;    memset( p_synchro->p_tau, 0, 4 * sizeof(mtime_t) );    memset( p_synchro->pi_meaningful, 0, 4 * sizeof(unsigned int) );    p_synchro->i_nb_ref = 0;    p_synchro->i_trash_nb_ref = p_synchro->i_dec_nb_ref = 0;    p_synchro->current_pts = mdate() + DEFAULT_PTS_DELAY;    p_synchro->backward_pts = 0;    p_synchro->i_current_period = p_synchro->i_backward_period = 0;    p_synchro->i_trashed_pic = p_synchro->i_not_chosen_pic =        p_synchro->i_pic = 0;    p_synchro->i_frame_rate = i_frame_rate;    return p_synchro;}/***************************************************************************** * decoder_SynchroRelease : You know what ? *****************************************************************************/void decoder_SynchroRelease( decoder_synchro_t * p_synchro ){    free( p_synchro );}/***************************************************************************** * decoder_SynchroReset : Reset the reference picture counter *****************************************************************************/void decoder_SynchroReset( decoder_synchro_t * p_synchro ){    p_synchro->i_nb_ref = 0;    p_synchro->i_trash_nb_ref = p_synchro->i_dec_nb_ref = 0;}/***************************************************************************** * decoder_SynchroChoose : Decide whether we will decode a picture or not *****************************************************************************/bool decoder_SynchroChoose( decoder_synchro_t * p_synchro, int i_coding_type,                               int i_render_time, bool b_low_delay ){#define TAU_PRIME( coding_type )    (p_synchro->p_tau[(coding_type)] \                                    + (p_synchro->p_tau[(coding_type)] >> 1) \                                    + p_synchro->i_render_time)#define S (*p_synchro)    mtime_t         now, period;    mtime_t         pts = 0;    bool      b_decode = 0;    if ( p_synchro->b_no_skip )        return 1;    now = mdate();    period = 1000000 * 1001 / p_synchro->i_frame_rate                     * p_synchro->i_current_rate / INPUT_RATE_DEFAULT;    p_synchro->i_render_time = i_render_time;    switch( i_coding_type )    {    case I_CODING_TYPE:        if( b_low_delay )        {            pts = S.current_pts;        }        else if( S.backward_pts )        {            pts = S.backward_pts;        }        else        {            /* displaying order : B B P B B I             *                      ^       ^             *                      |       +- current picture             *                      +- current PTS             */            pts = S.current_pts + period * (S.i_n_b + 2);        }        if( (1 + S.i_n_p * (S.i_n_b + 1)) * period >                S.p_tau[I_CODING_TYPE] )        {            b_decode = 1;        }        else        {            b_decode = (pts - now) > (TAU_PRIME(I_CODING_TYPE) + DELTA);        }        if( !b_decode && !p_synchro->b_quiet )        {            msg_Warn( p_synchro->p_dec,                      "synchro trashing I (%"PRId64")", pts - now );        }        break;    case P_CODING_TYPE:        if( b_low_delay )        {            pts = S.current_pts;        }        else if( S.backward_pts )        {            pts = S.backward_pts;        }        else        {            pts = S.current_pts + period * (S.i_n_b + 1);        }        if( p_synchro->i_nb_ref < 1 )        {            b_decode = 0;        }        else if( (1 + S.i_n_p * (S.i_n_b + 1)) * period >                S.p_tau[I_CODING_TYPE] )        {            if( (S.i_n_b + 1) * period > S.p_tau[P_CODING_TYPE] )            {                /* Security in case we're _really_ late */                b_decode = (pts - now > 0);            }            else

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -