📄 frame.c
字号:
/***************************************************************************** * 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 + -