📄 mpegvideo.c
字号:
/* * The simplest mpeg encoder (well, it was the simplest!) * Copyright (c) 2000,2001 Fabrice Bellard. * Copyright (c) 2002-2004 Michael Niedermayer <michaelni@gmx.at> * * 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 "avcodec.h"#include "dsputil.h"#include "mpegvideo.h"#include "faandct.h"#include <limits.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_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_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);#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 dct_quantize_refine(MpegEncContext *s, DCTELEM *block, int16_t *weight, DCTELEM *orig, int n, int qscale);static int sse_mb(MpegEncContext *s);static void denoise_dct_c(MpegEncContext *s, DCTELEM *block);#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,};static 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};#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 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_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]); } } 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 then %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= 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_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; s->dct_unquantize_mpeg2_inter = dct_unquantize_mpeg2_inter_c;#ifdef CONFIG_ENCODERS s->dct_quantize= dct_quantize_c; s->denoise_dct= denoise_dct_c;#endif //CONFIG_ENCODERS #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 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;}static void copy_picture(Picture *dst, Picture *src){ *dst = *src; dst->type= FF_BUFFER_TYPE_COPY;}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)); } } }}/** * 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; 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; 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; }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -