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

📄 msmpeg4.c

📁 Trolltech公司发布的图形界面操作系统。可在qt-embedded-2.3.10平台上编译为嵌入式图形界面操作系统。
💻 C
📖 第 1 页 / 共 5 页
字号:
/* * MSMPEG4 backend for ffmpeg encoder and decoder * Copyright (c) 2001 Fabrice Bellard. * * This library 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 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 * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA * * msmpeg4v1 & v2 stuff by Michael Niedermayer <michaelni@gmx.at> *//** * @file msmpeg4.c * MSMPEG4 backend for ffmpeg encoder and decoder. */#include "avcodec.h"#include "dsputil.h"#include "mpegvideo.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 INTER_INTRA_VLC_BITS 3#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 MB_NON_INTRA_VLC_BITS 9#define MB_INTRA_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 inline void msmpeg4_encode_block(MpegEncContext * s, DCTELEM * block, int n);static inline int msmpeg4_decode_block(MpegEncContext * s, DCTELEM * block,                                       int n, int coded, const uint8_t *scantable);static int msmpeg4_decode_dc(MpegEncContext * s, int n, int *dir_ptr);static int msmpeg4_decode_motion(MpegEncContext * s,                                  int *mx_ptr, int *my_ptr);static void msmpeg4v2_encode_motion(MpegEncContext * s, int val);static void init_h263_dc_for_msmpeg4(void);static inline void msmpeg4_memsetw(short *tab, int val, int n);#ifdef CONFIG_ENCODERSstatic 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]);static int wmv2_decode_mb(MpegEncContext *s, DCTELEM block[6][64]);#ifdef DEBUGint intra_count = 0;int frame_count = 0;#endif#include "msmpeg4data.h"#ifdef CONFIG_ENCODERS //strangely gcc includes this even if its not referencesstatic uint8_t rl_length[NB_RL_TABLES][MAX_LEVEL+1][MAX_RUN+1][2];#endif //CONFIG_ENCODERS#ifdef STATSconst char *st_names[ST_NB] = {    "unknown",    "dc",    "intra_ac",    "inter_ac",    "intra_mb",    "inter_mb",    "mv",};int st_current_index = 0;unsigned int st_bit_counts[ST_NB];unsigned int st_out_bit_counts[ST_NB];#define set_stat(var) st_current_index = var;void print_stats(void){    unsigned int total;    int i;    printf("Input:\n");    total = 0;    for(i=0;i<ST_NB;i++)        total += st_bit_counts[i];    if (total == 0)        total = 1;    for(i=0;i<ST_NB;i++) {        printf("%-10s : %10.1f %5.1f%%\n",                st_names[i],                (double)st_bit_counts[i] / 8.0,                (double)st_bit_counts[i] * 100.0 / total);    }    printf("%-10s : %10.1f %5.1f%%\n",           "total",            (double)total / 8.0,            100.0);    printf("Output:\n");    total = 0;    for(i=0;i<ST_NB;i++)        total += st_out_bit_counts[i];    if (total == 0)        total = 1;    for(i=0;i<ST_NB;i++) {        printf("%-10s : %10.1f %5.1f%%\n",                st_names[i],                (double)st_out_bit_counts[i] / 8.0,                (double)st_out_bit_counts[i] * 100.0 / total);    }    printf("%-10s : %10.1f %5.1f%%\n",           "total",            (double)total / 8.0,            100.0);}#else#define set_stat(var)#endifstatic 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(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;    }}static void 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]);        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;}static void 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){    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){                code012(&s->pb, s->rl_chroma_table_index);                code012(&s->pb, s->rl_table_index);            }            put_bits(&s->pb, 1, s->dc_table_index);        }

⌨️ 快捷键说明

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