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

📄 fame_syntax_mpeg4.c

📁 一个很好用的MPEG1/4的开源编码器
💻 C
📖 第 1 页 / 共 5 页
字号:
/*    libfame - Fast Assembly MPEG Encoder Library    Copyright (C) 2000-2001 Vivien Chappelier                            Thomas Cougnard    This library is free software; you can redistribute it and/or    modify it under the terms of the GNU Library General Public    License as published by the Free Software Foundation; either    version 2 of the License, or (at your option) any later version.    This library 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    Library General Public License for more details.    You should have received a copy of the GNU Library General Public    License along with this library; if not, write to the Free    Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.*/#include <stdio.h>#include <stdlib.h>#include <string.h>#include "fame.h"#include "fame_malloc.h"#include "fame_syntax.h"#include "fame_bitbuffer.h"#include "fame_syntax_mpeg4.h"#include "table_zigzag_mpeg4.h"#include "table_rlehuff_mpeg4.h"#include "table_dc_mpeg4.h"#include "table_cae.h"#include "table_quant_mpeg4.h"#include "table_cbp_mpeg4.h"#include "table_mv.h"#include "table_clip_mpeg4.h"#if defined(HAS_MMX)#include "ac_mmx.h"#else#include "ac_int.h"#endif#define OPENDIVX_COMPATIBILITY /* needed to output OpenDivX readable output *//* prediction direction */#define LEFT_PREDICTED 0#define TOP_PREDICTED 1/* maximum size of arithmetic coded sequence */#define CAE_SEQUENCE_LENGTH 4096#define CAE_MAX_HEADING   3#define CAE_MAX_MIDDLE   10#define CAE_MAX_TRAILING  2#define CAE_1_2 0x80000000#define CAE_1_4 0x40000000/* The header codes */#define MPEG4_SEQUENCE_START_CODE          0x1b0#define MPEG4_SEQUENCE_END_CODE            0x1b1#define MPEG4_VISUAL_OBJ_START_CODE        0x1b5#define MPEG4_VIDEO_OBJ_START_CODE         0x100#define MPEG4_VIDEO_OBJ_LAYER_START_CODE   0x120#define MPEG4_GVOP_START_CODE              0x1b3#define MPEG4_VOP_START_CODE               0x1b6#define MPEG4_SLICE_BASE_CODE     0x100/* Visual Object Type */#define MPEG4_Visual_Object_Type_VideoID 0x01#define MPEG4_Visual_Object_Type_still_textureID 0x02#define MPEG4_Visual_Object_Type_meshID 0x03#define MPEG4_Visual_Object_Type_FBA_ID 0x04#define MPEG4_Visual_Object_Type_3D_meshID 0x05/* Video Object type */#define MPEG4_Video_Object_Type_SimpleObject 0x01/* ... */#define MPEG4_Video_Object_Type_FineGranularityScalable 0x12/* Aspect Ratio Info */#define MPEG4_Aspect_Ratio_Info_Square      0x01#define MPEG4_Aspect_Ratio_Info_ExtendedPAR 0x0A/* Video Object layer Shape */#define MPEG4_Video_Object_Layer_Shape_Rectangular 0x00#define MPEG4_Video_Object_Layer_Shape_Binary 0x01#define MPEG4_Video_Object_Layer_Shape_BinaryOnly 0x02#define MPEG4_Video_Object_Layer_Shape_Grayscale 0x03/* VOP Coding Type */#define MPEG4_I_FRAME 0#define MPEG4_P_FRAME 1#define MPEG4_B_FRAME 2/* The fixed values */#define MPEG4_PROFILE_AND_LEVEL	    0x01#define MPEG4_IS_VISUAL_OBJ_IDENT   0x00#define MPEG4_VISUAL_OBJ_TYPE       0x01#define MPEG4_VIDEO_SIGNAL_TYPE     0x00#define MPEG4_IS_OBJ_LAYER_IDENT    0x00#define MPEG4_VOL_SHAPE_RECTANGULAR 0x00#define MPEG4_VOL_SHAPE_BINARY_ONLY 0x02#define MPEG4_VOP_TIME_INCR_RES     0x000F /* ?? */static void mpeg4_init(fame_syntax_t *syntax,		       int mb_width,		       int mb_height, 		       unsigned char **intra_default_matrix,		       unsigned char **inter_default_matrix,		       unsigned char *intra_dc_y_scale_table,		       unsigned char *intra_dc_c_scale_table,		       fame_mismatch_t *mismatch_type,		       unsigned int flags);static void mpeg4_close(fame_syntax_t *syntax);static void mpeg4_use(fame_syntax_t *syntax,		      unsigned char *buffer,		      int size);static int  mpeg4_flush(fame_syntax_t *syntax);static void mpeg4_start_sequence(fame_syntax_t *syntax,				 int width,				 int height,				 int fps_num,				 int fps_den,				 int size,				 int bitrate);static void mpeg4_start_GOP(fame_syntax_t *syntax,			    int frame);static void mpeg4_start_picture(fame_syntax_t *syntax,				char frame_type,				int frame_number,				fame_box_t *box,				int rounding_control,				int search_range);static void mpeg4_start_slice(fame_syntax_t *syntax,			      int vpos,			      int length,			      unsigned char qscale);static void mpeg4_end_slice(fame_syntax_t *syntax);static void mpeg4_end_sequence(fame_syntax_t *syntax);static void mpeg4_predict_vector(fame_syntax_t *syntax,				 int mb_x,				 int mb_y,				 int k,				 fame_motion_vector_t *mv);static void mpeg4_compute_chrominance_vectors(fame_syntax_t *syntax,					      fame_motion_vector_t *vectors,					      unsigned char pattern);static int mpeg4_write_intra_mb(fame_syntax_t *syntax,                                int mb_x,                                int mb_y,                                short *blocks[6],                                unsigned char *bab,                                unsigned char *bab_map,                                fame_bab_t bab_type,                                int dquant,                                unsigned char pattern);static int mpeg4_write_inter_mb(fame_syntax_t *syntax,                                int mb_x,                                int mb_y,                                short *blocks[6],                                unsigned char *bab,                                unsigned char *bab_map,                                fame_bab_t bab_type,                                int dquant,                                unsigned char pattern,                                fame_motion_vector_t *forward,                                fame_motion_vector_t *backward,                                fame_motion_coding_t motion_coding);FAME_CONSTRUCTOR(fame_syntax_mpeg4_t){  FAME_OBJECT(this)->name = "MPEG-4 bitstream syntax";  FAME_SYNTAX(this)->init = mpeg4_init;  FAME_SYNTAX(this)->use = mpeg4_use;  FAME_SYNTAX(this)->flush = mpeg4_flush;  FAME_SYNTAX(this)->start_sequence = mpeg4_start_sequence;  FAME_SYNTAX(this)->start_GOP = mpeg4_start_GOP;  FAME_SYNTAX(this)->start_picture = mpeg4_start_picture;  FAME_SYNTAX(this)->start_slice = mpeg4_start_slice;  FAME_SYNTAX(this)->end_slice = mpeg4_end_slice;  FAME_SYNTAX(this)->end_sequence = mpeg4_end_sequence;  FAME_SYNTAX(this)->predict_vector = mpeg4_predict_vector;  FAME_SYNTAX(this)->compute_chrominance_vectors = mpeg4_compute_chrominance_vectors;  FAME_SYNTAX(this)->write_intra_mb = mpeg4_write_intra_mb;  FAME_SYNTAX(this)->write_inter_mb = mpeg4_write_inter_mb;  FAME_SYNTAX(this)->close = mpeg4_close;  return(this);}static const int bab_type_intra_context_weight[4] = {  1, 3, 9, 27};static const int bab_type_intra_vl[81][3] = {  { 1, 3, 2 },  { 3, 2, 1 },  { 2, 3, 1 },  { 1, 3, 2 },  { 1, 2, 3 },  { 1, 2, 3 },  { 1, 3, 2 },  { 1, 2, 3 },  { 2, 3, 1 },  { 3, 2, 1 },  { 1, 2, 3 },  { 1, 2, 3 },  { 3, 2, 1 },  { 1, 2, 3 },  { 2, 1, 3 },  { 3, 2, 1 },  { 1, 2, 3 },  { 1, 2, 3 },  { 2, 3, 1 },  { 1, 2, 3 },  { 3, 2, 1 },  { 2, 3, 1 },  { 1, 2, 3 },  { 3, 2, 1 },  { 2, 3, 1 },  { 3, 2, 1 },  { 3, 2, 1 },  { 1, 2, 3 },  { 1, 2, 3 },  { 1, 2, 3 },  { 1, 2, 3 },  { 1, 2, 3 },  { 1, 2, 3 },  { 1, 2, 3 },  { 1, 2, 3 },  { 3, 2, 1 },  { 1, 2, 3 },  { 3, 2, 1 },  { 3, 2, 1 },  { 1, 2, 3 },  { 3, 1, 2 },  { 3, 2, 1 },  { 1, 2, 3 },  { 3, 1, 2 },  { 3, 2, 1 },  { 1, 2, 3 },  { 3, 2, 1 },  { 2, 3, 1 },  { 1, 2, 3 },  { 3, 2, 1 },  { 2, 3, 1 },  { 1, 3, 2 },  { 3, 1, 2 },  { 2, 3, 1 },  { 1, 3, 2 },  { 2, 3, 1 },  { 2, 3, 1 },  { 1, 2, 3 },  { 1, 2, 3 },  { 1, 2, 3 },  { 1, 2, 3 },  { 1, 2, 3 },  { 2, 3, 1 },  { 1, 2, 3 },  { 3, 2, 1 },  { 3, 2, 1 },  { 2, 3, 1 },  { 3, 1, 2 },  { 3, 1, 2 },  { 2, 3, 1 },  { 3, 1, 2 },  { 3, 2, 1 },  { 1, 3, 2 },  { 3, 2, 1 },  { 2, 3, 1 },  { 2, 3, 1 },  { 3, 1, 2 },  { 3, 2, 1 },  { 1, 3, 2 },  { 3, 1, 2 },  { 3, 2, 1 }};static int inline get_min_bit(unsigned int n){  unsigned int i=0;  while (n) {    i++;    n>>=1;  }  return i;}static void inline mpeg4_init_vlc_tables(fame_vlc_t *intra, fame_vlc_t *inter){  int z, l;  int level, run, last, t;    for(t = 0; t < 2; t++) {    fame_vlc_t *vlc;    /* level = [-255;255], run = [0;64], last = [0;1] */    if(t == 0)	vlc = intra;    else	vlc = inter;    for(last = 0; last < 2; last++) {      char *max_level, *max_run;      fame_vlc_t **table;      if(t == 0) {	if(last == 0) {	  max_level = rlehuff_intra_max_level;	  max_run = rlehuff_intra_max_run;	  table = rlehuff_intra_notlast_vlc;	} else {	  max_level = rlehuff_intra_max_level_last;	  max_run = rlehuff_intra_max_run_last;	  table = rlehuff_intra_last_vlc;	}      } else {	if(last == 0) {	  max_level = rlehuff_inter_max_level;	  max_run = rlehuff_inter_max_run;	  table = rlehuff_inter_notlast_vlc;	} else {	  max_level = rlehuff_inter_max_level_last;	  max_run = rlehuff_inter_max_run_last;	  table = rlehuff_inter_last_vlc;	}      }      for(l = -255; l < 256; l++) {	for(z = 0; z < 64; z++) {	  	  level = l;	  run = z;	  	  if(abs(level) <= max_level[run] && run <= max_run[abs(level)]) {	    /* vlc */	    vlc->code = table[run][level].code;	    vlc->length = table[run][level].length;	  } else {	    /* reduce level */	    if(level > 0) level -= max_level[run];	    else level += max_level[run];	    	    if(abs(level) <=  max_level[run] && run <= max_run[abs(level)]) {	      /* escape + 1 + vlc */	      vlc->code = (0x06 << table[run][level].length) |		                   table[run][level].code;	      vlc->length = table[run][level].length + 8;	    } else {	      /* restore level */	      if(level > 0) level += max_level[run];	      else level -= max_level[run];	      	      /* reduce run */	      run -=  max_run[abs(level)] + 1;	    	      if(abs(level) <=  max_level[run] && run <= max_run[abs(level)]) {		/* escape + 01 + vlc */		vlc->code = (0x0e << table[run][level].length) |		                     table[run][level].code;		vlc->length = table[run][level].length + 9;	      } else {		/* restore run */		run +=  max_run[abs(level)] + 1;		/* escape + 00 + last + run + level */		vlc->code = (unsigned long) ((0x1e + last) << 20) |		  (z << 14) | (1 << 13) | ((l & 0xfff) << 1) | 1;		vlc->length = 30;	      }	    }	  }	  vlc++;	}      }    }  }}static void inline mpeg4_init_symbol(int *symbol){  int i;    for(i = 0; i < 2048; i++) {    if(i & 1) {      if(cae_intra_prob[i >> 1] > 32768)	symbol[i] = 65536 - cae_intra_prob[i >> 1];   /* > 0 : LPS */      else	symbol[i] = -cae_intra_prob[i >> 1];          /* < 0 : MPS */    } else {      if(cae_intra_prob[i >> 1] > 32768)	symbol[i] = -(65536 - cae_intra_prob[i >> 1]); /* < 0 : MPS */      else	symbol[i] = cae_intra_prob[i >> 1];            /* > 0 : LPS */    }  }}static void inline mpeg4_next_start_code(fame_bitbuffer_t *buffer){  bitbuffer_write(buffer, 0, 1);  if(bitbuffer_padding(buffer) != 0)    bitbuffer_write(buffer, ((1 << bitbuffer_padding(buffer)) - 1), bitbuffer_padding(buffer));}/* The default intra quantisation table */static void mpeg4_init(fame_syntax_t *syntax,		       int mb_width,		       int mb_height,		       unsigned char **intra_matrix,		       unsigned char **inter_matrix,		       unsigned char *intra_dc_y_scale_table,		       unsigned char *intra_dc_c_scale_table,		       fame_mismatch_t *mismatch_type,		       unsigned int flags){  fame_syntax_mpeg4_t *syntax_mpeg4 = FAME_SYNTAX_MPEG4(syntax);  int i;

⌨️ 快捷键说明

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