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

📄 mpegvideo.c

📁 君正早期ucos系统(只有早期的才不没有打包成库),MPLAYER,文件系统,图片解码,浏览,电子书,录音,想学ucos,识货的人就下吧 russblock fmradio explore set
💻 C
📖 第 1 页 / 共 5 页
字号:
/* * The simplest mpeg encoder (well, it was the simplest!) * Copyright (c) 2000,2001 Fabrice Bellard. * Copyright (c) 2002-2004 Michael Niedermayer <michaelni@gmx.at> * * 4MV & hq & B-frame encoding 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 mpegvideo.c * The simplest mpeg encoder (well, it was the simplest!). */#include "avcodec.h"#include "dsputil.h"#include "mpegvideo.h"#include "mpegvideo_common.h"#include "mjpegenc.h"#include "msmpeg4.h"#include "faandct.h"#include "jzmedia.h"#undef memcpy#define memcpy uc_memcpy#ifdef USE_16M_SDRAMvoid (*ff_wmv2_add_mb_funcp)(MpegEncContext *s, DCTELEM block[6][64], uint8_t *dest_y,                              uint8_t *dest_cb, uint8_t *dest_cr) = NULL;const uint8_t ff_mpeg1_dc_scale_table[128]={//  0  1  2  3  4  5  6  7  8  9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31    8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,    8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,    8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,    8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,};#endif//#undef NDEBUG//#include <assert.h>//static int idct_row_max;static void dct_unquantize_mpeg1_intra_c(MpegEncContext *s,                                   DCTELEM *block, int n, int qscale);static void dct_unquantize_mpeg1_inter_c(MpegEncContext *s,                                   DCTELEM *block, int n, int qscale);static void dct_unquantize_mpeg2_intra_c(MpegEncContext *s,                                   DCTELEM *block, int n, int qscale);static void dct_unquantize_mpeg2_intra_bitexact(MpegEncContext *s,                                   DCTELEM *block, int n, int qscale);static void dct_unquantize_mpeg2_inter_c(MpegEncContext *s,                                   DCTELEM *block, int n, int qscale);static void dct_unquantize_h263_intra_c(MpegEncContext *s,                                  DCTELEM *block, int n, int qscale);static void dct_unquantize_h263_inter_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);static void idct_put_mxu_c (uint8_t *dest, int line_size, DCTELEM *block);//static void idct_add_mxu_c (uint8_t *dest, int line_size, DCTELEM *block);#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 DEBUGstatic const uint8_t ff_default_chroma_qscale_table[32]={//  0  1  2  3  4  5  6  7  8  9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31    0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31};void 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;    }}const uint8_t *ff_find_start_code(const uint8_t * restrict p, const uint8_t *end, uint32_t * restrict state){    int i;    assert(p<=end);    if(p>=end)        return end;    for(i=0; i<3; i++){        uint32_t tmp= *state << 8;        *state= tmp + *(p++);        if(tmp == 0x100 || p==end)            return p;    }    while(p<end){        if     (p[-1] > 1      ) p+= 3;        else if(p[-2]          ) p+= 2;        else if(p[-3]|(p[-1]-1)) p++;        else{            p++;            break;        }    }    p= FFMIN(p, end)-4;    *state= AV_RB32(p);    return p+4;}/* init common dct for both encoder and decoder */static int DCT_common_init(MpegEncContext *s){    s->dct_unquantize_h263_intra = dct_unquantize_h263_intra_c;    s->dct_unquantize_h263_inter = dct_unquantize_h263_inter_c;    s->dct_unquantize_mpeg1_intra = dct_unquantize_mpeg1_intra_c;    s->dct_unquantize_mpeg1_inter = dct_unquantize_mpeg1_inter_c;    s->dct_unquantize_mpeg2_intra = dct_unquantize_mpeg2_intra_c;    if(s->flags & CODEC_FLAG_BITEXACT)        s->dct_unquantize_mpeg2_intra = dct_unquantize_mpeg2_intra_bitexact;    s->dct_unquantize_mpeg2_inter = dct_unquantize_mpeg2_inter_c;#if defined(HAVE_MMX)    MPV_common_init_mmx(s);#elif defined(ARCH_ALPHA)    MPV_common_init_axp(s);#elif defined(HAVE_MLIB)    MPV_common_init_mlib(s);#elif defined(HAVE_MMI)    MPV_common_init_mmi(s);#elif defined(ARCH_ARMV4L)    MPV_common_init_armv4l(s);#elif defined(HAVE_ALTIVEC)    MPV_common_init_altivec(s);#elif defined(ARCH_BFIN)    MPV_common_init_bfin(s);#endif    /* load & permutate scantables       note: only wmv uses different ones    */    if(s->alternate_scan){        ff_init_scantable(s->dsp.idct_permutation, &s->inter_scantable  , ff_alternate_vertical_scan);        ff_init_scantable(s->dsp.idct_permutation, &s->intra_scantable  , ff_alternate_vertical_scan);    }else{        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);    return 0;}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 */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) does not sig11    const int mb_array_size= s->mb_stride*s->mb_height;    const int b8_array_size= s->b8_stride*s->mb_height*2;    const int b4_array_size= s->b4_stride*s->mb_height*4;    int i;    int r= -1;    if(shared){        assert(pic->data[0]);        assert(pic->type == 0 || pic->type == FF_BUFFER_TYPE_SHARED);        pic->type= FF_BUFFER_TYPE_SHARED;    }else{        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");            s->avctx->release_buffer(s->avctx, (AVFrame*)pic);            return -1;        }        if(pic->linesize[1] != pic->linesize[2]){            av_log(s->avctx, AV_LOG_ERROR, "get_buffer() failed (uv stride mismatch)\n");            s->avctx->release_buffer(s->avctx, (AVFrame*)pic);            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->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(uint32_t))        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_base[i], 2 * (b4_array_size+4)  * sizeof(int16_t))                pic->motion_val[i]= pic->motion_val_base[i]+4;                CHECKED_ALLOCZ(pic->ref_index[i], b8_array_size * sizeof(uint8_t))            }            pic->motion_subsample_log2= 2;        }else if(s->out_format == FMT_H263 || s->encoding || (s->avctx->debug&FF_DEBUG_MV) || (s->avctx->debug_mv)){            for(i=0; i<2; i++){                CHECKED_ALLOCZ(pic->motion_val_base[i], 2 * (b8_array_size+4) * sizeof(int16_t))                pic->motion_val[i]= pic->motion_val_base[i]+4;                CHECKED_ALLOCZ(pic->ref_index[i], b8_array_size * sizeof(uint8_t))            }            pic->motion_subsample_log2= 3;        }        if(s->avctx->debug&FF_DEBUG_DCT_COEFF) {            CHECKED_ALLOCZ(pic->dct_coeff, 64 * mb_array_size * sizeof(DCTELEM)*6)        }        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 an 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; // Skipped MBs in B-frames are quite rare in MPEG-1/2 and it is a bit tricky to skip them anyway.    return 0;fail: //for the CHECKED_ALLOCZ macro    if(r>=0)        s->avctx->release_buffer(s->avctx, (AVFrame*)pic);    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);    av_freep(&pic->mbskip_table);    av_freep(&pic->qscale_table);    av_freep(&pic->mb_type_base);    av_freep(&pic->dct_coeff);    av_freep(&pic->pan_scan);    pic->mb_type= NULL;    for(i=0; i<2; i++){        av_freep(&pic->motion_val_base[i]);        av_freep(&pic->ref_index[i]);    }    if(pic->type == FF_BUFFER_TYPE_SHARED){        for(i=0; i<4; i++){            pic->base[i]=            pic->data[i]= NULL;        }        pic->type= 0;    }}static int init_duplicate_context(MpegEncContext *s, MpegEncContext *base){    int i;    // edge emu needs blocksize + filter length - 1 (=17x17 for halfpel / 21x21 for h264)    CHECKED_ALLOCZ(s->allocated_edge_emu_buffer, (s->width+64)*2*21*2); //(width + edge + align)*interlaced*MBsize*tolerance    s->edge_emu_buffer= s->allocated_edge_emu_buffer + (s->width+64)*2*21;     //FIXME should be linesize instead of s->width*2 but that is not known before get_buffer()    CHECKED_ALLOCZ(s->me.scratchpad,  (s->width+64)*4*16*2*sizeof(uint8_t))    s->rd_scratchpad=   s->me.scratchpad;    s->b_scratchpad=    s->me.scratchpad;    s->obmc_scratchpad= s->me.scratchpad + 16;    if (s->encoding) {        CHECKED_ALLOCZ(s->me.map      , ME_MAP_SIZE*sizeof(uint32_t))        CHECKED_ALLOCZ(s->me.score_map, ME_MAP_SIZE*sizeof(uint32_t))        if(s->avctx->noise_reduction){            CHECKED_ALLOCZ(s->dct_error_sum, 2 * 64 * sizeof(int))        }    }    CHECKED_ALLOCZ(s->blocks, 64*12*2 * sizeof(DCTELEM))    s->block= s->blocks[0];    for(i=0;i<12;i++){        s->pblocks[i] = (short *)(&s->block[i]);    }    return 0;fail:

⌨️ 快捷键说明

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