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

📄 vout_synchro.c

📁 video linux conference
💻 C
📖 第 1 页 / 共 2 页
字号:
/***************************************************************************** * vout_synchro.c : frame dropping routines ***************************************************************************** * Copyright (C) 1999-2005 VideoLAN * $Id: vout_synchro.c 11086 2005-05-20 18:00:02Z massiot $ * * 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., 59 Temple Place - Suite 330, Boston, MA  02111, 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碔 + 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碢 + DELTA * * Second criterion : it shouldn't prevent us from displaying the forthcoming * I picture, which is more important. *      t12 - t > tau碢 + tau碔 + DELTA * * 6. Decoding of a B picture *    ======================= * On fast machines, we decode all B's. Otherwise : *      t1 - t > tau碆 + 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 *****************************************************************************/#include <stdlib.h>                                                /* free() */#include <string.h>                                    /* memcpy(), memset() */#include <vlc/vlc.h>#include <vlc/vout.h>#include <vlc/input.h>#include "vout_synchro.h"/* * Local prototypes *//* 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/***************************************************************************** * vout_SynchroInit : You know what ? *****************************************************************************/vout_synchro_t * __vout_SynchroInit( vlc_object_t * p_object,                                     int i_frame_rate ){    vout_synchro_t * p_synchro = vlc_object_create( p_object,                                                  sizeof(vout_synchro_t) );    if ( p_synchro == NULL )    {        msg_Err( p_object, "out of memory" );        return NULL;    }    vlc_object_attach( p_synchro, p_object );    p_synchro->b_no_skip = !config_GetInt( p_object, "skip-frames" );    p_synchro->b_quiet = config_GetInt( p_object, "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;}/***************************************************************************** * vout_SynchroRelease : You know what ? *****************************************************************************/void vout_SynchroRelease( vout_synchro_t * p_synchro ){    vlc_object_detach( p_synchro );    vlc_object_destroy( p_synchro );}/***************************************************************************** * vout_SynchroReset : Reset the reference picture counter *****************************************************************************/void vout_SynchroReset( vout_synchro_t * p_synchro ){    p_synchro->i_nb_ref = 0;    p_synchro->i_trash_nb_ref = p_synchro->i_dec_nb_ref = 0;}/***************************************************************************** * vout_SynchroChoose : Decide whether we will decode a picture or not *****************************************************************************/vlc_bool_t vout_SynchroChoose( vout_synchro_t * p_synchro, int i_coding_type,                               int i_render_time, vlc_bool_t 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;    vlc_bool_t      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,                      "synchro trashing I ("I64Fd")", 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            {                b_decode = (pts - now) > (TAU_PRIME(P_CODING_TYPE) + DELTA);                /* next I */                b_decode &= (pts - now                              + period                          * ( (S.i_n_p - S.i_eta_p) * (1 + S.i_n_b) - 1 ))                            > (TAU_PRIME(P_CODING_TYPE)                                + TAU_PRIME(I_CODING_TYPE) + DELTA);            }        }        else        {            b_decode = 0;        }        break;    case B_CODING_TYPE:        pts = S.current_pts;

⌨️ 快捷键说明

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