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

📄 msmpeg4.c.svn-base

📁 mediastreamer2是开源的网络传输媒体流的库
💻 SVN-BASE
📖 第 1 页 / 共 5 页
字号:
/* * MSMPEG4 backend for ffmpeg encoder and decoder * Copyright (c) 2001 Fabrice Bellard. * Copyright (c) 2002-2004 Michael Niedermayer <michaelni@gmx.at> * * msmpeg4v1 & v2 stuff by Michael Niedermayer <michaelni@gmx.at> * * This file is part of FFmpeg. * * FFmpeg is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * FFmpeg 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 * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with FFmpeg; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA *//** * @file msmpeg4.c * MSMPEG4 backend for ffmpeg encoder and decoder. */#include "avcodec.h"#include "dsputil.h"#include "mpegvideo.h"#include "msmpeg4.h"/* * You can also call this codec : MPEG4 with a twist ! * * TODO: *        - (encoding) select best mv table (two choices) *        - (encoding) select best vlc/dc table *///#define DEBUG#define DC_VLC_BITS 9#define CBPY_VLC_BITS 6#define V1_INTRA_CBPC_VLC_BITS 6#define V1_INTER_CBPC_VLC_BITS 6#define V2_INTRA_CBPC_VLC_BITS 3#define V2_MB_TYPE_VLC_BITS 7#define MV_VLC_BITS 9#define V2_MV_VLC_BITS 9#define TEX_VLC_BITS 9#define II_BITRATE 128*1024#define MBAC_BITRATE 50*1024#define DEFAULT_INTER_INDEX 3static uint32_t v2_dc_lum_table[512][2];static uint32_t v2_dc_chroma_table[512][2];static int msmpeg4_decode_dc(MpegEncContext * s, int n, int *dir_ptr);static void init_h263_dc_for_msmpeg4(void);static inline void msmpeg4_memsetw(short *tab, int val, int n);#ifdef CONFIG_ENCODERSstatic void msmpeg4v2_encode_motion(MpegEncContext * s, int val);static int get_size_of_code(MpegEncContext * s, RLTable *rl, int last, int run, int level, int intra);#endif //CONFIG_ENCODERSstatic int msmpeg4v12_decode_mb(MpegEncContext *s, DCTELEM block[6][64]);static int msmpeg4v34_decode_mb(MpegEncContext *s, DCTELEM block[6][64]);/* vc1 externs */extern const uint8_t wmv3_dc_scale_table[32];#ifdef DEBUGint intra_count = 0;int frame_count = 0;#endif#include "msmpeg4data.h"#ifdef CONFIG_ENCODERS //strangely gcc includes this even if it is not referencesstatic uint8_t rl_length[NB_RL_TABLES][MAX_LEVEL+1][MAX_RUN+1][2];#endif //CONFIG_ENCODERSstatic uint8_t static_rl_table_store[NB_RL_TABLES][2][2*MAX_RUN + MAX_LEVEL + 3];static void common_init(MpegEncContext * s){    static int inited=0;    switch(s->msmpeg4_version){    case 1:    case 2:        s->y_dc_scale_table=        s->c_dc_scale_table= ff_mpeg1_dc_scale_table;        break;    case 3:        if(s->workaround_bugs){            s->y_dc_scale_table= old_ff_y_dc_scale_table;            s->c_dc_scale_table= old_ff_c_dc_scale_table;        } else{            s->y_dc_scale_table= ff_mpeg4_y_dc_scale_table;            s->c_dc_scale_table= ff_mpeg4_c_dc_scale_table;        }        break;    case 4:    case 5:        s->y_dc_scale_table= wmv1_y_dc_scale_table;        s->c_dc_scale_table= wmv1_c_dc_scale_table;        break;#if defined(CONFIG_WMV3_DECODER)||defined(CONFIG_VC1_DECODER)    case 6:        s->y_dc_scale_table= wmv3_dc_scale_table;        s->c_dc_scale_table= wmv3_dc_scale_table;        break;#endif    }    if(s->msmpeg4_version>=4){        ff_init_scantable(s->dsp.idct_permutation, &s->intra_scantable  , wmv1_scantable[1]);        ff_init_scantable(s->dsp.idct_permutation, &s->intra_h_scantable, wmv1_scantable[2]);        ff_init_scantable(s->dsp.idct_permutation, &s->intra_v_scantable, wmv1_scantable[3]);        ff_init_scantable(s->dsp.idct_permutation, &s->inter_scantable  , wmv1_scantable[0]);    }    //Note the default tables are set in common_init in mpegvideo.c    if(!inited){        inited=1;        init_h263_dc_for_msmpeg4();    }}#ifdef CONFIG_ENCODERS/* build the table which associate a (x,y) motion vector to a vlc */static void init_mv_table(MVTable *tab){    int i, x, y;    tab->table_mv_index = av_malloc(sizeof(uint16_t) * 4096);    /* mark all entries as not used */    for(i=0;i<4096;i++)        tab->table_mv_index[i] = tab->n;    for(i=0;i<tab->n;i++) {        x = tab->table_mvx[i];        y = tab->table_mvy[i];        tab->table_mv_index[(x << 6) | y] = i;    }}void ff_msmpeg4_code012(PutBitContext *pb, int n){    if (n == 0) {        put_bits(pb, 1, 0);    } else {        put_bits(pb, 1, 1);        put_bits(pb, 1, (n >= 2));    }}void ff_msmpeg4_encode_init(MpegEncContext *s){    static int init_done=0;    int i;    common_init(s);    if(s->msmpeg4_version>=4){        s->min_qcoeff= -255;        s->max_qcoeff=  255;    }    if (!init_done) {        /* init various encoding tables */        init_done = 1;        init_mv_table(&mv_tables[0]);        init_mv_table(&mv_tables[1]);        for(i=0;i<NB_RL_TABLES;i++)            init_rl(&rl_table[i], static_rl_table_store[i]);        for(i=0; i<NB_RL_TABLES; i++){            int level;            for(level=0; level<=MAX_LEVEL; level++){                int run;                for(run=0; run<=MAX_RUN; run++){                    int last;                    for(last=0; last<2; last++){                        rl_length[i][level][run][last]= get_size_of_code(s, &rl_table[  i], last, run, level, 0);                    }                }            }        }    }}static int get_size_of_code(MpegEncContext * s, RLTable *rl, int last, int run, int level, int intra){    int size=0;    int code;    int run_diff= intra ? 0 : 1;    code = get_rl_index(rl, last, run, level);    size+= rl->table_vlc[code][1];    if (code == rl->n) {        int level1, run1;        level1 = level - rl->max_level[last][run];        if (level1 < 1)            goto esc2;        code = get_rl_index(rl, last, run, level1);        if (code == rl->n) {            esc2:            size++;            if (level > MAX_LEVEL)                goto esc3;            run1 = run - rl->max_run[last][level] - run_diff;            if (run1 < 0)                goto esc3;            code = get_rl_index(rl, last, run1, level);            if (code == rl->n) {            esc3:                /* third escape */                size+=1+1+6+8;            } else {                /* second escape */                size+= 1+1+ rl->table_vlc[code][1];            }        } else {            /* first escape */            size+= 1+1+ rl->table_vlc[code][1];        }    } else {        size++;    }    return size;}void ff_find_best_tables(MpegEncContext * s){    int i;    int best       =-1, best_size       =9999999;    int chroma_best=-1, best_chroma_size=9999999;    for(i=0; i<3; i++){        int level;        int chroma_size=0;        int size=0;        if(i>0){// ;)            size++;            chroma_size++;        }        for(level=0; level<=MAX_LEVEL; level++){            int run;            for(run=0; run<=MAX_RUN; run++){                int last;                const int last_size= size + chroma_size;                for(last=0; last<2; last++){                    int inter_count       = s->ac_stats[0][0][level][run][last] + s->ac_stats[0][1][level][run][last];                    int intra_luma_count  = s->ac_stats[1][0][level][run][last];                    int intra_chroma_count= s->ac_stats[1][1][level][run][last];                    if(s->pict_type==I_TYPE){                        size       += intra_luma_count  *rl_length[i  ][level][run][last];                        chroma_size+= intra_chroma_count*rl_length[i+3][level][run][last];                    }else{                        size+=        intra_luma_count  *rl_length[i  ][level][run][last]                                     +intra_chroma_count*rl_length[i+3][level][run][last]                                     +inter_count       *rl_length[i+3][level][run][last];                    }                }                if(last_size == size+chroma_size) break;            }        }        if(size<best_size){            best_size= size;            best= i;        }        if(chroma_size<best_chroma_size){            best_chroma_size= chroma_size;            chroma_best= i;        }    }//    printf("type:%d, best:%d, qp:%d, var:%d, mcvar:%d, size:%d //\n",//           s->pict_type, best, s->qscale, s->mb_var_sum, s->mc_mb_var_sum, best_size);    if(s->pict_type==P_TYPE) chroma_best= best;    memset(s->ac_stats, 0, sizeof(int)*(MAX_LEVEL+1)*(MAX_RUN+1)*2*2*2);    s->rl_table_index       =        best;    s->rl_chroma_table_index= chroma_best;    if(s->pict_type != s->last_non_b_pict_type){        s->rl_table_index= 2;        if(s->pict_type==I_TYPE)            s->rl_chroma_table_index= 1;        else            s->rl_chroma_table_index= 2;    }}/* write MSMPEG4 compatible frame header */void msmpeg4_encode_picture_header(MpegEncContext * s, int picture_number){    ff_find_best_tables(s);    align_put_bits(&s->pb);    put_bits(&s->pb, 2, s->pict_type - 1);    put_bits(&s->pb, 5, s->qscale);    if(s->msmpeg4_version<=2){        s->rl_table_index = 2;        s->rl_chroma_table_index = 2;    }    s->dc_table_index = 1;    s->mv_table_index = 1; /* only if P frame */    s->use_skip_mb_code = 1; /* only if P frame */    s->per_mb_rl_table = 0;    if(s->msmpeg4_version==4)        s->inter_intra_pred= (s->width*s->height < 320*240 && s->bit_rate<=II_BITRATE && s->pict_type==P_TYPE);//printf("%d %d %d %d %d\n", s->pict_type, s->bit_rate, s->inter_intra_pred, s->width, s->height);    if (s->pict_type == I_TYPE) {        s->slice_height= s->mb_height/1;        put_bits(&s->pb, 5, 0x16 + s->mb_height/s->slice_height);        if(s->msmpeg4_version==4){            msmpeg4_encode_ext_header(s);            if(s->bit_rate>MBAC_BITRATE)                put_bits(&s->pb, 1, s->per_mb_rl_table);        }        if(s->msmpeg4_version>2){            if(!s->per_mb_rl_table){                ff_msmpeg4_code012(&s->pb, s->rl_chroma_table_index);                ff_msmpeg4_code012(&s->pb, s->rl_table_index);            }            put_bits(&s->pb, 1, s->dc_table_index);        }    } else {        put_bits(&s->pb, 1, s->use_skip_mb_code);        if(s->msmpeg4_version==4 && s->bit_rate>MBAC_BITRATE)            put_bits(&s->pb, 1, s->per_mb_rl_table);        if(s->msmpeg4_version>2){            if(!s->per_mb_rl_table)                ff_msmpeg4_code012(&s->pb, s->rl_table_index);            put_bits(&s->pb, 1, s->dc_table_index);            put_bits(&s->pb, 1, s->mv_table_index);        }    }    s->esc3_level_length= 0;    s->esc3_run_length= 0;#ifdef DEBUG    intra_count = 0;    av_log(s->avctx, AV_LOG_DEBUG, "*****frame %d:\n", frame_count++);#endif}void msmpeg4_encode_ext_header(MpegEncContext * s){        put_bits(&s->pb, 5, s->avctx->time_base.den / s->avctx->time_base.num); //yes 29.97 -> 29        put_bits(&s->pb, 11, FFMIN(s->bit_rate/1024, 2047));        if(s->msmpeg4_version>=3)            put_bits(&s->pb, 1, s->flipflop_rounding);        else            assert(s->flipflop_rounding==0);}#endif //CONFIG_ENCODERS/* predict coded block */int ff_msmpeg4_coded_block_pred(MpegEncContext * s, int n, uint8_t **coded_block_ptr){

⌨️ 快捷键说明

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