diff options
Diffstat (limited to 'libavcodec/mpeg4videoenc.c')
-rw-r--r-- | libavcodec/mpeg4videoenc.c | 75 |
1 files changed, 46 insertions, 29 deletions
diff --git a/libavcodec/mpeg4videoenc.c b/libavcodec/mpeg4videoenc.c index fd39b3f8d7..8454edd0dc 100644 --- a/libavcodec/mpeg4videoenc.c +++ b/libavcodec/mpeg4videoenc.c @@ -3,20 +3,20 @@ * Copyright (c) 2000,2001 Fabrice Bellard * Copyright (c) 2002-2010 Michael Niedermayer <michaelni@gmx.at> * - * This file is part of Libav. + * This file is part of FFmpeg. * - * Libav is free software; you can redistribute it and/or + * 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. * - * Libav is distributed in the hope that it will be useful, + * 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 Libav; if not, write to the Free Software + * License along with FFmpeg; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ @@ -200,7 +200,7 @@ static inline int decide_ac_pred(MpegEncContext * s, int16_t block[6][64], const } /** - * modify mb_type & qscale so that encoding is acually possible in mpeg4 + * modify mb_type & qscale so that encoding is actually possible in mpeg4 */ void ff_clean_mpeg4_qscales(MpegEncContext *s){ int i; @@ -495,9 +495,9 @@ void ff_mpeg4_encode_mb(MpegEncContext * s, } } - assert(s->dquant>=-2 && s->dquant<=2); - assert((s->dquant&1)==0); - assert(mb_type>=0); + av_assert2(s->dquant>=-2 && s->dquant<=2); + av_assert2((s->dquant&1)==0); + av_assert2(mb_type>=0); /* nothing to do if this MB was skipped in the next P Frame */ if (s->next_picture.mbskip_table[s->mb_y * s->mb_stride + s->mb_x]) { //FIXME avoid DCT & ... @@ -517,7 +517,7 @@ void ff_mpeg4_encode_mb(MpegEncContext * s, if ((cbp | motion_x | motion_y | mb_type) ==0) { /* direct MB with MV={0,0} */ - assert(s->dquant==0); + av_assert2(s->dquant==0); put_bits(&s->pb, 1, 1); /* mb not coded modb1=1 */ @@ -554,12 +554,12 @@ void ff_mpeg4_encode_mb(MpegEncContext * s, } if(mb_type == 0){ - assert(s->mv_dir & MV_DIRECT); + av_assert2(s->mv_dir & MV_DIRECT); ff_h263_encode_motion_vector(s, motion_x, motion_y, 1); s->b_count++; s->f_count++; }else{ - assert(mb_type > 0 && mb_type < 4); + av_assert2(mb_type > 0 && mb_type < 4); if(s->mv_type != MV_TYPE_FIELD){ if(s->mv_dir & MV_DIR_FORWARD){ ff_h263_encode_motion_vector(s, s->mv[0][0][0] - s->last_mv[0][0][0], @@ -628,8 +628,6 @@ void ff_mpeg4_encode_mb(MpegEncContext * s, x= s->mb_x*16; y= s->mb_y*16; - if(x+16 > s->width) x= s->width-16; - if(y+16 > s->height) y= s->height-16; offset= x + y*s->linesize; p_pic = s->new_picture.f.data[0] + offset; @@ -646,7 +644,21 @@ void ff_mpeg4_encode_mb(MpegEncContext * s, b_pic = pic->f.data[0] + offset; if (!pic->shared) b_pic+= INPLACE_OFFSET; - diff= s->dsp.sad[0](NULL, p_pic, b_pic, s->linesize, 16); + + if(x+16 > s->width || y+16 > s->height){ + int x1,y1; + int xe= FFMIN(16, s->width - x); + int ye= FFMIN(16, s->height- y); + diff=0; + for(y1=0; y1<ye; y1++){ + for(x1=0; x1<xe; x1++){ + diff+= FFABS(p_pic[x1+y1*s->linesize] - b_pic[x1+y1*s->linesize]); + } + } + diff= diff*256/(xe*ye); + }else{ + diff= s->dsp.sad[0](NULL, p_pic, b_pic, s->linesize, 16); + } if(diff>s->qscale*70){ //FIXME check that 70 is optimal s->mb_skipped=0; break; @@ -708,7 +720,7 @@ void ff_mpeg4_encode_mb(MpegEncContext * s, if(s->dquant) put_bits(pb2, 2, dquant_code[s->dquant+2]); - assert(!s->progressive_sequence); + av_assert2(!s->progressive_sequence); if(cbp) put_bits(pb2, 1, s->interlaced_dct); put_bits(pb2, 1, 1); @@ -729,7 +741,7 @@ void ff_mpeg4_encode_mb(MpegEncContext * s, ff_h263_encode_motion_vector(s, s->mv[0][1][0] - pred_x, s->mv[0][1][1] - pred_y, s->f_code); }else{ - assert(s->mv_type==MV_TYPE_8X8); + av_assert2(s->mv_type==MV_TYPE_8X8); put_bits(&s->pb, ff_h263_inter_MCBPC_bits[cbpc+16], ff_h263_inter_MCBPC_code[cbpc+16]); @@ -847,7 +859,7 @@ void ff_set_mpeg4_time(MpegEncContext * s){ ff_mpeg4_init_direct_mv(s); }else{ s->last_time_base= s->time_base; - s->time_base= s->time/s->avctx->time_base.den; + s->time_base= FFUDIV(s->time, s->avctx->time_base.den); } } @@ -862,11 +874,12 @@ static void mpeg4_encode_gop_header(MpegEncContext * s){ if(s->reordered_input_picture[1]) time = FFMIN(time, s->reordered_input_picture[1]->f.pts); time= time*s->avctx->time_base.num; + s->last_time_base= FFUDIV(time, s->avctx->time_base.den); - seconds= time/s->avctx->time_base.den; - minutes= seconds/60; seconds %= 60; - hours= minutes/60; minutes %= 60; - hours%=24; + seconds= FFUDIV(time, s->avctx->time_base.den); + minutes= FFUDIV(seconds, 60); seconds = FFUMOD(seconds, 60); + hours = FFUDIV(minutes, 60); minutes = FFUMOD(minutes, 60); + hours = FFUMOD(hours , 24); put_bits(&s->pb, 5, hours); put_bits(&s->pb, 6, minutes); @@ -876,8 +889,6 @@ static void mpeg4_encode_gop_header(MpegEncContext * s){ put_bits(&s->pb, 1, !!(s->flags&CODEC_FLAG_CLOSED_GOP)); put_bits(&s->pb, 1, 0); //broken link == NO - s->last_time_base= time / s->avctx->time_base.den; - ff_mpeg4_stuffing(&s->pb); } @@ -959,6 +970,8 @@ static void mpeg4_encode_vol_header(MpegEncContext * s, int vo_number, int vol_n put_bits(&s->pb, 4, s->aspect_ratio_info);/* aspect ratio info */ if (s->aspect_ratio_info == FF_ASPECT_EXTENDED){ + av_reduce(&s->avctx->sample_aspect_ratio.num, &s->avctx->sample_aspect_ratio.den, + s->avctx->sample_aspect_ratio.num, s->avctx->sample_aspect_ratio.den, 255); put_bits(&s->pb, 8, s->avctx->sample_aspect_ratio.num); put_bits(&s->pb, 8, s->avctx->sample_aspect_ratio.den); } @@ -1050,11 +1063,10 @@ void ff_mpeg4_encode_picture_header(MpegEncContext * s, int picture_number) put_bits(&s->pb, 16, VOP_STARTCODE); /* vop header */ put_bits(&s->pb, 2, s->pict_type - 1); /* pict type: I = 0 , P = 1 */ - assert(s->time>=0); - time_div= s->time/s->avctx->time_base.den; - time_mod= s->time%s->avctx->time_base.den; + time_div= FFUDIV(s->time, s->avctx->time_base.den); + time_mod= FFUMOD(s->time, s->avctx->time_base.den); time_incr= time_div - s->last_time_base; - assert(time_incr >= 0); + av_assert0(time_incr >= 0); while(time_incr--) put_bits(&s->pb, 1, 1); @@ -1141,8 +1153,8 @@ static av_cold void init_uni_mpeg4_rl_tab(RLTable *rl, uint32_t *bits_tab, { int slevel, run, last; - assert(MAX_LEVEL >= 64); - assert(MAX_RUN >= 63); + av_assert0(MAX_LEVEL >= 64); + av_assert0(MAX_RUN >= 63); for(slevel=-64; slevel<64; slevel++){ if(slevel==0) continue; @@ -1225,6 +1237,11 @@ static av_cold int encode_init(AVCodecContext *avctx) int ret; static int done = 0; + if (avctx->width >= (1<<13) || avctx->height >= (1<<13)) { + av_log(avctx, AV_LOG_ERROR, "dimensions too large for MPEG-4\n"); + return AVERROR(EINVAL); + } + if((ret=ff_MPV_encode_init(avctx)) < 0) return ret; |