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

📄 h263.c

📁 Trolltech公司发布的图形界面操作系统。可在qt-embedded-2.3.7平台上编译为嵌入式图形界面操作系统。
💻 C
📖 第 1 页 / 共 5 页
字号:
/* * H263/MPEG4 backend for ffmpeg encoder and decoder * Copyright (c) 2000,2001 Fabrice Bellard. * H263+ support. * Copyright (c) 2001 Juan J. Sierralta P. * * 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 * * ac prediction encoding, b-frame support, error resilience, optimizations, * qpel decoding, gmc decoding, interlaced decoding,  * by Michael Niedermayer <michaelni@gmx.at> */ //#define DEBUG#include "common.h"#include "dsputil.h"#include "avcodec.h"#include "mpegvideo.h"#include "h263data.h"#include "mpeg4data.h"//#undef NDEBUG//#include <assert.h>#if 1#define PRINT_MB_TYPE(a) {}#else#define PRINT_MB_TYPE(a) printf(a)#endif#define INTRA_MCBPC_VLC_BITS 6#define INTER_MCBPC_VLC_BITS 6#define CBPY_VLC_BITS 6#define MV_VLC_BITS 9#define DC_VLC_BITS 9#define SPRITE_TRAJ_VLC_BITS 6#define MB_TYPE_B_VLC_BITS 4#define TEX_VLC_BITS 9#ifdef CONFIG_ENCODERSstatic void h263_encode_block(MpegEncContext * s, DCTELEM * block,			      int n);static void h263_encode_motion(MpegEncContext * s, int val, int fcode);static void h263p_encode_umotion(MpegEncContext * s, int val);static inline void mpeg4_encode_block(MpegEncContext * s, DCTELEM * block,			       int n, int dc, UINT8 *scan_table,                                PutBitContext *dc_pb, PutBitContext *ac_pb);#endifstatic int h263_decode_motion(MpegEncContext * s, int pred, int fcode);static int h263p_decode_umotion(MpegEncContext * s, int pred);static int h263_decode_block(MpegEncContext * s, DCTELEM * block,                             int n, int coded);static inline int mpeg4_decode_dc(MpegEncContext * s, int n, int *dir_ptr);static inline int mpeg4_decode_block(MpegEncContext * s, DCTELEM * block,                              int n, int coded, int intra);static int h263_pred_dc(MpegEncContext * s, int n, UINT16 **dc_val_ptr);static void mpeg4_inv_pred_ac(MpegEncContext * s, INT16 *block, int n,                              int dir);static void mpeg4_decode_sprite_trajectory(MpegEncContext * s);static inline int ff_mpeg4_pred_dc(MpegEncContext * s, int n, UINT16 **dc_val_ptr, int *dir_ptr);extern UINT32 inverse[256];static UINT16 uni_DCtab_lum  [512][2];static UINT16 uni_DCtab_chrom[512][2];#ifdef CONFIG_ENCODERSstatic UINT16 (*mv_penalty)[MAX_MV*2+1]= NULL;static UINT8 fcode_tab[MAX_MV*2+1];static UINT8 umv_fcode_tab[MAX_MV*2+1];static UINT32 uni_mpeg4_intra_rl_bits[64*64*2*2];static UINT8  uni_mpeg4_intra_rl_len [64*64*2*2];static UINT32 uni_mpeg4_inter_rl_bits[64*64*2*2];static UINT8  uni_mpeg4_inter_rl_len [64*64*2*2];#define UNI_MPEG4_ENC_INDEX(last,run,level) ((last)*128 + (run)*256 + (level))//#define UNI_MPEG4_ENC_INDEX(last,run,level) ((last)*128*64 + (run) + (level)*64)/* mpeg4intermax level: 24/6max run: 53/63intramax level: 53/16max run: 29/41*/#endifint h263_get_picture_format(int width, int height){    int format;    if (width == 128 && height == 96)        format = 1;    else if (width == 176 && height == 144)        format = 2;    else if (width == 352 && height == 288)        format = 3;    else if (width == 704 && height == 576)        format = 4;    else if (width == 1408 && height == 1152)        format = 5;    else        format = 7;    return format;}static void init_aspect_info(MpegEncContext * s){    double aspect;        emms_c(); //paranoia ;)        if(s->avctx->aspect_ratio==0) aspect= 1.0;    aspect= s->avctx->aspect_ratio;        ff_float2fraction(&s->aspected_width, &s->aspected_height, aspect, 255);        if(s->aspected_width == 4 && s->aspected_height == 3)        s->aspect_ratio_info= FF_ASPECT_4_3_625;    else if(s->aspected_width == 16 && s->aspected_height == 9)        s->aspect_ratio_info= FF_ASPECT_16_9_625;    else if(s->aspected_width == 1 && s->aspected_height == 1)        s->aspect_ratio_info= FF_ASPECT_SQUARE;    else        s->aspect_ratio_info= FF_ASPECT_EXTENDED;}void h263_encode_picture_header(MpegEncContext * s, int picture_number){    int format;    align_put_bits(&s->pb);    /* Update the pointer to last GOB */    s->ptr_lastgob = pbBufPtr(&s->pb);    s->gob_number = 0;    put_bits(&s->pb, 22, 0x20); /* PSC */    put_bits(&s->pb, 8, (((INT64)s->picture_number * 30 * FRAME_RATE_BASE) /                          s->frame_rate) & 0xff);    put_bits(&s->pb, 1, 1);	/* marker */    put_bits(&s->pb, 1, 0);	/* h263 id */    put_bits(&s->pb, 1, 0);	/* split screen off */    put_bits(&s->pb, 1, 0);	/* camera  off */    put_bits(&s->pb, 1, 0);	/* freeze picture release off */        format = h263_get_picture_format(s->width, s->height);    if (!s->h263_plus) {        /* H.263v1 */        put_bits(&s->pb, 3, format);        put_bits(&s->pb, 1, (s->pict_type == P_TYPE));        /* By now UMV IS DISABLED ON H.263v1, since the restrictions        of H.263v1 UMV implies to check the predicted MV after        calculation of the current MB to see if we're on the limits */        put_bits(&s->pb, 1, 0);	/* unrestricted motion vector: off */        put_bits(&s->pb, 1, 0);	/* SAC: off */        put_bits(&s->pb, 1, 0);	/* advanced prediction mode: off */        put_bits(&s->pb, 1, 0);	/* not PB frame */        put_bits(&s->pb, 5, s->qscale);        put_bits(&s->pb, 1, 0);	/* Continuous Presence Multipoint mode: off */    } else {        /* H.263v2 */        /* H.263 Plus PTYPE */        put_bits(&s->pb, 3, 7);        put_bits(&s->pb,3,1); /* Update Full Extended PTYPE */        if (format == 7)            put_bits(&s->pb,3,6); /* Custom Source Format */        else            put_bits(&s->pb, 3, format);                    put_bits(&s->pb,1,0); /* Custom PCF: off */        s->umvplus = (s->pict_type == P_TYPE) && s->unrestricted_mv;        put_bits(&s->pb, 1, s->umvplus); /* Unrestricted Motion Vector */        put_bits(&s->pb,1,0); /* SAC: off */        put_bits(&s->pb,1,0); /* Advanced Prediction Mode: off */        put_bits(&s->pb,1,s->h263_aic); /* Advanced Intra Coding */        put_bits(&s->pb,1,0); /* Deblocking Filter: off */        put_bits(&s->pb,1,0); /* Slice Structured: off */        put_bits(&s->pb,1,0); /* Reference Picture Selection: off */        put_bits(&s->pb,1,0); /* Independent Segment Decoding: off */        put_bits(&s->pb,1,0); /* Alternative Inter VLC: off */        put_bits(&s->pb,1,0); /* Modified Quantization: off */        put_bits(&s->pb,1,1); /* "1" to prevent start code emulation */        put_bits(&s->pb,3,0); /* Reserved */		        put_bits(&s->pb, 3, s->pict_type == P_TYPE);		        put_bits(&s->pb,1,0); /* Reference Picture Resampling: off */        put_bits(&s->pb,1,0); /* Reduced-Resolution Update: off */        if (s->pict_type == I_TYPE)            s->no_rounding = 0;        else            s->no_rounding ^= 1;        put_bits(&s->pb,1,s->no_rounding); /* Rounding Type */        put_bits(&s->pb,2,0); /* Reserved */        put_bits(&s->pb,1,1); /* "1" to prevent start code emulation */		        /* This should be here if PLUSPTYPE */        put_bits(&s->pb, 1, 0);	/* Continuous Presence Multipoint mode: off */				if (format == 7) {            /* Custom Picture Format (CPFMT) */            init_aspect_info(s);            put_bits(&s->pb,4,s->aspect_ratio_info);            put_bits(&s->pb,9,(s->width >> 2) - 1);            put_bits(&s->pb,1,1); /* "1" to prevent start code emulation */            put_bits(&s->pb,9,(s->height >> 2));	    if (s->aspect_ratio_info == FF_ASPECT_EXTENDED)	    {		put_bits(&s->pb, 8, s->aspected_width);		put_bits(&s->pb, 8, s->aspected_height);	    }        }                /* Unlimited Unrestricted Motion Vectors Indicator (UUI) */        if (s->umvplus)            put_bits(&s->pb,1,1); /* Limited according tables of Annex D */        put_bits(&s->pb, 5, s->qscale);    }    put_bits(&s->pb, 1, 0);	/* no PEI */    if(s->h263_aic){         s->y_dc_scale_table=          s->c_dc_scale_table= h263_aic_dc_scale_table;    }else{        s->y_dc_scale_table=        s->c_dc_scale_table= ff_mpeg1_dc_scale_table;    }}/** * Encodes a group of blocks header. */int h263_encode_gob_header(MpegEncContext * s, int mb_line){           align_put_bits(&s->pb);           flush_put_bits(&s->pb);           /* Call the RTP callback to send the last GOB */           if (s->rtp_callback) {               int pdif = pbBufPtr(&s->pb) - s->ptr_lastgob;               s->rtp_callback(s->ptr_lastgob, pdif, s->gob_number);           }           put_bits(&s->pb, 17, 1); /* GBSC */           s->gob_number = mb_line / s->gob_index;           put_bits(&s->pb, 5, s->gob_number); /* GN */           put_bits(&s->pb, 2, s->pict_type == I_TYPE); /* GFID */           put_bits(&s->pb, 5, s->qscale); /* GQUANT */           //fprintf(stderr,"\nGOB: %2d size: %d", s->gob_number - 1, pdif);    return 0;}static inline int decide_ac_pred(MpegEncContext * s, DCTELEM block[6][64], int dir[6]){    int score0=0, score1=0;    int i, n;    for(n=0; n<6; n++){        INT16 *ac_val, *ac_val1;        ac_val = s->ac_val[0][0] + s->block_index[n] * 16;        ac_val1= ac_val;        if(dir[n]){            const int xy= s->mb_x + s->mb_y*s->mb_width - s->mb_width;            /* top prediction */            ac_val-= s->block_wrap[n]*16;            if(s->mb_y==0 || s->qscale == s->qscale_table[xy] || n==2 || n==3){                /* same qscale */                for(i=1; i<8; i++){                    const int level= block[n][s->idct_permutation[i   ]];                    score0+= ABS(level);                    score1+= ABS(level - ac_val[i+8]);                    ac_val1[i  ]=    block[n][s->idct_permutation[i<<3]];                    ac_val1[i+8]= level;                }            }else{                /* different qscale, we must rescale */                for(i=1; i<8; i++){                    const int level= block[n][s->idct_permutation[i   ]];                    score0+= ABS(level);                    score1+= ABS(level - ROUNDED_DIV(ac_val[i + 8]*s->qscale_table[xy], s->qscale));                    ac_val1[i  ]=    block[n][s->idct_permutation[i<<3]];                    ac_val1[i+8]= level;                }            }        }else{            const int xy= s->mb_x-1 + s->mb_y*s->mb_width;            /* left prediction */            ac_val-= 16;            if(s->mb_x==0 || s->qscale == s->qscale_table[xy] || n==1 || n==3){                /* same qscale */                for(i=1; i<8; i++){                    const int level= block[n][s->idct_permutation[i<<3]];                    score0+= ABS(level);                    score1+= ABS(level - ac_val[i]);                    ac_val1[i  ]= level;                    ac_val1[i+8]=    block[n][s->idct_permutation[i   ]];                }            }else{                /* different qscale, we must rescale */                for(i=1; i<8; i++){                    const int level= block[n][s->idct_permutation[i<<3]];                    score0+= ABS(level);                    score1+= ABS(level - ROUNDED_DIV(ac_val[i]*s->qscale_table[xy], s->qscale));                    ac_val1[i  ]= level;                    ac_val1[i+8]=    block[n][s->idct_permutation[i   ]];                }            }        }    }    return score0 > score1 ? 1 : 0;    }/** * modify qscale so that encoding is acually possible in h263 (limit difference to -2..2) */void ff_clean_h263_qscales(MpegEncContext *s){    int i;        for(i=1; i<s->mb_num; i++){        if(s->qscale_table[i] - s->qscale_table[i-1] >2)            s->qscale_table[i]= s->qscale_table[i-1]+2;    }    for(i=s->mb_num-2; i>=0; i--){        if(s->qscale_table[i] - s->qscale_table[i+1] >2)            s->qscale_table[i]= s->qscale_table[i+1]+2;    }}/** * modify mb_type & qscale so that encoding is acually possible in mpeg4 */void ff_clean_mpeg4_qscales(MpegEncContext *s){    int i;        ff_clean_h263_qscales(s);        for(i=1; i<s->mb_num; i++){        if(s->qscale_table[i] != s->qscale_table[i-1] && (s->mb_type[i]&MB_TYPE_INTER4V)){            s->mb_type[i]&= ~MB_TYPE_INTER4V;            s->mb_type[i]|= MB_TYPE_INTER;        }    }    if(s->pict_type== B_TYPE){        int odd=0;        /* ok, come on, this isnt funny anymore, theres more code for handling this mpeg4 mess than           for the actual adaptive quantization */                for(i=0; i<s->mb_num; i++){            odd += s->qscale_table[i]&1;        }                if(2*odd > s->mb_num) odd=1;        else                  odd=0;                for(i=0; i<s->mb_num; i++){            if((s->qscale_table[i]&1) != odd)                s->qscale_table[i]++;            if(s->qscale_table[i] > 31)                s->qscale_table[i]= 31;        }                        for(i=1; i<s->mb_num; i++){            if(s->qscale_table[i] != s->qscale_table[i-1] && (s->mb_type[i]&MB_TYPE_DIRECT)){                s->mb_type[i]&= ~MB_TYPE_DIRECT;                s->mb_type[i]|= MB_TYPE_BIDIR;            }        }    }}#ifdef CONFIG_ENCODERSvoid mpeg4_encode_mb(MpegEncContext * s,		    DCTELEM block[6][64],		    int motion_x, int motion_y){    int cbpc, cbpy, i, pred_x, pred_y;    int bits;    PutBitContext * const pb2    = s->data_partitioning                         ? &s->pb2    : &s->pb;    PutBitContext * const tex_pb = s->data_partitioning && s->pict_type!=B_TYPE ? &s->tex_pb : &s->pb;    PutBitContext * const dc_pb  = s->data_partitioning && s->pict_type!=I_TYPE ? &s->pb2    : &s->pb;    const int interleaved_stats= (s->flags&CODEC_FLAG_PASS1) && !s->data_partitioning ? 1 : 0;    const int dquant_code[5]= {1,0,9,2,3};        //    printf("**mb x=%d y=%d\n", s->mb_x, s->mb_y);    if (!s->mb_intra) {        /* compute cbp */

⌨️ 快捷键说明

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