From eb727387fd41d0e6ae2a35a718701f454b940fb6 Mon Sep 17 00:00:00 2001 From: Anton Khirnov Date: Thu, 1 Mar 2012 12:15:45 +0100 Subject: lavc: shrink encoded video packet size after encoding. Based on a patch by Nicolas George normalesup.org> --- libavcodec/utils.c | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'libavcodec') diff --git a/libavcodec/utils.c b/libavcodec/utils.c index 2d79f66e35..d797c8a0b7 100644 --- a/libavcodec/utils.c +++ b/libavcodec/utils.c @@ -1113,6 +1113,12 @@ int attribute_align_arg avcodec_encode_video2(AVCodecContext *avctx, else if (!(avctx->codec->capabilities & CODEC_CAP_DELAY)) avpkt->pts = avpkt->dts = frame->pts; + if (!user_packet && avpkt->data) { + uint8_t *new_data = av_realloc(avpkt->data, avpkt->size); + if (new_data) + avpkt->data = new_data; + } + avctx->frame_number++; } -- cgit v1.2.3 From 2f4b476e04160dad9472a61db2dd575471f39812 Mon Sep 17 00:00:00 2001 From: Diego Biurrun Date: Sat, 18 Feb 2012 14:28:43 +0100 Subject: msmpeg4: Split encoding backend code off from general backend code. --- libavcodec/Makefile | 12 +- libavcodec/msmpeg4.c | 700 +---------------------------------------------- libavcodec/msmpeg4.h | 12 + libavcodec/msmpeg4data.c | 4 + libavcodec/msmpeg4data.h | 4 + libavcodec/msmpeg4enc.c | 692 ++++++++++++++++++++++++++++++++++++++++++++++ 6 files changed, 734 insertions(+), 690 deletions(-) create mode 100644 libavcodec/msmpeg4enc.c (limited to 'libavcodec') diff --git a/libavcodec/Makefile b/libavcodec/Makefile index b177450563..53e67dc97c 100644 --- a/libavcodec/Makefile +++ b/libavcodec/Makefile @@ -272,12 +272,14 @@ OBJS-$(CONFIG_MPEG4_VAAPI_HWACCEL) += vaapi_mpeg4.o OBJS-$(CONFIG_MSMPEG4V1_DECODER) += msmpeg4.o msmpeg4data.o OBJS-$(CONFIG_MSMPEG4V2_DECODER) += msmpeg4.o msmpeg4data.o h263dec.o \ h263.o ituh263dec.o mpeg4videodec.o -OBJS-$(CONFIG_MSMPEG4V2_ENCODER) += msmpeg4.o msmpeg4data.o h263dec.o \ - h263.o ituh263dec.o mpeg4videodec.o +OBJS-$(CONFIG_MSMPEG4V2_ENCODER) += msmpeg4.o msmpeg4enc.o msmpeg4data.o \ + h263dec.o h263.o ituh263dec.o \ + mpeg4videodec.o OBJS-$(CONFIG_MSMPEG4V3_DECODER) += msmpeg4.o msmpeg4data.o h263dec.o \ h263.o ituh263dec.o mpeg4videodec.o -OBJS-$(CONFIG_MSMPEG4V3_ENCODER) += msmpeg4.o msmpeg4data.o h263dec.o \ - h263.o ituh263dec.o mpeg4videodec.o +OBJS-$(CONFIG_MSMPEG4V3_ENCODER) += msmpeg4.o msmpeg4enc.o msmpeg4data.o \ + h263dec.o h263.o ituh263dec.o \ + mpeg4videodec.o OBJS-$(CONFIG_MSRLE_DECODER) += msrle.o msrledec.o OBJS-$(CONFIG_MSVIDEO1_DECODER) += msvideo1.o OBJS-$(CONFIG_MSZH_DECODER) += lcldec.o @@ -429,7 +431,7 @@ OBJS-$(CONFIG_WMV2_DECODER) += wmv2dec.o wmv2.o \ msmpeg4.o msmpeg4data.o \ intrax8.o intrax8dsp.o OBJS-$(CONFIG_WMV2_ENCODER) += wmv2enc.o wmv2.o \ - msmpeg4.o msmpeg4data.o \ + msmpeg4.o msmpeg4enc.o msmpeg4data.o \ mpeg4videodec.o ituh263dec.o h263dec.o OBJS-$(CONFIG_WNV1_DECODER) += wnv1.o OBJS-$(CONFIG_WS_SND1_DECODER) += ws-snd1.o diff --git a/libavcodec/msmpeg4.c b/libavcodec/msmpeg4.c index 1f3dc3a3a1..6cf0748ece 100644 --- a/libavcodec/msmpeg4.c +++ b/libavcodec/msmpeg4.c @@ -34,6 +34,7 @@ #include "libavutil/x86_cpu.h" #include "h263.h" #include "mpeg4video.h" +#include "msmpeg4data.h" #include "vc1data.h" /* @@ -52,22 +53,8 @@ #define V2_MV_VLC_BITS 9 #define TEX_VLC_BITS 9 -#define II_BITRATE 128*1024 -#define MBAC_BITRATE 50*1024 - #define DEFAULT_INTER_INDEX 3 -static uint32_t v2_dc_lum_table[512][2]; -static uint32_t v2_dc_chroma_table[512][2]; - -#include "msmpeg4data.h" - -#if CONFIG_ENCODERS //strangely gcc includes this even if it is not referenced -static uint8_t rl_length[NB_RL_TABLES][MAX_LEVEL+1][MAX_RUN+1][2]; -#endif //CONFIG_ENCODERS - -static uint8_t static_rl_table_store[NB_RL_TABLES][2][2*MAX_RUN + MAX_LEVEL + 3]; - /* This table is practically identical to the one from h263 * except that it is inverted. */ static av_cold void init_h263_dc_for_msmpeg4(void) @@ -102,8 +89,8 @@ static av_cold void init_h263_dc_for_msmpeg4(void) uni_len++; } } - v2_dc_lum_table[level+256][0]= uni_code; - v2_dc_lum_table[level+256][1]= uni_len; + ff_v2_dc_lum_table[level + 256][0] = uni_code; + ff_v2_dc_lum_table[level + 256][1] = uni_len; /* chrominance h263 */ uni_code= ff_mpeg4_DCtab_chrom[size][0]; @@ -118,13 +105,13 @@ static av_cold void init_h263_dc_for_msmpeg4(void) uni_len++; } } - v2_dc_chroma_table[level+256][0]= uni_code; - v2_dc_chroma_table[level+256][1]= uni_len; + ff_v2_dc_chroma_table[level + 256][0] = uni_code; + ff_v2_dc_chroma_table[level + 256][1] = uni_len; } } -static av_cold void common_init(MpegEncContext * s) +av_cold void ff_msmpeg4_common_init(MpegEncContext *s) { static int initialized=0; @@ -173,251 +160,6 @@ static av_cold void common_init(MpegEncContext * s) } } -#if CONFIG_ENCODERS - -/* build the table which associate a (x,y) motion vector to a vlc */ -static void init_mv_table(MVTable *tab) -{ - int i, x, y; - - tab->table_mv_index = av_malloc(sizeof(uint16_t) * 4096); - /* mark all entries as not used */ - for(i=0;i<4096;i++) - tab->table_mv_index[i] = tab->n; - - for(i=0;in;i++) { - x = tab->table_mvx[i]; - y = tab->table_mvy[i]; - tab->table_mv_index[(x << 6) | y] = i; - } -} - -void ff_msmpeg4_code012(PutBitContext *pb, int n) -{ - if (n == 0) { - put_bits(pb, 1, 0); - } else { - put_bits(pb, 1, 1); - put_bits(pb, 1, (n >= 2)); - } -} - -static int get_size_of_code(MpegEncContext * s, RLTable *rl, int last, int run, int level, int intra){ - int size=0; - int code; - int run_diff= intra ? 0 : 1; - - code = get_rl_index(rl, last, run, level); - size+= rl->table_vlc[code][1]; - if (code == rl->n) { - int level1, run1; - - level1 = level - rl->max_level[last][run]; - if (level1 < 1) - goto esc2; - code = get_rl_index(rl, last, run, level1); - if (code == rl->n) { - esc2: - size++; - if (level > MAX_LEVEL) - goto esc3; - run1 = run - rl->max_run[last][level] - run_diff; - if (run1 < 0) - goto esc3; - code = get_rl_index(rl, last, run1, level); - if (code == rl->n) { - esc3: - /* third escape */ - size+=1+1+6+8; - } else { - /* second escape */ - size+= 1+1+ rl->table_vlc[code][1]; - } - } else { - /* first escape */ - size+= 1+1+ rl->table_vlc[code][1]; - } - } else { - size++; - } - return size; -} - -av_cold void ff_msmpeg4_encode_init(MpegEncContext *s) -{ - static int init_done=0; - int i; - - common_init(s); - if(s->msmpeg4_version>=4){ - s->min_qcoeff= -255; - s->max_qcoeff= 255; - } - - if (!init_done) { - /* init various encoding tables */ - init_done = 1; - init_mv_table(&ff_mv_tables[0]); - init_mv_table(&ff_mv_tables[1]); - for(i=0;i0){// ;) - size++; - chroma_size++; - } - for(level=0; level<=MAX_LEVEL; level++){ - int run; - for(run=0; run<=MAX_RUN; run++){ - int last; - const int last_size= size + chroma_size; - for(last=0; last<2; last++){ - int inter_count = s->ac_stats[0][0][level][run][last] + s->ac_stats[0][1][level][run][last]; - int intra_luma_count = s->ac_stats[1][0][level][run][last]; - int intra_chroma_count= s->ac_stats[1][1][level][run][last]; - - if(s->pict_type==AV_PICTURE_TYPE_I){ - size += intra_luma_count *rl_length[i ][level][run][last]; - chroma_size+= intra_chroma_count*rl_length[i+3][level][run][last]; - }else{ - size+= intra_luma_count *rl_length[i ][level][run][last] - +intra_chroma_count*rl_length[i+3][level][run][last] - +inter_count *rl_length[i+3][level][run][last]; - } - } - if(last_size == size+chroma_size) break; - } - } - if(sizepict_type, best, s->qscale, s->mb_var_sum, s->mc_mb_var_sum, best_size); - - if(s->pict_type==AV_PICTURE_TYPE_P) chroma_best= best; - - memset(s->ac_stats, 0, sizeof(int)*(MAX_LEVEL+1)*(MAX_RUN+1)*2*2*2); - - s->rl_table_index = best; - s->rl_chroma_table_index= chroma_best; - - if(s->pict_type != s->last_non_b_pict_type){ - s->rl_table_index= 2; - if(s->pict_type==AV_PICTURE_TYPE_I) - s->rl_chroma_table_index= 1; - else - s->rl_chroma_table_index= 2; - } - -} - -/* write MSMPEG4 compatible frame header */ -void ff_msmpeg4_encode_picture_header(MpegEncContext * s, int picture_number) -{ - find_best_tables(s); - - avpriv_align_put_bits(&s->pb); - put_bits(&s->pb, 2, s->pict_type - 1); - - put_bits(&s->pb, 5, s->qscale); - if(s->msmpeg4_version<=2){ - s->rl_table_index = 2; - s->rl_chroma_table_index = 2; - } - - s->dc_table_index = 1; - s->mv_table_index = 1; /* only if P frame */ - s->use_skip_mb_code = 1; /* only if P frame */ - s->per_mb_rl_table = 0; - if(s->msmpeg4_version==4) - s->inter_intra_pred= (s->width*s->height < 320*240 && s->bit_rate<=II_BITRATE && s->pict_type==AV_PICTURE_TYPE_P); -//printf("%d %d %d %d %d\n", s->pict_type, s->bit_rate, s->inter_intra_pred, s->width, s->height); - - if (s->pict_type == AV_PICTURE_TYPE_I) { - s->slice_height= s->mb_height/1; - put_bits(&s->pb, 5, 0x16 + s->mb_height/s->slice_height); - - if(s->msmpeg4_version==4){ - ff_msmpeg4_encode_ext_header(s); - if(s->bit_rate>MBAC_BITRATE) - put_bits(&s->pb, 1, s->per_mb_rl_table); - } - - if(s->msmpeg4_version>2){ - if(!s->per_mb_rl_table){ - ff_msmpeg4_code012(&s->pb, s->rl_chroma_table_index); - ff_msmpeg4_code012(&s->pb, s->rl_table_index); - } - - put_bits(&s->pb, 1, s->dc_table_index); - } - } else { - put_bits(&s->pb, 1, s->use_skip_mb_code); - - if(s->msmpeg4_version==4 && s->bit_rate>MBAC_BITRATE) - put_bits(&s->pb, 1, s->per_mb_rl_table); - - if(s->msmpeg4_version>2){ - if(!s->per_mb_rl_table) - ff_msmpeg4_code012(&s->pb, s->rl_table_index); - - put_bits(&s->pb, 1, s->dc_table_index); - - put_bits(&s->pb, 1, s->mv_table_index); - } - } - - s->esc3_level_length= 0; - s->esc3_run_length= 0; -} - -void ff_msmpeg4_encode_ext_header(MpegEncContext * s) -{ - put_bits(&s->pb, 5, s->avctx->time_base.den / s->avctx->time_base.num); //yes 29.97 -> 29 - - put_bits(&s->pb, 11, FFMIN(s->bit_rate/1024, 2047)); - - if(s->msmpeg4_version>=3) - put_bits(&s->pb, 1, s->flipflop_rounding); - else - assert(s->flipflop_rounding==0); -} - -#endif //CONFIG_ENCODERS - /* predict coded block */ int ff_msmpeg4_coded_block_pred(MpegEncContext * s, int n, uint8_t **coded_block_ptr) { @@ -445,217 +187,6 @@ int ff_msmpeg4_coded_block_pred(MpegEncContext * s, int n, uint8_t **coded_block return pred; } -#if CONFIG_ENCODERS - -void ff_msmpeg4_encode_motion(MpegEncContext * s, - int mx, int my) -{ - int code; - MVTable *mv; - - /* modulo encoding */ - /* WARNING : you cannot reach all the MVs even with the modulo - encoding. This is a somewhat strange compromise they took !!! */ - if (mx <= -64) - mx += 64; - else if (mx >= 64) - mx -= 64; - if (my <= -64) - my += 64; - else if (my >= 64) - my -= 64; - - mx += 32; - my += 32; -#if 0 - if ((unsigned)mx >= 64 || - (unsigned)my >= 64) - av_log(s->avctx, AV_LOG_ERROR, "error mx=%d my=%d\n", mx, my); -#endif - mv = &ff_mv_tables[s->mv_table_index]; - - code = mv->table_mv_index[(mx << 6) | my]; - put_bits(&s->pb, - mv->table_mv_bits[code], - mv->table_mv_code[code]); - if (code == mv->n) { - /* escape : code literally */ - put_bits(&s->pb, 6, mx); - put_bits(&s->pb, 6, my); - } -} - -void ff_msmpeg4_handle_slices(MpegEncContext *s){ - if (s->mb_x == 0) { - if (s->slice_height && (s->mb_y % s->slice_height) == 0) { - if(s->msmpeg4_version < 4){ - ff_mpeg4_clean_buffers(s); - } - s->first_slice_line = 1; - } else { - s->first_slice_line = 0; - } - } -} - -static void msmpeg4v2_encode_motion(MpegEncContext * s, int val) -{ - int range, bit_size, sign, code, bits; - - if (val == 0) { - /* zero vector */ - code = 0; - put_bits(&s->pb, ff_mvtab[code][1], ff_mvtab[code][0]); - } else { - bit_size = s->f_code - 1; - range = 1 << bit_size; - if (val <= -64) - val += 64; - else if (val >= 64) - val -= 64; - - if (val >= 0) { - sign = 0; - } else { - val = -val; - sign = 1; - } - val--; - code = (val >> bit_size) + 1; - bits = val & (range - 1); - - put_bits(&s->pb, ff_mvtab[code][1] + 1, (ff_mvtab[code][0] << 1) | sign); - if (bit_size > 0) { - put_bits(&s->pb, bit_size, bits); - } - } -} - -void ff_msmpeg4_encode_mb(MpegEncContext * s, - DCTELEM block[6][64], - int motion_x, int motion_y) -{ - int cbp, coded_cbp, i; - int pred_x, pred_y; - uint8_t *coded_block; - - ff_msmpeg4_handle_slices(s); - - if (!s->mb_intra) { - /* compute cbp */ - cbp = 0; - for (i = 0; i < 6; i++) { - if (s->block_last_index[i] >= 0) - cbp |= 1 << (5 - i); - } - if (s->use_skip_mb_code && (cbp | motion_x | motion_y) == 0) { - /* skip macroblock */ - put_bits(&s->pb, 1, 1); - s->last_bits++; - s->misc_bits++; - s->skip_count++; - - return; - } - if (s->use_skip_mb_code) - put_bits(&s->pb, 1, 0); /* mb coded */ - - if(s->msmpeg4_version<=2){ - put_bits(&s->pb, - ff_v2_mb_type[cbp&3][1], - ff_v2_mb_type[cbp&3][0]); - if((cbp&3) != 3) coded_cbp= cbp ^ 0x3C; - else coded_cbp= cbp; - - put_bits(&s->pb, - ff_h263_cbpy_tab[coded_cbp>>2][1], - ff_h263_cbpy_tab[coded_cbp>>2][0]); - - s->misc_bits += get_bits_diff(s); - - ff_h263_pred_motion(s, 0, 0, &pred_x, &pred_y); - msmpeg4v2_encode_motion(s, motion_x - pred_x); - msmpeg4v2_encode_motion(s, motion_y - pred_y); - }else{ - put_bits(&s->pb, - ff_table_mb_non_intra[cbp + 64][1], - ff_table_mb_non_intra[cbp + 64][0]); - - s->misc_bits += get_bits_diff(s); - - /* motion vector */ - ff_h263_pred_motion(s, 0, 0, &pred_x, &pred_y); - ff_msmpeg4_encode_motion(s, motion_x - pred_x, - motion_y - pred_y); - } - - s->mv_bits += get_bits_diff(s); - - for (i = 0; i < 6; i++) { - ff_msmpeg4_encode_block(s, block[i], i); - } - s->p_tex_bits += get_bits_diff(s); - } else { - /* compute cbp */ - cbp = 0; - coded_cbp = 0; - for (i = 0; i < 6; i++) { - int val, pred; - val = (s->block_last_index[i] >= 1); - cbp |= val << (5 - i); - if (i < 4) { - /* predict value for close blocks only for luma */ - pred = ff_msmpeg4_coded_block_pred(s, i, &coded_block); - *coded_block = val; - val = val ^ pred; - } - coded_cbp |= val << (5 - i); - } - - if(s->msmpeg4_version<=2){ - if (s->pict_type == AV_PICTURE_TYPE_I) { - put_bits(&s->pb, - ff_v2_intra_cbpc[cbp&3][1], ff_v2_intra_cbpc[cbp&3][0]); - } else { - if (s->use_skip_mb_code) - put_bits(&s->pb, 1, 0); /* mb coded */ - put_bits(&s->pb, - ff_v2_mb_type[(cbp&3) + 4][1], - ff_v2_mb_type[(cbp&3) + 4][0]); - } - put_bits(&s->pb, 1, 0); /* no AC prediction yet */ - put_bits(&s->pb, - ff_h263_cbpy_tab[cbp>>2][1], - ff_h263_cbpy_tab[cbp>>2][0]); - }else{ - if (s->pict_type == AV_PICTURE_TYPE_I) { - put_bits(&s->pb, - ff_msmp4_mb_i_table[coded_cbp][1], ff_msmp4_mb_i_table[coded_cbp][0]); - } else { - if (s->use_skip_mb_code) - put_bits(&s->pb, 1, 0); /* mb coded */ - put_bits(&s->pb, - ff_table_mb_non_intra[cbp][1], - ff_table_mb_non_intra[cbp][0]); - } - put_bits(&s->pb, 1, 0); /* no AC prediction yet */ - if(s->inter_intra_pred){ - s->h263_aic_dir=0; - put_bits(&s->pb, ff_table_inter_intra[s->h263_aic_dir][1], ff_table_inter_intra[s->h263_aic_dir][0]); - } - } - s->misc_bits += get_bits_diff(s); - - for (i = 0; i < 6; i++) { - ff_msmpeg4_encode_block(s, block[i], i); - } - s->i_tex_bits += get_bits_diff(s); - s->i_count++; - } -} - -#endif //CONFIG_ENCODERS - static inline int msmpeg4v1_pred_dc(MpegEncContext * s, int n, int32_t **dc_val_ptr) { @@ -685,8 +216,8 @@ static int get_dc(uint8_t *src, int stride, int scale) } /* dir = 0: left, dir = 1: top prediction */ -static inline int msmpeg4_pred_dc(MpegEncContext * s, int n, - int16_t **dc_val_ptr, int *dir_ptr) +int ff_msmpeg4_pred_dc(MpegEncContext *s, int n, + int16_t **dc_val_ptr, int *dir_ptr) { int a, b, c, wrap, pred, scale; int16_t *dc_val; @@ -832,207 +363,6 @@ static inline int msmpeg4_pred_dc(MpegEncContext * s, int n, return pred; } -#define DC_MAX 119 - -static void msmpeg4_encode_dc(MpegEncContext * s, int level, int n, int *dir_ptr) -{ - int sign, code; - int pred, extquant; - int extrabits = 0; - - int16_t *dc_val; - pred = msmpeg4_pred_dc(s, n, &dc_val, dir_ptr); - - /* update predictor */ - if (n < 4) { - *dc_val = level * s->y_dc_scale; - } else { - *dc_val = level * s->c_dc_scale; - } - - /* do the prediction */ - level -= pred; - - if(s->msmpeg4_version<=2){ - if (n < 4) { - put_bits(&s->pb, - v2_dc_lum_table[level+256][1], - v2_dc_lum_table[level+256][0]); - }else{ - put_bits(&s->pb, - v2_dc_chroma_table[level+256][1], - v2_dc_chroma_table[level+256][0]); - } - }else{ - sign = 0; - if (level < 0) { - level = -level; - sign = 1; - } - code = level; - if (code > DC_MAX) - code = DC_MAX; - else if( s->msmpeg4_version>=6 ) { - if( s->qscale == 1 ) { - extquant = (level + 3) & 0x3; - code = ((level+3)>>2); - } else if( s->qscale == 2 ) { - extquant = (level + 1) & 0x1; - code = ((level+1)>>1); - } - } - - if (s->dc_table_index == 0) { - if (n < 4) { - put_bits(&s->pb, ff_table0_dc_lum[code][1], ff_table0_dc_lum[code][0]); - } else { - put_bits(&s->pb, ff_table0_dc_chroma[code][1], ff_table0_dc_chroma[code][0]); - } - } else { - if (n < 4) { - put_bits(&s->pb, ff_table1_dc_lum[code][1], ff_table1_dc_lum[code][0]); - } else { - put_bits(&s->pb, ff_table1_dc_chroma[code][1], ff_table1_dc_chroma[code][0]); - } - } - - if(s->msmpeg4_version>=6 && s->qscale<=2) - extrabits = 3 - s->qscale; - - if (code == DC_MAX) - put_bits(&s->pb, 8 + extrabits, level); - else if(extrabits > 0)//== VC1 && s->qscale<=2 - put_bits(&s->pb, extrabits, extquant); - - if (level != 0) { - put_bits(&s->pb, 1, sign); - } - } -} - -/* Encoding of a block. Very similar to MPEG4 except for a different - escape coding (same as H263) and more vlc tables. - */ -void ff_msmpeg4_encode_block(MpegEncContext * s, DCTELEM * block, int n) -{ - int level, run, last, i, j, last_index; - int last_non_zero, sign, slevel; - int code, run_diff, dc_pred_dir; - const RLTable *rl; - const uint8_t *scantable; - - if (s->mb_intra) { - msmpeg4_encode_dc(s, block[0], n, &dc_pred_dir); - i = 1; - if (n < 4) { - rl = &ff_rl_table[s->rl_table_index]; - } else { - rl = &ff_rl_table[3 + s->rl_chroma_table_index]; - } - run_diff = s->msmpeg4_version>=4; - scantable= s->intra_scantable.permutated; - } else { - i = 0; - rl = &ff_rl_table[3 + s->rl_table_index]; - if(s->msmpeg4_version<=2) - run_diff = 0; - else - run_diff = 1; - scantable= s->inter_scantable.permutated; - } - - /* recalculate block_last_index for M$ wmv1 */ - if(s->msmpeg4_version>=4 && s->msmpeg4_version<6 && s->block_last_index[n]>0){ - for(last_index=63; last_index>=0; last_index--){ - if(block[scantable[last_index]]) break; - } - s->block_last_index[n]= last_index; - }else - last_index = s->block_last_index[n]; - /* AC coefs */ - last_non_zero = i - 1; - for (; i <= last_index; i++) { - j = scantable[i]; - level = block[j]; - if (level) { - run = i - last_non_zero - 1; - last = (i == last_index); - sign = 0; - slevel = level; - if (level < 0) { - sign = 1; - level = -level; - } - - if(level<=MAX_LEVEL && run<=MAX_RUN){ - s->ac_stats[s->mb_intra][n>3][level][run][last]++; - } - - s->ac_stats[s->mb_intra][n > 3][40][63][0]++; //esc3 like - - code = get_rl_index(rl, last, run, level); - put_bits(&s->pb, rl->table_vlc[code][1], rl->table_vlc[code][0]); - if (code == rl->n) { - int level1, run1; - - level1 = level - rl->max_level[last][run]; - if (level1 < 1) - goto esc2; - code = get_rl_index(rl, last, run, level1); - if (code == rl->n) { - esc2: - put_bits(&s->pb, 1, 0); - if (level > MAX_LEVEL) - goto esc3; - run1 = run - rl->max_run[last][level] - run_diff; - if (run1 < 0) - goto esc3; - code = get_rl_index(rl, last, run1+1, level); - if (s->msmpeg4_version == 4 && code == rl->n) - goto esc3; - code = get_rl_index(rl, last, run1, level); - if (code == rl->n) { - esc3: - /* third escape */ - put_bits(&s->pb, 1, 0); - put_bits(&s->pb, 1, last); - if(s->msmpeg4_version>=4){ - if(s->esc3_level_length==0){ - s->esc3_level_length=8; - s->esc3_run_length= 6; - //ESCLVLSZ + ESCRUNSZ - if(s->qscale<8) - put_bits(&s->pb, 6 + (s->msmpeg4_version>=6), 3); - else - put_bits(&s->pb, 8, 3); - } - put_bits(&s->pb, s->esc3_run_length, run); - put_bits(&s->pb, 1, sign); - put_bits(&s->pb, s->esc3_level_length, level); - }else{ - put_bits(&s->pb, 6, run); - put_sbits(&s->pb, 8, slevel); - } - } else { - /* second escape */ - put_bits(&s->pb, 1, 1); - put_bits(&s->pb, rl->table_vlc[code][1], rl->table_vlc[code][0]); - put_bits(&s->pb, 1, sign); - } - } else { - /* first escape */ - put_bits(&s->pb, 1, 1); - put_bits(&s->pb, rl->table_vlc[code][1], rl->table_vlc[code][0]); - put_bits(&s->pb, 1, sign); - } - } else { - put_bits(&s->pb, 1, sign); - } - last_non_zero = i; - } - } -} - /****************************************/ /* decoding stuff */ @@ -1263,13 +593,13 @@ av_cold int ff_msmpeg4_decode_init(AVCodecContext *avctx) if (ff_h263_decode_init(avctx) < 0) return -1; - common_init(s); + ff_msmpeg4_common_init(s); if (!done) { done = 1; for(i=0;i + #include "config.h" #include "avcodec.h" #include "dsputil.h" #include "mpegvideo.h" +#include "msmpeg4data.h" +#include "put_bits.h" #define INTER_INTRA_VLC_BITS 3 #define MB_NON_INTRA_VLC_BITS 9 #define MB_INTRA_VLC_BITS 9 +#define II_BITRATE 128*1024 +#define MBAC_BITRATE 50*1024 + +#define DC_MAX 119 + extern VLC ff_mb_non_intra_vlc[4]; extern VLC ff_inter_intra_vlc; void ff_msmpeg4_code012(PutBitContext *pb, int n); +void ff_msmpeg4_common_init(MpegEncContext *s); void ff_msmpeg4_encode_block(MpegEncContext * s, DCTELEM * block, int n); void ff_msmpeg4_handle_slices(MpegEncContext *s); void ff_msmpeg4_encode_motion(MpegEncContext * s, int mx, int my); @@ -43,6 +53,8 @@ int ff_msmpeg4_coded_block_pred(MpegEncContext * s, int n, int ff_msmpeg4_decode_motion(MpegEncContext * s, int *mx_ptr, int *my_ptr); int ff_msmpeg4_decode_block(MpegEncContext * s, DCTELEM * block, int n, int coded, const uint8_t *scan_table); +int ff_msmpeg4_pred_dc(MpegEncContext *s, int n, + int16_t **dc_val_ptr, int *dir_ptr); int ff_wmv2_decode_mb(MpegEncContext *s, DCTELEM block[6][64]); #define CONFIG_MSMPEG4_DECODER (CONFIG_MSMPEG4V1_DECODER || \ diff --git a/libavcodec/msmpeg4data.c b/libavcodec/msmpeg4data.c index b3dc45490f..5721d8ff75 100644 --- a/libavcodec/msmpeg4data.c +++ b/libavcodec/msmpeg4data.c @@ -29,6 +29,10 @@ #include "msmpeg4data.h" +uint32_t ff_v2_dc_lum_table[512][2]; +uint32_t ff_v2_dc_chroma_table[512][2]; +uint8_t ff_static_rl_table_store[NB_RL_TABLES][2][2 * MAX_RUN + MAX_LEVEL + 3]; + VLC ff_msmp4_mb_i_vlc; VLC ff_msmp4_dc_luma_vlc[2]; VLC ff_msmp4_dc_chroma_vlc[2]; diff --git a/libavcodec/msmpeg4data.h b/libavcodec/msmpeg4data.h index c37664fab1..ca2dac14bd 100644 --- a/libavcodec/msmpeg4data.h +++ b/libavcodec/msmpeg4data.h @@ -59,6 +59,10 @@ extern const uint8_t ff_wmv1_scantable[WMV1_SCANTABLE_COUNT][64]; #define NB_RL_TABLES 6 extern RLTable ff_rl_table[NB_RL_TABLES]; +extern uint8_t ff_static_rl_table_store[NB_RL_TABLES][2][2 * MAX_RUN + MAX_LEVEL + 3]; + +extern uint32_t ff_v2_dc_lum_table[512][2]; +extern uint32_t ff_v2_dc_chroma_table[512][2]; extern const uint8_t ff_wmv1_y_dc_scale_table[32]; extern const uint8_t ff_wmv1_c_dc_scale_table[32]; diff --git a/libavcodec/msmpeg4enc.c b/libavcodec/msmpeg4enc.c new file mode 100644 index 0000000000..67490b53f6 --- /dev/null +++ b/libavcodec/msmpeg4enc.c @@ -0,0 +1,692 @@ +/* + * MSMPEG4 encoder backend + * Copyright (c) 2001 Fabrice Bellard + * Copyright (c) 2002-2004 Michael Niedermayer + * + * msmpeg4v1 & v2 stuff by Michael Niedermayer + * + * This file is part of Libav. + * + * Libav 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, + * 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 + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/** + * @file + * MSMPEG4 encoder backend + */ + +#include +#include + +#include "libavutil/avutil.h" +#include "libavutil/mem.h" +#include "mpegvideo.h" +#include "msmpeg4.h" +#include "h263.h" +#include "mpeg4video.h" +#include "msmpeg4.h" +#include "msmpeg4data.h" +#include "put_bits.h" +#include "rl.h" +#include "vc1data.h" + +static uint8_t rl_length[NB_RL_TABLES][MAX_LEVEL+1][MAX_RUN+1][2]; + +/* build the table which associate a (x,y) motion vector to a vlc */ +static void init_mv_table(MVTable *tab) +{ + int i, x, y; + + tab->table_mv_index = av_malloc(sizeof(uint16_t) * 4096); + /* mark all entries as not used */ + for(i=0;i<4096;i++) + tab->table_mv_index[i] = tab->n; + + for(i=0;in;i++) { + x = tab->table_mvx[i]; + y = tab->table_mvy[i]; + tab->table_mv_index[(x << 6) | y] = i; + } +} + +void ff_msmpeg4_code012(PutBitContext *pb, int n) +{ + if (n == 0) { + put_bits(pb, 1, 0); + } else { + put_bits(pb, 1, 1); + put_bits(pb, 1, (n >= 2)); + } +} + +static int get_size_of_code(MpegEncContext * s, RLTable *rl, int last, int run, int level, int intra){ + int size=0; + int code; + int run_diff= intra ? 0 : 1; + + code = get_rl_index(rl, last, run, level); + size+= rl->table_vlc[code][1]; + if (code == rl->n) { + int level1, run1; + + level1 = level - rl->max_level[last][run]; + if (level1 < 1) + goto esc2; + code = get_rl_index(rl, last, run, level1); + if (code == rl->n) { + esc2: + size++; + if (level > MAX_LEVEL) + goto esc3; + run1 = run - rl->max_run[last][level] - run_diff; + if (run1 < 0) + goto esc3; + code = get_rl_index(rl, last, run1, level); + if (code == rl->n) { + esc3: + /* third escape */ + size+=1+1+6+8; + } else { + /* second escape */ + size+= 1+1+ rl->table_vlc[code][1]; + } + } else { + /* first escape */ + size+= 1+1+ rl->table_vlc[code][1]; + } + } else { + size++; + } + return size; +} + +av_cold void ff_msmpeg4_encode_init(MpegEncContext *s) +{ + static int init_done=0; + int i; + + ff_msmpeg4_common_init(s); + if(s->msmpeg4_version>=4){ + s->min_qcoeff= -255; + s->max_qcoeff= 255; + } + + if (!init_done) { + /* init various encoding tables */ + init_done = 1; + init_mv_table(&ff_mv_tables[0]); + init_mv_table(&ff_mv_tables[1]); + for(i=0;i0){// ;) + size++; + chroma_size++; + } + for(level=0; level<=MAX_LEVEL; level++){ + int run; + for(run=0; run<=MAX_RUN; run++){ + int last; + const int last_size= size + chroma_size; + for(last=0; last<2; last++){ + int inter_count = s->ac_stats[0][0][level][run][last] + s->ac_stats[0][1][level][run][last]; + int intra_luma_count = s->ac_stats[1][0][level][run][last]; + int intra_chroma_count= s->ac_stats[1][1][level][run][last]; + + if(s->pict_type==AV_PICTURE_TYPE_I){ + size += intra_luma_count *rl_length[i ][level][run][last]; + chroma_size+= intra_chroma_count*rl_length[i+3][level][run][last]; + }else{ + size+= intra_luma_count *rl_length[i ][level][run][last] + +intra_chroma_count*rl_length[i+3][level][run][last] + +inter_count *rl_length[i+3][level][run][last]; + } + } + if(last_size == size+chroma_size) break; + } + } + if(sizepict_type, best, s->qscale, s->mb_var_sum, s->mc_mb_var_sum, best_size); + + if(s->pict_type==AV_PICTURE_TYPE_P) chroma_best= best; + + memset(s->ac_stats, 0, sizeof(int)*(MAX_LEVEL+1)*(MAX_RUN+1)*2*2*2); + + s->rl_table_index = best; + s->rl_chroma_table_index= chroma_best; + + if(s->pict_type != s->last_non_b_pict_type){ + s->rl_table_index= 2; + if(s->pict_type==AV_PICTURE_TYPE_I) + s->rl_chroma_table_index= 1; + else + s->rl_chroma_table_index= 2; + } + +} + +/* write MSMPEG4 compatible frame header */ +void ff_msmpeg4_encode_picture_header(MpegEncContext * s, int picture_number) +{ + find_best_tables(s); + + avpriv_align_put_bits(&s->pb); + put_bits(&s->pb, 2, s->pict_type - 1); + + put_bits(&s->pb, 5, s->qscale); + if(s->msmpeg4_version<=2){ + s->rl_table_index = 2; + s->rl_chroma_table_index = 2; + } + + s->dc_table_index = 1; + s->mv_table_index = 1; /* only if P frame */ + s->use_skip_mb_code = 1; /* only if P frame */ + s->per_mb_rl_table = 0; + if(s->msmpeg4_version==4) + s->inter_intra_pred= (s->width*s->height < 320*240 && s->bit_rate<=II_BITRATE && s->pict_type==AV_PICTURE_TYPE_P); +//printf("%d %d %d %d %d\n", s->pict_type, s->bit_rate, s->inter_intra_pred, s->width, s->height); + + if (s->pict_type == AV_PICTURE_TYPE_I) { + s->slice_height= s->mb_height/1; + put_bits(&s->pb, 5, 0x16 + s->mb_height/s->slice_height); + + if(s->msmpeg4_version==4){ + ff_msmpeg4_encode_ext_header(s); + if(s->bit_rate>MBAC_BITRATE) + put_bits(&s->pb, 1, s->per_mb_rl_table); + } + + if(s->msmpeg4_version>2){ + if(!s->per_mb_rl_table){ + ff_msmpeg4_code012(&s->pb, s->rl_chroma_table_index); + ff_msmpeg4_code012(&s->pb, s->rl_table_index); + } + + put_bits(&s->pb, 1, s->dc_table_index); + } + } else { + put_bits(&s->pb, 1, s->use_skip_mb_code); + + if(s->msmpeg4_version==4 && s->bit_rate>MBAC_BITRATE) + put_bits(&s->pb, 1, s->per_mb_rl_table); + + if(s->msmpeg4_version>2){ + if(!s->per_mb_rl_table) + ff_msmpeg4_code012(&s->pb, s->rl_table_index); + + put_bits(&s->pb, 1, s->dc_table_index); + + put_bits(&s->pb, 1, s->mv_table_index); + } + } + + s->esc3_level_length= 0; + s->esc3_run_length= 0; +} + +void ff_msmpeg4_encode_ext_header(MpegEncContext * s) +{ + put_bits(&s->pb, 5, s->avctx->time_base.den / s->avctx->time_base.num); //yes 29.97 -> 29 + + put_bits(&s->pb, 11, FFMIN(s->bit_rate/1024, 2047)); + + if(s->msmpeg4_version>=3) + put_bits(&s->pb, 1, s->flipflop_rounding); + else + assert(s->flipflop_rounding==0); +} + +void ff_msmpeg4_encode_motion(MpegEncContext * s, + int mx, int my) +{ + int code; + MVTable *mv; + + /* modulo encoding */ + /* WARNING : you cannot reach all the MVs even with the modulo + encoding. This is a somewhat strange compromise they took !!! */ + if (mx <= -64) + mx += 64; + else if (mx >= 64) + mx -= 64; + if (my <= -64) + my += 64; + else if (my >= 64) + my -= 64; + + mx += 32; + my += 32; +#if 0 + if ((unsigned)mx >= 64 || + (unsigned)my >= 64) + av_log(s->avctx, AV_LOG_ERROR, "error mx=%d my=%d\n", mx, my); +#endif + mv = &ff_mv_tables[s->mv_table_index]; + + code = mv->table_mv_index[(mx << 6) | my]; + put_bits(&s->pb, + mv->table_mv_bits[code], + mv->table_mv_code[code]); + if (code == mv->n) { + /* escape : code literally */ + put_bits(&s->pb, 6, mx); + put_bits(&s->pb, 6, my); + } +} + +void ff_msmpeg4_handle_slices(MpegEncContext *s){ + if (s->mb_x == 0) { + if (s->slice_height && (s->mb_y % s->slice_height) == 0) { + if(s->msmpeg4_version < 4){ + ff_mpeg4_clean_buffers(s); + } + s->first_slice_line = 1; + } else { + s->first_slice_line = 0; + } + } +} + +static void msmpeg4v2_encode_motion(MpegEncContext * s, int val) +{ + int range, bit_size, sign, code, bits; + + if (val == 0) { + /* zero vector */ + code = 0; + put_bits(&s->pb, ff_mvtab[code][1], ff_mvtab[code][0]); + } else { + bit_size = s->f_code - 1; + range = 1 << bit_size; + if (val <= -64) + val += 64; + else if (val >= 64) + val -= 64; + + if (val >= 0) { + sign = 0; + } else { + val = -val; + sign = 1; + } + val--; + code = (val >> bit_size) + 1; + bits = val & (range - 1); + + put_bits(&s->pb, ff_mvtab[code][1] + 1, (ff_mvtab[code][0] << 1) | sign); + if (bit_size > 0) { + put_bits(&s->pb, bit_size, bits); + } + } +} + +void ff_msmpeg4_encode_mb(MpegEncContext * s, + DCTELEM block[6][64], + int motion_x, int motion_y) +{ + int cbp, coded_cbp, i; + int pred_x, pred_y; + uint8_t *coded_block; + + ff_msmpeg4_handle_slices(s); + + if (!s->mb_intra) { + /* compute cbp */ + cbp = 0; + for (i = 0; i < 6; i++) { + if (s->block_last_index[i] >= 0) + cbp |= 1 << (5 - i); + } + if (s->use_skip_mb_code && (cbp | motion_x | motion_y) == 0) { + /* skip macroblock */ + put_bits(&s->pb, 1, 1); + s->last_bits++; + s->misc_bits++; + s->skip_count++; + + return; + } + if (s->use_skip_mb_code) + put_bits(&s->pb, 1, 0); /* mb coded */ + + if(s->msmpeg4_version<=2){ + put_bits(&s->pb, + ff_v2_mb_type[cbp&3][1], + ff_v2_mb_type[cbp&3][0]); + if((cbp&3) != 3) coded_cbp= cbp ^ 0x3C; + else coded_cbp= cbp; + + put_bits(&s->pb, + ff_h263_cbpy_tab[coded_cbp>>2][1], + ff_h263_cbpy_tab[coded_cbp>>2][0]); + + s->misc_bits += get_bits_diff(s); + + ff_h263_pred_motion(s, 0, 0, &pred_x, &pred_y); + msmpeg4v2_encode_motion(s, motion_x - pred_x); + msmpeg4v2_encode_motion(s, motion_y - pred_y); + }else{ + put_bits(&s->pb, + ff_table_mb_non_intra[cbp + 64][1], + ff_table_mb_non_intra[cbp + 64][0]); + + s->misc_bits += get_bits_diff(s); + + /* motion vector */ + ff_h263_pred_motion(s, 0, 0, &pred_x, &pred_y); + ff_msmpeg4_encode_motion(s, motion_x - pred_x, + motion_y - pred_y); + } + + s->mv_bits += get_bits_diff(s); + + for (i = 0; i < 6; i++) { + ff_msmpeg4_encode_block(s, block[i], i); + } + s->p_tex_bits += get_bits_diff(s); + } else { + /* compute cbp */ + cbp = 0; + coded_cbp = 0; + for (i = 0; i < 6; i++) { + int val, pred; + val = (s->block_last_index[i] >= 1); + cbp |= val << (5 - i); + if (i < 4) { + /* predict value for close blocks only for luma */ + pred = ff_msmpeg4_coded_block_pred(s, i, &coded_block); + *coded_block = val; + val = val ^ pred; + } + coded_cbp |= val << (5 - i); + } + + if(s->msmpeg4_version<=2){ + if (s->pict_type == AV_PICTURE_TYPE_I) { + put_bits(&s->pb, + ff_v2_intra_cbpc[cbp&3][1], ff_v2_intra_cbpc[cbp&3][0]); + } else { + if (s->use_skip_mb_code) + put_bits(&s->pb, 1, 0); /* mb coded */ + put_bits(&s->pb, + ff_v2_mb_type[(cbp&3) + 4][1], + ff_v2_mb_type[(cbp&3) + 4][0]); + } + put_bits(&s->pb, 1, 0); /* no AC prediction yet */ + put_bits(&s->pb, + ff_h263_cbpy_tab[cbp>>2][1], + ff_h263_cbpy_tab[cbp>>2][0]); + }else{ + if (s->pict_type == AV_PICTURE_TYPE_I) { + put_bits(&s->pb, + ff_msmp4_mb_i_table[coded_cbp][1], ff_msmp4_mb_i_table[coded_cbp][0]); + } else { + if (s->use_skip_mb_code) + put_bits(&s->pb, 1, 0); /* mb coded */ + put_bits(&s->pb, + ff_table_mb_non_intra[cbp][1], + ff_table_mb_non_intra[cbp][0]); + } + put_bits(&s->pb, 1, 0); /* no AC prediction yet */ + if(s->inter_intra_pred){ + s->h263_aic_dir=0; + put_bits(&s->pb, ff_table_inter_intra[s->h263_aic_dir][1], ff_table_inter_intra[s->h263_aic_dir][0]); + } + } + s->misc_bits += get_bits_diff(s); + + for (i = 0; i < 6; i++) { + ff_msmpeg4_encode_block(s, block[i], i); + } + s->i_tex_bits += get_bits_diff(s); + s->i_count++; + } +} + +static void msmpeg4_encode_dc(MpegEncContext * s, int level, int n, int *dir_ptr) +{ + int sign, code; + int pred, extquant; + int extrabits = 0; + + int16_t *dc_val; + pred = ff_msmpeg4_pred_dc(s, n, &dc_val, dir_ptr); + + /* update predictor */ + if (n < 4) { + *dc_val = level * s->y_dc_scale; + } else { + *dc_val = level * s->c_dc_scale; + } + + /* do the prediction */ + level -= pred; + + if(s->msmpeg4_version<=2){ + if (n < 4) { + put_bits(&s->pb, + ff_v2_dc_lum_table[level + 256][1], + ff_v2_dc_lum_table[level + 256][0]); + }else{ + put_bits(&s->pb, + ff_v2_dc_chroma_table[level + 256][1], + ff_v2_dc_chroma_table[level + 256][0]); + } + }else{ + sign = 0; + if (level < 0) { + level = -level; + sign = 1; + } + code = level; + if (code > DC_MAX) + code = DC_MAX; + else if( s->msmpeg4_version>=6 ) { + if( s->qscale == 1 ) { + extquant = (level + 3) & 0x3; + code = ((level+3)>>2); + } else if( s->qscale == 2 ) { + extquant = (level + 1) & 0x1; + code = ((level+1)>>1); + } + } + + if (s->dc_table_index == 0) { + if (n < 4) { + put_bits(&s->pb, ff_table0_dc_lum[code][1], ff_table0_dc_lum[code][0]); + } else { + put_bits(&s->pb, ff_table0_dc_chroma[code][1], ff_table0_dc_chroma[code][0]); + } + } else { + if (n < 4) { + put_bits(&s->pb, ff_table1_dc_lum[code][1], ff_table1_dc_lum[code][0]); + } else { + put_bits(&s->pb, ff_table1_dc_chroma[code][1], ff_table1_dc_chroma[code][0]); + } + } + + if(s->msmpeg4_version>=6 && s->qscale<=2) + extrabits = 3 - s->qscale; + + if (code == DC_MAX) + put_bits(&s->pb, 8 + extrabits, level); + else if(extrabits > 0)//== VC1 && s->qscale<=2 + put_bits(&s->pb, extrabits, extquant); + + if (level != 0) { + put_bits(&s->pb, 1, sign); + } + } +} + +/* Encoding of a block. Very similar to MPEG4 except for a different + escape coding (same as H263) and more vlc tables. + */ +void ff_msmpeg4_encode_block(MpegEncContext * s, DCTELEM * block, int n) +{ + int level, run, last, i, j, last_index; + int last_non_zero, sign, slevel; + int code, run_diff, dc_pred_dir; + const RLTable *rl; + const uint8_t *scantable; + + if (s->mb_intra) { + msmpeg4_encode_dc(s, block[0], n, &dc_pred_dir); + i = 1; + if (n < 4) { + rl = &ff_rl_table[s->rl_table_index]; + } else { + rl = &ff_rl_table[3 + s->rl_chroma_table_index]; + } + run_diff = s->msmpeg4_version>=4; + scantable= s->intra_scantable.permutated; + } else { + i = 0; + rl = &ff_rl_table[3 + s->rl_table_index]; + if(s->msmpeg4_version<=2) + run_diff = 0; + else + run_diff = 1; + scantable= s->inter_scantable.permutated; + } + + /* recalculate block_last_index for M$ wmv1 */ + if(s->msmpeg4_version>=4 && s->msmpeg4_version<6 && s->block_last_index[n]>0){ + for(last_index=63; last_index>=0; last_index--){ + if(block[scantable[last_index]]) break; + } + s->block_last_index[n]= last_index; + }else + last_index = s->block_last_index[n]; + /* AC coefs */ + last_non_zero = i - 1; + for (; i <= last_index; i++) { + j = scantable[i]; + level = block[j]; + if (level) { + run = i - last_non_zero - 1; + last = (i == last_index); + sign = 0; + slevel = level; + if (level < 0) { + sign = 1; + level = -level; + } + + if(level<=MAX_LEVEL && run<=MAX_RUN){ + s->ac_stats[s->mb_intra][n>3][level][run][last]++; + } + + s->ac_stats[s->mb_intra][n > 3][40][63][0]++; //esc3 like + + code = get_rl_index(rl, last, run, level); + put_bits(&s->pb, rl->table_vlc[code][1], rl->table_vlc[code][0]); + if (code == rl->n) { + int level1, run1; + + level1 = level - rl->max_level[last][run]; + if (level1 < 1) + goto esc2; + code = get_rl_index(rl, last, run, level1); + if (code == rl->n) { + esc2: + put_bits(&s->pb, 1, 0); + if (level > MAX_LEVEL) + goto esc3; + run1 = run - rl->max_run[last][level] - run_diff; + if (run1 < 0) + goto esc3; + code = get_rl_index(rl, last, run1+1, level); + if (s->msmpeg4_version == 4 && code == rl->n) + goto esc3; + code = get_rl_index(rl, last, run1, level); + if (code == rl->n) { + esc3: + /* third escape */ + put_bits(&s->pb, 1, 0); + put_bits(&s->pb, 1, last); + if(s->msmpeg4_version>=4){ + if(s->esc3_level_length==0){ + s->esc3_level_length=8; + s->esc3_run_length= 6; + //ESCLVLSZ + ESCRUNSZ + if(s->qscale<8) + put_bits(&s->pb, 6 + (s->msmpeg4_version>=6), 3); + else + put_bits(&s->pb, 8, 3); + } + put_bits(&s->pb, s->esc3_run_length, run); + put_bits(&s->pb, 1, sign); + put_bits(&s->pb, s->esc3_level_length, level); + }else{ + put_bits(&s->pb, 6, run); + put_sbits(&s->pb, 8, slevel); + } + } else { + /* second escape */ + put_bits(&s->pb, 1, 1); + put_bits(&s->pb, rl->table_vlc[code][1], rl->table_vlc[code][0]); + put_bits(&s->pb, 1, sign); + } + } else { + /* first escape */ + put_bits(&s->pb, 1, 1); + put_bits(&s->pb, rl->table_vlc[code][1], rl->table_vlc[code][0]); + put_bits(&s->pb, 1, sign); + } + } else { + put_bits(&s->pb, 1, sign); + } + last_non_zero = i; + } + } +} -- cgit v1.2.3 From 562b6c744abdde4e673038fcb0c126a4aadfa6c7 Mon Sep 17 00:00:00 2001 From: Diego Biurrun Date: Mon, 27 Feb 2012 08:51:20 +0100 Subject: Remove unnecessary AVFrame pointer casts. --- libavcodec/a64multienc.c | 2 +- libavcodec/avs.c | 2 +- libavcodec/bmp.c | 4 ++-- libavcodec/bmpenc.c | 6 +++--- libavcodec/fraps.c | 4 ++-- libavcodec/gif.c | 2 +- libavcodec/indeo2.c | 2 +- libavcodec/jpeglsenc.c | 2 +- libavcodec/loco.c | 2 +- libavcodec/mdec.c | 2 +- libavcodec/pamenc.c | 2 +- libavcodec/pnm.c | 4 ++-- libavcodec/pnmdec.c | 2 +- libavcodec/pnmenc.c | 2 +- libavcodec/qdrw.c | 2 +- libavcodec/qpeg.c | 4 ++-- libavcodec/rawdec.c | 4 ++-- libavcodec/rawenc.c | 2 +- libavcodec/svq1enc.c | 4 ++-- libavcodec/targa.c | 6 +++--- libavcodec/tiff.c | 6 +++--- libavcodec/tiffenc.c | 2 +- libavcodec/truemotion2.c | 2 +- libavcodec/ulti.c | 2 +- libavcodec/vcr1.c | 6 +++--- libavcodec/wnv1.c | 2 +- libavcodec/xl.c | 2 +- libavcodec/zmbvenc.c | 2 +- 28 files changed, 42 insertions(+), 42 deletions(-) (limited to 'libavcodec') diff --git a/libavcodec/a64multienc.c b/libavcodec/a64multienc.c index cb2425fdf9..363b80c3ac 100644 --- a/libavcodec/a64multienc.c +++ b/libavcodec/a64multienc.c @@ -246,7 +246,7 @@ static int a64multi_encode_frame(AVCodecContext *avctx, AVPacket *pkt, const AVFrame *pict, int *got_packet) { A64Context *c = avctx->priv_data; - AVFrame *const p = (AVFrame *) & c->picture; + AVFrame *const p = &c->picture; int frame; int x, y; diff --git a/libavcodec/avs.c b/libavcodec/avs.c index b3cd5b1478..ce119ebd72 100644 --- a/libavcodec/avs.c +++ b/libavcodec/avs.c @@ -51,7 +51,7 @@ avs_decode_frame(AVCodecContext * avctx, int buf_size = avpkt->size; AvsContext *const avs = avctx->priv_data; AVFrame *picture = data; - AVFrame *const p = (AVFrame *) & avs->picture; + AVFrame *const p = &avs->picture; const uint8_t *table, *vect; uint8_t *out; int i, j, x, y, stride, vect_w = 3, vect_h = 3; diff --git a/libavcodec/bmp.c b/libavcodec/bmp.c index 1f725f5369..4d586dc89b 100644 --- a/libavcodec/bmp.c +++ b/libavcodec/bmp.c @@ -27,8 +27,8 @@ static av_cold int bmp_decode_init(AVCodecContext *avctx){ BMPContext *s = avctx->priv_data; - avcodec_get_frame_defaults((AVFrame*)&s->picture); - avctx->coded_frame = (AVFrame*)&s->picture; + avcodec_get_frame_defaults(&s->picture); + avctx->coded_frame = &s->picture; return 0; } diff --git a/libavcodec/bmpenc.c b/libavcodec/bmpenc.c index 3747784183..0bbbb61315 100644 --- a/libavcodec/bmpenc.c +++ b/libavcodec/bmpenc.c @@ -33,8 +33,8 @@ static const uint32_t rgb444_masks[] = { 0x0F00, 0x00F0, 0x000F }; static av_cold int bmp_encode_init(AVCodecContext *avctx){ BMPContext *s = avctx->priv_data; - avcodec_get_frame_defaults((AVFrame*)&s->picture); - avctx->coded_frame = (AVFrame*)&s->picture; + avcodec_get_frame_defaults(&s->picture); + avctx->coded_frame = &s->picture; switch (avctx->pix_fmt) { case PIX_FMT_BGR24: @@ -68,7 +68,7 @@ static int bmp_encode_frame(AVCodecContext *avctx, AVPacket *pkt, const AVFrame *pict, int *got_packet) { BMPContext *s = avctx->priv_data; - AVFrame * const p= (AVFrame*)&s->picture; + AVFrame * const p = &s->picture; int n_bytes_image, n_bytes_per_row, n_bytes, i, n, hsize, ret; const uint32_t *pal = NULL; int pad_bytes_per_row, pal_entries = 0, compression = BMP_RGB; diff --git a/libavcodec/fraps.c b/libavcodec/fraps.c index e2355d8f2f..dc74b5112f 100644 --- a/libavcodec/fraps.c +++ b/libavcodec/fraps.c @@ -60,7 +60,7 @@ static av_cold int decode_init(AVCodecContext *avctx) { FrapsContext * const s = avctx->priv_data; - avctx->coded_frame = (AVFrame*)&s->frame; + avctx->coded_frame = &s->frame; avctx->pix_fmt= PIX_FMT_NONE; /* set in decode_frame */ s->avctx = avctx; @@ -131,7 +131,7 @@ static int decode_frame(AVCodecContext *avctx, int buf_size = avpkt->size; FrapsContext * const s = avctx->priv_data; AVFrame *frame = data; - AVFrame * const f = (AVFrame*)&s->frame; + AVFrame * const f = &s->frame; uint32_t header; unsigned int version,header_size; unsigned int x, y; diff --git a/libavcodec/gif.c b/libavcodec/gif.c index 6b190f1d0c..d5ceb0d05e 100644 --- a/libavcodec/gif.c +++ b/libavcodec/gif.c @@ -146,7 +146,7 @@ static int gif_encode_frame(AVCodecContext *avctx, AVPacket *pkt, const AVFrame *pict, int *got_packet) { GIFContext *s = avctx->priv_data; - AVFrame *const p = (AVFrame *)&s->picture; + AVFrame *const p = &s->picture; uint8_t *outbuf_ptr, *end; int ret; diff --git a/libavcodec/indeo2.c b/libavcodec/indeo2.c index ecf89cc817..b114573ff0 100644 --- a/libavcodec/indeo2.c +++ b/libavcodec/indeo2.c @@ -143,7 +143,7 @@ static int ir2_decode_frame(AVCodecContext *avctx, int buf_size = avpkt->size; Ir2Context * const s = avctx->priv_data; AVFrame *picture = data; - AVFrame * const p= (AVFrame*)&s->picture; + AVFrame * const p = &s->picture; int start; if(p->data[0]) diff --git a/libavcodec/jpeglsenc.c b/libavcodec/jpeglsenc.c index f264c79ae7..d3f2e0fe84 100644 --- a/libavcodec/jpeglsenc.c +++ b/libavcodec/jpeglsenc.c @@ -232,7 +232,7 @@ static int encode_picture_ls(AVCodecContext *avctx, AVPacket *pkt, const AVFrame *pict, int *got_packet) { JpeglsContext * const s = avctx->priv_data; - AVFrame * const p= (AVFrame*)&s->picture; + AVFrame * const p = &s->picture; const int near = avctx->prediction_method; PutBitContext pb, pb2; GetBitContext gb; diff --git a/libavcodec/loco.c b/libavcodec/loco.c index 919a06b123..22b165db53 100644 --- a/libavcodec/loco.c +++ b/libavcodec/loco.c @@ -163,7 +163,7 @@ static int decode_frame(AVCodecContext *avctx, const uint8_t *buf = avpkt->data; int buf_size = avpkt->size; LOCOContext * const l = avctx->priv_data; - AVFrame * const p= (AVFrame*)&l->pic; + AVFrame * const p = &l->pic; int decoded; if(p->data[0]) diff --git a/libavcodec/mdec.c b/libavcodec/mdec.c index 3ce24641d4..391cecfb65 100644 --- a/libavcodec/mdec.c +++ b/libavcodec/mdec.c @@ -242,7 +242,7 @@ static av_cold int decode_init(AVCodecContext *avctx){ static av_cold int decode_init_thread_copy(AVCodecContext *avctx){ MDECContext * const a = avctx->priv_data; - AVFrame *p = (AVFrame*)&a->picture; + AVFrame *p = &a->picture; avctx->coded_frame = p; a->avctx= avctx; diff --git a/libavcodec/pamenc.c b/libavcodec/pamenc.c index 599b7e9a27..4802ca396d 100644 --- a/libavcodec/pamenc.c +++ b/libavcodec/pamenc.c @@ -29,7 +29,7 @@ static int pam_encode_frame(AVCodecContext *avctx, AVPacket *pkt, const AVFrame *pict, int *got_packet) { PNMContext *s = avctx->priv_data; - AVFrame * const p = (AVFrame*)&s->picture; + AVFrame * const p = &s->picture; int i, h, w, n, linesize, depth, maxval, ret; const char *tuple_type; uint8_t *ptr; diff --git a/libavcodec/pnm.c b/libavcodec/pnm.c index f6e6d53ec9..6d72f234c1 100644 --- a/libavcodec/pnm.c +++ b/libavcodec/pnm.c @@ -189,8 +189,8 @@ av_cold int ff_pnm_init(AVCodecContext *avctx) { PNMContext *s = avctx->priv_data; - avcodec_get_frame_defaults((AVFrame*)&s->picture); - avctx->coded_frame = (AVFrame*)&s->picture; + avcodec_get_frame_defaults(&s->picture); + avctx->coded_frame = &s->picture; return 0; } diff --git a/libavcodec/pnmdec.c b/libavcodec/pnmdec.c index c5d236f971..ada0fd8a36 100644 --- a/libavcodec/pnmdec.c +++ b/libavcodec/pnmdec.c @@ -32,7 +32,7 @@ static int pnm_decode_frame(AVCodecContext *avctx, void *data, int buf_size = avpkt->size; PNMContext * const s = avctx->priv_data; AVFrame *picture = data; - AVFrame * const p = (AVFrame*)&s->picture; + AVFrame * const p = &s->picture; int i, j, n, linesize, h, upgrade = 0; unsigned char *ptr; int components, sample_len; diff --git a/libavcodec/pnmenc.c b/libavcodec/pnmenc.c index 40621c852e..843629e8b9 100644 --- a/libavcodec/pnmenc.c +++ b/libavcodec/pnmenc.c @@ -29,7 +29,7 @@ static int pnm_encode_frame(AVCodecContext *avctx, AVPacket *pkt, const AVFrame *pict, int *got_packet) { PNMContext *s = avctx->priv_data; - AVFrame * const p = (AVFrame*)&s->picture; + AVFrame * const p = &s->picture; int i, h, h1, c, n, linesize, ret; uint8_t *ptr, *ptr1, *ptr2; diff --git a/libavcodec/qdrw.c b/libavcodec/qdrw.c index 7410f6e152..baf5de3e95 100644 --- a/libavcodec/qdrw.c +++ b/libavcodec/qdrw.c @@ -40,7 +40,7 @@ static int decode_frame(AVCodecContext *avctx, const uint8_t *buf_end = avpkt->data + avpkt->size; int buf_size = avpkt->size; QdrawContext * const a = avctx->priv_data; - AVFrame * const p= (AVFrame*)&a->pic; + AVFrame * const p = &a->pic; uint8_t* outdata; int colors; int i; diff --git a/libavcodec/qpeg.c b/libavcodec/qpeg.c index 9513dd0ad3..0f1bcd7ac9 100644 --- a/libavcodec/qpeg.c +++ b/libavcodec/qpeg.c @@ -254,7 +254,7 @@ static int decode_frame(AVCodecContext *avctx, const uint8_t *buf = avpkt->data; int buf_size = avpkt->size; QpegContext * const a = avctx->priv_data; - AVFrame * const p= (AVFrame*)&a->pic; + AVFrame * const p = &a->pic; uint8_t* outdata; int delta; const uint8_t *pal = av_packet_get_side_data(avpkt, AV_PKT_DATA_PALETTE, NULL); @@ -297,7 +297,7 @@ static av_cold int decode_init(AVCodecContext *avctx){ static av_cold int decode_end(AVCodecContext *avctx){ QpegContext * const a = avctx->priv_data; - AVFrame * const p= (AVFrame*)&a->pic; + AVFrame * const p = &a->pic; if(p->data[0]) avctx->release_buffer(avctx, p); diff --git a/libavcodec/rawdec.c b/libavcodec/rawdec.c index bb93129027..d3c816580a 100644 --- a/libavcodec/rawdec.c +++ b/libavcodec/rawdec.c @@ -120,8 +120,8 @@ static int raw_decode(AVCodecContext *avctx, int buf_size = avpkt->size; RawVideoContext *context = avctx->priv_data; - AVFrame * frame = (AVFrame *) data; - AVPicture * picture = (AVPicture *) data; + AVFrame *frame = data; + AVPicture *picture = data; frame->pict_type = avctx->coded_frame->pict_type; frame->interlaced_frame = avctx->coded_frame->interlaced_frame; diff --git a/libavcodec/rawenc.c b/libavcodec/rawenc.c index 8eb818c618..f435333fef 100644 --- a/libavcodec/rawenc.c +++ b/libavcodec/rawenc.c @@ -32,7 +32,7 @@ static av_cold int raw_init_encoder(AVCodecContext *avctx) { - avctx->coded_frame = (AVFrame *)avctx->priv_data; + avctx->coded_frame = avctx->priv_data; avctx->coded_frame->pict_type = AV_PICTURE_TYPE_I; avctx->coded_frame->key_frame = 1; avctx->bits_per_coded_sample = av_get_bits_per_pixel(&av_pix_fmt_descriptors[avctx->pix_fmt]); diff --git a/libavcodec/svq1enc.c b/libavcodec/svq1enc.c index 864c4ac962..c2c927c6c4 100644 --- a/libavcodec/svq1enc.c +++ b/libavcodec/svq1enc.c @@ -473,7 +473,7 @@ static av_cold int svq1_encode_init(AVCodecContext *avctx) SVQ1Context * const s = avctx->priv_data; ff_dsputil_init(&s->dsp, avctx); - avctx->coded_frame= (AVFrame*)&s->picture; + avctx->coded_frame = &s->picture; s->frame_width = avctx->width; s->frame_height = avctx->height; @@ -501,7 +501,7 @@ static int svq1_encode_frame(AVCodecContext *avctx, AVPacket *pkt, const AVFrame *pict, int *got_packet) { SVQ1Context * const s = avctx->priv_data; - AVFrame * const p= (AVFrame*)&s->picture; + AVFrame * const p = &s->picture; AVFrame temp; int i, ret; diff --git a/libavcodec/targa.c b/libavcodec/targa.c index 00da7587d0..94a50fbb79 100644 --- a/libavcodec/targa.c +++ b/libavcodec/targa.c @@ -106,7 +106,7 @@ static int decode_frame(AVCodecContext *avctx, const uint8_t *buf_end = avpkt->data + avpkt->size; TargaContext * const s = avctx->priv_data; AVFrame *picture = data; - AVFrame * const p= (AVFrame*)&s->picture; + AVFrame * const p = &s->picture; uint8_t *dst; int stride; int idlen, compr, y, w, h, bpp, flags; @@ -257,8 +257,8 @@ static int decode_frame(AVCodecContext *avctx, static av_cold int targa_init(AVCodecContext *avctx){ TargaContext *s = avctx->priv_data; - avcodec_get_frame_defaults((AVFrame*)&s->picture); - avctx->coded_frame= (AVFrame*)&s->picture; + avcodec_get_frame_defaults(&s->picture); + avctx->coded_frame = &s->picture; return 0; } diff --git a/libavcodec/tiff.c b/libavcodec/tiff.c index d807149922..57720a5018 100644 --- a/libavcodec/tiff.c +++ b/libavcodec/tiff.c @@ -506,7 +506,7 @@ static int decode_frame(AVCodecContext *avctx, int buf_size = avpkt->size; TiffContext * const s = avctx->priv_data; AVFrame *picture = data; - AVFrame * const p= (AVFrame*)&s->picture; + AVFrame * const p = &s->picture; const uint8_t *orig_buf = buf, *end_buf = buf + buf_size; unsigned off; int id, le, ret; @@ -619,8 +619,8 @@ static av_cold int tiff_init(AVCodecContext *avctx){ s->width = 0; s->height = 0; s->avctx = avctx; - avcodec_get_frame_defaults((AVFrame*)&s->picture); - avctx->coded_frame= (AVFrame*)&s->picture; + avcodec_get_frame_defaults(&s->picture); + avctx->coded_frame = &s->picture; ff_lzw_decode_open(&s->lzw); ff_ccitt_unpack_init(); diff --git a/libavcodec/tiffenc.c b/libavcodec/tiffenc.c index f85b1577ca..50fee906e9 100644 --- a/libavcodec/tiffenc.c +++ b/libavcodec/tiffenc.c @@ -204,7 +204,7 @@ static int encode_frame(AVCodecContext * avctx, AVPacket *pkt, const AVFrame *pict, int *got_packet) { TiffEncoderContext *s = avctx->priv_data; - AVFrame *const p = (AVFrame *) & s->picture; + AVFrame *const p = &s->picture; int i; uint8_t *ptr; uint8_t *offset; diff --git a/libavcodec/truemotion2.c b/libavcodec/truemotion2.c index 7be148c602..97feaf1f37 100644 --- a/libavcodec/truemotion2.c +++ b/libavcodec/truemotion2.c @@ -764,7 +764,7 @@ static int decode_frame(AVCodecContext *avctx, const uint8_t *buf = avpkt->data; int buf_size = avpkt->size; TM2Context * const l = avctx->priv_data; - AVFrame * const p= (AVFrame*)&l->pic; + AVFrame * const p = &l->pic; int i, skip, t; uint8_t *swbuf; diff --git a/libavcodec/ulti.c b/libavcodec/ulti.c index 96f13e430a..b671d91fd3 100644 --- a/libavcodec/ulti.c +++ b/libavcodec/ulti.c @@ -50,7 +50,7 @@ static av_cold int ulti_decode_init(AVCodecContext *avctx) s->height = avctx->height; s->blocks = (s->width / 8) * (s->height / 8); avctx->pix_fmt = PIX_FMT_YUV410P; - avctx->coded_frame = (AVFrame*) &s->frame; + avctx->coded_frame = &s->frame; s->ulti_codebook = ulti_codebook; return 0; diff --git a/libavcodec/vcr1.c b/libavcodec/vcr1.c index e50e092c7e..bace3a34b8 100644 --- a/libavcodec/vcr1.c +++ b/libavcodec/vcr1.c @@ -49,7 +49,7 @@ static int decode_frame(AVCodecContext *avctx, int buf_size = avpkt->size; VCR1Context * const a = avctx->priv_data; AVFrame *picture = data; - AVFrame * const p= (AVFrame*)&a->picture; + AVFrame * const p = &a->picture; const uint8_t *bytestream= buf; int i, x, y; @@ -121,7 +121,7 @@ static int decode_frame(AVCodecContext *avctx, static int encode_frame(AVCodecContext *avctx, unsigned char *buf, int buf_size, void *data){ VCR1Context * const a = avctx->priv_data; AVFrame *pict = data; - AVFrame * const p= (AVFrame*)&a->picture; + AVFrame * const p = &a->picture; int size; *p = *pict; @@ -141,7 +141,7 @@ static int encode_frame(AVCodecContext *avctx, unsigned char *buf, int buf_size, static av_cold void common_init(AVCodecContext *avctx){ VCR1Context * const a = avctx->priv_data; - avctx->coded_frame= (AVFrame*)&a->picture; + avctx->coded_frame = &a->picture; a->avctx= avctx; } diff --git a/libavcodec/wnv1.c b/libavcodec/wnv1.c index f6e4694df2..e4b222cf87 100644 --- a/libavcodec/wnv1.c +++ b/libavcodec/wnv1.c @@ -64,7 +64,7 @@ static int decode_frame(AVCodecContext *avctx, const uint8_t *buf = avpkt->data; int buf_size = avpkt->size; WNV1Context * const l = avctx->priv_data; - AVFrame * const p= (AVFrame*)&l->pic; + AVFrame * const p = &l->pic; unsigned char *Y,*U,*V; int i, j; int prev_y = 0, prev_u = 0, prev_v = 0; diff --git a/libavcodec/xl.c b/libavcodec/xl.c index 0ebc9467e0..19cb44fb6b 100644 --- a/libavcodec/xl.c +++ b/libavcodec/xl.c @@ -45,7 +45,7 @@ static int decode_frame(AVCodecContext *avctx, const uint8_t *buf = avpkt->data; int buf_size = avpkt->size; VideoXLContext * const a = avctx->priv_data; - AVFrame * const p= (AVFrame*)&a->pic; + AVFrame * const p = &a->pic; uint8_t *Y, *U, *V; int i, j; int stride; diff --git a/libavcodec/zmbvenc.c b/libavcodec/zmbvenc.c index 1c1e78d912..5d2728e0e7 100644 --- a/libavcodec/zmbvenc.c +++ b/libavcodec/zmbvenc.c @@ -313,7 +313,7 @@ static av_cold int encode_init(AVCodecContext *avctx) return -1; } - avctx->coded_frame = (AVFrame*)&c->pic; + avctx->coded_frame = &c->pic; return 0; } -- cgit v1.2.3 From 47c0ac96aa3530aad9fbc5250a531589f251d4d7 Mon Sep 17 00:00:00 2001 From: Diego Biurrun Date: Mon, 27 Feb 2012 22:02:45 +0100 Subject: Replace AVFrame pointer casts by proper struct member accesses. --- libavcodec/cavsdec.c | 10 +++++----- libavcodec/error_resilience.c | 6 +++--- libavcodec/h264.c | 35 ++++++++++++++++++++++++----------- libavcodec/h264_direct.c | 4 +++- libavcodec/ljpegenc.c | 2 +- libavcodec/mpeg4videodec.c | 7 ++++--- libavcodec/mpegvideo.c | 42 +++++++++++++++++++++--------------------- libavcodec/mpegvideo_enc.c | 12 ++++++------ 8 files changed, 67 insertions(+), 51 deletions(-) (limited to 'libavcodec') diff --git a/libavcodec/cavsdec.c b/libavcodec/cavsdec.c index 12564e8eac..f59c73ad1c 100644 --- a/libavcodec/cavsdec.c +++ b/libavcodec/cavsdec.c @@ -500,9 +500,9 @@ static int decode_pic(AVSContext *h) { } /* release last B frame */ if(h->picture.f.data[0]) - s->avctx->release_buffer(s->avctx, (AVFrame *)&h->picture); + s->avctx->release_buffer(s->avctx, &h->picture.f); - s->avctx->get_buffer(s->avctx, (AVFrame *)&h->picture); + s->avctx->get_buffer(s->avctx, &h->picture.f); ff_cavs_init_pic(h); h->picture.poc = get_bits(&s->gb,8)*2; @@ -591,7 +591,7 @@ static int decode_pic(AVSContext *h) { } if(h->pic_type != AV_PICTURE_TYPE_B) { if(h->DPB[1].f.data[0]) - s->avctx->release_buffer(s->avctx, (AVFrame *)&h->DPB[1]); + s->avctx->release_buffer(s->avctx, &h->DPB[1].f); h->DPB[1] = h->DPB[0]; h->DPB[0] = h->picture; memset(&h->picture,0,sizeof(Picture)); @@ -675,9 +675,9 @@ static int cavs_decode_frame(AVCodecContext * avctx,void *data, int *data_size, case PIC_I_START_CODE: if(!h->got_keyframe) { if(h->DPB[0].f.data[0]) - avctx->release_buffer(avctx, (AVFrame *)&h->DPB[0]); + avctx->release_buffer(avctx, &h->DPB[0].f); if(h->DPB[1].f.data[0]) - avctx->release_buffer(avctx, (AVFrame *)&h->DPB[1]); + avctx->release_buffer(avctx, &h->DPB[1].f); h->got_keyframe = 1; } case PIC_PB_START_CODE: diff --git a/libavcodec/error_resilience.c b/libavcodec/error_resilience.c index e28cc35928..0fab8be1fd 100644 --- a/libavcodec/error_resilience.c +++ b/libavcodec/error_resilience.c @@ -592,7 +592,7 @@ skip_mean_and_median: if (s->avctx->codec_id == CODEC_ID_H264) { // FIXME } else { - ff_thread_await_progress((AVFrame *) s->last_picture_ptr, + ff_thread_await_progress(&s->last_picture_ptr->f, mb_y, 0); } if (!s->last_picture.f.motion_val[0] || @@ -763,7 +763,7 @@ static int is_intra_more_likely(MpegEncContext *s) if (s->avctx->codec_id == CODEC_ID_H264) { // FIXME } else { - ff_thread_await_progress((AVFrame *) s->last_picture_ptr, + ff_thread_await_progress(&s->last_picture_ptr->f, mb_y, 0); } is_intra_likely += s->dsp.sad[0](NULL, last_mb_ptr, mb_ptr, @@ -1144,7 +1144,7 @@ void ff_er_frame_end(MpegEncContext *s) if (s->avctx->codec_id == CODEC_ID_H264) { // FIXME } else { - ff_thread_await_progress((AVFrame *) s->next_picture_ptr, mb_y, 0); + ff_thread_await_progress(&s->next_picture_ptr->f, mb_y, 0); } s->mv[0][0][0] = s->next_picture.f.motion_val[0][xy][0] * time_pb / time_pp; s->mv[0][0][1] = s->next_picture.f.motion_val[0][xy][1] * time_pb / time_pp; diff --git a/libavcodec/h264.c b/libavcodec/h264.c index de79dba3af..afa9c2747d 100644 --- a/libavcodec/h264.c +++ b/libavcodec/h264.c @@ -361,14 +361,26 @@ static void await_references(H264Context *h){ nrefs[list]--; if(!FIELD_PICTURE && ref_field_picture){ // frame referencing two fields - ff_thread_await_progress((AVFrame*)ref_pic, FFMIN((row >> 1) - !(row&1), pic_height-1), 1); - ff_thread_await_progress((AVFrame*)ref_pic, FFMIN((row >> 1) , pic_height-1), 0); + ff_thread_await_progress(&ref_pic->f, + FFMIN((row >> 1) - !(row & 1), + pic_height - 1), + 1); + ff_thread_await_progress(&ref_pic->f, + FFMIN((row >> 1), pic_height - 1), + 0); }else if(FIELD_PICTURE && !ref_field_picture){ // field referencing one field of a frame - ff_thread_await_progress((AVFrame*)ref_pic, FFMIN(row*2 + ref_field , pic_height-1), 0); + ff_thread_await_progress(&ref_pic->f, + FFMIN(row * 2 + ref_field, + pic_height - 1), + 0); }else if(FIELD_PICTURE){ - ff_thread_await_progress((AVFrame*)ref_pic, FFMIN(row, pic_height-1), ref_field); + ff_thread_await_progress(&ref_pic->f, + FFMIN(row, pic_height - 1), + ref_field); }else{ - ff_thread_await_progress((AVFrame*)ref_pic, FFMIN(row, pic_height-1), 0); + ff_thread_await_progress(&ref_pic->f, + FFMIN(row, pic_height - 1), + 0); } } } @@ -2522,8 +2534,9 @@ static int field_end(H264Context *h, int in_setup){ s->mb_y= 0; if (!in_setup && !s->dropable) - ff_thread_report_progress((AVFrame*)s->current_picture_ptr, (16*s->mb_height >> FIELD_PICTURE) - 1, - s->picture_structure==PICT_BOTTOM_FIELD); + ff_thread_report_progress(&s->current_picture_ptr->f, + (16 * s->mb_height >> FIELD_PICTURE) - 1, + s->picture_structure == PICT_BOTTOM_FIELD); if (CONFIG_H264_VDPAU_DECODER && s->avctx->codec->capabilities&CODEC_CAP_HWACCEL_VDPAU) ff_vdpau_h264_set_reference_frames(s); @@ -2893,8 +2906,8 @@ static int decode_slice_header(H264Context *h, H264Context *h0){ h->prev_frame_num++; h->prev_frame_num %= 1<sps.log2_max_frame_num; s->current_picture_ptr->frame_num= h->prev_frame_num; - ff_thread_report_progress((AVFrame*)s->current_picture_ptr, INT_MAX, 0); - ff_thread_report_progress((AVFrame*)s->current_picture_ptr, INT_MAX, 1); + ff_thread_report_progress(&s->current_picture_ptr->f, INT_MAX, 0); + ff_thread_report_progress(&s->current_picture_ptr->f, INT_MAX, 1); ff_generate_sliding_window_mmcos(h); if (ff_h264_execute_ref_pic_marking(h, h->mmco, h->mmco_index) < 0 && (s->avctx->err_recognition & AV_EF_EXPLODE)) @@ -3557,8 +3570,8 @@ static void decode_finish_row(H264Context *h){ if (s->dropable) return; - ff_thread_report_progress((AVFrame*)s->current_picture_ptr, top + height - 1, - s->picture_structure==PICT_BOTTOM_FIELD); + ff_thread_report_progress(&s->current_picture_ptr->f, top + height - 1, + s->picture_structure == PICT_BOTTOM_FIELD); } static int decode_slice(struct AVCodecContext *avctx, void *arg){ diff --git a/libavcodec/h264_direct.c b/libavcodec/h264_direct.c index a953728a12..d72c67b586 100644 --- a/libavcodec/h264_direct.c +++ b/libavcodec/h264_direct.c @@ -153,7 +153,9 @@ static void await_reference_mb_row(H264Context * const h, Picture *ref, int mb_y //FIXME it can be safe to access mb stuff //even if pixels aren't deblocked yet - ff_thread_await_progress((AVFrame*)ref, FFMIN(16*mb_y >> ref_field_picture, ref_height-1), + ff_thread_await_progress(&ref->f, + FFMIN(16 * mb_y >> ref_field_picture, + ref_height - 1), ref_field_picture && ref_field); } diff --git a/libavcodec/ljpegenc.c b/libavcodec/ljpegenc.c index d2b9317114..a73ef45500 100644 --- a/libavcodec/ljpegenc.c +++ b/libavcodec/ljpegenc.c @@ -45,7 +45,7 @@ static int encode_picture_lossless(AVCodecContext *avctx, AVPacket *pkt, MJpegContext * const m = s->mjpeg_ctx; const int width= s->width; const int height= s->height; - AVFrame * const p= (AVFrame*)&s->current_picture; + AVFrame * const p = &s->current_picture.f; const int predictor= avctx->prediction_method+1; const int mb_width = (width + s->mjpeg_hsample[0] - 1) / s->mjpeg_hsample[0]; const int mb_height = (height + s->mjpeg_vsample[0] - 1) / s->mjpeg_vsample[0]; diff --git a/libavcodec/mpeg4videodec.c b/libavcodec/mpeg4videodec.c index a3fc0348d4..8c817bc8ae 100644 --- a/libavcodec/mpeg4videodec.c +++ b/libavcodec/mpeg4videodec.c @@ -377,7 +377,8 @@ int ff_mpeg4_decode_video_packet_header(MpegEncContext *s) int mb_x = 0, mb_y = 0; while (s->next_picture.f.mbskip_table[s->mb_index2xy[mb_num]]) { - if (!mb_x) ff_thread_await_progress((AVFrame*)s->next_picture_ptr, mb_y++, 0); + if (!mb_x) + ff_thread_await_progress(&s->next_picture_ptr->f, mb_y++, 0); mb_num++; if (++mb_x == s->mb_width) mb_x = 0; } @@ -1288,7 +1289,7 @@ static int mpeg4_decode_mb(MpegEncContext *s, s->last_mv[i][1][1]= 0; } - ff_thread_await_progress((AVFrame*)s->next_picture_ptr, s->mb_y, 0); + ff_thread_await_progress(&s->next_picture_ptr->f, s->mb_y, 0); } /* if we skipped it in the future P Frame than skip it now too */ @@ -1470,7 +1471,7 @@ end: const int delta= s->mb_x + 1 == s->mb_width ? 2 : 1; if (s->pict_type == AV_PICTURE_TYPE_B && s->next_picture.f.mbskip_table[xy + delta]) { - ff_thread_await_progress((AVFrame*)s->next_picture_ptr, + ff_thread_await_progress(&s->next_picture_ptr->f, (s->mb_x + delta >= s->mb_width) ? FFMIN(s->mb_y+1, s->mb_height-1) : s->mb_y, 0); } diff --git a/libavcodec/mpegvideo.c b/libavcodec/mpegvideo.c index d894ee4748..8be596b39e 100644 --- a/libavcodec/mpegvideo.c +++ b/libavcodec/mpegvideo.c @@ -232,9 +232,9 @@ static void free_frame_buffer(MpegEncContext *s, Picture *pic) * dimensions; ignore user defined callbacks for these */ if (s->codec_id != CODEC_ID_WMV3IMAGE && s->codec_id != CODEC_ID_VC1IMAGE) - ff_thread_release_buffer(s->avctx, (AVFrame *) pic); + ff_thread_release_buffer(s->avctx, &pic->f); else - avcodec_default_release_buffer(s->avctx, (AVFrame *) pic); + avcodec_default_release_buffer(s->avctx, &pic->f); av_freep(&pic->f.hwaccel_picture_private); } @@ -257,9 +257,9 @@ static int alloc_frame_buffer(MpegEncContext *s, Picture *pic) } if (s->codec_id != CODEC_ID_WMV3IMAGE && s->codec_id != CODEC_ID_VC1IMAGE) - r = ff_thread_get_buffer(s->avctx, (AVFrame *) pic); + r = ff_thread_get_buffer(s->avctx, &pic->f); else - r = avcodec_default_get_buffer(s->avctx, (AVFrame *) pic); + r = avcodec_default_get_buffer(s->avctx, &pic->f); if (r < 0 || !pic->f.type || !pic->f.data[0]) { av_log(s->avctx, AV_LOG_ERROR, "get_buffer() failed (%d %d %p)\n", @@ -729,7 +729,7 @@ av_cold int ff_MPV_common_init(MpegEncContext *s) s->stream_codec_tag = avpriv_toupper4(s->avctx->stream_codec_tag); - s->avctx->coded_frame = (AVFrame *)&s->current_picture; + s->avctx->coded_frame = &s->current_picture.f; FF_ALLOCZ_OR_GOTO(s->avctx, s->mb_index2xy, (s->mb_num + 1) * sizeof(int), fail); // error ressilience code looks cleaner with this @@ -805,7 +805,7 @@ av_cold int ff_MPV_common_init(MpegEncContext *s) FF_ALLOCZ_OR_GOTO(s->avctx, s->picture, s->picture_count * sizeof(Picture), fail); for (i = 0; i < s->picture_count; i++) { - avcodec_get_frame_defaults((AVFrame *) &s->picture[i]); + avcodec_get_frame_defaults(&s->picture[i].f); } if (s->width && s->height) { @@ -1269,10 +1269,8 @@ int ff_MPV_frame_start(MpegEncContext *s, AVCodecContext *avctx) s->last_picture_ptr = &s->picture[i]; if (ff_alloc_picture(s, s->last_picture_ptr, 0) < 0) return -1; - ff_thread_report_progress((AVFrame *) s->last_picture_ptr, - INT_MAX, 0); - ff_thread_report_progress((AVFrame *) s->last_picture_ptr, - INT_MAX, 1); + ff_thread_report_progress(&s->last_picture_ptr->f, INT_MAX, 0); + ff_thread_report_progress(&s->last_picture_ptr->f, INT_MAX, 1); } if ((s->next_picture_ptr == NULL || s->next_picture_ptr->f.data[0] == NULL) && @@ -1282,10 +1280,8 @@ int ff_MPV_frame_start(MpegEncContext *s, AVCodecContext *avctx) s->next_picture_ptr = &s->picture[i]; if (ff_alloc_picture(s, s->next_picture_ptr, 0) < 0) return -1; - ff_thread_report_progress((AVFrame *) s->next_picture_ptr, - INT_MAX, 0); - ff_thread_report_progress((AVFrame *) s->next_picture_ptr, - INT_MAX, 1); + ff_thread_report_progress(&s->next_picture_ptr->f, INT_MAX, 0); + ff_thread_report_progress(&s->next_picture_ptr->f, INT_MAX, 1); } } @@ -1410,10 +1406,10 @@ void ff_MPV_frame_end(MpegEncContext *s) memset(&s->next_picture, 0, sizeof(Picture)); memset(&s->current_picture, 0, sizeof(Picture)); #endif - s->avctx->coded_frame = (AVFrame *) s->current_picture_ptr; + s->avctx->coded_frame = &s->current_picture_ptr->f; if (s->codec_id != CODEC_ID_H264 && s->current_picture.f.reference) { - ff_thread_report_progress((AVFrame *) s->current_picture_ptr, + ff_thread_report_progress(&s->current_picture_ptr->f, s->mb_height - 1, 0); } } @@ -2365,10 +2361,14 @@ void MPV_decode_mb_internal(MpegEncContext *s, DCTELEM block[12][64], if(HAVE_THREADS && s->avctx->active_thread_type&FF_THREAD_FRAME) { if (s->mv_dir & MV_DIR_FORWARD) { - ff_thread_await_progress((AVFrame*)s->last_picture_ptr, ff_MPV_lowest_referenced_row(s, 0), 0); + ff_thread_await_progress(&s->last_picture_ptr->f, + ff_MPV_lowest_referenced_row(s, 0), + 0); } if (s->mv_dir & MV_DIR_BACKWARD) { - ff_thread_await_progress((AVFrame*)s->next_picture_ptr, ff_MPV_lowest_referenced_row(s, 1), 0); + ff_thread_await_progress(&s->next_picture_ptr->f, + ff_MPV_lowest_referenced_row(s, 1), + 0); } } @@ -2575,9 +2575,9 @@ void ff_draw_horiz_band(MpegEncContext *s, int y, int h){ int i; if(s->pict_type==AV_PICTURE_TYPE_B || s->low_delay || (s->avctx->slice_flags&SLICE_FLAG_CODED_ORDER)) - src= (AVFrame*)s->current_picture_ptr; + src = &s->current_picture_ptr->f; else if(s->last_picture_ptr) - src= (AVFrame*)s->last_picture_ptr; + src = &s->last_picture_ptr->f; else return; @@ -2896,5 +2896,5 @@ void ff_set_qscale(MpegEncContext * s, int qscale) void ff_MPV_report_decode_progress(MpegEncContext *s) { if (s->pict_type != AV_PICTURE_TYPE_B && !s->partitioned_frame && !s->error_occurred) - ff_thread_report_progress((AVFrame*)s->current_picture_ptr, s->mb_y, 0); + ff_thread_report_progress(&s->current_picture_ptr->f, s->mb_y, 0); } diff --git a/libavcodec/mpegvideo_enc.c b/libavcodec/mpegvideo_enc.c index fbb5cf15c7..7074ddaeec 100644 --- a/libavcodec/mpegvideo_enc.c +++ b/libavcodec/mpegvideo_enc.c @@ -974,7 +974,7 @@ static int load_input_picture(MpegEncContext *s, AVFrame *pic_arg) if (i < 0) return i; - pic = (AVFrame *) &s->picture[i]; + pic = &s->picture[i].f; pic->reference = 3; for (i = 0; i < 4; i++) { @@ -989,7 +989,7 @@ static int load_input_picture(MpegEncContext *s, AVFrame *pic_arg) if (i < 0) return i; - pic = (AVFrame *) &s->picture[i]; + pic = &s->picture[i].f; pic->reference = 3; if (ff_alloc_picture(s, (Picture *) pic, 0) < 0) { @@ -1241,7 +1241,7 @@ static int select_input_picture(MpegEncContext *s) s->input_picture[0]->f.type == FF_BUFFER_TYPE_INTERNAL); s->avctx->release_buffer(s->avctx, - (AVFrame *) s->input_picture[0]); + &s->input_picture[0]->f); } emms_c(); @@ -1374,13 +1374,13 @@ no_output_pic: /* mark us unused / free shared pic */ if (s->reordered_input_picture[0]->f.type == FF_BUFFER_TYPE_INTERNAL) s->avctx->release_buffer(s->avctx, - (AVFrame *) s->reordered_input_picture[0]); + &s->reordered_input_picture[0]->f); for (i = 0; i < 4; i++) s->reordered_input_picture[0]->f.data[i] = NULL; s->reordered_input_picture[0]->f.type = 0; - copy_picture_attributes(s, (AVFrame *) pic, - (AVFrame *) s->reordered_input_picture[0]); + copy_picture_attributes(s, &pic->f, + &s->reordered_input_picture[0]->f); s->current_picture_ptr = pic; } else { -- cgit v1.2.3 From 324deaa26883efbdac3b82d4b06eee0285826a7f Mon Sep 17 00:00:00 2001 From: Diego Biurrun Date: Mon, 27 Feb 2012 22:08:41 +0100 Subject: Replace AVFrame pointer type punning by proper struct member assignments. --- libavcodec/asv1.c | 2 +- libavcodec/avs.c | 2 +- libavcodec/cavsdec.c | 6 +++--- libavcodec/h261dec.c | 3 ++- libavcodec/h263dec.c | 6 +++--- libavcodec/h264.c | 26 +++++++------------------- libavcodec/h264_direct.c | 3 +-- libavcodec/indeo2.c | 2 +- libavcodec/mpeg12.c | 6 +++--- libavcodec/pnmdec.c | 2 +- libavcodec/rv10.c | 4 ++-- libavcodec/rv34.c | 6 +++--- libavcodec/svq1dec.c | 2 +- libavcodec/svq3.c | 6 +++--- libavcodec/targa.c | 2 +- libavcodec/tiff.c | 2 +- libavcodec/vc1dec.c | 6 +++--- libavcodec/vcr1.c | 2 +- 18 files changed, 38 insertions(+), 50 deletions(-) (limited to 'libavcodec') diff --git a/libavcodec/asv1.c b/libavcodec/asv1.c index 94073c087e..8dfe276f93 100644 --- a/libavcodec/asv1.c +++ b/libavcodec/asv1.c @@ -454,7 +454,7 @@ static int decode_frame(AVCodecContext *avctx, } } - *picture= *(AVFrame*)&a->picture; + *picture = a->picture; *data_size = sizeof(AVPicture); emms_c(); diff --git a/libavcodec/avs.c b/libavcodec/avs.c index ce119ebd72..f4d8f69610 100644 --- a/libavcodec/avs.c +++ b/libavcodec/avs.c @@ -149,7 +149,7 @@ avs_decode_frame(AVCodecContext * avctx, align_get_bits(&change_map); } - *picture = *(AVFrame *) & avs->picture; + *picture = avs->picture; *data_size = sizeof(AVPicture); return buf_size; diff --git a/libavcodec/cavsdec.c b/libavcodec/cavsdec.c index f59c73ad1c..1da4eb1922 100644 --- a/libavcodec/cavsdec.c +++ b/libavcodec/cavsdec.c @@ -655,7 +655,7 @@ static int cavs_decode_frame(AVCodecContext * avctx,void *data, int *data_size, if (buf_size == 0) { if (!s->low_delay && h->DPB[0].f.data[0]) { *data_size = sizeof(AVPicture); - *picture = *(AVFrame *) &h->DPB[0]; + *picture = h->DPB[0].f; } return 0; } @@ -691,12 +691,12 @@ static int cavs_decode_frame(AVCodecContext * avctx,void *data, int *data_size, *data_size = sizeof(AVPicture); if(h->pic_type != AV_PICTURE_TYPE_B) { if(h->DPB[1].f.data[0]) { - *picture = *(AVFrame *) &h->DPB[1]; + *picture = h->DPB[1].f; } else { *data_size = 0; } } else - *picture = *(AVFrame *) &h->picture; + *picture = h->picture.f; break; case EXT_START_CODE: //mpeg_decode_extension(avctx,buf_ptr, input_size); diff --git a/libavcodec/h261dec.c b/libavcodec/h261dec.c index 38d5e2efc3..dd1931d6da 100644 --- a/libavcodec/h261dec.c +++ b/libavcodec/h261dec.c @@ -624,7 +624,8 @@ retry: assert(s->current_picture.f.pict_type == s->current_picture_ptr->f.pict_type); assert(s->current_picture.f.pict_type == s->pict_type); - *pict= *(AVFrame*)s->current_picture_ptr; + + *pict = s->current_picture_ptr->f; ff_print_debug_info(s, pict); *data_size = sizeof(AVFrame); diff --git a/libavcodec/h263dec.c b/libavcodec/h263dec.c index 4f0e4563da..992e5fd32b 100644 --- a/libavcodec/h263dec.c +++ b/libavcodec/h263dec.c @@ -355,7 +355,7 @@ uint64_t time= rdtsc(); if (buf_size == 0) { /* special case for last picture */ if (s->low_delay==0 && s->next_picture_ptr) { - *pict= *(AVFrame*)s->next_picture_ptr; + *pict = s->next_picture_ptr->f; s->next_picture_ptr= NULL; *data_size = sizeof(AVFrame); @@ -712,9 +712,9 @@ intrax8_decoded: assert(s->current_picture.f.pict_type == s->current_picture_ptr->f.pict_type); assert(s->current_picture.f.pict_type == s->pict_type); if (s->pict_type == AV_PICTURE_TYPE_B || s->low_delay) { - *pict= *(AVFrame*)s->current_picture_ptr; + *pict = s->current_picture_ptr->f; } else if (s->last_picture_ptr != NULL) { - *pict= *(AVFrame*)s->last_picture_ptr; + *pict = s->last_picture_ptr->f; } if(s->last_picture_ptr || s->low_delay){ diff --git a/libavcodec/h264.c b/libavcodec/h264.c index afa9c2747d..36a4e2bb03 100644 --- a/libavcodec/h264.c +++ b/libavcodec/h264.c @@ -361,26 +361,14 @@ static void await_references(H264Context *h){ nrefs[list]--; if(!FIELD_PICTURE && ref_field_picture){ // frame referencing two fields - ff_thread_await_progress(&ref_pic->f, - FFMIN((row >> 1) - !(row & 1), - pic_height - 1), - 1); - ff_thread_await_progress(&ref_pic->f, - FFMIN((row >> 1), pic_height - 1), - 0); + ff_thread_await_progress(&ref_pic->f, FFMIN((row >> 1) - !(row & 1), pic_height - 1), 1); + ff_thread_await_progress(&ref_pic->f, FFMIN((row >> 1), pic_height - 1), 0); }else if(FIELD_PICTURE && !ref_field_picture){ // field referencing one field of a frame - ff_thread_await_progress(&ref_pic->f, - FFMIN(row * 2 + ref_field, - pic_height - 1), - 0); + ff_thread_await_progress(&ref_pic->f, FFMIN(row * 2 + ref_field, pic_height - 1), 0); }else if(FIELD_PICTURE){ - ff_thread_await_progress(&ref_pic->f, - FFMIN(row, pic_height - 1), - ref_field); + ff_thread_await_progress(&ref_pic->f, FFMIN(row, pic_height - 1), ref_field); }else{ - ff_thread_await_progress(&ref_pic->f, - FFMIN(row, pic_height - 1), - 0); + ff_thread_await_progress(&ref_pic->f, FFMIN(row, pic_height - 1), 0); } } } @@ -4053,7 +4041,7 @@ static int decode_frame(AVCodecContext *avctx, if(out){ *data_size = sizeof(AVFrame); - *pict= *(AVFrame*)out; + *pict = out->f; } return buf_index; @@ -4087,7 +4075,7 @@ static int decode_frame(AVCodecContext *avctx, } else { *data_size = sizeof(AVFrame); - *pict = *(AVFrame*)h->next_output_pic; + *pict = h->next_output_pic->f; } } diff --git a/libavcodec/h264_direct.c b/libavcodec/h264_direct.c index d72c67b586..9010cacfd9 100644 --- a/libavcodec/h264_direct.c +++ b/libavcodec/h264_direct.c @@ -154,8 +154,7 @@ static void await_reference_mb_row(H264Context * const h, Picture *ref, int mb_y //even if pixels aren't deblocked yet ff_thread_await_progress(&ref->f, - FFMIN(16 * mb_y >> ref_field_picture, - ref_height - 1), + FFMIN(16 * mb_y >> ref_field_picture, ref_height - 1), ref_field_picture && ref_field); } diff --git a/libavcodec/indeo2.c b/libavcodec/indeo2.c index b114573ff0..6761c59eed 100644 --- a/libavcodec/indeo2.c +++ b/libavcodec/indeo2.c @@ -191,7 +191,7 @@ static int ir2_decode_frame(AVCodecContext *avctx, s->picture.data[1], s->picture.linesize[1], ir2_luma_table); } - *picture= *(AVFrame*)&s->picture; + *picture = s->picture; *data_size = sizeof(AVPicture); return buf_size; diff --git a/libavcodec/mpeg12.c b/libavcodec/mpeg12.c index 4b526eb6ef..a5dafbd1fc 100644 --- a/libavcodec/mpeg12.c +++ b/libavcodec/mpeg12.c @@ -1915,7 +1915,7 @@ static int slice_end(AVCodecContext *avctx, AVFrame *pict) ff_MPV_frame_end(s); if (s->pict_type == AV_PICTURE_TYPE_B || s->low_delay) { - *pict = *(AVFrame*)s->current_picture_ptr; + *pict = s->current_picture_ptr->f; ff_print_debug_info(s, pict); } else { if (avctx->active_thread_type & FF_THREAD_FRAME) @@ -1923,7 +1923,7 @@ static int slice_end(AVCodecContext *avctx, AVFrame *pict) /* latency of 1 frame for I- and P-frames */ /* XXX: use another variable than picture_number */ if (s->last_picture_ptr != NULL) { - *pict = *(AVFrame*)s->last_picture_ptr; + *pict = s->last_picture_ptr->f; ff_print_debug_info(s, pict); } } @@ -2203,7 +2203,7 @@ static int mpeg_decode_frame(AVCodecContext *avctx, if (buf_size == 0 || (buf_size == 4 && AV_RB32(buf) == SEQ_END_CODE)) { /* special case for last picture */ if (s2->low_delay == 0 && s2->next_picture_ptr) { - *picture = *(AVFrame*)s2->next_picture_ptr; + *picture = s2->next_picture_ptr->f; s2->next_picture_ptr = NULL; *data_size = sizeof(AVFrame); diff --git a/libavcodec/pnmdec.c b/libavcodec/pnmdec.c index ada0fd8a36..50e8bce168 100644 --- a/libavcodec/pnmdec.c +++ b/libavcodec/pnmdec.c @@ -180,7 +180,7 @@ static int pnm_decode_frame(AVCodecContext *avctx, void *data, } break; } - *picture = *(AVFrame*)&s->picture; + *picture = s->picture; *data_size = sizeof(AVPicture); return s->bytestream - s->bytestream_start; diff --git a/libavcodec/rv10.c b/libavcodec/rv10.c index 75d529f42d..6e6516feeb 100644 --- a/libavcodec/rv10.c +++ b/libavcodec/rv10.c @@ -677,9 +677,9 @@ static int rv10_decode_frame(AVCodecContext *avctx, ff_MPV_frame_end(s); if (s->pict_type == AV_PICTURE_TYPE_B || s->low_delay) { - *pict= *(AVFrame*)s->current_picture_ptr; + *pict = s->current_picture_ptr->f; } else if (s->last_picture_ptr != NULL) { - *pict= *(AVFrame*)s->last_picture_ptr; + *pict = s->last_picture_ptr->f; } if(s->last_picture_ptr || s->low_delay){ diff --git a/libavcodec/rv34.c b/libavcodec/rv34.c index e15affeb8d..cf74eab56f 100644 --- a/libavcodec/rv34.c +++ b/libavcodec/rv34.c @@ -1656,7 +1656,7 @@ int ff_rv34_decode_frame(AVCodecContext *avctx, if (buf_size == 0) { /* special case for last picture */ if (s->low_delay==0 && s->next_picture_ptr) { - *pict = *(AVFrame*)s->next_picture_ptr; + *pict = s->next_picture_ptr->f; s->next_picture_ptr = NULL; *data_size = sizeof(AVFrame); @@ -1743,9 +1743,9 @@ int ff_rv34_decode_frame(AVCodecContext *avctx, ff_thread_report_progress(&s->current_picture_ptr->f, INT_MAX, 0); if (s->pict_type == AV_PICTURE_TYPE_B || s->low_delay) { - *pict = *(AVFrame*)s->current_picture_ptr; + *pict = s->current_picture_ptr->f; } else if (s->last_picture_ptr != NULL) { - *pict = *(AVFrame*)s->last_picture_ptr; + *pict = s->last_picture_ptr->f; } if(s->last_picture_ptr || s->low_delay){ diff --git a/libavcodec/svq1dec.c b/libavcodec/svq1dec.c index 80f96c8cc6..a831459611 100644 --- a/libavcodec/svq1dec.c +++ b/libavcodec/svq1dec.c @@ -735,7 +735,7 @@ static int svq1_decode_frame(AVCodecContext *avctx, } } - *pict = *(AVFrame*)&s->current_picture; + *pict = s->current_picture.f; ff_MPV_frame_end(s); diff --git a/libavcodec/svq3.c b/libavcodec/svq3.c index 73de55a457..e157061f64 100644 --- a/libavcodec/svq3.c +++ b/libavcodec/svq3.c @@ -956,7 +956,7 @@ static int svq3_decode_frame(AVCodecContext *avctx, /* special case for last picture */ if (buf_size == 0) { if (s->next_picture_ptr && !s->low_delay) { - *(AVFrame *) data = *(AVFrame *) &s->next_picture; + *(AVFrame *) data = s->next_picture.f; s->next_picture_ptr = NULL; *data_size = sizeof(AVFrame); } @@ -1076,9 +1076,9 @@ static int svq3_decode_frame(AVCodecContext *avctx, ff_MPV_frame_end(s); if (s->pict_type == AV_PICTURE_TYPE_B || s->low_delay) { - *(AVFrame *) data = *(AVFrame *) &s->current_picture; + *(AVFrame *) data = s->current_picture.f; } else { - *(AVFrame *) data = *(AVFrame *) &s->last_picture; + *(AVFrame *) data = s->last_picture.f; } /* Do not output the last pic after seeking. */ diff --git a/libavcodec/targa.c b/libavcodec/targa.c index 94a50fbb79..d5559145a5 100644 --- a/libavcodec/targa.c +++ b/libavcodec/targa.c @@ -248,7 +248,7 @@ static int decode_frame(AVCodecContext *avctx, } } - *picture= *(AVFrame*)&s->picture; + *picture = s->picture; *data_size = sizeof(AVPicture); return avpkt->size; diff --git a/libavcodec/tiff.c b/libavcodec/tiff.c index 57720a5018..0ff6ceb7cc 100644 --- a/libavcodec/tiff.c +++ b/libavcodec/tiff.c @@ -607,7 +607,7 @@ static int decode_frame(AVCodecContext *avctx, src += s->picture.linesize[0]; } } - *picture= *(AVFrame*)&s->picture; + *picture = s->picture; *data_size = sizeof(AVPicture); return buf_size; diff --git a/libavcodec/vc1dec.c b/libavcodec/vc1dec.c index 8ab92b4177..4a991f0149 100644 --- a/libavcodec/vc1dec.c +++ b/libavcodec/vc1dec.c @@ -5449,7 +5449,7 @@ static int vc1_decode_frame(AVCodecContext *avctx, void *data, if (buf_size == 0 || (buf_size == 4 && AV_RB32(buf) == VC1_CODE_ENDOFSEQ)) { /* special case for last picture */ if (s->low_delay == 0 && s->next_picture_ptr) { - *pict = *(AVFrame*)s->next_picture_ptr; + *pict = s->next_picture_ptr->f; s->next_picture_ptr = NULL; *data_size = sizeof(AVFrame); @@ -5755,9 +5755,9 @@ image: *data_size = sizeof(AVFrame); } else { if (s->pict_type == AV_PICTURE_TYPE_B || s->low_delay) { - *pict = *(AVFrame*)s->current_picture_ptr; + *pict = s->current_picture_ptr->f; } else if (s->last_picture_ptr != NULL) { - *pict = *(AVFrame*)s->last_picture_ptr; + *pict = s->last_picture_ptr->f; } if (s->last_picture_ptr || s->low_delay) { *data_size = sizeof(AVFrame); diff --git a/libavcodec/vcr1.c b/libavcodec/vcr1.c index bace3a34b8..c0a0a1cdb6 100644 --- a/libavcodec/vcr1.c +++ b/libavcodec/vcr1.c @@ -111,7 +111,7 @@ static int decode_frame(AVCodecContext *avctx, } } - *picture= *(AVFrame*)&a->picture; + *picture = a->picture; *data_size = sizeof(AVPicture); return buf_size; -- cgit v1.2.3 From 1c4717be4f37e42938f1a1e6ec8c99e0142e52ba Mon Sep 17 00:00:00 2001 From: Diego Biurrun Date: Wed, 29 Feb 2012 19:47:49 +0100 Subject: mjpegdec: use correct variable in av_log invocation MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit libavcodec/mjpegdec.c:1463: warning: format ‘%x’ expects type ‘unsigned int’, but argument 5 has type ‘const uint8_t *’ --- libavcodec/mjpegdec.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'libavcodec') diff --git a/libavcodec/mjpegdec.c b/libavcodec/mjpegdec.c index 47a85cb598..ea6230c3cd 100644 --- a/libavcodec/mjpegdec.c +++ b/libavcodec/mjpegdec.c @@ -1460,7 +1460,7 @@ int ff_mjpeg_decode_frame(AVCodecContext *avctx, void *data, int *data_size, goto the_end; } else if (unescaped_buf_size > (1U<<29)) { av_log(avctx, AV_LOG_ERROR, "MJPEG packet 0x%x too big (0x%x/0x%x), corrupt data?\n", - start_code, unescaped_buf_ptr, buf_size); + start_code, unescaped_buf_size, buf_size); return AVERROR_INVALIDDATA; } else { av_log(avctx, AV_LOG_DEBUG, "marker=%x avail_size_in_buf=%td\n", -- cgit v1.2.3 From f604eab30a7ec33e6d803a4d320ca9b453bde836 Mon Sep 17 00:00:00 2001 From: Derek Buitenhuis Date: Thu, 1 Mar 2012 16:34:57 -0500 Subject: wavpack: Fix an integer overflow Integer Overflow Checker detected an integer overflow while FATE was running. See: http://fate.libav.org/x86_64-linux-ioc/ Signed-off-by: Derek Buitenhuis Signed-off-by: Kostya Shishkov --- libavcodec/wavpack.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'libavcodec') diff --git a/libavcodec/wavpack.c b/libavcodec/wavpack.c index 6eb913fa64..022a4ce7d5 100644 --- a/libavcodec/wavpack.c +++ b/libavcodec/wavpack.c @@ -428,7 +428,7 @@ static float wv_get_value_float(WavpackFrameContext *s, uint32_t *crc, int S) uint32_t u; } value; - int sign; + unsigned int sign; int exp = s->float_max_exp; if (s->got_extra_bits) { -- cgit v1.2.3 From b087ce2bee81db8cc5caffb8f0a4f6c7c92a30fe Mon Sep 17 00:00:00 2001 From: Martin Storsjö Date: Fri, 2 Mar 2012 17:03:06 +0200 Subject: g722: Fix the QMF scaling MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This fixes clipping if the encoder input used the full 16 bit input range (samples with a magnitude below 16383 worked fine). The filtered subband samples should be 15 bit maximum, while the code earlier produced them scaled to 16 bit. This makes the decoder output have double the magnitude compared to before. The spec reference samples doesn't test the QMF at all, which was why this part slipped past initially. Signed-off-by: Martin Storsjö --- libavcodec/g722dec.c | 4 +- libavcodec/g722enc.c | 4 +- tests/ref/acodec/g722 | 8 +- tests/ref/fate/g722dec-1 | 334 +++++++++++++++++++++++------------------------ tests/ref/fate/g722enc | 2 +- 5 files changed, 176 insertions(+), 176 deletions(-) (limited to 'libavcodec') diff --git a/libavcodec/g722dec.c b/libavcodec/g722dec.c index 50a224ba10..72bb0ef3c7 100644 --- a/libavcodec/g722dec.c +++ b/libavcodec/g722dec.c @@ -126,8 +126,8 @@ static int g722_decode_frame(AVCodecContext *avctx, void *data, c->prev_samples[c->prev_samples_pos++] = rlow - rhigh; ff_g722_apply_qmf(c->prev_samples + c->prev_samples_pos - 24, &xout1, &xout2); - *out_buf++ = av_clip_int16(xout1 >> 12); - *out_buf++ = av_clip_int16(xout2 >> 12); + *out_buf++ = av_clip_int16(xout1 >> 11); + *out_buf++ = av_clip_int16(xout2 >> 11); if (c->prev_samples_pos >= PREV_SAMPLES_BUF_SIZE) { memmove(c->prev_samples, c->prev_samples + c->prev_samples_pos - 22, 22 * sizeof(c->prev_samples[0])); diff --git a/libavcodec/g722enc.c b/libavcodec/g722enc.c index a5ae0a5153..ba8ceeff86 100644 --- a/libavcodec/g722enc.c +++ b/libavcodec/g722enc.c @@ -136,8 +136,8 @@ static inline void filter_samples(G722Context *c, const int16_t *samples, c->prev_samples[c->prev_samples_pos++] = samples[0]; c->prev_samples[c->prev_samples_pos++] = samples[1]; ff_g722_apply_qmf(c->prev_samples + c->prev_samples_pos - 24, &xout1, &xout2); - *xlow = xout1 + xout2 >> 13; - *xhigh = xout1 - xout2 >> 13; + *xlow = xout1 + xout2 >> 14; + *xhigh = xout1 - xout2 >> 14; if (c->prev_samples_pos >= PREV_SAMPLES_BUF_SIZE) { memmove(c->prev_samples, c->prev_samples + c->prev_samples_pos - 22, diff --git a/tests/ref/acodec/g722 b/tests/ref/acodec/g722 index 6ea492ae45..0e2f7e75b0 100644 --- a/tests/ref/acodec/g722 +++ b/tests/ref/acodec/g722 @@ -1,4 +1,4 @@ -1975cc4a3521e374b33ae042e182f6b6 *./tests/data/acodec/g722.wav -48053 ./tests/data/acodec/g722.wav -ade04cdcf249e6946395f109b077dd62 *./tests/data/g722.acodec.out.wav -stddev: 8841.24 PSNR: 17.40 MAXDIFF:36225 bytes: 191980/ 1058400 +7b0492eee76b04b710990235f97a0bf2 *./tests/data/acodec/g722.wav + 48053 ./tests/data/acodec/g722.wav +b5568e0e3930ff563824156e8e1015f0 *./tests/data/g722.acodec.out.wav +stddev: 8939.44 PSNR: 17.30 MAXDIFF:40370 bytes: 191980/ 1058400 diff --git a/tests/ref/fate/g722dec-1 b/tests/ref/fate/g722dec-1 index 55f125995d..e94c3e6a11 100644 --- a/tests/ref/fate/g722dec-1 +++ b/tests/ref/fate/g722dec-1 @@ -1,168 +1,168 @@ #tb 0: 1/16000 -0, 0, 0, 2048, 4096, 0xde68394d -0, 2048, 2048, 2048, 4096, 0xa5c28cb7 -0, 4096, 4096, 2048, 4096, 0x2e3c2f23 -0, 6144, 6144, 2048, 4096, 0xd7757825 -0, 8192, 8192, 2048, 4096, 0xafd1fd61 -0, 10240, 10240, 2048, 4096, 0x686afcbe -0, 12288, 12288, 2048, 4096, 0x2290e848 -0, 14336, 14336, 2048, 4096, 0xddd484ad -0, 16384, 16384, 2048, 4096, 0x148811a6 -0, 18432, 18432, 2048, 4096, 0x8b965613 -0, 20480, 20480, 2048, 4096, 0x8b095d51 -0, 22528, 22528, 2048, 4096, 0xf7625485 -0, 24576, 24576, 2048, 4096, 0x982a688c -0, 26624, 26624, 2048, 4096, 0xc290dcfc -0, 28672, 28672, 2048, 4096, 0x8bdef225 -0, 30720, 30720, 2048, 4096, 0xfca27fdc -0, 32768, 32768, 2048, 4096, 0x95eff313 -0, 34816, 34816, 2048, 4096, 0x691ed4f7 -0, 36864, 36864, 2048, 4096, 0xd7e7b492 -0, 38912, 38912, 2048, 4096, 0xb0416bfe -0, 40960, 40960, 2048, 4096, 0xf94b3ebd -0, 43008, 43008, 2048, 4096, 0x7f73ca12 -0, 45056, 45056, 2048, 4096, 0xe91da4a3 -0, 47104, 47104, 2048, 4096, 0x1f74dc0e -0, 49152, 49152, 2048, 4096, 0xd95b35e8 -0, 51200, 51200, 2048, 4096, 0x6dcdde1a -0, 53248, 53248, 2048, 4096, 0x614fd4e4 -0, 55296, 55296, 2048, 4096, 0xe38d0fd5 -0, 57344, 57344, 2048, 4096, 0xfeba2999 -0, 59392, 59392, 2048, 4096, 0x1bf541e1 -0, 61440, 61440, 2048, 4096, 0x689f50d8 -0, 63488, 63488, 2048, 4096, 0x0aa60f5f -0, 65536, 65536, 2048, 4096, 0x60ac3116 -0, 67584, 67584, 2048, 4096, 0xfa60e5e6 -0, 69632, 69632, 2048, 4096, 0xc7207c5b -0, 71680, 71680, 2048, 4096, 0x01196277 -0, 73728, 73728, 2048, 4096, 0x609ca46c -0, 75776, 75776, 2048, 4096, 0xfb799142 -0, 77824, 77824, 2048, 4096, 0x720910df -0, 79872, 79872, 2048, 4096, 0xe21a8662 -0, 81920, 81920, 2048, 4096, 0x07105120 -0, 83968, 83968, 2048, 4096, 0x593f627e -0, 86016, 86016, 2048, 4096, 0x28ddc80c -0, 88064, 88064, 2048, 4096, 0xc69ef356 -0, 90112, 90112, 2048, 4096, 0x2defc5bd -0, 92160, 92160, 2048, 4096, 0x82a4f418 -0, 94208, 94208, 2048, 4096, 0x424cb997 -0, 96256, 96256, 2048, 4096, 0x167a49b7 -0, 98304, 98304, 2048, 4096, 0x32a3e0d4 -0, 100352, 100352, 2048, 4096, 0x08a353ae -0, 102400, 102400, 2048, 4096, 0x9543577b -0, 104448, 104448, 2048, 4096, 0x2ed137cf -0, 106496, 106496, 2048, 4096, 0xd80b0538 -0, 108544, 108544, 2048, 4096, 0x2ad31bef -0, 110592, 110592, 2048, 4096, 0x1060cff8 -0, 112640, 112640, 2048, 4096, 0x76ab5ab8 -0, 114688, 114688, 2048, 4096, 0x8eedb68d -0, 116736, 116736, 2048, 4096, 0xf4e2dc46 -0, 118784, 118784, 2048, 4096, 0xc52d3326 -0, 120832, 120832, 2048, 4096, 0x25201a26 -0, 122880, 122880, 2048, 4096, 0x16419378 -0, 124928, 124928, 2048, 4096, 0x97061f3c -0, 126976, 126976, 2048, 4096, 0xd54edecd -0, 129024, 129024, 2048, 4096, 0xc830b07b -0, 131072, 131072, 2048, 4096, 0x804bae00 -0, 133120, 133120, 2048, 4096, 0xbb279150 -0, 135168, 135168, 2048, 4096, 0x95c4d5aa -0, 137216, 137216, 2048, 4096, 0xc51d5259 -0, 139264, 139264, 2048, 4096, 0x856e1ab0 -0, 141312, 141312, 2048, 4096, 0x9e6ccb12 -0, 143360, 143360, 2048, 4096, 0xa2e5c1bb -0, 145408, 145408, 2048, 4096, 0xe62fb62f -0, 147456, 147456, 2048, 4096, 0xf10e3df0 -0, 149504, 149504, 2048, 4096, 0x76def18b -0, 151552, 151552, 2048, 4096, 0xc9c3a26d -0, 153600, 153600, 2048, 4096, 0x8ec0e061 -0, 155648, 155648, 2048, 4096, 0x3d4e8512 -0, 157696, 157696, 2048, 4096, 0xec45cd46 -0, 159744, 159744, 2048, 4096, 0xa34f3ddf -0, 161792, 161792, 2048, 4096, 0x52b81c53 -0, 163840, 163840, 2048, 4096, 0xd0f0397a -0, 165888, 165888, 2048, 4096, 0x7c0de231 -0, 167936, 167936, 2048, 4096, 0xfe86c032 -0, 169984, 169984, 2048, 4096, 0x67cdb848 -0, 172032, 172032, 2048, 4096, 0x90532cc0 -0, 174080, 174080, 2048, 4096, 0x03bca9e9 -0, 176128, 176128, 2048, 4096, 0x73169fd1 -0, 178176, 178176, 2048, 4096, 0x0b93967d -0, 180224, 180224, 2048, 4096, 0x6486d8be -0, 182272, 182272, 2048, 4096, 0x555cc2ac -0, 184320, 184320, 2048, 4096, 0x07c1912e -0, 186368, 186368, 2048, 4096, 0xe0423c66 -0, 188416, 188416, 2048, 4096, 0xc12d0fa1 -0, 190464, 190464, 2048, 4096, 0xdf497c2f -0, 192512, 192512, 2048, 4096, 0x9298d1ba -0, 194560, 194560, 2048, 4096, 0x691a4e15 -0, 196608, 196608, 2048, 4096, 0x725adc6e -0, 198656, 198656, 2048, 4096, 0xf68e88de -0, 200704, 200704, 2048, 4096, 0x37a234aa -0, 202752, 202752, 2048, 4096, 0x43fb0558 -0, 204800, 204800, 2048, 4096, 0x653e4320 -0, 206848, 206848, 2048, 4096, 0x651e2f13 -0, 208896, 208896, 2048, 4096, 0x179049f9 -0, 210944, 210944, 2048, 4096, 0xe02fbb9d -0, 212992, 212992, 2048, 4096, 0xb7e9f2a0 -0, 215040, 215040, 2048, 4096, 0x94ee81df -0, 217088, 217088, 2048, 4096, 0x398a98de -0, 219136, 219136, 2048, 4096, 0x1267594a -0, 221184, 221184, 2048, 4096, 0x715adbaf -0, 223232, 223232, 2048, 4096, 0x28ce1a20 -0, 225280, 225280, 2048, 4096, 0x4f8073d0 -0, 227328, 227328, 2048, 4096, 0x536846d3 -0, 229376, 229376, 2048, 4096, 0x7dc7defe -0, 231424, 231424, 2048, 4096, 0x08a28e2a -0, 233472, 233472, 2048, 4096, 0xd717c5cd -0, 235520, 235520, 2048, 4096, 0x5d6e1efd -0, 237568, 237568, 2048, 4096, 0x4d0eea27 -0, 239616, 239616, 2048, 4096, 0x70fff90c -0, 241664, 241664, 2048, 4096, 0xd5cc8207 -0, 243712, 243712, 2048, 4096, 0xf87cae0e -0, 245760, 245760, 2048, 4096, 0x26814ab5 -0, 247808, 247808, 2048, 4096, 0x9569fb8d -0, 249856, 249856, 2048, 4096, 0x7835122e -0, 251904, 251904, 2048, 4096, 0xa38840dd -0, 253952, 253952, 2048, 4096, 0xfc499ba3 -0, 256000, 256000, 2048, 4096, 0x0aa60cb0 -0, 258048, 258048, 2048, 4096, 0x530ef56e -0, 260096, 260096, 2048, 4096, 0xead968db -0, 262144, 262144, 2048, 4096, 0x64484214 -0, 264192, 264192, 2048, 4096, 0xfd0cc89e -0, 266240, 266240, 2048, 4096, 0x0d452a5d -0, 268288, 268288, 2048, 4096, 0x36ef8482 -0, 270336, 270336, 2048, 4096, 0x462b641b -0, 272384, 272384, 2048, 4096, 0x2a5c1c0c -0, 274432, 274432, 2048, 4096, 0x8837ff80 -0, 276480, 276480, 2048, 4096, 0x27a3de22 -0, 278528, 278528, 2048, 4096, 0xf88d28c1 -0, 280576, 280576, 2048, 4096, 0xed85ea97 -0, 282624, 282624, 2048, 4096, 0x50c3e7db -0, 284672, 284672, 2048, 4096, 0x82bcb480 -0, 286720, 286720, 2048, 4096, 0xc50ee536 -0, 288768, 288768, 2048, 4096, 0x086280ee -0, 290816, 290816, 2048, 4096, 0x6f18f2b2 -0, 292864, 292864, 2048, 4096, 0x1c7c0856 -0, 294912, 294912, 2048, 4096, 0xc576268a -0, 296960, 296960, 2048, 4096, 0x7a9af56d -0, 299008, 299008, 2048, 4096, 0x6d058fc5 -0, 301056, 301056, 2048, 4096, 0x8fb1107b -0, 303104, 303104, 2048, 4096, 0x807588d1 -0, 305152, 305152, 2048, 4096, 0x56178443 -0, 307200, 307200, 2048, 4096, 0xf2460763 -0, 309248, 309248, 2048, 4096, 0x284255f2 -0, 311296, 311296, 2048, 4096, 0xb29d17fb -0, 313344, 313344, 2048, 4096, 0x5e7e4633 -0, 315392, 315392, 2048, 4096, 0x57704db1 -0, 317440, 317440, 2048, 4096, 0xd87dcc1d -0, 319488, 319488, 2048, 4096, 0x28d4bb93 -0, 321536, 321536, 2048, 4096, 0x3a2e5c6c -0, 323584, 323584, 2048, 4096, 0xf3581656 -0, 325632, 325632, 2048, 4096, 0x42f1942f -0, 327680, 327680, 2048, 4096, 0xe75c5092 -0, 329728, 329728, 2048, 4096, 0x3fae7f6d -0, 331776, 331776, 2048, 4096, 0xf99ad73e -0, 333824, 333824, 2048, 4096, 0x80564e3e -0, 335872, 335872, 2048, 4096, 0x8ff6ebe5 -0, 337920, 337920, 2048, 4096, 0x436d5e69 -0, 339968, 339968, 684, 1368, 0xe0ebeda3 +0, 0, 0, 2048, 4096, 0x4f9228b3 +0, 2048, 2048, 2048, 4096, 0xfab58157 +0, 4096, 4096, 2048, 4096, 0x0b641c78 +0, 6144, 6144, 2048, 4096, 0x601c6803 +0, 8192, 8192, 2048, 4096, 0xb3e2f166 +0, 10240, 10240, 2048, 4096, 0x5681f206 +0, 12288, 12288, 2048, 4096, 0x1e69e71f +0, 14336, 14336, 2048, 4096, 0x05628be3 +0, 16384, 16384, 2048, 4096, 0x109b1aef +0, 18432, 18432, 2048, 4096, 0xd5435a9e +0, 20480, 20480, 2048, 4096, 0xb38b5d28 +0, 22528, 22528, 2048, 4096, 0x64514c93 +0, 24576, 24576, 2048, 4096, 0x453350e7 +0, 26624, 26624, 2048, 4096, 0x6deccce6 +0, 28672, 28672, 2048, 4096, 0xd427ede1 +0, 30720, 30720, 2048, 4096, 0xdecb8c42 +0, 32768, 32768, 2048, 4096, 0x3841e4d2 +0, 34816, 34816, 2048, 4096, 0x858ac1b1 +0, 36864, 36864, 2048, 4096, 0x8e9dbfa0 +0, 38912, 38912, 2048, 4096, 0xcbc0766f +0, 40960, 40960, 2048, 4096, 0x78d52555 +0, 43008, 43008, 2048, 4096, 0x600ac7d5 +0, 45056, 45056, 2048, 4096, 0xafadb7ee +0, 47104, 47104, 2048, 4096, 0x8009d5a1 +0, 49152, 49152, 2048, 4096, 0xb07d475e +0, 51200, 51200, 2048, 4096, 0xfcfecceb +0, 53248, 53248, 2048, 4096, 0x38b5d85f +0, 55296, 55296, 2048, 4096, 0xbd48072e +0, 57344, 57344, 2048, 4096, 0xd04724d8 +0, 59392, 59392, 2048, 4096, 0x08425144 +0, 61440, 61440, 2048, 4096, 0x7b14483e +0, 63488, 63488, 2048, 4096, 0x8858ef4c +0, 65536, 65536, 2048, 4096, 0x1e3024c2 +0, 67584, 67584, 2048, 4096, 0xcd6bfe4f +0, 69632, 69632, 2048, 4096, 0x8cde8d18 +0, 71680, 71680, 2048, 4096, 0xbbd856b8 +0, 73728, 73728, 2048, 4096, 0x988c9b7a +0, 75776, 75776, 2048, 4096, 0x2a858e03 +0, 77824, 77824, 2048, 4096, 0x6dee1e4a +0, 79872, 79872, 2048, 4096, 0x8cc38b41 +0, 81920, 81920, 2048, 4096, 0x48bd5cec +0, 83968, 83968, 2048, 4096, 0xeb7f606b +0, 86016, 86016, 2048, 4096, 0x75f5d28c +0, 88064, 88064, 2048, 4096, 0x5bfeec4b +0, 90112, 90112, 2048, 4096, 0xfc35c22a +0, 92160, 92160, 2048, 4096, 0x3a95efba +0, 94208, 94208, 2048, 4096, 0xefdbce9c +0, 96256, 96256, 2048, 4096, 0x00594ada +0, 98304, 98304, 2048, 4096, 0x20ffebfa +0, 100352, 100352, 2048, 4096, 0x1b31370a +0, 102400, 102400, 2048, 4096, 0x50766a56 +0, 104448, 104448, 2048, 4096, 0x0058315a +0, 106496, 106496, 2048, 4096, 0x98090cbf +0, 108544, 108544, 2048, 4096, 0x66ed2d40 +0, 110592, 110592, 2048, 4096, 0xdfd7c0a7 +0, 112640, 112640, 2048, 4096, 0x2adc57e1 +0, 114688, 114688, 2048, 4096, 0x838bbc82 +0, 116736, 116736, 2048, 4096, 0x2c55de1a +0, 118784, 118784, 2048, 4096, 0xeae027f4 +0, 120832, 120832, 2048, 4096, 0x09fe00f6 +0, 122880, 122880, 2048, 4096, 0xa25d9970 +0, 124928, 124928, 2048, 4096, 0xedb11a20 +0, 126976, 126976, 2048, 4096, 0x9ce2e63e +0, 129024, 129024, 2048, 4096, 0xeb699974 +0, 131072, 131072, 2048, 4096, 0xcc04a296 +0, 133120, 133120, 2048, 4096, 0xe90e9a12 +0, 135168, 135168, 2048, 4096, 0xae85c0f7 +0, 137216, 137216, 2048, 4096, 0x7ee877db +0, 139264, 139264, 2048, 4096, 0x9ecf14ee +0, 141312, 141312, 2048, 4096, 0xa821cecd +0, 143360, 143360, 2048, 4096, 0x2714bb11 +0, 145408, 145408, 2048, 4096, 0x28f1c1e0 +0, 147456, 147456, 2048, 4096, 0xf81c4f60 +0, 149504, 149504, 2048, 4096, 0x1ae0e5a1 +0, 151552, 151552, 2048, 4096, 0xbdae9d9a +0, 153600, 153600, 2048, 4096, 0x5202e560 +0, 155648, 155648, 2048, 4096, 0x82408396 +0, 157696, 157696, 2048, 4096, 0xc850ce0c +0, 159744, 159744, 2048, 4096, 0x1d732d88 +0, 161792, 161792, 2048, 4096, 0xc5c01e33 +0, 163840, 163840, 2048, 4096, 0x84942d6c +0, 165888, 165888, 2048, 4096, 0x7c27cd3a +0, 167936, 167936, 2048, 4096, 0x22adc503 +0, 169984, 169984, 2048, 4096, 0xfbc3af31 +0, 172032, 172032, 2048, 4096, 0xe9652b18 +0, 174080, 174080, 2048, 4096, 0xae75987e +0, 176128, 176128, 2048, 4096, 0x0f7ea428 +0, 178176, 178176, 2048, 4096, 0x92b89582 +0, 180224, 180224, 2048, 4096, 0xf393d910 +0, 182272, 182272, 2048, 4096, 0x6349b600 +0, 184320, 184320, 2048, 4096, 0x16918dbd +0, 186368, 186368, 2048, 4096, 0x14ee15ad +0, 188416, 188416, 2048, 4096, 0x26b510d3 +0, 190464, 190464, 2048, 4096, 0x97007bf8 +0, 192512, 192512, 2048, 4096, 0x3718c509 +0, 194560, 194560, 2048, 4096, 0x24a54ccd +0, 196608, 196608, 2048, 4096, 0xc960df4e +0, 198656, 198656, 2048, 4096, 0xc7cb6e6f +0, 200704, 200704, 2048, 4096, 0x4c563ae5 +0, 202752, 202752, 2048, 4096, 0x0dd51432 +0, 204800, 204800, 2048, 4096, 0xdb4243c8 +0, 206848, 206848, 2048, 4096, 0x9bb6417f +0, 208896, 208896, 2048, 4096, 0xec6a40a1 +0, 210944, 210944, 2048, 4096, 0x82d6c3b4 +0, 212992, 212992, 2048, 4096, 0xd181e2ec +0, 215040, 215040, 2048, 4096, 0xba5d7b55 +0, 217088, 217088, 2048, 4096, 0x78fcb938 +0, 219136, 219136, 2048, 4096, 0x6691671c +0, 221184, 221184, 2048, 4096, 0x44fadee7 +0, 223232, 223232, 2048, 4096, 0xa42720d5 +0, 225280, 225280, 2048, 4096, 0xc1165a91 +0, 227328, 227328, 2048, 4096, 0x86aa3e3f +0, 229376, 229376, 2048, 4096, 0xab5ae57d +0, 231424, 231424, 2048, 4096, 0x291a91f3 +0, 233472, 233472, 2048, 4096, 0xfdf0dcfc +0, 235520, 235520, 2048, 4096, 0x1ef91f67 +0, 237568, 237568, 2048, 4096, 0xc899efee +0, 239616, 239616, 2048, 4096, 0x5ade15ac +0, 241664, 241664, 2048, 4096, 0x04516beb +0, 243712, 243712, 2048, 4096, 0xbf5ebbb9 +0, 245760, 245760, 2048, 4096, 0x4a235122 +0, 247808, 247808, 2048, 4096, 0xd7a3f4a6 +0, 249856, 249856, 2048, 4096, 0x5f900f20 +0, 251904, 251904, 2048, 4096, 0xa90b4365 +0, 253952, 253952, 2048, 4096, 0x63149dc4 +0, 256000, 256000, 2048, 4096, 0xf12c1ee8 +0, 258048, 258048, 2048, 4096, 0x6d0fec8c +0, 260096, 260096, 2048, 4096, 0x65e07850 +0, 262144, 262144, 2048, 4096, 0x16d951cc +0, 264192, 264192, 2048, 4096, 0xd296d0c4 +0, 266240, 266240, 2048, 4096, 0x619b2a53 +0, 268288, 268288, 2048, 4096, 0x316972d5 +0, 270336, 270336, 2048, 4096, 0xcfd64e21 +0, 272384, 272384, 2048, 4096, 0xcbcb10c6 +0, 274432, 274432, 2048, 4096, 0x20aeff7c +0, 276480, 276480, 2048, 4096, 0xd205dabd +0, 278528, 278528, 2048, 4096, 0xac9d3001 +0, 280576, 280576, 2048, 4096, 0x6d53dfdd +0, 282624, 282624, 2048, 4096, 0xbb9fe15c +0, 284672, 284672, 2048, 4096, 0x1852b88b +0, 286720, 286720, 2048, 4096, 0xb0acec01 +0, 288768, 288768, 2048, 4096, 0xb52a9342 +0, 290816, 290816, 2048, 4096, 0x7529faee +0, 292864, 292864, 2048, 4096, 0x150ff449 +0, 294912, 294912, 2048, 4096, 0xa81d31d9 +0, 296960, 296960, 2048, 4096, 0xbcb8084a +0, 299008, 299008, 2048, 4096, 0x07229514 +0, 301056, 301056, 2048, 4096, 0xa85cfd88 +0, 303104, 303104, 2048, 4096, 0x0aef9c27 +0, 305152, 305152, 2048, 4096, 0x8ec47b39 +0, 307200, 307200, 2048, 4096, 0x910b0560 +0, 309248, 309248, 2048, 4096, 0x99a8578e +0, 311296, 311296, 2048, 4096, 0xb3df1d84 +0, 313344, 313344, 2048, 4096, 0x48e52559 +0, 315392, 315392, 2048, 4096, 0xb25c4800 +0, 317440, 317440, 2048, 4096, 0x913bc8ce +0, 319488, 319488, 2048, 4096, 0xb736cc8c +0, 321536, 321536, 2048, 4096, 0x13c66646 +0, 323584, 323584, 2048, 4096, 0x70a71221 +0, 325632, 325632, 2048, 4096, 0x3a50a08e +0, 327680, 327680, 2048, 4096, 0xc0a037b0 +0, 329728, 329728, 2048, 4096, 0x9a789475 +0, 331776, 331776, 2048, 4096, 0xc890ca16 +0, 333824, 333824, 2048, 4096, 0xa0d34bed +0, 335872, 335872, 2048, 4096, 0x1689fa60 +0, 337920, 337920, 2048, 4096, 0x5bac4c83 +0, 339968, 339968, 684, 1368, 0x904be5e5 diff --git a/tests/ref/fate/g722enc b/tests/ref/fate/g722enc index c1094565b5..9b8e469a8b 100644 --- a/tests/ref/fate/g722enc +++ b/tests/ref/fate/g722enc @@ -1 +1 @@ -750269cc236541df28e15da5c7b0df7a +94e2f200d6e05b47cec4aa3e94571cf3 -- cgit v1.2.3 From 2f6528537fdd88820f3a4683d5e595d7b3a62689 Mon Sep 17 00:00:00 2001 From: Alex Converse Date: Thu, 1 Mar 2012 14:07:22 -0800 Subject: rv10/20: Fix a buffer overread caused by losing track of the remaining buffer size. Found-by: Mateusz "j00ru" Jurczyk and Gynvael Coldwind CC: libav-stable@libav.org --- libavcodec/rv10.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'libavcodec') diff --git a/libavcodec/rv10.c b/libavcodec/rv10.c index 6e6516feeb..5dd08e9fef 100644 --- a/libavcodec/rv10.c +++ b/libavcodec/rv10.c @@ -642,8 +642,12 @@ static int rv10_decode_frame(AVCodecContext *avctx, if(!avctx->slice_count){ slice_count = (*buf++) + 1; + buf_size--; slices_hdr = buf + 4; buf += 8 * slice_count; + buf_size -= 8 * slice_count; + if (buf_size <= 0) + return AVERROR_INVALIDDATA; }else slice_count = avctx->slice_count; @@ -689,7 +693,7 @@ static int rv10_decode_frame(AVCodecContext *avctx, s->current_picture_ptr= NULL; //so we can detect if frame_end wasnt called (find some nicer solution...) } - return buf_size; + return avpkt->size; } AVCodec ff_rv10_decoder = { -- cgit v1.2.3 From 71db86d53b5c6872cea31bf714a1a38ec78feaba Mon Sep 17 00:00:00 2001 From: Michael Niedermayer Date: Fri, 17 Feb 2012 13:35:10 -0800 Subject: h263dec: Disallow width/height changing with frame threads. Fixes CVE-2011-3937 Found-by: Mateusz "j00ru" Jurczyk and Gynvael Coldwind Signed-off-by: Michael Niedermayer --- libavcodec/h263dec.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) (limited to 'libavcodec') diff --git a/libavcodec/h263dec.c b/libavcodec/h263dec.c index 992e5fd32b..86282fdbd1 100644 --- a/libavcodec/h263dec.c +++ b/libavcodec/h263dec.c @@ -556,8 +556,7 @@ retry: #if HAVE_MMX if (s->codec_id == CODEC_ID_MPEG4 && s->xvid_build>=0 && avctx->idct_algo == FF_IDCT_AUTO && (av_get_cpu_flags() & AV_CPU_FLAG_MMX)) { avctx->idct_algo= FF_IDCT_XVIDMMX; - avctx->coded_width= 0; // force reinit -// ff_dsputil_init(&s->dsp, avctx); + ff_dct_common_init(s); s->picture_number=0; } #endif @@ -571,6 +570,12 @@ retry: || s->height != avctx->coded_height) { /* H.263 could change picture size any time */ ParseContext pc= s->parse_context; //FIXME move these demuxng hack to avformat + + if (HAVE_THREADS && (s->avctx->active_thread_type&FF_THREAD_FRAME)) { + av_log_missing_feature(s->avctx, "Width/height/bit depth/chroma idc changing with threads is", 0); + return -1; // width / height changed during parallelized decoding + } + s->parse_context.buffer=0; ff_MPV_common_end(s); s->parse_context= pc; -- cgit v1.2.3 From 9243ec4a508c81a621e941bb7e012e2d45d93659 Mon Sep 17 00:00:00 2001 From: Alex Converse Date: Thu, 1 Mar 2012 13:24:55 -0800 Subject: rv10/20: Fix slice overflow with checked bitstream reader. --- libavcodec/rv10.c | 28 +++++++++++++++++++++------- 1 file changed, 21 insertions(+), 7 deletions(-) (limited to 'libavcodec') diff --git a/libavcodec/rv10.c b/libavcodec/rv10.c index 5dd08e9fef..2b1a09dc69 100644 --- a/libavcodec/rv10.c +++ b/libavcodec/rv10.c @@ -499,9 +499,10 @@ static int rv10_decode_packet(AVCodecContext *avctx, const uint8_t *buf, int buf_size, int buf_size2) { MpegEncContext *s = avctx->priv_data; - int mb_count, mb_pos, left, start_mb_x; + int mb_count, mb_pos, left, start_mb_x, active_bits_size; - init_get_bits(&s->gb, buf, buf_size*8); + active_bits_size = buf_size * 8; + init_get_bits(&s->gb, buf, FFMAX(buf_size, buf_size2) * 8); if(s->codec_id ==CODEC_ID_RV10) mb_count = rv10_decode_picture_header(s); else @@ -584,13 +585,26 @@ static int rv10_decode_packet(AVCodecContext *avctx, s->mv_type = MV_TYPE_16X16; ret=ff_h263_decode_mb(s, s->block); - if (ret != SLICE_ERROR && s->gb.size_in_bits < get_bits_count(&s->gb) && 8*buf_size2 >= get_bits_count(&s->gb)){ - av_log(avctx, AV_LOG_DEBUG, "update size from %d to %d\n", s->gb.size_in_bits, 8*buf_size2); - s->gb.size_in_bits= 8*buf_size2; + // Repeat the slice end check from ff_h263_decode_mb with our active + // bitstream size + if (ret != SLICE_ERROR) { + int v = show_bits(&s->gb, 16); + + if (get_bits_count(&s->gb) + 16 > active_bits_size) + v >>= get_bits_count(&s->gb) + 16 - active_bits_size; + + if (!v) + ret = SLICE_END; + } + if (ret != SLICE_ERROR && active_bits_size < get_bits_count(&s->gb) && + 8 * buf_size2 >= get_bits_count(&s->gb)) { + active_bits_size = buf_size2 * 8; + av_log(avctx, AV_LOG_DEBUG, "update size from %d to %d\n", + 8 * buf_size, active_bits_size); ret= SLICE_OK; } - if (ret == SLICE_ERROR || s->gb.size_in_bits < get_bits_count(&s->gb)) { + if (ret == SLICE_ERROR || active_bits_size < get_bits_count(&s->gb)) { av_log(s->avctx, AV_LOG_ERROR, "ERROR at MB %d %d\n", s->mb_x, s->mb_y); return -1; } @@ -612,7 +626,7 @@ static int rv10_decode_packet(AVCodecContext *avctx, ff_er_add_slice(s, start_mb_x, s->resync_mb_y, s->mb_x-1, s->mb_y, ER_MB_END); - return s->gb.size_in_bits; + return active_bits_size; } static int get_slice_offset(AVCodecContext *avctx, const uint8_t *buf, int n) -- cgit v1.2.3 From 9d25f1f6194dba9cfd60c0596aa59ad145d61382 Mon Sep 17 00:00:00 2001 From: Mashiat Sarker Shakkhar Date: Thu, 1 Mar 2012 12:43:00 +0000 Subject: Windows Media Audio Lossless decoder MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Decodes 16-bit WMA Lossless encoded files. 24-bit is not supported yet. Bitstream parser written by Andreas Öman with contributions from Baptiste Coudurier and Ulion. Includes a number of bug-fixes from Benjamin Larsson, Michael Niedermayer and Konstantin Shishkov, shine and polish by Diego Biurrun. Signed-off-by: Diego Biurrun --- Changelog | 1 + doc/general.texi | 1 + libavcodec/Makefile | 1 + libavcodec/allcodecs.c | 1 + libavcodec/version.h | 2 +- libavcodec/wmalosslessdec.c | 1248 +++++++++++++++++++++++++++++++++++++++++++ 6 files changed, 1253 insertions(+), 1 deletion(-) create mode 100644 libavcodec/wmalosslessdec.c (limited to 'libavcodec') diff --git a/Changelog b/Changelog index 9dc2ae951c..87039559ec 100644 --- a/Changelog +++ b/Changelog @@ -11,6 +11,7 @@ version : - Sun Rasterfile Encoder - remove libpostproc - ID3v2 attached pictures reading and writing +- WMA Lossless decoder version 0.8: diff --git a/doc/general.texi b/doc/general.texi index c61951ac71..9f3108129b 100644 --- a/doc/general.texi +++ b/doc/general.texi @@ -768,6 +768,7 @@ following image formats are supported: @item Westwood Audio (SND1) @tab @tab X @item Windows Media Audio 1 @tab X @tab X @item Windows Media Audio 2 @tab X @tab X +@item Windows Media Audio Lossless @tab @tab X @item Windows Media Audio Pro @tab @tab X @item Windows Media Audio Voice @tab @tab X @end multitable diff --git a/libavcodec/Makefile b/libavcodec/Makefile index 53e67dc97c..33a19748eb 100644 --- a/libavcodec/Makefile +++ b/libavcodec/Makefile @@ -418,6 +418,7 @@ OBJS-$(CONFIG_VP6_DECODER) += vp6.o vp56.o vp56data.o vp56dsp.o \ OBJS-$(CONFIG_VP8_DECODER) += vp8.o vp8dsp.o vp56rac.o OBJS-$(CONFIG_VQA_DECODER) += vqavideo.o OBJS-$(CONFIG_WAVPACK_DECODER) += wavpack.o +OBJS-$(CONFIG_WMALOSSLESS_DECODER) += wmalosslessdec.o wma.o OBJS-$(CONFIG_WMAPRO_DECODER) += wmaprodec.o wma.o OBJS-$(CONFIG_WMAV1_DECODER) += wmadec.o wma.o aactab.o OBJS-$(CONFIG_WMAV1_ENCODER) += wmaenc.o wma.o aactab.o diff --git a/libavcodec/allcodecs.c b/libavcodec/allcodecs.c index 3d3289c4ee..2844cfcbd7 100644 --- a/libavcodec/allcodecs.c +++ b/libavcodec/allcodecs.c @@ -289,6 +289,7 @@ void avcodec_register_all(void) REGISTER_DECODER (VMDAUDIO, vmdaudio); REGISTER_ENCDEC (VORBIS, vorbis); REGISTER_DECODER (WAVPACK, wavpack); + REGISTER_DECODER (WMALOSSLESS, wmalossless); REGISTER_DECODER (WMAPRO, wmapro); REGISTER_ENCDEC (WMAV1, wmav1); REGISTER_ENCDEC (WMAV2, wmav2); diff --git a/libavcodec/version.h b/libavcodec/version.h index 49f929f024..7790f24c0c 100644 --- a/libavcodec/version.h +++ b/libavcodec/version.h @@ -21,7 +21,7 @@ #define AVCODEC_VERSION_H #define LIBAVCODEC_VERSION_MAJOR 54 -#define LIBAVCODEC_VERSION_MINOR 4 +#define LIBAVCODEC_VERSION_MINOR 5 #define LIBAVCODEC_VERSION_MICRO 0 #define LIBAVCODEC_VERSION_INT AV_VERSION_INT(LIBAVCODEC_VERSION_MAJOR, \ diff --git a/libavcodec/wmalosslessdec.c b/libavcodec/wmalosslessdec.c new file mode 100644 index 0000000000..d311c39605 --- /dev/null +++ b/libavcodec/wmalosslessdec.c @@ -0,0 +1,1248 @@ +/* + * Windows Media Audio Lossless decoder + * Copyright (c) 2007 Baptiste Coudurier, Benjamin Larsson, Ulion + * Copyright (c) 2008 - 2011 Sascha Sommer, Benjamin Larsson + * Copyright (c) 2011 Andreas Öman + * Copyright (c) 2011 - 2012 Mashiat Sarker Shakkhar + * + * This file is part of Libav. + * + * Libav 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, + * 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 + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "avcodec.h" +#include "internal.h" +#include "get_bits.h" +#include "put_bits.h" +#include "wma.h" + +/** current decoder limitations */ +#define WMALL_MAX_CHANNELS 8 ///< max number of handled channels +#define MAX_SUBFRAMES 32 ///< max number of subframes per channel +#define MAX_BANDS 29 ///< max number of scale factor bands +#define MAX_FRAMESIZE 32768 ///< maximum compressed frame size + +#define WMALL_BLOCK_MIN_BITS 6 ///< log2 of min block size +#define WMALL_BLOCK_MAX_BITS 12 ///< log2 of max block size +#define WMALL_BLOCK_MAX_SIZE (1 << WMALL_BLOCK_MAX_BITS) ///< maximum block size +#define WMALL_BLOCK_SIZES (WMALL_BLOCK_MAX_BITS - WMALL_BLOCK_MIN_BITS + 1) ///< possible block sizes + + +/** + * @brief frame-specific decoder context for a single channel + */ +typedef struct { + int16_t prev_block_len; ///< length of the previous block + uint8_t transmit_coefs; + uint8_t num_subframes; + uint16_t subframe_len[MAX_SUBFRAMES]; ///< subframe length in samples + uint16_t subframe_offsets[MAX_SUBFRAMES]; ///< subframe positions in the current frame + uint8_t cur_subframe; ///< current subframe number + uint16_t decoded_samples; ///< number of already processed samples + int quant_step; ///< quantization step for the current subframe + int transient_counter; ///< number of transient samples from the beginning of the transient zone +} WmallChannelCtx; + +/** + * @brief main decoder context + */ +typedef struct WmallDecodeCtx { + /* generic decoder variables */ + AVCodecContext *avctx; + AVFrame frame; + uint8_t frame_data[MAX_FRAMESIZE + FF_INPUT_BUFFER_PADDING_SIZE]; ///< compressed frame data + PutBitContext pb; ///< context for filling the frame_data buffer + + /* frame size dependent frame information (set during initialization) */ + uint32_t decode_flags; ///< used compression features + int len_prefix; ///< frame is prefixed with its length + int dynamic_range_compression; ///< frame contains DRC data + uint8_t bits_per_sample; ///< integer audio sample size for the unscaled IMDCT output (used to scale to [-1.0, 1.0]) + uint16_t samples_per_frame; ///< number of samples to output + uint16_t log2_frame_size; + int8_t num_channels; ///< number of channels in the stream (same as AVCodecContext.num_channels) + int8_t lfe_channel; ///< lfe channel index + uint8_t max_num_subframes; + uint8_t subframe_len_bits; ///< number of bits used for the subframe length + uint8_t max_subframe_len_bit; ///< flag indicating that the subframe is of maximum size when the first subframe length bit is 1 + uint16_t min_samples_per_subframe; + + /* packet decode state */ + GetBitContext pgb; ///< bitstream reader context for the packet + int next_packet_start; ///< start offset of the next WMA packet in the demuxer packet + uint8_t packet_offset; ///< offset to the frame in the packet + uint8_t packet_sequence_number; ///< current packet number + int num_saved_bits; ///< saved number of bits + int frame_offset; ///< frame offset in the bit reservoir + int subframe_offset; ///< subframe offset in the bit reservoir + uint8_t packet_loss; ///< set in case of bitstream error + uint8_t packet_done; ///< set when a packet is fully decoded + + /* frame decode state */ + uint32_t frame_num; ///< current frame number (not used for decoding) + GetBitContext gb; ///< bitstream reader context + int buf_bit_size; ///< buffer size in bits + int16_t *samples_16; ///< current samplebuffer pointer (16-bit) + int16_t *samples_16_end; ///< maximum samplebuffer pointer + int *samples_32; ///< current samplebuffer pointer (24-bit) + int *samples_32_end; ///< maximum samplebuffer pointer + uint8_t drc_gain; ///< gain for the DRC tool + int8_t skip_frame; ///< skip output step + int8_t parsed_all_subframes; ///< all subframes decoded? + + /* subframe/block decode state */ + int16_t subframe_len; ///< current subframe length + int8_t channels_for_cur_subframe; ///< number of channels that contain the subframe + int8_t channel_indexes_for_cur_subframe[WMALL_MAX_CHANNELS]; + + WmallChannelCtx channel[WMALL_MAX_CHANNELS]; ///< per channel data + + // WMA Lossless-specific + + uint8_t do_arith_coding; + uint8_t do_ac_filter; + uint8_t do_inter_ch_decorr; + uint8_t do_mclms; + uint8_t do_lpc; + + int8_t acfilter_order; + int8_t acfilter_scaling; + int64_t acfilter_coeffs[16]; + int acfilter_prevvalues[2][16]; + + int8_t mclms_order; + int8_t mclms_scaling; + int16_t mclms_coeffs[128]; + int16_t mclms_coeffs_cur[4]; + int16_t mclms_prevvalues[64]; + int16_t mclms_updates[64]; + int mclms_recent; + + int movave_scaling; + int quant_stepsize; + + struct { + int order; + int scaling; + int coefsend; + int bitsend; + int16_t coefs[256]; + int16_t lms_prevvalues[512]; + int16_t lms_updates[512]; + int recent; + } cdlms[2][9]; + + int cdlms_ttl[2]; + + int bV3RTM; + + int is_channel_coded[2]; + int update_speed[2]; + + int transient[2]; + int transient_pos[2]; + int seekable_tile; + + int ave_sum[2]; + + int channel_residues[2][2048]; + + int lpc_coefs[2][40]; + int lpc_order; + int lpc_scaling; + int lpc_intbits; + + int channel_coeffs[2][2048]; +} WmallDecodeCtx; + + +static av_cold int decode_init(AVCodecContext *avctx) +{ + WmallDecodeCtx *s = avctx->priv_data; + uint8_t *edata_ptr = avctx->extradata; + unsigned int channel_mask; + int i, log2_max_num_subframes, num_possible_block_sizes; + + s->avctx = avctx; + init_put_bits(&s->pb, s->frame_data, MAX_FRAMESIZE); + + if (avctx->extradata_size >= 18) { + s->decode_flags = AV_RL16(edata_ptr + 14); + channel_mask = AV_RL32(edata_ptr + 2); + s->bits_per_sample = AV_RL16(edata_ptr); + if (s->bits_per_sample == 16) + avctx->sample_fmt = AV_SAMPLE_FMT_S16; + else if (s->bits_per_sample == 24) { + avctx->sample_fmt = AV_SAMPLE_FMT_S32; + av_log_missing_feature(avctx, "bit-depth higher than 16", 0); + return AVERROR_PATCHWELCOME; + } else { + av_log(avctx, AV_LOG_ERROR, "Unknown bit-depth: %d\n", + s->bits_per_sample); + return AVERROR_INVALIDDATA; + } + /* dump the extradata */ + for (i = 0; i < avctx->extradata_size; i++) + av_dlog(avctx, AV_LOG_DEBUG, "[%x] ", avctx->extradata[i]); + av_dlog(avctx, AV_LOG_DEBUG, "\n"); + + } else { + av_log_ask_for_sample(avctx, "Unsupported extradata size\n"); + return AVERROR_INVALIDDATA; + } + + /* generic init */ + s->log2_frame_size = av_log2(avctx->block_align) + 4; + + /* frame info */ + s->skip_frame = 1; /* skip first frame */ + s->packet_loss = 1; + s->len_prefix = s->decode_flags & 0x40; + + /* get frame len */ + s->samples_per_frame = 1 << ff_wma_get_frame_len_bits(avctx->sample_rate, + 3, s->decode_flags); + + /* init previous block len */ + for (i = 0; i < avctx->channels; i++) + s->channel[i].prev_block_len = s->samples_per_frame; + + /* subframe info */ + log2_max_num_subframes = (s->decode_flags & 0x38) >> 3; + s->max_num_subframes = 1 << log2_max_num_subframes; + s->max_subframe_len_bit = 0; + s->subframe_len_bits = av_log2(log2_max_num_subframes) + 1; + + num_possible_block_sizes = log2_max_num_subframes + 1; + s->min_samples_per_subframe = s->samples_per_frame / s->max_num_subframes; + s->dynamic_range_compression = s->decode_flags & 0x80; + s->bV3RTM = s->decode_flags & 0x100; + + if (s->max_num_subframes > MAX_SUBFRAMES) { + av_log(avctx, AV_LOG_ERROR, "invalid number of subframes %i\n", + s->max_num_subframes); + return AVERROR_INVALIDDATA; + } + + s->num_channels = avctx->channels; + + /* extract lfe channel position */ + s->lfe_channel = -1; + + if (channel_mask & 8) { + unsigned int mask; + for (mask = 1; mask < 16; mask <<= 1) + if (channel_mask & mask) + ++s->lfe_channel; + } + + if (s->num_channels < 0) { + av_log(avctx, AV_LOG_ERROR, "invalid number of channels %d\n", + s->num_channels); + return AVERROR_INVALIDDATA; + } else if (s->num_channels > WMALL_MAX_CHANNELS) { + av_log_ask_for_sample(avctx, "unsupported number of channels\n"); + return AVERROR_PATCHWELCOME; + } + + avcodec_get_frame_defaults(&s->frame); + avctx->coded_frame = &s->frame; + avctx->channel_layout = channel_mask; + return 0; +} + +/** + * @brief Decode the subframe length. + * @param s context + * @param offset sample offset in the frame + * @return decoded subframe length on success, < 0 in case of an error + */ +static int decode_subframe_length(WmallDecodeCtx *s, int offset) +{ + int frame_len_ratio, subframe_len, len; + + /* no need to read from the bitstream when only one length is possible */ + if (offset == s->samples_per_frame - s->min_samples_per_subframe) + return s->min_samples_per_subframe; + + len = av_log2(s->max_num_subframes - 1) + 1; + frame_len_ratio = get_bits(&s->gb, len); + subframe_len = s->min_samples_per_subframe * (frame_len_ratio + 1); + + /* sanity check the length */ + if (subframe_len < s->min_samples_per_subframe || + subframe_len > s->samples_per_frame) { + av_log(s->avctx, AV_LOG_ERROR, "broken frame: subframe_len %i\n", + subframe_len); + return AVERROR_INVALIDDATA; + } + return subframe_len; +} + +/** + * @brief Decode how the data in the frame is split into subframes. + * Every WMA frame contains the encoded data for a fixed number of + * samples per channel. The data for every channel might be split + * into several subframes. This function will reconstruct the list of + * subframes for every channel. + * + * If the subframes are not evenly split, the algorithm estimates the + * channels with the lowest number of total samples. + * Afterwards, for each of these channels a bit is read from the + * bitstream that indicates if the channel contains a subframe with the + * next subframe size that is going to be read from the bitstream or not. + * If a channel contains such a subframe, the subframe size gets added to + * the channel's subframe list. + * The algorithm repeats these steps until the frame is properly divided + * between the individual channels. + * + * @param s context + * @return 0 on success, < 0 in case of an error + */ +static int decode_tilehdr(WmallDecodeCtx *s) +{ + uint16_t num_samples[WMALL_MAX_CHANNELS] = { 0 }; /* sum of samples for all currently known subframes of a channel */ + uint8_t contains_subframe[WMALL_MAX_CHANNELS]; /* flag indicating if a channel contains the current subframe */ + int channels_for_cur_subframe = s->num_channels; /* number of channels that contain the current subframe */ + int fixed_channel_layout = 0; /* flag indicating that all channels use the same subfra2me offsets and sizes */ + int min_channel_len = 0; /* smallest sum of samples (channels with this length will be processed first) */ + int c, tile_aligned; + + /* reset tiling information */ + for (c = 0; c < s->num_channels; c++) + s->channel[c].num_subframes = 0; + + tile_aligned = get_bits1(&s->gb); + if (s->max_num_subframes == 1 || tile_aligned) + fixed_channel_layout = 1; + + /* loop until the frame data is split between the subframes */ + do { + int subframe_len; + + /* check which channels contain the subframe */ + for (c = 0; c < s->num_channels; c++) { + if (num_samples[c] == min_channel_len) { + if (fixed_channel_layout || channels_for_cur_subframe == 1 || + (min_channel_len == s->samples_per_frame - s->min_samples_per_subframe)) { + contains_subframe[c] = 1; + } else { + contains_subframe[c] = get_bits1(&s->gb); + } + } else + contains_subframe[c] = 0; + } + + /* get subframe length, subframe_len == 0 is not allowed */ + if ((subframe_len = decode_subframe_length(s, min_channel_len)) <= 0) + return AVERROR_INVALIDDATA; + /* add subframes to the individual channels and find new min_channel_len */ + min_channel_len += subframe_len; + for (c = 0; c < s->num_channels; c++) { + WmallChannelCtx *chan = &s->channel[c]; + + if (contains_subframe[c]) { + if (chan->num_subframes >= MAX_SUBFRAMES) { + av_log(s->avctx, AV_LOG_ERROR, + "broken frame: num subframes > 31\n"); + return AVERROR_INVALIDDATA; + } + chan->subframe_len[chan->num_subframes] = subframe_len; + num_samples[c] += subframe_len; + ++chan->num_subframes; + if (num_samples[c] > s->samples_per_frame) { + av_log(s->avctx, AV_LOG_ERROR, "broken frame: " + "channel len(%d) > samples_per_frame(%d)\n", + num_samples[c], s->samples_per_frame); + return AVERROR_INVALIDDATA; + } + } else if (num_samples[c] <= min_channel_len) { + if (num_samples[c] < min_channel_len) { + channels_for_cur_subframe = 0; + min_channel_len = num_samples[c]; + } + ++channels_for_cur_subframe; + } + } + } while (min_channel_len < s->samples_per_frame); + + for (c = 0; c < s->num_channels; c++) { + int i, offset = 0; + for (i = 0; i < s->channel[c].num_subframes; i++) { + s->channel[c].subframe_offsets[i] = offset; + offset += s->channel[c].subframe_len[i]; + } + } + + return 0; +} + +static void decode_ac_filter(WmallDecodeCtx *s) +{ + int i; + s->acfilter_order = get_bits(&s->gb, 4) + 1; + s->acfilter_scaling = get_bits(&s->gb, 4); + + for (i = 0; i < s->acfilter_order; i++) + s->acfilter_coeffs[i] = get_bits(&s->gb, s->acfilter_scaling) + 1; +} + +static void decode_mclms(WmallDecodeCtx *s) +{ + s->mclms_order = (get_bits(&s->gb, 4) + 1) * 2; + s->mclms_scaling = get_bits(&s->gb, 4); + if (get_bits1(&s->gb)) { + int i, send_coef_bits; + int cbits = av_log2(s->mclms_scaling + 1); + assert(cbits == my_log2(s->mclms_scaling + 1)); + if (1 << cbits < s->mclms_scaling + 1) + cbits++; + + send_coef_bits = (cbits ? get_bits(&s->gb, cbits) : 0) + 2; + + for (i = 0; i < s->mclms_order * s->num_channels * s->num_channels; i++) + s->mclms_coeffs[i] = get_bits(&s->gb, send_coef_bits); + + for (i = 0; i < s->num_channels; i++) { + int c; + for (c = 0; c < i; c++) + s->mclms_coeffs_cur[i * s->num_channels + c] = get_bits(&s->gb, send_coef_bits); + } + } +} + +static void decode_cdlms(WmallDecodeCtx *s) +{ + int c, i; + int cdlms_send_coef = get_bits1(&s->gb); + + for (c = 0; c < s->num_channels; c++) { + s->cdlms_ttl[c] = get_bits(&s->gb, 3) + 1; + for (i = 0; i < s->cdlms_ttl[c]; i++) + s->cdlms[c][i].order = (get_bits(&s->gb, 7) + 1) * 8; + + for (i = 0; i < s->cdlms_ttl[c]; i++) + s->cdlms[c][i].scaling = get_bits(&s->gb, 4); + + if (cdlms_send_coef) { + for (i = 0; i < s->cdlms_ttl[c]; i++) { + int cbits, shift_l, shift_r, j; + cbits = av_log2(s->cdlms[c][i].order); + if ((1 << cbits) < s->cdlms[c][i].order) + cbits++; + s->cdlms[c][i].coefsend = get_bits(&s->gb, cbits) + 1; + + cbits = av_log2(s->cdlms[c][i].scaling + 1); + if ((1 << cbits) < s->cdlms[c][i].scaling + 1) + cbits++; + + s->cdlms[c][i].bitsend = get_bits(&s->gb, cbits) + 2; + shift_l = 32 - s->cdlms[c][i].bitsend; + shift_r = 32 - s->cdlms[c][i].scaling - 2; + for (j = 0; j < s->cdlms[c][i].coefsend; j++) + s->cdlms[c][i].coefs[j] = + (get_bits(&s->gb, s->cdlms[c][i].bitsend) << shift_l) >> shift_r; + } + } + } +} + +static int decode_channel_residues(WmallDecodeCtx *s, int ch, int tile_size) +{ + int i = 0; + unsigned int ave_mean; + s->transient[ch] = get_bits1(&s->gb); + if (s->transient[ch]) { + s->transient_pos[ch] = get_bits(&s->gb, av_log2(tile_size)); + if (s->transient_pos[ch]) + s->transient[ch] = 0; + s->channel[ch].transient_counter = + FFMAX(s->channel[ch].transient_counter, s->samples_per_frame / 2); + } else if (s->channel[ch].transient_counter) + s->transient[ch] = 1; + + if (s->seekable_tile) { + ave_mean = get_bits(&s->gb, s->bits_per_sample); + s->ave_sum[ch] = ave_mean << (s->movave_scaling + 1); + } + + if (s->seekable_tile) { + if (s->do_inter_ch_decorr) + s->channel_residues[ch][0] = get_sbits(&s->gb, s->bits_per_sample + 1); + else + s->channel_residues[ch][0] = get_sbits(&s->gb, s->bits_per_sample); + i++; + } + for (; i < tile_size; i++) { + int quo = 0, rem, rem_bits, residue; + while(get_bits1(&s->gb)) { + quo++; + if (get_bits_left(&s->gb) <= 0) + return -1; + } + if (quo >= 32) + quo += get_bits_long(&s->gb, get_bits(&s->gb, 5) + 1); + + ave_mean = (s->ave_sum[ch] + (1 << s->movave_scaling)) >> (s->movave_scaling + 1); + if (ave_mean <= 1) + residue = quo; + else { + rem_bits = av_ceil_log2(ave_mean); + rem = rem_bits ? get_bits(&s->gb, rem_bits) : 0; + residue = (quo << rem_bits) + rem; + } + + s->ave_sum[ch] = residue + s->ave_sum[ch] - + (s->ave_sum[ch] >> s->movave_scaling); + + if (residue & 1) + residue = -(residue >> 1) - 1; + else + residue = residue >> 1; + s->channel_residues[ch][i] = residue; + } + + return 0; + +} + +static void decode_lpc(WmallDecodeCtx *s) +{ + int ch, i, cbits; + s->lpc_order = get_bits(&s->gb, 5) + 1; + s->lpc_scaling = get_bits(&s->gb, 4); + s->lpc_intbits = get_bits(&s->gb, 3) + 1; + cbits = s->lpc_scaling + s->lpc_intbits; + for (ch = 0; ch < s->num_channels; ch++) + for (i = 0; i < s->lpc_order; i++) + s->lpc_coefs[ch][i] = get_sbits(&s->gb, cbits); +} + +static void clear_codec_buffers(WmallDecodeCtx *s) +{ + int ich, ilms; + + memset(s->acfilter_coeffs, 0, sizeof(s->acfilter_coeffs)); + memset(s->acfilter_prevvalues, 0, sizeof(s->acfilter_prevvalues)); + memset(s->lpc_coefs, 0, sizeof(s->lpc_coefs)); + + memset(s->mclms_coeffs, 0, sizeof(s->mclms_coeffs)); + memset(s->mclms_coeffs_cur, 0, sizeof(s->mclms_coeffs_cur)); + memset(s->mclms_prevvalues, 0, sizeof(s->mclms_prevvalues)); + memset(s->mclms_updates, 0, sizeof(s->mclms_updates)); + + for (ich = 0; ich < s->num_channels; ich++) { + for (ilms = 0; ilms < s->cdlms_ttl[ich]; ilms++) { + memset(s->cdlms[ich][ilms].coefs, 0, + sizeof(s->cdlms[ich][ilms].coefs)); + memset(s->cdlms[ich][ilms].lms_prevvalues, 0, + sizeof(s->cdlms[ich][ilms].lms_prevvalues)); + memset(s->cdlms[ich][ilms].lms_updates, 0, + sizeof(s->cdlms[ich][ilms].lms_updates)); + } + s->ave_sum[ich] = 0; + } +} + +/** + * @brief Reset filter parameters and transient area at new seekable tile. + */ +static void reset_codec(WmallDecodeCtx *s) +{ + int ich, ilms; + s->mclms_recent = s->mclms_order * s->num_channels; + for (ich = 0; ich < s->num_channels; ich++) { + for (ilms = 0; ilms < s->cdlms_ttl[ich]; ilms++) + s->cdlms[ich][ilms].recent = s->cdlms[ich][ilms].order; + /* first sample of a seekable subframe is considered as the starting of + a transient area which is samples_per_frame samples long */ + s->channel[ich].transient_counter = s->samples_per_frame; + s->transient[ich] = 1; + s->transient_pos[ich] = 0; + } +} + +static void mclms_update(WmallDecodeCtx *s, int icoef, int *pred) +{ + int i, j, ich, pred_error; + int order = s->mclms_order; + int num_channels = s->num_channels; + int range = 1 << (s->bits_per_sample - 1); + + for (ich = 0; ich < num_channels; ich++) { + pred_error = s->channel_residues[ich][icoef] - pred[ich]; + if (pred_error > 0) { + for (i = 0; i < order * num_channels; i++) + s->mclms_coeffs[i + ich * order * num_channels] += + s->mclms_updates[s->mclms_recent + i]; + for (j = 0; j < ich; j++) { + if (s->channel_residues[j][icoef] > 0) + s->mclms_coeffs_cur[ich * num_channels + j] += 1; + else if (s->channel_residues[j][icoef] < 0) + s->mclms_coeffs_cur[ich * num_channels + j] -= 1; + } + } else if (pred_error < 0) { + for (i = 0; i < order * num_channels; i++) + s->mclms_coeffs[i + ich * order * num_channels] -= + s->mclms_updates[s->mclms_recent + i]; + for (j = 0; j < ich; j++) { + if (s->channel_residues[j][icoef] > 0) + s->mclms_coeffs_cur[ich * num_channels + j] -= 1; + else if (s->channel_residues[j][icoef] < 0) + s->mclms_coeffs_cur[ich * num_channels + j] += 1; + } + } + } + + for (ich = num_channels - 1; ich >= 0; ich--) { + s->mclms_recent--; + s->mclms_prevvalues[s->mclms_recent] = s->channel_residues[ich][icoef]; + if (s->channel_residues[ich][icoef] > range - 1) + s->mclms_prevvalues[s->mclms_recent] = range - 1; + else if (s->channel_residues[ich][icoef] < -range) + s->mclms_prevvalues[s->mclms_recent] = -range; + + s->mclms_updates[s->mclms_recent] = 0; + if (s->channel_residues[ich][icoef] > 0) + s->mclms_updates[s->mclms_recent] = 1; + else if (s->channel_residues[ich][icoef] < 0) + s->mclms_updates[s->mclms_recent] = -1; + } + + if (s->mclms_recent == 0) { + memcpy(&s->mclms_prevvalues[order * num_channels], + s->mclms_prevvalues, + 2 * order * num_channels); + memcpy(&s->mclms_updates[order * num_channels], + s->mclms_updates, + 2 * order * num_channels); + s->mclms_recent = num_channels * order; + } +} + +static void mclms_predict(WmallDecodeCtx *s, int icoef, int *pred) +{ + int ich, i; + int order = s->mclms_order; + int num_channels = s->num_channels; + + for (ich = 0; ich < num_channels; ich++) { + if (!s->is_channel_coded[ich]) + continue; + pred[ich] = 0; + for (i = 0; i < order * num_channels; i++) + pred[ich] += s->mclms_prevvalues[i + s->mclms_recent] * + s->mclms_coeffs[i + order * num_channels * ich]; + for (i = 0; i < ich; i++) + pred[ich] += s->channel_residues[i][icoef] * + s->mclms_coeffs_cur[i + num_channels * ich]; + pred[ich] += 1 << s->mclms_scaling - 1; + pred[ich] >>= s->mclms_scaling; + s->channel_residues[ich][icoef] += pred[ich]; + } +} + +static void revert_mclms(WmallDecodeCtx *s, int tile_size) +{ + int icoef, pred[WMALL_MAX_CHANNELS] = { 0 }; + for (icoef = 0; icoef < tile_size; icoef++) { + mclms_predict(s, icoef, pred); + mclms_update(s, icoef, pred); + } +} + +static int lms_predict(WmallDecodeCtx *s, int ich, int ilms) +{ + int pred = 0, icoef; + int recent = s->cdlms[ich][ilms].recent; + + for (icoef = 0; icoef < s->cdlms[ich][ilms].order; icoef++) + pred += s->cdlms[ich][ilms].coefs[icoef] * + s->cdlms[ich][ilms].lms_prevvalues[icoef + recent]; + + return pred; +} + +static void lms_update(WmallDecodeCtx *s, int ich, int ilms, + int input, int residue) +{ + int icoef; + int recent = s->cdlms[ich][ilms].recent; + int range = 1 << s->bits_per_sample - 1; + + if (residue < 0) { + for (icoef = 0; icoef < s->cdlms[ich][ilms].order; icoef++) + s->cdlms[ich][ilms].coefs[icoef] -= + s->cdlms[ich][ilms].lms_updates[icoef + recent]; + } else if (residue > 0) { + for (icoef = 0; icoef < s->cdlms[ich][ilms].order; icoef++) + s->cdlms[ich][ilms].coefs[icoef] += + s->cdlms[ich][ilms].lms_updates[icoef + recent]; + } + + if (recent) + recent--; + else { + memcpy(&s->cdlms[ich][ilms].lms_prevvalues[s->cdlms[ich][ilms].order], + s->cdlms[ich][ilms].lms_prevvalues, + 2 * s->cdlms[ich][ilms].order); + memcpy(&s->cdlms[ich][ilms].lms_updates[s->cdlms[ich][ilms].order], + s->cdlms[ich][ilms].lms_updates, + 2 * s->cdlms[ich][ilms].order); + recent = s->cdlms[ich][ilms].order - 1; + } + + s->cdlms[ich][ilms].lms_prevvalues[recent] = av_clip(input, -range, range - 1); + if (!input) + s->cdlms[ich][ilms].lms_updates[recent] = 0; + else if (input < 0) + s->cdlms[ich][ilms].lms_updates[recent] = -s->update_speed[ich]; + else + s->cdlms[ich][ilms].lms_updates[recent] = s->update_speed[ich]; + + s->cdlms[ich][ilms].lms_updates[recent + (s->cdlms[ich][ilms].order >> 4)] >>= 2; + s->cdlms[ich][ilms].lms_updates[recent + (s->cdlms[ich][ilms].order >> 3)] >>= 1; + s->cdlms[ich][ilms].recent = recent; +} + +static void use_high_update_speed(WmallDecodeCtx *s, int ich) +{ + int ilms, recent, icoef; + for (ilms = s->cdlms_ttl[ich] - 1; ilms >= 0; ilms--) { + recent = s->cdlms[ich][ilms].recent; + if (s->update_speed[ich] == 16) + continue; + if (s->bV3RTM) { + for (icoef = 0; icoef < s->cdlms[ich][ilms].order; icoef++) + s->cdlms[ich][ilms].lms_updates[icoef + recent] *= 2; + } else { + for (icoef = 0; icoef < s->cdlms[ich][ilms].order; icoef++) + s->cdlms[ich][ilms].lms_updates[icoef] *= 2; + } + } + s->update_speed[ich] = 16; +} + +static void use_normal_update_speed(WmallDecodeCtx *s, int ich) +{ + int ilms, recent, icoef; + for (ilms = s->cdlms_ttl[ich] - 1; ilms >= 0; ilms--) { + recent = s->cdlms[ich][ilms].recent; + if (s->update_speed[ich] == 8) + continue; + if (s->bV3RTM) + for (icoef = 0; icoef < s->cdlms[ich][ilms].order; icoef++) + s->cdlms[ich][ilms].lms_updates[icoef + recent] /= 2; + else + for (icoef = 0; icoef < s->cdlms[ich][ilms].order; icoef++) + s->cdlms[ich][ilms].lms_updates[icoef] /= 2; + } + s->update_speed[ich] = 8; +} + +static void revert_cdlms(WmallDecodeCtx *s, int ch, + int coef_begin, int coef_end) +{ + int icoef, pred, ilms, num_lms, residue, input; + + num_lms = s->cdlms_ttl[ch]; + for (ilms = num_lms - 1; ilms >= 0; ilms--) { + for (icoef = coef_begin; icoef < coef_end; icoef++) { + pred = 1 << (s->cdlms[ch][ilms].scaling - 1); + residue = s->channel_residues[ch][icoef]; + pred += lms_predict(s, ch, ilms); + input = residue + (pred >> s->cdlms[ch][ilms].scaling); + lms_update(s, ch, ilms, input, residue); + s->channel_residues[ch][icoef] = input; + } + } +} + +static void revert_inter_ch_decorr(WmallDecodeCtx *s, int tile_size) +{ + if (s->num_channels != 2) + return; + else if (s->is_channel_coded[0] && s->is_channel_coded[1]) { + int icoef; + for (icoef = 0; icoef < tile_size; icoef++) { + s->channel_residues[0][icoef] -= s->channel_residues[1][icoef] >> 1; + s->channel_residues[1][icoef] += s->channel_residues[0][icoef]; + } + } +} + +static void revert_acfilter(WmallDecodeCtx *s, int tile_size) +{ + int ich, pred, i, j; + int64_t *filter_coeffs = s->acfilter_coeffs; + int scaling = s->acfilter_scaling; + int order = s->acfilter_order; + + for (ich = 0; ich < s->num_channels; ich++) { + int *prevvalues = s->acfilter_prevvalues[ich]; + for (i = 0; i < order; i++) { + pred = 0; + for (j = 0; j < order; j++) { + if (i <= j) + pred += filter_coeffs[j] * prevvalues[j - i]; + else + pred += s->channel_residues[ich][i - j - 1] * filter_coeffs[j]; + } + pred >>= scaling; + s->channel_residues[ich][i] += pred; + } + for (i = order; i < tile_size; i++) { + pred = 0; + for (j = 0; j < order; j++) + pred += s->channel_residues[ich][i - j - 1] * filter_coeffs[j]; + pred >>= scaling; + s->channel_residues[ich][i] += pred; + } + for (j = 0; j < order; j++) + prevvalues[j] = s->channel_residues[ich][tile_size - j - 1]; + } +} + +static int decode_subframe(WmallDecodeCtx *s) +{ + int offset = s->samples_per_frame; + int subframe_len = s->samples_per_frame; + int total_samples = s->samples_per_frame * s->num_channels; + int i, j, rawpcm_tile, padding_zeroes; + + s->subframe_offset = get_bits_count(&s->gb); + + /* reset channel context and find the next block offset and size + == the next block of the channel with the smallest number of + decoded samples */ + for (i = 0; i < s->num_channels; i++) { + if (offset > s->channel[i].decoded_samples) { + offset = s->channel[i].decoded_samples; + subframe_len = + s->channel[i].subframe_len[s->channel[i].cur_subframe]; + } + } + + /* get a list of all channels that contain the estimated block */ + s->channels_for_cur_subframe = 0; + for (i = 0; i < s->num_channels; i++) { + const int cur_subframe = s->channel[i].cur_subframe; + /* subtract already processed samples */ + total_samples -= s->channel[i].decoded_samples; + + /* and count if there are multiple subframes that match our profile */ + if (offset == s->channel[i].decoded_samples && + subframe_len == s->channel[i].subframe_len[cur_subframe]) { + total_samples -= s->channel[i].subframe_len[cur_subframe]; + s->channel[i].decoded_samples += + s->channel[i].subframe_len[cur_subframe]; + s->channel_indexes_for_cur_subframe[s->channels_for_cur_subframe] = i; + ++s->channels_for_cur_subframe; + } + } + + /* check if the frame will be complete after processing the + estimated block */ + if (!total_samples) + s->parsed_all_subframes = 1; + + + s->seekable_tile = get_bits1(&s->gb); + if (s->seekable_tile) { + clear_codec_buffers(s); + + s->do_arith_coding = get_bits1(&s->gb); + if (s->do_arith_coding) { + av_dlog(s->avctx, AV_LOG_DEBUG, "do_arith_coding == 1"); + abort(); + } + s->do_ac_filter = get_bits1(&s->gb); + s->do_inter_ch_decorr = get_bits1(&s->gb); + s->do_mclms = get_bits1(&s->gb); + + if (s->do_ac_filter) + decode_ac_filter(s); + + if (s->do_mclms) + decode_mclms(s); + + decode_cdlms(s); + s->movave_scaling = get_bits(&s->gb, 3); + s->quant_stepsize = get_bits(&s->gb, 8) + 1; + + reset_codec(s); + } + + rawpcm_tile = get_bits1(&s->gb); + + for (i = 0; i < s->num_channels; i++) + s->is_channel_coded[i] = 1; + + if (!rawpcm_tile) { + for (i = 0; i < s->num_channels; i++) + s->is_channel_coded[i] = get_bits1(&s->gb); + + if (s->bV3RTM) { + // LPC + s->do_lpc = get_bits1(&s->gb); + if (s->do_lpc) { + decode_lpc(s); + av_log_ask_for_sample(s->avctx, "Inverse LPC filter not " + "implemented. Expect wrong output.\n"); + } + } else + s->do_lpc = 0; + } + + + if (get_bits1(&s->gb)) + padding_zeroes = get_bits(&s->gb, 5); + else + padding_zeroes = 0; + + if (rawpcm_tile) { + int bits = s->bits_per_sample - padding_zeroes; + av_dlog(s->avctx, AV_LOG_DEBUG, "RAWPCM %d bits per sample. " + "total %d bits, remain=%d\n", bits, + bits * s->num_channels * subframe_len, get_bits_count(&s->gb)); + for (i = 0; i < s->num_channels; i++) + for (j = 0; j < subframe_len; j++) + s->channel_coeffs[i][j] = get_sbits(&s->gb, bits); + } else { + for (i = 0; i < s->num_channels; i++) + if (s->is_channel_coded[i]) { + decode_channel_residues(s, i, subframe_len); + if (s->seekable_tile) + use_high_update_speed(s, i); + else + use_normal_update_speed(s, i); + revert_cdlms(s, i, 0, subframe_len); + } + } + if (s->do_mclms) + revert_mclms(s, subframe_len); + if (s->do_inter_ch_decorr) + revert_inter_ch_decorr(s, subframe_len); + if (s->do_ac_filter) + revert_acfilter(s, subframe_len); + + /* Dequantize */ + if (s->quant_stepsize != 1) + for (i = 0; i < s->num_channels; i++) + for (j = 0; j < subframe_len; j++) + s->channel_residues[i][j] *= s->quant_stepsize; + + /* Write to proper output buffer depending on bit-depth */ + for (i = 0; i < subframe_len; i++) + for (j = 0; j < s->num_channels; j++) { + if (s->bits_per_sample == 16) + *s->samples_16++ = (int16_t) s->channel_residues[j][i]; + else + *s->samples_32++ = s->channel_residues[j][i]; + } + + /* handled one subframe */ + for (i = 0; i < s->channels_for_cur_subframe; i++) { + int c = s->channel_indexes_for_cur_subframe[i]; + if (s->channel[c].cur_subframe >= s->channel[c].num_subframes) { + av_log(s->avctx, AV_LOG_ERROR, "broken subframe\n"); + return AVERROR_INVALIDDATA; + } + ++s->channel[c].cur_subframe; + } + return 0; +} + +/** + * @brief Decode one WMA frame. + * @param s codec context + * @return 0 if the trailer bit indicates that this is the last frame, + * 1 if there are additional frames + */ +static int decode_frame(WmallDecodeCtx *s) +{ + GetBitContext* gb = &s->gb; + int more_frames = 0, len = 0, i, ret; + + s->frame.nb_samples = s->samples_per_frame; + if ((ret = s->avctx->get_buffer(s->avctx, &s->frame)) < 0) { + /* return an error if no frame could be decoded at all */ + av_log(s->avctx, AV_LOG_ERROR, + "not enough space for the output samples\n"); + s->packet_loss = 1; + return ret; + } + s->samples_16 = (int16_t *)s->frame.data[0]; + s->samples_32 = (int32_t *)s->frame.data[0]; + + /* get frame length */ + if (s->len_prefix) + len = get_bits(gb, s->log2_frame_size); + + /* decode tile information */ + if (decode_tilehdr(s)) { + s->packet_loss = 1; + return 0; + } + + /* read drc info */ + if (s->dynamic_range_compression) + s->drc_gain = get_bits(gb, 8); + + /* no idea what these are for, might be the number of samples + that need to be skipped at the beginning or end of a stream */ + if (get_bits1(gb)) { + int skip; + + /* usually true for the first frame */ + if (get_bits1(gb)) { + skip = get_bits(gb, av_log2(s->samples_per_frame * 2)); + av_dlog(s->avctx, AV_LOG_DEBUG, "start skip: %i\n", skip); + } + + /* sometimes true for the last frame */ + if (get_bits1(gb)) { + skip = get_bits(gb, av_log2(s->samples_per_frame * 2)); + av_dlog(s->avctx, AV_LOG_DEBUG, "end skip: %i\n", skip); + } + + } + + /* reset subframe states */ + s->parsed_all_subframes = 0; + for (i = 0; i < s->num_channels; i++) { + s->channel[i].decoded_samples = 0; + s->channel[i].cur_subframe = 0; + } + + /* decode all subframes */ + while (!s->parsed_all_subframes) { + if (decode_subframe(s) < 0) { + s->packet_loss = 1; + return 0; + } + } + + av_dlog(s->avctx, AV_LOG_DEBUG, "Frame done\n"); + + if (s->skip_frame) + s->skip_frame = 0; + + if (s->len_prefix) { + if (len != (get_bits_count(gb) - s->frame_offset) + 2) { + /* FIXME: not sure if this is always an error */ + av_log(s->avctx, AV_LOG_ERROR, + "frame[%i] would have to skip %i bits\n", s->frame_num, + len - (get_bits_count(gb) - s->frame_offset) - 1); + s->packet_loss = 1; + return 0; + } + + /* skip the rest of the frame data */ + skip_bits_long(gb, len - (get_bits_count(gb) - s->frame_offset) - 1); + } + + /* decode trailer bit */ + more_frames = get_bits1(gb); + ++s->frame_num; + return more_frames; +} + +/** + * @brief Calculate remaining input buffer length. + * @param s codec context + * @param gb bitstream reader context + * @return remaining size in bits + */ +static int remaining_bits(WmallDecodeCtx *s, GetBitContext *gb) +{ + return s->buf_bit_size - get_bits_count(gb); +} + +/** + * @brief Fill the bit reservoir with a (partial) frame. + * @param s codec context + * @param gb bitstream reader context + * @param len length of the partial frame + * @param append decides whether to reset the buffer or not + */ +static void save_bits(WmallDecodeCtx *s, GetBitContext* gb, int len, + int append) +{ + int buflen; + PutBitContext tmp; + + /* when the frame data does not need to be concatenated, the input buffer + is reset and additional bits from the previous frame are copied + and skipped later so that a fast byte copy is possible */ + + if (!append) { + s->frame_offset = get_bits_count(gb) & 7; + s->num_saved_bits = s->frame_offset; + init_put_bits(&s->pb, s->frame_data, MAX_FRAMESIZE); + } + + buflen = (s->num_saved_bits + len + 8) >> 3; + + if (len <= 0 || buflen > MAX_FRAMESIZE) { + av_log_ask_for_sample(s->avctx, "input buffer too small\n"); + s->packet_loss = 1; + return; + } + + s->num_saved_bits += len; + if (!append) { + avpriv_copy_bits(&s->pb, gb->buffer + (get_bits_count(gb) >> 3), + s->num_saved_bits); + } else { + int align = 8 - (get_bits_count(gb) & 7); + align = FFMIN(align, len); + put_bits(&s->pb, align, get_bits(gb, align)); + len -= align; + avpriv_copy_bits(&s->pb, gb->buffer + (get_bits_count(gb) >> 3), len); + } + skip_bits_long(gb, len); + + tmp = s->pb; + flush_put_bits(&tmp); + + init_get_bits(&s->gb, s->frame_data, s->num_saved_bits); + skip_bits(&s->gb, s->frame_offset); +} + +/** + * @brief Decode a single WMA packet. + * @param avctx codec context + * @param data the output buffer + * @param data_size number of bytes that were written to the output buffer + * @param avpkt input packet + * @return number of bytes that were read from the input buffer + */ +static int decode_packet(AVCodecContext *avctx, void *data, int *got_frame_ptr, + AVPacket* avpkt) +{ + WmallDecodeCtx *s = avctx->priv_data; + GetBitContext* gb = &s->pgb; + const uint8_t* buf = avpkt->data; + int buf_size = avpkt->size; + int num_bits_prev_frame, packet_sequence_number, + seekable_frame_in_packet, spliced_packet; + + if (s->packet_done || s->packet_loss) { + s->packet_done = 0; + + /* sanity check for the buffer length */ + if (buf_size < avctx->block_align) + return 0; + + s->next_packet_start = buf_size - avctx->block_align; + buf_size = avctx->block_align; + s->buf_bit_size = buf_size << 3; + + /* parse packet header */ + init_get_bits(gb, buf, s->buf_bit_size); + packet_sequence_number = get_bits(gb, 4); + seekable_frame_in_packet = get_bits1(gb); + spliced_packet = get_bits1(gb); + + /* get number of bits that need to be added to the previous frame */ + num_bits_prev_frame = get_bits(gb, s->log2_frame_size); + + /* check for packet loss */ + if (!s->packet_loss && + ((s->packet_sequence_number + 1) & 0xF) != packet_sequence_number) { + s->packet_loss = 1; + av_log(avctx, AV_LOG_ERROR, "Packet loss detected! seq %x vs %x\n", + s->packet_sequence_number, packet_sequence_number); + } + s->packet_sequence_number = packet_sequence_number; + + if (num_bits_prev_frame > 0) { + int remaining_packet_bits = s->buf_bit_size - get_bits_count(gb); + if (num_bits_prev_frame >= remaining_packet_bits) { + num_bits_prev_frame = remaining_packet_bits; + s->packet_done = 1; + } + + /* Append the previous frame data to the remaining data from the + * previous packet to create a full frame. */ + save_bits(s, gb, num_bits_prev_frame, 1); + + /* decode the cross packet frame if it is valid */ + if (!s->packet_loss) + decode_frame(s); + } else if (s->num_saved_bits - s->frame_offset) { + av_dlog(avctx, AV_LOG_DEBUG, "ignoring %x previously saved bits\n", + s->num_saved_bits - s->frame_offset); + } + + if (s->packet_loss) { + /* Reset number of saved bits so that the decoder does not start + * to decode incomplete frames in the s->len_prefix == 0 case. */ + s->num_saved_bits = 0; + s->packet_loss = 0; + } + + } else { + int frame_size; + + s->buf_bit_size = (avpkt->size - s->next_packet_start) << 3; + init_get_bits(gb, avpkt->data, s->buf_bit_size); + skip_bits(gb, s->packet_offset); + + if (s->len_prefix && remaining_bits(s, gb) > s->log2_frame_size && + (frame_size = show_bits(gb, s->log2_frame_size)) && + frame_size <= remaining_bits(s, gb)) { + save_bits(s, gb, frame_size, 0); + s->packet_done = !decode_frame(s); + } else if (!s->len_prefix + && s->num_saved_bits > get_bits_count(&s->gb)) { + /* when the frames do not have a length prefix, we don't know the + * compressed length of the individual frames however, we know what + * part of a new packet belongs to the previous frame therefore we + * save the incoming packet first, then we append the "previous + * frame" data from the next packet so that we get a buffer that + * only contains full frames */ + s->packet_done = !decode_frame(s); + } else { + s->packet_done = 1; + } + } + + if (s->packet_done && !s->packet_loss && + remaining_bits(s, gb) > 0) { + /* save the rest of the data so that it can be decoded + * with the next packet */ + save_bits(s, gb, remaining_bits(s, gb), 0); + } + + *(AVFrame *)data = s->frame; + *got_frame_ptr = 1; + s->packet_offset = get_bits_count(gb) & 7; + + return (s->packet_loss) ? AVERROR_INVALIDDATA : get_bits_count(gb) >> 3; +} + + +AVCodec ff_wmalossless_decoder = { + .name = "wmalossless", + .type = AVMEDIA_TYPE_AUDIO, + .id = CODEC_ID_WMALOSSLESS, + .priv_data_size = sizeof(WmallDecodeCtx), + .init = decode_init, + .decode = decode_packet, + .capabilities = CODEC_CAP_SUBFRAMES | CODEC_CAP_DR1, + .long_name = NULL_IF_CONFIG_SMALL("Windows Media Audio Lossless"), +}; -- cgit v1.2.3 From 349b7977e408f18cff01ab31dfa66c8249b6584a Mon Sep 17 00:00:00 2001 From: "Ronald S. Bultje" Date: Thu, 1 Mar 2012 16:19:51 -0800 Subject: wma: fix invalid buffer size assumptions causing random overreads. Found-by: Mateusz "j00ru" Jurczyk and Gynvael Coldwind CC: libav-stable@libav.org --- libavcodec/wma.h | 2 +- libavcodec/wmadec.c | 13 ++++++++++--- 2 files changed, 11 insertions(+), 4 deletions(-) (limited to 'libavcodec') diff --git a/libavcodec/wma.h b/libavcodec/wma.h index 4acbf04bbf..d6f4880c14 100644 --- a/libavcodec/wma.h +++ b/libavcodec/wma.h @@ -124,7 +124,7 @@ typedef struct WMACodecContext { /* output buffer for one frame and the last for IMDCT windowing */ DECLARE_ALIGNED(32, float, frame_out)[MAX_CHANNELS][BLOCK_MAX_SIZE * 2]; /* last frame info */ - uint8_t last_superframe[MAX_CODED_SUPERFRAME_SIZE + 4]; /* padding added */ + uint8_t last_superframe[MAX_CODED_SUPERFRAME_SIZE + FF_INPUT_BUFFER_PADDING_SIZE]; /* padding added */ int last_bitoffset; int last_superframe_len; float noise_table[NOISE_TAB_SIZE]; diff --git a/libavcodec/wmadec.c b/libavcodec/wmadec.c index b9fc21fd3e..37feca1f7f 100644 --- a/libavcodec/wmadec.c +++ b/libavcodec/wmadec.c @@ -845,6 +845,12 @@ static int wma_decode_superframe(AVCodecContext *avctx, void *data, if (s->use_bit_reservoir) { bit_offset = get_bits(&s->gb, s->byte_offset_bits + 3); + if (bit_offset > get_bits_left(&s->gb)) { + av_log(avctx, AV_LOG_ERROR, + "Invalid last frame bit offset %d > buf size %d (%d)\n", + bit_offset, get_bits_left(&s->gb), buf_size); + goto fail; + } if (s->last_superframe_len > 0) { // printf("skip=%d\n", s->last_bitoffset); @@ -861,9 +867,10 @@ static int wma_decode_superframe(AVCodecContext *avctx, void *data, if (len > 0) { *q++ = (get_bits)(&s->gb, len) << (8 - len); } + memset(q, 0, FF_INPUT_BUFFER_PADDING_SIZE); /* XXX: bit_offset bits into last frame */ - init_get_bits(&s->gb, s->last_superframe, MAX_CODED_SUPERFRAME_SIZE*8); + init_get_bits(&s->gb, s->last_superframe, s->last_superframe_len * 8 + bit_offset); /* skip unused bits */ if (s->last_bitoffset > 0) skip_bits(&s->gb, s->last_bitoffset); @@ -877,9 +884,9 @@ static int wma_decode_superframe(AVCodecContext *avctx, void *data, /* read each frame starting from bit_offset */ pos = bit_offset + 4 + 4 + s->byte_offset_bits + 3; - if (pos >= MAX_CODED_SUPERFRAME_SIZE * 8) + if (pos >= MAX_CODED_SUPERFRAME_SIZE * 8 || pos > buf_size * 8) return AVERROR_INVALIDDATA; - init_get_bits(&s->gb, buf + (pos >> 3), (MAX_CODED_SUPERFRAME_SIZE - (pos >> 3))*8); + init_get_bits(&s->gb, buf + (pos >> 3), (buf_size - (pos >> 3))*8); len = pos & 7; if (len > 0) skip_bits(&s->gb, len); -- cgit v1.2.3 From bd66f073fe7286bd3c03e608f923577e4768445a Mon Sep 17 00:00:00 2001 From: "Ronald S. Bultje" Date: Thu, 1 Mar 2012 21:17:03 -0800 Subject: vp8: change int stride to ptrdiff_t stride. On 64bit platforms with 32bit int, this means we won't have to sign- extend the integer anymore. --- libavcodec/arm/vp8dsp_init_arm.c | 32 +++---- libavcodec/ppc/vp8dsp_altivec.c | 16 ++-- libavcodec/vp8dsp.c | 44 ++++----- libavcodec/vp8dsp.h | 45 ++++++---- libavcodec/x86/vp8dsp-init.c | 189 ++++++++++++++++++++++----------------- 5 files changed, 178 insertions(+), 148 deletions(-) (limited to 'libavcodec') diff --git a/libavcodec/arm/vp8dsp_init_arm.c b/libavcodec/arm/vp8dsp_init_arm.c index 5eea8464dd..83f36345f5 100644 --- a/libavcodec/arm/vp8dsp_init_arm.c +++ b/libavcodec/arm/vp8dsp_init_arm.c @@ -22,38 +22,38 @@ void ff_vp8_luma_dc_wht_neon(DCTELEM block[4][4][16], DCTELEM dc[16]); void ff_vp8_luma_dc_wht_dc_neon(DCTELEM block[4][4][16], DCTELEM dc[16]); -void ff_vp8_idct_add_neon(uint8_t *dst, DCTELEM block[16], int stride); -void ff_vp8_idct_dc_add_neon(uint8_t *dst, DCTELEM block[16], int stride); -void ff_vp8_idct_dc_add4y_neon(uint8_t *dst, DCTELEM block[4][16], int stride); -void ff_vp8_idct_dc_add4uv_neon(uint8_t *dst, DCTELEM block[4][16], int stride); +void ff_vp8_idct_add_neon(uint8_t *dst, DCTELEM block[16], ptrdiff_t stride); +void ff_vp8_idct_dc_add_neon(uint8_t *dst, DCTELEM block[16], ptrdiff_t stride); +void ff_vp8_idct_dc_add4y_neon(uint8_t *dst, DCTELEM block[4][16], ptrdiff_t stride); +void ff_vp8_idct_dc_add4uv_neon(uint8_t *dst, DCTELEM block[4][16], ptrdiff_t stride); -void ff_vp8_v_loop_filter16_neon(uint8_t *dst, int stride, +void ff_vp8_v_loop_filter16_neon(uint8_t *dst, ptrdiff_t stride, int flim_E, int flim_I, int hev_thresh); -void ff_vp8_h_loop_filter16_neon(uint8_t *dst, int stride, +void ff_vp8_h_loop_filter16_neon(uint8_t *dst, ptrdiff_t stride, int flim_E, int flim_I, int hev_thresh); -void ff_vp8_v_loop_filter8uv_neon(uint8_t *dstU, uint8_t *dstV, int stride, +void ff_vp8_v_loop_filter8uv_neon(uint8_t *dstU, uint8_t *dstV, ptrdiff_t stride, int flim_E, int flim_I, int hev_thresh); -void ff_vp8_h_loop_filter8uv_neon(uint8_t *dstU, uint8_t *dstV, int stride, +void ff_vp8_h_loop_filter8uv_neon(uint8_t *dstU, uint8_t *dstV, ptrdiff_t stride, int flim_E, int flim_I, int hev_thresh); -void ff_vp8_v_loop_filter16_inner_neon(uint8_t *dst, int stride, +void ff_vp8_v_loop_filter16_inner_neon(uint8_t *dst, ptrdiff_t stride, int flim_E, int flim_I, int hev_thresh); -void ff_vp8_h_loop_filter16_inner_neon(uint8_t *dst, int stride, +void ff_vp8_h_loop_filter16_inner_neon(uint8_t *dst, ptrdiff_t stride, int flim_E, int flim_I, int hev_thresh); void ff_vp8_v_loop_filter8uv_inner_neon(uint8_t *dstU, uint8_t *dstV, - int stride, int flim_E, int flim_I, + ptrdiff_t stride, int flim_E, int flim_I, int hev_thresh); void ff_vp8_h_loop_filter8uv_inner_neon(uint8_t *dstU, uint8_t *dstV, - int stride, int flim_E, int flim_I, + ptrdiff_t stride, int flim_E, int flim_I, int hev_thresh); -void ff_vp8_v_loop_filter16_simple_neon(uint8_t *dst, int stride, int flim); -void ff_vp8_h_loop_filter16_simple_neon(uint8_t *dst, int stride, int flim); +void ff_vp8_v_loop_filter16_simple_neon(uint8_t *dst, ptrdiff_t stride, int flim); +void ff_vp8_h_loop_filter16_simple_neon(uint8_t *dst, ptrdiff_t stride, int flim); #define VP8_MC(n) \ - void ff_put_vp8_##n##_neon(uint8_t *dst, int dststride, \ - uint8_t *src, int srcstride, \ + void ff_put_vp8_##n##_neon(uint8_t *dst, ptrdiff_t dststride, \ + uint8_t *src, ptrdiff_t srcstride, \ int h, int x, int y) #define VP8_EPEL(w) \ diff --git a/libavcodec/ppc/vp8dsp_altivec.c b/libavcodec/ppc/vp8dsp_altivec.c index 9c0f663a71..c3f6502ded 100644 --- a/libavcodec/ppc/vp8dsp_altivec.c +++ b/libavcodec/ppc/vp8dsp_altivec.c @@ -75,8 +75,8 @@ static const vec_s8 h_subpel_filters_outer[3] = dstv = vec_sra(dstv, c7) static av_always_inline -void put_vp8_epel_h_altivec_core(uint8_t *dst, int dst_stride, - uint8_t *src, int src_stride, +void put_vp8_epel_h_altivec_core(uint8_t *dst, ptrdiff_t dst_stride, + uint8_t *src, ptrdiff_t src_stride, int h, int mx, int w, int is6tap) { LOAD_H_SUBPEL_FILTER(mx-1); @@ -161,8 +161,8 @@ static const vec_u8 v_subpel_filters[7] = dstv = vec_sra(dstv, c7) static av_always_inline -void put_vp8_epel_v_altivec_core(uint8_t *dst, int dst_stride, - uint8_t *src, int src_stride, +void put_vp8_epel_v_altivec_core(uint8_t *dst, ptrdiff_t dst_stride, + uint8_t *src, ptrdiff_t src_stride, int h, int my, int w, int is6tap) { LOAD_V_SUBPEL_FILTER(my-1); @@ -226,19 +226,19 @@ void put_vp8_epel_v_altivec_core(uint8_t *dst, int dst_stride, #define EPEL_FUNCS(WIDTH, TAPS) \ static av_noinline \ -void put_vp8_epel ## WIDTH ## _h ## TAPS ## _altivec(uint8_t *dst, int dst_stride, uint8_t *src, int src_stride, int h, int mx, int my) \ +void put_vp8_epel ## WIDTH ## _h ## TAPS ## _altivec(uint8_t *dst, ptrdiff_t dst_stride, uint8_t *src, ptrdiff_t src_stride, int h, int mx, int my) \ { \ put_vp8_epel_h_altivec_core(dst, dst_stride, src, src_stride, h, mx, WIDTH, TAPS == 6); \ } \ \ static av_noinline \ -void put_vp8_epel ## WIDTH ## _v ## TAPS ## _altivec(uint8_t *dst, int dst_stride, uint8_t *src, int src_stride, int h, int mx, int my) \ +void put_vp8_epel ## WIDTH ## _v ## TAPS ## _altivec(uint8_t *dst, ptrdiff_t dst_stride, uint8_t *src, ptrdiff_t src_stride, int h, int mx, int my) \ { \ put_vp8_epel_v_altivec_core(dst, dst_stride, src, src_stride, h, my, WIDTH, TAPS == 6); \ } #define EPEL_HV(WIDTH, HTAPS, VTAPS) \ -static void put_vp8_epel ## WIDTH ## _h ## HTAPS ## v ## VTAPS ## _altivec(uint8_t *dst, int stride, uint8_t *src, int s, int h, int mx, int my) \ +static void put_vp8_epel ## WIDTH ## _h ## HTAPS ## v ## VTAPS ## _altivec(uint8_t *dst, ptrdiff_t stride, uint8_t *src, ptrdiff_t s, int h, int mx, int my) \ { \ DECLARE_ALIGNED(16, uint8_t, tmp)[(2*WIDTH+5)*16]; \ if (VTAPS == 6) { \ @@ -266,7 +266,7 @@ EPEL_HV(4, 4,6) EPEL_HV(4, 6,4) EPEL_HV(4, 4,4) -static void put_vp8_pixels16_altivec(uint8_t *dst, int stride, uint8_t *src, int s, int h, int mx, int my) +static void put_vp8_pixels16_altivec(uint8_t *dst, ptrdiff_t stride, uint8_t *src, ptrdiff_t s, int h, int mx, int my) { ff_put_pixels16_altivec(dst, src, stride, h); } diff --git a/libavcodec/vp8dsp.c b/libavcodec/vp8dsp.c index 89c3453efc..86dc42ed37 100644 --- a/libavcodec/vp8dsp.c +++ b/libavcodec/vp8dsp.c @@ -77,7 +77,7 @@ static void vp8_luma_dc_wht_dc_c(DCTELEM block[4][4][16], DCTELEM dc[16]) #define MUL_20091(a) ((((a)*20091) >> 16) + (a)) #define MUL_35468(a) (((a)*35468) >> 16) -static void vp8_idct_add_c(uint8_t *dst, DCTELEM block[16], int stride) +static void vp8_idct_add_c(uint8_t *dst, DCTELEM block[16], ptrdiff_t stride) { int i, t0, t1, t2, t3; uint8_t *cm = ff_cropTbl + MAX_NEG_CROP; @@ -113,7 +113,7 @@ static void vp8_idct_add_c(uint8_t *dst, DCTELEM block[16], int stride) } } -static void vp8_idct_dc_add_c(uint8_t *dst, DCTELEM block[16], int stride) +static void vp8_idct_dc_add_c(uint8_t *dst, DCTELEM block[16], ptrdiff_t stride) { int i, dc = (block[0] + 4) >> 3; uint8_t *cm = ff_cropTbl + MAX_NEG_CROP + dc; @@ -128,7 +128,7 @@ static void vp8_idct_dc_add_c(uint8_t *dst, DCTELEM block[16], int stride) } } -static void vp8_idct_dc_add4uv_c(uint8_t *dst, DCTELEM block[4][16], int stride) +static void vp8_idct_dc_add4uv_c(uint8_t *dst, DCTELEM block[4][16], ptrdiff_t stride) { vp8_idct_dc_add_c(dst+stride*0+0, block[0], stride); vp8_idct_dc_add_c(dst+stride*0+4, block[1], stride); @@ -136,7 +136,7 @@ static void vp8_idct_dc_add4uv_c(uint8_t *dst, DCTELEM block[4][16], int stride) vp8_idct_dc_add_c(dst+stride*4+4, block[3], stride); } -static void vp8_idct_dc_add4y_c(uint8_t *dst, DCTELEM block[4][16], int stride) +static void vp8_idct_dc_add4y_c(uint8_t *dst, DCTELEM block[4][16], ptrdiff_t stride) { vp8_idct_dc_add_c(dst+ 0, block[0], stride); vp8_idct_dc_add_c(dst+ 4, block[1], stride); @@ -157,7 +157,7 @@ static void vp8_idct_dc_add4y_c(uint8_t *dst, DCTELEM block[4][16], int stride) #define clip_int8(n) (cm[n+0x80]-0x80) -static av_always_inline void filter_common(uint8_t *p, int stride, int is4tap) +static av_always_inline void filter_common(uint8_t *p, ptrdiff_t stride, int is4tap) { LOAD_PIXELS int a, f1, f2; @@ -188,7 +188,7 @@ static av_always_inline void filter_common(uint8_t *p, int stride, int is4tap) } } -static av_always_inline int simple_limit(uint8_t *p, int stride, int flim) +static av_always_inline int simple_limit(uint8_t *p, ptrdiff_t stride, int flim) { LOAD_PIXELS return 2*FFABS(p0-q0) + (FFABS(p1-q1) >> 1) <= flim; @@ -198,7 +198,7 @@ static av_always_inline int simple_limit(uint8_t *p, int stride, int flim) * E - limit at the macroblock edge * I - limit for interior difference */ -static av_always_inline int normal_limit(uint8_t *p, int stride, int E, int I) +static av_always_inline int normal_limit(uint8_t *p, ptrdiff_t stride, int E, int I) { LOAD_PIXELS return simple_limit(p, stride, E) @@ -207,13 +207,13 @@ static av_always_inline int normal_limit(uint8_t *p, int stride, int E, int I) } // high edge variance -static av_always_inline int hev(uint8_t *p, int stride, int thresh) +static av_always_inline int hev(uint8_t *p, ptrdiff_t stride, int thresh) { LOAD_PIXELS return FFABS(p1-p0) > thresh || FFABS(q1-q0) > thresh; } -static av_always_inline void filter_mbedge(uint8_t *p, int stride) +static av_always_inline void filter_mbedge(uint8_t *p, ptrdiff_t stride) { int a0, a1, a2, w; uint8_t *cm = ff_cropTbl + MAX_NEG_CROP; @@ -236,7 +236,7 @@ static av_always_inline void filter_mbedge(uint8_t *p, int stride) } #define LOOP_FILTER(dir, size, stridea, strideb, maybe_inline) \ -static maybe_inline void vp8_ ## dir ## _loop_filter ## size ## _c(uint8_t *dst, int stride,\ +static maybe_inline void vp8_ ## dir ## _loop_filter ## size ## _c(uint8_t *dst, ptrdiff_t stride,\ int flim_E, int flim_I, int hev_thresh)\ {\ int i;\ @@ -250,7 +250,7 @@ static maybe_inline void vp8_ ## dir ## _loop_filter ## size ## _c(uint8_t *dst, }\ }\ \ -static maybe_inline void vp8_ ## dir ## _loop_filter ## size ## _inner_c(uint8_t *dst, int stride,\ +static maybe_inline void vp8_ ## dir ## _loop_filter ## size ## _inner_c(uint8_t *dst, ptrdiff_t stride,\ int flim_E, int flim_I, int hev_thresh)\ {\ int i;\ @@ -270,13 +270,13 @@ LOOP_FILTER(h, 16, stride, 1,) #define UV_LOOP_FILTER(dir, stridea, strideb) \ LOOP_FILTER(dir, 8, stridea, strideb, av_always_inline) \ -static void vp8_ ## dir ## _loop_filter8uv_c(uint8_t *dstU, uint8_t *dstV, int stride,\ +static void vp8_ ## dir ## _loop_filter8uv_c(uint8_t *dstU, uint8_t *dstV, ptrdiff_t stride,\ int fE, int fI, int hev_thresh)\ {\ vp8_ ## dir ## _loop_filter8_c(dstU, stride, fE, fI, hev_thresh);\ vp8_ ## dir ## _loop_filter8_c(dstV, stride, fE, fI, hev_thresh);\ }\ -static void vp8_ ## dir ## _loop_filter8uv_inner_c(uint8_t *dstU, uint8_t *dstV, int stride,\ +static void vp8_ ## dir ## _loop_filter8uv_inner_c(uint8_t *dstU, uint8_t *dstV, ptrdiff_t stride,\ int fE, int fI, int hev_thresh)\ {\ vp8_ ## dir ## _loop_filter8_inner_c(dstU, stride, fE, fI, hev_thresh);\ @@ -286,7 +286,7 @@ static void vp8_ ## dir ## _loop_filter8uv_inner_c(uint8_t *dstU, uint8_t *dstV, UV_LOOP_FILTER(v, 1, stride) UV_LOOP_FILTER(h, stride, 1) -static void vp8_v_loop_filter_simple_c(uint8_t *dst, int stride, int flim) +static void vp8_v_loop_filter_simple_c(uint8_t *dst, ptrdiff_t stride, int flim) { int i; @@ -295,7 +295,7 @@ static void vp8_v_loop_filter_simple_c(uint8_t *dst, int stride, int flim) filter_common(dst+i, stride, 1); } -static void vp8_h_loop_filter_simple_c(uint8_t *dst, int stride, int flim) +static void vp8_h_loop_filter_simple_c(uint8_t *dst, ptrdiff_t stride, int flim) { int i; @@ -315,7 +315,7 @@ static const uint8_t subpel_filters[7][6] = { }; #define PUT_PIXELS(WIDTH) \ -static void put_vp8_pixels ## WIDTH ##_c(uint8_t *dst, int dststride, uint8_t *src, int srcstride, int h, int x, int y) { \ +static void put_vp8_pixels ## WIDTH ##_c(uint8_t *dst, ptrdiff_t dststride, uint8_t *src, ptrdiff_t srcstride, int h, int x, int y) { \ int i; \ for (i = 0; i < h; i++, dst+= dststride, src+= srcstride) { \ memcpy(dst, src, WIDTH); \ @@ -335,7 +335,7 @@ PUT_PIXELS(4) F[3]*src[x+1*stride] - F[4]*src[x+2*stride] + 64) >> 7] #define VP8_EPEL_H(SIZE, TAPS) \ -static void put_vp8_epel ## SIZE ## _h ## TAPS ## _c(uint8_t *dst, int dststride, uint8_t *src, int srcstride, int h, int mx, int my) \ +static void put_vp8_epel ## SIZE ## _h ## TAPS ## _c(uint8_t *dst, ptrdiff_t dststride, uint8_t *src, ptrdiff_t srcstride, int h, int mx, int my) \ { \ const uint8_t *filter = subpel_filters[mx-1]; \ uint8_t *cm = ff_cropTbl + MAX_NEG_CROP; \ @@ -349,7 +349,7 @@ static void put_vp8_epel ## SIZE ## _h ## TAPS ## _c(uint8_t *dst, int dststride } \ } #define VP8_EPEL_V(SIZE, TAPS) \ -static void put_vp8_epel ## SIZE ## _v ## TAPS ## _c(uint8_t *dst, int dststride, uint8_t *src, int srcstride, int h, int mx, int my) \ +static void put_vp8_epel ## SIZE ## _v ## TAPS ## _c(uint8_t *dst, ptrdiff_t dststride, uint8_t *src, ptrdiff_t srcstride, int h, int mx, int my) \ { \ const uint8_t *filter = subpel_filters[my-1]; \ uint8_t *cm = ff_cropTbl + MAX_NEG_CROP; \ @@ -363,7 +363,7 @@ static void put_vp8_epel ## SIZE ## _v ## TAPS ## _c(uint8_t *dst, int dststride } \ } #define VP8_EPEL_HV(SIZE, HTAPS, VTAPS) \ -static void put_vp8_epel ## SIZE ## _h ## HTAPS ## v ## VTAPS ## _c(uint8_t *dst, int dststride, uint8_t *src, int srcstride, int h, int mx, int my) \ +static void put_vp8_epel ## SIZE ## _h ## HTAPS ## v ## VTAPS ## _c(uint8_t *dst, ptrdiff_t dststride, uint8_t *src, ptrdiff_t srcstride, int h, int mx, int my) \ { \ const uint8_t *filter = subpel_filters[mx-1]; \ uint8_t *cm = ff_cropTbl + MAX_NEG_CROP; \ @@ -416,7 +416,7 @@ VP8_EPEL_HV(8, 6, 6) VP8_EPEL_HV(4, 6, 6) #define VP8_BILINEAR(SIZE) \ -static void put_vp8_bilinear ## SIZE ## _h_c(uint8_t *dst, int stride, uint8_t *src, int s2, int h, int mx, int my) \ +static void put_vp8_bilinear ## SIZE ## _h_c(uint8_t *dst, ptrdiff_t stride, uint8_t *src, ptrdiff_t s2, int h, int mx, int my) \ { \ int a = 8-mx, b = mx; \ int x, y; \ @@ -428,7 +428,7 @@ static void put_vp8_bilinear ## SIZE ## _h_c(uint8_t *dst, int stride, uint8_t * src += stride; \ } \ } \ -static void put_vp8_bilinear ## SIZE ## _v_c(uint8_t *dst, int stride, uint8_t *src, int s2, int h, int mx, int my) \ +static void put_vp8_bilinear ## SIZE ## _v_c(uint8_t *dst, ptrdiff_t stride, uint8_t *src, ptrdiff_t s2, int h, int mx, int my) \ { \ int c = 8-my, d = my; \ int x, y; \ @@ -441,7 +441,7 @@ static void put_vp8_bilinear ## SIZE ## _v_c(uint8_t *dst, int stride, uint8_t * } \ } \ \ -static void put_vp8_bilinear ## SIZE ## _hv_c(uint8_t *dst, int stride, uint8_t *src, int s2, int h, int mx, int my) \ +static void put_vp8_bilinear ## SIZE ## _hv_c(uint8_t *dst, ptrdiff_t stride, uint8_t *src, ptrdiff_t s2, int h, int mx, int my) \ { \ int a = 8-mx, b = mx; \ int c = 8-my, d = my; \ diff --git a/libavcodec/vp8dsp.h b/libavcodec/vp8dsp.h index 81e19f435b..62cc010989 100644 --- a/libavcodec/vp8dsp.h +++ b/libavcodec/vp8dsp.h @@ -29,40 +29,44 @@ #include "dsputil.h" -typedef void (*vp8_mc_func)(uint8_t *dst/*align 8*/, int dstStride, - uint8_t *src/*align 1*/, int srcStride, +typedef void (*vp8_mc_func)(uint8_t *dst/*align 8*/, ptrdiff_t dstStride, + uint8_t *src/*align 1*/, ptrdiff_t srcStride, int h, int x, int y); typedef struct VP8DSPContext { void (*vp8_luma_dc_wht)(DCTELEM block[4][4][16], DCTELEM dc[16]); void (*vp8_luma_dc_wht_dc)(DCTELEM block[4][4][16], DCTELEM dc[16]); - void (*vp8_idct_add)(uint8_t *dst, DCTELEM block[16], int stride); - void (*vp8_idct_dc_add)(uint8_t *dst, DCTELEM block[16], int stride); - void (*vp8_idct_dc_add4y)(uint8_t *dst, DCTELEM block[4][16], int stride); - void (*vp8_idct_dc_add4uv)(uint8_t *dst, DCTELEM block[4][16], int stride); + void (*vp8_idct_add)(uint8_t *dst, DCTELEM block[16], ptrdiff_t stride); + void (*vp8_idct_dc_add)(uint8_t *dst, DCTELEM block[16], ptrdiff_t stride); + void (*vp8_idct_dc_add4y)(uint8_t *dst, DCTELEM block[4][16], + ptrdiff_t stride); + void (*vp8_idct_dc_add4uv)(uint8_t *dst, DCTELEM block[4][16], + ptrdiff_t stride); // loop filter applied to edges between macroblocks - void (*vp8_v_loop_filter16y)(uint8_t *dst, int stride, + void (*vp8_v_loop_filter16y)(uint8_t *dst, ptrdiff_t stride, int flim_E, int flim_I, int hev_thresh); - void (*vp8_h_loop_filter16y)(uint8_t *dst, int stride, + void (*vp8_h_loop_filter16y)(uint8_t *dst, ptrdiff_t stride, int flim_E, int flim_I, int hev_thresh); - void (*vp8_v_loop_filter8uv)(uint8_t *dstU, uint8_t *dstV, int stride, + void (*vp8_v_loop_filter8uv)(uint8_t *dstU, uint8_t *dstV, ptrdiff_t stride, int flim_E, int flim_I, int hev_thresh); - void (*vp8_h_loop_filter8uv)(uint8_t *dstU, uint8_t *dstV, int stride, + void (*vp8_h_loop_filter8uv)(uint8_t *dstU, uint8_t *dstV, ptrdiff_t stride, int flim_E, int flim_I, int hev_thresh); // loop filter applied to inner macroblock edges - void (*vp8_v_loop_filter16y_inner)(uint8_t *dst, int stride, + void (*vp8_v_loop_filter16y_inner)(uint8_t *dst, ptrdiff_t stride, int flim_E, int flim_I, int hev_thresh); - void (*vp8_h_loop_filter16y_inner)(uint8_t *dst, int stride, + void (*vp8_h_loop_filter16y_inner)(uint8_t *dst, ptrdiff_t stride, int flim_E, int flim_I, int hev_thresh); - void (*vp8_v_loop_filter8uv_inner)(uint8_t *dstU, uint8_t *dstV, int stride, + void (*vp8_v_loop_filter8uv_inner)(uint8_t *dstU, uint8_t *dstV, + ptrdiff_t stride, int flim_E, int flim_I, int hev_thresh); - void (*vp8_h_loop_filter8uv_inner)(uint8_t *dstU, uint8_t *dstV, int stride, + void (*vp8_h_loop_filter8uv_inner)(uint8_t *dstU, uint8_t *dstV, + ptrdiff_t stride, int flim_E, int flim_I, int hev_thresh); - void (*vp8_v_loop_filter_simple)(uint8_t *dst, int stride, int flim); - void (*vp8_h_loop_filter_simple)(uint8_t *dst, int stride, int flim); + void (*vp8_v_loop_filter_simple)(uint8_t *dst, ptrdiff_t stride, int flim); + void (*vp8_h_loop_filter_simple)(uint8_t *dst, ptrdiff_t stride, int flim); /** * first dimension: width>>3, height is assumed equal to width @@ -76,9 +80,12 @@ typedef struct VP8DSPContext { vp8_mc_func put_vp8_bilinear_pixels_tab[3][3][3]; } VP8DSPContext; -void ff_put_vp8_pixels16_c(uint8_t *dst, uint8_t *src, int stride, int h, int x, int y); -void ff_put_vp8_pixels8_c(uint8_t *dst, uint8_t *src, int stride, int h, int x, int y); -void ff_put_vp8_pixels4_c(uint8_t *dst, uint8_t *src, int stride, int h, int x, int y); +void ff_put_vp8_pixels16_c(uint8_t *dst, uint8_t *src, ptrdiff_t stride, + int h, int x, int y); +void ff_put_vp8_pixels8_c(uint8_t *dst, uint8_t *src, ptrdiff_t stride, + int h, int x, int y); +void ff_put_vp8_pixels4_c(uint8_t *dst, uint8_t *src, ptrdiff_t stride, + int h, int x, int y); void ff_vp8dsp_init(VP8DSPContext *c); void ff_vp8dsp_init_x86(VP8DSPContext *c); diff --git a/libavcodec/x86/vp8dsp-init.c b/libavcodec/x86/vp8dsp-init.c index f5e89faa3c..f6589da8c4 100644 --- a/libavcodec/x86/vp8dsp-init.c +++ b/libavcodec/x86/vp8dsp-init.c @@ -29,98 +29,98 @@ /* * MC functions */ -extern void ff_put_vp8_epel4_h4_mmxext(uint8_t *dst, int dststride, - uint8_t *src, int srcstride, +extern void ff_put_vp8_epel4_h4_mmxext(uint8_t *dst, ptrdiff_t dststride, + uint8_t *src, ptrdiff_t srcstride, int height, int mx, int my); -extern void ff_put_vp8_epel4_h6_mmxext(uint8_t *dst, int dststride, - uint8_t *src, int srcstride, +extern void ff_put_vp8_epel4_h6_mmxext(uint8_t *dst, ptrdiff_t dststride, + uint8_t *src, ptrdiff_t srcstride, int height, int mx, int my); -extern void ff_put_vp8_epel4_v4_mmxext(uint8_t *dst, int dststride, - uint8_t *src, int srcstride, +extern void ff_put_vp8_epel4_v4_mmxext(uint8_t *dst, ptrdiff_t dststride, + uint8_t *src, ptrdiff_t srcstride, int height, int mx, int my); -extern void ff_put_vp8_epel4_v6_mmxext(uint8_t *dst, int dststride, - uint8_t *src, int srcstride, +extern void ff_put_vp8_epel4_v6_mmxext(uint8_t *dst, ptrdiff_t dststride, + uint8_t *src, ptrdiff_t srcstride, int height, int mx, int my); -extern void ff_put_vp8_epel8_h4_sse2 (uint8_t *dst, int dststride, - uint8_t *src, int srcstride, +extern void ff_put_vp8_epel8_h4_sse2 (uint8_t *dst, ptrdiff_t dststride, + uint8_t *src, ptrdiff_t srcstride, int height, int mx, int my); -extern void ff_put_vp8_epel8_h6_sse2 (uint8_t *dst, int dststride, - uint8_t *src, int srcstride, +extern void ff_put_vp8_epel8_h6_sse2 (uint8_t *dst, ptrdiff_t dststride, + uint8_t *src, ptrdiff_t srcstride, int height, int mx, int my); -extern void ff_put_vp8_epel8_v4_sse2 (uint8_t *dst, int dststride, - uint8_t *src, int srcstride, +extern void ff_put_vp8_epel8_v4_sse2 (uint8_t *dst, ptrdiff_t dststride, + uint8_t *src, ptrdiff_t srcstride, int height, int mx, int my); -extern void ff_put_vp8_epel8_v6_sse2 (uint8_t *dst, int dststride, - uint8_t *src, int srcstride, +extern void ff_put_vp8_epel8_v6_sse2 (uint8_t *dst, ptrdiff_t dststride, + uint8_t *src, ptrdiff_t srcstride, int height, int mx, int my); -extern void ff_put_vp8_epel4_h4_ssse3 (uint8_t *dst, int dststride, - uint8_t *src, int srcstride, +extern void ff_put_vp8_epel4_h4_ssse3 (uint8_t *dst, ptrdiff_t dststride, + uint8_t *src, ptrdiff_t srcstride, int height, int mx, int my); -extern void ff_put_vp8_epel4_h6_ssse3 (uint8_t *dst, int dststride, - uint8_t *src, int srcstride, +extern void ff_put_vp8_epel4_h6_ssse3 (uint8_t *dst, ptrdiff_t dststride, + uint8_t *src, ptrdiff_t srcstride, int height, int mx, int my); -extern void ff_put_vp8_epel4_v4_ssse3 (uint8_t *dst, int dststride, - uint8_t *src, int srcstride, +extern void ff_put_vp8_epel4_v4_ssse3 (uint8_t *dst, ptrdiff_t dststride, + uint8_t *src, ptrdiff_t srcstride, int height, int mx, int my); -extern void ff_put_vp8_epel4_v6_ssse3 (uint8_t *dst, int dststride, - uint8_t *src, int srcstride, +extern void ff_put_vp8_epel4_v6_ssse3 (uint8_t *dst, ptrdiff_t dststride, + uint8_t *src, ptrdiff_t srcstride, int height, int mx, int my); -extern void ff_put_vp8_epel8_h4_ssse3 (uint8_t *dst, int dststride, - uint8_t *src, int srcstride, +extern void ff_put_vp8_epel8_h4_ssse3 (uint8_t *dst, ptrdiff_t dststride, + uint8_t *src, ptrdiff_t srcstride, int height, int mx, int my); -extern void ff_put_vp8_epel8_h6_ssse3 (uint8_t *dst, int dststride, - uint8_t *src, int srcstride, +extern void ff_put_vp8_epel8_h6_ssse3 (uint8_t *dst, ptrdiff_t dststride, + uint8_t *src, ptrdiff_t srcstride, int height, int mx, int my); -extern void ff_put_vp8_epel8_v4_ssse3 (uint8_t *dst, int dststride, - uint8_t *src, int srcstride, +extern void ff_put_vp8_epel8_v4_ssse3 (uint8_t *dst, ptrdiff_t dststride, + uint8_t *src, ptrdiff_t srcstride, int height, int mx, int my); -extern void ff_put_vp8_epel8_v6_ssse3 (uint8_t *dst, int dststride, - uint8_t *src, int srcstride, +extern void ff_put_vp8_epel8_v6_ssse3 (uint8_t *dst, ptrdiff_t dststride, + uint8_t *src, ptrdiff_t srcstride, int height, int mx, int my); -extern void ff_put_vp8_bilinear4_h_mmxext(uint8_t *dst, int dststride, - uint8_t *src, int srcstride, +extern void ff_put_vp8_bilinear4_h_mmxext(uint8_t *dst, ptrdiff_t dststride, + uint8_t *src, ptrdiff_t srcstride, int height, int mx, int my); -extern void ff_put_vp8_bilinear8_h_sse2 (uint8_t *dst, int dststride, - uint8_t *src, int srcstride, +extern void ff_put_vp8_bilinear8_h_sse2 (uint8_t *dst, ptrdiff_t dststride, + uint8_t *src, ptrdiff_t srcstride, int height, int mx, int my); -extern void ff_put_vp8_bilinear4_h_ssse3 (uint8_t *dst, int dststride, - uint8_t *src, int srcstride, +extern void ff_put_vp8_bilinear4_h_ssse3 (uint8_t *dst, ptrdiff_t dststride, + uint8_t *src, ptrdiff_t srcstride, int height, int mx, int my); -extern void ff_put_vp8_bilinear8_h_ssse3 (uint8_t *dst, int dststride, - uint8_t *src, int srcstride, +extern void ff_put_vp8_bilinear8_h_ssse3 (uint8_t *dst, ptrdiff_t dststride, + uint8_t *src, ptrdiff_t srcstride, int height, int mx, int my); -extern void ff_put_vp8_bilinear4_v_mmxext(uint8_t *dst, int dststride, - uint8_t *src, int srcstride, +extern void ff_put_vp8_bilinear4_v_mmxext(uint8_t *dst, ptrdiff_t dststride, + uint8_t *src, ptrdiff_t srcstride, int height, int mx, int my); -extern void ff_put_vp8_bilinear8_v_sse2 (uint8_t *dst, int dststride, - uint8_t *src, int srcstride, +extern void ff_put_vp8_bilinear8_v_sse2 (uint8_t *dst, ptrdiff_t dststride, + uint8_t *src, ptrdiff_t srcstride, int height, int mx, int my); -extern void ff_put_vp8_bilinear4_v_ssse3 (uint8_t *dst, int dststride, - uint8_t *src, int srcstride, +extern void ff_put_vp8_bilinear4_v_ssse3 (uint8_t *dst, ptrdiff_t dststride, + uint8_t *src, ptrdiff_t srcstride, int height, int mx, int my); -extern void ff_put_vp8_bilinear8_v_ssse3 (uint8_t *dst, int dststride, - uint8_t *src, int srcstride, +extern void ff_put_vp8_bilinear8_v_ssse3 (uint8_t *dst, ptrdiff_t dststride, + uint8_t *src, ptrdiff_t srcstride, int height, int mx, int my); -extern void ff_put_vp8_pixels8_mmx (uint8_t *dst, int dststride, - uint8_t *src, int srcstride, +extern void ff_put_vp8_pixels8_mmx (uint8_t *dst, ptrdiff_t dststride, + uint8_t *src, ptrdiff_t srcstride, int height, int mx, int my); -extern void ff_put_vp8_pixels16_mmx(uint8_t *dst, int dststride, - uint8_t *src, int srcstride, +extern void ff_put_vp8_pixels16_mmx(uint8_t *dst, ptrdiff_t dststride, + uint8_t *src, ptrdiff_t srcstride, int height, int mx, int my); -extern void ff_put_vp8_pixels16_sse(uint8_t *dst, int dststride, - uint8_t *src, int srcstride, +extern void ff_put_vp8_pixels16_sse(uint8_t *dst, ptrdiff_t dststride, + uint8_t *src, ptrdiff_t srcstride, int height, int mx, int my); #define TAP_W16(OPT, FILTERTYPE, TAPTYPE) \ static void ff_put_vp8_ ## FILTERTYPE ## 16_ ## TAPTYPE ## _ ## OPT( \ - uint8_t *dst, int dststride, uint8_t *src, \ - int srcstride, int height, int mx, int my) \ + uint8_t *dst, ptrdiff_t dststride, uint8_t *src, \ + ptrdiff_t srcstride, int height, int mx, int my) \ { \ ff_put_vp8_ ## FILTERTYPE ## 8_ ## TAPTYPE ## _ ## OPT( \ dst, dststride, src, srcstride, height, mx, my); \ @@ -129,8 +129,8 @@ static void ff_put_vp8_ ## FILTERTYPE ## 16_ ## TAPTYPE ## _ ## OPT( \ } #define TAP_W8(OPT, FILTERTYPE, TAPTYPE) \ static void ff_put_vp8_ ## FILTERTYPE ## 8_ ## TAPTYPE ## _ ## OPT( \ - uint8_t *dst, int dststride, uint8_t *src, \ - int srcstride, int height, int mx, int my) \ + uint8_t *dst, ptrdiff_t dststride, uint8_t *src, \ + ptrdiff_t srcstride, int height, int mx, int my) \ { \ ff_put_vp8_ ## FILTERTYPE ## 4_ ## TAPTYPE ## _ ## OPT( \ dst, dststride, src, srcstride, height, mx, my); \ @@ -161,8 +161,8 @@ TAP_W16(ssse3, bilinear, v) #define HVTAP(OPT, ALIGN, TAPNUMX, TAPNUMY, SIZE, MAXHEIGHT) \ static void ff_put_vp8_epel ## SIZE ## _h ## TAPNUMX ## v ## TAPNUMY ## _ ## OPT( \ - uint8_t *dst, int dststride, uint8_t *src, \ - int srcstride, int height, int mx, int my) \ + uint8_t *dst, ptrdiff_t dststride, uint8_t *src, \ + ptrdiff_t srcstride, int height, int mx, int my) \ { \ DECLARE_ALIGNED(ALIGN, uint8_t, tmp)[SIZE * (MAXHEIGHT + TAPNUMY - 1)]; \ uint8_t *tmpptr = tmp + SIZE * (TAPNUMY / 2 - 1); \ @@ -200,8 +200,8 @@ HVTAP(ssse3, 16, 6, 6, 4, 8) #define HVBILIN(OPT, ALIGN, SIZE, MAXHEIGHT) \ static void ff_put_vp8_bilinear ## SIZE ## _hv_ ## OPT( \ - uint8_t *dst, int dststride, uint8_t *src, \ - int srcstride, int height, int mx, int my) \ + uint8_t *dst, ptrdiff_t dststride, uint8_t *src, \ + ptrdiff_t srcstride, int height, int mx, int my) \ { \ DECLARE_ALIGNED(ALIGN, uint8_t, tmp)[SIZE * (MAXHEIGHT + 2)]; \ ff_put_vp8_bilinear ## SIZE ## _h_ ## OPT( \ @@ -219,35 +219,58 @@ HVBILIN(ssse3, 8, 4, 8) HVBILIN(ssse3, 8, 8, 16) HVBILIN(ssse3, 8, 16, 16) -extern void ff_vp8_idct_dc_add_mmx(uint8_t *dst, DCTELEM block[16], int stride); -extern void ff_vp8_idct_dc_add_sse4(uint8_t *dst, DCTELEM block[16], int stride); -extern void ff_vp8_idct_dc_add4y_mmx(uint8_t *dst, DCTELEM block[4][16], int stride); -extern void ff_vp8_idct_dc_add4y_sse2(uint8_t *dst, DCTELEM block[4][16], int stride); -extern void ff_vp8_idct_dc_add4uv_mmx(uint8_t *dst, DCTELEM block[2][16], int stride); +extern void ff_vp8_idct_dc_add_mmx(uint8_t *dst, DCTELEM block[16], + ptrdiff_t stride); +extern void ff_vp8_idct_dc_add_sse4(uint8_t *dst, DCTELEM block[16], + ptrdiff_t stride); +extern void ff_vp8_idct_dc_add4y_mmx(uint8_t *dst, DCTELEM block[4][16], + ptrdiff_t stride); +extern void ff_vp8_idct_dc_add4y_sse2(uint8_t *dst, DCTELEM block[4][16], + ptrdiff_t stride); +extern void ff_vp8_idct_dc_add4uv_mmx(uint8_t *dst, DCTELEM block[2][16], + ptrdiff_t stride); extern void ff_vp8_luma_dc_wht_mmx(DCTELEM block[4][4][16], DCTELEM dc[16]); extern void ff_vp8_luma_dc_wht_sse(DCTELEM block[4][4][16], DCTELEM dc[16]); -extern void ff_vp8_idct_add_mmx(uint8_t *dst, DCTELEM block[16], int stride); -extern void ff_vp8_idct_add_sse(uint8_t *dst, DCTELEM block[16], int stride); +extern void ff_vp8_idct_add_mmx(uint8_t *dst, DCTELEM block[16], + ptrdiff_t stride); +extern void ff_vp8_idct_add_sse(uint8_t *dst, DCTELEM block[16], + ptrdiff_t stride); #define DECLARE_LOOP_FILTER(NAME)\ -extern void ff_vp8_v_loop_filter_simple_ ## NAME(uint8_t *dst, int stride, int flim);\ -extern void ff_vp8_h_loop_filter_simple_ ## NAME(uint8_t *dst, int stride, int flim);\ -extern void ff_vp8_v_loop_filter16y_inner_ ## NAME (uint8_t *dst, int stride,\ +extern void ff_vp8_v_loop_filter_simple_ ## NAME(uint8_t *dst, \ + ptrdiff_t stride, \ + int flim);\ +extern void ff_vp8_h_loop_filter_simple_ ## NAME(uint8_t *dst, \ + ptrdiff_t stride, \ + int flim);\ +extern void ff_vp8_v_loop_filter16y_inner_ ## NAME (uint8_t *dst, \ + ptrdiff_t stride,\ int e, int i, int hvt);\ -extern void ff_vp8_h_loop_filter16y_inner_ ## NAME (uint8_t *dst, int stride,\ +extern void ff_vp8_h_loop_filter16y_inner_ ## NAME (uint8_t *dst, \ + ptrdiff_t stride,\ int e, int i, int hvt);\ -extern void ff_vp8_v_loop_filter8uv_inner_ ## NAME (uint8_t *dstU, uint8_t *dstV,\ - int s, int e, int i, int hvt);\ -extern void ff_vp8_h_loop_filter8uv_inner_ ## NAME (uint8_t *dstU, uint8_t *dstV,\ - int s, int e, int i, int hvt);\ -extern void ff_vp8_v_loop_filter16y_mbedge_ ## NAME(uint8_t *dst, int stride,\ +extern void ff_vp8_v_loop_filter8uv_inner_ ## NAME (uint8_t *dstU, \ + uint8_t *dstV,\ + ptrdiff_t s, \ int e, int i, int hvt);\ -extern void ff_vp8_h_loop_filter16y_mbedge_ ## NAME(uint8_t *dst, int stride,\ +extern void ff_vp8_h_loop_filter8uv_inner_ ## NAME (uint8_t *dstU, \ + uint8_t *dstV,\ + ptrdiff_t s, \ int e, int i, int hvt);\ -extern void ff_vp8_v_loop_filter8uv_mbedge_ ## NAME(uint8_t *dstU, uint8_t *dstV,\ - int s, int e, int i, int hvt);\ -extern void ff_vp8_h_loop_filter8uv_mbedge_ ## NAME(uint8_t *dstU, uint8_t *dstV,\ - int s, int e, int i, int hvt); +extern void ff_vp8_v_loop_filter16y_mbedge_ ## NAME(uint8_t *dst, \ + ptrdiff_t stride,\ + int e, int i, int hvt);\ +extern void ff_vp8_h_loop_filter16y_mbedge_ ## NAME(uint8_t *dst, \ + ptrdiff_t stride,\ + int e, int i, int hvt);\ +extern void ff_vp8_v_loop_filter8uv_mbedge_ ## NAME(uint8_t *dstU, \ + uint8_t *dstV,\ + ptrdiff_t s, \ + int e, int i, int hvt);\ +extern void ff_vp8_h_loop_filter8uv_mbedge_ ## NAME(uint8_t *dstU, \ + uint8_t *dstV,\ + ptrdiff_t s, \ + int e, int i, int hvt); DECLARE_LOOP_FILTER(mmx) DECLARE_LOOP_FILTER(mmxext) -- cgit v1.2.3 From 45549339bc072734015eaf6c907e5a5e68a1ccee Mon Sep 17 00:00:00 2001 From: "Ronald S. Bultje" Date: Thu, 1 Mar 2012 20:39:49 -0800 Subject: vp8: disable mmx functions with sse/sse2 counterparts on x86-64. x86-64 is guaranteed to have at least SSE2, therefore the MMX/MMX2 functions will never be used in practice. --- libavcodec/x86/vp8dsp-init.c | 24 ++++++++++++++++++++---- libavcodec/x86/vp8dsp.asm | 15 +++++++++++++++ 2 files changed, 35 insertions(+), 4 deletions(-) (limited to 'libavcodec') diff --git a/libavcodec/x86/vp8dsp-init.c b/libavcodec/x86/vp8dsp-init.c index f6589da8c4..3e05bb2fb9 100644 --- a/libavcodec/x86/vp8dsp-init.c +++ b/libavcodec/x86/vp8dsp-init.c @@ -138,6 +138,7 @@ static void ff_put_vp8_ ## FILTERTYPE ## 8_ ## TAPTYPE ## _ ## OPT( \ dst + 4, dststride, src + 4, srcstride, height, mx, my); \ } +#if ARCH_X86_32 TAP_W8 (mmxext, epel, h4) TAP_W8 (mmxext, epel, h6) TAP_W16(mmxext, epel, h6) @@ -148,6 +149,7 @@ TAP_W8 (mmxext, bilinear, h) TAP_W16(mmxext, bilinear, h) TAP_W8 (mmxext, bilinear, v) TAP_W16(mmxext, bilinear, v) +#endif TAP_W16(sse2, epel, h6) TAP_W16(sse2, epel, v6) @@ -173,15 +175,21 @@ static void ff_put_vp8_epel ## SIZE ## _h ## TAPNUMX ## v ## TAPNUMY ## _ ## OPT dst, dststride, tmpptr, SIZE, height, mx, my); \ } +#if ARCH_X86_32 #define HVTAPMMX(x, y) \ HVTAP(mmxext, 8, x, y, 4, 8) \ HVTAP(mmxext, 8, x, y, 8, 16) +HVTAP(mmxext, 8, 6, 6, 16, 16) +#else +#define HVTAPMMX(x, y) \ +HVTAP(mmxext, 8, x, y, 4, 8) +#endif + HVTAPMMX(4, 4) HVTAPMMX(4, 6) HVTAPMMX(6, 4) HVTAPMMX(6, 6) -HVTAP(mmxext, 8, 6, 6, 16, 16) #define HVTAPSSE2(x, y, w) \ HVTAP(sse2, 16, x, y, w, 16) \ @@ -211,8 +219,10 @@ static void ff_put_vp8_bilinear ## SIZE ## _hv_ ## OPT( \ } HVBILIN(mmxext, 8, 4, 8) +#if ARCH_X86_32 HVBILIN(mmxext, 8, 8, 16) HVBILIN(mmxext, 8, 16, 16) +#endif HVBILIN(sse2, 8, 8, 16) HVBILIN(sse2, 8, 16, 16) HVBILIN(ssse3, 8, 4, 8) @@ -311,15 +321,18 @@ av_cold void ff_vp8dsp_init_x86(VP8DSPContext* c) if (mm_flags & AV_CPU_FLAG_MMX) { c->vp8_idct_dc_add = ff_vp8_idct_dc_add_mmx; - c->vp8_idct_dc_add4y = ff_vp8_idct_dc_add4y_mmx; c->vp8_idct_dc_add4uv = ff_vp8_idct_dc_add4uv_mmx; +#if ARCH_X86_32 + c->vp8_idct_dc_add4y = ff_vp8_idct_dc_add4y_mmx; c->vp8_idct_add = ff_vp8_idct_add_mmx; c->vp8_luma_dc_wht = ff_vp8_luma_dc_wht_mmx; c->put_vp8_epel_pixels_tab[0][0][0] = c->put_vp8_bilinear_pixels_tab[0][0][0] = ff_put_vp8_pixels16_mmx; +#endif c->put_vp8_epel_pixels_tab[1][0][0] = c->put_vp8_bilinear_pixels_tab[1][0][0] = ff_put_vp8_pixels8_mmx; +#if ARCH_X86_32 c->vp8_v_loop_filter_simple = ff_vp8_v_loop_filter_simple_mmx; c->vp8_h_loop_filter_simple = ff_vp8_h_loop_filter_simple_mmx; @@ -332,17 +345,19 @@ av_cold void ff_vp8dsp_init_x86(VP8DSPContext* c) c->vp8_h_loop_filter16y = ff_vp8_h_loop_filter16y_mbedge_mmx; c->vp8_v_loop_filter8uv = ff_vp8_v_loop_filter8uv_mbedge_mmx; c->vp8_h_loop_filter8uv = ff_vp8_h_loop_filter8uv_mbedge_mmx; +#endif } /* note that 4-tap width=16 functions are missing because w=16 * is only used for luma, and luma is always a copy or sixtap. */ if (mm_flags & AV_CPU_FLAG_MMX2) { + VP8_MC_FUNC(2, 4, mmxext); + VP8_BILINEAR_MC_FUNC(2, 4, mmxext); +#if ARCH_X86_32 VP8_LUMA_MC_FUNC(0, 16, mmxext); VP8_MC_FUNC(1, 8, mmxext); - VP8_MC_FUNC(2, 4, mmxext); VP8_BILINEAR_MC_FUNC(0, 16, mmxext); VP8_BILINEAR_MC_FUNC(1, 8, mmxext); - VP8_BILINEAR_MC_FUNC(2, 4, mmxext); c->vp8_v_loop_filter_simple = ff_vp8_v_loop_filter_simple_mmxext; c->vp8_h_loop_filter_simple = ff_vp8_h_loop_filter_simple_mmxext; @@ -356,6 +371,7 @@ av_cold void ff_vp8dsp_init_x86(VP8DSPContext* c) c->vp8_h_loop_filter16y = ff_vp8_h_loop_filter16y_mbedge_mmxext; c->vp8_v_loop_filter8uv = ff_vp8_v_loop_filter8uv_mbedge_mmxext; c->vp8_h_loop_filter8uv = ff_vp8_h_loop_filter8uv_mbedge_mmxext; +#endif } if (mm_flags & AV_CPU_FLAG_SSE) { diff --git a/libavcodec/x86/vp8dsp.asm b/libavcodec/x86/vp8dsp.asm index 7d9ebc9463..a7b83797ea 100644 --- a/libavcodec/x86/vp8dsp.asm +++ b/libavcodec/x86/vp8dsp.asm @@ -865,6 +865,7 @@ cglobal put_vp8_pixels8_mmx, 5,5 jg .nextrow REP_RET +%if ARCH_X86_32 cglobal put_vp8_pixels16_mmx, 5,5 .nextrow: movq mm0, [r2+r3*0+0] @@ -880,6 +881,7 @@ cglobal put_vp8_pixels16_mmx, 5,5 sub r4d, 2 jg .nextrow REP_RET +%endif cglobal put_vp8_pixels16_sse, 5,5,2 .nextrow: @@ -973,6 +975,7 @@ cglobal vp8_idct_dc_add_sse4, 3, 3, 6 ; void vp8_idct_dc_add4y_(uint8_t *dst, DCTELEM block[4][16], int stride); ;----------------------------------------------------------------------------- +%if ARCH_X86_32 INIT_MMX cglobal vp8_idct_dc_add4y_mmx, 3, 3 ; load data @@ -1007,6 +1010,7 @@ cglobal vp8_idct_dc_add4y_mmx, 3, 3 ADD_DC m0, m6, 0, mova ADD_DC m1, m7, 8, mova RET +%endif INIT_XMM cglobal vp8_idct_dc_add4y_sse2, 3, 3, 6 @@ -1152,7 +1156,9 @@ cglobal vp8_idct_add_%1, 3, 3 RET %endmacro +%if ARCH_X86_32 VP8_IDCT_ADD mmx +%endif VP8_IDCT_ADD sse ;----------------------------------------------------------------------------- @@ -1217,7 +1223,9 @@ cglobal vp8_luma_dc_wht_%1, 2,3 %endmacro INIT_MMX +%if ARCH_X86_32 VP8_DC_WHT mmx +%endif VP8_DC_WHT sse ;----------------------------------------------------------------------------- @@ -1610,6 +1618,7 @@ cglobal vp8_%2_loop_filter_simple_%1, 3, %3, %4 %endif %endmacro +%if ARCH_X86_32 INIT_MMX %define SPLATB_REG SPLATB_REG_MMX SIMPLE_LOOPFILTER mmx, v, 4, 0 @@ -1617,6 +1626,8 @@ SIMPLE_LOOPFILTER mmx, h, 5, 0 %define SPLATB_REG SPLATB_REG_MMXEXT SIMPLE_LOOPFILTER mmxext, v, 4, 0 SIMPLE_LOOPFILTER mmxext, h, 5, 0 +%endif + INIT_XMM %define SPLATB_REG SPLATB_REG_SSE2 %define WRITE_8W WRITE_8W_SSE2 @@ -2118,6 +2129,7 @@ cglobal vp8_%2_loop_filter16y_inner_%1, 5, %3, %5 RET %endmacro +%if ARCH_X86_32 INIT_MMX %define SPLATB_REG SPLATB_REG_MMX INNER_LOOPFILTER mmx, v, 6, 16, 0 @@ -2130,6 +2142,7 @@ INNER_LOOPFILTER mmxext, v, 6, 16, 0 INNER_LOOPFILTER mmxext, h, 6, 16, 0 INNER_LOOPFILTER mmxext, v, 6, 8, 0 INNER_LOOPFILTER mmxext, h, 6, 8, 0 +%endif INIT_XMM %define SPLATB_REG SPLATB_REG_SSE2 @@ -2814,6 +2827,7 @@ cglobal vp8_%2_loop_filter16y_mbedge_%1, 5, %3, %5 RET %endmacro +%if ARCH_X86_32 INIT_MMX %define SPLATB_REG SPLATB_REG_MMX MBEDGE_LOOPFILTER mmx, v, 6, 16, 0 @@ -2826,6 +2840,7 @@ MBEDGE_LOOPFILTER mmxext, v, 6, 16, 0 MBEDGE_LOOPFILTER mmxext, h, 6, 16, 0 MBEDGE_LOOPFILTER mmxext, v, 6, 8, 0 MBEDGE_LOOPFILTER mmxext, h, 6, 8, 0 +%endif INIT_XMM %define SPLATB_REG SPLATB_REG_SSE2 -- cgit v1.2.3 From 291c9b62855d555ac5385e23219461b6080da7db Mon Sep 17 00:00:00 2001 From: "Ronald S. Bultje" Date: Sat, 25 Feb 2012 17:24:56 -0800 Subject: h264: change underread for 10bit QPEL to overread. This prevents us from reading before the start of the buffer, and thus prevents crashes resulting from this behaviour. Fixes bug 237. --- libavcodec/x86/h264_qpel_10bit.asm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'libavcodec') diff --git a/libavcodec/x86/h264_qpel_10bit.asm b/libavcodec/x86/h264_qpel_10bit.asm index 51412e3977..bdacf9f472 100644 --- a/libavcodec/x86/h264_qpel_10bit.asm +++ b/libavcodec/x86/h264_qpel_10bit.asm @@ -619,7 +619,7 @@ MC MC33 %define PAD 12 %define COUNT 2 %else -%define PAD 0 +%define PAD 4 %define COUNT 3 %endif put_hv%2_10_%1: -- cgit v1.2.3 From 154b8bb80029e71d562e8936164266300dd35a0e Mon Sep 17 00:00:00 2001 From: "Ronald S. Bultje" Date: Thu, 1 Mar 2012 13:51:21 -0800 Subject: amrwb: error out early if mode is invalid. Prevents using the invalid mode as an index in a static array, which would generate invalid reads. Found-by: Mateusz "j00ru" Jurczyk and Gynvael Coldwind CC: libav-stable@libav.org --- libavcodec/amrwbdec.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) (limited to 'libavcodec') diff --git a/libavcodec/amrwbdec.c b/libavcodec/amrwbdec.c index 6ea5d228dd..0ebaf47441 100644 --- a/libavcodec/amrwbdec.c +++ b/libavcodec/amrwbdec.c @@ -1095,23 +1095,27 @@ static int amrwb_decode_frame(AVCodecContext *avctx, void *data, buf_out = (float *)ctx->avframe.data[0]; header_size = decode_mime_header(ctx, buf); + if (ctx->fr_cur_mode > MODE_SID) { + av_log(avctx, AV_LOG_ERROR, + "Invalid mode %d\n", ctx->fr_cur_mode); + return AVERROR_INVALIDDATA; + } expected_fr_size = ((cf_sizes_wb[ctx->fr_cur_mode] + 7) >> 3) + 1; if (buf_size < expected_fr_size) { av_log(avctx, AV_LOG_ERROR, "Frame too small (%d bytes). Truncated file?\n", buf_size); *got_frame_ptr = 0; - return buf_size; + return AVERROR_INVALIDDATA; } if (!ctx->fr_quality || ctx->fr_cur_mode > MODE_SID) av_log(avctx, AV_LOG_ERROR, "Encountered a bad or corrupted frame\n"); - if (ctx->fr_cur_mode == MODE_SID) /* Comfort noise frame */ + if (ctx->fr_cur_mode == MODE_SID) { /* Comfort noise frame */ av_log_missing_feature(avctx, "SID mode", 1); - - if (ctx->fr_cur_mode >= MODE_SID) return -1; + } ff_amr_bit_reorder((uint16_t *) &ctx->frame, sizeof(AMRWBFrame), buf + header_size, amr_bit_orderings_by_mode[ctx->fr_cur_mode]); -- cgit v1.2.3 From 9d87374ec0f382c8394ad511243db6980afa42af Mon Sep 17 00:00:00 2001 From: "Ronald S. Bultje" Date: Thu, 1 Mar 2012 15:44:25 -0800 Subject: amrwb: remove duplicate arguments from extrapolate_isf(). Prevents warnings because the dst and src overlap (are the same) in the memcpy() inside the function. Found-by: Mateusz "j00ru" Jurczyk and Gynvael Coldwind CC: libav-stable@libav.org --- libavcodec/amrwbdec.c | 25 ++++++++++++------------- 1 file changed, 12 insertions(+), 13 deletions(-) (limited to 'libavcodec') diff --git a/libavcodec/amrwbdec.c b/libavcodec/amrwbdec.c index 0ebaf47441..b9ae9ece66 100644 --- a/libavcodec/amrwbdec.c +++ b/libavcodec/amrwbdec.c @@ -898,10 +898,10 @@ static float auto_correlation(float *diff_isf, float mean, int lag) * Extrapolate a ISF vector to the 16kHz range (20th order LP) * used at mode 6k60 LP filter for the high frequency band. * - * @param[out] out Buffer for extrapolated isf - * @param[in] isf Input isf vector + * @param[out] isf Buffer for extrapolated isf; contains LP_ORDER + * values on input */ -static void extrapolate_isf(float out[LP_ORDER_16k], float isf[LP_ORDER]) +static void extrapolate_isf(float isf[LP_ORDER_16k]) { float diff_isf[LP_ORDER - 2], diff_mean; float *diff_hi = diff_isf - LP_ORDER + 1; // diff array for extrapolated indexes @@ -909,8 +909,7 @@ static void extrapolate_isf(float out[LP_ORDER_16k], float isf[LP_ORDER]) float est, scale; int i, i_max_corr; - memcpy(out, isf, (LP_ORDER - 1) * sizeof(float)); - out[LP_ORDER_16k - 1] = isf[LP_ORDER - 1]; + isf[LP_ORDER_16k - 1] = isf[LP_ORDER - 1]; /* Calculate the difference vector */ for (i = 0; i < LP_ORDER - 2; i++) @@ -931,16 +930,16 @@ static void extrapolate_isf(float out[LP_ORDER_16k], float isf[LP_ORDER]) i_max_corr++; for (i = LP_ORDER - 1; i < LP_ORDER_16k - 1; i++) - out[i] = isf[i - 1] + isf[i - 1 - i_max_corr] + isf[i] = isf[i - 1] + isf[i - 1 - i_max_corr] - isf[i - 2 - i_max_corr]; /* Calculate an estimate for ISF(18) and scale ISF based on the error */ - est = 7965 + (out[2] - out[3] - out[4]) / 6.0; - scale = 0.5 * (FFMIN(est, 7600) - out[LP_ORDER - 2]) / - (out[LP_ORDER_16k - 2] - out[LP_ORDER - 2]); + est = 7965 + (isf[2] - isf[3] - isf[4]) / 6.0; + scale = 0.5 * (FFMIN(est, 7600) - isf[LP_ORDER - 2]) / + (isf[LP_ORDER_16k - 2] - isf[LP_ORDER - 2]); for (i = LP_ORDER - 1; i < LP_ORDER_16k - 1; i++) - diff_hi[i] = scale * (out[i] - out[i - 1]); + diff_hi[i] = scale * (isf[i] - isf[i - 1]); /* Stability insurance */ for (i = LP_ORDER; i < LP_ORDER_16k - 1; i++) @@ -952,11 +951,11 @@ static void extrapolate_isf(float out[LP_ORDER_16k], float isf[LP_ORDER]) } for (i = LP_ORDER - 1; i < LP_ORDER_16k - 1; i++) - out[i] = out[i - 1] + diff_hi[i] * (1.0f / (1 << 15)); + isf[i] = isf[i - 1] + diff_hi[i] * (1.0f / (1 << 15)); /* Scale the ISF vector for 16000 Hz */ for (i = 0; i < LP_ORDER_16k - 1; i++) - out[i] *= 0.8; + isf[i] *= 0.8; } /** @@ -1003,7 +1002,7 @@ static void hb_synthesis(AMRWBContext *ctx, int subframe, float *samples, ff_weighted_vector_sumf(e_isf, isf_past, isf, isfp_inter[subframe], 1.0 - isfp_inter[subframe], LP_ORDER); - extrapolate_isf(e_isf, e_isf); + extrapolate_isf(e_isf); e_isf[LP_ORDER_16k - 1] *= 2.0; ff_acelp_lsf2lspd(e_isp, e_isf, LP_ORDER_16k); -- cgit v1.2.3