diff --git a/Changelog b/Changelog index 98bd2c6b9d..872a97d20e 100644 --- a/Changelog +++ b/Changelog @@ -1,7 +1,537 @@ Entries are sorted chronologically from oldest to youngest within each release, releases are sorted from youngest to oldest. -version : +version 2.5.11 +- MAINTAINERS: remove unmaintained releases +- avcodec/jpeg2000dec: More completely check cdef +- avutil/opt: check for and handle errors in av_opt_set_dict2() +- avcodec/flacenc: fix calculation of bits required in case of custom sample rate +- avformat: Document urls a bit +- avformat/libquvi: Set default demuxer and protocol limitations +- avformat/concat: Check protocol prefix +- doc/demuxers: Document enable_drefs and use_absolute_path +- avcodec/mjpegdec: Check for end for both bytes in unescaping +- avcodec/mpegvideo_enc: Check for integer overflow in ff_mpv_reallocate_putbitbuffer() +- avformat/avformat: Replace some references to filenames by urls +- avcodec/wmaenc: Check ff_wma_init() for failure +- avcodec/mpeg12enc: Move high resolution thread check to before initializing threads +- avformat/avio: Limit url option parsing to the documented cases +- avcodec/ass_split: Fix null pointer dereference in ff_ass_style_get() +- mov: Add an option to toggle dref opening +- avcodec/gif: Fix lzw buffer size +- avcodec/put_bits: Assert buf_ptr in flush_put_bits() +- avcodec/tiff: Check subsample & rps values more completely +- swscale/swscale: Add some sanity checks for srcSlice* parameters +- swscale/x86/rgb2rgb_template: Fix planar2x() for short width +- swscale/swscale_unscaled: Fix odd height inputs for bayer_to_yv12_wrapper() +- swscale/swscale_unscaled: Fix odd height inputs for bayer_to_rgb24_wrapper() +- avcodec/aacenc: Check both channels for finiteness +- swscale/swscale-test: Fix slice height in random reference data creation. +- dca: fix misaligned access in avpriv_dca_convert_bitstream +- brstm: fix missing closing brace +- brstm: also allocate b->table in read_packet +- brstm: make sure an ADPC chunk was read for adpcm_thp +- vorbisdec: reject rangebits 0 with non-0 partitions +- vorbisdec: reject channel mapping with less than two channels +- ffmdec: reset packet_end in case of failure +- avformat/ipmovie: put video decoding_map_size into packet and use it in decoder +- avcodec/samidec: make sure to properly restore parsing context after a tag + +version 2.5.10 +- configure: bump copyright year to 2016 +- avformat/hls: Even stricter URL checks +- avformat/hls: More strict url checks +- swscale/utils: Detect and skip unneeded sws_setColorspaceDetails() calls +- swscale/yuv2rgb: Increase YUV2RGB table headroom +- swscale/yuv2rgb: Factor YUVRGB_TABLE_LUMA_HEADROOM out +- avformat/hls: forbid all protocols except http(s) & file +- avformat/aviobuf: Fix end check in put_str16() +- avformat/asfenc: Check pts +- avcodec/mpeg4video: Check time_incr +- avcodec/wavpackenc: Check the number of channels +- avcodec/wavpackenc: Headers are per channel +- avcodec/dvdec: Fix "left shift of negative value -254" +- avcodec/mjpegdec: Fix negative shift +- avcodec/mss2: Check for repeat overflow +- avformat: Add integer fps from 31 to 60 to get_std_framerate() +- avcodec/mpegvideo_enc: Clip bits_per_raw_sample within valid range +- avfilter/vf_scale: set proper out frame color range +- avcodec/motion_est: Fix mv_penalty table size +- avcodec/h264_slice: Fix integer overflow in implicit weight computation +- swscale/utils: Use normal bilinear scaler if fast cannot be used due to tiny dimensions +- avcodec/put_bits: Always check buffer end before writing +- mjpegdec: extend check for incompatible values of s->rgb and s->ls +- swscale/utils: Fix intermediate format for cascaded alpha downscaling +- avcodec/h264_refs: Fix long_idx check +- avfilter/vf_mpdecimate: Add missing emms_c() +- avformat/mxfenc: Do not crash if there is no packet in the first stream +- avformat/utils: estimate_timings_from_pts - increase retry counter, fixes invalid duration for ts files with hevc codec +- avformat/matroskaenc: Check codecdelay before use +- avutil/mathematics: Fix division by 0 +- x86/float_dsp: zero extend offset from ff_scalarproduct_float_sse +- avcodec/mpeg4videodec: also for empty partitioned slices +- nuv: sanitize negative fps rate +- rawdec: only exempt BIT0 with need_copy from buffer sanity check +- mlvdec: check that index_entries exist +- nutdec: reject negative value_len in read_sm_data +- xwddec: prevent overflow of lsize * avctx->height +- nutdec: only copy the header if it exists +- exr: fix out of bounds read in get_code +- on2avc: limit number of bits to 30 in get_egolomb +- sonic: make sure num_taps * channels is not larger than frame_size +- opus_silk: fix typo causing overflow in silk_stabilize_lsf +- ffm: reject invalid codec_id and codec_type +- aaccoder: prevent crash of anmr coder +- ffmdec: reject zero-sized chunks +- swscale/x86/rgb2rgb_template: Fallback to mmx in interleaveBytes() if the alignment is insufficient for SSE* +- swscale/x86/rgb2rgb_template: Do not crash on misaligend stride + + +version 2.5.9 +- avcodec/hevc: Check max ctb addresses for WPP +- avcodec/vp3: ensure header is parsed successfully before tables +- avcodec/jpeg2000dec: Check bpno in decode_cblk() +- avcodec/pgssubdec: Fix left shift of 255 by 24 places cannot be represented in type int +- swscale/utils: Fix for runtime error: left shift of negative value -1 +- avcodec/hevc: Fix integer overflow of entry_point_offset +- avcodec/dirac_parser: Check that there is a previous PU before accessing it +- avcodec/dirac_parser: Add basic validity checks for next_pu_offset and prev_pu_offset +- avcodec/dirac_parser: Fix potential overflows in pointer checks +- avcodec/wmaprodec: Check bits per sample to be within the range not causing integer overflows +- avcodec/wmaprodec: Fix overflow of cutoff +- avformat/smacker: fix integer overflow with pts_inc +- avcodec/vp3: Fix "runtime error: left shift of negative value" +- mpegencts: Fix overflow in cbr mode period calculations +- avutil/timecode: Fix fps check +- avutil/mathematics: return INT64_MIN (=AV_NOPTS_VALUE) from av_rescale_rnd() for overflows +- avcodec/apedec: Check length in long_filter_high_3800() +- avcodec/vp3: always set pix_fmt in theora_decode_header() +- avcodec/mpeg4videodec: Check available data before reading custom matrix +- avutil/mathematics: Do not treat INT64_MIN as positive in av_rescale_rnd +- avutil/integer: Fix av_mod_i() with negative dividend +- avformat/dump: Fix integer overflow in av_dump_format() +- avcodec/utils: Clear dimensions in ff_get_buffer() on failure +- avcodec/utils: Use 64bit for aspect ratio calculation in avcodec_string() +- avcodec/vp3: Clear context on reinitialization failure +- avcodec/hevc: allocate entries unconditionally +- avcodec/hevc_cabac: Fix multiple integer overflows +- avcodec/jpeg2000dwt: Check ndeclevels before calling dwt_encode*() +- avcodec/jpeg2000dwt: Check ndeclevels before calling dwt_decode*() +- avcodec/hevc: Check entry_point_offsets +- avcodec/cabac: Check initial cabac decoder state +- avcodec/cabac_functions: Fix "left shift of negative value -31767" +- avcodec/ffv1dec: Clear quant_table_count if its invalid +- avcodec/ffv1dec: Print an error if the quant table count is invalid +- doc/filters/drawtext: fix centering example +- avcodec/h264_slice: Limit max_contexts when slice_context_count is initialized +- avcodec/vp8: Do not use num_coeff_partitions in thread/buffer setup +- rtmpcrypt: Do the xtea decryption in little endian mode +- avformat/matroskadec: Check subtitle stream before dereferencing +- avformat/utils: Do not init parser if probing is unfinished +- avcodec/jpeg2000dec: Fix potential integer overflow with tile dimensions +- avcodec/jpeg2000dec: Check SIZ dimensions to be within the supported range +- avcodec/jpeg2000: Check comp coords to be within the supported size +- avcodec/jpeg2000: Use av_image_check_size() in ff_jpeg2000_init_component() +- avcodec/wmaprodec: Check for overread in decode_packet() +- avcodec/smacker: Check that the data size is a multiple of a sample vector +- avcodec/takdec: Skip last p2 sample (which is unused) +- avcodec/dxtory: Fix input size check in dxtory_decode_v1_410() +- avcodec/dxtory: Fix input size check in dxtory_decode_v1_420() +- avcodec/error_resilience: avoid accessing previous or next frames tables beyond height +- avcodec/dpx: Move need_align to act per line +- avcodec/flashsv: Check size before updating it +- avcodec/ivi: Check image dimensions +- avcodec/utils: Better check for channels in av_get_audio_frame_duration() +- avcodec/jpeg2000dec: Check for duplicate SIZ marker +- avcodec/jpeg2000dec: Clip all tile coordinates +- avcodec/microdvddec: Check for string end in 'P' case +- avcodec/dirac_parser: Fix undefined memcpy() use +- avformat/xmv: Discard remainder of packet on error +- avformat/xmv: factor return check out of if/else +- libavutil/channel_layout: Check strtol*() for failure +- avcodec/ffv1dec: Check for 0 quant tables +- avcodec/mjpegdec: Reinitialize IDCT on BPP changes +- avcodec/mjpegdec: Check index in ljpeg_decode_yuv_scan() before using it +- avutil/file_open: avoid file handle inheritance on Windows +- opusdec: Don't run vector_fmul_scalar on zero length arrays +- avcodec/ffv1: Initialize vlc_state on allocation +- avcodec/ffv1dec: update progress in case of broken pointer chains +- avcodec/ffv1dec: Clear slice coordinates if they are invalid or slice header decoding fails for other reasons +- avformat/httpauth: Add space after commas in HTTP/RTSP auth header +- avcodec/x86/sbrdsp: Fix using uninitialized upper 32bit of noise +- avcodec/ffv1dec: Fix off by 1 error in quant_table_count check +- avcodec/ffv1dec: Explicitly check read_quant_table() return value +- avcodec/rangecoder: Check e +- lavf/webvttenc: Require webvtt file to contain exactly one WebVTT stream. +- avcodec/mjpegdec: Fix decoding RGBA RCT LJPEG +- avfilter/af_asyncts: use llabs for int64_t +- avcodec/g2meet: Also clear tile dimensions on header_fail +- avcodec/g2meet: Fix potential overflow in tile dimensions check +- avcodec/svq1dec: Check init_get_bits8() for failure +- avcodec/tta: Check init_get_bits8() for failure +- swresample/swresample: Fix integer overflow in seed calculation +- avformat/mov: Fix integer overflow in FFABS +- avutil/common: Add FFNABS() +- avutil/common: Document FFABS() corner case +- avformat/dump: Fix integer overflow in aspect ratio calculation +- avcodec/truemotion1: Check for even width +- avcodec/mpeg12dec: Set dimensions in mpeg1_decode_sequence() only in absence of errors +- avcodec/libopusenc: Fix infinite loop on flushing after 0 input +- avformat/hevc: Check num_long_term_ref_pics_sps to avoid potentially long loops +- avformat/hevc: Fix parsing errors +- ffmpeg: Use correct codec_id for av_parser_change() check +- ffmpeg: Check av_parser_change() for failure +- ffmpeg: Check for RAWVIDEO and do not relay only on AVFMT_RAWPICTURE +- ffmpeg: check avpicture_fill() return value +- avformat/mux: Update sidedata in ff_write_chained() +- avcodec/flashsvenc: Correct max dimension in error message +- avcodec/svq1enc: Check dimensions +- avcodec/dcaenc: clear bitstream end +- libavcodec/aacdec_template: Use init_get_bits8() in aac_decode_frame() +- mxfdec: check edit_rate also for physical_track +- mpegvideo: clear overread in clear_context +- dvdsubdec: validate offset2 similar to offset1 +- avcodec/takdec: Use memove, avoid undefined memcpy() use +- jvdec: avoid unsigned overflow in comparison +- avcodec/mpeg12dec: Do not call show_bits() with invalid bits +- riffdec: prevent negative bit rate +- Merge commit 'd80811c94e068085aab797f9ba35790529126f85' +- imc: use correct position for flcoeffs2 calculation +- wavpack: limit extra_bits to 32 and use get_bits_long +- wavpack: use get_bits_long to read up to 32 bits +- nutdec: check maxpos in read_sm_data before returning success +- s302m: fix arithmetic exception +- avcodec/s302m: Only set the sample rate when some data is output +- vp9: add support for resolution changes in inter frames. +- alsdec: limit avctx->bits_per_raw_sample to 32 +- vp9: avoid infinite loop with broken files +- videodsp: don't overread edges in vfix3 emu_edge. +- avcodec/h264_mp4toannexb_bsf: Reorder operations in nal_size check +- avformat/oggenc: Check segments_count for headers too +- avformat/avidec: Workaround broken initial frame +- hevc: properly handle no_rasl_output_flag when removing pictures from the DPB +- hevc: fix wpp threading deadlock. +- avcodec/ffv1: separate slice_count from max_slice_count +- lavf/img2dec: Fix memory leak +- avcodec/mp3: fix skipping zeros +- avformat/srtdec: make sure we probe a number +- avformat/srtdec: more lenient first line probing +- doc: mention libavcodec can decode Opus natively +- MAINTAINERS: Remove myself as leader + + +version 2.5.8 +- snow: remove an obsolete av_assert2 +- huffyuvdec: validate image size +- vc1dec: use get_bits_long and limit the read bits to 32 +- mpegaudiodec: copy AVFloatDSPContext from first context to all contexts +- libshine: fix support for shine 3.0 +- avidec: check for valid bit_rate range +- avformat/nut: support WavPack +- avcodec/diracdec: Check slices malloc and propagate error code +- avcodec/vp8: Check buffer size in vp8_decode_frame_header() +- avcodec/vp8: Fix null pointer dereference in ff_vp8_decode_free() +- avcodec/diracdec: Check for hpel_base allocation failure +- avcodec/rv34: Clear pointers in ff_rv34_decode_init_thread_copy() +- avfilter/af_aresample: Check ff_all_* for allocation failures +- avcodec/pthread_frame: clear priv_data, avoid stale pointer in error case +- swscale/utils: Clear pix buffers +- avutil/fifo: Fix the case where func() returns less bytes than requested in av_fifo_generic_write() +- avformat/mov: Fix deallocation when MOVStreamContext failed to allocate +- ffmpeg: Fix crash with ost->last_frame allocation failure +- ffmpeg: Fix cleanup with ost = NULL +- avcodec/pthread_frame: check avctx on deallocation +- avcodec/sanm: Reset sizes in destroy_buffers() +- avcodec/alac: Clear pointers in allocate_buffers() +- bytestream2: set the reader to the end when reading more than available +- avcodec/utils: use a minimum 32pixel width in avcodec_align_dimensions2() for H.264 +- avcodec/mpegvideo: Clear pointers in ff_mpv_common_init() +- oggparsedirac: check return value of init_get_bits +- wmalosslessdec: reset frame->nb_samples on packet loss +- wmalosslessdec: avoid reading 0 bits with get_bits +- avcodec/rawenc: Use ff_alloc_packet() instead of ff_alloc_packet2() +- avcodec/aacsbr: Assert that bs_num_env is positive +- avcodec/aacsbr: check that the element type matches before applying SBR +- avcodec/h264_slice: Use w/h from the AVFrame instead of mb_w/h +- vp9/update_prob: prevent out of bounds table read +- avfilter/vf_transpose: Fix rounding error +- avcodec/pngdec: Check values before updating context in decode_fctl_chunk() +- avcodec/pngdec: Require a IHDR chunk before fctl +- avcodec/pngdec: Only allow one IHDR chunk +- wmavoice: limit wmavoice_decode_packet return value to packet size +- swscale/swscale_unscaled: Fix rounding difference with RGBA output between little and big endian +- ffmpeg: Do not use the data/size of a bitstream filter after failure +- swscale/x86/rgb2rgb_template: fix signedness of v in shuffle_bytes_2103_{mmx,mmxext} +- swscale/x86/rgb2rgb_template: add missing xmm clobbers +- vda: unlock the pixel buffer base address. +- swscale/rgb2rgb_template: Fix signedness of v in shuffle_bytes_2103_c() +- swscale/rgb2rgb_template: Implement shuffle_bytes_0321_c and fix shuffle_bytes_2103_c on BE +- swscale/rgb2rgb_template: Disable shuffle_bytes_2103_c on big endian +- swr: Remember previously set int_sample_format from user +- matroskadec: check audio sample rate +- matroskadec: validate audio channels and bitdepth +- avcodec/dpxenc: implement write16/32 as functions +- postproc: fix unaligned access +- ffmpeg: Free last_frame instead of just unref +- avio: fix potential crashes when combining ffio_ensure_seekback + crc +- h264: er: Copy from the previous reference only if compatible +- sonic: set avctx->channels in sonic_decode_init +- vp8: change mv_{min,max}.{x,y} type to int +- vp9: change type of tile_size from unsigned to int64_t +- arm: only enable setend on ARMv6 +- libopenjpegdec: check existence of image component data +- mov: abort on EOF in ff_mov_read_chan +- ffmpeg_opt: Check for localtime() failure +- avformat: Fix bug in parse_rps for HEVC. +- takdec: ensure chan2 is a valid channel index +- avcodec/h264_slice: Use AVFrame diemensions for grayscale handling +- avdevice/lavfi: do not rescale AV_NOPTS_VALUE in lavfi_read_packet() +- libavutil/channel_layout: Correctly return layout when channel specification ends with a trailing 'c'. +- avcodec/jpeg2000dec: Check that coords match before applying ICT +- avformat/ffmdec: Check ffio_set_buf_size() return value +- avcodec/adpcm: Check for overreads +- avcodec/alsdec: Check for overread +- avcodec/atrac3plusdec: consume only as many bytes as available +- libavutil/softfloat: Fix av_normalize1_sf bias. +- swresample/swresample: Cleanup on init failure. +- Revert "avformat/rtpenc: check av_packet_get_side_data() return, fix null ptr dereference" +- avformat/mxfenc: Accept MXF D-10 with 49.999840 Mbit/sec +- swresample/dither: check memory allocation +- libopenjpegenc: add NULL check for img before accessing it +- swresample: Check the return value of resampler->init() +- h264: Make sure reinit failures mark the context as not initialized +- ffmpeg_opt: Set the video VBV parameters only for the video stream from -target +- avcodec/bitstream: Assert that there is enough space left in avpriv_copy_bits() +- avcodec/put_bits: Assert that there is enough space left in skip_put_bytes() +- avcodec/mpegvideo_enc: Update the buffer size as more slices are merged +- avcodec/put_bits: Update size_in_bits in set_put_bits_buffer_size() +- avformat/wavdec: Increase dts packet threshold to fix more misdetections +- avformat/wavdec: Increase probe_packets limit +- avformat/swfdec: Do not error out on pixel format changes +- avfilter/x86/vf_hqdn3d: Fix register types +- avcodec/mjpegenc_common: Use ff_mpv_reallocate_putbitbuffer() +- avcodec/mpegvideo: Factor ff_mpv_reallocate_putbitbuffer() out +- avformat/mov: Mark avio context of decompressed atoms as seekable +- avcodec/hevc_ps: Only discard overread VPS if a previous is available +- avcodec/x86/h264_weight: handle weight1=128 +- avcodec/exr: fix crash caused by merge + + +version 2.5.7 +- avformat/nutdec: Fix recovery when immedeately after seeking a failure happens +- nutdec: fix memleaks on error in nut_read_header +- rtpenc_jpeg: handle case of picture dimensions not dividing by 8 +- avformat/mov: Fix parsing short loci +- avcodec/shorten: Fix code depending on signed overflow behavior +- avcodec/proresdec2: Reset slice_count on deallocation +- ffmpeg_opt: Fix -timestamp parsing +- hevc: make avcodec_decode_video2() fail if get_format() fails +- avcodec/mpeg4audio: add some padding/alignment to MAX_PCE_SIZE +- swr: fix alignment issue caused by 8ch sse functions +- libswscale/x86/hscale_fast_bilinear_simd.c: Include BX in the clobber list on x86_64, because it isn't implicitly included when PIC is on. +- aacdec: don't return frames without data +- avformat/matroskadec: Cleanup error handling for bz2 & zlib +- avformat/nutdec: Fix use of uinitialized value +- tools/graph2dot: use larger data types than int for array/string sizes +- id3v2: catch avio_read errors in check_tag +- aacsbr: break infinite loop in sbr_hf_calc_npatches +- diracdec: avoid overflow of bytes*8 in decode_lowdelay +- diracdec: prevent overflow in data_unit_size check +- avidec: avoid infinite loop due to negative ast->sample_size +- pngdec: don't use AV_PIX_FMT_MONOBLACK for apng +- avcodec/wavpack: Check L/R values before use to avoid harmless integer overflow and undefined behavior in fate +- xcbgrab: Validate the capture area +- xcbgrab: Do not assume the non shm image data is always available +- avfilter/lavfutils: disable frame threads when decoding a single image +- nutdec: fix illegal count check in decode_main_header +- ffmpeg: remove incorrect network deinit +- OpenCL: Avoid potential buffer overflow in cmdutils_opencl.c +- apedec: set s->samples only when init_frame_decoder succeeded +- swscale/ppc/swscale_altivec.c: POWER LE support in yuv2planeX_8() delete macro GET_VF() +- libvpxenc: only set noise reduction w/vp8 +- tests/fate-run: do not attempt to parse tiny_psnrs output if it failed +- alac: reject rice_limit 0 if compression is used +- alsdec: only adapt order for positive max_order +- alsdec: check sample pointer range in revert_channel_correlation +- tests: drop bc dependency +- fate: Include branch information in the payload header + + +version 2.5.6 +- avcodec/atrac3plusdsp: fix on stack alignment +- ac3: validate end in ff_ac3_bit_alloc_calc_mask +- aacpsy: avoid psy_band->threshold becoming NaN +- aasc: return correct buffer size from aasc_decode_frame +- msrledec: use signed pixel_ptr in msrle_decode_pal4 +- swresample: Allow reinitialization without ever setting channel layouts (cherry picked from commit 80a28c7509a11114e1aea5b208d56c6646d69c07) +- swresample: Allow reinitialization without ever setting channel counts +- avcodec/h264: Do not fail with randomly truncated VUIs +- avcodec/h264_ps: Move truncation check from VUI to SPS +- avcodec/h264: Be more tolerant to changing pps id between slices +- avcodec/aacdec: Fix storing state before PCE decode +- avcodec/h264: reset the counts in the correct context +- avcodec/h264_slice: Do not reset mb_aff_frame per slice +- avcodec/h264: finish previous slices before switching to single thread mode +- avcodec/h264: Fix race between slices where one overwrites data from the next +- avcodec/h264_refs: Do not set reference to things which do not exist +- avcodec/h264: Fail for invalid mixed IDR / non IDR frames in slice threading mode +- h264: avoid unnecessary calls to get_format +- avcodec/msrledec: restructure msrle_decode_pal4() based on the line number instead of the pixel pointer + + +version 2.5.5: +- vp9: make above buffer pointer 32-byte aligned. +- avcodec/dnxhddec: Check that the frame is interlaced before using cur_field +- avformat/mov: Disallow ".." in dref unless use_absolute_path is set +- avformat/mov: Check for string truncation in mov_open_dref() +- avformat/mov: Use sizeof(filename) instead of a literal number +- eac3dec: fix scaling +- ac3_fixed: fix computation of spx_noise_blend +- ac3_fixed: fix out-of-bound read +- ac3dec_fixed: always use the USE_FIXED=1 variant of the AC3DecodeContext +- avcodec/012v: redesign main loop +- avcodec/012v: Check dimensions more completely +- asfenc: fix leaking asf->index_ptr on error +- avcodec/options_table: remove extradata_size from the AVOptions table +- ffmdec: limit the backward seek to the last resync position +- ffmdec: make sure the time base is valid +- ffmdec: fix infinite loop at EOF +- ffmdec: initialize f_cprv, f_stvi and f_stau +- avformat/rm: limit packet size +- avcodec/webp: validate the distance prefix code +- avcodec/rv10: check size of s->mb_width * s->mb_height +- eamad: check for out of bounds read +- mdec: check for out of bounds read +- arm: Suppress tags about used cpu arch and extensions +- aic: Fix decoding files with odd dimensions +- avcodec/tiff: move bpp check to after "end:" +- mxfdec: Fix the error handling for when strftime fails +- avcodec/opusdec: Fix delayed sample value +- avcodec/opusdec: Clear out pointers per packet +- avcodec/utils: Align YUV411 by as much as the other YUV variants +- vp9: fix segmentation map retention with threading enabled. +- webp: ensure that each transform is only used once +- doc/protocols/tcp: fix units of listen_timeout option value, from microseconds to milliseconds +- fix VP9 packet decoder returning 0 instead of the used data size +- avformat/flvenc: check that the codec_tag fits in the available bits +- avcodec/utils: use correct printf specifier in ff_set_sar +- avutil/imgutils: correctly check for negative SAR components +- swscale/utils: clear formatConvBuffer on allocation +- avformat/bit: only accept the g729 codec and 1 channel +- avformat/bit: check that pkt->size is 10 in write_packet +- avformat/adxdec: check avctx->channels for invalid values +- avformat/adxdec: set avctx->channels in adx_read_header +- Fix buffer_size argument to init_put_bits() in multiple encoders. +- mips/acelp_filters: fix incorrect register constraint +- avcodec/hevc_ps: Sanity checks for some log2_* values +- avcodec/zmbv: Check len before reading in decode_frame() +- avcodec/h264: Only reinit quant tables if a new PPS is allowed +- avcodec/snowdec: Fix ref value check +- swscale/utils: More carefully merge and clear coefficients outside the input +- avcodec/a64multienc: Assert that the Packet size does not grow +- avcodec/a64multienc: simplify frame handling code +- avcodec/a64multienc: fix use of uninitialized values in to_meta_with_crop +- avcodec/a64multienc: initialize mc_meta_charset to zero +- avcodec/a64multienc: don't set incorrect packet size +- avcodec/a64multienc: use av_frame_ref instead of copying the frame +- avcodec/x86/mlpdsp_init: Simplify mlp_filter_channel_x86() +- h264: initialize H264Context.avctx in init_thread_copy +- wtvdec: fix integer overflow resulting in errors with large files +- avcodec/gif: fix off by one in column offsetting finding + + +version 2.5.4: +- avcodec/arm/videodsp_armv5te: Fix linking failure with shared libs +- avcodec/mjpegdec: Skip blocks which are outside the visible area +- avcodec/h264_slice: ignore SAR changes in slices after the first +- avcodec/h264_slice: Check picture structure before setting the related fields +- avcodec/h264_slice: Do not change frame_num after the first slice +- avutil/opt: Fix type used to access AV_OPT_TYPE_SAMPLE_FMT +- avutil/opt: Fix types used to access AV_OPT_TYPE_PIXEL_FMT +- avcodec/h264: Be more strict on rejecting pps/sps changes +- avcodec/h264: Be more strict on rejecting pps_id changes +- avcodec/h264_ps: More completely check the bit depths +- avformat/thp: Check av_get_packet() for failure not only for partial output +- swscale/utils: Limit filter shifting so as not to read from prior the array +- avcodec/mpegvideo_motion: Fix gmc chroma dimensions +- avcodec/mjpegdec: Check number of components for JPEG-LS +- avcodec/mjpegdec: Check escape sequence validity +- avformat/mpc8: Use uint64_t in *_get_v() to avoid undefined behavior +- avformat/mpc8: fix broken pointer math +- avformat/mpc8: fix hang with fuzzed file +- avformat/tta: fix crash with corrupted files +- avcodec/ppc/idctdsp.c: POWER LE support in idct_add_altivec() +- swscale/input: fix rgba64 alpha non native +- swscale/input: Fix alpha of YA16 input +- libavcodec/ppc/mpegvideoencdsp.c: fix stack smashing in pix_norm1_altivec() and pix_sum_altivec() +- avformat/rmdec: Check for overflow in ff_rm_read_mdpr_codecdata() +- avformat/mpeg: do not count PES packets inside PES packets during probing +- hevc: always clip luma_log2_weight_denom +- rtpdec_h263_rfc2190: Clear the stored bits if discarding buffered data +- aacenc: correctly check returned value +- swscale: check memory allocations +- opt: check memory allocation +- avformat/utils: check for malloc failure +- avcodec/flac_parser: fix handling EOF if no headers are found +- avfilter/vf_framepack: Check and update frame_rate +- vp8: improve memory allocation checks +- configure: enable vsx together with altivec for ppc64el +- avcodec/hevc: Fix handling of skipped_bytes() reallocation failures +- qpeg: avoid pointless invalid memcpy() + + +version 2.5.3: +- vp9: fix parser return values in error case +- ffmpeg: Clear error message array at init. +- avcodec/dvdsubdec: fix accessing dangling pointers +- avcodec/dvdsubdec: error on bitmaps with size 0 +- cmdutils: Use 64bit for file size/offset related variable in cmdutils_read_file() +- mov: Fix negative size calculation in mov_read_default(). +- avformat/mov: fix integer overflow in mov_read_udta_string() +- mov: Fix overflow and error handling in read_tfra(). +- mov: Avoid overflow with mov_metadata_raw() +- avcodec/dvdsubdec: fix out of bounds accesses +- avfilter/vf_sab: fix filtering tiny images +- avformat/flvdec: Increase string array size +- avformat/flvdec: do not inject dts=0 metadata packets which failed to be parsed into a new data stream +- avformat/cdxl: Fix integer overflow of image_size +- libavformat: Build hevc.o when building the RTP muxer + +version 2.5.2: +- avcodec/indeo3: ensure offsets are non negative +- avcodec/h264: Check *log2_weight_denom +- avcodec/hevc_ps: Check diff_cu_qp_delta_depth +- avcodec/h264: Clear delayed_pic on deallocation +- avcodec/hevc: clear filter_slice_edges() on allocation +- avcodec/dcadec: Check that the added xch channel isnt already there +- avcodec/indeo3: use signed variables to avoid underflow +- swscale: increase yuv2rgb table headroom +- avformat/mov: fix integer overflow of size +- avformat/mov: check atom nesting depth +- avcodec/utvideodec: Fix handling of slice_height=0 +- avcodec/xface: correct the XFACE_MAX_* values +- avcodec/vmdvideo: Check len before using it in method 3 +- configure: create the tests directory like the doc directory +- mmvideo: check frame dimensions +- jvdec: check frame dimensions + +version 2.5.1: +- lavu/frame: fix malloc error path in av_frame_copy_props() +- avformat/aviobuf: Check that avio_seek() target is non negative +- swresample/soxr_resample: fix error handling +- avformat/flvdec: fix potential use of uninitialized variables +- avformat/crypto: fix key vs iv typo +- configure: use use_pkg_config() instead of check_pkg_config() for libsmbclient +- avcodec/ppc/vp3dsp_altivec: POWER LE support to vp3_idct_add_altivec() +- avformat/matroskadec: fix handling of recursive SeekHead elements +- doc/examples/filtering_video: fix frame rate +- avcodec/mpegaudiodec_template: only allocate fdsp when its used +- doc/examples/transcoding: check encoder before using it +- update MAINTAINERS file +- POWER LE support in put_vp8_epel_h_altivec_core() put_vp8_epel_v_altivec_core() put_vp8_pixels16_altivec() +- POWER LE support in vc1_inv_trans_8x4_altivec() + +version 2.5: - HEVC/H.265 RTP payload format (draft v6) packetizer - SUP/PGS subtitle demuxer - ffprobe -show_pixel_formats option @@ -16,7 +546,7 @@ version : - creating DASH compatible fragmented MP4, MPEG-DASH segmenting muxer - WebP muxer with animated WebP support - zygoaudio decoding support -- APNG demuxer +- APNG decoder and demuxer - postproc visualization support diff --git a/MAINTAINERS b/MAINTAINERS index 15b976fee7..11ca678747 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -14,7 +14,6 @@ patches and related discussions. Project Leader ============== -Michael Niedermayer final design decisions @@ -532,14 +531,13 @@ Windows ICL Matthew Oliver ADI/Blackfin DSP Marc Hoffman Sparc Roman Shaposhnik x86 Michael Niedermayer +OS/2 KO Myung-Hun Releases ======== -2.4 Michael Niedermayer -2.2 Michael Niedermayer -1.2 Michael Niedermayer +2.5 Michael Niedermayer If you want to maintain an older release, please contact us diff --git a/Makefile b/Makefile index 1e1dbb3cd4..845a274953 100644 --- a/Makefile +++ b/Makefile @@ -112,7 +112,7 @@ endef $(foreach P,$(PROGS),$(eval $(call DOPROG,$(P:$(PROGSSUF)$(EXESUF)=)))) -ffprobe.o cmdutils.o : libavutil/ffversion.h +ffprobe.o cmdutils.o libavcodec/utils.o libavformat/utils.o libavdevice/avdevice.o libavfilter/avfilter.o libavutil/utils.o libpostproc/postprocess.o libswresample/swresample.o libswscale/utils.o : libavutil/ffversion.h $(PROGS): %$(PROGSSUF)$(EXESUF): %$(PROGSSUF)_g$(EXESUF) $(CP) $< $@ diff --git a/RELEASE b/RELEASE index 5360d2ef3f..398d0dac7e 100644 --- a/RELEASE +++ b/RELEASE @@ -1 +1 @@ -2.4.git +2.5.11 diff --git a/RELEASE_NOTES b/RELEASE_NOTES index a1ddd35dbf..5bd3273d37 100644 --- a/RELEASE_NOTES +++ b/RELEASE_NOTES @@ -2,9 +2,13 @@ │ RELEASE NOTES for FFmpeg 2.5 "Bohr" │ └────────────────────────────────────────┘ - The FFmpeg Project proudly presents FFmpeg 2.5 "Bohr", just 2.5 months - after the release of 2.4. Since this wasn't a long time ago, the Changelog - is a bit short this time. + The FFmpeg Project proudly presents FFmpeg 2.5 "Bohr", 2.5 months after the + release of 2.4. + + The most important new features are AVFoundation screen-grabbing support, + animated WebP decoding support, and Animated PNG support. In addition, many + exciting features for video streaming are also implemented, including MPEG- + DASH fragmenting muxer, HEVC RTP payload muxer, and UDP Lite support. As usual, if you have any question on this release or any FFmpeg related topic, feel free to join us on the #ffmpeg IRC channel (on @@ -56,6 +60,7 @@ • libutvideo YUV 4:2:2 10bit support • animated WebP decoding support • zygoaudio decoding support + • APNG decoder ┌────────────────────────────┐ │ libavdevice │ @@ -72,7 +77,8 @@ • SUP/PGS subtitle demuxer • STL subtitle demuxer • UDP-Lite support (RFC 3828) - • creating DASH compatible fragmented MP4, MPEG-DASH segmenting muxer + • MPEG-DASH segmenting muxer, which allows creating DASH compatible + fragmented MP4 • WebP muxer • APNG demuxer @@ -93,7 +99,3 @@ └────────────────────────────┘ • visualization support - - ┌────────────────────────────┐ - │ ⚠ Behaviour changes │ - └────────────────────────────┘ diff --git a/cmdutils.c b/cmdutils.c index b68dae9753..708b536a68 100644 --- a/cmdutils.c +++ b/cmdutils.c @@ -1860,7 +1860,7 @@ int read_yesno(void) int cmdutils_read_file(const char *filename, char **bufptr, size_t *size) { - int ret; + int64_t ret; FILE *f = av_fopen_utf8(filename, "rb"); if (!f) { diff --git a/cmdutils_opencl.c b/cmdutils_opencl.c index 3dfd156195..61478e27af 100644 --- a/cmdutils_opencl.c +++ b/cmdutils_opencl.c @@ -22,6 +22,7 @@ #include "libavutil/time.h" #include "libavutil/log.h" #include "libavutil/opencl.h" +#include "libavutil/avstring.h" #include "cmdutils.h" typedef struct { @@ -238,7 +239,8 @@ int opt_opencl_bench(void *optctx, const char *opt, const char *arg) devices[count].platform_idx = i; devices[count].device_idx = j; devices[count].runtime = score; - strcpy(devices[count].device_name, device_node->device_name); + av_strlcpy(devices[count].device_name, device_node->device_name, + sizeof(devices[count].device_name)); count++; } } diff --git a/configure b/configure index c046e3484d..c52c006279 100755 --- a/configure +++ b/configure @@ -1635,7 +1635,6 @@ HEADERS_LIST=" asm_types_h cdio_paranoia_h cdio_paranoia_paranoia_h - CL_cl_h dev_bktr_ioctl_bt848_h dev_bktr_ioctl_meteor_h dev_ic_bt8xx_h @@ -1761,6 +1760,7 @@ SYSTEM_FUNCS=" TOOLCHAIN_FEATURES=" as_dn_directive as_func + as_object_arch asm_mod_q attribute_may_alias attribute_packed @@ -4413,7 +4413,7 @@ unsigned int endian = 'B' << 24 | 'I' << 16 | 'G' << 8 | 'E'; EOF od -t x1 $TMPO | grep -q '42 *49 *47 *45' && enable bigendian -if [ "$cpu" = "power7" ] || [ "$cpu" = "power8" ] ;then +if [ "$cpu" = "power7" ] || [ "$cpu" = "power8" ] || enabled ppc64; then if ! enabled bigendian && enabled altivec ;then enable vsx fi @@ -4520,6 +4520,11 @@ EOF check_as < $TMPH <> $TMPH mkdir -p doc +mkdir -p tests echo "@c auto-generated by configure" > doc/config.texi print_config ARCH_ "$config_files" $ARCH_LIST diff --git a/doc/APIchanges b/doc/APIchanges index abb83b84c7..13b435c2a0 100644 --- a/doc/APIchanges +++ b/doc/APIchanges @@ -200,7 +200,7 @@ API changes, most recent first: Increase FF_INPUT_BUFFER_PADDING_SIZE to 32 due to some corner cases needing it -2014-06-10 - xxxxxxx - lavf 55.43.100 - avformat.h +2014-06-10 - 5482780 - lavf 55.43.100 - avformat.h New field int64_t max_analyze_duration2 instead of deprecated int max_analyze_duration. @@ -224,7 +224,7 @@ API changes, most recent first: Add strict_std_compliance and related AVOptions to support experimental muxing. -2014-05-26 - xxxxxxx - lavu 52.87.100 - threadmessage.h +2014-05-26 - 55cc60c - lavu 52.87.100 - threadmessage.h Add thread message queue API. 2014-05-26 - c37d179 - lavf 55.41.100 - avformat.h @@ -234,7 +234,7 @@ API changes, most recent first: Add av_stream_get_side_data() to access stream-level side data in the same way as av_packet_get_side_data(). -2014-05-xx - xxxxxxx - lavu 52.86.100 - fifo.h +2014-05-20 - 7336e39 - lavu 52.86.100 - fifo.h Add av_fifo_alloc_array() function. 2014-05-19 - ef1d4ee / bddd8cb - lavu 52.85.100 / 53.15.0 - frame.h, display.h @@ -266,7 +266,7 @@ API changes, most recent first: 2014-05-11 - 14aef38 / 66e6c8a - lavu 52.83.100 / 53.14.0 - pixfmt.h Add AV_PIX_FMT_VDA for new-style VDA acceleration. -2014-05-xx - xxxxxxx - lavu 52.82.100 - fifo.h +2014-05-07 - 351f611 - lavu 52.82.100 - fifo.h Add av_fifo_freep() function. 2014-05-02 - ba52fb11 - lavu 52.81.100 - opt.h @@ -288,10 +288,14 @@ API changes, most recent first: Deprecate CODEC_FLAG_INPUT_PRESERVED. Its functionality is replaced by passing reference-counted frames to encoders. +2014-04-30 - 617e866 - lavu 52.81.100 - pixdesc.h + Add av_find_best_pix_fmt_of_2(), av_get_pix_fmt_loss() + Deprecate avcodec_get_pix_fmt_loss(), avcodec_find_best_pix_fmt_of_2() + 2014-04-29 - 1bf6396 - lavc 55.60.100 - avcodec.h Add AVCodecDescriptor.mime_types field. -2014-04-29 - xxxxxxx - lavu 52.80.0 - hash.h +2014-04-29 - b804eb4 - lavu 52.80.100 - hash.h Add av_hash_final_bin(), av_hash_final_hex() and av_hash_final_b64(). 2014-03-07 - 8b2a130 - lavc 55.50.0 / 55.53.100 - dxva2.h @@ -303,7 +307,7 @@ API changes, most recent first: 2014-04-17 - a8d01a7 / 0983d48 - lavu 53.12.0 / 52.77.100 - crc.h Add AV_CRC_16_ANSI_LE crc variant. -2014-04-XX - xxxxxxx - lavf xx.xx.1xx - avformat.h +2014-04-15 - ef818d8 - lavf 55.37.101 - avformat.h Add av_format_inject_global_side_data() 2014-04-12 - 4f698be - lavu 52.76.100 - log.h @@ -383,7 +387,7 @@ API changes, most recent first: 2014-02-19 - f4c8d00 / 6bb8720 - lavu 52.64.101 / 53.3.1 - opt.h Deprecate unused AV_OPT_FLAG_METADATA. -2014-02-xx - xxxxxxx - lavd 55.10.100 - avdevice.h +2014-02-16 - 81c3f81 - lavd 55.10.100 - avdevice.h Add avdevice_list_devices() and avdevice_free_list_devices() 2014-02-16 - db3c970 - lavf 55.33.100 - avio.h @@ -424,7 +428,7 @@ API changes, most recent first: 2014-01-19 - 1a193c4 - lavf 55.25.100 - avformat.h Add avformat_get_mov_video_tags() and avformat_get_mov_audio_tags(). -2014-01-19 - xxxxxxx - lavu 52.63.100 - rational.h +2014-01-19 - 3532dd5 - lavu 52.63.100 - rational.h Add av_make_q() function. 2014-01-05 - 4cf4da9 / 5b4797a - lavu 52.62.100 / 53.2.0 - frame.h diff --git a/doc/Doxyfile b/doc/Doxyfile index 8697e6c551..a524a5c240 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.5.11 # 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/demuxers.texi b/doc/demuxers.texi index 11dfe1b9c1..fa5af02d5a 100644 --- a/doc/demuxers.texi +++ b/doc/demuxers.texi @@ -98,7 +98,7 @@ All subsequent file-related directives apply to that file. @item @code{ffconcat version 1.0} Identify the script type and version. It also sets the @option{safe} option -to 1 if it was to its default -1. +to 1 if it was -1. To make FFmpeg recognize the format automatically, this directive must appears exactly as is (no extra space or byte-order-mark) on the very first @@ -145,7 +145,9 @@ component. If set to 0, any file name is accepted. -The default is -1, it is equivalent to 1 if the format was automatically +The default is 1. + +-1 is equivalent to 1 if the format was automatically probed and 0 otherwise. @item auto_convert @@ -359,6 +361,23 @@ ffmpeg -framerate 10 -pattern_type glob -i "*.png" out.mkv @end example @end itemize +@section mov/mp4/3gp/Quicktme + +Quicktime / MP4 demuxer. + +This demuxer accepts the following options: +@table @option +@item enable_drefs +Enable loading of external tracks, disabled by default. +Enabling this can theoretically leak information in some use cases. + +@item use_absolute_path +Allows loading of external tracks via absolute paths, disabled by default. +Enabling this poses a security risk. It should only be enabled if the source +is known to be non malicious. + +@end table + @section mpegts MPEG-2 transport stream demuxer. diff --git a/doc/examples/Makefile b/doc/examples/Makefile index 07251fe3c2..9f03f04b57 100644 --- a/doc/examples/Makefile +++ b/doc/examples/Makefile @@ -29,6 +29,7 @@ OBJS=$(addsuffix .o,$(EXAMPLES)) # the following examples make explicit use of the math library avcodec: LDLIBS += -lm +decoding_encoding: LDLIBS += -lm muxing: LDLIBS += -lm resampling_audio: LDLIBS += -lm diff --git a/doc/examples/filtering_video.c b/doc/examples/filtering_video.c index 8d595735b3..601c3d87f0 100644 --- a/doc/examples/filtering_video.c +++ b/doc/examples/filtering_video.c @@ -90,6 +90,7 @@ static int init_filters(const char *filters_descr) AVFilter *buffersink = avfilter_get_by_name("buffersink"); AVFilterInOut *outputs = avfilter_inout_alloc(); AVFilterInOut *inputs = avfilter_inout_alloc(); + AVRational time_base = fmt_ctx->streams[video_stream_index]->time_base; enum AVPixelFormat pix_fmts[] = { AV_PIX_FMT_GRAY8, AV_PIX_FMT_NONE }; filter_graph = avfilter_graph_alloc(); @@ -102,7 +103,7 @@ static int init_filters(const char *filters_descr) snprintf(args, sizeof(args), "video_size=%dx%d:pix_fmt=%d:time_base=%d/%d:pixel_aspect=%d/%d", dec_ctx->width, dec_ctx->height, dec_ctx->pix_fmt, - dec_ctx->time_base.num, dec_ctx->time_base.den, + time_base.num, time_base.den, dec_ctx->sample_aspect_ratio.num, dec_ctx->sample_aspect_ratio.den); ret = avfilter_graph_create_filter(&buffersrc_ctx, buffersrc, "in", diff --git a/doc/examples/transcoding.c b/doc/examples/transcoding.c index 759c628e93..5572461616 100644 --- a/doc/examples/transcoding.c +++ b/doc/examples/transcoding.c @@ -116,6 +116,10 @@ static int open_output_file(const char *filename) || dec_ctx->codec_type == AVMEDIA_TYPE_AUDIO) { /* in this example, we choose transcoding to same codec */ encoder = avcodec_find_encoder(dec_ctx->codec_id); + if (!encoder) { + av_log(NULL, AV_LOG_FATAL, "Neccessary encoder not found\n"); + return AVERROR_INVALIDDATA; + } /* In this example, we transcode to same properties (picture size, * sample rate etc.). These properties can be changed for output diff --git a/doc/faq.texi b/doc/faq.texi index fdcb46d334..54b61fc9ea 100644 --- a/doc/faq.texi +++ b/doc/faq.texi @@ -298,7 +298,7 @@ FFmpeg has a @url{http://ffmpeg.org/ffmpeg-protocols.html#concat, @code{concat}} protocol designed specifically for that, with examples in the documentation. -A few multimedia containers (MPEG-1, MPEG-2 PS, DV) allow to concatenate +A few multimedia containers (MPEG-1, MPEG-2 PS, DV) allow one to concatenate video by merely concatenating the files containing them. Hence you may concatenate your multimedia files by first transcoding them to diff --git a/doc/ffserver.texi b/doc/ffserver.texi index 83b6520dd1..0394c3636b 100644 --- a/doc/ffserver.texi +++ b/doc/ffserver.texi @@ -71,7 +71,7 @@ the HTTP server (configured through the @option{HTTPPort} option), and configuration file. Each feed is associated to a file which is stored on disk. This stored -file is used to allow to send pre-recorded data to a player as fast as +file is used to send pre-recorded data to a player as fast as possible when new content is added in real-time to the stream. A "live-stream" or "stream" is a resource published by diff --git a/doc/fftools-common-opts.texi b/doc/fftools-common-opts.texi index 0e8f849b9d..c3e60dbd66 100644 --- a/doc/fftools-common-opts.texi +++ b/doc/fftools-common-opts.texi @@ -253,10 +253,14 @@ Possible flags for this option are: @item sse4.1 @item sse4.2 @item avx +@item avx2 @item xop +@item fma3 @item fma4 @item 3dnow @item 3dnowext +@item bmi1 +@item bmi2 @item cmov @end table @item ARM @@ -267,6 +271,13 @@ Possible flags for this option are: @item vfp @item vfpv3 @item neon +@item setend +@end table +@item AArch64 +@table @samp +@item armv8 +@item vfp +@item neon @end table @item PowerPC @table @samp diff --git a/doc/filters.texi b/doc/filters.texi index 8c16c7a546..64b91ec284 100644 --- a/doc/filters.texi +++ b/doc/filters.texi @@ -3378,7 +3378,7 @@ Set number overlapping pixels for each block. Since the filter can be slow, you may want to reduce this value, at the cost of a less effective filter and the risk of various artefacts. -If the overlapping value doesn't allow to process the whole input width or +If the overlapping value doesn't permit processing the whole input width or height, a warning will be displayed and according borders won't be denoised. Default value is @var{blocksize}-1, which is the best possible setting. @@ -4135,7 +4135,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 diff --git a/doc/formats.texi b/doc/formats.texi index 41387098b7..cbbdc1032c 100644 --- a/doc/formats.texi +++ b/doc/formats.texi @@ -23,7 +23,7 @@ Reduce buffering. @item probesize @var{integer} (@emph{input}) Set probing size in bytes, i.e. the size of the data to analyze to get -stream information. A higher value will allow to detect more +stream information. A higher value will enable detecting more information in case it is dispersed into the stream, but will increase latency. Must be an integer not lesser than 32. It is 5000000 by default. @@ -67,7 +67,7 @@ Default is 0. @item analyzeduration @var{integer} (@emph{input}) Specify how many microseconds are analyzed to probe the input. A -higher value will allow to detect more accurate information, but will +higher value will enable detecting more accurate information, but will increase latency. It defaults to 5,000,000 microseconds = 5 seconds. @item cryptokey @var{hexadecimal string} (@emph{input}) diff --git a/doc/general.texi b/doc/general.texi index dd19fcc101..508d587ea9 100644 --- a/doc/general.texi +++ b/doc/general.texi @@ -936,8 +936,8 @@ following image formats are supported: @item Musepack SV8 @tab @tab X @item Nellymoser Asao @tab X @tab X @item On2 AVC (Audio for Video Codec) @tab @tab X -@item Opus @tab E @tab E - @tab supported through external library libopus +@item Opus @tab E @tab X + @tab encoding supported through external library libopus @item PCM A-law @tab X @tab X @item PCM mu-law @tab X @tab X @item PCM signed 8-bit planar @tab X @tab X diff --git a/doc/indevs.texi b/doc/indevs.texi index ad823abad4..84cdeb5d3a 100644 --- a/doc/indevs.texi +++ b/doc/indevs.texi @@ -1,7 +1,7 @@ @chapter Input Devices @c man begin INPUT DEVICES -Input devices are configured elements in FFmpeg which allow to access +Input devices are configured elements in FFmpeg which enable accessing the data coming from a multimedia device attached to your system. When you configure your FFmpeg build, all the supported input devices diff --git a/doc/platform.texi b/doc/platform.texi index ca76492753..fa91ce2b6c 100644 --- a/doc/platform.texi +++ b/doc/platform.texi @@ -135,8 +135,6 @@ You will need the following prerequisites: (if using MSVC 2012 or earlier) @item @uref{http://www.mingw.org/, MSYS} @item @uref{http://yasm.tortall.net/, YASM} -@item @uref{http://gnuwin32.sourceforge.net/packages/bc.htm, bc for Windows} if -you want to run @uref{fate.html, FATE}. @end itemize To set up a proper environment in MSYS, you need to run @code{msys.bat} from @@ -283,7 +281,7 @@ binutils, gcc4-core, make, git, mingw-runtime, texinfo In order to run FATE you will also need the following "Utils" packages: @example -bc, diffutils +diffutils @end example If you want to build FFmpeg with additional libraries, download Cygwin diff --git a/doc/protocols.texi b/doc/protocols.texi index d165bda0e4..006324c68d 100644 --- a/doc/protocols.texi +++ b/doc/protocols.texi @@ -1081,8 +1081,8 @@ Set raise error timeout, expressed in microseconds. This option is only relevant in read mode: if no data arrived in more than this time interval, raise error. -@item listen_timeout=@var{microseconds} -Set listen timeout, expressed in microseconds. +@item listen_timeout=@var{milliseconds} +Set listen timeout, expressed in milliseconds. @end table The following example shows how to setup a listening TCP connection diff --git a/doc/utils.texi b/doc/utils.texi index b0455af00c..00d6c31c11 100644 --- a/doc/utils.texi +++ b/doc/utils.texi @@ -844,7 +844,7 @@ Return 1.0 if @var{x} is +/-INFINITY, 0.0 otherwise. Return 1.0 if @var{x} is NAN, 0.0 otherwise. @item ld(var) -Allow to load the value of the internal variable with number +Load the value of the internal variable with number @var{var}, which was previously stored with st(@var{var}, @var{expr}). The function returns the loaded value. @@ -861,7 +861,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}. @@ -912,7 +912,7 @@ Compute the square root of @var{expr}. This is equivalent to Compute expression @code{1/(1 + exp(4*x))}. @item st(var, expr) -Allow to store the value of the expression @var{expr} in an internal +Store the value of the expression @var{expr} in an internal variable. @var{var} specifies the number of the variable where to store the value, and it is a value ranging from 0 to 9. The function returns the value stored in the internal variable. diff --git a/ffmpeg.c b/ffmpeg.c index eef774bda7..a392d98d93 100644 --- a/ffmpeg.c +++ b/ffmpeg.c @@ -352,7 +352,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). */ @@ -467,7 +466,12 @@ static void ffmpeg_cleanup(int ret) } for (i = 0; i < nb_output_streams; i++) { OutputStream *ost = output_streams[i]; - AVBitStreamFilterContext *bsfc = ost->bitstream_filters; + AVBitStreamFilterContext *bsfc; + + if (!ost) + continue; + + bsfc = ost->bitstream_filters; while (bsfc) { AVBitStreamFilterContext *next = bsfc->next; av_bitstream_filter_close(bsfc); @@ -651,6 +655,7 @@ static void write_frame(AVFormatContext *s, AVPacket *pkt, OutputStream *ost) if (!new_pkt.buf) exit_program(1); } else if (a < 0) { + new_pkt = *pkt; av_log(NULL, AV_LOG_ERROR, "Failed to open bitstream filter %s for stream %d with codec %s", bsfc->filter->name, pkt->stream_index, avctx->codec ? avctx->codec->name : "copy"); @@ -1143,7 +1148,10 @@ static void do_video_out(AVFormatContext *s, if (!ost->last_frame) ost->last_frame = av_frame_alloc(); av_frame_unref(ost->last_frame); - av_frame_ref(ost->last_frame, next_picture); + if (next_picture && ost->last_frame) + av_frame_ref(ost->last_frame, next_picture); + else + av_frame_free(&ost->last_frame); } static double psnr(double d) @@ -1728,17 +1736,21 @@ static void do_streamcopy(InputStream *ist, OutputStream *ost, const AVPacket *p opkt.duration = av_rescale_q(pkt->duration, ist->st->time_base, ost->st->time_base); opkt.flags = pkt->flags; - // FIXME remove the following 2 lines they shall be replaced by the bitstream filters - if ( ost->enc_ctx->codec_id != AV_CODEC_ID_H264 - && ost->enc_ctx->codec_id != AV_CODEC_ID_MPEG1VIDEO - && ost->enc_ctx->codec_id != AV_CODEC_ID_MPEG2VIDEO - && ost->enc_ctx->codec_id != AV_CODEC_ID_VC1 + if ( ost->st->codec->codec_id != AV_CODEC_ID_H264 + && ost->st->codec->codec_id != AV_CODEC_ID_MPEG1VIDEO + && ost->st->codec->codec_id != AV_CODEC_ID_MPEG2VIDEO + && ost->st->codec->codec_id != AV_CODEC_ID_VC1 ) { - if (av_parser_change(ost->parser, ost->st->codec, + int ret = av_parser_change(ost->parser, ost->st->codec, &opkt.data, &opkt.size, pkt->data, pkt->size, - pkt->flags & AV_PKT_FLAG_KEY)) { + pkt->flags & AV_PKT_FLAG_KEY); + if (ret < 0) { + av_log(NULL, AV_LOG_FATAL, "av_parser_change failed\n"); + exit_program(1); + } + if (ret) { opkt.buf = av_buffer_create(opkt.data, opkt.size, av_buffer_default_free, NULL, 0); if (!opkt.buf) exit_program(1); @@ -1749,9 +1761,15 @@ static void do_streamcopy(InputStream *ist, OutputStream *ost, const AVPacket *p } av_copy_packet_side_data(&opkt, pkt); - if (ost->st->codec->codec_type == AVMEDIA_TYPE_VIDEO && (of->ctx->oformat->flags & AVFMT_RAWPICTURE)) { + if (ost->st->codec->codec_type == AVMEDIA_TYPE_VIDEO && + ost->st->codec->codec_id == AV_CODEC_ID_RAWVIDEO && + (of->ctx->oformat->flags & AVFMT_RAWPICTURE)) { /* store AVPicture in AVPacket, as expected by the output format */ - avpicture_fill(&pict, opkt.data, ost->st->codec->pix_fmt, ost->st->codec->width, ost->st->codec->height); + int ret = avpicture_fill(&pict, opkt.data, ost->st->codec->pix_fmt, ost->st->codec->width, ost->st->codec->height); + if (ret < 0) { + av_log(NULL, AV_LOG_FATAL, "avpicture_fill failed\n"); + exit_program(1); + } opkt.data = (uint8_t *)&pict; opkt.size = sizeof(AVPicture); opkt.flags |= AV_PKT_FLAG_KEY; @@ -2521,7 +2539,7 @@ static int transcode_init(void) AVFormatContext *oc; OutputStream *ost; InputStream *ist; - char error[1024]; + char error[1024] = {0}; int want_sdp = 1; for (i = 0; i < nb_filtergraphs; i++) { @@ -2620,11 +2638,13 @@ static int transcode_init(void) enc_ctx->rc_max_rate = dec_ctx->rc_max_rate; enc_ctx->rc_buffer_size = dec_ctx->rc_buffer_size; enc_ctx->field_order = dec_ctx->field_order; - enc_ctx->extradata = av_mallocz(extra_size); - if (!enc_ctx->extradata) { - return AVERROR(ENOMEM); + if (dec_ctx->extradata_size) { + enc_ctx->extradata = av_mallocz(extra_size); + if (!enc_ctx->extradata) { + return AVERROR(ENOMEM); + } + memcpy(enc_ctx->extradata, dec_ctx->extradata, dec_ctx->extradata_size); } - memcpy(enc_ctx->extradata, dec_ctx->extradata, dec_ctx->extradata_size); enc_ctx->extradata_size= dec_ctx->extradata_size; enc_ctx->bits_per_coded_sample = dec_ctx->bits_per_coded_sample; diff --git a/ffmpeg_opt.c b/ffmpeg_opt.c index 1f281f605a..e0c48cee82 100644 --- a/ffmpeg_opt.c +++ b/ffmpeg_opt.c @@ -2248,9 +2248,9 @@ static int opt_target(void *optctx, const char *opt, const char *arg) opt_default(NULL, "g", norm == PAL ? "15" : "18"); opt_default(NULL, "b:v", "1150000"); - opt_default(NULL, "maxrate", "1150000"); - opt_default(NULL, "minrate", "1150000"); - opt_default(NULL, "bufsize", "327680"); // 40*1024*8; + opt_default(NULL, "maxrate:v", "1150000"); + opt_default(NULL, "minrate:v", "1150000"); + opt_default(NULL, "bufsize:v", "327680"); // 40*1024*8; opt_default(NULL, "b:a", "224000"); parse_option(o, "ar", "44100", options); @@ -2277,9 +2277,9 @@ static int opt_target(void *optctx, const char *opt, const char *arg) opt_default(NULL, "g", norm == PAL ? "15" : "18"); opt_default(NULL, "b:v", "2040000"); - opt_default(NULL, "maxrate", "2516000"); - opt_default(NULL, "minrate", "0"); // 1145000; - opt_default(NULL, "bufsize", "1835008"); // 224*1024*8; + opt_default(NULL, "maxrate:v", "2516000"); + opt_default(NULL, "minrate:v", "0"); // 1145000; + opt_default(NULL, "bufsize:v", "1835008"); // 224*1024*8; opt_default(NULL, "scan_offset", "1"); opt_default(NULL, "b:a", "224000"); @@ -2299,9 +2299,9 @@ static int opt_target(void *optctx, const char *opt, const char *arg) opt_default(NULL, "g", norm == PAL ? "15" : "18"); opt_default(NULL, "b:v", "6000000"); - opt_default(NULL, "maxrate", "9000000"); - opt_default(NULL, "minrate", "0"); // 1500000; - opt_default(NULL, "bufsize", "1835008"); // 224*1024*8; + opt_default(NULL, "maxrate:v", "9000000"); + opt_default(NULL, "minrate:v", "0"); // 1500000; + opt_default(NULL, "bufsize:v", "1835008"); // 224*1024*8; opt_default(NULL, "packetsize", "2048"); // from www.mpucoder.com: DVD sectors contain 2048 bytes of data, this is also the size of one pack. opt_default(NULL, "muxrate", "10080000"); // from mplex project: data_rate = 1260000. mux_rate = data_rate * 8 @@ -2345,6 +2345,9 @@ static int opt_vstats(void *optctx, const char *opt, const char *arg) time_t today2 = time(NULL); struct tm *today = localtime(&today2); + if (!today) + return AVERROR(errno); + snprintf(filename, sizeof(filename), "vstats_%02d%02d%02d.log", today->tm_hour, today->tm_min, today->tm_sec); return opt_vstats_file(NULL, opt, filename); @@ -2825,7 +2828,7 @@ const OptionDef options[] = { { "itsscale", HAS_ARG | OPT_DOUBLE | OPT_SPEC | OPT_EXPERT | OPT_INPUT, { .off = OFFSET(ts_scale) }, "set the input ts scale", "scale" }, - { "timestamp", HAS_ARG | OPT_PERFILE, { .func_arg = opt_recording_timestamp }, + { "timestamp", HAS_ARG | OPT_PERFILE | OPT_OUTPUT, { .func_arg = opt_recording_timestamp }, "set the recording timestamp ('now' to set the current time)", "time" }, { "metadata", HAS_ARG | OPT_STRING | OPT_SPEC | OPT_OUTPUT, { .off = OFFSET(metadata) }, "add metadata", "string=string" }, diff --git a/ffmpeg_vda.c b/ffmpeg_vda.c index b9f0975f55..fded39e79b 100644 --- a/ffmpeg_vda.c +++ b/ffmpeg_vda.c @@ -77,6 +77,8 @@ static int vda_retrieve_data(AVCodecContext *s, AVFrame *frame) frame->width, frame->height); ret = av_frame_copy_props(vda->tmp_frame, frame); + CVPixelBufferUnlockBaseAddress(pixbuf, kCVPixelBufferLock_ReadOnly); + if (ret < 0) return ret; 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 fa0f53d70e..4c901fe10a 100644 --- a/libavcodec/Makefile +++ b/libavcodec/Makefile @@ -210,7 +210,7 @@ OBJS-$(CONFIG_DVVIDEO_DECODER) += dvdec.o dv.o dvdata.o OBJS-$(CONFIG_DVVIDEO_ENCODER) += dvenc.o dv.o dvdata.o OBJS-$(CONFIG_DXA_DECODER) += dxa.o OBJS-$(CONFIG_DXTORY_DECODER) += dxtory.o -OBJS-$(CONFIG_EAC3_DECODER) += eac3dec.o eac3_data.o +OBJS-$(CONFIG_EAC3_DECODER) += eac3_data.o OBJS-$(CONFIG_EAC3_ENCODER) += eac3enc.o eac3_data.o OBJS-$(CONFIG_EACMV_DECODER) += eacmv.o OBJS-$(CONFIG_EAMAD_DECODER) += eamad.o eaidct.o mpeg12.o \ diff --git a/libavcodec/a64multienc.c b/libavcodec/a64multienc.c index fc00d3fc62..0d926672f6 100644 --- a/libavcodec/a64multienc.c +++ b/libavcodec/a64multienc.c @@ -28,6 +28,7 @@ #include "a64tables.h" #include "elbg.h" #include "internal.h" +#include "libavutil/avassert.h" #include "libavutil/common.h" #include "libavutil/intreadwrite.h" @@ -65,7 +66,7 @@ static const int mc_colors[5]={0x0,0xb,0xc,0xf,0x1}; //static const int mc_colors[5]={0x0,0x8,0xa,0xf,0x7}; //static const int mc_colors[5]={0x0,0x9,0x8,0xa,0x3}; -static void to_meta_with_crop(AVCodecContext *avctx, AVFrame *p, int *dest) +static void to_meta_with_crop(AVCodecContext *avctx, const AVFrame *p, int *dest) { int blockx, blocky, x, y; int luma = 0; @@ -78,9 +79,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; } @@ -186,7 +191,6 @@ 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_freep(&c->mc_meta_charset); av_freep(&c->mc_best_cb); av_freep(&c->mc_charset); @@ -220,7 +224,7 @@ static av_cold int a64multi_encode_init(AVCodecContext *avctx) a64_palette[mc_colors[a]][2] * 0.11; } - if (!(c->mc_meta_charset = av_malloc_array(c->mc_lifetime, 32000 * sizeof(int))) || + if (!(c->mc_meta_charset = av_mallocz_array(c->mc_lifetime, 32000 * sizeof(int))) || !(c->mc_best_cb = av_malloc(CHARSET_CHARS * 32 * sizeof(int))) || !(c->mc_charmap = av_mallocz_array(c->mc_lifetime, 1000 * sizeof(int))) || !(c->mc_colram = av_mallocz(CHARSET_CHARS * sizeof(uint8_t))) || @@ -238,14 +242,6 @@ static av_cold int a64multi_encode_init(AVCodecContext *avctx) AV_WB32(avctx->extradata, c->mc_lifetime); AV_WB32(avctx->extradata + 16, INTERLACED); - 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) avctx->codec_tag = AV_RL32("a64m"); @@ -270,10 +266,9 @@ static void a64_compress_colram(unsigned char *buf, int *charmap, uint8_t *colra } static int a64multi_encode_frame(AVCodecContext *avctx, AVPacket *pkt, - const AVFrame *pict, int *got_packet) + const AVFrame *p, int *got_packet) { A64Context *c = avctx->priv_data; - AVFrame *const p = avctx->coded_frame; int frame; int x, y; @@ -304,7 +299,7 @@ static int a64multi_encode_frame(AVCodecContext *avctx, AVPacket *pkt, } /* no data, means end encoding asap */ - if (!pict) { + if (!p) { /* all done, end encoding */ if (!c->mc_lifetime) return 0; /* no more frames in queue, prepare to flush remaining frames */ @@ -317,13 +312,10 @@ 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; - p->pict_type = AV_PICTURE_TYPE_I; - p->key_frame = 1; to_meta_with_crop(avctx, p, meta + 32000 * c->mc_frame_counter); c->mc_frame_counter++; if (c->next_pts == AV_NOPTS_VALUE) - c->next_pts = pict->pts; + c->next_pts = p->pts; /* lifetime is not reached so wait for next frame first */ return 0; } @@ -334,8 +326,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; @@ -351,6 +343,7 @@ static int a64multi_encode_frame(AVCodecContext *avctx, AVPacket *pkt, /* advance pointers */ buf += charset_size; + req_size += charset_size; } /* write x frames to buf */ @@ -387,6 +380,7 @@ static int a64multi_encode_frame(AVCodecContext *avctx, AVPacket *pkt, pkt->pts = pkt->dts = c->next_pts; c->next_pts = AV_NOPTS_VALUE; + av_assert0(pkt->size >= req_size); pkt->size = req_size; pkt->flags |= AV_PKT_FLAG_KEY; *got_packet = !!req_size; diff --git a/libavcodec/aaccoder.c b/libavcodec/aaccoder.c index 5bf6a9c155..4b915da2c1 100644 --- a/libavcodec/aaccoder.c +++ b/libavcodec/aaccoder.c @@ -691,7 +691,7 @@ static void search_for_quantizers_anmr(AVCodecContext *avctx, AACEncContext *s, } while (idx) { sce->sf_idx[bandaddr[idx]] = minq + q0; - minq = paths[idx][minq].prev; + minq = FFMAX(paths[idx][minq].prev, 0); idx--; } //set the same quantizers inside window groups diff --git a/libavcodec/aacdec.c b/libavcodec/aacdec.c index db2a9b676e..44066f13e3 100644 --- a/libavcodec/aacdec.c +++ b/libavcodec/aacdec.c @@ -425,7 +425,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; @@ -904,7 +904,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); @@ -2780,7 +2780,7 @@ static void spectral_to_sample(AACContext *ac) apply_channel_coupling(ac, che, type, i, AFTER_IMDCT, apply_independent_coupling); che->present = 0; } else if (che) { - av_log(ac->avctx, AV_LOG_WARNING, "ChannelElement %d.%d missing \n", type, i); + av_log(ac->avctx, AV_LOG_VERBOSE, "ChannelElement %d.%d missing \n", type, i); } } } @@ -3059,6 +3059,12 @@ static int aac_decode_frame_int(AVCodecContext *avctx, void *data, AV_WL32(side, 2*AV_RL32(side)); } + if (!ac->frame->data[0] && samples) { + av_log(avctx, AV_LOG_ERROR, "no frame data found\n"); + err = AVERROR_INVALIDDATA; + goto fail; + } + *got_frame_ptr = !!samples; if (samples) { ac->frame->nb_samples = samples; @@ -3128,7 +3134,7 @@ static int aac_decode_frame(AVCodecContext *avctx, void *data, if (INT_MAX / 8 <= buf_size) return AVERROR_INVALIDDATA; - if ((err = init_get_bits(&gb, buf, buf_size * 8)) < 0) + if ((err = init_get_bits8(&gb, buf, buf_size)) < 0) return err; switch (ac->oc[1].m4ac.object_type) { diff --git a/libavcodec/aacenc.c b/libavcodec/aacenc.c index d9c72155b1..edf28f2aa6 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); @@ -567,8 +567,16 @@ static int aac_encode_frame(AVCodecContext *avctx, AVPacket *avpkt, ics->group_len[w] = wi[ch].grouping[w]; apply_window_and_mdct(s, &cpe->ch[ch], overlap); - if (isnan(cpe->ch->coeffs[0])) { - av_log(avctx, AV_LOG_ERROR, "Input contains NaN\n"); + + if (isnan(cpe->ch[ch].coeffs[ 0]) || isinf(cpe->ch[ch].coeffs[ 0]) || + isnan(cpe->ch[ch].coeffs[ 128]) || isinf(cpe->ch[ch].coeffs[ 128]) || + isnan(cpe->ch[ch].coeffs[2*128]) || isinf(cpe->ch[ch].coeffs[2*128]) || + isnan(cpe->ch[ch].coeffs[3*128]) || isinf(cpe->ch[ch].coeffs[3*128]) || + isnan(cpe->ch[ch].coeffs[4*128]) || isinf(cpe->ch[ch].coeffs[4*128]) || + isnan(cpe->ch[ch].coeffs[5*128]) || isinf(cpe->ch[ch].coeffs[5*128]) || + isnan(cpe->ch[ch].coeffs[6*128]) || isinf(cpe->ch[ch].coeffs[6*128]) || + isnan(cpe->ch[ch].coeffs[7*128]) || isinf(cpe->ch[ch].coeffs[7*128])) { + av_log(avctx, AV_LOG_ERROR, "Input contains NaN/+-Inf\n"); return AVERROR(EINVAL); } } @@ -753,10 +761,10 @@ static av_cold int aac_encode_init(AVCodecContext *avctx) s->chan_map = aac_chan_configs[s->channels-1]; - if (ret = dsp_init(avctx, s)) + if ((ret = dsp_init(avctx, s)) < 0) goto fail; - if (ret = alloc_buffers(avctx, s)) + if ((ret = alloc_buffers(avctx, s)) < 0) goto fail; avctx->extradata_size = 5; @@ -768,7 +776,8 @@ static av_cold int aac_encode_init(AVCodecContext *avctx) lengths[1] = ff_aac_num_swb_128[i]; for (i = 0; i < s->chan_map[0]; i++) grouping[i] = s->chan_map[i + 1] == TYPE_CPE; - if (ret = ff_psy_init(&s->psy, avctx, 2, sizes, lengths, s->chan_map[0], grouping)) + if ((ret = ff_psy_init(&s->psy, avctx, 2, sizes, lengths, + s->chan_map[0], grouping)) < 0) goto fail; s->psypp = ff_psy_preprocess_init(avctx); s->coder = &ff_aac_coders[s->options.aac_coder]; diff --git a/libavcodec/aacpsy.c b/libavcodec/aacpsy.c index 9eeb836523..cee4bf2921 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/aacsbr.c b/libavcodec/aacsbr.c index 94a5685e98..1c06aba832 100644 --- a/libavcodec/aacsbr.c +++ b/libavcodec/aacsbr.c @@ -514,7 +514,7 @@ static int sbr_make_f_master(AACContext *ac, SpectralBandReplication *sbr, /// High Frequency Generation - Patch Construction (14496-3 sp04 p216 fig. 4.46) static int sbr_hf_calc_npatches(AACContext *ac, SpectralBandReplication *sbr) { - int i, k, sb = 0; + int i, k, last_k = -1, last_msb = -1, sb = 0; int msb = sbr->k[0]; int usb = sbr->kx[1]; int goal_sb = ((1000 << 11) + (sbr->sample_rate >> 1)) / sbr->sample_rate; @@ -528,6 +528,12 @@ static int sbr_hf_calc_npatches(AACContext *ac, SpectralBandReplication *sbr) do { int odd = 0; + if (k == last_k && msb == last_msb) { + av_log(ac->avctx, AV_LOG_ERROR, "patch construction failed\n"); + return AVERROR_INVALIDDATA; + } + last_k = k; + last_msb = msb; for (i = k; i == k || sb > (sbr->k[0] - 1 + msb - odd); i--) { sb = sbr->f_master[i]; odd = (sb + sbr->k[0]) & 1; @@ -1012,6 +1018,8 @@ static unsigned int read_sbr_data(AACContext *ac, SpectralBandReplication *sbr, { unsigned int cnt = get_bits_count(gb); + sbr->id_aac = id_aac; + if (id_aac == TYPE_SCE || id_aac == TYPE_CCE) { if (read_sbr_single_channel_element(ac, sbr, gb)) { sbr_turnoff(sbr); @@ -1688,6 +1696,12 @@ void ff_sbr_apply(AACContext *ac, SpectralBandReplication *sbr, int id_aac, int nch = (id_aac == TYPE_CPE) ? 2 : 1; int err; + if (id_aac != sbr->id_aac) { + av_log(ac->avctx, AV_LOG_ERROR, + "element type mismatch %d != %d\n", id_aac, sbr->id_aac); + sbr_turnoff(sbr); + } + if (!sbr->kx_and_m_pushed) { sbr->kx[0] = sbr->kx[1]; sbr->m[0] = sbr->m[1]; @@ -1711,6 +1725,7 @@ void ff_sbr_apply(AACContext *ac, SpectralBandReplication *sbr, int id_aac, sbr->c.sbr_hf_inverse_filter(&sbr->dsp, sbr->alpha0, sbr->alpha1, (const float (*)[40][2]) sbr->X_low, sbr->k[0]); sbr_chirp(sbr, &sbr->data[ch]); + av_assert0(sbr->data[ch].bs_num_env > 0); sbr_hf_gen(ac, sbr, sbr->X_high, (const float (*)[40][2]) sbr->X_low, (const float (*)[2]) sbr->alpha0, diff --git a/libavcodec/aarch64/h264dsp_init_aarch64.c b/libavcodec/aarch64/h264dsp_init_aarch64.c index ed5e4bdd9b..e0f378f5ab 100644 --- a/libavcodec/aarch64/h264dsp_init_aarch64.c +++ b/libavcodec/aarch64/h264dsp_init_aarch64.c @@ -78,6 +78,7 @@ av_cold void ff_h264dsp_init_aarch64(H264DSPContext *c, const int bit_depth, c->h264_v_loop_filter_luma = ff_h264_v_loop_filter_luma_neon; c->h264_h_loop_filter_luma = ff_h264_h_loop_filter_luma_neon; c->h264_v_loop_filter_chroma = ff_h264_v_loop_filter_chroma_neon; + if (chroma_format_idc <= 1) c->h264_h_loop_filter_chroma = ff_h264_h_loop_filter_chroma_neon; c->weight_h264_pixels_tab[0] = ff_weight_h264_pixels_16_neon; diff --git a/libavcodec/aasc.c b/libavcodec/aasc.c index 65ef782688..469fc5eef6 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/ac3dec.c b/libavcodec/ac3dec.c index d3e8713e03..0ffd0a10a7 100644 --- a/libavcodec/ac3dec.c +++ b/libavcodec/ac3dec.c @@ -872,7 +872,7 @@ static int decode_audio_block(AC3DecodeContext *s, int blk) start_subband += start_subband - 7; end_subband = get_bits(gbc, 3) + 5; #if USE_FIXED - s->spx_dst_end_freq = end_freq_inv_tab[end_subband]; + s->spx_dst_end_freq = end_freq_inv_tab[end_subband-5]; #endif if (end_subband > 7) end_subband += end_subband - 7; @@ -902,11 +902,13 @@ static int decode_audio_block(AC3DecodeContext *s, int blk) ff_eac3_default_spx_band_struct, &s->num_spx_bands, s->spx_band_sizes); - } else { - for (ch = 1; ch <= fbw_channels; ch++) { - s->channel_uses_spx[ch] = 0; - s->first_spx_coords[ch] = 1; - } + } + } + if (!s->eac3 || !s->spx_in_use) { + s->spx_in_use = 0; + for (ch = 1; ch <= fbw_channels; ch++) { + s->channel_uses_spx[ch] = 0; + s->first_spx_coords[ch] = 1; } } @@ -939,7 +941,7 @@ static int decode_audio_block(AC3DecodeContext *s, int blk) nblend = 0; sblend = 0x800000; } else if (nratio > 0x7fffff) { - nblend = 0x800000; + nblend = 14529495; // sqrt(3) in FP.23 sblend = 0; } else { nblend = fixed_sqrt(nratio, 23); diff --git a/libavcodec/ac3dec.h b/libavcodec/ac3dec.h index be29f00b14..5259c60009 100644 --- a/libavcodec/ac3dec.h +++ b/libavcodec/ac3dec.h @@ -243,19 +243,19 @@ typedef struct AC3DecodeContext { * Parse the E-AC-3 frame header. * This parses both the bit stream info and audio frame header. */ -int ff_eac3_parse_header(AC3DecodeContext *s); +static int ff_eac3_parse_header(AC3DecodeContext *s); /** * Decode mantissas in a single channel for the entire frame. * This is used when AHT mode is enabled. */ -void ff_eac3_decode_transform_coeffs_aht_ch(AC3DecodeContext *s, int ch); +static void ff_eac3_decode_transform_coeffs_aht_ch(AC3DecodeContext *s, int ch); /** * Apply spectral extension to each channel by copying lower frequency * coefficients to higher frequency bins and applying side information to * approximate the original high frequency signal. */ -void ff_eac3_apply_spectral_extension(AC3DecodeContext *s); +static void ff_eac3_apply_spectral_extension(AC3DecodeContext *s); #endif /* AVCODEC_AC3DEC_H */ diff --git a/libavcodec/ac3dec_fixed.c b/libavcodec/ac3dec_fixed.c index cb3b251589..b4beee6dd7 100644 --- a/libavcodec/ac3dec_fixed.c +++ b/libavcodec/ac3dec_fixed.c @@ -164,6 +164,7 @@ static void ac3_downmix_c_fixed16(int16_t **samples, int16_t (*matrix)[2], } } +#include "eac3dec.c" #include "ac3dec.c" static const AVOption options[] = { diff --git a/libavcodec/ac3dec_float.c b/libavcodec/ac3dec_float.c index e7fc5cbed1..d74a0df68d 100644 --- a/libavcodec/ac3dec_float.c +++ b/libavcodec/ac3dec_float.c @@ -28,6 +28,7 @@ * Upmix delay samples from stereo to original channel layout. */ #include "ac3dec.h" +#include "eac3dec.c" #include "ac3dec.c" static const AVOption options[] = { diff --git a/libavcodec/adpcm.c b/libavcodec/adpcm.c index 2f95a6ff45..f7ca208993 100644 --- a/libavcodec/adpcm.c +++ b/libavcodec/adpcm.c @@ -574,6 +574,8 @@ static int get_nb_samples(AVCodecContext *avctx, GetByteContext *gb, case AV_CODEC_ID_ADPCM_IMA_DK4: if (avctx->block_align > 0) buf_size = FFMIN(buf_size, avctx->block_align); + if (buf_size < 4 * ch) + return AVERROR_INVALIDDATA; nb_samples = 1 + (buf_size - 4 * ch) * 2 / ch; break; case AV_CODEC_ID_ADPCM_IMA_RAD: @@ -587,13 +589,15 @@ static int get_nb_samples(AVCodecContext *avctx, GetByteContext *gb, int bsamples = ff_adpcm_ima_block_samples[avctx->bits_per_coded_sample - 2]; if (avctx->block_align > 0) buf_size = FFMIN(buf_size, avctx->block_align); + if (buf_size < 4 * ch) + return AVERROR_INVALIDDATA; nb_samples = 1 + (buf_size - 4 * ch) / (bsize * ch) * bsamples; break; } case AV_CODEC_ID_ADPCM_MS: if (avctx->block_align > 0) buf_size = FFMIN(buf_size, avctx->block_align); - nb_samples = 2 + (buf_size - 7 * ch) * 2 / ch; + nb_samples = (buf_size - 6 * ch) * 2 / ch; break; case AV_CODEC_ID_ADPCM_SBPRO_2: case AV_CODEC_ID_ADPCM_SBPRO_3: @@ -606,6 +610,8 @@ static int get_nb_samples(AVCodecContext *avctx, GetByteContext *gb, case AV_CODEC_ID_ADPCM_SBPRO_4: samples_per_byte = 2; break; } if (!s->status[0].step_index) { + if (buf_size < ch) + return AVERROR_INVALIDDATA; nb_samples++; buf_size -= ch; } @@ -1524,6 +1530,11 @@ static int adpcm_decode_frame(AVCodecContext *avctx, void *data, *got_frame_ptr = 1; + if (avpkt->size < bytestream2_tell(&gb)) { + av_log(avctx, AV_LOG_ERROR, "Overread of %d < %d\n", avpkt->size, bytestream2_tell(&gb)); + return avpkt->size; + } + return bytestream2_tell(&gb); } diff --git a/libavcodec/adpcmenc.c b/libavcodec/adpcmenc.c index ea6cc23e97..7692db4d67 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]; @@ -571,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 3472301f53..5882bf1b9a 100644 --- a/libavcodec/aic.c +++ b/libavcodec/aic.c @@ -438,8 +438,8 @@ static av_cold int aic_decode_init(AVCodecContext *avctx) 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 aec7bb4e4e..48013f6472 100644 --- a/libavcodec/alac.c +++ b/libavcodec/alac.c @@ -316,6 +316,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); @@ -528,6 +533,12 @@ static int allocate_buffers(ALACContext *alac) int ch; int buf_size = alac->max_samples_per_frame * sizeof(int32_t); + for (ch = 0; ch < 2; ch++) { + alac->predict_error_buffer[ch] = NULL; + alac->output_samples_buffer[ch] = NULL; + alac->extra_bits_buffer[ch] = NULL; + } + for (ch = 0; ch < FFMIN(alac->channels, 2); ch++) { FF_ALLOC_OR_GOTO(alac->avctx, alac->predict_error_buffer[ch], buf_size, buf_alloc_fail); diff --git a/libavcodec/alsdec.c b/libavcodec/alsdec.c index cfece44285..1855f53921 100644 --- a/libavcodec/alsdec.c +++ b/libavcodec/alsdec.c @@ -357,11 +357,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; @@ -678,7 +682,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); @@ -1242,6 +1246,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; @@ -1272,9 +1277,9 @@ static int revert_channel_correlation(ALSDecContext *ctx, ALSBlockData *bd, bd->raw_samples = ctx->raw_samples[c] + offset; for (dep = 0; !ch[dep].stop_flag; dep++) { - 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; @@ -1286,11 +1291,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 ]) + @@ -1303,6 +1325,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]) + @@ -1461,6 +1493,11 @@ static int read_frame_data(ALSDecContext *ctx, unsigned int ra_frame) // TODO: read_diff_float_data + if (get_bits_left(gb) < 0) { + av_log(ctx->avctx, AV_LOG_ERROR, "Overread %d\n", -get_bits_left(gb)); + return AVERROR_INVALIDDATA; + } + return 0; } @@ -1665,6 +1702,12 @@ static av_cold int decode_init(AVCodecContext *avctx) avctx->sample_fmt = sconf->resolution > 1 ? AV_SAMPLE_FMT_S32 : AV_SAMPLE_FMT_S16; avctx->bits_per_raw_sample = (sconf->resolution + 1) * 8; + if (avctx->bits_per_raw_sample > 32) { + av_log(avctx, AV_LOG_ERROR, "Bits per raw sample %d larger than 32.\n", + avctx->bits_per_raw_sample); + ret = AVERROR_INVALIDDATA; + goto fail; + } } // set maximum Rice parameter for progressive decoding based on resolution @@ -1727,9 +1770,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/apedec.c b/libavcodec/apedec.c index 383b7fe669..4b11b1b4bc 100644 --- a/libavcodec/apedec.c +++ b/libavcodec/apedec.c @@ -601,14 +601,14 @@ 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; if (rice->k >= 24) return; - for (; i < 64; i++) { + 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; @@ -905,6 +905,9 @@ static void long_filter_high_3800(int32_t *buffer, int order, int shift, int i, j; int32_t dotprod, sign; + if (order >= length) + return; + memset(coeffs, 0, order * sizeof(*coeffs)); for (i = 0; i < order; i++) delay[i] = buffer[i]; @@ -1384,7 +1387,7 @@ static void ape_unpack_stereo(APEContext *ctx, int count) int32_t *decoded0 = ctx->decoded[0]; int32_t *decoded1 = ctx->decoded[1]; - if (ctx->frameflags & APE_FRAMECODE_STEREO_SILENCE) { + if ((ctx->frameflags & APE_FRAMECODE_STEREO_SILENCE) == APE_FRAMECODE_STEREO_SILENCE) { /* We are pure silence, so we're done. */ av_log(ctx->avctx, AV_LOG_DEBUG, "pure silence stereo\n"); return; @@ -1476,13 +1479,13 @@ static int ape_decode_frame(AVCodecContext *avctx, void *data, 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/videodsp_armv5te.S b/libavcodec/arm/videodsp_armv5te.S index 55bcce5cb6..aff1161ada 100644 --- a/libavcodec/arm/videodsp_armv5te.S +++ b/libavcodec/arm/videodsp_armv5te.S @@ -23,9 +23,10 @@ #include "libavutil/arm/asm.S" function ff_prefetch_arm, export=1 +1: subs r2, r2, #1 pld [r0] add r0, r0, r1 - bne X(ff_prefetch_arm) + bne 1b bx lr endfunc diff --git a/libavcodec/ass_split.c b/libavcodec/ass_split.c index cc4f961c4d..cdf4d845db 100644 --- a/libavcodec/ass_split.c +++ b/libavcodec/ass_split.c @@ -523,7 +523,7 @@ ASSStyle *ff_ass_style_get(ASSSplitContext *ctx, const char *style) if (!style || !*style) style = "Default"; for (i=0; istyles_count; i++) - if (!strcmp(ass->styles[i].name, style)) + if (ass->styles[i].name && !strcmp(ass->styles[i].name, style)) return ass->styles + i; return NULL; } diff --git a/libavcodec/atrac3plusdec.c b/libavcodec/atrac3plusdec.c index 78121e8467..50cf74ec43 100644 --- a/libavcodec/atrac3plusdec.c +++ b/libavcodec/atrac3plusdec.c @@ -383,7 +383,7 @@ static int atrac3p_decode_frame(AVCodecContext *avctx, void *data, *got_frame_ptr = 1; - return avctx->block_align; + return FFMIN(avctx->block_align, avpkt->size); } AVCodec ff_atrac3p_decoder = { diff --git a/libavcodec/atrac3plusdsp.c b/libavcodec/atrac3plusdsp.c index 3522af1e5a..3c68f74d25 100644 --- a/libavcodec/atrac3plusdsp.c +++ b/libavcodec/atrac3plusdsp.c @@ -599,8 +599,8 @@ void ff_atrac3p_ipqf(FFTContext *dct_ctx, Atrac3pIPQFChannelCtx *hist, const float *in, float *out) { int i, s, sb, t, pos_now, pos_next; - DECLARE_ALIGNED(32, float, idct_in)[ATRAC3P_SUBBANDS]; - DECLARE_ALIGNED(32, float, idct_out)[ATRAC3P_SUBBANDS]; + LOCAL_ALIGNED(32, float, idct_in, [ATRAC3P_SUBBANDS]); + LOCAL_ALIGNED(32, float, idct_out, [ATRAC3P_SUBBANDS]); memset(out, 0, ATRAC3P_FRAME_SAMPLES * sizeof(*out)); diff --git a/libavcodec/avpacket.c b/libavcodec/avpacket.c index 3c26046dad..51b5c525ac 100644 --- a/libavcodec/avpacket.c +++ b/libavcodec/avpacket.c @@ -58,6 +58,7 @@ void av_init_packet(AVPacket *pkt) #if FF_API_DESTRUCT_PACKET FF_DISABLE_DEPRECATION_WARNINGS pkt->destruct = NULL; + pkt->priv = NULL; FF_ENABLE_DEPRECATION_WARNINGS #endif pkt->buf = NULL; @@ -387,10 +388,12 @@ int av_packet_split_side_data(AVPacket *pkt){ p = pkt->data + pkt->size - 8 - 5; for (i=1; ; i++){ size = AV_RB32(p); - if (size>INT_MAX || p - pkt->data < size) + if (size>INT_MAX - 5 || p - pkt->data < size) return 0; if (p[4]&128) break; + if (p - pkt->data < size + 5) + return 0; p-= size+5; } @@ -401,7 +404,7 @@ int av_packet_split_side_data(AVPacket *pkt){ p= pkt->data + pkt->size - 8 - 5; for (i=0; ; i++){ size= AV_RB32(p); - av_assert0(size<=INT_MAX && p - pkt->data >= size); + av_assert0(size<=INT_MAX - 5 && p - pkt->data >= size); pkt->side_data[i].data = av_mallocz(size + FF_INPUT_BUFFER_PADDING_SIZE); pkt->side_data[i].size = size; pkt->side_data[i].type = p[4]&127; diff --git a/libavcodec/bitstream.c b/libavcodec/bitstream.c index d041643eff..2e102df71b 100644 --- a/libavcodec/bitstream.c +++ b/libavcodec/bitstream.c @@ -69,6 +69,8 @@ void avpriv_copy_bits(PutBitContext *pb, const uint8_t *src, int length) if (length == 0) return; + av_assert0(length <= put_bits_left(pb)); + if (CONFIG_SMALL || words < 16 || put_bits_count(pb) & 7) { for (i = 0; i < words; i++) put_bits(pb, 16, AV_RB16(src + 2 * i)); diff --git a/libavcodec/bmp_parser.c b/libavcodec/bmp_parser.c index c9493dc32d..7ab32a0b00 100644 --- a/libavcodec/bmp_parser.c +++ b/libavcodec/bmp_parser.c @@ -63,7 +63,7 @@ restart: continue; } bpc->pc.frame_start_found++; - bpc->remaining_size = bpc->fsize + i - 17; + bpc->remaining_size = bpc->fsize + FFMAX(i - 17, 0); if (bpc->pc.index + i > 17) { next = i - 17; diff --git a/libavcodec/bytestream.h b/libavcodec/bytestream.h index c2cb601806..7c05ea6cf5 100644 --- a/libavcodec/bytestream.h +++ b/libavcodec/bytestream.h @@ -71,8 +71,10 @@ static av_always_inline type bytestream2_get_ ## name ## u(GetByteContext *g) \ } \ static av_always_inline type bytestream2_get_ ## name(GetByteContext *g) \ { \ - if (g->buffer_end - g->buffer < bytes) \ + if (g->buffer_end - g->buffer < bytes) { \ + g->buffer = g->buffer_end; \ return 0; \ + } \ return bytestream2_get_ ## name ## u(g); \ } \ static av_always_inline type bytestream2_peek_ ## name(GetByteContext *g) \ diff --git a/libavcodec/cabac.c b/libavcodec/cabac.c index 81a75dd52a..48f70ca30e 100644 --- a/libavcodec/cabac.c +++ b/libavcodec/cabac.c @@ -51,7 +51,7 @@ void ff_init_cabac_encoder(CABACContext *c, uint8_t *buf, int buf_size){ * * @param buf_size size of buf in bits */ -void ff_init_cabac_decoder(CABACContext *c, const uint8_t *buf, int buf_size){ +int ff_init_cabac_decoder(CABACContext *c, const uint8_t *buf, int buf_size){ c->bytestream_start= c->bytestream= buf; c->bytestream_end= buf + buf_size; @@ -64,6 +64,9 @@ void ff_init_cabac_decoder(CABACContext *c, const uint8_t *buf, int buf_size){ #endif c->low+= ((*c->bytestream++)<<2) + 2; c->range= 0x1FE; + if ((c->range<<(CABAC_BITS+1)) < c->low) + return AVERROR_INVALIDDATA; + return 0; } void ff_init_cabac_states(void) diff --git a/libavcodec/cabac.h b/libavcodec/cabac.h index f9eafed105..857211c9d9 100644 --- a/libavcodec/cabac.h +++ b/libavcodec/cabac.h @@ -56,7 +56,7 @@ typedef struct CABACContext{ }CABACContext; void ff_init_cabac_encoder(CABACContext *c, uint8_t *buf, int buf_size); -void ff_init_cabac_decoder(CABACContext *c, const uint8_t *buf, int buf_size); +int ff_init_cabac_decoder(CABACContext *c, const uint8_t *buf, int buf_size); void ff_init_cabac_states(void); #endif /* AVCODEC_CABAC_H */ diff --git a/libavcodec/cabac_functions.h b/libavcodec/cabac_functions.h index 15dba29f8e..2d1d2a6b89 100644 --- a/libavcodec/cabac_functions.h +++ b/libavcodec/cabac_functions.h @@ -74,7 +74,8 @@ static inline void renorm_cabac_decoder_once(CABACContext *c){ #ifndef get_cabac_inline static void refill2(CABACContext *c){ - int i, x; + int i; + unsigned x; x= c->low ^ (c->low-1); i= 7 - ff_h264_norm_shift[x>>(CABAC_BITS-1)]; @@ -190,7 +191,8 @@ static av_unused const uint8_t* skip_bytes(CABACContext *c, int n) { #endif if ((int) (c->bytestream_end - ptr) < n) return NULL; - ff_init_cabac_decoder(c, ptr + n, c->bytestream_end - ptr - n); + if (ff_init_cabac_decoder(c, ptr + n, c->bytestream_end - ptr - n) < 0) + return NULL; return ptr; } diff --git a/libavcodec/cavsdec.c b/libavcodec/cavsdec.c index b5304eab9e..1ae897b774 100644 --- a/libavcodec/cavsdec.c +++ b/libavcodec/cavsdec.c @@ -563,6 +563,11 @@ static int decode_residual_block(AVSContext *h, GetBitContext *gb, return AVERROR_INVALIDDATA; } esc_code = get_ue_code(gb, esc_golomb_order); + if (esc_code < 0 || esc_code > 32767) { + av_log(h->avctx, AV_LOG_ERROR, "esc_code invalid\n"); + return AVERROR_INVALIDDATA; + } + level = esc_code + (run > r->max_run ? 1 : r->level_add[run]); while (level > r->inc_limit) r++; @@ -1118,6 +1123,7 @@ static int decode_seq_header(AVSContext *h) { int frame_rate_code; int width, height; + int ret; h->profile = get_bits(&h->gb, 8); h->level = get_bits(&h->gb, 8); @@ -1134,9 +1140,6 @@ static int decode_seq_header(AVSContext *h) av_log(h->avctx, AV_LOG_ERROR, "Dimensions invalid\n"); return AVERROR_INVALIDDATA; } - h->width = width; - h->height = height; - skip_bits(&h->gb, 2); //chroma format skip_bits(&h->gb, 3); //sample_precision h->aspect_ratio = get_bits(&h->gb, 4); @@ -1145,11 +1148,16 @@ static int decode_seq_header(AVSContext *h) skip_bits1(&h->gb); //marker_bit skip_bits(&h->gb, 12); //bit_rate_upper h->low_delay = get_bits1(&h->gb); + + ret = ff_set_dimensions(h->avctx, width, height); + if (ret < 0) + return ret; + + h->width = width; + h->height = height; h->mb_width = (h->width + 15) >> 4; h->mb_height = (h->height + 15) >> 4; h->avctx->framerate = ff_mpeg12_frame_rate_tab[frame_rate_code]; - h->avctx->width = h->width; - h->avctx->height = h->height; if (!h->top_qp) ff_cavs_init_top_lines(h); return 0; diff --git a/libavcodec/dca.c b/libavcodec/dca.c index 22be88fe1a..57c65150da 100644 --- a/libavcodec/dca.c +++ b/libavcodec/dca.c @@ -40,8 +40,6 @@ int avpriv_dca_convert_bitstream(const uint8_t *src, int src_size, uint8_t *dst, { uint32_t mrk; int i, tmp; - const uint16_t *ssrc = (const uint16_t *) src; - uint16_t *sdst = (uint16_t *) dst; PutBitContext pb; if ((unsigned) src_size > (unsigned) max_size) @@ -53,8 +51,11 @@ int avpriv_dca_convert_bitstream(const uint8_t *src, int src_size, uint8_t *dst, memcpy(dst, src, src_size); return src_size; case DCA_MARKER_RAW_LE: - for (i = 0; i < (src_size + 1) >> 1; i++) - *sdst++ = av_bswap16(*ssrc++); + for (i = 0; i < (src_size + 1) >> 1; i++) { + AV_WB16(dst, AV_RL16(src)); + src += 2; + dst += 2; + } return src_size; case DCA_MARKER_14B_BE: case DCA_MARKER_14B_LE: diff --git a/libavcodec/dcadec.c b/libavcodec/dcadec.c index a36f69b2ae..907e49b64d 100644 --- a/libavcodec/dcadec.c +++ b/libavcodec/dcadec.c @@ -584,6 +584,14 @@ static int dca_parse_audio_coding_header(DCAContext *s, int base_channel, } nchans = get_bits(&s->gb, 3) + 1; + if (xxch && nchans >= 3) { + av_log(s->avctx, AV_LOG_ERROR, "nchans %d is too large\n", nchans); + return AVERROR_INVALIDDATA; + } else if (nchans + base_channel > DCA_PRIM_CHANNELS_MAX) { + av_log(s->avctx, AV_LOG_ERROR, "channel sum %d + %d is too large\n", nchans, base_channel); + return AVERROR_INVALIDDATA; + } + s->total_channels = nchans + base_channel; s->prim_channels = s->total_channels; @@ -848,6 +856,10 @@ static int dca_subframe_header(DCAContext *s, int base_channel, int block_index) if (!base_channel) { s->subsubframes[s->current_subframe] = get_bits(&s->gb, 2) + 1; + if (block_index + s->subsubframes[s->current_subframe] > s->sample_blocks/8) { + s->subsubframes[s->current_subframe] = 1; + return AVERROR_INVALIDDATA; + } s->partial_samples[s->current_subframe] = get_bits(&s->gb, 3); } @@ -1811,8 +1823,13 @@ static int dca_xbr_parse_frame(DCAContext *s) for(i = 0; i < num_chsets; i++) { n_xbr_ch[i] = get_bits(&s->gb, 3) + 1; k = get_bits(&s->gb, 2) + 5; - for(j = 0; j < n_xbr_ch[i]; j++) + for(j = 0; j < n_xbr_ch[i]; j++) { active_bands[i][j] = get_bits(&s->gb, k) + 1; + if (active_bands[i][j] > DCA_SUBBANDS) { + av_log(s->avctx, AV_LOG_ERROR, "too many active subbands (%d)\n", active_bands[i][j]); + return AVERROR_INVALIDDATA; + } + } } /* skip to the end of the header */ @@ -1854,23 +1871,34 @@ static int dca_xbr_parse_frame(DCAContext *s) for(i = 0; i < n_xbr_ch[chset]; i++) { const uint32_t *scale_table; int nbits; + int scale_table_size; if (s->scalefactor_huffman[chan_base+i] == 6) { scale_table = scale_factor_quant7; + scale_table_size = FF_ARRAY_ELEMS(scale_factor_quant7); } else { scale_table = scale_factor_quant6; + scale_table_size = FF_ARRAY_ELEMS(scale_factor_quant6); } nbits = anctemp[i]; for(j = 0; j < active_bands[chset][i]; j++) { if(abits_high[i][j] > 0) { - scale_table_high[i][j][0] = - scale_table[get_bits(&s->gb, nbits)]; + int index = get_bits(&s->gb, nbits); + if (index >= scale_table_size) { + av_log(s->avctx, AV_LOG_ERROR, "scale table index %d invalid\n", index); + return AVERROR_INVALIDDATA; + } + scale_table_high[i][j][0] = scale_table[index]; if(xbr_tmode && s->transition_mode[i][j]) { - scale_table_high[i][j][1] = - scale_table[get_bits(&s->gb, nbits)]; + int index = get_bits(&s->gb, nbits); + if (index >= scale_table_size) { + av_log(s->avctx, AV_LOG_ERROR, "scale table index %d invalid\n", index); + return AVERROR_INVALIDDATA; + } + scale_table_high[i][j][1] = scale_table[index]; } } } @@ -2360,6 +2388,10 @@ FF_ENABLE_DEPRECATION_WARNINGS #else if (s->xch_present && !s->xch_disable) { #endif + if (avctx->channel_layout & AV_CH_BACK_CENTER) { + avpriv_request_sample(avctx, "XCh with Back center channel"); + return AVERROR_INVALIDDATA; + } avctx->channel_layout |= AV_CH_BACK_CENTER; if (s->lfe) { avctx->channel_layout |= AV_CH_LOW_FREQUENCY; diff --git a/libavcodec/dcaenc.c b/libavcodec/dcaenc.c index 905cdc9ade..182494a208 100644 --- a/libavcodec/dcaenc.c +++ b/libavcodec/dcaenc.c @@ -939,6 +939,10 @@ static int encode_frame(AVCodecContext *avctx, AVPacket *avpkt, for (i = 0; i < SUBFRAMES; i++) put_subframe(c, i); + + for (i = put_bits_count(&c->pb); i < 8*c->frame_size; i++) + put_bits(&c->pb, 1, 0); + flush_put_bits(&c->pb); avpkt->pts = frame->pts; diff --git a/libavcodec/dirac_parser.c b/libavcodec/dirac_parser.c index 45ded5a779..1ca7e31f1c 100644 --- a/libavcodec/dirac_parser.c +++ b/libavcodec/dirac_parser.c @@ -100,10 +100,12 @@ typedef struct DiracParseUnit { static int unpack_parse_unit(DiracParseUnit *pu, DiracParseContext *pc, int offset) { - uint8_t *start = pc->buffer + offset; - uint8_t *end = pc->buffer + pc->index; - if (start < pc->buffer || (start + 13 > end)) + int8_t *start; + + if (offset < 0 || pc->index - 13 < offset) return 0; + + start = pc->buffer + offset; pu->pu_type = start[4]; pu->next_pu_offset = AV_RB32(start + 5); @@ -112,6 +114,15 @@ static int unpack_parse_unit(DiracParseUnit *pu, DiracParseContext *pc, if (pu->pu_type == 0x10 && pu->next_pu_offset == 0) pu->next_pu_offset = 13; + if (pu->next_pu_offset && pu->next_pu_offset < 13) { + av_log(NULL, AV_LOG_ERROR, "next_pu_offset %d is invalid\n", pu->next_pu_offset); + return 0; + } + if (pu->prev_pu_offset && pu->prev_pu_offset < 13) { + av_log(NULL, AV_LOG_ERROR, "prev_pu_offset %d is invalid\n", pu->prev_pu_offset); + return 0; + } + return 1; } @@ -123,7 +134,7 @@ static int dirac_combine_frame(AVCodecParserContext *s, AVCodecContext *avctx, DiracParseContext *pc = s->priv_data; if (pc->overread_index) { - memcpy(pc->buffer, pc->buffer + pc->overread_index, + memmove(pc->buffer, pc->buffer + pc->overread_index, pc->index - pc->overread_index); pc->index -= pc->overread_index; pc->overread_index = 0; @@ -190,7 +201,7 @@ static int dirac_combine_frame(AVCodecParserContext *s, AVCodecContext *avctx, } /* Get the picture number to set the pts and dts*/ - if (parse_timing_info) { + if (parse_timing_info && pu1.prev_pu_offset >= 13) { uint8_t *cur_pu = pc->buffer + pc->index - 13 - pu1.prev_pu_offset; int pts = AV_RB32(cur_pu + 13); diff --git a/libavcodec/diracdec.c b/libavcodec/diracdec.c index aa8e2b0db9..9640c82e83 100644 --- a/libavcodec/diracdec.c +++ b/libavcodec/diracdec.c @@ -772,7 +772,7 @@ static int decode_lowdelay_slice(AVCodecContext *avctx, void *arg) * Dirac Specification -> * 13.5.1 low_delay_transform_data() */ -static void decode_lowdelay(DiracContext *s) +static int decode_lowdelay(DiracContext *s) { AVCodecContext *avctx = s->avctx; int slice_x, slice_y, bytes, bufsize; @@ -781,6 +781,8 @@ static void decode_lowdelay(DiracContext *s) int slice_num = 0; slices = av_mallocz_array(s->lowdelay.num_x, s->lowdelay.num_y * sizeof(struct lowdelay_slice)); + if (!slices) + return AVERROR(ENOMEM); align_get_bits(&s->gb); /*[DIRAC_STD] 13.5.2 Slices. slice(sx,sy) */ @@ -799,7 +801,10 @@ static void decode_lowdelay(DiracContext *s) slice_num++; buf += bytes; - bufsize -= bytes*8; + if (bufsize/8 >= bytes) + bufsize -= bytes*8; + else + bufsize = 0; } avctx->execute(avctx, decode_lowdelay_slice, slices, NULL, slice_num, @@ -808,6 +813,7 @@ static void decode_lowdelay(DiracContext *s) intra_dc_prediction(&s->plane[1].band[0][0]); /* [DIRAC_STD] 13.3 intra_dc_prediction() */ intra_dc_prediction(&s->plane[2].band[0][0]); /* [DIRAC_STD] 13.3 intra_dc_prediction() */ av_free(slices); + return 0; } static void init_planes(DiracContext *s) @@ -896,6 +902,14 @@ static int dirac_unpack_prediction_parameters(DiracContext *s) /*[DIRAC_STD] 11.2.4 motion_data_dimensions() Calculated in function dirac_unpack_block_motion_data */ + if (s->plane[0].xblen % (1 << s->chroma_x_shift) != 0 || + s->plane[0].yblen % (1 << s->chroma_y_shift) != 0 || + !s->plane[0].xblen || !s->plane[0].yblen) { + av_log(s->avctx, AV_LOG_ERROR, + "invalid x/y block length (%d/%d) for x/y chroma shift (%d/%d)\n", + s->plane[0].xblen, s->plane[0].yblen, s->chroma_x_shift, s->chroma_y_shift); + return AVERROR_INVALIDDATA; + } if (!s->plane[0].xbsep || !s->plane[0].ybsep || s->plane[0].xbsep < s->plane[0].xblen/2 || s->plane[0].ybsep < s->plane[0].yblen/2) { av_log(s->avctx, AV_LOG_ERROR, "Block separation too small\n"); return -1; @@ -1550,7 +1564,7 @@ static void select_dsp_funcs(DiracContext *s, int width, int height, int xblen, } } -static void interpolate_refplane(DiracContext *s, DiracFrame *ref, int plane, int width, int height) +static int interpolate_refplane(DiracContext *s, DiracFrame *ref, int plane, int width, int height) { /* chroma allocates an edge of 8 when subsampled which for 4:2:2 means an h edge of 16 and v edge of 8 @@ -1562,11 +1576,14 @@ static void interpolate_refplane(DiracContext *s, DiracFrame *ref, int plane, in /* no need for hpel if we only have fpel vectors */ if (!s->mv_precision) - return; + return 0; 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); + if (!ref->hpel_base[plane][i]) { + return AVERROR(ENOMEM); + } /* 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; } @@ -1580,6 +1597,8 @@ static void interpolate_refplane(DiracContext *s, DiracFrame *ref, int plane, in s->mpvencdsp.draw_edges(ref->hpel[plane][3], ref->avframe->linesize[plane], width, height, edge, edge, EDGE_TOP | EDGE_BOTTOM); } ref->interpolated[plane] = 1; + + return 0; } /** @@ -1590,6 +1609,7 @@ static int dirac_decode_frame_internal(DiracContext *s) { DWTContext d; int y, i, comp, dsty; + int ret; if (s->low_delay) { /* [DIRAC_STD] 13.5.1 low_delay_transform_data() */ @@ -1597,8 +1617,10 @@ static int dirac_decode_frame_internal(DiracContext *s) Plane *p = &s->plane[comp]; memset(p->idwt_buf, 0, p->idwt_stride * p->idwt_height * sizeof(IDWTELEM)); } - if (!s->zero_res) - decode_lowdelay(s); + if (!s->zero_res) { + if ((ret = decode_lowdelay(s)) < 0) + return ret; + } } for (comp = 0; comp < 3; comp++) { @@ -1629,8 +1651,11 @@ static int dirac_decode_frame_internal(DiracContext *s) select_dsp_funcs(s, p->width, p->height, p->xblen, p->yblen); - for (i = 0; i < s->num_refs; i++) - interpolate_refplane(s, s->ref_pics[i], comp, p->width, p->height); + for (i = 0; i < s->num_refs; i++) { + int ret = interpolate_refplane(s, s->ref_pics[i], comp, p->width, p->height); + if (ret < 0) + return ret; + } memset(s->mctmp, 0, 4*p->yoffset*p->stride); @@ -1736,6 +1761,12 @@ static int dirac_decode_picture_header(DiracContext *s) get_buffer_with_edge(s->avctx, s->ref_pics[i]->avframe, AV_GET_BUFFER_FLAG_REF); break; } + + if (!s->ref_pics[i]) { + av_log(s->avctx, AV_LOG_ERROR, "Reference could not be allocated\n"); + return -1; + } + } /* retire the reference frames that are not used anymore */ @@ -1931,8 +1962,8 @@ static int dirac_decode_frame(AVCodecContext *avctx, void *data, int *got_frame, break; data_unit_size = AV_RB32(buf+buf_idx+5); - if (buf_idx + data_unit_size > buf_size || !data_unit_size) { - if(buf_idx + data_unit_size > buf_size) + if (data_unit_size > buf_size - buf_idx || !data_unit_size) { + if(data_unit_size > buf_size - buf_idx) av_log(s->avctx, AV_LOG_ERROR, "Data unit with size %d is larger than input buffer, discarding\n", data_unit_size); diff --git a/libavcodec/dnxhddec.c b/libavcodec/dnxhddec.c index 06800746d1..a8cf0800aa 100644 --- a/libavcodec/dnxhddec.c +++ b/libavcodec/dnxhddec.c @@ -363,7 +363,7 @@ static int dnxhd_decode_macroblock(DNXHDContext *ctx, AVFrame *frame, dest_u = frame->data[1] + ((y * dct_linesize_chroma) << 4) + (x << (3 + shift1 + ctx->is_444)); dest_v = frame->data[2] + ((y * dct_linesize_chroma) << 4) + (x << (3 + shift1 + ctx->is_444)); - 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]; diff --git a/libavcodec/dpx.c b/libavcodec/dpx.c index 3b78486bb3..60f5107622 100644 --- a/libavcodec/dpx.c +++ b/libavcodec/dpx.c @@ -334,11 +334,11 @@ static int decode_frame(AVCodecContext *avctx, // For 12 bit, ignore alpha if (elements == 4) buf += 2; - // Jump to next aligned position - buf += need_align; } for (i = 0; i < 3; i++) ptr[i] += p->linesize[i]; + // Jump to next aligned position + buf += need_align; } break; case 16: diff --git a/libavcodec/dpxenc.c b/libavcodec/dpxenc.c index aca745bb58..76aa0cc473 100644 --- a/libavcodec/dpxenc.c +++ b/libavcodec/dpxenc.c @@ -75,17 +75,20 @@ static av_cold int encode_init(AVCodecContext *avctx) return 0; } -#define write16(p, value) \ -do { \ - if (s->big_endian) AV_WB16(p, value); \ - else AV_WL16(p, value); \ -} while(0) +static av_always_inline void write16_internal(int big_endian, void *p, int value) +{ + if (big_endian) AV_WB16(p, value); + else AV_WL16(p, value); +} -#define write32(p, value) \ -do { \ - if (s->big_endian) AV_WB32(p, value); \ - else AV_WL32(p, value); \ -} while(0) +static av_always_inline void write32_internal(int big_endian, void *p, int value) +{ + if (big_endian) AV_WB32(p, value); + else AV_WL32(p, value); +} + +#define write16(p, value) write16_internal(s->big_endian, p, value) +#define write32(p, value) write32_internal(s->big_endian, p, value) static void encode_rgb48_10bit(AVCodecContext *avctx, const AVPicture *pic, uint8_t *dst) { diff --git a/libavcodec/dvdec.c b/libavcodec/dvdec.c index 99fe1f4981..4728e429e9 100644 --- a/libavcodec/dvdec.c +++ b/libavcodec/dvdec.c @@ -333,7 +333,7 @@ static int dv_decode_video_segment(AVCodecContext *avctx, void *arg) dct_mode * 22 * 64 + (quant + ff_dv_quant_offset[class1]) * 64]; } - dc = dc << 2; + dc = dc * 4; /* convert to unsigned because 128 is not added in the * standard IDCT */ dc += 1024; diff --git a/libavcodec/dvdsubdec.c b/libavcodec/dvdsubdec.c index 39604f3ada..62c9348668 100644 --- a/libavcodec/dvdsubdec.c +++ b/libavcodec/dvdsubdec.c @@ -39,7 +39,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; int forced_subs_only; #ifdef DEBUG @@ -108,6 +108,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); @@ -340,7 +346,7 @@ static int decode_dvd_subtitles(DVDSubContext *ctx, AVSubtitle *sub_header, } } the_end: - if (offset1 >= 0) { + if (offset1 >= 0 && offset2 >= 0) { int w, h; uint8_t *bitmap; @@ -359,10 +365,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) @@ -501,15 +509,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; @@ -525,7 +529,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; @@ -567,7 +571,6 @@ static int dvdsub_decode(AVCodecContext *avctx, } #endif - av_freep(&ctx->buf); ctx->buf_size = 0; *data_size = 1; return buf_size; @@ -711,7 +714,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/dxtory.c b/libavcodec/dxtory.c index 4d8b7b29a6..2fa8b4fa8e 100644 --- a/libavcodec/dxtory.c +++ b/libavcodec/dxtory.c @@ -65,7 +65,7 @@ static int dxtory_decode_v1_410(AVCodecContext *avctx, AVFrame *pic, uint8_t *Y1, *Y2, *Y3, *Y4, *U, *V; int ret; - if (src_size < avctx->width * avctx->height * 9L / 8) { + if (src_size < FFALIGN(avctx->width, 4) * FFALIGN(avctx->height, 4) * 9LL / 8) { av_log(avctx, AV_LOG_ERROR, "packet too small\n"); return AVERROR_INVALIDDATA; } @@ -108,7 +108,7 @@ static int dxtory_decode_v1_420(AVCodecContext *avctx, AVFrame *pic, uint8_t *Y1, *Y2, *U, *V; int ret; - if (src_size < avctx->width * avctx->height * 3L / 2) { + if (src_size < FFALIGN(avctx->width, 2) * FFALIGN(avctx->height, 2) * 3LL / 2) { av_log(avctx, AV_LOG_ERROR, "packet too small\n"); return AVERROR_INVALIDDATA; } @@ -145,7 +145,7 @@ static int dxtory_decode_v1_444(AVCodecContext *avctx, AVFrame *pic, uint8_t *Y, *U, *V; int ret; - if (src_size < avctx->width * avctx->height * 3L) { + if (src_size < avctx->width * avctx->height * 3LL) { av_log(avctx, AV_LOG_ERROR, "packet too small\n"); return AVERROR_INVALIDDATA; } diff --git a/libavcodec/eac3dec.c b/libavcodec/eac3dec.c index 8e931fddeb..ef815afb55 100644 --- a/libavcodec/eac3dec.c +++ b/libavcodec/eac3dec.c @@ -63,7 +63,7 @@ typedef enum { #define EAC3_SR_CODE_REDUCED 3 -void ff_eac3_apply_spectral_extension(AC3DecodeContext *s) +static void ff_eac3_apply_spectral_extension(AC3DecodeContext *s) { int bin, bnd, ch, i; uint8_t wrapflag[SPX_MAX_BANDS]={1,0,}, num_copy_sections, copy_sizes[SPX_MAX_BANDS]; @@ -101,7 +101,7 @@ void ff_eac3_apply_spectral_extension(AC3DecodeContext *s) for (i = 0; i < num_copy_sections; i++) { memcpy(&s->transform_coeffs[ch][bin], &s->transform_coeffs[ch][s->spx_dst_start_freq], - copy_sizes[i]*sizeof(float)); + copy_sizes[i]*sizeof(INTFLOAT)); bin += copy_sizes[i]; } @@ -124,7 +124,7 @@ void ff_eac3_apply_spectral_extension(AC3DecodeContext *s) bin = s->spx_src_start_freq - 2; for (bnd = 0; bnd < s->num_spx_bands; bnd++) { if (wrapflag[bnd]) { - float *coeffs = &s->transform_coeffs[ch][bin]; + INTFLOAT *coeffs = &s->transform_coeffs[ch][bin]; coeffs[0] *= atten_tab[0]; coeffs[1] *= atten_tab[1]; coeffs[2] *= atten_tab[2]; @@ -142,6 +142,11 @@ void ff_eac3_apply_spectral_extension(AC3DecodeContext *s) for (bnd = 0; bnd < s->num_spx_bands; bnd++) { float nscale = s->spx_noise_blend[ch][bnd] * rms_energy[bnd] * (1.0f / INT32_MIN); float sscale = s->spx_signal_blend[ch][bnd]; +#if USE_FIXED + // spx_noise_blend and spx_signal_blend are both FP.23 + nscale *= 1.0 / (1<<23); + sscale *= 1.0 / (1<<23); +#endif for (i = 0; i < s->spx_band_sizes[bnd]; i++) { float noise = nscale * (int32_t)av_lfg_get(&s->dith_state); s->transform_coeffs[ch][bin] *= sscale; @@ -195,7 +200,7 @@ static void idct6(int pre_mant[6]) pre_mant[5] = even0 - odd0; } -void ff_eac3_decode_transform_coeffs_aht_ch(AC3DecodeContext *s, int ch) +static void ff_eac3_decode_transform_coeffs_aht_ch(AC3DecodeContext *s, int ch) { int bin, blk, gs; int end_bap, gaq_mode; @@ -288,7 +293,7 @@ void ff_eac3_decode_transform_coeffs_aht_ch(AC3DecodeContext *s, int ch) } } -int ff_eac3_parse_header(AC3DecodeContext *s) +static int ff_eac3_parse_header(AC3DecodeContext *s) { int i, blk, ch; int ac3_exponent_strategy, parse_aht_info, parse_spx_atten_data; diff --git a/libavcodec/eamad.c b/libavcodec/eamad.c index 813a2d1cdb..6b7134a98d 100644 --- a/libavcodec/eamad.c +++ b/libavcodec/eamad.c @@ -151,6 +151,11 @@ static inline int decode_block_intra(MadContext *s, int16_t * block) break; } else if (level != 0) { i += run; + if (i > 63) { + av_log(s->avctx, AV_LOG_ERROR, + "ac-tex damaged at %d %d\n", s->mb_x, s->mb_y); + return -1; + } j = scantable[i]; level = (level*quant_matrix[j]) >> 4; level = (level-1)|1; @@ -165,6 +170,11 @@ static inline int decode_block_intra(MadContext *s, int16_t * block) run = SHOW_UBITS(re, &s->gb, 6)+1; LAST_SKIP_BITS(re, &s->gb, 6); i += run; + if (i > 63) { + av_log(s->avctx, AV_LOG_ERROR, + "ac-tex damaged at %d %d\n", s->mb_x, s->mb_y); + return -1; + } j = scantable[i]; if (level < 0) { level = -level; @@ -176,10 +186,6 @@ static inline int decode_block_intra(MadContext *s, int16_t * block) level = (level-1)|1; } } - if (i > 63) { - av_log(s->avctx, AV_LOG_ERROR, "ac-tex damaged at %d %d\n", s->mb_x, s->mb_y); - return -1; - } block[j] = level; } diff --git a/libavcodec/error_resilience.c b/libavcodec/error_resilience.c index c72c562078..fb71a71df7 100644 --- a/libavcodec/error_resilience.c +++ b/libavcodec/error_resilience.c @@ -377,14 +377,19 @@ static void guess_mv(ERContext *s) #define MV_UNCHANGED 1 const int mb_stride = s->mb_stride; const int mb_width = s->mb_width; - const int mb_height = s->mb_height; + int mb_height = s->mb_height; int i, depth, num_avail; int mb_x, mb_y, mot_step, mot_stride; + if (s->last_pic.f && s->last_pic.f->data[0]) + mb_height = FFMIN(mb_height, (s->last_pic.f->height+15)>>4); + if (s->next_pic.f && s->next_pic.f->data[0]) + mb_height = FFMIN(mb_height, (s->next_pic.f->height+15)>>4); + set_mv_strides(s, &mot_step, &mot_stride); num_avail = 0; - for (i = 0; i < s->mb_num; i++) { + for (i = 0; i < mb_width * mb_height; i++) { const int mb_xy = s->mb_index2xy[i]; int f = 0; int error = s->error_status_table[mb_xy]; @@ -409,7 +414,7 @@ static void guess_mv(ERContext *s) if ((!(s->avctx->error_concealment&FF_EC_GUESS_MVS)) || num_avail <= mb_width / 2) { - for (mb_y = 0; mb_y < s->mb_height; mb_y++) { + for (mb_y = 0; mb_y < mb_height; mb_y++) { for (mb_x = 0; mb_x < s->mb_width; mb_x++) { const int mb_xy = mb_x + mb_y * s->mb_stride; int mv_dir = (s->last_pic.f && s->last_pic.f->data[0]) ? MV_DIR_FORWARD : MV_DIR_BACKWARD; @@ -438,7 +443,7 @@ static void guess_mv(ERContext *s) int score_sum = 0; changed = 0; - for (mb_y = 0; mb_y < s->mb_height; mb_y++) { + for (mb_y = 0; mb_y < mb_height; mb_y++) { for (mb_x = 0; mb_x < s->mb_width; mb_x++) { const int mb_xy = mb_x + mb_y * s->mb_stride; int mv_predictor[8][2] = { { 0 } }; @@ -671,7 +676,7 @@ skip_last_mv: if (none_left) return; - for (i = 0; i < s->mb_num; i++) { + for (i = 0; i < mb_width * mb_height; i++) { int mb_xy = s->mb_index2xy[i]; if (fixed[mb_xy]) fixed[mb_xy] = MV_FROZEN; diff --git a/libavcodec/exr.c b/libavcodec/exr.c index b56fe2e7f6..9088581b91 100644 --- a/libavcodec/exr.c +++ b/libavcodec/exr.c @@ -461,7 +461,7 @@ static int huf_build_dec_table(const uint64_t *hcode, int im, lc += 8; \ } -#define get_code(po, rlc, c, lc, gb, out, oe) \ +#define get_code(po, rlc, c, lc, gb, out, oe, outb) \ { \ if (po == rlc) { \ if (lc < 8) \ @@ -470,7 +470,7 @@ static int huf_build_dec_table(const uint64_t *hcode, int im, \ cs = c >> lc; \ \ - if (out + cs > oe) \ + if (out + cs > oe || out == outb) \ return AVERROR_INVALIDDATA; \ \ s = out[-1]; \ @@ -503,7 +503,7 @@ static int huf_decode(const uint64_t *hcode, const HufDec *hdecod, if (pl.len) { lc -= pl.len; - get_code(pl.lit, rlc, c, lc, gb, out, oe); + get_code(pl.lit, rlc, c, lc, gb, out, oe, outb); } else { int j; @@ -520,7 +520,7 @@ static int huf_decode(const uint64_t *hcode, const HufDec *hdecod, if ((hcode[pl.p[j]] >> 6) == ((c >> (lc - l)) & ((1LL << l) - 1))) { lc -= l; - get_code(pl.p[j], rlc, c, lc, gb, out, oe); + get_code(pl.p[j], rlc, c, lc, gb, out, oe, outb); break; } } @@ -541,7 +541,7 @@ static int huf_decode(const uint64_t *hcode, const HufDec *hdecod, if (pl.len) { lc -= pl.len; - get_code(pl.lit, rlc, c, lc, gb, out, oe); + get_code(pl.lit, rlc, c, lc, gb, out, oe, outb); } else { return AVERROR_INVALIDDATA; } @@ -1012,6 +1012,22 @@ static int decode_header(EXRContext *s) int current_channel_offset = 0; int magic_number, version, flags, i; + s->xmin = ~0; + s->xmax = ~0; + s->ymin = ~0; + s->ymax = ~0; + s->xdelta = ~0; + s->ydelta = ~0; + s->channel_offsets[0] = -1; + s->channel_offsets[1] = -1; + s->channel_offsets[2] = -1; + s->channel_offsets[3] = -1; + s->pixel_type = EXR_UNKNOWN; + s->compression = EXR_UNKN; + s->nb_channels = 0; + s->w = 0; + s->h = 0; + if (bytestream2_get_bytes_left(&s->gb) < 10) { av_log(s->avctx, AV_LOG_ERROR, "Header too short to parse.\n"); return AVERROR_INVALIDDATA; @@ -1352,21 +1368,6 @@ static av_cold int decode_init(AVCodecContext *avctx) float one_gamma = 1.0f / s->gamma; s->avctx = avctx; - s->xmin = ~0; - s->xmax = ~0; - s->ymin = ~0; - s->ymax = ~0; - s->xdelta = ~0; - s->ydelta = ~0; - s->channel_offsets[0] = -1; - s->channel_offsets[1] = -1; - s->channel_offsets[2] = -1; - s->channel_offsets[3] = -1; - s->pixel_type = EXR_UNKNOWN; - s->compression = EXR_UNKN; - s->nb_channels = 0; - s->w = 0; - s->h = 0; if ( one_gamma > 0.9999f && one_gamma < 1.0001f ) { for ( i = 0; i < 65536; ++i ) { diff --git a/libavcodec/faxcompr.c b/libavcodec/faxcompr.c index 155f78da66..ba7096d3b1 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 ab58a6074f..89c4e61d17 100644 --- a/libavcodec/ffv1.c +++ b/libavcodec/ffv1.c @@ -66,7 +66,7 @@ av_cold int ffv1_common_init(AVCodecContext *avctx) av_cold int ffv1_init_slice_state(FFV1Context *f, FFV1Context *fs) { - int j; + int j, i; fs->plane_count = f->plane_count; fs->transparency = f->transparency; @@ -80,10 +80,15 @@ av_cold int ffv1_init_slice_state(FFV1Context *f, FFV1Context *fs) if (!p->state) return AVERROR(ENOMEM); } else { - if (!p->vlc_state) - p->vlc_state = av_malloc_array(p->context_count, sizeof(VlcState)); - if (!p->vlc_state) - return AVERROR(ENOMEM); + if (!p->vlc_state) { + p->vlc_state = av_mallocz_array(p->context_count, sizeof(VlcState)); + if (!p->vlc_state) + return AVERROR(ENOMEM); + for (i = 0; i < p->context_count; i++) { + p->vlc_state[i].error_sum = 4; + p->vlc_state[i].count = 1; + } + } } } @@ -101,7 +106,7 @@ av_cold int ffv1_init_slice_state(FFV1Context *f, FFV1Context *fs) av_cold int ffv1_init_slices_state(FFV1Context *f) { int i, ret; - for (i = 0; i < f->slice_count; i++) { + for (i = 0; i < f->max_slice_count; i++) { FFV1Context *fs = f->slice_context[i]; if ((ret = ffv1_init_slice_state(f, fs)) < 0) return AVERROR(ENOMEM); @@ -113,10 +118,10 @@ av_cold int ffv1_init_slice_contexts(FFV1Context *f) { int i; - f->slice_count = f->num_h_slices * f->num_v_slices; - av_assert0(f->slice_count > 0); + f->max_slice_count = f->num_h_slices * f->num_v_slices; + av_assert0(f->max_slice_count > 0); - for (i = 0; i < f->slice_count; i++) { + for (i = 0; i < f->max_slice_count; i++) { FFV1Context *fs = av_mallocz(sizeof(*fs)); int sx = i % f->num_h_slices; int sy = i / f->num_h_slices; @@ -201,7 +206,7 @@ av_cold int ffv1_close(AVCodecContext *avctx) ff_thread_release_buffer(avctx, &s->last_picture); av_frame_free(&s->last_picture.f); - for (j = 0; j < s->slice_count; j++) { + for (j = 0; j < s->max_slice_count; j++) { FFV1Context *fs = s->slice_context[j]; for (i = 0; i < s->plane_count; i++) { PlaneContext *p = &fs->plane[i]; @@ -215,14 +220,14 @@ av_cold int ffv1_close(AVCodecContext *avctx) av_freep(&avctx->stats_out); for (j = 0; j < s->quant_table_count; j++) { av_freep(&s->initial_states[j]); - for (i = 0; i < s->slice_count; i++) { + for (i = 0; i < s->max_slice_count; i++) { FFV1Context *sf = s->slice_context[i]; av_freep(&sf->rc_stat2[j]); } av_freep(&s->rc_stat2[j]); } - for (i = 0; i < s->slice_count; i++) + for (i = 0; i < s->max_slice_count; i++) av_freep(&s->slice_context[i]); return 0; diff --git a/libavcodec/ffv1.h b/libavcodec/ffv1.h index 5081397f54..cc354c385e 100644 --- a/libavcodec/ffv1.h +++ b/libavcodec/ffv1.h @@ -117,6 +117,7 @@ typedef struct FFV1Context { struct FFV1Context *slice_context[MAX_SLICES]; int slice_count; + int max_slice_count; int num_v_slices; int num_h_slices; int slice_width; diff --git a/libavcodec/ffv1dec.c b/libavcodec/ffv1dec.c index 5fbe51c5a5..ebcb2b0d2b 100644 --- a/libavcodec/ffv1dec.c +++ b/libavcodec/ffv1dec.c @@ -47,8 +47,11 @@ static inline av_flatten int get_symbol_inline(RangeCoder *c, uint8_t *state, else { int i, e, a; e = 0; - while (get_rac(c, state + 1 + FFMIN(e, 9))) // 1..10 + while (get_rac(c, state + 1 + FFMIN(e, 9))) { // 1..10 e++; + if (e > 31) + return AVERROR_INVALIDDATA; + } a = 1; for (i = e - 1; i >= 0; i--) @@ -303,7 +306,7 @@ static int decode_slice_header(FFV1Context *f, FFV1Context *fs) for (i = 0; i < f->plane_count; i++) { PlaneContext * const p = &fs->plane[i]; int idx = get_symbol(c, state, 0); - if (idx > (unsigned)f->quant_table_count) { + if (idx >= (unsigned)f->quant_table_count) { av_log(f->avctx, AV_LOG_ERROR, "quant_table_index out of range\n"); return -1; } @@ -406,6 +409,7 @@ static int decode_slice(AVCodecContext *c, void *arg) if (ffv1_init_slice_state(f, fs) < 0) return AVERROR(ENOMEM); if (decode_slice_header(f, fs) < 0) { + fs->slice_x = fs->slice_y = fs->slice_height = fs->slice_width = 0; fs->slice_damaged = 1; return AVERROR_INVALIDDATA; } @@ -500,7 +504,10 @@ static int read_quant_tables(RangeCoder *c, int context_count = 1; for (i = 0; i < 5; i++) { - context_count *= read_quant_table(c, quant_table[i], context_count); + int ret = read_quant_table(c, quant_table[i], context_count); + if (ret < 0) + return ret; + context_count *= ret; if (context_count > 32768U) { return AVERROR_INVALIDDATA; } @@ -546,6 +553,12 @@ static int read_extra_header(FFV1Context *f) f->num_h_slices = 1 + get_symbol(c, state, 0); f->num_v_slices = 1 + get_symbol(c, state, 0); + if (f->chroma_h_shift > 4U || f->chroma_v_shift > 4U) { + av_log(f->avctx, AV_LOG_ERROR, "chroma shift parameters %d %d are invalid\n", + f->chroma_h_shift, f->chroma_v_shift); + return AVERROR_INVALIDDATA; + } + if (f->num_h_slices > (unsigned)f->width || !f->num_h_slices || f->num_v_slices > (unsigned)f->height || !f->num_v_slices ) { @@ -554,8 +567,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]); @@ -651,6 +667,12 @@ static int read_header(FFV1Context *f) } } + if (chroma_h_shift > 4U || chroma_v_shift > 4U) { + av_log(f->avctx, AV_LOG_ERROR, "chroma shift parameters %d %d are invalid\n", + chroma_h_shift, chroma_v_shift); + return AVERROR_INVALIDDATA; + } + f->colorspace = colorspace; f->avctx->bits_per_raw_sample = bits_per_raw_sample; f->chroma_planes = chroma_planes; @@ -758,6 +780,7 @@ static int read_header(FFV1Context *f) av_log(f->avctx, AV_LOG_ERROR, "read_quant_table error\n"); return AVERROR_INVALIDDATA; } + f->slice_count = f->max_slice_count; } else if (f->version < 3) { f->slice_count = get_symbol(c, state, 0); } else { @@ -772,8 +795,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; } @@ -915,6 +938,7 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame, AVPac else v = buf_p - c->bytestream_start; if (buf_p - c->bytestream_start < v) { av_log(avctx, AV_LOG_ERROR, "Slice pointer chain broken\n"); + ff_thread_report_progress(&f->picture, INT_MAX, 0); return AVERROR_INVALIDDATA; } buf_p -= v; @@ -996,6 +1020,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++) { @@ -1071,7 +1096,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 cf2a13dc6b..25b70d673e 100644 --- a/libavcodec/ffv1enc.c +++ b/libavcodec/ffv1enc.c @@ -961,6 +961,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; @@ -970,7 +971,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] * @@ -1194,6 +1195,7 @@ static int encode_frame(AVCodecContext *avctx, AVPacket *pkt, for (i = 0; i < f->quant_table_count; i++) memset(f->rc_stat2[i], 0, f->context_count[i] * sizeof(*f->rc_stat2[i])); + av_assert0(f->slice_count == f->max_slice_count); for (j = 0; j < f->slice_count; j++) { FFV1Context *fs = f->slice_context[j]; for (i = 0; i < 256; i++) { diff --git a/libavcodec/flac_parser.c b/libavcodec/flac_parser.c index 0e45ab0fed..b74be29a80 100644 --- a/libavcodec/flac_parser.c +++ b/libavcodec/flac_parser.c @@ -697,7 +697,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/flacenc.c b/libavcodec/flacenc.c index e66ef3db5e..5d3e002aa9 100644 --- a/libavcodec/flacenc.c +++ b/libavcodec/flacenc.c @@ -916,7 +916,7 @@ static int count_frame_header(FlacEncodeContext *s) count += 16; /* explicit sample rate */ - count += ((s->sr_code[0] == 12) + (s->sr_code[0] > 12)) * 8; + count += ((s->sr_code[0] == 12) + (s->sr_code[0] > 12) * 2) * 8; /* frame header CRC-8 */ count += 8; diff --git a/libavcodec/flashsv.c b/libavcodec/flashsv.c index 8791a2d750..f777f24e19 100644 --- a/libavcodec/flashsv.c +++ b/libavcodec/flashsv.c @@ -413,6 +413,10 @@ static int flashsv_decode_frame(AVCodecContext *avctx, void *data, } if (has_diff) { + if (size < 3) { + av_log(avctx, AV_LOG_ERROR, "size too small for diff\n"); + return AVERROR_INVALIDDATA; + } if (!s->keyframe) { av_log(avctx, AV_LOG_ERROR, "Inter frame without keyframe\n"); @@ -440,6 +444,10 @@ static int flashsv_decode_frame(AVCodecContext *avctx, void *data, int row = get_bits(&gb, 8); av_log(avctx, AV_LOG_DEBUG, "%dx%d zlibprime_curr %dx%d\n", i, j, col, row); + if (size < 3) { + av_log(avctx, AV_LOG_ERROR, "size too small for zlibprime_curr\n"); + return AVERROR_INVALIDDATA; + } size -= 2; avpriv_request_sample(avctx, "zlibprime_curr"); return AVERROR_PATCHWELCOME; diff --git a/libavcodec/flashsv2enc.c b/libavcodec/flashsv2enc.c index 1c016f2265..c7bb410f6f 100644 --- a/libavcodec/flashsv2enc.c +++ b/libavcodec/flashsv2enc.c @@ -287,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); diff --git a/libavcodec/flashsvenc.c b/libavcodec/flashsvenc.c index a6d7caa97b..2a6854750d 100644 --- a/libavcodec/flashsvenc.c +++ b/libavcodec/flashsvenc.c @@ -111,7 +111,7 @@ static av_cold int flashsv_encode_init(AVCodecContext *avctx) if (avctx->width > 4095 || avctx->height > 4095) { av_log(avctx, AV_LOG_ERROR, - "Input dimensions too large, input must be max 4096x4096 !\n"); + "Input dimensions too large, input must be max 4095x4095 !\n"); return AVERROR_INVALIDDATA; } @@ -151,7 +151,7 @@ static int encode_bitstream(FlashSVContext *s, const 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); diff --git a/libavcodec/g2meet.c b/libavcodec/g2meet.c index 0cd502bc08..83298d4a76 100644 --- a/libavcodec/g2meet.c +++ b/libavcodec/g2meet.c @@ -738,7 +738,7 @@ static int g2m_decode_frame(AVCodecContext *avctx, void *data, c->tile_height = bytestream2_get_be32(&bc); 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 + c->tile_width * (uint64_t)c->tile_height >= INT_MAX / 4 ) { av_log(avctx, AV_LOG_ERROR, "Invalid tile dimensions %dx%d\n", @@ -869,6 +869,8 @@ header_fail: c->height = 0; c->tiles_x = c->tiles_y = 0; + c->tile_width = + c->tile_height = 0; return ret; } diff --git a/libavcodec/gif.c b/libavcodec/gif.c index 27d054e512..b56d58c4df 100644 --- a/libavcodec/gif.c +++ b/libavcodec/gif.c @@ -43,6 +43,7 @@ typedef struct { const AVClass *class; LZWState *lzw; uint8_t *buf; + int buf_size; AVFrame *last_frame; int flags; uint32_t palette[AVPALETTE_COUNT]; ///< local reference palette for !pal8 @@ -105,7 +106,7 @@ static int gif_image_write_image(AVCodecContext *avctx, /* skip common columns */ while (x_start < x_end) { int same_column = 1; - for (y = y_start; y < y_end; y++) { + for (y = y_start; y <= y_end; y++) { if (ref[y*ref_linesize + x_start] != buf[y*linesize + x_start]) { same_column = 0; break; @@ -117,7 +118,7 @@ static int gif_image_write_image(AVCodecContext *avctx, } while (x_end > x_start) { int same_column = 1; - for (y = y_start; y < y_end; y++) { + for (y = y_start; y <= y_end; y++) { if (ref[y*ref_linesize + x_end] != buf[y*linesize + x_end]) { same_column = 0; break; @@ -168,7 +169,7 @@ static int gif_image_write_image(AVCodecContext *avctx, bytestream_put_byte(bytestream, 0x08); - ff_lzw_encode_init(s->lzw, s->buf, 2 * width * height, + ff_lzw_encode_init(s->lzw, s->buf, s->buf_size, 12, FF_LZW_GIF, put_bits); ptr = buf + y_start*linesize + x_start; @@ -224,7 +225,8 @@ static av_cold int gif_encode_init(AVCodecContext *avctx) 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->buf_size = avctx->width*avctx->height*2 + 1000; + s->buf = av_malloc(s->buf_size); s->tmpl = av_malloc(avctx->width); if (!s->tmpl || !s->buf || !s->lzw) return AVERROR(ENOMEM); @@ -283,6 +285,7 @@ static int gif_encode_close(AVCodecContext *avctx) av_freep(&s->lzw); av_freep(&s->buf); + s->buf_size = 0; av_frame_free(&s->last_frame); av_freep(&s->tmpl); return 0; diff --git a/libavcodec/golomb.h b/libavcodec/golomb.h index 81d8aeef9e..a65c17e326 100644 --- a/libavcodec/golomb.h +++ b/libavcodec/golomb.h @@ -346,8 +346,16 @@ static inline int get_ur_golomb_jpegls(GetBitContext *gb, int k, int limit, if (i < limit - 1) { if (k) { - buf = SHOW_UBITS(re, gb, k); - LAST_SKIP_BITS(re, gb, k); + if (k > MIN_CACHE_BITS - 1) { + buf = SHOW_UBITS(re, gb, 16) << (k-16); + LAST_SKIP_BITS(re, gb, 16); + UPDATE_CACHE(re, gb); + buf |= SHOW_UBITS(re, gb, k-16); + LAST_SKIP_BITS(re, gb, k-16); + } else { + buf = SHOW_UBITS(re, gb, k); + LAST_SKIP_BITS(re, gb, k); + } } else { buf = 0; } diff --git a/libavcodec/h264.c b/libavcodec/h264.c index 222bf58b10..ba3d910b62 100644 --- a/libavcodec/h264.c +++ b/libavcodec/h264.c @@ -391,6 +391,7 @@ void ff_h264_free_tables(H264Context *h, int free_rbsp) if (free_rbsp && h->DPB) { for (i = 0; i < H264_MAX_PICTURE_COUNT; i++) ff_h264_unref_picture(h, &h->DPB[i]); + memset(h->delayed_pic, 0, sizeof(h->delayed_pic)); av_freep(&h->DPB); } else if (h->DPB) { for (i = 0; i < H264_MAX_PICTURE_COUNT; i++) @@ -726,6 +727,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; @@ -990,6 +992,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; @@ -1504,9 +1516,6 @@ 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 */ @@ -1542,8 +1551,14 @@ again: ret = -1; goto end; } - if(!idr_cleared) + if(!idr_cleared) { + if (h->current_slice && (avctx->active_thread_type & FF_THREAD_SLICE)) { + av_log(h, AV_LOG_ERROR, "invalid mixed IDR / non IDR frames cannot be decoded in slice multithreading mode\n"); + ret = AVERROR_INVALIDDATA; + goto end; + } 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: @@ -1552,6 +1567,10 @@ again: hx->inter_gb_ptr = &hx->gb; hx->data_partitioning = 0; + if ( nals_needed >= nal_index + || (!(avctx->active_thread_type & FF_THREAD_FRAME) && !context_count)) + h->au_pps_id = -1; + if ((err = ff_h264_decode_slice_header(hx, h))) break; @@ -1673,7 +1692,9 @@ again: break; case NAL_SPS: init_get_bits(&h->gb, ptr, bit_length); - if (ff_h264_decode_seq_parameter_set(h) < 0 && (h->is_avc ? nalsize : 1)) { + if (ff_h264_decode_seq_parameter_set(h, 0) >= 0) + break; + if (h->is_avc ? nalsize : 1) { av_log(h->avctx, AV_LOG_DEBUG, "SPS decoding failure, trying again with the complete NAL\n"); if (h->is_avc) @@ -1682,8 +1703,11 @@ again: break; init_get_bits(&h->gb, &buf[buf_index + 1 - consumed], 8*(next_avc - buf_index + consumed - 1)); - ff_h264_decode_seq_parameter_set(h); + if (ff_h264_decode_seq_parameter_set(h, 0) >= 0) + break; } + init_get_bits(&h->gb, ptr, bit_length); + ff_h264_decode_seq_parameter_set(h, 1); break; case NAL_PPS: @@ -1716,8 +1740,14 @@ again: if (err < 0 || err == SLICE_SKIPED) { if (err < 0) av_log(h->avctx, AV_LOG_ERROR, "decode_slice_header error\n"); - h->ref_count[0] = h->ref_count[1] = h->list_count = 0; + hx->ref_count[0] = hx->ref_count[1] = hx->list_count = 0; } else if (err == SLICE_SINGLETHREAD) { + if (context_count > 1) { + ret = ff_h264_execute_decode_slices(h, context_count - 1); + if (ret < 0 && (h->avctx->err_recognition & AV_EF_EXPLODE)) + goto end; + context_count = 0; + } /* Slice could not be decoded in parallel mode, copy down * NAL unit stuff to context 0 and restart. Note that * rbsp_buffer is not transferred, but since we no longer @@ -1791,7 +1821,7 @@ static int is_extra(const uint8_t *buf, int buf_size) const uint8_t *p= buf+6; while(cnt--){ int nalsize= AV_RB16(p) + 2; - if(nalsize > buf_size - (p-buf) || p[2]!=0x67) + if(nalsize > buf_size - (p-buf) || (p[2] & 0x9F) != 7) return 0; p += nalsize; } @@ -1800,7 +1830,7 @@ static int is_extra(const uint8_t *buf, int buf_size) return 0; while(cnt--){ int nalsize= AV_RB16(p) + 2; - if(nalsize > buf_size - (p-buf) || p[2]!=0x68) + if(nalsize > buf_size - (p-buf) || (p[2] & 0x9F) != 8) return 0; p += nalsize; } diff --git a/libavcodec/h264.h b/libavcodec/h264.h index b94f06b6d1..2c975934a2 100644 --- a/libavcodec/h264.h +++ b/libavcodec/h264.h @@ -338,6 +338,7 @@ typedef struct H264Picture { * H264Context */ typedef struct H264Context { + AVClass *av_class; AVCodecContext *avctx; MECmpContext mecc; VideoDSPContext vdsp; @@ -538,6 +539,7 @@ typedef struct H264Context { int mb_x, mb_y; int resync_mb_x; int resync_mb_y; + int mb_index_end; int mb_skip_run; int mb_height, mb_width; int mb_stride; @@ -777,7 +779,7 @@ int ff_h264_decode_sei(H264Context *h); /** * Decode SPS */ -int ff_h264_decode_seq_parameter_set(H264Context *h); +int ff_h264_decode_seq_parameter_set(H264Context *h, int ignore_truncation); /** * compute profile from sps diff --git a/libavcodec/h264_cabac.c b/libavcodec/h264_cabac.c index 6455ee7b2d..1492d8d9d0 100644 --- a/libavcodec/h264_cabac.c +++ b/libavcodec/h264_cabac.c @@ -1282,7 +1282,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; @@ -2000,6 +2000,7 @@ decode_intra_mb: const int mb_size = ff_h264_mb_sizes[h->sps.chroma_format_idc] * h->sps.bit_depth_luma >> 3; const uint8_t *ptr; + int ret; // We assume these blocks are very rare so we do not optimize it. // FIXME The two following lines get the bitstream position in the cabac @@ -2016,7 +2017,9 @@ decode_intra_mb: h->intra_pcm_ptr = ptr; ptr += mb_size; - ff_init_cabac_decoder(&h->cabac, ptr, h->cabac.bytestream_end - ptr); + ret = ff_init_cabac_decoder(&h->cabac, ptr, h->cabac.bytestream_end - ptr); + if (ret < 0) + return ret; // All blocks are present h->cbp_table[mb_xy] = 0xf7ef; diff --git a/libavcodec/h264_mp4toannexb_bsf.c b/libavcodec/h264_mp4toannexb_bsf.c index ae96ee953d..2187264c2f 100644 --- a/libavcodec/h264_mp4toannexb_bsf.c +++ b/libavcodec/h264_mp4toannexb_bsf.c @@ -182,7 +182,7 @@ 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; if (unit_type == 7) diff --git a/libavcodec/h264_parser.c b/libavcodec/h264_parser.c index 6e87efabe8..0c4282add8 100644 --- a/libavcodec/h264_parser.c +++ b/libavcodec/h264_parser.c @@ -271,7 +271,7 @@ static inline int parse_nal_units(AVCodecParserContext *s, init_get_bits(&h->gb, ptr, 8 * dst_length); switch (h->nal_unit_type) { case NAL_SPS: - ff_h264_decode_seq_parameter_set(h); + ff_h264_decode_seq_parameter_set(h, 0); break; case NAL_PPS: ff_h264_decode_picture_parameter_set(h, h->gb.size_in_bits); diff --git a/libavcodec/h264_ps.c b/libavcodec/h264_ps.c index 4070490e46..fa4bc78d9d 100644 --- a/libavcodec/h264_ps.c +++ b/libavcodec/h264_ps.c @@ -241,12 +241,6 @@ static inline int decode_vui_parameters(H264Context *h, SPS *sps) } } - if (get_bits_left(&h->gb) < 0) { - av_log(h->avctx, AV_LOG_ERROR, - "Overread VUI by %d bits\n", -get_bits_left(&h->gb)); - return AVERROR_INVALIDDATA; - } - return 0; } @@ -303,7 +297,7 @@ static void decode_scaling_matrices(H264Context *h, SPS *sps, } } -int ff_h264_decode_seq_parameter_set(H264Context *h) +int ff_h264_decode_seq_parameter_set(H264Context *h, int ignore_truncation) { int profile_idc, level_idc, constraint_set_flags = 0; unsigned int sps_id; @@ -371,7 +365,8 @@ int ff_h264_decode_seq_parameter_set(H264Context *h) "Different chroma and luma bit depth"); goto fail; } - if (sps->bit_depth_luma > 14U || sps->bit_depth_chroma > 14U) { + if (sps->bit_depth_luma < 8 || sps->bit_depth_luma > 14 || + sps->bit_depth_chroma < 8 || sps->bit_depth_chroma > 14) { av_log(h->avctx, AV_LOG_ERROR, "illegal bit depth value (%d, %d)\n", sps->bit_depth_luma, sps->bit_depth_chroma); goto fail; @@ -522,6 +517,13 @@ int ff_h264_decode_seq_parameter_set(H264Context *h) goto fail; } + if (get_bits_left(&h->gb) < 0) { + av_log(h->avctx, ignore_truncation ? AV_LOG_WARNING : AV_LOG_ERROR, + "Overread %s by %d bits\n", sps->vui_parameters_present_flag ? "VUI" : "SPS", -get_bits_left(&h->gb)); + if (!ignore_truncation) + goto fail; + } + if (!sps->sar.den) sps->sar.den = 1; diff --git a/libavcodec/h264_refs.c b/libavcodec/h264_refs.c index 12da9210be..d0a902c06e 100644 --- a/libavcodec/h264_refs.c +++ b/libavcodec/h264_refs.c @@ -283,7 +283,7 @@ int ff_h264_decode_ref_pic_list_reordering(H264Context *h) long_idx = pic_num_extract(h, pic_id, &pic_structure); - if (long_idx > 31) { + if (long_idx > 31U) { av_log(h->avctx, AV_LOG_ERROR, "long_term_pic_idx overflow\n"); return AVERROR_INVALIDDATA; @@ -707,7 +707,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 " diff --git a/libavcodec/h264_slice.c b/libavcodec/h264_slice.c index 53f61caa7d..b24978a95a 100644 --- a/libavcodec/h264_slice.c +++ b/libavcodec/h264_slice.c @@ -278,11 +278,11 @@ static int alloc_picture(H264Context *h, H264Picture *pic) 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++) { + for(i=0; if.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)); + 0x80, FF_CEIL_RSHIFT(pic->f.width, h_chroma_shift)); memset(pic->f.data[2] + pic->f.linesize[2]*i, - 0x80, FF_CEIL_RSHIFT(h->avctx->width, h_chroma_shift)); + 0x80, FF_CEIL_RSHIFT(pic->f.width, h_chroma_shift)); } } @@ -924,7 +924,7 @@ static void implicit_weight_table(H264Context *h, int field) cur_poc = h->cur_pic_ptr->field_poc[h->picture_structure - 1]; } if (h->ref_count[0] == 1 && h->ref_count[1] == 1 && !FRAME_MBAFF(h) && - h->ref_list[0][0].poc + h->ref_list[1][0].poc == 2 * cur_poc) { + h->ref_list[0][0].poc + (int64_t)h->ref_list[1][0].poc == 2 * cur_poc) { h->use_weight = 0; h->use_weight_chroma = 0; return; @@ -945,7 +945,7 @@ static void implicit_weight_table(H264Context *h, int field) h->chroma_log2_weight_denom = 5; for (ref0 = ref_start; ref0 < ref_count0; ref0++) { - int poc0 = h->ref_list[0][ref0].poc; + int64_t poc0 = h->ref_list[0][ref0].poc; for (ref1 = ref_start; ref1 < ref_count1; ref1++) { int w = 32; if (!h->ref_list[0][ref0].long_ref && !h->ref_list[1][ref1].long_ref) { @@ -1208,6 +1208,7 @@ static int h264_slice_header_init(H264Context *h, int reinit) nb_slices = max_slices; } h->slice_context_count = nb_slices; + h->max_contexts = FFMIN(h->max_contexts, nb_slices); if (!HAVE_THREADS || !(h->avctx->active_thread_type & FF_THREAD_SLICE)) { ret = ff_h264_context_init(h); @@ -1305,6 +1306,10 @@ int ff_h264_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; + int mb_aff_frame, last_mb_aff_frame; + PPS *pps; h->qpel_put = h->h264qpel.put_h264_qpel_pixels_tab; h->qpel_avg = h->h264qpel.avg_h264_qpel_pixels_tab; @@ -1378,18 +1383,27 @@ int ff_h264_decode_slice_header(H264Context *h, H264Context *h0) h0->au_pps_id, pps_id); return AVERROR_INVALIDDATA; } - h->pps = *h0->pps_buffers[pps_id]; - 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->sps.sps_id || - h->pps.sps_id != h->current_sps_id || - h0->sps_buffers[h->pps.sps_id]->new) { + if (pps->sps_id != h->sps.sps_id || + 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->sps = *h0->sps_buffers[h->pps.sps_id]; @@ -1419,11 +1433,14 @@ int ff_h264_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 (non_j_pixfmt(h0->avctx->pix_fmt) != non_j_pixfmt(get_pixel_format(h0, 0))) + if (h0->avctx->pix_fmt == AV_PIX_FMT_NONE + || (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; @@ -1456,6 +1473,7 @@ int ff_h264_decode_slice_header(H264Context *h, H264Context *h0) if (h->context_initialized && (must_reinit || needs_reinit)) { + h->context_initialized = 0; if (h != h0) { av_log(h->avctx, AV_LOG_ERROR, "changing width %d -> %d / height %d -> %d on " @@ -1466,6 +1484,8 @@ int ff_h264_decode_slice_header(H264Context *h, H264Context *h0) return AVERROR_INVALIDDATA; } + av_assert1(first_slice); + ff_h264_flush_change(h); if ((ret = get_pixel_format(h, 1)) < 0) @@ -1499,44 +1519,50 @@ int ff_h264_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; h264_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; + mb_aff_frame = 0; + last_mb_aff_frame = h0->mb_aff_frame; 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; - h->mb_aff_frame = h->sps.mb_aff; + picture_structure = PICT_FRAME; + 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 || + last_mb_aff_frame != mb_aff_frame) { 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, @@ -1544,7 +1570,15 @@ int ff_h264_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_aff_frame = mb_aff_frame; + 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) { @@ -1654,14 +1688,17 @@ int ff_h264_decode_slice_header(H264Context *h, H264Context *h0) * vectors. Given we are concealing a lost frame, this probably * is not noticeable by comparison, but it should be fixed. */ if (h->short_ref_count) { - if (prev) { + if (prev && + h->short_ref[0]->f.width == prev->f.width && + h->short_ref[0]->f.height == prev->f.height && + h->short_ref[0]->f.format == prev->f.format) { av_image_copy(h->short_ref[0]->f.data, h->short_ref[0]->f.linesize, (const uint8_t **)prev->f.data, prev->f.linesize, - h->avctx->pix_fmt, - h->mb_width * 16, - h->mb_height * 16); + prev->f.format, + prev->f.width, + prev->f.height); h->short_ref[0]->poc = prev->poc + 2; } h->short_ref[0]->frame_num = h->prev_frame_num; @@ -2405,20 +2442,32 @@ static int decode_slice(struct AVCodecContext *avctx, void *arg) } if (h->pps.cabac) { + int ret; /* realign */ align_get_bits(&h->gb); /* init cabac */ - ff_init_cabac_decoder(&h->cabac, + ret = ff_init_cabac_decoder(&h->cabac, h->gb.buffer + get_bits_count(&h->gb) / 8, (get_bits_left(&h->gb) + 7) / 8); + if (ret < 0) + return ret; ff_h264_init_cabac_states(h); for (;;) { // START_TIMER - int ret = ff_h264_decode_mb_cabac(h); - int eos; + int ret, eos; + + if (h->mb_x + h->mb_y * h->mb_width >= h->mb_index_end) { + av_log(h->avctx, AV_LOG_ERROR, "Slice overlaps next at %d\n", + h->mb_index_end); + er_add_slice(h, h->resync_mb_x, h->resync_mb_y, h->mb_x, + h->mb_y, ER_MB_ERROR); + return AVERROR_INVALIDDATA; + } + + ret = ff_h264_decode_mb_cabac(h); // STOP_TIMER("decode_mb_cabac") if (ret >= 0) @@ -2480,7 +2529,17 @@ static int decode_slice(struct AVCodecContext *avctx, void *arg) } } else { for (;;) { - int ret = ff_h264_decode_mb_cavlc(h); + int ret; + + if (h->mb_x + h->mb_y * h->mb_width >= h->mb_index_end) { + av_log(h->avctx, AV_LOG_ERROR, "Slice overlaps next at %d\n", + h->mb_index_end); + er_add_slice(h, h->resync_mb_x, h->resync_mb_y, h->mb_x, + h->mb_y, ER_MB_ERROR); + return AVERROR_INVALIDDATA; + } + + ret = ff_h264_decode_mb_cavlc(h); if (ret >= 0) ff_h264_hl_decode_mb(h); @@ -2568,19 +2627,33 @@ int ff_h264_execute_decode_slices(H264Context *h, unsigned context_count) av_assert0(h->mb_y < h->mb_height); + h->mb_index_end = INT_MAX; + if (h->avctx->hwaccel || h->avctx->codec->capabilities & CODEC_CAP_HWACCEL_VDPAU) return 0; if (context_count == 1) { return decode_slice(avctx, &h); } else { + int j, mb_index; av_assert0(context_count > 0); - for (i = 1; i < context_count; i++) { + for (i = 0; i < context_count; i++) { + int mb_index_end = h->mb_width * h->mb_height; hx = h->thread_context[i]; - if (CONFIG_ERROR_RESILIENCE) { + mb_index = hx->resync_mb_x + hx->resync_mb_y * h->mb_width; + if (CONFIG_ERROR_RESILIENCE && i) { hx->er.error_count = 0; } hx->x264_build = h->x264_build; + for (j = 0; j < context_count; j++) { + H264Context *sl2 = h->thread_context[j]; + int mb_index2 = sl2->resync_mb_x + sl2->resync_mb_y * h->mb_width; + + if (i==j || mb_index > mb_index2) + continue; + mb_index_end = FFMIN(mb_index_end, mb_index2); + } + hx->mb_index_end = mb_index_end; } avctx->execute(avctx, decode_slice, h->thread_context, diff --git a/libavcodec/hevc.c b/libavcodec/hevc.c index d4dc52c9dd..5735e68351 100644 --- a/libavcodec/hevc.c +++ b/libavcodec/hevc.c @@ -108,7 +108,7 @@ static int pic_arrays_init(HEVCContext *s, const HEVCSPS *sps) if (!s->tab_ipm || !s->cbf_luma || !s->is_pcm) goto fail; - s->filter_slice_edges = av_malloc(ctb_count); + s->filter_slice_edges = av_mallocz(ctb_count); s->tab_slice_address = av_malloc_array(pic_size_in_ctb, sizeof(*s->tab_slice_address)); s->qp_y_tab = av_malloc_array(pic_size_in_ctb, @@ -144,7 +144,7 @@ static void pred_weight_table(HEVCContext *s, GetBitContext *gb) uint8_t luma_weight_l1_flag[16]; uint8_t chroma_weight_l1_flag[16]; - s->sh.luma_log2_weight_denom = get_ue_golomb_long(gb); + s->sh.luma_log2_weight_denom = av_clip_c(get_ue_golomb_long(gb), 0, 7); if (s->sps->chroma_format_idc != 0) { int delta = get_se_golomb(gb); s->sh.chroma_log2_weight_denom = av_clip(s->sh.luma_log2_weight_denom + delta, 0, 7); @@ -674,15 +674,29 @@ static int hls_slice_header(HEVCContext *s) sh->num_entry_point_offsets = 0; if (s->pps->tiles_enabled_flag || s->pps->entropy_coding_sync_enabled_flag) { - sh->num_entry_point_offsets = get_ue_golomb_long(gb); + unsigned num_entry_point_offsets = get_ue_golomb_long(gb); + // It would be possible to bound this tighter but this here is simpler + if (num_entry_point_offsets > get_bits_left(gb)) { + av_log(s->avctx, AV_LOG_ERROR, "num_entry_point_offsets %d is invalid\n", num_entry_point_offsets); + return AVERROR_INVALIDDATA; + } + + sh->num_entry_point_offsets = num_entry_point_offsets; if (sh->num_entry_point_offsets > 0) { int offset_len = get_ue_golomb_long(gb) + 1; int segments = offset_len >> 4; int rest = (offset_len & 15); + + if (offset_len < 1 || offset_len > 32) { + sh->num_entry_point_offsets = 0; + av_log(s->avctx, AV_LOG_ERROR, "offset_len %d is invalid\n", offset_len); + return AVERROR_INVALIDDATA; + } + av_freep(&sh->entry_point_offset); av_freep(&sh->offset); av_freep(&sh->size); - sh->entry_point_offset = av_malloc_array(sh->num_entry_point_offsets, sizeof(int)); + sh->entry_point_offset = av_malloc_array(sh->num_entry_point_offsets, sizeof(unsigned)); 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) { @@ -755,6 +769,8 @@ static int hls_slice_header(HEVCContext *s) s->HEVClc->tu.cu_qp_offset_cb = 0; s->HEVClc->tu.cu_qp_offset_cr = 0; + s->no_rasl_output_flag = IS_IDR(s) || IS_BLA(s) || (s->nal_unit_type == NAL_CRA_NUT && s->last_eos); + return 0; } @@ -2336,6 +2352,8 @@ static int hls_decode_entry_wpp(AVCodecContext *avctxt, void *input_ctb_row, int if (more_data < 0) { s->tab_slice_address[ctb_addr_rs] = -1; + avpriv_atomic_int_set(&s1->wpp_err, 1); + ff_thread_report_progress2(s->avctx, ctb_row ,thread, SHIFT_CTB_WPP); return more_data; } @@ -2373,15 +2391,22 @@ static int hls_slice_data_wpp(HEVCContext *s, const uint8_t *nal, int length) HEVCLocalContext *lc = s->HEVClc; 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; + int64_t offset; + int64_t startheader, cmpt = 0; int i, j, res = 0; + if (s->sh.slice_ctb_addr_rs + s->sh.num_entry_point_offsets * s->sps->ctb_width >= s->sps->ctb_width * s->sps->ctb_height) { + av_log(s->avctx, AV_LOG_ERROR, "WPP ctb addresses are wrong (%d %d %d %d)\n", + s->sh.slice_ctb_addr_rs, s->sh.num_entry_point_offsets, + s->sps->ctb_width, s->sps->ctb_height + ); + res = AVERROR_INVALIDDATA; + goto error; + } + + ff_alloc_entries(s->avctx, s->sh.num_entry_point_offsets + 1); if (!s->sList[1]) { - ff_alloc_entries(s->avctx, s->sh.num_entry_point_offsets + 1); - - for (i = 1; i < s->threads_number; i++) { s->sList[i] = av_malloc(sizeof(HEVCContext)); memcpy(s->sList[i], s, sizeof(HEVCContext)); @@ -2414,6 +2439,11 @@ static int hls_slice_data_wpp(HEVCContext *s, const uint8_t *nal, int length) } if (s->sh.num_entry_point_offsets != 0) { offset += s->sh.entry_point_offset[s->sh.num_entry_point_offsets - 1] - cmpt; + if (length < offset) { + av_log(s->avctx, AV_LOG_ERROR, "entry_point_offset table is corrupted\n"); + res = AVERROR_INVALIDDATA; + goto error; + } s->sh.size[s->sh.num_entry_point_offsets - 1] = length - offset; s->sh.offset[s->sh.num_entry_point_offsets - 1] = offset; @@ -2440,6 +2470,7 @@ static int hls_slice_data_wpp(HEVCContext *s, const uint8_t *nal, int length) for (i = 0; i <= s->sh.num_entry_point_offsets; i++) res += ret[i]; +error: av_free(ret); av_free(arg); return res; @@ -2870,17 +2901,30 @@ static int decode_nal_units(HEVCContext *s, const uint8_t *buf, int length) if (s->nals_allocated < s->nb_nals + 1) { int new_size = s->nals_allocated + 1; - HEVCNAL *tmp = av_realloc_array(s->nals, new_size, sizeof(*tmp)); + void *tmp = av_realloc_array(s->nals, new_size, sizeof(*s->nals)); + ret = AVERROR(ENOMEM); if (!tmp) { - ret = AVERROR(ENOMEM); goto fail; } s->nals = tmp; memset(s->nals + s->nals_allocated, 0, - (new_size - s->nals_allocated) * sizeof(*tmp)); - av_reallocp_array(&s->skipped_bytes_nal, new_size, sizeof(*s->skipped_bytes_nal)); - av_reallocp_array(&s->skipped_bytes_pos_size_nal, new_size, sizeof(*s->skipped_bytes_pos_size_nal)); - av_reallocp_array(&s->skipped_bytes_pos_nal, new_size, sizeof(*s->skipped_bytes_pos_nal)); + (new_size - s->nals_allocated) * sizeof(*s->nals)); + + tmp = av_realloc_array(s->skipped_bytes_nal, new_size, sizeof(*s->skipped_bytes_nal)); + if (!tmp) + goto fail; + s->skipped_bytes_nal = tmp; + + tmp = av_realloc_array(s->skipped_bytes_pos_size_nal, new_size, sizeof(*s->skipped_bytes_pos_size_nal)); + if (!tmp) + goto fail; + s->skipped_bytes_pos_size_nal = tmp; + + tmp = av_realloc_array(s->skipped_bytes_pos_nal, new_size, sizeof(*s->skipped_bytes_pos_nal)); + if (!tmp) + goto fail; + s->skipped_bytes_pos_nal = tmp; + s->skipped_bytes_pos_size_nal[s->nals_allocated] = 1024; // initial buffer size s->skipped_bytes_pos_nal[s->nals_allocated] = av_malloc_array(s->skipped_bytes_pos_size_nal[s->nals_allocated], sizeof(*s->skipped_bytes_pos)); s->nals_allocated = new_size; @@ -2916,7 +2960,6 @@ static int decode_nal_units(HEVCContext *s, const uint8_t *buf, int length) /* parse the NAL units */ for (i = 0; i < s->nb_nals; i++) { - int ret; s->skipped_bytes = s->skipped_bytes_nal[i]; s->skipped_bytes_pos = s->skipped_bytes_pos_nal[i]; @@ -3264,6 +3307,7 @@ static int hevc_update_thread_context(AVCodecContext *dst, s->pocTid0 = s0->pocTid0; s->max_ra = s0->max_ra; s->eos = s0->eos; + s->no_rasl_output_flag = s0->no_rasl_output_flag; s->is_nalff = s0->is_nalff; s->nal_length_size = s0->nal_length_size; @@ -3358,6 +3402,7 @@ static av_cold int hevc_decode_init(AVCodecContext *avctx) s->enable_parallel_tiles = 0; s->picture_struct = 0; + s->eos = 1; if(avctx->active_thread_type & FF_THREAD_SLICE) s->threads_number = avctx->thread_count; @@ -3399,6 +3444,7 @@ static void hevc_decode_flush(AVCodecContext *avctx) HEVCContext *s = avctx->priv_data; ff_hevc_flush_dpb(s); s->max_ra = INT_MAX; + s->eos = 1; } #define OFFSET(x) offsetof(HEVCContext, x) diff --git a/libavcodec/hevc.h b/libavcodec/hevc.h index 8fdefbbdcf..40beb52884 100644 --- a/libavcodec/hevc.h +++ b/libavcodec/hevc.h @@ -298,10 +298,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 { @@ -607,7 +607,7 @@ typedef struct SliceHeader { unsigned int max_num_merge_cand; ///< 5 - 5_minus_max_num_merge_cand - int *entry_point_offset; + unsigned *entry_point_offset; int * offset; int * size; int num_entry_point_offsets; @@ -835,6 +835,7 @@ typedef struct HEVCContext { int bs_height; int is_decoded; + int no_rasl_output_flag; HEVCPredContext hpc; HEVCDSPContext hevcdsp; diff --git a/libavcodec/hevc_cabac.c b/libavcodec/hevc_cabac.c index 3862df7bdf..9fe99da8f5 100644 --- a/libavcodec/hevc_cabac.c +++ b/libavcodec/hevc_cabac.c @@ -883,11 +883,13 @@ static av_always_inline int mvd_decode(HEVCContext *s) int k = 1; while (k < CABAC_MAX_BIN && get_cabac_bypass(&s->HEVClc->cc)) { - ret += 1 << k; + ret += 1U << k; k++; } - if (k == CABAC_MAX_BIN) + if (k == CABAC_MAX_BIN) { av_log(s->avctx, AV_LOG_ERROR, "CABAC_MAX_BIN : %d\n", k); + return 0; + } while (k--) ret += get_cabac_bypass(&s->HEVClc->cc) << k; return get_cabac_bypass_sign(&s->HEVClc->cc, -ret); @@ -1025,8 +1027,10 @@ static av_always_inline int coeff_abs_level_remaining_decode(HEVCContext *s, int while (prefix < CABAC_MAX_BIN && get_cabac_bypass(&s->HEVClc->cc)) prefix++; - if (prefix == CABAC_MAX_BIN) + if (prefix == CABAC_MAX_BIN) { av_log(s->avctx, AV_LOG_ERROR, "CABAC_MAX_BIN : %d\n", prefix); + return 0; + } if (prefix < 3) { for (i = 0; i < rc_rice_param; i++) suffix = (suffix << 1) | get_cabac_bypass(&s->HEVClc->cc); diff --git a/libavcodec/hevc_ps.c b/libavcodec/hevc_ps.c index 6b5e13fc5b..5f5bad224f 100644 --- a/libavcodec/hevc_ps.c +++ b/libavcodec/hevc_ps.c @@ -424,7 +424,8 @@ int ff_hevc_decode_nal_vps(HEVCContext *s) vps->vps_max_layer_id = get_bits(gb, 6); vps->vps_num_layer_sets = get_ue_golomb_long(gb) + 1; - if ((vps->vps_num_layer_sets - 1LL) * (vps->vps_max_layer_id + 1LL) > get_bits_left(gb)) { + if (vps->vps_num_layer_sets < 1 || vps->vps_num_layer_sets > 1024 || + (vps->vps_num_layer_sets - 1LL) * (vps->vps_max_layer_id + 1LL) > get_bits_left(gb)) { av_log(s->avctx, AV_LOG_ERROR, "too many layer_id_included_flags\n"); goto err; } @@ -441,6 +442,11 @@ int ff_hevc_decode_nal_vps(HEVCContext *s) if (vps->vps_poc_proportional_to_timing_flag) vps->vps_num_ticks_poc_diff_one = get_ue_golomb_long(gb) + 1; vps->vps_num_hrd_parameters = get_ue_golomb_long(gb); + if (vps->vps_num_hrd_parameters > (unsigned)vps->vps_num_layer_sets) { + av_log(s->avctx, AV_LOG_ERROR, + "vps_num_hrd_parameters %d is invalid\n", vps->vps_num_hrd_parameters); + goto err; + } for (i = 0; i < vps->vps_num_hrd_parameters; i++) { int common_inf_present = 1; @@ -455,7 +461,8 @@ int ff_hevc_decode_nal_vps(HEVCContext *s) if (get_bits_left(gb) < 0) { av_log(s->avctx, AV_LOG_ERROR, "Overread VPS by %d bits\n", -get_bits_left(gb)); - goto err; + if (s->vps_list[vps_id]) + goto err; } av_buffer_unref(&s->vps_list[vps_id]); @@ -895,11 +902,30 @@ int ff_hevc_decode_nal_sps(HEVCContext *s) 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); @@ -1021,7 +1047,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) { @@ -1255,6 +1282,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", @@ -1281,14 +1316,14 @@ int ff_hevc_decode_nal_pps(HEVCContext *s) if (pps->tiles_enabled_flag) { pps->num_tile_columns = get_ue_golomb_long(gb) + 1; pps->num_tile_rows = get_ue_golomb_long(gb) + 1; - if (pps->num_tile_columns == 0 || + if (pps->num_tile_columns <= 0 || pps->num_tile_columns >= sps->width) { av_log(s->avctx, AV_LOG_ERROR, "num_tile_columns_minus1 out of range: %d\n", pps->num_tile_columns - 1); ret = AVERROR_INVALIDDATA; goto err; } - if (pps->num_tile_rows == 0 || + if (pps->num_tile_rows <= 0 || pps->num_tile_rows >= sps->height) { av_log(s->avctx, AV_LOG_ERROR, "num_tile_rows_minus1 out of range: %d\n", pps->num_tile_rows - 1); diff --git a/libavcodec/hevc_refs.c b/libavcodec/hevc_refs.c index b3a97871d5..dc35d3591a 100644 --- a/libavcodec/hevc_refs.c +++ b/libavcodec/hevc_refs.c @@ -158,7 +158,7 @@ int ff_hevc_output_frame(HEVCContext *s, AVFrame *out, int flush) int min_poc = INT_MAX; int i, min_idx, ret; - if (s->sh.no_output_of_prior_pics_flag == 1) { + if (s->sh.no_output_of_prior_pics_flag == 1 && s->no_rasl_output_flag == 1) { for (i = 0; i < FF_ARRAY_ELEMS(s->DPB); i++) { HEVCFrame *frame = &s->DPB[i]; if (!(frame->flags & HEVC_FRAME_FLAG_BUMPING) && frame->poc != s->poc && diff --git a/libavcodec/hevc_sei.c b/libavcodec/hevc_sei.c index 5bb5c9010a..13ebcd3ede 100644 --- a/libavcodec/hevc_sei.c +++ b/libavcodec/hevc_sei.c @@ -126,6 +126,11 @@ static int active_parameter_sets(HEVCContext *s) get_bits(gb, 1); // num_sps_ids_minus1 num_sps_ids_minus1 = get_ue_golomb_long(gb); // num_sps_ids_minus1 + if (num_sps_ids_minus1 < 0 || num_sps_ids_minus1 > 15) { + av_log(s->avctx, AV_LOG_ERROR, "num_sps_ids_minus1 %d invalid\n", num_sps_ids_minus1); + return AVERROR_INVALIDDATA; + } + active_seq_parameter_set_id = get_ue_golomb_long(gb); if (active_seq_parameter_set_id >= MAX_SPS_COUNT) { av_log(s->avctx, AV_LOG_ERROR, "active_parameter_set_id %d invalid\n", active_seq_parameter_set_id); diff --git a/libavcodec/huffyuvdec.c b/libavcodec/huffyuvdec.c index 98c6128470..a99ac71a89 100644 --- a/libavcodec/huffyuvdec.c +++ b/libavcodec/huffyuvdec.c @@ -37,6 +37,7 @@ #include "huffyuv.h" #include "huffyuvdsp.h" #include "thread.h" +#include "libavutil/imgutils.h" #include "libavutil/pixdesc.h" #define classic_shift_luma_table_size 42 @@ -291,6 +292,10 @@ static av_cold int decode_init(AVCodecContext *avctx) HYuvContext *s = avctx->priv_data; int ret; + ret = av_image_check_size(avctx->width, avctx->height, 0, avctx); + if (ret < 0) + return ret; + ff_huffyuvdsp_init(&s->hdsp); memset(s->vlc, 0, 4 * sizeof(VLC)); diff --git a/libavcodec/imc.c b/libavcodec/imc.c index 6c9ffd7980..422d834a4e 100644 --- a/libavcodec/imc.c +++ b/libavcodec/imc.c @@ -426,7 +426,7 @@ static void imc_decode_level_coefficients_raw(IMCContext *q, int *levlCoeffBuf, pos = q->coef0_pos; flcoeffs1[pos] = 20000.0 / pow (2, levlCoeffBuf[0] * 0.18945); // 0.18945 = log2(10) * 0.05703125 - flcoeffs2[pos] = log2f(flcoeffs1[0]); + flcoeffs2[pos] = log2f(flcoeffs1[pos]); tmp = flcoeffs1[pos]; tmp2 = flcoeffs2[pos]; diff --git a/libavcodec/imgconvert.c b/libavcodec/imgconvert.c index 158bc739a1..c6e52b381a 100644 --- a/libavcodec/imgconvert.c +++ b/libavcodec/imgconvert.c @@ -236,9 +236,41 @@ int av_picture_pad(AVPicture *dst, const AVPicture *src, int height, int width, int x_shift; int yheight; int i, y; + int max_step[4]; - if (pix_fmt < 0 || pix_fmt >= AV_PIX_FMT_NB || - !is_yuv_planar(desc)) return -1; + if (pix_fmt < 0 || pix_fmt >= AV_PIX_FMT_NB) + return -1; + + if (!is_yuv_planar(desc)) { + if (src) + return -1; //TODO: Not yet implemented + + av_image_fill_max_pixsteps(max_step, NULL, desc); + + if (padtop || padleft) { + memset(dst->data[0], color[0], + dst->linesize[0] * padtop + (padleft * max_step[0])); + } + + if (padleft || padright) { + optr = dst->data[0] + dst->linesize[0] * padtop + + (dst->linesize[0] - (padright * max_step[0])); + yheight = height - 1 - (padtop + padbottom); + for (y = 0; y < yheight; y++) { + memset(optr, color[0], (padleft + padright) * max_step[0]); + optr += dst->linesize[0]; + } + } + + if (padbottom || padright) { + optr = dst->data[0] + dst->linesize[0] * (height - padbottom) - + (padright * max_step[0]); + memset(optr, color[0], dst->linesize[0] * padbottom + + (padright * max_step[0])); + } + + return 0; + } for (i = 0; i < 3; i++) { x_shift = i ? desc->log2_chroma_w : 0; @@ -284,6 +316,7 @@ int av_picture_pad(AVPicture *dst, const AVPicture *src, int height, int width, (padbottom >> y_shift) + (padright >> x_shift)); } } + return 0; } diff --git a/libavcodec/indeo2.c b/libavcodec/indeo2.c index 39735c2e4b..b2656686a2 100644 --- a/libavcodec/indeo2.c +++ b/libavcodec/indeo2.c @@ -146,6 +146,7 @@ static int ir2_decode_frame(AVCodecContext *avctx, AVFrame *picture = data; AVFrame * const p = s->picture; int start, ret; + int ltab, ctab; if ((ret = ff_reget_buffer(avctx, p)) < 0) return ret; @@ -167,34 +168,36 @@ static int ir2_decode_frame(AVCodecContext *avctx, init_get_bits(&s->gb, buf + start, (buf_size - start) * 8); + ltab = buf[0x22] & 3; + ctab = buf[0x22] >> 2; if (s->decode_delta) { /* intraframe */ if ((ret = ir2_decode_plane(s, avctx->width, avctx->height, p->data[0], p->linesize[0], - ir2_luma_table)) < 0) + ir2_delta_table[ltab])) < 0) return ret; /* swapped U and V */ if ((ret = ir2_decode_plane(s, avctx->width >> 2, avctx->height >> 2, p->data[2], p->linesize[2], - ir2_luma_table)) < 0) + ir2_delta_table[ctab])) < 0) return ret; if ((ret = ir2_decode_plane(s, avctx->width >> 2, avctx->height >> 2, p->data[1], p->linesize[1], - ir2_luma_table)) < 0) + ir2_delta_table[ctab])) < 0) return ret; } else { /* interframe */ if ((ret = ir2_decode_plane_inter(s, avctx->width, avctx->height, p->data[0], p->linesize[0], - ir2_luma_table)) < 0) + ir2_delta_table[ltab])) < 0) return ret; /* swapped U and V */ if ((ret = ir2_decode_plane_inter(s, avctx->width >> 2, avctx->height >> 2, p->data[2], p->linesize[2], - ir2_luma_table)) < 0) + ir2_delta_table[ctab])) < 0) return ret; if ((ret = ir2_decode_plane_inter(s, avctx->width >> 2, avctx->height >> 2, p->data[1], p->linesize[1], - ir2_luma_table)) < 0) + ir2_delta_table[ctab])) < 0) return ret; } diff --git a/libavcodec/indeo2data.h b/libavcodec/indeo2data.h index 0d6d82f22c..e05c91ff58 100644 --- a/libavcodec/indeo2data.h +++ b/libavcodec/indeo2data.h @@ -27,115 +27,211 @@ #define IR2_CODES 143 static const uint16_t ir2_codes[IR2_CODES][2] = { #ifdef BITSTREAM_READER_LE -{0x0000, 3}, {0x0004, 3}, {0x0006, 3}, {0x0001, 5}, -{0x0009, 5}, {0x0019, 5}, {0x000D, 5}, {0x001D, 5}, -{0x0023, 6}, {0x0013, 6}, {0x0033, 6}, {0x000B, 6}, -{0x002B, 6}, {0x001B, 6}, {0x0007, 8}, {0x0087, 8}, -{0x0027, 8}, {0x00A7, 8}, {0x0067, 8}, {0x00E7, 8}, -{0x0097, 8}, {0x0057, 8}, {0x0037, 8}, {0x00B7, 8}, -{0x00F7, 8}, {0x000F, 9}, {0x008F, 9}, {0x018F, 9}, -{0x014F, 9}, {0x00CF, 9}, {0x002F, 9}, {0x012F, 9}, -{0x01AF, 9}, {0x006F, 9}, {0x00EF, 9}, {0x01EF, 9}, -{0x001F, 10}, {0x021F, 10}, {0x011F, 10}, {0x031F, 10}, -{0x009F, 10}, {0x029F, 10}, {0x019F, 10}, {0x039F, 10}, -{0x005F, 10}, {0x025F, 10}, {0x015F, 10}, {0x035F, 10}, -{0x00DF, 10}, {0x02DF, 10}, {0x01DF, 10}, {0x03DF, 10}, -{0x003F, 13}, {0x103F, 13}, {0x083F, 13}, {0x183F, 13}, -{0x043F, 13}, {0x143F, 13}, {0x0C3F, 13}, {0x1C3F, 13}, -{0x023F, 13}, {0x123F, 13}, {0x0A3F, 13}, {0x1A3F, 13}, -{0x063F, 13}, {0x163F, 13}, {0x0E3F, 13}, {0x1E3F, 13}, -{0x013F, 13}, {0x113F, 13}, {0x093F, 13}, {0x193F, 13}, -{0x053F, 13}, {0x153F, 13}, {0x0D3F, 13}, {0x1D3F, 13}, -{0x033F, 13}, {0x133F, 13}, {0x0B3F, 13}, {0x1B3F, 13}, -{0x073F, 13}, {0x173F, 13}, {0x0F3F, 13}, {0x1F3F, 13}, -{0x00BF, 13}, {0x10BF, 13}, {0x08BF, 13}, {0x18BF, 13}, -{0x04BF, 13}, {0x14BF, 13}, {0x0CBF, 13}, {0x1CBF, 13}, -{0x02BF, 13}, {0x12BF, 13}, {0x0ABF, 13}, {0x1ABF, 13}, -{0x06BF, 13}, {0x16BF, 13}, {0x0EBF, 13}, {0x1EBF, 13}, -{0x01BF, 13}, {0x11BF, 13}, {0x09BF, 13}, {0x19BF, 13}, -{0x05BF, 13}, {0x15BF, 13}, {0x0DBF, 13}, {0x1DBF, 13}, -{0x03BF, 13}, {0x13BF, 13}, {0x0BBF, 13}, {0x1BBF, 13}, -{0x07BF, 13}, {0x17BF, 13}, {0x0FBF, 13}, {0x1FBF, 13}, -{0x007F, 14}, {0x207F, 14}, {0x107F, 14}, {0x307F, 14}, -{0x087F, 14}, {0x287F, 14}, {0x187F, 14}, {0x387F, 14}, -{0x047F, 14}, {0x247F, 14}, {0x147F, 14}, {0x0002, 3}, -{0x0011, 5}, {0x0005, 5}, {0x0015, 5}, {0x0003, 6}, -{0x003B, 6}, {0x0047, 8}, {0x00C7, 8}, {0x0017, 8}, -{0x00D7, 8}, {0x0077, 8}, {0x010F, 9}, {0x004F, 9}, -{0x01CF, 9}, {0x00AF, 9}, {0x016F, 9}, + { 0x0000, 3 }, { 0x0004, 3 }, { 0x0006, 3 }, { 0x0001, 5 }, + { 0x0009, 5 }, { 0x0019, 5 }, { 0x000D, 5 }, { 0x001D, 5 }, + { 0x0023, 6 }, { 0x0013, 6 }, { 0x0033, 6 }, { 0x000B, 6 }, + { 0x002B, 6 }, { 0x001B, 6 }, { 0x0007, 8 }, { 0x0087, 8 }, + { 0x0027, 8 }, { 0x00A7, 8 }, { 0x0067, 8 }, { 0x00E7, 8 }, + { 0x0097, 8 }, { 0x0057, 8 }, { 0x0037, 8 }, { 0x00B7, 8 }, + { 0x00F7, 8 }, { 0x000F, 9 }, { 0x008F, 9 }, { 0x018F, 9 }, + { 0x014F, 9 }, { 0x00CF, 9 }, { 0x002F, 9 }, { 0x012F, 9 }, + { 0x01AF, 9 }, { 0x006F, 9 }, { 0x00EF, 9 }, { 0x01EF, 9 }, + { 0x001F, 10 }, { 0x021F, 10 }, { 0x011F, 10 }, { 0x031F, 10 }, + { 0x009F, 10 }, { 0x029F, 10 }, { 0x019F, 10 }, { 0x039F, 10 }, + { 0x005F, 10 }, { 0x025F, 10 }, { 0x015F, 10 }, { 0x035F, 10 }, + { 0x00DF, 10 }, { 0x02DF, 10 }, { 0x01DF, 10 }, { 0x03DF, 10 }, + { 0x003F, 13 }, { 0x103F, 13 }, { 0x083F, 13 }, { 0x183F, 13 }, + { 0x043F, 13 }, { 0x143F, 13 }, { 0x0C3F, 13 }, { 0x1C3F, 13 }, + { 0x023F, 13 }, { 0x123F, 13 }, { 0x0A3F, 13 }, { 0x1A3F, 13 }, + { 0x063F, 13 }, { 0x163F, 13 }, { 0x0E3F, 13 }, { 0x1E3F, 13 }, + { 0x013F, 13 }, { 0x113F, 13 }, { 0x093F, 13 }, { 0x193F, 13 }, + { 0x053F, 13 }, { 0x153F, 13 }, { 0x0D3F, 13 }, { 0x1D3F, 13 }, + { 0x033F, 13 }, { 0x133F, 13 }, { 0x0B3F, 13 }, { 0x1B3F, 13 }, + { 0x073F, 13 }, { 0x173F, 13 }, { 0x0F3F, 13 }, { 0x1F3F, 13 }, + { 0x00BF, 13 }, { 0x10BF, 13 }, { 0x08BF, 13 }, { 0x18BF, 13 }, + { 0x04BF, 13 }, { 0x14BF, 13 }, { 0x0CBF, 13 }, { 0x1CBF, 13 }, + { 0x02BF, 13 }, { 0x12BF, 13 }, { 0x0ABF, 13 }, { 0x1ABF, 13 }, + { 0x06BF, 13 }, { 0x16BF, 13 }, { 0x0EBF, 13 }, { 0x1EBF, 13 }, + { 0x01BF, 13 }, { 0x11BF, 13 }, { 0x09BF, 13 }, { 0x19BF, 13 }, + { 0x05BF, 13 }, { 0x15BF, 13 }, { 0x0DBF, 13 }, { 0x1DBF, 13 }, + { 0x03BF, 13 }, { 0x13BF, 13 }, { 0x0BBF, 13 }, { 0x1BBF, 13 }, + { 0x07BF, 13 }, { 0x17BF, 13 }, { 0x0FBF, 13 }, { 0x1FBF, 13 }, + { 0x007F, 14 }, { 0x207F, 14 }, { 0x107F, 14 }, { 0x307F, 14 }, + { 0x087F, 14 }, { 0x287F, 14 }, { 0x187F, 14 }, { 0x387F, 14 }, + { 0x047F, 14 }, { 0x247F, 14 }, { 0x147F, 14 }, { 0x0002, 3 }, + { 0x0011, 5 }, { 0x0005, 5 }, { 0x0015, 5 }, { 0x0003, 6 }, + { 0x003B, 6 }, { 0x0047, 8 }, { 0x00C7, 8 }, { 0x0017, 8 }, + { 0x00D7, 8 }, { 0x0077, 8 }, { 0x010F, 9 }, { 0x004F, 9 }, + { 0x01CF, 9 }, { 0x00AF, 9 }, { 0x016F, 9 }, #else - {0x0000, 3}, {0x0001, 3}, {0x0003, 3}, {0x0010, 5}, - {0x0012, 5}, {0x0013, 5}, {0x0016, 5}, {0x0017, 5}, - {0x0031, 6}, {0x0032, 6}, {0x0033, 6}, {0x0034, 6}, - {0x0035, 6}, {0x0036, 6}, {0x00E0, 8}, {0x00E1, 8}, - {0x00E4, 8}, {0x00E5, 8}, {0x00E6, 8}, {0x00E7, 8}, - {0x00E9, 8}, {0x00EA, 8}, {0x00EC, 8}, {0x00ED, 8}, - {0x00EF, 8}, {0x01E0, 9}, {0x01E2, 9}, {0x01E3, 9}, - {0x01E5, 9}, {0x01E6, 9}, {0x01E8, 9}, {0x01E9, 9}, - {0x01EB, 9}, {0x01EC, 9}, {0x01EE, 9}, {0x01EF, 9}, - {0x03E0, 10}, {0x03E1, 10}, {0x03E2, 10}, {0x03E3, 10}, - {0x03E4, 10}, {0x03E5, 10}, {0x03E6, 10}, {0x03E7, 10}, - {0x03E8, 10}, {0x03E9, 10}, {0x03EA, 10}, {0x03EB, 10}, - {0x03EC, 10}, {0x03ED, 10}, {0x03EE, 10}, {0x03EF, 10}, - {0x1F80, 13}, {0x1F81, 13}, {0x1F82, 13}, {0x1F83, 13}, - {0x1F84, 13}, {0x1F85, 13}, {0x1F86, 13}, {0x1F87, 13}, - {0x1F88, 13}, {0x1F89, 13}, {0x1F8A, 13}, {0x1F8B, 13}, - {0x1F8C, 13}, {0x1F8D, 13}, {0x1F8E, 13}, {0x1F8F, 13}, - {0x1F90, 13}, {0x1F91, 13}, {0x1F92, 13}, {0x1F93, 13}, - {0x1F94, 13}, {0x1F95, 13}, {0x1F96, 13}, {0x1F97, 13}, - {0x1F98, 13}, {0x1F99, 13}, {0x1F9A, 13}, {0x1F9B, 13}, - {0x1F9C, 13}, {0x1F9D, 13}, {0x1F9E, 13}, {0x1F9F, 13}, - {0x1FA0, 13}, {0x1FA1, 13}, {0x1FA2, 13}, {0x1FA3, 13}, - {0x1FA4, 13}, {0x1FA5, 13}, {0x1FA6, 13}, {0x1FA7, 13}, - {0x1FA8, 13}, {0x1FA9, 13}, {0x1FAA, 13}, {0x1FAB, 13}, - {0x1FAC, 13}, {0x1FAD, 13}, {0x1FAE, 13}, {0x1FAF, 13}, - {0x1FB0, 13}, {0x1FB1, 13}, {0x1FB2, 13}, {0x1FB3, 13}, - {0x1FB4, 13}, {0x1FB5, 13}, {0x1FB6, 13}, {0x1FB7, 13}, - {0x1FB8, 13}, {0x1FB9, 13}, {0x1FBA, 13}, {0x1FBB, 13}, - {0x1FBC, 13}, {0x1FBD, 13}, {0x1FBE, 13}, {0x1FBF, 13}, - {0x3F80, 14}, {0x3F81, 14}, {0x3F82, 14}, {0x3F83, 14}, - {0x3F84, 14}, {0x3F85, 14}, {0x3F86, 14}, {0x3F87, 14}, - {0x3F88, 14}, {0x3F89, 14}, {0x3F8A, 14}, {0x0002, 3}, - {0x0011, 5}, {0x0014, 5}, {0x0015, 5}, {0x0030, 6}, - {0x0037, 6}, {0x00E2, 8}, {0x00E3, 8}, {0x00E8, 8}, - {0x00EB, 8}, {0x00EE, 8}, {0x01E1, 9}, {0x01E4, 9}, - {0x01E7, 9}, {0x01EA, 9}, {0x01ED, 9} + { 0x0000, 3 }, { 0x0001, 3 }, { 0x0003, 3 }, { 0x0010, 5 }, + { 0x0012, 5 }, { 0x0013, 5 }, { 0x0016, 5 }, { 0x0017, 5 }, + { 0x0031, 6 }, { 0x0032, 6 }, { 0x0033, 6 }, { 0x0034, 6 }, + { 0x0035, 6 }, { 0x0036, 6 }, { 0x00E0, 8 }, { 0x00E1, 8 }, + { 0x00E4, 8 }, { 0x00E5, 8 }, { 0x00E6, 8 }, { 0x00E7, 8 }, + { 0x00E9, 8 }, { 0x00EA, 8 }, { 0x00EC, 8 }, { 0x00ED, 8 }, + { 0x00EF, 8 }, { 0x01E0, 9 }, { 0x01E2, 9 }, { 0x01E3, 9 }, + { 0x01E5, 9 }, { 0x01E6, 9 }, { 0x01E8, 9 }, { 0x01E9, 9 }, + { 0x01EB, 9 }, { 0x01EC, 9 }, { 0x01EE, 9 }, { 0x01EF, 9 }, + { 0x03E0, 10 }, { 0x03E1, 10 }, { 0x03E2, 10 }, { 0x03E3, 10 }, + { 0x03E4, 10 }, { 0x03E5, 10 }, { 0x03E6, 10 }, { 0x03E7, 10 }, + { 0x03E8, 10 }, { 0x03E9, 10 }, { 0x03EA, 10 }, { 0x03EB, 10 }, + { 0x03EC, 10 }, { 0x03ED, 10 }, { 0x03EE, 10 }, { 0x03EF, 10 }, + { 0x1F80, 13 }, { 0x1F81, 13 }, { 0x1F82, 13 }, { 0x1F83, 13 }, + { 0x1F84, 13 }, { 0x1F85, 13 }, { 0x1F86, 13 }, { 0x1F87, 13 }, + { 0x1F88, 13 }, { 0x1F89, 13 }, { 0x1F8A, 13 }, { 0x1F8B, 13 }, + { 0x1F8C, 13 }, { 0x1F8D, 13 }, { 0x1F8E, 13 }, { 0x1F8F, 13 }, + { 0x1F90, 13 }, { 0x1F91, 13 }, { 0x1F92, 13 }, { 0x1F93, 13 }, + { 0x1F94, 13 }, { 0x1F95, 13 }, { 0x1F96, 13 }, { 0x1F97, 13 }, + { 0x1F98, 13 }, { 0x1F99, 13 }, { 0x1F9A, 13 }, { 0x1F9B, 13 }, + { 0x1F9C, 13 }, { 0x1F9D, 13 }, { 0x1F9E, 13 }, { 0x1F9F, 13 }, + { 0x1FA0, 13 }, { 0x1FA1, 13 }, { 0x1FA2, 13 }, { 0x1FA3, 13 }, + { 0x1FA4, 13 }, { 0x1FA5, 13 }, { 0x1FA6, 13 }, { 0x1FA7, 13 }, + { 0x1FA8, 13 }, { 0x1FA9, 13 }, { 0x1FAA, 13 }, { 0x1FAB, 13 }, + { 0x1FAC, 13 }, { 0x1FAD, 13 }, { 0x1FAE, 13 }, { 0x1FAF, 13 }, + { 0x1FB0, 13 }, { 0x1FB1, 13 }, { 0x1FB2, 13 }, { 0x1FB3, 13 }, + { 0x1FB4, 13 }, { 0x1FB5, 13 }, { 0x1FB6, 13 }, { 0x1FB7, 13 }, + { 0x1FB8, 13 }, { 0x1FB9, 13 }, { 0x1FBA, 13 }, { 0x1FBB, 13 }, + { 0x1FBC, 13 }, { 0x1FBD, 13 }, { 0x1FBE, 13 }, { 0x1FBF, 13 }, + { 0x3F80, 14 }, { 0x3F81, 14 }, { 0x3F82, 14 }, { 0x3F83, 14 }, + { 0x3F84, 14 }, { 0x3F85, 14 }, { 0x3F86, 14 }, { 0x3F87, 14 }, + { 0x3F88, 14 }, { 0x3F89, 14 }, { 0x3F8A, 14 }, { 0x0002, 3 }, + { 0x0011, 5 }, { 0x0014, 5 }, { 0x0015, 5 }, { 0x0030, 6 }, + { 0x0037, 6 }, { 0x00E2, 8 }, { 0x00E3, 8 }, { 0x00E8, 8 }, + { 0x00EB, 8 }, { 0x00EE, 8 }, { 0x01E1, 9 }, { 0x01E4, 9 }, + { 0x01E7, 9 }, { 0x01EA, 9 }, { 0x01ED, 9 }, #endif }; -static const uint8_t ir2_luma_table[256] = { - 0x80, 0x80, 0x84, 0x84, 0x7C, 0x7C, 0x7F, 0x85, - 0x81, 0x7B, 0x85, 0x7F, 0x7B, 0x81, 0x8C, 0x8C, - 0x74, 0x74, 0x83, 0x8D, 0x7D, 0x73, 0x8D, 0x83, - 0x73, 0x7D, 0x77, 0x89, 0x89, 0x77, 0x89, 0x77, - 0x77, 0x89, 0x8C, 0x95, 0x74, 0x6B, 0x95, 0x8C, - 0x6B, 0x74, 0x7C, 0x90, 0x84, 0x70, 0x90, 0x7C, - 0x70, 0x84, 0x96, 0x96, 0x6A, 0x6A, 0x82, 0x98, - 0x7E, 0x68, 0x98, 0x82, 0x68, 0x7E, 0x97, 0xA2, - 0x69, 0x5E, 0xA2, 0x97, 0x5E, 0x69, 0xA2, 0xA2, - 0x5E, 0x5E, 0x8B, 0xA3, 0x75, 0x5D, 0xA3, 0x8B, - 0x5D, 0x75, 0x71, 0x95, 0x8F, 0x6B, 0x95, 0x71, - 0x6B, 0x8F, 0x78, 0x9D, 0x88, 0x63, 0x9D, 0x78, - 0x63, 0x88, 0x7F, 0xA7, 0x81, 0x59, 0xA7, 0x7F, - 0x59, 0x81, 0xA4, 0xB1, 0x5C, 0x4F, 0xB1, 0xA4, - 0x4F, 0x5C, 0x96, 0xB1, 0x6A, 0x4F, 0xB1, 0x96, - 0x4F, 0x6A, 0xB2, 0xB2, 0x4E, 0x4E, 0x65, 0x9B, - 0x9B, 0x65, 0x9B, 0x65, 0x65, 0x9B, 0x89, 0xB4, - 0x77, 0x4C, 0xB4, 0x89, 0x4C, 0x77, 0x6A, 0xA3, - 0x96, 0x5D, 0xA3, 0x6A, 0x5D, 0x96, 0x73, 0xAC, - 0x8D, 0x54, 0xAC, 0x73, 0x54, 0x8D, 0xB4, 0xC3, - 0x4C, 0x3D, 0xC3, 0xB4, 0x3D, 0x4C, 0xA4, 0xC3, - 0x5C, 0x3D, 0xC3, 0xA4, 0x3D, 0x5C, 0xC4, 0xC4, - 0x3C, 0x3C, 0x96, 0xC6, 0x6A, 0x3A, 0xC6, 0x96, - 0x3A, 0x6A, 0x7C, 0xBA, 0x84, 0x46, 0xBA, 0x7C, - 0x46, 0x84, 0x5B, 0xAB, 0xA5, 0x55, 0xAB, 0x5B, - 0x55, 0xA5, 0x63, 0xB4, 0x9D, 0x4C, 0xB4, 0x63, - 0x4C, 0x9D, 0x86, 0xCA, 0x7A, 0x36, 0xCA, 0x86, - 0x36, 0x7A, 0xB6, 0xD7, 0x4A, 0x29, 0xD7, 0xB6, - 0x29, 0x4A, 0xC8, 0xD7, 0x38, 0x29, 0xD7, 0xC8, - 0x29, 0x38, 0xA4, 0xD8, 0x5C, 0x28, 0xD8, 0xA4, - 0x28, 0x5C, 0x6C, 0xC1, 0x94, 0x3F, 0xC1, 0x6C, - 0x3F, 0x94, 0xD9, 0xD9, 0x27, 0x27, 0x80, 0x80 +static const uint8_t ir2_delta_table[4][256] = { + { 0x80, 0x80, 0x84, 0x84, 0x7C, 0x7C, 0x7F, 0x85, + 0x81, 0x7B, 0x85, 0x7F, 0x7B, 0x81, 0x8C, 0x8C, + 0x74, 0x74, 0x83, 0x8D, 0x7D, 0x73, 0x8D, 0x83, + 0x73, 0x7D, 0x77, 0x89, 0x89, 0x77, 0x89, 0x77, + 0x77, 0x89, 0x8C, 0x95, 0x74, 0x6B, 0x95, 0x8C, + 0x6B, 0x74, 0x7C, 0x90, 0x84, 0x70, 0x90, 0x7C, + 0x70, 0x84, 0x96, 0x96, 0x6A, 0x6A, 0x82, 0x98, + 0x7E, 0x68, 0x98, 0x82, 0x68, 0x7E, 0x97, 0xA2, + 0x69, 0x5E, 0xA2, 0x97, 0x5E, 0x69, 0xA2, 0xA2, + 0x5E, 0x5E, 0x8B, 0xA3, 0x75, 0x5D, 0xA3, 0x8B, + 0x5D, 0x75, 0x71, 0x95, 0x8F, 0x6B, 0x95, 0x71, + 0x6B, 0x8F, 0x78, 0x9D, 0x88, 0x63, 0x9D, 0x78, + 0x63, 0x88, 0x7F, 0xA7, 0x81, 0x59, 0xA7, 0x7F, + 0x59, 0x81, 0xA4, 0xB1, 0x5C, 0x4F, 0xB1, 0xA4, + 0x4F, 0x5C, 0x96, 0xB1, 0x6A, 0x4F, 0xB1, 0x96, + 0x4F, 0x6A, 0xB2, 0xB2, 0x4E, 0x4E, 0x65, 0x9B, + 0x9B, 0x65, 0x9B, 0x65, 0x65, 0x9B, 0x89, 0xB4, + 0x77, 0x4C, 0xB4, 0x89, 0x4C, 0x77, 0x6A, 0xA3, + 0x96, 0x5D, 0xA3, 0x6A, 0x5D, 0x96, 0x73, 0xAC, + 0x8D, 0x54, 0xAC, 0x73, 0x54, 0x8D, 0xB4, 0xC3, + 0x4C, 0x3D, 0xC3, 0xB4, 0x3D, 0x4C, 0xA4, 0xC3, + 0x5C, 0x3D, 0xC3, 0xA4, 0x3D, 0x5C, 0xC4, 0xC4, + 0x3C, 0x3C, 0x96, 0xC6, 0x6A, 0x3A, 0xC6, 0x96, + 0x3A, 0x6A, 0x7C, 0xBA, 0x84, 0x46, 0xBA, 0x7C, + 0x46, 0x84, 0x5B, 0xAB, 0xA5, 0x55, 0xAB, 0x5B, + 0x55, 0xA5, 0x63, 0xB4, 0x9D, 0x4C, 0xB4, 0x63, + 0x4C, 0x9D, 0x86, 0xCA, 0x7A, 0x36, 0xCA, 0x86, + 0x36, 0x7A, 0xB6, 0xD7, 0x4A, 0x29, 0xD7, 0xB6, + 0x29, 0x4A, 0xC8, 0xD7, 0x38, 0x29, 0xD7, 0xC8, + 0x29, 0x38, 0xA4, 0xD8, 0x5C, 0x28, 0xD8, 0xA4, + 0x28, 0x5C, 0x6C, 0xC1, 0x94, 0x3F, 0xC1, 0x6C, + 0x3F, 0x94, 0xD9, 0xD9, 0x27, 0x27, 0x80, 0x80, }, + { 0x80, 0x80, 0x85, 0x85, 0x7B, 0x7B, 0x7E, 0x87, + 0x82, 0x79, 0x87, 0x7E, 0x79, 0x82, 0x8F, 0x8F, + 0x71, 0x71, 0x84, 0x8F, 0x7C, 0x71, 0x8F, 0x84, + 0x71, 0x7C, 0x75, 0x8B, 0x8B, 0x75, 0x8B, 0x75, + 0x75, 0x8B, 0x8E, 0x9A, 0x72, 0x66, 0x9A, 0x8E, + 0x66, 0x72, 0x7B, 0x93, 0x85, 0x6D, 0x93, 0x7B, + 0x6D, 0x85, 0x9B, 0x9B, 0x65, 0x65, 0x82, 0x9D, + 0x7E, 0x63, 0x9D, 0x82, 0x63, 0x7E, 0x9B, 0xA8, + 0x65, 0x58, 0xA8, 0x9B, 0x58, 0x65, 0xA9, 0xA9, + 0x57, 0x57, 0x8D, 0xAA, 0x73, 0x56, 0xAA, 0x8D, + 0x56, 0x73, 0x6E, 0x99, 0x92, 0x67, 0x99, 0x6E, + 0x67, 0x92, 0x76, 0xA2, 0x8A, 0x5E, 0xA2, 0x76, + 0x5E, 0x8A, 0x7F, 0xAF, 0x81, 0x51, 0xAF, 0x7F, + 0x51, 0x81, 0xAB, 0xBA, 0x55, 0x46, 0xBA, 0xAB, + 0x46, 0x55, 0x9A, 0xBB, 0x66, 0x45, 0xBB, 0x9A, + 0x45, 0x66, 0xBB, 0xBB, 0x45, 0x45, 0x60, 0xA0, + 0xA0, 0x60, 0xA0, 0x60, 0x60, 0xA0, 0x8B, 0xBE, + 0x75, 0x42, 0xBE, 0x8B, 0x42, 0x75, 0x66, 0xAA, + 0x9A, 0x56, 0xAA, 0x66, 0x56, 0x9A, 0x70, 0xB5, + 0x90, 0x4B, 0xB5, 0x70, 0x4B, 0x90, 0xBE, 0xCF, + 0x42, 0x31, 0xCF, 0xBE, 0x31, 0x42, 0xAB, 0xD0, + 0x55, 0x30, 0xD0, 0xAB, 0x30, 0x55, 0xD1, 0xD1, + 0x2F, 0x2F, 0x9A, 0xD3, 0x66, 0x2D, 0xD3, 0x9A, + 0x2D, 0x66, 0x7B, 0xC5, 0x85, 0x3B, 0xC5, 0x7B, + 0x3B, 0x85, 0x54, 0xB4, 0xAC, 0x4C, 0xB4, 0x54, + 0x4C, 0xAC, 0x5E, 0xBE, 0xA2, 0x42, 0xBE, 0x5E, + 0x42, 0xA2, 0x87, 0xD8, 0x79, 0x28, 0xD8, 0x87, + 0x28, 0x79, 0xC0, 0xE8, 0x40, 0x18, 0xE8, 0xC0, + 0x18, 0x40, 0xD5, 0xE8, 0x2B, 0x18, 0xE8, 0xD5, + 0x18, 0x2B, 0xAB, 0xE9, 0x55, 0x17, 0xE9, 0xAB, + 0x17, 0x55, 0x68, 0xCD, 0x98, 0x33, 0xCD, 0x68, + 0x33, 0x98, 0xEA, 0xEA, 0x16, 0x16, 0x80, 0x80, }, + { 0x80, 0x80, 0x86, 0x86, 0x7A, 0x7A, 0x7E, 0x88, + 0x82, 0x78, 0x88, 0x7E, 0x78, 0x82, 0x92, 0x92, + 0x6E, 0x6E, 0x85, 0x92, 0x7B, 0x6E, 0x92, 0x85, + 0x6E, 0x7B, 0x73, 0x8D, 0x8D, 0x73, 0x8D, 0x73, + 0x73, 0x8D, 0x91, 0x9E, 0x6F, 0x62, 0x9E, 0x91, + 0x62, 0x6F, 0x79, 0x97, 0x87, 0x69, 0x97, 0x79, + 0x69, 0x87, 0xA0, 0xA0, 0x60, 0x60, 0x83, 0xA2, + 0x7D, 0x5E, 0xA2, 0x83, 0x5E, 0x7D, 0xA0, 0xB0, + 0x60, 0x50, 0xB0, 0xA0, 0x50, 0x60, 0xB1, 0xB1, + 0x4F, 0x4F, 0x8F, 0xB2, 0x71, 0x4E, 0xB2, 0x8F, + 0x4E, 0x71, 0x6B, 0x9E, 0x95, 0x62, 0x9E, 0x6B, + 0x62, 0x95, 0x74, 0xA9, 0x8C, 0x57, 0xA9, 0x74, + 0x57, 0x8C, 0x7F, 0xB8, 0x81, 0x48, 0xB8, 0x7F, + 0x48, 0x81, 0xB4, 0xC5, 0x4C, 0x3B, 0xC5, 0xB4, + 0x3B, 0x4C, 0x9F, 0xC6, 0x61, 0x3A, 0xC6, 0x9F, + 0x3A, 0x61, 0xC6, 0xC6, 0x3A, 0x3A, 0x59, 0xA7, + 0xA7, 0x59, 0xA7, 0x59, 0x59, 0xA7, 0x8D, 0xCA, + 0x73, 0x36, 0xCA, 0x8D, 0x36, 0x73, 0x61, 0xB2, + 0x9F, 0x4E, 0xB2, 0x61, 0x4E, 0x9F, 0x6D, 0xBF, + 0x93, 0x41, 0xBF, 0x6D, 0x41, 0x93, 0xCA, 0xDF, + 0x36, 0x21, 0xDF, 0xCA, 0x21, 0x36, 0xB3, 0xDF, + 0x4D, 0x21, 0xDF, 0xB3, 0x21, 0x4D, 0xE1, 0xE1, + 0x1F, 0x1F, 0x9F, 0xE3, 0x61, 0x1D, 0xE3, 0x9F, + 0x1D, 0x61, 0x7A, 0xD3, 0x86, 0x2D, 0xD3, 0x7A, + 0x2D, 0x86, 0x4C, 0xBE, 0xB4, 0x42, 0xBE, 0x4C, + 0x42, 0xB4, 0x57, 0xCA, 0xA9, 0x36, 0xCA, 0x57, + 0x36, 0xA9, 0x88, 0xE9, 0x78, 0x17, 0xE9, 0x88, + 0x17, 0x78, 0xCC, 0xFB, 0x34, 0x05, 0xFB, 0xCC, + 0x05, 0x34, 0xE6, 0xFB, 0x1A, 0x05, 0xFB, 0xE6, + 0x05, 0x1A, 0xB4, 0xFD, 0x4C, 0x03, 0xFD, 0xB4, + 0x03, 0x4C, 0x63, 0xDC, 0x9D, 0x24, 0xDC, 0x63, + 0x24, 0x9D, 0xFE, 0xFE, 0x02, 0x02, 0x80, 0x80, }, + { 0x80, 0x80, 0x87, 0x87, 0x79, 0x79, 0x7E, 0x89, + 0x82, 0x77, 0x89, 0x7E, 0x77, 0x82, 0x95, 0x95, + 0x6B, 0x6B, 0x86, 0x96, 0x7A, 0x6A, 0x96, 0x86, + 0x6A, 0x7A, 0x70, 0x90, 0x90, 0x70, 0x90, 0x70, + 0x70, 0x90, 0x94, 0xA4, 0x6C, 0x5C, 0xA4, 0x94, + 0x5C, 0x6C, 0x78, 0x9B, 0x88, 0x65, 0x9B, 0x78, + 0x65, 0x88, 0xA6, 0xA6, 0x5A, 0x5A, 0x83, 0xA9, + 0x7D, 0x57, 0xA9, 0x83, 0x57, 0x7D, 0xA6, 0xB9, + 0x5A, 0x47, 0xB9, 0xA6, 0x47, 0x5A, 0xBA, 0xBA, + 0x46, 0x46, 0x92, 0xBC, 0x6E, 0x44, 0xBC, 0x92, + 0x44, 0x6E, 0x67, 0xA3, 0x99, 0x5D, 0xA3, 0x67, + 0x5D, 0x99, 0x72, 0xB0, 0x8E, 0x50, 0xB0, 0x72, + 0x50, 0x8E, 0x7F, 0xC3, 0x81, 0x3D, 0xC3, 0x7F, + 0x3D, 0x81, 0xBE, 0xD2, 0x42, 0x2E, 0xD2, 0xBE, + 0x2E, 0x42, 0xA5, 0xD4, 0x5B, 0x2C, 0xD4, 0xA5, + 0x2C, 0x5B, 0xD4, 0xD4, 0x2C, 0x2C, 0x52, 0xAE, + 0xAE, 0x52, 0xAE, 0x52, 0x52, 0xAE, 0x8F, 0xD8, + 0x71, 0x28, 0xD8, 0x8F, 0x28, 0x71, 0x5B, 0xBB, + 0xA5, 0x45, 0xBB, 0x5B, 0x45, 0xA5, 0x69, 0xCB, + 0x97, 0x35, 0xCB, 0x69, 0x35, 0x97, 0xD8, 0xF0, + 0x28, 0x10, 0xF0, 0xD8, 0x10, 0x28, 0xBD, 0xF1, + 0x43, 0x0F, 0xF1, 0xBD, 0x0F, 0x43, 0xF3, 0xF3, + 0x0D, 0x0D, 0xA5, 0xF6, 0x5B, 0x0A, 0xF6, 0xA5, + 0x0A, 0x5B, 0x78, 0xE2, 0x88, 0x1E, 0xE2, 0x78, + 0x1E, 0x88, 0x42, 0xC9, 0xBE, 0x37, 0xC9, 0x42, + 0x37, 0xBE, 0x4F, 0xD8, 0xB1, 0x28, 0xD8, 0x4F, + 0x28, 0xB1, 0x8A, 0xFD, 0x76, 0x03, 0xFD, 0x8A, + 0x03, 0x76, 0xDB, 0xFF, 0x25, 0x01, 0xFF, 0xDB, + 0x01, 0x25, 0xF9, 0xFF, 0x07, 0x01, 0xFF, 0xF9, + 0x01, 0x07, 0xBE, 0xFF, 0x42, 0x01, 0xFF, 0xBE, + 0x01, 0x42, 0x5E, 0xED, 0xA2, 0x13, 0xED, 0x5E, + 0x13, 0xA2, 0xFF, 0xFF, 0x01, 0x01, 0x80, 0x80, }, }; #endif /* AVCODEC_INDEO2DATA_H */ diff --git a/libavcodec/indeo3.c b/libavcodec/indeo3.c index d38765ea40..9fde0fdf6c 100644 --- a/libavcodec/indeo3.c +++ b/libavcodec/indeo3.c @@ -94,7 +94,7 @@ typedef struct Indeo3DecodeContext { int16_t width, height; uint32_t frame_num; ///< current frame number (zero-based) - uint32_t data_size; ///< size of the frame data in bytes + int data_size; ///< size of the frame data in bytes uint16_t frame_flags; ///< frame properties uint8_t cb_offset; ///< needed for selecting VQ tables uint8_t buf_sel; ///< active frame buffer: 0 - primary, 1 -secondary @@ -899,7 +899,8 @@ static int decode_frame_headers(Indeo3DecodeContext *ctx, AVCodecContext *avctx, GetByteContext gb; const uint8_t *bs_hdr; uint32_t frame_num, word2, check_sum, data_size; - uint32_t y_offset, u_offset, v_offset, starts[3], ends[3]; + int y_offset, u_offset, v_offset; + uint32_t starts[3], ends[3]; uint16_t height, width; int i, j; @@ -981,7 +982,8 @@ static int decode_frame_headers(Indeo3DecodeContext *ctx, AVCodecContext *avctx, ctx->y_data_size = ends[0] - starts[0]; ctx->v_data_size = ends[1] - starts[1]; ctx->u_data_size = ends[2] - starts[2]; - if (FFMAX3(y_offset, v_offset, u_offset) >= ctx->data_size - 16 || + if (FFMIN3(y_offset, v_offset, u_offset) < 0 || + FFMAX3(y_offset, v_offset, u_offset) >= ctx->data_size - 16 || FFMIN3(y_offset, v_offset, u_offset) < gb.buffer - bs_hdr + 16 || FFMIN3(ctx->y_data_size, ctx->v_data_size, ctx->u_data_size) <= 0) { av_log(avctx, AV_LOG_ERROR, "One of the y/u/v offsets is invalid\n"); diff --git a/libavcodec/interplayvideo.c b/libavcodec/interplayvideo.c index 96c0cd1397..f9e74b0a85 100644 --- a/libavcodec/interplayvideo.c +++ b/libavcodec/interplayvideo.c @@ -38,6 +38,7 @@ #include #include +#include "libavutil/intreadwrite.h" #include "avcodec.h" #include "bytestream.h" #include "hpeldsp.h" @@ -949,7 +950,7 @@ static void ipvideo_decode_opcodes(IpvideoContext *s, AVFrame *frame) } } if (bytestream2_get_bytes_left(&s->stream_ptr) > 1) { - av_log(s->avctx, AV_LOG_ERROR, + av_log(s->avctx, AV_LOG_DEBUG, "decode finished with %d bytes left over\n", bytestream2_get_bytes_left(&s->stream_ptr)); } @@ -987,12 +988,15 @@ static int ipvideo_decode_frame(AVCodecContext *avctx, AVFrame *frame = data; int ret; + if (buf_size < 2) + return AVERROR_INVALIDDATA; + /* decoding map contains 4 bits of information per 8x8 block */ - s->decoding_map_size = avctx->width * avctx->height / (8 * 8 * 2); + s->decoding_map_size = AV_RL16(avpkt->data); /* compressed buffer needs to be large enough to at least hold an entire * decoding map */ - if (buf_size < s->decoding_map_size) + if (buf_size < s->decoding_map_size + 2) return buf_size; if (av_packet_get_side_data(avpkt, AV_PKT_DATA_PARAM_CHANGE, NULL)) { @@ -1000,8 +1004,8 @@ static int ipvideo_decode_frame(AVCodecContext *avctx, av_frame_unref(s->second_last_frame); } - s->decoding_map = buf; - bytestream2_init(&s->stream_ptr, buf + s->decoding_map_size, + s->decoding_map = buf + 2; + bytestream2_init(&s->stream_ptr, buf + 2 + s->decoding_map_size, buf_size - s->decoding_map_size); if ((ret = ff_get_buffer(avctx, frame, AV_GET_BUFFER_FLAG_REF)) < 0) diff --git a/libavcodec/ituh263enc.c b/libavcodec/ituh263enc.c index 43ad08026f..7a91dc0e86 100644 --- a/libavcodec/ituh263enc.c +++ b/libavcodec/ituh263enc.c @@ -43,7 +43,7 @@ /** * Table of number of bits a motion vector component needs. */ -static uint8_t mv_penalty[MAX_FCODE+1][MAX_MV*2+1]; +static uint8_t mv_penalty[MAX_FCODE+1][MAX_DMV*2+1]; /** * Minimal fcode that a motion vector component would need. @@ -676,7 +676,7 @@ static av_cold void init_mv_penalty_and_fcode(MpegEncContext *s) int mv; for(f_code=1; f_code<=MAX_FCODE; f_code++){ - for(mv=-MAX_MV; mv<=MAX_MV; mv++){ + for(mv=-MAX_DMV; mv<=MAX_DMV; mv++){ int len; if(mv==0) len= ff_mvtab[0][1]; @@ -697,7 +697,7 @@ static av_cold void init_mv_penalty_and_fcode(MpegEncContext *s) } } - mv_penalty[f_code][mv+MAX_MV]= len; + mv_penalty[f_code][mv+MAX_DMV]= len; } } diff --git a/libavcodec/ivi_common.c b/libavcodec/ivi_common.c index 379508123f..80b0676287 100644 --- a/libavcodec/ivi_common.c +++ b/libavcodec/ivi_common.c @@ -30,6 +30,7 @@ #define BITSTREAM_READER_LE #include "libavutil/attributes.h" +#include "libavutil/imgutils.h" #include "libavutil/timer.h" #include "avcodec.h" #include "get_bits.h" @@ -310,7 +311,7 @@ av_cold int ff_ivi_init_planes(IVIPlaneDesc *planes, const IVIPicConfig *cfg, ivi_free_buffers(planes); - if (cfg->pic_width < 1 || cfg->pic_height < 1 || + if (av_image_check_size(cfg->pic_width, cfg->pic_height, 0, NULL) < 0 || cfg->luma_bands < 1 || cfg->chroma_bands < 1) return AVERROR_INVALIDDATA; diff --git a/libavcodec/j2kenc.c b/libavcodec/j2kenc.c index ddb0b686cb..60e211e7e3 100644 --- a/libavcodec/j2kenc.c +++ b/libavcodec/j2kenc.c @@ -17,8 +17,46 @@ * 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 + * + * ********************************************************************************************************************** + * + * + * + * This source code incorporates work covered by the following copyright and + * permission notice: + * + * Copyright (c) 2002-2007, Communications and Remote Sensing Laboratory, Universite catholique de Louvain (UCL), Belgium + * Copyright (c) 2002-2007, Professor Benoit Macq + * Copyright (c) 2001-2003, David Janssens + * Copyright (c) 2002-2003, Yannick Verschueren + * Copyright (c) 2003-2007, Francois-Olivier Devaux and Antonin Descampe + * Copyright (c) 2005, Herve Drolon, FreeImage Team + * Copyright (c) 2007, Callum Lerwick + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS `AS IS' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. */ + /** * JPEG2000 image encoder * @file diff --git a/libavcodec/jpeg2000.c b/libavcodec/jpeg2000.c index 644e25d399..2023978b0c 100644 --- a/libavcodec/jpeg2000.c +++ b/libavcodec/jpeg2000.c @@ -28,6 +28,7 @@ #include "libavutil/attributes.h" #include "libavutil/avassert.h" #include "libavutil/common.h" +#include "libavutil/imgutils.h" #include "libavutil/mem.h" #include "avcodec.h" #include "jpeg2000.h" @@ -210,9 +211,17 @@ int ff_jpeg2000_init_component(Jpeg2000Component *comp, codsty->nreslevels2decode - 1, codsty->transform)) return ret; - // component size comp->coord is uint16_t so ir cannot overflow + + if (av_image_check_size(comp->coord[0][1] - comp->coord[0][0], + comp->coord[1][1] - comp->coord[1][0], 0, avctx)) + return AVERROR_INVALIDDATA; csize = (comp->coord[0][1] - comp->coord[0][0]) * (comp->coord[1][1] - comp->coord[1][0]); + if (comp->coord[0][1] > 32768 || + comp->coord[1][1] > 32768) { + av_log(avctx, AV_LOG_ERROR, "component size too large\n"); + return AVERROR_PATCHWELCOME; + } if (codsty->transform == FF_DWT97) { comp->i_data = NULL; diff --git a/libavcodec/jpeg2000dec.c b/libavcodec/jpeg2000dec.c index 17ee5418c0..2430c73e2e 100644 --- a/libavcodec/jpeg2000dec.c +++ b/libavcodec/jpeg2000dec.c @@ -252,6 +252,10 @@ static int get_siz(Jpeg2000DecoderContext *s) avpriv_request_sample(s->avctx, "Support for image offsets"); return AVERROR_PATCHWELCOME; } + if (s->width > 32768U || s->height > 32768U) { + avpriv_request_sample(s->avctx, "Large Dimensions"); + return AVERROR_PATCHWELCOME; + } if (ncomponents <= 0) { av_log(s->avctx, AV_LOG_ERROR, "Invalid number of components: %d\n", @@ -686,10 +690,10 @@ static int init_tile(Jpeg2000DecoderContext *s, int tileno) Jpeg2000QuantStyle *qntsty = tile->qntsty + compno; int ret; // global bandno - comp->coord_o[0][0] = FFMAX(tilex * s->tile_width + s->tile_offset_x, s->image_offset_x); - comp->coord_o[0][1] = FFMIN((tilex + 1) * s->tile_width + s->tile_offset_x, s->width); - comp->coord_o[1][0] = FFMAX(tiley * s->tile_height + s->tile_offset_y, s->image_offset_y); - comp->coord_o[1][1] = FFMIN((tiley + 1) * s->tile_height + s->tile_offset_y, s->height); + comp->coord_o[0][0] = av_clip(tilex * (int64_t)s->tile_width + s->tile_offset_x, s->image_offset_x, s->width); + comp->coord_o[0][1] = av_clip((tilex + 1) * (int64_t)s->tile_width + s->tile_offset_x, s->image_offset_x, s->width); + comp->coord_o[1][0] = av_clip(tiley * (int64_t)s->tile_height + s->tile_offset_y, s->image_offset_y, s->height); + comp->coord_o[1][1] = av_clip((tiley + 1) * (int64_t)s->tile_height + s->tile_offset_y, s->image_offset_y, s->height); comp->coord[0][0] = ff_jpeg2000_ceildivpow2(comp->coord_o[0][0], s->reduction_factor); comp->coord[0][1] = ff_jpeg2000_ceildivpow2(comp->coord_o[0][1], s->reduction_factor); @@ -1077,6 +1081,10 @@ static int decode_cblk(Jpeg2000DecoderContext *s, Jpeg2000CodingStyle *codsty, ff_mqc_initdec(&t1->mqc, cblk->data); while (passno--) { + if (bpno < 0) { + av_log(s->avctx, AV_LOG_ERROR, "bpno became negative\n"); + return AVERROR_INVALIDDATA; + } switch(pass_t) { case 0: decode_sigpass(t1, width, height, bpno + 1, bandpos, @@ -1148,11 +1156,16 @@ static inline void mct_decode(Jpeg2000DecoderContext *s, Jpeg2000Tile *tile) int i, csize = 1; void *src[3]; - for (i = 1; i < 3; i++) + for (i = 1; i < 3; i++) { if (tile->codsty[0].transform != tile->codsty[i].transform) { av_log(s->avctx, AV_LOG_ERROR, "Transforms mismatch, MCT not supported\n"); return; } + if (memcmp(tile->comp[0].coord, tile->comp[i].coord, sizeof(tile->comp[0].coord))) { + av_log(s->avctx, AV_LOG_ERROR, "Coords mismatch, MCT not supported\n"); + return; + } + } for (i = 0; i < 3; i++) if (tile->codsty[0].transform == FF_DWT97) @@ -1232,11 +1245,15 @@ static int jpeg2000_decode_tile(Jpeg2000DecoderContext *s, Jpeg2000Tile *tile, if (tile->codsty[0].mct) mct_decode(s, tile); - if (s->cdef[0] < 0) { - for (x = 0; x < s->ncomponents; x++) - s->cdef[x] = x + 1; - if ((s->ncomponents & 1) == 0) - s->cdef[s->ncomponents-1] = 0; + for (x = 0; x < s->ncomponents; x++) { + if (s->cdef[x] < 0) { + for (x = 0; x < s->ncomponents; x++) { + s->cdef[x] = x + 1; + } + if ((s->ncomponents & 1) == 0) + s->cdef[s->ncomponents-1] = 0; + break; + } } if (s->precision <= 8) { @@ -1351,6 +1368,7 @@ static void jpeg2000_dec_cleanup(Jpeg2000DecoderContext *s) memset(s->codsty, 0, sizeof(s->codsty)); memset(s->qntsty, 0, sizeof(s->qntsty)); s->numXtiles = s->numYtiles = 0; + s->ncomponents = 0; } static int jpeg2000_read_main_headers(Jpeg2000DecoderContext *s) @@ -1405,6 +1423,10 @@ static int jpeg2000_read_main_headers(Jpeg2000DecoderContext *s) switch (marker) { case JPEG2000_SIZ: + if (s->ncomponents) { + av_log(s->avctx, AV_LOG_ERROR, "Duplicate SIZ\n"); + return AVERROR_INVALIDDATA; + } ret = get_siz(s); if (!s->tile) s->numXtiles = s->numYtiles = 0; @@ -1559,7 +1581,7 @@ static int jp2_find_codestream(Jpeg2000DecoderContext *s) int cn = bytestream2_get_be16(&s->g); int av_unused typ = bytestream2_get_be16(&s->g); int asoc = bytestream2_get_be16(&s->g); - if (cn < 4 || asoc < 4) + if (cn < 4 && asoc < 4) s->cdef[cn] = asoc; } } diff --git a/libavcodec/jpeg2000dwt.c b/libavcodec/jpeg2000dwt.c index ceceda36dc..925adea13b 100644 --- a/libavcodec/jpeg2000dwt.c +++ b/libavcodec/jpeg2000dwt.c @@ -540,6 +540,9 @@ int ff_jpeg2000_dwt_init(DWTContext *s, uint16_t border[2][2], int ff_dwt_encode(DWTContext *s, void *t) { + if (s->ndeclevels == 0) + return 0; + switch(s->type){ case FF_DWT97: dwt_encode97_float(s, t); break; @@ -555,6 +558,9 @@ int ff_dwt_encode(DWTContext *s, void *t) int ff_dwt_decode(DWTContext *s, void *t) { + if (s->ndeclevels == 0) + return 0; + switch (s->type) { case FF_DWT97: dwt_decode97_float(s, t); diff --git a/libavcodec/jvdec.c b/libavcodec/jvdec.c index 47e8edcae6..9c4a8d4ca3 100644 --- a/libavcodec/jvdec.c +++ b/libavcodec/jvdec.c @@ -43,6 +43,13 @@ static av_cold int decode_init(AVCodecContext *avctx) { JvContext *s = avctx->priv_data; + if (!avctx->width || !avctx->height || + (avctx->width & 7) || (avctx->height & 7)) { + av_log(avctx, AV_LOG_ERROR, "Invalid video dimensions: %dx%d\n", + avctx->width, avctx->height); + return AVERROR(EINVAL); + } + s->frame = av_frame_alloc(); if (!s->frame) return AVERROR(ENOMEM); diff --git a/libavcodec/libopenjpegdec.c b/libavcodec/libopenjpegdec.c index 0cf46e613d..33c570fd8a 100644 --- a/libavcodec/libopenjpegdec.c +++ b/libavcodec/libopenjpegdec.c @@ -356,6 +356,15 @@ static int libopenjpeg_decode_frame(AVCodecContext *avctx, goto done; } + for (i = 0; i < image->numcomps; i++) { + if (!image->comps[i].data) { + av_log(avctx, AV_LOG_ERROR, + "Image component %d contains no data.\n", i); + ret = AVERROR_INVALIDDATA; + goto done; + } + } + desc = av_pix_fmt_desc_get(avctx->pix_fmt); pixel_size = desc->comp[0].step_minus1 + 1; ispacked = libopenjpeg_ispacked(avctx->pix_fmt); diff --git a/libavcodec/libopenjpegenc.c b/libavcodec/libopenjpegenc.c index 66633f4ad2..458cf7c2c1 100644 --- a/libavcodec/libopenjpegenc.c +++ b/libavcodec/libopenjpegenc.c @@ -164,6 +164,9 @@ static opj_image_t *mj2_create_image(AVCodecContext *avctx, opj_cparameters_t *p img = opj_image_create(numcomps, cmptparm, color_space); + if (!img) + return NULL; + // x0, y0 is the top left corner of the image // x1, y1 is the width, height of the reference grid img->x0 = 0; diff --git a/libavcodec/libopusenc.c b/libavcodec/libopusenc.c index 6bb48628ab..1d665b9b7c 100644 --- a/libavcodec/libopusenc.c +++ b/libavcodec/libopusenc.c @@ -326,7 +326,7 @@ static int libopus_encode(AVCodecContext *avctx, AVPacket *avpkt, } else audio = frame->data[0]; } else { - if (!opus->afq.remaining_samples) + if (!opus->afq.remaining_samples || (!opus->afq.frame_alloc && !opus->afq.frame_count)) return 0; audio = opus->samples; memset(audio, 0, opus->opts.packet_size * sample_size); diff --git a/libavcodec/libshine.c b/libavcodec/libshine.c index 48333bb3c7..27c1a5f43f 100644 --- a/libavcodec/libshine.c +++ b/libavcodec/libshine.c @@ -71,7 +71,7 @@ static int libshine_encode_frame(AVCodecContext *avctx, AVPacket *avpkt, SHINEContext *s = avctx->priv_data; MPADecodeHeader hdr; unsigned char *data; - long written; + int written; int ret, len; if (frame) diff --git a/libavcodec/libtheoraenc.c b/libavcodec/libtheoraenc.c index 4c90822439..36d48fbbb3 100644 --- a/libavcodec/libtheoraenc.c +++ b/libavcodec/libtheoraenc.c @@ -108,6 +108,8 @@ static int get_stats(AVCodecContext *avctx, int eos) // libtheora generates a summary header at the end memcpy(h->stats, buf, bytes); avctx->stats_out = av_malloc(b64_size); + if (!avctx->stats_out) + return AVERROR(ENOMEM); av_base64_encode(avctx->stats_out, b64_size, h->stats, h->stats_offset); } return 0; diff --git a/libavcodec/libutvideodec.cpp b/libavcodec/libutvideodec.cpp index e4b87a8bbc..93fbcb4a51 100644 --- a/libavcodec/libutvideodec.cpp +++ b/libavcodec/libutvideodec.cpp @@ -222,9 +222,19 @@ static int utvideo_decode_frame(AVCodecContext *avctx, void *data, pic->data[0] = utv->buffer + utv->buf_size + pic->linesize[0]; break; } + pic->width = w; + pic->height = h; + pic->format = avctx->pix_fmt; + + if (avctx->refcounted_frames) { + int ret = av_frame_ref((AVFrame*)data, pic); + if (ret < 0) + return ret; + } else { + av_frame_move_ref((AVFrame*)data, pic); + } *got_frame = 1; - av_frame_move_ref((AVFrame*)data, pic); return avpkt->size; } diff --git a/libavcodec/libvpxenc.c b/libavcodec/libvpxenc.c index c69acc00ef..d62a8037cd 100644 --- a/libavcodec/libvpxenc.c +++ b/libavcodec/libvpxenc.c @@ -441,9 +441,10 @@ static av_cold int vpx_init(AVCodecContext *avctx, codecctl_int(avctx, VP8E_SET_ARNR_STRENGTH, ctx->arnr_strength); if (ctx->arnr_type >= 0) codecctl_int(avctx, VP8E_SET_ARNR_TYPE, ctx->arnr_type); - codecctl_int(avctx, VP8E_SET_NOISE_SENSITIVITY, avctx->noise_reduction); - if (avctx->codec_id == AV_CODEC_ID_VP8) + if (avctx->codec_id == AV_CODEC_ID_VP8) { + codecctl_int(avctx, VP8E_SET_NOISE_SENSITIVITY, avctx->noise_reduction); codecctl_int(avctx, VP8E_SET_TOKEN_PARTITIONS, av_log2(avctx->slices)); + } #if FF_API_MPV_OPT FF_DISABLE_DEPRECATION_WARNINGS if (avctx->mb_threshold) { diff --git a/libavcodec/mdec.c b/libavcodec/mdec.c index 051adaefe2..5fd06f4aa6 100644 --- a/libavcodec/mdec.c +++ b/libavcodec/mdec.c @@ -88,7 +88,12 @@ static inline int mdec_decode_block_intra(MDECContext *a, int16_t *block, int n) if (level == 127) { break; } else if (level != 0) { - i += run; + 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]; level = (level * qscale * quant_matrix[j]) >> 3; level = (level ^ SHOW_SBITS(re, &a->gb, 1)) - SHOW_SBITS(re, &a->gb, 1); @@ -98,8 +103,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; @@ -110,10 +120,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/microdvddec.c b/libavcodec/microdvddec.c index 96034a042a..9035892205 100644 --- a/libavcodec/microdvddec.c +++ b/libavcodec/microdvddec.c @@ -164,6 +164,8 @@ static char *microdvd_load_tags(struct microdvd_tag *tags, char *s) /* Position */ case 'P': + if (!*s) + break; tag.persistent = MICRODVD_PERSISTENT_ON; tag.data1 = (*s++ == '1'); if (*s != '}') 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/mjpegdec.c b/libavcodec/mjpegdec.c index a29a533826..bc87c1ef0e 100644 --- a/libavcodec/mjpegdec.c +++ b/libavcodec/mjpegdec.c @@ -96,6 +96,15 @@ static void parse_avid(MJpegDecodeContext *s, uint8_t *buf, int len) av_log(s->avctx, AV_LOG_INFO, "AVID: len:%d %d\n", len, len > 14 ? buf[12] : -1); } +static void init_idct(AVCodecContext *avctx) +{ + MJpegDecodeContext *s = avctx->priv_data; + + ff_idctdsp_init(&s->idsp, avctx); + ff_init_scantable(s->idsp.idct_permutation, &s->scantable, + ff_zigzag_direct); +} + av_cold int ff_mjpeg_decode_init(AVCodecContext *avctx) { MJpegDecodeContext *s = avctx->priv_data; @@ -110,9 +119,7 @@ av_cold int ff_mjpeg_decode_init(AVCodecContext *avctx) s->avctx = avctx; ff_blockdsp_init(&s->bdsp, avctx); ff_hpeldsp_init(&s->hdsp, avctx->flags); - ff_idctdsp_init(&s->idsp, avctx); - ff_init_scantable(s->idsp.idct_permutation, &s->scantable, - ff_zigzag_direct); + init_idct(avctx); s->buffer_size = 0; s->buffer = NULL; s->start_code = -1; @@ -182,7 +189,7 @@ int ff_mjpeg_decode_dqt(MJpegDecodeContext *s) s->quant_matrixes[index][s->scantable.permutated[8]]) >> 1; av_log(s->avctx, AV_LOG_DEBUG, "qscale[%d]: %d\n", index, s->qscale[index]); - len -= 65; + len -= 1 + 64 * (1+pr); } return 0; } @@ -254,7 +261,6 @@ int ff_mjpeg_decode_sof(MJpegDecodeContext *s) /* XXX: verify len field validity */ len = get_bits(&s->gb, 16); - s->avctx->bits_per_raw_sample = bits = get_bits(&s->gb, 8); if (bits > 16 || bits < 1) { @@ -262,6 +268,11 @@ int ff_mjpeg_decode_sof(MJpegDecodeContext *s) return AVERROR_INVALIDDATA; } + if (s->avctx->bits_per_raw_sample != bits) { + av_log(s->avctx, AV_LOG_INFO, "Changeing bps to %d\n", bits); + s->avctx->bits_per_raw_sample = bits; + init_idct(s->avctx); + } if (s->pegasus_rct) bits = 9; if (bits == 9 && !s->pegasus_rct) @@ -561,9 +572,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->palette_index && 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->palette_index && s->bits <= 8) s->avctx->pix_fmt = AV_PIX_FMT_PAL8; else if (s->bits <= 8) s->avctx->pix_fmt = AV_PIX_FMT_GRAY8; @@ -595,7 +609,8 @@ unk_pixfmt: av_log(s->avctx, AV_LOG_DEBUG, "decode_sof0: error, len(%d) mismatch\n", len); } - if (s->rgb && !s->lossless && !s->ls) { + if ((s->rgb && !s->lossless && !s->ls) || + (!s->rgb && s->ls && s->nb_components > 1)) { av_log(s->avctx, AV_LOG_ERROR, "Unsupported coding and pixel format combination\n"); return AVERROR_PATCHWELCOME; } @@ -960,7 +975,7 @@ static int ljpeg_decode_rgb_scan(MJpegDecodeContext *s, int nb_components, int p return -1; left[i] = buffer[mb_x][i] = - mask & (pred + (dc << point_transform)); + mask & (pred + (dc * (1 << point_transform))); } if (s->restart_interval && !--s->restart_count) { @@ -968,7 +983,14 @@ static int ljpeg_decode_rgb_scan(MJpegDecodeContext *s, int nb_components, int p skip_bits(&s->gb, 16); /* skip RSTn */ } } - if (s->nb_components == 4) { + if (s->rct && s->nb_components == 4) { + for (mb_x = 0; mb_x < s->mb_width; mb_x++) { + ptr[4*mb_x + 2] = buffer[mb_x][0] - ((buffer[mb_x][1] + buffer[mb_x][2] - 0x200) >> 2); + ptr[4*mb_x + 1] = buffer[mb_x][1] + ptr[4*mb_x + 2]; + ptr[4*mb_x + 3] = buffer[mb_x][2] + ptr[4*mb_x + 2]; + ptr[4*mb_x + 0] = buffer[mb_x][3]; + } + } else if (s->nb_components == 4) { for(i=0; icomp_index[i]; if (s->bits <= 8) { @@ -1059,7 +1081,10 @@ static int ljpeg_decode_yuv_scan(MJpegDecodeContext *s, int predictor, dc = mjpeg_decode_dc(s, s->dc_index[i]); if(dc == 0xFFFFF) return -1; - if(bits<=8){ + if ( h * mb_x + x >= s->width + || v * mb_y + y >= s->height) { + // Nothing to do + } else if (bits<=8) { 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){ @@ -1127,7 +1152,10 @@ static int ljpeg_decode_yuv_scan(MJpegDecodeContext *s, int predictor, dc = mjpeg_decode_dc(s, s->dc_index[i]); if(dc == 0xFFFFF) return -1; - if(bits<=8){ + if ( h * mb_x + x >= s->width + || v * mb_y + y >= s->height) { + // Nothing to do + } else if (bits<=8) { ptr = s->picture_ptr->data[c] + (linesize * (v * mb_y + y)) + (h * mb_x + x); //FIXME optimize this crap @@ -1195,7 +1223,7 @@ static int mjpeg_decode_scan(MJpegDecodeContext *s, int nb_components, int Ah, int mb_bitmask_size, const AVFrame *reference) { - int i, mb_x, mb_y; + int i, mb_x, mb_y, chroma_h_shift, chroma_v_shift, chroma_width, chroma_height; uint8_t *data[MAX_COMPONENTS]; const uint8_t *reference_data[MAX_COMPONENTS]; int linesize[MAX_COMPONENTS]; @@ -1212,6 +1240,11 @@ static int mjpeg_decode_scan(MJpegDecodeContext *s, int nb_components, int Ah, s->restart_count = 0; + av_pix_fmt_get_chroma_sub_sample(s->avctx->pix_fmt, &chroma_h_shift, + &chroma_v_shift); + chroma_width = FF_CEIL_RSHIFT(s->width, chroma_h_shift); + chroma_height = FF_CEIL_RSHIFT(s->height, chroma_v_shift); + for (i = 0; i < nb_components; i++) { int c = s->comp_index[i]; data[c] = s->picture_ptr->data[c]; @@ -1248,13 +1281,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) < ((c == 1) || (c == 2) ? chroma_width : s->width) + && 8*(v * mb_y + y) < ((c == 1) || (c == 2) ? chroma_height : 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->bdsp.clear_block(s->block); if (decode_block(s, s->block, i, s->dc_index[i], s->ac_index[i], @@ -1263,9 +1301,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->idsp.idct_put(ptr, linesize[c], s->block); - if (s->bits & 7) - shift_output(s, ptr, linesize[c]); + if (ptr) { + s->idsp.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) + @@ -1317,12 +1357,10 @@ static int mjpeg_decode_scan_progressive_ac(MJpegDecodeContext *s, int ss, return AVERROR_INVALIDDATA; } - if (!Al) { - // s->coefs_finished is a bitmask for coefficients coded - // ss and se are parameters telling start and end coefficients - s->coefs_finished[c] |= (2ULL << se) - (1ULL << ss); - last_scan = !~s->coefs_finished[c]; - } + // s->coefs_finished is a bitmask for coefficients coded + // ss and se are parameters telling start and end coefficients + s->coefs_finished[c] |= (2ULL << se) - (1ULL << ss); + last_scan = !Al && !~s->coefs_finished[c]; if (s->interlaced && s->bottom_field) data += linesize >> 1; @@ -1902,8 +1940,12 @@ int ff_mjpeg_find_marker(MJpegDecodeContext *s, while (b < t) { uint8_t x = src[b++]; put_bits(&pb, 8, x); - if (x == 0xFF) { + if (x == 0xFF && b < t) { 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--; } diff --git a/libavcodec/mjpegenc_common.c b/libavcodec/mjpegenc_common.c index 8a5b99f227..1517bdce9e 100644 --- a/libavcodec/mjpegenc_common.c +++ b/libavcodec/mjpegenc_common.c @@ -117,14 +117,24 @@ static void jpeg_put_comments(AVCodecContext *avctx, PutBitContext *p) uint8_t *ptr; if (avctx->sample_aspect_ratio.num > 0 && avctx->sample_aspect_ratio.den > 0) { + AVRational sar = avctx->sample_aspect_ratio; + + if (sar.num > 65535 || sar.den > 65535) { + if (!av_reduce(&sar.num, &sar.den, avctx->sample_aspect_ratio.num, avctx->sample_aspect_ratio.den, 65535)) + av_log(avctx, AV_LOG_WARNING, + "Cannot store exact aspect ratio %d:%d\n", + avctx->sample_aspect_ratio.num, + avctx->sample_aspect_ratio.den); + } + /* JFIF header */ put_marker(p, APP0); put_bits(p, 16, 16); avpriv_put_string(p, "JFIF", 1); /* this puts the trailing zero-byte too */ put_bits(p, 16, 0x0102); /* v 1.02 */ put_bits(p, 8, 0); /* units type: 0 - aspect ratio */ - put_bits(p, 16, avctx->sample_aspect_ratio.num); - put_bits(p, 16, avctx->sample_aspect_ratio.den); + put_bits(p, 16, sar.num); + put_bits(p, 16, sar.den); put_bits(p, 8, 0); /* thumbnail width */ put_bits(p, 8, 0); /* thumbnail height */ } @@ -337,20 +347,30 @@ void ff_mjpeg_escape_FF(PutBitContext *pb, int start) } } -void ff_mjpeg_encode_stuffing(MpegEncContext *s) +int ff_mjpeg_encode_stuffing(MpegEncContext *s) { int i; PutBitContext *pbc = &s->pb; int mb_y = s->mb_y - !s->mb_x; + int ret = ff_mpv_reallocate_putbitbuffer(s, put_bits_count(&s->pb) / 8 + 100, + put_bits_count(&s->pb) / 4 + 1000); + if (ret < 0) { + av_log(s->avctx, AV_LOG_ERROR, "Buffer reallocation failed\n"); + goto fail; + } + ff_mjpeg_escape_FF(pbc, s->esc_pos); if((s->avctx->active_thread_type & FF_THREAD_SLICE) && mb_y < s->mb_height) put_marker(pbc, RST0 + (mb_y&7)); s->esc_pos = put_bits_count(pbc) >> 3; +fail: for(i=0; i<3; i++) s->last_dc[i] = 128 << s->intra_dc_precision; + + return ret; } void ff_mjpeg_encode_picture_trailer(PutBitContext *pb, int header_bits) diff --git a/libavcodec/mjpegenc_common.h b/libavcodec/mjpegenc_common.h index 38b9b3f9f0..87f150550d 100644 --- a/libavcodec/mjpegenc_common.h +++ b/libavcodec/mjpegenc_common.h @@ -34,7 +34,7 @@ void ff_mjpeg_encode_picture_header(AVCodecContext *avctx, PutBitContext *pb, uint16_t chroma_intra_matrix[64]); void ff_mjpeg_encode_picture_trailer(PutBitContext *pb, int header_bits); void ff_mjpeg_escape_FF(PutBitContext *pb, int start); -void ff_mjpeg_encode_stuffing(MpegEncContext *s); +int ff_mjpeg_encode_stuffing(MpegEncContext *s); void ff_mjpeg_init_hvsample(AVCodecContext *avctx, int hsample[3], int vsample[3]); void ff_mjpeg_encode_dc(PutBitContext *pb, int val, diff --git a/libavcodec/mmvideo.c b/libavcodec/mmvideo.c index 9a7c10c3ab..8b04965d59 100644 --- a/libavcodec/mmvideo.c +++ b/libavcodec/mmvideo.c @@ -61,6 +61,13 @@ static av_cold int mm_decode_init(AVCodecContext *avctx) avctx->pix_fmt = AV_PIX_FMT_PAL8; + if (!avctx->width || !avctx->height || + (avctx->width & 1) || (avctx->height & 1)) { + av_log(avctx, AV_LOG_ERROR, "Invalid video dimensions: %dx%d\n", + avctx->width, avctx->height); + return AVERROR(EINVAL); + } + s->frame = av_frame_alloc(); if (!s->frame) return AVERROR(ENOMEM); diff --git a/libavcodec/motion_est.c b/libavcodec/motion_est.c index 901fafdf26..100e503eb3 100644 --- a/libavcodec/motion_est.c +++ b/libavcodec/motion_est.c @@ -906,7 +906,7 @@ void ff_estimate_p_frame_motion(MpegEncContext * s, c->penalty_factor = get_penalty_factor(s->lambda, s->lambda2, c->avctx->me_cmp); c->sub_penalty_factor= get_penalty_factor(s->lambda, s->lambda2, c->avctx->me_sub_cmp); c->mb_penalty_factor = get_penalty_factor(s->lambda, s->lambda2, c->avctx->mb_cmp); - c->current_mv_penalty= c->mv_penalty[s->f_code] + MAX_MV; + c->current_mv_penalty= c->mv_penalty[s->f_code] + MAX_DMV; get_limits(s, 16*mb_x, 16*mb_y); c->skip=0; @@ -1082,7 +1082,7 @@ int ff_pre_estimate_p_frame_motion(MpegEncContext * s, av_assert0(s->quarter_sample==0 || s->quarter_sample==1); c->pre_penalty_factor = get_penalty_factor(s->lambda, s->lambda2, c->avctx->me_pre_cmp); - c->current_mv_penalty= c->mv_penalty[s->f_code] + MAX_MV; + c->current_mv_penalty= c->mv_penalty[s->f_code] + MAX_DMV; get_limits(s, 16*mb_x, 16*mb_y); c->skip=0; @@ -1131,7 +1131,7 @@ static int estimate_motion_b(MpegEncContext *s, int mb_x, int mb_y, const int shift= 1+s->quarter_sample; const int mot_stride = s->mb_stride; const int mot_xy = mb_y*mot_stride + mb_x; - uint8_t * const mv_penalty= c->mv_penalty[f_code] + MAX_MV; + uint8_t * const mv_penalty= c->mv_penalty[f_code] + MAX_DMV; int mv_scale; c->penalty_factor = get_penalty_factor(s->lambda, s->lambda2, c->avctx->me_cmp); @@ -1205,8 +1205,8 @@ static inline int check_bidir_mv(MpegEncContext * s, //FIXME better f_code prediction (max mv & distance) //FIXME pointers MotionEstContext * const c= &s->me; - uint8_t * const mv_penalty_f= c->mv_penalty[s->f_code] + MAX_MV; // f_code of the prev frame - uint8_t * const mv_penalty_b= c->mv_penalty[s->b_code] + MAX_MV; // f_code of the prev frame + uint8_t * const mv_penalty_f= c->mv_penalty[s->f_code] + MAX_DMV; // f_code of the prev frame + uint8_t * const mv_penalty_b= c->mv_penalty[s->b_code] + MAX_DMV; // f_code of the prev frame int stride= c->stride; uint8_t *dest_y = c->scratchpad; uint8_t *ptr; @@ -1419,7 +1419,7 @@ static inline int direct_search(MpegEncContext * s, int mb_x, int mb_y) int mx, my, xmin, xmax, ymin, ymax; int16_t (*mv_table)[2]= s->b_direct_mv_table; - c->current_mv_penalty= c->mv_penalty[1] + MAX_MV; + c->current_mv_penalty= c->mv_penalty[1] + MAX_DMV; ymin= xmin=(-32)>>shift; ymax= xmax= 31>>shift; @@ -1555,11 +1555,11 @@ void ff_estimate_b_frame_motion(MpegEncContext * s, if(s->flags & CODEC_FLAG_INTERLACED_ME){ //FIXME mb type penalty c->skip=0; - c->current_mv_penalty= c->mv_penalty[s->f_code] + MAX_MV; + c->current_mv_penalty= c->mv_penalty[s->f_code] + MAX_DMV; fimin= interlaced_search(s, 0, s->b_field_mv_table[0], s->b_field_select_table[0], s->b_forw_mv_table[xy][0], s->b_forw_mv_table[xy][1], 0); - c->current_mv_penalty= c->mv_penalty[s->b_code] + MAX_MV; + c->current_mv_penalty= c->mv_penalty[s->b_code] + MAX_DMV; bimin= interlaced_search(s, 2, s->b_field_mv_table[1], s->b_field_select_table[1], s->b_back_mv_table[xy][0], s->b_back_mv_table[xy][1], 0); diff --git a/libavcodec/mpeg12dec.c b/libavcodec/mpeg12dec.c index 78888c7309..be48162969 100644 --- a/libavcodec/mpeg12dec.c +++ b/libavcodec/mpeg12dec.c @@ -1909,7 +1909,7 @@ static int mpeg_decode_slice(MpegEncContext *s, int mb_y, (left && show_bits(&s->gb, FFMIN(left, 23)) && !is_d10) || ((avctx->err_recognition & (AV_EF_BITSTREAM | AV_EF_AGGRESSIVE)) && left > 8)) { av_log(avctx, AV_LOG_ERROR, "end mismatch left=%d %0X\n", - left, show_bits(&s->gb, FFMIN(left, 23))); + left, left>0 ? show_bits(&s->gb, FFMIN(left, 23)) : 0); return -1; } else goto eos; @@ -2133,8 +2133,6 @@ static int mpeg1_decode_sequence(AVCodecContext *avctx, av_log(avctx, AV_LOG_ERROR, "Marker in sequence header missing\n"); return AVERROR_INVALIDDATA; } - s->width = width; - s->height = height; s->avctx->rc_buffer_size = get_bits(&s->gb, 10) * 1024 * 16; skip_bits(&s->gb, 1); @@ -2166,6 +2164,9 @@ static int mpeg1_decode_sequence(AVCodecContext *avctx, return AVERROR_INVALIDDATA; } + s->width = width; + s->height = height; + /* We set MPEG-2 parameters so that it emulates MPEG-1. */ s->progressive_sequence = 1; s->progressive_frame = 1; diff --git a/libavcodec/mpeg12enc.c b/libavcodec/mpeg12enc.c index 9795b7f648..8baa60ee0b 100644 --- a/libavcodec/mpeg12enc.c +++ b/libavcodec/mpeg12enc.c @@ -52,7 +52,7 @@ static const uint8_t svcd_scan_offset_placeholder[] = { 0x81, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, }; -static uint8_t mv_penalty[MAX_FCODE + 1][MAX_MV * 2 + 1]; +static uint8_t mv_penalty[MAX_FCODE + 1][MAX_DMV * 2 + 1]; static uint8_t fcode_tab[MAX_MV * 2 + 1]; static uint8_t uni_mpeg1_ac_vlc_len[64 * 64 * 2]; @@ -144,9 +144,6 @@ static av_cold int encode_init(AVCodecContext *avctx) { MpegEncContext *s = avctx->priv_data; - if (avctx->codec_id == AV_CODEC_ID_MPEG1VIDEO && avctx->height > 2800) - avctx->thread_count = 1; - if (ff_mpv_encode_init(avctx) < 0) return -1; @@ -1051,7 +1048,7 @@ av_cold void ff_mpeg1_encode_init(MpegEncContext *s) } for (f_code = 1; f_code <= MAX_FCODE; f_code++) - for (mv = -MAX_MV; mv <= MAX_MV; mv++) { + for (mv = -MAX_DMV; mv <= MAX_DMV; mv++) { int len; if (mv == 0) { @@ -1074,7 +1071,7 @@ av_cold void ff_mpeg1_encode_init(MpegEncContext *s) 2 + bit_size; } - mv_penalty[f_code][mv + MAX_MV] = len; + mv_penalty[f_code][mv + MAX_DMV] = len; } diff --git a/libavcodec/mpeg4audio.h b/libavcodec/mpeg4audio.h index 0f410455f5..a1f3ffc59b 100644 --- a/libavcodec/mpeg4audio.h +++ b/libavcodec/mpeg4audio.h @@ -101,7 +101,7 @@ enum AudioObjectType { AOT_USAC, ///< N Unified Speech and Audio Coding }; -#define MAX_PCE_SIZE 304 /// 0) x = get_xbits(gb, length); if (!(ctx->divx_version == 500 && ctx->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 */ @@ -881,7 +881,7 @@ int ff_mpeg4_decode_partitions(Mpeg4DecContext *ctx) const int part_a_end = s->pict_type == AV_PICTURE_TYPE_I ? (ER_DC_END | ER_MV_END) : ER_MV_END; mb_num = mpeg4_decode_partition_a(ctx); - if (mb_num < 0) { + if (mb_num <= 0) { ff_er_add_slice(&s->er, s->resync_mb_x, s->resync_mb_y, s->mb_x, s->mb_y, part_a_error); return -1; @@ -1874,6 +1874,10 @@ static int decode_vol_header(Mpeg4DecContext *ctx, GetBitContext *gb) int last = 0; for (i = 0; i < 64; i++) { int j; + if (get_bits_left(gb) < 8) { + av_log(s->avctx, AV_LOG_ERROR, "insufficient data for custom matrix\n"); + return AVERROR_INVALIDDATA; + } v = get_bits(gb, 8); if (v == 0) break; @@ -1897,6 +1901,10 @@ static int decode_vol_header(Mpeg4DecContext *ctx, GetBitContext *gb) int last = 0; for (i = 0; i < 64; i++) { int j; + if (get_bits_left(gb) < 8) { + av_log(s->avctx, AV_LOG_ERROR, "insufficient data for custom matrix\n"); + return AVERROR_INVALIDDATA; + } v = get_bits(gb, 8); if (v == 0) break; diff --git a/libavcodec/mpeg4videoenc.c b/libavcodec/mpeg4videoenc.c index 5751432a31..c47b6e8410 100644 --- a/libavcodec/mpeg4videoenc.c +++ b/libavcodec/mpeg4videoenc.c @@ -1086,7 +1086,7 @@ static void mpeg4_encode_vol_header(MpegEncContext *s, } /* write mpeg4 VOP header */ -void ff_mpeg4_encode_picture_header(MpegEncContext *s, int picture_number) +int ff_mpeg4_encode_picture_header(MpegEncContext *s, int picture_number) { int time_incr; int time_div, time_mod; @@ -1112,6 +1112,12 @@ void ff_mpeg4_encode_picture_header(MpegEncContext *s, int picture_number) time_mod = FFUMOD(s->time, s->avctx->time_base.den); time_incr = time_div - s->last_time_base; av_assert0(time_incr >= 0); + + // This limits the frame duration to max 1 hour + if (time_incr > 3600) { + av_log(s->avctx, AV_LOG_ERROR, "time_incr %d too large\n", time_incr); + return AVERROR(EINVAL); + } while (time_incr--) put_bits(&s->pb, 1, 1); @@ -1137,6 +1143,8 @@ void ff_mpeg4_encode_picture_header(MpegEncContext *s, int picture_number) put_bits(&s->pb, 3, s->f_code); /* fcode_for */ if (s->pict_type == AV_PICTURE_TYPE_B) put_bits(&s->pb, 3, s->b_code); /* fcode_back */ + + return 0; } static av_cold void init_uni_dc_tab(void) diff --git a/libavcodec/mpegaudiodec_template.c b/libavcodec/mpegaudiodec_template.c index bbd07c5f0b..dcbde7c6aa 100644 --- a/libavcodec/mpegaudiodec_template.c +++ b/libavcodec/mpegaudiodec_template.c @@ -428,9 +428,11 @@ static av_cold int decode_init(AVCodecContext * avctx) s->avctx = avctx; +#if USE_FLOATS s->fdsp = avpriv_float_dsp_alloc(avctx->flags & CODEC_FLAG_BITEXACT); if (!s->fdsp) return AVERROR(ENOMEM); +#endif ff_mpadsp_init(&s->mpadsp); @@ -1655,9 +1657,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) @@ -1712,7 +1716,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) @@ -1891,6 +1895,7 @@ static av_cold int decode_init_mp3on4(AVCodecContext * avctx) s->mp3decctx[i]->adu_mode = 1; s->mp3decctx[i]->avctx = avctx; s->mp3decctx[i]->mpadsp = s->mp3decctx[0]->mpadsp; + s->mp3decctx[i]->fdsp = s->mp3decctx[0]->fdsp; } return 0; diff --git a/libavcodec/mpegvideo.c b/libavcodec/mpegvideo.c index f84557b4d3..53d1873a94 100644 --- a/libavcodec/mpegvideo.c +++ b/libavcodec/mpegvideo.c @@ -1286,6 +1286,83 @@ fail: return AVERROR(ENOMEM); } +static void clear_context(MpegEncContext *s) +{ + int i, j, k; + + memset(&s->next_picture, 0, sizeof(s->next_picture)); + memset(&s->last_picture, 0, sizeof(s->last_picture)); + memset(&s->current_picture, 0, sizeof(s->current_picture)); + memset(&s->new_picture, 0, sizeof(s->new_picture)); + + memset(s->thread_context, 0, sizeof(s->thread_context)); + + s->me.map = NULL; + s->me.score_map = NULL; + s->dct_error_sum = NULL; + s->block = NULL; + s->blocks = NULL; + memset(s->pblocks, 0, sizeof(s->pblocks)); + s->ac_val_base = NULL; + s->ac_val[0] = + s->ac_val[1] = + s->ac_val[2] =NULL; + s->edge_emu_buffer = NULL; + s->me.scratchpad = NULL; + s->me.temp = + s->rd_scratchpad = + s->b_scratchpad = + s->obmc_scratchpad = NULL; + + s->parse_context.buffer = NULL; + s->parse_context.buffer_size = 0; + s->parse_context.overread = 0; + s->bitstream_buffer = NULL; + s->allocated_bitstream_buffer_size = 0; + s->picture = NULL; + s->mb_type = NULL; + s->p_mv_table_base = NULL; + s->b_forw_mv_table_base = NULL; + s->b_back_mv_table_base = NULL; + s->b_bidir_forw_mv_table_base = NULL; + s->b_bidir_back_mv_table_base = NULL; + s->b_direct_mv_table_base = NULL; + s->p_mv_table = NULL; + s->b_forw_mv_table = NULL; + s->b_back_mv_table = NULL; + s->b_bidir_forw_mv_table = NULL; + s->b_bidir_back_mv_table = NULL; + s->b_direct_mv_table = NULL; + for (i = 0; i < 2; i++) { + for (j = 0; j < 2; j++) { + for (k = 0; k < 2; k++) { + s->b_field_mv_table_base[i][j][k] = NULL; + s->b_field_mv_table[i][j][k] = NULL; + } + s->b_field_select_table[i][j] = NULL; + s->p_field_mv_table_base[i][j] = NULL; + s->p_field_mv_table[i][j] = NULL; + } + s->p_field_select_table[i] = NULL; + } + + s->dc_val_base = NULL; + s->coded_block_base = NULL; + s->mbintra_table = NULL; + s->cbp_table = NULL; + s->pred_dir_table = NULL; + + s->mbskip_table = NULL; + + s->er.error_status_table = NULL; + s->er.er_temp_buffer = NULL; + s->mb_index2xy = NULL; + s->lambda_table = NULL; + + s->cplx_tab = NULL; + s->bits_tab = NULL; +} + /** * init common structure for both encoder and decoder. * this assumes that some variables like width/height are already set @@ -1297,6 +1374,8 @@ av_cold int ff_mpv_common_init(MpegEncContext *s) s->avctx->active_thread_type & FF_THREAD_SLICE) ? s->avctx->thread_count : 1; + clear_context(s); + if (s->encoding && s->avctx->slices) nb_slices = s->avctx->slices; @@ -1344,10 +1423,6 @@ av_cold int ff_mpv_common_init(MpegEncContext *s) if (!s->picture[i].f) goto fail; } - memset(&s->next_picture, 0, sizeof(s->next_picture)); - memset(&s->last_picture, 0, sizeof(s->last_picture)); - memset(&s->current_picture, 0, sizeof(s->current_picture)); - memset(&s->new_picture, 0, sizeof(s->new_picture)); s->next_picture.f = av_frame_alloc(); if (!s->next_picture.f) goto fail; diff --git a/libavcodec/mpegvideo.h b/libavcodec/mpegvideo.h index cadf6f2450..2c768b732c 100644 --- a/libavcodec/mpegvideo.h +++ b/libavcodec/mpegvideo.h @@ -66,6 +66,7 @@ enum OutputFormat { #define MAX_FCODE 7 #define MAX_MV 4096 +#define MAX_DMV (2*MAX_MV) #define MAX_THREADS 32 #define MAX_PICTURE_COUNT 36 @@ -198,7 +199,7 @@ typedef struct MotionEstContext{ op_pixels_func (*hpel_avg)[4]; qpel_mc_func (*qpel_put)[16]; qpel_mc_func (*qpel_avg)[16]; - uint8_t (*mv_penalty)[MAX_MV*2+1]; ///< amount of bits needed to encode a MV + uint8_t (*mv_penalty)[MAX_DMV*2+1]; ///< amount of bits needed to encode a MV uint8_t *current_mv_penalty; int (*sub_motion_search)(struct MpegEncContext * s, int *mx_ptr, int *my_ptr, int dmin, @@ -773,6 +774,7 @@ void ff_mpv_encode_init_x86(MpegEncContext *s); int ff_mpv_encode_end(AVCodecContext *avctx); int ff_mpv_encode_picture(AVCodecContext *avctx, AVPacket *pkt, const AVFrame *frame, int *got_packet); +int ff_mpv_reallocate_putbitbuffer(MpegEncContext *s, size_t threshold, size_t size_increase); void ff_clean_intra_table_entries(MpegEncContext *s); void ff_mpeg_draw_horiz_band(MpegEncContext *s, int y, int h); @@ -883,7 +885,7 @@ extern const uint8_t ff_aic_dc_scale_table[32]; extern const uint8_t ff_h263_chroma_qscale_table[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 27153cf6a8..2084a3ac75 100644 --- a/libavcodec/mpegvideo_enc.c +++ b/libavcodec/mpegvideo_enc.c @@ -70,7 +70,7 @@ static int sse_mb(MpegEncContext *s); static void denoise_dct_c(MpegEncContext *s, int16_t *block); static int dct_quantize_trellis_c(MpegEncContext *s, int16_t *block, int n, int qscale, int *overflow); -static uint8_t default_mv_penalty[MAX_FCODE + 1][MAX_MV * 2 + 1]; +static uint8_t default_mv_penalty[MAX_FCODE + 1][MAX_DMV * 2 + 1]; static uint8_t default_fcode_tab[MAX_MV * 2 + 1]; const AVOption ff_mpv_generic_options[] = { @@ -315,6 +315,7 @@ av_cold int ff_mpv_encode_init(AVCodecContext *avctx) break; } + avctx->bits_per_raw_sample = av_clip(avctx->bits_per_raw_sample, 0, 8); s->bit_rate = avctx->bit_rate; s->width = avctx->width; s->height = avctx->height; @@ -395,18 +396,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; @@ -2718,6 +2719,40 @@ static void update_mb_info(MpegEncContext *s, int startcode) write_mb_info(s); } +int ff_mpv_reallocate_putbitbuffer(MpegEncContext *s, size_t threshold, size_t size_increase) +{ + if ( s->pb.buf_end - s->pb.buf - (put_bits_count(&s->pb)>>3) < threshold + && s->slice_context_count == 1 + && s->pb.buf == s->avctx->internal->byte_buffer) { + int lastgob_pos = s->ptr_lastgob - s->pb.buf; + int vbv_pos = s->vbv_delay_ptr - s->pb.buf; + + uint8_t *new_buffer = NULL; + int new_buffer_size = 0; + + if ((s->avctx->internal->byte_buffer_size + size_increase) >= INT_MAX/8) { + av_log(s->avctx, AV_LOG_ERROR, "Cannot reallocate putbit buffer\n"); + return AVERROR(ENOMEM); + } + + av_fast_padded_malloc(&new_buffer, &new_buffer_size, + s->avctx->internal->byte_buffer_size + size_increase); + if (!new_buffer) + return AVERROR(ENOMEM); + + memcpy(new_buffer, s->avctx->internal->byte_buffer, s->avctx->internal->byte_buffer_size); + av_free(s->avctx->internal->byte_buffer); + s->avctx->internal->byte_buffer = new_buffer; + s->avctx->internal->byte_buffer_size = new_buffer_size; + rebase_put_bits(&s->pb, new_buffer, new_buffer_size); + s->ptr_lastgob = s->pb.buf + lastgob_pos; + s->vbv_delay_ptr = s->pb.buf + vbv_pos; + } + if (s->pb.buf_end - s->pb.buf - (put_bits_count(&s->pb)>>3) < threshold) + return AVERROR(EINVAL); + return 0; +} + static int encode_thread(AVCodecContext *c, void *arg){ MpegEncContext *s= *(void**)arg; int mb_x, mb_y, pdif = 0; @@ -2794,30 +2829,10 @@ static int encode_thread(AVCodecContext *c, void *arg){ // int d; int dmin= INT_MAX; int dir; + int size_increase = s->avctx->internal->byte_buffer_size/4 + + s->mb_width*MAX_MB_BYTES; - if ( s->pb.buf_end - s->pb.buf - (put_bits_count(&s->pb)>>3) < MAX_MB_BYTES - && s->slice_context_count == 1 - && s->pb.buf == s->avctx->internal->byte_buffer) { - int new_size = s->avctx->internal->byte_buffer_size - + s->avctx->internal->byte_buffer_size/4 - + s->mb_width*MAX_MB_BYTES; - int lastgob_pos = s->ptr_lastgob - s->pb.buf; - int vbv_pos = s->vbv_delay_ptr - s->pb.buf; - - uint8_t *new_buffer = NULL; - int new_buffer_size = 0; - - av_fast_padded_malloc(&new_buffer, &new_buffer_size, new_size); - if (new_buffer) { - memcpy(new_buffer, s->avctx->internal->byte_buffer, s->avctx->internal->byte_buffer_size); - av_free(s->avctx->internal->byte_buffer); - s->avctx->internal->byte_buffer = new_buffer; - s->avctx->internal->byte_buffer_size = new_buffer_size; - rebase_put_bits(&s->pb, new_buffer, new_buffer_size); - s->ptr_lastgob = s->pb.buf + lastgob_pos; - s->vbv_delay_ptr = s->pb.buf + vbv_pos; - } - } + ff_mpv_reallocate_putbitbuffer(s, MAX_MB_BYTES, size_increase); if(s->pb.buf_end - s->pb.buf - (put_bits_count(&s->pb)>>3) < MAX_MB_BYTES){ av_log(s->avctx, AV_LOG_ERROR, "encoded frame too large\n"); return -1; @@ -3704,10 +3719,15 @@ static int encode_picture(MpegEncContext *s, int picture_number) ff_wmv2_encode_picture_header(s, picture_number); else if (CONFIG_MSMPEG4_ENCODER && s->msmpeg4_version) 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_MPEG4_ENCODER && s->h263_pred) { + ret = ff_mpeg4_encode_picture_header(s, picture_number); + if (ret < 0) + return ret; + } 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) @@ -3730,6 +3750,8 @@ static int encode_picture(MpegEncContext *s, int picture_number) } s->avctx->execute(s->avctx, encode_thread, &s->thread_context[0], NULL, context_count, sizeof(void*)); for(i=1; ipb.buf_end == s->thread_context[i]->pb.buf) + set_put_bits_buffer_size(&s->pb, FFMIN(s->thread_context[i]->pb.buf_end - s->pb.buf, INT_MAX/8-32)); merge_context_after_encode(s, s->thread_context[i]); } emms_c(); diff --git a/libavcodec/mpegvideo_motion.c b/libavcodec/mpegvideo_motion.c index e7a585dd5f..e320511947 100644 --- a/libavcodec/mpegvideo_motion.c +++ b/libavcodec/mpegvideo_motion.c @@ -178,7 +178,7 @@ static void gmc_motion(MpegEncContext *s, s->sprite_delta[0][0], s->sprite_delta[0][1], s->sprite_delta[1][0], s->sprite_delta[1][1], a + 1, (1 << (2 * a + 1)) - s->no_rounding, - s->h_edge_pos >> 1, s->v_edge_pos >> 1); + (s->h_edge_pos + 1) >> 1, (s->v_edge_pos + 1) >> 1); ptr = ref_picture[2]; s->mdsp.gmc(dest_cr, ptr, uvlinesize, 8, @@ -186,7 +186,7 @@ static void gmc_motion(MpegEncContext *s, s->sprite_delta[0][0], s->sprite_delta[0][1], s->sprite_delta[1][0], s->sprite_delta[1][1], a + 1, (1 << (2 * a + 1)) - s->no_rounding, - s->h_edge_pos >> 1, s->v_edge_pos >> 1); + (s->h_edge_pos + 1) >> 1, (s->v_edge_pos + 1) >> 1); } static inline int hpel_motion(MpegEncContext *s, 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/mss2.c b/libavcodec/mss2.c index 4d53f8ab8f..ea448dabc5 100644 --- a/libavcodec/mss2.c +++ b/libavcodec/mss2.c @@ -209,8 +209,13 @@ static int decode_555(GetByteContext *gB, uint16_t *dst, int stride, last_symbol = b << 8 | bytestream2_get_byte(gB); else if (b > 129) { repeat = 0; - while (b-- > 130) + while (b-- > 130) { + if (repeat >= (INT_MAX >> 8) - 1) { + av_log(NULL, AV_LOG_ERROR, "repeat overflow\n"); + return AVERROR_INVALIDDATA; + } repeat = (repeat << 8) + bytestream2_get_byte(gB) + 1; + } if (last_symbol == -2) { int skip = FFMIN((unsigned)repeat, dst + w - p); repeat -= skip; diff --git a/libavcodec/nellymoserenc.c b/libavcodec/nellymoserenc.c index 48caba23b9..148dbd9c77 100644 --- a/libavcodec/nellymoserenc.c +++ b/libavcodec/nellymoserenc.c @@ -308,7 +308,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/on2avc.c b/libavcodec/on2avc.c index 01977e5bbc..15b75e6b09 100644 --- a/libavcodec/on2avc.c +++ b/libavcodec/on2avc.c @@ -119,12 +119,12 @@ static int on2avc_decode_band_types(On2AVCContext *c, GetBitContext *gb) run_len = 1; do { run = get_bits(gb, bits_per_sect); + if (run > num_bands - band - run_len) { + av_log(c->avctx, AV_LOG_ERROR, "Invalid band type run\n"); + return AVERROR_INVALIDDATA; + } run_len += run; } while (run == esc_val); - if (band + run_len > num_bands) { - av_log(c->avctx, AV_LOG_ERROR, "Invalid band type run\n"); - return AVERROR_INVALIDDATA; - } for (i = band; i < band + run_len; i++) { c->band_type[i] = band_type; c->band_run_end[i] = band + run_len; @@ -211,9 +211,16 @@ static inline int get_egolomb(GetBitContext *gb) { int v = 4; - while (get_bits1(gb)) v++; + while (get_bits1(gb)) { + v++; + if (v > 30) { + av_log(NULL, AV_LOG_WARNING, "Too large golomb code in get_egolomb.\n"); + v = 30; + break; + } + } - return (1 << v) + get_bits(gb, v); + return (1 << v) + get_bits_long(gb, v); } static int on2avc_decode_pairs(On2AVCContext *c, GetBitContext *gb, float *dst, diff --git a/libavcodec/options_table.h b/libavcodec/options_table.h index 1d5b07884a..9ac67ea4f1 100644 --- a/libavcodec/options_table.h +++ b/libavcodec/options_table.h @@ -103,7 +103,6 @@ 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 }, 0, INT_MAX, A|D|E}, diff --git a/libavcodec/opus_silk.c b/libavcodec/opus_silk.c index 7a89479fb9..4c64cdfce6 100644 --- a/libavcodec/opus_silk.c +++ b/libavcodec/opus_silk.c @@ -824,7 +824,7 @@ static inline void silk_stabilize_lsf(int16_t nlsf[16], int order, const uint16_ /* upper extent */ for (i = order; i > k; i--) - max_center -= min_delta[k]; + max_center -= min_delta[i]; max_center -= min_delta[k] >> 1; /* move apart */ diff --git a/libavcodec/opusdec.c b/libavcodec/opusdec.c index 759eaa529c..ab81de1aa7 100644 --- a/libavcodec/opusdec.c +++ b/libavcodec/opusdec.c @@ -451,6 +451,14 @@ static int opus_decode_packet(AVCodecContext *avctx, void *data, int coded_samples = 0; int decoded_samples = 0; int i, ret; + int delayed_samples = 0; + + for (i = 0; i < c->nb_streams; i++) { + OpusStreamContext *s = &c->streams[i]; + s->out[0] = + s->out[1] = NULL; + delayed_samples = FFMAX(delayed_samples, s->delayed_samples); + } /* decode the header of the first sub-packet to find out the sample count */ if (buf) { @@ -464,7 +472,7 @@ static int opus_decode_packet(AVCodecContext *avctx, void *data, c->streams[0].silk_samplerate = get_silk_samplerate(pkt->config); } - frame->nb_samples = coded_samples + c->streams[0].delayed_samples; + frame->nb_samples = coded_samples + delayed_samples; /* no input or buffered data => nothing to do */ if (!frame->nb_samples) { @@ -534,7 +542,7 @@ static int opus_decode_packet(AVCodecContext *avctx, void *data, memset(frame->extended_data[i], 0, frame->linesize[0]); } - if (c->gain_i) { + if (c->gain_i && decoded_samples > 0) { c->fdsp->vector_fmul_scalar((float*)frame->extended_data[i], (float*)frame->extended_data[i], c->gain, FFALIGN(decoded_samples, 8)); diff --git a/libavcodec/pgssubdec.c b/libavcodec/pgssubdec.c index 36f1f8265a..6603cc2927 100644 --- a/libavcodec/pgssubdec.c +++ b/libavcodec/pgssubdec.c @@ -33,7 +33,7 @@ #include "libavutil/imgutils.h" #include "libavutil/opt.h" -#define RGBA(r,g,b,a) (((a) << 24) | ((r) << 16) | ((g) << 8) | (b)) +#define RGBA(r,g,b,a) (((unsigned)(a) << 24) | ((r) << 16) | ((g) << 8) | (b)) #define MAX_EPOCH_PALETTES 8 // Max 8 allowed per PGS epoch #define MAX_EPOCH_OBJECTS 64 // Max 64 allowed per PGS epoch #define MAX_OBJECT_REFS 2 // Max objects per display set @@ -354,8 +354,14 @@ static int parse_palette_segment(AVCodecContext *avctx, cb = bytestream_get_byte(&buf); alpha = bytestream_get_byte(&buf); - YUV_TO_RGB1(cb, cr); - YUV_TO_RGB2(r, g, b, y); + /* Default to BT.709 colorimetry. In case of <= 576 height use BT.601 */ + if (avctx->height <= 0 || avctx->height > 576) { + YUV_TO_RGB1_CCIR_BT709(cb, cr); + } else { + YUV_TO_RGB1_CCIR(cb, cr); + } + + YUV_TO_RGB2_CCIR(r, g, b, y); av_dlog(avctx, "Color %d := (%d,%d,%d,%d)\n", color_id, r, g, b, alpha); diff --git a/libavcodec/pngdec.c b/libavcodec/pngdec.c index 7e7b2858b3..d5ad14e9bc 100644 --- a/libavcodec/pngdec.c +++ b/libavcodec/pngdec.c @@ -538,6 +538,11 @@ static int decode_ihdr_chunk(AVCodecContext *avctx, PNGDecContext *s, return AVERROR_INVALIDDATA; } + if (s->state & PNG_IHDR) { + av_log(avctx, AV_LOG_ERROR, "Multiple IHDR\n"); + return AVERROR_INVALIDDATA; + } + s->width = s->cur_w = bytestream2_get_be32(&s->gb); s->height = s->cur_h = bytestream2_get_be32(&s->gb); if (av_image_check_size(s->width, s->height, 0, avctx)) { @@ -617,7 +622,7 @@ static int decode_idat_chunk(AVCodecContext *avctx, PNGDecContext *s, } 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 && s->bits_per_pixel == 1) { + } else if (s->bit_depth == 1 && s->bits_per_pixel == 1 && avctx->codec_id != AV_CODEC_ID_APNG) { avctx->pix_fmt = AV_PIX_FMT_MONOBLACK; } else if (s->bit_depth == 8 && s->color_type == PNG_COLOR_TYPE_GRAY_ALPHA) { @@ -804,28 +809,34 @@ static int decode_fctl_chunk(AVCodecContext *avctx, PNGDecContext *s, uint32_t length) { uint32_t sequence_number; + int cur_w, cur_h, x_offset, y_offset, dispose_op, blend_op; if (length != 26) return AVERROR_INVALIDDATA; + if (!(s->state & PNG_IHDR)) { + av_log(avctx, AV_LOG_ERROR, "fctl before IHDR\n"); + return AVERROR_INVALIDDATA; + } + sequence_number = bytestream2_get_be32(&s->gb); - s->cur_w = bytestream2_get_be32(&s->gb); - s->cur_h = bytestream2_get_be32(&s->gb); - s->x_offset = bytestream2_get_be32(&s->gb); - s->y_offset = bytestream2_get_be32(&s->gb); + cur_w = bytestream2_get_be32(&s->gb); + cur_h = bytestream2_get_be32(&s->gb); + x_offset = bytestream2_get_be32(&s->gb); + y_offset = bytestream2_get_be32(&s->gb); bytestream2_skip(&s->gb, 4); /* delay_num (2), delay_den (2) */ - s->dispose_op = bytestream2_get_byte(&s->gb); - s->blend_op = bytestream2_get_byte(&s->gb); + dispose_op = bytestream2_get_byte(&s->gb); + blend_op = bytestream2_get_byte(&s->gb); bytestream2_skip(&s->gb, 4); /* crc */ if (sequence_number == 0 && - (s->cur_w != s->width || - s->cur_h != s->height || - s->x_offset != 0 || - s->y_offset != 0) || - s->cur_w <= 0 || s->cur_h <= 0 || - s->x_offset < 0 || s->y_offset < 0 || - s->cur_w > s->width - s->x_offset|| s->cur_h > s->height - s->y_offset) + (cur_w != s->width || + cur_h != s->height || + x_offset != 0 || + y_offset != 0) || + cur_w <= 0 || cur_h <= 0 || + x_offset < 0 || y_offset < 0 || + cur_w > s->width - x_offset|| cur_h > s->height - y_offset) return AVERROR_INVALIDDATA; /* always (re)start with a clean frame */ @@ -839,6 +850,13 @@ static int decode_fctl_chunk(AVCodecContext *avctx, PNGDecContext *s, s->dispose_op = APNG_DISPOSE_OP_NONE; } + s->cur_w = cur_w; + s->cur_h = cur_h; + s->x_offset = x_offset; + s->y_offset = y_offset; + s->dispose_op = dispose_op; + s->blend_op = blend_op; + return 0; } @@ -963,7 +981,7 @@ static int decode_frame_common(AVCodecContext *avctx, PNGDecContext *s, AVDictionary *metadata = NULL; uint32_t tag, length; int decode_next_dat = 0; - int ret = AVERROR_INVALIDDATA; + int ret; AVFrame *ref; for (;;) { @@ -979,12 +997,14 @@ static int decode_frame_common(AVCodecContext *avctx, PNGDecContext *s, if ( s->state & PNG_ALLIMAGE && avctx->strict_std_compliance <= FF_COMPLIANCE_NORMAL) goto exit_loop; + ret = AVERROR_INVALIDDATA; goto fail; } length = bytestream2_get_be32(&s->gb); if (length > 0x7fffffff || length > bytestream2_get_bytes_left(&s->gb)) { av_log(avctx, AV_LOG_ERROR, "chunk too big\n"); + ret = AVERROR_INVALIDDATA; goto fail; } tag = bytestream2_get_le32(&s->gb); @@ -996,11 +1016,11 @@ static int decode_frame_common(AVCodecContext *avctx, PNGDecContext *s, ((tag >> 24) & 0xff), length); switch (tag) { case MKTAG('I', 'H', 'D', 'R'): - if (decode_ihdr_chunk(avctx, s, length) < 0) + if ((ret = decode_ihdr_chunk(avctx, s, length)) < 0) goto fail; break; case MKTAG('p', 'H', 'Y', 's'): - if (decode_phys_chunk(avctx, s) < 0) + if ((ret = decode_phys_chunk(avctx, s)) < 0) goto fail; break; case MKTAG('f', 'c', 'T', 'L'): @@ -1013,15 +1033,17 @@ static int decode_frame_common(AVCodecContext *avctx, PNGDecContext *s, case MKTAG('f', 'd', 'A', 'T'): if (!CONFIG_APNG_DECODER || avctx->codec_id != AV_CODEC_ID_APNG) goto skip_tag; - if (!decode_next_dat) + if (!decode_next_dat) { + ret = AVERROR_INVALIDDATA; goto fail; + } bytestream2_get_be32(&s->gb); length -= 4; /* fallthrough */ case MKTAG('I', 'D', 'A', 'T'): if (CONFIG_APNG_DECODER && avctx->codec_id == AV_CODEC_ID_APNG && !decode_next_dat) goto skip_tag; - if (decode_idat_chunk(avctx, s, length, p) < 0) + if ((ret = decode_idat_chunk(avctx, s, length, p)) < 0) goto fail; break; case MKTAG('P', 'L', 'T', 'E'): @@ -1046,6 +1068,7 @@ static int decode_frame_common(AVCodecContext *avctx, PNGDecContext *s, if (!(s->state & PNG_ALLIMAGE)) av_log(avctx, AV_LOG_ERROR, "IEND without all image\n"); if (!(s->state & (PNG_ALLIMAGE|PNG_IDAT))) { + ret = AVERROR_INVALIDDATA; goto fail; } bytestream2_skip(&s->gb, 4); /* crc */ @@ -1065,7 +1088,7 @@ exit_loop: /* handle p-frames only if a predecessor frame is available */ ref = s->dispose_op == APNG_DISPOSE_OP_PREVIOUS ? s->previous_picture.f : s->last_picture.f; - if (ref->data[0]) { + if (ref->data[0] && s->last_picture.f->data[0]) { if ( !(avpkt->flags & AV_PKT_FLAG_KEY) && avctx->codec_tag != AV_RL32("MPNG") && ref->width == p->width && ref->height== p->height diff --git a/libavcodec/ppc/idctdsp.c b/libavcodec/ppc/idctdsp.c index 5ef514b51b..ea56a70948 100644 --- a/libavcodec/ppc/idctdsp.c +++ b/libavcodec/ppc/idctdsp.c @@ -209,16 +209,26 @@ static void idct_add_altivec(uint8_t *dest, int stride, int16_t *blk) IDCT; +#if HAVE_BIGENDIAN p0 = vec_lvsl(0, dest); p1 = vec_lvsl(stride, dest); p = vec_splat_u8(-1); perm0 = vec_mergeh(p, p0); perm1 = vec_mergeh(p, p1); +#endif + +#if HAVE_BIGENDIAN +#define GET_TMP2(dest, prm) \ + tmp = vec_ld(0, dest); \ + tmp2 = (vec_s16) vec_perm(tmp, (vec_u8) zero, prm); +#else +#define GET_TMP2(dest, prm) \ + tmp = vec_vsx_ld(0, dest); \ + tmp2 = (vec_s16) vec_mergeh(tmp, (vec_u8) zero) +#endif #define ADD(dest, src, perm) \ - /* *(uint64_t *) &tmp = *(uint64_t *) dest; */ \ - tmp = vec_ld(0, dest); \ - tmp2 = (vec_s16) vec_perm(tmp, (vec_u8) zero, perm); \ + GET_TMP2(dest, perm); \ tmp3 = vec_adds(tmp2, src); \ tmp = vec_packsu(tmp3, tmp3); \ vec_ste((vec_u32) tmp, 0, (unsigned int *) dest); \ diff --git a/libavcodec/ppc/mpegvideoencdsp.c b/libavcodec/ppc/mpegvideoencdsp.c index e91ba5d25f..3e6765ce15 100644 --- a/libavcodec/ppc/mpegvideoencdsp.c +++ b/libavcodec/ppc/mpegvideoencdsp.c @@ -55,7 +55,7 @@ static int pix_norm1_altivec(uint8_t *pix, int line_size) /* Sum up the four partial sums, and put the result into s. */ sum = vec_sums((vector signed int) sv, (vector signed int) zero); sum = vec_splat(sum, 3); - vec_vsx_st(sum, 0, &s); + vec_ste(sum, 0, &s); return s; } #else @@ -113,7 +113,7 @@ static int pix_sum_altivec(uint8_t *pix, int line_size) /* Sum up the four partial sums, and put the result into s. */ sumdiffs = vec_sums((vector signed int) sad, (vector signed int) zero); sumdiffs = vec_splat(sumdiffs, 3); - vec_vsx_st(sumdiffs, 0, &s); + vec_ste(sumdiffs, 0, &s); return s; } #else diff --git a/libavcodec/ppc/vc1dsp_altivec.c b/libavcodec/ppc/vc1dsp_altivec.c index 2128b56d05..35bb280842 100644 --- a/libavcodec/ppc/vc1dsp_altivec.c +++ b/libavcodec/ppc/vc1dsp_altivec.c @@ -304,16 +304,23 @@ static void vc1_inv_trans_8x4_altivec(uint8_t *dest, int stride, int16_t *block) src2 = vec_pack(s2, sA); src3 = vec_pack(s3, sB); +#if HAVE_BIGENDIAN p0 = vec_lvsl (0, dest); p1 = vec_lvsl (stride, dest); p = vec_splat_u8 (-1); perm0 = vec_mergeh (p, p0); perm1 = vec_mergeh (p, p1); +#define GET_TMP2(dst, p) \ + tmp = vec_ld (0, dest); \ + tmp2 = (vector signed short)vec_perm (tmp, vec_splat_u8(0), p); +#else +#define GET_TMP2(dst,p) \ + tmp = vec_vsx_ld (0, dst); \ + tmp2 = (vector signed short)vec_mergeh (tmp, vec_splat_u8(0)); +#endif #define ADD(dest,src,perm) \ - /* *(uint64_t *)&tmp = *(uint64_t *)dest; */ \ - tmp = vec_ld (0, dest); \ - tmp2 = (vector signed short)vec_perm (tmp, vec_splat_u8(0), perm); \ + GET_TMP2(dest, perm); \ tmp3 = vec_adds (tmp2, src); \ tmp = vec_packsu (tmp3, tmp3); \ vec_ste ((vector unsigned int)tmp, 0, (unsigned int *)dest); \ diff --git a/libavcodec/ppc/vp3dsp_altivec.c b/libavcodec/ppc/vp3dsp_altivec.c index 9d81b3f265..4a367b655e 100644 --- a/libavcodec/ppc/vp3dsp_altivec.c +++ b/libavcodec/ppc/vp3dsp_altivec.c @@ -32,8 +32,13 @@ static const vec_s16 constants = {0, 64277, 60547, 54491, 46341, 36410, 25080, 12785}; +#if HAVE_BIGENDIAN static const vec_u8 interleave_high = {0, 1, 16, 17, 4, 5, 20, 21, 8, 9, 24, 25, 12, 13, 28, 29}; +#else +static const vec_u8 interleave_high = + {2, 3, 18, 19, 6, 7, 22, 23, 10, 11, 26, 27, 14, 15, 30, 31}; +#endif #define IDCT_START \ vec_s16 A, B, C, D, Ad, Bd, Cd, Dd, E, F, G, H;\ @@ -156,9 +161,18 @@ static void vp3_idct_add_altivec(uint8_t *dst, int stride, int16_t block[64]) TRANSPOSE8(b0, b1, b2, b3, b4, b5, b6, b7); IDCT_1D(ADD8, SHIFT4) -#define ADD(a)\ +#if HAVE_BIGENDIAN +#define GET_VDST16\ vdst = vec_ld(0, dst);\ - vdst_16 = (vec_s16)vec_perm(vdst, zero_u8v, vdst_mask);\ + vdst_16 = (vec_s16)vec_perm(vdst, zero_u8v, vdst_mask); +#else +#define GET_VDST16\ + vdst = vec_vsx_ld(0,dst);\ + vdst_16 = (vec_s16)vec_mergeh(vdst, zero_u8v); +#endif + +#define ADD(a)\ + GET_VDST16;\ vdst_16 = vec_adds(a, vdst_16);\ t = vec_packsu(vdst_16, vdst_16);\ vec_ste((vec_u32)t, 0, (unsigned int *)dst);\ diff --git a/libavcodec/ppc/vp8dsp_altivec.c b/libavcodec/ppc/vp8dsp_altivec.c index 91ff8cc8ff..23e4ace7da 100644 --- a/libavcodec/ppc/vp8dsp_altivec.c +++ b/libavcodec/ppc/vp8dsp_altivec.c @@ -59,17 +59,30 @@ static const vec_s8 h_subpel_filters_outer[3] = vec_s8 filter_outerh = h_subpel_filters_outer[(i)>>1]; \ vec_s8 filter_outerl = vec_sld(filter_outerh, filter_outerh, 2) +#if HAVE_BIGENDIAN +#define GET_PIXHL(offset) \ + a = vec_ld((offset)-is6tap-1, src); \ + b = vec_ld((offset)-is6tap-1+15, src); \ + pixh = vec_perm(a, b, permh##offset); \ + pixl = vec_perm(a, b, perml##offset) + +#define GET_OUTER(offset) outer = vec_perm(a, b, perm_6tap##offset) +#else +#define GET_PIXHL(offset) \ + a = vec_vsx_ld((offset)-is6tap-1, src); \ + pixh = vec_perm(a, a, perm_inner); \ + pixl = vec_perm(a, a, vec_add(perm_inner, vec_splat_u8(4))) + +#define GET_OUTER(offset) outer = vec_perm(a, a, perm_outer) +#endif + #define FILTER_H(dstv, off) \ - a = vec_ld((off)-is6tap-1, src); \ - b = vec_ld((off)-is6tap-1+15, src); \ -\ - pixh = vec_perm(a, b, permh##off); \ - pixl = vec_perm(a, b, perml##off); \ + GET_PIXHL(off); \ filth = vec_msum(filter_inner, pixh, c64); \ filtl = vec_msum(filter_inner, pixl, c64); \ \ if (is6tap) { \ - outer = vec_perm(a, b, perm_6tap##off); \ + GET_OUTER(off); \ filth = vec_msum(filter_outerh, outer, filth); \ filtl = vec_msum(filter_outerl, outer, filtl); \ } \ @@ -84,9 +97,12 @@ void put_vp8_epel_h_altivec_core(uint8_t *dst, ptrdiff_t dst_stride, int h, int mx, int w, int is6tap) { LOAD_H_SUBPEL_FILTER(mx-1); - vec_u8 align_vec0, align_vec8, permh0, permh8, filt; +#if HAVE_BIGENDIAN + vec_u8 align_vec0, align_vec8, permh0, permh8; vec_u8 perm_6tap0, perm_6tap8, perml0, perml8; - vec_u8 a, b, pixh, pixl, outer; + vec_u8 b; +#endif + vec_u8 filt, a, pixh, pixl, outer; vec_s16 f16h, f16l; vec_s32 filth, filtl; @@ -97,6 +113,7 @@ void put_vp8_epel_h_altivec_core(uint8_t *dst, ptrdiff_t dst_stride, vec_s32 c64 = vec_sl(vec_splat_s32(1), vec_splat_u32(6)); vec_u16 c7 = vec_splat_u16(7); +#if HAVE_BIGENDIAN align_vec0 = vec_lvsl( -is6tap-1, src); align_vec8 = vec_lvsl(8-is6tap-1, src); @@ -107,6 +124,7 @@ void put_vp8_epel_h_altivec_core(uint8_t *dst, ptrdiff_t dst_stride, perml8 = vec_perm(align_vec8, align_vec8, perm_inner); perm_6tap0 = vec_perm(align_vec0, align_vec0, perm_outer); perm_6tap8 = vec_perm(align_vec8, align_vec8, perm_outer); +#endif while (h --> 0) { FILTER_H(f16h, 0); @@ -164,6 +182,12 @@ static const vec_u8 v_subpel_filters[7] = dstv = vec_adds(dstv, c64); \ dstv = vec_sra(dstv, c7) +#if HAVE_BIGENDIAN +#define LOAD_HL(off, s, perm) load_with_perm_vec(off, s, perm) +#else +#define LOAD_HL(off, s, perm) vec_mergeh(vec_vsx_ld(off,s), vec_vsx_ld(off+8,s)) +#endif + static av_always_inline void put_vp8_epel_v_altivec_core(uint8_t *dst, ptrdiff_t dst_stride, uint8_t *src, ptrdiff_t src_stride, @@ -175,6 +199,7 @@ void put_vp8_epel_v_altivec_core(uint8_t *dst, ptrdiff_t dst_stride, vec_s16 c64 = vec_sl(vec_splat_s16(1), vec_splat_u16(6)); vec_u16 c7 = vec_splat_u16(7); +#if HAVE_BIGENDIAN // we want pixels 0-7 to be in the even positions and 8-15 in the odd, // so combine this permute with the alignment permute vector align_vech = vec_lvsl(0, src); @@ -183,22 +208,23 @@ void put_vp8_epel_v_altivec_core(uint8_t *dst, ptrdiff_t dst_stride, perm_vec = vec_mergeh(align_vech, align_vecl); else perm_vec = vec_mergeh(align_vech, align_vech); +#endif if (is6tap) - s0 = load_with_perm_vec(-2*src_stride, src, perm_vec); - s1 = load_with_perm_vec(-1*src_stride, src, perm_vec); - s2 = load_with_perm_vec( 0*src_stride, src, perm_vec); - s3 = load_with_perm_vec( 1*src_stride, src, perm_vec); + s0 = LOAD_HL(-2*src_stride, src, perm_vec); + s1 = LOAD_HL(-1*src_stride, src, perm_vec); + s2 = LOAD_HL( 0*src_stride, src, perm_vec); + s3 = LOAD_HL( 1*src_stride, src, perm_vec); if (is6tap) - s4 = load_with_perm_vec( 2*src_stride, src, perm_vec); + s4 = LOAD_HL( 2*src_stride, src, perm_vec); src += (2+is6tap)*src_stride; while (h --> 0) { if (is6tap) - s5 = load_with_perm_vec(0, src, perm_vec); + s5 = LOAD_HL(0, src, perm_vec); else - s4 = load_with_perm_vec(0, src, perm_vec); + s4 = LOAD_HL(0, src, perm_vec); FILTER_V(f16h, vec_mule); @@ -272,39 +298,25 @@ EPEL_HV(4, 4,4) static void put_vp8_pixels16_altivec(uint8_t *dst, ptrdiff_t dstride, uint8_t *src, ptrdiff_t sstride, int h, int mx, int my) { - register vector unsigned char pixelsv1, pixelsv2; - register vector unsigned char pixelsv1B, pixelsv2B; - register vector unsigned char pixelsv1C, pixelsv2C; - register vector unsigned char pixelsv1D, pixelsv2D; - - register vector unsigned char perm = vec_lvsl(0, src); + register vector unsigned char perm; int i; register ptrdiff_t dstride2 = dstride << 1, sstride2 = sstride << 1; register ptrdiff_t dstride3 = dstride2 + dstride, sstride3 = sstride + sstride2; register ptrdiff_t dstride4 = dstride << 2, sstride4 = sstride << 2; +#if HAVE_BIGENDIAN + perm = vec_lvsl(0, src); +#endif // hand-unrolling the loop by 4 gains about 15% // mininum execution time goes from 74 to 60 cycles // it's faster than -funroll-loops, but using // -funroll-loops w/ this is bad - 74 cycles again. // all this is on a 7450, tuning for the 7450 for (i = 0; i < h; i += 4) { - pixelsv1 = vec_ld( 0, src); - pixelsv2 = vec_ld(15, src); - pixelsv1B = vec_ld(sstride, src); - pixelsv2B = vec_ld(15 + sstride, src); - pixelsv1C = vec_ld(sstride2, src); - pixelsv2C = vec_ld(15 + sstride2, src); - pixelsv1D = vec_ld(sstride3, src); - pixelsv2D = vec_ld(15 + sstride3, src); - vec_st(vec_perm(pixelsv1, pixelsv2, perm), - 0, (unsigned char*)dst); - vec_st(vec_perm(pixelsv1B, pixelsv2B, perm), - dstride, (unsigned char*)dst); - vec_st(vec_perm(pixelsv1C, pixelsv2C, perm), - dstride2, (unsigned char*)dst); - vec_st(vec_perm(pixelsv1D, pixelsv2D, perm), - dstride3, (unsigned char*)dst); + vec_st(load_with_perm_vec(0, src, perm), 0, dst); + vec_st(load_with_perm_vec(sstride, src, perm), dstride, dst); + vec_st(load_with_perm_vec(sstride2, src, perm), dstride2, dst); + vec_st(load_with_perm_vec(sstride3, src, perm), dstride3, dst); src += sstride4; dst += dstride4; } diff --git a/libavcodec/proresdec2.c b/libavcodec/proresdec2.c index 4d04a0ad85..a1d497f049 100644 --- a/libavcodec/proresdec2.c +++ b/libavcodec/proresdec2.c @@ -183,6 +183,7 @@ static int decode_picture_header(AVCodecContext *avctx, const uint8_t *buf, cons if (ctx->slice_count != slice_count || !ctx->slices) { av_freep(&ctx->slices); + ctx->slice_count = 0; ctx->slices = av_mallocz_array(slice_count, sizeof(*ctx->slices)); if (!ctx->slices) return AVERROR(ENOMEM); diff --git a/libavcodec/proresenc_anatoliy.c b/libavcodec/proresenc_anatoliy.c index f471f4987e..801d58ed7b 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 5f432a97cd..ab295aa924 100644 --- a/libavcodec/proresenc_kostya.c +++ b/libavcodec/proresenc_kostya.c @@ -1058,7 +1058,7 @@ static int encode_frame(AVCodecContext *avctx, AVPacket *pkt, slice_hdr = pkt->data + (slice_hdr - start); tmp = pkt->data + (tmp - start); } - init_put_bits(&pb, buf, (pkt_size - (buf - orig_buf)) * 8); + 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) diff --git a/libavcodec/pthread_frame.c b/libavcodec/pthread_frame.c index 5a4ab84a4a..41fafcefd4 100644 --- a/libavcodec/pthread_frame.c +++ b/libavcodec/pthread_frame.c @@ -571,7 +571,7 @@ void ff_frame_thread_free(AVCodecContext *avctx, int thread_count) pthread_join(p->thread, NULL); p->thread_init=0; - if (codec->close) + if (codec->close && p->avctx) codec->close(p->avctx); avctx->codec = NULL; @@ -591,12 +591,13 @@ void ff_frame_thread_free(AVCodecContext *avctx, int thread_count) av_packet_unref(&p->avpkt); av_freep(&p->released_buffers); - if (i) { + if (i && p->avctx) { av_freep(&p->avctx->priv_data); av_freep(&p->avctx->slice_offset); } - av_freep(&p->avctx->internal); + if (p->avctx) + av_freep(&p->avctx->internal); av_freep(&p->avctx); } @@ -668,6 +669,7 @@ int ff_frame_thread_init(AVCodecContext *avctx) copy->internal = av_malloc(sizeof(AVCodecInternal)); if (!copy->internal) { + copy->priv_data = NULL; err = AVERROR(ENOMEM); goto error; } diff --git a/libavcodec/pthread_slice.c b/libavcodec/pthread_slice.c index b948e16d24..a3bcd21fea 100644 --- a/libavcodec/pthread_slice.c +++ b/libavcodec/pthread_slice.c @@ -181,6 +181,12 @@ int ff_slice_thread_init(AVCodecContext *avctx) w32thread_init(); #endif + // We cannot do this in the encoder init as the threads are created before + if (av_codec_is_encoder(avctx->codec) && + avctx->codec_id == AV_CODEC_ID_MPEG1VIDEO && + avctx->height > 2800) + thread_count = avctx->thread_count = 1; + if (!thread_count) { int nb_cpus = av_cpu_count(); if (avctx->height) diff --git a/libavcodec/put_bits.h b/libavcodec/put_bits.h index 8858caaacc..81fe039811 100644 --- a/libavcodec/put_bits.h +++ b/libavcodec/put_bits.h @@ -106,7 +106,7 @@ static inline void flush_put_bits(PutBitContext *s) s->bit_buf <<= s->bit_left; #endif while (s->bit_left < 32) { - /* XXX: should test end of buffer */ + av_assert0(s->buf_ptr < s->buf_end); #ifdef BITSTREAM_WRITER_LE *s->buf_ptr++ = s->bit_buf; s->bit_buf >>= 8; @@ -164,9 +164,13 @@ static inline void put_bits(PutBitContext *s, int n, unsigned int value) #ifdef BITSTREAM_WRITER_LE bit_buf |= value << (32 - bit_left); if (n >= bit_left) { - av_assert2(s->buf_ptr+3buf_end); - AV_WL32(s->buf_ptr, bit_buf); - s->buf_ptr += 4; + if (3 < s->buf_end - s->buf_ptr) { + AV_WL32(s->buf_ptr, bit_buf); + s->buf_ptr += 4; + } else { + av_log(NULL, AV_LOG_ERROR, "Internal error, put_bits buffer too small\n"); + av_assert2(0); + } bit_buf = (bit_left == 32) ? 0 : value >> bit_left; bit_left += 32; } @@ -178,9 +182,13 @@ static inline void put_bits(PutBitContext *s, int n, unsigned int value) } else { bit_buf <<= bit_left; bit_buf |= value >> (n - bit_left); - av_assert2(s->buf_ptr+3buf_end); - AV_WB32(s->buf_ptr, bit_buf); - s->buf_ptr += 4; + if (3 < s->buf_end - s->buf_ptr) { + AV_WB32(s->buf_ptr, bit_buf); + s->buf_ptr += 4; + } else { + av_log(NULL, AV_LOG_ERROR, "Internal error, put_bits buffer too small\n"); + av_assert2(0); + } bit_left += 32 - n; bit_buf = value; } @@ -230,6 +238,7 @@ static inline void skip_put_bytes(PutBitContext *s, int n) { av_assert2((put_bits_count(s) & 7) == 0); av_assert2(s->bit_left == 32); + av_assert0(n <= s->buf_end - s->buf_ptr); s->buf_ptr += n; } @@ -253,6 +262,7 @@ static inline void skip_put_bits(PutBitContext *s, int n) static inline void set_put_bits_buffer_size(PutBitContext *s, int size) { s->buf_end = s->buf + size; + s->size_in_bits = 8*size; } #endif /* AVCODEC_PUT_BITS_H */ diff --git a/libavcodec/qpeg.c b/libavcodec/qpeg.c index d61bceafd7..71f322b828 100644 --- a/libavcodec/qpeg.c +++ b/libavcodec/qpeg.c @@ -120,12 +120,13 @@ static void av_noinline qpeg_decode_inter(QpegContext *qctx, uint8_t *dst, int filled = 0; int orig_height; - if(!refdata) - refdata= dst; - - /* copy prev frame */ - for(i = 0; i < height; i++) - memcpy(dst + (i * stride), refdata + (i * stride), width); + if (refdata) { + /* copy prev frame */ + for (i = 0; i < height; i++) + memcpy(dst + (i * stride), refdata + (i * stride), width); + } else { + refdata = dst; + } orig_height = height; height--; diff --git a/libavcodec/rawdec.c b/libavcodec/rawdec.c index 647dfa9a0a..568553923b 100644 --- a/libavcodec/rawdec.c +++ b/libavcodec/rawdec.c @@ -258,7 +258,7 @@ static int raw_decode(AVCodecContext *avctx, void *data, int *got_frame, buf += buf_size - context->frame_size; len = context->frame_size - (avctx->pix_fmt==AV_PIX_FMT_PAL8 ? AVPALETTE_SIZE : 0); - if (buf_size < len && (avctx->codec_tag & 0xFFFFFF) != MKTAG('B','I','T', 0)) { + if (buf_size < len && ((avctx->codec_tag & 0xFFFFFF) != MKTAG('B','I','T', 0) || !need_copy)) { av_log(avctx, AV_LOG_ERROR, "Invalid buffer size, packet size %d < expected frame_size %d\n", buf_size, len); av_buffer_unref(&frame->buf[0]); return AVERROR(EINVAL); diff --git a/libavcodec/rawenc.c b/libavcodec/rawenc.c index c579230013..9bcf5c4cc6 100644 --- a/libavcodec/rawenc.c +++ b/libavcodec/rawenc.c @@ -51,7 +51,7 @@ static int raw_encode(AVCodecContext *avctx, AVPacket *pkt, if (ret < 0) return ret; - if ((ret = ff_alloc_packet2(avctx, pkt, ret)) < 0) + if ((ret = ff_alloc_packet(pkt, ret)) < 0) return ret; if ((ret = avpicture_layout((const AVPicture *)frame, avctx->pix_fmt, avctx->width, avctx->height, pkt->data, pkt->size)) < 0) diff --git a/libavcodec/resample.c b/libavcodec/resample.c index c45aa16cd1..ec311c7bfb 100644 --- a/libavcodec/resample.c +++ b/libavcodec/resample.c @@ -290,12 +290,6 @@ int audio_resample(ReSampleContext *s, short *output, short *input, int nb_sampl short *output_bak = NULL; int lenout; - if (s->input_channels == s->output_channels && s->ratio == 1.0 && 0) { - /* nothing to do */ - memcpy(output, input, nb_samples * s->input_channels * sizeof(short)); - return nb_samples; - } - if (s->sample_fmt[0] != AV_SAMPLE_FMT_S16) { int istride[1] = { s->sample_size[0] }; int ostride[1] = { 2 }; diff --git a/libavcodec/roqvideoenc.c b/libavcodec/roqvideoenc.c index 694792e059..b3eb58aa3a 100644 --- a/libavcodec/roqvideoenc.c +++ b/libavcodec/roqvideoenc.c @@ -966,6 +966,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/rv10enc.c b/libavcodec/rv10enc.c index 25411322a6..37efe6cca4 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/rv34.c b/libavcodec/rv34.c index a232ab2593..6e86ebd35e 100644 --- a/libavcodec/rv34.c +++ b/libavcodec/rv34.c @@ -1534,7 +1534,14 @@ int ff_rv34_decode_init_thread_copy(AVCodecContext *avctx) if (avctx->internal->is_copy) { r->tmp_b_block_base = NULL; + r->cbp_chroma = NULL; + r->cbp_luma = NULL; + r->deblock_coefs = NULL; + r->intra_types_hist = NULL; + r->mb_type = NULL; + ff_mpv_idct_init(&r->s); + if ((err = ff_mpv_common_init(&r->s)) < 0) return err; if ((err = rv34_decoder_alloc(r)) < 0) { diff --git a/libavcodec/s302m.c b/libavcodec/s302m.c index 7639a0f1c9..61c0fe8f96 100644 --- a/libavcodec/s302m.c +++ b/libavcodec/s302m.c @@ -79,11 +79,6 @@ static int s302m_parse_frame_header(AVCodecContext *avctx, const uint8_t *buf, case 8: avctx->channel_layout = AV_CH_LAYOUT_5POINT1_BACK | AV_CH_LAYOUT_STEREO_DOWNMIX; } - avctx->sample_rate = 48000; - avctx->bit_rate = 48000 * avctx->channels * (avctx->bits_per_raw_sample + 4) + - 32 * (48000 / (buf_size * 8 / - (avctx->channels * - (avctx->bits_per_raw_sample + 4)))); return frame_size; } @@ -109,6 +104,8 @@ static int s302m_decode_frame(AVCodecContext *avctx, void *data, if ((ret = ff_get_buffer(avctx, frame, 0)) < 0) return ret; + avctx->bit_rate = 48000 * avctx->channels * (avctx->bits_per_raw_sample + 4) + + 32 * 48000 / frame->nb_samples; buf_size = (frame->nb_samples * avctx->channels / 2) * block_size; if (avctx->bits_per_raw_sample == 24) { @@ -146,6 +143,8 @@ static int s302m_decode_frame(AVCodecContext *avctx, void *data, } } + avctx->sample_rate = 48000; + *got_frame_ptr = 1; return avpkt->size; diff --git a/libavcodec/s302menc.c b/libavcodec/s302menc.c index 540ac29dab..e738f09d19 100644 --- a/libavcodec/s302menc.c +++ b/libavcodec/s302menc.c @@ -82,7 +82,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/samidec.c b/libavcodec/samidec.c index 7705f93e7b..47850e2126 100644 --- a/libavcodec/samidec.c +++ b/libavcodec/samidec.c @@ -91,6 +91,7 @@ static int sami_paragraph_to_ass(AVCodecContext *avctx, const char *src) break; if (*p == '>') p++; + continue; } if (!av_isspace(*p)) av_bprint_chars(dst, *p, 1); diff --git a/libavcodec/sanm.c b/libavcodec/sanm.c index 9e5ec5400e..2547abb840 100644 --- a/libavcodec/sanm.c +++ b/libavcodec/sanm.c @@ -457,6 +457,7 @@ static void destroy_buffers(SANMVideoContext *ctx) ctx->frm0_size = ctx->frm1_size = ctx->frm2_size = 0; + init_sizes(ctx, 0, 0); } static av_cold int init_buffers(SANMVideoContext *ctx) diff --git a/libavcodec/sbr.h b/libavcodec/sbr.h index e28fccda09..ff00acba0d 100644 --- a/libavcodec/sbr.h +++ b/libavcodec/sbr.h @@ -137,6 +137,7 @@ typedef struct AACSBRContext { struct SpectralBandReplication { int sample_rate; int start; + int id_aac; int reset; SpectrumParameters spectrum_params; int bs_amp_res_header; diff --git a/libavcodec/shorten.c b/libavcodec/shorten.c index 4c9cc0636c..6ea5d0c644 100644 --- a/libavcodec/shorten.c +++ b/libavcodec/shorten.c @@ -129,8 +129,7 @@ static int allocate_buffers(ShortenContext *s) av_log(s->avctx, AV_LOG_ERROR, "nmean too large\n"); return AVERROR_INVALIDDATA; } - if (s->blocksize + s->nwrap >= UINT_MAX / sizeof(int32_t) || - s->blocksize + s->nwrap <= (unsigned)s->nwrap) { + if (s->blocksize + (uint64_t)s->nwrap >= UINT_MAX / sizeof(int32_t)) { av_log(s->avctx, AV_LOG_ERROR, "s->blocksize + s->nwrap too large\n"); return AVERROR_INVALIDDATA; @@ -278,7 +277,7 @@ static int decode_subframe_lpc(ShortenContext *s, int command, int channel, if (command == FN_QLPC) { /* read/validate prediction order */ pred_order = get_ur_golomb_shorten(&s->gb, LPCQSIZE); - if (pred_order > s->nwrap) { + if ((unsigned)pred_order > s->nwrap) { av_log(s->avctx, AV_LOG_ERROR, "invalid pred_order %d\n", pred_order); return AVERROR(EINVAL); @@ -370,6 +369,11 @@ static int read_header(ShortenContext *s) s->nmean = get_uint(s, 0); skip_bytes = get_uint(s, NSKIPSIZE); + if ((unsigned)skip_bytes > get_bits_left(&s->gb)/8) { + av_log(s->avctx, AV_LOG_ERROR, "invalid skip_bytes: %d\n", skip_bytes); + return AVERROR_INVALIDDATA; + } + for (i = 0; i < skip_bytes; i++) skip_bits(&s->gb, 8); } diff --git a/libavcodec/smacker.c b/libavcodec/smacker.c index b5538c7494..7b30664f38 100644 --- a/libavcodec/smacker.c +++ b/libavcodec/smacker.c @@ -668,6 +668,10 @@ static int smka_decode_frame(AVCodecContext *avctx, void *data, /* get output buffer */ frame->nb_samples = unp_size / (avctx->channels * (bits + 1)); + if (unp_size % (avctx->channels * (bits + 1))) { + av_log(avctx, AV_LOG_ERROR, "unp_size %d is odd\n", unp_size); + return AVERROR(EINVAL); + } if ((ret = ff_get_buffer(avctx, frame, 0)) < 0) return ret; samples = (int16_t *)frame->data[0]; diff --git a/libavcodec/smvjpegdec.c b/libavcodec/smvjpegdec.c index 375c9d91c3..c99b029c87 100644 --- a/libavcodec/smvjpegdec.c +++ b/libavcodec/smvjpegdec.c @@ -155,6 +155,10 @@ static int smvjpeg_decode_frame(AVCodecContext *avctx, void *data, int *data_siz if (!cur_frame) { av_frame_unref(mjpeg_data); ret = avcodec_decode_video2(s->avctx, mjpeg_data, &s->mjpeg_data_size, avpkt); + if (ret < 0) { + s->mjpeg_data_size = 0; + return ret; + } } else if (!s->mjpeg_data_size) return AVERROR(EINVAL); diff --git a/libavcodec/snow.h b/libavcodec/snow.h index 6f1fca378c..23e04bd66f 100644 --- a/libavcodec/snow.h +++ b/libavcodec/snow.h @@ -298,6 +298,8 @@ static av_always_inline void add_yblock(SnowContext *s, int sliced, slice_buffer BlockNode *lb= lt+b_stride; BlockNode *rb= lb+1; uint8_t *block[4]; + // When src_stride is large enough, it is possible to interleave the blocks. + // Otherwise the blocks are written sequentially in the tmp buffer. int tmp_step= src_stride >= 7*MB_SIZE ? MB_SIZE : MB_SIZE*src_stride; uint8_t *tmp = s->scratchbuf; uint8_t *ptmp; @@ -341,8 +343,6 @@ static av_always_inline void add_yblock(SnowContext *s, int sliced, slice_buffer if(b_w<=0 || b_h<=0) return; - av_assert2(src_stride > 2*MB_SIZE + 5); - if(!sliced && offset_dst) dst += src_x + src_y*dst_stride; dst8+= src_x + src_y*src_stride; @@ -557,6 +557,8 @@ static inline int get_symbol(RangeCoder *c, uint8_t *state, int is_signed){ e= 0; while(get_rac(c, state+1 + FFMIN(e,9))){ //1..10 e++; + if (e > 31) + return AVERROR_INVALIDDATA; } a= 1; diff --git a/libavcodec/snowdec.c b/libavcodec/snowdec.c index 327157b0d2..c5fa20339a 100644 --- a/libavcodec/snowdec.c +++ b/libavcodec/snowdec.c @@ -152,7 +152,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/snowenc.c b/libavcodec/snowenc.c index cbc89c985b..24efdc0bf0 100644 --- a/libavcodec/snowenc.c +++ b/libavcodec/snowenc.c @@ -285,7 +285,7 @@ static int encode_q_branch(SnowContext *s, int level, int x, int y){ c->penalty_factor = get_penalty_factor(s->lambda, s->lambda2, c->avctx->me_cmp); c->sub_penalty_factor= get_penalty_factor(s->lambda, s->lambda2, c->avctx->me_sub_cmp); c->mb_penalty_factor = get_penalty_factor(s->lambda, s->lambda2, c->avctx->mb_cmp); - c->current_mv_penalty= c->mv_penalty[s->m.f_code=1] + MAX_MV; + c->current_mv_penalty= c->mv_penalty[s->m.f_code=1] + MAX_DMV; c->xmin = - x*block_w - 16+3; c->ymin = - y*block_w - 16+3; diff --git a/libavcodec/sonic.c b/libavcodec/sonic.c index a5e573a7aa..ab947c47b0 100644 --- a/libavcodec/sonic.c +++ b/libavcodec/sonic.c @@ -497,12 +497,15 @@ static int predictor_calc_error(int *k, int *state, int order, int error) // copes better with quantization, and calculates the // actual whitened result as it goes. -static void modified_levinson_durbin(int *window, int window_entries, +static int modified_levinson_durbin(int *window, int window_entries, int *out, int out_entries, int channels, int *tap_quant) { int i; int *state = av_calloc(window_entries, sizeof(*state)); + if (!state) + return AVERROR(ENOMEM); + memcpy(state, window, 4* window_entries); for (i = 0; i < out_entries; i++) @@ -567,6 +570,7 @@ static void modified_levinson_durbin(int *window, int window_entries, } av_free(state); + return 0; } static inline int code_samplerate(int samplerate) @@ -627,6 +631,9 @@ static av_cold int sonic_encode_init(AVCodecContext *avctx) // generate taps s->tap_quant = av_calloc(s->num_taps, sizeof(*s->tap_quant)); + if (!s->tap_quant) + return AVERROR(ENOMEM); + for (i = 0; i < s->num_taps; i++) s->tap_quant[i] = ff_sqrt(i+1); @@ -656,7 +663,7 @@ static av_cold int sonic_encode_init(AVCodecContext *avctx) s->window_size = ((2*s->tail_size)+s->frame_size); s->window = av_calloc(s->window_size, sizeof(*s->window)); - if (!s->window) + if (!s->window || !s->int_samples) return AVERROR(ENOMEM); avctx->extradata = av_mallocz(16); @@ -769,8 +776,11 @@ static int sonic_encode_frame(AVCodecContext *avctx, AVPacket *avpkt, s->tail[i] = s->int_samples[s->frame_size - s->tail_size + i]; // generate taps - modified_levinson_durbin(s->window, s->window_size, + ret = modified_levinson_durbin(s->window, s->window_size, s->predictor_k, s->num_taps, s->channels, s->tap_quant); + if (ret < 0) + return ret; + if ((ret = intlist_write(&c, state, s->predictor_k, s->num_taps, 0)) < 0) return ret; @@ -873,17 +883,24 @@ static av_cold int sonic_decode_init(AVCodecContext *avctx) if (s->version >= 1) { + int sample_rate_index; s->channels = get_bits(&gb, 2); - s->samplerate = samplerate_table[get_bits(&gb, 4)]; + sample_rate_index = get_bits(&gb, 4); + if (sample_rate_index >= FF_ARRAY_ELEMS(samplerate_table)) { + av_log(avctx, AV_LOG_ERROR, "Invalid sample_rate_index %d\n", sample_rate_index); + return AVERROR_INVALIDDATA; + } + s->samplerate = samplerate_table[sample_rate_index]; av_log(avctx, AV_LOG_INFO, "Sonicv2 chans: %d samprate: %d\n", s->channels, s->samplerate); } - if (s->channels > MAX_CHANNELS) + if (s->channels > MAX_CHANNELS || s->channels < 1) { av_log(avctx, AV_LOG_ERROR, "Only mono and stereo streams are supported by now\n"); return AVERROR_INVALIDDATA; } + avctx->channels = s->channels; s->lossless = get_bits1(&gb); if (!s->lossless) @@ -908,11 +925,21 @@ static av_cold int sonic_decode_init(AVCodecContext *avctx) s->frame_size = s->channels*s->block_align*s->downsampling; // avctx->frame_size = s->block_align; + if (s->num_taps * s->channels > s->frame_size) { + av_log(avctx, AV_LOG_ERROR, + "number of taps times channels (%d * %d) larger than frame size %d\n", + s->num_taps, s->channels, s->frame_size); + return AVERROR_INVALIDDATA; + } + av_log(avctx, AV_LOG_INFO, "Sonic: ver: %d.%d ls: %d dr: %d taps: %d block: %d frame: %d downsamp: %d\n", s->version, s->minor_version, s->lossless, s->decorrelation, s->num_taps, s->block_align, s->frame_size, s->downsampling); // generate taps s->tap_quant = av_calloc(s->num_taps, sizeof(*s->tap_quant)); + if (!s->tap_quant) + return AVERROR(ENOMEM); + for (i = 0; i < s->num_taps; i++) s->tap_quant[i] = ff_sqrt(i+1); @@ -932,6 +959,8 @@ static av_cold int sonic_decode_init(AVCodecContext *avctx) return AVERROR(ENOMEM); } s->int_samples = av_calloc(s->frame_size, sizeof(*s->int_samples)); + if (!s->int_samples) + return AVERROR(ENOMEM); avctx->sample_fmt = AV_SAMPLE_FMT_S16; return 0; diff --git a/libavcodec/svq1dec.c b/libavcodec/svq1dec.c index 052b61839e..52147f595b 100644 --- a/libavcodec/svq1dec.c +++ b/libavcodec/svq1dec.c @@ -617,9 +617,12 @@ static int svq1_decode_frame(AVCodecContext *avctx, void *data, uint8_t *current; int result, i, x, y, width, height; svq1_pmv *pmv; + int ret; /* initialize bit buffer */ - init_get_bits8(&s->gb, buf, buf_size); + ret = init_get_bits8(&s->gb, buf, buf_size); + if (ret < 0) + return ret; /* decode frame header */ s->frame_code = get_bits(&s->gb, 22); diff --git a/libavcodec/svq1enc.c b/libavcodec/svq1enc.c index 2a0d78043a..493027dfb5 100644 --- a/libavcodec/svq1enc.c +++ b/libavcodec/svq1enc.c @@ -514,6 +514,11 @@ static av_cold int svq1_encode_init(AVCodecContext *avctx) SVQ1EncContext *const s = avctx->priv_data; int ret; + if (avctx->width >= 4096 || avctx->height >= 4096) { + av_log(avctx, AV_LOG_ERROR, "Dimensions too large, maximum is 4095x4095\n"); + return AVERROR(EINVAL); + } + ff_hpeldsp_init(&s->hdsp, avctx->flags); ff_me_cmp_init(&s->mecc, avctx); ff_mpegvideoencdsp_init(&s->m.mpvencdsp, avctx); diff --git a/libavcodec/takdec.c b/libavcodec/takdec.c index 5810a01c24..2b72e8476c 100644 --- a/libavcodec/takdec.c +++ b/libavcodec/takdec.c @@ -224,6 +224,7 @@ static void decode_lpc(int32_t *coeffs, int mode, int length) int a3 = coeffs[2]; int a4 = a3 + a1; int a5 = a4 + a2; + coeffs[2] = a5; coeffs += 3; for (i = 0; i < length - 3; i++) { a3 += *coeffs; @@ -632,7 +633,7 @@ static int decorrelate(TAKDecContext *s, int c1, int c2, int length) for (; length2 > 0; length2 -= tmp) { tmp = FFMIN(length2, x); - for (i = 0; i < tmp; i++) + for (i = 0; i < tmp - (tmp == length2); i++) s->residues[filter_order + i] = *p2++ >> dshift; for (i = 0; i < tmp; i++) { @@ -656,7 +657,7 @@ static int decorrelate(TAKDecContext *s, int c1, int c2, int length) *p1++ = v; } - memcpy(s->residues, &s->residues[tmp], 2 * filter_order); + memmove(s->residues, &s->residues[tmp], 2 * filter_order); } emms_c(); @@ -799,6 +800,12 @@ static int tak_decode_frame(AVCodecContext *avctx, void *data, if (s->mcdparams[i].present) { s->mcdparams[i].index = get_bits(gb, 2); s->mcdparams[i].chan2 = get_bits(gb, 4); + if (s->mcdparams[i].chan2 >= avctx->channels) { + av_log(avctx, AV_LOG_ERROR, + "invalid channel 2 (%d) for %d channel(s)\n", + s->mcdparams[i].chan2, avctx->channels); + return AVERROR_INVALIDDATA; + } if (s->mcdparams[i].index == 1) { if ((nbit == s->mcdparams[i].chan2) || (ch_mask & 1 << s->mcdparams[i].chan2)) diff --git a/libavcodec/tiff.c b/libavcodec/tiff.c index ee16d7805d..df43ed2c87 100644 --- a/libavcodec/tiff.c +++ b/libavcodec/tiff.c @@ -839,13 +839,6 @@ static int tiff_decode_tag(TiffContext *s, AVFrame *frame) s->bpp = -1; } } - if (s->bpp > 64U) { - av_log(s->avctx, AV_LOG_ERROR, - "This format is not supported (bpp=%d, %d components)\n", - s->bpp, count); - s->bpp = 0; - return AVERROR_INVALIDDATA; - } break; case TIFF_SAMPLES_PER_PIXEL: if (count != 1) { @@ -1007,8 +1000,13 @@ static int tiff_decode_tag(TiffContext *s, AVFrame *frame) av_log(s->avctx, AV_LOG_ERROR, "subsample count invalid\n"); return AVERROR_INVALIDDATA; } - for (i = 0; i < count; i++) + for (i = 0; i < count; i++) { s->subsampling[i] = ff_tget(&s->gb, type, s->le); + if (s->subsampling[i] <= 0) { + av_log(s->avctx, AV_LOG_ERROR, "subsampling %d is invalid\n", s->subsampling[i]); + return AVERROR_INVALIDDATA; + } + } break; case TIFF_T4OPTIONS: if (s->compr == TIFF_G3) @@ -1158,6 +1156,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; } @@ -1249,7 +1254,7 @@ static int decode_frame(AVCodecContext *avctx, avpkt->size - s->strippos); } - if (s->rps <= 0) { + if (s->rps <= 0 || s->rps % s->subsampling[1]) { av_log(avctx, AV_LOG_ERROR, "rps %d invalid\n", s->rps); return AVERROR_INVALIDDATA; } diff --git a/libavcodec/truemotion1.c b/libavcodec/truemotion1.c index 660ecf5413..b2de889c46 100644 --- a/libavcodec/truemotion1.c +++ b/libavcodec/truemotion1.c @@ -402,6 +402,10 @@ static int truemotion1_decode_header(TrueMotion1Context *s) new_pix_fmt = AV_PIX_FMT_RGB555; // RGB565 is supported as well s->w >>= width_shift; + if (s->w & 1) { + avpriv_request_sample(s->avctx, "Frame with odd width"); + return AVERROR_PATCHWELCOME; + } if (s->w != s->avctx->width || s->h != s->avctx->height || new_pix_fmt != s->avctx->pix_fmt) { diff --git a/libavcodec/tta.c b/libavcodec/tta.c index 01584d957e..81f5dddf69 100644 --- a/libavcodec/tta.c +++ b/libavcodec/tta.c @@ -123,6 +123,7 @@ static av_cold int tta_decode_init(AVCodecContext * avctx) TTAContext *s = avctx->priv_data; GetBitContext gb; int total_frames; + int ret; s->avctx = avctx; @@ -131,7 +132,10 @@ static av_cold int tta_decode_init(AVCodecContext * avctx) return AVERROR_INVALIDDATA; s->crc_table = av_crc_get_table(AV_CRC_32_IEEE_LE); - init_get_bits8(&gb, avctx->extradata, avctx->extradata_size); + ret = init_get_bits8(&gb, avctx->extradata, avctx->extradata_size); + if (ret < 0) + return ret; + if (show_bits_long(&gb, 32) == AV_RL32("TTA1")) { /* signature */ skip_bits_long(&gb, 32); diff --git a/libavcodec/ttaenc.c b/libavcodec/ttaenc.c index ccd41a90c9..37624a9c62 100644 --- a/libavcodec/ttaenc.c +++ b/libavcodec/ttaenc.c @@ -114,9 +114,12 @@ static int tta_encode_frame(AVCodecContext *avctx, AVPacket *avpkt, { TTAEncContext *s = avctx->priv_data; PutBitContext pb; - int ret, i, out_bytes, cur_chan = 0, res = 0, samples = 0; + int ret, i, out_bytes, cur_chan, res, samples; + int64_t pkt_size = frame->nb_samples * 2LL * avctx->channels * s->bps; - if ((ret = ff_alloc_packet2(avctx, avpkt, frame->nb_samples * 2 * avctx->channels * s->bps)) < 0) +pkt_alloc: + cur_chan = 0, res = 0, samples = 0; + if ((ret = ff_alloc_packet2(avctx, avpkt, pkt_size)) < 0) return ret; init_put_bits(&pb, avpkt->data, avpkt->size); @@ -174,6 +177,14 @@ static int tta_encode_frame(AVCodecContext *avctx, AVPacket *avpkt, rice->k1++; unary = 1 + (outval >> k); + if (unary + 100LL > put_bits_left(&pb)) { + if (pkt_size < INT_MAX/2) { + pkt_size *= 2; + av_packet_unref(avpkt); + goto pkt_alloc; + } else + return AVERROR(ENOMEM); + } do { if (unary > 31) { put_bits(&pb, 31, 0x7FFFFFFF); diff --git a/libavcodec/utils.c b/libavcodec/utils.c index 66fe62cc85..e70c464126 100644 --- a/libavcodec/utils.c +++ b/libavcodec/utils.c @@ -66,6 +66,9 @@ #include "compat/os2threads.h" #endif +#include "libavutil/ffversion.h" +const char av_codec_ffversion[] = "FFmpeg version " FFMPEG_VERSION; + #if HAVE_PTHREADS || HAVE_W32THREADS || HAVE_OS2THREADS static int default_lockmgr_cb(void **arg, enum AVLockOp op) { @@ -243,7 +246,7 @@ int ff_set_sar(AVCodecContext *avctx, AVRational sar) int ret = av_image_check_sar(avctx->width, avctx->height, sar); if (ret < 0) { - av_log(avctx, AV_LOG_WARNING, "ignoring invalid SAR: %u/%u\n", + av_log(avctx, AV_LOG_WARNING, "ignoring invalid SAR: %d/%d\n", sar.num, sar.den); avctx->sample_aspect_ratio = (AVRational){ 0, 1 }; return ret; @@ -371,7 +374,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) { @@ -421,10 +424,12 @@ void avcodec_align_dimensions2(AVCodecContext *s, int *width, int *height, *width = FFALIGN(*width, w_align); *height = FFALIGN(*height, h_align); - if (s->codec_id == AV_CODEC_ID_H264 || s->lowres) + if (s->codec_id == AV_CODEC_ID_H264 || s->lowres) { // some of the optimized chroma MC reads one line too much // which is also done in mpeg decoders with lowres > 0 *height += 2; + *width = FFMAX(*width, 32); + } for (i = 0; i < 4; i++) linesize_align[i] = STRIDE_ALIGN; @@ -1023,8 +1028,10 @@ end: int ff_get_buffer(AVCodecContext *avctx, AVFrame *frame, int flags) { int ret = get_buffer_internal(avctx, frame, flags); - if (ret < 0) + if (ret < 0) { av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n"); + frame->width = frame->height = 0; + } return ret; } @@ -3063,8 +3070,8 @@ void avcodec_string(char *buf, int buf_size, AVCodecContext *enc, int encode) if (enc->sample_aspect_ratio.num) { av_reduce(&display_aspect_ratio.num, &display_aspect_ratio.den, - enc->width * enc->sample_aspect_ratio.num, - enc->height * enc->sample_aspect_ratio.den, + enc->width * (int64_t)enc->sample_aspect_ratio.num, + enc->height * (int64_t)enc->sample_aspect_ratio.den, 1024 * 1024); snprintf(buf + strlen(buf), buf_size - strlen(buf), " [SAR %d:%d DAR %d:%d]", @@ -3366,7 +3373,7 @@ int av_get_audio_frame_duration(AVCodecContext *avctx, int frame_bytes) return frame_bytes * 8 / bps; } - if (ch > 0) { + if (ch > 0 && ch < INT_MAX/16) { /* calc from frame_bytes and channels */ switch (id) { case AV_CODEC_ID_ADPCM_AFC: diff --git a/libavcodec/utvideodec.c b/libavcodec/utvideodec.c index b565c1076c..3a3c46e0bc 100644 --- a/libavcodec/utvideodec.c +++ b/libavcodec/utvideodec.c @@ -215,6 +215,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 @@ -270,6 +272,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; diff --git a/libavcodec/vc1dec.c b/libavcodec/vc1dec.c index da6724ca39..e5725b4b2a 100644 --- a/libavcodec/vc1dec.c +++ b/libavcodec/vc1dec.c @@ -465,7 +465,7 @@ static av_cold int vc1_decode_init(AVCodecContext *avctx) count = avctx->extradata_size*8 - get_bits_count(&gb); if (count > 0) { av_log(avctx, AV_LOG_INFO, "Extra data: %i bits left, value: %X\n", - count, get_bits(&gb, count)); + count, get_bits_long(&gb, FFMIN(count, 32))); } else if (count < 0) { av_log(avctx, AV_LOG_INFO, "Read %i bits in overflow\n", -count); } diff --git a/libavcodec/vmdvideo.c b/libavcodec/vmdvideo.c index fa0fbe32d4..a2ba1c959b 100644 --- a/libavcodec/vmdvideo.c +++ b/libavcodec/vmdvideo.c @@ -339,6 +339,9 @@ static int vmd_decode(VmdVideoContext *s, AVFrame *frame) ofs += slen; bytestream2_skip(&gb, len); } else { + if (ofs + len > frame_width || + bytestream2_get_bytes_left(&gb) < len) + return AVERROR_INVALIDDATA; bytestream2_get_buffer(&gb, &dp[ofs], len); ofs += len; } diff --git a/libavcodec/vorbisdec.c b/libavcodec/vorbisdec.c index fb1609920d..624092f837 100644 --- a/libavcodec/vorbisdec.c +++ b/libavcodec/vorbisdec.c @@ -568,6 +568,11 @@ static int vorbis_parse_setup_hdr_floors(vorbis_context *vc) return AVERROR(ENOMEM); rangebits = get_bits(gb, 4); + if (!rangebits && floor_setup->data.t1.partitions) { + av_log(vc->avctx, AV_LOG_ERROR, + "A rangebits value of 0 is not compliant with the Vorbis I specification.\n"); + return AVERROR_INVALIDDATA; + } rangemax = (1 << rangebits); if (rangemax > vc->blocksize[1] / 2) { av_log(vc->avctx, AV_LOG_ERROR, @@ -784,6 +789,11 @@ static int vorbis_parse_setup_hdr_mappings(vorbis_context *vc) if (get_bits1(gb)) { mapping_setup->coupling_steps = get_bits(gb, 8) + 1; + if (vc->audio_channels < 2) { + av_log(vc->avctx, AV_LOG_ERROR, + "Square polar channel mapping with less than two channels is not compliant with the Vorbis I specification.\n"); + return AVERROR_INVALIDDATA; + } mapping_setup->magnitude = av_mallocz(mapping_setup->coupling_steps * sizeof(*mapping_setup->magnitude)); mapping_setup->angle = av_mallocz(mapping_setup->coupling_steps * diff --git a/libavcodec/vp3.c b/libavcodec/vp3.c index 8aca83ae09..14f9e3f548 100644 --- a/libavcodec/vp3.c +++ b/libavcodec/vp3.c @@ -131,7 +131,7 @@ static const uint8_t hilbert_offset[16][2] = { typedef struct Vp3DecodeContext { AVCodecContext *avctx; - int theora, theora_tables; + int theora, theora_tables, theora_header; int version; int width, height; int chroma_x_shift, chroma_y_shift; @@ -206,8 +206,8 @@ typedef struct Vp3DecodeContext { int16_t *dct_tokens[3][64]; int16_t *dct_tokens_base; #define TOKEN_EOB(eob_run) ((eob_run) << 2) -#define TOKEN_ZERO_RUN(coeff, zero_run) (((coeff) << 9) + ((zero_run) << 2) + 1) -#define TOKEN_COEFF(coeff) (((coeff) << 2) + 2) +#define TOKEN_ZERO_RUN(coeff, zero_run) (((coeff) * 512) + ((zero_run) << 2) + 1) +#define TOKEN_COEFF(coeff) (((coeff) * 4) + 2) /** * number of blocks that contain DCT coefficients at @@ -2010,17 +2010,19 @@ static int vp3_decode_frame(AVCodecContext *avctx, vp3_decode_end(avctx); ret = theora_decode_header(avctx, &gb); + if (ret >= 0) + ret = vp3_decode_init(avctx); if (ret < 0) { vp3_decode_end(avctx); - } else - ret = vp3_decode_init(avctx); + } return ret; } else if (type == 2) { ret = theora_decode_tables(avctx, &gb); + if (ret >= 0) + ret = vp3_decode_init(avctx); if (ret < 0) { vp3_decode_end(avctx); - } else - ret = vp3_decode_init(avctx); + } return ret; } @@ -2238,6 +2240,7 @@ static int theora_decode_header(AVCodecContext *avctx, GetBitContext *gb) int ret; AVRational fps, aspect; + s->theora_header = 0; s->theora = get_bits_long(gb, 24); av_log(avctx, AV_LOG_DEBUG, "Theora bitstream version %X\n", s->theora); @@ -2297,7 +2300,8 @@ static int theora_decode_header(AVCodecContext *avctx, GetBitContext *gb) return AVERROR_INVALIDDATA; } skip_bits(gb, 3); /* reserved */ - } + } else + avctx->pix_fmt = AV_PIX_FMT_YUV420P; // align_get_bits(gb); @@ -2320,6 +2324,7 @@ static int theora_decode_header(AVCodecContext *avctx, GetBitContext *gb) avctx->color_trc = AVCOL_TRC_BT709; } + s->theora_header = 1; return 0; } @@ -2328,6 +2333,9 @@ static int theora_decode_tables(AVCodecContext *avctx, GetBitContext *gb) Vp3DecodeContext *s = avctx->priv_data; int i, n, matrices, inter, plane; + if (!s->theora_header) + return AVERROR_INVALIDDATA; + if (s->theora >= 0x030200) { n = get_bits(gb, 3); /* loop filter limit values table */ diff --git a/libavcodec/vp8.c b/libavcodec/vp8.c index 6ad26f3a7b..167f8f8765 100644 --- a/libavcodec/vp8.c +++ b/libavcodec/vp8.c @@ -164,7 +164,7 @@ int update_dimensions(VP8Context *s, int width, int height, int is_vp7) s->mb_height = (s->avctx->coded_height + 15) / 16; s->mb_layout = is_vp7 || avctx->active_thread_type == FF_THREAD_SLICE && - FFMIN(s->num_coeff_partitions, avctx->thread_count) > 1; + avctx->thread_count > 1; if (!s->mb_layout) { // Frame threading and one thread s->macroblocks_base = av_mallocz((s->mb_width + s->mb_height * 2 + 1) * sizeof(*s->macroblocks)); @@ -176,19 +176,25 @@ int update_dimensions(VP8Context *s, int width, int height, int is_vp7) s->top_border = av_mallocz((s->mb_width + 1) * sizeof(*s->top_border)); s->thread_data = av_mallocz(MAX_THREADS * sizeof(VP8ThreadData)); + if (!s->macroblocks_base || !s->top_nnz || !s->top_border || + !s->thread_data || (!s->intra4x4_pred_mode_top && !s->mb_layout)) { + free_buffers(s); + return AVERROR(ENOMEM); + } + for (i = 0; i < MAX_THREADS; i++) { s->thread_data[i].filter_strength = av_mallocz(s->mb_width * sizeof(*s->thread_data[0].filter_strength)); + if (!s->thread_data[i].filter_strength) { + free_buffers(s); + return AVERROR(ENOMEM); + } #if HAVE_THREADS pthread_mutex_init(&s->thread_data[i].lock, NULL); pthread_cond_init(&s->thread_data[i].cond, NULL); #endif } - if (!s->macroblocks_base || !s->top_nnz || !s->top_border || - (!s->intra4x4_pred_mode_top && !s->mb_layout)) - return AVERROR(ENOMEM); - s->macroblocks = s->macroblocks_base + 1; return 0; @@ -633,6 +639,11 @@ static int vp8_decode_frame_header(VP8Context *s, const uint8_t *buf, int buf_si int width = s->avctx->width; int height = s->avctx->height; + if (buf_size < 3) { + av_log(s->avctx, AV_LOG_ERROR, "Insufficent data (%d) for header\n", buf_size); + return AVERROR_INVALIDDATA; + } + s->keyframe = !(buf[0] & 1); s->profile = (buf[0]>>1) & 7; s->invisible = !(buf[0] & 0x10); @@ -751,8 +762,10 @@ static int vp8_decode_frame_header(VP8Context *s, const uint8_t *buf, int buf_si static av_always_inline void clamp_mv(VP8Context *s, VP56mv *dst, const VP56mv *src) { - dst->x = av_clip(src->x, s->mv_min.x, s->mv_max.x); - dst->y = av_clip(src->y, s->mv_min.y, s->mv_max.y); + dst->x = av_clip(src->x, av_clip(s->mv_min.x, INT16_MIN, INT16_MAX), + av_clip(s->mv_max.x, INT16_MIN, INT16_MAX)); + dst->y = av_clip(src->y, av_clip(s->mv_min.y, INT16_MIN, INT16_MAX), + av_clip(s->mv_max.y, INT16_MIN, INT16_MAX)); } /** @@ -2681,6 +2694,9 @@ av_cold int ff_vp8_decode_free(AVCodecContext *avctx) VP8Context *s = avctx->priv_data; int i; + if (!s) + return 0; + vp8_decode_flush_impl(avctx, 1); for (i = 0; i < FF_ARRAY_ELEMS(s->frames); i++) av_frame_free(&s->frames[i].tf.f); diff --git a/libavcodec/vp8.h b/libavcodec/vp8.h index b650892735..2135bd9d83 100644 --- a/libavcodec/vp8.h +++ b/libavcodec/vp8.h @@ -134,6 +134,11 @@ typedef struct VP8Frame { AVBufferRef *seg_map; } VP8Frame; +typedef struct VP8intmv { + int x; + int y; +} VP8intmv; + #define MAX_THREADS 8 typedef struct VP8Context { VP8ThreadData *thread_data; @@ -152,8 +157,8 @@ typedef struct VP8Context { uint8_t deblock_filter; uint8_t mbskip_enabled; uint8_t profile; - VP56mv mv_min; - VP56mv mv_max; + VP8intmv mv_min; + VP8intmv mv_max; int8_t sign_bias[4]; ///< one state [0, 1] per ref frame type int ref_count[3]; diff --git a/libavcodec/vp9.c b/libavcodec/vp9.c index 07df9ef75d..28e6bc9109 100644 --- a/libavcodec/vp9.c +++ b/libavcodec/vp9.c @@ -240,7 +240,7 @@ typedef struct VP9Context { // whole-frame cache uint8_t *intra_pred_data[3]; struct VP9Filter *lflvl; - DECLARE_ALIGNED(32, uint8_t, edge_emu_buffer)[71*80]; + DECLARE_ALIGNED(32, uint8_t, edge_emu_buffer)[135*144]; // block reconstruction intermediates int block_alloc_using_2pass; @@ -249,6 +249,8 @@ typedef struct VP9Context { struct { int x, y; } min_mv, max_mv; DECLARE_ALIGNED(32, uint8_t, tmp_y)[64*64]; DECLARE_ALIGNED(32, uint8_t, tmp_uv)[2][32*32]; + uint16_t mvscale[3][2]; + uint8_t mvstep[3][2]; } VP9Context; static const uint8_t bwh_tab[2][N_BS_SIZES][2] = { @@ -279,7 +281,8 @@ static int vp9_alloc_frame(AVCodecContext *ctx, VP9Frame *f) // retain segmentation map if it doesn't update if (s->segmentation.enabled && !s->segmentation.update_map && - !s->intraonly && !s->keyframe && !s->errorres) { + !s->intraonly && !s->keyframe && !s->errorres && + ctx->active_thread_type != FF_THREAD_FRAME) { memcpy(f->segmentation_map, s->frames[LAST_FRAME].segmentation_map, sz); } @@ -409,7 +412,7 @@ static av_always_inline int inv_recenter_nonneg(int v, int m) // differential forward probability updates static int update_prob(VP56RangeCoder *c, int p) { - static const int inv_map_table[254] = { + static const int inv_map_table[255] = { 7, 20, 33, 46, 59, 72, 85, 98, 111, 124, 137, 150, 163, 176, 189, 202, 215, 228, 241, 254, 1, 2, 3, 4, 5, 6, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 21, 22, 23, 24, @@ -428,7 +431,7 @@ static int update_prob(VP56RangeCoder *c, int p) 207, 208, 209, 210, 211, 212, 213, 214, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, - 252, 253, + 252, 253, 253, }; int d; @@ -458,6 +461,7 @@ static int update_prob(VP56RangeCoder *c, int p) if (d >= 65) d = (d << 1) - 65 + vp8_rac_get(c); d += 64; + av_assert2(d < FF_ARRAY_ELEMS(inv_map_table)); } return p <= 128 ? 1 + inv_recenter_nonneg(inv_map_table[d], p - 1) : @@ -581,6 +585,26 @@ static int decode_frame_header(AVCodecContext *ctx, s->varcompref[1] = 2; } } + + for (i = 0; i < 3; i++) { + AVFrame *ref = s->refs[s->refidx[i]].f; + int refw = ref->width, refh = ref->height; + + if (refw == w && refh == h) { + s->mvscale[i][0] = s->mvscale[i][1] = 0; + } else { + if (w * 2 < refw || h * 2 < refh || w > 16 * refw || h > 16 * refh) { + av_log(ctx, AV_LOG_ERROR, + "Invalid ref frame dimensions %dx%d for frame size %dx%d\n", + refw, refh, w, h); + return AVERROR_INVALIDDATA; + } + s->mvscale[i][0] = (refw << 14) / w; + s->mvscale[i][1] = (refh << 14) / h; + s->mvstep[i][0] = 16 * s->mvscale[i][0] >> 14; + s->mvstep[i][1] = 16 * s->mvscale[i][1] >> 14; + } + } } } s->refreshctx = s->errorres ? 0 : get_bits1(&s->gb); @@ -1351,9 +1375,18 @@ static void decode_mode(AVCodecContext *ctx) if (!s->last_uses_2pass) ff_thread_await_progress(&s->frames[LAST_FRAME].tf, row >> 3, 0); - for (y = 0; y < h4; y++) + for (y = 0; y < h4; y++) { + int idx_base = (y + row) * 8 * s->sb_cols + col; for (x = 0; x < w4; x++) - pred = FFMIN(pred, refsegmap[(y + row) * 8 * s->sb_cols + x + col]); + pred = FFMIN(pred, refsegmap[idx_base + x]); + if (!s->segmentation.update_map && ctx->active_thread_type == FF_THREAD_FRAME) { + // FIXME maybe retain reference to previous frame as + // segmap reference instead of copying the whole map + // into a new buffer + memcpy(&s->frames[CUR_FRAME].segmentation_map[idx_base], + &refsegmap[idx_base], w4); + } + } av_assert1(pred < 8); b->seg_id = pred; } else { @@ -2496,7 +2529,7 @@ static void intra_recon(AVCodecContext *ctx, ptrdiff_t y_off, ptrdiff_t uv_off) for (x = 0; x < end_x; x += uvstep1d, ptr += 4 * uvstep1d, ptr_r += 4 * uvstep1d, n += step) { int mode = b->uvmode; - uint8_t *a = &a_buf[16]; + uint8_t *a = &a_buf[32]; int eob = b->skip ? 0 : b->uvtx > TX_8X8 ? AV_RN16A(&s->uveob[p][n]) : s->uveob[p][n]; mode = check_intra_mode(s, mode, &a, ptr_r, @@ -2514,12 +2547,118 @@ static void intra_recon(AVCodecContext *ctx, ptrdiff_t y_off, ptrdiff_t uv_off) } } -static av_always_inline void mc_luma_dir(VP9Context *s, vp9_mc_func (*mc)[2], - uint8_t *dst, ptrdiff_t dst_stride, - const uint8_t *ref, ptrdiff_t ref_stride, - ThreadFrame *ref_frame, - ptrdiff_t y, ptrdiff_t x, const VP56mv *mv, - int bw, int bh, int w, int h) +static av_always_inline void mc_luma_scaled(VP9Context *s, vp9_scaled_mc_func smc, + uint8_t *dst, ptrdiff_t dst_stride, + const uint8_t *ref, ptrdiff_t ref_stride, + ThreadFrame *ref_frame, + ptrdiff_t y, ptrdiff_t x, const VP56mv *mv, + int bw, int bh, int w, int h, + const uint16_t *scale, const uint8_t *step) +{ +#define scale_mv(n, dim) (((int64_t)n * scale[dim]) >> 14) + // BUG libvpx seems to scale the two components separately. This introduces + // rounding errors but we have to reproduce them to be exactly compatible + // with the output from libvpx... + int mx = scale_mv(mv->x * 2, 0) + scale_mv(x * 16, 0); + int my = scale_mv(mv->y * 2, 1) + scale_mv(y * 16, 1); + int refbw_m1, refbh_m1; + int th; + + y = my >> 4; + x = mx >> 4; + ref += y * ref_stride + x; + mx &= 15; + my &= 15; + refbw_m1 = ((bw - 1) * step[0] + mx) >> 4; + refbh_m1 = ((bh - 1) * step[1] + my) >> 4; + // FIXME bilinear filter only needs 0/1 pixels, not 3/4 + // we use +7 because the last 7 pixels of each sbrow can be changed in + // the longest loopfilter of the next sbrow + th = (y + refbh_m1 + 4 + 7) >> 6; + ff_thread_await_progress(ref_frame, FFMAX(th, 0), 0); + if (x < 3 || y < 3 || x + 4 >= w - refbw_m1 || y + 4 >= h - refbh_m1) { + s->vdsp.emulated_edge_mc(s->edge_emu_buffer, + ref - 3 * ref_stride - 3, + 144, ref_stride, + refbw_m1 + 8, refbh_m1 + 8, + x - 3, y - 3, w, h); + ref = s->edge_emu_buffer + 3 * 144 + 3; + ref_stride = 144; + } + smc(dst, dst_stride, ref, ref_stride, bh, mx, my, step[0], step[1]); +} + +static av_always_inline void mc_chroma_scaled(VP9Context *s, vp9_scaled_mc_func smc, + uint8_t *dst_u, uint8_t *dst_v, + ptrdiff_t dst_stride, + const uint8_t *ref_u, ptrdiff_t src_stride_u, + const uint8_t *ref_v, ptrdiff_t src_stride_v, + ThreadFrame *ref_frame, + ptrdiff_t y, ptrdiff_t x, const VP56mv *mv, + int bw, int bh, int w, int h, + const uint16_t *scale, const uint8_t *step) +{ + // BUG https://code.google.com/p/webm/issues/detail?id=820 + int mx = scale_mv(mv->x, 0) + (scale_mv(x * 16, 0) & ~15) + (scale_mv(x * 32, 0) & 15); + int my = scale_mv(mv->y, 1) + (scale_mv(y * 16, 1) & ~15) + (scale_mv(y * 32, 1) & 15); +#undef scale_mv + int refbw_m1, refbh_m1; + int th; + + y = my >> 4; + x = mx >> 4; + ref_u += y * src_stride_u + x; + ref_v += y * src_stride_v + x; + mx &= 15; + my &= 15; + refbw_m1 = ((bw - 1) * step[0] + mx) >> 4; + refbh_m1 = ((bh - 1) * step[1] + my) >> 4; + // FIXME bilinear filter only needs 0/1 pixels, not 3/4 + // we use +7 because the last 7 pixels of each sbrow can be changed in + // the longest loopfilter of the next sbrow + th = (y + refbh_m1 + 4 + 7) >> 5; + ff_thread_await_progress(ref_frame, FFMAX(th, 0), 0); + if (x < 3 || y < 3 || x + 4 >= w - refbw_m1 || y + 4 >= h - refbh_m1) { + s->vdsp.emulated_edge_mc(s->edge_emu_buffer, + ref_u - 3 * src_stride_u - 3, + 144, src_stride_u, + refbw_m1 + 8, refbh_m1 + 8, + x - 3, y - 3, w, h); + ref_u = s->edge_emu_buffer + 3 * 144 + 3; + smc(dst_u, dst_stride, ref_u, 144, bh, mx, my, step[0], step[1]); + + s->vdsp.emulated_edge_mc(s->edge_emu_buffer, + ref_v - 3 * src_stride_v - 3, + 144, src_stride_v, + refbw_m1 + 8, refbh_m1 + 8, + x - 3, y - 3, w, h); + ref_v = s->edge_emu_buffer + 3 * 144 + 3; + smc(dst_v, dst_stride, ref_v, 144, bh, mx, my, step[0], step[1]); + } else { + smc(dst_u, dst_stride, ref_u, src_stride_u, bh, mx, my, step[0], step[1]); + smc(dst_v, dst_stride, ref_v, src_stride_v, bh, mx, my, step[0], step[1]); + } +} + +#define FN(x) x##_scaled +#define mc_luma_dir(s, mc, dst, dst_ls, src, src_ls, tref, row, col, mv, bw, bh, w, h, i) \ + mc_luma_scaled(s, s->dsp.s##mc, dst, dst_ls, src, src_ls, tref, row, col, \ + mv, bw, bh, w, h, s->mvscale[b->ref[i]], s->mvstep[b->ref[i]]) +#define mc_chroma_dir(s, mc, dstu, dstv, dst_ls, srcu, srcu_ls, srcv, srcv_ls, tref, \ + row, col, mv, bw, bh, w, h, i) \ + mc_chroma_scaled(s, s->dsp.s##mc, dstu, dstv, dst_ls, srcu, srcu_ls, srcv, srcv_ls, tref, \ + row, col, mv, bw, bh, w, h, s->mvscale[b->ref[i]], s->mvstep[b->ref[i]]) +#include "vp9_mc_template.c" +#undef mc_luma_dir +#undef mc_chroma_dir +#undef FN + +static av_always_inline void mc_luma_unscaled(VP9Context *s, vp9_mc_func (*mc)[2], + uint8_t *dst, ptrdiff_t dst_stride, + const uint8_t *ref, ptrdiff_t ref_stride, + ThreadFrame *ref_frame, + ptrdiff_t y, ptrdiff_t x, const VP56mv *mv, + int bw, int bh, int w, int h) { int mx = mv->x, my = mv->y, th; @@ -2546,14 +2685,14 @@ static av_always_inline void mc_luma_dir(VP9Context *s, vp9_mc_func (*mc)[2], mc[!!mx][!!my](dst, dst_stride, ref, ref_stride, bh, mx << 1, my << 1); } -static av_always_inline void mc_chroma_dir(VP9Context *s, vp9_mc_func (*mc)[2], - uint8_t *dst_u, uint8_t *dst_v, - ptrdiff_t dst_stride, - const uint8_t *ref_u, ptrdiff_t src_stride_u, - const uint8_t *ref_v, ptrdiff_t src_stride_v, - ThreadFrame *ref_frame, - ptrdiff_t y, ptrdiff_t x, const VP56mv *mv, - int bw, int bh, int w, int h) +static av_always_inline void mc_chroma_unscaled(VP9Context *s, vp9_mc_func (*mc)[2], + uint8_t *dst_u, uint8_t *dst_v, + ptrdiff_t dst_stride, + const uint8_t *ref_u, ptrdiff_t src_stride_u, + const uint8_t *ref_v, ptrdiff_t src_stride_v, + ThreadFrame *ref_frame, + ptrdiff_t y, ptrdiff_t x, const VP56mv *mv, + int bw, int bh, int w, int h) { int mx = mv->x, my = mv->y, th; @@ -2591,156 +2730,32 @@ static av_always_inline void mc_chroma_dir(VP9Context *s, vp9_mc_func (*mc)[2], } } +#define FN(x) x +#define mc_luma_dir(s, mc, dst, dst_ls, src, src_ls, tref, row, col, mv, bw, bh, w, h, i) \ + mc_luma_unscaled(s, s->dsp.mc, dst, dst_ls, src, src_ls, tref, row, col, \ + mv, bw, bh, w, h) +#define mc_chroma_dir(s, mc, dstu, dstv, dst_ls, srcu, srcu_ls, srcv, srcv_ls, tref, \ + row, col, mv, bw, bh, w, h, i) \ + mc_chroma_unscaled(s, s->dsp.mc, dstu, dstv, dst_ls, srcu, srcu_ls, srcv, srcv_ls, tref, \ + row, col, mv, bw, bh, w, h) +#include "vp9_mc_template.c" +#undef mc_luma_dir_dir +#undef mc_chroma_dir_dir +#undef FN + static void inter_recon(AVCodecContext *ctx) { - static const uint8_t bwlog_tab[2][N_BS_SIZES] = { - { 0, 0, 1, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4 }, - { 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 4, 4, 4 }, - }; VP9Context *s = ctx->priv_data; VP9Block *b = s->b; int row = s->row, col = s->col; - ThreadFrame *tref1 = &s->refs[s->refidx[b->ref[0]]], *tref2; - AVFrame *ref1 = tref1->f, *ref2; - int w1 = ref1->width, h1 = ref1->height, w2, h2; - ptrdiff_t ls_y = s->y_stride, ls_uv = s->uv_stride; - if (b->comp) { - tref2 = &s->refs[s->refidx[b->ref[1]]]; - ref2 = tref2->f; - w2 = ref2->width; - h2 = ref2->height; - } - - // y inter pred - if (b->bs > BS_8x8) { - if (b->bs == BS_8x4) { - mc_luma_dir(s, s->dsp.mc[3][b->filter][0], s->dst[0], ls_y, - ref1->data[0], ref1->linesize[0], tref1, - row << 3, col << 3, &b->mv[0][0], 8, 4, w1, h1); - mc_luma_dir(s, s->dsp.mc[3][b->filter][0], - s->dst[0] + 4 * ls_y, ls_y, - ref1->data[0], ref1->linesize[0], tref1, - (row << 3) + 4, col << 3, &b->mv[2][0], 8, 4, w1, h1); - - if (b->comp) { - mc_luma_dir(s, s->dsp.mc[3][b->filter][1], s->dst[0], ls_y, - ref2->data[0], ref2->linesize[0], tref2, - row << 3, col << 3, &b->mv[0][1], 8, 4, w2, h2); - mc_luma_dir(s, s->dsp.mc[3][b->filter][1], - s->dst[0] + 4 * ls_y, ls_y, - ref2->data[0], ref2->linesize[0], tref2, - (row << 3) + 4, col << 3, &b->mv[2][1], 8, 4, w2, h2); - } - } else if (b->bs == BS_4x8) { - mc_luma_dir(s, s->dsp.mc[4][b->filter][0], s->dst[0], ls_y, - ref1->data[0], ref1->linesize[0], tref1, - row << 3, col << 3, &b->mv[0][0], 4, 8, w1, h1); - mc_luma_dir(s, s->dsp.mc[4][b->filter][0], s->dst[0] + 4, ls_y, - ref1->data[0], ref1->linesize[0], tref1, - row << 3, (col << 3) + 4, &b->mv[1][0], 4, 8, w1, h1); - - if (b->comp) { - mc_luma_dir(s, s->dsp.mc[4][b->filter][1], s->dst[0], ls_y, - ref2->data[0], ref2->linesize[0], tref2, - row << 3, col << 3, &b->mv[0][1], 4, 8, w2, h2); - mc_luma_dir(s, s->dsp.mc[4][b->filter][1], s->dst[0] + 4, ls_y, - ref2->data[0], ref2->linesize[0], tref2, - row << 3, (col << 3) + 4, &b->mv[1][1], 4, 8, w2, h2); - } - } else { - av_assert2(b->bs == BS_4x4); - - // FIXME if two horizontally adjacent blocks have the same MV, - // do a w8 instead of a w4 call - mc_luma_dir(s, s->dsp.mc[4][b->filter][0], s->dst[0], ls_y, - ref1->data[0], ref1->linesize[0], tref1, - row << 3, col << 3, &b->mv[0][0], 4, 4, w1, h1); - mc_luma_dir(s, s->dsp.mc[4][b->filter][0], s->dst[0] + 4, ls_y, - ref1->data[0], ref1->linesize[0], tref1, - row << 3, (col << 3) + 4, &b->mv[1][0], 4, 4, w1, h1); - mc_luma_dir(s, s->dsp.mc[4][b->filter][0], - s->dst[0] + 4 * ls_y, ls_y, - ref1->data[0], ref1->linesize[0], tref1, - (row << 3) + 4, col << 3, &b->mv[2][0], 4, 4, w1, h1); - mc_luma_dir(s, s->dsp.mc[4][b->filter][0], - s->dst[0] + 4 * ls_y + 4, ls_y, - ref1->data[0], ref1->linesize[0], tref1, - (row << 3) + 4, (col << 3) + 4, &b->mv[3][0], 4, 4, w1, h1); - - if (b->comp) { - mc_luma_dir(s, s->dsp.mc[4][b->filter][1], s->dst[0], ls_y, - ref2->data[0], ref2->linesize[0], tref2, - row << 3, col << 3, &b->mv[0][1], 4, 4, w2, h2); - mc_luma_dir(s, s->dsp.mc[4][b->filter][1], s->dst[0] + 4, ls_y, - ref2->data[0], ref2->linesize[0], tref2, - row << 3, (col << 3) + 4, &b->mv[1][1], 4, 4, w2, h2); - mc_luma_dir(s, s->dsp.mc[4][b->filter][1], - s->dst[0] + 4 * ls_y, ls_y, - ref2->data[0], ref2->linesize[0], tref2, - (row << 3) + 4, col << 3, &b->mv[2][1], 4, 4, w2, h2); - mc_luma_dir(s, s->dsp.mc[4][b->filter][1], - s->dst[0] + 4 * ls_y + 4, ls_y, - ref2->data[0], ref2->linesize[0], tref2, - (row << 3) + 4, (col << 3) + 4, &b->mv[3][1], 4, 4, w2, h2); - } - } + if (s->mvscale[b->ref[0]][0] || (b->comp && s->mvscale[b->ref[1]][0])) { + inter_pred_scaled(ctx); } else { - int bwl = bwlog_tab[0][b->bs]; - int bw = bwh_tab[0][b->bs][0] * 4, bh = bwh_tab[0][b->bs][1] * 4; - - mc_luma_dir(s, s->dsp.mc[bwl][b->filter][0], s->dst[0], ls_y, - ref1->data[0], ref1->linesize[0], tref1, - row << 3, col << 3, &b->mv[0][0],bw, bh, w1, h1); - - if (b->comp) - mc_luma_dir(s, s->dsp.mc[bwl][b->filter][1], s->dst[0], ls_y, - ref2->data[0], ref2->linesize[0], tref2, - row << 3, col << 3, &b->mv[0][1], bw, bh, w2, h2); + inter_pred(ctx); } - - // uv inter pred - { - int bwl = bwlog_tab[1][b->bs]; - int bw = bwh_tab[1][b->bs][0] * 4, bh = bwh_tab[1][b->bs][1] * 4; - VP56mv mvuv; - - w1 = (w1 + 1) >> 1; - h1 = (h1 + 1) >> 1; - if (b->comp) { - w2 = (w2 + 1) >> 1; - h2 = (h2 + 1) >> 1; - } - if (b->bs > BS_8x8) { - mvuv.x = ROUNDED_DIV(b->mv[0][0].x + b->mv[1][0].x + b->mv[2][0].x + b->mv[3][0].x, 4); - mvuv.y = ROUNDED_DIV(b->mv[0][0].y + b->mv[1][0].y + b->mv[2][0].y + b->mv[3][0].y, 4); - } else { - mvuv = b->mv[0][0]; - } - - mc_chroma_dir(s, s->dsp.mc[bwl][b->filter][0], - s->dst[1], s->dst[2], ls_uv, - ref1->data[1], ref1->linesize[1], - ref1->data[2], ref1->linesize[2], tref1, - row << 2, col << 2, &mvuv, bw, bh, w1, h1); - - if (b->comp) { - if (b->bs > BS_8x8) { - mvuv.x = ROUNDED_DIV(b->mv[0][1].x + b->mv[1][1].x + b->mv[2][1].x + b->mv[3][1].x, 4); - mvuv.y = ROUNDED_DIV(b->mv[0][1].y + b->mv[1][1].y + b->mv[2][1].y + b->mv[3][1].y, 4); - } else { - mvuv = b->mv[0][1]; - } - mc_chroma_dir(s, s->dsp.mc[bwl][b->filter][1], - s->dst[1], s->dst[2], ls_uv, - ref2->data[1], ref2->linesize[1], - ref2->data[2], ref2->linesize[2], tref2, - row << 2, col << 2, &mvuv, bw, bh, w2, h2); - } - } - if (!b->skip) { - /* mostly copied intra_reconn() */ + /* mostly copied intra_recon() */ int w4 = bwh_tab[1][b->bs][0] << 1, step1d = 1 << b->tx, n; int h4 = bwh_tab[1][b->bs][1] << 1, x, y, step = 1 << (b->tx * 2); @@ -3748,7 +3763,7 @@ static int vp9_decode_frame(AVCodecContext *ctx, void *frame, if ((res = av_frame_ref(frame, s->refs[ref].f)) < 0) return res; *got_frame = 1; - return 0; + return pkt->size; } data += res; size -= res; @@ -3846,7 +3861,7 @@ static int vp9_decode_frame(AVCodecContext *ctx, void *frame, tile_row, s->tiling.log2_tile_rows, s->sb_rows); if (s->pass != 2) { for (tile_col = 0; tile_col < s->tiling.tile_cols; tile_col++) { - unsigned tile_size; + int64_t tile_size; if (tile_col == s->tiling.tile_cols - 1 && tile_row == s->tiling.tile_rows - 1) { @@ -3972,7 +3987,7 @@ static int vp9_decode_frame(AVCodecContext *ctx, void *frame, *got_frame = 1; } - return 0; + return pkt->size; } static void vp9_decode_flush(AVCodecContext *ctx) diff --git a/libavcodec/vp9_mc_template.c b/libavcodec/vp9_mc_template.c new file mode 100644 index 0000000000..c6ae432e26 --- /dev/null +++ b/libavcodec/vp9_mc_template.c @@ -0,0 +1,171 @@ +/* + * VP9 compatible video decoder + * + * Copyright (C) 2013 Ronald S. Bultje + * Copyright (C) 2013 Clément Bœsch + * + * 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 + */ + +static void FN(inter_pred)(AVCodecContext *ctx) +{ + static const uint8_t bwlog_tab[2][N_BS_SIZES] = { + { 0, 0, 1, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4 }, + { 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 4, 4, 4 }, + }; + VP9Context *s = ctx->priv_data; + VP9Block *b = s->b; + int row = s->row, col = s->col; + ThreadFrame *tref1 = &s->refs[s->refidx[b->ref[0]]], *tref2; + AVFrame *ref1 = tref1->f, *ref2; + int w1 = ref1->width, h1 = ref1->height, w2, h2; + ptrdiff_t ls_y = s->y_stride, ls_uv = s->uv_stride; + + if (b->comp) { + tref2 = &s->refs[s->refidx[b->ref[1]]]; + ref2 = tref2->f; + w2 = ref2->width; + h2 = ref2->height; + } + + // y inter pred + if (b->bs > BS_8x8) { + if (b->bs == BS_8x4) { + mc_luma_dir(s, mc[3][b->filter][0], s->dst[0], ls_y, + ref1->data[0], ref1->linesize[0], tref1, + row << 3, col << 3, &b->mv[0][0], 8, 4, w1, h1, 0); + mc_luma_dir(s, mc[3][b->filter][0], + s->dst[0] + 4 * ls_y, ls_y, + ref1->data[0], ref1->linesize[0], tref1, + (row << 3) + 4, col << 3, &b->mv[2][0], 8, 4, w1, h1, 0); + + if (b->comp) { + mc_luma_dir(s, mc[3][b->filter][1], s->dst[0], ls_y, + ref2->data[0], ref2->linesize[0], tref2, + row << 3, col << 3, &b->mv[0][1], 8, 4, w2, h2, 1); + mc_luma_dir(s, mc[3][b->filter][1], + s->dst[0] + 4 * ls_y, ls_y, + ref2->data[0], ref2->linesize[0], tref2, + (row << 3) + 4, col << 3, &b->mv[2][1], 8, 4, w2, h2, 1); + } + } else if (b->bs == BS_4x8) { + mc_luma_dir(s, mc[4][b->filter][0], s->dst[0], ls_y, + ref1->data[0], ref1->linesize[0], tref1, + row << 3, col << 3, &b->mv[0][0], 4, 8, w1, h1, 0); + mc_luma_dir(s, mc[4][b->filter][0], s->dst[0] + 4, ls_y, + ref1->data[0], ref1->linesize[0], tref1, + row << 3, (col << 3) + 4, &b->mv[1][0], 4, 8, w1, h1, 0); + + if (b->comp) { + mc_luma_dir(s, mc[4][b->filter][1], s->dst[0], ls_y, + ref2->data[0], ref2->linesize[0], tref2, + row << 3, col << 3, &b->mv[0][1], 4, 8, w2, h2, 1); + mc_luma_dir(s, mc[4][b->filter][1], s->dst[0] + 4, ls_y, + ref2->data[0], ref2->linesize[0], tref2, + row << 3, (col << 3) + 4, &b->mv[1][1], 4, 8, w2, h2, 1); + } + } else { + av_assert2(b->bs == BS_4x4); + + // FIXME if two horizontally adjacent blocks have the same MV, + // do a w8 instead of a w4 call + mc_luma_dir(s, mc[4][b->filter][0], s->dst[0], ls_y, + ref1->data[0], ref1->linesize[0], tref1, + row << 3, col << 3, &b->mv[0][0], 4, 4, w1, h1, 0); + mc_luma_dir(s, mc[4][b->filter][0], s->dst[0] + 4, ls_y, + ref1->data[0], ref1->linesize[0], tref1, + row << 3, (col << 3) + 4, &b->mv[1][0], 4, 4, w1, h1, 0); + mc_luma_dir(s, mc[4][b->filter][0], + s->dst[0] + 4 * ls_y, ls_y, + ref1->data[0], ref1->linesize[0], tref1, + (row << 3) + 4, col << 3, &b->mv[2][0], 4, 4, w1, h1, 0); + mc_luma_dir(s, mc[4][b->filter][0], + s->dst[0] + 4 * ls_y + 4, ls_y, + ref1->data[0], ref1->linesize[0], tref1, + (row << 3) + 4, (col << 3) + 4, &b->mv[3][0], 4, 4, w1, h1, 0); + + if (b->comp) { + mc_luma_dir(s, mc[4][b->filter][1], s->dst[0], ls_y, + ref2->data[0], ref2->linesize[0], tref2, + row << 3, col << 3, &b->mv[0][1], 4, 4, w2, h2, 1); + mc_luma_dir(s, mc[4][b->filter][1], s->dst[0] + 4, ls_y, + ref2->data[0], ref2->linesize[0], tref2, + row << 3, (col << 3) + 4, &b->mv[1][1], 4, 4, w2, h2, 1); + mc_luma_dir(s, mc[4][b->filter][1], + s->dst[0] + 4 * ls_y, ls_y, + ref2->data[0], ref2->linesize[0], tref2, + (row << 3) + 4, col << 3, &b->mv[2][1], 4, 4, w2, h2, 1); + mc_luma_dir(s, mc[4][b->filter][1], + s->dst[0] + 4 * ls_y + 4, ls_y, + ref2->data[0], ref2->linesize[0], tref2, + (row << 3) + 4, (col << 3) + 4, &b->mv[3][1], 4, 4, w2, h2, 1); + } + } + } else { + int bwl = bwlog_tab[0][b->bs]; + int bw = bwh_tab[0][b->bs][0] * 4, bh = bwh_tab[0][b->bs][1] * 4; + + mc_luma_dir(s, mc[bwl][b->filter][0], s->dst[0], ls_y, + ref1->data[0], ref1->linesize[0], tref1, + row << 3, col << 3, &b->mv[0][0],bw, bh, w1, h1, 0); + + if (b->comp) + mc_luma_dir(s, mc[bwl][b->filter][1], s->dst[0], ls_y, + ref2->data[0], ref2->linesize[0], tref2, + row << 3, col << 3, &b->mv[0][1], bw, bh, w2, h2, 1); + } + + // uv inter pred + { + int bwl = bwlog_tab[1][b->bs]; + int bw = bwh_tab[1][b->bs][0] * 4, bh = bwh_tab[1][b->bs][1] * 4; + VP56mv mvuv; + + w1 = (w1 + 1) >> 1; + h1 = (h1 + 1) >> 1; + if (b->comp) { + w2 = (w2 + 1) >> 1; + h2 = (h2 + 1) >> 1; + } + if (b->bs > BS_8x8) { + mvuv.x = ROUNDED_DIV(b->mv[0][0].x + b->mv[1][0].x + b->mv[2][0].x + b->mv[3][0].x, 4); + mvuv.y = ROUNDED_DIV(b->mv[0][0].y + b->mv[1][0].y + b->mv[2][0].y + b->mv[3][0].y, 4); + } else { + mvuv = b->mv[0][0]; + } + + mc_chroma_dir(s, mc[bwl][b->filter][0], + s->dst[1], s->dst[2], ls_uv, + ref1->data[1], ref1->linesize[1], + ref1->data[2], ref1->linesize[2], tref1, + row << 2, col << 2, &mvuv, bw, bh, w1, h1, 0); + + if (b->comp) { + if (b->bs > BS_8x8) { + mvuv.x = ROUNDED_DIV(b->mv[0][1].x + b->mv[1][1].x + b->mv[2][1].x + b->mv[3][1].x, 4); + mvuv.y = ROUNDED_DIV(b->mv[0][1].y + b->mv[1][1].y + b->mv[2][1].y + b->mv[3][1].y, 4); + } else { + mvuv = b->mv[0][1]; + } + mc_chroma_dir(s, mc[bwl][b->filter][1], + s->dst[1], s->dst[2], ls_uv, + ref2->data[1], ref2->linesize[1], + ref2->data[2], ref2->linesize[2], tref2, + row << 2, col << 2, &mvuv, bw, bh, w2, h2, 1); + } + } +} diff --git a/libavcodec/vp9_parser.c b/libavcodec/vp9_parser.c index af033c25e6..8e55d2593e 100644 --- a/libavcodec/vp9_parser.c +++ b/libavcodec/vp9_parser.c @@ -1,5 +1,8 @@ /* - * Copyright (C) 2008 Michael Niedermayer + * VP9 compatible video decoder + * + * Copyright (C) 2013 Ronald S. Bultje + * Copyright (C) 2013 Clément Bœsch * * This file is part of FFmpeg. * @@ -43,6 +46,7 @@ static int parse(AVCodecParserContext *ctx, const uint8_t *data, int size) { VP9ParseContext *s = ctx->priv_data; + int full_size = size; int marker; if (size <= 0) { @@ -77,10 +81,12 @@ static int parse(AVCodecParserContext *ctx, idx += a; \ if (sz > size) { \ s->n_frames = 0; \ + *out_size = size; \ + *out_data = data; \ av_log(avctx, AV_LOG_ERROR, \ "Superframe packet size too big: %u > %d\n", \ sz, size); \ - return size; \ + return full_size; \ } \ if (first) { \ first = 0; \ diff --git a/libavcodec/vp9dsp.c b/libavcodec/vp9dsp.c index 6356adde32..95b7eb5c71 100644 --- a/libavcodec/vp9dsp.c +++ b/libavcodec/vp9dsp.c @@ -1707,8 +1707,9 @@ copy_avg_fn(4) #undef fpel_fn #undef copy_avg_fn -static const int8_t vp9_subpel_filters[3][15][8] = { +static const int16_t vp9_subpel_filters[3][16][8] = { [FILTER_8TAP_REGULAR] = { + { 0, 0, 0, 128, 0, 0, 0, 0 }, { 0, 1, -5, 126, 8, -3, 1, 0 }, { -1, 3, -10, 122, 18, -6, 2, 0 }, { -1, 4, -13, 118, 27, -9, 3, -1 }, @@ -1725,6 +1726,7 @@ static const int8_t vp9_subpel_filters[3][15][8] = { { 0, 2, -6, 18, 122, -10, 3, -1 }, { 0, 1, -3, 8, 126, -5, 1, 0 }, }, [FILTER_8TAP_SHARP] = { + { 0, 0, 0, 128, 0, 0, 0, 0 }, { -1, 3, -7, 127, 8, -3, 1, 0 }, { -2, 5, -13, 125, 17, -6, 3, -1 }, { -3, 7, -17, 121, 27, -10, 5, -2 }, @@ -1741,6 +1743,7 @@ static const int8_t vp9_subpel_filters[3][15][8] = { { -1, 3, -6, 17, 125, -13, 5, -2 }, { 0, 1, -3, 8, 127, -7, 3, -1 }, }, [FILTER_8TAP_SMOOTH] = { + { 0, 0, 0, 128, 0, 0, 0, 0 }, { -3, -1, 32, 64, 38, 1, -3, 0 }, { -2, -2, 29, 63, 41, 2, -3, 0 }, { -2, -2, 26, 63, 43, 4, -4, 0 }, @@ -1772,7 +1775,7 @@ static const int8_t vp9_subpel_filters[3][15][8] = { static av_always_inline void do_8tap_1d_c(uint8_t *dst, ptrdiff_t dst_stride, const uint8_t *src, ptrdiff_t src_stride, int w, int h, ptrdiff_t ds, - const int8_t *filter, int avg) + const int16_t *filter, int avg) { do { int x; @@ -1792,7 +1795,7 @@ static av_always_inline void do_8tap_1d_c(uint8_t *dst, ptrdiff_t dst_stride, #define filter_8tap_1d_fn(opn, opa, dir, ds) \ static av_noinline void opn##_8tap_1d_##dir##_c(uint8_t *dst, ptrdiff_t dst_stride, \ const uint8_t *src, ptrdiff_t src_stride, \ - int w, int h, const int8_t *filter) \ + int w, int h, const int16_t *filter) \ { \ do_8tap_1d_c(dst, dst_stride, src, src_stride, w, h, ds, filter, opa); \ } @@ -1806,8 +1809,8 @@ filter_8tap_1d_fn(avg, 1, h, 1) static av_always_inline void do_8tap_2d_c(uint8_t *dst, ptrdiff_t dst_stride, const uint8_t *src, ptrdiff_t src_stride, - int w, int h, const int8_t *filterx, - const int8_t *filtery, int avg) + int w, int h, const int16_t *filterx, + const int16_t *filtery, int avg) { int tmp_h = h + 7; uint8_t tmp[64 * 71], *tmp_ptr = tmp; @@ -1842,8 +1845,8 @@ static av_always_inline void do_8tap_2d_c(uint8_t *dst, ptrdiff_t dst_stride, #define filter_8tap_2d_fn(opn, opa) \ static av_noinline void opn##_8tap_2d_hv_c(uint8_t *dst, ptrdiff_t dst_stride, \ const uint8_t *src, ptrdiff_t src_stride, \ - int w, int h, const int8_t *filterx, \ - const int8_t *filtery) \ + int w, int h, const int16_t *filterx, \ + const int16_t *filtery) \ { \ do_8tap_2d_c(dst, dst_stride, src, src_stride, w, h, filterx, filtery, opa); \ } @@ -1853,15 +1856,13 @@ filter_8tap_2d_fn(avg, 1) #undef filter_8tap_2d_fn -#undef FILTER_8TAP - #define filter_fn_1d(sz, dir, dir_m, type, type_idx, avg) \ static void avg##_8tap_##type##_##sz##dir##_c(uint8_t *dst, ptrdiff_t dst_stride, \ const uint8_t *src, ptrdiff_t src_stride, \ int h, int mx, int my) \ { \ avg##_8tap_1d_##dir##_c(dst, dst_stride, src, src_stride, sz, h, \ - vp9_subpel_filters[type_idx][dir_m - 1]); \ + vp9_subpel_filters[type_idx][dir_m]); \ } #define filter_fn_2d(sz, type, type_idx, avg) \ @@ -1870,8 +1871,8 @@ static void avg##_8tap_##type##_##sz##hv_c(uint8_t *dst, ptrdiff_t dst_stride, \ int h, int mx, int my) \ { \ avg##_8tap_2d_hv_c(dst, dst_stride, src, src_stride, sz, h, \ - vp9_subpel_filters[type_idx][mx - 1], \ - vp9_subpel_filters[type_idx][my - 1]); \ + vp9_subpel_filters[type_idx][mx], \ + vp9_subpel_filters[type_idx][my]); \ } #define FILTER_BILIN(src, x, mxy, stride) \ @@ -1957,8 +1958,6 @@ bilin_2d_fn(avg, 1) #undef bilin_2d_fn -#undef FILTER_BILIN - #define bilinf_fn_1d(sz, dir, dir_m, avg) \ static void avg##_bilin_##sz##dir##_c(uint8_t *dst, ptrdiff_t dst_stride, \ const uint8_t *src, ptrdiff_t src_stride, \ @@ -2053,12 +2052,190 @@ static av_cold void vp9dsp_mc_init(VP9DSPContext *dsp) #undef init_subpel3 } +static av_always_inline void do_scaled_8tap_c(uint8_t *dst, ptrdiff_t dst_stride, + const uint8_t *src, ptrdiff_t src_stride, + int w, int h, int mx, int my, + int dx, int dy, int avg, + const int16_t (*filters)[8]) +{ + int tmp_h = (((h - 1) * dy + my) >> 4) + 8; + uint8_t tmp[64 * 135], *tmp_ptr = tmp; + + src -= src_stride * 3; + do { + int x; + int imx = mx, ioff = 0; + + for (x = 0; x < w; x++) { + tmp_ptr[x] = FILTER_8TAP(src, ioff, filters[imx], 1); + imx += dx; + ioff += imx >> 4; + imx &= 0xf; + } + + tmp_ptr += 64; + src += src_stride; + } while (--tmp_h); + + tmp_ptr = tmp + 64 * 3; + do { + int x; + const int16_t *filter = filters[my]; + + for (x = 0; x < w; x++) + if (avg) { + dst[x] = (dst[x] + FILTER_8TAP(tmp_ptr, x, filter, 64) + 1) >> 1; + } else { + dst[x] = FILTER_8TAP(tmp_ptr, x, filter, 64); + } + + my += dy; + tmp_ptr += (my >> 4) * 64; + my &= 0xf; + dst += dst_stride; + } while (--h); +} + +#define scaled_filter_8tap_fn(opn, opa) \ +static av_noinline void opn##_scaled_8tap_c(uint8_t *dst, ptrdiff_t dst_stride, \ + const uint8_t *src, ptrdiff_t src_stride, \ + int w, int h, int mx, int my, int dx, int dy, \ + const int16_t (*filters)[8]) \ +{ \ + do_scaled_8tap_c(dst, dst_stride, src, src_stride, w, h, mx, my, dx, dy, \ + opa, filters); \ +} + +scaled_filter_8tap_fn(put, 0) +scaled_filter_8tap_fn(avg, 1) + +#undef scaled_filter_8tap_fn + +#undef FILTER_8TAP + +#define scaled_filter_fn(sz, type, type_idx, avg) \ +static void avg##_scaled_##type##_##sz##_c(uint8_t *dst, ptrdiff_t dst_stride, \ + const uint8_t *src, ptrdiff_t src_stride, \ + int h, int mx, int my, int dx, int dy) \ +{ \ + avg##_scaled_8tap_c(dst, dst_stride, src, src_stride, sz, h, mx, my, dx, dy, \ + vp9_subpel_filters[type_idx]); \ +} + +static av_always_inline void do_scaled_bilin_c(uint8_t *dst, ptrdiff_t dst_stride, + const uint8_t *src, ptrdiff_t src_stride, + int w, int h, int mx, int my, + int dx, int dy, int avg) +{ + uint8_t tmp[64 * 129], *tmp_ptr = tmp; + int tmp_h = (((h - 1) * dy + my) >> 4) + 2; + + do { + int x; + int imx = mx, ioff = 0; + + for (x = 0; x < w; x++) { + tmp_ptr[x] = FILTER_BILIN(src, ioff, imx, 1); + imx += dx; + ioff += imx >> 4; + imx &= 0xf; + } + + tmp_ptr += 64; + src += src_stride; + } while (--tmp_h); + + tmp_ptr = tmp; + do { + int x; + + for (x = 0; x < w; x++) + if (avg) { + dst[x] = (dst[x] + FILTER_BILIN(tmp_ptr, x, my, 64) + 1) >> 1; + } else { + dst[x] = FILTER_BILIN(tmp_ptr, x, my, 64); + } + + my += dy; + tmp_ptr += (my >> 4) * 64; + my &= 0xf; + dst += dst_stride; + } while (--h); +} + +#define scaled_bilin_fn(opn, opa) \ +static av_noinline void opn##_scaled_bilin_c(uint8_t *dst, ptrdiff_t dst_stride, \ + const uint8_t *src, ptrdiff_t src_stride, \ + int w, int h, int mx, int my, int dx, int dy) \ +{ \ + do_scaled_bilin_c(dst, dst_stride, src, src_stride, w, h, mx, my, dx, dy, opa); \ +} + +scaled_bilin_fn(put, 0) +scaled_bilin_fn(avg, 1) + +#undef scaled_bilin_fn + +#undef FILTER_BILIN + +#define scaled_bilinf_fn(sz, avg) \ +static void avg##_scaled_bilin_##sz##_c(uint8_t *dst, ptrdiff_t dst_stride, \ + const uint8_t *src, ptrdiff_t src_stride, \ + int h, int mx, int my, int dx, int dy) \ +{ \ + avg##_scaled_bilin_c(dst, dst_stride, src, src_stride, sz, h, mx, my, dx, dy); \ +} + +#define scaled_filter_fns(sz, avg) \ +scaled_filter_fn(sz, regular, FILTER_8TAP_REGULAR, avg) \ +scaled_filter_fn(sz, smooth, FILTER_8TAP_SMOOTH, avg) \ +scaled_filter_fn(sz, sharp, FILTER_8TAP_SHARP, avg) \ +scaled_bilinf_fn(sz, avg) + +#define scaled_filter_fn_set(avg) \ +scaled_filter_fns(64, avg) \ +scaled_filter_fns(32, avg) \ +scaled_filter_fns(16, avg) \ +scaled_filter_fns(8, avg) \ +scaled_filter_fns(4, avg) + +scaled_filter_fn_set(put) +scaled_filter_fn_set(avg) + +#undef scaled_filter_fns +#undef scaled_filter_fn_set +#undef scaled_filter_fn +#undef scaled_bilinf_fn + +static av_cold void vp9dsp_scaled_mc_init(VP9DSPContext *dsp) +{ +#define init_scaled(idx1, idx2, sz, type) \ + dsp->smc[idx1][FILTER_8TAP_SMOOTH ][idx2] = type##_scaled_smooth_##sz##_c; \ + dsp->smc[idx1][FILTER_8TAP_REGULAR][idx2] = type##_scaled_regular_##sz##_c; \ + dsp->smc[idx1][FILTER_8TAP_SHARP ][idx2] = type##_scaled_sharp_##sz##_c; \ + dsp->smc[idx1][FILTER_BILINEAR ][idx2] = type##_scaled_bilin_##sz##_c + +#define init_scaled_put_avg(idx, sz) \ + init_scaled(idx, 0, sz, put); \ + init_scaled(idx, 1, sz, avg) + + init_scaled_put_avg(0, 64); + init_scaled_put_avg(1, 32); + init_scaled_put_avg(2, 16); + init_scaled_put_avg(3, 8); + init_scaled_put_avg(4, 4); + +#undef init_scaled_put_avg +#undef init_scaled +} + av_cold void ff_vp9dsp_init(VP9DSPContext *dsp) { vp9dsp_intrapred_init(dsp); vp9dsp_itxfm_init(dsp); vp9dsp_loopfilter_init(dsp); vp9dsp_mc_init(dsp); + vp9dsp_scaled_mc_init(dsp); if (ARCH_X86) ff_vp9dsp_init_x86(dsp); } diff --git a/libavcodec/vp9dsp.h b/libavcodec/vp9dsp.h index db0a92e210..33dfc09acd 100644 --- a/libavcodec/vp9dsp.h +++ b/libavcodec/vp9dsp.h @@ -32,6 +32,9 @@ typedef void (*vp9_mc_func)(uint8_t *dst, ptrdiff_t dst_stride, const uint8_t *ref, ptrdiff_t ref_stride, int h, int mx, int my); +typedef void (*vp9_scaled_mc_func)(uint8_t *dst, ptrdiff_t dst_stride, + const uint8_t *ref, ptrdiff_t ref_stride, + int h, int mx, int my, int dx, int dy); typedef struct VP9DSPContext { /* @@ -109,6 +112,12 @@ typedef struct VP9DSPContext { * dst/stride are aligned by hsize */ vp9_mc_func mc[5][4][2][2][2]; + + /* + * for scalable MC, first 3 dimensions identical to above, the other two + * don't exist since it changes per stepsize. + */ + vp9_scaled_mc_func smc[5][4][2]; } VP9DSPContext; void ff_vp9dsp_init(VP9DSPContext *dsp); diff --git a/libavcodec/vqavideo.c b/libavcodec/vqavideo.c index 4dcebd4849..bf55571fe9 100644 --- a/libavcodec/vqavideo.c +++ b/libavcodec/vqavideo.c @@ -231,6 +231,12 @@ static int decode_format80(VqaContext *s, int src_size, unsigned char color; int i; + if (src_size < 0 || src_size > bytestream2_get_bytes_left(&s->gb)) { + av_log(s->avctx, AV_LOG_ERROR, "Chunk size %d is out of range\n", + src_size); + return AVERROR_INVALIDDATA; + } + start = bytestream2_tell(&s->gb); while (bytestream2_tell(&s->gb) - start < src_size) { opcode = bytestream2_get_byte(&s->gb); diff --git a/libavcodec/wavpack.c b/libavcodec/wavpack.c index 1ad3901600..554367b32f 100644 --- a/libavcodec/wavpack.c +++ b/libavcodec/wavpack.c @@ -155,7 +155,7 @@ static int wv_get_value(WavpackFrameContext *ctx, GetBitContext *gb, if (t >= 2) { if (get_bits_left(gb) < t - 1) goto error; - t = get_bits(gb, t - 1) | (1 << (t - 1)); + t = get_bits_long(gb, t - 1) | (1 << (t - 1)); } else { if (get_bits_left(gb) < 0) goto error; @@ -186,7 +186,7 @@ static int wv_get_value(WavpackFrameContext *ctx, GetBitContext *gb, } else { if (get_bits_left(gb) < t2 - 1) goto error; - t += get_bits(gb, t2 - 1) | (1 << (t2 - 1)); + t += get_bits_long(gb, t2 - 1) | (1 << (t2 - 1)); } } @@ -271,7 +271,7 @@ static inline int wv_get_value_integer(WavpackFrameContext *s, uint32_t *crc, if (s->got_extra_bits && get_bits_left(&s->gb_extra_bits) >= s->extra_bits) { - S |= get_bits(&s->gb_extra_bits, s->extra_bits); + S |= get_bits_long(&s->gb_extra_bits, s->extra_bits); *crc = *crc * 9 + (S & 0xffff) * 3 + ((unsigned)S >> 16); } } @@ -472,6 +472,14 @@ static inline int wv_unpack_stereo(WavpackFrameContext *s, GetBitContext *gb, s->decorr[i].samplesB[0] = L; } } + + if (type == AV_SAMPLE_FMT_S16P) { + if (FFABS(L) + FFABS(R) > (1<<19)) { + av_log(s->avctx, AV_LOG_ERROR, "sample %d %d too large\n", L, R); + return AVERROR_INVALIDDATA; + } + } + pos = (pos + 1) & 7; if (s->joint) L += (R -= (L >> 1)); @@ -827,7 +835,11 @@ static int wavpack_decode_block(AVCodecContext *avctx, int block_no, continue; } bytestream2_get_buffer(&gb, val, 4); - if (val[0]) { + if (val[0] > 32) { + av_log(avctx, AV_LOG_ERROR, + "Invalid INT32INFO, extra_bits = %d (> 32)\n", val[0]); + continue; + } else if (val[0]) { s->extra_bits = val[0]; } else if (val[1]) { s->shift = val[1]; diff --git a/libavcodec/wavpackenc.c b/libavcodec/wavpackenc.c index 63971c6755..4bfeadb2e6 100644 --- a/libavcodec/wavpackenc.c +++ b/libavcodec/wavpackenc.c @@ -128,6 +128,11 @@ static av_cold int wavpack_encode_init(AVCodecContext *avctx) s->avctx = avctx; + if (avctx->channels > 255) { + av_log(avctx, AV_LOG_ERROR, "Invalid channel count: %d\n", avctx->channels); + return AVERROR(EINVAL); + } + if (!avctx->frame_size) { int block_samples; if (!(avctx->sample_rate & 1)) @@ -2882,7 +2887,7 @@ static int wavpack_encode_frame(AVCodecContext *avctx, AVPacket *avpkt, } buf_size = s->block_samples * avctx->channels * 8 - + 200 /* for headers */; + + 200 * avctx->channels /* for headers */; if ((ret = ff_alloc_packet2(avctx, avpkt, buf_size)) < 0) return ret; buf = avpkt->data; diff --git a/libavcodec/webp.c b/libavcodec/webp.c index 4b1c8e7f8b..f299550056 100644 --- a/libavcodec/webp.c +++ b/libavcodec/webp.c @@ -694,6 +694,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 { @@ -1099,7 +1104,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; @@ -1149,8 +1154,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/wmaenc.c b/libavcodec/wmaenc.c index 08d45e9273..d78c4357e8 100644 --- a/libavcodec/wmaenc.c +++ b/libavcodec/wmaenc.c @@ -32,6 +32,7 @@ static av_cold int encode_init(AVCodecContext *avctx) WMACodecContext *s = avctx->priv_data; int i, flags1, flags2, block_align; uint8_t *extradata; + int ret; s->avctx = avctx; @@ -78,7 +79,8 @@ static av_cold int encode_init(AVCodecContext *avctx) if (avctx->channels == 2) s->ms_stereo = 1; - ff_wma_init(avctx, flags2); + if ((ret = ff_wma_init(avctx, flags2)) < 0) + return ret; /* init MDCT */ for (i = 0; i < s->nb_block_sizes; i++) diff --git a/libavcodec/wmalosslessdec.c b/libavcodec/wmalosslessdec.c index e6e34767bb..72535d5030 100644 --- a/libavcodec/wmalosslessdec.c +++ b/libavcodec/wmalosslessdec.c @@ -486,7 +486,7 @@ static int decode_cdlms(WmallDecodeCtx *s) if ((1 << cbits) < s->cdlms[c][i].scaling + 1) cbits++; - s->cdlms[c][i].bitsend = get_bits(&s->gb, cbits) + 2; + s->cdlms[c][i].bitsend = (cbits ? get_bits(&s->gb, cbits) : 0) + 2; shift_l = 32 - s->cdlms[c][i].bitsend; shift_r = 32 - s->cdlms[c][i].scaling - 2; for (j = 0; j < s->cdlms[c][i].coefsend; j++) @@ -1028,6 +1028,7 @@ static int decode_frame(WmallDecodeCtx *s) if ((ret = ff_get_buffer(s->avctx, s->frame, 0)) < 0) { /* return an error if no frame could be decoded at all */ s->packet_loss = 1; + s->frame->nb_samples = 0; return ret; } for (i = 0; i < s->num_channels; i++) { diff --git a/libavcodec/wmaprodec.c b/libavcodec/wmaprodec.c index cc7ad0d408..fb4e1e3815 100644 --- a/libavcodec/wmaprodec.c +++ b/libavcodec/wmaprodec.c @@ -300,6 +300,12 @@ static av_cold int decode_init(AVCodecContext *avctx) s->decode_flags = AV_RL16(edata_ptr+14); channel_mask = AV_RL32(edata_ptr+2); s->bits_per_sample = AV_RL16(edata_ptr); + + if (s->bits_per_sample > 32 || s->bits_per_sample < 1) { + avpriv_request_sample(avctx, "bits per sample is %d", s->bits_per_sample); + return AVERROR_PATCHWELCOME; + } + /** dump the extradata */ for (i = 0; i < avctx->extradata_size; i++) av_dlog(avctx, "[%x] ", avctx->extradata[i]); @@ -477,7 +483,7 @@ static av_cold int decode_init(AVCodecContext *avctx) /** calculate subwoofer cutoff values */ for (i = 0; i < num_possible_block_sizes; i++) { int block_size = s->samples_per_frame >> i; - int cutoff = (440*block_size + 3 * (s->avctx->sample_rate >> 1) - 1) + int cutoff = (440*block_size + 3LL * (s->avctx->sample_rate >> 1) - 1) / s->avctx->sample_rate; s->subwoofer_cutoffs[i] = av_clip(cutoff, 4, block_size); } @@ -1623,6 +1629,11 @@ static int decode_packet(AVCodecContext *avctx, void *data, s->packet_done = 1; } + if (remaining_bits(s, gb) < 0) { + av_log(avctx, AV_LOG_ERROR, "Overread %d\n", -remaining_bits(s, gb)); + s->packet_loss = 1; + } + if (s->packet_done && !s->packet_loss && remaining_bits(s, gb) > 0) { /** save the rest of the data so that it can be decoded diff --git a/libavcodec/wmavoice.c b/libavcodec/wmavoice.c index c2737abd47..1c9958891f 100644 --- a/libavcodec/wmavoice.c +++ b/libavcodec/wmavoice.c @@ -1982,7 +1982,14 @@ static int wmavoice_decode_packet(AVCodecContext *ctx, void *data, *got_frame_ptr) { cnt += s->spillover_nbits; s->skip_bits_next = cnt & 7; - return cnt >> 3; + res = cnt >> 3; + if (res > avpkt->size) { + av_log(ctx, AV_LOG_ERROR, + "Trying to skip %d bytes in packet of size %d\n", + res, avpkt->size); + return AVERROR_INVALIDDATA; + } + return res; } else skip_bits_long (gb, s->spillover_nbits - cnt + get_bits_count(gb)); // resync @@ -2001,7 +2008,14 @@ static int wmavoice_decode_packet(AVCodecContext *ctx, void *data, } else if (*got_frame_ptr) { int cnt = get_bits_count(gb); s->skip_bits_next = cnt & 7; - return cnt >> 3; + res = cnt >> 3; + if (res > avpkt->size) { + av_log(ctx, AV_LOG_ERROR, + "Trying to skip %d bytes in packet of size %d\n", + res, avpkt->size); + return AVERROR_INVALIDDATA; + } + return res; } else if ((s->sframe_cache_size = pos) > 0) { /* rewind bit reader to start of last (incomplete) superframe... */ init_get_bits(gb, avpkt->data, size << 3); diff --git a/libavcodec/x86/h264_weight.asm b/libavcodec/x86/h264_weight.asm index b4fb9db309..1e1219ddde 100644 --- a/libavcodec/x86/h264_weight.asm +++ b/libavcodec/x86/h264_weight.asm @@ -135,8 +135,11 @@ WEIGHT_FUNC_HALF_MM 8, 8 add off_regd, 1 or off_regd, 1 add r4, 1 + cmp r6d, 128 + je .nonnormal cmp r5, 128 jne .normal +.nonnormal sar r5, 1 sar r6, 1 sar off_regd, 1 diff --git a/libavcodec/x86/lossless_audiodsp.asm b/libavcodec/x86/lossless_audiodsp.asm index 39395fecca..64b769f7d4 100644 --- a/libavcodec/x86/lossless_audiodsp.asm +++ b/libavcodec/x86/lossless_audiodsp.asm @@ -26,12 +26,6 @@ SECTION_TEXT ; int ff_scalarproduct_and_madd_int16(int16_t *v1, int16_t *v2, int16_t *v3, ; int order, int mul) cglobal scalarproduct_and_madd_int16, 4,4,8, v1, v2, v3, order, mul -%if mmsize == 16 - test orderq, 8 - jnz scalarproduct_and_madd_int16_fallback -%else - scalarproduct_and_madd_int16_fallback -%endif shl orderq, 1 movd m7, mulm %if mmsize == 16 @@ -123,8 +117,6 @@ align 16 ; int order, int mul) INIT_XMM ssse3 cglobal scalarproduct_and_madd_int16, 4,5,10, v1, v2, v3, order, mul - test orderq, 8 - jnz scalarproduct_and_madd_int16_fallback shl orderq, 1 movd m7, mulm pshuflw m7, m7, 0 diff --git a/libavcodec/x86/lossless_audiodsp_init.c b/libavcodec/x86/lossless_audiodsp_init.c index 4879dff1de..da1e9e8efc 100644 --- a/libavcodec/x86/lossless_audiodsp_init.c +++ b/libavcodec/x86/lossless_audiodsp_init.c @@ -31,17 +31,41 @@ int32_t ff_scalarproduct_and_madd_int16_ssse3(int16_t *v1, const int16_t *v2, const int16_t *v3, int order, int mul); +#if HAVE_YASM +static int32_t scalarproduct_and_madd_int16_sse2(int16_t *v1, const int16_t *v2, + const int16_t *v3, + int order, int mul) +{ + if (order & 8) + return ff_scalarproduct_and_madd_int16_mmxext(v1, v2, v3, order, mul); + else + return ff_scalarproduct_and_madd_int16_sse2(v1, v2, v3, order, mul); +} + +static int32_t scalarproduct_and_madd_int16_ssse3(int16_t *v1, const int16_t *v2, + const int16_t *v3, + int order, int mul) +{ + if (order & 8) + return ff_scalarproduct_and_madd_int16_mmxext(v1, v2, v3, order, mul); + else + return ff_scalarproduct_and_madd_int16_ssse3(v1, v2, v3, order, mul); +} +#endif + av_cold void ff_llauddsp_init_x86(LLAudDSPContext *c) { +#if HAVE_YASM int cpu_flags = av_get_cpu_flags(); if (EXTERNAL_MMXEXT(cpu_flags)) c->scalarproduct_and_madd_int16 = ff_scalarproduct_and_madd_int16_mmxext; if (EXTERNAL_SSE2(cpu_flags)) - c->scalarproduct_and_madd_int16 = ff_scalarproduct_and_madd_int16_sse2; + c->scalarproduct_and_madd_int16 = scalarproduct_and_madd_int16_sse2; if (EXTERNAL_SSSE3(cpu_flags) && !(cpu_flags & (AV_CPU_FLAG_SSE42 | AV_CPU_FLAG_3DNOW))) // cachesplit - c->scalarproduct_and_madd_int16 = ff_scalarproduct_and_madd_int16_ssse3; + c->scalarproduct_and_madd_int16 = scalarproduct_and_madd_int16_ssse3; +#endif } diff --git a/libavcodec/x86/mlpdsp_init.c b/libavcodec/x86/mlpdsp_init.c index dc0bc585c7..e9d9b1bf18 100644 --- a/libavcodec/x86/mlpdsp_init.c +++ b/libavcodec/x86/mlpdsp_init.c @@ -148,8 +148,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" @@ -178,8 +178,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/sbrdsp.asm b/libavcodec/x86/sbrdsp.asm index 6f2e4f48d9..f7f7fe9a14 100644 --- a/libavcodec/x86/sbrdsp.asm +++ b/libavcodec/x86/sbrdsp.asm @@ -381,6 +381,7 @@ apply_noise_main: %else %define count m_maxq %endif + movsxdifnidn noiseq, noised dec noiseq shl count, 2 %ifdef PIC diff --git a/libavcodec/x86/videodsp.asm b/libavcodec/x86/videodsp.asm index 25d43640ab..48f5ac0ce6 100644 --- a/libavcodec/x86/videodsp.asm +++ b/libavcodec/x86/videodsp.asm @@ -194,8 +194,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 @@ -251,12 +255,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/xface.c b/libavcodec/xface.c index 0ebf2f2ec0..8c0cbfdb84 100644 --- a/libavcodec/xface.c +++ b/libavcodec/xface.c @@ -24,6 +24,8 @@ * X-Face common data and utilities definition. */ +#include "libavutil/avassert.h" + #include "xface.h" void ff_big_add(BigInt *b, uint8_t a) @@ -43,6 +45,7 @@ void ff_big_add(BigInt *b, uint8_t a) c >>= XFACE_BITSPERWORD; } if (i == b->nb_words && c) { + av_assert0(b->nb_words < XFACE_MAX_WORDS); b->nb_words++; *w = c & XFACE_WORDMASK; } @@ -98,6 +101,7 @@ void ff_big_mul(BigInt *b, uint8_t a) return; if (a == 0) { /* treat this as a == WORDCARRY and just shift everything left a WORD */ + av_assert0(b->nb_words < XFACE_MAX_WORDS); i = b->nb_words++; w = b->words + i; while (i--) { @@ -116,6 +120,7 @@ void ff_big_mul(BigInt *b, uint8_t a) c >>= XFACE_BITSPERWORD; } if (c) { + av_assert0(b->nb_words < XFACE_MAX_WORDS); b->nb_words++; *w = c & XFACE_WORDMASK; } diff --git a/libavcodec/xface.h b/libavcodec/xface.h index 63df5d3308..0236d713ad 100644 --- a/libavcodec/xface.h +++ b/libavcodec/xface.h @@ -41,17 +41,17 @@ /* * Image is encoded as a big integer, using characters from '~' to * '!', for a total of 94 symbols. In order to express - * 48x48*2=8*XFACE_MAX_WORDS=4608 - * bits, we need a total of 704 digits, as given by: - * ceil(lg_94(2^4608)) = 704 + * 48x48 pixels with the worst case encoding 666 symbols should + * be sufficient. */ -#define XFACE_MAX_DIGITS 704 +#define XFACE_MAX_DIGITS 666 #define XFACE_BITSPERWORD 8 #define XFACE_WORDCARRY (1 << XFACE_BITSPERWORD) #define XFACE_WORDMASK (XFACE_WORDCARRY - 1) -#define XFACE_MAX_WORDS ((XFACE_PIXELS * 2 + XFACE_BITSPERWORD - 1) / XFACE_BITSPERWORD) +// This must be larger or equal to log256(94^XFACE_MAX_DIGITS) +#define XFACE_MAX_WORDS 546 /* Portable, very large unsigned integer arithmetic is needed. * Implementation uses arrays of WORDs. */ diff --git a/libavcodec/xwddec.c b/libavcodec/xwddec.c index 62dfdace16..18b1f93d2e 100644 --- a/libavcodec/xwddec.c +++ b/libavcodec/xwddec.c @@ -141,7 +141,7 @@ static int xwd_decode_frame(AVCodecContext *avctx, void *data, return AVERROR_INVALIDDATA; } - if (bytestream2_get_bytes_left(&gb) < ncolors * XWD_CMAP_SIZE + avctx->height * lsize) { + if (bytestream2_get_bytes_left(&gb) < ncolors * XWD_CMAP_SIZE + (uint64_t)avctx->height * lsize) { av_log(avctx, AV_LOG_ERROR, "input buffer too small\n"); return AVERROR_INVALIDDATA; } diff --git a/libavcodec/zmbv.c b/libavcodec/zmbv.c index c16d912117..82ae169ef4 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/libavdevice/avdevice.c b/libavdevice/avdevice.c index 755f251727..844b20089c 100644 --- a/libavdevice/avdevice.c +++ b/libavdevice/avdevice.c @@ -23,6 +23,9 @@ #include "avdevice.h" #include "config.h" +#include "libavutil/ffversion.h" +const char av_device_ffversion[] = "FFmpeg version " FFMPEG_VERSION; + #define E AV_OPT_FLAG_ENCODING_PARAM #define D AV_OPT_FLAG_DECODING_PARAM #define A AV_OPT_FLAG_AUDIO_PARAM @@ -131,9 +134,9 @@ int avdevice_app_to_dev_control_message(struct AVFormatContext *s, enum AVAppToD int avdevice_dev_to_app_control_message(struct AVFormatContext *s, enum AVDevToAppMessageType type, void *data, size_t data_size) { - if (!s->control_message_cb) + if (!av_format_get_control_message_cb(s)) return AVERROR(ENOSYS); - return s->control_message_cb(s, type, data, data_size); + return av_format_get_control_message_cb(s)(s, type, data, data_size); } int avdevice_capabilities_create(AVDeviceCapabilitiesQuery **caps, AVFormatContext *s, diff --git a/libavdevice/iec61883.c b/libavdevice/iec61883.c index 0900ffadf7..b29aad1d48 100644 --- a/libavdevice/iec61883.c +++ b/libavdevice/iec61883.c @@ -350,7 +350,7 @@ static int iec61883_read_header(AVFormatContext *context) if (!dv->max_packets) dv->max_packets = 100; - if (dv->type == IEC61883_HDV) { + if (CONFIG_MPEGTS_DEMUXER && dv->type == IEC61883_HDV) { /* Init HDV receive */ @@ -444,7 +444,7 @@ static int iec61883_close(AVFormatContext *context) pthread_mutex_destroy(&dv->mutex); #endif - if (dv->type == IEC61883_HDV) { + if (CONFIG_MPEGTS_DEMUXER && dv->type == IEC61883_HDV) { iec61883_mpeg2_recv_stop(dv->iec61883_mpeg2); iec61883_mpeg2_close(dv->iec61883_mpeg2); avpriv_mpegts_parse_close(dv->mpeg_demux); diff --git a/libavdevice/lavfi.c b/libavdevice/lavfi.c index 1398ece508..f6c92bcac2 100644 --- a/libavdevice/lavfi.c +++ b/libavdevice/lavfi.c @@ -339,7 +339,7 @@ static int lavfi_read_packet(AVFormatContext *avctx, AVPacket *pkt) continue; } else if (ret < 0) return ret; - d = av_rescale_q(frame->pts, tb, AV_TIME_BASE_Q); + d = av_rescale_q_rnd(frame->pts, tb, AV_TIME_BASE_Q, AV_ROUND_NEAR_INF|AV_ROUND_PASS_MINMAX); av_dlog(avctx, "sink_idx:%d time:%f\n", i, d); av_frame_unref(frame); diff --git a/libavdevice/xcbgrab.c b/libavdevice/xcbgrab.c index df8de20459..1a06d33b41 100644 --- a/libavdevice/xcbgrab.c +++ b/libavdevice/xcbgrab.c @@ -144,13 +144,25 @@ static int xcbgrab_frame(AVFormatContext *s, AVPacket *pkt) xcb_get_image_cookie_t iq; xcb_get_image_reply_t *img; xcb_drawable_t drawable = c->screen->root; + xcb_generic_error_t *e = NULL; uint8_t *data; int length, ret; iq = xcb_get_image(c->conn, XCB_IMAGE_FORMAT_Z_PIXMAP, drawable, c->x, c->y, c->width, c->height, ~0); - img = xcb_get_image_reply(c->conn, iq, NULL); + img = xcb_get_image_reply(c->conn, iq, &e); + + if (e) { + av_log(s, AV_LOG_ERROR, + "Cannot get the image data " + "event_error: response_type:%u error_code:%u " + "sequence:%u resource_id:%u minor_code:%u major_code:%u.\n", + e->response_type, e->error_code, + e->sequence, e->resource_id, e->minor_code, e->major_code); + return AVERROR(EACCES); + } + if (!img) return AVERROR(EAGAIN); @@ -404,7 +416,7 @@ static int xcbgrab_read_packet(AVFormatContext *s, AVPacket *pkt) ret = xcbgrab_frame(s, pkt); #if CONFIG_LIBXCB_XFIXES - if (c->draw_mouse && p->same_screen) + if (ret >= 0 && c->draw_mouse && p->same_screen) xcbgrab_draw_mouse(s, pkt, p, geo); #endif @@ -515,8 +527,17 @@ static int create_stream(AVFormatContext *s) gc = xcb_get_geometry(c->conn, c->screen->root); geo = xcb_get_geometry_reply(c->conn, gc, NULL); - c->width = FFMIN(geo->width, c->width); - c->height = FFMIN(geo->height, c->height); + if (c->x + c->width > geo->width || + c->y + c->height > geo->height) { + av_log(s, AV_LOG_ERROR, + "Capture area %dx%d at position %d.%d " + "outside the screen size %dx%d\n", + c->width, c->height, + c->x, c->y, + geo->width, geo->height); + return AVERROR(EINVAL); + } + c->time_base = (AVRational){ st->avg_frame_rate.den, st->avg_frame_rate.num }; c->time_frame = av_gettime(); diff --git a/libavfilter/af_amix.c b/libavfilter/af_amix.c index e40969f70c..fd9d13556f 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_aresample.c b/libavfilter/af_aresample.c index 57ac3978be..6cb765df1b 100644 --- a/libavfilter/af_aresample.c +++ b/libavfilter/af_aresample.c @@ -87,15 +87,24 @@ static int query_formats(AVFilterContext *ctx) AVFilterLink *inlink = ctx->inputs[0]; AVFilterLink *outlink = ctx->outputs[0]; - AVFilterFormats *in_formats = ff_all_formats(AVMEDIA_TYPE_AUDIO); - AVFilterFormats *out_formats; - AVFilterFormats *in_samplerates = ff_all_samplerates(); - AVFilterFormats *out_samplerates; - AVFilterChannelLayouts *in_layouts = ff_all_channel_counts(); - AVFilterChannelLayouts *out_layouts; + AVFilterFormats *in_formats, *out_formats; + AVFilterFormats *in_samplerates, *out_samplerates; + AVFilterChannelLayouts *in_layouts, *out_layouts; + + in_formats = ff_all_formats(AVMEDIA_TYPE_AUDIO); + if (!in_formats) + return AVERROR(ENOMEM); ff_formats_ref (in_formats, &inlink->out_formats); + + in_samplerates = ff_all_samplerates(); + if (!in_samplerates) + return AVERROR(ENOMEM); ff_formats_ref (in_samplerates, &inlink->out_samplerates); + + in_layouts = ff_all_channel_counts(); + if (!in_layouts) + return AVERROR(ENOMEM); ff_channel_layouts_ref(in_layouts, &inlink->out_channel_layouts); if(out_rate > 0) { diff --git a/libavfilter/af_asyncts.c b/libavfilter/af_asyncts.c index 5f8e1f61cc..4be093b194 100644 --- a/libavfilter/af_asyncts.c +++ b/libavfilter/af_asyncts.c @@ -205,7 +205,7 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *buf) delta = pts - s->pts - get_delay(s); out_size = avresample_available(s->avr); - if (labs(delta) > s->min_delta || + if (llabs(delta) > s->min_delta || (s->first_frame && delta && s->first_pts != AV_NOPTS_VALUE)) { av_log(ctx, AV_LOG_VERBOSE, "Discontinuity - %"PRId64" samples.\n", delta); out_size = av_clipl_int32((int64_t)out_size + delta); diff --git a/libavfilter/af_join.c b/libavfilter/af_join.c index a1717c63b9..71a454bba7 100644 --- a/libavfilter/af_join.c +++ b/libavfilter/af_join.c @@ -214,6 +214,8 @@ static av_cold int join_init(AVFilterContext *ctx) snprintf(name, sizeof(name), "input%d", i); pad.type = AVMEDIA_TYPE_AUDIO; pad.name = av_strdup(name); + if (!pad.name) + return AVERROR(ENOMEM); pad.filter_frame = filter_frame; pad.needs_fifo = 1; diff --git a/libavfilter/avfilter.c b/libavfilter/avfilter.c index 963f5e6479..b37ff1f2c8 100644 --- a/libavfilter/avfilter.c +++ b/libavfilter/avfilter.c @@ -37,6 +37,9 @@ #include "formats.h" #include "internal.h" +#include "libavutil/ffversion.h" +const char av_filter_ffversion[] = "FFmpeg version " FFMPEG_VERSION; + static int ff_filter_frame_framed(AVFilterLink *link, AVFrame *frame); void ff_tlog_ref(void *ctx, AVFrame *ref, int end) diff --git a/libavfilter/lavfutils.c b/libavfilter/lavfutils.c index 80310d2fea..095f84baad 100644 --- a/libavfilter/lavfutils.c +++ b/libavfilter/lavfutils.c @@ -32,6 +32,7 @@ int ff_load_image(uint8_t *data[4], int linesize[4], AVFrame *frame; int frame_decoded, ret = 0; AVPacket pkt; + AVDictionary *opt=NULL; av_init_packet(&pkt); @@ -57,7 +58,8 @@ int ff_load_image(uint8_t *data[4], int linesize[4], goto end; } - if ((ret = avcodec_open2(codec_ctx, codec, NULL)) < 0) { + av_dict_set(&opt, "thread_type", "slice", 0); + if ((ret = avcodec_open2(codec_ctx, codec, &opt)) < 0) { av_log(log_ctx, AV_LOG_ERROR, "Failed to open codec\n"); goto end; } @@ -97,6 +99,7 @@ end: avcodec_close(codec_ctx); avformat_close_input(&format_ctx); av_freep(&frame); + av_dict_free(&opt); if (ret < 0) av_log(log_ctx, AV_LOG_ERROR, "Error loading image file '%s'\n", filename); diff --git a/libavfilter/split.c b/libavfilter/split.c index 6abd5ee2e0..7353810677 100644 --- a/libavfilter/split.c +++ b/libavfilter/split.c @@ -52,6 +52,8 @@ static av_cold int split_init(AVFilterContext *ctx) snprintf(name, sizeof(name), "output%d", i); pad.type = ctx->filter->inputs[0].type; pad.name = av_strdup(name); + if (!pad.name) + return AVERROR(ENOMEM); ff_insert_outpad(ctx, i, &pad); } diff --git a/libavfilter/src_movie.c b/libavfilter/src_movie.c index 0b97b827e4..6df52f75cc 100644 --- a/libavfilter/src_movie.c +++ b/libavfilter/src_movie.c @@ -240,7 +240,7 @@ static av_cold int movie_common_init(AVFilterContext *ctx) timestamp = movie->seek_point; // add the stream start time, should it exist if (movie->format_ctx->start_time != AV_NOPTS_VALUE) { - if (timestamp > INT64_MAX - movie->format_ctx->start_time) { + if (timestamp > 0 && movie->format_ctx->start_time > INT64_MAX - timestamp) { av_log(ctx, AV_LOG_ERROR, "%s: seek value overflow with start_time:%"PRId64" seek_point:%"PRId64"\n", movie->file_name, movie->format_ctx->start_time, movie->seek_point); @@ -289,6 +289,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_dctdnoiz.c b/libavfilter/vf_dctdnoiz.c index a9017b1f1c..7246b01d0b 100644 --- a/libavfilter/vf_dctdnoiz.c +++ b/libavfilter/vf_dctdnoiz.c @@ -534,7 +534,7 @@ static int config_input(AVFilterLink *inlink) /* each slice will need to (pre & re)process the top and bottom block of * the previous one in in addition to its processing area. This is because * each pixel is averaged by all the surrounding blocks */ - slice_h = (int)ceilf(s->pr_height / s->nb_threads) + (s->bsize - 1) * 2; + slice_h = (int)ceilf(s->pr_height / (float)s->nb_threads) + (s->bsize - 1) * 2; for (i = 0; i < s->nb_threads; i++) { s->slices[i] = av_malloc_array(linesize, slice_h * sizeof(*s->slices[i])); if (!s->slices[i]) diff --git a/libavfilter/vf_drawtext.c b/libavfilter/vf_drawtext.c index d20f8055c4..864ff63e8c 100644 --- a/libavfilter/vf_drawtext.c +++ b/libavfilter/vf_drawtext.c @@ -1174,7 +1174,9 @@ static int draw_text(AVFilterContext *ctx, AVFrame *frame, dummy.code = code; glyph = av_tree_find(s->glyphs, &dummy, glyph_cmp, NULL); if (!glyph) { - load_glyph(ctx, &glyph, code); + ret = load_glyph(ctx, &glyph, code); + if (ret < 0) + return ret; } y_min = FFMIN(glyph->bbox.yMin, y_min); diff --git a/libavfilter/vf_fade.c b/libavfilter/vf_fade.c index 80ce75dcda..a7597cdff0 100644 --- a/libavfilter/vf_fade.c +++ b/libavfilter/vf_fade.c @@ -138,7 +138,9 @@ static int config_props(AVFilterLink *inlink) s->hsub = pixdesc->log2_chroma_w; s->vsub = pixdesc->log2_chroma_h; - s->bpp = av_get_bits_per_pixel(pixdesc) >> 3; + s->bpp = pixdesc->flags & AV_PIX_FMT_FLAG_PLANAR ? + 1 : + av_get_bits_per_pixel(pixdesc) >> 3; s->alpha &= !!(pixdesc->flags & AV_PIX_FMT_FLAG_ALPHA); s->is_packed_rgb = ff_fill_rgba_map(s->rgba_map, inlink->format) >= 0; diff --git a/libavfilter/vf_framepack.c b/libavfilter/vf_framepack.c index 8a7d4e8f32..f5215fed9d 100644 --- a/libavfilter/vf_framepack.c +++ b/libavfilter/vf_framepack.c @@ -82,6 +82,7 @@ static int config_output(AVFilterLink *outlink) int width = ctx->inputs[LEFT]->w; int height = ctx->inputs[LEFT]->h; AVRational time_base = ctx->inputs[LEFT]->time_base; + AVRational frame_rate = ctx->inputs[LEFT]->frame_rate; // check size and fps match on the other input if (width != ctx->inputs[RIGHT]->w || @@ -93,11 +94,18 @@ static int config_output(AVFilterLink *outlink) return AVERROR_INVALIDDATA; } else if (av_cmp_q(time_base, ctx->inputs[RIGHT]->time_base) != 0) { av_log(ctx, AV_LOG_ERROR, - "Left and right framerates differ (%d/%d vs %d/%d).\n", + "Left and right time bases differ (%d/%d vs %d/%d).\n", time_base.num, time_base.den, ctx->inputs[RIGHT]->time_base.num, ctx->inputs[RIGHT]->time_base.den); return AVERROR_INVALIDDATA; + } else if (av_cmp_q(frame_rate, ctx->inputs[RIGHT]->frame_rate) != 0) { + av_log(ctx, AV_LOG_ERROR, + "Left and right framerates differ (%d/%d vs %d/%d).\n", + frame_rate.num, frame_rate.den, + ctx->inputs[RIGHT]->frame_rate.num, + ctx->inputs[RIGHT]->frame_rate.den); + return AVERROR_INVALIDDATA; } s->pix_desc = av_pix_fmt_desc_get(outlink->format); @@ -108,6 +116,8 @@ static int config_output(AVFilterLink *outlink) switch (s->format) { case AV_STEREO3D_FRAMESEQUENCE: time_base.den *= 2; + frame_rate.num *= 2; + s->double_pts = AV_NOPTS_VALUE; break; case AV_STEREO3D_COLUMNS: @@ -126,6 +136,7 @@ static int config_output(AVFilterLink *outlink) outlink->w = width; outlink->h = height; outlink->time_base = time_base; + outlink->frame_rate= frame_rate; return 0; } diff --git a/libavfilter/vf_mpdecimate.c b/libavfilter/vf_mpdecimate.c index 3ed96024c3..94c9e0bd9d 100644 --- a/libavfilter/vf_mpdecimate.c +++ b/libavfilter/vf_mpdecimate.c @@ -120,10 +120,13 @@ static int decimate_frame(AVFilterContext *ctx, cur->data[plane], cur->linesize[plane], ref->data[plane], ref->linesize[plane], FF_CEIL_RSHIFT(ref->width, hsub), - FF_CEIL_RSHIFT(ref->height, vsub))) + FF_CEIL_RSHIFT(ref->height, vsub))) { + emms_c(); return 0; + } } + emms_c(); return 1; } diff --git a/libavfilter/vf_sab.c b/libavfilter/vf_sab.c index aa38b533fe..b8af27cdcd 100644 --- a/libavfilter/vf_sab.c +++ b/libavfilter/vf_sab.c @@ -220,6 +220,19 @@ static int config_props(AVFilterLink *inlink) #define NB_PLANES 4 +static inline int mirror(int x, int w) +{ + if (!w) + return 0; + + while ((unsigned)x > (unsigned)w) { + x = -x; + if (x < 0) + x += 2 * w; + } + return x; +} + static void blur(uint8_t *dst, const int dst_linesize, const uint8_t *src, const int src_linesize, const int w, const int h, FilterParam *fp) @@ -253,8 +266,7 @@ static void blur(uint8_t *dst, const int dst_linesize, for (dy = 0; dy < radius*2 + 1; dy++) { int dx; int iy = y+dy - radius; - if (iy < 0) iy = -iy; - else if (iy >= h) iy = h+h-iy-1; + iy = mirror(iy, h-1); for (dx = 0; dx < radius*2 + 1; dx++) { const int ix = x+dx - radius; @@ -265,13 +277,11 @@ static void blur(uint8_t *dst, const int dst_linesize, for (dy = 0; dy < radius*2+1; dy++) { int dx; int iy = y+dy - radius; - if (iy < 0) iy = -iy; - else if (iy >= h) iy = h+h-iy-1; + iy = mirror(iy, h-1); for (dx = 0; dx < radius*2 + 1; dx++) { int ix = x+dx - radius; - if (ix < 0) ix = -ix; - else if (ix >= w) ix = w+w-ix-1; + ix = mirror(ix, w-1); UPDATE_FACTOR; } } diff --git a/libavfilter/vf_scale.c b/libavfilter/vf_scale.c index 64b88c2357..237f3b8b5e 100644 --- a/libavfilter/vf_scale.c +++ b/libavfilter/vf_scale.c @@ -512,6 +512,8 @@ static int filter_frame(AVFilterLink *link, AVFrame *in) sws_setColorspaceDetails(scale->isws[1], inv_table, in_full, table, out_full, brightness, contrast, saturation); + + av_frame_set_color_range(out, out_full ? AVCOL_RANGE_JPEG : AVCOL_RANGE_MPEG); } av_reduce(&out->sample_aspect_ratio.num, &out->sample_aspect_ratio.den, diff --git a/libavfilter/vf_transpose.c b/libavfilter/vf_transpose.c index d9b165cfeb..6ae5fce815 100644 --- a/libavfilter/vf_transpose.c +++ b/libavfilter/vf_transpose.c @@ -152,7 +152,7 @@ static int filter_slice(AVFilterContext *ctx, void *arg, int jobnr, int hsub = plane == 1 || plane == 2 ? trans->hsub : 0; int vsub = plane == 1 || plane == 2 ? trans->vsub : 0; int pixstep = trans->pixsteps[plane]; - int inh = in->height >> vsub; + int inh = FF_CEIL_RSHIFT(in->height, vsub); int outw = FF_CEIL_RSHIFT(out->width, hsub); int outh = FF_CEIL_RSHIFT(out->height, vsub); int start = (outh * jobnr ) / nb_jobs; diff --git a/libavfilter/x86/vf_hqdn3d.asm b/libavfilter/x86/vf_hqdn3d.asm index 961127e670..e3b1bdca53 100644 --- a/libavfilter/x86/vf_hqdn3d.asm +++ b/libavfilter/x86/vf_hqdn3d.asm @@ -27,8 +27,8 @@ SECTION .text %if lut_bits != 8 sar %1q, 8-lut_bits %endif - movsx %1d, word [%3q+%1q*2] - add %1d, %2d + movsx %1q, word [%3q+%1q*2] + add %1q, %2q %endmacro %macro LOAD 3 ; dstreg, x, bitdepth diff --git a/libavformat/Makefile b/libavformat/Makefile index c1b5acee93..6bf0761b21 100644 --- a/libavformat/Makefile +++ b/libavformat/Makefile @@ -377,7 +377,7 @@ OBJS-$(CONFIG_RTP_MUXER) += rtp.o \ rtpenc_h264.o \ rtpenc_vp8.o \ rtpenc_xiph.o \ - avc.o + avc.o hevc.o OBJS-$(CONFIG_RTSP_DEMUXER) += rtsp.o rtspdec.o httpauth.o \ urldecode.o OBJS-$(CONFIG_RTSP_MUXER) += rtsp.o rtspenc.o httpauth.o \ @@ -519,6 +519,9 @@ OBJS-$(CONFIG_UNIX_PROTOCOL) += unix.o OBJS-$(HAVE_LIBC_MSVCRT) += file_open.o +# libavdevice dependencies +OBJS-$(CONFIG_IEC61883_INDEV) += dv.o + # Windows resource file SLIBOBJS-$(HAVE_GNU_WINDRES) += avformatres.o diff --git a/libavformat/act.c b/libavformat/act.c index 3f223d57b6..faa693ccb9 100644 --- a/libavformat/act.c +++ b/libavformat/act.c @@ -75,7 +75,7 @@ static int read_header(AVFormatContext *s) avio_skip(pb, 16); size=avio_rl32(pb); - ff_get_wav_header(pb, st->codec, size); + ff_get_wav_header(s, pb, st->codec, size); /* 8000Hz (Fine-rec) file format has 10 bytes long diff --git a/libavformat/adxdec.c b/libavformat/adxdec.c index ddaa201179..e7107ac579 100644 --- a/libavformat/adxdec.c +++ b/libavformat/adxdec.c @@ -40,6 +40,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); @@ -83,8 +88,14 @@ static int adx_read_header(AVFormatContext *s) av_log(s, AV_LOG_ERROR, "Invalid extradata size.\n"); return AVERROR_INVALIDDATA; } + avctx->channels = AV_RB8(avctx->extradata + 7); avctx->sample_rate = AV_RB32(avctx->extradata + 8); + if (avctx->channels <= 0) { + av_log(s, AV_LOG_ERROR, "invalid number of channels %d\n", avctx->channels); + return AVERROR_INVALIDDATA; + } + st->codec->codec_type = AVMEDIA_TYPE_AUDIO; st->codec->codec_id = s->iformat->raw_codec_id; diff --git a/libavformat/apngdec.c b/libavformat/apngdec.c index d97b015a79..6deff3b66b 100644 --- a/libavformat/apngdec.c +++ b/libavformat/apngdec.c @@ -150,7 +150,8 @@ static int apng_read_header(AVFormatContext *s) AVIOContext *pb = s->pb; uint32_t len, tag; AVStream *st; - int ret = AVERROR_INVALIDDATA, acTL_found = 0; + int acTL_found = 0; + int64_t ret = AVERROR_INVALIDDATA; /* verify PNGSIG */ if (avio_rb64(pb) != PNGSIG) @@ -321,7 +322,7 @@ static int decode_fctl_chunk(AVFormatContext *s, APNGDemuxContext *ctx, AVPacket static int apng_read_packet(AVFormatContext *s, AVPacket *pkt) { APNGDemuxContext *ctx = s->priv_data; - int ret; + int64_t ret; int64_t size; AVIOContext *pb = s->pb; uint32_t len, tag; @@ -404,7 +405,7 @@ static int apng_read_packet(AVFormatContext *s, AVPacket *pkt) return 0; default: { - char tag_buf[5]; + char tag_buf[32]; av_get_codec_tag_string(tag_buf, sizeof(tag_buf), tag); avpriv_request_sample(s, "In-stream tag=%s (0x%08X) len=%"PRIu32, tag_buf, tag, len); diff --git a/libavformat/asfdec.c b/libavformat/asfdec.c index 7f7bb4d5d4..fcb4be42b2 100644 --- a/libavformat/asfdec.c +++ b/libavformat/asfdec.c @@ -423,7 +423,7 @@ static int asf_read_stream_properties(AVFormatContext *s, int64_t size) st->codec->codec_type = type; if (type == AVMEDIA_TYPE_AUDIO) { - int ret = ff_get_wav_header(pb, st->codec, type_specific_size); + int ret = ff_get_wav_header(s, pb, st->codec, type_specific_size); if (ret < 0) return ret; if (is_dvr_ms_audio) { @@ -1484,7 +1484,7 @@ static int asf_build_simple_index(AVFormatContext *s, int stream_index) ff_asf_guid g; ASFContext *asf = s->priv_data; int64_t current_pos = avio_tell(s->pb); - int ret = 0; + int64_t ret; if((ret = avio_seek(s->pb, asf->data_object_offset + asf->data_object_size, SEEK_SET)) < 0) { return ret; @@ -1554,7 +1554,7 @@ static int asf_read_seek(AVFormatContext *s, int stream_index, /* Try using the protocol's read_seek if available */ if (s->pb) { - int ret = avio_seek_time(s->pb, stream_index, pts, flags); + int64_t ret = avio_seek_time(s->pb, stream_index, pts, flags); if (ret >= 0) asf_reset_header(s); if (ret != AVERROR(ENOSYS)) diff --git a/libavformat/asfenc.c b/libavformat/asfenc.c index fbf6158cef..d4a72da893 100644 --- a/libavformat/asfenc.c +++ b/libavformat/asfenc.c @@ -664,6 +664,7 @@ static int asf_write_header(AVFormatContext *s) * It is needed to use asf as a streamable format. */ if (asf_write_header1(s, 0, DATA_HEADER_SIZE) < 0) { //av_free(asf); + av_freep(&asf->index_ptr); return -1; } @@ -928,6 +929,11 @@ static int asf_write_packet(AVFormatContext *s, AVPacket *pkt) pts = (pkt->pts != AV_NOPTS_VALUE) ? pkt->pts : pkt->dts; av_assert0(pts != AV_NOPTS_VALUE); + if ( pts < - PREROLL_TIME + || pts > (INT_MAX-3)/10000LL * ASF_INDEXED_INTERVAL - PREROLL_TIME) { + av_log(s, AV_LOG_ERROR, "input pts %"PRId64" is invalid\n", pts); + return AVERROR(EINVAL); + } pts *= 10000; asf->duration = FFMAX(asf->duration, pts + pkt->duration * 10000); diff --git a/libavformat/avformat.h b/libavformat/avformat.h index 2e54ed1f01..c2cef3cc4a 100644 --- a/libavformat/avformat.h +++ b/libavformat/avformat.h @@ -78,6 +78,18 @@ * if its AVClass is non-NULL, and the protocols layer. See the discussion on * nesting in @ref avoptions documentation to learn how to access those. * + * @section urls + * URL strings in libavformat are made of a scheme/protocol, a ':', and a + * scheme specific string. URLs without a scheme and ':' used for local files + * are supported but deprecated. "file:" should be used for local files. + * + * It is important that the scheme string is not taken from untrusted + * sources without checks. + * + * Note that some schemes/protocols are quite powerful, allowing access to + * both local and remote files, parts of them, concatenations of them, local + * audio and video devices and so on. + * * @defgroup lavf_decoding Demuxing * @{ * Demuxers read a media file and split it into chunks of data (@em packets). A @@ -88,10 +100,10 @@ * cleanup. * * @section lavf_decoding_open Opening a media file - * The minimum information required to open a file is its URL or filename, which + * The minimum information required to open a file is its URL, which * is passed to avformat_open_input(), as in the following code: * @code - * const char *url = "in.mp3"; + * const char *url = "file:in.mp3"; * AVFormatContext *s = NULL; * int ret = avformat_open_input(&s, url, NULL, NULL); * if (ret < 0) @@ -916,7 +928,7 @@ typedef struct AVStream { /** * Stream information used internally by av_find_stream_info() */ -#define MAX_STD_TIMEBASES (30*12+7+6) +#define MAX_STD_TIMEBASES (30*12+30+3+6) struct { int64_t last_dts; int64_t duration_gcd; @@ -1985,7 +1997,7 @@ AVInputFormat *av_probe_input_format3(AVProbeData *pd, int is_opened, int *score * * @param pb the bytestream to probe * @param fmt the input format is put here - * @param filename the filename of the stream + * @param url the url of the stream * @param logctx the log context * @param offset the offset within the bytestream to probe from * @param max_probe_size the maximum probe buffer size (zero for default) @@ -1994,14 +2006,14 @@ AVInputFormat *av_probe_input_format3(AVProbeData *pd, int is_opened, int *score * AVERROR code otherwise */ int av_probe_input_buffer2(AVIOContext *pb, AVInputFormat **fmt, - const char *filename, void *logctx, + const char *url, void *logctx, unsigned int offset, unsigned int max_probe_size); /** * Like av_probe_input_buffer2() but returns 0 on success */ int av_probe_input_buffer(AVIOContext *pb, AVInputFormat **fmt, - const char *filename, void *logctx, + const char *url, void *logctx, unsigned int offset, unsigned int max_probe_size); /** @@ -2012,7 +2024,7 @@ int av_probe_input_buffer(AVIOContext *pb, AVInputFormat **fmt, * May be a pointer to NULL, in which case an AVFormatContext is allocated by this * function and written into ps. * Note that a user-supplied AVFormatContext will be freed on failure. - * @param filename Name of the stream to open. + * @param url URL of the stream to open. * @param fmt If non-NULL, this parameter forces a specific input format. * Otherwise the format is autodetected. * @param options A dictionary filled with AVFormatContext and demuxer-private options. @@ -2023,7 +2035,7 @@ int av_probe_input_buffer(AVIOContext *pb, AVInputFormat **fmt, * * @note If you want to use custom IO, preallocate the format context and set its pb field. */ -int avformat_open_input(AVFormatContext **ps, const char *filename, AVInputFormat *fmt, AVDictionary **options); +int avformat_open_input(AVFormatContext **ps, const char *url, AVInputFormat *fmt, AVDictionary **options); attribute_deprecated int av_demuxer_open(AVFormatContext *ic); diff --git a/libavformat/avidec.c b/libavformat/avidec.c index 78a6deae7d..161e76a1dc 100644 --- a/libavformat/avidec.c +++ b/libavformat/avidec.c @@ -36,6 +36,7 @@ #include "riff.h" #include "libavcodec/bytestream.h" #include "libavcodec/exif.h" +#include "libavformat/isom.h" typedef struct AVIStream { int64_t frame_offset; /* current frame (video) or byte (audio) counter @@ -447,6 +448,7 @@ static int calculate_bitrate(AVFormatContext *s) int64_t len = 0; AVStream *st = s->streams[i]; int64_t duration; + int64_t bitrate; for (j = 0; j < st->nb_index_entries; j++) len += st->index_entries[j].size; @@ -454,7 +456,10 @@ static int calculate_bitrate(AVFormatContext *s) 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); + bitrate = av_rescale(8*len, st->time_base.den, duration * st->time_base.num); + if (bitrate <= INT_MAX && bitrate > 0) { + st->codec->bit_rate = bitrate; + } } return 1; } @@ -685,6 +690,7 @@ static int avi_read_header(AVFormatContext *s) default: av_log(s, AV_LOG_INFO, "unknown stream type %X\n", tag1); } + ast->sample_size = FFMAX(ast->sample_size, 0); if (ast->sample_size == 0) { st->duration = st->nb_frames; if (st->duration > 0 && avi->io_fsize > 0 && avi->riff_end > avi->io_fsize) { @@ -771,6 +777,12 @@ static int avi_read_header(AVFormatContext *s) st->codec->codec_tag = tag1; st->codec->codec_id = ff_codec_get_id(ff_codec_bmp_tags, tag1); + if (!st->codec->codec_id) { + st->codec->codec_id = ff_codec_get_id(ff_codec_movvideo_tags, + tag1); + if (st->codec->codec_id) + av_log(s, AV_LOG_WARNING, "mov tag found in avi\n"); + } /* This is needed to get the pict type which is necessary * for generating correct pts. */ st->need_parsing = AVSTREAM_PARSE_HEADERS; @@ -794,7 +806,7 @@ static int avi_read_header(AVFormatContext *s) // avio_skip(pb, size - 5 * 4); break; case AVMEDIA_TYPE_AUDIO: - ret = ff_get_wav_header(pb, st->codec, size); + ret = ff_get_wav_header(s, pb, st->codec, size); if (ret < 0) return ret; ast->dshow_block_align = st->codec->block_align; @@ -1536,7 +1548,8 @@ static int avi_read_idx1(AVFormatContext *s, int size) ast = st->priv_data; if (first_packet && first_packet_pos) { - data_offset = first_packet_pos - pos; + if (avi->movi_list + 4 != pos || pos + 500 > first_packet_pos) + data_offset = first_packet_pos - pos; first_packet = 0; } pos += data_offset; diff --git a/libavformat/avio.c b/libavformat/avio.c index 326bb0aa78..78d15cc40d 100644 --- a/libavformat/avio.c +++ b/libavformat/avio.c @@ -155,9 +155,16 @@ static int url_alloc_for_protocol(URLContext **puc, struct URLProtocol *up, char sep= *++p; char *key, *val; p++; + + if (strcmp(up->name, "subfile")) + ret = AVERROR(EINVAL); + while(ret >= 0 && (key= strchr(p, sep)) && ppriv_data, p, key+1, 0); + if (strcmp(p, "start") && strcmp(p, "end")) { + ret = AVERROR_OPTION_NOT_FOUND; + } else + ret= av_opt_set(uc->priv_data, p, key+1, 0); if (ret == AVERROR_OPTION_NOT_FOUND) av_log(uc, AV_LOG_ERROR, "Key '%s' not found.\n", p); *val= *key= sep; @@ -222,7 +229,7 @@ static struct URLProtocol *url_find_protocol(const char *filename) size_t proto_len = strspn(filename, URL_SCHEME_CHARS); if (filename[proto_len] != ':' && - (filename[proto_len] != ',' || !strchr(filename + proto_len + 1, ':')) || + (strncmp(filename, "subfile,", 8) || !strchr(filename + proto_len + 1, ':')) || is_dos_path(filename)) strcpy(proto_str, "file"); else diff --git a/libavformat/aviobuf.c b/libavformat/aviobuf.c index f374314fba..20621baa0c 100644 --- a/libavformat/aviobuf.c +++ b/libavformat/aviobuf.c @@ -223,6 +223,9 @@ int64_t avio_seek(AVIOContext *s, int64_t offset, int whence) return offset1; offset += offset1; } + if (offset < 0) + return AVERROR(EINVAL); + offset1 = offset - pos; if (!s->must_flush && (!s->direct || !s->seek) && offset1 >= 0 && offset1 <= buffer_size) { @@ -355,6 +358,8 @@ int avio_put_str16le(AVIOContext *s, const char *str) invalid: av_log(s, AV_LOG_ERROR, "Invaid UTF8 sequence in avio_put_str16le\n"); err = AVERROR(EINVAL); + if (!*(q-1)) + break; } avio_wl16(s, 0); if (err) @@ -782,6 +787,7 @@ int ffio_ensure_seekback(AVIOContext *s, int64_t buf_size) int max_buffer_size = s->max_packet_size ? s->max_packet_size : IO_BUFFER_SIZE; int filled = s->buf_end - s->buffer; + ptrdiff_t checksum_ptr_offset = s->checksum_ptr ? s->checksum_ptr - s->buffer : -1; buf_size += s->buf_ptr - s->buffer + max_buffer_size; @@ -799,6 +805,8 @@ int ffio_ensure_seekback(AVIOContext *s, int64_t buf_size) s->buf_end = buffer + (s->buf_end - s->buffer); s->buffer = buffer; s->buffer_size = buf_size; + if (checksum_ptr_offset >= 0) + s->checksum_ptr = s->buffer + checksum_ptr_offset; return 0; } diff --git a/libavformat/bink.c b/libavformat/bink.c index 395c8d9aa8..350c64f7bb 100644 --- a/libavformat/bink.c +++ b/libavformat/bink.c @@ -194,7 +194,10 @@ static int read_header(AVFormatContext *s) return ret; } - avio_seek(pb, vst->index_entries[0].pos, SEEK_SET); + if (vst->index_entries) + avio_seek(pb, vst->index_entries[0].pos, SEEK_SET); + else + avio_skip(pb, 4); bink->current_track = -1; return 0; diff --git a/libavformat/bit.c b/libavformat/bit.c index 7b807b9bc1..138d2feadb 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/brstm.c b/libavformat/brstm.c index 19a4a2a96b..6afae73b2f 100644 --- a/libavformat/brstm.c +++ b/libavformat/brstm.c @@ -260,6 +260,16 @@ static int read_packet(AVFormatContext *s, AVPacket *pkt) if (codec->codec_id == AV_CODEC_ID_ADPCM_THP) { uint8_t *dst; + if (!b->adpc) { + av_log(s, AV_LOG_ERROR, "adpcm_thp requires ADPC chunk, but none was found.\n"); + return AVERROR_INVALIDDATA; + } + if (!b->table) { + b->table = av_mallocz(32 * codec->channels); + if (!b->table) + return AVERROR(ENOMEM); + } + if (av_new_packet(pkt, 8 + (32 + 4) * codec->channels + size) < 0) return AVERROR(ENOMEM); dst = pkt->data; diff --git a/libavformat/cdxl.c b/libavformat/cdxl.c index e3e379aef7..6d8e750b83 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/concat.c b/libavformat/concat.c index 81fe97082c..7bcc27905e 100644 --- a/libavformat/concat.c +++ b/libavformat/concat.c @@ -65,7 +65,10 @@ static av_cold int concat_open(URLContext *h, const char *uri, int flags) struct concat_data *data = h->priv_data; struct concat_nodes *nodes; - av_strstart(uri, "concat:", &uri); + if (!av_strstart(uri, "concat:", &uri)) { + av_log(h, AV_LOG_ERROR, "URL %s lacks prefix\n", uri); + return AVERROR(EINVAL); + } for (i = 0, len = 1; uri[i]; i++) { if (uri[i] == *AV_CAT_SEPARATOR) { diff --git a/libavformat/concatdec.c b/libavformat/concatdec.c index a2584d70e2..14e1cf663a 100644 --- a/libavformat/concatdec.c +++ b/libavformat/concatdec.c @@ -619,7 +619,7 @@ static int concat_seek(AVFormatContext *avf, int stream, static const AVOption options[] = { { "safe", "enable safe mode", - OFFSET(safe), AV_OPT_TYPE_INT, {.i64 = -1}, -1, 1, DEC }, + OFFSET(safe), AV_OPT_TYPE_INT, {.i64 = 1}, -1, 1, DEC }, { "auto_convert", "automatically convert bitstream format", OFFSET(auto_convert), AV_OPT_TYPE_INT, {.i64 = 0}, 0, 1, DEC }, { NULL } diff --git a/libavformat/crypto.c b/libavformat/crypto.c index c1754b0b11..22529fb521 100644 --- a/libavformat/crypto.c +++ b/libavformat/crypto.c @@ -122,7 +122,7 @@ static int crypto_open2(URLContext *h, const char *uri, int flags, AVDictionary c->key, c->keylen, "decryption key")) < 0) goto err; if ((ret = set_aes_arg(c, &c->decrypt_iv, &c->decrypt_ivlen, - c->key, c->keylen, "decryption IV")) < 0) + c->iv, c->ivlen, "decryption IV")) < 0) goto err; } @@ -132,7 +132,7 @@ static int crypto_open2(URLContext *h, const char *uri, int flags, AVDictionary if (ret < 0) goto err; if ((ret = set_aes_arg(c, &c->encrypt_iv, &c->encrypt_ivlen, - c->key, c->keylen, "encryption IV")) < 0) + c->iv, c->ivlen, "encryption IV")) < 0) goto err; } diff --git a/libavformat/dump.c b/libavformat/dump.c index 56b37ff7d8..71bb5bd057 100644 --- a/libavformat/dump.c +++ b/libavformat/dump.c @@ -371,8 +371,8 @@ static void dump_stream_format(AVFormatContext *ic, int i, av_cmp_q(st->sample_aspect_ratio, st->codec->sample_aspect_ratio)) { AVRational display_aspect_ratio; av_reduce(&display_aspect_ratio.num, &display_aspect_ratio.den, - st->codec->width * st->sample_aspect_ratio.num, - st->codec->height * st->sample_aspect_ratio.den, + st->codec->width * (int64_t)st->sample_aspect_ratio.num, + st->codec->height * (int64_t)st->sample_aspect_ratio.den, 1024 * 1024); av_log(NULL, AV_LOG_INFO, ", SAR %d:%d DAR %d:%d", st->sample_aspect_ratio.num, st->sample_aspect_ratio.den, @@ -444,7 +444,7 @@ void av_dump_format(AVFormatContext *ic, int index, av_log(NULL, AV_LOG_INFO, " Duration: "); if (ic->duration != AV_NOPTS_VALUE) { int hours, mins, secs, us; - int64_t duration = ic->duration + 5000; + int64_t duration = ic->duration + (ic->duration <= INT64_MAX - 5000 ? 5000 : 0); secs = duration / AV_TIME_BASE; us = duration % AV_TIME_BASE; mins = secs / 60; diff --git a/libavformat/dxa.c b/libavformat/dxa.c index 6ad1c9ffac..9ddfbc3212 100644 --- a/libavformat/dxa.c +++ b/libavformat/dxa.c @@ -106,7 +106,7 @@ static int dxa_read_header(AVFormatContext *s) ast = avformat_new_stream(s, NULL); if (!ast) return AVERROR(ENOMEM); - ret = ff_get_wav_header(pb, ast->codec, fsize); + ret = ff_get_wav_header(s, pb, ast->codec, fsize); if (ret < 0) return ret; if (ast->codec->sample_rate > 0) diff --git a/libavformat/ffmdec.c b/libavformat/ffmdec.c index 987f419c96..4faecacd10 100644 --- a/libavformat/ffmdec.c +++ b/libavformat/ffmdec.c @@ -26,6 +26,7 @@ #include "libavutil/opt.h" #include "libavutil/avassert.h" #include "libavutil/avstring.h" +#include "libavutil/pixdesc.h" #include "avformat.h" #include "internal.h" #include "ffm.h" @@ -82,6 +83,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) { @@ -97,35 +99,44 @@ static int ffm_read_data(AVFormatContext *s, retry_read: if (pb->buffer_size != ffm->packet_size) { int64_t tell = avio_tell(pb); - ffio_set_buf_size(pb, ffm->packet_size); + int ret = ffio_set_buf_size(pb, ffm->packet_size); + if (ret < 0) + return ret; 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); avio_read(pb, ffm->packet, ffm->packet_size - FFM_HEADER_SIZE); - ffm->packet_end = ffm->packet + (ffm->packet_size - FFM_HEADER_SIZE - fill_size); - if (ffm->packet_end < ffm->packet || frame_offset < 0) + if (ffm->packet_size < FFM_HEADER_SIZE + fill_size || frame_offset < 0) { return -1; + } + ffm->packet_end = ffm->packet + (ffm->packet_size - FFM_HEADER_SIZE - fill_size); /* if first packet or resynchronization packet, we must handle it specifically */ if (ffm->first_packet || (frame_offset & 0x8000)) { 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 */ return 0; } ffm->first_packet = 0; - if ((frame_offset & 0x7fff) < FFM_HEADER_SIZE) + if ((frame_offset & 0x7fff) < FFM_HEADER_SIZE) { + ffm->packet_end = ffm->packet_ptr; return -1; + } ffm->packet_ptr = ffm->packet + (frame_offset & 0x7fff) - FFM_HEADER_SIZE; if (!header) break; @@ -260,8 +271,9 @@ static int ffm2_read_header(AVFormatContext *s) AVStream *st; AVIOContext *pb = s->pb; AVCodecContext *codec; + const AVCodecDescriptor *codec_desc; int ret; - int f_main = 0, f_cprv, f_stvi, f_stau; + int f_main = 0, f_cprv = -1, f_stvi = -1, f_stau = -1; AVCodec *enc; char *buffer; @@ -314,7 +326,20 @@ static int ffm2_read_header(AVFormatContext *s) codec = st->codec; /* generic info */ codec->codec_id = avio_rb32(pb); + codec_desc = avcodec_descriptor_get(codec->codec_id); + if (!codec_desc) { + av_log(s, AV_LOG_ERROR, "Invalid codec id: %d\n", codec->codec_id); + codec->codec_id = AV_CODEC_ID_NONE; + goto fail; + } codec->codec_type = avio_r8(pb); + if (codec->codec_type != codec_desc->type) { + av_log(s, AV_LOG_ERROR, "Codec type mismatch: expected %d, found %d\n", + codec_desc->type, codec->codec_type); + codec->codec_id = AV_CODEC_ID_NONE; + codec->codec_type = AVMEDIA_TYPE_UNKNOWN; + goto fail; + } codec->bit_rate = avio_rb32(pb); codec->flags = avio_rb32(pb); codec->flags2 = avio_rb32(pb); @@ -331,10 +356,21 @@ static int ffm2_read_header(AVFormatContext *s) } 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); + ret = AVERROR_INVALIDDATA; + goto fail; + } codec->width = avio_rb16(pb); codec->height = avio_rb16(pb); codec->gop_size = avio_rb16(pb); codec->pix_fmt = avio_rb32(pb); + if (!av_pix_fmt_desc_get(codec->pix_fmt)) { + av_log(s, AV_LOG_ERROR, "Invalid pix fmt id: %d\n", codec->pix_fmt); + codec->pix_fmt = AV_PIX_FMT_NONE; + goto fail; + } codec->qmin = avio_r8(pb); codec->qmax = avio_r8(pb); codec->max_qdiff = avio_r8(pb); @@ -401,7 +437,7 @@ static int ffm2_read_header(AVFormatContext *s) } break; case MKBETAG('S', '2', 'V', 'I'): - if (f_stvi++) { + if (f_stvi++ || !size) { ret = AVERROR(EINVAL); goto fail; } @@ -416,7 +452,7 @@ static int ffm2_read_header(AVFormatContext *s) goto fail; break; case MKBETAG('S', '2', 'A', 'U'): - if (f_stau++) { + if (f_stau++ || !size) { ret = AVERROR(EINVAL); goto fail; } @@ -434,7 +470,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 */ @@ -456,6 +492,7 @@ static int ffm_read_header(AVFormatContext *s) AVStream *st; AVIOContext *pb = s->pb; AVCodecContext *codec; + const AVCodecDescriptor *codec_desc; int i, nb_streams; uint32_t tag; @@ -493,7 +530,20 @@ static int ffm_read_header(AVFormatContext *s) codec = st->codec; /* generic info */ codec->codec_id = avio_rb32(pb); + codec_desc = avcodec_descriptor_get(codec->codec_id); + if (!codec_desc) { + av_log(s, AV_LOG_ERROR, "Invalid codec id: %d\n", codec->codec_id); + codec->codec_id = AV_CODEC_ID_NONE; + goto fail; + } codec->codec_type = avio_r8(pb); /* codec_type */ + if (codec->codec_type != codec_desc->type) { + av_log(s, AV_LOG_ERROR, "Codec type mismatch: expected %d, found %d\n", + codec_desc->type, codec->codec_type); + codec->codec_id = AV_CODEC_ID_NONE; + codec->codec_type = AVMEDIA_TYPE_UNKNOWN; + goto fail; + } codec->bit_rate = avio_rb32(pb); codec->flags = avio_rb32(pb); codec->flags2 = avio_rb32(pb); @@ -503,10 +553,20 @@ 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); codec->pix_fmt = avio_rb32(pb); + if (!av_pix_fmt_desc_get(codec->pix_fmt)) { + av_log(s, AV_LOG_ERROR, "Invalid pix fmt id: %d\n", codec->pix_fmt); + codec->pix_fmt = AV_PIX_FMT_NONE; + goto fail; + } codec->qmin = avio_r8(pb); codec->qmax = avio_r8(pb); codec->max_qdiff = avio_r8(pb); @@ -561,7 +621,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/flacenc.c b/libavformat/flacenc.c index 0eea94288f..aeac70ba4b 100644 --- a/libavformat/flacenc.c +++ b/libavformat/flacenc.c @@ -50,12 +50,14 @@ static int flac_write_block_comment(AVIOContext *pb, AVDictionary **m, int last_block, int bitexact) { const char *vendor = bitexact ? "ffmpeg" : LIBAVFORMAT_IDENT; - unsigned int len; + int64_t len; uint8_t *p, *p0; ff_metadata_conv(m, ff_vorbiscomment_metadata_conv, NULL); len = ff_vorbiscomment_length(*m, vendor); + if (len >= ((1<<24) - 4)) + return AVERROR(EINVAL); p0 = av_malloc(len+4); if (!p0) return AVERROR(ENOMEM); diff --git a/libavformat/flvdec.c b/libavformat/flvdec.c index 17d1313d60..da277a1218 100644 --- a/libavformat/flvdec.c +++ b/libavformat/flvdec.c @@ -390,7 +390,7 @@ static int amf_parse_object(AVFormatContext *s, AVStream *astream, FLVContext *flv = s->priv_data; AVIOContext *ioc; AMFDataType amf_type; - char str_val[256]; + char str_val[1024]; double num_val; num_val = 0; @@ -459,11 +459,11 @@ static int amf_parse_object(AVFormatContext *s, AVStream *astream, } if (key) { + acodec = astream ? astream->codec : NULL; + vcodec = vstream ? vstream->codec : NULL; + // stream info doesn't live any deeper than the first object if (depth == 1) { - acodec = astream ? astream->codec : NULL; - vcodec = vstream ? vstream->codec : NULL; - if (amf_type == AMF_DATA_TYPE_NUMBER || amf_type == AMF_DATA_TYPE_BOOL) { if (!strcmp(key, "duration")) @@ -558,13 +558,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") && strcmp(buffer, "onCuePoint")) - 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. @@ -623,7 +623,7 @@ static int flv_read_close(AVFormatContext *s) static int flv_get_extradata(AVFormatContext *s, AVStream *st, int size) { - av_free(st->codec->extradata); + av_freep(&st->codec->extradata); if (ff_get_extradata(st->codec, s->pb, size) < 0) return AVERROR(ENOMEM); return 0; @@ -822,7 +822,7 @@ static int flv_read_packet(AVFormatContext *s, AVPacket *pkt) stream_type=FLV_STREAM_TYPE_DATA; if (size > 13 + 1 + 4 && dts == 0) { // Header-type metadata stuff meta_pos = avio_tell(s->pb); - if (flv_read_metabody(s, next) == 0) { + if (flv_read_metabody(s, next) <= 0) { goto skip; } avio_seek(s->pb, meta_pos, SEEK_SET); diff --git a/libavformat/flvenc.c b/libavformat/flvenc.c index 5468c4d0e9..009f97558f 100644 --- a/libavformat/flvenc.c +++ b/libavformat/flvenc.c @@ -521,7 +521,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/gxf.c b/libavformat/gxf.c index 6c624f00a8..d9b629d7de 100644 --- a/libavformat/gxf.c +++ b/libavformat/gxf.c @@ -560,7 +560,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/hdsenc.c b/libavformat/hdsenc.c index 33d7c3a3a8..a161b642c9 100644 --- a/libavformat/hdsenc.c +++ b/libavformat/hdsenc.c @@ -145,15 +145,15 @@ static void hds_free(AVFormatContext *s) if (os->ctx && os->ctx_inited) av_write_trailer(os->ctx); if (os->ctx && os->ctx->pb) - av_free(os->ctx->pb); + av_freep(&os->ctx->pb); if (os->ctx) avformat_free_context(os->ctx); - av_free(os->metadata); + av_freep(&os->metadata); for (j = 0; j < os->nb_extra_packets; j++) - av_free(os->extra_packets[j]); + av_freep(&os->extra_packets[j]); for (j = 0; j < os->nb_fragments; j++) - av_free(os->fragments[j]); - av_free(os->fragments); + av_freep(&os->fragments[j]); + av_freep(&os->fragments); } av_freep(&c->streams); } @@ -499,7 +499,7 @@ static int hds_flush(AVFormatContext *s, OutputStream *os, int final, if (remove > 0) { for (i = 0; i < remove; i++) { unlink(os->fragments[i]->file); - av_free(os->fragments[i]); + av_freep(&os->fragments[i]); } os->nb_fragments -= remove; memmove(os->fragments, os->fragments + remove, diff --git a/libavformat/hevc.c b/libavformat/hevc.c index 45b00c45bc..f403e1c522 100644 --- a/libavformat/hevc.c +++ b/libavformat/hevc.c @@ -189,7 +189,7 @@ static void skip_sub_layer_hrd_parameters(GetBitContext *gb, } } -static void skip_hrd_parameters(GetBitContext *gb, uint8_t cprms_present_flag, +static int skip_hrd_parameters(GetBitContext *gb, uint8_t cprms_present_flag, unsigned int max_sub_layers_minus1) { unsigned int i; @@ -246,8 +246,11 @@ static void skip_hrd_parameters(GetBitContext *gb, uint8_t cprms_present_flag, else low_delay_hrd_flag = get_bits1(gb); - if (!low_delay_hrd_flag) + if (!low_delay_hrd_flag) { cpb_cnt_minus1 = get_ue_golomb_long(gb); + if (cpb_cnt_minus1 > 31) + return AVERROR_INVALIDDATA; + } if (nal_hrd_parameters_present_flag) skip_sub_layer_hrd_parameters(gb, cpb_cnt_minus1, @@ -257,6 +260,8 @@ static void skip_hrd_parameters(GetBitContext *gb, uint8_t cprms_present_flag, skip_sub_layer_hrd_parameters(gb, cpb_cnt_minus1, sub_pic_hrd_params_present_flag); } + + return 0; } static void skip_timing_info(GetBitContext *gb) @@ -444,7 +449,7 @@ static int parse_rps(GetBitContext *gb, unsigned int rps_idx, * * NumDeltaPocs[RefRpsIdx]: num_delta_pocs[rps_idx - 1] */ - for (i = 0; i < num_delta_pocs[rps_idx - 1]; i++) { + for (i = 0; i <= num_delta_pocs[rps_idx - 1]; i++) { uint8_t use_delta_flag = 0; uint8_t used_by_curr_pic_flag = get_bits1(gb); if (!used_by_curr_pic_flag) @@ -457,6 +462,9 @@ static int parse_rps(GetBitContext *gb, unsigned int rps_idx, unsigned int num_negative_pics = get_ue_golomb_long(gb); unsigned int num_positive_pics = get_ue_golomb_long(gb); + if ((num_positive_pics + (uint64_t)num_negative_pics) * 2 > get_bits_left(gb)) + return AVERROR_INVALIDDATA; + num_delta_pocs[rps_idx] = num_negative_pics + num_positive_pics; for (i = 0; i < num_negative_pics; i++) { @@ -557,7 +565,10 @@ static int hvcc_parse_sps(GetBitContext *gb, } if (get_bits1(gb)) { // long_term_ref_pics_present_flag - for (i = 0; i < get_ue_golomb_long(gb); i++) { // num_long_term_ref_pics_sps + unsigned num_long_term_ref_pics_sps = get_ue_golomb_long(gb); + if (num_long_term_ref_pics_sps > 31U) + return AVERROR_INVALIDDATA; + for (i = 0; i < num_long_term_ref_pics_sps; i++) { // num_long_term_ref_pics_sps int len = FFMIN(log2_max_pic_order_cnt_lsb_minus4 + 4, 16); skip_bits (gb, len); // lt_ref_pic_poc_lsb_sps[i] skip_bits1(gb); // used_by_curr_pic_lt_sps_flag[i] @@ -608,11 +619,12 @@ static int hvcc_parse_pps(GetBitContext *gb, get_se_golomb_long(gb); // pps_cr_qp_offset /* + * pps_slice_chroma_qp_offsets_present_flag u(1) * weighted_pred_flag u(1) * weighted_bipred_flag u(1) * transquant_bypass_enabled_flag u(1) */ - skip_bits(gb, 3); + skip_bits(gb, 4); tiles_enabled_flag = get_bits1(gb); entropy_coding_sync_enabled_flag = get_bits1(gb); diff --git a/libavformat/hls.c b/libavformat/hls.c index f17b826f30..7fc761ac8c 100644 --- a/libavformat/hls.c +++ b/libavformat/hls.c @@ -900,6 +900,24 @@ static void intercept_id3(struct playlist *pls, uint8_t *buf, pls->is_id3_timestamped = (pls->id3_mpegts_timestamp != AV_NOPTS_VALUE); } + +static int check_url(const char *url) { + const char *proto_name = avio_find_protocol_name(url); + + if (!proto_name) + return AVERROR_INVALIDDATA; + + if (!av_strstart(proto_name, "http", NULL) && !av_strstart(proto_name, "file", NULL)) + return AVERROR_INVALIDDATA; + + if (!strncmp(proto_name, url, strlen(proto_name)) && url[strlen(proto_name)] == ':') + return 0; + else if (strcmp(proto_name, "file") || !strncmp(url, "file,", 5)) + return AVERROR_INVALIDDATA; + + return 0; +} + static int open_input(HLSContext *c, struct playlist *pls) { AVDictionary *opts = NULL; @@ -927,6 +945,10 @@ static int open_input(HLSContext *c, struct playlist *pls) seg->url, seg->url_offset, pls->index); if (seg->key_type == KEY_NONE) { + ret = check_url(seg->url); + if (ret < 0) + goto cleanup; + ret = ffurl_open(&pls->input, seg->url, AVIO_FLAG_READ, &pls->parent->interrupt_callback, &opts); @@ -934,6 +956,10 @@ static int open_input(HLSContext *c, struct playlist *pls) char iv[33], key[33], url[MAX_URL_SIZE]; if (strcmp(seg->key, pls->key_url)) { URLContext *uc; + ret = check_url(seg->key); + if (ret < 0) + goto cleanup; + if (ffurl_open(&uc, seg->key, AVIO_FLAG_READ, &pls->parent->interrupt_callback, &opts2) == 0) { if (ffurl_read_complete(uc, pls->key, sizeof(pls->key)) diff --git a/libavformat/httpauth.c b/libavformat/httpauth.c index dbe3eff48f..18cf36bcfe 100644 --- a/libavformat/httpauth.c +++ b/libavformat/httpauth.c @@ -220,21 +220,21 @@ static char *make_digest_auth(HTTPAuthState *state, const char *username, /* TODO: Escape the quoted strings properly. */ av_strlcatf(authstr, len, "username=\"%s\"", username); - av_strlcatf(authstr, len, ",realm=\"%s\"", state->realm); - av_strlcatf(authstr, len, ",nonce=\"%s\"", digest->nonce); - av_strlcatf(authstr, len, ",uri=\"%s\"", uri); - av_strlcatf(authstr, len, ",response=\"%s\"", response); + av_strlcatf(authstr, len, ", realm=\"%s\"", state->realm); + av_strlcatf(authstr, len, ", nonce=\"%s\"", digest->nonce); + av_strlcatf(authstr, len, ", uri=\"%s\"", uri); + av_strlcatf(authstr, len, ", response=\"%s\"", response); // we are violating the RFC and use "" because all others seem to do that too. if (digest->algorithm[0]) - av_strlcatf(authstr, len, ",algorithm=\"%s\"", digest->algorithm); + av_strlcatf(authstr, len, ", algorithm=\"%s\"", digest->algorithm); if (digest->opaque[0]) - av_strlcatf(authstr, len, ",opaque=\"%s\"", digest->opaque); + av_strlcatf(authstr, len, ", opaque=\"%s\"", digest->opaque); if (digest->qop[0]) { - av_strlcatf(authstr, len, ",qop=\"%s\"", digest->qop); - av_strlcatf(authstr, len, ",cnonce=\"%s\"", cnonce); - av_strlcatf(authstr, len, ",nc=%s", nc); + av_strlcatf(authstr, len, ", qop=\"%s\"", digest->qop); + av_strlcatf(authstr, len, ", cnonce=\"%s\"", cnonce); + av_strlcatf(authstr, len, ", nc=%s", nc); } av_strlcatf(authstr, len, "\r\n"); diff --git a/libavformat/id3v2.c b/libavformat/id3v2.c index cbf43757fe..42c72477aa 100644 --- a/libavformat/id3v2.c +++ b/libavformat/id3v2.c @@ -204,7 +204,7 @@ static int check_tag(AVIOContext *s, int offset, unsigned int len) if (len > 4 || avio_seek(s, offset, SEEK_SET) < 0 || - avio_read(s, tag, len) < len) + avio_read(s, tag, len) < (int)len) return -1; else if (!AV_RB32(tag) || is_tag(tag, len)) return 1; diff --git a/libavformat/idcin.c b/libavformat/idcin.c index d7a46a17fd..4e455bfcee 100644 --- a/libavformat/idcin.c +++ b/libavformat/idcin.c @@ -359,7 +359,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/img2dec.c b/libavformat/img2dec.c index a20868cbaf..78e2102308 100644 --- a/libavformat/img2dec.c +++ b/libavformat/img2dec.c @@ -339,7 +339,10 @@ int ff_img_read_header(AVFormatContext *s1) break; } } - ffio_rewind_with_probe_data(s1->pb, &probe_buffer, probe_buffer_size); + if (s1->flags & AVFMT_FLAG_CUSTOM_IO) { + avio_seek(s1->pb, 0, SEEK_SET); + } else + ffio_rewind_with_probe_data(s1->pb, &probe_buffer, probe_buffer_size); } if (st->codec->codec_id == AV_CODEC_ID_NONE) st->codec->codec_id = ff_guess_image2_codec(s->path); @@ -437,14 +440,17 @@ int ff_img_read_packet(AVFormatContext *s1, AVPacket *pkt) } res = av_new_packet(pkt, size[0] + size[1] + size[2]); - if (res < 0) - return res; + if (res < 0) { + goto fail; + } pkt->stream_index = 0; pkt->flags |= AV_PKT_FLAG_KEY; if (s->ts_from_file) { struct stat img_stat; - if (stat(filename, &img_stat)) - return AVERROR(EIO); + if (stat(filename, &img_stat)) { + res = AVERROR(EIO); + goto fail; + } pkt->pts = (int64_t)img_stat.st_mtime; #if HAVE_STRUCT_STAT_ST_MTIM_TV_NSEC if (s->ts_from_file == 2) @@ -478,18 +484,29 @@ int ff_img_read_packet(AVFormatContext *s1, AVPacket *pkt) if (ret[0] <= 0 || ret[1] < 0 || ret[2] < 0) { av_free_packet(pkt); if (ret[0] < 0) { - return ret[0]; + res = ret[0]; } else if (ret[1] < 0) { - return ret[1]; - } else if (ret[2] < 0) - return ret[2]; - return AVERROR_EOF; + res = ret[1]; + } else if (ret[2] < 0) { + res = ret[2]; + } else { + res = AVERROR_EOF; + } + goto fail; } else { s->img_count++; s->img_number++; s->pts++; return 0; } + +fail: + if (!s->is_pipe) { + for (i = 0; i < 3; i++) { + avio_closep(&f[i]); + } + } + return res; } static int img_read_close(struct AVFormatContext* s1) diff --git a/libavformat/ipmovie.c b/libavformat/ipmovie.c index 01e70e858f..0112009d9b 100644 --- a/libavformat/ipmovie.c +++ b/libavformat/ipmovie.c @@ -156,7 +156,7 @@ static int load_ipmovie_packet(IPMVEContext *s, AVIOContext *pb, /* send both the decode map and the video data together */ - if (av_new_packet(pkt, s->decode_map_chunk_size + s->video_chunk_size)) + if (av_new_packet(pkt, 2 + s->decode_map_chunk_size + s->video_chunk_size)) return CHUNK_NOMEM; if (s->has_palette) { @@ -178,7 +178,8 @@ static int load_ipmovie_packet(IPMVEContext *s, AVIOContext *pb, avio_seek(pb, s->decode_map_chunk_offset, SEEK_SET); s->decode_map_chunk_offset = 0; - if (avio_read(pb, pkt->data, s->decode_map_chunk_size) != + AV_WL16(pkt->data, s->decode_map_chunk_size); + if (avio_read(pb, pkt->data + 2, s->decode_map_chunk_size) != s->decode_map_chunk_size) { av_free_packet(pkt); return CHUNK_EOF; @@ -187,7 +188,7 @@ static int load_ipmovie_packet(IPMVEContext *s, AVIOContext *pb, avio_seek(pb, s->video_chunk_offset, SEEK_SET); s->video_chunk_offset = 0; - if (avio_read(pb, pkt->data + s->decode_map_chunk_size, + if (avio_read(pb, pkt->data + 2 + s->decode_map_chunk_size, s->video_chunk_size) != s->video_chunk_size) { av_free_packet(pkt); return CHUNK_EOF; diff --git a/libavformat/isom.h b/libavformat/isom.h index e3160d00f8..9aafe12125 100644 --- a/libavformat/isom.h +++ b/libavformat/isom.h @@ -189,6 +189,8 @@ typedef struct MOVContext { int has_looked_for_mfra; MOVFragmentIndex** fragment_index_data; unsigned fragment_index_count; + int atom_depth; + int enable_drefs; } MOVContext; int ff_mp4_read_descr_len(AVIOContext *pb); diff --git a/libavformat/jvdec.c b/libavformat/jvdec.c index 21eb14d265..9053c61cf2 100644 --- a/libavformat/jvdec.c +++ b/libavformat/jvdec.c @@ -54,7 +54,7 @@ typedef struct { static int read_probe(AVProbeData *pd) { - if (pd->buf[0] == 'J' && pd->buf[1] == 'V' && strlen(MAGIC) <= pd->buf_size - 4 && + if (pd->buf[0] == 'J' && pd->buf[1] == 'V' && strlen(MAGIC) + 4 <= pd->buf_size && !memcmp(pd->buf + 4, MAGIC, strlen(MAGIC))) return AVPROBE_SCORE_MAX; return 0; diff --git a/libavformat/libquvi.c b/libavformat/libquvi.c index 0a593cc9cf..9d47692f8b 100644 --- a/libavformat/libquvi.c +++ b/libavformat/libquvi.c @@ -79,6 +79,20 @@ static int libquvi_read_header(AVFormatContext *s) if ((ret = ff_copy_whitelists(qc->fmtctx, s)) < 0) goto end; + if (!qc->fmtctx->format_whitelist) { + qc->fmtctx->format_whitelist = av_strdup("avi,asf,flv,mov,mpeg,mpegts,aac,h264,hevc,mp3,ogg,matroska,mxf,mp2"); + if (!qc->fmtctx->format_whitelist) { + avformat_free_context(qc->fmtctx); + qc->fmtctx = NULL; + goto err_quvi_cleanup; + } + } + if (strncmp(media_url, "http:", 5) && strncmp(media_url, "https:", 6)) { + avformat_free_context(qc->fmtctx); + qc->fmtctx = NULL; + goto err_quvi_cleanup; + } + ret = avformat_open_input(&qc->fmtctx, media_url, NULL, NULL); if (ret < 0) goto end; diff --git a/libavformat/librtmp.c b/libavformat/librtmp.c index 67939b912e..8c7345f0c8 100644 --- a/libavformat/librtmp.c +++ b/libavformat/librtmp.c @@ -189,6 +189,8 @@ static int rtmp_open(URLContext *s, const char *uri, int flags) if (sep) p = sep + 1; + else + break; } } if (ctx->playpath) { diff --git a/libavformat/matroskadec.c b/libavformat/matroskadec.c index c81b5a04af..9107815615 100644 --- a/libavformat/matroskadec.c +++ b/libavformat/matroskadec.c @@ -1080,7 +1080,7 @@ static void ebml_free(EbmlSyntax *syntax, void *data) for (j = 0; j < list->nb_elem; j++, ptr += syntax[i].list_elem_size) ebml_free(syntax[i].def.n, ptr); - av_free(list->elem); + av_freep(&list->elem); } else ebml_free(syntax[i].def.n, data_off); default: @@ -1218,15 +1218,13 @@ static int matroska_decode_buffer(uint8_t **buf, int *buf_size, newpktdata = av_realloc(pkt_data, pkt_size); if (!newpktdata) { inflateEnd(&zstream); + result = AVERROR(ENOMEM); goto failed; } pkt_data = newpktdata; zstream.avail_out = pkt_size - zstream.total_out; zstream.next_out = pkt_data + zstream.total_out; - if (pkt_data) { - result = inflate(&zstream, Z_NO_FLUSH); - } else - result = Z_MEM_ERROR; + result = inflate(&zstream, Z_NO_FLUSH); } while (result == Z_OK && pkt_size < 10000000); pkt_size = zstream.total_out; inflateEnd(&zstream); @@ -1253,15 +1251,13 @@ static int matroska_decode_buffer(uint8_t **buf, int *buf_size, newpktdata = av_realloc(pkt_data, pkt_size); if (!newpktdata) { BZ2_bzDecompressEnd(&bzstream); + result = AVERROR(ENOMEM); goto failed; } pkt_data = newpktdata; bzstream.avail_out = pkt_size - bzstream.total_out_lo32; bzstream.next_out = pkt_data + bzstream.total_out_lo32; - if (pkt_data) { - result = BZ2_bzDecompress(&bzstream); - } else - result = BZ_MEM_ERROR; + result = BZ2_bzDecompress(&bzstream); } while (result == BZ_OK && pkt_size < 10000000); pkt_size = bzstream.total_out_lo32; BZ2_bzDecompressEnd(&bzstream); @@ -1414,13 +1410,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; @@ -1443,7 +1443,7 @@ static void matroska_add_index_entries(MatroskaDemuxContext *matroska) { EbmlList *index_list; MatroskaIndex *index; - int index_scale = 1; + uint64_t index_scale = 1; int i, j; index_list = &matroska->index; @@ -1604,6 +1604,14 @@ static int matroska_parse_tracks(AVFormatContext *s) if (!track->codec_id) continue; + if (track->audio.samplerate < 0 || track->audio.samplerate > INT_MAX || + isnan(track->audio.samplerate)) { + av_log(matroska->ctx, AV_LOG_WARNING, + "Invalid sample rate %f, defaulting to 8000 instead.\n", + track->audio.samplerate); + track->audio.samplerate = 8000; + } + if (track->type == MATROSKA_TRACK_TYPE_VIDEO) { if (!track->default_duration && track->video.frame_rate > 0) track->default_duration = 1000000000 / track->video.frame_rate; @@ -1708,7 +1716,7 @@ static int matroska_parse_tracks(AVFormatContext *s) ffio_init_context(&b, track->codec_priv.data, track->codec_priv.size, 0, NULL, NULL, NULL, NULL); - ret = ff_get_wav_header(&b, st->codec, track->codec_priv.size); + ret = ff_get_wav_header(s, &b, st->codec, track->codec_priv.size); if (ret < 0) return ret; codec_id = st->codec->codec_id; @@ -1799,6 +1807,18 @@ static int matroska_parse_tracks(AVFormatContext *s) NULL, NULL, NULL, NULL); avio_write(&b, "TTA1", 4); avio_wl16(&b, 1); + if (track->audio.channels > UINT16_MAX || + track->audio.bitdepth > UINT16_MAX) { + av_log(matroska->ctx, AV_LOG_WARNING, + "Too large audio channel number %"PRIu64 + " or bitdepth %"PRIu64". Skipping track.\n", + track->audio.channels, track->audio.bitdepth); + av_freep(&extradata); + if (matroska->ctx->error_recognition & AV_EF_EXPLODE) + return AVERROR_INVALIDDATA; + else + continue; + } avio_wl16(&b, track->audio.channels); avio_wl16(&b, track->audio.bitdepth); if (track->audio.out_samplerate < 0 || track->audio.out_samplerate > INT_MAX) @@ -1922,8 +1942,8 @@ static int matroska_parse_tracks(AVFormatContext *s) av_reduce(&st->avg_frame_rate.num, &st->avg_frame_rate.den, 1000000000, track->default_duration, 30000); #if FF_API_R_FRAME_RATE - if ( st->avg_frame_rate.num < st->avg_frame_rate.den * 1000L - && st->avg_frame_rate.num > st->avg_frame_rate.den * 5L) + if ( st->avg_frame_rate.num < st->avg_frame_rate.den * 1000LL + && st->avg_frame_rate.num > st->avg_frame_rate.den * 5LL) st->r_frame_rate = st->avg_frame_rate; #endif } @@ -1944,8 +1964,8 @@ static int matroska_parse_tracks(AVFormatContext *s) snprintf(buf, sizeof(buf), "%s_%d", ff_matroska_video_stereo_plane[planes[j].type], i); for (k=0; k < matroska->tracks.nb_elem; k++) - if (planes[j].uid == tracks[k].uid) { - av_dict_set(&s->streams[k]->metadata, + if (planes[j].uid == tracks[k].uid && tracks[k].stream) { + av_dict_set(&tracks[k].stream->metadata, "stereo_mode", buf, 0); break; } @@ -2130,7 +2150,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], @@ -2161,7 +2181,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; @@ -2951,6 +2971,7 @@ static int matroska_read_seek(AVFormatContext *s, int stream_index, tracks[i].audio.buf_timecode = AV_NOPTS_VALUE; tracks[i].end_timecode = 0; if (tracks[i].type == MATROSKA_TRACK_TYPE_SUBTITLE && + tracks[i].stream && tracks[i].stream->discard != AVDISCARD_ALL) { index_sub = av_index_search_timestamp( tracks[i].stream, st->index_entries[index].timestamp, @@ -2999,7 +3020,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 e8e8da043f..ee90c31a3c 100644 --- a/libavformat/matroskaenc.c +++ b/libavformat/matroskaenc.c @@ -543,12 +543,15 @@ static int put_flac_codecpriv(AVFormatContext *s, "Lavf" : LIBAVFORMAT_IDENT; AVDictionary *dict = NULL; uint8_t buf[32], *data, *p; - int len; + int64_t len; snprintf(buf, sizeof(buf), "0x%"PRIx64, codec->channel_layout); av_dict_set(&dict, "WAVEFORMATEXTENSIBLE_CHANNEL_MASK", buf, 0); len = ff_vorbiscomment_length(dict, vendor); + if (len >= ((1<<24) - 4)) + return AVERROR(EINVAL); + data = av_malloc(len + 4); if (!data) { av_dict_free(&dict); @@ -878,14 +881,18 @@ static int mkv_write_track(AVFormatContext *s, MatroskaMuxContext *mkv, } if (codec->codec_type == AVMEDIA_TYPE_AUDIO && codec->initial_padding && codec->codec_id == AV_CODEC_ID_OPUS) { + int64_t codecdelay = av_rescale_q(codec->initial_padding, + (AVRational){ 1, codec->sample_rate }, + (AVRational){ 1, 1000000000 }); + if (codecdelay < 0) { + av_log(s, AV_LOG_ERROR, "Initial padding is invalid\n"); + return AVERROR(EINVAL); + } // mkv->tracks[i].ts_offset = av_rescale_q(codec->initial_padding, // (AVRational){ 1, codec->sample_rate }, // st->time_base); - put_ebml_uint(pb, MATROSKA_ID_CODECDELAY, - av_rescale_q(codec->initial_padding, - (AVRational){ 1, codec->sample_rate }, - (AVRational){ 1, 1000000000 })); + put_ebml_uint(pb, MATROSKA_ID_CODECDELAY, codecdelay); } if (codec->codec_id == AV_CODEC_ID_OPUS) { put_ebml_uint(pb, MATROSKA_ID_SEEKPREROLL, OPUS_SEEK_PREROLL); diff --git a/libavformat/mlvdec.c b/libavformat/mlvdec.c index 17bdb17e72..e6400dad10 100644 --- a/libavformat/mlvdec.c +++ b/libavformat/mlvdec.c @@ -142,7 +142,7 @@ static int scan_file(AVFormatContext *avctx, AVStream *vst, AVStream *ast, int f vst->codec->codec_tag = MKTAG('B', 'I', 'T', 16); size -= 164; } else if (ast && type == MKTAG('W', 'A', 'V', 'I') && size >= 16) { - ret = ff_get_wav_header(pb, ast->codec, 16); + ret = ff_get_wav_header(avctx, pb, ast->codec, 16); if (ret < 0) return ret; size -= 16; @@ -363,6 +363,11 @@ static int read_header(AVFormatContext *avctx) if (ast) ast->duration = ast->nb_index_entries; + if ((vst && !vst->nb_index_entries) || (ast && !ast->nb_index_entries)) { + av_log(avctx, AV_LOG_ERROR, "no index entries found\n"); + return AVERROR_INVALIDDATA; + } + if (vst && ast) avio_seek(pb, FFMIN(vst->index_entries[0].pos, ast->index_entries[0].pos), SEEK_SET); else if (vst) diff --git a/libavformat/mov.c b/libavformat/mov.c index 8d66c0afdd..cebd0b8b4c 100644 --- a/libavformat/mov.c +++ b/libavformat/mov.c @@ -210,7 +210,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); @@ -226,8 +230,10 @@ static int mov_metadata_loci(MOVContext *c, AVIOContext *pb, unsigned len) double longitude, latitude; const char *key = "location"; - if (len < 4 + 2 + 1 + 1 + 4 + 4 + 4) + if (len < 4 + 2 + 1 + 1 + 4 + 4 + 4) { + av_log(c->fc, AV_LOG_ERROR, "loci too short\n"); return AVERROR_INVALIDDATA; + } avio_skip(pb, 4); // version+flags langcode = avio_rb16(pb); @@ -235,13 +241,17 @@ static int mov_metadata_loci(MOVContext *c, AVIOContext *pb, unsigned len) len -= 6; len -= avio_get_str(pb, len, buf, sizeof(buf)); // place name - if (len < 1) + if (len < 1) { + av_log(c->fc, AV_LOG_ERROR, "place name too long\n"); return AVERROR_INVALIDDATA; + } avio_skip(pb, 1); // role len -= 1; - if (len < 14) + if (len < 12) { + av_log(c->fc, AV_LOG_ERROR, "no space for coordinates left (%d)\n", len); return AVERROR_INVALIDDATA; + } longitude = ((int32_t) avio_rb32(pb)) / (float) (1 << 16); latitude = ((int32_t) avio_rb32(pb)) / (float) (1 << 16); @@ -352,7 +362,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_alloc = str_size << 1; // worst-case requirement for output string in case of utf8 coded input @@ -690,7 +700,7 @@ static int mov_read_wfex(MOVContext *c, AVIOContext *pb, MOVAtom atom) return 0; st = c->fc->streams[c->fc->nb_streams-1]; - if ((ret = ff_get_wav_header(pb, st->codec, atom.size)) < 0) + if ((ret = ff_get_wav_header(c->fc, pb, st->codec, atom.size)) < 0) av_log(c->fc, AV_LOG_WARNING, "get_wav_header failed\n"); return ret; @@ -1150,7 +1160,7 @@ static int mov_read_wave(MOVContext *c, AVIOContext *pb, MOVAtom atom) st->codec->codec_id == AV_CODEC_ID_QDMC || st->codec->codec_id == AV_CODEC_ID_SPEEX) { // pass all frma atom to codec, needed at least for QDMC and QDM2 - av_free(st->codec->extradata); + av_freep(&st->codec->extradata); if (ff_get_extradata(st->codec, pb, atom.size) < 0) return AVERROR(ENOMEM); } else if (atom.size > 8) { /* to read frma, esds atoms */ @@ -1190,7 +1200,7 @@ static int mov_read_glbl(MOVContext *c, AVIOContext *pb, MOVAtom atom) av_log(c, AV_LOG_WARNING, "ignoring multiple glbl\n"); return 0; } - av_free(st->codec->extradata); + av_freep(&st->codec->extradata); if (ff_get_extradata(st->codec, pb, atom.size) < 0) return AVERROR(ENOMEM); @@ -1215,7 +1225,7 @@ static int mov_read_dvc1(MOVContext *c, AVIOContext *pb, MOVAtom atom) return 0; avio_seek(pb, 6, SEEK_CUR); - av_free(st->codec->extradata); + av_freep(&st->codec->extradata); if ((ret = ff_get_extradata(st->codec, pb, atom.size - 7)) < 0) return ret; @@ -1241,7 +1251,7 @@ static int mov_read_strf(MOVContext *c, AVIOContext *pb, MOVAtom atom) return AVERROR_INVALIDDATA; avio_skip(pb, 40); - av_free(st->codec->extradata); + av_freep(&st->codec->extradata); if (ff_get_extradata(st->codec, pb, atom.size - 40) < 0) return AVERROR(ENOMEM); return 0; @@ -1550,7 +1560,7 @@ static void mov_parse_stsd_audio(MOVContext *c, AVIOContext *pb, static void mov_parse_stsd_subtitle(MOVContext *c, AVIOContext *pb, AVStream *st, MOVStreamContext *sc, - int size) + int64_t size) { // ttxt stsd contains display flags, justification, background // color, fonts, and default styles, so fake an atom to read it @@ -1615,10 +1625,10 @@ static int mov_rewrite_dvd_sub_extradata(AVStream *st) static int mov_parse_stsd_data(MOVContext *c, AVIOContext *pb, AVStream *st, MOVStreamContext *sc, - int size) + int64_t size) { if (st->codec->codec_tag == MKTAG('t','m','c','d')) { - if (ff_get_extradata(st->codec, pb, size) < 0) + if ((int)size != size || ff_get_extradata(st->codec, pb, size) < 0) return AVERROR(ENOMEM); if (size > 16) { MOVStreamContext *tmcd_ctx = st->priv_data; @@ -2167,7 +2177,7 @@ static int mov_read_ctts(MOVContext *c, AVIOContext *pb, MOVAtom atom) av_dlog(c->fc, "count=%d, duration=%d\n", count, duration); - if (FFABS(duration) > (1<<28) && i+2fc, AV_LOG_WARNING, "CTTS invalid\n"); av_freep(&sc->ctts_data); sc->ctts_count = 0; @@ -2456,7 +2466,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; @@ -2482,10 +2492,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; } @@ -2544,13 +2559,23 @@ static int mov_read_trak(MOVContext *c, AVIOContext *pb, MOVAtom atom) if (sc->dref_id-1 < sc->drefs_count && sc->drefs[sc->dref_id-1].path) { MOVDref *dref = &sc->drefs[sc->dref_id - 1]; - if (mov_open_dref(&sc->pb, c->fc->filename, dref, &c->fc->interrupt_callback, - c->use_absolute_path, c->fc) < 0) - av_log(c->fc, AV_LOG_ERROR, - "stream %d, error opening alias: path='%s', dir='%s', " - "filename='%s', volume='%s', nlvl_from=%d, nlvl_to=%d\n", + if (c->enable_drefs) { + if (mov_open_dref(&sc->pb, c->fc->filename, dref, &c->fc->interrupt_callback, + c->use_absolute_path, c->fc) < 0) + av_log(c->fc, AV_LOG_ERROR, + "stream %d, error opening alias: path='%s', dir='%s', " + "filename='%s', volume='%s', nlvl_from=%d, nlvl_to=%d\n", + st->index, dref->path, dref->dir, dref->filename, + dref->volume, dref->nlvl_from, dref->nlvl_to); + } else { + av_log(c->fc, AV_LOG_WARNING, + "Skipped opening external track: " + "stream %d, alias: path='%s', dir='%s', " + "filename='%s', volume='%s', nlvl_from=%d, nlvl_to=%d." + "Set enable_drefs to allow this.\n", st->index, dref->path, dref->dir, dref->filename, dref->volume, dref->nlvl_from, dref->nlvl_to); + } } else { sc->pb = c->fc->pb; sc->pb_is_copied = 1; @@ -3053,7 +3078,7 @@ static int mov_read_trun(MOVContext *c, AVIOContext *pb, MOVAtom atom) } av_log(c->fc, AV_LOG_DEBUG, "calculated into dts %"PRId64"\n", dts); } else { - dts = frag->time; + dts = frag->time - sc->time_offset; av_log(c->fc, AV_LOG_DEBUG, "found frag time %"PRId64 ", using it for dts\n", dts); } @@ -3147,6 +3172,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); @@ -3388,6 +3414,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 && !avio_feof(pb)) { @@ -3417,11 +3449,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; } @@ -3453,13 +3486,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; @@ -3479,6 +3515,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; } @@ -3690,6 +3727,9 @@ static int mov_read_close(AVFormatContext *s) AVStream *st = s->streams[i]; MOVStreamContext *sc = st->priv_data; + if (!sc) + continue; + av_freep(&sc->ctts_data); for (j = 0; j < sc->drefs_count; j++) { av_freep(&sc->drefs[j].path); @@ -3768,35 +3808,39 @@ static void export_orphan_timecode(AVFormatContext *s) static int read_tfra(MOVContext *mov, AVIOContext *f) { MOVFragmentIndex* index = NULL; - int version, fieldlength, i, j, err; + int version, fieldlength, i, j; int64_t pos = avio_tell(f); uint32_t size = avio_rb32(f); + void *tmp; + if (avio_rb32(f) != MKBETAG('t', 'f', 'r', 'a')) { - return -1; + return 1; } av_log(mov->fc, AV_LOG_VERBOSE, "found tfra\n"); index = av_mallocz(sizeof(MOVFragmentIndex)); if (!index) { return AVERROR(ENOMEM); } - mov->fragment_index_count++; - if ((err = av_reallocp(&mov->fragment_index_data, - mov->fragment_index_count * - sizeof(MOVFragmentIndex*))) < 0) { + + tmp = av_realloc_array(mov->fragment_index_data, + mov->fragment_index_count + 1, + sizeof(MOVFragmentIndex*)); + if (!tmp) { av_freep(&index); - return err; + return AVERROR(ENOMEM); } - mov->fragment_index_data[mov->fragment_index_count - 1] = - index; + mov->fragment_index_data = tmp; + mov->fragment_index_data[mov->fragment_index_count++] = index; version = avio_r8(f); avio_rb24(f); index->track_id = avio_rb32(f); fieldlength = avio_rb32(f); index->item_count = avio_rb32(f); - index->items = av_mallocz( - index->item_count * sizeof(MOVFragmentIndexItem)); + index->items = av_mallocz_array( + index->item_count, sizeof(MOVFragmentIndexItem)); if (!index->items) { + index->item_count = 0; return AVERROR(ENOMEM); } for (i = 0; i < index->item_count; i++) { @@ -3850,11 +3894,13 @@ static int mov_read_mfra(MOVContext *c, AVIOContext *f) av_log(c->fc, AV_LOG_DEBUG, "doesn't look like mfra (tag mismatch)\n"); goto fail; } - ret = 0; av_log(c->fc, AV_LOG_VERBOSE, "stream has mfra\n"); - while (!read_tfra(c, f)) { - /* Empty */ - } + do { + ret = read_tfra(c, f); + if (ret < 0) + goto fail; + } while (!ret); + ret = 0; fail: seek_ret = avio_seek(f, original_pos, SEEK_SET); if (seek_ret < 0) { @@ -4093,7 +4139,7 @@ static int mov_read_packet(AVFormatContext *s, AVPacket *pkt) #if CONFIG_DV_DEMUXER if (mov->dv_demux && sc->dv_audio_container) { avpriv_dv_produce_packet(mov->dv_demux, pkt, pkt->data, pkt->size, pkt->pos); - av_free(pkt->data); + av_freep(&pkt->data); pkt->size = 0; ret = avpriv_dv_get_packet(mov->dv_demux, pkt); if (ret < 0) @@ -4214,6 +4260,8 @@ static const AVOption mov_options[] = { AV_OPT_FLAG_VIDEO_PARAM|AV_OPT_FLAG_DECODING_PARAM, "use_mfra_for" }, { "export_all", "Export unrecognized metadata entries", OFFSET(export_all), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 1, .flags = FLAGS }, + { "enable_drefs", "Enable external track support.", OFFSET(enable_drefs), AV_OPT_TYPE_INT, + {.i64 = 0}, 0, 1, FLAGS }, { NULL }, }; diff --git a/libavformat/mov_chan.c b/libavformat/mov_chan.c index 3b91ed7054..b63310b270 100644 --- a/libavformat/mov_chan.c +++ b/libavformat/mov_chan.c @@ -566,6 +566,11 @@ int ff_mov_read_chan(AVFormatContext *s, AVIOContext *pb, AVStream *st, label_mask = 0; for (i = 0; i < num_descr; i++) { uint32_t label; + if (pb->eof_reached) { + av_log(s, AV_LOG_ERROR, + "reached EOF while reading channel layout\n"); + return AVERROR_INVALIDDATA; + } label = avio_rb32(pb); // mChannelLabel avio_rb32(pb); // mChannelFlags avio_rl32(pb); // mCoordinates[0] diff --git a/libavformat/movenc.c b/libavformat/movenc.c index 10e883c923..ef250412b9 100644 --- a/libavformat/movenc.c +++ b/libavformat/movenc.c @@ -2499,7 +2499,8 @@ static int mov_write_mvhd_tag(AVIOContext *pb, MOVMuxContext *mov) } version = max_track_len < UINT32_MAX ? 0 : 1; - (version == 1) ? avio_wb32(pb, 120) : avio_wb32(pb, 108); /* size */ + avio_wb32(pb, version == 1 ? 120 : 108); /* size */ + ffio_wfourcc(pb, "mvhd"); avio_w8(pb, version); avio_wb24(pb, 0); /* flags */ diff --git a/libavformat/mp3dec.c b/libavformat/mp3dec.c index c4c1bb7ca5..d981874582 100644 --- a/libavformat/mp3dec.c +++ b/libavformat/mp3dec.c @@ -61,7 +61,10 @@ static int mp3_read_probe(AVProbeData *p) int fsize, frames, sample_rate; uint32_t header; const uint8_t *buf, *buf0, *buf2, *end; - AVCodecContext avctx; + AVCodecContext *avctx = avcodec_alloc_context3(NULL); + + if (!avctx) + return 0; buf0 = p->buf; end = p->buf + p->buf_size - sizeof(uint32_t); @@ -78,7 +81,7 @@ static int mp3_read_probe(AVProbeData *p) for(frames = 0; buf2 < end; frames++) { header = AV_RB32(buf2); - fsize = avpriv_mpa_decode_header(&avctx, header, &sample_rate, &sample_rate, &sample_rate, &sample_rate); + fsize = avpriv_mpa_decode_header(avctx, header, &sample_rate, &sample_rate, &sample_rate, &sample_rate); if(fsize < 0) break; buf2 += fsize; @@ -87,6 +90,7 @@ static int mp3_read_probe(AVProbeData *p) if(buf == buf0) first_frames= frames; } + avcodec_free_context(&avctx); // keep this in sync with ac3 probe, both need to avoid // issues with MPEG-files! if (first_frames>=4) return AVPROBE_SCORE_EXTENSION + 1; diff --git a/libavformat/mpc8.c b/libavformat/mpc8.c index a15dc25a69..684a0eeae0 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; @@ -223,6 +223,10 @@ static int mpc8_read_header(AVFormatContext *s) while(!avio_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/mpeg.c b/libavformat/mpeg.c index 827a3c2c5f..8e1848c9ca 100644 --- a/libavformat/mpeg.c +++ b/libavformat/mpeg.c @@ -70,20 +70,23 @@ static int mpegps_probe(AVProbeData *p) int i; int sys = 0, pspack = 0, priv1 = 0, vid = 0; int audio = 0, invalid = 0, score = 0; + int endpes = 0; for (i = 0; i < p->buf_size; i++) { code = (code << 8) + p->buf[i]; if ((code & 0xffffff00) == 0x100) { int len = p->buf[i + 1] << 8 | p->buf[i + 2]; - int pes = check_pes(p->buf + i, p->buf + p->buf_size); + int pes = endpes <= i && check_pes(p->buf + i, p->buf + p->buf_size); int pack = check_pack_header(p->buf + i); if (code == SYSTEM_HEADER_START_CODE) sys++; else if (code == PACK_START_CODE && pack) pspack++; - else if ((code & 0xf0) == VIDEO_ID && pes) + else if ((code & 0xf0) == VIDEO_ID && pes) { + endpes = i + len; vid++; + } // skip pes payload to avoid start code emulation for private // and audio streams else if ((code & 0xe0) == AUDIO_ID && pes) {audio++; i+=len;} diff --git a/libavformat/mpegtsenc.c b/libavformat/mpegtsenc.c index a32c6d6787..fd23430659 100644 --- a/libavformat/mpegtsenc.c +++ b/libavformat/mpegtsenc.c @@ -739,11 +739,11 @@ static int mpegts_write_header(AVFormatContext *s) ts_st = pcr_st->priv_data; if (ts->mux_rate > 1) { - service->pcr_packet_period = (ts->mux_rate * ts->pcr_period) / + service->pcr_packet_period = (int64_t)ts->mux_rate * ts->pcr_period / (TS_PACKET_SIZE * 8 * 1000); - ts->sdt_packet_period = (ts->mux_rate * SDT_RETRANS_TIME) / + ts->sdt_packet_period = (int64_t)ts->mux_rate * SDT_RETRANS_TIME / (TS_PACKET_SIZE * 8 * 1000); - ts->pat_packet_period = (ts->mux_rate * PAT_RETRANS_TIME) / + ts->pat_packet_period = (int64_t)ts->mux_rate * PAT_RETRANS_TIME / (TS_PACKET_SIZE * 8 * 1000); if (ts->copyts < 1) diff --git a/libavformat/mux.c b/libavformat/mux.c index 023832c336..a0165738f6 100644 --- a/libavformat/mux.c +++ b/libavformat/mux.c @@ -998,6 +998,8 @@ int ff_write_chained(AVFormatContext *dst, int dst_stream, AVPacket *pkt, if (interleave) ret = av_interleaved_write_frame(dst, &local_pkt); else ret = av_write_frame(dst, &local_pkt); pkt->buf = local_pkt.buf; + pkt->side_data = local_pkt.side_data; + pkt->side_data_elems = local_pkt.side_data_elems; pkt->destruct = local_pkt.destruct; return ret; } diff --git a/libavformat/mvdec.c b/libavformat/mvdec.c index c8a5ebf119..7aa6452f66 100644 --- a/libavformat/mvdec.c +++ b/libavformat/mvdec.c @@ -408,7 +408,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 0c88a8ae9c..34ec5527cf 100644 --- a/libavformat/mxfdec.c +++ b/libavformat/mxfdec.c @@ -1596,6 +1596,16 @@ static int mxf_parse_physical_source_package(MXFContext *mxf, MXFTrack *source_t continue; } + if (physical_track->edit_rate.num <= 0 || + physical_track->edit_rate.den <= 0) { + av_log(mxf->fc, AV_LOG_WARNING, + "Invalid edit rate (%d/%d) found on structural" + " component #%d, defaulting to 25/1\n", + physical_track->edit_rate.num, + physical_track->edit_rate.den, i); + physical_track->edit_rate = (AVRational){25, 1}; + } + for (k = 0; k < physical_track->sequence->structural_components_count; k++) { if (!(mxf_tc = mxf_resolve_timecode_component(mxf, &physical_track->sequence->structural_components_refs[k]))) continue; @@ -1976,7 +1986,7 @@ static int mxf_timestamp_to_str(uint64_t timestamp, char **str) if (!*str) return AVERROR(ENOMEM); if (!strftime(*str, 32, "%Y-%m-%d %H:%M:%S", &time)) - str[0] = '\0'; + (*str)[0] = '\0'; return 0; } diff --git a/libavformat/mxfenc.c b/libavformat/mxfenc.c index a850239375..7607f959e6 100644 --- a/libavformat/mxfenc.c +++ b/libavformat/mxfenc.c @@ -1840,9 +1840,10 @@ static int mxf_write_header(AVFormatContext *s) return ret; sc->video_bit_rate = st->codec->bit_rate ? st->codec->bit_rate : st->codec->rc_max_rate; if (s->oformat == &ff_mxf_d10_muxer) { - if (sc->video_bit_rate == 50000000) { - if (mxf->time_base.den == 25) sc->index = 3; - else sc->index = 5; + if ((sc->video_bit_rate == 50000000) && (mxf->time_base.den == 25)) { + sc->index = 3; + } else if ((sc->video_bit_rate == 49999840 || sc->video_bit_rate == 50000000) && (mxf->time_base.den != 25)) { + sc->index = 5; } else if (sc->video_bit_rate == 40000000) { if (mxf->time_base.den == 25) sc->index = 7; else sc->index = 9; @@ -2121,6 +2122,10 @@ static int mxf_write_packet(AVFormatContext *s, AVPacket *pkt) } mxf->edit_units_count++; } else if (!mxf->edit_unit_byte_count && st->index == 1) { + if (!mxf->edit_units_count) { + av_log(s, AV_LOG_ERROR, "No packets in first stream\n"); + return AVERROR_PATCHWELCOME; + } mxf->index_entries[mxf->edit_units_count-1].slice_offset = mxf->body_offset - mxf->index_entries[mxf->edit_units_count-1].offset; } diff --git a/libavformat/nut.c b/libavformat/nut.c index 86a03015af..6cd34458ac 100644 --- a/libavformat/nut.c +++ b/libavformat/nut.c @@ -182,6 +182,7 @@ const AVCodecTag ff_nut_audio_extra_tags[] = { { AV_CODEC_ID_PCM_ALAW, MKTAG('A', 'L', 'A', 'W') }, { AV_CODEC_ID_PCM_MULAW, MKTAG('U', 'L', 'A', 'W') }, { AV_CODEC_ID_MP3, MKTAG('M', 'P', '3', ' ') }, + { AV_CODEC_ID_WAVPACK, MKTAG('w', 'v', 'p', 'k') }, { AV_CODEC_ID_NONE, 0 } }; diff --git a/libavformat/nut.h b/libavformat/nut.h index 943081caf6..0c678a51b9 100644 --- a/libavformat/nut.h +++ b/libavformat/nut.h @@ -102,6 +102,7 @@ typedef struct NUTContext { unsigned int max_distance; unsigned int time_base_count; int64_t last_syncpoint_pos; + int64_t last_resync_pos; int header_count; AVRational *time_base; struct AVTreeNode *syncpoints; diff --git a/libavformat/nutdec.c b/libavformat/nutdec.c index ef29bdf79c..6ace90abcb 100644 --- a/libavformat/nutdec.c +++ b/libavformat/nutdec.c @@ -47,11 +47,15 @@ static int get_str(AVIOContext *bc, char *string, unsigned int maxlen) while (len > maxlen) { avio_r8(bc); len--; + if (bc->eof_reached) + len = maxlen; } if (maxlen) string[FFMIN(len, maxlen - 1)] = 0; + if (bc->eof_reached) + return AVERROR_EOF; if (maxlen == len) return -1; else @@ -211,8 +215,11 @@ static int skip_reserved(AVIOContext *bc, int64_t pos) avio_seek(bc, pos, SEEK_CUR); return AVERROR_INVALIDDATA; } else { - while (pos--) + while (pos--) { + if (bc->eof_reached) + return AVERROR_INVALIDDATA; avio_r8(bc); + } return 0; } } @@ -291,10 +298,15 @@ static int decode_main_header(NUTContext *nut) if (tmp_fields > 7) tmp_head_idx = ffio_read_varlen(bc); - while (tmp_fields-- > 8) + while (tmp_fields-- > 8) { + if (bc->eof_reached) { + av_log(s, AV_LOG_ERROR, "reached EOF while decoding main header\n"); + return AVERROR_INVALIDDATA; + } 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; } @@ -480,7 +492,7 @@ static int decode_info_header(NUTContext *nut) AVIOContext *bc = s->pb; uint64_t tmp, chapter_start, chapter_len; unsigned int stream_id_plus1, count; - int chapter_id, i; + int chapter_id, i, ret; int64_t value, end; char name[256], str_value[1024], type_str[256]; const char *type; @@ -505,6 +517,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]; @@ -518,8 +534,14 @@ static int decode_info_header(NUTContext *nut) } for (i = 0; i < count; i++) { - get_str(bc, name, sizeof(name)); + ret = get_str(bc, name, sizeof(name)); + if (ret < 0) { + av_log(s, AV_LOG_ERROR, "get_str failed while decoding info header\n"); + return ret; + } value = get_s(bc); + str_value[0] = 0; + if (value == -1) { type = "UTF-8"; get_str(bc, str_value, sizeof(str_value)); @@ -553,7 +575,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; } @@ -697,6 +720,10 @@ static int find_and_decode_index(NUTContext *nut) has_keyframe[n++] = flag; has_keyframe[n++] = !flag; } else { + if (x <= 1) { + av_log(s, AV_LOG_ERROR, "index: x %"PRIu64" is invalid\n", x); + goto fail; + } while (x != 1) { if (n >= syncpoint_count + 1) { av_log(s, AV_LOG_ERROR, "index overflow B\n"); @@ -740,12 +767,14 @@ fail: return ret; } +static int nut_read_close(AVFormatContext *s); + static int nut_read_header(AVFormatContext *s) { NUTContext *nut = s->priv_data; AVIOContext *bc = s->pb; int64_t pos; - int initialized_stream_count; + int initialized_stream_count, ret = 0; nut->avf = s; @@ -755,7 +784,8 @@ static int nut_read_header(AVFormatContext *s) pos = find_startcode(bc, MAIN_STARTCODE, pos) + 1; if (pos < 0 + 1) { av_log(s, AV_LOG_ERROR, "No main startcode found.\n"); - return AVERROR_INVALIDDATA; + ret = AVERROR_INVALIDDATA; + goto end; } } while (decode_main_header(nut) < 0); @@ -765,7 +795,8 @@ static int nut_read_header(AVFormatContext *s) pos = find_startcode(bc, STREAM_STARTCODE, pos) + 1; if (pos < 0 + 1) { av_log(s, AV_LOG_ERROR, "Not all stream headers found.\n"); - return AVERROR_INVALIDDATA; + ret = AVERROR_INVALIDDATA; + goto end; } if (decode_stream_header(nut) >= 0) initialized_stream_count++; @@ -779,7 +810,8 @@ static int nut_read_header(AVFormatContext *s) if (startcode == 0) { av_log(s, AV_LOG_ERROR, "EOF before video frames\n"); - return AVERROR_INVALIDDATA; + ret = AVERROR_INVALIDDATA; + goto end; } else if (startcode == SYNCPOINT_STARTCODE) { nut->next_startcode = startcode; break; @@ -801,7 +833,10 @@ static int nut_read_header(AVFormatContext *s) ff_metadata_conv_ctx(s, NULL, ff_nut_metadata_conv); - return 0; +end: + if (ret < 0) + nut_read_close(s); + return FFMIN(ret, 0); } static int read_sm_data(AVFormatContext *s, AVIOContext *bc, AVPacket *pkt, int is_meta, int64_t maxpos) @@ -814,14 +849,18 @@ static int read_sm_data(AVFormatContext *s, AVIOContext *bc, AVPacket *pkt, int int sample_rate = 0; int width = 0; int height = 0; - int i; + int i, ret; for (i=0; i= maxpos) return AVERROR_INVALIDDATA; - get_str(bc, name, sizeof(name)); + ret = get_str(bc, name, sizeof(name)); + if (ret < 0) { + av_log(s, AV_LOG_ERROR, "get_str failed while reading sm data\n"); + return ret; + } value = get_s(bc); if (value == -1) { @@ -833,7 +872,7 @@ static int read_sm_data(AVFormatContext *s, AVIOContext *bc, AVPacket *pkt, int get_str(bc, type_str, sizeof(type_str)); value_len = ffio_read_varlen(bc); - if (avio_tell(bc) + value_len >= maxpos) + if (value_len < 0 || value_len >= maxpos - avio_tell(bc)) return AVERROR_INVALIDDATA; if (!strcmp(name, "Palette")) { dst = av_packet_new_side_data(pkt, AV_PKT_DATA_PALETTE, value_len); @@ -911,6 +950,9 @@ static int read_sm_data(AVFormatContext *s, AVIOContext *bc, AVPacket *pkt, int AV_WL32(dst+4, skip_end); } + if (avio_tell(bc) >= maxpos) + return AVERROR_INVALIDDATA; + return 0; } @@ -964,8 +1006,13 @@ static int decode_frame_header(NUTContext *nut, int64_t *pts, int *stream_id, *header_idx = ffio_read_varlen(bc); if (flags & FLAG_RESERVED) reserved_count = ffio_read_varlen(bc); - for (i = 0; i < reserved_count; i++) + for (i = 0; i < reserved_count; i++) { + if (bc->eof_reached) { + av_log(s, AV_LOG_ERROR, "reached EOF while decoding frame header\n"); + return AVERROR_INVALIDDATA; + } ffio_read_varlen(bc); + } if (*header_idx >= (unsigned)nut->header_count) { av_log(s, AV_LOG_ERROR, "header_idx invalid\n"); @@ -1022,7 +1069,8 @@ static int decode_frame(NUTContext *nut, AVPacket *pkt, int frame_code) ret = av_new_packet(pkt, size + nut->header_len[header_idx]); if (ret < 0) return ret; - memcpy(pkt->data, nut->header[header_idx], nut->header_len[header_idx]); + if (nut->header[header_idx]) + memcpy(pkt->data, nut->header[header_idx], nut->header_len[header_idx]); pkt->pos = avio_tell(bc); // FIXME if (stc->last_flags & FLAG_SM_DATA) { int sm_size; @@ -1098,7 +1146,8 @@ static int nut_read_packet(AVFormatContext *s, AVPacket *pkt) default: resync: av_log(s, AV_LOG_DEBUG, "syncing from %"PRId64"\n", pos); - tmp = find_any_startcode(bc, nut->last_syncpoint_pos + 1); + tmp = find_any_startcode(bc, FFMAX(nut->last_syncpoint_pos, nut->last_resync_pos) + 1); + nut->last_resync_pos = avio_tell(bc); if (tmp == 0) return AVERROR_INVALIDDATA; av_log(s, AV_LOG_DEBUG, "sync\n"); @@ -1192,12 +1241,15 @@ static int read_seek(AVFormatContext *s, int stream_index, av_log(NULL, AV_LOG_DEBUG, "SEEKTO: %"PRId64"\n", pos2); pos = find_startcode(s->pb, SYNCPOINT_STARTCODE, pos2); avio_seek(s->pb, pos, SEEK_SET); + nut->last_syncpoint_pos = pos; av_log(NULL, AV_LOG_DEBUG, "SP: %"PRId64"\n", pos); if (pos2 > pos || pos2 + 15 < pos) av_log(NULL, AV_LOG_ERROR, "no syncpoint at backptr pos\n"); for (i = 0; i < s->nb_streams; i++) nut->stream[i].skip_until_key_frame = 1; + nut->last_resync_pos = 0; + return 0; } diff --git a/libavformat/nuv.c b/libavformat/nuv.c index e7f0eeae8e..f1bc93e2f8 100644 --- a/libavformat/nuv.c +++ b/libavformat/nuv.c @@ -171,6 +171,15 @@ static int nuv_header(AVFormatContext *s) if (aspect > 0.9999 && aspect < 1.0001) aspect = 4.0 / 3.0; fps = av_int2double(avio_rl64(pb)); + if (fps < 0.0f) { + if (s->error_recognition & AV_EF_EXPLODE) { + av_log(s, AV_LOG_ERROR, "Invalid frame rate %f\n", fps); + return AVERROR_INVALIDDATA; + } else { + av_log(s, AV_LOG_WARNING, "Invalid frame rate %f, setting to 0.\n", fps); + fps = 0.0f; + } + } // number of packets per stream type, -1 means unknown, e.g. streaming v_packs = avio_rl32(pb); diff --git a/libavformat/oggenc.c b/libavformat/oggenc.c index f3413c54c9..321bee8587 100644 --- a/libavformat/oggenc.c +++ b/libavformat/oggenc.c @@ -257,7 +257,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, @@ -265,10 +265,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); + } } } } @@ -279,16 +282,18 @@ static int ogg_buffer_data(AVFormatContext *s, AVStream *st, return 0; } -static uint8_t *ogg_write_vorbiscomment(int offset, int bitexact, +static uint8_t *ogg_write_vorbiscomment(int64_t offset, int bitexact, int *header_len, AVDictionary **m, int framing_bit) { const char *vendor = bitexact ? "ffmpeg" : LIBAVFORMAT_IDENT; - int size; + int64_t size; uint8_t *p, *p0; ff_metadata_conv(m, ff_vorbiscomment_metadata_conv, NULL); size = offset + ff_vorbiscomment_length(*m, vendor) + framing_bit; + if (size > INT_MAX) + return NULL; p = av_mallocz(size); if (!p) return NULL; diff --git a/libavformat/oggparsedirac.c b/libavformat/oggparsedirac.c index 10fb07e92d..ab40f96c63 100644 --- a/libavformat/oggparsedirac.c +++ b/libavformat/oggparsedirac.c @@ -31,14 +31,19 @@ static int dirac_header(AVFormatContext *s, int idx) AVStream *st = s->streams[idx]; dirac_source_params source; GetBitContext gb; + int ret; // already parsed the header if (st->codec->codec_id == AV_CODEC_ID_DIRAC) return 0; - init_get_bits(&gb, os->buf + os->pstart + 13, (os->psize - 13) * 8); - if (avpriv_dirac_parse_sequence_header(st->codec, &gb, &source) < 0) - return -1; + ret = init_get_bits8(&gb, os->buf + os->pstart + 13, (os->psize - 13)); + if (ret < 0) + return ret; + + ret = avpriv_dirac_parse_sequence_header(st->codec, &gb, &source); + if (ret < 0) + return ret; st->codec->codec_type = AVMEDIA_TYPE_VIDEO; st->codec->codec_id = AV_CODEC_ID_DIRAC; diff --git a/libavformat/oggparsevp8.c b/libavformat/oggparsevp8.c index 5959d32b6a..7c67cc55a3 100644 --- a/libavformat/oggparsevp8.c +++ b/libavformat/oggparsevp8.c @@ -79,7 +79,11 @@ static uint64_t vp8_gptopts(AVFormatContext *s, int idx, uint64_t granule, int64 struct ogg *ogg = s->priv_data; struct ogg_stream *os = ogg->streams + idx; - uint64_t pts = (granule >> 32); + int invcnt = !((granule >> 30) & 3); + // If page granule is that of an invisible vp8 frame, its pts will be + // that of the end of the next visible frame. We substract 1 for those + // to prevent messing up pts calculations. + uint64_t pts = (granule >> 32) - invcnt; uint32_t dist = (granule >> 3) & 0x07ffffff; if (!dist) diff --git a/libavformat/omadec.c b/libavformat/omadec.c index 9f3d3aa860..7cf1e1a4b2 100644 --- a/libavformat/omadec.c +++ b/libavformat/omadec.c @@ -174,7 +174,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; @@ -464,7 +464,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/os_support.c b/libavformat/os_support.c index f9d6eeaf90..7950e44889 100644 --- a/libavformat/os_support.c +++ b/libavformat/os_support.c @@ -159,9 +159,9 @@ void ff_freeaddrinfo(struct addrinfo *res) } #endif /* HAVE_WINSOCK2_H */ - av_free(res->ai_canonname); - av_free(res->ai_addr); - av_free(res); + av_freep(&res->ai_canonname); + av_freep(&res->ai_addr); + av_freep(&res); } int ff_getnameinfo(const struct sockaddr *sa, int salen, diff --git a/libavformat/rawdec.c b/libavformat/rawdec.c index bbb76b6c95..d8dc1c3940 100644 --- a/libavformat/rawdec.c +++ b/libavformat/rawdec.c @@ -188,10 +188,10 @@ static int mjpeg_probe(AVProbeData *p) } if (nb_invalid*4 + 1 < nb_frames) { - static const char ct_jpeg[] = "\r\nContent-Type: image/jpeg\r\n\r\n"; + static const char ct_jpeg[] = "\r\nContent-Type: image/jpeg\r\n"; int i; - for (i=0; ibuf_size - sizeof(ct_jpeg), 100); i++) + for (i=0; ibuf_size - (int)sizeof(ct_jpeg), 100); i++) if (!memcmp(p->buf + i, ct_jpeg, sizeof(ct_jpeg) - 1)) return AVPROBE_SCORE_EXTENSION; diff --git a/libavformat/riff.c b/libavformat/riff.c index 8d7b1c2c61..c63e406be4 100644 --- a/libavformat/riff.c +++ b/libavformat/riff.c @@ -362,7 +362,6 @@ const AVCodecTag ff_codec_bmp_tags[] = { { AV_CODEC_ID_G2M, MKTAG('G', '2', 'M', '4') }, { AV_CODEC_ID_G2M, MKTAG('G', '2', 'M', '5') }, { AV_CODEC_ID_FIC, MKTAG('F', 'I', 'C', 'V') }, - { AV_CODEC_ID_PRORES, MKTAG('A', 'P', 'C', 'N') }, { AV_CODEC_ID_NONE, 0 } }; diff --git a/libavformat/riff.h b/libavformat/riff.h index e9256344f8..31345ec9e7 100644 --- a/libavformat/riff.h +++ b/libavformat/riff.h @@ -62,7 +62,7 @@ void ff_put_bmp_header(AVIOContext *pb, AVCodecContext *enc, const AVCodecTag *t int ff_put_wav_header(AVIOContext *pb, AVCodecContext *enc, int flags); enum AVCodecID ff_wav_codec_get_id(unsigned int tag, int bps); -int ff_get_wav_header(AVIOContext *pb, AVCodecContext *codec, int size); +int ff_get_wav_header(AVFormatContext *s, AVIOContext *pb, AVCodecContext *codec, int size); extern const AVCodecTag ff_codec_bmp_tags[]; // exposed through avformat_get_riff_video_tags() extern const AVCodecTag ff_codec_wav_tags[]; diff --git a/libavformat/riffdec.c b/libavformat/riffdec.c index 88e2229a77..d200116a87 100644 --- a/libavformat/riffdec.c +++ b/libavformat/riffdec.c @@ -80,7 +80,8 @@ static void parse_waveformatex(AVIOContext *pb, AVCodecContext *c) } } -int ff_get_wav_header(AVIOContext *pb, AVCodecContext *codec, int size) +int ff_get_wav_header(AVFormatContext *s, AVIOContext *pb, + AVCodecContext *codec, int size) { int id; @@ -93,6 +94,14 @@ int ff_get_wav_header(AVIOContext *pb, AVCodecContext *codec, int size) codec->sample_rate = avio_rl32(pb); codec->bit_rate = avio_rl32(pb) * 8; codec->block_align = avio_rl16(pb); + if (codec->bit_rate < 0) { + av_log(s, AV_LOG_WARNING, + "Invalid bit rate: %d\n", codec->bit_rate); + if (s->error_recognition & AV_EF_EXPLODE) + return AVERROR_INVALIDDATA; + else + codec->bit_rate = 0; + } if (size == 14) { /* We're dealing with plain vanilla WAVEFORMAT */ codec->bits_per_coded_sample = 8; } else @@ -114,7 +123,7 @@ int ff_get_wav_header(AVIOContext *pb, AVCodecContext *codec, int size) size -= 22; } if (cbSize > 0) { - av_free(codec->extradata); + av_freep(&codec->extradata); if (ff_get_extradata(codec, pb, cbSize) < 0) return AVERROR(ENOMEM); size -= cbSize; @@ -125,7 +134,7 @@ int ff_get_wav_header(AVIOContext *pb, AVCodecContext *codec, int size) avio_skip(pb, size); } if (codec->sample_rate <= 0) { - av_log(NULL, AV_LOG_ERROR, + av_log(s, AV_LOG_ERROR, "Invalid sample rate: %d\n", codec->sample_rate); return AVERROR_INVALIDDATA; } diff --git a/libavformat/rmdec.c b/libavformat/rmdec.c index 19bd7a7a0b..65982efe79 100644 --- a/libavformat/rmdec.c +++ b/libavformat/rmdec.c @@ -412,7 +412,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; } diff --git a/libavformat/rmenc.c b/libavformat/rmenc.c index 2e50ed338c..27b5d8264d 100644 --- a/libavformat/rmenc.c +++ b/libavformat/rmenc.c @@ -394,6 +394,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 bb2f3bc7a2..1eff5de7e6 100644 --- a/libavformat/rsd.c +++ b/libavformat/rsd.c @@ -70,7 +70,7 @@ static int rsd_read_header(AVFormatContext *s) codec->codec_tag = avio_rl32(pb); codec->codec_id = ff_codec_get_id(rsd_tags, codec->codec_tag); if (!codec->codec_id) { - char tag_buf[5]; + char tag_buf[32]; av_get_codec_tag_string(tag_buf, sizeof(tag_buf), codec->codec_tag); for (i=0; i < FF_ARRAY_ELEMS(rsd_unsupported_tags); i++) { diff --git a/libavformat/rtmpcrypt.c b/libavformat/rtmpcrypt.c index 2312527d37..fb46449a67 100644 --- a/libavformat/rtmpcrypt.c +++ b/libavformat/rtmpcrypt.c @@ -184,9 +184,14 @@ int ff_rtmpe_compute_secret_key(URLContext *h, const uint8_t *serverdata, static void rtmpe8_sig(const uint8_t *in, uint8_t *out, int key_id) { struct AVXTEA ctx; + uint8_t tmpbuf[8]; av_xtea_init(&ctx, rtmpe8_keys[key_id]); - av_xtea_crypt(&ctx, out, in, 1, NULL, 0); + AV_WB32(tmpbuf, AV_RL32(in)); + AV_WB32(tmpbuf + 4, AV_RL32(in + 4)); + av_xtea_crypt(&ctx, tmpbuf, tmpbuf, 1, NULL, 0); + AV_WL32(out, AV_RB32(tmpbuf)); + AV_WL32(out + 4, AV_RB32(tmpbuf + 4)); } static void rtmpe9_sig(const uint8_t *in, uint8_t *out, int key_id) diff --git a/libavformat/rtmpproto.c b/libavformat/rtmpproto.c index ebc1628855..3d7cdaab2d 100644 --- a/libavformat/rtmpproto.c +++ b/libavformat/rtmpproto.c @@ -217,9 +217,8 @@ static void free_tracked_methods(RTMPContext *rt) int i; for (i = 0; i < rt->nb_tracked_methods; i ++) - av_free(rt->tracked_methods[i].name); - av_free(rt->tracked_methods); - rt->tracked_methods = NULL; + av_freep(&rt->tracked_methods[i].name); + av_freep(&rt->tracked_methods); rt->tracked_methods_size = 0; rt->nb_tracked_methods = 0; } @@ -2552,7 +2551,7 @@ static int inject_fake_duration_metadata(RTMPContext *rt) // Increase the size by the injected packet rt->flv_size += 55; // Delete the old FLV data - av_free(old_flv_data); + av_freep(&old_flv_data); p = rt->flv_data + 13; bytestream_put_byte(&p, FLV_TAG_TYPE_META); diff --git a/libavformat/rtpdec_h263_rfc2190.c b/libavformat/rtpdec_h263_rfc2190.c index a2279013dc..8a36e5334c 100644 --- a/libavformat/rtpdec_h263_rfc2190.c +++ b/libavformat/rtpdec_h263_rfc2190.c @@ -83,6 +83,7 @@ static int h263_handle_packet(AVFormatContext *ctx, PayloadContext *data, avio_close_dyn_buf(data->buf, &p); av_free(p); data->buf = NULL; + data->endbyte_bits = 0; } if (len < 4) { diff --git a/libavformat/rtpdec_jpeg.c b/libavformat/rtpdec_jpeg.c index ccd80ad7e8..cefc00a370 100644 --- a/libavformat/rtpdec_jpeg.c +++ b/libavformat/rtpdec_jpeg.c @@ -207,16 +207,17 @@ static void create_default_qtables(uint8_t *qtables, uint8_t q) { int factor = q; int i; + uint16_t S; factor = av_clip(q, 1, 99); if (q < 50) - q = 5000 / factor; + S = 5000 / factor; else - q = 200 - factor * 2; + S = 200 - factor * 2; for (i = 0; i < 128; i++) { - int val = (default_quantizers[i] * q + 50) / 100; + int val = (default_quantizers[i] * S + 50) / 100; /* Limit the quantizers to 1 <= q <= 255. */ val = av_clip(val, 1, 255); diff --git a/libavformat/rtpdec_xiph.c b/libavformat/rtpdec_xiph.c index dc34f9e224..da9a1e2c22 100644 --- a/libavformat/rtpdec_xiph.c +++ b/libavformat/rtpdec_xiph.c @@ -112,7 +112,7 @@ static int xiph_handle_packet(AVFormatContext *ctx, PayloadContext *data, return data->split_pkts > 0; } - if (len < 6) { + if (len < 6 || len > INT_MAX/2) { av_log(ctx, AV_LOG_ERROR, "Invalid %d byte packet\n", len); return AVERROR_INVALIDDATA; } diff --git a/libavformat/rtpenc.c b/libavformat/rtpenc.c index c608dfb46a..93538d9203 100644 --- a/libavformat/rtpenc.c +++ b/libavformat/rtpenc.c @@ -292,7 +292,8 @@ static void rtcp_send_sr(AVFormatContext *s1, int64_t ntp_time, int bye) avio_w8(s1->pb, RTCP_SR); avio_wb16(s1->pb, 6); /* length in words - 1 */ avio_wb32(s1->pb, s->ssrc); - avio_wb64(s1->pb, NTP_TO_RTP_FORMAT(ntp_time)); + avio_wb32(s1->pb, ntp_time / 1000000); + avio_wb32(s1->pb, ((ntp_time % 1000000) << 32) / 1000000); avio_wb32(s1->pb, rtp_ts); avio_wb32(s1->pb, s->packet_count); avio_wb32(s1->pb, s->octet_count); @@ -576,10 +577,6 @@ static int rtp_write_packet(AVFormatContext *s1, AVPacket *pkt) const uint8_t *mb_info = av_packet_get_side_data(pkt, AV_PKT_DATA_H263_MB_INFO, &mb_info_size); - if (!mb_info) { - av_log(s1, AV_LOG_ERROR, "failed to allocate side data\n"); - return AVERROR(ENOMEM); - } ff_rtp_send_h263_rfc2190(s1, pkt->data, size, mb_info, mb_info_size); break; } diff --git a/libavformat/rtpenc_jpeg.c b/libavformat/rtpenc_jpeg.c index c35332953c..7ee26c435e 100644 --- a/libavformat/rtpenc_jpeg.c +++ b/libavformat/rtpenc_jpeg.c @@ -40,8 +40,8 @@ void ff_rtp_send_jpeg(AVFormatContext *s1, const uint8_t *buf, int size) s->timestamp = s->cur_timestamp; /* convert video pixel dimensions from pixels to blocks */ - w = s1->streams[0]->codec->width >> 3; - h = s1->streams[0]->codec->height >> 3; + w = FF_CEIL_RSHIFT(s1->streams[0]->codec->width, 3); + h = FF_CEIL_RSHIFT(s1->streams[0]->codec->height, 3); /* get the pixel format type or fail */ if (s1->streams[0]->codec->pix_fmt == AV_PIX_FMT_YUVJ422P || @@ -84,6 +84,11 @@ void ff_rtp_send_jpeg(AVFormatContext *s1, const uint8_t *buf, int size) } else if (buf[i + 1] == SOS) { /* SOS is last marker in the header */ i += AV_RB16(&buf[i + 2]) + 2; + if (i > size) { + av_log(s1, AV_LOG_ERROR, + "Insufficient data. Aborted!\n"); + return; + } break; } } diff --git a/libavformat/rtsp.c b/libavformat/rtsp.c index ae62252a22..6b9b544256 100644 --- a/libavformat/rtsp.c +++ b/libavformat/rtsp.c @@ -931,6 +931,8 @@ static void rtsp_parse_transport(RTSPMessageHeader *reply, const char *p) p++; reply->nb_transports++; + if (reply->nb_transports >= RTSP_MAX_TRANSPORTS) + break; } } diff --git a/libavformat/segment.c b/libavformat/segment.c index 2cad6e3dab..56ffcdcd7c 100644 --- a/libavformat/segment.c +++ b/libavformat/segment.c @@ -343,7 +343,7 @@ static int segment_end(AVFormatContext *s, int write_trailer, int is_last) if (seg->list_size && seg->segment_count >= seg->list_size) { entry = seg->segment_list_entries; seg->segment_list_entries = seg->segment_list_entries->next; - av_free(entry->filename); + av_freep(&entry->filename); av_freep(&entry); } @@ -501,10 +501,10 @@ static int open_null_ctx(AVIOContext **ctx) return 0; } -static void close_null_ctx(AVIOContext *pb) +static void close_null_ctxp(AVIOContext **pb) { - av_free(pb->buffer); - av_free(pb); + av_freep(&(*pb)->buffer); + av_freep(pb); } static int select_reference_stream(AVFormatContext *s) @@ -687,7 +687,7 @@ static int seg_write_header(AVFormatContext *s) s->avoid_negative_ts = 1; if (!seg->write_header_trailer) { - close_null_ctx(oc->pb); + close_null_ctxp(&oc->pb); if ((ret = avio_open2(&oc->pb, oc->filename, AVIO_FLAG_WRITE, &s->interrupt_callback, NULL)) < 0) goto fail; @@ -820,7 +820,7 @@ static int seg_write_trailer(struct AVFormatContext *s) goto fail; open_null_ctx(&oc->pb); ret = av_write_trailer(oc); - close_null_ctx(oc->pb); + close_null_ctxp(&oc->pb); } else { ret = segment_end(s, 1, 1); } @@ -836,7 +836,7 @@ fail: cur = seg->segment_list_entries; while (cur) { next = cur->next; - av_free(cur->filename); + av_freep(&cur->filename); av_free(cur); cur = next; } diff --git a/libavformat/smacker.c b/libavformat/smacker.c index 284cdc196a..de8bbdb07a 100644 --- a/libavformat/smacker.c +++ b/libavformat/smacker.c @@ -120,6 +120,11 @@ static int smacker_read_header(AVFormatContext *s) smk->height = avio_rl32(pb); smk->frames = avio_rl32(pb); smk->pts_inc = (int32_t)avio_rl32(pb); + if (smk->pts_inc > INT_MAX / 100) { + av_log(s, AV_LOG_ERROR, "pts_inc %d is too large\n", smk->pts_inc); + return AVERROR_INVALIDDATA; + } + smk->flags = avio_rl32(pb); if(smk->flags & SMACKER_FLAG_RING_FRAME) smk->frames++; @@ -321,7 +326,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/srtdec.c b/libavformat/srtdec.c index b35e50fc36..3b1373f559 100644 --- a/libavformat/srtdec.c +++ b/libavformat/srtdec.c @@ -41,9 +41,11 @@ static int srt_probe(AVProbeData *p) ff_text_r8(&tr); /* Check if the first non-empty line is a number. We do not check what the - * number is because in practice it can be anything. */ + * number is because in practice it can be anything. + * Also, that number can be followed by random garbage, so we can not + * unfortunately check that we only have a number. */ if (ff_subtitles_read_line(&tr, buf, sizeof(buf)) < 0 || - strtol(buf, &pbuf, 10) < 0 || *pbuf) + strtol(buf, &pbuf, 10) < 0 || pbuf == buf) return 0; /* Check if the next line matches a SRT timestamp */ diff --git a/libavformat/subtitles.c b/libavformat/subtitles.c index 67624fcf32..5bdbc8dc51 100644 --- a/libavformat/subtitles.c +++ b/libavformat/subtitles.c @@ -109,7 +109,7 @@ int ff_text_peek_r8(FFTextReader *r) } AVPacket *ff_subtitles_queue_insert(FFDemuxSubtitlesQueue *q, - const uint8_t *event, int len, int merge) + const uint8_t *event, size_t len, int merge) { AVPacket *subs, *sub; @@ -303,7 +303,7 @@ int ff_smil_extract_next_text_chunk(FFTextReader *tr, AVBPrint *buf, char *c) const char *ff_smil_get_attr_ptr(const char *s, const char *attr) { int in_quotes = 0; - const int len = strlen(attr); + const size_t len = strlen(attr); while (*s) { while (*s) { diff --git a/libavformat/subtitles.h b/libavformat/subtitles.h index eb719ea770..885285cc47 100644 --- a/libavformat/subtitles.h +++ b/libavformat/subtitles.h @@ -116,7 +116,7 @@ typedef struct { * previous one instead of adding a new entry, 0 otherwise */ AVPacket *ff_subtitles_queue_insert(FFDemuxSubtitlesQueue *q, - const uint8_t *event, int len, int merge); + const uint8_t *event, size_t len, int merge); /** * Set missing durations and sort subtitles by PTS, and then byte position. diff --git a/libavformat/swfdec.c b/libavformat/swfdec.c index 528bc236f2..b2c652eb9c 100644 --- a/libavformat/swfdec.c +++ b/libavformat/swfdec.c @@ -390,10 +390,8 @@ static int swf_read_packet(AVFormatContext *s, AVPacket *pkt) } 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"); - res = AVERROR_PATCHWELCOME; - goto bitmap_end; - } - st->codec->pix_fmt = pix_fmt; + }else + st->codec->pix_fmt = pix_fmt; if (linesize * height > pkt->size) { res = AVERROR_INVALIDDATA; diff --git a/libavformat/thp.c b/libavformat/thp.c index 714cec6cd3..91fa90f942 100644 --- a/libavformat/thp.c +++ b/libavformat/thp.c @@ -184,6 +184,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/url.c b/libavformat/url.c index acfb0cf2f0..5dd28a253d 100644 --- a/libavformat/url.c +++ b/libavformat/url.c @@ -68,7 +68,7 @@ int ff_url_join(char *str, int size, const char *proto, av_strlcatf(str, size, ":%d", port); if (fmt) { va_list vl; - int len = strlen(str); + size_t len = strlen(str); va_start(vl, fmt); vsnprintf(str + len, size > len ? size - len : 0, fmt, vl); diff --git a/libavformat/utils.c b/libavformat/utils.c index 798c6123e0..bbf67ef49e 100644 --- a/libavformat/utils.c +++ b/libavformat/utils.c @@ -53,6 +53,9 @@ #include "riff.h" #include "url.h" +#include "libavutil/ffversion.h" +const char av_format_ffversion[] = "FFmpeg version " FFMPEG_VERSION; + /** * @file * various utility functions for use within FFmpeg @@ -415,6 +418,9 @@ int avformat_open_input(AVFormatContext **ps, const char *filename, 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; @@ -594,6 +600,8 @@ static int update_wrap_reference(AVFormatContext *s, AVStream *st, int stream_in int default_stream_index = av_find_default_stream_index(s); if (s->streams[default_stream_index]->pts_wrap_reference == AV_NOPTS_VALUE) { for (i = 0; i < s->nb_streams; i++) { + if (av_find_program_from_stream(s, NULL, i)) + continue; s->streams[i]->pts_wrap_reference = pts_wrap_reference; s->streams[i]->pts_wrap_behavior = pts_wrap_behavior; } @@ -1578,6 +1586,9 @@ int av_find_default_stream_index(AVFormatContext *s) score += 50; } + if (st->discard != AVDISCARD_ALL) + score += 200; + if (score > best_score) { best_score = score; best_stream = i; @@ -2350,7 +2361,7 @@ static void estimate_timings_from_bit_rate(AVFormatContext *ic) } #define DURATION_MAX_READ_SIZE 250000LL -#define DURATION_MAX_RETRY 4 +#define DURATION_MAX_RETRY 6 /* only usable for MPEG-PS streams */ static void estimate_timings_from_pts(AVFormatContext *ic, int64_t old_offset) @@ -2791,10 +2802,14 @@ static int get_std_framerate(int i) return (i + 1) * 1001; i -= 30*12; - if (i < 7) - return ((const int[]) { 40, 48, 50, 60, 80, 120, 240})[i] * 1001 * 12; + if (i < 30) + return (i + 31) * 1001 * 12; + i -= 30; - i -= 7; + if (i < 3) + return ((const int[]) { 80, 120, 240})[i] * 1001 * 12; + + i -= 3; return ((const int[]) { 24, 30, 60, 12, 15, 48 })[i] * 1000 * 12; } @@ -2807,8 +2822,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") || @@ -2824,6 +2839,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); } @@ -3025,7 +3041,7 @@ int avformat_find_stream_info(AVFormatContext *ic, AVDictionary **options) st->codec->time_base = st->time_base; } // only for the split stuff - if (!st->parser && !(ic->flags & AVFMT_FLAG_NOPARSE)) { + if (!st->parser && !(ic->flags & AVFMT_FLAG_NOPARSE) && st->request_probe <= 0) { st->parser = av_parser_init(st->codec->codec_id); if (st->parser) { if (st->need_parsing == AVSTREAM_PARSE_HEADERS) { @@ -3644,6 +3660,11 @@ AVStream *avformat_new_stream(AVFormatContext *s, const AVCodec *c) st->info->last_dts = AV_NOPTS_VALUE; st->codec = avcodec_alloc_context3(c); + if (!st->codec) { + av_free(st->info); + av_free(st); + return NULL; + } if (s->iformat) { /* no default bitrate if decoding */ st->codec->bit_rate = 0; @@ -4081,6 +4102,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/vorbiscomment.c b/libavformat/vorbiscomment.c index cc9b6620ef..e953d83d65 100644 --- a/libavformat/vorbiscomment.c +++ b/libavformat/vorbiscomment.c @@ -61,8 +61,10 @@ int ff_vorbiscomment_write(uint8_t **p, AVDictionary **m, AVDictionaryEntry *tag = NULL; bytestream_put_le32(p, count); while ((tag = av_dict_get(*m, "", tag, AV_DICT_IGNORE_SUFFIX))) { - unsigned int len1 = strlen(tag->key); - unsigned int len2 = strlen(tag->value); + int64_t len1 = strlen(tag->key); + int64_t len2 = strlen(tag->value); + if (len1+1+len2 > UINT32_MAX) + return AVERROR(EINVAL); bytestream_put_le32(p, len1+1+len2); bytestream_put_buffer(p, tag->key, len1); bytestream_put_byte(p, '='); diff --git a/libavformat/vqf.c b/libavformat/vqf.c index 15e8246432..a8a639d8dc 100644 --- a/libavformat/vqf.c +++ b/libavformat/vqf.c @@ -261,7 +261,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/wavdec.c b/libavformat/wavdec.c index 9c4e2dfa14..cf824d834e 100644 --- a/libavformat/wavdec.c +++ b/libavformat/wavdec.c @@ -114,7 +114,7 @@ static void handle_stream_probing(AVStream *st) { if (st->codec->codec_id == AV_CODEC_ID_PCM_S16LE) { st->request_probe = AVPROBE_SCORE_EXTENSION; - st->probe_packets = FFMIN(st->probe_packets, 14); + st->probe_packets = FFMIN(st->probe_packets, 32); } } @@ -128,7 +128,7 @@ static int wav_parse_fmt_tag(AVFormatContext *s, int64_t size, AVStream **st) if (!*st) return AVERROR(ENOMEM); - ret = ff_get_wav_header(pb, (*st)->codec, size); + ret = ff_get_wav_header(s, pb, (*st)->codec, size); if (ret < 0) return ret; handle_stream_probing(*st); @@ -662,7 +662,7 @@ static int w64_read_header(AVFormatContext *s) if (!memcmp(guid, ff_w64_guid_fmt, 16)) { /* subtract chunk header size - normal wav file doesn't count it */ - ret = ff_get_wav_header(pb, st->codec, size - 24); + ret = ff_get_wav_header(s, pb, st->codec, size - 24); if (ret < 0) return ret; avio_skip(pb, FFALIGN(size, INT64_C(8)) - size); diff --git a/libavformat/webvttenc.c b/libavformat/webvttenc.c index b93993d55c..c386538718 100644 --- a/libavformat/webvttenc.c +++ b/libavformat/webvttenc.c @@ -46,8 +46,14 @@ static void webvtt_write_time(AVIOContext *pb, int64_t millisec) static int webvtt_write_header(AVFormatContext *ctx) { AVStream *s = ctx->streams[0]; + AVCodecContext *avctx = ctx->streams[0]->codec; AVIOContext *pb = ctx->pb; + if (ctx->nb_streams != 1 || avctx->codec_id != AV_CODEC_ID_WEBVTT) { + av_log(ctx, AV_LOG_ERROR, "Exactly one WebVTT stream is needed.\n"); + return AVERROR(EINVAL); + } + avpriv_set_pts_info(s, 64, 1, 1000); avio_printf(pb, "WEBVTT\n"); diff --git a/libavformat/wtvdec.c b/libavformat/wtvdec.c index 4009964824..da02978d2a 100644 --- a/libavformat/wtvdec.c +++ b/libavformat/wtvdec.c @@ -670,7 +670,7 @@ static AVStream * parse_media_type(AVFormatContext *s, AVStream *st, int sid, if (!st) return NULL; if (!ff_guidcmp(formattype, ff_format_waveformatex)) { - int ret = ff_get_wav_header(pb, st->codec, size); + int ret = ff_get_wav_header(s, pb, st->codec, size); if (ret < 0) return NULL; } else { @@ -767,7 +767,7 @@ static int recover(WtvContext *wtv, uint64_t broken_pos) int i; for (i = 0; i < wtv->nb_index_entries; i++) { if (wtv->index_entries[i].pos > broken_pos) { - int ret = avio_seek(pb, wtv->index_entries[i].pos, SEEK_SET); + int64_t ret = avio_seek(pb, wtv->index_entries[i].pos, SEEK_SET); if (ret < 0) return ret; wtv->pts = wtv->index_entries[i].timestamp; @@ -965,7 +965,7 @@ static int read_header(AVFormatContext *s) uint8_t root[WTV_SECTOR_SIZE]; AVIOContext *pb; int64_t timeline_pos; - int ret; + int64_t ret; wtv->epoch = wtv->pts = diff --git a/libavformat/xmv.c b/libavformat/xmv.c index 6eac4d21e8..1410bff8ee 100644 --- a/libavformat/xmv.c +++ b/libavformat/xmv.c @@ -547,16 +547,17 @@ static int xmv_read_packet(AVFormatContext *s, /* Fetch a video frame */ result = xmv_fetch_video_packet(s, pkt); - if (result) - return result; - } else { /* Fetch an audio frame */ result = xmv_fetch_audio_packet(s, pkt, xmv->current_stream - 1); - if (result) - return result; } + if (result) { + xmv->current_stream = 0; + xmv->video.current_frame = xmv->video.frame_count; + return result; + } + /* Increase our counters */ if (++xmv->current_stream >= xmv->stream_count) { diff --git a/libavformat/xwma.c b/libavformat/xwma.c index 5d29d0b99e..dec1c3ea53 100644 --- a/libavformat/xwma.c +++ b/libavformat/xwma.c @@ -75,7 +75,7 @@ static int xwma_read_header(AVFormatContext *s) if (!st) return AVERROR(ENOMEM); - ret = ff_get_wav_header(pb, st->codec, size); + ret = ff_get_wav_header(s, pb, st->codec, size); if (ret < 0) return ret; st->need_parsing = AVSTREAM_PARSE_NONE; diff --git a/libavutil/arm/asm.S b/libavutil/arm/asm.S index 35559ce27a..30b3dc2ca5 100644 --- a/libavutil/arm/asm.S +++ b/libavutil/arm/asm.S @@ -49,11 +49,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/arm/cpu.c b/libavutil/arm/cpu.c index f1683e8d76..02def0b470 100644 --- a/libavutil/arm/cpu.c +++ b/libavutil/arm/cpu.c @@ -128,7 +128,7 @@ int ff_get_cpu_flags_arm(void) trickle down. */ if (flags & (AV_CPU_FLAG_VFPV3 | AV_CPU_FLAG_NEON)) flags |= AV_CPU_FLAG_ARMV6T2; - else + else if (flags & (AV_CPU_FLAG_ARMV6T2 | AV_CPU_FLAG_ARMV6)) /* Some functions use the 'setend' instruction which is deprecated on ARMv8 * and serializing on some ARMv7 cores. This ensures such functions * are only enabled on ARMv6. */ diff --git a/libavutil/avstring.c b/libavutil/avstring.c index 25c65b4238..5200dd767f 100644 --- a/libavutil/avstring.c +++ b/libavutil/avstring.c @@ -100,7 +100,7 @@ size_t av_strlcat(char *dst, const char *src, size_t size) size_t av_strlcatf(char *dst, size_t size, const char *fmt, ...) { - int len = strlen(dst); + size_t len = strlen(dst); va_list vl; va_start(vl, fmt); diff --git a/libavutil/channel_layout.c b/libavutil/channel_layout.c index 4c0677f794..7aceb81971 100644 --- a/libavutil/channel_layout.c +++ b/libavutil/channel_layout.c @@ -94,7 +94,7 @@ static const struct { { "6.0(front)", 6, AV_CH_LAYOUT_6POINT0_FRONT }, { "hexagonal", 6, AV_CH_LAYOUT_HEXAGONAL }, { "6.1", 7, AV_CH_LAYOUT_6POINT1 }, - { "6.1", 7, AV_CH_LAYOUT_6POINT1_BACK }, + { "6.1(back)", 7, AV_CH_LAYOUT_6POINT1_BACK }, { "6.1(front)", 7, AV_CH_LAYOUT_6POINT1_FRONT }, { "7.0", 7, AV_CH_LAYOUT_7POINT0 }, { "7.0(front)", 7, AV_CH_LAYOUT_7POINT0_FRONT }, @@ -125,6 +125,8 @@ static uint64_t get_channel_layout_single(const char *name, int name_len) strlen(channel_names[i].name) == name_len && !memcmp(channel_names[i].name, name, name_len)) return (int64_t)1 << i; + + errno = 0; i = strtol(name, &end, 10); #if FF_API_GET_CHANNEL_LAYOUT_COMPAT @@ -138,19 +140,20 @@ static uint64_t get_channel_layout_single(const char *name, int name_len) "switch to the syntax '%.*sc' otherwise it will be interpreted as a " "channel layout number in a later version\n", name_len, name, name_len, name); - return layout; } + return layout; } } else { #endif - if ((end + 1 - name == name_len && *end == 'c')) + if (!errno && (end + 1 - name == name_len && *end == 'c')) return av_get_default_channel_layout(i); #if FF_API_GET_CHANNEL_LAYOUT_COMPAT } #endif + errno = 0; layout = strtoll(name, &end, 0); - if (end - name == name_len) + if (!errno && end - name == name_len) return FFMAX(layout, 0); return 0; } diff --git a/libavutil/colorspace.h b/libavutil/colorspace.h index f438159811..dbb0ce8b8e 100644 --- a/libavutil/colorspace.h +++ b/libavutil/colorspace.h @@ -41,6 +41,16 @@ b_add = FIX(1.77200*255.0/224.0) * cb + ONE_HALF;\ } +#define YUV_TO_RGB1_CCIR_BT709(cb1, cr1)\ +{\ + cb = (cb1) - 128;\ + cr = (cr1) - 128;\ + r_add = FIX(1.5747*255.0/224.0) * cr + ONE_HALF;\ + g_add = - FIX(0.1873*255.0/224.0) * cb - FIX(0.4682*255.0/224.0) * cr + \ + ONE_HALF;\ + b_add = FIX(1.8556*255.0/224.0) * cb + ONE_HALF;\ +} + #define YUV_TO_RGB2_CCIR(r, g, b, y1)\ {\ y = ((y1) - 16) * FIX(255.0/219.0);\ diff --git a/libavutil/common.h b/libavutil/common.h index c82a3a6240..526f5c6e51 100644 --- a/libavutil/common.h +++ b/libavutil/common.h @@ -58,9 +58,24 @@ : ((a) + (1<<(b)) - 1) >> (b)) #define FFUDIV(a,b) (((a)>0 ?(a):(a)-(b)+1) / (b)) #define FFUMOD(a,b) ((a)-(b)*FFUDIV(a,b)) + +/** + * Absolute value, Note, INT_MIN / INT64_MIN result in undefined behavior as they + * are not representable as absolute values of their type. This is the same + * as with *abs() + * @see FFNABS() + */ #define FFABS(a) ((a) >= 0 ? (a) : (-(a))) #define FFSIGN(a) ((a) > 0 ? 1 : -1) +/** + * Negative Absolute value. + * this works for all integers of all types. + * As with many macros, this evaluates its argument twice, it thus must not have + * a sideeffect, that is FFNABS(x++) has undefined behavior. + */ +#define FFNABS(a) ((a) <= 0 ? (a) : (-(a))) + #define FFMAX(a,b) ((a) > (b) ? (a) : (b)) #define FFMAX3(a,b,c) FFMAX(FFMAX(a,b),c) #define FFMIN(a,b) ((a) > (b) ? (b) : (a)) diff --git a/libavutil/cpu.c b/libavutil/cpu.c index 53c12273ef..1617464980 100644 --- a/libavutil/cpu.c +++ b/libavutil/cpu.c @@ -49,6 +49,7 @@ static int flags, checked; void av_force_cpu_flags(int arg){ if ( (arg & ( AV_CPU_FLAG_3DNOW | AV_CPU_FLAG_3DNOWEXT | + AV_CPU_FLAG_MMXEXT | AV_CPU_FLAG_SSE | AV_CPU_FLAG_SSE2 | AV_CPU_FLAG_SSE2SLOW | diff --git a/libavutil/dict.c b/libavutil/dict.c index 2983ea57a9..bfcc6151a5 100644 --- a/libavutil/dict.c +++ b/libavutil/dict.c @@ -103,7 +103,7 @@ int av_dict_set(AVDictionary **pm, const char *key, const char *value, if (flags & AV_DICT_DONT_STRDUP_VAL) { m->elems[m->count].value = (char*)(intptr_t)value; } else if (oldval && flags & AV_DICT_APPEND) { - int len = strlen(oldval) + strlen(value) + 1; + size_t len = strlen(oldval) + strlen(value) + 1; char *newval = av_mallocz(len); if (!newval) goto err_out; diff --git a/libavutil/fifo.c b/libavutil/fifo.c index 4ff3194c5f..f2fe93de75 100644 --- a/libavutil/fifo.c +++ b/libavutil/fifo.c @@ -129,7 +129,8 @@ int av_fifo_generic_write(AVFifoBuffer *f, void *src, int size, do { int len = FFMIN(f->end - wptr, size); if (func) { - if (func(src, wptr, len) <= 0) + len = func(src, wptr, len); + if (len <= 0) break; } else { memcpy(wptr, src, len); diff --git a/libavutil/file_open.c b/libavutil/file_open.c index 3f9a67c3fc..9e76127919 100644 --- a/libavutil/file_open.c +++ b/libavutil/file_open.c @@ -77,6 +77,9 @@ int avpriv_open(const char *filename, int flags, ...) #ifdef O_CLOEXEC flags |= O_CLOEXEC; #endif +#ifdef O_NOINHERIT + flags |= O_NOINHERIT; +#endif fd = open(filename, flags, mode); #if HAVE_FCNTL diff --git a/libavutil/frame.c b/libavutil/frame.c index 4ee06306ce..5c9aa2914c 100644 --- a/libavutil/frame.c +++ b/libavutil/frame.c @@ -503,6 +503,7 @@ int av_frame_copy_props(AVFrame *dst, const AVFrame *src) free_side_data(&dst->side_data[i]); } av_freep(&dst->side_data); + dst->nb_side_data = 0; return AVERROR(ENOMEM); } memcpy(sd_dst->data, sd_src->data, sd_src->size); diff --git a/libavutil/imgutils.c b/libavutil/imgutils.c index 7f3032bdf3..a12079d228 100644 --- a/libavutil/imgutils.c +++ b/libavutil/imgutils.c @@ -245,7 +245,7 @@ int av_image_check_sar(unsigned int w, unsigned int h, AVRational sar) { int64_t scaled_dim; - if (!sar.den) + if (sar.den <= 0 || sar.num < 0) return AVERROR(EINVAL); if (!sar.num || sar.num == sar.den) diff --git a/libavutil/integer.c b/libavutil/integer.c index 5bcde0dc6e..6d6855fa1b 100644 --- a/libavutil/integer.c +++ b/libavutil/integer.c @@ -29,6 +29,8 @@ #include "integer.h" #include "avassert.h" +static const AVInteger zero_i; + AVInteger av_add_i(AVInteger a, AVInteger b){ int i, carry=0; @@ -111,6 +113,12 @@ AVInteger av_mod_i(AVInteger *quot, AVInteger a, AVInteger b){ AVInteger quot_temp; if(!quot) quot = "_temp; + if ((int16_t)a.v[AV_INTEGER_SIZE-1] < 0) { + a = av_mod_i(quot, av_sub_i(zero_i, a), b); + *quot = av_sub_i(zero_i, *quot); + return av_sub_i(zero_i, a); + } + av_assert2((int16_t)a.v[AV_INTEGER_SIZE-1] >= 0 && (int16_t)b.v[AV_INTEGER_SIZE-1] >= 0); av_assert2(av_log2_i(b)>=0); diff --git a/libavutil/mathematics.c b/libavutil/mathematics.c index 126cffc3f0..78a87d8457 100644 --- a/libavutil/mathematics.c +++ b/libavutil/mathematics.c @@ -76,8 +76,8 @@ int64_t av_rescale_rnd(int64_t a, int64_t b, int64_t c, enum AVRounding rnd) rnd -= AV_ROUND_PASS_MINMAX; } - if (a < 0 && a != INT64_MIN) - return -av_rescale_rnd(-a, b, c, rnd ^ ((rnd >> 1) & 1)); + if (a < 0) + return -(uint64_t)av_rescale_rnd(-FFMAX(a, -INT64_MAX), b, c, rnd ^ ((rnd >> 1) & 1)); if (rnd == AV_ROUND_NEAR_INF) r = c / 2; @@ -87,8 +87,13 @@ int64_t av_rescale_rnd(int64_t a, int64_t b, int64_t c, enum AVRounding rnd) if (b <= INT_MAX && c <= INT_MAX) { if (a <= INT_MAX) return (a * b + r) / c; - else - return a / c * b + (a % c * b + r) / c; + else { + int64_t ad = a / c; + int64_t a2 = (a % c * b + r) / c; + if (ad >= INT32_MAX && b && ad > (INT64_MAX - a2) / b) + return INT64_MIN; + return ad * b + a2; + } } else { #if 1 uint64_t a0 = a & 0xFFFFFFFF; @@ -112,6 +117,8 @@ int64_t av_rescale_rnd(int64_t a, int64_t b, int64_t c, enum AVRounding rnd) t1++; } } + if (t1 > INT64_MAX) + return INT64_MIN; return t1; } #else diff --git a/libavutil/mem.c b/libavutil/mem.c index 35a82e8a2d..9dc1ac7a49 100644 --- a/libavutil/mem.c +++ b/libavutil/mem.c @@ -259,7 +259,7 @@ char *av_strdup(const char *s) { char *ptr = NULL; if (s) { - int len = strlen(s) + 1; + size_t len = strlen(s) + 1; ptr = av_realloc(NULL, len); if (ptr) memcpy(ptr, s, len); diff --git a/libavutil/opencl.h b/libavutil/opencl.h index 4655cba552..0b7b8d4764 100644 --- a/libavutil/opencl.h +++ b/libavutil/opencl.h @@ -32,11 +32,10 @@ #ifndef LIBAVUTIL_OPENCL_H #define LIBAVUTIL_OPENCL_H -#include "config.h" -#if HAVE_CL_CL_H -#include -#else +#ifdef __APPLE__ #include +#else +#include #endif #include #include "dict.h" diff --git a/libavutil/opt.c b/libavutil/opt.c index d873bd205e..ed7e983d59 100644 --- a/libavutil/opt.c +++ b/libavutil/opt.c @@ -65,8 +65,8 @@ static int read_number(const AVOption *o, const void *dst, double *num, int *den { switch (o->type) { case AV_OPT_TYPE_FLAGS: *intnum = *(unsigned int*)dst;return 0; - case AV_OPT_TYPE_PIXEL_FMT: - case AV_OPT_TYPE_SAMPLE_FMT: + case AV_OPT_TYPE_PIXEL_FMT: *intnum = *(enum AVPixelFormat *)dst;return 0; + case AV_OPT_TYPE_SAMPLE_FMT:*intnum = *(enum AVSampleFormat*)dst;return 0; case AV_OPT_TYPE_INT: *intnum = *(int *)dst;return 0; case AV_OPT_TYPE_CHANNEL_LAYOUT: case AV_OPT_TYPE_DURATION: @@ -100,9 +100,9 @@ static int write_number(void *obj, const AVOption *o, void *dst, double num, int } switch (o->type) { + case AV_OPT_TYPE_PIXEL_FMT: *(enum AVPixelFormat *)dst = llrint(num/den) * intnum; break; + case AV_OPT_TYPE_SAMPLE_FMT:*(enum AVSampleFormat*)dst = llrint(num/den) * intnum; break; case AV_OPT_TYPE_FLAGS: - case AV_OPT_TYPE_PIXEL_FMT: - case AV_OPT_TYPE_SAMPLE_FMT: case AV_OPT_TYPE_INT: *(int *)dst= llrint(num/den)*intnum; break; case AV_OPT_TYPE_DURATION: case AV_OPT_TYPE_CHANNEL_LAYOUT: @@ -143,6 +143,8 @@ static int set_string_binary(void *obj, const AVOption *o, const char *val, uint len /= 2; ptr = bin = av_malloc(len); + if (!ptr) + return AVERROR(ENOMEM); while (*val) { int a = hexchar2int(*val++); int b = hexchar2int(*val++); @@ -1461,10 +1463,11 @@ int av_opt_set_dict2(void *obj, AVDictionary **options, int search_flags) while ((t = av_dict_get(*options, "", t, AV_DICT_IGNORE_SUFFIX))) { ret = av_opt_set(obj, t->key, t->value, search_flags); if (ret == AVERROR_OPTION_NOT_FOUND) - av_dict_set(&tmp, t->key, t->value, 0); - else if (ret < 0) { + ret = av_dict_set(&tmp, t->key, t->value, 0); + if (ret < 0) { av_log(obj, AV_LOG_ERROR, "Error setting option %s to value %s.\n", t->key, t->value); - break; + av_dict_free(&tmp); + return ret; } ret = 0; } diff --git a/libavutil/pca.c b/libavutil/pca.c index f7ae350b48..1d88ff300a 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_array(n, sizeof(*pca->z)); 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/pixdesc.c b/libavutil/pixdesc.c index 648d014daa..fd269f6452 100644 --- a/libavutil/pixdesc.c +++ b/libavutil/pixdesc.c @@ -2143,6 +2143,7 @@ enum AVPixelFormat av_pix_fmt_swap_endianness(enum AVPixelFormat pix_fmt) #define FF_COLOR_GRAY 1 /**< gray color space */ #define FF_COLOR_YUV 2 /**< YUV color space. 16 <= Y <= 235, 16 <= U, V <= 240 */ #define FF_COLOR_YUV_JPEG 3 /**< YUV color space. 0 <= Y <= 255, 0 <= U, V <= 255 */ +#define FF_COLOR_XYZ 4 #define pixdesc_has_alpha(pixdesc) \ ((pixdesc)->nb_components == 2 || (pixdesc)->nb_components == 4 || (pixdesc)->flags & AV_PIX_FMT_FLAG_PAL) @@ -2158,6 +2159,9 @@ static int get_color_type(const AVPixFmtDescriptor *desc) { if(desc->name && !strncmp(desc->name, "yuvj", 4)) return FF_COLOR_YUV_JPEG; + if(desc->name && !strncmp(desc->name, "xyz", 3)) + return FF_COLOR_XYZ; + if(desc->flags & AV_PIX_FMT_FLAG_RGB) return FF_COLOR_RGB; diff --git a/libavutil/random_seed.c b/libavutil/random_seed.c index 8aa8c3879b..5af8e9e524 100644 --- a/libavutil/random_seed.c +++ b/libavutil/random_seed.c @@ -97,8 +97,13 @@ static uint32_t get_generic_seed(void) last_t = t; } - if(TEST) + if(TEST) { buffer[0] = buffer[1] = 0; + } else { +#ifdef AV_READ_TIME + buffer[111] += AV_READ_TIME(); +#endif + } av_sha_init(sha, 160); av_sha_update(sha, (const uint8_t *)buffer, sizeof(buffer)); diff --git a/libavutil/softfloat.h b/libavutil/softfloat.h index 8647e6a4fc..a487c34af3 100644 --- a/libavutil/softfloat.h +++ b/libavutil/softfloat.h @@ -59,7 +59,7 @@ static av_const SoftFloat av_normalize_sf(SoftFloat a){ static inline av_const SoftFloat av_normalize1_sf(SoftFloat a){ #if 1 - if((int32_t)(a.mant + 0x40000000U) < 0){ + if((int32_t)(a.mant + 0x40000000U) <= 0){ a.exp++; a.mant>>=1; } diff --git a/libavutil/timecode.c b/libavutil/timecode.c index 1dfd040868..bf463ed515 100644 --- a/libavutil/timecode.c +++ b/libavutil/timecode.c @@ -151,7 +151,7 @@ static int check_fps(int fps) static int check_timecode(void *log_ctx, AVTimecode *tc) { - if (tc->fps <= 0) { + if ((int)tc->fps <= 0) { av_log(log_ctx, AV_LOG_ERROR, "Timecode frame rate must be specified\n"); return AVERROR(EINVAL); } diff --git a/libavutil/utils.c b/libavutil/utils.c index aafd3b909e..da8b5ae2d3 100644 --- a/libavutil/utils.c +++ b/libavutil/utils.c @@ -27,6 +27,9 @@ * various utility functions */ +#include "libavutil/ffversion.h" +const char av_util_ffversion[] = "FFmpeg version " FFMPEG_VERSION; + unsigned avutil_version(void) { static int checks_done; diff --git a/libavutil/x86/float_dsp.asm b/libavutil/x86/float_dsp.asm index ec3d22b230..c4484a28e6 100644 --- a/libavutil/x86/float_dsp.asm +++ b/libavutil/x86/float_dsp.asm @@ -332,10 +332,10 @@ VECTOR_FMUL_REVERSE ; float scalarproduct_float_sse(const float *v1, const float *v2, int len) INIT_XMM sse cglobal scalarproduct_float, 3,3,2, v1, v2, offset + shl offsetd, 2 + add v1q, offsetq + add v2q, offsetq neg offsetq - shl offsetq, 2 - sub v1q, offsetq - sub v2q, offsetq xorps xmm0, xmm0 .loop: movaps xmm1, [v1q+offsetq] diff --git a/libpostproc/postprocess.c b/libpostproc/postprocess.c index f8fb356391..d95b682c3c 100644 --- a/libpostproc/postprocess.c +++ b/libpostproc/postprocess.c @@ -76,6 +76,7 @@ try to unroll inner for(x=0 ... loop to avoid these damn if(x ... checks #include "config.h" #include "libavutil/avutil.h" #include "libavutil/avassert.h" +#include "libavutil/intreadwrite.h" #include #include #include @@ -89,6 +90,9 @@ try to unroll inner for(x=0 ... loop to avoid these damn if(x ... checks #include "postprocess_internal.h" #include "libavutil/avstring.h" +#include "libavutil/ffversion.h" +const char postproc_ffversion[] = "FFmpeg version " FFMPEG_VERSION; + unsigned postproc_version(void) { av_assert0(LIBPOSTPROC_VERSION_MICRO >= 100); @@ -996,7 +1000,7 @@ void pp_postprocess(const uint8_t * src[3], const int srcStride[3], int i; 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; + AV_WN32(c->stdQPTable + (i<<2), AV_RN32(QP_store + (i<<2)) >> 1 & 0x7F7F7F7F); } for(i<<=2; istdQPTable[i] = QP_store[i]>>1; @@ -1021,7 +1025,7 @@ void pp_postprocess(const uint8_t * src[3], const int srcStride[3], int i; 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; + AV_WN32(c->nonBQPTable + (i<<2), AV_RN32(QP_store + (i<<2)) & 0x3F3F3F3F); } for(i<<=2; inonBQPTable[i] = QP_store[i] & 0x3F; diff --git a/libswresample/dither.c b/libswresample/dither.c index b8b592a7ce..23e7e12ede 100644 --- a/libswresample/dither.c +++ b/libswresample/dither.c @@ -23,12 +23,15 @@ #include "noise_shaping_data.c" -void swri_get_dither(SwrContext *s, void *dst, int len, unsigned seed, enum AVSampleFormat noise_fmt) { +int swri_get_dither(SwrContext *s, void *dst, int len, unsigned seed, enum AVSampleFormat noise_fmt) { double scale = s->dither.noise_scale; #define TMP_EXTRA 2 double *tmp = av_malloc_array(len + TMP_EXTRA, sizeof(double)); int i; + if (!tmp) + return AVERROR(ENOMEM); + 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/options.c b/libswresample/options.c index 01cdb1e141..1bc1a70510 100644 --- a/libswresample/options.c +++ b/libswresample/options.c @@ -35,12 +35,12 @@ #define PARAM AV_OPT_FLAG_AUDIO_PARAM static const AVOption options[]={ -{"ich" , "set input channel count" , OFFSET( in.ch_count ), AV_OPT_TYPE_INT , {.i64=0 }, 0 , SWR_CH_MAX, PARAM}, -{"in_channel_count" , "set input channel count" , OFFSET( in.ch_count ), AV_OPT_TYPE_INT , {.i64=0 }, 0 , SWR_CH_MAX, PARAM}, -{"och" , "set output channel count" , OFFSET(out.ch_count ), AV_OPT_TYPE_INT , {.i64=0 }, 0 , SWR_CH_MAX, PARAM}, -{"out_channel_count" , "set output channel count" , OFFSET(out.ch_count ), AV_OPT_TYPE_INT , {.i64=0 }, 0 , SWR_CH_MAX, PARAM}, -{"uch" , "set used channel count" , OFFSET(used_ch_count ), AV_OPT_TYPE_INT , {.i64=0 }, 0 , SWR_CH_MAX, PARAM}, -{"used_channel_count" , "set used channel count" , OFFSET(used_ch_count ), AV_OPT_TYPE_INT , {.i64=0 }, 0 , SWR_CH_MAX, PARAM}, +{"ich" , "set input channel count" , OFFSET(user_in_ch_count ), AV_OPT_TYPE_INT, {.i64=0 }, 0 , SWR_CH_MAX, PARAM}, +{"in_channel_count" , "set input channel count" , OFFSET(user_in_ch_count ), AV_OPT_TYPE_INT, {.i64=0 }, 0 , SWR_CH_MAX, PARAM}, +{"och" , "set output channel count" , OFFSET(user_out_ch_count ), AV_OPT_TYPE_INT, {.i64=0 }, 0 , SWR_CH_MAX, PARAM}, +{"out_channel_count" , "set output channel count" , OFFSET(user_out_ch_count ), AV_OPT_TYPE_INT, {.i64=0 }, 0 , SWR_CH_MAX, PARAM}, +{"uch" , "set used channel count" , OFFSET(user_used_ch_count), AV_OPT_TYPE_INT, {.i64=0 }, 0 , SWR_CH_MAX, PARAM}, +{"used_channel_count" , "set used channel count" , OFFSET(user_used_ch_count), AV_OPT_TYPE_INT, {.i64=0 }, 0 , SWR_CH_MAX, PARAM}, {"isr" , "set input sample rate" , OFFSET( in_sample_rate), AV_OPT_TYPE_INT , {.i64=0 }, 0 , INT_MAX , PARAM}, {"in_sample_rate" , "set input sample rate" , OFFSET( in_sample_rate), AV_OPT_TYPE_INT , {.i64=0 }, 0 , INT_MAX , PARAM}, {"osr" , "set output sample rate" , OFFSET(out_sample_rate), AV_OPT_TYPE_INT , {.i64=0 }, 0 , INT_MAX , PARAM}, @@ -49,12 +49,12 @@ static const AVOption options[]={ {"in_sample_fmt" , "set input sample format" , OFFSET( in_sample_fmt ), AV_OPT_TYPE_SAMPLE_FMT , {.i64=AV_SAMPLE_FMT_NONE}, -1 , INT_MAX, PARAM}, {"osf" , "set output sample format" , OFFSET(out_sample_fmt ), AV_OPT_TYPE_SAMPLE_FMT , {.i64=AV_SAMPLE_FMT_NONE}, -1 , INT_MAX, PARAM}, {"out_sample_fmt" , "set output sample format" , OFFSET(out_sample_fmt ), AV_OPT_TYPE_SAMPLE_FMT , {.i64=AV_SAMPLE_FMT_NONE}, -1 , INT_MAX, PARAM}, -{"tsf" , "set internal sample format" , OFFSET(int_sample_fmt ), AV_OPT_TYPE_SAMPLE_FMT , {.i64=AV_SAMPLE_FMT_NONE}, -1 , INT_MAX, PARAM}, -{"internal_sample_fmt" , "set internal sample format" , OFFSET(int_sample_fmt ), AV_OPT_TYPE_SAMPLE_FMT , {.i64=AV_SAMPLE_FMT_NONE}, -1 , INT_MAX, PARAM}, -{"icl" , "set input channel layout" , OFFSET( in_ch_layout ), AV_OPT_TYPE_CHANNEL_LAYOUT, {.i64=0 }, 0 , INT64_MAX , PARAM, "channel_layout"}, -{"in_channel_layout" , "set input channel layout" , OFFSET( in_ch_layout ), AV_OPT_TYPE_CHANNEL_LAYOUT, {.i64=0 }, 0 , INT64_MAX , PARAM, "channel_layout"}, -{"ocl" , "set output channel layout" , OFFSET(out_ch_layout ), AV_OPT_TYPE_CHANNEL_LAYOUT, {.i64=0 }, 0 , INT64_MAX , PARAM, "channel_layout"}, -{"out_channel_layout" , "set output channel layout" , OFFSET(out_ch_layout ), AV_OPT_TYPE_CHANNEL_LAYOUT, {.i64=0 }, 0 , INT64_MAX , PARAM, "channel_layout"}, +{"tsf" , "set internal sample format" , OFFSET(user_int_sample_fmt), AV_OPT_TYPE_SAMPLE_FMT , {.i64=AV_SAMPLE_FMT_NONE}, -1 , INT_MAX, PARAM}, +{"internal_sample_fmt" , "set internal sample format" , OFFSET(user_int_sample_fmt), AV_OPT_TYPE_SAMPLE_FMT , {.i64=AV_SAMPLE_FMT_NONE}, -1 , INT_MAX, PARAM}, +{"icl" , "set input channel layout" , OFFSET(user_in_ch_layout ), AV_OPT_TYPE_CHANNEL_LAYOUT, {.i64=0 }, 0 , INT64_MAX , PARAM, "channel_layout"}, +{"in_channel_layout" , "set input channel layout" , OFFSET(user_in_ch_layout ), AV_OPT_TYPE_CHANNEL_LAYOUT, {.i64=0 }, 0 , INT64_MAX , PARAM, "channel_layout"}, +{"ocl" , "set output channel layout" , OFFSET(user_out_ch_layout), AV_OPT_TYPE_CHANNEL_LAYOUT, {.i64=0 }, 0 , INT64_MAX , PARAM, "channel_layout"}, +{"out_channel_layout" , "set output channel layout" , OFFSET(user_out_ch_layout), AV_OPT_TYPE_CHANNEL_LAYOUT, {.i64=0 }, 0 , INT64_MAX , PARAM, "channel_layout"}, {"clev" , "set center mix level" , OFFSET(clev ), AV_OPT_TYPE_FLOAT, {.dbl=C_30DB }, -32 , 32 , PARAM}, {"center_mix_level" , "set center mix level" , OFFSET(clev ), AV_OPT_TYPE_FLOAT, {.dbl=C_30DB }, -32 , 32 , PARAM}, {"slev" , "set surround mix level" , OFFSET(slev ), AV_OPT_TYPE_FLOAT, {.dbl=C_30DB }, -32 , 32 , PARAM}, diff --git a/libswresample/rematrix.c b/libswresample/rematrix.c index 6552a2fea2..2238f0aae3 100644 --- a/libswresample/rematrix.c +++ b/libswresample/rematrix.c @@ -65,8 +65,8 @@ int swr_set_matrix(struct SwrContext *s, const double *matrix, int stride) if (!s || s->in_convert) // s needs to be allocated but not initialized return AVERROR(EINVAL); memset(s->matrix, 0, sizeof(s->matrix)); - nb_in = av_get_channel_layout_nb_channels(s->in_ch_layout); - nb_out = av_get_channel_layout_nb_channels(s->out_ch_layout); + nb_in = av_get_channel_layout_nb_channels(s->user_in_ch_layout); + nb_out = av_get_channel_layout_nb_channels(s->user_out_ch_layout); for (out = 0; out < nb_out; out++) { for (in = 0; in < nb_in; in++) s->matrix[out][in] = matrix[in]; diff --git a/libswresample/soxr_resample.c b/libswresample/soxr_resample.c index 064451df45..9e87f2fc4b 100644 --- a/libswresample/soxr_resample.c +++ b/libswresample/soxr_resample.c @@ -76,8 +76,12 @@ static int process( AudioData *src, int src_size, int *consumed){ size_t idone, odone; soxr_error_t error = soxr_set_error((soxr_t)c, soxr_set_num_channels((soxr_t)c, src->ch_count)); - error = soxr_process((soxr_t)c, src->ch, (size_t)src_size, - &idone, dst->ch, (size_t)dst_size, &odone); + if (!error) + error = soxr_process((soxr_t)c, src->ch, (size_t)src_size, + &idone, dst->ch, (size_t)dst_size, &odone); + else + idone = 0; + *consumed = (int)idone; return error? -1 : odone; } diff --git a/libswresample/swresample-test.c b/libswresample/swresample-test.c index c0162cd646..694880648a 100644 --- a/libswresample/swresample-test.c +++ b/libswresample/swresample-test.c @@ -314,6 +314,11 @@ int main(int argc, char **argv){ fprintf(stderr, "Failed to init backw_ctx\n"); return 1; } + if (uint_rand(rand_seed) % 3 == 0) + av_opt_set_int(forw_ctx, "ich", 0, 0); + if (uint_rand(rand_seed) % 3 == 0) + av_opt_set_int(forw_ctx, "och", 0, 0); + if(swr_init( forw_ctx) < 0) fprintf(stderr, "swr_init(->) failed\n"); if(swr_init(backw_ctx) < 0) diff --git a/libswresample/swresample.c b/libswresample/swresample.c index b0bd697e04..bf41332ee0 100644 --- a/libswresample/swresample.c +++ b/libswresample/swresample.c @@ -23,11 +23,15 @@ #include "audioconvert.h" #include "libavutil/avassert.h" #include "libavutil/channel_layout.h" +#include "libavutil/internal.h" #include #define ALIGN 32 +#include "libavutil/ffversion.h" +const char swr_ffversion[] = "FFmpeg version " FFMPEG_VERSION; + unsigned swresample_version(void) { av_assert0(LIBSWRESAMPLE_VERSION_MICRO >= 100); @@ -83,10 +87,10 @@ struct SwrContext *swr_alloc_set_opts(struct SwrContext *s, if (av_opt_set_int(s, "tsf", AV_SAMPLE_FMT_NONE, 0) < 0) goto fail; - if (av_opt_set_int(s, "ich", av_get_channel_layout_nb_channels(s-> in_ch_layout), 0) < 0) + if (av_opt_set_int(s, "ich", av_get_channel_layout_nb_channels(s-> user_in_ch_layout), 0) < 0) goto fail; - if (av_opt_set_int(s, "och", av_get_channel_layout_nb_channels(s->out_ch_layout), 0) < 0) + if (av_opt_set_int(s, "och", av_get_channel_layout_nb_channels(s->user_out_ch_layout), 0) < 0) goto fail; av_opt_set_int(s, "uch", 0, 0); @@ -149,6 +153,7 @@ av_cold void swr_close(SwrContext *s){ av_cold int swr_init(struct SwrContext *s){ int ret; + char l1[1024], l2[1024]; clear_context(s); @@ -161,6 +166,15 @@ av_cold int swr_init(struct SwrContext *s){ return AVERROR(EINVAL); } + s->out.ch_count = s-> user_out_ch_count; + s-> in.ch_count = s-> user_in_ch_count; + s->used_ch_count = s->user_used_ch_count; + + s-> in_ch_layout = s-> user_in_ch_layout; + s->out_ch_layout = s->user_out_ch_layout; + + s->int_sample_fmt= s->user_int_sample_fmt; + if(av_get_channel_layout_nb_channels(s-> in_ch_layout) > SWR_CH_MAX) { av_log(s, AV_LOG_WARNING, "Input channel layout 0x%"PRIx64" is invalid or unsupported.\n", s-> in_ch_layout); s->in_ch_layout = 0; @@ -243,6 +257,10 @@ av_cold int swr_init(struct SwrContext *s){ if (s->out_sample_rate!=s->in_sample_rate || (s->flags & SWR_FLAG_RESAMPLE)){ s->resample = s->resampler->init(s->resample, s->out_sample_rate, s->in_sample_rate, s->filter_size, s->phase_shift, s->linear_interp, s->cutoff, s->int_sample_fmt, s->filter_type, s->kaiser_beta, s->precision, s->cheby); + if (!s->resample) { + av_log(s, AV_LOG_ERROR, "Failed to initilaize resampler\n"); + return AVERROR(ENOMEM); + } }else s->resampler->free(&s->resample); if( s->int_sample_fmt != AV_SAMPLE_FMT_S16P @@ -251,7 +269,8 @@ av_cold int swr_init(struct SwrContext *s){ && s->int_sample_fmt != AV_SAMPLE_FMT_DBLP && s->resample){ av_log(s, AV_LOG_ERROR, "Resampling only supported with internal s16/s32/flt/dbl\n"); - return -1; + ret = AVERROR(EINVAL); + goto fail; } #define RSC 1 //FIXME finetune @@ -265,16 +284,28 @@ av_cold int swr_init(struct SwrContext *s){ if(!s-> in.ch_count){ av_assert0(!s->in_ch_layout); av_log(s, AV_LOG_ERROR, "Input channel count and layout are unset\n"); - return -1; + ret = AVERROR(EINVAL); + goto fail; + } + + av_get_channel_layout_string(l1, sizeof(l1), s-> in.ch_count, s-> in_ch_layout); + av_get_channel_layout_string(l2, sizeof(l2), s->out.ch_count, s->out_ch_layout); + if (s->out_ch_layout && s->out.ch_count != av_get_channel_layout_nb_channels(s->out_ch_layout)) { + av_log(s, AV_LOG_ERROR, "Output channel layout %s mismatches specified channel count %d\n", l2, s->out.ch_count); + ret = AVERROR(EINVAL); + goto fail; + } + if (s->in_ch_layout && s->used_ch_count != av_get_channel_layout_nb_channels(s->in_ch_layout)) { + av_log(s, AV_LOG_ERROR, "Input channel layout %s mismatches specified channel count %d\n", l1, s->used_ch_count); + ret = AVERROR(EINVAL); + goto fail; } if ((!s->out_ch_layout || !s->in_ch_layout) && s->used_ch_count != s->out.ch_count && !s->rematrix_custom) { - char l1[1024], l2[1024]; - av_get_channel_layout_string(l1, sizeof(l1), s-> in.ch_count, s-> in_ch_layout); - av_get_channel_layout_string(l2, sizeof(l2), s->out.ch_count, s->out_ch_layout); av_log(s, AV_LOG_ERROR, "Rematrix is needed between %s and %s " "but there is not enough information to do it\n", l1, l2); - return -1; + ret = AVERROR(EINVAL); + goto fail; } av_assert0(s->used_ch_count); @@ -296,8 +327,10 @@ av_assert0(s->out.ch_count); s->out_convert= swri_audio_convert_alloc(s->out_sample_fmt, s->int_sample_fmt, s->out.ch_count, NULL, 0); - if (!s->in_convert || !s->out_convert) - return AVERROR(ENOMEM); + if (!s->in_convert || !s->out_convert) { + ret = AVERROR(ENOMEM); + goto fail; + } s->postin= s->in; s->preout= s->out; @@ -324,12 +357,19 @@ av_assert0(s->out.ch_count); } if ((ret = swri_dither_init(s, s->out_sample_fmt, s->int_sample_fmt)) < 0) - return ret; + goto fail; - if(s->rematrix || s->dither.method) - return swri_rematrix_init(s); + if(s->rematrix || s->dither.method) { + ret = swri_rematrix_init(s); + if (ret < 0) + goto fail; + } return 0; +fail: + swr_close(s); + return ret; + } int swri_realloc_audio(AudioData *a, int count){ @@ -604,7 +644,8 @@ static int swr_convert_internal(struct SwrContext *s, AudioData *out, int out_co return ret; if(ret) for(ch=0; chdither.noise.ch_count; ch++) - swri_get_dither(s, s->dither.noise.ch[ch], s->dither.noise.count, 12345678913579<dither.noise.fmt); + if((ret=swri_get_dither(s, s->dither.noise.ch[ch], s->dither.noise.count, (12345678913579ULL*ch + 3141592) % 2718281828U, s->dither.noise.fmt))<0) + return ret; av_assert0(s->dither.noise.ch_count == preout->ch_count); if(s->dither.noise_pos + out_count > s->dither.noise.count) @@ -645,8 +686,8 @@ int swr_is_initialized(struct SwrContext *s) { return !!s->in_buffer.ch_count; } -int swr_convert(struct SwrContext *s, uint8_t *out_arg[SWR_CH_MAX], int out_count, - const uint8_t *in_arg [SWR_CH_MAX], int in_count){ +int attribute_align_arg swr_convert(struct SwrContext *s, uint8_t *out_arg[SWR_CH_MAX], int out_count, + const uint8_t *in_arg [SWR_CH_MAX], int in_count){ AudioData * in= &s->in; AudioData *out= &s->out; diff --git a/libswresample/swresample_internal.h b/libswresample/swresample_internal.h index 3761843e3b..f55bd9df6d 100644 --- a/libswresample/swresample_internal.h +++ b/libswresample/swresample_internal.h @@ -90,6 +90,13 @@ struct SwrContext { int used_ch_count; ///< number of used input channels (mapped channel count if channel_map, otherwise in.ch_count) enum SwrEngine engine; + int user_in_ch_count; ///< User set input channel count + int user_out_ch_count; ///< User set output channel count + int user_used_ch_count; ///< User set used channel count + int64_t user_in_ch_layout; ///< User set input channel layout + int64_t user_out_ch_layout; ///< User set output channel layout + enum AVSampleFormat user_int_sample_fmt; ///< User set internal sample format + struct DitherContext dither; int filter_size; /**< length of each FIR filter in the resampling filterbank relative to the cutoff frequency */ @@ -185,7 +192,7 @@ void swri_rematrix_free(SwrContext *s); int swri_rematrix(SwrContext *s, AudioData *out, AudioData *in, int len, int mustcopy); void swri_rematrix_init_x86(struct SwrContext *s); -void swri_get_dither(SwrContext *s, void *dst, int len, unsigned seed, enum AVSampleFormat noise_fmt); +int swri_get_dither(SwrContext *s, void *dst, int len, unsigned seed, enum AVSampleFormat noise_fmt); int swri_dither_init(SwrContext *s, enum AVSampleFormat out_fmt, enum AVSampleFormat in_fmt); void swri_audio_convert_init_aarch64(struct AudioConvert *ac, diff --git a/libswresample/x86/audio_convert.asm b/libswresample/x86/audio_convert.asm index 57d3a8951f..9bccf3f842 100644 --- a/libswresample/x86/audio_convert.asm +++ b/libswresample/x86/audio_convert.asm @@ -221,6 +221,8 @@ cglobal pack_6ch_%2_to_%1_%3, 2,8,7, dst, src, src1, src2, src3, src4, src5, len jne pack_6ch_%2_to_%1_u_int %+ SUFFIX test srcq, mmsize-1 jne pack_6ch_%2_to_%1_u_int %+ SUFFIX + test src1q, mmsize-1 + jne pack_6ch_%2_to_%1_u_int %+ SUFFIX test src2q, mmsize-1 jne pack_6ch_%2_to_%1_u_int %+ SUFFIX test src3q, mmsize-1 diff --git a/libswscale/input.c b/libswscale/input.c index 6716f0dcec..5dcae8cd7d 100644 --- a/libswscale/input.c +++ b/libswscale/input.c @@ -412,14 +412,24 @@ static void gbr24pToUV_half_c(uint8_t *_dstU, uint8_t *_dstV, } } -static void rgba64ToA_c(uint8_t *_dst, const uint8_t *_src, const uint8_t *unused1, - const uint8_t *unused2, int width, uint32_t *unused) +static void rgba64leToA_c(uint8_t *_dst, const uint8_t *_src, const uint8_t *unused1, + const uint8_t *unused2, int width, uint32_t *unused) { int16_t *dst = (int16_t *)_dst; const uint16_t *src = (const uint16_t *)_src; int i; for (i = 0; i < width; i++) - dst[i] = src[4 * i + 3]; + dst[i] = AV_RL16(src + 4 * i + 3); +} + +static void rgba64beToA_c(uint8_t *_dst, const uint8_t *_src, const uint8_t *unused1, + const uint8_t *unused2, int width, uint32_t *unused) +{ + int16_t *dst = (int16_t *)_dst; + const uint16_t *src = (const uint16_t *)_src; + int i; + for (i = 0; i < width; i++) + dst[i] = AV_RB16(src + 4 * i + 3); } static void abgrToA_c(uint8_t *_dst, const uint8_t *src, const uint8_t *unused1, const uint8_t *unused2, int width, uint32_t *unused) @@ -808,6 +818,19 @@ static av_always_inline void planar_rgb16_to_y(uint8_t *_dst, const uint8_t *_sr } } +static av_always_inline void planar_rgb16_to_a(uint8_t *_dst, const uint8_t *_src[4], + int width, int bpc, int is_be, int32_t *rgb2yuv) +{ + int i; + const uint16_t **src = (const uint16_t **)_src; + uint16_t *dst = (uint16_t *)_dst; + int shift = bpc < 16 ? bpc : 14; + + for (i = 0; i < width; i++) { + dst[i] = rdpx(src[3] + i) << (14 - shift); + } +} + static av_always_inline void planar_rgb16_to_uv(uint8_t *_dstU, uint8_t *_dstV, const uint8_t *_src[4], int width, int bpc, int is_be, int32_t *rgb2yuv) @@ -836,6 +859,11 @@ static void planar_rgb##nbits##endian_name##_to_y(uint8_t *dst, const uint8_t *s { \ planar_rgb16_to_y(dst, src, w, nbits, endian, rgb2yuv); \ } \ +static void planar_rgb##nbits##endian_name##_to_a(uint8_t *dst, const uint8_t *src[4], \ + int w, int32_t *rgb2yuv) \ +{ \ + planar_rgb16_to_a(dst, src, w, nbits, endian, rgb2yuv); \ +} \ static void planar_rgb##nbits##endian_name##_to_uv(uint8_t *dstU, uint8_t *dstV, \ const uint8_t *src[4], int w, int32_t *rgb2yuv) \ { \ @@ -1158,6 +1186,7 @@ av_cold void ff_sws_init_input_funcs(SwsContext *c) c->readLumPlanar = planar_rgb14le_to_y; break; case AV_PIX_FMT_GBRAP16LE: + c->readAlpPlanar = planar_rgb16le_to_a; case AV_PIX_FMT_GBRP16LE: c->readLumPlanar = planar_rgb16le_to_y; break; @@ -1174,6 +1203,7 @@ av_cold void ff_sws_init_input_funcs(SwsContext *c) c->readLumPlanar = planar_rgb14be_to_y; break; case AV_PIX_FMT_GBRAP16BE: + c->readAlpPlanar = planar_rgb16be_to_a; case AV_PIX_FMT_GBRP16BE: c->readLumPlanar = planar_rgb16be_to_y; break; @@ -1249,11 +1279,9 @@ av_cold void ff_sws_init_input_funcs(SwsContext *c) #endif case AV_PIX_FMT_YA16LE: c->lumToYV12 = read_ya16le_gray_c; - c->alpToYV12 = read_ya16le_alpha_c; break; case AV_PIX_FMT_YA16BE: c->lumToYV12 = read_ya16be_gray_c; - c->alpToYV12 = read_ya16be_alpha_c; break; case AV_PIX_FMT_YUYV422: case AV_PIX_FMT_YVYU422: @@ -1361,9 +1389,9 @@ av_cold void ff_sws_init_input_funcs(SwsContext *c) } switch (srcFormat) { case AV_PIX_FMT_BGRA64LE: + case AV_PIX_FMT_RGBA64LE: c->alpToYV12 = rgba64leToA_c; break; case AV_PIX_FMT_BGRA64BE: - case AV_PIX_FMT_RGBA64LE: - case AV_PIX_FMT_RGBA64BE: c->alpToYV12 = rgba64ToA_c; break; + case AV_PIX_FMT_RGBA64BE: c->alpToYV12 = rgba64beToA_c; break; case AV_PIX_FMT_BGRA: case AV_PIX_FMT_RGBA: c->alpToYV12 = rgbaToA_c; @@ -1375,6 +1403,12 @@ av_cold void ff_sws_init_input_funcs(SwsContext *c) case AV_PIX_FMT_YA8: c->alpToYV12 = uyvyToY_c; break; + case AV_PIX_FMT_YA16LE: + c->alpToYV12 = read_ya16le_alpha_c; + break; + case AV_PIX_FMT_YA16BE: + c->alpToYV12 = read_ya16be_alpha_c; + break; case AV_PIX_FMT_PAL8 : c->alpToYV12 = palToA_c; break; diff --git a/libswscale/ppc/swscale_altivec.c b/libswscale/ppc/swscale_altivec.c index a1548a7717..3f8cedb8d3 100644 --- a/libswscale/ppc/swscale_altivec.c +++ b/libswscale/ppc/swscale_altivec.c @@ -40,19 +40,11 @@ ls = vec_perm(a, l2, c);\ a = l2;\ } -#define GET_VF(a, b, c,d) {\ - a = vec_mergeh(c, d);\ - b = vec_mergel(c, d);\ - } #else #define GET_LS(a,b,c,s) {\ ls = a;\ a = vec_vsx_ld(((b) << 1) + 16, s);\ } -#define GET_VF(a, b, c, d) {\ - a = vec_mergel(d, c);\ - b = vec_mergeh(d, c);\ - } #endif #define yuv2planeX_8(d1, d2, l1, src, x, perm, filter) do {\ @@ -61,7 +53,8 @@ vector signed int i1 = vec_mule(filter, ls);\ vector signed int i2 = vec_mulo(filter, ls);\ vector signed int vf1, vf2;\ - GET_VF(vf1, vf2, i1, i2);\ + vf1 = vec_mergeh(i1, i2);\ + vf2 = vec_mergel(i1, i2);\ d1 = vec_add(d1, vf1);\ d2 = vec_add(d2, vf2);\ } while (0) diff --git a/libswscale/rgb2rgb.c b/libswscale/rgb2rgb.c index 5b1fcf73ca..340174fd65 100644 --- a/libswscale/rgb2rgb.c +++ b/libswscale/rgb2rgb.c @@ -51,6 +51,7 @@ void (*rgb16to15)(const uint8_t *src, uint8_t *dst, int src_size); void (*rgb15to16)(const uint8_t *src, uint8_t *dst, int src_size); void (*rgb15to32)(const uint8_t *src, uint8_t *dst, int src_size); +void (*shuffle_bytes_0321)(const uint8_t *src, uint8_t *dst, int src_size); void (*shuffle_bytes_2103)(const uint8_t *src, uint8_t *dst, int src_size); void (*yv12toyuy2)(const uint8_t *ysrc, const uint8_t *usrc, @@ -333,7 +334,6 @@ void shuffle_bytes_ ## a ## b ## c ## d(const uint8_t *src, \ } \ } -DEFINE_SHUFFLE_BYTES(0, 3, 2, 1) DEFINE_SHUFFLE_BYTES(1, 2, 3, 0) DEFINE_SHUFFLE_BYTES(3, 0, 1, 2) DEFINE_SHUFFLE_BYTES(3, 2, 1, 0) diff --git a/libswscale/rgb2rgb.h b/libswscale/rgb2rgb.h index 5df5dea420..8faebe6a43 100644 --- a/libswscale/rgb2rgb.h +++ b/libswscale/rgb2rgb.h @@ -50,6 +50,7 @@ extern void (*rgb24to15)(const uint8_t *src, uint8_t *dst, int src_size); extern void (*rgb32tobgr16)(const uint8_t *src, uint8_t *dst, int src_size); extern void (*rgb32tobgr15)(const uint8_t *src, uint8_t *dst, int src_size); +extern void (*shuffle_bytes_0321)(const uint8_t *src, uint8_t *dst, int src_size); extern void (*shuffle_bytes_2103)(const uint8_t *src, uint8_t *dst, int src_size); void rgb64tobgr48_nobswap(const uint8_t *src, uint8_t *dst, int src_size); @@ -71,7 +72,6 @@ void rgb15tobgr15(const uint8_t *src, uint8_t *dst, int src_size); void rgb12tobgr12(const uint8_t *src, uint8_t *dst, int src_size); void rgb12to15(const uint8_t *src, uint8_t *dst, int src_size); -void shuffle_bytes_0321(const uint8_t *src, uint8_t *dst, int src_size); void shuffle_bytes_1230(const uint8_t *src, uint8_t *dst, int src_size); void shuffle_bytes_3012(const uint8_t *src, uint8_t *dst, int src_size); void shuffle_bytes_3210(const uint8_t *src, uint8_t *dst, int src_size); diff --git a/libswscale/rgb2rgb_template.c b/libswscale/rgb2rgb_template.c index f9a98a8701..1cc28cdd13 100644 --- a/libswscale/rgb2rgb_template.c +++ b/libswscale/rgb2rgb_template.c @@ -322,12 +322,26 @@ static inline void shuffle_bytes_2103_c(const uint8_t *src, uint8_t *dst, uint8_t *d = dst - idx; for (; idx < 15; idx += 4) { - register int v = *(const uint32_t *)&s[idx], g = v & 0xff00ff00; + register unsigned v = *(const uint32_t *)&s[idx], g = v & 0xff00ff00; v &= 0xff00ff; *(uint32_t *)&d[idx] = (v >> 16) + g + (v << 16); } } +static inline void shuffle_bytes_0321_c(const uint8_t *src, uint8_t *dst, + int src_size) +{ + int idx = 15 - src_size; + const uint8_t *s = src - idx; + uint8_t *d = dst - idx; + + for (; idx < 15; idx += 4) { + register unsigned v = *(const uint32_t *)&s[idx], g = v & 0x00ff00ff; + v &= 0xff00ff00; + *(uint32_t *)&d[idx] = (v >> 16) + g + (v << 16); + } +} + static inline void rgb24tobgr24_c(const uint8_t *src, uint8_t *dst, int src_size) { unsigned i; @@ -929,7 +943,13 @@ static av_cold void rgb2rgb_init_c(void) rgb24to15 = rgb24to15_c; rgb24to16 = rgb24to16_c; rgb24tobgr24 = rgb24tobgr24_c; +#if HAVE_BIGENDIAN + shuffle_bytes_0321 = shuffle_bytes_2103_c; + shuffle_bytes_2103 = shuffle_bytes_0321_c; +#else + shuffle_bytes_0321 = shuffle_bytes_0321_c; shuffle_bytes_2103 = shuffle_bytes_2103_c; +#endif rgb32tobgr16 = rgb32tobgr16_c; rgb32tobgr15 = rgb32tobgr15_c; yv12toyuy2 = yv12toyuy2_c; diff --git a/libswscale/swscale-test.c b/libswscale/swscale-test.c index 661ff5b7b2..b79bb2373a 100644 --- a/libswscale/swscale-test.c +++ b/libswscale/swscale-test.c @@ -399,7 +399,7 @@ bad_option: for (y = 0; y < H; y++) for (x = 0; x < W * 4; x++) rgb_data[ x + y * 4 * W] = av_lfg_get(&rand); - sws_scale(sws, rgb_src, rgb_stride, 0, H, src, stride); + sws_scale(sws, rgb_src, rgb_stride, 0, H / 12, src, stride); sws_freeContext(sws); av_free(rgb_data); diff --git a/libswscale/swscale.c b/libswscale/swscale.c index 16a31cee40..a29e2ae50f 100644 --- a/libswscale/swscale.c +++ b/libswscale/swscale.c @@ -895,11 +895,19 @@ int attribute_align_arg sws_scale(struct SwsContext *c, const uint8_t *src2[4]; uint8_t *dst2[4]; uint8_t *rgb0_tmp = NULL; + int macro_height = isBayer(c->srcFormat) ? 2 : (1 << c->chrSrcVSubSample); 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; } + + if ((srcSliceY & (macro_height-1)) || + ((srcSliceH& (macro_height-1)) && srcSliceY + srcSliceH != c->srcH) || + srcSliceY + srcSliceH > c->srcH) { + av_log(c, AV_LOG_ERROR, "Slice parameters %d, %d are invalid\n", srcSliceY, srcSliceH); + return AVERROR(EINVAL); + } if (c->cascaded_context[0] && srcSliceY == 0 && srcSliceH == c->cascaded_context[0]->srcH) { ret = sws_scale(c->cascaded_context[0], srcSlice, srcStride, srcSliceY, srcSliceH, diff --git a/libswscale/swscale_internal.h b/libswscale/swscale_internal.h index 63b4eca829..a3e7e267f8 100644 --- a/libswscale/swscale_internal.h +++ b/libswscale/swscale_internal.h @@ -39,7 +39,8 @@ #define STR(s) AV_TOSTRING(s) // AV_STRINGIFY is too long -#define YUVRGB_TABLE_HEADROOM 128 +#define YUVRGB_TABLE_HEADROOM 512 +#define YUVRGB_TABLE_LUMA_HEADROOM 512 #define MAX_FILTER_SIZE SWS_MAX_FILTER_SIZE diff --git a/libswscale/swscale_unscaled.c b/libswscale/swscale_unscaled.c index da457dfbdb..60f8c619b3 100644 --- a/libswscale/swscale_unscaled.c +++ b/libswscale/swscale_unscaled.c @@ -1058,6 +1058,8 @@ static int bayer_to_rgb24_wrapper(SwsContext *c, const uint8_t* src[], int srcSt default: return 0; } + av_assert0(srcSliceH > 1); + copy(srcPtr, srcStride[0], dstPtr, dstStride[0], c->srcW); srcPtr += 2 * srcStride[0]; dstPtr += 2 * dstStride[0]; @@ -1068,7 +1070,10 @@ static int bayer_to_rgb24_wrapper(SwsContext *c, const uint8_t* src[], int srcSt dstPtr += 2 * dstStride[0]; } - copy(srcPtr, srcStride[0], dstPtr, dstStride[0], c->srcW); + if (i + 1 == srcSliceH) { + copy(srcPtr, -srcStride[0], dstPtr, -dstStride[0], c->srcW); + } else if (i < srcSliceH) + copy(srcPtr, srcStride[0], dstPtr, dstStride[0], c->srcW); return srcSliceH; } @@ -1104,6 +1109,8 @@ static int bayer_to_yv12_wrapper(SwsContext *c, const uint8_t* src[], int srcStr default: return 0; } + av_assert0(srcSliceH > 1); + copy(srcPtr, srcStride[0], dstY, dstU, dstV, dstStride[0], c->srcW, c->input_rgb2yuv_table); srcPtr += 2 * srcStride[0]; dstY += 2 * dstStride[0]; @@ -1118,7 +1125,10 @@ static int bayer_to_yv12_wrapper(SwsContext *c, const uint8_t* src[], int srcStr dstV += dstStride[1]; } - copy(srcPtr, srcStride[0], dstY, dstU, dstV, dstStride[0], c->srcW, c->input_rgb2yuv_table); + if (i + 1 == srcSliceH) { + copy(srcPtr, -srcStride[0], dstY, dstU, dstV, -dstStride[0], c->srcW, c->input_rgb2yuv_table); + } else if (i < srcSliceH) + copy(srcPtr, srcStride[0], dstY, dstU, dstV, dstStride[0], c->srcW, c->input_rgb2yuv_table); return srcSliceH; } @@ -1242,6 +1252,11 @@ static rgbConvFn findRgbConvFn(SwsContext *c) if ((dstFormat == AV_PIX_FMT_RGB32_1 || dstFormat == AV_PIX_FMT_BGR32_1) && !isRGBA32(srcFormat) && ALT32_CORR<0) return NULL; + // Maintain symmetry between endianness + if (c->flags & SWS_BITEXACT) + if ((dstFormat == AV_PIX_FMT_RGB32 || dstFormat == AV_PIX_FMT_BGR32 ) && !isRGBA32(srcFormat) && ALT32_CORR>0) + return NULL; + return conv; } diff --git a/libswscale/utils.c b/libswscale/utils.c index ab494ed79c..2baf1f47ef 100644 --- a/libswscale/utils.c +++ b/libswscale/utils.c @@ -380,7 +380,7 @@ static av_cold int initFilter(int16_t **outFilter, int32_t **filterPos, xDstInSrc = ((dstPos*(int64_t)xInc)>>7) - ((srcPos*0x10000LL)>>7); for (i = 0; i < dstW; i++) { - int xx = (xDstInSrc - ((int64_t)(filterSize - 2) << 16)) / (1 << 17); + int xx = (xDstInSrc - (filterSize - 2) * (1LL<<16)) / (1 << 17); int j; (*filterPos)[i] = xx; for (j = 0; j < filterSize; j++) { @@ -611,14 +611,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; } } @@ -807,8 +818,6 @@ int sws_setColorspaceDetails(struct SwsContext *c, const int inv_table[4], const AVPixFmtDescriptor *desc_dst; const AVPixFmtDescriptor *desc_src; int need_reinit = 0; - memmove(c->srcColorspaceTable, inv_table, sizeof(int) * 4); - memmove(c->dstColorspaceTable, table, sizeof(int) * 4); handle_formats(c); desc_dst = av_pix_fmt_desc_get(c->dstFormat); @@ -819,11 +828,24 @@ int sws_setColorspaceDetails(struct SwsContext *c, const int inv_table[4], if(!isYUV(c->srcFormat) && !isGray(c->srcFormat)) srcRange = 0; + if (c->srcRange != srcRange || + c->dstRange != dstRange || + c->brightness != brightness || + c->contrast != contrast || + c->saturation != saturation || + memcmp(c->srcColorspaceTable, inv_table, sizeof(int) * 4) || + memcmp(c->dstColorspaceTable, table, sizeof(int) * 4) + ) + need_reinit = 1; + + memmove(c->srcColorspaceTable, inv_table, sizeof(int) * 4); + memmove(c->dstColorspaceTable, table, sizeof(int) * 4); + + + c->brightness = brightness; c->contrast = contrast; c->saturation = saturation; - if (c->srcRange != srcRange || c->dstRange != dstRange) - need_reinit = 1; c->srcRange = srcRange; c->dstRange = dstRange; @@ -838,6 +860,9 @@ int sws_setColorspaceDetails(struct SwsContext *c, const int inv_table[4], c->dstFormatBpp = av_get_bits_per_pixel(desc_dst); c->srcFormatBpp = av_get_bits_per_pixel(desc_src); + if (!need_reinit) + return 0; + if (!isYUV(c->dstFormat) && !isGray(c->dstFormat)) { ff_yuv2rgb_c_init_tables(c, inv_table, srcRange, brightness, contrast, saturation); @@ -1034,6 +1059,12 @@ av_cold int sws_init_context(SwsContext *c, SwsFilter *srcFilter, srcW, srcH, dstW, dstH); return AVERROR(EINVAL); } + if (flags & SWS_FAST_BILINEAR) { + if (srcW < 8 || dstW < 8) { + flags ^= SWS_FAST_BILINEAR | SWS_BILINEAR; + c->flags = flags; + } + } if (!dstFilter) dstFilter = &dummyFilter; @@ -1156,6 +1187,7 @@ av_cold int sws_init_context(SwsContext *c, SwsFilter *srcFilter, srcFormat != AV_PIX_FMT_GBRP12BE && srcFormat != AV_PIX_FMT_GBRP12LE && srcFormat != AV_PIX_FMT_GBRP14BE && srcFormat != AV_PIX_FMT_GBRP14LE && srcFormat != AV_PIX_FMT_GBRP16BE && srcFormat != AV_PIX_FMT_GBRP16LE && + srcFormat != AV_PIX_FMT_GBRAP16BE && srcFormat != AV_PIX_FMT_GBRAP16LE && ((dstW >> c->chrDstHSubSample) <= (srcW >> 1) || (flags & SWS_FAST_BILINEAR))) c->chrSrcHSubSample = 1; @@ -1166,7 +1198,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); c->srcBpc = 1 + desc_src->comp[0].depth_minus1; if (c->srcBpc < 8) @@ -1399,9 +1431,9 @@ av_cold int sws_init_context(SwsContext *c, SwsFilter *srcFilter, /* Allocate pixbufs (we use dynamic allocation because otherwise we would * need to allocate several megabytes to handle all possible cases) */ - FF_ALLOC_OR_GOTO(c, c->lumPixBuf, c->vLumBufSize * 3 * sizeof(int16_t *), fail); - FF_ALLOC_OR_GOTO(c, c->chrUPixBuf, c->vChrBufSize * 3 * sizeof(int16_t *), fail); - FF_ALLOC_OR_GOTO(c, c->chrVPixBuf, c->vChrBufSize * 3 * sizeof(int16_t *), fail); + FF_ALLOCZ_OR_GOTO(c, c->lumPixBuf, c->vLumBufSize * 3 * sizeof(int16_t *), fail); + FF_ALLOCZ_OR_GOTO(c, c->chrUPixBuf, c->vChrBufSize * 3 * sizeof(int16_t *), fail); + FF_ALLOCZ_OR_GOTO(c, c->chrVPixBuf, c->vChrBufSize * 3 * sizeof(int16_t *), fail); if (CONFIG_SWSCALE_ALPHA && isALPHA(c->srcFormat) && isALPHA(c->dstFormat)) FF_ALLOCZ_OR_GOTO(c, c->alpPixBuf, c->vLumBufSize * 3 * sizeof(int16_t *), fail); /* Note we need at least one pixel more at the end because of the MMX code @@ -1510,6 +1542,9 @@ fail: // FIXME replace things by appropriate error codes int tmpH = sqrt(srcH * (int64_t)dstH); enum AVPixelFormat tmpFormat = AV_PIX_FMT_YUV420P; + if (isALPHA(srcFormat)) + tmpFormat = AV_PIX_FMT_YUVA420P; + if (srcW*(int64_t)srcH <= 4LL*dstW*dstH) return AVERROR(EINVAL); diff --git a/libswscale/x86/hscale_fast_bilinear_simd.c b/libswscale/x86/hscale_fast_bilinear_simd.c index 103793d27a..7887b6b651 100644 --- a/libswscale/x86/hscale_fast_bilinear_simd.c +++ b/libswscale/x86/hscale_fast_bilinear_simd.c @@ -277,7 +277,7 @@ void ff_hyscale_fast_mmxext(SwsContext *c, int16_t *dst, ,"m"(retsave) #endif : "%"REG_a, "%"REG_c, "%"REG_d, "%"REG_S, "%"REG_D -#if !defined(PIC) +#if ARCH_X86_64 || !defined(PIC) ,"%"REG_b #endif ); @@ -361,7 +361,7 @@ void ff_hcscale_fast_mmxext(SwsContext *c, int16_t *dst1, int16_t *dst2, ,"m"(retsave) #endif : "%"REG_a, "%"REG_c, "%"REG_d, "%"REG_S, "%"REG_D -#if !defined(PIC) +#if ARCH_X86_64 || !defined(PIC) ,"%"REG_b #endif ); diff --git a/libswscale/x86/output.asm b/libswscale/x86/output.asm index 9ea4af9535..133817cb71 100644 --- a/libswscale/x86/output.asm +++ b/libswscale/x86/output.asm @@ -54,6 +54,118 @@ SECTION .text ; int32_t if $output_size is 16. $filter is 12-bits. $filterSize is a multiple ; of 2. $offset is either 0 or 3. $dither holds 8 values. ;----------------------------------------------------------------------------- +%macro yuv2planeX_mainloop 2 +.pixelloop_%2: +%assign %%i 0 + ; the rep here is for the 8bit output mmx case, where dither covers + ; 8 pixels but we can only handle 2 pixels per register, and thus 4 + ; pixels per iteration. In order to not have to keep track of where + ; we are w.r.t. dithering, we unroll the mmx/8bit loop x2. +%if %1 == 8 +%assign %%repcnt 16/mmsize +%else +%assign %%repcnt 1 +%endif + +%rep %%repcnt + +%if %1 == 8 +%if ARCH_X86_32 + mova m2, [rsp+mmsize*(0+%%i)] + mova m1, [rsp+mmsize*(1+%%i)] +%else ; x86-64 + mova m2, m8 + mova m1, m_dith +%endif ; x86-32/64 +%else ; %1 == 9/10/16 + mova m1, [yuv2yuvX_%1_start] + mova m2, m1 +%endif ; %1 == 8/9/10/16 + movsx cntr_reg, fltsizem +.filterloop_%2_ %+ %%i: + ; input pixels + mov r6, [srcq+gprsize*cntr_reg-2*gprsize] +%if %1 == 16 + mova m3, [r6+r5*4] + mova m5, [r6+r5*4+mmsize] +%else ; %1 == 8/9/10 + mova m3, [r6+r5*2] +%endif ; %1 == 8/9/10/16 + mov r6, [srcq+gprsize*cntr_reg-gprsize] +%if %1 == 16 + mova m4, [r6+r5*4] + mova m6, [r6+r5*4+mmsize] +%else ; %1 == 8/9/10 + mova m4, [r6+r5*2] +%endif ; %1 == 8/9/10/16 + + ; coefficients + movd m0, [filterq+2*cntr_reg-4] ; coeff[0], coeff[1] +%if %1 == 16 + pshuflw m7, m0, 0 ; coeff[0] + pshuflw m0, m0, 0x55 ; coeff[1] + pmovsxwd m7, m7 ; word -> dword + pmovsxwd m0, m0 ; word -> dword + + pmulld m3, m7 + pmulld m5, m7 + pmulld m4, m0 + pmulld m6, m0 + + paddd m2, m3 + paddd m1, m5 + paddd m2, m4 + paddd m1, m6 +%else ; %1 == 10/9/8 + punpcklwd m5, m3, m4 + punpckhwd m3, m4 + SPLATD m0 + + pmaddwd m5, m0 + pmaddwd m3, m0 + + paddd m2, m5 + paddd m1, m3 +%endif ; %1 == 8/9/10/16 + + sub cntr_reg, 2 + jg .filterloop_%2_ %+ %%i + +%if %1 == 16 + psrad m2, 31 - %1 + psrad m1, 31 - %1 +%else ; %1 == 10/9/8 + psrad m2, 27 - %1 + psrad m1, 27 - %1 +%endif ; %1 == 8/9/10/16 + +%if %1 == 8 + packssdw m2, m1 + packuswb m2, m2 + movh [dstq+r5*1], m2 +%else ; %1 == 9/10/16 +%if %1 == 16 + packssdw m2, m1 + paddw m2, [minshort] +%else ; %1 == 9/10 +%if cpuflag(sse4) + packusdw m2, m1 +%else ; mmxext/sse2 + packssdw m2, m1 + pmaxsw m2, m6 +%endif ; mmxext/sse2/sse4/avx + pminsw m2, [yuv2yuvX_%1_upper] +%endif ; %1 == 9/10/16 + mov%2 [dstq+r5*2], m2 +%endif ; %1 == 8/9/10/16 + + add r5, mmsize/2 + sub wd, mmsize/2 + +%assign %%i %%i+2 +%endrep + jg .pixelloop_%2 +%endmacro %macro yuv2planeX_fn 3 @@ -123,116 +235,16 @@ cglobal yuv2planeX_%1, %3, 8, %2, filter, fltsize, src, dst, w, dither, offset xor r5, r5 -.pixelloop: -%assign %%i 0 - ; the rep here is for the 8bit output mmx case, where dither covers - ; 8 pixels but we can only handle 2 pixels per register, and thus 4 - ; pixels per iteration. In order to not have to keep track of where - ; we are w.r.t. dithering, we unroll the mmx/8bit loop x2. -%if %1 == 8 -%assign %%repcnt 16/mmsize -%else -%assign %%repcnt 1 -%endif - -%rep %%repcnt - -%if %1 == 8 -%if ARCH_X86_32 - mova m2, [rsp+mmsize*(0+%%i)] - mova m1, [rsp+mmsize*(1+%%i)] -%else ; x86-64 - mova m2, m8 - mova m1, m_dith -%endif ; x86-32/64 -%else ; %1 == 9/10/16 - mova m1, [yuv2yuvX_%1_start] - mova m2, m1 -%endif ; %1 == 8/9/10/16 - movsx cntr_reg, fltsizem -.filterloop_ %+ %%i: - ; input pixels - mov r6, [srcq+gprsize*cntr_reg-2*gprsize] -%if %1 == 16 - mova m3, [r6+r5*4] - mova m5, [r6+r5*4+mmsize] -%else ; %1 == 8/9/10 - mova m3, [r6+r5*2] -%endif ; %1 == 8/9/10/16 - mov r6, [srcq+gprsize*cntr_reg-gprsize] -%if %1 == 16 - mova m4, [r6+r5*4] - mova m6, [r6+r5*4+mmsize] -%else ; %1 == 8/9/10 - mova m4, [r6+r5*2] -%endif ; %1 == 8/9/10/16 - - ; coefficients - movd m0, [filterq+2*cntr_reg-4] ; coeff[0], coeff[1] -%if %1 == 16 - pshuflw m7, m0, 0 ; coeff[0] - pshuflw m0, m0, 0x55 ; coeff[1] - pmovsxwd m7, m7 ; word -> dword - pmovsxwd m0, m0 ; word -> dword - - pmulld m3, m7 - pmulld m5, m7 - pmulld m4, m0 - pmulld m6, m0 - - paddd m2, m3 - paddd m1, m5 - paddd m2, m4 - paddd m1, m6 -%else ; %1 == 10/9/8 - punpcklwd m5, m3, m4 - punpckhwd m3, m4 - SPLATD m0 - - pmaddwd m5, m0 - pmaddwd m3, m0 - - paddd m2, m5 - paddd m1, m3 -%endif ; %1 == 8/9/10/16 - - sub cntr_reg, 2 - jg .filterloop_ %+ %%i - -%if %1 == 16 - psrad m2, 31 - %1 - psrad m1, 31 - %1 -%else ; %1 == 10/9/8 - psrad m2, 27 - %1 - psrad m1, 27 - %1 -%endif ; %1 == 8/9/10/16 - -%if %1 == 8 - packssdw m2, m1 - packuswb m2, m2 - movh [dstq+r5*1], m2 -%else ; %1 == 9/10/16 -%if %1 == 16 - packssdw m2, m1 - paddw m2, [minshort] -%else ; %1 == 9/10 -%if cpuflag(sse4) - packusdw m2, m1 -%else ; mmxext/sse2 - packssdw m2, m1 - pmaxsw m2, m6 -%endif ; mmxext/sse2/sse4/avx - pminsw m2, [yuv2yuvX_%1_upper] -%endif ; %1 == 9/10/16 - mova [dstq+r5*2], m2 -%endif ; %1 == 8/9/10/16 - - add r5, mmsize/2 - sub wd, mmsize/2 - -%assign %%i %%i+2 -%endrep - jg .pixelloop +%if mmsize == 8 || %1 == 8 + yuv2planeX_mainloop %1, a +%else ; mmsize == 16 + test dstq, 15 + jnz .unaligned + yuv2planeX_mainloop %1, a + REP_RET +.unaligned: + yuv2planeX_mainloop %1, u +%endif ; mmsize == 8/16 %if %1 == 8 %if ARCH_X86_32 diff --git a/libswscale/x86/rgb2rgb_template.c b/libswscale/x86/rgb2rgb_template.c index e71c7ebfe3..73af74e6aa 100644 --- a/libswscale/x86/rgb2rgb_template.c +++ b/libswscale/x86/rgb2rgb_template.c @@ -1090,7 +1090,7 @@ static inline void RENAME(shuffle_bytes_2103)(const uint8_t *src, uint8_t *dst, : "r" (s), "r" (d), "m" (mask32b), "m" (mask32r), "m" (mmx_one) : "memory"); for (; idx<15; idx+=4) { - register int v = *(const uint32_t *)&s[idx], g = v & 0xff00ff00; + register unsigned v = *(const uint32_t *)&s[idx], g = v & 0xff00ff00; v &= 0xff00ff; *(uint32_t *)&d[idx] = (v>>16) + g + (v<<16); } @@ -1434,7 +1434,9 @@ static inline void RENAME(planar2x)(const uint8_t *src, uint8_t *dst, int srcWid dst+= dstStride; for (y=1; y> 2; + dst[dstStride] = (src[0] + 3 * src[srcStride]) >> 2; + } for (x=mmxSize-1; x>2; @@ -1887,8 +1894,9 @@ static void RENAME(interleaveBytes)(const uint8_t *src1, const uint8_t *src2, ui for (h=0; h < height; h++) { int w; - if (width >= 16) + if (width >= 16) { #if COMPILE_TEMPLATE_SSE2 + if (!((((intptr_t)src1) | ((intptr_t)src2) | ((intptr_t)dest))&15)) { __asm__( "xor %%"REG_a", %%"REG_a" \n\t" "1: \n\t" @@ -1905,9 +1913,10 @@ static void RENAME(interleaveBytes)(const uint8_t *src1, const uint8_t *src2, ui "cmp %3, %%"REG_a" \n\t" " jb 1b \n\t" ::"r"(dest), "r"(src1), "r"(src2), "r" ((x86_reg)width-15) - : "memory", "%"REG_a"" + : "memory", XMM_CLOBBERS("xmm0", "xmm1", "xmm2",) "%"REG_a ); -#else + } else +#endif __asm__( "xor %%"REG_a", %%"REG_a" \n\t" "1: \n\t" @@ -1933,7 +1942,8 @@ static void RENAME(interleaveBytes)(const uint8_t *src1, const uint8_t *src2, ui ::"r"(dest), "r"(src1), "r"(src2), "r" ((x86_reg)width-15) : "memory", "%"REG_a ); -#endif + + } for (w= (width&(~15)); w < width; w++) { dest[2*w+0] = src1[w]; dest[2*w+1] = src2[w]; diff --git a/libswscale/yuv2rgb.c b/libswscale/yuv2rgb.c index 8e92e6da3e..86de94cfe7 100644 --- a/libswscale/yuv2rgb.c +++ b/libswscale/yuv2rgb.c @@ -720,7 +720,8 @@ av_cold int ff_yuv2rgb_c_init_tables(SwsContext *c, const int inv_table[4], uint16_t *y_table16; uint32_t *y_table32; int i, base, rbase, gbase, bbase, av_uninit(abase), needAlpha; - const int yoffs = fullRange ? 384 : 326; + const int yoffs = (fullRange ? 384 : 326) + YUVRGB_TABLE_LUMA_HEADROOM; + const int table_plane_size = 1024 + 2*YUVRGB_TABLE_LUMA_HEADROOM; int64_t crv = inv_table[0]; int64_t cbu = inv_table[1]; @@ -771,12 +772,16 @@ 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(table_plane_size); y_table = c->yuvTable; - yb = -(384 << 16) - oy; - for (i = 0; i < 1024 - 110; i++) { + yb = -(384 << 16) - YUVRGB_TABLE_LUMA_HEADROOM*cy - oy; + for (i = 0; i < table_plane_size - 110; i++) { y_table[i + 110] = av_clip_uint8((yb + 0x8000) >> 16) >> 7; yb += cy; } @@ -788,60 +793,60 @@ 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(table_plane_size * 3); y_table = c->yuvTable; - yb = -(384 << 16) - oy; - for (i = 0; i < 1024 - 110; i++) { + yb = -(384 << 16) - YUVRGB_TABLE_LUMA_HEADROOM*cy - oy; + for (i = 0; i < table_plane_size - 110; i++) { int yval = av_clip_uint8((yb + 0x8000) >> 16); y_table[i + 110] = (yval >> 7) << rbase; - y_table[i + 37 + 1024] = ((yval + 43) / 85) << gbase; - y_table[i + 110 + 2048] = (yval >> 7) << bbase; + y_table[i + 37 + table_plane_size] = ((yval + 43) / 85) << gbase; + y_table[i + 110 + 2*table_plane_size] = (yval >> 7) << bbase; yb += cy; } fill_table(c->table_rV, 1, crv, y_table + yoffs); - fill_table(c->table_gU, 1, cgu, y_table + yoffs + 1024); - fill_table(c->table_bU, 1, cbu, y_table + yoffs + 2048); + fill_table(c->table_gU, 1, cgu, y_table + yoffs + table_plane_size); + fill_table(c->table_bU, 1, cbu, y_table + yoffs + 2*table_plane_size); fill_gv_table(c->table_gV, 1, cgv); break; case 8: rbase = isRgb ? 5 : 0; gbase = isRgb ? 2 : 3; bbase = isRgb ? 0 : 6; - c->yuvTable = av_malloc(1024 * 3); + ALLOC_YUV_TABLE(table_plane_size * 3); y_table = c->yuvTable; - yb = -(384 << 16) - oy; - for (i = 0; i < 1024 - 38; i++) { + yb = -(384 << 16) - YUVRGB_TABLE_LUMA_HEADROOM*cy - oy; + for (i = 0; i < table_plane_size - 38; i++) { int yval = av_clip_uint8((yb + 0x8000) >> 16); y_table[i + 16] = ((yval + 18) / 36) << rbase; - y_table[i + 16 + 1024] = ((yval + 18) / 36) << gbase; - y_table[i + 37 + 2048] = ((yval + 43) / 85) << bbase; + y_table[i + 16 + table_plane_size] = ((yval + 18) / 36) << gbase; + y_table[i + 37 + 2*table_plane_size] = ((yval + 43) / 85) << bbase; yb += cy; } fill_table(c->table_rV, 1, crv, y_table + yoffs); - fill_table(c->table_gU, 1, cgu, y_table + yoffs + 1024); - fill_table(c->table_bU, 1, cbu, y_table + yoffs + 2048); + fill_table(c->table_gU, 1, cgu, y_table + yoffs + table_plane_size); + fill_table(c->table_bU, 1, cbu, y_table + yoffs + 2*table_plane_size); fill_gv_table(c->table_gV, 1, cgv); break; case 12: rbase = isRgb ? 8 : 0; gbase = 4; bbase = isRgb ? 0 : 8; - c->yuvTable = av_malloc(1024 * 3 * 2); + ALLOC_YUV_TABLE(table_plane_size * 3 * 2); y_table16 = c->yuvTable; - yb = -(384 << 16) - oy; - for (i = 0; i < 1024; i++) { + yb = -(384 << 16) - YUVRGB_TABLE_LUMA_HEADROOM*cy - oy; + for (i = 0; i < table_plane_size; i++) { uint8_t yval = av_clip_uint8((yb + 0x8000) >> 16); y_table16[i] = (yval >> 4) << rbase; - y_table16[i + 1024] = (yval >> 4) << gbase; - y_table16[i + 2048] = (yval >> 4) << bbase; + y_table16[i + table_plane_size] = (yval >> 4) << gbase; + y_table16[i + 2*table_plane_size] = (yval >> 4) << bbase; yb += cy; } if (isNotNe) - for (i = 0; i < 1024 * 3; i++) + for (i = 0; i < table_plane_size * 3; i++) y_table16[i] = av_bswap16(y_table16[i]); fill_table(c->table_rV, 2, crv, y_table16 + yoffs); - fill_table(c->table_gU, 2, cgu, y_table16 + yoffs + 1024); - fill_table(c->table_bU, 2, cbu, y_table16 + yoffs + 2048); + fill_table(c->table_gU, 2, cgu, y_table16 + yoffs + table_plane_size); + fill_table(c->table_bU, 2, cbu, y_table16 + yoffs + 2*table_plane_size); fill_gv_table(c->table_gV, 2, cgv); break; case 15: @@ -849,30 +854,30 @@ 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(table_plane_size * 3 * 2); y_table16 = c->yuvTable; - yb = -(384 << 16) - oy; - for (i = 0; i < 1024; i++) { + yb = -(384 << 16) - YUVRGB_TABLE_LUMA_HEADROOM*cy - oy; + for (i = 0; i < table_plane_size; i++) { uint8_t yval = av_clip_uint8((yb + 0x8000) >> 16); y_table16[i] = (yval >> 3) << rbase; - y_table16[i + 1024] = (yval >> (18 - bpp)) << gbase; - y_table16[i + 2048] = (yval >> 3) << bbase; + y_table16[i + table_plane_size] = (yval >> (18 - bpp)) << gbase; + y_table16[i + 2*table_plane_size] = (yval >> 3) << bbase; yb += cy; } if (isNotNe) - for (i = 0; i < 1024 * 3; i++) + for (i = 0; i < table_plane_size * 3; i++) y_table16[i] = av_bswap16(y_table16[i]); fill_table(c->table_rV, 2, crv, y_table16 + yoffs); - fill_table(c->table_gU, 2, cgu, y_table16 + yoffs + 1024); - fill_table(c->table_bU, 2, cbu, y_table16 + yoffs + 2048); + fill_table(c->table_gU, 2, cgu, y_table16 + yoffs + table_plane_size); + fill_table(c->table_bU, 2, cbu, y_table16 + yoffs + 2*table_plane_size); fill_gv_table(c->table_gV, 2, cgv); break; case 24: case 48: - c->yuvTable = av_malloc(1024); + ALLOC_YUV_TABLE(table_plane_size); y_table = c->yuvTable; - yb = -(384 << 16) - oy; - for (i = 0; i < 1024; i++) { + yb = -(384 << 16) - YUVRGB_TABLE_LUMA_HEADROOM*cy - oy; + for (i = 0; i < table_plane_size; i++) { y_table[i] = av_clip_uint8((yb + 0x8000) >> 16); yb += cy; } @@ -891,20 +896,20 @@ 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(table_plane_size * 3 * 4); y_table32 = c->yuvTable; - yb = -(384 << 16) - oy; - for (i = 0; i < 1024; i++) { + yb = -(384 << 16) - YUVRGB_TABLE_LUMA_HEADROOM*cy - oy; + for (i = 0; i < table_plane_size; i++) { unsigned yval = av_clip_uint8((yb + 0x8000) >> 16); y_table32[i] = (yval << rbase) + (needAlpha ? 0 : (255u << abase)); - y_table32[i + 1024] = yval << gbase; - y_table32[i + 2048] = yval << bbase; + y_table32[i + table_plane_size] = yval << gbase; + y_table32[i + 2*table_plane_size] = yval << bbase; yb += cy; } fill_table(c->table_rV, 4, crv, y_table32 + yoffs); - fill_table(c->table_gU, 4, cgu, y_table32 + yoffs + 1024); - fill_table(c->table_bU, 4, cbu, y_table32 + yoffs + 2048); + fill_table(c->table_gU, 4, cgu, y_table32 + yoffs + table_plane_size); + fill_table(c->table_bU, 4, cbu, y_table32 + yoffs + 2*table_plane_size); fill_gv_table(c->table_gV, 4, cgv); break; default: diff --git a/tests/fate-run.sh b/tests/fate-run.sh index f78e4fcfd5..ed36a68440 100755 --- a/tests/fate-run.sh +++ b/tests/fate-run.sh @@ -38,11 +38,11 @@ target_path(){ # $1=value1, $2=value2, $3=threshold # prints 0 if absolute difference between value1 and value2 is <= threshold compare(){ - echo "scale=2; v = $1 - $2; if (v < 0) v = -v; if (v > $3) r = 1; r" | bc + awk "BEGIN { v = $1 - $2; printf ((v < 0 ? -v : v) > $3) }" } 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]*\)') diff --git a/tests/fate.sh b/tests/fate.sh index 5a78018b42..b55d87efc0 100755 --- a/tests/fate.sh +++ b/tests/fate.sh @@ -83,8 +83,7 @@ clean(){ report(){ date=$(date -u +%Y%m%d%H%M%S) - echo "fate:0:${date}:${slot}:${version}:$1:$2:${comment}" >report -# echo "fate:1:${date}:${slot}:${version}:$1:$2:${branch}:${comment}" >report + echo "fate:1:${date}:${slot}:${version}:$1:$2:${branch}:${comment}" >report cat ${build}/config.fate >>report cat ${build}/tests/data/fate/*.rep >>report || for i in ${build}/tests/data/fate/*.rep ; do cat "$i" >>report ; done test -n "$fate_recv" && $tar report *.log | gzip | $fate_recv diff --git a/tests/fate/acodec.mak b/tests/fate/acodec.mak index 325bbd9e32..37fc688730 100644 --- a/tests/fate/acodec.mak +++ b/tests/fate/acodec.mak @@ -103,7 +103,7 @@ fate-acodec-dca: tests/data/asynth-44100-2.wav fate-acodec-dca: SRC = tests/data/asynth-44100-2.wav fate-acodec-dca: CMD = md5 -i $(TARGET_PATH)/$(SRC) -c:a dca -strict -2 -f dts -flags +bitexact fate-acodec-dca: CMP = oneline -fate-acodec-dca: REF = fe28cef432ed88de4ee01b87537fd2bd +fate-acodec-dca: REF = c54ca9a13711755ef90fa143a9b38386 FATE_ACODEC-$(call ENCDEC, DCA, WAV) += fate-acodec-dca2 fate-acodec-dca2: CMD = enc_dec_pcm dts wav s16le $(SRC) -c:a dca -strict -2 -flags +bitexact diff --git a/tests/ref/fate/filter-framepack-frameseq b/tests/ref/fate/filter-framepack-frameseq index c3d2a15e8e..83c08a0324 100644 --- a/tests/ref/fate/filter-framepack-frameseq +++ b/tests/ref/fate/filter-framepack-frameseq @@ -1,16 +1,16 @@ -#tb 0: 1/25 +#tb 0: 1/50 0, 0, 0, 1, 152064, 0x05b789ef 0, 1, 1, 1, 152064, 0x05b789ef 0, 2, 2, 1, 152064, 0x4bb46551 -0, 3, 3, 1, 152064, 0x9dddf64a -0, 4, 4, 1, 152064, 0x2a8380b0 -0, 5, 5, 1, 152064, 0x4de3b652 -0, 6, 6, 1, 152064, 0xedb5a8e6 -0, 7, 7, 1, 152064, 0xe20f7c23 -0, 8, 8, 1, 152064, 0x5ab58bac -0, 9, 9, 1, 152064, 0x1f1b8026 -0, 10, 10, 1, 152064, 0x91373915 -0, 11, 11, 1, 152064, 0x02344760 -0, 12, 12, 1, 152064, 0x30f5fcd5 -0, 13, 13, 1, 152064, 0xc711ad61 -0, 14, 14, 1, 152064, 0x24eca223 +0, 3, 3, 1, 152064, 0x4bb46551 +0, 4, 4, 1, 152064, 0x9dddf64a +0, 5, 5, 1, 152064, 0x9dddf64a +0, 6, 6, 1, 152064, 0x2a8380b0 +0, 7, 7, 1, 152064, 0x2a8380b0 +0, 8, 8, 1, 152064, 0x4de3b652 +0, 9, 9, 1, 152064, 0x4de3b652 +0, 10, 10, 1, 152064, 0xedb5a8e6 +0, 11, 11, 1, 152064, 0xedb5a8e6 +0, 12, 12, 1, 152064, 0xe20f7c23 +0, 13, 13, 1, 152064, 0xe20f7c23 +0, 14, 14, 1, 152064, 0x5ab58bac diff --git a/tests/ref/fate/gifenc-bgr8 b/tests/ref/fate/gifenc-bgr8 index 9f4a593f4d..f3b7772785 100644 --- a/tests/ref/fate/gifenc-bgr8 +++ b/tests/ref/fate/gifenc-bgr8 @@ -35,15 +35,15 @@ 0, 33, 33, 1, 4295, 0xf71b0b38, S=1, 1024, 0xf351799f 0, 34, 34, 1, 2044, 0x5adcb93b, S=1, 1024, 0xf351799f 0, 35, 35, 1, 3212, 0xcf79eeed, S=1, 1024, 0xf351799f -0, 36, 36, 1, 2281, 0x68464d30, S=1, 1024, 0xf351799f +0, 36, 36, 1, 2292, 0xb4386334, S=1, 1024, 0xf351799f 0, 37, 37, 1, 3633, 0x0010992f, S=1, 1024, 0xf351799f 0, 38, 38, 1, 3552, 0x23697490, S=1, 1024, 0xf351799f 0, 39, 39, 1, 3690, 0x62afdbb8, S=1, 1024, 0xf351799f -0, 40, 40, 1, 1558, 0x7a13e53b, S=1, 1024, 0xf351799f -0, 41, 41, 1, 940, 0xb1b6cba2, S=1, 1024, 0xf351799f +0, 40, 40, 1, 1559, 0x5baef54a, S=1, 1024, 0xf351799f +0, 41, 41, 1, 954, 0xca75ca79, S=1, 1024, 0xf351799f 0, 42, 42, 1, 273, 0x3687799b, S=1, 1024, 0xf351799f 0, 43, 43, 1, 930, 0x29f3b0c4, S=1, 1024, 0xf351799f -0, 44, 44, 1, 271, 0xe7af807c, S=1, 1024, 0xf351799f +0, 44, 44, 1, 271, 0x305e8094, S=1, 1024, 0xf351799f 0, 45, 45, 1, 196, 0xf5ab51ee, S=1, 1024, 0xf351799f 0, 46, 46, 1, 4299, 0x67ec0d55, S=1, 1024, 0xf351799f 0, 47, 47, 1, 4895, 0xb394406c, S=1, 1024, 0xf351799f @@ -56,7 +56,7 @@ 0, 54, 54, 1, 5179, 0x860fc6a1, S=1, 1024, 0xf351799f 0, 55, 55, 1, 5046, 0xce9183d3, S=1, 1024, 0xf351799f 0, 56, 56, 1, 5140, 0xa6d7b9af, S=1, 1024, 0xf351799f -0, 57, 57, 1, 4289, 0xb415f717, S=1, 1024, 0xf351799f +0, 57, 57, 1, 4301, 0x03b6ef3f, S=1, 1024, 0xf351799f 0, 58, 58, 1, 5079, 0xa8d59e01, S=1, 1024, 0xf351799f 0, 59, 59, 1, 5284, 0xea34e3b3, S=1, 1024, 0xf351799f 0, 60, 60, 1, 5426, 0x556a15cd, S=1, 1024, 0xf351799f diff --git a/tests/ref/fate/gifenc-rgb8 b/tests/ref/fate/gifenc-rgb8 index a894173225..d1a990d07e 100644 --- a/tests/ref/fate/gifenc-rgb8 +++ b/tests/ref/fate/gifenc-rgb8 @@ -35,15 +35,15 @@ 0, 33, 33, 1, 4295, 0xc1850a80, S=1, 1024, 0xcfc8799f 0, 34, 34, 1, 2044, 0x0440c072, S=1, 1024, 0xcfc8799f 0, 35, 35, 1, 3212, 0xe91af08f, S=1, 1024, 0xcfc8799f -0, 36, 36, 1, 2281, 0x6a414aa1, S=1, 1024, 0xcfc8799f +0, 36, 36, 1, 2292, 0x6765633e, S=1, 1024, 0xcfc8799f 0, 37, 37, 1, 3633, 0xac779aa3, S=1, 1024, 0xcfc8799f 0, 38, 38, 1, 3552, 0xed2c75b2, S=1, 1024, 0xcfc8799f 0, 39, 39, 1, 3690, 0x2020dd0d, S=1, 1024, 0xcfc8799f -0, 40, 40, 1, 1558, 0x2c14e4b2, S=1, 1024, 0xcfc8799f -0, 41, 41, 1, 940, 0x4927cd90, S=1, 1024, 0xcfc8799f +0, 40, 40, 1, 1559, 0x596ef330, S=1, 1024, 0xcfc8799f +0, 41, 41, 1, 954, 0xac12c9c5, S=1, 1024, 0xcfc8799f 0, 42, 42, 1, 273, 0x138c7831, S=1, 1024, 0xcfc8799f 0, 43, 43, 1, 930, 0xf1c3ae3f, S=1, 1024, 0xcfc8799f -0, 44, 44, 1, 271, 0x6d338044, S=1, 1024, 0xcfc8799f +0, 44, 44, 1, 271, 0x921a80af, S=1, 1024, 0xcfc8799f 0, 45, 45, 1, 196, 0xa5de5322, S=1, 1024, 0xcfc8799f 0, 46, 46, 1, 4299, 0x5bac0d86, S=1, 1024, 0xcfc8799f 0, 47, 47, 1, 4895, 0xc43639a6, S=1, 1024, 0xcfc8799f @@ -56,7 +56,7 @@ 0, 54, 54, 1, 5179, 0x97aac3a1, S=1, 1024, 0xcfc8799f 0, 55, 55, 1, 5046, 0x836a80cd, S=1, 1024, 0xcfc8799f 0, 56, 56, 1, 5140, 0xa725c1e7, S=1, 1024, 0xcfc8799f -0, 57, 57, 1, 4289, 0x7b3afbc0, S=1, 1024, 0xcfc8799f +0, 57, 57, 1, 4301, 0x0203f239, S=1, 1024, 0xcfc8799f 0, 58, 58, 1, 5079, 0xb2e7a2de, S=1, 1024, 0xcfc8799f 0, 59, 59, 1, 5284, 0xb757dfe1, S=1, 1024, 0xcfc8799f 0, 60, 60, 1, 5426, 0xf9f11e57, S=1, 1024, 0xcfc8799f diff --git a/tools/graph2dot.c b/tools/graph2dot.c index 964322d080..868c62f0d8 100644 --- a/tools/graph2dot.c +++ b/tools/graph2dot.c @@ -153,7 +153,7 @@ int main(int argc, char **argv) /* read from infile and put it in a buffer */ { - unsigned int count = 0; + int64_t count = 0; struct line *line, *last_line, *first_line; char *p; last_line = first_line = av_malloc(sizeof(struct line)); @@ -169,7 +169,7 @@ int main(int argc, char **argv) graph_string = av_malloc(count + 1); p = graph_string; for (line = first_line; line->next; line = line->next) { - unsigned int l = strlen(line->data); + size_t l = strlen(line->data); memcpy(p, line->data, l); p += l; }