diff --git a/avconv.c b/avconv.c index 89264aa8d3..76d8def806 100644 --- a/avconv.c +++ b/avconv.c @@ -2122,10 +2122,6 @@ static int transcode_init(OutputFile *output_files, codec->frame_size = icodec->frame_size; codec->audio_service_type = icodec->audio_service_type; codec->block_align= icodec->block_align; - if(codec->block_align == 1 && codec->codec_id == CODEC_ID_MP3) - codec->block_align= 0; - if(codec->codec_id == CODEC_ID_AC3) - codec->block_align= 0; break; case AVMEDIA_TYPE_VIDEO: codec->pix_fmt = icodec->pix_fmt; diff --git a/doc/libavfilter.texi b/doc/libavfilter.texi index 5bb5b1a84d..766b77f083 100644 --- a/doc/libavfilter.texi +++ b/doc/libavfilter.texi @@ -36,11 +36,10 @@ and the vflip filter before merging it back with the other stream by overlaying it on top. You can use the following command to achieve this: @example -./ffmpeg -i in.avi -s 240x320 -vf "[in] split [T1], fifo, [T2] overlay= 0:240 [out]; [T1] fifo, crop=0:0:-1:240, vflip [T2] +./ffmpeg -i input -vf "[in] split [T1], fifo, [T2] overlay=0:H/2 [out]; [T1] fifo, crop=iw:ih/2:0:ih/2, vflip [T2]" output @end example -where input_video.avi has a vertical resolution of 480 pixels. The -result will be that in output the top half of the video is mirrored +The result will be that in output the top half of the video is mirrored onto the bottom half. Video filters are loaded using the @var{-vf} option passed to diff --git a/ffmpeg.c b/ffmpeg.c index 7efbd88045..d3e97a3fc9 100644 --- a/ffmpeg.c +++ b/ffmpeg.c @@ -2165,10 +2165,6 @@ static int transcode_init(OutputFile *output_files, int nb_output_files, codec->frame_size = icodec->frame_size; codec->audio_service_type = icodec->audio_service_type; codec->block_align= icodec->block_align; - if(codec->block_align == 1 && codec->codec_id == CODEC_ID_MP3) - codec->block_align= 0; - if(codec->codec_id == CODEC_ID_AC3) - codec->block_align= 0; break; case AVMEDIA_TYPE_VIDEO: codec->pix_fmt = icodec->pix_fmt; diff --git a/libavcodec/apedec.c b/libavcodec/apedec.c index 9d2ce1dfaa..9285472245 100644 --- a/libavcodec/apedec.c +++ b/libavcodec/apedec.c @@ -140,8 +140,6 @@ typedef struct APEContext { uint32_t CRC; ///< frame CRC int frameflags; ///< frame flags - int currentframeblocks; ///< samples (per channel) in current frame - int blocksdecoded; ///< count of decoded samples in current frame APEPredictor predictor; ///< predictor used for final reconstruction int32_t decoded0[BLOCKS_PER_LOOP]; ///< decoded data for the first channel @@ -157,7 +155,6 @@ typedef struct APEContext { uint8_t *data; ///< current frame data uint8_t *data_end; ///< frame data end const uint8_t *ptr; ///< current position in frame data - const uint8_t *last_ptr; ///< position where last 4608-sample block ended int error; } APEContext; @@ -457,8 +454,6 @@ static void entropy_decode(APEContext *ctx, int blockstodecode, int stereo) int32_t *decoded0 = ctx->decoded0; int32_t *decoded1 = ctx->decoded1; - ctx->blocksdecoded = blockstodecode; - if (ctx->frameflags & APE_FRAMECODE_STEREO_SILENCE) { /* We are pure silence, just memset the output buffer. */ memset(decoded0, 0, blockstodecode * sizeof(int32_t)); @@ -470,9 +465,6 @@ static void entropy_decode(APEContext *ctx, int blockstodecode, int stereo) *decoded1++ = ape_decode_value(ctx, &ctx->riceX); } } - - if (ctx->blocksdecoded == ctx->currentframeblocks) - range_dec_normalize(ctx); /* normalize to use up all bytes */ } static int init_entropy_decoder(APEContext *ctx) @@ -492,9 +484,6 @@ static int init_entropy_decoder(APEContext *ctx) ctx->frameflags = bytestream_get_be32(&ctx->ptr); } - /* Keep a count of the blocks decoded in this frame */ - ctx->blocksdecoded = 0; - /* Initialize the rice structs */ ctx->riceX.k = 10; ctx->riceX.ksum = (1 << ctx->riceX.k) * 16; @@ -824,25 +813,22 @@ static int ape_decode_frame(AVCodecContext *avctx, int buf_size = avpkt->size; APEContext *s = avctx->priv_data; int16_t *samples = data; - uint32_t nblocks; int i; - int blockstodecode; - int bytes_used; - - /* 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 AVERROR(EINVAL); - } + int blockstodecode, out_size; + int bytes_used = 0; /* 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; + uint32_t nblocks, offset; void *tmp_data; + if (!buf_size) { + *data_size = 0; + return 0; + } if (buf_size < 8) { av_log(avctx, AV_LOG_ERROR, "Packet is too small\n"); return AVERROR_INVALIDDATA; @@ -853,7 +839,7 @@ static int ape_decode_frame(AVCodecContext *avctx, 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->ptr = s->data; s->data_end = s->data + buf_size; nblocks = bytestream_get_be32(&s->ptr); @@ -873,7 +859,7 @@ static int ape_decode_frame(AVCodecContext *avctx, av_log(avctx, AV_LOG_ERROR, "Invalid sample count: %u.\n", nblocks); return AVERROR_INVALIDDATA; } - s->currentframeblocks = s->samples = nblocks; + s->samples = nblocks; memset(s->decoded0, 0, sizeof(s->decoded0)); memset(s->decoded1, 0, sizeof(s->decoded1)); @@ -883,6 +869,8 @@ static int ape_decode_frame(AVCodecContext *avctx, av_log(avctx, AV_LOG_ERROR, "Error reading frame header\n"); return AVERROR_INVALIDDATA; } + + bytes_used = buf_size; } if (!s->data) { @@ -890,8 +878,14 @@ static int ape_decode_frame(AVCodecContext *avctx, return buf_size; } - nblocks = s->samples; - blockstodecode = FFMIN(BLOCKS_PER_LOOP, nblocks); + blockstodecode = FFMIN(BLOCKS_PER_LOOP, s->samples); + + out_size = blockstodecode * avctx->channels * + av_get_bytes_per_sample(avctx->sample_fmt); + if (*data_size < out_size) { + av_log(avctx, AV_LOG_ERROR, "Output buffer is too small.\n"); + return AVERROR(EINVAL); + } s->error=0; @@ -915,9 +909,7 @@ static int ape_decode_frame(AVCodecContext *avctx, s->samples -= blockstodecode; - *data_size = blockstodecode * 2 * s->channels; - bytes_used = s->samples ? s->ptr - s->last_ptr : buf_size; - s->last_ptr = s->ptr; + *data_size = out_size; return bytes_used; } @@ -935,7 +927,7 @@ AVCodec ff_ape_decoder = { .init = ape_decode_init, .close = ape_decode_close, .decode = ape_decode_frame, - .capabilities = CODEC_CAP_SUBFRAMES, + .capabilities = CODEC_CAP_SUBFRAMES | CODEC_CAP_DELAY, .flush = ape_flush, .long_name = NULL_IF_CONFIG_SMALL("Monkey's Audio"), }; diff --git a/libavcodec/atrac1.c b/libavcodec/atrac1.c index d4d5986821..f341b1c554 100644 --- a/libavcodec/atrac1.c +++ b/libavcodec/atrac1.c @@ -284,7 +284,7 @@ static int atrac1_decode_frame(AVCodecContext *avctx, void *data, if (buf_size < 212 * q->channels) { - av_log(avctx,AV_LOG_ERROR,"Not enough data to decode!\n"); + av_log(avctx, AV_LOG_ERROR, "Not enough data to decode!\n"); return AVERROR_INVALIDDATA; } diff --git a/libavcodec/mpc7.c b/libavcodec/mpc7.c index 272e1b28ba..3418b7b4f8 100644 --- a/libavcodec/mpc7.c +++ b/libavcodec/mpc7.c @@ -200,7 +200,7 @@ static int mpc7_decode_frame(AVCodecContext * avctx, int off, out_size; int bits_used, bits_avail; - memset(bands, 0, sizeof(bands)); + memset(bands, 0, sizeof(*bands) * (c->maxbands + 1)); if(buf_size <= 4){ av_log(avctx, AV_LOG_ERROR, "Too small buffer passed (%i bytes)\n", buf_size); return AVERROR(EINVAL); diff --git a/libavcodec/sunrast.c b/libavcodec/sunrast.c index ea7a3e55c0..36dfa98293 100644 --- a/libavcodec/sunrast.c +++ b/libavcodec/sunrast.c @@ -68,7 +68,7 @@ static int sunrast_decode_frame(AVCodecContext *avctx, void *data, type = AV_RB32(buf+20); maptype = AV_RB32(buf+24); maplength = AV_RB32(buf+28); - buf += 32; + buf += 32; if (type < RT_OLD || type > RT_FORMAT_IFF) { av_log(avctx, AV_LOG_ERROR, "invalid (compression) type\n"); diff --git a/libavcodec/truespeech.c b/libavcodec/truespeech.c index 8cd05145db..b0a8e44150 100644 --- a/libavcodec/truespeech.c +++ b/libavcodec/truespeech.c @@ -233,8 +233,7 @@ static void truespeech_update_filters(TSContext *dec, int16_t *out, int quart) { int i; - for(i = 0; i < 86; i++) - dec->filtbuf[i] = dec->filtbuf[i + 60]; + memmove(dec->filtbuf, &dec->filtbuf[60], 86 * sizeof(*dec->filtbuf)); for(i = 0; i < 60; i++){ dec->filtbuf[i + 86] = out[i] + dec->newvec[i] - (dec->newvec[i] >> 3); out[i] += dec->newvec[i]; diff --git a/libavcodec/vorbisdec.c b/libavcodec/vorbisdec.c index 675de02d86..0457d8b454 100644 --- a/libavcodec/vorbisdec.c +++ b/libavcodec/vorbisdec.c @@ -168,7 +168,7 @@ static const char idx_err_str[] = "Index value %d out of range (0 - %d) for %s a av_log(vc->avccontext, AV_LOG_ERROR,\ idx_err_str,\ (int)(idx), (int)(limit - 1), #idx, __FILE__, __LINE__);\ - return -1;\ + return AVERROR_INVALIDDATA;\ } #define GET_VALIDATED_INDEX(idx, bits, limit) \ {\ @@ -241,6 +241,7 @@ static int vorbis_parse_setup_hdr_codebooks(vorbis_context *vc) uint32_t *tmp_vlc_codes; GetBitContext *gb = &vc->gb; uint16_t *codebook_multiplicands; + int ret = 0; vc->codebook_count = get_bits(gb, 8) + 1; @@ -260,6 +261,7 @@ static int vorbis_parse_setup_hdr_codebooks(vorbis_context *vc) if (get_bits(gb, 24) != 0x564342) { av_log(vc->avccontext, AV_LOG_ERROR, " %u. Codebook setup data corrupt.\n", cb); + ret = AVERROR_INVALIDDATA; goto error; } @@ -268,6 +270,7 @@ static int vorbis_parse_setup_hdr_codebooks(vorbis_context *vc) av_log(vc->avccontext, AV_LOG_ERROR, " %u. Codebook's dimension is invalid (%d).\n", cb, codebook_setup->dimensions); + ret = AVERROR_INVALIDDATA; goto error; } entries = get_bits(gb, 24); @@ -275,6 +278,7 @@ static int vorbis_parse_setup_hdr_codebooks(vorbis_context *vc) av_log(vc->avccontext, AV_LOG_ERROR, " %u. Codebook has too many entries (%u).\n", cb, entries); + ret = AVERROR_INVALIDDATA; goto error; } @@ -332,6 +336,7 @@ static int vorbis_parse_setup_hdr_codebooks(vorbis_context *vc) } if (current_entry>used_entries) { av_log(vc->avccontext, AV_LOG_ERROR, " More codelengths than codes in codebook. \n"); + ret = AVERROR_INVALIDDATA; goto error; } } @@ -399,17 +404,20 @@ static int vorbis_parse_setup_hdr_codebooks(vorbis_context *vc) } if (j != used_entries) { av_log(vc->avccontext, AV_LOG_ERROR, "Bug in codevector vector building code. \n"); + ret = AVERROR_INVALIDDATA; goto error; } entries = used_entries; } else if (codebook_setup->lookup_type >= 2) { av_log(vc->avccontext, AV_LOG_ERROR, "Codebook lookup type not supported. \n"); + ret = AVERROR_INVALIDDATA; goto error; } // Initialize VLC table if (ff_vorbis_len2vlc(tmp_vlc_bits, tmp_vlc_codes, entries)) { av_log(vc->avccontext, AV_LOG_ERROR, " Invalid code lengths while generating vlcs. \n"); + ret = AVERROR_INVALIDDATA; goto error; } codebook_setup->maxdepth = 0; @@ -424,7 +432,11 @@ static int vorbis_parse_setup_hdr_codebooks(vorbis_context *vc) codebook_setup->maxdepth = (codebook_setup->maxdepth+codebook_setup->nb_bits - 1) / codebook_setup->nb_bits; - if (init_vlc(&codebook_setup->vlc, codebook_setup->nb_bits, entries, tmp_vlc_bits, sizeof(*tmp_vlc_bits), sizeof(*tmp_vlc_bits), tmp_vlc_codes, sizeof(*tmp_vlc_codes), sizeof(*tmp_vlc_codes), INIT_VLC_LE)) { + if ((ret = init_vlc(&codebook_setup->vlc, codebook_setup->nb_bits, + entries, tmp_vlc_bits, sizeof(*tmp_vlc_bits), + sizeof(*tmp_vlc_bits), tmp_vlc_codes, + sizeof(*tmp_vlc_codes), sizeof(*tmp_vlc_codes), + INIT_VLC_LE))) { av_log(vc->avccontext, AV_LOG_ERROR, " Error generating vlc tables. \n"); goto error; } @@ -440,7 +452,7 @@ error: av_free(tmp_vlc_bits); av_free(tmp_vlc_codes); av_free(codebook_multiplicands); - return -1; + return ret; } // Process time domain transforms part (unused in Vorbis I) @@ -458,7 +470,7 @@ static int vorbis_parse_setup_hdr_tdtransforms(vorbis_context *vc) if (vorbis_tdtransform) { av_log(vc->avccontext, AV_LOG_ERROR, "Vorbis time domain transform data nonzero. \n"); - return -1; + return AVERROR_INVALIDDATA; } } return 0; @@ -550,7 +562,7 @@ static int vorbis_parse_setup_hdr_floors(vorbis_context *vc) av_log(vc->avccontext, AV_LOG_ERROR, "Floor value is too large for blocksize: %u (%"PRIu32")\n", rangemax, vc->blocksize[1] / 2); - return -1; + return AVERROR_INVALIDDATA; } floor_setup->data.t1.list[0].x = 0; floor_setup->data.t1.list[1].x = rangemax; @@ -580,7 +592,7 @@ static int vorbis_parse_setup_hdr_floors(vorbis_context *vc) if (floor_setup->data.t0.amplitude_bits == 0) { av_log(vc->avccontext, AV_LOG_ERROR, "Floor 0 amplitude bits is 0.\n"); - return -1; + return AVERROR_INVALIDDATA; } floor_setup->data.t0.amplitude_offset = get_bits(gb, 8); floor_setup->data.t0.num_books = get_bits(gb, 4) + 1; @@ -589,7 +601,7 @@ static int vorbis_parse_setup_hdr_floors(vorbis_context *vc) floor_setup->data.t0.book_list = av_malloc(floor_setup->data.t0.num_books); if (!floor_setup->data.t0.book_list) - return -1; + return AVERROR(ENOMEM); /* read book indexes */ { int idx; @@ -610,7 +622,7 @@ static int vorbis_parse_setup_hdr_floors(vorbis_context *vc) av_malloc((floor_setup->data.t0.order + 1 + max_codebook_dim) * sizeof(*floor_setup->data.t0.lsp)); if (!floor_setup->data.t0.lsp) - return -1; + return AVERROR(ENOMEM); /* debug output parsed headers */ av_dlog(NULL, "floor0 order: %u\n", floor_setup->data.t0.order); @@ -634,7 +646,7 @@ static int vorbis_parse_setup_hdr_floors(vorbis_context *vc) } } else { av_log(vc->avccontext, AV_LOG_ERROR, "Invalid floor type!\n"); - return -1; + return AVERROR_INVALIDDATA; } } return 0; @@ -672,7 +684,7 @@ static int vorbis_parse_setup_hdr_residues(vorbis_context *vc) "partition out of bounds: type, begin, end, size, blocksize: %"PRIu16", %"PRIu32", %"PRIu32", %u, %"PRIu32"\n", res_setup->type, res_setup->begin, res_setup->end, res_setup->partition_size, vc->blocksize[1] / 2); - return -1; + return AVERROR_INVALIDDATA; } res_setup->classifications = get_bits(gb, 6) + 1; @@ -737,7 +749,7 @@ static int vorbis_parse_setup_hdr_mappings(vorbis_context *vc) if (get_bits(gb, 16)) { av_log(vc->avccontext, AV_LOG_ERROR, "Other mappings than type 0 are not compliant with the Vorbis I specification. \n"); - return -1; + return AVERROR_INVALIDDATA; } if (get_bits1(gb)) { mapping_setup->submaps = get_bits(gb, 4) + 1; @@ -764,7 +776,7 @@ static int vorbis_parse_setup_hdr_mappings(vorbis_context *vc) if (get_bits(gb, 2)) { av_log(vc->avccontext, AV_LOG_ERROR, "%u. mapping setup data invalid.\n", i); - return -1; // following spec. + return AVERROR_INVALIDDATA; // following spec. } if (mapping_setup->submaps>1) { @@ -851,41 +863,42 @@ static int vorbis_parse_setup_hdr_modes(vorbis_context *vc) static int vorbis_parse_setup_hdr(vorbis_context *vc) { GetBitContext *gb = &vc->gb; + int ret; if ((get_bits(gb, 8) != 'v') || (get_bits(gb, 8) != 'o') || (get_bits(gb, 8) != 'r') || (get_bits(gb, 8) != 'b') || (get_bits(gb, 8) != 'i') || (get_bits(gb, 8) != 's')) { av_log(vc->avccontext, AV_LOG_ERROR, " Vorbis setup header packet corrupt (no vorbis signature). \n"); - return -1; + return AVERROR_INVALIDDATA; } - if (vorbis_parse_setup_hdr_codebooks(vc)) { + if ((ret = vorbis_parse_setup_hdr_codebooks(vc))) { av_log(vc->avccontext, AV_LOG_ERROR, " Vorbis setup header packet corrupt (codebooks). \n"); - return -2; + return ret; } - if (vorbis_parse_setup_hdr_tdtransforms(vc)) { + if ((ret = vorbis_parse_setup_hdr_tdtransforms(vc))) { av_log(vc->avccontext, AV_LOG_ERROR, " Vorbis setup header packet corrupt (time domain transforms). \n"); - return -3; + return ret; } - if (vorbis_parse_setup_hdr_floors(vc)) { + if ((ret = vorbis_parse_setup_hdr_floors(vc))) { av_log(vc->avccontext, AV_LOG_ERROR, " Vorbis setup header packet corrupt (floors). \n"); - return -4; + return ret; } - if (vorbis_parse_setup_hdr_residues(vc)) { + if ((ret = vorbis_parse_setup_hdr_residues(vc))) { av_log(vc->avccontext, AV_LOG_ERROR, " Vorbis setup header packet corrupt (residues). \n"); - return -5; + return ret; } - if (vorbis_parse_setup_hdr_mappings(vc)) { + if ((ret = vorbis_parse_setup_hdr_mappings(vc))) { av_log(vc->avccontext, AV_LOG_ERROR, " Vorbis setup header packet corrupt (mappings). \n"); - return -6; + return ret; } - if (vorbis_parse_setup_hdr_modes(vc)) { + if ((ret = vorbis_parse_setup_hdr_modes(vc))) { av_log(vc->avccontext, AV_LOG_ERROR, " Vorbis setup header packet corrupt (modes). \n"); - return -7; + return ret; } if (!get_bits1(gb)) { av_log(vc->avccontext, AV_LOG_ERROR, " Vorbis setup header packet corrupt (framing flag). \n"); - return -8; // framing flag bit unset error + return AVERROR_INVALIDDATA; // framing flag bit unset error } return 0; @@ -902,19 +915,19 @@ static int vorbis_parse_id_hdr(vorbis_context *vc) (get_bits(gb, 8) != 'r') || (get_bits(gb, 8) != 'b') || (get_bits(gb, 8) != 'i') || (get_bits(gb, 8) != 's')) { av_log(vc->avccontext, AV_LOG_ERROR, " Vorbis id header packet corrupt (no vorbis signature). \n"); - return -1; + return AVERROR_INVALIDDATA; } vc->version = get_bits_long(gb, 32); //FIXME check 0 vc->audio_channels = get_bits(gb, 8); if (vc->audio_channels <= 0) { av_log(vc->avccontext, AV_LOG_ERROR, "Invalid number of channels\n"); - return -1; + return AVERROR_INVALIDDATA; } vc->audio_samplerate = get_bits_long(gb, 32); if (vc->audio_samplerate <= 0) { av_log(vc->avccontext, AV_LOG_ERROR, "Invalid samplerate\n"); - return -1; + return AVERROR_INVALIDDATA; } vc->bitrate_maximum = get_bits_long(gb, 32); vc->bitrate_nominal = get_bits_long(gb, 32); @@ -925,20 +938,14 @@ static int vorbis_parse_id_hdr(vorbis_context *vc) vc->blocksize[1] = (1 << bl1); if (bl0 > 13 || bl0 < 6 || bl1 > 13 || bl1 < 6 || bl1 < bl0) { av_log(vc->avccontext, AV_LOG_ERROR, " Vorbis id header packet corrupt (illegal blocksize). \n"); - return -3; - } - // output format int16 - if (vc->blocksize[1] / 2 * vc->audio_channels * 2 > AVCODEC_MAX_AUDIO_FRAME_SIZE) { - av_log(vc->avccontext, AV_LOG_ERROR, "Vorbis channel count makes " - "output packets too large.\n"); - return -4; + return AVERROR_INVALIDDATA; } vc->win[0] = ff_vorbis_vwin[bl0 - 6]; vc->win[1] = ff_vorbis_vwin[bl1 - 6]; if ((get_bits1(gb)) == 0) { av_log(vc->avccontext, AV_LOG_ERROR, " Vorbis id header packet corrupt (framing flag not set). \n"); - return -2; + return AVERROR_INVALIDDATA; } vc->channel_residues = av_malloc((vc->blocksize[1] / 2) * vc->audio_channels * sizeof(*vc->channel_residues)); @@ -972,7 +979,7 @@ static av_cold int vorbis_decode_init(AVCodecContext *avccontext) uint8_t *header_start[3]; int header_len[3]; GetBitContext *gb = &(vc->gb); - int hdr_type; + int hdr_type, ret; vc->avccontext = avccontext; dsputil_init(&vc->dsp, avccontext); @@ -988,24 +995,24 @@ static av_cold int vorbis_decode_init(AVCodecContext *avccontext) if (!headers_len) { av_log(avccontext, AV_LOG_ERROR, "Extradata missing.\n"); - return -1; + return AVERROR_INVALIDDATA; } - if (avpriv_split_xiph_headers(headers, headers_len, 30, header_start, header_len) < 0) { + if ((ret = avpriv_split_xiph_headers(headers, headers_len, 30, header_start, header_len)) < 0) { av_log(avccontext, AV_LOG_ERROR, "Extradata corrupt.\n"); - return -1; + return ret; } init_get_bits(gb, header_start[0], header_len[0]*8); hdr_type = get_bits(gb, 8); if (hdr_type != 1) { av_log(avccontext, AV_LOG_ERROR, "First header is not the id header.\n"); - return -1; + return AVERROR_INVALIDDATA; } - if (vorbis_parse_id_hdr(vc)) { + if ((ret = vorbis_parse_id_hdr(vc))) { av_log(avccontext, AV_LOG_ERROR, "Id header corrupt.\n"); vorbis_free(vc); - return -1; + return ret; } init_get_bits(gb, header_start[2], header_len[2]*8); @@ -1013,12 +1020,12 @@ static av_cold int vorbis_decode_init(AVCodecContext *avccontext) if (hdr_type != 5) { av_log(avccontext, AV_LOG_ERROR, "Third header is not the setup header.\n"); vorbis_free(vc); - return -1; + return AVERROR_INVALIDDATA; } - if (vorbis_parse_setup_hdr(vc)) { + if ((ret = vorbis_parse_setup_hdr(vc))) { av_log(avccontext, AV_LOG_ERROR, "Setup header corrupt.\n"); vorbis_free(vc); - return -1; + return ret; } if (vc->audio_channels > 8) @@ -1061,7 +1068,7 @@ static int vorbis_floor0_decode(vorbis_context *vc, codebook = vc->codebooks[vf->book_list[book_idx]]; /* Invalid codebook! */ if (!codebook.codevectors) - return -1; + return AVERROR_INVALIDDATA; while (lsp_lenorder) { int vec_off; @@ -1427,7 +1434,7 @@ static inline int vorbis_residue_decode(vorbis_context *vc, vorbis_residue *vr, return vorbis_residue_decode_internal(vc, vr, ch, do_not_decode, vec, vlen, 0); else { av_log(vc->avccontext, AV_LOG_ERROR, " Invalid residue type while residue decode?! \n"); - return -1; + return AVERROR_INVALIDDATA; } } @@ -1475,7 +1482,7 @@ static int vorbis_parse_audio_packet(vorbis_context *vc) if (get_bits1(gb)) { av_log(vc->avccontext, AV_LOG_ERROR, "Not a Vorbis I audio packet.\n"); - return -1; // packet type not audio + return AVERROR_INVALIDDATA; // packet type not audio } if (vc->mode_count == 1) { @@ -1512,7 +1519,7 @@ static int vorbis_parse_audio_packet(vorbis_context *vc) if (ret < 0) { av_log(vc->avccontext, AV_LOG_ERROR, "Invalid codebook in vorbis_floor_decode.\n"); - return -1; + return AVERROR_INVALIDDATA; } no_residue[i] = ret; ch_floor_ptr += blocksize / 2; @@ -1613,19 +1620,12 @@ static int vorbis_decode_frame(AVCodecContext *avccontext, const float *channel_ptrs[255]; int i, len, out_size; - if (!buf_size) - return 0; - av_dlog(NULL, "packet length %d \n", buf_size); init_get_bits(gb, buf, buf_size*8); - len = vorbis_parse_audio_packet(vc); - - if (len <= 0) { - *data_size = 0; - return buf_size; - } + if ((len = vorbis_parse_audio_packet(vc)) <= 0) + return len; if (!vc->first_frame) { vc->first_frame = 1; diff --git a/libavformat/avc.c b/libavformat/avc.c index ed2125b527..eff1ddb121 100644 --- a/libavformat/avc.c +++ b/libavformat/avc.c @@ -75,8 +75,11 @@ int ff_avc_parse_nal_units(AVIOContext *pb, const uint8_t *buf_in, int size) size = 0; nal_start = ff_avc_find_startcode(p, end); - while (nal_start < end) { - while(!*(nal_start++)); + for (;;) { + while (nal_start < end && !*(nal_start++)); + if (nal_start == end) + break; + nal_end = ff_avc_find_startcode(nal_start, end); avio_wb32(pb, nal_end - nal_start); avio_write(pb, nal_start, nal_end - nal_start); @@ -117,22 +120,26 @@ int ff_isom_write_avcc(AVIOContext *pb, const uint8_t *data, int len) end = buf + len; /* look for sps and pps */ - while (buf < end) { - unsigned int size; + while (end - buf > 4) { + uint32_t size; uint8_t nal_type; - size = AV_RB32(buf); - nal_type = buf[4] & 0x1f; + size = FFMIN(AV_RB32(buf), end - buf - 4); + buf += 4; + nal_type = buf[0] & 0x1f; + if (nal_type == 7) { /* SPS */ - sps = buf + 4; + sps = buf; sps_size = size; } else if (nal_type == 8) { /* PPS */ - pps = buf + 4; + pps = buf; pps_size = size; } - buf += size + 4; + + buf += size; } - assert(sps); - assert(pps); + + if (!sps || !pps || sps_size < 4 || sps_size > UINT16_MAX || pps_size > UINT16_MAX) + return AVERROR_INVALIDDATA; avio_w8(pb, 1); /* version */ avio_w8(pb, sps[1]); /* profile */ diff --git a/libavformat/avio.c b/libavformat/avio.c index 47b2d51ebd..4141d0bd7d 100644 --- a/libavformat/avio.c +++ b/libavformat/avio.c @@ -338,8 +338,11 @@ int ffurl_close(URLContext *h) #if CONFIG_NETWORK ff_network_close(); #endif - if (h->prot->priv_data_size) + if (h->prot->priv_data_size) { + if (h->prot->priv_data_class) + av_opt_free(h->priv_data); av_free(h->priv_data); + } av_free(h); return ret; } diff --git a/libavformat/crypto.c b/libavformat/crypto.c index b9d3e0326f..ea417470b6 100644 --- a/libavformat/crypto.c +++ b/libavformat/crypto.c @@ -45,9 +45,10 @@ typedef struct { } CryptoContext; #define OFFSET(x) offsetof(CryptoContext, x) +#define D AV_OPT_FLAG_DECODING_PARAM static const AVOption options[] = { - {"key", "AES decryption key", OFFSET(key), AV_OPT_TYPE_BINARY }, - {"iv", "AES decryption initialization vector", OFFSET(iv), AV_OPT_TYPE_BINARY }, + {"key", "AES decryption key", OFFSET(key), AV_OPT_TYPE_BINARY, .flags = D }, + {"iv", "AES decryption initialization vector", OFFSET(iv), AV_OPT_TYPE_BINARY, .flags = D }, { NULL } }; @@ -61,7 +62,7 @@ static const AVClass crypto_class = { static int crypto_open(URLContext *h, const char *uri, int flags) { const char *nested_url; - int ret; + int ret = 0; CryptoContext *c = h->priv_data; if (!av_strstart(uri, "crypto+", &nested_url) && @@ -95,10 +96,7 @@ static int crypto_open(URLContext *h, const char *uri, int flags) h->is_streamed = 1; - return 0; err: - av_freep(&c->key); - av_freep(&c->iv); return ret; } @@ -157,8 +155,6 @@ static int crypto_close(URLContext *h) if (c->hd) ffurl_close(c->hd); av_freep(&c->aes); - av_freep(&c->key); - av_freep(&c->iv); return 0; } diff --git a/libavformat/http.c b/libavformat/http.c index 414eb8719f..5f1837d6ad 100644 --- a/libavformat/http.c +++ b/libavformat/http.c @@ -47,36 +47,33 @@ typedef struct { int64_t off, filesize; char location[MAX_URL_SIZE]; HTTPAuthState auth_state; - unsigned char headers[BUFFER_SIZE]; + char *headers; int willclose; /**< Set if the server correctly handles Connection: close and will close the connection after feeding us the content. */ + int chunked_post; } HTTPContext; #define OFFSET(x) offsetof(HTTPContext, x) +#define D AV_OPT_FLAG_DECODING_PARAM +#define E AV_OPT_FLAG_ENCODING_PARAM static const AVOption options[] = { -{"chunksize", "use chunked transfer-encoding for posts, -1 disables it, 0 enables it", OFFSET(chunksize), AV_OPT_TYPE_INT64, {.dbl = 0}, -1, 0 }, /* Default to 0, for chunked POSTs */ +{"chunked_post", "use chunked transfer-encoding for posts", OFFSET(chunked_post), AV_OPT_TYPE_INT, {.dbl = 1}, 0, 1, E }, +{"headers", "custom HTTP headers, can override built in default headers", OFFSET(headers), AV_OPT_TYPE_STRING, { 0 }, 0, 0, D|E }, {NULL} }; -static const AVClass httpcontext_class = { - .class_name = "HTTP", - .item_name = av_default_item_name, - .option = options, - .version = LIBAVUTIL_VERSION_INT, +#define HTTP_CLASS(flavor)\ +static const AVClass flavor ## _context_class = {\ + .class_name = #flavor,\ + .item_name = av_default_item_name,\ + .option = options,\ + .version = LIBAVUTIL_VERSION_INT,\ }; +HTTP_CLASS(http); +HTTP_CLASS(https); + static int http_connect(URLContext *h, const char *path, const char *hoststr, const char *auth, int *new_location); -void ff_http_set_headers(URLContext *h, const char *headers) -{ - HTTPContext *s = h->priv_data; - int len = strlen(headers); - - if (len && strcmp("\r\n", headers + len - 2)) - av_log(h, AV_LOG_ERROR, "No trailing CRLF found in HTTP header.\n"); - - av_strlcpy(s->headers, headers, sizeof(s->headers)); -} - void ff_http_init_auth_state(URLContext *dest, const URLContext *src) { memcpy(&((HTTPContext*)dest->priv_data)->auth_state, @@ -168,6 +165,12 @@ static int http_open(URLContext *h, const char *uri, int flags) s->filesize = -1; av_strlcpy(s->location, uri, sizeof(s->location)); + if (s->headers) { + int len = strlen(s->headers); + if (len < 2 || strcmp("\r\n", s->headers + len - 2)) + av_log(h, AV_LOG_WARNING, "No trailing CRLF found in HTTP header.\n"); + } + return http_open_cnx(h); } static int http_getc(HTTPContext *s) @@ -285,6 +288,8 @@ static int process_line(URLContext *h, char *line, int line_count, static inline int has_header(const char *str, const char *header) { /* header + 2 to skip over CRLF prefix. (make sure you have one!) */ + if (!str) + return 0; return av_stristart(str, header + 2, NULL) || av_stristr(str, header); } @@ -312,7 +317,7 @@ static int http_connect(URLContext *h, const char *path, const char *hoststr, if (!has_header(s->headers, "\r\nAccept: ")) len += av_strlcpy(headers + len, "Accept: */*\r\n", sizeof(headers) - len); - if (!has_header(s->headers, "\r\nRange: ")) + if (!has_header(s->headers, "\r\nRange: ") && !post) len += av_strlcatf(headers + len, sizeof(headers) - len, "Range: bytes=%"PRId64"-\r\n", s->off); if (!has_header(s->headers, "\r\nConnection: ")) @@ -323,7 +328,8 @@ static int http_connect(URLContext *h, const char *path, const char *hoststr, "Host: %s\r\n", hoststr); /* now add in custom headers */ - av_strlcpy(headers+len, s->headers, sizeof(headers)-len); + if (s->headers) + av_strlcpy(headers + len, s->headers, sizeof(headers) - len); snprintf(s->buffer, sizeof(s->buffer), "%s %s HTTP/1.1\r\n" @@ -333,7 +339,7 @@ static int http_connect(URLContext *h, const char *path, const char *hoststr, "\r\n", post ? "POST" : "GET", path, - post && s->chunksize >= 0 ? "Transfer-Encoding: chunked\r\n" : "", + post && s->chunked_post ? "Transfer-Encoding: chunked\r\n" : "", headers, authstr ? authstr : ""); @@ -430,7 +436,7 @@ static int http_write(URLContext *h, const uint8_t *buf, int size) char crlf[] = "\r\n"; HTTPContext *s = h->priv_data; - if (s->chunksize == -1) { + if (!s->chunked_post) { /* non-chunked data is sent without any special encoding */ return ffurl_write(s->hd, buf, size); } @@ -456,7 +462,7 @@ static int http_close(URLContext *h) HTTPContext *s = h->priv_data; /* signal end of chunked encoding if used */ - if ((h->flags & AVIO_FLAG_WRITE) && s->chunksize != -1) { + if ((h->flags & AVIO_FLAG_WRITE) && s->chunked_post) { ret = ffurl_write(s->hd, footer, sizeof(footer) - 1); ret = ret > 0 ? 0 : ret; } @@ -519,7 +525,7 @@ URLProtocol ff_http_protocol = { .url_close = http_close, .url_get_file_handle = http_get_file_handle, .priv_data_size = sizeof(HTTPContext), - .priv_data_class = &httpcontext_class, + .priv_data_class = &http_context_class, }; #endif #if CONFIG_HTTPS_PROTOCOL @@ -532,6 +538,6 @@ URLProtocol ff_https_protocol = { .url_close = http_close, .url_get_file_handle = http_get_file_handle, .priv_data_size = sizeof(HTTPContext), - .priv_data_class = &httpcontext_class, + .priv_data_class = &https_context_class, }; #endif diff --git a/libavformat/http.h b/libavformat/http.h index 19c4099ef0..342434d202 100644 --- a/libavformat/http.h +++ b/libavformat/http.h @@ -24,24 +24,6 @@ #include "url.h" -/** - * Set custom HTTP headers. - * A trailing CRLF ("\r\n") is required for custom headers. - * Passing in an empty header string ("\0") will reset to defaults. - * - * The following headers can be overriden by custom values, - * otherwise they will be set to their defaults. - * -User-Agent - * -Accept - * -Range - * -Host - * -Connection - * - * @param h URL context for this HTTP connection - * @param headers the custom headers to set - */ -void ff_http_set_headers(URLContext *h, const char *headers); - /** * Initialize the authentication state based on another HTTP URLContext. * This can be used to pre-initialize the authentication parameters if diff --git a/libavformat/mmsh.c b/libavformat/mmsh.c index f54a976e19..c710ad9ccc 100644 --- a/libavformat/mmsh.c +++ b/libavformat/mmsh.c @@ -28,6 +28,7 @@ #include #include "libavutil/intreadwrite.h" #include "libavutil/avstring.h" +#include "libavutil/opt.h" #include "internal.h" #include "mms.h" #include "asf.h" @@ -246,7 +247,7 @@ static int mmsh_open_internal(URLContext *h, const char *uri, int flags, int tim CLIENTGUID "Connection: Close\r\n", host, port, mmsh->request_seq++); - ff_http_set_headers(mms->mms_hd, headers); + av_opt_set(mms->mms_hd->priv_data, "headers", headers, 0); err = ffurl_connect(mms->mms_hd); if (err) { @@ -293,7 +294,7 @@ static int mmsh_open_internal(URLContext *h, const char *uri, int flags, int tim goto fail; } av_dlog(NULL, "out_buffer is %s", headers); - ff_http_set_headers(mms->mms_hd, headers); + av_opt_set(mms->mms_hd->priv_data, "headers", headers, 0); err = ffurl_connect(mms->mms_hd); if (err) { diff --git a/libavformat/rtsp.c b/libavformat/rtsp.c index c53b728271..68083ae2ac 100644 --- a/libavformat/rtsp.c +++ b/libavformat/rtsp.c @@ -1462,7 +1462,7 @@ redirect: "Pragma: no-cache\r\n" "Cache-Control: no-cache\r\n", sessioncookie); - ff_http_set_headers(rt->rtsp_hd, headers); + av_opt_set(rt->rtsp_hd->priv_data, "headers", headers, 0); /* complete the connection */ if (ffurl_connect(rt->rtsp_hd)) { @@ -1485,8 +1485,8 @@ redirect: "Content-Length: 32767\r\n" "Expires: Sun, 9 Jan 1972 00:00:00 GMT\r\n", sessioncookie); - ff_http_set_headers(rt->rtsp_hd_out, headers); - av_opt_set(rt->rtsp_hd_out->priv_data, "chunksize", "-1", 0); + av_opt_set(rt->rtsp_hd_out->priv_data, "headers", headers, 0); + av_opt_set(rt->rtsp_hd_out->priv_data, "chunked_post", "0", 0); /* Initialize the authentication state for the POST session. The HTTP * protocol implementation doesn't properly handle multi-pass diff --git a/libavformat/tls.c b/libavformat/tls.c index bd73febd4d..8211e88846 100644 --- a/libavformat/tls.c +++ b/libavformat/tls.c @@ -73,7 +73,7 @@ static int do_tls_poll(URLContext *h, int ret) struct pollfd p = { c->fd, 0, 0 }; #if CONFIG_GNUTLS if (ret != GNUTLS_E_AGAIN && ret != GNUTLS_E_INTERRUPTED) { - av_log(NULL, AV_LOG_ERROR, "%s\n", gnutls_strerror(ret)); + av_log(h, AV_LOG_ERROR, "%s\n", gnutls_strerror(ret)); return AVERROR(EIO); } if (gnutls_record_get_direction(c->session)) @@ -87,11 +87,11 @@ static int do_tls_poll(URLContext *h, int ret) } else if (ret == SSL_ERROR_WANT_WRITE) { p.events = POLLOUT; } else { - av_log(NULL, AV_LOG_ERROR, "%s\n", ERR_error_string(ERR_get_error(), NULL)); + av_log(h, AV_LOG_ERROR, "%s\n", ERR_error_string(ERR_get_error(), NULL)); return AVERROR(EIO); } #endif - if (h->flags & URL_FLAG_NONBLOCK) + if (h->flags & AVIO_FLAG_NONBLOCK) return AVERROR(EAGAIN); while (1) { int n = poll(&p, 1, 100); @@ -148,13 +148,13 @@ static int tls_open(URLContext *h, const char *uri, int flags) #elif CONFIG_OPENSSL c->ctx = SSL_CTX_new(SSLv3_client_method()); if (!c->ctx) { - av_log(NULL, AV_LOG_ERROR, "%s\n", ERR_error_string(ERR_get_error(), NULL)); + av_log(h, AV_LOG_ERROR, "%s\n", ERR_error_string(ERR_get_error(), NULL)); ret = AVERROR(EIO); goto fail; } c->ssl = SSL_new(c->ctx); if (!c->ssl) { - av_log(NULL, AV_LOG_ERROR, "%s\n", ERR_error_string(ERR_get_error(), NULL)); + av_log(h, AV_LOG_ERROR, "%s\n", ERR_error_string(ERR_get_error(), NULL)); ret = AVERROR(EIO); goto fail; } @@ -166,7 +166,7 @@ static int tls_open(URLContext *h, const char *uri, int flags) if (ret > 0) break; if (ret == 0) { - av_log(NULL, AV_LOG_ERROR, "Unable to negotiate TLS/SSL session\n"); + av_log(h, AV_LOG_ERROR, "Unable to negotiate TLS/SSL session\n"); ret = AVERROR(EIO); goto fail; } diff --git a/libavutil/aes.c b/libavutil/aes.c index 49093efc53..af55261864 100644 --- a/libavutil/aes.c +++ b/libavutil/aes.c @@ -222,11 +222,9 @@ int av_aes_init(AVAES *a, const uint8_t *key, int key_bits, int decrypt) a->rounds = rounds; memcpy(tk, key, KC * 4); + memcpy(a->round_key[0].u8, key, KC * 4); - for (t = 0; t < (rounds + 1) * 16;) { - memcpy(a->round_key[0].u8 + t, tk, KC * 4); - t += KC * 4; - + for (t = KC * 4; t < (rounds + 1) * 16; t += KC * 4) { for (i = 0; i < 4; i++) tk[0][i] ^= sbox[tk[KC - 1][(i + 1) & 3]]; tk[0][0] ^= rcon[rconpointer++]; @@ -239,6 +237,8 @@ int av_aes_init(AVAES *a, const uint8_t *key, int key_bits, int decrypt) for (i = 0; i < 4; i++) tk[j][i] ^= sbox[tk[j - 1][i]]; } + + memcpy(a->round_key[0].u8 + t, tk, KC * 4); } if (decrypt) {