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

📄 fame_encoder_mpeg.c

📁 一个很好用的MPEG1/4的开源编码器
💻 C
📖 第 1 页 / 共 2 页
字号:
/*    libfame - Fast Assembly MPEG Encoder Library    Copyright (C) 2000-2001 Vivien Chappelier    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.*//**************************** mpeg encoder ***********************************/#include <stdio.h>#include <stdlib.h>#include <string.h>#include <math.h>#include "fame.h"#include "fame_encoder.h"#include "fame_encoder_mpeg.h"#include "table_scale.h"#if defined(HAS_MMX)#define arch_enter_state()#define arch_leave_state() asm("emms")#include "transpose_mmx.h"#include "dct_mmx.h"#include "quantize_mmx.h"#include "fetch_mmx.h"#else#define arch_enter_state() #define arch_leave_state() #include "dct_float.h"#include "quantize_float.h"#include "fetch_float.h"#endif#if __GNUC__ < 2 || (__GNUC__ == 2 && __GNUC_MINOR__ <= 95 && __GNUC_PATCHLEVEL__ <= 3)/* gcc bug?? workaround */extern void __fame_dummy_call(int q);#endifstatic void mpeg_init(fame_encoder_t *encoder,		      int width,		      int height,		      unsigned char *intra_quantisation_table,		      unsigned char *inter_quantisation_table,		      unsigned char *intra_dc_y_scale_table,		      unsigned char *intra_dc_c_scale_table,		      fame_mismatch_t mismatch_type);static void mpeg_enter(fame_encoder_t *encoder,			fame_yuv_t **past_ref,			fame_yuv_t **new_ref,			fame_yuv_t **future_ref,			fame_yuv_t *yuv,			unsigned char *shape);static void mpeg_encode_intra_mb(fame_encoder_t *encoder,				 short x,				 short y,				 short *blocks[6],				 unsigned char q,				 fame_bab_t bab_type);static void mpeg_encode_inter_mb(fame_encoder_t *encoder,				 short x,				 short y,				 short *blocks[6],				 fame_motion_vector_t *forward,				 fame_motion_vector_t *backward,				 fame_motion_coding_t motion_coding,				 unsigned char q,				 fame_bab_t bab_type);static void mpeg_leave(fame_encoder_t *encoder);static void mpeg_close(fame_encoder_t *encoder);FAME_CONSTRUCTOR(fame_encoder_mpeg_t){  FAME_OBJECT(this)->name = "MPEG encoder";  FAME_ENCODER(this)->init = mpeg_init;  FAME_ENCODER(this)->enter = mpeg_enter;  FAME_ENCODER(this)->encode_intra_mb = mpeg_encode_intra_mb;  FAME_ENCODER(this)->encode_inter_mb = mpeg_encode_inter_mb;  FAME_ENCODER(this)->leave = mpeg_leave;  FAME_ENCODER(this)->close = mpeg_close;  return(this);}/*  mpeg_init                                                                *//*                                                                           *//*  Description:                                                             *//*    Initialize the encoder.                                                *//*                                                                           *//*  Arguments:                                                               *//*    fame_encoder_t *encoder: the encoder to initialize                     *//*    int width: width of the frame                                          *//*    int height: height of the frame                                        *//*    unsigned char *intra_quantisation_table: quantisation matrix for intra *//*    unsigned char *inter_quantisation_table: quantisation matrix for inter *//*    unsigned char *intra_dc_y_scale_table: quantisation table for DC of Y  *//*    unsigned char *intra_dc_c_scale_table: quantisation table for DC of C  *//*    fame_mismatch_t mismatch_type: type of mismatch control                *//*                                                                           *//*  Return value:                                                            *//*    None.                                                                  */static void mpeg_init(fame_encoder_t *encoder,		      int width,		      int height,		      unsigned char *iqtable,		      unsigned char *niqtable,		      unsigned char *intra_dc_y_scale_table,		      unsigned char *intra_dc_c_scale_table,		      fame_mismatch_t mismatch_type){  fame_encoder_mpeg_t *encoder_mpeg = FAME_ENCODER_MPEG(encoder);  int i, q;#ifdef HAS_MMX    asm("emms");#endif  /* set width and height */  encoder_mpeg->width = width;  encoder_mpeg->height = height;  /* allocate padded shape buffer */  encoder_mpeg->padded = (unsigned char *) malloc(encoder_mpeg->width*						   encoder_mpeg->height);  encoder_mpeg->mismatch = mismatch_type;  /* compute quantization matrixes */  for(q = 1; q < 32; q++) {    /* compute the intra quantisation and dequantisation DC scaler */#ifdef HAS_MMX    encoder_mpeg->yiqmatrixes[q][0] =       (dct_t) ((double)(1UL<<16)*postscale[0]/intra_dc_y_scale_table[q]);    encoder_mpeg->ciqmatrixes[q][0] =      (dct_t) ((double)(1UL<<16)*postscale[0]/intra_dc_c_scale_table[q]);    encoder_mpeg->yiqround[q][0] =       (dct_t) ((double)intra_dc_y_scale_table[q]/(2*postscale[0])+0.5);    encoder_mpeg->ciqround[q][0] =       (dct_t) ((double)intra_dc_c_scale_table[q]/(2*postscale[0])+0.5);#else    encoder_mpeg->yiqmatrixes[q][0] = postscale[0] / intra_dc_y_scale_table[q];    encoder_mpeg->ciqmatrixes[q][0] = postscale[0] / intra_dc_c_scale_table[q];    encoder_mpeg->yiqround[q][0] = ((dct_t) intra_dc_y_scale_table[q])/(2*postscale[0]);    encoder_mpeg->ciqround[q][0] = ((dct_t) intra_dc_c_scale_table[q])/(2*postscale[0]);#endif    /* compute the intra quantisation and dequantisation matrix */    for(i = 1; i < 64; i++)    {#ifdef HAS_MMX#if __GNUC__ < 2 || (__GNUC__ == 2 && __GNUC_MINOR__ <= 95 && __GNUC_PATCHLEVEL__ <= 3)//#error Your GCC is too old, and may produce bad code for libfame.      /* gcc bug here?? try to comment/uncomment the following line*/      /* or was I wrong in some earlier asm directive??! */      /* force unoptimized access to q */      __fame_dummy_call(q);#endif      encoder_mpeg->yiqmatrixes[q][i] = encoder_mpeg->ciqmatrixes[q][i] =	(dct_t) ((double)(1UL<<19)*postscale[i] / (q*iqtable[i]));      encoder_mpeg->yiqround[q][i] = encoder_mpeg->ciqround[q][i] = 	(dct_t) ((double)((1+(6*q+3)/4) * iqtable[i]) / (4 * 8.0 * postscale[i]) + 0.5);#else      encoder_mpeg->yiqmatrixes[q][i] = encoder_mpeg->ciqmatrixes[q][i] =	8.0 * postscale[i] / (q * iqtable[i]);      /* mpeg-4 rounding gives better rate-distortion results */      /* than mpeg-1 except maybe for q = 1 (need more tests) */      encoder_mpeg->yiqround[q][i] = encoder_mpeg->ciqround[q][i] = 	((dct_t) (1+(6*q+3)/4) * iqtable[i]) / (4 * 8.0 * postscale[i]);#endif    }    /* compute the inter quantisation and dequantisation matrix */    for(i = 0; i < 64; i++)    {#ifdef HAS_MMX      encoder_mpeg->niqmatrixes[q][i] =	(dct_t) ((double)(1UL<<19)*postscale[i]/(q*niqtable[i]));      encoder_mpeg->niqround[q][i] =	(dct_t) ((double)niqtable[i] / (4 * 8.0 * postscale[i]) + 0.5);#else      encoder_mpeg->niqmatrixes[q][i] =	8.0 * postscale[i] / (q * niqtable[i]);      encoder_mpeg->niqround[q][i] = 	(dct_t) niqtable[i] / (4 * 8.0 * postscale[i]);#endif    }		       }}/*  mpeg_enter                                                               *//*                                                                           *//*  Description:                                                             *//*    Start encoding a new picture.                                          *//*                                                                           *//*  Arguments:                                                               *//*    fame_encoder_t *encoder: the encoder                                   *//*    fame_yuv_t **past_ref: past reference images                           *//*    fame_yuv_t **new_ref: new reconstructed reference images               *//*    fame_yuv_t **future_ref: future reference images                       *//*    fame_yuv_t *yuv: source image                                          *//*    unsigned char *shape: shape binary mask                                *//*                                                                           *//*  Return value:                                                            *//*    None.                                                                  */  static void mpeg_enter(fame_encoder_t *encoder,			fame_yuv_t **past_ref,			fame_yuv_t **new_ref,			fame_yuv_t **future_ref,			fame_yuv_t *yuv,			unsigned char *shape){  fame_encoder_mpeg_t *encoder_mpeg = FAME_ENCODER_MPEG(encoder);  /* Make pointers on the input frame and reference frame */  encoder_mpeg->input = yuv;  encoder_mpeg->past_ref = past_ref;  encoder_mpeg->new_ref = new_ref;  encoder_mpeg->future_ref = future_ref;  encoder_mpeg->shape = shape;  arch_enter_state();}  /*  mpeg_encode_intra_mb                                                    *//*                                                                           *//*  Description:                                                             *//*    Encode an intra macroblock.                                            *//*                                                                           *//*  Arguments:                                                               *//*    fame_encoder_t *encoder: the encoder                                   *//*    bitbuffer_t *bb: a bit buffer to write the resulting encoded data to.  *//*    short x: the x location of the macroblock in macroblock units          *//*    short y: the y location of the macroblock in macroblock units          *//*    short *blocks[6]: the DCT coded blocks                                 *//*    unsigned char q: the quantizer scale for this block                    *//*    fame_bab_t bab_type: binary alpha block type                           *//*                                                                           *//*  Return value:                                                            *//*    None.                                                                  */static void mpeg_encode_intra_mb(fame_encoder_t *encoder,				 short x,				 short y,				 short *blocks[6],				 unsigned char q,				 fame_bab_t bab_type){  fame_encoder_mpeg_t *encoder_mpeg = FAME_ENCODER_MPEG(encoder);  unsigned long offset0, offset1, offset2, offset3, offset4, offset5;  int i, pitch;  void (* prefetch_Y)(unsigned char *input,		      dct_t *output,		      unsigned char *shape,		      int pitch);  void (* prefetch_C)(unsigned char *input,		      dct_t *output,		      unsigned char *shape,		      int pitch);  void (* dct_)(dct_t *block);  void (* quantize_)(short *block, dct_t *qblock, dct_t *matrix, dct_t *round);  pitch = encoder_mpeg->input->p;  /* Make offsets to blocks */  offset0 = (y << 4) * pitch + (x << 4);         /* Y(0,0) */  offset1 = offset0 + 8;                       /* Y(0,1) */  offset2 = offset0 + (pitch << 3);            /* Y(1,0) */  offset3 = offset2 + 8;                       /* Y(1,1) */  offset4 = (y << 3) * (pitch >> 1) + (x << 3);  /* Cb     */  offset5 = (y << 3) * (pitch >> 1) + (x << 3);  /* Cr     */  /* Encode blocks */  for(i = 0; i < 6; i++)    blocks[i] = encoder_mpeg->blocks[i];  if(bab_type != bab_all_coded)  {

⌨️ 快捷键说明

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