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

📄 mpegvideo.c

📁 Trolltech公司发布的图形界面操作系统。可在qt-embedded-2.3.7平台上编译为嵌入式图形界面操作系统。
💻 C
📖 第 1 页 / 共 5 页
字号:
/* * The simplest mpeg encoder (well, it was the simplest!) * Copyright (c) 2000,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 * * 4MV & hq & b-frame encoding stuff by Michael Niedermayer <michaelni@gmx.at> */ #include <ctype.h>#include "avcodec.h"#include "dsputil.h"#include "mpegvideo.h"#include "simple_idct.h"#ifdef USE_FASTMEMCPY#include "fastmemcpy.h"#endif//#undef NDEBUG//#include <assert.h>static void encode_picture(MpegEncContext *s, int picture_number);static void dct_unquantize_mpeg1_c(MpegEncContext *s,                                    DCTELEM *block, int n, int qscale);static void dct_unquantize_mpeg2_c(MpegEncContext *s,                                   DCTELEM *block, int n, int qscale);static void dct_unquantize_h263_c(MpegEncContext *s,                                   DCTELEM *block, int n, int qscale);static void draw_edges_c(UINT8 *buf, int wrap, int width, int height, int w);static int dct_quantize_c(MpegEncContext *s, DCTELEM *block, int n, int qscale, int *overflow);void (*draw_edges)(UINT8 *buf, int wrap, int width, int height, int w)= draw_edges_c;static void emulated_edge_mc(MpegEncContext *s, UINT8 *src, int linesize, int block_w, int block_h,                                     int src_x, int src_y, int w, int h);#define EDGE_WIDTH 16/* enable all paranoid tests for rounding, overflows, etc... *///#define PARANOID//#define DEBUG/* for jpeg fast DCT */#define CONST_BITS 14static const uint16_t aanscales[64] = {    /* precomputed values scaled up by 14 bits */    16384, 22725, 21407, 19266, 16384, 12873,  8867,  4520,    22725, 31521, 29692, 26722, 22725, 17855, 12299,  6270,    21407, 29692, 27969, 25172, 21407, 16819, 11585,  5906,    19266, 26722, 25172, 22654, 19266, 15137, 10426,  5315,    16384, 22725, 21407, 19266, 16384, 12873,  8867,  4520,    12873, 17855, 16819, 15137, 12873, 10114,  6967,  3552,    8867, 12299, 11585, 10426,  8867,  6967,  4799,  2446,    4520,  6270,  5906,  5315,  4520,  3552,  2446,  1247};/* Input permutation for the simple_idct_mmx */static const uint8_t simple_mmx_permutation[64]={	0x00, 0x08, 0x04, 0x09, 0x01, 0x0C, 0x05, 0x0D, 	0x10, 0x18, 0x14, 0x19, 0x11, 0x1C, 0x15, 0x1D, 	0x20, 0x28, 0x24, 0x29, 0x21, 0x2C, 0x25, 0x2D, 	0x12, 0x1A, 0x16, 0x1B, 0x13, 0x1E, 0x17, 0x1F, 	0x02, 0x0A, 0x06, 0x0B, 0x03, 0x0E, 0x07, 0x0F, 	0x30, 0x38, 0x34, 0x39, 0x31, 0x3C, 0x35, 0x3D, 	0x22, 0x2A, 0x26, 0x2B, 0x23, 0x2E, 0x27, 0x2F, 	0x32, 0x3A, 0x36, 0x3B, 0x33, 0x3E, 0x37, 0x3F,};static const uint8_t h263_chroma_roundtab[16] = {    0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2,};static UINT16 (*default_mv_penalty)[MAX_MV*2+1]=NULL;static UINT8 default_fcode_tab[MAX_MV*2+1];/* default motion estimation */int motion_estimation_method = ME_EPZS;static void convert_matrix(MpegEncContext *s, int (*qmat)[64], uint16_t (*qmat16)[64], uint16_t (*qmat16_bias)[64],                           const UINT16 *quant_matrix, int bias, int qmin, int qmax){    int qscale;    for(qscale=qmin; qscale<=qmax; qscale++){        int i;        if (s->fdct == ff_jpeg_fdct_islow) {            for(i=0;i<64;i++) {                const int j= s->idct_permutation[i];                /* 16 <= qscale * quant_matrix[i] <= 7905 */                /* 19952         <= aanscales[i] * qscale * quant_matrix[i]           <= 249205026 */                /* (1<<36)/19952 >= (1<<36)/(aanscales[i] * qscale * quant_matrix[i]) >= (1<<36)/249205026 */                /* 3444240       >= (1<<36)/(aanscales[i] * qscale * quant_matrix[i]) >= 275 */                                qmat[qscale][i] = (int)((UINT64_C(1) << QMAT_SHIFT) /                                 (qscale * quant_matrix[j]));            }        } else if (s->fdct == fdct_ifast) {            for(i=0;i<64;i++) {                const int j= s->idct_permutation[i];                /* 16 <= qscale * quant_matrix[i] <= 7905 */                /* 19952         <= aanscales[i] * qscale * quant_matrix[i]           <= 249205026 */                /* (1<<36)/19952 >= (1<<36)/(aanscales[i] * qscale * quant_matrix[i]) >= (1<<36)/249205026 */                /* 3444240       >= (1<<36)/(aanscales[i] * qscale * quant_matrix[i]) >= 275 */                                qmat[qscale][i] = (int)((UINT64_C(1) << (QMAT_SHIFT + 14)) /                                 (aanscales[i] * qscale * quant_matrix[j]));            }        } else {            for(i=0;i<64;i++) {                const int j= s->idct_permutation[i];                /* We can safely suppose that 16 <= quant_matrix[i] <= 255                   So 16           <= qscale * quant_matrix[i]             <= 7905                   so (1<<19) / 16 >= (1<<19) / (qscale * quant_matrix[i]) >= (1<<19) / 7905                   so 32768        >= (1<<19) / (qscale * quant_matrix[i]) >= 67                */                qmat  [qscale][i] = (1 << QMAT_SHIFT_MMX) / (qscale * quant_matrix[i]);                qmat16[qscale][i] = (1 << QMAT_SHIFT_MMX) / (qscale * quant_matrix[j]);                if(qmat16[qscale][i]==0 || qmat16[qscale][i]==128*256) qmat16[qscale][i]=128*256-1;                qmat16_bias[qscale][i]= ROUNDED_DIV(bias<<(16-QUANT_BIAS_SHIFT), qmat16[qscale][i]);            }        }    }}// move into common.c perhaps #define CHECKED_ALLOCZ(p, size)\{\    p= av_mallocz(size);\    if(p==NULL){\        perror("malloc");\        goto fail;\    }\}void ff_init_scantable(MpegEncContext *s, ScanTable *st, const UINT8 *src_scantable){    int i;    int end;        st->scantable= src_scantable;    for(i=0; i<64; i++){        int j;        j = src_scantable[i];        st->permutated[i] = s->idct_permutation[j];#ifdef ARCH_POWERPC        st->inverse[j] = i;#endif    }        end=-1;    for(i=0; i<64; i++){        int j;        j = st->permutated[i];        if(j>end) end=j;        st->raster_end[i]= end;    }}/* XXX: those functions should be suppressed ASAP when all IDCTs are converted */// *FIXME* this is ugly hack using local staticstatic void (*ff_put_pixels_clamped)(const DCTELEM *block, UINT8 *pixels, int line_size);static void (*ff_add_pixels_clamped)(const DCTELEM *block, UINT8 *pixels, int line_size);static void ff_jref_idct_put(UINT8 *dest, int line_size, DCTELEM *block){    j_rev_dct (block);    ff_put_pixels_clamped(block, dest, line_size);}static void ff_jref_idct_add(UINT8 *dest, int line_size, DCTELEM *block){    j_rev_dct (block);    ff_add_pixels_clamped(block, dest, line_size);}/* init common dct for both encoder and decoder */int DCT_common_init(MpegEncContext *s){    int i;    ff_put_pixels_clamped = s->dsp.put_pixels_clamped;    ff_add_pixels_clamped = s->dsp.add_pixels_clamped;    s->dct_unquantize_h263 = dct_unquantize_h263_c;    s->dct_unquantize_mpeg1 = dct_unquantize_mpeg1_c;    s->dct_unquantize_mpeg2 = dct_unquantize_mpeg2_c;    s->dct_quantize= dct_quantize_c;    if(s->avctx->dct_algo==FF_DCT_FASTINT)        s->fdct = fdct_ifast;    else        s->fdct = ff_jpeg_fdct_islow; //slow/accurate/default    if(s->avctx->idct_algo==FF_IDCT_INT){        s->idct_put= ff_jref_idct_put;        s->idct_add= ff_jref_idct_add;        s->idct_permutation_type= FF_LIBMPEG2_IDCT_PERM;    }else{ //accurate/default        s->idct_put= simple_idct_put;        s->idct_add= simple_idct_add;        s->idct_permutation_type= FF_NO_IDCT_PERM;    }        #ifdef HAVE_MMX    MPV_common_init_mmx(s);#endif#ifdef ARCH_ALPHA    MPV_common_init_axp(s);#endif#ifdef HAVE_MLIB    MPV_common_init_mlib(s);#endif#ifdef HAVE_MMI    MPV_common_init_mmi(s);#endif#ifdef ARCH_ARMV4L    MPV_common_init_armv4l(s);#endif#ifdef ARCH_POWERPC    MPV_common_init_ppc(s);#endif    switch(s->idct_permutation_type){    case FF_NO_IDCT_PERM:        for(i=0; i<64; i++)            s->idct_permutation[i]= i;        break;    case FF_LIBMPEG2_IDCT_PERM:        for(i=0; i<64; i++)            s->idct_permutation[i]= (i & 0x38) | ((i & 6) >> 1) | ((i & 1) << 2);        break;    case FF_SIMPLE_IDCT_PERM:        for(i=0; i<64; i++)            s->idct_permutation[i]= simple_mmx_permutation[i];        break;    case FF_TRANSPOSE_IDCT_PERM:        for(i=0; i<64; i++)            s->idct_permutation[i]= ((i&7)<<3) | (i>>3);        break;    default:        fprintf(stderr, "Internal error, IDCT permutation not set\n");        return -1;    }    /* load & permutate scantables       note: only wmv uses differnt ones     */    ff_init_scantable(s, &s->inter_scantable  , ff_zigzag_direct);    ff_init_scantable(s, &s->intra_scantable  , ff_zigzag_direct);    ff_init_scantable(s, &s->intra_h_scantable, ff_alternate_horizontal_scan);    ff_init_scantable(s, &s->intra_v_scantable, ff_alternate_vertical_scan);    return 0;}/* init common structure for both encoder and decoder */int MPV_common_init(MpegEncContext *s){    UINT8 *pict;    int y_size, c_size, yc_size, i;    dsputil_init(&s->dsp, s->avctx->dsp_mask);    DCT_common_init(s);    s->flags= s->avctx->flags;    s->mb_width = (s->width + 15) / 16;    s->mb_height = (s->height + 15) / 16;    /* set default edge pos, will be overriden in decode_header if needed */    s->h_edge_pos= s->mb_width*16;    s->v_edge_pos= s->mb_height*16;    s->mb_num = s->mb_width * s->mb_height;    y_size = (2 * s->mb_width + 2) * (2 * s->mb_height + 2);    c_size = (s->mb_width + 2) * (s->mb_height + 2);    yc_size = y_size + 2 * c_size;    /* convert fourcc to upper case */    s->avctx->fourcc=   toupper( s->avctx->fourcc     &0xFF)                               + (toupper((s->avctx->fourcc>>8 )&0xFF)<<8 )                     + (toupper((s->avctx->fourcc>>16)&0xFF)<<16)                      + (toupper((s->avctx->fourcc>>24)&0xFF)<<24);    if(!(s->flags&CODEC_FLAG_DR1)){      s->linesize   = s->mb_width * 16 + 2 * EDGE_WIDTH;      s->uvlinesize = s->mb_width * 8  +     EDGE_WIDTH;      for(i=0;i<3;i++) {	int w, h, shift, pict_start;	unsigned size;        w = s->linesize;        h = s->mb_height * 16 + 2 * EDGE_WIDTH;        shift = (i == 0) ? 0 : 1;        size = (s->linesize>>shift) * (h >> shift);        pict_start = (s->linesize>>shift) * (EDGE_WIDTH >> shift) + (EDGE_WIDTH >> shift);        CHECKED_ALLOCZ(pict, size)        s->last_picture_base[i] = pict;        s->last_picture[i] = pict + pict_start;        if(i>0) memset(s->last_picture_base[i], 128, size);            CHECKED_ALLOCZ(pict, size)        s->next_picture_base[i] = pict;        s->next_picture[i] = pict + pict_start;        if(i>0) memset(s->next_picture_base[i], 128, size);                if (s->has_b_frames || s->codec_id==CODEC_ID_MPEG4) {        /* Note the MPEG4 stuff is here cuz of buggy encoders which dont set the low_delay flag but            do low-delay encoding, so we cant allways distinguish b-frame containing streams from low_delay streams */            CHECKED_ALLOCZ(pict, size)            s->aux_picture_base[i] = pict;            s->aux_picture[i] = pict + pict_start;            if(i>0) memset(s->aux_picture_base[i], 128, size);        }      }      s->ip_buffer_count= 2;    }        CHECKED_ALLOCZ(s->edge_emu_buffer, (s->width+64)*2*17*2); //(width + edge + align)*interlaced*MBsize*tolerance        if (s->encoding) {        int j;        int mv_table_size= (s->mb_width+2)*(s->mb_height+2);                CHECKED_ALLOCZ(s->mb_var   , s->mb_num * sizeof(INT16))        CHECKED_ALLOCZ(s->mc_mb_var, s->mb_num * sizeof(INT16))        CHECKED_ALLOCZ(s->mb_mean  , s->mb_num * sizeof(INT8))        /* Allocate MV tables */        CHECKED_ALLOCZ(s->p_mv_table            , mv_table_size * 2 * sizeof(INT16))        CHECKED_ALLOCZ(s->b_forw_mv_table       , mv_table_size * 2 * sizeof(INT16))        CHECKED_ALLOCZ(s->b_back_mv_table       , mv_table_size * 2 * sizeof(INT16))        CHECKED_ALLOCZ(s->b_bidir_forw_mv_table , mv_table_size * 2 * sizeof(INT16))        CHECKED_ALLOCZ(s->b_bidir_back_mv_table , mv_table_size * 2 * sizeof(INT16))        CHECKED_ALLOCZ(s->b_direct_forw_mv_table, mv_table_size * 2 * sizeof(INT16))        CHECKED_ALLOCZ(s->b_direct_back_mv_table, mv_table_size * 2 * sizeof(INT16))        CHECKED_ALLOCZ(s->b_direct_mv_table     , mv_table_size * 2 * sizeof(INT16))        CHECKED_ALLOCZ(s->me_scratchpad,  s->linesize*16*3*sizeof(uint8_t))                CHECKED_ALLOCZ(s->me_map      , ME_MAP_SIZE*sizeof(uint32_t))        CHECKED_ALLOCZ(s->me_score_map, ME_MAP_SIZE*sizeof(uint16_t))        if(s->max_b_frames){            for(j=0; j<REORDER_BUFFER_SIZE; j++){                int i;                for(i=0;i<3;i++) {                    int w, h, shift, size;                    w = s->linesize;                    h = s->mb_height * 16;                    shift = (i == 0) ? 0 : 1;                    size = (w >> shift) * (h >> shift);                    CHECKED_ALLOCZ(pict, size);

⌨️ 快捷键说明

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