From 4be1e1dfa7233380171da98586c42505a26655d1 Mon Sep 17 00:00:00 2001 From: Justin Ruggles Date: Tue, 27 Sep 2011 10:39:54 -0400 Subject: [PATCH 01/53] mpegaudiodec: Skip only bad frames instead of the whole packet. On frame decoding failure, return an error if the frame is the same size as the whole packet, otherwise just log an error message and return the number of bytes consumed. --- libavcodec/mpegaudiodec.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/libavcodec/mpegaudiodec.c b/libavcodec/mpegaudiodec.c index e3d19c0946..004048ce93 100644 --- a/libavcodec/mpegaudiodec.c +++ b/libavcodec/mpegaudiodec.c @@ -1819,8 +1819,15 @@ static int decode_frame(AVCodecContext * avctx, *data_size = out_size; avctx->sample_rate = s->sample_rate; //FIXME maybe move the other codec info stuff from above here too - }else - av_log(avctx, AV_LOG_DEBUG, "Error while decoding MPEG audio frame.\n"); //FIXME return -1 / but also return the number of bytes consumed + } else { + av_log(avctx, AV_LOG_ERROR, "Error while decoding MPEG audio frame.\n"); + /* Only return an error if the bad frame makes up the whole packet. + If there is more data in the packet, just consume the bad frame + instead of returning an error, which would discard the whole + packet. */ + if (buf_size == avpkt->size) + return out_size; + } s->frame_size = 0; return buf_size; } From dac15a03afca88dc5abe65cbe4782d32d1b74184 Mon Sep 17 00:00:00 2001 From: Justin Ruggles Date: Tue, 27 Sep 2011 11:49:50 -0400 Subject: [PATCH 02/53] mpegaudiodec: return AVERROR return codes instead of -1 --- libavcodec/mpegaudiodec.c | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/libavcodec/mpegaudiodec.c b/libavcodec/mpegaudiodec.c index 004048ce93..a731a292b4 100644 --- a/libavcodec/mpegaudiodec.c +++ b/libavcodec/mpegaudiodec.c @@ -1486,7 +1486,7 @@ static int mp_decode_layer3(MPADecodeContext *s) g->big_values = get_bits(&s->gb, 9); if(g->big_values > 288){ av_log(s->avctx, AV_LOG_ERROR, "big_values too big\n"); - return -1; + return AVERROR_INVALIDDATA; } g->global_gain = get_bits(&s->gb, 8); @@ -1504,7 +1504,7 @@ static int mp_decode_layer3(MPADecodeContext *s) g->block_type = get_bits(&s->gb, 2); if (g->block_type == 0){ av_log(s->avctx, AV_LOG_ERROR, "invalid block type\n"); - return -1; + return AVERROR_INVALIDDATA; } g->switch_point = get_bits1(&s->gb); for(i=0;i<2;i++) @@ -1782,18 +1782,18 @@ static int decode_frame(AVCodecContext * avctx, OUT_INT *out_samples = data; if(buf_size < HEADER_SIZE) - return -1; + return AVERROR_INVALIDDATA; header = AV_RB32(buf); if(ff_mpa_check_header(header) < 0){ av_log(avctx, AV_LOG_ERROR, "Header missing\n"); - return -1; + return AVERROR_INVALIDDATA; } if (avpriv_mpegaudio_decode_header((MPADecodeHeader *)s, header) == 1) { /* free format: prepare to compute frame size */ s->frame_size = -1; - return -1; + return AVERROR_INVALIDDATA; } /* update codec info */ avctx->channels = s->nb_channels; @@ -1803,12 +1803,12 @@ static int decode_frame(AVCodecContext * avctx, avctx->sub_id = s->layer; if(*data_size < 1152*avctx->channels*sizeof(OUT_INT)) - return -1; + return AVERROR(EINVAL); *data_size = 0; if(s->frame_size<=0 || s->frame_size > buf_size){ av_log(avctx, AV_LOG_ERROR, "incomplete frame\n"); - return -1; + return AVERROR_INVALIDDATA; }else if(s->frame_size < buf_size){ av_log(avctx, AV_LOG_ERROR, "incorrect frame size\n"); buf_size= s->frame_size; @@ -1954,13 +1954,13 @@ static int decode_init_mp3on4(AVCodecContext * avctx) if ((avctx->extradata_size < 2) || (avctx->extradata == NULL)) { av_log(avctx, AV_LOG_ERROR, "Codec extradata missing or too short.\n"); - return -1; + return AVERROR_INVALIDDATA; } avpriv_mpeg4audio_get_config(&cfg, avctx->extradata, avctx->extradata_size); if (!cfg.chan_config || cfg.chan_config > 7) { av_log(avctx, AV_LOG_ERROR, "Invalid channel config number.\n"); - return -1; + return AVERROR_INVALIDDATA; } s->frames = mp3Frames[cfg.chan_config]; s->coff = chan_offset[cfg.chan_config]; @@ -2050,7 +2050,7 @@ static int decode_frame_mp3on4(AVCodecContext * avctx, *data_size = 0; // Discard too short frames if (buf_size < HEADER_SIZE) - return -1; + return AVERROR_INVALIDDATA; // If only one decoder interleave is not needed outptr = s->frames == 1 ? out_samples : s->decoded_buf; From c17e534f2e3b07159fba65ba065b08cbe9c7d05c Mon Sep 17 00:00:00 2001 From: Justin Ruggles Date: Tue, 27 Sep 2011 12:02:30 -0400 Subject: [PATCH 03/53] mpegaudiodec: remove frame_count field from MPADecodeContext. Its functionality was removed several years ago, so it doesn't do anything. AVCodecContext.frame_number could serve the same purpose if someone wants to debug the frame count. --- libavcodec/mpegaudiodec.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/libavcodec/mpegaudiodec.c b/libavcodec/mpegaudiodec.c index a731a292b4..3a90bc973a 100644 --- a/libavcodec/mpegaudiodec.c +++ b/libavcodec/mpegaudiodec.c @@ -74,9 +74,6 @@ typedef struct MPADecodeContext { DECLARE_ALIGNED(32, INTFLOAT, sb_samples)[MPA_MAX_CHANNELS][36][SBLIMIT]; INTFLOAT mdct_buf[MPA_MAX_CHANNELS][SBLIMIT * 18]; /* previous samples, for layer 3 MDCT */ GranuleDef granules[2][2]; /* Used in Layer 3 */ -#ifdef DEBUG - int frame_count; -#endif int adu_mode; ///< 0 for standard mp3, 1 for adu formatted mp3 int dither_state; int err_recognition; @@ -1709,7 +1706,6 @@ static int mp_decode_frame(MPADecodeContext *s, if (s->error_protection) skip_bits(&s->gb, 16); - av_dlog(s->avctx, "frame %d:\n", s->frame_count); switch(s->layer) { case 1: s->avctx->frame_size = 384; From cd816d9bbb3e248b5805b8f4aff67cfec12e30f9 Mon Sep 17 00:00:00 2001 From: Justin Ruggles Date: Tue, 27 Sep 2011 13:15:24 -0400 Subject: [PATCH 04/53] mpegaudiodec: cosmetics: basic pretty-printing --- libavcodec/mpegaudiodec.c | 857 +++++++++++++++++++------------------- 1 file changed, 426 insertions(+), 431 deletions(-) diff --git a/libavcodec/mpegaudiodec.c b/libavcodec/mpegaudiodec.c index 3a90bc973a..13a3c56447 100644 --- a/libavcodec/mpegaudiodec.c +++ b/libavcodec/mpegaudiodec.c @@ -21,7 +21,7 @@ /** * @file - * MPEG Audio decoder. + * MPEG Audio decoder */ #include "libavutil/audioconvert.h" @@ -63,7 +63,7 @@ typedef struct GranuleDef { typedef struct MPADecodeContext { MPA_DECODE_HEADER - uint8_t last_buf[2*BACKSTEP_SIZE + EXTRABYTES]; + uint8_t last_buf[2 * BACKSTEP_SIZE + EXTRABYTES]; int last_buf_size; /* next header (used in free format parsing) */ uint32_t free_format_next_header; @@ -92,7 +92,7 @@ typedef struct MPADecodeContext { # define OUT_FMT AV_SAMPLE_FMT_FLT #else # define SHR(a,b) ((a)>>(b)) -/* WARNING: only correct for posititive numbers */ +/* WARNING: only correct for positive numbers */ # define FIXR_OLD(a) ((int)((a) * FRAC_ONE + 0.5)) # define FIXR(a) ((int)((a) * FRAC_ONE + 0.5)) # define FIXHR(a) ((int)((a) * (1LL<<32) + 0.5)) @@ -112,18 +112,16 @@ typedef struct MPADecodeContext { /* vlc structure for decoding layer 3 huffman tables */ static VLC huff_vlc[16]; static VLC_TYPE huff_vlc_tables[ - 0+128+128+128+130+128+154+166+ - 142+204+190+170+542+460+662+414 + 0 + 128 + 128 + 128 + 130 + 128 + 154 + 166 + + 142 + 204 + 190 + 170 + 542 + 460 + 662 + 414 ][2]; static const int huff_vlc_tables_sizes[16] = { - 0, 128, 128, 128, 130, 128, 154, 166, - 142, 204, 190, 170, 542, 460, 662, 414 + 0, 128, 128, 128, 130, 128, 154, 166, + 142, 204, 190, 170, 542, 460, 662, 414 }; static VLC huff_quad_vlc[2]; -static VLC_TYPE huff_quad_vlc_tables[128+16][2]; -static const int huff_quad_vlc_tables_sizes[2] = { - 128, 16 -}; +static VLC_TYPE huff_quad_vlc_tables[128+16][2]; +static const int huff_quad_vlc_tables_sizes[2] = { 128, 16 }; /* computed from band_size_long */ static uint16_t band_index_long[9][23]; #include "mpegaudio_tablegen.h" @@ -160,17 +158,19 @@ static const int32_t scale_factor_mult2[3][3] = { * Convert region offsets to region sizes and truncate * size to big_values. */ -static void ff_region_offset2size(GranuleDef *g){ - int i, k, j=0; - g->region_size[2] = (576 / 2); - for(i=0;i<3;i++) { +static void ff_region_offset2size(GranuleDef *g) +{ + int i, k, j = 0; + g->region_size[2] = 576 / 2; + for (i = 0; i < 3; i++) { k = FFMIN(g->region_size[i], g->big_values); g->region_size[i] = k - j; j = k; } } -static void ff_init_short_region(MPADecodeContext *s, GranuleDef *g){ +static void ff_init_short_region(MPADecodeContext *s, GranuleDef *g) +{ if (g->block_type == 2) g->region_size[0] = (36 / 2); else { @@ -184,17 +184,17 @@ static void ff_init_short_region(MPADecodeContext *s, GranuleDef *g){ g->region_size[1] = (576 / 2); } -static void ff_init_long_region(MPADecodeContext *s, GranuleDef *g, int ra1, int ra2){ +static void ff_init_long_region(MPADecodeContext *s, GranuleDef *g, int ra1, int ra2) +{ int l; - g->region_size[0] = - band_index_long[s->sample_rate_index][ra1 + 1] >> 1; + g->region_size[0] = band_index_long[s->sample_rate_index][ra1 + 1] >> 1; /* should not overflow */ l = FFMIN(ra1 + ra2 + 2, 22); - g->region_size[1] = - band_index_long[s->sample_rate_index][l] >> 1; + g->region_size[1] = band_index_long[s->sample_rate_index][ l] >> 1; } -static void ff_compute_band_indexes(MPADecodeContext *s, GranuleDef *g){ +static void ff_compute_band_indexes(MPADecodeContext *s, GranuleDef *g) +{ if (g->block_type == 2) { if (g->switch_point) { /* if switched mode, we handle the 36 first samples as @@ -209,12 +209,12 @@ static void ff_compute_band_indexes(MPADecodeContext *s, GranuleDef *g){ g->short_start = 2 + (s->sample_rate_index != 8); } else { - g->long_end = 0; + g->long_end = 0; g->short_start = 0; } } else { g->short_start = 13; - g->long_end = 22; + g->long_end = 22; } } @@ -225,11 +225,11 @@ static inline int l1_unscale(int n, int mant, int scale_factor) int shift, mod; int64_t val; - shift = scale_factor_modshift[scale_factor]; - mod = shift & 3; + shift = scale_factor_modshift[scale_factor]; + mod = shift & 3; shift >>= 2; - val = MUL64(mant + (-1 << n) + 1, scale_factor_mult[n-1][mod]); - shift += n; + val = MUL64(mant + (-1 << n) + 1, scale_factor_mult[n-1][mod]); + shift += n; /* NOTE: at this point, 1 <= shift >= 21 + 15 */ return (int)((val + (1LL << (shift - 1))) >> shift); } @@ -238,8 +238,8 @@ static inline int l2_unscale_group(int steps, int mant, int scale_factor) { int shift, mod, val; - shift = scale_factor_modshift[scale_factor]; - mod = shift & 3; + shift = scale_factor_modshift[scale_factor]; + mod = shift & 3; shift >>= 2; val = (mant - (steps >> 1)) * scale_factor_mult2[steps >> 2][mod]; @@ -255,13 +255,13 @@ static inline int l3_unscale(int value, int exponent) unsigned int m; int e; - e = table_4_3_exp [4*value + (exponent&3)]; - m = table_4_3_value[4*value + (exponent&3)]; - e -= (exponent >> 2); - assert(e>=1); + e = table_4_3_exp [4 * value + (exponent & 3)]; + m = table_4_3_value[4 * value + (exponent & 3)]; + e -= exponent >> 2; + assert(e >= 1); if (e > 31) return 0; - m = (m + (1 << (e-1))) >> e; + m = (m + (1 << (e - 1))) >> e; return m; } @@ -269,7 +269,7 @@ static inline int l3_unscale(int value, int exponent) static av_cold int decode_init(AVCodecContext * avctx) { MPADecodeContext *s = avctx->priv_data; - static int init=0; + static int init = 0; int i, j, k; s->avctx = avctx; @@ -283,24 +283,23 @@ static av_cold int decode_init(AVCodecContext * avctx) int offset; /* scale factors table for layer 1/2 */ - for(i=0;i<64;i++) { + for (i = 0; i < 64; i++) { int shift, mod; /* 1.0 (i = 3) is normalized to 2 ^ FRAC_BITS */ - shift = (i / 3); - mod = i % 3; + shift = i / 3; + mod = i % 3; scale_factor_modshift[i] = mod | (shift << 2); } /* scale factor multiply for layer 1 */ - for(i=0;i<15;i++) { + for (i = 0; i < 15; i++) { int n, norm; n = i + 2; norm = ((INT64_C(1) << n) * FRAC_ONE) / ((1 << n) - 1); scale_factor_mult[i][0] = MULLx(norm, FIXR(1.0 * 2.0), FRAC_BITS); scale_factor_mult[i][1] = MULLx(norm, FIXR(0.7937005259 * 2.0), FRAC_BITS); scale_factor_mult[i][2] = MULLx(norm, FIXR(0.6299605249 * 2.0), FRAC_BITS); - av_dlog(avctx, "%d: norm=%x s=%x %x %x\n", - i, norm, + av_dlog(avctx, "%d: norm=%x s=%x %x %x\n", i, norm, scale_factor_mult[i][0], scale_factor_mult[i][1], scale_factor_mult[i][2]); @@ -310,7 +309,7 @@ static av_cold int decode_init(AVCodecContext * avctx) /* huffman decode tables */ offset = 0; - for(i=1;i<16;i++) { + for (i = 1; i < 16; i++) { const HuffTable *h = &mpa_huff_tables[i]; int xsize, x, y; uint8_t tmp_bits [512]; @@ -322,8 +321,8 @@ static av_cold int decode_init(AVCodecContext * avctx) xsize = h->xsize; j = 0; - for(x=0;xbits [j ]; tmp_codes[(x << 5) | y | ((x&&y)<<4)]= h->codes[j++]; } @@ -340,7 +339,7 @@ static av_cold int decode_init(AVCodecContext * avctx) assert(offset == FF_ARRAY_ELEMS(huff_vlc_tables)); offset = 0; - for(i=0;i<2;i++) { + for (i = 0; i < 2; i++) { huff_quad_vlc[i].table = huff_quad_vlc_tables+offset; huff_quad_vlc[i].table_allocated = huff_quad_vlc_tables_sizes[i]; init_vlc(&huff_quad_vlc[i], i == 0 ? 7 : 4, 16, @@ -350,9 +349,9 @@ static av_cold int decode_init(AVCodecContext * avctx) } assert(offset == FF_ARRAY_ELEMS(huff_quad_vlc_tables)); - for(i=0;i<9;i++) { + for (i = 0; i < 9; i++) { k = 0; - for(j=0;j<22;j++) { + for (j = 0; j < 22; j++) { band_index_long[i][j] = k; k += band_size_long[i][j]; } @@ -363,21 +362,23 @@ static av_cold int decode_init(AVCodecContext * avctx) mpegaudio_tableinit(); - for (i = 0; i < 4; i++) - if (ff_mpa_quant_bits[i] < 0) - for (j = 0; j < (1<<(-ff_mpa_quant_bits[i]+1)); j++) { + for (i = 0; i < 4; i++) { + if (ff_mpa_quant_bits[i] < 0) { + for (j = 0; j < (1 << (-ff_mpa_quant_bits[i]+1)); j++) { int val1, val2, val3, steps; int val = j; - steps = ff_mpa_quant_steps[i]; - val1 = val % steps; - val /= steps; - val2 = val % steps; - val3 = val / steps; + steps = ff_mpa_quant_steps[i]; + val1 = val % steps; + val /= steps; + val2 = val % steps; + val3 = val / steps; division_tabs[i][j] = val1 + (val2 << 4) + (val3 << 8); } + } + } - for(i=0;i<7;i++) { + for (i = 0; i < 7; i++) { float f; INTFLOAT v; if (i != 6) { @@ -386,30 +387,30 @@ static av_cold int decode_init(AVCodecContext * avctx) } else { v = FIXR(1.0); } - is_table[0][i] = v; + is_table[0][ i] = v; is_table[1][6 - i] = v; } /* invalid values */ - for(i=7;i<16;i++) + for (i = 7; i < 16; i++) is_table[0][i] = is_table[1][i] = 0.0; - for(i=0;i<16;i++) { + for (i = 0; i < 16; i++) { double f; int e, k; - for(j=0;j<2;j++) { + for (j = 0; j < 2; j++) { e = -(j + 1) * ((i + 1) >> 1); f = pow(2.0, e / 4.0); k = i & 1; is_table_lsf[j][k ^ 1][i] = FIXR(f); - is_table_lsf[j][k][i] = FIXR(1.0); + is_table_lsf[j][k ][i] = FIXR(1.0); av_dlog(avctx, "is_table_lsf %d %d: %f %f\n", i, j, (float) is_table_lsf[j][0][i], (float) is_table_lsf[j][1][i]); } } - for(i=0;i<8;i++) { + for (i = 0; i < 8; i++) { float ci, cs, ca; ci = ci_table[i]; cs = 1.0 / sqrt(1.0 + ci * ci); @@ -428,27 +429,27 @@ static av_cold int decode_init(AVCodecContext * avctx) } /* compute mdct windows */ - for(i=0;i<36;i++) { - for(j=0; j<4; j++){ + for (i = 0; i < 36; i++) { + for (j = 0; j < 4; j++) { double d; - if(j==2 && i%3 != 1) + if (j == 2 && i % 3 != 1) continue; - d= sin(M_PI * (i + 0.5) / 36.0); - if(j==1){ - if (i>=30) d= 0; - else if(i>=24) d= sin(M_PI * (i - 18 + 0.5) / 12.0); - else if(i>=18) d= 1; - }else if(j==3){ - if (i< 6) d= 0; - else if(i< 12) d= sin(M_PI * (i - 6 + 0.5) / 12.0); - else if(i< 18) d= 1; + d = sin(M_PI * (i + 0.5) / 36.0); + if (j == 1) { + if (i >= 30) d = 0; + else if (i >= 24) d = sin(M_PI * (i - 18 + 0.5) / 12.0); + else if (i >= 18) d = 1; + } else if (j == 3) { + if (i < 6) d = 0; + else if (i < 12) d = sin(M_PI * (i - 6 + 0.5) / 12.0); + else if (i < 18) d = 1; } //merge last stage of imdct into the window coefficients - d*= 0.5 / cos(M_PI*(2*i + 19)/72); + d *= 0.5 / cos(M_PI * (2 * i + 19) / 72); - if(j==2) + if (j == 2) mdct_win[j][i/3] = FIXHR((d / (1<<5))); else mdct_win[j][i ] = FIXHR((d / (1<<5))); @@ -457,9 +458,9 @@ static av_cold int decode_init(AVCodecContext * avctx) /* NOTE: we do frequency inversion adter the MDCT by changing the sign of the right window coefs */ - for(j=0;j<4;j++) { - for(i=0;i<36;i+=2) { - mdct_win[j + 4][i] = mdct_win[j][i]; + for (j = 0; j < 4; j++) { + for (i = 0; i < 36; i += 2) { + mdct_win[j + 4][i ] = mdct_win[j][i ]; mdct_win[j + 4][i + 1] = -mdct_win[j][i + 1]; } } @@ -506,41 +507,41 @@ static void imdct12(INTFLOAT *out, INTFLOAT *in) { INTFLOAT in0, in1, in2, in3, in4, in5, t1, t2; - in0= in[0*3]; - in1= in[1*3] + in[0*3]; - in2= in[2*3] + in[1*3]; - in3= in[3*3] + in[2*3]; - in4= in[4*3] + in[3*3]; - in5= in[5*3] + in[4*3]; + in0 = in[0*3]; + in1 = in[1*3] + in[0*3]; + in2 = in[2*3] + in[1*3]; + in3 = in[3*3] + in[2*3]; + in4 = in[4*3] + in[3*3]; + in5 = in[5*3] + in[4*3]; in5 += in3; in3 += in1; - in2= MULH3(in2, C3, 2); - in3= MULH3(in3, C3, 4); + in2 = MULH3(in2, C3, 2); + in3 = MULH3(in3, C3, 4); - t1 = in0 - in4; - t2 = MULH3(in1 - in5, icos36h[4], 2); + t1 = in0 - in4; + t2 = MULH3(in1 - in5, icos36h[4], 2); - out[ 7]= - out[10]= t1 + t2; - out[ 1]= - out[ 4]= t1 - t2; + out[ 7] = + out[10] = t1 + t2; + out[ 1] = + out[ 4] = t1 - t2; - in0 += SHR(in4, 1); - in4 = in0 + in2; - in5 += 2*in1; - in1 = MULH3(in5 + in3, icos36h[1], 1); - out[ 8]= - out[ 9]= in4 + in1; - out[ 2]= - out[ 3]= in4 - in1; + in0 += SHR(in4, 1); + in4 = in0 + in2; + in5 += 2*in1; + in1 = MULH3(in5 + in3, icos36h[1], 1); + out[ 8] = + out[ 9] = in4 + in1; + out[ 2] = + out[ 3] = in4 - in1; - in0 -= in2; - in5 = MULH3(in5 - in3, icos36h[7], 2); - out[ 0]= - out[ 5]= in0 - in5; - out[ 6]= - out[11]= in0 + in5; + in0 -= in2; + in5 = MULH3(in5 - in3, icos36h[7], 2); + out[ 0] = + out[ 5] = in0 - in5; + out[ 6] = + out[11] = in0 + in5; } /* cos(pi*i/18) */ @@ -561,12 +562,12 @@ static void imdct36(INTFLOAT *out, INTFLOAT *buf, INTFLOAT *in, INTFLOAT *win) INTFLOAT t0, t1, t2, t3, s0, s1, s2, s3; INTFLOAT tmp[18], *tmp1, *in1; - for(i=17;i>=1;i--) + for (i = 17; i >= 1; i--) in[i] += in[i-1]; - for(i=17;i>=3;i-=2) + for (i = 17; i >= 3; i -= 2) in[i] += in[i-2]; - for(j=0;j<2;j++) { + for (j = 0; j < 2; j++) { tmp1 = tmp + j; in1 = in + j; @@ -598,7 +599,7 @@ static void imdct36(INTFLOAT *out, INTFLOAT *buf, INTFLOAT *in, INTFLOAT *win) } i = 0; - for(j=0;j<4;j++) { + for (j = 0; j < 4; j++) { t0 = tmp[i]; t1 = tmp[i + 2]; s0 = t1 + t0; @@ -606,22 +607,22 @@ static void imdct36(INTFLOAT *out, INTFLOAT *buf, INTFLOAT *in, INTFLOAT *win) t2 = tmp[i + 1]; t3 = tmp[i + 3]; - s1 = MULH3(t3 + t2, icos36h[j], 2); - s3 = MULLx(t3 - t2, icos36[8 - j], FRAC_BITS); + s1 = MULH3(t3 + t2, icos36h[ j], 2); + s3 = MULLx(t3 - t2, icos36 [8 - j], FRAC_BITS); t0 = s0 + s1; t1 = s0 - s1; - out[(9 + j)*SBLIMIT] = MULH3(t1, win[9 + j], 1) + buf[9 + j]; - out[(8 - j)*SBLIMIT] = MULH3(t1, win[8 - j], 1) + buf[8 - j]; - buf[9 + j] = MULH3(t0, win[18 + 9 + j], 1); - buf[8 - j] = MULH3(t0, win[18 + 8 - j], 1); + out[(9 + j) * SBLIMIT] = MULH3(t1, win[ 9 + j], 1) + buf[9 + j]; + out[(8 - j) * SBLIMIT] = MULH3(t1, win[ 8 - j], 1) + buf[8 - j]; + buf[ 9 + j ] = MULH3(t0, win[18 + 9 + j], 1); + buf[ 8 - j ] = MULH3(t0, win[18 + 8 - j], 1); t0 = s2 + s3; t1 = s2 - s3; - out[(9 + 8 - j)*SBLIMIT] = MULH3(t1, win[9 + 8 - j], 1) + buf[9 + 8 - j]; - out[( j)*SBLIMIT] = MULH3(t1, win[ j], 1) + buf[ j]; - buf[9 + 8 - j] = MULH3(t0, win[18 + 9 + 8 - j], 1); - buf[ + j] = MULH3(t0, win[18 + j], 1); + out[(9 + 8 - j) * SBLIMIT] = MULH3(t1, win[ 9 + 8 - j], 1) + buf[9 + 8 - j]; + out[ j * SBLIMIT] = MULH3(t1, win[ j], 1) + buf[ j]; + buf[ 9 + 8 - j ] = MULH3(t0, win[18 + 9 + 8 - j], 1); + buf[ j ] = MULH3(t0, win[18 + j], 1); i += 4; } @@ -629,10 +630,10 @@ static void imdct36(INTFLOAT *out, INTFLOAT *buf, INTFLOAT *in, INTFLOAT *win) s1 = MULH3(tmp[17], icos36h[4], 2); t0 = s0 + s1; t1 = s0 - s1; - out[(9 + 4)*SBLIMIT] = MULH3(t1, win[9 + 4], 1) + buf[9 + 4]; - out[(8 - 4)*SBLIMIT] = MULH3(t1, win[8 - 4], 1) + buf[8 - 4]; - buf[9 + 4] = MULH3(t0, win[18 + 9 + 4], 1); - buf[8 - 4] = MULH3(t0, win[18 + 8 - 4], 1); + out[(9 + 4) * SBLIMIT] = MULH3(t1, win[ 9 + 4], 1) + buf[9 + 4]; + out[(8 - 4) * SBLIMIT] = MULH3(t1, win[ 8 - 4], 1) + buf[8 - 4]; + buf[ 9 + 4 ] = MULH3(t0, win[18 + 9 + 4], 1); + buf[ 8 - 4 ] = MULH3(t0, win[18 + 8 - 4], 1); } /* return the number of decoded frames */ @@ -648,23 +649,22 @@ static int mp_decode_layer1(MPADecodeContext *s) bound = SBLIMIT; /* allocation bits */ - for(i=0;inb_channels;ch++) { + for (i = 0; i < bound; i++) { + for (ch = 0; ch < s->nb_channels; ch++) { allocation[ch][i] = get_bits(&s->gb, 4); } } - for(i=bound;igb, 4); - } /* scale factors */ - for(i=0;inb_channels;ch++) { + for (i = 0; i < bound; i++) { + for (ch = 0; ch < s->nb_channels; ch++) { if (allocation[ch][i]) scale_factors[ch][i] = get_bits(&s->gb, 6); } } - for(i=bound;igb, 6); scale_factors[1][i] = get_bits(&s->gb, 6); @@ -672,9 +672,9 @@ static int mp_decode_layer1(MPADecodeContext *s) } /* compute samples */ - for(j=0;j<12;j++) { - for(i=0;inb_channels;ch++) { + for (j = 0; j < 12; j++) { + for (i = 0; i < bound; i++) { + for (ch = 0; ch < s->nb_channels; ch++) { n = allocation[ch][i]; if (n) { mant = get_bits(&s->gb, n + 1); @@ -685,7 +685,7 @@ static int mp_decode_layer1(MPADecodeContext *s) s->sb_samples[ch][j][i] = v; } } - for(i=bound;igb, n + 1); @@ -714,8 +714,8 @@ static int mp_decode_layer2(MPADecodeContext *s) /* select decoding table */ table = ff_mpa_l2_select_table(s->bit_rate / 1000, s->nb_channels, - s->sample_rate, s->lsf); - sblimit = ff_mpa_sblimit_table[table]; + s->sample_rate, s->lsf); + sblimit = ff_mpa_sblimit_table[table]; alloc_table = ff_mpa_alloc_tables[table]; if (s->mode == MPA_JSTEREO) @@ -726,18 +726,18 @@ static int mp_decode_layer2(MPADecodeContext *s) av_dlog(s->avctx, "bound=%d sblimit=%d\n", bound, sblimit); /* sanity check */ - if( bound > sblimit ) bound = sblimit; + if (bound > sblimit) + bound = sblimit; /* parse bit allocation */ j = 0; - for(i=0;inb_channels;ch++) { + for (ch = 0; ch < s->nb_channels; ch++) bit_alloc[ch][i] = get_bits(&s->gb, bit_alloc_bits); - } j += 1 << bit_alloc_bits; } - for(i=bound;igb, bit_alloc_bits); bit_alloc[0][i] = v; @@ -746,19 +746,19 @@ static int mp_decode_layer2(MPADecodeContext *s) } /* scale codes */ - for(i=0;inb_channels;ch++) { + for (i = 0; i < sblimit; i++) { + for (ch = 0; ch < s->nb_channels; ch++) { if (bit_alloc[ch][i]) scale_code[ch][i] = get_bits(&s->gb, 2); } } /* scale factors */ - for(i=0;inb_channels;ch++) { + for (i = 0; i < sblimit; i++) { + for (ch = 0; ch < s->nb_channels; ch++) { if (bit_alloc[ch][i]) { sf = scale_factors[ch][i]; - switch(scale_code[ch][i]) { + switch (scale_code[ch][i]) { default: case 0: sf[0] = get_bits(&s->gb, 6); @@ -786,12 +786,12 @@ static int mp_decode_layer2(MPADecodeContext *s) } /* samples */ - for(k=0;k<3;k++) { - for(l=0;l<12;l+=3) { + for (k = 0; k < 3; k++) { + for (l = 0; l < 12; l += 3) { j = 0; - for(i=0;inb_channels;ch++) { + for (ch = 0; ch < s->nb_channels; ch++) { b = bit_alloc[ch][i]; if (b) { scale = scale_factors[ch][i][k]; @@ -805,13 +805,13 @@ static int mp_decode_layer2(MPADecodeContext *s) steps = ff_mpa_quant_steps[qindex]; s->sb_samples[ch][k * 12 + l + 0][i] = - l2_unscale_group(steps, v2 & 15, scale); + l2_unscale_group(steps, v2 & 15, scale); s->sb_samples[ch][k * 12 + l + 1][i] = l2_unscale_group(steps, (v2 >> 4) & 15, scale); s->sb_samples[ch][k * 12 + l + 2][i] = l2_unscale_group(steps, v2 >> 8 , scale); } else { - for(m=0;m<3;m++) { + for (m = 0; m < 3; m++) { v = get_bits(&s->gb, bits); v = l1_unscale(bits - 1, v, scale); s->sb_samples[ch][k * 12 + l + m][i] = v; @@ -827,7 +827,7 @@ static int mp_decode_layer2(MPADecodeContext *s) j += 1 << bit_alloc_bits; } /* XXX: find a way to avoid this duplication of code */ - for(i=bound;isb_samples[1][k * 12 + l + 2][i] = l2_unscale_group(steps, v, scale1); } else { - for(m=0;m<3;m++) { + for (m = 0; m < 3; m++) { mant = get_bits(&s->gb, bits); s->sb_samples[0][k * 12 + l + m][i] = l1_unscale(bits - 1, mant, scale0); @@ -877,8 +877,8 @@ static int mp_decode_layer2(MPADecodeContext *s) j += 1 << bit_alloc_bits; } /* fill remaining samples to zero */ - for(i=sblimit;inb_channels;ch++) { + for (i = sblimit; i < SBLIMIT; i++) { + for (ch = 0; ch < s->nb_channels; ch++) { s->sb_samples[ch][k * 12 + l + 0][i] = 0; s->sb_samples[ch][k * 12 + l + 1][i] = 0; s->sb_samples[ch][k * 12 + l + 2][i] = 0; @@ -889,28 +889,28 @@ static int mp_decode_layer2(MPADecodeContext *s) return 3 * 12; } -#define SPLIT(dst,sf,n)\ - if(n==3){\ - int m= (sf*171)>>9;\ - dst= sf - 3*m;\ - sf=m;\ - }else if(n==4){\ - dst= sf&3;\ - sf>>=2;\ - }else if(n==5){\ - int m= (sf*205)>>10;\ - dst= sf - 5*m;\ - sf=m;\ - }else if(n==6){\ - int m= (sf*171)>>10;\ - dst= sf - 6*m;\ - sf=m;\ - }else{\ - dst=0;\ +#define SPLIT(dst,sf,n) \ + if (n == 3) { \ + int m = (sf * 171) >> 9; \ + dst = sf - 3 * m; \ + sf = m; \ + } else if (n == 4) { \ + dst = sf & 3; \ + sf >>= 2; \ + } else if (n == 5) { \ + int m = (sf * 205) >> 10; \ + dst = sf - 5 * m; \ + sf = m; \ + } else if (n == 6) { \ + int m = (sf * 171) >> 10; \ + dst = sf - 6 * m; \ + sf = m; \ + } else { \ + dst = 0; \ } -static av_always_inline void lsf_sf_expand(int *slen, - int sf, int n1, int n2, int n3) +static av_always_inline void lsf_sf_expand(int *slen, int sf, int n1, int n2, + int n3) { SPLIT(slen[3], sf, n3) SPLIT(slen[2], sf, n2) @@ -918,8 +918,7 @@ static av_always_inline void lsf_sf_expand(int *slen, slen[0] = sf; } -static void exponents_from_scale_factors(MPADecodeContext *s, - GranuleDef *g, +static void exponents_from_scale_factors(MPADecodeContext *s, GranuleDef *g, int16_t *exponents) { const uint8_t *bstab, *pretab; @@ -927,30 +926,30 @@ static void exponents_from_scale_factors(MPADecodeContext *s, int16_t *exp_ptr; exp_ptr = exponents; - gain = g->global_gain - 210; - shift = g->scalefac_scale + 1; + gain = g->global_gain - 210; + shift = g->scalefac_scale + 1; - bstab = band_size_long[s->sample_rate_index]; + bstab = band_size_long[s->sample_rate_index]; pretab = mpa_pretab[g->preflag]; - for(i=0;ilong_end;i++) { + for (i = 0; i < g->long_end; i++) { v0 = gain - ((g->scale_factors[i] + pretab[i]) << shift) + 400; len = bstab[i]; - for(j=len;j>0;j--) + for (j = len; j > 0; j--) *exp_ptr++ = v0; } if (g->short_start < 13) { - bstab = band_size_short[s->sample_rate_index]; + bstab = band_size_short[s->sample_rate_index]; gains[0] = gain - (g->subblock_gain[0] << 3); gains[1] = gain - (g->subblock_gain[1] << 3); gains[2] = gain - (g->subblock_gain[2] << 3); - k = g->long_end; - for(i=g->short_start;i<13;i++) { + k = g->long_end; + for (i = g->short_start; i < 13; i++) { len = bstab[i]; - for(l=0;l<3;l++) { + for (l = 0; l < 3; l++) { v0 = gains[l] - (g->scale_factors[k++] << shift) + 400; - for(j=len;j>0;j--) - *exp_ptr++ = v0; + for (j = len; j > 0; j--) + *exp_ptr++ = v0; } } } @@ -959,22 +958,21 @@ static void exponents_from_scale_factors(MPADecodeContext *s, /* handle n = 0 too */ static inline int get_bitsz(GetBitContext *s, int n) { - if (n == 0) - return 0; - else - return get_bits(s, n); + return n ? get_bits(s, n) : 0; } -static void switch_buffer(MPADecodeContext *s, int *pos, int *end_pos, int *end_pos2){ - if(s->in_gb.buffer && *pos >= s->gb.size_in_bits){ - s->gb= s->in_gb; - s->in_gb.buffer=NULL; +static void switch_buffer(MPADecodeContext *s, int *pos, int *end_pos, + int *end_pos2) +{ + if (s->in_gb.buffer && *pos >= s->gb.size_in_bits) { + s->gb = s->in_gb; + s->in_gb.buffer = NULL; assert((get_bits_count(&s->gb) & 7) == 0); skip_bits_long(&s->gb, *pos - *end_pos); - *end_pos2= - *end_pos= *end_pos2 + get_bits_count(&s->gb) - *pos; - *pos= get_bits_count(&s->gb); + *end_pos2 = + *end_pos = *end_pos2 + get_bits_count(&s->gb) - *pos; + *pos = get_bits_count(&s->gb); } } @@ -985,13 +983,13 @@ static void switch_buffer(MPADecodeContext *s, int *pos, int *end_pos, int *end_ *dst = v; */ #if CONFIG_FLOAT -#define READ_FLIP_SIGN(dst,src)\ - v = AV_RN32A(src) ^ (get_bits1(&s->gb)<<31);\ - AV_WN32A(dst, v); +#define READ_FLIP_SIGN(dst,src) \ + v = AV_RN32A(src) ^ (get_bits1(&s->gb) << 31); \ + AV_WN32A(dst, v); #else -#define READ_FLIP_SIGN(dst,src)\ - v= -get_bits1(&s->gb);\ - *(dst) = (*(src) ^ v) - v; +#define READ_FLIP_SIGN(dst,src) \ + v = -get_bits1(&s->gb); \ + *(dst) = (*(src) ^ v) - v; #endif static int huffman_decode(MPADecodeContext *s, GranuleDef *g, @@ -1001,43 +999,43 @@ static int huffman_decode(MPADecodeContext *s, GranuleDef *g, int i; int last_pos, bits_left; VLC *vlc; - int end_pos= FFMIN(end_pos2, s->gb.size_in_bits); + int end_pos = FFMIN(end_pos2, s->gb.size_in_bits); /* low frequencies (called big values) */ s_index = 0; - for(i=0;i<3;i++) { + for (i = 0; i < 3; i++) { int j, k, l, linbits; j = g->region_size[i]; if (j == 0) continue; /* select vlc table */ - k = g->table_select[i]; - l = mpa_huff_data[k][0]; + k = g->table_select[i]; + l = mpa_huff_data[k][0]; linbits = mpa_huff_data[k][1]; - vlc = &huff_vlc[l]; + vlc = &huff_vlc[l]; - if(!l){ - memset(&g->sb_hybrid[s_index], 0, sizeof(*g->sb_hybrid)*2*j); - s_index += 2*j; + if (!l) { + memset(&g->sb_hybrid[s_index], 0, sizeof(*g->sb_hybrid) * 2 * j); + s_index += 2 * j; continue; } /* read huffcode and compute each couple */ - for(;j>0;j--) { + for (; j > 0; j--) { int exponent, x, y; int v; - int pos= get_bits_count(&s->gb); + int pos = get_bits_count(&s->gb); if (pos >= end_pos){ // av_log(NULL, AV_LOG_ERROR, "pos: %d %d %d %d\n", pos, end_pos, end_pos2, s_index); switch_buffer(s, &pos, &end_pos, &end_pos2); // av_log(NULL, AV_LOG_ERROR, "new pos: %d %d\n", pos, end_pos); - if(pos >= end_pos) + if (pos >= end_pos) break; } y = get_vlc2(&s->gb, vlc->table, 7, 3); - if(!y){ + if (!y) { g->sb_hybrid[s_index ] = g->sb_hybrid[s_index+1] = 0; s_index += 2; @@ -1048,54 +1046,54 @@ static int huffman_decode(MPADecodeContext *s, GranuleDef *g, av_dlog(s->avctx, "region=%d n=%d x=%d y=%d exp=%d\n", i, g->region_size[i] - j, x, y, exponent); - if(y&16){ + if (y & 16) { x = y >> 5; y = y & 0x0f; - if (x < 15){ - READ_FLIP_SIGN(g->sb_hybrid+s_index, RENAME(expval_table)[ exponent ]+x) - }else{ + if (x < 15) { + READ_FLIP_SIGN(g->sb_hybrid + s_index, RENAME(expval_table)[exponent] + x) + } else { x += get_bitsz(&s->gb, linbits); - v = l3_unscale(x, exponent); + v = l3_unscale(x, exponent); if (get_bits1(&s->gb)) v = -v; g->sb_hybrid[s_index] = v; } - if (y < 15){ - READ_FLIP_SIGN(g->sb_hybrid+s_index+1, RENAME(expval_table)[ exponent ]+y) - }else{ + if (y < 15) { + READ_FLIP_SIGN(g->sb_hybrid + s_index + 1, RENAME(expval_table)[exponent] + y) + } else { y += get_bitsz(&s->gb, linbits); - v = l3_unscale(y, exponent); + v = l3_unscale(y, exponent); if (get_bits1(&s->gb)) v = -v; g->sb_hybrid[s_index+1] = v; } - }else{ + } else { x = y >> 5; y = y & 0x0f; x += y; - if (x < 15){ - READ_FLIP_SIGN(g->sb_hybrid+s_index+!!y, RENAME(expval_table)[ exponent ]+x) - }else{ + if (x < 15) { + READ_FLIP_SIGN(g->sb_hybrid + s_index + !!y, RENAME(expval_table)[exponent] + x) + } else { x += get_bitsz(&s->gb, linbits); - v = l3_unscale(x, exponent); + v = l3_unscale(x, exponent); if (get_bits1(&s->gb)) v = -v; g->sb_hybrid[s_index+!!y] = v; } - g->sb_hybrid[s_index+ !y] = 0; + g->sb_hybrid[s_index + !y] = 0; } - s_index+=2; + s_index += 2; } } /* high frequencies */ vlc = &huff_quad_vlc[g->count1table_select]; - last_pos=0; + last_pos = 0; while (s_index <= 572) { int pos, code; pos = get_bits_count(&s->gb); if (pos >= end_pos) { - if (pos > end_pos2 && last_pos){ + if (pos > end_pos2 && last_pos) { /* some encoders generate an incorrect size for this part. We must go back into the data */ s_index -= 4; @@ -1108,25 +1106,25 @@ static int huffman_decode(MPADecodeContext *s, GranuleDef *g, // av_log(NULL, AV_LOG_ERROR, "pos2: %d %d %d %d\n", pos, end_pos, end_pos2, s_index); switch_buffer(s, &pos, &end_pos, &end_pos2); // av_log(NULL, AV_LOG_ERROR, "new pos2: %d %d %d\n", pos, end_pos, s_index); - if(pos >= end_pos) + if (pos >= end_pos) break; } - last_pos= pos; + last_pos = pos; code = get_vlc2(&s->gb, vlc->table, vlc->bits, 1); av_dlog(s->avctx, "t=%d code=%d\n", g->count1table_select, code); - g->sb_hybrid[s_index+0]= - g->sb_hybrid[s_index+1]= - g->sb_hybrid[s_index+2]= - g->sb_hybrid[s_index+3]= 0; - while(code){ - static const int idxtab[16]={3,3,2,2,1,1,1,1,0,0,0,0,0,0,0,0}; + g->sb_hybrid[s_index+0] = + g->sb_hybrid[s_index+1] = + g->sb_hybrid[s_index+2] = + g->sb_hybrid[s_index+3] = 0; + while (code) { + static const int idxtab[16] = { 3,3,2,2,1,1,1,1,0,0,0,0,0,0,0,0 }; int v; - int pos= s_index+idxtab[code]; - code ^= 8>>idxtab[code]; - READ_FLIP_SIGN(g->sb_hybrid+pos, RENAME(exp_table)+exponents[pos]) + int pos = s_index + idxtab[code]; + code ^= 8 >> idxtab[code]; + READ_FLIP_SIGN(g->sb_hybrid + pos, RENAME(exp_table)+exponents[pos]) } - s_index+=4; + s_index += 4; } /* skip extension bits */ bits_left = end_pos2 - get_bits_count(&s->gb); @@ -1134,14 +1132,14 @@ static int huffman_decode(MPADecodeContext *s, GranuleDef *g, if (bits_left < 0 && (s->err_recognition & AV_EF_BITSTREAM)) { av_log(s->avctx, AV_LOG_ERROR, "bits_left=%d\n", bits_left); s_index=0; - }else if(bits_left > 0 && (s->err_recognition & AV_EF_BUFFER)){ + } else if (bits_left > 0 && (s->err_recognition & AV_EF_BUFFER)) { av_log(s->avctx, AV_LOG_ERROR, "bits_left=%d\n", bits_left); - s_index=0; + s_index = 0; } - memset(&g->sb_hybrid[s_index], 0, sizeof(*g->sb_hybrid)*(576 - s_index)); + memset(&g->sb_hybrid[s_index], 0, sizeof(*g->sb_hybrid) * (576 - s_index)); skip_bits_long(&s->gb, bits_left); - i= get_bits_count(&s->gb); + i = get_bits_count(&s->gb); switch_buffer(s, &i, &end_pos, &end_pos2); return 0; @@ -1160,34 +1158,32 @@ static void reorder_block(MPADecodeContext *s, GranuleDef *g) return; if (g->switch_point) { - if (s->sample_rate_index != 8) { + if (s->sample_rate_index != 8) ptr = g->sb_hybrid + 36; - } else { + else ptr = g->sb_hybrid + 48; - } } else { ptr = g->sb_hybrid; } - for(i=g->short_start;i<13;i++) { - len = band_size_short[s->sample_rate_index][i]; + for (i = g->short_start; i < 13; i++) { + len = band_size_short[s->sample_rate_index][i]; ptr1 = ptr; - dst = tmp; - for(j=len;j>0;j--) { + dst = tmp; + for (j = len; j > 0; j--) { *dst++ = ptr[0*len]; *dst++ = ptr[1*len]; *dst++ = ptr[2*len]; ptr++; } - ptr+=2*len; + ptr += 2 * len; memcpy(ptr1, tmp, len * 3 * sizeof(*ptr1)); } } #define ISQRT2 FIXR(0.70710678118654752440) -static void compute_stereo(MPADecodeContext *s, - GranuleDef *g0, GranuleDef *g1) +static void compute_stereo(MPADecodeContext *s, GranuleDef *g0, GranuleDef *g1) { int i, j, k, l; int sf_max, sf, len, non_zero_found; @@ -1211,17 +1207,17 @@ static void compute_stereo(MPADecodeContext *s, non_zero_found_short[1] = 0; non_zero_found_short[2] = 0; k = (13 - g1->short_start) * 3 + g1->long_end - 3; - for(i = 12;i >= g1->short_start;i--) { + for (i = 12; i >= g1->short_start; i--) { /* for last band, use previous scale factor */ if (i != 11) k -= 3; len = band_size_short[s->sample_rate_index][i]; - for(l=2;l>=0;l--) { + for (l = 2; l >= 0; l--) { tab0 -= len; tab1 -= len; if (!non_zero_found_short[l]) { /* test if non zero band. if so, stop doing i-stereo */ - for(j=0;jmode_ext & MODE_EXT_MS_STEREO) { /* lower part of the spectrum : do ms stereo if enabled */ - for(j=0;jlong_end - 1;i >= 0;i--) { - len = band_size_long[s->sample_rate_index][i]; + for (i = g1->long_end - 1;i >= 0;i--) { + len = band_size_long[s->sample_rate_index][i]; tab0 -= len; tab1 -= len; /* test if non zero band. if so, stop doing i-stereo */ if (!non_zero_found) { - for(j=0;jscale_factors[k]; if (sf >= sf_max) goto found2; v1 = is_tab[0][sf]; v2 = is_tab[1][sf]; - for(j=0;jmode_ext & MODE_EXT_MS_STEREO) { /* lower part of the spectrum : do ms stereo if enabled */ - for(j=0;jsb_hybrid; tab1 = g1->sb_hybrid; - for(i=0;i<576;i++) { - tmp0 = tab0[i]; - tmp1 = tab1[i]; + for (i = 0; i < 576; i++) { + tmp0 = tab0[i]; + tmp1 = tab1[i]; tab0[i] = tmp0 + tmp1; tab1[i] = tmp0 - tmp1; } @@ -1323,8 +1319,8 @@ static void compute_stereo(MPADecodeContext *s, int tmp0 = ptr[-1-j]; \ int tmp1 = ptr[ j]; \ int tmp2 = MULH(tmp0 + tmp1, csa_table[j][0]); \ - ptr[-1-j] = 4*(tmp2 - MULH(tmp1, csa_table[j][2])); \ - ptr[ j] = 4*(tmp2 + MULH(tmp0, csa_table[j][3])); \ + ptr[-1-j] = 4 * (tmp2 - MULH(tmp1, csa_table[j][2])); \ + ptr[ j] = 4 * (tmp2 + MULH(tmp0, csa_table[j][3])); \ } while (0) #endif @@ -1344,7 +1340,7 @@ static void compute_antialias(MPADecodeContext *s, GranuleDef *g) } ptr = g->sb_hybrid + 18; - for(i = n;i > 0;i--) { + for (i = n; i > 0; i--) { AA(0); AA(1); AA(2); @@ -1358,23 +1354,21 @@ static void compute_antialias(MPADecodeContext *s, GranuleDef *g) } } -static void compute_imdct(MPADecodeContext *s, - GranuleDef *g, - INTFLOAT *sb_samples, - INTFLOAT *mdct_buf) +static void compute_imdct(MPADecodeContext *s, GranuleDef *g, + INTFLOAT *sb_samples, INTFLOAT *mdct_buf) { INTFLOAT *win, *win1, *out_ptr, *ptr, *buf, *ptr1; INTFLOAT out2[12]; int i, j, mdct_long_end, sblimit; /* find last non zero block */ - ptr = g->sb_hybrid + 576; + ptr = g->sb_hybrid + 576; ptr1 = g->sb_hybrid + 2 * 18; while (ptr >= ptr1) { int32_t *p; ptr -= 6; - p= (int32_t*)ptr; - if(p[0] | p[1] | p[2] | p[3] | p[4] | p[5]) + p = (int32_t*)ptr; + if (p[0] | p[1] | p[2] | p[3] | p[4] | p[5]) break; } sblimit = ((ptr - g->sb_hybrid) / 18) + 1; @@ -1391,7 +1385,7 @@ static void compute_imdct(MPADecodeContext *s, buf = mdct_buf; ptr = g->sb_hybrid; - for(j=0;jgb, 5); nb_granules = 2; - for(ch=0;chnb_channels;ch++) { + for (ch = 0; ch < s->nb_channels; ch++) { s->granules[ch][0].scfsi = 0;/* all scale factors are transmitted */ s->granules[ch][1].scfsi = get_bits(&s->gb, 4); } } - for(gr=0;grnb_channels;ch++) { + for (gr = 0; gr < nb_granules; gr++) { + for (ch = 0; ch < s->nb_channels; ch++) { av_dlog(s->avctx, "gr=%d ch=%d: side_info\n", gr, ch); g = &s->granules[ch][gr]; g->part2_3_length = get_bits(&s->gb, 12); - g->big_values = get_bits(&s->gb, 9); - if(g->big_values > 288){ + g->big_values = get_bits(&s->gb, 9); + if (g->big_values > 288) { av_log(s->avctx, AV_LOG_ERROR, "big_values too big\n"); return AVERROR_INVALIDDATA; } @@ -1499,21 +1493,21 @@ static int mp_decode_layer3(MPADecodeContext *s) blocksplit_flag = get_bits1(&s->gb); if (blocksplit_flag) { g->block_type = get_bits(&s->gb, 2); - if (g->block_type == 0){ + if (g->block_type == 0) { av_log(s->avctx, AV_LOG_ERROR, "invalid block type\n"); return AVERROR_INVALIDDATA; } g->switch_point = get_bits1(&s->gb); - for(i=0;i<2;i++) + for (i = 0; i < 2; i++) g->table_select[i] = get_bits(&s->gb, 5); - for(i=0;i<3;i++) + for (i = 0; i < 3; i++) g->subblock_gain[i] = get_bits(&s->gb, 3); ff_init_short_region(s, g); } else { int region_address1, region_address2; g->block_type = 0; g->switch_point = 0; - for(i=0;i<3;i++) + for (i = 0; i < 3; i++) g->table_select[i] = get_bits(&s->gb, 5); /* compute huffman coded region sizes */ region_address1 = get_bits(&s->gb, 4); @@ -1528,38 +1522,38 @@ static int mp_decode_layer3(MPADecodeContext *s) g->preflag = 0; if (!s->lsf) g->preflag = get_bits1(&s->gb); - g->scalefac_scale = get_bits1(&s->gb); + g->scalefac_scale = get_bits1(&s->gb); g->count1table_select = get_bits1(&s->gb); av_dlog(s->avctx, "block_type=%d switch_point=%d\n", g->block_type, g->switch_point); } } - if (!s->adu_mode) { - const uint8_t *ptr = s->gb.buffer + (get_bits_count(&s->gb)>>3); - assert((get_bits_count(&s->gb) & 7) == 0); - /* now we get bits from the main_data_begin offset */ - av_dlog(s->avctx, "seekback: %d\n", main_data_begin); -//av_log(NULL, AV_LOG_ERROR, "backstep:%d, lastbuf:%d\n", main_data_begin, s->last_buf_size); + if (!s->adu_mode) { + const uint8_t *ptr = s->gb.buffer + (get_bits_count(&s->gb)>>3); + assert((get_bits_count(&s->gb) & 7) == 0); + /* now we get bits from the main_data_begin offset */ + av_dlog(s->avctx, "seekback: %d\n", main_data_begin); + //av_log(NULL, AV_LOG_ERROR, "backstep:%d, lastbuf:%d\n", main_data_begin, s->last_buf_size); - memcpy(s->last_buf + s->last_buf_size, ptr, EXTRABYTES); - s->in_gb= s->gb; + memcpy(s->last_buf + s->last_buf_size, ptr, EXTRABYTES); + s->in_gb = s->gb; init_get_bits(&s->gb, s->last_buf, s->last_buf_size*8); skip_bits_long(&s->gb, 8*(s->last_buf_size - main_data_begin)); - } + } - for(gr=0;grnb_channels;ch++) { + for (gr = 0; gr < nb_granules; gr++) { + for (ch = 0; ch < s->nb_channels; ch++) { g = &s->granules[ch][gr]; - if(get_bits_count(&s->gb)<0){ + if (get_bits_count(&s->gb) < 0) { av_log(s->avctx, AV_LOG_DEBUG, "mdb:%d, lastbuf:%d skipping granule %d\n", - main_data_begin, s->last_buf_size, gr); + main_data_begin, s->last_buf_size, gr); skip_bits_long(&s->gb, g->part2_3_length); memset(g->sb_hybrid, 0, sizeof(g->sb_hybrid)); - if(get_bits_count(&s->gb) >= s->gb.size_in_bits && s->in_gb.buffer){ + if (get_bits_count(&s->gb) >= s->gb.size_in_bits && s->in_gb.buffer) { skip_bits_long(&s->in_gb, get_bits_count(&s->gb) - s->gb.size_in_bits); - s->gb= s->in_gb; - s->in_gb.buffer=NULL; + s->gb = s->in_gb; + s->in_gb.buffer = NULL; } continue; } @@ -1577,39 +1571,39 @@ static int mp_decode_layer3(MPADecodeContext *s) if (g->block_type == 2) { n = g->switch_point ? 17 : 18; j = 0; - if(slen1){ - for(i=0;iscale_factors[j++] = get_bits(&s->gb, slen1); - }else{ - for(i=0;iscale_factors[j++] = 0; } - if(slen2){ - for(i=0;i<18;i++) + if (slen2) { + for (i = 0; i < 18; i++) g->scale_factors[j++] = get_bits(&s->gb, slen2); - for(i=0;i<3;i++) + for (i = 0; i < 3; i++) g->scale_factors[j++] = 0; - }else{ - for(i=0;i<21;i++) + } else { + for (i = 0; i < 21; i++) g->scale_factors[j++] = 0; } } else { sc = s->granules[ch][0].scale_factors; j = 0; - for(k=0;k<4;k++) { - n = (k == 0 ? 6 : 5); + for (k = 0; k < 4; k++) { + n = k == 0 ? 6 : 5; if ((g->scfsi & (0x8 >> k)) == 0) { slen = (k < 2) ? slen1 : slen2; - if(slen){ - for(i=0;iscale_factors[j++] = get_bits(&s->gb, slen); - }else{ - for(i=0;iscale_factors[j++] = 0; } } else { /* simply copy from last granule */ - for(i=0;iscale_factors[j] = sc[j]; j++; } @@ -1621,11 +1615,11 @@ static int mp_decode_layer3(MPADecodeContext *s) int tindex, tindex2, slen[4], sl, sf; /* LSF scale factors */ - if (g->block_type == 2) { + if (g->block_type == 2) tindex = g->switch_point ? 2 : 1; - } else { + else tindex = 0; - } + sf = g->scalefac_compress; if ((s->mode_ext & MODE_EXT_I_STEREO) && ch == 1) { /* intensity stereo case */ @@ -1656,19 +1650,19 @@ static int mp_decode_layer3(MPADecodeContext *s) } j = 0; - for(k=0;k<4;k++) { - n = lsf_nsf_table[tindex2][tindex][k]; + for (k = 0; k < 4; k++) { + n = lsf_nsf_table[tindex2][tindex][k]; sl = slen[k]; - if(sl){ - for(i=0;iscale_factors[j++] = get_bits(&s->gb, sl); - }else{ - for(i=0;iscale_factors[j++] = 0; } } /* XXX: should compute exact size */ - for(;j<40;j++) + for (; j < 40; j++) g->scale_factors[j] = 0; } @@ -1681,7 +1675,7 @@ static int mp_decode_layer3(MPADecodeContext *s) if (s->nb_channels == 2) compute_stereo(s, &s->granules[0][gr], &s->granules[1][gr]); - for(ch=0;chnb_channels;ch++) { + for (ch = 0; ch < s->nb_channels; ch++) { g = &s->granules[ch][gr]; reorder_block(s, g); @@ -1689,18 +1683,18 @@ static int mp_decode_layer3(MPADecodeContext *s) compute_imdct(s, g, &s->sb_samples[ch][18 * gr][0], s->mdct_buf[ch]); } } /* gr */ - if(get_bits_count(&s->gb)<0) + if (get_bits_count(&s->gb) < 0) skip_bits_long(&s->gb, -get_bits_count(&s->gb)); return nb_granules * 18; } -static int mp_decode_frame(MPADecodeContext *s, - OUT_INT *samples, const uint8_t *buf, int buf_size) +static int mp_decode_frame(MPADecodeContext *s, OUT_INT *samples, + const uint8_t *buf, int buf_size) { int i, nb_frames, ch; OUT_INT *samples_ptr; - init_get_bits(&s->gb, buf + HEADER_SIZE, (buf_size - HEADER_SIZE)*8); + init_get_bits(&s->gb, buf + HEADER_SIZE, (buf_size - HEADER_SIZE) * 8); /* skip error protection field */ if (s->error_protection) @@ -1721,28 +1715,28 @@ static int mp_decode_frame(MPADecodeContext *s, nb_frames = mp_decode_layer3(s); s->last_buf_size=0; - if(s->in_gb.buffer){ + if (s->in_gb.buffer) { align_get_bits(&s->gb); - i= get_bits_left(&s->gb)>>3; - if(i >= 0 && i <= BACKSTEP_SIZE){ + i = get_bits_left(&s->gb)>>3; + if (i >= 0 && i <= BACKSTEP_SIZE) { memmove(s->last_buf, s->gb.buffer + (get_bits_count(&s->gb)>>3), i); s->last_buf_size=i; - }else + } else av_log(s->avctx, AV_LOG_ERROR, "invalid old backstep %d\n", i); - s->gb= s->in_gb; - s->in_gb.buffer= NULL; + s->gb = s->in_gb; + s->in_gb.buffer = NULL; } align_get_bits(&s->gb); assert((get_bits_count(&s->gb) & 7) == 0); - i= get_bits_left(&s->gb)>>3; + i = get_bits_left(&s->gb) >> 3; - if(i<0 || i > BACKSTEP_SIZE || nb_frames<0){ - if(i<0) + if (i < 0 || i > BACKSTEP_SIZE || nb_frames < 0) { + if (i < 0) av_log(s->avctx, AV_LOG_ERROR, "invalid new backstep %d\n", i); - i= FFMIN(BACKSTEP_SIZE, buf_size - HEADER_SIZE); + i = FFMIN(BACKSTEP_SIZE, buf_size - HEADER_SIZE); } - assert(i <= buf_size - HEADER_SIZE && i>= 0); + assert(i <= buf_size - HEADER_SIZE && i >= 0); memcpy(s->last_buf + s->last_buf_size, s->gb.buffer + buf_size - HEADER_SIZE - i, i); s->last_buf_size += i; @@ -1750,9 +1744,9 @@ static int mp_decode_frame(MPADecodeContext *s, } /* apply the synthesis filter */ - for(ch=0;chnb_channels;ch++) { + for (ch = 0; ch < s->nb_channels; ch++) { samples_ptr = samples + ch; - for(i=0;impadsp, s->synth_buf[ch], &(s->synth_buf_offset[ch]), @@ -1766,22 +1760,21 @@ static int mp_decode_frame(MPADecodeContext *s, return nb_frames * 32 * sizeof(OUT_INT) * s->nb_channels; } -static int decode_frame(AVCodecContext * avctx, - void *data, int *data_size, +static int decode_frame(AVCodecContext * avctx, void *data, int *data_size, AVPacket *avpkt) { - const uint8_t *buf = avpkt->data; - int buf_size = avpkt->size; + const uint8_t *buf = avpkt->data; + int buf_size = avpkt->size; MPADecodeContext *s = avctx->priv_data; uint32_t header; int out_size; OUT_INT *out_samples = data; - if(buf_size < HEADER_SIZE) + if (buf_size < HEADER_SIZE) return AVERROR_INVALIDDATA; header = AV_RB32(buf); - if(ff_mpa_check_header(header) < 0){ + if (ff_mpa_check_header(header) < 0) { av_log(avctx, AV_LOG_ERROR, "Header missing\n"); return AVERROR_INVALIDDATA; } @@ -1792,27 +1785,27 @@ static int decode_frame(AVCodecContext * avctx, return AVERROR_INVALIDDATA; } /* update codec info */ - avctx->channels = s->nb_channels; + avctx->channels = s->nb_channels; avctx->channel_layout = s->nb_channels == 1 ? AV_CH_LAYOUT_MONO : AV_CH_LAYOUT_STEREO; if (!avctx->bit_rate) avctx->bit_rate = s->bit_rate; avctx->sub_id = s->layer; - if(*data_size < 1152*avctx->channels*sizeof(OUT_INT)) + if (*data_size < 1152 * avctx->channels * sizeof(OUT_INT)) return AVERROR(EINVAL); *data_size = 0; - if(s->frame_size<=0 || s->frame_size > buf_size){ + if (s->frame_size <= 0 || s->frame_size > buf_size) { av_log(avctx, AV_LOG_ERROR, "incomplete frame\n"); return AVERROR_INVALIDDATA; - }else if(s->frame_size < buf_size){ + } else if (s->frame_size < buf_size) { av_log(avctx, AV_LOG_ERROR, "incorrect frame size\n"); buf_size= s->frame_size; } out_size = mp_decode_frame(s, out_samples, buf, buf_size); - if(out_size>=0){ - *data_size = out_size; + if (out_size >= 0) { + *data_size = out_size; avctx->sample_rate = s->sample_rate; //FIXME maybe move the other codec info stuff from above here too } else { @@ -1828,19 +1821,19 @@ static int decode_frame(AVCodecContext * avctx, return buf_size; } -static void flush(AVCodecContext *avctx){ +static void flush(AVCodecContext *avctx) +{ MPADecodeContext *s = avctx->priv_data; memset(s->synth_buf, 0, sizeof(s->synth_buf)); - s->last_buf_size= 0; + s->last_buf_size = 0; } #if CONFIG_MP3ADU_DECODER || CONFIG_MP3ADUFLOAT_DECODER -static int decode_frame_adu(AVCodecContext * avctx, - void *data, int *data_size, - AVPacket *avpkt) +static int decode_frame_adu(AVCodecContext *avctx, void *data, int *data_size, + AVPacket *avpkt) { - const uint8_t *buf = avpkt->data; - int buf_size = avpkt->size; + const uint8_t *buf = avpkt->data; + int buf_size = avpkt->size; MPADecodeContext *s = avctx->priv_data; uint32_t header; int len, out_size; @@ -1869,18 +1862,17 @@ static int decode_frame_adu(AVCodecContext * avctx, avpriv_mpegaudio_decode_header((MPADecodeHeader *)s, header); /* update codec info */ avctx->sample_rate = s->sample_rate; - avctx->channels = s->nb_channels; + avctx->channels = s->nb_channels; if (!avctx->bit_rate) avctx->bit_rate = s->bit_rate; avctx->sub_id = s->layer; s->frame_size = len; - if (avctx->parse_only) { + if (avctx->parse_only) out_size = buf_size; - } else { + else out_size = mp_decode_frame(s, out_samples, buf, buf_size); - } *data_size = out_size; return buf_size; @@ -1893,9 +1885,9 @@ static int decode_frame_adu(AVCodecContext * avctx, * Context for MP3On4 decoder */ typedef struct MP3On4DecodeContext { - int frames; ///< number of mp3 frames per block (number of mp3 decoder instances) - int syncword; ///< syncword patch - const uint8_t *coff; ///< channels offsets in output buffer + int frames; ///< number of mp3 frames per block (number of mp3 decoder instances) + int syncword; ///< syncword patch + const uint8_t *coff; ///< channel offsets in output buffer MPADecodeContext *mp3decctx[5]; ///< MPADecodeContext for every decoder instance OUT_INT *decoded_buf; ///< output buffer for decoded samples } MP3On4DecodeContext; @@ -1903,17 +1895,20 @@ typedef struct MP3On4DecodeContext { #include "mpeg4audio.h" /* Next 3 arrays are indexed by channel config number (passed via codecdata) */ -static const uint8_t mp3Frames[8] = {0,1,1,2,3,3,4,5}; /* number of mp3 decoder instances */ + +/* number of mp3 decoder instances */ +static const uint8_t mp3Frames[8] = { 0, 1, 1, 2, 3, 3, 4, 5 }; + /* offsets into output buffer, assume output order is FL FR C LFE BL BR SL SR */ static const uint8_t chan_offset[8][5] = { - {0}, - {0}, // C - {0}, // FLR - {2,0}, // C FLR - {2,0,3}, // C FLR BS - {2,0,3}, // C FLR BLRS - {2,0,4,3}, // C FLR BLRS LFE - {2,0,6,4,3}, // C FLR BLRS BLR LFE + { 0 }, + { 0 }, // C + { 0 }, // FLR + { 2, 0 }, // C FLR + { 2, 0, 3 }, // C FLR BS + { 2, 0, 3 }, // C FLR BLRS + { 2, 0, 4, 3 }, // C FLR BLRS LFE + { 2, 0, 6, 4, 3 }, // C FLR BLRS BLR LFE }; /* mp3on4 channel layouts */ @@ -1958,9 +1953,9 @@ static int decode_init_mp3on4(AVCodecContext * avctx) av_log(avctx, AV_LOG_ERROR, "Invalid channel config number.\n"); return AVERROR_INVALIDDATA; } - s->frames = mp3Frames[cfg.chan_config]; - s->coff = chan_offset[cfg.chan_config]; - avctx->channels = ff_mpeg4audio_channels[cfg.chan_config]; + s->frames = mp3Frames[cfg.chan_config]; + s->coff = chan_offset[cfg.chan_config]; + avctx->channels = ff_mpeg4audio_channels[cfg.chan_config]; avctx->channel_layout = chan_layout[cfg.chan_config]; if (cfg.sample_rate < 16000) @@ -2028,8 +2023,8 @@ static int decode_frame_mp3on4(AVCodecContext * avctx, void *data, int *data_size, AVPacket *avpkt) { - const uint8_t *buf = avpkt->data; - int buf_size = avpkt->size; + const uint8_t *buf = avpkt->data; + int buf_size = avpkt->size; MP3On4DecodeContext *s = avctx->priv_data; MPADecodeContext *m; int fsize, len = buf_size, out_size = 0; @@ -2057,8 +2052,8 @@ static int decode_frame_mp3on4(AVCodecContext * avctx, for (fr = 0; fr < s->frames; fr++) { fsize = AV_RB16(buf) >> 4; fsize = FFMIN3(fsize, len, MPA_MAX_CODED_FRAME_SIZE); - m = s->mp3decctx[fr]; - assert (m != NULL); + m = s->mp3decctx[fr]; + assert(m != NULL); header = (AV_RB32(buf) & 0x000fffff) | s->syncword; // patch header @@ -2075,23 +2070,23 @@ static int decode_frame_mp3on4(AVCodecContext * avctx, ch += m->nb_channels; out_size += mp_decode_frame(m, outptr, buf, fsize); - buf += fsize; - len -= fsize; + buf += fsize; + len -= fsize; - if(s->frames > 1) { + if (s->frames > 1) { n = m->avctx->frame_size*m->nb_channels; /* interleave output data */ bp = out_samples + s->coff[fr]; - if(m->nb_channels == 1) { - for(j = 0; j < n; j++) { + if (m->nb_channels == 1) { + for (j = 0; j < n; j++) { *bp = s->decoded_buf[j]; bp += avctx->channels; } } else { - for(j = 0; j < n; j++) { + for (j = 0; j < n; j++) { bp[0] = s->decoded_buf[j++]; bp[1] = s->decoded_buf[j]; - bp += avctx->channels; + bp += avctx->channels; } } } From 512557b291d97ce72dc00e8c1e9a8c1c782fade9 Mon Sep 17 00:00:00 2001 From: Justin Ruggles Date: Tue, 27 Sep 2011 13:54:25 -0400 Subject: [PATCH 05/53] avcodec: remove avcodec_parse_frame and deprecate associated elements. The documentation for CODEC_CAP_PARSE_ONLY and AVCodecContext.parse_only indicates that they are utilized through avcodec_parse_frame(), which was never actually implemented. --- doc/APIchanges | 4 ++++ libavcodec/avcodec.h | 18 +++++++++++------- libavcodec/mpegaudiodec.c | 16 +++++++++++++++- libavcodec/mpegaudiodec_float.c | 8 ++++++++ libavcodec/version.h | 5 ++++- 5 files changed, 42 insertions(+), 9 deletions(-) diff --git a/doc/APIchanges b/doc/APIchanges index bd55cb0172..79aa202ec1 100644 --- a/doc/APIchanges +++ b/doc/APIchanges @@ -13,6 +13,10 @@ libavutil: 2011-04-18 API changes, most recent first: +2011-xx-xx - xxxxxxx - lavc 53.15.0 + Remove avcodec_parse_frame. + Deprecate AVCodecContext.parse_only and CODEC_CAP_PARSE_ONLY. + 2011-10-xx - xxxxxxx - lavf 53.10.0 Add avformat_new_stream(). Deprecate av_new_stream(). diff --git a/libavcodec/avcodec.h b/libavcodec/avcodec.h index 28dde3fe85..1c9bd96a5f 100644 --- a/libavcodec/avcodec.h +++ b/libavcodec/avcodec.h @@ -668,8 +668,10 @@ typedef struct RcOverride{ * assume the buffer was allocated by avcodec_default_get_buffer. */ #define CODEC_CAP_DR1 0x0002 +#if FF_API_PARSE_FRAME /* If 'parse_only' field is true, then avcodec_parse_frame() can be used. */ #define CODEC_CAP_PARSE_ONLY 0x0004 +#endif #define CODEC_CAP_TRUNCATED 0x0008 /* Codec can export data for HW decoding (XvMC). */ #define CODEC_CAP_HWACCEL 0x0010 @@ -1530,9 +1532,15 @@ typedef struct AVCodecContext { */ int block_align; - int parse_only; /* - decoding only: If true, only parsing is done - (function avcodec_parse_frame()). The frame - data is returned. Only MPEG codecs support this now. */ +#if FF_API_PARSE_FRAME + /** + * If true, only parsing is done. The frame data is returned. + * Only MPEG audio decoders support this now. + * - encoding: unused + * - decoding: Set by user + */ + attribute_deprecated int parse_only; +#endif /** * 0-> h263 quant 1-> mpeg quant @@ -3925,10 +3933,6 @@ int avcodec_decode_subtitle2(AVCodecContext *avctx, AVSubtitle *sub, */ void avsubtitle_free(AVSubtitle *sub); -int avcodec_parse_frame(AVCodecContext *avctx, uint8_t **pdata, - int *data_size_ptr, - uint8_t *buf, int buf_size); - /** * Encode an audio frame from samples into buf. * diff --git a/libavcodec/mpegaudiodec.c b/libavcodec/mpegaudiodec.c index 13a3c56447..3aef5fb08d 100644 --- a/libavcodec/mpegaudiodec.c +++ b/libavcodec/mpegaudiodec.c @@ -279,7 +279,11 @@ static av_cold int decode_init(AVCodecContext * avctx) avctx->sample_fmt= OUT_FMT; s->err_recognition = avctx->err_recognition; +#if FF_API_PARSE_FRAME if (!init && !avctx->parse_only) { +#else + if (!init) { +#endif int offset; /* scale factors table for layer 1/2 */ @@ -1869,10 +1873,12 @@ static int decode_frame_adu(AVCodecContext *avctx, void *data, int *data_size, s->frame_size = len; +#if FF_API_PARSE_FRAME if (avctx->parse_only) out_size = buf_size; else - out_size = mp_decode_frame(s, out_samples, buf, buf_size); +#endif + out_size = mp_decode_frame(s, out_samples, buf, buf_size); *data_size = out_size; return buf_size; @@ -2110,7 +2116,9 @@ AVCodec ff_mp1_decoder = { .priv_data_size = sizeof(MPADecodeContext), .init = decode_init, .decode = decode_frame, +#if FF_API_PARSE_FRAME .capabilities = CODEC_CAP_PARSE_ONLY, +#endif .flush = flush, .long_name = NULL_IF_CONFIG_SMALL("MP1 (MPEG audio layer 1)"), }; @@ -2123,7 +2131,9 @@ AVCodec ff_mp2_decoder = { .priv_data_size = sizeof(MPADecodeContext), .init = decode_init, .decode = decode_frame, +#if FF_API_PARSE_FRAME .capabilities = CODEC_CAP_PARSE_ONLY, +#endif .flush = flush, .long_name = NULL_IF_CONFIG_SMALL("MP2 (MPEG audio layer 2)"), }; @@ -2136,7 +2146,9 @@ AVCodec ff_mp3_decoder = { .priv_data_size = sizeof(MPADecodeContext), .init = decode_init, .decode = decode_frame, +#if FF_API_PARSE_FRAME .capabilities = CODEC_CAP_PARSE_ONLY, +#endif .flush = flush, .long_name = NULL_IF_CONFIG_SMALL("MP3 (MPEG audio layer 3)"), }; @@ -2149,7 +2161,9 @@ AVCodec ff_mp3adu_decoder = { .priv_data_size = sizeof(MPADecodeContext), .init = decode_init, .decode = decode_frame_adu, +#if FF_API_PARSE_FRAME .capabilities = CODEC_CAP_PARSE_ONLY, +#endif .flush = flush, .long_name = NULL_IF_CONFIG_SMALL("ADU (Application Data Unit) MP3 (MPEG audio layer 3)"), }; diff --git a/libavcodec/mpegaudiodec_float.c b/libavcodec/mpegaudiodec_float.c index 7f512500b3..9300de29b9 100644 --- a/libavcodec/mpegaudiodec_float.c +++ b/libavcodec/mpegaudiodec_float.c @@ -30,7 +30,9 @@ AVCodec ff_mp1float_decoder = { .priv_data_size = sizeof(MPADecodeContext), .init = decode_init, .decode = decode_frame, +#if FF_API_PARSE_FRAME .capabilities = CODEC_CAP_PARSE_ONLY, +#endif .flush = flush, .long_name = NULL_IF_CONFIG_SMALL("MP1 (MPEG audio layer 1)"), }; @@ -43,7 +45,9 @@ AVCodec ff_mp2float_decoder = { .priv_data_size = sizeof(MPADecodeContext), .init = decode_init, .decode = decode_frame, +#if FF_API_PARSE_FRAME .capabilities = CODEC_CAP_PARSE_ONLY, +#endif .flush = flush, .long_name = NULL_IF_CONFIG_SMALL("MP2 (MPEG audio layer 2)"), }; @@ -56,7 +60,9 @@ AVCodec ff_mp3float_decoder = { .priv_data_size = sizeof(MPADecodeContext), .init = decode_init, .decode = decode_frame, +#if FF_API_PARSE_FRAME .capabilities = CODEC_CAP_PARSE_ONLY, +#endif .flush = flush, .long_name = NULL_IF_CONFIG_SMALL("MP3 (MPEG audio layer 3)"), }; @@ -69,7 +75,9 @@ AVCodec ff_mp3adufloat_decoder = { .priv_data_size = sizeof(MPADecodeContext), .init = decode_init, .decode = decode_frame_adu, +#if FF_API_PARSE_FRAME .capabilities = CODEC_CAP_PARSE_ONLY, +#endif .flush = flush, .long_name = NULL_IF_CONFIG_SMALL("ADU (Application Data Unit) MP3 (MPEG audio layer 3)"), }; diff --git a/libavcodec/version.h b/libavcodec/version.h index a361bbdf8c..65cc5594cc 100644 --- a/libavcodec/version.h +++ b/libavcodec/version.h @@ -21,7 +21,7 @@ #define AVCODEC_VERSION_H #define LIBAVCODEC_VERSION_MAJOR 53 -#define LIBAVCODEC_VERSION_MINOR 14 +#define LIBAVCODEC_VERSION_MINOR 15 #define LIBAVCODEC_VERSION_MICRO 0 #define LIBAVCODEC_VERSION_INT AV_VERSION_INT(LIBAVCODEC_VERSION_MAJOR, \ @@ -101,5 +101,8 @@ #ifndef FF_API_GET_ALPHA_INFO #define FF_API_GET_ALPHA_INFO (LIBAVCODEC_VERSION_MAJOR < 54) #endif +#ifndef FF_API_PARSE_FRAME +#define FF_API_PARSE_FRAME (LIBAVCODEC_VERSION_MAJOR < 54) +#endif #endif /* AVCODEC_VERSION_H */ From e2e6c8799b3c4a61b8be36c84c5e5e15c49a31cd Mon Sep 17 00:00:00 2001 From: Justin Ruggles Date: Tue, 27 Sep 2011 14:27:43 -0400 Subject: [PATCH 06/53] mpegaudiodec: check output data size based on avctx->frame_size --- libavcodec/mpegaudiodec.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/libavcodec/mpegaudiodec.c b/libavcodec/mpegaudiodec.c index 3aef5fb08d..58e2bf7c38 100644 --- a/libavcodec/mpegaudiodec.c +++ b/libavcodec/mpegaudiodec.c @@ -1795,7 +1795,7 @@ static int decode_frame(AVCodecContext * avctx, void *data, int *data_size, avctx->bit_rate = s->bit_rate; avctx->sub_id = s->layer; - if (*data_size < 1152 * avctx->channels * sizeof(OUT_INT)) + if (*data_size < avctx->frame_size * avctx->channels * sizeof(OUT_INT)) return AVERROR(EINVAL); *data_size = 0; @@ -1871,6 +1871,9 @@ static int decode_frame_adu(AVCodecContext *avctx, void *data, int *data_size, avctx->bit_rate = s->bit_rate; avctx->sub_id = s->layer; + if (*data_size < avctx->frame_size * avctx->channels * sizeof(OUT_INT)) + return AVERROR(EINVAL); + s->frame_size = len; #if FF_API_PARSE_FRAME From 99975966c319f8995f20c8db56a5cf77cfeb69ee Mon Sep 17 00:00:00 2001 From: Justin Ruggles Date: Tue, 25 Oct 2011 12:45:39 -0400 Subject: [PATCH 07/53] mp3adu: return error instead of just consuming bad packets --- libavcodec/mpegaudiodec.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/libavcodec/mpegaudiodec.c b/libavcodec/mpegaudiodec.c index 58e2bf7c38..2751df6213 100644 --- a/libavcodec/mpegaudiodec.c +++ b/libavcodec/mpegaudiodec.c @@ -1847,8 +1847,8 @@ static int decode_frame_adu(AVCodecContext *avctx, void *data, int *data_size, // Discard too short frames if (buf_size < HEADER_SIZE) { - *data_size = 0; - return buf_size; + av_log(avctx, AV_LOG_ERROR, "Packet is too small\n"); + return AVERROR_INVALIDDATA; } @@ -1859,8 +1859,8 @@ static int decode_frame_adu(AVCodecContext *avctx, void *data, int *data_size, header = AV_RB32(buf) | 0xffe00000; if (ff_mpa_check_header(header) < 0) { // Bad header, discard frame - *data_size = 0; - return buf_size; + av_log(avctx, AV_LOG_ERROR, "Invalid frame header\n"); + return AVERROR_INVALIDDATA; } avpriv_mpegaudio_decode_header((MPADecodeHeader *)s, header); From ec6d743118282bbbc652372a7af44c6ec6f8048e Mon Sep 17 00:00:00 2001 From: Justin Ruggles Date: Tue, 25 Oct 2011 12:46:57 -0400 Subject: [PATCH 08/53] mp3on4: do not needlessly set data_size to 0 --- libavcodec/mpegaudiodec.c | 1 - 1 file changed, 1 deletion(-) diff --git a/libavcodec/mpegaudiodec.c b/libavcodec/mpegaudiodec.c index 2751df6213..d5af782ac7 100644 --- a/libavcodec/mpegaudiodec.c +++ b/libavcodec/mpegaudiodec.c @@ -2047,7 +2047,6 @@ static int decode_frame_mp3on4(AVCodecContext * avctx, return AVERROR(EINVAL); } - *data_size = 0; // Discard too short frames if (buf_size < HEADER_SIZE) return AVERROR_INVALIDDATA; From a2faa9515167bf1537abdc4fa9caa88934171cdd Mon Sep 17 00:00:00 2001 From: Anton Khirnov Date: Sun, 16 Oct 2011 15:03:30 +0200 Subject: [PATCH 09/53] lavf: make some seeking functions private Specifically av_update_cur_dts(), av_seek_frame_binary() and av_gen_search(). They are not supposed to be called outside lavf. --- libavformat/asfdec.c | 2 +- libavformat/avformat.h | 30 +++++--------------------- libavformat/internal.h | 33 ++++++++++++++++++++++++++++ libavformat/matroskadec.c | 2 +- libavformat/mpegts.c | 4 ++-- libavformat/mxfdec.c | 3 ++- libavformat/nutdec.c | 8 +++---- libavformat/oggdec.c | 3 ++- libavformat/utils.c | 45 +++++++++++++++++++++++++++++++++------ libavformat/version.h | 3 +++ 10 files changed, 91 insertions(+), 42 deletions(-) diff --git a/libavformat/asfdec.c b/libavformat/asfdec.c index 88091a5c9e..ed06e8a897 100644 --- a/libavformat/asfdec.c +++ b/libavformat/asfdec.c @@ -1282,7 +1282,7 @@ static int asf_read_seek(AVFormatContext *s, int stream_index, int64_t pts, int } } /* no index or seeking by index failed */ - if(av_seek_frame_binary(s, stream_index, pts, flags)<0) + if (ff_seek_frame_binary(s, stream_index, pts, flags) < 0) return -1; asf_reset_header(s); return 0; diff --git a/libavformat/avformat.h b/libavformat/avformat.h index 1b67ee6bc2..d9d45a52d6 100644 --- a/libavformat/avformat.h +++ b/libavformat/avformat.h @@ -1388,40 +1388,20 @@ int av_index_search_timestamp(AVStream *st, int64_t timestamp, int flags); int av_add_index_entry(AVStream *st, int64_t pos, int64_t timestamp, int size, int distance, int flags); -/** - * Perform a binary search using av_index_search_timestamp() and - * AVInputFormat.read_timestamp(). - * This is not supposed to be called directly by a user application, - * but by demuxers. - * @param target_ts target timestamp in the time base of the given stream - * @param stream_index stream number - */ +#if FF_API_SEEK_PUBLIC +attribute_deprecated int av_seek_frame_binary(AVFormatContext *s, int stream_index, int64_t target_ts, int flags); - -/** - * Update cur_dts of all streams based on the given timestamp and AVStream. - * - * Stream ref_st unchanged, others set cur_dts in their native time base. - * Only needed for timestamp wrapping or if (dts not set and pts!=dts). - * @param timestamp new dts expressed in time_base of param ref_st - * @param ref_st reference stream giving time_base of param timestamp - */ +attribute_deprecated void av_update_cur_dts(AVFormatContext *s, AVStream *ref_st, int64_t timestamp); - -/** - * Perform a binary search using read_timestamp(). - * This is not supposed to be called directly by a user application, - * but by demuxers. - * @param target_ts target timestamp in the time base of the given stream - * @param stream_index stream number - */ +attribute_deprecated int64_t av_gen_search(AVFormatContext *s, int stream_index, int64_t target_ts, int64_t pos_min, int64_t pos_max, int64_t pos_limit, int64_t ts_min, int64_t ts_max, int flags, int64_t *ts_ret, int64_t (*read_timestamp)(struct AVFormatContext *, int , int64_t *, int64_t )); +#endif /** * media file output diff --git a/libavformat/internal.h b/libavformat/internal.h index 9ef9d64051..0d8bbe7d96 100644 --- a/libavformat/internal.h +++ b/libavformat/internal.h @@ -253,4 +253,37 @@ enum CodecID ff_guess_image2_codec(const char *filename); */ int64_t ff_iso8601_to_unix_time(const char *datestr); +/** + * Perform a binary search using av_index_search_timestamp() and + * AVInputFormat.read_timestamp(). + * + * @param target_ts target timestamp in the time base of the given stream + * @param stream_index stream number + */ +int ff_seek_frame_binary(AVFormatContext *s, int stream_index, + int64_t target_ts, int flags); + +/** + * Update cur_dts of all streams based on the given timestamp and AVStream. + * + * Stream ref_st unchanged, others set cur_dts in their native time base. + * Only needed for timestamp wrapping or if (dts not set and pts!=dts). + * @param timestamp new dts expressed in time_base of param ref_st + * @param ref_st reference stream giving time_base of param timestamp + */ +void ff_update_cur_dts(AVFormatContext *s, AVStream *ref_st, int64_t timestamp); + +/** + * Perform a binary search using read_timestamp(). + * + * @param target_ts target timestamp in the time base of the given stream + * @param stream_index stream number + */ +int64_t ff_gen_search(AVFormatContext *s, int stream_index, + int64_t target_ts, int64_t pos_min, + int64_t pos_max, int64_t pos_limit, + int64_t ts_min, int64_t ts_max, + int flags, int64_t *ts_ret, + int64_t (*read_timestamp)(struct AVFormatContext *, int , int64_t *, int64_t )); + #endif /* AVFORMAT_INTERNAL_H */ diff --git a/libavformat/matroskadec.c b/libavformat/matroskadec.c index 8ee3698ac4..3f48a72c8e 100644 --- a/libavformat/matroskadec.c +++ b/libavformat/matroskadec.c @@ -2002,7 +2002,7 @@ static int matroska_read_seek(AVFormatContext *s, int stream_index, matroska->skip_to_keyframe = !(flags & AVSEEK_FLAG_ANY); matroska->skip_to_timecode = st->index_entries[index].timestamp; matroska->done = 0; - av_update_cur_dts(s, st, st->index_entries[index].timestamp); + ff_update_cur_dts(s, st, st->index_entries[index].timestamp); return 0; } diff --git a/libavformat/mpegts.c b/libavformat/mpegts.c index b7814e59c9..5668f546f6 100644 --- a/libavformat/mpegts.c +++ b/libavformat/mpegts.c @@ -1768,7 +1768,7 @@ static int read_seek2(AVFormatContext *s, ts_adj = target_ts; stream_index_gen_search = stream_index; } - pos = av_gen_search(s, stream_index_gen_search, ts_adj, + pos = ff_gen_search(s, stream_index_gen_search, ts_adj, 0, INT64_MAX, -1, AV_NOPTS_VALUE, AV_NOPTS_VALUE, @@ -1816,7 +1816,7 @@ static int read_seek(AVFormatContext *s, int stream_index, int64_t target_ts, in uint8_t buf[TS_PACKET_SIZE]; int64_t pos; - if(av_seek_frame_binary(s, stream_index, target_ts, flags) < 0) + if (ff_seek_frame_binary(s, stream_index, target_ts, flags) < 0) return -1; pos= avio_tell(s->pb); diff --git a/libavformat/mxfdec.c b/libavformat/mxfdec.c index 76a8329766..c0386583bd 100644 --- a/libavformat/mxfdec.c +++ b/libavformat/mxfdec.c @@ -49,6 +49,7 @@ #include "libavutil/mathematics.h" #include "libavcodec/bytestream.h" #include "avformat.h" +#include "internal.h" #include "mxf.h" typedef struct { @@ -1020,7 +1021,7 @@ static int mxf_read_seek(AVFormatContext *s, int stream_index, int64_t sample_ti sample_time = 0; seconds = av_rescale(sample_time, st->time_base.num, st->time_base.den); avio_seek(s->pb, (s->bit_rate * seconds) >> 3, SEEK_SET); - av_update_cur_dts(s, st, sample_time); + ff_update_cur_dts(s, st, sample_time); return 0; } diff --git a/libavformat/nutdec.c b/libavformat/nutdec.c index fb5ccf7fa9..8903424b09 100644 --- a/libavformat/nutdec.c +++ b/libavformat/nutdec.c @@ -874,16 +874,16 @@ static int read_seek(AVFormatContext *s, int stream_index, int64_t pts, int flag (void **) next_node); av_log(s, AV_LOG_DEBUG, "%"PRIu64"-%"PRIu64" %"PRId64"-%"PRId64"\n", next_node[0]->pos, next_node[1]->pos, next_node[0]->ts , next_node[1]->ts); - pos= av_gen_search(s, -1, dummy.ts, next_node[0]->pos, next_node[1]->pos, next_node[1]->pos, - next_node[0]->ts , next_node[1]->ts, AVSEEK_FLAG_BACKWARD, &ts, nut_read_timestamp); + pos = ff_gen_search(s, -1, dummy.ts, next_node[0]->pos, next_node[1]->pos, next_node[1]->pos, + next_node[0]->ts , next_node[1]->ts, AVSEEK_FLAG_BACKWARD, &ts, nut_read_timestamp); if(!(flags & AVSEEK_FLAG_BACKWARD)){ dummy.pos= pos+16; next_node[1]= &nopts_sp; av_tree_find(nut->syncpoints, &dummy, (void *) ff_nut_sp_pos_cmp, (void **) next_node); - pos2= av_gen_search(s, -2, dummy.pos, next_node[0]->pos , next_node[1]->pos, next_node[1]->pos, - next_node[0]->back_ptr, next_node[1]->back_ptr, flags, &ts, nut_read_timestamp); + pos2 = ff_gen_search(s, -2, dummy.pos, next_node[0]->pos , next_node[1]->pos, next_node[1]->pos, + next_node[0]->back_ptr, next_node[1]->back_ptr, flags, &ts, nut_read_timestamp); if(pos2>=0) pos= pos2; //FIXME dir but I think it does not matter diff --git a/libavformat/oggdec.c b/libavformat/oggdec.c index 7fd50a5590..f7513cffd2 100644 --- a/libavformat/oggdec.c +++ b/libavformat/oggdec.c @@ -33,6 +33,7 @@ #include #include "oggdec.h" #include "avformat.h" +#include "internal.h" #include "vorbiscomment.h" #define MAX_PAGE_SIZE 65307 @@ -637,7 +638,7 @@ static int ogg_read_seek(AVFormatContext *s, int stream_index, && !(flags & AVSEEK_FLAG_ANY)) os->keyframe_seek = 1; - ret = av_seek_frame_binary(s, stream_index, timestamp, flags); + ret = ff_seek_frame_binary(s, stream_index, timestamp, flags); os = ogg->streams + stream_index; if (ret < 0) os->keyframe_seek = 0; diff --git a/libavformat/utils.c b/libavformat/utils.c index 640fa70c3d..637d615d90 100644 --- a/libavformat/utils.c +++ b/libavformat/utils.c @@ -1374,7 +1374,15 @@ void ff_read_frame_flush(AVFormatContext *s) } } -void av_update_cur_dts(AVFormatContext *s, AVStream *ref_st, int64_t timestamp){ +#if FF_API_SEEK_PUBLIC +void av_update_cur_dts(AVFormatContext *s, AVStream *ref_st, int64_t timestamp) +{ + return ff_update_cur_dts(s, ref_st, timestamp); +} +#endif + +void ff_update_cur_dts(AVFormatContext *s, AVStream *ref_st, int64_t timestamp) +{ int i; for(i = 0; i < s->nb_streams; i++) { @@ -1494,7 +1502,14 @@ int av_index_search_timestamp(AVStream *st, int64_t wanted_timestamp, wanted_timestamp, flags); } +#if FF_API_SEEK_PUBLIC int av_seek_frame_binary(AVFormatContext *s, int stream_index, int64_t target_ts, int flags){ + return ff_seek_frame_binary(s, stream_index, target_ts, flags); +} +#endif + +int ff_seek_frame_binary(AVFormatContext *s, int stream_index, int64_t target_ts, int flags) +{ AVInputFormat *avif= s->iformat; int64_t av_uninit(pos_min), av_uninit(pos_max), pos, pos_limit; int64_t ts_min, ts_max, ts; @@ -1541,7 +1556,7 @@ int av_seek_frame_binary(AVFormatContext *s, int stream_index, int64_t target_ts } } - pos= av_gen_search(s, stream_index, target_ts, pos_min, pos_max, pos_limit, ts_min, ts_max, flags, &ts, avif->read_timestamp); + pos= ff_gen_search(s, stream_index, target_ts, pos_min, pos_max, pos_limit, ts_min, ts_max, flags, &ts, avif->read_timestamp); if(pos<0) return -1; @@ -1549,12 +1564,28 @@ int av_seek_frame_binary(AVFormatContext *s, int stream_index, int64_t target_ts if ((ret = avio_seek(s->pb, pos, SEEK_SET)) < 0) return ret; - av_update_cur_dts(s, st, ts); + ff_update_cur_dts(s, st, ts); return 0; } -int64_t av_gen_search(AVFormatContext *s, int stream_index, int64_t target_ts, int64_t pos_min, int64_t pos_max, int64_t pos_limit, int64_t ts_min, int64_t ts_max, int flags, int64_t *ts_ret, int64_t (*read_timestamp)(struct AVFormatContext *, int , int64_t *, int64_t )){ +#if FF_API_SEEK_PUBLIC +int64_t av_gen_search(AVFormatContext *s, int stream_index, int64_t target_ts, + int64_t pos_min, int64_t pos_max, int64_t pos_limit, + int64_t ts_min, int64_t ts_max, int flags, int64_t *ts_ret, + int64_t (*read_timestamp)(struct AVFormatContext *, int , int64_t *, int64_t )) +{ + return ff_gen_search(s, stream_index, target_ts, pos_min, pos_max, + pos_limit, ts_min, ts_max, flags, ts_ret, + read_timestamp); +} +#endif + +int64_t ff_gen_search(AVFormatContext *s, int stream_index, int64_t target_ts, + int64_t pos_min, int64_t pos_max, int64_t pos_limit, + int64_t ts_min, int64_t ts_max, int flags, int64_t *ts_ret, + int64_t (*read_timestamp)(struct AVFormatContext *, int , int64_t *, int64_t )) +{ int64_t pos, ts; int64_t start_pos, filesize; int no_change; @@ -1708,7 +1739,7 @@ static int seek_frame_generic(AVFormatContext *s, ie= &st->index_entries[st->nb_index_entries-1]; if ((ret = avio_seek(s->pb, ie->pos, SEEK_SET)) < 0) return ret; - av_update_cur_dts(s, st, ie->timestamp); + ff_update_cur_dts(s, st, ie->timestamp); }else{ if ((ret = avio_seek(s->pb, s->data_offset, SEEK_SET)) < 0) return ret; @@ -1739,7 +1770,7 @@ static int seek_frame_generic(AVFormatContext *s, ie = &st->index_entries[index]; if ((ret = avio_seek(s->pb, ie->pos, SEEK_SET)) < 0) return ret; - av_update_cur_dts(s, st, ie->timestamp); + ff_update_cur_dts(s, st, ie->timestamp); return 0; } @@ -1778,7 +1809,7 @@ int av_seek_frame(AVFormatContext *s, int stream_index, int64_t timestamp, int f if (s->iformat->read_timestamp && !(s->iformat->flags & AVFMT_NOBINSEARCH)) { ff_read_frame_flush(s); - return av_seek_frame_binary(s, stream_index, timestamp, flags); + return ff_seek_frame_binary(s, stream_index, timestamp, flags); } else if (!(s->iformat->flags & AVFMT_NOGENSEARCH)) { ff_read_frame_flush(s); return seek_frame_generic(s, stream_index, timestamp, flags); diff --git a/libavformat/version.h b/libavformat/version.h index 6041daebd6..99a2017d7a 100644 --- a/libavformat/version.h +++ b/libavformat/version.h @@ -104,5 +104,8 @@ #ifndef FF_API_STREAM_COPY #define FF_API_STREAM_COPY (LIBAVFORMAT_VERSION_MAJOR < 54) #endif +#ifndef FF_API_SEEK_PUBLIC +#define FF_API_SEEK_PUBLIC (LIBAVFORMAT_VERSION_MAJOR < 54) +#endif #endif /* AVFORMAT_VERSION_H */ From df968050abc94f219d293056ce93ee9e464f2f75 Mon Sep 17 00:00:00 2001 From: Anton Khirnov Date: Wed, 19 Oct 2011 20:00:09 +0200 Subject: [PATCH 10/53] lavf: move private fields in AVFormatContext to the end at next bump. --- libavformat/avformat.h | 45 ++++++++++++++++++++++++++++++++++++++++++ libavformat/version.h | 3 +++ 2 files changed, 48 insertions(+) diff --git a/libavformat/avformat.h b/libavformat/avformat.h index d9d45a52d6..f20eabe810 100644 --- a/libavformat/avformat.h +++ b/libavformat/avformat.h @@ -695,6 +695,7 @@ typedef struct AVFormatContext { #endif int ctx_flags; /**< Format-specific flags, see AVFMTCTX_xx */ +#if FF_API_REORDER_PRIVATE /* private data for pts handling (do not modify directly). */ /** * This buffer is only needed when packets were already buffered but @@ -702,6 +703,7 @@ typedef struct AVFormatContext { * streams. */ struct AVPacketList *packet_buffer; +#endif /** * Decoding: position of the first frame of the component, in @@ -732,11 +734,13 @@ typedef struct AVFormatContext { */ int bit_rate; +#if FF_API_REORDER_PRIVATE /* av_read_frame() support */ AVStream *cur_st; /* av_seek_frame() support */ int64_t data_offset; /**< offset of the first packet */ +#endif #if FF_API_MUXRATE /** @@ -843,6 +847,7 @@ typedef struct AVFormatContext { int debug; #define FF_FDEBUG_TS 0x0001 +#if FF_API_REORDER_PRIVATE /** * Raw packets from the demuxer, prior to parsing and decoding. * This buffer is used for buffering packets until the codec can @@ -853,15 +858,18 @@ typedef struct AVFormatContext { struct AVPacketList *raw_packet_buffer_end; struct AVPacketList *packet_buffer_end; +#endif AVDictionary *metadata; +#if FF_API_REORDER_PRIVATE /** * Remaining size available for raw_packet_buffer, in bytes. * NOT PART OF PUBLIC API */ #define RAW_PACKET_BUFFER_SIZE 2500000 int raw_packet_buffer_remaining_size; +#endif /** * Start time of the stream in real world time, in microseconds @@ -884,6 +892,43 @@ typedef struct AVFormatContext { * - decoding: Set by user. */ int error_recognition; + + /***************************************************************** + * All fields below this line are not part of the public API. They + * may not be used outside of libavformat and can be changed and + * removed at will. + * New public fields should be added right above. + ***************************************************************** + */ +#if !FF_API_REORDER_PRIVATE + /** + * Raw packets from the demuxer, prior to parsing and decoding. + * This buffer is used for buffering packets until the codec can + * be identified, as parsing cannot be done without knowing the + * codec. + */ + struct AVPacketList *raw_packet_buffer; + struct AVPacketList *raw_packet_buffer_end; + /** + * Remaining size available for raw_packet_buffer, in bytes. + */ +#define RAW_PACKET_BUFFER_SIZE 2500000 + int raw_packet_buffer_remaining_size; + + /** + * This buffer is only needed when packets were already buffered but + * not decoded, for example to get the codec parameters in MPEG + * streams. + */ + struct AVPacketList *packet_buffer; + struct AVPacketList *packet_buffer_end; + + /* av_read_frame() support */ + AVStream *cur_st; + + /* av_seek_frame() support */ + int64_t data_offset; /**< offset of the first packet */ +#endif } AVFormatContext; typedef struct AVPacketList { diff --git a/libavformat/version.h b/libavformat/version.h index 99a2017d7a..b0c1f9481e 100644 --- a/libavformat/version.h +++ b/libavformat/version.h @@ -107,5 +107,8 @@ #ifndef FF_API_SEEK_PUBLIC #define FF_API_SEEK_PUBLIC (LIBAVFORMAT_VERSION_MAJOR < 54) #endif +#ifndef FF_API_REORDER_PRIVATE +#define FF_API_REORDER_PRIVATE (LIBAVFORMAT_VERSION_MAJOR < 54) +#endif #endif /* AVFORMAT_VERSION_H */ From 9a174562e4622d7f3dcb89422fd92390cb336daa Mon Sep 17 00:00:00 2001 From: Anton Khirnov Date: Wed, 19 Oct 2011 20:00:09 +0200 Subject: [PATCH 11/53] lavf: move private fields in AVStream to the end at next bump. --- libavformat/avformat.h | 61 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 61 insertions(+) diff --git a/libavformat/avformat.h b/libavformat/avformat.h index f20eabe810..d16be90c8f 100644 --- a/libavformat/avformat.h +++ b/libavformat/avformat.h @@ -513,8 +513,10 @@ typedef struct AVStream { AVRational r_frame_rate; void *priv_data; +#if FF_API_REORDER_PRIVATE /* internal data used in av_find_stream_info() */ int64_t first_dts; +#endif /** * encoding: pts generation when outputting stream @@ -529,7 +531,9 @@ typedef struct AVStream { * encoding: set by libavformat in av_write_header */ AVRational time_base; +#if FF_API_REORDER_PRIVATE int pts_wrap_bits; /**< number of bits in pts (used for wrapping control) */ +#endif #if FF_API_STREAM_COPY /* ffmpeg.c private use */ attribute_deprecated int stream_copy; /**< If set, just copy stream. */ @@ -560,6 +564,7 @@ typedef struct AVStream { */ int64_t duration; +#if FF_API_REORDER_PRIVATE /* av_read_frame() support */ enum AVStreamParseType need_parsing; struct AVCodecParserContext *parser; @@ -572,14 +577,17 @@ typedef struct AVStream { support seeking natively. */ int nb_index_entries; unsigned int index_entries_allocated_size; +#endif int64_t nb_frames; ///< number of frames in this stream if known or 0 int disposition; /**< AV_DISPOSITION_* bit field */ +#if FF_API_REORDER_PRIVATE AVProbeData probe_data; #define MAX_REORDER_DELAY 16 int64_t pts_buffer[MAX_REORDER_DELAY+1]; +#endif /** * sample aspect ratio (0 if unknown) @@ -590,6 +598,7 @@ typedef struct AVStream { AVDictionary *metadata; +#if FF_API_REORDER_PRIVATE /* Intended mostly for av_read_frame() support. Not supposed to be used by */ /* external applications; try to use something else if at all possible. */ const uint8_t *cur_ptr; @@ -618,12 +627,21 @@ typedef struct AVStream { * used internally, NOT PART OF PUBLIC API, dont read or write from outside of libav* */ struct AVPacketList *last_in_packet_buffer; +#endif /** * Average framerate */ AVRational avg_frame_rate; + /***************************************************************** + * All fields below this line are not part of the public API. They + * may not be used outside of libavformat and can be changed and + * removed at will. + * New public fields should be added right above. + ***************************************************************** + */ + /** * Number of frames that have been demuxed during av_find_stream_info() */ @@ -640,6 +658,49 @@ typedef struct AVStream { double duration_error[MAX_STD_TIMEBASES]; int64_t codec_info_duration; } *info; +#if !FF_API_REORDER_PRIVATE + const uint8_t *cur_ptr; + int cur_len; + AVPacket cur_pkt; + + // Timestamp generation support: + /** + * Timestamp corresponding to the last dts sync point. + * + * Initialized when AVCodecParserContext.dts_sync_point >= 0 and + * a DTS is received from the underlying container. Otherwise set to + * AV_NOPTS_VALUE by default. + */ + int64_t reference_dts; + int64_t first_dts; + int64_t cur_dts; + int last_IP_duration; + int64_t last_IP_pts; + + /** + * Number of packets to buffer for codec probing + */ +#define MAX_PROBE_PACKETS 2500 + int probe_packets; + + /** + * last packet in packet_buffer for this stream when muxing. + */ + struct AVPacketList *last_in_packet_buffer; + AVProbeData probe_data; +#define MAX_REORDER_DELAY 16 + int64_t pts_buffer[MAX_REORDER_DELAY+1]; + /* av_read_frame() support */ + enum AVStreamParseType need_parsing; + struct AVCodecParserContext *parser; + + AVIndexEntry *index_entries; /**< Only used if the format does not + support seeking natively. */ + int nb_index_entries; + unsigned int index_entries_allocated_size; + + int pts_wrap_bits; /**< number of bits in pts (used for wrapping control) */ +#endif } AVStream; #define AV_PROGRAM_RUNNING 1 From 3c25209bd9ee83eeb0373dcf790eb116e986f8e1 Mon Sep 17 00:00:00 2001 From: Justin Ruggles Date: Mon, 10 Oct 2011 15:54:36 -0400 Subject: [PATCH 12/53] apedec: remove unneeded check for zero-size packet. This is already checked by avcodec_decode_audio3(). --- libavcodec/apedec.c | 5 ----- 1 file changed, 5 deletions(-) diff --git a/libavcodec/apedec.c b/libavcodec/apedec.c index a8ca44b9f7..bc77148d88 100644 --- a/libavcodec/apedec.c +++ b/libavcodec/apedec.c @@ -802,11 +802,6 @@ static int ape_decode_frame(AVCodecContext * avctx, int blockstodecode; int bytes_used; - if (buf_size == 0 && !s->samples) { - *data_size = 0; - return 0; - } - /* should not happen but who knows */ if (BLOCKS_PER_LOOP * 2 * avctx->channels > *data_size) { av_log (avctx, AV_LOG_ERROR, "Packet size is too big to be handled in lavc! (max is %d where you have %d)\n", *data_size, s->samples * 2 * avctx->channels); From b9d6b02713f8da3d4280ba24e8a8d28b309e5308 Mon Sep 17 00:00:00 2001 From: Justin Ruggles Date: Tue, 11 Oct 2011 11:37:55 -0400 Subject: [PATCH 13/53] apedec: use memcpy for pseudo-stereo mode --- libavcodec/apedec.c | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/libavcodec/apedec.c b/libavcodec/apedec.c index bc77148d88..b9ef2f4db8 100644 --- a/libavcodec/apedec.c +++ b/libavcodec/apedec.c @@ -735,7 +735,6 @@ static void init_frame_decoder(APEContext * ctx) static void ape_unpack_mono(APEContext * ctx, int count) { - int32_t left; int32_t *decoded0 = ctx->decoded0; int32_t *decoded1 = ctx->decoded1; @@ -754,10 +753,7 @@ static void ape_unpack_mono(APEContext * ctx, int count) /* Pseudo-stereo - just copy left channel to right channel */ if (ctx->channels == 2) { - while (count--) { - left = *decoded0; - *(decoded1++) = *(decoded0++) = left; - } + memcpy(decoded1, decoded0, count * sizeof(*decoded1)); } } From 7500781313d11b37772c05a28da20fbc112db478 Mon Sep 17 00:00:00 2001 From: Justin Ruggles Date: Tue, 11 Oct 2011 11:47:15 -0400 Subject: [PATCH 14/53] apedec: check for filter buffer allocation failure --- libavcodec/apedec.c | 31 ++++++++++++++++++------------- 1 file changed, 18 insertions(+), 13 deletions(-) diff --git a/libavcodec/apedec.c b/libavcodec/apedec.c index b9ef2f4db8..031dee44de 100644 --- a/libavcodec/apedec.c +++ b/libavcodec/apedec.c @@ -163,6 +163,18 @@ typedef struct APEContext { // TODO: dsputilize +static av_cold int ape_decode_close(AVCodecContext * avctx) +{ + APEContext *s = avctx->priv_data; + int i; + + for (i = 0; i < APE_FILTER_LEVELS; i++) + av_freep(&s->filterbuf[i]); + + av_freep(&s->data); + return 0; +} + static av_cold int ape_decode_init(AVCodecContext * avctx) { APEContext *s = avctx->priv_data; @@ -195,25 +207,18 @@ static av_cold int ape_decode_init(AVCodecContext * avctx) for (i = 0; i < APE_FILTER_LEVELS; i++) { if (!ape_filter_orders[s->fset][i]) break; - s->filterbuf[i] = av_malloc((ape_filter_orders[s->fset][i] * 3 + HISTORY_SIZE) * 4); + FF_ALLOC_OR_GOTO(avctx, s->filterbuf[i], + (ape_filter_orders[s->fset][i] * 3 + HISTORY_SIZE) * 4, + filter_alloc_fail); } dsputil_init(&s->dsp, avctx); avctx->sample_fmt = AV_SAMPLE_FMT_S16; avctx->channel_layout = (avctx->channels==2) ? AV_CH_LAYOUT_STEREO : AV_CH_LAYOUT_MONO; return 0; -} - -static av_cold int ape_decode_close(AVCodecContext * avctx) -{ - APEContext *s = avctx->priv_data; - int i; - - for (i = 0; i < APE_FILTER_LEVELS; i++) - av_freep(&s->filterbuf[i]); - - av_freep(&s->data); - return 0; +filter_alloc_fail: + ape_decode_close(avctx); + return AVERROR(ENOMEM); } /** From f64e0a2f379c1297dc9b1744999e29ab84646261 Mon Sep 17 00:00:00 2001 From: Justin Ruggles Date: Tue, 11 Oct 2011 11:48:39 -0400 Subject: [PATCH 15/53] apedec: return meaningful error codes from ape_decode_init() --- libavcodec/apedec.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/libavcodec/apedec.c b/libavcodec/apedec.c index 031dee44de..847b4ad27c 100644 --- a/libavcodec/apedec.c +++ b/libavcodec/apedec.c @@ -182,15 +182,15 @@ static av_cold int ape_decode_init(AVCodecContext * avctx) if (avctx->extradata_size != 6) { av_log(avctx, AV_LOG_ERROR, "Incorrect extradata\n"); - return -1; + return AVERROR(EINVAL); } if (avctx->bits_per_coded_sample != 16) { av_log(avctx, AV_LOG_ERROR, "Only 16-bit samples are supported\n"); - return -1; + return AVERROR(EINVAL); } if (avctx->channels > 2) { av_log(avctx, AV_LOG_ERROR, "Only mono and stereo is supported\n"); - return -1; + return AVERROR(EINVAL); } s->avctx = avctx; s->channels = avctx->channels; @@ -201,7 +201,7 @@ static av_cold int ape_decode_init(AVCodecContext * avctx) av_log(avctx, AV_LOG_DEBUG, "Compression Level: %d - Flags: %d\n", s->compression_level, s->flags); if (s->compression_level % 1000 || s->compression_level > COMPRESSION_LEVEL_INSANE) { av_log(avctx, AV_LOG_ERROR, "Incorrect compression level %d\n", s->compression_level); - return -1; + return AVERROR_INVALIDDATA; } s->fset = s->compression_level / 1000 - 1; for (i = 0; i < APE_FILTER_LEVELS; i++) { From da55e0980ec1851b81ffff3e9dfaf20e295459af Mon Sep 17 00:00:00 2001 From: Justin Ruggles Date: Tue, 11 Oct 2011 11:53:17 -0400 Subject: [PATCH 16/53] apedec: cosmetics break some excessively long lines and remove space after '*' --- libavcodec/apedec.c | 88 ++++++++++++++++++++++++++------------------- 1 file changed, 52 insertions(+), 36 deletions(-) diff --git a/libavcodec/apedec.c b/libavcodec/apedec.c index 847b4ad27c..b0d19cdf1d 100644 --- a/libavcodec/apedec.c +++ b/libavcodec/apedec.c @@ -163,7 +163,7 @@ typedef struct APEContext { // TODO: dsputilize -static av_cold int ape_decode_close(AVCodecContext * avctx) +static av_cold int ape_decode_close(AVCodecContext *avctx) { APEContext *s = avctx->priv_data; int i; @@ -175,7 +175,7 @@ static av_cold int ape_decode_close(AVCodecContext * avctx) return 0; } -static av_cold int ape_decode_init(AVCodecContext * avctx) +static av_cold int ape_decode_init(AVCodecContext *avctx) { APEContext *s = avctx->priv_data; int i; @@ -198,9 +198,11 @@ static av_cold int ape_decode_init(AVCodecContext * avctx) s->compression_level = AV_RL16(avctx->extradata + 2); s->flags = AV_RL16(avctx->extradata + 4); - av_log(avctx, AV_LOG_DEBUG, "Compression Level: %d - Flags: %d\n", s->compression_level, s->flags); + av_log(avctx, AV_LOG_DEBUG, "Compression Level: %d - Flags: %d\n", + s->compression_level, s->flags); if (s->compression_level % 1000 || s->compression_level > COMPRESSION_LEVEL_INSANE) { - av_log(avctx, AV_LOG_ERROR, "Incorrect compression level %d\n", s->compression_level); + av_log(avctx, AV_LOG_ERROR, "Incorrect compression level %d\n", + s->compression_level); return AVERROR_INVALIDDATA; } s->fset = s->compression_level / 1000 - 1; @@ -233,7 +235,7 @@ filter_alloc_fail: #define BOTTOM_VALUE (TOP_VALUE >> 8) /** Start the decoder */ -static inline void range_start_decoding(APEContext * ctx) +static inline void range_start_decoding(APEContext *ctx) { ctx->rc.buffer = bytestream_get_byte(&ctx->ptr); ctx->rc.low = ctx->rc.buffer >> (8 - EXTRA_BITS); @@ -241,7 +243,7 @@ static inline void range_start_decoding(APEContext * ctx) } /** Perform normalization */ -static inline void range_dec_normalize(APEContext * ctx) +static inline void range_dec_normalize(APEContext *ctx) { while (ctx->rc.range <= BOTTOM_VALUE) { ctx->rc.buffer <<= 8; @@ -259,7 +261,7 @@ static inline void range_dec_normalize(APEContext * ctx) * @param tot_f is the total frequency or (code_value)1<rc.help = ctx->rc.range / tot_f; @@ -271,7 +273,7 @@ static inline int range_decode_culfreq(APEContext * ctx, int tot_f) * @param ctx decoder context * @param shift number of bits to decode */ -static inline int range_decode_culshift(APEContext * ctx, int shift) +static inline int range_decode_culshift(APEContext *ctx, int shift) { range_dec_normalize(ctx); ctx->rc.help = ctx->rc.range >> shift; @@ -285,14 +287,14 @@ static inline int range_decode_culshift(APEContext * ctx, int shift) * @param sy_f the interval length (frequency of the symbol) * @param lt_f the lower end (frequency sum of < symbols) */ -static inline void range_decode_update(APEContext * ctx, int sy_f, int lt_f) +static inline void range_decode_update(APEContext *ctx, int sy_f, int lt_f) { ctx->rc.low -= ctx->rc.help * lt_f; ctx->rc.range = ctx->rc.help * sy_f; } /** Decode n bits (n <= 16) without modelling */ -static inline int range_decode_bits(APEContext * ctx, int n) +static inline int range_decode_bits(APEContext *ctx, int n) { int sym = range_decode_culshift(ctx, n); range_decode_update(ctx, 1, sym); @@ -344,7 +346,7 @@ static const uint16_t counts_diff_3980[21] = { * @param counts probability range start position * @param counts_diff probability range widths */ -static inline int range_get_symbol(APEContext * ctx, +static inline int range_get_symbol(APEContext *ctx, const uint16_t counts[], const uint16_t counts_diff[]) { @@ -379,7 +381,7 @@ static inline void update_rice(APERice *rice, int x) rice->k++; } -static inline int ape_decode_value(APEContext * ctx, APERice *rice) +static inline int ape_decode_value(APEContext *ctx, APERice *rice) { int x, overflow; @@ -446,7 +448,7 @@ static inline int ape_decode_value(APEContext * ctx, APERice *rice) return -(x >> 1); } -static void entropy_decode(APEContext * ctx, int blockstodecode, int stereo) +static void entropy_decode(APEContext *ctx, int blockstodecode, int stereo) { int32_t *decoded0 = ctx->decoded0; int32_t *decoded1 = ctx->decoded1; @@ -469,7 +471,7 @@ static void entropy_decode(APEContext * ctx, int blockstodecode, int stereo) range_dec_normalize(ctx); /* normalize to use up all bytes */ } -static void init_entropy_decoder(APEContext * ctx) +static void init_entropy_decoder(APEContext *ctx) { /* Read the CRC */ ctx->CRC = bytestream_get_be32(&ctx->ptr); @@ -501,7 +503,7 @@ static const int32_t initial_coeffs[4] = { 360, 317, -109, 98 }; -static void init_predictor_decoder(APEContext * ctx) +static void init_predictor_decoder(APEContext *ctx) { APEPredictor *p = &ctx->predictor; @@ -524,7 +526,10 @@ static inline int APESIGN(int32_t x) { return (x < 0) - (x > 0); } -static av_always_inline int predictor_update_filter(APEPredictor *p, const int decoded, const int filter, const int delayA, const int delayB, const int adaptA, const int adaptB) +static av_always_inline int predictor_update_filter(APEPredictor *p, + const int decoded, const int filter, + const int delayA, const int delayB, + const int adaptA, const int adaptB) { int32_t predictionA, predictionB, sign; @@ -568,7 +573,7 @@ static av_always_inline int predictor_update_filter(APEPredictor *p, const int d return p->filterA[filter]; } -static void predictor_decode_stereo(APEContext * ctx, int count) +static void predictor_decode_stereo(APEContext *ctx, int count) { APEPredictor *p = &ctx->predictor; int32_t *decoded0 = ctx->decoded0; @@ -576,9 +581,11 @@ static void predictor_decode_stereo(APEContext * ctx, int count) while (count--) { /* Predictor Y */ - *decoded0 = predictor_update_filter(p, *decoded0, 0, YDELAYA, YDELAYB, YADAPTCOEFFSA, YADAPTCOEFFSB); + *decoded0 = predictor_update_filter(p, *decoded0, 0, YDELAYA, YDELAYB, + YADAPTCOEFFSA, YADAPTCOEFFSB); decoded0++; - *decoded1 = predictor_update_filter(p, *decoded1, 1, XDELAYA, XDELAYB, XADAPTCOEFFSA, XADAPTCOEFFSB); + *decoded1 = predictor_update_filter(p, *decoded1, 1, XDELAYA, XDELAYB, + XADAPTCOEFFSA, XADAPTCOEFFSB); decoded1++; /* Combined */ @@ -592,7 +599,7 @@ static void predictor_decode_stereo(APEContext * ctx, int count) } } -static void predictor_decode_mono(APEContext * ctx, int count) +static void predictor_decode_mono(APEContext *ctx, int count) { APEPredictor *p = &ctx->predictor; int32_t *decoded0 = ctx->decoded0; @@ -637,7 +644,7 @@ static void predictor_decode_mono(APEContext * ctx, int count) p->lastA[0] = currentA; } -static void do_init_filter(APEFilter *f, int16_t * buf, int order) +static void do_init_filter(APEFilter *f, int16_t *buf, int order) { f->coeffs = buf; f->historybuffer = buf + order; @@ -649,20 +656,23 @@ static void do_init_filter(APEFilter *f, int16_t * buf, int order) f->avg = 0; } -static void init_filter(APEContext * ctx, APEFilter *f, int16_t * buf, int order) +static void init_filter(APEContext *ctx, APEFilter *f, int16_t *buf, int order) { do_init_filter(&f[0], buf, order); do_init_filter(&f[1], buf + order * 3 + HISTORY_SIZE, order); } -static void do_apply_filter(APEContext * ctx, int version, APEFilter *f, int32_t *data, int count, int order, int fracbits) +static void do_apply_filter(APEContext *ctx, int version, APEFilter *f, + int32_t *data, int count, int order, int fracbits) { int res; int absres; while (count--) { /* round fixedpoint scalar product */ - res = ctx->dsp.scalarproduct_and_madd_int16(f->coeffs, f->delay - order, f->adaptcoeffs - order, order, APESIGN(*data)); + res = ctx->dsp.scalarproduct_and_madd_int16(f->coeffs, f->delay - order, + f->adaptcoeffs - order, + order, APESIGN(*data)); res = (res + (1 << (fracbits - 1))) >> fracbits; res += *data; *data++ = res; @@ -681,7 +691,8 @@ static void do_apply_filter(APEContext * ctx, int version, APEFilter *f, int32_t /* Update the adaption coefficients */ absres = FFABS(res); if (absres) - *f->adaptcoeffs = ((res & (1<<31)) - (1<<30)) >> (25 + (absres <= f->avg*3) + (absres <= f->avg*4/3)); + *f->adaptcoeffs = ((res & (1<<31)) - (1<<30)) >> + (25 + (absres <= f->avg*3) + (absres <= f->avg*4/3)); else *f->adaptcoeffs = 0; @@ -704,8 +715,8 @@ static void do_apply_filter(APEContext * ctx, int version, APEFilter *f, int32_t } } -static void apply_filter(APEContext * ctx, APEFilter *f, - int32_t * data0, int32_t * data1, +static void apply_filter(APEContext *ctx, APEFilter *f, + int32_t *data0, int32_t *data1, int count, int order, int fracbits) { do_apply_filter(ctx, ctx->fileversion, &f[0], data0, count, order, fracbits); @@ -713,19 +724,21 @@ static void apply_filter(APEContext * ctx, APEFilter *f, do_apply_filter(ctx, ctx->fileversion, &f[1], data1, count, order, fracbits); } -static void ape_apply_filters(APEContext * ctx, int32_t * decoded0, - int32_t * decoded1, int count) +static void ape_apply_filters(APEContext *ctx, int32_t *decoded0, + int32_t *decoded1, int count) { int i; for (i = 0; i < APE_FILTER_LEVELS; i++) { if (!ape_filter_orders[ctx->fset][i]) break; - apply_filter(ctx, ctx->filters[i], decoded0, decoded1, count, ape_filter_orders[ctx->fset][i], ape_filter_fracbits[ctx->fset][i]); + apply_filter(ctx, ctx->filters[i], decoded0, decoded1, count, + ape_filter_orders[ctx->fset][i], + ape_filter_fracbits[ctx->fset][i]); } } -static void init_frame_decoder(APEContext * ctx) +static void init_frame_decoder(APEContext *ctx) { int i; init_entropy_decoder(ctx); @@ -734,11 +747,12 @@ static void init_frame_decoder(APEContext * ctx) for (i = 0; i < APE_FILTER_LEVELS; i++) { if (!ape_filter_orders[ctx->fset][i]) break; - init_filter(ctx, ctx->filters[i], ctx->filterbuf[i], ape_filter_orders[ctx->fset][i]); + init_filter(ctx, ctx->filters[i], ctx->filterbuf[i], + ape_filter_orders[ctx->fset][i]); } } -static void ape_unpack_mono(APEContext * ctx, int count) +static void ape_unpack_mono(APEContext *ctx, int count) { int32_t *decoded0 = ctx->decoded0; int32_t *decoded1 = ctx->decoded1; @@ -762,7 +776,7 @@ static void ape_unpack_mono(APEContext * ctx, int count) } } -static void ape_unpack_stereo(APEContext * ctx, int count) +static void ape_unpack_stereo(APEContext *ctx, int count) { int32_t left, right; int32_t *decoded0 = ctx->decoded0; @@ -790,7 +804,7 @@ static void ape_unpack_stereo(APEContext * ctx, int count) } } -static int ape_decode_frame(AVCodecContext * avctx, +static int ape_decode_frame(AVCodecContext *avctx, void *data, int *data_size, AVPacket *avpkt) { @@ -805,7 +819,9 @@ static int ape_decode_frame(AVCodecContext * avctx, /* should not happen but who knows */ if (BLOCKS_PER_LOOP * 2 * avctx->channels > *data_size) { - av_log (avctx, AV_LOG_ERROR, "Packet size is too big to be handled in lavc! (max is %d where you have %d)\n", *data_size, s->samples * 2 * avctx->channels); + av_log (avctx, AV_LOG_ERROR, "Packet size is too big to be handled " + "in lavc! (max is %d where you have %d)\n", + *data_size, s->samples * 2 * avctx->channels); return -1; } From c6defb41ef78909e25cf7940ae1542775099f995 Mon Sep 17 00:00:00 2001 From: Justin Ruggles Date: Tue, 11 Oct 2011 11:54:42 -0400 Subject: [PATCH 17/53] apedec: correct an error message --- libavcodec/apedec.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/libavcodec/apedec.c b/libavcodec/apedec.c index b0d19cdf1d..9a15bfb872 100644 --- a/libavcodec/apedec.c +++ b/libavcodec/apedec.c @@ -819,9 +819,7 @@ static int ape_decode_frame(AVCodecContext *avctx, /* should not happen but who knows */ if (BLOCKS_PER_LOOP * 2 * avctx->channels > *data_size) { - av_log (avctx, AV_LOG_ERROR, "Packet size is too big to be handled " - "in lavc! (max is %d where you have %d)\n", - *data_size, s->samples * 2 * avctx->channels); + av_log (avctx, AV_LOG_ERROR, "Output buffer is too small.\n"); return -1; } From 91b71460b5b2ba1060314d5811029159a013fcac Mon Sep 17 00:00:00 2001 From: Justin Ruggles Date: Tue, 11 Oct 2011 11:55:56 -0400 Subject: [PATCH 18/53] apedec: return meaningful error values in ape_decode_frame() --- libavcodec/apedec.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/libavcodec/apedec.c b/libavcodec/apedec.c index 9a15bfb872..a754fd75b0 100644 --- a/libavcodec/apedec.c +++ b/libavcodec/apedec.c @@ -820,7 +820,7 @@ static int ape_decode_frame(AVCodecContext *avctx, /* should not happen but who knows */ if (BLOCKS_PER_LOOP * 2 * avctx->channels > *data_size) { av_log (avctx, AV_LOG_ERROR, "Output buffer is too small.\n"); - return -1; + return AVERROR(EINVAL); } if(!s->samples){ @@ -834,7 +834,7 @@ static int ape_decode_frame(AVCodecContext *avctx, if(n < 0 || n > 3){ av_log(avctx, AV_LOG_ERROR, "Incorrect offset passed\n"); s->data = NULL; - return -1; + return AVERROR_INVALIDDATA; } s->ptr += n; @@ -871,7 +871,7 @@ static int ape_decode_frame(AVCodecContext *avctx, if(s->error || s->ptr > s->data_end){ s->samples=0; av_log(avctx, AV_LOG_ERROR, "Error decoding frame\n"); - return -1; + return AVERROR_INVALIDDATA; } for (i = 0; i < blockstodecode; i++) { From 11ca8b2d7486e879926488404b3b79af774f0f2d Mon Sep 17 00:00:00 2001 From: Justin Ruggles Date: Tue, 11 Oct 2011 12:47:11 -0400 Subject: [PATCH 19/53] apedec: check for data buffer realloc failure --- libavcodec/apedec.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/libavcodec/apedec.c b/libavcodec/apedec.c index a754fd75b0..2041e2b3c5 100644 --- a/libavcodec/apedec.c +++ b/libavcodec/apedec.c @@ -824,7 +824,10 @@ static int ape_decode_frame(AVCodecContext *avctx, } if(!s->samples){ - s->data = av_realloc(s->data, (buf_size + 3) & ~3); + void *tmp_data = av_realloc(s->data, (buf_size + 3) & ~3); + if (!tmp_data) + return AVERROR(ENOMEM); + s->data = tmp_data; s->dsp.bswap_buf((uint32_t*)s->data, (const uint32_t*)buf, buf_size >> 2); s->ptr = s->last_ptr = s->data; s->data_end = s->data + buf_size; From b7e514575982fd2f5db5ea4f3b466d6dd6a08aa7 Mon Sep 17 00:00:00 2001 From: Justin Ruggles Date: Tue, 11 Oct 2011 12:49:46 -0400 Subject: [PATCH 20/53] apedec: do not set s->samples until after validation. This prevents errors and/or invalid writes in the next decode call due to s->samples still being negative. --- libavcodec/apedec.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/libavcodec/apedec.c b/libavcodec/apedec.c index 2041e2b3c5..a741c7d469 100644 --- a/libavcodec/apedec.c +++ b/libavcodec/apedec.c @@ -832,7 +832,7 @@ static int ape_decode_frame(AVCodecContext *avctx, s->ptr = s->last_ptr = s->data; s->data_end = s->data + buf_size; - nblocks = s->samples = bytestream_get_be32(&s->ptr); + nblocks = bytestream_get_be32(&s->ptr); n = bytestream_get_be32(&s->ptr); if(n < 0 || n > 3){ av_log(avctx, AV_LOG_ERROR, "Incorrect offset passed\n"); @@ -843,10 +843,11 @@ static int ape_decode_frame(AVCodecContext *avctx, s->currentframeblocks = nblocks; buf += 4; - if (s->samples <= 0) { + if (nblocks <= 0) { *data_size = 0; return buf_size; } + s->samples = nblocks; memset(s->decoded0, 0, sizeof(s->decoded0)); memset(s->decoded1, 0, sizeof(s->decoded1)); From 2cab5784892c6ae47feb5f1a97445946b3404ac0 Mon Sep 17 00:00:00 2001 From: Justin Ruggles Date: Tue, 11 Oct 2011 13:17:44 -0400 Subject: [PATCH 21/53] apedec: use unsigned int for 'nblocks' and make sure that it's within int range --- libavcodec/apedec.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/libavcodec/apedec.c b/libavcodec/apedec.c index a741c7d469..f6ec47039d 100644 --- a/libavcodec/apedec.c +++ b/libavcodec/apedec.c @@ -812,7 +812,7 @@ static int ape_decode_frame(AVCodecContext *avctx, int buf_size = avpkt->size; APEContext *s = avctx->priv_data; int16_t *samples = data; - int nblocks; + uint32_t nblocks; int i, n; int blockstodecode; int bytes_used; @@ -843,9 +843,9 @@ static int ape_decode_frame(AVCodecContext *avctx, s->currentframeblocks = nblocks; buf += 4; - if (nblocks <= 0) { - *data_size = 0; - return buf_size; + if (!nblocks || nblocks > INT_MAX) { + av_log(avctx, AV_LOG_ERROR, "Invalid sample count: %u.\n", nblocks); + return AVERROR_INVALIDDATA; } s->samples = nblocks; From 52d4fb2a3dd7aea62a06cf8358dc41fdb4913f6f Mon Sep 17 00:00:00 2001 From: Justin Ruggles Date: Tue, 11 Oct 2011 13:25:27 -0400 Subject: [PATCH 22/53] apedec: set s->currentframeblocks after validating nblocks --- libavcodec/apedec.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/libavcodec/apedec.c b/libavcodec/apedec.c index f6ec47039d..9274b231ce 100644 --- a/libavcodec/apedec.c +++ b/libavcodec/apedec.c @@ -841,13 +841,12 @@ static int ape_decode_frame(AVCodecContext *avctx, } s->ptr += n; - s->currentframeblocks = nblocks; buf += 4; if (!nblocks || nblocks > INT_MAX) { av_log(avctx, AV_LOG_ERROR, "Invalid sample count: %u.\n", nblocks); return AVERROR_INVALIDDATA; } - s->samples = nblocks; + s->currentframeblocks = s->samples = nblocks; memset(s->decoded0, 0, sizeof(s->decoded0)); memset(s->decoded1, 0, sizeof(s->decoded1)); From 89ec474a437770150c048d0db631b0bee4251b8a Mon Sep 17 00:00:00 2001 From: Justin Ruggles Date: Tue, 11 Oct 2011 13:25:48 -0400 Subject: [PATCH 23/53] apedec: remove pointless increment of 'buf' The variable is not used anymore at that point. --- libavcodec/apedec.c | 1 - 1 file changed, 1 deletion(-) diff --git a/libavcodec/apedec.c b/libavcodec/apedec.c index 9274b231ce..4e09871b54 100644 --- a/libavcodec/apedec.c +++ b/libavcodec/apedec.c @@ -841,7 +841,6 @@ static int ape_decode_frame(AVCodecContext *avctx, } s->ptr += n; - buf += 4; if (!nblocks || nblocks > INT_MAX) { av_log(avctx, AV_LOG_ERROR, "Invalid sample count: %u.\n", nblocks); return AVERROR_INVALIDDATA; From fd244ae3a068f4f480e967e8e522f69ef6968c69 Mon Sep 17 00:00:00 2001 From: Justin Ruggles Date: Tue, 11 Oct 2011 13:34:18 -0400 Subject: [PATCH 24/53] apedec: use unsigned int for offset avoids implementation-defined unsigned-to-signed conversion and simplifies the bounds checking. --- libavcodec/apedec.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/libavcodec/apedec.c b/libavcodec/apedec.c index 4e09871b54..ed9073cf9b 100644 --- a/libavcodec/apedec.c +++ b/libavcodec/apedec.c @@ -813,7 +813,7 @@ static int ape_decode_frame(AVCodecContext *avctx, APEContext *s = avctx->priv_data; int16_t *samples = data; uint32_t nblocks; - int i, n; + int i; int blockstodecode; int bytes_used; @@ -824,6 +824,7 @@ static int ape_decode_frame(AVCodecContext *avctx, } if(!s->samples){ + uint32_t offset; void *tmp_data = av_realloc(s->data, (buf_size + 3) & ~3); if (!tmp_data) return AVERROR(ENOMEM); @@ -833,13 +834,13 @@ static int ape_decode_frame(AVCodecContext *avctx, s->data_end = s->data + buf_size; nblocks = bytestream_get_be32(&s->ptr); - n = bytestream_get_be32(&s->ptr); - if(n < 0 || n > 3){ + offset = bytestream_get_be32(&s->ptr); + if (offset > 3) { av_log(avctx, AV_LOG_ERROR, "Incorrect offset passed\n"); s->data = NULL; return AVERROR_INVALIDDATA; } - s->ptr += n; + s->ptr += offset; if (!nblocks || nblocks > INT_MAX) { av_log(avctx, AV_LOG_ERROR, "Invalid sample count: %u.\n", nblocks); From a4c32c9a63142b602820800742f2d543b58cd278 Mon Sep 17 00:00:00 2001 From: Justin Ruggles Date: Tue, 11 Oct 2011 14:06:52 -0400 Subject: [PATCH 25/53] apedec: check for input buffer overflow while reading frame header --- libavcodec/apedec.c | 34 ++++++++++++++++++++++++++++------ 1 file changed, 28 insertions(+), 6 deletions(-) diff --git a/libavcodec/apedec.c b/libavcodec/apedec.c index ed9073cf9b..ef990bf693 100644 --- a/libavcodec/apedec.c +++ b/libavcodec/apedec.c @@ -471,9 +471,11 @@ static void entropy_decode(APEContext *ctx, int blockstodecode, int stereo) range_dec_normalize(ctx); /* normalize to use up all bytes */ } -static void init_entropy_decoder(APEContext *ctx) +static int init_entropy_decoder(APEContext *ctx) { /* Read the CRC */ + if (ctx->data_end - ctx->ptr < 6) + return AVERROR_INVALIDDATA; ctx->CRC = bytestream_get_be32(&ctx->ptr); /* Read the frame flags if they exist */ @@ -481,6 +483,8 @@ static void init_entropy_decoder(APEContext *ctx) if ((ctx->fileversion > 3820) && (ctx->CRC & 0x80000000)) { ctx->CRC &= ~0x80000000; + if (ctx->data_end - ctx->ptr < 6) + return AVERROR_INVALIDDATA; ctx->frameflags = bytestream_get_be32(&ctx->ptr); } @@ -497,6 +501,8 @@ static void init_entropy_decoder(APEContext *ctx) ctx->ptr++; range_start_decoding(ctx); + + return 0; } static const int32_t initial_coeffs[4] = { @@ -738,10 +744,11 @@ static void ape_apply_filters(APEContext *ctx, int32_t *decoded0, } } -static void init_frame_decoder(APEContext *ctx) +static int init_frame_decoder(APEContext *ctx) { - int i; - init_entropy_decoder(ctx); + int i, ret; + if ((ret = init_entropy_decoder(ctx)) < 0) + return ret; init_predictor_decoder(ctx); for (i = 0; i < APE_FILTER_LEVELS; i++) { @@ -750,6 +757,7 @@ static void init_frame_decoder(APEContext *ctx) init_filter(ctx, ctx->filters[i], ctx->filterbuf[i], ape_filter_orders[ctx->fset][i]); } + return 0; } static void ape_unpack_mono(APEContext *ctx, int count) @@ -825,7 +833,14 @@ static int ape_decode_frame(AVCodecContext *avctx, if(!s->samples){ uint32_t offset; - void *tmp_data = av_realloc(s->data, (buf_size + 3) & ~3); + void *tmp_data; + + if (buf_size < 8) { + av_log(avctx, AV_LOG_ERROR, "Packet is too small\n"); + return AVERROR_INVALIDDATA; + } + + tmp_data = av_realloc(s->data, (buf_size + 3) & ~3); if (!tmp_data) return AVERROR(ENOMEM); s->data = tmp_data; @@ -840,6 +855,10 @@ static int ape_decode_frame(AVCodecContext *avctx, s->data = NULL; return AVERROR_INVALIDDATA; } + if (s->data_end - s->ptr < offset) { + av_log(avctx, AV_LOG_ERROR, "Packet is too small\n"); + return AVERROR_INVALIDDATA; + } s->ptr += offset; if (!nblocks || nblocks > INT_MAX) { @@ -852,7 +871,10 @@ static int ape_decode_frame(AVCodecContext *avctx, memset(s->decoded1, 0, sizeof(s->decoded1)); /* Initialize the frame decoder */ - init_frame_decoder(s); + if (init_frame_decoder(s) < 0) { + av_log(avctx, AV_LOG_ERROR, "Error reading frame header\n"); + return AVERROR_INVALIDDATA; + } } if (!s->data) { From 5b8009f4c80d8fd96523c8c163441ad4011ad472 Mon Sep 17 00:00:00 2001 From: Justin Ruggles Date: Tue, 11 Oct 2011 14:12:54 -0400 Subject: [PATCH 26/53] apedec: do not keep incrementing the input data pointer past the end of the buffer during entropy decoding. The pointer address could overflow, which would likely segfault. Instead set the context error flag to indicate that the decoder tried to read past the end of the packet data. --- libavcodec/apedec.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/libavcodec/apedec.c b/libavcodec/apedec.c index ef990bf693..133eb2da58 100644 --- a/libavcodec/apedec.c +++ b/libavcodec/apedec.c @@ -247,9 +247,12 @@ static inline void range_dec_normalize(APEContext *ctx) { while (ctx->rc.range <= BOTTOM_VALUE) { ctx->rc.buffer <<= 8; - if(ctx->ptr < ctx->data_end) + if(ctx->ptr < ctx->data_end) { ctx->rc.buffer += *ctx->ptr; - ctx->ptr++; + ctx->ptr++; + } else { + ctx->error = 1; + } ctx->rc.low = (ctx->rc.low << 8) | ((ctx->rc.buffer >> 1) & 0xFF); ctx->rc.range <<= 8; } @@ -893,7 +896,7 @@ static int ape_decode_frame(AVCodecContext *avctx, ape_unpack_stereo(s, blockstodecode); emms_c(); - if(s->error || s->ptr > s->data_end){ + if (s->error) { s->samples=0; av_log(avctx, AV_LOG_ERROR, "Error decoding frame\n"); return AVERROR_INVALIDDATA; From 0927154d378317be29dd997bda92b305e6dabc00 Mon Sep 17 00:00:00 2001 From: Justin Ruggles Date: Tue, 11 Oct 2011 14:35:33 -0400 Subject: [PATCH 27/53] apedec: use FFALIGN macro for internal data buffer size --- libavcodec/apedec.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libavcodec/apedec.c b/libavcodec/apedec.c index 133eb2da58..8b1af80934 100644 --- a/libavcodec/apedec.c +++ b/libavcodec/apedec.c @@ -843,7 +843,7 @@ static int ape_decode_frame(AVCodecContext *avctx, return AVERROR_INVALIDDATA; } - tmp_data = av_realloc(s->data, (buf_size + 3) & ~3); + tmp_data = av_realloc(s->data, FFALIGN(buf_size, 4)); if (!tmp_data) return AVERROR(ENOMEM); s->data = tmp_data; From 9a33264478796fd790a3bdc182fb1dda65d0a9de Mon Sep 17 00:00:00 2001 From: Justin Ruggles Date: Tue, 11 Oct 2011 14:38:21 -0400 Subject: [PATCH 28/53] apedec: assert that s->samples is not negative before trying to decode --- libavcodec/apedec.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/libavcodec/apedec.c b/libavcodec/apedec.c index 8b1af80934..e9069031ad 100644 --- a/libavcodec/apedec.c +++ b/libavcodec/apedec.c @@ -26,6 +26,7 @@ #include "get_bits.h" #include "bytestream.h" #include "libavutil/audioconvert.h" +#include "libavutil/avassert.h" /** * @file @@ -834,6 +835,10 @@ static int ape_decode_frame(AVCodecContext *avctx, return AVERROR(EINVAL); } + /* this should never be negative, but bad things will happen if it is, so + check it just to make sure. */ + av_assert0(s->samples >= 0); + if(!s->samples){ uint32_t offset; void *tmp_data; From d0b1b1c5c74a14d0b3acc39470c23af4561c617b Mon Sep 17 00:00:00 2001 From: Justin Ruggles Date: Fri, 23 Sep 2011 23:38:36 -0400 Subject: [PATCH 29/53] wmadec: consolidate 2 output buffer size checks into 1 check --- libavcodec/wmadec.c | 25 ++++++++++++++----------- 1 file changed, 14 insertions(+), 11 deletions(-) diff --git a/libavcodec/wmadec.c b/libavcodec/wmadec.c index 389bf02931..1e3b7e32a5 100644 --- a/libavcodec/wmadec.c +++ b/libavcodec/wmadec.c @@ -804,7 +804,7 @@ static int wma_decode_superframe(AVCodecContext *avctx, const uint8_t *buf = avpkt->data; int buf_size = avpkt->size; WMACodecContext *s = avctx->priv_data; - int nb_frames, bit_offset, i, pos, len; + int nb_frames, bit_offset, i, pos, len, out_size; uint8_t *q; int16_t *samples; @@ -825,13 +825,19 @@ static int wma_decode_superframe(AVCodecContext *avctx, if (s->use_bit_reservoir) { /* read super frame header */ skip_bits(&s->gb, 4); /* super frame index */ - nb_frames = get_bits(&s->gb, 4) - 1; + nb_frames = get_bits(&s->gb, 4) - (s->last_superframe_len <= 0); + } else { + nb_frames = 1; + } - if((nb_frames+1) * s->nb_channels * s->frame_len * sizeof(int16_t) > *data_size){ - av_log(s->avctx, AV_LOG_ERROR, "Insufficient output space\n"); - goto fail; - } + out_size = nb_frames * s->frame_len * s->nb_channels * + av_get_bytes_per_sample(avctx->sample_fmt); + if (*data_size < out_size) { + av_log(s->avctx, AV_LOG_ERROR, "Insufficient output space\n"); + goto fail; + } + if (s->use_bit_reservoir) { bit_offset = get_bits(&s->gb, s->byte_offset_bits + 3); if (s->last_superframe_len > 0) { @@ -860,6 +866,7 @@ static int wma_decode_superframe(AVCodecContext *avctx, if (wma_decode_frame(s, samples) < 0) goto fail; samples += s->nb_channels * s->frame_len; + nb_frames--; } /* read each frame starting from bit_offset */ @@ -888,10 +895,6 @@ static int wma_decode_superframe(AVCodecContext *avctx, s->last_superframe_len = len; memcpy(s->last_superframe, buf + pos, len); } else { - if(s->nb_channels * s->frame_len * sizeof(int16_t) > *data_size){ - av_log(s->avctx, AV_LOG_ERROR, "Insufficient output space\n"); - goto fail; - } /* single frame decode */ if (wma_decode_frame(s, samples) < 0) goto fail; @@ -900,7 +903,7 @@ static int wma_decode_superframe(AVCodecContext *avctx, //av_log(NULL, AV_LOG_ERROR, "%d %d %d %d outbytes:%d eaten:%d\n", s->frame_len_bits, s->block_len_bits, s->frame_len, s->block_len, (int8_t *)samples - (int8_t *)data, s->block_align); - *data_size = (int8_t *)samples - (int8_t *)data; + *data_size = out_size; return s->block_align; fail: /* when error, we reset the bit reservoir */ From b8b4c9c328bf19f4dc8dd5666ce80ec91200cac4 Mon Sep 17 00:00:00 2001 From: Justin Ruggles Date: Sat, 24 Sep 2011 00:34:37 -0400 Subject: [PATCH 30/53] wmapro: use FmtConvertContext.float_interleave() to interleave output samples --- libavcodec/wmaprodec.c | 20 +++++++++----------- 1 file changed, 9 insertions(+), 11 deletions(-) diff --git a/libavcodec/wmaprodec.c b/libavcodec/wmaprodec.c index b3ba9abe15..ce83bb6c54 100644 --- a/libavcodec/wmaprodec.c +++ b/libavcodec/wmaprodec.c @@ -92,6 +92,7 @@ #include "put_bits.h" #include "wmaprodata.h" #include "dsputil.h" +#include "fmtconvert.h" #include "sinewin.h" #include "wma.h" @@ -166,6 +167,7 @@ typedef struct WMAProDecodeCtx { /* generic decoder variables */ AVCodecContext* avctx; ///< codec context for av_log DSPContext dsp; ///< accelerated DSP functions + FmtConvertContext fmt_conv; uint8_t frame_data[MAX_FRAMESIZE + FF_INPUT_BUFFER_PADDING_SIZE];///< compressed frame data PutBitContext pb; ///< context for filling the frame_data buffer @@ -279,6 +281,7 @@ static av_cold int decode_init(AVCodecContext *avctx) s->avctx = avctx; dsputil_init(&s->dsp, avctx); + ff_fmt_convert_init(&s->fmt_conv, avctx); init_put_bits(&s->pb, s->frame_data, MAX_FRAMESIZE); avctx->sample_fmt = AV_SAMPLE_FMT_FLT; @@ -1281,6 +1284,7 @@ static int decode_frame(WMAProDecodeCtx *s) int more_frames = 0; int len = 0; int i; + const float *out_ptr[WMAPRO_MAX_CHANNELS]; /** check for potential output buffer overflow */ if (s->num_channels * s->samples_per_frame > s->samples_end - s->samples) { @@ -1356,18 +1360,12 @@ static int decode_frame(WMAProDecodeCtx *s) } /** interleave samples and write them to the output buffer */ + for (i = 0; i < s->num_channels; i++) + out_ptr[i] = s->channel[i].out; + s->fmt_conv.float_interleave(s->samples, out_ptr, s->samples_per_frame, + s->num_channels); + for (i = 0; i < s->num_channels; i++) { - float* ptr = s->samples + i; - int incr = s->num_channels; - float* iptr = s->channel[i].out; - float* iend = iptr + s->samples_per_frame; - - // FIXME should create/use a DSP function here - while (iptr < iend) { - *ptr = *iptr++; - ptr += incr; - } - /** reuse second half of the IMDCT output for the next frame */ memcpy(&s->channel[i].out[0], &s->channel[i].out[s->samples_per_frame], From 1db6437f6ce88be241981b78f776b14404bb14fe Mon Sep 17 00:00:00 2001 From: Justin Ruggles Date: Sat, 24 Sep 2011 00:50:22 -0400 Subject: [PATCH 31/53] wmapro: fix strict-aliasing violations by using av_alias32 Also fix some undefined unsigned/signed conversions. --- libavcodec/wmaprodec.c | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/libavcodec/wmaprodec.c b/libavcodec/wmaprodec.c index ce83bb6c54..aaae6e1f3a 100644 --- a/libavcodec/wmaprodec.c +++ b/libavcodec/wmaprodec.c @@ -86,6 +86,7 @@ * subframe in order to reconstruct the output samples. */ +#include "libavutil/intreadwrite.h" #include "avcodec.h" #include "internal.h" #include "get_bits.h" @@ -770,7 +771,7 @@ static int decode_coeffs(WMAProDecodeCtx *s, int c) /* Integers 0..15 as single-precision floats. The table saves a costly int to float conversion, and storing the values as integers allows fast sign-flipping. */ - static const int fval_tab[16] = { + static const uint32_t fval_tab[16] = { 0x00000000, 0x3f800000, 0x40000000, 0x40400000, 0x40800000, 0x40a00000, 0x40c00000, 0x40e00000, 0x41000000, 0x41100000, 0x41200000, 0x41300000, @@ -802,7 +803,7 @@ static int decode_coeffs(WMAProDecodeCtx *s, int c) 4 vector coded large values) */ while ((s->transmit_num_vec_coeffs || !rl_mode) && (cur_coeff + 3 < ci->num_vec_coeffs)) { - int vals[4]; + uint32_t vals[4]; int i; unsigned int idx; @@ -812,15 +813,15 @@ static int decode_coeffs(WMAProDecodeCtx *s, int c) for (i = 0; i < 4; i += 2) { idx = get_vlc2(&s->gb, vec2_vlc.table, VLCBITS, VEC2MAXDEPTH); if (idx == HUFF_VEC2_SIZE - 1) { - int v0, v1; + uint32_t v0, v1; v0 = get_vlc2(&s->gb, vec1_vlc.table, VLCBITS, VEC1MAXDEPTH); if (v0 == HUFF_VEC1_SIZE - 1) v0 += ff_wma_get_large_val(&s->gb); v1 = get_vlc2(&s->gb, vec1_vlc.table, VLCBITS, VEC1MAXDEPTH); if (v1 == HUFF_VEC1_SIZE - 1) v1 += ff_wma_get_large_val(&s->gb); - ((float*)vals)[i ] = v0; - ((float*)vals)[i+1] = v1; + vals[i ] = ((av_alias32){ .f32 = v0 }).u32; + vals[i+1] = ((av_alias32){ .f32 = v1 }).u32; } else { vals[i] = fval_tab[symbol_to_vec2[idx] >> 4 ]; vals[i+1] = fval_tab[symbol_to_vec2[idx] & 0xF]; @@ -836,8 +837,8 @@ static int decode_coeffs(WMAProDecodeCtx *s, int c) /** decode sign */ for (i = 0; i < 4; i++) { if (vals[i]) { - int sign = get_bits1(&s->gb) - 1; - *(uint32_t*)&ci->coeffs[cur_coeff] = vals[i] ^ sign<<31; + uint32_t sign = get_bits1(&s->gb) - 1; + AV_WN32A(&ci->coeffs[cur_coeff], vals[i] ^ sign << 31); num_zeros = 0; } else { ci->coeffs[cur_coeff] = 0; From d0640765708405215e13c88a0c48d4231ec646ab Mon Sep 17 00:00:00 2001 From: Justin Ruggles Date: Sat, 24 Sep 2011 20:11:34 -0400 Subject: [PATCH 32/53] wmavoice: only set data_size to 0 when necessary --- libavcodec/wmavoice.c | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/libavcodec/wmavoice.c b/libavcodec/wmavoice.c index 2096d69870..d20fd69822 100644 --- a/libavcodec/wmavoice.c +++ b/libavcodec/wmavoice.c @@ -1748,7 +1748,10 @@ static int synth_superframe(AVCodecContext *ctx, s->sframe_cache_size = 0; } - if ((res = check_bits_for_superframe(gb, s)) == 1) return 1; + if ((res = check_bits_for_superframe(gb, s)) == 1) { + *data_size = 0; + return 1; + } /* First bit is speech/music bit, it differentiates between WMAVoice * speech samples (the actual codec) and WMAVoice music samples, which @@ -1808,8 +1811,10 @@ static int synth_superframe(AVCodecContext *ctx, &samples[n * MAX_FRAMESIZE], lsps[n], n == 0 ? s->prev_lsps : lsps[n - 1], &excitation[s->history_nsamples + n * MAX_FRAMESIZE], - &synth[s->lsps + n * MAX_FRAMESIZE]))) + &synth[s->lsps + n * MAX_FRAMESIZE]))) { + *data_size = 0; return res; + } } /* Statistics? FIXME - we don't check for length, a slight overrun @@ -1921,7 +1926,6 @@ static int wmavoice_decode_packet(AVCodecContext *ctx, void *data, *data_size, 480 * sizeof(float)); return -1; } - *data_size = 0; /* Packets are sometimes a multiple of ctx->block_align, with a packet * header at each ctx->block_align bytes. However, Libav's ASF demuxer @@ -1929,8 +1933,10 @@ static int wmavoice_decode_packet(AVCodecContext *ctx, void *data, * in a single "muxer" packet, so we artificially emulate that by * capping the packet size at ctx->block_align. */ for (size = avpkt->size; size > ctx->block_align; size -= ctx->block_align); - if (!size) + if (!size) { + *data_size = 0; return 0; + } init_get_bits(&s->gb, avpkt->data, size << 3); /* size == ctx->block_align is used to indicate whether we are dealing with From 813907d42483279e767fc84f2d02aa088197a22d Mon Sep 17 00:00:00 2001 From: Justin Ruggles Date: Sat, 24 Sep 2011 20:13:56 -0400 Subject: [PATCH 33/53] wmavoice: move output buffer size check to synth_superframe(). this allows for checking against the actual output size instead of max size. --- libavcodec/wmavoice.c | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/libavcodec/wmavoice.c b/libavcodec/wmavoice.c index d20fd69822..61258ba1ce 100644 --- a/libavcodec/wmavoice.c +++ b/libavcodec/wmavoice.c @@ -1730,7 +1730,7 @@ static int synth_superframe(AVCodecContext *ctx, { WMAVoiceContext *s = ctx->priv_data; GetBitContext *gb = &s->gb, s_gb; - int n, res, n_samples = 480; + int n, res, out_size, n_samples = 480; double lsps[MAX_FRAMES][MAX_LSPS]; const double *mean_lsf = s->lsps == 16 ? wmavoice_mean_lsf16[s->lsp_def_mode] : wmavoice_mean_lsf10[s->lsp_def_mode]; @@ -1792,6 +1792,14 @@ static int synth_superframe(AVCodecContext *ctx, stabilize_lsps(lsps[n], s->lsps); } + out_size = n_samples * av_get_bytes_per_sample(ctx->sample_fmt); + if (*data_size < out_size) { + av_log(ctx, AV_LOG_ERROR, + "Output buffer too small (%d given - %zu needed)\n", + *data_size, out_size); + return -1; + } + /* Parse frames, optionally preceeded by per-frame (independent) LSPs. */ for (n = 0; n < 3; n++) { if (!s->has_residual_lsps) { @@ -1826,7 +1834,7 @@ static int synth_superframe(AVCodecContext *ctx, } /* Specify nr. of output samples */ - *data_size = n_samples * sizeof(float); + *data_size = out_size; /* Update history */ memcpy(s->prev_lsps, lsps[2], @@ -1920,13 +1928,6 @@ static int wmavoice_decode_packet(AVCodecContext *ctx, void *data, GetBitContext *gb = &s->gb; int size, res, pos; - if (*data_size < 480 * sizeof(float)) { - av_log(ctx, AV_LOG_ERROR, - "Output buffer too small (%d given - %zu needed)\n", - *data_size, 480 * sizeof(float)); - return -1; - } - /* Packets are sometimes a multiple of ctx->block_align, with a packet * header at each ctx->block_align bytes. However, Libav's ASF demuxer * feeds us ASF packets, which may concatenate multiple "codec" packets From d88e9f1c07437c197f3b7c76454fbb5f9bb24a8f Mon Sep 17 00:00:00 2001 From: Janne Grunau Date: Fri, 28 Oct 2011 18:32:51 +0200 Subject: [PATCH 34/53] seek-test: update to recent avformat api --- libavformat/seek-test.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/libavformat/seek-test.c b/libavformat/seek-test.c index 3dd60dc160..771036087a 100644 --- a/libavformat/seek-test.c +++ b/libavformat/seek-test.c @@ -64,10 +64,10 @@ int main(int argc, char **argv) AVFormatContext *ic = NULL; int i, ret, stream_id; int64_t timestamp; - AVFormatParameters params, *ap= ¶ms; - memset(ap, 0, sizeof(params)); - ap->channels=1; - ap->sample_rate= 22050; + AVDictionary *format_opts = NULL; + + av_dict_set(&format_opts, "channels", "1", 0); + av_dict_set(&format_opts, "sample_rate", "22050", 0); /* initialize libavcodec, and register all codecs and formats */ av_register_all(); @@ -80,7 +80,7 @@ int main(int argc, char **argv) filename = argv[1]; - ret = av_open_input_file(&ic, filename, NULL, 0, ap); + ret = avformat_open_input(&ic, filename, NULL, &format_opts); if (ret < 0) { fprintf(stderr, "cannot open %s\n", filename); exit(1); From d830264abd6453ea983f009418f263ebcfaaa144 Mon Sep 17 00:00:00 2001 From: Janne Grunau Date: Fri, 28 Oct 2011 18:36:54 +0200 Subject: [PATCH 35/53] tools/pktdumper: update to recent avformat api --- tools/pktdumper.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tools/pktdumper.c b/tools/pktdumper.c index 56bc7b7ce0..2da1146430 100644 --- a/tools/pktdumper.c +++ b/tools/pktdumper.c @@ -44,7 +44,7 @@ int main(int argc, char **argv) { char fntemplate[PATH_MAX]; char pktfilename[PATH_MAX]; - AVFormatContext *fctx; + AVFormatContext *fctx = NULL; AVPacket pkt; int64_t pktnum = 0; int64_t maxpkts = 0; @@ -83,9 +83,9 @@ int main(int argc, char **argv) // register all file formats av_register_all(); - err = av_open_input_file(&fctx, argv[1], NULL, 0, NULL); + err = avformat_open_input(&fctx, argv[1], NULL, NULL); if (err < 0) { - fprintf(stderr, "av_open_input_file: error %d\n", err); + fprintf(stderr, "cannot open input: error %d\n", err); return 1; } From 8fa97302e03f00a81177027c3578274fef41c250 Mon Sep 17 00:00:00 2001 From: Michael Niedermayer Date: Wed, 26 Oct 2011 15:47:14 +0200 Subject: [PATCH 36/53] snow: do not draw_edge if emu_edge is set Fix segfault on emu edge, to reproduce make fate-vsynth1-snow avplay -flags emu_edge tests/data/vsynth1/snow.avi Signed-off-by: Luca Barbato --- libavcodec/snow.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/libavcodec/snow.c b/libavcodec/snow.c index 02fc5f79ab..a3af5772c2 100644 --- a/libavcodec/snow.c +++ b/libavcodec/snow.c @@ -1609,8 +1609,6 @@ static void dwt_quantize(SnowContext *s, Plane *p, DWTELEM *buffer, int width, i static void halfpel_interpol(SnowContext *s, uint8_t *halfpel[4][4], AVFrame *frame){ int p,x,y; - assert(!(s->avctx->flags & CODEC_FLAG_EMU_EDGE)); - for(p=0; p<3; p++){ int is_chroma= !!p; int w= s->avctx->width >>is_chroma; @@ -1667,7 +1665,7 @@ static int frame_start(SnowContext *s){ int w= s->avctx->width; //FIXME round up to x16 ? int h= s->avctx->height; - if(s->current_picture.data[0]){ + if (s->current_picture.data[0] && !(s->avctx->flags&CODEC_FLAG_EMU_EDGE)) { s->dsp.draw_edges(s->current_picture.data[0], s->current_picture.linesize[0], w , h , EDGE_WIDTH , EDGE_WIDTH , EDGE_TOP | EDGE_BOTTOM); From c12ef64d699fb209f2474068368154e9fb9ecab0 Mon Sep 17 00:00:00 2001 From: Janne Grunau Date: Fri, 28 Oct 2011 19:22:27 +0200 Subject: [PATCH 37/53] seek-test: free options dictionary after use --- libavformat/seek-test.c | 1 + 1 file changed, 1 insertion(+) diff --git a/libavformat/seek-test.c b/libavformat/seek-test.c index 771036087a..363be8a88b 100644 --- a/libavformat/seek-test.c +++ b/libavformat/seek-test.c @@ -81,6 +81,7 @@ int main(int argc, char **argv) filename = argv[1]; ret = avformat_open_input(&ic, filename, NULL, &format_opts); + av_dict_free(&format_opts); if (ret < 0) { fprintf(stderr, "cannot open %s\n", filename); exit(1); From 854eadccb69e44e98aaf94906708839d6c0e4ed0 Mon Sep 17 00:00:00 2001 From: Anton Khirnov Date: Fri, 28 Oct 2011 19:53:55 +0200 Subject: [PATCH 38/53] lavf: add init_put_byte() to the list of visible symbols. --- libavformat/libavformat.v | 1 + 1 file changed, 1 insertion(+) diff --git a/libavformat/libavformat.v b/libavformat/libavformat.v index a99fbcf9a5..c5dc982878 100644 --- a/libavformat/libavformat.v +++ b/libavformat/libavformat.v @@ -24,5 +24,6 @@ LIBAVFORMAT_$MAJOR { udp_set_remote_url; udp_get_local_port; init_checksum; + init_put_byte; local: *; }; From f19305fe93e3b400f4d6f0c3450e40e0605878d0 Mon Sep 17 00:00:00 2001 From: Justin Ruggles Date: Mon, 17 Oct 2011 10:09:52 -0400 Subject: [PATCH 39/53] nellymoserdec: remove pointless buffer size check. --- libavcodec/nellymoserdec.c | 5 ----- 1 file changed, 5 deletions(-) diff --git a/libavcodec/nellymoserdec.c b/libavcodec/nellymoserdec.c index 2d59abf9a8..ec045af16b 100644 --- a/libavcodec/nellymoserdec.c +++ b/libavcodec/nellymoserdec.c @@ -170,11 +170,6 @@ static int decode_tag(AVCodecContext * avctx, int16_t *samples_s16 = data; float *samples_flt = data; - if (buf_size < avctx->block_align) { - *data_size = 0; - return buf_size; - } - if (buf_size % NELLY_BLOCK_LEN) { av_log(avctx, AV_LOG_ERROR, "Tag size %d.\n", buf_size); *data_size = 0; From 0aaa85dbedbd4029dac0e78f10a412c7ec9a0d4d Mon Sep 17 00:00:00 2001 From: Justin Ruggles Date: Mon, 17 Oct 2011 10:22:46 -0400 Subject: [PATCH 40/53] nellymoserdec: fail if output buffer is too small avoids silently truncating the output --- libavcodec/nellymoserdec.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/libavcodec/nellymoserdec.c b/libavcodec/nellymoserdec.c index ec045af16b..3812d78b11 100644 --- a/libavcodec/nellymoserdec.c +++ b/libavcodec/nellymoserdec.c @@ -176,8 +176,12 @@ static int decode_tag(AVCodecContext * avctx, return buf_size; } block_size = NELLY_SAMPLES * av_get_bytes_per_sample(avctx->sample_fmt); - blocks = FFMIN(buf_size / NELLY_BLOCK_LEN, *data_size / block_size); + blocks = buf_size / NELLY_BLOCK_LEN; if (blocks <= 0) { + av_log(avctx, AV_LOG_ERROR, "Packet is too small\n"); + return AVERROR_INVALIDDATA; + } + if (*data_size < blocks * block_size) { av_log(avctx, AV_LOG_ERROR, "Output buffer is too small\n"); return AVERROR(EINVAL); } From 8c9581f052d3724f7ccb893b1e79d5f06f5425d7 Mon Sep 17 00:00:00 2001 From: Justin Ruggles Date: Mon, 17 Oct 2011 10:24:47 -0400 Subject: [PATCH 41/53] nellymoserdec: do not fail if there is extra data in the packet instead just print a warning --- libavcodec/nellymoserdec.c | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/libavcodec/nellymoserdec.c b/libavcodec/nellymoserdec.c index 3812d78b11..53538d0c6b 100644 --- a/libavcodec/nellymoserdec.c +++ b/libavcodec/nellymoserdec.c @@ -170,11 +170,6 @@ static int decode_tag(AVCodecContext * avctx, int16_t *samples_s16 = data; float *samples_flt = data; - if (buf_size % NELLY_BLOCK_LEN) { - av_log(avctx, AV_LOG_ERROR, "Tag size %d.\n", buf_size); - *data_size = 0; - return buf_size; - } block_size = NELLY_SAMPLES * av_get_bytes_per_sample(avctx->sample_fmt); blocks = buf_size / NELLY_BLOCK_LEN; if (blocks <= 0) { @@ -185,6 +180,10 @@ static int decode_tag(AVCodecContext * avctx, av_log(avctx, AV_LOG_ERROR, "Output buffer is too small\n"); return AVERROR(EINVAL); } + if (buf_size % NELLY_BLOCK_LEN) { + av_log(avctx, AV_LOG_WARNING, "Leftover bytes: %d.\n", + buf_size % NELLY_BLOCK_LEN); + } /* Normal numbers of blocks for sample rates: * 8000 Hz - 1 * 11025 Hz - 2 From 77c8ef9a36cf3489420486d356bbaaed72c48592 Mon Sep 17 00:00:00 2001 From: Justin Ruggles Date: Fri, 28 Oct 2011 14:15:25 -0400 Subject: [PATCH 42/53] nellymoserdec: use dsp functions for overlap and windowing --- libavcodec/nellymoserdec.c | 23 ++++------------------- 1 file changed, 4 insertions(+), 19 deletions(-) diff --git a/libavcodec/nellymoserdec.c b/libavcodec/nellymoserdec.c index 53538d0c6b..278b6b3891 100644 --- a/libavcodec/nellymoserdec.c +++ b/libavcodec/nellymoserdec.c @@ -48,7 +48,7 @@ typedef struct NellyMoserDecodeContext { AVCodecContext* avctx; float *float_buf; - float state[NELLY_BUF_LEN]; + DECLARE_ALIGNED(16, float, state)[NELLY_BUF_LEN]; AVLFG random_state; GetBitContext gb; float scale_bias; @@ -58,23 +58,6 @@ typedef struct NellyMoserDecodeContext { DECLARE_ALIGNED(32, float, imdct_out)[NELLY_BUF_LEN * 2]; } NellyMoserDecodeContext; -static void overlap_and_window(NellyMoserDecodeContext *s, float *state, float *audio, float *a_in) -{ - int bot, top; - - bot = 0; - top = NELLY_BUF_LEN-1; - - while (bot < NELLY_BUF_LEN) { - audio[bot] = a_in [bot]*ff_sine_128[bot] - +state[bot]*ff_sine_128[top]; - - bot++; - top--; - } - memcpy(state, a_in + NELLY_BUF_LEN, sizeof(float)*NELLY_BUF_LEN); -} - static void nelly_decode_block(NellyMoserDecodeContext *s, const unsigned char block[NELLY_BLOCK_LEN], float audio[NELLY_SAMPLES]) @@ -125,7 +108,9 @@ static void nelly_decode_block(NellyMoserDecodeContext *s, s->imdct_ctx.imdct_calc(&s->imdct_ctx, s->imdct_out, aptr); /* XXX: overlapping and windowing should be part of a more generic imdct function */ - overlap_and_window(s, s->state, aptr, s->imdct_out); + s->dsp.vector_fmul_reverse(s->state, s->state, ff_sine_128, NELLY_BUF_LEN); + s->dsp.vector_fmul_add(aptr, s->imdct_out, ff_sine_128, s->state, NELLY_BUF_LEN); + memcpy(s->state, s->imdct_out + NELLY_BUF_LEN, sizeof(float)*NELLY_BUF_LEN); } } From f3db0f7403f652428930dd77d5fd049b8165c54a Mon Sep 17 00:00:00 2001 From: Justin Ruggles Date: Mon, 24 Oct 2011 08:44:24 -0400 Subject: [PATCH 43/53] nellymoserenc: take float input samples instead of int16 This avoids having to convert all input data from int16 to float, which is used internally for encoding. --- libavcodec/nellymoserenc.c | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/libavcodec/nellymoserenc.c b/libavcodec/nellymoserenc.c index 0f94e75c92..0f521db1e9 100644 --- a/libavcodec/nellymoserenc.c +++ b/libavcodec/nellymoserenc.c @@ -146,7 +146,7 @@ static av_cold int encode_init(AVCodecContext *avctx) avctx->frame_size = NELLY_SAMPLES; s->avctx = avctx; - ff_mdct_init(&s->mdct_ctx, 8, 0, 1.0); + ff_mdct_init(&s->mdct_ctx, 8, 0, 32768.0); dsputil_init(&s->dsp, avctx); /* Generate overlap window */ @@ -352,17 +352,15 @@ static void encode_block(NellyMoserEncodeContext *s, unsigned char *output, int static int encode_frame(AVCodecContext *avctx, uint8_t *frame, int buf_size, void *data) { NellyMoserEncodeContext *s = avctx->priv_data; - const int16_t *samples = data; + const float *samples = data; int i; if (s->last_frame) return 0; if (data) { - for (i = 0; i < avctx->frame_size; i++) { - s->buf[s->bufsel][i] = samples[i]; - } - for (; i < NELLY_SAMPLES; i++) { + memcpy(s->buf[s->bufsel], samples, avctx->frame_size * sizeof(*samples)); + for (i = avctx->frame_size; i < NELLY_SAMPLES; i++) { s->buf[s->bufsel][i] = 0; } s->bufsel = 1 - s->bufsel; @@ -393,5 +391,5 @@ AVCodec ff_nellymoser_encoder = { .close = encode_end, .capabilities = CODEC_CAP_SMALL_LAST_FRAME | CODEC_CAP_DELAY, .long_name = NULL_IF_CONFIG_SMALL("Nellymoser Asao"), - .sample_fmts = (const enum AVSampleFormat[]){AV_SAMPLE_FMT_S16,AV_SAMPLE_FMT_NONE}, + .sample_fmts = (const enum AVSampleFormat[]){AV_SAMPLE_FMT_FLT,AV_SAMPLE_FMT_NONE}, }; From bc2dd36740ef13d1f95c243ff58167fafb3d9a51 Mon Sep 17 00:00:00 2001 From: Michael Niedermayer Date: Fri, 21 Oct 2011 09:41:35 +0000 Subject: [PATCH 44/53] aacdec: allow output reconfiguration on channel changes Locking the decoder against channel config changes in parse_adts_frame_header() seems to be unnecessary and streams with channel config changes are reported. The sample in http://roundup.libav.org/issue999 still works. Signed-off-by: Janne Grunau --- libavcodec/aacdec.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libavcodec/aacdec.c b/libavcodec/aacdec.c index ca69e77e29..203ecd3423 100644 --- a/libavcodec/aacdec.c +++ b/libavcodec/aacdec.c @@ -2079,7 +2079,7 @@ static int parse_adts_frame_header(AACContext *ac, GetBitContext *gb) size = avpriv_aac_parse_header(gb, &hdr_info); if (size > 0) { - if (ac->output_configured != OC_LOCKED && hdr_info.chan_config) { + if (hdr_info.chan_config) { enum ChannelPosition new_che_pos[4][MAX_ELEM_ID]; memset(new_che_pos, 0, 4 * MAX_ELEM_ID * sizeof(new_che_pos[0][0])); ac->m4ac.chan_config = hdr_info.chan_config; From 77b5c82b49dacfab9966df2d7532ae155478769e Mon Sep 17 00:00:00 2001 From: Alex Converse Date: Wed, 5 Oct 2011 10:59:15 -0700 Subject: [PATCH 45/53] isom: Add MPEG4SYSTEMS dummy object type indication. --- libavcodec/avcodec.h | 2 ++ libavformat/isom.c | 2 ++ 2 files changed, 4 insertions(+) diff --git a/libavcodec/avcodec.h b/libavcodec/avcodec.h index 1c9bd96a5f..649bce488c 100644 --- a/libavcodec/avcodec.h +++ b/libavcodec/avcodec.h @@ -372,6 +372,8 @@ enum CodecID { CODEC_ID_MPEG2TS= 0x20000, /**< _FAKE_ codec to indicate a raw MPEG-2 TS * stream (only used by libavformat) */ + CODEC_ID_MPEG4SYSTEMS = 0x20001, /**< _FAKE_ codec to indicate a MPEG-4 Systems + * stream (only used by libavformat) */ CODEC_ID_FFMETADATA=0x21000, ///< Dummy codec for streams containing only metadata information. }; diff --git a/libavformat/isom.c b/libavformat/isom.c index c5b01f22e3..b0eef375c6 100644 --- a/libavformat/isom.c +++ b/libavformat/isom.c @@ -61,6 +61,8 @@ const AVCodecTag ff_mp4_obj_type[] = { { CODEC_ID_VORBIS , 0xDD }, /* non standard, gpac uses it */ { CODEC_ID_DVD_SUBTITLE, 0xE0 }, /* non standard, see unsupported-embedded-subs-2.mp4 */ { CODEC_ID_QCELP , 0xE1 }, + { CODEC_ID_MPEG4SYSTEMS, 0x01 }, + { CODEC_ID_MPEG4SYSTEMS, 0x02 }, { CODEC_ID_NONE , 0 }, }; From 476d04a56ac499b9a5a081646d9737d956f24130 Mon Sep 17 00:00:00 2001 From: Alex Converse Date: Tue, 4 Oct 2011 18:24:22 -0700 Subject: [PATCH 46/53] mpegts: Parse mpeg2 SL descriptors. --- libavformat/mpegts.c | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/libavformat/mpegts.c b/libavformat/mpegts.c index 5668f546f6..faa834d3cf 100644 --- a/libavformat/mpegts.c +++ b/libavformat/mpegts.c @@ -909,7 +909,7 @@ int ff_parse_mpeg2_descriptor(AVFormatContext *fc, AVStream *st, int stream_type uint8_t *mp4_dec_config_descr) { const uint8_t *desc_end; - int desc_len, desc_tag; + int desc_len, desc_tag, desc_es_id; char language[252]; int i; @@ -930,6 +930,18 @@ int ff_parse_mpeg2_descriptor(AVFormatContext *fc, AVStream *st, int stream_type mpegts_find_stream_type(st, desc_tag, DESC_types); switch(desc_tag) { + case 0x1E: /* SL descriptor */ + desc_es_id = get16(pp, desc_end); + if (mp4_dec_config_descr_len && mp4_es_id == desc_es_id) { + AVIOContext pb; + ffio_init_context(&pb, mp4_dec_config_descr, + mp4_dec_config_descr_len, 0, NULL, NULL, NULL, NULL); + ff_mp4_read_dec_config_descr(fc, st, &pb); + if (st->codec->codec_id == CODEC_ID_AAC && + st->codec->extradata_size > 0) + st->need_parsing = 0; + } + break; case 0x1F: /* FMC descriptor */ get16(pp, desc_end); if (st->codec->codec_id == CODEC_ID_AAC_LATM && From c3bc6096f234151a09f79c6d1c0360bc08dde9d8 Mon Sep 17 00:00:00 2001 From: Alex Converse Date: Tue, 4 Oct 2011 23:43:59 -0700 Subject: [PATCH 47/53] mpegts: Add support for multiple mp4 descriptors --- libavformat/mpegts.c | 40 ++++++++++++++++++++++++---------------- libavformat/mpegts.h | 9 +++++++-- libavformat/wtv.c | 2 +- 3 files changed, 32 insertions(+), 19 deletions(-) diff --git a/libavformat/mpegts.c b/libavformat/mpegts.c index faa834d3cf..0284c3987e 100644 --- a/libavformat/mpegts.c +++ b/libavformat/mpegts.c @@ -42,6 +42,8 @@ #define MAX_PES_PAYLOAD 200*1024 +#define MAX_MP4_DESCR_COUNT 16 + enum MpegTSFilterType { MPEGTS_PES, MPEGTS_SECTION, @@ -905,8 +907,7 @@ static int mp4_read_iods(AVFormatContext *s, const uint8_t *buf, unsigned size, int ff_parse_mpeg2_descriptor(AVFormatContext *fc, AVStream *st, int stream_type, const uint8_t **pp, const uint8_t *desc_list_end, - int mp4_dec_config_descr_len, int mp4_es_id, int pid, - uint8_t *mp4_dec_config_descr) + Mp4Descr *mp4_descr, int mp4_descr_count, int pid) { const uint8_t *desc_end; int desc_len, desc_tag, desc_es_id; @@ -932,10 +933,12 @@ int ff_parse_mpeg2_descriptor(AVFormatContext *fc, AVStream *st, int stream_type switch(desc_tag) { case 0x1E: /* SL descriptor */ desc_es_id = get16(pp, desc_end); - if (mp4_dec_config_descr_len && mp4_es_id == desc_es_id) { + for (i = 0; i < mp4_descr_count; i++) + if (mp4_descr[i].dec_config_descr_len && + mp4_descr[i].es_id == desc_es_id) { AVIOContext pb; - ffio_init_context(&pb, mp4_dec_config_descr, - mp4_dec_config_descr_len, 0, NULL, NULL, NULL, NULL); + ffio_init_context(&pb, mp4_descr[i].dec_config_descr, + mp4_descr[i].dec_config_descr_len, 0, NULL, NULL, NULL, NULL); ff_mp4_read_dec_config_descr(fc, st, &pb); if (st->codec->codec_id == CODEC_ID_AAC && st->codec->extradata_size > 0) @@ -944,11 +947,11 @@ int ff_parse_mpeg2_descriptor(AVFormatContext *fc, AVStream *st, int stream_type break; case 0x1F: /* FMC descriptor */ get16(pp, desc_end); - if (st->codec->codec_id == CODEC_ID_AAC_LATM && - mp4_dec_config_descr_len && mp4_es_id == pid) { + if (mp4_descr_count > 0 && st->codec->codec_id == CODEC_ID_AAC_LATM && + mp4_descr->dec_config_descr_len && mp4_descr->es_id == pid) { AVIOContext pb; - ffio_init_context(&pb, mp4_dec_config_descr, - mp4_dec_config_descr_len, 0, NULL, NULL, NULL, NULL); + ffio_init_context(&pb, mp4_descr->dec_config_descr, + mp4_descr->dec_config_descr_len, 0, NULL, NULL, NULL, NULL); ff_mp4_read_dec_config_descr(fc, st, &pb); if (st->codec->codec_id == CODEC_ID_AAC && st->codec->extradata_size > 0) @@ -1032,9 +1035,10 @@ static void pmt_cb(MpegTSFilter *filter, const uint8_t *section, int section_len int program_info_length, pcr_pid, pid, stream_type; int desc_list_len; uint32_t prog_reg_desc = 0; /* registration descriptor */ - uint8_t *mp4_dec_config_descr = NULL; - int mp4_dec_config_descr_len = 0; - int mp4_es_id = 0; + + Mp4Descr mp4_descr[MAX_MP4_DESCR_COUNT] = {{ 0 }}; + int mp4_descr_count = 0; + int i; av_dlog(ts->stream, "PMT: len %i\n", section_len); hex_dump_debug(ts->stream, (uint8_t *)section, section_len); @@ -1076,8 +1080,11 @@ static void pmt_cb(MpegTSFilter *filter, const uint8_t *section, int section_len get8(&p, p_end); // scope get8(&p, p_end); // label len -= 2; - mp4_read_iods(ts->stream, p, len, &mp4_es_id, - &mp4_dec_config_descr, &mp4_dec_config_descr_len); + if (mp4_descr_count < MAX_MP4_DESCR_COUNT) { + mp4_descr_count++; + mp4_read_iods(ts->stream, p, len, &mp4_descr->es_id, + &mp4_descr->dec_config_descr, &mp4_descr->dec_config_descr_len); + } } else if (tag == 0x05 && len >= 4) { // registration descriptor prog_reg_desc = bytestream_get_le32(&p); len -= 4; @@ -1136,7 +1143,7 @@ static void pmt_cb(MpegTSFilter *filter, const uint8_t *section, int section_len break; for(;;) { if (ff_parse_mpeg2_descriptor(ts->stream, st, stream_type, &p, desc_list_end, - mp4_dec_config_descr_len, mp4_es_id, pid, mp4_dec_config_descr) < 0) + mp4_descr, mp4_descr_count, pid) < 0) break; if (prog_reg_desc == AV_RL32("HDMV") && stream_type == 0x83 && pes->sub_st) { @@ -1148,7 +1155,8 @@ static void pmt_cb(MpegTSFilter *filter, const uint8_t *section, int section_len } out: - av_free(mp4_dec_config_descr); + for (i = 0; i < mp4_descr_count; i++) + av_free(mp4_descr[i].dec_config_descr); } static void pat_cb(MpegTSFilter *filter, const uint8_t *section, int section_len) diff --git a/libavformat/mpegts.h b/libavformat/mpegts.h index 73ef2ed10a..15eee60782 100644 --- a/libavformat/mpegts.h +++ b/libavformat/mpegts.h @@ -64,6 +64,12 @@ int ff_mpegts_parse_packet(MpegTSContext *ts, AVPacket *pkt, const uint8_t *buf, int len); void ff_mpegts_parse_close(MpegTSContext *ts); +typedef struct { + int es_id; + int dec_config_descr_len; + uint8_t *dec_config_descr; +} Mp4Descr; + /** * Parse an MPEG-2 descriptor * @param[in] fc Format context (used for logging only) @@ -79,7 +85,6 @@ void ff_mpegts_parse_close(MpegTSContext *ts); */ int ff_parse_mpeg2_descriptor(AVFormatContext *fc, AVStream *st, int stream_type, const uint8_t **pp, const uint8_t *desc_list_end, - int mp4_dec_config_descr_len, int mp4_es_id, int pid, - uint8_t *mp4_dec_config_descr); + Mp4Descr *mp4_descr, int mp4_descr_count, int pid); #endif /* AVFORMAT_MPEGTS_H */ diff --git a/libavformat/wtv.c b/libavformat/wtv.c index 4defc14e3c..f848968d72 100644 --- a/libavformat/wtv.c +++ b/libavformat/wtv.c @@ -837,7 +837,7 @@ static int parse_chunks(AVFormatContext *s, int mode, int64_t seekts, int *len_p buf_size = FFMIN(len - consumed, sizeof(buf)); avio_read(pb, buf, buf_size); consumed += buf_size; - ff_parse_mpeg2_descriptor(s, st, 0, &pbuf, buf + buf_size, 0, 0, 0, 0); + ff_parse_mpeg2_descriptor(s, st, 0, &pbuf, buf + buf_size, NULL, 0, 0); } } else if (!ff_guidcmp(g, EVENTID_AudioTypeSpanningEvent)) { int stream_index = ff_find_stream_index(s, sid); From fec2836483c15f169c3f8be39347978f1698ae8d Mon Sep 17 00:00:00 2001 From: Alex Converse Date: Wed, 5 Oct 2011 11:04:42 -0700 Subject: [PATCH 48/53] mpegts: Replace the MP4 descriptor parser with a recursive parser. --- libavformat/mpegts.c | 172 ++++++++++++++++++++++++++++++++++--------- 1 file changed, 139 insertions(+), 33 deletions(-) diff --git a/libavformat/mpegts.c b/libavformat/mpegts.c index 0284c3987e..3703d2cdaa 100644 --- a/libavformat/mpegts.c +++ b/libavformat/mpegts.c @@ -870,41 +870,150 @@ static PESContext *add_pes_stream(MpegTSContext *ts, int pid, int pcr_pid) return pes; } -static int mp4_read_iods(AVFormatContext *s, const uint8_t *buf, unsigned size, - int *es_id, uint8_t **dec_config_descr, - int *dec_config_descr_size) -{ +#define MAX_LEVEL 4 +typedef struct { + AVFormatContext *s; AVIOContext pb; - int tag; - unsigned len; + Mp4Descr *descr; + Mp4Descr *active_descr; + int descr_count; + int max_descr_count; + int level; +} MP4DescrParseContext; - ffio_init_context(&pb, buf, size, 0, NULL, NULL, NULL, NULL); +static int init_MP4DescrParseContext( + MP4DescrParseContext *d, AVFormatContext *s, const uint8_t *buf, + unsigned size, Mp4Descr *descr, int max_descr_count) +{ + int ret; + if (size > (1<<30)) + return AVERROR_INVALIDDATA; - len = ff_mp4_read_descr(s, &pb, &tag); - if (tag == MP4IODescrTag) { - avio_rb16(&pb); // ID - avio_r8(&pb); - avio_r8(&pb); - avio_r8(&pb); - avio_r8(&pb); - avio_r8(&pb); - len = ff_mp4_read_descr(s, &pb, &tag); - if (tag == MP4ESDescrTag) { - ff_mp4_parse_es_descr(&pb, es_id); - av_dlog(s, "ES_ID %#x\n", *es_id); - len = ff_mp4_read_descr(s, &pb, &tag); - if (tag == MP4DecConfigDescrTag) { - *dec_config_descr = av_malloc(len); - if (!*dec_config_descr) - return AVERROR(ENOMEM); - *dec_config_descr_size = len; - avio_read(&pb, *dec_config_descr, len); - } - } + if ((ret = ffio_init_context(&d->pb, (unsigned char*)buf, size, 0, + NULL, NULL, NULL, NULL)) < 0) + return ret; + + d->s = s; + d->level = 0; + d->descr_count = 0; + d->descr = descr; + d->active_descr = NULL; + d->max_descr_count = max_descr_count; + + return 0; +} + +static void update_offsets(AVIOContext *pb, int64_t *off, int *len) { + int64_t new_off = avio_tell(pb); + (*len) -= new_off - *off; + *off = new_off; +} + +static int parse_mp4_descr(MP4DescrParseContext *d, int64_t off, int len, + int target_tag); + +static int parse_mp4_descr_arr(MP4DescrParseContext *d, int64_t off, int len) +{ + while (len > 0) { + if (parse_mp4_descr(d, off, len, 0) < 0) + return -1; + update_offsets(&d->pb, &off, &len); } return 0; } +static int parse_MP4IODescrTag(MP4DescrParseContext *d, int64_t off, int len) +{ + avio_rb16(&d->pb); // ID + avio_r8(&d->pb); + avio_r8(&d->pb); + avio_r8(&d->pb); + avio_r8(&d->pb); + avio_r8(&d->pb); + update_offsets(&d->pb, &off, &len); + return parse_mp4_descr_arr(d, off, len); +} + +static int parse_MP4ESDescrTag(MP4DescrParseContext *d, int64_t off, int len) +{ + int es_id = 0; + if (d->descr_count >= d->max_descr_count) + return -1; + ff_mp4_parse_es_descr(&d->pb, &es_id); + d->active_descr = d->descr + (d->descr_count++); + + d->active_descr->es_id = es_id; + update_offsets(&d->pb, &off, &len); + parse_mp4_descr(d, off, len, MP4DecConfigDescrTag); + //SLConfigDescriptor + d->active_descr = NULL; + return 0; +} + +static int parse_MP4DecConfigDescrTag(MP4DescrParseContext *d, int64_t off, int len) +{ + Mp4Descr *descr = d->active_descr; + if (!descr) + return -1; + d->active_descr->dec_config_descr = av_malloc(len); + if (!descr->dec_config_descr) + return AVERROR(ENOMEM); + descr->dec_config_descr_len = len; + avio_read(&d->pb, descr->dec_config_descr, len); + return 0; +} + +static int parse_mp4_descr(MP4DescrParseContext *d, int64_t off, int len, + int target_tag) { + int tag; + int len1 = ff_mp4_read_descr(d->s, &d->pb, &tag); + update_offsets(&d->pb, &off, &len); + if (len < 0 || len1 > len || len1 <= 0) { + av_log(d->s, AV_LOG_ERROR, "Tag %x length violation new length %d bytes remaining %d\n", tag, len1, len); + return -1; + } + + if (d->level++ >= MAX_LEVEL) { + av_log(d->s, AV_LOG_ERROR, "Maximum MP4 descriptor level exceeded\n"); + goto done; + } + + if (target_tag && tag != target_tag) { + av_log(d->s, AV_LOG_ERROR, "Found tag %x expected %x\n", tag, target_tag); + goto done; + } + + switch (tag) { + case MP4IODescrTag: + parse_MP4IODescrTag(d, off, len1); + break; + case MP4ESDescrTag: + parse_MP4ESDescrTag(d, off, len1); + break; + case MP4DecConfigDescrTag: + parse_MP4DecConfigDescrTag(d, off, len1); + break; + } + +done: + d->level--; + avio_seek(&d->pb, off + len1, SEEK_SET); + return 0; +} + +static int mp4_read_iods(AVFormatContext *s, const uint8_t *buf, unsigned size, + Mp4Descr *descr, int *descr_count, int max_descr_count) +{ + MP4DescrParseContext d; + if (init_MP4DescrParseContext(&d, s, buf, size, descr, max_descr_count) < 0) + return -1; + + parse_mp4_descr(&d, avio_tell(&d.pb), size, MP4IODescrTag); + + *descr_count = d.descr_count; + return 0; +} + int ff_parse_mpeg2_descriptor(AVFormatContext *fc, AVStream *st, int stream_type, const uint8_t **pp, const uint8_t *desc_list_end, Mp4Descr *mp4_descr, int mp4_descr_count, int pid) @@ -1080,11 +1189,8 @@ static void pmt_cb(MpegTSFilter *filter, const uint8_t *section, int section_len get8(&p, p_end); // scope get8(&p, p_end); // label len -= 2; - if (mp4_descr_count < MAX_MP4_DESCR_COUNT) { - mp4_descr_count++; - mp4_read_iods(ts->stream, p, len, &mp4_descr->es_id, - &mp4_descr->dec_config_descr, &mp4_descr->dec_config_descr_len); - } + mp4_read_iods(ts->stream, p, len, mp4_descr + mp4_descr_count, + &mp4_descr_count, MAX_MP4_DESCR_COUNT); } else if (tag == 0x05 && len >= 4) { // registration descriptor prog_reg_desc = bytestream_get_le32(&p); len -= 4; From 4682a1dc3aa2554ad7077f5db32d0f2d598d018e Mon Sep 17 00:00:00 2001 From: Alex Converse Date: Wed, 5 Oct 2011 18:24:17 -0700 Subject: [PATCH 49/53] mpegts: Add support for Sections in PMT --- libavformat/mpegts.c | 40 +++++++++++++++++++++++++++++++++++----- libavformat/mpegts.h | 4 +++- libavformat/wtv.c | 2 +- 3 files changed, 39 insertions(+), 7 deletions(-) diff --git a/libavformat/mpegts.c b/libavformat/mpegts.c index 3703d2cdaa..abc3596d91 100644 --- a/libavformat/mpegts.c +++ b/libavformat/mpegts.c @@ -1014,9 +1014,28 @@ static int mp4_read_iods(AVFormatContext *s, const uint8_t *buf, unsigned size, return 0; } +static void m4sl_cb(MpegTSFilter *filter, const uint8_t *section, int section_len) +{ + MpegTSContext *ts = filter->u.section_filter.opaque; + SectionHeader h1, *h = &h1; + const uint8_t *p, *p_end; + + av_dlog(ts->stream, "m4SL/od:\n"); + hex_dump_debug(ts->stream, (uint8_t *)section, section_len); + + p_end = section + section_len - 4; + p = section; + if (parse_section_header(h, &p, p_end) < 0) + return; + if (h->tid != M4OD_TID) + return; + +} + int ff_parse_mpeg2_descriptor(AVFormatContext *fc, AVStream *st, int stream_type, const uint8_t **pp, const uint8_t *desc_list_end, - Mp4Descr *mp4_descr, int mp4_descr_count, int pid) + Mp4Descr *mp4_descr, int mp4_descr_count, int pid, + MpegTSContext *ts) { const uint8_t *desc_end; int desc_len, desc_tag, desc_es_id; @@ -1052,6 +1071,8 @@ int ff_parse_mpeg2_descriptor(AVFormatContext *fc, AVStream *st, int stream_type if (st->codec->codec_id == CODEC_ID_AAC && st->codec->extradata_size > 0) st->need_parsing = 0; + if (st->codec->codec_id == CODEC_ID_MPEG4SYSTEMS) + mpegts_open_section_filter(ts, pid, m4sl_cb, ts, 1); } break; case 0x1F: /* FMC descriptor */ @@ -1207,6 +1228,7 @@ static void pmt_cb(MpegTSFilter *filter, const uint8_t *section, int section_len for(;;) { st = 0; + pes = NULL; stream_type = get8(&p, p_end); if (stream_type < 0) break; @@ -1222,19 +1244,27 @@ static void pmt_cb(MpegTSFilter *filter, const uint8_t *section, int section_len st->id = pes->pid; } st = pes->st; - } else { + } else if (stream_type != 0x13) { if (ts->pids[pid]) mpegts_close_filter(ts, ts->pids[pid]); //wrongly added sdt filter probably pes = add_pes_stream(ts, pid, pcr_pid); if (pes) { st = avformat_new_stream(pes->stream, NULL); st->id = pes->pid; } + } else { + int idx = ff_find_stream_index(ts->stream, pid); + if (idx >= 0) { + st = ts->stream->streams[idx]; + } else { + st = avformat_new_stream(pes->stream, NULL); + st->id = pid; + } } if (!st) goto out; - if (!pes->stream_type) + if (pes && !pes->stream_type) mpegts_set_stream_info(st, pes, stream_type, prog_reg_desc); add_pid_to_pmt(ts, h->id, pid); @@ -1249,10 +1279,10 @@ static void pmt_cb(MpegTSFilter *filter, const uint8_t *section, int section_len break; for(;;) { if (ff_parse_mpeg2_descriptor(ts->stream, st, stream_type, &p, desc_list_end, - mp4_descr, mp4_descr_count, pid) < 0) + mp4_descr, mp4_descr_count, pid, ts) < 0) break; - if (prog_reg_desc == AV_RL32("HDMV") && stream_type == 0x83 && pes->sub_st) { + if (pes && prog_reg_desc == AV_RL32("HDMV") && stream_type == 0x83 && pes->sub_st) { ff_program_add_stream_index(ts->stream, h->id, pes->sub_st->index); pes->sub_st->codec->codec_tag = st->codec->codec_tag; } diff --git a/libavformat/mpegts.h b/libavformat/mpegts.h index 15eee60782..560637b4fe 100644 --- a/libavformat/mpegts.h +++ b/libavformat/mpegts.h @@ -39,6 +39,7 @@ /* table ids */ #define PAT_TID 0x00 #define PMT_TID 0x02 +#define M4OD_TID 0x05 #define SDT_TID 0x42 #define STREAM_TYPE_VIDEO_MPEG1 0x01 @@ -85,6 +86,7 @@ typedef struct { */ int ff_parse_mpeg2_descriptor(AVFormatContext *fc, AVStream *st, int stream_type, const uint8_t **pp, const uint8_t *desc_list_end, - Mp4Descr *mp4_descr, int mp4_descr_count, int pid); + Mp4Descr *mp4_descr, int mp4_descr_count, int pid, + MpegTSContext *ts); #endif /* AVFORMAT_MPEGTS_H */ diff --git a/libavformat/wtv.c b/libavformat/wtv.c index f848968d72..cdb5c49fb6 100644 --- a/libavformat/wtv.c +++ b/libavformat/wtv.c @@ -837,7 +837,7 @@ static int parse_chunks(AVFormatContext *s, int mode, int64_t seekts, int *len_p buf_size = FFMIN(len - consumed, sizeof(buf)); avio_read(pb, buf, buf_size); consumed += buf_size; - ff_parse_mpeg2_descriptor(s, st, 0, &pbuf, buf + buf_size, NULL, 0, 0); + ff_parse_mpeg2_descriptor(s, st, 0, &pbuf, buf + buf_size, NULL, 0, 0, NULL); } } else if (!ff_guidcmp(g, EVENTID_AudioTypeSpanningEvent)) { int stream_index = ff_find_stream_index(s, sid); From c5302670244bd587d6ff3b6e8ef73451d1c01211 Mon Sep 17 00:00:00 2001 From: Alex Converse Date: Mon, 10 Oct 2011 12:50:00 -0700 Subject: [PATCH 50/53] mpegts: MP4 OD support --- libavformat/isom.h | 1 + libavformat/mpegts.c | 88 ++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 89 insertions(+) diff --git a/libavformat/isom.h b/libavformat/isom.h index 838eb42f97..04edb1f1cf 100644 --- a/libavformat/isom.h +++ b/libavformat/isom.h @@ -148,6 +148,7 @@ int ff_mp4_read_descr(AVFormatContext *fc, AVIOContext *pb, int *tag); int ff_mp4_read_dec_config_descr(AVFormatContext *fc, AVStream *st, AVIOContext *pb); void ff_mp4_parse_es_descr(AVIOContext *pb, int *es_id); +#define MP4ODescrTag 0x01 #define MP4IODescrTag 0x02 #define MP4ESDescrTag 0x03 #define MP4DecConfigDescrTag 0x04 diff --git a/libavformat/mpegts.c b/libavformat/mpegts.c index abc3596d91..4c9462cead 100644 --- a/libavformat/mpegts.c +++ b/libavformat/mpegts.c @@ -74,6 +74,7 @@ typedef struct MpegTSSectionFilter { struct MpegTSFilter { int pid; + int es_id; int last_cc; /* last cc code (-1 if first packet) */ enum MpegTSFilterType type; union { @@ -317,6 +318,7 @@ static MpegTSFilter *mpegts_open_section_filter(MpegTSContext *ts, unsigned int ts->pids[pid] = filter; filter->type = MPEGTS_SECTION; filter->pid = pid; + filter->es_id = -1; filter->last_cc = -1; sec = &filter->u.section_filter; sec->section_cb = section_cb; @@ -345,6 +347,7 @@ static MpegTSFilter *mpegts_open_pes_filter(MpegTSContext *ts, unsigned int pid, ts->pids[pid] = filter; filter->type = MPEGTS_PES; filter->pid = pid; + filter->es_id = -1; filter->last_cc = -1; pes = &filter->u.pes_filter; pes->pes_cb = pes_cb; @@ -934,6 +937,20 @@ static int parse_MP4IODescrTag(MP4DescrParseContext *d, int64_t off, int len) return parse_mp4_descr_arr(d, off, len); } +static int parse_MP4ODescrTag(MP4DescrParseContext *d, int64_t off, int len) +{ + int id_flags; + if (len < 2) + return 0; + id_flags = avio_rb16(&d->pb); + if (!(id_flags & 0x0020)) { //URL_Flag + update_offsets(&d->pb, &off, &len); + return parse_mp4_descr_arr(d, off, len); //ES_Descriptor[] + } else { + return 0; + } +} + static int parse_MP4ESDescrTag(MP4DescrParseContext *d, int64_t off, int len) { int es_id = 0; @@ -987,6 +1004,9 @@ static int parse_mp4_descr(MP4DescrParseContext *d, int64_t off, int len, case MP4IODescrTag: parse_MP4IODescrTag(d, off, len1); break; + case MP4ODescrTag: + parse_MP4ODescrTag(d, off, len1); + break; case MP4ESDescrTag: parse_MP4ESDescrTag(d, off, len1); break; @@ -1014,6 +1034,70 @@ static int mp4_read_iods(AVFormatContext *s, const uint8_t *buf, unsigned size, return 0; } +static int mp4_read_od(AVFormatContext *s, const uint8_t *buf, unsigned size, + Mp4Descr *descr, int *descr_count, int max_descr_count) +{ + MP4DescrParseContext d; + if (init_MP4DescrParseContext(&d, s, buf, size, descr, max_descr_count) < 0) + return -1; + + parse_mp4_descr_arr(&d, avio_tell(&d.pb), size); + + *descr_count = d.descr_count; + return 0; +} + +static void SL_packet(AVFormatContext *s, MpegTSContext *ts, const uint8_t *p, const uint8_t *p_end) +{ + AVIOContext pb; + Mp4Descr mp4_descr[MAX_MP4_DESCR_COUNT] = {{ 0 }}; + int mp4_descr_count = 0; + int i, pid; + + mp4_read_od(s, p, (unsigned)(p_end - p), mp4_descr, &mp4_descr_count, MAX_MP4_DESCR_COUNT); + + for (pid = 0; pid < NB_PID_MAX; pid++) { + if (!ts->pids[pid]) + continue; + for (i = 0; i < mp4_descr_count; i++) { + PESContext *pes; + AVStream *st; + if (ts->pids[pid]->es_id != mp4_descr[i].es_id) + continue; + if (!(ts->pids[pid] && ts->pids[pid]->type == MPEGTS_PES)) { + av_log(s, AV_LOG_ERROR, "pid %x is not PES\n", pid); + continue; + } + pes = ts->pids[pid]->u.pes_filter.opaque; + st = pes->st; + if (!st) { + continue; + } + + ffio_init_context(&pb, mp4_descr[i].dec_config_descr, + mp4_descr[i].dec_config_descr_len, 0, NULL, NULL, NULL, NULL); + ff_mp4_read_dec_config_descr(s, st, &pb); + if (st->codec->codec_id == CODEC_ID_AAC && + st->codec->extradata_size > 0) + st->need_parsing = 0; + if (st->codec->codec_id == CODEC_ID_H264 && + st->codec->extradata_size > 0) + st->need_parsing = 0; + + if (st->codec->codec_id <= CODEC_ID_NONE) { + } else if (st->codec->codec_id < CODEC_ID_FIRST_AUDIO) { + st->codec->codec_type = AVMEDIA_TYPE_VIDEO; + } else if (st->codec->codec_id < CODEC_ID_FIRST_SUBTITLE) { + st->codec->codec_type = AVMEDIA_TYPE_AUDIO; + } else if (st->codec->codec_id < CODEC_ID_FIRST_UNKNOWN) { + st->codec->codec_type = AVMEDIA_TYPE_SUBTITLE; + } + } + } + for (i = 0; i < mp4_descr_count; i++) + av_free(mp4_descr[i].dec_config_descr); +} + static void m4sl_cb(MpegTSFilter *filter, const uint8_t *section, int section_len) { MpegTSContext *ts = filter->u.section_filter.opaque; @@ -1030,6 +1114,7 @@ static void m4sl_cb(MpegTSFilter *filter, const uint8_t *section, int section_le if (h->tid != M4OD_TID) return; + SL_packet(ts->stream, ts, p, p_end); } int ff_parse_mpeg2_descriptor(AVFormatContext *fc, AVStream *st, int stream_type, @@ -1061,6 +1146,8 @@ int ff_parse_mpeg2_descriptor(AVFormatContext *fc, AVStream *st, int stream_type switch(desc_tag) { case 0x1E: /* SL descriptor */ desc_es_id = get16(pp, desc_end); + if (ts && ts->pids[pid]) + ts->pids[pid]->es_id = desc_es_id; for (i = 0; i < mp4_descr_count; i++) if (mp4_descr[i].dec_config_descr_len && mp4_descr[i].es_id == desc_es_id) { @@ -1258,6 +1345,7 @@ static void pmt_cb(MpegTSFilter *filter, const uint8_t *section, int section_len } else { st = avformat_new_stream(pes->stream, NULL); st->id = pid; + st->codec->codec_type = AVMEDIA_TYPE_DATA; } } From ca65932bbf2a4851838f84456050e2972091950d Mon Sep 17 00:00:00 2001 From: Alex Converse Date: Tue, 11 Oct 2011 14:49:59 -0700 Subject: [PATCH 51/53] mpegts: MP4 SL support --- libavformat/isom.h | 1 + libavformat/mpegts.c | 159 +++++++++++++++++++++++++++++++++++++------ libavformat/mpegts.h | 18 +++++ 3 files changed, 157 insertions(+), 21 deletions(-) diff --git a/libavformat/isom.h b/libavformat/isom.h index 04edb1f1cf..e6d04dc526 100644 --- a/libavformat/isom.h +++ b/libavformat/isom.h @@ -153,6 +153,7 @@ void ff_mp4_parse_es_descr(AVIOContext *pb, int *es_id); #define MP4ESDescrTag 0x03 #define MP4DecConfigDescrTag 0x04 #define MP4DecSpecificDescrTag 0x05 +#define MP4SLDescrTag 0x06 int ff_mov_read_esds(AVFormatContext *fc, AVIOContext *pb, MOVAtom atom); enum CodecID ff_mov_get_lpcm_codec_id(int bps, int flags); diff --git a/libavformat/mpegts.c b/libavformat/mpegts.c index 4c9462cead..5fa82dc21a 100644 --- a/libavformat/mpegts.c +++ b/libavformat/mpegts.c @@ -28,6 +28,7 @@ #include "libavutil/mathematics.h" #include "libavutil/opt.h" #include "libavcodec/bytestream.h" +#include "libavcodec/get_bits.h" #include "avformat.h" #include "mpegts.h" #include "internal.h" @@ -175,6 +176,7 @@ typedef struct PESContext { int64_t ts_packet_pos; /**< position of first TS packet of this PES packet */ uint8_t header[MAX_PES_HEADER_SIZE]; uint8_t *buffer; + SLConfigDescr sl; } PESContext; extern AVInputFormat ff_mpegts_demuxer; @@ -658,6 +660,83 @@ static void new_pes_packet(PESContext *pes, AVPacket *pkt) pes->flags = 0; } +static uint64_t get_bits64(GetBitContext *gb, int bits) +{ + uint64_t ret = 0; + while (bits > 17) { + ret <<= 17; + ret |= get_bits(gb, 17); + bits -= 17; + } + ret <<= bits; + ret |= get_bits(gb, bits); + return ret; +} + +static int read_sl_header(PESContext *pes, SLConfigDescr *sl, const uint8_t *buf, int buf_size) +{ + GetBitContext gb; + int au_start_flag = 0, au_end_flag = 0, ocr_flag = 0, idle_flag = 0; + int padding_flag = 0, padding_bits = 0, inst_bitrate_flag = 0; + int dts_flag = -1, cts_flag = -1; + int64_t dts = AV_NOPTS_VALUE, cts = AV_NOPTS_VALUE; + init_get_bits(&gb, buf, buf_size*8); + + if (sl->use_au_start) + au_start_flag = get_bits1(&gb); + if (sl->use_au_end) + au_end_flag = get_bits1(&gb); + if (!sl->use_au_start && !sl->use_au_end) + au_start_flag = au_end_flag = 1; + if (sl->ocr_len > 0) + ocr_flag = get_bits1(&gb); + if (sl->use_idle) + idle_flag = get_bits1(&gb); + if (sl->use_padding) + padding_flag = get_bits1(&gb); + if (padding_flag) + padding_bits = get_bits(&gb, 3); + + if (!idle_flag && (!padding_flag || padding_bits != 0)) { + if (sl->packet_seq_num_len) + skip_bits_long(&gb, sl->packet_seq_num_len); + if (sl->degr_prior_len) + if (get_bits1(&gb)) + skip_bits(&gb, sl->degr_prior_len); + if (ocr_flag) + skip_bits_long(&gb, sl->ocr_len); + if (au_start_flag) { + if (sl->use_rand_acc_pt) + get_bits1(&gb); + if (sl->au_seq_num_len > 0) + skip_bits_long(&gb, sl->au_seq_num_len); + if (sl->use_timestamps) { + dts_flag = get_bits1(&gb); + cts_flag = get_bits1(&gb); + } + } + if (sl->inst_bitrate_len) + inst_bitrate_flag = get_bits1(&gb); + if (dts_flag == 1) + dts = get_bits64(&gb, sl->timestamp_len); + if (cts_flag == 1) + cts = get_bits64(&gb, sl->timestamp_len); + if (sl->au_len > 0) + skip_bits_long(&gb, sl->au_len); + if (inst_bitrate_flag) + skip_bits_long(&gb, sl->inst_bitrate_len); + } + + if (dts != AV_NOPTS_VALUE) + pes->dts = dts; + if (cts != AV_NOPTS_VALUE) + pes->pts = cts; + + av_set_pts_info(pes->st, sl->timestamp_len, 1, sl->timestamp_res); + + return (get_bits_count(&gb) + 7) >> 3; +} + /* return non zero if a packet could be constructed */ static int mpegts_push_data(MpegTSFilter *filter, const uint8_t *buf, int buf_size, int is_start, @@ -809,6 +888,12 @@ static int mpegts_push_data(MpegTSFilter *filter, /* we got the full header. We parse it and get the payload */ pes->state = MPEGTS_PAYLOAD; pes->data_index = 0; + if (pes->stream_type == 0x12) { + int sl_header_bytes = read_sl_header(pes, &pes->sl, p, buf_size); + pes->pes_header_size += sl_header_bytes; + p += sl_header_bytes; + buf_size -= sl_header_bytes; + } } break; case MPEGTS_PAYLOAD: @@ -962,7 +1047,9 @@ static int parse_MP4ESDescrTag(MP4DescrParseContext *d, int64_t off, int len) d->active_descr->es_id = es_id; update_offsets(&d->pb, &off, &len); parse_mp4_descr(d, off, len, MP4DecConfigDescrTag); - //SLConfigDescriptor + update_offsets(&d->pb, &off, &len); + if (len > 0) + parse_mp4_descr(d, off, len, MP4SLDescrTag); d->active_descr = NULL; return 0; } @@ -980,6 +1067,39 @@ static int parse_MP4DecConfigDescrTag(MP4DescrParseContext *d, int64_t off, int return 0; } +static int parse_MP4SLDescrTag(MP4DescrParseContext *d, int64_t off, int len) +{ + Mp4Descr *descr = d->active_descr; + int predefined; + if (!descr) + return -1; + + predefined = avio_r8(&d->pb); + if (!predefined) { + int lengths; + int flags = avio_r8(&d->pb); + descr->sl.use_au_start = !!(flags & 0x80); + descr->sl.use_au_end = !!(flags & 0x40); + descr->sl.use_rand_acc_pt = !!(flags & 0x20); + descr->sl.use_padding = !!(flags & 0x08); + descr->sl.use_timestamps = !!(flags & 0x04); + descr->sl.use_idle = !!(flags & 0x02); + descr->sl.timestamp_res = avio_rb32(&d->pb); + avio_rb32(&d->pb); + descr->sl.timestamp_len = avio_r8(&d->pb); + descr->sl.ocr_len = avio_r8(&d->pb); + descr->sl.au_len = avio_r8(&d->pb); + descr->sl.inst_bitrate_len = avio_r8(&d->pb); + lengths = avio_rb16(&d->pb); + descr->sl.degr_prior_len = lengths >> 12; + descr->sl.au_seq_num_len = (lengths >> 7) & 0x1f; + descr->sl.packet_seq_num_len = (lengths >> 2) & 0x1f; + } else { + av_log_missing_feature(d->s, "Predefined SLConfigDescriptor\n", 0); + } + return 0; +} + static int parse_mp4_descr(MP4DescrParseContext *d, int64_t off, int len, int target_tag) { int tag; @@ -1013,6 +1133,9 @@ static int parse_mp4_descr(MP4DescrParseContext *d, int64_t off, int len, case MP4DecConfigDescrTag: parse_MP4DecConfigDescrTag(d, off, len1); break; + case MP4SLDescrTag: + parse_MP4SLDescrTag(d, off, len1); + break; } done: @@ -1047,12 +1170,23 @@ static int mp4_read_od(AVFormatContext *s, const uint8_t *buf, unsigned size, return 0; } -static void SL_packet(AVFormatContext *s, MpegTSContext *ts, const uint8_t *p, const uint8_t *p_end) +static void m4sl_cb(MpegTSFilter *filter, const uint8_t *section, int section_len) { + MpegTSContext *ts = filter->u.section_filter.opaque; + SectionHeader h; + const uint8_t *p, *p_end; AVIOContext pb; Mp4Descr mp4_descr[MAX_MP4_DESCR_COUNT] = {{ 0 }}; int mp4_descr_count = 0; int i, pid; + AVFormatContext *s = ts->stream; + + p_end = section + section_len - 4; + p = section; + if (parse_section_header(&h, &p, p_end) < 0) + return; + if (h.tid != M4OD_TID) + return; mp4_read_od(s, p, (unsigned)(p_end - p), mp4_descr, &mp4_descr_count, MAX_MP4_DESCR_COUNT); @@ -1074,6 +1208,8 @@ static void SL_packet(AVFormatContext *s, MpegTSContext *ts, const uint8_t *p, c continue; } + pes->sl = mp4_descr[i].sl; + ffio_init_context(&pb, mp4_descr[i].dec_config_descr, mp4_descr[i].dec_config_descr_len, 0, NULL, NULL, NULL, NULL); ff_mp4_read_dec_config_descr(s, st, &pb); @@ -1098,25 +1234,6 @@ static void SL_packet(AVFormatContext *s, MpegTSContext *ts, const uint8_t *p, c av_free(mp4_descr[i].dec_config_descr); } -static void m4sl_cb(MpegTSFilter *filter, const uint8_t *section, int section_len) -{ - MpegTSContext *ts = filter->u.section_filter.opaque; - SectionHeader h1, *h = &h1; - const uint8_t *p, *p_end; - - av_dlog(ts->stream, "m4SL/od:\n"); - hex_dump_debug(ts->stream, (uint8_t *)section, section_len); - - p_end = section + section_len - 4; - p = section; - if (parse_section_header(h, &p, p_end) < 0) - return; - if (h->tid != M4OD_TID) - return; - - SL_packet(ts->stream, ts, p, p_end); -} - int ff_parse_mpeg2_descriptor(AVFormatContext *fc, AVStream *st, int stream_type, const uint8_t **pp, const uint8_t *desc_list_end, Mp4Descr *mp4_descr, int mp4_descr_count, int pid, diff --git a/libavformat/mpegts.h b/libavformat/mpegts.h index 560637b4fe..e38f2e09a3 100644 --- a/libavformat/mpegts.h +++ b/libavformat/mpegts.h @@ -65,10 +65,28 @@ int ff_mpegts_parse_packet(MpegTSContext *ts, AVPacket *pkt, const uint8_t *buf, int len); void ff_mpegts_parse_close(MpegTSContext *ts); +typedef struct { + int use_au_start; + int use_au_end; + int use_rand_acc_pt; + int use_padding; + int use_timestamps; + int use_idle; + int timestamp_res; + int timestamp_len; + int ocr_len; + int au_len; + int inst_bitrate_len; + int degr_prior_len; + int au_seq_num_len; + int packet_seq_num_len; +} SLConfigDescr; + typedef struct { int es_id; int dec_config_descr_len; uint8_t *dec_config_descr; + SLConfigDescr sl; } Mp4Descr; /** From 7a773d4d59c9a2e14cb84201f8d17cbf3edaede8 Mon Sep 17 00:00:00 2001 From: Alex Converse Date: Tue, 25 Oct 2011 18:26:35 -0700 Subject: [PATCH 52/53] probe: Remove id3 tag presence as a criteria to do file extension checking. This only encourages our users to put id3v2 tags on non-mp3 files to opt into extension based probing. --- libavformat/utils.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libavformat/utils.c b/libavformat/utils.c index 637d615d90..20be871669 100644 --- a/libavformat/utils.c +++ b/libavformat/utils.c @@ -339,7 +339,7 @@ AVInputFormat *av_probe_input_format2(AVProbeData *pd, int is_opened, int *score } /* a hack for files with huge id3v2 tags -- try to guess by file extension. */ - if (!fmt && id3 && *score_max < AVPROBE_SCORE_MAX/4) { + if (!fmt && is_opened && *score_max < AVPROBE_SCORE_MAX/4) { while ((fmt = av_iformat_next(fmt))) if (fmt->extensions && av_match_ext(lpd.filename, fmt->extensions)) { *score_max = AVPROBE_SCORE_MAX/4; From 61856d06eb30955290911140e6745bad93a25323 Mon Sep 17 00:00:00 2001 From: Alex Converse Date: Tue, 25 Oct 2011 18:37:24 -0700 Subject: [PATCH 53/53] probe: Restore identification of files with very large id3 tags and no extension. Restore behavior of identifying files with huge id3 tags as mp3 at AVPROBE_SCORE_MAX/4. This was broken in r25378 and subsequently removed in r25929. --- libavformat/utils.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/libavformat/utils.c b/libavformat/utils.c index 20be871669..81eee97a84 100644 --- a/libavformat/utils.c +++ b/libavformat/utils.c @@ -347,6 +347,14 @@ AVInputFormat *av_probe_input_format2(AVProbeData *pd, int is_opened, int *score } } + if (!fmt && id3 && *score_max < AVPROBE_SCORE_MAX/4-1) { + while ((fmt = av_iformat_next(fmt))) + if (fmt->extensions && av_match_ext("mp3", fmt->extensions)) { + *score_max = AVPROBE_SCORE_MAX/4-1; + break; + } + } + return fmt; }