diff --git a/MAINTAINERS b/MAINTAINERS index a9a55dfe4a..3ea7c23759 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -14,7 +14,6 @@ patches and related discussions. Project Leader ============== -Michael Niedermayer final design decisions diff --git a/RELEASE b/RELEASE index cd5ac039d6..ebf14b4698 100644 --- a/RELEASE +++ b/RELEASE @@ -1 +1 @@ -2.0 +2.1.8 diff --git a/VERSION b/VERSION new file mode 100644 index 0000000000..ebf14b4698 --- /dev/null +++ b/VERSION @@ -0,0 +1 @@ +2.1.8 diff --git a/cmdutils.c b/cmdutils.c index 1fbd73cf84..ca9bc50020 100644 --- a/cmdutils.c +++ b/cmdutils.c @@ -68,7 +68,7 @@ struct SwsContext *sws_opts; AVDictionary *swr_opts; AVDictionary *format_opts, *codec_opts, *resample_opts; -const int this_year = 2013; +const int this_year = 2015; static FILE *report_file; diff --git a/configure b/configure index 46a9adef37..39b5f6258f 100755 --- a/configure +++ b/configure @@ -105,6 +105,7 @@ Configuration options: --disable-all disable building components, libraries and programs --enable-incompatible-libav-abi enable incompatible Libav fork ABI [no] --enable-incompatible-fork-abi enable incompatible Libav fork ABI (deprecated) [no] + --enable-raise-major increase major version numbers in sonames [no] Program options: --disable-programs do not build command line programs @@ -728,6 +729,10 @@ add_ldflags(){ append LDFLAGS $($ldflags_filter "$@") } +add_stripflags(){ + append ASMSTRIPFLAGS "$@" +} + add_extralibs(){ prepend extralibs $($ldflags_filter "$@") } @@ -885,6 +890,20 @@ check_ldflags(){ test_ldflags "$@" && add_ldflags "$@" } +test_stripflags(){ + log test_stripflags "$@" + # call check_cc to get a fresh TMPO + check_cc <" + echo "#include FT_FREETYPE_H" + echo "long check_func(void) { return (long) FT_Init_FreeType; }" + echo "int main(void) { return 0; }" + } | check_ld "cc" $pkg_cflags $pkg_libs \ + && set_safe ${pkg}_cflags $pkg_cflags \ + && set_safe ${pkg}_libs $pkg_libs \ + || die "ERROR: $pkg not found" + add_cflags $(get_safe ${pkg}_cflags) + add_extralibs $(get_safe ${pkg}_libs) +} + hostcc_o(){ eval printf '%s\\n' $HOSTCC_O } @@ -1280,6 +1319,7 @@ CONFIG_LIST=" network nonfree pic + raise_major rdft runtime_cpudetect safe_bitstream_reader @@ -1426,6 +1466,7 @@ HAVE_LIST=" alsa_asoundlib_h altivec_h arpa_inet_h + as_object_arch asm_mod_q asm_mod_y asm_types_h @@ -1996,6 +2037,7 @@ wmv3_vdpau_hwaccel_select="vc1_vdpau_hwaccel" # parsers h264_parser_select="golomb h264chroma h264dsp h264pred h264qpel videodsp" +hevc_parser_select="hevc_decoder" mpeg4video_parser_select="error_resilience mpegvideo" mpegvideo_parser_select="error_resilience mpegvideo" vc1_parser_select="mpegvideo" @@ -2878,7 +2920,9 @@ probe_cc(){ unset _depflags _DEPCMD _DEPFLAGS _flags_filter=echo - if $_cc -v 2>&1 | grep -q '^gcc.*LLVM'; then + if $_cc --version 2>&1 | grep -q '^GNU assembler'; then + true # no-op to avoid reading stdin in following checks + elif $_cc -v 2>&1 | grep -q '^gcc.*LLVM'; then _type=llvm_gcc gcc_extra_ver=$(expr "$($_cc --version | head -n1)" : '.*\((.*)\)') _ident="llvm-gcc $($_cc -dumpversion) $gcc_extra_ver" @@ -3921,6 +3965,11 @@ EOF [ $target_os != win32 ] && enabled_all armv6t2 shared !pic && enable_weak_pic + # llvm's integrated assembler supports .object_arch from llvm 3.5 + [ "$objformat" = elf ] && check_as <= 2.0.0" aacplus.h aacplusEncOpen -laacplus enabled libass && require_pkg_config libass ass/ass.h ass_library_init -enabled libbluray && require libbluray libbluray/bluray.h bd_open -lbluray +enabled libbluray && require_pkg_config libbluray libbluray/bluray.h bd_open enabled libcelt && require libcelt celt/celt.h celt_decode -lcelt0 && { check_lib celt/celt.h celt_decoder_create_custom -lcelt0 || die "ERROR: libcelt must be installed and version must be >= 0.11.0."; } @@ -4240,7 +4290,7 @@ enabled libfaac && require2 libfaac "stdint.h faac.h" faacEncGetVersio enabled libfdk_aac && require libfdk_aac fdk-aac/aacenc_lib.h aacEncOpen -lfdk-aac flite_libs="-lflite_cmu_time_awb -lflite_cmu_us_awb -lflite_cmu_us_kal -lflite_cmu_us_kal16 -lflite_cmu_us_rms -lflite_cmu_us_slt -lflite_usenglish -lflite_cmulex -lflite" enabled libflite && require2 libflite "flite/flite.h" flite_init $flite_libs -enabled libfreetype && require_pkg_config freetype2 "ft2build.h freetype/freetype.h" FT_Init_FreeType +enabled libfreetype && require_libfreetype enabled libgme && require libgme gme/gme.h gme_new_emu -lgme -lstdc++ enabled libgsm && { for gsm_hdr in "gsm.h" "gsm/gsm.h"; do check_lib "${gsm_hdr}" gsm_create -lgsm && break; @@ -4436,6 +4486,10 @@ check_ldflags -Wl,--warn-common check_ldflags -Wl,-rpath-link=libpostproc:libswresample:libswscale:libavfilter:libavdevice:libavformat:libavcodec:libavutil:libavresample test_ldflags -Wl,-Bsymbolic && append SHFLAGS -Wl,-Bsymbolic +# add some strip flags +# -wN '..@*' is more selective than -x, but not available everywhere. +check_stripflags -wN \'..@*\' || check_stripflags -x + enabled xmm_clobber_test && check_ldflags -Wl,--wrap,avcodec_open2 \ -Wl,--wrap,avcodec_decode_audio4 \ @@ -4786,6 +4840,7 @@ LD_PATH=$LD_PATH DLLTOOL=$dlltool LDFLAGS=$LDFLAGS SHFLAGS=$(echo $($ldflags_filter $SHFLAGS)) +ASMSTRIPFLAGS=$ASMSTRIPFLAGS YASMFLAGS=$YASMFLAGS BUILDSUF=$build_suffix PROGSSUF=$progs_suffix @@ -4849,6 +4904,7 @@ get_version(){ name=$(toupper $lcname) file=$source_path/$lcname/version.h eval $(awk "/#define ${name}_VERSION_M/ { print \$2 \"=\" \$3 }" "$file") + enabled raise_major && eval ${name}_VERSION_MAJOR=$((${name}_VERSION_MAJOR+100)) eval ${name}_VERSION=\$${name}_VERSION_MAJOR.\$${name}_VERSION_MINOR.\$${name}_VERSION_MICRO eval echo "${lcname}_VERSION=\$${name}_VERSION" >> config.mak eval echo "${lcname}_VERSION_MAJOR=\$${name}_VERSION_MAJOR" >> config.mak @@ -4888,6 +4944,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/Doxyfile b/doc/Doxyfile index 6488aadd35..e3305c44a8 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.1.8 # 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/encoders.texi b/doc/encoders.texi index 67f2a39278..143862c861 100644 --- a/doc/encoders.texi +++ b/doc/encoders.texi @@ -786,7 +786,7 @@ Set maximum frame size, or duration of a frame in milliseconds. The argument must be exactly the following: 2.5, 5, 10, 20, 40, 60. Smaller frame sizes achieve lower latency but less quality at a given bitrate. Sizes greater than 20ms are only interesting at fairly low bitrates. -The default of FFmpeg is 10ms, but is 20ms in @command{opusenc}. +The default is 20ms. @item packet_loss (@emph{expect-loss}) Set expected packet loss percentage. The default is 0. diff --git a/doc/filters.texi b/doc/filters.texi index 14692a2148..41b676936b 100644 --- a/doc/filters.texi +++ b/doc/filters.texi @@ -3656,7 +3656,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 @@ -6422,9 +6422,11 @@ The main purpose of setting @option{mp} to a chroma plane is to reduce CPU load and make pullup usable in realtime on slow machines. @end table -For example to inverse telecined NTSC input: +For best results (without duplicated frames in the output file) it is +necessary to change the output frame rate. For example, to inverse +telecine NTSC input: @example -pullup,fps=24000/1001 +ffmpeg -i input -vf pullup -r 24000/1001 ... @end example @section removelogo diff --git a/doc/scaler.texi b/doc/scaler.texi index 08d90bcc81..f043ffd5f2 100644 --- a/doc/scaler.texi +++ b/doc/scaler.texi @@ -35,7 +35,7 @@ Select nearest neighbor rescaling algorithm. @item area Select averaging area rescaling algorithm. -@item bicubiclin +@item bicublin Select bicubic scaling algorithm for the luma component, bilinear for chroma components. diff --git a/doc/utils.texi b/doc/utils.texi index 937713902a..69a612249a 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 001e5c15da..94780f9ffe 100644 --- a/ffmpeg.c +++ b/ffmpeg.c @@ -319,7 +319,7 @@ sigterm_handler(int sig) received_nb_signals++; term_exit(); if(received_nb_signals > 3) - exit_program(123); + exit(123); } void term_init(void) @@ -349,7 +349,6 @@ void term_init(void) signal(SIGQUIT, sigterm_handler); /* Quit (POSIX). */ } #endif - avformat_network_deinit(); signal(SIGINT , sigterm_handler); /* Interrupt (ANSI). */ signal(SIGTERM, sigterm_handler); /* Termination (ANSI). */ @@ -817,10 +816,26 @@ static void do_video_out(AVFormatContext *s, nb_frames = 1; format_video_sync = video_sync_method; - if (format_video_sync == VSYNC_AUTO) + if (format_video_sync == VSYNC_AUTO) { format_video_sync = (s->oformat->flags & AVFMT_VARIABLE_FPS) ? ((s->oformat->flags & AVFMT_NOTIMESTAMPS) ? VSYNC_PASSTHROUGH : VSYNC_VFR) : VSYNC_CFR; + if ( ist + && format_video_sync == VSYNC_CFR + && input_files[ist->file_index]->ctx->nb_streams == 1 + && input_files[ist->file_index]->input_ts_offset == 0) { + format_video_sync = VSYNC_VSCFR; + } + if (format_video_sync == VSYNC_CFR && copy_ts) { + format_video_sync = VSYNC_VSCFR; + } + } switch (format_video_sync) { + case VSYNC_VSCFR: + if (ost->frame_number == 0 && delta - duration >= 0.5) { + av_log(NULL, AV_LOG_DEBUG, "Not duplicating %d initial frames\n", (int)lrintf(delta - duration)); + delta = duration; + ost->sync_opts = lrint(sync_ipts); + } case VSYNC_CFR: // FIXME set to 0.5 after we fix some dts/pts bugs like in avidec.c if (delta < -1.1) @@ -1467,7 +1482,7 @@ static void do_streamcopy(InputStream *ist, OutputStream *ost, const AVPacket *p && ost->st->codec->codec_id != AV_CODEC_ID_MPEG2VIDEO && ost->st->codec->codec_id != AV_CODEC_ID_VC1 ) { - if (av_parser_change(ist->st->parser, ost->st->codec, &opkt.data, &opkt.size, pkt->data, pkt->size, pkt->flags & AV_PKT_FLAG_KEY)) { + if (av_parser_change(av_stream_get_parser(ist->st), ost->st->codec, &opkt.data, &opkt.size, pkt->data, pkt->size, pkt->flags & AV_PKT_FLAG_KEY)) { opkt.buf = av_buffer_create(opkt.data, opkt.size, av_buffer_default_free, NULL, 0); if (!opkt.buf) exit_program(1); @@ -1867,7 +1882,7 @@ static int output_packet(InputStream *ist, const AVPacket *pkt) if (avpkt.duration) { duration = av_rescale_q(avpkt.duration, ist->st->time_base, AV_TIME_BASE_Q); } else if(ist->st->codec->time_base.num != 0 && ist->st->codec->time_base.den != 0) { - int ticks= ist->st->parser ? ist->st->parser->repeat_pict+1 : ist->st->codec->ticks_per_frame; + int ticks= av_stream_get_parser(ist->st) ? av_stream_get_parser(ist->st)->repeat_pict+1 : ist->st->codec->ticks_per_frame; duration = ((int64_t)AV_TIME_BASE * ist->st->codec->time_base.num * ticks) / ist->st->codec->time_base.den; @@ -1924,7 +1939,7 @@ static int output_packet(InputStream *ist, const AVPacket *pkt) } else if (pkt->duration) { ist->next_dts += av_rescale_q(pkt->duration, ist->st->time_base, AV_TIME_BASE_Q); } else if(ist->st->codec->time_base.num != 0) { - int ticks= ist->st->parser ? ist->st->parser->repeat_pict + 1 : ist->st->codec->ticks_per_frame; + int ticks= av_stream_get_parser(ist->st) ? av_stream_get_parser(ist->st)->repeat_pict + 1 : ist->st->codec->ticks_per_frame; ist->next_dts += ((int64_t)AV_TIME_BASE * ist->st->codec->time_base.num * ticks) / ist->st->codec->time_base.den; @@ -2101,7 +2116,7 @@ static int transcode_init(void) AVCodecContext *codec; OutputStream *ost; InputStream *ist; - char error[1024]; + char error[1024] = {0}; int want_sdp = 1; for (i = 0; i < nb_filtergraphs; i++) { @@ -2357,7 +2372,7 @@ static int transcode_init(void) if (ost->filter && !(codec->time_base.num && codec->time_base.den)) codec->time_base = ost->filter->filter->inputs[0]->time_base; if ( av_q2d(codec->time_base) < 0.001 && video_sync_method != VSYNC_PASSTHROUGH - && (video_sync_method == VSYNC_CFR || (video_sync_method == VSYNC_AUTO && !(oc->oformat->flags & AVFMT_VARIABLE_FPS)))){ + && (video_sync_method == VSYNC_CFR || video_sync_method == VSYNC_VSCFR || (video_sync_method == VSYNC_AUTO && !(oc->oformat->flags & AVFMT_VARIABLE_FPS)))){ av_log(oc, AV_LOG_WARNING, "Frame rate very high for a muxer not efficiently supporting it.\n" "Please consider specifying a lower framerate, a different muxer or -vsync 2\n"); } diff --git a/ffmpeg.h b/ffmpeg.h index 054e71814d..1471739107 100644 --- a/ffmpeg.h +++ b/ffmpeg.h @@ -51,6 +51,7 @@ #define VSYNC_PASSTHROUGH 0 #define VSYNC_CFR 1 #define VSYNC_VFR 2 +#define VSYNC_VSCFR 0xfe #define VSYNC_DROP 0xff #define MAX_STREAMS 1024 /* arbitrary sanity check value */ @@ -281,6 +282,7 @@ typedef struct InputFile { int eof_reached; /* true if eof reached */ int eagain; /* true if last read attempt returned EAGAIN */ int ist_index; /* index of first stream in input_streams */ + int64_t input_ts_offset; int64_t ts_offset; int64_t last_ts; int64_t start_time; /* user-specified start time in AV_TIME_BASE or AV_NOPTS_VALUE */ diff --git a/ffmpeg_filter.c b/ffmpeg_filter.c index 461cc900fe..a33f0d497f 100644 --- a/ffmpeg_filter.c +++ b/ffmpeg_filter.c @@ -42,12 +42,15 @@ enum AVPixelFormat choose_pixel_fmt(AVStream *st, AVCodec *codec, enum AVPixelFo const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(target); int has_alpha = desc ? desc->nb_components % 2 == 0 : 0; enum AVPixelFormat best= AV_PIX_FMT_NONE; + const enum AVPixelFormat mjpeg_formats[] = { AV_PIX_FMT_YUVJ420P, AV_PIX_FMT_YUVJ422P, AV_PIX_FMT_YUV420P, AV_PIX_FMT_YUV422P, AV_PIX_FMT_NONE }; + const enum AVPixelFormat ljpeg_formats[] = { AV_PIX_FMT_YUVJ420P, AV_PIX_FMT_YUVJ422P, AV_PIX_FMT_YUVJ444P, AV_PIX_FMT_YUV420P, + AV_PIX_FMT_YUV422P, AV_PIX_FMT_YUV444P, AV_PIX_FMT_BGRA, AV_PIX_FMT_NONE }; + if (st->codec->strict_std_compliance <= FF_COMPLIANCE_UNOFFICIAL) { if (st->codec->codec_id == AV_CODEC_ID_MJPEG) { - p = (const enum AVPixelFormat[]) { AV_PIX_FMT_YUVJ420P, AV_PIX_FMT_YUVJ422P, AV_PIX_FMT_YUV420P, AV_PIX_FMT_YUV422P, AV_PIX_FMT_NONE }; + p = mjpeg_formats; } else if (st->codec->codec_id == AV_CODEC_ID_LJPEG) { - p = (const enum AVPixelFormat[]) { AV_PIX_FMT_YUVJ420P, AV_PIX_FMT_YUVJ422P, AV_PIX_FMT_YUVJ444P, AV_PIX_FMT_YUV420P, - AV_PIX_FMT_YUV422P, AV_PIX_FMT_YUV444P, AV_PIX_FMT_BGRA, AV_PIX_FMT_NONE }; + p =ljpeg_formats; } } for (; *p != AV_PIX_FMT_NONE; p++) { diff --git a/ffmpeg_opt.c b/ffmpeg_opt.c index c9283d69fa..3c80a248c1 100644 --- a/ffmpeg_opt.c +++ b/ffmpeg_opt.c @@ -852,6 +852,7 @@ static int open_input_file(OptionsContext *o, const char *filename) f->ist_index = nb_input_streams - ic->nb_streams; f->start_time = o->start_time; f->recording_time = o->recording_time; + f->input_ts_offset = o->input_ts_offset; f->ts_offset = o->input_ts_offset - (copy_ts ? 0 : timestamp); f->nb_streams = ic->nb_streams; f->rate_emu = o->rate_emu; @@ -1689,7 +1690,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++) { @@ -1711,7 +1712,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]; @@ -1727,7 +1728,7 @@ static int open_output_file(OptionsContext *o, const char *filename) /* subtitles: pick first */ MATCH_PER_TYPE_OPT(codec_names, str, subtitle_codec_name, oc, "s"); - if (!o->subtitle_disable && (oc->oformat->subtitle_codec != AV_CODEC_ID_NONE || subtitle_codec_name)) { + if (!o->subtitle_disable && (avcodec_find_encoder(oc->oformat->subtitle_codec) || subtitle_codec_name)) { for (i = 0; i < nb_input_streams; i++) if (input_streams[i]->st->codec->codec_type == AVMEDIA_TYPE_SUBTITLE) { new_subtitle_stream(o, oc, i); diff --git a/ffprobe.c b/ffprobe.c index 80a286b20a..ba11060ccf 100644 --- a/ffprobe.c +++ b/ffprobe.c @@ -183,6 +183,7 @@ static const char unit_hertz_str[] = "Hz" ; static const char unit_byte_str[] = "byte" ; static const char unit_bit_per_second_str[] = "bit/s"; +static int nb_streams; static uint64_t *nb_streams_packets; static uint64_t *nb_streams_frames; static int *selected_streams; @@ -238,6 +239,7 @@ static char *value_string(char *buf, int buf_size, struct unit_value uv) vald /= pow(10, index * 3); prefix_string = decimal_unit_prefixes[index]; } + vali = vald; } if (show_float || (use_value_prefix && vald != (long long int)vald)) @@ -1455,6 +1457,14 @@ static void writer_register_all(void) #define print_section_header(s) writer_print_section_header(w, s) #define print_section_footer(s) writer_print_section_footer(w, s) +#define REALLOCZ_ARRAY_STREAM(ptr, cur_n, new_n) \ +{ \ + ret = av_reallocp_array(&(ptr), (new_n), sizeof(*(ptr))); \ + if (ret < 0) \ + goto end; \ + memset( (ptr) + (cur_n), 0, ((new_n) - (cur_n)) * sizeof(*(ptr)) ); \ +} + static inline void show_tags(WriterContext *wctx, AVDictionary *tags, int section_id) { AVDictionaryEntry *tag = NULL; @@ -1580,7 +1590,6 @@ static av_always_inline int process_frame(WriterContext *w, AVCodecContext *dec_ctx = fmt_ctx->streams[pkt->stream_index]->codec; int ret = 0, got_frame = 0; - avcodec_get_frame_defaults(frame); if (dec_ctx->codec) { switch (dec_ctx->codec_type) { case AVMEDIA_TYPE_VIDEO: @@ -1634,7 +1643,7 @@ static int read_interval_packets(WriterContext *w, AVFormatContext *fmt_ctx, const ReadInterval *interval, int64_t *cur_ts) { AVPacket pkt, pkt1; - AVFrame frame; + AVFrame *frame = NULL; int ret = 0, i = 0, frame_count = 0; int64_t start = -INT64_MAX, end = interval->end; int has_start = 0, has_end = interval->has_end && !interval->end_is_offset; @@ -1668,7 +1677,18 @@ static int read_interval_packets(WriterContext *w, AVFormatContext *fmt_ctx, } } + frame = av_frame_alloc(); + if (!frame) { + ret = AVERROR(ENOMEM); + goto end; + } while (!av_read_frame(fmt_ctx, &pkt)) { + if (fmt_ctx->nb_streams > nb_streams) { + REALLOCZ_ARRAY_STREAM(nb_streams_frames, nb_streams, fmt_ctx->nb_streams); + REALLOCZ_ARRAY_STREAM(nb_streams_packets, nb_streams, fmt_ctx->nb_streams); + REALLOCZ_ARRAY_STREAM(selected_streams, nb_streams, fmt_ctx->nb_streams); + nb_streams = fmt_ctx->nb_streams; + } if (selected_streams[pkt.stream_index]) { AVRational tb = fmt_ctx->streams[pkt.stream_index]->time_base; @@ -1700,7 +1720,7 @@ static int read_interval_packets(WriterContext *w, AVFormatContext *fmt_ctx, } if (do_read_frames) { pkt1 = pkt; - while (pkt1.size && process_frame(w, fmt_ctx, &frame, &pkt1) > 0); + while (pkt1.size && process_frame(w, fmt_ctx, frame, &pkt1) > 0); } } av_free_packet(&pkt); @@ -1712,10 +1732,11 @@ static int read_interval_packets(WriterContext *w, AVFormatContext *fmt_ctx, for (i = 0; i < fmt_ctx->nb_streams; i++) { pkt.stream_index = i; if (do_read_frames) - while (process_frame(w, fmt_ctx, &frame, &pkt) > 0); + while (process_frame(w, fmt_ctx, frame, &pkt) > 0); } end: + av_frame_free(&frame); if (ret < 0) { av_log(NULL, AV_LOG_ERROR, "Could not read packets in interval "); log_read_interval(interval, NULL, AV_LOG_ERROR); @@ -2111,9 +2132,10 @@ static int probe_file(WriterContext *wctx, const char *filename) if (ret < 0) return ret; - nb_streams_frames = av_calloc(fmt_ctx->nb_streams, sizeof(*nb_streams_frames)); - nb_streams_packets = av_calloc(fmt_ctx->nb_streams, sizeof(*nb_streams_packets)); - selected_streams = av_calloc(fmt_ctx->nb_streams, sizeof(*selected_streams)); + nb_streams = fmt_ctx->nb_streams; + REALLOCZ_ARRAY_STREAM(nb_streams_frames,0,fmt_ctx->nb_streams); + REALLOCZ_ARRAY_STREAM(nb_streams_packets,0,fmt_ctx->nb_streams); + REALLOCZ_ARRAY_STREAM(selected_streams,0,fmt_ctx->nb_streams); for (i = 0; i < fmt_ctx->nb_streams; i++) { if (stream_specifier) { diff --git a/ffserver.c b/ffserver.c index 5ecdb08d38..44f843eb4b 100644 --- a/ffserver.c +++ b/ffserver.c @@ -2972,6 +2972,8 @@ static int prepare_sdp_description(FFStream *stream, uint8_t **pbuffer, AVOutputFormat *rtp_format = av_guess_format("rtp", NULL, NULL); int i; + *pbuffer = NULL; + avc = avformat_alloc_context(); if (avc == NULL || !rtp_format) { return -1; @@ -3008,7 +3010,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/012v.c b/libavcodec/012v.c index c2b6a35041..b87551e0a5 100644 --- a/libavcodec/012v.c +++ b/libavcodec/012v.c @@ -38,15 +38,15 @@ static av_cold int zero12v_decode_init(AVCodecContext *avctx) static int zero12v_decode_frame(AVCodecContext *avctx, void *data, int *got_frame, AVPacket *avpkt) { - int line = 0, ret; + int line, ret; const int width = avctx->width; AVFrame *pic = data; uint16_t *y, *u, *v; const uint8_t *line_end, *src = avpkt->data; int stride = avctx->width * 8 / 3; - if (width == 1) { - av_log(avctx, AV_LOG_ERROR, "Width 1 not supported.\n"); + if (width <= 1 || avctx->height <= 0) { + av_log(avctx, AV_LOG_ERROR, "Dimensions %dx%d not supported.\n", width, avctx->height); return AVERROR_INVALIDDATA; } @@ -67,45 +67,45 @@ static int zero12v_decode_frame(AVCodecContext *avctx, void *data, pic->pict_type = AV_PICTURE_TYPE_I; pic->key_frame = 1; - y = (uint16_t *)pic->data[0]; - u = (uint16_t *)pic->data[1]; - v = (uint16_t *)pic->data[2]; line_end = avpkt->data + stride; + for (line = 0; line < avctx->height; line++) { + uint16_t y_temp[6] = {0x8000, 0x8000, 0x8000, 0x8000, 0x8000, 0x8000}; + uint16_t u_temp[3] = {0x8000, 0x8000, 0x8000}; + uint16_t v_temp[3] = {0x8000, 0x8000, 0x8000}; + int x; + y = (uint16_t *)(pic->data[0] + line * pic->linesize[0]); + u = (uint16_t *)(pic->data[1] + line * pic->linesize[1]); + v = (uint16_t *)(pic->data[2] + line * pic->linesize[2]); - while (line++ < avctx->height) { - while (1) { - uint32_t t = AV_RL32(src); + for (x = 0; x < width; x += 6) { + uint32_t t; + + if (width - x < 6 || line_end - src < 16) { + y = y_temp; + u = u_temp; + v = v_temp; + } + + if (line_end - src < 4) + break; + + t = AV_RL32(src); src += 4; *u++ = t << 6 & 0xFFC0; *y++ = t >> 4 & 0xFFC0; *v++ = t >> 14 & 0xFFC0; - if (src >= line_end - 1) { - *y = 0x80; - src++; - line_end += stride; - y = (uint16_t *)(pic->data[0] + line * pic->linesize[0]); - u = (uint16_t *)(pic->data[1] + line * pic->linesize[1]); - v = (uint16_t *)(pic->data[2] + line * pic->linesize[2]); + if (line_end - src < 4) break; - } t = AV_RL32(src); src += 4; *y++ = t << 6 & 0xFFC0; *u++ = t >> 4 & 0xFFC0; *y++ = t >> 14 & 0xFFC0; - if (src >= line_end - 2) { - if (!(width & 1)) { - *y = 0x80; - src += 2; - } - line_end += stride; - y = (uint16_t *)(pic->data[0] + line * pic->linesize[0]); - u = (uint16_t *)(pic->data[1] + line * pic->linesize[1]); - v = (uint16_t *)(pic->data[2] + line * pic->linesize[2]); + + if (line_end - src < 4) break; - } t = AV_RL32(src); src += 4; @@ -113,15 +113,8 @@ static int zero12v_decode_frame(AVCodecContext *avctx, void *data, *y++ = t >> 4 & 0xFFC0; *u++ = t >> 14 & 0xFFC0; - if (src >= line_end - 1) { - *y = 0x80; - src++; - line_end += stride; - y = (uint16_t *)(pic->data[0] + line * pic->linesize[0]); - u = (uint16_t *)(pic->data[1] + line * pic->linesize[1]); - v = (uint16_t *)(pic->data[2] + line * pic->linesize[2]); + if (line_end - src < 4) break; - } t = AV_RL32(src); src += 4; @@ -129,18 +122,21 @@ static int zero12v_decode_frame(AVCodecContext *avctx, void *data, *v++ = t >> 4 & 0xFFC0; *y++ = t >> 14 & 0xFFC0; - if (src >= line_end - 2) { - if (width & 1) { - *y = 0x80; - src += 2; - } - line_end += stride; - y = (uint16_t *)(pic->data[0] + line * pic->linesize[0]); - u = (uint16_t *)(pic->data[1] + line * pic->linesize[1]); - v = (uint16_t *)(pic->data[2] + line * pic->linesize[2]); + if (width - x < 6) break; - } } + + if (x < width) { + y = x + (uint16_t *)(pic->data[0] + line * pic->linesize[0]); + u = x/2 + (uint16_t *)(pic->data[1] + line * pic->linesize[1]); + v = x/2 + (uint16_t *)(pic->data[2] + line * pic->linesize[2]); + memcpy(y, y_temp, sizeof(*y) * (width - x)); + memcpy(u, u_temp, sizeof(*u) * (width - x + 1) / 2); + memcpy(v, v_temp, sizeof(*v) * (width - x + 1) / 2); + } + + line_end += stride; + src = line_end - stride; } *got_frame = 1; diff --git a/libavcodec/Makefile b/libavcodec/Makefile index d46c5462a5..f60f752b75 100644 --- a/libavcodec/Makefile +++ b/libavcodec/Makefile @@ -331,22 +331,22 @@ OBJS-$(CONFIG_NUV_DECODER) += nuv.o rtjpeg.o OBJS-$(CONFIG_PAF_VIDEO_DECODER) += paf.o OBJS-$(CONFIG_PAF_AUDIO_DECODER) += paf.o OBJS-$(CONFIG_PAM_DECODER) += pnmdec.o pnm.o -OBJS-$(CONFIG_PAM_ENCODER) += pamenc.o pnm.o +OBJS-$(CONFIG_PAM_ENCODER) += pamenc.o OBJS-$(CONFIG_PBM_DECODER) += pnmdec.o pnm.o -OBJS-$(CONFIG_PBM_ENCODER) += pnmenc.o pnm.o +OBJS-$(CONFIG_PBM_ENCODER) += pnmenc.o OBJS-$(CONFIG_PCX_DECODER) += pcx.o OBJS-$(CONFIG_PCX_ENCODER) += pcxenc.o OBJS-$(CONFIG_PGM_DECODER) += pnmdec.o pnm.o -OBJS-$(CONFIG_PGM_ENCODER) += pnmenc.o pnm.o +OBJS-$(CONFIG_PGM_ENCODER) += pnmenc.o OBJS-$(CONFIG_PGMYUV_DECODER) += pnmdec.o pnm.o -OBJS-$(CONFIG_PGMYUV_ENCODER) += pnmenc.o pnm.o +OBJS-$(CONFIG_PGMYUV_ENCODER) += pnmenc.o OBJS-$(CONFIG_PGSSUB_DECODER) += pgssubdec.o OBJS-$(CONFIG_PICTOR_DECODER) += pictordec.o cga_data.o OBJS-$(CONFIG_PJS_DECODER) += textdec.o ass.o OBJS-$(CONFIG_PNG_DECODER) += png.o pngdec.o pngdsp.o OBJS-$(CONFIG_PNG_ENCODER) += png.o pngenc.o OBJS-$(CONFIG_PPM_DECODER) += pnmdec.o pnm.o -OBJS-$(CONFIG_PPM_ENCODER) += pnmenc.o pnm.o +OBJS-$(CONFIG_PPM_ENCODER) += pnmenc.o OBJS-$(CONFIG_PRORES_DECODER) += proresdec2.o proresdsp.o proresdata.o OBJS-$(CONFIG_PRORES_LGPL_DECODER) += proresdec_lgpl.o proresdsp.o proresdata.o OBJS-$(CONFIG_PRORES_ENCODER) += proresenc_anatoliy.o diff --git a/libavcodec/a64multienc.c b/libavcodec/a64multienc.c index e5c0fa782f..1bdb662759 100644 --- a/libavcodec/a64multienc.c +++ b/libavcodec/a64multienc.c @@ -40,9 +40,6 @@ #define C64YRES 200 typedef struct A64Context { - /* general variables */ - AVFrame picture; - /* variables for multicolor modes */ AVLFG randctx; int mc_lifetime; @@ -81,9 +78,13 @@ static void to_meta_with_crop(AVCodecContext *avctx, AVFrame *p, int *dest) for (y = blocky; y < blocky + 8 && y < C64YRES; y++) { for (x = blockx; x < blockx + 8 && x < C64XRES; x += 2) { if(x < width && y < height) { - /* build average over 2 pixels */ - luma = (src[(x + 0 + y * p->linesize[0])] + - src[(x + 1 + y * p->linesize[0])]) / 2; + if (x + 1 < width) { + /* build average over 2 pixels */ + luma = (src[(x + 0 + y * p->linesize[0])] + + src[(x + 1 + y * p->linesize[0])]) / 2; + } else { + luma = src[(x + y * p->linesize[0])]; + } /* write blocks as linear data now so they are suitable for elbg */ dest[0] = luma; } @@ -189,6 +190,7 @@ static void render_charset(AVCodecContext *avctx, uint8_t *charset, static av_cold int a64multi_close_encoder(AVCodecContext *avctx) { A64Context *c = avctx->priv_data; + av_frame_free(&avctx->coded_frame); av_free(c->mc_meta_charset); av_free(c->mc_best_cb); av_free(c->mc_charset); @@ -240,8 +242,12 @@ static av_cold int a64multi_init_encoder(AVCodecContext *avctx) AV_WB32(avctx->extradata, c->mc_lifetime); AV_WB32(avctx->extradata + 16, INTERLACED); - avcodec_get_frame_defaults(&c->picture); - avctx->coded_frame = &c->picture; + avctx->coded_frame = av_frame_alloc(); + if (!avctx->coded_frame) { + a64multi_close_encoder(avctx); + return AVERROR(ENOMEM); + } + avctx->coded_frame->pict_type = AV_PICTURE_TYPE_I; avctx->coded_frame->key_frame = 1; if (!avctx->codec_tag) @@ -271,7 +277,7 @@ static int a64multi_encode_frame(AVCodecContext *avctx, AVPacket *pkt, const AVFrame *pict, int *got_packet) { A64Context *c = avctx->priv_data; - AVFrame *const p = &c->picture; + AVFrame *const p = avctx->coded_frame; int frame; int x, y; @@ -315,7 +321,9 @@ static int a64multi_encode_frame(AVCodecContext *avctx, AVPacket *pkt, } else { /* fill up mc_meta_charset with data until lifetime exceeds */ if (c->mc_frame_counter < c->mc_lifetime) { - *p = *pict; + ret = av_frame_ref(p, pict); + if (ret < 0) + return ret; p->pict_type = AV_PICTURE_TYPE_I; p->key_frame = 1; to_meta_with_crop(avctx, p, meta + 32000 * c->mc_frame_counter); @@ -332,8 +340,8 @@ static int a64multi_encode_frame(AVCodecContext *avctx, AVPacket *pkt, req_size = 0; /* any frames to encode? */ if (c->mc_lifetime) { - req_size = charset_size + c->mc_lifetime*(screen_size + colram_size); - if ((ret = ff_alloc_packet2(avctx, pkt, req_size)) < 0) + int alloc_size = charset_size + c->mc_lifetime*(screen_size + colram_size); + if ((ret = ff_alloc_packet2(avctx, pkt, alloc_size)) < 0) return ret; buf = pkt->data; @@ -350,6 +358,7 @@ static int a64multi_encode_frame(AVCodecContext *avctx, AVPacket *pkt, /* advance pointers */ buf += charset_size; charset += charset_size; + req_size += charset_size; } /* write x frames to buf */ diff --git a/libavcodec/aac.h b/libavcodec/aac.h index 89f463e341..1bcd95c7ad 100644 --- a/libavcodec/aac.h +++ b/libavcodec/aac.h @@ -81,7 +81,7 @@ enum BandType { INTENSITY_BT = 15, ///< Scalefactor data are intensity stereo positions. }; -#define IS_CODEBOOK_UNSIGNED(x) ((x - 1) & 10) +#define IS_CODEBOOK_UNSIGNED(x) (((x) - 1) & 10) enum ChannelPosition { AAC_CHANNEL_OFF = 0, 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/aacdec.c b/libavcodec/aacdec.c index eb6ee5e331..2feb4af9cc 100644 --- a/libavcodec/aacdec.c +++ b/libavcodec/aacdec.c @@ -194,6 +194,9 @@ static int frame_configure_elements(AVCodecContext *avctx) /* get output buffer */ av_frame_unref(ac->frame); + if (!avctx->channels) + return 1; + ac->frame->nb_samples = 2048; if ((ret = ff_get_buffer(avctx, ac->frame, 0)) < 0) return ret; @@ -420,7 +423,7 @@ static uint64_t sniff_channel_order(uint8_t (*layout_map)[3], int tags) * Save current output configuration if and only if it has been locked. */ static void push_output_configuration(AACContext *ac) { - if (ac->oc[1].status == OC_LOCKED) { + if (ac->oc[1].status == OC_LOCKED || ac->oc[0].status == OC_NONE) { ac->oc[0] = ac->oc[1]; } ac->oc[1].status = OC_NONE; @@ -857,7 +860,7 @@ static int decode_eld_specific_config(AACContext *ac, AVCodecContext *avctx, if (len == 15 + 255) len += get_bits(gb, 16); if (get_bits_left(gb) < len * 8 + 4) { - av_log(ac->avctx, AV_LOG_ERROR, overread_err); + av_log(avctx, AV_LOG_ERROR, overread_err); return AVERROR_INVALIDDATA; } skip_bits_long(gb, 8 * len); @@ -1402,12 +1405,12 @@ static int decode_pulses(Pulse *pulse, GetBitContext *gb, return -1; pulse->pos[0] = swb_offset[pulse_swb]; pulse->pos[0] += get_bits(gb, 5); - if (pulse->pos[0] > 1023) + if (pulse->pos[0] >= swb_offset[num_swb]) return -1; pulse->amp[0] = get_bits(gb, 4); for (i = 1; i < pulse->num_pulse; i++) { pulse->pos[i] = get_bits(gb, 5) + pulse->pos[i - 1]; - if (pulse->pos[i] > 1023) + if (pulse->pos[i] >= swb_offset[num_swb]) return -1; pulse->amp[i] = get_bits(gb, 4); } diff --git a/libavcodec/aacenc.c b/libavcodec/aacenc.c index 5596b4bfad..24de94f327 100644 --- a/libavcodec/aacenc.c +++ b/libavcodec/aacenc.c @@ -165,7 +165,7 @@ static void put_audio_specific_config(AVCodecContext *avctx) PutBitContext pb; AACEncContext *s = avctx->priv_data; - init_put_bits(&pb, avctx->extradata, avctx->extradata_size*8); + init_put_bits(&pb, avctx->extradata, avctx->extradata_size); put_bits(&pb, 5, 2); //object type - AAC-LC put_bits(&pb, 4, s->samplerate_index); //sample rate index put_bits(&pb, 4, s->channels); diff --git a/libavcodec/aacpsy.c b/libavcodec/aacpsy.c index d2a782e8dd..a1183bea3f 100644 --- a/libavcodec/aacpsy.c +++ b/libavcodec/aacpsy.c @@ -727,7 +727,10 @@ static void psy_3gpp_analyze_channel(FFPsyContext *ctx, int channel, if (active_lines > 0.0f) band->thr = calc_reduced_thr_3gpp(band, coeffs[g].min_snr, reduction); pe += calc_pe_3gpp(band); - band->norm_fac = band->active_lines / band->thr; + if (band->thr > 0.0f) + band->norm_fac = band->active_lines / band->thr; + else + band->norm_fac = 0.0f; norm_fac += band->norm_fac; } } diff --git a/libavcodec/aasc.c b/libavcodec/aasc.c index 38658f86c4..a23f9b3ec3 100644 --- a/libavcodec/aasc.c +++ b/libavcodec/aasc.c @@ -137,7 +137,7 @@ static int aasc_decode_frame(AVCodecContext *avctx, return ret; /* report that the buffer was completely consumed */ - return buf_size; + return avpkt->size; } static av_cold int aasc_decode_end(AVCodecContext *avctx) diff --git a/libavcodec/ac3.c b/libavcodec/ac3.c index 29e132f5d1..8d39bbe83b 100644 --- a/libavcodec/ac3.c +++ b/libavcodec/ac3.c @@ -131,6 +131,9 @@ int ff_ac3_bit_alloc_calc_mask(AC3BitAllocParameters *s, int16_t *band_psd, int band_start, band_end, begin, end1; int lowcomp, fastleak, slowleak; + if (end <= 0) + return AVERROR_INVALIDDATA; + /* excitation function */ band_start = ff_ac3_bin_to_band_tab[start]; band_end = ff_ac3_bin_to_band_tab[end-1] + 1; diff --git a/libavcodec/ac3_parser.c b/libavcodec/ac3_parser.c index 8dc4c0d480..acfbc2ea66 100644 --- a/libavcodec/ac3_parser.c +++ b/libavcodec/ac3_parser.c @@ -147,7 +147,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; GetBitContext gbc; diff --git a/libavcodec/ac3dec.c b/libavcodec/ac3dec.c index f91ded0fcb..2acd20949c 100644 --- a/libavcodec/ac3dec.c +++ b/libavcodec/ac3dec.c @@ -488,6 +488,10 @@ static void ac3_decode_transform_coeffs_ch(AC3DecodeContext *s, int ch_index, ma break; default: /* 6 to 15 */ /* Shift mantissa and sign-extend it. */ + if (bap > 15) { + av_log(s->avctx, AV_LOG_ERROR, "bap %d is invalid in plain AC-3\n", bap); + bap = 15; + } mantissa = get_sbits(gbc, quantization_tab[bap]); mantissa <<= 24 - quantization_tab[bap]; break; diff --git a/libavcodec/ac3enc_template.c b/libavcodec/ac3enc_template.c index 354be53c7f..69dd135898 100644 --- a/libavcodec/ac3enc_template.c +++ b/libavcodec/ac3enc_template.c @@ -260,7 +260,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/adpcm.c b/libavcodec/adpcm.c index 8e20de2a63..8e67541916 100644 --- a/libavcodec/adpcm.c +++ b/libavcodec/adpcm.c @@ -471,9 +471,11 @@ static void adpcm_swf_decode(AVCodecContext *avctx, const uint8_t *buf, int buf_ * @param[out] coded_samples set to the number of samples as coded in the * packet, or 0 if the codec does not encode the * number of samples in each frame. + * @param[out] approx_nb_samples set to non-zero if the number of samples + * returned is an approximation. */ static int get_nb_samples(AVCodecContext *avctx, GetByteContext *gb, - int buf_size, int *coded_samples) + int buf_size, int *coded_samples, int *approx_nb_samples) { ADPCMDecodeContext *s = avctx->priv_data; int nb_samples = 0; @@ -482,6 +484,7 @@ static int get_nb_samples(AVCodecContext *avctx, GetByteContext *gb, int header_size; *coded_samples = 0; + *approx_nb_samples = 0; if(ch <= 0) return 0; @@ -552,10 +555,12 @@ static int get_nb_samples(AVCodecContext *avctx, GetByteContext *gb, case AV_CODEC_ID_ADPCM_EA_R2: header_size = 4 + 5 * ch; *coded_samples = bytestream2_get_le32(gb); + *approx_nb_samples = 1; break; case AV_CODEC_ID_ADPCM_EA_R3: header_size = 4 + 5 * ch; *coded_samples = bytestream2_get_be32(gb); + *approx_nb_samples = 1; break; } *coded_samples -= *coded_samples % 28; @@ -663,11 +668,11 @@ static int adpcm_decode_frame(AVCodecContext *avctx, void *data, int16_t **samples_p; int st; /* stereo */ int count1, count2; - int nb_samples, coded_samples, ret; + int nb_samples, coded_samples, approx_nb_samples, ret; GetByteContext gb; bytestream2_init(&gb, buf, buf_size); - nb_samples = get_nb_samples(avctx, &gb, buf_size, &coded_samples); + nb_samples = get_nb_samples(avctx, &gb, buf_size, &coded_samples, &approx_nb_samples); if (nb_samples <= 0) { av_log(avctx, AV_LOG_ERROR, "invalid number of samples in packet\n"); return AVERROR_INVALIDDATA; @@ -683,7 +688,7 @@ static int adpcm_decode_frame(AVCodecContext *avctx, void *data, /* use coded_samples when applicable */ /* it is always <= nb_samples, so the output buffer will be large enough */ if (coded_samples) { - if (coded_samples != nb_samples) + if (!approx_nb_samples && coded_samples != nb_samples) av_log(avctx, AV_LOG_WARNING, "mismatch in coded sample count\n"); frame->nb_samples = nb_samples = coded_samples; } @@ -917,6 +922,9 @@ static int adpcm_decode_frame(AVCodecContext *avctx, void *data, *samples++ = c->status[0].predictor + c->status[1].predictor; *samples++ = c->status[0].predictor - c->status[1].predictor; } + + if ((bytestream2_tell(&gb) & 1)) + bytestream2_skip(&gb, 1); break; } case AV_CODEC_ID_ADPCM_IMA_ISS: diff --git a/libavcodec/adpcmenc.c b/libavcodec/adpcmenc.c index 5391570de7..e0737e221f 100644 --- a/libavcodec/adpcmenc.c +++ b/libavcodec/adpcmenc.c @@ -541,7 +541,7 @@ static int adpcm_encode_frame(AVCodecContext *avctx, AVPacket *avpkt, case AV_CODEC_ID_ADPCM_IMA_QT: { PutBitContext pb; - init_put_bits(&pb, dst, pkt_size * 8); + init_put_bits(&pb, dst, pkt_size); for (ch = 0; ch < avctx->channels; ch++) { ADPCMChannelStatus *status = &c->status[ch]; @@ -549,10 +549,11 @@ static int adpcm_encode_frame(AVCodecContext *avctx, AVPacket *avpkt, put_bits(&pb, 7, status->step_index); if (avctx->trellis > 0) { uint8_t buf[64]; - adpcm_compress_trellis(avctx, &samples_p[ch][1], buf, status, + adpcm_compress_trellis(avctx, &samples_p[ch][0], buf, status, 64, 1); for (i = 0; i < 64; i++) put_bits(&pb, 4, buf[i ^ 1]); + status->prev_sample = status->predictor; } else { for (i = 0; i < 64; i += 2) { int t1, t2; @@ -570,7 +571,7 @@ static int adpcm_encode_frame(AVCodecContext *avctx, AVPacket *avpkt, case AV_CODEC_ID_ADPCM_SWF: { PutBitContext pb; - init_put_bits(&pb, dst, pkt_size * 8); + init_put_bits(&pb, dst, pkt_size); n = frame->nb_samples - 1; diff --git a/libavcodec/aic.c b/libavcodec/aic.c index a7e3691aa0..674f230875 100644 --- a/libavcodec/aic.c +++ b/libavcodec/aic.c @@ -150,6 +150,7 @@ typedef struct AICContext { int16_t *data_ptr[NUM_BANDS]; DECLARE_ALIGNED(16, int16_t, block)[64]; + DECLARE_ALIGNED(16, uint8_t, quant_matrix)[64]; } AICContext; static int aic_decode_header(AICContext *ctx, const uint8_t *src, int size) @@ -285,7 +286,7 @@ static void recombine_block_il(int16_t *dst, const uint8_t *scan, } } -static void unquant_block(int16_t *block, int q) +static void unquant_block(int16_t *block, int q, uint8_t *quant_matrix) { int i; @@ -293,7 +294,7 @@ static void unquant_block(int16_t *block, int q) int val = (uint16_t)block[i]; int sign = val & 1; - block[i] = (((val >> 1) ^ -sign) * q * aic_quant_matrix[i] >> 4) + block[i] = (((val >> 1) ^ -sign) * q * quant_matrix[i] >> 4) + sign; } } @@ -334,7 +335,7 @@ static int aic_decode_slice(AICContext *ctx, int mb_x, int mb_y, else recombine_block_il(ctx->block, ctx->scantable.permutated, &base_y, &ext_y, blk); - unquant_block(ctx->block, ctx->quant); + unquant_block(ctx->block, ctx->quant, ctx->quant_matrix); ctx->dsp.idct(ctx->block); if (!ctx->interlaced) { @@ -352,7 +353,7 @@ static int aic_decode_slice(AICContext *ctx, int mb_x, int mb_y, for (blk = 0; blk < 2; blk++) { recombine_block(ctx->block, ctx->scantable.permutated, &base_c, &ext_c); - unquant_block(ctx->block, ctx->quant); + unquant_block(ctx->block, ctx->quant, ctx->quant_matrix); ctx->dsp.idct(ctx->block); ctx->dsp.put_signed_pixels_clamped(ctx->block, C[blk], ctx->frame->linesize[blk + 1]); @@ -430,12 +431,14 @@ static av_cold int aic_decode_init(AVCodecContext *avctx) for (i = 0; i < 64; i++) scan[i] = i; ff_init_scantable(ctx->dsp.idct_permutation, &ctx->scantable, scan); + for (i = 0; i < 64; i++) + ctx->quant_matrix[ctx->dsp.idct_permutation[i]] = aic_quant_matrix[i]; ctx->mb_width = FFALIGN(avctx->width, 16) >> 4; ctx->mb_height = FFALIGN(avctx->height, 16) >> 4; - ctx->num_x_slices = 16; - ctx->slice_width = ctx->mb_width / 16; + ctx->num_x_slices = (ctx->mb_width + 15) >> 4; + ctx->slice_width = 16; for (i = 1; i < 32; i++) { if (!(ctx->mb_width % i) && (ctx->mb_width / i < 32)) { ctx->slice_width = ctx->mb_width / i; diff --git a/libavcodec/alac.c b/libavcodec/alac.c index 3f37f61883..0021e87baf 100644 --- a/libavcodec/alac.c +++ b/libavcodec/alac.c @@ -311,6 +311,11 @@ static int decode_element(AVCodecContext *avctx, AVFrame *frame, int ch_index, int lpc_quant[2]; int rice_history_mult[2]; + if (!alac->rice_limit) { + avpriv_request_sample(alac->avctx, "Compression with rice limit 0"); + return AVERROR(ENOSYS); + } + decorr_shift = get_bits(&alac->gb, 8); decorr_left_weight = get_bits(&alac->gb, 8); @@ -490,7 +495,8 @@ static int alac_decode_frame(AVCodecContext *avctx, void *data, avpkt->size * 8 - get_bits_count(&alac->gb)); } - *got_frame_ptr = 1; + if (alac->channels == ch) + *got_frame_ptr = 1; return avpkt->size; } diff --git a/libavcodec/alsdec.c b/libavcodec/alsdec.c index 7b99d8689e..97afe68609 100644 --- a/libavcodec/alsdec.c +++ b/libavcodec/alsdec.c @@ -280,7 +280,7 @@ static av_cold int read_specific_config(ALSDecContext *ctx) GetBitContext gb; uint64_t ht_size; int i, config_offset; - MPEG4AudioConfig m4ac; + MPEG4AudioConfig m4ac = {0}; ALSSpecificConfig *sconf = &ctx->sconf; AVCodecContext *avctx = ctx->avctx; uint32_t als_id, header_size, trailer_size; @@ -355,11 +355,15 @@ static av_cold int read_specific_config(ALSDecContext *ctx) ctx->cs_switch = 1; + for (i = 0; i < avctx->channels; i++) { + sconf->chan_pos[i] = -1; + } + for (i = 0; i < avctx->channels; i++) { int idx; idx = get_bits(&gb, chan_pos_bits); - if (idx >= avctx->channels) { + if (idx >= avctx->channels || sconf->chan_pos[idx] != -1) { av_log(avctx, AV_LOG_WARNING, "Invalid channel reordering.\n"); ctx->cs_switch = 0; break; @@ -676,7 +680,7 @@ static int read_var_block_data(ALSDecContext *ctx, ALSBlockData *bd) if (!sconf->rlslms) { - if (sconf->adapt_order) { + if (sconf->adapt_order && sconf->max_order) { int opt_order_length = av_ceil_log2(av_clip((bd->block_length >> 3) - 1, 2, sconf->max_order + 1)); *bd->opt_order = get_bits(gb, opt_order_length); @@ -688,7 +692,11 @@ static int read_var_block_data(ALSDecContext *ctx, ALSBlockData *bd) } else { *bd->opt_order = sconf->max_order; } - + if (*bd->opt_order > bd->block_length) { + *bd->opt_order = bd->block_length; + av_log(avctx, AV_LOG_ERROR, "Predictor order too large.\n"); + return AVERROR_INVALIDDATA; + } opt_order = *bd->opt_order; if (opt_order) { @@ -1234,6 +1242,7 @@ static int revert_channel_correlation(ALSDecContext *ctx, ALSBlockData *bd, ALSChannelData *ch = cd[c]; unsigned int dep = 0; unsigned int channels = ctx->avctx->channels; + unsigned int channel_size = ctx->sconf.frame_length + ctx->sconf.max_order; if (reverted[c]) return 0; @@ -1265,9 +1274,9 @@ static int revert_channel_correlation(ALSDecContext *ctx, ALSBlockData *bd, dep = 0; while (!ch[dep].stop_flag) { - unsigned int smp; - unsigned int begin = 1; - unsigned int end = bd->block_length - 1; + ptrdiff_t smp; + ptrdiff_t begin = 1; + ptrdiff_t end = bd->block_length - 1; int64_t y; int32_t *master = ctx->raw_samples[ch[dep].master_channel] + offset; @@ -1276,11 +1285,28 @@ static int revert_channel_correlation(ALSDecContext *ctx, ALSBlockData *bd, if (ch[dep].time_diff_sign) { t = -t; + if (begin < t) { + av_log(ctx->avctx, AV_LOG_ERROR, "begin %td smaller than time diff index %d.\n", begin, t); + return AVERROR_INVALIDDATA; + } begin -= t; } else { + if (end < t) { + av_log(ctx->avctx, AV_LOG_ERROR, "end %td smaller than time diff index %d.\n", end, t); + return AVERROR_INVALIDDATA; + } end -= t; } + if (FFMIN(begin - 1, begin - 1 + t) < ctx->raw_buffer - master || + FFMAX(end + 1, end + 1 + t) > ctx->raw_buffer + channels * channel_size - master) { + av_log(ctx->avctx, AV_LOG_ERROR, + "sample pointer range [%p, %p] not contained in raw_buffer [%p, %p].\n", + master + FFMIN(begin - 1, begin - 1 + t), master + FFMAX(end + 1, end + 1 + t), + ctx->raw_buffer, ctx->raw_buffer + channels * channel_size); + return AVERROR_INVALIDDATA; + } + for (smp = begin; smp < end; smp++) { y = (1 << 6) + MUL64(ch[dep].weighting[0], master[smp - 1 ]) + @@ -1293,6 +1319,16 @@ static int revert_channel_correlation(ALSDecContext *ctx, ALSBlockData *bd, bd->raw_samples[smp] += y >> 7; } } else { + + if (begin - 1 < ctx->raw_buffer - master || + end + 1 > ctx->raw_buffer + channels * channel_size - master) { + av_log(ctx->avctx, AV_LOG_ERROR, + "sample pointer range [%p, %p] not contained in raw_buffer [%p, %p].\n", + master + begin - 1, master + end + 1, + ctx->raw_buffer, ctx->raw_buffer + channels * channel_size); + return AVERROR_INVALIDDATA; + } + for (smp = begin; smp < end; smp++) { y = (1 << 6) + MUL64(ch[dep].weighting[0], master[smp - 1]) + @@ -1711,9 +1747,9 @@ static av_cold int decode_init(AVCodecContext *avctx) // allocate and assign channel data buffer for mcc mode if (sconf->mc_coding) { - ctx->chan_data_buffer = av_malloc(sizeof(*ctx->chan_data_buffer) * + ctx->chan_data_buffer = av_mallocz(sizeof(*ctx->chan_data_buffer) * num_buffers * num_buffers); - ctx->chan_data = av_malloc(sizeof(*ctx->chan_data) * + ctx->chan_data = av_mallocz(sizeof(*ctx->chan_data) * num_buffers); ctx->reverted_channels = av_malloc(sizeof(*ctx->reverted_channels) * num_buffers); diff --git a/libavcodec/ansi.c b/libavcodec/ansi.c index 8dce61a8c6..8e2b61d912 100644 --- a/libavcodec/ansi.c +++ b/libavcodec/ansi.c @@ -417,7 +417,7 @@ static int decode_frame(AVCodecContext *avctx, switch(buf[0]) { case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': - if (s->nb_args < MAX_NB_ARGS) + if (s->nb_args < MAX_NB_ARGS && s->args[s->nb_args] < 6553) s->args[s->nb_args] = FFMAX(s->args[s->nb_args], 0) * 10 + buf[0] - '0'; break; case ';': diff --git a/libavcodec/apedec.c b/libavcodec/apedec.c index ea71ea0ef3..e1e7da7a39 100644 --- a/libavcodec/apedec.c +++ b/libavcodec/apedec.c @@ -598,15 +598,19 @@ static void decode_array_0000(APEContext *ctx, GetBitContext *gb, int ksummax, ksummin; rice->ksum = 0; - for (i = 0; i < 5; i++) { + for (i = 0; i < FFMIN(blockstodecode, 5); i++) { out[i] = get_rice_ook(&ctx->gb, 10); rice->ksum += out[i]; } rice->k = av_log2(rice->ksum / 10) + 1; - for (; i < 64; i++) { + if (rice->k >= 24) + return; + for (; i < FFMIN(blockstodecode, 64); i++) { out[i] = get_rice_ook(&ctx->gb, rice->k); rice->ksum += out[i]; rice->k = av_log2(rice->ksum / ((i + 1) * 2)) + 1; + if (rice->k >= 24) + return; } ksummax = 1 << rice->k + 7; ksummin = rice->k ? (1 << rice->k + 6) : 0; @@ -1467,13 +1471,13 @@ static int ape_decode_frame(AVCodecContext *avctx, void *data, av_log(avctx, AV_LOG_ERROR, "Invalid sample count: %u.\n", nblocks); return AVERROR_INVALIDDATA; } - s->samples = nblocks; /* Initialize the frame decoder */ if (init_frame_decoder(s) < 0) { av_log(avctx, AV_LOG_ERROR, "Error reading frame header\n"); return AVERROR_INVALIDDATA; } + s->samples = nblocks; } if (!s->data) { diff --git a/libavcodec/arm/int_neon.S b/libavcodec/arm/int_neon.S index dea1ad51eb..b3f5a69ea4 100644 --- a/libavcodec/arm/int_neon.S +++ b/libavcodec/arm/int_neon.S @@ -41,10 +41,10 @@ function ff_scalarproduct_int16_neon, export=1 vpadd.s32 d16, d0, d1 vpadd.s32 d17, d2, d3 - vpadd.s32 d10, d4, d5 - vpadd.s32 d11, d6, d7 + vpadd.s32 d18, d4, d5 + vpadd.s32 d19, d6, d7 vpadd.s32 d0, d16, d17 - vpadd.s32 d1, d10, d11 + vpadd.s32 d1, d18, d19 vpadd.s32 d2, d0, d1 vpaddl.s32 d3, d2 vmov.32 r0, d3[0] @@ -81,10 +81,10 @@ function ff_scalarproduct_and_madd_int16_neon, export=1 vpadd.s32 d16, d0, d1 vpadd.s32 d17, d2, d3 - vpadd.s32 d10, d4, d5 - vpadd.s32 d11, d6, d7 + vpadd.s32 d18, d4, d5 + vpadd.s32 d19, d6, d7 vpadd.s32 d0, d16, d17 - vpadd.s32 d1, d10, d11 + vpadd.s32 d1, d18, d19 vpadd.s32 d2, d0, d1 vpaddl.s32 d3, d2 vmov.32 r0, d3[0] diff --git a/libavcodec/asv.c b/libavcodec/asv.c index 21f179bb77..58d2a895a6 100644 --- a/libavcodec/asv.c +++ b/libavcodec/asv.c @@ -89,6 +89,5 @@ av_cold void ff_asv_common_init(AVCodecContext *avctx) { a->mb_width2 = (avctx->width + 0) / 16; a->mb_height2 = (avctx->height + 0) / 16; - avctx->coded_frame= &a->picture; a->avctx= avctx; } diff --git a/libavcodec/asv.h b/libavcodec/asv.h index ca67c67daa..ce3c73aba4 100644 --- a/libavcodec/asv.h +++ b/libavcodec/asv.h @@ -38,7 +38,6 @@ typedef struct ASV1Context{ AVCodecContext *avctx; DSPContext dsp; - AVFrame picture; PutBitContext pb; GetBitContext gb; ScanTable scantable; diff --git a/libavcodec/asvenc.c b/libavcodec/asvenc.c index 38d971abcb..066dbbab8b 100644 --- a/libavcodec/asvenc.c +++ b/libavcodec/asvenc.c @@ -148,14 +148,16 @@ static inline int encode_mb(ASV1Context *a, int16_t block[6][64]){ return 0; } -static inline void dct_get(ASV1Context *a, int mb_x, int mb_y){ +static inline void dct_get(ASV1Context *a, const AVFrame *frame, + int mb_x, int mb_y) +{ int16_t (*block)[64]= a->block; - int linesize= a->picture.linesize[0]; + int linesize = frame->linesize[0]; int i; - uint8_t *ptr_y = a->picture.data[0] + (mb_y * 16* linesize ) + mb_x * 16; - uint8_t *ptr_cb = a->picture.data[1] + (mb_y * 8 * a->picture.linesize[1]) + mb_x * 8; - uint8_t *ptr_cr = a->picture.data[2] + (mb_y * 8 * a->picture.linesize[2]) + mb_x * 8; + uint8_t *ptr_y = frame->data[0] + (mb_y * 16* linesize ) + mb_x * 16; + uint8_t *ptr_cb = frame->data[1] + (mb_y * 8 * frame->linesize[1]) + mb_x * 8; + uint8_t *ptr_cr = frame->data[2] + (mb_y * 8 * frame->linesize[2]) + mb_x * 8; a->dsp.get_pixels(block[0], ptr_y , linesize); a->dsp.get_pixels(block[1], ptr_y + 8, linesize); @@ -165,8 +167,8 @@ static inline void dct_get(ASV1Context *a, int mb_x, int mb_y){ a->dsp.fdct(block[i]); if(!(a->avctx->flags&CODEC_FLAG_GRAY)){ - a->dsp.get_pixels(block[4], ptr_cb, a->picture.linesize[1]); - a->dsp.get_pixels(block[5], ptr_cr, a->picture.linesize[2]); + a->dsp.get_pixels(block[4], ptr_cb, frame->linesize[1]); + a->dsp.get_pixels(block[5], ptr_cr, frame->linesize[2]); for(i=4; i<6; i++) a->dsp.fdct(block[i]); } @@ -176,7 +178,6 @@ static int encode_frame(AVCodecContext *avctx, AVPacket *pkt, const AVFrame *pict, int *got_packet) { ASV1Context * const a = avctx->priv_data; - AVFrame * const p= &a->picture; int size, ret; int mb_x, mb_y; @@ -186,13 +187,9 @@ static int encode_frame(AVCodecContext *avctx, AVPacket *pkt, init_put_bits(&a->pb, pkt->data, pkt->size); - *p = *pict; - p->pict_type= AV_PICTURE_TYPE_I; - p->key_frame= 1; - for(mb_y=0; mb_ymb_height2; mb_y++){ for(mb_x=0; mb_xmb_width2; mb_x++){ - dct_get(a, mb_x, mb_y); + dct_get(a, pict, mb_x, mb_y); encode_mb(a, a->block); } } @@ -200,7 +197,7 @@ static int encode_frame(AVCodecContext *avctx, AVPacket *pkt, if(a->mb_width2 != a->mb_width){ mb_x= a->mb_width2; for(mb_y=0; mb_ymb_height2; mb_y++){ - dct_get(a, mb_x, mb_y); + dct_get(a, pict, mb_x, mb_y); encode_mb(a, a->block); } } @@ -208,7 +205,7 @@ static int encode_frame(AVCodecContext *avctx, AVPacket *pkt, if(a->mb_height2 != a->mb_height){ mb_y= a->mb_height2; for(mb_x=0; mb_xmb_width; mb_x++){ - dct_get(a, mb_x, mb_y); + dct_get(a, pict, mb_x, mb_y); encode_mb(a, a->block); } } @@ -240,6 +237,12 @@ static av_cold int encode_init(AVCodecContext *avctx){ int i; const int scale= avctx->codec_id == AV_CODEC_ID_ASV1 ? 1 : 2; + avctx->coded_frame = av_frame_alloc(); + if (!avctx->coded_frame) + return AVERROR(ENOMEM); + avctx->coded_frame->pict_type = AV_PICTURE_TYPE_I; + avctx->coded_frame->key_frame = 1; + ff_asv_common_init(avctx); if(avctx->global_quality == 0) avctx->global_quality= 4*FF_QUALITY_SCALE; diff --git a/libavcodec/avpacket.c b/libavcodec/avpacket.c index d9cfb38e24..73a919c919 100644 --- a/libavcodec/avpacket.c +++ b/libavcodec/avpacket.c @@ -380,7 +380,7 @@ FF_ENABLE_DEPRECATION_WARNINGS int av_packet_split_side_data(AVPacket *pkt){ if (!pkt->side_data_elems && pkt->size >12 && AV_RB64(pkt->data + pkt->size - 8) == FF_MERGE_MARKER){ int i; - unsigned int size, orig_pktsize = pkt->size; + unsigned int size; uint8_t *p; p = pkt->data + pkt->size - 8 - 5; @@ -413,13 +413,6 @@ int av_packet_split_side_data(AVPacket *pkt){ p-= size+5; } pkt->size -= 8; - /* FFMIN() prevents overflow in case the packet wasn't allocated with - * proper padding. - * If the side data is smaller than the buffer padding size, the - * remaining bytes should have already been filled with zeros by the - * original packet allocation anyway. */ - memset(pkt->data + pkt->size, 0, - FFMIN(orig_pktsize - pkt->size, FF_INPUT_BUFFER_PADDING_SIZE)); pkt->side_data_elems = i+1; return 1; } diff --git a/libavcodec/avs.c b/libavcodec/avs.c index 065345b5cd..a0d2045885 100644 --- a/libavcodec/avs.c +++ b/libavcodec/avs.c @@ -25,7 +25,7 @@ typedef struct { - AVFrame picture; + AVFrame *frame; } AvsContext; typedef enum { @@ -52,7 +52,7 @@ avs_decode_frame(AVCodecContext * avctx, int buf_size = avpkt->size; AvsContext *const avs = avctx->priv_data; AVFrame *picture = data; - AVFrame *const p = &avs->picture; + AVFrame *const p = avs->frame; const uint8_t *table, *vect; uint8_t *out; int i, j, x, y, stride, ret, vect_w = 3, vect_h = 3; @@ -65,8 +65,8 @@ avs_decode_frame(AVCodecContext * avctx, p->pict_type = AV_PICTURE_TYPE_P; p->key_frame = 0; - out = avs->picture.data[0]; - stride = avs->picture.linesize[0]; + out = p->data[0]; + stride = p->linesize[0]; if (buf_end - buf < 4) return AVERROR_INVALIDDATA; @@ -76,7 +76,7 @@ avs_decode_frame(AVCodecContext * avctx, if (type == AVS_PALETTE) { int first, last; - uint32_t *pal = (uint32_t *) avs->picture.data[1]; + uint32_t *pal = (uint32_t *) p->data[1]; first = AV_RL16(buf); last = first + AV_RL16(buf + 2); @@ -149,7 +149,7 @@ avs_decode_frame(AVCodecContext * avctx, align_get_bits(&change_map); } - if ((ret = av_frame_ref(picture, &avs->picture)) < 0) + if ((ret = av_frame_ref(picture, p)) < 0) return ret; *got_frame = 1; @@ -159,16 +159,21 @@ avs_decode_frame(AVCodecContext * avctx, static av_cold int avs_decode_init(AVCodecContext * avctx) { AvsContext *s = avctx->priv_data; + + s->frame = av_frame_alloc(); + if (!s->frame) + return AVERROR(ENOMEM); + avctx->pix_fmt = AV_PIX_FMT_PAL8; avcodec_set_dimensions(avctx, 318, 198); - avcodec_get_frame_defaults(&s->picture); + return 0; } static av_cold int avs_decode_end(AVCodecContext *avctx) { AvsContext *s = avctx->priv_data; - av_frame_unref(&s->picture); + av_frame_free(&s->frame); return 0; } diff --git a/libavcodec/bethsoftvideo.c b/libavcodec/bethsoftvideo.c index 71d111f893..37cd22eb39 100644 --- a/libavcodec/bethsoftvideo.c +++ b/libavcodec/bethsoftvideo.c @@ -34,21 +34,25 @@ #include "internal.h" typedef struct BethsoftvidContext { - AVFrame frame; + AVFrame *frame; GetByteContext g; } BethsoftvidContext; static av_cold int bethsoftvid_decode_init(AVCodecContext *avctx) { BethsoftvidContext *vid = avctx->priv_data; - avcodec_get_frame_defaults(&vid->frame); avctx->pix_fmt = AV_PIX_FMT_PAL8; + + vid->frame = av_frame_alloc(); + if (!vid->frame) + return AVERROR(ENOMEM); + return 0; } static int set_palette(BethsoftvidContext *ctx) { - uint32_t *palette = (uint32_t *)ctx->frame.data[1]; + uint32_t *palette = (uint32_t *)ctx->frame->data[1]; int a; if (bytestream2_get_bytes_left(&ctx->g) < 256*3) @@ -58,7 +62,7 @@ static int set_palette(BethsoftvidContext *ctx) palette[a] = 0xFFU << 24 | bytestream2_get_be24u(&ctx->g) * 4; palette[a] |= palette[a] >> 6 & 0x30303; } - ctx->frame.palette_has_changed = 1; + ctx->frame->palette_has_changed = 1; return 0; } @@ -75,9 +79,9 @@ static int bethsoftvid_decode_frame(AVCodecContext *avctx, int code, ret; int yoffset; - if ((ret = ff_reget_buffer(avctx, &vid->frame)) < 0) + if ((ret = ff_reget_buffer(avctx, vid->frame)) < 0) return ret; - wrap_to_next_line = vid->frame.linesize[0] - avctx->width; + wrap_to_next_line = vid->frame->linesize[0] - avctx->width; if (avpkt->side_data_elems > 0 && avpkt->side_data[0].type == AV_PKT_DATA_PALETTE) { @@ -88,8 +92,8 @@ static int bethsoftvid_decode_frame(AVCodecContext *avctx, } bytestream2_init(&vid->g, avpkt->data, avpkt->size); - dst = vid->frame.data[0]; - frame_end = vid->frame.data[0] + vid->frame.linesize[0] * avctx->height; + dst = vid->frame->data[0]; + frame_end = vid->frame->data[0] + vid->frame->linesize[0] * avctx->height; switch(block_type = bytestream2_get_byte(&vid->g)){ case PALETTE_BLOCK: { @@ -104,7 +108,7 @@ static int bethsoftvid_decode_frame(AVCodecContext *avctx, yoffset = bytestream2_get_le16(&vid->g); if(yoffset >= avctx->height) return AVERROR_INVALIDDATA; - dst += vid->frame.linesize[0] * yoffset; + dst += vid->frame->linesize[0] * yoffset; } // main code @@ -134,7 +138,7 @@ static int bethsoftvid_decode_frame(AVCodecContext *avctx, } end: - if ((ret = av_frame_ref(data, &vid->frame)) < 0) + if ((ret = av_frame_ref(data, vid->frame)) < 0) return ret; *got_frame = 1; @@ -145,7 +149,7 @@ static int bethsoftvid_decode_frame(AVCodecContext *avctx, static av_cold int bethsoftvid_decode_end(AVCodecContext *avctx) { BethsoftvidContext * vid = avctx->priv_data; - av_frame_unref(&vid->frame); + av_frame_free(&vid->frame); return 0; } diff --git a/libavcodec/bink.c b/libavcodec/bink.c index 8878694777..8f8a036d4f 100644 --- a/libavcodec/bink.c +++ b/libavcodec/bink.c @@ -120,6 +120,7 @@ typedef struct BinkContext { int version; ///< internal Bink file version int has_alpha; int swap_planes; + unsigned frame_num; Bundle bundle[BINKB_NB_SRC]; ///< bundles for decoding all data types Tree col_high[16]; ///< trees for decoding high nibble in "colours" data type @@ -1206,6 +1207,8 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame, AVPac if (c->version >= 'i') skip_bits_long(&gb, 32); + c->frame_num++; + for (plane = 0; plane < 3; plane++) { plane_idx = (!plane || !c->swap_planes) ? plane : (plane ^ 3); @@ -1214,7 +1217,7 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame, AVPac return ret; } else { if ((ret = binkb_decode_plane(c, frame, &gb, plane_idx, - !avctx->frame_number, !!plane)) < 0) + c->frame_num == 1, !!plane)) < 0) return ret; } if (get_bits_count(&gb) >= bits_count) @@ -1332,6 +1335,13 @@ static av_cold int decode_end(AVCodecContext *avctx) return 0; } +static void flush(AVCodecContext *avctx) +{ + BinkContext * const c = avctx->priv_data; + + c->frame_num = 0; +} + AVCodec ff_bink_decoder = { .name = "binkvideo", .long_name = NULL_IF_CONFIG_SMALL("Bink video"), @@ -1341,5 +1351,6 @@ AVCodec ff_bink_decoder = { .init = decode_init, .close = decode_end, .decode = decode_frame, + .flush = flush, .capabilities = CODEC_CAP_DR1, }; diff --git a/libavcodec/bmpenc.c b/libavcodec/bmpenc.c index ad02a6b314..2a1956dc4a 100644 --- a/libavcodec/bmpenc.c +++ b/libavcodec/bmpenc.c @@ -60,22 +60,26 @@ static av_cold int bmp_encode_init(AVCodecContext *avctx){ return AVERROR(EINVAL); } + avctx->coded_frame = av_frame_alloc(); + if (!avctx->coded_frame) + return AVERROR(ENOMEM); + return 0; } static int bmp_encode_frame(AVCodecContext *avctx, AVPacket *pkt, const AVFrame *pict, int *got_packet) { + const AVFrame * const p = pict; int n_bytes_image, n_bytes_per_row, n_bytes, i, n, hsize, ret; const uint32_t *pal = NULL; uint32_t palette256[256]; int pad_bytes_per_row, pal_entries = 0, compression = BMP_RGB; int bit_count = avctx->bits_per_coded_sample; uint8_t *ptr, *buf; - AVFrame * const p = (AVFrame *)pict; - p->pict_type= AV_PICTURE_TYPE_I; - p->key_frame= 1; + avctx->coded_frame->pict_type = AV_PICTURE_TYPE_I; + avctx->coded_frame->key_frame = 1; switch (avctx->pix_fmt) { case AV_PIX_FMT_RGB444: compression = BMP_BITFIELDS; @@ -159,6 +163,12 @@ static int bmp_encode_frame(AVCodecContext *avctx, AVPacket *pkt, return 0; } +static av_cold int bmp_encode_close(AVCodecContext *avctx) +{ + av_frame_free(&avctx->coded_frame); + return 0; +} + AVCodec ff_bmp_encoder = { .name = "bmp", .long_name = NULL_IF_CONFIG_SMALL("BMP (Windows and OS/2 bitmap)"), @@ -166,6 +176,7 @@ AVCodec ff_bmp_encoder = { .id = AV_CODEC_ID_BMP, .init = bmp_encode_init, .encode2 = bmp_encode_frame, + .close = bmp_encode_close, .pix_fmts = (const enum AVPixelFormat[]){ AV_PIX_FMT_BGRA, AV_PIX_FMT_BGR24, AV_PIX_FMT_RGB565, AV_PIX_FMT_RGB555, AV_PIX_FMT_RGB444, diff --git a/libavcodec/c93.c b/libavcodec/c93.c index f25368b101..f220762719 100644 --- a/libavcodec/c93.c +++ b/libavcodec/c93.c @@ -24,7 +24,7 @@ #include "internal.h" typedef struct { - AVFrame pictures[2]; + AVFrame *pictures[2]; int currentpic; } C93DecoderContext; @@ -46,21 +46,27 @@ typedef enum { #define C93_HAS_PALETTE 0x01 #define C93_FIRST_FRAME 0x02 -static av_cold int decode_init(AVCodecContext *avctx) -{ - C93DecoderContext *s = avctx->priv_data; - avctx->pix_fmt = AV_PIX_FMT_PAL8; - avcodec_get_frame_defaults(&s->pictures[0]); - avcodec_get_frame_defaults(&s->pictures[1]); - return 0; -} - static av_cold int decode_end(AVCodecContext *avctx) { C93DecoderContext * const c93 = avctx->priv_data; - av_frame_unref(&c93->pictures[0]); - av_frame_unref(&c93->pictures[1]); + av_frame_free(&c93->pictures[0]); + av_frame_free(&c93->pictures[1]); + + return 0; +} + +static av_cold int decode_init(AVCodecContext *avctx) +{ + C93DecoderContext *s = avctx->priv_data; + avctx->pix_fmt = AV_PIX_FMT_PAL8; + + s->pictures[0] = av_frame_alloc(); + s->pictures[1] = av_frame_alloc(); + if (!s->pictures[0] || !s->pictures[1]) { + decode_end(avctx); + return AVERROR(ENOMEM); + } return 0; } @@ -121,8 +127,8 @@ static int decode_frame(AVCodecContext *avctx, void *data, const uint8_t *buf = avpkt->data; int buf_size = avpkt->size; C93DecoderContext * const c93 = avctx->priv_data; - AVFrame * const newpic = &c93->pictures[c93->currentpic]; - AVFrame * const oldpic = &c93->pictures[c93->currentpic^1]; + AVFrame * const newpic = c93->pictures[c93->currentpic]; + AVFrame * const oldpic = c93->pictures[c93->currentpic^1]; GetByteContext gb; uint8_t *out; int stride, ret, i, x, y, b, bt = 0; diff --git a/libavcodec/cabac.c b/libavcodec/cabac.c index 29b188bc31..dff0a91273 100644 --- a/libavcodec/cabac.c +++ b/libavcodec/cabac.c @@ -301,7 +301,7 @@ STOP_TIMER("get_cabac_bypass") for(i=0; ilow+= c->bytestream[0]<<1; #endif c->low -= CABAC_MASK; - c->bytestream += CABAC_BITS / 8; +#if !UNCHECKED_BITSTREAM_READER + if (c->bytestream < c->bytestream_end) +#endif + c->bytestream += CABAC_BITS / 8; } static inline void renorm_cabac_decoder_once(CABACContext *c){ @@ -76,7 +79,10 @@ static void refill2(CABACContext *c){ #endif c->low += x<bytestream += CABAC_BITS/8; +#if !UNCHECKED_BITSTREAM_READER + if (c->bytestream < c->bytestream_end) +#endif + c->bytestream += CABAC_BITS/8; } static av_always_inline int get_cabac_inline(CABACContext *c, uint8_t * const state){ diff --git a/libavcodec/cavs.h b/libavcodec/cavs.h index f3c05dc9f0..f85140927b 100644 --- a/libavcodec/cavs.h +++ b/libavcodec/cavs.h @@ -214,6 +214,7 @@ typedef struct AVSContext { int luma_scan[4]; int qp; int qp_fixed; + int pic_qp_fixed; int cbp; ScanTable scantable; diff --git a/libavcodec/cavsdec.c b/libavcodec/cavsdec.c index 74983a75a9..4502084901 100644 --- a/libavcodec/cavsdec.c +++ b/libavcodec/cavsdec.c @@ -900,7 +900,7 @@ static inline int decode_slice_header(AVSContext *h, GetBitContext *gb) /* mark top macroblocks as unavailable */ h->flags &= ~(B_AVAIL | C_AVAIL); - if ((h->mby == 0) && (!h->qp_fixed)) { + if (!h->pic_qp_fixed) { h->qp_fixed = get_bits1(gb); h->qp = get_bits(gb, 6); } @@ -1023,6 +1023,7 @@ static int decode_pic(AVSContext *h) skip_bits1(&h->gb); //advanced_pred_mode_disable skip_bits1(&h->gb); //top_field_first skip_bits1(&h->gb); //repeat_first_field + h->pic_qp_fixed = h->qp_fixed = get_bits1(&h->gb); h->qp = get_bits(&h->gb, 6); if (h->cur.f->pict_type == AV_PICTURE_TYPE_I) { 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/cljr.c b/libavcodec/cljr.c index 51ac10662a..7e0773b6be 100644 --- a/libavcodec/cljr.c +++ b/libavcodec/cljr.c @@ -99,16 +99,21 @@ AVCodec ff_cljr_decoder = { #if CONFIG_CLJR_ENCODER typedef struct CLJRContext { AVClass *avclass; - AVFrame picture; int dither_type; } CLJRContext; static av_cold int encode_init(AVCodecContext *avctx) { - CLJRContext * const a = avctx->priv_data; + avctx->coded_frame = av_frame_alloc(); + if (!avctx->coded_frame) + return AVERROR(ENOMEM); - avctx->coded_frame = &a->picture; + return 0; +} +static av_cold int encode_close(AVCodecContext *avctx) +{ + av_frame_free(&avctx->coded_frame); return 0; } @@ -183,6 +188,7 @@ AVCodec ff_cljr_encoder = { .priv_data_size = sizeof(CLJRContext), .init = encode_init, .encode2 = encode_frame, + .close = encode_close, .pix_fmts = (const enum AVPixelFormat[]) { AV_PIX_FMT_YUV411P, AV_PIX_FMT_NONE }, .priv_class = &cljr_class, diff --git a/libavcodec/cook.c b/libavcodec/cook.c index 083d26bf6f..008dee93ef 100644 --- a/libavcodec/cook.c +++ b/libavcodec/cook.c @@ -1217,8 +1217,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/dirac_arith.h b/libavcodec/dirac_arith.h index f9a8bba5fd..a1fa96b5bc 100644 --- a/libavcodec/dirac_arith.h +++ b/libavcodec/dirac_arith.h @@ -28,6 +28,7 @@ #ifndef AVCODEC_DIRAC_ARITH_H #define AVCODEC_DIRAC_ARITH_H +#include "libavutil/x86/asm.h" #include "bytestream.h" #include "get_bits.h" @@ -134,7 +135,7 @@ static inline int dirac_get_arith_bit(DiracArith *c, int ctx) range_times_prob = (c->range * prob_zero) >> 16; -#if HAVE_FAST_CMOV && HAVE_INLINE_ASM +#if HAVE_FAST_CMOV && HAVE_INLINE_ASM && HAVE_6REGS low -= range_times_prob << 16; range -= range_times_prob; bit = 0; @@ -170,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 15baf75108..80cf297406 100644 --- a/libavcodec/diracdec.c +++ b/libavcodec/diracdec.c @@ -80,7 +80,7 @@ #define DIVRNDUP(a, b) (((a) + (b) - 1) / (b)) typedef struct { - AVFrame avframe; + AVFrame *avframe; int interpolated[3]; /* 1 if hpel[] is valid */ uint8_t *hpel[3][4]; uint8_t *hpel_base[3][4]; @@ -201,6 +201,7 @@ typedef struct DiracContext { uint16_t *mctmp; /* buffer holding the MC data multipled by OBMC weights */ uint8_t *mcscratch; + int buffer_stride; DECLARE_ALIGNED(16, uint8_t, obmc_weight)[3][MAX_BLOCKSIZE*MAX_BLOCKSIZE]; @@ -291,7 +292,7 @@ static DiracFrame *remove_frame(DiracFrame *framelist[], int picnum) int i, remove_idx = -1; for (i = 0; framelist[i]; i++) - if (framelist[i]->avframe.display_picture_number == picnum) { + if (framelist[i]->avframe->display_picture_number == picnum) { remove_pic = framelist[i]; remove_idx = i; } @@ -343,29 +344,51 @@ static int alloc_sequence_buffers(DiracContext *s) return AVERROR(ENOMEM); } - w = s->source.width; - h = s->source.height; - /* fixme: allocate using real stride here */ - s->sbsplit = av_malloc(sbwidth * sbheight); - s->blmotion = av_malloc(sbwidth * sbheight * 16 * sizeof(*s->blmotion)); - s->edge_emu_buffer_base = av_malloc((w+64)*MAX_BLOCKSIZE); + s->sbsplit = av_malloc_array(sbwidth, sbheight); + s->blmotion = av_malloc_array(sbwidth, sbheight * 16 * sizeof(*s->blmotion)); - s->mctmp = av_malloc((w+64+MAX_BLOCKSIZE) * (h+MAX_BLOCKSIZE) * sizeof(*s->mctmp)); - s->mcscratch = av_malloc((w+64)*MAX_BLOCKSIZE); - - if (!s->sbsplit || !s->blmotion || !s->mctmp || !s->mcscratch) + if (!s->sbsplit || !s->blmotion) return AVERROR(ENOMEM); return 0; } +static int alloc_buffers(DiracContext *s, int stride) +{ + int w = s->source.width; + int h = s->source.height; + + av_assert0(stride >= w); + stride += 64; + + if (s->buffer_stride >= stride) + return 0; + s->buffer_stride = 0; + + av_freep(&s->edge_emu_buffer_base); + memset(s->edge_emu_buffer, 0, sizeof(s->edge_emu_buffer)); + av_freep(&s->mctmp); + av_freep(&s->mcscratch); + + s->edge_emu_buffer_base = av_malloc_array(stride, MAX_BLOCKSIZE); + + s->mctmp = av_malloc_array((stride+MAX_BLOCKSIZE), (h+MAX_BLOCKSIZE) * sizeof(*s->mctmp)); + s->mcscratch = av_malloc_array(stride, MAX_BLOCKSIZE); + + if (!s->edge_emu_buffer_base || !s->mctmp || !s->mcscratch) + return AVERROR(ENOMEM); + + s->buffer_stride = stride; + return 0; +} + static void free_sequence_buffers(DiracContext *s) { int i, j, k; for (i = 0; i < MAX_FRAMES; i++) { - if (s->all_frames[i].avframe.data[0]) { - av_frame_unref(&s->all_frames[i].avframe); + if (s->all_frames[i].avframe->data[0]) { + av_frame_unref(s->all_frames[i].avframe); memset(s->all_frames[i].interpolated, 0, sizeof(s->all_frames[i].interpolated)); } @@ -382,6 +405,7 @@ static void free_sequence_buffers(DiracContext *s) av_freep(&s->plane[i].idwt_tmp); } + s->buffer_stride = 0; av_freep(&s->sbsplit); av_freep(&s->blmotion); av_freep(&s->edge_emu_buffer_base); @@ -393,6 +417,8 @@ static void free_sequence_buffers(DiracContext *s) static av_cold int dirac_decode_init(AVCodecContext *avctx) { DiracContext *s = avctx->priv_data; + int i; + s->avctx = avctx; s->frame_number = -1; @@ -404,6 +430,15 @@ static av_cold int dirac_decode_init(AVCodecContext *avctx) ff_dsputil_init(&s->dsp, avctx); ff_diracdsp_init(&s->diracdsp); + for (i = 0; i < MAX_FRAMES; i++) { + s->all_frames[i].avframe = av_frame_alloc(); + if (!s->all_frames[i].avframe) { + while (i > 0) + av_frame_free(&s->all_frames[--i].avframe); + return AVERROR(ENOMEM); + } + } + return 0; } @@ -417,7 +452,13 @@ static void dirac_decode_flush(AVCodecContext *avctx) static av_cold int dirac_decode_end(AVCodecContext *avctx) { + DiracContext *s = avctx->priv_data; + int i; + dirac_decode_flush(avctx); + for (i = 0; i < MAX_FRAMES; i++) + av_frame_free(&s->all_frames[i].avframe); + return 0; } @@ -574,10 +615,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; } @@ -966,8 +1007,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") @@ -1343,8 +1384,8 @@ static int mc_subpel(DiracContext *s, DiracBlock *block, const uint8_t *src[5], motion_y >>= s->chroma_y_shift; } - mx = motion_x & ~(-1 << s->mv_precision); - my = motion_y & ~(-1 << s->mv_precision); + mx = motion_x & ~(-1U << s->mv_precision); + my = motion_y & ~(-1U << s->mv_precision); motion_x >>= s->mv_precision; motion_y >>= s->mv_precision; /* normalize subpel coordinates to epel */ @@ -1519,8 +1560,8 @@ static void interpolate_refplane(DiracContext *s, DiracFrame *ref, int plane, in just use 8 for everything for the moment */ int i, edge = EDGE_WIDTH/2; - ref->hpel[plane][0] = ref->avframe.data[plane]; - s->dsp.draw_edges(ref->hpel[plane][0], ref->avframe.linesize[plane], width, height, edge, edge, EDGE_TOP | EDGE_BOTTOM); /* EDGE_TOP | EDGE_BOTTOM values just copied to make it build, this needs to be ensured */ + ref->hpel[plane][0] = ref->avframe->data[plane]; + s->dsp.draw_edges(ref->hpel[plane][0], ref->avframe->linesize[plane], width, height, edge, edge, EDGE_TOP | EDGE_BOTTOM); /* EDGE_TOP | EDGE_BOTTOM values just copied to make it build, this needs to be ensured */ /* no need for hpel if we only have fpel vectors */ if (!s->mv_precision) @@ -1528,18 +1569,18 @@ static void interpolate_refplane(DiracContext *s, DiracFrame *ref, int plane, in for (i = 1; i < 4; i++) { if (!ref->hpel_base[plane][i]) - ref->hpel_base[plane][i] = av_malloc((height+2*edge) * ref->avframe.linesize[plane] + 32); + ref->hpel_base[plane][i] = av_malloc((height+2*edge) * ref->avframe->linesize[plane] + 32); /* we need to be 16-byte aligned even for chroma */ - ref->hpel[plane][i] = ref->hpel_base[plane][i] + edge*ref->avframe.linesize[plane] + 16; + ref->hpel[plane][i] = ref->hpel_base[plane][i] + edge*ref->avframe->linesize[plane] + 16; } if (!ref->interpolated[plane]) { s->diracdsp.dirac_hpel_filter(ref->hpel[plane][1], ref->hpel[plane][2], ref->hpel[plane][3], ref->hpel[plane][0], - ref->avframe.linesize[plane], width, height); - s->dsp.draw_edges(ref->hpel[plane][1], ref->avframe.linesize[plane], width, height, edge, edge, EDGE_TOP | EDGE_BOTTOM); - s->dsp.draw_edges(ref->hpel[plane][2], ref->avframe.linesize[plane], width, height, edge, edge, EDGE_TOP | EDGE_BOTTOM); - s->dsp.draw_edges(ref->hpel[plane][3], ref->avframe.linesize[plane], width, height, edge, edge, EDGE_TOP | EDGE_BOTTOM); + ref->avframe->linesize[plane], width, height); + s->dsp.draw_edges(ref->hpel[plane][1], ref->avframe->linesize[plane], width, height, edge, edge, EDGE_TOP | EDGE_BOTTOM); + s->dsp.draw_edges(ref->hpel[plane][2], ref->avframe->linesize[plane], width, height, edge, edge, EDGE_TOP | EDGE_BOTTOM); + s->dsp.draw_edges(ref->hpel[plane][3], ref->avframe->linesize[plane], width, height, edge, edge, EDGE_TOP | EDGE_BOTTOM); } ref->interpolated[plane] = 1; } @@ -1565,7 +1606,7 @@ static int dirac_decode_frame_internal(DiracContext *s) for (comp = 0; comp < 3; comp++) { Plane *p = &s->plane[comp]; - uint8_t *frame = s->current_picture->avframe.data[comp]; + uint8_t *frame = s->current_picture->avframe->data[comp]; /* FIXME: small resolutions */ for (i = 0; i < 4; i++) @@ -1640,7 +1681,7 @@ static int dirac_decode_picture_header(DiracContext *s) GetBitContext *gb = &s->gb; /* [DIRAC_STD] 11.1.1 Picture Header. picture_header() PICTURE_NUM */ - picnum = s->current_picture->avframe.display_picture_number = get_bits_long(gb, 32); + picnum = s->current_picture->avframe->display_picture_number = get_bits_long(gb, 32); av_log(s->avctx,AV_LOG_DEBUG,"PICTURE_NUM: %d\n",picnum); @@ -1659,9 +1700,9 @@ static int dirac_decode_picture_header(DiracContext *s) /* Jordi: this is needed if the referenced picture hasn't yet arrived */ for (j = 0; j < MAX_REFERENCE_FRAMES && refdist; j++) if (s->ref_frames[j] - && FFABS(s->ref_frames[j]->avframe.display_picture_number - refnum) < refdist) { + && FFABS(s->ref_frames[j]->avframe->display_picture_number - refnum) < refdist) { s->ref_pics[i] = s->ref_frames[j]; - refdist = FFABS(s->ref_frames[j]->avframe.display_picture_number - refnum); + refdist = FFABS(s->ref_frames[j]->avframe->display_picture_number - refnum); } if (!s->ref_pics[i] || refdist) @@ -1670,21 +1711,21 @@ static int dirac_decode_picture_header(DiracContext *s) /* if there were no references at all, allocate one */ if (!s->ref_pics[i]) for (j = 0; j < MAX_FRAMES; j++) - if (!s->all_frames[j].avframe.data[0]) { + if (!s->all_frames[j].avframe->data[0]) { s->ref_pics[i] = &s->all_frames[j]; - ff_get_buffer(s->avctx, &s->ref_pics[i]->avframe, AV_GET_BUFFER_FLAG_REF); + ff_get_buffer(s->avctx, s->ref_pics[i]->avframe, AV_GET_BUFFER_FLAG_REF); break; } } /* retire the reference frames that are not used anymore */ - if (s->current_picture->avframe.reference) { + if (s->current_picture->avframe->reference) { retire = picnum + dirac_get_se_golomb(gb); if (retire != picnum) { DiracFrame *retire_pic = remove_frame(s->ref_frames, retire); if (retire_pic) - retire_pic->avframe.reference &= DELAYED_PIC_REF; + retire_pic->avframe->reference &= DELAYED_PIC_REF; else av_log(s->avctx, AV_LOG_DEBUG, "Frame to retire not found\n"); } @@ -1692,7 +1733,7 @@ static int dirac_decode_picture_header(DiracContext *s) /* if reference array is full, remove the oldest as per the spec */ while (add_frame(s->ref_frames, MAX_REFERENCE_FRAMES, s->current_picture)) { av_log(s->avctx, AV_LOG_ERROR, "Reference frame overflow\n"); - remove_frame(s->ref_frames, s->ref_frames[0]->avframe.display_picture_number)->avframe.reference &= DELAYED_PIC_REF; + remove_frame(s->ref_frames, s->ref_frames[0]->avframe->display_picture_number)->avframe->reference &= DELAYED_PIC_REF; } } @@ -1717,7 +1758,7 @@ static int get_delayed_pic(DiracContext *s, AVFrame *picture, int *got_frame) /* find frame with lowest picture number */ for (i = 1; s->delay_frames[i]; i++) - if (s->delay_frames[i]->avframe.display_picture_number < out->avframe.display_picture_number) { + if (s->delay_frames[i]->avframe->display_picture_number < out->avframe->display_picture_number) { out = s->delay_frames[i]; out_idx = i; } @@ -1726,9 +1767,9 @@ static int get_delayed_pic(DiracContext *s, AVFrame *picture, int *got_frame) s->delay_frames[i] = s->delay_frames[i+1]; if (out) { - out->avframe.reference ^= DELAYED_PIC_REF; + out->avframe->reference ^= DELAYED_PIC_REF; *got_frame = 1; - if((ret = av_frame_ref(picture, &out->avframe)) < 0) + if((ret = av_frame_ref(picture, out->avframe)) < 0) return ret; } @@ -1790,14 +1831,14 @@ static int dirac_decode_data_unit(AVCodecContext *avctx, const uint8_t *buf, int /* find an unused frame */ for (i = 0; i < MAX_FRAMES; i++) - if (s->all_frames[i].avframe.data[0] == NULL) + if (s->all_frames[i].avframe->data[0] == NULL) pic = &s->all_frames[i]; if (!pic) { av_log(avctx, AV_LOG_ERROR, "framelist full\n"); return -1; } - avcodec_get_frame_defaults(&pic->avframe); + av_frame_unref(pic->avframe); /* [DIRAC_STD] Defined in 9.6.1 ... */ tmp = parse_code & 0x03; /* [DIRAC_STD] num_refs() */ @@ -1808,16 +1849,19 @@ static int dirac_decode_data_unit(AVCodecContext *avctx, const uint8_t *buf, int s->num_refs = tmp; s->is_arith = (parse_code & 0x48) == 0x08; /* [DIRAC_STD] using_ac() */ s->low_delay = (parse_code & 0x88) == 0x88; /* [DIRAC_STD] is_low_delay() */ - pic->avframe.reference = (parse_code & 0x0C) == 0x0C; /* [DIRAC_STD] is_reference() */ - pic->avframe.key_frame = s->num_refs == 0; /* [DIRAC_STD] is_intra() */ - pic->avframe.pict_type = s->num_refs + 1; /* Definition of AVPictureType in avutil.h */ + pic->avframe->reference = (parse_code & 0x0C) == 0x0C; /* [DIRAC_STD] is_reference() */ + pic->avframe->key_frame = s->num_refs == 0; /* [DIRAC_STD] is_intra() */ + pic->avframe->pict_type = s->num_refs + 1; /* Definition of AVPictureType in avutil.h */ - if ((ret = ff_get_buffer(avctx, &pic->avframe, (parse_code & 0x0C) == 0x0C ? AV_GET_BUFFER_FLAG_REF : 0)) < 0) + if ((ret = ff_get_buffer(avctx, pic->avframe, (parse_code & 0x0C) == 0x0C ? AV_GET_BUFFER_FLAG_REF : 0)) < 0) return ret; s->current_picture = pic; - s->plane[0].stride = pic->avframe.linesize[0]; - s->plane[1].stride = pic->avframe.linesize[1]; - s->plane[2].stride = pic->avframe.linesize[2]; + s->plane[0].stride = pic->avframe->linesize[0]; + s->plane[1].stride = pic->avframe->linesize[1]; + s->plane[2].stride = pic->avframe->linesize[2]; + + if (alloc_buffers(s, FFMAX3(FFABS(s->plane[0].stride), FFABS(s->plane[1].stride), FFABS(s->plane[2].stride))) < 0) + return AVERROR(ENOMEM); /* [DIRAC_STD] 11.1 Picture parse. picture_parse() */ if (dirac_decode_picture_header(s)) @@ -1833,7 +1877,7 @@ static int dirac_decode_data_unit(AVCodecContext *avctx, const uint8_t *buf, int static int dirac_decode_frame(AVCodecContext *avctx, void *data, int *got_frame, AVPacket *pkt) { DiracContext *s = avctx->priv_data; - DiracFrame *picture = data; + AVFrame *picture = data; uint8_t *buf = pkt->data; int buf_size = pkt->size; int i, data_unit_size, buf_idx = 0; @@ -1841,8 +1885,8 @@ static int dirac_decode_frame(AVCodecContext *avctx, void *data, int *got_frame, /* release unused frames */ for (i = 0; i < MAX_FRAMES; i++) - if (s->all_frames[i].avframe.data[0] && !s->all_frames[i].avframe.reference) { - av_frame_unref(&s->all_frames[i].avframe); + if (s->all_frames[i].avframe->data[0] && !s->all_frames[i].avframe->reference) { + av_frame_unref(s->all_frames[i].avframe); memset(s->all_frames[i].interpolated, 0, sizeof(s->all_frames[i].interpolated)); } @@ -1887,40 +1931,40 @@ static int dirac_decode_frame(AVCodecContext *avctx, void *data, int *got_frame, if (!s->current_picture) return buf_size; - if (s->current_picture->avframe.display_picture_number > s->frame_number) { + if (s->current_picture->avframe->display_picture_number > s->frame_number) { DiracFrame *delayed_frame = remove_frame(s->delay_frames, s->frame_number); - s->current_picture->avframe.reference |= DELAYED_PIC_REF; + s->current_picture->avframe->reference |= DELAYED_PIC_REF; if (add_frame(s->delay_frames, MAX_DELAY, s->current_picture)) { - int min_num = s->delay_frames[0]->avframe.display_picture_number; + int min_num = s->delay_frames[0]->avframe->display_picture_number; /* Too many delayed frames, so we display the frame with the lowest pts */ av_log(avctx, AV_LOG_ERROR, "Delay frame overflow\n"); delayed_frame = s->delay_frames[0]; for (i = 1; s->delay_frames[i]; i++) - if (s->delay_frames[i]->avframe.display_picture_number < min_num) - min_num = s->delay_frames[i]->avframe.display_picture_number; + if (s->delay_frames[i]->avframe->display_picture_number < min_num) + min_num = s->delay_frames[i]->avframe->display_picture_number; delayed_frame = remove_frame(s->delay_frames, min_num); add_frame(s->delay_frames, MAX_DELAY, s->current_picture); } if (delayed_frame) { - delayed_frame->avframe.reference ^= DELAYED_PIC_REF; - if((ret=av_frame_ref(data, &delayed_frame->avframe)) < 0) + delayed_frame->avframe->reference ^= DELAYED_PIC_REF; + if((ret=av_frame_ref(data, delayed_frame->avframe)) < 0) return ret; *got_frame = 1; } - } else if (s->current_picture->avframe.display_picture_number == s->frame_number) { + } else if (s->current_picture->avframe->display_picture_number == s->frame_number) { /* The right frame at the right time :-) */ - if((ret=av_frame_ref(data, &s->current_picture->avframe)) < 0) + if((ret=av_frame_ref(data, s->current_picture->avframe)) < 0) return ret; *got_frame = 1; } if (*got_frame) - s->frame_number = picture->avframe.display_picture_number + 1; + s->frame_number = picture->display_picture_number + 1; return buf_idx; } diff --git a/libavcodec/dnxhddec.c b/libavcodec/dnxhddec.c index 15e6c679e4..bef750af5c 100644 --- a/libavcodec/dnxhddec.c +++ b/libavcodec/dnxhddec.c @@ -35,6 +35,7 @@ typedef struct DNXHDContext { GetBitContext gb; 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 @@ -128,7 +129,7 @@ static int dnxhd_decode_header(DNXHDContext *ctx, AVFrame *frame, av_dlog(ctx->avctx, "width %d, height %d\n", ctx->width, ctx->height); 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_dsputil_init(&ctx->dsp, ctx->avctx); @@ -136,7 +137,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_dsputil_init(&ctx->dsp, ctx->avctx); @@ -311,7 +312,7 @@ static int dnxhd_decode_macroblock(DNXHDContext *ctx, AVFrame *frame, int x, int dest_u = frame->data[1] + ((y * dct_linesize_chroma) << 4) + (x << (3 + shift1)); dest_v = frame->data[2] + ((y * dct_linesize_chroma) << 4) + (x << (3 + shift1)); - if (ctx->cur_field) { + if (frame->interlaced_frame && ctx->cur_field) { dest_y += frame->linesize[0]; dest_u += frame->linesize[1]; dest_v += frame->linesize[2]; @@ -376,9 +377,15 @@ static int dnxhd_decode_frame(AVCodecContext *avctx, void *data, int *got_frame, 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; + } if (av_image_check_size(ctx->width, ctx->height, 0, avctx)) return -1; + avctx->pix_fmt = ctx->pix_fmt; avcodec_set_dimensions(avctx, ctx->width, ctx->height); if (first_field) { diff --git a/libavcodec/dnxhdenc.c b/libavcodec/dnxhdenc.c index 5cf6d8b0f3..b16c7ed97d 100644 --- a/libavcodec/dnxhdenc.c +++ b/libavcodec/dnxhdenc.c @@ -235,7 +235,7 @@ static av_cold int dnxhd_init_qmat(DNXHDEncContext *ctx, int lbias, int cbias) static av_cold int dnxhd_init_rc(DNXHDEncContext *ctx) { - FF_ALLOCZ_OR_GOTO(ctx->m.avctx, ctx->mb_rc, 8160*ctx->m.avctx->qmax*sizeof(RCEntry), fail); + FF_ALLOCZ_OR_GOTO(ctx->m.avctx, ctx->mb_rc, 8160*(ctx->m.avctx->qmax + 1)*sizeof(RCEntry), fail); if (ctx->m.avctx->mb_decision != FF_MB_DECISION_RD) FF_ALLOCZ_OR_GOTO(ctx->m.avctx, ctx->mb_cmp, ctx->m.mb_num*sizeof(RCCMPEntry), fail); @@ -329,9 +329,12 @@ static av_cold int dnxhd_encode_init(AVCodecContext *avctx) FF_ALLOCZ_OR_GOTO(ctx->m.avctx, ctx->mb_bits, ctx->m.mb_num *sizeof(uint16_t), fail); FF_ALLOCZ_OR_GOTO(ctx->m.avctx, ctx->mb_qscale, ctx->m.mb_num *sizeof(uint8_t), fail); - ctx->frame.key_frame = 1; - ctx->frame.pict_type = AV_PICTURE_TYPE_I; - ctx->m.avctx->coded_frame = &ctx->frame; + avctx->coded_frame = av_frame_alloc(); + if (!avctx->coded_frame) + return AVERROR(ENOMEM); + + avctx->coded_frame->key_frame = 1; + avctx->coded_frame->pict_type = AV_PICTURE_TYPE_I; if (avctx->thread_count > MAX_THREADS) { av_log(avctx, AV_LOG_ERROR, "too many threads\n"); @@ -922,19 +925,14 @@ static void dnxhd_load_picture(DNXHDEncContext *ctx, const AVFrame *frame) { int i; - for (i = 0; i < 3; i++) { - ctx->frame.data[i] = frame->data[i]; - ctx->frame.linesize[i] = frame->linesize[i]; - } - for (i = 0; i < ctx->m.avctx->thread_count; i++) { - ctx->thread[i]->m.linesize = ctx->frame.linesize[0]<interlaced; - ctx->thread[i]->m.uvlinesize = ctx->frame.linesize[1]<interlaced; + ctx->thread[i]->m.linesize = frame->linesize[0] << ctx->interlaced; + ctx->thread[i]->m.uvlinesize = frame->linesize[1] << ctx->interlaced; ctx->thread[i]->dct_y_offset = ctx->m.linesize *8; ctx->thread[i]->dct_uv_offset = ctx->m.uvlinesize*8; } - ctx->frame.interlaced_frame = frame->interlaced_frame; + ctx->m.avctx->coded_frame->interlaced_frame = frame->interlaced_frame; ctx->cur_field = frame->interlaced_frame && !frame->top_field_first; } @@ -954,9 +952,9 @@ static int dnxhd_encode_picture(AVCodecContext *avctx, AVPacket *pkt, encode_coding_unit: for (i = 0; i < 3; i++) { - ctx->src[i] = ctx->frame.data[i]; + ctx->src[i] = frame->data[i]; if (ctx->interlaced && ctx->cur_field) - ctx->src[i] += ctx->frame.linesize[i]; + ctx->src[i] += frame->linesize[i]; } dnxhd_write_header(avctx, buf); @@ -994,7 +992,7 @@ static int dnxhd_encode_picture(AVCodecContext *avctx, AVPacket *pkt, goto encode_coding_unit; } - ctx->frame.quality = ctx->qscale*FF_QP2LAMBDA; + avctx->coded_frame->quality = ctx->qscale * FF_QP2LAMBDA; pkt->flags |= AV_PKT_FLAG_KEY; *got_packet = 1; @@ -1027,6 +1025,8 @@ static av_cold int dnxhd_encode_end(AVCodecContext *avctx) for (i = 1; i < avctx->thread_count; i++) av_freep(&ctx->thread[i]); + av_frame_free(&avctx->coded_frame); + return 0; } diff --git a/libavcodec/dnxhdenc.h b/libavcodec/dnxhdenc.h index 9b59b96d3e..110b0ad9e2 100644 --- a/libavcodec/dnxhdenc.h +++ b/libavcodec/dnxhdenc.h @@ -43,7 +43,6 @@ typedef struct DNXHDEncContext { AVClass *class; MpegEncContext m; ///< Used for quantization dsp functions - AVFrame frame; int cid; const CIDEntry *cid_table; uint8_t *msip; ///< Macroblock Scan Indexes Payload diff --git a/libavcodec/dsicinav.c b/libavcodec/dsicinav.c index 14bba55e1d..2d06ad8c10 100644 --- a/libavcodec/dsicinav.c +++ b/libavcodec/dsicinav.c @@ -39,7 +39,7 @@ typedef enum CinVideoBitmapIndex { typedef struct CinVideoContext { AVCodecContext *avctx; - AVFrame frame; + AVFrame *frame; unsigned int bitmap_size; uint32_t palette[256]; uint8_t *bitmap_table[3]; @@ -118,7 +118,9 @@ static av_cold int cinvideo_decode_init(AVCodecContext *avctx) cin->avctx = avctx; avctx->pix_fmt = AV_PIX_FMT_PAL8; - avcodec_get_frame_defaults(&cin->frame); + cin->frame = av_frame_alloc(); + if (!cin->frame) + return AVERROR(ENOMEM); cin->bitmap_size = avctx->width * avctx->height; if (allocate_buffers(cin)) @@ -315,20 +317,20 @@ static int cinvideo_decode_frame(AVCodecContext *avctx, break; } - if ((res = ff_reget_buffer(avctx, &cin->frame)) < 0) + if ((res = ff_reget_buffer(avctx, cin->frame)) < 0) return res; - memcpy(cin->frame.data[1], cin->palette, sizeof(cin->palette)); - cin->frame.palette_has_changed = 1; + memcpy(cin->frame->data[1], cin->palette, sizeof(cin->palette)); + cin->frame->palette_has_changed = 1; for (y = 0; y < cin->avctx->height; ++y) - memcpy(cin->frame.data[0] + (cin->avctx->height - 1 - y) * cin->frame.linesize[0], + memcpy(cin->frame->data[0] + (cin->avctx->height - 1 - y) * cin->frame->linesize[0], cin->bitmap_table[CIN_CUR_BMP] + y * cin->avctx->width, cin->avctx->width); FFSWAP(uint8_t *, cin->bitmap_table[CIN_CUR_BMP], cin->bitmap_table[CIN_PRE_BMP]); - if ((res = av_frame_ref(data, &cin->frame)) < 0) + if ((res = av_frame_ref(data, cin->frame)) < 0) return res; *got_frame = 1; @@ -340,7 +342,7 @@ static av_cold int cinvideo_decode_end(AVCodecContext *avctx) { CinVideoContext *cin = avctx->priv_data; - av_frame_unref(&cin->frame); + av_frame_free(&cin->frame); destroy_buffers(cin); diff --git a/libavcodec/dv.c b/libavcodec/dv.c index ba07c71905..fca01fe04f 100644 --- a/libavcodec/dv.c +++ b/libavcodec/dv.c @@ -320,8 +320,6 @@ av_cold int ff_dvvideo_init(AVCodecContext *avctx) }else memcpy(s->dv_zigzag[1], ff_zigzag248_direct, 64); - avcodec_get_frame_defaults(&s->picture); - avctx->coded_frame = &s->picture; s->avctx = avctx; avctx->chroma_sample_location = AVCHROMA_LOC_TOPLEFT; @@ -342,6 +340,10 @@ static av_cold int dvvideo_init_encoder(AVCodecContext *avctx) return AVERROR_PATCHWELCOME; } + avctx->coded_frame = av_frame_alloc(); + if (!avctx->coded_frame) + return AVERROR(ENOMEM); + dv_vlc_map_tableinit(); return ff_dvvideo_init(avctx); @@ -687,12 +689,12 @@ static int dv_encode_video_segment(AVCodecContext *avctx, void *arg) if ((s->sys->pix_fmt == AV_PIX_FMT_YUV420P) || (s->sys->pix_fmt == AV_PIX_FMT_YUV411P && mb_x >= (704 / 8)) || (s->sys->height >= 720 && mb_y != 134)) { - y_stride = s->picture.linesize[0] << 3; + y_stride = s->frame->linesize[0] << 3; } else { y_stride = 16; } - y_ptr = s->picture.data[0] + ((mb_y * s->picture.linesize[0] + mb_x) << 3); - linesize = s->picture.linesize[0]; + y_ptr = s->frame->data[0] + ((mb_y * s->frame->linesize[0] + mb_x) << 3); + linesize = s->frame->linesize[0]; if (s->sys->video_stype == 4) { /* SD 422 */ vs_bit_size += @@ -710,12 +712,12 @@ static int dv_encode_video_segment(AVCodecContext *avctx, void *arg) enc_blk += 4; /* initializing chrominance blocks */ - c_offset = (((mb_y >> (s->sys->pix_fmt == AV_PIX_FMT_YUV420P)) * s->picture.linesize[1] + + c_offset = (((mb_y >> (s->sys->pix_fmt == AV_PIX_FMT_YUV420P)) * s->frame->linesize[1] + (mb_x >> ((s->sys->pix_fmt == AV_PIX_FMT_YUV411P) ? 2 : 1))) << 3); for (j = 2; j; j--) { - uint8_t *c_ptr = s->picture.data[j] + c_offset; - linesize = s->picture.linesize[j]; - y_stride = (mb_y == 134) ? 8 : (s->picture.linesize[j] << 3); + uint8_t *c_ptr = s->frame->data[j] + c_offset; + linesize = s->frame->linesize[j]; + y_stride = (mb_y == 134) ? 8 : (s->frame->linesize[j] << 3); if (s->sys->pix_fmt == AV_PIX_FMT_YUV411P && mb_x >= (704 / 8)) { uint8_t* d; uint8_t* b = scratch; @@ -814,7 +816,7 @@ static inline int dv_write_pack(enum dv_pack_type pack_id, DVVideoContext *c, * compression scheme (if any). */ int apt = (c->sys->pix_fmt == AV_PIX_FMT_YUV420P ? 0 : 1); - int fs = c->picture.top_field_first ? 0x00 : 0x40; + int fs = c->frame->top_field_first ? 0x00 : 0x40; uint8_t aspect = 0; if ((int)(av_q2d(c->avctx->sample_aspect_ratio) * c->avctx->width / c->avctx->height * 10) >= 17) /* 16:9 */ @@ -963,10 +965,10 @@ static int dvvideo_encode_frame(AVCodecContext *c, AVPacket *pkt, if ((ret = ff_alloc_packet2(c, pkt, s->sys->frame_size)) < 0) return ret; - c->pix_fmt = s->sys->pix_fmt; - s->picture = *frame; - s->picture.key_frame = 1; - s->picture.pict_type = AV_PICTURE_TYPE_I; + c->pix_fmt = s->sys->pix_fmt; + s->frame = frame; + c->coded_frame->key_frame = 1; + c->coded_frame->pict_type = AV_PICTURE_TYPE_I; s->buf = pkt->data; c->execute(c, dv_encode_video_segment, s->sys->work_chunks, NULL, @@ -982,6 +984,12 @@ static int dvvideo_encode_frame(AVCodecContext *c, AVPacket *pkt, return 0; } +static int dvvideo_encode_close(AVCodecContext *avctx) +{ + av_frame_free(&avctx->coded_frame); + return 0; +} + AVCodec ff_dvvideo_encoder = { .name = "dvvideo", .long_name = NULL_IF_CONFIG_SMALL("DV (Digital Video)"), @@ -990,6 +998,7 @@ AVCodec ff_dvvideo_encoder = { .priv_data_size = sizeof(DVVideoContext), .init = dvvideo_init_encoder, .encode2 = dvvideo_encode_frame, + .close = dvvideo_encode_close, .capabilities = CODEC_CAP_SLICE_THREADS, .pix_fmts = (const enum AVPixelFormat[]) { AV_PIX_FMT_YUV411P, AV_PIX_FMT_YUV422P, AV_PIX_FMT_YUV420P, AV_PIX_FMT_NONE diff --git a/libavcodec/dvdata.h b/libavcodec/dvdata.h index 97c20e3a1a..448c640bca 100644 --- a/libavcodec/dvdata.h +++ b/libavcodec/dvdata.h @@ -34,7 +34,7 @@ typedef struct DVVideoContext { const DVprofile *sys; - AVFrame picture; + AVFrame *frame; AVCodecContext *avctx; uint8_t *buf; diff --git a/libavcodec/dvdec.c b/libavcodec/dvdec.c index b86926a5a7..4f424fc30e 100644 --- a/libavcodec/dvdec.c +++ b/libavcodec/dvdec.c @@ -258,12 +258,12 @@ static int dv_decode_video_segment(AVCodecContext *avctx, void *arg) if ((s->sys->pix_fmt == AV_PIX_FMT_YUV420P) || (s->sys->pix_fmt == AV_PIX_FMT_YUV411P && mb_x >= (704 / 8)) || (s->sys->height >= 720 && mb_y != 134)) { - y_stride = (s->picture.linesize[0] << ((!is_field_mode[mb_index]) * log2_blocksize)); + y_stride = (s->frame->linesize[0] << ((!is_field_mode[mb_index]) * log2_blocksize)); } else { y_stride = (2 << log2_blocksize); } - y_ptr = s->picture.data[0] + ((mb_y * s->picture.linesize[0] + mb_x) << log2_blocksize); - linesize = s->picture.linesize[0] << is_field_mode[mb_index]; + y_ptr = s->frame->data[0] + ((mb_y * s->frame->linesize[0] + mb_x) << log2_blocksize); + linesize = s->frame->linesize[0] << is_field_mode[mb_index]; mb[0] .idct_put(y_ptr , linesize, block + 0*64); if (s->sys->video_stype == 4) { /* SD 422 */ mb[2].idct_put(y_ptr + (1 << log2_blocksize) , linesize, block + 2*64); @@ -276,19 +276,19 @@ static int dv_decode_video_segment(AVCodecContext *avctx, void *arg) block += 4*64; /* idct_put'ting chrominance */ - c_offset = (((mb_y >> (s->sys->pix_fmt == AV_PIX_FMT_YUV420P)) * s->picture.linesize[1] + + c_offset = (((mb_y >> (s->sys->pix_fmt == AV_PIX_FMT_YUV420P)) * s->frame->linesize[1] + (mb_x >> ((s->sys->pix_fmt == AV_PIX_FMT_YUV411P) ? 2 : 1))) << log2_blocksize); for (j = 2; j; j--) { - uint8_t *c_ptr = s->picture.data[j] + c_offset; + uint8_t *c_ptr = s->frame->data[j] + c_offset; if (s->sys->pix_fmt == AV_PIX_FMT_YUV411P && mb_x >= (704 / 8)) { uint64_t aligned_pixels[64/8]; uint8_t *pixels = (uint8_t*)aligned_pixels; uint8_t *c_ptr1, *ptr1; int x, y; mb->idct_put(pixels, 8, block); - for (y = 0; y < (1 << log2_blocksize); y++, c_ptr += s->picture.linesize[j], pixels += 8) { + for (y = 0; y < (1 << log2_blocksize); y++, c_ptr += s->frame->linesize[j], pixels += 8) { ptr1 = pixels + ((1 << (log2_blocksize))>>1); - c_ptr1 = c_ptr + (s->picture.linesize[j] << log2_blocksize); + c_ptr1 = c_ptr + (s->frame->linesize[j] << log2_blocksize); for (x = 0; x < (1 << FFMAX(log2_blocksize - 1, 0)); x++) { c_ptr[x] = pixels[x]; c_ptr1[x] = ptr1[x]; @@ -297,8 +297,8 @@ static int dv_decode_video_segment(AVCodecContext *avctx, void *arg) block += 64; mb++; } else { y_stride = (mb_y == 134) ? (1 << log2_blocksize) : - s->picture.linesize[j] << ((!is_field_mode[mb_index]) * log2_blocksize); - linesize = s->picture.linesize[j] << is_field_mode[mb_index]; + s->frame->linesize[j] << ((!is_field_mode[mb_index]) * log2_blocksize); + linesize = s->frame->linesize[j] << is_field_mode[mb_index]; (mb++)-> idct_put(c_ptr , linesize, block); block += 64; if (s->sys->bpm == 8) { (mb++)->idct_put(c_ptr + y_stride, linesize, block); block += 64; @@ -327,15 +327,16 @@ static int dvvideo_decode_frame(AVCodecContext *avctx, return -1; /* NOTE: we only accept several full frames */ } - s->picture.key_frame = 1; - s->picture.pict_type = AV_PICTURE_TYPE_I; + s->frame = data; + s->frame->key_frame = 1; + s->frame->pict_type = AV_PICTURE_TYPE_I; avctx->pix_fmt = s->sys->pix_fmt; avctx->time_base = s->sys->time_base; avcodec_set_dimensions(avctx, s->sys->width, s->sys->height); - if ((ret = ff_get_buffer(avctx, &s->picture, 0)) < 0) + if ((ret = ff_get_buffer(avctx, s->frame, 0)) < 0) return ret; - s->picture.interlaced_frame = 1; - s->picture.top_field_first = 0; + s->frame->interlaced_frame = 1; + s->frame->top_field_first = 0; /* Determine the codec's sample_aspect ratio and field order from the packet */ vsc_pack = buf + 80*5 + 48 + 5; @@ -343,7 +344,7 @@ static int dvvideo_decode_frame(AVCodecContext *avctx, apt = buf[4] & 0x07; is16_9 = (vsc_pack[2] & 0x07) == 0x02 || (!apt && (vsc_pack[2] & 0x07) == 0x07); avctx->sample_aspect_ratio = s->sys->sar[is16_9]; - s->picture.top_field_first = !(vsc_pack[3] & 0x40); + s->frame->top_field_first = !(vsc_pack[3] & 0x40); } s->buf = buf; @@ -354,20 +355,10 @@ static int dvvideo_decode_frame(AVCodecContext *avctx, /* return image */ *got_frame = 1; - av_frame_move_ref(data, &s->picture); return s->sys->frame_size; } -static int dvvideo_close(AVCodecContext *c) -{ - DVVideoContext *s = c->priv_data; - - av_frame_unref(&s->picture); - - return 0; -} - AVCodec ff_dvvideo_decoder = { .name = "dvvideo", .long_name = NULL_IF_CONFIG_SMALL("DV (Digital Video)"), @@ -375,7 +366,6 @@ AVCodec ff_dvvideo_decoder = { .id = AV_CODEC_ID_DVVIDEO, .priv_data_size = sizeof(DVVideoContext), .init = ff_dvvideo_init, - .close = dvvideo_close, .decode = dvvideo_decode_frame, .capabilities = CODEC_CAP_DR1 | CODEC_CAP_SLICE_THREADS, .max_lowres = 3, 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 f0dd289139..524930867d 100644 --- a/libavcodec/dvdsubdec.c +++ b/libavcodec/dvdsubdec.c @@ -35,7 +35,7 @@ typedef struct DVDSubContext int has_palette; uint8_t colormap[4]; uint8_t alpha[256]; - uint8_t *buf; + uint8_t buf[0x10000]; int buf_size; #ifdef DEBUG int sub_id; @@ -103,6 +103,12 @@ 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; + + if (w <= 0 || h <= 0) + return -1; + bit_len = (buf_size - start) * 8; init_get_bits(&gb, buf + start, bit_len); @@ -354,10 +360,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) @@ -495,15 +503,11 @@ static int append_to_cached_buf(AVCodecContext *avctx, { DVDSubContext *ctx = avctx->priv_data; - if (ctx->buf_size > 0xffff - buf_size) { + if (ctx->buf_size >= sizeof(ctx->buf) - buf_size) { av_log(avctx, AV_LOG_WARNING, "Attempt to reconstruct " "too large SPU packets aborted.\n"); - av_freep(&ctx->buf); return AVERROR_INVALIDDATA; } - ctx->buf = av_realloc(ctx->buf, ctx->buf_size + buf_size); - if (!ctx->buf) - return AVERROR(ENOMEM); memcpy(ctx->buf + ctx->buf_size, buf, buf_size); ctx->buf_size += buf_size; return 0; @@ -519,7 +523,7 @@ static int dvdsub_decode(AVCodecContext *avctx, AVSubtitle *sub = data; int is_menu; - if (ctx->buf) { + if (ctx->buf_size) { int ret = append_to_cached_buf(avctx, buf, buf_size); if (ret < 0) { *data_size = 0; @@ -557,7 +561,6 @@ static int dvdsub_decode(AVCodecContext *avctx, } #endif - av_freep(&ctx->buf); ctx->buf_size = 0; *data_size = 1; return buf_size; @@ -635,7 +638,6 @@ static av_cold int dvdsub_init(AVCodecContext *avctx) static av_cold int dvdsub_close(AVCodecContext *avctx) { DVDSubContext *ctx = avctx->priv_data; - av_freep(&ctx->buf); ctx->buf_size = 0; return 0; } diff --git a/libavcodec/dxa.c b/libavcodec/dxa.c index 2704852768..ff7581f757 100644 --- a/libavcodec/dxa.c +++ b/libavcodec/dxa.c @@ -321,12 +321,17 @@ static av_cold int decode_init(AVCodecContext *avctx) { DxaDecContext * const c = avctx->priv_data; - avctx->pix_fmt = AV_PIX_FMT_PAL8; + 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); + avctx->pix_fmt = AV_PIX_FMT_PAL8; + c->dsize = avctx->width * avctx->height * 2; c->decomp_buf = av_malloc(c->dsize); if (!c->decomp_buf) { diff --git a/libavcodec/eamad.c b/libavcodec/eamad.c index 6d8291e514..cfdb4c5f16 100644 --- a/libavcodec/eamad.c +++ b/libavcodec/eamad.c @@ -45,7 +45,7 @@ typedef struct MadContext { AVCodecContext *avctx; DSPContext dsp; - AVFrame last_frame; + AVFrame *last_frame; GetBitContext gb; void *bitstream_buf; unsigned int bitstream_buf_size; @@ -65,6 +65,11 @@ static av_cold int decode_init(AVCodecContext *avctx) ff_init_scantable_permutation(s->dsp.idct_permutation, FF_NO_IDCT_PERM); ff_init_scantable(s->dsp.idct_permutation, &s->scantable, ff_zigzag_direct); ff_mpeg12_init_vlcs(); + + s->last_frame = av_frame_alloc(); + if (!s->last_frame) + return AVERROR(ENOMEM); + return 0; } @@ -82,22 +87,22 @@ static inline void comp_block(MadContext *t, AVFrame *frame, int j, int mv_x, int mv_y, int add) { if (j < 4) { - unsigned offset = (mb_y*16 + ((j&2)<<2) + mv_y)*t->last_frame.linesize[0] + mb_x*16 + ((j&1)<<3) + mv_x; - if (offset >= (t->avctx->height - 7) * t->last_frame.linesize[0] - 7) + unsigned offset = (mb_y*16 + ((j&2)<<2) + mv_y)*t->last_frame->linesize[0] + mb_x*16 + ((j&1)<<3) + mv_x; + if (offset >= (t->avctx->height - 7) * t->last_frame->linesize[0] - 7) return; comp(frame->data[0] + (mb_y*16 + ((j&2)<<2))*frame->linesize[0] + mb_x*16 + ((j&1)<<3), frame->linesize[0], - t->last_frame.data[0] + offset, - t->last_frame.linesize[0], add); + t->last_frame->data[0] + offset, + t->last_frame->linesize[0], add); } else if (!(t->avctx->flags & CODEC_FLAG_GRAY)) { int index = j - 3; - unsigned offset = (mb_y * 8 + (mv_y/2))*t->last_frame.linesize[index] + mb_x * 8 + (mv_x/2); - if (offset >= (t->avctx->height/2 - 7) * t->last_frame.linesize[index] - 7) + unsigned offset = (mb_y * 8 + (mv_y/2))*t->last_frame->linesize[index] + mb_x * 8 + (mv_x/2); + if (offset >= (t->avctx->height/2 - 7) * t->last_frame->linesize[index] - 7) return; comp(frame->data[index] + (mb_y*8)*frame->linesize[index] + mb_x * 8, frame->linesize[index], - t->last_frame.data[index] + offset, - t->last_frame.linesize[index], add); + t->last_frame->data[index] + offset, + t->last_frame->linesize[index], add); } } @@ -205,7 +210,7 @@ static int decode_mb(MadContext *s, AVFrame *frame, int inter) for (j=0; j<6; j++) { if (mv_map & (1<gb); - if (s->last_frame.data[0]) + if (s->last_frame->data[0]) comp_block(s, frame, s->mb_x, s->mb_y, j, mv_x, mv_y, add); } else { s->dsp.clear_block(s->block); @@ -263,28 +268,28 @@ static int decode_frame(AVCodecContext *avctx, } if (avctx->width != width || avctx->height != height) { + av_frame_unref(s->last_frame); if((width * height)/2048*7 > buf_end-buf) return AVERROR_INVALIDDATA; if ((ret = av_image_check_size(width, height, 0, avctx)) < 0) return ret; avcodec_set_dimensions(avctx, width, height); - av_frame_unref(&s->last_frame); } if ((ret = ff_get_buffer(avctx, frame, AV_GET_BUFFER_FLAG_REF)) < 0) return ret; - if (inter && !s->last_frame.data[0]) { + if (inter && !s->last_frame->data[0]) { av_log(avctx, AV_LOG_WARNING, "Missing reference frame.\n"); - ret = ff_get_buffer(avctx, &s->last_frame, AV_GET_BUFFER_FLAG_REF); + ret = ff_get_buffer(avctx, s->last_frame, AV_GET_BUFFER_FLAG_REF); if (ret < 0) return ret; - memset(s->last_frame.data[0], 0, s->last_frame.height * - s->last_frame.linesize[0]); - memset(s->last_frame.data[1], 0x80, s->last_frame.height / 2 * - s->last_frame.linesize[1]); - memset(s->last_frame.data[2], 0x80, s->last_frame.height / 2 * - s->last_frame.linesize[2]); + memset(s->last_frame->data[0], 0, s->last_frame->height * + s->last_frame->linesize[0]); + memset(s->last_frame->data[1], 0x80, s->last_frame->height / 2 * + s->last_frame->linesize[1]); + memset(s->last_frame->data[2], 0x80, s->last_frame->height / 2 * + s->last_frame->linesize[2]); } av_fast_padded_malloc(&s->bitstream_buf, &s->bitstream_buf_size, @@ -303,8 +308,8 @@ static int decode_frame(AVCodecContext *avctx, *got_frame = 1; if (chunk_type != MADe_TAG) { - av_frame_unref(&s->last_frame); - if ((ret = av_frame_ref(&s->last_frame, frame)) < 0) + av_frame_unref(s->last_frame); + if ((ret = av_frame_ref(s->last_frame, frame)) < 0) return ret; } @@ -314,7 +319,7 @@ static int decode_frame(AVCodecContext *avctx, static av_cold int decode_end(AVCodecContext *avctx) { MadContext *t = avctx->priv_data; - av_frame_unref(&t->last_frame); + av_frame_free(&t->last_frame); av_free(t->bitstream_buf); return 0; } diff --git a/libavcodec/eatgv.c b/libavcodec/eatgv.c index bfdfb76b9b..8d898aba16 100644 --- a/libavcodec/eatgv.c +++ b/libavcodec/eatgv.c @@ -40,7 +40,7 @@ typedef struct TgvContext { AVCodecContext *avctx; - AVFrame last_frame; + AVFrame *last_frame; uint8_t *frame_buffer; int width,height; uint32_t palette[AVPALETTE_COUNT]; @@ -57,7 +57,11 @@ static av_cold int tgv_decode_init(AVCodecContext *avctx) s->avctx = avctx; avctx->time_base = (AVRational){1, 15}; avctx->pix_fmt = AV_PIX_FMT_PAL8; - avcodec_get_frame_defaults(&s->last_frame); + + s->last_frame = av_frame_alloc(); + if (!s->last_frame) + return AVERROR(ENOMEM); + return 0; } @@ -232,8 +236,8 @@ static int tgv_decode_inter(TgvContext *s, AVFrame *frame, continue; } - src = s->last_frame.data[0] + mx + my * s->last_frame.linesize[0]; - src_stride = s->last_frame.linesize[0]; + src = s->last_frame->data[0] + mx + my * s->last_frame->linesize[0]; + src_stride = s->last_frame->linesize[0]; } else { int offset = vector - num_mvs; if (offset < num_blocks_raw) @@ -283,7 +287,7 @@ static int tgv_decode_frame(AVCodecContext *avctx, if (s->avctx->width != s->width || s->avctx->height != s->height) { avcodec_set_dimensions(s->avctx, s->width, s->height); av_freep(&s->frame_buffer); - av_frame_unref(&s->last_frame); + av_frame_unref(s->last_frame); } pal_count = AV_RL16(&buf[6]); @@ -320,7 +324,7 @@ static int tgv_decode_frame(AVCodecContext *avctx, s->frame_buffer + y * s->width, s->width); } else { - if (!s->last_frame.data[0]) { + if (!s->last_frame->data[0]) { av_log(avctx, AV_LOG_WARNING, "inter frame without corresponding intra frame\n"); return buf_size; } @@ -332,8 +336,8 @@ static int tgv_decode_frame(AVCodecContext *avctx, } } - av_frame_unref(&s->last_frame); - if ((ret = av_frame_ref(&s->last_frame, frame)) < 0) + av_frame_unref(s->last_frame); + if ((ret = av_frame_ref(s->last_frame, frame)) < 0) return ret; *got_frame = 1; @@ -344,7 +348,7 @@ static int tgv_decode_frame(AVCodecContext *avctx, static av_cold int tgv_decode_end(AVCodecContext *avctx) { TgvContext *s = avctx->priv_data; - av_frame_unref(&s->last_frame); + av_frame_free(&s->last_frame); av_freep(&s->frame_buffer); av_free(s->mv_codebook); av_free(s->block_codebook); diff --git a/libavcodec/error_resilience.c b/libavcodec/error_resilience.c index 23180dc273..70fbaf72dd 100644 --- a/libavcodec/error_resilience.c +++ b/libavcodec/error_resilience.c @@ -762,6 +762,17 @@ void ff_er_frame_start(ERContext *s) s->error_occurred = 0; } +static int er_supported(ERContext *s) +{ + if(s->avctx->hwaccel || + s->avctx->codec->capabilities&CODEC_CAP_HWACCEL_VDPAU || + !s->cur_pic || + s->cur_pic->field_picture + ) + return 0; + return 1; +} + /** * Add a slice. * @param endx x component of the last macroblock, can be -1 @@ -828,7 +839,7 @@ void ff_er_add_slice(ERContext *s, int startx, int starty, s->error_status_table[start_xy] |= VP_START; if (start_xy > 0 && !(s->avctx->active_thread_type & FF_THREAD_SLICE) && - s->avctx->skip_top * s->mb_width < start_i) { + er_supported(s) && s->avctx->skip_top * s->mb_width < start_i) { int prev_status = s->error_status_table[s->mb_index2xy[start_i - 1]]; prev_status &= ~ VP_START; @@ -853,9 +864,7 @@ void ff_er_frame_end(ERContext *s) * though it should not crash if enabled. */ if (!s->avctx->error_concealment || s->error_count == 0 || s->avctx->lowres || - s->avctx->hwaccel || - s->avctx->codec->capabilities&CODEC_CAP_HWACCEL_VDPAU || - !s->cur_pic || s->cur_pic->field_picture || + !er_supported(s) || s->error_count == 3 * s->mb_width * (s->avctx->skip_top + s->avctx->skip_bottom)) { return; diff --git a/libavcodec/escape124.c b/libavcodec/escape124.c index a050fcb4e9..bed1efb5c8 100644 --- a/libavcodec/escape124.c +++ b/libavcodec/escape124.c @@ -42,7 +42,7 @@ typedef struct CodeBook { } CodeBook; typedef struct Escape124Context { - AVFrame frame; + AVFrame *frame; unsigned num_superblocks; @@ -58,12 +58,15 @@ static av_cold int escape124_decode_init(AVCodecContext *avctx) { Escape124Context *s = avctx->priv_data; - avcodec_get_frame_defaults(&s->frame); avctx->pix_fmt = AV_PIX_FMT_RGB555; s->num_superblocks = ((unsigned)avctx->width / 8) * ((unsigned)avctx->height / 8); + s->frame = av_frame_alloc(); + if (!s->frame) + return AVERROR(ENOMEM); + return 0; } @@ -75,7 +78,7 @@ static av_cold int escape124_decode_close(AVCodecContext *avctx) for (i = 0; i < 3; i++) av_free(s->codebooks[i].blocks); - av_frame_unref(&s->frame); + av_frame_free(&s->frame); return 0; } @@ -227,13 +230,13 @@ static int escape124_decode_frame(AVCodecContext *avctx, // Leave last frame unchanged // FIXME: Is this necessary? I haven't seen it in any real samples if (!(frame_flags & 0x114) || !(frame_flags & 0x7800000)) { - if (!s->frame.data[0]) + if (!s->frame->data[0]) return AVERROR_INVALIDDATA; av_log(avctx, AV_LOG_DEBUG, "Skipping frame\n"); *got_frame = 1; - if ((ret = av_frame_ref(frame, &s->frame)) < 0) + if ((ret = av_frame_ref(frame, s->frame)) < 0) return ret; return frame_size; @@ -272,8 +275,8 @@ static int escape124_decode_frame(AVCodecContext *avctx, new_frame_data = (uint16_t*)frame->data[0]; new_stride = frame->linesize[0] / 2; - old_frame_data = (uint16_t*)s->frame.data[0]; - old_stride = s->frame.linesize[0] / 2; + old_frame_data = (uint16_t*)s->frame->data[0]; + old_stride = s->frame->linesize[0] / 2; for (superblock_index = 0; superblock_index < s->num_superblocks; superblock_index++) { @@ -350,8 +353,8 @@ static int escape124_decode_frame(AVCodecContext *avctx, "Escape sizes: %i, %i, %i\n", frame_size, buf_size, get_bits_count(&gb) / 8); - av_frame_unref(&s->frame); - if ((ret = av_frame_ref(&s->frame, frame)) < 0) + av_frame_unref(s->frame); + if ((ret = av_frame_ref(s->frame, frame)) < 0) return ret; *got_frame = 1; diff --git a/libavcodec/faxcompr.c b/libavcodec/faxcompr.c index 900851b3f1..d2ba7068ca 100644 --- a/libavcodec/faxcompr.c +++ b/libavcodec/faxcompr.c @@ -251,7 +251,7 @@ static void put_line(uint8_t *dst, int size, int width, const int *runs) PutBitContext pb; int run, mode = ~0, pix_left = width, run_idx = 0; - init_put_bits(&pb, dst, size * 8); + init_put_bits(&pb, dst, size); while (pix_left > 0) { run = runs[run_idx++]; mode = ~mode; diff --git a/libavcodec/ffv1.c b/libavcodec/ffv1.c index 9f3206f92c..ed0f29a5c5 100644 --- a/libavcodec/ffv1.c +++ b/libavcodec/ffv1.c @@ -53,6 +53,7 @@ av_cold int ffv1_common_init(AVCodecContext *avctx) s->last_picture.f = av_frame_alloc(); if (!s->picture.f || !s->last_picture.f) return AVERROR(ENOMEM); + ff_dsputil_init(&s->dsp, avctx); s->width = avctx->width; @@ -102,7 +103,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); @@ -114,10 +115,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; @@ -202,7 +203,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]; @@ -216,14 +217,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 bdc7b862d0..d859bd2e60 100644 --- a/libavcodec/ffv1.h +++ b/libavcodec/ffv1.h @@ -122,6 +122,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 0add4ffa57..ffba37f033 100644 --- a/libavcodec/ffv1dec.c +++ b/libavcodec/ffv1dec.c @@ -533,8 +533,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]); @@ -737,6 +740,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 { @@ -751,8 +755,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; } @@ -938,12 +942,12 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame, AVPac uint8_t *dst[4]; ff_thread_await_progress(&f->last_picture, INT_MAX, 0); for (j = 0; j < 4; j++) { - int sh = (j==1 || j==2) ? f->chroma_h_shift : 0; - int sv = (j==1 || j==2) ? f->chroma_v_shift : 0; - dst[j] = p->data[j] + p->linesize[j]* - (fs->slice_y>>sv) + (fs->slice_x>>sh); - src[j] = f->last_picture.f->data[j] + f->last_picture.f->linesize[j]* - (fs->slice_y>>sv) + (fs->slice_x>>sh); + int sh = (j == 1 || j == 2) ? f->chroma_h_shift : 0; + int sv = (j == 1 || j == 2) ? f->chroma_v_shift : 0; + dst[j] = p->data[j] + p->linesize[j] * + (fs->slice_y >> sv) + (fs->slice_x >> sh); + src[j] = f->last_picture.f->data[j] + f->last_picture.f->linesize[j] * + (fs->slice_y >> sv) + (fs->slice_x >> sh); } av_image_copy(dst, p->linesize, (const uint8_t **)src, f->last_picture.f->linesize, @@ -975,6 +979,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++) { @@ -1045,7 +1050,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 59d2869dc1..c7d6ada20d 100644 --- a/libavcodec/ffv1enc.c +++ b/libavcodec/ffv1enc.c @@ -771,6 +771,10 @@ static av_cold int encode_init(AVCodecContext *avctx) s->colorspace = 1; s->chroma_planes = 1; s->version = FFMAX(s->version, 1); + if (!s->ac) { + av_log(avctx, AV_LOG_ERROR, "bits_per_raw_sample of more than 8 needs -coder 1 currently\n"); + return AVERROR(ENOSYS); + } break; default: av_log(avctx, AV_LOG_ERROR, "format not supported\n"); @@ -826,6 +830,12 @@ static av_cold int encode_init(AVCodecContext *avctx) if ((ret = ffv1_allocate_initial_states(s)) < 0) return ret; + avctx->coded_frame = av_frame_alloc(); + if (!avctx->coded_frame) + return AVERROR(ENOMEM); + + avctx->coded_frame->pict_type = AV_PICTURE_TYPE_I; + if (!s->transparency) s->plane_count = 2; if (!s->chroma_planes && s->version > 3) @@ -937,6 +947,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; @@ -946,7 +957,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] * @@ -996,7 +1007,7 @@ static int encode_slice(AVCodecContext *c, void *arg) int height = fs->slice_height; int x = fs->slice_x; int y = fs->slice_y; - AVFrame *const p = f->picture.f; + const AVFrame *const p = f->picture.f; const int ps = av_pix_fmt_desc_get(c->pix_fmt)->comp[0].step_minus1 + 1; int ret; RangeCoder c_bak = fs->c; @@ -1004,7 +1015,7 @@ static int encode_slice(AVCodecContext *c, void *arg) fs->slice_coding_mode = 0; retry: - if (p->key_frame) + if (c->coded_frame->key_frame) ffv1_clear_slice_state(f, fs); if (f->version > 2) { encode_slice_header(f, fs); @@ -1080,16 +1091,16 @@ static int encode_frame(AVCodecContext *avctx, AVPacket *pkt, av_frame_unref(p); if ((ret = av_frame_ref(p, pict)) < 0) return ret; - p->pict_type = AV_PICTURE_TYPE_I; + avctx->coded_frame->pict_type = AV_PICTURE_TYPE_I; if (avctx->gop_size == 0 || f->picture_number % avctx->gop_size == 0) { put_rac(c, &keystate, 1); - p->key_frame = 1; + avctx->coded_frame->key_frame = 1; f->gob_count++; write_header(f); } else { put_rac(c, &keystate, 0); - p->key_frame = 0; + avctx->coded_frame->key_frame = 0; } if (f->ac > 1) { @@ -1184,12 +1195,19 @@ static int encode_frame(AVCodecContext *avctx, AVPacket *pkt, f->picture_number++; pkt->size = buf_p - pkt->data; - pkt->flags |= AV_PKT_FLAG_KEY * p->key_frame; + pkt->flags |= AV_PKT_FLAG_KEY * avctx->coded_frame->key_frame; *got_packet = 1; return 0; } +static av_cold int encode_close(AVCodecContext *avctx) +{ + av_frame_free(&avctx->coded_frame); + ffv1_close(avctx); + return 0; +} + #define OFFSET(x) offsetof(FFV1Context, x) #define VE AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_ENCODING_PARAM static const AVOption options[] = { @@ -1217,7 +1235,7 @@ AVCodec ff_ffv1_encoder = { .priv_data_size = sizeof(FFV1Context), .init = encode_init, .encode2 = encode_frame, - .close = ffv1_close, + .close = encode_close, .capabilities = CODEC_CAP_SLICE_THREADS, .pix_fmts = (const enum AVPixelFormat[]) { AV_PIX_FMT_YUV420P, AV_PIX_FMT_YUVA420P, AV_PIX_FMT_YUVA422P, AV_PIX_FMT_YUV444P, diff --git a/libavcodec/ffwavesynth.c b/libavcodec/ffwavesynth.c index a62746d61c..4a5031a8ca 100644 --- a/libavcodec/ffwavesynth.c +++ b/libavcodec/ffwavesynth.c @@ -93,7 +93,6 @@ struct wavesynth_context { int64_t cur_ts; int64_t next_ts; int32_t *sin; - AVFrame frame; struct ws_interval *inter; uint32_t dither_state; uint32_t pink_state; @@ -341,8 +340,6 @@ static av_cold int wavesynth_init(AVCodecContext *avc) ws->pink_need += ws->inter[i].type == WS_NOISE; ws->pink_state = MKTAG('P','I','N','K'); ws->pink_pos = PINK_UNIT; - avcodec_get_frame_defaults(&ws->frame); - avc->coded_frame = &ws->frame; wavesynth_seek(ws, 0); avc->sample_fmt = AV_SAMPLE_FMT_S16; return 0; @@ -428,6 +425,7 @@ static int wavesynth_decode(AVCodecContext *avc, void *rframe, int *rgot_frame, AVPacket *packet) { struct wavesynth_context *ws = avc->priv_data; + AVFrame *frame = rframe; int64_t ts; int duration; int s, c, r; @@ -443,11 +441,11 @@ static int wavesynth_decode(AVCodecContext *avc, void *rframe, int *rgot_frame, duration = AV_RL32(packet->data + 8); if (duration <= 0) return AVERROR(EINVAL); - ws->frame.nb_samples = duration; - r = ff_get_buffer(avc, &ws->frame, 0); + frame->nb_samples = duration; + r = ff_get_buffer(avc, frame, 0); if (r < 0) return r; - pcm = (int16_t *)ws->frame.data[0]; + pcm = (int16_t *)frame->data[0]; for (s = 0; s < duration; s++, ts++) { memset(channels, 0, avc->channels * sizeof(*channels)); if (ts >= ws->next_ts) @@ -458,7 +456,6 @@ static int wavesynth_decode(AVCodecContext *avc, void *rframe, int *rgot_frame, } ws->cur_ts += duration; *rgot_frame = 1; - *(AVFrame *)rframe = ws->frame; return packet->size; } diff --git a/libavcodec/flac_parser.c b/libavcodec/flac_parser.c index ba1f060fd9..0512575d85 100644 --- a/libavcodec/flac_parser.c +++ b/libavcodec/flac_parser.c @@ -685,7 +685,7 @@ static int flac_parse(AVCodecParserContext *s, AVCodecContext *avctx, handle_error: *poutbuf = NULL; *poutbuf_size = 0; - return read_end - buf; + return buf_size ? read_end - buf : 0; } static av_cold int flac_parse_init(AVCodecParserContext *c) diff --git a/libavcodec/flacdec.c b/libavcodec/flacdec.c index 9bf950ae3e..bd246f7af6 100644 --- a/libavcodec/flacdec.c +++ b/libavcodec/flacdec.c @@ -465,10 +465,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/flashsv.c b/libavcodec/flashsv.c index 3d185d5184..65b9da42dd 100644 --- a/libavcodec/flashsv.c +++ b/libavcodec/flashsv.c @@ -50,7 +50,7 @@ typedef struct BlockInfo { typedef struct FlashSVContext { AVCodecContext *avctx; - AVFrame frame; + AVFrame *frame; int image_width, image_height; int block_width, block_height; uint8_t *tmpblock; @@ -100,6 +100,19 @@ static int decode_hybrid(const uint8_t *sptr, uint8_t *dptr, int dx, int dy, return sptr - orig_src; } +static av_cold int flashsv_decode_end(AVCodecContext *avctx) +{ + FlashSVContext *s = avctx->priv_data; + inflateEnd(&s->zstream); + /* release the frame if needed */ + av_frame_free(&s->frame); + + /* free the tmpblock */ + av_freep(&s->tmpblock); + + return 0; +} + static av_cold int flashsv_decode_init(AVCodecContext *avctx) { FlashSVContext *s = avctx->priv_data; @@ -115,7 +128,12 @@ static av_cold int flashsv_decode_init(AVCodecContext *avctx) return 1; } avctx->pix_fmt = AV_PIX_FMT_BGR24; - avcodec_get_frame_defaults(&s->frame); + + s->frame = av_frame_alloc(); + if (!s->frame) { + flashsv_decode_end(avctx); + return AVERROR(ENOMEM); + } return 0; } @@ -205,18 +223,18 @@ static int flashsv_decode_block(AVCodecContext *avctx, AVPacket *avpkt, /* Flash Screen Video stores the image upside down, so copy * lines to destination in reverse order. */ for (k = 1; k <= s->diff_height; k++) { - memcpy(s->frame.data[0] + x_pos * 3 + - (s->image_height - y_pos - s->diff_start - k) * s->frame.linesize[0], + memcpy(s->frame->data[0] + x_pos * 3 + + (s->image_height - y_pos - s->diff_start - k) * s->frame->linesize[0], line, width * 3); /* advance source pointer to next line */ line += width * 3; } } else { /* hybrid 15-bit/palette mode */ - decode_hybrid(s->tmpblock, s->frame.data[0], + decode_hybrid(s->tmpblock, s->frame->data[0], s->image_height - (y_pos + 1 + s->diff_start + s->diff_height), x_pos, s->diff_height, width, - s->frame.linesize[0], s->pal); + s->frame->linesize[0], s->pal); } skip_bits_long(gb, 8 * block_size); /* skip the consumed bits */ return 0; @@ -337,7 +355,7 @@ static int flashsv_decode_frame(AVCodecContext *avctx, void *data, s->image_width, s->image_height, s->block_width, s->block_height, h_blocks, v_blocks, h_part, v_part); - if ((ret = ff_reget_buffer(avctx, &s->frame)) < 0) + if ((ret = ff_reget_buffer(avctx, s->frame)) < 0) return ret; /* loop over all block columns */ @@ -362,7 +380,7 @@ static int flashsv_decode_frame(AVCodecContext *avctx, void *data, s->diff_height = cur_blk_height; if (8 * size > get_bits_left(&gb)) { - av_frame_unref(&s->frame); + av_frame_unref(s->frame); return AVERROR_INVALIDDATA; } @@ -418,11 +436,11 @@ static int flashsv_decode_frame(AVCodecContext *avctx, void *data, if (has_diff) { int k; - int off = (s->image_height - y_pos - 1) * s->frame.linesize[0]; + int off = (s->image_height - y_pos - 1) * s->frame->linesize[0]; for (k = 0; k < cur_blk_height; k++) - memcpy(s->frame.data[0] + off - k*s->frame.linesize[0] + x_pos*3, - s->keyframe + off - k*s->frame.linesize[0] + x_pos*3, + memcpy(s->frame->data[0] + off - k*s->frame->linesize[0] + x_pos*3, + s->keyframe + off - k*s->frame->linesize[0] + x_pos*3, cur_blk_width * 3); } @@ -439,16 +457,16 @@ static int flashsv_decode_frame(AVCodecContext *avctx, void *data, } if (s->is_keyframe && s->ver == 2) { if (!s->keyframe) { - s->keyframe = av_malloc(s->frame.linesize[0] * avctx->height); + s->keyframe = av_malloc(s->frame->linesize[0] * avctx->height); if (!s->keyframe) { av_log(avctx, AV_LOG_ERROR, "Cannot allocate image data\n"); return AVERROR(ENOMEM); } } - memcpy(s->keyframe, s->frame.data[0], s->frame.linesize[0] * avctx->height); + memcpy(s->keyframe, s->frame->data[0], s->frame->linesize[0] * avctx->height); } - if ((ret = av_frame_ref(data, &s->frame)) < 0) + if ((ret = av_frame_ref(data, s->frame)) < 0) return ret; *got_frame = 1; @@ -461,21 +479,6 @@ static int flashsv_decode_frame(AVCodecContext *avctx, void *data, return buf_size; } - -static av_cold int flashsv_decode_end(AVCodecContext *avctx) -{ - FlashSVContext *s = avctx->priv_data; - inflateEnd(&s->zstream); - /* release the frame if needed */ - av_frame_unref(&s->frame); - - /* free the tmpblock */ - av_free(s->tmpblock); - - return 0; -} - - #if CONFIG_FLASHSV_DECODER AVCodec ff_flashsv_decoder = { .name = "flashsv", diff --git a/libavcodec/flashsv2enc.c b/libavcodec/flashsv2enc.c index 2115a46594..5fff04cb00 100644 --- a/libavcodec/flashsv2enc.c +++ b/libavcodec/flashsv2enc.c @@ -87,7 +87,6 @@ typedef struct FlashSV2Context { AVCodecContext *avctx; uint8_t *current_frame; uint8_t *key_frame; - AVFrame frame; uint8_t *encbuffer; uint8_t *keybuffer; uint8_t *databuffer; @@ -288,7 +287,7 @@ static int write_header(FlashSV2Context * s, uint8_t * buf, int buf_size) if (buf_size < 5) return -1; - init_put_bits(&pb, buf, buf_size * 8); + init_put_bits(&pb, buf, buf_size); put_bits(&pb, 4, (s->block_width >> 4) - 1); put_bits(&pb, 12, s->image_width); @@ -849,15 +848,12 @@ static int reconfigure_at_keyframe(FlashSV2Context * s, const uint8_t * image, } static int flashsv2_encode_frame(AVCodecContext *avctx, AVPacket *pkt, - const AVFrame *pict, int *got_packet) + const AVFrame *p, int *got_packet) { FlashSV2Context *const s = avctx->priv_data; - AVFrame *const p = &s->frame; int res; int keyframe = 0; - *p = *pict; - if ((res = ff_alloc_packet2(avctx, pkt, s->frame_size + FF_MIN_BUFFER_SIZE)) < 0) return res; @@ -891,18 +887,11 @@ static int flashsv2_encode_frame(AVCodecContext *avctx, AVPacket *pkt, if (keyframe) { new_key_frame(s); - p->pict_type = AV_PICTURE_TYPE_I; - p->key_frame = 1; s->last_key_frame = avctx->frame_number; pkt->flags |= AV_PKT_FLAG_KEY; av_log(avctx, AV_LOG_DEBUG, "Inserting key frame at frame %d\n", avctx->frame_number); - } else { - p->pict_type = AV_PICTURE_TYPE_P; - p->key_frame = 0; } - avctx->coded_frame = p; - pkt->size = res; *got_packet = 1; diff --git a/libavcodec/flashsvenc.c b/libavcodec/flashsvenc.c index ee67652eba..6d406e9fa6 100644 --- a/libavcodec/flashsvenc.c +++ b/libavcodec/flashsvenc.c @@ -57,7 +57,6 @@ typedef struct FlashSVContext { AVCodecContext *avctx; uint8_t *previous_frame; - AVFrame frame; int image_width, image_height; int block_width, block_height; uint8_t *tmpblock; @@ -89,6 +88,21 @@ static int copy_region_enc(uint8_t *sptr, uint8_t *dptr, int dx, int dy, return 0; } +static av_cold int flashsv_encode_end(AVCodecContext *avctx) +{ + FlashSVContext *s = avctx->priv_data; + + deflateEnd(&s->zstream); + + av_free(s->encbuffer); + av_free(s->previous_frame); + av_free(s->tmpblock); + + av_frame_free(&avctx->coded_frame); + + return 0; +} + static av_cold int flashsv_encode_init(AVCodecContext *avctx) { FlashSVContext *s = avctx->priv_data; @@ -117,11 +131,17 @@ static av_cold int flashsv_encode_init(AVCodecContext *avctx) return AVERROR(ENOMEM); } + avctx->coded_frame = av_frame_alloc(); + if (!avctx->coded_frame) { + flashsv_encode_end(avctx); + return AVERROR(ENOMEM); + } + return 0; } -static int encode_bitstream(FlashSVContext *s, AVFrame *p, uint8_t *buf, +static int encode_bitstream(FlashSVContext *s, const AVFrame *p, uint8_t *buf, int buf_size, int block_width, int block_height, uint8_t *previous_frame, int *I_frame) { @@ -131,7 +151,7 @@ static int encode_bitstream(FlashSVContext *s, AVFrame *p, uint8_t *buf, int buf_pos, res; int pred_blocks = 0; - init_put_bits(&pb, buf, buf_size * 8); + init_put_bits(&pb, buf, buf_size); put_bits(&pb, 4, block_width / 16 - 1); put_bits(&pb, 12, s->image_width); @@ -199,14 +219,12 @@ static int flashsv_encode_frame(AVCodecContext *avctx, AVPacket *pkt, const AVFrame *pict, int *got_packet) { FlashSVContext * const s = avctx->priv_data; - AVFrame * const p = &s->frame; + const AVFrame * const p = pict; uint8_t *pfptr; int res; int I_frame = 0; int opt_w = 4, opt_h = 4; - *p = *pict; - /* First frame needs to be a keyframe */ if (avctx->frame_number == 0) { s->previous_frame = av_mallocz(FFABS(p->linesize[0]) * s->image_height); @@ -244,37 +262,22 @@ static int flashsv_encode_frame(AVCodecContext *avctx, AVPacket *pkt, //mark the frame type so the muxer can mux it correctly if (I_frame) { - p->pict_type = AV_PICTURE_TYPE_I; - p->key_frame = 1; + avctx->coded_frame->pict_type = AV_PICTURE_TYPE_I; + avctx->coded_frame->key_frame = 1; s->last_key_frame = avctx->frame_number; av_dlog(avctx, "Inserting keyframe at frame %d\n", avctx->frame_number); } else { - p->pict_type = AV_PICTURE_TYPE_P; - p->key_frame = 0; + avctx->coded_frame->pict_type = AV_PICTURE_TYPE_P; + avctx->coded_frame->key_frame = 0; } - avctx->coded_frame = p; - - if (p->key_frame) + if (avctx->coded_frame->key_frame) pkt->flags |= AV_PKT_FLAG_KEY; *got_packet = 1; return 0; } -static av_cold int flashsv_encode_end(AVCodecContext *avctx) -{ - FlashSVContext *s = avctx->priv_data; - - deflateEnd(&s->zstream); - - av_free(s->encbuffer); - av_free(s->previous_frame); - av_free(s->tmpblock); - - return 0; -} - AVCodec ff_flashsv_encoder = { .name = "flashsv", .long_name = NULL_IF_CONFIG_SMALL("Flash Screen Video"), diff --git a/libavcodec/flicvideo.c b/libavcodec/flicvideo.c index 76a7976a7d..a2d59e86c3 100644 --- a/libavcodec/flicvideo.c +++ b/libavcodec/flicvideo.c @@ -71,7 +71,7 @@ typedef struct FlicDecodeContext { AVCodecContext *avctx; - AVFrame frame; + AVFrame *frame; unsigned int palette[256]; int new_palette; @@ -141,7 +141,10 @@ static av_cold int flic_decode_init(AVCodecContext *avctx) return AVERROR_INVALIDDATA; } - avcodec_get_frame_defaults(&s->frame); + s->frame = av_frame_alloc(); + if (!s->frame) + return AVERROR(ENOMEM); + s->new_palette = 0; return 0; @@ -185,11 +188,11 @@ static int flic_decode_frame_8BPP(AVCodecContext *avctx, bytestream2_init(&g2, buf, buf_size); - if ((ret = ff_reget_buffer(avctx, &s->frame)) < 0) + if ((ret = ff_reget_buffer(avctx, s->frame)) < 0) return ret; - pixels = s->frame.data[0]; - pixel_limit = s->avctx->height * s->frame.linesize[0]; + pixels = s->frame->data[0]; + pixel_limit = s->avctx->height * s->frame->linesize[0]; if (buf_size < 16 || buf_size > INT_MAX - (3 * 256 + FF_INPUT_BUFFER_PADDING_SIZE)) return AVERROR_INVALIDDATA; frame_size = bytestream2_get_le32(&g2); @@ -273,12 +276,12 @@ static int flic_decode_frame_8BPP(AVCodecContext *avctx, if ((line_packets & 0xC000) == 0xC000) { // line skip opcode line_packets = -line_packets; - y_ptr += line_packets * s->frame.linesize[0]; + y_ptr += line_packets * s->frame->linesize[0]; } else if ((line_packets & 0xC000) == 0x4000) { av_log(avctx, AV_LOG_ERROR, "Undefined opcode (%x) in DELTA_FLI\n", line_packets); } else if ((line_packets & 0xC000) == 0x8000) { // "last byte" opcode - pixel_ptr= y_ptr + s->frame.linesize[0] - 1; + pixel_ptr= y_ptr + s->frame->linesize[0] - 1; CHECK_PIXEL_PTR(0); pixels[pixel_ptr] = line_packets & 0xff; } else { @@ -313,7 +316,7 @@ static int flic_decode_frame_8BPP(AVCodecContext *avctx, } } - y_ptr += s->frame.linesize[0]; + y_ptr += s->frame->linesize[0]; } } break; @@ -322,7 +325,7 @@ static int flic_decode_frame_8BPP(AVCodecContext *avctx, /* line compressed */ starting_line = bytestream2_get_le16(&g2); y_ptr = 0; - y_ptr += starting_line * s->frame.linesize[0]; + y_ptr += starting_line * s->frame->linesize[0]; compressed_lines = bytestream2_get_le16(&g2); while (compressed_lines > 0) { @@ -359,7 +362,7 @@ static int flic_decode_frame_8BPP(AVCodecContext *avctx, } } - y_ptr += s->frame.linesize[0]; + y_ptr += s->frame->linesize[0]; compressed_lines--; } break; @@ -367,7 +370,7 @@ static int flic_decode_frame_8BPP(AVCodecContext *avctx, case FLI_BLACK: /* set the whole frame to color 0 (which is usually black) */ memset(pixels, 0, - s->frame.linesize[0] * s->avctx->height); + s->frame->linesize[0] * s->avctx->height); break; case FLI_BRUN: @@ -414,7 +417,7 @@ static int flic_decode_frame_8BPP(AVCodecContext *avctx, } } - y_ptr += s->frame.linesize[0]; + y_ptr += s->frame->linesize[0]; } break; @@ -425,8 +428,8 @@ static int flic_decode_frame_8BPP(AVCodecContext *avctx, "has incorrect size, skipping chunk\n", chunk_size - 6); bytestream2_skip(&g2, chunk_size - 6); } else { - for (y_ptr = 0; y_ptr < s->frame.linesize[0] * s->avctx->height; - y_ptr += s->frame.linesize[0]) { + for (y_ptr = 0; y_ptr < s->frame->linesize[0] * s->avctx->height; + y_ptr += s->frame->linesize[0]) { bytestream2_get_buffer(&g2, &pixels[y_ptr], s->avctx->width); } @@ -457,13 +460,13 @@ static int flic_decode_frame_8BPP(AVCodecContext *avctx, buf_size - bytestream2_get_bytes_left(&g2)); /* make the palette available on the way out */ - memcpy(s->frame.data[1], s->palette, AVPALETTE_SIZE); + memcpy(s->frame->data[1], s->palette, AVPALETTE_SIZE); if (s->new_palette) { - s->frame.palette_has_changed = 1; + s->frame->palette_has_changed = 1; s->new_palette = 0; } - if ((ret = av_frame_ref(data, &s->frame)) < 0) + if ((ret = av_frame_ref(data, s->frame)) < 0) return ret; *got_frame = 1; @@ -504,11 +507,11 @@ static int flic_decode_frame_15_16BPP(AVCodecContext *avctx, bytestream2_init(&g2, buf, buf_size); - if ((ret = ff_reget_buffer(avctx, &s->frame)) < 0) + if ((ret = ff_reget_buffer(avctx, s->frame)) < 0) return ret; - pixels = s->frame.data[0]; - pixel_limit = s->avctx->height * s->frame.linesize[0]; + pixels = s->frame->data[0]; + pixel_limit = s->avctx->height * s->frame->linesize[0]; frame_size = bytestream2_get_le32(&g2); bytestream2_skip(&g2, 2); /* skip the magic number */ @@ -556,7 +559,7 @@ static int flic_decode_frame_15_16BPP(AVCodecContext *avctx, line_packets = bytestream2_get_le16(&g2); if (line_packets < 0) { line_packets = -line_packets; - y_ptr += line_packets * s->frame.linesize[0]; + y_ptr += line_packets * s->frame->linesize[0]; } else { compressed_lines--; pixel_ptr = y_ptr; @@ -589,7 +592,7 @@ static int flic_decode_frame_15_16BPP(AVCodecContext *avctx, } } - y_ptr += s->frame.linesize[0]; + y_ptr += s->frame->linesize[0]; } } break; @@ -602,7 +605,7 @@ static int flic_decode_frame_15_16BPP(AVCodecContext *avctx, case FLI_BLACK: /* set the whole frame to 0x0000 which is black in both 15Bpp and 16Bpp modes. */ memset(pixels, 0x0000, - s->frame.linesize[0] * s->avctx->height); + s->frame->linesize[0] * s->avctx->height); break; case FLI_BRUN: @@ -657,7 +660,7 @@ static int flic_decode_frame_15_16BPP(AVCodecContext *avctx, pixel_ptr += 2; } #endif - y_ptr += s->frame.linesize[0]; + y_ptr += s->frame->linesize[0]; } break; @@ -701,7 +704,7 @@ static int flic_decode_frame_15_16BPP(AVCodecContext *avctx, } } - y_ptr += s->frame.linesize[0]; + y_ptr += s->frame->linesize[0]; } break; @@ -714,8 +717,8 @@ static int flic_decode_frame_15_16BPP(AVCodecContext *avctx, bytestream2_skip(&g2, chunk_size - 6); } else { - for (y_ptr = 0; y_ptr < s->frame.linesize[0] * s->avctx->height; - y_ptr += s->frame.linesize[0]) { + for (y_ptr = 0; y_ptr < s->frame->linesize[0] * s->avctx->height; + y_ptr += s->frame->linesize[0]) { pixel_countdown = s->avctx->width; pixel_ptr = 0; @@ -748,7 +751,7 @@ static int flic_decode_frame_15_16BPP(AVCodecContext *avctx, av_log(avctx, AV_LOG_ERROR, "Processed FLI chunk where chunk size = %d " \ "and final chunk ptr = %d\n", buf_size, bytestream2_tell(&g2)); - if ((ret = av_frame_ref(data, &s->frame)) < 0) + if ((ret = av_frame_ref(data, s->frame)) < 0) return ret; *got_frame = 1; @@ -797,7 +800,7 @@ static av_cold int flic_decode_end(AVCodecContext *avctx) { FlicDecodeContext *s = avctx->priv_data; - av_frame_unref(&s->frame); + av_frame_free(&s->frame); return 0; } diff --git a/libavcodec/g2meet.c b/libavcodec/g2meet.c index 16671497d6..a9c44cfcad 100644 --- a/libavcodec/g2meet.c +++ b/libavcodec/g2meet.c @@ -375,6 +375,8 @@ static int kempf_decode_tile(G2MContext *c, int tile_x, int tile_y, src += 3; } npal = *src++ + 1; + if (src_end - src < npal * 3) + return AVERROR_INVALIDDATA; memcpy(pal, src, npal * 3); src += npal * 3; if (sub_type != 2) { for (i = 0; i < npal; i++) { @@ -490,7 +492,7 @@ static int g2m_load_cursor(AVCodecContext *avctx, G2MContext *c, cursor_hot_y = bytestream2_get_byte(gb); cursor_fmt = bytestream2_get_byte(gb); - cursor_stride = FFALIGN(cursor_w, c->cursor_fmt==1 ? 32 : 1) * 4; + cursor_stride = FFALIGN(cursor_w, cursor_fmt==1 ? 32 : 1) * 4; if (cursor_w < 1 || cursor_w > 256 || cursor_h < 1 || cursor_h > 256) { @@ -707,11 +709,15 @@ static int g2m_decode_frame(AVCodecContext *avctx, void *data, av_log(avctx, AV_LOG_ERROR, "Unknown compression method %d\n", c->compression); - return AVERROR_PATCHWELCOME; + ret = AVERROR_PATCHWELCOME; + goto header_fail; } c->tile_width = bytestream2_get_be32(&bc); c->tile_height = bytestream2_get_be32(&bc); - if (!c->tile_width || !c->tile_height) { + 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); diff --git a/libavcodec/g723_1.c b/libavcodec/g723_1.c index 09da7665b8..e4bde2afd1 100644 --- a/libavcodec/g723_1.c +++ b/libavcodec/g723_1.c @@ -2285,7 +2285,8 @@ static int pack_bitstream(G723_1_Context *p, unsigned char *frame, int size) if (p->cur_rate == RATE_6300) { info_bits = 0; put_bits(&pb, 2, info_bits); - } + }else + av_assert0(0); put_bits(&pb, 8, p->lsp_index[2]); put_bits(&pb, 8, p->lsp_index[1]); diff --git a/libavcodec/gif.c b/libavcodec/gif.c index 8b9d95fe09..27d054e512 100644 --- a/libavcodec/gif.c +++ b/libavcodec/gif.c @@ -216,6 +216,13 @@ static av_cold int gif_encode_init(AVCodecContext *avctx) return AVERROR(EINVAL); } + avctx->coded_frame = av_frame_alloc(); + if (!avctx->coded_frame) + return AVERROR(ENOMEM); + + avctx->coded_frame->pict_type = AV_PICTURE_TYPE_I; + avctx->coded_frame->key_frame = 1; + s->lzw = av_mallocz(ff_lzw_encode_state_size); s->buf = av_malloc(avctx->width*avctx->height*2); s->tmpl = av_malloc(avctx->width); @@ -232,7 +239,6 @@ static int gif_encode_frame(AVCodecContext *avctx, AVPacket *pkt, const AVFrame *pict, int *got_packet) { GIFContext *s = avctx->priv_data; - AVFrame *const p = (AVFrame *)pict; uint8_t *outbuf_ptr, *end; const uint32_t *palette = NULL; int ret; @@ -242,15 +248,12 @@ static int gif_encode_frame(AVCodecContext *avctx, AVPacket *pkt, outbuf_ptr = pkt->data; end = pkt->data + pkt->size; - p->pict_type = AV_PICTURE_TYPE_I; - p->key_frame = 1; - if (avctx->pix_fmt == AV_PIX_FMT_PAL8) { uint8_t *pal_exdata = av_packet_new_side_data(pkt, AV_PKT_DATA_PALETTE, AVPALETTE_SIZE); if (!pal_exdata) return AVERROR(ENOMEM); - memcpy(pal_exdata, p->data[1], AVPALETTE_SIZE); - palette = (uint32_t*)p->data[1]; + memcpy(pal_exdata, pict->data[1], AVPALETTE_SIZE); + palette = (uint32_t*)pict->data[1]; } gif_image_write_image(avctx, &outbuf_ptr, end, palette, @@ -276,6 +279,8 @@ static int gif_encode_close(AVCodecContext *avctx) { GIFContext *s = avctx->priv_data; + av_frame_free(&avctx->coded_frame); + av_freep(&s->lzw); av_freep(&s->buf); av_frame_free(&s->last_frame); diff --git a/libavcodec/gifdec.c b/libavcodec/gifdec.c index 4151b88856..73cbb7c39d 100644 --- a/libavcodec/gifdec.c +++ b/libavcodec/gifdec.c @@ -251,26 +251,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/golomb-test.c b/libavcodec/golomb-test.c index 8adcdf63d8..2dfe917144 100644 --- a/libavcodec/golomb-test.c +++ b/libavcodec/golomb-test.c @@ -58,7 +58,7 @@ int main(void) } } -#define EXTEND(i) (i << 3 | i & 7) +#define EXTEND(i) ((i) << 3 | (i) & 7) init_put_bits(&pb, temp, SIZE); for (i = 0; i < COUNT; i++) set_ue_golomb(&pb, EXTEND(i)); diff --git a/libavcodec/h263dec.c b/libavcodec/h263dec.c index 7db32e76de..58358ad69e 100644 --- a/libavcodec/h263dec.c +++ b/libavcodec/h263dec.c @@ -755,10 +755,9 @@ frame_end: } if (startcode_found) { - av_fast_malloc(&s->bitstream_buffer, + av_fast_padded_mallocz(&s->bitstream_buffer, &s->allocated_bitstream_buffer_size, - buf_size - current_pos + - FF_INPUT_BUFFER_PADDING_SIZE); + buf_size - current_pos); if (!s->bitstream_buffer) return AVERROR(ENOMEM); memcpy(s->bitstream_buffer, buf + current_pos, diff --git a/libavcodec/h264.c b/libavcodec/h264.c index 1be723a6d0..4e10b93e2e 100644 --- a/libavcodec/h264.c +++ b/libavcodec/h264.c @@ -452,6 +452,18 @@ static int alloc_picture(H264Context *h, Picture *pic) pic->hwaccel_picture_private = pic->hwaccel_priv_buf->data; } } + if (!h->avctx->hwaccel && CONFIG_GRAY && h->flags & CODEC_FLAG_GRAY && pic->f.data[2]) { + int h_chroma_shift, v_chroma_shift; + av_pix_fmt_get_chroma_sub_sample(pic->f.format, + &h_chroma_shift, &v_chroma_shift); + + for(i=0; iavctx->height, v_chroma_shift); i++) { + memset(pic->f.data[1] + pic->f.linesize[1]*i, + 0x80, FF_CEIL_RSHIFT(h->avctx->width, h_chroma_shift)); + memset(pic->f.data[2] + pic->f.linesize[2]*i, + 0x80, FF_CEIL_RSHIFT(h->avctx->width, h_chroma_shift)); + } + } if (!h->qscale_table_pool) { ret = init_table_pools(h); @@ -586,18 +598,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; @@ -619,7 +631,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; \ } \ @@ -692,7 +704,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; @@ -1219,6 +1231,7 @@ static void free_tables(H264Context *h, int free_rbsp) av_buffer_pool_uninit(&h->ref_index_pool); if (free_rbsp && h->DPB) { + memset(h->delayed_pic, 0, sizeof(h->delayed_pic)); for (i = 0; i < MAX_PICTURE_COUNT; i++) unref_picture(h, &h->DPB[i]); av_freep(&h->DPB); @@ -1686,6 +1699,7 @@ static int decode_init_thread_copy(AVCodecContext *avctx) memset(h->sps_buffers, 0, sizeof(h->sps_buffers)); memset(h->pps_buffers, 0, sizeof(h->pps_buffers)); + h->avctx = avctx; h->rbsp_buffer[0] = NULL; h->rbsp_buffer[1] = NULL; h->rbsp_buffer_size[0] = 0; @@ -1787,6 +1801,7 @@ static int decode_update_thread_context(AVCodecContext *dst, memset(&h->mb, 0, sizeof(h->mb)); memset(&h->mb_luma_dc, 0, sizeof(h->mb_luma_dc)); memset(&h->mb_padding, 0, sizeof(h->mb_padding)); + memset(&h->cur_pic, 0, sizeof(h->cur_pic)); h->avctx = dst; h->DPB = NULL; @@ -1794,6 +1809,17 @@ static int decode_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; @@ -1839,7 +1865,7 @@ static int decode_update_thread_context(AVCodecContext *dst, for (i = 0; h->DPB && i < MAX_PICTURE_COUNT; i++) { unref_picture(h, &h->DPB[i]); - if (h1->DPB[i].f.data[0] && + if (h1->DPB && h1->DPB[i].f.data[0] && (ret = ref_picture(h, &h->DPB[i], &h1->DPB[i])) < 0) return ret; } @@ -1957,6 +1983,10 @@ static int h264_frame_start(H264Context *h) h->cur_pic_ptr = pic; unref_picture(h, &h->cur_pic); + if (CONFIG_ERROR_RESILIENCE) { + h->er.cur_pic = NULL; + } + if ((ret = ref_picture(h, &h->cur_pic, h->cur_pic_ptr)) < 0) return ret; @@ -2612,6 +2642,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; @@ -3354,6 +3394,17 @@ int ff_set_ref_count(H264Context *h) return 0; } +static enum AVPixelFormat non_j_pixfmt(enum AVPixelFormat a) +{ + switch (a) { + case AV_PIX_FMT_YUVJ420P: return AV_PIX_FMT_YUV420P; + case AV_PIX_FMT_YUVJ422P: return AV_PIX_FMT_YUV422P; + case AV_PIX_FMT_YUVJ444P: return AV_PIX_FMT_YUV444P; + default: + return a; + } +} + /** * Decode a slice header. * This will also call ff_MPV_common_init() and frame_start() as needed. @@ -3374,6 +3425,9 @@ static int decode_slice_header(H264Context *h, H264Context *h0) int must_reinit; int needs_reinit = 0; int field_pic_flag, bottom_field_flag; + int first_slice = h == h0 && !h0->current_slice; + int frame_num, picture_structure, droppable; + PPS *pps; h->me.qpel_put = h->h264qpel.put_h264_qpel_pixels_tab; h->me.qpel_avg = h->h264qpel.avg_h264_qpel_pixels_tab; @@ -3426,20 +3480,33 @@ static int decode_slice_header(H264Context *h, H264Context *h0) pps_id); return AVERROR_INVALIDDATA; } - h->pps = *h0->pps_buffers[pps_id]; + if (h0->au_pps_id >= 0 && pps_id != h0->au_pps_id) { + av_log(h->avctx, AV_LOG_ERROR, + "PPS change from %d to %d forbidden\n", + h0->au_pps_id, pps_id); + return AVERROR_INVALIDDATA; + } - if (!h0->sps_buffers[h->pps.sps_id]) { + pps = h0->pps_buffers[pps_id]; + + if (!h0->sps_buffers[pps->sps_id]) { av_log(h->avctx, AV_LOG_ERROR, "non-existing SPS %u referenced\n", h->pps.sps_id); return AVERROR_INVALIDDATA; } + if (first_slice) + h->pps = *h0->pps_buffers[pps_id]; - if (h->pps.sps_id != h->current_sps_id || - h0->sps_buffers[h->pps.sps_id]->new) { - h0->sps_buffers[h->pps.sps_id]->new = 0; + if (pps->sps_id != h->current_sps_id || + h0->sps_buffers[pps->sps_id]->new) { + + if (!first_slice) { + av_log(h->avctx, AV_LOG_ERROR, + "SPS changed in the middle of the frame\n"); + return AVERROR_INVALIDDATA; + } - h->current_sps_id = h->pps.sps_id; h->sps = *h0->sps_buffers[h->pps.sps_id]; if (h->mb_width != h->sps.mb_width || @@ -3468,11 +3535,13 @@ static int decode_slice_header(H264Context *h, H264Context *h0) || 16*h->sps.mb_height * (2 - h->sps.frame_mbs_only_flag) != h->avctx->coded_height || h->avctx->bits_per_raw_sample != h->sps.bit_depth_luma || h->cur_chroma_format_idc != h->sps.chroma_format_idc - || av_cmp_q(h->sps.sar, h->avctx->sample_aspect_ratio) || h->mb_width != h->sps.mb_width || h->mb_height != h->sps.mb_height * (2 - h->sps.frame_mbs_only_flag) )); - if (h0->avctx->pix_fmt != get_pixel_format(h0, 0)) + if (non_j_pixfmt(h0->avctx->pix_fmt) != non_j_pixfmt(get_pixel_format(h0, 0))) + must_reinit = 1; + + if (first_slice && av_cmp_q(h->sps.sar, h->avctx->sample_aspect_ratio)) must_reinit = 1; h->mb_width = h->sps.mb_width; @@ -3547,44 +3616,48 @@ static int decode_slice_header(H264Context *h, H264Context *h0) } } - if (h == h0 && h->dequant_coeff_pps != pps_id) { + if (first_slice && h->dequant_coeff_pps != pps_id) { h->dequant_coeff_pps = pps_id; init_dequant_tables(h); } - h->frame_num = get_bits(&h->gb, h->sps.log2_max_frame_num); + frame_num = get_bits(&h->gb, h->sps.log2_max_frame_num); + if (!first_slice) { + if (h0->frame_num != frame_num) { + av_log(h->avctx, AV_LOG_ERROR, "Frame num change from %d to %d\n", + h0->frame_num, frame_num); + return AVERROR_INVALIDDATA; + } + } h->mb_mbaff = 0; h->mb_aff_frame = 0; last_pic_structure = h0->picture_structure; last_pic_droppable = h0->droppable; - h->droppable = h->nal_ref_idc == 0; + droppable = h->nal_ref_idc == 0; if (h->sps.frame_mbs_only_flag) { - h->picture_structure = PICT_FRAME; + picture_structure = PICT_FRAME; } else { if (!h->sps.direct_8x8_inference_flag && slice_type == AV_PICTURE_TYPE_B) { av_log(h->avctx, AV_LOG_ERROR, "This stream was generated by a broken encoder, invalid 8x8 inference\n"); return -1; } field_pic_flag = get_bits1(&h->gb); + if (field_pic_flag) { bottom_field_flag = get_bits1(&h->gb); - h->picture_structure = PICT_TOP_FIELD + bottom_field_flag; + picture_structure = PICT_TOP_FIELD + bottom_field_flag; } else { - h->picture_structure = PICT_FRAME; + picture_structure = PICT_FRAME; h->mb_aff_frame = h->sps.mb_aff; } } - h->mb_field_decoding_flag = h->picture_structure != PICT_FRAME; - - if (h0->current_slice != 0) { - if (last_pic_structure != h->picture_structure || - last_pic_droppable != h->droppable) { + if (h0->current_slice) { + if (last_pic_structure != picture_structure || + last_pic_droppable != droppable) { av_log(h->avctx, AV_LOG_ERROR, "Changing field mode (%d -> %d) between slices is not allowed\n", last_pic_structure, h->picture_structure); - h->picture_structure = last_pic_structure; - h->droppable = last_pic_droppable; return AVERROR_INVALIDDATA; } else if (!h0->cur_pic_ptr) { av_log(h->avctx, AV_LOG_ERROR, @@ -3592,10 +3665,17 @@ static int decode_slice_header(H264Context *h, H264Context *h0) h0->current_slice + 1); return AVERROR_INVALIDDATA; } - } else { + } + + h->picture_structure = picture_structure; + h->droppable = droppable; + h->frame_num = frame_num; + h->mb_field_decoding_flag = picture_structure != PICT_FRAME; + + if (h0->current_slice == 0) { /* Shorten frame num gaps so we don't have to allocate reference * frames just to throw them away */ - if (h->frame_num != h->prev_frame_num && h->prev_frame_num >= 0) { + if (h->frame_num != h->prev_frame_num) { int unwrap_prev_frame_num = h->prev_frame_num; int max_frame_num = 1 << h->sps.log2_max_frame_num; @@ -3668,7 +3748,7 @@ static int decode_slice_header(H264Context *h, H264Context *h0) } } - while (h->frame_num != h->prev_frame_num && h->prev_frame_num >= 0 && !h0->first_field && + while (h->frame_num != h->prev_frame_num && !h0->first_field && h->frame_num != (h->prev_frame_num + 1) % (1 << h->sps.log2_max_frame_num)) { Picture *prev = h->short_ref_count ? h->short_ref[0] : NULL; av_log(h->avctx, AV_LOG_DEBUG, "Frame num gap %d %d\n", @@ -3924,8 +4004,8 @@ static int decode_slice_header(H264Context *h, H264Context *h0) if (h->deblocking_filter) { h->slice_alpha_c0_offset += get_se_golomb(&h->gb) << 1; h->slice_beta_offset += get_se_golomb(&h->gb) << 1; - if (h->slice_alpha_c0_offset > 104U || - h->slice_beta_offset > 104U) { + if (h->slice_alpha_c0_offset < 52 - 12 || h->slice_alpha_c0_offset > 52 + 12 || + h->slice_beta_offset < 52 - 12 || h->slice_beta_offset > 52 + 12) { av_log(h->avctx, AV_LOG_ERROR, "deblocking filter parameters %d %d out of range\n", h->slice_alpha_c0_offset, h->slice_beta_offset); @@ -4018,6 +4098,10 @@ static int decode_slice_header(H264Context *h, H264Context *h0) if (h->ref_count[0]) h->er.last_pic = &h->ref_list[0][0]; if (h->ref_count[1]) h->er.next_pic = &h->ref_list[1][0]; h->er.ref_count = h->ref_count[0]; + h0->au_pps_id = pps_id; + h->sps.new = + h0->sps_buffers[h->pps.sps_id]->new = 0; + h->current_sps_id = h->pps.sps_id; if (h->avctx->debug & FF_DEBUG_PICT_INFO) { av_log(h->avctx, AV_LOG_DEBUG, @@ -4601,6 +4685,8 @@ static int execute_decode_slices(H264Context *h, int context_count) H264Context *hx; int i; + av_assert0(h->mb_y < h->mb_height); + if (h->avctx->hwaccel || h->avctx->codec->capabilities & CODEC_CAP_HWACCEL_VDPAU) return 0; @@ -4782,6 +4868,9 @@ static int decode_nal_units(H264Context *h, const uint8_t *buf, int buf_size, continue; again: + if ( !(avctx->active_thread_type & FF_THREAD_FRAME) + || nals_needed >= nal_index) + h->au_pps_id = -1; /* Ignore per frame NAL unit type during extradata * parsing. Decoding slices is not possible in codec init * with frame-mt */ @@ -4814,6 +4903,7 @@ again: if(!idr_cleared) idr(h); // FIXME ensure we don't lose some frames if there is reordering idr_cleared = 1; + h->has_recovery_point = 1; case NAL_SLICE: init_get_bits(&hx->gb, ptr, bit_length); hx->intra_gb_ptr = @@ -5004,6 +5094,7 @@ static int get_consumed_bytes(int pos, int buf_size) static int output_frame(H264Context *h, AVFrame *dst, Picture *srcp) { AVFrame *src = &srcp->f; + const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(src->format); int i; int ret = av_frame_ref(dst, src); if (ret < 0) @@ -5014,9 +5105,9 @@ static int output_frame(H264Context *h, AVFrame *dst, Picture *srcp) if (!srcp->crop) return 0; - for (i = 0; i < 3; i++) { - int hshift = (i > 0) ? h->chroma_x_shift : 0; - int vshift = (i > 0) ? h->chroma_y_shift : 0; + for (i = 0; i < desc->nb_components; i++) { + int hshift = (i > 0) ? desc->log2_chroma_w : 0; + int vshift = (i > 0) ? desc->log2_chroma_h : 0; int off = ((srcp->crop_left >> hshift) << h->pixel_shift) + (srcp->crop_top >> vshift) * dst->linesize[i]; dst->data[i] += off; diff --git a/libavcodec/h264.h b/libavcodec/h264.h index ed7f04b853..bc7db9f298 100644 --- a/libavcodec/h264.h +++ b/libavcodec/h264.h @@ -61,10 +61,10 @@ #define MAX_SLICES 16 #ifdef ALLOW_INTERLACE -#define MB_MBAFF(h) h->mb_mbaff -#define MB_FIELD(h) h->mb_field_decoding_flag -#define FRAME_MBAFF(h) h->mb_aff_frame -#define FIELD_PICTURE(h) (h->picture_structure != PICT_FRAME) +#define MB_MBAFF(h) (h)->mb_mbaff +#define MB_FIELD(h) (h)->mb_field_decoding_flag +#define FRAME_MBAFF(h) (h)->mb_aff_frame +#define FIELD_PICTURE(h) ((h)->picture_structure != PICT_FRAME) #define LEFT_MBS 2 #define LTOP 0 #define LBOT 1 @@ -84,12 +84,12 @@ #define FIELD_OR_MBAFF_PICTURE(h) (FRAME_MBAFF(h) || FIELD_PICTURE(h)) #ifndef CABAC -#define CABAC(h) h->pps.cabac +#define CABAC(h) (h)->pps.cabac #endif -#define CHROMA(h) (h->sps.chroma_format_idc) -#define CHROMA422(h) (h->sps.chroma_format_idc == 2) -#define CHROMA444(h) (h->sps.chroma_format_idc == 3) +#define CHROMA(h) ((h)->sps.chroma_format_idc) +#define CHROMA422(h) ((h)->sps.chroma_format_idc == 2) +#define CHROMA444(h) ((h)->sps.chroma_format_idc == 3) #define EXTENDED_SAR 255 @@ -284,6 +284,7 @@ typedef struct MMCO { * H264Context */ typedef struct H264Context { + AVClass *av_class; AVCodecContext *avctx; VideoDSPContext vdsp; H264DSPContext h264dsp; @@ -390,6 +391,8 @@ typedef struct H264Context { */ PPS pps; // FIXME move to Picture perhaps? (->no) do we need that? + int au_pps_id; ///< pps_id of current access unit + uint32_t dequant4_buffer[6][QP_MAX_NUM + 1][16]; // FIXME should these be moved down? uint32_t dequant8_buffer[6][QP_MAX_NUM + 1][64]; uint32_t(*dequant4_coeff[6])[16]; @@ -656,6 +659,8 @@ typedef struct H264Context { FPA sei_fpa; + int has_recovery_point; + int luma_weight_flag[2]; ///< 7.4.3.2 luma_weight_lX_flag int chroma_weight_flag[2]; ///< 7.4.3.2 chroma_weight_lX_flag diff --git a/libavcodec/h264_cabac.c b/libavcodec/h264_cabac.c index 7b1ee05e3d..14b8e6850a 100644 --- a/libavcodec/h264_cabac.c +++ b/libavcodec/h264_cabac.c @@ -1279,7 +1279,7 @@ void ff_h264_init_cabac_states(H264Context *h) { } static int decode_cabac_field_decoding_flag(H264Context *h) { - const long mbb_xy = h->mb_xy - 2L*h->mb_stride; + const int mbb_xy = h->mb_xy - 2*h->mb_stride; unsigned long ctx = 0; diff --git a/libavcodec/h264_mp4toannexb_bsf.c b/libavcodec/h264_mp4toannexb_bsf.c index 58568a7a5a..06861b7ce3 100644 --- a/libavcodec/h264_mp4toannexb_bsf.c +++ b/libavcodec/h264_mp4toannexb_bsf.c @@ -174,11 +174,11 @@ 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) { + if (ctx->first_idr && (unit_type == 5 || unit_type == 7 || unit_type == 8)) { if ((ret=alloc_and_copy(poutbuf, poutbuf_size, avctx->extradata, avctx->extradata_size, buf, nal_size)) < 0) diff --git a/libavcodec/h264_ps.c b/libavcodec/h264_ps.c index e667359e2b..5f95f65c35 100644 --- a/libavcodec/h264_ps.c +++ b/libavcodec/h264_ps.c @@ -376,7 +376,9 @@ int ff_h264_decode_seq_parameter_set(H264Context *h) } sps->bit_depth_luma = get_ue_golomb(&h->gb) + 8; sps->bit_depth_chroma = get_ue_golomb(&h->gb) + 8; - if (sps->bit_depth_luma > 14U || sps->bit_depth_chroma > 14U || sps->bit_depth_luma != sps->bit_depth_chroma) { + if (sps->bit_depth_luma < 8 || sps->bit_depth_luma > 14 || + sps->bit_depth_chroma < 8 || sps->bit_depth_chroma > 14 || + sps->bit_depth_luma != sps->bit_depth_chroma) { av_log(h->avctx, AV_LOG_ERROR, "illegal bit depth value (%d, %d)\n", sps->bit_depth_luma, sps->bit_depth_chroma); goto fail; diff --git a/libavcodec/h264_refs.c b/libavcodec/h264_refs.c index 27ca8f8163..bb99b03247 100644 --- a/libavcodec/h264_refs.c +++ b/libavcodec/h264_refs.c @@ -562,6 +562,7 @@ int ff_generate_sliding_window_mmcos(H264Context *h, int first_slice) int ff_h264_execute_ref_pic_marking(H264Context *h, MMCO *mmco, int mmco_count) { int i, av_uninit(j); + int pps_count; int current_ref_assigned = 0, err = 0; Picture *av_uninit(pic); @@ -680,7 +681,7 @@ int ff_h264_execute_ref_pic_marking(H264Context *h, MMCO *mmco, int mmco_count) */ if (h->short_ref_count && h->short_ref[0] == h->cur_pic_ptr) { /* Just mark the second field valid */ - h->cur_pic_ptr->reference = PICT_FRAME; + h->cur_pic_ptr->reference |= h->picture_structure; } else if (h->cur_pic_ptr->long_ref) { av_log(h->avctx, AV_LOG_ERROR, "illegal short term reference " "assignment for second field " @@ -732,7 +733,15 @@ int ff_h264_execute_ref_pic_marking(H264Context *h, MMCO *mmco, int mmco_count) print_short_term(h); print_long_term(h); - if(err >= 0 && h->long_ref_count==0 && h->short_ref_count<=2 && h->pps.ref_count[0]<=2 + (h->picture_structure != PICT_FRAME) && h->cur_pic_ptr->f.pict_type == AV_PICTURE_TYPE_I){ + pps_count = 0; + for (i = 0; i < FF_ARRAY_ELEMS(h->pps_buffers); i++) + pps_count += !!h->pps_buffers[i]; + + if ( err >= 0 + && h->long_ref_count==0 + && (h->short_ref_count<=2 || h->pps.ref_count[0] <= 1 && h->pps.ref_count[1] <= 1 && pps_count == 1) + && h->pps.ref_count[0]<=2 + (h->picture_structure != PICT_FRAME) + (2*!h->has_recovery_point) + && h->cur_pic_ptr->f.pict_type == AV_PICTURE_TYPE_I){ h->cur_pic_ptr->sync |= 1; if(!h->avctx->has_b_frames) h->sync = 2; diff --git a/libavcodec/h264_sei.c b/libavcodec/h264_sei.c index 7d5558acb3..d65f40e4cc 100644 --- a/libavcodec/h264_sei.c +++ b/libavcodec/h264_sei.c @@ -184,6 +184,8 @@ static int decode_recovery_point(H264Context *h) if (h->avctx->debug & FF_DEBUG_PICT_INFO) av_log(h->avctx, AV_LOG_DEBUG, "sei_recovery_frame_cnt: %d\n", h->sei_recovery_frame_cnt); + h->has_recovery_point = 1; + return 0; } diff --git a/libavcodec/hevc.c b/libavcodec/hevc.c index 011b1ee216..4290e5d1d1 100644 --- a/libavcodec/hevc.c +++ b/libavcodec/hevc.c @@ -105,24 +105,26 @@ static int pic_arrays_init(HEVCContext *s) goto fail; s->skip_flag = av_malloc(pic_size_in_ctb); - s->tab_ct_depth = av_malloc(s->sps->min_cb_height * s->sps->min_cb_width); + s->tab_ct_depth = av_malloc_array(s->sps->min_cb_height, s->sps->min_cb_width); if (!s->skip_flag || !s->tab_ct_depth) goto fail; - s->tab_ipm = av_malloc(pic_size_in_min_pu); - s->cbf_luma = av_malloc(pic_width_in_min_tu * pic_height_in_min_tu); + s->tab_ipm = av_mallocz(pic_size_in_min_pu); + s->cbf_luma = av_malloc_array(pic_width_in_min_tu, pic_height_in_min_tu); s->is_pcm = av_malloc(pic_size_in_min_pu); if (!s->tab_ipm || !s->cbf_luma || !s->is_pcm) goto fail; - s->filter_slice_edges = av_malloc(ctb_count); - s->tab_slice_address = av_malloc(pic_size_in_ctb * sizeof(*s->tab_slice_address)); - s->qp_y_tab = av_malloc(pic_size_in_ctb * sizeof(*s->qp_y_tab)); + 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, + sizeof(*s->qp_y_tab)); if (!s->qp_y_tab || !s->filter_slice_edges || !s->tab_slice_address) goto fail; - s->horizontal_bs = av_mallocz(2 * s->bs_width * (s->bs_height + 1)); - s->vertical_bs = av_mallocz(2 * s->bs_width * (s->bs_height + 1)); + s->horizontal_bs = av_mallocz_array(2 * s->bs_width, (s->bs_height + 1)); + s->vertical_bs = av_mallocz_array(2 * s->bs_width, (s->bs_height + 1)); if (!s->horizontal_bs || !s->vertical_bs) goto fail; @@ -599,9 +601,14 @@ static int hls_slice_header(HEVCContext *s) av_freep(&sh->entry_point_offset); av_freep(&sh->offset); av_freep(&sh->size); - sh->entry_point_offset = av_malloc(sh->num_entry_point_offsets * sizeof(int)); - sh->offset = av_malloc(sh->num_entry_point_offsets * sizeof(int)); - sh->size = av_malloc(sh->num_entry_point_offsets * sizeof(int)); + sh->entry_point_offset = av_malloc_array(sh->num_entry_point_offsets, sizeof(int)); + sh->offset = av_malloc_array(sh->num_entry_point_offsets, sizeof(int)); + sh->size = av_malloc_array(sh->num_entry_point_offsets, sizeof(int)); + if (!sh->entry_point_offset || !sh->offset || !sh->size) { + sh->num_entry_point_offsets = 0; + av_log(s->avctx, AV_LOG_ERROR, "Failed to allocate memory\n"); + return AVERROR(ENOMEM); + } for (i = 0; i < sh->num_entry_point_offsets; i++) { int val = 0; for (j = 0; j < segments; j++) { @@ -630,14 +637,24 @@ static int hls_slice_header(HEVCContext *s) } // Inferred parameters - sh->slice_qp = 26 + s->pps->pic_init_qp_minus26 + sh->slice_qp_delta; + sh->slice_qp = 26U + s->pps->pic_init_qp_minus26 + sh->slice_qp_delta; + if (sh->slice_qp > 51 || + sh->slice_qp < -s->sps->qp_bd_offset) { + av_log(s->avctx, AV_LOG_ERROR, + "The slice_qp %d is outside the valid range " + "[%d, 51].\n", + sh->slice_qp, + -s->sps->qp_bd_offset); + return AVERROR_INVALIDDATA; + } + sh->slice_ctb_addr_rs = sh->slice_segment_addr; s->HEVClc->first_qp_group = !s->sh.dependent_slice_segment_flag; if (!s->pps->cu_qp_delta_enabled_flag) - s->HEVClc->qp_y = ((s->sh.slice_qp + 52 + 2 * s->sps->qp_bd_offset) % - (52 + s->sps->qp_bd_offset)) - s->sps->qp_bd_offset; + s->HEVClc->qp_y = FFUMOD(s->sh.slice_qp + 52 + 2 * s->sps->qp_bd_offset, + 52 + s->sps->qp_bd_offset) - s->sps->qp_bd_offset; s->slice_initialized = 1; @@ -728,11 +745,10 @@ static void hls_sao_param(HEVCContext *s, int rx, int ry) #undef SET_SAO #undef CTB - -static void hls_transform_unit(HEVCContext *s, int x0, int y0, - int xBase, int yBase, int cb_xBase, int cb_yBase, - int log2_cb_size, int log2_trafo_size, - int trafo_depth, int blk_idx) +static int hls_transform_unit(HEVCContext *s, int x0, int y0, + int xBase, int yBase, int cb_xBase, int cb_yBase, + int log2_cb_size, int log2_trafo_size, + int trafo_depth, int blk_idx) { HEVCLocalContext *lc = s->HEVClc; @@ -766,6 +782,18 @@ static void hls_transform_unit(HEVCContext *s, int x0, int y0, if (ff_hevc_cu_qp_delta_sign_flag(s) == 1) lc->tu.cu_qp_delta = -lc->tu.cu_qp_delta; lc->tu.is_cu_qp_delta_coded = 1; + + if (lc->tu.cu_qp_delta < -(26 + s->sps->qp_bd_offset / 2) || + lc->tu.cu_qp_delta > (25 + s->sps->qp_bd_offset / 2)) { + av_log(s->avctx, AV_LOG_ERROR, + "The cu_qp_delta %d is outside the valid range " + "[%d, %d].\n", + lc->tu.cu_qp_delta, + -(26 + s->sps->qp_bd_offset / 2), + (25 + s->sps->qp_bd_offset / 2)); + return AVERROR_INVALIDDATA; + } + ff_hevc_set_qPy(s, x0, y0, cb_xBase, cb_yBase, log2_cb_size); } @@ -801,6 +829,7 @@ static void hls_transform_unit(HEVCContext *s, int x0, int y0, ff_hevc_hls_residual_coding(s, xBase, yBase, log2_trafo_size, scan_idx_c, 2); } } + return 0; } static void set_deblocking_bypass(HEVCContext *s, int x0, int y0, int log2_cb_size) @@ -818,13 +847,14 @@ static void set_deblocking_bypass(HEVCContext *s, int x0, int y0, int log2_cb_si s->is_pcm[i + j * min_pu_width] = 2; } -static void hls_transform_tree(HEVCContext *s, int x0, int y0, - int xBase, int yBase, int cb_xBase, int cb_yBase, - int log2_cb_size, int log2_trafo_size, - int trafo_depth, int blk_idx) +static int hls_transform_tree(HEVCContext *s, int x0, int y0, + int xBase, int yBase, int cb_xBase, int cb_yBase, + int log2_cb_size, int log2_trafo_size, + int trafo_depth, int blk_idx) { HEVCLocalContext *lc = s->HEVClc; uint8_t split_transform_flag; + int ret; if (trafo_depth > 0 && log2_trafo_size == 2) { SAMPLE_CBF(lc->tt.cbf_cb[trafo_depth], x0, y0) = @@ -877,14 +907,26 @@ static void hls_transform_tree(HEVCContext *s, int x0, int y0, int x1 = x0 + ((1 << log2_trafo_size) >> 1); int y1 = y0 + ((1 << log2_trafo_size) >> 1); - hls_transform_tree(s, x0, y0, x0, y0, cb_xBase, cb_yBase, log2_cb_size, - log2_trafo_size - 1, trafo_depth + 1, 0); - hls_transform_tree(s, x1, y0, x0, y0, cb_xBase, cb_yBase, log2_cb_size, - log2_trafo_size - 1, trafo_depth + 1, 1); - hls_transform_tree(s, x0, y1, x0, y0, cb_xBase, cb_yBase, log2_cb_size, - log2_trafo_size - 1, trafo_depth + 1, 2); - hls_transform_tree(s, x1, y1, x0, y0, cb_xBase, cb_yBase, log2_cb_size, - log2_trafo_size - 1, trafo_depth + 1, 3); + ret = hls_transform_tree(s, x0, y0, x0, y0, cb_xBase, cb_yBase, + log2_cb_size, log2_trafo_size - 1, + trafo_depth + 1, 0); + if (ret < 0) + return ret; + ret = hls_transform_tree(s, x1, y0, x0, y0, cb_xBase, cb_yBase, + log2_cb_size, log2_trafo_size - 1, + trafo_depth + 1, 1); + if (ret < 0) + return ret; + ret = hls_transform_tree(s, x0, y1, x0, y0, cb_xBase, cb_yBase, + log2_cb_size, log2_trafo_size - 1, + trafo_depth + 1, 2); + if (ret < 0) + return ret; + ret = hls_transform_tree(s, x1, y1, x0, y0, cb_xBase, cb_yBase, + log2_cb_size, log2_trafo_size - 1, + trafo_depth + 1, 3); + if (ret < 0) + return ret; } else { int min_tu_size = 1 << s->sps->log2_min_tb_size; int log2_min_tu_size = s->sps->log2_min_tb_size; @@ -896,9 +938,11 @@ static void hls_transform_tree(HEVCContext *s, int x0, int y0, lc->tt.cbf_luma = ff_hevc_cbf_luma_decode(s, trafo_depth); } - hls_transform_unit(s, x0, y0, xBase, yBase, cb_xBase, cb_yBase, - log2_cb_size, log2_trafo_size, trafo_depth, blk_idx); - + ret = hls_transform_unit(s, x0, y0, xBase, yBase, cb_xBase, cb_yBase, + log2_cb_size, log2_trafo_size, trafo_depth, + blk_idx); + if (ret < 0) + return ret; // TODO: store cbf_luma somewhere else if (lc->tt.cbf_luma) { int i, j; @@ -917,6 +961,7 @@ static void hls_transform_tree(HEVCContext *s, int x0, int y0, set_deblocking_bypass(s, x0, y0, log2_trafo_size); } } + return 0; } static int hls_pcm_sample(HEVCContext *s, int x0, int y0, int log2_cb_size) @@ -1505,7 +1550,8 @@ static int hls_coding_unit(HEVCContext *s, int x0, int y0, int log2_cb_size) int min_cb_width = s->sps->min_cb_width; int x_cb = x0 >> log2_min_cb_size; int y_cb = y0 >> log2_min_cb_size; - int x, y; + int x, y, ret; + int qp_block_mask = (1<<(s->sps->log2_ctb_size - s->pps->diff_cu_qp_delta_depth)) - 1; lc->cu.x = x0; lc->cu.y = y0; @@ -1562,7 +1608,6 @@ static int hls_coding_unit(HEVCContext *s, int x0, int y0, int log2_cb_size) lc->cu.pcm_flag = ff_hevc_pcm_flag_decode(s); } if (lc->cu.pcm_flag) { - int ret; intra_prediction_unit_default_value(s, x0, y0, log2_cb_size); ret = hls_pcm_sample(s, x0, y0, log2_cb_size); if (s->sps->pcm.loop_filter_disable_flag) @@ -1621,8 +1666,11 @@ static int hls_coding_unit(HEVCContext *s, int x0, int y0, int log2_cb_size) lc->cu.max_trafo_depth = lc->cu.pred_mode == MODE_INTRA ? s->sps->max_transform_hierarchy_depth_intra + lc->cu.intra_split_flag : s->sps->max_transform_hierarchy_depth_inter; - hls_transform_tree(s, x0, y0, x0, y0, x0, y0, log2_cb_size, - log2_cb_size, 0, 0); + ret = hls_transform_tree(s, x0, y0, x0, y0, x0, y0, + log2_cb_size, + log2_cb_size, 0, 0); + if (ret < 0) + return ret; } else { if (!s->sh.disable_deblocking_filter_flag) ff_hevc_deblocking_boundary_strengths(s, x0, y0, log2_cb_size, @@ -1641,6 +1689,11 @@ static int hls_coding_unit(HEVCContext *s, int x0, int y0, int log2_cb_size) x += min_cb_width; } + if(((x0 + (1<qPy_pred = lc->qp_y; + } + set_ct_depth(s, x0, y0, log2_cb_size, lc->ct.depth); return 0; @@ -1652,6 +1705,7 @@ static int hls_coding_quadtree(HEVCContext *s, int x0, int y0, HEVCLocalContext *lc = s->HEVClc; const int cb_size = 1 << log2_cb_size; int ret; + int qp_block_mask = (1<<(s->sps->log2_ctb_size - s->pps->diff_cu_qp_delta_depth)) - 1; lc->ct.depth = cb_depth; if ((x0 + cb_size <= s->sps->width) && @@ -1679,14 +1733,27 @@ static int hls_coding_quadtree(HEVCContext *s, int x0, int y0, if (more_data < 0) return more_data; - if (more_data && x1 < s->sps->width) + if (more_data && x1 < s->sps->width) { more_data = hls_coding_quadtree(s, x1, y0, log2_cb_size - 1, cb_depth + 1); - if (more_data && y1 < s->sps->height) + if (more_data < 0) + return more_data; + } + if (more_data && y1 < s->sps->height) { more_data = hls_coding_quadtree(s, x0, y1, log2_cb_size - 1, cb_depth + 1); + if (more_data < 0) + return more_data; + } if (more_data && x1 < s->sps->width && y1 < s->sps->height) { - return hls_coding_quadtree(s, x1, y1, log2_cb_size - 1, cb_depth + 1); + more_data = hls_coding_quadtree(s, x1, y1, log2_cb_size - 1, cb_depth + 1); + if (more_data < 0) + return more_data; } + + if(((x0 + (1<qPy_pred = lc->qp_y; + if (more_data) return ((x1 + cb_size_split) < s->sps->width || (y1 + cb_size_split) < s->sps->height); @@ -1775,6 +1842,19 @@ static int hls_decode_entry(AVCodecContext *avctxt, void *isFilterThread) int y_ctb = 0; int ctb_addr_ts = s->pps->ctb_addr_rs_to_ts[s->sh.slice_ctb_addr_rs]; + if (!ctb_addr_ts && s->sh.dependent_slice_segment_flag) { + av_log(s->avctx, AV_LOG_ERROR, "Impossible initial tile.\n"); + return AVERROR_INVALIDDATA; + } + + if (s->sh.dependent_slice_segment_flag) { + int prev_rs = s->pps->ctb_addr_ts_to_rs[ctb_addr_ts - 1]; + if (s->tab_slice_address[prev_rs] != s->sh.slice_addr) { + av_log(s->avctx, AV_LOG_ERROR, "Previous slice segment missing\n"); + return AVERROR_INVALIDDATA; + } + } + while (more_data && ctb_addr_ts < s->sps->ctb_size) { int ctb_addr_rs = s->pps->ctb_addr_ts_to_rs[ctb_addr_ts]; @@ -1791,8 +1871,11 @@ static int hls_decode_entry(AVCodecContext *avctxt, void *isFilterThread) s->filter_slice_edges[ctb_addr_rs] = s->sh.slice_loop_filter_across_slices_enabled_flag; more_data = hls_coding_quadtree(s, x_ctb, y_ctb, s->sps->log2_ctb_size, 0); - if (more_data < 0) + if (more_data < 0) { + s->tab_slice_address[ctb_addr_rs] = -1; return more_data; + } + ctb_addr_ts++; ff_hevc_save_states(s, ctb_addr_ts); @@ -1858,8 +1941,10 @@ static int hls_decode_entry_wpp(AVCodecContext *avctxt, void *input_ctb_row, int hls_sao_param(s, x_ctb >> s->sps->log2_ctb_size, y_ctb >> s->sps->log2_ctb_size); more_data = hls_coding_quadtree(s, x_ctb, y_ctb, s->sps->log2_ctb_size, 0); - if (more_data < 0) + if (more_data < 0) { + s->tab_slice_address[ctb_addr_rs] = -1; return more_data; + } ctb_addr_ts++; @@ -1893,8 +1978,8 @@ static int hls_decode_entry_wpp(AVCodecContext *avctxt, void *input_ctb_row, int static int hls_slice_data_wpp(HEVCContext *s, const uint8_t *nal, int length) { HEVCLocalContext *lc = s->HEVClc; - int *ret = av_malloc((s->sh.num_entry_point_offsets + 1) * sizeof(int)); - int *arg = av_malloc((s->sh.num_entry_point_offsets + 1) * sizeof(int)); + int *ret = av_malloc_array(s->sh.num_entry_point_offsets + 1, sizeof(int)); + int *arg = av_malloc_array(s->sh.num_entry_point_offsets + 1, sizeof(int)); int offset; int startheader, cmpt = 0; int i, j, res = 0; @@ -2023,13 +2108,16 @@ static void restore_tqb_pixels(HEVCContext *s) static int hevc_frame_start(HEVCContext *s) { - HEVCLocalContext *lc = s->HEVClc; + HEVCLocalContext *lc = s->HEVClc; + int pic_size_in_ctb = ((s->sps->width >> s->sps->log2_min_cb_size) + 1) * + ((s->sps->height >> s->sps->log2_min_cb_size) + 1); int ret; memset(s->horizontal_bs, 0, 2 * s->bs_width * (s->bs_height + 1)); memset(s->vertical_bs, 0, 2 * s->bs_width * (s->bs_height + 1)); memset(s->cbf_luma, 0, s->sps->min_tb_width * s->sps->min_tb_height); memset(s->is_pcm, 0, s->sps->min_pu_width * s->sps->min_pu_height); + memset(s->tab_slice_address, -1, pic_size_in_ctb * sizeof(*s->tab_slice_address)); lc->start_of_tiles_x = 0; s->is_decoded = 0; @@ -2060,7 +2148,8 @@ static int hevc_frame_start(HEVCContext *s) if (ret < 0) goto fail; - ff_thread_finish_setup(s->avctx); + if (!s->avctx->hwaccel) + ff_thread_finish_setup(s->avctx); return 0; fail: @@ -2584,7 +2673,8 @@ static av_cold int hevc_decode_free(AVCodecContext *avctx) pic_arrays_free(s); - av_freep(&lc->edge_emu_buffer); + if (lc) + av_freep(&lc->edge_emu_buffer); av_freep(&s->md5_ctx); for(i=0; i < s->nals_allocated; i++) { @@ -2611,6 +2701,8 @@ static av_cold int hevc_decode_free(AVCodecContext *avctx) for (i = 0; i < FF_ARRAY_ELEMS(s->pps_list); i++) av_buffer_unref(&s->pps_list[i]); + av_buffer_unref(&s->current_sps); + av_freep(&s->sh.entry_point_offset); av_freep(&s->sh.offset); av_freep(&s->sh.size); @@ -2624,6 +2716,8 @@ static av_cold int hevc_decode_free(AVCodecContext *avctx) av_freep(&s->sList[i]); } } + if (s->HEVClc == s->HEVClcList[0]) + s->HEVClc = NULL; av_freep(&s->HEVClcList[0]); for (i = 0; i < s->nals_allocated; i++) @@ -2722,6 +2816,13 @@ static int hevc_update_thread_context(AVCodecContext *dst, } } + av_buffer_unref(&s->current_sps); + if (s0->current_sps) { + s->current_sps = av_buffer_ref(s0->current_sps); + if (!s->current_sps) + return AVERROR(ENOMEM); + } + s->seq_decode = s0->seq_decode; s->seq_output = s0->seq_output; s->pocTid0 = s0->pocTid0; diff --git a/libavcodec/hevc.h b/libavcodec/hevc.h index 90953ad59a..4a9f17f5b9 100644 --- a/libavcodec/hevc.h +++ b/libavcodec/hevc.h @@ -280,10 +280,10 @@ typedef struct RefPicListTab { } RefPicListTab; typedef struct HEVCWindow { - int left_offset; - int right_offset; - int top_offset; - int bottom_offset; + unsigned int left_offset; + unsigned int right_offset; + unsigned int top_offset; + unsigned int bottom_offset; } HEVCWindow; typedef struct VUI { @@ -373,7 +373,7 @@ typedef struct ScalingList { } ScalingList; typedef struct HEVCSPS { - int vps_id; + unsigned vps_id; int chroma_format_idc; uint8_t separate_colour_plane_flag; @@ -454,7 +454,7 @@ typedef struct HEVCSPS { } HEVCSPS; typedef struct HEVCPPS { - int sps_id; ///< seq_parameter_set_id + unsigned sps_id; ///< seq_parameter_set_id uint8_t sign_data_hiding_flag; @@ -733,6 +733,8 @@ typedef struct HEVCLocalContext { int8_t qp_y; int8_t curr_qp_y; + int qPy_pred; + TransformUnit tu; uint8_t ctb_left_flag; @@ -784,6 +786,8 @@ typedef struct HEVCContext { AVBufferRef *sps_list[MAX_SPS_COUNT]; AVBufferRef *pps_list[MAX_PPS_COUNT]; + AVBufferRef *current_sps; + AVBufferPool *tab_mvf_pool; AVBufferPool *rpl_tab_pool; diff --git a/libavcodec/hevc_filter.c b/libavcodec/hevc_filter.c index 0a6d7c9fb5..bad5359e7d 100644 --- a/libavcodec/hevc_filter.c +++ b/libavcodec/hevc_filter.c @@ -93,45 +93,7 @@ static int get_qPy_pred(HEVCContext *s, int xC, int yC, int xBase, int yBase, in lc->first_qp_group = !lc->tu.is_cu_qp_delta_coded; qPy_pred = s->sh.slice_qp; } else { - qPy_pred = lc->qp_y; - if (log2_cb_size < s->sps->log2_ctb_size - s->pps->diff_cu_qp_delta_depth) { - static const int offsetX[8][8] = { - {-1, 1, 3, 1, 7, 1, 3, 1}, - { 0, 0, 0, 0, 0, 0, 0, 0}, - { 1, 3, 1, 3, 1, 3, 1, 3}, - { 2, 2, 2, 2, 2, 2, 2, 2}, - { 3, 5, 7, 5, 3, 5, 7, 5}, - { 4, 4, 4, 4, 4, 4, 4, 4}, - { 5, 7, 5, 7, 5, 7, 5, 7}, - { 6, 6, 6, 6, 6, 6, 6, 6} - }; - static const int offsetY[8][8] = { - { 7, 0, 1, 2, 3, 4, 5, 6}, - { 0, 1, 2, 3, 4, 5, 6, 7}, - { 1, 0, 3, 2, 5, 4, 7, 6}, - { 0, 1, 2, 3, 4, 5, 6, 7}, - { 3, 0, 1, 2, 7, 4, 5, 6}, - { 0, 1, 2, 3, 4, 5, 6, 7}, - { 1, 0, 3, 2, 5, 4, 7, 6}, - { 0, 1, 2, 3, 4, 5, 6, 7} - }; - int xC0b = (xC - (xC & ctb_size_mask)) >> s->sps->log2_min_cb_size; - int yC0b = (yC - (yC & ctb_size_mask)) >> s->sps->log2_min_cb_size; - int idxX = (xQgBase & ctb_size_mask) >> s->sps->log2_min_cb_size; - int idxY = (yQgBase & ctb_size_mask) >> s->sps->log2_min_cb_size; - int idx_mask = ctb_size_mask >> s->sps->log2_min_cb_size; - int x, y; - - x = FFMIN(xC0b + offsetX[idxX][idxY], min_cb_width - 1); - y = FFMIN(yC0b + (offsetY[idxX][idxY] & idx_mask), min_cb_height - 1); - - if (xC0b == (lc->start_of_tiles_x >> s->sps->log2_min_cb_size) && - offsetX[idxX][idxY] == -1) { - x = (lc->end_of_tiles_x >> s->sps->log2_min_cb_size) - 1; - y = yC0b - 1; - } - qPy_pred = s->qp_y_tab[y * min_cb_width + x]; - } + qPy_pred = lc->qPy_pred; } // qPy_a @@ -155,7 +117,8 @@ void ff_hevc_set_qPy(HEVCContext *s, int xC, int yC, int xBase, int yBase, int l if (s->HEVClc->tu.cu_qp_delta != 0) { int off = s->sps->qp_bd_offset; - s->HEVClc->qp_y = ((qp_y + s->HEVClc->tu.cu_qp_delta + 52 + 2 * off) % (52 + off)) - off; + s->HEVClc->qp_y = FFUMOD(qp_y + s->HEVClc->tu.cu_qp_delta + 52 + 2 * off, + 52 + off) - off; } else s->HEVClc->qp_y = qp_y; } diff --git a/libavcodec/hevc_parser.c b/libavcodec/hevc_parser.c index 642f9752a4..0a75f20d19 100644 --- a/libavcodec/hevc_parser.c +++ b/libavcodec/hevc_parser.c @@ -329,6 +329,9 @@ static void hevc_close(AVCodecParserContext *s) for (i = 0; i < FF_ARRAY_ELEMS(h->pps_list); i++) av_buffer_unref(&h->pps_list[i]); + av_buffer_unref(&h->current_sps); + h->sps = NULL; + for (i = 0; i < h->nals_allocated; i++) av_freep(&h->nals[i].rbsp_buffer); av_freep(&h->nals); diff --git a/libavcodec/hevc_ps.c b/libavcodec/hevc_ps.c index 4318af01e8..4f7f12ba37 100644 --- a/libavcodec/hevc_ps.c +++ b/libavcodec/hevc_ps.c @@ -489,8 +489,8 @@ static void decode_vui(HEVCContext *s, HEVCSPS *sps) vui->vui_timing_info_present_flag = get_bits1(gb); if (vui->vui_timing_info_present_flag) { - vui->vui_num_units_in_tick = get_bits(gb, 32); - vui->vui_time_scale = get_bits(gb, 32); + vui->vui_num_units_in_tick = get_bits_long(gb, 32); + vui->vui_time_scale = get_bits_long(gb, 32); vui->vui_poc_proportional_to_timing_flag = get_bits1(gb); if (vui->vui_poc_proportional_to_timing_flag) vui->vui_num_ticks_poc_diff_one_minus1 = get_ue_golomb_long(gb); @@ -621,6 +621,12 @@ int ff_hevc_decode_nal_sps(HEVCContext *s) goto err; } + if (!s->vps_list[sps->vps_id]) { + av_log(s->avctx, AV_LOG_ERROR, "VPS does not exist \n"); + ret = AVERROR_INVALIDDATA; + goto err; + } + sps->max_sub_layers = get_bits(gb, 3) + 1; if (sps->max_sub_layers > MAX_SUB_LAYERS) { av_log(s->avctx, AV_LOG_ERROR, "sps_max_sub_layers out of range: %d\n", @@ -762,11 +768,30 @@ int ff_hevc_decode_nal_sps(HEVCContext *s) log2_diff_max_min_transform_block_size = get_ue_golomb_long(gb); sps->log2_max_trafo_size = log2_diff_max_min_transform_block_size + sps->log2_min_tb_size; - if (sps->log2_min_tb_size >= sps->log2_min_cb_size) { + if (sps->log2_min_cb_size < 3 || sps->log2_min_cb_size > 30) { + av_log(s->avctx, AV_LOG_ERROR, "Invalid value %d for log2_min_cb_size", sps->log2_min_cb_size); + ret = AVERROR_INVALIDDATA; + goto err; + } + + if (sps->log2_diff_max_min_coding_block_size > 30) { + av_log(s->avctx, AV_LOG_ERROR, "Invalid value %d for log2_diff_max_min_coding_block_size", sps->log2_diff_max_min_coding_block_size); + ret = AVERROR_INVALIDDATA; + goto err; + } + + if (sps->log2_min_tb_size >= sps->log2_min_cb_size || sps->log2_min_tb_size < 2) { av_log(s->avctx, AV_LOG_ERROR, "Invalid value for log2_min_tb_size"); ret = AVERROR_INVALIDDATA; goto err; } + + if (log2_diff_max_min_transform_block_size < 0 || log2_diff_max_min_transform_block_size > 30) { + av_log(s->avctx, AV_LOG_ERROR, "Invalid value %d for log2_diff_max_min_transform_block_size", log2_diff_max_min_transform_block_size); + ret = AVERROR_INVALIDDATA; + goto err; + } + sps->max_transform_hierarchy_depth_inter = get_ue_golomb_long(gb); sps->max_transform_hierarchy_depth_intra = get_ue_golomb_long(gb); @@ -818,6 +843,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); @@ -849,7 +879,8 @@ int ff_hevc_decode_nal_sps(HEVCContext *s) (sps->output_window.left_offset + sps->output_window.right_offset); sps->output_height = sps->height - (sps->output_window.top_offset + sps->output_window.bottom_offset); - if (sps->output_width <= 0 || sps->output_height <= 0) { + if (sps->width <= sps->output_window.left_offset + (int64_t)sps->output_window.right_offset || + sps->height <= sps->output_window.top_offset + (int64_t)sps->output_window.bottom_offset) { av_log(s->avctx, AV_LOG_WARNING, "Invalid visible frame dimensions: %dx%d.\n", sps->output_width, sps->output_height); if (s->avctx->err_recognition & AV_EF_EXPLODE) { @@ -857,10 +888,8 @@ int ff_hevc_decode_nal_sps(HEVCContext *s) goto err; } av_log(s->avctx, AV_LOG_WARNING, "Displaying the whole video surface.\n"); - sps->pic_conf_win.left_offset = - sps->pic_conf_win.right_offset = - sps->pic_conf_win.top_offset = - sps->pic_conf_win.bottom_offset = 0; + memset(&sps->pic_conf_win, 0, sizeof(sps->pic_conf_win)); + memset(&sps->output_window, 0, sizeof(sps->output_window)); sps->output_width = sps->width; sps->output_height = sps->height; } @@ -928,6 +957,12 @@ int ff_hevc_decode_nal_sps(HEVCContext *s) if (s->pps_list[i] && ((HEVCPPS*)s->pps_list[i]->data)->sps_id == sps_id) av_buffer_unref(&s->pps_list[i]); } + if (s->sps_list[sps_id] && s->sps == (HEVCSPS*)s->sps_list[sps_id]->data) { + av_buffer_unref(&s->current_sps); + s->current_sps = av_buffer_ref(s->sps_list[sps_id]); + if (!s->current_sps) + s->sps = NULL; + } av_buffer_unref(&s->sps_list[sps_id]); s->sps_list[sps_id] = sps_buf; } @@ -1032,6 +1067,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", diff --git a/libavcodec/hevcdsp_template.c b/libavcodec/hevcdsp_template.c index bda1dee757..4f6b7119d2 100644 --- a/libavcodec/hevcdsp_template.c +++ b/libavcodec/hevcdsp_template.c @@ -51,7 +51,7 @@ static void FUNC(transquant_bypass4x4)(uint8_t *_dst, int16_t *coeffs, ptrdiff_t for (y = 0; y < 4; y++) { for (x = 0; x < 4; x++) { - dst[x] += *coeffs; + dst[x] = av_clip_pixel(dst[x] + *coeffs); coeffs++; } dst += stride; @@ -67,7 +67,7 @@ static void FUNC(transquant_bypass8x8)(uint8_t *_dst, int16_t *coeffs, ptrdiff_t for (y = 0; y < 8; y++) { for (x = 0; x < 8; x++) { - dst[x] += *coeffs; + dst[x] = av_clip_pixel(dst[x] + *coeffs); coeffs++; } dst += stride; @@ -82,7 +82,7 @@ static void FUNC(transquant_bypass16x16)(uint8_t *_dst, int16_t *coeffs, ptrdiff for (y = 0; y < 16; y++) { for (x = 0; x < 16; x++) { - dst[x] += *coeffs; + dst[x] = av_clip_pixel(dst[x] + *coeffs); coeffs++; } dst += stride; @@ -98,7 +98,7 @@ static void FUNC(transquant_bypass32x32)(uint8_t *_dst, int16_t *coeffs, ptrdiff for (y = 0; y < 32; y++) { for (x = 0; x < 32; x++) { - dst[x] += *coeffs; + dst[x] = av_clip_pixel(dst[x] + *coeffs); coeffs++; } dst += stride; @@ -391,7 +391,7 @@ static void FUNC(sao_band_filter)(uint8_t *_dst, uint8_t *_src, offset_table[(k + sao_left_class) & 31] = sao_offset_val[k + 1]; for (y = 0; y < height; y++) { for (x = 0; x < width; x++) - dst[x] = av_clip_pixel(src[x] + offset_table[av_clip_pixel(src[x] >> shift)]); + dst[x] = av_clip_pixel(src[x] + offset_table[src[x] >> shift]); dst += stride; src += stride; } diff --git a/libavcodec/huffyuv.h b/libavcodec/huffyuv.h index e34b562b76..e2cacc1ae4 100644 --- a/libavcodec/huffyuv.h +++ b/libavcodec/huffyuv.h @@ -78,7 +78,6 @@ typedef struct HYuvContext { uint32_t bits[3][256]; uint32_t pix_bgr_map[1<vlc, 0, 3 * sizeof(VLC)); - avcodec_get_frame_defaults(&s->picture); s->interlaced = s->height > 288; s->bgr32 = 1; diff --git a/libavcodec/huffyuvenc.c b/libavcodec/huffyuvenc.c index c56e281014..3a55d543a9 100644 --- a/libavcodec/huffyuvenc.c +++ b/libavcodec/huffyuvenc.c @@ -156,7 +156,12 @@ static av_cold int encode_init(AVCodecContext *avctx) } s->version = 2; - avctx->coded_frame = &s->picture; + avctx->coded_frame = av_frame_alloc(); + if (!avctx->coded_frame) + return AVERROR(ENOMEM); + + avctx->coded_frame->pict_type = AV_PICTURE_TYPE_I; + avctx->coded_frame->key_frame = 1; switch (avctx->pix_fmt) { case AV_PIX_FMT_YUV420P: @@ -446,16 +451,12 @@ static int encode_frame(AVCodecContext *avctx, AVPacket *pkt, const int fake_ystride = s->interlaced ? pict->linesize[0]*2 : pict->linesize[0]; const int fake_ustride = s->interlaced ? pict->linesize[1]*2 : pict->linesize[1]; const int fake_vstride = s->interlaced ? pict->linesize[2]*2 : pict->linesize[2]; - AVFrame * const p = &s->picture; + const AVFrame * const p = pict; int i, j, size = 0, ret; if ((ret = ff_alloc_packet2(avctx, pkt, width * height * 3 * 4 + FF_MIN_BUFFER_SIZE)) < 0) return ret; - *p = *pict; - p->pict_type = AV_PICTURE_TYPE_I; - p->key_frame = 1; - if (s->context) { for (i = 0; i < 3; i++) { ff_huff_gen_len_table(s->len[i], s->stats[i]); @@ -681,6 +682,8 @@ static av_cold int encode_end(AVCodecContext *avctx) av_freep(&avctx->extradata); av_freep(&avctx->stats_out); + av_frame_free(&avctx->coded_frame); + return 0; } diff --git a/libavcodec/iff.c b/libavcodec/iff.c index a4b90fa4a3..f69b420d1e 100644 --- a/libavcodec/iff.c +++ b/libavcodec/iff.c @@ -318,6 +318,16 @@ static int extract_header(AVCodecContext *const avctx, return 0; } +static av_cold int decode_end(AVCodecContext *avctx) +{ + IffContext *s = avctx->priv_data; + av_frame_free(&s->frame); + av_freep(&s->planebuf); + av_freep(&s->ham_buf); + av_freep(&s->ham_palbuf); + return 0; +} + static av_cold int decode_init(AVCodecContext *avctx) { IffContext *s = avctx->priv_data; @@ -360,8 +370,10 @@ static av_cold int decode_init(AVCodecContext *avctx) s->bpp = avctx->bits_per_coded_sample; s->frame = av_frame_alloc(); - if (!s->frame) + if (!s->frame) { + decode_end(avctx); return AVERROR(ENOMEM); + } if ((err = extract_header(avctx, NULL)) < 0) return err; @@ -829,9 +841,9 @@ 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); @@ -858,16 +870,6 @@ static int decode_frame(AVCodecContext *avctx, return buf_size; } -static av_cold int decode_end(AVCodecContext *avctx) -{ - IffContext *s = avctx->priv_data; - av_frame_free(&s->frame); - av_freep(&s->planebuf); - av_freep(&s->ham_buf); - av_freep(&s->ham_palbuf); - return 0; -} - #if CONFIG_IFF_ILBM_DECODER AVCodec ff_iff_ilbm_decoder = { .name = "iff", diff --git a/libavcodec/indeo2.c b/libavcodec/indeo2.c index d3bbc6d20f..aabe348b4f 100644 --- a/libavcodec/indeo2.c +++ b/libavcodec/indeo2.c @@ -171,36 +171,36 @@ static int ir2_decode_frame(AVCodecContext *avctx, if (s->decode_delta) { /* intraframe */ if ((ret = ir2_decode_plane(s, avctx->width, avctx->height, - s->picture->data[0], s->picture->linesize[0], + p->data[0], p->linesize[0], ir2_luma_table)) < 0) return ret; /* swapped U and V */ if ((ret = ir2_decode_plane(s, avctx->width >> 2, avctx->height >> 2, - s->picture->data[2], s->picture->linesize[2], + p->data[2], p->linesize[2], ir2_luma_table)) < 0) return ret; if ((ret = ir2_decode_plane(s, avctx->width >> 2, avctx->height >> 2, - s->picture->data[1], s->picture->linesize[1], + p->data[1], p->linesize[1], ir2_luma_table)) < 0) return ret; } else { /* interframe */ if ((ret = ir2_decode_plane_inter(s, avctx->width, avctx->height, - s->picture->data[0], s->picture->linesize[0], + p->data[0], p->linesize[0], ir2_luma_table)) < 0) return ret; /* swapped U and V */ if ((ret = ir2_decode_plane_inter(s, avctx->width >> 2, avctx->height >> 2, - s->picture->data[2], s->picture->linesize[2], + p->data[2], p->linesize[2], ir2_luma_table)) < 0) return ret; if ((ret = ir2_decode_plane_inter(s, avctx->width >> 2, avctx->height >> 2, - s->picture->data[1], s->picture->linesize[1], + p->data[1], p->linesize[1], ir2_luma_table)) < 0) return ret; } - if ((ret = av_frame_ref(picture, s->picture)) < 0) + if ((ret = av_frame_ref(picture, p)) < 0) return ret; *got_frame = 1; diff --git a/libavcodec/indeo3.c b/libavcodec/indeo3.c index b8827634e1..b6633f8c15 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; @@ -980,7 +981,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/indeo4.c b/libavcodec/indeo4.c index df878c5905..0774f82ce5 100644 --- a/libavcodec/indeo4.c +++ b/libavcodec/indeo4.c @@ -284,6 +284,7 @@ static int decode_band_hdr(IVI45DecContext *ctx, IVIBandDesc *band, { int plane, band_num, indx, transform_id, scan_indx; int i; + int quant_mat; plane = get_bits(&ctx->gb, 2); band_num = get_bits(&ctx->gb, 4); @@ -382,18 +383,17 @@ static int decode_band_hdr(IVI45DecContext *ctx, IVIBandDesc *band, band->scan = scan_index_to_tab[scan_indx]; band->scan_size = band->blk_size; - band->quant_mat = get_bits(&ctx->gb, 5); - if (band->quant_mat >= FF_ARRAY_ELEMS(quant_index_to_tab)) { - - if (band->quant_mat == 31) - av_log(avctx, AV_LOG_ERROR, - "Custom quant matrix encountered!\n"); - else - avpriv_request_sample(avctx, "Quantization matrix %d", - band->quant_mat); - band->quant_mat = -1; + quant_mat = get_bits(&ctx->gb, 5); + if (quant_mat == 31) { + av_log(avctx, AV_LOG_ERROR, "Custom quant matrix encountered!\n"); return AVERROR_INVALIDDATA; } + if (quant_mat >= FF_ARRAY_ELEMS(quant_index_to_tab)) { + avpriv_request_sample(avctx, "Quantization matrix %d", + quant_mat); + return AVERROR_INVALIDDATA; + } + band->quant_mat = quant_mat; } else { if (old_blk_size != band->blk_size) { av_log(avctx, AV_LOG_ERROR, @@ -401,10 +401,6 @@ static int decode_band_hdr(IVI45DecContext *ctx, IVIBandDesc *band, "inherited\n"); return AVERROR_INVALIDDATA; } - if (band->quant_mat < 0) { - av_log(avctx, AV_LOG_ERROR, "Invalid quant_mat inherited\n"); - return AVERROR_INVALIDDATA; - } } if (quant_index_to_tab[band->quant_mat] > 4 && band->blk_size == 4) { av_log(avctx, AV_LOG_ERROR, "Invalid quant matrix for 4x4 block encountered!\n"); diff --git a/libavcodec/ivi_dsp.c b/libavcodec/ivi_dsp.c index f5e5e6b52e..9537cb0376 100644 --- a/libavcodec/ivi_dsp.c +++ b/libavcodec/ivi_dsp.c @@ -235,15 +235,15 @@ void ff_ivi_recompose_haar(const IVIPlaneDesc *plane, uint8_t *dst, /** butterfly operation for the inverse Haar transform */ #define IVI_HAAR_BFLY(s1, s2, o1, o2, t) \ - t = (s1 - s2) >> 1;\ - o1 = (s1 + s2) >> 1;\ - o2 = t;\ + t = ((s1) - (s2)) >> 1;\ + o1 = ((s1) + (s2)) >> 1;\ + o2 = (t);\ /** inverse 8-point Haar transform */ #define INV_HAAR8(s1, s5, s3, s7, s2, s4, s6, s8,\ d1, d2, d3, d4, d5, d6, d7, d8,\ t0, t1, t2, t3, t4, t5, t6, t7, t8) {\ - t1 = s1 << 1; t5 = s5 << 1;\ + t1 = (s1) << 1; t5 = (s5) << 1;\ IVI_HAAR_BFLY(t1, t5, t1, t5, t0); IVI_HAAR_BFLY(t1, s3, t1, t3, t0);\ IVI_HAAR_BFLY(t5, s7, t5, t7, t0); IVI_HAAR_BFLY(t1, s2, t1, t2, t0);\ IVI_HAAR_BFLY(t3, s4, t3, t4, t0); IVI_HAAR_BFLY(t5, s6, t5, t6, t0);\ @@ -485,21 +485,21 @@ void ff_ivi_dc_haar_2d(const int32_t *in, int16_t *out, uint32_t pitch, /** butterfly operation for the inverse slant transform */ #define IVI_SLANT_BFLY(s1, s2, o1, o2, t) \ - t = s1 - s2;\ - o1 = s1 + s2;\ - o2 = t;\ + t = (s1) - (s2);\ + o1 = (s1) + (s2);\ + o2 = (t);\ /** This is a reflection a,b = 1/2, 5/4 for the inverse slant transform */ #define IVI_IREFLECT(s1, s2, o1, o2, t) \ - t = ((s1 + s2*2 + 2) >> 2) + s1;\ - o2 = ((s1*2 - s2 + 2) >> 2) - s2;\ - o1 = t;\ + t = (((s1) + (s2)*2 + 2) >> 2) + (s1);\ + o2 = (((s1)*2 - (s2) + 2) >> 2) - (s2);\ + o1 = (t);\ /** This is a reflection a,b = 1/2, 7/8 for the inverse slant transform */ #define IVI_SLANT_PART4(s1, s2, o1, o2, t) \ - t = s2 + ((s1*4 - s2 + 4) >> 3);\ - o2 = s1 + ((-s1 - s2*4 + 4) >> 3);\ - o1 = t;\ + t = (s2) + (((s1)*4 - (s2) + 4) >> 3);\ + o2 = (s1) + ((-(s1) - (s2)*4 + 4) >> 3);\ + o1 = (t);\ /** inverse slant8 transform */ #define IVI_INV_SLANT8(s1, s4, s8, s5, s2, s6, s3, s7,\ @@ -557,7 +557,7 @@ void ff_ivi_inverse_slant_8x8(const int32_t *in, int16_t *out, uint32_t pitch, c } #undef COMPENSATE -#define COMPENSATE(x) ((x + 1)>>1) +#define COMPENSATE(x) (((x) + 1)>>1) src = tmp; for (i = 0; i < 8; i++) { if (!src[0] && !src[1] && !src[2] && !src[3] && !src[4] && !src[5] && !src[6] && !src[7]) { @@ -597,7 +597,7 @@ void ff_ivi_inverse_slant_4x4(const int32_t *in, int16_t *out, uint32_t pitch, c } #undef COMPENSATE -#define COMPENSATE(x) ((x + 1)>>1) +#define COMPENSATE(x) (((x) + 1)>>1) src = tmp; for (i = 0; i < 4; i++) { if (!src[0] && !src[1] && !src[2] && !src[3]) { @@ -631,7 +631,7 @@ void ff_ivi_row_slant8(const int32_t *in, int16_t *out, uint32_t pitch, const ui int i; int t0, t1, t2, t3, t4, t5, t6, t7, t8; -#define COMPENSATE(x) ((x + 1)>>1) +#define COMPENSATE(x) (((x) + 1)>>1) for (i = 0; i < 8; i++) { if (!in[0] && !in[1] && !in[2] && !in[3] && !in[4] && !in[5] && !in[6] && !in[7]) { memset(out, 0, 8*sizeof(out[0])); @@ -673,7 +673,7 @@ void ff_ivi_col_slant8(const int32_t *in, int16_t *out, uint32_t pitch, const ui row4 = pitch << 2; row8 = pitch << 3; -#define COMPENSATE(x) ((x + 1)>>1) +#define COMPENSATE(x) (((x) + 1)>>1) for (i = 0; i < 8; i++) { if (flags[i]) { IVI_INV_SLANT8(in[0], in[8], in[16], in[24], in[32], in[40], in[48], in[56], @@ -710,7 +710,7 @@ void ff_ivi_row_slant4(const int32_t *in, int16_t *out, uint32_t pitch, const ui int i; int t0, t1, t2, t3, t4; -#define COMPENSATE(x) ((x + 1)>>1) +#define COMPENSATE(x) (((x) + 1)>>1) for (i = 0; i < 4; i++) { if (!in[0] && !in[1] && !in[2] && !in[3]) { memset(out, 0, 4*sizeof(out[0])); @@ -732,7 +732,7 @@ void ff_ivi_col_slant4(const int32_t *in, int16_t *out, uint32_t pitch, const ui row2 = pitch << 1; -#define COMPENSATE(x) ((x + 1)>>1) +#define COMPENSATE(x) (((x) + 1)>>1) for (i = 0; i < 4; i++) { if (flags[i]) { IVI_INV_SLANT4(in[0], in[4], in[8], in[12], diff --git a/libavcodec/j2kenc.c b/libavcodec/j2kenc.c index d9f5eaf5f4..498c7c022c 100644 --- a/libavcodec/j2kenc.c +++ b/libavcodec/j2kenc.c @@ -60,7 +60,7 @@ typedef struct { typedef struct { AVCodecContext *avctx; - AVFrame picture; + const AVFrame *picture; int width, height; ///< image width and height uint8_t cbps[4]; ///< bits per sample in particular components @@ -390,18 +390,18 @@ static void copy_frame(Jpeg2000EncoderContext *s) for (compno = 0; compno < s->ncomponents; compno++){ Jpeg2000Component *comp = tile->comp + compno; int *dst = comp->i_data; - line = s->picture.data[compno] - + comp->coord[1][0] * s->picture.linesize[compno] + line = s->picture->data[compno] + + comp->coord[1][0] * s->picture->linesize[compno] + comp->coord[0][0]; for (y = comp->coord[1][0]; y < comp->coord[1][1]; y++){ uint8_t *ptr = line; for (x = comp->coord[0][0]; x < comp->coord[0][1]; x++) *dst++ = *ptr++ - (1 << 7); - line += s->picture.linesize[compno]; + line += s->picture->linesize[compno]; } } } else{ - line = s->picture.data[0] + tile->comp[0].coord[1][0] * s->picture.linesize[0] + line = s->picture->data[0] + tile->comp[0].coord[1][0] * s->picture->linesize[0] + tile->comp[0].coord[0][0] * s->ncomponents; i = 0; @@ -412,7 +412,7 @@ static void copy_frame(Jpeg2000EncoderContext *s) tile->comp[compno].i_data[i] = *ptr++ - (1 << 7); } } - line += s->picture.linesize[0]; + line += s->picture->linesize[0]; } } } @@ -927,10 +927,9 @@ static int encode_frame(AVCodecContext *avctx, AVPacket *pkt, s->buf = s->buf_start = pkt->data; s->buf_end = pkt->data + pkt->size; - s->picture = *pict; - avctx->coded_frame= &s->picture; + s->picture = pict; - s->lambda = s->picture.quality * LAMBDA_SCALE; + s->lambda = s->picture->quality * LAMBDA_SCALE; copy_frame(s); reinit(s); diff --git a/libavcodec/jpeg2000dec.c b/libavcodec/jpeg2000dec.c index b150bc1595..21b19f52f0 100644 --- a/libavcodec/jpeg2000dec.c +++ b/libavcodec/jpeg2000dec.c @@ -344,7 +344,7 @@ static int get_siz(Jpeg2000DecoderContext *s) break; } } - if (s->avctx->pix_fmt == AV_PIX_FMT_NONE) { + if (i == possible_fmts_nb) { av_log(s->avctx, AV_LOG_ERROR, "Unknown pix_fmt, profile: %d, colour_space: %d, " "components: %d, precision: %d, " @@ -354,6 +354,7 @@ static int get_siz(Jpeg2000DecoderContext *s) ncomponents > 2 ? s->cdy[1] : 0, ncomponents > 2 ? s->cdx[2] : 0, ncomponents > 2 ? s->cdy[2] : 0); + return AVERROR_PATCHWELCOME; } s->avctx->bits_per_raw_sample = s->precision; return 0; @@ -889,6 +890,10 @@ static int jpeg2000_decode_packets(Jpeg2000DecoderContext *s, Jpeg2000Tile *tile prcx = ff_jpeg2000_ceildivpow2(x, reducedresno) >> rlevel->log2_prec_width; prcy = ff_jpeg2000_ceildivpow2(y, reducedresno) >> rlevel->log2_prec_height; precno = prcx + rlevel->num_precincts_x * prcy; + + if (prcx >= rlevel->num_precincts_x || prcy >= rlevel->num_precincts_y) + return AVERROR_PATCHWELCOME; + for (layno = 0; layno < tile->codsty[0].nlayers; layno++) { if ((ret = jpeg2000_decode_packet(s, codsty, rlevel, precno, layno, diff --git a/libavcodec/jpegls.h b/libavcodec/jpegls.h index 2dc3832517..10ae054a7b 100644 --- a/libavcodec/jpegls.h +++ b/libavcodec/jpegls.h @@ -33,7 +33,6 @@ typedef struct JpeglsContext { AVCodecContext *avctx; - AVFrame picture; } JpeglsContext; typedef struct JLSState { diff --git a/libavcodec/jpeglsdec.c b/libavcodec/jpeglsdec.c index 0e344f54d8..5740aaafe5 100644 --- a/libavcodec/jpeglsdec.c +++ b/libavcodec/jpeglsdec.c @@ -148,6 +148,8 @@ static inline int ls_get_code_runterm(GetBitContext *gb, JLSState *state, ret = ret >> 1; } + if(FFABS(ret) > 0xFFFF) + return -0x10000; /* update state */ state->A[Q] += FFABS(ret) - RItype; ret *= state->twonear; @@ -215,6 +217,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; @@ -279,9 +286,9 @@ int ff_jpegls_decode_picture(MJpegDecodeContext *s, int near, JLSState *state; int off = 0, stride = 1, width, shift, ret = 0; - zero = av_mallocz(s->picture.linesize[0]); + zero = av_mallocz(s->picture_ptr->linesize[0]); last = zero; - cur = s->picture.data[0]; + cur = s->picture_ptr->data[0]; state = av_mallocz(sizeof(JLSState)); /* initialize JPEG-LS state from JPEG parameters */ @@ -328,7 +335,7 @@ int ff_jpegls_decode_picture(MJpegDecodeContext *s, int near, t = *((uint16_t *)last); } last = cur; - cur += s->picture.linesize[0]; + cur += s->picture_ptr->linesize[0]; if (s->restart_interval && !--s->restart_count) { align_get_bits(&s->gb); @@ -339,7 +346,7 @@ int ff_jpegls_decode_picture(MJpegDecodeContext *s, int near, int j; int Rc[3] = { 0, 0, 0 }; stride = (s->nb_components > 1) ? 3 : 1; - memset(cur, 0, s->picture.linesize[0]); + memset(cur, 0, s->picture_ptr->linesize[0]); width = s->width * stride; for (i = 0; i < s->height; i++) { for (j = 0; j < stride; j++) { @@ -353,7 +360,7 @@ int ff_jpegls_decode_picture(MJpegDecodeContext *s, int near, } } last = cur; - cur += s->picture.linesize[0]; + cur += s->picture_ptr->linesize[0]; } } else if (ilv == 2) { /* sample interleaving */ avpriv_report_missing_feature(s->avctx, "Sample interleaved images"); @@ -367,7 +374,7 @@ int ff_jpegls_decode_picture(MJpegDecodeContext *s, int near, w = s->width * s->nb_components; if (s->bits <= 8) { - uint8_t *src = s->picture.data[0]; + uint8_t *src = s->picture_ptr->data[0]; for (i = 0; i < s->height; i++) { switch(s->xfrm) { @@ -402,7 +409,7 @@ int ff_jpegls_decode_picture(MJpegDecodeContext *s, int near, } break; } - src += s->picture.linesize[0]; + src += s->picture_ptr->linesize[0]; } }else avpriv_report_missing_feature(s->avctx, "16bit xfrm"); @@ -414,20 +421,20 @@ int ff_jpegls_decode_picture(MJpegDecodeContext *s, int near, w = s->width * s->nb_components; if (s->bits <= 8) { - uint8_t *src = s->picture.data[0]; + uint8_t *src = s->picture_ptr->data[0]; for (i = 0; i < s->height; i++) { for (x = off; x < w; x += stride) src[x] <<= shift; - src += s->picture.linesize[0]; + src += s->picture_ptr->linesize[0]; } } else { - uint16_t *src = (uint16_t *)s->picture.data[0]; + uint16_t *src = (uint16_t *)s->picture_ptr->data[0]; for (i = 0; i < s->height; i++) { for (x = 0; x < w; x++) src[x] <<= shift; - src += s->picture.linesize[0] / 2; + src += s->picture_ptr->linesize[0] / 2; } } } diff --git a/libavcodec/jpeglsenc.c b/libavcodec/jpeglsenc.c index 308d6d3e68..030178f9ac 100644 --- a/libavcodec/jpeglsenc.c +++ b/libavcodec/jpeglsenc.c @@ -249,8 +249,7 @@ static void ls_store_lse(JLSState *state, PutBitContext *pb) static int encode_picture_ls(AVCodecContext *avctx, AVPacket *pkt, const AVFrame *pict, int *got_packet) { - JpeglsContext *const s = avctx->priv_data; - AVFrame *const p = &s->picture; + const AVFrame *const p = pict; const int near = avctx->prediction_method; PutBitContext pb, pb2; GetBitContext gb; @@ -259,10 +258,6 @@ static int encode_picture_ls(AVCodecContext *avctx, AVPacket *pkt, int i, size, ret; int comps; - *p = *pict; - p->pict_type = AV_PICTURE_TYPE_I; - p->key_frame = 1; - if (avctx->pix_fmt == AV_PIX_FMT_GRAY8 || avctx->pix_fmt == AV_PIX_FMT_GRAY16) comps = 1; @@ -349,7 +344,7 @@ static int encode_picture_ls(AVCodecContext *avctx, AVPacket *pkt, Rc[j] = last[j]; } last = cur; - cur += s->picture.linesize[0]; + cur += p->linesize[0]; } } else if (avctx->pix_fmt == AV_PIX_FMT_BGR24) { int j, width; @@ -363,7 +358,7 @@ static int encode_picture_ls(AVCodecContext *avctx, AVPacket *pkt, Rc[j] = last[j]; } last = cur; - cur += s->picture.linesize[0]; + cur += p->linesize[0]; } } @@ -403,12 +398,20 @@ static int encode_picture_ls(AVCodecContext *avctx, AVPacket *pkt, return 0; } +static av_cold int encode_close(AVCodecContext *avctx) +{ + av_frame_free(&avctx->coded_frame); + return 0; +} + static av_cold int encode_init_ls(AVCodecContext *ctx) { - JpeglsContext *c = (JpeglsContext *)ctx->priv_data; + ctx->coded_frame = av_frame_alloc(); + if (!ctx->coded_frame) + return AVERROR(ENOMEM); - c->avctx = ctx; - ctx->coded_frame = &c->picture; + ctx->coded_frame->pict_type = AV_PICTURE_TYPE_I; + ctx->coded_frame->key_frame = 1; if (ctx->pix_fmt != AV_PIX_FMT_GRAY8 && ctx->pix_fmt != AV_PIX_FMT_GRAY16 && @@ -426,8 +429,8 @@ AVCodec ff_jpegls_encoder = { .long_name = NULL_IF_CONFIG_SMALL("JPEG-LS"), .type = AVMEDIA_TYPE_VIDEO, .id = AV_CODEC_ID_JPEGLS, - .priv_data_size = sizeof(JpeglsContext), .init = encode_init_ls, + .close = encode_close, .encode2 = encode_picture_ls, .pix_fmts = (const enum AVPixelFormat[]) { AV_PIX_FMT_BGR24, AV_PIX_FMT_RGB24, diff --git a/libavcodec/jvdec.c b/libavcodec/jvdec.c index 740884ad3b..7c0a42b04e 100644 --- a/libavcodec/jvdec.c +++ b/libavcodec/jvdec.c @@ -41,11 +41,20 @@ typedef struct JvContext { static av_cold int decode_init(AVCodecContext *avctx) { JvContext *s = avctx->priv_data; - avctx->pix_fmt = AV_PIX_FMT_PAL8; - ff_dsputil_init(&s->dsp, avctx); + + 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); + + avctx->pix_fmt = AV_PIX_FMT_PAL8; + ff_dsputil_init(&s->dsp, avctx); return 0; } diff --git a/libavcodec/kgv1dec.c b/libavcodec/kgv1dec.c index f793137306..d4f8356dab 100644 --- a/libavcodec/kgv1dec.c +++ b/libavcodec/kgv1dec.c @@ -38,7 +38,7 @@ static void decode_flush(AVCodecContext *avctx) { KgvContext * const c = avctx->priv_data; - av_frame_unref(c->prev); + av_frame_free(&c->prev); } static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame, @@ -157,13 +157,13 @@ static av_cold int decode_init(AVCodecContext *avctx) { KgvContext * const c = avctx->priv_data; - avctx->pix_fmt = AV_PIX_FMT_RGB555; - avctx->flags |= CODEC_FLAG_EMU_EDGE; - c->prev = av_frame_alloc(); if (!c->prev) return AVERROR(ENOMEM); + avctx->pix_fmt = AV_PIX_FMT_RGB555; + avctx->flags |= CODEC_FLAG_EMU_EDGE; + return 0; } diff --git a/libavcodec/lclenc.c b/libavcodec/lclenc.c index 1dac307dd2..0afe5530ba 100644 --- a/libavcodec/lclenc.c +++ b/libavcodec/lclenc.c @@ -135,6 +135,13 @@ static av_cold int encode_init(AVCodecContext *avctx) if (!avctx->extradata) return AVERROR(ENOMEM); + avctx->coded_frame = av_frame_alloc(); + if (!avctx->coded_frame) + return AVERROR(ENOMEM); + + avctx->coded_frame->pict_type = AV_PICTURE_TYPE_I; + avctx->coded_frame->key_frame = 1; + c->compression = avctx->compression_level == FF_COMPRESSION_DEFAULT ? COMP_ZLIB_NORMAL : av_clip(avctx->compression_level, 0, 9); @@ -176,6 +183,8 @@ static av_cold int encode_end(AVCodecContext *avctx) av_freep(&avctx->extradata); deflateEnd(&c->zstream); + av_frame_free(&avctx->coded_frame); + return 0; } 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/libopenjpegdec.c b/libavcodec/libopenjpegdec.c index 734b54faed..e1ebccf552 100644 --- a/libavcodec/libopenjpegdec.c +++ b/libavcodec/libopenjpegdec.c @@ -172,7 +172,7 @@ static inline void libopenjpeg_copy_to_packed16(AVFrame *picture, opj_image_t *i int index, x, y, c; int adjust[4]; for (x = 0; x < image->numcomps; x++) - adjust[x] = FFMAX(FFMIN(16 - image->comps[x].prec, 8), 0); + adjust[x] = FFMAX(FFMIN(av_pix_fmt_desc_get(picture->format)->comp[x].depth_minus1 + 1 - image->comps[x].prec, 8), 0); for (y = 0; y < picture->height; y++) { index = y*picture->width; @@ -209,7 +209,7 @@ static inline void libopenjpeg_copyto16(AVFrame *picture, opj_image_t *image) { int index, x, y; int adjust[4]; for (x = 0; x < image->numcomps; x++) - adjust[x] = FFMAX(FFMIN(16 - image->comps[x].prec, 8), 0); + adjust[x] = FFMAX(FFMIN(av_pix_fmt_desc_get(picture->format)->comp[x].depth_minus1 + 1 - image->comps[x].prec, 8), 0); for (index = 0; index < image->numcomps; index++) { comp_data = image->comps[index].data; diff --git a/libavcodec/libopenjpegenc.c b/libavcodec/libopenjpegenc.c index c7769f7a02..6c5aab14ee 100644 --- a/libavcodec/libopenjpegenc.c +++ b/libavcodec/libopenjpegenc.c @@ -480,7 +480,7 @@ static int libopenjpeg_encode_frame(AVCodecContext *avctx, AVPacket *pkt, opj_cio_t *stream = ctx->stream; int cpyresult = 0; int ret, len; - AVFrame gbrframe; + AVFrame *gbrframe; switch (avctx->pix_fmt) { case AV_PIX_FMT_RGB24: @@ -501,18 +501,22 @@ static int libopenjpeg_encode_frame(AVCodecContext *avctx, AVPacket *pkt, case AV_PIX_FMT_GBRP12: case AV_PIX_FMT_GBRP14: case AV_PIX_FMT_GBRP16: - gbrframe = *frame; - gbrframe.data[0] = frame->data[2]; // swap to be rgb - gbrframe.data[1] = frame->data[0]; - gbrframe.data[2] = frame->data[1]; - gbrframe.linesize[0] = frame->linesize[2]; - gbrframe.linesize[1] = frame->linesize[0]; - gbrframe.linesize[2] = frame->linesize[1]; + gbrframe = av_frame_alloc(); + if (!gbrframe) + return AVERROR(ENOMEM); + av_frame_ref(gbrframe, frame); + gbrframe->data[0] = frame->data[2]; // swap to be rgb + gbrframe->data[1] = frame->data[0]; + gbrframe->data[2] = frame->data[1]; + gbrframe->linesize[0] = frame->linesize[2]; + gbrframe->linesize[1] = frame->linesize[0]; + gbrframe->linesize[2] = frame->linesize[1]; if (avctx->pix_fmt == AV_PIX_FMT_GBR24P) { - cpyresult = libopenjpeg_copy_unpacked8(avctx, &gbrframe, image); + cpyresult = libopenjpeg_copy_unpacked8(avctx, gbrframe, image); } else { - cpyresult = libopenjpeg_copy_unpacked16(avctx, &gbrframe, image); + cpyresult = libopenjpeg_copy_unpacked16(avctx, gbrframe, image); } + av_frame_free(&gbrframe); break; case AV_PIX_FMT_GRAY8: case AV_PIX_FMT_YUV410P: diff --git a/libavcodec/libopusenc.c b/libavcodec/libopusenc.c index 97d3bba180..8ceb877f38 100644 --- a/libavcodec/libopusenc.c +++ b/libavcodec/libopusenc.c @@ -400,7 +400,7 @@ static const AVOption libopus_options[] = { { "voip", "Favor improved speech intelligibility", 0, AV_OPT_TYPE_CONST, { .i64 = OPUS_APPLICATION_VOIP }, 0, 0, FLAGS, "application" }, { "audio", "Favor faithfulness to the input", 0, AV_OPT_TYPE_CONST, { .i64 = OPUS_APPLICATION_AUDIO }, 0, 0, FLAGS, "application" }, { "lowdelay", "Restrict to only the lowest delay modes", 0, AV_OPT_TYPE_CONST, { .i64 = OPUS_APPLICATION_RESTRICTED_LOWDELAY }, 0, 0, FLAGS, "application" }, - { "frame_duration", "Duration of a frame in milliseconds", OFFSET(frame_duration), AV_OPT_TYPE_FLOAT, { .dbl = 10.0 }, 2.5, 60.0, FLAGS }, + { "frame_duration", "Duration of a frame in milliseconds", OFFSET(frame_duration), AV_OPT_TYPE_FLOAT, { .dbl = 20.0 }, 2.5, 60.0, FLAGS }, { "packet_loss", "Expected packet loss percentage", OFFSET(packet_loss), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 100, FLAGS }, { "vbr", "Variable bit rate mode", OFFSET(vbr), AV_OPT_TYPE_INT, { .i64 = 1 }, 0, 2, FLAGS, "vbr" }, { "off", "Use constant bit rate", 0, AV_OPT_TYPE_CONST, { .i64 = 0 }, 0, 0, FLAGS, "vbr" }, diff --git a/libavcodec/libschroedingerenc.c b/libavcodec/libschroedingerenc.c index 43530e8536..f3455df1f3 100644 --- a/libavcodec/libschroedingerenc.c +++ b/libavcodec/libschroedingerenc.c @@ -47,9 +47,6 @@ typedef struct SchroEncoderParams { /** Schroedinger frame format */ SchroFrameFormat frame_format; - /** frame being encoded */ - AVFrame picture; - /** frame size */ int frame_size; @@ -162,7 +159,9 @@ static av_cold int libschroedinger_encode_init(AVCodecContext *avctx) avctx->width, avctx->height); - avctx->coded_frame = &p_schro_params->picture; + avctx->coded_frame = av_frame_alloc(); + if (!avctx->coded_frame) + return AVERROR(ENOMEM); if (!avctx->gop_size) { schro_encoder_setting_set_double(p_schro_params->encoder, @@ -427,6 +426,8 @@ static int libschroedinger_encode_close(AVCodecContext *avctx) /* Free the video format structure. */ av_freep(&p_schro_params->format); + av_frame_free(&avctx->coded_frame); + return 0; } diff --git a/libavcodec/libutvideodec.cpp b/libavcodec/libutvideodec.cpp index 0fae9f78f4..0bf2abe769 100644 --- a/libavcodec/libutvideodec.cpp +++ b/libavcodec/libutvideodec.cpp @@ -164,7 +164,7 @@ static int utvideo_decode_frame(AVCodecContext *avctx, void *data, } *got_frame = 1; - *(AVFrame *)data = *pic; + av_frame_move_ref((AVFrame*)data, pic); return avpkt->size; } diff --git a/libavcodec/libvorbisenc.c b/libavcodec/libvorbisenc.c index a2faac702b..2a9f067409 100644 --- a/libavcodec/libvorbisenc.c +++ b/libavcodec/libvorbisenc.c @@ -41,7 +41,6 @@ typedef struct OggVorbisEncContext { AVClass *av_class; /**< class for AVOptions */ - AVFrame frame; vorbis_info vi; /**< vorbis_info used during init */ vorbis_dsp_state vd; /**< DSP state used for analysis */ vorbis_block vb; /**< vorbis_block used for analysis */ @@ -351,7 +350,8 @@ static int oggvorbis_encode_frame(AVCodecContext *avctx, AVPacket *avpkt, avctx->delay = duration; av_assert0(!s->afq.remaining_delay); s->afq.frames->duration += duration; - s->afq.frames->pts -= duration; + if (s->afq.frames->pts != AV_NOPTS_VALUE) + s->afq.frames->pts -= duration; s->afq.remaining_samples += duration; } ff_af_queue_remove(&s->afq, duration, &avpkt->pts, &avpkt->duration); diff --git a/libavcodec/libx264.c b/libavcodec/libx264.c index 4093510c66..39338d3f38 100644 --- a/libavcodec/libx264.c +++ b/libavcodec/libx264.c @@ -44,7 +44,6 @@ typedef struct X264Context { x264_picture_t pic; uint8_t *sei; int sei_size; - AVFrame out_pic; char *preset; char *tune; char *profile; @@ -208,20 +207,20 @@ static int X264_frame(AVCodecContext *ctx, AVPacket *pkt, const AVFrame *frame, switch (pic_out.i_type) { case X264_TYPE_IDR: case X264_TYPE_I: - x4->out_pic.pict_type = AV_PICTURE_TYPE_I; + ctx->coded_frame->pict_type = AV_PICTURE_TYPE_I; break; case X264_TYPE_P: - x4->out_pic.pict_type = AV_PICTURE_TYPE_P; + ctx->coded_frame->pict_type = AV_PICTURE_TYPE_P; break; case X264_TYPE_B: case X264_TYPE_BREF: - x4->out_pic.pict_type = AV_PICTURE_TYPE_B; + ctx->coded_frame->pict_type = AV_PICTURE_TYPE_B; break; } pkt->flags |= AV_PKT_FLAG_KEY*pic_out.b_keyframe; if (ret) - x4->out_pic.quality = (pic_out.i_qpplus1 - 1) * FF_QP2LAMBDA; + ctx->coded_frame->quality = (pic_out.i_qpplus1 - 1) * FF_QP2LAMBDA; *got_packet = ret; return 0; @@ -237,6 +236,8 @@ static av_cold int X264_close(AVCodecContext *avctx) if (x4->enc) x264_encoder_close(x4->enc); + av_frame_free(&avctx->coded_frame); + return 0; } @@ -354,19 +355,6 @@ static av_cold int X264_init(AVCodecContext *avctx) OPT_STR("level", x4->level); - if(x4->x264opts){ - const char *p= x4->x264opts; - while(p){ - char param[256]={0}, val[256]={0}; - if(sscanf(p, "%255[^:=]=%255[^:]", param, val) == 1){ - OPT_STR(param, "1"); - }else - OPT_STR(param, val); - p= strchr(p, ':'); - p+=!!p; - } - } - if (avctx->i_quant_factor > 0) x4->params.rc.f_ip_factor = 1 / fabs(avctx->i_quant_factor); @@ -542,6 +530,19 @@ static av_cold int X264_init(AVCodecContext *avctx) if (avctx->flags & CODEC_FLAG_GLOBAL_HEADER) x4->params.b_repeat_headers = 0; + if(x4->x264opts){ + const char *p= x4->x264opts; + while(p){ + char param[256]={0}, val[256]={0}; + if(sscanf(p, "%255[^:=]=%255[^:]", param, val) == 1){ + OPT_STR(param, "1"); + }else + OPT_STR(param, val); + p= strchr(p, ':'); + p+=!!p; + } + } + if (x4->x264_params) { AVDictionary *dict = NULL; AVDictionaryEntry *en = NULL; @@ -570,7 +571,9 @@ static av_cold int X264_init(AVCodecContext *avctx) if (!x4->enc) return -1; - avctx->coded_frame = &x4->out_pic; + avctx->coded_frame = av_frame_alloc(); + if (!avctx->coded_frame) + return AVERROR(ENOMEM); if (avctx->flags & CODEC_FLAG_GLOBAL_HEADER) { x264_nal_t *nal; diff --git a/libavcodec/libxavs.c b/libavcodec/libxavs.c index f7b99e0bcd..ffe3411c96 100644 --- a/libavcodec/libxavs.c +++ b/libavcodec/libxavs.c @@ -45,7 +45,6 @@ typedef struct XavsContext { xavs_picture_t pic; uint8_t *sei; int sei_size; - AVFrame out_pic; int end_of_stream; float crf; int cqp; @@ -111,10 +110,10 @@ static int encode_nals(AVCodecContext *ctx, AVPacket *pkt, return 1; } -static int XAVS_frame(AVCodecContext *ctx, AVPacket *pkt, +static int XAVS_frame(AVCodecContext *avctx, AVPacket *pkt, const AVFrame *frame, int *got_packet) { - XavsContext *x4 = ctx->priv_data; + XavsContext *x4 = avctx->priv_data; xavs_nal_t *nal; int nnal, i, ret; xavs_picture_t pic_out; @@ -130,67 +129,67 @@ static int XAVS_frame(AVCodecContext *ctx, AVPacket *pkt, x4->pic.i_pts = frame->pts; x4->pic.i_type = XAVS_TYPE_AUTO; - x4->pts_buffer[ctx->frame_number % (ctx->max_b_frames+1)] = frame->pts; + x4->pts_buffer[avctx->frame_number % (avctx->max_b_frames+1)] = frame->pts; } if (xavs_encoder_encode(x4->enc, &nal, &nnal, frame? &x4->pic: NULL, &pic_out) < 0) return -1; - ret = encode_nals(ctx, pkt, nal, nnal); + ret = encode_nals(avctx, pkt, nal, nnal); if (ret < 0) return -1; if (!ret) { if (!frame && !(x4->end_of_stream)) { - if ((ret = ff_alloc_packet2(ctx, pkt, 4)) < 0) + if ((ret = ff_alloc_packet2(avctx, pkt, 4)) < 0) return ret; pkt->data[0] = 0x0; pkt->data[1] = 0x0; pkt->data[2] = 0x01; pkt->data[3] = 0xb1; - pkt->dts = 2*x4->pts_buffer[(x4->out_frame_count-1)%(ctx->max_b_frames+1)] - - x4->pts_buffer[(x4->out_frame_count-2)%(ctx->max_b_frames+1)]; + pkt->dts = 2*x4->pts_buffer[(x4->out_frame_count-1)%(avctx->max_b_frames+1)] - + x4->pts_buffer[(x4->out_frame_count-2)%(avctx->max_b_frames+1)]; x4->end_of_stream = END_OF_STREAM; *got_packet = 1; } return 0; } - x4->out_pic.pts = pic_out.i_pts; + avctx->coded_frame->pts = pic_out.i_pts; pkt->pts = pic_out.i_pts; - if (ctx->has_b_frames) { + if (avctx->has_b_frames) { if (!x4->out_frame_count) pkt->dts = pkt->pts - (x4->pts_buffer[1] - x4->pts_buffer[0]); else - pkt->dts = x4->pts_buffer[(x4->out_frame_count-1)%(ctx->max_b_frames+1)]; + pkt->dts = x4->pts_buffer[(x4->out_frame_count-1)%(avctx->max_b_frames+1)]; } else pkt->dts = pkt->pts; switch (pic_out.i_type) { case XAVS_TYPE_IDR: case XAVS_TYPE_I: - x4->out_pic.pict_type = AV_PICTURE_TYPE_I; + avctx->coded_frame->pict_type = AV_PICTURE_TYPE_I; break; case XAVS_TYPE_P: - x4->out_pic.pict_type = AV_PICTURE_TYPE_P; + avctx->coded_frame->pict_type = AV_PICTURE_TYPE_P; break; case XAVS_TYPE_B: case XAVS_TYPE_BREF: - x4->out_pic.pict_type = AV_PICTURE_TYPE_B; + avctx->coded_frame->pict_type = AV_PICTURE_TYPE_B; break; } /* There is no IDR frame in AVS JiZhun */ /* Sequence header is used as a flag */ if (pic_out.i_type == XAVS_TYPE_I) { - x4->out_pic.key_frame = 1; + avctx->coded_frame->key_frame = 1; pkt->flags |= AV_PKT_FLAG_KEY; } - x4->out_pic.quality = (pic_out.i_qpplus1 - 1) * FF_QP2LAMBDA; + avctx->coded_frame->quality = (pic_out.i_qpplus1 - 1) * FF_QP2LAMBDA; x4->out_frame_count++; *got_packet = ret; @@ -208,6 +207,8 @@ static av_cold int XAVS_close(AVCodecContext *avctx) if (x4->enc) xavs_encoder_close(x4->enc); + av_frame_free(&avctx->coded_frame); + return 0; } @@ -355,7 +356,10 @@ static av_cold int XAVS_init(AVCodecContext *avctx) if (!(x4->pts_buffer = av_mallocz((avctx->max_b_frames+1) * sizeof(*x4->pts_buffer)))) return AVERROR(ENOMEM); - avctx->coded_frame = &x4->out_pic; + avctx->coded_frame = av_frame_alloc(); + if (!avctx->coded_frame) + return AVERROR(ENOMEM); + /* TAG: Do we have GLOBAL HEADER in AVS */ /* We Have PPS and SPS in AVS */ if (avctx->flags & CODEC_FLAG_GLOBAL_HEADER) { diff --git a/libavcodec/libxvid.c b/libavcodec/libxvid.c index d4c71490e7..97ab2d4a07 100644 --- a/libavcodec/libxvid.c +++ b/libavcodec/libxvid.c @@ -48,6 +48,7 @@ * This stores all the private context for the codec. */ struct xvid_context { + AVClass *class; void *encoder_handle; /**< Handle for Xvid encoder */ int xsize; /**< Frame x size */ int ysize; /**< Frame y size */ @@ -56,7 +57,6 @@ struct xvid_context { int me_flags; /**< Motion Estimation flags */ int qscale; /**< Do we use constant scale? */ int quicktime_format; /**< Are we in a QT-based format? */ - AVFrame encoded_picture; /**< Encoded frame information */ char *twopassbuffer; /**< Character buffer for two-pass */ char *old_twopassbuffer; /**< Old character buffer (two-pass) */ char *twopassfile; /**< second pass temp file name */ @@ -651,7 +651,9 @@ static av_cold int xvid_encode_init(AVCodecContext *avctx) { } x->encoder_handle = xvid_enc_create.handle; - avctx->coded_frame = &x->encoded_picture; + avctx->coded_frame = av_frame_alloc(); + if (!avctx->coded_frame) + return AVERROR(ENOMEM); return 0; fail: @@ -665,7 +667,7 @@ static int xvid_encode_frame(AVCodecContext *avctx, AVPacket *pkt, int xerr, i, ret, user_packet = !!pkt->data; char *tmp; struct xvid_context *x = avctx->priv_data; - AVFrame *p = &x->encoded_picture; + AVFrame *p = avctx->coded_frame; int mb_width = (avctx->width + 15) / 16; int mb_height = (avctx->height + 15) / 16; @@ -678,7 +680,6 @@ static int xvid_encode_frame(AVCodecContext *avctx, AVPacket *pkt, /* Start setting up the frame */ xvid_enc_frame.version = XVID_VERSION; xvid_enc_stats.version = XVID_VERSION; - *p = *picture; /* Let Xvid know where to put the frame. */ xvid_enc_frame.bitstream = pkt->data; diff --git a/libavcodec/lpc.c b/libavcodec/lpc.c index 1d52edf744..a6f23775a5 100644 --- a/libavcodec/lpc.c +++ b/libavcodec/lpc.c @@ -20,7 +20,7 @@ */ #include "libavutil/common.h" -#include "libavutil/lls.h" +#include "libavutil/lls2.h" #define LPC_USE_DOUBLE #include "lpc.h" @@ -208,7 +208,7 @@ int ff_lpc_calc_coefs(LPCContext *s, } if (lpc_type == FF_LPC_TYPE_CHOLESKY) { - LLSModel m[2]; + LLSModel2 m[2]; LOCAL_ALIGNED(32, double, var, [FFALIGN(MAX_LPC_ORDER+1,4)]); double av_uninit(weight); memset(var, 0, FFALIGN(MAX_LPC_ORDER+1,4)*sizeof(*var)); @@ -217,7 +217,7 @@ int ff_lpc_calc_coefs(LPCContext *s, m[0].coeff[max_order-1][j] = -lpc[max_order-1][j]; for(; pass 63) { + av_log(a->avctx, AV_LOG_ERROR, + "ac-tex damaged at %d %d\n", a->mb_x, a->mb_y); + return AVERROR_INVALIDDATA; + } j = scantable[i]; level = (level * qscale * quant_matrix[j]) >> 3; level = (level ^ SHOW_SBITS(re, &a->gb, 1)) - SHOW_SBITS(re, &a->gb, 1); @@ -93,8 +98,13 @@ static inline int mdec_decode_block_intra(MDECContext *a, int16_t *block, int n) run = SHOW_UBITS(re, &a->gb, 6)+1; LAST_SKIP_BITS(re, &a->gb, 6); UPDATE_CACHE(re, &a->gb); level = SHOW_SBITS(re, &a->gb, 10); SKIP_BITS(re, &a->gb, 10); - i += run; - j = scantable[i]; + i += run; + if (i > 63) { + av_log(a->avctx, AV_LOG_ERROR, + "ac-tex damaged at %d %d\n", a->mb_x, a->mb_y); + return AVERROR_INVALIDDATA; + } + j = scantable[i]; if (level < 0) { level = -level; level = (level * qscale * quant_matrix[j]) >> 3; @@ -105,10 +115,6 @@ static inline int mdec_decode_block_intra(MDECContext *a, int16_t *block, int n) level = (level - 1) | 1; } } - if (i > 63) { - av_log(a->avctx, AV_LOG_ERROR, "ac-tex damaged at %d %d\n", a->mb_x, a->mb_y); - return AVERROR_INVALIDDATA; - } block[j] = level; } diff --git a/libavcodec/mips/acelp_filters_mips.c b/libavcodec/mips/acelp_filters_mips.c index c8d980aa00..ffc0fe6250 100644 --- a/libavcodec/mips/acelp_filters_mips.c +++ b/libavcodec/mips/acelp_filters_mips.c @@ -89,7 +89,7 @@ static void ff_acelp_interpolatef_mips(float *out, const float *in, "addu %[p_filter_coeffs_m], %[p_filter_coeffs_m], %[prec] \n\t" "madd.s %[v],%[v],%[in_val_m], %[fc_val_m] \n\t" - : [v] "=&f" (v),[p_in_p] "+r" (p_in_p), [p_in_m] "+r" (p_in_m), + : [v] "+&f" (v),[p_in_p] "+r" (p_in_p), [p_in_m] "+r" (p_in_m), [p_filter_coeffs_p] "+r" (p_filter_coeffs_p), [in_val_p] "=&f" (in_val_p), [in_val_m] "=&f" (in_val_m), [fc_val_p] "=&f" (fc_val_p), [fc_val_m] "=&f" (fc_val_m), diff --git a/libavcodec/mjpegbdec.c b/libavcodec/mjpegbdec.c index f061f0bc26..61640952ff 100644 --- a/libavcodec/mjpegbdec.c +++ b/libavcodec/mjpegbdec.c @@ -119,7 +119,7 @@ read_header: 8 * FFMIN(field_size, buf_end - buf_ptr - sos_offs)); s->mjpb_skiptosod = (sod_offs - sos_offs - show_bits(&s->gb, 16)); s->start_code = SOS; - if (ff_mjpeg_decode_sos(s, NULL, NULL) < 0 && + if (ff_mjpeg_decode_sos(s, NULL, 0, NULL) < 0 && (avctx->err_recognition & AV_EF_EXPLODE)) return AVERROR_INVALIDDATA; } diff --git a/libavcodec/mjpegdec.c b/libavcodec/mjpegdec.c index 5c25a07ac4..11f7500761 100644 --- a/libavcodec/mjpegdec.c +++ b/libavcodec/mjpegdec.c @@ -87,9 +87,12 @@ av_cold int ff_mjpeg_decode_init(AVCodecContext *avctx) { MJpegDecodeContext *s = avctx->priv_data; - if (!s->picture_ptr) - s->picture_ptr = &s->picture; - avcodec_get_frame_defaults(&s->picture); + if (!s->picture_ptr) { + s->picture = av_frame_alloc(); + if (!s->picture) + return AVERROR(ENOMEM); + s->picture_ptr = s->picture; + } s->avctx = avctx; ff_hpeldsp_init(&s->hdsp, avctx->flags); @@ -215,7 +218,7 @@ int ff_mjpeg_decode_dht(MJpegDecodeContext *s) int ff_mjpeg_decode_sof(MJpegDecodeContext *s) { - int len, nb_components, i, width, height, pix_fmt_id; + int len, nb_components, i, width, height, bits, pix_fmt_id; int h_count[MAX_COMPONENTS]; int v_count[MAX_COMPONENTS]; @@ -225,11 +228,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){ @@ -259,7 +262,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"); @@ -305,11 +308,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; @@ -331,7 +336,7 @@ int ff_mjpeg_decode_sof(MJpegDecodeContext *s) s->first_picture = 0; } - if (s->interlaced && (s->bottom_field == !s->interlace_polarity)) { + if (s->got_picture && s->interlaced && (s->bottom_field == !s->interlace_polarity)) { if (s->progressive) { avpriv_request_sample(s->avctx, "progressively coded interlaced picture"); return AVERROR_INVALIDDATA; @@ -466,9 +471,12 @@ unk_pixfmt: } if (s->ls) { s->upscale_h = s->upscale_v = 0; - if (s->nb_components > 1) + if (s->nb_components == 3) { s->avctx->pix_fmt = AV_PIX_FMT_RGB24; - else if (s->bits <= 8) + } else if (s->nb_components != 1) { + av_log(s->avctx, AV_LOG_ERROR, "Unsupported number of components %d\n", s->nb_components); + return AVERROR_PATCHWELCOME; + } else if (s->bits <= 8) s->avctx->pix_fmt = AV_PIX_FMT_GRAY8; else s->avctx->pix_fmt = AV_PIX_FMT_GRAY16; @@ -823,7 +831,7 @@ static int ljpeg_decode_rgb_scan(MJpegDecodeContext *s, int nb_components, int p buffer[0][i] = 1 << (s->bits - 1); for (mb_y = 0; mb_y < s->mb_height; mb_y++) { - uint8_t *ptr = s->picture.data[0] + (linesize * mb_y); + uint8_t *ptr = s->picture_ptr->data[0] + (linesize * mb_y); if (s->interlaced && s->bottom_field) ptr += linesize >> 1; @@ -957,7 +965,7 @@ static int ljpeg_decode_yuv_scan(MJpegDecodeContext *s, int predictor, if(dc == 0xFFFFF) return -1; if(bits<=8){ - ptr = s->picture.data[c] + (linesize * (v * mb_y + y)) + (h * mb_x + x); //FIXME optimize this crap + ptr = s->picture_ptr->data[c] + (linesize * (v * mb_y + y)) + (h * mb_x + x); //FIXME optimize this crap if(y==0 && toprow){ if(x==0 && leftcol){ pred= 1 << (bits - 1); @@ -977,7 +985,7 @@ static int ljpeg_decode_yuv_scan(MJpegDecodeContext *s, int predictor, pred &= mask; *ptr= pred + (dc << point_transform); }else{ - ptr16 = (uint16_t*)(s->picture.data[c] + 2*(linesize * (v * mb_y + y)) + 2*(h * mb_x + x)); //FIXME optimize this crap + ptr16 = (uint16_t*)(s->picture_ptr->data[c] + 2*(linesize * (v * mb_y + y)) + 2*(h * mb_x + x)); //FIXME optimize this crap if(y==0 && toprow){ if(x==0 && leftcol){ pred= 1 << (bits - 1); @@ -1025,7 +1033,7 @@ static int ljpeg_decode_yuv_scan(MJpegDecodeContext *s, int predictor, if(dc == 0xFFFFF) return -1; if(bits<=8){ - ptr = s->picture.data[c] + + ptr = s->picture_ptr->data[c] + (linesize * (v * mb_y + y)) + (h * mb_x + x); //FIXME optimize this crap PREDICT(pred, ptr[-linesize-1], ptr[-linesize], ptr[-1], predictor); @@ -1033,7 +1041,7 @@ static int ljpeg_decode_yuv_scan(MJpegDecodeContext *s, int predictor, pred &= mask; *ptr = pred + (dc << point_transform); }else{ - ptr16 = (uint16_t*)(s->picture.data[c] + 2*(linesize * (v * mb_y + y)) + 2*(h * mb_x + x)); //FIXME optimize this crap + ptr16 = (uint16_t*)(s->picture_ptr->data[c] + 2*(linesize * (v * mb_y + y)) + 2*(h * mb_x + x)); //FIXME optimize this crap PREDICT(pred, ptr16[-linesize-1], ptr16[-linesize], ptr16[-1], predictor); pred &= mask; @@ -1089,6 +1097,7 @@ static void shift_output(MJpegDecodeContext *s, uint8_t *ptr, int linesize) static int mjpeg_decode_scan(MJpegDecodeContext *s, int nb_components, int Ah, int Al, const uint8_t *mb_bitmask, + int mb_bitmask_size, const AVFrame *reference) { int i, mb_x, mb_y; @@ -1098,8 +1107,13 @@ static int mjpeg_decode_scan(MJpegDecodeContext *s, int nb_components, int Ah, GetBitContext mb_bitmask_gb; int bytes_per_pixel = 1 + (s->bits > 8); - if (mb_bitmask) + if (mb_bitmask) { + if (mb_bitmask_size != (s->mb_width * s->mb_height + 7)>>3) { + av_log(s->avctx, AV_LOG_ERROR, "mb_bitmask_size mismatches\n"); + return AVERROR_INVALIDDATA; + } init_get_bits(&mb_bitmask_gb, mb_bitmask, s->mb_width * s->mb_height); + } if (s->flipped && s->avctx->lowres) { av_log(s->avctx, AV_LOG_ERROR, "Can not flip image with lowres\n"); @@ -1150,13 +1164,18 @@ static int mjpeg_decode_scan(MJpegDecodeContext *s, int nb_components, int Ah, if (s->interlaced && s->bottom_field) block_offset += linesize[c] >> 1; - ptr = data[c] + block_offset; + if ( 8*(h * mb_x + x) < s->width + && 8*(v * mb_y + y) < s->height) { + ptr = data[c] + block_offset; + } else + ptr = NULL; if (!s->progressive) { - if (copy_mb) - mjpeg_copy_block(s, ptr, reference_data[c] + block_offset, - linesize[c], s->avctx->lowres); + if (copy_mb) { + if (ptr) + mjpeg_copy_block(s, ptr, reference_data[c] + block_offset, + linesize[c], s->avctx->lowres); - else { + } else { s->dsp.clear_block(s->block); if (decode_block(s, s->block, i, s->dc_index[i], s->ac_index[i], @@ -1165,9 +1184,11 @@ static int mjpeg_decode_scan(MJpegDecodeContext *s, int nb_components, int Ah, "error y=%d x=%d\n", mb_y, mb_x); return AVERROR_INVALIDDATA; } - s->dsp.idct_put(ptr, linesize[c], s->block); - if (s->bits & 7) - shift_output(s, ptr, linesize[c]); + if (ptr) { + s->dsp.idct_put(ptr, linesize[c], s->block); + if (s->bits & 7) + shift_output(s, ptr, linesize[c]); + } } } else { int block_idx = s->block_stride[c] * (v * mb_y + y) + @@ -1207,7 +1228,7 @@ static int mjpeg_decode_scan_progressive_ac(MJpegDecodeContext *s, int ss, int mb_x, mb_y; int EOBRUN = 0; int c = s->comp_index[0]; - uint8_t *data = s->picture.data[c]; + uint8_t *data = s->picture_ptr->data[c]; int linesize = s->linesize[c]; int last_scan = 0; int16_t *quant_matrix = s->quant_matrixes[s->quant_sindex[0]]; @@ -1220,7 +1241,7 @@ static int mjpeg_decode_scan_progressive_ac(MJpegDecodeContext *s, int ss, } if (!Al) { - s->coefs_finished[c] |= (1LL << (se + 1)) - (1LL << ss); + s->coefs_finished[c] |= (2LL << se) - (1LL << ss); last_scan = !~s->coefs_finished[c]; } @@ -1265,7 +1286,7 @@ static int mjpeg_decode_scan_progressive_ac(MJpegDecodeContext *s, int ss, } int ff_mjpeg_decode_sos(MJpegDecodeContext *s, const uint8_t *mb_bitmask, - const AVFrame *reference) + int mb_bitmask_size, const AVFrame *reference) { int len, nb_components, i, h, v, predictor, point_transform; int index, id, ret; @@ -1368,7 +1389,7 @@ next_field: s->last_dc[i] = (4 << s->bits); if (s->lossless) { - av_assert0(s->picture_ptr == &s->picture); + av_assert0(s->picture_ptr == s->picture); if (CONFIG_JPEGLS_DECODER && s->ls) { // for () { // reset_ls_coding_parameters(s, 0); @@ -1389,7 +1410,7 @@ next_field: } } else { if (s->progressive && predictor) { - av_assert0(s->picture_ptr == &s->picture); + av_assert0(s->picture_ptr == s->picture); if ((ret = mjpeg_decode_scan_progressive_ac(s, predictor, ilv, prev_shift, point_transform)) < 0) @@ -1397,7 +1418,7 @@ next_field: } else { if ((ret = mjpeg_decode_scan(s, nb_components, prev_shift, point_transform, - mb_bitmask, reference)) < 0) + mb_bitmask, mb_bitmask_size, reference)) < 0) return ret; } } @@ -1441,7 +1462,7 @@ static int mjpeg_decode_app(MJpegDecodeContext *s) int len, id, i; len = get_bits(&s->gb, 16); - if (len < 5) + if (len < 6) return AVERROR_INVALIDDATA; if (8 * len > get_bits_left(&s->gb)) return AVERROR_INVALIDDATA; @@ -1517,6 +1538,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"); @@ -1526,17 +1549,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) { @@ -1555,7 +1588,7 @@ static int mjpeg_decode_app(MJpegDecodeContext *s) } /* EXIF metadata */ - if (s->start_code == APP1 && id == AV_RB32("Exif")) { + if (s->start_code == APP1 && id == AV_RB32("Exif") && len >= 2) { GetByteContext gbytes; int ret, le, ifd_offset, bytes_read; const uint8_t *aligned; @@ -1647,7 +1680,7 @@ static int mjpeg_decode_com(MJpegDecodeContext *s) s->interlace_polarity = 1; } else if (!strcmp(cbuf, "CS=ITU601")) s->cs_itu601 = 1; - else if ((!strncmp(cbuf, "Intel(R) JPEG Library, version 1", 32)) || + else if ((!strncmp(cbuf, "Intel(R) JPEG Library, version 1", 32) && s->avctx->codec_tag) || (!strncmp(cbuf, "Metasoft MJPEG Codec", 20))) s->flipped = 1; @@ -1732,8 +1765,6 @@ int ff_mjpeg_find_marker(MJpegDecodeContext *s, int t = 0, b = 0; PutBitContext pb; - s->cur_scan++; - /* find marker */ while (src + t < buf_end) { uint8_t x = src[t++]; @@ -1755,6 +1786,10 @@ int ff_mjpeg_find_marker(MJpegDecodeContext *s, put_bits(&pb, 8, x); if (x == 0xFF) { x = src[b++]; + if (x & 0x80) { + av_log(s->avctx, AV_LOG_WARNING, "Invalid escape sequence\n"); + x &= 0x7f; + } put_bits(&pb, 7, x); bit_count--; } @@ -1798,7 +1833,7 @@ int ff_mjpeg_decode_frame(AVCodecContext *avctx, void *data, int *got_frame, &unescaped_buf_size); /* EOF */ if (start_code < 0) { - goto the_end; + break; } else if (unescaped_buf_size > INT_MAX / 8) { av_log(avctx, AV_LOG_ERROR, "MJPEG packet 0x%x too big (%d/%d), corrupt data?\n", @@ -1923,7 +1958,8 @@ eoi_parser: goto the_end; case SOS: - if ((ret = ff_mjpeg_decode_sos(s, NULL, NULL)) < 0 && + s->cur_scan++; + if ((ret = ff_mjpeg_decode_sos(s, NULL, 0, NULL)) < 0 && (avctx->err_recognition & AV_EF_EXPLODE)) goto fail; break; @@ -1951,7 +1987,7 @@ eoi_parser: "marker parser used %d bytes (%d bits)\n", (get_bits_count(&s->gb) + 7) / 8, get_bits_count(&s->gb)); } - if (s->got_picture) { + if (s->got_picture && s->cur_scan) { av_log(avctx, AV_LOG_WARNING, "EOI missing, emulating\n"); goto eoi_parser; } @@ -2035,7 +2071,10 @@ av_cold int ff_mjpeg_decode_end(AVCodecContext *avctx) av_log(avctx, AV_LOG_INFO, "Single field\n"); } - if (s->picture_ptr) + if (s->picture) { + av_frame_free(&s->picture); + s->picture_ptr = NULL; + } else if (s->picture_ptr) av_frame_unref(s->picture_ptr); av_free(s->buffer); diff --git a/libavcodec/mjpegdec.h b/libavcodec/mjpegdec.h index fa69d50389..abfa9a3475 100644 --- a/libavcodec/mjpegdec.h +++ b/libavcodec/mjpegdec.h @@ -90,7 +90,7 @@ typedef struct MJpegDecodeContext { int h_max, v_max; /* maximum h and v counts */ int quant_index[4]; /* quant table index for each component */ int last_dc[MAX_COMPONENTS]; /* last DEQUANTIZED dc (XXX: am I right to do that ?) */ - AVFrame picture; /* picture structure */ + AVFrame *picture; /* picture structure */ AVFrame *picture_ptr; /* pointer to picture structure */ int got_picture; ///< we found a SOF and picture is valid, too. int linesize[MAX_COMPONENTS]; ///< linesize << interlaced @@ -131,7 +131,8 @@ int ff_mjpeg_decode_dqt(MJpegDecodeContext *s); int ff_mjpeg_decode_dht(MJpegDecodeContext *s); int ff_mjpeg_decode_sof(MJpegDecodeContext *s); int ff_mjpeg_decode_sos(MJpegDecodeContext *s, - const uint8_t *mb_bitmask, const AVFrame *reference); + const uint8_t *mb_bitmask,int mb_bitmask_size, + const AVFrame *reference); int ff_mjpeg_find_marker(MJpegDecodeContext *s, const uint8_t **buf_ptr, const uint8_t *buf_end, const uint8_t **unescaped_buf_ptr, int *unescaped_buf_size); diff --git a/libavcodec/mjpegenc.c b/libavcodec/mjpegenc.c index 74817cadc2..4abb0d3253 100644 --- a/libavcodec/mjpegenc.c +++ b/libavcodec/mjpegenc.c @@ -46,12 +46,12 @@ av_cold int ff_mjpeg_encode_init(MpegEncContext *s) if (s->width > 65500 || s->height > 65500) { av_log(s, AV_LOG_ERROR, "JPEG does not support resolutions above 65500x65500\n"); - return -1; + return AVERROR(EINVAL); } m = av_malloc(sizeof(MJpegContext)); if (!m) - return -1; + return AVERROR(ENOMEM); s->min_qcoeff=-1023; s->max_qcoeff= 1023; @@ -456,7 +456,7 @@ static void encode_block(MpegEncContext *s, int16_t *block, int n) put_bits(&s->pb, huff_size_ac[0], huff_code_ac[0]); } -void ff_mjpeg_encode_mb(MpegEncContext *s, int16_t block[6][64]) +void ff_mjpeg_encode_mb(MpegEncContext *s, int16_t block[12][64]) { int i; if (s->chroma_format == CHROMA_444) { @@ -498,19 +498,25 @@ static int amv_encode_picture(AVCodecContext *avctx, AVPacket *pkt, { MpegEncContext *s = avctx->priv_data; - AVFrame pic = *pic_arg; - int i; + AVFrame *pic; + int i, ret; //CODEC_FLAG_EMU_EDGE have to be cleared if(s->avctx->flags & CODEC_FLAG_EMU_EDGE) - return -1; + return AVERROR(EINVAL); + pic = av_frame_alloc(); + if (!pic) + return AVERROR(ENOMEM); + av_frame_ref(pic, pic_arg); //picture should be flipped upside-down for(i=0; i < 3; i++) { - pic.data[i] += (pic.linesize[i] * (s->mjpeg_vsample[i] * (8 * s->mb_height -((s->height/V_MAX)&7)) - 1 )); - pic.linesize[i] *= -1; + pic->data[i] += (pic->linesize[i] * (s->mjpeg_vsample[i] * (8 * s->mb_height -((s->height/V_MAX)&7)) - 1 )); + pic->linesize[i] *= -1; } - return ff_MPV_encode_picture(avctx, pkt, &pic, got_packet); + ret = ff_MPV_encode_picture(avctx, pkt, pic, got_packet); + av_frame_free(&pic); + return ret; } #if CONFIG_MJPEG_ENCODER diff --git a/libavcodec/mjpegenc.h b/libavcodec/mjpegenc.h index ce0c1cce15..041f026bba 100644 --- a/libavcodec/mjpegenc.h +++ b/libavcodec/mjpegenc.h @@ -56,6 +56,6 @@ void ff_mjpeg_encode_picture_trailer(MpegEncContext *s); void ff_mjpeg_encode_stuffing(MpegEncContext *s); void ff_mjpeg_encode_dc(MpegEncContext *s, int val, uint8_t *huff_size, uint16_t *huff_code); -void ff_mjpeg_encode_mb(MpegEncContext *s, int16_t block[6][64]); +void ff_mjpeg_encode_mb(MpegEncContext *s, int16_t block[12][64]); #endif /* AVCODEC_MJPEGENC_H */ diff --git a/libavcodec/mlpdec.c b/libavcodec/mlpdec.c index aab82939ab..f685c00d48 100644 --- a/libavcodec/mlpdec.c +++ b/libavcodec/mlpdec.c @@ -818,7 +818,7 @@ static int read_decoding_params(MLPDecodeContext *m, GetBitContext *gbp, return 0; } -#define MSB_MASK(bits) (-1u << bits) +#define MSB_MASK(bits) (-1u << (bits)) /** Generate PCM samples using the prediction filters and residual values * read from the data stream, and update the filter state. */ diff --git a/libavcodec/mmvideo.c b/libavcodec/mmvideo.c index 800e65c64c..22251269bc 100644 --- a/libavcodec/mmvideo.c +++ b/libavcodec/mmvideo.c @@ -48,7 +48,7 @@ typedef struct MmContext { AVCodecContext *avctx; - AVFrame frame; + AVFrame *frame; int palette[AVPALETTE_COUNT]; GetByteContext gb; } MmContext; @@ -61,7 +61,16 @@ static av_cold int mm_decode_init(AVCodecContext *avctx) avctx->pix_fmt = AV_PIX_FMT_PAL8; - avcodec_get_frame_defaults(&s->frame); + 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); return 0; } @@ -108,9 +117,9 @@ static int mm_decode_intra(MmContext * s, int half_horiz, int half_vert) return AVERROR_INVALIDDATA; if (color) { - memset(s->frame.data[0] + y*s->frame.linesize[0] + x, color, run_length); - if (half_vert) - memset(s->frame.data[0] + (y+1)*s->frame.linesize[0] + x, color, run_length); + memset(s->frame->data[0] + y*s->frame->linesize[0] + x, color, run_length); + 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; @@ -158,13 +167,13 @@ static int mm_decode_inter(MmContext * s, int half_horiz, int half_vert) return AVERROR_INVALIDDATA; if (replace) { int color = bytestream2_get_byte(&data_ptr); - s->frame.data[0][y*s->frame.linesize[0] + x] = color; + s->frame->data[0][y*s->frame->linesize[0] + x] = color; if (half_horiz) - s->frame.data[0][y*s->frame.linesize[0] + x + 1] = color; + s->frame->data[0][y*s->frame->linesize[0] + x + 1] = color; if (half_vert) { - s->frame.data[0][(y+1)*s->frame.linesize[0] + x] = color; + s->frame->data[0][(y+1)*s->frame->linesize[0] + x] = color; if (half_horiz) - s->frame.data[0][(y+1)*s->frame.linesize[0] + x + 1] = color; + s->frame->data[0][(y+1)*s->frame->linesize[0] + x + 1] = color; } } x += 1 + half_horiz; @@ -193,7 +202,7 @@ static int mm_decode_frame(AVCodecContext *avctx, buf_size -= MM_PREAMBLE_SIZE; bytestream2_init(&s->gb, buf, buf_size); - if ((res = ff_reget_buffer(avctx, &s->frame)) < 0) + if ((res = ff_reget_buffer(avctx, s->frame)) < 0) return res; switch(type) { @@ -211,9 +220,9 @@ static int mm_decode_frame(AVCodecContext *avctx, if (res < 0) return res; - memcpy(s->frame.data[1], s->palette, AVPALETTE_SIZE); + memcpy(s->frame->data[1], s->palette, AVPALETTE_SIZE); - if ((res = av_frame_ref(data, &s->frame)) < 0) + if ((res = av_frame_ref(data, s->frame)) < 0) return res; *got_frame = 1; @@ -225,7 +234,7 @@ static av_cold int mm_decode_end(AVCodecContext *avctx) { MmContext *s = avctx->priv_data; - av_frame_unref(&s->frame); + av_frame_free(&s->frame); return 0; } diff --git a/libavcodec/motion_est.c b/libavcodec/motion_est.c index f4d217bf30..02aeb2ef90 100644 --- a/libavcodec/motion_est.c +++ b/libavcodec/motion_est.c @@ -189,7 +189,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/motionpixels.c b/libavcodec/motionpixels.c index f8aa08bcb6..dbe4a68995 100644 --- a/libavcodec/motionpixels.c +++ b/libavcodec/motionpixels.c @@ -36,7 +36,7 @@ typedef struct HuffCode { typedef struct MotionPixelsContext { AVCodecContext *avctx; - AVFrame frame; + AVFrame *frame; DSPContext dsp; uint8_t *changes_map; int offset_bits_len; @@ -50,6 +50,19 @@ typedef struct MotionPixelsContext { int bswapbuf_size; } MotionPixelsContext; +static av_cold int mp_decode_end(AVCodecContext *avctx) +{ + MotionPixelsContext *mp = avctx->priv_data; + + av_freep(&mp->changes_map); + av_freep(&mp->vpt); + av_freep(&mp->hpt); + av_freep(&mp->bswapbuf); + av_frame_free(&mp->frame); + + return 0; +} + static av_cold int mp_decode_init(AVCodecContext *avctx) { MotionPixelsContext *mp = avctx->priv_data; @@ -75,7 +88,13 @@ static av_cold int mp_decode_init(AVCodecContext *avctx) return AVERROR(ENOMEM); } avctx->pix_fmt = AV_PIX_FMT_RGB555; - avcodec_get_frame_defaults(&mp->frame); + + mp->frame = av_frame_alloc(); + if (!mp->frame) { + mp_decode_end(avctx); + return AVERROR(ENOMEM); + } + return 0; } @@ -96,14 +115,14 @@ static void mp_read_changes_map(MotionPixelsContext *mp, GetBitContext *gb, int continue; w = FFMIN(w, mp->avctx->width - x); h = FFMIN(h, mp->avctx->height - y); - pixels = (uint16_t *)&mp->frame.data[0][y * mp->frame.linesize[0] + x * 2]; + pixels = (uint16_t *)&mp->frame->data[0][y * mp->frame->linesize[0] + x * 2]; while (h--) { mp->changes_map[offset] = w; if (read_color) for (i = 0; i < w; ++i) pixels[i] = color; offset += mp->avctx->width; - pixels += mp->frame.linesize[0] / 2; + pixels += mp->frame->linesize[0] / 2; } } } @@ -165,7 +184,7 @@ static YuvPixel mp_get_yuv_from_rgb(MotionPixelsContext *mp, int x, int y) { int color; - color = *(uint16_t *)&mp->frame.data[0][y * mp->frame.linesize[0] + x * 2]; + color = *(uint16_t *)&mp->frame->data[0][y * mp->frame->linesize[0] + x * 2]; return mp_rgb_yuv_table[color]; } @@ -174,7 +193,7 @@ static void mp_set_rgb_from_yuv(MotionPixelsContext *mp, int x, int y, const Yuv int color; color = mp_yuv_to_rgb(p->y, p->v, p->u, 1); - *(uint16_t *)&mp->frame.data[0][y * mp->frame.linesize[0] + x * 2] = color; + *(uint16_t *)&mp->frame->data[0][y * mp->frame->linesize[0] + x * 2] = color; } static int mp_get_vlc(MotionPixelsContext *mp, GetBitContext *gb) @@ -271,7 +290,7 @@ static int mp_decode_frame(AVCodecContext *avctx, GetBitContext gb; int i, count1, count2, sz, ret; - if ((ret = ff_reget_buffer(avctx, &mp->frame)) < 0) + if ((ret = ff_reget_buffer(avctx, mp->frame)) < 0) return ret; /* le32 bitstream msb first */ @@ -297,7 +316,7 @@ static int mp_decode_frame(AVCodecContext *avctx, goto end; if (mp->changes_map[0] == 0) { - *(uint16_t *)mp->frame.data[0] = get_bits(&gb, 15); + *(uint16_t *)mp->frame->data[0] = get_bits(&gb, 15); mp->changes_map[0] = 1; } if (mp_read_codes_table(mp, &gb) < 0) @@ -317,25 +336,12 @@ static int mp_decode_frame(AVCodecContext *avctx, ff_free_vlc(&mp->vlc); end: - if ((ret = av_frame_ref(data, &mp->frame)) < 0) + if ((ret = av_frame_ref(data, mp->frame)) < 0) return ret; *got_frame = 1; return buf_size; } -static av_cold int mp_decode_end(AVCodecContext *avctx) -{ - MotionPixelsContext *mp = avctx->priv_data; - - av_freep(&mp->changes_map); - av_freep(&mp->vpt); - av_freep(&mp->hpt); - av_freep(&mp->bswapbuf); - av_frame_unref(&mp->frame); - - return 0; -} - AVCodec ff_motionpixels_decoder = { .name = "motionpixels", .long_name = NULL_IF_CONFIG_SMALL("Motion Pixels video"), diff --git a/libavcodec/mpeg12dec.c b/libavcodec/mpeg12dec.c index 82b503d717..31a986199e 100644 --- a/libavcodec/mpeg12dec.c +++ b/libavcodec/mpeg12dec.c @@ -2070,7 +2070,6 @@ static int vcr2_init_sequence(AVCodecContext *avctx) if (s->codec_tag == AV_RL32("BW10")) { s->codec_id = s->avctx->codec_id = AV_CODEC_ID_MPEG1VIDEO; } else { - exchange_uv(s); // common init reset pblocks, so we swap them here s->swap_uv = 1; // in case of xvmc we need to swap uv for each MB s->codec_id = s->avctx->codec_id = AV_CODEC_ID_MPEG2VIDEO; } diff --git a/libavcodec/mpeg4videodec.c b/libavcodec/mpeg4videodec.c index dd97bd791b..6d2a0eddd4 100644 --- a/libavcodec/mpeg4videodec.c +++ b/libavcodec/mpeg4videodec.c @@ -186,13 +186,13 @@ static int mpeg4_decode_sprite_trajectory(MpegEncContext *s, GetBitContext *gb) int x=0, y=0; length= get_vlc2(gb, sprite_trajectory.table, SPRITE_TRAJ_VLC_BITS, 3); - if(length){ + if(length > 0){ x= get_xbits(gb, length); } if(!(s->divx_version==500 && s->divx_build==413)) skip_bits1(gb); /* marker bit */ length= get_vlc2(gb, sprite_trajectory.table, SPRITE_TRAJ_VLC_BITS, 3); - if(length){ + if(length > 0){ y=get_xbits(gb, length); } skip_bits1(gb); /* marker bit */ @@ -1766,6 +1766,11 @@ static int decode_vol_header(MpegEncContext *s, GetBitContext *gb){ s->quarter_sample= get_bits1(gb); else s->quarter_sample=0; + if (get_bits_left(gb) < 4) { + av_log(s->avctx, AV_LOG_ERROR, "VOL Header truncated\n"); + return AVERROR_INVALIDDATA; + } + if(!get_bits1(gb)){ int pos= get_bits_count(gb); int estimation_method= get_bits(gb, 2); diff --git a/libavcodec/mpegaudiodec.c b/libavcodec/mpegaudiodec.c index fc900d855b..4d06f891eb 100644 --- a/libavcodec/mpegaudiodec.c +++ b/libavcodec/mpegaudiodec.c @@ -1667,9 +1667,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) @@ -1724,7 +1726,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 32d6fa71f8..834cc0d551 100644 --- a/libavcodec/mpegvideo.c +++ b/libavcodec/mpegvideo.c @@ -537,6 +537,15 @@ fail: return ret; } +static void exchange_uv(MpegEncContext *s) +{ + int16_t (*tmp)[64]; + + tmp = s->pblocks[4]; + s->pblocks[4] = s->pblocks[5]; + s->pblocks[5] = tmp; +} + static int init_duplicate_context(MpegEncContext *s) { int y_size = s->b8_stride * (2 * s->mb_height + 1); @@ -567,6 +576,8 @@ static int init_duplicate_context(MpegEncContext *s) for (i = 0; i < 12; i++) { s->pblocks[i] = &s->block[i]; } + if (s->avctx->codec_tag == AV_RL32("VCR2")) + exchange_uv(s); if (s->out_format == FMT_H263) { /* ac values */ @@ -641,6 +652,8 @@ int ff_update_duplicate_context(MpegEncContext *dst, MpegEncContext *src) for (i = 0; i < 12; i++) { dst->pblocks[i] = &dst->block[i]; } + if (dst->avctx->codec_tag == AV_RL32("VCR2")) + exchange_uv(dst); if (!dst->edge_emu_buffer && (ret = ff_mpv_frame_size_alloc(dst, dst->linesize)) < 0) { av_log(dst->avctx, AV_LOG_ERROR, "failed to allocate context " @@ -1171,6 +1184,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]); @@ -1200,8 +1216,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; @@ -1217,7 +1233,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/mpegvideo.h b/libavcodec/mpegvideo.h index 2152af2e10..d21a71d1ac 100644 --- a/libavcodec/mpegvideo.h +++ b/libavcodec/mpegvideo.h @@ -96,6 +96,7 @@ struct MpegEncContext; */ typedef struct Picture{ struct AVFrame f; + uint8_t avframe_padding[1024]; // hack to allow linking to a avutil with larger AVFrame ThreadFrame tf; AVBufferRef *qscale_table_buf; @@ -745,6 +746,9 @@ typedef struct MpegEncContext { int context_reinit; ERContext er; + + /* temporary frames used by b_frame_strategy = 2 */ + AVFrame *tmp_frames[FF_MAX_B_FRAMES + 2]; } MpegEncContext; #define REBASE_PICTURE(pic, new_ctx, old_ctx) \ @@ -927,7 +931,7 @@ extern const uint8_t ff_h263_chroma_qscale_table[32]; extern const uint8_t ff_h263_loop_filter_strength[32]; /* rv10.c */ -void ff_rv10_encode_picture_header(MpegEncContext *s, int picture_number); +int ff_rv10_encode_picture_header(MpegEncContext *s, int picture_number); int ff_rv_decode_dc(MpegEncContext *s, int n); void ff_rv20_encode_picture_header(MpegEncContext *s, int picture_number); diff --git a/libavcodec/mpegvideo_enc.c b/libavcodec/mpegvideo_enc.c index 9b503865c6..417d8c8952 100644 --- a/libavcodec/mpegvideo_enc.c +++ b/libavcodec/mpegvideo_enc.c @@ -236,7 +236,7 @@ av_cold int ff_dct_encode_init(MpegEncContext *s) { av_cold int ff_MPV_encode_init(AVCodecContext *avctx) { MpegEncContext *s = avctx->priv_data; - int i; + int i, ret; int chroma_h_shift, chroma_v_shift; MPV_encode_defaults(s); @@ -351,18 +351,18 @@ av_cold int ff_MPV_encode_init(AVCodecContext *avctx) switch(avctx->codec_id) { case AV_CODEC_ID_MPEG1VIDEO: case AV_CODEC_ID_MPEG2VIDEO: - avctx->rc_buffer_size = FFMAX(avctx->rc_max_rate, 15000000) * 112L / 15000000 * 16384; + avctx->rc_buffer_size = FFMAX(avctx->rc_max_rate, 15000000) * 112LL / 15000000 * 16384; break; case AV_CODEC_ID_MPEG4: case AV_CODEC_ID_MSMPEG4V1: case AV_CODEC_ID_MSMPEG4V2: case AV_CODEC_ID_MSMPEG4V3: if (avctx->rc_max_rate >= 15000000) { - avctx->rc_buffer_size = 320 + (avctx->rc_max_rate - 15000000L) * (760-320) / (38400000 - 15000000); + avctx->rc_buffer_size = 320 + (avctx->rc_max_rate - 15000000LL) * (760-320) / (38400000 - 15000000); } else if(avctx->rc_max_rate >= 2000000) { - avctx->rc_buffer_size = 80 + (avctx->rc_max_rate - 2000000L) * (320- 80) / (15000000 - 2000000); + avctx->rc_buffer_size = 80 + (avctx->rc_max_rate - 2000000LL) * (320- 80) / (15000000 - 2000000); } else if(avctx->rc_max_rate >= 384000) { - avctx->rc_buffer_size = 40 + (avctx->rc_max_rate - 384000L) * ( 80- 40) / ( 2000000 - 384000); + avctx->rc_buffer_size = 40 + (avctx->rc_max_rate - 384000LL) * ( 80- 40) / ( 2000000 - 384000); } else avctx->rc_buffer_size = 40; avctx->rc_buffer_size *= 16384; @@ -876,12 +876,29 @@ av_cold int ff_MPV_encode_init(AVCodecContext *avctx) if (ff_rate_control_init(s) < 0) return -1; + if (avctx->b_frame_strategy == 2) { + for (i = 0; i < s->max_b_frames + 2; i++) { + s->tmp_frames[i] = av_frame_alloc(); + if (!s->tmp_frames[i]) + return AVERROR(ENOMEM); + + s->tmp_frames[i]->format = AV_PIX_FMT_YUV420P; + s->tmp_frames[i]->width = s->width >> avctx->brd_scale; + s->tmp_frames[i]->height = s->height >> avctx->brd_scale; + + ret = av_frame_get_buffer(s->tmp_frames[i], 32); + if (ret < 0) + return ret; + } + } + return 0; } av_cold int ff_MPV_encode_end(AVCodecContext *avctx) { MpegEncContext *s = avctx->priv_data; + int i; ff_rate_control_uninit(s); @@ -892,6 +909,9 @@ av_cold int ff_MPV_encode_end(AVCodecContext *avctx) av_freep(&avctx->extradata); + for (i = 0; i < FF_ARRAY_ELEMS(s->tmp_frames); i++) + av_frame_free(&s->tmp_frames[i]); + return 0; } @@ -1133,7 +1153,6 @@ static int estimate_best_b_count(MpegEncContext *s) { AVCodec *codec = avcodec_find_encoder(s->avctx->codec_id); AVCodecContext *c = avcodec_alloc_context3(NULL); - AVFrame input[FF_MAX_B_FRAMES + 2]; const int scale = s->avctx->brd_scale; int i, j, out_size, p_lambda, b_lambda, lambda2; int64_t best_rd = INT64_MAX; @@ -1168,19 +1187,9 @@ static int estimate_best_b_count(MpegEncContext *s) return -1; for (i = 0; i < s->max_b_frames + 2; i++) { - int ysize = c->width * c->height; - int csize = (c->width / 2) * (c->height / 2); Picture pre_input, *pre_input_ptr = i ? s->input_picture[i - 1] : s->next_picture_ptr; - avcodec_get_frame_defaults(&input[i]); - input[i].data[0] = av_malloc(ysize + 2 * csize); - input[i].data[1] = input[i].data[0] + ysize; - input[i].data[2] = input[i].data[1] + csize; - input[i].linesize[0] = c->width; - input[i].linesize[1] = - input[i].linesize[2] = c->width / 2; - if (pre_input_ptr && (!i || s->input_picture[i - 1])) { pre_input = *pre_input_ptr; @@ -1190,13 +1199,13 @@ static int estimate_best_b_count(MpegEncContext *s) pre_input.f.data[2] += INPLACE_OFFSET; } - s->dsp.shrink[scale](input[i].data[0], input[i].linesize[0], + s->dsp.shrink[scale](s->tmp_frames[i]->data[0], s->tmp_frames[i]->linesize[0], pre_input.f.data[0], pre_input.f.linesize[0], c->width, c->height); - s->dsp.shrink[scale](input[i].data[1], input[i].linesize[1], + s->dsp.shrink[scale](s->tmp_frames[i]->data[1], s->tmp_frames[i]->linesize[1], pre_input.f.data[1], pre_input.f.linesize[1], c->width >> 1, c->height >> 1); - s->dsp.shrink[scale](input[i].data[2], input[i].linesize[2], + s->dsp.shrink[scale](s->tmp_frames[i]->data[2], s->tmp_frames[i]->linesize[2], pre_input.f.data[2], pre_input.f.linesize[2], c->width >> 1, c->height >> 1); } @@ -1210,21 +1219,21 @@ static int estimate_best_b_count(MpegEncContext *s) c->error[0] = c->error[1] = c->error[2] = 0; - input[0].pict_type = AV_PICTURE_TYPE_I; - input[0].quality = 1 * FF_QP2LAMBDA; + s->tmp_frames[0]->pict_type = AV_PICTURE_TYPE_I; + s->tmp_frames[0]->quality = 1 * FF_QP2LAMBDA; - out_size = encode_frame(c, &input[0]); + out_size = encode_frame(c, s->tmp_frames[0]); //rd += (out_size * lambda2) >> FF_LAMBDA_SHIFT; for (i = 0; i < s->max_b_frames + 1; i++) { int is_p = i % (j + 1) == j || i == s->max_b_frames; - input[i + 1].pict_type = is_p ? + s->tmp_frames[i + 1]->pict_type = is_p ? AV_PICTURE_TYPE_P : AV_PICTURE_TYPE_B; - input[i + 1].quality = is_p ? p_lambda : b_lambda; + s->tmp_frames[i + 1]->quality = is_p ? p_lambda : b_lambda; - out_size = encode_frame(c, &input[i + 1]); + out_size = encode_frame(c, s->tmp_frames[i + 1]); rd += (out_size * lambda2) >> (FF_LAMBDA_SHIFT - 3); } @@ -1246,10 +1255,6 @@ static int estimate_best_b_count(MpegEncContext *s) avcodec_close(c); av_freep(&c); - for (i = 0; i < s->max_b_frames + 2; i++) { - av_freep(&input[i].data[0]); - } - return best_b_count; } @@ -3385,8 +3390,11 @@ static int encode_picture(MpegEncContext *s, int picture_number) ff_msmpeg4_encode_picture_header(s, picture_number); else if (CONFIG_MPEG4_ENCODER && s->h263_pred) ff_mpeg4_encode_picture_header(s, picture_number); - else if (CONFIG_RV10_ENCODER && s->codec_id == AV_CODEC_ID_RV10) - ff_rv10_encode_picture_header(s, picture_number); + else if (CONFIG_RV10_ENCODER && s->codec_id == AV_CODEC_ID_RV10) { + ret = ff_rv10_encode_picture_header(s, picture_number); + if (ret < 0) + return ret; + } else if (CONFIG_RV20_ENCODER && s->codec_id == AV_CODEC_ID_RV20) ff_rv20_encode_picture_header(s, picture_number); else if (CONFIG_FLV_ENCODER && s->codec_id == AV_CODEC_ID_FLV1) diff --git a/libavcodec/msrle.c b/libavcodec/msrle.c index 2b4ab1a6a5..9f0cac61e3 100644 --- a/libavcodec/msrle.c +++ b/libavcodec/msrle.c @@ -35,10 +35,11 @@ #include "avcodec.h" #include "internal.h" #include "msrledec.h" +#include "libavutil/imgutils.h" typedef struct MsrleContext { AVCodecContext *avctx; - AVFrame frame; + AVFrame *frame; GetByteContext gb; const unsigned char *buf; @@ -70,7 +71,9 @@ static av_cold int msrle_decode_init(AVCodecContext *avctx) return AVERROR_INVALIDDATA; } - avcodec_get_frame_defaults(&s->frame); + s->frame = av_frame_alloc(); + if (!s->frame) + return AVERROR(ENOMEM); if (avctx->extradata_size >= 4) for (i = 0; i < FFMIN(avctx->extradata_size, AVPALETTE_SIZE)/4; i++) @@ -92,27 +95,30 @@ static int msrle_decode_frame(AVCodecContext *avctx, s->buf = buf; s->size = buf_size; - if ((ret = ff_reget_buffer(avctx, &s->frame)) < 0) + if ((ret = ff_reget_buffer(avctx, s->frame)) < 0) return ret; if (avctx->bits_per_coded_sample > 1 && avctx->bits_per_coded_sample <= 8) { const uint8_t *pal = av_packet_get_side_data(avpkt, AV_PKT_DATA_PALETTE, NULL); if (pal) { - s->frame.palette_has_changed = 1; + s->frame->palette_has_changed = 1; memcpy(s->pal, pal, AVPALETTE_SIZE); } /* make the palette available */ - memcpy(s->frame.data[1], s->pal, AVPALETTE_SIZE); + memcpy(s->frame->data[1], s->pal, AVPALETTE_SIZE); } /* FIXME how to correctly detect RLE ??? */ if (avctx->height * istride == avpkt->size) { /* assume uncompressed */ - int linesize = (avctx->width * avctx->bits_per_coded_sample + 7) / 8; - uint8_t *ptr = s->frame.data[0]; + int linesize = av_image_get_linesize(avctx->pix_fmt, avctx->width, 0); + uint8_t *ptr = s->frame->data[0]; uint8_t *buf = avpkt->data + (avctx->height-1)*istride; int i, j; + if (linesize < 0) + return linesize; + for (i = 0; i < avctx->height; i++) { if (avctx->bits_per_coded_sample == 4) { for (j = 0; j < avctx->width - 1; j += 2) { @@ -125,14 +131,14 @@ static int msrle_decode_frame(AVCodecContext *avctx, memcpy(ptr, buf, linesize); } buf -= istride; - ptr += s->frame.linesize[0]; + ptr += s->frame->linesize[0]; } } else { bytestream2_init(&s->gb, buf, buf_size); - ff_msrle_decode(avctx, (AVPicture*)&s->frame, avctx->bits_per_coded_sample, &s->gb); + ff_msrle_decode(avctx, (AVPicture*)s->frame, avctx->bits_per_coded_sample, &s->gb); } - if ((ret = av_frame_ref(data, &s->frame)) < 0) + if ((ret = av_frame_ref(data, s->frame)) < 0) return ret; *got_frame = 1; @@ -146,7 +152,7 @@ static av_cold int msrle_decode_end(AVCodecContext *avctx) MsrleContext *s = avctx->priv_data; /* release the last frame */ - av_frame_unref(&s->frame); + av_frame_free(&s->frame); return 0; } diff --git a/libavcodec/msrledec.c b/libavcodec/msrledec.c index 4d3da5ba17..200221a0ee 100644 --- a/libavcodec/msrledec.c +++ b/libavcodec/msrledec.c @@ -36,17 +36,15 @@ static int msrle_decode_pal4(AVCodecContext *avctx, AVPicture *pic, unsigned char rle_code; unsigned char extra_byte, odd_pixel; unsigned char stream_byte; - unsigned int pixel_ptr = 0; - int row_dec = pic->linesize[0]; - int row_ptr = (avctx->height - 1) * row_dec; - int frame_size = row_dec * avctx->height; + int pixel_ptr = 0; + int line = avctx->height - 1; int i; - while (row_ptr >= 0) { + while (line >= 0 && pixel_ptr <= avctx->width) { if (bytestream2_get_bytes_left(gb) <= 0) { av_log(avctx, AV_LOG_ERROR, - "MS RLE: bytestream overrun, %d rows left\n", - row_ptr); + "MS RLE: bytestream overrun, %dx%d left\n", + avctx->width - pixel_ptr, line); return AVERROR_INVALIDDATA; } rle_code = stream_byte = bytestream2_get_byteu(gb); @@ -55,7 +53,7 @@ static int msrle_decode_pal4(AVCodecContext *avctx, AVPicture *pic, stream_byte = bytestream2_get_byte(gb); if (stream_byte == 0) { /* line is done, goto the next one */ - row_ptr -= row_dec; + line--; pixel_ptr = 0; } else if (stream_byte == 1) { /* decode is done */ @@ -65,13 +63,12 @@ static int msrle_decode_pal4(AVCodecContext *avctx, AVPicture *pic, stream_byte = bytestream2_get_byte(gb); pixel_ptr += stream_byte; stream_byte = bytestream2_get_byte(gb); - row_ptr -= stream_byte * row_dec; } else { // copy pixels from encoded stream odd_pixel = stream_byte & 1; rle_code = (stream_byte + 1) / 2; extra_byte = rle_code & 0x01; - if (row_ptr + pixel_ptr + stream_byte > frame_size || + if (pixel_ptr + 2*rle_code - odd_pixel > avctx->width || bytestream2_get_bytes_left(gb) < rle_code) { av_log(avctx, AV_LOG_ERROR, "MS RLE: frame/stream ptr just went out of bounds (copy)\n"); @@ -82,13 +79,13 @@ static int msrle_decode_pal4(AVCodecContext *avctx, AVPicture *pic, if (pixel_ptr >= avctx->width) break; stream_byte = bytestream2_get_byteu(gb); - pic->data[0][row_ptr + pixel_ptr] = stream_byte >> 4; + pic->data[0][line * pic->linesize[0] + pixel_ptr] = stream_byte >> 4; pixel_ptr++; if (i + 1 == rle_code && odd_pixel) break; if (pixel_ptr >= avctx->width) break; - pic->data[0][row_ptr + pixel_ptr] = stream_byte & 0x0F; + pic->data[0][line * pic->linesize[0] + pixel_ptr] = stream_byte & 0x0F; pixel_ptr++; } @@ -98,7 +95,7 @@ static int msrle_decode_pal4(AVCodecContext *avctx, AVPicture *pic, } } else { // decode a run of data - if (row_ptr + pixel_ptr + stream_byte > frame_size) { + if (pixel_ptr + rle_code > avctx->width + 1) { av_log(avctx, AV_LOG_ERROR, "MS RLE: frame ptr just went out of bounds (run)\n"); return AVERROR_INVALIDDATA; @@ -108,9 +105,9 @@ static int msrle_decode_pal4(AVCodecContext *avctx, AVPicture *pic, if (pixel_ptr >= avctx->width) break; if ((i & 1) == 0) - pic->data[0][row_ptr + pixel_ptr] = stream_byte >> 4; + pic->data[0][line * pic->linesize[0] + pixel_ptr] = stream_byte >> 4; else - pic->data[0][row_ptr + pixel_ptr] = stream_byte & 0x0F; + pic->data[0][line * pic->linesize[0] + pixel_ptr] = stream_byte & 0x0F; pixel_ptr++; } } diff --git a/libavcodec/mss1.c b/libavcodec/mss1.c index 46ea2b55d6..041898488c 100644 --- a/libavcodec/mss1.c +++ b/libavcodec/mss1.c @@ -30,7 +30,7 @@ typedef struct MSS1Context { MSS12Context ctx; - AVFrame pic; + AVFrame *pic; SliceContext sc; } MSS1Context; @@ -151,32 +151,32 @@ static int mss1_decode_frame(AVCodecContext *avctx, void *data, int *got_frame, init_get_bits(&gb, buf, buf_size * 8); arith_init(&acoder, &gb); - if ((ret = ff_reget_buffer(avctx, &ctx->pic)) < 0) + if ((ret = ff_reget_buffer(avctx, ctx->pic)) < 0) return ret; - c->pal_pic = ctx->pic.data[0] + ctx->pic.linesize[0] * (avctx->height - 1); - c->pal_stride = -ctx->pic.linesize[0]; + c->pal_pic = ctx->pic->data[0] + ctx->pic->linesize[0] * (avctx->height - 1); + c->pal_stride = -ctx->pic->linesize[0]; c->keyframe = !arith_get_bit(&acoder); if (c->keyframe) { c->corrupted = 0; ff_mss12_slicecontext_reset(&ctx->sc); pal_changed = decode_pal(c, &acoder); - ctx->pic.key_frame = 1; - ctx->pic.pict_type = AV_PICTURE_TYPE_I; + ctx->pic->key_frame = 1; + ctx->pic->pict_type = AV_PICTURE_TYPE_I; } else { if (c->corrupted) return AVERROR_INVALIDDATA; - ctx->pic.key_frame = 0; - ctx->pic.pict_type = AV_PICTURE_TYPE_P; + ctx->pic->key_frame = 0; + ctx->pic->pict_type = AV_PICTURE_TYPE_P; } c->corrupted = ff_mss12_decode_rect(&ctx->sc, &acoder, 0, 0, avctx->width, avctx->height); if (c->corrupted) return AVERROR_INVALIDDATA; - memcpy(ctx->pic.data[1], c->pal, AVPALETTE_SIZE); - ctx->pic.palette_has_changed = pal_changed; + memcpy(ctx->pic->data[1], c->pal, AVPALETTE_SIZE); + ctx->pic->palette_has_changed = pal_changed; - if ((ret = av_frame_ref(data, &ctx->pic)) < 0) + if ((ret = av_frame_ref(data, ctx->pic)) < 0) return ret; *got_frame = 1; @@ -192,7 +192,9 @@ static av_cold int mss1_decode_init(AVCodecContext *avctx) c->ctx.avctx = avctx; - avcodec_get_frame_defaults(&c->pic); + c->pic = av_frame_alloc(); + if (!c->pic) + return AVERROR(ENOMEM); ret = ff_mss12_decode_init(&c->ctx, 0, &c->sc, NULL); @@ -205,7 +207,7 @@ static av_cold int mss1_decode_end(AVCodecContext *avctx) { MSS1Context * const ctx = avctx->priv_data; - av_frame_unref(&ctx->pic); + av_frame_free(&ctx->pic); ff_mss12_decode_end(&ctx->ctx); return 0; diff --git a/libavcodec/mss2.c b/libavcodec/mss2.c index fcb50e3f09..6c616fa522 100644 --- a/libavcodec/mss2.c +++ b/libavcodec/mss2.c @@ -837,6 +837,7 @@ static av_cold int mss2_decode_init(AVCodecContext *avctx) avctx->pix_fmt = c->free_colours == 127 ? AV_PIX_FMT_RGB555 : AV_PIX_FMT_RGB24; + return 0; } diff --git a/libavcodec/mss3.c b/libavcodec/mss3.c index a3aec80c2d..c6bb838045 100644 --- a/libavcodec/mss3.c +++ b/libavcodec/mss3.c @@ -803,15 +803,24 @@ static int mss3_decode_frame(AVCodecContext *avctx, void *data, int *got_frame, return buf_size; } +static av_cold int mss3_decode_end(AVCodecContext *avctx) +{ + MSS3Context * const c = avctx->priv_data; + int i; + + av_frame_free(&c->pic); + for (i = 0; i < 3; i++) + av_freep(&c->dct_coder[i].prev_dc); + + return 0; +} + static av_cold int mss3_decode_init(AVCodecContext *avctx) { MSS3Context * const c = avctx->priv_data; int i; c->avctx = avctx; - c->pic = av_frame_alloc(); - if (!c->pic) - return AVERROR(ENOMEM); if ((avctx->width & 0xF) || (avctx->height & 0xF)) { av_log(avctx, AV_LOG_ERROR, @@ -838,6 +847,12 @@ static av_cold int mss3_decode_init(AVCodecContext *avctx) } } + c->pic = av_frame_alloc(); + if (!c->pic) { + mss3_decode_end(avctx); + return AVERROR(ENOMEM); + } + avctx->pix_fmt = AV_PIX_FMT_YUV420P; init_coders(c); @@ -845,18 +860,6 @@ static av_cold int mss3_decode_init(AVCodecContext *avctx) return 0; } -static av_cold int mss3_decode_end(AVCodecContext *avctx) -{ - MSS3Context * const c = avctx->priv_data; - int i; - - av_frame_free(&c->pic); - for (i = 0; i < 3; i++) - av_freep(&c->dct_coder[i].prev_dc); - - return 0; -} - AVCodec ff_msa1_decoder = { .name = "msa1", .long_name = NULL_IF_CONFIG_SMALL("MS ATC Screen"), diff --git a/libavcodec/mss34dsp.c b/libavcodec/mss34dsp.c index e4d4299805..0397add17d 100644 --- a/libavcodec/mss34dsp.c +++ b/libavcodec/mss34dsp.c @@ -84,8 +84,8 @@ void ff_mss34_gen_quant_mat(uint16_t *qmat, int quality, int luma) blk[6 * step] = (-(t3 + t7) + t8 + tA) >> shift; \ blk[7 * step] = (-(t1 + t6) + t9 + tB) >> shift; \ -#define SOP_ROW(a) ((a) << 16) + 0x2000 -#define SOP_COL(a) ((a + 32) << 16) +#define SOP_ROW(a) (((a) << 16) + 0x2000) +#define SOP_COL(a) (((a) + 32) << 16) void ff_mss34_dct_put(uint8_t *dst, int stride, int *block) { diff --git a/libavcodec/mss4.c b/libavcodec/mss4.c index fd1f316bbf..6dadf07313 100644 --- a/libavcodec/mss4.c +++ b/libavcodec/mss4.c @@ -364,7 +364,7 @@ static int get_value_cached(GetBitContext *gb, int vec_pos, uint8_t *vec, return prev[component]; } -#define MKVAL(vals) (vals[0] | (vals[1] << 3) | (vals[2] << 6)) +#define MKVAL(vals) ((vals)[0] | ((vals)[1] << 3) | ((vals)[2] << 6)) /* Image mode - the hardest to comprehend MSS4 coding mode. * @@ -626,14 +626,23 @@ static int mss4_decode_frame(AVCodecContext *avctx, void *data, int *got_frame, return buf_size; } -static av_cold int mss4_decode_init(AVCodecContext *avctx) +static av_cold int mss4_decode_end(AVCodecContext *avctx) { MSS4Context * const c = avctx->priv_data; int i; - c->pic = av_frame_alloc(); - if (!c->pic) - return AVERROR(ENOMEM); + av_frame_free(&c->pic); + for (i = 0; i < 3; i++) + av_freep(&c->prev_dc[i]); + mss4_free_vlcs(c); + + return 0; +} + +static av_cold int mss4_decode_init(AVCodecContext *avctx) +{ + MSS4Context * const c = avctx->priv_data; + int i; if (mss4_init_vlcs(c)) { av_log(avctx, AV_LOG_ERROR, "Cannot initialise VLCs\n"); @@ -650,25 +659,17 @@ static av_cold int mss4_decode_init(AVCodecContext *avctx) } } + c->pic = av_frame_alloc(); + if (!c->pic) { + mss4_decode_end(avctx); + return AVERROR(ENOMEM); + } + avctx->pix_fmt = AV_PIX_FMT_YUV444P; return 0; } -static av_cold int mss4_decode_end(AVCodecContext *avctx) -{ - MSS4Context * const c = avctx->priv_data; - int i; - - av_frame_free(&c->pic); - - for (i = 0; i < 3; i++) - av_freep(&c->prev_dc[i]); - mss4_free_vlcs(c); - - return 0; -} - AVCodec ff_mts2_decoder = { .name = "mts2", .long_name = NULL_IF_CONFIG_SMALL("MS Expression Encoder Screen"), diff --git a/libavcodec/msvideo1.c b/libavcodec/msvideo1.c index 83c50ac46d..970c67ce12 100644 --- a/libavcodec/msvideo1.c +++ b/libavcodec/msvideo1.c @@ -47,7 +47,7 @@ typedef struct Msvideo1Context { AVCodecContext *avctx; - AVFrame frame; + AVFrame *frame; const unsigned char *buf; int size; @@ -72,7 +72,9 @@ static av_cold int msvideo1_decode_init(AVCodecContext *avctx) avctx->pix_fmt = AV_PIX_FMT_RGB555; } - avcodec_get_frame_defaults(&s->frame); + s->frame = av_frame_alloc(); + if (!s->frame) + return AVERROR(ENOMEM); return 0; } @@ -93,8 +95,8 @@ static void msvideo1_decode_8bit(Msvideo1Context *s) unsigned short flags; int skip_blocks; unsigned char colors[8]; - unsigned char *pixels = s->frame.data[0]; - int stride = s->frame.linesize[0]; + unsigned char *pixels = s->frame->data[0]; + int stride = s->frame->linesize[0]; stream_ptr = 0; skip_blocks = 0; @@ -174,7 +176,7 @@ static void msvideo1_decode_8bit(Msvideo1Context *s) /* make the palette available on the way out */ if (s->avctx->pix_fmt == AV_PIX_FMT_PAL8) - memcpy(s->frame.data[1], s->pal, AVPALETTE_SIZE); + memcpy(s->frame->data[1], s->pal, AVPALETTE_SIZE); } static void msvideo1_decode_16bit(Msvideo1Context *s) @@ -193,8 +195,8 @@ static void msvideo1_decode_16bit(Msvideo1Context *s) unsigned short flags; int skip_blocks; unsigned short colors[8]; - unsigned short *pixels = (unsigned short *)s->frame.data[0]; - int stride = s->frame.linesize[0] / 2; + unsigned short *pixels = (unsigned short *)s->frame->data[0]; + int stride = s->frame->linesize[0] / 2; stream_ptr = 0; skip_blocks = 0; @@ -298,7 +300,7 @@ static int msvideo1_decode_frame(AVCodecContext *avctx, s->buf = buf; s->size = buf_size; - if ((ret = ff_reget_buffer(avctx, &s->frame)) < 0) + if ((ret = ff_reget_buffer(avctx, s->frame)) < 0) return ret; if (s->mode_8bit) { @@ -306,7 +308,7 @@ static int msvideo1_decode_frame(AVCodecContext *avctx, if (pal) { memcpy(s->pal, pal, AVPALETTE_SIZE); - s->frame.palette_has_changed = 1; + s->frame->palette_has_changed = 1; } } @@ -315,7 +317,7 @@ static int msvideo1_decode_frame(AVCodecContext *avctx, else msvideo1_decode_16bit(s); - if ((ret = av_frame_ref(data, &s->frame)) < 0) + if ((ret = av_frame_ref(data, s->frame)) < 0) return ret; *got_frame = 1; @@ -328,7 +330,7 @@ static av_cold int msvideo1_decode_end(AVCodecContext *avctx) { Msvideo1Context *s = avctx->priv_data; - av_frame_unref(&s->frame); + av_frame_free(&s->frame); return 0; } diff --git a/libavcodec/msvideo1enc.c b/libavcodec/msvideo1enc.c index 1da302a019..896e1e1f0c 100644 --- a/libavcodec/msvideo1enc.c +++ b/libavcodec/msvideo1enc.c @@ -35,7 +35,6 @@ */ typedef struct Msvideo1EncContext { AVCodecContext *avctx; - AVFrame pic; AVLFG rnd; uint8_t *prev; @@ -58,7 +57,7 @@ enum MSV1Mode{ }; #define SKIP_PREFIX 0x8400 -#define SKIPS_MAX 0x0FFF +#define SKIPS_MAX 0x03FF #define MKRGB555(in, off) ((in[off] << 10) | (in[off + 1] << 5) | (in[off + 2])) static const int remap[16] = { 0, 1, 4, 5, 2, 3, 6, 7, 8, 9, 12, 13, 10, 11, 14, 15 }; @@ -67,7 +66,7 @@ static int encode_frame(AVCodecContext *avctx, AVPacket *pkt, const AVFrame *pict, int *got_packet) { Msvideo1EncContext * const c = avctx->priv_data; - AVFrame * const p = &c->pic; + const AVFrame *p = pict; uint16_t *src; uint8_t *prevptr; uint8_t *dst, *buf; @@ -75,12 +74,12 @@ static int encode_frame(AVCodecContext *avctx, AVPacket *pkt, int no_skips = 1; int i, j, k, x, y, ret; int skips = 0; + int quality = 24; if ((ret = ff_alloc_packet2(avctx, pkt, avctx->width*avctx->height*9 + FF_MIN_BUFFER_SIZE)) < 0) return ret; dst= buf= pkt->data; - *p = *pict; if(!c->prev) c->prev = av_malloc(avctx->width * 3 * (avctx->height + 3)); prevptr = c->prev + avctx->width * 3 * (FFALIGN(avctx->height, 4) - 1); @@ -88,7 +87,6 @@ static int encode_frame(AVCodecContext *avctx, AVPacket *pkt, if(c->keyint >= avctx->keyint_min) keyframe = 1; - p->quality = 24; for(y = 0; y < avctx->height; y += 4){ for(x = 0; x < avctx->width; x += 4){ @@ -114,7 +112,7 @@ static int encode_frame(AVCodecContext *avctx, AVPacket *pkt, bestscore += t*t; } } - bestscore /= p->quality; + bestscore /= quality; } // try to find optimal value to fill whole 4x4 block score = 0; @@ -130,7 +128,7 @@ static int encode_frame(AVCodecContext *avctx, AVPacket *pkt, } } } - score /= p->quality; + score /= quality; score += 2; if(score < bestscore){ bestscore = score; @@ -155,7 +153,7 @@ static int encode_frame(AVCodecContext *avctx, AVPacket *pkt, } } } - score /= p->quality; + score /= quality; score += 6; if(score < bestscore){ bestscore = score; @@ -182,7 +180,7 @@ static int encode_frame(AVCodecContext *avctx, AVPacket *pkt, } } } - score /= p->quality; + score /= quality; score += 18; if(score < bestscore){ bestscore = score; @@ -248,8 +246,6 @@ static int encode_frame(AVCodecContext *avctx, AVPacket *pkt, c->keyint = 0; else c->keyint++; - p->pict_type= keyframe ? AV_PICTURE_TYPE_I : AV_PICTURE_TYPE_P; - p->key_frame= keyframe; if (keyframe) pkt->flags |= AV_PKT_FLAG_KEY; pkt->size = dst - buf; *got_packet = 1; @@ -274,8 +270,6 @@ static av_cold int encode_init(AVCodecContext *avctx) return -1; } - avcodec_get_frame_defaults(&c->pic); - avctx->coded_frame = (AVFrame*)&c->pic; avctx->bits_per_coded_sample = 16; c->keyint = avctx->keyint_min; diff --git a/libavcodec/mxpegdec.c b/libavcodec/mxpegdec.c index 0069ca5885..155d348905 100644 --- a/libavcodec/mxpegdec.c +++ b/libavcodec/mxpegdec.c @@ -31,7 +31,7 @@ typedef struct MXpegDecodeContext { MJpegDecodeContext jpg; - AVFrame picture[2]; /* pictures array */ + AVFrame *picture[2]; /* pictures array */ int picture_index; /* index of current picture */ int got_sof_data; /* true if SOF data successfully parsed */ int got_mxm_bitmask; /* true if MXM bitmask available */ @@ -42,11 +42,36 @@ typedef struct MXpegDecodeContext { unsigned mb_width, mb_height; /* size of picture in MB's from MXM header */ } MXpegDecodeContext; +static av_cold int mxpeg_decode_end(AVCodecContext *avctx) +{ + MXpegDecodeContext *s = avctx->priv_data; + MJpegDecodeContext *jpg = &s->jpg; + int i; + + jpg->picture_ptr = NULL; + ff_mjpeg_decode_end(avctx); + + for (i = 0; i < 2; ++i) + av_frame_free(&s->picture[i]); + + av_freep(&s->mxm_bitmask); + av_freep(&s->completion_bitmask); + + return 0; +} + static av_cold int mxpeg_decode_init(AVCodecContext *avctx) { MXpegDecodeContext *s = avctx->priv_data; - s->jpg.picture_ptr = &s->picture[0]; + s->picture[0] = av_frame_alloc(); + s->picture[1] = av_frame_alloc(); + if (!s->picture[0] || !s->picture[1]) { + mxpeg_decode_end(avctx); + return AVERROR(ENOMEM); + } + + s->jpg.picture_ptr = s->picture[0]; return ff_mjpeg_decode_init(avctx); } @@ -260,7 +285,7 @@ static int mxpeg_decode_frame(AVCodecContext *avctx, } if (s->got_mxm_bitmask) { - AVFrame *reference_ptr = &s->picture[s->picture_index ^ 1]; + AVFrame *reference_ptr = s->picture[s->picture_index ^ 1]; if (mxpeg_check_dimensions(s, jpg, reference_ptr) < 0) break; @@ -270,11 +295,11 @@ static int mxpeg_decode_frame(AVCodecContext *avctx, AV_GET_BUFFER_FLAG_REF)) < 0) return ret; - ret = ff_mjpeg_decode_sos(jpg, s->mxm_bitmask, reference_ptr); + ret = ff_mjpeg_decode_sos(jpg, s->mxm_bitmask, s->bitmask_size, reference_ptr); if (ret < 0 && (avctx->err_recognition & AV_EF_EXPLODE)) return ret; } else { - ret = ff_mjpeg_decode_sos(jpg, NULL, NULL); + ret = ff_mjpeg_decode_sos(jpg, NULL, 0, NULL); if (ret < 0 && (avctx->err_recognition & AV_EF_EXPLODE)) return ret; } @@ -295,7 +320,7 @@ the_end: *got_frame = 1; s->picture_index ^= 1; - jpg->picture_ptr = &s->picture[s->picture_index]; + jpg->picture_ptr = s->picture[s->picture_index]; if (!s->has_complete_frame) { if (!s->got_mxm_bitmask) @@ -308,24 +333,6 @@ the_end: return buf_ptr - buf; } -static av_cold int mxpeg_decode_end(AVCodecContext *avctx) -{ - MXpegDecodeContext *s = avctx->priv_data; - MJpegDecodeContext *jpg = &s->jpg; - int i; - - jpg->picture_ptr = NULL; - ff_mjpeg_decode_end(avctx); - - for (i = 0; i < 2; ++i) - av_frame_unref(&s->picture[i]); - - av_freep(&s->mxm_bitmask); - av_freep(&s->completion_bitmask); - - return 0; -} - AVCodec ff_mxpeg_decoder = { .name = "mxpeg", .long_name = NULL_IF_CONFIG_SMALL("Mobotix MxPEG video"), diff --git a/libavcodec/nellymoserenc.c b/libavcodec/nellymoserenc.c index f9d1389a78..8f15757888 100644 --- a/libavcodec/nellymoserenc.c +++ b/libavcodec/nellymoserenc.c @@ -301,7 +301,7 @@ static void encode_block(NellyMoserEncodeContext *s, unsigned char *output, int apply_mdct(s); - init_put_bits(&pb, output, output_size * 8); + init_put_bits(&pb, output, output_size); i = 0; for (band = 0; band < NELLY_BANDS; band++) { diff --git a/libavcodec/nuv.c b/libavcodec/nuv.c index bfbf802777..d4d9318bf7 100644 --- a/libavcodec/nuv.c +++ b/libavcodec/nuv.c @@ -32,7 +32,7 @@ #include "rtjpeg.h" typedef struct { - AVFrame pic; + AVFrame *pic; int codec_frameheader; int quality; int width, height; @@ -140,7 +140,7 @@ static int codec_reinit(AVCodecContext *avctx, int width, int height, } ff_rtjpeg_decode_init(&c->rtj, &c->dsp, c->width, c->height, c->lq, c->cq); - av_frame_unref(&c->pic); + av_frame_unref(c->pic); return 1; } else if (quality != c->quality) ff_rtjpeg_decode_init(&c->rtj, &c->dsp, c->width, c->height, @@ -248,20 +248,20 @@ retry: } if (size_change || keyframe) { - av_frame_unref(&c->pic); + av_frame_unref(c->pic); init_frame = 1; } - if ((result = ff_reget_buffer(avctx, &c->pic)) < 0) + if ((result = ff_reget_buffer(avctx, c->pic)) < 0) return result; if (init_frame) { - memset(c->pic.data[0], 0, avctx->height * c->pic.linesize[0]); - memset(c->pic.data[1], 0x80, avctx->height * c->pic.linesize[1] / 2); - memset(c->pic.data[2], 0x80, avctx->height * c->pic.linesize[2] / 2); + memset(c->pic->data[0], 0, avctx->height * c->pic->linesize[0]); + memset(c->pic->data[1], 0x80, avctx->height * c->pic->linesize[1] / 2); + memset(c->pic->data[2], 0x80, avctx->height * c->pic->linesize[2] / 2); } - c->pic.pict_type = keyframe ? AV_PICTURE_TYPE_I : AV_PICTURE_TYPE_P; - c->pic.key_frame = keyframe; + c->pic->pict_type = keyframe ? AV_PICTURE_TYPE_I : AV_PICTURE_TYPE_P; + c->pic->key_frame = keyframe; // decompress/copy/whatever data switch (comptype) { case NUV_LZO: @@ -272,19 +272,19 @@ retry: height = buf_size / c->width / 3 * 2; } if(height > 0) - copy_frame(&c->pic, buf, c->width, height); + copy_frame(c->pic, buf, c->width, height); break; } case NUV_RTJPEG_IN_LZO: case NUV_RTJPEG: - ret = ff_rtjpeg_decode_frame_yuv420(&c->rtj, &c->pic, buf, buf_size); + ret = ff_rtjpeg_decode_frame_yuv420(&c->rtj, c->pic, buf, buf_size); if (ret < 0) return ret; break; case NUV_BLACK: - memset(c->pic.data[0], 0, c->width * c->height); - memset(c->pic.data[1], 128, c->width * c->height / 4); - memset(c->pic.data[2], 128, c->width * c->height / 4); + memset(c->pic->data[0], 0, c->width * c->height); + memset(c->pic->data[1], 128, c->width * c->height / 4); + memset(c->pic->data[2], 128, c->width * c->height / 4); break; case NUV_COPY_LAST: /* nothing more to do here */ @@ -294,7 +294,7 @@ retry: return AVERROR_INVALIDDATA; } - if ((result = av_frame_ref(picture, &c->pic)) < 0) + if ((result = av_frame_ref(picture, c->pic)) < 0) return result; *got_frame = 1; @@ -306,8 +306,11 @@ static av_cold int decode_init(AVCodecContext *avctx) NuvContext *c = avctx->priv_data; int ret; + c->pic = av_frame_alloc(); + if (!c->pic) + return AVERROR(ENOMEM); + avctx->pix_fmt = AV_PIX_FMT_YUV420P; - c->pic.data[0] = NULL; c->decomp_buf = NULL; c->quality = -1; c->width = 0; @@ -331,7 +334,7 @@ static av_cold int decode_end(AVCodecContext *avctx) NuvContext *c = avctx->priv_data; av_freep(&c->decomp_buf); - av_frame_unref(&c->pic); + av_frame_free(&c->pic); return 0; } diff --git a/libavcodec/options_table.h b/libavcodec/options_table.h index c1a4ceb3a9..933a949c61 100644 --- a/libavcodec/options_table.h +++ b/libavcodec/options_table.h @@ -89,11 +89,10 @@ static const AVOption avcodec_options[] = { {"hex", "hex motion estimation", 0, AV_OPT_TYPE_CONST, {.i64 = ME_HEX }, INT_MIN, INT_MAX, V|E, "me_method" }, {"umh", "umh motion estimation", 0, AV_OPT_TYPE_CONST, {.i64 = ME_UMH }, INT_MIN, INT_MAX, V|E, "me_method" }, {"iter", "iter motion estimation", 0, AV_OPT_TYPE_CONST, {.i64 = ME_ITER }, INT_MIN, INT_MAX, V|E, "me_method" }, -{"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/pamenc.c b/libavcodec/pamenc.c index 2421464204..64ab2b5faa 100644 --- a/libavcodec/pamenc.c +++ b/libavcodec/pamenc.c @@ -21,13 +21,11 @@ #include "avcodec.h" #include "internal.h" -#include "pnm.h" - static int pam_encode_frame(AVCodecContext *avctx, AVPacket *pkt, const AVFrame *p, int *got_packet) { - PNMContext *s = avctx->priv_data; + uint8_t *bytestream_start, *bytestream, *bytestream_end; int i, h, w, n, linesize, depth, maxval, ret; const char *tuple_type; uint8_t *ptr; @@ -90,14 +88,14 @@ static int pam_encode_frame(AVCodecContext *avctx, AVPacket *pkt, if ((ret = ff_alloc_packet2(avctx, pkt, n*h + 200)) < 0) return ret; - s->bytestream_start = - s->bytestream = pkt->data; - s->bytestream_end = pkt->data + pkt->size; + bytestream_start = + bytestream = pkt->data; + bytestream_end = pkt->data + pkt->size; - snprintf(s->bytestream, s->bytestream_end - s->bytestream, + snprintf(bytestream, bytestream_end - bytestream, "P7\nWIDTH %d\nHEIGHT %d\nDEPTH %d\nMAXVAL %d\nTUPLTYPE %s\nENDHDR\n", w, h, depth, maxval, tuple_type); - s->bytestream += strlen(s->bytestream); + bytestream += strlen(bytestream); ptr = p->data[0]; linesize = p->linesize[0]; @@ -106,30 +104,48 @@ static int pam_encode_frame(AVCodecContext *avctx, AVPacket *pkt, int j; for (i = 0; i < h; i++) { for (j = 0; j < w; j++) - *s->bytestream++ = ptr[j >> 3] >> (7 - j & 7) & 1; + *bytestream++ = ptr[j >> 3] >> (7 - j & 7) & 1; ptr += linesize; } } else { for (i = 0; i < h; i++) { - memcpy(s->bytestream, ptr, n); - s->bytestream += n; - ptr += linesize; + memcpy(bytestream, ptr, n); + bytestream += n; + ptr += linesize; } } - pkt->size = s->bytestream - s->bytestream_start; + pkt->size = bytestream - bytestream_start; pkt->flags |= AV_PKT_FLAG_KEY; *got_packet = 1; return 0; } +static av_cold int pam_encode_init(AVCodecContext *avctx) +{ + avctx->coded_frame = av_frame_alloc(); + if (!avctx->coded_frame) + return AVERROR(ENOMEM); + + avctx->coded_frame->pict_type = AV_PICTURE_TYPE_I; + avctx->coded_frame->key_frame = 1; + + return 0; +} + +static av_cold int pam_encode_close(AVCodecContext *avctx) +{ + av_frame_free(&avctx->coded_frame); + return 0; +} AVCodec ff_pam_encoder = { .name = "pam", .long_name = NULL_IF_CONFIG_SMALL("PAM (Portable AnyMap) image"), .type = AVMEDIA_TYPE_VIDEO, .id = AV_CODEC_ID_PAM, - .priv_data_size = sizeof(PNMContext), + .init = pam_encode_init, + .close = pam_encode_close, .encode2 = pam_encode_frame, .pix_fmts = (const enum AVPixelFormat[]){ AV_PIX_FMT_RGB24, AV_PIX_FMT_RGBA, AV_PIX_FMT_RGB48BE, AV_PIX_FMT_RGBA64BE, AV_PIX_FMT_GRAY8, AV_PIX_FMT_GRAY8A, AV_PIX_FMT_GRAY16BE, AV_PIX_FMT_MONOBLACK, AV_PIX_FMT_NONE diff --git a/libavcodec/pcm-dvd.c b/libavcodec/pcm-dvd.c index 9696b09115..243b6aa0bb 100644 --- a/libavcodec/pcm-dvd.c +++ b/libavcodec/pcm-dvd.c @@ -173,6 +173,17 @@ static void *pcm_dvd_decode_samples(AVCodecContext *avctx, const uint8_t *src, #endif return dst16; case 20: + if (avctx->channels == 1) { + do { + for (i = 2; i; i--) { + dst32[0] = bytestream2_get_be16u(&gb) << 16; + dst32[1] = bytestream2_get_be16u(&gb) << 16; + t = bytestream2_get_byteu(&gb); + *dst32++ += (t & 0xf0) << 8; + *dst32++ += (t & 0x0f) << 12; + } + } while (--blocks); + } else { do { for (i = s->groups_per_block; i; i--) { dst32[0] = bytestream2_get_be16u(&gb) << 16; @@ -180,15 +191,26 @@ static void *pcm_dvd_decode_samples(AVCodecContext *avctx, const uint8_t *src, dst32[2] = bytestream2_get_be16u(&gb) << 16; dst32[3] = bytestream2_get_be16u(&gb) << 16; t = bytestream2_get_byteu(&gb); - *dst32 += (t & 0xf0) << 8; - *dst32 += (t & 0x0f) << 12; + *dst32++ += (t & 0xf0) << 8; + *dst32++ += (t & 0x0f) << 12; t = bytestream2_get_byteu(&gb); - *dst32 += (t & 0xf0) << 8; - *dst32 += (t & 0x0f) << 12; + *dst32++ += (t & 0xf0) << 8; + *dst32++ += (t & 0x0f) << 12; } } while (--blocks); + } return dst32; case 24: + if (avctx->channels == 1) { + do { + for (i = 2; i; i--) { + dst32[0] = bytestream2_get_be16u(&gb) << 16; + dst32[1] = bytestream2_get_be16u(&gb) << 16; + *dst32++ += bytestream2_get_byteu(&gb) << 8; + *dst32++ += bytestream2_get_byteu(&gb) << 8; + } + } while (--blocks); + } else { do { for (i = s->groups_per_block; i; i--) { dst32[0] = bytestream2_get_be16u(&gb) << 16; @@ -201,6 +223,7 @@ static void *pcm_dvd_decode_samples(AVCodecContext *avctx, const uint8_t *src, *dst32++ += bytestream2_get_byteu(&gb) << 8; } } while (--blocks); + } return dst32; default: return NULL; diff --git a/libavcodec/pcxenc.c b/libavcodec/pcxenc.c index fa45888466..f48063b9b2 100644 --- a/libavcodec/pcxenc.c +++ b/libavcodec/pcxenc.c @@ -33,6 +33,24 @@ static const uint32_t monoblack_pal[16] = { 0x000000, 0xFFFFFF }; +static av_cold int pcx_encode_init(AVCodecContext *avctx) +{ + avctx->coded_frame = av_frame_alloc(); + if (!avctx->coded_frame) + return AVERROR(ENOMEM); + + avctx->coded_frame->pict_type = AV_PICTURE_TYPE_I; + avctx->coded_frame->key_frame = 1; + + return 0; +} + +static av_cold int pcx_encode_close(AVCodecContext *avctx) +{ + av_frame_free(&avctx->coded_frame); + return 0; +} + /** * PCX run-length encoder * @param dst output buffer @@ -86,7 +104,6 @@ static int pcx_rle_encode( uint8_t *dst, int dst_size, static int pcx_encode_frame(AVCodecContext *avctx, AVPacket *pkt, const AVFrame *frame, int *got_packet) { - AVFrame *const pict = (AVFrame *) frame; const uint8_t *buf_end; uint8_t *buf; @@ -95,9 +112,6 @@ static int pcx_encode_frame(AVCodecContext *avctx, AVPacket *pkt, uint32_t palette256[256]; const uint8_t *src; - pict->pict_type = AV_PICTURE_TYPE_I; - pict->key_frame = 1; - if (avctx->width > 65535 || avctx->height > 65535) { av_log(avctx, AV_LOG_ERROR, "image dimensions do not fit in 16 bits\n"); return -1; @@ -121,7 +135,7 @@ static int pcx_encode_frame(AVCodecContext *avctx, AVPacket *pkt, case AV_PIX_FMT_PAL8: bpp = 8; nplanes = 1; - pal = (uint32_t *)pict->data[1]; + pal = (uint32_t *)frame->data[1]; break; case AV_PIX_FMT_MONOBLACK: bpp = 1; @@ -166,7 +180,7 @@ static int pcx_encode_frame(AVCodecContext *avctx, AVPacket *pkt, while (buf - pkt->data < 128) *buf++= 0; - src = pict->data[0]; + src = frame->data[0]; for (y = 0; y < avctx->height; y++) { if ((written = pcx_rle_encode(buf, buf_end - buf, @@ -175,7 +189,7 @@ static int pcx_encode_frame(AVCodecContext *avctx, AVPacket *pkt, return -1; } buf += written; - src += pict->linesize[0]; + src += frame->linesize[0]; } if (nplanes == 1 && bpp == 8) { @@ -201,6 +215,8 @@ AVCodec ff_pcx_encoder = { .long_name = NULL_IF_CONFIG_SMALL("PC Paintbrush PCX image"), .type = AVMEDIA_TYPE_VIDEO, .id = AV_CODEC_ID_PCX, + .init = pcx_encode_init, + .close = pcx_encode_close, .encode2 = pcx_encode_frame, .pix_fmts = (const enum AVPixelFormat[]){ AV_PIX_FMT_RGB24, diff --git a/libavcodec/pngdec.c b/libavcodec/pngdec.c index 3d21e50288..a279f40ed8 100644 --- a/libavcodec/pngdec.c +++ b/libavcodec/pngdec.c @@ -565,6 +565,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)) { @@ -633,7 +639,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) { @@ -841,10 +847,11 @@ static int decode_frame(AVCodecContext *avctx, 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; diff --git a/libavcodec/pngenc.c b/libavcodec/pngenc.c index 58acc3c409..bf61be1609 100644 --- a/libavcodec/pngenc.c +++ b/libavcodec/pngenc.c @@ -38,7 +38,6 @@ typedef struct PNGEncContext { uint8_t *bytestream; uint8_t *bytestream_start; uint8_t *bytestream_end; - AVFrame picture; int filter_type; @@ -218,7 +217,7 @@ static int encode_frame(AVCodecContext *avctx, AVPacket *pkt, const AVFrame *pict, int *got_packet) { PNGEncContext *s = avctx->priv_data; - AVFrame * const p= &s->picture; + const AVFrame * const p = pict; int bit_depth, color_type, y, len, row_size, ret, is_progressive; int bits_per_pixel, pass_row_size, enc_row_size; int64_t max_packet_size; @@ -228,10 +227,6 @@ static int encode_frame(AVCodecContext *avctx, AVPacket *pkt, uint8_t *progressive_buf = NULL; uint8_t *top_buf = NULL; - *p = *pict; - p->pict_type= AV_PICTURE_TYPE_I; - p->key_frame= 1; - is_progressive = !!(avctx->flags & CODEC_FLAG_INTERLACED_DCT); switch(avctx->pix_fmt) { case AV_PIX_FMT_RGBA64BE: @@ -454,8 +449,13 @@ static av_cold int png_enc_init(AVCodecContext *avctx){ avctx->bits_per_coded_sample = 8; } - avcodec_get_frame_defaults(&s->picture); - avctx->coded_frame= &s->picture; + avctx->coded_frame = av_frame_alloc(); + if (!avctx->coded_frame) + return AVERROR(ENOMEM); + + avctx->coded_frame->pict_type = AV_PICTURE_TYPE_I; + avctx->coded_frame->key_frame = 1; + ff_dsputil_init(&s->dsp, avctx); s->filter_type = av_clip(avctx->prediction_method, PNG_FILTER_VALUE_NONE, PNG_FILTER_VALUE_MIXED); @@ -472,6 +472,12 @@ static av_cold int png_enc_init(AVCodecContext *avctx){ return 0; } +static av_cold int png_enc_close(AVCodecContext *avctx) +{ + av_frame_free(&avctx->coded_frame); + return 0; +} + #define OFFSET(x) offsetof(PNGEncContext, x) #define VE AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_ENCODING_PARAM static const AVOption options[] = { @@ -494,6 +500,7 @@ AVCodec ff_png_encoder = { .id = AV_CODEC_ID_PNG, .priv_data_size = sizeof(PNGEncContext), .init = png_enc_init, + .close = png_enc_close, .encode2 = encode_frame, .capabilities = CODEC_CAP_FRAME_THREADS | CODEC_CAP_INTRA_ONLY, .pix_fmts = (const enum AVPixelFormat[]){ diff --git a/libavcodec/pnmenc.c b/libavcodec/pnmenc.c index 9b2824a104..e6c3635e7b 100644 --- a/libavcodec/pnmenc.c +++ b/libavcodec/pnmenc.c @@ -22,13 +22,11 @@ #include "libavutil/pixdesc.h" #include "avcodec.h" #include "internal.h" -#include "pnm.h" - static int pnm_encode_frame(AVCodecContext *avctx, AVPacket *pkt, const AVFrame *p, int *got_packet) { - PNMContext *s = avctx->priv_data; + uint8_t *bytestream, *bytestream_start, *bytestream_end; int i, h, h1, c, n, linesize, ret; uint8_t *ptr, *ptr1, *ptr2; @@ -37,9 +35,9 @@ static int pnm_encode_frame(AVCodecContext *avctx, AVPacket *pkt, avctx->height) + 200)) < 0) return ret; - s->bytestream_start = - s->bytestream = pkt->data; - s->bytestream_end = pkt->data + pkt->size; + bytestream_start = + bytestream = pkt->data; + bytestream_end = pkt->data + pkt->size; h = avctx->height; h1 = h; @@ -81,22 +79,22 @@ static int pnm_encode_frame(AVCodecContext *avctx, AVPacket *pkt, default: return -1; } - snprintf(s->bytestream, s->bytestream_end - s->bytestream, + snprintf(bytestream, bytestream_end - bytestream, "P%c\n%d %d\n", c, avctx->width, h1); - s->bytestream += strlen(s->bytestream); + bytestream += strlen(bytestream); if (avctx->pix_fmt != AV_PIX_FMT_MONOWHITE) { int maxdepth = (1 << (av_pix_fmt_desc_get(avctx->pix_fmt)->comp[0].depth_minus1 + 1)) - 1; - snprintf(s->bytestream, s->bytestream_end - s->bytestream, + snprintf(bytestream, bytestream_end - bytestream, "%d\n", maxdepth); - s->bytestream += strlen(s->bytestream); + bytestream += strlen(bytestream); } ptr = p->data[0]; linesize = p->linesize[0]; for (i = 0; i < h; i++) { - memcpy(s->bytestream, ptr, n); - s->bytestream += n; - ptr += linesize; + memcpy(bytestream, ptr, n); + bytestream += n; + ptr += linesize; } if (avctx->pix_fmt == AV_PIX_FMT_YUV420P || avctx->pix_fmt == AV_PIX_FMT_YUV420P16BE) { @@ -105,21 +103,38 @@ static int pnm_encode_frame(AVCodecContext *avctx, AVPacket *pkt, ptr1 = p->data[1]; ptr2 = p->data[2]; for (i = 0; i < h; i++) { - memcpy(s->bytestream, ptr1, n); - s->bytestream += n; - memcpy(s->bytestream, ptr2, n); - s->bytestream += n; + memcpy(bytestream, ptr1, n); + bytestream += n; + memcpy(bytestream, ptr2, n); + bytestream += n; ptr1 += p->linesize[1]; ptr2 += p->linesize[2]; } } - pkt->size = s->bytestream - s->bytestream_start; + pkt->size = bytestream - bytestream_start; pkt->flags |= AV_PKT_FLAG_KEY; *got_packet = 1; return 0; } +static av_cold int pnm_encode_init(AVCodecContext *avctx) +{ + avctx->coded_frame = av_frame_alloc(); + if (!avctx->coded_frame) + return AVERROR(ENOMEM); + + avctx->coded_frame->pict_type = AV_PICTURE_TYPE_I; + avctx->coded_frame->key_frame = 1; + + return 0; +} + +static av_cold int pnm_encode_close(AVCodecContext *avctx) +{ + av_frame_free(&avctx->coded_frame); + return 0; +} #if CONFIG_PGM_ENCODER AVCodec ff_pgm_encoder = { @@ -127,7 +142,8 @@ AVCodec ff_pgm_encoder = { .long_name = NULL_IF_CONFIG_SMALL("PGM (Portable GrayMap) image"), .type = AVMEDIA_TYPE_VIDEO, .id = AV_CODEC_ID_PGM, - .priv_data_size = sizeof(PNMContext), + .init = pnm_encode_init, + .close = pnm_encode_close, .encode2 = pnm_encode_frame, .pix_fmts = (const enum AVPixelFormat[]){ AV_PIX_FMT_GRAY8, AV_PIX_FMT_GRAY16BE, AV_PIX_FMT_NONE @@ -141,7 +157,8 @@ AVCodec ff_pgmyuv_encoder = { .long_name = NULL_IF_CONFIG_SMALL("PGMYUV (Portable GrayMap YUV) image"), .type = AVMEDIA_TYPE_VIDEO, .id = AV_CODEC_ID_PGMYUV, - .priv_data_size = sizeof(PNMContext), + .init = pnm_encode_init, + .close = pnm_encode_close, .encode2 = pnm_encode_frame, .pix_fmts = (const enum AVPixelFormat[]){ AV_PIX_FMT_YUV420P, AV_PIX_FMT_YUV420P16BE, AV_PIX_FMT_NONE @@ -155,7 +172,8 @@ AVCodec ff_ppm_encoder = { .long_name = NULL_IF_CONFIG_SMALL("PPM (Portable PixelMap) image"), .type = AVMEDIA_TYPE_VIDEO, .id = AV_CODEC_ID_PPM, - .priv_data_size = sizeof(PNMContext), + .init = pnm_encode_init, + .close = pnm_encode_close, .encode2 = pnm_encode_frame, .pix_fmts = (const enum AVPixelFormat[]){ AV_PIX_FMT_RGB24, AV_PIX_FMT_RGB48BE, AV_PIX_FMT_NONE @@ -169,7 +187,8 @@ AVCodec ff_pbm_encoder = { .long_name = NULL_IF_CONFIG_SMALL("PBM (Portable BitMap) image"), .type = AVMEDIA_TYPE_VIDEO, .id = AV_CODEC_ID_PBM, - .priv_data_size = sizeof(PNMContext), + .init = pnm_encode_init, + .close = pnm_encode_close, .encode2 = pnm_encode_frame, .pix_fmts = (const enum AVPixelFormat[]){ AV_PIX_FMT_MONOWHITE, AV_PIX_FMT_NONE }, diff --git a/libavcodec/proresenc_anatoliy.c b/libavcodec/proresenc_anatoliy.c index e124b41bdd..1e842d63eb 100644 --- a/libavcodec/proresenc_anatoliy.c +++ b/libavcodec/proresenc_anatoliy.c @@ -304,7 +304,7 @@ static int encode_slice_plane(AVCodecContext *avctx, int mb_count, } blocks_per_slice = mb_count << (2 - chroma); - init_put_bits(&pb, buf, buf_size << 3); + init_put_bits(&pb, buf, buf_size); encode_dc_coeffs(&pb, blocks, blocks_per_slice, qmat); encode_ac_coeffs(avctx, &pb, blocks, blocks_per_slice, qmat); diff --git a/libavcodec/proresenc_kostya.c b/libavcodec/proresenc_kostya.c index 510b4084e2..8e5ab36ab6 100644 --- a/libavcodec/proresenc_kostya.c +++ b/libavcodec/proresenc_kostya.c @@ -470,7 +470,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) { @@ -565,11 +564,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; } @@ -940,9 +944,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; @@ -1018,8 +1022,10 @@ static int encode_frame(AVCodecContext *avctx, AVPacket *pkt, bytestream_put_byte(&buf, slice_hdr_size << 3); 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); + init_put_bits(&pb, buf, (pkt_size - (buf - orig_buf))); + 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]; @@ -1187,8 +1193,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 * @@ -1197,6 +1201,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/pthread.c b/libavcodec/pthread.c index b8beac3ed1..cdbe729b12 100644 --- a/libavcodec/pthread.c +++ b/libavcodec/pthread.c @@ -95,7 +95,7 @@ typedef struct PerThreadContext { uint8_t *buf; ///< backup storage for packet data when the input packet is not refcounted int allocated_buf_size; ///< Size allocated for buf - AVFrame frame; ///< Output frame (for decoding) or input (for encoding). + AVFrame *frame; ///< Output frame (for decoding) or input (for encoding). int got_frame; ///< The output of got_picture_ptr from the last avcodec_decode_video() call. int result; ///< The result of the last codec decode/encode() call. @@ -340,13 +340,9 @@ static attribute_align_arg void *frame_worker_thread(void *arg) if (!codec->update_thread_context && THREAD_SAFE_CALLBACKS(avctx)) ff_thread_finish_setup(avctx); - avcodec_get_frame_defaults(&p->frame); + av_frame_unref(p->frame); p->got_frame = 0; - p->result = codec->decode(avctx, &p->frame, &p->got_frame, &p->avpkt); - - /* many decoders assign whole AVFrames, thus overwriting extended_data; - * make sure it's set correctly */ - p->frame.extended_data = p->frame.data; + p->result = codec->decode(avctx, p->frame, &p->got_frame, &p->avpkt); if (p->state == STATE_SETTING_UP) ff_thread_finish_setup(avctx); @@ -638,7 +634,7 @@ int ff_thread_decode_frame(AVCodecContext *avctx, pthread_mutex_unlock(&p->progress_mutex); } - av_frame_move_ref(picture, &p->frame); + av_frame_move_ref(picture, p->frame); *got_picture_ptr = p->got_frame; picture->pkt_dts = p->avpkt.dts; @@ -766,7 +762,7 @@ static void frame_thread_free(AVCodecContext *avctx, int thread_count) avctx->codec = NULL; release_delayed_buffers(p); - av_frame_unref(&p->frame); + av_frame_free(&p->frame); } for (i = 0; i < thread_count; i++) { @@ -835,6 +831,12 @@ static int frame_thread_init(AVCodecContext *avctx) pthread_cond_init(&p->progress_cond, NULL); pthread_cond_init(&p->output_cond, NULL); + p->frame = av_frame_alloc(); + if (!p->frame) { + err = AVERROR(ENOMEM); + goto error; + } + p->parent = fctx; p->avctx = copy; @@ -900,8 +902,6 @@ void ff_thread_flush(AVCodecContext *avctx) if (fctx->prev_thread) { if (fctx->prev_thread != &fctx->threads[0]) update_context_from_thread(fctx->threads[0].avctx, fctx->prev_thread->avctx, 0); - if (avctx->codec->flush) - avctx->codec->flush(fctx->threads[0].avctx); } fctx->next_decoding = fctx->next_finished = 0; @@ -911,9 +911,12 @@ void ff_thread_flush(AVCodecContext *avctx) PerThreadContext *p = &fctx->threads[i]; // Make sure decode flush calls with size=0 won't return old frames p->got_frame = 0; - av_frame_unref(&p->frame); + av_frame_unref(p->frame); release_delayed_buffers(p); + + if (avctx->codec->flush) + avctx->codec->flush(fctx->threads[0].avctx); } } diff --git a/libavcodec/qpeg.c b/libavcodec/qpeg.c index edde937b15..eb1be3bf1d 100644 --- a/libavcodec/qpeg.c +++ b/libavcodec/qpeg.c @@ -30,7 +30,7 @@ typedef struct QpegContext{ AVCodecContext *avctx; - AVFrame pic, ref; + AVFrame *pic, *ref; uint32_t pal[256]; GetByteContext buffer; } QpegContext; @@ -163,7 +163,7 @@ static void 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); @@ -255,8 +255,8 @@ static int decode_frame(AVCodecContext *avctx, { uint8_t ctable[128]; QpegContext * const a = avctx->priv_data; - AVFrame * p = &a->pic; - AVFrame * ref= &a->ref; + AVFrame * const p = a->pic; + AVFrame * const ref = a->ref; uint8_t* outdata; int delta, ret; const uint8_t *pal = av_packet_get_side_data(avpkt, AV_PKT_DATA_PALETTE, NULL); @@ -273,26 +273,26 @@ static int decode_frame(AVCodecContext *avctx, if ((ret = ff_get_buffer(avctx, p, AV_GET_BUFFER_FLAG_REF)) < 0) return ret; - outdata = a->pic.data[0]; + outdata = p->data[0]; bytestream2_skip(&a->buffer, 4); bytestream2_get_buffer(&a->buffer, ctable, 128); bytestream2_skip(&a->buffer, 1); delta = bytestream2_get_byte(&a->buffer); if(delta == 0x10) { - qpeg_decode_intra(a, outdata, a->pic.linesize[0], avctx->width, avctx->height); + qpeg_decode_intra(a, outdata, p->linesize[0], avctx->width, avctx->height); } else { - qpeg_decode_inter(a, outdata, a->pic.linesize[0], avctx->width, avctx->height, delta, ctable, a->ref.data[0]); + qpeg_decode_inter(a, outdata, p->linesize[0], avctx->width, avctx->height, delta, ctable, ref->data[0]); } /* make the palette available on the way out */ if (pal) { - a->pic.palette_has_changed = 1; + p->palette_has_changed = 1; memcpy(a->pal, pal, AVPALETTE_SIZE); } - memcpy(a->pic.data[1], a->pal, AVPALETTE_SIZE); + memcpy(p->data[1], a->pal, AVPALETTE_SIZE); - if ((ret = av_frame_ref(data, &a->pic)) < 0) + if ((ret = av_frame_ref(data, p)) < 0) return ret; *got_frame = 1; @@ -312,6 +312,16 @@ static void decode_flush(AVCodecContext *avctx){ a->pal[i] = 0xFFU<<24 | AV_RL32(pal_src+4*i); } +static av_cold int decode_end(AVCodecContext *avctx) +{ + QpegContext * const a = avctx->priv_data; + + av_frame_free(&a->pic); + av_frame_free(&a->ref); + + return 0; +} + static av_cold int decode_init(AVCodecContext *avctx){ QpegContext * const a = avctx->priv_data; @@ -322,18 +332,12 @@ static av_cold int decode_init(AVCodecContext *avctx){ decode_flush(avctx); - avcodec_get_frame_defaults(&a->pic); - - return 0; -} - -static av_cold int decode_end(AVCodecContext *avctx){ - QpegContext * const a = avctx->priv_data; - AVFrame * const p = &a->pic; - AVFrame * const ref= &a->ref; - - av_frame_unref(p); - av_frame_unref(ref); + a->pic = av_frame_alloc(); + a->ref = av_frame_alloc(); + if (!a->pic || !a->ref) { + decode_end(avctx); + return AVERROR(ENOMEM); + } return 0; } diff --git a/libavcodec/qtrleenc.c b/libavcodec/qtrleenc.c index 2395cffb0d..7f9525abe0 100644 --- a/libavcodec/qtrleenc.c +++ b/libavcodec/qtrleenc.c @@ -36,7 +36,6 @@ typedef struct QtrleEncContext { AVCodecContext *avctx; - AVFrame frame; int pixel_size; AVPicture previous_frame; unsigned int max_buf_size; @@ -61,6 +60,19 @@ typedef struct QtrleEncContext { uint8_t* skip_table; } QtrleEncContext; +static av_cold int qtrle_encode_end(AVCodecContext *avctx) +{ + QtrleEncContext *s = avctx->priv_data; + + av_frame_free(&avctx->coded_frame); + + avpicture_free(&s->previous_frame); + av_free(s->rlecode_table); + av_free(s->length_table); + av_free(s->skip_table); + return 0; +} + static av_cold int qtrle_encode_init(AVCodecContext *avctx) { QtrleEncContext *s = avctx->priv_data; @@ -108,7 +120,13 @@ static av_cold int qtrle_encode_init(AVCodecContext *avctx) + 15 /* header + footer */ + s->avctx->height*2 /* skip code+rle end */ + s->logical_width/MAX_RLE_BULK + 1 /* rle codes */; - avctx->coded_frame = &s->frame; + + avctx->coded_frame = av_frame_alloc(); + if (!avctx->coded_frame) { + qtrle_encode_end(avctx); + return AVERROR(ENOMEM); + } + return 0; } @@ -197,7 +215,7 @@ static void qtrle_encode_line(QtrleEncContext *s, const AVFrame *p, int line, ui } } - if (!s->frame.key_frame && !memcmp(this_line, prev_line, s->pixel_size)) + if (!s->avctx->coded_frame->key_frame && !memcmp(this_line, prev_line, s->pixel_size)) skipcount = FFMIN(skipcount + 1, MAX_RLE_SKIP); else skipcount = 0; @@ -308,7 +326,7 @@ static int encode_frame(QtrleEncContext *s, const AVFrame *p, uint8_t *buf) int end_line = s->avctx->height; uint8_t *orig_buf = buf; - if (!s->frame.key_frame) { + if (!s->avctx->coded_frame->key_frame) { unsigned line_size = s->logical_width * s->pixel_size; for (start_line = 0; start_line < s->avctx->height; start_line++) if (memcmp(p->data[0] + start_line*p->linesize[0], @@ -346,11 +364,9 @@ static int qtrle_encode_frame(AVCodecContext *avctx, AVPacket *pkt, const AVFrame *pict, int *got_packet) { QtrleEncContext * const s = avctx->priv_data; - AVFrame * const p = &s->frame; + AVFrame * const p = avctx->coded_frame; int ret; - *p = *pict; - if ((ret = ff_alloc_packet2(avctx, pkt, s->max_buf_size)) < 0) return ret; @@ -367,7 +383,8 @@ static int qtrle_encode_frame(AVCodecContext *avctx, AVPacket *pkt, pkt->size = encode_frame(s, pict, pkt->data); /* save the current frame */ - av_picture_copy(&s->previous_frame, (AVPicture *)p, avctx->pix_fmt, avctx->width, avctx->height); + av_picture_copy(&s->previous_frame, (const AVPicture *)pict, + avctx->pix_fmt, avctx->width, avctx->height); if (p->key_frame) pkt->flags |= AV_PKT_FLAG_KEY; @@ -376,17 +393,6 @@ static int qtrle_encode_frame(AVCodecContext *avctx, AVPacket *pkt, return 0; } -static av_cold int qtrle_encode_end(AVCodecContext *avctx) -{ - QtrleEncContext *s = avctx->priv_data; - - avpicture_free(&s->previous_frame); - av_free(s->rlecode_table); - av_free(s->length_table); - av_free(s->skip_table); - return 0; -} - AVCodec ff_qtrle_encoder = { .name = "qtrle", .long_name = NULL_IF_CONFIG_SMALL("QuickTime Animation (RLE) video"), diff --git a/libavcodec/ra144enc.c b/libavcodec/ra144enc.c index 3558254e56..a01833381f 100644 --- a/libavcodec/ra144enc.c +++ b/libavcodec/ra144enc.c @@ -34,7 +34,6 @@ #include "celp_filters.h" #include "ra144.h" - static av_cold int ra144_encode_close(AVCodecContext *avctx) { RA144Context *ractx = avctx->priv_data; diff --git a/libavcodec/rawdec.c b/libavcodec/rawdec.c index dd47f532fd..5e98e24b32 100644 --- a/libavcodec/rawdec.c +++ b/libavcodec/rawdec.c @@ -144,6 +144,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/roqvideo.h b/libavcodec/roqvideo.h index 3834897252..39dda0c88b 100644 --- a/libavcodec/roqvideo.h +++ b/libavcodec/roqvideo.h @@ -44,7 +44,6 @@ struct RoqTempData; typedef struct RoqContext { AVCodecContext *avctx; - AVFrame frames[2]; AVFrame *last_frame; AVFrame *current_frame; int first_frame; diff --git a/libavcodec/roqvideoenc.c b/libavcodec/roqvideoenc.c index bf0756cbe3..30548ebf35 100644 --- a/libavcodec/roqvideoenc.c +++ b/libavcodec/roqvideoenc.c @@ -959,6 +959,8 @@ static av_cold int roq_encode_init(AVCodecContext *avctx) av_lfg_init(&enc->randctx, 1); + enc->avctx = avctx; + enc->framesSinceKeyframe = 0; if ((avctx->width & 0xf) || (avctx->height & 0xf)) { av_log(avctx, AV_LOG_ERROR, "Dimensions must be divisible by 16\n"); diff --git a/libavcodec/rpza.c b/libavcodec/rpza.c index 4917369de0..d4e2b17add 100644 --- a/libavcodec/rpza.c +++ b/libavcodec/rpza.c @@ -46,7 +46,7 @@ typedef struct RpzaContext { AVCodecContext *avctx; - AVFrame frame; + AVFrame *frame; const unsigned char *buf; int size; @@ -72,7 +72,7 @@ typedef struct RpzaContext { static void rpza_decode_stream(RpzaContext *s) { int width = s->avctx->width; - int stride = s->frame.linesize[0] / 2; + int stride = s->frame->linesize[0] / 2; int row_inc = stride - 4; int stream_ptr = 0; int chunk_size; @@ -82,7 +82,7 @@ static void rpza_decode_stream(RpzaContext *s) unsigned short color4[4]; unsigned char index, idx; unsigned short ta, tb; - unsigned short *pixels = (unsigned short *)s->frame.data[0]; + unsigned short *pixels = (unsigned short *)s->frame->data[0]; int row_ptr = 0; int pixel_ptr = -4; @@ -239,7 +239,9 @@ static av_cold int rpza_decode_init(AVCodecContext *avctx) s->avctx = avctx; avctx->pix_fmt = AV_PIX_FMT_RGB555; - avcodec_get_frame_defaults(&s->frame); + s->frame = av_frame_alloc(); + if (!s->frame) + return AVERROR(ENOMEM); return 0; } @@ -256,12 +258,12 @@ static int rpza_decode_frame(AVCodecContext *avctx, s->buf = buf; s->size = buf_size; - if ((ret = ff_reget_buffer(avctx, &s->frame)) < 0) + if ((ret = ff_reget_buffer(avctx, s->frame)) < 0) return ret; rpza_decode_stream(s); - if ((ret = av_frame_ref(data, &s->frame)) < 0) + if ((ret = av_frame_ref(data, s->frame)) < 0) return ret; *got_frame = 1; @@ -274,7 +276,7 @@ static av_cold int rpza_decode_end(AVCodecContext *avctx) { RpzaContext *s = avctx->priv_data; - av_frame_unref(&s->frame); + av_frame_free(&s->frame); return 0; } diff --git a/libavcodec/rv10enc.c b/libavcodec/rv10enc.c index 1f85743b7b..ae4993c81b 100644 --- a/libavcodec/rv10enc.c +++ b/libavcodec/rv10enc.c @@ -28,7 +28,7 @@ #include "mpegvideo.h" #include "put_bits.h" -void ff_rv10_encode_picture_header(MpegEncContext *s, int picture_number) +int ff_rv10_encode_picture_header(MpegEncContext *s, int picture_number) { int full_frame= 0; @@ -48,12 +48,17 @@ void ff_rv10_encode_picture_header(MpegEncContext *s, int picture_number) /* if multiple packets per frame are sent, the position at which to display the macroblocks is coded here */ if(!full_frame){ + if (s->mb_width * s->mb_height >= (1U << 12)) { + avpriv_report_missing_feature(s, "Encoding frames with 4096 or more macroblocks"); + return AVERROR(ENOSYS); + } put_bits(&s->pb, 6, 0); /* mb_x */ put_bits(&s->pb, 6, 0); /* mb_y */ put_bits(&s->pb, 12, s->mb_width * s->mb_height); } put_bits(&s->pb, 3, 0); /* ignored */ + return 0; } FF_MPV_GENERIC_CLASS(rv10) diff --git a/libavcodec/s302menc.c b/libavcodec/s302menc.c index c428d54353..cb902826be 100644 --- a/libavcodec/s302menc.c +++ b/libavcodec/s302menc.c @@ -81,7 +81,7 @@ static int s302m_encode2_frame(AVCodecContext *avctx, AVPacket *avpkt, return ret; o = avpkt->data; - init_put_bits(&pb, o, buf_size * 8); + init_put_bits(&pb, o, buf_size); put_bits(&pb, 16, buf_size - AES3_HEADER_LEN); put_bits(&pb, 2, (avctx->channels - 2) >> 1); // number of channels put_bits(&pb, 8, 0); // channel ID diff --git a/libavcodec/sgienc.c b/libavcodec/sgienc.c index 48532ff3e1..0e4f304a23 100644 --- a/libavcodec/sgienc.c +++ b/libavcodec/sgienc.c @@ -34,6 +34,9 @@ static av_cold int encode_init(AVCodecContext *avctx) av_log(avctx, AV_LOG_ERROR, "SGI does not support resolutions above 65535x65535\n"); return -1; } + avctx->coded_frame = av_frame_alloc(); + if (!avctx->coded_frame) + return AVERROR(ENOMEM); return 0; } @@ -41,14 +44,14 @@ static av_cold int encode_init(AVCodecContext *avctx) static int encode_frame(AVCodecContext *avctx, AVPacket *pkt, const AVFrame *frame, int *got_packet) { - AVFrame * const p = (AVFrame *)frame; + const AVFrame * const p = frame; uint8_t *offsettab, *lengthtab, *in_buf, *encode_buf, *buf; int x, y, z, length, tablesize, ret; unsigned int width, height, depth, dimension, bytes_per_channel, pixmax, put_be; unsigned char *end_buf; - p->pict_type = AV_PICTURE_TYPE_I; - p->key_frame = 1; + avctx->coded_frame->pict_type = AV_PICTURE_TYPE_I; + avctx->coded_frame->key_frame = 1; width = avctx->width; height = avctx->height; @@ -199,6 +202,12 @@ static int encode_frame(AVCodecContext *avctx, AVPacket *pkt, return 0; } +static av_cold int encode_close(AVCodecContext *avctx) +{ + av_frame_free(&avctx->coded_frame); + return 0; +} + AVCodec ff_sgi_encoder = { .name = "sgi", .long_name = NULL_IF_CONFIG_SMALL("SGI image"), @@ -206,6 +215,7 @@ AVCodec ff_sgi_encoder = { .id = AV_CODEC_ID_SGI, .init = encode_init, .encode2 = encode_frame, + .close = encode_close, .pix_fmts = (const enum AVPixelFormat[]){ AV_PIX_FMT_RGB24, AV_PIX_FMT_RGBA, AV_PIX_FMT_RGB48LE, AV_PIX_FMT_RGB48BE, diff --git a/libavcodec/smacker.c b/libavcodec/smacker.c index 3cdb0d58b3..717e9ea033 100644 --- a/libavcodec/smacker.c +++ b/libavcodec/smacker.c @@ -584,6 +584,10 @@ static av_cold int decode_init(AVCodecContext *avctx) avctx->pix_fmt = AV_PIX_FMT_PAL8; + c->pic = av_frame_alloc(); + if (!c->pic) + return AVERROR(ENOMEM); + /* decode huffman trees from extradata */ if(avctx->extradata_size < 16){ av_log(avctx, AV_LOG_ERROR, "Extradata missing!\n"); @@ -596,10 +600,6 @@ static av_cold int decode_init(AVCodecContext *avctx) return ret; } - c->pic = av_frame_alloc(); - if (!c->pic) - return AVERROR(ENOMEM); - return 0; } diff --git a/libavcodec/smc.c b/libavcodec/smc.c index 3b836e7c7a..791612ebd4 100644 --- a/libavcodec/smc.c +++ b/libavcodec/smc.c @@ -46,7 +46,7 @@ typedef struct SmcContext { AVCodecContext *avctx; - AVFrame frame; + AVFrame *frame; GetByteContext gb; @@ -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; \ @@ -81,7 +81,7 @@ static void smc_decode_stream(SmcContext *s) { int width = s->avctx->width; int height = s->avctx->height; - int stride = s->frame.linesize[0]; + int stride = s->frame->linesize[0]; int i; int chunk_size; int buf_size = bytestream2_size(&s->gb); @@ -92,9 +92,9 @@ static void smc_decode_stream(SmcContext *s) unsigned int color_flags_b; unsigned int flag_mask; - unsigned char *pixels = s->frame.data[0]; + unsigned char *pixels = s->frame->data[0]; - int image_size = height * s->frame.linesize[0]; + int image_size = height * s->frame->linesize[0]; int row_ptr = 0; int pixel_ptr = 0; int pixel_x, pixel_y; @@ -112,7 +112,7 @@ static void smc_decode_stream(SmcContext *s) int color_octet_index = 0; /* make the palette available */ - memcpy(s->frame.data[1], s->pal, AVPALETTE_SIZE); + memcpy(s->frame->data[1], s->pal, AVPALETTE_SIZE); bytestream2_skip(&s->gb, 1); chunk_size = bytestream2_get_be24(&s->gb); @@ -417,7 +417,9 @@ static av_cold int smc_decode_init(AVCodecContext *avctx) s->avctx = avctx; avctx->pix_fmt = AV_PIX_FMT_PAL8; - avcodec_get_frame_defaults(&s->frame); + s->frame = av_frame_alloc(); + if (!s->frame) + return AVERROR(ENOMEM); return 0; } @@ -434,18 +436,18 @@ static int smc_decode_frame(AVCodecContext *avctx, bytestream2_init(&s->gb, buf, buf_size); - if ((ret = ff_reget_buffer(avctx, &s->frame)) < 0) + if ((ret = ff_reget_buffer(avctx, s->frame)) < 0) return ret; if (pal) { - s->frame.palette_has_changed = 1; + s->frame->palette_has_changed = 1; memcpy(s->pal, pal, AVPALETTE_SIZE); } smc_decode_stream(s); *got_frame = 1; - if ((ret = av_frame_ref(data, &s->frame)) < 0) + if ((ret = av_frame_ref(data, s->frame)) < 0) return ret; /* always report that the buffer was completely consumed */ @@ -456,7 +458,7 @@ static av_cold int smc_decode_end(AVCodecContext *avctx) { SmcContext *s = avctx->priv_data; - av_frame_unref(&s->frame); + av_frame_free(&s->frame); return 0; } diff --git a/libavcodec/snow.c b/libavcodec/snow.c index b54c491f42..9a07d976e5 100644 --- a/libavcodec/snow.c +++ b/libavcodec/snow.c @@ -688,7 +688,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 1222a776de..9910f3f6c1 100644 --- a/libavcodec/snow.h +++ b/libavcodec/snow.h @@ -318,7 +318,8 @@ static av_always_inline void add_yblock(SnowContext *s, int sliced, slice_buffer if(!sliced && !offset_dst) dst -= src_x; src_x=0; - }else if(src_x + b_w > w){ + } + if(src_x + b_w > w){ b_w = w - src_x; } if(src_y<0){ @@ -327,7 +328,8 @@ static av_always_inline void add_yblock(SnowContext *s, int sliced, slice_buffer if(!sliced && !offset_dst) dst -= src_y*dst_stride; src_y=0; - }else if(src_y + b_h> h){ + } + if(src_y + b_h> h){ b_h = h - src_y; } @@ -653,7 +655,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; } @@ -663,6 +668,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/snowdec.c b/libavcodec/snowdec.c index c9d40b84e3..5aae25ae0f 100644 --- a/libavcodec/snowdec.c +++ b/libavcodec/snowdec.c @@ -153,7 +153,7 @@ static int decode_q_branch(SnowContext *s, int level, int x, int y){ int l = left->color[0]; int cb= left->color[1]; int cr= left->color[2]; - int ref = 0; + unsigned ref = 0; int ref_context= av_log2(2*left->ref) + av_log2(2*top->ref); int mx_context= av_log2(2*FFABS(left->mx - top->mx)) + 0*av_log2(2*FFABS(tr->mx - top->mx)); int my_context= av_log2(2*FFABS(left->my - top->my)) + 0*av_log2(2*FFABS(tr->my - top->my)); diff --git a/libavcodec/srtenc.c b/libavcodec/srtenc.c index 3036a7fb0c..89c26dcbf0 100644 --- a/libavcodec/srtenc.c +++ b/libavcodec/srtenc.c @@ -22,6 +22,7 @@ #include #include "avcodec.h" #include "libavutil/avstring.h" +#include "libavutil/bprint.h" #include "ass_split.h" #include "ass.h" @@ -31,10 +32,8 @@ typedef struct { AVCodecContext *avctx; ASSSplitContext *ass_ctx; - char buffer[2048]; - char *ptr; - char *end; - char *dialog_start; + AVBPrint buffer; + unsigned timestamp_end; int count; char stack[SRT_STACK_SIZE]; int stack_ptr; @@ -49,7 +48,7 @@ static void srt_print(SRTContext *s, const char *str, ...) { va_list vargs; va_start(vargs, str); - s->ptr += vsnprintf(s->ptr, s->end - s->ptr, str, vargs); + av_vbprintf(&s->buffer, str, vargs); va_end(vargs); } @@ -138,14 +137,14 @@ static av_cold int srt_encode_init(AVCodecContext *avctx) SRTContext *s = avctx->priv_data; s->avctx = avctx; s->ass_ctx = ff_ass_split(avctx->subtitle_header); + av_bprint_init(&s->buffer, 0, AV_BPRINT_SIZE_UNLIMITED); return s->ass_ctx ? 0 : AVERROR_INVALIDDATA; } static void srt_text_cb(void *priv, const char *text, int len) { SRTContext *s = priv; - av_strlcpy(s->ptr, text, FFMIN(s->end-s->ptr, len+1)); - s->ptr += len; + av_bprint_append_data(&s->buffer, text, len); } static void srt_new_line_cb(void *priv, int forced) @@ -208,11 +207,19 @@ static void srt_move_cb(void *priv, int x1, int y1, int x2, int y2, char buffer[32]; int len = snprintf(buffer, sizeof(buffer), " X1:%03u X2:%03u Y1:%03u Y2:%03u", x1, x2, y1, y2); - if (s->end - s->ptr > len) { - memmove(s->dialog_start+len, s->dialog_start, s->ptr-s->dialog_start+1); - memcpy(s->dialog_start, buffer, len); - s->ptr += len; + unsigned char *dummy; + unsigned room; + + av_bprint_get_buffer(&s->buffer, len, &dummy, &room); + if (room >= len) { + memmove(s->buffer.str + s->timestamp_end + len, + s->buffer.str + s->timestamp_end, + s->buffer.len - s->timestamp_end + 1); + memcpy(s->buffer.str + s->timestamp_end, buffer, len); } + /* Increment even if av_bprint_get_buffer() did not return enough room: + the bprint structure will be treated as truncated. */ + s->buffer.len += len; } } @@ -243,10 +250,9 @@ static int srt_encode_frame(AVCodecContext *avctx, { SRTContext *s = avctx->priv_data; ASSDialog *dialog; - int i, len, num; + int i, num; - s->ptr = s->buffer; - s->end = s->ptr + sizeof(s->buffer); + av_bprint_clear(&s->buffer); for (i=0; inum_rects; i++) { @@ -268,7 +274,7 @@ static int srt_encode_frame(AVCodecContext *avctx, es = ec/ 1000; ec -= 1000*es; srt_print(s,"%d\r\n%02d:%02d:%02d,%03d --> %02d:%02d:%02d,%03d\r\n", ++s->count, sh, sm, ss, sc, eh, em, es, ec); - s->dialog_start = s->ptr - 2; + s->timestamp_end = s->buffer.len - 2; } s->alignment_applied = 0; srt_style_apply(s, dialog->style); @@ -276,23 +282,25 @@ static int srt_encode_frame(AVCodecContext *avctx, } } - if (s->ptr == s->buffer) + if (!av_bprint_is_complete(&s->buffer)) + return AVERROR(ENOMEM); + if (!s->buffer.len) return 0; - len = av_strlcpy(buf, s->buffer, bufsize); - - if (len > bufsize-1) { + if (s->buffer.len > bufsize) { av_log(avctx, AV_LOG_ERROR, "Buffer too small for ASS event.\n"); return -1; } + memcpy(buf, s->buffer.str, s->buffer.len); - return len; + return s->buffer.len; } static int srt_encode_close(AVCodecContext *avctx) { SRTContext *s = avctx->priv_data; ff_ass_split_free(s->ass_ctx); + av_bprint_finalize(&s->buffer, NULL); return 0; } diff --git a/libavcodec/sunrastenc.c b/libavcodec/sunrastenc.c index 0879ce62cb..a55e3d439a 100644 --- a/libavcodec/sunrastenc.c +++ b/libavcodec/sunrastenc.c @@ -198,6 +198,12 @@ static int sunrast_encode_frame(AVCodecContext *avctx, AVPacket *avpkt, return 0; } +static av_cold int sunrast_encode_close(AVCodecContext *avctx) +{ + av_frame_free(&avctx->coded_frame); + return 0; +} + static const AVCodecDefault sunrast_defaults[] = { { "coder", "rle" }, { NULL }, @@ -210,6 +216,7 @@ AVCodec ff_sunrast_encoder = { .id = AV_CODEC_ID_SUNRAST, .priv_data_size = sizeof(SUNRASTContext), .init = sunrast_encode_init, + .close = sunrast_encode_close, .encode2 = sunrast_encode_frame, .defaults = sunrast_defaults, .pix_fmts = (const enum AVPixelFormat[]){ AV_PIX_FMT_BGR24, diff --git a/libavcodec/svq1dec.c b/libavcodec/svq1dec.c index 5193798ea4..b1aadcde6c 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/svq1enc.c b/libavcodec/svq1enc.c index a6c94ad006..2d7e848fc7 100644 --- a/libavcodec/svq1enc.c +++ b/libavcodec/svq1enc.c @@ -45,9 +45,8 @@ typedef struct SVQ1Context { AVCodecContext *avctx; DSPContext dsp; HpelDSPContext hdsp; - AVFrame picture; - AVFrame current_picture; - AVFrame last_picture; + AVFrame *current_picture; + AVFrame *last_picture; PutBitContext pb; GetBitContext gb; @@ -264,13 +263,14 @@ static int svq1_encode_plane(SVQ1Context *s, int plane, unsigned char *decoded_plane, int width, int height, int src_stride, int stride) { + const AVFrame *f = s->avctx->coded_frame; int x, y; int i; int block_width, block_height; int level; int threshold[6]; uint8_t *src = s->scratchbuf + stride * 16; - const int lambda = (s->picture.quality * s->picture.quality) >> + const int lambda = (f->quality * f->quality) >> (2 * FF_LAMBDA_SHIFT); /* figure out the acceptable level thresholds in advance */ @@ -281,7 +281,7 @@ static int svq1_encode_plane(SVQ1Context *s, int plane, block_width = (width + 15) / 16; block_height = (height + 15) / 16; - if (s->picture.pict_type == AV_PICTURE_TYPE_P) { + if (f->pict_type == AV_PICTURE_TYPE_P) { s->m.avctx = s->avctx; s->m.current_picture_ptr = &s->m.current_picture; s->m.last_picture_ptr = &s->m.last_picture; @@ -297,13 +297,13 @@ static int svq1_encode_plane(SVQ1Context *s, int plane, s->m.mb_stride = s->m.mb_width + 1; s->m.b8_stride = 2 * s->m.mb_width + 1; s->m.f_code = 1; - s->m.pict_type = s->picture.pict_type; + s->m.pict_type = f->pict_type; s->m.me_method = s->avctx->me_method; s->m.me.scene_change_score = 0; s->m.flags = s->avctx->flags; // s->m.out_format = FMT_H263; // s->m.unrestricted_mv = 1; - s->m.lambda = s->picture.quality; + s->m.lambda = f->quality; s->m.qscale = s->m.lambda * 139 + FF_LAMBDA_SCALE * 64 >> FF_LAMBDA_SHIFT + 7; @@ -396,13 +396,13 @@ static int svq1_encode_plane(SVQ1Context *s, int plane, ff_init_block_index(&s->m); ff_update_block_index(&s->m); - if (s->picture.pict_type == AV_PICTURE_TYPE_I || + if (f->pict_type == AV_PICTURE_TYPE_I || (s->m.mb_type[x + y * s->m.mb_stride] & CANDIDATE_MB_TYPE_INTRA)) { for (i = 0; i < 6; i++) init_put_bits(&s->reorder_pb[i], reorder_buffer[0][i], 7 * 32); - if (s->picture.pict_type == AV_PICTURE_TYPE_P) { + if (f->pict_type == AV_PICTURE_TYPE_P) { const uint8_t *vlc = ff_svq1_block_type_vlc[SVQ1_BLOCK_INTRA]; put_bits(&s->reorder_pb[5], vlc[1], vlc[0]); score[0] = vlc[1] * lambda; @@ -418,7 +418,7 @@ static int svq1_encode_plane(SVQ1Context *s, int plane, best = 0; - if (s->picture.pict_type == AV_PICTURE_TYPE_P) { + if (f->pict_type == AV_PICTURE_TYPE_P) { const uint8_t *vlc = ff_svq1_block_type_vlc[SVQ1_BLOCK_INTER]; int mx, my, pred_x, pred_y, dxy; int16_t *motion_ptr; @@ -498,13 +498,48 @@ static int svq1_encode_plane(SVQ1Context *s, int plane, return 0; } +static av_cold int svq1_encode_end(AVCodecContext *avctx) +{ + SVQ1Context *const s = avctx->priv_data; + int i; + + av_log(avctx, AV_LOG_DEBUG, "RD: %f\n", + s->rd_total / (double)(avctx->width * avctx->height * + avctx->frame_number)); + + av_freep(&s->m.me.scratchpad); + av_freep(&s->m.me.map); + av_freep(&s->m.me.score_map); + av_freep(&s->mb_type); + av_freep(&s->dummy); + av_freep(&s->scratchbuf); + + for (i = 0; i < 3; i++) { + av_freep(&s->motion_val8[i]); + av_freep(&s->motion_val16[i]); + } + + av_frame_free(&s->current_picture); + av_frame_free(&s->last_picture); + av_frame_free(&avctx->coded_frame); + + return 0; +} + static av_cold int svq1_encode_init(AVCodecContext *avctx) { SVQ1Context *const s = avctx->priv_data; ff_dsputil_init(&s->dsp, avctx); ff_hpeldsp_init(&s->hdsp, avctx->flags); - avctx->coded_frame = &s->picture; + + avctx->coded_frame = av_frame_alloc(); + s->current_picture = av_frame_alloc(); + s->last_picture = av_frame_alloc(); + if (!avctx->coded_frame || !s->current_picture || !s->last_picture) { + svq1_encode_end(avctx); + return AVERROR(ENOMEM); + } s->frame_width = avctx->width; s->frame_height = avctx->height; @@ -536,8 +571,7 @@ static int svq1_encode_frame(AVCodecContext *avctx, AVPacket *pkt, const AVFrame *pict, int *got_packet) { SVQ1Context *const s = avctx->priv_data; - AVFrame *const p = &s->picture; - AVFrame temp; + AVFrame *const p = avctx->coded_frame; int i, ret; if ((ret = ff_alloc_packet2(avctx, pkt, s->y_block_width * s->y_block_height * @@ -549,35 +583,33 @@ static int svq1_encode_frame(AVCodecContext *avctx, AVPacket *pkt, return -1; } - if (!s->current_picture.data[0]) { - if ((ret = ff_get_buffer(avctx, &s->current_picture, 0))< 0 || - (ret = ff_get_buffer(avctx, &s->last_picture, 0)) < 0) { + if (!s->current_picture->data[0]) { + if ((ret = ff_get_buffer(avctx, s->current_picture, 0))< 0 || + (ret = ff_get_buffer(avctx, s->last_picture, 0)) < 0) { return ret; } - s->scratchbuf = av_malloc(s->current_picture.linesize[0] * 16 * 2); + s->scratchbuf = av_malloc(s->current_picture->linesize[0] * 16 * 2); } - av_frame_move_ref(&temp, &s->current_picture); - av_frame_move_ref(&s->current_picture, &s->last_picture); - av_frame_move_ref(&s->last_picture, &temp); + FFSWAP(AVFrame*, s->current_picture, s->last_picture); init_put_bits(&s->pb, pkt->data, pkt->size); - *p = *pict; p->pict_type = avctx->gop_size && avctx->frame_number % avctx->gop_size ? AV_PICTURE_TYPE_P : AV_PICTURE_TYPE_I; p->key_frame = p->pict_type == AV_PICTURE_TYPE_I; + p->quality = pict->quality; svq1_write_header(s, p->pict_type); for (i = 0; i < 3; i++) if (svq1_encode_plane(s, i, - s->picture.data[i], - s->last_picture.data[i], - s->current_picture.data[i], + pict->data[i], + s->last_picture->data[i], + s->current_picture->data[i], s->frame_width / (i ? 4 : 1), s->frame_height / (i ? 4 : 1), - s->picture.linesize[i], - s->current_picture.linesize[i]) < 0) + pict->linesize[i], + s->current_picture->linesize[i]) < 0) return -1; // avpriv_align_put_bits(&s->pb); @@ -594,33 +626,6 @@ static int svq1_encode_frame(AVCodecContext *avctx, AVPacket *pkt, return 0; } -static av_cold int svq1_encode_end(AVCodecContext *avctx) -{ - SVQ1Context *const s = avctx->priv_data; - int i; - - av_log(avctx, AV_LOG_DEBUG, "RD: %f\n", - s->rd_total / (double)(avctx->width * avctx->height * - avctx->frame_number)); - - av_freep(&s->m.me.scratchpad); - av_freep(&s->m.me.map); - av_freep(&s->m.me.score_map); - av_freep(&s->mb_type); - av_freep(&s->dummy); - av_freep(&s->scratchbuf); - - for (i = 0; i < 3; i++) { - av_freep(&s->motion_val8[i]); - av_freep(&s->motion_val16[i]); - } - - av_frame_unref(&s->current_picture); - av_frame_unref(&s->last_picture); - - return 0; -} - AVCodec ff_svq1_encoder = { .name = "svq1", .long_name = NULL_IF_CONFIG_SMALL("Sorenson Vector Quantizer 1 / Sorenson Video 1 / SVQ1"), diff --git a/libavcodec/svq3.c b/libavcodec/svq3.c index 89bb616797..a983dce7cd 100644 --- a/libavcodec/svq3.c +++ b/libavcodec/svq3.c @@ -1157,7 +1157,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(Picture, tf)); ret = av_frame_ref(&h->cur_pic.f, &s->cur_pic->f); if (ret < 0) return ret; diff --git a/libavcodec/takdec.c b/libavcodec/takdec.c index 77de4c095f..b3a7e3a5f3 100644 --- a/libavcodec/takdec.c +++ b/libavcodec/takdec.c @@ -720,11 +720,9 @@ static int tak_decode_frame(AVCodecContext *avctx, void *data, return AVERROR_INVALIDDATA; } - if (s->ti.bps != avctx->bits_per_raw_sample) { - avctx->bits_per_raw_sample = s->ti.bps; - if ((ret = set_bps_params(avctx)) < 0) - return ret; - } + avctx->bits_per_raw_sample = s->ti.bps; + if ((ret = set_bps_params(avctx)) < 0) + return ret; if (s->ti.sample_rate != avctx->sample_rate) { avctx->sample_rate = s->ti.sample_rate; set_sample_rate_params(avctx); diff --git a/libavcodec/targaenc.c b/libavcodec/targaenc.c index 108e1485e4..d4483ec398 100644 --- a/libavcodec/targaenc.c +++ b/libavcodec/targaenc.c @@ -170,11 +170,31 @@ static int targa_encode_frame(AVCodecContext *avctx, AVPacket *pkt, return 0; } +static av_cold int targa_encode_init(AVCodecContext *avctx) +{ + avctx->coded_frame = av_frame_alloc(); + if (!avctx->coded_frame) + return AVERROR(ENOMEM); + + avctx->coded_frame->key_frame = 1; + avctx->coded_frame->pict_type = AV_PICTURE_TYPE_I; + + return 0; +} + +static av_cold int targa_encode_close(AVCodecContext *avctx) +{ + av_frame_free(&avctx->coded_frame); + return 0; +} + AVCodec ff_targa_encoder = { .name = "targa", .long_name = NULL_IF_CONFIG_SMALL("Truevision Targa image"), .type = AVMEDIA_TYPE_VIDEO, .id = AV_CODEC_ID_TARGA, + .init = targa_encode_init, + .close = targa_encode_close, .encode2 = targa_encode_frame, .pix_fmts = (const enum AVPixelFormat[]){ AV_PIX_FMT_BGR24, AV_PIX_FMT_BGRA, AV_PIX_FMT_RGB555LE, AV_PIX_FMT_GRAY8, AV_PIX_FMT_PAL8, diff --git a/libavcodec/tiertexseqv.c b/libavcodec/tiertexseqv.c index 0da9afdaa3..7c62208dc5 100644 --- a/libavcodec/tiertexseqv.c +++ b/libavcodec/tiertexseqv.c @@ -32,7 +32,7 @@ typedef struct SeqVideoContext { AVCodecContext *avctx; - AVFrame frame; + AVFrame *frame; } SeqVideoContext; @@ -93,14 +93,14 @@ static const unsigned char *seq_decode_op1(SeqVideoContext *seq, src = seq_unpack_rle_block(src, src_end, block, sizeof(block)); for (b = 0; b < 8; b++) { memcpy(dst, &block[b * 8], 8); - dst += seq->frame.linesize[0]; + dst += seq->frame->linesize[0]; } break; case 2: src = seq_unpack_rle_block(src, src_end, block, sizeof(block)); for (i = 0; i < 8; i++) { for (b = 0; b < 8; b++) - dst[b * seq->frame.linesize[0]] = block[i * 8 + b]; + dst[b * seq->frame->linesize[0]] = block[i * 8 + b]; ++dst; } break; @@ -117,7 +117,7 @@ static const unsigned char *seq_decode_op1(SeqVideoContext *seq, for (b = 0; b < 8; b++) { for (i = 0; i < 8; i++) dst[i] = color_table[get_bits(&gb, bits)]; - dst += seq->frame.linesize[0]; + dst += seq->frame->linesize[0]; } } @@ -137,7 +137,7 @@ static const unsigned char *seq_decode_op2(SeqVideoContext *seq, for (i = 0; i < 8; i++) { memcpy(dst, src, 8); src += 8; - dst += seq->frame.linesize[0]; + dst += seq->frame->linesize[0]; } return src; @@ -154,7 +154,7 @@ static const unsigned char *seq_decode_op3(SeqVideoContext *seq, if (src_end - src < 2) return NULL; pos = *src++; - offset = ((pos >> 3) & 7) * seq->frame.linesize[0] + (pos & 7); + offset = ((pos >> 3) & 7) * seq->frame->linesize[0] + (pos & 7); dst[offset] = *src++; } while (!(pos & 0x80)); @@ -173,7 +173,7 @@ static int seqvideo_decode(SeqVideoContext *seq, const unsigned char *data, int flags = *data++; if (flags & 1) { - palette = (uint32_t *)seq->frame.data[1]; + palette = (uint32_t *)seq->frame->data[1]; if (data_end - data < 256 * 3) return AVERROR_INVALIDDATA; for (i = 0; i < 256; i++) { @@ -181,7 +181,7 @@ static int seqvideo_decode(SeqVideoContext *seq, const unsigned char *data, int c[j] = (*data << 2) | (*data >> 4); palette[i] = 0xFFU << 24 | AV_RB24(c); } - seq->frame.palette_has_changed = 1; + seq->frame->palette_has_changed = 1; } if (flags & 2) { @@ -190,7 +190,7 @@ static int seqvideo_decode(SeqVideoContext *seq, const unsigned char *data, int init_get_bits(&gb, data, 128 * 8); data += 128; for (y = 0; y < 128; y += 8) for (x = 0; x < 256; x += 8) { - dst = &seq->frame.data[0][y * seq->frame.linesize[0] + x]; + dst = &seq->frame->data[0][y * seq->frame->linesize[0] + x]; op = get_bits(&gb, 2); switch (op) { case 1: @@ -217,7 +217,9 @@ static av_cold int seqvideo_decode_init(AVCodecContext *avctx) seq->avctx = avctx; avctx->pix_fmt = AV_PIX_FMT_PAL8; - avcodec_get_frame_defaults(&seq->frame); + seq->frame = av_frame_alloc(); + if (!seq->frame) + return AVERROR(ENOMEM); return 0; } @@ -232,13 +234,13 @@ static int seqvideo_decode_frame(AVCodecContext *avctx, SeqVideoContext *seq = avctx->priv_data; - if ((ret = ff_reget_buffer(avctx, &seq->frame)) < 0) + if ((ret = ff_reget_buffer(avctx, seq->frame)) < 0) return ret; if (seqvideo_decode(seq, buf, buf_size)) return AVERROR_INVALIDDATA; - if ((ret = av_frame_ref(data, &seq->frame)) < 0) + if ((ret = av_frame_ref(data, seq->frame)) < 0) return ret; *got_frame = 1; @@ -249,7 +251,7 @@ static av_cold int seqvideo_decode_end(AVCodecContext *avctx) { SeqVideoContext *seq = avctx->priv_data; - av_frame_unref(&seq->frame); + av_frame_free(&seq->frame); return 0; } diff --git a/libavcodec/tiff.c b/libavcodec/tiff.c index 2b100ede5e..f3abfd950d 100644 --- a/libavcodec/tiff.c +++ b/libavcodec/tiff.c @@ -79,6 +79,7 @@ static void free_geotags(TiffContext *const s) av_freep(&s->geotags[i].val); } av_freep(&s->geotags); + s->geotag_count = 0; } #define RET_GEOKEY(TYPE, array, element)\ @@ -603,13 +604,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 { @@ -918,6 +919,13 @@ static int tiff_decode_tag(TiffContext *s, AVFrame *frame) } } end: + 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; + } bytestream2_seek(&s->gb, start, SEEK_SET); return 0; } diff --git a/libavcodec/tiff_common.c b/libavcodec/tiff_common.c index 6a10d71743..ce91219150 100644 --- a/libavcodec/tiff_common.c +++ b/libavcodec/tiff_common.c @@ -219,7 +219,7 @@ int ff_tadd_bytes_metadata(int count, const char *name, const char *sep, char *ap; int i; - if (count >= INT_MAX / sizeof(int8_t) || count <= 0) + if (count >= INT_MAX / sizeof(int8_t) || count < 0) return AVERROR_INVALIDDATA; if (bytestream2_get_bytes_left(gb) < count * sizeof(int8_t)) return AVERROR_INVALIDDATA; diff --git a/libavcodec/tiffenc.c b/libavcodec/tiffenc.c index f5d04eaf2b..7b1e5104bd 100644 --- a/libavcodec/tiffenc.c +++ b/libavcodec/tiffenc.c @@ -52,7 +52,6 @@ static const uint8_t type_sizes2[14] = { typedef struct TiffEncoderContext { AVClass *class; ///< for private options AVCodecContext *avctx; - AVFrame picture; int width; ///< picture width int height; ///< picture height @@ -195,9 +194,9 @@ static int encode_strip(TiffEncoderContext *s, const int8_t *src, } } -static void pack_yuv(TiffEncoderContext *s, uint8_t *dst, int lnum) +static void pack_yuv(TiffEncoderContext *s, const AVFrame *p, + uint8_t *dst, int lnum) { - AVFrame *p = &s->picture; int i, j, k; int w = (s->width - 1) / s->subsampling[0] + 1; uint8_t *pu = &p->data[1][lnum / s->subsampling[1] * p->linesize[1]]; @@ -223,24 +222,12 @@ static void pack_yuv(TiffEncoderContext *s, uint8_t *dst, int lnum) } } -static av_cold int encode_init(AVCodecContext *avctx) -{ - TiffEncoderContext *s = avctx->priv_data; - - avctx->coded_frame = &s->picture; - avctx->coded_frame->pict_type = AV_PICTURE_TYPE_I; - avctx->coded_frame->key_frame = 1; - s->avctx = avctx; - - return 0; -} - static int encode_frame(AVCodecContext *avctx, AVPacket *pkt, const AVFrame *pict, int *got_packet) { const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(avctx->pix_fmt); TiffEncoderContext *s = avctx->priv_data; - AVFrame *const p = &s->picture; + const AVFrame *const p = pict; int i; uint8_t *ptr; uint8_t *offset; @@ -252,8 +239,6 @@ static int encode_frame(AVCodecContext *avctx, AVPacket *pkt, int is_yuv = 0, alpha = 0; int shift_h, shift_v; - *p = *pict; - s->width = avctx->width; s->height = avctx->height; s->subsampling[0] = 1; @@ -373,7 +358,7 @@ static int encode_frame(AVCodecContext *avctx, AVPacket *pkt, zn = 0; for (j = 0; j < s->rps; j++) { if (is_yuv) { - pack_yuv(s, s->yuv_line, j); + pack_yuv(s, p, s->yuv_line, j); memcpy(zbuf + zn, s->yuv_line, bytes_per_row); j += s->subsampling[1] - 1; } else @@ -409,7 +394,7 @@ static int encode_frame(AVCodecContext *avctx, AVPacket *pkt, s->strip_offsets[i / s->rps] = ptr - pkt->data; } if (is_yuv) { - pack_yuv(s, s->yuv_line, i); + pack_yuv(s, p, s->yuv_line, i); ret = encode_strip(s, s->yuv_line, ptr, bytes_per_row, s->compr); i += s->subsampling[1] - 1; } else @@ -497,10 +482,26 @@ fail: return ret < 0 ? ret : 0; } +static av_cold int encode_init(AVCodecContext *avctx) +{ + TiffEncoderContext *s = avctx->priv_data; + + avctx->coded_frame = av_frame_alloc(); + if (!avctx->coded_frame) + return AVERROR(ENOMEM); + + avctx->coded_frame->pict_type = AV_PICTURE_TYPE_I; + avctx->coded_frame->key_frame = 1; + s->avctx = avctx; + + return 0; +} + static av_cold int encode_close(AVCodecContext *avctx) { TiffEncoderContext *s = avctx->priv_data; + av_frame_free(&avctx->coded_frame); av_freep(&s->strip_sizes); av_freep(&s->strip_offsets); av_freep(&s->yuv_line); @@ -536,8 +537,8 @@ AVCodec ff_tiff_encoder = { .id = AV_CODEC_ID_TIFF, .priv_data_size = sizeof(TiffEncoderContext), .init = encode_init, - .encode2 = encode_frame, .close = encode_close, + .encode2 = encode_frame, .pix_fmts = (const enum AVPixelFormat[]) { AV_PIX_FMT_RGB24, AV_PIX_FMT_PAL8, AV_PIX_FMT_GRAY8, AV_PIX_FMT_GRAY8A, AV_PIX_FMT_GRAY16LE, diff --git a/libavcodec/truemotion1.c b/libavcodec/truemotion1.c index d72cee8aea..db49080de2 100644 --- a/libavcodec/truemotion1.c +++ b/libavcodec/truemotion1.c @@ -44,7 +44,7 @@ typedef struct TrueMotion1Context { AVCodecContext *avctx; - AVFrame frame; + AVFrame *frame; const uint8_t *buf; int size; @@ -402,7 +402,7 @@ static int truemotion1_decode_header(TrueMotion1Context *s) if (s->w != s->avctx->width || s->h != s->avctx->height || new_pix_fmt != s->avctx->pix_fmt) { - av_frame_unref(&s->frame); + av_frame_unref(s->frame); s->avctx->sample_aspect_ratio = (AVRational){ 1 << width_shift, 1 }; s->avctx->pix_fmt = new_pix_fmt; avcodec_set_dimensions(s->avctx, s->w, s->h); @@ -470,7 +470,9 @@ static av_cold int truemotion1_decode_init(AVCodecContext *avctx) // else // avctx->pix_fmt = AV_PIX_FMT_RGB555; - avcodec_get_frame_defaults(&s->frame); + s->frame = av_frame_alloc(); + if (!s->frame) + return AVERROR(ENOMEM); /* there is a vertical predictor for each pixel in a line; each vertical * predictor is 0 to start with */ @@ -613,7 +615,7 @@ static void truemotion1_decode_16bit(TrueMotion1Context *s) unsigned int horiz_pred; unsigned int *vert_pred; unsigned int *current_pixel_pair; - unsigned char *current_line = s->frame.data[0]; + unsigned char *current_line = s->frame->data[0]; int keyframe = s->flags & FLAG_KEYFRAME; /* these variables are for managing the stream of macroblock change bits */ @@ -727,7 +729,7 @@ static void truemotion1_decode_16bit(TrueMotion1Context *s) if (((y + 1) & 3) == 0) mb_change_bits += s->mb_change_bits_row_size; - current_line += s->frame.linesize[0]; + current_line += s->frame->linesize[0]; } } @@ -739,7 +741,7 @@ static void truemotion1_decode_24bit(TrueMotion1Context *s) unsigned int horiz_pred; unsigned int *vert_pred; unsigned int *current_pixel_pair; - unsigned char *current_line = s->frame.data[0]; + unsigned char *current_line = s->frame->data[0]; int keyframe = s->flags & FLAG_KEYFRAME; /* these variables are for managing the stream of macroblock change bits */ @@ -853,7 +855,7 @@ static void truemotion1_decode_24bit(TrueMotion1Context *s) if (((y + 1) & 3) == 0) mb_change_bits += s->mb_change_bits_row_size; - current_line += s->frame.linesize[0]; + current_line += s->frame->linesize[0]; } } @@ -872,7 +874,7 @@ static int truemotion1_decode_frame(AVCodecContext *avctx, if ((ret = truemotion1_decode_header(s)) < 0) return ret; - if ((ret = ff_reget_buffer(avctx, &s->frame)) < 0) + if ((ret = ff_reget_buffer(avctx, s->frame)) < 0) return ret; if (compression_types[s->compression].algorithm == ALGO_RGB24H) { @@ -881,7 +883,7 @@ static int truemotion1_decode_frame(AVCodecContext *avctx, truemotion1_decode_16bit(s); } - if ((ret = av_frame_ref(data, &s->frame)) < 0) + if ((ret = av_frame_ref(data, s->frame)) < 0) return ret; *got_frame = 1; @@ -894,7 +896,7 @@ static av_cold int truemotion1_decode_end(AVCodecContext *avctx) { TrueMotion1Context *s = avctx->priv_data; - av_frame_unref(&s->frame); + av_frame_free(&s->frame); av_freep(&s->vert_pred); return 0; diff --git a/libavcodec/truemotion2.c b/libavcodec/truemotion2.c index 42badcbf8e..a1683f5b1a 100644 --- a/libavcodec/truemotion2.c +++ b/libavcodec/truemotion2.c @@ -931,6 +931,7 @@ static av_cold int decode_init(AVCodecContext *avctx) l->avctx = avctx; avctx->pix_fmt = AV_PIX_FMT_BGR24; + l->pic = av_frame_alloc(); if (!l->pic) return AVERROR(ENOMEM); diff --git a/libavcodec/ulti.c b/libavcodec/ulti.c index aee713fe1d..6b762148bb 100644 --- a/libavcodec/ulti.c +++ b/libavcodec/ulti.c @@ -37,7 +37,7 @@ typedef struct UltimotionDecodeContext { AVCodecContext *avctx; int width, height, blocks; - AVFrame frame; + AVFrame *frame; const uint8_t *ulti_codebook; GetByteContext gb; } UltimotionDecodeContext; @@ -51,19 +51,19 @@ static av_cold int ulti_decode_init(AVCodecContext *avctx) s->height = avctx->height; s->blocks = (s->width / 8) * (s->height / 8); avctx->pix_fmt = AV_PIX_FMT_YUV410P; - avctx->coded_frame = &s->frame; - avctx->coded_frame = (AVFrame*) &s->frame; s->ulti_codebook = ulti_codebook; - avcodec_get_frame_defaults(&s->frame); + + s->frame = av_frame_alloc(); + if (!s->frame) + return AVERROR(ENOMEM); return 0; } static av_cold int ulti_decode_end(AVCodecContext *avctx){ UltimotionDecodeContext *s = avctx->priv_data; - AVFrame *pic = &s->frame; - av_frame_unref(pic); + av_frame_free(&s->frame); return 0; } @@ -227,7 +227,7 @@ static int ulti_decode_frame(AVCodecContext *avctx, int skip; int tmp; - if ((ret = ff_reget_buffer(avctx, &s->frame)) < 0) + if ((ret = ff_reget_buffer(avctx, s->frame)) < 0) return ret; bytestream2_init(&s->gb, buf, buf_size); @@ -368,7 +368,7 @@ static int ulti_decode_frame(AVCodecContext *avctx, Luma[14] = (tmp >> 6) & 0x3F; Luma[15] = tmp & 0x3F; - ulti_convert_yuv(&s->frame, tx, ty, Luma, chroma); + ulti_convert_yuv(s->frame, tx, ty, Luma, chroma); } else { if (bytestream2_get_bytes_left(&s->gb) < 4) goto err; @@ -380,20 +380,20 @@ static int ulti_decode_frame(AVCodecContext *avctx, Y[1] = tmp & 0x3F; Y[2] = bytestream2_get_byteu(&s->gb) & 0x3F; Y[3] = bytestream2_get_byteu(&s->gb) & 0x3F; - ulti_grad(&s->frame, tx, ty, Y, chroma, angle); //draw block + ulti_grad(s->frame, tx, ty, Y, chroma, angle); //draw block } else { // some patterns int f0, f1; f0 = bytestream2_get_byteu(&s->gb); f1 = tmp; Y[0] = bytestream2_get_byteu(&s->gb) & 0x3F; Y[1] = bytestream2_get_byteu(&s->gb) & 0x3F; - ulti_pattern(&s->frame, tx, ty, f1, f0, Y[0], Y[1], chroma); + ulti_pattern(s->frame, tx, ty, f1, f0, Y[0], Y[1], chroma); } } break; } if(code != 3) - ulti_grad(&s->frame, tx, ty, Y, chroma, angle); // draw block + ulti_grad(s->frame, tx, ty, Y, chroma, angle); // draw block } blocks++; x += 8; @@ -405,7 +405,7 @@ static int ulti_decode_frame(AVCodecContext *avctx, } *got_frame = 1; - if ((ret = av_frame_ref(data, &s->frame)) < 0) + if ((ret = av_frame_ref(data, s->frame)) < 0) return ret; return buf_size; diff --git a/libavcodec/utils.c b/libavcodec/utils.c index 186993dc02..922bd7aa8d 100644 --- a/libavcodec/utils.c +++ b/libavcodec/utils.c @@ -218,7 +218,8 @@ av_cold void avcodec_register(AVCodec *codec) avcodec_init(); p = &first_avcodec; codec->next = NULL; - while(avpriv_atomic_ptr_cas((void * volatile *)p, NULL, codec)) + + while(*p || avpriv_atomic_ptr_cas((void * volatile *)p, NULL, codec)) p = &(*p)->next; if (codec->init_static_data) @@ -250,6 +251,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: @@ -326,6 +333,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; @@ -333,7 +342,7 @@ void avcodec_align_dimensions2(AVCodecContext *s, int *width, int *height, case AV_PIX_FMT_YUVJ411P: case AV_PIX_FMT_UYYVYY411: w_align = 32; - h_align = 8; + h_align = 16 * 2; break; case AV_PIX_FMT_YUV410P: if (s->codec_id == AV_CODEC_ID_SVQ1) { @@ -355,6 +364,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) || @@ -370,8 +383,6 @@ void avcodec_align_dimensions2(AVCodecContext *s, int *width, int *height, } break; default: - w_align = 1; - h_align = 1; break; } @@ -732,8 +743,7 @@ int ff_init_buffer_info(AVCodecContext *avctx, AVFrame *frame) case AVMEDIA_TYPE_VIDEO: frame->width = FFMAX(avctx->width, FF_CEIL_RSHIFT(avctx->coded_width, avctx->lowres)); frame->height = FFMAX(avctx->height, FF_CEIL_RSHIFT(avctx->coded_height, avctx->lowres)); - if (frame->format < 0) - frame->format = avctx->pix_fmt; + frame->format = avctx->pix_fmt; if (!frame->sample_aspect_ratio.num) frame->sample_aspect_ratio = avctx->sample_aspect_ratio; if (av_frame_get_colorspace(frame) == AVCOL_SPC_UNSPECIFIED) @@ -780,6 +790,7 @@ int avcodec_default_get_buffer(AVCodecContext *avctx, AVFrame *frame) typedef struct CompatReleaseBufPriv { AVCodecContext avctx; AVFrame frame; + uint8_t avframe_padding[1024]; // hack to allow linking to a avutil with larger AVFrame } CompatReleaseBufPriv; static void compat_free_buffer(void *opaque, uint8_t *data) @@ -1070,15 +1081,7 @@ void avcodec_get_frame_defaults(AVFrame *frame) AVFrame *avcodec_alloc_frame(void) { - AVFrame *frame = av_malloc(sizeof(AVFrame)); - - if (frame == NULL) - return NULL; - - frame->extended_data = NULL; - avcodec_get_frame_defaults(frame); - - return frame; + return av_frame_alloc(); } void avcodec_free_frame(AVFrame **frame) @@ -1599,7 +1602,7 @@ int attribute_align_arg avcodec_encode_audio2(AVCodecContext *avctx, const AVFrame *frame, int *got_packet_ptr) { - AVFrame tmp; + AVFrame *extended_frame = NULL; AVFrame *padded_frame = NULL; int ret; AVPacket user_pkt = *avpkt; @@ -1624,9 +1627,13 @@ int attribute_align_arg avcodec_encode_audio2(AVCodecContext *avctx, } av_log(avctx, AV_LOG_WARNING, "extended_data is not set.\n"); - tmp = *frame; - tmp.extended_data = tmp.data; - frame = &tmp; + extended_frame = av_frame_alloc(); + if (!extended_frame) + return AVERROR(ENOMEM); + + memcpy(extended_frame, frame, sizeof(AVFrame)); + extended_frame->extended_data = extended_frame->data; + frame = extended_frame; } /* check for valid frame size */ @@ -1634,14 +1641,15 @@ int attribute_align_arg avcodec_encode_audio2(AVCodecContext *avctx, if (avctx->codec->capabilities & CODEC_CAP_SMALL_LAST_FRAME) { if (frame->nb_samples > avctx->frame_size) { av_log(avctx, AV_LOG_ERROR, "more samples than frame size (avcodec_encode_audio2)\n"); - return AVERROR(EINVAL); + ret = AVERROR(EINVAL); + goto end; } } else if (!(avctx->codec->capabilities & CODEC_CAP_VARIABLE_FRAME_SIZE)) { if (frame->nb_samples < avctx->frame_size && !avctx->internal->last_audio_frame) { ret = pad_last_frame(avctx, &padded_frame, frame); if (ret < 0) - return ret; + goto end; frame = padded_frame; avctx->internal->last_audio_frame = 1; @@ -1713,6 +1721,7 @@ int attribute_align_arg avcodec_encode_audio2(AVCodecContext *avctx, end: av_frame_free(&padded_frame); + av_free(extended_frame); return ret; } @@ -1723,7 +1732,6 @@ int attribute_align_arg avcodec_encode_audio(AVCodecContext *avctx, const short *samples) { AVPacket pkt; - AVFrame frame0 = { { 0 } }; AVFrame *frame; int ret, samples_size, got_packet; @@ -1732,8 +1740,9 @@ int attribute_align_arg avcodec_encode_audio(AVCodecContext *avctx, pkt.size = buf_size; if (samples) { - frame = &frame0; - avcodec_get_frame_defaults(frame); + frame = av_frame_alloc(); + if (!frame) + return AVERROR(ENOMEM); if (avctx->frame_size) { frame->nb_samples = avctx->frame_size; @@ -1744,13 +1753,16 @@ int attribute_align_arg avcodec_encode_audio(AVCodecContext *avctx, if (!av_get_bits_per_sample(avctx->codec_id)) { av_log(avctx, AV_LOG_ERROR, "avcodec_encode_audio() does not " "support this codec\n"); + av_frame_free(&frame); return AVERROR(EINVAL); } nb_samples = (int64_t)buf_size * 8 / (av_get_bits_per_sample(avctx->codec_id) * avctx->channels); - if (nb_samples >= INT_MAX) + if (nb_samples >= INT_MAX) { + av_frame_free(&frame); return AVERROR(EINVAL); + } frame->nb_samples = nb_samples; } @@ -1762,8 +1774,10 @@ int attribute_align_arg avcodec_encode_audio(AVCodecContext *avctx, if ((ret = avcodec_fill_audio_frame(frame, avctx->channels, avctx->sample_fmt, (const uint8_t *)samples, - samples_size, 1)) < 0) + samples_size, 1)) < 0) { + av_frame_free(&frame); return ret; + } /* fabricate frame pts from sample count. * this is needed because the avcodec_encode_audio() API does not have @@ -1790,6 +1804,7 @@ int attribute_align_arg avcodec_encode_audio(AVCodecContext *avctx, if (frame && frame->extended_data != frame->data) av_freep(&frame->extended_data); + av_frame_free(&frame); return ret ? ret : pkt.size; } @@ -2117,9 +2132,11 @@ int attribute_align_arg avcodec_decode_audio3(AVCodecContext *avctx, int16_t *sa int *frame_size_ptr, AVPacket *avpkt) { - AVFrame frame = { { 0 } }; + AVFrame *frame = av_frame_alloc(); int ret, got_frame = 0; + if (!frame) + return AVERROR(ENOMEM); if (avctx->get_buffer != avcodec_default_get_buffer) { av_log(avctx, AV_LOG_ERROR, "Custom get_buffer() for use with" "avcodec_decode_audio3() detected. Overriding with avcodec_default_get_buffer\n"); @@ -2129,26 +2146,27 @@ int attribute_align_arg avcodec_decode_audio3(AVCodecContext *avctx, int16_t *sa avctx->release_buffer = avcodec_default_release_buffer; } - ret = avcodec_decode_audio4(avctx, &frame, &got_frame, avpkt); + ret = avcodec_decode_audio4(avctx, frame, &got_frame, avpkt); if (ret >= 0 && got_frame) { int ch, plane_size; int planar = av_sample_fmt_is_planar(avctx->sample_fmt); int data_size = av_samples_get_buffer_size(&plane_size, avctx->channels, - frame.nb_samples, + frame->nb_samples, avctx->sample_fmt, 1); if (*frame_size_ptr < data_size) { av_log(avctx, AV_LOG_ERROR, "output buffer size is too small for " "the current frame (%d < %d)\n", *frame_size_ptr, data_size); + av_frame_free(&frame); return AVERROR(EINVAL); } - memcpy(samples, frame.extended_data[0], plane_size); + memcpy(samples, frame->extended_data[0], plane_size); if (planar && avctx->channels > 1) { uint8_t *out = ((uint8_t *)samples) + plane_size; for (ch = 1; ch < avctx->channels; ch++) { - memcpy(out, frame.extended_data[ch], plane_size); + memcpy(out, frame->extended_data[ch], plane_size); out += plane_size; } } @@ -2156,6 +2174,7 @@ int attribute_align_arg avcodec_decode_audio3(AVCodecContext *avctx, int16_t *sa } else { *frame_size_ptr = 0; } + av_frame_free(&frame); return ret; } @@ -2413,6 +2432,16 @@ int avcodec_decode_subtitle2(AVCodecContext *avctx, AVSubtitle *sub, int did_split = av_packet_split_side_data(&tmp); //apply_param_change(avctx, &tmp); + if (did_split) { + /* FFMIN() prevents overflow in case the packet wasn't allocated with + * proper padding. + * If the side data is smaller than the buffer padding size, the + * remaining bytes should have already been filled with zeros by the + * original packet allocation anyway. */ + memset(tmp.data + tmp.size, 0, + FFMIN(avpkt->size - tmp.size, FF_INPUT_BUFFER_PADDING_SIZE)); + } + pkt_recoded = tmp; ret = recode_subtitle(avctx, &pkt_recoded, &tmp); if (ret < 0) { @@ -3172,7 +3201,7 @@ void av_register_hwaccel(AVHWAccel *hwaccel) { AVHWAccel **p = &first_hwaccel; hwaccel->next = NULL; - while(avpriv_atomic_ptr_cas((void * volatile *)p, NULL, hwaccel)) + while(*p || avpriv_atomic_ptr_cas((void * volatile *)p, NULL, hwaccel)) p = &(*p)->next; } @@ -3376,6 +3405,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 e3ef22d2a2..05db9623cf 100644 --- a/libavcodec/utvideodec.c +++ b/libavcodec/utvideodec.c @@ -70,7 +70,7 @@ static int build_huff(const uint8_t *src, VLC *vlc, int *fsym) code += 0x80000000u >> (he[i].len - 1); } - return ff_init_vlc_sparse(vlc, FFMIN(he[last].len, 10), last + 1, + return ff_init_vlc_sparse(vlc, FFMIN(he[last].len, 11), last + 1, bits, sizeof(*bits), sizeof(*bits), codes, sizeof(*codes), sizeof(*codes), syms, sizeof(*syms), sizeof(*syms), 0); @@ -212,6 +212,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 @@ -222,7 +224,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]; @@ -267,6 +269,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; @@ -282,7 +286,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 c4885a59b1..b165b37629 100644 --- a/libavcodec/utvideoenc.c +++ b/libavcodec/utvideoenc.c @@ -351,7 +351,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; @@ -361,6 +361,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; @@ -369,7 +370,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); @@ -378,7 +379,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); } @@ -386,7 +387,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); } @@ -449,14 +450,14 @@ 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, * get the offset in bits and convert to bytes. */ offset += write_huff_codes(dst + sstart * width, c->slice_bits, - width * (send - sstart), width, + width * height + 4, width, send - sstart, he) >> 3; slice_len = offset - slice_len; @@ -513,8 +514,7 @@ static int utvideo_encode_frame(AVCodecContext *avctx, AVPacket *pkt, bytestream2_init_writer(&pb, dst, pkt->size); - av_fast_malloc(&c->slice_bits, &c->slice_bits_size, - width * height + FF_INPUT_BUFFER_PADDING_SIZE); + av_fast_padded_malloc(&c->slice_bits, &c->slice_bits_size, width * height + 4); if (!c->slice_bits) { av_log(avctx, AV_LOG_ERROR, "Cannot allocate temporary buffer 2.\n"); @@ -532,7 +532,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) { @@ -544,7 +544,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); @@ -555,7 +555,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/vc1.c b/libavcodec/vc1.c index f7558116d1..b9a6fdfb52 100644 --- a/libavcodec/vc1.c +++ b/libavcodec/vc1.c @@ -621,12 +621,30 @@ static void rotate_luts(VC1Context *v) INIT_LUT(32, 0, v->curr_luty[0], v->curr_lutuv[0], 0); INIT_LUT(32, 0, v->curr_luty[1], v->curr_lutuv[1], 0); v->curr_use_ic = 0; + if (v->curr_luty == v->next_luty) { + // If we just initialized next_lut, clear next_use_ic to match. + v->next_use_ic = 0; + } +} + +static int read_bfraction(VC1Context *v, GetBitContext* gb) { + int bfraction_lut_index = get_vlc2(gb, ff_vc1_bfraction_vlc.table, VC1_BFRACTION_VLC_BITS, 1); + + if (bfraction_lut_index == 21 || bfraction_lut_index < 0) { + av_log(v->s.avctx, AV_LOG_ERROR, "bfraction invalid\n"); + return AVERROR_INVALIDDATA; + } + v->bfraction_lut_index = bfraction_lut_index; + v->bfraction = ff_vc1_bfraction_lut[v->bfraction_lut_index]; + return 0; } int ff_vc1_parse_frame_header(VC1Context *v, GetBitContext* gb) { int pqindex, lowquant, status; + v->field_mode = 0; + v->fcm = 0; if (v->finterpflag) v->interpfrm = get_bits1(gb); if (!v->s.avctx->codec) @@ -654,8 +672,8 @@ int ff_vc1_parse_frame_header(VC1Context *v, GetBitContext* gb) v->bi_type = 0; if (v->s.pict_type == AV_PICTURE_TYPE_B) { - v->bfraction_lut_index = get_vlc2(gb, ff_vc1_bfraction_vlc.table, VC1_BFRACTION_VLC_BITS, 1); - v->bfraction = ff_vc1_bfraction_lut[v->bfraction_lut_index]; + if (read_bfraction(v, gb) < 0) + return AVERROR_INVALIDDATA; if (v->bfraction == 0) { v->s.pict_type = AV_PICTURE_TYPE_BI; } @@ -933,8 +951,8 @@ int ff_vc1_parse_frame_header_adv(VC1Context *v, GetBitContext* gb) v->refdist += get_unary(gb, 0, 16); } if ((v->s.pict_type == AV_PICTURE_TYPE_B) || (v->s.pict_type == AV_PICTURE_TYPE_BI)) { - v->bfraction_lut_index = get_vlc2(gb, ff_vc1_bfraction_vlc.table, VC1_BFRACTION_VLC_BITS, 1); - v->bfraction = ff_vc1_bfraction_lut[v->bfraction_lut_index]; + if (read_bfraction(v, gb) < 0) + return AVERROR_INVALIDDATA; v->frfd = (v->bfraction * v->refdist) >> 8; v->brfd = v->refdist - v->frfd - 1; if (v->brfd < 0) @@ -946,8 +964,8 @@ int ff_vc1_parse_frame_header_adv(VC1Context *v, GetBitContext* gb) if (v->finterpflag) v->interpfrm = get_bits1(gb); if (v->s.pict_type == AV_PICTURE_TYPE_B) { - v->bfraction_lut_index = get_vlc2(gb, ff_vc1_bfraction_vlc.table, VC1_BFRACTION_VLC_BITS, 1); - v->bfraction = ff_vc1_bfraction_lut[v->bfraction_lut_index]; + if (read_bfraction(v, gb) < 0) + return AVERROR_INVALIDDATA; if (v->bfraction == 0) { v->s.pict_type = AV_PICTURE_TYPE_BI; /* XXX: should not happen here */ } @@ -1191,8 +1209,8 @@ int ff_vc1_parse_frame_header_adv(VC1Context *v, GetBitContext* gb) break; case AV_PICTURE_TYPE_B: if (v->fcm == ILACE_FRAME) { - v->bfraction_lut_index = get_vlc2(gb, ff_vc1_bfraction_vlc.table, VC1_BFRACTION_VLC_BITS, 1); - v->bfraction = ff_vc1_bfraction_lut[v->bfraction_lut_index]; + if (read_bfraction(v, gb) < 0) + return AVERROR_INVALIDDATA; if (v->bfraction == 0) { return -1; } diff --git a/libavcodec/vc1.h b/libavcodec/vc1.h index c77ab7ce09..df69c77a4d 100644 --- a/libavcodec/vc1.h +++ b/libavcodec/vc1.h @@ -378,7 +378,7 @@ typedef struct VC1Context{ //@{ int new_sprite; int two_sprites; - AVFrame sprite_output_frame; + AVFrame *sprite_output_frame; int output_width, output_height, sprite_width, sprite_height; uint8_t* sr_rows[2][2]; ///< Sprite resizer line cache //@} diff --git a/libavcodec/vc1dec.c b/libavcodec/vc1dec.c index 682a9d2000..d87b89cf3f 100644 --- a/libavcodec/vc1dec.c +++ b/libavcodec/vc1dec.c @@ -1917,9 +1917,10 @@ static void vc1_interp_mc(VC1Context *v) uvmx = (mx + ((mx & 3) == 3)) >> 1; uvmy = (my + ((my & 3) == 3)) >> 1; if (v->field_mode) { - if (v->cur_field_type != v->ref_field_type[1]) + if (v->cur_field_type != v->ref_field_type[1]) { my = my - 2 + 4 * v->cur_field_type; uvmy = uvmy - 2 + 4 * v->cur_field_type; + } } if (v->fastuvmc) { uvmx = uvmx + ((uvmx < 0) ? -(uvmx & 1) : (uvmx & 1)); @@ -4342,6 +4343,10 @@ static void vc1_decode_b_mb_intfi(VC1Context *v) if (bmvtype == BMV_TYPE_DIRECT) { dmv_x[0] = dmv_y[0] = pred_flag[0] = 0; dmv_x[1] = dmv_y[1] = pred_flag[0] = 0; + if (!s->next_picture_ptr->field_picture) { + av_log(s->avctx, AV_LOG_ERROR, "Mixed field/frame direct mode not supported\n"); + return; + } } vc1_pred_b_mv_intfi(v, 0, dmv_x, dmv_y, 1, pred_flag); vc1_b_mc(v, dmv_x, dmv_y, (bmvtype == BMV_TYPE_DIRECT), bmvtype); @@ -5365,8 +5370,8 @@ static void vc1_draw_sprites(VC1Context *v, SpriteData* sd) int width = v->output_width>>!!plane; for (row = 0; row < v->output_height>>!!plane; row++) { - uint8_t *dst = v->sprite_output_frame.data[plane] + - v->sprite_output_frame.linesize[plane] * row; + uint8_t *dst = v->sprite_output_frame->data[plane] + + v->sprite_output_frame->linesize[plane] * row; for (sprite = 0; sprite <= v->two_sprites; sprite++) { uint8_t *iplane = s->current_picture.f.data[plane]; @@ -5457,8 +5462,8 @@ static int vc1_decode_sprites(VC1Context *v, GetBitContext* gb) v->two_sprites = 0; } - av_frame_unref(&v->sprite_output_frame); - if ((ret = ff_get_buffer(avctx, &v->sprite_output_frame, 0)) < 0) + av_frame_unref(v->sprite_output_frame); + if ((ret = ff_get_buffer(avctx, v->sprite_output_frame, 0)) < 0) return ret; vc1_draw_sprites(v, &sd); @@ -5685,6 +5690,10 @@ static av_cold int vc1_decode_init(AVCodecContext *avctx) v->res_sprite = (avctx->codec_id == AV_CODEC_ID_VC1IMAGE); } + v->sprite_output_frame = av_frame_alloc(); + if (!v->sprite_output_frame) + return AVERROR(ENOMEM); + avctx->profile = v->profile; if (v->profile == PROFILE_ADVANCED) avctx->level = v->level; @@ -5731,7 +5740,7 @@ av_cold int ff_vc1_decode_end(AVCodecContext *avctx) VC1Context *v = avctx->priv_data; int i; - av_frame_unref(&v->sprite_output_frame); + av_frame_free(&v->sprite_output_frame); for (i = 0; i < 4; i++) av_freep(&v->sr_rows[i >> 1][i & 1]); @@ -6005,7 +6014,7 @@ static int vc1_decode_frame(AVCodecContext *avctx, void *data, /* skip B-frames if we don't have reference frames */ if (s->last_picture_ptr == NULL && (s->pict_type == AV_PICTURE_TYPE_B || s->droppable)) { - goto err; + goto end; } if ((avctx->skip_frame >= AVDISCARD_NONREF && s->pict_type == AV_PICTURE_TYPE_B) || (avctx->skip_frame >= AVDISCARD_NONKEY && s->pict_type != AV_PICTURE_TYPE_I) || @@ -6024,6 +6033,7 @@ static int vc1_decode_frame(AVCodecContext *avctx, void *data, goto err; } + v->s.current_picture_ptr->field_picture = v->field_mode; v->s.current_picture_ptr->f.interlaced_frame = (v->fcm != PROGRESSIVE); v->s.current_picture_ptr->f.top_field_first = v->tff; @@ -6186,7 +6196,7 @@ image: if (vc1_decode_sprites(v, &s->gb)) goto err; #endif - if ((ret = av_frame_ref(pict, &v->sprite_output_frame)) < 0) + if ((ret = av_frame_ref(pict, v->sprite_output_frame)) < 0) goto err; *got_frame = 1; } else { diff --git a/libavcodec/vdpau.c b/libavcodec/vdpau.c index 7a4d1458a9..3a6684148e 100644 --- a/libavcodec/vdpau.c +++ b/libavcodec/vdpau.c @@ -69,6 +69,15 @@ int ff_vdpau_mpeg_end_frame(AVCodecContext *avctx) struct vdpau_picture_context *pic_ctx = pic->hwaccel_picture_private; VdpVideoSurface surf = ff_vdpau_get_surface_id(pic); +#if FF_API_BUFS_VDPAU +FF_DISABLE_DEPRECATION_WARNINGS + hwctx->info = pic_ctx->info; + hwctx->bitstream_buffers = pic_ctx->bitstream_buffers; + hwctx->bitstream_buffers_used = pic_ctx->bitstream_buffers_used; + hwctx->bitstream_buffers_allocated = pic_ctx->bitstream_buffers_allocated; +FF_ENABLE_DEPRECATION_WARNINGS +#endif + if (!hwctx->render) { res = hwctx->render2(avctx, &pic->f, (void *)&pic_ctx->info, pic_ctx->bitstream_buffers_used, pic_ctx->bitstream_buffers); @@ -79,6 +88,14 @@ int ff_vdpau_mpeg_end_frame(AVCodecContext *avctx) ff_mpeg_draw_horiz_band(s, 0, s->avctx->height); av_freep(&pic_ctx->bitstream_buffers); +#if FF_API_BUFS_VDPAU +FF_DISABLE_DEPRECATION_WARNINGS + hwctx->bitstream_buffers = NULL; + hwctx->bitstream_buffers_used = 0; + hwctx->bitstream_buffers_allocated = 0; +FF_ENABLE_DEPRECATION_WARNINGS +#endif + return res; } #endif diff --git a/libavcodec/vdpau_h264.c b/libavcodec/vdpau_h264.c index 3f6415d4f8..ea69c147f1 100644 --- a/libavcodec/vdpau_h264.c +++ b/libavcodec/vdpau_h264.c @@ -195,6 +195,15 @@ static int vdpau_h264_end_frame(AVCodecContext *avctx) struct vdpau_picture_context *pic_ctx = pic->hwaccel_picture_private; VdpVideoSurface surf = ff_vdpau_get_surface_id(pic); +#if FF_API_BUFS_VDPAU +FF_DISABLE_DEPRECATION_WARNINGS + hwctx->info = pic_ctx->info; + hwctx->bitstream_buffers = pic_ctx->bitstream_buffers; + hwctx->bitstream_buffers_used = pic_ctx->bitstream_buffers_used; + hwctx->bitstream_buffers_allocated = pic_ctx->bitstream_buffers_allocated; +FF_ENABLE_DEPRECATION_WARNINGS +#endif + if (!hwctx->render) { res = hwctx->render2(avctx, &pic->f, (void *)&pic_ctx->info, pic_ctx->bitstream_buffers_used, pic_ctx->bitstream_buffers); @@ -205,6 +214,14 @@ static int vdpau_h264_end_frame(AVCodecContext *avctx) ff_h264_draw_horiz_band(h, 0, h->avctx->height); av_freep(&pic_ctx->bitstream_buffers); +#if FF_API_BUFS_VDPAU +FF_DISABLE_DEPRECATION_WARNINGS + hwctx->bitstream_buffers = NULL; + hwctx->bitstream_buffers_used = 0; + hwctx->bitstream_buffers_allocated = 0; +FF_ENABLE_DEPRECATION_WARNINGS +#endif + return res; } diff --git a/libavcodec/version.h b/libavcodec/version.h index 75283627f8..63f6346ab3 100644 --- a/libavcodec/version.h +++ b/libavcodec/version.h @@ -30,7 +30,7 @@ #define LIBAVCODEC_VERSION_MAJOR 55 #define LIBAVCODEC_VERSION_MINOR 39 -#define LIBAVCODEC_VERSION_MICRO 100 +#define LIBAVCODEC_VERSION_MICRO 101 #define LIBAVCODEC_VERSION_INT AV_VERSION_INT(LIBAVCODEC_VERSION_MAJOR, \ LIBAVCODEC_VERSION_MINOR, \ diff --git a/libavcodec/vmdav.c b/libavcodec/vmdav.c index ea0e8428d2..8710f333d3 100644 --- a/libavcodec/vmdav.c +++ b/libavcodec/vmdav.c @@ -61,7 +61,7 @@ typedef struct VmdVideoContext { AVCodecContext *avctx; - AVFrame prev_frame; + AVFrame *prev_frame; const unsigned char *buf; int size; @@ -244,11 +244,11 @@ static int vmd_decode(VmdVideoContext *s, AVFrame *frame) /* if only a certain region will be updated, copy the entire previous * frame before the decode */ - if (s->prev_frame.data[0] && + if (s->prev_frame->data[0] && (frame_x || frame_y || (frame_width != s->avctx->width) || (frame_height != s->avctx->height))) { - memcpy(frame->data[0], s->prev_frame.data[0], + memcpy(frame->data[0], s->prev_frame->data[0], s->avctx->height * frame->linesize[0]); } @@ -291,7 +291,7 @@ static int vmd_decode(VmdVideoContext *s, AVFrame *frame) } dp = &frame->data[0][frame_y * frame->linesize[0] + frame_x]; - pp = &s->prev_frame.data[0][frame_y * s->prev_frame.linesize[0] + frame_x]; + pp = &s->prev_frame->data[0][frame_y * s->prev_frame->linesize[0] + frame_x]; switch (meth) { case 1: for (i = 0; i < frame_height; i++) { @@ -307,7 +307,7 @@ static int vmd_decode(VmdVideoContext *s, AVFrame *frame) ofs += len; } else { /* interframe pixel copy */ - if (ofs + len + 1 > frame_width || !s->prev_frame.data[0]) + if (ofs + len + 1 > frame_width || !s->prev_frame->data[0]) return AVERROR_INVALIDDATA; memcpy(&dp[ofs], &pp[ofs], len + 1); ofs += len + 1; @@ -320,7 +320,7 @@ static int vmd_decode(VmdVideoContext *s, AVFrame *frame) return AVERROR_INVALIDDATA; } dp += frame->linesize[0]; - pp += s->prev_frame.linesize[0]; + pp += s->prev_frame->linesize[0]; } break; @@ -328,7 +328,7 @@ static int vmd_decode(VmdVideoContext *s, AVFrame *frame) for (i = 0; i < frame_height; i++) { bytestream2_get_buffer(&gb, dp, frame_width); dp += frame->linesize[0]; - pp += s->prev_frame.linesize[0]; + pp += s->prev_frame->linesize[0]; } break; @@ -348,12 +348,15 @@ 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; } } else { /* interframe pixel copy */ - if (ofs + len + 1 > frame_width || !s->prev_frame.data[0]) + if (ofs + len + 1 > frame_width || !s->prev_frame->data[0]) return AVERROR_INVALIDDATA; memcpy(&dp[ofs], &pp[ofs], len + 1); ofs += len + 1; @@ -366,13 +369,23 @@ static int vmd_decode(VmdVideoContext *s, AVFrame *frame) return AVERROR_INVALIDDATA; } dp += frame->linesize[0]; - pp += s->prev_frame.linesize[0]; + pp += s->prev_frame->linesize[0]; } break; } return 0; } +static av_cold int vmdvideo_decode_end(AVCodecContext *avctx) +{ + VmdVideoContext *s = avctx->priv_data; + + av_frame_free(&s->prev_frame); + av_freep(&s->unpack_buffer); + + return 0; +} + static av_cold int vmdvideo_decode_init(AVCodecContext *avctx) { VmdVideoContext *s = avctx->priv_data; @@ -412,7 +425,11 @@ static av_cold int vmdvideo_decode_init(AVCodecContext *avctx) palette32[i] |= palette32[i] >> 6 & 0x30303; } - avcodec_get_frame_defaults(&s->prev_frame); + s->prev_frame = av_frame_alloc(); + if (!s->prev_frame) { + vmdvideo_decode_end(avctx); + return AVERROR(ENOMEM); + } return 0; } @@ -443,8 +460,8 @@ static int vmdvideo_decode_frame(AVCodecContext *avctx, memcpy(frame->data[1], s->palette, PALETTE_COUNT * 4); /* shuffle frames */ - av_frame_unref(&s->prev_frame); - if ((ret = av_frame_ref(&s->prev_frame, frame)) < 0) + av_frame_unref(s->prev_frame); + if ((ret = av_frame_ref(s->prev_frame, frame)) < 0) return ret; *got_frame = 1; @@ -453,17 +470,6 @@ static int vmdvideo_decode_frame(AVCodecContext *avctx, return buf_size; } -static av_cold int vmdvideo_decode_end(AVCodecContext *avctx) -{ - VmdVideoContext *s = avctx->priv_data; - - av_frame_unref(&s->prev_frame); - av_free(s->unpack_buffer); - - return 0; -} - - /* * Audio Decoder */ diff --git a/libavcodec/vmnc.c b/libavcodec/vmnc.c index c1b6d4e85d..46bd52ee26 100644 --- a/libavcodec/vmnc.c +++ b/libavcodec/vmnc.c @@ -57,7 +57,7 @@ enum HexTile_Flags { */ typedef struct VmncContext { AVCodecContext *avctx; - AVFrame *frame; + AVFrame *pic; int bpp; int bpp2; @@ -291,6 +291,11 @@ static int decode_hextile(VmncContext *c, uint8_t* dst, GetByteContext *gb, fg = vmnc_get_pixel(gb, bpp, c->bigendian); xy = bytestream2_get_byte(gb); wh = bytestream2_get_byte(gb); + if ( (xy >> 4) + (wh >> 4) + 1 > w - i + || (xy & 0xF) + (wh & 0xF)+1 > h - j) { + av_log(c->avctx, AV_LOG_ERROR, "Rectangle outside picture\n"); + return AVERROR_INVALIDDATA; + } paint_rect(dst2, xy >> 4, xy & 0xF, (wh>>4)+1, (wh & 0xF)+1, fg, bpp, stride); } @@ -320,15 +325,14 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame, GetByteContext *gb = &c->gb; uint8_t *outptr; int dx, dy, w, h, depth, enc, chunks, res, size_left, ret; - AVFrame *frame = c->frame; - if ((ret = ff_reget_buffer(avctx, frame)) < 0) + if ((ret = ff_reget_buffer(avctx, c->pic)) < 0) return ret; bytestream2_init(gb, buf, buf_size); - frame->key_frame = 0; - frame->pict_type = AV_PICTURE_TYPE_P; + c->pic->key_frame = 0; + c->pic->pict_type = AV_PICTURE_TYPE_P; // restore screen after cursor if (c->screendta) { @@ -350,11 +354,11 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame, dy = 0; } if ((w > 0) && (h > 0)) { - outptr = frame->data[0] + dx * c->bpp2 + dy * frame->linesize[0]; + outptr = c->pic->data[0] + dx * c->bpp2 + dy * c->pic->linesize[0]; for (i = 0; i < h; i++) { memcpy(outptr, c->screendta + i * c->cur_w * c->bpp2, w * c->bpp2); - outptr += frame->linesize[0]; + outptr += c->pic->linesize[0]; } } } @@ -370,7 +374,7 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame, w = bytestream2_get_be16(gb); h = bytestream2_get_be16(gb); enc = bytestream2_get_be32(gb); - outptr = frame->data[0] + dx * c->bpp2 + dy * frame->linesize[0]; + outptr = c->pic->data[0] + dx * c->bpp2 + dy * c->pic->linesize[0]; size_left = bytestream2_get_bytes_left(gb); switch (enc) { case MAGIC_WMVd: // cursor @@ -424,8 +428,8 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame, bytestream2_skip(gb, 4); break; case MAGIC_WMVi: // ServerInitialization struct - frame->key_frame = 1; - frame->pict_type = AV_PICTURE_TYPE_I; + c->pic->key_frame = 1; + c->pic->pict_type = AV_PICTURE_TYPE_I; depth = bytestream2_get_byte(gb); if (depth != c->bpp) { av_log(avctx, AV_LOG_INFO, @@ -460,7 +464,7 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame, return AVERROR_INVALIDDATA; } paint_raw(outptr, w, h, gb, c->bpp2, c->bigendian, - frame->linesize[0]); + c->pic->linesize[0]); break; case 0x00000005: // HexTile encoded rectangle if ((dx + w > c->width) || (dy + h > c->height)) { @@ -469,7 +473,7 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame, w, h, dx, dy, c->width, c->height); return AVERROR_INVALIDDATA; } - res = decode_hextile(c, outptr, gb, w, h, frame->linesize[0]); + res = decode_hextile(c, outptr, gb, w, h, c->pic->linesize[0]); if (res < 0) return res; break; @@ -498,18 +502,18 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame, dy = 0; } if ((w > 0) && (h > 0)) { - outptr = frame->data[0] + dx * c->bpp2 + dy * frame->linesize[0]; + outptr = c->pic->data[0] + dx * c->bpp2 + dy * c->pic->linesize[0]; for (i = 0; i < h; i++) { memcpy(c->screendta + i * c->cur_w * c->bpp2, outptr, w * c->bpp2); - outptr += frame->linesize[0]; + outptr += c->pic->linesize[0]; } - outptr = frame->data[0]; - put_cursor(outptr, frame->linesize[0], c, c->cur_x, c->cur_y); + outptr = c->pic->data[0]; + put_cursor(outptr, c->pic->linesize[0], c, c->cur_x, c->cur_y); } } *got_frame = 1; - if ((ret = av_frame_ref(data, frame)) < 0) + if ((ret = av_frame_ref(data, c->pic)) < 0) return ret; /* always report that the buffer was completely consumed */ @@ -541,8 +545,8 @@ static av_cold int decode_init(AVCodecContext *avctx) return AVERROR_INVALIDDATA; } - c->frame = av_frame_alloc(); - if (!c->frame) + c->pic = av_frame_alloc(); + if (!c->pic) return AVERROR(ENOMEM); return 0; @@ -552,7 +556,7 @@ static av_cold int decode_end(AVCodecContext *avctx) { VmncContext * const c = avctx->priv_data; - av_frame_free(&c->frame); + av_frame_free(&c->pic); av_freep(&c->curbits); av_freep(&c->curmask); diff --git a/libavcodec/vorbisdec.c b/libavcodec/vorbisdec.c index a2f7dd27f8..1221326561 100644 --- a/libavcodec/vorbisdec.c +++ b/libavcodec/vorbisdec.c @@ -151,7 +151,7 @@ typedef struct vorbis_context_s { uint8_t mode_count; vorbis_mode *modes; uint8_t mode_number; // mode number for the current packet - uint8_t previous_window; + int8_t previous_window; float *channel_residues; float *saved; } vorbis_context; @@ -701,8 +701,7 @@ static int vorbis_parse_setup_hdr_residues(vorbis_context *vc) res_setup->partition_size = get_bits(gb, 24) + 1; /* Validations to prevent a buffer overflow later. */ if (res_setup->begin>res_setup->end || - res_setup->end > (res_setup->type == 2 ? vc->audio_channels : 1) * vc->blocksize[1] / 2 || - (res_setup->end-res_setup->begin) / res_setup->partition_size > V_MAX_PARTITIONS) { + (res_setup->end-res_setup->begin) / res_setup->partition_size > FFMIN(V_MAX_PARTITIONS, 65535)) { av_log(vc->avctx, AV_LOG_ERROR, "partition out of bounds: type, begin, end, size, blocksize: %"PRIu16", %"PRIu32", %"PRIu32", %u, %"PRIu32"\n", res_setup->type, res_setup->begin, res_setup->end, @@ -989,7 +988,7 @@ static int vorbis_parse_id_hdr(vorbis_context *vc) if (!vc->channel_residues || !vc->saved) return AVERROR(ENOMEM); - vc->previous_window = 0; + vc->previous_window = -1; ff_mdct_init(&vc->mdct[0], bl0, 1, -1.0); ff_mdct_init(&vc->mdct[1], bl1, 1, -1.0); @@ -1315,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; @@ -1337,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; } @@ -1345,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; } @@ -1372,6 +1373,7 @@ static av_always_inline int vorbis_residue_decode_internal(vorbis_context *vc, unsigned pass, ch_used, i, j, k, l; unsigned max_output = (ch - 1) * vlen; int ptns_to_read = vr->ptns_to_read; + int libvorbis_bug = 0; if (vr_type == 2) { for (j = 1; j < ch; ++j) @@ -1386,8 +1388,13 @@ static av_always_inline int vorbis_residue_decode_internal(vorbis_context *vc, } if (max_output > ch_left * vlen) { - av_log(vc->avctx, AV_LOG_ERROR, "Insufficient output buffer\n"); - return AVERROR_INVALIDDATA; + if (max_output <= ch_left * vlen + vr->partition_size*ch_used/ch) { + ptns_to_read--; + libvorbis_bug = 1; + } else { + av_log(vc->avctx, AV_LOG_ERROR, "Insufficient output buffer\n"); + return AVERROR_INVALIDDATA; + } } av_dlog(NULL, " residue type 0/1/2 decode begin, ch: %d cpc %d \n", ch, c_p_c); @@ -1399,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) { @@ -1496,6 +1503,14 @@ static av_always_inline int vorbis_residue_decode_internal(vorbis_context *vc, voffset += vr->partition_size; } } + if (libvorbis_bug && !pass) { + for (j = 0; j < ch_used; ++j) { + if (!do_not_decode[j]) { + get_vlc2(&vc->gb, vc->codebooks[vr->classbook].vlc.table, + vc->codebooks[vr->classbook].nb_bits, 3); + } + } + } } return 0; } @@ -1548,7 +1563,7 @@ static int vorbis_parse_audio_packet(vorbis_context *vc, float **floor_ptr) { GetBitContext *gb = &vc->gb; FFTContext *mdct; - unsigned previous_window = vc->previous_window; + int previous_window = vc->previous_window; unsigned mode_number, blockflag, blocksize; int i, j; uint8_t no_residue[255]; @@ -1581,9 +1596,11 @@ static int vorbis_parse_audio_packet(vorbis_context *vc, float **floor_ptr) blocksize = vc->blocksize[blockflag]; vlen = blocksize / 2; if (blockflag) { - previous_window = get_bits(gb, 1); - skip_bits1(gb); // next_window - } + int code = get_bits(gb, 2); + if (previous_window < 0) + previous_window = code>>1; + } else if (previous_window < 0) + previous_window = 0; memset(ch_res_ptr, 0, sizeof(float) * vc->audio_channels * vlen); //FIXME can this be removed ? for (i = 0; i < vc->audio_channels; ++i) @@ -1812,7 +1829,7 @@ static av_cold void vorbis_decode_flush(AVCodecContext *avctx) memset(vc->saved, 0, (vc->blocksize[1] / 4) * vc->audio_channels * sizeof(*vc->saved)); } - vc->previous_window = 0; + vc->previous_window = -1; } AVCodec ff_vorbis_decoder = { diff --git a/libavcodec/wavpack.c b/libavcodec/wavpack.c index 203cd28f6d..367150cbb0 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 d7a1c61e91..80cc088154 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 213e1cef16..b78822c6bb 100644 --- a/libavcodec/webp.c +++ b/libavcodec/webp.c @@ -668,6 +668,11 @@ static int decode_entropy_coded_image(WebPContext *s, enum ImageRole role, length = offset + get_bits(&s->gb, extra_bits) + 1; } prefix_code = huff_reader_get_symbol(&hg[HUFF_IDX_DIST], &s->gb); + if (prefix_code > 39) { + av_log(s->avctx, AV_LOG_ERROR, + "distance prefix code too large: %d\n", prefix_code); + return AVERROR_INVALIDDATA; + } if (prefix_code < 4) { distance = prefix_code + 1; } else { @@ -1002,7 +1007,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]; @@ -1040,11 +1045,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); } } @@ -1056,7 +1061,7 @@ static int vp8_lossless_decode_frame(AVCodecContext *avctx, AVFrame *p, unsigned int data_size, int is_alpha_chunk) { WebPContext *s = avctx->priv_data; - int w, h, ret, i; + int w, h, ret, i, used; if (!is_alpha_chunk) { s->lossless = 1; @@ -1106,8 +1111,16 @@ static int vp8_lossless_decode_frame(AVCodecContext *avctx, AVFrame *p, /* parse transformations */ s->nb_transforms = 0; s->reduced_width = 0; + used = 0; while (get_bits1(&s->gb)) { enum TransformType transform = get_bits(&s->gb, 2); + if (used & (1 << transform)) { + av_log(avctx, AV_LOG_ERROR, "Transform %d used more than once\n", + transform); + ret = AVERROR_INVALIDDATA; + goto free_and_return; + } + used |= (1 << transform); s->transforms[s->nb_transforms++] = transform; switch (transform) { case PREDICTOR_TRANSFORM: diff --git a/libavcodec/wma.c b/libavcodec/wma.c index 0122ee6fe3..b6d6351acf 100644 --- a/libavcodec/wma.c +++ b/libavcodec/wma.c @@ -386,9 +386,9 @@ int ff_wma_end(AVCodecContext *avctx) } for (i = 0; i < 2; i++) { ff_free_vlc(&s->coef_vlc[i]); - av_free(s->run_table[i]); - av_free(s->level_table[i]); - av_free(s->int_table[i]); + av_freep(&s->run_table[i]); + av_freep(&s->level_table[i]); + av_freep(&s->int_table[i]); } return 0; diff --git a/libavcodec/wmalosslessdec.c b/libavcodec/wmalosslessdec.c index 7a80248ffc..29982bc01b 100644 --- a/libavcodec/wmalosslessdec.c +++ b/libavcodec/wmalosslessdec.c @@ -127,8 +127,8 @@ typedef struct WmallDecodeCtx { int8_t mclms_order; int8_t mclms_scaling; - int16_t mclms_coeffs[128]; - int16_t mclms_coeffs_cur[4]; + int16_t mclms_coeffs[WMALL_MAX_CHANNELS * WMALL_MAX_CHANNELS * 32]; + int16_t mclms_coeffs_cur[WMALL_MAX_CHANNELS * WMALL_MAX_CHANNELS]; int16_t mclms_prevvalues[WMALL_MAX_CHANNELS * 2 * 32]; int16_t mclms_updates[WMALL_MAX_CHANNELS * 2 * 32]; int mclms_recent; @@ -1038,9 +1038,10 @@ static int decode_frame(WmallDecodeCtx *s) len = get_bits(gb, s->log2_frame_size); /* decode tile information */ - if (decode_tilehdr(s)) { + if ((ret = decode_tilehdr(s))) { s->packet_loss = 1; - return 0; + av_frame_unref(s->frame); + return ret; } /* read drc info */ @@ -1075,8 +1076,11 @@ static int decode_frame(WmallDecodeCtx *s) /* decode all subframes */ while (!s->parsed_all_subframes) { + int decoded_samples = s->channel[0].decoded_samples; if (decode_subframe(s) < 0) { s->packet_loss = 1; + if (s->frame->nb_samples) + s->frame->nb_samples = decoded_samples; return 0; } } diff --git a/libavcodec/wmaprodec.c b/libavcodec/wmaprodec.c index d57c24dddf..19f5566e8d 100644 --- a/libavcodec/wmaprodec.c +++ b/libavcodec/wmaprodec.c @@ -420,6 +420,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/cabac.h b/libavcodec/x86/cabac.h index 7d431e5ea4..558d287032 100644 --- a/libavcodec/x86/cabac.h +++ b/libavcodec/x86/cabac.h @@ -36,6 +36,18 @@ #if HAVE_INLINE_ASM +#ifndef UNCHECKED_BITSTREAM_READER +#define UNCHECKED_BITSTREAM_READER !CONFIG_SAFE_BITSTREAM_READER +#endif + +#if UNCHECKED_BITSTREAM_READER +#define END_CHECK(end) "" +#else +#define END_CHECK(end) \ + "cmp "end" , %%"REG_c" \n\t"\ + "jge 1f \n\t" +#endif + #ifdef BROKEN_RELOCATIONS #define TABLES_ARG , "r"(tables) @@ -80,7 +92,9 @@ "test "lowword" , "lowword" \n\t"\ "jnz 2f \n\t"\ "mov "byte" , %%"REG_c" \n\t"\ + END_CHECK(end)\ "add"OPSIZE" $2 , "byte" \n\t"\ + "1: \n\t"\ "movzwl (%%"REG_c") , "tmp" \n\t"\ "lea -1("low") , %%ecx \n\t"\ "xor "low" , %%ecx \n\t"\ @@ -139,7 +153,9 @@ "test "lowword" , "lowword" \n\t"\ " jnz 2f \n\t"\ "mov "byte" , %%"REG_c" \n\t"\ + END_CHECK(end)\ "add"OPSIZE" $2 , "byte" \n\t"\ + "1: \n\t"\ "movzwl (%%"REG_c") , "tmp" \n\t"\ "lea -1("low") , %%ecx \n\t"\ "xor "low" , %%ecx \n\t"\ @@ -214,9 +230,16 @@ static av_always_inline int get_cabac_bypass_sign_x86(CABACContext *c, int val) "movzwl (%1), %%edx \n\t" "bswap %%edx \n\t" "shrl $15, %%edx \n\t" +#if UNCHECKED_BITSTREAM_READER "add $2, %1 \n\t" "addl %%edx, %%eax \n\t" "mov %1, %c4(%2) \n\t" +#else + "addl %%edx, %%eax \n\t" + "cmp %c5(%2), %1 \n\t" + "jge 1f \n\t" + "add"OPSIZE" $2, %c4(%2) \n\t" +#endif "1: \n\t" "movl %%eax, %c3(%2) \n\t" diff --git a/libavcodec/x86/dsputil.asm b/libavcodec/x86/dsputil.asm index 77069e20f8..d7825ee387 100644 --- a/libavcodec/x86/dsputil.asm +++ b/libavcodec/x86/dsputil.asm @@ -61,6 +61,9 @@ cglobal scalarproduct_int16, 3,3,3, v1, v2, order %endif paddd m2, m0 movd eax, m2 +%if mmsize == 8 + emms +%endif RET ; int scalarproduct_and_madd_int16(int16_t *v1, int16_t *v2, int16_t *v3, int order, int mul) diff --git a/libavcodec/x86/h264_weight.asm b/libavcodec/x86/h264_weight.asm index 4759a063a6..f6b9d5f6ad 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/idct_sse2_xvid.c b/libavcodec/x86/idct_sse2_xvid.c index af4790ca92..4c5e74b98f 100644 --- a/libavcodec/x86/idct_sse2_xvid.c +++ b/libavcodec/x86/idct_sse2_xvid.c @@ -343,7 +343,7 @@ DECLARE_ASM_CONST(16, int32_t, walkenIdctRounders)[] = { "movdqa %%xmm6, 4*16("dct") \n\t" \ "movdqa "SREG2", 7*16("dct") \n\t" -inline void ff_idct_xvid_sse2(short *block) +av_extern_inline void ff_idct_xvid_sse2(short *block) { __asm__ volatile( "movq "MANGLE(m127)", %%mm0 \n\t" diff --git a/libavcodec/x86/mlpdsp.c b/libavcodec/x86/mlpdsp.c index 94849b7e79..a3ac207a60 100644 --- a/libavcodec/x86/mlpdsp.c +++ b/libavcodec/x86/mlpdsp.c @@ -132,8 +132,8 @@ static void mlp_filter_channel_x86(int32_t *state, const int32_t *coeff, FIRMUL (ff_mlp_firorder_6, 0x14 ) FIRMUL (ff_mlp_firorder_5, 0x10 ) FIRMUL (ff_mlp_firorder_4, 0x0c ) - FIRMULREG(ff_mlp_firorder_3, 0x08,10) - FIRMULREG(ff_mlp_firorder_2, 0x04, 9) + FIRMUL (ff_mlp_firorder_3, 0x08 ) + FIRMUL (ff_mlp_firorder_2, 0x04 ) FIRMULREG(ff_mlp_firorder_1, 0x00, 8) LABEL_MANGLE(ff_mlp_firorder_0)":\n\t" "jmp *%6 \n\t" @@ -162,8 +162,6 @@ static void mlp_filter_channel_x86(int32_t *state, const int32_t *coeff, : /* 4*/"r"((x86_reg)mask), /* 5*/"r"(firjump), /* 6*/"r"(iirjump) , /* 7*/"c"(filter_shift) , /* 8*/"r"((int64_t)coeff[0]) - , /* 9*/"r"((int64_t)coeff[1]) - , /*10*/"r"((int64_t)coeff[2]) : "rax", "rdx", "rsi" #else /* ARCH_X86_32 */ /* 3*/"+m"(blocksize) diff --git a/libavcodec/x86/mpegvideoenc_template.c b/libavcodec/x86/mpegvideoenc_template.c index 1e0505ea3c..b0ba234d4b 100644 --- a/libavcodec/x86/mpegvideoenc_template.c +++ b/libavcodec/x86/mpegvideoenc_template.c @@ -216,7 +216,7 @@ static int RENAME(dct_quantize)(MpegEncContext *s, "psubusw "MM"1, "MM"4 \n\t" "packuswb "MM"4, "MM"4 \n\t" #if COMPILE_TEMPLATE_SSE2 - "packuswb "MM"4, "MM"4 \n\t" + "packsswb "MM"4, "MM"4 \n\t" #endif "movd "MM"4, %0 \n\t" // *overflow : "=g" (*overflow) 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/xan.c b/libavcodec/xan.c index 1c2e97cda2..c400f40307 100644 --- a/libavcodec/xan.c +++ b/libavcodec/xan.c @@ -71,7 +71,18 @@ typedef struct XanContext { } XanContext; -static av_cold int xan_decode_end(AVCodecContext *avctx); +static av_cold int xan_decode_end(AVCodecContext *avctx) +{ + XanContext *s = avctx->priv_data; + + av_frame_free(&s->last_frame); + + av_freep(&s->buffer1); + av_freep(&s->buffer2); + av_freep(&s->palettes); + + return 0; +} static av_cold int xan_decode_init(AVCodecContext *avctx) { @@ -92,6 +103,7 @@ static av_cold int xan_decode_init(AVCodecContext *avctx) av_freep(&s->buffer1); return AVERROR(ENOMEM); } + s->last_frame = av_frame_alloc(); if (!s->last_frame) { xan_decode_end(avctx); @@ -624,19 +636,6 @@ static int xan_decode_frame(AVCodecContext *avctx, return buf_size; } -static av_cold int xan_decode_end(AVCodecContext *avctx) -{ - XanContext *s = avctx->priv_data; - - av_frame_free(&s->last_frame); - - av_freep(&s->buffer1); - av_freep(&s->buffer2); - av_freep(&s->palettes); - - return 0; -} - AVCodec ff_xan_wc3_decoder = { .name = "xan_wc3", .long_name = NULL_IF_CONFIG_SMALL("Wing Commander III / Xan"), diff --git a/libavcodec/xxan.c b/libavcodec/xxan.c index 56d5f4961d..b261cdfdec 100644 --- a/libavcodec/xxan.c +++ b/libavcodec/xxan.c @@ -38,7 +38,17 @@ typedef struct XanContext { GetByteContext gb; } XanContext; -static av_cold int xan_decode_end(AVCodecContext *avctx); +static av_cold int xan_decode_end(AVCodecContext *avctx) +{ + XanContext *s = avctx->priv_data; + + av_frame_free(&s->pic); + + av_freep(&s->y_buffer); + av_freep(&s->scratch_buffer); + + return 0; +} static av_cold int xan_decode_init(AVCodecContext *avctx) { @@ -428,18 +438,6 @@ static int xan_decode_frame(AVCodecContext *avctx, return avpkt->size; } -static av_cold int xan_decode_end(AVCodecContext *avctx) -{ - XanContext *s = avctx->priv_data; - - av_frame_free(&s->pic); - - av_freep(&s->y_buffer); - av_freep(&s->scratch_buffer); - - return 0; -} - AVCodec ff_xan_wc4_decoder = { .name = "xan_wc4", .long_name = NULL_IF_CONFIG_SMALL("Wing Commander IV / Xxan"), diff --git a/libavcodec/zerocodec.c b/libavcodec/zerocodec.c index 80264b34d6..9f6c37c02a 100644 --- a/libavcodec/zerocodec.c +++ b/libavcodec/zerocodec.c @@ -23,7 +23,7 @@ #include "libavutil/common.h" typedef struct { - AVFrame previous_frame; + AVFrame *previous_frame; z_stream zstream; } ZeroCodecContext; @@ -32,7 +32,7 @@ static int zerocodec_decode_frame(AVCodecContext *avctx, void *data, { ZeroCodecContext *zc = avctx->priv_data; AVFrame *pic = data; - AVFrame *prev_pic = &zc->previous_frame; + AVFrame *prev_pic = zc->previous_frame; z_stream *zstream = &zc->zstream; uint8_t *prev = prev_pic->data[0]; uint8_t *dst; @@ -91,8 +91,8 @@ static int zerocodec_decode_frame(AVCodecContext *avctx, void *data, dst -= pic->linesize[0]; } - av_frame_unref(&zc->previous_frame); - if ((ret = av_frame_ref(&zc->previous_frame, pic)) < 0) + av_frame_unref(zc->previous_frame); + if ((ret = av_frame_ref(zc->previous_frame, pic)) < 0) return ret; *got_frame = 1; @@ -104,7 +104,7 @@ static av_cold int zerocodec_decode_close(AVCodecContext *avctx) { ZeroCodecContext *zc = avctx->priv_data; - av_frame_unref(&zc->previous_frame); + av_frame_free(&zc->previous_frame); inflateEnd(&zc->zstream); @@ -130,6 +130,12 @@ static av_cold int zerocodec_decode_init(AVCodecContext *avctx) return AVERROR(ENOMEM); } + zc->previous_frame = av_frame_alloc(); + if (!zc->previous_frame) { + zerocodec_decode_close(avctx); + return AVERROR(ENOMEM); + } + return 0; } diff --git a/libavcodec/zmbv.c b/libavcodec/zmbv.c index 71e828771a..048cbb5eed 100644 --- a/libavcodec/zmbv.c +++ b/libavcodec/zmbv.c @@ -410,11 +410,16 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame, AVPac int hi_ver, lo_ver, ret; /* parse header */ + if (len < 1) + return AVERROR_INVALIDDATA; c->flags = buf[0]; buf++; len--; if (c->flags & ZMBV_KEYFRAME) { void *decode_intra = NULL; c->decode_intra= NULL; + + if (len < 6) + return AVERROR_INVALIDDATA; hi_ver = buf[0]; lo_ver = buf[1]; c->comp = buf[2]; diff --git a/libavcodec/zmbvenc.c b/libavcodec/zmbvenc.c index 2907c99abc..28dbe20f06 100644 --- a/libavcodec/zmbvenc.c +++ b/libavcodec/zmbvenc.c @@ -44,6 +44,7 @@ */ typedef struct ZmbvEncContext { AVCodecContext *avctx; + int range; uint8_t *comp_buf, *work_buf; uint8_t pal[768]; @@ -119,7 +120,7 @@ static int encode_frame(AVCodecContext *avctx, AVPacket *pkt, const AVFrame *pict, int *got_packet) { ZmbvEncContext * const c = avctx->priv_data; - AVFrame * const p = (AVFrame *)pict; + const AVFrame * const p = pict; uint8_t *src, *prev, *buf; uint32_t *palptr; int keyframe, chpal; @@ -132,8 +133,8 @@ static int encode_frame(AVCodecContext *avctx, AVPacket *pkt, c->curfrm++; if(c->curfrm == c->keyint) c->curfrm = 0; - p->pict_type= keyframe ? AV_PICTURE_TYPE_I : AV_PICTURE_TYPE_P; - p->key_frame= keyframe; + avctx->coded_frame->pict_type = keyframe ? AV_PICTURE_TYPE_I : AV_PICTURE_TYPE_P; + avctx->coded_frame->key_frame = keyframe; chpal = !keyframe && memcmp(p->data[1], c->pal2, 1024); palptr = (uint32_t*)p->data[1]; @@ -248,6 +249,20 @@ static int encode_frame(AVCodecContext *avctx, AVPacket *pkt, return 0; } +static av_cold int encode_end(AVCodecContext *avctx) +{ + ZmbvEncContext * const c = avctx->priv_data; + + av_freep(&c->comp_buf); + av_freep(&c->work_buf); + + deflateEnd(&c->zstream); + av_freep(&c->prev); + + av_frame_free(&avctx->coded_frame); + + return 0; +} /** * Init zmbv encoder @@ -309,23 +324,11 @@ static av_cold int encode_init(AVCodecContext *avctx) return -1; } - return 0; -} - - - -/** - * Uninit zmbv encoder - */ -static av_cold int encode_end(AVCodecContext *avctx) -{ - ZmbvEncContext * const c = avctx->priv_data; - - av_freep(&c->comp_buf); - av_freep(&c->work_buf); - - deflateEnd(&c->zstream); - av_freep(&c->prev); + avctx->coded_frame = av_frame_alloc(); + if (!avctx->coded_frame) { + encode_end(avctx); + return AVERROR(ENOMEM); + } return 0; } diff --git a/libavdevice/Makefile b/libavdevice/Makefile index 21ca954eeb..bc7cb83e2d 100644 --- a/libavdevice/Makefile +++ b/libavdevice/Makefile @@ -34,7 +34,7 @@ OBJS-$(CONFIG_OPENAL_INDEV) += openal-dec.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_SDL_OUTDEV) += sdl.o diff --git a/libavdevice/bktr.c b/libavdevice/bktr.c index 4e25aa6ad8..ac6b61a2d4 100644 --- a/libavdevice/bktr.c +++ b/libavdevice/bktr.c @@ -3,7 +3,7 @@ * Copyright (c) 2002 Steve O'Hara-Smith * based on * Linux video grab interface - * Copyright (c) 2000,2001 Gerard Lantau + * Copyright (c) 2000, 2001 Fabrice Bellard * and * simple_grab.c Copyright (c) 1999 Roger Hardiman * diff --git a/libavdevice/lavfi.c b/libavdevice/lavfi.c index 559f721c8f..a177ad0271 100644 --- a/libavdevice/lavfi.c +++ b/libavdevice/lavfi.c @@ -248,6 +248,10 @@ av_cold static int lavfi_read_header(AVFormatContext *avctx) ret = av_opt_set_int_list(sink, "sample_fmts", sample_fmts, AV_SAMPLE_FMT_NONE, AV_OPT_SEARCH_CHILDREN); if (ret < 0) goto end; + ret = av_opt_set_int(sink, "all_channel_counts", 1, + AV_OPT_SEARCH_CHILDREN); + if (ret < 0) + goto end; } lavfi->sinks[i] = sink; diff --git a/libavdevice/v4l2enc.c b/libavdevice/v4l2enc.c index 21f0ef6983..db4946581e 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_aconvert.c b/libavfilter/af_aconvert.c index a198d2b396..43158f08e8 100644 --- a/libavfilter/af_aconvert.c +++ b/libavfilter/af_aconvert.c @@ -66,7 +66,7 @@ static av_cold int init(AVFilterContext *ctx) (ret = ff_parse_sample_format(&aconvert->out_sample_fmt, aconvert->format_str, ctx)) < 0) return ret; if (aconvert->channel_layout_str && strcmp(aconvert->channel_layout_str, "auto")) - return ff_parse_channel_layout(&aconvert->out_chlayout, aconvert->channel_layout_str, ctx); + return ff_parse_channel_layout(&aconvert->out_chlayout, NULL, aconvert->channel_layout_str, ctx); return ret; } diff --git a/libavfilter/af_amix.c b/libavfilter/af_amix.c index 0902c2ac50..9d7b728145 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_atempo.c b/libavfilter/af_atempo.c index ad12786584..0857257451 100644 --- a/libavfilter/af_atempo.c +++ b/libavfilter/af_atempo.c @@ -1058,11 +1058,11 @@ static int push_samples(ATempoContext *atempo, outlink->time_base); ret = ff_filter_frame(outlink, atempo->dst_buffer); - if (ret < 0) - return ret; atempo->dst_buffer = NULL; atempo->dst = NULL; atempo->dst_end = NULL; + if (ret < 0) + return ret; atempo->nsamples_out += n_out; return 0; diff --git a/libavfilter/af_join.c b/libavfilter/af_join.c index a266a248cd..045c15e68e 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/af_pan.c b/libavfilter/af_pan.c index 9cee9d9c3d..3d3b98d6db 100644 --- a/libavfilter/af_pan.c +++ b/libavfilter/af_pan.c @@ -46,7 +46,6 @@ typedef struct PanContext { double gain[MAX_CHANNELS][MAX_CHANNELS]; int64_t need_renorm; int need_renumber; - int nb_input_channels; int nb_output_channels; int pure_gains; @@ -116,10 +115,10 @@ static av_cold int init(AVFilterContext *ctx) if (!args) return AVERROR(ENOMEM); arg = av_strtok(args, "|", &tokenizer); - ret = ff_parse_channel_layout(&pan->out_channel_layout, arg, ctx); + ret = ff_parse_channel_layout(&pan->out_channel_layout, + &pan->nb_output_channels, arg, ctx); if (ret < 0) goto fail; - pan->nb_output_channels = av_get_channel_layout_nb_channels(pan->out_channel_layout); /* parse channel specifications */ while ((arg = arg0 = av_strtok(NULL, "|", &tokenizer))) { @@ -239,12 +238,14 @@ static int query_formats(AVFilterContext *ctx) ff_set_common_samplerates(ctx, formats); // inlink supports any channel layout - layouts = ff_all_channel_layouts(); + layouts = ff_all_channel_counts(); ff_channel_layouts_ref(layouts, &inlink->out_channel_layouts); // outlink supports only requested output channel layout layouts = NULL; - ff_add_channel_layout(&layouts, pan->out_channel_layout); + ff_add_channel_layout(&layouts, + pan->out_channel_layout ? pan->out_channel_layout : + FF_COUNT2LAYOUT(pan->nb_output_channels)); ff_channel_layouts_ref(layouts, &outlink->in_channel_layouts); return 0; } @@ -257,7 +258,6 @@ static int config_props(AVFilterLink *link) int i, j, k, r; double t; - pan->nb_input_channels = av_get_channel_layout_nb_channels(link->channel_layout); if (pan->need_renumber) { // input channels were given by their name: renumber them for (i = j = 0; i < MAX_CHANNELS; i++) { @@ -271,7 +271,7 @@ static int config_props(AVFilterLink *link) // sanity check; can't be done in query_formats since the inlink // channel layout is unknown at that time - if (pan->nb_input_channels > SWR_CH_MAX || + if (link->channels > SWR_CH_MAX || pan->nb_output_channels > SWR_CH_MAX) { av_log(ctx, AV_LOG_ERROR, "libswresample support a maximum of %d channels. " @@ -286,6 +286,10 @@ static int config_props(AVFilterLink *link) 0, ctx); if (!pan->swr) return AVERROR(ENOMEM); + if (!link->channel_layout) + av_opt_set_int(pan->swr, "ich", link->channels, 0); + if (!pan->out_channel_layout) + av_opt_set_int(pan->swr, "och", pan->nb_output_channels, 0); // gains are pure, init the channel mapping if (pan->pure_gains) { @@ -293,7 +297,7 @@ static int config_props(AVFilterLink *link) // get channel map from the pure gains for (i = 0; i < pan->nb_output_channels; i++) { int ch_id = -1; - for (j = 0; j < pan->nb_input_channels; j++) { + for (j = 0; j < link->channels; j++) { if (pan->gain[i][j]) { ch_id = j; break; @@ -311,7 +315,7 @@ static int config_props(AVFilterLink *link) if (!((pan->need_renorm >> i) & 1)) continue; t = 0; - for (j = 0; j < pan->nb_input_channels; j++) + for (j = 0; j < link->channels; j++) t += pan->gain[i][j]; if (t > -1E-5 && t < 1E-5) { // t is almost 0 but not exactly, this is probably a mistake @@ -320,7 +324,7 @@ static int config_props(AVFilterLink *link) "Degenerate coefficients while renormalizing\n"); continue; } - for (j = 0; j < pan->nb_input_channels; j++) + for (j = 0; j < link->channels; j++) pan->gain[i][j] /= t; } av_opt_set_int(pan->swr, "icl", link->channel_layout, 0); @@ -335,7 +339,7 @@ static int config_props(AVFilterLink *link) // summary for (i = 0; i < pan->nb_output_channels; i++) { cur = buf; - for (j = 0; j < pan->nb_input_channels; j++) { + for (j = 0; j < link->channels; j++) { r = snprintf(cur, buf + sizeof(buf) - cur, "%s%.3g i%d", j ? " + " : "", pan->gain[i][j], j); cur += FFMIN(buf + sizeof(buf) - cur, r); diff --git a/libavfilter/asrc_aevalsrc.c b/libavfilter/asrc_aevalsrc.c index 3f71ac33d8..79fb4b276c 100644 --- a/libavfilter/asrc_aevalsrc.c +++ b/libavfilter/asrc_aevalsrc.c @@ -109,7 +109,7 @@ static av_cold int init(AVFilterContext *ctx) if (eval->chlayout_str) { int n; - ret = ff_parse_channel_layout(&eval->chlayout, eval->chlayout_str, ctx); + ret = ff_parse_channel_layout(&eval->chlayout, NULL, eval->chlayout_str, ctx); if (ret < 0) goto end; diff --git a/libavfilter/asrc_anullsrc.c b/libavfilter/asrc_anullsrc.c index 4f76759419..a4bf01394a 100644 --- a/libavfilter/asrc_anullsrc.c +++ b/libavfilter/asrc_anullsrc.c @@ -68,7 +68,7 @@ static av_cold int init(AVFilterContext *ctx) null->sample_rate_str, ctx)) < 0) return ret; - if ((ret = ff_parse_channel_layout(&null->channel_layout, + if ((ret = ff_parse_channel_layout(&null->channel_layout, NULL, null->channel_layout_str, ctx)) < 0) return ret; diff --git a/libavfilter/avfilter.c b/libavfilter/avfilter.c index f31968f394..c9c8accc2a 100644 --- a/libavfilter/avfilter.c +++ b/libavfilter/avfilter.c @@ -487,7 +487,7 @@ int avfilter_register(AVFilter *filter) filter->next = NULL; - while(avpriv_atomic_ptr_cas((void * volatile *)f, NULL, filter)) + while(*f || avpriv_atomic_ptr_cas((void * volatile *)f, NULL, filter)) f = &(*f)->next; return 0; diff --git a/libavfilter/avfiltergraph.c b/libavfilter/avfiltergraph.c index 506d79ec71..1fb83c4877 100644 --- a/libavfilter/avfiltergraph.c +++ b/libavfilter/avfiltergraph.c @@ -654,6 +654,10 @@ static int pick_format(AVFilterLink *link, AVFilterLink *ref) av_log(link->src, AV_LOG_ERROR, "Cannot select channel layout for" " the link between filters %s and %s.\n", link->src->name, link->dst->name); + if (!link->in_channel_layouts->all_counts) + av_log(link->src, AV_LOG_ERROR, "Unknown channel layouts not " + "supported, try specifying a channel layout using " + "'aformat=channel_layouts=something'.\n"); return AVERROR(EINVAL); } link->in_channel_layouts->nb_channel_layouts = 1; @@ -737,7 +741,8 @@ static int reduce_formats_on_filter(AVFilterContext *filter) if (inlink->type != outlink->type || fmts->nb_channel_layouts == 1) continue; - if (fmts->all_layouts) { + if (fmts->all_layouts && + (!FF_LAYOUT2COUNT(fmt) || fmts->all_counts)) { /* Turn the infinite list into a singleton */ fmts->all_layouts = fmts->all_counts = 0; ff_add_channel_layout(&outlink->in_channel_layouts, fmt); diff --git a/libavfilter/dualinput.c b/libavfilter/dualinput.c index 97e15cbe01..88f7a272f1 100644 --- a/libavfilter/dualinput.c +++ b/libavfilter/dualinput.c @@ -57,7 +57,7 @@ int ff_dualinput_init(AVFilterContext *ctx, FFDualInputContext *s) in[1].after = EXT_INFINITY; if (s->shortest) - in[1].after = EXT_STOP; + in[0].after = in[1].after = EXT_STOP; if (!s->repeatlast) { in[0].after = EXT_STOP; in[1].sync = 0; diff --git a/libavfilter/f_select.c b/libavfilter/f_select.c index 60cc311e5f..1baa5c23d6 100644 --- a/libavfilter/f_select.c +++ b/libavfilter/f_select.c @@ -279,7 +279,7 @@ static double get_scene_score(AVFilterContext *ctx, AVFrame *frame) p2 += 8 * linesize; } emms_c(); - mafd = nb_sad ? sad / nb_sad : 0; + mafd = nb_sad ? (double)sad / nb_sad : 0; diff = fabs(mafd - select->prev_mafd); ret = av_clipf(FFMIN(mafd, diff) / 100., 0, 1); select->prev_mafd = mafd; diff --git a/libavfilter/filtfmts.c b/libavfilter/filtfmts.c index e6c9b039be..b3efa78343 100644 --- a/libavfilter/filtfmts.c +++ b/libavfilter/filtfmts.c @@ -38,7 +38,7 @@ static void print_formats(AVFilterContext *filter_ctx) for (j = 0; j < fmts->nb_formats; j++) \ if(av_get_pix_fmt_name(fmts->formats[j])) \ printf(#INOUT "PUT[%d] %s: fmt:%s\n", \ - i, filter_ctx->filter->inout##puts[i].name, \ + i, filter_ctx->inout##put_pads[i].name, \ av_get_pix_fmt_name(fmts->formats[j])); \ } else if (filter_ctx->inout##puts[i]->type == AVMEDIA_TYPE_AUDIO) { \ AVFilterFormats *fmts; \ @@ -47,7 +47,7 @@ static void print_formats(AVFilterContext *filter_ctx) fmts = filter_ctx->inout##puts[i]->outin##_formats; \ for (j = 0; j < fmts->nb_formats; j++) \ printf(#INOUT "PUT[%d] %s: fmt:%s\n", \ - i, filter_ctx->filter->inout##puts[i].name, \ + i, filter_ctx->inout##put_pads[i].name, \ av_get_sample_fmt_name(fmts->formats[j])); \ \ layouts = filter_ctx->inout##puts[i]->outin##_channel_layouts; \ @@ -56,7 +56,7 @@ static void print_formats(AVFilterContext *filter_ctx) av_get_channel_layout_string(buf, sizeof(buf), -1, \ layouts->channel_layouts[j]); \ printf(#INOUT "PUT[%d] %s: chlayout:%s\n", \ - i, filter_ctx->filter->inout##puts[i].name, buf); \ + i, filter_ctx->inout##put_pads[i].name, buf); \ } \ } \ } \ @@ -113,12 +113,12 @@ int main(int argc, char **argv) /* create a link for each of the input pads */ for (i = 0; i < filter_ctx->nb_inputs; i++) { AVFilterLink *link = av_mallocz(sizeof(AVFilterLink)); - link->type = filter_ctx->filter->inputs[i].type; + link->type = filter_ctx->input_pads[i].type; filter_ctx->inputs[i] = link; } for (i = 0; i < filter_ctx->nb_outputs; i++) { AVFilterLink *link = av_mallocz(sizeof(AVFilterLink)); - link->type = filter_ctx->filter->outputs[i].type; + link->type = filter_ctx->output_pads[i].type; filter_ctx->outputs[i] = link; } diff --git a/libavfilter/formats.c b/libavfilter/formats.c index d51bf3c51d..5816032746 100644 --- a/libavfilter/formats.c +++ b/libavfilter/formats.c @@ -615,10 +615,21 @@ int ff_parse_sample_rate(int *ret, const char *arg, void *log_ctx) return 0; } -int ff_parse_channel_layout(int64_t *ret, const char *arg, void *log_ctx) +int ff_parse_channel_layout(int64_t *ret, int *nret, const char *arg, + void *log_ctx) { char *tail; - int64_t chlayout = av_get_channel_layout(arg); + int64_t chlayout, count; + + if (nret) { + count = strtol(arg, &tail, 10); + if (*tail == 'c' && !tail[1] && count > 0 && count < 63) { + *nret = count; + *ret = 0; + return 0; + } + } + chlayout = av_get_channel_layout(arg); if (chlayout == 0) { chlayout = strtol(arg, &tail, 10); if (*tail || chlayout == 0) { @@ -627,6 +638,8 @@ int ff_parse_channel_layout(int64_t *ret, const char *arg, void *log_ctx) } } *ret = chlayout; + if (nret) + *nret = av_get_channel_layout_nb_channels(chlayout); return 0; } diff --git a/libavfilter/graphdump.c b/libavfilter/graphdump.c index 1b5932115b..3d702c6af5 100644 --- a/libavfilter/graphdump.c +++ b/libavfilter/graphdump.c @@ -31,9 +31,10 @@ static int print_link_prop(AVBPrint *buf, AVFilterLink *link) { char *format; char layout[64]; + AVBPrint dummy_buffer = { 0 }; if (!buf) - buf = &(AVBPrint){ 0 }; /* dummy buffer */ + buf = &dummy_buffer; switch (link->type) { case AVMEDIA_TYPE_VIDEO: format = av_x_if_null(av_get_pix_fmt_name(link->format), "?"); diff --git a/libavfilter/internal.h b/libavfilter/internal.h index f8d0cce638..5e19698d07 100644 --- a/libavfilter/internal.h +++ b/libavfilter/internal.h @@ -207,11 +207,14 @@ int ff_parse_sample_format(int *ret, const char *arg, void *log_ctx); * Parse a channel layout or a corresponding integer representation. * * @param ret 64bit integer pointer to where the value should be written. + * @param nret integer pointer to the number of channels; + * if not NULL, then unknown channel layouts are accepted * @param arg string to parse * @param log_ctx log context * @return >= 0 in case of success, a negative AVERROR code on error */ -int ff_parse_channel_layout(int64_t *ret, const char *arg, void *log_ctx); +int ff_parse_channel_layout(int64_t *ret, int *nret, const char *arg, + void *log_ctx); void ff_update_link_current_pts(AVFilterLink *link, int64_t pts); diff --git a/libavfilter/split.c b/libavfilter/split.c index 21e1a60f38..a14cf0503e 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 dfb4289f3c..ecb8ea4821 100644 --- a/libavfilter/src_movie.c +++ b/libavfilter/src_movie.c @@ -291,6 +291,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_deshake.c b/libavfilter/vf_deshake.c index 24ac41d783..a8fe63a9b1 100644 --- a/libavfilter/vf_deshake.c +++ b/libavfilter/vf_deshake.c @@ -306,8 +306,8 @@ static void find_motion(DeshakeContext *deshake, uint8_t *src1, uint8_t *src2, //av_log(NULL, AV_LOG_ERROR, "\n"); } - p_x = (center_x - width / 2); - p_y = (center_y - height / 2); + p_x = (center_x - width / 2.0); + p_y = (center_y - height / 2.0); t->vector.x += (cos(t->angle)-1)*p_x - sin(t->angle)*p_y; t->vector.y += sin(t->angle)*p_x + (cos(t->angle)-1)*p_y; diff --git a/libavfilter/vf_drawtext.c b/libavfilter/vf_drawtext.c index f1c7b26dad..05bd733266 100644 --- a/libavfilter/vf_drawtext.c +++ b/libavfilter/vf_drawtext.c @@ -48,7 +48,6 @@ #include "video.h" #include -#include #include FT_FREETYPE_H #include FT_GLYPH_H #if CONFIG_FONTCONFIG diff --git a/libavfilter/vf_fade.c b/libavfilter/vf_fade.c index 1473273a97..e482fa7550 100644 --- a/libavfilter/vf_fade.c +++ b/libavfilter/vf_fade.c @@ -125,7 +125,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_format.c b/libavfilter/vf_format.c index 1813a2c5e9..a9e386f373 100644 --- a/libavfilter/vf_format.c +++ b/libavfilter/vf_format.c @@ -55,6 +55,9 @@ static av_cold int init(AVFilterContext *ctx) int pix_fmt_name_len, ret; enum AVPixelFormat pix_fmt; + if (!s->pix_fmts) + return AVERROR(EINVAL); + /* parse the list of formats */ for (cur = s->pix_fmts; cur; cur = sep ? sep + 1 : NULL) { if (!(sep = strchr(cur, '|'))) diff --git a/libavfilter/vf_pad.c b/libavfilter/vf_pad.c index bb556c9403..45921057dd 100644 --- a/libavfilter/vf_pad.c +++ b/libavfilter/vf_pad.c @@ -251,7 +251,7 @@ static int buffer_needs_copy(PadContext *s, AVFrame *frame, AVBufferRef *buf) (s->y >> vsub) * frame->linesize[planes[i]]; ptrdiff_t req_end = ((s->w - s->x - frame->width) >> hsub) * s->draw.pixelstep[planes[i]] + - (s->y >> vsub) * frame->linesize[planes[i]]; + ((s->h - s->y - frame->height) >> vsub) * frame->linesize[planes[i]]; if (frame->linesize[planes[i]] < (s->w >> hsub) * s->draw.pixelstep[planes[i]]) return 1; diff --git a/libavfilter/vf_pullup.c b/libavfilter/vf_pullup.c index 4ad441f996..7c658521fa 100644 --- a/libavfilter/vf_pullup.c +++ b/libavfilter/vf_pullup.c @@ -69,7 +69,7 @@ static int query_formats(AVFilterContext *ctx) #define ABS(a) (((a) ^ ((a) >> 31)) - ((a) >> 31)) -static int diff_c(const uint8_t *a, const uint8_t *b, int s) +static int diff_c(const uint8_t *a, const uint8_t *b, ptrdiff_t s) { int i, j, diff = 0; @@ -83,7 +83,7 @@ static int diff_c(const uint8_t *a, const uint8_t *b, int s) return diff; } -static int comb_c(const uint8_t *a, const uint8_t *b, int s) +static int comb_c(const uint8_t *a, const uint8_t *b, ptrdiff_t s) { int i, j, comb = 0; @@ -98,7 +98,7 @@ static int comb_c(const uint8_t *a, const uint8_t *b, int s) return comb; } -static int var_c(const uint8_t *a, const uint8_t *b, int s) +static int var_c(const uint8_t *a, const uint8_t *b, ptrdiff_t s) { int i, j, var = 0; @@ -235,6 +235,8 @@ static int alloc_buffer(PullupContext *s, PullupBuffer *b) for (i = 0; i < s->nb_planes; i++) { b->planes[i] = av_malloc(s->planeheight[i] * s->planewidth[i]); } + if (s->nb_planes == 1) + b->planes[1] = av_malloc(4*256); return 0; } @@ -508,7 +510,7 @@ static void pullup_release_frame(PullupFrame *f) static void compute_metric(PullupContext *s, int *dest, PullupField *fa, int pa, PullupField *fb, int pb, - int (*func)(const uint8_t *, const uint8_t *, int)) + int (*func)(const uint8_t *, const uint8_t *, ptrdiff_t)) { int mp = s->metric_plane; int xstep = 8; diff --git a/libavfilter/vf_pullup.h b/libavfilter/vf_pullup.h index 3213b4d231..8f59335180 100644 --- a/libavfilter/vf_pullup.h +++ b/libavfilter/vf_pullup.h @@ -61,9 +61,9 @@ typedef struct PullupContext { PullupBuffer buffers[10]; PullupFrame frame; - int (*diff)(const uint8_t *a, const uint8_t *b, int s); - int (*comb)(const uint8_t *a, const uint8_t *b, int s); - int (*var )(const uint8_t *a, const uint8_t *b, int s); + int (*diff)(const uint8_t *a, const uint8_t *b, ptrdiff_t s); + int (*comb)(const uint8_t *a, const uint8_t *b, ptrdiff_t s); + int (*var )(const uint8_t *a, const uint8_t *b, ptrdiff_t s); } PullupContext; void ff_pullup_init_x86(PullupContext *s); diff --git a/libavfilter/vf_sab.c b/libavfilter/vf_sab.c index 1d970fa95f..67c24a9bce 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/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/libavfilter/x86/vf_pullup.asm b/libavfilter/x86/vf_pullup.asm index 3689b04ef2..4ce8b9b6f9 100644 --- a/libavfilter/x86/vf_pullup.asm +++ b/libavfilter/x86/vf_pullup.asm @@ -68,7 +68,7 @@ cglobal pullup_filter_comb, 3, 5, 8, first, second, size sub secondq, sizeq .loop: - movq m0, [secondq] + movq m0, [firstq] movq m1, [secondq] punpcklbw m0, m7 movq m2, [secondq+sizeq] diff --git a/libavfilter/x86/vf_pullup_init.c b/libavfilter/x86/vf_pullup_init.c index 9948abf13e..5b36b68e51 100644 --- a/libavfilter/x86/vf_pullup_init.c +++ b/libavfilter/x86/vf_pullup_init.c @@ -23,9 +23,9 @@ #include "libavutil/x86/cpu.h" #include "libavfilter/vf_pullup.h" -int ff_pullup_filter_diff_mmx(const uint8_t *a, const uint8_t *b, int s); -int ff_pullup_filter_comb_mmx(const uint8_t *a, const uint8_t *b, int s); -int ff_pullup_filter_var_mmx (const uint8_t *a, const uint8_t *b, int s); +int ff_pullup_filter_diff_mmx(const uint8_t *a, const uint8_t *b, ptrdiff_t s); +int ff_pullup_filter_comb_mmx(const uint8_t *a, const uint8_t *b, ptrdiff_t s); +int ff_pullup_filter_var_mmx (const uint8_t *a, const uint8_t *b, ptrdiff_t s); av_cold void ff_pullup_init_x86(PullupContext *s) { diff --git a/libavformat/adxdec.c b/libavformat/adxdec.c index 0a0436f184..e5caa095f6 100644 --- a/libavformat/adxdec.c +++ b/libavformat/adxdec.c @@ -41,6 +41,11 @@ static int adx_read_packet(AVFormatContext *s, AVPacket *pkt) AVCodecContext *avctx = s->streams[0]->codec; int ret, size; + if (avctx->channels <= 0) { + av_log(s, AV_LOG_ERROR, "invalid number of channels %d\n", avctx->channels); + return AVERROR_INVALIDDATA; + } + size = BLOCK_SIZE * avctx->channels; pkt->pos = avio_tell(s->pb); diff --git a/libavformat/aiffdec.c b/libavformat/aiffdec.c index 6f82d9339a..3da0d95b13 100644 --- a/libavformat/aiffdec.c +++ b/libavformat/aiffdec.c @@ -237,7 +237,7 @@ static int aiff_read_header(AVFormatContext *s) break; case MKTAG('I', 'D', '3', ' '): position = avio_tell(pb); - ff_id3v2_read(s, ID3v2_DEFAULT_MAGIC, &id3v2_extra_meta); + ff_id3v2_read(s, ID3v2_DEFAULT_MAGIC, &id3v2_extra_meta, size); if (id3v2_extra_meta) if ((ret = ff_id3v2_parse_apic(s, &id3v2_extra_meta)) < 0) { ff_id3v2_free_extra_meta(&id3v2_extra_meta); @@ -345,10 +345,16 @@ static int aiff_read_packet(AVFormatContext *s, return AVERROR_EOF; /* Now for that packet */ - if (st->codec->block_align >= 17) // GSM, QCLP, IMA4 + switch (st->codec->codec_id) { + case AV_CODEC_ID_ADPCM_IMA_QT: + case AV_CODEC_ID_GSM: + case AV_CODEC_ID_QDM2: + case AV_CODEC_ID_QCELP: size = st->codec->block_align; - else + break; + default: size = (MAX_SIZE / st->codec->block_align) * st->codec->block_align; + } size = FFMIN(max_size, size); res = av_get_packet(s->pb, pkt, size); if (res < 0) diff --git a/libavformat/ape.c b/libavformat/ape.c index 613a59d5f8..05013045fb 100644 --- a/libavformat/ape.c +++ b/libavformat/ape.c @@ -411,8 +411,10 @@ static int ape_read_packet(AVFormatContext * s, AVPacket * pkt) AV_WL32(pkt->data , nblocks); AV_WL32(pkt->data + 4, ape->frames[ape->currentframe].skip); ret = avio_read(s->pb, pkt->data + extra_size, ape->frames[ape->currentframe].size); - if (ret < 0) + if (ret < 0) { + av_free_packet(pkt); return ret; + } pkt->pts = ape->frames[ape->currentframe].pts; pkt->stream_index = 0; diff --git a/libavformat/apetag.c b/libavformat/apetag.c index a376a0bc4a..fda8f95441 100644 --- a/libavformat/apetag.c +++ b/libavformat/apetag.c @@ -53,8 +53,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/asfdec.c b/libavformat/asfdec.c index 528bcbd5b1..fe4c3f32ae 100644 --- a/libavformat/asfdec.c +++ b/libavformat/asfdec.c @@ -266,7 +266,7 @@ static void get_id3_tag(AVFormatContext *s, int len) { ID3v2ExtraMeta *id3v2_extra_meta = NULL; - ff_id3v2_read(s, ID3v2_DEFAULT_MAGIC, &id3v2_extra_meta); + ff_id3v2_read(s, ID3v2_DEFAULT_MAGIC, &id3v2_extra_meta, len); if (id3v2_extra_meta) ff_id3v2_parse_apic(s, &id3v2_extra_meta); ff_id3v2_free_extra_meta(&id3v2_extra_meta); @@ -370,7 +370,8 @@ static int asf_read_stream_properties(AVFormatContext *s, int64_t size) if (!(asf->hdr.flags & 0x01)) { // if we aren't streaming... int64_t fsize = avio_size(pb); - if (fsize <= 0 || (int64_t)asf->hdr.file_size <= 0 || FFABS(fsize - (int64_t)asf->hdr.file_size) < 10000) + if (fsize <= 0 || (int64_t)asf->hdr.file_size <= 0 || + FFABS(fsize - (int64_t)asf->hdr.file_size) / (float)FFMIN(fsize, asf->hdr.file_size) < 0.05) st->duration = asf->hdr.play_time / (10000000 / 1000) - start_time; } diff --git a/libavformat/asfenc.c b/libavformat/asfenc.c index b4a3ffb7ef..8e343b3fe0 100644 --- a/libavformat/asfenc.c +++ b/libavformat/asfenc.c @@ -525,7 +525,7 @@ static int asf_write_header1(AVFormatContext *s, int64_t file_size, avio_wl16(pb, 40 + enc->extradata_size); /* size */ /* BITMAPINFOHEADER header */ - ff_put_bmp_header(pb, enc, ff_codec_bmp_tags, 1); + ff_put_bmp_header(pb, enc, ff_codec_bmp_tags, 1, 0); } end_header(pb, hpos); } diff --git a/libavformat/avformat.h b/libavformat/avformat.h index 4e5683c66a..97bd5db1b3 100644 --- a/libavformat/avformat.h +++ b/libavformat/avformat.h @@ -892,6 +892,7 @@ typedef struct AVStream { AVRational av_stream_get_r_frame_rate(const AVStream *s); void av_stream_set_r_frame_rate(AVStream *s, AVRational r); +struct AVCodecParserContext *av_stream_get_parser(const AVStream *s); #define AV_PROGRAM_RUNNING 1 diff --git a/libavformat/avidec.c b/libavformat/avidec.c index 1a40e94c82..2ad9a94ba8 100644 --- a/libavformat/avidec.c +++ b/libavformat/avidec.c @@ -348,6 +348,7 @@ static void avi_read_nikon(AVFormatContext *s, uint64_t end) uint16_t size = avio_rl16(s->pb); const char *name = NULL; char buffer[64] = { 0 }; + size = FFMIN(size, tag_end - avio_tell(s->pb)); size -= avio_read(s->pb, buffer, FFMIN(size, sizeof(buffer) - 1)); switch (tag) { @@ -376,6 +377,46 @@ static void avi_read_nikon(AVFormatContext *s, uint64_t end) } } +static int calculate_bitrate(AVFormatContext *s) +{ + AVIContext *avi = s->priv_data; + int i, j; + int64_t lensum = 0; + int64_t maxpos = 0; + + for (i = 0; inb_streams; i++) { + int64_t len = 0; + AVStream *st = s->streams[i]; + + if (!st->nb_index_entries) + continue; + + for (j = 0; j < st->nb_index_entries; j++) + len += st->index_entries[j].size; + maxpos = FFMAX(maxpos, st->index_entries[j-1].pos); + lensum += len; + } + if (maxpos < avi->io_fsize*9/10) // index doesnt cover the whole file + return 0; + if (lensum*9/10 > maxpos || lensum < maxpos*9/10) // frame sum and filesize mismatch + return 0; + + for (i = 0; inb_streams; i++) { + int64_t len = 0; + AVStream *st = s->streams[i]; + int64_t duration; + + for (j = 0; j < st->nb_index_entries; j++) + len += st->index_entries[j].size; + + if (st->nb_index_entries < 2 || st->codec->bit_rate > 0) + continue; + duration = st->index_entries[j-1].timestamp - st->index_entries[0].timestamp; + st->codec->bit_rate = av_rescale(8*len, st->time_base.den, duration * st->time_base.num); + } + return 1; +} + static int avi_read_header(AVFormatContext *s) { AVIContext *avi = s->priv_data; @@ -685,6 +726,8 @@ static int avi_read_header(AVFormatContext *s) /* This is needed to get the pict type which is necessary * for generating correct pts. */ st->need_parsing = AVSTREAM_PARSE_HEADERS; + if (st->codec->codec_tag == MKTAG('V', 'S', 'S', 'H')) + st->need_parsing = AVSTREAM_PARSE_FULL; if (st->codec->codec_tag == 0 && st->codec->height > 0 && st->codec->extradata_size < 1U << 30) { @@ -858,6 +901,7 @@ fail: if (!avi->index_loaded && pb->seekable) avi_load_index(s); + calculate_bitrate(s); avi->index_loaded |= 1; avi->non_interleaved |= guess_ni_flag(s) | (s->flags & AVFMT_FLAG_SORT_DTS); @@ -1037,7 +1081,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) @@ -1049,6 +1093,9 @@ start_sync: goto start_sync; } + if (avi->dv_demux && n != 0) + continue; + // parse ##dc/##wb if (n < s->nb_streams) { AVStream *st; @@ -1306,12 +1353,11 @@ FF_ENABLE_DEPRECATION_WARNINGS size); pkt->stream_index = avi->stream_index; - if (st->codec->codec_type == AVMEDIA_TYPE_VIDEO) { + if (st->codec->codec_type == AVMEDIA_TYPE_VIDEO && st->index_entries) { AVIndexEntry *e; int index; - av_assert0(st->index_entries); - index = av_index_search_timestamp(st, ast->frame_offset, 0); + index = av_index_search_timestamp(st, ast->frame_offset, AVSEEK_FLAG_ANY); e = &st->index_entries[index]; if (index >= 0 && e->timestamp == ast->frame_offset) { @@ -1421,7 +1467,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; @@ -1489,6 +1536,7 @@ static int guess_ni_flag(AVFormatContext *s) return 0; for (min_pos=pos=0; min_pos!=INT64_MAX; pos= min_pos+1LU) { int64_t max_dts = INT64_MIN/2, min_dts= INT64_MAX/2; + int64_t max_buffer = 0; min_pos = INT64_MAX; for (i=0; inb_streams; i++) { @@ -1501,10 +1549,20 @@ static int guess_ni_flag(AVFormatContext *s) min_dts = FFMIN(min_dts, av_rescale_q(st->index_entries[idx[i]].timestamp/FFMAX(ast->sample_size, 1), st->time_base, AV_TIME_BASE_Q)); min_pos = FFMIN(min_pos, st->index_entries[idx[i]].pos); } - if (idx[i]) - max_dts = FFMAX(max_dts, av_rescale_q(st->index_entries[idx[i]-1].timestamp/FFMAX(ast->sample_size, 1), st->time_base, AV_TIME_BASE_Q)); } - if (max_dts - min_dts > 2*AV_TIME_BASE) { + for (i=0; inb_streams; i++) { + AVStream *st = s->streams[i]; + AVIStream *ast = st->priv_data; + + if (idx[i] && min_dts != INT64_MAX/2) { + int64_t dts = av_rescale_q(st->index_entries[idx[i]-1].timestamp/FFMAX(ast->sample_size, 1), st->time_base, AV_TIME_BASE_Q); + max_dts = FFMAX(max_dts, dts); + max_buffer = FFMAX(max_buffer, av_rescale(dts - min_dts, st->codec->bit_rate, AV_TIME_BASE)); + } + } + if (max_dts - min_dts > 2*AV_TIME_BASE || + max_buffer > 1024 * 1024 * 8 *8 + ) { av_free(idx); return 1; } @@ -1646,8 +1704,7 @@ static int avi_read_seek(AVFormatContext *s, int stream_index, continue; // av_assert1(st2->codec->block_align); - av_assert0((int64_t)st2->time_base.num * ast2->rate == - (int64_t)st2->time_base.den * ast2->scale); + av_assert0(fabs(av_q2d(st2->time_base) - ast2->scale / (double)ast2->rate) < av_q2d(st2->time_base) * 0.00000001); index = av_index_search_timestamp(st2, av_rescale_q(timestamp, st->time_base, diff --git a/libavformat/avienc.c b/libavformat/avienc.c index 3401cbc237..bd6cd02faf 100644 --- a/libavformat/avienc.c +++ b/libavformat/avienc.c @@ -291,7 +291,7 @@ static int avi_write_header(AVFormatContext *s) // are not (yet) supported. if (stream->codec_id != AV_CODEC_ID_XSUB) break; case AVMEDIA_TYPE_VIDEO: - ff_put_bmp_header(pb, stream, ff_codec_bmp_tags, 0); + ff_put_bmp_header(pb, stream, ff_codec_bmp_tags, 0, 0); break; case AVMEDIA_TYPE_AUDIO: if ((ret = ff_put_wav_header(pb, stream)) < 0) { diff --git a/libavformat/aviobuf.c b/libavformat/aviobuf.c index 8218078dae..87ad388fa6 100644 --- a/libavformat/aviobuf.c +++ b/libavformat/aviobuf.c @@ -217,6 +217,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 <= (s->buf_end - s->buffer)) { diff --git a/libavformat/bink.c b/libavformat/bink.c index 6db73cce3a..b9c853cb14 100644 --- a/libavformat/bink.c +++ b/libavformat/bink.c @@ -79,6 +79,7 @@ static int read_header(AVFormatContext *s) uint32_t pos, next_pos; uint16_t flags; int keyframe; + int ret; vst = avformat_new_stream(s, NULL); if (!vst) @@ -177,8 +178,9 @@ static int read_header(AVFormatContext *s) av_log(s, AV_LOG_ERROR, "invalid frame index table\n"); return AVERROR(EIO); } - av_add_index_entry(vst, pos, i, next_pos - pos, 0, - keyframe ? AVINDEX_KEYFRAME : 0); + if ((ret = av_add_index_entry(vst, pos, i, next_pos - pos, 0, + keyframe ? AVINDEX_KEYFRAME : 0)) < 0) + return ret; } avio_skip(pb, 4); diff --git a/libavformat/bit.c b/libavformat/bit.c index 0be471ac4f..f5112c2fea 100644 --- a/libavformat/bit.c +++ b/libavformat/bit.c @@ -119,8 +119,12 @@ static int write_header(AVFormatContext *s) { AVCodecContext *enc = s->streams[0]->codec; - enc->codec_id = AV_CODEC_ID_G729; - enc->channels = 1; + if ((enc->codec_id != AV_CODEC_ID_G729) || enc->channels != 1) { + av_log(s, AV_LOG_ERROR, + "only codec g729 with 1 channel is supported by this format\n"); + return AVERROR(EINVAL); + } + enc->bits_per_coded_sample = 16; enc->block_align = (enc->bits_per_coded_sample * enc->channels) >> 3; @@ -133,6 +137,9 @@ static int write_packet(AVFormatContext *s, AVPacket *pkt) GetBitContext gb; int i; + if (pkt->size != 10) + return AVERROR(EINVAL); + avio_wl16(pb, SYNC_WORD); avio_wl16(pb, 8 * 10); diff --git a/libavformat/cavsvideodec.c b/libavformat/cavsvideodec.c index 5ca3c80b32..880f4ab534 100644 --- a/libavformat/cavsvideodec.c +++ b/libavformat/cavsvideodec.c @@ -61,7 +61,7 @@ static int cavsvideo_probe(AVProbeData *p) } } if(seq && seq*9<=pic*10) - return AVPROBE_SCORE_EXTENSION; + return AVPROBE_SCORE_EXTENSION+1; return 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 e3b0d0a31e..10f6e24b35 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/ffmdec.c b/libavformat/ffmdec.c index b20ee131b6..5196e1d17a 100644 --- a/libavformat/ffmdec.c +++ b/libavformat/ffmdec.c @@ -77,6 +77,7 @@ static int ffm_read_data(AVFormatContext *s, FFMContext *ffm = s->priv_data; AVIOContext *pb = s->pb; int len, fill_size, size1, frame_offset, id; + int64_t last_pos = -1; size1 = size; while (size > 0) { @@ -96,9 +97,11 @@ static int ffm_read_data(AVFormatContext *s, avio_seek(pb, tell, SEEK_SET); } id = avio_rb16(pb); /* PACKET_ID */ - if (id != PACKET_ID) + if (id != PACKET_ID) { if (ffm_resync(s, id) < 0) return -1; + last_pos = avio_tell(pb); + } fill_size = avio_rb16(pb); ffm->dts = avio_rb64(pb); frame_offset = avio_rb16(pb); @@ -112,7 +115,9 @@ static int ffm_read_data(AVFormatContext *s, if (!frame_offset) { /* This packet has no frame headers in it */ if (avio_tell(pb) >= ffm->packet_size * 3LL) { - avio_seek(pb, -ffm->packet_size * 2LL, SEEK_CUR); + int64_t seekback = FFMIN(ffm->packet_size * 2LL, avio_tell(pb) - last_pos); + seekback = FFMAX(seekback, 0); + avio_seek(pb, -seekback, SEEK_CUR); goto retry_read; } /* This is bad, we cannot find a valid frame header */ @@ -290,6 +295,11 @@ static int ffm2_read_header(AVFormatContext *s) case MKBETAG('S', 'T', 'V', 'I'): codec->time_base.num = avio_rb32(pb); codec->time_base.den = avio_rb32(pb); + if (codec->time_base.num <= 0 || codec->time_base.den <= 0) { + av_log(s, AV_LOG_ERROR, "Invalid time base %d/%d\n", + codec->time_base.num, codec->time_base.den); + goto fail; + } codec->width = avio_rb16(pb); codec->height = avio_rb16(pb); codec->gop_size = avio_rb16(pb); @@ -345,7 +355,7 @@ static int ffm2_read_header(AVFormatContext *s) } /* get until end of block reached */ - while ((avio_tell(pb) % ffm->packet_size) != 0) + while ((avio_tell(pb) % ffm->packet_size) != 0 && !pb->eof_reached) avio_r8(pb); /* init packet demux */ @@ -414,6 +424,11 @@ static int ffm_read_header(AVFormatContext *s) case AVMEDIA_TYPE_VIDEO: codec->time_base.num = avio_rb32(pb); codec->time_base.den = avio_rb32(pb); + if (codec->time_base.num <= 0 || codec->time_base.den <= 0) { + av_log(s, AV_LOG_ERROR, "Invalid time base %d/%d\n", + codec->time_base.num, codec->time_base.den); + goto fail; + } codec->width = avio_rb16(pb); codec->height = avio_rb16(pb); codec->gop_size = avio_rb16(pb); @@ -473,7 +488,7 @@ static int ffm_read_header(AVFormatContext *s) } /* get until end of block reached */ - while ((avio_tell(pb) % ffm->packet_size) != 0) + while ((avio_tell(pb) % ffm->packet_size) != 0 && !pb->eof_reached) avio_r8(pb); /* init packet demux */ diff --git a/libavformat/flac_picture.c b/libavformat/flac_picture.c index 12d73e488f..5f2026d1d0 100644 --- a/libavformat/flac_picture.c +++ b/libavformat/flac_picture.c @@ -107,9 +107,10 @@ int ff_flac_parse_picture(AVFormatContext *s, uint8_t *buf, int buf_size) ret = AVERROR_INVALIDDATA; goto fail; } - if (!(data = av_buffer_alloc(len))) { + if (!(data = av_buffer_alloc(len + FF_INPUT_BUFFER_PADDING_SIZE))) { RETURN_ERROR(AVERROR(ENOMEM)); } + memset(data->data + len, 0, FF_INPUT_BUFFER_PADDING_SIZE); if (avio_read(pb, data->data, len) != len) { av_log(s, AV_LOG_ERROR, "Error reading attached picture data.\n"); if (s->error_recognition & AV_EF_EXPLODE) diff --git a/libavformat/flvdec.c b/libavformat/flvdec.c index 1024001a47..04196ad00a 100644 --- a/libavformat/flvdec.c +++ b/libavformat/flvdec.c @@ -375,7 +375,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; @@ -540,13 +540,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. @@ -813,7 +813,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); @@ -916,7 +916,7 @@ retry_duration: flv->last_channels = channels = st->codec->channels; } else { - AVCodecContext ctx; + AVCodecContext ctx = {0}; ctx.sample_rate = sample_rate; flv_set_audio_codec(s, st, &ctx, flags & FLV_AUDIO_CODECID_MASK); sample_rate = ctx.sample_rate; @@ -938,6 +938,10 @@ retry_duration: flv->wrong_dts = 1; av_log(s, AV_LOG_WARNING, "negative cts, previous timestamps might be wrong\n"); + } else if (FFABS(dts - pts) > 1000*60*15) { + av_log(s, AV_LOG_WARNING, + "invalid timestamps %"PRId64" %"PRId64"\n", dts, pts); + dts = pts = AV_NOPTS_VALUE; } if (flv->wrong_dts) dts = AV_NOPTS_VALUE; diff --git a/libavformat/flvenc.c b/libavformat/flvenc.c index 922410386e..31f23712ce 100644 --- a/libavformat/flvenc.c +++ b/libavformat/flvenc.c @@ -222,6 +222,18 @@ static int flv_write_header(AVFormatContext *s) avcodec_get_name(enc->codec_id), i); return AVERROR(EINVAL); } + if (enc->codec_id == AV_CODEC_ID_MPEG4 || + enc->codec_id == AV_CODEC_ID_H263) { + int error = enc->strict_std_compliance > FF_COMPLIANCE_UNOFFICIAL; + av_log(s, error ? AV_LOG_ERROR : AV_LOG_WARNING, + "Codec %s is not supported in the official FLV specification,\n", avcodec_get_name(enc->codec_id)); + + if (error) { + av_log(s, AV_LOG_ERROR, + "use vstrict=-1 / -strict -1 to use it anyway.\n"); + return AVERROR(EINVAL); + } + } break; case AVMEDIA_TYPE_AUDIO: if (audio_enc) { @@ -472,7 +484,7 @@ static int flv_write_packet(AVFormatContext *s, AVPacket *pkt) avio_w8(pb, FLV_TAG_TYPE_VIDEO); flags = enc->codec_tag; - if (flags == 0) { + if (flags <= 0 || flags > 15) { av_log(s, AV_LOG_ERROR, "Video codec '%s' is not compatible with FLV\n", avcodec_get_name(enc->codec_id)); diff --git a/libavformat/format.c b/libavformat/format.c index ac9100b604..36c0131c12 100644 --- a/libavformat/format.c +++ b/libavformat/format.c @@ -54,7 +54,7 @@ void av_register_input_format(AVInputFormat *format) AVInputFormat **p = &first_iformat; format->next = NULL; - while(avpriv_atomic_ptr_cas((void * volatile *)p, NULL, format)) + while(*p || avpriv_atomic_ptr_cas((void * volatile *)p, NULL, format)) p = &(*p)->next; } @@ -63,7 +63,7 @@ void av_register_output_format(AVOutputFormat *format) AVOutputFormat **p = &first_oformat; format->next = NULL; - while(avpriv_atomic_ptr_cas((void * volatile *)p, NULL, format)) + while(*p || avpriv_atomic_ptr_cas((void * volatile *)p, NULL, format)) p = &(*p)->next; } diff --git a/libavformat/gxf.c b/libavformat/gxf.c index e15d06aaf9..c0a38171fc 100644 --- a/libavformat/gxf.c +++ b/libavformat/gxf.c @@ -556,7 +556,7 @@ static int gxf_packet(AVFormatContext *s, AVPacket *pkt) { } static int gxf_seek(AVFormatContext *s, int stream_index, int64_t timestamp, int flags) { - int res = 0; + int64_t res = 0; uint64_t pos; uint64_t maxlen = 100 * 1024 * 1024; AVStream *st = s->streams[0]; diff --git a/libavformat/h263dec.c b/libavformat/h263dec.c index e6e0345b69..19ed6a94ca 100644 --- a/libavformat/h263dec.c +++ b/libavformat/h263dec.c @@ -35,7 +35,7 @@ static int h263_probe(AVProbeData *p) for(i=0; ibuf_size; i++){ code = (code<<8) + p->buf[i]; if ((code & 0xfffffc0000) == 0x800000) { - src_fmt= (code>>2)&3; + src_fmt= (code>>2)&7; if( src_fmt != last_src_fmt && last_src_fmt>0 && last_src_fmt<6 && src_fmt<6) diff --git a/libavformat/hlsenc.c b/libavformat/hlsenc.c index dcd53e5f40..6f5fe1eb87 100644 --- a/libavformat/hlsenc.c +++ b/libavformat/hlsenc.c @@ -306,9 +306,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/http.c b/libavformat/http.c index c5b5c53814..9be1181f30 100644 --- a/libavformat/http.c +++ b/libavformat/http.c @@ -95,7 +95,7 @@ static const AVOption options[] = { {"multiple_requests", "use persistent connections", OFFSET(multiple_requests), AV_OPT_TYPE_INT, {.i64 = 0}, 0, 1, D|E }, {"post_data", "set custom HTTP post data", OFFSET(post_data), AV_OPT_TYPE_BINARY, .flags = D|E }, {"mime_type", "set MIME type", OFFSET(mime_type), AV_OPT_TYPE_STRING, {0}, 0, 0, 0 }, -{"cookies", "set cookies to be sent in applicable future requests, use newline delimited Set-Cookie HTTP field value syntax", OFFSET(cookies), AV_OPT_TYPE_STRING, {0}, 0, 0, 0 }, +{"cookies", "set cookies to be sent in applicable future requests, use newline delimited Set-Cookie HTTP field value syntax", OFFSET(cookies), AV_OPT_TYPE_STRING, {0}, 0, 0, D }, {"icy", "request ICY metadata", OFFSET(icy), AV_OPT_TYPE_INT, {.i64 = 0}, 0, 1, D }, {"icy_metadata_headers", "return ICY metadata headers", OFFSET(icy_metadata_headers), AV_OPT_TYPE_STRING, {0}, 0, 0, 0 }, {"icy_metadata_packet", "return current ICY metadata packet", OFFSET(icy_metadata_packet), AV_OPT_TYPE_STRING, {0}, 0, 0, 0 }, diff --git a/libavformat/id3v2.c b/libavformat/id3v2.c index 4bc76a321c..a3434c9d80 100644 --- a/libavformat/id3v2.c +++ b/libavformat/id3v2.c @@ -815,16 +815,25 @@ error: } void ff_id3v2_read(AVFormatContext *s, const char *magic, - ID3v2ExtraMeta **extra_meta) + ID3v2ExtraMeta **extra_meta, unsigned int max_search_size) { int len, ret; uint8_t buf[ID3v2_HEADER_SIZE]; int found_header; - int64_t off; + int64_t start, off; + if (max_search_size && max_search_size < ID3v2_HEADER_SIZE) + return; + + start = avio_tell(s->pb); do { /* save the current offset in case there's nothing to read/skip */ off = avio_tell(s->pb); + if (max_search_size && off - start >= max_search_size - ID3v2_HEADER_SIZE) { + avio_seek(s->pb, off, SEEK_SET); + break; + } + ret = avio_read(s->pb, buf, ID3v2_HEADER_SIZE); if (ret != ID3v2_HEADER_SIZE) { avio_seek(s->pb, off, SEEK_SET); @@ -860,6 +869,8 @@ void ff_id3v2_free_extra_meta(ID3v2ExtraMeta **extra_meta) av_freep(¤t); current = next; } + + *extra_meta = NULL; } int ff_id3v2_parse_apic(AVFormatContext *s, ID3v2ExtraMeta **extra_meta) diff --git a/libavformat/id3v2.h b/libavformat/id3v2.h index e893922133..25d37f37d0 100644 --- a/libavformat/id3v2.h +++ b/libavformat/id3v2.h @@ -92,8 +92,10 @@ int ff_id3v2_tag_len(const uint8_t *buf); * Read an ID3v2 tag, including supported extra metadata * @param extra_meta If not NULL, extra metadata is parsed into a list of * ID3v2ExtraMeta structs and *extra_meta points to the head of the list + * @param[opt] max_search_search restrict ID3 magic number search (bytes from start) */ -void ff_id3v2_read(AVFormatContext *s, const char *magic, ID3v2ExtraMeta **extra_meta); +void ff_id3v2_read(AVFormatContext *s, const char *magic, ID3v2ExtraMeta **extra_meta, + unsigned int max_search_size); /** * Initialize an ID3v2 tag. diff --git a/libavformat/idcin.c b/libavformat/idcin.c index 9671fca6f8..e45376f0fa 100644 --- a/libavformat/idcin.c +++ b/libavformat/idcin.c @@ -357,7 +357,7 @@ static int idcin_read_seek(AVFormatContext *s, int stream_index, IdcinDemuxContext *idcin = s->priv_data; if (idcin->first_pkt_pos > 0) { - int ret = avio_seek(s->pb, idcin->first_pkt_pos, SEEK_SET); + int64_t ret = avio_seek(s->pb, idcin->first_pkt_pos, SEEK_SET); if (ret < 0) return ret; ff_update_cur_dts(s, s->streams[idcin->video_stream_index], 0); diff --git a/libavformat/img2enc.c b/libavformat/img2enc.c index 8adf3526a6..56aa5fca22 100644 --- a/libavformat/img2enc.c +++ b/libavformat/img2enc.c @@ -21,6 +21,7 @@ */ #include "libavutil/intreadwrite.h" +#include "libavutil/avassert.h" #include "libavutil/avstring.h" #include "libavutil/log.h" #include "libavutil/opt.h" @@ -37,6 +38,7 @@ typedef struct { char path[1024]; int update; int use_strftime; + const char *muxer; } VideoMuxData; static int write_header(AVFormatContext *s) @@ -44,7 +46,6 @@ static int write_header(AVFormatContext *s) VideoMuxData *img = s->priv_data; AVStream *st = s->streams[0]; const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(st->codec->pix_fmt); - const char *str; av_strlcpy(img->path, s->filename, sizeof(img->path)); @@ -54,14 +55,18 @@ static int write_header(AVFormatContext *s) else img->is_pipe = 1; - str = strrchr(img->path, '.'); + if (st->codec->codec_id == AV_CODEC_ID_GIF) { + img->muxer = "gif"; + } else if (st->codec->codec_id == AV_CODEC_ID_RAWVIDEO) { + const char *str = strrchr(img->path, '.'); + /* TODO: reindent */ img->split_planes = str && !av_strcasecmp(str + 1, "y") && s->nb_streams == 1 - && st->codec->codec_id == AV_CODEC_ID_RAWVIDEO && desc &&(desc->flags & AV_PIX_FMT_FLAG_PLANAR) && desc->nb_components >= 3; + } return 0; } @@ -124,6 +129,37 @@ static int write_packet(AVFormatContext *s, AVPacket *pkt) avio_write(pb[3], pkt->data + ysize + 2*usize, ysize); avio_close(pb[3]); } + } else if (img->muxer) { + int ret; + AVStream *st; + AVPacket pkt2 = {0}; + AVFormatContext *fmt = NULL; + + av_assert0(!img->split_planes); + + ret = avformat_alloc_output_context2(&fmt, NULL, img->muxer, s->filename); + if (ret < 0) + return ret; + st = avformat_new_stream(fmt, NULL); + if (!st) { + avformat_free_context(fmt); + return AVERROR(ENOMEM); + } + st->id = pkt->stream_index; + + fmt->pb = pb[0]; + if ((ret = av_copy_packet(&pkt2, pkt)) < 0 || + (ret = av_dup_packet(&pkt2)) < 0 || + (ret = avcodec_copy_context(st->codec, s->streams[0]->codec)) < 0 || + (ret = avformat_write_header(fmt, NULL)) < 0 || + (ret = av_interleaved_write_frame(fmt, &pkt2)) < 0 || + (ret = av_write_trailer(fmt)) < 0) { + av_free_packet(&pkt2); + avformat_free_context(fmt); + return ret; + } + av_free_packet(&pkt2); + avformat_free_context(fmt); } else { avio_write(pb[0], pkt->data, pkt->size); } diff --git a/libavformat/ipmovie.c b/libavformat/ipmovie.c index 676363b628..368c05922d 100644 --- a/libavformat/ipmovie.c +++ b/libavformat/ipmovie.c @@ -376,7 +376,7 @@ static int process_ipmovie_chunk(IPMVEContext *s, AVIOContext *pb, case OPCODE_INIT_VIDEO_BUFFERS: av_dlog(NULL, "initialize video buffers\n"); - if ((opcode_version > 2) || (opcode_size > 8)) { + if ((opcode_version > 2) || (opcode_size > 8) || opcode_size < 4) { av_dlog(NULL, "bad init_video_buffers opcode\n"); chunk_type = CHUNK_BAD; break; diff --git a/libavformat/isom.h b/libavformat/isom.h index 828e5005ad..9fc30d418a 100644 --- a/libavformat/isom.h +++ b/libavformat/isom.h @@ -164,6 +164,7 @@ typedef struct MOVContext { int64_t next_root_atom; ///< offset of the next root atom int *bitrates; ///< bitrates read before streams creation int bitrates_count; + int atom_depth; } MOVContext; int ff_mp4_read_descr_len(AVIOContext *pb); diff --git a/libavformat/libssh.c b/libavformat/libssh.c index 4a9b8674cf..5d5b91ff80 100644 --- a/libavformat/libssh.c +++ b/libavformat/libssh.c @@ -159,7 +159,7 @@ static int64_t libssh_seek(URLContext *h, int64_t pos, int whence) newpos = pos; break; case SEEK_CUR: - newpos = sftp_tell64(s->file); + newpos = sftp_tell64(s->file) + pos; break; case SEEK_END: newpos = s->filesize + pos; diff --git a/libavformat/m4vdec.c b/libavformat/m4vdec.c index c2fd4d7ab6..7a8f79fe7e 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 52e095f447..e52245dd90 100644 --- a/libavformat/matroskadec.c +++ b/libavformat/matroskadec.c @@ -62,6 +62,7 @@ typedef enum { EBML_NEST, EBML_PASS, EBML_STOP, + EBML_SINT, EBML_TYPE_COUNT } EbmlType; @@ -292,7 +293,7 @@ typedef struct { EbmlBin bin; uint64_t additional_id; EbmlBin additional; - uint64_t discard_padding; + int64_t discard_padding; } MatroskaBlock; static EbmlSyntax ebml_header[] = { @@ -570,8 +571,8 @@ static EbmlSyntax matroska_blockgroup[] = { { MATROSKA_ID_BLOCKADDITIONS, EBML_NEST, 0, 0, {.n=matroska_blockadditions} }, { MATROSKA_ID_SIMPLEBLOCK, EBML_BIN, 0, offsetof(MatroskaBlock,bin) }, { MATROSKA_ID_BLOCKDURATION, EBML_UINT, 0, offsetof(MatroskaBlock,duration) }, - { MATROSKA_ID_DISCARDPADDING, EBML_UINT, 0, offsetof(MatroskaBlock,discard_padding) }, - { MATROSKA_ID_BLOCKREFERENCE, EBML_UINT, 0, offsetof(MatroskaBlock,reference) }, + { MATROSKA_ID_DISCARDPADDING, EBML_SINT, 0, offsetof(MatroskaBlock,discard_padding) }, + { MATROSKA_ID_BLOCKREFERENCE, EBML_SINT, 0, offsetof(MatroskaBlock,reference) }, { MATROSKA_ID_CODECSTATE, EBML_NONE }, { 1, EBML_UINT, 0, offsetof(MatroskaBlock,non_simple), {.u=1} }, { 0 } @@ -758,6 +759,30 @@ static int ebml_read_uint(AVIOContext *pb, int size, uint64_t *num) return 0; } +/* + * Read the next element as a signed int. + * 0 is success, < 0 is failure. + */ +static int ebml_read_sint(AVIOContext *pb, int size, int64_t *num) +{ + int n = 1; + + if (size > 8) + return AVERROR_INVALIDDATA; + + if (size == 0) { + *num = 0; + } else { + *num = sign_extend(avio_r8(pb), 8); + + /* big-endian ordering; build up number */ + while (n++ < size) + *num = (*num << 8) | avio_r8(pb); + } + + return 0; +} + /* * Read the next element as a float. * 0 is success, < 0 is failure. @@ -985,6 +1010,7 @@ static int ebml_parse_elem(MatroskaDemuxContext *matroska, switch (syntax->type) { case EBML_UINT: res = ebml_read_uint (pb, length, data); break; + case EBML_SINT: res = ebml_read_sint (pb, length, data); break; case EBML_FLOAT: res = ebml_read_float (pb, length, data); break; case EBML_STR: case EBML_UTF8: res = ebml_read_ascii (pb, length, data); break; @@ -1023,7 +1049,7 @@ static void ebml_free(EbmlSyntax *syntax, void *data) char *ptr = list->elem; for (j=0; jnb_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: break; @@ -1399,13 +1425,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; @@ -1697,8 +1727,12 @@ static int matroska_read_header(AVFormatContext *s) } else if (!strcmp(track->codec_id, "V_QUICKTIME") && (track->codec_priv.size >= 86) && (track->codec_priv.data != NULL)) { - fourcc = AV_RL32(track->codec_priv.data); + fourcc = AV_RL32(track->codec_priv.data + 4); codec_id = ff_codec_get_id(ff_codec_movvideo_tags, fourcc); + if (ff_codec_get_id(ff_codec_movvideo_tags, AV_RL32(track->codec_priv.data))) { + fourcc = AV_RL32(track->codec_priv.data); + codec_id = ff_codec_get_id(ff_codec_movvideo_tags, fourcc); + } } else if (codec_id == AV_CODEC_ID_PCM_S16BE) { switch (track->audio.bitdepth) { case 8: codec_id = AV_CODEC_ID_PCM_U8; break; @@ -1777,7 +1811,7 @@ static int matroska_read_header(AVFormatContext *s) track->audio.sub_packet_h = avio_rb16(&b); track->audio.frame_size = avio_rb16(&b); track->audio.sub_packet_size = avio_rb16(&b); - if (flavor <= 0 || track->audio.coded_framesize <= 0 || + if (flavor < 0 || track->audio.coded_framesize <= 0 || track->audio.sub_packet_h <= 0 || track->audio.frame_size <= 0 || track->audio.sub_packet_size <= 0) return AVERROR_INVALIDDATA; @@ -1808,7 +1842,7 @@ static int matroska_read_header(AVFormatContext *s) avpriv_set_pts_info(st, 64, matroska->time_scale*track->time_scale, 1000*1000*1000); /* 64 bit pts in ns */ st->codec->codec_id = codec_id; - st->start_time = 0; + if (strcmp(track->language, "und")) av_dict_set(&st->metadata, "language", track->language, 0); av_dict_set(&st->metadata, "title", track->name, 0); @@ -1849,7 +1883,7 @@ static int matroska_read_header(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 * 1000LL) st->r_frame_rate = st->avg_frame_rate; #endif } @@ -1880,6 +1914,7 @@ static int matroska_read_header(AVFormatContext *s) st->codec->codec_type = AVMEDIA_TYPE_AUDIO; st->codec->sample_rate = track->audio.out_samplerate; st->codec->channels = track->audio.channels; + if (!st->codec->bits_per_coded_sample) st->codec->bits_per_coded_sample = track->audio.bitdepth; if (st->codec->codec_id != AV_CODEC_ID_AAC) st->need_parsing = AVSTREAM_PARSE_HEADERS; @@ -1973,7 +2008,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], @@ -2003,7 +2038,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; @@ -2152,7 +2187,7 @@ static int matroska_parse_rm_audio(MatroskaDemuxContext *matroska, } memcpy(track->audio.buf + y*w, data, w); } else { - if (size < sps * w / sps || h<=0) { + if (size < sps * w / sps || h<=0 || w%sps) { av_log(matroska->ctx, AV_LOG_ERROR, "Corrupt generic RM-style audio packet size\n"); return AVERROR_INVALIDDATA; @@ -2389,7 +2424,7 @@ static int matroska_parse_frame(MatroskaDemuxContext *matroska, uint64_t timecode, uint64_t lace_duration, int64_t pos, int is_keyframe, uint8_t *additional, uint64_t additional_id, int additional_size, - uint64_t discard_padding) + int64_t discard_padding) { MatroskaTrackEncoding *encodings = track->encodings.elem; uint8_t *pkt_data = data; @@ -2526,7 +2561,7 @@ static int matroska_parse_block(MatroskaDemuxContext *matroska, uint8_t *data, int size, int64_t pos, uint64_t cluster_time, uint64_t block_duration, int is_keyframe, uint8_t *additional, uint64_t additional_id, int additional_size, - int64_t cluster_pos, uint64_t discard_padding) + int64_t cluster_pos, int64_t discard_padding) { uint64_t timecode = AV_NOPTS_VALUE; MatroskaTrack *track; @@ -2762,7 +2797,7 @@ static int matroska_read_seek(AVFormatContext *s, int stream_index, int64_t timestamp, int flags) { MatroskaDemuxContext *matroska = s->priv_data; - MatroskaTrack *tracks = matroska->tracks.elem; + MatroskaTrack *tracks = NULL; AVStream *st = s->streams[stream_index]; int i, index, index_sub, index_min; @@ -2791,6 +2826,7 @@ static int matroska_read_seek(AVFormatContext *s, int stream_index, goto err; index_min = index; + tracks = matroska->tracks.elem; for (i=0; i < matroska->tracks.nb_elem; i++) { tracks[i].audio.pkt_cnt = 0; tracks[i].audio.sub_packet_cnt = 0; @@ -2843,7 +2879,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 b9848b66a5..8bc13f12e9 100644 --- a/libavformat/matroskaenc.c +++ b/libavformat/matroskaenc.c @@ -202,6 +202,19 @@ static void put_ebml_uint(AVIOContext *pb, unsigned int elementid, uint64_t val) avio_w8(pb, (uint8_t)(val >> i*8)); } +static void put_ebml_sint(AVIOContext *pb, unsigned int elementid, int64_t val) +{ + int i, bytes = 1; + uint64_t tmp = 2*(val < 0 ? val^-1 : val); + + while (tmp>>=8) bytes++; + + put_ebml_id(pb, elementid); + put_ebml_num(pb, bytes, 0); + for (i = bytes - 1; i >= 0; i--) + avio_w8(pb, (uint8_t)(val >> i*8)); +} + static void put_ebml_float(AVIOContext *pb, unsigned int elementid, double val) { put_ebml_id(pb, elementid); @@ -533,8 +546,18 @@ static int mkv_write_codecprivate(AVFormatContext *s, AVIOContext *pb, AVCodecCo if (qt_id) { if (!codec->codec_tag) codec->codec_tag = ff_codec_get_tag(ff_codec_movvideo_tags, codec->codec_id); - if (codec->extradata_size) + if (codec->extradata_size) { + if ( ff_codec_get_id(ff_codec_movvideo_tags, codec->codec_tag) == codec->codec_id + && ff_codec_get_id(ff_codec_movvideo_tags, AV_RL32(codec->extradata+4)) != codec->codec_id + ) { + int i; + avio_wb32(dyn_cp, 0x5a + codec->extradata_size); + avio_wl32(dyn_cp, codec->codec_tag); + for(i=0; i<0x5a-8; i++) + avio_w8(dyn_cp, 0); + } avio_write(dyn_cp, codec->extradata, codec->extradata_size); + } } else { if (!codec->codec_tag) codec->codec_tag = ff_codec_get_tag(ff_codec_bmp_tags, codec->codec_id); @@ -544,7 +567,7 @@ static int mkv_write_codecprivate(AVFormatContext *s, AVIOContext *pb, AVCodecCo ret = AVERROR(EINVAL); } - ff_put_bmp_header(dyn_cp, codec, ff_codec_bmp_tags, 0); + ff_put_bmp_header(dyn_cp, codec, ff_codec_bmp_tags, 0, 0); } } else if (codec->codec_type == AVMEDIA_TYPE_AUDIO) { @@ -599,7 +622,7 @@ static int mkv_write_tracks(AVFormatContext *s) continue; } - if (!bit_depth) + if (!bit_depth && codec->codec_id != AV_CODEC_ID_ADPCM_G726) bit_depth = av_get_bytes_per_sample(codec->sample_fmt) << 3; if (!bit_depth) bit_depth = codec->bits_per_coded_sample; @@ -1034,7 +1057,7 @@ static int mkv_write_header(AVFormatContext *s) AVIOContext *pb = s->pb; ebml_master ebml_header, segment_info; AVDictionaryEntry *tag; - int ret, i; + int ret, i, version = 2; if (!strcmp(s->oformat->name, "webm")) mkv->mode = MODE_WEBM; else mkv->mode = MODE_MATROSKAv2; @@ -1042,7 +1065,12 @@ static int mkv_write_header(AVFormatContext *s) if (s->avoid_negative_ts < 0) s->avoid_negative_ts = 1; - for (i = 0; i < s->nb_streams; i++) + if (mkv->mode != MODE_WEBM || + av_dict_get(s->metadata, "stereo_mode", NULL, 0) || + av_dict_get(s->metadata, "alpha_mode", NULL, 0)) + version = 4; + + for (i = 0; i < s->nb_streams; i++) { if (s->streams[i]->codec->codec_id == AV_CODEC_ID_ATRAC3 || s->streams[i]->codec->codec_id == AV_CODEC_ID_COOK || s->streams[i]->codec->codec_id == AV_CODEC_ID_RA_288 || @@ -1054,6 +1082,11 @@ static int mkv_write_header(AVFormatContext *s) avcodec_get_name(s->streams[i]->codec->codec_id)); return AVERROR_PATCHWELCOME; } + if (s->streams[i]->codec->codec_id == AV_CODEC_ID_OPUS || + av_dict_get(s->streams[i]->metadata, "stereo_mode", NULL, 0) || + av_dict_get(s->streams[i]->metadata, "alpha_mode", NULL, 0)) + version = 4; + } mkv->tracks = av_mallocz(s->nb_streams * sizeof(*mkv->tracks)); if (!mkv->tracks) @@ -1065,7 +1098,7 @@ static int mkv_write_header(AVFormatContext *s) put_ebml_uint (pb, EBML_ID_EBMLMAXIDLENGTH , 4); put_ebml_uint (pb, EBML_ID_EBMLMAXSIZELENGTH , 8); put_ebml_string (pb, EBML_ID_DOCTYPE , s->oformat->name); - put_ebml_uint (pb, EBML_ID_DOCTYPEVERSION , 4); + put_ebml_uint (pb, EBML_ID_DOCTYPEVERSION , version); put_ebml_uint (pb, EBML_ID_DOCTYPEREADVERSION , 2); end_ebml_master(pb, ebml_header); @@ -1304,7 +1337,8 @@ static void mkv_write_block(AVFormatContext *s, AVIOContext *pb, uint8_t *data = NULL, *side_data = NULL; int offset = 0, size = pkt->size, side_data_size = 0; int64_t ts = mkv->tracks[pkt->stream_index].write_dts ? pkt->dts : pkt->pts; - uint64_t additional_id = 0, discard_padding = 0; + uint64_t additional_id = 0; + int64_t discard_padding = 0; ebml_master block_group, block_additions, block_more; av_log(s, AV_LOG_DEBUG, "Writing block at offset %" PRIu64 ", size %d, " @@ -1363,7 +1397,7 @@ static void mkv_write_block(AVFormatContext *s, AVIOContext *pb, av_free(data); if (discard_padding) { - put_ebml_uint(pb, MATROSKA_ID_DISCARDPADDING, discard_padding); + put_ebml_sint(pb, MATROSKA_ID_DISCARDPADDING, discard_padding); } if (side_data_size && additional_id == 1) { diff --git a/libavformat/mov.c b/libavformat/mov.c index eec8485b65..e5af31d4e1 100644 --- a/libavformat/mov.c +++ b/libavformat/mov.c @@ -278,7 +278,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); @@ -382,7 +386,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); @@ -1042,15 +1046,17 @@ static int mov_read_targa_y216(MOVContext *c, AVIOContext *pb, MOVAtom atom) static int mov_read_ares(MOVContext *c, AVIOContext *pb, MOVAtom atom) { - AVCodecContext *codec = c->fc->streams[c->fc->nb_streams-1]->codec; - if (codec->codec_tag == MKTAG('A', 'V', 'i', 'n') && - codec->codec_id == AV_CODEC_ID_H264 && - atom.size > 11) { - avio_skip(pb, 10); - /* For AVID AVCI50, force width of 1440 to be able to select the correct SPS and PPS */ - if (avio_rb16(pb) == 0xd4d) - codec->width = 1440; - return 0; + if (c->fc->nb_streams >= 1) { + AVCodecContext *codec = c->fc->streams[c->fc->nb_streams-1]->codec; + if (codec->codec_tag == MKTAG('A', 'V', 'i', 'n') && + codec->codec_id == AV_CODEC_ID_H264 && + atom.size > 11) { + avio_skip(pb, 10); + /* For AVID AVCI50, force width of 1440 to be able to select the correct SPS and PPS */ + if (avio_rb16(pb) == 0xd4d) + codec->width = 1440; + return 0; + } } return mov_read_avid(c, pb, atom); @@ -1191,6 +1197,10 @@ static int mov_read_stco(MOVContext *c, AVIOContext *pb, MOVAtom atom) if (entries >= UINT_MAX/sizeof(int64_t)) return AVERROR_INVALIDDATA; + 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(entries * sizeof(int64_t)); if (!sc->chunk_offsets) return AVERROR(ENOMEM); @@ -1707,6 +1717,10 @@ static int mov_read_stsc(MOVContext *c, AVIOContext *pb, MOVAtom atom) return 0; if (entries >= UINT_MAX / sizeof(*sc->stsc_data)) return AVERROR_INVALIDDATA; + 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(entries * sizeof(*sc->stsc_data)); if (!sc->stsc_data) return AVERROR(ENOMEM); @@ -1779,7 +1793,7 @@ static int mov_read_stss(MOVContext *c, AVIOContext *pb, MOVAtom atom) if (!entries) { sc->keyframe_absent = 1; - if (!st->need_parsing) + if (!st->need_parsing && st->codec->codec_type == AVMEDIA_TYPE_VIDEO) st->need_parsing = AVSTREAM_PARSE_HEADERS; return 0; } @@ -2142,6 +2156,11 @@ static void mov_build_index(MOVContext *mov, AVStream *st) rap_group_index++; } } + if (sc->keyframe_absent + && !sc->stps_count + && !rap_group_present + && st->codec->codec_type == AVMEDIA_TYPE_AUDIO) + keyframe = 1; if (keyframe) distance = 0; sample_size = sc->stsz_sample_size > 0 ? sc->stsz_sample_size : sc->sample_sizes[current_sample]; @@ -2267,7 +2286,7 @@ static int mov_open_dref(AVIOContext **pb, const char *src, MOVDref *ref, /* try relative path, we do not try the absolute because it can leak information about our system to an attacker */ if (ref->nlvl_to > 0 && ref->nlvl_from > 0) { - char filename[1024]; + char filename[1025]; const char *src_path; int i, l; @@ -2293,10 +2312,15 @@ static int mov_open_dref(AVIOContext **pb, const char *src, MOVDref *ref, filename[src_path - src] = 0; for (i = 1; i < ref->nlvl_from; i++) - av_strlcat(filename, "../", 1024); + av_strlcat(filename, "../", sizeof(filename)); - av_strlcat(filename, ref->path + l + 1, 1024); + av_strlcat(filename, ref->path + l + 1, sizeof(filename)); + if (!use_absolute_path) + if(strstr(ref->path + l + 1, "..") || ref->nlvl_from > 1) + return AVERROR(ENOENT); + if (strlen(filename) + 1 == sizeof(filename)) + return AVERROR(ENOENT); if (!avio_open2(pb, filename, AVIO_FLAG_READ, int_cb, NULL)) return 0; } @@ -2762,6 +2786,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); @@ -2977,6 +3002,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)) { @@ -2993,11 +3024,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; } @@ -3029,13 +3061,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; @@ -3055,6 +3090,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/movenc.c b/libavformat/movenc.c index cfb73d7b39..c1ee3ead4d 100644 --- a/libavformat/movenc.c +++ b/libavformat/movenc.c @@ -899,11 +899,14 @@ static AVRational find_fps(AVFormatContext *s, AVStream *st) static int mov_get_mpeg2_xdcam_codec_tag(AVFormatContext *s, MOVTrack *track) { - int tag = MKTAG('m', '2', 'v', '1'); //fallback tag + int tag = track->enc->codec_tag; int interlaced = track->enc->field_order > AV_FIELD_PROGRESSIVE; AVStream *st = track->st; int rate = av_q2d(find_fps(s, st)); + if (!tag) + tag = MKTAG('m', '2', 'v', '1'); //fallback tag + if (track->enc->pix_fmt == AV_PIX_FMT_YUV420P) { if (track->enc->width == 1280 && track->enc->height == 720) { if (!interlaced) { diff --git a/libavformat/mp3enc.c b/libavformat/mp3enc.c index a5f672b257..209ddca1f2 100644 --- a/libavformat/mp3enc.c +++ b/libavformat/mp3enc.c @@ -414,14 +414,14 @@ static int mp3_write_packet(AVFormatContext *s, AVPacket *pkt) if (mp3->pics_to_write) { /* buffer audio packets until we get all the pictures */ AVPacketList *pktl = av_mallocz(sizeof(*pktl)); + int ret; if (!pktl) return AVERROR(ENOMEM); - pktl->pkt = *pkt; - pktl->pkt.buf = av_buffer_ref(pkt->buf); - if (!pktl->pkt.buf) { + ret = av_copy_packet(&pktl->pkt, pkt); + if (ret < 0) { av_freep(&pktl); - return AVERROR(ENOMEM); + return ret; } if (mp3->queue_end) diff --git a/libavformat/mpc.c b/libavformat/mpc.c index 8abc488553..06b4b450b1 100644 --- a/libavformat/mpc.c +++ b/libavformat/mpc.c @@ -153,7 +153,7 @@ static int mpc_read_packet(AVFormatContext *s, AVPacket *pkt) } c->curbits = (curbits + size2) & 0x1F; - if ((ret = av_new_packet(pkt, size)) < 0) + if ((ret = av_new_packet(pkt, size + 4)) < 0) return ret; pkt->data[0] = curbits; diff --git a/libavformat/mpc8.c b/libavformat/mpc8.c index 7017c187f7..4352c78b92 100644 --- a/libavformat/mpc8.c +++ b/libavformat/mpc8.c @@ -57,7 +57,7 @@ typedef struct { static inline int64_t bs_get_v(const uint8_t **bs) { - int64_t v = 0; + uint64_t v = 0; int br = 0; int c; @@ -91,7 +91,7 @@ static int mpc8_probe(AVProbeData *p) size = bs_get_v(&bs); if (size < 2) return 0; - if (bs + size - 2 >= bs_end) + if (size >= bs_end - bs + 2) return AVPROBE_SCORE_EXTENSION - 1; // seems to be valid MPC but no header yet if (header_found) { if (size < 11 || size > 28) @@ -108,7 +108,7 @@ static int mpc8_probe(AVProbeData *p) static inline int64_t gb_get_v(GetBitContext *gb) { - int64_t v = 0; + uint64_t v = 0; int bits = 0; while(get_bits1(gb) && bits < 64-7){ v <<= 7; @@ -216,6 +216,10 @@ static int mpc8_read_header(AVFormatContext *s) while(!url_feof(pb)){ pos = avio_tell(pb); mpc8_get_chunk_header(pb, &tag, &size); + if (size < 0) { + av_log(s, AV_LOG_ERROR, "Invalid chunk length\n"); + return AVERROR_INVALIDDATA; + } if(tag == TAG_STREAMHDR) break; mpc8_handle_chunk(s, tag, pos, size); diff --git a/libavformat/mpegts.c b/libavformat/mpegts.c index 5f2dfe9cb3..b57eaf5908 100644 --- a/libavformat/mpegts.c +++ b/libavformat/mpegts.c @@ -1222,6 +1222,11 @@ static int parse_MP4SLDescrTag(MP4DescrParseContext *d, int64_t off, int len) descr->sl.timestamp_res = avio_rb32(&d->pb); avio_rb32(&d->pb); descr->sl.timestamp_len = avio_r8(&d->pb); + if (descr->sl.timestamp_len > 64) { + avpriv_request_sample(NULL, "timestamp_len > 64"); + descr->sl.timestamp_len = 64; + return AVERROR_PATCHWELCOME; + } descr->sl.ocr_len = avio_r8(&d->pb); descr->sl.au_len = avio_r8(&d->pb); descr->sl.inst_bitrate_len = avio_r8(&d->pb); @@ -1333,7 +1338,7 @@ static void m4sl_cb(MpegTSFilter *filter, const uint8_t *section, int section_le AVStream *st; if (ts->pids[pid]->es_id != mp4_descr[i].es_id) continue; - if (!(ts->pids[pid] && ts->pids[pid]->type == MPEGTS_PES)) { + if (ts->pids[pid]->type != MPEGTS_PES) { av_log(s, AV_LOG_ERROR, "pid %x is not PES\n", pid); continue; } @@ -1761,7 +1766,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", @@ -1976,7 +1981,9 @@ static int read_packet(AVFormatContext *s, uint8_t *buf, int raw_packet_size, co /* check packet sync byte */ if ((*data)[0] != 0x47) { /* find a new packet start */ - avio_seek(pb, -raw_packet_size, SEEK_CUR); + uint64_t pos = avio_tell(pb); + avio_seek(pb, -FFMIN(raw_packet_size, pos), SEEK_CUR); + if (mpegts_resync(s) < 0) return AVERROR(EAGAIN); else diff --git a/libavformat/mpegtsenc.c b/libavformat/mpegtsenc.c index 1d51b97bdf..8045db5675 100644 --- a/libavformat/mpegtsenc.c +++ b/libavformat/mpegtsenc.c @@ -259,7 +259,7 @@ static void mpegts_write_pat(AVFormatContext *s) data, q - data); } -static void mpegts_write_pmt(AVFormatContext *s, MpegTSService *service) +static int mpegts_write_pmt(AVFormatContext *s, MpegTSService *service) { MpegTSWrite *ts = s->priv_data; uint8_t data[1012], *q, *desc_length_ptr, *program_info_length_ptr; @@ -315,6 +315,10 @@ static void mpegts_write_pmt(AVFormatContext *s, MpegTSService *service) stream_type = STREAM_TYPE_PRIVATE_DATA; break; } + + if (q - data > sizeof(data) - 32) + return AVERROR(EINVAL); + *q++ = stream_type; put16(&q, 0xe000 | ts_st->pid); desc_length_ptr = q; @@ -346,7 +350,7 @@ static void mpegts_write_pmt(AVFormatContext *s, MpegTSService *service) len_ptr = q++; *len_ptr = 0; - for (p = lang->value; next && *len_ptr < 255 / 4 * 4; p = next + 1) { + for (p = lang->value; next && *len_ptr < 255 / 4 * 4 && q - data < sizeof(data) - 4; p = next + 1) { next = strchr(p, ','); if (strlen(p) != 3 && (!next || next != p + 3)) continue; /* not a 3-letter code */ @@ -418,6 +422,7 @@ static void mpegts_write_pmt(AVFormatContext *s, MpegTSService *service) } mpegts_write_section1(&service->pmt, PMT_TID, service->sid, ts->tables_version, 0, 0, data, q - data); + return 0; } /* NOTE: str == NULL is accepted for an empty string */ diff --git a/libavformat/mux.c b/libavformat/mux.c index eff7caab25..c012e3ab37 100644 --- a/libavformat/mux.c +++ b/libavformat/mux.c @@ -421,6 +421,12 @@ static int compute_pkt_fields2(AVFormatContext *s, AVStream *st, AVPacket *pkt) av_dlog(s, "compute_pkt_fields2: pts:%s dts:%s cur_dts:%s b:%d size:%d st:%d\n", av_ts2str(pkt->pts), av_ts2str(pkt->dts), av_ts2str(st->cur_dts), delay, pkt->size, pkt->stream_index); + if (pkt->duration < 0 && st->codec->codec_type != AVMEDIA_TYPE_SUBTITLE) { + av_log(s, AV_LOG_WARNING, "Packet with invalid duration %d in stream %d\n", + pkt->duration, pkt->stream_index); + pkt->duration = 0; + } + /* duration field */ if (pkt->duration == 0) { ff_compute_frame_duration(&num, &den, st, NULL, pkt); diff --git a/libavformat/mvdec.c b/libavformat/mvdec.c index 5525233db5..8d6a26cd6c 100644 --- a/libavformat/mvdec.c +++ b/libavformat/mvdec.c @@ -371,7 +371,7 @@ static int mv_read_packet(AVFormatContext *avctx, AVPacket *pkt) AVStream *st = avctx->streams[mv->stream_index]; const AVIndexEntry *index; int frame = mv->frame[mv->stream_index]; - int ret; + int64_t ret; uint64_t pos; if (frame < st->nb_index_entries) { diff --git a/libavformat/mxfdec.c b/libavformat/mxfdec.c index d0cbeead96..e6352de1cc 100644 --- a/libavformat/mxfdec.c +++ b/libavformat/mxfdec.c @@ -484,7 +484,10 @@ static int mxf_read_partition_pack(void *arg, AVIOContext *pb, int tag, int size partition->index_sid = avio_rb32(pb); avio_skip(pb, 8); partition->body_sid = avio_rb32(pb); - avio_read(pb, op, sizeof(UID)); + if (avio_read(pb, op, sizeof(UID)) != sizeof(UID)) { + av_log(mxf->fc, AV_LOG_ERROR, "Failed reading UID\n"); + return AVERROR_INVALIDDATA; + } nb_essence_containers = avio_rb32(pb); /* some files don'thave FooterPartition set in every partition */ @@ -2005,6 +2008,8 @@ static int mxf_read_header(AVFormatContext *s) MXFContext *mxf = s->priv_data; KLVPacket klv; int64_t essence_offset = 0; + int64_t last_pos = -1; + uint64_t last_pos_index = 1; int ret; mxf->last_forward_tell = INT64_MAX; @@ -2022,7 +2027,12 @@ static int mxf_read_header(AVFormatContext *s) while (!url_feof(s->pb)) { const MXFMetadataReadTableEntry *metadata; - + if (avio_tell(s->pb) == last_pos) { + av_log(mxf->fc, AV_LOG_ERROR, "MXF structure loop detected\n"); + return AVERROR_INVALIDDATA; + } + if ((1ULL<<61) % last_pos_index++ == 0) + last_pos = avio_tell(s->pb); if (klv_read_packet(&klv, s->pb) < 0) { /* EOF - seek to previous partition or stop */ if(mxf_parse_handle_partition_or_eof(mxf) <= 0) diff --git a/libavformat/nutdec.c b/libavformat/nutdec.c index aa7ca676fb..0b4b12c00c 100644 --- a/libavformat/nutdec.c +++ b/libavformat/nutdec.c @@ -288,7 +288,7 @@ static int decode_main_header(NUTContext *nut) while (tmp_fields-- > 8) ffio_read_varlen(bc); - if (count == 0 || i + count > 256) { + if (count <= 0 || count > 256 - (i <= 'N') - i) { av_log(s, AV_LOG_ERROR, "illegal count %d at %d\n", count, i); return AVERROR_INVALIDDATA; } @@ -491,6 +491,10 @@ static int decode_info_header(NUTContext *nut) nut->time_base[chapter_start % nut->time_base_count], start, start + chapter_len, NULL); + if (!chapter) { + av_log(s, AV_LOG_ERROR, "could not create chapter\n"); + return AVERROR(ENOMEM); + } metadata = &chapter->metadata; } else if (stream_id_plus1) { st = s->streams[stream_id_plus1 - 1]; @@ -534,7 +538,8 @@ static int decode_info_header(NUTContext *nut) if (stream_id_plus1 && !strcmp(name, "r_frame_rate")) { sscanf(str_value, "%d/%d", &st->r_frame_rate.num, &st->r_frame_rate.den); - if (st->r_frame_rate.num >= 1000LL*st->r_frame_rate.den) + if (st->r_frame_rate.num >= 1000LL*st->r_frame_rate.den || + st->r_frame_rate.num < 0 || st->r_frame_rate.num < 0) st->r_frame_rate.num = st->r_frame_rate.den = 0; continue; } diff --git a/libavformat/nutenc.c b/libavformat/nutenc.c index b6d754d595..08223545b7 100644 --- a/libavformat/nutenc.c +++ b/libavformat/nutenc.c @@ -584,8 +584,15 @@ static int write_index(NUTContext *nut, AVIOContext *bc) { int64_t last_pts= -1; int j, k; for (j=0; jsp_count; j++) { - int flag = (nus->keyframe_pts[j] != AV_NOPTS_VALUE) ^ (j+1 == nut->sp_count); + int flag; int n = 0; + + if (j && nus->keyframe_pts[j] == nus->keyframe_pts[j-1]) { + av_log(nut->avf, AV_LOG_WARNING, "Multiple keyframes with same PTS\n"); + nus->keyframe_pts[j] = AV_NOPTS_VALUE; + } + + flag = (nus->keyframe_pts[j] != AV_NOPTS_VALUE) ^ (j+1 == nut->sp_count); for (; jsp_count && (nus->keyframe_pts[j] != AV_NOPTS_VALUE) == flag; j++) n++; diff --git a/libavformat/oggdec.c b/libavformat/oggdec.c index a099eb382e..d6e09b4e08 100644 --- a/libavformat/oggdec.c +++ b/libavformat/oggdec.c @@ -780,7 +780,6 @@ retry: 10); if(side_data == NULL) { av_free_packet(pkt); - av_free(pkt); return AVERROR(ENOMEM); } AV_WL32(side_data + 4, os->end_trimming); @@ -805,6 +804,11 @@ static int64_t ogg_read_timestamp(AVFormatContext *s, int stream_index, && !ogg_packet(s, &i, &pstart, &psize, pos_arg)) { if (i == stream_index) { struct ogg_stream *os = ogg->streams + stream_index; + // Dont trust the last timestamps of a ogm video + if ( (os->flags & OGG_FLAG_EOS) + && !(os->flags & OGG_FLAG_BOS) + && os->codec == &ff_ogm_video_codec) + continue; pts = ogg_calc_pts(s, i, NULL); ogg_validate_keyframe(s, i, pstart, psize); if (os->pflags & AV_PKT_FLAG_KEY) { diff --git a/libavformat/oggenc.c b/libavformat/oggenc.c index 1883501745..6b90a5ce80 100644 --- a/libavformat/oggenc.c +++ b/libavformat/oggenc.c @@ -255,7 +255,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, @@ -263,10 +263,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/oggparseopus.c b/libavformat/oggparseopus.c index 78aa333187..86aaaf53e0 100644 --- a/libavformat/oggparseopus.c +++ b/libavformat/oggparseopus.c @@ -81,6 +81,26 @@ static int opus_header(AVFormatContext *avf, int idx) return 0; } +static int opus_duration(uint8_t *src, int size) +{ + unsigned nb_frames = 1; + unsigned toc = src[0]; + unsigned toc_config = toc >> 3; + unsigned toc_count = toc & 3; + unsigned frame_size = toc_config < 12 ? FFMAX(480, 960 * (toc_config & 3)) : + toc_config < 16 ? 480 << (toc_config & 1) : + 120 << (toc_config & 3); + if (toc_count == 3) { + if (size<2) + return AVERROR_INVALIDDATA; + nb_frames = src[1] & 0x3F; + } else if (toc_count) { + nb_frames = 2; + } + + return frame_size * nb_frames; +} + static int opus_packet(AVFormatContext *avf, int idx) { struct ogg *ogg = avf->priv_data; @@ -88,26 +108,46 @@ static int opus_packet(AVFormatContext *avf, int idx) AVStream *st = avf->streams[idx]; struct oggopus_private *priv = os->private; uint8_t *packet = os->buf + os->pstart; - unsigned toc, toc_config, toc_count, frame_size, nb_frames = 1; + int ret; if (!os->psize) return AVERROR_INVALIDDATA; - toc = *packet; - toc_config = toc >> 3; - toc_count = toc & 3; - frame_size = toc_config < 12 ? FFMAX(480, 960 * (toc_config & 3)) : - toc_config < 16 ? 480 << (toc_config & 1) : - 120 << (toc_config & 3); - if (toc_count == 3) { - if (os->psize < 2) - return AVERROR_INVALIDDATA; - nb_frames = packet[1] & 0x3F; - } else if (toc_count) { - nb_frames = 2; + if ((!os->lastpts || os->lastpts == AV_NOPTS_VALUE) && !(os->flags & OGG_FLAG_EOS)) { + int seg, d; + int duration; + uint8_t *last_pkt = os->buf + os->pstart; + uint8_t *next_pkt = last_pkt; + + duration = 0; + seg = os->segp; + d = opus_duration(last_pkt, os->psize); + if (d < 0) { + os->pflags |= AV_PKT_FLAG_CORRUPT; + return 0; + } + duration += d; + last_pkt = next_pkt = next_pkt + os->psize; + for (; seg < os->nsegs; seg++) { + if (os->segments[seg] < 255) { + int d = opus_duration(last_pkt, os->segments[seg]); + if (d < 0) { + duration = os->granule; + break; + } + duration += d; + last_pkt = next_pkt + os->segments[seg]; + } + next_pkt += os->segments[seg]; + } + os->lastpts = + os->lastdts = os->granule - duration; } - os->pduration = frame_size * nb_frames; + if ((ret = opus_duration(packet, os->psize)) < 0) + return ret; + + os->pduration = ret; if (os->lastpts != AV_NOPTS_VALUE) { if (st->start_time == AV_NOPTS_VALUE) st->start_time = os->lastpts; diff --git a/libavformat/oggparsevorbis.c b/libavformat/oggparsevorbis.c index 36ad7384ea..14c7ddd04f 100644 --- a/libavformat/oggparsevorbis.c +++ b/libavformat/oggparsevorbis.c @@ -351,7 +351,7 @@ static int vorbis_packet(AVFormatContext *s, int idx) * here we parse the duration of each packet in the first page and compare * the total duration to the page granule to find the encoder delay and * set the first timestamp */ - if ((!os->lastpts || os->lastpts == AV_NOPTS_VALUE) && !(os->flags & OGG_FLAG_EOS)) { + if ((!os->lastpts || os->lastpts == AV_NOPTS_VALUE) && !(os->flags & OGG_FLAG_EOS) && (int64_t)os->granule>=0) { int seg, d; uint8_t *last_pkt = os->buf + os->pstart; uint8_t *next_pkt = last_pkt; diff --git a/libavformat/omadec.c b/libavformat/omadec.c index 4017db3f2b..f5d09f65ae 100644 --- a/libavformat/omadec.c +++ b/libavformat/omadec.c @@ -171,7 +171,7 @@ static int nprobe(AVFormatContext *s, uint8_t *enc_header, unsigned size, taglen = AV_RB32(&enc_header[pos + 32]); datalen = AV_RB32(&enc_header[pos + 36]) >> 4; - pos += 44L + taglen; + pos += 44LL + taglen; if (pos + (((uint64_t)datalen) << 4) > size) return -1; @@ -293,7 +293,7 @@ static int oma_read_header(AVFormatContext *s) ID3v2ExtraMeta *extra_meta = NULL; OMAContext *oc = s->priv_data; - ff_id3v2_read(s, ID3v2_EA3_MAGIC, &extra_meta); + ff_id3v2_read(s, ID3v2_EA3_MAGIC, &extra_meta, 0); ret = avio_read(s->pb, buf, EA3_HEADER_SIZE); if (ret < EA3_HEADER_SIZE) return -1; @@ -470,7 +470,7 @@ static int oma_read_seek(struct AVFormatContext *s, int stream_index, int64_t timestamp, int flags) { OMAContext *oc = s->priv_data; - int err = ff_pcm_read_seek(s, stream_index, timestamp, flags); + int64_t err = ff_pcm_read_seek(s, stream_index, timestamp, flags); if (!oc->encrypted) return err; diff --git a/libavformat/pjsdec.c b/libavformat/pjsdec.c index a69a31660d..6f5db37886 100644 --- a/libavformat/pjsdec.c +++ b/libavformat/pjsdec.c @@ -53,7 +53,8 @@ static int64_t read_ts(char **line, int *duration) int64_t start, end; if (sscanf(*line, "%"SCNd64",%"SCNd64, &start, &end) == 2) { - *line += strcspn(*line, "\"") + 1; + *line += strcspn(*line, "\""); + *line += !!**line; *duration = end - start; return start; } diff --git a/libavformat/riff.h b/libavformat/riff.h index 1bf437e06c..ce078698c2 100644 --- a/libavformat/riff.h +++ b/libavformat/riff.h @@ -45,7 +45,7 @@ void ff_end_tag(AVIOContext *pb, int64_t start); */ int ff_get_bmp_header(AVIOContext *pb, AVStream *st, unsigned *esize); -void ff_put_bmp_header(AVIOContext *pb, AVCodecContext *enc, const AVCodecTag *tags, int for_asf); +void ff_put_bmp_header(AVIOContext *pb, AVCodecContext *enc, const AVCodecTag *tags, int for_asf, int ignore_extradata); int ff_put_wav_header(AVIOContext *pb, AVCodecContext *enc); enum AVCodecID ff_wav_codec_get_id(unsigned int tag, int bps); int ff_get_wav_header(AVIOContext *pb, AVCodecContext *codec, int size); diff --git a/libavformat/riffenc.c b/libavformat/riffenc.c index bcfe018f74..183fb7f525 100644 --- a/libavformat/riffenc.c +++ b/libavformat/riffenc.c @@ -201,13 +201,17 @@ int ff_put_wav_header(AVIOContext *pb, AVCodecContext *enc) /* BITMAPINFOHEADER header */ void ff_put_bmp_header(AVIOContext *pb, AVCodecContext *enc, - const AVCodecTag *tags, int for_asf) + 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 + 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 */ @@ -220,10 +224,12 @@ void ff_put_bmp_header(AVIOContext *pb, AVCodecContext *enc, avio_wl32(pb, 0); avio_wl32(pb, 0); - avio_write(pb, enc->extradata, enc->extradata_size); + if (!ignore_extradata) { + avio_write(pb, enc->extradata, extradata_size); - if (!for_asf && enc->extradata_size & 1) - avio_w8(pb, 0); + if (!for_asf && extradata_size & 1) + avio_w8(pb, 0); + } } void ff_parse_specific_params(AVCodecContext *stream, int *au_rate, diff --git a/libavformat/rmdec.c b/libavformat/rmdec.c index b0876fe5bd..3fa0200a3d 100644 --- a/libavformat/rmdec.c +++ b/libavformat/rmdec.c @@ -257,16 +257,6 @@ static int rm_read_audio_stream_info(AVFormatContext *s, AVIOContext *pb, default: av_strlcpy(st->codec->codec_name, buf, sizeof(st->codec->codec_name)); } - if (ast->deint_id == DEINT_ID_INT4 || - ast->deint_id == DEINT_ID_GENR || - ast->deint_id == DEINT_ID_SIPR) { - if (st->codec->block_align <= 0 || - ast->audio_framesize * sub_packet_h > (unsigned)INT_MAX || - ast->audio_framesize * sub_packet_h < st->codec->block_align) - return AVERROR_INVALIDDATA; - if (av_new_packet(&ast->pkt, ast->audio_framesize * sub_packet_h) < 0) - return AVERROR(ENOMEM); - } switch (ast->deint_id) { case DEINT_ID_INT4: if (ast->coded_framesize > ast->audio_framesize || @@ -288,6 +278,16 @@ static int rm_read_audio_stream_info(AVFormatContext *s, AVIOContext *pb, av_log(s, AV_LOG_ERROR, "Unknown interleaver %X\n", ast->deint_id); return AVERROR_INVALIDDATA; } + if (ast->deint_id == DEINT_ID_INT4 || + ast->deint_id == DEINT_ID_GENR || + ast->deint_id == DEINT_ID_SIPR) { + if (st->codec->block_align <= 0 || + ast->audio_framesize * sub_packet_h > (unsigned)INT_MAX || + ast->audio_framesize * sub_packet_h < st->codec->block_align) + return AVERROR_INVALIDDATA; + if (av_new_packet(&ast->pkt, ast->audio_framesize * sub_packet_h) < 0) + return AVERROR(ENOMEM); + } if (read_all) { avio_r8(pb); @@ -308,6 +308,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); @@ -390,7 +393,11 @@ ff_rm_read_mdpr_codecdata (AVFormatContext *s, AVIOContext *pb, skip: /* skip codec info */ size = avio_tell(pb) - codec_pos; - avio_skip(pb, codec_data_size - size); + if (codec_data_size >= size) { + avio_skip(pb, codec_data_size - size); + } else { + av_log(s, AV_LOG_WARNING, "codec_data_size %u < size %d\n", codec_data_size, size); + } return 0; } @@ -785,6 +792,16 @@ rm_ac3_swap_bytes (AVStream *st, AVPacket *pkt) } } +static int readfull(AVFormatContext *s, AVIOContext *pb, uint8_t *dst, int n) { + int ret = avio_read(pb, dst, n); + if (ret != n) { + if (ret >= 0) memset(dst + ret, 0, n - ret); + else memset(dst , 0, n); + av_log(s, AV_LOG_ERROR, "Failed to fully read block\n"); + } + return ret; +} + int ff_rm_parse_packet (AVFormatContext *s, AVIOContext *pb, AVStream *st, RMStream *ast, int len, AVPacket *pkt, @@ -817,14 +834,14 @@ ff_rm_parse_packet (AVFormatContext *s, AVIOContext *pb, switch (ast->deint_id) { case DEINT_ID_INT4: for (x = 0; x < h/2; x++) - avio_read(pb, ast->pkt.data+x*2*w+y*cfs, cfs); + readfull(s, pb, ast->pkt.data+x*2*w+y*cfs, cfs); break; case DEINT_ID_GENR: for (x = 0; x < w/sps; x++) - avio_read(pb, ast->pkt.data+sps*(h*x+((h+1)/2)*(y&1)+(y>>1)), sps); + readfull(s, pb, ast->pkt.data+sps*(h*x+((h+1)/2)*(y&1)+(y>>1)), sps); break; case DEINT_ID_SIPR: - avio_read(pb, ast->pkt.data + y * w, w); + readfull(s, pb, ast->pkt.data + y * w, w); break; } diff --git a/libavformat/rmenc.c b/libavformat/rmenc.c index 17192ff275..a4e97a02e9 100644 --- a/libavformat/rmenc.c +++ b/libavformat/rmenc.c @@ -391,6 +391,11 @@ static int rm_write_video(AVFormatContext *s, const uint8_t *buf, int size, int /* Well, I spent some time finding the meaning of these bits. I am not sure I understood everything, but it works !! */ #if 1 + /* 0xFFFF is the maximal chunk size; header needs at most 7 + 4 + 12 B */ + if (size > 0xFFFF - 7 - 4 - 12) { + av_log(s, AV_LOG_ERROR, "large packet size %d not supported\n", size); + return AVERROR_PATCHWELCOME; + } write_packet_header(s, stream, size + 7 + (size >= 0x4000)*4, key_frame); /* bit 7: '1' if final packet of a frame converted in several packets */ avio_w8(pb, 0x81); diff --git a/libavformat/rsd.c b/libavformat/rsd.c index 37e544acb1..19d197dfa3 100644 --- a/libavformat/rsd.c +++ b/libavformat/rsd.c @@ -67,7 +67,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/rtpdec_asf.c b/libavformat/rtpdec_asf.c index 123894f275..541b86fe41 100644 --- a/libavformat/rtpdec_asf.c +++ b/libavformat/rtpdec_asf.c @@ -144,6 +144,8 @@ static int asfrtp_parse_sdp_line(AVFormatContext *s, int stream_index, if (s->streams[stream_index]->id == rt->asf_ctx->streams[i]->id) { *s->streams[stream_index]->codec = *rt->asf_ctx->streams[i]->codec; + s->streams[stream_index]->need_parsing = + rt->asf_ctx->streams[i]->need_parsing; rt->asf_ctx->streams[i]->codec->extradata_size = 0; rt->asf_ctx->streams[i]->codec->extradata = NULL; avpriv_set_pts_info(s->streams[stream_index], 32, 1, 1000); diff --git a/libavformat/segafilm.c b/libavformat/segafilm.c index a56568c300..7d33189cf5 100644 --- a/libavformat/segafilm.c +++ b/libavformat/segafilm.c @@ -72,13 +72,22 @@ static int film_probe(AVProbeData *p) return AVPROBE_SCORE_MAX; } +static int film_read_close(AVFormatContext *s) +{ + FilmDemuxContext *film = s->priv_data; + + av_freep(&film->sample_table); + + return 0; +} + static int film_read_header(AVFormatContext *s) { FilmDemuxContext *film = s->priv_data; AVIOContext *pb = s->pb; AVStream *st; unsigned char scratch[256]; - int i; + int i, ret; unsigned int data_offset; unsigned int audio_frame_counter; @@ -203,14 +212,16 @@ static int film_read_header(AVFormatContext *s) for (i = 0; i < film->sample_count; i++) { /* load the next sample record and transfer it to an internal struct */ if (avio_read(pb, scratch, 16) != 16) { - av_freep(&film->sample_table); - return AVERROR(EIO); + ret = AVERROR(EIO); + goto fail; } film->sample_table[i].sample_offset = data_offset + AV_RB32(&scratch[0]); film->sample_table[i].sample_size = AV_RB32(&scratch[4]); - if (film->sample_table[i].sample_size > INT_MAX / 4) - return AVERROR_INVALIDDATA; + if (film->sample_table[i].sample_size > INT_MAX / 4) { + ret = AVERROR_INVALIDDATA; + goto fail; + } if (AV_RB32(&scratch[8]) == 0xFFFFFFFF) { film->sample_table[i].stream = film->audio_stream_index; film->sample_table[i].pts = audio_frame_counter; @@ -231,6 +242,9 @@ static int film_read_header(AVFormatContext *s) film->current_sample = 0; return 0; +fail: + film_read_close(s); + return ret; } static int film_read_packet(AVFormatContext *s, @@ -270,15 +284,6 @@ static int film_read_packet(AVFormatContext *s, return ret; } -static int film_read_close(AVFormatContext *s) -{ - FilmDemuxContext *film = s->priv_data; - - av_freep(&film->sample_table); - - return 0; -} - AVInputFormat ff_segafilm_demuxer = { .name = "film_cpk", .long_name = NULL_IF_CONFIG_SMALL("Sega FILM / CPK"), diff --git a/libavformat/segment.c b/libavformat/segment.c index 05e29d427a..ce4af8bb9e 100644 --- a/libavformat/segment.c +++ b/libavformat/segment.c @@ -646,7 +646,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 { end_pts = seg->time * (seg->segment_count+1); @@ -710,12 +710,6 @@ fail: if (pkt->stream_index == seg->reference_stream_index) seg->frame_count++; - if (ret < 0) { - if (seg->list) - avio_close(seg->list_pb); - avformat_free_context(oc); - } - return ret; } diff --git a/libavformat/smacker.c b/libavformat/smacker.c index 527faf7dd8..cbacb6216d 100644 --- a/libavformat/smacker.c +++ b/libavformat/smacker.c @@ -314,7 +314,7 @@ static int smacker_read_packet(AVFormatContext *s, AVPacket *pkt) int err; size = avio_rl32(s->pb) - 4; - if (!size || size + 4L > frame_size) { + if (!size || size + 4LL > frame_size) { av_log(s, AV_LOG_ERROR, "Invalid audio part size\n"); return AVERROR_INVALIDDATA; } diff --git a/libavformat/spdifdec.c b/libavformat/spdifdec.c index 69843503b0..7da16c95ba 100644 --- a/libavformat/spdifdec.c +++ b/libavformat/spdifdec.c @@ -57,7 +57,7 @@ static int spdif_get_offset_and_codec(AVFormatContext *s, break; case IEC61937_MPEG2_AAC: init_get_bits(&gbc, buf, AAC_ADTS_HEADER_SIZE * 8); - if (avpriv_aac_parse_header(&gbc, &aac_hdr)) { + if (avpriv_aac_parse_header(&gbc, &aac_hdr) < 0) { if (s) /* be silent during a probe */ av_log(s, AV_LOG_ERROR, "Invalid AAC packet in IEC 61937\n"); return AVERROR_INVALIDDATA; diff --git a/libavformat/swfdec.c b/libavformat/swfdec.c index 54e0f6dc0e..43a82b8b0e 100644 --- a/libavformat/swfdec.c +++ b/libavformat/swfdec.c @@ -283,6 +283,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; @@ -347,17 +348,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); @@ -369,14 +374,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 12ea0ea27d..90c9759af5 100644 --- a/libavformat/tee.c +++ b/libavformat/tee.c @@ -468,7 +468,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/thp.c b/libavformat/thp.c index 3717b8f12c..3ef9497b42 100644 --- a/libavformat/thp.c +++ b/libavformat/thp.c @@ -26,15 +26,15 @@ typedef struct ThpDemuxContext { int version; - int first_frame; - int first_framesz; - int last_frame; + unsigned first_frame; + unsigned first_framesz; + unsigned last_frame; int compoff; - int framecnt; + unsigned framecnt; AVRational fps; - int frame; - int next_frame; - int next_framesz; + unsigned frame; + int64_t next_frame; + unsigned next_framesz; int video_stream_index; int audio_stream_index; int compcount; @@ -158,7 +158,7 @@ static int thp_read_packet(AVFormatContext *s, avio_seek(pb, thp->next_frame, SEEK_SET); /* Locate the next frame and read out its size. */ - thp->next_frame += thp->next_framesz; + thp->next_frame += FFMAX(thp->next_framesz, 1); thp->next_framesz = avio_rb32(pb); avio_rb32(pb); /* Previous total size. */ @@ -180,6 +180,8 @@ static int thp_read_packet(AVFormatContext *s, pkt->stream_index = thp->video_stream_index; } else { ret = av_get_packet(pb, pkt, thp->audiosize); + if (ret < 0) + return ret; if (ret != thp->audiosize) { av_free_packet(pkt); return AVERROR(EIO); diff --git a/libavformat/tta.c b/libavformat/tta.c index 7174fd5438..d3b3fb0471 100644 --- a/libavformat/tta.c +++ b/libavformat/tta.c @@ -118,8 +118,10 @@ static int tta_read_header(AVFormatContext *s) ffio_init_checksum(s->pb, tta_check_crc, UINT32_MAX); for (i = 0; i < c->totalframes; i++) { uint32_t size = avio_rl32(s->pb); - av_add_index_entry(st, framepos, i * c->frame_size, size, 0, - AVINDEX_KEYFRAME); + int r; + if ((r = av_add_index_entry(st, framepos, i * c->frame_size, size, 0, + AVINDEX_KEYFRAME)) < 0) + return r; framepos += size; } crc = ffio_get_checksum(s->pb) ^ UINT32_MAX; @@ -153,6 +155,11 @@ static int tta_read_packet(AVFormatContext *s, AVPacket *pkt) if (c->currentframe >= c->totalframes) return AVERROR_EOF; + if (st->nb_index_entries < c->totalframes) { + av_log(s, AV_LOG_ERROR, "Index entry disappeared\n"); + return AVERROR_INVALIDDATA; + } + size = st->index_entries[c->currentframe].size; ret = av_get_packet(s->pb, pkt, size); diff --git a/libavformat/utils.c b/libavformat/utils.c index 265813693a..7e4a6ffc14 100644 --- a/libavformat/utils.c +++ b/libavformat/utils.c @@ -102,6 +102,11 @@ MAKE_ACCESSORS(AVFormatContext, format, AVCodec *, video_codec) MAKE_ACCESSORS(AVFormatContext, format, AVCodec *, audio_codec) MAKE_ACCESSORS(AVFormatContext, format, AVCodec *, subtitle_codec) +struct AVCodecParserContext *av_stream_get_parser(const AVStream *st) +{ + return st->parser; +} + static AVCodec *find_decoder(AVFormatContext *s, AVStream *st, enum AVCodecID codec_id) { if (st->codec->codec) @@ -370,9 +375,6 @@ int av_probe_input_buffer2(AVIOContext *pb, AVInputFormat **fmt, for(probe_size= PROBE_BUF_MIN; probe_size<=max_probe_size && !*fmt; probe_size = FFMIN(probe_size<<1, FFMAX(max_probe_size, probe_size+1))) { - if (probe_size < offset) { - continue; - } score = probe_size < max_probe_size ? AVPROBE_SCORE_RETRY : 0; /* read probe data */ @@ -387,7 +389,10 @@ int av_probe_input_buffer2(AVIOContext *pb, AVInputFormat **fmt, score = 0; ret = 0; /* error was end of file, nothing read */ } - pd.buf_size = buf_offset += ret; + buf_offset += ret; + if (buf_offset < offset) + continue; + pd.buf_size = buf_offset - offset; pd.buf = &buf[offset]; memset(pd.buf + pd.buf_size, 0, AVPROBE_PADDING_SIZE); @@ -408,7 +413,7 @@ int av_probe_input_buffer2(AVIOContext *pb, AVInputFormat **fmt, } /* rewind. reuse probe buffer to avoid seeking */ - ret = ffio_rewind_with_probe_data(pb, &buf, pd.buf_size); + ret = ffio_rewind_with_probe_data(pb, &buf, buf_offset); return ret < 0 ? ret : score; } @@ -503,6 +508,9 @@ int avformat_open_input(AVFormatContext **ps, const char *filename, AVInputForma if (options) av_dict_copy(&tmp, *options, 0); + if (s->pb) // must be before any goto fail + s->flags |= AVFMT_FLAG_CUSTOM_IO; + if ((ret = av_opt_set_dict(s, &tmp)) < 0) goto fail; @@ -538,7 +546,7 @@ int avformat_open_input(AVFormatContext **ps, const char *filename, AVInputForma /* e.g. AVFMT_NOFILE formats will not have a AVIOContext */ if (s->pb) - ff_id3v2_read(s, ID3v2_DEFAULT_MAGIC, &id3v2_extra_meta); + ff_id3v2_read(s, ID3v2_DEFAULT_MAGIC, &id3v2_extra_meta, 0); if (!(s->flags&AVFMT_FLAG_PRIV_OPT) && s->iformat->read_header) if ((ret = s->iformat->read_header(s)) < 0) @@ -1039,7 +1047,8 @@ static void compute_pkt_fields(AVFormatContext *s, AVStream *st, if((s->flags & AVFMT_FLAG_IGNDTS) && pkt->pts != AV_NOPTS_VALUE) pkt->dts= AV_NOPTS_VALUE; - if (st->codec->codec_id != AV_CODEC_ID_H264 && pc && pc->pict_type == AV_PICTURE_TYPE_B) + if (pc && pc->pict_type == AV_PICTURE_TYPE_B + && !st->codec->has_b_frames) //FIXME Set low_delay = 0 when has_b_frames = 1 st->codec->has_b_frames = 1; @@ -1480,7 +1489,8 @@ int av_read_frame(AVFormatContext *s, AVPacket *pkt) } /* read packet from packet buffer, if there is data */ - if (!(next_pkt->pts == AV_NOPTS_VALUE && + st = s->streams[next_pkt->stream_index]; + if (!(next_pkt->pts == AV_NOPTS_VALUE && st->discard < AVDISCARD_ALL && next_pkt->dts != AV_NOPTS_VALUE && !eof)) { ret = read_from_packet_buffer(&s->packet_buffer, &s->packet_buffer_end, pkt); @@ -2667,8 +2677,8 @@ static int get_std_framerate(int i){ * And there are "variable" fps files this needs to detect as well. */ static int tb_unreliable(AVCodecContext *c){ - if( c->time_base.den >= 101L*c->time_base.num - || c->time_base.den < 5L*c->time_base.num + if( c->time_base.den >= 101LL*c->time_base.num + || c->time_base.den < 5LL*c->time_base.num /* || c->codec_tag == AV_RL32("DIVX") || c->codec_tag == AV_RL32("XVID")*/ || c->codec_tag == AV_RL32("mp4v") @@ -2691,6 +2701,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); } @@ -2863,9 +2874,10 @@ int avformat_find_stream_info(AVFormatContext *ic, AVDictionary **options) goto find_stream_info_err; } - read_size += pkt->size; - st = ic->streams[pkt->stream_index]; + if (!(st->disposition & AV_DISPOSITION_ATTACHED_PIC)) + read_size += pkt->size; + if (pkt->dts != AV_NOPTS_VALUE && st->codec_info_nb_frames > 1) { /* check for non-increasing dts */ if (st->info->fps_last_dts != AV_NOPTS_VALUE && @@ -4043,6 +4055,7 @@ int avformat_network_deinit(void) #if CONFIG_NETWORK ff_network_close(); ff_tls_deinit(); + ff_network_inited_globally = 0; #endif return 0; } diff --git a/libavformat/vqf.c b/libavformat/vqf.c index 4cd0a6deec..9fa31a15b9 100644 --- a/libavformat/vqf.c +++ b/libavformat/vqf.c @@ -262,7 +262,7 @@ static int vqf_read_seek(AVFormatContext *s, { VqfContext *c = s->priv_data; AVStream *st; - int ret; + int64_t ret; int64_t pos; st = s->streams[stream_index]; diff --git a/libavformat/wtvenc.c b/libavformat/wtvenc.c index 04e6cc22f8..ba0f178f98 100644 --- a/libavformat/wtvenc.c +++ b/libavformat/wtvenc.c @@ -223,9 +223,50 @@ static void finish_chunk(AVFormatContext *s) write_index(s); } +static void put_videoinfoheader2(AVIOContext *pb, AVStream *st) +{ + AVRational dar = av_mul_q(st->sample_aspect_ratio, (AVRational){st->codec->width, st->codec->height}); + unsigned int num, den; + av_reduce(&num, &den, dar.num, dar.den, 0xFFFFFFFF); + + /* VIDEOINFOHEADER2 */ + avio_wl32(pb, 0); + avio_wl32(pb, 0); + avio_wl32(pb, st->codec->width); + avio_wl32(pb, st->codec->height); + + avio_wl32(pb, 0); + avio_wl32(pb, 0); + avio_wl32(pb, 0); + avio_wl32(pb, 0); + + avio_wl32(pb, st->codec->bit_rate); + avio_wl32(pb, 0); + avio_wl64(pb, st->avg_frame_rate.num && st->avg_frame_rate.den ? INT64_C(10000000) / av_q2d(st->avg_frame_rate) : 0); + avio_wl32(pb, 0); + avio_wl32(pb, 0); + + avio_wl32(pb, num); + avio_wl32(pb, den); + avio_wl32(pb, 0); + avio_wl32(pb, 0); + + ff_put_bmp_header(pb, st->codec, ff_codec_bmp_tags, 0, 1); + + if (st->codec->codec_id == AV_CODEC_ID_MPEG2VIDEO) { + /* MPEG2VIDEOINFO */ + avio_wl32(pb, 0); + avio_wl32(pb, st->codec->extradata_size); + avio_wl32(pb, -1); + avio_wl32(pb, -1); + avio_wl32(pb, 0); + avio_write(pb, st->codec->extradata, st->codec->extradata_size); + avio_wl64(pb, 0); + } +} + static int write_stream_codec_info(AVFormatContext *s, AVStream *st) { - WtvContext *wctx = s->priv_data; const ff_asf_guid *g, *media_type, *format_type; AVIOContext *pb = s->pb; int64_t hdr_pos_start; @@ -257,13 +298,7 @@ static int write_stream_codec_info(AVFormatContext *s, AVStream *st) hdr_pos_start = avio_tell(pb); if (st->codec->codec_type == AVMEDIA_TYPE_VIDEO) { - if (wctx->first_video_flag) { - write_pad(pb, 216); //The size is sensitive. - wctx->first_video_flag = 0; - } else { - write_pad(pb, 72); // aspect ratio - ff_put_bmp_header(pb, st->codec, ff_codec_bmp_tags, 0); - } + put_videoinfoheader2(pb, st); } else { ff_put_wav_header(pb, st->codec); } diff --git a/libavutil/Makefile b/libavutil/Makefile index 7b3b439e70..9b5cd4e6b7 100644 --- a/libavutil/Makefile +++ b/libavutil/Makefile @@ -90,7 +90,8 @@ OBJS = adler32.o \ intfloat_readwrite.o \ intmath.o \ lfg.o \ - lls.o \ + lls1.o \ + lls2.o \ log.o \ log2_tab.o \ mathematics.o \ @@ -143,7 +144,8 @@ TESTPROGS = adler32 \ fifo \ hmac \ lfg \ - lls \ + lls1 \ + lls2 \ md5 \ murmur3 \ opt \ diff --git a/libavutil/arm/asm.S b/libavutil/arm/asm.S index 9cdcce9a18..0d9fb2c868 100644 --- a/libavutil/arm/asm.S +++ b/libavutil/arm/asm.S @@ -43,11 +43,17 @@ #elif HAVE_ARMV5TE .arch armv5te #endif +#if HAVE_AS_OBJECT_ARCH +ELF .object_arch armv4 +#endif #if HAVE_NEON .fpu neon +ELF .eabi_attribute 10, 0 @ suppress Tag_FP_arch +ELF .eabi_attribute 12, 0 @ suppress Tag_Advanced_SIMD_arch #elif HAVE_VFP .fpu vfp +ELF .eabi_attribute 10, 0 @ suppress Tag_FP_arch #endif .syntax unified diff --git a/libavutil/cpu.c b/libavutil/cpu.c index 1dc5abb2b8..9c0c8747fa 100644 --- a/libavutil/cpu.c +++ b/libavutil/cpu.c @@ -45,6 +45,25 @@ static int flags, checked; void av_force_cpu_flags(int arg){ + if ( (arg & ( AV_CPU_FLAG_3DNOW | + AV_CPU_FLAG_3DNOWEXT | + AV_CPU_FLAG_SSE | + AV_CPU_FLAG_SSE2 | + AV_CPU_FLAG_SSE2SLOW | + AV_CPU_FLAG_SSE3 | + AV_CPU_FLAG_SSE3SLOW | + AV_CPU_FLAG_SSSE3 | + AV_CPU_FLAG_SSE4 | + AV_CPU_FLAG_SSE42 | + AV_CPU_FLAG_AVX | + AV_CPU_FLAG_XOP | + AV_CPU_FLAG_FMA4 | + AV_CPU_FLAG_AVX2 )) + && !(arg & AV_CPU_FLAG_MMX)) { + av_log(NULL, AV_LOG_WARNING, "MMX implied by specified flags\n"); + arg |= AV_CPU_FLAG_MMX; + } + flags = arg; checked = arg != -1; } diff --git a/libavutil/frame.c b/libavutil/frame.c index 654f17428b..774413fa21 100644 --- a/libavutil/frame.c +++ b/libavutil/frame.c @@ -489,6 +489,7 @@ int av_frame_copy_props(AVFrame *dst, const AVFrame *src) av_dict_free(&dst->side_data[i]->metadata); } 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/lls.c b/libavutil/lls1.c similarity index 87% rename from libavutil/lls.c rename to libavutil/lls1.c index abed8efaff..c452d82334 100644 --- a/libavutil/lls.c +++ b/libavutil/lls1.c @@ -30,14 +30,23 @@ #include "attributes.h" #include "version.h" -#include "lls.h" +#include "lls1.h" -static void update_lls(LLSModel *m, double *var) +#if FF_API_LLS1 + +av_cold void avpriv_init_lls(LLSModel *m, int indep_count) +{ + memset(m, 0, sizeof(LLSModel)); + m->indep_count = indep_count; +} + +void avpriv_update_lls(LLSModel *m, double *var, double decay) { int i, j; for (i = 0; i <= m->indep_count; i++) { for (j = i; j <= m->indep_count; j++) { + m->covariance[i][j] *= decay; m->covariance[i][j] += var[i] * var[j]; } } @@ -46,8 +55,8 @@ static void update_lls(LLSModel *m, double *var) void avpriv_solve_lls(LLSModel *m, double threshold, unsigned short min_order) { int i, j, k; - double (*factor)[MAX_VARS_ALIGN] = (void *) &m->covariance[1][0]; - double (*covar) [MAX_VARS_ALIGN] = (void *) &m->covariance[1][1]; + double (*factor)[MAX_VARS + 1] = (void *) &m->covariance[1][0]; + double (*covar) [MAX_VARS + 1] = (void *) &m->covariance[1][1]; double *covar_y = m->covariance[0]; int count = m->indep_count; @@ -100,7 +109,7 @@ void avpriv_solve_lls(LLSModel *m, double threshold, unsigned short min_order) } } -static double evaluate_lls(LLSModel *m, double *param, int order) +double avpriv_evaluate_lls(LLSModel *m, double *param, int order) { int i; double out = 0; @@ -111,16 +120,6 @@ static double evaluate_lls(LLSModel *m, double *param, int order) return out; } -av_cold void avpriv_init_lls(LLSModel *m, int indep_count) -{ - memset(m, 0, sizeof(LLSModel)); - m->indep_count = indep_count; - m->update_lls = update_lls; - m->evaluate_lls = evaluate_lls; - if (ARCH_X86) - ff_init_lls_x86(m); -} - #if FF_API_LLS_PRIVATE av_cold void av_init_lls(LLSModel *m, int indep_count) { @@ -128,7 +127,7 @@ av_cold void av_init_lls(LLSModel *m, int indep_count) } void av_update_lls(LLSModel *m, double *param, double decay) { - m->update_lls(m, param); + avpriv_update_lls(m, param, decay); } void av_solve_lls(LLSModel *m, double threshold, int min_order) { @@ -136,10 +135,12 @@ void av_solve_lls(LLSModel *m, double threshold, int min_order) } double av_evaluate_lls(LLSModel *m, double *param, int order) { - return m->evaluate_lls(m, param, order); + return avpriv_evaluate_lls(m, param, order); } #endif /* FF_API_LLS_PRIVATE */ +#endif /* FF_API_LLS1 */ + #ifdef TEST #include @@ -156,17 +157,17 @@ int main(void) avpriv_init_lls(&m, 3); for (i = 0; i < 100; i++) { - LOCAL_ALIGNED(32, double, var, [4]); + double var[4]; double eval; var[0] = (av_lfg_get(&lfg) / (double) UINT_MAX - 0.5) * 2; var[1] = var[0] + av_lfg_get(&lfg) / (double) UINT_MAX - 0.5; var[2] = var[1] + av_lfg_get(&lfg) / (double) UINT_MAX - 0.5; var[3] = var[2] + av_lfg_get(&lfg) / (double) UINT_MAX - 0.5; - m.update_lls(&m, var); + avpriv_update_lls(&m, var, 0.99); avpriv_solve_lls(&m, 0.001, 0); for (order = 0; order < 3; order++) { - eval = m.evaluate_lls(&m, var + 1, order); + eval = avpriv_evaluate_lls(&m, var + 1, order); printf("real:%9f order:%d pred:%9f var:%f coeffs:%f %9f %9f\n", var[0], order, eval, sqrt(m.variance[order] / (i + 1)), m.coeff[order][0], m.coeff[order][1], diff --git a/libavutil/lls1.h b/libavutil/lls1.h new file mode 100644 index 0000000000..c785d44421 --- /dev/null +++ b/libavutil/lls1.h @@ -0,0 +1,54 @@ +/* + * linear least squares model + * + * Copyright (c) 2006 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 + */ + +#ifndef AVUTIL_LLS_H +#define AVUTIL_LLS_H + +#include "version.h" + +#define MAX_VARS 32 + +//FIXME avoid direct access to LLSModel from outside + +/** + * Linear least squares model. + */ +typedef struct LLSModel { + double covariance[MAX_VARS + 1][MAX_VARS + 1]; + double coeff[MAX_VARS][MAX_VARS]; + double variance[MAX_VARS]; + int indep_count; +} LLSModel; + +void avpriv_init_lls(LLSModel *m, int indep_count); +void avpriv_update_lls(LLSModel *m, double *param, double decay); +void avpriv_solve_lls(LLSModel *m, double threshold, unsigned short min_order); +double avpriv_evaluate_lls(LLSModel *m, double *param, int order); + +#if FF_API_LLS_PRIVATE +void av_init_lls(LLSModel *m, int indep_count); +void av_update_lls(LLSModel *m, double *param, double decay); +void av_solve_lls(LLSModel *m, double threshold, int min_order); +double av_evaluate_lls(LLSModel *m, double *param, int order); +#endif /* FF_API_LLS_PRIVATE */ + +#endif /* AVUTIL_LLS_H */ diff --git a/libavutil/lls2.c b/libavutil/lls2.c new file mode 100644 index 0000000000..8cadacb11d --- /dev/null +++ b/libavutil/lls2.c @@ -0,0 +1,160 @@ +/* + * linear least squares model + * + * Copyright (c) 2006 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 + */ + +/** + * @file + * linear least squares model + */ + +#include +#include + +#include "attributes.h" +#include "version.h" +#include "lls2.h" + +static void update_lls(LLSModel2 *m, double *var) +{ + int i, j; + + for (i = 0; i <= m->indep_count; i++) { + for (j = i; j <= m->indep_count; j++) { + m->covariance[i][j] += var[i] * var[j]; + } + } +} + +void avpriv_solve_lls2(LLSModel2 *m, double threshold, unsigned short min_order) +{ + int i, j, k; + double (*factor)[MAX_VARS_ALIGN] = (void *) &m->covariance[1][0]; + double (*covar) [MAX_VARS_ALIGN] = (void *) &m->covariance[1][1]; + double *covar_y = m->covariance[0]; + int count = m->indep_count; + + for (i = 0; i < count; i++) { + for (j = i; j < count; j++) { + double sum = covar[i][j]; + + for (k = i - 1; k >= 0; k--) + sum -= factor[i][k] * factor[j][k]; + + if (i == j) { + if (sum < threshold) + sum = 1.0; + factor[i][i] = sqrt(sum); + } else { + factor[j][i] = sum / factor[i][i]; + } + } + } + + for (i = 0; i < count; i++) { + double sum = covar_y[i + 1]; + + for (k = i - 1; k >= 0; k--) + sum -= factor[i][k] * m->coeff[0][k]; + + m->coeff[0][i] = sum / factor[i][i]; + } + + for (j = count - 1; j >= min_order; j--) { + for (i = j; i >= 0; i--) { + double sum = m->coeff[0][i]; + + for (k = i + 1; k <= j; k++) + sum -= factor[k][i] * m->coeff[j][k]; + + m->coeff[j][i] = sum / factor[i][i]; + } + + m->variance[j] = covar_y[0]; + + for (i = 0; i <= j; i++) { + double sum = m->coeff[j][i] * covar[i][i] - 2 * covar_y[i + 1]; + + for (k = 0; k < i; k++) + sum += 2 * m->coeff[j][k] * covar[k][i]; + + m->variance[j] += m->coeff[j][i] * sum; + } + } +} + +static double evaluate_lls(LLSModel2 *m, double *param, int order) +{ + int i; + double out = 0; + + for (i = 0; i <= order; i++) + out += param[i] * m->coeff[order][i]; + + return out; +} + +av_cold void avpriv_init_lls2(LLSModel2 *m, int indep_count) +{ + memset(m, 0, sizeof(LLSModel2)); + m->indep_count = indep_count; + m->update_lls = update_lls; + m->evaluate_lls = evaluate_lls; + if (ARCH_X86) + ff_init_lls_x86(m); +} + +#ifdef TEST + +#include +#include +#include "lfg.h" + +int main(void) +{ + LLSModel2 m; + int i, order; + AVLFG lfg; + + av_lfg_init(&lfg, 1); + avpriv_init_lls2(&m, 3); + + for (i = 0; i < 100; i++) { + LOCAL_ALIGNED(32, double, var, [4]); + double eval; + + var[0] = (av_lfg_get(&lfg) / (double) UINT_MAX - 0.5) * 2; + var[1] = var[0] + av_lfg_get(&lfg) / (double) UINT_MAX - 0.5; + var[2] = var[1] + av_lfg_get(&lfg) / (double) UINT_MAX - 0.5; + var[3] = var[2] + av_lfg_get(&lfg) / (double) UINT_MAX - 0.5; + m.update_lls(&m, var); + avpriv_solve_lls2(&m, 0.001, 0); + for (order = 0; order < 3; order++) { + eval = m.evaluate_lls(&m, var + 1, order); + printf("real:%9f order:%d pred:%9f var:%f coeffs:%f %9f %9f\n", + var[0], order, eval, sqrt(m.variance[order] / (i + 1)), + m.coeff[order][0], m.coeff[order][1], + m.coeff[order][2]); + } + } + return 0; +} + +#endif diff --git a/libavutil/lls.h b/libavutil/lls2.h similarity index 72% rename from libavutil/lls.h rename to libavutil/lls2.h index c62d78a230..35815d2704 100644 --- a/libavutil/lls.h +++ b/libavutil/lls2.h @@ -30,12 +30,12 @@ #define MAX_VARS 32 #define MAX_VARS_ALIGN FFALIGN(MAX_VARS+1,4) -//FIXME avoid direct access to LLSModel from outside +//FIXME avoid direct access to LLSModel2 from outside /** * Linear least squares model. */ -typedef struct LLSModel { +typedef struct LLSModel2 { DECLARE_ALIGNED(32, double, covariance[MAX_VARS_ALIGN][MAX_VARS_ALIGN]); DECLARE_ALIGNED(32, double, coeff[MAX_VARS][MAX_VARS]); double variance[MAX_VARS]; @@ -47,25 +47,18 @@ typedef struct LLSModel { * 32-byte aligned, and any padding elements must be initialized * (i.e not denormal/nan). */ - void (*update_lls)(struct LLSModel *m, double *var); + void (*update_lls)(struct LLSModel2 *m, double *var); /** * Inner product of var[] and the LPC coefs. * @param m this context * @param var training samples, excluding the value to be predicted. unaligned. * @param order lpc order */ - double (*evaluate_lls)(struct LLSModel *m, double *var, int order); -} LLSModel; + double (*evaluate_lls)(struct LLSModel2 *m, double *var, int order); +} LLSModel2; -void avpriv_init_lls(LLSModel *m, int indep_count); -void ff_init_lls_x86(LLSModel *m); -void avpriv_solve_lls(LLSModel *m, double threshold, unsigned short min_order); - -#if FF_API_LLS_PRIVATE -void av_init_lls(LLSModel *m, int indep_count); -void av_update_lls(LLSModel *m, double *param, double decay); -void av_solve_lls(LLSModel *m, double threshold, int min_order); -double av_evaluate_lls(LLSModel *m, double *param, int order); -#endif /* FF_API_LLS_PRIVATE */ +void avpriv_init_lls2(LLSModel2 *m, int indep_count); +void ff_init_lls_x86(LLSModel2 *m); +void avpriv_solve_lls2(LLSModel2 *m, double threshold, unsigned short min_order); #endif /* AVUTIL_LLS_H */ diff --git a/libavutil/log.c b/libavutil/log.c index 56ef53b378..03fb30ec75 100644 --- a/libavutil/log.c +++ b/libavutil/log.c @@ -109,6 +109,9 @@ static int use_color = -1; static void colored_fputs(int level, const char *str) { + if (!*str) + return; + if (use_color < 0) { #if HAVE_SETCONSOLETEXTATTRIBUTE CONSOLE_SCREEN_BUFFER_INFO con_info; @@ -200,7 +203,7 @@ static void format_line(void *ptr, int level, const char *fmt, va_list vl, av_vbprintf(part+2, fmt, vl); if(*part[0].str || *part[1].str || *part[2].str) { - char lastc = part[2].len ? part[2].str[part[2].len - 1] : 0; + char lastc = part[2].len && part[2].len <= part[2].size ? part[2].str[part[2].len - 1] : 0; *print_prefix = lastc == '\n' || lastc == '\r'; } } diff --git a/libavutil/lzo.c b/libavutil/lzo.c index 221a66b9ab..6104fc3085 100644 --- a/libavutil/lzo.c +++ b/libavutil/lzo.c @@ -22,6 +22,7 @@ #include #include "avutil.h" +#include "avassert.h" #include "common.h" #include "intreadwrite.h" #include "lzo.h" @@ -65,8 +66,13 @@ static inline int get_len(LZOContext *c, int x, int mask) { int cnt = x & mask; if (!cnt) { - while (!(x = get_byte(c))) + while (!(x = get_byte(c))) { + if (cnt >= INT_MAX - 1000) { + c->error |= AV_LZO_ERROR; + break; + } cnt += 255; + } cnt += mask + x; } return cnt; @@ -80,6 +86,7 @@ static inline void copy(LZOContext *c, int cnt) { register const uint8_t *src = c->in; register uint8_t *dst = c->out; + av_assert0(cnt >= 0); if (cnt > c->in_end - src) { cnt = FFMAX(c->in_end - src, 0); c->error |= AV_LZO_INPUT_DEPLETED; @@ -111,6 +118,7 @@ static inline void copy(LZOContext *c, int cnt) static inline void copy_backptr(LZOContext *c, int back, int cnt) { register uint8_t *dst = c->out; + av_assert0(cnt > 0); if (dst - c->out_start < back) { c->error |= AV_LZO_INVALID_BACKPTR; return; diff --git a/libavutil/opt.c b/libavutil/opt.c index a367dbbbcb..95d92a7221 100644 --- a/libavutil/opt.c +++ b/libavutil/opt.c @@ -566,7 +566,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; } @@ -1507,8 +1507,10 @@ void av_opt_freep_ranges(AVOptionRanges **rangesp) for (i = 0; i < ranges->nb_ranges; i++) { AVOptionRange *range = ranges->range[i]; - av_freep(&range->str); - av_freep(&ranges->range[i]); + if (range) { + av_freep(&range->str); + av_freep(&ranges->range[i]); + } } av_freep(&ranges->range); av_freep(rangesp); diff --git a/libavutil/pca.c b/libavutil/pca.c index 311b6bc9cb..a745136e1d 100644 --- a/libavutil/pca.c +++ b/libavutil/pca.c @@ -41,12 +41,20 @@ PCA *ff_pca_init(int n){ return NULL; pca= av_mallocz(sizeof(*pca)); + if (!pca) + return NULL; + pca->n= n; pca->z = av_malloc(sizeof(*pca->z) * n); pca->count=0; pca->covariance= av_calloc(n*n, sizeof(double)); pca->mean= av_calloc(n, sizeof(double)); + if (!pca->z || !pca->covariance || !pca->mean) { + ff_pca_free(pca); + return NULL; + } + return pca; } diff --git a/libavutil/samplefmt.c b/libavutil/samplefmt.c index 08ecc83467..a1986980f0 100644 --- a/libavutil/samplefmt.c +++ b/libavutil/samplefmt.c @@ -135,6 +135,8 @@ int av_samples_get_buffer_size(int *linesize, int nb_channels, int nb_samples, /* auto-select alignment if not specified */ if (!align) { + if (nb_samples > INT_MAX - 31) + return AVERROR(EINVAL); align = 1; nb_samples = FFALIGN(nb_samples, 32); } diff --git a/libavutil/timestamp.h b/libavutil/timestamp.h index f63a08c579..f010a7ee38 100644 --- a/libavutil/timestamp.h +++ b/libavutil/timestamp.h @@ -26,6 +26,10 @@ #include "common.h" +#if defined(__cplusplus) && !defined(__STDC_FORMAT_MACROS) && !defined(PRId64) +#error missing -D__STDC_FORMAT_MACROS / #define __STDC_FORMAT_MACROS +#endif + #define AV_TS_MAX_STRING_SIZE 32 /** diff --git a/libavutil/version.h b/libavutil/version.h index 67a2acd107..dd70beb9ea 100644 --- a/libavutil/version.h +++ b/libavutil/version.h @@ -76,7 +76,7 @@ #define LIBAVUTIL_VERSION_MAJOR 52 #define LIBAVUTIL_VERSION_MINOR 48 -#define LIBAVUTIL_VERSION_MICRO 100 +#define LIBAVUTIL_VERSION_MICRO 101 #define LIBAVUTIL_VERSION_INT AV_VERSION_INT(LIBAVUTIL_VERSION_MAJOR, \ LIBAVUTIL_VERSION_MINOR, \ @@ -132,6 +132,9 @@ #ifndef FF_API_LLS_PRIVATE #define FF_API_LLS_PRIVATE (LIBAVUTIL_VERSION_MAJOR < 53) #endif +#ifndef FF_API_LLS1 +#define FF_API_LLS1 (LIBAVUTIL_VERSION_MAJOR < 53) +#endif #ifndef FF_API_AVFRAME_LAVC #define FF_API_AVFRAME_LAVC (LIBAVUTIL_VERSION_MAJOR < 53) #endif diff --git a/libavutil/x86/cpu.c b/libavutil/x86/cpu.c index 18049eaead..65ec8259ab 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/libavutil/x86/lls.asm b/libavutil/x86/lls.asm index 769befb769..c2aead38ef 100644 --- a/libavutil/x86/lls.asm +++ b/libavutil/x86/lls.asm @@ -29,7 +29,7 @@ SECTION .text %define COVAR_STRIDE MAX_VARS_ALIGN*8 %define COVAR(x,y) [covarq + (x)*8 + (y)*COVAR_STRIDE] -struc LLSModel +struc LLSModel2 .covariance: resq MAX_VARS_ALIGN*MAX_VARS_ALIGN .coeff: resq MAX_VARS*MAX_VARS .variance: resq MAX_VARS @@ -49,7 +49,7 @@ INIT_XMM sse2 %define movdqa movaps cglobal update_lls, 2,5,8, ctx, var, i, j, covar2 %define covarq ctxq - mov id, [ctxq + LLSModel.indep_count] + mov id, [ctxq + LLSModel2.indep_count] lea varq, [varq + iq*8] neg iq mov covar2q, covarq @@ -129,7 +129,7 @@ cglobal update_lls, 2,5,8, ctx, var, i, j, covar2 INIT_YMM avx cglobal update_lls, 3,6,8, ctx, var, count, i, j, count2 %define covarq ctxq - mov countd, [ctxq + LLSModel.indep_count] + mov countd, [ctxq + LLSModel2.indep_count] lea count2d, [countq-2] xor id, id .loopi: @@ -206,7 +206,7 @@ cglobal evaluate_lls, 3,4,2, ctx, var, order, i %define coefsq ctxq mov id, orderd imul orderd, MAX_VARS - lea coefsq, [ctxq + LLSModel.coeff + orderq*8] + lea coefsq, [ctxq + LLSModel2.coeff + orderq*8] movsd m0, [varq] movhpd m0, [varq + 8] mulpd m0, [coefsq] diff --git a/libavutil/x86/lls_init.c b/libavutil/x86/lls_init.c index 181ca38dae..bf999d5fc3 100644 --- a/libavutil/x86/lls_init.c +++ b/libavutil/x86/lls_init.c @@ -20,14 +20,14 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ -#include "libavutil/lls.h" +#include "libavutil/lls2.h" #include "libavutil/x86/cpu.h" -void ff_update_lls_sse2(LLSModel *m, double *var); -void ff_update_lls_avx(LLSModel *m, double *var); -double ff_evaluate_lls_sse2(LLSModel *m, double *var, int order); +void ff_update_lls_sse2(LLSModel2 *m, double *var); +void ff_update_lls_avx(LLSModel2 *m, double *var); +double ff_evaluate_lls_sse2(LLSModel2 *m, double *var, int order); -av_cold void ff_init_lls_x86(LLSModel *m) +av_cold void ff_init_lls_x86(LLSModel2 *m) { int cpu_flags = av_get_cpu_flags(); if (EXTERNAL_SSE2(cpu_flags)) { diff --git a/libpostproc/postprocess.c b/libpostproc/postprocess.c index b34943f983..8e5b043060 100644 --- a/libpostproc/postprocess.c +++ b/libpostproc/postprocess.c @@ -975,7 +975,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; } @@ -1000,7 +1000,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/library.mak b/library.mak index e48aba19b9..737f5bb6cd 100644 --- a/library.mak +++ b/library.mak @@ -25,7 +25,7 @@ $(SUBDIR)%-test.i: $(SUBDIR)%.c $(SUBDIR)x86/%.o: $(SUBDIR)x86/%.asm $(DEPYASM) $(YASMFLAGS) -I $( $(@:.o=.d) $(YASM) $(YASMFLAGS) -I $(dither.noise_scale; #define TMP_EXTRA 2 - double *tmp = av_malloc((len + TMP_EXTRA) * sizeof(double)); + double *tmp = av_malloc_array(len + TMP_EXTRA, sizeof(double)); int i; for(i=0; idither.output_sample_bits&31)) scale = 1; - if(in_fmt == AV_SAMPLE_FMT_S32 && out_fmt == AV_SAMPLE_FMT_S16) scale = 1L<<16; - if(in_fmt == AV_SAMPLE_FMT_S32 && out_fmt == AV_SAMPLE_FMT_U8 ) scale = 1L<<24; - if(in_fmt == AV_SAMPLE_FMT_S16 && out_fmt == AV_SAMPLE_FMT_U8 ) scale = 1L<<8; + if(in_fmt == AV_SAMPLE_FMT_S32 && out_fmt == AV_SAMPLE_FMT_S16) scale = 1<<16; + if(in_fmt == AV_SAMPLE_FMT_S32 && out_fmt == AV_SAMPLE_FMT_U8 ) scale = 1<<24; + if(in_fmt == AV_SAMPLE_FMT_S16 && out_fmt == AV_SAMPLE_FMT_U8 ) scale = 1<<8; scale *= s->dither.scale; diff --git a/libswresample/rematrix.c b/libswresample/rematrix.c index 5c98e68990..bf2abcfb20 100644 --- a/libswresample/rematrix.c +++ b/libswresample/rematrix.c @@ -127,6 +127,11 @@ av_cold static int auto_matrix(SwrContext *s) ) out_ch_layout = AV_CH_LAYOUT_STEREO; + if( in_ch_layout == AV_CH_LAYOUT_STEREO_DOWNMIX + && (out_ch_layout & AV_CH_LAYOUT_STEREO_DOWNMIX) == 0 + ) + in_ch_layout = AV_CH_LAYOUT_STEREO; + if(!sane_layout(in_ch_layout)){ av_get_channel_layout_string(buf, sizeof(buf), -1, s->in_ch_layout); av_log(s, AV_LOG_ERROR, "Input channel layout '%s' is not supported\n", buf); @@ -433,8 +438,8 @@ int swri_rematrix(SwrContext *s, AudioData *out, AudioData *in, int len, int mus off = len1 * out->bps; } - av_assert0(out->ch_count == av_get_channel_layout_nb_channels(s->out_ch_layout)); - av_assert0(in ->ch_count == av_get_channel_layout_nb_channels(s-> in_ch_layout)); + av_assert0(!s->out_ch_layout || out->ch_count == av_get_channel_layout_nb_channels(s->out_ch_layout)); + av_assert0(!s-> in_ch_layout || in ->ch_count == av_get_channel_layout_nb_channels(s-> in_ch_layout)); for(out_i=0; out_ich_count; out_i++){ switch(s->matrix_ch[out_i][0]){ diff --git a/libswresample/resample.c b/libswresample/resample.c index 8b1b6ca9af..65fd817be9 100644 --- a/libswresample/resample.c +++ b/libswresample/resample.c @@ -95,7 +95,7 @@ static int build_filter(ResampleContext *c, void *filter, double factor, int tap int filter_type, int kaiser_beta){ int ph, i; double x, y, w; - double *tab = av_malloc(tap_count * sizeof(*tab)); + double *tab = av_malloc_array(tap_count, sizeof(*tab)); const int center= (tap_count-1)/2; if (!tab) @@ -229,6 +229,11 @@ static ResampleContext *resample_init(ResampleContext *c, int out_rate, int in_r av_assert0(0); } + if (filter_size/factor > INT32_MAX/256) { + av_log(NULL, AV_LOG_ERROR, "Filter length too large\n"); + goto error; + } + c->phase_shift = phase_shift; c->phase_mask = phase_count - 1; c->linear = linear; diff --git a/libswresample/soxr_resample.c b/libswresample/soxr_resample.c index 4c000db0ca..7467f8d5cc 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 30c34348e4..ec0c770ab4 100644 --- a/libswresample/swresample.c +++ b/libswresample/swresample.c @@ -753,6 +753,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.c b/libswscale/swscale.c index 710dce3330..1d3e4731a5 100644 --- a/libswscale/swscale.c +++ b/libswscale/swscale.c @@ -208,8 +208,9 @@ static void lumRangeToJpeg16_c(int16_t *_dst, int width) { int i; int32_t *dst = (int32_t *) _dst; - for (i = 0; i < width; i++) - dst[i] = (FFMIN(dst[i], 30189 << 4) * 4769 - (39057361 << 2)) >> 12; + for (i = 0; i < width; i++) { + dst[i] = ((int)(FFMIN(dst[i], 30189 << 4) * 4769U - (39057361 << 2))) >> 12; + } } static void lumRangeFromJpeg16_c(int16_t *_dst, int width) @@ -921,7 +922,7 @@ int attribute_align_arg sws_scale(struct SwsContext *c, uint8_t *dst2[4]; uint8_t *rgb0_tmp = NULL; - if (!srcSlice || !dstStride || !dst || !srcSlice) { + if (!srcStride || !dstStride || !dst || !srcSlice) { av_log(c, AV_LOG_ERROR, "One of the input parameters to sws_scale() is NULL, please check the calling code\n"); return 0; } diff --git a/libswscale/swscale_internal.h b/libswscale/swscale_internal.h index 33fdfc2771..c9f6a063a2 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 256 diff --git a/libswscale/swscale_unscaled.c b/libswscale/swscale_unscaled.c index 83086f7865..957d781790 100644 --- a/libswscale/swscale_unscaled.c +++ b/libswscale/swscale_unscaled.c @@ -1222,7 +1222,7 @@ void ff_get_unscaled_swscale(SwsContext *c) c->swscale = ff_yuv2rgb_get_func_ptr(c); } - if (srcFormat == AV_PIX_FMT_YUV410P && + if (srcFormat == AV_PIX_FMT_YUV410P && !(dstH & 3) && (dstFormat == AV_PIX_FMT_YUV420P || dstFormat == AV_PIX_FMT_YUVA420P) && !(flags & SWS_BITEXACT)) { c->swscale = yvu9ToYv12Wrapper; diff --git a/libswscale/utils.c b/libswscale/utils.c index 69087dc3fa..2da0756485 100644 --- a/libswscale/utils.c +++ b/libswscale/utils.c @@ -596,14 +596,25 @@ static av_cold int initFilter(int16_t **outFilter, int32_t **filterPos, } if ((*filterPos)[i] + filterSize > srcW) { - int shift = (*filterPos)[i] + filterSize - srcW; - // move filter coefficients right to compensate for filterPos - for (j = filterSize - 2; j >= 0; j--) { - int right = FFMIN(j + shift, filterSize - 1); - filter[i * filterSize + right] += filter[i * filterSize + j]; - filter[i * filterSize + j] = 0; + int shift = (*filterPos)[i] + FFMIN(filterSize - srcW, 0); + int64_t acc = 0; + + for (j = filterSize - 1; j >= 0; j--) { + if ((*filterPos)[i] + j >= srcW) { + acc += filter[i * filterSize + j]; + filter[i * filterSize + j] = 0; + } } - (*filterPos)[i]= srcW - filterSize; + for (j = filterSize - 1; j >= 0; j--) { + if (j < shift) { + filter[i * filterSize + j] = 0; + } else { + filter[i * filterSize + j] = filter[i * filterSize + j - shift]; + } + } + + (*filterPos)[i]-= shift; + filter[i * filterSize + srcW - 1 - (*filterPos)[i]] += acc; } } @@ -975,8 +986,6 @@ int sws_setColorspaceDetails(struct SwsContext *c, const int inv_table[4], c->srcRange = srcRange; c->dstRange = dstRange; - fill_xyztables(c); - if ((isYUV(c->dstFormat) || isGray(c->dstFormat)) && (isYUV(c->srcFormat) || isGray(c->srcFormat))) return -1; @@ -1067,6 +1076,8 @@ static void handle_formats(SwsContext *c) c->dst0Alpha |= handle_0alpha(&c->dstFormat); c->srcXYZ |= handle_xyz(&c->srcFormat); c->dstXYZ |= handle_xyz(&c->dstFormat); + if (c->srcXYZ || c->dstXYZ) + fill_xyztables(c); } SwsContext *sws_alloc_context(void) @@ -1303,7 +1314,7 @@ av_cold int sws_init_context(SwsContext *c, SwsFilter *srcFilter, c->chrDstW = FF_CEIL_RSHIFT(dstW, c->chrDstHSubSample); c->chrDstH = FF_CEIL_RSHIFT(dstH, c->chrDstVSubSample); - FF_ALLOC_OR_GOTO(c, c->formatConvBuffer, FFALIGN(srcW*2+78, 16) * 2, fail); + FF_ALLOCZ_OR_GOTO(c, c->formatConvBuffer, FFALIGN(srcW*2+78, 16) * 2, fail); /* unscaled special cases */ if (unscaled && !usesHFilter && !usesVFilter && @@ -1331,9 +1342,10 @@ av_cold int sws_init_context(SwsContext *c, SwsFilter *srcFilter, dst_stride <<= 1; if (INLINE_MMXEXT(cpu_flags) && c->srcBpc == 8 && c->dstBpc <= 14) { - c->canMMXEXTBeUsed = (dstW >= srcW && (dstW & 31) == 0 && - (srcW & 15) == 0) ? 1 : 0; - if (!c->canMMXEXTBeUsed && dstW >= srcW && (srcW & 15) == 0 + c->canMMXEXTBeUsed = dstW >= srcW && (dstW & 31) == 0 && + c->chrDstW >= c->chrSrcW && + (srcW & 15) == 0; + if (!c->canMMXEXTBeUsed && dstW >= srcW && c->chrDstW >= c->chrSrcW && (srcW & 15) == 0 && (flags & SWS_FAST_BILINEAR)) { if (flags & SWS_PRINT_INFO) diff --git a/libswscale/x86/rgb2rgb_template.c b/libswscale/x86/rgb2rgb_template.c index d684b70d4c..bfcaead9d0 100644 --- a/libswscale/x86/rgb2rgb_template.c +++ b/libswscale/x86/rgb2rgb_template.c @@ -1623,6 +1623,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 + && !((((intptr_t)src1) | ((intptr_t)src2) | ((intptr_t)dest))&15) + ) __asm__( "xor %%"REG_a", %%"REG_a" \n\t" "1: \n\t" @@ -1884,6 +1897,7 @@ static void RENAME(interleaveBytes)(const uint8_t *src1, const uint8_t *src2, ui : "memory", "%"REG_a"" ); #else + ) __asm__( "xor %%"REG_a", %%"REG_a" \n\t" "1: \n\t" diff --git a/libswscale/x86/swscale.c b/libswscale/x86/swscale.c index a86f9f82f3..6cccf44e0f 100644 --- a/libswscale/x86/swscale.c +++ b/libswscale/x86/swscale.c @@ -266,7 +266,8 @@ static void yuv2yuvX_sse3(const int16_t *filter, int filterSize, "jb 1b \n\t"\ :: "g" (filter), "r" (dest-offset), "g" ((x86_reg)(dstW+offset)), "m" (offset) - : "%"REG_d, "%"REG_S, "%"REG_c + : XMM_CLOBBERS("%xmm0" , "%xmm1" , "%xmm2" , "%xmm3" , "%xmm4" , "%xmm5" , "%xmm7" ,) + "%"REG_d, "%"REG_S, "%"REG_c ); } #endif diff --git a/libswscale/x86/swscale_template.c b/libswscale/x86/swscale_template.c index c7a1bb46d9..c72104bd09 100644 --- a/libswscale/x86/swscale_template.c +++ b/libswscale/x86/swscale_template.c @@ -332,7 +332,7 @@ static void RENAME(yuv2yuvX)(const int16_t *filter, int filterSize, MOVNTQ( q3, 24(dst, index, 4))\ \ "add $8, "#index" \n\t"\ - "cmp "#dstw", "#index" \n\t"\ + "cmp "dstw", "#index" \n\t"\ " jb 1b \n\t" #define WRITEBGR32(dst, dstw, index, b, g, r, a, q0, q2, q3, t) REAL_WRITEBGR32(dst, dstw, index, b, g, r, a, q0, q2, q3, t) @@ -358,13 +358,13 @@ static void RENAME(yuv2rgb32_X_ar)(SwsContext *c, const int16_t *lumFilter, "psraw $3, %%mm1 \n\t" "psraw $3, %%mm7 \n\t" "packuswb %%mm7, %%mm1 \n\t" - WRITEBGR32(%4, %5, %%REGa, %%mm3, %%mm4, %%mm5, %%mm1, %%mm0, %%mm7, %%mm2, %%mm6) + WRITEBGR32(%4, "%5", %%REGa, %%mm3, %%mm4, %%mm5, %%mm1, %%mm0, %%mm7, %%mm2, %%mm6) YSCALEYUV2PACKEDX_END } else { YSCALEYUV2PACKEDX_ACCURATE YSCALEYUV2RGBX "pcmpeqd %%mm7, %%mm7 \n\t" - WRITEBGR32(%4, %5, %%REGa, %%mm2, %%mm4, %%mm5, %%mm7, %%mm0, %%mm1, %%mm3, %%mm6) + WRITEBGR32(%4, "%5", %%REGa, %%mm2, %%mm4, %%mm5, %%mm7, %%mm0, %%mm1, %%mm3, %%mm6) YSCALEYUV2PACKEDX_END } } @@ -387,13 +387,13 @@ static void RENAME(yuv2rgb32_X)(SwsContext *c, const int16_t *lumFilter, "psraw $3, %%mm1 \n\t" "psraw $3, %%mm7 \n\t" "packuswb %%mm7, %%mm1 \n\t" - WRITEBGR32(%4, %5, %%REGa, %%mm2, %%mm4, %%mm5, %%mm1, %%mm0, %%mm7, %%mm3, %%mm6) + WRITEBGR32(%4, "%5", %%REGa, %%mm2, %%mm4, %%mm5, %%mm1, %%mm0, %%mm7, %%mm3, %%mm6) YSCALEYUV2PACKEDX_END } else { YSCALEYUV2PACKEDX YSCALEYUV2RGBX "pcmpeqd %%mm7, %%mm7 \n\t" - WRITEBGR32(%4, %5, %%REGa, %%mm2, %%mm4, %%mm5, %%mm7, %%mm0, %%mm1, %%mm3, %%mm6) + WRITEBGR32(%4, "%5", %%REGa, %%mm2, %%mm4, %%mm5, %%mm7, %%mm0, %%mm1, %%mm3, %%mm6) YSCALEYUV2PACKEDX_END } } @@ -422,7 +422,7 @@ static void RENAME(yuv2rgb32_X)(SwsContext *c, const int16_t *lumFilter, MOVNTQ(%%mm1, 8(dst, index, 2))\ \ "add $8, "#index" \n\t"\ - "cmp "#dstw", "#index" \n\t"\ + "cmp "dstw", "#index" \n\t"\ " jb 1b \n\t" #define WRITERGB16(dst, dstw, index) REAL_WRITERGB16(dst, dstw, index) @@ -446,7 +446,7 @@ static void RENAME(yuv2rgb565_X_ar)(SwsContext *c, const int16_t *lumFilter, "paddusb "GREEN_DITHER"(%0), %%mm4\n\t" "paddusb "RED_DITHER"(%0), %%mm5\n\t" #endif - WRITERGB16(%4, %5, %%REGa) + WRITERGB16(%4, "%5", %%REGa) YSCALEYUV2PACKEDX_END } @@ -470,7 +470,7 @@ static void RENAME(yuv2rgb565_X)(SwsContext *c, const int16_t *lumFilter, "paddusb "GREEN_DITHER"(%0), %%mm4 \n\t" "paddusb "RED_DITHER"(%0), %%mm5 \n\t" #endif - WRITERGB16(%4, %5, %%REGa) + WRITERGB16(%4, "%5", %%REGa) YSCALEYUV2PACKEDX_END } @@ -499,7 +499,7 @@ static void RENAME(yuv2rgb565_X)(SwsContext *c, const int16_t *lumFilter, MOVNTQ(%%mm1, 8(dst, index, 2))\ \ "add $8, "#index" \n\t"\ - "cmp "#dstw", "#index" \n\t"\ + "cmp "dstw", "#index" \n\t"\ " jb 1b \n\t" #define WRITERGB15(dst, dstw, index) REAL_WRITERGB15(dst, dstw, index) @@ -523,7 +523,7 @@ static void RENAME(yuv2rgb555_X_ar)(SwsContext *c, const int16_t *lumFilter, "paddusb "GREEN_DITHER"(%0), %%mm4\n\t" "paddusb "RED_DITHER"(%0), %%mm5\n\t" #endif - WRITERGB15(%4, %5, %%REGa) + WRITERGB15(%4, "%5", %%REGa) YSCALEYUV2PACKEDX_END } @@ -547,7 +547,7 @@ static void RENAME(yuv2rgb555_X)(SwsContext *c, const int16_t *lumFilter, "paddusb "GREEN_DITHER"(%0), %%mm4 \n\t" "paddusb "RED_DITHER"(%0), %%mm5 \n\t" #endif - WRITERGB15(%4, %5, %%REGa) + WRITERGB15(%4, "%5", %%REGa) YSCALEYUV2PACKEDX_END } @@ -601,7 +601,7 @@ static void RENAME(yuv2rgb555_X)(SwsContext *c, const int16_t *lumFilter, "add $24, "#dst" \n\t"\ \ "add $8, "#index" \n\t"\ - "cmp "#dstw", "#index" \n\t"\ + "cmp "dstw", "#index" \n\t"\ " jb 1b \n\t" #define WRITEBGR24MMXEXT(dst, dstw, index) \ @@ -649,7 +649,7 @@ static void RENAME(yuv2rgb555_X)(SwsContext *c, const int16_t *lumFilter, "add $24, "#dst" \n\t"\ \ "add $8, "#index" \n\t"\ - "cmp "#dstw", "#index" \n\t"\ + "cmp "dstw", "#index" \n\t"\ " jb 1b \n\t" #if COMPILE_TEMPLATE_MMXEXT @@ -676,7 +676,7 @@ static void RENAME(yuv2bgr24_X_ar)(SwsContext *c, const int16_t *lumFilter, "pxor %%mm7, %%mm7 \n\t" "lea (%%"REG_a", %%"REG_a", 2), %%"REG_c"\n\t" //FIXME optimize "add %4, %%"REG_c" \n\t" - WRITEBGR24(%%REGc, %5, %%REGa) + WRITEBGR24(%%REGc, "%5", %%REGa) :: "r" (&c->redDither), "m" (dummy), "m" (dummy), "m" (dummy), "r" (dest), "m" (dstW_reg), "m"(uv_off) @@ -700,7 +700,7 @@ static void RENAME(yuv2bgr24_X)(SwsContext *c, const int16_t *lumFilter, "pxor %%mm7, %%mm7 \n\t" "lea (%%"REG_a", %%"REG_a", 2), %%"REG_c" \n\t" //FIXME optimize "add %4, %%"REG_c" \n\t" - WRITEBGR24(%%REGc, %5, %%REGa) + WRITEBGR24(%%REGc, "%5", %%REGa) :: "r" (&c->redDither), "m" (dummy), "m" (dummy), "m" (dummy), "r" (dest), "m" (dstW_reg), "m"(uv_off) @@ -721,7 +721,7 @@ static void RENAME(yuv2bgr24_X)(SwsContext *c, const int16_t *lumFilter, MOVNTQ(%%mm7, 8(dst, index, 2))\ \ "add $8, "#index" \n\t"\ - "cmp "#dstw", "#index" \n\t"\ + "cmp "dstw", "#index" \n\t"\ " jb 1b \n\t" #define WRITEYUY2(dst, dstw, index) REAL_WRITEYUY2(dst, dstw, index) @@ -742,7 +742,7 @@ static void RENAME(yuv2yuyv422_X_ar)(SwsContext *c, const int16_t *lumFilter, "psraw $3, %%mm4 \n\t" "psraw $3, %%mm1 \n\t" "psraw $3, %%mm7 \n\t" - WRITEYUY2(%4, %5, %%REGa) + WRITEYUY2(%4, "%5", %%REGa) YSCALEYUV2PACKEDX_END } @@ -763,7 +763,7 @@ static void RENAME(yuv2yuyv422_X)(SwsContext *c, const int16_t *lumFilter, "psraw $3, %%mm4 \n\t" "psraw $3, %%mm1 \n\t" "psraw $3, %%mm7 \n\t" - WRITEYUY2(%4, %5, %%REGa) + WRITEYUY2(%4, "%5", %%REGa) YSCALEYUV2PACKEDX_END } @@ -864,7 +864,7 @@ static void RENAME(yuv2rgb32_2)(SwsContext *c, const int16_t *buf[2], "psraw $3, %%mm1 \n\t" /* abuf0[eax] - abuf1[eax] >>7*/ "psraw $3, %%mm7 \n\t" /* abuf0[eax] - abuf1[eax] >>7*/ "packuswb %%mm7, %%mm1 \n\t" - WRITEBGR32(%4, 8280(%5), %%r8, %%mm2, %%mm4, %%mm5, %%mm1, %%mm0, %%mm7, %%mm3, %%mm6) + WRITEBGR32(%4, DSTW_OFFSET"(%5)", %%r8, %%mm2, %%mm4, %%mm5, %%mm1, %%mm0, %%mm7, %%mm3, %%mm6) :: "c" (buf0), "d" (buf1), "S" (ubuf0), "D" (ubuf1), "r" (dest), "a" (&c->redDither), "r" (abuf0), "r" (abuf1) @@ -888,7 +888,7 @@ static void RENAME(yuv2rgb32_2)(SwsContext *c, const int16_t *buf[2], "packuswb %%mm7, %%mm1 \n\t" "pop %1 \n\t" "pop %0 \n\t" - WRITEBGR32(%%REGb, 8280(%5), %%REGBP, %%mm2, %%mm4, %%mm5, %%mm1, %%mm0, %%mm7, %%mm3, %%mm6) + WRITEBGR32(%%REGb, DSTW_OFFSET"(%5)", %%REGBP, %%mm2, %%mm4, %%mm5, %%mm1, %%mm0, %%mm7, %%mm3, %%mm6) "pop %%"REG_BP" \n\t" "mov "ESP_OFFSET"(%5), %%"REG_b" \n\t" :: "c" (buf0), "d" (buf1), "S" (ubuf0), "D" (ubuf1), "m" (dest), @@ -902,7 +902,7 @@ static void RENAME(yuv2rgb32_2)(SwsContext *c, const int16_t *buf[2], "push %%"REG_BP" \n\t" YSCALEYUV2RGB(%%REGBP, %5) "pcmpeqd %%mm7, %%mm7 \n\t" - WRITEBGR32(%%REGb, 8280(%5), %%REGBP, %%mm2, %%mm4, %%mm5, %%mm7, %%mm0, %%mm1, %%mm3, %%mm6) + WRITEBGR32(%%REGb, DSTW_OFFSET"(%5)", %%REGBP, %%mm2, %%mm4, %%mm5, %%mm7, %%mm0, %%mm1, %%mm3, %%mm6) "pop %%"REG_BP" \n\t" "mov "ESP_OFFSET"(%5), %%"REG_b" \n\t" :: "c" (buf0), "d" (buf1), "S" (ubuf0), "D" (ubuf1), "m" (dest), @@ -919,14 +919,13 @@ static void RENAME(yuv2bgr24_2)(SwsContext *c, const int16_t *buf[2], const int16_t *buf0 = buf[0], *buf1 = buf[1], *ubuf0 = ubuf[0], *ubuf1 = ubuf[1]; - //Note 8280 == DSTW_OFFSET but the preprocessor can't handle that there :( __asm__ volatile( "mov %%"REG_b", "ESP_OFFSET"(%5) \n\t" "mov %4, %%"REG_b" \n\t" "push %%"REG_BP" \n\t" YSCALEYUV2RGB(%%REGBP, %5) "pxor %%mm7, %%mm7 \n\t" - WRITEBGR24(%%REGb, 8280(%5), %%REGBP) + WRITEBGR24(%%REGb, DSTW_OFFSET"(%5)", %%REGBP) "pop %%"REG_BP" \n\t" "mov "ESP_OFFSET"(%5), %%"REG_b" \n\t" :: "c" (buf0), "d" (buf1), "S" (ubuf0), "D" (ubuf1), "m" (dest), @@ -942,7 +941,6 @@ static void RENAME(yuv2rgb555_2)(SwsContext *c, const int16_t *buf[2], const int16_t *buf0 = buf[0], *buf1 = buf[1], *ubuf0 = ubuf[0], *ubuf1 = ubuf[1]; - //Note 8280 == DSTW_OFFSET but the preprocessor can't handle that there :( __asm__ volatile( "mov %%"REG_b", "ESP_OFFSET"(%5) \n\t" "mov %4, %%"REG_b" \n\t" @@ -955,7 +953,7 @@ static void RENAME(yuv2rgb555_2)(SwsContext *c, const int16_t *buf[2], "paddusb "GREEN_DITHER"(%5), %%mm4 \n\t" "paddusb "RED_DITHER"(%5), %%mm5 \n\t" #endif - WRITERGB15(%%REGb, 8280(%5), %%REGBP) + WRITERGB15(%%REGb, DSTW_OFFSET"(%5)", %%REGBP) "pop %%"REG_BP" \n\t" "mov "ESP_OFFSET"(%5), %%"REG_b" \n\t" :: "c" (buf0), "d" (buf1), "S" (ubuf0), "D" (ubuf1), "m" (dest), @@ -971,7 +969,6 @@ static void RENAME(yuv2rgb565_2)(SwsContext *c, const int16_t *buf[2], const int16_t *buf0 = buf[0], *buf1 = buf[1], *ubuf0 = ubuf[0], *ubuf1 = ubuf[1]; - //Note 8280 == DSTW_OFFSET but the preprocessor can't handle that there :( __asm__ volatile( "mov %%"REG_b", "ESP_OFFSET"(%5) \n\t" "mov %4, %%"REG_b" \n\t" @@ -984,7 +981,7 @@ static void RENAME(yuv2rgb565_2)(SwsContext *c, const int16_t *buf[2], "paddusb "GREEN_DITHER"(%5), %%mm4 \n\t" "paddusb "RED_DITHER"(%5), %%mm5 \n\t" #endif - WRITERGB16(%%REGb, 8280(%5), %%REGBP) + WRITERGB16(%%REGb, DSTW_OFFSET"(%5)", %%REGBP) "pop %%"REG_BP" \n\t" "mov "ESP_OFFSET"(%5), %%"REG_b" \n\t" :: "c" (buf0), "d" (buf1), "S" (ubuf0), "D" (ubuf1), "m" (dest), @@ -1040,13 +1037,12 @@ static void RENAME(yuv2yuyv422_2)(SwsContext *c, const int16_t *buf[2], const int16_t *buf0 = buf[0], *buf1 = buf[1], *ubuf0 = ubuf[0], *ubuf1 = ubuf[1]; - //Note 8280 == DSTW_OFFSET but the preprocessor can't handle that there :( __asm__ volatile( "mov %%"REG_b", "ESP_OFFSET"(%5) \n\t" "mov %4, %%"REG_b" \n\t" "push %%"REG_BP" \n\t" YSCALEYUV2PACKED(%%REGBP, %5) - WRITEYUY2(%%REGb, 8280(%5), %%REGBP) + WRITEYUY2(%%REGb, DSTW_OFFSET"(%5)", %%REGBP) "pop %%"REG_BP" \n\t" "mov "ESP_OFFSET"(%5), %%"REG_b" \n\t" :: "c" (buf0), "d" (buf1), "S" (ubuf0), "D" (ubuf1), "m" (dest), @@ -1189,7 +1185,7 @@ static void RENAME(yuv2rgb32_1)(SwsContext *c, const int16_t *buf0, "push %%"REG_BP" \n\t" YSCALEYUV2RGB1(%%REGBP, %5) YSCALEYUV2RGB1_ALPHA(%%REGBP) - WRITEBGR32(%%REGb, 8280(%5), %%REGBP, %%mm2, %%mm4, %%mm5, %%mm7, %%mm0, %%mm1, %%mm3, %%mm6) + WRITEBGR32(%%REGb, DSTW_OFFSET"(%5)", %%REGBP, %%mm2, %%mm4, %%mm5, %%mm7, %%mm0, %%mm1, %%mm3, %%mm6) "pop %%"REG_BP" \n\t" "mov "ESP_OFFSET"(%5), %%"REG_b" \n\t" :: "c" (buf0), "d" (abuf0), "S" (ubuf0), "D" (ubuf1), "m" (dest), @@ -1202,7 +1198,7 @@ static void RENAME(yuv2rgb32_1)(SwsContext *c, const int16_t *buf0, "push %%"REG_BP" \n\t" YSCALEYUV2RGB1(%%REGBP, %5) "pcmpeqd %%mm7, %%mm7 \n\t" - WRITEBGR32(%%REGb, 8280(%5), %%REGBP, %%mm2, %%mm4, %%mm5, %%mm7, %%mm0, %%mm1, %%mm3, %%mm6) + WRITEBGR32(%%REGb, DSTW_OFFSET"(%5)", %%REGBP, %%mm2, %%mm4, %%mm5, %%mm7, %%mm0, %%mm1, %%mm3, %%mm6) "pop %%"REG_BP" \n\t" "mov "ESP_OFFSET"(%5), %%"REG_b" \n\t" :: "c" (buf0), "d" (buf1), "S" (ubuf0), "D" (ubuf1), "m" (dest), @@ -1218,7 +1214,7 @@ static void RENAME(yuv2rgb32_1)(SwsContext *c, const int16_t *buf0, "push %%"REG_BP" \n\t" YSCALEYUV2RGB1b(%%REGBP, %5) YSCALEYUV2RGB1_ALPHA(%%REGBP) - WRITEBGR32(%%REGb, 8280(%5), %%REGBP, %%mm2, %%mm4, %%mm5, %%mm7, %%mm0, %%mm1, %%mm3, %%mm6) + WRITEBGR32(%%REGb, DSTW_OFFSET"(%5)", %%REGBP, %%mm2, %%mm4, %%mm5, %%mm7, %%mm0, %%mm1, %%mm3, %%mm6) "pop %%"REG_BP" \n\t" "mov "ESP_OFFSET"(%5), %%"REG_b" \n\t" :: "c" (buf0), "d" (abuf0), "S" (ubuf0), "D" (ubuf1), "m" (dest), @@ -1231,7 +1227,7 @@ static void RENAME(yuv2rgb32_1)(SwsContext *c, const int16_t *buf0, "push %%"REG_BP" \n\t" YSCALEYUV2RGB1b(%%REGBP, %5) "pcmpeqd %%mm7, %%mm7 \n\t" - WRITEBGR32(%%REGb, 8280(%5), %%REGBP, %%mm2, %%mm4, %%mm5, %%mm7, %%mm0, %%mm1, %%mm3, %%mm6) + WRITEBGR32(%%REGb, DSTW_OFFSET"(%5)", %%REGBP, %%mm2, %%mm4, %%mm5, %%mm7, %%mm0, %%mm1, %%mm3, %%mm6) "pop %%"REG_BP" \n\t" "mov "ESP_OFFSET"(%5), %%"REG_b" \n\t" :: "c" (buf0), "d" (buf1), "S" (ubuf0), "D" (ubuf1), "m" (dest), @@ -1257,7 +1253,7 @@ static void RENAME(yuv2bgr24_1)(SwsContext *c, const int16_t *buf0, "push %%"REG_BP" \n\t" YSCALEYUV2RGB1(%%REGBP, %5) "pxor %%mm7, %%mm7 \n\t" - WRITEBGR24(%%REGb, 8280(%5), %%REGBP) + WRITEBGR24(%%REGb, DSTW_OFFSET"(%5)", %%REGBP) "pop %%"REG_BP" \n\t" "mov "ESP_OFFSET"(%5), %%"REG_b" \n\t" :: "c" (buf0), "d" (buf1), "S" (ubuf0), "D" (ubuf1), "m" (dest), @@ -1271,7 +1267,7 @@ static void RENAME(yuv2bgr24_1)(SwsContext *c, const int16_t *buf0, "push %%"REG_BP" \n\t" YSCALEYUV2RGB1b(%%REGBP, %5) "pxor %%mm7, %%mm7 \n\t" - WRITEBGR24(%%REGb, 8280(%5), %%REGBP) + WRITEBGR24(%%REGb, DSTW_OFFSET"(%5)", %%REGBP) "pop %%"REG_BP" \n\t" "mov "ESP_OFFSET"(%5), %%"REG_b" \n\t" :: "c" (buf0), "d" (buf1), "S" (ubuf0), "D" (ubuf1), "m" (dest), @@ -1302,7 +1298,7 @@ static void RENAME(yuv2rgb555_1)(SwsContext *c, const int16_t *buf0, "paddusb "GREEN_DITHER"(%5), %%mm4 \n\t" "paddusb "RED_DITHER"(%5), %%mm5 \n\t" #endif - WRITERGB15(%%REGb, 8280(%5), %%REGBP) + WRITERGB15(%%REGb, DSTW_OFFSET"(%5)", %%REGBP) "pop %%"REG_BP" \n\t" "mov "ESP_OFFSET"(%5), %%"REG_b" \n\t" :: "c" (buf0), "d" (buf1), "S" (ubuf0), "D" (ubuf1), "m" (dest), @@ -1322,7 +1318,7 @@ static void RENAME(yuv2rgb555_1)(SwsContext *c, const int16_t *buf0, "paddusb "GREEN_DITHER"(%5), %%mm4 \n\t" "paddusb "RED_DITHER"(%5), %%mm5 \n\t" #endif - WRITERGB15(%%REGb, 8280(%5), %%REGBP) + WRITERGB15(%%REGb, DSTW_OFFSET"(%5)", %%REGBP) "pop %%"REG_BP" \n\t" "mov "ESP_OFFSET"(%5), %%"REG_b" \n\t" :: "c" (buf0), "d" (buf1), "S" (ubuf0), "D" (ubuf1), "m" (dest), @@ -1353,7 +1349,7 @@ static void RENAME(yuv2rgb565_1)(SwsContext *c, const int16_t *buf0, "paddusb "GREEN_DITHER"(%5), %%mm4 \n\t" "paddusb "RED_DITHER"(%5), %%mm5 \n\t" #endif - WRITERGB16(%%REGb, 8280(%5), %%REGBP) + WRITERGB16(%%REGb, DSTW_OFFSET"(%5)", %%REGBP) "pop %%"REG_BP" \n\t" "mov "ESP_OFFSET"(%5), %%"REG_b" \n\t" :: "c" (buf0), "d" (buf1), "S" (ubuf0), "D" (ubuf1), "m" (dest), @@ -1373,7 +1369,7 @@ static void RENAME(yuv2rgb565_1)(SwsContext *c, const int16_t *buf0, "paddusb "GREEN_DITHER"(%5), %%mm4 \n\t" "paddusb "RED_DITHER"(%5), %%mm5 \n\t" #endif - WRITERGB16(%%REGb, 8280(%5), %%REGBP) + WRITERGB16(%%REGb, DSTW_OFFSET"(%5)", %%REGBP) "pop %%"REG_BP" \n\t" "mov "ESP_OFFSET"(%5), %%"REG_b" \n\t" :: "c" (buf0), "d" (buf1), "S" (ubuf0), "D" (ubuf1), "m" (dest), @@ -1434,7 +1430,7 @@ static void RENAME(yuv2yuyv422_1)(SwsContext *c, const int16_t *buf0, "mov %4, %%"REG_b" \n\t" "push %%"REG_BP" \n\t" YSCALEYUV2PACKED1(%%REGBP, %5) - WRITEYUY2(%%REGb, 8280(%5), %%REGBP) + WRITEYUY2(%%REGb, DSTW_OFFSET"(%5)", %%REGBP) "pop %%"REG_BP" \n\t" "mov "ESP_OFFSET"(%5), %%"REG_b" \n\t" :: "c" (buf0), "d" (buf1), "S" (ubuf0), "D" (ubuf1), "m" (dest), @@ -1447,7 +1443,7 @@ static void RENAME(yuv2yuyv422_1)(SwsContext *c, const int16_t *buf0, "mov %4, %%"REG_b" \n\t" "push %%"REG_BP" \n\t" YSCALEYUV2PACKED1b(%%REGBP, %5) - WRITEYUY2(%%REGb, 8280(%5), %%REGBP) + WRITEYUY2(%%REGb, DSTW_OFFSET"(%5)", %%REGBP) "pop %%"REG_BP" \n\t" "mov "ESP_OFFSET"(%5), %%"REG_b" \n\t" :: "c" (buf0), "d" (buf1), "S" (ubuf0), "D" (ubuf1), "m" (dest), diff --git a/libswscale/yuv2rgb.c b/libswscale/yuv2rgb.c index 77c56a9772..7f7ec7873a 100644 --- a/libswscale/yuv2rgb.c +++ b/libswscale/yuv2rgb.c @@ -775,9 +775,13 @@ av_cold int ff_yuv2rgb_c_init_tables(SwsContext *c, const int inv_table[4], av_freep(&c->yuvTable); +#define ALLOC_YUV_TABLE(x) \ + c->yuvTable = av_malloc(x); \ + if (!c->yuvTable) \ + return AVERROR(ENOMEM); switch (bpp) { case 1: - c->yuvTable = av_malloc(1024); + ALLOC_YUV_TABLE(1024); y_table = c->yuvTable; yb = -(384 << 16) - oy; for (i = 0; i < 1024 - 110; i++) { @@ -792,7 +796,7 @@ av_cold int ff_yuv2rgb_c_init_tables(SwsContext *c, const int inv_table[4], rbase = isRgb ? 3 : 0; gbase = 1; bbase = isRgb ? 0 : 3; - c->yuvTable = av_malloc(1024 * 3); + ALLOC_YUV_TABLE(1024 * 3); y_table = c->yuvTable; yb = -(384 << 16) - oy; for (i = 0; i < 1024 - 110; i++) { @@ -811,7 +815,7 @@ av_cold int ff_yuv2rgb_c_init_tables(SwsContext *c, const int inv_table[4], rbase = isRgb ? 5 : 0; gbase = isRgb ? 2 : 3; bbase = isRgb ? 0 : 6; - c->yuvTable = av_malloc(1024 * 3); + ALLOC_YUV_TABLE(1024 * 3); y_table = c->yuvTable; yb = -(384 << 16) - oy; for (i = 0; i < 1024 - 38; i++) { @@ -830,7 +834,7 @@ av_cold int ff_yuv2rgb_c_init_tables(SwsContext *c, const int inv_table[4], rbase = isRgb ? 8 : 0; gbase = 4; bbase = isRgb ? 0 : 8; - c->yuvTable = av_malloc(1024 * 3 * 2); + ALLOC_YUV_TABLE(1024 * 3 * 2); y_table16 = c->yuvTable; yb = -(384 << 16) - oy; for (i = 0; i < 1024; i++) { @@ -853,7 +857,7 @@ av_cold int ff_yuv2rgb_c_init_tables(SwsContext *c, const int inv_table[4], rbase = isRgb ? bpp - 5 : 0; gbase = 5; bbase = isRgb ? 0 : (bpp - 5); - c->yuvTable = av_malloc(1024 * 3 * 2); + ALLOC_YUV_TABLE(1024 * 3 * 2); y_table16 = c->yuvTable; yb = -(384 << 16) - oy; for (i = 0; i < 1024; i++) { @@ -873,7 +877,7 @@ av_cold int ff_yuv2rgb_c_init_tables(SwsContext *c, const int inv_table[4], break; case 24: case 48: - c->yuvTable = av_malloc(1024); + ALLOC_YUV_TABLE(1024); y_table = c->yuvTable; yb = -(384 << 16) - oy; for (i = 0; i < 1024; i++) { @@ -895,7 +899,7 @@ av_cold int ff_yuv2rgb_c_init_tables(SwsContext *c, const int inv_table[4], needAlpha = CONFIG_SWSCALE_ALPHA && isALPHA(c->srcFormat); if (!needAlpha) abase = (base + 24) & 31; - c->yuvTable = av_malloc(1024 * 3 * 4); + ALLOC_YUV_TABLE(1024 * 3 * 4); y_table32 = c->yuvTable; yb = -(384 << 16) - oy; for (i = 0; i < 1024; i++) { diff --git a/tests/fate-run.sh b/tests/fate-run.sh index 48e9dd0bdc..391cef541c 100755 --- a/tests/fate-run.sh +++ b/tests/fate-run.sh @@ -42,7 +42,7 @@ compare(){ } do_tiny_psnr(){ - psnr=$(tests/tiny_psnr "$1" "$2" $cmp_unit $cmp_shift 0) + psnr=$(tests/tiny_psnr "$1" "$2" $cmp_unit $cmp_shift 0) || return 1 val=$(expr "$psnr" : ".*$3: *\([0-9.]*\)") size1=$(expr "$psnr" : '.*bytes: *\([0-9]*\)') size2=$(expr "$psnr" : '.*bytes:[ 0-9]*/ *\([0-9]*\)') @@ -200,12 +200,14 @@ pixfmts(){ $showfiltfmts $filter | awk -F '[ \r]' '/^INPUT/{ fmt=substr($3, 5); print fmt }' | sort >$in_fmts pix_fmts=$(comm -12 $scale_exclude_fmts $in_fmts) + outertest=$test for pix_fmt in $pix_fmts; do test=$pix_fmt video_filter "${prefilter_chain}format=$pix_fmt,$filter=$filter_args" -pix_fmt $pix_fmt done rm $in_fmts $scale_in_fmts $scale_out_fmts $scale_exclude_fmts + test=$outertest } mkdir -p "$outdir" diff --git a/tests/fate.sh b/tests/fate.sh index c474be7139..fd2d8fc21c 100755 --- a/tests/fate.sh +++ b/tests/fate.sh @@ -111,8 +111,8 @@ echo ${version} >version-$slot rm -rf "${build}" *.log mkdir -p ${build} -configure >configure.log 2>&1 || fail $? "error configuring" -compile >compile.log 2>&1 || fail $? "error compiling" -fate >test.log 2>&1 || fail $? "error testing" +configure >configure.log 2>&1 || fail 3 "error configuring" +compile >compile.log 2>&1 || fail 2 "error compiling" +fate >test.log 2>&1 || fail 1 "error testing" report 0 success clean diff --git a/tests/fate/real.mak b/tests/fate/real.mak index 82d7e3a579..81237e484b 100644 --- a/tests/fate/real.mak +++ b/tests/fate/real.mak @@ -31,8 +31,9 @@ fate-sipr-8k5: CMD = pcm -i $(TARGET_SAMPLES)/sipr/sipr_8k5.rm fate-sipr-8k5: REF = $(SAMPLES)/sipr/sipr_8k5.pcm FATE_SIPR += fate-sipr-16k -fate-sipr-16k: CMD = pcm -i $(TARGET_SAMPLES)/sipr/sipr_16k.rm +fate-sipr-16k: CMD = pcm -i $(TARGET_SAMPLES)/sipr/sipr_16k.rm -aframes 3250 fate-sipr-16k: REF = $(SAMPLES)/sipr/sipr_16k.pcm +fate-sipr-16k: SIZE_TOLERANCE = 40000 $(FATE_SIPR): CMP = oneoff diff --git a/tests/ref/fate/filter-metadata-scenedetect b/tests/ref/fate/filter-metadata-scenedetect index 67251dfe60..4e70723fe8 100644 --- a/tests/ref/fate/filter-metadata-scenedetect +++ b/tests/ref/fate/filter-metadata-scenedetect @@ -1,10 +1,10 @@ pkt_pts=1620|tag:lavfi.scene_score=1.000000 -pkt_pts=4140|tag:lavfi.scene_score=0.880000 +pkt_pts=4140|tag:lavfi.scene_score=0.876043 pkt_pts=5800|tag:lavfi.scene_score=1.000000 -pkt_pts=6720|tag:lavfi.scene_score=0.460000 +pkt_pts=6720|tag:lavfi.scene_score=0.463259 pkt_pts=8160|tag:lavfi.scene_score=1.000000 pkt_pts=9760|tag:lavfi.scene_score=1.000000 -pkt_pts=14080|tag:lavfi.scene_score=0.840000 +pkt_pts=14080|tag:lavfi.scene_score=0.841420 pkt_pts=15700|tag:lavfi.scene_score=1.000000 -pkt_pts=18500|tag:lavfi.scene_score=0.470000 +pkt_pts=18500|tag:lavfi.scene_score=0.471738 pkt_pts=21760|tag:lavfi.scene_score=1.000000 diff --git a/tests/ref/fate/filter-pp3 b/tests/ref/fate/filter-pp3 index ccf2eebc62..1af87610c8 100644 --- a/tests/ref/fate/filter-pp3 +++ b/tests/ref/fate/filter-pp3 @@ -1 +1 @@ -pp3 39af1a30d0ea0e906df264773adfcaa6 +pp3 c8277ef31ab01bad51356841c9634522 diff --git a/tests/ref/fate/vc1_sa10143 b/tests/ref/fate/vc1_sa10143 index 6a5137f712..c0ecc3bb9d 100644 --- a/tests/ref/fate/vc1_sa10143 +++ b/tests/ref/fate/vc1_sa10143 @@ -1,31 +1,31 @@ #tb 0: 1/25 0, 0, 0, 1, 518400, 0x89407f55 -0, 2, 2, 1, 518400, 0x8611849c +0, 2, 2, 1, 518400, 0xaa896afd 0, 3, 3, 1, 518400, 0x0e69ff59 -0, 4, 4, 1, 518400, 0xf31adb03 +0, 4, 4, 1, 518400, 0x0c30bfa0 0, 5, 5, 1, 518400, 0x1a5b6a69 -0, 6, 6, 1, 518400, 0x6ae6232e +0, 6, 6, 1, 518400, 0x23470858 0, 7, 7, 1, 518400, 0x9a4e3c54 -0, 8, 8, 1, 518400, 0xe5852b45 +0, 8, 8, 1, 518400, 0xad63160b 0, 9, 9, 1, 518400, 0x0fcfeebc -0, 10, 10, 1, 518400, 0x06e22dc3 +0, 10, 10, 1, 518400, 0x20b31777 0, 11, 11, 1, 518400, 0x9d79df09 -0, 12, 12, 1, 518400, 0xcb2c716f +0, 12, 12, 1, 518400, 0x3e86766f 0, 13, 13, 1, 518400, 0x638a8746 -0, 14, 14, 1, 518400, 0xf7032efd +0, 14, 14, 1, 518400, 0x7a6c1a0e 0, 15, 15, 1, 518400, 0x306f6cef -0, 16, 16, 1, 518400, 0xe83d2518 +0, 16, 16, 1, 518400, 0x81f81281 0, 17, 17, 1, 518400, 0x49ab5bf5 -0, 18, 18, 1, 518400, 0x6b336b6f +0, 18, 18, 1, 518400, 0x8f316e44 0, 19, 19, 1, 518400, 0x95ae00c9 -0, 20, 20, 1, 518400, 0x68ddb64f +0, 20, 20, 1, 518400, 0xf71bb7f5 0, 21, 21, 1, 518400, 0x5205ea68 -0, 22, 22, 1, 518400, 0xb088e617 +0, 22, 22, 1, 518400, 0x74a1d8b9 0, 23, 23, 1, 518400, 0xa3217616 -0, 24, 24, 1, 518400, 0x1723bc53 +0, 24, 24, 1, 518400, 0x2b28bbf8 0, 25, 25, 1, 518400, 0xf024872a -0, 26, 26, 1, 518400, 0x2e81a8bb +0, 26, 26, 1, 518400, 0x2fdbaaf3 0, 27, 27, 1, 518400, 0xa3a2418e -0, 28, 28, 1, 518400, 0xb7beffed +0, 28, 28, 1, 518400, 0x55bfe435 0, 29, 29, 1, 518400, 0x50fb6c94 0, 30, 30, 1, 518400, 0x5584bb40 diff --git a/tests/ref/fate/vp8-alpha b/tests/ref/fate/vp8-alpha index f857a87504..2b89817964 100644 --- a/tests/ref/fate/vp8-alpha +++ b/tests/ref/fate/vp8-alpha @@ -1,121 +1,121 @@ #tb 0: 1/1000 -0, 1, 1, 0, 2108, 0x59b92a34, S=1, 1900, 0x8fb3adc5 -0, 33, 33, 0, 142, 0x2f2a3fed, F=0x0, S=1, 160, 0xa13346af -0, 66, 66, 0, 157, 0x17804767, F=0x0, S=1, 209, 0x64115f15 -0, 100, 100, 0, 206, 0x537262ca, F=0x0, S=1, 317, 0x44a09dd0 -0, 133, 133, 0, 259, 0x73ff74b6, F=0x0, S=1, 384, 0x2ee2c588 -0, 166, 166, 0, 320, 0x0fcf8ce4, F=0x0, S=1, 415, 0xff68c953 -0, 200, 200, 0, 377, 0x8fffb5f5, F=0x0, S=1, 475, 0x4166f3eb -0, 233, 233, 0, 407, 0xe476c19e, F=0x0, S=1, 193, 0x3ff75489 -0, 266, 266, 0, 539, 0x90202334, F=0x0, S=1, 681, 0x776656b0 -0, 300, 300, 0, 560, 0xc6e2168d, F=0x0, S=1, 585, 0xddc81b8a -0, 333, 333, 0, 597, 0x201a32a7, F=0x0, S=1, 574, 0x8baa1d65 -0, 366, 366, 0, 770, 0xab2b8891, F=0x0, S=1, 666, 0xcd8e51eb -0, 400, 400, 0, 708, 0xc2386711, F=0x0, S=1, 706, 0x046b6444 -0, 433, 433, 0, 905, 0x7211c52d, F=0x0, S=1, 814, 0x5e288def -0, 466, 466, 0, 770, 0xda4f8574, F=0x0, S=1, 829, 0xa0e8a949 -0, 500, 500, 0, 955, 0xf9a1d77a, F=0x0, S=1, 857, 0x9b63b955 -0, 533, 533, 0, 970, 0xff4de39a, F=0x0, S=1, 153, 0x3b00416c -0, 566, 566, 0, 978, 0x12bcf81f, F=0x0, S=1, 1181, 0xce175555 -0, 600, 600, 0, 1233, 0x2903744a, F=0x0, S=1, 860, 0x737eb566 -0, 633, 633, 0, 1118, 0x7f274f50, F=0x0, S=1, 933, 0xb669c6b6 -0, 666, 666, 0, 941, 0x6bffd4b1, F=0x0, S=1, 1058, 0x07581cee -0, 700, 700, 0, 1598, 0xc007219f, F=0x0, S=1, 939, 0x2c0bdc45 -0, 733, 733, 0, 1218, 0x25d962b6, F=0x0, S=1, 1090, 0x96482341 -0, 766, 766, 0, 1200, 0x86b85be3, F=0x0, S=1, 189, 0x3f085309 -0, 800, 800, 0, 1329, 0x298a848a, F=0x0, S=1, 1426, 0x6ea3df12 -0, 833, 833, 0, 1500, 0xe437edec, F=0x0, S=1, 1244, 0x32836b8d -0, 866, 866, 0, 1288, 0xc4447dd5, F=0x0, S=1, 1289, 0x06a57b0f -0, 900, 900, 0, 1281, 0xb5bf7e9f, F=0x0, S=1, 1227, 0xd96d5697 -0, 933, 933, 0, 1372, 0x09be9014, F=0x0, S=1, 1556, 0x2630fbff -0, 966, 966, 0, 1238, 0x42ce6316, F=0x0, S=1, 1287, 0x1d3084f6 -0, 1000, 1000, 0, 1655, 0xb94b45c2, F=0x0, S=1, 1494, 0x34dbd1a4 -0, 1033, 1033, 0, 1164, 0xf6b93ad0, F=0x0, S=1, 1337, 0xba6d9673 -0, 1066, 1066, 0, 1084, 0x58c50fb5, F=0x0, S=1, 1384, 0x3fabb82b -0, 1100, 1100, 0, 1151, 0x0b3f3359, F=0x0, S=1, 1353, 0x08e2a1d7 -0, 1133, 1133, 0, 1277, 0xa3ae77e1, F=0x0, S=1, 1409, 0xf65cb9f7 -0, 1166, 1166, 0, 782, 0xdcf671ff, F=0x0, S=1, 1408, 0x01e2ac53 -0, 1200, 1200, 0, 926, 0xe913c286, F=0x0, S=1, 1320, 0x32e38e42 -0, 1233, 1233, 0, 970, 0x3d86e5ae, F=0x0, S=1, 1608, 0x40b52618 -0, 1266, 1266, 0, 1353, 0xe4f197b2, F=0x0, S=1, 1272, 0xf1d272a5 -0, 1300, 1300, 0, 685, 0x629b4ce4, F=0x0, S=1, 1257, 0x14845de9 -0, 1333, 1333, 0, 743, 0x6f1172a3, F=0x0, S=1, 1260, 0xa6c66fda -0, 1366, 1366, 0, 789, 0x94fc84cd, F=0x0, S=1, 1009, 0x7daaf2b0 -0, 1400, 1400, 0, 1460, 0x668adb82, F=0x0, S=1, 944, 0x44b6ccf5 -0, 1433, 1433, 0, 766, 0x49c884ef, F=0x0, S=1, 996, 0x8646e6dd -0, 1466, 1466, 0, 1037, 0x24831498, F=0x0, S=1, 983, 0x14a9e7a6 -0, 1500, 1500, 0, 943, 0x1f53d180, F=0x0, S=1, 1107, 0x02f72acb -0, 1533, 1533, 0, 1152, 0xbf6a35ae, F=0x0, S=1, 1026, 0xd57afda0 -0, 1566, 1566, 0, 730, 0x42806abf, F=0x0, S=1, 1029, 0xfb0402d5 -0, 1600, 1600, 0, 975, 0xa5ffec57, F=0x0, S=1, 1081, 0xe2890cea -0, 1633, 1633, 0, 970, 0xbe8ee224, F=0x0, S=1, 1151, 0x7b0d3b20 -0, 1666, 1666, 0, 1012, 0x20c6f0d8, F=0x0, S=1, 979, 0xc25cd69c -0, 1700, 1700, 0, 874, 0x1a2fb4da, F=0x0, S=1, 943, 0xdb2dc9f8 -0, 1733, 1733, 0, 869, 0xab0caf3d, F=0x0, S=1, 934, 0x48b9bfcc -0, 1766, 1766, 0, 863, 0xd8caa2e5, F=0x0, S=1, 874, 0x0b34b026 -0, 1800, 1800, 0, 1246, 0x47866cdc, F=0x0, S=1, 818, 0x0c908eeb -0, 1833, 1833, 0, 742, 0xa6296ac1, F=0x0, S=1, 921, 0x97b6b053 -0, 1866, 1866, 0, 828, 0x0b568d7a, F=0x0, S=1, 969, 0x3314dbfa -0, 1900, 1900, 0, 825, 0x6d329394, F=0x0, S=1, 982, 0x5f66e68c -0, 1933, 1933, 0, 836, 0x8ace8dfb, F=0x0, S=1, 929, 0x9ffdc2fd -0, 1966, 1966, 0, 1774, 0xd4686726, F=0x0, S=1, 909, 0x11a9c07a -0, 2000, 2000, 0, 1803, 0x08c879ce, F=0x0, S=1, 1525, 0x1e11f02f -0, 2033, 2033, 0, 518, 0x7c32fc72, F=0x0, S=1, 785, 0xfc1f792a -0, 2066, 2066, 0, 790, 0x3dac8aa0, F=0x0, S=1, 876, 0x0918c88d -0, 2100, 2100, 0, 927, 0x4feccb24, F=0x0, S=1, 1059, 0xbcaa05c7 -0, 2133, 2133, 0, 835, 0x29d39266, F=0x0, S=1, 980, 0x4913e409 -0, 2166, 2166, 0, 951, 0xc1dddd12, F=0x0, S=1, 1041, 0x0541047e -0, 2200, 2200, 0, 876, 0x2f6eb89d, F=0x0, S=1, 949, 0x2d56c53b -0, 2233, 2233, 0, 959, 0xf0dedabd, F=0x0, S=1, 1022, 0x8d33f5fa -0, 2266, 2266, 0, 860, 0x9274ab39, F=0x0, S=1, 1061, 0x289c0132 -0, 2300, 2300, 0, 863, 0x7058ba30, F=0x0, S=1, 940, 0x1f32d4a3 -0, 2333, 2333, 0, 1021, 0xcabdf84f, F=0x0, S=1, 887, 0xda8ab95e -0, 2366, 2366, 0, 897, 0x9867c8e8, F=0x0, S=1, 840, 0xd93eaaf5 -0, 2400, 2400, 0, 897, 0x6a16b5db, F=0x0, S=1, 977, 0x7b77dc9b -0, 2433, 2433, 0, 953, 0xe9b4cf1f, F=0x0, S=1, 921, 0x75a8ca45 -0, 2466, 2466, 0, 847, 0x0335ad37, F=0x0, S=1, 1000, 0x2691f3bd -0, 2500, 2500, 0, 902, 0x3360b315, F=0x0, S=1, 1008, 0xd5e1deb6 -0, 2533, 2533, 0, 881, 0xf5309d59, F=0x0, S=1, 1113, 0xdbef3065 -0, 2566, 2566, 0, 974, 0x7c2de3ce, F=0x0, S=1, 1086, 0x365626bb -0, 2600, 2600, 0, 974, 0xf42bd9f5, F=0x0, S=1, 1039, 0xa7e9060d -0, 2633, 2633, 0, 1029, 0x7c33f4d0, F=0x0, S=1, 1041, 0xf4affa59 -0, 2666, 2666, 0, 881, 0x9021a565, F=0x0, S=1, 1039, 0xc1e00521 -0, 2700, 2700, 0, 1157, 0xe1c136f7, F=0x0, S=1, 917, 0x357ac7d3 -0, 2733, 2733, 0, 649, 0xdffb3cb7, F=0x0, S=1, 976, 0xa386e05e -0, 2766, 2766, 0, 758, 0xb67875f3, F=0x0, S=1, 1041, 0xae4e0a63 -0, 2800, 2800, 0, 1105, 0x8ffb1a26, F=0x0, S=1, 962, 0x211ddc5e -0, 2833, 2833, 0, 866, 0xa60eb2d9, F=0x0, S=1, 929, 0xe9e4c84b -0, 2866, 2866, 0, 912, 0xcd34bf9b, F=0x0, S=1, 946, 0xfce9d359 -0, 2900, 2900, 0, 868, 0x5651a343, F=0x0, S=1, 809, 0x624a8ef9 -0, 2933, 2933, 0, 997, 0xfa66eaeb, F=0x0, S=1, 992, 0xc913e5e2 -0, 2966, 2966, 0, 1111, 0x3f272497, F=0x0, S=1, 1007, 0xf78ee6a7 -0, 3000, 3000, 0, 842, 0xe442999f, F=0x0, S=1, 972, 0x25a0d25c -0, 3033, 3033, 0, 1030, 0x6f97ffad, F=0x0, S=1, 993, 0x4059fd6b -0, 3066, 3066, 0, 1176, 0x66e64926, F=0x0, S=1, 951, 0x2762cdf1 -0, 3100, 3100, 0, 803, 0xfd1699cb, F=0x0, S=1, 959, 0x5cf9d56c -0, 3133, 3133, 0, 972, 0x1cdff00e, F=0x0, S=1, 1023, 0xeaf20900 -0, 3166, 3166, 0, 907, 0x17f8acca, F=0x0, S=1, 1054, 0xeb010c4d -0, 3200, 3200, 0, 915, 0x3569b545, F=0x0, S=1, 987, 0x73b2e159 -0, 3233, 3233, 0, 1021, 0x14c5076a, F=0x0, S=1, 1007, 0x6c4bf7f0 -0, 3266, 3266, 0, 837, 0xbf86b0ef, F=0x0, S=1, 963, 0xf472d31a -0, 3300, 3300, 0, 885, 0x1caac123, F=0x0, S=1, 1052, 0x2b7bfd20 -0, 3333, 3333, 0, 1355, 0x299e8d3c, F=0x0, S=1, 858, 0x2bbca3f0 -0, 3366, 3366, 0, 784, 0xb0bd7e9d, F=0x0, S=1, 969, 0xc865dc00 -0, 3400, 3400, 0, 991, 0xbc7ddda9, F=0x0, S=1, 1028, 0x801b00a6 -0, 3433, 3433, 0, 986, 0xb356f6b1, F=0x0, S=1, 1056, 0x8b840add -0, 3466, 3466, 0, 978, 0x94a3e87e, F=0x0, S=1, 1018, 0xe766fa52 -0, 3500, 3500, 0, 976, 0x55ddd14a, F=0x0, S=1, 992, 0x58a9ddfe -0, 3533, 3533, 0, 1241, 0x1ec867f7, F=0x0, S=1, 966, 0xa329e84f -0, 3566, 3566, 0, 975, 0xecf5dbb3, F=0x0, S=1, 899, 0xa7539f4d -0, 3600, 3600, 0, 1129, 0xb7243037, F=0x0, S=1, 1057, 0xbd0d10bd -0, 3633, 3633, 0, 913, 0xe5f1d03d, F=0x0, S=1, 1092, 0xeb9621f8 -0, 3666, 3666, 0, 943, 0x87d0ed78, F=0x0, S=1, 1057, 0x079c1054 -0, 3700, 3700, 0, 917, 0x536cc3fd, F=0x0, S=1, 946, 0xd2b9d0e2 -0, 3733, 3733, 0, 892, 0x4dffb1e2, F=0x0, S=1, 930, 0x70c9cc40 -0, 3766, 3766, 0, 957, 0x1a98e71c, F=0x0, S=1, 719, 0x6fec614a -0, 3800, 3800, 0, 893, 0xf405b2c3, F=0x0, S=1, 821, 0x63529cab -0, 3833, 3833, 0, 978, 0xa0a8d5f6, F=0x0, S=1, 745, 0x3c616219 -0, 3866, 3866, 0, 887, 0xfa7cb65d, F=0x0, S=1, 768, 0xb8f07885 -0, 3900, 3900, 0, 867, 0xd808ade7, F=0x0, S=1, 783, 0xf82b6b9a -0, 3933, 3933, 0, 1068, 0x6f8b135a, F=0x0, S=1, 807, 0x52028d50 -0, 3966, 3966, 0, 2010, 0x536fe0b6, F=0x0, S=1, 1512, 0x690aeb55 +0, 0, 0, 0, 2108, 0x59b92a34, S=1, 1900, 0x8fb3adc5 +0, 32, 32, 0, 142, 0x2f2a3fed, F=0x0, S=1, 160, 0xa13346af +0, 65, 65, 0, 157, 0x17804767, F=0x0, S=1, 209, 0x64115f15 +0, 99, 99, 0, 206, 0x537262ca, F=0x0, S=1, 317, 0x44a09dd0 +0, 132, 132, 0, 259, 0x73ff74b6, F=0x0, S=1, 384, 0x2ee2c588 +0, 165, 165, 0, 320, 0x0fcf8ce4, F=0x0, S=1, 415, 0xff68c953 +0, 199, 199, 0, 377, 0x8fffb5f5, F=0x0, S=1, 475, 0x4166f3eb +0, 232, 232, 0, 407, 0xe476c19e, F=0x0, S=1, 193, 0x3ff75489 +0, 265, 265, 0, 539, 0x90202334, F=0x0, S=1, 681, 0x776656b0 +0, 299, 299, 0, 560, 0xc6e2168d, F=0x0, S=1, 585, 0xddc81b8a +0, 332, 332, 0, 597, 0x201a32a7, F=0x0, S=1, 574, 0x8baa1d65 +0, 365, 365, 0, 770, 0xab2b8891, F=0x0, S=1, 666, 0xcd8e51eb +0, 399, 399, 0, 708, 0xc2386711, F=0x0, S=1, 706, 0x046b6444 +0, 432, 432, 0, 905, 0x7211c52d, F=0x0, S=1, 814, 0x5e288def +0, 465, 465, 0, 770, 0xda4f8574, F=0x0, S=1, 829, 0xa0e8a949 +0, 499, 499, 0, 955, 0xf9a1d77a, F=0x0, S=1, 857, 0x9b63b955 +0, 532, 532, 0, 970, 0xff4de39a, F=0x0, S=1, 153, 0x3b00416c +0, 565, 565, 0, 978, 0x12bcf81f, F=0x0, S=1, 1181, 0xce175555 +0, 599, 599, 0, 1233, 0x2903744a, F=0x0, S=1, 860, 0x737eb566 +0, 632, 632, 0, 1118, 0x7f274f50, F=0x0, S=1, 933, 0xb669c6b6 +0, 665, 665, 0, 941, 0x6bffd4b1, F=0x0, S=1, 1058, 0x07581cee +0, 699, 699, 0, 1598, 0xc007219f, F=0x0, S=1, 939, 0x2c0bdc45 +0, 732, 732, 0, 1218, 0x25d962b6, F=0x0, S=1, 1090, 0x96482341 +0, 765, 765, 0, 1200, 0x86b85be3, F=0x0, S=1, 189, 0x3f085309 +0, 799, 799, 0, 1329, 0x298a848a, F=0x0, S=1, 1426, 0x6ea3df12 +0, 832, 832, 0, 1500, 0xe437edec, F=0x0, S=1, 1244, 0x32836b8d +0, 865, 865, 0, 1288, 0xc4447dd5, F=0x0, S=1, 1289, 0x06a57b0f +0, 899, 899, 0, 1281, 0xb5bf7e9f, F=0x0, S=1, 1227, 0xd96d5697 +0, 932, 932, 0, 1372, 0x09be9014, F=0x0, S=1, 1556, 0x2630fbff +0, 965, 965, 0, 1238, 0x42ce6316, F=0x0, S=1, 1287, 0x1d3084f6 +0, 999, 999, 0, 1655, 0xb94b45c2, F=0x0, S=1, 1494, 0x34dbd1a4 +0, 1032, 1032, 0, 1164, 0xf6b93ad0, F=0x0, S=1, 1337, 0xba6d9673 +0, 1065, 1065, 0, 1084, 0x58c50fb5, F=0x0, S=1, 1384, 0x3fabb82b +0, 1099, 1099, 0, 1151, 0x0b3f3359, F=0x0, S=1, 1353, 0x08e2a1d7 +0, 1132, 1132, 0, 1277, 0xa3ae77e1, F=0x0, S=1, 1409, 0xf65cb9f7 +0, 1165, 1165, 0, 782, 0xdcf671ff, F=0x0, S=1, 1408, 0x01e2ac53 +0, 1199, 1199, 0, 926, 0xe913c286, F=0x0, S=1, 1320, 0x32e38e42 +0, 1232, 1232, 0, 970, 0x3d86e5ae, F=0x0, S=1, 1608, 0x40b52618 +0, 1265, 1265, 0, 1353, 0xe4f197b2, F=0x0, S=1, 1272, 0xf1d272a5 +0, 1299, 1299, 0, 685, 0x629b4ce4, F=0x0, S=1, 1257, 0x14845de9 +0, 1332, 1332, 0, 743, 0x6f1172a3, F=0x0, S=1, 1260, 0xa6c66fda +0, 1365, 1365, 0, 789, 0x94fc84cd, F=0x0, S=1, 1009, 0x7daaf2b0 +0, 1399, 1399, 0, 1460, 0x668adb82, F=0x0, S=1, 944, 0x44b6ccf5 +0, 1432, 1432, 0, 766, 0x49c884ef, F=0x0, S=1, 996, 0x8646e6dd +0, 1465, 1465, 0, 1037, 0x24831498, F=0x0, S=1, 983, 0x14a9e7a6 +0, 1499, 1499, 0, 943, 0x1f53d180, F=0x0, S=1, 1107, 0x02f72acb +0, 1532, 1532, 0, 1152, 0xbf6a35ae, F=0x0, S=1, 1026, 0xd57afda0 +0, 1565, 1565, 0, 730, 0x42806abf, F=0x0, S=1, 1029, 0xfb0402d5 +0, 1599, 1599, 0, 975, 0xa5ffec57, F=0x0, S=1, 1081, 0xe2890cea +0, 1632, 1632, 0, 970, 0xbe8ee224, F=0x0, S=1, 1151, 0x7b0d3b20 +0, 1665, 1665, 0, 1012, 0x20c6f0d8, F=0x0, S=1, 979, 0xc25cd69c +0, 1699, 1699, 0, 874, 0x1a2fb4da, F=0x0, S=1, 943, 0xdb2dc9f8 +0, 1732, 1732, 0, 869, 0xab0caf3d, F=0x0, S=1, 934, 0x48b9bfcc +0, 1765, 1765, 0, 863, 0xd8caa2e5, F=0x0, S=1, 874, 0x0b34b026 +0, 1799, 1799, 0, 1246, 0x47866cdc, F=0x0, S=1, 818, 0x0c908eeb +0, 1832, 1832, 0, 742, 0xa6296ac1, F=0x0, S=1, 921, 0x97b6b053 +0, 1865, 1865, 0, 828, 0x0b568d7a, F=0x0, S=1, 969, 0x3314dbfa +0, 1899, 1899, 0, 825, 0x6d329394, F=0x0, S=1, 982, 0x5f66e68c +0, 1932, 1932, 0, 836, 0x8ace8dfb, F=0x0, S=1, 929, 0x9ffdc2fd +0, 1965, 1965, 0, 1774, 0xd4686726, F=0x0, S=1, 909, 0x11a9c07a +0, 1999, 1999, 0, 1803, 0x08c879ce, F=0x0, S=1, 1525, 0x1e11f02f +0, 2032, 2032, 0, 518, 0x7c32fc72, F=0x0, S=1, 785, 0xfc1f792a +0, 2065, 2065, 0, 790, 0x3dac8aa0, F=0x0, S=1, 876, 0x0918c88d +0, 2099, 2099, 0, 927, 0x4feccb24, F=0x0, S=1, 1059, 0xbcaa05c7 +0, 2132, 2132, 0, 835, 0x29d39266, F=0x0, S=1, 980, 0x4913e409 +0, 2165, 2165, 0, 951, 0xc1dddd12, F=0x0, S=1, 1041, 0x0541047e +0, 2199, 2199, 0, 876, 0x2f6eb89d, F=0x0, S=1, 949, 0x2d56c53b +0, 2232, 2232, 0, 959, 0xf0dedabd, F=0x0, S=1, 1022, 0x8d33f5fa +0, 2265, 2265, 0, 860, 0x9274ab39, F=0x0, S=1, 1061, 0x289c0132 +0, 2299, 2299, 0, 863, 0x7058ba30, F=0x0, S=1, 940, 0x1f32d4a3 +0, 2332, 2332, 0, 1021, 0xcabdf84f, F=0x0, S=1, 887, 0xda8ab95e +0, 2365, 2365, 0, 897, 0x9867c8e8, F=0x0, S=1, 840, 0xd93eaaf5 +0, 2399, 2399, 0, 897, 0x6a16b5db, F=0x0, S=1, 977, 0x7b77dc9b +0, 2432, 2432, 0, 953, 0xe9b4cf1f, F=0x0, S=1, 921, 0x75a8ca45 +0, 2465, 2465, 0, 847, 0x0335ad37, F=0x0, S=1, 1000, 0x2691f3bd +0, 2499, 2499, 0, 902, 0x3360b315, F=0x0, S=1, 1008, 0xd5e1deb6 +0, 2532, 2532, 0, 881, 0xf5309d59, F=0x0, S=1, 1113, 0xdbef3065 +0, 2565, 2565, 0, 974, 0x7c2de3ce, F=0x0, S=1, 1086, 0x365626bb +0, 2599, 2599, 0, 974, 0xf42bd9f5, F=0x0, S=1, 1039, 0xa7e9060d +0, 2632, 2632, 0, 1029, 0x7c33f4d0, F=0x0, S=1, 1041, 0xf4affa59 +0, 2665, 2665, 0, 881, 0x9021a565, F=0x0, S=1, 1039, 0xc1e00521 +0, 2699, 2699, 0, 1157, 0xe1c136f7, F=0x0, S=1, 917, 0x357ac7d3 +0, 2732, 2732, 0, 649, 0xdffb3cb7, F=0x0, S=1, 976, 0xa386e05e +0, 2765, 2765, 0, 758, 0xb67875f3, F=0x0, S=1, 1041, 0xae4e0a63 +0, 2799, 2799, 0, 1105, 0x8ffb1a26, F=0x0, S=1, 962, 0x211ddc5e +0, 2832, 2832, 0, 866, 0xa60eb2d9, F=0x0, S=1, 929, 0xe9e4c84b +0, 2865, 2865, 0, 912, 0xcd34bf9b, F=0x0, S=1, 946, 0xfce9d359 +0, 2899, 2899, 0, 868, 0x5651a343, F=0x0, S=1, 809, 0x624a8ef9 +0, 2932, 2932, 0, 997, 0xfa66eaeb, F=0x0, S=1, 992, 0xc913e5e2 +0, 2965, 2965, 0, 1111, 0x3f272497, F=0x0, S=1, 1007, 0xf78ee6a7 +0, 2999, 2999, 0, 842, 0xe442999f, F=0x0, S=1, 972, 0x25a0d25c +0, 3032, 3032, 0, 1030, 0x6f97ffad, F=0x0, S=1, 993, 0x4059fd6b +0, 3065, 3065, 0, 1176, 0x66e64926, F=0x0, S=1, 951, 0x2762cdf1 +0, 3099, 3099, 0, 803, 0xfd1699cb, F=0x0, S=1, 959, 0x5cf9d56c +0, 3132, 3132, 0, 972, 0x1cdff00e, F=0x0, S=1, 1023, 0xeaf20900 +0, 3165, 3165, 0, 907, 0x17f8acca, F=0x0, S=1, 1054, 0xeb010c4d +0, 3199, 3199, 0, 915, 0x3569b545, F=0x0, S=1, 987, 0x73b2e159 +0, 3232, 3232, 0, 1021, 0x14c5076a, F=0x0, S=1, 1007, 0x6c4bf7f0 +0, 3265, 3265, 0, 837, 0xbf86b0ef, F=0x0, S=1, 963, 0xf472d31a +0, 3299, 3299, 0, 885, 0x1caac123, F=0x0, S=1, 1052, 0x2b7bfd20 +0, 3332, 3332, 0, 1355, 0x299e8d3c, F=0x0, S=1, 858, 0x2bbca3f0 +0, 3365, 3365, 0, 784, 0xb0bd7e9d, F=0x0, S=1, 969, 0xc865dc00 +0, 3399, 3399, 0, 991, 0xbc7ddda9, F=0x0, S=1, 1028, 0x801b00a6 +0, 3432, 3432, 0, 986, 0xb356f6b1, F=0x0, S=1, 1056, 0x8b840add +0, 3465, 3465, 0, 978, 0x94a3e87e, F=0x0, S=1, 1018, 0xe766fa52 +0, 3499, 3499, 0, 976, 0x55ddd14a, F=0x0, S=1, 992, 0x58a9ddfe +0, 3532, 3532, 0, 1241, 0x1ec867f7, F=0x0, S=1, 966, 0xa329e84f +0, 3565, 3565, 0, 975, 0xecf5dbb3, F=0x0, S=1, 899, 0xa7539f4d +0, 3599, 3599, 0, 1129, 0xb7243037, F=0x0, S=1, 1057, 0xbd0d10bd +0, 3632, 3632, 0, 913, 0xe5f1d03d, F=0x0, S=1, 1092, 0xeb9621f8 +0, 3665, 3665, 0, 943, 0x87d0ed78, F=0x0, S=1, 1057, 0x079c1054 +0, 3699, 3699, 0, 917, 0x536cc3fd, F=0x0, S=1, 946, 0xd2b9d0e2 +0, 3732, 3732, 0, 892, 0x4dffb1e2, F=0x0, S=1, 930, 0x70c9cc40 +0, 3765, 3765, 0, 957, 0x1a98e71c, F=0x0, S=1, 719, 0x6fec614a +0, 3799, 3799, 0, 893, 0xf405b2c3, F=0x0, S=1, 821, 0x63529cab +0, 3832, 3832, 0, 978, 0xa0a8d5f6, F=0x0, S=1, 745, 0x3c616219 +0, 3865, 3865, 0, 887, 0xfa7cb65d, F=0x0, S=1, 768, 0xb8f07885 +0, 3899, 3899, 0, 867, 0xd808ade7, F=0x0, S=1, 783, 0xf82b6b9a +0, 3932, 3932, 0, 1068, 0x6f8b135a, F=0x0, S=1, 807, 0x52028d50 +0, 3965, 3965, 0, 2010, 0x536fe0b6, F=0x0, S=1, 1512, 0x690aeb55 diff --git a/tests/ref/lavf/wtv b/tests/ref/lavf/wtv index fe1b83c1ea..8d69f7998a 100644 --- a/tests/ref/lavf/wtv +++ b/tests/ref/lavf/wtv @@ -1,3 +1,3 @@ -98dd5205889313542da71351fbaf4172 *./tests/data/lavf/lavf.wtv +13cbdaf2c5e7c97991781cc48d9a958f *./tests/data/lavf/lavf.wtv 413696 ./tests/data/lavf/lavf.wtv ./tests/data/lavf/lavf.wtv CRC=0x71287e25 diff --git a/tests/ref/seek/lavf-wtv b/tests/ref/seek/lavf-wtv index 71703c5d0a..2808c109a1 100644 --- a/tests/ref/seek/lavf-wtv +++ b/tests/ref/seek/lavf-wtv @@ -1,48 +1,48 @@ -ret: 0 st: 1 flags:1 dts: 0.029093 pts: 0.029093 pos: 26344 size: 208 +ret: 0 st: 1 flags:1 dts: 0.029093 pts: 0.029093 pos: 26288 size: 208 ret: 0 st:-1 flags:0 ts:-1.000000 -ret: 0 st: 1 flags:1 dts: 0.029093 pts: 0.029093 pos: 26344 size: 208 +ret: 0 st: 1 flags:1 dts: 0.029093 pts: 0.029093 pos: 26288 size: 208 ret: 0 st:-1 flags:1 ts: 1.894167 -ret: 0 st: 1 flags:1 dts: 0.734399 pts: 0.734399 pos: 294744 size: 209 +ret: 0 st: 1 flags:1 dts: 0.734399 pts: 0.734399 pos: 294688 size: 209 ret: 0 st: 0 flags:0 ts: 0.788334 -ret: 0 st: 1 flags:1 dts: 0.734399 pts: 0.734399 pos: 294744 size: 209 +ret: 0 st: 1 flags:1 dts: 0.734399 pts: 0.734399 pos: 294688 size: 209 ret: 0 st: 0 flags:1 ts:-0.317499 -ret: 0 st: 1 flags:1 dts: 0.029093 pts: 0.029093 pos: 26344 size: 208 +ret: 0 st: 1 flags:1 dts: 0.029093 pts: 0.029093 pos: 26288 size: 208 ret:-1 st: 1 flags:0 ts: 2.576668 ret: 0 st: 1 flags:1 ts: 1.470835 -ret: 0 st: 1 flags:1 dts: 0.734399 pts: 0.734399 pos: 294744 size: 209 +ret: 0 st: 1 flags:1 dts: 0.734399 pts: 0.734399 pos: 294688 size: 209 ret: 0 st:-1 flags:0 ts: 0.365002 -ret: 0 st: 1 flags:1 dts: 0.029093 pts: 0.029093 pos: 26344 size: 208 +ret: 0 st: 1 flags:1 dts: 0.029093 pts: 0.029093 pos: 26288 size: 208 ret: 0 st:-1 flags:1 ts:-0.740831 -ret: 0 st: 1 flags:1 dts: 0.029093 pts: 0.029093 pos: 26344 size: 208 +ret: 0 st: 1 flags:1 dts: 0.029093 pts: 0.029093 pos: 26288 size: 208 ret:-1 st: 0 flags:0 ts: 2.153336 ret: 0 st: 0 flags:1 ts: 1.047503 -ret: 0 st: 1 flags:1 dts: 0.029093 pts: 0.029093 pos: 26344 size: 208 +ret: 0 st: 1 flags:1 dts: 0.029093 pts: 0.029093 pos: 26288 size: 208 ret: 0 st: 1 flags:0 ts:-0.058330 -ret: 0 st: 1 flags:1 dts: 0.029093 pts: 0.029093 pos: 26344 size: 208 +ret: 0 st: 1 flags:1 dts: 0.029093 pts: 0.029093 pos: 26288 size: 208 ret: 0 st: 1 flags:1 ts: 2.835837 -ret: 0 st: 1 flags:1 dts: 0.734399 pts: 0.734399 pos: 294744 size: 209 +ret: 0 st: 1 flags:1 dts: 0.734399 pts: 0.734399 pos: 294688 size: 209 ret:-1 st:-1 flags:0 ts: 1.730004 ret: 0 st:-1 flags:1 ts: 0.624171 -ret: 0 st: 1 flags:1 dts: 0.029093 pts: 0.029093 pos: 26344 size: 208 +ret: 0 st: 1 flags:1 dts: 0.029093 pts: 0.029093 pos: 26288 size: 208 ret: 0 st: 0 flags:0 ts:-0.481662 -ret: 0 st: 1 flags:1 dts: 0.029093 pts: 0.029093 pos: 26344 size: 208 +ret: 0 st: 1 flags:1 dts: 0.029093 pts: 0.029093 pos: 26288 size: 208 ret: 0 st: 0 flags:1 ts: 2.412505 -ret: 0 st: 1 flags:1 dts: 0.734399 pts: 0.734399 pos: 294744 size: 209 +ret: 0 st: 1 flags:1 dts: 0.734399 pts: 0.734399 pos: 294688 size: 209 ret:-1 st: 1 flags:0 ts: 1.306672 ret: 0 st: 1 flags:1 ts: 0.200839 -ret: 0 st: 1 flags:1 dts: 0.211950 pts: 0.211950 pos: 99352 size: 209 +ret: 0 st: 1 flags:1 dts: 0.211950 pts: 0.211950 pos: 99296 size: 209 ret: 0 st:-1 flags:0 ts:-0.904994 -ret: 0 st: 1 flags:1 dts: 0.029093 pts: 0.029093 pos: 26344 size: 208 +ret: 0 st: 1 flags:1 dts: 0.029093 pts: 0.029093 pos: 26288 size: 208 ret: 0 st:-1 flags:1 ts: 1.989173 -ret: 0 st: 1 flags:1 dts: 0.734399 pts: 0.734399 pos: 294744 size: 209 +ret: 0 st: 1 flags:1 dts: 0.734399 pts: 0.734399 pos: 294688 size: 209 ret: 0 st: 0 flags:0 ts: 0.883340 -ret: 0 st: 1 flags:1 dts: 0.734399 pts: 0.734399 pos: 294744 size: 209 +ret: 0 st: 1 flags:1 dts: 0.734399 pts: 0.734399 pos: 294688 size: 209 ret: 0 st: 0 flags:1 ts:-0.222493 -ret: 0 st: 1 flags:1 dts: 0.029093 pts: 0.029093 pos: 26344 size: 208 +ret: 0 st: 1 flags:1 dts: 0.029093 pts: 0.029093 pos: 26288 size: 208 ret:-1 st: 1 flags:0 ts: 2.671674 ret: 0 st: 1 flags:1 ts: 1.565841 -ret: 0 st: 1 flags:1 dts: 0.734399 pts: 0.734399 pos: 294744 size: 209 +ret: 0 st: 1 flags:1 dts: 0.734399 pts: 0.734399 pos: 294688 size: 209 ret: 0 st:-1 flags:0 ts: 0.460008 -ret: 0 st: 1 flags:1 dts: 0.029093 pts: 0.029093 pos: 26344 size: 208 +ret: 0 st: 1 flags:1 dts: 0.029093 pts: 0.029093 pos: 26288 size: 208 ret: 0 st:-1 flags:1 ts:-0.645825 -ret: 0 st: 1 flags:1 dts: 0.029093 pts: 0.029093 pos: 26344 size: 208 +ret: 0 st: 1 flags:1 dts: 0.029093 pts: 0.029093 pos: 26288 size: 208 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