diff --git a/Changelog b/Changelog index 4518c217fd..7c8d914f96 100644 --- a/Changelog +++ b/Changelog @@ -1,6 +1,511 @@ Entries are sorted chronologically from oldest to youngest within each release, releases are sorted from youngest to oldest. +version 2.6.9: +- avcodec/mjpegdec: Do not try to detect last scan but apply idct after all scans for progressive jpeg +- avformat/options_table: Add missing identifier for very strict compliance +- avformat/ffmdec: Check pix_fmt +- avcodec/ttaenc: Reallocate packet if its too small +- pgssubdec: fix subpicture output colorspace and range +- avcodec/ac3dec: Reset SPX when switching from EAC3 to AC3 +- avfilter/vf_drawtext: Check return code of load_glyph() +- avcodec/takdec: add code that got somehow lost in process of REing +- avcodec/apedec: fix decoding of stereo files with one channel full of silence +- avcodec/avpacket: Fix off by 5 error +- avcodec/h264: Fix for H.264 configuration parsing +- avcodec/bmp_parser: Ensure remaining_size is not too small in startcode packet crossing corner case +- avfilter/src_movie: fix how we check for overflows with seek_point +- avcodec/j2kenc: Add attribution to OpenJPEG project: +- avcodec/libutvideodec: copy frame so it has reference counters when refcounted_frames is set +- avformat/rtpdec_jpeg: fix low contrast image on low quality setting +- avcodec/mjpegenc_common: Store approximate aspect if exact cannot be stored +- avcodec/resample: Remove disabled and faulty code +- indeo2: Fix banding artefacts +- indeo2data: K&R formatting cosmetics +- avcodec/imgconvert: Support non-planar colorspaces while padding +- avutil/random_seed: Add the runtime in cycles of the main loop to the entropy pool +- avutil/channel_layout: AV_CH_LAYOUT_6POINT1_BACK not reachable in parsing +- avformat/concatdec: set safe mode to enabled instead of auto +- avformat/rtpenc: Fix integer overflow in NTP_TO_RTP_FORMAT +- avformat/cache: Fix memleak of tree entries +- lavf/mov: fix sidx with edit lists (cherry picked from commit 3617e69d50dd9dd07b5011dfb9477a9d1a630354) +- avcodec/mjpegdec: Fix decoding slightly odd progressive jpeg +- avcodec/avpacket: clear priv in av_init_packet() +- swscale/utils: Fix chrSrcHSubSample for GBRAP16 +- swscale/input: Fix GBRAP16 input +- postproc: fix unaligned access +- avutil/pixdesc: Make get_color_type() aware of CIE XYZ formats +- swscale/x86/output: Fix yuv2planeX_16* with unaligned destination +- swscale/x86/output: Move code into yuv2planeX_mainloop +- doc/utils: fix typo for min() description + + +version 2.6.8: +- 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 + +version 2.6.7: +- 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 +- x86/float_dsp: zero extend offset from ff_scalarproduct_float_sse + + +version 2.6.6: +- 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 +- avcodec/mpeg4videodec: also for empty partitioned slices +- 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 +- 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: 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() +- 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/h264_slice: Limit max_contexts when slice_context_count is initialized +- avcodec/vp8: Do not use num_coeff_partitions in thread/buffer setup +- avcodec/mpeg4videodec: Check available data before reading custom matrix +- mjpegdec: consider chroma subsampling in size check +- avcodec/dirac_parser: Check that there is a previous PU before accessing it +- 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 +- golomb: always check for invalid UE golomb codes in get_ue_golomb +- 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 +- 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 +- mxfdec: check edit_rate also for physical_track +- mpegvideo: clear overread in clear_context +- dvdsubdec: validate offset2 similar to offset1 +- aacdec: don't return frames without data from aac_decode_er_frame +- avcodec/takdec: Use memove, avoid undefined memcpy() use +- riffdec: prevent negative bit rate +- Merge commit 'd80811c94e068085aab797f9ba35790529126f85' +- 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. + + +version 2.6.5: +- 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 +- doc/ffmpeg: Clarify that the sdp_file option requires an rtp output. +- ffmpeg: Don't try and write sdp info if none of the outputs had an rtp format. +- jvdec: avoid unsigned overflow in comparison +- avcodec/jpeg2000dec: Clip all tile coordinates +- avcodec/hevc_ps: Check chroma_format_idc +- 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 +- avcodec/mpeg12dec: Do not call show_bits() with invalid bits +- 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 +- avcodec/vp3: 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() +- rawdec: fix mjpeg probing buffer size check +- rawdec: fix mjpeg probing +- videodsp: don't overread edges in vfix3 emu_edge. +- lavf/matroskadec: Fully parse and repack MP3 packets +- 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.6.4: +- imc: use correct position for flcoeffs2 calculation +- hevc: check slice address length +- snow: remove an obsolete av_assert2 +- webp: fix infinite loop in webp_decode_frame +- wavpack: limit extra_bits to 32 and use get_bits_long +- ffmpeg: only count got_output/errors in decode_error_stat +- ffmpeg: exit_on_error if decoding a packet failed +- pthread_frame: forward error codes when flushing +- huffyuvdec: validate image size +- wavpack: use get_bits_long to read up to 32 bits +- nutdec: check maxpos in read_sm_data before returning success +- vc1dec: use get_bits_long and limit the read bits to 32 +- mpegaudiodec: copy AVFloatDSPContext from first context to all contexts +- 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() +- ffmpeg: Fix cleanup after failed allocation of output_files +- 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 +- examples/demuxing_decoding: use properties from frame instead of video_dec_ctx +- 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 +- avfilter/x86/vf_fspp: Fix invalid combination of opcode and operands +- 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 +- nutdec: abort if EOF is reached in decode_info_header/read_sm_data +- nutdec: stop skipping bytes at EOF +- nutdec: fix infinite resync loops +- avformat/nutdec: Check X in 2nd branch of index reading +- avformat/nutdec: Fix recovery when immedeately after seeking a failure happens +- avformat/nutdec: Return error on EOF from get_str() +- rtsp: Make sure we don't write too many transport entries into a fixed-size array +- rtpenc_jpeg: handle case of picture dimensions not dividing by 8 +- avcodec/golomb: get_ur_golomb_jpegls: Fix reading huge k values +- avformat/swfdec: Do not error out on pixel format changes +- avformat/mov: Mark avio context of decompressed atoms as seekable +- avcodec/mjpegenc_common: Use ff_mpv_reallocate_putbitbuffer() +- avcodec/mpegvideo: Factor ff_mpv_reallocate_putbitbuffer() out +- avfilter/x86/vf_hqdn3d: Fix register types +- avcodec/exr: fix crash caused by merge +- avcodec/x86/h264_weight: handle weight1=128 +- avcodec/dvbsubdec: Fix buf_size check in dvbsub_parse_display_definition_segment() +- avcodec/hevc_ps: Only discard overread VPS if a previous is available +- avcodec/flacenc: Fix Invalid Rice order +- lavd/xcbgrab: fix comparison with screen size. + +version 2.6.3: +- avcodec/libtheoraenc: Check for av_malloc failure +- ffmpeg_opt: Fix -timestamp parsing +- hevc: make avcodec_decode_video2() fail if get_format() fails +- avcodec/cavsdec: Use ff_set_dimensions() +- swr: fix alignment issue caused by 8ch sse functions +- avcodec/mjpegdec: fix len computation in ff_mjpeg_decode_dqt() +- avcodec/jpeg2000dec: fix boolean operator +- avcodec/hevc_ps: Explicitly check num_tile_* for negative values +- 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 +- avformat/matroskaenc: Check ff_vorbiscomment_length in put_flac_codecpriv() +- avcodec/mpeg12dec: use the correct dimensions for checking SAR +- 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 +- avformat/mov: Do not read ACLR into extradata for H.264 +- ffmpeg: remove incorrect network deinit +- OpenCL: Avoid potential buffer overflow in cmdutils_opencl.c +- libvpxenc: only set noise reduction w/vp8 +- vp9: remove another optimization branch in iadst16 which causes overflows. +- lavf: Reset global flag on deinit +- network: Do not leave context locked on error +- vp9: remove one optimization branch in iadst16 which causes overflows. +- fate: Include branch information in the payload header +- avformat/utils: Ensure that AVFMT_FLAG_CUSTOM_IO is set before use +- avformat/img2dec: do not rewind custom io buffers +- avcodec/alsdec: Use av_mallocz_array() for chan_data to ensure the arrays never contain random data +- avcodec/atrac3plusdsp: fix on stack alignment +- swresample/swresample-test: Randomly wipe out channel counts +- swresample: Check channel layouts and channels against each other and print human readable error messages +- swresample: Allow reinitialization without ever setting channel layouts (cherry picked from commit 80a28c7509a11114e1aea5b208d56c6646d69c07) +- swresample: Allow reinitialization without ever setting channel counts +- dashenc: replace attribute id with contentType for the AdaptationSet element +- avformat/matroskaenc: Use avoid_negative_ts_use_pts if no stream writes dts +- avformat/mux: Add avoid_negative_ts_use_pts +- tests/fate-run: do not attempt to parse tiny_psnrs output if it failed +- cafdec: free extradata before allocating it +- imgutils: initialize palette padding bytes in av_image_alloc +- aacdec: don't return frames without data +- id3v2: catch avio_read errors in check_tag +- avi: Validate sample_size +- 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 +- avformat/matroskadec: Use tracks[k]->stream instead of s->streams[k] +- matroskadec: use uint64_t instead of int for index_scale +- pngdec: don't use AV_PIX_FMT_MONOBLACK for apng +- pngdec: return correct error code from decode_frame_common +- nutdec: fix illegal count check in decode_main_header +- nutdec: fix memleaks on error in nut_read_header +- apedec: prevent out of array writes in decode_array_0000 +- 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() it was wrong +- alac: reject rice_limit 0 if compression is used +- alsdec: only adapt order for positive max_order +- bink: check vst->index_entries before using it +- mpeg4videodec: only allow a positive length +- aacpsy: correct calculation of minath in psy_3gpp_init +- alsdec: validate time diff index +- alsdec: ensure channel reordering is reversible +- 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 +- matroskadec: export cover art correctly +- mxfenc: don't try to write footer without header +- mxfenc: fix memleaks in mxf_write_footer +- rtpenc_mpegts: Set chain->rtp_ctx only after avformat_write_header succeeded +- rtpenc_mpegts: Free the right ->pb in the error path in the init function + +version 2.6.2: +- 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 +- avformat/utils: avoid discarded streams in av_find_default_stream_index() +- ffmpeg: Fix extradata allocation +- 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 +- Revert "avcodec/exr: fix memset first arg in reverse_lut()" +- h264: avoid unnecessary calls to get_format +- avutil/pca: Check for av_malloc* failures +- avutil/cpu: add missing check for mmxext to av_force_cpu_flags +- lavc/dnxhd: Fix pix_fmt change. +- avformat/http: replace cookies with updated values instead of appending forever +- avformat/hls: store cookies returned in HLS key response +- avformat/rmdec: fix support for 0 sized mdpr +- avcodec/msrledec: restructure msrle_decode_pal4() based on the line number instead of the pixel pointer +- avcodec/hevc_ps: Check cropping parameters more correctly +- hevc: make the crop sizes unsigned +- avcodec/dnxhddec: Reset is_444 if format is not 444 +- avcodec/dnxhddec: Check that the frame is interlaced before using cur_field +- mips/float_dsp: fix vector_fmul_window_mips on mips64 +- doc: Remove non-existing decklink options. + +version 2.6.1: +- avformat/mov: Disallow ".." in dref unless use_absolute_path is set +- avfilter/palettegen: make sure at least one frame was sent to the filter +- avformat/mov: Check for string truncation in mov_open_dref() +- ac3_fixed: fix out-of-bound read +- mips/asmdefs: use _ABI64 as defined by gcc +- hevc: delay ff_thread_finish_setup for hwaccel +- avcodec/012v: Check dimensions more completely +- asfenc: fix leaking asf->index_ptr on error +- roqvideoenc: set enc->avctx in roq_encode_init +- avcodec/options_table: remove extradata_size from the AVOptions table +- ffmdec: limit the backward seek to the last resync position +- Add dependencies to configure file for vf_fftfilt +- ffmdec: make sure the time base is valid +- ffmdec: fix infinite loop at EOF +- ffmdec: initialize f_cprv, f_stvi and f_stau +- arm: Suppress tags about used cpu arch and extensions +- 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 +- lavc/hevcdsp: Fix compilation for arm with --disable-neon. +- vp9: fix segmentation map retention with threading enabled. +- Revert "avutil/opencl: is_compiled flag not being cleared in av_opencl_uninit" + version 2.6: - nvenc encoder - 10bit spp filter @@ -35,8 +540,7 @@ version 2.6: - Fix stsd atom corruption in DNxHD QuickTimes - Canopus HQX decoder - RTP depacketization of T.140 text (RFC 4103) -- VP9 RTP payload format (draft 0) experimental depacketizer -- Port MIPS opttimizations to 64-bit +- Port MIPS optimizations to 64-bit version 2.5: diff --git a/MAINTAINERS b/MAINTAINERS index 1f434b06d4..bf2c5b474c 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -14,7 +14,6 @@ patches and related discussions. Project Leader ============== -Michael Niedermayer final design decisions @@ -540,14 +539,14 @@ Windows ICL Matthew Oliver ADI/Blackfin DSP Marc Hoffman Sparc Roman Shaposhnik x86 Michael Niedermayer +OS/2 KO Myung-Hun Releases ======== +2.6 Michael Niedermayer 2.5 Michael Niedermayer -2.4 Michael Niedermayer -2.2 Michael Niedermayer If you want to maintain an older release, please contact us diff --git a/RELEASE b/RELEASE index 5db7a1abc4..d48d3702ae 100644 --- a/RELEASE +++ b/RELEASE @@ -1 +1 @@ -2.5.git +2.6.9 diff --git a/RELEASE_NOTES b/RELEASE_NOTES new file mode 100644 index 0000000000..b0975bafa2 --- /dev/null +++ b/RELEASE_NOTES @@ -0,0 +1,65 @@ + + ┌─────────────────────────────────────────────┐ + │ RELEASE NOTES for FFmpeg 2.6 "Grothendieck" │ + └─────────────────────────────────────────────┘ + + The FFmpeg Project proudly presents FFmpeg 2.6 "Grothendieck", about 3 + months after the release of FFmpeg 2.5. + + A lot of important work got in this time, so let's start talking about what + we like to brag the most about: features. + + A lot of people will probably be happy to hear that we now have support for + NVENC — the Nvidia Video Encoder interface for H.264 encoding — thanks to + Timo Rothenpieler, with some little help from NVIDIA and Philip Langdale. + + People in the broadcasting industry might also be interested in the first + steps of closed captions support with the introduction of a decoder by + Anshul Maheswhwari. + + Regarding filters love, we improved and added many. We could talk about the + 10-bit support in spp, but maybe it's more important to mention the addition + of colorlevels (yet another color handling filter), tblend (allowing you + to for example run a diff between successive frames of a video stream), or + the dcshift audio filter. + + There are also two other important filters landing in libavfilter: palettegen + and paletteuse. Both submitted by the Stupeflix company. These filters will + be very useful in case you are looking for creating high quality GIFs, a + format that still bravely fights annihilation in 2015. + + There are many other new features, but let's follow-up on one big cleanup + achievement: the libmpcodecs (MPlayer filters) wrapper is finally dead. The + last remaining filters (softpulldown/repeatfields, eq*, and various + postprocessing filters) were ported by Arwa Arif (OPW student) and Paul B + Mahol. + + Concerning API changes, there are not many things to mention. Though, the + introduction of device inputs and outputs listing by Lukasz Marek is a + notable addition (try ffmpeg -sources or ffmpeg -sinks for an example of + the usage). As usual, see doc/APIchanges for more information. + + Now let's talk about optimizations. Ronald S. Bultje made the VP9 decoder + usable on x86 32-bit systems and pre-ssse3 CPUs like Phenom (even dual core + Athlons can play 1080p 30fps VP9 content now), so we now secretly hope for + Google and Mozilla to use ffvp9 instead of libvpx. But VP9 is not the + center of attention anymore, and HEVC/H.265 is also getting many + improvements, which include C and x86 ASM optimizations, mainly from James + Almer, Christophe Gisquet and Pierre-Edouard Lepere. + + Even though we had many x86 contributions, it is not the only architecture + getting some love, with Seppo Tomperi adding ARM NEON optimizations to the + HEVC stack, and James Cowgill adding MIPS64 assembly for all kind of audio + processing code in libavcodec. + + And finally, Michael Niedermayer is still fixing many bugs, dealing with + most of the boring work such as making releases, applying tons of + contributors patches, and daily merging the changes from the Libav project. + + A more complete Changelog is available at the root of the project, and the + complete Git history on http://source.ffmpeg.org. + + We hope you will like this release as much as we enjoyed working on it, and + as usual, if you have any questions about it, or any FFmpeg related topic, + feel free to join us on the #ffmpeg IRC channel (on irc.freenode.net) or ask + on the mailing-lists. 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 ce745d21e4..e13b7674cf 100755 --- a/configure +++ b/configure @@ -1769,6 +1769,7 @@ SYSTEM_FUNCS=" TOOLCHAIN_FEATURES=" as_dn_directive as_func + as_object_arch asm_mod_q attribute_may_alias attribute_packed @@ -2595,6 +2596,8 @@ deshake_filter_select="pixelutils" drawtext_filter_deps="libfreetype" ebur128_filter_deps="gpl" eq_filter_deps="gpl" +fftfilt_filter_deps="avcodec" +fftfilt_filter_select="rdft" flite_filter_deps="libflite" frei0r_filter_deps="frei0r dlopen" frei0r_src_filter_deps="frei0r dlopen" @@ -4560,6 +4563,11 @@ EOF check_as < $TMPH <width != width || video_dec_ctx->height != height || - video_dec_ctx->pix_fmt != pix_fmt) { - /* To handle this change, one could call av_image_alloc again and - * decode the following frames into another rawvideo file. */ - fprintf(stderr, "Error: Width, height and pixel format have to be " - "constant in a rawvideo file, but the width, height or " - "pixel format of the input video changed:\n" - "old: width = %d, height = %d, format = %s\n" - "new: width = %d, height = %d, format = %s\n", - width, height, av_get_pix_fmt_name(pix_fmt), - video_dec_ctx->width, video_dec_ctx->height, - av_get_pix_fmt_name(video_dec_ctx->pix_fmt)); - return -1; - } if (*got_frame) { + + if (frame->width != width || frame->height != height || + frame->format != pix_fmt) { + /* To handle this change, one could call av_image_alloc again and + * decode the following frames into another rawvideo file. */ + fprintf(stderr, "Error: Width, height and pixel format have to be " + "constant in a rawvideo file, but the width, height or " + "pixel format of the input video changed:\n" + "old: width = %d, height = %d, format = %s\n" + "new: width = %d, height = %d, format = %s\n", + width, height, av_get_pix_fmt_name(pix_fmt), + frame->width, frame->height, + av_get_pix_fmt_name(frame->format)); + return -1; + } + printf("video_frame%s n:%d coded_n:%d pts:%s\n", cached ? "(cached)" : "", video_frame_count++, frame->coded_picture_number, diff --git a/doc/faq.texi b/doc/faq.texi index c3db720681..5fe716b8a1 100644 --- a/doc/faq.texi +++ b/doc/faq.texi @@ -349,7 +349,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/ffmpeg.texi b/doc/ffmpeg.texi index 6772f2f685..e154e8baa9 100644 --- a/doc/ffmpeg.texi +++ b/doc/ffmpeg.texi @@ -1175,9 +1175,9 @@ The option is intended for cases where features are needed that cannot be specified to @command{ffserver} but can be to @command{ffmpeg}. @item -sdp_file @var{file} (@emph{global}) -Print sdp information to @var{file}. +Print sdp information for an output stream to @var{file}. This allows dumping sdp information when at least one output isn't an -rtp stream. +rtp stream. (Requires at least one of the output formats to be rtp). @item -discard (@emph{input}) Allows discarding specific streams or frames of streams at the demuxer. diff --git a/doc/ffserver.texi b/doc/ffserver.texi index 57c95fbbda..336cec19a2 100644 --- a/doc/ffserver.texi +++ b/doc/ffserver.texi @@ -72,7 +72,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 655690956a..b1c5e651c1 100644 --- a/doc/fftools-common-opts.texi +++ b/doc/fftools-common-opts.texi @@ -261,10 +261,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 @@ -275,6 +279,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 0c72145d80..19cdd21e78 100644 --- a/doc/filters.texi +++ b/doc/filters.texi @@ -3486,7 +3486,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. @@ -4243,7 +4243,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 6c9531b03e..795f594041 100644 --- a/doc/general.texi +++ b/doc/general.texi @@ -948,8 +948,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 1a49293d31..f4a763de22 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 @@ -150,6 +150,81 @@ $ ffmpeg -f avfoundation -pixel_format bgr0 -i "default:none" out.avi BSD video input device. +@section decklink + +The decklink input device provides capture capabilities for Blackmagic +DeckLink devices. + +To enable this input device, you need the Blackmagic DeckLink SDK and you +need to configure with the appropriate @code{--extra-cflags} +and @code{--extra-ldflags}. +On Windows, you need to run the IDL files through @command{widl}. + +DeckLink is very picky about the formats it supports. Pixel format is +uyvy422 or v210, framerate and video size must be determined for your device with +@command{-list_formats 1}. Audio sample rate is always 48 kHz and the number +of channels can be 2, 8 or 16. + +@subsection Options + +@table @option + +@item list_devices +If set to @option{true}, print a list of devices and exit. +Defaults to @option{false}. + +@item list_formats +If set to @option{true}, print a list of supported formats and exit. +Defaults to @option{false}. + +@item bm_v210 +If set to @samp{1}, video is captured in 10 bit v210 instead +of uyvy422. Not all Blackmagic devices support this option. + +@end table + +@subsection Examples + +@itemize + +@item +List input devices: +@example +ffmpeg -f decklink -list_devices 1 -i dummy +@end example + +@item +List supported formats: +@example +ffmpeg -f decklink -list_formats 1 -i 'Intensity Pro' +@end example + +@item +Capture video clip at 1080i50 (format 11): +@example +ffmpeg -f decklink -i 'Intensity Pro@@11' -acodec copy -vcodec copy output.avi +@end example + +@item +Capture video clip at 1080i50 10 bit: +@example +ffmpeg -bm_v210 1 -f decklink -i 'UltraStudio Mini Recorder@@11' -acodec copy -vcodec copy output.avi +@end example + +@item +Capture video clip at 720p50 with 32bit audio: +@example +ffmpeg -bm_audiodepth 32 -f decklink -i 'UltraStudio Mini Recorder@@14' -acodec copy -vcodec copy output.avi +@end example + +@item +Capture video clip at 576i50 with 8 audio channels: +@example +ffmpeg -bm_channels 8 -f decklink -i 'UltraStudio Mini Recorder@@3' -acodec copy -vcodec copy output.avi +@end example + +@end itemize + @section dshow Windows DirectShow input device. @@ -1109,89 +1184,8 @@ The syntax is: -grab_x @var{x_offset} -grab_y @var{y_offset} @end example -Set the grabing region coordinates. The are expressed as offset from the top left +Set the grabbing region coordinates. They are expressed as offset from the top left corner of the X11 window. The default value is 0. -@section decklink - -The decklink input device provides capture capabilities for Blackmagic -DeckLink devices. - -To enable this input device, you need the Blackmagic DeckLink SDK and you -need to configure with the appropriate @code{--extra-cflags} -and @code{--extra-ldflags}. -On Windows, you need to run the IDL files through @command{widl}. - -DeckLink is very picky about the formats it supports. Pixel format is -uyvy422 or v210, framerate and video size must be determined for your device with -@command{-list_formats 1}. Audio sample rate is always 48 kHz and the number -of channels can be 2, 8 or 16. - -@subsection Options - -@table @option - -@item list_devices -If set to @option{true}, print a list of devices and exit. -Defaults to @option{false}. - -@item list_formats -If set to @option{true}, print a list of supported formats and exit. -Defaults to @option{false}. - -@item bm_v210 -If set to @samp{1}, video is captured in 10 bit v210 instead -of uyvy422. Not all Blackmagic devices support this option. - -@item bm_channels -Number of audio channels, can be 2, 8 or 16 - -@item bm_audiodepth -Audio bit depth, can be 16 or 32. - -@end table - -@subsection Examples - -@itemize - -@item -List input devices: -@example -ffmpeg -f decklink -list_devices 1 -i dummy -@end example - -@item -List supported formats: -@example -ffmpeg -f decklink -list_formats 1 -i 'Intensity Pro' -@end example - -@item -Capture video clip at 1080i50 (format 11): -@example -ffmpeg -f decklink -i 'Intensity Pro@@11' -acodec copy -vcodec copy output.avi -@end example - -@item -Capture video clip at 1080i50 10 bit: -@example -ffmpeg -bm_v210 1 -f decklink -i 'UltraStudio Mini Recorder@@11' -acodec copy -vcodec copy output.avi -@end example - -@item -Capture video clip at 720p50 with 32bit audio: -@example -ffmpeg -bm_audiodepth 32 -f decklink -i 'UltraStudio Mini Recorder@@14' -acodec copy -vcodec copy output.avi -@end example - -@item -Capture video clip at 576i50 with 8 audio channels: -@example -ffmpeg -bm_channels 8 -f decklink -i 'UltraStudio Mini Recorder@@3' -acodec copy -vcodec copy output.avi -@end example - -@end itemize - @c man end INPUT DEVICES diff --git a/doc/protocols.texi b/doc/protocols.texi index 006324c68d..5f6dfa8916 100644 --- a/doc/protocols.texi +++ b/doc/protocols.texi @@ -63,7 +63,7 @@ cache:@var{URL} Physical concatenation protocol. -Allow to read and seek from many resource in sequence as if they were +Read and seek from many resources in sequence as if they were a unique resource. A URL accepted by this protocol has the syntax: @@ -117,7 +117,7 @@ ffmpeg -i "data:image/gif;base64,R0lGODdhCAAIAMIEAAAAAAAA//8AAP//AP///////////// File access protocol. -Allow to read from or write to a file. +Read from or write to a file. A file URL can have the form: @example @@ -155,7 +155,7 @@ time, which is valuable for files on slow medium. FTP (File Transfer Protocol). -Allow to read from or write to remote resources using FTP protocol. +Read from or write to remote resources using FTP protocol. Following syntax is required. @example @@ -374,7 +374,7 @@ be seekable, so they will fail with the MD5 output protocol. UNIX pipe access protocol. -Allow to read and write from UNIX pipes. +Read and write from UNIX pipes. The accepted syntax is: @example @@ -614,7 +614,7 @@ For more information see: @url{http://www.samba.org/}. Secure File Transfer Protocol via libssh -Allow to read from or write to remote resources using SFTP protocol. +Read from or write to remote resources using SFTP protocol. Following syntax is required. 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 6604ff057b..8fb26c2f7e 100644 --- a/ffmpeg.c +++ b/ffmpeg.c @@ -351,7 +351,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). */ @@ -456,7 +455,10 @@ static void ffmpeg_cleanup(int ret) /* close files */ for (i = 0; i < nb_output_files; i++) { OutputFile *of = output_files[i]; - AVFormatContext *s = of->ctx; + AVFormatContext *s; + if (!of) + continue; + s = of->ctx; if (s && s->oformat && !(s->oformat->flags & AVFMT_NOFILE)) avio_closep(&s->pb); avformat_free_context(s); @@ -466,7 +468,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); @@ -650,6 +657,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"); @@ -1156,7 +1164,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) @@ -1756,17 +1767,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); @@ -1777,9 +1792,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; @@ -1830,9 +1851,12 @@ static int decode_audio(InputStream *ist, AVPacket *pkt, int *got_output) ret = AVERROR_INVALIDDATA; } - if (*got_output || ret<0 || pkt->size) + if (*got_output || ret<0) decode_error_stat[ret<0] ++; + if (ret < 0 && exit_on_error) + exit_program(1); + if (!*got_output || ret < 0) { if (!pkt->size) { for (i = 0; i < ist->nb_filters; i++) @@ -1975,9 +1999,12 @@ static int decode_video(InputStream *ist, AVPacket *pkt, int *got_output) ); } - if (*got_output || ret<0 || pkt->size) + if (*got_output || ret<0) decode_error_stat[ret<0] ++; + if (ret < 0 && exit_on_error) + exit_program(1); + if (*got_output && ret >= 0) { if (ist->dec_ctx->width != decoded_frame->width || ist->dec_ctx->height != decoded_frame->height || @@ -2093,9 +2120,12 @@ static int transcode_subtitles(InputStream *ist, AVPacket *pkt, int *got_output) int i, ret = avcodec_decode_subtitle2(ist->dec_ctx, &subtitle, got_output, pkt); - if (*got_output || ret<0 || pkt->size) + if (*got_output || ret<0) decode_error_stat[ret<0] ++; + if (ret < 0 && exit_on_error) + exit_program(1); + if (ret < 0 || !*got_output) { if (!pkt->size) sub2video_flush(ist); @@ -2307,6 +2337,9 @@ static void print_sdp(void) } } + if (!j) + goto fail; + av_sdp_create(avc, j, sdp, sizeof(sdp)); if (!sdp_filename) { @@ -2322,6 +2355,7 @@ static void print_sdp(void) } } +fail: av_freep(&avc); } @@ -2666,11 +2700,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 39c5f49d67..c620045640 100644 --- a/ffmpeg_opt.c +++ b/ffmpeg_opt.c @@ -2282,9 +2282,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); @@ -2311,9 +2311,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"); @@ -2333,9 +2333,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 @@ -2379,6 +2379,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); @@ -2859,7 +2862,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 d15ef492d7..34516973dd 100644 --- a/libavcodec/Makefile +++ b/libavcodec/Makefile @@ -217,7 +217,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/aaccoder.c b/libavcodec/aaccoder.c index 64eee3236b..c9a7253db7 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 daec5bc355..da97f288c1 100644 --- a/libavcodec/aacdec.c +++ b/libavcodec/aacdec.c @@ -424,7 +424,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; @@ -900,7 +900,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); @@ -2919,6 +2919,11 @@ static int aac_decode_er_frame(AVCodecContext *avctx, void *data, spectral_to_sample(ac); + if (!ac->frame->data[0] && samples) { + av_log(avctx, AV_LOG_ERROR, "no frame data found\n"); + return AVERROR_INVALIDDATA; + } + ac->frame->nb_samples = samples; ac->frame->sample_rate = avctx->sample_rate; *got_frame_ptr = 1; @@ -3073,6 +3078,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; @@ -3142,7 +3153,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 7015a2789c..f852b7d475 100644 --- a/libavcodec/aacenc.c +++ b/libavcodec/aacenc.c @@ -578,8 +578,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); } } diff --git a/libavcodec/aacpsy.c b/libavcodec/aacpsy.c index d1e65f6607..49ff3fe139 100644 --- a/libavcodec/aacpsy.c +++ b/libavcodec/aacpsy.c @@ -313,7 +313,7 @@ static av_cold int psy_3gpp_init(FFPsyContext *ctx) { ctx->bitres.size = 6144 - pctx->frame_bits; ctx->bitres.size -= ctx->bitres.size % 8; pctx->fill_level = ctx->bitres.size; - minath = ath(3410, ATH_ADD); + minath = ath(3410 - 0.733 * ATH_ADD, ATH_ADD); for (j = 0; j < 2; j++) { AacPsyCoeffs *coeffs = pctx->psy_coef[j]; const uint8_t *band_sizes = ctx->bands[j]; @@ -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/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 2f78d73ce8..c01859093d 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 1c3fdc43d3..27d0499423 100644 --- a/libavcodec/adpcm.c +++ b/libavcodec/adpcm.c @@ -578,6 +578,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: @@ -591,13 +593,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: @@ -610,6 +614,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; } @@ -1528,6 +1534,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/alac.c b/libavcodec/alac.c index ffd2d77d7c..d7aa7fb429 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 bac434fa63..e05eaed4fb 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; } @@ -1666,6 +1703,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 @@ -1728,9 +1771,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 536361cd84..2cd77d4d18 100644 --- a/libavcodec/apedec.c +++ b/libavcodec/apedec.c @@ -592,14 +592,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; @@ -892,6 +892,9 @@ static void long_filter_high_3800(int32_t *buffer, int order, int shift, int len int32_t dotprod, sign; int32_t coeffs[256], delay[256]; + if (order >= length) + return; + memset(coeffs, 0, order * sizeof(*coeffs)); for (i = 0; i < order; i++) delay[i] = buffer[i]; @@ -1369,7 +1372,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; @@ -1461,13 +1464,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/Makefile b/libavcodec/arm/Makefile index 1fea3b83d9..2f8739691e 100644 --- a/libavcodec/arm/Makefile +++ b/libavcodec/arm/Makefile @@ -37,6 +37,7 @@ OBJS-$(CONFIG_DCA_DECODER) += arm/dcadsp_init_arm.o OBJS-$(CONFIG_FLAC_DECODER) += arm/flacdsp_init_arm.o \ arm/flacdsp_arm.o OBJS-$(CONFIG_FLAC_ENCODER) += arm/flacdsp_init_arm.o +OBJS-$(CONFIG_HEVC_DECODER) += arm/hevcdsp_init_arm.o OBJS-$(CONFIG_MLP_DECODER) += arm/mlpdsp_init_arm.o OBJS-$(CONFIG_VC1_DECODER) += arm/vc1dsp_init_arm.o OBJS-$(CONFIG_VORBIS_DECODER) += arm/vorbisdsp_init_arm.o diff --git a/libavcodec/arm/hevcdsp_arm.h b/libavcodec/arm/hevcdsp_arm.h new file mode 100644 index 0000000000..7735df9cd2 --- /dev/null +++ b/libavcodec/arm/hevcdsp_arm.h @@ -0,0 +1,26 @@ +/* + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef AVCODEC_ARM_HEVCDSP_ARM_H +#define AVCODEC_ARM_HEVCDSP_ARM_H + +#include "libavcodec/hevcdsp.h" + +void ff_hevcdsp_init_neon(HEVCDSPContext *c, const int bit_depth); + +#endif /* AVCODEC_ARM_HEVCDSP_ARM_H */ diff --git a/libavcodec/arm/hevcdsp_init_arm.c b/libavcodec/arm/hevcdsp_init_arm.c new file mode 100644 index 0000000000..adcc454511 --- /dev/null +++ b/libavcodec/arm/hevcdsp_init_arm.c @@ -0,0 +1,32 @@ +/* + * Copyright (c) 2014 Seppo Tomperi + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "libavutil/attributes.h" +#include "libavutil/arm/cpu.h" +#include "libavcodec/hevcdsp.h" +#include "hevcdsp_arm.h" + +av_cold void ff_hevcdsp_init_arm(HEVCDSPContext *c, const int bit_depth) +{ + int cpu_flags = av_get_cpu_flags(); + + if (have_neon(cpu_flags)) + ff_hevcdsp_init_neon(c, bit_depth); +} diff --git a/libavcodec/arm/hevcdsp_init_neon.c b/libavcodec/arm/hevcdsp_init_neon.c index 61e6462cbd..55918077e2 100644 --- a/libavcodec/arm/hevcdsp_init_neon.c +++ b/libavcodec/arm/hevcdsp_init_neon.c @@ -21,6 +21,7 @@ #include "libavutil/attributes.h" #include "libavutil/arm/cpu.h" #include "libavcodec/hevcdsp.h" +#include "hevcdsp_arm.h" void ff_hevc_v_loop_filter_luma_neon(uint8_t *_pix, ptrdiff_t _stride, int _beta, int *_tc, uint8_t *_no_p, uint8_t *_no_q); void ff_hevc_h_loop_filter_luma_neon(uint8_t *_pix, ptrdiff_t _stride, int _beta, int *_tc, uint8_t *_no_p, uint8_t *_no_q); @@ -141,9 +142,8 @@ void ff_hevc_put_qpel_bi_neon_wrapper(uint8_t *dst, ptrdiff_t dststride, uint8_t put_hevc_qpel_uw_neon[my][mx](dst, dststride, src, srcstride, width, height, src2, MAX_PB_SIZE); } -static av_cold void hevcdsp_init_neon(HEVCDSPContext *c, const int bit_depth) +av_cold void ff_hevcdsp_init_neon(HEVCDSPContext *c, const int bit_depth) { -#if HAVE_NEON if (bit_depth == 8) { int x; c->hevc_v_loop_filter_luma = ff_hevc_v_loop_filter_luma_neon; @@ -221,13 +221,4 @@ static av_cold void hevcdsp_init_neon(HEVCDSPContext *c, const int bit_depth) c->put_hevc_qpel_uni[8][0][0] = ff_hevc_put_qpel_uw_pixels_w48_neon_8; c->put_hevc_qpel_uni[9][0][0] = ff_hevc_put_qpel_uw_pixels_w64_neon_8; } -#endif // HAVE_NEON -} - -void ff_hevcdsp_init_arm(HEVCDSPContext *c, const int bit_depth) -{ - int cpu_flags = av_get_cpu_flags(); - - if (have_neon(cpu_flags)) - hevcdsp_init_neon(c, bit_depth); } diff --git a/libavcodec/ass_split.c b/libavcodec/ass_split.c index 2458cb9225..5b6d7af1d1 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 e6f0416317..e98036e6db 100644 --- a/libavcodec/atrac3plusdec.c +++ b/libavcodec/atrac3plusdec.c @@ -381,7 +381,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 22a2d5d57d..aba27b8832 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 6e550ff7d1..caf031788b 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 cffb19c959..01f0033d17 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) return ff_cavs_init_top_lines(h); return 0; diff --git a/libavcodec/dca.c b/libavcodec/dca.c index 8dd043088e..714509b267 100644 --- a/libavcodec/dca.c +++ b/libavcodec/dca.c @@ -41,8 +41,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) @@ -54,8 +52,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_SYNCWORD_CORE_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_SYNCWORD_CORE_14B_BE: case DCA_SYNCWORD_CORE_14B_LE: diff --git a/libavcodec/dcadec.c b/libavcodec/dcadec.c index d06e6d2cdc..7940cd9df1 100644 --- a/libavcodec/dcadec.c +++ b/libavcodec/dcadec.c @@ -226,6 +226,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; @@ -426,6 +434,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); } @@ -1120,8 +1132,13 @@ int ff_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 */ @@ -1163,23 +1180,34 @@ int ff_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 = ff_dca_scale_factor_quant7; + scale_table_size = FF_ARRAY_ELEMS(ff_dca_scale_factor_quant7); } else { scale_table = ff_dca_scale_factor_quant6; + scale_table_size = FF_ARRAY_ELEMS(ff_dca_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]; } } } diff --git a/libavcodec/dcaenc.c b/libavcodec/dcaenc.c index d57d658122..59c6f68300 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 05e954bd63..9640c82e83 100644 --- a/libavcodec/diracdec.c +++ b/libavcodec/diracdec.c @@ -801,7 +801,10 @@ static int 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, @@ -899,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; @@ -1553,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 @@ -1565,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; } @@ -1583,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; } /** @@ -1635,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); @@ -1742,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 */ @@ -1937,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 433597720f..0ed960dfb6 100644 --- a/libavcodec/dnxhddec.c +++ b/libavcodec/dnxhddec.c @@ -119,6 +119,7 @@ static int dnxhd_decode_header(DNXHDContext *ctx, AVFrame *frame, static const uint8_t header_prefix[] = { 0x00, 0x00, 0x02, 0x80, 0x01 }; static const uint8_t header_prefix444[] = { 0x00, 0x00, 0x02, 0x80, 0x02 }; int i, cid, ret; + int old_bit_depth = ctx->bit_depth; if (buf_size < 0x280) { av_log(ctx->avctx, AV_LOG_ERROR, "buffer too small (%d < 640).\n", @@ -143,10 +144,6 @@ static int dnxhd_decode_header(DNXHDContext *ctx, AVFrame *frame, av_dlog(ctx->avctx, "width %d, height %d\n", ctx->width, ctx->height); - if (!ctx->bit_depth) { - ff_blockdsp_init(&ctx->bdsp, ctx->avctx); - ff_idctdsp_init(&ctx->idsp, ctx->avctx); - } if (buf[0x21] == 0x58) { /* 10 bit */ ctx->bit_depth = ctx->avctx->bits_per_raw_sample = 10; @@ -157,17 +154,23 @@ static int dnxhd_decode_header(DNXHDContext *ctx, AVFrame *frame, } else { ctx->decode_dct_block = dnxhd_decode_dct_block_10; ctx->pix_fmt = AV_PIX_FMT_YUV422P10; + ctx->is_444 = 0; } } else if (buf[0x21] == 0x38) { /* 8 bit */ ctx->bit_depth = ctx->avctx->bits_per_raw_sample = 8; ctx->pix_fmt = AV_PIX_FMT_YUV422P; + ctx->is_444 = 0; ctx->decode_dct_block = dnxhd_decode_dct_block_8; } else { av_log(ctx->avctx, AV_LOG_ERROR, "invalid bit depth value (%d).\n", buf[0x21]); return AVERROR_INVALIDDATA; } + if (ctx->bit_depth != old_bit_depth) { + ff_blockdsp_init(&ctx->bdsp, ctx->avctx); + ff_idctdsp_init(&ctx->idsp, ctx->avctx); + } cid = AV_RB32(buf + 0x28); av_dlog(ctx->avctx, "compression id %d\n", cid); @@ -373,7 +376,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 66d8428951..3b45b8eb98 100644 --- a/libavcodec/dpx.c +++ b/libavcodec/dpx.c @@ -348,11 +348,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/dvbsubdec.c b/libavcodec/dvbsubdec.c index e2b37e42dd..a1b8cea938 100644 --- a/libavcodec/dvbsubdec.c +++ b/libavcodec/dvbsubdec.c @@ -1197,8 +1197,12 @@ static int dvbsub_parse_region_segment(AVCodecContext *avctx, region->buf_size = region->width * region->height; region->pbuf = av_malloc(region->buf_size); - if (!region->pbuf) + if (!region->pbuf) { + region->buf_size = + region->width = + region->height = 0; return AVERROR(ENOMEM); + } fill = 1; region->dirty = 0; @@ -1417,7 +1421,7 @@ static void save_display_set(DVBSubContext *ctx) pbuf = av_malloc(width * height * 4); if (!pbuf) - return AVERROR(ENOMEM); + return; for (display = ctx->display_list; display; display = display->next) { region = get_region(ctx, display->region_id); @@ -1499,10 +1503,10 @@ static int dvbsub_parse_display_definition_segment(AVCodecContext *avctx, avctx->height = display_def->height; } - if (buf_size < 13) - return AVERROR_INVALIDDATA; - if (info_byte & 1<<3) { // display_window_flag + if (buf_size < 13) + return AVERROR_INVALIDDATA; + display_def->x = bytestream_get_be16(&buf); display_def->width = bytestream_get_be16(&buf) - display_def->x + 1; display_def->y = bytestream_get_be16(&buf); diff --git a/libavcodec/dvdec.c b/libavcodec/dvdec.c index 388bbf2fee..2a4a18d915 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 ffb2bcc115..a24b800704 100644 --- a/libavcodec/dvdsubdec.c +++ b/libavcodec/dvdsubdec.c @@ -346,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; diff --git a/libavcodec/dxtory.c b/libavcodec/dxtory.c index 22e7b2f4eb..4f84c524f0 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 * 9LL / 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 * 3LL / 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; } 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/error_resilience.c b/libavcodec/error_resilience.c index 4fa7bc4e21..73c3491703 100644 --- a/libavcodec/error_resilience.c +++ b/libavcodec/error_resilience.c @@ -378,14 +378,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]; @@ -410,7 +415,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; @@ -439,7 +444,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 } }; @@ -672,7 +677,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 6251fb76fd..29cb4030c8 100644 --- a/libavcodec/exr.c +++ b/libavcodec/exr.c @@ -322,7 +322,7 @@ static uint16_t reverse_lut(const uint8_t *bitmap, uint16_t *lut) i = k - 1; - memset(lut + k * 2, 0, (USHORT_RANGE - k) * 2); + memset(lut + k, 0, (USHORT_RANGE - k) * 2); return i; } @@ -459,7 +459,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) \ @@ -468,7 +468,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]; \ @@ -501,7 +501,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; @@ -518,7 +518,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; } } @@ -539,7 +539,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; } @@ -1010,6 +1010,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; @@ -1350,21 +1366,6 @@ static av_cold int decode_init(AVCodecContext *avctx) float one_gamma = 1.0f / s->gamma; s->avctx = avctx; - s->xmin = ~0; - s->xmax = ~0; - s->ymin = ~0; - s->ymax = ~0; - s->xdelta = ~0; - s->ydelta = ~0; - s->channel_offsets[0] = -1; - s->channel_offsets[1] = -1; - s->channel_offsets[2] = -1; - s->channel_offsets[3] = -1; - s->pixel_type = EXR_UNKNOWN; - s->compression = EXR_UNKN; - s->nb_channels = 0; - s->w = 0; - s->h = 0; if (one_gamma > 0.9999f && one_gamma < 1.0001f) { for (i = 0; i < 65536; ++i) diff --git a/libavcodec/ffv1.c b/libavcodec/ffv1.c index ab58a6074f..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 b8df7efe8d..7be30270be 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 c3bf759a85..8ed56d2b0e 100644 --- a/libavcodec/ffv1enc.c +++ b/libavcodec/ffv1enc.c @@ -962,6 +962,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; @@ -971,7 +972,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] * @@ -1195,6 +1196,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/flacenc.c b/libavcodec/flacenc.c index 97867823d9..c96609e609 100644 --- a/libavcodec/flacenc.c +++ b/libavcodec/flacenc.c @@ -663,7 +663,7 @@ static uint64_t calc_rice_params(RiceContext *rc, int pmin, int pmax, bits[pmin] = UINT32_MAX; for (i = pmax; ; ) { bits[i] = calc_optimal_rice_params(&tmp_rc, i, sums, n, pred_order); - if (bits[i] < bits[opt_porder]) { + if (bits[i] < bits[opt_porder] || pmax == pmin) { opt_porder = i; *rc = tmp_rc; } @@ -920,7 +920,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/flashsvenc.c b/libavcodec/flashsvenc.c index 14e8adab2e..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; } diff --git a/libavcodec/g2meet.c b/libavcodec/g2meet.c index 67bb1fd31a..df1f260152 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 cf5d438a72..e55337568a 100644 --- a/libavcodec/gif.c +++ b/libavcodec/gif.c @@ -43,6 +43,7 @@ typedef struct GIFContext { 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 @@ -174,7 +175,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; @@ -232,7 +233,8 @@ static av_cold int gif_encode_init(AVCodecContext *avctx) s->transparent_index = -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); @@ -324,6 +326,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 1632ee37cc..86cd357af9 100644 --- a/libavcodec/golomb.h +++ b/libavcodec/golomb.h @@ -68,7 +68,7 @@ static inline int get_ue_golomb(GetBitContext *gb) int log = 2 * av_log2(buf) - 31; LAST_SKIP_BITS(re, gb, 32 - log); CLOSE_READER(re, gb); - if (CONFIG_FTRAPV && log < 0) { + if (log < 7) { av_log(NULL, AV_LOG_ERROR, "Invalid UE golomb code\n"); return AVERROR_INVALIDDATA; } @@ -337,8 +337,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 8ec46dfb1c..4d331f1445 100644 --- a/libavcodec/h264.c +++ b/libavcodec/h264.c @@ -1499,9 +1499,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->current_slice) - 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 */ @@ -1537,8 +1534,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: @@ -1546,6 +1549,10 @@ again: hx->intra_gb_ptr = hx->inter_gb_ptr = &hx->gb; + 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; @@ -1629,7 +1636,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) @@ -1638,8 +1647,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: @@ -1672,8 +1684,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 @@ -1747,7 +1765,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; } @@ -1756,7 +1774,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 21e9952720..b260d5520b 100644 --- a/libavcodec/h264.h +++ b/libavcodec/h264.h @@ -536,6 +536,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; @@ -776,7 +777,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 41e0f867c0..397b070ca4 100644 --- a/libavcodec/h264_cabac.c +++ b/libavcodec/h264_cabac.c @@ -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 8eda6b88a9..6e8b1e856b 100644 --- a/libavcodec/h264_parser.c +++ b/libavcodec/h264_parser.c @@ -280,7 +280,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 c2747ac84c..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; @@ -523,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 75025dc3fe..353412d27a 100644 --- a/libavcodec/h264_refs.c +++ b/libavcodec/h264_refs.c @@ -276,7 +276,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; @@ -705,7 +705,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 e9a89d11f7..5e7efddf4a 100644 --- a/libavcodec/h264_slice.c +++ b/libavcodec/h264_slice.c @@ -242,11 +242,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)); } } @@ -893,7 +893,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; @@ -914,7 +914,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) { @@ -1194,6 +1194,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); @@ -1289,6 +1290,7 @@ int ff_h264_decode_slice_header(H264Context *h, H264Context *h0) 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; @@ -1416,7 +1418,8 @@ int ff_h264_decode_slice_header(H264Context *h, H264Context *h0) || 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)) @@ -1452,6 +1455,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 " @@ -1512,7 +1516,8 @@ int ff_h264_decode_slice_header(H264Context *h, H264Context *h0) } 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; droppable = h->nal_ref_idc == 0; @@ -1530,12 +1535,13 @@ int ff_h264_decode_slice_header(H264Context *h, H264Context *h0) picture_structure = PICT_TOP_FIELD + bottom_field_flag; } else { picture_structure = PICT_FRAME; - h->mb_aff_frame = h->sps.mb_aff; + mb_aff_frame = h->sps.mb_aff; } } if (h0->current_slice) { if (last_pic_structure != picture_structure || - last_pic_droppable != droppable) { + 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); @@ -1551,6 +1557,7 @@ int ff_h264_decode_slice_header(H264Context *h, H264Context *h0) 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) { @@ -1663,14 +1670,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; @@ -2412,20 +2422,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) @@ -2487,7 +2509,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); @@ -2575,19 +2607,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 fdbaa28a97..061ea41dbc 100644 --- a/libavcodec/hevc.c +++ b/libavcodec/hevc.c @@ -440,7 +440,7 @@ static int hls_slice_header(HEVCContext *s) slice_address_length = av_ceil_log2(s->sps->ctb_width * s->sps->ctb_height); - sh->slice_segment_addr = get_bits(gb, slice_address_length); + sh->slice_segment_addr = slice_address_length ? get_bits(gb, slice_address_length) : 0; if (sh->slice_segment_addr >= s->sps->ctb_width * s->sps->ctb_height) { av_log(s->avctx, AV_LOG_ERROR, "Invalid slice segment address: %u.\n", @@ -694,15 +694,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) { @@ -775,6 +789,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; } @@ -2365,6 +2381,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; } @@ -2402,8 +2420,8 @@ 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 (!ret || !arg) { @@ -2412,11 +2430,18 @@ static int hls_slice_data_wpp(HEVCContext *s, const uint8_t *nal, int length) return AVERROR(ENOMEM); } + 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)); @@ -2449,6 +2474,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; @@ -2475,6 +2505,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; @@ -2600,7 +2631,8 @@ static int hevc_frame_start(HEVCContext *s) if (ret < 0) goto fail; - ff_thread_finish_setup(s->avctx); + if (!s->avctx->hwaccel) + ff_thread_finish_setup(s->avctx); return 0; @@ -2982,7 +3014,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]; @@ -3342,6 +3373,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; @@ -3436,6 +3468,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; @@ -3477,6 +3510,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 e0af6f1810..9e183b71b0 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 { @@ -609,7 +609,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; @@ -844,6 +844,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_parser.c b/libavcodec/hevc_parser.c index a6fdbb722d..f5354aae6e 100644 --- a/libavcodec/hevc_parser.c +++ b/libavcodec/hevc_parser.c @@ -200,7 +200,7 @@ static inline int parse_nal_units(AVCodecParserContext *s, AVCodecContext *avctx slice_address_length = av_ceil_log2_c(h->sps->ctb_width * h->sps->ctb_height); - sh->slice_segment_addr = get_bits(gb, slice_address_length); + sh->slice_segment_addr = slice_address_length ? get_bits(gb, slice_address_length) : 0; if (sh->slice_segment_addr >= h->sps->ctb_width * h->sps->ctb_height) { av_log(h->avctx, AV_LOG_ERROR, "Invalid slice segment address: %u.\n", sh->slice_segment_addr); diff --git a/libavcodec/hevc_ps.c b/libavcodec/hevc_ps.c index 85ce2ccc87..7857d0c915 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]); @@ -755,6 +762,9 @@ int ff_hevc_decode_nal_sps(HEVCContext *s) } sps->chroma_format_idc = get_ue_golomb_long(gb); + if (sps->chroma_format_idc > 3U) { + return AVERROR_INVALIDDATA; + } if (sps->chroma_format_idc == 3) sps->separate_colour_plane_flag = get_bits1(gb); @@ -1039,7 +1049,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) { @@ -1315,14 +1326,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 f6596e8d1e..fdfde91bf0 100644 --- a/libavcodec/hevc_refs.c +++ b/libavcodec/hevc_refs.c @@ -174,7 +174,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 2fa910a5e5..d89d370584 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 8cb609946a..8336460441 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/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 7d4d9b09db..6ce634d147 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 d27eff2c3e..526dd83f0a 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 ecb6393f27..be1c9c0fd3 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/libopenjpegdec.c b/libavcodec/libopenjpegdec.c index 1cd1b9b009..ab681f1246 100644 --- a/libavcodec/libopenjpegdec.c +++ b/libavcodec/libopenjpegdec.c @@ -358,6 +358,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 95b0987e14..6c77527b77 100644 --- a/libavcodec/libopenjpegenc.c +++ b/libavcodec/libopenjpegenc.c @@ -200,6 +200,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 785460972d..edb0b38bc4 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/libtheoraenc.c b/libavcodec/libtheoraenc.c index b4b395aa8c..0ccb9ecc11 100644 --- a/libavcodec/libtheoraenc.c +++ b/libavcodec/libtheoraenc.c @@ -111,6 +111,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 69c3a459d6..7ee86411f3 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/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/mjpegdec.c b/libavcodec/mjpegdec.c index 5e86c2ecd7..d69474f439 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) @@ -595,7 +606,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 +972,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 +980,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 +1078,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 +1149,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 +1220,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 +1237,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,8 +1278,8 @@ static int mjpeg_decode_scan(MJpegDecodeContext *s, int nb_components, int Ah, if (s->interlaced && s->bottom_field) block_offset += linesize[c] >> 1; - if ( 8*(h * mb_x + x) < s->width - && 8*(v * mb_y + y) < s->height) { + 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; @@ -1312,11 +1342,7 @@ static int mjpeg_decode_scan_progressive_ac(MJpegDecodeContext *s, int ss, int mb_x, mb_y; int EOBRUN = 0; int c = s->comp_index[0]; - uint8_t *data = s->picture_ptr->data[c]; - int linesize = s->linesize[c]; - int last_scan = 0; int16_t *quant_matrix = s->quant_matrixes[s->quant_sindex[0]]; - int bytes_per_pixel = 1 + (s->bits > 8); av_assert0(ss>=0 && Ah>=0 && Al>=0); if (se < ss || se > 63) { @@ -1324,20 +1350,13 @@ 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]; - } - - if (s->interlaced && s->bottom_field) - data += linesize >> 1; + // 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); s->restart_count = 0; for (mb_y = 0; mb_y < s->mb_height; mb_y++) { - uint8_t *ptr = data + (mb_y * linesize * 8 >> s->avctx->lowres); int block_idx = mb_y * s->block_stride[c]; int16_t (*block)[64] = &s->blocks[c][block_idx]; uint8_t *last_nnz = &s->last_nnz[c][block_idx]; @@ -1358,12 +1377,6 @@ static int mjpeg_decode_scan_progressive_ac(MJpegDecodeContext *s, int ss, return AVERROR_INVALIDDATA; } - if (last_scan) { - s->idsp.idct_put(ptr, linesize, *block); - if (s->bits & 7) - shift_output(s, ptr, linesize); - ptr += bytes_per_pixel*8 >> s->avctx->lowres; - } if (handle_rstn(s, 0)) EOBRUN = 0; } @@ -1371,6 +1384,41 @@ static int mjpeg_decode_scan_progressive_ac(MJpegDecodeContext *s, int ss, return 0; } +static void mjpeg_idct_scan_progressive_ac(MJpegDecodeContext *s) +{ + int mb_x, mb_y; + int c; + const int bytes_per_pixel = 1 + (s->bits > 8); + const int block_size = s->lossless ? 1 : 8; + + for (c = 0; c < s->nb_components; c++) { + uint8_t *data = s->picture_ptr->data[c]; + int linesize = s->linesize[c]; + int h = s->h_max / s->h_count[c]; + int v = s->v_max / s->v_count[c]; + int mb_width = (s->width + h * block_size - 1) / (h * block_size); + int mb_height = (s->height + v * block_size - 1) / (v * block_size); + + if (~s->coefs_finished[c]) + av_log(s->avctx, AV_LOG_WARNING, "component %d is incomplete\n", c); + + if (s->interlaced && s->bottom_field) + data += linesize >> 1; + + for (mb_y = 0; mb_y < mb_height; mb_y++) { + uint8_t *ptr = data + (mb_y * linesize * 8 >> s->avctx->lowres); + int block_idx = mb_y * s->block_stride[c]; + int16_t (*block)[64] = &s->blocks[c][block_idx]; + for (mb_x = 0; mb_x < mb_width; mb_x++, block++) { + s->idsp.idct_put(ptr, linesize, *block); + if (s->bits & 7) + shift_output(s, ptr, linesize); + ptr += bytes_per_pixel*8 >> s->avctx->lowres; + } + } + } +} + int ff_mjpeg_decode_sos(MJpegDecodeContext *s, const uint8_t *mb_bitmask, int mb_bitmask_size, const AVFrame *reference) { @@ -1909,7 +1957,7 @@ 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"); @@ -2053,6 +2101,8 @@ int ff_mjpeg_decode_frame(AVCodecContext *avctx, void *data, int *got_frame, break; case EOI: eoi_parser: + if (avctx->skip_frame != AVDISCARD_ALL && s->progressive && s->cur_scan && s->got_picture) + mjpeg_idct_scan_progressive_ac(s); s->cur_scan = 0; if (!s->got_picture) { av_log(avctx, AV_LOG_WARNING, 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/motion_est.c b/libavcodec/motion_est.c index a0a5965321..d161043323 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 f7e57f934d..40b7cd2536 100644 --- a/libavcodec/mpeg12dec.c +++ b/libavcodec/mpeg12dec.c @@ -29,6 +29,7 @@ #include #include "libavutil/attributes.h" +#include "libavutil/imgutils.h" #include "libavutil/internal.h" #include "libavutil/stereo3d.h" @@ -1315,7 +1316,13 @@ static int mpeg_decode_postinit(AVCodecContext *avctx) } } // MPEG-2 - ff_set_sar(s->avctx, s->avctx->sample_aspect_ratio); + if (av_image_check_sar(s->width, s->height, + avctx->sample_aspect_ratio) < 0) { + av_log(avctx, AV_LOG_WARNING, "ignoring invalid SAR: %u/%u\n", + avctx->sample_aspect_ratio.num, + avctx->sample_aspect_ratio.den); + avctx->sample_aspect_ratio = (AVRational){ 0, 1 }; + } if ((s1->mpeg_enc_ctx_allocated == 0) || avctx->coded_width != s->width || @@ -1910,7 +1917,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 AVERROR_INVALIDDATA; } else goto eos; @@ -2135,8 +2142,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); @@ -2168,6 +2173,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 a3d37247f7..8239081747 100644 --- a/libavcodec/mpeg4audio.h +++ b/libavcodec/mpeg4audio.h @@ -102,7 +102,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 138a107b85..dcbde7c6aa 100644 --- a/libavcodec/mpegaudiodec_template.c +++ b/libavcodec/mpegaudiodec_template.c @@ -1657,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) @@ -1714,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) @@ -1893,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 72e7eda36b..949aebac6c 100644 --- a/libavcodec/mpegvideo.c +++ b/libavcodec/mpegvideo.c @@ -1288,6 +1288,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 @@ -1299,6 +1376,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; @@ -1346,10 +1425,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 0be20241f3..7dd5ad74ac 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, @@ -770,6 +771,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); diff --git a/libavcodec/mpegvideo_enc.c b/libavcodec/mpegvideo_enc.c index 847b1164b6..d27d54efae 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; @@ -2721,6 +2722,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; @@ -2797,30 +2832,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,9 +3719,11 @@ 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) { + 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; @@ -3733,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/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/on2avc.c b/libavcodec/on2avc.c index 4a38da00e5..9ca716c8fa 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 442b21299c..a906864dcd 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 841d1ed25c..73526f9800 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 f8ca133a94..3f383aeec2 100644 --- a/libavcodec/opusdec.c +++ b/libavcodec/opusdec.c @@ -449,6 +449,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) { @@ -462,7 +470,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) { @@ -530,7 +538,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 2bee31540e..e25519a040 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 901abaebd3..dd71f27015 100644 --- a/libavcodec/pngdec.c +++ b/libavcodec/pngdec.c @@ -539,6 +539,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)) { @@ -618,7 +623,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) { @@ -805,28 +810,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 */ @@ -840,6 +851,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; } @@ -968,7 +986,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 (;;) { @@ -984,12 +1002,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); @@ -1001,11 +1021,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'): @@ -1018,15 +1038,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'): @@ -1051,6 +1073,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 */ @@ -1070,7 +1093,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/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/pthread_frame.c b/libavcodec/pthread_frame.c index 5a4ab84a4a..d07df0d150 100644 --- a/libavcodec/pthread_frame.c +++ b/libavcodec/pthread_frame.c @@ -453,6 +453,9 @@ int ff_thread_decode_frame(AVCodecContext *avctx, *got_picture_ptr = p->got_frame; picture->pkt_dts = p->avpkt.dts; + if (p->result < 0) + err = p->result; + /* * A later call with avkpt->size == 0 may loop over all threads, * including this one, searching for a frame to return before being @@ -470,6 +473,14 @@ int ff_thread_decode_frame(AVCodecContext *avctx, fctx->next_finished = finished; + /* + * When no frame was found while flushing, but an error occured in + * any thread, return it instead of 0. + * Otherwise the error can get lost. + */ + if (!avpkt->size && !*got_picture_ptr) + return err; + /* return the size of the consumed packet if no error occurred */ return (p->result >= 0) ? avpkt->size : p->result; } @@ -571,7 +582,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 +602,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 +680,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 c8e69f0a9a..f9fc8042fe 100644 --- a/libavcodec/pthread_slice.c +++ b/libavcodec/pthread_slice.c @@ -193,6 +193,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 81be6b311b..86f9f63bac 100644 --- a/libavcodec/put_bits.h +++ b/libavcodec/put_bits.h @@ -105,7 +105,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; @@ -163,9 +163,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; } @@ -177,9 +181,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; } @@ -229,6 +237,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; } @@ -252,6 +261,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/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 3215f0a51c..89879e81b3 100644 --- a/libavcodec/roqvideoenc.c +++ b/libavcodec/roqvideoenc.c @@ -999,6 +999,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/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/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 deae0fa1ce..db2e3c5feb 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 f5cbae37f2..51623d6e73 100644 --- a/libavcodec/snow.h +++ b/libavcodec/snow.h @@ -303,6 +303,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; @@ -346,8 +348,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; @@ -562,6 +562,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/snowenc.c b/libavcodec/snowenc.c index 544efbfb9e..957fc9ba98 100644 --- a/libavcodec/snowenc.c +++ b/libavcodec/snowenc.c @@ -286,7 +286,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 a95c7c866e..0af4708fa7 100644 --- a/libavcodec/svq1dec.c +++ b/libavcodec/svq1dec.c @@ -616,9 +616,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 ec540a25e3..bd35e31bce 100644 --- a/libavcodec/svq1enc.c +++ b/libavcodec/svq1enc.c @@ -516,6 +516,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 a453da81ec..fbec0e037b 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(); @@ -801,6 +802,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 4fe1168774..6ee57b14e9 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 581cd04dbb..a83b0ba91b 100644 --- a/libavcodec/utils.c +++ b/libavcodec/utils.c @@ -374,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) { @@ -424,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; @@ -1030,8 +1032,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; } @@ -3090,8 +3094,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]", @@ -3393,7 +3397,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/vc1dec.c b/libavcodec/vc1dec.c index 70694471ce..d9bfbece02 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/vorbisdec.c b/libavcodec/vorbisdec.c index 0fce735d61..6f7d8399a1 100644 --- a/libavcodec/vorbisdec.c +++ b/libavcodec/vorbisdec.c @@ -573,6 +573,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, @@ -789,6 +794,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 8a7c6b21e8..3b19db9638 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; @@ -209,8 +209,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 @@ -2014,17 +2014,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; } @@ -2249,6 +2251,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); @@ -2319,7 +2322,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; ret = ff_set_dimensions(avctx, s->width, s->height); if (ret < 0) @@ -2353,6 +2357,7 @@ static int theora_decode_header(AVCodecContext *avctx, GetBitContext *gb) avctx->color_trc = AVCOL_TRC_BT709; } + s->theora_header = 1; return 0; } @@ -2361,6 +2366,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 */ @@ -2473,6 +2481,7 @@ static av_cold int theora_decode_init(AVCodecContext *avctx) const uint8_t *header_start[3]; int header_len[3]; int i; + int ret; avctx->pix_fmt = AV_PIX_FMT_YUV420P; @@ -2492,7 +2501,9 @@ static av_cold int theora_decode_init(AVCodecContext *avctx) for (i = 0; i < 3; i++) { if (header_len[i] <= 0) continue; - init_get_bits8(&gb, header_start[i], header_len[i]); + ret = init_get_bits8(&gb, header_start[i], header_len[i]); + if (ret < 0) + return ret; ptype = get_bits(&gb, 8); diff --git a/libavcodec/vp8.c b/libavcodec/vp8.c index 448710b279..7cea03480c 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)); @@ -639,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); @@ -757,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)); } /** @@ -2687,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 c7f351bdd7..2d6ba3d9f4 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 { @@ -2508,7 +2541,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, @@ -2526,12 +2559,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; @@ -2558,14 +2697,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; @@ -2603,156 +2742,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); @@ -3858,7 +3873,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) { 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 220290fbf1..ab33c33414 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. * diff --git a/libavcodec/vp9dsp.c b/libavcodec/vp9dsp.c index 4d4518748a..19b93cf073 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 c1749505e7..cc9b0837b6 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 47e9e9e662..723a84769b 100644 --- a/libavcodec/webp.c +++ b/libavcodec/webp.c @@ -1387,7 +1387,7 @@ static int webp_decode_frame(AVCodecContext *avctx, void *data, int *got_frame, } av_dict_free(&s->exif_metadata); - while (bytestream2_get_bytes_left(&gb) > 0) { + while (bytestream2_get_bytes_left(&gb) > 8) { char chunk_str[5] = { 0 }; chunk_type = bytestream2_get_le32(&gb); diff --git a/libavcodec/wmaenc.c b/libavcodec/wmaenc.c index b922acdee8..9361855939 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; @@ -82,7 +83,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 fcadbc034b..98ae3c892f 100644 --- a/libavcodec/wmalosslessdec.c +++ b/libavcodec/wmalosslessdec.c @@ -488,7 +488,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++) @@ -1005,6 +1005,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 3b7a8128fd..4ea61c0e29 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 ae88d4ec80..fff1aa87ae 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/sbrdsp.asm b/libavcodec/x86/sbrdsp.asm index 083461a107..498c136abd 100644 --- a/libavcodec/x86/sbrdsp.asm +++ b/libavcodec/x86/sbrdsp.asm @@ -382,6 +382,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/x86/vp9itxfm.asm b/libavcodec/x86/vp9itxfm.asm index bfe427fa70..9cf0d78fab 100644 --- a/libavcodec/x86/vp9itxfm.asm +++ b/libavcodec/x86/vp9itxfm.asm @@ -1622,7 +1622,9 @@ VP9_IDCT_IDCT_16x16_ADD_XMM avx PSIGNW m3, [pw_m1] ; m3=out1[w], m7=t10[w] SUMSUB_BA w, 2, 6, 1 ; m2=out14[w], m6=t11[w] -%if cpuflag(ssse3) + ; unfortunately, the code below overflows in some cases, e.g. + ; http://downloads.webmproject.org/test_data/libvpx/vp90-2-14-resize-fp-tiles-16-8.webm +%if 0; cpuflag(ssse3) SUMSUB_BA w, 7, 6, 1 pmulhrsw m7, [pw_11585x2] ; m7=out6[w] pmulhrsw m6, [pw_11585x2] ; m6=out9[w] @@ -1699,7 +1701,9 @@ VP9_IDCT_IDCT_16x16_ADD_XMM avx SUMSUB_BA w, 5, 7, 4 PSIGNW m5, [pw_m1] ; m12=out15[w], m8=t3[w] -%if cpuflag(ssse3) + ; unfortunately, the code below overflows in some cases, e.g. + ; http://downloads.webmproject.org/test_data/libvpx/vp90-2-14-resize-fp-tiles-16-8-4-2-1.webm +%if 0 ; cpuflag(ssse3) SUMSUB_BA w, 7, 6, 4 pmulhrsw m7, [pw_m11585x2] ; m8=out7[w] pmulhrsw m6, [pw_11585x2] ; m1=out8[w] 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/libavdevice/lavfi.c b/libavdevice/lavfi.c index 64db376899..126e5f62ce 100644 --- a/libavdevice/lavfi.c +++ b/libavdevice/lavfi.c @@ -411,7 +411,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/v4l2.c b/libavdevice/v4l2.c index 0f64d741b6..005beca303 100644 --- a/libavdevice/v4l2.c +++ b/libavdevice/v4l2.c @@ -286,7 +286,7 @@ static void list_formats(AVFormatContext *ctx, int type) } else if (vfd.flags & V4L2_FMT_FLAG_COMPRESSED && type & V4L_COMPFORMATS) { const AVCodecDescriptor *desc = avcodec_descriptor_get(codec_id); - av_log(ctx, AV_LOG_INFO, "Compressedll : %9s : %20s :", + av_log(ctx, AV_LOG_INFO, "Compressed: %9s : %20s :", desc ? desc->name : "Unsupported", vfd.description); } else { @@ -747,7 +747,7 @@ static int v4l2_set_parameters(AVFormatContext *ctx) } } else { av_log(ctx, AV_LOG_WARNING, - "The driver does not allow to change time per frame\n"); + "The driver does not permit changing the time per frame\n"); } } if (tpf->denominator > 0 && tpf->numerator > 0) { diff --git a/libavdevice/xcbgrab.c b/libavdevice/xcbgrab.c index 477eed700a..fc20ca64ff 100644 --- a/libavdevice/xcbgrab.c +++ b/libavdevice/xcbgrab.c @@ -149,13 +149,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); @@ -409,7 +421,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 @@ -520,8 +532,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_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/lavfutils.c b/libavfilter/lavfutils.c index 75e68a7d06..9952e6eab6 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_frame_free(&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/src_movie.c b/libavfilter/src_movie.c index 908c03e1d3..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); diff --git a/libavfilter/vf_boxblur.c b/libavfilter/vf_boxblur.c index 3ccf26899f..bcf0ca5b72 100644 --- a/libavfilter/vf_boxblur.c +++ b/libavfilter/vf_boxblur.c @@ -124,7 +124,7 @@ static int query_formats(AVFilterContext *ctx) const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(fmt); if (!(desc->flags & (AV_PIX_FMT_FLAG_HWACCEL | AV_PIX_FMT_FLAG_BITSTREAM | AV_PIX_FMT_FLAG_PAL)) && (desc->flags & AV_PIX_FMT_FLAG_PLANAR || desc->nb_components == 1) && - (!(desc->flags & AV_PIX_FMT_FLAG_BE) == !HAVE_BIGENDIAN) || desc->comp[0].depth_minus1 == 7) + (!(desc->flags & AV_PIX_FMT_FLAG_BE) == !HAVE_BIGENDIAN || desc->comp[0].depth_minus1 == 7)) ff_add_format(&formats, fmt); } 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_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_palettegen.c b/libavfilter/vf_palettegen.c index 8b08140283..4b49058b35 100644 --- a/libavfilter/vf_palettegen.c +++ b/libavfilter/vf_palettegen.c @@ -504,7 +504,7 @@ static int request_frame(AVFilterLink *outlink) int r; r = ff_request_frame(inlink); - if (r == AVERROR_EOF && !s->palette_pushed) { + if (r == AVERROR_EOF && !s->palette_pushed && s->nb_refs) { r = ff_filter_frame(outlink, get_palette_frame(ctx)); s->palette_pushed = 1; return r; diff --git a/libavfilter/vf_scale.c b/libavfilter/vf_scale.c index f77884c27a..ab6cab0a07 100644 --- a/libavfilter/vf_scale.c +++ b/libavfilter/vf_scale.c @@ -523,6 +523,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_fspp.asm b/libavfilter/x86/vf_fspp.asm index e88feb981a..c7f8f64f1b 100644 --- a/libavfilter/x86/vf_fspp.asm +++ b/libavfilter/x86/vf_fspp.asm @@ -65,13 +65,13 @@ cglobal store_slice, 2, 7, 0, dst, src, width, dither_height, dither, tmp, tmp2 mov tmpq, src_strideq and widthq, ~7 sub dst_strideq, widthq - movd m5, ditherq ; log2_scale + movd m5, ditherd ; log2_scale xor ditherq, -1 ; log2_scale mov tmp2q, tmpq add ditherq, 7 ; log2_scale neg tmpq sub tmp2q, widthq - movd m2, ditherq ; log2_scale + movd m2, ditherd ; log2_scale add tmp2q, tmp2q lea ditherq, [pb_dither] mov src_strideq, tmp2q @@ -132,12 +132,12 @@ cglobal store_slice2, 0, 7, 0, dst, src, width, dither_height, dither, tmp, tmp2 mov tmpq, src_strideq and widthq, ~7 sub dst_strideq, widthq - movd m5, ditherq ; log2_scale + movd m5, ditherd ; log2_scale xor ditherq, -1 ; log2_scale mov tmp2q, tmpq add ditherq, 7 ; log2_scale sub tmp2q, widthq - movd m2, ditherq ; log2_scale + movd m2, ditherd ; log2_scale add tmp2q, tmp2q lea ditherq, [pb_dither] mov src_strideq, tmp2q 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/act.c b/libavformat/act.c index 7b6b8406fc..35aacbc459 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, 0); + ff_get_wav_header(s, pb, st->codec, size, 0); /* 8000Hz (Fine-rec) file format has 10 bytes long diff --git a/libavformat/asfdec.c b/libavformat/asfdec.c index 0a2e77e390..d8edac5efa 100644 --- a/libavformat/asfdec.c +++ b/libavformat/asfdec.c @@ -429,7 +429,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, 0); + int ret = ff_get_wav_header(s, pb, st->codec, type_specific_size, 0); if (ret < 0) return ret; if (is_dvr_ms_audio) { diff --git a/libavformat/asfenc.c b/libavformat/asfenc.c index f4f64a62e1..0aea5525bd 100644 --- a/libavformat/asfenc.c +++ b/libavformat/asfenc.c @@ -660,6 +660,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; } @@ -924,6 +925,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 4211a95fca..dc4aaad6a3 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) @@ -921,7 +933,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; @@ -1955,7 +1967,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) @@ -1964,14 +1976,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); /** @@ -1982,7 +1994,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. @@ -1993,7 +2005,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 5c9443a4f4..86e98997b9 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 @@ -127,7 +128,7 @@ static inline int get_duration(AVIStream *ast, int len) { if (ast->sample_size) return len; - else if (ast->dshow_block_align > 1) + else if (ast->dshow_block_align) return (len + ast->dshow_block_align - 1) / ast->dshow_block_align; else return 1; @@ -449,6 +450,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; @@ -456,7 +458,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; } @@ -687,6 +692,23 @@ static int avi_read_header(AVFormatContext *s) default: av_log(s, AV_LOG_INFO, "unknown stream type %X\n", tag1); } + + if (ast->sample_size < 0) { + if (s->error_recognition & AV_EF_EXPLODE) { + av_log(s, AV_LOG_ERROR, + "Invalid sample_size %d at stream %d\n", + ast->sample_size, + stream_index); + goto fail; + } + av_log(s, AV_LOG_WARNING, + "Invalid sample_size %d at stream %d " + "setting it to 0\n", + ast->sample_size, + stream_index); + 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) { @@ -773,6 +795,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; @@ -801,7 +829,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, 0); + ret = ff_get_wav_header(s, pb, st->codec, size, 0); if (ret < 0) return ret; ast->dshow_block_align = st->codec->block_align; @@ -838,7 +866,8 @@ static int avi_read_header(AVFormatContext *s) st->codec->codec_id = AV_CODEC_ID_ADPCM_IMA_AMV; ast->dshow_block_align = 0; } - if (st->codec->codec_id == AV_CODEC_ID_AAC && ast->dshow_block_align <= 4 && ast->dshow_block_align) { + if (st->codec->codec_id == AV_CODEC_ID_AAC && ast->dshow_block_align <= 4 && ast->dshow_block_align || + st->codec->codec_id == AV_CODEC_ID_MP2 && ast->dshow_block_align <= 4 && ast->dshow_block_align) { av_log(s, AV_LOG_DEBUG, "overriding invalid dshow_block_align of %d\n", ast->dshow_block_align); ast->dshow_block_align = 0; } @@ -1543,7 +1572,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 537c11f6b4..3cb8c820f0 100644 --- a/libavformat/aviobuf.c +++ b/libavformat/aviobuf.c @@ -359,6 +359,8 @@ static inline int put_str16(AVIOContext *s, const char *str, const int be) invalid: av_log(s, AV_LOG_ERROR, "Invaid UTF8 sequence in avio_put_str16%s\n", be ? "be" : "le"); err = AVERROR(EINVAL); + if (!*(q-1)) + break; } if (be) avio_wb16(s, 0); @@ -800,6 +802,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; @@ -817,6 +820,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 92ce26198d..332edbb7d9 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/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/cache.c b/libavformat/cache.c index 26e68c5130..7cb6c22b36 100644 --- a/libavformat/cache.c +++ b/libavformat/cache.c @@ -145,7 +145,7 @@ static int add_entry(URLContext *h, const unsigned char *buf, int size) return 0; fail: - //we could truncate the file to pos here if pos >=0 but ftruncate isnt available in VS so + //we could truncate the file to pos here if pos >=0 but ftruncate isn't available in VS so //for simplicty we just leave the file a bit larger av_free(entry); av_free(node); @@ -282,6 +282,12 @@ resolve_eof: return ret; } +static int enu_free(void *opaque, void *elem) +{ + av_free(elem); + return 0; +} + static int cache_close(URLContext *h) { Context *c= h->priv_data; @@ -291,6 +297,7 @@ static int cache_close(URLContext *h) close(c->fd); ffurl_close(c->inner); + av_tree_enumerate(c->root, NULL, NULL, enu_free); av_tree_destroy(c->root); return 0; @@ -300,7 +307,7 @@ static int cache_close(URLContext *h) #define D AV_OPT_FLAG_DECODING_PARAM static const AVOption options[] = { - { "read_ahead_limit", "Amount in bytes that may be read ahead when seeking isnt supported, -1 for unlimited", OFFSET(read_ahead_limit), AV_OPT_TYPE_INT, { .i64 = 65536 }, -1, INT_MAX, D }, + { "read_ahead_limit", "Amount in bytes that may be read ahead when seeking isn't supported, -1 for unlimited", OFFSET(read_ahead_limit), AV_OPT_TYPE_INT, { .i64 = 65536 }, -1, INT_MAX, D }, {NULL}, }; diff --git a/libavformat/cafdec.c b/libavformat/cafdec.c index e31c0a52bc..cc6ed0ce9f 100644 --- a/libavformat/cafdec.c +++ b/libavformat/cafdec.c @@ -129,8 +129,12 @@ static int read_kuki_chunk(AVFormatContext *s, int64_t size) avio_skip(pb, size); return AVERROR_INVALIDDATA; } - avio_read(pb, preamble, ALAC_PREAMBLE); + if (avio_read(pb, preamble, ALAC_PREAMBLE) != ALAC_PREAMBLE) { + av_log(s, AV_LOG_ERROR, "failed to read preamble\n"); + return AVERROR_INVALIDDATA; + } + av_freep(&st->codec->extradata); if (ff_alloc_extradata(st->codec, ALAC_HEADER)) return AVERROR(ENOMEM); @@ -144,17 +148,26 @@ static int read_kuki_chunk(AVFormatContext *s, int64_t size) av_freep(&st->codec->extradata); return AVERROR_INVALIDDATA; } - avio_read(pb, st->codec->extradata, ALAC_HEADER); + if (avio_read(pb, st->codec->extradata, ALAC_HEADER) != ALAC_HEADER) { + av_log(s, AV_LOG_ERROR, "failed to read kuki header\n"); + av_freep(&st->codec->extradata); + return AVERROR_INVALIDDATA; + } avio_skip(pb, size - ALAC_PREAMBLE - ALAC_HEADER); } else { AV_WB32(st->codec->extradata, 36); memcpy(&st->codec->extradata[4], "alac", 4); AV_WB32(&st->codec->extradata[8], 0); memcpy(&st->codec->extradata[12], preamble, 12); - avio_read(pb, &st->codec->extradata[24], ALAC_NEW_KUKI - 12); + if (avio_read(pb, &st->codec->extradata[24], ALAC_NEW_KUKI - 12) != ALAC_NEW_KUKI - 12) { + av_log(s, AV_LOG_ERROR, "failed to read new kuki header\n"); + av_freep(&st->codec->extradata); + return AVERROR_INVALIDDATA; + } avio_skip(pb, size - ALAC_NEW_KUKI); } } else { + av_freep(&st->codec->extradata); if (ff_get_extradata(st->codec, pb, size) < 0) return AVERROR(ENOMEM); } 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 f07cfd7e8f..5b8c76f738 100644 --- a/libavformat/concatdec.c +++ b/libavformat/concatdec.c @@ -625,7 +625,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/dashenc.c b/libavformat/dashenc.c index 92b7d6c773..0c75713412 100644 --- a/libavformat/dashenc.c +++ b/libavformat/dashenc.c @@ -494,7 +494,7 @@ static int write_manifest(AVFormatContext *s, int final) } if (c->has_video) { - avio_printf(out, "\t\t\n"); + avio_printf(out, "\t\t\n"); for (i = 0; i < s->nb_streams; i++) { AVStream *st = s->streams[i]; OutputStream *os = &c->streams[i]; @@ -509,7 +509,7 @@ static int write_manifest(AVFormatContext *s, int final) avio_printf(out, "\t\t\n"); } if (c->has_audio) { - avio_printf(out, "\t\t\n"); + avio_printf(out, "\t\t\n"); for (i = 0; i < s->nb_streams; i++) { AVStream *st = s->streams[i]; OutputStream *os = &c->streams[i]; 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 44033563f8..228e6fdca1 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, 0); + ret = ff_get_wav_header(s, pb, ast->codec, fsize, 0); 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 4255363f95..a45f83ec21 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/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 5e8e1b2b5b..8aa9a83938 100644 --- a/libavformat/hls.c +++ b/libavformat/hls.c @@ -903,6 +903,31 @@ static void intercept_id3(struct playlist *pls, uint8_t *buf, pls->is_id3_timestamped = (pls->id3_mpegts_timestamp != AV_NOPTS_VALUE); } +static void update_options(char **dest, const char *name, void *src) +{ + av_freep(dest); + av_opt_get(src, name, 0, (uint8_t**)dest); + if (*dest && !strlen(*dest)) + av_freep(dest); +} + +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; @@ -930,6 +955,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); @@ -937,6 +966,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)) @@ -944,6 +977,8 @@ static int open_input(HLSContext *c, struct playlist *pls) av_log(NULL, AV_LOG_ERROR, "Unable to read key file %s\n", seg->key); } + update_options(&c->cookies, "cookies", uc->priv_data); + av_dict_set(&opts, "cookies", c->cookies, 0); ffurl_close(uc); } else { av_log(NULL, AV_LOG_ERROR, "Unable to open key file %s\n", @@ -1252,22 +1287,13 @@ static int hls_read_header(AVFormatContext *s) // if the URL context is good, read important options we must broker later if (u && u->prot->priv_data_class) { // get the previous user agent & set back to null if string size is zero - av_freep(&c->user_agent); - av_opt_get(u->priv_data, "user-agent", 0, (uint8_t**)&(c->user_agent)); - if (c->user_agent && !strlen(c->user_agent)) - av_freep(&c->user_agent); + update_options(&c->user_agent, "user-agent", u->priv_data); // get the previous cookies & set back to null if string size is zero - av_freep(&c->cookies); - av_opt_get(u->priv_data, "cookies", 0, (uint8_t**)&(c->cookies)); - if (c->cookies && !strlen(c->cookies)) - av_freep(&c->cookies); + update_options(&c->cookies, "cookies", u->priv_data); // get the previous headers & set back to null if string size is zero - av_freep(&c->headers); - av_opt_get(u->priv_data, "headers", 0, (uint8_t**)&(c->headers)); - if (c->headers && !strlen(c->headers)) - av_freep(&c->headers); + update_options(&c->headers, "headers", u->priv_data); } if ((ret = parse_playlist(c, s->filename, NULL, s->pb)) < 0) diff --git a/libavformat/http.c b/libavformat/http.c index 55dcb6ec67..f4ac90c30c 100644 --- a/libavformat/http.c +++ b/libavformat/http.c @@ -77,6 +77,8 @@ typedef struct HTTPContext { int is_akamai; int is_mediagateway; char *cookies; ///< holds newline (\n) delimited Set-Cookie header field values (without the "Set-Cookie: " field name) + /* A dictionary containing cookies keyed by cookie name */ + AVDictionary *cookie_dict; int icy; /* how much data was read since the last ICY metadata packet */ int icy_data_read; @@ -464,6 +466,43 @@ static int parse_icy(HTTPContext *s, const char *tag, const char *p) return 0; } +static int parse_cookie(HTTPContext *s, const char *p, AVDictionary **cookies) +{ + char *eql, *name; + + // duplicate the cookie name (dict will dupe the value) + if (!(eql = strchr(p, '='))) return AVERROR(EINVAL); + if (!(name = av_strndup(p, eql - p))) return AVERROR(ENOMEM); + + // add the cookie to the dictionary + av_dict_set(cookies, name, eql, AV_DICT_DONT_STRDUP_KEY); + + return 0; +} + +static int cookie_string(AVDictionary *dict, char **cookies) +{ + AVDictionaryEntry *e = NULL; + int len = 1; + + // determine how much memory is needed for the cookies string + while (e = av_dict_get(dict, "", e, AV_DICT_IGNORE_SUFFIX)) + len += strlen(e->key) + strlen(e->value) + 1; + + // reallocate the cookies + e = NULL; + if (*cookies) av_free(*cookies); + *cookies = av_malloc(len); + if (!cookies) return AVERROR(ENOMEM); + *cookies[0] = '\0'; + + // write out the cookies + while (e = av_dict_get(dict, "", e, AV_DICT_IGNORE_SUFFIX)) + av_strlcatf(*cookies, len, "%s%s\n", e->key, e->value); + + return 0; +} + static int process_line(URLContext *h, char *line, int line_count, int *new_location) { @@ -535,19 +574,8 @@ static int process_line(URLContext *h, char *line, int line_count, av_free(s->mime_type); s->mime_type = av_strdup(p); } else if (!av_strcasecmp(tag, "Set-Cookie")) { - if (!s->cookies) { - if (!(s->cookies = av_strdup(p))) - return AVERROR(ENOMEM); - } else { - char *tmp = s->cookies; - size_t str_size = strlen(tmp) + strlen(p) + 2; - if (!(s->cookies = av_malloc(str_size))) { - s->cookies = tmp; - return AVERROR(ENOMEM); - } - snprintf(s->cookies, str_size, "%s\n%s", tmp, p); - av_free(tmp); - } + if (parse_cookie(s, p, &s->cookie_dict)) + av_log(h, AV_LOG_WARNING, "Unable to parse '%s'\n", p); } else if (!av_strcasecmp(tag, "Icy-MetaInt")) { s->icy_metaint = strtoll(p, NULL, 10); } else if (!av_strncasecmp(tag, "Icy-", 4)) { @@ -578,12 +606,19 @@ static int get_cookies(HTTPContext *s, char **cookies, const char *path, if (!set_cookies) return AVERROR(EINVAL); + // destroy any cookies in the dictionary. + av_dict_free(&s->cookie_dict); + *cookies = NULL; while ((cookie = av_strtok(set_cookies, "\n", &next))) { int domain_offset = 0; char *param, *next_param, *cdomain = NULL, *cpath = NULL, *cvalue = NULL; set_cookies = NULL; + // store the cookie in a dict in case it is updated in the response + if (parse_cookie(s, cookie, &s->cookie_dict)) + av_log(s, AV_LOG_WARNING, "Unable to parse '%s'\n", cookie); + while ((param = av_strtok(cookie, "; ", &next_param))) { if (cookie) { // first key-value pair is the actual cookie value @@ -691,6 +726,10 @@ static int http_read_header(URLContext *h, int *new_location) if (s->seekable == -1 && s->is_mediagateway && s->filesize == 2000000000) h->is_streamed = 1; /* we can in fact _not_ seek */ + // add any new cookies into the existing cookie string + cookie_string(s->cookie_dict, &s->cookies); + av_dict_free(&s->cookie_dict); + return err; } 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 a8273e282c..2918ef681f 100644 --- a/libavformat/id3v2.c +++ b/libavformat/id3v2.c @@ -205,7 +205,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/img2dec.c b/libavformat/img2dec.c index 8c5e9d5d56..046b962501 100644 --- a/libavformat/img2dec.c +++ b/libavformat/img2dec.c @@ -341,7 +341,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); @@ -439,14 +442,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) @@ -480,18 +486,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/internal.h b/libavformat/internal.h index 76ffcc517e..5dacb45133 100644 --- a/libavformat/internal.h +++ b/libavformat/internal.h @@ -97,6 +97,8 @@ struct AVFormatInternal { AVRational offset_timebase; int inject_global_side_data; + + int avoid_negative_ts_use_pts; }; #ifdef __GNUC__ 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 d233839dab..2f031145fc 100644 --- a/libavformat/isom.h +++ b/libavformat/isom.h @@ -197,6 +197,7 @@ typedef struct MOVContext { 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 64d31e0ee6..103507df4c 100644 --- a/libavformat/jvdec.c +++ b/libavformat/jvdec.c @@ -54,7 +54,7 @@ typedef struct JVDemuxContext { 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 bfa9a718f1..5a138adad4 100644 --- a/libavformat/librtmp.c +++ b/libavformat/librtmp.c @@ -193,6 +193,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/matroska.c b/libavformat/matroska.c index bc5007a433..faa662d09f 100644 --- a/libavformat/matroska.c +++ b/libavformat/matroska.c @@ -99,12 +99,17 @@ const CodecTags ff_mkv_codec_tags[]={ {"" , AV_CODEC_ID_NONE} }; -const CodecMime ff_mkv_mime_tags[] = { - {"text/plain" , AV_CODEC_ID_TEXT}, +const CodecMime ff_mkv_image_mime_tags[] = { {"image/gif" , AV_CODEC_ID_GIF}, {"image/jpeg" , AV_CODEC_ID_MJPEG}, {"image/png" , AV_CODEC_ID_PNG}, {"image/tiff" , AV_CODEC_ID_TIFF}, + + {"" , AV_CODEC_ID_NONE} +}; + +const CodecMime ff_mkv_mime_tags[] = { + {"text/plain" , AV_CODEC_ID_TEXT}, {"application/x-truetype-font", AV_CODEC_ID_TTF}, {"application/x-font" , AV_CODEC_ID_TTF}, {"application/vnd.ms-opentype", AV_CODEC_ID_OTF}, diff --git a/libavformat/matroska.h b/libavformat/matroska.h index 391c56c0aa..344b2c32fa 100644 --- a/libavformat/matroska.h +++ b/libavformat/matroska.h @@ -280,6 +280,7 @@ typedef struct CodecTags{ extern const CodecTags ff_mkv_codec_tags[]; extern const CodecMime ff_mkv_mime_tags[]; +extern const CodecMime ff_mkv_image_mime_tags[]; extern const AVMetadataConv ff_mkv_metadata_conv[]; extern const char * const ff_matroska_video_stereo_mode[MATROSKA_VIDEO_STEREOMODE_TYPE_NB]; extern const char * const ff_matroska_video_stereo_plane[MATROSKA_VIDEO_STEREO_PLANE_COUNT]; diff --git a/libavformat/matroskadec.c b/libavformat/matroskadec.c index 6c0d0d5c15..082d3dd7b4 100644 --- a/libavformat/matroskadec.c +++ b/libavformat/matroskadec.c @@ -1274,15 +1274,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); @@ -1309,15 +1307,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); @@ -1496,7 +1492,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; if (matroska->ctx->flags & AVFMT_FLAG_IGNIDX) @@ -1664,6 +1660,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; @@ -1768,7 +1772,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, 0); + ret = ff_get_wav_header(s, &b, st->codec, track->codec_priv.size, 0); if (ret < 0) return ret; codec_id = st->codec->codec_id; @@ -1859,6 +1863,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) @@ -2004,8 +2020,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; } @@ -2023,7 +2039,9 @@ static int matroska_parse_tracks(AVFormatContext *s) st->codec->channels = track->audio.channels; if (!st->codec->bits_per_coded_sample) st->codec->bits_per_coded_sample = track->audio.bitdepth; - if (st->codec->codec_id != AV_CODEC_ID_AAC) + if (st->codec->codec_id == AV_CODEC_ID_MP3) + st->need_parsing = AVSTREAM_PARSE_FULL; + else if (st->codec->codec_id != AV_CODEC_ID_AAC) st->need_parsing = AVSTREAM_PARSE_HEADERS; if (track->codec_delay > 0) { st->codec->delay = av_rescale_q(track->codec_delay, @@ -2142,20 +2160,41 @@ static int matroska_read_header(AVFormatContext *s) av_dict_set(&st->metadata, "filename", attachments[j].filename, 0); av_dict_set(&st->metadata, "mimetype", attachments[j].mime, 0); st->codec->codec_id = AV_CODEC_ID_NONE; - st->codec->codec_type = AVMEDIA_TYPE_ATTACHMENT; - if (ff_alloc_extradata(st->codec, attachments[j].bin.size)) - break; - memcpy(st->codec->extradata, attachments[j].bin.data, - attachments[j].bin.size); - for (i = 0; ff_mkv_mime_tags[i].id != AV_CODEC_ID_NONE; i++) { - if (!strncmp(ff_mkv_mime_tags[i].str, attachments[j].mime, - strlen(ff_mkv_mime_tags[i].str))) { - st->codec->codec_id = ff_mkv_mime_tags[i].id; + for (i = 0; ff_mkv_image_mime_tags[i].id != AV_CODEC_ID_NONE; i++) { + if (!strncmp(ff_mkv_image_mime_tags[i].str, attachments[j].mime, + strlen(ff_mkv_image_mime_tags[i].str))) { + st->codec->codec_id = ff_mkv_image_mime_tags[i].id; break; } } - attachments[j].stream = st; + + if (st->codec->codec_id != AV_CODEC_ID_NONE) { + st->disposition |= AV_DISPOSITION_ATTACHED_PIC; + st->codec->codec_type = AVMEDIA_TYPE_VIDEO; + + av_init_packet(&st->attached_pic); + if ((res = av_new_packet(&st->attached_pic, attachments[j].bin.size)) < 0) + return res; + memcpy(st->attached_pic.data, attachments[j].bin.data, attachments[j].bin.size); + st->attached_pic.stream_index = st->index; + st->attached_pic.flags |= AV_PKT_FLAG_KEY; + } else { + st->codec->codec_type = AVMEDIA_TYPE_ATTACHMENT; + if (ff_alloc_extradata(st->codec, attachments[j].bin.size)) + break; + memcpy(st->codec->extradata, attachments[j].bin.data, + attachments[j].bin.size); + + for (i = 0; ff_mkv_mime_tags[i].id != AV_CODEC_ID_NONE; i++) { + if (!strncmp(ff_mkv_mime_tags[i].str, attachments[j].mime, + strlen(ff_mkv_mime_tags[i].str))) { + st->codec->codec_id = ff_mkv_mime_tags[i].id; + break; + } + } + attachments[j].stream = st; + } } } @@ -3016,6 +3055,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, diff --git a/libavformat/matroskaenc.c b/libavformat/matroskaenc.c index 0051b9f509..2867c06bb1 100644 --- a/libavformat/matroskaenc.c +++ b/libavformat/matroskaenc.c @@ -545,12 +545,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); @@ -893,14 +896,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); @@ -940,6 +947,7 @@ static int mkv_write_track(AVFormatContext *s, MatroskaMuxContext *mkv, // if there is no mkv-specific codec ID, use VFW mode put_ebml_string(pb, MATROSKA_ID_CODECID, "V_MS/VFW/FOURCC"); mkv->tracks[i].write_dts = 1; + s->internal->avoid_negative_ts_use_pts = 0; } subinfo = start_ebml_master(pb, MATROSKA_ID_TRACKVIDEO, 0); @@ -1265,6 +1273,11 @@ static int mkv_write_attachments(AVFormatContext *s) mimetype = ff_mkv_mime_tags[i].str; break; } + for (i = 0; ff_mkv_image_mime_tags[i].id != AV_CODEC_ID_NONE; i++) + if (ff_mkv_image_mime_tags[i].id == st->codec->codec_id) { + mimetype = ff_mkv_image_mime_tags[i].str; + break; + } } if (!mimetype) { av_log(s, AV_LOG_ERROR, "Attachment stream %d has no mimetype tag and " @@ -1311,8 +1324,10 @@ static int mkv_write_header(AVFormatContext *s) else mkv->mode = MODE_MATROSKAv2; - if (s->avoid_negative_ts < 0) + if (s->avoid_negative_ts < 0) { s->avoid_negative_ts = 1; + s->internal->avoid_negative_ts_use_pts = 1; + } if (mkv->mode != MODE_WEBM || av_dict_get(s->metadata, "stereo_mode", NULL, 0) || @@ -1995,6 +2010,12 @@ static const AVCodecTag additional_video_tags[] = { { AV_CODEC_ID_NONE, 0xFFFFFFFF } }; +static const AVCodecTag additional_subtitle_tags[] = { + { AV_CODEC_ID_DVB_SUBTITLE, 0xFFFFFFFF }, + { AV_CODEC_ID_HDMV_PGS_SUBTITLE, 0xFFFFFFFF }, + { AV_CODEC_ID_NONE, 0xFFFFFFFF } +}; + #define OFFSET(x) offsetof(MatroskaMuxContext, x) #define FLAGS AV_OPT_FLAG_ENCODING_PARAM static const AVOption options[] = { @@ -2032,7 +2053,7 @@ AVOutputFormat ff_matroska_muxer = { AVFMT_TS_NONSTRICT | AVFMT_ALLOW_FLUSH, .codec_tag = (const AVCodecTag* const []){ ff_codec_bmp_tags, ff_codec_wav_tags, - additional_audio_tags, additional_video_tags, 0 + additional_audio_tags, additional_video_tags, additional_subtitle_tags, 0 }, .subtitle_codec = AV_CODEC_ID_ASS, .query_codec = mkv_query_codec, diff --git a/libavformat/mlvdec.c b/libavformat/mlvdec.c index 9d821bb7b3..4416814437 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, 0); + ret = ff_get_wav_header(avctx, pb, ast->codec, 16, 0); if (ret < 0) return ret; size -= 16; @@ -358,6 +358,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 986af57e7c..032e364981 100644 --- a/libavformat/mov.c +++ b/libavformat/mov.c @@ -211,8 +211,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); @@ -220,13 +222,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); @@ -733,7 +739,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)) < 0) + if ((ret = ff_get_wav_header(c->fc, pb, st->codec, atom.size, 0)) < 0) av_log(c->fc, AV_LOG_WARNING, "get_wav_header failed\n"); return ret; @@ -1209,6 +1215,8 @@ static int mov_read_aclr(MOVContext *c, AVIOContext *pb, MOVAtom atom) uint64_t original_size; if (c->fc->nb_streams >= 1) { AVCodecContext *codec = c->fc->streams[c->fc->nb_streams-1]->codec; + if (codec->codec_id == AV_CODEC_ID_H264) + return 0; if (atom.size == 16) { original_size = codec->extradata_size; ret = mov_realloc_extradata(codec, atom); @@ -2289,7 +2297,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; @@ -2600,7 +2608,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; @@ -2626,10 +2634,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; } @@ -2688,13 +2701,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; @@ -3193,7 +3216,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); } @@ -3290,6 +3313,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); @@ -3839,6 +3863,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); @@ -4372,6 +4399,8 @@ static const AVOption mov_options[] = { AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 1, .flags = FLAGS }, { "export_xmp", "Export full XMP metadata", OFFSET(export_xmp), 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/mpegtsenc.c b/libavformat/mpegtsenc.c index cc650bbd29..4440932f38 100644 --- a/libavformat/mpegtsenc.c +++ b/libavformat/mpegtsenc.c @@ -751,11 +751,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 72d8e942d5..1e86318939 100644 --- a/libavformat/mux.c +++ b/libavformat/mux.c @@ -554,10 +554,11 @@ static int write_packet(AVFormatContext *s, AVPacket *pkt) if (s->avoid_negative_ts > 0) { AVStream *st = s->streams[pkt->stream_index]; int64_t offset = st->mux_ts_offset; + int64_t ts = s->internal->avoid_negative_ts_use_pts ? pkt->pts : pkt->dts; - if (s->internal->offset == AV_NOPTS_VALUE && pkt->dts != AV_NOPTS_VALUE && - (pkt->dts < 0 || s->avoid_negative_ts == AVFMT_AVOID_NEG_TS_MAKE_ZERO)) { - s->internal->offset = -pkt->dts; + if (s->internal->offset == AV_NOPTS_VALUE && ts != AV_NOPTS_VALUE && + (ts < 0 || s->avoid_negative_ts == AVFMT_AVOID_NEG_TS_MAKE_ZERO)) { + s->internal->offset = -ts; s->internal->offset_timebase = st->time_base; } @@ -574,15 +575,26 @@ static int write_packet(AVFormatContext *s, AVPacket *pkt) if (pkt->pts != AV_NOPTS_VALUE) pkt->pts += offset; - av_assert2(pkt->dts == AV_NOPTS_VALUE || pkt->dts >= 0 || s->max_interleave_delta > 0); - if (pkt->dts != AV_NOPTS_VALUE && pkt->dts < 0) { - av_log(s, AV_LOG_WARNING, - "Packets poorly interleaved, failed to avoid negative " - "timestamp %s in stream %d.\n" - "Try -max_interleave_delta 0 as a possible workaround.\n", - av_ts2str(pkt->dts), - pkt->stream_index - ); + if (s->internal->avoid_negative_ts_use_pts) { + if (pkt->pts != AV_NOPTS_VALUE && pkt->pts < 0) { + av_log(s, AV_LOG_WARNING, "failed to avoid negative " + "pts %s in stream %d.\n" + "Try -avoid_negative_ts 1 as a possible workaround.\n", + av_ts2str(pkt->dts), + pkt->stream_index + ); + } + } else { + av_assert2(pkt->dts == AV_NOPTS_VALUE || pkt->dts >= 0 || s->max_interleave_delta > 0); + if (pkt->dts != AV_NOPTS_VALUE && pkt->dts < 0) { + av_log(s, AV_LOG_WARNING, + "Packets poorly interleaved, failed to avoid negative " + "timestamp %s in stream %d.\n" + "Try -max_interleave_delta 0 as a possible workaround.\n", + av_ts2str(pkt->dts), + pkt->stream_index + ); + } } } @@ -996,6 +1008,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/mxfdec.c b/libavformat/mxfdec.c index 2e8dd05ab4..5ca444ba19 100644 --- a/libavformat/mxfdec.c +++ b/libavformat/mxfdec.c @@ -1669,6 +1669,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; @@ -2041,7 +2051,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 7d35af4dcc..5e7a8b8f11 100644 --- a/libavformat/mxfenc.c +++ b/libavformat/mxfenc.c @@ -1874,9 +1874,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; @@ -2210,6 +2211,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; } @@ -2263,7 +2268,14 @@ static int mxf_write_footer(AVFormatContext *s) { MXFContext *mxf = s->priv_data; AVIOContext *pb = s->pb; - int err; + int err = 0; + + if (!mxf->header_written || + (s->oformat == &ff_mxf_opatom_muxer && !mxf->body_partition_offset)) { + /* reason could be invalid options/not supported codec/out of memory */ + err = AVERROR_UNKNOWN; + goto end; + } mxf->duration = mxf->last_indexed_edit_unit + mxf->edit_units_count; @@ -2271,10 +2283,10 @@ static int mxf_write_footer(AVFormatContext *s) mxf->footer_partition_offset = avio_tell(pb); if (mxf->edit_unit_byte_count && s->oformat != &ff_mxf_opatom_muxer) { // no need to repeat index if ((err = mxf_write_partition(s, 0, 0, footer_partition_key, 0)) < 0) - return err; + goto end; } else { if ((err = mxf_write_partition(s, 0, 2, footer_partition_key, 0)) < 0) - return err; + goto end; mxf_write_klv_fill(s); mxf_write_index_table_segment(s); } @@ -2287,21 +2299,22 @@ static int mxf_write_footer(AVFormatContext *s) /* rewrite body partition to update lengths */ avio_seek(pb, mxf->body_partition_offset[0], SEEK_SET); if ((err = mxf_write_opatom_body_partition(s)) < 0) - return err; + goto end; } avio_seek(pb, 0, SEEK_SET); if (mxf->edit_unit_byte_count && s->oformat != &ff_mxf_opatom_muxer) { if ((err = mxf_write_partition(s, 1, 2, header_closed_partition_key, 1)) < 0) - return err; + goto end; mxf_write_klv_fill(s); mxf_write_index_table_segment(s); } else { if ((err = mxf_write_partition(s, 0, 0, header_closed_partition_key, 1)) < 0) - return err; + goto end; } } +end: ff_audio_interleave_close(s); av_freep(&mxf->index_entries); @@ -2311,7 +2324,7 @@ static int mxf_write_footer(AVFormatContext *s) mxf_free(s); - return 0; + return err < 0 ? err : 0; } static int mxf_interleave_get_packet(AVFormatContext *s, AVPacket *out, AVPacket *pkt, int flush) diff --git a/libavformat/network.c b/libavformat/network.c index e9eab297e2..57a5b418e7 100644 --- a/libavformat/network.c +++ b/libavformat/network.c @@ -77,8 +77,10 @@ int ff_tls_init(void) if (!CRYPTO_get_locking_callback()) { int i; openssl_mutexes = av_malloc_array(sizeof(pthread_mutex_t), CRYPTO_num_locks()); - if (!openssl_mutexes) + if (!openssl_mutexes) { + avpriv_unlock_avformat(); return AVERROR(ENOMEM); + } for (i = 0; i < CRYPTO_num_locks(); i++) pthread_mutex_init(&openssl_mutexes[i], NULL); CRYPTO_set_locking_callback(openssl_lock); 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 00e86bb50b..e0f106ab5d 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 001d9c8860..cb51511943 100644 --- a/libavformat/nuv.c +++ b/libavformat/nuv.c @@ -172,6 +172,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 ca40063f0d..1dde18829a 100644 --- a/libavformat/oggenc.c +++ b/libavformat/oggenc.c @@ -260,7 +260,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, @@ -268,10 +268,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); + } } } } @@ -282,16 +285,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 7aed8abad3..ca13928f1e 100644 --- a/libavformat/oggparsevp8.c +++ b/libavformat/oggparsevp8.c @@ -82,7 +82,11 @@ static uint64_t vp8_gptopts(AVFormatContext *s, int idx, 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/options_table.h b/libavformat/options_table.h index 40f1e0ae43..00cc9dee45 100644 --- a/libavformat/options_table.h +++ b/libavformat/options_table.h @@ -86,6 +86,7 @@ static const AVOption avformat_options[] = { {"max_interleave_delta", "maximum buffering duration for interleaving", OFFSET(max_interleave_delta), AV_OPT_TYPE_INT64, { .i64 = 10000000 }, 0, INT64_MAX, E }, {"f_strict", "how strictly to follow the standards (deprecated; use strict, save via avconv)", OFFSET(strict_std_compliance), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, INT_MIN, INT_MAX, D|E, "strict"}, {"strict", "how strictly to follow the standards", OFFSET(strict_std_compliance), AV_OPT_TYPE_INT, {.i64 = DEFAULT }, INT_MIN, INT_MAX, D|E, "strict"}, +{"very", "strictly conform to a older more strict version of the spec or reference software", 0, AV_OPT_TYPE_CONST, {.i64 = FF_COMPLIANCE_VERY_STRICT }, INT_MIN, INT_MAX, D|E, "strict"}, {"strict", "strictly conform to all the things in the spec no matter what the consequences", 0, AV_OPT_TYPE_CONST, {.i64 = FF_COMPLIANCE_STRICT }, INT_MIN, INT_MAX, D|E, "strict"}, {"normal", NULL, 0, AV_OPT_TYPE_CONST, {.i64 = FF_COMPLIANCE_NORMAL }, INT_MIN, INT_MAX, D|E, "strict"}, {"unofficial", "allow unofficial extensions", 0, AV_OPT_TYPE_CONST, {.i64 = FF_COMPLIANCE_UNOFFICIAL }, INT_MIN, INT_MAX, D|E, "strict"}, diff --git a/libavformat/rawdec.c b/libavformat/rawdec.c index b903e63fb4..7684e1dd9a 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 399523c777..696b06bc1a 100644 --- a/libavformat/riff.c +++ b/libavformat/riff.c @@ -362,9 +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_PRORES, MKTAG('A', 'P', 'C', 'H') }, - { AV_CODEC_ID_QTRLE, MKTAG('r', 'l', 'e', ' ') }, { AV_CODEC_ID_HQX, MKTAG('C', 'H', 'Q', 'X') }, { AV_CODEC_ID_NONE, 0 } }; diff --git a/libavformat/riff.h b/libavformat/riff.h index ae5ecef4c5..399c52738f 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 big_endian); +int ff_get_wav_header(AVFormatContext *s, AVIOContext *pb, AVCodecContext *codec, int size, int big_endian); 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 f44df1e672..632c58cfd5 100644 --- a/libavformat/riffdec.c +++ b/libavformat/riffdec.c @@ -81,7 +81,8 @@ static void parse_waveformatex(AVIOContext *pb, AVCodecContext *c) } /* "big_endian" values are needed for RIFX file format */ -int ff_get_wav_header(AVIOContext *pb, AVCodecContext *codec, int size, int big_endian) +int ff_get_wav_header(AVFormatContext *s, AVIOContext *pb, + AVCodecContext *codec, int size, int big_endian) { int id; @@ -102,6 +103,14 @@ int ff_get_wav_header(AVIOContext *pb, AVCodecContext *codec, int size, int big_ codec->bit_rate = avio_rb32(pb) * 8; codec->block_align = avio_rb16(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 { @@ -143,7 +152,7 @@ int ff_get_wav_header(AVIOContext *pb, AVCodecContext *codec, int size, int big_ 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 9468d9764f..3506d0712a 100644 --- a/libavformat/rmdec.c +++ b/libavformat/rmdec.c @@ -320,6 +320,8 @@ int ff_rm_read_mdpr_codecdata(AVFormatContext *s, AVIOContext *pb, if (codec_data_size > INT_MAX) return AVERROR_INVALIDDATA; + if (codec_data_size == 0) + return 0; avpriv_set_pts_info(st, 64, 1, 1000); codec_pos = avio_tell(pb); @@ -708,7 +710,7 @@ static int rm_assemble_video_frame(AVFormatContext *s, AVIOContext *pb, int64_t *timestamp) { int hdr; - int seq = 0, pic_num = 0, len2 = 0, pos = 0; //init to silcense compiler warning + int seq = 0, pic_num = 0, len2 = 0, pos = 0; //init to silence compiler warning int type; int ret; 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/rtpdec_jpeg.c b/libavformat/rtpdec_jpeg.c index 2028053536..e8855d0529 100644 --- a/libavformat/rtpdec_jpeg.c +++ b/libavformat/rtpdec_jpeg.c @@ -192,16 +192,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 a09653f340..8492865b4f 100644 --- a/libavformat/rtpdec_xiph.c +++ b/libavformat/rtpdec_xiph.c @@ -88,7 +88,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 1eb01911a8..aa419ca93e 100644 --- a/libavformat/rtpenc.c +++ b/libavformat/rtpenc.c @@ -271,7 +271,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); @@ -561,10 +562,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/rtpenc_mpegts.c b/libavformat/rtpenc_mpegts.c index 5b94e73d82..db1680e069 100644 --- a/libavformat/rtpenc_mpegts.c +++ b/libavformat/rtpenc_mpegts.c @@ -88,17 +88,16 @@ static int rtp_mpegts_write_header(AVFormatContext *s) st->time_base.num = 1; st->time_base.den = 90000; st->codec->codec_id = AV_CODEC_ID_MPEG2TS; - chain->rtp_ctx = rtp_ctx; rtp_ctx->pb = s->pb; if ((ret = avformat_write_header(rtp_ctx, NULL)) < 0) goto fail; - rtp_ctx = NULL; + chain->rtp_ctx = rtp_ctx; return 0; fail: if (mpegts_ctx) { - ffio_free_dyn_buf(&chain->mpegts_ctx->pb); + ffio_free_dyn_buf(&mpegts_ctx->pb); avformat_free_context(mpegts_ctx); } if (rtp_ctx) diff --git a/libavformat/rtsp.c b/libavformat/rtsp.c index 91128e1309..5d1c5a99f2 100644 --- a/libavformat/rtsp.c +++ b/libavformat/rtsp.c @@ -964,6 +964,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/smacker.c b/libavformat/smacker.c index 5dcf4adafe..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++; 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 d34d3d90df..570a4f5439 100644 --- a/libavformat/swfdec.c +++ b/libavformat/swfdec.c @@ -407,10 +407,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/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 17ae300a8f..0e23c1d4fe 100644 --- a/libavformat/utils.c +++ b/libavformat/utils.c @@ -418,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; @@ -1597,6 +1600,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; @@ -2377,7 +2383,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) @@ -2818,10 +2824,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; } @@ -3053,7 +3063,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) { @@ -4118,6 +4128,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/wavdec.c b/libavformat/wavdec.c index 410c2ec1f9..2bdff1979c 100644 --- a/libavformat/wavdec.c +++ b/libavformat/wavdec.c @@ -119,7 +119,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); } } @@ -134,7 +134,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, wav->rifx); + ret = ff_get_wav_header(s, pb, (*st)->codec, size, wav->rifx); if (ret < 0) return ret; handle_stream_probing(*st); @@ -684,7 +684,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, 0); + ret = ff_get_wav_header(s, pb, st->codec, size - 24, 0); 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 e226690283..e8f6196a5e 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, 0); + int ret = ff_get_wav_header(s, pb, st->codec, size, 0); if (ret < 0) return NULL; } else { diff --git a/libavformat/xmv.c b/libavformat/xmv.c index 45c24642cc..14d007a3e0 100644 --- a/libavformat/xmv.c +++ b/libavformat/xmv.c @@ -549,16 +549,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 075a85a2e7..264f94e9d2 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, 0); + ret = ff_get_wav_header(s, pb, st->codec, size, 0); if (ret < 0) return ret; st->need_parsing = AVSTREAM_PARSE_NONE; diff --git a/libavutil/arm/asm.S b/libavutil/arm/asm.S index 1d0e5a97b2..e9b0bcabdb 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 852c1de850..11f88efaf3 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 0d54c7970a..caec50eff7 100644 --- a/libavutil/dict.c +++ b/libavutil/dict.c @@ -107,7 +107,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/imgutils.c b/libavutil/imgutils.c index a8bc18d025..ef0e67154b 100644 --- a/libavutil/imgutils.c +++ b/libavutil/imgutils.c @@ -219,6 +219,14 @@ int av_image_alloc(uint8_t *pointers[4], int linesizes[4], if (desc->flags & AV_PIX_FMT_FLAG_PAL || desc->flags & AV_PIX_FMT_FLAG_PSEUDOPAL) avpriv_set_systematic_pal2((uint32_t*)pointers[1], pix_fmt); + if ((desc->flags & AV_PIX_FMT_FLAG_PAL || + desc->flags & AV_PIX_FMT_FLAG_PSEUDOPAL) && + pointers[1] - pointers[0] > linesizes[0] * h) { + /* zero-initialize the padding before the palette */ + memset(pointers[0] + linesizes[0] * h, 0, + pointers[1] - pointers[0] - linesizes[0] * h); + } + return ret; } 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 5fd2395dab..da291fb970 100644 --- a/libavutil/mem.c +++ b/libavutil/mem.c @@ -266,7 +266,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/mips/asmdefs.h b/libavutil/mips/asmdefs.h index 4d2922c951..fdf82a0107 100644 --- a/libavutil/mips/asmdefs.h +++ b/libavutil/mips/asmdefs.h @@ -24,12 +24,10 @@ * assembly (rather than from within .s files). */ -#ifndef AVCODEC_MIPS_ASMDEFS_H -#define AVCODEC_MIPS_ASMDEFS_H +#ifndef AVUTIL_MIPS_ASMDEFS_H +#define AVUTIL_MIPS_ASMDEFS_H -#include - -#if _MIPS_SIM == _ABI64 +#if defined(_ABI64) && _MIPS_SIM == _ABI64 # define PTRSIZE " 8 " # define PTRLOG " 3 " # define PTR_ADDU "daddu " diff --git a/libavutil/mips/float_dsp_mips.c b/libavutil/mips/float_dsp_mips.c index a45568778a..b3a812ceeb 100644 --- a/libavutil/mips/float_dsp_mips.c +++ b/libavutil/mips/float_dsp_mips.c @@ -188,10 +188,10 @@ static void vector_fmul_window_mips(float *dst, const float *src0, "lwc1 %[wj3], -12(%[win_j]) \n\t" "lwc1 %[s0], 8(%[src0_i]) \n\t" "lwc1 %[s01], 12(%[src0_i]) \n\t" - "addiu %[src1_j],-16 \n\t" - "addiu %[win_i], 16 \n\t" - "addiu %[win_j], -16 \n\t" - "addiu %[src0_i], 16 \n\t" + PTR_ADDIU "%[src1_j],-16 \n\t" + PTR_ADDIU "%[win_i],16 \n\t" + PTR_ADDIU "%[win_j],-16 \n\t" + PTR_ADDIU "%[src0_i],16 \n\t" "swc1 %[temp], 0(%[dst_i]) \n\t" /* dst[i] = s0*wj - s1*wi; */ "swc1 %[temp1], 0(%[dst_j]) \n\t" /* dst[j] = s0*wi + s1*wj; */ "swc1 %[temp2], 4(%[dst_i]) \n\t" /* dst[i+1] = s01*wj1 - s11*wi1; */ @@ -208,8 +208,8 @@ static void vector_fmul_window_mips(float *dst, const float *src0, "swc1 %[temp1], -8(%[dst_j]) \n\t" /* dst[j-2] = s0*wi2 + s1*wj2; */ "swc1 %[temp2], 12(%[dst_i]) \n\t" /* dst[i+2] = s01*wj3 - s11*wi3; */ "swc1 %[temp3], -12(%[dst_j]) \n\t" /* dst[j-3] = s01*wi3 + s11*wj3; */ - "addiu %[dst_i], 16 \n\t" - "addiu %[dst_j], -16 \n\t" + PTR_ADDIU "%[dst_i],16 \n\t" + PTR_ADDIU "%[dst_j],-16 \n\t" "bne %[win_i], %[lp_end], 1b \n\t" : [temp]"=&f"(temp), [temp1]"=&f"(temp1), [temp2]"=&f"(temp2), [temp3]"=&f"(temp3), [src0_i]"+r"(src0_i), [win_i]"+r"(win_i), diff --git a/libavutil/opencl.c b/libavutil/opencl.c index a3866cae1d..36cb6fe81d 100644 --- a/libavutil/opencl.c +++ b/libavutil/opencl.c @@ -611,9 +611,6 @@ void av_opencl_uninit(void) } opencl_ctx.context = NULL; } - for (i = 0; i < opencl_ctx.kernel_code_count; i++) { - opencl_ctx.kernel_code[i].is_compiled = 0; - } free_device_list(&opencl_ctx.device_list); end: if (opencl_ctx.init_count <= 0) diff --git a/libavutil/opt.c b/libavutil/opt.c index 092446b02b..99827aef6f 100644 --- a/libavutil/opt.c +++ b/libavutil/opt.c @@ -1463,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 41bbe5d236..acd33e2b91 100644 --- a/libavutil/pixdesc.c +++ b/libavutil/pixdesc.c @@ -2147,6 +2147,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) @@ -2162,6 +2163,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/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 9d8978204e..6a11811a42 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 @@ -1003,7 +1004,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; @@ -1028,7 +1029,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 ca09e67f4d..248062aab8 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; iin_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/swresample-test.c b/libswresample/swresample-test.c index 8859e9412c..7e2854da7c 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 9baccd2b6e..f3c922bc26 100644 --- a/libswresample/swresample.c +++ b/libswresample/swresample.c @@ -23,6 +23,7 @@ #include "audioconvert.h" #include "libavutil/avassert.h" #include "libavutil/channel_layout.h" +#include "libavutil/internal.h" #include @@ -86,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); @@ -152,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); @@ -164,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; @@ -245,6 +256,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 @@ -253,7 +268,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 @@ -267,16 +283,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); @@ -298,8 +326,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; @@ -326,12 +356,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){ @@ -606,7 +643,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) @@ -647,8 +685,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 77ec9bb1bb..4034e7c879 100644 --- a/libswresample/swresample_internal.h +++ b/libswresample/swresample_internal.h @@ -112,6 +112,13 @@ struct SwrContext { int used_ch_count; ///< number of used input channels (mapped channel count if channel_map, otherwise in.ch_count) int 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 */ @@ -186,7 +193,7 @@ void swri_rematrix_free(SwrContext *s); int swri_rematrix(SwrContext *s, AudioData *out, AudioData *in, int len, int mustcopy); int 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/libswscale/input.c b/libswscale/input.c index 7b3b7060e6..5dcae8cd7d 100644 --- a/libswscale/input.c +++ b/libswscale/input.c @@ -818,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) @@ -846,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) \ { \ @@ -1168,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; @@ -1184,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; 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 91bfe180a9..3324c39b8c 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 55f683f5be..4181308152 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 256 +#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 490290f795..228cbba756 100644 --- a/libswscale/swscale_unscaled.c +++ b/libswscale/swscale_unscaled.c @@ -1059,6 +1059,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]; @@ -1069,7 +1071,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; } @@ -1105,6 +1110,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]; @@ -1119,7 +1126,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; } @@ -1243,6 +1253,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 df8d0a92ca..e770283af6 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++) { @@ -825,8 +825,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); @@ -837,11 +835,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; @@ -856,6 +867,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); @@ -1052,6 +1066,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; @@ -1174,6 +1194,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; @@ -1417,9 +1438,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 @@ -1528,6 +1549,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 1d682ba57c..e81f3f6f31 100644 --- a/libswscale/yuv2rgb.c +++ b/libswscale/yuv2rgb.c @@ -776,7 +776,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]; @@ -833,10 +834,10 @@ av_cold int ff_yuv2rgb_c_init_tables(SwsContext *c, const int inv_table[4], return AVERROR(ENOMEM); switch (bpp) { case 1: - ALLOC_YUV_TABLE(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; } @@ -848,60 +849,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; - ALLOC_YUV_TABLE(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; - ALLOC_YUV_TABLE(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; - ALLOC_YUV_TABLE(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: @@ -909,30 +910,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); - ALLOC_YUV_TABLE(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: - ALLOC_YUV_TABLE(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; } @@ -951,20 +952,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; - ALLOC_YUV_TABLE(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 824d5f48d1..ed36a68440 100755 --- a/tests/fate-run.sh +++ b/tests/fate-run.sh @@ -42,7 +42,7 @@ compare(){ } do_tiny_psnr(){ - psnr=$(tests/tiny_psnr "$1" "$2" $cmp_unit $cmp_shift 0) + psnr=$(tests/tiny_psnr "$1" "$2" $cmp_unit $cmp_shift 0) || return 1 val=$(expr "$psnr" : ".*$3: *\([0-9.]*\)") size1=$(expr "$psnr" : '.*bytes: *\([0-9]*\)') size2=$(expr "$psnr" : '.*bytes:[ 0-9]*/ *\([0-9]*\)') 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 b7e510c272..bcb1189fb9 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/tools/graph2dot.c b/tools/graph2dot.c index 5552b3400d..23c7331dc3 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)); @@ -181,7 +181,7 @@ int main(int argc, char **argv) } 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; }