diff --git a/Changelog b/Changelog index 24a3c01de5..98179ea946 100644 --- a/Changelog +++ b/Changelog @@ -1,7 +1,31 @@ Entries are sorted chronologically from oldest to youngest within each release, releases are sorted from youngest to oldest. -version : +version 2.3.3: +- h264: fix grayscale only decoding with weighted prediction +- mjpegdec: support AV_PIX_FMT_YUV420P16 with upscale_h +- proresenc_ks: fix buffer overflow +- matroskadec: fix crash + +version 2.3.2: +- snow: fix null pointer dereference +- huffyucdec: fix overread +- vc1dec: fix crash +- iff: fix out of array access +- matroskaenc: fix assertion failure +- cdgraphics: fix infinite loop +- dvdsub_parser: fix infinite loop +- mpeg12dec: support decoding some broken files +- v4l2enc: fix crash +- h264_parser: fix handling huge resolutions +- h264_mp4toannexb_bsf: multiple bugfixes + +version 2.3.1: +- public AVDCT API/ABI for DCT functions +- g2meet: allow size changes within original sizes +- dv: improved error resilience, fixing Ticket2340 and Ticket2341 + +version 2.3: - AC3 fixed-point decoding - shuffleplanes filter - subfile protocol diff --git a/MAINTAINERS b/MAINTAINERS index 38437725fb..08d771f7c5 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -14,7 +14,6 @@ patches and related discussions. Project Leader ============== -Michael Niedermayer final design decisions @@ -528,8 +527,8 @@ x86 Michael Niedermayer Releases ======== +2.3 Michael Niedermayer 2.2 Michael Niedermayer -2.1 Michael Niedermayer 1.2 Michael Niedermayer If you want to maintain an older release, please contact us diff --git a/Makefile b/Makefile index 86b3508425..e83ec39eb5 100644 --- a/Makefile +++ b/Makefile @@ -110,7 +110,7 @@ endef $(foreach P,$(PROGS),$(eval $(call DOPROG,$(P:$(PROGSSUF)$(EXESUF)=)))) -ffprobe.o cmdutils.o : libavutil/ffversion.h +ffprobe.o cmdutils.o libavcodec/utils.o libavformat/utils.o libavdevice/avdevice.o libavfilter/avfilter.o libavutil/utils.o libpostproc/postprocess.o libswresample/swresample.o libswscale/utils.o : libavutil/ffversion.h $(PROGS): %$(PROGSSUF)$(EXESUF): %$(PROGSSUF)_g$(EXESUF) $(CP) $< $@ diff --git a/RELEASE b/RELEASE index bd5ee42fcc..e75da3e63d 100644 --- a/RELEASE +++ b/RELEASE @@ -1 +1 @@ -2.2.git +2.3.6 diff --git a/RELEASE_NOTES b/RELEASE_NOTES index 145abfaca7..6323cf543c 100644 --- a/RELEASE_NOTES +++ b/RELEASE_NOTES @@ -7,9 +7,10 @@ since the release of FFmpeg 2.2. In this release, there are lots of internal overhauls that make FFmpeg a - more accessible project for new developers. Many important new features - like QTKit and AVFoundation input devices are committed. Contributions done - by Libav such as a new native Opus decoder are also merged. + more accessible project for new developers. Many important new + optimizations and features like QTKit and AVFoundation input devices are + committed. Contributions done by Libav such as a new native Opus decoder + are also merged. Because of the increasing difficulty to maintain and lack of maintainers, we are very sorry to say that we have removed all Blackfin and SPARC @@ -17,8 +18,9 @@ interested in maintaining optimization for these two architecture, feel free to contact us and we will restore the code! - Since this release, the traditional Changelog file is upgraded to this - modern-looking release note. Old changelogs are moved to doc/Changelog.old. + Oh, and since this release, this modern-looking release note is provided in + addition to the old-style Changelog file, to make it easier for you to + focus on the most important features in this release. Enjoy! @@ -33,9 +35,9 @@ • libavutil 52.92.100 • libavcodec 55.69.100 - • libavformat 55.47.100 + • libavformat 55.48.100 • libavdevice 55.13.102 - • libavfilter 4.10.100 + • libavfilter 4.11.100 • libswscale 2. 6.100 • libswresample 0.19.100 • libpostproc 52. 3.100 @@ -103,7 +105,7 @@ Other interesting new features including hqx video filter, a pixel art scaling filter; a fixed-point AC-3 decoder contributed by Imagination Technologies; an On2 TrueMotion VP7 video decoder; an HTML5 WebVTT - subtitle decoder that allows creation of WebVTT from any text-based + subtitle encoder that allows creation of WebVTT from any text-based subtitles; and an 1-bit Direct Stream Digital audio decoder. ┌────────────────────────────┐ diff --git a/cmdutils.c b/cmdutils.c index 67bb66e9b5..081d37b26e 100644 --- a/cmdutils.c +++ b/cmdutils.c @@ -1857,7 +1857,7 @@ int read_yesno(void) int cmdutils_read_file(const char *filename, char **bufptr, size_t *size) { - int ret; + int64_t ret; FILE *f = av_fopen_utf8(filename, "rb"); if (!f) { diff --git a/configure b/configure index 4ed43a0fdd..d61c6f9867 100755 --- a/configure +++ b/configure @@ -4528,6 +4528,7 @@ EOF fi check_ldflags -Wl,--as-needed +check_ldflags -Wl,-z,noexecstack if check_func dlopen; then ldl= @@ -5534,6 +5535,7 @@ enabled getenv || echo "#define getenv(x) NULL" >> $TMPH mkdir -p doc +mkdir -p tests echo "@c auto-generated by configure" > doc/config.texi print_config ARCH_ "$config_files" $ARCH_LIST diff --git a/doc/APIchanges b/doc/APIchanges index e87f16579d..2497d8854a 100644 --- a/doc/APIchanges +++ b/doc/APIchanges @@ -15,13 +15,13 @@ libavutil: 2012-10-22 API changes, most recent first: -2014-07-14 - xxxxxxx - lavf 55.47.100 - avformat.h +2014-07-14 - 62227a7 - lavf 55.47.100 - avformat.h Add av_stream_get_parser() -2014-07-xx - xxxxxxx - lavu 53.18.0 - display.h +2014-07-09 - c67690f / a54f03b - lavu 52.92.100 / 53.18.0 - display.h Add av_display_matrix_flip() to flip the transformation matrix. -2014-07-xx - xxxxxxx - lavc 55.56.0 - dv_profile.h +2014-07-09 - 1b58f13 / f6ee61f - lavc 55.69.100 / 55.56.0 - dv_profile.h Add a public API for DV profile handling. 2014-06-20 - 0dceefc / 9e500ef - lavu 52.90.100 / 53.17.0 - imgutils.h @@ -35,6 +35,10 @@ API changes, most recent first: is now setting AVStream.time_base, instead of AVStream.codec.time_base as was done previously. The old method is now deprecated. +2014-06-11 - 67d29da - lavc 55.66.101 - avcodec.h + Increase FF_INPUT_BUFFER_PADDING_SIZE to 32 due to some corner cases needing + it + 2014-06-10 - xxxxxxx - lavf 55.43.100 - avformat.h New field int64_t max_analyze_duration2 instead of deprecated int max_analyze_duration. @@ -42,7 +46,7 @@ API changes, most recent first: 2014-05-30 - 00759d7 - lavu 52.89.100 - opt.h Add av_opt_copy() -2014-04-xx - 03bb99a / 0957b27 - lavc 55.66.100 / 55.54.0 - avcodec.h +2014-06-01 - 03bb99a / 0957b27 - lavc 55.66.100 / 55.54.0 - avcodec.h Add AVCodecContext.side_data_only_packets to allow encoders to output packets with only side data. This option may become mandatory in the future, so all users are recommended to update their code and enable this option. @@ -52,7 +56,7 @@ API changes, most recent first: AVColorTransferCharacteristic, and AVChromaLocation) inside lavu. And add AVFrame fields for them. -2014-04-xx - bdb2e80 / b2d4565 - lavr 1.3.0 - avresample.h +2014-05-29 - bdb2e80 / b2d4565 - lavr 1.3.0 - avresample.h Add avresample_max_output_samples 2014-05-24 - d858ee7 / 6d21259 - lavf 55.42.100 / 55.19.0 - avformat.h @@ -101,10 +105,10 @@ API changes, most recent first: 2014-05-11 - 14aef38 / 66e6c8a - lavu 52.83.100 / 53.14.0 - pixfmt.h Add AV_PIX_FMT_VDA for new-style VDA acceleration. -2014-05-xx - xxxxxxx - lavu 52.82.0 - fifo.h +2014-05-xx - xxxxxxx - lavu 52.82.100 - fifo.h Add av_fifo_freep() function. -2014-05-02 - ba52fb11 - lavu 52.81.0 - opt.h +2014-05-02 - ba52fb11 - lavu 52.81.100 - opt.h Add av_opt_set_dict2() function. 2014-05-01 - e77b985 / a2941c8 - lavc 55.60.103 / 55.50.3 - avcodec.h diff --git a/doc/Doxyfile b/doc/Doxyfile index 8697e6c551..2ae11e63f9 100644 --- a/doc/Doxyfile +++ b/doc/Doxyfile @@ -31,7 +31,7 @@ PROJECT_NAME = FFmpeg # This could be handy for archiving the generated documentation or # if some version control system is used. -PROJECT_NUMBER = +PROJECT_NUMBER = 2.3.6 # With the PROJECT_LOGO tag one can specify a logo or icon that is included # in the documentation. The maximum height of the logo should not exceed 55 diff --git a/doc/examples/transcoding.c b/doc/examples/transcoding.c index a8f4210e6e..d7c4a84de9 100644 --- a/doc/examples/transcoding.c +++ b/doc/examples/transcoding.c @@ -116,6 +116,10 @@ static int open_output_file(const char *filename) || dec_ctx->codec_type == AVMEDIA_TYPE_AUDIO) { /* in this example, we choose transcoding to same codec */ encoder = avcodec_find_encoder(dec_ctx->codec_id); + if (!encoder) { + av_log(NULL, AV_LOG_FATAL, "Neccessary encoder not found\n"); + return AVERROR_INVALIDDATA; + } /* In this example, we transcode to same properties (picture size, * sample rate etc.). These properties can be changed for output diff --git a/doc/filters.texi b/doc/filters.texi index 0f73314a12..9064f4aaba 100644 --- a/doc/filters.texi +++ b/doc/filters.texi @@ -491,7 +491,7 @@ aeval=val(ch)/2:c=same @item Invert phase of the second channel: @example -eval=val(0)|-val(1) +aeval=val(0)|-val(1) @end example @end itemize @@ -3968,7 +3968,7 @@ within the parameter list. @item Show the text at the center of the video frame: @example -drawtext="fontsize=30:fontfile=FreeSerif.ttf:text='hello world':x=(w-text_w)/2:y=(h-text_h-line_h)/2" +drawtext="fontsize=30:fontfile=FreeSerif.ttf:text='hello world':x=(w-text_w)/2:y=(h-text_h)/2" @end example @item @@ -9318,7 +9318,7 @@ Default value is "all", which will cycle through the list of all tests. Some examples: @example -testsrc=t=dc_luma +mptestsrc=t=dc_luma @end example will generate a "dc_luma" test pattern. diff --git a/doc/indevs.texi b/doc/indevs.texi index 4205808776..5cac07f16f 100644 --- a/doc/indevs.texi +++ b/doc/indevs.texi @@ -483,6 +483,21 @@ ffplay -f lavfi "movie=test.avi[out0];amovie=test.wav[out1]" @end itemize +@section libcdio + +Audio-CD input device based on cdio. + +To enable this input device during configuration you need libcdio +installed on your system. + +This device allows playing and grabbing from an Audio-CD. + +For example to copy with @command{ffmpeg} the entire Audio-CD in /dev/sr0, +you may run the command: +@example +ffmpeg -f libcdio -i /dev/sr0 cd.wav +@end example + @section libdc1394 IIDC1394 input device, based on libdc1394 and libraw1394. diff --git a/doc/utils.texi b/doc/utils.texi index c46ad4523b..72aef7c718 100644 --- a/doc/utils.texi +++ b/doc/utils.texi @@ -858,7 +858,7 @@ Return 1 if @var{x} is lesser than or equal to @var{y}, 0 otherwise. Return the maximum between @var{x} and @var{y}. @item min(x, y) -Return the maximum between @var{x} and @var{y}. +Return the minimum between @var{x} and @var{y}. @item mod(x, y) Compute the remainder of division of @var{x} by @var{y}. diff --git a/ffmpeg.c b/ffmpeg.c index 1c1a5599d0..af171d23ce 100644 --- a/ffmpeg.c +++ b/ffmpeg.c @@ -578,6 +578,14 @@ static void write_frame(AVFormatContext *s, AVPacket *pkt, OutputStream *ost) AVCodecContext *avctx = ost->st->codec; int ret; + if (!ost->st->codec->extradata_size && ost->enc_ctx->extradata_size) { + ost->st->codec->extradata = av_mallocz(ost->enc_ctx->extradata_size + FF_INPUT_BUFFER_PADDING_SIZE); + if (ost->st->codec->extradata) { + memcpy(ost->st->codec->extradata, ost->enc_ctx->extradata, ost->enc_ctx->extradata_size); + ost->st->codec->extradata_size = ost->enc_ctx->extradata_size; + } + } + if ((avctx->codec_type == AVMEDIA_TYPE_VIDEO && video_sync_method == VSYNC_DROP) || (avctx->codec_type == AVMEDIA_TYPE_AUDIO && audio_sync_method < 0)) pkt->pts = pkt->dts = AV_NOPTS_VALUE; @@ -1799,18 +1807,10 @@ static int decode_audio(InputStream *ist, AVPacket *pkt, int *got_output) for (i = 0; i < nb_filtergraphs; i++) if (ist_in_filtergraph(filtergraphs[i], ist)) { FilterGraph *fg = filtergraphs[i]; - int j; if (configure_filtergraph(fg) < 0) { av_log(NULL, AV_LOG_FATAL, "Error reinitializing filters!\n"); exit_program(1); } - for (j = 0; j < fg->nb_outputs; j++) { - OutputStream *ost = fg->outputs[j]->ost; - if (ost->enc->type == AVMEDIA_TYPE_AUDIO && - !(ost->enc->capabilities & CODEC_CAP_VARIABLE_FRAME_SIZE)) - av_buffersink_set_frame_size(ost->filter->filter, - ost->enc_ctx->frame_size); - } } } @@ -3419,7 +3419,7 @@ static int process_input(int file_index) } /* add the stream-global side data to the first packet */ - if (ist->nb_packets == 1) + if (ist->nb_packets == 1) { if (ist->st->nb_side_data) av_packet_split_side_data(&pkt); for (i = 0; i < ist->st->nb_side_data; i++) { @@ -3435,6 +3435,7 @@ static int process_input(int file_index) memcpy(dst_data, src_sd->data, src_sd->size); } + } if (pkt.dts != AV_NOPTS_VALUE) pkt.dts += av_rescale_q(ifile->ts_offset, AV_TIME_BASE_Q, ist->st->time_base); diff --git a/ffmpeg_filter.c b/ffmpeg_filter.c index 50ee422c6c..7b75e6fe5e 100644 --- a/ffmpeg_filter.c +++ b/ffmpeg_filter.c @@ -919,6 +919,16 @@ int configure_filtergraph(FilterGraph *fg) } fg->reconfiguration = 1; + + for (i = 0; i < fg->nb_outputs; i++) { + OutputStream *ost = fg->outputs[i]->ost; + if (ost && + ost->enc->type == AVMEDIA_TYPE_AUDIO && + !(ost->enc->capabilities & CODEC_CAP_VARIABLE_FRAME_SIZE)) + av_buffersink_set_frame_size(ost->filter->filter, + ost->enc_ctx->frame_size); + } + return 0; } diff --git a/ffmpeg_opt.c b/ffmpeg_opt.c index ab13d3cf16..a825062a7d 100644 --- a/ffmpeg_opt.c +++ b/ffmpeg_opt.c @@ -1828,7 +1828,7 @@ static int open_output_file(OptionsContext *o, const char *filename) /* pick the "best" stream of each type */ /* video: highest resolution */ - if (!o->video_disable && oc->oformat->video_codec != AV_CODEC_ID_NONE) { + if (!o->video_disable && av_guess_codec(oc->oformat, NULL, filename, NULL, AVMEDIA_TYPE_VIDEO) != AV_CODEC_ID_NONE) { int area = 0, idx = -1; int qcr = avformat_query_codec(oc->oformat, oc->oformat->video_codec, 0); for (i = 0; i < nb_input_streams; i++) { @@ -1850,7 +1850,7 @@ static int open_output_file(OptionsContext *o, const char *filename) } /* audio: most channels */ - if (!o->audio_disable && oc->oformat->audio_codec != AV_CODEC_ID_NONE) { + if (!o->audio_disable && av_guess_codec(oc->oformat, NULL, filename, NULL, AVMEDIA_TYPE_AUDIO) != AV_CODEC_ID_NONE) { int channels = 0, idx = -1; for (i = 0; i < nb_input_streams; i++) { ist = input_streams[i]; diff --git a/ffserver.c b/ffserver.c index 08f7878541..fa04a54550 100644 --- a/ffserver.c +++ b/ffserver.c @@ -2977,6 +2977,8 @@ static int prepare_sdp_description(FFStream *stream, uint8_t **pbuffer, AVDictionaryEntry *entry = av_dict_get(stream->metadata, "title", NULL, 0); int i; + *pbuffer = NULL; + avc = avformat_alloc_context(); if (avc == NULL || !rtp_format) { return -1; @@ -3013,7 +3015,7 @@ static int prepare_sdp_description(FFStream *stream, uint8_t **pbuffer, av_free(avc); av_free(avs); - return strlen(*pbuffer); + return *pbuffer ? strlen(*pbuffer) : AVERROR(ENOMEM); } static void rtsp_cmd_options(HTTPContext *c, const char *url) diff --git a/libavcodec/Makefile b/libavcodec/Makefile index 0bbfa27e48..e5233f9496 100644 --- a/libavcodec/Makefile +++ b/libavcodec/Makefile @@ -15,6 +15,7 @@ HEADERS = avcodec.h \ OBJS = allcodecs.o \ audioconvert.o \ + avdct.o \ avpacket.o \ avpicture.o \ bitstream.o \ diff --git a/libavcodec/aac_parser.c b/libavcodec/aac_parser.c index ab6ca4e268..cb93ba9482 100644 --- a/libavcodec/aac_parser.c +++ b/libavcodec/aac_parser.c @@ -34,7 +34,7 @@ static int aac_sync(uint64_t state, AACAC3ParseContext *hdr_info, int size; union { uint64_t u64; - uint8_t u8[8]; + uint8_t u8[8 + FF_INPUT_BUFFER_PADDING_SIZE]; } tmp; tmp.u64 = av_be2ne64(state); diff --git a/libavcodec/ac3_parser.c b/libavcodec/ac3_parser.c index dd6d77c9ab..131e180360 100644 --- a/libavcodec/ac3_parser.c +++ b/libavcodec/ac3_parser.c @@ -166,7 +166,7 @@ static int ac3_sync(uint64_t state, AACAC3ParseContext *hdr_info, int err; union { uint64_t u64; - uint8_t u8[8]; + uint8_t u8[8 + FF_INPUT_BUFFER_PADDING_SIZE]; } tmp = { av_be2ne64(state) }; AC3HeaderInfo hdr, *phdr = &hdr; GetBitContext gbc; diff --git a/libavcodec/ac3enc_template.c b/libavcodec/ac3enc_template.c index 192d16f57e..0d6bc45fd8 100644 --- a/libavcodec/ac3enc_template.c +++ b/libavcodec/ac3enc_template.c @@ -263,7 +263,7 @@ static void apply_channel_coupling(AC3EncodeContext *s) energy_cpl = energy[blk][CPL_CH][bnd]; energy_ch = energy[blk][ch][bnd]; blk1 = blk+1; - while (!s->blocks[blk1].new_cpl_coords[ch] && blk1 < s->num_blocks) { + while (blk1 < s->num_blocks && !s->blocks[blk1].new_cpl_coords[ch]) { if (s->blocks[blk1].cpl_in_use) { energy_cpl += energy[blk1][CPL_CH][bnd]; energy_ch += energy[blk1][ch][bnd]; diff --git a/libavcodec/avdct.c b/libavcodec/avdct.c new file mode 100644 index 0000000000..58f4974b49 --- /dev/null +++ b/libavcodec/avdct.c @@ -0,0 +1,124 @@ +/* + * Copyright (c) 2014 Michael Niedermayer + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "avcodec.h" +#include "idctdsp.h" +#include "fdctdsp.h" +#include "avdct.h" + +#define OFFSET(x) offsetof(AVDCT,x) +#define DEFAULT 0 //should be NAN but it does not work as it is not a constant in glibc as required by ANSI/ISO C +//these names are too long to be readable +#define V AV_OPT_FLAG_VIDEO_PARAM +#define A AV_OPT_FLAG_AUDIO_PARAM +#define E AV_OPT_FLAG_ENCODING_PARAM +#define D AV_OPT_FLAG_DECODING_PARAM + +static const AVOption avdct_options[] = { +{"dct", "DCT algorithm", OFFSET(dct_algo), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, 0, INT_MAX, V|E, "dct"}, +{"auto", "autoselect a good one (default)", 0, AV_OPT_TYPE_CONST, {.i64 = FF_DCT_AUTO }, INT_MIN, INT_MAX, V|E, "dct"}, +{"fastint", "fast integer (experimental / for debugging)", 0, AV_OPT_TYPE_CONST, {.i64 = FF_DCT_FASTINT }, INT_MIN, INT_MAX, V|E, "dct"}, +{"int", "accurate integer", 0, AV_OPT_TYPE_CONST, {.i64 = FF_DCT_INT }, INT_MIN, INT_MAX, V|E, "dct"}, +{"mmx", "experimental / for debugging", 0, AV_OPT_TYPE_CONST, {.i64 = FF_DCT_MMX }, INT_MIN, INT_MAX, V|E, "dct"}, +{"altivec", "experimental / for debugging", 0, AV_OPT_TYPE_CONST, {.i64 = FF_DCT_ALTIVEC }, INT_MIN, INT_MAX, V|E, "dct"}, +{"faan", "floating point AAN DCT (experimental / for debugging)", 0, AV_OPT_TYPE_CONST, {.i64 = FF_DCT_FAAN }, INT_MIN, INT_MAX, V|E, "dct"}, + +{"idct", "select IDCT implementation", OFFSET(idct_algo), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, 0, INT_MAX, V|E|D, "idct"}, +{"auto", "autoselect a good one (default)", 0, AV_OPT_TYPE_CONST, {.i64 = FF_IDCT_AUTO }, INT_MIN, INT_MAX, V|E|D, "idct"}, +{"int", "experimental / for debugging", 0, AV_OPT_TYPE_CONST, {.i64 = FF_IDCT_INT }, INT_MIN, INT_MAX, V|E|D, "idct"}, +{"simple", "experimental / for debugging", 0, AV_OPT_TYPE_CONST, {.i64 = FF_IDCT_SIMPLE }, INT_MIN, INT_MAX, V|E|D, "idct"}, +{"simplemmx", "experimental / for debugging", 0, AV_OPT_TYPE_CONST, {.i64 = FF_IDCT_SIMPLEMMX }, INT_MIN, INT_MAX, V|E|D, "idct"}, +{"arm", "experimental / for debugging", 0, AV_OPT_TYPE_CONST, {.i64 = FF_IDCT_ARM }, INT_MIN, INT_MAX, V|E|D, "idct"}, +{"altivec", "experimental / for debugging", 0, AV_OPT_TYPE_CONST, {.i64 = FF_IDCT_ALTIVEC }, INT_MIN, INT_MAX, V|E|D, "idct"}, +#if FF_API_ARCH_SH4 +{"sh4", "experimental / for debugging", 0, AV_OPT_TYPE_CONST, {.i64 = FF_IDCT_SH4 }, INT_MIN, INT_MAX, V|E|D, "idct"}, +#endif +{"simplearm", "experimental / for debugging", 0, AV_OPT_TYPE_CONST, {.i64 = FF_IDCT_SIMPLEARM }, INT_MIN, INT_MAX, V|E|D, "idct"}, +{"simplearmv5te", "experimental / for debugging", 0, AV_OPT_TYPE_CONST, {.i64 = FF_IDCT_SIMPLEARMV5TE }, INT_MIN, INT_MAX, V|E|D, "idct"}, +{"simplearmv6", "experimental / for debugging", 0, AV_OPT_TYPE_CONST, {.i64 = FF_IDCT_SIMPLEARMV6 }, INT_MIN, INT_MAX, V|E|D, "idct"}, +{"simpleneon", "experimental / for debugging", 0, AV_OPT_TYPE_CONST, {.i64 = FF_IDCT_SIMPLENEON }, INT_MIN, INT_MAX, V|E|D, "idct"}, +#if FF_API_ARCH_ALPHA +{"simplealpha", "experimental / for debugging", 0, AV_OPT_TYPE_CONST, {.i64 = FF_IDCT_SIMPLEALPHA }, INT_MIN, INT_MAX, V|E|D, "idct"}, +#endif +{"ipp", "experimental / for debugging", 0, AV_OPT_TYPE_CONST, {.i64 = FF_IDCT_IPP }, INT_MIN, INT_MAX, V|E|D, "idct"}, +{"xvidmmx", "experimental / for debugging", 0, AV_OPT_TYPE_CONST, {.i64 = FF_IDCT_XVIDMMX }, INT_MIN, INT_MAX, V|E|D, "idct"}, +{"faani", "floating point AAN IDCT (experimental / for debugging)", 0, AV_OPT_TYPE_CONST, {.i64 = FF_IDCT_FAAN }, INT_MIN, INT_MAX, V|D|E, "idct"}, +{"simpleauto", "experimental / for debugging", 0, AV_OPT_TYPE_CONST, {.i64 = FF_IDCT_SIMPLEAUTO }, INT_MIN, INT_MAX, V|E|D, "idct"}, +{NULL}, +}; + +static const AVClass avdct_class = { + .class_name = "AVDCT", + .option = avdct_options, + .version = LIBAVUTIL_VERSION_INT, +}; + +const AVClass *avcodec_dct_get_class(void) +{ + return &avdct_class; +} + +AVDCT *avcodec_dct_alloc(void) +{ + AVDCT *dsp = av_mallocz(sizeof(AVDCT)); + + if (!dsp) + return NULL; + + dsp->av_class = &avdct_class; + av_opt_set_defaults(dsp); + + return dsp; +} + +int avcodec_dct_init(AVDCT *dsp) +{ + AVCodecContext *avctx = avcodec_alloc_context3(NULL); + + if (!avctx) + return AVERROR(ENOMEM); + + avctx->idct_algo = dsp->idct_algo; + avctx->dct_algo = dsp->dct_algo; + +#define COPY(src, name) memcpy(&dsp->name, &src.name, sizeof(dsp->name)) + +#if CONFIG_IDCTDSP + { + IDCTDSPContext idsp; + ff_idctdsp_init(&idsp, avctx); + COPY(idsp, idct); + COPY(idsp, idct_permutation); + } +#endif + +#if CONFIG_FDCTDSP + { + FDCTDSPContext fdsp; + ff_fdctdsp_init(&fdsp, avctx); + COPY(fdsp, fdct); + } +#endif + + avcodec_close(avctx); + av_free(avctx); + + return 0; +} diff --git a/libavcodec/avdct.h b/libavcodec/avdct.h new file mode 100644 index 0000000000..4c9d00f904 --- /dev/null +++ b/libavcodec/avdct.h @@ -0,0 +1,78 @@ +/* + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVCODEC_AVDCT_H +#define AVCODEC_AVDCT_H + +#include "libavutil/opt.h" + +/** + * AVDCT context. + * @note function pointers can be NULL if the specific features have been + * disabled at build time. + */ +typedef struct AVDCT { + const AVClass *av_class; + + void (*idct)(int16_t *block /* align 16 */); + + /** + * IDCT input permutation. + * Several optimized IDCTs need a permutated input (relative to the + * normal order of the reference IDCT). + * This permutation must be performed before the idct_put/add. + * Note, normally this can be merged with the zigzag/alternate scan
+ * An example to avoid confusion: + * - (->decode coeffs -> zigzag reorder -> dequant -> reference IDCT -> ...) + * - (x -> reference DCT -> reference IDCT -> x) + * - (x -> reference DCT -> simple_mmx_perm = idct_permutation + * -> simple_idct_mmx -> x) + * - (-> decode coeffs -> zigzag reorder -> simple_mmx_perm -> dequant + * -> simple_idct_mmx -> ...) + */ + uint8_t idct_permutation[64]; + + void (*fdct)(int16_t *block /* align 16 */); + + + /** + * DCT algorithm. + * must use AVOptions to set this field. + */ + int dct_algo; + + /** + * IDCT algorithm. + * must use AVOptions to set this field. + */ + int idct_algo; +} AVDCT; + +/** + * Allocates a AVDCT context. + * This needs to be initialized with avcodec_dct_init() after optionally + * configuring it with AVOptions. + * + * To free it use av_free() + */ +AVDCT *avcodec_dct_alloc(void); +int avcodec_dct_init(AVDCT *); + +const AVClass *avcodec_dct_get_class(void); + +#endif /* AVCODEC_AVDCT_H */ diff --git a/libavcodec/cabac_functions.h b/libavcodec/cabac_functions.h index d7d6d7dfdb..14fdd76b58 100644 --- a/libavcodec/cabac_functions.h +++ b/libavcodec/cabac_functions.h @@ -32,6 +32,10 @@ #include "cabac.h" #include "config.h" +#ifndef UNCHECKED_BITSTREAM_READER +#define UNCHECKED_BITSTREAM_READER !CONFIG_SAFE_BITSTREAM_READER +#endif + #if ARCH_AARCH64 # include "aarch64/cabac.h" #endif diff --git a/libavcodec/cdgraphics.c b/libavcodec/cdgraphics.c index b7a8fa7ba2..3c07fc726e 100644 --- a/libavcodec/cdgraphics.c +++ b/libavcodec/cdgraphics.c @@ -353,10 +353,9 @@ static int cdg_decode_frame(AVCodecContext *avctx, *got_frame = 1; } else { *got_frame = 0; - buf_size = 0; } - return buf_size; + return avpkt->size; } static av_cold int cdg_decode_end(AVCodecContext *avctx) diff --git a/libavcodec/cinepak.c b/libavcodec/cinepak.c index 082d0b232a..d0d07bc9ef 100644 --- a/libavcodec/cinepak.c +++ b/libavcodec/cinepak.c @@ -135,7 +135,7 @@ static int cinepak_decode_vectors (CinepakContext *s, cvid_strip *strip, const uint8_t *eod = (data + size); uint32_t flag, mask; uint8_t *cb0, *cb1, *cb2, *cb3; - unsigned int x, y; + int x, y; char *ip0, *ip1, *ip2, *ip3; flag = 0; diff --git a/libavcodec/cook.c b/libavcodec/cook.c index 5860288e04..4f83c9dc25 100644 --- a/libavcodec/cook.c +++ b/libavcodec/cook.c @@ -1215,8 +1215,8 @@ static av_cold int cook_decode_init(AVCodecContext *avctx) q->num_subpackets++; s++; - if (s > MAX_SUBPACKETS) { - avpriv_request_sample(avctx, "subpackets > %d", MAX_SUBPACKETS); + if (s > FFMIN(MAX_SUBPACKETS, avctx->block_align)) { + avpriv_request_sample(avctx, "subpackets > %d", FFMIN(MAX_SUBPACKETS, avctx->block_align)); return AVERROR_PATCHWELCOME; } } diff --git a/libavcodec/dcadec.c b/libavcodec/dcadec.c index c671fcd722..06fd74c8bf 100644 --- a/libavcodec/dcadec.c +++ b/libavcodec/dcadec.c @@ -2359,6 +2359,10 @@ FF_ENABLE_DEPRECATION_WARNINGS #else if (s->xch_present && !s->xch_disable) { #endif + if (avctx->channel_layout & AV_CH_BACK_CENTER) { + avpriv_request_sample(avctx, "XCh with Back center channel"); + return AVERROR_INVALIDDATA; + } avctx->channel_layout |= AV_CH_BACK_CENTER; if (s->lfe) { avctx->channel_layout |= AV_CH_LOW_FREQUENCY; diff --git a/libavcodec/dirac_arith.h b/libavcodec/dirac_arith.h index 089c71a698..a1fa96b5bc 100644 --- a/libavcodec/dirac_arith.h +++ b/libavcodec/dirac_arith.h @@ -171,6 +171,10 @@ static inline int dirac_get_arith_uint(DiracArith *c, int follow_ctx, int data_c { int ret = 1; while (!dirac_get_arith_bit(c, follow_ctx)) { + if (ret >= 0x40000000) { + av_log(NULL, AV_LOG_ERROR, "dirac_get_arith_uint overflow\n"); + return -1; + } ret <<= 1; ret += dirac_get_arith_bit(c, data_ctx); follow_ctx = ff_dirac_next_ctx[follow_ctx]; diff --git a/libavcodec/diracdec.c b/libavcodec/diracdec.c index a18c867a3a..806ff82c92 100644 --- a/libavcodec/diracdec.c +++ b/libavcodec/diracdec.c @@ -611,10 +611,10 @@ static av_always_inline void decode_subband_internal(DiracContext *s, SubBand *b top = 0; for (cb_y = 0; cb_y < cb_height; cb_y++) { - bottom = (b->height * (cb_y+1)) / cb_height; + bottom = (b->height * (cb_y+1LL)) / cb_height; left = 0; for (cb_x = 0; cb_x < cb_width; cb_x++) { - right = (b->width * (cb_x+1)) / cb_width; + right = (b->width * (cb_x+1LL)) / cb_width; codeblock(s, b, &gb, &c, left, right, top, bottom, blockcnt_one, is_arith); left = right; } @@ -1003,8 +1003,8 @@ static int dirac_unpack_idwt_params(DiracContext *s) /* Codeblock parameters (core syntax only) */ if (get_bits1(gb)) { for (i = 0; i <= s->wavelet_depth; i++) { - CHECKEDREAD(s->codeblock[i].width , tmp < 1, "codeblock width invalid\n") - CHECKEDREAD(s->codeblock[i].height, tmp < 1, "codeblock height invalid\n") + CHECKEDREAD(s->codeblock[i].width , tmp < 1 || tmp > (s->avctx->width >>s->wavelet_depth-i), "codeblock width invalid\n") + CHECKEDREAD(s->codeblock[i].height, tmp < 1 || tmp > (s->avctx->height>>s->wavelet_depth-i), "codeblock height invalid\n") } CHECKEDREAD(s->codeblock_mode, tmp > 1, "unknown codeblock mode\n") diff --git a/libavcodec/dnxhddec.c b/libavcodec/dnxhddec.c index 787c6c5ec4..06800746d1 100644 --- a/libavcodec/dnxhddec.c +++ b/libavcodec/dnxhddec.c @@ -38,6 +38,7 @@ typedef struct DNXHDContext { BlockDSPContext bdsp; int64_t cid; ///< compression id unsigned int width, height; + enum AVPixelFormat pix_fmt; unsigned int mb_width, mb_height; uint32_t mb_scan_index[68]; /* max for 1080p */ int cur_field; ///< current interlaced field @@ -141,7 +142,7 @@ static int dnxhd_decode_header(DNXHDContext *ctx, AVFrame *frame, ctx->is_444 = 0; if (buf[0x4] == 0x2) { - ctx->avctx->pix_fmt = AV_PIX_FMT_YUV444P10; + ctx->pix_fmt = AV_PIX_FMT_YUV444P10; ctx->avctx->bits_per_raw_sample = 10; if (ctx->bit_depth != 10) { ff_blockdsp_init(&ctx->bdsp, ctx->avctx); @@ -151,7 +152,7 @@ static int dnxhd_decode_header(DNXHDContext *ctx, AVFrame *frame, } ctx->is_444 = 1; } else if (buf[0x21] & 0x40) { - ctx->avctx->pix_fmt = AV_PIX_FMT_YUV422P10; + ctx->pix_fmt = AV_PIX_FMT_YUV422P10; ctx->avctx->bits_per_raw_sample = 10; if (ctx->bit_depth != 10) { ff_blockdsp_init(&ctx->bdsp, ctx->avctx); @@ -160,7 +161,7 @@ static int dnxhd_decode_header(DNXHDContext *ctx, AVFrame *frame, ctx->decode_dct_block = dnxhd_decode_dct_block_10; } } else { - ctx->avctx->pix_fmt = AV_PIX_FMT_YUV422P; + ctx->pix_fmt = AV_PIX_FMT_YUV422P; ctx->avctx->bits_per_raw_sample = 8; if (ctx->bit_depth != 8) { ff_blockdsp_init(&ctx->bdsp, ctx->avctx); @@ -446,7 +447,13 @@ decode_coding_unit: avctx->width, avctx->height, ctx->width, ctx->height); first_field = 1; } + if (avctx->pix_fmt != AV_PIX_FMT_NONE && avctx->pix_fmt != ctx->pix_fmt) { + av_log(avctx, AV_LOG_WARNING, "pix_fmt changed: %s -> %s\n", + av_get_pix_fmt_name(avctx->pix_fmt), av_get_pix_fmt_name(ctx->pix_fmt)); + first_field = 1; + } + avctx->pix_fmt = ctx->pix_fmt; ret = ff_set_dimensions(avctx, ctx->width, ctx->height); if (ret < 0) return ret; diff --git a/libavcodec/dvdsub_parser.c b/libavcodec/dvdsub_parser.c index e50c3396e4..32a945ed65 100644 --- a/libavcodec/dvdsub_parser.c +++ b/libavcodec/dvdsub_parser.c @@ -45,8 +45,11 @@ static int dvdsub_parse(AVCodecParserContext *s, DVDSubParseContext *pc = s->priv_data; if (pc->packet_index == 0) { - if (buf_size < 2) - return 0; + if (buf_size < 2 || AV_RB16(buf) && buf_size < 6) { + if (buf_size) + av_log(avctx, AV_LOG_DEBUG, "Parser input %d too small\n", buf_size); + return buf_size; + } pc->packet_len = AV_RB16(buf); if (pc->packet_len == 0) /* HD-DVD subpicture packet */ pc->packet_len = AV_RB32(buf+2); diff --git a/libavcodec/dvdsubdec.c b/libavcodec/dvdsubdec.c index 39b0e25a13..7dbaf17198 100644 --- a/libavcodec/dvdsubdec.c +++ b/libavcodec/dvdsubdec.c @@ -105,6 +105,9 @@ static int decode_rle(uint8_t *bitmap, int linesize, int w, int h, int x, y, len, color; uint8_t *d; + if (start >= buf_size) + return -1; + bit_len = (buf_size - start) * 8; init_get_bits(&gb, buf + start, bit_len); @@ -356,10 +359,12 @@ static int decode_dvd_subtitles(DVDSubContext *ctx, AVSubtitle *sub_header, sub_header->rects[0] = av_mallocz(sizeof(AVSubtitleRect)); sub_header->num_rects = 1; sub_header->rects[0]->pict.data[0] = bitmap; - decode_rle(bitmap, w * 2, w, (h + 1) / 2, - buf, offset1, buf_size, is_8bit); - decode_rle(bitmap + w, w * 2, w, h / 2, - buf, offset2, buf_size, is_8bit); + if (decode_rle(bitmap, w * 2, w, (h + 1) / 2, + buf, offset1, buf_size, is_8bit) < 0) + goto fail; + if (decode_rle(bitmap + w, w * 2, w, h / 2, + buf, offset2, buf_size, is_8bit) < 0) + goto fail; sub_header->rects[0]->pict.data[1] = av_mallocz(AVPALETTE_SIZE); if (is_8bit) { if (yuv_palette == 0) diff --git a/libavcodec/dxa.c b/libavcodec/dxa.c index 0f64b5e619..c8e3f71399 100644 --- a/libavcodec/dxa.c +++ b/libavcodec/dxa.c @@ -329,6 +329,11 @@ static av_cold int decode_init(AVCodecContext *avctx) { DxaDecContext * const c = avctx->priv_data; + if (avctx->width%4 || avctx->height%4) { + avpriv_request_sample(avctx, "dimensions are not a multiple of 4"); + return AVERROR_INVALIDDATA; + } + c->prev = av_frame_alloc(); if (!c->prev) return AVERROR(ENOMEM); diff --git a/libavcodec/exr.c b/libavcodec/exr.c index 62e8521adc..ff2d7b062c 100644 --- a/libavcodec/exr.c +++ b/libavcodec/exr.c @@ -1011,6 +1011,22 @@ static int decode_header(EXRContext *s) int current_channel_offset = 0; int magic_number, version, flags, i; + s->xmin = ~0; + s->xmax = ~0; + s->ymin = ~0; + s->ymax = ~0; + s->xdelta = ~0; + s->ydelta = ~0; + s->channel_offsets[0] = -1; + s->channel_offsets[1] = -1; + s->channel_offsets[2] = -1; + s->channel_offsets[3] = -1; + s->pixel_type = EXR_UNKNOWN; + s->compression = EXR_UNKN; + s->nb_channels = 0; + s->w = 0; + s->h = 0; + if (bytestream2_get_bytes_left(&s->gb) < 10) { av_log(s->avctx, AV_LOG_ERROR, "Header too short to parse.\n"); return AVERROR_INVALIDDATA; @@ -1351,21 +1367,6 @@ static av_cold int decode_init(AVCodecContext *avctx) float one_gamma = 1.0f / s->gamma; s->avctx = avctx; - s->xmin = ~0; - s->xmax = ~0; - s->ymin = ~0; - s->ymax = ~0; - s->xdelta = ~0; - s->ydelta = ~0; - s->channel_offsets[0] = -1; - s->channel_offsets[1] = -1; - s->channel_offsets[2] = -1; - s->channel_offsets[3] = -1; - s->pixel_type = EXR_UNKNOWN; - s->compression = EXR_UNKN; - s->nb_channels = 0; - s->w = 0; - s->h = 0; if ( one_gamma > 0.9999f && one_gamma < 1.0001f ) { for ( i = 0; i < 65536; ++i ) { diff --git a/libavcodec/ffv1.c b/libavcodec/ffv1.c index ab58a6074f..6073bc4461 100644 --- a/libavcodec/ffv1.c +++ b/libavcodec/ffv1.c @@ -101,7 +101,7 @@ av_cold int ffv1_init_slice_state(FFV1Context *f, FFV1Context *fs) av_cold int ffv1_init_slices_state(FFV1Context *f) { int i, ret; - for (i = 0; i < f->slice_count; i++) { + for (i = 0; i < f->max_slice_count; i++) { FFV1Context *fs = f->slice_context[i]; if ((ret = ffv1_init_slice_state(f, fs)) < 0) return AVERROR(ENOMEM); @@ -113,10 +113,10 @@ av_cold int ffv1_init_slice_contexts(FFV1Context *f) { int i; - f->slice_count = f->num_h_slices * f->num_v_slices; - av_assert0(f->slice_count > 0); + f->max_slice_count = f->num_h_slices * f->num_v_slices; + av_assert0(f->max_slice_count > 0); - for (i = 0; i < f->slice_count; i++) { + for (i = 0; i < f->max_slice_count; i++) { FFV1Context *fs = av_mallocz(sizeof(*fs)); int sx = i % f->num_h_slices; int sy = i / f->num_h_slices; @@ -201,7 +201,7 @@ av_cold int ffv1_close(AVCodecContext *avctx) ff_thread_release_buffer(avctx, &s->last_picture); av_frame_free(&s->last_picture.f); - for (j = 0; j < s->slice_count; j++) { + for (j = 0; j < s->max_slice_count; j++) { FFV1Context *fs = s->slice_context[j]; for (i = 0; i < s->plane_count; i++) { PlaneContext *p = &fs->plane[i]; @@ -215,14 +215,14 @@ av_cold int ffv1_close(AVCodecContext *avctx) av_freep(&avctx->stats_out); for (j = 0; j < s->quant_table_count; j++) { av_freep(&s->initial_states[j]); - for (i = 0; i < s->slice_count; i++) { + for (i = 0; i < s->max_slice_count; i++) { FFV1Context *sf = s->slice_context[i]; av_freep(&sf->rc_stat2[j]); } av_freep(&s->rc_stat2[j]); } - for (i = 0; i < s->slice_count; i++) + for (i = 0; i < s->max_slice_count; i++) av_freep(&s->slice_context[i]); return 0; diff --git a/libavcodec/ffv1.h b/libavcodec/ffv1.h index 5081397f54..cc354c385e 100644 --- a/libavcodec/ffv1.h +++ b/libavcodec/ffv1.h @@ -117,6 +117,7 @@ typedef struct FFV1Context { struct FFV1Context *slice_context[MAX_SLICES]; int slice_count; + int max_slice_count; int num_v_slices; int num_h_slices; int slice_width; diff --git a/libavcodec/ffv1dec.c b/libavcodec/ffv1dec.c index b10e212ce5..6aece65e6f 100644 --- a/libavcodec/ffv1dec.c +++ b/libavcodec/ffv1dec.c @@ -554,8 +554,11 @@ static int read_extra_header(FFV1Context *f) } f->quant_table_count = get_symbol(c, state, 0); - if (f->quant_table_count > (unsigned)MAX_QUANT_TABLES) + if (f->quant_table_count > (unsigned)MAX_QUANT_TABLES || !f->quant_table_count) { + av_log(f->avctx, AV_LOG_ERROR, "quant table count %d is invalid\n", f->quant_table_count); + f->quant_table_count = 0; return AVERROR_INVALIDDATA; + } for (i = 0; i < f->quant_table_count; i++) { f->context_count[i] = read_quant_tables(c, f->quant_tables[i]); @@ -758,6 +761,7 @@ static int read_header(FFV1Context *f) av_log(f->avctx, AV_LOG_ERROR, "read_quant_table error\n"); return AVERROR_INVALIDDATA; } + f->slice_count = f->max_slice_count; } else if (f->version < 3) { f->slice_count = get_symbol(c, state, 0); } else { @@ -772,8 +776,8 @@ static int read_header(FFV1Context *f) p -= size + trailer; } } - if (f->slice_count > (unsigned)MAX_SLICES || f->slice_count <= 0) { - av_log(f->avctx, AV_LOG_ERROR, "slice count %d is invalid\n", f->slice_count); + if (f->slice_count > (unsigned)MAX_SLICES || f->slice_count <= 0 || f->slice_count > f->max_slice_count) { + av_log(f->avctx, AV_LOG_ERROR, "slice count %d is invalid (max=%d)\n", f->slice_count, f->max_slice_count); return AVERROR_INVALIDDATA; } @@ -996,6 +1000,7 @@ static int init_thread_copy(AVCodecContext *avctx) f->picture.f = NULL; f->last_picture.f = NULL; f->sample_buffer = NULL; + f->max_slice_count = 0; f->slice_count = 0; for (i = 0; i < f->quant_table_count; i++) { @@ -1066,7 +1071,7 @@ static int update_thread_context(AVCodecContext *dst, const AVCodecContext *src) av_assert0(!fdst->sample_buffer); } - av_assert1(fdst->slice_count == fsrc->slice_count); + av_assert1(fdst->max_slice_count == fsrc->max_slice_count); ff_thread_release_buffer(dst, &fdst->picture); diff --git a/libavcodec/ffv1enc.c b/libavcodec/ffv1enc.c index b63ed429d9..a289ff3b0d 100644 --- a/libavcodec/ffv1enc.c +++ b/libavcodec/ffv1enc.c @@ -955,6 +955,7 @@ slices_ok: if ((ret = ffv1_init_slice_contexts(s)) < 0) return ret; + s->slice_count = s->max_slice_count; if ((ret = ffv1_init_slices_state(s)) < 0) return ret; @@ -964,7 +965,7 @@ slices_ok: if (!avctx->stats_out) return AVERROR(ENOMEM); for (i = 0; i < s->quant_table_count; i++) - for (j = 0; j < s->slice_count; j++) { + for (j = 0; j < s->max_slice_count; j++) { FFV1Context *sf = s->slice_context[j]; av_assert0(!sf->rc_stat2[i]); sf->rc_stat2[i] = av_mallocz(s->context_count[i] * @@ -1188,6 +1189,7 @@ static int encode_frame(AVCodecContext *avctx, AVPacket *pkt, for (i = 0; i < f->quant_table_count; i++) memset(f->rc_stat2[i], 0, f->context_count[i] * sizeof(*f->rc_stat2[i])); + av_assert0(f->slice_count == f->max_slice_count); for (j = 0; j < f->slice_count; j++) { FFV1Context *fs = f->slice_context[j]; for (i = 0; i < 256; i++) { diff --git a/libavcodec/flacdec.c b/libavcodec/flacdec.c index b8d45b8e1b..614f5aac37 100644 --- a/libavcodec/flacdec.c +++ b/libavcodec/flacdec.c @@ -471,10 +471,10 @@ static int decode_frame(FLACContext *s) ret = allocate_buffers(s); if (ret < 0) return ret; - ff_flacdsp_init(&s->dsp, s->avctx->sample_fmt, s->bps); s->got_streaminfo = 1; dump_headers(s->avctx, (FLACStreaminfo *)s); } + ff_flacdsp_init(&s->dsp, s->avctx->sample_fmt, s->bps); // dump_headers(s->avctx, (FLACStreaminfo *)s); diff --git a/libavcodec/g2meet.c b/libavcodec/g2meet.c index 60c48c382f..d0cb88cb56 100644 --- a/libavcodec/g2meet.c +++ b/libavcodec/g2meet.c @@ -90,6 +90,7 @@ typedef struct G2MContext { int compression; int width, height, bpp; + int orig_width, orig_height; int tile_width, tile_height; int tiles_x, tiles_y, tile_x, tile_y; @@ -712,8 +713,8 @@ static int g2m_decode_frame(AVCodecContext *avctx, void *data, } c->width = bytestream2_get_be32(&bc); c->height = bytestream2_get_be32(&bc); - if (c->width < 16 || c->width > avctx->width || - c->height < 16 || c->height > avctx->height) { + if (c->width < 16 || c->width > c->orig_width || + c->height < 16 || c->height > c->orig_height) { av_log(avctx, AV_LOG_ERROR, "Invalid frame dimensions %dx%d\n", c->width, c->height); @@ -735,8 +736,10 @@ static int g2m_decode_frame(AVCodecContext *avctx, void *data, } c->tile_width = bytestream2_get_be32(&bc); c->tile_height = bytestream2_get_be32(&bc); - if (!c->tile_width || !c->tile_height || - ((c->tile_width | c->tile_height) & 0xF)) { + if (c->tile_width <= 0 || c->tile_height <= 0 || + ((c->tile_width | c->tile_height) & 0xF) || + c->tile_width * 4LL * c->tile_height >= INT_MAX + ) { av_log(avctx, AV_LOG_ERROR, "Invalid tile dimensions %dx%d\n", c->tile_width, c->tile_height); @@ -882,6 +885,10 @@ static av_cold int g2m_decode_init(AVCodecContext *avctx) avctx->pix_fmt = AV_PIX_FMT_RGB24; + // store original sizes and check against those if resize happens + c->orig_width = avctx->width; + c->orig_height = avctx->height; + return 0; } diff --git a/libavcodec/get_bits.h b/libavcodec/get_bits.h index d8d7b6ea08..d67263c619 100644 --- a/libavcodec/get_bits.h +++ b/libavcodec/get_bits.h @@ -113,6 +113,9 @@ typedef struct RL_VLC_ELEM { * LAST_SKIP_BITS(name, gb, num) * Like SKIP_BITS, to be used if next call is UPDATE_CACHE or CLOSE_READER. * + * BITS_LEFT(name, gb) + * Return the number of bits left + * * For examples see get_bits, show_bits, skip_bits, get_vlc. */ @@ -179,6 +182,8 @@ typedef struct RL_VLC_ELEM { name ## _index = FFMIN(name ## _size_plus8, name ## _index + (num)) #endif +#define BITS_LEFT(name, gb) ((int)((gb)->size_in_bits - name ## _index)) + #define SKIP_BITS(name, gb, num) \ do { \ SKIP_CACHE(name, gb, num); \ diff --git a/libavcodec/gifdec.c b/libavcodec/gifdec.c index 78c8900628..6d9b926b05 100644 --- a/libavcodec/gifdec.c +++ b/libavcodec/gifdec.c @@ -258,26 +258,21 @@ static int gif_read_image(GifState *s, AVFrame *frame) case 1: y1 += 8; ptr += linesize * 8; - if (y1 >= height) { - y1 = pass ? 2 : 4; - ptr = ptr1 + linesize * y1; - pass++; - } break; case 2: y1 += 4; ptr += linesize * 4; - if (y1 >= height) { - y1 = 1; - ptr = ptr1 + linesize; - pass++; - } break; case 3: y1 += 2; ptr += linesize * 2; break; } + while (y1 >= height) { + y1 = 4 >> pass; + ptr = ptr1 + linesize * y1; + pass++; + } } else { ptr += linesize; } diff --git a/libavcodec/h263dec.c b/libavcodec/h263dec.c index 31ec642e9f..7680858769 100644 --- a/libavcodec/h263dec.c +++ b/libavcodec/h263dec.c @@ -336,6 +336,14 @@ static int decode_slice(MpegEncContext *s) s->padding_bug_score += 32; } + if (s->codec_id == AV_CODEC_ID_H263 && + (s->workaround_bugs & FF_BUG_AUTODETECT) && + get_bits_left(&s->gb) >= 64 && + AV_RB64(s->gb.buffer_end - 8) == 0xCDCDCDCDFC7F0000) { + + s->padding_bug_score += 32; + } + if (s->workaround_bugs & FF_BUG_AUTODETECT) { if (s->padding_bug_score > -2 && !s->data_partitioning) s->workaround_bugs |= FF_BUG_NO_PADDING; diff --git a/libavcodec/h264.c b/libavcodec/h264.c index 1d919872fe..34e520d7e4 100644 --- a/libavcodec/h264.c +++ b/libavcodec/h264.c @@ -215,18 +215,18 @@ int ff_h264_check_intra_pred_mode(H264Context *h, int mode, int is_chroma) if ((h->left_samples_available & 0x8080) != 0x8080) { mode = left[mode]; - if (is_chroma && (h->left_samples_available & 0x8080)) { - // mad cow disease mode, aka MBAFF + constrained_intra_pred - mode = ALZHEIMER_DC_L0T_PRED8x8 + - (!(h->left_samples_available & 0x8000)) + - 2 * (mode == DC_128_PRED8x8); - } if (mode < 0) { av_log(h->avctx, AV_LOG_ERROR, "left block unavailable for requested intra mode at %d %d\n", h->mb_x, h->mb_y); return AVERROR_INVALIDDATA; } + if (is_chroma && (h->left_samples_available & 0x8080)) { + // mad cow disease mode, aka MBAFF + constrained_intra_pred + mode = ALZHEIMER_DC_L0T_PRED8x8 + + (!(h->left_samples_available & 0x8000)) + + 2 * (mode == DC_128_PRED8x8); + } } return mode; @@ -248,7 +248,7 @@ const uint8_t *ff_h264_decode_nal(H264Context *h, const uint8_t *src, #define STARTCODE_TEST \ if (i + 2 < length && src[i + 1] == 0 && src[i + 2] <= 3) { \ - if (src[i + 2] != 3) { \ + if (src[i + 2] != 3 && src[i + 2] != 0) { \ /* startcode, so we must be past the end */ \ length = i; \ } \ @@ -321,7 +321,7 @@ const uint8_t *ff_h264_decode_nal(H264Context *h, const uint8_t *src, if (src[si + 2] > 3) { dst[di++] = src[si++]; dst[di++] = src[si++]; - } else if (src[si] == 0 && src[si + 1] == 0) { + } else if (src[si] == 0 && src[si + 1] == 0 && src[si + 2] != 0) { if (src[si + 2] == 3) { // escape dst[di++] = 0; dst[di++] = 0; @@ -392,6 +392,7 @@ void ff_h264_free_tables(H264Context *h, int free_rbsp) if (free_rbsp && h->DPB) { for (i = 0; i < H264_MAX_PICTURE_COUNT; i++) ff_h264_unref_picture(h, &h->DPB[i]); + memset(h->delayed_pic, 0, sizeof(h->delayed_pic)); av_freep(&h->DPB); } else if (h->DPB) { for (i = 0; i < H264_MAX_PICTURE_COUNT; i++) @@ -841,10 +842,10 @@ static void decode_postinit(H264Context *h, int setup_finished) stereo->type = AV_STEREO3D_CHECKERBOARD; break; case 1: - stereo->type = AV_STEREO3D_LINES; + stereo->type = AV_STEREO3D_COLUMNS; break; case 2: - stereo->type = AV_STEREO3D_COLUMNS; + stereo->type = AV_STEREO3D_LINES; break; case 3: if (h->quincunx_subsampling) @@ -990,6 +991,16 @@ int ff_pred_weight_table(H264Context *h) h->luma_log2_weight_denom = get_ue_golomb(&h->gb); if (h->sps.chroma_format_idc) h->chroma_log2_weight_denom = get_ue_golomb(&h->gb); + + if (h->luma_log2_weight_denom > 7U) { + av_log(h->avctx, AV_LOG_ERROR, "luma_log2_weight_denom %d is out of range\n", h->luma_log2_weight_denom); + h->luma_log2_weight_denom = 0; + } + if (h->chroma_log2_weight_denom > 7U) { + av_log(h->avctx, AV_LOG_ERROR, "chroma_log2_weight_denom %d is out of range\n", h->chroma_log2_weight_denom); + h->chroma_log2_weight_denom = 0; + } + luma_def = 1 << h->luma_log2_weight_denom; chroma_def = 1 << h->chroma_log2_weight_denom; @@ -1330,43 +1341,6 @@ int ff_set_ref_count(H264Context *h) static const uint8_t start_code[] = { 0x00, 0x00, 0x01 }; -static int find_start_code(const uint8_t *buf, int buf_size, - int buf_index, int next_avc) -{ - // start code prefix search - for (; buf_index + 3 < next_avc; buf_index++) - // This should always succeed in the first iteration. - if (buf[buf_index] == 0 && - buf[buf_index + 1] == 0 && - buf[buf_index + 2] == 1) - break; - - buf_index += 3; - - if (buf_index >= buf_size) - return buf_size; - - return buf_index; -} - -static int get_avc_nalsize(H264Context *h, const uint8_t *buf, - int buf_size, int *buf_index) -{ - int i, nalsize = 0; - - if (*buf_index >= buf_size - h->nal_length_size) - return -1; - - for (i = 0; i < h->nal_length_size; i++) - nalsize = (nalsize << 8) | buf[(*buf_index)++]; - if (nalsize <= 0 || nalsize > buf_size - *buf_index) { - av_log(h->avctx, AV_LOG_ERROR, - "AVC: nal size %d\n", nalsize); - return -1; - } - return nalsize; -} - static int get_bit_length(H264Context *h, const uint8_t *buf, const uint8_t *ptr, int dst_length, int i, int next_avc) diff --git a/libavcodec/h264.h b/libavcodec/h264.h index 228558b6f4..fd42df8e87 100644 --- a/libavcodec/h264.h +++ b/libavcodec/h264.h @@ -37,6 +37,7 @@ #include "h264dsp.h" #include "h264pred.h" #include "h264qpel.h" +#include "internal.h" // for avpriv_find_start_code() #include "mpegutils.h" #include "parser.h" #include "qpeldsp.h" @@ -337,6 +338,7 @@ typedef struct H264Picture { * H264Context */ typedef struct H264Context { + AVClass *av_class; AVCodecContext *avctx; VideoDSPContext vdsp; H264DSPContext h264dsp; @@ -749,7 +751,7 @@ typedef struct H264Context { int16_t slice_row[MAX_SLICES]; ///< to detect when MAX_SLICES is too low - uint8_t parse_history[4]; + uint8_t parse_history[6]; int parse_history_count; int parse_last_mb; uint8_t *edge_emu_buffer; @@ -1092,6 +1094,34 @@ static av_always_inline int get_dct8x8_allowed(H264Context *h) 0x0001000100010001ULL)); } +static inline int find_start_code(const uint8_t *buf, int buf_size, + int buf_index, int next_avc) +{ + uint32_t state = -1; + + buf_index = avpriv_find_start_code(buf + buf_index, buf + next_avc + 1, &state) - buf - 1; + + return FFMIN(buf_index, buf_size); +} + +static inline int get_avc_nalsize(H264Context *h, const uint8_t *buf, + int buf_size, int *buf_index) +{ + int i, nalsize = 0; + + if (*buf_index >= buf_size - h->nal_length_size) + return -1; + + for (i = 0; i < h->nal_length_size; i++) + nalsize = ((unsigned)nalsize << 8) | buf[(*buf_index)++]; + if (nalsize <= 0 || nalsize > buf_size - *buf_index) { + av_log(h->avctx, AV_LOG_ERROR, + "AVC: nal size %d\n", nalsize); + return -1; + } + return nalsize; +} + int ff_h264_field_end(H264Context *h, int in_setup); int ff_h264_ref_picture(H264Context *h, H264Picture *dst, H264Picture *src); diff --git a/libavcodec/h264_mb.c b/libavcodec/h264_mb.c index 191c01aa74..7feae5761c 100644 --- a/libavcodec/h264_mb.c +++ b/libavcodec/h264_mb.c @@ -420,10 +420,12 @@ static av_always_inline void mc_part_weighted(H264Context *h, int n, int square, int weight1 = 64 - weight0; luma_weight_avg(dest_y, tmp_y, h->mb_linesize, height, 5, weight0, weight1, 0); - chroma_weight_avg(dest_cb, tmp_cb, h->mb_uvlinesize, - chroma_height, 5, weight0, weight1, 0); - chroma_weight_avg(dest_cr, tmp_cr, h->mb_uvlinesize, - chroma_height, 5, weight0, weight1, 0); + if (!CONFIG_GRAY || !(h->flags & CODEC_FLAG_GRAY)) { + chroma_weight_avg(dest_cb, tmp_cb, h->mb_uvlinesize, + chroma_height, 5, weight0, weight1, 0); + chroma_weight_avg(dest_cr, tmp_cr, h->mb_uvlinesize, + chroma_height, 5, weight0, weight1, 0); + } } else { luma_weight_avg(dest_y, tmp_y, h->mb_linesize, height, h->luma_log2_weight_denom, @@ -431,18 +433,20 @@ static av_always_inline void mc_part_weighted(H264Context *h, int n, int square, h->luma_weight[refn1][1][0], h->luma_weight[refn0][0][1] + h->luma_weight[refn1][1][1]); - chroma_weight_avg(dest_cb, tmp_cb, h->mb_uvlinesize, chroma_height, - h->chroma_log2_weight_denom, - h->chroma_weight[refn0][0][0][0], - h->chroma_weight[refn1][1][0][0], - h->chroma_weight[refn0][0][0][1] + - h->chroma_weight[refn1][1][0][1]); - chroma_weight_avg(dest_cr, tmp_cr, h->mb_uvlinesize, chroma_height, - h->chroma_log2_weight_denom, - h->chroma_weight[refn0][0][1][0], - h->chroma_weight[refn1][1][1][0], - h->chroma_weight[refn0][0][1][1] + - h->chroma_weight[refn1][1][1][1]); + if (!CONFIG_GRAY || !(h->flags & CODEC_FLAG_GRAY)) { + chroma_weight_avg(dest_cb, tmp_cb, h->mb_uvlinesize, chroma_height, + h->chroma_log2_weight_denom, + h->chroma_weight[refn0][0][0][0], + h->chroma_weight[refn1][1][0][0], + h->chroma_weight[refn0][0][0][1] + + h->chroma_weight[refn1][1][0][1]); + chroma_weight_avg(dest_cr, tmp_cr, h->mb_uvlinesize, chroma_height, + h->chroma_log2_weight_denom, + h->chroma_weight[refn0][0][1][0], + h->chroma_weight[refn1][1][1][0], + h->chroma_weight[refn0][0][1][1] + + h->chroma_weight[refn1][1][1][1]); + } } } else { int list = list1 ? 1 : 0; @@ -456,15 +460,17 @@ static av_always_inline void mc_part_weighted(H264Context *h, int n, int square, h->luma_log2_weight_denom, h->luma_weight[refn][list][0], h->luma_weight[refn][list][1]); - if (h->use_weight_chroma) { - chroma_weight_op(dest_cb, h->mb_uvlinesize, chroma_height, - h->chroma_log2_weight_denom, - h->chroma_weight[refn][list][0][0], - h->chroma_weight[refn][list][0][1]); - chroma_weight_op(dest_cr, h->mb_uvlinesize, chroma_height, - h->chroma_log2_weight_denom, - h->chroma_weight[refn][list][1][0], - h->chroma_weight[refn][list][1][1]); + if (!CONFIG_GRAY || !(h->flags & CODEC_FLAG_GRAY)) { + if (h->use_weight_chroma) { + chroma_weight_op(dest_cb, h->mb_uvlinesize, chroma_height, + h->chroma_log2_weight_denom, + h->chroma_weight[refn][list][0][0], + h->chroma_weight[refn][list][0][1]); + chroma_weight_op(dest_cr, h->mb_uvlinesize, chroma_height, + h->chroma_log2_weight_denom, + h->chroma_weight[refn][list][1][0], + h->chroma_weight[refn][list][1][1]); + } } } } diff --git a/libavcodec/h264_mp4toannexb_bsf.c b/libavcodec/h264_mp4toannexb_bsf.c index 0f142bb2ad..91605ff863 100644 --- a/libavcodec/h264_mp4toannexb_bsf.c +++ b/libavcodec/h264_mp4toannexb_bsf.c @@ -28,6 +28,7 @@ typedef struct H264BSFContext { uint8_t length_size; uint8_t first_idr; + uint8_t idr_sps_pps_seen; int extradata_parsed; } H264BSFContext; @@ -155,6 +156,7 @@ static int h264_mp4toannexb_filter(AVBitStreamFilterContext *bsfc, return ret; ctx->length_size = ret; ctx->first_idr = 1; + ctx->idr_sps_pps_seen = 0; ctx->extradata_parsed = 1; } @@ -171,11 +173,20 @@ static int h264_mp4toannexb_filter(AVBitStreamFilterContext *bsfc, buf += ctx->length_size; unit_type = *buf & 0x1f; - if (buf + nal_size > buf_end || nal_size < 0) + if (nal_size > buf_end - buf || nal_size < 0) goto fail; - /* prepend only to the first type 5 NAL unit of an IDR picture */ - if (ctx->first_idr && (unit_type == 5 || unit_type == 7 || unit_type == 8)) { + if (ctx->first_idr && (unit_type == 7 || unit_type == 8)) + ctx->idr_sps_pps_seen = 1; + + /* if this is a new IDR picture following an IDR picture, reset the idr flag. + * Just check first_mb_in_slice to be 0 as this is the simplest solution. + * This could be checking idr_pic_id instead, but would complexify the parsing. */ + if (!ctx->first_idr && unit_type == 5 && (buf[1] & 0x80)) + ctx->first_idr = 1; + + /* prepend only to the first type 5 NAL unit of an IDR picture, if no sps/pps are already present */ + if (ctx->first_idr && unit_type == 5 && !ctx->idr_sps_pps_seen) { if ((ret=alloc_and_copy(poutbuf, poutbuf_size, avctx->extradata, avctx->extradata_size, buf, nal_size)) < 0) @@ -185,8 +196,10 @@ static int h264_mp4toannexb_filter(AVBitStreamFilterContext *bsfc, if ((ret=alloc_and_copy(poutbuf, poutbuf_size, NULL, 0, buf, nal_size)) < 0) goto fail; - if (!ctx->first_idr && unit_type == 1) + if (!ctx->first_idr && unit_type == 1) { ctx->first_idr = 1; + ctx->idr_sps_pps_seen = 0; + } } buf += nal_size; diff --git a/libavcodec/h264_parser.c b/libavcodec/h264_parser.c index ea0ab98034..1e1d7581a6 100644 --- a/libavcodec/h264_parser.c +++ b/libavcodec/h264_parser.c @@ -92,7 +92,7 @@ static int h264_find_frame_end(H264Context *h, const uint8_t *buf, state = 7; } else { h->parse_history[h->parse_history_count++]= buf[i]; - if (h->parse_history_count>3) { + if (h->parse_history_count>5) { unsigned int mb, last_mb= h->parse_last_mb; GetBitContext gb; @@ -120,7 +120,7 @@ found: pc->frame_start_found = 0; if (h->is_avc) return next_avc; - return i - (state & 5) - 3 * (state > 7); + return i - (state & 5) - 5 * (state > 7); } static int scan_mmco_reset(AVCodecParserContext *s) @@ -203,10 +203,10 @@ static int scan_mmco_reset(AVCodecParserContext *s) */ static inline int parse_nal_units(AVCodecParserContext *s, AVCodecContext *avctx, - const uint8_t *buf, int buf_size) + const uint8_t * const buf, int buf_size) { H264Context *h = s->priv_data; - const uint8_t *buf_end = buf + buf_size; + int buf_index, next_avc; unsigned int pps_id; unsigned int slice_type; int state = -1, got_reset = 0; @@ -226,26 +226,26 @@ static inline int parse_nal_units(AVCodecParserContext *s, if (!buf_size) return 0; + buf_index = 0; + next_avc = h->is_avc ? 0 : buf_size; for (;;) { int src_length, dst_length, consumed, nalsize = 0; - if (h->is_avc) { - int i; - if (h->nal_length_size >= buf_end - buf) break; - nalsize = 0; - for (i = 0; i < h->nal_length_size; i++) - nalsize = (nalsize << 8) | *buf++; - if (nalsize <= 0 || nalsize > buf_end - buf) { - av_log(h->avctx, AV_LOG_ERROR, "AVC: nal size %d\n", nalsize); + + if (buf_index >= next_avc) { + nalsize = get_avc_nalsize(h, buf, buf_size, &buf_index); + if (nalsize < 0) break; - } - src_length = nalsize; + next_avc = buf_index + nalsize; } else { - buf = avpriv_find_start_code(buf, buf_end, &state); - if (buf >= buf_end) - break; - --buf; - src_length = buf_end - buf; + buf_index = find_start_code(buf, buf_size, buf_index, next_avc); + if (buf_index >= buf_size) + break; + if (buf_index >= next_avc) + continue; } + src_length = next_avc - buf_index; + + state = buf[buf_index]; switch (state & 0x1f) { case NAL_SLICE: case NAL_IDR_SLICE: @@ -262,10 +262,13 @@ static inline int parse_nal_units(AVCodecParserContext *s, } break; } - ptr = ff_h264_decode_nal(h, buf, &dst_length, &consumed, src_length); + ptr = ff_h264_decode_nal(h, buf + buf_index, &dst_length, + &consumed, src_length); if (ptr == NULL || dst_length < 0) break; + buf_index += consumed; + init_get_bits(&h->gb, ptr, 8 * dst_length); switch (h->nal_unit_type) { case NAL_SPS: @@ -440,7 +443,6 @@ static inline int parse_nal_units(AVCodecParserContext *s, return 0; /* no need to evaluate the rest */ } - buf += h->is_avc ? nalsize : consumed; } if (q264) return 0; diff --git a/libavcodec/h264_slice.c b/libavcodec/h264_slice.c index ded26f8465..489000b69e 100644 --- a/libavcodec/h264_slice.c +++ b/libavcodec/h264_slice.c @@ -586,6 +586,17 @@ int ff_h264_update_thread_context(AVCodecContext *dst, h->mb_type_pool = NULL; h->ref_index_pool = NULL; h->motion_val_pool = NULL; + h->intra4x4_pred_mode= NULL; + h->non_zero_count = NULL; + h->slice_table_base = NULL; + h->slice_table = NULL; + h->cbp_table = NULL; + h->chroma_pred_mode_table = NULL; + memset(h->mvd_table, 0, sizeof(h->mvd_table)); + h->direct_table = NULL; + h->list_counts = NULL; + h->mb2b_xy = NULL; + h->mb2br_xy = NULL; for (i = 0; i < 2; i++) { h->rbsp_buffer[i] = NULL; h->rbsp_buffer_size[i] = 0; diff --git a/libavcodec/hevc.c b/libavcodec/hevc.c index afb2baaf65..0a7ba5472e 100644 --- a/libavcodec/hevc.c +++ b/libavcodec/hevc.c @@ -108,7 +108,7 @@ static int pic_arrays_init(HEVCContext *s, const HEVCSPS *sps) if (!s->tab_ipm || !s->cbf_luma || !s->is_pcm) goto fail; - s->filter_slice_edges = av_malloc(ctb_count); + s->filter_slice_edges = av_mallocz(ctb_count); s->tab_slice_address = av_malloc_array(pic_size_in_ctb, sizeof(*s->tab_slice_address)); s->qp_y_tab = av_malloc_array(pic_size_in_ctb, @@ -746,6 +746,8 @@ static int hls_slice_header(HEVCContext *s) s->HEVClc->tu.cu_qp_offset_cb = 0; s->HEVClc->tu.cu_qp_offset_cr = 0; + s->no_rasl_output_flag = IS_IDR(s) || IS_BLA(s) || (s->nal_unit_type == NAL_CRA_NUT && s->last_eos); + return 0; } @@ -978,7 +980,7 @@ static int hls_transform_unit(HEVCContext *s, int x0, int y0, for (i = 0; i < (size * size); i++) { coeffs[i] = ((lc->tu.res_scale_val * coeffs_y[i]) >> 3); } - s->hevcdsp.transform_add[log2_trafo_size-2](dst, coeffs, stride); + s->hevcdsp.transform_add[log2_trafo_size_c-2](dst, coeffs, stride); } } @@ -1007,7 +1009,7 @@ static int hls_transform_unit(HEVCContext *s, int x0, int y0, for (i = 0; i < (size * size); i++) { coeffs[i] = ((lc->tu.res_scale_val * coeffs_y[i]) >> 3); } - s->hevcdsp.transform_add[log2_trafo_size-2](dst, coeffs, stride); + s->hevcdsp.transform_add[log2_trafo_size_c-2](dst, coeffs, stride); } } } else if (blk_idx == 3) { @@ -2378,6 +2380,8 @@ static int hls_decode_entry_wpp(AVCodecContext *avctxt, void *input_ctb_row, int if (more_data < 0) { s->tab_slice_address[ctb_addr_rs] = -1; + avpriv_atomic_int_set(&s1->wpp_err, 1); + ff_thread_report_progress2(s->avctx, ctb_row ,thread, SHIFT_CTB_WPP); return more_data; } @@ -3306,6 +3310,7 @@ static int hevc_update_thread_context(AVCodecContext *dst, s->pocTid0 = s0->pocTid0; s->max_ra = s0->max_ra; s->eos = s0->eos; + s->no_rasl_output_flag = s0->no_rasl_output_flag; s->is_nalff = s0->is_nalff; s->nal_length_size = s0->nal_length_size; @@ -3400,6 +3405,7 @@ static av_cold int hevc_decode_init(AVCodecContext *avctx) s->enable_parallel_tiles = 0; s->picture_struct = 0; + s->eos = 1; if(avctx->active_thread_type & FF_THREAD_SLICE) s->threads_number = avctx->thread_count; @@ -3441,6 +3447,7 @@ static void hevc_decode_flush(AVCodecContext *avctx) HEVCContext *s = avctx->priv_data; ff_hevc_flush_dpb(s); s->max_ra = INT_MAX; + s->eos = 1; } #define OFFSET(x) offsetof(HEVCContext, x) diff --git a/libavcodec/hevc.h b/libavcodec/hevc.h index 2a5ce2523c..9a10022dcc 100644 --- a/libavcodec/hevc.h +++ b/libavcodec/hevc.h @@ -850,6 +850,7 @@ typedef struct HEVCContext { int bs_height; int is_decoded; + int no_rasl_output_flag; HEVCPredContext hpc; HEVCDSPContext hevcdsp; diff --git a/libavcodec/hevc_ps.c b/libavcodec/hevc_ps.c index 98d987dcf4..40b8b74403 100644 --- a/libavcodec/hevc_ps.c +++ b/libavcodec/hevc_ps.c @@ -865,6 +865,11 @@ int ff_hevc_decode_nal_sps(HEVCContext *s) sps->long_term_ref_pics_present_flag = get_bits1(gb); if (sps->long_term_ref_pics_present_flag) { sps->num_long_term_ref_pics_sps = get_ue_golomb_long(gb); + if (sps->num_long_term_ref_pics_sps > 31U) { + av_log(0, AV_LOG_ERROR, "num_long_term_ref_pics_sps %d is out of range.\n", + sps->num_long_term_ref_pics_sps); + goto err; + } for (i = 0; i < sps->num_long_term_ref_pics_sps; i++) { sps->lt_ref_pic_poc_lsb_sps[i] = get_bits(gb, sps->log2_max_poc_lsb); sps->used_by_curr_pic_lt_sps_flag[i] = get_bits1(gb); @@ -1164,6 +1169,14 @@ int ff_hevc_decode_nal_pps(HEVCContext *s) if (pps->cu_qp_delta_enabled_flag) pps->diff_cu_qp_delta_depth = get_ue_golomb_long(gb); + if (pps->diff_cu_qp_delta_depth < 0 || + pps->diff_cu_qp_delta_depth > sps->log2_diff_max_min_coding_block_size) { + av_log(s->avctx, AV_LOG_ERROR, "diff_cu_qp_delta_depth %d is invalid\n", + pps->diff_cu_qp_delta_depth); + ret = AVERROR_INVALIDDATA; + goto err; + } + pps->cb_qp_offset = get_se_golomb(gb); if (pps->cb_qp_offset < -12 || pps->cb_qp_offset > 12) { av_log(s->avctx, AV_LOG_ERROR, "pps_cb_qp_offset out of range: %d\n", @@ -1289,7 +1302,8 @@ int ff_hevc_decode_nal_pps(HEVCContext *s) if (sps->ptl.general_ptl.profile_idc == FF_PROFILE_HEVC_REXT && pps_range_extensions_flag) { av_log(s->avctx, AV_LOG_ERROR, "PPS extension flag is partially implemented.\n"); - pps_range_extensions(s, pps, sps); + if ((ret = pps_range_extensions(s, pps, sps)) < 0) + goto err; } } diff --git a/libavcodec/hevc_refs.c b/libavcodec/hevc_refs.c index 136cc6ff0e..53b4bcf2c1 100644 --- a/libavcodec/hevc_refs.c +++ b/libavcodec/hevc_refs.c @@ -163,7 +163,7 @@ int ff_hevc_output_frame(HEVCContext *s, AVFrame *out, int flush) int min_poc = INT_MAX; int i, min_idx, ret; - if (s->sh.no_output_of_prior_pics_flag == 1) { + if (s->sh.no_output_of_prior_pics_flag == 1 && s->no_rasl_output_flag == 1) { for (i = 0; i < FF_ARRAY_ELEMS(s->DPB); i++) { HEVCFrame *frame = &s->DPB[i]; if ((frame->flags & HEVC_FRAME_FLAG_OUTPUT) && frame->poc != s->poc && diff --git a/libavcodec/huffyuvdec.c b/libavcodec/huffyuvdec.c index 74872d2caa..662095f909 100644 --- a/libavcodec/huffyuvdec.c +++ b/libavcodec/huffyuvdec.c @@ -625,9 +625,9 @@ static void decode_422_bitstream(HYuvContext *s, int count) READ_2PIX(s->temp[0][2 * i ], s->temp[1][i], 1); READ_2PIX(s->temp[0][2 * i + 1], s->temp[2][i], 2); } - for (; i < count && get_bits_left(&s->gb) > 0; i++) { + for (; i < count && BITS_LEFT(re, &s->gb) > 0; i++) { READ_2PIX(s->temp[0][2 * i ], s->temp[1][i], 1); - if (get_bits_left(&s->gb) <= 0) break; + if (BITS_LEFT(re, &s->gb) <= 0) break; READ_2PIX(s->temp[0][2 * i + 1], s->temp[2][i], 2); } for (; i < count; i++) @@ -666,7 +666,7 @@ static void decode_plane_bitstream(HYuvContext *s, int count, int plane) if (s->bps <= 8) { OPEN_READER(re, &s->gb); if (count >= (get_bits_left(&s->gb)) / (32 * 2)) { - for (i = 0; i < count && get_bits_left(&s->gb) > 0; i++) { + for (i = 0; i < count && BITS_LEFT(re, &s->gb) > 0; i++) { READ_2PIX_PLANE(s->temp[0][2 * i], s->temp[0][2 * i + 1], plane, OP8bits); } } else { @@ -678,7 +678,7 @@ static void decode_plane_bitstream(HYuvContext *s, int count, int plane) } else if (s->bps <= 14) { OPEN_READER(re, &s->gb); if (count >= (get_bits_left(&s->gb)) / (32 * 2)) { - for (i = 0; i < count && get_bits_left(&s->gb) > 0; i++) { + for (i = 0; i < count && BITS_LEFT(re, &s->gb) > 0; i++) { READ_2PIX_PLANE(s->temp16[0][2 * i], s->temp16[0][2 * i + 1], plane, OP14bits); } } else { @@ -707,7 +707,7 @@ static void decode_gray_bitstream(HYuvContext *s, int count) count/=2; if (count >= (get_bits_left(&s->gb)) / (32 * 2)) { - for (i = 0; i < count && get_bits_left(&s->gb) > 0; i++) { + for (i = 0; i < count && BITS_LEFT(re, &s->gb) > 0; i++) { READ_2PIX(s->temp[0][2 * i], s->temp[0][2 * i + 1], 0); } } else { @@ -724,7 +724,7 @@ static av_always_inline void decode_bgr_1(HYuvContext *s, int count, int i; OPEN_READER(re, &s->gb); - for (i = 0; i < count && get_bits_left(&s->gb) > 0; i++) { + for (i = 0; i < count && BITS_LEFT(re, &s->gb) > 0; i++) { unsigned int index; int code, n; diff --git a/libavcodec/iff.c b/libavcodec/iff.c index f08a0f70ce..ce06b365fc 100644 --- a/libavcodec/iff.c +++ b/libavcodec/iff.c @@ -677,11 +677,15 @@ static int decode_frame(AVCodecContext *avctx, const uint8_t *buf_end = buf + buf_size; int y, plane, res; GetByteContext gb; + const AVPixFmtDescriptor *desc; if ((res = extract_header(avctx, avpkt)) < 0) return res; if ((res = ff_reget_buffer(avctx, s->frame)) < 0) return res; + + desc = av_pix_fmt_desc_get(avctx->pix_fmt); + if (!s->init && avctx->bits_per_coded_sample <= 8 && avctx->pix_fmt == AV_PIX_FMT_PAL8) { if ((res = cmap_read_palette(avctx, (uint32_t *)s->frame->data[1])) < 0) @@ -721,7 +725,6 @@ static int decode_frame(AVCodecContext *avctx, } else return unsupported(avctx); } else if (avctx->codec_tag == MKTAG('D', 'E', 'E', 'P')) { - const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(avctx->pix_fmt); int raw_width = avctx->width * (av_get_bits_per_pixel(desc) >> 3); int x; for (y = 0; y < avctx->height && buf < buf_end; y++) { @@ -838,7 +841,6 @@ static int decode_frame(AVCodecContext *avctx, } else return unsupported(avctx); } else if (avctx->codec_tag == MKTAG('D', 'E', 'E', 'P')) { // IFF-DEEP - const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(avctx->pix_fmt); if (av_get_bits_per_pixel(desc) == 32) decode_deep_rle32(s->frame->data[0], buf, buf_size, avctx->width, avctx->height, s->frame->linesize[0]); else @@ -847,16 +849,15 @@ static int decode_frame(AVCodecContext *avctx, break; case 4: bytestream2_init(&gb, buf, buf_size); - if (avctx->codec_tag == MKTAG('R', 'G', 'B', '8')) + if (avctx->codec_tag == MKTAG('R', 'G', 'B', '8') && avctx->pix_fmt == AV_PIX_FMT_RGB32) decode_rgb8(&gb, s->frame->data[0], avctx->width, avctx->height, s->frame->linesize[0]); - else if (avctx->codec_tag == MKTAG('R', 'G', 'B', 'N')) + else if (avctx->codec_tag == MKTAG('R', 'G', 'B', 'N') && avctx->pix_fmt == AV_PIX_FMT_RGB444) decode_rgbn(&gb, s->frame->data[0], avctx->width, avctx->height, s->frame->linesize[0]); else return unsupported(avctx); break; case 5: if (avctx->codec_tag == MKTAG('D', 'E', 'E', 'P')) { - const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(avctx->pix_fmt); if (av_get_bits_per_pixel(desc) == 32) decode_deep_tvdc32(s->frame->data[0], buf, buf_size, avctx->width, avctx->height, s->frame->linesize[0], s->tvdc); else diff --git a/libavcodec/indeo3.c b/libavcodec/indeo3.c index aa9c30aca9..97ca180cce 100644 --- a/libavcodec/indeo3.c +++ b/libavcodec/indeo3.c @@ -94,7 +94,7 @@ typedef struct Indeo3DecodeContext { int16_t width, height; uint32_t frame_num; ///< current frame number (zero-based) - uint32_t data_size; ///< size of the frame data in bytes + int data_size; ///< size of the frame data in bytes uint16_t frame_flags; ///< frame properties uint8_t cb_offset; ///< needed for selecting VQ tables uint8_t buf_sel; ///< active frame buffer: 0 - primary, 1 -secondary @@ -899,7 +899,8 @@ static int decode_frame_headers(Indeo3DecodeContext *ctx, AVCodecContext *avctx, GetByteContext gb; const uint8_t *bs_hdr; uint32_t frame_num, word2, check_sum, data_size; - uint32_t y_offset, u_offset, v_offset, starts[3], ends[3]; + int y_offset, u_offset, v_offset; + uint32_t starts[3], ends[3]; uint16_t height, width; int i, j; @@ -981,7 +982,8 @@ static int decode_frame_headers(Indeo3DecodeContext *ctx, AVCodecContext *avctx, ctx->y_data_size = ends[0] - starts[0]; ctx->v_data_size = ends[1] - starts[1]; ctx->u_data_size = ends[2] - starts[2]; - if (FFMAX3(y_offset, v_offset, u_offset) >= ctx->data_size - 16 || + if (FFMIN3(y_offset, v_offset, u_offset) < 0 || + FFMAX3(y_offset, v_offset, u_offset) >= ctx->data_size - 16 || FFMIN3(y_offset, v_offset, u_offset) < gb.buffer - bs_hdr + 16 || FFMIN3(ctx->y_data_size, ctx->v_data_size, ctx->u_data_size) <= 0) { av_log(avctx, AV_LOG_ERROR, "One of the y/u/v offsets is invalid\n"); diff --git a/libavcodec/jpeglsdec.c b/libavcodec/jpeglsdec.c index fb3762dad0..bb8c264ae0 100644 --- a/libavcodec/jpeglsdec.c +++ b/libavcodec/jpeglsdec.c @@ -269,6 +269,11 @@ static inline void ls_decode_line(JLSState *state, MJpegDecodeContext *s, x += stride; } + if (x >= w) { + av_log(NULL, AV_LOG_ERROR, "run overflow\n"); + return; + } + /* decode run termination value */ Rb = R(last, x); RItype = (FFABS(Ra - Rb) <= state->near) ? 1 : 0; diff --git a/libavcodec/jvdec.c b/libavcodec/jvdec.c index 47e8edcae6..9c4a8d4ca3 100644 --- a/libavcodec/jvdec.c +++ b/libavcodec/jvdec.c @@ -43,6 +43,13 @@ static av_cold int decode_init(AVCodecContext *avctx) { JvContext *s = avctx->priv_data; + if (!avctx->width || !avctx->height || + (avctx->width & 7) || (avctx->height & 7)) { + av_log(avctx, AV_LOG_ERROR, "Invalid video dimensions: %dx%d\n", + avctx->width, avctx->height); + return AVERROR(EINVAL); + } + s->frame = av_frame_alloc(); if (!s->frame) return AVERROR(ENOMEM); diff --git a/libavcodec/libilbc.c b/libavcodec/libilbc.c index 898fe83b1c..9fdd3c83f5 100644 --- a/libavcodec/libilbc.c +++ b/libavcodec/libilbc.c @@ -96,8 +96,7 @@ static int ilbc_decode_frame(AVCodecContext *avctx, void *data, if ((ret = ff_get_buffer(avctx, frame, 0)) < 0) return ret; - WebRtcIlbcfix_DecodeImpl((WebRtc_Word16*) frame->data[0], - (const WebRtc_UWord16*) buf, &s->decoder, 1); + WebRtcIlbcfix_DecodeImpl((int16_t *) frame->data[0], (const uint16_t *) buf, &s->decoder, 1); *got_frame_ptr = 1; @@ -170,7 +169,7 @@ static int ilbc_encode_frame(AVCodecContext *avctx, AVPacket *avpkt, if ((ret = ff_alloc_packet2(avctx, avpkt, 50)) < 0) return ret; - WebRtcIlbcfix_EncodeImpl((WebRtc_UWord16*) avpkt->data, (const WebRtc_Word16*) frame->data[0], &s->encoder); + WebRtcIlbcfix_EncodeImpl((uint16_t *) avpkt->data, (const int16_t *) frame->data[0], &s->encoder); avpkt->size = s->encoder.no_of_bytes; *got_packet_ptr = 1; diff --git a/libavcodec/libx264.c b/libavcodec/libx264.c index edf6fc6130..ab3d59a272 100644 --- a/libavcodec/libx264.c +++ b/libavcodec/libx264.c @@ -236,10 +236,10 @@ static int X264_frame(AVCodecContext *ctx, AVPacket *pkt, const AVFrame *frame, case AV_STEREO3D_CHECKERBOARD: fpa_type = 0; break; - case AV_STEREO3D_LINES: + case AV_STEREO3D_COLUMNS: fpa_type = 1; break; - case AV_STEREO3D_COLUMNS: + case AV_STEREO3D_LINES: fpa_type = 2; break; case AV_STEREO3D_SIDEBYSIDE: diff --git a/libavcodec/mjpegdec.c b/libavcodec/mjpegdec.c index 1a774ddc61..7f6e0549b9 100644 --- a/libavcodec/mjpegdec.c +++ b/libavcodec/mjpegdec.c @@ -244,7 +244,8 @@ int ff_mjpeg_decode_dht(MJpegDecodeContext *s) int ff_mjpeg_decode_sof(MJpegDecodeContext *s) { - int len, nb_components, i, width, height, pix_fmt_id, ret; + int len, nb_components, i, width, height, bits, ret; + unsigned pix_fmt_id; int h_count[MAX_COMPONENTS]; int v_count[MAX_COMPONENTS]; @@ -254,11 +255,11 @@ int ff_mjpeg_decode_sof(MJpegDecodeContext *s) /* XXX: verify len field validity */ len = get_bits(&s->gb, 16); s->avctx->bits_per_raw_sample = - s->bits = get_bits(&s->gb, 8); + bits = get_bits(&s->gb, 8); if (s->pegasus_rct) - s->bits = 9; - if (s->bits == 9 && !s->pegasus_rct) + bits = 9; + if (bits == 9 && !s->pegasus_rct) s->rct = 1; // FIXME ugly if(s->lossless && s->avctx->lowres){ @@ -291,7 +292,7 @@ int ff_mjpeg_decode_sof(MJpegDecodeContext *s) return AVERROR_INVALIDDATA; } } - if (s->ls && !(s->bits <= 8 || nb_components == 1)) { + if (s->ls && !(bits <= 8 || nb_components == 1)) { avpriv_report_missing_feature(s->avctx, "JPEG-LS that is not <= 8 " "bits/component or 16-bit gray"); @@ -337,11 +338,13 @@ int ff_mjpeg_decode_sof(MJpegDecodeContext *s) /* if different size, realloc/alloc picture */ if ( width != s->width || height != s->height + || bits != s->bits || memcmp(s->h_count, h_count, sizeof(h_count)) || memcmp(s->v_count, v_count, sizeof(v_count))) { s->width = width; s->height = height; + s->bits = bits; memcpy(s->h_count, h_count, sizeof(h_count)); memcpy(s->v_count, v_count, sizeof(v_count)); s->interlaced = 0; @@ -376,7 +379,7 @@ int ff_mjpeg_decode_sof(MJpegDecodeContext *s) else if (!s->lossless) s->rgb = 0; /* XXX: not complete test ! */ - pix_fmt_id = (s->h_count[0] << 28) | (s->v_count[0] << 24) | + pix_fmt_id = ((unsigned)s->h_count[0] << 28) | (s->v_count[0] << 24) | (s->h_count[1] << 20) | (s->v_count[1] << 16) | (s->h_count[2] << 12) | (s->v_count[2] << 8) | (s->h_count[3] << 4) | s->v_count[3]; @@ -511,6 +514,8 @@ int ff_mjpeg_decode_sof(MJpegDecodeContext *s) else s->avctx->pix_fmt = AV_PIX_FMT_YUV420P16; s->avctx->color_range = s->cs_itu601 ? AVCOL_RANGE_MPEG : AVCOL_RANGE_JPEG; if (pix_fmt_id == 0x42111100) { + if (s->bits > 8) + goto unk_pixfmt; s->upscale_h = 6; s->chroma_height = s->height / 2; } @@ -1591,6 +1596,8 @@ static int mjpeg_decode_app(MJpegDecodeContext *s) } if (id == AV_RB32("LJIF")) { + int rgb = s->rgb; + int pegasus_rct = s->pegasus_rct; if (s->avctx->debug & FF_DEBUG_PICT_INFO) av_log(s->avctx, AV_LOG_INFO, "Pegasus lossless jpeg header found\n"); @@ -1600,17 +1607,27 @@ static int mjpeg_decode_app(MJpegDecodeContext *s) skip_bits(&s->gb, 16); /* unknown always 0? */ switch (i=get_bits(&s->gb, 8)) { case 1: - s->rgb = 1; - s->pegasus_rct = 0; + rgb = 1; + pegasus_rct = 0; break; case 2: - s->rgb = 1; - s->pegasus_rct = 1; + rgb = 1; + pegasus_rct = 1; break; default: av_log(s->avctx, AV_LOG_ERROR, "unknown colorspace %d\n", i); } + len -= 9; + if (s->got_picture) + if (rgb != s->rgb || pegasus_rct != s->pegasus_rct) { + av_log(s->avctx, AV_LOG_WARNING, "Mismatching LJIF tag\n"); + goto out; + } + + s->rgb = rgb; + s->pegasus_rct = pegasus_rct; + goto out; } if (id == AV_RL32("colr") && len > 0) { @@ -1894,6 +1911,7 @@ int ff_mjpeg_decode_frame(AVCodecContext *avctx, void *data, int *got_frame, int start_code; int i, index; int ret = 0; + int is16bit; av_dict_free(&s->exif_metadata); av_freep(&s->stereo3d); @@ -2072,6 +2090,9 @@ fail: s->got_picture = 0; return ret; the_end: + + is16bit = av_pix_fmt_desc_get(s->avctx->pix_fmt)->comp[0].step_minus1; + if (s->upscale_h) { int p; av_assert0(avctx->pix_fmt == AV_PIX_FMT_YUVJ444P || @@ -2081,6 +2102,7 @@ the_end: avctx->pix_fmt == AV_PIX_FMT_YUVA444P || avctx->pix_fmt == AV_PIX_FMT_YUVJ420P || avctx->pix_fmt == AV_PIX_FMT_YUV420P || + avctx->pix_fmt == AV_PIX_FMT_YUV420P16|| avctx->pix_fmt == AV_PIX_FMT_GBRAP ); avcodec_get_chroma_sub_sample(s->avctx->pix_fmt, &hshift, &vshift); @@ -2091,9 +2113,16 @@ the_end: continue; if (p==1 || p==2) w >>= hshift; + av_assert0(w > 0); for (i = 0; i < s->chroma_height; i++) { - for (index = w - 1; index; index--) - line[index] = (line[index / 2] + line[(index + 1) / 2]) >> 1; + if (is16bit) ((uint16_t*)line)[w - 1] = ((uint16_t*)line)[(w - 1) / 2]; + else line[w - 1] = line[(w - 1) / 2]; + for (index = w - 2; index > 0; index--) { + if (is16bit) + ((uint16_t*)line)[index] = (((uint16_t*)line)[index / 2] + ((uint16_t*)line)[(index + 1) / 2]) >> 1; + else + line[index] = (line[index / 2] + line[(index + 1) / 2]) >> 1; + } line += s->linesize[p]; } } @@ -2114,11 +2143,11 @@ the_end: if (!(s->upscale_v & (1<>= hshift; + w = FF_CEIL_RSHIFT(w, hshift); for (i = s->height - 1; i; i--) { uint8_t *src1 = &((uint8_t *)s->picture_ptr->data[p])[i / 2 * s->linesize[p]]; uint8_t *src2 = &((uint8_t *)s->picture_ptr->data[p])[(i + 1) / 2 * s->linesize[p]]; - if (src1 == src2) { + if (src1 == src2 || i == s->height - 1) { memcpy(dst, src1, w); } else { for (index = 0; index < w; index++) diff --git a/libavcodec/mmvideo.c b/libavcodec/mmvideo.c index ab59b58781..9af35e5108 100644 --- a/libavcodec/mmvideo.c +++ b/libavcodec/mmvideo.c @@ -61,6 +61,13 @@ static av_cold int mm_decode_init(AVCodecContext *avctx) avctx->pix_fmt = AV_PIX_FMT_PAL8; + if (!avctx->width || !avctx->height || + (avctx->width & 1) || (avctx->height & 1)) { + av_log(avctx, AV_LOG_ERROR, "Invalid video dimensions: %dx%d\n", + avctx->width, avctx->height); + return AVERROR(EINVAL); + } + s->frame = av_frame_alloc(); if (!s->frame) return AVERROR(ENOMEM); @@ -111,7 +118,7 @@ static int mm_decode_intra(MmContext * s, int half_horiz, int half_vert) if (color) { memset(s->frame->data[0] + y*s->frame->linesize[0] + x, color, run_length); - if (half_vert) + if (half_vert && y + half_vert < s->avctx->height) memset(s->frame->data[0] + (y+1)*s->frame->linesize[0] + x, color, run_length); } x+= run_length; diff --git a/libavcodec/motion_est.c b/libavcodec/motion_est.c index 6b3cd61e8a..6e6d3f69e4 100644 --- a/libavcodec/motion_est.c +++ b/libavcodec/motion_est.c @@ -190,7 +190,13 @@ static av_always_inline int cmp_inline(MpegEncContext *s, const int x, const int int uvdxy; /* no, it might not be used uninitialized */ if(dxy){ if(qpel){ - c->qpel_put[size][dxy](c->temp, ref[0] + x + y*stride, stride); //FIXME prototype (add h) + if (h << size == 16) { + c->qpel_put[size][dxy](c->temp, ref[0] + x + y*stride, stride); //FIXME prototype (add h) + } else if (size == 0 && h == 8) { + c->qpel_put[1][dxy](c->temp , ref[0] + x + y*stride , stride); + c->qpel_put[1][dxy](c->temp + 8, ref[0] + x + y*stride + 8, stride); + } else + av_assert2(0); if(chroma){ int cx= hx/2; int cy= hy/2; diff --git a/libavcodec/mpeg12dec.c b/libavcodec/mpeg12dec.c index fcc1d4c48b..0eecb7d1f7 100644 --- a/libavcodec/mpeg12dec.c +++ b/libavcodec/mpeg12dec.c @@ -1884,6 +1884,14 @@ static int mpeg_decode_slice(MpegEncContext *s, int mb_y, } else goto eos; } + if (s->mb_y >= ((s->height + 15) >> 4) && + s->progressive_frame && + !s->progressive_sequence && + get_bits_left(&s->gb) <= 8 && + get_bits_left(&s->gb) >= 0 && + s->mb_skip_run == -1 && + show_bits(&s->gb, 8) == 0) + goto eos; ff_init_block_index(s); } diff --git a/libavcodec/mpegaudio_parser.c b/libavcodec/mpegaudio_parser.c index 3d9e94688a..79dbf635b4 100644 --- a/libavcodec/mpegaudio_parser.c +++ b/libavcodec/mpegaudio_parser.c @@ -73,20 +73,21 @@ static int mpegaudio_parse(AVCodecParserContext *s1, if (i > 4) s->header_count = -2; } else { + int header_threshold = avctx->codec_id != AV_CODEC_ID_NONE && avctx->codec_id != codec_id; if((state&SAME_HEADER_MASK) != (s->header&SAME_HEADER_MASK) && s->header) s->header_count= -3; s->header= state; s->header_count++; s->frame_size = ret-4; - if (s->header_count > 0 + (avctx->codec_id != AV_CODEC_ID_NONE && avctx->codec_id != codec_id)) { + if (s->header_count > header_threshold) { avctx->sample_rate= sr; avctx->channels = channels; s1->duration = frame_size; avctx->codec_id = codec_id; if (s->no_bitrate || !avctx->bit_rate) { s->no_bitrate = 1; - avctx->bit_rate += (bit_rate - avctx->bit_rate) / s->header_count; + avctx->bit_rate += (bit_rate - avctx->bit_rate) / (s->header_count - header_threshold); } } break; diff --git a/libavcodec/mpegaudiodec_template.c b/libavcodec/mpegaudiodec_template.c index 05237070ea..90543aa6dc 100644 --- a/libavcodec/mpegaudiodec_template.c +++ b/libavcodec/mpegaudiodec_template.c @@ -1642,9 +1642,11 @@ static int decode_frame(AVCodecContext * avctx, void *data, int *got_frame_ptr, uint32_t header; int ret; + int skipped = 0; while(buf_size && !*buf){ buf++; buf_size--; + skipped++; } if (buf_size < HEADER_SIZE) @@ -1699,7 +1701,7 @@ static int decode_frame(AVCodecContext * avctx, void *data, int *got_frame_ptr, return ret; } s->frame_size = 0; - return buf_size; + return buf_size + skipped; } static void mp_flush(MPADecodeContext *ctx) diff --git a/libavcodec/mpegvideo.c b/libavcodec/mpegvideo.c index a9024a978e..65c7c9de3c 100644 --- a/libavcodec/mpegvideo.c +++ b/libavcodec/mpegvideo.c @@ -1436,6 +1436,9 @@ int ff_MPV_common_frame_size_change(MpegEncContext *s) { int i, err = 0; + if (!s->context_initialized) + return AVERROR(EINVAL); + if (s->slice_context_count > 1) { for (i = 0; i < s->slice_context_count; i++) { free_duplicate_context(s->thread_context[i]); @@ -1465,8 +1468,8 @@ int ff_MPV_common_frame_size_change(MpegEncContext *s) s->mb_height = (s->height + 15) / 16; if ((s->width || s->height) && - av_image_check_size(s->width, s->height, 0, s->avctx)) - return AVERROR_INVALIDDATA; + (err = av_image_check_size(s->width, s->height, 0, s->avctx)) < 0) + goto fail; if ((err = init_context_frame(s))) goto fail; @@ -1482,7 +1485,7 @@ int ff_MPV_common_frame_size_change(MpegEncContext *s) } for (i = 0; i < nb_slices; i++) { - if (init_duplicate_context(s->thread_context[i]) < 0) + if ((err = init_duplicate_context(s->thread_context[i])) < 0) goto fail; s->thread_context[i]->start_mb_y = (s->mb_height * (i) + nb_slices / 2) / nb_slices; diff --git a/libavcodec/on2avc.c b/libavcodec/on2avc.c index ab6048b63e..e5e7cc3879 100644 --- a/libavcodec/on2avc.c +++ b/libavcodec/on2avc.c @@ -908,6 +908,11 @@ static av_cold int on2avc_decode_init(AVCodecContext *avctx) On2AVCContext *c = avctx->priv_data; int i; + if (avctx->channels > 2U) { + avpriv_request_sample(avctx, "Decoding more than 2 channels"); + return AVERROR_PATCHWELCOME; + } + c->avctx = avctx; avctx->sample_fmt = AV_SAMPLE_FMT_FLTP; avctx->channel_layout = (avctx->channels == 2) ? AV_CH_LAYOUT_STEREO diff --git a/libavcodec/options_table.h b/libavcodec/options_table.h index cbefa52275..ca700769cd 100644 --- a/libavcodec/options_table.h +++ b/libavcodec/options_table.h @@ -102,8 +102,8 @@ static const AVOption avcodec_options[] = { {"extradata_size", NULL, OFFSET(extradata_size), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, INT_MIN, INT_MAX}, {"time_base", NULL, OFFSET(time_base), AV_OPT_TYPE_RATIONAL, {.dbl = 0}, INT_MIN, INT_MAX}, {"g", "set the group of picture (GOP) size", OFFSET(gop_size), AV_OPT_TYPE_INT, {.i64 = 12 }, INT_MIN, INT_MAX, V|E}, -{"ar", "set audio sampling rate (in Hz)", OFFSET(sample_rate), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, INT_MIN, INT_MAX, A|D|E}, -{"ac", "set number of audio channels", OFFSET(channels), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, INT_MIN, INT_MAX, A|D|E}, +{"ar", "set audio sampling rate (in Hz)", OFFSET(sample_rate), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, 0, INT_MAX, A|D|E}, +{"ac", "set number of audio channels", OFFSET(channels), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, 0, INT_MAX, A|D|E}, {"cutoff", "set cutoff bandwidth", OFFSET(cutoff), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, INT_MIN, INT_MAX, A|E}, {"frame_size", NULL, OFFSET(frame_size), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, INT_MIN, INT_MAX, A|E}, {"frame_number", NULL, OFFSET(frame_number), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, INT_MIN, INT_MAX}, diff --git a/libavcodec/opusdec.c b/libavcodec/opusdec.c index b28edfbcd9..3ce519d1dc 100644 --- a/libavcodec/opusdec.c +++ b/libavcodec/opusdec.c @@ -499,6 +499,12 @@ static int opus_decode_packet(AVCodecContext *avctx, void *data, av_log(avctx, AV_LOG_ERROR, "Error parsing the packet header.\n"); return ret; } + if (coded_samples != s->packet.frame_count * s->packet.frame_duration) { + av_log(avctx, AV_LOG_ERROR, + "Mismatching coded sample count in substream %d.\n", i); + return AVERROR_INVALIDDATA; + } + s->silk_samplerate = get_silk_samplerate(s->packet.config); } diff --git a/libavcodec/pngdec.c b/libavcodec/pngdec.c index c92087f5e8..5e62a60318 100644 --- a/libavcodec/pngdec.c +++ b/libavcodec/pngdec.c @@ -576,6 +576,12 @@ static int decode_frame(AVCodecContext *avctx, case MKTAG('I', 'H', 'D', 'R'): if (length != 13) goto fail; + + if (s->state & PNG_IDAT) { + av_log(avctx, AV_LOG_ERROR, "IHDR after IDAT\n"); + goto fail; + } + s->width = bytestream2_get_be32(&s->gb); s->height = bytestream2_get_be32(&s->gb); if (av_image_check_size(s->width, s->height, 0, avctx)) { @@ -644,7 +650,7 @@ static int decode_frame(AVCodecContext *avctx, } else if ((s->bits_per_pixel == 1 || s->bits_per_pixel == 2 || s->bits_per_pixel == 4 || s->bits_per_pixel == 8) && s->color_type == PNG_COLOR_TYPE_PALETTE) { avctx->pix_fmt = AV_PIX_FMT_PAL8; - } else if (s->bit_depth == 1) { + } else if (s->bit_depth == 1 && s->bits_per_pixel == 1) { avctx->pix_fmt = AV_PIX_FMT_MONOBLACK; } else if (s->bit_depth == 8 && s->color_type == PNG_COLOR_TYPE_GRAY_ALPHA) { @@ -851,10 +857,11 @@ exit_loop: int i, j; uint8_t *pd = p->data[0]; uint8_t *pd_last = s->last_picture.f->data[0]; + int ls = FFMIN(av_image_get_linesize(p->format, s->width, 0), s->width * s->bpp); ff_thread_await_progress(&s->last_picture, INT_MAX, 0); for (j = 0; j < s->height; j++) { - for (i = 0; i < s->width * s->bpp; i++) + for (i = 0; i < ls; i++) pd[i] += pd_last[i]; pd += s->image_linesize; pd_last += s->image_linesize; diff --git a/libavcodec/proresenc_kostya.c b/libavcodec/proresenc_kostya.c index 93bcde727d..c3c2363109 100644 --- a/libavcodec/proresenc_kostya.c +++ b/libavcodec/proresenc_kostya.c @@ -471,7 +471,6 @@ static void put_alpha_run(PutBitContext *pb, int run) // todo alpha quantisation for high quants static int encode_alpha_plane(ProresContext *ctx, PutBitContext *pb, - const uint16_t *src, int linesize, int mbs_per_slice, uint16_t *blocks, int quant) { @@ -566,11 +565,16 @@ static int encode_slice(AVCodecContext *avctx, const AVFrame *pic, get_alpha_data(ctx, src, linesize, xp, yp, pwidth, avctx->height / ctx->pictures_per_frame, ctx->blocks[0], mbs_per_slice, ctx->alpha_bits); - sizes[i] = encode_alpha_plane(ctx, pb, src, linesize, + sizes[i] = encode_alpha_plane(ctx, pb, mbs_per_slice, ctx->blocks[0], quant); } total_size += sizes[i]; + if (put_bits_left(pb) < 0) { + av_log(avctx, AV_LOG_ERROR, "Serious underevaluation of" + "required buffer size"); + return AVERROR_BUFFER_TOO_SMALL; + } } return total_size; } @@ -941,9 +945,9 @@ static int encode_frame(AVCodecContext *avctx, AVPacket *pkt, avctx->coded_frame->pict_type = AV_PICTURE_TYPE_I; avctx->coded_frame->key_frame = 1; - pkt_size = ctx->frame_size_upper_bound + FF_MIN_BUFFER_SIZE; + pkt_size = ctx->frame_size_upper_bound; - if ((ret = ff_alloc_packet2(avctx, pkt, pkt_size)) < 0) + if ((ret = ff_alloc_packet2(avctx, pkt, pkt_size + FF_MIN_BUFFER_SIZE)) < 0) return ret; orig_buf = pkt->data; @@ -1020,7 +1024,9 @@ static int encode_frame(AVCodecContext *avctx, AVPacket *pkt, slice_hdr = buf; buf += slice_hdr_size - 1; init_put_bits(&pb, buf, (pkt_size - (buf - orig_buf)) * 8); - encode_slice(avctx, pic, &pb, sizes, x, y, q, mbs_per_slice); + ret = encode_slice(avctx, pic, &pb, sizes, x, y, q, mbs_per_slice); + if (ret < 0) + return ret; bytestream_put_byte(&slice_hdr, q); slice_size = slice_hdr_size + sizes[ctx->num_planes - 1]; @@ -1202,8 +1208,6 @@ static av_cold int encode_init(AVCodecContext *avctx) ctx->bits_per_mb = ls * 8; if (ctx->chroma_factor == CFACTOR_Y444) ctx->bits_per_mb += ls * 4; - if (ctx->num_planes == 4) - ctx->bits_per_mb += ls * 4; } ctx->frame_size_upper_bound = ctx->pictures_per_frame * @@ -1212,6 +1216,14 @@ static av_cold int encode_init(AVCodecContext *avctx) (mps * ctx->bits_per_mb) / 8) + 200; + if (ctx->alpha_bits) { + // alpha plane is run-coded and might run over bit budget + ctx->frame_size_upper_bound += ctx->pictures_per_frame * + ctx->slices_per_picture * + /* num pixels per slice */ (ctx->mbs_per_slice * 256 * + /* bits per pixel */ (1 + ctx->alpha_bits + 1) + 7 >> 3); + } + avctx->codec_tag = ctx->profile_info->tag; av_log(avctx, AV_LOG_DEBUG, diff --git a/libavcodec/qpeg.c b/libavcodec/qpeg.c index 94cb5bd0b6..d61bceafd7 100644 --- a/libavcodec/qpeg.c +++ b/libavcodec/qpeg.c @@ -163,7 +163,7 @@ static void av_noinline qpeg_decode_inter(QpegContext *qctx, uint8_t *dst, /* check motion vector */ if ((me_x + filled < 0) || (me_x + me_w + filled > width) || - (height - me_y - me_h < 0) || (height - me_y > orig_height) || + (height - me_y - me_h < 0) || (height - me_y >= orig_height) || (filled + me_w > width) || (height - me_h < 0)) av_log(NULL, AV_LOG_ERROR, "Bogus motion vector (%i,%i), block size %ix%i at %i,%i\n", me_x, me_y, me_w, me_h, filled, height); diff --git a/libavcodec/rawdec.c b/libavcodec/rawdec.c index ee1f3970ad..04fd68f259 100644 --- a/libavcodec/rawdec.c +++ b/libavcodec/rawdec.c @@ -117,6 +117,9 @@ static av_cold int raw_init_decoder(AVCodecContext *avctx) context->frame_size = avpicture_get_size(avctx->pix_fmt, avctx->width, avctx->height); } + if (context->frame_size < 0) + return context->frame_size; + if ((avctx->extradata_size >= 9 && !memcmp(avctx->extradata + avctx->extradata_size - 9, "BottomUp", 9)) || diff --git a/libavcodec/sgidec.c b/libavcodec/sgidec.c index 6f51ec3531..3ddbf77bc8 100644 --- a/libavcodec/sgidec.c +++ b/libavcodec/sgidec.c @@ -98,7 +98,7 @@ static int expand_rle_row16(SgiState *s, uint16_t *out_buf, break; /* Check for buffer overflow. */ - if (pixelstride * (count - 1) >= len) { + if (out_end - out_buf <= pixelstride * (count - 1)) { av_log(s->avctx, AV_LOG_ERROR, "Invalid pixel count.\n"); return AVERROR_INVALIDDATA; } @@ -145,7 +145,7 @@ static int read_rle_sgi(uint8_t *out_buf, SgiState *s) for (z = 0; z < s->depth; z++) { dest_row = out_buf; for (y = 0; y < s->height; y++) { - linesize = s->width * s->depth * s->bytes_per_channel; + linesize = s->width * s->depth; dest_row -= s->linesize; start_offset = bytestream2_get_be32(&g_table); bytestream2_seek(&s->g, start_offset, SEEK_SET); diff --git a/libavcodec/smc.c b/libavcodec/smc.c index 31e6c885bf..791612ebd4 100644 --- a/libavcodec/smc.c +++ b/libavcodec/smc.c @@ -70,7 +70,7 @@ typedef struct SmcContext { row_ptr += stride * 4; \ } \ total_blocks--; \ - if (total_blocks < 0) \ + if (total_blocks < 0 + !!n_blocks) \ { \ av_log(s->avctx, AV_LOG_INFO, "warning: block counter just went negative (this should not happen)\n"); \ return; \ diff --git a/libavcodec/snow.c b/libavcodec/snow.c index 711d1a4f08..f7629c59d3 100644 --- a/libavcodec/snow.c +++ b/libavcodec/snow.c @@ -713,7 +713,7 @@ av_cold void ff_snow_common_end(SnowContext *s) for(i=0; iref_mvs[i]); av_freep(&s->ref_scores[i]); - if(s->last_picture[i]->data[0]) { + if(s->last_picture[i] && s->last_picture[i]->data[0]) { av_assert0(s->last_picture[i]->data[0] != s->current_picture->data[0]); } av_frame_free(&s->last_picture[i]); diff --git a/libavcodec/snow.h b/libavcodec/snow.h index 2cda5b323d..b890d3f176 100644 --- a/libavcodec/snow.h +++ b/libavcodec/snow.h @@ -659,7 +659,10 @@ static inline void unpack_coeffs(SnowContext *s, SubBand *b, SubBand * parent, i if(v){ v= 2*(get_symbol2(&s->c, b->state[context + 2], context-4) + 1); v+=get_rac(&s->c, &b->state[0][16 + 1 + 3 + ff_quant3bA[l&0xFF] + 3*ff_quant3bA[t&0xFF]]); - + if ((uint16_t)v != v) { + av_log(s->avctx, AV_LOG_ERROR, "Coefficient damaged\n"); + v = 1; + } xc->x=x; (xc++)->coeff= v; } @@ -669,6 +672,10 @@ static inline void unpack_coeffs(SnowContext *s, SubBand *b, SubBand * parent, i else run= INT_MAX; v= 2*(get_symbol2(&s->c, b->state[0 + 2], 0-4) + 1); v+=get_rac(&s->c, &b->state[0][16 + 1 + 3]); + if ((uint16_t)v != v) { + av_log(s->avctx, AV_LOG_ERROR, "Coefficient damaged\n"); + v = 1; + } xc->x=x; (xc++)->coeff= v; diff --git a/libavcodec/svq1dec.c b/libavcodec/svq1dec.c index 1e7ab494a8..8ac7885c14 100644 --- a/libavcodec/svq1dec.c +++ b/libavcodec/svq1dec.c @@ -495,7 +495,7 @@ static int svq1_decode_delta_block(AVCodecContext *avctx, HpelDSPContext *hdsp, return result; } -static void svq1_parse_string(GetBitContext *bitbuf, uint8_t *out) +static void svq1_parse_string(GetBitContext *bitbuf, uint8_t out[257]) { uint8_t seed; int i; @@ -507,6 +507,7 @@ static void svq1_parse_string(GetBitContext *bitbuf, uint8_t *out) out[i] = get_bits(bitbuf, 8) ^ seed; seed = string_table[out[i] ^ seed]; } + out[i] = 0; } static int svq1_decode_frame_header(AVCodecContext *avctx, AVFrame *frame) @@ -549,12 +550,12 @@ static int svq1_decode_frame_header(AVCodecContext *avctx, AVFrame *frame) } if ((s->frame_code ^ 0x10) >= 0x50) { - uint8_t msg[256]; + uint8_t msg[257]; svq1_parse_string(bitbuf, msg); av_log(avctx, AV_LOG_INFO, - "embedded message:\n%s\n", (char *)msg); + "embedded message:\n%s\n", ((char *)msg) + 1); } skip_bits(bitbuf, 2); diff --git a/libavcodec/svq3.c b/libavcodec/svq3.c index 97233b19d6..9459329058 100644 --- a/libavcodec/svq3.c +++ b/libavcodec/svq3.c @@ -1176,7 +1176,7 @@ static int svq3_decode_frame(AVCodecContext *avctx, void *data, h->cur_pic_ptr = s->cur_pic; av_frame_unref(&h->cur_pic.f); - h->cur_pic = *s->cur_pic; + memcpy(&h->cur_pic.tf, &s->cur_pic->tf, sizeof(h->cur_pic) - offsetof(H264Picture, tf)); ret = av_frame_ref(&h->cur_pic.f, &s->cur_pic->f); if (ret < 0) return ret; diff --git a/libavcodec/tiff.c b/libavcodec/tiff.c index 1caad84845..a57dee13ef 100644 --- a/libavcodec/tiff.c +++ b/libavcodec/tiff.c @@ -712,13 +712,13 @@ static int tiff_decode_tag(TiffContext *s, AVFrame *frame) s->height = value; break; case TIFF_BPP: - s->bppcount = count; - if (count > 4) { + if (count > 4U) { av_log(s->avctx, AV_LOG_ERROR, "This format is not supported (bpp=%d, %d components)\n", - s->bpp, count); + value, count); return AVERROR_INVALIDDATA; } + s->bppcount = count; if (count == 1) s->bpp = value; else { @@ -736,6 +736,13 @@ static int tiff_decode_tag(TiffContext *s, AVFrame *frame) s->bpp = -1; } } + if (s->bpp > 64U) { + av_log(s->avctx, AV_LOG_ERROR, + "This format is not supported (bpp=%d, %d components)\n", + s->bpp, count); + s->bpp = 0; + return AVERROR_INVALIDDATA; + } break; case TIFF_SAMPLES_PER_PIXEL: if (count != 1) { diff --git a/libavcodec/tiffenc.c b/libavcodec/tiffenc.c index 5a61f1aefa..138d214c2f 100644 --- a/libavcodec/tiffenc.c +++ b/libavcodec/tiffenc.c @@ -305,7 +305,9 @@ static int encode_frame(AVCodecContext *avctx, AVPacket *pkt, strips = (s->height - 1) / s->rps + 1; - packet_size = avctx->height * ((avctx->width * s->bpp + 7) >> 3) * 2 + + bytes_per_row = (((s->width - 1) / s->subsampling[0] + 1) * s->bpp * + s->subsampling[0] * s->subsampling[1] + 7) >> 3; + packet_size = avctx->height * bytes_per_row * 2 + avctx->height * 4 + FF_MIN_BUFFER_SIZE; if ((ret = ff_alloc_packet2(avctx, pkt, packet_size)) < 0) @@ -333,8 +335,6 @@ static int encode_frame(AVCodecContext *avctx, AVPacket *pkt, goto fail; } - bytes_per_row = (((s->width - 1) / s->subsampling[0] + 1) * s->bpp * - s->subsampling[0] * s->subsampling[1] + 7) >> 3; if (is_yuv) { av_fast_padded_malloc(&s->yuv_line, &s->yuv_line_size, bytes_per_row); if (s->yuv_line == NULL) { diff --git a/libavcodec/utils.c b/libavcodec/utils.c index 9fa8e16042..020524f498 100644 --- a/libavcodec/utils.c +++ b/libavcodec/utils.c @@ -66,6 +66,9 @@ #include "compat/os2threads.h" #endif +#include "libavutil/ffversion.h" +const char av_codec_ffversion[] = "FFmpeg version " FFMPEG_VERSION; + #if HAVE_PTHREADS || HAVE_W32THREADS || HAVE_OS2THREADS static int default_lockmgr_cb(void **arg, enum AVLockOp op) { @@ -297,6 +300,12 @@ void avcodec_align_dimensions2(AVCodecContext *s, int *width, int *height, int i; int w_align = 1; int h_align = 1; + AVPixFmtDescriptor const *desc = av_pix_fmt_desc_get(s->pix_fmt); + + if (desc) { + w_align = 1 << desc->log2_chroma_w; + h_align = 1 << desc->log2_chroma_h; + } switch (s->pix_fmt) { case AV_PIX_FMT_YUV420P: @@ -374,6 +383,8 @@ void avcodec_align_dimensions2(AVCodecContext *s, int *width, int *height, case AV_PIX_FMT_GBRP12BE: case AV_PIX_FMT_GBRP14LE: case AV_PIX_FMT_GBRP14BE: + case AV_PIX_FMT_GBRP16LE: + case AV_PIX_FMT_GBRP16BE: w_align = 16; //FIXME assume 16 pixel per macroblock h_align = 16 * 2; // interlaced needs 2 macroblocks height break; @@ -403,6 +414,10 @@ void avcodec_align_dimensions2(AVCodecContext *s, int *width, int *height, w_align = 4; h_align = 4; } + if (s->codec_id == AV_CODEC_ID_JV) { + w_align = 8; + h_align = 8; + } break; case AV_PIX_FMT_BGR24: if ((s->codec_id == AV_CODEC_ID_MSZH) || @@ -418,8 +433,6 @@ void avcodec_align_dimensions2(AVCodecContext *s, int *width, int *height, } break; default: - w_align = 1; - h_align = 1; break; } @@ -3591,6 +3604,11 @@ int avpriv_bprint_to_extradata(AVCodecContext *avctx, struct AVBPrint *buf) ret = av_bprint_finalize(buf, &str); if (ret < 0) return ret; + if (!av_bprint_is_complete(buf)) { + av_free(str); + return AVERROR(ENOMEM); + } + avctx->extradata = str; /* Note: the string is NUL terminated (so extradata can be read as a * string), but the ending character is not accounted in the size (in diff --git a/libavcodec/utvideodec.c b/libavcodec/utvideodec.c index afd56ea1bd..abf550b081 100644 --- a/libavcodec/utvideodec.c +++ b/libavcodec/utvideodec.c @@ -214,6 +214,8 @@ static void restore_median(uint8_t *src, int step, int stride, slice_height = ((((slice + 1) * height) / slices) & cmask) - slice_start; + if (!slice_height) + continue; bsrc = src + slice_start * stride; // first line - left neighbour prediction @@ -224,7 +226,7 @@ static void restore_median(uint8_t *src, int step, int stride, A = bsrc[i]; } bsrc += stride; - if (slice_height == 1) + if (slice_height <= 1) continue; // second line - first element has top prediction, the rest uses median C = bsrc[-stride]; @@ -269,6 +271,8 @@ static void restore_median_il(uint8_t *src, int step, int stride, slice_height = ((((slice + 1) * height) / slices) & cmask) - slice_start; slice_height >>= 1; + if (!slice_height) + continue; bsrc = src + slice_start * stride; @@ -284,7 +288,7 @@ static void restore_median_il(uint8_t *src, int step, int stride, A = bsrc[stride + i]; } bsrc += stride2; - if (slice_height == 1) + if (slice_height <= 1) continue; // second line - first element has top prediction, the rest uses median C = bsrc[-stride2]; diff --git a/libavcodec/utvideoenc.c b/libavcodec/utvideoenc.c index cbd34d01fd..355fdb1b8d 100644 --- a/libavcodec/utvideoenc.c +++ b/libavcodec/utvideoenc.c @@ -389,7 +389,7 @@ static int write_huff_codes(uint8_t *src, uint8_t *dst, int dst_size, } static int encode_plane(AVCodecContext *avctx, uint8_t *src, - uint8_t *dst, int stride, + uint8_t *dst, int stride, int plane_no, int width, int height, PutByteContext *pb) { UtvideoContext *c = avctx->priv_data; @@ -399,6 +399,7 @@ static int encode_plane(AVCodecContext *avctx, uint8_t *src, HuffEntry he[256]; uint32_t offset = 0, slice_len = 0; + const int cmask = ~(!plane_no && avctx->pix_fmt == AV_PIX_FMT_YUV420P); int i, sstart, send = 0; int symbol; int ret; @@ -408,7 +409,7 @@ static int encode_plane(AVCodecContext *avctx, uint8_t *src, case PRED_NONE: for (i = 0; i < c->slices; i++) { sstart = send; - send = height * (i + 1) / c->slices; + send = height * (i + 1) / c->slices & cmask; av_image_copy_plane(dst + sstart * width, width, src + sstart * stride, stride, width, send - sstart); @@ -417,7 +418,7 @@ static int encode_plane(AVCodecContext *avctx, uint8_t *src, case PRED_LEFT: for (i = 0; i < c->slices; i++) { sstart = send; - send = height * (i + 1) / c->slices; + send = height * (i + 1) / c->slices & cmask; left_predict(src + sstart * stride, dst + sstart * width, stride, width, send - sstart); } @@ -425,7 +426,7 @@ static int encode_plane(AVCodecContext *avctx, uint8_t *src, case PRED_MEDIAN: for (i = 0; i < c->slices; i++) { sstart = send; - send = height * (i + 1) / c->slices; + send = height * (i + 1) / c->slices & cmask; median_predict(c, src + sstart * stride, dst + sstart * width, stride, width, send - sstart); } @@ -489,7 +490,7 @@ static int encode_plane(AVCodecContext *avctx, uint8_t *src, send = 0; for (i = 0; i < c->slices; i++) { sstart = send; - send = height * (i + 1) / c->slices; + send = height * (i + 1) / c->slices & cmask; /* * Write the huffman codes to a buffer, @@ -571,7 +572,7 @@ static int utvideo_encode_frame(AVCodecContext *avctx, AVPacket *pkt, case AV_PIX_FMT_RGBA: for (i = 0; i < c->planes; i++) { ret = encode_plane(avctx, c->slice_buffer[i] + 2 * c->slice_stride, - c->slice_buffer[i], c->slice_stride, + c->slice_buffer[i], c->slice_stride, i, width, height, &pb); if (ret) { @@ -583,7 +584,7 @@ static int utvideo_encode_frame(AVCodecContext *avctx, AVPacket *pkt, case AV_PIX_FMT_YUV422P: for (i = 0; i < c->planes; i++) { ret = encode_plane(avctx, pic->data[i], c->slice_buffer[0], - pic->linesize[i], width >> !!i, height, &pb); + pic->linesize[i], i, width >> !!i, height, &pb); if (ret) { av_log(avctx, AV_LOG_ERROR, "Error encoding plane %d.\n", i); @@ -594,7 +595,7 @@ static int utvideo_encode_frame(AVCodecContext *avctx, AVPacket *pkt, case AV_PIX_FMT_YUV420P: for (i = 0; i < c->planes; i++) { ret = encode_plane(avctx, pic->data[i], c->slice_buffer[0], - pic->linesize[i], width >> !!i, height >> !!i, + pic->linesize[i], i, width >> !!i, height >> !!i, &pb); if (ret) { diff --git a/libavcodec/vc1dec.c b/libavcodec/vc1dec.c index 06deb7fad6..2d4fdd3ab8 100644 --- a/libavcodec/vc1dec.c +++ b/libavcodec/vc1dec.c @@ -5484,7 +5484,7 @@ static int vc1_decode_sprites(VC1Context *v, GetBitContext* gb) if (ret < 0) return ret; - if (!s->current_picture.f->data[0]) { + if (!s->current_picture.f || !s->current_picture.f->data[0]) { av_log(avctx, AV_LOG_ERROR, "Got no sprites\n"); return -1; } @@ -5514,7 +5514,7 @@ static void vc1_sprite_flush(AVCodecContext *avctx) Since we can't enforce it, clear to black the missing sprite. This is wrong but it looks better than doing nothing. */ - if (f->data[0]) + if (f && f->data[0]) for (plane = 0; plane < (s->flags&CODEC_FLAG_GRAY ? 1 : 3); plane++) for (i = 0; i < v->sprite_height>>!!plane; i++) memset(f->data[plane] + i * f->linesize[plane], diff --git a/libavcodec/vmdvideo.c b/libavcodec/vmdvideo.c index 279c56ab4f..42e19ae53c 100644 --- a/libavcodec/vmdvideo.c +++ b/libavcodec/vmdvideo.c @@ -339,6 +339,9 @@ static int vmd_decode(VmdVideoContext *s, AVFrame *frame) ofs += slen; bytestream2_skip(&gb, len); } else { + if (ofs + len > frame_width || + bytestream2_get_bytes_left(&gb) < len) + return AVERROR_INVALIDDATA; bytestream2_get_buffer(&gb, &dp[ofs], len); ofs += len; } diff --git a/libavcodec/vorbisdec.c b/libavcodec/vorbisdec.c index 87d1bbb97a..354ab0e466 100644 --- a/libavcodec/vorbisdec.c +++ b/libavcodec/vorbisdec.c @@ -1314,7 +1314,9 @@ static av_always_inline int setup_classifs(vorbis_context *vc, vorbis_residue *vr, uint8_t *do_not_decode, unsigned ch_used, - int partition_count) + int partition_count, + int ptns_to_read + ) { int p, j, i; unsigned c_p_c = vc->codebooks[vr->classbook].dimensions; @@ -1336,7 +1338,7 @@ static av_always_inline int setup_classifs(vorbis_context *vc, for (i = partition_count + c_p_c - 1; i >= partition_count; i--) { temp2 = (((uint64_t)temp) * inverse_class) >> 32; - if (i < vr->ptns_to_read) + if (i < ptns_to_read) vr->classifs[p + i] = temp - temp2 * vr->classifications; temp = temp2; } @@ -1344,13 +1346,13 @@ static av_always_inline int setup_classifs(vorbis_context *vc, for (i = partition_count + c_p_c - 1; i >= partition_count; i--) { temp2 = temp / vr->classifications; - if (i < vr->ptns_to_read) + if (i < ptns_to_read) vr->classifs[p + i] = temp - temp2 * vr->classifications; temp = temp2; } } } - p += vr->ptns_to_read; + p += ptns_to_read; } return 0; } @@ -1404,7 +1406,7 @@ static av_always_inline int vorbis_residue_decode_internal(vorbis_context *vc, for (partition_count = 0; partition_count < ptns_to_read;) { // SPEC error if (!pass) { int ret; - if ((ret = setup_classifs(vc, vr, do_not_decode, ch_used, partition_count)) < 0) + if ((ret = setup_classifs(vc, vr, do_not_decode, ch_used, partition_count, ptns_to_read)) < 0) return ret; } for (i = 0; (i < c_p_c) && (partition_count < ptns_to_read); ++i) { diff --git a/libavcodec/wavpack.c b/libavcodec/wavpack.c index 7c60f78b66..9f72ebef2b 100644 --- a/libavcodec/wavpack.c +++ b/libavcodec/wavpack.c @@ -253,6 +253,10 @@ static int wv_get_value(WavpackFrameContext *ctx, GetBitContext *gb, return sign ? ~ret : ret; error: + ret = get_bits_left(gb); + if (ret <= 0) { + av_log(ctx->avctx, AV_LOG_ERROR, "Too few bits (%d) left\n", ret); + } *last = 1; return 0; } diff --git a/libavcodec/wavpackenc.c b/libavcodec/wavpackenc.c index 66ebf2fa3c..005cf7c2e5 100644 --- a/libavcodec/wavpackenc.c +++ b/libavcodec/wavpackenc.c @@ -638,7 +638,7 @@ static uint32_t log2sample(uint32_t v, int limit, uint32_t *result) if ((v += v >> 9) < (1 << 8)) { dbits = nbits_table[v]; - result += (dbits << 8) + wp_log2_table[(v << (9 - dbits)) & 0xff]; + *result += (dbits << 8) + wp_log2_table[(v << (9 - dbits)) & 0xff]; } else { if (v < (1L << 16)) dbits = nbits_table[v >> 8] + 8; @@ -647,7 +647,7 @@ static uint32_t log2sample(uint32_t v, int limit, uint32_t *result) else dbits = nbits_table[v >> 24] + 24; - result += dbits = (dbits << 8) + wp_log2_table[(v >> (dbits - 9)) & 0xff]; + *result += dbits = (dbits << 8) + wp_log2_table[(v >> (dbits - 9)) & 0xff]; if (limit && dbits >= limit) return 1; @@ -2876,10 +2876,11 @@ static int wavpack_encode_frame(AVCodecContext *avctx, AVPacket *avpkt, return AVERROR(ENOMEM); } - if ((ret = ff_alloc_packet2(avctx, avpkt, s->block_samples * avctx->channels * 8)) < 0) + buf_size = s->block_samples * avctx->channels * 8 + + 200 /* for headers */; + if ((ret = ff_alloc_packet2(avctx, avpkt, buf_size)) < 0) return ret; buf = avpkt->data; - buf_size = avpkt->size; for (s->ch_offset = 0; s->ch_offset < avctx->channels;) { set_samplerate(s); diff --git a/libavcodec/webp.c b/libavcodec/webp.c index c737f5492d..274708df79 100644 --- a/libavcodec/webp.c +++ b/libavcodec/webp.c @@ -1028,7 +1028,7 @@ static int apply_color_indexing_transform(WebPContext *s) ImageContext *img; ImageContext *pal; int i, x, y; - uint8_t *p, *pi; + uint8_t *p; img = &s->image[IMAGE_ROLE_ARGB]; pal = &s->image[IMAGE_ROLE_COLOR_INDEXING]; @@ -1066,11 +1066,11 @@ static int apply_color_indexing_transform(WebPContext *s) p = GET_PIXEL(img->frame, x, y); i = p[2]; if (i >= pal->frame->width) { - av_log(s->avctx, AV_LOG_ERROR, "invalid palette index %d\n", i); - return AVERROR_INVALIDDATA; + AV_WB32(p, 0x00000000); + } else { + const uint8_t *pi = GET_PIXEL(pal->frame, i, 0); + AV_COPY32(p, pi); } - pi = GET_PIXEL(pal->frame, i, 0); - AV_COPY32(p, pi); } } diff --git a/libavcodec/wmaprodec.c b/libavcodec/wmaprodec.c index 2f6c485891..345fad87b7 100644 --- a/libavcodec/wmaprodec.c +++ b/libavcodec/wmaprodec.c @@ -422,6 +422,9 @@ static av_cold int decode_init(AVCodecContext *avctx) offset &= ~3; if (offset > s->sfb_offsets[i][band - 1]) s->sfb_offsets[i][band++] = offset; + + if (offset >= subframe_len) + break; } s->sfb_offsets[i][band - 1] = subframe_len; s->num_sfb[i] = band - 1; diff --git a/libavcodec/x86/h264_weight.asm b/libavcodec/x86/h264_weight.asm index b4fb9db309..1e1219ddde 100644 --- a/libavcodec/x86/h264_weight.asm +++ b/libavcodec/x86/h264_weight.asm @@ -135,8 +135,11 @@ WEIGHT_FUNC_HALF_MM 8, 8 add off_regd, 1 or off_regd, 1 add r4, 1 + cmp r6d, 128 + je .nonnormal cmp r5, 128 jne .normal +.nonnormal sar r5, 1 sar r6, 1 sar off_regd, 1 diff --git a/libavcodec/x86/hevc_mc.asm b/libavcodec/x86/hevc_mc.asm index 5cf37d0194..d7796ec673 100644 --- a/libavcodec/x86/hevc_mc.asm +++ b/libavcodec/x86/hevc_mc.asm @@ -342,7 +342,7 @@ QPEL_TABLE 10, 4, w, sse4 %macro LOOP_END 4 lea %1q, [%1q+2*%2q] ; dst += dststride - lea %3q, [%3q+ %4q] ; src += srcstride + add %3q, %4q ; src += srcstride dec heightd ; cmp height jnz .loop ; height loop %endmacro diff --git a/libavcodec/x86/videodsp.asm b/libavcodec/x86/videodsp.asm index 1ac02574d6..77189fa6ef 100644 --- a/libavcodec/x86/videodsp.asm +++ b/libavcodec/x86/videodsp.asm @@ -185,8 +185,12 @@ hvar_fn %elif (%2-%%off) == 2 mov valw, [srcq+%2-2] %elifidn %1, body - mov vald, [srcq+%2-3] -%else + mov valb, [srcq+%2-1] + sal vald, 16 + mov valw, [srcq+%2-3] +%elifidn %1, bottom + movd mm %+ %%mmx_idx, [srcq+%2-4] +%else ; top movd mm %+ %%mmx_idx, [srcq+%2-3] %endif %endif ; (%2-%%off) >= 1 @@ -242,12 +246,15 @@ hvar_fn mov [dstq+%2-2], valw %elifidn %1, body mov [dstq+%2-3], valw - shr vald, 16 + sar vald, 16 mov [dstq+%2-1], valb %else movd vald, mm %+ %%mmx_idx +%ifidn %1, bottom + sar vald, 8 +%endif mov [dstq+%2-3], valw - shr vald, 16 + sar vald, 16 mov [dstq+%2-1], valb %endif %endif ; (%2-%%off) >= 1 diff --git a/libavcodec/x86/vp9lpf.asm b/libavcodec/x86/vp9lpf.asm index c5db0caffb..1d58f5d807 100644 --- a/libavcodec/x86/vp9lpf.asm +++ b/libavcodec/x86/vp9lpf.asm @@ -20,10 +20,10 @@ ;* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA ;****************************************************************************** -%if ARCH_X86_64 - %include "libavutil/x86/x86util.asm" +%if ARCH_X86_64 + SECTION_RODATA cextern pb_3 diff --git a/libavdevice/Makefile b/libavdevice/Makefile index 767df19aa7..d6207f9ba7 100644 --- a/libavdevice/Makefile +++ b/libavdevice/Makefile @@ -34,7 +34,7 @@ OBJS-$(CONFIG_OPENGL_OUTDEV) += opengl_enc.o OBJS-$(CONFIG_OSS_INDEV) += oss_audio.o OBJS-$(CONFIG_OSS_OUTDEV) += oss_audio.o OBJS-$(CONFIG_PULSE_INDEV) += pulse_audio_dec.o \ - pulse_audio_common.o + pulse_audio_common.o timefilter.o OBJS-$(CONFIG_PULSE_OUTDEV) += pulse_audio_enc.o \ pulse_audio_common.o OBJS-$(CONFIG_QTKIT_INDEV) += qtkit.o diff --git a/libavdevice/avdevice.c b/libavdevice/avdevice.c index 6a75bd79d7..c391931ac2 100644 --- a/libavdevice/avdevice.c +++ b/libavdevice/avdevice.c @@ -23,6 +23,9 @@ #include "avdevice.h" #include "config.h" +#include "libavutil/ffversion.h" +const char av_device_ffversion[] = "FFmpeg version " FFMPEG_VERSION; + #define E AV_OPT_FLAG_ENCODING_PARAM #define D AV_OPT_FLAG_DECODING_PARAM #define A AV_OPT_FLAG_AUDIO_PARAM diff --git a/libavdevice/libavdevice.v b/libavdevice/libavdevice.v index 663af85ba8..de7278c193 100644 --- a/libavdevice/libavdevice.v +++ b/libavdevice/libavdevice.v @@ -1,4 +1,4 @@ LIBAVDEVICE_$MAJOR { - global: avdevice_*; + global: avdevice_*; av_*; local: *; }; diff --git a/libavdevice/pulse_audio_enc.c b/libavdevice/pulse_audio_enc.c index b07d4c0c84..bc4d1f0516 100644 --- a/libavdevice/pulse_audio_enc.c +++ b/libavdevice/pulse_audio_enc.c @@ -681,7 +681,7 @@ static int pulse_write_frame(AVFormatContext *h, int stream_index, AVERROR(EINVAL) : 0; pkt.data = (*frame)->data[0]; - pkt.size = (*frame)->nb_samples * av_get_bytes_per_sample((*frame)->format) * (*frame)->channels; + pkt.size = (*frame)->nb_samples * av_get_bytes_per_sample((*frame)->format) * av_frame_get_channels(*frame); pkt.dts = (*frame)->pkt_dts; pkt.duration = av_frame_get_pkt_duration(*frame); return pulse_write_packet(h, &pkt); diff --git a/libavdevice/v4l2.c b/libavdevice/v4l2.c index 64df0c7950..1e394fa439 100644 --- a/libavdevice/v4l2.c +++ b/libavdevice/v4l2.c @@ -868,9 +868,6 @@ static int v4l2_read_header(AVFormatContext *s1) avpriv_set_pts_info(st, 64, 1, 1000000); /* 64 bits pts in us */ - if ((res = v4l2_set_parameters(s1)) < 0) - return res; - if (s->pixel_format) { AVCodec *codec = avcodec_find_decoder_by_name(s->pixel_format); @@ -922,6 +919,9 @@ static int v4l2_read_header(AVFormatContext *s1) s->frame_format = desired_format; + if ((res = v4l2_set_parameters(s1)) < 0) + return res; + st->codec->pix_fmt = avpriv_fmt_v4l2ff(desired_format, codec_id); s->frame_size = avpicture_get_size(st->codec->pix_fmt, s->width, s->height); diff --git a/libavdevice/v4l2enc.c b/libavdevice/v4l2enc.c index efe08b589e..c9f8d92d2b 100644 --- a/libavdevice/v4l2enc.c +++ b/libavdevice/v4l2enc.c @@ -22,6 +22,7 @@ #include "avdevice.h" typedef struct { + AVClass *class; int fd; } V4L2Context; diff --git a/libavfilter/af_amix.c b/libavfilter/af_amix.c index 1eef70d8c4..34f23b0e4c 100644 --- a/libavfilter/af_amix.c +++ b/libavfilter/af_amix.c @@ -496,6 +496,8 @@ static av_cold int init(AVFilterContext *ctx) snprintf(name, sizeof(name), "input%d", i); pad.type = AVMEDIA_TYPE_AUDIO; pad.name = av_strdup(name); + if (!pad.name) + return AVERROR(ENOMEM); pad.filter_frame = filter_frame; ff_insert_inpad(ctx, i, &pad); diff --git a/libavfilter/af_join.c b/libavfilter/af_join.c index 3e9ccc8d74..7d99a4c8d1 100644 --- a/libavfilter/af_join.c +++ b/libavfilter/af_join.c @@ -214,6 +214,8 @@ static av_cold int join_init(AVFilterContext *ctx) snprintf(name, sizeof(name), "input%d", i); pad.type = AVMEDIA_TYPE_AUDIO; pad.name = av_strdup(name); + if (!pad.name) + return AVERROR(ENOMEM); pad.filter_frame = filter_frame; pad.needs_fifo = 1; diff --git a/libavfilter/avfilter.c b/libavfilter/avfilter.c index 7e166e04f8..885be470c5 100644 --- a/libavfilter/avfilter.c +++ b/libavfilter/avfilter.c @@ -37,6 +37,9 @@ #include "formats.h" #include "internal.h" +#include "libavutil/ffversion.h" +const char av_filter_ffversion[] = "FFmpeg version " FFMPEG_VERSION; + static int ff_filter_frame_framed(AVFilterLink *link, AVFrame *frame); void ff_tlog_ref(void *ctx, AVFrame *ref, int end) diff --git a/libavfilter/split.c b/libavfilter/split.c index 6abd5ee2e0..7353810677 100644 --- a/libavfilter/split.c +++ b/libavfilter/split.c @@ -52,6 +52,8 @@ static av_cold int split_init(AVFilterContext *ctx) snprintf(name, sizeof(name), "output%d", i); pad.type = ctx->filter->inputs[0].type; pad.name = av_strdup(name); + if (!pad.name) + return AVERROR(ENOMEM); ff_insert_outpad(ctx, i, &pad); } diff --git a/libavfilter/src_movie.c b/libavfilter/src_movie.c index bcc8e05495..b7b1ec7256 100644 --- a/libavfilter/src_movie.c +++ b/libavfilter/src_movie.c @@ -292,6 +292,8 @@ static av_cold int movie_common_init(AVFilterContext *ctx) snprintf(name, sizeof(name), "out%d", i); pad.type = movie->st[i].st->codec->codec_type; pad.name = av_strdup(name); + if (!pad.name) + return AVERROR(ENOMEM); pad.config_props = movie_config_output_props; pad.request_frame = movie_request_frame; ff_insert_outpad(ctx, i, &pad); diff --git a/libavfilter/vf_fade.c b/libavfilter/vf_fade.c index 80ce75dcda..a7597cdff0 100644 --- a/libavfilter/vf_fade.c +++ b/libavfilter/vf_fade.c @@ -138,7 +138,9 @@ static int config_props(AVFilterLink *inlink) s->hsub = pixdesc->log2_chroma_w; s->vsub = pixdesc->log2_chroma_h; - s->bpp = av_get_bits_per_pixel(pixdesc) >> 3; + s->bpp = pixdesc->flags & AV_PIX_FMT_FLAG_PLANAR ? + 1 : + av_get_bits_per_pixel(pixdesc) >> 3; s->alpha &= !!(pixdesc->flags & AV_PIX_FMT_FLAG_ALPHA); s->is_packed_rgb = ff_fill_rgba_map(s->rgba_map, inlink->format) >= 0; diff --git a/libavfilter/vf_sab.c b/libavfilter/vf_sab.c index aa38b533fe..b8af27cdcd 100644 --- a/libavfilter/vf_sab.c +++ b/libavfilter/vf_sab.c @@ -220,6 +220,19 @@ static int config_props(AVFilterLink *inlink) #define NB_PLANES 4 +static inline int mirror(int x, int w) +{ + if (!w) + return 0; + + while ((unsigned)x > (unsigned)w) { + x = -x; + if (x < 0) + x += 2 * w; + } + return x; +} + static void blur(uint8_t *dst, const int dst_linesize, const uint8_t *src, const int src_linesize, const int w, const int h, FilterParam *fp) @@ -253,8 +266,7 @@ static void blur(uint8_t *dst, const int dst_linesize, for (dy = 0; dy < radius*2 + 1; dy++) { int dx; int iy = y+dy - radius; - if (iy < 0) iy = -iy; - else if (iy >= h) iy = h+h-iy-1; + iy = mirror(iy, h-1); for (dx = 0; dx < radius*2 + 1; dx++) { const int ix = x+dx - radius; @@ -265,13 +277,11 @@ static void blur(uint8_t *dst, const int dst_linesize, for (dy = 0; dy < radius*2+1; dy++) { int dx; int iy = y+dy - radius; - if (iy < 0) iy = -iy; - else if (iy >= h) iy = h+h-iy-1; + iy = mirror(iy, h-1); for (dx = 0; dx < radius*2 + 1; dx++) { int ix = x+dx - radius; - if (ix < 0) ix = -ix; - else if (ix >= w) ix = w+w-ix-1; + ix = mirror(ix, w-1); UPDATE_FACTOR; } } diff --git a/libavfilter/vf_spp.c b/libavfilter/vf_spp.c index 4e4a5795f4..aff1ddf305 100644 --- a/libavfilter/vf_spp.c +++ b/libavfilter/vf_spp.c @@ -233,9 +233,9 @@ static void filter(SPPContext *p, uint8_t *dst, uint8_t *src, const int y1 = y + offset[i + count - 1][1]; const int index = x1 + y1*linesize; p->pdsp.get_pixels(block, p->src + index, linesize); - p->fdsp.fdct(block); - p->requantize(block2, block, qp, p->idsp.idct_permutation); - p->idsp.idct(block2); + p->dct->fdct(block); + p->requantize(block2, block, qp, p->dct->idct_permutation); + p->dct->idct(block2); add_block(p->temp + index, linesize, block2); } } @@ -378,11 +378,11 @@ static av_cold int init(AVFilterContext *ctx) SPPContext *spp = ctx->priv; spp->avctx = avcodec_alloc_context3(NULL); - if (!spp->avctx) + spp->dct = avcodec_dct_alloc(); + if (!spp->avctx || !spp->dct) return AVERROR(ENOMEM); - ff_idctdsp_init(&spp->idsp, spp->avctx); - ff_fdctdsp_init(&spp->fdsp, spp->avctx); ff_pixblockdsp_init(&spp->pdsp, spp->avctx); + avcodec_dct_init(spp->dct); spp->store_slice = store_slice_c; switch (spp->mode) { case MODE_HARD: spp->requantize = hardthresh_c; break; @@ -403,6 +403,7 @@ static av_cold void uninit(AVFilterContext *ctx) avcodec_close(spp->avctx); av_freep(&spp->avctx); } + av_freep(&spp->dct); av_freep(&spp->non_b_qp_table); } diff --git a/libavfilter/vf_spp.h b/libavfilter/vf_spp.h index c8eac3caf2..2dcf813ed3 100644 --- a/libavfilter/vf_spp.h +++ b/libavfilter/vf_spp.h @@ -24,8 +24,7 @@ #include "libavcodec/avcodec.h" #include "libavcodec/pixblockdsp.h" -#include "libavcodec/idctdsp.h" -#include "libavcodec/fdctdsp.h" +#include "libavcodec/avdct.h" #include "avfilter.h" #define MAX_LEVEL 6 /* quality levels */ @@ -41,9 +40,8 @@ typedef struct { uint8_t *src; int16_t *temp; AVCodecContext *avctx; - IDCTDSPContext idsp; - FDCTDSPContext fdsp; PixblockDSPContext pdsp; + AVDCT *dct; int8_t *non_b_qp_table; int non_b_qp_alloc_size; int use_bframe_qp; diff --git a/libavfilter/x86/vf_hqdn3d.asm b/libavfilter/x86/vf_hqdn3d.asm index 961127e670..e3b1bdca53 100644 --- a/libavfilter/x86/vf_hqdn3d.asm +++ b/libavfilter/x86/vf_hqdn3d.asm @@ -27,8 +27,8 @@ SECTION .text %if lut_bits != 8 sar %1q, 8-lut_bits %endif - movsx %1d, word [%3q+%1q*2] - add %1d, %2d + movsx %1q, word [%3q+%1q*2] + add %1q, %2q %endmacro %macro LOAD 3 ; dstreg, x, bitdepth diff --git a/libavformat/apetag.c b/libavformat/apetag.c index 7d2f0b3222..c8d1bdca5a 100644 --- a/libavformat/apetag.c +++ b/libavformat/apetag.c @@ -55,8 +55,10 @@ static int ape_tag_read_field(AVFormatContext *s) av_log(s, AV_LOG_WARNING, "Invalid APE tag key '%s'.\n", key); return -1; } - if (size >= UINT_MAX) - return -1; + if (size > INT32_MAX - FF_INPUT_BUFFER_PADDING_SIZE) { + av_log(s, AV_LOG_ERROR, "APE tag size too large.\n"); + return AVERROR_INVALIDDATA; + } if (flags & APE_TAG_FLAG_IS_BINARY) { uint8_t filename[1024]; enum AVCodecID id; diff --git a/libavformat/avidec.c b/libavformat/avidec.c index 8c70649b47..44ed45e7ed 100644 --- a/libavformat/avidec.c +++ b/libavformat/avidec.c @@ -1141,7 +1141,7 @@ start_sync: goto start_sync; } - n = avi->dv_demux ? 0 : get_stream_idx(d); + n = get_stream_idx(d); if (!((i - avi->last_pkt_pos) & 1) && get_stream_idx(d + 1) < s->nb_streams) @@ -1153,6 +1153,9 @@ start_sync: goto start_sync; } + if (avi->dv_demux && n != 0) + continue; + // parse ##dc/##wb if (n < s->nb_streams) { AVStream *st; @@ -1524,7 +1527,8 @@ static int avi_read_idx1(AVFormatContext *s, int size) ast = st->priv_data; if (first_packet && first_packet_pos) { - data_offset = first_packet_pos - pos; + if (avi->movi_list + 4 != pos || pos + 500 > first_packet_pos) + data_offset = first_packet_pos - pos; first_packet = 0; } pos += data_offset; diff --git a/libavformat/aviobuf.c b/libavformat/aviobuf.c index 738459e830..baf7d600a6 100644 --- a/libavformat/aviobuf.c +++ b/libavformat/aviobuf.c @@ -220,6 +220,9 @@ int64_t avio_seek(AVIOContext *s, int64_t offset, int whence) return offset1; offset += offset1; } + if (offset < 0) + return AVERROR(EINVAL); + offset1 = offset - pos; if (!s->must_flush && (!s->direct || !s->seek) && offset1 >= 0 && offset1 <= buffer_size) { @@ -666,7 +669,7 @@ int ff_get_line(AVIOContext *s, char *buf, int maxlen) if (c && i < maxlen-1) buf[i++] = c; } while (c != '\n' && c != '\r' && c); - if (c == '\r' && avio_r8(s) != '\n') + if (c == '\r' && avio_r8(s) != '\n' && !url_feof(s)) avio_skip(s, -1); buf[i] = 0; diff --git a/libavformat/cdxl.c b/libavformat/cdxl.c index ab8a846cc5..51b9567d20 100644 --- a/libavformat/cdxl.c +++ b/libavformat/cdxl.c @@ -127,6 +127,8 @@ static int cdxl_read_packet(AVFormatContext *s, AVPacket *pkt) height = AV_RB16(&cdxl->header[16]); palette_size = AV_RB16(&cdxl->header[20]); audio_size = AV_RB16(&cdxl->header[22]); + if (FFALIGN(width, 16) * (uint64_t)height * cdxl->header[19] > INT_MAX) + return AVERROR_INVALIDDATA; image_size = FFALIGN(width, 16) * height * cdxl->header[19] / 8; video_size = palette_size + image_size; diff --git a/libavformat/dv.c b/libavformat/dv.c index 4f7b062f8b..1e15c08203 100644 --- a/libavformat/dv.c +++ b/libavformat/dv.c @@ -72,30 +72,33 @@ static inline uint16_t dv_audio_12to16(uint16_t sample) return result; } -/* - * This is the dumbest implementation of all -- it simply looks at - * a fixed offset and if pack isn't there -- fails. We might want - * to have a fallback mechanism for complete search of missing packs. - */ static const uint8_t *dv_extract_pack(uint8_t *frame, enum dv_pack_type t) { int offs; + int c; - switch (t) { - case dv_audio_source: - offs = (80 * 6 + 80 * 16 * 3 + 3); - break; - case dv_audio_control: - offs = (80 * 6 + 80 * 16 * 4 + 3); - break; - case dv_video_control: - offs = (80 * 5 + 48 + 5); - break; - case dv_timecode: - offs = (80*1 + 3 + 3); - break; - default: - return NULL; + for (c = 0; c < 10; c++) { + switch (t) { + case dv_audio_source: + if (c&1) offs = (80 * 6 + 80 * 16 * 0 + 3 + c*12000); + else offs = (80 * 6 + 80 * 16 * 3 + 3 + c*12000); + break; + case dv_audio_control: + if (c&1) offs = (80 * 6 + 80 * 16 * 1 + 3 + c*12000); + else offs = (80 * 6 + 80 * 16 * 4 + 3 + c*12000); + break; + case dv_video_control: + if (c&1) offs = (80 * 3 + 8 + c*12000); + else offs = (80 * 5 + 48 + 5 + c*12000); + break; + case dv_timecode: + offs = (80*1 + 3 + 3); + break; + default: + return NULL; + } + if (frame[offs] == t) + break; } return frame[offs] == t ? &frame[offs] : NULL; diff --git a/libavformat/flvdec.c b/libavformat/flvdec.c index 899a0368f4..263a7035d1 100644 --- a/libavformat/flvdec.c +++ b/libavformat/flvdec.c @@ -390,7 +390,7 @@ static int amf_parse_object(AVFormatContext *s, AVStream *astream, FLVContext *flv = s->priv_data; AVIOContext *ioc; AMFDataType amf_type; - char str_val[256]; + char str_val[1024]; double num_val; num_val = 0; @@ -555,13 +555,13 @@ static int flv_read_metabody(AVFormatContext *s, int64_t next_pos) type = avio_r8(ioc); if (type != AMF_DATA_TYPE_STRING || amf_get_string(ioc, buffer, sizeof(buffer)) < 0) - return -1; + return 2; if (!strcmp(buffer, "onTextData")) return 1; if (strcmp(buffer, "onMetaData")) - return -1; + return 2; // find the streams now so that amf_parse_object doesn't need to do // the lookup every time it is called. @@ -620,7 +620,7 @@ static int flv_read_close(AVFormatContext *s) static int flv_get_extradata(AVFormatContext *s, AVStream *st, int size) { - av_free(st->codec->extradata); + av_freep(&st->codec->extradata); if (ff_get_extradata(st->codec, s->pb, size) < 0) return AVERROR(ENOMEM); return 0; @@ -819,7 +819,7 @@ static int flv_read_packet(AVFormatContext *s, AVPacket *pkt) stream_type=FLV_STREAM_TYPE_DATA; if (size > 13 + 1 + 4 && dts == 0) { // Header-type metadata stuff meta_pos = avio_tell(s->pb); - if (flv_read_metabody(s, next) == 0) { + if (flv_read_metabody(s, next) <= 0) { goto skip; } avio_seek(s->pb, meta_pos, SEEK_SET); diff --git a/libavformat/hlsenc.c b/libavformat/hlsenc.c index 388a23a18b..313fcd3e6a 100644 --- a/libavformat/hlsenc.c +++ b/libavformat/hlsenc.c @@ -314,9 +314,10 @@ static int hls_write_trailer(struct AVFormatContext *s) av_write_trailer(oc); avio_closep(&oc->pb); - avformat_free_context(oc); av_free(hls->basename); append_entry(hls, hls->duration); + avformat_free_context(oc); + hls->avf = NULL; hls_window(s, 1); free_entries(hls); diff --git a/libavformat/img2dec.c b/libavformat/img2dec.c index cda4996568..f97800797e 100644 --- a/libavformat/img2dec.c +++ b/libavformat/img2dec.c @@ -666,6 +666,7 @@ static const AVClass imgname ## _class = {\ };\ AVInputFormat ff_image_ ## imgname ## _pipe_demuxer = {\ .name = AV_STRINGIFY(imgname) "_pipe",\ + .long_name = NULL_IF_CONFIG_SMALL("piped " AV_STRINGIFY(imgname) " sequence"),\ .priv_data_size = sizeof(VideoDemuxData),\ .read_probe = imgname ## _probe,\ .read_header = ff_img_read_header,\ diff --git a/libavformat/isom.h b/libavformat/isom.h index 414b87cc9d..ab285af4ea 100644 --- a/libavformat/isom.h +++ b/libavformat/isom.h @@ -171,6 +171,7 @@ typedef struct MOVContext { int *bitrates; ///< bitrates read before streams creation int bitrates_count; int moov_retry; + int atom_depth; } MOVContext; int ff_mp4_read_descr_len(AVIOContext *pb); diff --git a/libavformat/m4vdec.c b/libavformat/m4vdec.c index ead0066cca..80bd75e589 100644 --- a/libavformat/m4vdec.c +++ b/libavformat/m4vdec.c @@ -33,13 +33,15 @@ static int mpeg4video_probe(AVProbeData *probe_packet) for(i=0; ibuf_size; i++){ temp_buffer = (temp_buffer<<8) + probe_packet->buf[i]; - if ((temp_buffer & 0xffffff00) != 0x100) + if (temp_buffer & 0xfffffe00) + continue; + if (temp_buffer < 2) continue; if (temp_buffer == VOP_START_CODE) VOP++; else if (temp_buffer == VISUAL_OBJECT_START_CODE) VISO++; - else if (temp_buffer < 0x120) VO++; - else if (temp_buffer < 0x130) VOL++; + else if (temp_buffer >= 0x100 && temp_buffer < 0x120) VO++; + else if (temp_buffer >= 0x120 && temp_buffer < 0x130) VOL++; else if ( !(0x1AF < temp_buffer && temp_buffer < 0x1B7) && !(0x1B9 < temp_buffer && temp_buffer < 0x1C4)) res++; } diff --git a/libavformat/matroskadec.c b/libavformat/matroskadec.c index ec43526727..ac7d0ea095 100644 --- a/libavformat/matroskadec.c +++ b/libavformat/matroskadec.c @@ -1078,7 +1078,7 @@ static void ebml_free(EbmlSyntax *syntax, void *data) for (j = 0; j < list->nb_elem; j++, ptr += syntax[i].list_elem_size) ebml_free(syntax[i].def.n, ptr); - av_free(list->elem); + av_freep(&list->elem); } else ebml_free(syntax[i].def.n, data_off); default: @@ -1471,13 +1471,17 @@ static void matroska_execute_seekhead(MatroskaDemuxContext *matroska) EbmlList *seekhead_list = &matroska->seekhead; int64_t before_pos = avio_tell(matroska->ctx->pb); int i; + int nb_elem; // we should not do any seeking in the streaming case if (!matroska->ctx->pb->seekable || (matroska->ctx->flags & AVFMT_FLAG_IGNIDX)) return; - for (i = 0; i < seekhead_list->nb_elem; i++) { + // do not read entries that are added while parsing seekhead entries + nb_elem = seekhead_list->nb_elem; + + for (i = 0; i < nb_elem; i++) { MatroskaSeekhead *seekhead = seekhead_list->elem; if (seekhead[i].pos <= before_pos) continue; @@ -1979,7 +1983,8 @@ static int matroska_parse_tracks(AVFormatContext *s) av_reduce(&st->avg_frame_rate.num, &st->avg_frame_rate.den, 1000000000, track->default_duration, 30000); #if FF_API_R_FRAME_RATE - if (st->avg_frame_rate.num < st->avg_frame_rate.den * 1000L) + if ( st->avg_frame_rate.num < st->avg_frame_rate.den * 1000L + && st->avg_frame_rate.num > st->avg_frame_rate.den * 5L) st->r_frame_rate = st->avg_frame_rate; #endif } @@ -2161,8 +2166,10 @@ static int matroska_read_header(AVFormatContext *s) (AVRational) { 1, 1000000000 }, chapters[i].start, chapters[i].end, chapters[i].title); - av_dict_set(&chapters[i].chapter->metadata, - "title", chapters[i].title, 0); + if (chapters[i].chapter) { + av_dict_set(&chapters[i].chapter->metadata, + "title", chapters[i].title, 0); + } max_start = chapters[i].start; } @@ -2182,7 +2189,7 @@ static int matroska_deliver_packet(MatroskaDemuxContext *matroska, { if (matroska->num_packets > 0) { memcpy(pkt, matroska->packets[0], sizeof(AVPacket)); - av_free(matroska->packets[0]); + av_freep(&matroska->packets[0]); if (matroska->num_packets > 1) { void *newpackets; memmove(&matroska->packets[0], &matroska->packets[1], @@ -2213,7 +2220,7 @@ static void matroska_clear_queue(MatroskaDemuxContext *matroska) int n; for (n = 0; n < matroska->num_packets; n++) { av_free_packet(matroska->packets[n]); - av_free(matroska->packets[n]); + av_freep(&matroska->packets[n]); } av_freep(&matroska->packets); matroska->num_packets = 0; @@ -3061,7 +3068,7 @@ static int matroska_read_close(AVFormatContext *s) for (n = 0; n < matroska->tracks.nb_elem; n++) if (tracks[n].type == MATROSKA_TRACK_TYPE_AUDIO) - av_free(tracks[n].audio.buf); + av_freep(&tracks[n].audio.buf); ebml_free(matroska_cluster, &matroska->current_cluster); ebml_free(matroska_segment, matroska); diff --git a/libavformat/matroskaenc.c b/libavformat/matroskaenc.c index 92d091f7cf..fc9c72852a 100644 --- a/libavformat/matroskaenc.c +++ b/libavformat/matroskaenc.c @@ -445,8 +445,21 @@ static int64_t mkv_write_cues(AVFormatContext *s, mkv_cues *cues, mkv_track *tra ebml_master cuepoint, track_positions; mkv_cuepoint *entry = &cues->entries[i]; uint64_t pts = entry->pts; + int ctp_nb = 0; - cuepoint = start_ebml_master(pb, MATROSKA_ID_POINTENTRY, MAX_CUEPOINT_SIZE(num_tracks)); + // Calculate the number of entries, so we know the element size + for (j = 0; j < num_tracks; j++) + tracks[j].has_cue = 0; + for (j = 0; j < cues->num_entries - i && entry[j].pts == pts; j++) { + int tracknum = entry[j].stream_idx; + av_assert0(tracknum>=0 && tracknumstreams[tracknum]->codec->codec_type != AVMEDIA_TYPE_SUBTITLE) + continue; + tracks[tracknum].has_cue = 1; + ctp_nb ++; + } + + cuepoint = start_ebml_master(pb, MATROSKA_ID_POINTENTRY, MAX_CUEPOINT_SIZE(ctp_nb)); put_ebml_uint(pb, MATROSKA_ID_CUETIME, pts); // put all the entries from different tracks that have the exact same diff --git a/libavformat/mov.c b/libavformat/mov.c index 9b4832fb34..303c9accf1 100644 --- a/libavformat/mov.c +++ b/libavformat/mov.c @@ -214,7 +214,11 @@ static int mov_read_covr(MOVContext *c, AVIOContext *pb, int type, int len) static int mov_metadata_raw(MOVContext *c, AVIOContext *pb, unsigned len, const char *key) { - char *value = av_malloc(len + 1); + char *value; + // Check for overflow. + if (len >= INT_MAX) + return AVERROR(EINVAL); + value = av_malloc(len + 1); if (!value) return AVERROR(ENOMEM); avio_read(pb, value, len); @@ -356,7 +360,7 @@ static int mov_read_udta_string(MOVContext *c, AVIOContext *pb, MOVAtom atom) if (!key) return 0; - if (atom.size < 0) + if (atom.size < 0 || str_size >= INT_MAX/2) return AVERROR_INVALIDDATA; str_size = FFMIN3(sizeof(str)-1, str_size, atom.size); @@ -1173,10 +1177,12 @@ static int mov_read_stco(MOVContext *c, AVIOContext *pb, MOVAtom atom) if (!entries) return 0; - if (entries >= UINT_MAX/sizeof(int64_t)) - return AVERROR_INVALIDDATA; - sc->chunk_offsets = av_malloc(entries * sizeof(int64_t)); + if (sc->chunk_offsets) + av_log(c->fc, AV_LOG_WARNING, "Duplicate STCO atom\n"); + av_free(sc->chunk_offsets); + sc->chunk_count = 0; + sc->chunk_offsets = av_malloc_array(entries, sizeof(*sc->chunk_offsets)); if (!sc->chunk_offsets) return AVERROR(ENOMEM); sc->chunk_count = entries; @@ -1452,7 +1458,7 @@ static void mov_parse_stsd_audio(MOVContext *c, AVIOContext *pb, static void mov_parse_stsd_subtitle(MOVContext *c, AVIOContext *pb, AVStream *st, MOVStreamContext *sc, - int size) + int64_t size) { // ttxt stsd contains display flags, justification, background // color, fonts, and default styles, so fake an atom to read it @@ -1517,10 +1523,10 @@ static int mov_rewrite_dvd_sub_extradata(AVStream *st) static int mov_parse_stsd_data(MOVContext *c, AVIOContext *pb, AVStream *st, MOVStreamContext *sc, - int size) + int64_t size) { if (st->codec->codec_tag == MKTAG('t','m','c','d')) { - if (ff_get_extradata(st->codec, pb, size) < 0) + if ((int)size != size || ff_get_extradata(st->codec, pb, size) < 0) return AVERROR(ENOMEM); if (size > 16) { MOVStreamContext *tmcd_ctx = st->priv_data; @@ -1745,9 +1751,11 @@ static int mov_read_stsc(MOVContext *c, AVIOContext *pb, MOVAtom atom) if (!entries) return 0; - if (entries >= UINT_MAX / sizeof(*sc->stsc_data)) - return AVERROR_INVALIDDATA; - sc->stsc_data = av_malloc(entries * sizeof(*sc->stsc_data)); + if (sc->stsc_data) + av_log(c->fc, AV_LOG_WARNING, "Duplicate STSC atom\n"); + av_free(sc->stsc_data); + sc->stsc_count = 0; + sc->stsc_data = av_malloc_array(entries, sizeof(*sc->stsc_data)); if (!sc->stsc_data) return AVERROR(ENOMEM); @@ -1779,9 +1787,11 @@ static int mov_read_stps(MOVContext *c, AVIOContext *pb, MOVAtom atom) avio_rb32(pb); // version + flags entries = avio_rb32(pb); - if (entries >= UINT_MAX / sizeof(*sc->stps_data)) - return AVERROR_INVALIDDATA; - sc->stps_data = av_malloc(entries * sizeof(*sc->stps_data)); + if (sc->stps_data) + av_log(c->fc, AV_LOG_WARNING, "Duplicate STPS atom\n"); + av_free(sc->stps_data); + sc->stps_count = 0; + sc->stps_data = av_malloc_array(entries, sizeof(*sc->stps_data)); if (!sc->stps_data) return AVERROR(ENOMEM); @@ -1823,9 +1833,11 @@ static int mov_read_stss(MOVContext *c, AVIOContext *pb, MOVAtom atom) st->need_parsing = AVSTREAM_PARSE_HEADERS; return 0; } - if (entries >= UINT_MAX / sizeof(int)) - return AVERROR_INVALIDDATA; - sc->keyframes = av_malloc(entries * sizeof(int)); + if (sc->keyframes) + av_log(c->fc, AV_LOG_WARNING, "Duplicate STSS atom\n"); + av_free(sc->keyframes); + sc->keyframe_count = 0; + sc->keyframes = av_malloc_array(entries, sizeof(*sc->keyframes)); if (!sc->keyframes) return AVERROR(ENOMEM); @@ -1884,9 +1896,13 @@ static int mov_read_stsz(MOVContext *c, AVIOContext *pb, MOVAtom atom) if (!entries) return 0; - if (entries >= UINT_MAX / sizeof(int) || entries >= (UINT_MAX - 4) / field_size) + if (entries >= (UINT_MAX - 4) / field_size) return AVERROR_INVALIDDATA; - sc->sample_sizes = av_malloc(entries * sizeof(int)); + if (sc->sample_sizes) + av_log(c->fc, AV_LOG_WARNING, "Duplicate STSZ atom\n"); + av_free(sc->sample_sizes); + sc->sample_count = 0; + sc->sample_sizes = av_malloc_array(entries, sizeof(*sc->sample_sizes)); if (!sc->sample_sizes) return AVERROR(ENOMEM); @@ -1940,11 +1956,11 @@ static int mov_read_stts(MOVContext *c, AVIOContext *pb, MOVAtom atom) av_dlog(c->fc, "track[%i].stts.entries = %i\n", c->fc->nb_streams-1, entries); - if (entries >= UINT_MAX / sizeof(*sc->stts_data)) - return -1; - + if (sc->stts_data) + av_log(c->fc, AV_LOG_WARNING, "Duplicate STTS atom\n"); av_free(sc->stts_data); - sc->stts_data = av_malloc(entries * sizeof(*sc->stts_data)); + sc->stts_count = 0; + sc->stts_data = av_malloc_array(entries, sizeof(*sc->stts_data)); if (!sc->stts_data) return AVERROR(ENOMEM); @@ -2083,9 +2099,11 @@ static int mov_read_sbgp(MOVContext *c, AVIOContext *pb, MOVAtom atom) entries = avio_rb32(pb); if (!entries) return 0; - if (entries >= UINT_MAX / sizeof(*sc->rap_group)) - return AVERROR_INVALIDDATA; - sc->rap_group = av_malloc(entries * sizeof(*sc->rap_group)); + if (sc->rap_group) + av_log(c->fc, AV_LOG_WARNING, "Duplicate SBGP atom\n"); + av_free(sc->rap_group); + sc->rap_group_count = 0; + sc->rap_group = av_malloc_array(entries, sizeof(*sc->rap_group)); if (!sc->rap_group) return AVERROR(ENOMEM); @@ -2935,6 +2953,7 @@ static int mov_read_cmov(MOVContext *c, AVIOContext *pb, MOVAtom atom) goto free_and_return; if (ffio_init_context(&ctx, moov_data, moov_len, 0, NULL, NULL, NULL, NULL) != 0) goto free_and_return; + ctx.seekable = AVIO_SEEKABLE_NORMAL; atom.type = MKTAG('m','o','o','v'); atom.size = moov_len; ret = mov_read_default(c, &ctx, atom); @@ -3151,6 +3170,12 @@ static int mov_read_default(MOVContext *c, AVIOContext *pb, MOVAtom atom) MOVAtom a; int i; + if (c->atom_depth > 10) { + av_log(c->fc, AV_LOG_ERROR, "Atoms too deeply nested\n"); + return AVERROR_INVALIDDATA; + } + c->atom_depth ++; + if (atom.size < 0) atom.size = INT64_MAX; while (total_size + 8 <= atom.size && !url_feof(pb)) { @@ -3180,11 +3205,12 @@ static int mov_read_default(MOVContext *c, AVIOContext *pb, MOVAtom atom) { av_log(c->fc, AV_LOG_ERROR, "Broken file, trak/mdat not at top-level\n"); avio_skip(pb, -8); + c->atom_depth --; return 0; } } total_size += 8; - if (a.size == 1) { /* 64 bit extended size */ + if (a.size == 1 && total_size + 8 <= atom.size) { /* 64 bit extended size */ a.size = avio_rb64(pb) - 8; total_size += 8; } @@ -3216,13 +3242,16 @@ static int mov_read_default(MOVContext *c, AVIOContext *pb, MOVAtom atom) int64_t start_pos = avio_tell(pb); int64_t left; int err = parse(c, pb, a); - if (err < 0) + if (err < 0) { + c->atom_depth --; return err; + } if (c->found_moov && c->found_mdat && ((!pb->seekable || c->fc->flags & AVFMT_FLAG_IGNIDX) || start_pos + a.size == avio_size(pb))) { if (!pb->seekable || c->fc->flags & AVFMT_FLAG_IGNIDX) c->next_root_atom = start_pos + a.size; + c->atom_depth --; return 0; } left = a.size - avio_tell(pb) + start_pos; @@ -3242,6 +3271,7 @@ static int mov_read_default(MOVContext *c, AVIOContext *pb, MOVAtom atom) if (total_size < atom.size && atom.size < 0x7ffff) avio_skip(pb, atom.size - total_size); + c->atom_depth --; return 0; } diff --git a/libavformat/mp3dec.c b/libavformat/mp3dec.c index 8335388409..8936854621 100644 --- a/libavformat/mp3dec.c +++ b/libavformat/mp3dec.c @@ -398,6 +398,8 @@ static int mp3_seek(AVFormatContext *s, int stream_index, int64_t timestamp, int64_t ret = av_index_search_timestamp(st, timestamp, flags); int i, j; int dir = (flags&AVSEEK_FLAG_BACKWARD) ? -1 : 1; + int64_t best_pos; + int best_score; if (mp3->is_cbr && st->duration > 0 && mp3->header_filesize > s->data_offset) { int64_t filesize = avio_size(s->pb); @@ -421,28 +423,37 @@ static int mp3_seek(AVFormatContext *s, int stream_index, int64_t timestamp, return -1; } - if (dir < 0) - avio_seek(s->pb, FFMAX(ie->pos - 4096, 0), SEEK_SET); + avio_seek(s->pb, FFMAX(ie->pos - 4096, 0), SEEK_SET); ret = avio_seek(s->pb, ie->pos, SEEK_SET); if (ret < 0) return ret; #define MIN_VALID 3 + best_pos = ie->pos; + best_score = 999; for(i=0; i<4096; i++) { - int64_t pos = ie->pos + i*dir; + int64_t pos = ie->pos + (dir > 0 ? i - 1024 : -i); + int64_t candidate = -1; + int score = 999; for(j=0; jpos - pos)*dir <= 0 && abs(MIN_VALID/2-j) < score) { + candidate = pos; + score = abs(MIN_VALID/2-j); + } pos += ret; } - if(j==MIN_VALID) - break; + if (best_score > score && j == MIN_VALID) { + best_pos = candidate; + best_score = score; + if(score == 0) + break; + } } - if(j!=MIN_VALID) - i=0; - ret = avio_seek(s->pb, ie->pos + i*dir, SEEK_SET); + ret = avio_seek(s->pb, best_pos, SEEK_SET); if (ret < 0) return ret; ff_update_cur_dts(s, st, ie->timestamp); diff --git a/libavformat/mpeg.c b/libavformat/mpeg.c index c53bab3e3c..14a75c0201 100644 --- a/libavformat/mpeg.c +++ b/libavformat/mpeg.c @@ -101,7 +101,7 @@ static int mpegps_probe(AVProbeData *p) if (sys > invalid && sys * 9 <= pspack * 10) return (audio > 12 || vid > 3 || pspack > 2) ? AVPROBE_SCORE_EXTENSION + 2 - : AVPROBE_SCORE_EXTENSION / 2; // 1 more than .mpg + : AVPROBE_SCORE_EXTENSION / 2 + 1; // 1 more than .mpg if (pspack > invalid && (priv1 + vid + audio) * 10 >= pspack * 9) return pspack > 2 ? AVPROBE_SCORE_EXTENSION + 2 : AVPROBE_SCORE_EXTENSION / 2; // 1 more than .mpg @@ -783,7 +783,7 @@ static int vobsub_read_header(AVFormatContext *s) while (*p == ' ') p++; - av_log(s, AV_LOG_DEBUG, "IDX stream[%d] name=%s\n", st->id, p); + av_log(s, AV_LOG_DEBUG, "IDX stream[%d] name=%s\n", stream_id, p); av_strlcpy(alt, p, sizeof(alt)); header_parsed = 1; diff --git a/libavformat/mpegts.c b/libavformat/mpegts.c index 71140888a5..520644fbbc 100644 --- a/libavformat/mpegts.c +++ b/libavformat/mpegts.c @@ -504,6 +504,7 @@ static void mpegts_close_filter(MpegTSContext *ts, MpegTSFilter *filter) static int analyze(const uint8_t *buf, int size, int packet_size, int *index) { int stat[TS_MAX_PACKET_SIZE]; + int stat_all = 0; int i; int best_score = 0; @@ -513,6 +514,7 @@ static int analyze(const uint8_t *buf, int size, int packet_size, int *index) if (buf[i] == 0x47 && !(buf[i + 1] & 0x80) && buf[i + 3] != 0x47) { int x = i % packet_size; stat[x]++; + stat_all++; if (stat[x] > best_score) { best_score = stat[x]; if (index) @@ -521,7 +523,7 @@ static int analyze(const uint8_t *buf, int size, int packet_size, int *index) } } - return best_score; + return best_score - FFMAX(stat_all - 10*best_score, 0)/10; } /* autodetect fec presence. Must have at least 1024 bytes */ @@ -849,8 +851,12 @@ static int read_sl_header(PESContext *pes, SLConfigDescr *sl, 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; + uint8_t buf_padded[128 + FF_INPUT_BUFFER_PADDING_SIZE]; + int buf_padded_size = FFMIN(buf_size, sizeof(buf_padded) - FF_INPUT_BUFFER_PADDING_SIZE); - init_get_bits(&gb, buf, buf_size * 8); + memcpy(buf_padded, buf, buf_padded_size); + + init_get_bits(&gb, buf_padded, buf_padded_size * 8); if (sl->use_au_start) au_start_flag = get_bits1(&gb); @@ -1985,7 +1991,7 @@ static void sdt_cb(MpegTSFilter *filter, const uint8_t *section, int section_len break; desc_len = get8(&p, desc_list_end); desc_end = p + desc_len; - if (desc_end > desc_list_end) + if (desc_len < 0 || desc_end > desc_list_end) break; av_dlog(ts->stream, "tag: 0x%02x len=%d\n", diff --git a/libavformat/oggdec.c b/libavformat/oggdec.c index f7d00c1b4b..74df6e72ad 100644 --- a/libavformat/oggdec.c +++ b/libavformat/oggdec.c @@ -817,7 +817,6 @@ retry: return psize; fail: av_free_packet(pkt); - av_free(pkt); return AVERROR(ENOMEM); } diff --git a/libavformat/oggenc.c b/libavformat/oggenc.c index f6a6d7d96d..2b1cbe3bf3 100644 --- a/libavformat/oggenc.c +++ b/libavformat/oggenc.c @@ -249,7 +249,7 @@ static int ogg_buffer_data(AVFormatContext *s, AVStream *st, if (i == total_segments) page->granule = granule; - if (!header) { + { AVStream *st = s->streams[page->stream_index]; int64_t start = av_rescale_q(page->start_granule, st->time_base, @@ -257,10 +257,13 @@ static int ogg_buffer_data(AVFormatContext *s, AVStream *st, int64_t next = av_rescale_q(page->granule, st->time_base, AV_TIME_BASE_Q); - if (page->segments_count == 255 || - (ogg->pref_size > 0 && page->size >= ogg->pref_size) || - (ogg->pref_duration > 0 && next - start >= ogg->pref_duration)) { + if (page->segments_count == 255) { ogg_buffer_page(s, oggstream); + } else if (!header) { + if ((ogg->pref_size > 0 && page->size >= ogg->pref_size) || + (ogg->pref_duration > 0 && next - start >= ogg->pref_duration)) { + ogg_buffer_page(s, oggstream); + } } } } diff --git a/libavformat/options_table.h b/libavformat/options_table.h index e3943fd5f3..c1a66a8fe8 100644 --- a/libavformat/options_table.h +++ b/libavformat/options_table.h @@ -93,6 +93,7 @@ static const AVOption avformat_options[] = { {"strict", "how strictly to follow the standards", OFFSET(strict_std_compliance), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, INT_MIN, INT_MAX, D|E, "strict"}, {"strict", "strictly conform to all the things in the spec no matter what the consequences", 0, AV_OPT_TYPE_CONST, {.i64 = FF_COMPLIANCE_STRICT }, INT_MIN, INT_MAX, D|E, "strict"}, {"normal", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_COMPLIANCE_NORMAL }, INT_MIN, INT_MAX, D|E, "strict"}, +{"unofficial", "allow unofficial extensions", 0, AV_OPT_TYPE_CONST, {.i64 = FF_COMPLIANCE_UNOFFICIAL }, INT_MIN, INT_MAX, D|E, "strict"}, {"experimental", "allow non-standardized experimental variants", 0, AV_OPT_TYPE_CONST, {.i64 = FF_COMPLIANCE_EXPERIMENTAL }, INT_MIN, INT_MAX, D|E, "strict"}, {NULL}, }; diff --git a/libavformat/riffenc.c b/libavformat/riffenc.c index ef4d399030..2eb2ae1d0e 100644 --- a/libavformat/riffenc.c +++ b/libavformat/riffenc.c @@ -209,11 +209,15 @@ int ff_put_wav_header(AVIOContext *pb, AVCodecContext *enc, int flags) void ff_put_bmp_header(AVIOContext *pb, AVCodecContext *enc, const AVCodecTag *tags, int for_asf, int ignore_extradata) { + int keep_height = enc->extradata_size >= 9 && + !memcmp(enc->extradata + enc->extradata_size - 9, "BottomUp", 9); + int extradata_size = enc->extradata_size - 9*keep_height; + /* size */ - avio_wl32(pb, 40 + (ignore_extradata ? 0 : enc->extradata_size)); + avio_wl32(pb, 40 + (ignore_extradata ? 0 :extradata_size)); avio_wl32(pb, enc->width); //We always store RGB TopDown - avio_wl32(pb, enc->codec_tag ? enc->height : -enc->height); + avio_wl32(pb, enc->codec_tag || keep_height ? enc->height : -enc->height); /* planes */ avio_wl16(pb, 1); /* depth */ @@ -227,9 +231,9 @@ void ff_put_bmp_header(AVIOContext *pb, AVCodecContext *enc, avio_wl32(pb, 0); if (!ignore_extradata) { - avio_write(pb, enc->extradata, enc->extradata_size); + avio_write(pb, enc->extradata, extradata_size); - if (!for_asf && enc->extradata_size & 1) + if (!for_asf && extradata_size & 1) avio_w8(pb, 0); } } diff --git a/libavformat/rmdec.c b/libavformat/rmdec.c index 36764ee9b2..11878a4931 100644 --- a/libavformat/rmdec.c +++ b/libavformat/rmdec.c @@ -312,6 +312,9 @@ ff_rm_read_mdpr_codecdata (AVFormatContext *s, AVIOContext *pb, int64_t codec_pos; int ret; + if (codec_data_size < 0) + return AVERROR_INVALIDDATA; + avpriv_set_pts_info(st, 64, 1, 1000); codec_pos = avio_tell(pb); v = avio_rb32(pb); diff --git a/libavformat/rsd.c b/libavformat/rsd.c index b6f168633b..c14ade09ea 100644 --- a/libavformat/rsd.c +++ b/libavformat/rsd.c @@ -70,7 +70,7 @@ static int rsd_read_header(AVFormatContext *s) codec->codec_tag = avio_rl32(pb); codec->codec_id = ff_codec_get_id(rsd_tags, codec->codec_tag); if (!codec->codec_id) { - char tag_buf[5]; + char tag_buf[32]; av_get_codec_tag_string(tag_buf, sizeof(tag_buf), codec->codec_tag); for (i=0; i < FF_ARRAY_ELEMS(rsd_unsupported_tags); i++) { diff --git a/libavformat/segment.c b/libavformat/segment.c index f8227d149e..07351d60dc 100644 --- a/libavformat/segment.c +++ b/libavformat/segment.c @@ -336,7 +336,7 @@ static int segment_end(AVFormatContext *s, int write_trailer, int is_last) if (seg->list_size && seg->segment_count > seg->list_size) { entry = seg->segment_list_entries; seg->segment_list_entries = seg->segment_list_entries->next; - av_free(entry->filename); + av_freep(&entry->filename); av_freep(&entry); } @@ -494,10 +494,10 @@ static int open_null_ctx(AVIOContext **ctx) return 0; } -static void close_null_ctx(AVIOContext *pb) +static void close_null_ctxp(AVIOContext **pb) { - av_free(pb->buffer); - av_free(pb); + av_freep(&(*pb)->buffer); + av_freep(pb); } static int select_reference_stream(AVFormatContext *s) @@ -562,6 +562,7 @@ static int seg_write_header(AVFormatContext *s) SegmentContext *seg = s->priv_data; AVFormatContext *oc = NULL; int ret; + int i; seg->segment_count = 0; if (!seg->write_header_trailer) @@ -649,11 +650,18 @@ static int seg_write_header(AVFormatContext *s) } seg->is_first_pkt = 1; + av_assert0(s->nb_streams == oc->nb_streams); + for (i = 0; i < s->nb_streams; i++) { + AVStream *inner_st = oc->streams[i]; + AVStream *outer_st = s->streams[i]; + avpriv_set_pts_info(outer_st, inner_st->pts_wrap_bits, inner_st->time_base.num, inner_st->time_base.den); + } + if (oc->avoid_negative_ts > 0 && s->avoid_negative_ts < 0) s->avoid_negative_ts = 1; if (!seg->write_header_trailer) { - close_null_ctx(oc->pb); + close_null_ctxp(&oc->pb); if ((ret = avio_open2(&oc->pb, oc->filename, AVIO_FLAG_WRITE, &s->interrupt_callback, NULL)) < 0) goto fail; @@ -684,7 +692,7 @@ static int seg_write_packet(AVFormatContext *s, AVPacket *pkt) end_pts = seg->segment_count < seg->nb_times ? seg->times[seg->segment_count] : INT64_MAX; } else if (seg->frames) { - start_frame = seg->segment_count <= seg->nb_frames ? + start_frame = seg->segment_count < seg->nb_frames ? seg->frames[seg->segment_count] : INT_MAX; } else { if (seg->use_clocktime) { @@ -779,7 +787,7 @@ static int seg_write_trailer(struct AVFormatContext *s) goto fail; open_null_ctx(&oc->pb); ret = av_write_trailer(oc); - close_null_ctx(oc->pb); + close_null_ctxp(&oc->pb); } else { ret = segment_end(s, 1, 1); } @@ -794,7 +802,7 @@ fail: cur = seg->segment_list_entries; while (cur) { next = cur->next; - av_free(cur->filename); + av_freep(&cur->filename); av_free(cur); cur = next; } diff --git a/libavformat/swfdec.c b/libavformat/swfdec.c index c95b18ec6c..35c91df794 100644 --- a/libavformat/swfdec.c +++ b/libavformat/swfdec.c @@ -289,6 +289,7 @@ static int swf_read_packet(AVFormatContext *s, AVPacket *pkt) const int bmp_fmt = avio_r8(pb); const int width = avio_rl16(pb); const int height = avio_rl16(pb); + int pix_fmt; len -= 2+1+2+2; @@ -353,17 +354,21 @@ static int swf_read_packet(AVFormatContext *s, AVPacket *pkt) avpriv_set_pts_info(vst, 64, 256, swf->frame_rate); st = vst; } - st->codec->width = width; - st->codec->height = height; if ((res = av_new_packet(pkt, out_len - colormapsize * colormapbpp)) < 0) goto bitmap_end; + if (!st->codec->width && !st->codec->height) { + st->codec->width = width; + st->codec->height = height; + } else { + ff_add_param_change(pkt, 0, 0, 0, width, height); + } pkt->pos = pos; pkt->stream_index = st->index; switch (bmp_fmt) { case 3: - st->codec->pix_fmt = AV_PIX_FMT_PAL8; + pix_fmt = AV_PIX_FMT_PAL8; for (i = 0; i < colormapsize; i++) if (alpha_bmp) colormap[i] = buf[3]<<24 | AV_RB24(buf + 4*i); else colormap[i] = 0xffU <<24 | AV_RB24(buf + 3*i); @@ -375,14 +380,18 @@ static int swf_read_packet(AVFormatContext *s, AVPacket *pkt) memcpy(pal, colormap, AVPALETTE_SIZE); break; case 4: - st->codec->pix_fmt = AV_PIX_FMT_RGB555; + pix_fmt = AV_PIX_FMT_RGB555; break; case 5: - st->codec->pix_fmt = alpha_bmp ? AV_PIX_FMT_ARGB : AV_PIX_FMT_0RGB; + pix_fmt = alpha_bmp ? AV_PIX_FMT_ARGB : AV_PIX_FMT_0RGB; break; default: av_assert0(0); } + if (st->codec->pix_fmt != AV_PIX_FMT_NONE && st->codec->pix_fmt != pix_fmt) { + av_log(s, AV_LOG_ERROR, "pixel format change unsupported\n"); + }else + st->codec->pix_fmt = pix_fmt; if (linesize * height > pkt->size) { res = AVERROR_INVALIDDATA; diff --git a/libavformat/tee.c b/libavformat/tee.c index f26e15742a..681f94330a 100644 --- a/libavformat/tee.c +++ b/libavformat/tee.c @@ -467,7 +467,7 @@ static int tee_write_packet(AVFormatContext *avf, AVPacket *pkt) if ((ret = av_copy_packet(&pkt2, pkt)) < 0 || (ret = av_dup_packet(&pkt2))< 0) if (!ret_all) { - ret = ret_all; + ret_all = ret; continue; } tb = avf ->streams[s ]->time_base; diff --git a/libavformat/utils.c b/libavformat/utils.c index e095d601e1..c43050f09c 100644 --- a/libavformat/utils.c +++ b/libavformat/utils.c @@ -53,6 +53,9 @@ #include "riff.h" #include "url.h" +#include "libavutil/ffversion.h" +const char av_format_ffversion[] = "FFmpeg version " FFMPEG_VERSION; + /** * @file * various utility functions for use within FFmpeg @@ -730,6 +733,8 @@ static int update_wrap_reference(AVFormatContext *s, AVStream *st, int stream_in int default_stream_index = av_find_default_stream_index(s); if (s->streams[default_stream_index]->pts_wrap_reference == AV_NOPTS_VALUE) { for (i = 0; i < s->nb_streams; i++) { + if (av_find_program_from_stream(s, NULL, i)) + continue; s->streams[i]->pts_wrap_reference = pts_wrap_reference; s->streams[i]->pts_wrap_behavior = pts_wrap_behavior; } @@ -2949,6 +2954,7 @@ int ff_alloc_extradata(AVCodecContext *avctx, int size) int ret; if (size < 0 || size >= INT32_MAX - FF_INPUT_BUFFER_PADDING_SIZE) { + avctx->extradata = NULL; avctx->extradata_size = 0; return AVERROR(EINVAL); } diff --git a/libavutil/cpu.c b/libavutil/cpu.c index 2d402117d0..e9bfb583c8 100644 --- a/libavutil/cpu.c +++ b/libavutil/cpu.c @@ -225,6 +225,10 @@ int av_parse_cpu_caps(unsigned *flags, const char *s) { "vfp", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = AV_CPU_FLAG_VFP }, .unit = "flags" }, { "vfpv3", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = AV_CPU_FLAG_VFPV3 }, .unit = "flags" }, { "neon", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = AV_CPU_FLAG_NEON }, .unit = "flags" }, +#elif ARCH_AARCH64 + { "armv8", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = AV_CPU_FLAG_ARMV8 }, .unit = "flags" }, + { "neon", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = AV_CPU_FLAG_NEON }, .unit = "flags" }, + { "vfp", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = AV_CPU_FLAG_VFP }, .unit = "flags" }, #endif { NULL }, }; diff --git a/libavutil/frame.c b/libavutil/frame.c index fdfbc46753..e44ce8e580 100644 --- a/libavutil/frame.c +++ b/libavutil/frame.c @@ -503,6 +503,7 @@ int av_frame_copy_props(AVFrame *dst, const AVFrame *src) free_side_data(&dst->side_data[i]); } av_freep(&dst->side_data); + dst->nb_side_data = 0; return AVERROR(ENOMEM); } memcpy(sd_dst->data, sd_src->data, sd_src->size); diff --git a/libavutil/opt.c b/libavutil/opt.c index 694295dc35..f1c71006b4 100644 --- a/libavutil/opt.c +++ b/libavutil/opt.c @@ -631,7 +631,7 @@ int av_opt_set_channel_layout(void *obj, const char *name, int64_t cl, int searc "The value set by option '%s' is not a channel layout.\n", o->name); return AVERROR(EINVAL); } - *(int *)(((int64_t *)target_obj) + o->offset) = cl; + *(int64_t *)(((uint8_t *)target_obj) + o->offset) = cl; return 0; } @@ -711,6 +711,10 @@ int av_opt_get(void *obj, const char *name, int search_flags, uint8_t **out_val) return AVERROR(EINVAL); if (!(*out_val = av_malloc(len*2 + 1))) return AVERROR(ENOMEM); + if (!len) { + *out_val[0] = '\0'; + return 0; + } bin = *(uint8_t**)dst; for (i = 0; i < len; i++) snprintf(*out_val + i*2, 3, "%02X", bin[i]); @@ -726,12 +730,14 @@ int av_opt_get(void *obj, const char *name, int search_flags, uint8_t **out_val) break; case AV_OPT_TYPE_DURATION: i64 = *(int64_t *)dst; - ret = snprintf(buf, sizeof(buf), "%"PRIi64"d:%02d:%02d.%06d", + ret = snprintf(buf, sizeof(buf), "%"PRIi64":%02d:%02d.%06d", i64 / 3600000000, (int)((i64 / 60000000) % 60), (int)((i64 / 1000000) % 60), (int)(i64 % 1000000)); break; case AV_OPT_TYPE_COLOR: - ret = snprintf(buf, sizeof(buf), "0x%02x%02x%02x%02x", ((int *)dst)[0], ((int *)dst)[1], ((int *)dst)[2], ((int *)dst)[3]); + ret = snprintf(buf, sizeof(buf), "0x%02x%02x%02x%02x", + (int)((uint8_t *)dst)[0], (int)((uint8_t *)dst)[1], + (int)((uint8_t *)dst)[2], (int)((uint8_t *)dst)[3]); break; case AV_OPT_TYPE_CHANNEL_LAYOUT: i64 = *(int64_t *)dst; diff --git a/libavutil/utils.c b/libavutil/utils.c index aafd3b909e..da8b5ae2d3 100644 --- a/libavutil/utils.c +++ b/libavutil/utils.c @@ -27,6 +27,9 @@ * various utility functions */ +#include "libavutil/ffversion.h" +const char av_util_ffversion[] = "FFmpeg version " FFMPEG_VERSION; + unsigned avutil_version(void) { static int checks_done; diff --git a/libavutil/x86/cpu.c b/libavutil/x86/cpu.c index 8ad478400c..2b62e92479 100644 --- a/libavutil/x86/cpu.c +++ b/libavutil/x86/cpu.c @@ -45,7 +45,7 @@ "cpuid \n\t" \ "xchg %%"REG_b", %%"REG_S \ : "=a" (eax), "=S" (ebx), "=c" (ecx), "=d" (edx) \ - : "0" (index)) + : "0" (index), "2"(0)) #define xgetbv(index, eax, edx) \ __asm__ (".byte 0x0f, 0x01, 0xd0" : "=a"(eax), "=d"(edx) : "c" (index)) diff --git a/libpostproc/postprocess.c b/libpostproc/postprocess.c index da586ffd31..f2757acc78 100644 --- a/libpostproc/postprocess.c +++ b/libpostproc/postprocess.c @@ -89,6 +89,9 @@ try to unroll inner for(x=0 ... loop to avoid these damn if(x ... checks #include "postprocess_internal.h" #include "libavutil/avstring.h" +#include "libavutil/ffversion.h" +const char postproc_ffversion[] = "FFmpeg version " FFMPEG_VERSION; + unsigned postproc_version(void) { av_assert0(LIBPOSTPROC_VERSION_MICRO >= 100); @@ -979,7 +982,7 @@ void pp_postprocess(const uint8_t * src[3], const int srcStride[3], if(pict_type & PP_PICT_TYPE_QP2){ int i; - const int count= mbHeight * absQPStride; + const int count= FFMAX(mbHeight * absQPStride, mbWidth); for(i=0; i<(count>>2); i++){ ((uint32_t*)c->stdQPTable)[i] = (((const uint32_t*)QP_store)[i]>>1) & 0x7F7F7F7F; } @@ -1004,7 +1007,7 @@ void pp_postprocess(const uint8_t * src[3], const int srcStride[3], if((pict_type&7)!=3){ if (QPStride >= 0){ int i; - const int count= mbHeight * QPStride; + const int count= FFMAX(mbHeight * QPStride, mbWidth); for(i=0; i<(count>>2); i++){ ((uint32_t*)c->nonBQPTable)[i] = ((const uint32_t*)QP_store)[i] & 0x3F3F3F3F; } diff --git a/libswresample/soxr_resample.c b/libswresample/soxr_resample.c index 064451df45..9e87f2fc4b 100644 --- a/libswresample/soxr_resample.c +++ b/libswresample/soxr_resample.c @@ -76,8 +76,12 @@ static int process( AudioData *src, int src_size, int *consumed){ size_t idone, odone; soxr_error_t error = soxr_set_error((soxr_t)c, soxr_set_num_channels((soxr_t)c, src->ch_count)); - error = soxr_process((soxr_t)c, src->ch, (size_t)src_size, - &idone, dst->ch, (size_t)dst_size, &odone); + if (!error) + error = soxr_process((soxr_t)c, src->ch, (size_t)src_size, + &idone, dst->ch, (size_t)dst_size, &odone); + else + idone = 0; + *consumed = (int)idone; return error? -1 : odone; } diff --git a/libswresample/swresample.c b/libswresample/swresample.c index 91baca62d2..fa09dca01b 100644 --- a/libswresample/swresample.c +++ b/libswresample/swresample.c @@ -28,6 +28,9 @@ #define ALIGN 32 +#include "libavutil/ffversion.h" +const char swr_ffversion[] = "FFmpeg version " FFMPEG_VERSION; + unsigned swresample_version(void) { av_assert0(LIBSWRESAMPLE_VERSION_MICRO >= 100); @@ -639,6 +642,8 @@ int swr_convert(struct SwrContext *s, uint8_t *out_arg[SWR_CH_MAX], int out_coun in_count = 0; if(ret>0) { s->drop_output -= ret; + if (!s->drop_output && !out_arg) + return 0; continue; } diff --git a/libswscale/swscale_internal.h b/libswscale/swscale_internal.h index 8d2d56acb7..7e48a62d98 100644 --- a/libswscale/swscale_internal.h +++ b/libswscale/swscale_internal.h @@ -37,7 +37,7 @@ #define STR(s) AV_TOSTRING(s) // AV_STRINGIFY is too long -#define YUVRGB_TABLE_HEADROOM 128 +#define YUVRGB_TABLE_HEADROOM 256 #define MAX_FILTER_SIZE SWS_MAX_FILTER_SIZE diff --git a/libswscale/x86/rgb2rgb_template.c b/libswscale/x86/rgb2rgb_template.c index 3899d0a842..7be4ab6455 100644 --- a/libswscale/x86/rgb2rgb_template.c +++ b/libswscale/x86/rgb2rgb_template.c @@ -1634,6 +1634,16 @@ static inline void RENAME(rgb24toyv12)(const uint8_t *src, uint8_t *ydst, uint8_ #define BGR2V_IDX "16*4+16*34" int y; const x86_reg chromWidth= width>>1; + + if (height > 2) { + ff_rgb24toyv12_c(src, ydst, udst, vdst, width, 2, lumStride, chromStride, srcStride, rgb2yuv); + src += 2*srcStride; + ydst += 2*lumStride; + udst += chromStride; + vdst += chromStride; + height -= 2; + } + for (y=0; y= 16) { #if COMPILE_TEMPLATE_SSE2 + if (!((((intptr_t)src1) | ((intptr_t)src2) | ((intptr_t)dest))&15)) { __asm__( "xor %%"REG_a", %%"REG_a" \n\t" "1: \n\t" @@ -1896,7 +1908,8 @@ static void RENAME(interleaveBytes)(const uint8_t *src1, const uint8_t *src2, ui ::"r"(dest), "r"(src1), "r"(src2), "r" ((x86_reg)width-15) : "memory", "%"REG_a"" ); -#else + } else +#endif __asm__( "xor %%"REG_a", %%"REG_a" \n\t" "1: \n\t" @@ -1922,7 +1935,8 @@ static void RENAME(interleaveBytes)(const uint8_t *src1, const uint8_t *src2, ui ::"r"(dest), "r"(src1), "r"(src2), "r" ((x86_reg)width-15) : "memory", "%"REG_a ); -#endif + + } for (w= (width&(~15)); w < width; w++) { dest[2*w+0] = src1[w]; dest[2*w+1] = src2[w]; diff --git a/tests/fate.sh b/tests/fate.sh index 38458c748c..5a78018b42 100755 --- a/tests/fate.sh +++ b/tests/fate.sh @@ -19,6 +19,8 @@ test -n "$slot" || die "slot not specified" test -n "$repo" || die "repo not specified" test -d "$samples" || die "samples location not specified" +: ${branch:=master} + lock(){ lock=$1/fate.lock (set -C; exec >$lock) 2>/dev/null || return @@ -28,14 +30,14 @@ lock(){ checkout(){ case "$repo" in file:*|/*) src="${repo#file:}" ;; - git:*) git clone --quiet "$repo" "$src" ;; + git:*) git clone --quiet --branch "$branch" "$repo" "$src" ;; esac } update()( cd ${src} || return case "$repo" in - git:*) git fetch --force && git reset --hard FETCH_HEAD ;; + git:*) git fetch --force && git reset --hard "origin/$branch" ;; esac ) @@ -82,7 +84,9 @@ clean(){ report(){ date=$(date -u +%Y%m%d%H%M%S) echo "fate:0:${date}:${slot}:${version}:$1:$2:${comment}" >report - cat ${build}/config.fate ${build}/tests/data/fate/*.rep >>report +# echo "fate:1:${date}:${slot}:${version}:$1:$2:${branch}:${comment}" >report + cat ${build}/config.fate >>report + cat ${build}/tests/data/fate/*.rep >>report || for i in ${build}/tests/data/fate/*.rep ; do cat "$i" >>report ; done test -n "$fate_recv" && $tar report *.log | gzip | $fate_recv } diff --git a/tests/ref/fate/filter-pp3 b/tests/ref/fate/filter-pp3 index 00d4595f37..c2f2b4cb16 100644 --- a/tests/ref/fate/filter-pp3 +++ b/tests/ref/fate/filter-pp3 @@ -1 +1 @@ -pp3 f38fdc2dfa4c8d889918efe6d7a7ac3a +pp3 ef0f10f1859af2f75717e8c9d64ee38a diff --git a/tests/ref/lavf/mkv b/tests/ref/lavf/mkv index 97c9864bba..edbfe60a00 100644 --- a/tests/ref/lavf/mkv +++ b/tests/ref/lavf/mkv @@ -1,5 +1,5 @@ -bda342503392d517955e1112def7b03a *./tests/data/lavf/lavf.mkv -472671 ./tests/data/lavf/lavf.mkv +bab98f5a04a9f7991fb960041c996478 *./tests/data/lavf/lavf.mkv +472668 ./tests/data/lavf/lavf.mkv ./tests/data/lavf/lavf.mkv CRC=0xec6c3c68 c93950920d4ee57eb3ff5ba0cf0c8b19 *./tests/data/lavf/lavf.mkv 320412 ./tests/data/lavf/lavf.mkv diff --git a/tools/crypto_bench.c b/tools/crypto_bench.c index 1a699ce684..5300380ebe 100644 --- a/tools/crypto_bench.c +++ b/tools/crypto_bench.c @@ -33,6 +33,10 @@ #include "libavutil/intreadwrite.h" #include "libavutil/timer.h" +#ifndef AV_READ_TIME +#define AV_READ_TIME(x) 0 +#endif + #if HAVE_UNISTD_H #include /* for getopt */ #endif diff --git a/version.sh b/version.sh index 92edcb9474..f9754eb3cf 100755 --- a/version.sh +++ b/version.sh @@ -4,7 +4,11 @@ # check for git short hash if ! test "$revision"; then - revision=$(cd "$1" && git describe --tags --match N 2> /dev/null) + if (cd "$1" && grep git RELEASE 2> /dev/null >/dev/null) ; then + revision=$(cd "$1" && git describe --tags --match N 2> /dev/null) + else + revision=$(cd "$1" && git describe --tags --always 2> /dev/null) + fi fi # Shallow Git clones (--depth) do not have the N tag: