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

📄 mpegvideo_enc.c

📁 ffmpeg移植到symbian的全部源代码
💻 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_enc.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 "h263.h"#include "faandct.h"#include <limits.h>//#undef NDEBUG//#include <assert.h>static int encode_picture(MpegEncContext *s, int picture_number);static int dct_quantize_refine(MpegEncContext *s, DCTELEM *block, int16_t *weight, DCTELEM *orig, int n, int qscale);static int sse_mb(MpegEncContext *s);/* enable all paranoid tests for rounding, overflows, etc... *///#define PARANOID//#define DEBUGstatic 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 uint16_t inv_aanscales[64] = {  4096,  2953,  3135,  3483,  4096,  5213,  7568, 14846,  2953,  2129,  2260,  2511,  2953,  3759,  5457, 10703,  3135,  2260,  2399,  2666,  3135,  3990,  5793, 11363,  3483,  2511,  2666,  2962,  3483,  4433,  6436, 12625,  4096,  2953,  3135,  3483,  4096,  5213,  7568, 14846,  5213,  3759,  3990,  4433,  5213,  6635,  9633, 18895,  7568,  5457,  5793,  6436,  7568,  9633, 13985, 27432, 14846, 10703, 11363, 12625, 14846, 18895, 27432, 53809,};static uint8_t default_mv_penalty[MAX_FCODE+1][MAX_MV*2+1];static uint8_t default_fcode_tab[MAX_MV*2+1];void ff_convert_matrix(DSPContext *dsp, int (*qmat)[64], uint16_t (*qmat16)[2][64],                           const uint16_t *quant_matrix, int bias, int qmin, int qmax, int intra){    int qscale;    int shift=0;    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_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_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_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]);            }        }        for(i=intra; i<64; i++){            int64_t max= 8191;            if (dsp->fdct == fdct_ifast#ifndef FAAN_POSTSCALE                   || dsp->fdct == ff_faandct#endif                   ) {                max= (8191LL*aanscales[i]) >> 14;            }            while(((max * qmat[qscale][i]) >> shift) > INT_MAX){                shift++;            }        }    }    if(shift){        av_log(NULL, AV_LOG_INFO, "Warning, QMAT_SHIFT is larger than %d, overflows possible\n", QMAT_SHIFT - shift);    }}static inline void update_qscale(MpegEncContext *s){    s->qscale= (s->lambda*139 + FF_LAMBDA_SCALE*64) >> (FF_LAMBDA_SHIFT + 7);    s->qscale= av_clip(s->qscale, s->avctx->qmin, s->avctx->qmax);    s->lambda2= (s->lambda*s->lambda + FF_LAMBDA_SCALE/2) >> FF_LAMBDA_SHIFT;}void ff_write_quant_matrix(PutBitContext *pb, uint16_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);}static void copy_picture_attributes(MpegEncContext *s, AVFrame *dst, AVFrame *src){    int i;    dst->pict_type              = src->pict_type;    dst->quality                = src->quality;    dst->coded_picture_number   = src->coded_picture_number;    dst->display_picture_number = src->display_picture_number;//    dst->reference              = src->reference;    dst->pts                    = src->pts;    dst->interlaced_frame       = src->interlaced_frame;    dst->top_field_first        = src->top_field_first;    if(s->avctx->me_threshold){        if(!src->motion_val[0])            av_log(s->avctx, AV_LOG_ERROR, "AVFrame.motion_val not set!\n");        if(!src->mb_type)            av_log(s->avctx, AV_LOG_ERROR, "AVFrame.mb_type not set!\n");        if(!src->ref_index[0])            av_log(s->avctx, AV_LOG_ERROR, "AVFrame.ref_index not set!\n");        if(src->motion_subsample_log2 != dst->motion_subsample_log2)            av_log(s->avctx, AV_LOG_ERROR, "AVFrame.motion_subsample_log2 doesn't match! (%d!=%d)\n",            src->motion_subsample_log2, dst->motion_subsample_log2);        memcpy(dst->mb_type, src->mb_type, s->mb_stride * s->mb_height * sizeof(dst->mb_type[0]));        for(i=0; i<2; i++){            int stride= ((16*s->mb_width )>>src->motion_subsample_log2) + 1;            int height= ((16*s->mb_height)>>src->motion_subsample_log2);            if(src->motion_val[i] && src->motion_val[i] != dst->motion_val[i]){                memcpy(dst->motion_val[i], src->motion_val[i], 2*stride*height*sizeof(int16_t));            }            if(src->ref_index[i] && src->ref_index[i] != dst->ref_index[i]){                memcpy(dst->ref_index[i], src->ref_index[i], s->b8_stride*2*s->mb_height*sizeof(int8_t));            }        }    }}static void update_duplicate_context_after_me(MpegEncContext *dst, MpegEncContext *src){#define COPY(a) dst->a= src->a    COPY(pict_type);    COPY(current_picture);    COPY(f_code);    COPY(b_code);    COPY(qscale);    COPY(lambda);    COPY(lambda2);    COPY(picture_in_gop_number);    COPY(gop_picture_number);    COPY(frame_pred_frame_dct); //FIXME don't set in encode_header    COPY(progressive_frame); //FIXME don't set in encode_header    COPY(partitioned_frame); //FIXME don't set in encode_header#undef COPY}/** * sets the given MpegEncContext to defaults for encoding. * the changed fields will not depend upon the prior state of the MpegEncContext. */static void MPV_encode_defaults(MpegEncContext *s){    int i;    MPV_common_defaults(s);    for(i=-16; i<16; i++){        default_fcode_tab[i + MAX_MV]= 1;    }    s->me.mv_penalty= default_mv_penalty;    s->fcode_tab= default_fcode_tab;}/* init video encoder */av_cold int MPV_encode_init(AVCodecContext *avctx){    MpegEncContext *s = avctx->priv_data;    int i;    int chroma_h_shift, chroma_v_shift;    MPV_encode_defaults(s);    switch (avctx->codec_id) {    case CODEC_ID_MPEG2VIDEO:        if(avctx->pix_fmt != PIX_FMT_YUV420P && avctx->pix_fmt != PIX_FMT_YUV422P){            av_log(avctx, AV_LOG_ERROR, "only YUV420 and YUV422 are supported\n");            return -1;        }        break;    case CODEC_ID_LJPEG:    case CODEC_ID_MJPEG:        if(avctx->pix_fmt != PIX_FMT_YUVJ420P && avctx->pix_fmt != PIX_FMT_YUVJ422P &&           ((avctx->pix_fmt != PIX_FMT_YUV420P && avctx->pix_fmt != PIX_FMT_YUV422P) || avctx->strict_std_compliance>FF_COMPLIANCE_INOFFICIAL)){            av_log(avctx, AV_LOG_ERROR, "colorspace not supported in jpeg\n");            return -1;        }        break;    default:        if(avctx->pix_fmt != PIX_FMT_YUV420P){            av_log(avctx, AV_LOG_ERROR, "only YUV420 is supported\n");            return -1;        }    }    switch (avctx->pix_fmt) {    case PIX_FMT_YUVJ422P:    case PIX_FMT_YUV422P:        s->chroma_format = CHROMA_422;        break;    case PIX_FMT_YUVJ420P:    case PIX_FMT_YUV420P:    default:        s->chroma_format = CHROMA_420;        break;    }    s->bit_rate = avctx->bit_rate;    s->width = avctx->width;    s->height = avctx->height;    if(avctx->gop_size > 600 && avctx->strict_std_compliance>FF_COMPLIANCE_EXPERIMENTAL){        av_log(avctx, AV_LOG_ERROR, "Warning keyframe interval too large! reducing it ...\n");        avctx->gop_size=600;    }    s->gop_size = avctx->gop_size;    s->avctx = avctx;    s->flags= avctx->flags;    s->flags2= avctx->flags2;    s->max_b_frames= avctx->max_b_frames;    s->codec_id= avctx->codec->id;    s->luma_elim_threshold  = avctx->luma_elim_threshold;    s->chroma_elim_threshold= avctx->chroma_elim_threshold;    s->strict_std_compliance= avctx->strict_std_compliance;    s->data_partitioning= avctx->flags & CODEC_FLAG_PART;    s->quarter_sample= (avctx->flags & CODEC_FLAG_QPEL)!=0;    s->mpeg_quant= avctx->mpeg_quant;    s->rtp_mode= !!avctx->rtp_payload_size;    s->intra_dc_precision= avctx->intra_dc_precision;    s->user_specified_pts = AV_NOPTS_VALUE;    if (s->gop_size <= 1) {        s->intra_only = 1;        s->gop_size = 12;    } else {        s->intra_only = 0;    }    s->me_method = avctx->me_method;    /* Fixed QSCALE */    s->fixed_qscale = !!(avctx->flags & CODEC_FLAG_QSCALE);    s->adaptive_quant= (   s->avctx->lumi_masking                        || s->avctx->dark_masking                        || s->avctx->temporal_cplx_masking                        || s->avctx->spatial_cplx_masking                        || s->avctx->p_masking                        || s->avctx->border_masking                        || (s->flags&CODEC_FLAG_QP_RD))                       && !s->fixed_qscale;    s->obmc= !!(s->flags & CODEC_FLAG_OBMC);    s->loop_filter= !!(s->flags & CODEC_FLAG_LOOP_FILTER);    s->alternate_scan= !!(s->flags & CODEC_FLAG_ALT_SCAN);    s->intra_vlc_format= !!(s->flags2 & CODEC_FLAG2_INTRA_VLC);    s->q_scale_type= !!(s->flags2 & CODEC_FLAG2_NON_LINEAR_QUANT);#if LIBAVCODEC_VERSION_INT < ((52<<16)+(0<<8)+0)    if (s->flags & CODEC_FLAG_TRELLIS_QUANT)        avctx->trellis = 1;#endif    if(avctx->rc_max_rate && !avctx->rc_buffer_size){        av_log(avctx, AV_LOG_ERROR, "a vbv buffer size is needed, for encoding with a maximum bitrate\n");        return -1;    }    if(avctx->rc_min_rate && avctx->rc_max_rate != avctx->rc_min_rate){        av_log(avctx, AV_LOG_INFO, "Warning min_rate > 0 but min_rate != max_rate isn't recommended!\n");    }    if(avctx->rc_min_rate && avctx->rc_min_rate > avctx->bit_rate){        av_log(avctx, AV_LOG_ERROR, "bitrate below min bitrate\n");

⌨️ 快捷键说明

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