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

📄 mpegvideo.c

📁 Trolltech公司发布的图形界面操作系统。可在qt-embedded-2.3.10平台上编译为嵌入式图形界面操作系统。
💻 C
📖 第 1 页 / 共 4 页
字号:
/* * 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> */ /** * @file mpegvideo.c * The simplest mpeg encoder (well, it was the simplest!). */  #include <limits.h>#include "avcodec.h"#include "dsputil.h"#include "mpegvideo.h"#include "faandct.h"#ifdef USE_FASTMEMCPY#include "fastmemcpy.h"#endif//#undef NDEBUG//#include <assert.h>#ifdef CONFIG_ENCODERSstatic void encode_picture(MpegEncContext *s, int picture_number);#endif //CONFIG_ENCODERSstatic 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_t *buf, int wrap, int width, int height, int w);#ifdef CONFIG_ENCODERSstatic int dct_quantize_c(MpegEncContext *s, DCTELEM *block, int n, int qscale, int *overflow);static int dct_quantize_trellis_c(MpegEncContext *s, DCTELEM *block, int n, int qscale, int *overflow);static int sse_mb(MpegEncContext *s);#endif //CONFIG_ENCODERS#ifdef HAVE_XVMCextern int  XVMC_field_start(MpegEncContext*s, AVCodecContext *avctx);extern void XVMC_field_end(MpegEncContext *s);extern void XVMC_decode_mb(MpegEncContext *s);#endifvoid (*draw_edges)(uint8_t *buf, int wrap, int width, int height, int w)= draw_edges_c;/* 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};static const uint8_t h263_chroma_roundtab[16] = {//  0  1  2  3  4  5  6  7  8  9 10 11 12 13 14 15    0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2,};#ifdef CONFIG_ENCODERSstatic uint8_t (*default_mv_penalty)[MAX_MV*2+1]=NULL;static uint8_t default_fcode_tab[MAX_MV*2+1];enum PixelFormat ff_yuv420p_list[2]= {PIX_FMT_YUV420P, -1};static void convert_matrix(DSPContext *dsp, int (*qmat)[64], uint16_t (*qmat16)[2][64],                           const uint16_t *quant_matrix, int bias, int qmin, int qmax){    int qscale;    for(qscale=qmin; qscale<=qmax; qscale++){        int i;        if (dsp->fdct == ff_jpeg_fdct_islow #ifdef FAAN_POSTSCALE            || dsp->fdct == ff_faandct#endif            ) {            for(i=0;i<64;i++) {                const int j= dsp->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_t_C(1) << QMAT_SHIFT) /                                 (qscale * quant_matrix[j]));            }        } else if (dsp->fdct == fdct_ifast#ifndef FAAN_POSTSCALE                   || dsp->fdct == ff_faandct#endif                   ) {            for(i=0;i<64;i++) {                const int j= dsp->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_t_C(1) << (QMAT_SHIFT + 14)) /                                 (aanscales[i] * qscale * quant_matrix[j]));            }        } else {            for(i=0;i<64;i++) {                const int j= dsp->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] = (int)((uint64_t_C(1) << QMAT_SHIFT) / (qscale * quant_matrix[j]));//                qmat  [qscale][i] = (1 << QMAT_SHIFT_MMX) / (qscale * quant_matrix[i]);                qmat16[qscale][0][i] = (1 << QMAT_SHIFT_MMX) / (qscale * quant_matrix[j]);                if(qmat16[qscale][0][i]==0 || qmat16[qscale][0][i]==128*256) qmat16[qscale][0][i]=128*256-1;                qmat16[qscale][1][i]= ROUNDED_DIV(bias<<(16-QUANT_BIAS_SHIFT), qmat16[qscale][0][i]);            }        }    }}static inline void update_qscale(MpegEncContext *s){    s->qscale= (s->lambda*139 + FF_LAMBDA_SCALE*64) >> (FF_LAMBDA_SHIFT + 7);    s->qscale= clip(s->qscale, s->avctx->qmin, s->avctx->qmax);        s->lambda2= (s->lambda*s->lambda + FF_LAMBDA_SCALE/2) >> FF_LAMBDA_SHIFT;}#endif //CONFIG_ENCODERSvoid ff_init_scantable(uint8_t *permutation, ScanTable *st, const uint8_t *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] = 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;    }}#ifdef CONFIG_ENCODERSvoid ff_write_quant_matrix(PutBitContext *pb, int16_t *matrix){    int i;    if(matrix){        put_bits(pb, 1, 1);        for(i=0;i<64;i++) {            put_bits(pb, 8, matrix[ ff_zigzag_direct[i] ]);        }    }else        put_bits(pb, 1, 0);}#endif //CONFIG_ENCODERS/* init common dct for both encoder and decoder */int DCT_common_init(MpegEncContext *s){    s->dct_unquantize_h263 = dct_unquantize_h263_c;    s->dct_unquantize_mpeg1 = dct_unquantize_mpeg1_c;    s->dct_unquantize_mpeg2 = dct_unquantize_mpeg2_c;#ifdef CONFIG_ENCODERS    s->dct_quantize= dct_quantize_c;#endif        #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#ifdef CONFIG_ENCODERS    s->fast_dct_quantize= s->dct_quantize;    if(s->flags&CODEC_FLAG_TRELLIS_QUANT){        s->dct_quantize= dct_quantize_trellis_c; //move before MPV_common_init_*    }#endif //CONFIG_ENCODERS    /* load & permutate scantables       note: only wmv uses differnt ones     */    ff_init_scantable(s->dsp.idct_permutation, &s->inter_scantable  , ff_zigzag_direct);    ff_init_scantable(s->dsp.idct_permutation, &s->intra_scantable  , ff_zigzag_direct);    ff_init_scantable(s->dsp.idct_permutation, &s->intra_h_scantable, ff_alternate_horizontal_scan);    ff_init_scantable(s->dsp.idct_permutation, &s->intra_v_scantable, ff_alternate_vertical_scan);    s->picture_structure= PICT_FRAME;        return 0;}static void copy_picture(Picture *dst, Picture *src){    *dst = *src;    dst->type= FF_BUFFER_TYPE_COPY;}/** * allocates a Picture * The pixels are allocated/set by calling get_buffer() if shared=0 */static int alloc_picture(MpegEncContext *s, Picture *pic, int shared){    const int big_mb_num= s->mb_stride*(s->mb_height+1) + 1; //the +1 is needed so memset(,,stride*height) doesnt sig11    const int mb_array_size= s->mb_stride*s->mb_height;    int i;        if(shared){        assert(pic->data[0]);        assert(pic->type == 0 || pic->type == FF_BUFFER_TYPE_SHARED);        pic->type= FF_BUFFER_TYPE_SHARED;    }else{        int r;                assert(!pic->data[0]);                r= s->avctx->get_buffer(s->avctx, (AVFrame*)pic);                if(r<0 || !pic->age || !pic->type || !pic->data[0]){	    av_log(s->avctx, AV_LOG_ERROR, "get_buffer() failed (%d %d %d %p)\n", r, pic->age, pic->type, pic->data[0]);            return -1;        }        if(s->linesize && (s->linesize != pic->linesize[0] || s->uvlinesize != pic->linesize[1])){            av_log(s->avctx, AV_LOG_ERROR, "get_buffer() failed (stride changed)\n");            return -1;        }        if(pic->linesize[1] != pic->linesize[2]){            av_log(s->avctx, AV_LOG_ERROR, "get_buffer() failed (uv stride missmatch)\n");            return -1;        }        s->linesize  = pic->linesize[0];        s->uvlinesize= pic->linesize[1];    }        if(pic->qscale_table==NULL){        if (s->encoding) {                    CHECKED_ALLOCZ(pic->mb_var   , mb_array_size * sizeof(int16_t))            CHECKED_ALLOCZ(pic->mc_mb_var, mb_array_size * sizeof(int16_t))            CHECKED_ALLOCZ(pic->mb_mean  , mb_array_size * sizeof(int8_t))            CHECKED_ALLOCZ(pic->mb_cmp_score, mb_array_size * sizeof(int32_t))        }        CHECKED_ALLOCZ(pic->mbskip_table , mb_array_size * sizeof(uint8_t)+2) //the +2 is for the slice end check        CHECKED_ALLOCZ(pic->qscale_table , mb_array_size * sizeof(uint8_t))        CHECKED_ALLOCZ(pic->mb_type_base , big_mb_num    * sizeof(int))        pic->mb_type= pic->mb_type_base + s->mb_stride+1;        if(s->out_format == FMT_H264){            for(i=0; i<2; i++){                CHECKED_ALLOCZ(pic->motion_val[i], 2 * 16 * s->mb_num * sizeof(uint16_t))                CHECKED_ALLOCZ(pic->ref_index[i] , 4 * s->mb_num * sizeof(uint8_t))            }        }        pic->qstride= s->mb_stride;        CHECKED_ALLOCZ(pic->pan_scan , 1 * sizeof(AVPanScan))    }    //it might be nicer if the application would keep track of these but it would require a API change    memmove(s->prev_pict_types+1, s->prev_pict_types, PREV_PICT_TYPES_BUFFER_SIZE-1);    s->prev_pict_types[0]= s->pict_type;    if(pic->age < PREV_PICT_TYPES_BUFFER_SIZE && s->prev_pict_types[pic->age] == B_TYPE)        pic->age= INT_MAX; // skiped MBs in b frames are quite rare in mpeg1/2 and its a bit tricky to skip them anyway        return 0;fail: //for the CHECKED_ALLOCZ macro    return -1;}/** * deallocates a picture */static void free_picture(MpegEncContext *s, Picture *pic){    int i;    if(pic->data[0] && pic->type!=FF_BUFFER_TYPE_SHARED){        s->avctx->release_buffer(s->avctx, (AVFrame*)pic);    }    av_freep(&pic->mb_var);    av_freep(&pic->mc_mb_var);    av_freep(&pic->mb_mean);

⌨️ 快捷键说明

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