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

📄 frame.c

📁 VLC Player Source Code
💻 C
📖 第 1 页 / 共 3 页
字号:
/***************************************************************************** * frame.c: MPEG2 video transrating module ***************************************************************************** * Copyright (C) 2003-2004 the VideoLAN team * Copyright (C) 2003 Antoine Missout <antoine.missout@metakine.com> * Copyright (C) 2000-2003 Michel Lespinasse <walken@zoy.org> * Copyright (C) 1999-2000 Aaron Holtzman <aholtzma@ess.engr.uvic.ca> * $Id: 5d7a02e3ffdc8380cea90fcacbabe818a213c823 $ * * Authors: Christophe Massiot <massiot@via.ecp.fr> *          Laurent Aimar <fenrir@via.ecp.fr> *          Antoine Missout <antoine.missout@metakine.com> *          Michel Lespinasse <walken@zoy.org> *          Aaron Holtzman <aholtzma@ess.engr.uvic.ca> * * 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. *****************************************************************************//***************************************************************************** * Preamble *****************************************************************************/#define NDEBUG 1#include <assert.h>#include <math.h>#ifdef HAVE_CONFIG_H# include "config.h"#endif#include <vlc_common.h>#include <vlc_sout.h>#include <vlc_codec.h>#include "transrate.h"/**************************************************************************** * transrater, code from M2VRequantizer http://www.metakine.com/ ****************************************************************************/// useful constantsenum{    I_TYPE = 1,    P_TYPE = 2,    B_TYPE = 3};/////---- begin ext mpeg code#include "putvlc.h"#include "getvlc.h"static const int non_linear_quantizer_scale [] ={     0,  1,  2,  3,  4,  5,   6,   7,     8, 10, 12, 14, 16, 18,  20,  22,    24, 28, 32, 36, 40, 44,  48,  52,    56, 64, 72, 80, 88, 96, 104, 112};static inline int get_macroblock_modes( transrate_t *tr ){    bs_transrate_t *bs = &tr->bs;    int macroblock_modes;    const MBtab * tab;    switch( tr->picture_coding_type )    {        case I_TYPE:            tab = MB_I + UBITS (bs->i_bit_in_cache, 1);            bs_flush( bs, tab->len );            macroblock_modes = tab->modes;            if ((!(tr->frame_pred_frame_dct)) && (tr->picture_structure == FRAME_PICTURE))            {                macroblock_modes |= UBITS (bs->i_bit_in_cache, 1) * DCT_TYPE_INTERLACED;                bs_flush( bs, 1 );            }            return macroblock_modes;        case P_TYPE:            tab = MB_P + UBITS (bs->i_bit_in_cache, 5);            bs_flush( bs, tab->len );            macroblock_modes = tab->modes;            if (tr->picture_structure != FRAME_PICTURE)            {                if (macroblock_modes & MACROBLOCK_MOTION_FORWARD)                {                    macroblock_modes |= UBITS (bs->i_bit_in_cache, 2) * MOTION_TYPE_BASE;                    bs_flush( bs, 2 );                }                return macroblock_modes;            }            else if (tr->frame_pred_frame_dct)            {                if (macroblock_modes & MACROBLOCK_MOTION_FORWARD)                    macroblock_modes |= MC_FRAME;                return macroblock_modes;            }            else            {                if (macroblock_modes & MACROBLOCK_MOTION_FORWARD)                {                    macroblock_modes |= UBITS (bs->i_bit_in_cache, 2) * MOTION_TYPE_BASE;                    bs_flush( bs, 2 );                }                if (macroblock_modes & (MACROBLOCK_INTRA | MACROBLOCK_PATTERN))                {                    macroblock_modes |= UBITS (bs->i_bit_in_cache, 1) * DCT_TYPE_INTERLACED;                    bs_flush( bs, 1 );                }                return macroblock_modes;            }        case B_TYPE:            tab = MB_B + UBITS (bs->i_bit_in_cache, 6);            bs_flush( bs, tab->len );            macroblock_modes = tab->modes;            if( tr->picture_structure != FRAME_PICTURE)            {                if (! (macroblock_modes & MACROBLOCK_INTRA))                {                    macroblock_modes |= UBITS (bs->i_bit_in_cache, 2) * MOTION_TYPE_BASE;                    bs_flush( bs, 2 );                }                return macroblock_modes;            }            else if (tr->frame_pred_frame_dct)            {                /* if (! (macroblock_modes & MACROBLOCK_INTRA)) */                macroblock_modes |= MC_FRAME;                return macroblock_modes;            }            else            {                if (macroblock_modes & MACROBLOCK_INTRA) goto intra;                macroblock_modes |= UBITS (bs->i_bit_in_cache, 2) * MOTION_TYPE_BASE;                bs_flush( bs, 2 );                if (macroblock_modes & (MACROBLOCK_INTRA | MACROBLOCK_PATTERN))                {                    intra:                    macroblock_modes |= UBITS (bs->i_bit_in_cache, 1) * DCT_TYPE_INTERLACED;                    bs_flush( bs, 1 );                }                return macroblock_modes;            }        default:            return 0;    }}static inline int get_quantizer_scale( transrate_t *tr ){    bs_transrate_t *bs = &tr->bs;    int quantizer_scale_code;    quantizer_scale_code = UBITS (bs->i_bit_in_cache, 5);    bs_flush( bs, 5 );    if( tr->q_scale_type )        return non_linear_quantizer_scale[quantizer_scale_code];    else        return quantizer_scale_code << 1;}static inline int get_motion_delta( bs_transrate_t *bs, const int f_code ){    int delta;    int sign;    const MVtab * tab;    if (bs->i_bit_in_cache & 0x80000000)    {        bs_copy( bs, 1 );        return 0;    }    else if (bs->i_bit_in_cache >= 0x0c000000)    {        tab = MV_4 + UBITS (bs->i_bit_in_cache, 4);        delta = (tab->delta << f_code) + 1;        bs_copy( bs, tab->len);        sign = SBITS (bs->i_bit_in_cache, 1);        bs_copy( bs, 1 );        if (f_code)        {            delta += UBITS (bs->i_bit_in_cache, f_code);            bs_copy( bs, f_code);        }        return (delta ^ sign) - sign;    }    else    {        tab = MV_10 + UBITS (bs->i_bit_in_cache, 10);        delta = (tab->delta << f_code) + 1;        bs_copy( bs, tab->len);        sign = SBITS (bs->i_bit_in_cache, 1);        bs_copy( bs, 1);        if (f_code)        {            delta += UBITS (bs->i_bit_in_cache, f_code);            bs_copy( bs, f_code);        }        return (delta ^ sign) - sign;    }}static inline int get_dmv( bs_transrate_t *bs ){    const DMVtab * tab;    tab = DMV_2 + UBITS (bs->i_bit_in_cache, 2);    bs_copy( bs, tab->len);    return tab->dmv;}static inline int get_coded_block_pattern( bs_transrate_t *bs ){    const CBPtab * tab;    if (bs->i_bit_in_cache >= 0x20000000)    {        tab = CBP_7 + (UBITS (bs->i_bit_in_cache, 7) - 16);        bs_flush( bs, tab->len );        return tab->cbp;    }    else    {        tab = CBP_9 + UBITS (bs->i_bit_in_cache, 9);        bs_flush( bs, tab->len );        return tab->cbp;    }}static inline int get_luma_dc_dct_diff( bs_transrate_t *bs, uint32_t *bits, uint8_t *len ){    const DCtab * tab;    int size;    int dc_diff;    if (bs->i_bit_in_cache < 0xf8000000)    {        tab = DC_lum_5 + UBITS (bs->i_bit_in_cache, 5);        size = tab->size;        if (size)        {            *bits = bs_read( bs, tab->len );            *len = tab->len;            //dc_diff = UBITS (bs->i_bit_in_cache, size) - UBITS (SBITS (~bs->i_bit_in_cache, 1), size);            dc_diff = UBITS (bs->i_bit_in_cache, size);            if (!(dc_diff >> (size - 1))) dc_diff = (dc_diff + 1) - (1 << size);            *bits <<= size;            *bits |= bs_read( bs, size );            *len += size;            return dc_diff;        }        else        {            *bits = bs_read( bs, 3 );            *len = 3;            return 0;        }    }    else    {        tab = DC_long + (UBITS (bs->i_bit_in_cache, 9) - 0x1e0);        size = tab->size;        *bits = bs_read( bs, tab->len );        *len = tab->len;        //dc_diff = UBITS (bs->i_bit_in_cache, size) - UBITS (SBITS (~bs->i_bit_in_cache, 1), size);        dc_diff = UBITS (bs->i_bit_in_cache, size);        if (!(dc_diff >> (size - 1))) dc_diff = (dc_diff + 1) - (1 << size);        *bits <<= size;        *bits |= bs_read( bs, size );        *len += size;        return dc_diff;    }}static inline int get_chroma_dc_dct_diff( bs_transrate_t *bs, uint32_t *bits, uint8_t *len ){    const DCtab * tab;    int size;    int dc_diff;    if (bs->i_bit_in_cache < 0xf8000000)    {        tab = DC_chrom_5 + UBITS (bs->i_bit_in_cache, 5);        size = tab->size;        if (size)        {            *bits = bs_read( bs, tab->len );            *len = tab->len;            //dc_diff = UBITS (bs->i_bit_in_cache, size) - UBITS (SBITS (~bs->i_bit_in_cache, 1), size);            dc_diff = UBITS (bs->i_bit_in_cache, size);            if (!(dc_diff >> (size - 1))) dc_diff = (dc_diff + 1) - (1 << size);            *bits <<= size;            *bits |= bs_read( bs, size );            *len += size;            return dc_diff;        }        else        {            *bits = bs_read( bs, 2 );            *len = 2;            return 0;        }    }    else    {        tab = DC_long + (UBITS (bs->i_bit_in_cache, 10) - 0x3e0);        size = tab->size;        *bits = bs_read( bs, tab->len + 1 );        *len = tab->len + 1;        //dc_diff = UBITS (bs->i_bit_in_cache, size) - UBITS (SBITS (~bs->i_bit_in_cache, 1), size);        dc_diff = UBITS (bs->i_bit_in_cache, size);        if (!(dc_diff >> (size - 1))) dc_diff = (dc_diff + 1) - (1 << size);        *bits <<= size;        *bits |= bs_read( bs, size );        *len += size;        return dc_diff;    }}static void motion_fr_frame( bs_transrate_t *bs, unsigned int f_code[2] ){    get_motion_delta( bs, f_code[0] );    get_motion_delta( bs, f_code[1] );}static void motion_fr_field( bs_transrate_t *bs, unsigned int f_code[2] ){    bs_copy( bs, 1);    get_motion_delta( bs, f_code[0]);    get_motion_delta( bs, f_code[1]);    bs_copy( bs, 1);    get_motion_delta( bs, f_code[0]);    get_motion_delta( bs, f_code[1]);}static void motion_fr_dmv( bs_transrate_t *bs, unsigned int f_code[2] ){    get_motion_delta( bs, f_code[0]);    get_dmv( bs );    get_motion_delta( bs, f_code[1]);    get_dmv( bs );}static void motion_fi_field( bs_transrate_t *bs, unsigned int f_code[2] ){    bs_copy( bs, 1);    get_motion_delta( bs, f_code[0]);    get_motion_delta( bs, f_code[1]);}static void motion_fi_16x8( bs_transrate_t *bs, unsigned int f_code[2] ){    bs_copy( bs, 1);    get_motion_delta( bs, f_code[0]);    get_motion_delta( bs, f_code[1]);    bs_copy( bs, 1);    get_motion_delta( bs, f_code[0]);    get_motion_delta( bs, f_code[1]);}static void motion_fi_dmv( bs_transrate_t *bs, unsigned int f_code[2] ){    get_motion_delta( bs, f_code[0]);    get_dmv( bs );    get_motion_delta( bs, f_code[1]);    get_dmv( bs );}#define MOTION_CALL(routine,direction)                      \do {                                                        \    if ((direction) & MACROBLOCK_MOTION_FORWARD)            \        routine( bs, tr->f_code[0]);                        \    if ((direction) & MACROBLOCK_MOTION_BACKWARD)           \        routine( bs, tr->f_code[1]);                        \} while (0)#define NEXT_MACROBLOCK                                         \do {                                                            \    tr->h_offset += 16;                                         \    if( tr->h_offset == tr->horizontal_size_value)              \    {                                                           \        tr->v_offset += 16;                                         \        if (tr->v_offset > (tr->vertical_size_value - 16)) return;      \        tr->h_offset = 0;                                       \    }                                                           \} while (0)static void putmbdata( transrate_t *tr, int macroblock_modes ){    bs_transrate_t *bs = &tr->bs;    bs_write( bs,              mbtypetab[tr->picture_coding_type-1][macroblock_modes&0x1F].code,              mbtypetab[tr->picture_coding_type-1][macroblock_modes&0x1F].len);    switch ( tr->picture_coding_type )    {        case I_TYPE:            if ((! (tr->frame_pred_frame_dct)) && (tr->picture_structure == FRAME_PICTURE))                bs_write( bs, macroblock_modes & DCT_TYPE_INTERLACED ? 1 : 0, 1);            break;        case P_TYPE:            if (tr->picture_structure != FRAME_PICTURE)            {

⌨️ 快捷键说明

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