diff --git a/CREDITS b/CREDITS index e29f0b853c..f1aea93d6b 100644 --- a/CREDITS +++ b/CREDITS @@ -1,6 +1,6 @@ -See the Git history of the project (git://source.ffmpeg.org/ffmpeg) to +See the Git history of the project (https://git.ffmpeg.org/ffmpeg) to get the names of people who have contributed to FFmpeg. To check the log, you can type the command "git log" in the FFmpeg source directory, or browse the online repository at -http://source.ffmpeg.org. +https://git.ffmpeg.org/ffmpeg diff --git a/Changelog b/Changelog index a96e350e09..dbe2432a79 100644 --- a/Changelog +++ b/Changelog @@ -1,7 +1,896 @@ Entries are sorted chronologically from oldest to youngest within each release, releases are sorted from youngest to oldest. -version : +version 4.4.6: + avcodec/takdec: Check remaining space for first predictors + avcodec/svq3: Check there are bits left before decompression + avcodec/sonic: Check num_taps + avformat/mov: reject negative ELST durations + avformat/avidec: Ignore duplicate GAB2 + avcodec/h264_mb: Fix tmp_cr for arm + avcodec/vorbisdec: Dont treat overread as error + libpostproc: check minimum size + avformat/hls: Fix flash1.bogulus.cfd support + avformat/hls: Split allowed_segment_extensions off allowed_extensions + avformat/hls: Fix Youtube AAC + avformat/hls: add fmp4 to allowed_extensions + avformat/hls: Add ec3 to allowed_extensions + avformat/hls: Add cmfv and cmfa to allowed_extensions + configure: Clearer documentation for "disable-safe-bitstream-reader" + swscale/output: Fix integer overflow in yuv2gbrp_full_X_c() + avcodec/libtheora: fix setting keyframe_mask + avfilter/buffersrc: check for valid sample rate + doc: replace http/git by https urls + Update for 4.4.6 + configure: update copyright year + avformat/hls: Partially revert "reduce default max reload to 3" + avformat/hls: Fix twitter + libavformat/hls: Be more restrictive on mpegts extensions + avformat/hls: .ts is always ok even if its a mov/mp4 + avformat/hls: Print input format in error message + avformat/hls: Be more picky on extensions + avformat: add ff_match_url_ext() + avfilter/bwdif: account for chroma sub-sampling in min size calculation + avformat/iff: Check that we have a stream in read_dst_frame() + avformat/mlvdec: fix size checks + avformat/mxfdec: Check edit unit for overflow in mxf_set_current_edit_unit() + avcodec/h263dec: Check against previous dimensions instead of coded + avformat/mxfdec: Check avio_read() success in mxf_decrypt_triplet() + avcodec/huffyuvdec: Initialize whole output for decode_gray_bitstream() + avformat/ipmovie: Check signature_buffer read + avformat/wtvdec: Initialize buf + avcodec/cbs_vp9: Initialize VP9RawSuperframeIndex + avformat/vqf: Propagate errors from add_metadata() + avformat/vqf: Check avio_read() in add_metadata() + avformat/dashdec: Check whitelist + avutil/avstring: dont mess with NULL pointers in av_match_list() + avfilter/vf_v360: Fix NULL pointer use + avcodec/mpegvideo_enc: Check FLV1 resolution limits + avcodec/ffv1enc: Fix handling of 32bit unsigned symbols + avcodec/vc1dec: Clear block_index in vc1_decode_reset() + avcodec/aacsbr_template: Clear n_q on error + swscale/output: Fix undefined overflow in yuv2rgba64_full_X_c_template() + avfilter/af_pan: Fix sscanf() use + avfilter/vf_addroi: Add missing NULL termination to addroi_var_names[]() + avformat/rmdec: check that buf if completely filled + avcodec/hapdec: Clear tex buffer + avformat/mxfdec: Check that key was read sucessfull + avformat/rpl: Fix check for negative values + avformat/mlvdec: Check avio_read() + avcodec/utils: Fix block align overflow for ADPCM_IMA_WAV + avformat/matroskadec: Check pre_ns for overflow + avutil/timecode: Avoid fps overflow in av_timecode_get_smpte_from_framenum() + avcodec/webp: Check ref_x/y + avcodec/ilbcdec: Initialize tempbuff2 + avformat/dxa: check bpc + swscale/slice: clear allocated memory in alloc_lines() + avcodec/mjpegdec: Disallow progressive bayer images + avformat/icodec: fix integer overflow with nb_pal + doc/developer: Document relationship between git accounts and MAINTAINERS + avformat/vividas: Check avio_read() for failure + avformat/ilbc: Check avio_read() for failure + avformat/nistspheredec: Clear buffer + avformat/mccdec: Initialize and check rate.den + INSTALL: explain the circular dependency issue and solution + avformat/mpegts: Initialize predefined_SLConfigDescriptor_seen + avformat/mxfdec: Fix overflow in midpoint computation + swscale/output: used unsigned for bit accumulation + avcodec/rangecoder: only perform renorm check/loop for callers that need it + avcodec/ffv1dec: Fix end computation with ec=2 + avcodec/ffv1enc: Prevent generation of files with broken slices + avformat/matroskadec: Check desc_bytes so bits fit in 64bit + avcodec/ffv1enc: Correct error message about unsupported version + avcodec/ffv1enc: Slice combination is unsupported + avcodec/ffv1enc: 2Pass mode is not possible with golomb coding + avcodec/ffv1enc: Fix >8bit context size + avcodec/xan: Add basic input size check + avcodec/svq3: Check for minimum size input + avcodec/eacmv: Check input size for intra frames + avcodec/jfdctint_template: use unsigned z* in row_fdct() + avformat/mxfdec: Check timecode for overflow + avformat/mxfdec: More offset_temp checks + swscale/output: Fix undefined integer overflow in yuv2rgba64_2_c_template() + swscale/swscale: Use unsigned operation to avoid undefined behavior + avcodec/vc2enc: basic sanity check on slice_max_bytes + avformat/mvdec: Check if name was fully read + avcodec/wmavoice: Do not use uninitialized pitch[0] + avformat/argo_brp: Check that ASF chunk header is completely read + avcodec/notchlc: Check bytes left before reading + avcodec/vc1_block: propagate error codes + avformat/apetag: Check APETAGEX + avcodec/avcodec: Warn about data returned from get_buffer*() + avcodec/aic: Clear slice_data + avcodec/vc1dec: Clear mb_type_base and ttblk_base + avcodec/shorten: clear padding + avformat/mpeg: Check an avio_read() for failure + avcodec/mvha: Clear remaining space after inflate() + avformat/segafilm: Set keyframe + avcodec/sga: av_assert1 check init_get_bits8() + avcodec/dxva2: initialize hr in ff_dxva2_common_end_frame() + avcodec/dxva2: initialize validate + avcodec/dxva2: Initialize ConfigBitstreamRaw + avcodec/dxva2: Initialize dxva_size and check it + avfilter/vf_xfade: Compute w2, h2 with float + avfilter/vf_v360: Assert that vf was initialized + avfilter/vf_tonemap_opencl: Dereference after NULL check + avfilter/vf_xfade_opencl: Check ff_inlink_consume_frame() for failure + avformat/lmlm4: Eliminate some AVERROR(EIO) + avformat/wtvdec: Check length of read mpeg2_descriptor + avformat/wtvdec: clear sectors + avcodec/parser: ensure input padding is zeroed + avformat/img2dec: Clear padding data after EOF + avformat/wavdec: Check if there are 16 bytes before testing them + avcodec/snow: Fix off by 1 error in run_buffer + avcodec/utils: apply the same alignment to YUV410 as we do to YUV420 for snow + lsws/ppc/yuv2rgb_altivec: Fix build in non-VSX environments with Clang v2 + lsws/ppc/yuv2rgb_altivec: Fix build in non-VSX environments with Clang + avformat/mov: (v4) fix get_eia608_packet + configure: Improve the check for the rsync --contimeout option + rtmpproto: Avoid rare crashes in the fail: codepath in rtmp_open + vp9: recon: Use emulated edge to prevent buffer overflows + arm: vp9mc: Load only 12 pixels in the 4 pixel wide horizontal filter + aarch64: vp9mc: Load only 12 pixels in the 4 pixel wide horizontal filter + avcodec/libx265: unbreak build for X265_BUILD >= 213 + lavc/libx265: unbreak build for X265_BUILD >= 210 + avformat/libzmq: fix check for zmq protocol prefix + configure: improve check for POSIX ioctl + configure: restore autodetection of v4l2 and fbdev + configure: use just the pkg-config for sndio + libavcodec/arm/mlpdsp_armv5te: fix label format to work with binutils 2.43 + +version 4.4.5: + avcodec/cfhdenc: Height of 16 is not supported + avcodec/cfhdenc: Allocate more space + avcodec/vaapi_encode: Check hwctx + avcodec/proresdec: Consider negative bits left + avcodec/hevc/hevcdec: Do not allow slices to depend on failed slices + avutil/slicethread: Check pthread_*_init() for failure + avutil/frame: Check log2_crop_align + avutil/buffer: Check ff_mutex_init() for failure + avformat/xmv: Check this_packet_size + avformat/ty: rec_size seems to only need 32bit + avformat/tty: Check avio_size() + avformat/siff: Basic pkt_size check + avformat/sauce: Check avio_size() for failure + avformat/sapdec: Check ffurl_get_file_handle() for error + avformat/nsvdec: Check asize for PCM + avformat/mp3dec: Check header_filesize + avformat/mp3dec; Check for avio_size() failure + avformat/mov: Use 64bit for str_size + avformat/mm: Check length + avformat/hnm: Check *chunk_size + avformat/hlsenc: Check ret + avformat/bintext: Check avio_size() return + avformat/asfdec_o: Check size of index object + avfilter/vf_scale: Check ff_scale_adjust_dimensions() for failure + avfilter/scale_eval: Use 64bit, check values in ff_scale_adjust_dimensions() + avfilter/vf_lut3d: Check av_scanf() + avfilter/vf_deshake_opencl: Ensure that the first iteration initializes the best variables + swscale/output: Fix integer overflows in yuv2rgba64_X_c_template + avformat/mxfdec: Reorder elements of expression in bisect loop + avcodec/pnmdec: Use 64bit for input size check + avcodec/utvideoenc: Use unsigned shift to build flags + avcodec/vc2enc: Fix overflows with storing large values + avcodec/mpegvideo_enc: Do not duplicate pictures on shifting + avdevice/dshow_capture: Fix error handling in ff_dshow_##prefix##_Create() + avcodec/tiff: Check value on positive signed targets + avfilter/vf_bm3d: Dont round MSE2SSE to an integer + avdevice/dshow: Check device_filter_unique_name before use + avdevice/dshow_filter: Use wcscpy_s() + avcodec/flac_parser: Assert that we do not overrun the link_penalty array + avcodec/pixlet: Simplify pfx computation + avcodec/motion_est: Fix score squaring overflow + avcodec/loco: Check loco_get_rice() for failure + avcodec/loco: check get_ur_golomb_jpegls() for failure + avcodec/imm4: check cbphi for error + avcodec/iff: Use signed count + avcodec/golomb: Assert that k is in the supported range for get_ur/sr_golomb() + avcodec/golomb: Document return for get_ur_golomb_jpegls() and get_sr_golomb_flac() + avcodec/dxv: Fix type in get_opcodes() + avcodec/cri: Check length + avcodec/xsubdec: Check parse_timecode() + avutil/imgutils: av_image_check_size2() ensure width and height fit in 32bit + doc/examples/mux: remove nop + avcodec/proresenc_kostya: use unsigned alpha for rotation + avformat/rtmppkt: Simplify and deobfuscate amf_tag_skip() slightly + avformat/rmdec: use 64bit for audio_framesize checks + avutil/hwcontext_d3d11va: correct sizeof IDirect3DSurface9 + avutil/hwcontext_d3d11va: correct sizeof AVD3D11FrameDescriptor + doc/examples/vaapi_encode: Try to check fwrite() for failure + avformat/tls_schannel: Initialize ret + avformat/subfile: Assert that whence is a known case + avformat/subfile: Merge if into switch() + avformat/rtsp: Check that lower transport is handled in one of the if() + avformat/rtsp: initialize reply1 + avformat/rtsp: use < 0 for error check + avformat/rtpenc_vc2hq: Check sizes + avfilter/af_aderivative: Free out on error + avfilter/af_pan: check nb_output_channels before use + cbs_av1: Reject thirty-two zero bits in uvlc code + avfilter/af_mcompand: compute half frequency in double + tools/coverity: Phase 1 study of anti-halicogenic for coverity av_rescale() + avfilter/vf_avgblur: Check plane instead of AVFrame + avformat/rdt: Check pkt_len + avformat/mpeg: Check len in mpegps_probe() + avdevice/dshow: Check ICaptureGraphBuilder2_SetFiltergraph() for failure + avcodec/mfenc: check IMFSample_ConvertToContiguousBuffer() for failure + avcodec/vc1_loopfilter: Factor duplicate code in vc1_b_h_intfi_loop_filter() + avformat/img2dec: assert no pipe on ts_from_file + avcodec/cbs_jpeg: Try to move the read entity to one side in a test + avformat/mov: Check edit list for overflow + fftools/ffmpeg: Check read() for failure + swscale/output: Avoid undefined overflow in yuv2rgb_write_full() + swscale/output: alpha can become negative after scaling, use multiply + avcodec/targaenc: Allocate space for the palette + avcodec/r210enc: Use av_rescale for bitrate + avcodec/jfdctint_template: Fewer integer anomalies + avcodec/snowenc: MV limits due to mv_penalty table size + avformat/mxfdec: Check container_ul->desc before use + MAINTAINERS: Update the entries for the release maintainer for FFmpeg + configure: update copyright year + avfilter/vf_rotate: Check ff_draw_init2() return value + avformat/matroskadec: Assert that num_levels is non negative + avformat/libzmq: Check av_strstart() + avformat/img2dec: Move DQT after unrelated if() + avdevice/xcbgrab: Check sscanf() return + fftools/cmdutils: Add protective () to FLAGS + avformat/sdp: Check before appending "," + avcodec/ilbcdec: Remove dead code + avcodec/vp8: Check cond init + avcodec/vp8: Check mutex init + avcodec/notchlc: Check init_get_bits8() for failure + avcodec/tests/dct: Use 64bit in intermediate for error computation + avcodec/scpr3: Check add_dec() for failure + avcodec/rv34: assert that size is not 0 in rv34_gen_vlc_ext() + avcodec/wavpackenc: Use unsigned for potential 31bit shift + avcodec/tests/jpeg2000dwt: Use 64bit in comparission + avcodec/tests/jpeg2000dwt: Use 64bit in err2 computation + avformat/fwse: Remove always false expression + avcodec/sga: Make it clear that the return is intentionally not checked + avformat/asfdec_f: Use 64bit for preroll computation + avformat/argo_asf: Use 64bit in offset intermediate + avformat/ape: Use 64bit for final frame size + avcodec/tiff: Assert init_get_bits8() success in unpack_gray() + avcodec/tiff: Assert init_get_bits8() success in horizontal_fill() + swscale/yuv2rgb: Use 64bit for brightness computation + avutil/tests/opt: Check av_set_options_string() for failure + avutil/tests/dict: Check av_dict_set() before get for failure + avdevice/dshow: fix badly indented line + avcodec/mscc & mwsc: Check loop counts before use + avcodec/mpegvideo_enc: Fix potential overflow in RD + avcodec/mpeg4videodec: assert impossible wrap points + avcodec/mpeg12dec: Use 64bit in bit computation + avcodec/vble: Check av_image_get_buffer_size() for failure + avcodec/vp3: Replace check by assert + avcodec/jpeg2000dec: remove ST=3 case + avcodec/qsvdec: Check av_image_get_buffer_size() for failure + avcodec/exr: Fix preview overflow + avcodec/fmvc: remove dead assignment + avcodec/h264_slice: Remove dead sps check + avcodec/lpc: copy levenson coeffs only when they have been computed + avutil/tests/base64: Check with too short output array + libavutil/base64: Try not to write over the array end + avcodec/cbs_av1: Avoid shift overflow + doc/examples/demux_decode: Simplify loop + avcodec/mpegvideo_enc: Fix 1 line and one column images + swscale/output: Fix integer overflow in yuv2rgba64_full_1_c_template() + swscale/output: Fix integer overflow in yuv2rgba64_1_c_template + avformat/mxfdec: Check body_offset + avformat/kvag: Check sample_rate + avcodec/ac3_parser: Check init_get_bits8() for failure + avcodec/pngdec: Check last AVFrame before deref + avcodec/hevcdec: Check ref frame + doc/examples/vaapi_transcode: Simplify loop + avfilter/vf_thumbnail_cuda: Set ret before checking it + avfilter/signature_lookup: Dont copy uninitialized stuff around + avfilter/signature_lookup: Fix 2 differences to the refernce SW + lavc/vp9: reset segmentation fields when segmentation isn't enabled + configure: enable ffnvcodec, nvenc, nvdec for FreeBSD + avcodec/x86/vp3dsp_init: Set correct function pointer, fix crash + avutil/ppc/cpu: Also use the machdep.altivec sysctl on NetBSD + avutil/ppc/cpu: Use proper header for OpenBSD PPC CPU detection + lavd/v4l2: Use proper field type for second parameter of ioctl() with BSD's + configure: use pkg-config for sndio + fate/subtitles: Ignore line endings for sub-scc test + avformat/mxfdec: Check index_edit_rate + swscale/utils: Fix xInc overflow + avcodec/exr: Dont use 64bits to hold 6bits + avcodec/exr: Check for remaining bits in huf_unpack_enc_table() + avformat/mpegts: Reset local nb_prg on add_program() failure + avformat/mxfdec: Make edit_unit_byte_count unsigned + avformat/movenc: Check that cts fits in 32bit + avformat/mxfdec: Check first case of offset_temp computation for overflow + avfilter/vf_signature: Dont crash on no frames + avformat/westwood_vqa: Fix 2g packets + avformat/matroskadec: Check timescale + avformat/wavdec: satuarte next_tag_ofs, data_end + avformat/sbgdec: Check for negative duration + avformat/rpl: Use 64bit for total_audio_size and check it + avformat/timecode: use 64bit for intermediate for rounding in fps_from_frame_rate() + avformat/jacosubdec: Use 64bit for abs + avformat/concatdec: Check user_duration sum + avcodec/truemotion1: Height not being a multiple of 4 is unsupported + avcodec/hcadec: do not set hfr_group_count to invalid values + avformat/concatdec: clip outpoint - inpoint overflow in get_best_effort_duration() + avformat/jacosubdec: clarify code + avformat/cafdec: Check that data chunk end fits within 64bit + avformat/iff: Saturate avio_tell() + 12 + avformat/dxa: Adjust order of operations around block align + avformat/cafdec: dont seek beyond 64bit + avformat/id3v2: read_uslt() check for the amount read + avcodec/proresenc_kostya: Remove bug similarity text + avcodec/vorbisdec: Check remaining data in vorbis_residue_decode_internal() + libswscale/utils: Fix bayer to yuvj + swscale/swscale: Check srcSliceH for bayer + swscale/utils: Allocate more dithererror + avcodec/indeo3: Round dimensions up in allocate_frame_buffers() + avutil/rational: Document what is to be expected from av_d2q() of doubles representing rational numbers + avfilter/signature_lookup: Do not dereference NULL pointers after malloc failure + avfilter/signature_lookup: dont leave uncleared pointers in sll_free() + avcodec/mpegvideo_enc: Use ptrdiff_t for stride + libavformat/hlsenc.c: Populate OTI using AAC profile in write_codec_attr. + avcodec/mpegvideo_enc: Dont copy beyond the image + avfilter/vf_minterpolate: Check pts before division + avformat/flacdec: Avoid double AVERRORS + avfilter/vf_vidstabdetect: Avoid double AVERRORS + avfilter/vf_swaprect: round coordinates down + avfilter/vf_swaprect: Use height for vertical variables + avfilter/vf_swaprect: assert that rectangles are within memory + avfilter/af_alimiter: Check nextpos before use + avfilter/af_stereowiden: Check length + avfilter/vf_weave: Fix odd height handling + avfilter/vf_gradfun: Do not overread last line + avformat/mov: do not set sign bit for chunk_offsets + avcodec/jpeglsdec: Check Jpeg-LS LSE + configure: Enable section_data_rel_ro for FreeBSD and NetBSD aarch64 / arm + avformat/mov: Check if a key is longer than the atom containing it + avcodec/nvdec: reset bitstream_len/nb_slices when resetting bitstream pointer + avformat/mov: don't abort on duplicate Mastering Display Metadata boxes + avcodec/x86/mathops: clip constants used with shift instructions within inline assembly + avcodec/av1dec: fix matrix coefficients exposed by codec context + avcodec/nvdec: don't free NVDECContext->bitstream + avcodec/av1dec: Fix resolving zero divisor + avformat/mov: Ignore duplicate ftyp + avformat/mov: Fix integer overflow in mov_read_packet(). + seek: Fix crashes in ff_seek_frame_binary if built with latest Clang 14 + avcodec/4xm: Check for cfrm exhaustion + avformat/mov: Disallow FTYP after streams + doc/html: fix styling issue with Texinfo 7.0 + doc/html: support texinfo 7.0 + doc/t2h.pm: fix missing TOC with texinfo 6.8 and above + doc/t2h.pm: fix missing CSS with texinfo 6.8 and above + avformat/matroskadec: Fix declaration-after-statement warnings + avformat/rtsp: Use rtsp_st->stream_index + avcodec/jpeg2000dec: Check image offset + avformat/mxfdec: Check klv offset + libavutil/ppc/cpu.c: check that AT_HWCAP2 is defined + avcodec/h2645_parse: Avoid EAGAIN + avcodec/xvididct: Make c* unsigned to avoid undefined overflows + avformat/tmv: Check video chunk size + avcodec/h264_parser: saturate dts a bit + avformat/asfdec_f: Saturate presentation time in marker + avformat/xwma: sanity check bits_per_coded_sample + avformat/matroskadec: Check prebuffered_ns for overflow + avformat/wavdec: Check left avio_tell for overflow + avformat/tta: Better totalframes check + avformat/rpl: Check for number_of_chunks overflow + avformat/mov: compute absolute dts difference without overflow in mov_find_next_sample() + avformat/jacosubdec: Check timeres + avformat/jacosubdec: avoid signed integer overflows in get_shift() + avformat/jacosubdec: Factorize code in get_shift() a bit + avcodec/escape124: Do not return random numbers + avcodec/apedec: Fix an integer overflow in predictor_update_filter() + avformat/avs: Check if return code is representable + avcodec/lcldec: Make PNG filter addressing match the code afterwards + avformat/westwood_vqa: Check chunk size + avformat/sbgdec: Check for period overflow + avformat/concatdec: Check in/outpoint for overflow + avcodec/xvididct: Fix integer overflow in idct_row() + avcodec/celp_math: avoid overflow in shift + tools/target_dec_fuzzer: Adjust threshold for rtv1 + avformat/hls: reduce default max reload to 3 + avformat/format: Stop reading data at EOF during probing + avcodec/huffyuvdec: avoid undefined behavior with get_vlc2() failure + avcodec/cscd: Fix "CamStudio Lossless Codec 1.0" gzip files + avcodec/cscd: Check for CamStudio Lossless Codec 1.0 behavior in end check of LZO files + avcodec/hevcdec: Fix undefined memcpy() + avcodec/mpeg4videodec: more unsigned in amv computation + avcodec/tta: fix signed overflow in decorrelate + avcodec/apedec: Fix 48khz 24bit below insane level + avcodec/apedec: Fix CRC for 24bps and bigendian + avcodec/xvididct: Fix integer overflow in idct_row() + avformat/avr: Check sample rate + avcodec/jpeg2000dec: Check for reduction factor and image offset + avutil/softfloat: Basic documentation for av_sincos_sf() + avutil/softfloat: fix av_sincos_sf() + avcodec/utils: fix 2 integer overflows in get_audio_frame_duration() + avcodec/hevcdec: Avoid null pointer dereferences in MC + avcodec/takdsp: Fix integer overflows + avcodec: Ignoring errors is only possible before the input end + avcodec/noise_bsf: Check for wrapped frames + avformat/oggparsetheora: clip duration within 64bit + avformat/wavdec: Check that smv block fits in available space + avcodec/tiff: add a zero DNG_LINEARIZATION_TABLE check + avcodec/tak: Check remaining bits in ff_tak_decode_frame_header() + avcodec/sonic: Fix two undefined integer overflows + avcodec/utils: the IFF_ILBM implementation assumes that there are a multiple of 16 allocated + avcodec/exr: Cleanup befor return + avcodec/pngdec: Do not pass AVFrame into global header decode + avcodec/pngdec: remove AVFrame argument from decode_iccp_chunk() + avcodec/vorbisdec: Check codebook float values to be finite + avcodec/g2meet: Replace fake allocation avoidance for framebuf + avcodec/lcldec: More space for rgb24 + avcodec/lcldec: Support 4:1:1 and 4:2:2 with odd width + libavcodec/lcldec: width and height should not be unsigned + avcodec/escape124: Check that blocks are allocated before use + avcodec/huffyuvdec: Fix undefined behavior with shift + avcodec/j2kenc: Replace RGB24 special case by generic test + avcodec/j2kenc: Replace BGR48 / GRAY16 test by test for number of bits + avcodec/j2kenc: simplify pixel format setup + avcodec/j2kenc: Fix funky bpno errors on decoding + avcodec/j2kenc: remove misleading pred value + avcodec/j2kenc: fix 5/3 DWT identifer + avcodec/vp3: Check width to avoid assertion failure + avcodec/g729postfilter: Limit shift in long term filter + avcodec/vdpau_mpeg4: fix order of quant matrix coefficients + avcodec/vdpau_mpeg12: fix order of quant matrix coefficients + avcodec/nvdec_mpeg4: fix order of quant matrix coefficients + avcodec/nvdec_mpeg2: fix order of quant matrix coefficients + avcodec/libsvtav1: remove compressed_ten_bit_format and simplify alloc_buffer + configure: account for openssl3 license change + + +version 4.4.4: +- avcodec/tests/snowenc: Fix 2nd test +- avcodec/tests/snowenc: return a failure if DWT/IDWT mismatches +- avcodec/snowenc: Fix visual weight calculation +- avcodec/tests/snowenc: unbreak DWT tests +- avcodec/vp3: Add missing check for av_malloc +- avformat/nutdec: Add check for avformat_new_stream +- avcodec/mpeg12dec: Check input size +- avcodec/escape124: Fix some return codes +- avcodec/escape124: fix signdness of end of input check +- Use https for repository links +- avcodec/rpzaenc: stop accessing out of bounds frame +- avcodec/motionpixels: Mask pixels to valid values +- avcodec/xpmdec: Check size before allocation to avoid truncation +- avcodec/bink: Avoid undefined out of array end pointers in binkb_decode_plane() +- avcodec/bink: Fix off by 1 error in ref end +- avcodec/utils: Ensure linesize for SVQ3 +- avcodec/utils: allocate a line more for VC1 and WMV3 +- avcodec/videodsp_template: Adjust pointers to avoid undefined pointer things +- avcodec/pngdec: Check deloco index more exactly +- avcodec/ffv1dec: Check that num h/v slices is supported +- avformat/mov: Check samplesize and offset to avoid integer overflow +- avcodec/pictordec: Remove mid exit branch +- avcodec/eac3dec: avoid float noise in fixed mode addition to overflow +- avcodec/utils: use 32pixel alignment for bink +- avcodec/scpr3: Check bx +- avcodec/012v: Order operations for odd size handling +- avcodec/eatgq: : Check index increments in tgq_decode_block() +- avcodec/scpr: Test bx before use +- avformat/mxfdec: Use 64bit in remainder +- avcodec/sunrast: Fix maplength check +- avcodec/wavpack: Avoid undefined shift in get_tail() +- avcodec/wavpack: Check for end of input in wv_unpack_dsd_high() +- avformat/id3v2: Check taglen in read_uslt() +- avcodec/tiff: Ignore tile_count +- avcodec/ffv1dec: restructure slice coordinate reading a bit +- avcodec/mlpdec: Check max matrix instead of max channel in noise check +- swscale/input: Use more unsigned intermediates +- avcodec/alsdec: The minimal block is at least 7 bits +- avformat/replaygain: avoid undefined / negative abs +- swscale/output: Bias 16bps output calculations to improve non overflowing range +- avcodec/speedhq: Check buf_size to be big enough for DC +- avcodec/ffv1dec: Fail earlier if prior context is corrupted +- avcodec/nvenc: fix b-frame DTS behavior with fractional framerates +- avfilter/vf_untile: swap the chroma shift values used for plane offsets +- avcodec/nvenc: fix vbv buffer size in cq mode +- avcodec/mjpegenc: take into account component count when writing the SOF header size +- swscale: aarch64: Fix yuv2rgb with negative stride + +version 4.4.3: +- avformat/vividas: Check packet size +- configure: link to libatomic when it's present +- avcodec/dstdec: Check for overflow in build_filter() +- avformat/spdifdec: Use 64bit to compute bit rate +- avformat/rpl: Use 64bit for duration computation +- avformat/xwma: Use av_rescale() for duration computation +- avformat/sdsdec: Use av_rescale() to avoid intermediate overflow in duration calculation +- avformat/sbgdec: Check ts_int in genrate_intervals +- avformat/rmdec: check tag_size +- avformat/nutdec: Check fields +- avformat/flvdec: Use 64bit for sum_flv_tag_size +- avformat/jacosubdec: Fix overflow in get_shift() +- avformat/dxa: avoid bpc overflows +- avformat/cafdec: Check that nb_frasmes fits within 64bit +- avformat/asfdec_o: Limit packet offset +- avformat/ape: Check frames size +- avformat/icodec: Check nb_pal +- avformat/aiffdec: Use 64bit for block_duration use +- avformat/aiffdec: Check block_duration +- avformat/mxfdec: only probe max run in +- avformat/mxfdec: Check run_in is within 65536 +- avcodec/mjpegdec: Check for unsupported bayer case +- avcodec/apedec: Fix integer overflow in filter_3800() +- avcodec/tta: Check 24bit scaling for overflow +- avcodec/mobiclip: Check quantizer for overflow +- avcodec/exr: Check preview psize +- avcodec/tiff: Fix loop detection +- libavformat/hls: Free keys +- avcodec/fmvc: Move frame allocation to a later stage +- avfilter/vf_showinfo: remove backspaces +- avcodec/speedhq: Check width +- avcodec/bink: disallow odd positioned scaled blocks +- avformat/asfdec_o: limit recursion depth in asf_read_unknown() +- doc/git-howto.texi: Document commit signing +- libavcodec/8bps: Check that line lengths fit within the buffer +- avcodec/midivid: Perform lzss_uncompress() before ff_reget_buffer() +- libavformat/iff: Check for overflow in body_end calculation +- avformat/avidec: Prevent entity expansion attacks +- avcodec/h263dec: Sanity check against minimal I/P frame size +- avcodec/hevcdec: Check s->ref in the md5 path similar to hwaccel +- avcodec/mpegaudiodec_template: use unsigned shift in handle_crc() +- avformat/subviewerdec: Make read_ts() more flexible +- avcodec/mjpegdec: bayer and rct are incompatible +- MAINTAINERS: Add ED25519 key for signing my commits in the future +- avcodec/hevc_filter: copy_CTB() only within width&height +- avcodec/tiff: Check tile_length and tile_width +- avcodec/mss4: Check image size with av_image_check_size2() +- avformat/flvdec: Check for EOF in index reading +- avformat/nutdec: Check get_packetheader() in mainheader +- avformat/asfdec_f: Use 64bit for packet start time +- avcodec/exr: Check x/ysize +- tools/target_dec_fuzzer: Adjust threshold for MMVIDEO +- avcodec/lagarith: Check dst/src in zero run code +- avcodec/h264dec: Skip late SEI +- avcodec/sbrdsp_fixed: Fix integer overflows in sbr_qmf_deint_neg_c() +- avfilter/vf_signature: Fix integer overflow in filter_frame() +- avformat/rtsp: break on unknown protocols +- avcodec/hevcdsp_template: stay within tables in sao_band_filter() +- avcodec/tiff: Check pixel format types for dng +- avcodec/qpeldsp: copy less for the mc0x cases +- avformat/aaxdec: Check for empty segments +- avcodec/ffv1dec: Limit golomb rice coded slices to width 8M +- avformat/iff: simplify duration calculation +- avcodec/wnv1: Check for width =1 +- avcodec/ffv1dec_template: fix indention +- avformat/sctp: close socket on errors +- avcodec/aasc: Fix indention +- avcodec/qdrw: adjust max colors to array size +- avcodec/alacdsp: Make intermediates unsigned +- avformat/aiffdec: cleanup size handling for extreem cases +- avformat/matroskadec: avoid integer overflows in SAR computation +- avcodec/jpeglsdec: fix end check for xfrm +- avcodec/cdgraphics: limit scrolling to the line +- avformat/hls: Limit start_seq_no to one bit less +- avformat/aiffdec: avoid integer overflow in get_meta() +- avformat/ape: more bits in size for less overflows +- avformat/aviobuf: Check buf_size in ffio_ensure_seekback() +- avformat/bfi: Check offsets better +- avformat/asfdec_f: Check packet_frag_timestamp +- avcodec/texturedspenc: Fix indexing in color distribution determination +- avformat/act: Check ff_get_wav_header() for failure +- avcodec/libxavs2: Improve r redundancy in occured +- avformat/libzmq: Improve r redundancy in occured +- avfilter/vsrc_mandelbrot: Check for malloc failure +- avfilter/vf_frei0r: Copy to frame allocated according to frei0r requirements +- avfilter/video: Add ff_default_get_video_buffer2() to set specific alignment +- avformat/genh: Check sample rate +- configure: bump year +- lavc/videotoolbox: do not pass AVCodecContext to decoder output callback +- lavc/pthread_frame: always transfer stashed hwaccel state +- avcodec/arm/sbcenc: avoid callee preserved vfp registers +- avfilter/vf_scale: overwrite the width and height expressions with the original values +- lavc/pthread_frame: avoid leaving stale hwaccel state in worker threads +- configure: extend SDL check to accept all 2.x versions +- lavf/tls_mbedtls: add support for mbedtls version 3 + +version 4.4.2: +- fate: update reference files after the recent dash manifest muxer changes +- avformat/webmdashenc: fix on-demand profile string +- Update for FFmpeg 4.4.2 +- avcodec/exr: Avoid signed overflow in displayWindow +- avcodec/diracdec: avoid signed integer overflow in global mv +- avcodec/takdsp: Fix integer overflow in decorrelate_sf() +- avcodec/apedec: fix a integer overflow in long_filter_high_3800() +- avfilter/vf_subtitles: pass storage size to libass +- avformat/aqtitledec: Skip unrepresentable durations +- avformat/cafdec: Do not store empty keys in read_info_chunk() +- avformat/mxfdec: Do not clear array in mxf_read_strong_ref_array() before writing +- avformat/mxfdec: Check for avio_read() failure in mxf_read_strong_ref_array() +- avformat/mxfdec: Check count in mxf_read_strong_ref_array() +- avformat/hls: Check target_duration +- avcodec/pixlet: Avoid signed integer overflow in scaling in filterfn() +- avformat/matroskadec: Check pre_ns +- avcodec/sonic: Use unsigned for predictor_k to avoid undefined behavior +- avcodec/libuavs3d: Check ff_set_dimensions() for failure +- avcodec/mjpegbdec: Set buf_size +- avformat/matroskadec: Use rounded down duration in get_cue_desc() check +- avcodec/argo: Check packet size +- avcodec/g729_parser: Check channels +- avformat/avidec: Check height +- avformat/rmdec: Better duplicate tags check +- avformat/mov: Disallow empty sidx +- avformat/argo_asf: Fix order of operations in error check in argo_asf_write_trailer() +- avformat/matroskadec: Check duration +- avformat/mov: Corner case encryption error cleanup in mov_read_senc() +- avcodec/jpeglsdec: Fix if( code style +- avcodec/jpeglsdec: Check get_ur_golomb_jpegls() for error +- avcodec/motion_est: fix indention of ff_get_best_fcode() +- avcodec/motion_est: Fix xy indexing on range violation in ff_get_best_fcode() +- avformat/hls: Use unsigned for iv computation +- avcodec/jpeglsdec: Increase range for N in ls_get_code_runterm() by using unsigned +- avformat/matroskadec: Check desc_bytes +- avformat/utils: Fix invalid NULL pointer operation in ff_parse_key_value() +- avformat/matroskadec: Fix infinite loop with bz decompression +- avformat/mov: Check size before subtraction +- avcodec/cfhd: Avoid signed integer overflow in coeff +- avcodec/apedec: Fix integer overflows in predictor_update_3930() +- avcodec/apedec: fix integer overflow in 8bit samples +- avformat/flvdec: timestamps cannot use the full int64 range +- avcodec/tiff: Remove messing with jpeg context +- avcodec/tiff: Use ff_set_dimensions() for setting up mjpeg context dimensions +- avcodec/tiff: Pass max_pixels to mjpeg context +- avcodec/vqavideo: reset accounting on error +- avcodec/alacdsp: fix integer overflow in decorrelate_stereo() +- avformat/4xm: Check for duplicate track ids +- avformat/4xm: Consider max_streams on reallocating tracks array +- avformat/mov: Check next offset in mov_read_dref() +- avformat/vivo: Favor setting fps from explicit fractions +- avformat/vivo: Do not use the general expression evaluator for parsing a floating point value +- avformat/mxfdec: Check for duplicate mxf_read_index_entry_array() +- avcodec/apedec: Change avg to uint32_t +- avformat/mxfdec: Check component_depth in mxf_get_color_range() +- avformat/mov: Disallow duplicate smdm +- avformat/mov: Check for EOF in mov_read_glbl() +- avcodec/vp3: Check version in all cases when VP4 code is not built +- avformat/mov: Check channels for mov_parse_stsd_audio() +- avformat/avidec: Check read_odml_index() for failure +- avformat/aiffdec: Use av_rescale() for bitrate +- avformat/aiffdec: sanity check block_align +- avformat/aiffdec: Check sample_rate +- avcodec/libdav1d: free the Dav1dData packet on dav1d_send_data() failure +- avcodec/zmbvenc: Fix memleak upon init error +- avcodec/dnxhdenc: Fix segfault when using too many slice threads +- avcodec/wma(dec|enc): Fix memleaks upon allocation error +- avfilter/avfilter: Actually error out on init error +- avcodec/opus_silk: Remove wrong size information in function declaration +- avformat/omadec: Don't output uninitialized values +- avformat/jacosubenc: Fix writing extradata +- avformat/cafenc: Fix memleak when trailer is never written +- avformat/cafenc: Don't segfault upon allocation error +- avformat/cafenc: Fix potential integer overflow +- avformat/movenc: Limit ism_lookahead to a sane value +- avutil/utils: Remove racy check from avutil_version() +- avformat/sccdec: Don't use uninitialized data, fix crash, simplify logic +- avformat/subtitles: Honour ff_subtitles_read_line() documentation +- avformat/tee: Fix leak of FIFO-options dictionary +- avformat/tee: Fix leak of strings +- avcodec/rasc: Fix potential use of uninitialized value +- avfilter/vf_w3fdif: Fix segfault on allocation error +- avfilter/af_surround: Fix memleaks upon allocation error +- avfilter/af_vibrato: Fix segfault upon allocation error +- avfilter/aeval: Fix leak of expressions upon reallocation error +- avdevice/xv: Increase array size +- avfilter/asrc_flite: Fix use-after-frees +- avfilter/asrc_flite: Don't segfault when using list_voices option +- Revert "avfilter/vf_idet: reduce noisyness if the filter has been auto inserted" +- avformat/matroskadec: Don't unnecessarily reduce aspect ratio +- avcodec/h263: Fix global-buffer-overflow with noout flag2 set +- avcodec/vaapi_encode: Fix segfault upon closing uninitialized encoder +- avcodec/movtextenc: Fix infinite loop due to variable truncation +- avcodec/libopenh264dec: Increase array sizes, fix stack-buffer overread +- avcodec/libkvazaar: Increase array size +- avformat/aadec: Don't use the same loop counter in inner and outer loop +- avformat/moflex: Don't use uninitialized timebase for data stream +- lavf/udp: do not return an uninitialized value from udp_open() +- avcodec/nvenc: zero-initialize NV_ENC_REGISTER_RESOURCE struct +- configure: Add missing libshine->mpegaudioheader dependency +- avcodec/Makefile: Add missing entry for ADPCM_IMA_AMV_ENCODER +- avcodec/Makefile: Only compile nvenc.o if needed +- avcodec/av1_vaapi: improve decode quality +- avcodec/av1_vaapi: enable segmentation features +- avcodec/av1_vaapi: setting 2 output surface for film grain +- avcodec/vaapi: increase av1 decode pool size +- avcodec/dxva2_av1: fix global motion params +- avcodec/av1_vaapi: add gm params valid check +- avcodec/av1dec: support setup shear process +- avcodec/av1: extend some definitions in spec section 3 +- cbs_av1: fix incorrect data type +- avcodec/libdav1d: let libdav1d choose optimal max frame delay +- avcodec/libdav1d: pass auto threads value to libdav1d + +version 4.4.1: +- avcodec/flac_parser: Consider AV_INPUT_BUFFER_PADDING_SIZE +- avcodec/ttadsp: Fix integer overflows in tta_filter_process_c() +- avutil/mathematics: Document av_rescale_rnd() behavior on non int64 results +- avcodec/utils: Ensure 8x8 alignment for ARGO in avcodec_align_dimensions2() +- avformat/matroskadec: Reset state also on failure in matroska_reset_status() +- avformat/wavdec: Check smv_block_size +- avformat/rmdec: Check for multiple audio_stream_info +- avcodec/apedec: Use 64bit to avoid overflow +- avcodec/apedec: Fix undefined integer overflow in long_filter_ehigh_3830() +- oavformat/avidec: Check offset in odml +- avformat/mpegts: use actually read packet size in mpegts_resync special case +- fftools/ffmpeg: Fix crash when flushing non-fully setup output stream +- avfilter/scale_npp: fix non-aligned output frame dimensions +- Revert "avformat/hlsenc: compute video_keyframe_size after write keyframe" +- Changelog: update +- swscale/alphablend: Fix slice handling +- avcodec/apedec: Fix integer overflow in filter_fast_3320() +- avformat/mov: Fix last mfra check +- avcodec/mxpegdec: Check for AVDISCARD_ALL +- avcodec/flicvideo: Check remaining bytes in FLI*COPY +- avcodec/utils: ARGO writes 4x4 blocks without regard to the image dimensions +- avcodec/cbs_h265_syntax_template: Limit sps_num_palette_predictor_initializer_minus1 to 127 +- avcodec/snowdec: Maintain avmv buffer +- avcodec/mpeg12dec: Do not put mpeg_f_code into an invalid state on error return +- avcodec/mpegvideo_enc: Limit bitrate tolerance to the representable +- avcodec/apedec: Fix integer overflow in intermediate +- avformat/mvdec: Do not set invalid sample rate +- avformat/sbgdec: Check for t0 overflow in expand_tseq() +- avformat/rmdec: Use 64bit for intermediate for DEINT_ID_INT4 +- avformat/sbgdec: Check opt_duration and start for overflow +- avcodec/exr: Fix undefined integer multiplication +- avformat/mov: Check for duplicate clli +- avformat/utils: Ignore negative duration in codec_info_duration computation +- avformat/jacosubdec: Check for min in t overflow in get_shift() +- avformat/mxfdec: check channel number in mxf_get_d10_aes3_packet() +- (origin/release/4.4) avcodec/wmadec: handle run_level_decode error +- avcodec/wma: Return specific error code +- avcodec/dxva2_av1: fix superres_denom parameter +- avcodec/libdav1d: fix compilation after recent libdav1d API changes +- Changelog: update +- avcodec/utils: don't return negative values in av_get_audio_frame_duration() +- avcodec/jpeg2000dec: Check that atom header is within bytsetream +- avcodec/apedec: Fix 2 integer overflows in filter_3800() +- avcodec/xpmdec: Move allocations down after more error checks +- avcodec/argo: Move U, fix shift +- avformat/mov: Check dts for overflow in mov_read_trun() +- avformat/avidec: Use 64bit for frame number in odml index parsing +- avcodec/mjpegbdec: Skip SOS on AVDISCARD_ALL as does mjpeg +- avcodec/mjpegdec: Check for bits left in mjpeg_decode_scan_progressive_ac() +- avformat/adtsenc: return value check for init_get_bits in adts_decode_extradata +- avcodec/webp: Check available space in loop in decode_entropy_coded_image() +- avcodec/h264dec: use picture parameters in ff_print_debug_info2() +- avcodec/vc1dec: ff_print_debug_info() does not support WMV3 field_mode +- avcodec/frame_thread_encoder: Free AVCodecContext structure on error during init +- avcodec/faxcompr: Check for end of input in cmode == 1 in decode_group3_2d_line() +- avcodec/vc1dec: Disable error concealment for *IMAGE +- avcodec/sbrdsp_fixed: Fix negation overflow in sbr_neg_odd_64_c() +- avcodec/argo: Check for even dimensions +- avformat/wtvdec: Check for EOF before seeking back in parse_media_type() +- avformat/mpc8: Check first keyframe position for overflow +- avcodec/exr: Check ac_count +- avformat/wavdec: Use 64bit in new_pos computation +- avformat/sbgdec: Check for overflow in timestamp preparation +- avformat/dsicin: Check packet size for overflow +- avformat/dsfdec: Change order of operations in bitrate computation +- avformat/bfi: check nframes +- avformat/avidec: fix position overflow in avi_load_index() +- avformat/asfdec_f: Check sizeX against padding +- avformat/aiffdec: Check for size overflow in header parsing +- avcodec/aaccoder: Add minimal bias in search_for_ms() +- avformat/mov: Fix incorrect overflow detection in mov_read_sidx() +- avformat/mov: Avoid undefined overflow in time_offset calculation +- avfilter/af_drmeter: Check that there is data +- avfilter/vf_fftdnoiz: Use lrintf() in export_row8() +- avfilter/vf_mestimate: Check b_count +- avformat/mov: do not ignore errors in mov_metadata_hmmt() +- avformat/mxfdec: Check size for shrinking +- avcodec/dnxhddec: check and propagate function return value +- swscale/slice: Fix wrong return on error +- avcodec/aacdec_template: Avoid some invalid values to be set by decode_audio_specific_config_gb() +- swscale/slice: Check slice for allocation failure +- avformat/matroskadec: Fix handling of huge default durations +- avcodec/lpc: check for zero err in normalization in compute_lpc_coefs() +- avcodec/j2kenc: Check for av_strtok() failure +- avformat/ftp: Check for av_strtok() failure +- tools/cws2fws: Check read() for failure +- avcodec/cpia: Fix missing src_size update +- avcodec/exr: Better size checks +- avcodec/clearvideo: Check tile_size to be not too large +- avcodec/utils: Use 64bit for intermediate in AV_CODEC_ID_ADPCM_THP* duration calculation +- avformat/aaxdec: Check avio_seek() in header reading +- avcodec/hevc_sei: Use get_bits_long() for time_offset_value +- avformat/rmdec: Check old_format len for overflow +- avformat/realtextdec: Check the pts difference before using it for the duration computation +- avformat/qcp: Avoid negative nb_rates +- avformat/pp_bnk: Use 64bit in bitrate computation +- avformat/nutdec: Check tmp_size +- avformat/msf: Check that channels doesnt overflow during extradata construction +- avformat/subtitles: Check pts difference before use +- avformat/mpc8: Check for position overflow in mpc8_handle_chunk() +- avformat/mccdec: Fix overflows in num/den +- avformat/iff: Use 64bit in duration computation +- avformat/dxa: Check fps to be within the supported range more precissely +- avcodec/iff: Only write palette to plane 1 if its PAL8 +- avformat/tta: Check for EOF in index reading loop +- avfilter/vf_scale: set the RGB matrix coefficients in case of RGB +- avfilter/vf_scale: reset color matrix in case of identity & non-RGB +- ffmpeg: fix order between field order autodetection and override +- avcodec/h264_slice: clear old slice POC values on parsing failure +- avfilter/f_metadata: do not return the frame early if there is no metadata +- ffbuild: Avoid using the --preprocessor argument to windres +- avcodec/crystalhd: signal that the decoder sets all output frame properties +- avcodec/cuviddec: signal that the decoder sets all output frame properties +- avcodec/decode: reindent after the previous commit +- avcodec/decode: add an internal codec flag to signal a decoder sets all output frame properties +- avcodec/decode: fetch packets from the pkt_props FIFO on every frame returned +- Update missed irc links +- avformat/rpl: The associative law doesnt hold for signed integers in C +- avcodec/faxcompr: Check available bits in decode_uncompressed() +- avcodec/faxcompr: Check if bits are available before reading in cmode == 9 || cmode == 10 +- avformat/utils: Avoid overflow in codec_info_duration computation for subtitles +- avformat/utils: check dts/duration to be representable before using them +- avcodec/utils: do "calc from frame_bytes, channels, and block_align" in 64bit +- avcodec/ttadata: Add sentinel at the end of ff_tta_shift_1 +- avformat/mov: Check for duplicate mdcv +- avfilter/vf_dctdnoiz: Check threads +- avfilter/vf_ciescope: Fix undefined behavior in rgb_to_xy() with black +- avcodec/dpx: fix off by 1 in bits_per_color check +- avformat/rpl: Check for EOF and zero framesize +- avcodec/vc2enc: Check for non negative slice bounds +- avformat/rpl: Use 64bit in bitrate computation and check it +- avcodec/mpegvideo_enc: Reset stuffing bits if they are not supported +- avcodec/svq1enc: Do not print debug RD value before it has been computed +- avcodec/aacpsy: Check bandwidth +- avcodec/aacenc: Do not divide by lambda_count if it is 0 +- avcodec/aacenc: Use FLT_EPSILON for lambda minimum +- avfilter/vf_yadif: Fix handing of tiny images +- avfilter/vf_vmafmotion: Check dimensions +- avformat/movenc: Check pal_size before use +- avcodec/lpc: Avoid floating point division by 0 +- avcodec/aacpsy: Avoid floating point division by 0 of norm_fac +- avcodec/aacenc: Avoid 0 lambda +- avcodec/exr: More strictly check dc_count +- avcodec/exr: x/ymax cannot be INT_MAX +- avformat/avio: Check av_opt_copy() for failure +- avformat/moflex: Remove unneeded format variable +- avformat/fifo: check for flushed packets and timeshift +- avcodec/clearvideo: Check for 0 tile_shift +- avcodec/vc1: Check remaining bits in ff_vc1_parse_frame_header() +- avformat/mov: Ignore duplicate CoLL +- avformat/mov: Limit nb_chapter_tracks to input size +- avformat/utils: Use 64bit earlier in r_frame_rate check +- avcodec/alsdec: Fix decoding error with mono audio files +- avformat/mvdec: Check sample rate in parse_audio_var() +- avcodec/faxcompr: Check for end of bitstream in decode_group3_1d_line() and decode_group3_2d_line() +- avcodec/utils: treat PAL8 for jpegs similar to other colorspaces +- avcodec/jpeglsdec: Set alpha plane in PAL8 so image is not 100% transparent +- avformat/asfdec_o: Use ff_get_extradata() +- avformat/id3v2: Check end for overflow in id3v2_parse() +- avformat/mxfdec: Fix file position addition +- avformat/wtvdec: Improve size overflow checks in parse_chunks() +- avcodec/faxcompr: Check remaining bits on error in decode_group3_1d_line() +- avformat/mov: check for pts overflow in mov_read_sidx() +- avcodec/utils: Check ima wav duration for overflow +- avcodec/rv10: Execute whole size check earlier for rv20 +- avformat/cafdec: Check channels +- avcodec/exr: increase vlc depth +- avcodec/dpx: Check bits_per_color earlier +- avformat/mvi: Check audio_data_size to be non negative +- avcodec/nvenc: disable s12m timestamps by default +- aarch64: hevc_idct: Fix overflows in idct_dc +- avcodec/vaapi_av1: pass full buffer size for each tile +- avcodec/videotoolboxenc: #define TARGET_CPU_ARM64 to 0 if not provided by the SDK +- lavc/pngdec: fix updating reference frames for APNG_DISPOSE_OP_BACKGROUND +- ffmpeg: return no chosen output if an uninitialized stream is unavailable +- avcodec/h263, h263data: Move ff_h263_init_rl_inter to h263.c +- configure: Add missing mpegvideo dependency for IPU decoder +- avcodec/ttmlenc: Don't confuse capabilities and caps_internal +- avformat/mpegts: add missing sample_rate value to Opus extradata +- avformat/movenc: fix writing dOps atoms +- avcodec/av1_metadata: don't store the inserted TD OBU in stack +- avcodec/nellymoserenc: Fix segfault when using unsupported channels/rate +- avutil/cpu: Use HW_NCPUONLINE to detect # of online CPUs with OpenBSD +- avcodec/nvenc: fix lossless tuning logic +- avfilter/overlay_cuda: check av_buffer_ref result +- avfilter/overlay_cuda: hold explicit reference to hw_device_ctx +- avformat/matroskaenc: Fix leak when writing attachment without filename + +version 4.4: - AudioToolbox output device - MacCaption demuxer - PGX decoder diff --git a/INSTALL.md b/INSTALL.md index 3b220bc6ff..bdf5814014 100644 --- a/INSTALL.md +++ b/INSTALL.md @@ -15,3 +15,11 @@ NOTICE ------ - Non system dependencies (e.g. libx264, libvpx) are disabled by default. + +NOTICE for Package Maintainers +------------------------------ + + - It is recommended to build FFmpeg twice, first with minimal external dependencies so + that 3rd party packages, which depend on FFmpegs libavutil/libavfilter/libavcodec/libavformat + can then be built. And last build FFmpeg with full dependancies (which may in turn depend on + some of these 3rd party packages). This avoids circular dependencies during build. diff --git a/MAINTAINERS b/MAINTAINERS index 3b6cfad4fc..d4e940ba9f 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -583,10 +583,12 @@ wm4 Releases ======== +7.0 Michael Niedermayer +6.1 Michael Niedermayer +5.1 Michael Niedermayer +4.4 Michael Niedermayer +3.4 Michael Niedermayer 2.8 Michael Niedermayer -2.7 Michael Niedermayer -2.6 Michael Niedermayer -2.5 Michael Niedermayer If you want to maintain an older release, please contact us @@ -615,6 +617,7 @@ Jean Delvare 7CA6 9F44 60F1 BDC4 1FD2 C858 A552 6B9B B3CD 4E6A Loren Merritt ABD9 08F4 C920 3F65 D8BE 35D7 1540 DAA7 060F 56DE Lynne FE50 139C 6805 72CA FD52 1F8D A2FE A5F0 3F03 4464 Michael Niedermayer 9FF2 128B 147E F673 0BAD F133 611E C787 040B 0FAB + DD1E C9E8 DE08 5C62 9B3E 1846 B18E 8928 B394 8D64 Nicolas George 24CE 01CE 9ACC 5CEB 74D8 8D9D B063 D997 36E5 4C93 Nikolay Aleksandrov 8978 1D8C FB71 588E 4B27 EAA8 C4F0 B5FC E011 13B1 Panagiotis Issaris 6571 13A3 33D9 3726 F728 AA98 F643 B12E ECF3 E029 diff --git a/RELEASE b/RELEASE index 826fe7119d..b98ff4c483 100644 --- a/RELEASE +++ b/RELEASE @@ -1 +1 @@ -4.4.git +4.4.6 diff --git a/RELEASE_NOTES b/RELEASE_NOTES new file mode 100644 index 0000000000..312ec6f219 --- /dev/null +++ b/RELEASE_NOTES @@ -0,0 +1,15 @@ + + ┌────────────────────────────────────┐ + │ RELEASE NOTES for FFmpeg 4.4 "Rao" │ + └────────────────────────────────────┘ + + The FFmpeg Project proudly presents FFmpeg 4.4 "Rao", about 10 + months after the release of FFmpeg 4.3. + + A complete Changelog is available at the root of the project, and the + complete Git history on https://git.ffmpeg.org/gitweb/ffmpeg.git + + 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.libera.chat) or ask + on the mailing-lists. diff --git a/configure b/configure index 7638d62d05..81dde9fa25 100755 --- a/configure +++ b/configure @@ -416,7 +416,9 @@ Advanced options (experts only): --enable-hardcoded-tables use hardcoded tables instead of runtime generation --disable-safe-bitstream-reader disable buffer boundary checking in bitreaders - (faster, but may crash) + (This disables some security checks and can cause undefined behavior, + crashes and arbitrary code execution, it may be faster, but + should only be used with trusted input) --sws-max-filter-size=N the max filter size swscale uses [$sws_max_filter_size_default] Optimization options (experts only): @@ -536,7 +538,7 @@ die(){ If you think configure made a mistake, make sure you are using the latest version from Git. If the latest version fails, report the problem to the -ffmpeg-user@ffmpeg.org mailing list or IRC #ffmpeg on irc.freenode.net. +ffmpeg-user@ffmpeg.org mailing list or IRC #ffmpeg on irc.libera.chat. EOF if disabled logging; then cat <= 3.0.0" openssl/ssl.h OPENSSL_init_ssl && + { enabled gplv3 || ! enabled gpl || enabled nonfree || die "ERROR: OpenSSL >=3.0.0 requires --enable-version3"; }; } || + { enabled gpl && ! enabled nonfree && die "ERROR: OpenSSL <3.0.0 is incompatible with the gpl"; } || + check_pkg_config openssl openssl openssl/ssl.h OPENSSL_init_ssl || check_pkg_config openssl openssl openssl/ssl.h SSL_library_init || check_lib openssl openssl/ssl.h OPENSSL_init_ssl -lssl -lcrypto || check_lib openssl openssl/ssl.h SSL_library_init -lssl -lcrypto || @@ -6553,7 +6577,7 @@ fi if enabled sdl2; then SDL2_CONFIG="${cross_prefix}sdl2-config" - test_pkg_config sdl2 "sdl2 >= 2.0.1 sdl2 < 2.1.0" SDL_events.h SDL_PollEvent + test_pkg_config sdl2 "sdl2 >= 2.0.1 sdl2 < 3.0.0" SDL_events.h SDL_PollEvent if disabled sdl2 && "${SDL2_CONFIG}" --version > /dev/null 2>&1; then sdl2_cflags=$("${SDL2_CONFIG}" --cflags) sdl2_extralibs=$("${SDL2_CONFIG}" --libs) @@ -6597,13 +6621,15 @@ enabled makeinfo \ disabled makeinfo_html && texi2html --help 2> /dev/null | grep -q 'init-file' && enable texi2html || disable texi2html perl -v > /dev/null 2>&1 && enable perl || disable perl pod2man --help > /dev/null 2>&1 && enable pod2man || disable pod2man -rsync --help 2> /dev/null | grep -q 'contimeout' && enable rsync_contimeout || disable rsync_contimeout +rsync --help 2> /dev/null | grep -q 'contimeout=' && enable rsync_contimeout || disable rsync_contimeout + +check_headers linux/fb.h +check_headers linux/videodev2.h +test_code cc linux/videodev2.h "struct v4l2_frmsizeenum vfse; vfse.discrete.width = 0;" && enable_sanitized struct_v4l2_frmivalenum_discrete +test_code cc sys/ioctl.h "int ioctl(int, int, ...)" && enable posix_ioctl # check V4L2 codecs available in the API if enabled v4l2_m2m; then - check_headers linux/fb.h - check_headers linux/videodev2.h - test_code cc linux/videodev2.h "struct v4l2_frmsizeenum vfse; vfse.discrete.width = 0;" && enable_sanitized struct_v4l2_frmivalenum_discrete check_cc v4l2_m2m linux/videodev2.h "int i = V4L2_CAP_VIDEO_M2M_MPLANE | V4L2_CAP_VIDEO_M2M | V4L2_BUF_FLAG_LAST;" check_cc vc1_v4l2_m2m linux/videodev2.h "int i = V4L2_PIX_FMT_VC1_ANNEX_G;" check_cc mpeg1_v4l2_m2m linux/videodev2.h "int i = V4L2_PIX_FMT_MPEG1;" @@ -6648,7 +6674,7 @@ enabled alsa && { check_pkg_config alsa alsa "alsa/asoundlib.h" snd_pcm_htimesta enabled libjack && require_pkg_config libjack jack jack/jack.h jack_port_get_latency_range -enabled sndio && check_lib sndio sndio.h sio_open -lsndio +enabled sndio && check_pkg_config sndio sndio sndio.h sio_open if enabled libcdio; then check_pkg_config libcdio libcdio_paranoia "cdio/cdda.h cdio/paranoia.h" cdio_cddap_open || @@ -6749,7 +6775,7 @@ enabled vulkan && if enabled x86; then case $target_os in - mingw32*|mingw64*|win32|win64|linux|cygwin*) + freebsd|mingw32*|mingw64*|win32|win64|linux|cygwin*) ;; *) disable ffnvcodec cuvid nvdec nvenc @@ -7348,6 +7374,7 @@ if enabled ppc; then echo "POWER8 enabled ${power8-no}" echo "PPC 4xx optimizations ${ppc4xx-no}" echo "dcbzl available ${dcbzl-no}" + echo "vec_xl available ${vec_xl-no}" fi echo "debug symbols ${debug-no}" echo "strip symbols ${stripping-no}" @@ -7500,7 +7527,6 @@ LD_LIB=$LD_LIB LD_PATH=$LD_PATH DLLTOOL=$dlltool WINDRES=$windres -DEPWINDRES=$dep_cc DOXYGEN=$doxygen LDFLAGS=$LDFLAGS LDEXEFLAGS=$LDEXEFLAGS @@ -7583,7 +7609,7 @@ cat > $TMPH <.caret,.dropup>.btn>.caret{border-top-color:#000!important}.label{border:1px solid #000}.table{border-collapse:collapse!important}.table-bordered th,.table-bordered td{border:1px solid #ddd!important}}@font-face{font-family:'Glyphicons Halflings';src:url(../fonts/glyphicons-halflings-regular.eot);src:url(../fonts/glyphicons-halflings-regular.eot?#iefix) format('embedded-opentype'),url(../fonts/glyphicons-halflings-regular.woff) format('woff'),url(../fonts/glyphicons-halflings-regular.ttf) format('truetype'),url(../fonts/glyphicons-halflings-regular.svg#glyphicons_halflingsregular) format('svg')}.glyphicon{position:relative;top:1px;display:inline-block;font-family:'Glyphicons Halflings';font-style:normal;font-weight:400;line-height:1;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.glyphicon-asterisk:before{content:"\2a"}.glyphicon-plus:before{content:"\2b"}.glyphicon-euro:before{content:"\20ac"}.glyphicon-minus:before{content:"\2212"}.glyphicon-cloud:before{content:"\2601"}.glyphicon-envelope:before{content:"\2709"}.glyphicon-pencil:before{content:"\270f"}.glyphicon-glass:before{content:"\e001"}.glyphicon-music:before{content:"\e002"}.glyphicon-search:before{content:"\e003"}.glyphicon-heart:before{content:"\e005"}.glyphicon-star:before{content:"\e006"}.glyphicon-star-empty:before{content:"\e007"}.glyphicon-user:before{content:"\e008"}.glyphicon-film:before{content:"\e009"}.glyphicon-th-large:before{content:"\e010"}.glyphicon-th:before{content:"\e011"}.glyphicon-th-list:before{content:"\e012"}.glyphicon-ok:before{content:"\e013"}.glyphicon-remove:before{content:"\e014"}.glyphicon-zoom-in:before{content:"\e015"}.glyphicon-zoom-out:before{content:"\e016"}.glyphicon-off:before{content:"\e017"}.glyphicon-signal:before{content:"\e018"}.glyphicon-cog:before{content:"\e019"}.glyphicon-trash:before{content:"\e020"}.glyphicon-home:before{content:"\e021"}.glyphicon-file:before{content:"\e022"}.glyphicon-time:before{content:"\e023"}.glyphicon-road:before{content:"\e024"}.glyphicon-download-alt:before{content:"\e025"}.glyphicon-download:before{content:"\e026"}.glyphicon-upload:before{content:"\e027"}.glyphicon-inbox:before{content:"\e028"}.glyphicon-play-circle:before{content:"\e029"}.glyphicon-repeat:before{content:"\e030"}.glyphicon-refresh:before{content:"\e031"}.glyphicon-list-alt:before{content:"\e032"}.glyphicon-lock:before{content:"\e033"}.glyphicon-flag:before{content:"\e034"}.glyphicon-headphones:before{content:"\e035"}.glyphicon-volume-off:before{content:"\e036"}.glyphicon-volume-down:before{content:"\e037"}.glyphicon-volume-up:before{content:"\e038"}.glyphicon-qrcode:before{content:"\e039"}.glyphicon-barcode:before{content:"\e040"}.glyphicon-tag:before{content:"\e041"}.glyphicon-tags:before{content:"\e042"}.glyphicon-book:before{content:"\e043"}.glyphicon-bookmark:before{content:"\e044"}.glyphicon-print:before{content:"\e045"}.glyphicon-camera:before{content:"\e046"}.glyphicon-font:before{content:"\e047"}.glyphicon-bold:before{content:"\e048"}.glyphicon-italic:before{content:"\e049"}.glyphicon-text-height:before{content:"\e050"}.glyphicon-text-width:before{content:"\e051"}.glyphicon-align-left:before{content:"\e052"}.glyphicon-align-center:before{content:"\e053"}.glyphicon-align-right:before{content:"\e054"}.glyphicon-align-justify:before{content:"\e055"}.glyphicon-list:before{content:"\e056"}.glyphicon-indent-left:before{content:"\e057"}.glyphicon-indent-right:before{content:"\e058"}.glyphicon-facetime-video:before{content:"\e059"}.glyphicon-picture:before{content:"\e060"}.glyphicon-map-marker:before{content:"\e062"}.glyphicon-adjust:before{content:"\e063"}.glyphicon-tint:before{content:"\e064"}.glyphicon-edit:before{content:"\e065"}.glyphicon-share:before{content:"\e066"}.glyphicon-check:before{content:"\e067"}.glyphicon-move:before{content:"\e068"}.glyphicon-step-backward:before{content:"\e069"}.glyphicon-fast-backward:before{content:"\e070"}.glyphicon-backward:before{content:"\e071"}.glyphicon-play:before{content:"\e072"}.glyphicon-pause:before{content:"\e073"}.glyphicon-stop:before{content:"\e074"}.glyphicon-forward:before{content:"\e075"}.glyphicon-fast-forward:before{content:"\e076"}.glyphicon-step-forward:before{content:"\e077"}.glyphicon-eject:before{content:"\e078"}.glyphicon-chevron-left:before{content:"\e079"}.glyphicon-chevron-right:before{content:"\e080"}.glyphicon-plus-sign:before{content:"\e081"}.glyphicon-minus-sign:before{content:"\e082"}.glyphicon-remove-sign:before{content:"\e083"}.glyphicon-ok-sign:before{content:"\e084"}.glyphicon-question-sign:before{content:"\e085"}.glyphicon-info-sign:before{content:"\e086"}.glyphicon-screenshot:before{content:"\e087"}.glyphicon-remove-circle:before{content:"\e088"}.glyphicon-ok-circle:before{content:"\e089"}.glyphicon-ban-circle:before{content:"\e090"}.glyphicon-arrow-left:before{content:"\e091"}.glyphicon-arrow-right:before{content:"\e092"}.glyphicon-arrow-up:before{content:"\e093"}.glyphicon-arrow-down:before{content:"\e094"}.glyphicon-share-alt:before{content:"\e095"}.glyphicon-resize-full:before{content:"\e096"}.glyphicon-resize-small:before{content:"\e097"}.glyphicon-exclamation-sign:before{content:"\e101"}.glyphicon-gift:before{content:"\e102"}.glyphicon-leaf:before{content:"\e103"}.glyphicon-fire:before{content:"\e104"}.glyphicon-eye-open:before{content:"\e105"}.glyphicon-eye-close:before{content:"\e106"}.glyphicon-warning-sign:before{content:"\e107"}.glyphicon-plane:before{content:"\e108"}.glyphicon-calendar:before{content:"\e109"}.glyphicon-random:before{content:"\e110"}.glyphicon-comment:before{content:"\e111"}.glyphicon-magnet:before{content:"\e112"}.glyphicon-chevron-up:before{content:"\e113"}.glyphicon-chevron-down:before{content:"\e114"}.glyphicon-retweet:before{content:"\e115"}.glyphicon-shopping-cart:before{content:"\e116"}.glyphicon-folder-close:before{content:"\e117"}.glyphicon-folder-open:before{content:"\e118"}.glyphicon-resize-vertical:before{content:"\e119"}.glyphicon-resize-horizontal:before{content:"\e120"}.glyphicon-hdd:before{content:"\e121"}.glyphicon-bullhorn:before{content:"\e122"}.glyphicon-bell:before{content:"\e123"}.glyphicon-certificate:before{content:"\e124"}.glyphicon-thumbs-up:before{content:"\e125"}.glyphicon-thumbs-down:before{content:"\e126"}.glyphicon-hand-right:before{content:"\e127"}.glyphicon-hand-left:before{content:"\e128"}.glyphicon-hand-up:before{content:"\e129"}.glyphicon-hand-down:before{content:"\e130"}.glyphicon-circle-arrow-right:before{content:"\e131"}.glyphicon-circle-arrow-left:before{content:"\e132"}.glyphicon-circle-arrow-up:before{content:"\e133"}.glyphicon-circle-arrow-down:before{content:"\e134"}.glyphicon-globe:before{content:"\e135"}.glyphicon-wrench:before{content:"\e136"}.glyphicon-tasks:before{content:"\e137"}.glyphicon-filter:before{content:"\e138"}.glyphicon-briefcase:before{content:"\e139"}.glyphicon-fullscreen:before{content:"\e140"}.glyphicon-dashboard:before{content:"\e141"}.glyphicon-paperclip:before{content:"\e142"}.glyphicon-heart-empty:before{content:"\e143"}.glyphicon-link:before{content:"\e144"}.glyphicon-phone:before{content:"\e145"}.glyphicon-pushpin:before{content:"\e146"}.glyphicon-usd:before{content:"\e148"}.glyphicon-gbp:before{content:"\e149"}.glyphicon-sort:before{content:"\e150"}.glyphicon-sort-by-alphabet:before{content:"\e151"}.glyphicon-sort-by-alphabet-alt:before{content:"\e152"}.glyphicon-sort-by-order:before{content:"\e153"}.glyphicon-sort-by-order-alt:before{content:"\e154"}.glyphicon-sort-by-attributes:before{content:"\e155"}.glyphicon-sort-by-attributes-alt:before{content:"\e156"}.glyphicon-unchecked:before{content:"\e157"}.glyphicon-expand:before{content:"\e158"}.glyphicon-collapse-down:before{content:"\e159"}.glyphicon-collapse-up:before{content:"\e160"}.glyphicon-log-in:before{content:"\e161"}.glyphicon-flash:before{content:"\e162"}.glyphicon-log-out:before{content:"\e163"}.glyphicon-new-window:before{content:"\e164"}.glyphicon-record:before{content:"\e165"}.glyphicon-save:before{content:"\e166"}.glyphicon-open:before{content:"\e167"}.glyphicon-saved:before{content:"\e168"}.glyphicon-import:before{content:"\e169"}.glyphicon-export:before{content:"\e170"}.glyphicon-send:before{content:"\e171"}.glyphicon-floppy-disk:before{content:"\e172"}.glyphicon-floppy-saved:before{content:"\e173"}.glyphicon-floppy-remove:before{content:"\e174"}.glyphicon-floppy-save:before{content:"\e175"}.glyphicon-floppy-open:before{content:"\e176"}.glyphicon-credit-card:before{content:"\e177"}.glyphicon-transfer:before{content:"\e178"}.glyphicon-cutlery:before{content:"\e179"}.glyphicon-header:before{content:"\e180"}.glyphicon-compressed:before{content:"\e181"}.glyphicon-earphone:before{content:"\e182"}.glyphicon-phone-alt:before{content:"\e183"}.glyphicon-tower:before{content:"\e184"}.glyphicon-stats:before{content:"\e185"}.glyphicon-sd-video:before{content:"\e186"}.glyphicon-hd-video:before{content:"\e187"}.glyphicon-subtitles:before{content:"\e188"}.glyphicon-sound-stereo:before{content:"\e189"}.glyphicon-sound-dolby:before{content:"\e190"}.glyphicon-sound-5-1:before{content:"\e191"}.glyphicon-sound-6-1:before{content:"\e192"}.glyphicon-sound-7-1:before{content:"\e193"}.glyphicon-copyright-mark:before{content:"\e194"}.glyphicon-registration-mark:before{content:"\e195"}.glyphicon-cloud-download:before{content:"\e197"}.glyphicon-cloud-upload:before{content:"\e198"}.glyphicon-tree-conifer:before{content:"\e199"}.glyphicon-tree-deciduous:before{content:"\e200"}*{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}:before,:after{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}html{font-size:10px;-webkit-tap-highlight-color:rgba(0,0,0,0)}body{font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:14px;line-height:1.42857143;color:#333;background-color:#fff}input,button,select,textarea{font-family:inherit;font-size:inherit;line-height:inherit}a{color:#428bca;text-decoration:none}a:hover,a:focus{color:#2a6496;text-decoration:underline}a:focus{outline:thin dotted;outline:5px auto -webkit-focus-ring-color;outline-offset:-2px}figure{margin:0}img{vertical-align:middle}.img-responsive,.thumbnail>img,.thumbnail a>img,.carousel-inner>.item>img,.carousel-inner>.item>a>img{display:block;width:100% \9;max-width:100%;height:auto}.img-rounded{border-radius:6px}.img-thumbnail{display:inline-block;width:100% \9;max-width:100%;height:auto;padding:4px;line-height:1.42857143;background-color:#fff;border:1px solid #ddd;border-radius:4px;-webkit-transition:all .2s ease-in-out;-o-transition:all .2s ease-in-out;transition:all .2s ease-in-out}.img-circle{border-radius:50%}hr{margin-top:20px;margin-bottom:20px;border:0;border-top:1px solid #eee}.sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);border:0}.sr-only-focusable:active,.sr-only-focusable:focus{position:static;width:auto;height:auto;margin:0;overflow:visible;clip:auto}h1,h2,h3,h4,h5,h6,.h1,.h2,.h3,.h4,.h5,.h6{font-family:inherit;font-weight:500;line-height:1.1;color:inherit}h1 small,h2 small,h3 small,h4 small,h5 small,h6 small,.h1 small,.h2 small,.h3 small,.h4 small,.h5 small,.h6 small,h1 .small,h2 .small,h3 .small,h4 .small,h5 .small,h6 .small,.h1 .small,.h2 .small,.h3 .small,.h4 .small,.h5 .small,.h6 .small{font-weight:400;line-height:1;color:#777}h1,.h1,h2,.h2,h3,.h3{margin-top:20px;margin-bottom:10px}h1 small,.h1 small,h2 small,.h2 small,h3 small,.h3 small,h1 .small,.h1 .small,h2 .small,.h2 .small,h3 .small,.h3 .small{font-size:65%}h4,.h4,h5,.h5,h6,.h6{margin-top:10px;margin-bottom:10px}h4 small,.h4 small,h5 small,.h5 small,h6 small,.h6 small,h4 .small,.h4 .small,h5 .small,.h5 .small,h6 .small,.h6 .small{font-size:75%}h1,.h1{font-size:36px}h2,.h2{font-size:30px}h3,.h3{font-size:24px}h4,.h4{font-size:18px}h5,.h5{font-size:14px}h6,.h6{font-size:12px}p{margin:0 0 10px}.lead{margin-bottom:20px;font-size:16px;font-weight:300;line-height:1.4}@media (min-width:768px){.lead{font-size:21px}}small,.small{font-size:85%}cite{font-style:normal}mark,.mark{padding:.2em;background-color:#fcf8e3}.text-left{text-align:left}.text-right{text-align:right}.text-center{text-align:center}.text-justify{text-align:justify}.text-nowrap{white-space:nowrap}.text-lowercase{text-transform:lowercase}.text-uppercase{text-transform:uppercase}.text-capitalize{text-transform:capitalize}.text-muted{color:#777}.text-primary{color:#428bca}a.text-primary:hover{color:#3071a9}.text-success{color:#3c763d}a.text-success:hover{color:#2b542c}.text-info{color:#31708f}a.text-info:hover{color:#245269}.text-warning{color:#8a6d3b}a.text-warning:hover{color:#66512c}.text-danger{color:#a94442}a.text-danger:hover{color:#843534}.bg-primary{color:#fff;background-color:#428bca}a.bg-primary:hover{background-color:#3071a9}.bg-success{background-color:#dff0d8}a.bg-success:hover{background-color:#c1e2b3}.bg-info{background-color:#d9edf7}a.bg-info:hover{background-color:#afd9ee}.bg-warning{background-color:#fcf8e3}a.bg-warning:hover{background-color:#f7ecb5}.bg-danger{background-color:#f2dede}a.bg-danger:hover{background-color:#e4b9b9}.page-header{padding-bottom:9px;margin:40px 0 20px;border-bottom:1px solid #eee}ul,ol{margin-top:0;margin-bottom:10px}ul ul,ol ul,ul ol,ol ol{margin-bottom:0}.list-unstyled{padding-left:0;list-style:none}.list-inline{padding-left:0;margin-left:-5px;list-style:none}.list-inline>li{display:inline-block;padding-right:5px;padding-left:5px}dl{margin-top:0;margin-bottom:20px}dt,dd{line-height:1.42857143}dt{font-weight:700}dd{margin-left:0}@media (min-width:768px){.dl-horizontal dt{float:left;width:160px;overflow:hidden;clear:left;text-align:right;text-overflow:ellipsis;white-space:nowrap}.dl-horizontal dd{margin-left:180px}}abbr[title],abbr[data-original-title]{cursor:help;border-bottom:1px dotted #777}.initialism{font-size:90%;text-transform:uppercase}blockquote{padding:10px 20px;margin:0 0 20px;font-size:17.5px;border-left:5px solid #eee}blockquote p:last-child,blockquote ul:last-child,blockquote ol:last-child{margin-bottom:0}blockquote footer,blockquote small,blockquote .small{display:block;font-size:80%;line-height:1.42857143;color:#777}blockquote footer:before,blockquote small:before,blockquote .small:before{content:'\2014 \00A0'}.blockquote-reverse,blockquote.pull-right{padding-right:15px;padding-left:0;text-align:right;border-right:5px solid #eee;border-left:0}.blockquote-reverse footer:before,blockquote.pull-right footer:before,.blockquote-reverse small:before,blockquote.pull-right small:before,.blockquote-reverse .small:before,blockquote.pull-right .small:before{content:''}.blockquote-reverse footer:after,blockquote.pull-right footer:after,.blockquote-reverse small:after,blockquote.pull-right small:after,.blockquote-reverse .small:after,blockquote.pull-right .small:after{content:'\00A0 \2014'}blockquote:before,blockquote:after{content:""}address{margin-bottom:20px;font-style:normal;line-height:1.42857143}code,kbd,pre,samp{font-family:Menlo,Monaco,Consolas,"Courier New",monospace}code{padding:2px 4px;font-size:90%;color:#c7254e;background-color:#f9f2f4;border-radius:4px}kbd{padding:2px 4px;font-size:90%;color:#fff;background-color:#333;border-radius:3px;-webkit-box-shadow:inset 0 -1px 0 rgba(0,0,0,.25);box-shadow:inset 0 -1px 0 rgba(0,0,0,.25)}kbd kbd{padding:0;font-size:100%;-webkit-box-shadow:none;box-shadow:none}pre{display:block;padding:9.5px;margin:0 0 10px;font-size:13px;line-height:1.42857143;color:#333;word-break:break-all;word-wrap:break-word;background-color:#f5f5f5;border:1px solid #ccc;border-radius:4px}pre code{padding:0;font-size:inherit;color:inherit;white-space:pre-wrap;background-color:transparent;border-radius:0}.pre-scrollable{max-height:340px;overflow-y:scroll}.container{padding-right:15px;padding-left:15px;margin-right:auto;margin-left:auto}@media (min-width:768px){.container{width:750px}}@media (min-width:992px){.container{width:970px}}@media (min-width:1200px){.container{width:1170px}}.container-fluid{padding-right:15px;padding-left:15px;margin-right:auto;margin-left:auto}.row{margin-right:-15px;margin-left:-15px}.col-xs-1,.col-sm-1,.col-md-1,.col-lg-1,.col-xs-2,.col-sm-2,.col-md-2,.col-lg-2,.col-xs-3,.col-sm-3,.col-md-3,.col-lg-3,.col-xs-4,.col-sm-4,.col-md-4,.col-lg-4,.col-xs-5,.col-sm-5,.col-md-5,.col-lg-5,.col-xs-6,.col-sm-6,.col-md-6,.col-lg-6,.col-xs-7,.col-sm-7,.col-md-7,.col-lg-7,.col-xs-8,.col-sm-8,.col-md-8,.col-lg-8,.col-xs-9,.col-sm-9,.col-md-9,.col-lg-9,.col-xs-10,.col-sm-10,.col-md-10,.col-lg-10,.col-xs-11,.col-sm-11,.col-md-11,.col-lg-11,.col-xs-12,.col-sm-12,.col-md-12,.col-lg-12{position:relative;min-height:1px;padding-right:15px;padding-left:15px}.col-xs-1,.col-xs-2,.col-xs-3,.col-xs-4,.col-xs-5,.col-xs-6,.col-xs-7,.col-xs-8,.col-xs-9,.col-xs-10,.col-xs-11,.col-xs-12{float:left}.col-xs-12{width:100%}.col-xs-11{width:91.66666667%}.col-xs-10{width:83.33333333%}.col-xs-9{width:75%}.col-xs-8{width:66.66666667%}.col-xs-7{width:58.33333333%}.col-xs-6{width:50%}.col-xs-5{width:41.66666667%}.col-xs-4{width:33.33333333%}.col-xs-3{width:25%}.col-xs-2{width:16.66666667%}.col-xs-1{width:8.33333333%}.col-xs-pull-12{right:100%}.col-xs-pull-11{right:91.66666667%}.col-xs-pull-10{right:83.33333333%}.col-xs-pull-9{right:75%}.col-xs-pull-8{right:66.66666667%}.col-xs-pull-7{right:58.33333333%}.col-xs-pull-6{right:50%}.col-xs-pull-5{right:41.66666667%}.col-xs-pull-4{right:33.33333333%}.col-xs-pull-3{right:25%}.col-xs-pull-2{right:16.66666667%}.col-xs-pull-1{right:8.33333333%}.col-xs-pull-0{right:auto}.col-xs-push-12{left:100%}.col-xs-push-11{left:91.66666667%}.col-xs-push-10{left:83.33333333%}.col-xs-push-9{left:75%}.col-xs-push-8{left:66.66666667%}.col-xs-push-7{left:58.33333333%}.col-xs-push-6{left:50%}.col-xs-push-5{left:41.66666667%}.col-xs-push-4{left:33.33333333%}.col-xs-push-3{left:25%}.col-xs-push-2{left:16.66666667%}.col-xs-push-1{left:8.33333333%}.col-xs-push-0{left:auto}.col-xs-offset-12{margin-left:100%}.col-xs-offset-11{margin-left:91.66666667%}.col-xs-offset-10{margin-left:83.33333333%}.col-xs-offset-9{margin-left:75%}.col-xs-offset-8{margin-left:66.66666667%}.col-xs-offset-7{margin-left:58.33333333%}.col-xs-offset-6{margin-left:50%}.col-xs-offset-5{margin-left:41.66666667%}.col-xs-offset-4{margin-left:33.33333333%}.col-xs-offset-3{margin-left:25%}.col-xs-offset-2{margin-left:16.66666667%}.col-xs-offset-1{margin-left:8.33333333%}.col-xs-offset-0{margin-left:0}@media (min-width:768px){.col-sm-1,.col-sm-2,.col-sm-3,.col-sm-4,.col-sm-5,.col-sm-6,.col-sm-7,.col-sm-8,.col-sm-9,.col-sm-10,.col-sm-11,.col-sm-12{float:left}.col-sm-12{width:100%}.col-sm-11{width:91.66666667%}.col-sm-10{width:83.33333333%}.col-sm-9{width:75%}.col-sm-8{width:66.66666667%}.col-sm-7{width:58.33333333%}.col-sm-6{width:50%}.col-sm-5{width:41.66666667%}.col-sm-4{width:33.33333333%}.col-sm-3{width:25%}.col-sm-2{width:16.66666667%}.col-sm-1{width:8.33333333%}.col-sm-pull-12{right:100%}.col-sm-pull-11{right:91.66666667%}.col-sm-pull-10{right:83.33333333%}.col-sm-pull-9{right:75%}.col-sm-pull-8{right:66.66666667%}.col-sm-pull-7{right:58.33333333%}.col-sm-pull-6{right:50%}.col-sm-pull-5{right:41.66666667%}.col-sm-pull-4{right:33.33333333%}.col-sm-pull-3{right:25%}.col-sm-pull-2{right:16.66666667%}.col-sm-pull-1{right:8.33333333%}.col-sm-pull-0{right:auto}.col-sm-push-12{left:100%}.col-sm-push-11{left:91.66666667%}.col-sm-push-10{left:83.33333333%}.col-sm-push-9{left:75%}.col-sm-push-8{left:66.66666667%}.col-sm-push-7{left:58.33333333%}.col-sm-push-6{left:50%}.col-sm-push-5{left:41.66666667%}.col-sm-push-4{left:33.33333333%}.col-sm-push-3{left:25%}.col-sm-push-2{left:16.66666667%}.col-sm-push-1{left:8.33333333%}.col-sm-push-0{left:auto}.col-sm-offset-12{margin-left:100%}.col-sm-offset-11{margin-left:91.66666667%}.col-sm-offset-10{margin-left:83.33333333%}.col-sm-offset-9{margin-left:75%}.col-sm-offset-8{margin-left:66.66666667%}.col-sm-offset-7{margin-left:58.33333333%}.col-sm-offset-6{margin-left:50%}.col-sm-offset-5{margin-left:41.66666667%}.col-sm-offset-4{margin-left:33.33333333%}.col-sm-offset-3{margin-left:25%}.col-sm-offset-2{margin-left:16.66666667%}.col-sm-offset-1{margin-left:8.33333333%}.col-sm-offset-0{margin-left:0}}@media (min-width:992px){.col-md-1,.col-md-2,.col-md-3,.col-md-4,.col-md-5,.col-md-6,.col-md-7,.col-md-8,.col-md-9,.col-md-10,.col-md-11,.col-md-12{float:left}.col-md-12{width:100%}.col-md-11{width:91.66666667%}.col-md-10{width:83.33333333%}.col-md-9{width:75%}.col-md-8{width:66.66666667%}.col-md-7{width:58.33333333%}.col-md-6{width:50%}.col-md-5{width:41.66666667%}.col-md-4{width:33.33333333%}.col-md-3{width:25%}.col-md-2{width:16.66666667%}.col-md-1{width:8.33333333%}.col-md-pull-12{right:100%}.col-md-pull-11{right:91.66666667%}.col-md-pull-10{right:83.33333333%}.col-md-pull-9{right:75%}.col-md-pull-8{right:66.66666667%}.col-md-pull-7{right:58.33333333%}.col-md-pull-6{right:50%}.col-md-pull-5{right:41.66666667%}.col-md-pull-4{right:33.33333333%}.col-md-pull-3{right:25%}.col-md-pull-2{right:16.66666667%}.col-md-pull-1{right:8.33333333%}.col-md-pull-0{right:auto}.col-md-push-12{left:100%}.col-md-push-11{left:91.66666667%}.col-md-push-10{left:83.33333333%}.col-md-push-9{left:75%}.col-md-push-8{left:66.66666667%}.col-md-push-7{left:58.33333333%}.col-md-push-6{left:50%}.col-md-push-5{left:41.66666667%}.col-md-push-4{left:33.33333333%}.col-md-push-3{left:25%}.col-md-push-2{left:16.66666667%}.col-md-push-1{left:8.33333333%}.col-md-push-0{left:auto}.col-md-offset-12{margin-left:100%}.col-md-offset-11{margin-left:91.66666667%}.col-md-offset-10{margin-left:83.33333333%}.col-md-offset-9{margin-left:75%}.col-md-offset-8{margin-left:66.66666667%}.col-md-offset-7{margin-left:58.33333333%}.col-md-offset-6{margin-left:50%}.col-md-offset-5{margin-left:41.66666667%}.col-md-offset-4{margin-left:33.33333333%}.col-md-offset-3{margin-left:25%}.col-md-offset-2{margin-left:16.66666667%}.col-md-offset-1{margin-left:8.33333333%}.col-md-offset-0{margin-left:0}}@media (min-width:1200px){.col-lg-1,.col-lg-2,.col-lg-3,.col-lg-4,.col-lg-5,.col-lg-6,.col-lg-7,.col-lg-8,.col-lg-9,.col-lg-10,.col-lg-11,.col-lg-12{float:left}.col-lg-12{width:100%}.col-lg-11{width:91.66666667%}.col-lg-10{width:83.33333333%}.col-lg-9{width:75%}.col-lg-8{width:66.66666667%}.col-lg-7{width:58.33333333%}.col-lg-6{width:50%}.col-lg-5{width:41.66666667%}.col-lg-4{width:33.33333333%}.col-lg-3{width:25%}.col-lg-2{width:16.66666667%}.col-lg-1{width:8.33333333%}.col-lg-pull-12{right:100%}.col-lg-pull-11{right:91.66666667%}.col-lg-pull-10{right:83.33333333%}.col-lg-pull-9{right:75%}.col-lg-pull-8{right:66.66666667%}.col-lg-pull-7{right:58.33333333%}.col-lg-pull-6{right:50%}.col-lg-pull-5{right:41.66666667%}.col-lg-pull-4{right:33.33333333%}.col-lg-pull-3{right:25%}.col-lg-pull-2{right:16.66666667%}.col-lg-pull-1{right:8.33333333%}.col-lg-pull-0{right:auto}.col-lg-push-12{left:100%}.col-lg-push-11{left:91.66666667%}.col-lg-push-10{left:83.33333333%}.col-lg-push-9{left:75%}.col-lg-push-8{left:66.66666667%}.col-lg-push-7{left:58.33333333%}.col-lg-push-6{left:50%}.col-lg-push-5{left:41.66666667%}.col-lg-push-4{left:33.33333333%}.col-lg-push-3{left:25%}.col-lg-push-2{left:16.66666667%}.col-lg-push-1{left:8.33333333%}.col-lg-push-0{left:auto}.col-lg-offset-12{margin-left:100%}.col-lg-offset-11{margin-left:91.66666667%}.col-lg-offset-10{margin-left:83.33333333%}.col-lg-offset-9{margin-left:75%}.col-lg-offset-8{margin-left:66.66666667%}.col-lg-offset-7{margin-left:58.33333333%}.col-lg-offset-6{margin-left:50%}.col-lg-offset-5{margin-left:41.66666667%}.col-lg-offset-4{margin-left:33.33333333%}.col-lg-offset-3{margin-left:25%}.col-lg-offset-2{margin-left:16.66666667%}.col-lg-offset-1{margin-left:8.33333333%}.col-lg-offset-0{margin-left:0}}table{background-color:transparent}th{text-align:left}.table{width:100%;max-width:100%;margin-bottom:20px}.table>thead>tr>th,.table>tbody>tr>th,.table>tfoot>tr>th,.table>thead>tr>td,.table>tbody>tr>td,.table>tfoot>tr>td{padding:8px;line-height:1.42857143;vertical-align:top;border-top:1px solid #ddd}.table>thead>tr>th{vertical-align:bottom;border-bottom:2px solid #ddd}.table>caption+thead>tr:first-child>th,.table>colgroup+thead>tr:first-child>th,.table>thead:first-child>tr:first-child>th,.table>caption+thead>tr:first-child>td,.table>colgroup+thead>tr:first-child>td,.table>thead:first-child>tr:first-child>td{border-top:0}.table>tbody+tbody{border-top:2px solid #ddd}.table .table{background-color:#fff}.table-condensed>thead>tr>th,.table-condensed>tbody>tr>th,.table-condensed>tfoot>tr>th,.table-condensed>thead>tr>td,.table-condensed>tbody>tr>td,.table-condensed>tfoot>tr>td{padding:5px}.table-bordered{border:1px solid #ddd}.table-bordered>thead>tr>th,.table-bordered>tbody>tr>th,.table-bordered>tfoot>tr>th,.table-bordered>thead>tr>td,.table-bordered>tbody>tr>td,.table-bordered>tfoot>tr>td{border:1px solid #ddd}.table-bordered>thead>tr>th,.table-bordered>thead>tr>td{border-bottom-width:2px}.table-striped>tbody>tr:nth-child(odd)>td,.table-striped>tbody>tr:nth-child(odd)>th{background-color:#f9f9f9}.table-hover>tbody>tr:hover>td,.table-hover>tbody>tr:hover>th{background-color:#f5f5f5}table col[class*=col-]{position:static;display:table-column;float:none}table td[class*=col-],table th[class*=col-]{position:static;display:table-cell;float:none}.table>thead>tr>td.active,.table>tbody>tr>td.active,.table>tfoot>tr>td.active,.table>thead>tr>th.active,.table>tbody>tr>th.active,.table>tfoot>tr>th.active,.table>thead>tr.active>td,.table>tbody>tr.active>td,.table>tfoot>tr.active>td,.table>thead>tr.active>th,.table>tbody>tr.active>th,.table>tfoot>tr.active>th{background-color:#f5f5f5}.table-hover>tbody>tr>td.active:hover,.table-hover>tbody>tr>th.active:hover,.table-hover>tbody>tr.active:hover>td,.table-hover>tbody>tr:hover>.active,.table-hover>tbody>tr.active:hover>th{background-color:#e8e8e8}.table>thead>tr>td.success,.table>tbody>tr>td.success,.table>tfoot>tr>td.success,.table>thead>tr>th.success,.table>tbody>tr>th.success,.table>tfoot>tr>th.success,.table>thead>tr.success>td,.table>tbody>tr.success>td,.table>tfoot>tr.success>td,.table>thead>tr.success>th,.table>tbody>tr.success>th,.table>tfoot>tr.success>th{background-color:#dff0d8}.table-hover>tbody>tr>td.success:hover,.table-hover>tbody>tr>th.success:hover,.table-hover>tbody>tr.success:hover>td,.table-hover>tbody>tr:hover>.success,.table-hover>tbody>tr.success:hover>th{background-color:#d0e9c6}.table>thead>tr>td.info,.table>tbody>tr>td.info,.table>tfoot>tr>td.info,.table>thead>tr>th.info,.table>tbody>tr>th.info,.table>tfoot>tr>th.info,.table>thead>tr.info>td,.table>tbody>tr.info>td,.table>tfoot>tr.info>td,.table>thead>tr.info>th,.table>tbody>tr.info>th,.table>tfoot>tr.info>th{background-color:#d9edf7}.table-hover>tbody>tr>td.info:hover,.table-hover>tbody>tr>th.info:hover,.table-hover>tbody>tr.info:hover>td,.table-hover>tbody>tr:hover>.info,.table-hover>tbody>tr.info:hover>th{background-color:#c4e3f3}.table>thead>tr>td.warning,.table>tbody>tr>td.warning,.table>tfoot>tr>td.warning,.table>thead>tr>th.warning,.table>tbody>tr>th.warning,.table>tfoot>tr>th.warning,.table>thead>tr.warning>td,.table>tbody>tr.warning>td,.table>tfoot>tr.warning>td,.table>thead>tr.warning>th,.table>tbody>tr.warning>th,.table>tfoot>tr.warning>th{background-color:#fcf8e3}.table-hover>tbody>tr>td.warning:hover,.table-hover>tbody>tr>th.warning:hover,.table-hover>tbody>tr.warning:hover>td,.table-hover>tbody>tr:hover>.warning,.table-hover>tbody>tr.warning:hover>th{background-color:#faf2cc}.table>thead>tr>td.danger,.table>tbody>tr>td.danger,.table>tfoot>tr>td.danger,.table>thead>tr>th.danger,.table>tbody>tr>th.danger,.table>tfoot>tr>th.danger,.table>thead>tr.danger>td,.table>tbody>tr.danger>td,.table>tfoot>tr.danger>td,.table>thead>tr.danger>th,.table>tbody>tr.danger>th,.table>tfoot>tr.danger>th{background-color:#f2dede}.table-hover>tbody>tr>td.danger:hover,.table-hover>tbody>tr>th.danger:hover,.table-hover>tbody>tr.danger:hover>td,.table-hover>tbody>tr:hover>.danger,.table-hover>tbody>tr.danger:hover>th{background-color:#ebcccc}@media screen and (max-width:767px){.table-responsive{width:100%;margin-bottom:15px;overflow-x:auto;overflow-y:hidden;-webkit-overflow-scrolling:touch;-ms-overflow-style:-ms-autohiding-scrollbar;border:1px solid #ddd}.table-responsive>.table{margin-bottom:0}.table-responsive>.table>thead>tr>th,.table-responsive>.table>tbody>tr>th,.table-responsive>.table>tfoot>tr>th,.table-responsive>.table>thead>tr>td,.table-responsive>.table>tbody>tr>td,.table-responsive>.table>tfoot>tr>td{white-space:nowrap}.table-responsive>.table-bordered{border:0}.table-responsive>.table-bordered>thead>tr>th:first-child,.table-responsive>.table-bordered>tbody>tr>th:first-child,.table-responsive>.table-bordered>tfoot>tr>th:first-child,.table-responsive>.table-bordered>thead>tr>td:first-child,.table-responsive>.table-bordered>tbody>tr>td:first-child,.table-responsive>.table-bordered>tfoot>tr>td:first-child{border-left:0}.table-responsive>.table-bordered>thead>tr>th:last-child,.table-responsive>.table-bordered>tbody>tr>th:last-child,.table-responsive>.table-bordered>tfoot>tr>th:last-child,.table-responsive>.table-bordered>thead>tr>td:last-child,.table-responsive>.table-bordered>tbody>tr>td:last-child,.table-responsive>.table-bordered>tfoot>tr>td:last-child{border-right:0}.table-responsive>.table-bordered>tbody>tr:last-child>th,.table-responsive>.table-bordered>tfoot>tr:last-child>th,.table-responsive>.table-bordered>tbody>tr:last-child>td,.table-responsive>.table-bordered>tfoot>tr:last-child>td{border-bottom:0}}fieldset{min-width:0;padding:0;margin:0;border:0}legend{display:block;width:100%;padding:0;margin-bottom:20px;font-size:21px;line-height:inherit;color:#333;border:0;border-bottom:1px solid #e5e5e5}label{display:inline-block;max-width:100%;margin-bottom:5px;font-weight:700}input[type=search]{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}input[type=radio],input[type=checkbox]{margin:4px 0 0;margin-top:1px \9;line-height:normal}input[type=file]{display:block}input[type=range]{display:block;width:100%}select[multiple],select[size]{height:auto}input[type=file]:focus,input[type=radio]:focus,input[type=checkbox]:focus{outline:thin dotted;outline:5px auto -webkit-focus-ring-color;outline-offset:-2px}output{display:block;padding-top:7px;font-size:14px;line-height:1.42857143;color:#555}.form-control{display:block;width:100%;height:34px;padding:6px 12px;font-size:14px;line-height:1.42857143;color:#555;background-color:#fff;background-image:none;border:1px solid #ccc;border-radius:4px;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075);box-shadow:inset 0 1px 1px rgba(0,0,0,.075);-webkit-transition:border-color ease-in-out .15s,-webkit-box-shadow ease-in-out .15s;-o-transition:border-color ease-in-out .15s,box-shadow ease-in-out .15s;transition:border-color ease-in-out .15s,box-shadow ease-in-out .15s}.form-control:focus{border-color:#66afe9;outline:0;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 8px rgba(102,175,233,.6);box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 8px rgba(102,175,233,.6)}.form-control::-moz-placeholder{color:#777;opacity:1}.form-control:-ms-input-placeholder{color:#777}.form-control::-webkit-input-placeholder{color:#777}.form-control[disabled],.form-control[readonly],fieldset[disabled] .form-control{cursor:not-allowed;background-color:#eee;opacity:1}textarea.form-control{height:auto}input[type=search]{-webkit-appearance:none}input[type=date],input[type=time],input[type=datetime-local],input[type=month]{line-height:34px;line-height:1.42857143 \0}input[type=date].input-sm,input[type=time].input-sm,input[type=datetime-local].input-sm,input[type=month].input-sm{line-height:30px}input[type=date].input-lg,input[type=time].input-lg,input[type=datetime-local].input-lg,input[type=month].input-lg{line-height:46px}.form-group{margin-bottom:15px}.radio,.checkbox{position:relative;display:block;min-height:20px;margin-top:10px;margin-bottom:10px}.radio label,.checkbox label{padding-left:20px;margin-bottom:0;font-weight:400;cursor:pointer}.radio input[type=radio],.radio-inline input[type=radio],.checkbox input[type=checkbox],.checkbox-inline input[type=checkbox]{position:absolute;margin-top:4px \9;margin-left:-20px}.radio+.radio,.checkbox+.checkbox{margin-top:-5px}.radio-inline,.checkbox-inline{display:inline-block;padding-left:20px;margin-bottom:0;font-weight:400;vertical-align:middle;cursor:pointer}.radio-inline+.radio-inline,.checkbox-inline+.checkbox-inline{margin-top:0;margin-left:10px}input[type=radio][disabled],input[type=checkbox][disabled],input[type=radio].disabled,input[type=checkbox].disabled,fieldset[disabled] input[type=radio],fieldset[disabled] input[type=checkbox]{cursor:not-allowed}.radio-inline.disabled,.checkbox-inline.disabled,fieldset[disabled] .radio-inline,fieldset[disabled] .checkbox-inline{cursor:not-allowed}.radio.disabled label,.checkbox.disabled label,fieldset[disabled] .radio label,fieldset[disabled] .checkbox label{cursor:not-allowed}.form-control-static{padding-top:7px;padding-bottom:7px;margin-bottom:0}.form-control-static.input-lg,.form-control-static.input-sm{padding-right:0;padding-left:0}.input-sm,.form-horizontal .form-group-sm .form-control{height:30px;padding:5px 10px;font-size:12px;line-height:1.5;border-radius:3px}select.input-sm{height:30px;line-height:30px}textarea.input-sm,select[multiple].input-sm{height:auto}.input-lg,.form-horizontal .form-group-lg .form-control{height:46px;padding:10px 16px;font-size:18px;line-height:1.33;border-radius:6px}select.input-lg{height:46px;line-height:46px}textarea.input-lg,select[multiple].input-lg{height:auto}.has-feedback{position:relative}.has-feedback .form-control{padding-right:42.5px}.form-control-feedback{position:absolute;top:25px;right:0;z-index:2;display:block;width:34px;height:34px;line-height:34px;text-align:center}.input-lg+.form-control-feedback{width:46px;height:46px;line-height:46px}.input-sm+.form-control-feedback{width:30px;height:30px;line-height:30px}.has-success .help-block,.has-success .control-label,.has-success .radio,.has-success .checkbox,.has-success .radio-inline,.has-success .checkbox-inline{color:#3c763d}.has-success .form-control{border-color:#3c763d;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075);box-shadow:inset 0 1px 1px rgba(0,0,0,.075)}.has-success .form-control:focus{border-color:#2b542c;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 6px #67b168;box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 6px #67b168}.has-success .input-group-addon{color:#3c763d;background-color:#dff0d8;border-color:#3c763d}.has-success .form-control-feedback{color:#3c763d}.has-warning .help-block,.has-warning .control-label,.has-warning .radio,.has-warning .checkbox,.has-warning .radio-inline,.has-warning .checkbox-inline{color:#8a6d3b}.has-warning .form-control{border-color:#8a6d3b;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075);box-shadow:inset 0 1px 1px rgba(0,0,0,.075)}.has-warning .form-control:focus{border-color:#66512c;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 6px #c0a16b;box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 6px #c0a16b}.has-warning .input-group-addon{color:#8a6d3b;background-color:#fcf8e3;border-color:#8a6d3b}.has-warning .form-control-feedback{color:#8a6d3b}.has-error .help-block,.has-error .control-label,.has-error .radio,.has-error .checkbox,.has-error .radio-inline,.has-error .checkbox-inline{color:#a94442}.has-error .form-control{border-color:#a94442;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075);box-shadow:inset 0 1px 1px rgba(0,0,0,.075)}.has-error .form-control:focus{border-color:#843534;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 6px #ce8483;box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 6px #ce8483}.has-error .input-group-addon{color:#a94442;background-color:#f2dede;border-color:#a94442}.has-error .form-control-feedback{color:#a94442}.has-feedback label.sr-only~.form-control-feedback{top:0}.help-block{display:block;margin-top:5px;margin-bottom:10px;color:#737373}@media (min-width:768px){.form-inline .form-group{display:inline-block;margin-bottom:0;vertical-align:middle}.form-inline .form-control{display:inline-block;width:auto;vertical-align:middle}.form-inline .input-group{display:inline-table;vertical-align:middle}.form-inline .input-group .input-group-addon,.form-inline .input-group .input-group-btn,.form-inline .input-group .form-control{width:auto}.form-inline .input-group>.form-control{width:100%}.form-inline .control-label{margin-bottom:0;vertical-align:middle}.form-inline .radio,.form-inline .checkbox{display:inline-block;margin-top:0;margin-bottom:0;vertical-align:middle}.form-inline .radio label,.form-inline .checkbox label{padding-left:0}.form-inline .radio input[type=radio],.form-inline .checkbox input[type=checkbox]{position:relative;margin-left:0}.form-inline .has-feedback .form-control-feedback{top:0}}.form-horizontal .radio,.form-horizontal .checkbox,.form-horizontal .radio-inline,.form-horizontal .checkbox-inline{padding-top:7px;margin-top:0;margin-bottom:0}.form-horizontal .radio,.form-horizontal .checkbox{min-height:27px}.form-horizontal .form-group{margin-right:-15px;margin-left:-15px}@media (min-width:768px){.form-horizontal .control-label{padding-top:7px;margin-bottom:0;text-align:right}}.form-horizontal .has-feedback .form-control-feedback{top:0;right:15px}@media (min-width:768px){.form-horizontal .form-group-lg .control-label{padding-top:14.3px}}@media (min-width:768px){.form-horizontal .form-group-sm .control-label{padding-top:6px}}.btn{display:inline-block;padding:6px 12px;margin-bottom:0;font-size:14px;font-weight:400;line-height:1.42857143;text-align:center;white-space:nowrap;vertical-align:middle;cursor:pointer;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;background-image:none;border:1px solid transparent;border-radius:4px}.btn:focus,.btn:active:focus,.btn.active:focus{outline:thin dotted;outline:5px auto -webkit-focus-ring-color;outline-offset:-2px}.btn:hover,.btn:focus{color:#333;text-decoration:none}.btn:active,.btn.active{background-image:none;outline:0;-webkit-box-shadow:inset 0 3px 5px rgba(0,0,0,.125);box-shadow:inset 0 3px 5px rgba(0,0,0,.125)}.btn.disabled,.btn[disabled],fieldset[disabled] .btn{pointer-events:none;cursor:not-allowed;filter:alpha(opacity=65);-webkit-box-shadow:none;box-shadow:none;opacity:.65}.btn-default{color:#333;background-color:#fff;border-color:#ccc}.btn-default:hover,.btn-default:focus,.btn-default:active,.btn-default.active,.open>.dropdown-toggle.btn-default{color:#333;background-color:#e6e6e6;border-color:#adadad}.btn-default:active,.btn-default.active,.open>.dropdown-toggle.btn-default{background-image:none}.btn-default.disabled,.btn-default[disabled],fieldset[disabled] .btn-default,.btn-default.disabled:hover,.btn-default[disabled]:hover,fieldset[disabled] .btn-default:hover,.btn-default.disabled:focus,.btn-default[disabled]:focus,fieldset[disabled] .btn-default:focus,.btn-default.disabled:active,.btn-default[disabled]:active,fieldset[disabled] .btn-default:active,.btn-default.disabled.active,.btn-default[disabled].active,fieldset[disabled] .btn-default.active{background-color:#fff;border-color:#ccc}.btn-default .badge{color:#fff;background-color:#333}.btn-primary{color:#fff;background-color:#428bca;border-color:#357ebd}.btn-primary:hover,.btn-primary:focus,.btn-primary:active,.btn-primary.active,.open>.dropdown-toggle.btn-primary{color:#fff;background-color:#3071a9;border-color:#285e8e}.btn-primary:active,.btn-primary.active,.open>.dropdown-toggle.btn-primary{background-image:none}.btn-primary.disabled,.btn-primary[disabled],fieldset[disabled] .btn-primary,.btn-primary.disabled:hover,.btn-primary[disabled]:hover,fieldset[disabled] .btn-primary:hover,.btn-primary.disabled:focus,.btn-primary[disabled]:focus,fieldset[disabled] .btn-primary:focus,.btn-primary.disabled:active,.btn-primary[disabled]:active,fieldset[disabled] .btn-primary:active,.btn-primary.disabled.active,.btn-primary[disabled].active,fieldset[disabled] .btn-primary.active{background-color:#428bca;border-color:#357ebd}.btn-primary .badge{color:#428bca;background-color:#fff}.btn-success{color:#fff;background-color:#5cb85c;border-color:#4cae4c}.btn-success:hover,.btn-success:focus,.btn-success:active,.btn-success.active,.open>.dropdown-toggle.btn-success{color:#fff;background-color:#449d44;border-color:#398439}.btn-success:active,.btn-success.active,.open>.dropdown-toggle.btn-success{background-image:none}.btn-success.disabled,.btn-success[disabled],fieldset[disabled] .btn-success,.btn-success.disabled:hover,.btn-success[disabled]:hover,fieldset[disabled] .btn-success:hover,.btn-success.disabled:focus,.btn-success[disabled]:focus,fieldset[disabled] .btn-success:focus,.btn-success.disabled:active,.btn-success[disabled]:active,fieldset[disabled] .btn-success:active,.btn-success.disabled.active,.btn-success[disabled].active,fieldset[disabled] .btn-success.active{background-color:#5cb85c;border-color:#4cae4c}.btn-success .badge{color:#5cb85c;background-color:#fff}.btn-info{color:#fff;background-color:#5bc0de;border-color:#46b8da}.btn-info:hover,.btn-info:focus,.btn-info:active,.btn-info.active,.open>.dropdown-toggle.btn-info{color:#fff;background-color:#31b0d5;border-color:#269abc}.btn-info:active,.btn-info.active,.open>.dropdown-toggle.btn-info{background-image:none}.btn-info.disabled,.btn-info[disabled],fieldset[disabled] .btn-info,.btn-info.disabled:hover,.btn-info[disabled]:hover,fieldset[disabled] .btn-info:hover,.btn-info.disabled:focus,.btn-info[disabled]:focus,fieldset[disabled] .btn-info:focus,.btn-info.disabled:active,.btn-info[disabled]:active,fieldset[disabled] .btn-info:active,.btn-info.disabled.active,.btn-info[disabled].active,fieldset[disabled] .btn-info.active{background-color:#5bc0de;border-color:#46b8da}.btn-info .badge{color:#5bc0de;background-color:#fff}.btn-warning{color:#fff;background-color:#f0ad4e;border-color:#eea236}.btn-warning:hover,.btn-warning:focus,.btn-warning:active,.btn-warning.active,.open>.dropdown-toggle.btn-warning{color:#fff;background-color:#ec971f;border-color:#d58512}.btn-warning:active,.btn-warning.active,.open>.dropdown-toggle.btn-warning{background-image:none}.btn-warning.disabled,.btn-warning[disabled],fieldset[disabled] .btn-warning,.btn-warning.disabled:hover,.btn-warning[disabled]:hover,fieldset[disabled] .btn-warning:hover,.btn-warning.disabled:focus,.btn-warning[disabled]:focus,fieldset[disabled] .btn-warning:focus,.btn-warning.disabled:active,.btn-warning[disabled]:active,fieldset[disabled] .btn-warning:active,.btn-warning.disabled.active,.btn-warning[disabled].active,fieldset[disabled] .btn-warning.active{background-color:#f0ad4e;border-color:#eea236}.btn-warning .badge{color:#f0ad4e;background-color:#fff}.btn-danger{color:#fff;background-color:#d9534f;border-color:#d43f3a}.btn-danger:hover,.btn-danger:focus,.btn-danger:active,.btn-danger.active,.open>.dropdown-toggle.btn-danger{color:#fff;background-color:#c9302c;border-color:#ac2925}.btn-danger:active,.btn-danger.active,.open>.dropdown-toggle.btn-danger{background-image:none}.btn-danger.disabled,.btn-danger[disabled],fieldset[disabled] .btn-danger,.btn-danger.disabled:hover,.btn-danger[disabled]:hover,fieldset[disabled] .btn-danger:hover,.btn-danger.disabled:focus,.btn-danger[disabled]:focus,fieldset[disabled] .btn-danger:focus,.btn-danger.disabled:active,.btn-danger[disabled]:active,fieldset[disabled] .btn-danger:active,.btn-danger.disabled.active,.btn-danger[disabled].active,fieldset[disabled] .btn-danger.active{background-color:#d9534f;border-color:#d43f3a}.btn-danger .badge{color:#d9534f;background-color:#fff}.btn-link{font-weight:400;color:#428bca;cursor:pointer;border-radius:0}.btn-link,.btn-link:active,.btn-link[disabled],fieldset[disabled] .btn-link{background-color:transparent;-webkit-box-shadow:none;box-shadow:none}.btn-link,.btn-link:hover,.btn-link:focus,.btn-link:active{border-color:transparent}.btn-link:hover,.btn-link:focus{color:#2a6496;text-decoration:underline;background-color:transparent}.btn-link[disabled]:hover,fieldset[disabled] .btn-link:hover,.btn-link[disabled]:focus,fieldset[disabled] .btn-link:focus{color:#777;text-decoration:none}.btn-lg,.btn-group-lg>.btn{padding:10px 16px;font-size:18px;line-height:1.33;border-radius:6px}.btn-sm,.btn-group-sm>.btn{padding:5px 10px;font-size:12px;line-height:1.5;border-radius:3px}.btn-xs,.btn-group-xs>.btn{padding:1px 5px;font-size:12px;line-height:1.5;border-radius:3px}.btn-block{display:block;width:100%}.btn-block+.btn-block{margin-top:5px}input[type=submit].btn-block,input[type=reset].btn-block,input[type=button].btn-block{width:100%}.fade{opacity:0;-webkit-transition:opacity .15s linear;-o-transition:opacity .15s linear;transition:opacity .15s linear}.fade.in{opacity:1}.collapse{display:none}.collapse.in{display:block}tr.collapse.in{display:table-row}tbody.collapse.in{display:table-row-group}.collapsing{position:relative;height:0;overflow:hidden;-webkit-transition:height .35s ease;-o-transition:height .35s ease;transition:height .35s ease}.caret{display:inline-block;width:0;height:0;margin-left:2px;vertical-align:middle;border-top:4px solid;border-right:4px solid transparent;border-left:4px solid transparent}.dropdown{position:relative}.dropdown-toggle:focus{outline:0}.dropdown-menu{position:absolute;top:100%;left:0;z-index:1000;display:none;float:left;min-width:160px;padding:5px 0;margin:2px 0 0;font-size:14px;text-align:left;list-style:none;background-color:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0,0,0,.15);border-radius:4px;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175)}.dropdown-menu.pull-right{right:0;left:auto}.dropdown-menu .divider{height:1px;margin:9px 0;overflow:hidden;background-color:#e5e5e5}.dropdown-menu>li>a{display:block;padding:3px 20px;clear:both;font-weight:400;line-height:1.42857143;color:#333;white-space:nowrap}.dropdown-menu>li>a:hover,.dropdown-menu>li>a:focus{color:#262626;text-decoration:none;background-color:#f5f5f5}.dropdown-menu>.active>a,.dropdown-menu>.active>a:hover,.dropdown-menu>.active>a:focus{color:#fff;text-decoration:none;background-color:#428bca;outline:0}.dropdown-menu>.disabled>a,.dropdown-menu>.disabled>a:hover,.dropdown-menu>.disabled>a:focus{color:#777}.dropdown-menu>.disabled>a:hover,.dropdown-menu>.disabled>a:focus{text-decoration:none;cursor:not-allowed;background-color:transparent;background-image:none;filter:progid:DXImageTransform.Microsoft.gradient(enabled=false)}.open>.dropdown-menu{display:block}.open>a{outline:0}.dropdown-menu-right{right:0;left:auto}.dropdown-menu-left{right:auto;left:0}.dropdown-header{display:block;padding:3px 20px;font-size:12px;line-height:1.42857143;color:#777;white-space:nowrap}.dropdown-backdrop{position:fixed;top:0;right:0;bottom:0;left:0;z-index:990}.pull-right>.dropdown-menu{right:0;left:auto}.dropup .caret,.navbar-fixed-bottom .dropdown .caret{content:"";border-top:0;border-bottom:4px solid}.dropup .dropdown-menu,.navbar-fixed-bottom .dropdown .dropdown-menu{top:auto;bottom:100%;margin-bottom:1px}@media (min-width:768px){.navbar-right .dropdown-menu{right:0;left:auto}.navbar-right .dropdown-menu-left{right:auto;left:0}}.btn-group,.btn-group-vertical{position:relative;display:inline-block;vertical-align:middle}.btn-group>.btn,.btn-group-vertical>.btn{position:relative;float:left}.btn-group>.btn:hover,.btn-group-vertical>.btn:hover,.btn-group>.btn:focus,.btn-group-vertical>.btn:focus,.btn-group>.btn:active,.btn-group-vertical>.btn:active,.btn-group>.btn.active,.btn-group-vertical>.btn.active{z-index:2}.btn-group>.btn:focus,.btn-group-vertical>.btn:focus{outline:0}.btn-group .btn+.btn,.btn-group .btn+.btn-group,.btn-group .btn-group+.btn,.btn-group .btn-group+.btn-group{margin-left:-1px}.btn-toolbar{margin-left:-5px}.btn-toolbar .btn-group,.btn-toolbar .input-group{float:left}.btn-toolbar>.btn,.btn-toolbar>.btn-group,.btn-toolbar>.input-group{margin-left:5px}.btn-group>.btn:not(:first-child):not(:last-child):not(.dropdown-toggle){border-radius:0}.btn-group>.btn:first-child{margin-left:0}.btn-group>.btn:first-child:not(:last-child):not(.dropdown-toggle){border-top-right-radius:0;border-bottom-right-radius:0}.btn-group>.btn:last-child:not(:first-child),.btn-group>.dropdown-toggle:not(:first-child){border-top-left-radius:0;border-bottom-left-radius:0}.btn-group>.btn-group{float:left}.btn-group>.btn-group:not(:first-child):not(:last-child)>.btn{border-radius:0}.btn-group>.btn-group:first-child>.btn:last-child,.btn-group>.btn-group:first-child>.dropdown-toggle{border-top-right-radius:0;border-bottom-right-radius:0}.btn-group>.btn-group:last-child>.btn:first-child{border-top-left-radius:0;border-bottom-left-radius:0}.btn-group .dropdown-toggle:active,.btn-group.open .dropdown-toggle{outline:0}.btn-group>.btn+.dropdown-toggle{padding-right:8px;padding-left:8px}.btn-group>.btn-lg+.dropdown-toggle{padding-right:12px;padding-left:12px}.btn-group.open .dropdown-toggle{-webkit-box-shadow:inset 0 3px 5px rgba(0,0,0,.125);box-shadow:inset 0 3px 5px rgba(0,0,0,.125)}.btn-group.open .dropdown-toggle.btn-link{-webkit-box-shadow:none;box-shadow:none}.btn .caret{margin-left:0}.btn-lg .caret{border-width:5px 5px 0;border-bottom-width:0}.dropup .btn-lg .caret{border-width:0 5px 5px}.btn-group-vertical>.btn,.btn-group-vertical>.btn-group,.btn-group-vertical>.btn-group>.btn{display:block;float:none;width:100%;max-width:100%}.btn-group-vertical>.btn-group>.btn{float:none}.btn-group-vertical>.btn+.btn,.btn-group-vertical>.btn+.btn-group,.btn-group-vertical>.btn-group+.btn,.btn-group-vertical>.btn-group+.btn-group{margin-top:-1px;margin-left:0}.btn-group-vertical>.btn:not(:first-child):not(:last-child){border-radius:0}.btn-group-vertical>.btn:first-child:not(:last-child){border-top-right-radius:4px;border-bottom-right-radius:0;border-bottom-left-radius:0}.btn-group-vertical>.btn:last-child:not(:first-child){border-top-left-radius:0;border-top-right-radius:0;border-bottom-left-radius:4px}.btn-group-vertical>.btn-group:not(:first-child):not(:last-child)>.btn{border-radius:0}.btn-group-vertical>.btn-group:first-child:not(:last-child)>.btn:last-child,.btn-group-vertical>.btn-group:first-child:not(:last-child)>.dropdown-toggle{border-bottom-right-radius:0;border-bottom-left-radius:0}.btn-group-vertical>.btn-group:last-child:not(:first-child)>.btn:first-child{border-top-left-radius:0;border-top-right-radius:0}.btn-group-justified{display:table;width:100%;table-layout:fixed;border-collapse:separate}.btn-group-justified>.btn,.btn-group-justified>.btn-group{display:table-cell;float:none;width:1%}.btn-group-justified>.btn-group .btn{width:100%}.btn-group-justified>.btn-group .dropdown-menu{left:auto}[data-toggle=buttons]>.btn>input[type=radio],[data-toggle=buttons]>.btn>input[type=checkbox]{position:absolute;z-index:-1;filter:alpha(opacity=0);opacity:0}.input-group{position:relative;display:table;border-collapse:separate}.input-group[class*=col-]{float:none;padding-right:0;padding-left:0}.input-group .form-control{position:relative;z-index:2;float:left;width:100%;margin-bottom:0}.input-group-lg>.form-control,.input-group-lg>.input-group-addon,.input-group-lg>.input-group-btn>.btn{height:46px;padding:10px 16px;font-size:18px;line-height:1.33;border-radius:6px}select.input-group-lg>.form-control,select.input-group-lg>.input-group-addon,select.input-group-lg>.input-group-btn>.btn{height:46px;line-height:46px}textarea.input-group-lg>.form-control,textarea.input-group-lg>.input-group-addon,textarea.input-group-lg>.input-group-btn>.btn,select[multiple].input-group-lg>.form-control,select[multiple].input-group-lg>.input-group-addon,select[multiple].input-group-lg>.input-group-btn>.btn{height:auto}.input-group-sm>.form-control,.input-group-sm>.input-group-addon,.input-group-sm>.input-group-btn>.btn{height:30px;padding:5px 10px;font-size:12px;line-height:1.5;border-radius:3px}select.input-group-sm>.form-control,select.input-group-sm>.input-group-addon,select.input-group-sm>.input-group-btn>.btn{height:30px;line-height:30px}textarea.input-group-sm>.form-control,textarea.input-group-sm>.input-group-addon,textarea.input-group-sm>.input-group-btn>.btn,select[multiple].input-group-sm>.form-control,select[multiple].input-group-sm>.input-group-addon,select[multiple].input-group-sm>.input-group-btn>.btn{height:auto}.input-group-addon,.input-group-btn,.input-group .form-control{display:table-cell}.input-group-addon:not(:first-child):not(:last-child),.input-group-btn:not(:first-child):not(:last-child),.input-group .form-control:not(:first-child):not(:last-child){border-radius:0}.input-group-addon,.input-group-btn{width:1%;white-space:nowrap;vertical-align:middle}.input-group-addon{padding:6px 12px;font-size:14px;font-weight:400;line-height:1;color:#555;text-align:center;background-color:#eee;border:1px solid #ccc;border-radius:4px}.input-group-addon.input-sm{padding:5px 10px;font-size:12px;border-radius:3px}.input-group-addon.input-lg{padding:10px 16px;font-size:18px;border-radius:6px}.input-group-addon input[type=radio],.input-group-addon input[type=checkbox]{margin-top:0}.input-group .form-control:first-child,.input-group-addon:first-child,.input-group-btn:first-child>.btn,.input-group-btn:first-child>.btn-group>.btn,.input-group-btn:first-child>.dropdown-toggle,.input-group-btn:last-child>.btn:not(:last-child):not(.dropdown-toggle),.input-group-btn:last-child>.btn-group:not(:last-child)>.btn{border-top-right-radius:0;border-bottom-right-radius:0}.input-group-addon:first-child{border-right:0}.input-group .form-control:last-child,.input-group-addon:last-child,.input-group-btn:last-child>.btn,.input-group-btn:last-child>.btn-group>.btn,.input-group-btn:last-child>.dropdown-toggle,.input-group-btn:first-child>.btn:not(:first-child),.input-group-btn:first-child>.btn-group:not(:first-child)>.btn{border-top-left-radius:0;border-bottom-left-radius:0}.input-group-addon:last-child{border-left:0}.input-group-btn{position:relative;font-size:0;white-space:nowrap}.input-group-btn>.btn{position:relative}.input-group-btn>.btn+.btn{margin-left:-1px}.input-group-btn>.btn:hover,.input-group-btn>.btn:focus,.input-group-btn>.btn:active{z-index:2}.input-group-btn:first-child>.btn,.input-group-btn:first-child>.btn-group{margin-right:-1px}.input-group-btn:last-child>.btn,.input-group-btn:last-child>.btn-group{margin-left:-1px}.nav{padding-left:0;margin-bottom:0;list-style:none}.nav>li{position:relative;display:block}.nav>li>a{position:relative;display:block;padding:10px 15px}.nav>li>a:hover,.nav>li>a:focus{text-decoration:none;background-color:#eee}.nav>li.disabled>a{color:#777}.nav>li.disabled>a:hover,.nav>li.disabled>a:focus{color:#777;text-decoration:none;cursor:not-allowed;background-color:transparent}.nav .open>a,.nav .open>a:hover,.nav .open>a:focus{background-color:#eee;border-color:#428bca}.nav .nav-divider{height:1px;margin:9px 0;overflow:hidden;background-color:#e5e5e5}.nav>li>a>img{max-width:none}.nav-tabs{border-bottom:1px solid #ddd}.nav-tabs>li{float:left;margin-bottom:-1px}.nav-tabs>li>a{margin-right:2px;line-height:1.42857143;border:1px solid transparent;border-radius:4px 4px 0 0}.nav-tabs>li>a:hover{border-color:#eee #eee #ddd}.nav-tabs>li.active>a,.nav-tabs>li.active>a:hover,.nav-tabs>li.active>a:focus{color:#555;cursor:default;background-color:#fff;border:1px solid #ddd;border-bottom-color:transparent}.nav-tabs.nav-justified{width:100%;border-bottom:0}.nav-tabs.nav-justified>li{float:none}.nav-tabs.nav-justified>li>a{margin-bottom:5px;text-align:center}.nav-tabs.nav-justified>.dropdown .dropdown-menu{top:auto;left:auto}@media (min-width:768px){.nav-tabs.nav-justified>li{display:table-cell;width:1%}.nav-tabs.nav-justified>li>a{margin-bottom:0}}.nav-tabs.nav-justified>li>a{margin-right:0;border-radius:4px}.nav-tabs.nav-justified>.active>a,.nav-tabs.nav-justified>.active>a:hover,.nav-tabs.nav-justified>.active>a:focus{border:1px solid #ddd}@media (min-width:768px){.nav-tabs.nav-justified>li>a{border-bottom:1px solid #ddd;border-radius:4px 4px 0 0}.nav-tabs.nav-justified>.active>a,.nav-tabs.nav-justified>.active>a:hover,.nav-tabs.nav-justified>.active>a:focus{border-bottom-color:#fff}}.nav-pills>li{float:left}.nav-pills>li>a{border-radius:4px}.nav-pills>li+li{margin-left:2px}.nav-pills>li.active>a,.nav-pills>li.active>a:hover,.nav-pills>li.active>a:focus{color:#fff;background-color:#428bca}.nav-stacked>li{float:none}.nav-stacked>li+li{margin-top:2px;margin-left:0}.nav-justified{width:100%}.nav-justified>li{float:none}.nav-justified>li>a{margin-bottom:5px;text-align:center}.nav-justified>.dropdown .dropdown-menu{top:auto;left:auto}@media (min-width:768px){.nav-justified>li{display:table-cell;width:1%}.nav-justified>li>a{margin-bottom:0}}.nav-tabs-justified{border-bottom:0}.nav-tabs-justified>li>a{margin-right:0;border-radius:4px}.nav-tabs-justified>.active>a,.nav-tabs-justified>.active>a:hover,.nav-tabs-justified>.active>a:focus{border:1px solid #ddd}@media (min-width:768px){.nav-tabs-justified>li>a{border-bottom:1px solid #ddd;border-radius:4px 4px 0 0}.nav-tabs-justified>.active>a,.nav-tabs-justified>.active>a:hover,.nav-tabs-justified>.active>a:focus{border-bottom-color:#fff}}.tab-content>.tab-pane{display:none}.tab-content>.active{display:block}.nav-tabs .dropdown-menu{margin-top:-1px;border-top-left-radius:0;border-top-right-radius:0}.navbar{position:relative;min-height:50px;margin-bottom:20px;border:1px solid transparent}@media (min-width:768px){.navbar{border-radius:4px}}@media (min-width:768px){.navbar-header{float:left}}.navbar-collapse{padding-right:15px;padding-left:15px;overflow-x:visible;-webkit-overflow-scrolling:touch;border-top:1px solid transparent;-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,.1);box-shadow:inset 0 1px 0 rgba(255,255,255,.1)}.navbar-collapse.in{overflow-y:auto}@media (min-width:768px){.navbar-collapse{width:auto;border-top:0;-webkit-box-shadow:none;box-shadow:none}.navbar-collapse.collapse{display:block!important;height:auto!important;padding-bottom:0;overflow:visible!important}.navbar-collapse.in{overflow-y:visible}.navbar-fixed-top .navbar-collapse,.navbar-static-top .navbar-collapse,.navbar-fixed-bottom .navbar-collapse{padding-right:0;padding-left:0}}.navbar-fixed-top .navbar-collapse,.navbar-fixed-bottom .navbar-collapse{max-height:340px}@media (max-width:480px) and (orientation:landscape){.navbar-fixed-top .navbar-collapse,.navbar-fixed-bottom .navbar-collapse{max-height:200px}}.container>.navbar-header,.container-fluid>.navbar-header,.container>.navbar-collapse,.container-fluid>.navbar-collapse{margin-right:-15px;margin-left:-15px}@media (min-width:768px){.container>.navbar-header,.container-fluid>.navbar-header,.container>.navbar-collapse,.container-fluid>.navbar-collapse{margin-right:0;margin-left:0}}.navbar-static-top{z-index:1000;border-width:0 0 1px}@media (min-width:768px){.navbar-static-top{border-radius:0}}.navbar-fixed-top,.navbar-fixed-bottom{position:fixed;right:0;left:0;z-index:1030;-webkit-transform:translate3d(0,0,0);-o-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}@media (min-width:768px){.navbar-fixed-top,.navbar-fixed-bottom{border-radius:0}}.navbar-fixed-top{top:0;border-width:0 0 1px}.navbar-fixed-bottom{bottom:0;margin-bottom:0;border-width:1px 0 0}.navbar-brand{float:left;height:50px;padding:15px 15px;font-size:18px;line-height:20px}.navbar-brand:hover,.navbar-brand:focus{text-decoration:none}@media (min-width:768px){.navbar>.container .navbar-brand,.navbar>.container-fluid .navbar-brand{margin-left:-15px}}.navbar-toggle{position:relative;float:right;padding:9px 10px;margin-top:8px;margin-right:15px;margin-bottom:8px;background-color:transparent;background-image:none;border:1px solid transparent;border-radius:4px}.navbar-toggle:focus{outline:0}.navbar-toggle .icon-bar{display:block;width:22px;height:2px;border-radius:1px}.navbar-toggle .icon-bar+.icon-bar{margin-top:4px}@media (min-width:768px){.navbar-toggle{display:none}}.navbar-nav{margin:7.5px -15px}.navbar-nav>li>a{padding-top:10px;padding-bottom:10px;line-height:20px}@media (max-width:767px){.navbar-nav .open .dropdown-menu{position:static;float:none;width:auto;margin-top:0;background-color:transparent;border:0;-webkit-box-shadow:none;box-shadow:none}.navbar-nav .open .dropdown-menu>li>a,.navbar-nav .open .dropdown-menu .dropdown-header{padding:5px 15px 5px 25px}.navbar-nav .open .dropdown-menu>li>a{line-height:20px}.navbar-nav .open .dropdown-menu>li>a:hover,.navbar-nav .open .dropdown-menu>li>a:focus{background-image:none}}@media (min-width:768px){.navbar-nav{float:left;margin:0}.navbar-nav>li{float:left}.navbar-nav>li>a{padding-top:15px;padding-bottom:15px}.navbar-nav.navbar-right:last-child{margin-right:-15px}}@media (min-width:768px){.navbar-left{float:left!important}.navbar-right{float:right!important}}.navbar-form{padding:10px 15px;margin-top:8px;margin-right:-15px;margin-bottom:8px;margin-left:-15px;border-top:1px solid transparent;border-bottom:1px solid transparent;-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,.1),0 1px 0 rgba(255,255,255,.1);box-shadow:inset 0 1px 0 rgba(255,255,255,.1),0 1px 0 rgba(255,255,255,.1)}@media (min-width:768px){.navbar-form .form-group{display:inline-block;margin-bottom:0;vertical-align:middle}.navbar-form .form-control{display:inline-block;width:auto;vertical-align:middle}.navbar-form .input-group{display:inline-table;vertical-align:middle}.navbar-form .input-group .input-group-addon,.navbar-form .input-group .input-group-btn,.navbar-form .input-group .form-control{width:auto}.navbar-form .input-group>.form-control{width:100%}.navbar-form .control-label{margin-bottom:0;vertical-align:middle}.navbar-form .radio,.navbar-form .checkbox{display:inline-block;margin-top:0;margin-bottom:0;vertical-align:middle}.navbar-form .radio label,.navbar-form .checkbox label{padding-left:0}.navbar-form .radio input[type=radio],.navbar-form .checkbox input[type=checkbox]{position:relative;margin-left:0}.navbar-form .has-feedback .form-control-feedback{top:0}}@media (max-width:767px){.navbar-form .form-group{margin-bottom:5px}}@media (min-width:768px){.navbar-form{width:auto;padding-top:0;padding-bottom:0;margin-right:0;margin-left:0;border:0;-webkit-box-shadow:none;box-shadow:none}.navbar-form.navbar-right:last-child{margin-right:-15px}}.navbar-nav>li>.dropdown-menu{margin-top:0;border-top-left-radius:0;border-top-right-radius:0}.navbar-fixed-bottom .navbar-nav>li>.dropdown-menu{border-bottom-right-radius:0;border-bottom-left-radius:0}.navbar-btn{margin-top:8px;margin-bottom:8px}.navbar-btn.btn-sm{margin-top:10px;margin-bottom:10px}.navbar-btn.btn-xs{margin-top:14px;margin-bottom:14px}.navbar-text{margin-top:15px;margin-bottom:15px}@media (min-width:768px){.navbar-text{float:left;margin-right:15px;margin-left:15px}.navbar-text.navbar-right:last-child{margin-right:0}}.navbar-default{background-color:#f8f8f8;border-color:#e7e7e7}.navbar-default .navbar-brand{color:#777}.navbar-default .navbar-brand:hover,.navbar-default .navbar-brand:focus{color:#5e5e5e;background-color:transparent}.navbar-default .navbar-text{color:#777}.navbar-default .navbar-nav>li>a{color:#777}.navbar-default .navbar-nav>li>a:hover,.navbar-default .navbar-nav>li>a:focus{color:#333;background-color:transparent}.navbar-default .navbar-nav>.active>a,.navbar-default .navbar-nav>.active>a:hover,.navbar-default .navbar-nav>.active>a:focus{color:#555;background-color:#e7e7e7}.navbar-default .navbar-nav>.disabled>a,.navbar-default .navbar-nav>.disabled>a:hover,.navbar-default .navbar-nav>.disabled>a:focus{color:#ccc;background-color:transparent}.navbar-default .navbar-toggle{border-color:#ddd}.navbar-default .navbar-toggle:hover,.navbar-default .navbar-toggle:focus{background-color:#ddd}.navbar-default .navbar-toggle .icon-bar{background-color:#888}.navbar-default .navbar-collapse,.navbar-default .navbar-form{border-color:#e7e7e7}.navbar-default .navbar-nav>.open>a,.navbar-default .navbar-nav>.open>a:hover,.navbar-default .navbar-nav>.open>a:focus{color:#555;background-color:#e7e7e7}@media (max-width:767px){.navbar-default .navbar-nav .open .dropdown-menu>li>a{color:#777}.navbar-default .navbar-nav .open .dropdown-menu>li>a:hover,.navbar-default .navbar-nav .open .dropdown-menu>li>a:focus{color:#333;background-color:transparent}.navbar-default .navbar-nav .open .dropdown-menu>.active>a,.navbar-default .navbar-nav .open .dropdown-menu>.active>a:hover,.navbar-default .navbar-nav .open .dropdown-menu>.active>a:focus{color:#555;background-color:#e7e7e7}.navbar-default .navbar-nav .open .dropdown-menu>.disabled>a,.navbar-default .navbar-nav .open .dropdown-menu>.disabled>a:hover,.navbar-default .navbar-nav .open .dropdown-menu>.disabled>a:focus{color:#ccc;background-color:transparent}}.navbar-default .navbar-link{color:#777}.navbar-default .navbar-link:hover{color:#333}.navbar-default .btn-link{color:#777}.navbar-default .btn-link:hover,.navbar-default .btn-link:focus{color:#333}.navbar-default .btn-link[disabled]:hover,fieldset[disabled] .navbar-default .btn-link:hover,.navbar-default .btn-link[disabled]:focus,fieldset[disabled] .navbar-default .btn-link:focus{color:#ccc}.navbar-inverse{background-color:#222;border-color:#080808}.navbar-inverse .navbar-brand{color:#777}.navbar-inverse .navbar-brand:hover,.navbar-inverse .navbar-brand:focus{color:#fff;background-color:transparent}.navbar-inverse .navbar-text{color:#777}.navbar-inverse .navbar-nav>li>a{color:#777}.navbar-inverse .navbar-nav>li>a:hover,.navbar-inverse .navbar-nav>li>a:focus{color:#fff;background-color:transparent}.navbar-inverse .navbar-nav>.active>a,.navbar-inverse .navbar-nav>.active>a:hover,.navbar-inverse .navbar-nav>.active>a:focus{color:#fff;background-color:#080808}.navbar-inverse .navbar-nav>.disabled>a,.navbar-inverse .navbar-nav>.disabled>a:hover,.navbar-inverse .navbar-nav>.disabled>a:focus{color:#444;background-color:transparent}.navbar-inverse .navbar-toggle{border-color:#333}.navbar-inverse .navbar-toggle:hover,.navbar-inverse .navbar-toggle:focus{background-color:#333}.navbar-inverse .navbar-toggle .icon-bar{background-color:#fff}.navbar-inverse .navbar-collapse,.navbar-inverse .navbar-form{border-color:#101010}.navbar-inverse .navbar-nav>.open>a,.navbar-inverse .navbar-nav>.open>a:hover,.navbar-inverse .navbar-nav>.open>a:focus{color:#fff;background-color:#080808}@media (max-width:767px){.navbar-inverse .navbar-nav .open .dropdown-menu>.dropdown-header{border-color:#080808}.navbar-inverse .navbar-nav .open .dropdown-menu .divider{background-color:#080808}.navbar-inverse .navbar-nav .open .dropdown-menu>li>a{color:#777}.navbar-inverse .navbar-nav .open .dropdown-menu>li>a:hover,.navbar-inverse .navbar-nav .open .dropdown-menu>li>a:focus{color:#fff;background-color:transparent}.navbar-inverse .navbar-nav .open .dropdown-menu>.active>a,.navbar-inverse .navbar-nav .open .dropdown-menu>.active>a:hover,.navbar-inverse .navbar-nav .open .dropdown-menu>.active>a:focus{color:#fff;background-color:#080808}.navbar-inverse .navbar-nav .open .dropdown-menu>.disabled>a,.navbar-inverse .navbar-nav .open .dropdown-menu>.disabled>a:hover,.navbar-inverse .navbar-nav .open .dropdown-menu>.disabled>a:focus{color:#444;background-color:transparent}}.navbar-inverse .navbar-link{color:#777}.navbar-inverse .navbar-link:hover{color:#fff}.navbar-inverse .btn-link{color:#777}.navbar-inverse .btn-link:hover,.navbar-inverse .btn-link:focus{color:#fff}.navbar-inverse .btn-link[disabled]:hover,fieldset[disabled] .navbar-inverse .btn-link:hover,.navbar-inverse .btn-link[disabled]:focus,fieldset[disabled] .navbar-inverse .btn-link:focus{color:#444}.breadcrumb{padding:8px 15px;margin-bottom:20px;list-style:none;background-color:#f5f5f5;border-radius:4px}.breadcrumb>li{display:inline-block}.breadcrumb>li+li:before{padding:0 5px;color:#ccc;content:"/\00a0"}.breadcrumb>.active{color:#777}.pagination{display:inline-block;padding-left:0;margin:20px 0;border-radius:4px}.pagination>li{display:inline}.pagination>li>a,.pagination>li>span{position:relative;float:left;padding:6px 12px;margin-left:-1px;line-height:1.42857143;color:#428bca;text-decoration:none;background-color:#fff;border:1px solid #ddd}.pagination>li:first-child>a,.pagination>li:first-child>span{margin-left:0;border-top-left-radius:4px;border-bottom-left-radius:4px}.pagination>li:last-child>a,.pagination>li:last-child>span{border-top-right-radius:4px;border-bottom-right-radius:4px}.pagination>li>a:hover,.pagination>li>span:hover,.pagination>li>a:focus,.pagination>li>span:focus{color:#2a6496;background-color:#eee;border-color:#ddd}.pagination>.active>a,.pagination>.active>span,.pagination>.active>a:hover,.pagination>.active>span:hover,.pagination>.active>a:focus,.pagination>.active>span:focus{z-index:2;color:#fff;cursor:default;background-color:#428bca;border-color:#428bca}.pagination>.disabled>span,.pagination>.disabled>span:hover,.pagination>.disabled>span:focus,.pagination>.disabled>a,.pagination>.disabled>a:hover,.pagination>.disabled>a:focus{color:#777;cursor:not-allowed;background-color:#fff;border-color:#ddd}.pagination-lg>li>a,.pagination-lg>li>span{padding:10px 16px;font-size:18px}.pagination-lg>li:first-child>a,.pagination-lg>li:first-child>span{border-top-left-radius:6px;border-bottom-left-radius:6px}.pagination-lg>li:last-child>a,.pagination-lg>li:last-child>span{border-top-right-radius:6px;border-bottom-right-radius:6px}.pagination-sm>li>a,.pagination-sm>li>span{padding:5px 10px;font-size:12px}.pagination-sm>li:first-child>a,.pagination-sm>li:first-child>span{border-top-left-radius:3px;border-bottom-left-radius:3px}.pagination-sm>li:last-child>a,.pagination-sm>li:last-child>span{border-top-right-radius:3px;border-bottom-right-radius:3px}.pager{padding-left:0;margin:20px 0;text-align:center;list-style:none}.pager li{display:inline}.pager li>a,.pager li>span{display:inline-block;padding:5px 14px;background-color:#fff;border:1px solid #ddd;border-radius:15px}.pager li>a:hover,.pager li>a:focus{text-decoration:none;background-color:#eee}.pager .next>a,.pager .next>span{float:right}.pager .previous>a,.pager .previous>span{float:left}.pager .disabled>a,.pager .disabled>a:hover,.pager .disabled>a:focus,.pager .disabled>span{color:#777;cursor:not-allowed;background-color:#fff}.label{display:inline;padding:.2em .6em .3em;font-size:75%;font-weight:700;line-height:1;color:#fff;text-align:center;white-space:nowrap;vertical-align:baseline;border-radius:.25em}a.label:hover,a.label:focus{color:#fff;text-decoration:none;cursor:pointer}.label:empty{display:none}.btn .label{position:relative;top:-1px}.label-default{background-color:#777}.label-default[href]:hover,.label-default[href]:focus{background-color:#5e5e5e}.label-primary{background-color:#428bca}.label-primary[href]:hover,.label-primary[href]:focus{background-color:#3071a9}.label-success{background-color:#5cb85c}.label-success[href]:hover,.label-success[href]:focus{background-color:#449d44}.label-info{background-color:#5bc0de}.label-info[href]:hover,.label-info[href]:focus{background-color:#31b0d5}.label-warning{background-color:#f0ad4e}.label-warning[href]:hover,.label-warning[href]:focus{background-color:#ec971f}.label-danger{background-color:#d9534f}.label-danger[href]:hover,.label-danger[href]:focus{background-color:#c9302c}.badge{display:inline-block;min-width:10px;padding:3px 7px;font-size:12px;font-weight:700;line-height:1;color:#fff;text-align:center;white-space:nowrap;vertical-align:baseline;background-color:#777;border-radius:10px}.badge:empty{display:none}.btn .badge{position:relative;top:-1px}.btn-xs .badge{top:0;padding:1px 5px}a.badge:hover,a.badge:focus{color:#fff;text-decoration:none;cursor:pointer}a.list-group-item.active>.badge,.nav-pills>.active>a>.badge{color:#428bca;background-color:#fff}.nav-pills>li>a>.badge{margin-left:3px}.jumbotron{padding:30px;margin-bottom:30px;color:inherit;background-color:#eee}.jumbotron h1,.jumbotron .h1{color:inherit}.jumbotron p{margin-bottom:15px;font-size:21px;font-weight:200}.jumbotron>hr{border-top-color:#d5d5d5}.container .jumbotron{border-radius:6px}.jumbotron .container{max-width:100%}@media screen and (min-width:768px){.jumbotron{padding-top:48px;padding-bottom:48px}.container .jumbotron{padding-right:60px;padding-left:60px}.jumbotron h1,.jumbotron .h1{font-size:63px}}.thumbnail{display:block;padding:4px;margin-bottom:20px;line-height:1.42857143;background-color:#fff;border:1px solid #ddd;border-radius:4px;-webkit-transition:all .2s ease-in-out;-o-transition:all .2s ease-in-out;transition:all .2s ease-in-out}.thumbnail>img,.thumbnail a>img{margin-right:auto;margin-left:auto}a.thumbnail:hover,a.thumbnail:focus,a.thumbnail.active{border-color:#428bca}.thumbnail .caption{padding:9px;color:#333}.alert{padding:15px;margin-bottom:20px;border:1px solid transparent;border-radius:4px}.alert h4{margin-top:0;color:inherit}.alert .alert-link{font-weight:700}.alert>p,.alert>ul{margin-bottom:0}.alert>p+p{margin-top:5px}.alert-dismissable,.alert-dismissible{padding-right:35px}.alert-dismissable .close,.alert-dismissible .close{position:relative;top:-2px;right:-21px;color:inherit}.alert-success{color:#3c763d;background-color:#dff0d8;border-color:#d6e9c6}.alert-success hr{border-top-color:#c9e2b3}.alert-success .alert-link{color:#2b542c}.alert-info{color:#31708f;background-color:#d9edf7;border-color:#bce8f1}.alert-info hr{border-top-color:#a6e1ec}.alert-info .alert-link{color:#245269}.alert-warning{color:#8a6d3b;background-color:#fcf8e3;border-color:#faebcc}.alert-warning hr{border-top-color:#f7e1b5}.alert-warning .alert-link{color:#66512c}.alert-danger{color:#a94442;background-color:#f2dede;border-color:#ebccd1}.alert-danger hr{border-top-color:#e4b9c0}.alert-danger .alert-link{color:#843534}@-webkit-keyframes progress-bar-stripes{from{background-position:40px 0}to{background-position:0 0}}@-o-keyframes progress-bar-stripes{from{background-position:40px 0}to{background-position:0 0}}@keyframes progress-bar-stripes{from{background-position:40px 0}to{background-position:0 0}}.progress{height:20px;margin-bottom:20px;overflow:hidden;background-color:#f5f5f5;border-radius:4px;-webkit-box-shadow:inset 0 1px 2px rgba(0,0,0,.1);box-shadow:inset 0 1px 2px rgba(0,0,0,.1)}.progress-bar{float:left;width:0;height:100%;font-size:12px;line-height:20px;color:#fff;text-align:center;background-color:#428bca;-webkit-box-shadow:inset 0 -1px 0 rgba(0,0,0,.15);box-shadow:inset 0 -1px 0 rgba(0,0,0,.15);-webkit-transition:width .6s ease;-o-transition:width .6s ease;transition:width .6s ease}.progress-striped .progress-bar,.progress-bar-striped{background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:-o-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);-webkit-background-size:40px 40px;background-size:40px 40px}.progress.active .progress-bar,.progress-bar.active{-webkit-animation:progress-bar-stripes 2s linear infinite;-o-animation:progress-bar-stripes 2s linear infinite;animation:progress-bar-stripes 2s linear infinite}.progress-bar[aria-valuenow="1"],.progress-bar[aria-valuenow="2"]{min-width:30px}.progress-bar[aria-valuenow="0"]{min-width:30px;color:#777;background-color:transparent;background-image:none;-webkit-box-shadow:none;box-shadow:none}.progress-bar-success{background-color:#5cb85c}.progress-striped .progress-bar-success{background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:-o-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent)}.progress-bar-info{background-color:#5bc0de}.progress-striped .progress-bar-info{background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:-o-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent)}.progress-bar-warning{background-color:#f0ad4e}.progress-striped .progress-bar-warning{background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:-o-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent)}.progress-bar-danger{background-color:#d9534f}.progress-striped .progress-bar-danger{background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:-o-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent)}.media,.media-body{overflow:hidden;zoom:1}.media,.media .media{margin-top:15px}.media:first-child{margin-top:0}.media-object{display:block}.media-heading{margin:0 0 5px}.media>.pull-left{margin-right:10px}.media>.pull-right{margin-left:10px}.media-list{padding-left:0;list-style:none}.list-group{padding-left:0;margin-bottom:20px}.list-group-item{position:relative;display:block;padding:10px 15px;margin-bottom:-1px;background-color:#fff;border:1px solid #ddd}.list-group-item:first-child{border-top-left-radius:4px;border-top-right-radius:4px}.list-group-item:last-child{margin-bottom:0;border-bottom-right-radius:4px;border-bottom-left-radius:4px}.list-group-item>.badge{float:right}.list-group-item>.badge+.badge{margin-right:5px}a.list-group-item{color:#555}a.list-group-item .list-group-item-heading{color:#333}a.list-group-item:hover,a.list-group-item:focus{color:#555;text-decoration:none;background-color:#f5f5f5}.list-group-item.disabled,.list-group-item.disabled:hover,.list-group-item.disabled:focus{color:#777;background-color:#eee}.list-group-item.disabled .list-group-item-heading,.list-group-item.disabled:hover .list-group-item-heading,.list-group-item.disabled:focus .list-group-item-heading{color:inherit}.list-group-item.disabled .list-group-item-text,.list-group-item.disabled:hover .list-group-item-text,.list-group-item.disabled:focus .list-group-item-text{color:#777}.list-group-item.active,.list-group-item.active:hover,.list-group-item.active:focus{z-index:2;color:#fff;background-color:#428bca;border-color:#428bca}.list-group-item.active .list-group-item-heading,.list-group-item.active:hover .list-group-item-heading,.list-group-item.active:focus .list-group-item-heading,.list-group-item.active .list-group-item-heading>small,.list-group-item.active:hover .list-group-item-heading>small,.list-group-item.active:focus .list-group-item-heading>small,.list-group-item.active .list-group-item-heading>.small,.list-group-item.active:hover .list-group-item-heading>.small,.list-group-item.active:focus .list-group-item-heading>.small{color:inherit}.list-group-item.active .list-group-item-text,.list-group-item.active:hover .list-group-item-text,.list-group-item.active:focus .list-group-item-text{color:#e1edf7}.list-group-item-success{color:#3c763d;background-color:#dff0d8}a.list-group-item-success{color:#3c763d}a.list-group-item-success .list-group-item-heading{color:inherit}a.list-group-item-success:hover,a.list-group-item-success:focus{color:#3c763d;background-color:#d0e9c6}a.list-group-item-success.active,a.list-group-item-success.active:hover,a.list-group-item-success.active:focus{color:#fff;background-color:#3c763d;border-color:#3c763d}.list-group-item-info{color:#31708f;background-color:#d9edf7}a.list-group-item-info{color:#31708f}a.list-group-item-info .list-group-item-heading{color:inherit}a.list-group-item-info:hover,a.list-group-item-info:focus{color:#31708f;background-color:#c4e3f3}a.list-group-item-info.active,a.list-group-item-info.active:hover,a.list-group-item-info.active:focus{color:#fff;background-color:#31708f;border-color:#31708f}.list-group-item-warning{color:#8a6d3b;background-color:#fcf8e3}a.list-group-item-warning{color:#8a6d3b}a.list-group-item-warning .list-group-item-heading{color:inherit}a.list-group-item-warning:hover,a.list-group-item-warning:focus{color:#8a6d3b;background-color:#faf2cc}a.list-group-item-warning.active,a.list-group-item-warning.active:hover,a.list-group-item-warning.active:focus{color:#fff;background-color:#8a6d3b;border-color:#8a6d3b}.list-group-item-danger{color:#a94442;background-color:#f2dede}a.list-group-item-danger{color:#a94442}a.list-group-item-danger .list-group-item-heading{color:inherit}a.list-group-item-danger:hover,a.list-group-item-danger:focus{color:#a94442;background-color:#ebcccc}a.list-group-item-danger.active,a.list-group-item-danger.active:hover,a.list-group-item-danger.active:focus{color:#fff;background-color:#a94442;border-color:#a94442}.list-group-item-heading{margin-top:0;margin-bottom:5px}.list-group-item-text{margin-bottom:0;line-height:1.3}.panel{margin-bottom:20px;background-color:#fff;border:1px solid transparent;border-radius:4px;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05)}.panel-body{padding:15px}.panel-heading{padding:10px 15px;border-bottom:1px solid transparent;border-top-left-radius:3px;border-top-right-radius:3px}.panel-heading>.dropdown .dropdown-toggle{color:inherit}.panel-title{margin-top:0;margin-bottom:0;font-size:16px;color:inherit}.panel-title>a{color:inherit}.panel-footer{padding:10px 15px;background-color:#f5f5f5;border-top:1px solid #ddd;border-bottom-right-radius:3px;border-bottom-left-radius:3px}.panel>.list-group{margin-bottom:0}.panel>.list-group .list-group-item{border-width:1px 0;border-radius:0}.panel>.list-group:first-child .list-group-item:first-child{border-top:0;border-top-left-radius:3px;border-top-right-radius:3px}.panel>.list-group:last-child .list-group-item:last-child{border-bottom:0;border-bottom-right-radius:3px;border-bottom-left-radius:3px}.panel-heading+.list-group .list-group-item:first-child{border-top-width:0}.list-group+.panel-footer{border-top-width:0}.panel>.table,.panel>.table-responsive>.table,.panel>.panel-collapse>.table{margin-bottom:0}.panel>.table:first-child,.panel>.table-responsive:first-child>.table:first-child{border-top-left-radius:3px;border-top-right-radius:3px}.panel>.table:first-child>thead:first-child>tr:first-child td:first-child,.panel>.table-responsive:first-child>.table:first-child>thead:first-child>tr:first-child td:first-child,.panel>.table:first-child>tbody:first-child>tr:first-child td:first-child,.panel>.table-responsive:first-child>.table:first-child>tbody:first-child>tr:first-child td:first-child,.panel>.table:first-child>thead:first-child>tr:first-child th:first-child,.panel>.table-responsive:first-child>.table:first-child>thead:first-child>tr:first-child th:first-child,.panel>.table:first-child>tbody:first-child>tr:first-child th:first-child,.panel>.table-responsive:first-child>.table:first-child>tbody:first-child>tr:first-child th:first-child{border-top-left-radius:3px}.panel>.table:first-child>thead:first-child>tr:first-child td:last-child,.panel>.table-responsive:first-child>.table:first-child>thead:first-child>tr:first-child td:last-child,.panel>.table:first-child>tbody:first-child>tr:first-child td:last-child,.panel>.table-responsive:first-child>.table:first-child>tbody:first-child>tr:first-child td:last-child,.panel>.table:first-child>thead:first-child>tr:first-child th:last-child,.panel>.table-responsive:first-child>.table:first-child>thead:first-child>tr:first-child th:last-child,.panel>.table:first-child>tbody:first-child>tr:first-child th:last-child,.panel>.table-responsive:first-child>.table:first-child>tbody:first-child>tr:first-child th:last-child{border-top-right-radius:3px}.panel>.table:last-child,.panel>.table-responsive:last-child>.table:last-child{border-bottom-right-radius:3px;border-bottom-left-radius:3px}.panel>.table:last-child>tbody:last-child>tr:last-child td:first-child,.panel>.table-responsive:last-child>.table:last-child>tbody:last-child>tr:last-child td:first-child,.panel>.table:last-child>tfoot:last-child>tr:last-child td:first-child,.panel>.table-responsive:last-child>.table:last-child>tfoot:last-child>tr:last-child td:first-child,.panel>.table:last-child>tbody:last-child>tr:last-child th:first-child,.panel>.table-responsive:last-child>.table:last-child>tbody:last-child>tr:last-child th:first-child,.panel>.table:last-child>tfoot:last-child>tr:last-child th:first-child,.panel>.table-responsive:last-child>.table:last-child>tfoot:last-child>tr:last-child th:first-child{border-bottom-left-radius:3px}.panel>.table:last-child>tbody:last-child>tr:last-child td:last-child,.panel>.table-responsive:last-child>.table:last-child>tbody:last-child>tr:last-child td:last-child,.panel>.table:last-child>tfoot:last-child>tr:last-child td:last-child,.panel>.table-responsive:last-child>.table:last-child>tfoot:last-child>tr:last-child td:last-child,.panel>.table:last-child>tbody:last-child>tr:last-child th:last-child,.panel>.table-responsive:last-child>.table:last-child>tbody:last-child>tr:last-child th:last-child,.panel>.table:last-child>tfoot:last-child>tr:last-child th:last-child,.panel>.table-responsive:last-child>.table:last-child>tfoot:last-child>tr:last-child th:last-child{border-bottom-right-radius:3px}.panel>.panel-body+.table,.panel>.panel-body+.table-responsive{border-top:1px solid #ddd}.panel>.table>tbody:first-child>tr:first-child th,.panel>.table>tbody:first-child>tr:first-child td{border-top:0}.panel>.table-bordered,.panel>.table-responsive>.table-bordered{border:0}.panel>.table-bordered>thead>tr>th:first-child,.panel>.table-responsive>.table-bordered>thead>tr>th:first-child,.panel>.table-bordered>tbody>tr>th:first-child,.panel>.table-responsive>.table-bordered>tbody>tr>th:first-child,.panel>.table-bordered>tfoot>tr>th:first-child,.panel>.table-responsive>.table-bordered>tfoot>tr>th:first-child,.panel>.table-bordered>thead>tr>td:first-child,.panel>.table-responsive>.table-bordered>thead>tr>td:first-child,.panel>.table-bordered>tbody>tr>td:first-child,.panel>.table-responsive>.table-bordered>tbody>tr>td:first-child,.panel>.table-bordered>tfoot>tr>td:first-child,.panel>.table-responsive>.table-bordered>tfoot>tr>td:first-child{border-left:0}.panel>.table-bordered>thead>tr>th:last-child,.panel>.table-responsive>.table-bordered>thead>tr>th:last-child,.panel>.table-bordered>tbody>tr>th:last-child,.panel>.table-responsive>.table-bordered>tbody>tr>th:last-child,.panel>.table-bordered>tfoot>tr>th:last-child,.panel>.table-responsive>.table-bordered>tfoot>tr>th:last-child,.panel>.table-bordered>thead>tr>td:last-child,.panel>.table-responsive>.table-bordered>thead>tr>td:last-child,.panel>.table-bordered>tbody>tr>td:last-child,.panel>.table-responsive>.table-bordered>tbody>tr>td:last-child,.panel>.table-bordered>tfoot>tr>td:last-child,.panel>.table-responsive>.table-bordered>tfoot>tr>td:last-child{border-right:0}.panel>.table-bordered>thead>tr:first-child>td,.panel>.table-responsive>.table-bordered>thead>tr:first-child>td,.panel>.table-bordered>tbody>tr:first-child>td,.panel>.table-responsive>.table-bordered>tbody>tr:first-child>td,.panel>.table-bordered>thead>tr:first-child>th,.panel>.table-responsive>.table-bordered>thead>tr:first-child>th,.panel>.table-bordered>tbody>tr:first-child>th,.panel>.table-responsive>.table-bordered>tbody>tr:first-child>th{border-bottom:0}.panel>.table-bordered>tbody>tr:last-child>td,.panel>.table-responsive>.table-bordered>tbody>tr:last-child>td,.panel>.table-bordered>tfoot>tr:last-child>td,.panel>.table-responsive>.table-bordered>tfoot>tr:last-child>td,.panel>.table-bordered>tbody>tr:last-child>th,.panel>.table-responsive>.table-bordered>tbody>tr:last-child>th,.panel>.table-bordered>tfoot>tr:last-child>th,.panel>.table-responsive>.table-bordered>tfoot>tr:last-child>th{border-bottom:0}.panel>.table-responsive{margin-bottom:0;border:0}.panel-group{margin-bottom:20px}.panel-group .panel{margin-bottom:0;border-radius:4px}.panel-group .panel+.panel{margin-top:5px}.panel-group .panel-heading{border-bottom:0}.panel-group .panel-heading+.panel-collapse>.panel-body{border-top:1px solid #ddd}.panel-group .panel-footer{border-top:0}.panel-group .panel-footer+.panel-collapse .panel-body{border-bottom:1px solid #ddd}.panel-default{border-color:#ddd}.panel-default>.panel-heading{color:#333;background-color:#f5f5f5;border-color:#ddd}.panel-default>.panel-heading+.panel-collapse>.panel-body{border-top-color:#ddd}.panel-default>.panel-heading .badge{color:#f5f5f5;background-color:#333}.panel-default>.panel-footer+.panel-collapse>.panel-body{border-bottom-color:#ddd}.panel-primary{border-color:#428bca}.panel-primary>.panel-heading{color:#fff;background-color:#428bca;border-color:#428bca}.panel-primary>.panel-heading+.panel-collapse>.panel-body{border-top-color:#428bca}.panel-primary>.panel-heading .badge{color:#428bca;background-color:#fff}.panel-primary>.panel-footer+.panel-collapse>.panel-body{border-bottom-color:#428bca}.panel-success{border-color:#d6e9c6}.panel-success>.panel-heading{color:#3c763d;background-color:#dff0d8;border-color:#d6e9c6}.panel-success>.panel-heading+.panel-collapse>.panel-body{border-top-color:#d6e9c6}.panel-success>.panel-heading .badge{color:#dff0d8;background-color:#3c763d}.panel-success>.panel-footer+.panel-collapse>.panel-body{border-bottom-color:#d6e9c6}.panel-info{border-color:#bce8f1}.panel-info>.panel-heading{color:#31708f;background-color:#d9edf7;border-color:#bce8f1}.panel-info>.panel-heading+.panel-collapse>.panel-body{border-top-color:#bce8f1}.panel-info>.panel-heading .badge{color:#d9edf7;background-color:#31708f}.panel-info>.panel-footer+.panel-collapse>.panel-body{border-bottom-color:#bce8f1}.panel-warning{border-color:#faebcc}.panel-warning>.panel-heading{color:#8a6d3b;background-color:#fcf8e3;border-color:#faebcc}.panel-warning>.panel-heading+.panel-collapse>.panel-body{border-top-color:#faebcc}.panel-warning>.panel-heading .badge{color:#fcf8e3;background-color:#8a6d3b}.panel-warning>.panel-footer+.panel-collapse>.panel-body{border-bottom-color:#faebcc}.panel-danger{border-color:#ebccd1}.panel-danger>.panel-heading{color:#a94442;background-color:#f2dede;border-color:#ebccd1}.panel-danger>.panel-heading+.panel-collapse>.panel-body{border-top-color:#ebccd1}.panel-danger>.panel-heading .badge{color:#f2dede;background-color:#a94442}.panel-danger>.panel-footer+.panel-collapse>.panel-body{border-bottom-color:#ebccd1}.embed-responsive{position:relative;display:block;height:0;padding:0;overflow:hidden}.embed-responsive .embed-responsive-item,.embed-responsive iframe,.embed-responsive embed,.embed-responsive object{position:absolute;top:0;bottom:0;left:0;width:100%;height:100%;border:0}.embed-responsive.embed-responsive-16by9{padding-bottom:56.25%}.embed-responsive.embed-responsive-4by3{padding-bottom:75%}.well{min-height:20px;padding:19px;margin-bottom:20px;background-color:#f5f5f5;border:1px solid #e3e3e3;border-radius:4px;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.05);box-shadow:inset 0 1px 1px rgba(0,0,0,.05)}.well blockquote{border-color:#ddd;border-color:rgba(0,0,0,.15)}.well-lg{padding:24px;border-radius:6px}.well-sm{padding:9px;border-radius:3px}.close{float:right;font-size:21px;font-weight:700;line-height:1;color:#000;text-shadow:0 1px 0 #fff;filter:alpha(opacity=20);opacity:.2}.close:hover,.close:focus{color:#000;text-decoration:none;cursor:pointer;filter:alpha(opacity=50);opacity:.5}button.close{-webkit-appearance:none;padding:0;cursor:pointer;background:0 0;border:0}.modal-open{overflow:hidden}.modal{position:fixed;top:0;right:0;bottom:0;left:0;z-index:1050;display:none;overflow:hidden;-webkit-overflow-scrolling:touch;outline:0}.modal.fade .modal-dialog{-webkit-transition:-webkit-transform .3s ease-out;-o-transition:-o-transform .3s ease-out;transition:transform .3s ease-out;-webkit-transform:translate3d(0,-25%,0);-o-transform:translate3d(0,-25%,0);transform:translate3d(0,-25%,0)}.modal.in .modal-dialog{-webkit-transform:translate3d(0,0,0);-o-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}.modal-open .modal{overflow-x:hidden;overflow-y:auto}.modal-dialog{position:relative;width:auto;margin:10px}.modal-content{position:relative;background-color:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #999;border:1px solid rgba(0,0,0,.2);border-radius:6px;outline:0;-webkit-box-shadow:0 3px 9px rgba(0,0,0,.5);box-shadow:0 3px 9px rgba(0,0,0,.5)}.modal-backdrop{position:fixed;top:0;right:0;bottom:0;left:0;z-index:1040;background-color:#000}.modal-backdrop.fade{filter:alpha(opacity=0);opacity:0}.modal-backdrop.in{filter:alpha(opacity=50);opacity:.5}.modal-header{min-height:16.43px;padding:15px;border-bottom:1px solid #e5e5e5}.modal-header .close{margin-top:-2px}.modal-title{margin:0;line-height:1.42857143}.modal-body{position:relative;padding:15px}.modal-footer{padding:15px;text-align:right;border-top:1px solid #e5e5e5}.modal-footer .btn+.btn{margin-bottom:0;margin-left:5px}.modal-footer .btn-group .btn+.btn{margin-left:-1px}.modal-footer .btn-block+.btn-block{margin-left:0}.modal-scrollbar-measure{position:absolute;top:-9999px;width:50px;height:50px;overflow:scroll}@media (min-width:768px){.modal-dialog{width:600px;margin:30px auto}.modal-content{-webkit-box-shadow:0 5px 15px rgba(0,0,0,.5);box-shadow:0 5px 15px rgba(0,0,0,.5)}.modal-sm{width:300px}}@media (min-width:992px){.modal-lg{width:900px}}.tooltip{position:absolute;z-index:1070;display:block;font-size:12px;line-height:1.4;visibility:visible;filter:alpha(opacity=0);opacity:0}.tooltip.in{filter:alpha(opacity=90);opacity:.9}.tooltip.top{padding:5px 0;margin-top:-3px}.tooltip.right{padding:0 5px;margin-left:3px}.tooltip.bottom{padding:5px 0;margin-top:3px}.tooltip.left{padding:0 5px;margin-left:-3px}.tooltip-inner{max-width:200px;padding:3px 8px;color:#fff;text-align:center;text-decoration:none;background-color:#000;border-radius:4px}.tooltip-arrow{position:absolute;width:0;height:0;border-color:transparent;border-style:solid}.tooltip.top .tooltip-arrow{bottom:0;left:50%;margin-left:-5px;border-width:5px 5px 0;border-top-color:#000}.tooltip.top-left .tooltip-arrow{bottom:0;left:5px;border-width:5px 5px 0;border-top-color:#000}.tooltip.top-right .tooltip-arrow{right:5px;bottom:0;border-width:5px 5px 0;border-top-color:#000}.tooltip.right .tooltip-arrow{top:50%;left:0;margin-top:-5px;border-width:5px 5px 5px 0;border-right-color:#000}.tooltip.left .tooltip-arrow{top:50%;right:0;margin-top:-5px;border-width:5px 0 5px 5px;border-left-color:#000}.tooltip.bottom .tooltip-arrow{top:0;left:50%;margin-left:-5px;border-width:0 5px 5px;border-bottom-color:#000}.tooltip.bottom-left .tooltip-arrow{top:0;left:5px;border-width:0 5px 5px;border-bottom-color:#000}.tooltip.bottom-right .tooltip-arrow{top:0;right:5px;border-width:0 5px 5px;border-bottom-color:#000}.popover{position:absolute;top:0;left:0;z-index:1060;display:none;max-width:276px;padding:1px;text-align:left;white-space:normal;background-color:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0,0,0,.2);border-radius:6px;-webkit-box-shadow:0 5px 10px rgba(0,0,0,.2);box-shadow:0 5px 10px rgba(0,0,0,.2)}.popover.top{margin-top:-10px}.popover.right{margin-left:10px}.popover.bottom{margin-top:10px}.popover.left{margin-left:-10px}.popover-title{padding:8px 14px;margin:0;font-size:14px;font-weight:400;line-height:18px;background-color:#f7f7f7;border-bottom:1px solid #ebebeb;border-radius:5px 5px 0 0}.popover-content{padding:9px 14px}.popover>.arrow,.popover>.arrow:after{position:absolute;display:block;width:0;height:0;border-color:transparent;border-style:solid}.popover>.arrow{border-width:11px}.popover>.arrow:after{content:"";border-width:10px}.popover.top>.arrow{bottom:-11px;left:50%;margin-left:-11px;border-top-color:#999;border-top-color:rgba(0,0,0,.25);border-bottom-width:0}.popover.top>.arrow:after{bottom:1px;margin-left:-10px;content:" ";border-top-color:#fff;border-bottom-width:0}.popover.right>.arrow{top:50%;left:-11px;margin-top:-11px;border-right-color:#999;border-right-color:rgba(0,0,0,.25);border-left-width:0}.popover.right>.arrow:after{bottom:-10px;left:1px;content:" ";border-right-color:#fff;border-left-width:0}.popover.bottom>.arrow{top:-11px;left:50%;margin-left:-11px;border-top-width:0;border-bottom-color:#999;border-bottom-color:rgba(0,0,0,.25)}.popover.bottom>.arrow:after{top:1px;margin-left:-10px;content:" ";border-top-width:0;border-bottom-color:#fff}.popover.left>.arrow{top:50%;right:-11px;margin-top:-11px;border-right-width:0;border-left-color:#999;border-left-color:rgba(0,0,0,.25)}.popover.left>.arrow:after{right:1px;bottom:-10px;content:" ";border-right-width:0;border-left-color:#fff}.carousel{position:relative}.carousel-inner{position:relative;width:100%;overflow:hidden}.carousel-inner>.item{position:relative;display:none;-webkit-transition:.6s ease-in-out left;-o-transition:.6s ease-in-out left;transition:.6s ease-in-out left}.carousel-inner>.item>img,.carousel-inner>.item>a>img{line-height:1}.carousel-inner>.active,.carousel-inner>.next,.carousel-inner>.prev{display:block}.carousel-inner>.active{left:0}.carousel-inner>.next,.carousel-inner>.prev{position:absolute;top:0;width:100%}.carousel-inner>.next{left:100%}.carousel-inner>.prev{left:-100%}.carousel-inner>.next.left,.carousel-inner>.prev.right{left:0}.carousel-inner>.active.left{left:-100%}.carousel-inner>.active.right{left:100%}.carousel-control{position:absolute;top:0;bottom:0;left:0;width:15%;font-size:20px;color:#fff;text-align:center;text-shadow:0 1px 2px rgba(0,0,0,.6);filter:alpha(opacity=50);opacity:.5}.carousel-control.left{background-image:-webkit-linear-gradient(left,rgba(0,0,0,.5) 0,rgba(0,0,0,.0001) 100%);background-image:-o-linear-gradient(left,rgba(0,0,0,.5) 0,rgba(0,0,0,.0001) 100%);background-image:-webkit-gradient(linear,left top,right top,from(rgba(0,0,0,.5)),to(rgba(0,0,0,.0001)));background-image:linear-gradient(to right,rgba(0,0,0,.5) 0,rgba(0,0,0,.0001) 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#80000000', endColorstr='#00000000', GradientType=1);background-repeat:repeat-x}.carousel-control.right{right:0;left:auto;background-image:-webkit-linear-gradient(left,rgba(0,0,0,.0001) 0,rgba(0,0,0,.5) 100%);background-image:-o-linear-gradient(left,rgba(0,0,0,.0001) 0,rgba(0,0,0,.5) 100%);background-image:-webkit-gradient(linear,left top,right top,from(rgba(0,0,0,.0001)),to(rgba(0,0,0,.5)));background-image:linear-gradient(to right,rgba(0,0,0,.0001) 0,rgba(0,0,0,.5) 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#00000000', endColorstr='#80000000', GradientType=1);background-repeat:repeat-x}.carousel-control:hover,.carousel-control:focus{color:#fff;text-decoration:none;filter:alpha(opacity=90);outline:0;opacity:.9}.carousel-control .icon-prev,.carousel-control .icon-next,.carousel-control .glyphicon-chevron-left,.carousel-control .glyphicon-chevron-right{position:absolute;top:50%;z-index:5;display:inline-block}.carousel-control .icon-prev,.carousel-control .glyphicon-chevron-left{left:50%;margin-left:-10px}.carousel-control .icon-next,.carousel-control .glyphicon-chevron-right{right:50%;margin-right:-10px}.carousel-control .icon-prev,.carousel-control .icon-next{width:20px;height:20px;margin-top:-10px;font-family:serif}.carousel-control .icon-prev:before{content:'\2039'}.carousel-control .icon-next:before{content:'\203a'}.carousel-indicators{position:absolute;bottom:10px;left:50%;z-index:15;width:60%;padding-left:0;margin-left:-30%;text-align:center;list-style:none}.carousel-indicators li{display:inline-block;width:10px;height:10px;margin:1px;text-indent:-999px;cursor:pointer;background-color:#000 \9;background-color:rgba(0,0,0,0);border:1px solid #fff;border-radius:10px}.carousel-indicators .active{width:12px;height:12px;margin:0;background-color:#fff}.carousel-caption{position:absolute;right:15%;bottom:20px;left:15%;z-index:10;padding-top:20px;padding-bottom:20px;color:#fff;text-align:center;text-shadow:0 1px 2px rgba(0,0,0,.6)}.carousel-caption .btn{text-shadow:none}@media screen and (min-width:768px){.carousel-control .glyphicon-chevron-left,.carousel-control .glyphicon-chevron-right,.carousel-control .icon-prev,.carousel-control .icon-next{width:30px;height:30px;margin-top:-15px;font-size:30px}.carousel-control .glyphicon-chevron-left,.carousel-control .icon-prev{margin-left:-15px}.carousel-control .glyphicon-chevron-right,.carousel-control .icon-next{margin-right:-15px}.carousel-caption{right:20%;left:20%;padding-bottom:30px}.carousel-indicators{bottom:20px}}.clearfix:before,.clearfix:after,.dl-horizontal dd:before,.dl-horizontal dd:after,.container:before,.container:after,.container-fluid:before,.container-fluid:after,.row:before,.row:after,.form-horizontal .form-group:before,.form-horizontal .form-group:after,.btn-toolbar:before,.btn-toolbar:after,.btn-group-vertical>.btn-group:before,.btn-group-vertical>.btn-group:after,.nav:before,.nav:after,.navbar:before,.navbar:after,.navbar-header:before,.navbar-header:after,.navbar-collapse:before,.navbar-collapse:after,.pager:before,.pager:after,.panel-body:before,.panel-body:after,.modal-footer:before,.modal-footer:after{display:table;content:" "}.clearfix:after,.dl-horizontal dd:after,.container:after,.container-fluid:after,.row:after,.form-horizontal .form-group:after,.btn-toolbar:after,.btn-group-vertical>.btn-group:after,.nav:after,.navbar:after,.navbar-header:after,.navbar-collapse:after,.pager:after,.panel-body:after,.modal-footer:after{clear:both}.center-block{display:block;margin-right:auto;margin-left:auto}.pull-right{float:right!important}.pull-left{float:left!important}.hide{display:none!important}.show{display:block!important}.invisible{visibility:hidden}.text-hide{font:0/0 a;color:transparent;text-shadow:none;background-color:transparent;border:0}.hidden{display:none!important;visibility:hidden!important}.affix{position:fixed;-webkit-transform:translate3d(0,0,0);-o-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}@-ms-viewport{width:device-width}.visible-xs,.visible-sm,.visible-md,.visible-lg{display:none!important}.visible-xs-block,.visible-xs-inline,.visible-xs-inline-block,.visible-sm-block,.visible-sm-inline,.visible-sm-inline-block,.visible-md-block,.visible-md-inline,.visible-md-inline-block,.visible-lg-block,.visible-lg-inline,.visible-lg-inline-block{display:none!important}@media (max-width:767px){.visible-xs{display:block!important}table.visible-xs{display:table}tr.visible-xs{display:table-row!important}th.visible-xs,td.visible-xs{display:table-cell!important}}@media (max-width:767px){.visible-xs-block{display:block!important}}@media (max-width:767px){.visible-xs-inline{display:inline!important}}@media (max-width:767px){.visible-xs-inline-block{display:inline-block!important}}@media (min-width:768px) and (max-width:991px){.visible-sm{display:block!important}table.visible-sm{display:table}tr.visible-sm{display:table-row!important}th.visible-sm,td.visible-sm{display:table-cell!important}}@media (min-width:768px) and (max-width:991px){.visible-sm-block{display:block!important}}@media (min-width:768px) and (max-width:991px){.visible-sm-inline{display:inline!important}}@media (min-width:768px) and (max-width:991px){.visible-sm-inline-block{display:inline-block!important}}@media (min-width:992px) and (max-width:1199px){.visible-md{display:block!important}table.visible-md{display:table}tr.visible-md{display:table-row!important}th.visible-md,td.visible-md{display:table-cell!important}}@media (min-width:992px) and (max-width:1199px){.visible-md-block{display:block!important}}@media (min-width:992px) and (max-width:1199px){.visible-md-inline{display:inline!important}}@media (min-width:992px) and (max-width:1199px){.visible-md-inline-block{display:inline-block!important}}@media (min-width:1200px){.visible-lg{display:block!important}table.visible-lg{display:table}tr.visible-lg{display:table-row!important}th.visible-lg,td.visible-lg{display:table-cell!important}}@media (min-width:1200px){.visible-lg-block{display:block!important}}@media (min-width:1200px){.visible-lg-inline{display:inline!important}}@media (min-width:1200px){.visible-lg-inline-block{display:inline-block!important}}@media (max-width:767px){.hidden-xs{display:none!important}}@media (min-width:768px) and (max-width:991px){.hidden-sm{display:none!important}}@media (min-width:992px) and (max-width:1199px){.hidden-md{display:none!important}}@media (min-width:1200px){.hidden-lg{display:none!important}}.visible-print{display:none!important}@media print{.visible-print{display:block!important}table.visible-print{display:table}tr.visible-print{display:table-row!important}th.visible-print,td.visible-print{display:table-cell!important}}.visible-print-block{display:none!important}@media print{.visible-print-block{display:block!important}}.visible-print-inline{display:none!important}@media print{.visible-print-inline{display:inline!important}}.visible-print-inline-block{display:none!important}@media print{.visible-print-inline-block{display:inline-block!important}}@media print{.hidden-print{display:none!important}} + *//*! normalize.css v3.0.1 | MIT License | git.io/normalize */html{font-family:sans-serif;-webkit-text-size-adjust:100%;-ms-text-size-adjust:100%}body{margin:0}article,aside,details,figcaption,figure,footer,header,hgroup,main,nav,section,summary{display:block}audio,canvas,progress,video{display:inline-block;vertical-align:baseline}audio:not([controls]){display:none;height:0}[hidden],template{display:none}a{background:0 0}a:active,a:hover{outline:0}abbr[title]{border-bottom:1px dotted}b,strong{font-weight:700}dfn{font-style:italic}h1{margin:.67em 0;font-size:2em}mark{color:#000;background:#ff0}small{font-size:80%}sub,sup{position:relative;font-size:75%;line-height:0;vertical-align:baseline}sup{top:-.5em}sub{bottom:-.25em}img{border:0}svg:not(:root){overflow:hidden}figure{margin:1em 40px}hr{height:0;-webkit-box-sizing:content-box;-moz-box-sizing:content-box;box-sizing:content-box}pre{overflow:auto}code,kbd,pre,samp{font-family:monospace,monospace;font-size:1em}button,input,optgroup,select,textarea{margin:0;font:inherit;color:inherit}button{overflow:visible}button,select{text-transform:none}button,html input[type=button],input[type=reset],input[type=submit]{-webkit-appearance:button;cursor:pointer}button[disabled],html input[disabled]{cursor:default}button::-moz-focus-inner,input::-moz-focus-inner{padding:0;border:0}input{line-height:normal}input[type=checkbox],input[type=radio]{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;padding:0}input[type=number]::-webkit-inner-spin-button,input[type=number]::-webkit-outer-spin-button{height:auto}input[type=search]{-webkit-box-sizing:content-box;-moz-box-sizing:content-box;box-sizing:content-box;-webkit-appearance:textfield}input[type=search]::-webkit-search-cancel-button,input[type=search]::-webkit-search-decoration{-webkit-appearance:none}fieldset{padding:.35em .625em .75em;margin:0 2px;border:1px solid silver}legend{padding:0;border:0}textarea{overflow:auto}optgroup{font-weight:700}table{border-spacing:0;border-collapse:collapse}td,th{padding:0}@media print{*{color:#000!important;text-shadow:none!important;background:transparent!important;-webkit-box-shadow:none!important;box-shadow:none!important}a,a:visited{text-decoration:underline}a[href]:after{content:" (" attr(href) ")"}abbr[title]:after{content:" (" attr(title) ")"}a[href^="javascript:"]:after,a[href^="#"]:after{content:""}pre,blockquote{border:1px solid #999;page-break-inside:avoid}thead{display:table-header-group}tr,img{page-break-inside:avoid}img{max-width:100%!important}p,h2,h3{orphans:3;widows:3}h2,h3{page-break-after:avoid}select{background:#fff!important}.navbar{display:none}.table td,.table th{background-color:#fff!important}.btn>.caret,.dropup>.btn>.caret{border-top-color:#000!important}.label{border:1px solid #000}.table{border-collapse:collapse!important}.table-bordered th,.table-bordered td{border:1px solid #ddd!important}}@font-face{font-family:'Glyphicons Halflings';src:url(../fonts/glyphicons-halflings-regular.eot);src:url(../fonts/glyphicons-halflings-regular.eot?#iefix) format('embedded-opentype'),url(../fonts/glyphicons-halflings-regular.woff) format('woff'),url(../fonts/glyphicons-halflings-regular.ttf) format('truetype'),url(../fonts/glyphicons-halflings-regular.svg#glyphicons_halflingsregular) format('svg')}.glyphicon{position:relative;top:1px;display:inline-block;font-family:'Glyphicons Halflings';font-style:normal;font-weight:400;line-height:1;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.glyphicon-asterisk:before{content:"\2a"}.glyphicon-plus:before{content:"\2b"}.glyphicon-euro:before{content:"\20ac"}.glyphicon-minus:before{content:"\2212"}.glyphicon-cloud:before{content:"\2601"}.glyphicon-envelope:before{content:"\2709"}.glyphicon-pencil:before{content:"\270f"}.glyphicon-glass:before{content:"\e001"}.glyphicon-music:before{content:"\e002"}.glyphicon-search:before{content:"\e003"}.glyphicon-heart:before{content:"\e005"}.glyphicon-star:before{content:"\e006"}.glyphicon-star-empty:before{content:"\e007"}.glyphicon-user:before{content:"\e008"}.glyphicon-film:before{content:"\e009"}.glyphicon-th-large:before{content:"\e010"}.glyphicon-th:before{content:"\e011"}.glyphicon-th-list:before{content:"\e012"}.glyphicon-ok:before{content:"\e013"}.glyphicon-remove:before{content:"\e014"}.glyphicon-zoom-in:before{content:"\e015"}.glyphicon-zoom-out:before{content:"\e016"}.glyphicon-off:before{content:"\e017"}.glyphicon-signal:before{content:"\e018"}.glyphicon-cog:before{content:"\e019"}.glyphicon-trash:before{content:"\e020"}.glyphicon-home:before{content:"\e021"}.glyphicon-file:before{content:"\e022"}.glyphicon-time:before{content:"\e023"}.glyphicon-road:before{content:"\e024"}.glyphicon-download-alt:before{content:"\e025"}.glyphicon-download:before{content:"\e026"}.glyphicon-upload:before{content:"\e027"}.glyphicon-inbox:before{content:"\e028"}.glyphicon-play-circle:before{content:"\e029"}.glyphicon-repeat:before{content:"\e030"}.glyphicon-refresh:before{content:"\e031"}.glyphicon-list-alt:before{content:"\e032"}.glyphicon-lock:before{content:"\e033"}.glyphicon-flag:before{content:"\e034"}.glyphicon-headphones:before{content:"\e035"}.glyphicon-volume-off:before{content:"\e036"}.glyphicon-volume-down:before{content:"\e037"}.glyphicon-volume-up:before{content:"\e038"}.glyphicon-qrcode:before{content:"\e039"}.glyphicon-barcode:before{content:"\e040"}.glyphicon-tag:before{content:"\e041"}.glyphicon-tags:before{content:"\e042"}.glyphicon-book:before{content:"\e043"}.glyphicon-bookmark:before{content:"\e044"}.glyphicon-print:before{content:"\e045"}.glyphicon-camera:before{content:"\e046"}.glyphicon-font:before{content:"\e047"}.glyphicon-bold:before{content:"\e048"}.glyphicon-italic:before{content:"\e049"}.glyphicon-text-height:before{content:"\e050"}.glyphicon-text-width:before{content:"\e051"}.glyphicon-align-left:before{content:"\e052"}.glyphicon-align-center:before{content:"\e053"}.glyphicon-align-right:before{content:"\e054"}.glyphicon-align-justify:before{content:"\e055"}.glyphicon-list:before{content:"\e056"}.glyphicon-indent-left:before{content:"\e057"}.glyphicon-indent-right:before{content:"\e058"}.glyphicon-facetime-video:before{content:"\e059"}.glyphicon-picture:before{content:"\e060"}.glyphicon-map-marker:before{content:"\e062"}.glyphicon-adjust:before{content:"\e063"}.glyphicon-tint:before{content:"\e064"}.glyphicon-edit:before{content:"\e065"}.glyphicon-share:before{content:"\e066"}.glyphicon-check:before{content:"\e067"}.glyphicon-move:before{content:"\e068"}.glyphicon-step-backward:before{content:"\e069"}.glyphicon-fast-backward:before{content:"\e070"}.glyphicon-backward:before{content:"\e071"}.glyphicon-play:before{content:"\e072"}.glyphicon-pause:before{content:"\e073"}.glyphicon-stop:before{content:"\e074"}.glyphicon-forward:before{content:"\e075"}.glyphicon-fast-forward:before{content:"\e076"}.glyphicon-step-forward:before{content:"\e077"}.glyphicon-eject:before{content:"\e078"}.glyphicon-chevron-left:before{content:"\e079"}.glyphicon-chevron-right:before{content:"\e080"}.glyphicon-plus-sign:before{content:"\e081"}.glyphicon-minus-sign:before{content:"\e082"}.glyphicon-remove-sign:before{content:"\e083"}.glyphicon-ok-sign:before{content:"\e084"}.glyphicon-question-sign:before{content:"\e085"}.glyphicon-info-sign:before{content:"\e086"}.glyphicon-screenshot:before{content:"\e087"}.glyphicon-remove-circle:before{content:"\e088"}.glyphicon-ok-circle:before{content:"\e089"}.glyphicon-ban-circle:before{content:"\e090"}.glyphicon-arrow-left:before{content:"\e091"}.glyphicon-arrow-right:before{content:"\e092"}.glyphicon-arrow-up:before{content:"\e093"}.glyphicon-arrow-down:before{content:"\e094"}.glyphicon-share-alt:before{content:"\e095"}.glyphicon-resize-full:before{content:"\e096"}.glyphicon-resize-small:before{content:"\e097"}.glyphicon-exclamation-sign:before{content:"\e101"}.glyphicon-gift:before{content:"\e102"}.glyphicon-leaf:before{content:"\e103"}.glyphicon-fire:before{content:"\e104"}.glyphicon-eye-open:before{content:"\e105"}.glyphicon-eye-close:before{content:"\e106"}.glyphicon-warning-sign:before{content:"\e107"}.glyphicon-plane:before{content:"\e108"}.glyphicon-calendar:before{content:"\e109"}.glyphicon-random:before{content:"\e110"}.glyphicon-comment:before{content:"\e111"}.glyphicon-magnet:before{content:"\e112"}.glyphicon-chevron-up:before{content:"\e113"}.glyphicon-chevron-down:before{content:"\e114"}.glyphicon-retweet:before{content:"\e115"}.glyphicon-shopping-cart:before{content:"\e116"}.glyphicon-folder-close:before{content:"\e117"}.glyphicon-folder-open:before{content:"\e118"}.glyphicon-resize-vertical:before{content:"\e119"}.glyphicon-resize-horizontal:before{content:"\e120"}.glyphicon-hdd:before{content:"\e121"}.glyphicon-bullhorn:before{content:"\e122"}.glyphicon-bell:before{content:"\e123"}.glyphicon-certificate:before{content:"\e124"}.glyphicon-thumbs-up:before{content:"\e125"}.glyphicon-thumbs-down:before{content:"\e126"}.glyphicon-hand-right:before{content:"\e127"}.glyphicon-hand-left:before{content:"\e128"}.glyphicon-hand-up:before{content:"\e129"}.glyphicon-hand-down:before{content:"\e130"}.glyphicon-circle-arrow-right:before{content:"\e131"}.glyphicon-circle-arrow-left:before{content:"\e132"}.glyphicon-circle-arrow-up:before{content:"\e133"}.glyphicon-circle-arrow-down:before{content:"\e134"}.glyphicon-globe:before{content:"\e135"}.glyphicon-wrench:before{content:"\e136"}.glyphicon-tasks:before{content:"\e137"}.glyphicon-filter:before{content:"\e138"}.glyphicon-briefcase:before{content:"\e139"}.glyphicon-fullscreen:before{content:"\e140"}.glyphicon-dashboard:before{content:"\e141"}.glyphicon-paperclip:before{content:"\e142"}.glyphicon-heart-empty:before{content:"\e143"}.glyphicon-link:before{content:"\e144"}.glyphicon-phone:before{content:"\e145"}.glyphicon-pushpin:before{content:"\e146"}.glyphicon-usd:before{content:"\e148"}.glyphicon-gbp:before{content:"\e149"}.glyphicon-sort:before{content:"\e150"}.glyphicon-sort-by-alphabet:before{content:"\e151"}.glyphicon-sort-by-alphabet-alt:before{content:"\e152"}.glyphicon-sort-by-order:before{content:"\e153"}.glyphicon-sort-by-order-alt:before{content:"\e154"}.glyphicon-sort-by-attributes:before{content:"\e155"}.glyphicon-sort-by-attributes-alt:before{content:"\e156"}.glyphicon-unchecked:before{content:"\e157"}.glyphicon-expand:before{content:"\e158"}.glyphicon-collapse-down:before{content:"\e159"}.glyphicon-collapse-up:before{content:"\e160"}.glyphicon-log-in:before{content:"\e161"}.glyphicon-flash:before{content:"\e162"}.glyphicon-log-out:before{content:"\e163"}.glyphicon-new-window:before{content:"\e164"}.glyphicon-record:before{content:"\e165"}.glyphicon-save:before{content:"\e166"}.glyphicon-open:before{content:"\e167"}.glyphicon-saved:before{content:"\e168"}.glyphicon-import:before{content:"\e169"}.glyphicon-export:before{content:"\e170"}.glyphicon-send:before{content:"\e171"}.glyphicon-floppy-disk:before{content:"\e172"}.glyphicon-floppy-saved:before{content:"\e173"}.glyphicon-floppy-remove:before{content:"\e174"}.glyphicon-floppy-save:before{content:"\e175"}.glyphicon-floppy-open:before{content:"\e176"}.glyphicon-credit-card:before{content:"\e177"}.glyphicon-transfer:before{content:"\e178"}.glyphicon-cutlery:before{content:"\e179"}.glyphicon-header:before{content:"\e180"}.glyphicon-compressed:before{content:"\e181"}.glyphicon-earphone:before{content:"\e182"}.glyphicon-phone-alt:before{content:"\e183"}.glyphicon-tower:before{content:"\e184"}.glyphicon-stats:before{content:"\e185"}.glyphicon-sd-video:before{content:"\e186"}.glyphicon-hd-video:before{content:"\e187"}.glyphicon-subtitles:before{content:"\e188"}.glyphicon-sound-stereo:before{content:"\e189"}.glyphicon-sound-dolby:before{content:"\e190"}.glyphicon-sound-5-1:before{content:"\e191"}.glyphicon-sound-6-1:before{content:"\e192"}.glyphicon-sound-7-1:before{content:"\e193"}.glyphicon-copyright-mark:before{content:"\e194"}.glyphicon-registration-mark:before{content:"\e195"}.glyphicon-cloud-download:before{content:"\e197"}.glyphicon-cloud-upload:before{content:"\e198"}.glyphicon-tree-conifer:before{content:"\e199"}.glyphicon-tree-deciduous:before{content:"\e200"}*{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}:before,:after{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}html{font-size:10px;-webkit-tap-highlight-color:rgba(0,0,0,0)}body{font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:14px;line-height:1.42857143;color:#333;background-color:#fff}input,button,select,textarea{font-family:inherit;font-size:inherit;line-height:inherit}a{color:#428bca;text-decoration:none}a:hover,a:focus{color:#2a6496;text-decoration:underline}a:focus{outline:thin dotted;outline:5px auto -webkit-focus-ring-color;outline-offset:-2px}figure{margin:0}img{vertical-align:middle}.img-responsive,.thumbnail>img,.thumbnail a>img,.carousel-inner>.item>img,.carousel-inner>.item>a>img{display:block;width:100% \9;max-width:100%;height:auto}.img-rounded{border-radius:6px}.img-thumbnail{display:inline-block;width:100% \9;max-width:100%;height:auto;padding:4px;line-height:1.42857143;background-color:#fff;border:1px solid #ddd;border-radius:4px;-webkit-transition:all .2s ease-in-out;-o-transition:all .2s ease-in-out;transition:all .2s ease-in-out}.img-circle{border-radius:50%}hr{margin-top:20px;margin-bottom:20px;border:0;border-top:1px solid #eee}.sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);border:0}.sr-only-focusable:active,.sr-only-focusable:focus{position:static;width:auto;height:auto;margin:0;overflow:visible;clip:auto}h1,h2,h3,h4,h5,h6,.h1,.h2,.h3,.h4,.h5,.h6{font-family:inherit;font-weight:500;line-height:1.1;color:inherit}h1 small,h2 small,h3 small,h4 small,h5 small,h6 small,.h1 small,.h2 small,.h3 small,.h4 small,.h5 small,.h6 small,h1 .small,h2 .small,h3 .small,h4 .small,h5 .small,h6 .small,.h1 .small,.h2 .small,.h3 .small,.h4 .small,.h5 .small,.h6 .small{font-weight:400;line-height:1;color:#777}h1,.h1,h2,.h2,h3,.h3{margin-top:20px;margin-bottom:10px}h1 small,.h1 small,h2 small,.h2 small,h3 small,.h3 small,h1 .small,.h1 .small,h2 .small,.h2 .small,h3 .small,.h3 .small{font-size:65%}h4,.h4,h5,.h5,h6,.h6{margin-top:10px;margin-bottom:10px}h4 small,.h4 small,h5 small,.h5 small,h6 small,.h6 small,h4 .small,.h4 .small,h5 .small,.h5 .small,h6 .small,.h6 .small{font-size:75%}h1,.h1{font-size:36px}h2,.h2{font-size:30px}h3,.h3{font-size:24px}h4,.h4{font-size:18px}h5,.h5{font-size:14px}h6,.h6{font-size:12px}p{margin:0 0 10px}.lead{margin-bottom:20px;font-size:16px;font-weight:300;line-height:1.4}@media (min-width:768px){.lead{font-size:21px}}small,.small{font-size:85%}cite{font-style:normal}mark,.mark{padding:.2em;background-color:#fcf8e3}.text-left{text-align:left}.text-right{text-align:right}.text-center{text-align:center}.text-justify{text-align:justify}.text-nowrap{white-space:nowrap}.text-lowercase{text-transform:lowercase}.text-uppercase{text-transform:uppercase}.text-capitalize{text-transform:capitalize}.text-muted{color:#777}.text-primary{color:#428bca}a.text-primary:hover{color:#3071a9}.text-success{color:#3c763d}a.text-success:hover{color:#2b542c}.text-info{color:#31708f}a.text-info:hover{color:#245269}.text-warning{color:#8a6d3b}a.text-warning:hover{color:#66512c}.text-danger{color:#a94442}a.text-danger:hover{color:#843534}.bg-primary{color:#fff;background-color:#428bca}a.bg-primary:hover{background-color:#3071a9}.bg-success{background-color:#dff0d8}a.bg-success:hover{background-color:#c1e2b3}.bg-info{background-color:#d9edf7}a.bg-info:hover{background-color:#afd9ee}.bg-warning{background-color:#fcf8e3}a.bg-warning:hover{background-color:#f7ecb5}.bg-danger{background-color:#f2dede}a.bg-danger:hover{background-color:#e4b9b9}.page-header{padding-bottom:9px;margin:40px 0 20px;border-bottom:1px solid #eee}ul,ol{margin-top:0;margin-bottom:10px}ul ul,ol ul,ul ol,ol ol{margin-bottom:0}.list-unstyled{padding-left:0;list-style:none}.list-inline{padding-left:0;margin-left:-5px;list-style:none}.list-inline>li{display:inline-block;padding-right:5px;padding-left:5px}dl{margin-top:0;margin-bottom:20px}dt,dd{line-height:1.42857143}dt{font-weight:700}dd{margin-left:0}@media (min-width:768px){.dl-horizontal dt{float:left;width:160px;overflow:hidden;clear:left;text-align:right;text-overflow:ellipsis;white-space:nowrap}.dl-horizontal dd{margin-left:180px}}abbr[title],abbr[data-original-title]{cursor:help;border-bottom:1px dotted #777}.initialism{font-size:90%;text-transform:uppercase}blockquote{padding:10px 20px;margin:0 0 20px;font-size:17.5px;border-left:5px solid #eee}blockquote p:last-child,blockquote ul:last-child,blockquote ol:last-child{margin-bottom:0}blockquote footer,blockquote small,blockquote .small{display:block;font-size:80%;line-height:1.42857143;color:#777}blockquote footer:before,blockquote small:before,blockquote .small:before{content:'\2014 \00A0'}.blockquote-reverse,blockquote.pull-right{padding-right:15px;padding-left:0;text-align:right;border-right:5px solid #eee;border-left:0}.blockquote-reverse footer:before,blockquote.pull-right footer:before,.blockquote-reverse small:before,blockquote.pull-right small:before,.blockquote-reverse .small:before,blockquote.pull-right .small:before{content:''}.blockquote-reverse footer:after,blockquote.pull-right footer:after,.blockquote-reverse small:after,blockquote.pull-right small:after,.blockquote-reverse .small:after,blockquote.pull-right .small:after{content:'\00A0 \2014'}blockquote:before,blockquote:after{content:""}address{margin-bottom:20px;font-style:normal;line-height:1.42857143}code,kbd,pre,samp{font-family:Menlo,Monaco,Consolas,"Courier New",monospace}code{padding:2px 4px;font-size:90%;color:#c7254e;background-color:#f9f2f4;border-radius:4px}kbd{padding:2px 4px;font-size:90%;color:#fff;background-color:#333;border-radius:3px;-webkit-box-shadow:inset 0 -1px 0 rgba(0,0,0,.25);box-shadow:inset 0 -1px 0 rgba(0,0,0,.25)}kbd kbd{padding:0;font-size:100%;-webkit-box-shadow:none;box-shadow:none}pre{display:block;padding:9.5px;margin:0 0 10px;font-size:13px;line-height:1.42857143;color:#333;word-break:break-all;word-wrap:break-word;background-color:#f5f5f5;border:1px solid #ccc;border-radius:4px}pre code{padding:0;font-size:inherit;color:inherit;white-space:pre-wrap;background-color:transparent;border-radius:0}.pre-scrollable{max-height:340px;overflow-y:scroll}.container{padding-right:15px;padding-left:15px;margin-right:auto;margin-left:auto}@media (min-width:768px){.container{width:750px}}@media (min-width:992px){.container{width:970px}}@media (min-width:1200px){.container{width:1170px}}.container-fluid{padding-right:15px;padding-left:15px;margin-right:auto;margin-left:auto}.row{margin-right:-15px;margin-left:-15px}.col-xs-1,.col-sm-1,.col-md-1,.col-lg-1,.col-xs-2,.col-sm-2,.col-md-2,.col-lg-2,.col-xs-3,.col-sm-3,.col-md-3,.col-lg-3,.col-xs-4,.col-sm-4,.col-md-4,.col-lg-4,.col-xs-5,.col-sm-5,.col-md-5,.col-lg-5,.col-xs-6,.col-sm-6,.col-md-6,.col-lg-6,.col-xs-7,.col-sm-7,.col-md-7,.col-lg-7,.col-xs-8,.col-sm-8,.col-md-8,.col-lg-8,.col-xs-9,.col-sm-9,.col-md-9,.col-lg-9,.col-xs-10,.col-sm-10,.col-md-10,.col-lg-10,.col-xs-11,.col-sm-11,.col-md-11,.col-lg-11,.col-xs-12,.col-sm-12,.col-md-12,.col-lg-12{position:relative;min-height:1px;padding-right:15px;padding-left:15px}.col-xs-1,.col-xs-2,.col-xs-3,.col-xs-4,.col-xs-5,.col-xs-6,.col-xs-7,.col-xs-8,.col-xs-9,.col-xs-10,.col-xs-11,.col-xs-12{float:left}.col-xs-12{width:100%}.col-xs-11{width:91.66666667%}.col-xs-10{width:83.33333333%}.col-xs-9{width:75%}.col-xs-8{width:66.66666667%}.col-xs-7{width:58.33333333%}.col-xs-6{width:50%}.col-xs-5{width:41.66666667%}.col-xs-4{width:33.33333333%}.col-xs-3{width:25%}.col-xs-2{width:16.66666667%}.col-xs-1{width:8.33333333%}.col-xs-pull-12{right:100%}.col-xs-pull-11{right:91.66666667%}.col-xs-pull-10{right:83.33333333%}.col-xs-pull-9{right:75%}.col-xs-pull-8{right:66.66666667%}.col-xs-pull-7{right:58.33333333%}.col-xs-pull-6{right:50%}.col-xs-pull-5{right:41.66666667%}.col-xs-pull-4{right:33.33333333%}.col-xs-pull-3{right:25%}.col-xs-pull-2{right:16.66666667%}.col-xs-pull-1{right:8.33333333%}.col-xs-pull-0{right:auto}.col-xs-push-12{left:100%}.col-xs-push-11{left:91.66666667%}.col-xs-push-10{left:83.33333333%}.col-xs-push-9{left:75%}.col-xs-push-8{left:66.66666667%}.col-xs-push-7{left:58.33333333%}.col-xs-push-6{left:50%}.col-xs-push-5{left:41.66666667%}.col-xs-push-4{left:33.33333333%}.col-xs-push-3{left:25%}.col-xs-push-2{left:16.66666667%}.col-xs-push-1{left:8.33333333%}.col-xs-push-0{left:auto}.col-xs-offset-12{margin-left:100%}.col-xs-offset-11{margin-left:91.66666667%}.col-xs-offset-10{margin-left:83.33333333%}.col-xs-offset-9{margin-left:75%}.col-xs-offset-8{margin-left:66.66666667%}.col-xs-offset-7{margin-left:58.33333333%}.col-xs-offset-6{margin-left:50%}.col-xs-offset-5{margin-left:41.66666667%}.col-xs-offset-4{margin-left:33.33333333%}.col-xs-offset-3{margin-left:25%}.col-xs-offset-2{margin-left:16.66666667%}.col-xs-offset-1{margin-left:8.33333333%}.col-xs-offset-0{margin-left:0}@media (min-width:768px){.col-sm-1,.col-sm-2,.col-sm-3,.col-sm-4,.col-sm-5,.col-sm-6,.col-sm-7,.col-sm-8,.col-sm-9,.col-sm-10,.col-sm-11,.col-sm-12{float:left}.col-sm-12{width:100%}.col-sm-11{width:91.66666667%}.col-sm-10{width:83.33333333%}.col-sm-9{width:75%}.col-sm-8{width:66.66666667%}.col-sm-7{width:58.33333333%}.col-sm-6{width:50%}.col-sm-5{width:41.66666667%}.col-sm-4{width:33.33333333%}.col-sm-3{width:25%}.col-sm-2{width:16.66666667%}.col-sm-1{width:8.33333333%}.col-sm-pull-12{right:100%}.col-sm-pull-11{right:91.66666667%}.col-sm-pull-10{right:83.33333333%}.col-sm-pull-9{right:75%}.col-sm-pull-8{right:66.66666667%}.col-sm-pull-7{right:58.33333333%}.col-sm-pull-6{right:50%}.col-sm-pull-5{right:41.66666667%}.col-sm-pull-4{right:33.33333333%}.col-sm-pull-3{right:25%}.col-sm-pull-2{right:16.66666667%}.col-sm-pull-1{right:8.33333333%}.col-sm-pull-0{right:auto}.col-sm-push-12{left:100%}.col-sm-push-11{left:91.66666667%}.col-sm-push-10{left:83.33333333%}.col-sm-push-9{left:75%}.col-sm-push-8{left:66.66666667%}.col-sm-push-7{left:58.33333333%}.col-sm-push-6{left:50%}.col-sm-push-5{left:41.66666667%}.col-sm-push-4{left:33.33333333%}.col-sm-push-3{left:25%}.col-sm-push-2{left:16.66666667%}.col-sm-push-1{left:8.33333333%}.col-sm-push-0{left:auto}.col-sm-offset-12{margin-left:100%}.col-sm-offset-11{margin-left:91.66666667%}.col-sm-offset-10{margin-left:83.33333333%}.col-sm-offset-9{margin-left:75%}.col-sm-offset-8{margin-left:66.66666667%}.col-sm-offset-7{margin-left:58.33333333%}.col-sm-offset-6{margin-left:50%}.col-sm-offset-5{margin-left:41.66666667%}.col-sm-offset-4{margin-left:33.33333333%}.col-sm-offset-3{margin-left:25%}.col-sm-offset-2{margin-left:16.66666667%}.col-sm-offset-1{margin-left:8.33333333%}.col-sm-offset-0{margin-left:0}}@media (min-width:992px){.col-md-1,.col-md-2,.col-md-3,.col-md-4,.col-md-5,.col-md-6,.col-md-7,.col-md-8,.col-md-9,.col-md-10,.col-md-11,.col-md-12{float:left}.col-md-12{width:100%}.col-md-11{width:91.66666667%}.col-md-10{width:83.33333333%}.col-md-9{width:75%}.col-md-8{width:66.66666667%}.col-md-7{width:58.33333333%}.col-md-6{width:50%}.col-md-5{width:41.66666667%}.col-md-4{width:33.33333333%}.col-md-3{width:25%}.col-md-2{width:16.66666667%}.col-md-1{width:8.33333333%}.col-md-pull-12{right:100%}.col-md-pull-11{right:91.66666667%}.col-md-pull-10{right:83.33333333%}.col-md-pull-9{right:75%}.col-md-pull-8{right:66.66666667%}.col-md-pull-7{right:58.33333333%}.col-md-pull-6{right:50%}.col-md-pull-5{right:41.66666667%}.col-md-pull-4{right:33.33333333%}.col-md-pull-3{right:25%}.col-md-pull-2{right:16.66666667%}.col-md-pull-1{right:8.33333333%}.col-md-pull-0{right:auto}.col-md-push-12{left:100%}.col-md-push-11{left:91.66666667%}.col-md-push-10{left:83.33333333%}.col-md-push-9{left:75%}.col-md-push-8{left:66.66666667%}.col-md-push-7{left:58.33333333%}.col-md-push-6{left:50%}.col-md-push-5{left:41.66666667%}.col-md-push-4{left:33.33333333%}.col-md-push-3{left:25%}.col-md-push-2{left:16.66666667%}.col-md-push-1{left:8.33333333%}.col-md-push-0{left:auto}.col-md-offset-12{margin-left:100%}.col-md-offset-11{margin-left:91.66666667%}.col-md-offset-10{margin-left:83.33333333%}.col-md-offset-9{margin-left:75%}.col-md-offset-8{margin-left:66.66666667%}.col-md-offset-7{margin-left:58.33333333%}.col-md-offset-6{margin-left:50%}.col-md-offset-5{margin-left:41.66666667%}.col-md-offset-4{margin-left:33.33333333%}.col-md-offset-3{margin-left:25%}.col-md-offset-2{margin-left:16.66666667%}.col-md-offset-1{margin-left:8.33333333%}.col-md-offset-0{margin-left:0}}@media (min-width:1200px){.col-lg-1,.col-lg-2,.col-lg-3,.col-lg-4,.col-lg-5,.col-lg-6,.col-lg-7,.col-lg-8,.col-lg-9,.col-lg-10,.col-lg-11,.col-lg-12{float:left}.col-lg-12{width:100%}.col-lg-11{width:91.66666667%}.col-lg-10{width:83.33333333%}.col-lg-9{width:75%}.col-lg-8{width:66.66666667%}.col-lg-7{width:58.33333333%}.col-lg-6{width:50%}.col-lg-5{width:41.66666667%}.col-lg-4{width:33.33333333%}.col-lg-3{width:25%}.col-lg-2{width:16.66666667%}.col-lg-1{width:8.33333333%}.col-lg-pull-12{right:100%}.col-lg-pull-11{right:91.66666667%}.col-lg-pull-10{right:83.33333333%}.col-lg-pull-9{right:75%}.col-lg-pull-8{right:66.66666667%}.col-lg-pull-7{right:58.33333333%}.col-lg-pull-6{right:50%}.col-lg-pull-5{right:41.66666667%}.col-lg-pull-4{right:33.33333333%}.col-lg-pull-3{right:25%}.col-lg-pull-2{right:16.66666667%}.col-lg-pull-1{right:8.33333333%}.col-lg-pull-0{right:auto}.col-lg-push-12{left:100%}.col-lg-push-11{left:91.66666667%}.col-lg-push-10{left:83.33333333%}.col-lg-push-9{left:75%}.col-lg-push-8{left:66.66666667%}.col-lg-push-7{left:58.33333333%}.col-lg-push-6{left:50%}.col-lg-push-5{left:41.66666667%}.col-lg-push-4{left:33.33333333%}.col-lg-push-3{left:25%}.col-lg-push-2{left:16.66666667%}.col-lg-push-1{left:8.33333333%}.col-lg-push-0{left:auto}.col-lg-offset-12{margin-left:100%}.col-lg-offset-11{margin-left:91.66666667%}.col-lg-offset-10{margin-left:83.33333333%}.col-lg-offset-9{margin-left:75%}.col-lg-offset-8{margin-left:66.66666667%}.col-lg-offset-7{margin-left:58.33333333%}.col-lg-offset-6{margin-left:50%}.col-lg-offset-5{margin-left:41.66666667%}.col-lg-offset-4{margin-left:33.33333333%}.col-lg-offset-3{margin-left:25%}.col-lg-offset-2{margin-left:16.66666667%}.col-lg-offset-1{margin-left:8.33333333%}.col-lg-offset-0{margin-left:0}}table{background-color:transparent}th{text-align:left}.table{width:100%;max-width:100%;margin-bottom:20px}.table>thead>tr>th,.table>tbody>tr>th,.table>tfoot>tr>th,.table>thead>tr>td,.table>tbody>tr>td,.table>tfoot>tr>td{padding:8px;line-height:1.42857143;vertical-align:top;border-top:1px solid #ddd}.table>thead>tr>th{vertical-align:bottom;border-bottom:2px solid #ddd}.table>caption+thead>tr:first-child>th,.table>colgroup+thead>tr:first-child>th,.table>thead:first-child>tr:first-child>th,.table>caption+thead>tr:first-child>td,.table>colgroup+thead>tr:first-child>td,.table>thead:first-child>tr:first-child>td{border-top:0}.table>tbody+tbody{border-top:2px solid #ddd}.table-condensed>thead>tr>th,.table-condensed>tbody>tr>th,.table-condensed>tfoot>tr>th,.table-condensed>thead>tr>td,.table-condensed>tbody>tr>td,.table-condensed>tfoot>tr>td{padding:5px}.table-bordered{border:1px solid #ddd}.table-bordered>thead>tr>th,.table-bordered>tbody>tr>th,.table-bordered>tfoot>tr>th,.table-bordered>thead>tr>td,.table-bordered>tbody>tr>td,.table-bordered>tfoot>tr>td{border:1px solid #ddd}.table-bordered>thead>tr>th,.table-bordered>thead>tr>td{border-bottom-width:2px}.table-striped>tbody>tr:nth-child(odd)>td,.table-striped>tbody>tr:nth-child(odd)>th{background-color:#f9f9f9}.table-hover>tbody>tr:hover>td,.table-hover>tbody>tr:hover>th{background-color:#f5f5f5}table col[class*=col-]{position:static;display:table-column;float:none}table td[class*=col-],table th[class*=col-]{position:static;display:table-cell;float:none}.table>thead>tr>td.active,.table>tbody>tr>td.active,.table>tfoot>tr>td.active,.table>thead>tr>th.active,.table>tbody>tr>th.active,.table>tfoot>tr>th.active,.table>thead>tr.active>td,.table>tbody>tr.active>td,.table>tfoot>tr.active>td,.table>thead>tr.active>th,.table>tbody>tr.active>th,.table>tfoot>tr.active>th{background-color:#f5f5f5}.table-hover>tbody>tr>td.active:hover,.table-hover>tbody>tr>th.active:hover,.table-hover>tbody>tr.active:hover>td,.table-hover>tbody>tr:hover>.active,.table-hover>tbody>tr.active:hover>th{background-color:#e8e8e8}.table>thead>tr>td.success,.table>tbody>tr>td.success,.table>tfoot>tr>td.success,.table>thead>tr>th.success,.table>tbody>tr>th.success,.table>tfoot>tr>th.success,.table>thead>tr.success>td,.table>tbody>tr.success>td,.table>tfoot>tr.success>td,.table>thead>tr.success>th,.table>tbody>tr.success>th,.table>tfoot>tr.success>th{background-color:#dff0d8}.table-hover>tbody>tr>td.success:hover,.table-hover>tbody>tr>th.success:hover,.table-hover>tbody>tr.success:hover>td,.table-hover>tbody>tr:hover>.success,.table-hover>tbody>tr.success:hover>th{background-color:#d0e9c6}.table>thead>tr>td.info,.table>tbody>tr>td.info,.table>tfoot>tr>td.info,.table>thead>tr>th.info,.table>tbody>tr>th.info,.table>tfoot>tr>th.info,.table>thead>tr.info>td,.table>tbody>tr.info>td,.table>tfoot>tr.info>td,.table>thead>tr.info>th,.table>tbody>tr.info>th,.table>tfoot>tr.info>th{background-color:#d9edf7}.table-hover>tbody>tr>td.info:hover,.table-hover>tbody>tr>th.info:hover,.table-hover>tbody>tr.info:hover>td,.table-hover>tbody>tr:hover>.info,.table-hover>tbody>tr.info:hover>th{background-color:#c4e3f3}.table>thead>tr>td.warning,.table>tbody>tr>td.warning,.table>tfoot>tr>td.warning,.table>thead>tr>th.warning,.table>tbody>tr>th.warning,.table>tfoot>tr>th.warning,.table>thead>tr.warning>td,.table>tbody>tr.warning>td,.table>tfoot>tr.warning>td,.table>thead>tr.warning>th,.table>tbody>tr.warning>th,.table>tfoot>tr.warning>th{background-color:#fcf8e3}.table-hover>tbody>tr>td.warning:hover,.table-hover>tbody>tr>th.warning:hover,.table-hover>tbody>tr.warning:hover>td,.table-hover>tbody>tr:hover>.warning,.table-hover>tbody>tr.warning:hover>th{background-color:#faf2cc}.table>thead>tr>td.danger,.table>tbody>tr>td.danger,.table>tfoot>tr>td.danger,.table>thead>tr>th.danger,.table>tbody>tr>th.danger,.table>tfoot>tr>th.danger,.table>thead>tr.danger>td,.table>tbody>tr.danger>td,.table>tfoot>tr.danger>td,.table>thead>tr.danger>th,.table>tbody>tr.danger>th,.table>tfoot>tr.danger>th{background-color:#f2dede}.table-hover>tbody>tr>td.danger:hover,.table-hover>tbody>tr>th.danger:hover,.table-hover>tbody>tr.danger:hover>td,.table-hover>tbody>tr:hover>.danger,.table-hover>tbody>tr.danger:hover>th{background-color:#ebcccc}@media screen and (max-width:767px){.table-responsive{width:100%;margin-bottom:15px;overflow-x:auto;overflow-y:hidden;-webkit-overflow-scrolling:touch;-ms-overflow-style:-ms-autohiding-scrollbar;border:1px solid #ddd}.table-responsive>.table{margin-bottom:0}.table-responsive>.table>thead>tr>th,.table-responsive>.table>tbody>tr>th,.table-responsive>.table>tfoot>tr>th,.table-responsive>.table>thead>tr>td,.table-responsive>.table>tbody>tr>td,.table-responsive>.table>tfoot>tr>td{white-space:nowrap}.table-responsive>.table-bordered{border:0}.table-responsive>.table-bordered>thead>tr>th:first-child,.table-responsive>.table-bordered>tbody>tr>th:first-child,.table-responsive>.table-bordered>tfoot>tr>th:first-child,.table-responsive>.table-bordered>thead>tr>td:first-child,.table-responsive>.table-bordered>tbody>tr>td:first-child,.table-responsive>.table-bordered>tfoot>tr>td:first-child{border-left:0}.table-responsive>.table-bordered>thead>tr>th:last-child,.table-responsive>.table-bordered>tbody>tr>th:last-child,.table-responsive>.table-bordered>tfoot>tr>th:last-child,.table-responsive>.table-bordered>thead>tr>td:last-child,.table-responsive>.table-bordered>tbody>tr>td:last-child,.table-responsive>.table-bordered>tfoot>tr>td:last-child{border-right:0}.table-responsive>.table-bordered>tbody>tr:last-child>th,.table-responsive>.table-bordered>tfoot>tr:last-child>th,.table-responsive>.table-bordered>tbody>tr:last-child>td,.table-responsive>.table-bordered>tfoot>tr:last-child>td{border-bottom:0}}fieldset{min-width:0;padding:0;margin:0;border:0}legend{display:block;width:100%;padding:0;margin-bottom:20px;font-size:21px;line-height:inherit;color:#333;border:0;border-bottom:1px solid #e5e5e5}label{display:inline-block;max-width:100%;margin-bottom:5px;font-weight:700}input[type=search]{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}input[type=radio],input[type=checkbox]{margin:4px 0 0;margin-top:1px \9;line-height:normal}input[type=file]{display:block}input[type=range]{display:block;width:100%}select[multiple],select[size]{height:auto}input[type=file]:focus,input[type=radio]:focus,input[type=checkbox]:focus{outline:thin dotted;outline:5px auto -webkit-focus-ring-color;outline-offset:-2px}output{display:block;padding-top:7px;font-size:14px;line-height:1.42857143;color:#555}.form-control{display:block;width:100%;height:34px;padding:6px 12px;font-size:14px;line-height:1.42857143;color:#555;background-color:#fff;background-image:none;border:1px solid #ccc;border-radius:4px;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075);box-shadow:inset 0 1px 1px rgba(0,0,0,.075);-webkit-transition:border-color ease-in-out .15s,-webkit-box-shadow ease-in-out .15s;-o-transition:border-color ease-in-out .15s,box-shadow ease-in-out .15s;transition:border-color ease-in-out .15s,box-shadow ease-in-out .15s}.form-control:focus{border-color:#66afe9;outline:0;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 8px rgba(102,175,233,.6);box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 8px rgba(102,175,233,.6)}.form-control::-moz-placeholder{color:#777;opacity:1}.form-control:-ms-input-placeholder{color:#777}.form-control::-webkit-input-placeholder{color:#777}.form-control[disabled],.form-control[readonly],fieldset[disabled] .form-control{cursor:not-allowed;background-color:#eee;opacity:1}textarea.form-control{height:auto}input[type=search]{-webkit-appearance:none}input[type=date],input[type=time],input[type=datetime-local],input[type=month]{line-height:34px;line-height:1.42857143 \0}input[type=date].input-sm,input[type=time].input-sm,input[type=datetime-local].input-sm,input[type=month].input-sm{line-height:30px}input[type=date].input-lg,input[type=time].input-lg,input[type=datetime-local].input-lg,input[type=month].input-lg{line-height:46px}.form-group{margin-bottom:15px}.radio,.checkbox{position:relative;display:block;min-height:20px;margin-top:10px;margin-bottom:10px}.radio label,.checkbox label{padding-left:20px;margin-bottom:0;font-weight:400;cursor:pointer}.radio input[type=radio],.radio-inline input[type=radio],.checkbox input[type=checkbox],.checkbox-inline input[type=checkbox]{position:absolute;margin-top:4px \9;margin-left:-20px}.radio+.radio,.checkbox+.checkbox{margin-top:-5px}.radio-inline,.checkbox-inline{display:inline-block;padding-left:20px;margin-bottom:0;font-weight:400;vertical-align:middle;cursor:pointer}.radio-inline+.radio-inline,.checkbox-inline+.checkbox-inline{margin-top:0;margin-left:10px}input[type=radio][disabled],input[type=checkbox][disabled],input[type=radio].disabled,input[type=checkbox].disabled,fieldset[disabled] input[type=radio],fieldset[disabled] input[type=checkbox]{cursor:not-allowed}.radio-inline.disabled,.checkbox-inline.disabled,fieldset[disabled] .radio-inline,fieldset[disabled] .checkbox-inline{cursor:not-allowed}.radio.disabled label,.checkbox.disabled label,fieldset[disabled] .radio label,fieldset[disabled] .checkbox label{cursor:not-allowed}.form-control-static{padding-top:7px;padding-bottom:7px;margin-bottom:0}.form-control-static.input-lg,.form-control-static.input-sm{padding-right:0;padding-left:0}.input-sm,.form-horizontal .form-group-sm .form-control{height:30px;padding:5px 10px;font-size:12px;line-height:1.5;border-radius:3px}select.input-sm{height:30px;line-height:30px}textarea.input-sm,select[multiple].input-sm{height:auto}.input-lg,.form-horizontal .form-group-lg .form-control{height:46px;padding:10px 16px;font-size:18px;line-height:1.33;border-radius:6px}select.input-lg{height:46px;line-height:46px}textarea.input-lg,select[multiple].input-lg{height:auto}.has-feedback{position:relative}.has-feedback .form-control{padding-right:42.5px}.form-control-feedback{position:absolute;top:25px;right:0;z-index:2;display:block;width:34px;height:34px;line-height:34px;text-align:center}.input-lg+.form-control-feedback{width:46px;height:46px;line-height:46px}.input-sm+.form-control-feedback{width:30px;height:30px;line-height:30px}.has-success .help-block,.has-success .control-label,.has-success .radio,.has-success .checkbox,.has-success .radio-inline,.has-success .checkbox-inline{color:#3c763d}.has-success .form-control{border-color:#3c763d;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075);box-shadow:inset 0 1px 1px rgba(0,0,0,.075)}.has-success .form-control:focus{border-color:#2b542c;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 6px #67b168;box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 6px #67b168}.has-success .input-group-addon{color:#3c763d;background-color:#dff0d8;border-color:#3c763d}.has-success .form-control-feedback{color:#3c763d}.has-warning .help-block,.has-warning .control-label,.has-warning .radio,.has-warning .checkbox,.has-warning .radio-inline,.has-warning .checkbox-inline{color:#8a6d3b}.has-warning .form-control{border-color:#8a6d3b;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075);box-shadow:inset 0 1px 1px rgba(0,0,0,.075)}.has-warning .form-control:focus{border-color:#66512c;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 6px #c0a16b;box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 6px #c0a16b}.has-warning .input-group-addon{color:#8a6d3b;background-color:#fcf8e3;border-color:#8a6d3b}.has-warning .form-control-feedback{color:#8a6d3b}.has-error .help-block,.has-error .control-label,.has-error .radio,.has-error .checkbox,.has-error .radio-inline,.has-error .checkbox-inline{color:#a94442}.has-error .form-control{border-color:#a94442;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075);box-shadow:inset 0 1px 1px rgba(0,0,0,.075)}.has-error .form-control:focus{border-color:#843534;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 6px #ce8483;box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 6px #ce8483}.has-error .input-group-addon{color:#a94442;background-color:#f2dede;border-color:#a94442}.has-error .form-control-feedback{color:#a94442}.has-feedback label.sr-only~.form-control-feedback{top:0}.help-block{display:block;margin-top:5px;margin-bottom:10px;color:#737373}@media (min-width:768px){.form-inline .form-group{display:inline-block;margin-bottom:0;vertical-align:middle}.form-inline .form-control{display:inline-block;width:auto;vertical-align:middle}.form-inline .input-group{display:inline-table;vertical-align:middle}.form-inline .input-group .input-group-addon,.form-inline .input-group .input-group-btn,.form-inline .input-group .form-control{width:auto}.form-inline .input-group>.form-control{width:100%}.form-inline .control-label{margin-bottom:0;vertical-align:middle}.form-inline .radio,.form-inline .checkbox{display:inline-block;margin-top:0;margin-bottom:0;vertical-align:middle}.form-inline .radio label,.form-inline .checkbox label{padding-left:0}.form-inline .radio input[type=radio],.form-inline .checkbox input[type=checkbox]{position:relative;margin-left:0}.form-inline .has-feedback .form-control-feedback{top:0}}.form-horizontal .radio,.form-horizontal .checkbox,.form-horizontal .radio-inline,.form-horizontal .checkbox-inline{padding-top:7px;margin-top:0;margin-bottom:0}.form-horizontal .radio,.form-horizontal .checkbox{min-height:27px}.form-horizontal .form-group{margin-right:-15px;margin-left:-15px}@media (min-width:768px){.form-horizontal .control-label{padding-top:7px;margin-bottom:0;text-align:right}}.form-horizontal .has-feedback .form-control-feedback{top:0;right:15px}@media (min-width:768px){.form-horizontal .form-group-lg .control-label{padding-top:14.3px}}@media (min-width:768px){.form-horizontal .form-group-sm .control-label{padding-top:6px}}.btn{display:inline-block;padding:6px 12px;margin-bottom:0;font-size:14px;font-weight:400;line-height:1.42857143;text-align:center;white-space:nowrap;vertical-align:middle;cursor:pointer;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;background-image:none;border:1px solid transparent;border-radius:4px}.btn:focus,.btn:active:focus,.btn.active:focus{outline:thin dotted;outline:5px auto -webkit-focus-ring-color;outline-offset:-2px}.btn:hover,.btn:focus{color:#333;text-decoration:none}.btn:active,.btn.active{background-image:none;outline:0;-webkit-box-shadow:inset 0 3px 5px rgba(0,0,0,.125);box-shadow:inset 0 3px 5px rgba(0,0,0,.125)}.btn.disabled,.btn[disabled],fieldset[disabled] .btn{pointer-events:none;cursor:not-allowed;filter:alpha(opacity=65);-webkit-box-shadow:none;box-shadow:none;opacity:.65}.btn-default{color:#333;background-color:#fff;border-color:#ccc}.btn-default:hover,.btn-default:focus,.btn-default:active,.btn-default.active,.open>.dropdown-toggle.btn-default{color:#333;background-color:#e6e6e6;border-color:#adadad}.btn-default:active,.btn-default.active,.open>.dropdown-toggle.btn-default{background-image:none}.btn-default.disabled,.btn-default[disabled],fieldset[disabled] .btn-default,.btn-default.disabled:hover,.btn-default[disabled]:hover,fieldset[disabled] .btn-default:hover,.btn-default.disabled:focus,.btn-default[disabled]:focus,fieldset[disabled] .btn-default:focus,.btn-default.disabled:active,.btn-default[disabled]:active,fieldset[disabled] .btn-default:active,.btn-default.disabled.active,.btn-default[disabled].active,fieldset[disabled] .btn-default.active{background-color:#fff;border-color:#ccc}.btn-default .badge{color:#fff;background-color:#333}.btn-primary{color:#fff;background-color:#428bca;border-color:#357ebd}.btn-primary:hover,.btn-primary:focus,.btn-primary:active,.btn-primary.active,.open>.dropdown-toggle.btn-primary{color:#fff;background-color:#3071a9;border-color:#285e8e}.btn-primary:active,.btn-primary.active,.open>.dropdown-toggle.btn-primary{background-image:none}.btn-primary.disabled,.btn-primary[disabled],fieldset[disabled] .btn-primary,.btn-primary.disabled:hover,.btn-primary[disabled]:hover,fieldset[disabled] .btn-primary:hover,.btn-primary.disabled:focus,.btn-primary[disabled]:focus,fieldset[disabled] .btn-primary:focus,.btn-primary.disabled:active,.btn-primary[disabled]:active,fieldset[disabled] .btn-primary:active,.btn-primary.disabled.active,.btn-primary[disabled].active,fieldset[disabled] .btn-primary.active{background-color:#428bca;border-color:#357ebd}.btn-primary .badge{color:#428bca;background-color:#fff}.btn-success{color:#fff;background-color:#5cb85c;border-color:#4cae4c}.btn-success:hover,.btn-success:focus,.btn-success:active,.btn-success.active,.open>.dropdown-toggle.btn-success{color:#fff;background-color:#449d44;border-color:#398439}.btn-success:active,.btn-success.active,.open>.dropdown-toggle.btn-success{background-image:none}.btn-success.disabled,.btn-success[disabled],fieldset[disabled] .btn-success,.btn-success.disabled:hover,.btn-success[disabled]:hover,fieldset[disabled] .btn-success:hover,.btn-success.disabled:focus,.btn-success[disabled]:focus,fieldset[disabled] .btn-success:focus,.btn-success.disabled:active,.btn-success[disabled]:active,fieldset[disabled] .btn-success:active,.btn-success.disabled.active,.btn-success[disabled].active,fieldset[disabled] .btn-success.active{background-color:#5cb85c;border-color:#4cae4c}.btn-success .badge{color:#5cb85c;background-color:#fff}.btn-info{color:#fff;background-color:#5bc0de;border-color:#46b8da}.btn-info:hover,.btn-info:focus,.btn-info:active,.btn-info.active,.open>.dropdown-toggle.btn-info{color:#fff;background-color:#31b0d5;border-color:#269abc}.btn-info:active,.btn-info.active,.open>.dropdown-toggle.btn-info{background-image:none}.btn-info.disabled,.btn-info[disabled],fieldset[disabled] .btn-info,.btn-info.disabled:hover,.btn-info[disabled]:hover,fieldset[disabled] .btn-info:hover,.btn-info.disabled:focus,.btn-info[disabled]:focus,fieldset[disabled] .btn-info:focus,.btn-info.disabled:active,.btn-info[disabled]:active,fieldset[disabled] .btn-info:active,.btn-info.disabled.active,.btn-info[disabled].active,fieldset[disabled] .btn-info.active{background-color:#5bc0de;border-color:#46b8da}.btn-info .badge{color:#5bc0de;background-color:#fff}.btn-warning{color:#fff;background-color:#f0ad4e;border-color:#eea236}.btn-warning:hover,.btn-warning:focus,.btn-warning:active,.btn-warning.active,.open>.dropdown-toggle.btn-warning{color:#fff;background-color:#ec971f;border-color:#d58512}.btn-warning:active,.btn-warning.active,.open>.dropdown-toggle.btn-warning{background-image:none}.btn-warning.disabled,.btn-warning[disabled],fieldset[disabled] .btn-warning,.btn-warning.disabled:hover,.btn-warning[disabled]:hover,fieldset[disabled] .btn-warning:hover,.btn-warning.disabled:focus,.btn-warning[disabled]:focus,fieldset[disabled] .btn-warning:focus,.btn-warning.disabled:active,.btn-warning[disabled]:active,fieldset[disabled] .btn-warning:active,.btn-warning.disabled.active,.btn-warning[disabled].active,fieldset[disabled] .btn-warning.active{background-color:#f0ad4e;border-color:#eea236}.btn-warning .badge{color:#f0ad4e;background-color:#fff}.btn-danger{color:#fff;background-color:#d9534f;border-color:#d43f3a}.btn-danger:hover,.btn-danger:focus,.btn-danger:active,.btn-danger.active,.open>.dropdown-toggle.btn-danger{color:#fff;background-color:#c9302c;border-color:#ac2925}.btn-danger:active,.btn-danger.active,.open>.dropdown-toggle.btn-danger{background-image:none}.btn-danger.disabled,.btn-danger[disabled],fieldset[disabled] .btn-danger,.btn-danger.disabled:hover,.btn-danger[disabled]:hover,fieldset[disabled] .btn-danger:hover,.btn-danger.disabled:focus,.btn-danger[disabled]:focus,fieldset[disabled] .btn-danger:focus,.btn-danger.disabled:active,.btn-danger[disabled]:active,fieldset[disabled] .btn-danger:active,.btn-danger.disabled.active,.btn-danger[disabled].active,fieldset[disabled] .btn-danger.active{background-color:#d9534f;border-color:#d43f3a}.btn-danger .badge{color:#d9534f;background-color:#fff}.btn-link{font-weight:400;color:#428bca;cursor:pointer;border-radius:0}.btn-link,.btn-link:active,.btn-link[disabled],fieldset[disabled] .btn-link{background-color:transparent;-webkit-box-shadow:none;box-shadow:none}.btn-link,.btn-link:hover,.btn-link:focus,.btn-link:active{border-color:transparent}.btn-link:hover,.btn-link:focus{color:#2a6496;text-decoration:underline;background-color:transparent}.btn-link[disabled]:hover,fieldset[disabled] .btn-link:hover,.btn-link[disabled]:focus,fieldset[disabled] .btn-link:focus{color:#777;text-decoration:none}.btn-lg,.btn-group-lg>.btn{padding:10px 16px;font-size:18px;line-height:1.33;border-radius:6px}.btn-sm,.btn-group-sm>.btn{padding:5px 10px;font-size:12px;line-height:1.5;border-radius:3px}.btn-xs,.btn-group-xs>.btn{padding:1px 5px;font-size:12px;line-height:1.5;border-radius:3px}.btn-block{display:block;width:100%}.btn-block+.btn-block{margin-top:5px}input[type=submit].btn-block,input[type=reset].btn-block,input[type=button].btn-block{width:100%}.fade{opacity:0;-webkit-transition:opacity .15s linear;-o-transition:opacity .15s linear;transition:opacity .15s linear}.fade.in{opacity:1}.collapse{display:none}.collapse.in{display:block}tr.collapse.in{display:table-row}tbody.collapse.in{display:table-row-group}.collapsing{position:relative;height:0;overflow:hidden;-webkit-transition:height .35s ease;-o-transition:height .35s ease;transition:height .35s ease}.caret{display:inline-block;width:0;height:0;margin-left:2px;vertical-align:middle;border-top:4px solid;border-right:4px solid transparent;border-left:4px solid transparent}.dropdown{position:relative}.dropdown-toggle:focus{outline:0}.dropdown-menu{position:absolute;top:100%;left:0;z-index:1000;display:none;float:left;min-width:160px;padding:5px 0;margin:2px 0 0;font-size:14px;text-align:left;list-style:none;background-color:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0,0,0,.15);border-radius:4px;-webkit-box-shadow:0 6px 12px rgba(0,0,0,.175);box-shadow:0 6px 12px rgba(0,0,0,.175)}.dropdown-menu.pull-right{right:0;left:auto}.dropdown-menu .divider{height:1px;margin:9px 0;overflow:hidden;background-color:#e5e5e5}.dropdown-menu>li>a{display:block;padding:3px 20px;clear:both;font-weight:400;line-height:1.42857143;color:#333;white-space:nowrap}.dropdown-menu>li>a:hover,.dropdown-menu>li>a:focus{color:#262626;text-decoration:none;background-color:#f5f5f5}.dropdown-menu>.active>a,.dropdown-menu>.active>a:hover,.dropdown-menu>.active>a:focus{color:#fff;text-decoration:none;background-color:#428bca;outline:0}.dropdown-menu>.disabled>a,.dropdown-menu>.disabled>a:hover,.dropdown-menu>.disabled>a:focus{color:#777}.dropdown-menu>.disabled>a:hover,.dropdown-menu>.disabled>a:focus{text-decoration:none;cursor:not-allowed;background-color:transparent;background-image:none;filter:progid:DXImageTransform.Microsoft.gradient(enabled=false)}.open>.dropdown-menu{display:block}.open>a{outline:0}.dropdown-menu-right{right:0;left:auto}.dropdown-menu-left{right:auto;left:0}.dropdown-header{display:block;padding:3px 20px;font-size:12px;line-height:1.42857143;color:#777;white-space:nowrap}.dropdown-backdrop{position:fixed;top:0;right:0;bottom:0;left:0;z-index:990}.pull-right>.dropdown-menu{right:0;left:auto}.dropup .caret,.navbar-fixed-bottom .dropdown .caret{content:"";border-top:0;border-bottom:4px solid}.dropup .dropdown-menu,.navbar-fixed-bottom .dropdown .dropdown-menu{top:auto;bottom:100%;margin-bottom:1px}@media (min-width:768px){.navbar-right .dropdown-menu{right:0;left:auto}.navbar-right .dropdown-menu-left{right:auto;left:0}}.btn-group,.btn-group-vertical{position:relative;display:inline-block;vertical-align:middle}.btn-group>.btn,.btn-group-vertical>.btn{position:relative;float:left}.btn-group>.btn:hover,.btn-group-vertical>.btn:hover,.btn-group>.btn:focus,.btn-group-vertical>.btn:focus,.btn-group>.btn:active,.btn-group-vertical>.btn:active,.btn-group>.btn.active,.btn-group-vertical>.btn.active{z-index:2}.btn-group>.btn:focus,.btn-group-vertical>.btn:focus{outline:0}.btn-group .btn+.btn,.btn-group .btn+.btn-group,.btn-group .btn-group+.btn,.btn-group .btn-group+.btn-group{margin-left:-1px}.btn-toolbar{margin-left:-5px}.btn-toolbar .btn-group,.btn-toolbar .input-group{float:left}.btn-toolbar>.btn,.btn-toolbar>.btn-group,.btn-toolbar>.input-group{margin-left:5px}.btn-group>.btn:not(:first-child):not(:last-child):not(.dropdown-toggle){border-radius:0}.btn-group>.btn:first-child{margin-left:0}.btn-group>.btn:first-child:not(:last-child):not(.dropdown-toggle){border-top-right-radius:0;border-bottom-right-radius:0}.btn-group>.btn:last-child:not(:first-child),.btn-group>.dropdown-toggle:not(:first-child){border-top-left-radius:0;border-bottom-left-radius:0}.btn-group>.btn-group{float:left}.btn-group>.btn-group:not(:first-child):not(:last-child)>.btn{border-radius:0}.btn-group>.btn-group:first-child>.btn:last-child,.btn-group>.btn-group:first-child>.dropdown-toggle{border-top-right-radius:0;border-bottom-right-radius:0}.btn-group>.btn-group:last-child>.btn:first-child{border-top-left-radius:0;border-bottom-left-radius:0}.btn-group .dropdown-toggle:active,.btn-group.open .dropdown-toggle{outline:0}.btn-group>.btn+.dropdown-toggle{padding-right:8px;padding-left:8px}.btn-group>.btn-lg+.dropdown-toggle{padding-right:12px;padding-left:12px}.btn-group.open .dropdown-toggle{-webkit-box-shadow:inset 0 3px 5px rgba(0,0,0,.125);box-shadow:inset 0 3px 5px rgba(0,0,0,.125)}.btn-group.open .dropdown-toggle.btn-link{-webkit-box-shadow:none;box-shadow:none}.btn .caret{margin-left:0}.btn-lg .caret{border-width:5px 5px 0;border-bottom-width:0}.dropup .btn-lg .caret{border-width:0 5px 5px}.btn-group-vertical>.btn,.btn-group-vertical>.btn-group,.btn-group-vertical>.btn-group>.btn{display:block;float:none;width:100%;max-width:100%}.btn-group-vertical>.btn-group>.btn{float:none}.btn-group-vertical>.btn+.btn,.btn-group-vertical>.btn+.btn-group,.btn-group-vertical>.btn-group+.btn,.btn-group-vertical>.btn-group+.btn-group{margin-top:-1px;margin-left:0}.btn-group-vertical>.btn:not(:first-child):not(:last-child){border-radius:0}.btn-group-vertical>.btn:first-child:not(:last-child){border-top-right-radius:4px;border-bottom-right-radius:0;border-bottom-left-radius:0}.btn-group-vertical>.btn:last-child:not(:first-child){border-top-left-radius:0;border-top-right-radius:0;border-bottom-left-radius:4px}.btn-group-vertical>.btn-group:not(:first-child):not(:last-child)>.btn{border-radius:0}.btn-group-vertical>.btn-group:first-child:not(:last-child)>.btn:last-child,.btn-group-vertical>.btn-group:first-child:not(:last-child)>.dropdown-toggle{border-bottom-right-radius:0;border-bottom-left-radius:0}.btn-group-vertical>.btn-group:last-child:not(:first-child)>.btn:first-child{border-top-left-radius:0;border-top-right-radius:0}.btn-group-justified{display:table;width:100%;table-layout:fixed;border-collapse:separate}.btn-group-justified>.btn,.btn-group-justified>.btn-group{display:table-cell;float:none;width:1%}.btn-group-justified>.btn-group .btn{width:100%}.btn-group-justified>.btn-group .dropdown-menu{left:auto}[data-toggle=buttons]>.btn>input[type=radio],[data-toggle=buttons]>.btn>input[type=checkbox]{position:absolute;z-index:-1;filter:alpha(opacity=0);opacity:0}.input-group{position:relative;display:table;border-collapse:separate}.input-group[class*=col-]{float:none;padding-right:0;padding-left:0}.input-group .form-control{position:relative;z-index:2;float:left;width:100%;margin-bottom:0}.input-group-lg>.form-control,.input-group-lg>.input-group-addon,.input-group-lg>.input-group-btn>.btn{height:46px;padding:10px 16px;font-size:18px;line-height:1.33;border-radius:6px}select.input-group-lg>.form-control,select.input-group-lg>.input-group-addon,select.input-group-lg>.input-group-btn>.btn{height:46px;line-height:46px}textarea.input-group-lg>.form-control,textarea.input-group-lg>.input-group-addon,textarea.input-group-lg>.input-group-btn>.btn,select[multiple].input-group-lg>.form-control,select[multiple].input-group-lg>.input-group-addon,select[multiple].input-group-lg>.input-group-btn>.btn{height:auto}.input-group-sm>.form-control,.input-group-sm>.input-group-addon,.input-group-sm>.input-group-btn>.btn{height:30px;padding:5px 10px;font-size:12px;line-height:1.5;border-radius:3px}select.input-group-sm>.form-control,select.input-group-sm>.input-group-addon,select.input-group-sm>.input-group-btn>.btn{height:30px;line-height:30px}textarea.input-group-sm>.form-control,textarea.input-group-sm>.input-group-addon,textarea.input-group-sm>.input-group-btn>.btn,select[multiple].input-group-sm>.form-control,select[multiple].input-group-sm>.input-group-addon,select[multiple].input-group-sm>.input-group-btn>.btn{height:auto}.input-group-addon,.input-group-btn,.input-group .form-control{display:table-cell}.input-group-addon:not(:first-child):not(:last-child),.input-group-btn:not(:first-child):not(:last-child),.input-group .form-control:not(:first-child):not(:last-child){border-radius:0}.input-group-addon,.input-group-btn{width:1%;white-space:nowrap;vertical-align:middle}.input-group-addon{padding:6px 12px;font-size:14px;font-weight:400;line-height:1;color:#555;text-align:center;background-color:#eee;border:1px solid #ccc;border-radius:4px}.input-group-addon.input-sm{padding:5px 10px;font-size:12px;border-radius:3px}.input-group-addon.input-lg{padding:10px 16px;font-size:18px;border-radius:6px}.input-group-addon input[type=radio],.input-group-addon input[type=checkbox]{margin-top:0}.input-group .form-control:first-child,.input-group-addon:first-child,.input-group-btn:first-child>.btn,.input-group-btn:first-child>.btn-group>.btn,.input-group-btn:first-child>.dropdown-toggle,.input-group-btn:last-child>.btn:not(:last-child):not(.dropdown-toggle),.input-group-btn:last-child>.btn-group:not(:last-child)>.btn{border-top-right-radius:0;border-bottom-right-radius:0}.input-group-addon:first-child{border-right:0}.input-group .form-control:last-child,.input-group-addon:last-child,.input-group-btn:last-child>.btn,.input-group-btn:last-child>.btn-group>.btn,.input-group-btn:last-child>.dropdown-toggle,.input-group-btn:first-child>.btn:not(:first-child),.input-group-btn:first-child>.btn-group:not(:first-child)>.btn{border-top-left-radius:0;border-bottom-left-radius:0}.input-group-addon:last-child{border-left:0}.input-group-btn{position:relative;font-size:0;white-space:nowrap}.input-group-btn>.btn{position:relative}.input-group-btn>.btn+.btn{margin-left:-1px}.input-group-btn>.btn:hover,.input-group-btn>.btn:focus,.input-group-btn>.btn:active{z-index:2}.input-group-btn:first-child>.btn,.input-group-btn:first-child>.btn-group{margin-right:-1px}.input-group-btn:last-child>.btn,.input-group-btn:last-child>.btn-group{margin-left:-1px}.nav{padding-left:0;margin-bottom:0;list-style:none}.nav>li{position:relative;display:block}.nav>li>a{position:relative;display:block;padding:10px 15px}.nav>li>a:hover,.nav>li>a:focus{text-decoration:none;background-color:#eee}.nav>li.disabled>a{color:#777}.nav>li.disabled>a:hover,.nav>li.disabled>a:focus{color:#777;text-decoration:none;cursor:not-allowed;background-color:transparent}.nav .open>a,.nav .open>a:hover,.nav .open>a:focus{background-color:#eee;border-color:#428bca}.nav .nav-divider{height:1px;margin:9px 0;overflow:hidden;background-color:#e5e5e5}.nav>li>a>img{max-width:none}.nav-tabs{border-bottom:1px solid #ddd}.nav-tabs>li{float:left;margin-bottom:-1px}.nav-tabs>li>a{margin-right:2px;line-height:1.42857143;border:1px solid transparent;border-radius:4px 4px 0 0}.nav-tabs>li>a:hover{border-color:#eee #eee #ddd}.nav-tabs>li.active>a,.nav-tabs>li.active>a:hover,.nav-tabs>li.active>a:focus{color:#555;cursor:default;background-color:#fff;border:1px solid #ddd;border-bottom-color:transparent}.nav-tabs.nav-justified{width:100%;border-bottom:0}.nav-tabs.nav-justified>li{float:none}.nav-tabs.nav-justified>li>a{margin-bottom:5px;text-align:center}.nav-tabs.nav-justified>.dropdown .dropdown-menu{top:auto;left:auto}@media (min-width:768px){.nav-tabs.nav-justified>li{display:table-cell;width:1%}.nav-tabs.nav-justified>li>a{margin-bottom:0}}.nav-tabs.nav-justified>li>a{margin-right:0;border-radius:4px}.nav-tabs.nav-justified>.active>a,.nav-tabs.nav-justified>.active>a:hover,.nav-tabs.nav-justified>.active>a:focus{border:1px solid #ddd}@media (min-width:768px){.nav-tabs.nav-justified>li>a{border-bottom:1px solid #ddd;border-radius:4px 4px 0 0}.nav-tabs.nav-justified>.active>a,.nav-tabs.nav-justified>.active>a:hover,.nav-tabs.nav-justified>.active>a:focus{border-bottom-color:#fff}}.nav-pills>li{float:left}.nav-pills>li>a{border-radius:4px}.nav-pills>li+li{margin-left:2px}.nav-pills>li.active>a,.nav-pills>li.active>a:hover,.nav-pills>li.active>a:focus{color:#fff;background-color:#428bca}.nav-stacked>li{float:none}.nav-stacked>li+li{margin-top:2px;margin-left:0}.nav-justified{width:100%}.nav-justified>li{float:none}.nav-justified>li>a{margin-bottom:5px;text-align:center}.nav-justified>.dropdown .dropdown-menu{top:auto;left:auto}@media (min-width:768px){.nav-justified>li{display:table-cell;width:1%}.nav-justified>li>a{margin-bottom:0}}.nav-tabs-justified{border-bottom:0}.nav-tabs-justified>li>a{margin-right:0;border-radius:4px}.nav-tabs-justified>.active>a,.nav-tabs-justified>.active>a:hover,.nav-tabs-justified>.active>a:focus{border:1px solid #ddd}@media (min-width:768px){.nav-tabs-justified>li>a{border-bottom:1px solid #ddd;border-radius:4px 4px 0 0}.nav-tabs-justified>.active>a,.nav-tabs-justified>.active>a:hover,.nav-tabs-justified>.active>a:focus{border-bottom-color:#fff}}.tab-content>.tab-pane{display:none}.tab-content>.active{display:block}.nav-tabs .dropdown-menu{margin-top:-1px;border-top-left-radius:0;border-top-right-radius:0}.navbar{position:relative;min-height:50px;margin-bottom:20px;border:1px solid transparent}@media (min-width:768px){.navbar{border-radius:4px}}@media (min-width:768px){.navbar-header{float:left}}.navbar-collapse{padding-right:15px;padding-left:15px;overflow-x:visible;-webkit-overflow-scrolling:touch;border-top:1px solid transparent;-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,.1);box-shadow:inset 0 1px 0 rgba(255,255,255,.1)}.navbar-collapse.in{overflow-y:auto}@media (min-width:768px){.navbar-collapse{width:auto;border-top:0;-webkit-box-shadow:none;box-shadow:none}.navbar-collapse.collapse{display:block!important;height:auto!important;padding-bottom:0;overflow:visible!important}.navbar-collapse.in{overflow-y:visible}.navbar-fixed-top .navbar-collapse,.navbar-static-top .navbar-collapse,.navbar-fixed-bottom .navbar-collapse{padding-right:0;padding-left:0}}.navbar-fixed-top .navbar-collapse,.navbar-fixed-bottom .navbar-collapse{max-height:340px}@media (max-width:480px) and (orientation:landscape){.navbar-fixed-top .navbar-collapse,.navbar-fixed-bottom .navbar-collapse{max-height:200px}}.container>.navbar-header,.container-fluid>.navbar-header,.container>.navbar-collapse,.container-fluid>.navbar-collapse{margin-right:-15px;margin-left:-15px}@media (min-width:768px){.container>.navbar-header,.container-fluid>.navbar-header,.container>.navbar-collapse,.container-fluid>.navbar-collapse{margin-right:0;margin-left:0}}.navbar-static-top{z-index:1000;border-width:0 0 1px}@media (min-width:768px){.navbar-static-top{border-radius:0}}.navbar-fixed-top,.navbar-fixed-bottom{position:fixed;right:0;left:0;z-index:1030;-webkit-transform:translate3d(0,0,0);-o-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}@media (min-width:768px){.navbar-fixed-top,.navbar-fixed-bottom{border-radius:0}}.navbar-fixed-top{top:0;border-width:0 0 1px}.navbar-fixed-bottom{bottom:0;margin-bottom:0;border-width:1px 0 0}.navbar-brand{float:left;height:50px;padding:15px 15px;font-size:18px;line-height:20px}.navbar-brand:hover,.navbar-brand:focus{text-decoration:none}@media (min-width:768px){.navbar>.container .navbar-brand,.navbar>.container-fluid .navbar-brand{margin-left:-15px}}.navbar-toggle{position:relative;float:right;padding:9px 10px;margin-top:8px;margin-right:15px;margin-bottom:8px;background-color:transparent;background-image:none;border:1px solid transparent;border-radius:4px}.navbar-toggle:focus{outline:0}.navbar-toggle .icon-bar{display:block;width:22px;height:2px;border-radius:1px}.navbar-toggle .icon-bar+.icon-bar{margin-top:4px}@media (min-width:768px){.navbar-toggle{display:none}}.navbar-nav{margin:7.5px -15px}.navbar-nav>li>a{padding-top:10px;padding-bottom:10px;line-height:20px}@media (max-width:767px){.navbar-nav .open .dropdown-menu{position:static;float:none;width:auto;margin-top:0;background-color:transparent;border:0;-webkit-box-shadow:none;box-shadow:none}.navbar-nav .open .dropdown-menu>li>a,.navbar-nav .open .dropdown-menu .dropdown-header{padding:5px 15px 5px 25px}.navbar-nav .open .dropdown-menu>li>a{line-height:20px}.navbar-nav .open .dropdown-menu>li>a:hover,.navbar-nav .open .dropdown-menu>li>a:focus{background-image:none}}@media (min-width:768px){.navbar-nav{float:left;margin:0}.navbar-nav>li{float:left}.navbar-nav>li>a{padding-top:15px;padding-bottom:15px}.navbar-nav.navbar-right:last-child{margin-right:-15px}}@media (min-width:768px){.navbar-left{float:left!important}.navbar-right{float:right!important}}.navbar-form{padding:10px 15px;margin-top:8px;margin-right:-15px;margin-bottom:8px;margin-left:-15px;border-top:1px solid transparent;border-bottom:1px solid transparent;-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,.1),0 1px 0 rgba(255,255,255,.1);box-shadow:inset 0 1px 0 rgba(255,255,255,.1),0 1px 0 rgba(255,255,255,.1)}@media (min-width:768px){.navbar-form .form-group{display:inline-block;margin-bottom:0;vertical-align:middle}.navbar-form .form-control{display:inline-block;width:auto;vertical-align:middle}.navbar-form .input-group{display:inline-table;vertical-align:middle}.navbar-form .input-group .input-group-addon,.navbar-form .input-group .input-group-btn,.navbar-form .input-group .form-control{width:auto}.navbar-form .input-group>.form-control{width:100%}.navbar-form .control-label{margin-bottom:0;vertical-align:middle}.navbar-form .radio,.navbar-form .checkbox{display:inline-block;margin-top:0;margin-bottom:0;vertical-align:middle}.navbar-form .radio label,.navbar-form .checkbox label{padding-left:0}.navbar-form .radio input[type=radio],.navbar-form .checkbox input[type=checkbox]{position:relative;margin-left:0}.navbar-form .has-feedback .form-control-feedback{top:0}}@media (max-width:767px){.navbar-form .form-group{margin-bottom:5px}}@media (min-width:768px){.navbar-form{width:auto;padding-top:0;padding-bottom:0;margin-right:0;margin-left:0;border:0;-webkit-box-shadow:none;box-shadow:none}.navbar-form.navbar-right:last-child{margin-right:-15px}}.navbar-nav>li>.dropdown-menu{margin-top:0;border-top-left-radius:0;border-top-right-radius:0}.navbar-fixed-bottom .navbar-nav>li>.dropdown-menu{border-bottom-right-radius:0;border-bottom-left-radius:0}.navbar-btn{margin-top:8px;margin-bottom:8px}.navbar-btn.btn-sm{margin-top:10px;margin-bottom:10px}.navbar-btn.btn-xs{margin-top:14px;margin-bottom:14px}.navbar-text{margin-top:15px;margin-bottom:15px}@media (min-width:768px){.navbar-text{float:left;margin-right:15px;margin-left:15px}.navbar-text.navbar-right:last-child{margin-right:0}}.navbar-default{background-color:#f8f8f8;border-color:#e7e7e7}.navbar-default .navbar-brand{color:#777}.navbar-default .navbar-brand:hover,.navbar-default .navbar-brand:focus{color:#5e5e5e;background-color:transparent}.navbar-default .navbar-text{color:#777}.navbar-default .navbar-nav>li>a{color:#777}.navbar-default .navbar-nav>li>a:hover,.navbar-default .navbar-nav>li>a:focus{color:#333;background-color:transparent}.navbar-default .navbar-nav>.active>a,.navbar-default .navbar-nav>.active>a:hover,.navbar-default .navbar-nav>.active>a:focus{color:#555;background-color:#e7e7e7}.navbar-default .navbar-nav>.disabled>a,.navbar-default .navbar-nav>.disabled>a:hover,.navbar-default .navbar-nav>.disabled>a:focus{color:#ccc;background-color:transparent}.navbar-default .navbar-toggle{border-color:#ddd}.navbar-default .navbar-toggle:hover,.navbar-default .navbar-toggle:focus{background-color:#ddd}.navbar-default .navbar-toggle .icon-bar{background-color:#888}.navbar-default .navbar-collapse,.navbar-default .navbar-form{border-color:#e7e7e7}.navbar-default .navbar-nav>.open>a,.navbar-default .navbar-nav>.open>a:hover,.navbar-default .navbar-nav>.open>a:focus{color:#555;background-color:#e7e7e7}@media (max-width:767px){.navbar-default .navbar-nav .open .dropdown-menu>li>a{color:#777}.navbar-default .navbar-nav .open .dropdown-menu>li>a:hover,.navbar-default .navbar-nav .open .dropdown-menu>li>a:focus{color:#333;background-color:transparent}.navbar-default .navbar-nav .open .dropdown-menu>.active>a,.navbar-default .navbar-nav .open .dropdown-menu>.active>a:hover,.navbar-default .navbar-nav .open .dropdown-menu>.active>a:focus{color:#555;background-color:#e7e7e7}.navbar-default .navbar-nav .open .dropdown-menu>.disabled>a,.navbar-default .navbar-nav .open .dropdown-menu>.disabled>a:hover,.navbar-default .navbar-nav .open .dropdown-menu>.disabled>a:focus{color:#ccc;background-color:transparent}}.navbar-default .navbar-link{color:#777}.navbar-default .navbar-link:hover{color:#333}.navbar-default .btn-link{color:#777}.navbar-default .btn-link:hover,.navbar-default .btn-link:focus{color:#333}.navbar-default .btn-link[disabled]:hover,fieldset[disabled] .navbar-default .btn-link:hover,.navbar-default .btn-link[disabled]:focus,fieldset[disabled] .navbar-default .btn-link:focus{color:#ccc}.navbar-inverse{background-color:#222;border-color:#080808}.navbar-inverse .navbar-brand{color:#777}.navbar-inverse .navbar-brand:hover,.navbar-inverse .navbar-brand:focus{color:#fff;background-color:transparent}.navbar-inverse .navbar-text{color:#777}.navbar-inverse .navbar-nav>li>a{color:#777}.navbar-inverse .navbar-nav>li>a:hover,.navbar-inverse .navbar-nav>li>a:focus{color:#fff;background-color:transparent}.navbar-inverse .navbar-nav>.active>a,.navbar-inverse .navbar-nav>.active>a:hover,.navbar-inverse .navbar-nav>.active>a:focus{color:#fff;background-color:#080808}.navbar-inverse .navbar-nav>.disabled>a,.navbar-inverse .navbar-nav>.disabled>a:hover,.navbar-inverse .navbar-nav>.disabled>a:focus{color:#444;background-color:transparent}.navbar-inverse .navbar-toggle{border-color:#333}.navbar-inverse .navbar-toggle:hover,.navbar-inverse .navbar-toggle:focus{background-color:#333}.navbar-inverse .navbar-toggle .icon-bar{background-color:#fff}.navbar-inverse .navbar-collapse,.navbar-inverse .navbar-form{border-color:#101010}.navbar-inverse .navbar-nav>.open>a,.navbar-inverse .navbar-nav>.open>a:hover,.navbar-inverse .navbar-nav>.open>a:focus{color:#fff;background-color:#080808}@media (max-width:767px){.navbar-inverse .navbar-nav .open .dropdown-menu>.dropdown-header{border-color:#080808}.navbar-inverse .navbar-nav .open .dropdown-menu .divider{background-color:#080808}.navbar-inverse .navbar-nav .open .dropdown-menu>li>a{color:#777}.navbar-inverse .navbar-nav .open .dropdown-menu>li>a:hover,.navbar-inverse .navbar-nav .open .dropdown-menu>li>a:focus{color:#fff;background-color:transparent}.navbar-inverse .navbar-nav .open .dropdown-menu>.active>a,.navbar-inverse .navbar-nav .open .dropdown-menu>.active>a:hover,.navbar-inverse .navbar-nav .open .dropdown-menu>.active>a:focus{color:#fff;background-color:#080808}.navbar-inverse .navbar-nav .open .dropdown-menu>.disabled>a,.navbar-inverse .navbar-nav .open .dropdown-menu>.disabled>a:hover,.navbar-inverse .navbar-nav .open .dropdown-menu>.disabled>a:focus{color:#444;background-color:transparent}}.navbar-inverse .navbar-link{color:#777}.navbar-inverse .navbar-link:hover{color:#fff}.navbar-inverse .btn-link{color:#777}.navbar-inverse .btn-link:hover,.navbar-inverse .btn-link:focus{color:#fff}.navbar-inverse .btn-link[disabled]:hover,fieldset[disabled] .navbar-inverse .btn-link:hover,.navbar-inverse .btn-link[disabled]:focus,fieldset[disabled] .navbar-inverse .btn-link:focus{color:#444}.breadcrumb{padding:8px 15px;margin-bottom:20px;list-style:none;background-color:#f5f5f5;border-radius:4px}.breadcrumb>li{display:inline-block}.breadcrumb>li+li:before{padding:0 5px;color:#ccc;content:"/\00a0"}.breadcrumb>.active{color:#777}.pagination{display:inline-block;padding-left:0;margin:20px 0;border-radius:4px}.pagination>li{display:inline}.pagination>li>a,.pagination>li>span{position:relative;float:left;padding:6px 12px;margin-left:-1px;line-height:1.42857143;color:#428bca;text-decoration:none;background-color:#fff;border:1px solid #ddd}.pagination>li:first-child>a,.pagination>li:first-child>span{margin-left:0;border-top-left-radius:4px;border-bottom-left-radius:4px}.pagination>li:last-child>a,.pagination>li:last-child>span{border-top-right-radius:4px;border-bottom-right-radius:4px}.pagination>li>a:hover,.pagination>li>span:hover,.pagination>li>a:focus,.pagination>li>span:focus{color:#2a6496;background-color:#eee;border-color:#ddd}.pagination>.active>a,.pagination>.active>span,.pagination>.active>a:hover,.pagination>.active>span:hover,.pagination>.active>a:focus,.pagination>.active>span:focus{z-index:2;color:#fff;cursor:default;background-color:#428bca;border-color:#428bca}.pagination>.disabled>span,.pagination>.disabled>span:hover,.pagination>.disabled>span:focus,.pagination>.disabled>a,.pagination>.disabled>a:hover,.pagination>.disabled>a:focus{color:#777;cursor:not-allowed;background-color:#fff;border-color:#ddd}.pagination-lg>li>a,.pagination-lg>li>span{padding:10px 16px;font-size:18px}.pagination-lg>li:first-child>a,.pagination-lg>li:first-child>span{border-top-left-radius:6px;border-bottom-left-radius:6px}.pagination-lg>li:last-child>a,.pagination-lg>li:last-child>span{border-top-right-radius:6px;border-bottom-right-radius:6px}.pagination-sm>li>a,.pagination-sm>li>span{padding:5px 10px;font-size:12px}.pagination-sm>li:first-child>a,.pagination-sm>li:first-child>span{border-top-left-radius:3px;border-bottom-left-radius:3px}.pagination-sm>li:last-child>a,.pagination-sm>li:last-child>span{border-top-right-radius:3px;border-bottom-right-radius:3px}.pager{padding-left:0;margin:20px 0;text-align:center;list-style:none}.pager li{display:inline}.pager li>a,.pager li>span{display:inline-block;padding:5px 14px;background-color:#fff;border:1px solid #ddd;border-radius:15px}.pager li>a:hover,.pager li>a:focus{text-decoration:none;background-color:#eee}.pager .next>a,.pager .next>span{float:right}.pager .previous>a,.pager .previous>span{float:left}.pager .disabled>a,.pager .disabled>a:hover,.pager .disabled>a:focus,.pager .disabled>span{color:#777;cursor:not-allowed;background-color:#fff}.label{display:inline;padding:.2em .6em .3em;font-size:75%;font-weight:700;line-height:1;color:#fff;text-align:center;white-space:nowrap;vertical-align:baseline;border-radius:.25em}a.label:hover,a.label:focus{color:#fff;text-decoration:none;cursor:pointer}.label:empty{display:none}.btn .label{position:relative;top:-1px}.label-default{background-color:#777}.label-default[href]:hover,.label-default[href]:focus{background-color:#5e5e5e}.label-primary{background-color:#428bca}.label-primary[href]:hover,.label-primary[href]:focus{background-color:#3071a9}.label-success{background-color:#5cb85c}.label-success[href]:hover,.label-success[href]:focus{background-color:#449d44}.label-info{background-color:#5bc0de}.label-info[href]:hover,.label-info[href]:focus{background-color:#31b0d5}.label-warning{background-color:#f0ad4e}.label-warning[href]:hover,.label-warning[href]:focus{background-color:#ec971f}.label-danger{background-color:#d9534f}.label-danger[href]:hover,.label-danger[href]:focus{background-color:#c9302c}.badge{display:inline-block;min-width:10px;padding:3px 7px;font-size:12px;font-weight:700;line-height:1;color:#fff;text-align:center;white-space:nowrap;vertical-align:baseline;background-color:#777;border-radius:10px}.badge:empty{display:none}.btn .badge{position:relative;top:-1px}.btn-xs .badge{top:0;padding:1px 5px}a.badge:hover,a.badge:focus{color:#fff;text-decoration:none;cursor:pointer}a.list-group-item.active>.badge,.nav-pills>.active>a>.badge{color:#428bca;background-color:#fff}.nav-pills>li>a>.badge{margin-left:3px}.jumbotron{padding:30px;margin-bottom:30px;color:inherit;background-color:#eee}.jumbotron h1,.jumbotron .h1{color:inherit}.jumbotron p{margin-bottom:15px;font-size:21px;font-weight:200}.jumbotron>hr{border-top-color:#d5d5d5}.container .jumbotron{border-radius:6px}.jumbotron .container{max-width:100%}@media screen and (min-width:768px){.jumbotron{padding-top:48px;padding-bottom:48px}.container .jumbotron{padding-right:60px;padding-left:60px}.jumbotron h1,.jumbotron .h1{font-size:63px}}.thumbnail{display:block;padding:4px;margin-bottom:20px;line-height:1.42857143;background-color:#fff;border:1px solid #ddd;border-radius:4px;-webkit-transition:all .2s ease-in-out;-o-transition:all .2s ease-in-out;transition:all .2s ease-in-out}.thumbnail>img,.thumbnail a>img{margin-right:auto;margin-left:auto}a.thumbnail:hover,a.thumbnail:focus,a.thumbnail.active{border-color:#428bca}.thumbnail .caption{padding:9px;color:#333}.alert{padding:15px;margin-bottom:20px;border:1px solid transparent;border-radius:4px}.alert h4{margin-top:0;color:inherit}.alert .alert-link{font-weight:700}.alert>p,.alert>ul{margin-bottom:0}.alert>p+p{margin-top:5px}.alert-dismissable,.alert-dismissible{padding-right:35px}.alert-dismissable .close,.alert-dismissible .close{position:relative;top:-2px;right:-21px;color:inherit}.alert-success{color:#3c763d;background-color:#dff0d8;border-color:#d6e9c6}.alert-success hr{border-top-color:#c9e2b3}.alert-success .alert-link{color:#2b542c}.alert-info{color:#31708f;background-color:#d9edf7;border-color:#bce8f1}.alert-info hr{border-top-color:#a6e1ec}.alert-info .alert-link{color:#245269}.alert-warning{color:#8a6d3b;background-color:#fcf8e3;border-color:#faebcc}.alert-warning hr{border-top-color:#f7e1b5}.alert-warning .alert-link{color:#66512c}.alert-danger{color:#a94442;background-color:#f2dede;border-color:#ebccd1}.alert-danger hr{border-top-color:#e4b9c0}.alert-danger .alert-link{color:#843534}@-webkit-keyframes progress-bar-stripes{from{background-position:40px 0}to{background-position:0 0}}@-o-keyframes progress-bar-stripes{from{background-position:40px 0}to{background-position:0 0}}@keyframes progress-bar-stripes{from{background-position:40px 0}to{background-position:0 0}}.progress{height:20px;margin-bottom:20px;overflow:hidden;background-color:#f5f5f5;border-radius:4px;-webkit-box-shadow:inset 0 1px 2px rgba(0,0,0,.1);box-shadow:inset 0 1px 2px rgba(0,0,0,.1)}.progress-bar{float:left;width:0;height:100%;font-size:12px;line-height:20px;color:#fff;text-align:center;background-color:#428bca;-webkit-box-shadow:inset 0 -1px 0 rgba(0,0,0,.15);box-shadow:inset 0 -1px 0 rgba(0,0,0,.15);-webkit-transition:width .6s ease;-o-transition:width .6s ease;transition:width .6s ease}.progress-striped .progress-bar,.progress-bar-striped{background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:-o-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);-webkit-background-size:40px 40px;background-size:40px 40px}.progress.active .progress-bar,.progress-bar.active{-webkit-animation:progress-bar-stripes 2s linear infinite;-o-animation:progress-bar-stripes 2s linear infinite;animation:progress-bar-stripes 2s linear infinite}.progress-bar[aria-valuenow="1"],.progress-bar[aria-valuenow="2"]{min-width:30px}.progress-bar[aria-valuenow="0"]{min-width:30px;color:#777;background-color:transparent;background-image:none;-webkit-box-shadow:none;box-shadow:none}.progress-bar-success{background-color:#5cb85c}.progress-striped .progress-bar-success{background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:-o-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent)}.progress-bar-info{background-color:#5bc0de}.progress-striped .progress-bar-info{background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:-o-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent)}.progress-bar-warning{background-color:#f0ad4e}.progress-striped .progress-bar-warning{background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:-o-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent)}.progress-bar-danger{background-color:#d9534f}.progress-striped .progress-bar-danger{background-image:-webkit-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:-o-linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-image:linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent)}.media,.media-body{overflow:hidden;zoom:1}.media,.media .media{margin-top:15px}.media:first-child{margin-top:0}.media-object{display:block}.media-heading{margin:0 0 5px}.media>.pull-left{margin-right:10px}.media>.pull-right{margin-left:10px}.media-list{padding-left:0;list-style:none}.list-group{padding-left:0;margin-bottom:20px}.list-group-item{position:relative;display:block;padding:10px 15px;margin-bottom:-1px;background-color:#fff;border:1px solid #ddd}.list-group-item:first-child{border-top-left-radius:4px;border-top-right-radius:4px}.list-group-item:last-child{margin-bottom:0;border-bottom-right-radius:4px;border-bottom-left-radius:4px}.list-group-item>.badge{float:right}.list-group-item>.badge+.badge{margin-right:5px}a.list-group-item{color:#555}a.list-group-item .list-group-item-heading{color:#333}a.list-group-item:hover,a.list-group-item:focus{color:#555;text-decoration:none;background-color:#f5f5f5}.list-group-item.disabled,.list-group-item.disabled:hover,.list-group-item.disabled:focus{color:#777;background-color:#eee}.list-group-item.disabled .list-group-item-heading,.list-group-item.disabled:hover .list-group-item-heading,.list-group-item.disabled:focus .list-group-item-heading{color:inherit}.list-group-item.disabled .list-group-item-text,.list-group-item.disabled:hover .list-group-item-text,.list-group-item.disabled:focus .list-group-item-text{color:#777}.list-group-item.active,.list-group-item.active:hover,.list-group-item.active:focus{z-index:2;color:#fff;background-color:#428bca;border-color:#428bca}.list-group-item.active .list-group-item-heading,.list-group-item.active:hover .list-group-item-heading,.list-group-item.active:focus .list-group-item-heading,.list-group-item.active .list-group-item-heading>small,.list-group-item.active:hover .list-group-item-heading>small,.list-group-item.active:focus .list-group-item-heading>small,.list-group-item.active .list-group-item-heading>.small,.list-group-item.active:hover .list-group-item-heading>.small,.list-group-item.active:focus .list-group-item-heading>.small{color:inherit}.list-group-item.active .list-group-item-text,.list-group-item.active:hover .list-group-item-text,.list-group-item.active:focus .list-group-item-text{color:#e1edf7}.list-group-item-success{color:#3c763d;background-color:#dff0d8}a.list-group-item-success{color:#3c763d}a.list-group-item-success .list-group-item-heading{color:inherit}a.list-group-item-success:hover,a.list-group-item-success:focus{color:#3c763d;background-color:#d0e9c6}a.list-group-item-success.active,a.list-group-item-success.active:hover,a.list-group-item-success.active:focus{color:#fff;background-color:#3c763d;border-color:#3c763d}.list-group-item-info{color:#31708f;background-color:#d9edf7}a.list-group-item-info{color:#31708f}a.list-group-item-info .list-group-item-heading{color:inherit}a.list-group-item-info:hover,a.list-group-item-info:focus{color:#31708f;background-color:#c4e3f3}a.list-group-item-info.active,a.list-group-item-info.active:hover,a.list-group-item-info.active:focus{color:#fff;background-color:#31708f;border-color:#31708f}.list-group-item-warning{color:#8a6d3b;background-color:#fcf8e3}a.list-group-item-warning{color:#8a6d3b}a.list-group-item-warning .list-group-item-heading{color:inherit}a.list-group-item-warning:hover,a.list-group-item-warning:focus{color:#8a6d3b;background-color:#faf2cc}a.list-group-item-warning.active,a.list-group-item-warning.active:hover,a.list-group-item-warning.active:focus{color:#fff;background-color:#8a6d3b;border-color:#8a6d3b}.list-group-item-danger{color:#a94442;background-color:#f2dede}a.list-group-item-danger{color:#a94442}a.list-group-item-danger .list-group-item-heading{color:inherit}a.list-group-item-danger:hover,a.list-group-item-danger:focus{color:#a94442;background-color:#ebcccc}a.list-group-item-danger.active,a.list-group-item-danger.active:hover,a.list-group-item-danger.active:focus{color:#fff;background-color:#a94442;border-color:#a94442}.list-group-item-heading{margin-top:0;margin-bottom:5px}.list-group-item-text{margin-bottom:0;line-height:1.3}.panel{margin-bottom:20px;background-color:#fff;border:1px solid transparent;border-radius:4px;-webkit-box-shadow:0 1px 1px rgba(0,0,0,.05);box-shadow:0 1px 1px rgba(0,0,0,.05)}.panel-body{padding:15px}.panel-heading{padding:10px 15px;border-bottom:1px solid transparent;border-top-left-radius:3px;border-top-right-radius:3px}.panel-heading>.dropdown .dropdown-toggle{color:inherit}.panel-title{margin-top:0;margin-bottom:0;font-size:16px;color:inherit}.panel-title>a{color:inherit}.panel-footer{padding:10px 15px;background-color:#f5f5f5;border-top:1px solid #ddd;border-bottom-right-radius:3px;border-bottom-left-radius:3px}.panel>.list-group{margin-bottom:0}.panel>.list-group .list-group-item{border-width:1px 0;border-radius:0}.panel>.list-group:first-child .list-group-item:first-child{border-top:0;border-top-left-radius:3px;border-top-right-radius:3px}.panel>.list-group:last-child .list-group-item:last-child{border-bottom:0;border-bottom-right-radius:3px;border-bottom-left-radius:3px}.panel-heading+.list-group .list-group-item:first-child{border-top-width:0}.list-group+.panel-footer{border-top-width:0}.panel>.table,.panel>.table-responsive>.table,.panel>.panel-collapse>.table{margin-bottom:0}.panel>.table:first-child,.panel>.table-responsive:first-child>.table:first-child{border-top-left-radius:3px;border-top-right-radius:3px}.panel>.table:first-child>thead:first-child>tr:first-child td:first-child,.panel>.table-responsive:first-child>.table:first-child>thead:first-child>tr:first-child td:first-child,.panel>.table:first-child>tbody:first-child>tr:first-child td:first-child,.panel>.table-responsive:first-child>.table:first-child>tbody:first-child>tr:first-child td:first-child,.panel>.table:first-child>thead:first-child>tr:first-child th:first-child,.panel>.table-responsive:first-child>.table:first-child>thead:first-child>tr:first-child th:first-child,.panel>.table:first-child>tbody:first-child>tr:first-child th:first-child,.panel>.table-responsive:first-child>.table:first-child>tbody:first-child>tr:first-child th:first-child{border-top-left-radius:3px}.panel>.table:first-child>thead:first-child>tr:first-child td:last-child,.panel>.table-responsive:first-child>.table:first-child>thead:first-child>tr:first-child td:last-child,.panel>.table:first-child>tbody:first-child>tr:first-child td:last-child,.panel>.table-responsive:first-child>.table:first-child>tbody:first-child>tr:first-child td:last-child,.panel>.table:first-child>thead:first-child>tr:first-child th:last-child,.panel>.table-responsive:first-child>.table:first-child>thead:first-child>tr:first-child th:last-child,.panel>.table:first-child>tbody:first-child>tr:first-child th:last-child,.panel>.table-responsive:first-child>.table:first-child>tbody:first-child>tr:first-child th:last-child{border-top-right-radius:3px}.panel>.table:last-child,.panel>.table-responsive:last-child>.table:last-child{border-bottom-right-radius:3px;border-bottom-left-radius:3px}.panel>.table:last-child>tbody:last-child>tr:last-child td:first-child,.panel>.table-responsive:last-child>.table:last-child>tbody:last-child>tr:last-child td:first-child,.panel>.table:last-child>tfoot:last-child>tr:last-child td:first-child,.panel>.table-responsive:last-child>.table:last-child>tfoot:last-child>tr:last-child td:first-child,.panel>.table:last-child>tbody:last-child>tr:last-child th:first-child,.panel>.table-responsive:last-child>.table:last-child>tbody:last-child>tr:last-child th:first-child,.panel>.table:last-child>tfoot:last-child>tr:last-child th:first-child,.panel>.table-responsive:last-child>.table:last-child>tfoot:last-child>tr:last-child th:first-child{border-bottom-left-radius:3px}.panel>.table:last-child>tbody:last-child>tr:last-child td:last-child,.panel>.table-responsive:last-child>.table:last-child>tbody:last-child>tr:last-child td:last-child,.panel>.table:last-child>tfoot:last-child>tr:last-child td:last-child,.panel>.table-responsive:last-child>.table:last-child>tfoot:last-child>tr:last-child td:last-child,.panel>.table:last-child>tbody:last-child>tr:last-child th:last-child,.panel>.table-responsive:last-child>.table:last-child>tbody:last-child>tr:last-child th:last-child,.panel>.table:last-child>tfoot:last-child>tr:last-child th:last-child,.panel>.table-responsive:last-child>.table:last-child>tfoot:last-child>tr:last-child th:last-child{border-bottom-right-radius:3px}.panel>.panel-body+.table,.panel>.panel-body+.table-responsive{border-top:1px solid #ddd}.panel>.table>tbody:first-child>tr:first-child th,.panel>.table>tbody:first-child>tr:first-child td{border-top:0}.panel>.table-bordered,.panel>.table-responsive>.table-bordered{border:0}.panel>.table-bordered>thead>tr>th:first-child,.panel>.table-responsive>.table-bordered>thead>tr>th:first-child,.panel>.table-bordered>tbody>tr>th:first-child,.panel>.table-responsive>.table-bordered>tbody>tr>th:first-child,.panel>.table-bordered>tfoot>tr>th:first-child,.panel>.table-responsive>.table-bordered>tfoot>tr>th:first-child,.panel>.table-bordered>thead>tr>td:first-child,.panel>.table-responsive>.table-bordered>thead>tr>td:first-child,.panel>.table-bordered>tbody>tr>td:first-child,.panel>.table-responsive>.table-bordered>tbody>tr>td:first-child,.panel>.table-bordered>tfoot>tr>td:first-child,.panel>.table-responsive>.table-bordered>tfoot>tr>td:first-child{border-left:0}.panel>.table-bordered>thead>tr>th:last-child,.panel>.table-responsive>.table-bordered>thead>tr>th:last-child,.panel>.table-bordered>tbody>tr>th:last-child,.panel>.table-responsive>.table-bordered>tbody>tr>th:last-child,.panel>.table-bordered>tfoot>tr>th:last-child,.panel>.table-responsive>.table-bordered>tfoot>tr>th:last-child,.panel>.table-bordered>thead>tr>td:last-child,.panel>.table-responsive>.table-bordered>thead>tr>td:last-child,.panel>.table-bordered>tbody>tr>td:last-child,.panel>.table-responsive>.table-bordered>tbody>tr>td:last-child,.panel>.table-bordered>tfoot>tr>td:last-child,.panel>.table-responsive>.table-bordered>tfoot>tr>td:last-child{border-right:0}.panel>.table-bordered>thead>tr:first-child>td,.panel>.table-responsive>.table-bordered>thead>tr:first-child>td,.panel>.table-bordered>tbody>tr:first-child>td,.panel>.table-responsive>.table-bordered>tbody>tr:first-child>td,.panel>.table-bordered>thead>tr:first-child>th,.panel>.table-responsive>.table-bordered>thead>tr:first-child>th,.panel>.table-bordered>tbody>tr:first-child>th,.panel>.table-responsive>.table-bordered>tbody>tr:first-child>th{border-bottom:0}.panel>.table-bordered>tbody>tr:last-child>td,.panel>.table-responsive>.table-bordered>tbody>tr:last-child>td,.panel>.table-bordered>tfoot>tr:last-child>td,.panel>.table-responsive>.table-bordered>tfoot>tr:last-child>td,.panel>.table-bordered>tbody>tr:last-child>th,.panel>.table-responsive>.table-bordered>tbody>tr:last-child>th,.panel>.table-bordered>tfoot>tr:last-child>th,.panel>.table-responsive>.table-bordered>tfoot>tr:last-child>th{border-bottom:0}.panel>.table-responsive{margin-bottom:0;border:0}.panel-group{margin-bottom:20px}.panel-group .panel{margin-bottom:0;border-radius:4px}.panel-group .panel+.panel{margin-top:5px}.panel-group .panel-heading{border-bottom:0}.panel-group .panel-heading+.panel-collapse>.panel-body{border-top:1px solid #ddd}.panel-group .panel-footer{border-top:0}.panel-group .panel-footer+.panel-collapse .panel-body{border-bottom:1px solid #ddd}.panel-default{border-color:#ddd}.panel-default>.panel-heading{color:#333;background-color:#f5f5f5;border-color:#ddd}.panel-default>.panel-heading+.panel-collapse>.panel-body{border-top-color:#ddd}.panel-default>.panel-heading .badge{color:#f5f5f5;background-color:#333}.panel-default>.panel-footer+.panel-collapse>.panel-body{border-bottom-color:#ddd}.panel-primary{border-color:#428bca}.panel-primary>.panel-heading{color:#fff;background-color:#428bca;border-color:#428bca}.panel-primary>.panel-heading+.panel-collapse>.panel-body{border-top-color:#428bca}.panel-primary>.panel-heading .badge{color:#428bca;background-color:#fff}.panel-primary>.panel-footer+.panel-collapse>.panel-body{border-bottom-color:#428bca}.panel-success{border-color:#d6e9c6}.panel-success>.panel-heading{color:#3c763d;background-color:#dff0d8;border-color:#d6e9c6}.panel-success>.panel-heading+.panel-collapse>.panel-body{border-top-color:#d6e9c6}.panel-success>.panel-heading .badge{color:#dff0d8;background-color:#3c763d}.panel-success>.panel-footer+.panel-collapse>.panel-body{border-bottom-color:#d6e9c6}.panel-info{border-color:#bce8f1}.panel-info>.panel-heading{color:#31708f;background-color:#d9edf7;border-color:#bce8f1}.panel-info>.panel-heading+.panel-collapse>.panel-body{border-top-color:#bce8f1}.panel-info>.panel-heading .badge{color:#d9edf7;background-color:#31708f}.panel-info>.panel-footer+.panel-collapse>.panel-body{border-bottom-color:#bce8f1}.panel-warning{border-color:#faebcc}.panel-warning>.panel-heading{color:#8a6d3b;background-color:#fcf8e3;border-color:#faebcc}.panel-warning>.panel-heading+.panel-collapse>.panel-body{border-top-color:#faebcc}.panel-warning>.panel-heading .badge{color:#fcf8e3;background-color:#8a6d3b}.panel-warning>.panel-footer+.panel-collapse>.panel-body{border-bottom-color:#faebcc}.panel-danger{border-color:#ebccd1}.panel-danger>.panel-heading{color:#a94442;background-color:#f2dede;border-color:#ebccd1}.panel-danger>.panel-heading+.panel-collapse>.panel-body{border-top-color:#ebccd1}.panel-danger>.panel-heading .badge{color:#f2dede;background-color:#a94442}.panel-danger>.panel-footer+.panel-collapse>.panel-body{border-bottom-color:#ebccd1}.embed-responsive{position:relative;display:block;height:0;padding:0;overflow:hidden}.embed-responsive .embed-responsive-item,.embed-responsive iframe,.embed-responsive embed,.embed-responsive object{position:absolute;top:0;bottom:0;left:0;width:100%;height:100%;border:0}.embed-responsive.embed-responsive-16by9{padding-bottom:56.25%}.embed-responsive.embed-responsive-4by3{padding-bottom:75%}.well{min-height:20px;padding:19px;margin-bottom:20px;background-color:#f5f5f5;border:1px solid #e3e3e3;border-radius:4px;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.05);box-shadow:inset 0 1px 1px rgba(0,0,0,.05)}.well blockquote{border-color:#ddd;border-color:rgba(0,0,0,.15)}.well-lg{padding:24px;border-radius:6px}.well-sm{padding:9px;border-radius:3px}.close{float:right;font-size:21px;font-weight:700;line-height:1;color:#000;text-shadow:0 1px 0 #fff;filter:alpha(opacity=20);opacity:.2}.close:hover,.close:focus{color:#000;text-decoration:none;cursor:pointer;filter:alpha(opacity=50);opacity:.5}button.close{-webkit-appearance:none;padding:0;cursor:pointer;background:0 0;border:0}.modal-open{overflow:hidden}.modal{position:fixed;top:0;right:0;bottom:0;left:0;z-index:1050;display:none;overflow:hidden;-webkit-overflow-scrolling:touch;outline:0}.modal.fade .modal-dialog{-webkit-transition:-webkit-transform .3s ease-out;-o-transition:-o-transform .3s ease-out;transition:transform .3s ease-out;-webkit-transform:translate3d(0,-25%,0);-o-transform:translate3d(0,-25%,0);transform:translate3d(0,-25%,0)}.modal.in .modal-dialog{-webkit-transform:translate3d(0,0,0);-o-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}.modal-open .modal{overflow-x:hidden;overflow-y:auto}.modal-dialog{position:relative;width:auto;margin:10px}.modal-content{position:relative;background-color:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #999;border:1px solid rgba(0,0,0,.2);border-radius:6px;outline:0;-webkit-box-shadow:0 3px 9px rgba(0,0,0,.5);box-shadow:0 3px 9px rgba(0,0,0,.5)}.modal-backdrop{position:fixed;top:0;right:0;bottom:0;left:0;z-index:1040;background-color:#000}.modal-backdrop.fade{filter:alpha(opacity=0);opacity:0}.modal-backdrop.in{filter:alpha(opacity=50);opacity:.5}.modal-header{min-height:16.43px;padding:15px;border-bottom:1px solid #e5e5e5}.modal-header .close{margin-top:-2px}.modal-title{margin:0;line-height:1.42857143}.modal-body{position:relative;padding:15px}.modal-footer{padding:15px;text-align:right;border-top:1px solid #e5e5e5}.modal-footer .btn+.btn{margin-bottom:0;margin-left:5px}.modal-footer .btn-group .btn+.btn{margin-left:-1px}.modal-footer .btn-block+.btn-block{margin-left:0}.modal-scrollbar-measure{position:absolute;top:-9999px;width:50px;height:50px;overflow:scroll}@media (min-width:768px){.modal-dialog{width:600px;margin:30px auto}.modal-content{-webkit-box-shadow:0 5px 15px rgba(0,0,0,.5);box-shadow:0 5px 15px rgba(0,0,0,.5)}.modal-sm{width:300px}}@media (min-width:992px){.modal-lg{width:900px}}.tooltip{position:absolute;z-index:1070;display:block;font-size:12px;line-height:1.4;visibility:visible;filter:alpha(opacity=0);opacity:0}.tooltip.in{filter:alpha(opacity=90);opacity:.9}.tooltip.top{padding:5px 0;margin-top:-3px}.tooltip.right{padding:0 5px;margin-left:3px}.tooltip.bottom{padding:5px 0;margin-top:3px}.tooltip.left{padding:0 5px;margin-left:-3px}.tooltip-inner{max-width:200px;padding:3px 8px;color:#fff;text-align:center;text-decoration:none;background-color:#000;border-radius:4px}.tooltip-arrow{position:absolute;width:0;height:0;border-color:transparent;border-style:solid}.tooltip.top .tooltip-arrow{bottom:0;left:50%;margin-left:-5px;border-width:5px 5px 0;border-top-color:#000}.tooltip.top-left .tooltip-arrow{bottom:0;left:5px;border-width:5px 5px 0;border-top-color:#000}.tooltip.top-right .tooltip-arrow{right:5px;bottom:0;border-width:5px 5px 0;border-top-color:#000}.tooltip.right .tooltip-arrow{top:50%;left:0;margin-top:-5px;border-width:5px 5px 5px 0;border-right-color:#000}.tooltip.left .tooltip-arrow{top:50%;right:0;margin-top:-5px;border-width:5px 0 5px 5px;border-left-color:#000}.tooltip.bottom .tooltip-arrow{top:0;left:50%;margin-left:-5px;border-width:0 5px 5px;border-bottom-color:#000}.tooltip.bottom-left .tooltip-arrow{top:0;left:5px;border-width:0 5px 5px;border-bottom-color:#000}.tooltip.bottom-right .tooltip-arrow{top:0;right:5px;border-width:0 5px 5px;border-bottom-color:#000}.popover{position:absolute;top:0;left:0;z-index:1060;display:none;max-width:276px;padding:1px;text-align:left;white-space:normal;background-color:#fff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0,0,0,.2);border-radius:6px;-webkit-box-shadow:0 5px 10px rgba(0,0,0,.2);box-shadow:0 5px 10px rgba(0,0,0,.2)}.popover.top{margin-top:-10px}.popover.right{margin-left:10px}.popover.bottom{margin-top:10px}.popover.left{margin-left:-10px}.popover-title{padding:8px 14px;margin:0;font-size:14px;font-weight:400;line-height:18px;background-color:#f7f7f7;border-bottom:1px solid #ebebeb;border-radius:5px 5px 0 0}.popover-content{padding:9px 14px}.popover>.arrow,.popover>.arrow:after{position:absolute;display:block;width:0;height:0;border-color:transparent;border-style:solid}.popover>.arrow{border-width:11px}.popover>.arrow:after{content:"";border-width:10px}.popover.top>.arrow{bottom:-11px;left:50%;margin-left:-11px;border-top-color:#999;border-top-color:rgba(0,0,0,.25);border-bottom-width:0}.popover.top>.arrow:after{bottom:1px;margin-left:-10px;content:" ";border-top-color:#fff;border-bottom-width:0}.popover.right>.arrow{top:50%;left:-11px;margin-top:-11px;border-right-color:#999;border-right-color:rgba(0,0,0,.25);border-left-width:0}.popover.right>.arrow:after{bottom:-10px;left:1px;content:" ";border-right-color:#fff;border-left-width:0}.popover.bottom>.arrow{top:-11px;left:50%;margin-left:-11px;border-top-width:0;border-bottom-color:#999;border-bottom-color:rgba(0,0,0,.25)}.popover.bottom>.arrow:after{top:1px;margin-left:-10px;content:" ";border-top-width:0;border-bottom-color:#fff}.popover.left>.arrow{top:50%;right:-11px;margin-top:-11px;border-right-width:0;border-left-color:#999;border-left-color:rgba(0,0,0,.25)}.popover.left>.arrow:after{right:1px;bottom:-10px;content:" ";border-right-width:0;border-left-color:#fff}.carousel{position:relative}.carousel-inner{position:relative;width:100%;overflow:hidden}.carousel-inner>.item{position:relative;display:none;-webkit-transition:.6s ease-in-out left;-o-transition:.6s ease-in-out left;transition:.6s ease-in-out left}.carousel-inner>.item>img,.carousel-inner>.item>a>img{line-height:1}.carousel-inner>.active,.carousel-inner>.next,.carousel-inner>.prev{display:block}.carousel-inner>.active{left:0}.carousel-inner>.next,.carousel-inner>.prev{position:absolute;top:0;width:100%}.carousel-inner>.next{left:100%}.carousel-inner>.prev{left:-100%}.carousel-inner>.next.left,.carousel-inner>.prev.right{left:0}.carousel-inner>.active.left{left:-100%}.carousel-inner>.active.right{left:100%}.carousel-control{position:absolute;top:0;bottom:0;left:0;width:15%;font-size:20px;color:#fff;text-align:center;text-shadow:0 1px 2px rgba(0,0,0,.6);filter:alpha(opacity=50);opacity:.5}.carousel-control.left{background-image:-webkit-linear-gradient(left,rgba(0,0,0,.5) 0,rgba(0,0,0,.0001) 100%);background-image:-o-linear-gradient(left,rgba(0,0,0,.5) 0,rgba(0,0,0,.0001) 100%);background-image:-webkit-gradient(linear,left top,right top,from(rgba(0,0,0,.5)),to(rgba(0,0,0,.0001)));background-image:linear-gradient(to right,rgba(0,0,0,.5) 0,rgba(0,0,0,.0001) 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#80000000', endColorstr='#00000000', GradientType=1);background-repeat:repeat-x}.carousel-control.right{right:0;left:auto;background-image:-webkit-linear-gradient(left,rgba(0,0,0,.0001) 0,rgba(0,0,0,.5) 100%);background-image:-o-linear-gradient(left,rgba(0,0,0,.0001) 0,rgba(0,0,0,.5) 100%);background-image:-webkit-gradient(linear,left top,right top,from(rgba(0,0,0,.0001)),to(rgba(0,0,0,.5)));background-image:linear-gradient(to right,rgba(0,0,0,.0001) 0,rgba(0,0,0,.5) 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#00000000', endColorstr='#80000000', GradientType=1);background-repeat:repeat-x}.carousel-control:hover,.carousel-control:focus{color:#fff;text-decoration:none;filter:alpha(opacity=90);outline:0;opacity:.9}.carousel-control .icon-prev,.carousel-control .icon-next,.carousel-control .glyphicon-chevron-left,.carousel-control .glyphicon-chevron-right{position:absolute;top:50%;z-index:5;display:inline-block}.carousel-control .icon-prev,.carousel-control .glyphicon-chevron-left{left:50%;margin-left:-10px}.carousel-control .icon-next,.carousel-control .glyphicon-chevron-right{right:50%;margin-right:-10px}.carousel-control .icon-prev,.carousel-control .icon-next{width:20px;height:20px;margin-top:-10px;font-family:serif}.carousel-control .icon-prev:before{content:'\2039'}.carousel-control .icon-next:before{content:'\203a'}.carousel-indicators{position:absolute;bottom:10px;left:50%;z-index:15;width:60%;padding-left:0;margin-left:-30%;text-align:center;list-style:none}.carousel-indicators li{display:inline-block;width:10px;height:10px;margin:1px;text-indent:-999px;cursor:pointer;background-color:#000 \9;background-color:rgba(0,0,0,0);border:1px solid #fff;border-radius:10px}.carousel-indicators .active{width:12px;height:12px;margin:0;background-color:#fff}.carousel-caption{position:absolute;right:15%;bottom:20px;left:15%;z-index:10;padding-top:20px;padding-bottom:20px;color:#fff;text-align:center;text-shadow:0 1px 2px rgba(0,0,0,.6)}.carousel-caption .btn{text-shadow:none}@media screen and (min-width:768px){.carousel-control .glyphicon-chevron-left,.carousel-control .glyphicon-chevron-right,.carousel-control .icon-prev,.carousel-control .icon-next{width:30px;height:30px;margin-top:-15px;font-size:30px}.carousel-control .glyphicon-chevron-left,.carousel-control .icon-prev{margin-left:-15px}.carousel-control .glyphicon-chevron-right,.carousel-control .icon-next{margin-right:-15px}.carousel-caption{right:20%;left:20%;padding-bottom:30px}.carousel-indicators{bottom:20px}}.clearfix:before,.clearfix:after,.dl-horizontal dd:before,.dl-horizontal dd:after,.container:before,.container:after,.container-fluid:before,.container-fluid:after,.row:before,.row:after,.form-horizontal .form-group:before,.form-horizontal .form-group:after,.btn-toolbar:before,.btn-toolbar:after,.btn-group-vertical>.btn-group:before,.btn-group-vertical>.btn-group:after,.nav:before,.nav:after,.navbar:before,.navbar:after,.navbar-header:before,.navbar-header:after,.navbar-collapse:before,.navbar-collapse:after,.pager:before,.pager:after,.panel-body:before,.panel-body:after,.modal-footer:before,.modal-footer:after{display:table;content:" "}.clearfix:after,.dl-horizontal dd:after,.container:after,.container-fluid:after,.row:after,.form-horizontal .form-group:after,.btn-toolbar:after,.btn-group-vertical>.btn-group:after,.nav:after,.navbar:after,.navbar-header:after,.navbar-collapse:after,.pager:after,.panel-body:after,.modal-footer:after{clear:both}.center-block{display:block;margin-right:auto;margin-left:auto}.pull-right{float:right!important}.pull-left{float:left!important}.hide{display:none!important}.show{display:block!important}.invisible{visibility:hidden}.text-hide{font:0/0 a;color:transparent;text-shadow:none;background-color:transparent;border:0}.hidden{display:none!important;visibility:hidden!important}.affix{position:fixed;-webkit-transform:translate3d(0,0,0);-o-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}@-ms-viewport{width:device-width}.visible-xs,.visible-sm,.visible-md,.visible-lg{display:none!important}.visible-xs-block,.visible-xs-inline,.visible-xs-inline-block,.visible-sm-block,.visible-sm-inline,.visible-sm-inline-block,.visible-md-block,.visible-md-inline,.visible-md-inline-block,.visible-lg-block,.visible-lg-inline,.visible-lg-inline-block{display:none!important}@media (max-width:767px){.visible-xs{display:block!important}table.visible-xs{display:table}tr.visible-xs{display:table-row!important}th.visible-xs,td.visible-xs{display:table-cell!important}}@media (max-width:767px){.visible-xs-block{display:block!important}}@media (max-width:767px){.visible-xs-inline{display:inline!important}}@media (max-width:767px){.visible-xs-inline-block{display:inline-block!important}}@media (min-width:768px) and (max-width:991px){.visible-sm{display:block!important}table.visible-sm{display:table}tr.visible-sm{display:table-row!important}th.visible-sm,td.visible-sm{display:table-cell!important}}@media (min-width:768px) and (max-width:991px){.visible-sm-block{display:block!important}}@media (min-width:768px) and (max-width:991px){.visible-sm-inline{display:inline!important}}@media (min-width:768px) and (max-width:991px){.visible-sm-inline-block{display:inline-block!important}}@media (min-width:992px) and (max-width:1199px){.visible-md{display:block!important}table.visible-md{display:table}tr.visible-md{display:table-row!important}th.visible-md,td.visible-md{display:table-cell!important}}@media (min-width:992px) and (max-width:1199px){.visible-md-block{display:block!important}}@media (min-width:992px) and (max-width:1199px){.visible-md-inline{display:inline!important}}@media (min-width:992px) and (max-width:1199px){.visible-md-inline-block{display:inline-block!important}}@media (min-width:1200px){.visible-lg{display:block!important}table.visible-lg{display:table}tr.visible-lg{display:table-row!important}th.visible-lg,td.visible-lg{display:table-cell!important}}@media (min-width:1200px){.visible-lg-block{display:block!important}}@media (min-width:1200px){.visible-lg-inline{display:inline!important}}@media (min-width:1200px){.visible-lg-inline-block{display:inline-block!important}}@media (max-width:767px){.hidden-xs{display:none!important}}@media (min-width:768px) and (max-width:991px){.hidden-sm{display:none!important}}@media (min-width:992px) and (max-width:1199px){.hidden-md{display:none!important}}@media (min-width:1200px){.hidden-lg{display:none!important}}.visible-print{display:none!important}@media print{.visible-print{display:block!important}table.visible-print{display:table}tr.visible-print{display:table-row!important}th.visible-print,td.visible-print{display:table-cell!important}}.visible-print-block{display:none!important}@media print{.visible-print-block{display:block!important}}.visible-print-inline{display:none!important}@media print{.visible-print-inline{display:inline!important}}.visible-print-inline-block{display:none!important}@media print{.visible-print-inline-block{display:inline-block!important}}@media print{.hidden-print{display:none!important}} diff --git a/doc/demuxers.texi b/doc/demuxers.texi index 3c15ab9eee..6c94863271 100644 --- a/doc/demuxers.texi +++ b/doc/demuxers.texi @@ -327,6 +327,13 @@ segment index to start live streams at (negative values are from the end). @item allowed_extensions ',' separated list of file extensions that hls is allowed to access. +@item extension_picky +This blocks disallowed extensions from probing +It also requires all available segments to have matching extensions to the format +except mpegts, which is always allowed. +It is recommended to set the whitelists correctly instead of depending on extensions +Enabled by default. + @item max_reload Maximum number of times a insufficient list is attempted to be reloaded. Default value is 1000. diff --git a/doc/developer.texi b/doc/developer.texi index b33cab0fc7..666be8223a 100644 --- a/doc/developer.texi +++ b/doc/developer.texi @@ -762,6 +762,25 @@ In case you need finer control over how valgrind is invoked, use the @code{--target-exec='valgrind } option in your configure line instead. +@anchor{Maintenance} +@chapter Maintenance process + +@anchor{MAINTAINERS} +@section MAINTAINERS + +The developers maintaining each part of the codebase are listed in @file{MAINTAINERS}. +Being listed in @file{MAINTAINERS}, gives one the right to have git write access to +the specific repository. + +@anchor{Becoming a maintainer} +@section Becoming a maintainer + +People add themselves to @file{MAINTAINERS} by sending a patch like any other code +change. These get reviewed by the community like any other patch. It is expected +that, if someone has an objection to a new maintainer, she is willing to object +in public with her full name and is willing to take over maintainership for the area. + + @anchor{Release process} @chapter Release process diff --git a/doc/examples/demuxing_decoding.c b/doc/examples/demuxing_decoding.c index db5e0cb951..b95f7682ac 100644 --- a/doc/examples/demuxing_decoding.c +++ b/doc/examples/demuxing_decoding.c @@ -137,11 +137,9 @@ static int decode_packet(AVCodecContext *dec, const AVPacket *pkt) ret = output_audio_frame(frame); av_frame_unref(frame); - if (ret < 0) - return ret; } - return 0; + return ret; } static int open_codec_context(int *stream_idx, diff --git a/doc/examples/muxing.c b/doc/examples/muxing.c index 42f704c258..c98f749163 100644 --- a/doc/examples/muxing.c +++ b/doc/examples/muxing.c @@ -350,8 +350,7 @@ static int write_audio_frame(AVFormatContext *oc, OutputStream *ost) if (frame) { /* convert samples from native format to destination codec format, using the resampler */ /* compute destination number of samples */ - dst_nb_samples = av_rescale_rnd(swr_get_delay(ost->swr_ctx, c->sample_rate) + frame->nb_samples, - c->sample_rate, c->sample_rate, AV_ROUND_UP); + dst_nb_samples = swr_get_delay(ost->swr_ctx, c->sample_rate) + frame->nb_samples; av_assert0(dst_nb_samples == frame->nb_samples); /* when we pass a frame to the encoder, it may keep a reference to it diff --git a/doc/examples/vaapi_encode.c b/doc/examples/vaapi_encode.c index 46bca1b3fe..07b20a7ec4 100644 --- a/doc/examples/vaapi_encode.c +++ b/doc/examples/vaapi_encode.c @@ -91,6 +91,10 @@ static int encode_write(AVCodecContext *avctx, AVFrame *frame, FILE *fout) enc_pkt->stream_index = 0; ret = fwrite(enc_pkt->data, enc_pkt->size, 1, fout); av_packet_unref(enc_pkt); + if (ret != enc_pkt->size) { + ret = AVERROR(errno); + break; + } } end: diff --git a/doc/examples/vaapi_transcode.c b/doc/examples/vaapi_transcode.c index 5a1a704a8e..40a6d58aad 100644 --- a/doc/examples/vaapi_transcode.c +++ b/doc/examples/vaapi_transcode.c @@ -218,10 +218,8 @@ static int dec_enc(AVPacket *pkt, AVCodec *enc_codec) fail: av_frame_free(&frame); - if (ret < 0) - return ret; } - return 0; + return ret; } int main(int argc, char **argv) diff --git a/doc/fate_config.sh.template b/doc/fate_config.sh.template index ab1bda45e4..ab990c3a58 100644 --- a/doc/fate_config.sh.template +++ b/doc/fate_config.sh.template @@ -1,5 +1,5 @@ slot= # some unique identifier -repo=git://source.ffmpeg.org/ffmpeg.git # the source repository +repo=https://git.ffmpeg.org/ffmpeg.git # the source repository #branch=release/2.6 # the branch to test samples= # path to samples directory workdir= # directory in which to do all the work diff --git a/doc/git-howto.texi b/doc/git-howto.texi index 2b4fb80233..8aa9b7cffa 100644 --- a/doc/git-howto.texi +++ b/doc/git-howto.texi @@ -53,7 +53,7 @@ Most distribution and operating system provide a package for it. @section Cloning the source tree @example -git clone git://source.ffmpeg.org/ffmpeg +git clone https://git.ffmpeg.org/ffmpeg.git @end example This will put the FFmpeg sources into the directory @var{}. @@ -143,7 +143,7 @@ git log @end example You may also use the graphical tools like @command{gitview} or @command{gitk} -or the web interface available at @url{http://source.ffmpeg.org/}. +or the web interface available at @url{https://git.ffmpeg.org/ffmpeg.git}. @section Checking source tree status @@ -187,11 +187,18 @@ to make sure you don't have untracked files or deletions. git add [-i|-p|-A] @end example -Make sure you have told Git your name and email address +Make sure you have told Git your name, email address and GPG key @example git config --global user.name "My Name" git config --global user.email my@@email.invalid +git config --global user.signingkey ABCDEF0123245 +@end example + +Enable signing all commits or use -S + +@example +git config --global commit.gpgsign true @end example Use @option{--global} to set the global configuration for all your Git checkouts. @@ -393,6 +400,19 @@ git checkout -b svn_23456 $SHA1 where @var{$SHA1} is the commit hash from the @command{git log} output. +@chapter gpg key generation + +If you have no gpg key yet, we recommend that you create a ed25519 based key as it +is small, fast and secure. Especially it results in small signatures in git. + +@example +gpg --default-new-key-algo "ed25519/cert,sign+cv25519/encr" --quick-generate-key "human@@server.com" +@end example + +When generating a key, make sure the email specified matches the email used in git as some sites like +github consider mismatches a reason to declare such commits unverified. After generating a key you +can add it to the MAINTAINER file and upload it to a keyserver. + @chapter Pre-push checklist Once you have a set of commits that you feel are ready for pushing, diff --git a/doc/t2h.pm b/doc/t2h.pm index e83d564a65..b7485e1f1e 100644 --- a/doc/t2h.pm +++ b/doc/t2h.pm @@ -20,8 +20,45 @@ # License along with FFmpeg; if not, write to the Free Software # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +# Texinfo 7.0 changed the syntax of various functions. +# Provide a shim for older versions. +sub ff_set_from_init_file($$) { + my $key = shift; + my $value = shift; + if (exists &{'texinfo_set_from_init_file'}) { + texinfo_set_from_init_file($key, $value); + } else { + set_from_init_file($key, $value); + } +} + +sub ff_get_conf($) { + my $key = shift; + if (exists &{'texinfo_get_conf'}) { + texinfo_get_conf($key); + } else { + get_conf($key); + } +} + +sub get_formatting_function($$) { + my $obj = shift; + my $func = shift; + + my $sub = $obj->can('formatting_function'); + if ($sub) { + return $obj->formatting_function($func); + } else { + return $obj->{$func}; + } +} + +# determine texinfo version +my $program_version_num = version->declare(ff_get_conf('PACKAGE_VERSION'))->numify; +my $program_version_6_8 = $program_version_num >= 6.008000; + # no navigation elements -set_from_init_file('HEADERS', 0); +ff_set_from_init_file('HEADERS', 0); sub ffmpeg_heading_command($$$$$) { @@ -55,7 +92,7 @@ sub ffmpeg_heading_command($$$$$) $element = $command->{'parent'}; } if ($element) { - $result .= &{$self->{'format_element_header'}}($self, $cmdname, + $result .= &{get_formatting_function($self, 'format_element_header')}($self, $cmdname, $command, $element); } @@ -112,7 +149,11 @@ sub ffmpeg_heading_command($$$$$) $cmdname = $Texinfo::Common::level_to_structuring_command{$cmdname}->[$heading_level]; } - $result .= &{$self->{'format_heading_text'}}( + # format_heading_text expects an array of headings for texinfo >= 7.0 + if ($program_version_num >= 7.000000) { + $heading = [$heading]; + } + $result .= &{get_formatting_function($self,'format_heading_text')}( $self, $cmdname, $heading, $heading_level + $self->get_conf('CHAPTER_HEADER_LEVEL') - 1, $command); @@ -127,14 +168,18 @@ foreach my $command (keys(%Texinfo::Common::sectioning_commands), 'node') { } # print the TOC where @contents is used -set_from_init_file('INLINE_CONTENTS', 1); +if ($program_version_6_8) { + ff_set_from_init_file('CONTENTS_OUTPUT_LOCATION', 'inline'); +} else { + ff_set_from_init_file('INLINE_CONTENTS', 1); +} # make chapters

-set_from_init_file('CHAPTER_HEADER_LEVEL', 2); +ff_set_from_init_file('CHAPTER_HEADER_LEVEL', 2); # Do not add
-set_from_init_file('DEFAULT_RULE', ''); -set_from_init_file('BIG_RULE', ''); +ff_set_from_init_file('DEFAULT_RULE', ''); +ff_set_from_init_file('BIG_RULE', ''); # Customized file beginning sub ffmpeg_begin_file($$$) @@ -151,7 +196,18 @@ sub ffmpeg_begin_file($$$) my ($title, $description, $encoding, $date, $css_lines, $doctype, $bodytext, $copying_comment, $after_body_open, $extra_head, $program_and_version, $program_homepage, - $program, $generator) = $self->_file_header_informations($command); + $program, $generator); + if ($program_version_num >= 7.000000) { + ($title, $description, $encoding, $date, $css_lines, + $doctype, $bodytext, $copying_comment, $after_body_open, + $extra_head, $program_and_version, $program_homepage, + $program, $generator) = $self->_file_header_information($command); + } else { + ($title, $description, $encoding, $date, $css_lines, + $doctype, $bodytext, $copying_comment, $after_body_open, + $extra_head, $program_and_version, $program_homepage, + $program, $generator) = $self->_file_header_informations($command); + } my $links = $self->_get_links ($filename, $element); @@ -184,7 +240,11 @@ EOT return $head1 . $head_title . $head2 . $head_title . $head3; } -texinfo_register_formatting_function('begin_file', \&ffmpeg_begin_file); +if ($program_version_6_8) { + texinfo_register_formatting_function('format_begin_file', \&ffmpeg_begin_file); +} else { + texinfo_register_formatting_function('begin_file', \&ffmpeg_begin_file); +} sub ffmpeg_program_string($) { @@ -201,13 +261,17 @@ sub ffmpeg_program_string($) $self->gdt('This document was generated automatically.')); } } -texinfo_register_formatting_function('program_string', \&ffmpeg_program_string); +if ($program_version_6_8) { + texinfo_register_formatting_function('format_program_string', \&ffmpeg_program_string); +} else { + texinfo_register_formatting_function('program_string', \&ffmpeg_program_string); +} # Customized file ending sub ffmpeg_end_file($) { my $self = shift; - my $program_string = &{$self->{'format_program_string'}}($self); + my $program_string = &{get_formatting_function($self,'format_program_string')}($self); my $program_text = < $program_string @@ -220,11 +284,15 @@ EOT EOT return $program_text . $footer; } -texinfo_register_formatting_function('end_file', \&ffmpeg_end_file); +if ($program_version_6_8) { + texinfo_register_formatting_function('format_end_file', \&ffmpeg_end_file); +} else { + texinfo_register_formatting_function('end_file', \&ffmpeg_end_file); +} # Dummy title command # Ignore title. Title is handled through ffmpeg_begin_file(). -set_from_init_file('USE_TITLEPAGE_FOR_TITLE', 1); +ff_set_from_init_file('USE_TITLEPAGE_FOR_TITLE', 1); sub ffmpeg_title($$$$) { return ''; @@ -242,8 +310,14 @@ sub ffmpeg_float($$$$$) my $args = shift; my $content = shift; - my ($caption, $prepended) = Texinfo::Common::float_name_caption($self, - $command); + my ($caption, $prepended); + if ($program_version_num >= 7.000000) { + ($caption, $prepended) = Texinfo::Convert::Converter::float_name_caption($self, + $command); + } else { + ($caption, $prepended) = Texinfo::Common::float_name_caption($self, + $command); + } my $caption_text = ''; my $prepended_text; my $prepended_save = ''; @@ -315,8 +389,13 @@ sub ffmpeg_float($$$$$) $caption->{'args'}->[0], 'float caption'); } if ($prepended_text.$caption_text ne '') { - $prepended_text = $self->_attribute_class('div','float-caption'). '>' - . $prepended_text; + if ($program_version_num >= 7.000000) { + $prepended_text = $self->html_attribute_class('div',['float-caption']). '>' + . $prepended_text; + } else { + $prepended_text = $self->_attribute_class('div','float-caption'). '>' + . $prepended_text; + } $caption_text .= ''; } my $html_class = ''; @@ -329,8 +408,13 @@ sub ffmpeg_float($$$$$) $prepended_text = ''; $caption_text = ''; } - return $self->_attribute_class('div', $html_class). '>' . "\n" . - $prepended_text . $caption_text . $content . ''; + if ($program_version_num >= 7.000000) { + return $self->html_attribute_class('div', [$html_class]). '>' . "\n" . + $prepended_text . $caption_text . $content . ''; + } else { + return $self->_attribute_class('div', $html_class). '>' . "\n" . + $prepended_text . $caption_text . $content . ''; + } } texinfo_register_command_formatting('float', diff --git a/doc/writing_filters.txt b/doc/writing_filters.txt index 2e25cbed71..e89d7d1e05 100644 --- a/doc/writing_filters.txt +++ b/doc/writing_filters.txt @@ -418,4 +418,4 @@ done: When all of this is done, you can submit your patch to the ffmpeg-devel mailing-list for review. If you need any help, feel free to come on our IRC -channel, #ffmpeg-devel on irc.freenode.net. +channel, #ffmpeg-devel on irc.libera.chat. diff --git a/ffbuild/common.mak b/ffbuild/common.mak index e070b6b5e2..164a43932d 100644 --- a/ffbuild/common.mak +++ b/ffbuild/common.mak @@ -90,7 +90,7 @@ COMPILE_MSA = $(call COMPILE,CC,MSAFLAGS) -$(if $(ASMSTRIPFLAGS), $(STRIP) $(ASMSTRIPFLAGS) $@) %.o: %.rc - $(WINDRES) $(IFLAGS) --preprocessor "$(DEPWINDRES) -E -xc-header -DRC_INVOKED $(CC_DEPFLAGS)" -o $@ $< + $(WINDRES) $(IFLAGS) $(foreach ARG,$(CC_DEPFLAGS),--preprocessor-arg "$(ARG)") -o $@ $< %.i: %.c $(CC) $(CCFLAGS) $(CC_E) $< diff --git a/fftools/cmdutils.c b/fftools/cmdutils.c index fe424b6a4c..a647651b1f 100644 --- a/fftools/cmdutils.c +++ b/fftools/cmdutils.c @@ -537,7 +537,7 @@ static const AVOption *opt_find(void *obj, const char *name, const char *unit, return o; } -#define FLAGS (o->type == AV_OPT_TYPE_FLAGS && (arg[0]=='-' || arg[0]=='+')) ? AV_DICT_APPEND : 0 +#define FLAGS ((o->type == AV_OPT_TYPE_FLAGS && (arg[0]=='-' || arg[0]=='+')) ? AV_DICT_APPEND : 0) int opt_default(void *optctx, const char *opt, const char *arg) { const AVOption *o; diff --git a/fftools/ffmpeg.c b/fftools/ffmpeg.c index 46bb014de8..b5cc3fa023 100644 --- a/fftools/ffmpeg.c +++ b/fftools/ffmpeg.c @@ -492,8 +492,9 @@ static int read_key(void) } //Read it if(nchars != 0) { - read(0, &ch, 1); - return ch; + if (read(0, &ch, 1) == 1) + return ch; + return 0; }else{ return -1; } @@ -1974,6 +1975,9 @@ static void flush_encoders(void) AVPacket *pkt = ost->pkt; int pkt_size; + if (!pkt) + break; + switch (enc->codec_type) { case AVMEDIA_TYPE_AUDIO: desc = "audio"; @@ -3463,12 +3467,7 @@ static int init_output_stream_encode(OutputStream *ost, AVFrame *frame) enc_ctx->bits_per_raw_sample = frame_bits_per_raw_sample; } - if (ost->top_field_first == 0) { - enc_ctx->field_order = AV_FIELD_BB; - } else if (ost->top_field_first == 1) { - enc_ctx->field_order = AV_FIELD_TT; - } - + // Field order: autodetection if (frame) { if (enc_ctx->flags & (AV_CODEC_FLAG_INTERLACED_DCT | AV_CODEC_FLAG_INTERLACED_ME) && ost->top_field_first >= 0) @@ -3483,6 +3482,13 @@ static int init_output_stream_encode(OutputStream *ost, AVFrame *frame) enc_ctx->field_order = AV_FIELD_PROGRESSIVE; } + // Field order: override + if (ost->top_field_first == 0) { + enc_ctx->field_order = AV_FIELD_BB; + } else if (ost->top_field_first == 1) { + enc_ctx->field_order = AV_FIELD_TT; + } + if (ost->forced_keyframes) { if (!strncmp(ost->forced_keyframes, "expr:", 5)) { ret = av_expr_parse(&ost->forced_keyframes_pexpr, ost->forced_keyframes+5, @@ -3950,7 +3956,7 @@ static OutputStream *choose_output(void) ost->st->index, ost->st->id, ost->initialized, ost->inputs_done, ost->finished); if (!ost->initialized && !ost->inputs_done) - return ost; + return ost->unavailable ? NULL : ost; if (!ost->finished && opts < opts_min) { opts_min = opts; diff --git a/libavcodec/012v.c b/libavcodec/012v.c index b5a4066656..41d9e2708e 100644 --- a/libavcodec/012v.c +++ b/libavcodec/012v.c @@ -131,8 +131,8 @@ static int zero12v_decode_frame(AVCodecContext *avctx, void *data, 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); + memcpy(u, u_temp, sizeof(*u) * ((width - x + 1) / 2)); + memcpy(v, v_temp, sizeof(*v) * ((width - x + 1) / 2)); } line_end += stride; diff --git a/libavcodec/4xm.c b/libavcodec/4xm.c index cbd8637763..dcb21a4ac2 100644 --- a/libavcodec/4xm.c +++ b/libavcodec/4xm.c @@ -886,6 +886,8 @@ static int decode_frame(AVCodecContext *avctx, void *data, } if (i >= CFRAME_BUFFER_COUNT) { + if (free_index < 0) + return AVERROR_INVALIDDATA; i = free_index; f->cfrm[i].id = id; } diff --git a/libavcodec/8bps.c b/libavcodec/8bps.c index 53e939d35d..6cc9a0c9ae 100644 --- a/libavcodec/8bps.c +++ b/libavcodec/8bps.c @@ -70,6 +70,9 @@ static int decode_frame(AVCodecContext *avctx, void *data, unsigned char *planemap = c->planemap; int ret; + if (buf_size < planes * height *2) + return AVERROR_INVALIDDATA; + if ((ret = ff_get_buffer(avctx, frame, 0)) < 0) return ret; diff --git a/libavcodec/Makefile b/libavcodec/Makefile index 33a280cf69..b3d284d7d0 100644 --- a/libavcodec/Makefile +++ b/libavcodec/Makefile @@ -132,7 +132,6 @@ OBJS-$(CONFIG_MPEGVIDEOENC) += mpegvideo_enc.o mpeg12data.o \ motion_est.o ratecontrol.o \ mpegvideoencdsp.o OBJS-$(CONFIG_MSS34DSP) += mss34dsp.o -OBJS-$(CONFIG_NVENC) += nvenc.o OBJS-$(CONFIG_PIXBLOCKDSP) += pixblockdsp.o OBJS-$(CONFIG_QPELDSP) += qpeldsp.o OBJS-$(CONFIG_QSV) += qsv.o @@ -375,9 +374,9 @@ OBJS-$(CONFIG_H264_CUVID_DECODER) += cuviddec.o OBJS-$(CONFIG_H264_MEDIACODEC_DECODER) += mediacodecdec.o OBJS-$(CONFIG_H264_MF_ENCODER) += mfenc.o mf_utils.o OBJS-$(CONFIG_H264_MMAL_DECODER) += mmaldec.o -OBJS-$(CONFIG_H264_NVENC_ENCODER) += nvenc_h264.o -OBJS-$(CONFIG_NVENC_ENCODER) += nvenc_h264.o -OBJS-$(CONFIG_NVENC_H264_ENCODER) += nvenc_h264.o +OBJS-$(CONFIG_H264_NVENC_ENCODER) += nvenc.o nvenc_h264.o +OBJS-$(CONFIG_NVENC_ENCODER) += nvenc.o nvenc_h264.o +OBJS-$(CONFIG_NVENC_H264_ENCODER) += nvenc.o nvenc_h264.o OBJS-$(CONFIG_H264_OMX_ENCODER) += omx.o OBJS-$(CONFIG_H264_QSV_DECODER) += qsvdec.o OBJS-$(CONFIG_H264_QSV_ENCODER) += qsvenc_h264.o @@ -397,8 +396,8 @@ OBJS-$(CONFIG_HEVC_AMF_ENCODER) += amfenc_hevc.o OBJS-$(CONFIG_HEVC_CUVID_DECODER) += cuviddec.o OBJS-$(CONFIG_HEVC_MEDIACODEC_DECODER) += mediacodecdec.o OBJS-$(CONFIG_HEVC_MF_ENCODER) += mfenc.o mf_utils.o -OBJS-$(CONFIG_HEVC_NVENC_ENCODER) += nvenc_hevc.o -OBJS-$(CONFIG_NVENC_HEVC_ENCODER) += nvenc_hevc.o +OBJS-$(CONFIG_HEVC_NVENC_ENCODER) += nvenc.o nvenc_hevc.o +OBJS-$(CONFIG_NVENC_HEVC_ENCODER) += nvenc.o nvenc_hevc.o OBJS-$(CONFIG_HEVC_QSV_DECODER) += qsvdec.o OBJS-$(CONFIG_HEVC_QSV_ENCODER) += qsvenc_hevc.o hevc_ps_enc.o \ hevc_data.o @@ -875,6 +874,7 @@ OBJS-$(CONFIG_ADPCM_G726_ENCODER) += g726.o OBJS-$(CONFIG_ADPCM_G726LE_DECODER) += g726.o OBJS-$(CONFIG_ADPCM_G726LE_ENCODER) += g726.o OBJS-$(CONFIG_ADPCM_IMA_AMV_DECODER) += adpcm.o adpcm_data.o +OBJS-$(CONFIG_ADPCM_IMA_AMV_ENCODER) += adpcmenc.o adpcm_data.o OBJS-$(CONFIG_ADPCM_IMA_ALP_DECODER) += adpcm.o adpcm_data.o OBJS-$(CONFIG_ADPCM_IMA_ALP_ENCODER) += adpcmenc.o adpcm_data.o OBJS-$(CONFIG_ADPCM_IMA_APC_DECODER) += adpcm.o adpcm_data.o diff --git a/libavcodec/a64multienc.c b/libavcodec/a64multienc.c index 55616c8524..91c89c87eb 100644 --- a/libavcodec/a64multienc.c +++ b/libavcodec/a64multienc.c @@ -107,13 +107,16 @@ static void render_charset(AVCodecContext *avctx, uint8_t *charset, uint8_t pix; int lowdiff, highdiff; int *best_cb = c->mc_best_cb; - static uint8_t index1[256]; - static uint8_t index2[256]; - static uint8_t dither[256]; + uint8_t index1[256]; + uint8_t index2[256]; + uint8_t dither[256]; int i; int distance; - /* generate lookup-tables for dither and index before looping */ + /* Generate lookup-tables for dither and index before looping. + * This code relies on c->mc_luma_vals[c->mc_pal_size - 1] being + * the maximum of all the mc_luma_vals values and on the minimum + * being zero; this ensures that dither is properly initialized. */ i = 0; for (a=0; a < 256; a++) { if(i < c->mc_pal_size -1 && a == c->mc_luma_vals[i + 1]) { diff --git a/libavcodec/aaccoder.c b/libavcodec/aaccoder.c index baa82489b1..11b0559e1c 100644 --- a/libavcodec/aaccoder.c +++ b/libavcodec/aaccoder.c @@ -843,25 +843,25 @@ static void search_for_ms(AACEncContext *s, ChannelElement *cpe) sce0->ics.swb_sizes[g], sce0->sf_idx[w*16+g], sce0->band_type[w*16+g], - lambda / band0->threshold, INFINITY, &b1, NULL, 0); + lambda / (band0->threshold + FLT_MIN), INFINITY, &b1, NULL, 0); dist1 += quantize_band_cost(s, &sce1->coeffs[start + (w+w2)*128], R34, sce1->ics.swb_sizes[g], sce1->sf_idx[w*16+g], sce1->band_type[w*16+g], - lambda / band1->threshold, INFINITY, &b2, NULL, 0); + lambda / (band1->threshold + FLT_MIN), INFINITY, &b2, NULL, 0); dist2 += quantize_band_cost(s, M, M34, sce0->ics.swb_sizes[g], mididx, midcb, - lambda / minthr, INFINITY, &b3, NULL, 0); + lambda / (minthr + FLT_MIN), INFINITY, &b3, NULL, 0); dist2 += quantize_band_cost(s, S, S34, sce1->ics.swb_sizes[g], sididx, sidcb, - mslambda / (minthr * bmax), INFINITY, &b4, NULL, 0); + mslambda / (minthr * bmax + FLT_MIN), INFINITY, &b4, NULL, 0); B0 += b1+b2; B1 += b3+b4; dist1 -= b1+b2; diff --git a/libavcodec/aacdec_template.c b/libavcodec/aacdec_template.c index 98f77a3ad7..3d7f3257db 100644 --- a/libavcodec/aacdec_template.c +++ b/libavcodec/aacdec_template.c @@ -1076,14 +1076,18 @@ static int decode_audio_specific_config_gb(AACContext *ac, { int i, ret; GetBitContext gbc = *gb; + MPEG4AudioConfig m4ac_bak = *m4ac; - if ((i = ff_mpeg4audio_get_config_gb(m4ac, &gbc, sync_extension, avctx)) < 0) + if ((i = ff_mpeg4audio_get_config_gb(m4ac, &gbc, sync_extension, avctx)) < 0) { + *m4ac = m4ac_bak; return AVERROR_INVALIDDATA; + } if (m4ac->sampling_index > 12) { av_log(avctx, AV_LOG_ERROR, "invalid sampling rate index %d\n", m4ac->sampling_index); + *m4ac = m4ac_bak; return AVERROR_INVALIDDATA; } if (m4ac->object_type == AOT_ER_AAC_LD && @@ -1091,6 +1095,7 @@ static int decode_audio_specific_config_gb(AACContext *ac, av_log(avctx, AV_LOG_ERROR, "invalid low delay sampling rate index %d\n", m4ac->sampling_index); + *m4ac = m4ac_bak; return AVERROR_INVALIDDATA; } diff --git a/libavcodec/aacenc.c b/libavcodec/aacenc.c index 070a2e706a..be5e8e2108 100644 --- a/libavcodec/aacenc.c +++ b/libavcodec/aacenc.c @@ -28,6 +28,7 @@ * TODOs: * add sane pulse detection ***********************************/ +#include #include "libavutil/libm.h" #include "libavutil/float_dsp.h" @@ -852,7 +853,7 @@ static int aac_encode_frame(AVCodecContext *avctx, AVPacket *avpkt, /* Not so fast though */ ratio = sqrtf(ratio); } - s->lambda = FFMIN(s->lambda * ratio, 65536.f); + s->lambda = av_clipf(s->lambda * ratio, FLT_EPSILON, 65536.f); /* Keep iterating if we must reduce and lambda is in the sky */ if (ratio > 0.9f && ratio < 1.1f) { @@ -897,7 +898,7 @@ static av_cold int aac_encode_end(AVCodecContext *avctx) { AACEncContext *s = avctx->priv_data; - av_log(avctx, AV_LOG_INFO, "Qavg: %.3f\n", s->lambda_sum / s->lambda_count); + av_log(avctx, AV_LOG_INFO, "Qavg: %.3f\n", s->lambda_count ? s->lambda_sum / s->lambda_count : NAN); ff_mdct_end(&s->mdct1024); ff_mdct_end(&s->mdct128); diff --git a/libavcodec/aacpsy.c b/libavcodec/aacpsy.c index fca692cb15..76458783ce 100644 --- a/libavcodec/aacpsy.c +++ b/libavcodec/aacpsy.c @@ -308,6 +308,9 @@ static av_cold int psy_3gpp_init(FFPsyContext *ctx) { const int bandwidth = ctx->cutoff ? ctx->cutoff : AAC_CUTOFF(ctx->avctx); const float num_bark = calc_bark((float)bandwidth); + if (bandwidth <= 0) + return AVERROR(EINVAL); + ctx->model_priv_data = av_mallocz(sizeof(AacPsyContext)); if (!ctx->model_priv_data) return AVERROR(ENOMEM); @@ -794,7 +797,7 @@ static void psy_3gpp_analyze_channel(FFPsyContext *ctx, int channel, if (pe < 1.15f * desired_pe) { /* 6.6.1.3.6 "Final threshold modification by linearization" */ - norm_fac = 1.0f / norm_fac; + norm_fac = norm_fac ? 1.0f / norm_fac : 0; for (w = 0; w < wi->num_windows*16; w += 16) { for (g = 0; g < num_bands; g++) { AacPsyBand *band = &pch->band[w+g]; diff --git a/libavcodec/aacsbr_template.c b/libavcodec/aacsbr_template.c index 774f12e77a..04ab2f1e36 100644 --- a/libavcodec/aacsbr_template.c +++ b/libavcodec/aacsbr_template.c @@ -588,6 +588,7 @@ static int sbr_make_f_derived(AACContext *ac, SpectralBandReplication *sbr) if (sbr->n_q > 5) { av_log(ac->avctx, AV_LOG_ERROR, "Too many noise floor scale factors: %d\n", sbr->n_q); + sbr->n_q = 1; return -1; } diff --git a/libavcodec/aarch64/hevcdsp_idct_neon.S b/libavcodec/aarch64/hevcdsp_idct_neon.S index 28c11e632c..0869431294 100644 --- a/libavcodec/aarch64/hevcdsp_idct_neon.S +++ b/libavcodec/aarch64/hevcdsp_idct_neon.S @@ -573,14 +573,13 @@ idct_16x16 10 // void ff_hevc_idct_NxN_dc_DEPTH_neon(int16_t *coeffs) .macro idct_dc size, bitdepth function ff_hevc_idct_\size\()x\size\()_dc_\bitdepth\()_neon, export=1 - movi v1.8h, #((1 << (14 - \bitdepth))+1) ld1r {v4.8h}, [x0] - add v4.8h, v4.8h, v1.8h - sshr v0.8h, v4.8h, #(15 - \bitdepth) - sshr v1.8h, v4.8h, #(15 - \bitdepth) + srshr v4.8h, v4.8h, #1 + srshr v0.8h, v4.8h, #(14 - \bitdepth) + srshr v1.8h, v4.8h, #(14 - \bitdepth) .if \size > 4 - sshr v2.8h, v4.8h, #(15 - \bitdepth) - sshr v3.8h, v4.8h, #(15 - \bitdepth) + srshr v2.8h, v4.8h, #(14 - \bitdepth) + srshr v3.8h, v4.8h, #(14 - \bitdepth) .if \size > 16 /* dc 32x32 */ mov x2, #4 1: diff --git a/libavcodec/aarch64/vp9mc_neon.S b/libavcodec/aarch64/vp9mc_neon.S index abf2bae9db..38f44ca56d 100644 --- a/libavcodec/aarch64/vp9mc_neon.S +++ b/libavcodec/aarch64/vp9mc_neon.S @@ -230,6 +230,9 @@ function \type\()_8tap_\size\()h_\idx1\idx2 // reduced dst stride .if \size >= 16 sub x1, x1, x5 +.elseif \size == 4 + add x12, x2, #8 + add x13, x7, #8 .endif // size >= 16 loads two qwords and increments x2, // for size 4/8 it's enough with one qword and no @@ -248,9 +251,14 @@ function \type\()_8tap_\size\()h_\idx1\idx2 .if \size >= 16 ld1 {v4.8b, v5.8b, v6.8b}, [x2], #24 ld1 {v16.8b, v17.8b, v18.8b}, [x7], #24 -.else +.elseif \size == 8 ld1 {v4.8b, v5.8b}, [x2] ld1 {v16.8b, v17.8b}, [x7] +.else // \size == 4 + ld1 {v4.8b}, [x2] + ld1 {v16.8b}, [x7] + ld1 {v5.s}[0], [x12], x3 + ld1 {v17.s}[0], [x13], x3 .endif uxtl v4.8h, v4.8b uxtl v5.8h, v5.8b diff --git a/libavcodec/aasc.c b/libavcodec/aasc.c index 26570f49e5..86cb9e85a1 100644 --- a/libavcodec/aasc.c +++ b/libavcodec/aasc.c @@ -104,26 +104,26 @@ static int aasc_decode_frame(AVCodecContext *avctx, ff_msrle_decode(avctx, s->frame, 8, &s->gb); break; case MKTAG('A', 'A', 'S', 'C'): - switch (compr) { - case 0: - stride = (avctx->width * psize + psize) & ~psize; - if (buf_size < stride * avctx->height) + switch (compr) { + case 0: + stride = (avctx->width * psize + psize) & ~psize; + if (buf_size < stride * avctx->height) + return AVERROR_INVALIDDATA; + for (i = avctx->height - 1; i >= 0; i--) { + memcpy(s->frame->data[0] + i * s->frame->linesize[0], buf, avctx->width * psize); + buf += stride; + buf_size -= stride; + } + break; + case 1: + bytestream2_init(&s->gb, buf, buf_size); + ff_msrle_decode(avctx, s->frame, 8, &s->gb); + break; + default: + av_log(avctx, AV_LOG_ERROR, "Unknown compression type %d\n", compr); return AVERROR_INVALIDDATA; - for (i = avctx->height - 1; i >= 0; i--) { - memcpy(s->frame->data[0] + i * s->frame->linesize[0], buf, avctx->width * psize); - buf += stride; - buf_size -= stride; } break; - case 1: - bytestream2_init(&s->gb, buf, buf_size); - ff_msrle_decode(avctx, s->frame, 8, &s->gb); - break; - default: - av_log(avctx, AV_LOG_ERROR, "Unknown compression type %d\n", compr); - return AVERROR_INVALIDDATA; - } - break; default: av_log(avctx, AV_LOG_ERROR, "Unknown FourCC: %X\n", avctx->codec_tag); return -1; diff --git a/libavcodec/ac3.h b/libavcodec/ac3.h index f8f6a81f45..1fb900ecb1 100644 --- a/libavcodec/ac3.h +++ b/libavcodec/ac3.h @@ -27,7 +27,6 @@ #ifndef AVCODEC_AC3_H #define AVCODEC_AC3_H -#define AC3_MAX_CODED_FRAME_SIZE 3840 /* in bytes */ #define EAC3_MAX_CHANNELS 16 /**< maximum number of channels in EAC3 */ #define AC3_MAX_CHANNELS 7 /**< maximum number of channels, including coupling channel */ #define CPL_CH 0 /**< coupling channel index */ @@ -75,6 +74,7 @@ #define AC3_DYNAMIC_RANGE1 0 typedef int INTFLOAT; +typedef unsigned int UINTFLOAT; typedef int16_t SHORTFLOAT; #else /* USE_FIXED */ @@ -94,6 +94,7 @@ typedef int16_t SHORTFLOAT; #define AC3_DYNAMIC_RANGE1 1.0f typedef float INTFLOAT; +typedef float UINTFLOAT; typedef float SHORTFLOAT; #endif /* USE_FIXED */ diff --git a/libavcodec/ac3_parser.c b/libavcodec/ac3_parser.c index ba171653ef..6cb6038833 100644 --- a/libavcodec/ac3_parser.c +++ b/libavcodec/ac3_parser.c @@ -179,7 +179,9 @@ int av_ac3_parse_header(const uint8_t *buf, size_t size, AC3HeaderInfo hdr; int err; - init_get_bits8(&gb, buf, size); + err = init_get_bits8(&gb, buf, size); + if (err < 0) + return AVERROR_INVALIDDATA; err = ff_ac3_parse_header(&gb, &hdr); if (err < 0) return AVERROR_INVALIDDATA; diff --git a/libavcodec/ac3enc.c b/libavcodec/ac3enc.c index 8044e6dcd0..4cfd0afe12 100644 --- a/libavcodec/ac3enc.c +++ b/libavcodec/ac3enc.c @@ -1729,7 +1729,7 @@ static void ac3_output_frame(AC3EncodeContext *s, unsigned char *frame) { int blk; - init_put_bits(&s->pb, frame, AC3_MAX_CODED_FRAME_SIZE); + init_put_bits(&s->pb, frame, s->frame_size); s->output_frame_header(s); diff --git a/libavcodec/adpcm.c b/libavcodec/adpcm.c index 5b6d1040af..8aab07e334 100644 --- a/libavcodec/adpcm.c +++ b/libavcodec/adpcm.c @@ -100,7 +100,7 @@ static const int8_t mtf_index_table[16] = { typedef struct ADPCMDecodeContext { ADPCMChannelStatus status[14]; int vqa_version; /**< VQA version. Used for ADPCM_IMA_WS */ - int has_status; + int has_status; /**< Status flag. Reset to 0 after a flush. */ } ADPCMDecodeContext; static av_cold int adpcm_decode_init(AVCodecContext * avctx) @@ -1811,11 +1811,6 @@ static int adpcm_decode_frame(AVCodecContext *avctx, void *data, } break; case AV_CODEC_ID_ADPCM_AICA: - if (!c->has_status) { - for (channel = 0; channel < avctx->channels; channel++) - c->status[channel].step = 0; - c->has_status = 1; - } for (channel = 0; channel < avctx->channels; channel++) { samples = samples_p[channel]; for (n = nb_samples >> 1; n > 0; n--) { @@ -2077,13 +2072,6 @@ static int adpcm_decode_frame(AVCodecContext *avctx, void *data, } break; case AV_CODEC_ID_ADPCM_ZORK: - if (!c->has_status) { - for (channel = 0; channel < avctx->channels; channel++) { - c->status[channel].predictor = 0; - c->status[channel].step_index = 0; - } - c->has_status = 1; - } for (n = 0; n < nb_samples * avctx->channels; n++) { int v = bytestream2_get_byteu(&gb); *samples++ = adpcm_zork_expand_nibble(&c->status[n % avctx->channels], v); @@ -2121,7 +2109,37 @@ static int adpcm_decode_frame(AVCodecContext *avctx, void *data, static void adpcm_flush(AVCodecContext *avctx) { ADPCMDecodeContext *c = avctx->priv_data; - c->has_status = 0; + + switch(avctx->codec_id) { + case AV_CODEC_ID_ADPCM_AICA: + for (int channel = 0; channel < avctx->channels; channel++) + c->status[channel].step = 0; + break; + + case AV_CODEC_ID_ADPCM_ARGO: + for (int channel = 0; channel < avctx->channels; channel++) { + c->status[channel].sample1 = 0; + c->status[channel].sample2 = 0; + } + break; + + case AV_CODEC_ID_ADPCM_IMA_ALP: + case AV_CODEC_ID_ADPCM_IMA_CUNNING: + case AV_CODEC_ID_ADPCM_IMA_SSI: + case AV_CODEC_ID_ADPCM_ZORK: + for (int channel = 0; channel < avctx->channels; channel++) { + c->status[channel].predictor = 0; + c->status[channel].step_index = 0; + } + break; + + default: + /* Other codecs may want to handle this during decoding. */ + c->has_status = 0; + return; + } + + c->has_status = 1; } diff --git a/libavcodec/adpcmenc.c b/libavcodec/adpcmenc.c index 78600735cf..58308dae47 100644 --- a/libavcodec/adpcmenc.c +++ b/libavcodec/adpcmenc.c @@ -959,14 +959,14 @@ static const AVOption options[] = { { NULL } }; -static const AVClass adpcm_encoder_class = { - .class_name = "ADPCM Encoder", - .item_name = av_default_item_name, - .option = options, - .version = LIBAVUTIL_VERSION_INT, -}; - #define ADPCM_ENCODER(id_, name_, sample_fmts_, capabilities_, long_name_) \ +static const AVClass name_ ## _encoder_class = { \ + .class_name = #name_, \ + .item_name = av_default_item_name, \ + .option = options, \ + .version = LIBAVUTIL_VERSION_INT, \ +}; \ + \ AVCodec ff_ ## name_ ## _encoder = { \ .name = #name_, \ .long_name = NULL_IF_CONFIG_SMALL(long_name_), \ @@ -979,7 +979,7 @@ AVCodec ff_ ## name_ ## _encoder = { \ .sample_fmts = sample_fmts_, \ .capabilities = capabilities_, \ .caps_internal = FF_CODEC_CAP_INIT_CLEANUP | FF_CODEC_CAP_INIT_THREADSAFE, \ - .priv_class = &adpcm_encoder_class, \ + .priv_class = &name_ ## _encoder_class, \ } ADPCM_ENCODER(AV_CODEC_ID_ADPCM_ARGO, adpcm_argo, sample_fmts_p, 0, "ADPCM Argonaut Games"); diff --git a/libavcodec/aic.c b/libavcodec/aic.c index cf5b0782be..5cb4d6b5c7 100644 --- a/libavcodec/aic.c +++ b/libavcodec/aic.c @@ -472,8 +472,7 @@ static av_cold int aic_decode_init(AVCodecContext *avctx) } } - ctx->slice_data = av_malloc_array(ctx->slice_width, AIC_BAND_COEFFS - * sizeof(*ctx->slice_data)); + ctx->slice_data = av_calloc(ctx->slice_width, AIC_BAND_COEFFS * sizeof(*ctx->slice_data)); if (!ctx->slice_data) { av_log(avctx, AV_LOG_ERROR, "Error allocating slice buffer\n"); diff --git a/libavcodec/alacdsp.c b/libavcodec/alacdsp.c index 9996eb4319..b3c1c424f3 100644 --- a/libavcodec/alacdsp.c +++ b/libavcodec/alacdsp.c @@ -29,12 +29,12 @@ static void decorrelate_stereo(int32_t *buffer[2], int nb_samples, int i; for (i = 0; i < nb_samples; i++) { - int32_t a, b; + uint32_t a, b; a = buffer[0][i]; b = buffer[1][i]; - a -= (b * decorr_left_weight) >> decorr_shift; + a -= (int)(b * decorr_left_weight) >> decorr_shift; b += a; buffer[0][i] = b; diff --git a/libavcodec/alsdec.c b/libavcodec/alsdec.c index a8c3433fa8..917e7b6264 100644 --- a/libavcodec/alsdec.c +++ b/libavcodec/alsdec.c @@ -1017,7 +1017,7 @@ static int read_block(ALSDecContext *ctx, ALSBlockData *bd) *bd->shift_lsbs = 0; - if (get_bits_left(gb) < 1) + if (get_bits_left(gb) < 7) return AVERROR_INVALIDDATA; // read block type flag and read the samples accordingly @@ -1632,7 +1632,7 @@ static int read_frame_data(ALSDecContext *ctx, unsigned int ra_frame) AVCodecContext *avctx = ctx->avctx; GetBitContext *gb = &ctx->gb; unsigned int div_blocks[32]; ///< block sizes. - unsigned int c; + int c; unsigned int js_blocks[2]; uint32_t bs_info = 0; int ret; @@ -1810,14 +1810,17 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame_ptr, else ctx->cur_frame_length = sconf->frame_length; - ctx->highest_decoded_channel = 0; + ctx->highest_decoded_channel = -1; // decode the frame data if ((invalid_frame = read_frame_data(ctx, ra_frame)) < 0) av_log(ctx->avctx, AV_LOG_WARNING, "Reading frame data failed. Skipping RA unit.\n"); - if (ctx->highest_decoded_channel == 0) + if (ctx->highest_decoded_channel == -1) { + av_log(ctx->avctx, AV_LOG_WARNING, + "No channel data decoded.\n"); return AVERROR_INVALIDDATA; + } ctx->frame_id++; diff --git a/libavcodec/apedec.c b/libavcodec/apedec.c index e0c6b6bb8b..ffdd6beaf4 100644 --- a/libavcodec/apedec.c +++ b/libavcodec/apedec.c @@ -102,7 +102,7 @@ typedef struct APEFilter { int16_t *historybuffer; ///< filter memory int16_t *delay; ///< filtered values - int avg; + uint32_t avg; } APEFilter; typedef struct APERice { @@ -879,7 +879,7 @@ static av_always_inline int filter_fast_3320(APEPredictor *p, } predictionA = p->buf[delayA] * 2U - p->buf[delayA - 1]; - p->lastA[filter] = decoded + ((int32_t)(predictionA * p->coeffsA[filter][0]) >> 9); + p->lastA[filter] = decoded + (unsigned)((int32_t)(predictionA * p->coeffsA[filter][0]) >> 9); if ((decoded ^ predictionA) > 0) p->coeffsA[filter][0]++; @@ -909,8 +909,8 @@ static av_always_inline int filter_3800(APEPredictor *p, return predictionA; } d2 = p->buf[delayA]; - d1 = (p->buf[delayA] - p->buf[delayA - 1]) * 2U; - d0 = p->buf[delayA] + ((p->buf[delayA - 2] - p->buf[delayA - 1]) * 8U); + d1 = (p->buf[delayA] - (unsigned)p->buf[delayA - 1]) * 2; + d0 = p->buf[delayA] + ((p->buf[delayA - 2] - (unsigned)p->buf[delayA - 1]) * 8); d3 = p->buf[delayB] * 2U - p->buf[delayB - 1]; d4 = p->buf[delayB]; @@ -930,7 +930,7 @@ static av_always_inline int filter_3800(APEPredictor *p, p->coeffsB[filter][0] += (((d3 >> 29) & 4) - 2) * sign; p->coeffsB[filter][1] -= (((d4 >> 30) & 2) - 1) * sign; - p->filterB[filter] = p->lastA[filter] + (predictionB >> shift); + p->filterB[filter] = p->lastA[filter] + (unsigned)(predictionB >> shift); p->filterA[filter] = p->filterB[filter] + (unsigned)((int)(p->filterA[filter] * 31U) >> 5); return p->filterA[filter]; @@ -955,7 +955,7 @@ static void long_filter_high_3800(int32_t *buffer, int order, int shift, int len dotprod += delay[j] * (unsigned)coeffs[j]; coeffs[j] += ((delay[j] >> 31) | 1) * sign; } - buffer[i] -= dotprod >> shift; + buffer[i] -= (unsigned)(dotprod >> shift); for (j = 0; j < order - 1; j++) delay[j] = delay[j + 1]; delay[order - 1] = buffer[i]; @@ -979,7 +979,7 @@ static void long_filter_ehigh_3830(int32_t *buffer, int length) for (j = 7; j > 0; j--) delay[j] = delay[j - 1]; delay[0] = buffer[i]; - buffer[i] -= dotprod >> 9; + buffer[i] -= (unsigned)(dotprod >> 9); } } @@ -1088,13 +1088,13 @@ static av_always_inline int predictor_update_3930(APEPredictor *p, const int delayA) { int32_t predictionA, sign; - int32_t d0, d1, d2, d3; + uint32_t d0, d1, d2, d3; p->buf[delayA] = p->lastA[filter]; d0 = p->buf[delayA ]; - d1 = p->buf[delayA ] - p->buf[delayA - 1]; - d2 = p->buf[delayA - 1] - p->buf[delayA - 2]; - d3 = p->buf[delayA - 2] - p->buf[delayA - 3]; + d1 = p->buf[delayA ] - (unsigned)p->buf[delayA - 1]; + d2 = p->buf[delayA - 1] - (unsigned)p->buf[delayA - 2]; + d3 = p->buf[delayA - 2] - (unsigned)p->buf[delayA - 3]; predictionA = d0 * p->coeffsA[filter][0] + d1 * p->coeffsA[filter][1] + @@ -1105,10 +1105,10 @@ static av_always_inline int predictor_update_3930(APEPredictor *p, p->filterA[filter] = p->lastA[filter] + ((int)(p->filterA[filter] * 31U) >> 5); sign = APESIGN(decoded); - p->coeffsA[filter][0] += ((d0 < 0) * 2 - 1) * sign; - p->coeffsA[filter][1] += ((d1 < 0) * 2 - 1) * sign; - p->coeffsA[filter][2] += ((d2 < 0) * 2 - 1) * sign; - p->coeffsA[filter][3] += ((d3 < 0) * 2 - 1) * sign; + p->coeffsA[filter][0] += (((int32_t)d0 < 0) * 2 - 1) * sign; + p->coeffsA[filter][1] += (((int32_t)d1 < 0) * 2 - 1) * sign; + p->coeffsA[filter][2] += (((int32_t)d2 < 0) * 2 - 1) * sign; + p->coeffsA[filter][3] += (((int32_t)d3 < 0) * 2 - 1) * sign; return p->filterA[filter]; } @@ -1166,7 +1166,8 @@ static void predictor_decode_mono_3930(APEContext *ctx, int count) static av_always_inline int predictor_update_filter(APEPredictor64 *p, const int decoded, const int filter, const int delayA, const int delayB, - const int adaptA, const int adaptB) + const int adaptA, const int adaptB, + int compression_level) { int64_t predictionA, predictionB; int32_t sign; @@ -1194,7 +1195,13 @@ static av_always_inline int predictor_update_filter(APEPredictor64 *p, p->buf[delayB - 3] * p->coeffsB[filter][3] + p->buf[delayB - 4] * p->coeffsB[filter][4]; - p->lastA[filter] = decoded + ((int64_t)((uint64_t)predictionA + (predictionB >> 1)) >> 10); + if (compression_level < COMPRESSION_LEVEL_INSANE) { + predictionA = (int32_t)predictionA; + predictionB = (int32_t)predictionB; + p->lastA[filter] = (int32_t)(decoded + (unsigned)((int32_t)(predictionA + (predictionB >> 1)) >> 10)); + } else { + p->lastA[filter] = decoded + ((int64_t)((uint64_t)predictionA + (predictionB >> 1)) >> 10); + } p->filterA[filter] = p->lastA[filter] + ((int64_t)(p->filterA[filter] * 31ULL) >> 5); sign = APESIGN(decoded); @@ -1222,10 +1229,12 @@ static void predictor_decode_stereo_3950(APEContext *ctx, int count) while (count--) { /* Predictor Y */ *decoded0 = predictor_update_filter(p, *decoded0, 0, YDELAYA, YDELAYB, - YADAPTCOEFFSA, YADAPTCOEFFSB); + YADAPTCOEFFSA, YADAPTCOEFFSB, + ctx->compression_level); decoded0++; *decoded1 = predictor_update_filter(p, *decoded1, 1, XDELAYA, XDELAYB, - XADAPTCOEFFSA, XADAPTCOEFFSB); + XADAPTCOEFFSA, XADAPTCOEFFSB, + ctx->compression_level); decoded1++; /* Combined */ @@ -1337,7 +1346,7 @@ static void do_apply_filter(APEContext *ctx, int version, APEFilter *f, absres = FFABSU(res); if (absres) *f->adaptcoeffs = APESIGN(res) * - (8 << ((absres > f->avg * 3) + (absres > f->avg * 4 / 3))); + (8 << ((absres > f->avg * 3LL) + (absres > (f->avg + f->avg / 3)))); /* equivalent to the following code if (absres <= f->avg * 4 / 3) *f->adaptcoeffs = APESIGN(res) * 8; @@ -1587,7 +1596,7 @@ static int ape_decode_frame(AVCodecContext *avctx, void *data, for (ch = 0; ch < s->channels; ch++) { sample8 = (uint8_t *)frame->data[ch]; for (i = 0; i < blockstodecode; i++) - *sample8++ = (s->decoded[ch][i] + 0x80) & 0xff; + *sample8++ = (s->decoded[ch][i] + 0x80U) & 0xff; } break; case 16: @@ -1609,13 +1618,24 @@ static int ape_decode_frame(AVCodecContext *avctx, void *data, s->samples -= blockstodecode; if (avctx->err_recognition & AV_EF_CRCCHECK && - s->fileversion >= 3900 && s->bps < 24) { + s->fileversion >= 3900) { uint32_t crc = s->CRC_state; const AVCRC *crc_tab = av_crc_get_table(AV_CRC_32_IEEE_LE); + int stride = s->bps == 24 ? 4 : (s->bps>>3); + int offset = s->bps == 24; + int bytes = s->bps >> 3; + for (i = 0; i < blockstodecode; i++) { for (ch = 0; ch < s->channels; ch++) { - uint8_t *smp = frame->data[ch] + (i*(s->bps >> 3)); - crc = av_crc(crc_tab, crc, smp, s->bps >> 3); +#if HAVE_BIGENDIAN + uint8_t *smp_native = frame->data[ch] + i*stride; + uint8_t smp[4]; + for(int j = 0; jdata[ch] + i*stride; +#endif + crc = av_crc(crc_tab, crc, smp+offset, bytes); } } diff --git a/libavcodec/argo.c b/libavcodec/argo.c index 7358d102e3..8f58e682f6 100644 --- a/libavcodec/argo.c +++ b/libavcodec/argo.c @@ -59,7 +59,7 @@ static int decode_pal8(AVCodecContext *avctx, uint32_t *pal) return AVERROR_INVALIDDATA; for (int i = 0; i < count; i++) - pal[start + i] = (0xFF << 24U) | bytestream2_get_be24u(gb); + pal[start + i] = (0xFFU << 24) | bytestream2_get_be24u(gb); return 0; } @@ -608,6 +608,9 @@ static int decode_frame(AVCodecContext *avctx, void *data, uint32_t chunk; int ret; + if (avpkt->size < 4) + return AVERROR_INVALIDDATA; + bytestream2_init(gb, avpkt->data, avpkt->size); if ((ret = ff_reget_buffer(avctx, frame, 0)) < 0) @@ -685,6 +688,11 @@ static av_cold int decode_init(AVCodecContext *avctx) return AVERROR_PATCHWELCOME; } + if (avctx->width % 2 || avctx->height % 2) { + avpriv_request_sample(s, "Odd dimensions\n"); + return AVERROR_PATCHWELCOME; + } + s->frame = av_frame_alloc(); if (!s->frame) return AVERROR(ENOMEM); diff --git a/libavcodec/arm/mlpdsp_armv5te.S b/libavcodec/arm/mlpdsp_armv5te.S index 4f9aa485fd..d31568611c 100644 --- a/libavcodec/arm/mlpdsp_armv5te.S +++ b/libavcodec/arm/mlpdsp_armv5te.S @@ -229,7 +229,7 @@ A .endif .endif // Begin loop -01: +1: .if TOTAL_TAPS == 0 // Things simplify a lot in this case // In fact this could be pipelined further if it's worth it... @@ -241,7 +241,7 @@ A .endif str ST0, [PST, #-4]! str ST0, [PST, #4 * (MAX_BLOCKSIZE + MAX_FIR_ORDER)] str ST0, [PSAMP], #4 * MAX_CHANNELS - bne 01b + bne 1b .else .if \fir_taps & 1 .set LOAD_REG, 1 @@ -333,7 +333,7 @@ T orr AC0, AC0, AC1 str ST3, [PST, #-4]! str ST2, [PST, #4 * (MAX_BLOCKSIZE + MAX_FIR_ORDER)] str ST3, [PSAMP], #4 * MAX_CHANNELS - bne 01b + bne 1b .endif b 99f diff --git a/libavcodec/arm/sbcdsp_neon.S b/libavcodec/arm/sbcdsp_neon.S index d83d21d202..914abfb6cc 100644 --- a/libavcodec/arm/sbcdsp_neon.S +++ b/libavcodec/arm/sbcdsp_neon.S @@ -38,49 +38,49 @@ function ff_sbc_analyze_4_neon, export=1 /* TODO: merge even and odd cases (or even merge all four calls to this * function) in order to have only aligned reads from 'in' array * and reduce number of load instructions */ - vld1.16 {d4, d5}, [r0, :64]! - vld1.16 {d8, d9}, [r2, :128]! + vld1.16 {d16, d17}, [r0, :64]! + vld1.16 {d20, d21}, [r2, :128]! - vmull.s16 q0, d4, d8 - vld1.16 {d6, d7}, [r0, :64]! - vmull.s16 q1, d5, d9 - vld1.16 {d10, d11}, [r2, :128]! + vmull.s16 q0, d16, d20 + vld1.16 {d18, d19}, [r0, :64]! + vmull.s16 q1, d17, d21 + vld1.16 {d22, d23}, [r2, :128]! - vmlal.s16 q0, d6, d10 - vld1.16 {d4, d5}, [r0, :64]! - vmlal.s16 q1, d7, d11 - vld1.16 {d8, d9}, [r2, :128]! + vmlal.s16 q0, d18, d22 + vld1.16 {d16, d17}, [r0, :64]! + vmlal.s16 q1, d19, d23 + vld1.16 {d20, d21}, [r2, :128]! - vmlal.s16 q0, d4, d8 - vld1.16 {d6, d7}, [r0, :64]! - vmlal.s16 q1, d5, d9 - vld1.16 {d10, d11}, [r2, :128]! + vmlal.s16 q0, d16, d20 + vld1.16 {d18, d19}, [r0, :64]! + vmlal.s16 q1, d17, d21 + vld1.16 {d22, d23}, [r2, :128]! - vmlal.s16 q0, d6, d10 - vld1.16 {d4, d5}, [r0, :64]! - vmlal.s16 q1, d7, d11 - vld1.16 {d8, d9}, [r2, :128]! + vmlal.s16 q0, d18, d22 + vld1.16 {d16, d17}, [r0, :64]! + vmlal.s16 q1, d19, d23 + vld1.16 {d20, d21}, [r2, :128]! - vmlal.s16 q0, d4, d8 - vmlal.s16 q1, d5, d9 + vmlal.s16 q0, d16, d20 + vmlal.s16 q1, d17, d21 vpadd.s32 d0, d0, d1 vpadd.s32 d1, d2, d3 vrshrn.s32 d0, q0, SBC_PROTO_FIXED_SCALE - vld1.16 {d2, d3, d4, d5}, [r2, :128]! + vld1.16 {d16, d17, d18, d19}, [r2, :128]! vdup.i32 d1, d0[1] /* TODO: can be eliminated */ vdup.i32 d0, d0[0] /* TODO: can be eliminated */ - vmull.s16 q3, d2, d0 - vmull.s16 q4, d3, d0 - vmlal.s16 q3, d4, d1 - vmlal.s16 q4, d5, d1 + vmull.s16 q10, d16, d0 + vmull.s16 q11, d17, d0 + vmlal.s16 q10, d18, d1 + vmlal.s16 q11, d19, d1 - vpadd.s32 d0, d6, d7 /* TODO: can be eliminated */ - vpadd.s32 d1, d8, d9 /* TODO: can be eliminated */ + vpadd.s32 d0, d20, d21 /* TODO: can be eliminated */ + vpadd.s32 d1, d22, d23 /* TODO: can be eliminated */ vst1.32 {d0, d1}, [r1, :128] @@ -91,57 +91,57 @@ function ff_sbc_analyze_8_neon, export=1 /* TODO: merge even and odd cases (or even merge all four calls to this * function) in order to have only aligned reads from 'in' array * and reduce number of load instructions */ - vld1.16 {d4, d5}, [r0, :64]! - vld1.16 {d8, d9}, [r2, :128]! + vld1.16 {d16, d17}, [r0, :64]! + vld1.16 {d20, d21}, [r2, :128]! - vmull.s16 q6, d4, d8 - vld1.16 {d6, d7}, [r0, :64]! - vmull.s16 q7, d5, d9 - vld1.16 {d10, d11}, [r2, :128]! - vmull.s16 q8, d6, d10 - vld1.16 {d4, d5}, [r0, :64]! - vmull.s16 q9, d7, d11 - vld1.16 {d8, d9}, [r2, :128]! + vmull.s16 q12, d16, d20 + vld1.16 {d18, d19}, [r0, :64]! + vmull.s16 q13, d17, d21 + vld1.16 {d22, d23}, [r2, :128]! + vmull.s16 q14, d18, d22 + vld1.16 {d16, d17}, [r0, :64]! + vmull.s16 q15, d19, d23 + vld1.16 {d20, d21}, [r2, :128]! - vmlal.s16 q6, d4, d8 - vld1.16 {d6, d7}, [r0, :64]! - vmlal.s16 q7, d5, d9 - vld1.16 {d10, d11}, [r2, :128]! - vmlal.s16 q8, d6, d10 - vld1.16 {d4, d5}, [r0, :64]! - vmlal.s16 q9, d7, d11 - vld1.16 {d8, d9}, [r2, :128]! + vmlal.s16 q12, d16, d20 + vld1.16 {d18, d19}, [r0, :64]! + vmlal.s16 q13, d17, d21 + vld1.16 {d22, d23}, [r2, :128]! + vmlal.s16 q14, d18, d22 + vld1.16 {d16, d17}, [r0, :64]! + vmlal.s16 q15, d19, d23 + vld1.16 {d20, d21}, [r2, :128]! - vmlal.s16 q6, d4, d8 - vld1.16 {d6, d7}, [r0, :64]! - vmlal.s16 q7, d5, d9 - vld1.16 {d10, d11}, [r2, :128]! - vmlal.s16 q8, d6, d10 - vld1.16 {d4, d5}, [r0, :64]! - vmlal.s16 q9, d7, d11 - vld1.16 {d8, d9}, [r2, :128]! + vmlal.s16 q12, d16, d20 + vld1.16 {d18, d19}, [r0, :64]! + vmlal.s16 q13, d17, d21 + vld1.16 {d22, d23}, [r2, :128]! + vmlal.s16 q14, d18, d22 + vld1.16 {d16, d17}, [r0, :64]! + vmlal.s16 q15, d19, d23 + vld1.16 {d20, d21}, [r2, :128]! - vmlal.s16 q6, d4, d8 - vld1.16 {d6, d7}, [r0, :64]! - vmlal.s16 q7, d5, d9 - vld1.16 {d10, d11}, [r2, :128]! - vmlal.s16 q8, d6, d10 - vld1.16 {d4, d5}, [r0, :64]! - vmlal.s16 q9, d7, d11 - vld1.16 {d8, d9}, [r2, :128]! + vmlal.s16 q12, d16, d20 + vld1.16 {d18, d19}, [r0, :64]! + vmlal.s16 q13, d17, d21 + vld1.16 {d22, d23}, [r2, :128]! + vmlal.s16 q14, d18, d22 + vld1.16 {d16, d17}, [r0, :64]! + vmlal.s16 q15, d19, d23 + vld1.16 {d20, d21}, [r2, :128]! - vmlal.s16 q6, d4, d8 - vld1.16 {d6, d7}, [r0, :64]! - vmlal.s16 q7, d5, d9 - vld1.16 {d10, d11}, [r2, :128]! + vmlal.s16 q12, d16, d20 + vld1.16 {d18, d19}, [r0, :64]! + vmlal.s16 q13, d17, d21 + vld1.16 {d22, d23}, [r2, :128]! - vmlal.s16 q8, d6, d10 - vmlal.s16 q9, d7, d11 + vmlal.s16 q14, d18, d22 + vmlal.s16 q15, d19, d23 - vpadd.s32 d0, d12, d13 - vpadd.s32 d1, d14, d15 - vpadd.s32 d2, d16, d17 - vpadd.s32 d3, d18, d19 + vpadd.s32 d0, d24, d25 + vpadd.s32 d1, d26, d27 + vpadd.s32 d2, d28, d29 + vpadd.s32 d3, d30, d31 vrshr.s32 q0, q0, SBC_PROTO_FIXED_SCALE vrshr.s32 q1, q1, SBC_PROTO_FIXED_SCALE @@ -153,38 +153,38 @@ function ff_sbc_analyze_8_neon, export=1 vdup.i32 d1, d0[1] /* TODO: can be eliminated */ vdup.i32 d0, d0[0] /* TODO: can be eliminated */ - vld1.16 {d4, d5}, [r2, :128]! - vmull.s16 q6, d4, d0 - vld1.16 {d6, d7}, [r2, :128]! - vmull.s16 q7, d5, d0 - vmull.s16 q8, d6, d0 - vmull.s16 q9, d7, d0 + vld1.16 {d16, d17}, [r2, :128]! + vmull.s16 q12, d16, d0 + vld1.16 {d18, d19}, [r2, :128]! + vmull.s16 q13, d17, d0 + vmull.s16 q14, d18, d0 + vmull.s16 q15, d19, d0 - vld1.16 {d4, d5}, [r2, :128]! - vmlal.s16 q6, d4, d1 - vld1.16 {d6, d7}, [r2, :128]! - vmlal.s16 q7, d5, d1 - vmlal.s16 q8, d6, d1 - vmlal.s16 q9, d7, d1 + vld1.16 {d16, d17}, [r2, :128]! + vmlal.s16 q12, d16, d1 + vld1.16 {d18, d19}, [r2, :128]! + vmlal.s16 q13, d17, d1 + vmlal.s16 q14, d18, d1 + vmlal.s16 q15, d19, d1 - vld1.16 {d4, d5}, [r2, :128]! - vmlal.s16 q6, d4, d2 - vld1.16 {d6, d7}, [r2, :128]! - vmlal.s16 q7, d5, d2 - vmlal.s16 q8, d6, d2 - vmlal.s16 q9, d7, d2 + vld1.16 {d16, d17}, [r2, :128]! + vmlal.s16 q12, d16, d2 + vld1.16 {d18, d19}, [r2, :128]! + vmlal.s16 q13, d17, d2 + vmlal.s16 q14, d18, d2 + vmlal.s16 q15, d19, d2 - vld1.16 {d4, d5}, [r2, :128]! - vmlal.s16 q6, d4, d3 - vld1.16 {d6, d7}, [r2, :128]! - vmlal.s16 q7, d5, d3 - vmlal.s16 q8, d6, d3 - vmlal.s16 q9, d7, d3 + vld1.16 {d16, d17}, [r2, :128]! + vmlal.s16 q12, d16, d3 + vld1.16 {d18, d19}, [r2, :128]! + vmlal.s16 q13, d17, d3 + vmlal.s16 q14, d18, d3 + vmlal.s16 q15, d19, d3 - vpadd.s32 d0, d12, d13 /* TODO: can be eliminated */ - vpadd.s32 d1, d14, d15 /* TODO: can be eliminated */ - vpadd.s32 d2, d16, d17 /* TODO: can be eliminated */ - vpadd.s32 d3, d18, d19 /* TODO: can be eliminated */ + vpadd.s32 d0, d24, d25 /* TODO: can be eliminated */ + vpadd.s32 d1, d26, d27 /* TODO: can be eliminated */ + vpadd.s32 d2, d28, d29 /* TODO: can be eliminated */ + vpadd.s32 d3, d30, d31 /* TODO: can be eliminated */ vst1.32 {d0, d1, d2, d3}, [r1, :128] diff --git a/libavcodec/arm/vp9mc_neon.S b/libavcodec/arm/vp9mc_neon.S index bd8cda7c30..2ec729bb31 100644 --- a/libavcodec/arm/vp9mc_neon.S +++ b/libavcodec/arm/vp9mc_neon.S @@ -279,11 +279,13 @@ function \type\()_8tap_\size\()h_\idx1\idx2 sub r1, r1, r5 .endif @ size >= 16 loads two qwords and increments r2, - @ for size 4/8 it's enough with one qword and no - @ postincrement + @ size 4 loads 1 d word, increments r2 and loads 1 32-bit lane + @ for size 8 it's enough with one qword and no postincrement .if \size >= 16 sub r3, r3, r5 sub r3, r3, #8 +.elseif \size == 4 + sub r3, r3, #8 .endif @ Load the filter vector vld1.16 {q0}, [r12,:128] @@ -295,9 +297,14 @@ function \type\()_8tap_\size\()h_\idx1\idx2 .if \size >= 16 vld1.8 {d18, d19, d20}, [r2]! vld1.8 {d24, d25, d26}, [r7]! -.else +.elseif \size == 8 vld1.8 {q9}, [r2] vld1.8 {q12}, [r7] +.else @ size == 4 + vld1.8 {d18}, [r2]! + vld1.8 {d24}, [r7]! + vld1.32 {d19[0]}, [r2] + vld1.32 {d25[0]}, [r7] .endif vmovl.u8 q8, d18 vmovl.u8 q9, d19 diff --git a/libavcodec/ass_split.c b/libavcodec/ass_split.c index c2c388d9f0..189272bbd9 100644 --- a/libavcodec/ass_split.c +++ b/libavcodec/ass_split.c @@ -376,7 +376,7 @@ ASSSplitContext *ff_ass_split(const char *buf) ASSSplitContext *ctx = av_mallocz(sizeof(*ctx)); if (!ctx) return NULL; - if (buf && !memcmp(buf, "\xef\xbb\xbf", 3)) // Skip UTF-8 BOM header + if (buf && !strncmp(buf, "\xef\xbb\xbf", 3)) // Skip UTF-8 BOM header buf += 3; ctx->current_section = -1; if (ass_split(ctx, buf) < 0) { diff --git a/libavcodec/av1.h b/libavcodec/av1.h index 0f99ae4829..951a18ecb2 100644 --- a/libavcodec/av1.h +++ b/libavcodec/av1.h @@ -114,6 +114,13 @@ enum { AV1_WARP_MODEL_TRANSLATION = 1, AV1_WARP_MODEL_ROTZOOM = 2, AV1_WARP_MODEL_AFFINE = 3, + AV1_WARP_PARAM_REDUCE_BITS = 6, + + AV1_DIV_LUT_BITS = 8, + AV1_DIV_LUT_PREC_BITS = 14, + AV1_DIV_LUT_NUM = 257, + + AV1_MAX_LOOP_FILTER = 63, }; diff --git a/libavcodec/av1_metadata_bsf.c b/libavcodec/av1_metadata_bsf.c index 8cafe461d1..1fb85d88b7 100644 --- a/libavcodec/av1_metadata_bsf.c +++ b/libavcodec/av1_metadata_bsf.c @@ -28,6 +28,7 @@ typedef struct AV1MetadataContext { CBSBSFContext common; int td; + AV1RawOBU td_obu; int color_primaries; int transfer_characteristics; @@ -107,12 +108,11 @@ static int av1_metadata_update_fragment(AVBSFContext *bsf, AVPacket *pkt, CodedBitstreamFragment *frag) { AV1MetadataContext *ctx = bsf->priv_data; - AV1RawOBU td, *obu; int err, i; for (i = 0; i < frag->nb_units; i++) { if (frag->units[i].type == AV1_OBU_SEQUENCE_HEADER) { - obu = frag->units[i].content; + AV1RawOBU *obu = frag->units[i].content; err = av1_metadata_update_sequence_header(bsf, &obu->obu.sequence_header); if (err < 0) return err; @@ -120,16 +120,12 @@ static int av1_metadata_update_fragment(AVBSFContext *bsf, AVPacket *pkt, } // If a Temporal Delimiter is present, it must be the first OBU. - if (frag->units[0].type == AV1_OBU_TEMPORAL_DELIMITER) { + if (frag->nb_units && frag->units[0].type == AV1_OBU_TEMPORAL_DELIMITER) { if (ctx->td == BSF_ELEMENT_REMOVE) ff_cbs_delete_unit(frag, 0); } else if (pkt && ctx->td == BSF_ELEMENT_INSERT) { - td = (AV1RawOBU) { - .header.obu_type = AV1_OBU_TEMPORAL_DELIMITER, - }; - err = ff_cbs_insert_unit_content(frag, 0, AV1_OBU_TEMPORAL_DELIMITER, - &td, NULL); + &ctx->td_obu, NULL); if (err < 0) { av_log(bsf, AV_LOG_ERROR, "Failed to insert Temporal Delimiter.\n"); return err; @@ -155,6 +151,12 @@ static const CBSBSFType av1_metadata_type = { static int av1_metadata_init(AVBSFContext *bsf) { + AV1MetadataContext *ctx = bsf->priv_data; + + ctx->td_obu = (AV1RawOBU) { + .header.obu_type = AV1_OBU_TEMPORAL_DELIMITER, + }; + return ff_cbs_bsf_generic_init(bsf, &av1_metadata_type); } diff --git a/libavcodec/av1dec.c b/libavcodec/av1dec.c index a75d6744d3..d04bc55883 100644 --- a/libavcodec/av1dec.c +++ b/libavcodec/av1dec.c @@ -28,6 +28,34 @@ #include "internal.h" #include "profiles.h" +/**< same with Div_Lut defined in spec 7.11.3.7 */ +static const uint16_t div_lut[AV1_DIV_LUT_NUM] = { + 16384, 16320, 16257, 16194, 16132, 16070, 16009, 15948, 15888, 15828, 15768, + 15709, 15650, 15592, 15534, 15477, 15420, 15364, 15308, 15252, 15197, 15142, + 15087, 15033, 14980, 14926, 14873, 14821, 14769, 14717, 14665, 14614, 14564, + 14513, 14463, 14413, 14364, 14315, 14266, 14218, 14170, 14122, 14075, 14028, + 13981, 13935, 13888, 13843, 13797, 13752, 13707, 13662, 13618, 13574, 13530, + 13487, 13443, 13400, 13358, 13315, 13273, 13231, 13190, 13148, 13107, 13066, + 13026, 12985, 12945, 12906, 12866, 12827, 12788, 12749, 12710, 12672, 12633, + 12596, 12558, 12520, 12483, 12446, 12409, 12373, 12336, 12300, 12264, 12228, + 12193, 12157, 12122, 12087, 12053, 12018, 11984, 11950, 11916, 11882, 11848, + 11815, 11782, 11749, 11716, 11683, 11651, 11619, 11586, 11555, 11523, 11491, + 11460, 11429, 11398, 11367, 11336, 11305, 11275, 11245, 11215, 11185, 11155, + 11125, 11096, 11067, 11038, 11009, 10980, 10951, 10923, 10894, 10866, 10838, + 10810, 10782, 10755, 10727, 10700, 10673, 10645, 10618, 10592, 10565, 10538, + 10512, 10486, 10460, 10434, 10408, 10382, 10356, 10331, 10305, 10280, 10255, + 10230, 10205, 10180, 10156, 10131, 10107, 10082, 10058, 10034, 10010, 9986, + 9963, 9939, 9916, 9892, 9869, 9846, 9823, 9800, 9777, 9754, 9732, + 9709, 9687, 9664, 9642, 9620, 9598, 9576, 9554, 9533, 9511, 9489, + 9468, 9447, 9425, 9404, 9383, 9362, 9341, 9321, 9300, 9279, 9259, + 9239, 9218, 9198, 9178, 9158, 9138, 9118, 9098, 9079, 9059, 9039, + 9020, 9001, 8981, 8962, 8943, 8924, 8905, 8886, 8867, 8849, 8830, + 8812, 8793, 8775, 8756, 8738, 8720, 8702, 8684, 8666, 8648, 8630, + 8613, 8595, 8577, 8560, 8542, 8525, 8508, 8490, 8473, 8456, 8439, + 8422, 8405, 8389, 8372, 8355, 8339, 8322, 8306, 8289, 8273, 8257, + 8240, 8224, 8208, 8192 +}; + static uint32_t inverse_recenter(int r, uint32_t v) { if (v > 2 * r) @@ -97,6 +125,70 @@ static void read_global_param(AV1DecContext *s, int type, int ref, int idx) -mx, mx + 1, r) << prec_diff) + round; } +static uint64_t round_two(uint64_t x, uint16_t n) +{ + if (n == 0) + return x; + return ((x + ((uint64_t)1 << (n - 1))) >> n); +} + +static int64_t round_two_signed(int64_t x, uint16_t n) +{ + return ((x<0) ? -((int64_t)round_two(-x, n)) : (int64_t)round_two(x, n)); +} + +/** + * Resolve divisor process. + * see spec 7.11.3.7 + */ +static int16_t resolve_divisor(uint32_t d, uint16_t *shift) +{ + int32_t e, f; + + *shift = av_log2(d); + e = d - (1 << (*shift)); + if (*shift > AV1_DIV_LUT_BITS) + f = round_two(e, *shift - AV1_DIV_LUT_BITS); + else + f = e << (AV1_DIV_LUT_BITS - (*shift)); + + *shift += AV1_DIV_LUT_PREC_BITS; + + return div_lut[f]; +} + +/** + * check if global motion params is valid. + * see spec 7.11.3.6 + */ +static uint8_t get_shear_params_valid(AV1DecContext *s, int idx) +{ + int16_t alpha, beta, gamma, delta, divf, divs; + int64_t v, w; + int32_t *param = &s->cur_frame.gm_params[idx][0]; + if (param[2] <= 0) + return 0; + + alpha = av_clip_int16(param[2] - (1 << AV1_WARPEDMODEL_PREC_BITS)); + beta = av_clip_int16(param[3]); + divf = resolve_divisor(abs(param[2]), &divs); + v = (int64_t)param[4] * (1 << AV1_WARPEDMODEL_PREC_BITS); + w = (int64_t)param[3] * param[4]; + gamma = av_clip_int16((int)round_two_signed((v * divf), divs)); + delta = av_clip_int16(param[5] - (int)round_two_signed((w * divf), divs) - (1 << AV1_WARPEDMODEL_PREC_BITS)); + + alpha = round_two_signed(alpha, AV1_WARP_PARAM_REDUCE_BITS) << AV1_WARP_PARAM_REDUCE_BITS; + beta = round_two_signed(beta, AV1_WARP_PARAM_REDUCE_BITS) << AV1_WARP_PARAM_REDUCE_BITS; + gamma = round_two_signed(gamma, AV1_WARP_PARAM_REDUCE_BITS) << AV1_WARP_PARAM_REDUCE_BITS; + delta = round_two_signed(delta, AV1_WARP_PARAM_REDUCE_BITS) << AV1_WARP_PARAM_REDUCE_BITS; + + if ((4 * abs(alpha) + 7 * abs(beta)) >= (1 << AV1_WARPEDMODEL_PREC_BITS) || + (4 * abs(gamma) + 4 * abs(delta)) >= (1 << AV1_WARPEDMODEL_PREC_BITS)) + return 0; + + return 1; +} + /** * update gm type/params, since cbs already implemented part of this funcation, * so we don't need to full implement spec. @@ -144,6 +236,9 @@ static void global_motion_params(AV1DecContext *s) read_global_param(s, type, ref, 0); read_global_param(s, type, ref, 1); } + if (type <= AV1_WARP_MODEL_AFFINE) { + s->cur_frame.gm_invalid[ref] = !get_shear_params_valid(s, ref); + } } } @@ -509,6 +604,9 @@ static int av1_frame_ref(AVCodecContext *avctx, AV1Frame *dst, const AV1Frame *s dst->spatial_id = src->spatial_id; dst->temporal_id = src->temporal_id; + memcpy(dst->gm_invalid, + src->gm_invalid, + AV1_NUM_REF_FRAMES * sizeof(uint8_t)); memcpy(dst->gm_type, src->gm_type, AV1_NUM_REF_FRAMES * sizeof(uint8_t)); @@ -563,7 +661,7 @@ static int set_context_with_sequence(AVCodecContext *avctx, avctx->color_range = seq->color_config.color_range ? AVCOL_RANGE_JPEG : AVCOL_RANGE_MPEG; avctx->color_primaries = seq->color_config.color_primaries; - avctx->colorspace = seq->color_config.color_primaries; + avctx->colorspace = seq->color_config.matrix_coefficients; avctx->color_trc = seq->color_config.transfer_characteristics; switch (seq->color_config.chroma_sample_position) { diff --git a/libavcodec/av1dec.h b/libavcodec/av1dec.h index 248a68750f..4e140588b9 100644 --- a/libavcodec/av1dec.h +++ b/libavcodec/av1dec.h @@ -42,6 +42,7 @@ typedef struct AV1Frame { int temporal_id; int spatial_id; + uint8_t gm_invalid[AV1_NUM_REF_FRAMES]; uint8_t gm_type[AV1_NUM_REF_FRAMES]; int32_t gm_params[AV1_NUM_REF_FRAMES][6]; diff --git a/libavcodec/avcodec.c b/libavcodec/avcodec.c index 34ab793490..e572e9533d 100644 --- a/libavcodec/avcodec.c +++ b/libavcodec/avcodec.c @@ -318,6 +318,13 @@ int attribute_align_arg avcodec_open2(AVCodecContext *avctx, const AVCodec *code avctx->time_base.den = avctx->sample_rate; } + if (av_codec_is_encoder(avctx->codec)) + ret = ff_encode_preinit(avctx); + else + ret = ff_decode_preinit(avctx); + if (ret < 0) + goto free_and_end; + if (!HAVE_THREADS) av_log(avctx, AV_LOG_WARNING, "Warning: not compiled with thread support, using thread emulation\n"); @@ -339,13 +346,6 @@ int attribute_align_arg avcodec_open2(AVCodecContext *avctx, const AVCodec *code if (!HAVE_THREADS && !(codec->caps_internal & FF_CODEC_CAP_AUTO_THREADS)) avctx->thread_count = 1; - if (av_codec_is_encoder(avctx->codec)) - ret = ff_encode_preinit(avctx); - else - ret = ff_decode_preinit(avctx); - if (ret < 0) - goto free_and_end; - if ( avctx->codec->init && (!(avctx->active_thread_type&FF_THREAD_FRAME) || avci->frame_thread_encoder)) { ret = avctx->codec->init(avctx); @@ -644,6 +644,11 @@ FF_ENABLE_DEPRECATION_WARNINGS return 0; } +static const char *unknown_if_null(const char *str) +{ + return str ? str : "unknown"; +} + void avcodec_string(char *buf, int buf_size, AVCodecContext *enc, int encode) { const char *codec_type; @@ -653,6 +658,7 @@ void avcodec_string(char *buf, int buf_size, AVCodecContext *enc, int encode) int new_line = 0; AVRational display_aspect_ratio; const char *separator = enc->dump_separator ? (const char *)enc->dump_separator : ", "; + const char *str; if (!buf || buf_size <= 0) return; @@ -688,28 +694,27 @@ void avcodec_string(char *buf, int buf_size, AVCodecContext *enc, int encode) av_strlcat(buf, separator, buf_size); snprintf(buf + strlen(buf), buf_size - strlen(buf), - "%s", enc->pix_fmt == AV_PIX_FMT_NONE ? "none" : - av_get_pix_fmt_name(enc->pix_fmt)); + "%s", enc->pix_fmt == AV_PIX_FMT_NONE ? "none" : + unknown_if_null(av_get_pix_fmt_name(enc->pix_fmt))); if (enc->bits_per_raw_sample && enc->pix_fmt != AV_PIX_FMT_NONE && enc->bits_per_raw_sample < av_pix_fmt_desc_get(enc->pix_fmt)->comp[0].depth) av_strlcatf(detail, sizeof(detail), "%d bpc, ", enc->bits_per_raw_sample); - if (enc->color_range != AVCOL_RANGE_UNSPECIFIED) - av_strlcatf(detail, sizeof(detail), "%s, ", - av_color_range_name(enc->color_range)); + if (enc->color_range != AVCOL_RANGE_UNSPECIFIED && + (str = av_color_range_name(enc->color_range))) + av_strlcatf(detail, sizeof(detail), "%s, ", str); if (enc->colorspace != AVCOL_SPC_UNSPECIFIED || enc->color_primaries != AVCOL_PRI_UNSPECIFIED || enc->color_trc != AVCOL_TRC_UNSPECIFIED) { - if (enc->colorspace != (int)enc->color_primaries || - enc->colorspace != (int)enc->color_trc) { + const char *col = unknown_if_null(av_color_space_name(enc->colorspace)); + const char *pri = unknown_if_null(av_color_primaries_name(enc->color_primaries)); + const char *trc = unknown_if_null(av_color_transfer_name(enc->color_trc)); + if (strcmp(col, pri) || strcmp(col, trc)) { new_line = 1; av_strlcatf(detail, sizeof(detail), "%s/%s/%s, ", - av_color_space_name(enc->colorspace), - av_color_primaries_name(enc->color_primaries), - av_color_transfer_name(enc->color_trc)); + col, pri, trc); } else - av_strlcatf(detail, sizeof(detail), "%s, ", - av_get_colorspace_name(enc->colorspace)); + av_strlcatf(detail, sizeof(detail), "%s, ", col); } if (enc->field_order != AV_FIELD_UNKNOWN) { @@ -727,9 +732,9 @@ void avcodec_string(char *buf, int buf_size, AVCodecContext *enc, int encode) } if (av_log_get_level() >= AV_LOG_VERBOSE && - enc->chroma_sample_location != AVCHROMA_LOC_UNSPECIFIED) - av_strlcatf(detail, sizeof(detail), "%s, ", - av_chroma_location_name(enc->chroma_sample_location)); + enc->chroma_sample_location != AVCHROMA_LOC_UNSPECIFIED && + (str = av_chroma_location_name(enc->chroma_sample_location))) + av_strlcatf(detail, sizeof(detail), "%s, ", str); if (strlen(detail) > 1) { detail[strlen(detail) - 2] = 0; @@ -787,9 +792,10 @@ void avcodec_string(char *buf, int buf_size, AVCodecContext *enc, int encode) "%d Hz, ", enc->sample_rate); } av_get_channel_layout_string(buf + strlen(buf), buf_size - strlen(buf), enc->channels, enc->channel_layout); - if (enc->sample_fmt != AV_SAMPLE_FMT_NONE) { + if (enc->sample_fmt != AV_SAMPLE_FMT_NONE && + (str = av_get_sample_fmt_name(enc->sample_fmt))) { snprintf(buf + strlen(buf), buf_size - strlen(buf), - ", %s", av_get_sample_fmt_name(enc->sample_fmt)); + ", %s", str); } if ( enc->bits_per_raw_sample > 0 && enc->bits_per_raw_sample != av_get_bytes_per_sample(enc->sample_fmt) * 8) diff --git a/libavcodec/avcodec.h b/libavcodec/avcodec.h index 8a71c04230..5813897a09 100644 --- a/libavcodec/avcodec.h +++ b/libavcodec/avcodec.h @@ -1304,6 +1304,10 @@ typedef struct AVCodecContext { * this callback and filled with the extra buffers if there are more * buffers than buf[] can hold. extended_buf will be freed in * av_frame_unref(). + * Decoders will generally initialize the whole buffer before it is output + * but it can in rare error conditions happen that uninitialized data is passed + * through. \important The buffers returned by get_buffer* should thus not contain sensitive + * data. * * If AV_CODEC_CAP_DR1 is not set then get_buffer2() must call * avcodec_default_get_buffer2() instead of providing buffers allocated by diff --git a/libavcodec/bink.c b/libavcodec/bink.c index 5efd24e9c3..f04017d4b4 100644 --- a/libavcodec/bink.c +++ b/libavcodec/bink.c @@ -869,7 +869,7 @@ static int binkb_decode_plane(BinkContext *c, AVFrame *frame, GetBitContext *gb, binkb_init_bundles(c); ref_start = frame->data[plane_idx]; - ref_end = frame->data[plane_idx] + (bh * frame->linesize[plane_idx] + bw) * 8; + ref_end = frame->data[plane_idx] + ((bh - 1) * frame->linesize[plane_idx] + bw - 1) * 8; for (i = 0; i < 64; i++) coordmap[i] = (i & 7) + (i >> 3) * stride; @@ -925,7 +925,7 @@ static int binkb_decode_plane(BinkContext *c, AVFrame *frame, GetBitContext *gb, xoff = binkb_get_value(c, BINKB_SRC_X_OFF); yoff = binkb_get_value(c, BINKB_SRC_Y_OFF) + ybias; ref = dst + xoff + yoff * stride; - if (ref < ref_start || ref + 8*stride > ref_end) { + if (ref < ref_start || ref > ref_end) { av_log(c->avctx, AV_LOG_WARNING, "Reference block is out of bounds\n"); } else if (ref + 8*stride < dst || ref >= dst + 8*stride) { c->put_pixels_tab(dst, ref, stride, 8); @@ -941,7 +941,7 @@ static int binkb_decode_plane(BinkContext *c, AVFrame *frame, GetBitContext *gb, xoff = binkb_get_value(c, BINKB_SRC_X_OFF); yoff = binkb_get_value(c, BINKB_SRC_Y_OFF) + ybias; ref = dst + xoff + yoff * stride; - if (ref < ref_start || ref + 8 * stride > ref_end) { + if (ref < ref_start || ref > ref_end) { av_log(c->avctx, AV_LOG_WARNING, "Reference block is out of bounds\n"); } else if (ref + 8*stride < dst || ref >= dst + 8*stride) { c->put_pixels_tab(dst, ref, stride, 8); @@ -973,7 +973,7 @@ static int binkb_decode_plane(BinkContext *c, AVFrame *frame, GetBitContext *gb, xoff = binkb_get_value(c, BINKB_SRC_X_OFF); yoff = binkb_get_value(c, BINKB_SRC_Y_OFF) + ybias; ref = dst + xoff + yoff * stride; - if (ref < ref_start || ref + 8 * stride > ref_end) { + if (ref < ref_start || ref > ref_end) { av_log(c->avctx, AV_LOG_WARNING, "Reference block is out of bounds\n"); } else if (ref + 8*stride < dst || ref >= dst + 8*stride) { c->put_pixels_tab(dst, ref, stride, 8); @@ -1086,7 +1086,7 @@ static int bink_decode_plane(BinkContext *c, AVFrame *frame, GetBitContext *gb, for (bx = 0; bx < bw; bx++, dst += 8, prev += 8) { blk = get_value(c, BINK_SRC_BLOCK_TYPES); // 16x16 block type on odd line means part of the already decoded block, so skip it - if ((by & 1) && blk == SCALED_BLOCK) { + if (((by & 1) || (bx & 1)) && blk == SCALED_BLOCK) { bx++; dst += 8; prev += 8; diff --git a/libavcodec/binkaudio.c b/libavcodec/binkaudio.c index 381fc4cd15..df15a0fd5b 100644 --- a/libavcodec/binkaudio.c +++ b/libavcodec/binkaudio.c @@ -70,7 +70,7 @@ static av_cold int decode_init(AVCodecContext *avctx) BinkAudioContext *s = avctx->priv_data; int sample_rate = avctx->sample_rate; int sample_rate_half; - int i; + int i, ret; int frame_len_bits; /* determine frame length */ @@ -132,11 +132,13 @@ static av_cold int decode_init(AVCodecContext *avctx) s->first = 1; if (CONFIG_BINKAUDIO_RDFT_DECODER && avctx->codec->id == AV_CODEC_ID_BINKAUDIO_RDFT) - ff_rdft_init(&s->trans.rdft, frame_len_bits, DFT_C2R); + ret = ff_rdft_init(&s->trans.rdft, frame_len_bits, DFT_C2R); else if (CONFIG_BINKAUDIO_DCT_DECODER) - ff_dct_init(&s->trans.dct, frame_len_bits, DCT_III); + ret = ff_dct_init(&s->trans.dct, frame_len_bits, DCT_III); else av_assert0(0); + if (ret < 0) + return ret; s->pkt = av_packet_alloc(); if (!s->pkt) @@ -345,6 +347,7 @@ AVCodec ff_binkaudio_rdft_decoder = { .close = decode_end, .receive_frame = binkaudio_receive_frame, .capabilities = AV_CODEC_CAP_DELAY | AV_CODEC_CAP_DR1, + .caps_internal = FF_CODEC_CAP_INIT_CLEANUP, }; AVCodec ff_binkaudio_dct_decoder = { @@ -357,4 +360,5 @@ AVCodec ff_binkaudio_dct_decoder = { .close = decode_end, .receive_frame = binkaudio_receive_frame, .capabilities = AV_CODEC_CAP_DELAY | AV_CODEC_CAP_DR1, + .caps_internal = FF_CODEC_CAP_INIT_CLEANUP, }; diff --git a/libavcodec/bsf.c b/libavcodec/bsf.c index d71bc32584..157984bd9a 100644 --- a/libavcodec/bsf.c +++ b/libavcodec/bsf.c @@ -45,14 +45,15 @@ void av_bsf_free(AVBSFContext **pctx) return; ctx = *pctx; - if (ctx->filter->close) - ctx->filter->close(ctx); + if (ctx->internal) { + if (ctx->filter->close) + ctx->filter->close(ctx); + av_packet_free(&ctx->internal->buffer_pkt); + av_freep(&ctx->internal); + } if (ctx->filter->priv_class && ctx->priv_data) av_opt_free(ctx->priv_data); - if (ctx->internal) - av_packet_free(&ctx->internal->buffer_pkt); - av_freep(&ctx->internal); av_freep(&ctx->priv_data); avcodec_parameters_free(&ctx->par_in); @@ -110,20 +111,6 @@ int av_bsf_alloc(const AVBitStreamFilter *filter, AVBSFContext **pctx) ret = AVERROR(ENOMEM); goto fail; } - - bsfi = av_mallocz(sizeof(*bsfi)); - if (!bsfi) { - ret = AVERROR(ENOMEM); - goto fail; - } - ctx->internal = bsfi; - - bsfi->buffer_pkt = av_packet_alloc(); - if (!bsfi->buffer_pkt) { - ret = AVERROR(ENOMEM); - goto fail; - } - /* allocate priv data and init private options */ if (filter->priv_data_size) { ctx->priv_data = av_mallocz(filter->priv_data_size); @@ -136,6 +123,20 @@ int av_bsf_alloc(const AVBitStreamFilter *filter, AVBSFContext **pctx) av_opt_set_defaults(ctx->priv_data); } } + /* Allocate AVBSFInternal; must happen after priv_data has been allocated + * so that a filter->close needing priv_data is never called without. */ + bsfi = av_mallocz(sizeof(*bsfi)); + if (!bsfi) { + ret = AVERROR(ENOMEM); + goto fail; + } + ctx->internal = bsfi; + + bsfi->buffer_pkt = av_packet_alloc(); + if (!bsfi->buffer_pkt) { + ret = AVERROR(ENOMEM); + goto fail; + } *pctx = ctx; return 0; diff --git a/libavcodec/cbs_av1.c b/libavcodec/cbs_av1.c index 302e1f38f5..615132f961 100644 --- a/libavcodec/cbs_av1.c +++ b/libavcodec/cbs_av1.c @@ -37,7 +37,7 @@ static int cbs_av1_read_uvlc(CodedBitstreamContext *ctx, GetBitContext *gbc, position = get_bits_count(gbc); zeroes = 0; - while (1) { + while (zeroes < 32) { if (get_bits_left(gbc) < 1) { av_log(ctx->log_ctx, AV_LOG_ERROR, "Invalid uvlc code at " "%s: bitstream ended.\n", name); @@ -50,7 +50,18 @@ static int cbs_av1_read_uvlc(CodedBitstreamContext *ctx, GetBitContext *gbc, } if (zeroes >= 32) { - value = MAX_UINT_BITS(32); + // The spec allows at least thirty-two zero bits followed by a + // one to mean 2^32-1, with no constraint on the number of + // zeroes. The libaom reference decoder does not match this, + // instead reading thirty-two zeroes but not the following one + // to mean 2^32-1. These two interpretations are incompatible + // and other implementations may follow one or the other. + // Therefore we reject thirty-two zeroes because the intended + // behaviour is not clear. + av_log(ctx->log_ctx, AV_LOG_ERROR, "Thirty-two zero bits in " + "%s uvlc code: considered invalid due to conflicting " + "standard and reference decoder behaviour.\n", name); + return AVERROR_INVALIDDATA; } else { if (get_bits_left(gbc) < zeroes) { av_log(ctx->log_ctx, AV_LOG_ERROR, "Invalid uvlc code at " @@ -379,7 +390,7 @@ static int cbs_av1_write_increment(CodedBitstreamContext *ctx, PutBitContext *pb } if (len > 0) - put_bits(pbc, len, (1 << len) - 1 - (value != range_max)); + put_bits(pbc, len, (1U << len) - 1 - (value != range_max)); return 0; } diff --git a/libavcodec/cbs_av1_syntax_template.c b/libavcodec/cbs_av1_syntax_template.c index 6fe6e9a4f3..d98d3d42de 100644 --- a/libavcodec/cbs_av1_syntax_template.c +++ b/libavcodec/cbs_av1_syntax_template.c @@ -355,7 +355,7 @@ static int FUNC(set_frame_refs)(CodedBitstreamContext *ctx, RWContext *rw, AV1_REF_FRAME_ALTREF2, AV1_REF_FRAME_ALTREF }; int8_t ref_frame_idx[AV1_REFS_PER_FRAME], used_frame[AV1_NUM_REF_FRAMES]; - int8_t shifted_order_hints[AV1_NUM_REF_FRAMES]; + int16_t shifted_order_hints[AV1_NUM_REF_FRAMES]; int cur_frame_hint, latest_order_hint, earliest_order_hint, ref; int i, j; diff --git a/libavcodec/cbs_h265_syntax_template.c b/libavcodec/cbs_h265_syntax_template.c index 5d216aad36..921daea68c 100644 --- a/libavcodec/cbs_h265_syntax_template.c +++ b/libavcodec/cbs_h265_syntax_template.c @@ -728,7 +728,7 @@ static int FUNC(sps_scc_extension)(CodedBitstreamContext *ctx, RWContext *rw, flag(sps_palette_predictor_initializer_present_flag); if (current->sps_palette_predictor_initializer_present_flag) { - ue(sps_num_palette_predictor_initializer_minus1, 0, 128); + ue(sps_num_palette_predictor_initializer_minus1, 0, 127); for (comp = 0; comp < (current->chroma_format_idc ? 3 : 1); comp++) { int bit_depth = comp == 0 ? current->bit_depth_luma_minus8 + 8 : current->bit_depth_chroma_minus8 + 8; diff --git a/libavcodec/cbs_jpeg.c b/libavcodec/cbs_jpeg.c index 7d3e10fcc8..dc5a1cc4d5 100644 --- a/libavcodec/cbs_jpeg.c +++ b/libavcodec/cbs_jpeg.c @@ -166,13 +166,13 @@ static int cbs_jpeg_split_fragment(CodedBitstreamContext *ctx, } } else { i = start; - if (i + 2 > frag->data_size) { + if (i > frag->data_size - 2) { av_log(ctx->log_ctx, AV_LOG_ERROR, "Invalid JPEG image: " "truncated at %02x marker.\n", marker); return AVERROR_INVALIDDATA; } length = AV_RB16(frag->data + i); - if (i + length > frag->data_size) { + if (length > frag->data_size - i) { av_log(ctx->log_ctx, AV_LOG_ERROR, "Invalid JPEG image: " "truncated at %02x marker segment.\n", marker); return AVERROR_INVALIDDATA; diff --git a/libavcodec/cbs_vp9.c b/libavcodec/cbs_vp9.c index e0b8c02ac2..0de894de66 100644 --- a/libavcodec/cbs_vp9.c +++ b/libavcodec/cbs_vp9.c @@ -422,7 +422,7 @@ static int cbs_vp9_split_fragment(CodedBitstreamContext *ctx, superframe_header = frag->data[frag->data_size - 1]; if ((superframe_header & 0xe0) == 0xc0) { - VP9RawSuperframeIndex sfi; + VP9RawSuperframeIndex sfi = {0}; GetBitContext gbc; size_t index_size, pos; int i; diff --git a/libavcodec/cdgraphics.c b/libavcodec/cdgraphics.c index 263459d0f2..b452baa7d8 100644 --- a/libavcodec/cdgraphics.c +++ b/libavcodec/cdgraphics.c @@ -239,7 +239,7 @@ static void cdg_scroll(CDGraphicsContext *cc, uint8_t *data, for (y = FFMAX(0, vinc); y < FFMIN(CDG_FULL_HEIGHT + vinc, CDG_FULL_HEIGHT); y++) memcpy(out + FFMAX(0, hinc) + stride * y, in + FFMAX(0, hinc) - hinc + (y - vinc) * stride, - FFMIN(stride + hinc, stride)); + FFABS(stride) - FFABS(hinc)); if (vinc > 0) cdg_fill_wrapper(0, 0, out, diff --git a/libavcodec/celp_math.h b/libavcodec/celp_math.h index 18888a425d..99a0470719 100644 --- a/libavcodec/celp_math.h +++ b/libavcodec/celp_math.h @@ -78,7 +78,7 @@ int64_t ff_dot_product(const int16_t *a, const int16_t *b, int length); * * @return value << offset, if offset>=0; value >> -offset - otherwise */ -static inline int bidir_sal(int value, int offset) +static inline unsigned bidir_sal(unsigned value, int offset) { if(offset < 0) return value >> -offset; else return value << offset; diff --git a/libavcodec/cfhd.c b/libavcodec/cfhd.c index 1f2ee853c1..b61d1e7222 100644 --- a/libavcodec/cfhd.c +++ b/libavcodec/cfhd.c @@ -221,6 +221,7 @@ static void free_buffers(CFHDContext *s) int i, j; for (i = 0; i < FF_ARRAY_ELEMS(s->plane); i++) { + Plane *p = &s->plane[i]; av_freep(&s->plane[i].idwt_buf); av_freep(&s->plane[i].idwt_tmp); s->plane[i].idwt_size = 0; @@ -230,9 +231,16 @@ static void free_buffers(CFHDContext *s) for (j = 0; j < 10; j++) s->plane[i].l_h[j] = NULL; + + for (j = 0; j < DWT_LEVELS_3D; j++) + p->band[j][0].read_ok = + p->band[j][1].read_ok = + p->band[j][2].read_ok = + p->band[j][3].read_ok = 0; } s->a_height = 0; s->a_width = 0; + s->a_transform_type = INT_MIN; } static int alloc_buffers(AVCodecContext *avctx) @@ -356,6 +364,7 @@ static int alloc_buffers(AVCodecContext *avctx) } } + s->a_transform_type = s->transform_type; s->a_height = s->coded_height; s->a_width = s->coded_width; s->a_format = s->coded_format; @@ -655,7 +664,8 @@ static int cfhd_decode(AVCodecContext *avctx, void *data, int *got_frame, s->coded_height = s->a_height; if (s->a_width != s->coded_width || s->a_height != s->coded_height || - s->a_format != s->coded_format) { + s->a_format != s->coded_format || + s->transform_type != s->a_transform_type) { free_buffers(s); if ((ret = alloc_buffers(avctx)) < 0) { free_buffers(s); @@ -698,11 +708,18 @@ static int cfhd_decode(AVCodecContext *avctx, void *data, int *got_frame, coeff_data = s->plane[s->channel_num].subband[s->subband_num_actual]; /* Lowpass coefficients */ - if (tag == BitstreamMarker && data == 0xf0f && s->a_width && s->a_height) { - int lowpass_height = s->plane[s->channel_num].band[0][0].height; - int lowpass_width = s->plane[s->channel_num].band[0][0].width; - int lowpass_a_height = s->plane[s->channel_num].band[0][0].a_height; - int lowpass_a_width = s->plane[s->channel_num].band[0][0].a_width; + if (tag == BitstreamMarker && data == 0xf0f) { + int lowpass_height, lowpass_width, lowpass_a_height, lowpass_a_width; + + if (!s->a_width || !s->a_height) { + ret = AVERROR_INVALIDDATA; + goto end; + } + + lowpass_height = s->plane[s->channel_num].band[0][0].height; + lowpass_width = s->plane[s->channel_num].band[0][0].width; + lowpass_a_height = s->plane[s->channel_num].band[0][0].a_height; + lowpass_a_width = s->plane[s->channel_num].band[0][0].a_width; if (lowpass_width < 3 || lowpass_width > lowpass_a_width) { @@ -749,20 +766,30 @@ static int cfhd_decode(AVCodecContext *avctx, void *data, int *got_frame, lowpass_width * sizeof(*coeff_data)); } + s->plane[s->channel_num].band[0][0].read_ok = 1; + av_log(avctx, AV_LOG_DEBUG, "Lowpass coefficients %d\n", lowpass_width * lowpass_height); } - if ((tag == BandHeader || tag == BandSecondPass) && s->subband_num_actual != 255 && s->a_width && s->a_height) { - int highpass_height = s->plane[s->channel_num].band[s->level][s->subband_num].height; - int highpass_width = s->plane[s->channel_num].band[s->level][s->subband_num].width; - int highpass_a_width = s->plane[s->channel_num].band[s->level][s->subband_num].a_width; - int highpass_a_height = s->plane[s->channel_num].band[s->level][s->subband_num].a_height; - int highpass_stride = s->plane[s->channel_num].band[s->level][s->subband_num].stride; + av_assert0(s->subband_num_actual != 255); + if (tag == BandHeader || tag == BandSecondPass) { + int highpass_height, highpass_width, highpass_a_width, highpass_a_height, highpass_stride, a_expected; int expected; - int a_expected = highpass_a_height * highpass_a_width; int level, run, coeff; int count = 0, bytes; + if (!s->a_width || !s->a_height) { + ret = AVERROR_INVALIDDATA; + goto end; + } + + highpass_height = s->plane[s->channel_num].band[s->level][s->subband_num].height; + highpass_width = s->plane[s->channel_num].band[s->level][s->subband_num].width; + highpass_a_width = s->plane[s->channel_num].band[s->level][s->subband_num].a_width; + highpass_a_height = s->plane[s->channel_num].band[s->level][s->subband_num].a_height; + highpass_stride = s->plane[s->channel_num].band[s->level][s->subband_num].stride; + a_expected = highpass_a_height * highpass_a_width; + if (!got_buffer) { av_log(avctx, AV_LOG_ERROR, "No end of header tag found\n"); ret = AVERROR(EINVAL); @@ -811,7 +838,7 @@ static int cfhd_decode(AVCodecContext *avctx, void *data, int *got_frame, const uint16_t q = s->quantisation; for (i = 0; i < run; i++) { - *coeff_data |= coeff * 256; + *coeff_data |= coeff * 256U; *coeff_data++ *= q; } } else { @@ -842,7 +869,7 @@ static int cfhd_decode(AVCodecContext *avctx, void *data, int *got_frame, const uint16_t q = s->quantisation; for (i = 0; i < run; i++) { - *coeff_data |= coeff * 256; + *coeff_data |= coeff * 256U; *coeff_data++ *= q; } } else { @@ -873,6 +900,7 @@ static int cfhd_decode(AVCodecContext *avctx, void *data, int *got_frame, bytestream2_seek(&gb, bytes, SEEK_CUR); av_log(avctx, AV_LOG_DEBUG, "End subband coeffs %i extra %i\n", count, count - expected); + s->plane[s->channel_num].band[s->level][s->subband_num].read_ok = 1; finish: if (s->subband_num_actual != 255) s->codebook = 0; @@ -888,6 +916,7 @@ finish: ff_thread_finish_setup(avctx); if (!s->a_width || !s->a_height || s->a_format == AV_PIX_FMT_NONE || + s->a_transform_type == INT_MIN || s->coded_width || s->coded_height || s->coded_format != AV_PIX_FMT_NONE) { av_log(avctx, AV_LOG_ERROR, "Invalid dimensions\n"); ret = AVERROR(EINVAL); @@ -900,6 +929,22 @@ finish: goto end; } + for (plane = 0; plane < s->planes; plane++) { + int o, level; + + for (level = 0; level < (s->transform_type == 0 ? DWT_LEVELS : DWT_LEVELS_3D) ; level++) { + if (s->transform_type == 2) + if (level == 2 || level == 5) + continue; + for (o = !!level; o < 4 ; o++) { + if (!s->plane[plane].band[level][o].read_ok) { + ret = AVERROR_INVALIDDATA; + goto end; + } + } + } + } + if (s->transform_type == 0 && s->sample_type != 1) { for (plane = 0; plane < s->planes && !ret; plane++) { /* level 1 */ @@ -1381,12 +1426,14 @@ static int update_thread_context(AVCodecContext *dst, const AVCodecContext *src) if (pdst->plane[0].idwt_size != psrc->plane[0].idwt_size || pdst->a_format != psrc->a_format || pdst->a_width != psrc->a_width || - pdst->a_height != psrc->a_height) + pdst->a_height != psrc->a_height || + pdst->a_transform_type != psrc->a_transform_type) free_buffers(pdst); pdst->a_format = psrc->a_format; pdst->a_width = psrc->a_width; pdst->a_height = psrc->a_height; + pdst->a_transform_type = psrc->a_transform_type; pdst->transform_type = psrc->transform_type; pdst->progressive = psrc->progressive; pdst->planes = psrc->planes; @@ -1395,6 +1442,7 @@ static int update_thread_context(AVCodecContext *dst, const AVCodecContext *src) pdst->coded_width = pdst->a_width; pdst->coded_height = pdst->a_height; pdst->coded_format = pdst->a_format; + pdst->transform_type = pdst->a_transform_type; ret = alloc_buffers(dst); if (ret < 0) return ret; diff --git a/libavcodec/cfhd.h b/libavcodec/cfhd.h index 8ea91270cd..19e5c7cf03 100644 --- a/libavcodec/cfhd.h +++ b/libavcodec/cfhd.h @@ -114,6 +114,7 @@ typedef struct SubBand { int width; int a_height; int height; + int8_t read_ok; } SubBand; typedef struct Plane { @@ -165,6 +166,7 @@ typedef struct CFHDContext { int a_width; int a_height; int a_format; + int a_transform_type; int bpc; // bits per channel/component int channel_cnt; diff --git a/libavcodec/cfhdenc.c b/libavcodec/cfhdenc.c index 42bbf99c96..f73bb7154f 100644 --- a/libavcodec/cfhdenc.c +++ b/libavcodec/cfhdenc.c @@ -258,6 +258,11 @@ static av_cold int cfhd_encode_init(AVCodecContext *avctx) if (ret < 0) return ret; + if (avctx->height < 32) { + av_log(avctx, AV_LOG_ERROR, "Height must be >= 32.\n"); + return AVERROR_INVALIDDATA; + } + if (avctx->width & 15) { av_log(avctx, AV_LOG_ERROR, "Width must be multiple of 16.\n"); return AVERROR_INVALIDDATA; @@ -547,7 +552,7 @@ static int cfhd_encode_frame(AVCodecContext *avctx, AVPacket *pkt, width, height * 2); } - ret = ff_alloc_packet2(avctx, pkt, 64LL + s->planes * (2LL * avctx->width * avctx->height + 1000LL), 0); + ret = ff_alloc_packet2(avctx, pkt, 256LL + s->planes * (4LL * avctx->width * (avctx->height + 15) + 2048LL), 0); if (ret < 0) return ret; diff --git a/libavcodec/clearvideo.c b/libavcodec/clearvideo.c index 79ba88857c..a56e09069b 100644 --- a/libavcodec/clearvideo.c +++ b/libavcodec/clearvideo.c @@ -722,8 +722,8 @@ static av_cold int clv_decode_init(AVCodecContext *avctx) } c->tile_shift = av_log2(c->tile_size); - if (1U << c->tile_shift != c->tile_size) { - av_log(avctx, AV_LOG_ERROR, "Tile size: %d, is not power of 2.\n", c->tile_size); + if (1U << c->tile_shift != c->tile_size || c->tile_shift < 1 || c->tile_shift > 30) { + av_log(avctx, AV_LOG_ERROR, "Tile size: %d, is not power of 2 > 1 and < 2^31\n", c->tile_size); return AVERROR_INVALIDDATA; } diff --git a/libavcodec/cpia.c b/libavcodec/cpia.c index 5f12a99a83..435834d617 100644 --- a/libavcodec/cpia.c +++ b/libavcodec/cpia.c @@ -111,6 +111,7 @@ static int cpia_decode_frame(AVCodecContext *avctx, // Read line length, two byte little endian linelength = AV_RL16(src); src += 2; + src_size -= 2; if (src_size < linelength) { frame->decode_error_flags = FF_DECODE_ERROR_INVALID_BITSTREAM; diff --git a/libavcodec/cri.c b/libavcodec/cri.c index 0558d0c8dd..d2d80b6f1c 100644 --- a/libavcodec/cri.c +++ b/libavcodec/cri.c @@ -236,10 +236,14 @@ static int cri_decode_frame(AVCodecContext *avctx, void *data, s->data_size = length; goto skip; case 105: + if (length <= 0) + return AVERROR_INVALIDDATA; hflip = bytestream2_get_byte(gb) != 0; length--; goto skip; case 106: + if (length <= 0) + return AVERROR_INVALIDDATA; vflip = bytestream2_get_byte(gb) != 0; length--; goto skip; diff --git a/libavcodec/crystalhd.c b/libavcodec/crystalhd.c index 228803183a..886488602e 100644 --- a/libavcodec/crystalhd.c +++ b/libavcodec/crystalhd.c @@ -785,6 +785,7 @@ static int crystalhd_receive_frame(AVCodecContext *avctx, AVFrame *frame) .flush = flush, \ .bsfs = bsf_name, \ .capabilities = AV_CODEC_CAP_DELAY | AV_CODEC_CAP_AVOID_PROBING | AV_CODEC_CAP_HARDWARE, \ + .caps_internal = FF_CODEC_CAP_SETS_FRAME_PROPS, \ .pix_fmts = (const enum AVPixelFormat[]){AV_PIX_FMT_YUYV422, AV_PIX_FMT_NONE}, \ .wrapper_name = "crystalhd", \ }; diff --git a/libavcodec/cscd.c b/libavcodec/cscd.c index f5c93e9912..9230f9edf3 100644 --- a/libavcodec/cscd.c +++ b/libavcodec/cscd.c @@ -71,6 +71,9 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame, int buf_size = avpkt->size; CamStudioContext *c = avctx->priv_data; int ret; + int bpp = avctx->bits_per_coded_sample / 8; + int bugdelta = FFALIGN(avctx->width * bpp, 4) * avctx->height + - (avctx->width & ~3) * bpp * avctx->height; if (buf_size < 2) { av_log(avctx, AV_LOG_ERROR, "coded frame too small\n"); @@ -84,7 +87,7 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame, switch ((buf[0] >> 1) & 7) { case 0: { // lzo compression int outlen = c->decomp_size, inlen = buf_size - 2; - if (av_lzo1x_decode(c->decomp_buf, &outlen, &buf[2], &inlen) || outlen) { + if (av_lzo1x_decode(c->decomp_buf, &outlen, &buf[2], &inlen) || (outlen && outlen != bugdelta)) { av_log(avctx, AV_LOG_ERROR, "error during lzo decompression\n"); return AVERROR_INVALIDDATA; } @@ -93,7 +96,7 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame, case 1: { // zlib compression #if CONFIG_ZLIB unsigned long dlen = c->decomp_size; - if (uncompress(c->decomp_buf, &dlen, &buf[2], buf_size - 2) != Z_OK || dlen != c->decomp_size) { + if (uncompress(c->decomp_buf, &dlen, &buf[2], buf_size - 2) != Z_OK || (dlen != c->decomp_size && dlen != c->decomp_size - bugdelta)) { av_log(avctx, AV_LOG_ERROR, "error during zlib decompression\n"); return AVERROR_INVALIDDATA; } diff --git a/libavcodec/cuviddec.c b/libavcodec/cuviddec.c index ec57afdefe..5c135d1714 100644 --- a/libavcodec/cuviddec.c +++ b/libavcodec/cuviddec.c @@ -1150,6 +1150,7 @@ static const AVCodecHWConfigInternal *const cuvid_hw_configs[] = { .flush = cuvid_flush, \ .bsfs = bsf_name, \ .capabilities = AV_CODEC_CAP_DELAY | AV_CODEC_CAP_AVOID_PROBING | AV_CODEC_CAP_HARDWARE, \ + .caps_internal = FF_CODEC_CAP_SETS_FRAME_PROPS, \ .pix_fmts = (const enum AVPixelFormat[]){ AV_PIX_FMT_CUDA, \ AV_PIX_FMT_NV12, \ AV_PIX_FMT_P010, \ diff --git a/libavcodec/dcaenc.c b/libavcodec/dcaenc.c index a40d2e0ca0..87fb5f5457 100644 --- a/libavcodec/dcaenc.c +++ b/libavcodec/dcaenc.c @@ -925,10 +925,10 @@ static void fill_in_adpcm_bufer(DCAEncContext *c) * But there are no proper value in decoder history, so likely result will be no good. * Bitstream has "Predictor history flag switch", but this flag disables history for all subbands */ - samples[0] = c->adpcm_history[ch][band][0] << 7; - samples[1] = c->adpcm_history[ch][band][1] << 7; - samples[2] = c->adpcm_history[ch][band][2] << 7; - samples[3] = c->adpcm_history[ch][band][3] << 7; + samples[0] = c->adpcm_history[ch][band][0] * (1 << 7); + samples[1] = c->adpcm_history[ch][band][1] * (1 << 7); + samples[2] = c->adpcm_history[ch][band][2] * (1 << 7); + samples[3] = c->adpcm_history[ch][band][3] * (1 << 7); } } } diff --git a/libavcodec/decode.c b/libavcodec/decode.c index 5a00aeedae..936e5d63da 100644 --- a/libavcodec/decode.c +++ b/libavcodec/decode.c @@ -233,9 +233,11 @@ int ff_decode_get_packet(AVCodecContext *avctx, AVPacket *pkt) if (ret < 0) return ret; - ret = extract_packet_props(avctx->internal, pkt); - if (ret < 0) - goto finish; + if (!(avctx->codec->caps_internal & FF_CODEC_CAP_SETS_FRAME_PROPS)) { + ret = extract_packet_props(avctx->internal, pkt); + if (ret < 0) + goto finish; + } ret = apply_param_change(avctx, pkt); if (ret < 0) @@ -502,11 +504,13 @@ FF_ENABLE_DEPRECATION_WARNINGS pkt->data += consumed; pkt->size -= consumed; - avci->last_pkt_props->size -= consumed; // See extract_packet_props() comment. pkt->pts = AV_NOPTS_VALUE; pkt->dts = AV_NOPTS_VALUE; - avci->last_pkt_props->pts = AV_NOPTS_VALUE; - avci->last_pkt_props->dts = AV_NOPTS_VALUE; + if (!(avctx->codec->caps_internal & FF_CODEC_CAP_SETS_FRAME_PROPS)) { + avci->last_pkt_props->size -= consumed; // See extract_packet_props() comment. + avci->last_pkt_props->pts = AV_NOPTS_VALUE; + avci->last_pkt_props->dts = AV_NOPTS_VALUE; + } } if (got_frame) @@ -548,6 +552,11 @@ static int decode_receive_frame_internal(AVCodecContext *avctx, AVFrame *frame) if (ret == AVERROR_EOF) avci->draining_done = 1; + if (!(avctx->codec->caps_internal & FF_CODEC_CAP_SETS_FRAME_PROPS) && + IS_EMPTY(avci->last_pkt_props) && av_fifo_size(avci->pkt_props) >= sizeof(*avci->last_pkt_props)) + av_fifo_generic_read(avci->pkt_props, + avci->last_pkt_props, sizeof(*avci->last_pkt_props), NULL); + if (!ret) { frame->best_effort_timestamp = guess_correct_pts(avctx, frame->pts, @@ -1738,39 +1747,37 @@ int ff_decode_frame_props(AVCodecContext *avctx, AVFrame *frame) { AV_PKT_DATA_S12M_TIMECODE, AV_FRAME_DATA_S12M_TIMECODE }, }; - if (IS_EMPTY(pkt) && av_fifo_size(avctx->internal->pkt_props) >= sizeof(*pkt)) - av_fifo_generic_read(avctx->internal->pkt_props, - pkt, sizeof(*pkt), NULL); - - frame->pts = pkt->pts; + if (!(avctx->codec->caps_internal & FF_CODEC_CAP_SETS_FRAME_PROPS)) { + frame->pts = pkt->pts; #if FF_API_PKT_PTS FF_DISABLE_DEPRECATION_WARNINGS - frame->pkt_pts = pkt->pts; + frame->pkt_pts = pkt->pts; FF_ENABLE_DEPRECATION_WARNINGS #endif - frame->pkt_pos = pkt->pos; - frame->pkt_duration = pkt->duration; - frame->pkt_size = pkt->size; + frame->pkt_pos = pkt->pos; + frame->pkt_duration = pkt->duration; + frame->pkt_size = pkt->size; - for (int i = 0; i < FF_ARRAY_ELEMS(sd); i++) { - buffer_size_t size; - uint8_t *packet_sd = av_packet_get_side_data(pkt, sd[i].packet, &size); - if (packet_sd) { - AVFrameSideData *frame_sd = av_frame_new_side_data(frame, - sd[i].frame, - size); - if (!frame_sd) - return AVERROR(ENOMEM); + for (int i = 0; i < FF_ARRAY_ELEMS(sd); i++) { + buffer_size_t size; + uint8_t *packet_sd = av_packet_get_side_data(pkt, sd[i].packet, &size); + if (packet_sd) { + AVFrameSideData *frame_sd = av_frame_new_side_data(frame, + sd[i].frame, + size); + if (!frame_sd) + return AVERROR(ENOMEM); - memcpy(frame_sd->data, packet_sd, size); + memcpy(frame_sd->data, packet_sd, size); + } } - } - add_metadata_from_side_data(pkt, frame); + add_metadata_from_side_data(pkt, frame); - if (pkt->flags & AV_PKT_FLAG_DISCARD) { - frame->flags |= AV_FRAME_FLAG_DISCARD; - } else { - frame->flags = (frame->flags & ~AV_FRAME_FLAG_DISCARD); + if (pkt->flags & AV_PKT_FLAG_DISCARD) { + frame->flags |= AV_FRAME_FLAG_DISCARD; + } else { + frame->flags = (frame->flags & ~AV_FRAME_FLAG_DISCARD); + } } frame->reordered_opaque = avctx->reordered_opaque; diff --git a/libavcodec/diracdec.c b/libavcodec/diracdec.c index b9999cde01..cf7fc2c56c 100644 --- a/libavcodec/diracdec.c +++ b/libavcodec/diracdec.c @@ -1432,8 +1432,8 @@ static void global_mv(DiracContext *s, DiracBlock *block, int x, int y, int ref) int *c = s->globalmc[ref].perspective; int64_t m = (1<u.mv[ref][0] = (mx + (1<<(ez+ep))) >> (ez+ep); block->u.mv[ref][1] = (my + (1<<(ez+ep))) >> (ez+ep); diff --git a/libavcodec/dnxhddec.c b/libavcodec/dnxhddec.c index c78d55aee5..9b475a6979 100644 --- a/libavcodec/dnxhddec.c +++ b/libavcodec/dnxhddec.c @@ -112,6 +112,7 @@ static av_cold int dnxhd_decode_init(AVCodecContext *avctx) static int dnxhd_init_vlc(DNXHDContext *ctx, uint32_t cid, int bitdepth) { + int ret; if (cid != ctx->cid) { const CIDEntry *cid_table = ff_dnxhd_get_cid_table(cid); @@ -132,19 +133,26 @@ static int dnxhd_init_vlc(DNXHDContext *ctx, uint32_t cid, int bitdepth) ff_free_vlc(&ctx->dc_vlc); ff_free_vlc(&ctx->run_vlc); - init_vlc(&ctx->ac_vlc, DNXHD_VLC_BITS, 257, + if ((ret = init_vlc(&ctx->ac_vlc, DNXHD_VLC_BITS, 257, ctx->cid_table->ac_bits, 1, 1, - ctx->cid_table->ac_codes, 2, 2, 0); - init_vlc(&ctx->dc_vlc, DNXHD_DC_VLC_BITS, bitdepth > 8 ? 14 : 12, + ctx->cid_table->ac_codes, 2, 2, 0)) < 0) + goto out; + if ((ret = init_vlc(&ctx->dc_vlc, DNXHD_DC_VLC_BITS, bitdepth > 8 ? 14 : 12, ctx->cid_table->dc_bits, 1, 1, - ctx->cid_table->dc_codes, 1, 1, 0); - init_vlc(&ctx->run_vlc, DNXHD_VLC_BITS, 62, + ctx->cid_table->dc_codes, 1, 1, 0)) < 0) + goto out; + if ((ret = init_vlc(&ctx->run_vlc, DNXHD_VLC_BITS, 62, ctx->cid_table->run_bits, 1, 1, - ctx->cid_table->run_codes, 2, 2, 0); + ctx->cid_table->run_codes, 2, 2, 0)) < 0) + goto out; ctx->cid = cid; } - return 0; + ret = 0; +out: + if (ret < 0) + av_log(ctx->avctx, AV_LOG_ERROR, "init_vlc failed\n"); + return ret; } static int dnxhd_get_profile(int cid) diff --git a/libavcodec/dnxhdenc.c b/libavcodec/dnxhdenc.c index 2461c51727..31ae147433 100644 --- a/libavcodec/dnxhdenc.c +++ b/libavcodec/dnxhdenc.c @@ -1353,7 +1353,7 @@ static av_cold int dnxhd_encode_end(AVCodecContext *avctx) av_freep(&ctx->qmatrix_c16); av_freep(&ctx->qmatrix_l16); - if (avctx->active_thread_type == FF_THREAD_SLICE) { + if (ctx->thread[1]) { for (i = 1; i < avctx->thread_count; i++) av_freep(&ctx->thread[i]); } diff --git a/libavcodec/dpx.c b/libavcodec/dpx.c index 5372e3d586..915d94077e 100644 --- a/libavcodec/dpx.c +++ b/libavcodec/dpx.c @@ -242,6 +242,9 @@ static int decode_frame(AVCodecContext *avctx, return AVERROR_PATCHWELCOME; } + if (bits_per_color > 31) + return AVERROR_INVALIDDATA; + buf += 820; avctx->sample_aspect_ratio.num = read32(&buf, endian); avctx->sample_aspect_ratio.den = read32(&buf, endian); @@ -316,7 +319,7 @@ static int decode_frame(AVCodecContext *avctx, minCV = av_int2float(i); maxCV = av_int2float(j); if (bits_per_color >= 1 && - minCV == 0.0f && maxCV == ((1<color_range = AVCOL_RANGE_JPEG; } else if (bits_per_color >= 8 && minCV == (1 <<(bits_per_color - 4)) && diff --git a/libavcodec/dstdec.c b/libavcodec/dstdec.c index 84d19b91aa..819a037c69 100644 --- a/libavcodec/dstdec.c +++ b/libavcodec/dstdec.c @@ -215,7 +215,7 @@ static uint8_t prob_dst_x_bit(int c) return (ff_reverse[c & 127] >> 1) + 1; } -static void build_filter(int16_t table[DST_MAX_ELEMENTS][16][256], const Table *fsets) +static int build_filter(int16_t table[DST_MAX_ELEMENTS][16][256], const Table *fsets) { int i, j, k, l; @@ -226,14 +226,17 @@ static void build_filter(int16_t table[DST_MAX_ELEMENTS][16][256], const Table * int total = av_clip(length - j * 8, 0, 8); for (k = 0; k < 256; k++) { - int v = 0; + int64_t v = 0; for (l = 0; l < total; l++) v += (((k >> l) & 1) * 2 - 1) * fsets->coeff[i][j * 8 + l]; + if ((int16_t)v != v) + return AVERROR_INVALIDDATA; table[i][j][k] = v; } } } + return 0; } static int decode_frame(AVCodecContext *avctx, void *data, @@ -329,7 +332,9 @@ static int decode_frame(AVCodecContext *avctx, void *data, return AVERROR_INVALIDDATA; ac_init(ac, gb); - build_filter(s->filter, &s->fsets); + ret = build_filter(s->filter, &s->fsets); + if (ret < 0) + return ret; memset(s->status, 0xAA, sizeof(s->status)); memset(dsd, 0, frame->nb_samples * 4 * channels); diff --git a/libavcodec/dv_profile.c b/libavcodec/dv_profile.c index 66505c886b..0fc227dd04 100644 --- a/libavcodec/dv_profile.c +++ b/libavcodec/dv_profile.c @@ -261,24 +261,22 @@ const AVDVProfile* ff_dv_frame_profile(AVCodecContext* codec, const AVDVProfile const uint8_t *frame, unsigned buf_size) { #if CONFIG_DVPROFILE - int i, dsf, stype; + int i, dsf, stype, pal; if(buf_size < DV_PROFILE_BYTES) return NULL; dsf = (frame[3] & 0x80) >> 7; stype = frame[80 * 5 + 48 + 3] & 0x1f; + pal = !!(frame[80 * 5 + 48 + 3] & 0x20); /* 576i50 25Mbps 4:1:1 is a special case */ if ((dsf == 1 && stype == 0 && frame[4] & 0x07 /* the APT field */) || (stype == 31 && codec && codec->codec_tag==AV_RL32("SL25") && codec->coded_width==720 && codec->coded_height==576)) return &dv_profiles[2]; - if( stype == 0 - && codec - && (codec->codec_tag==AV_RL32("dvsd") || codec->codec_tag==AV_RL32("CDVC")) - && codec->coded_width ==720 - && codec->coded_height==576) + /* hack for trac issues #8333 and #2177, PAL DV files with dsf flag 0 - detect via pal flag and buf_size */ + if (dsf == 0 && pal == 1 && stype == dv_profiles[1].video_stype && buf_size == dv_profiles[1].frame_size) return &dv_profiles[1]; for (i = 0; i < FF_ARRAY_ELEMS(dv_profiles); i++) diff --git a/libavcodec/dxv.c b/libavcodec/dxv.c index 71d85208d8..69263cd30d 100644 --- a/libavcodec/dxv.c +++ b/libavcodec/dxv.c @@ -440,7 +440,7 @@ static int get_opcodes(GetByteContext *gb, uint32_t *table, uint8_t *dst, int op size_in_bits = bytestream2_get_le32(gb); endoffset = ((size_in_bits + 7) >> 3) - 4; - if (endoffset <= 0 || bytestream2_get_bytes_left(gb) < endoffset) + if ((int)endoffset <= 0 || bytestream2_get_bytes_left(gb) < endoffset) return AVERROR_INVALIDDATA; offset = endoffset; diff --git a/libavcodec/dxva2.c b/libavcodec/dxva2.c index b57ea21941..7569ca7400 100644 --- a/libavcodec/dxva2.c +++ b/libavcodec/dxva2.c @@ -117,7 +117,7 @@ static int dxva_get_decoder_configuration(AVCodecContext *avctx, for (i = 0; i < cfg_count; i++) { unsigned score; - UINT ConfigBitstreamRaw; + UINT ConfigBitstreamRaw = 0; GUID guidConfigBitstreamEncryption; #if CONFIG_D3D11VA @@ -268,7 +268,7 @@ static int dxva_get_decoder_guid(AVCodecContext *avctx, void *service, void *sur *decoder_guid = ff_GUID_NULL; for (i = 0; dxva_modes[i].guid; i++) { const dxva_mode *mode = &dxva_modes[i]; - int validate; + int validate = 0; if (!dxva_check_codec_compatibility(avctx, mode)) continue; @@ -800,7 +800,7 @@ int ff_dxva2_commit_buffer(AVCodecContext *avctx, unsigned type, const void *data, unsigned size, unsigned mb_count) { - void *dxva_data; + void *dxva_data = NULL; unsigned dxva_size; int result; HRESULT hr = 0; @@ -822,7 +822,7 @@ int ff_dxva2_commit_buffer(AVCodecContext *avctx, type, (unsigned)hr); return -1; } - if (size <= dxva_size) { + if (dxva_data && size <= dxva_size) { memcpy(dxva_data, data, size); #if CONFIG_D3D11VA @@ -900,7 +900,7 @@ int ff_dxva2_common_end_frame(AVCodecContext *avctx, AVFrame *frame, #endif DECODER_BUFFER_DESC *buffer = NULL, *buffer_slice = NULL; int result, runs = 0; - HRESULT hr; + HRESULT hr = -1; unsigned type; FFDXVASharedContext *sctx = DXVA_SHARED_CONTEXT(avctx); diff --git a/libavcodec/dxva2_av1.c b/libavcodec/dxva2_av1.c index aa14e473df..8a912bf6c1 100644 --- a/libavcodec/dxva2_av1.c +++ b/libavcodec/dxva2_av1.c @@ -73,7 +73,7 @@ static int fill_picture_parameters(const AVCodecContext *avctx, AVDXVAContext *c pp->max_height = seq->max_frame_height_minus_1 + 1; pp->CurrPicTextureIndex = ff_dxva2_get_surface_index(avctx, ctx, h->cur_frame.tf.f); - pp->superres_denom = frame_header->use_superres ? frame_header->coded_denom : AV1_SUPERRES_NUM; + pp->superres_denom = frame_header->use_superres ? frame_header->coded_denom + AV1_SUPERRES_DENOM_MIN : AV1_SUPERRES_NUM; pp->bitdepth = get_bit_depth_from_seq(seq); pp->seq_profile = seq->seq_profile; @@ -139,7 +139,7 @@ static int fill_picture_parameters(const AVCodecContext *avctx, AVDXVAContext *c pp->frame_refs[i].Index = ref_frame->buf[0] ? ref_idx : 0xFF; /* Global Motion */ - pp->frame_refs[i].wminvalid = (h->cur_frame.gm_type[AV1_REF_FRAME_LAST + i] == AV1_WARP_MODEL_IDENTITY); + pp->frame_refs[i].wminvalid = h->cur_frame.gm_invalid[AV1_REF_FRAME_LAST + i]; pp->frame_refs[i].wmtype = h->cur_frame.gm_type[AV1_REF_FRAME_LAST + i]; for (j = 0; j < 6; ++j) { pp->frame_refs[i].wmmat[j] = h->cur_frame.gm_params[AV1_REF_FRAME_LAST + i][j]; diff --git a/libavcodec/eac3dec.c b/libavcodec/eac3dec.c index 3a5c7989b9..33b9c88bb2 100644 --- a/libavcodec/eac3dec.c +++ b/libavcodec/eac3dec.c @@ -139,9 +139,11 @@ static void ff_eac3_apply_spectral_extension(AC3DecodeContext *s) // spx_noise_blend and spx_signal_blend are both FP.23 nscale *= 1.0 / (1<<23); sscale *= 1.0 / (1<<23); + if (nscale < -1.0) + nscale = -1.0; #endif for (i = 0; i < s->spx_band_sizes[bnd]; i++) { - float noise = nscale * (int32_t)av_lfg_get(&s->dith_state); + UINTFLOAT noise = (INTFLOAT)(nscale * (int32_t)av_lfg_get(&s->dith_state)); s->transform_coeffs[ch][bin] *= sscale; s->transform_coeffs[ch][bin++] += noise; } diff --git a/libavcodec/eacmv.c b/libavcodec/eacmv.c index b239acffda..39caa1de0d 100644 --- a/libavcodec/eacmv.c +++ b/libavcodec/eacmv.c @@ -195,12 +195,15 @@ static int cmv_decode_frame(AVCodecContext *avctx, if ((ret = av_image_check_size(s->width, s->height, 0, s->avctx)) < 0) return ret; + buf += EA_PREAMBLE_SIZE; + if (!(buf[0]&1) && buf_end - buf < s->width * s->height * (int64_t)(100 - s->avctx->discard_damaged_percentage) / 100) + return AVERROR_INVALIDDATA; + if ((ret = ff_get_buffer(avctx, frame, AV_GET_BUFFER_FLAG_REF)) < 0) return ret; memcpy(frame->data[1], s->palette, AVPALETTE_SIZE); - buf += EA_PREAMBLE_SIZE; if ((buf[0]&1)) { // subtype cmv_decode_inter(s, frame, buf+2, buf_end); frame->key_frame = 0; diff --git a/libavcodec/eatgq.c b/libavcodec/eatgq.c index 197ba6fc6e..85f40a5c54 100644 --- a/libavcodec/eatgq.c +++ b/libavcodec/eatgq.c @@ -61,7 +61,7 @@ static av_cold int tgq_decode_init(AVCodecContext *avctx) return 0; } -static void tgq_decode_block(TgqContext *s, int16_t block[64], GetBitContext *gb) +static int tgq_decode_block(TgqContext *s, int16_t block[64], GetBitContext *gb) { uint8_t *perm = s->scantable.permutated; int i, j, value; @@ -69,6 +69,8 @@ static void tgq_decode_block(TgqContext *s, int16_t block[64], GetBitContext *gb for (i = 1; i < 64;) { switch (show_bits(gb, 3)) { case 4: + if (i >= 63) + return AVERROR_INVALIDDATA; block[perm[i++]] = 0; case 0: block[perm[i++]] = 0; @@ -78,6 +80,8 @@ static void tgq_decode_block(TgqContext *s, int16_t block[64], GetBitContext *gb case 1: skip_bits(gb, 2); value = get_bits(gb, 6); + if (value > 64 - i) + return AVERROR_INVALIDDATA; for (j = 0; j < value; j++) block[perm[i++]] = 0; break; @@ -105,6 +109,7 @@ static void tgq_decode_block(TgqContext *s, int16_t block[64], GetBitContext *gb } } block[0] += 128 << 4; + return 0; } static void tgq_idct_put_mb(TgqContext *s, int16_t (*block)[64], AVFrame *frame, @@ -164,8 +169,11 @@ static int tgq_decode_mb(TgqContext *s, AVFrame *frame, int mb_y, int mb_x) if (ret < 0) return ret; - for (i = 0; i < 6; i++) - tgq_decode_block(s, s->block[i], &gb); + for (i = 0; i < 6; i++) { + int ret = tgq_decode_block(s, s->block[i], &gb); + if (ret < 0) + return ret; + } tgq_idct_put_mb(s, s->block, frame, mb_x, mb_y); bytestream2_skip(&s->gb, mode); } else { diff --git a/libavcodec/encode.c b/libavcodec/encode.c index a93bb3ccf7..89df5235da 100644 --- a/libavcodec/encode.c +++ b/libavcodec/encode.c @@ -565,7 +565,7 @@ FF_ENABLE_DEPRECATION_WARNINGS if (avctx->pix_fmt == avctx->codec->pix_fmts[i]) break; if (avctx->codec->pix_fmts[i] == AV_PIX_FMT_NONE - && !((avctx->codec_id == AV_CODEC_ID_MJPEG || avctx->codec_id == AV_CODEC_ID_LJPEG) + && !(avctx->codec_id == AV_CODEC_ID_MJPEG && avctx->strict_std_compliance <= FF_COMPLIANCE_UNOFFICIAL)) { char buf[128]; snprintf(buf, sizeof(buf), "%d", avctx->pix_fmt); diff --git a/libavcodec/escape124.c b/libavcodec/escape124.c index 94c2a961e6..388fbaef47 100644 --- a/libavcodec/escape124.c +++ b/libavcodec/escape124.c @@ -88,11 +88,6 @@ static CodeBook unpack_codebook(GetBitContext* gb, unsigned depth, unsigned i, j; CodeBook cb = { 0 }; - if (size >= INT_MAX / 34 || get_bits_left(gb) < size * 34) - return cb; - - if (size >= INT_MAX / sizeof(MacroBlock)) - return cb; cb.blocks = av_malloc(size ? size * sizeof(MacroBlock) : 1); if (!cb.blocks) return cb; @@ -162,7 +157,7 @@ static MacroBlock decode_macroblock(Escape124Context* s, GetBitContext* gb, // This condition can occur with invalid bitstreams and // *codebook_index == 2 - if (block_index >= s->codebooks[*codebook_index].size) + if (block_index >= s->codebooks[*codebook_index].size || !s->codebooks[*codebook_index].blocks) return (MacroBlock) { { 0 } }; return s->codebooks[*codebook_index].blocks[block_index]; @@ -226,7 +221,7 @@ static int escape124_decode_frame(AVCodecContext *avctx, // represent a lower bound of the space needed for skipped superblocks. Non // skipped SBs need more space. if (get_bits_left(&gb) < 64 + s->num_superblocks * 23LL / 4320) - return -1; + return AVERROR_INVALIDDATA; frame_flags = get_bits_long(&gb, 32); frame_size = get_bits_long(&gb, 32); @@ -243,7 +238,7 @@ static int escape124_decode_frame(AVCodecContext *avctx, if ((ret = av_frame_ref(frame, s->frame)) < 0) return ret; - return frame_size; + return 0; } for (i = 0; i < 3; i++) { @@ -277,9 +272,14 @@ static int escape124_decode_frame(AVCodecContext *avctx, } av_freep(&s->codebooks[i].blocks); + if (cb_size >= INT_MAX / 34 || get_bits_left(&gb) < (int)cb_size * 34) + return AVERROR_INVALIDDATA; + + if (cb_size >= INT_MAX / sizeof(MacroBlock)) + return AVERROR_INVALIDDATA; s->codebooks[i] = unpack_codebook(&gb, cb_depth, cb_size); if (!s->codebooks[i].blocks) - return -1; + return AVERROR(ENOMEM); } } @@ -372,7 +372,7 @@ static int escape124_decode_frame(AVCodecContext *avctx, *got_frame = 1; - return frame_size; + return 0; } diff --git a/libavcodec/exr.c b/libavcodec/exr.c index 279cfe9412..e3585e85fa 100644 --- a/libavcodec/exr.c +++ b/libavcodec/exr.c @@ -333,7 +333,10 @@ static int huf_unpack_enc_table(GetByteContext *gb, return ret; for (; im <= iM; im++) { - uint64_t l = freq[im] = get_bits(&gbit, 6); + int l; + if (get_bits_left(&gbit) < 6) + return AVERROR_INVALIDDATA; + l = freq[im] = get_bits(&gbit, 6); if (l == LONG_ZEROCODE_RUN) { int zerun = get_bits(&gbit, 8) + SHORTEST_LONG_RUN; @@ -418,11 +421,16 @@ static int huf_decode(VLC *vlc, GetByteContext *gb, int nbits, int run_sym, init_get_bits(&gbit, gb->buffer, nbits); while (get_bits_left(&gbit) > 0 && oe < no) { - uint16_t x = get_vlc2(&gbit, vlc->table, 12, 2); + uint16_t x = get_vlc2(&gbit, vlc->table, 12, 3); if (x == run_sym) { int run = get_bits(&gbit, 8); - uint16_t fill = out[oe - 1]; + uint16_t fill; + + if (oe == 0 || oe + run > no) + return AVERROR_INVALIDDATA; + + fill = out[oe - 1]; while (run-- > 0) out[oe++] = fill; @@ -1009,7 +1017,9 @@ static int dwa_uncompress(EXRContext *s, const uint8_t *src, int compressed_size dc_count = AV_RL64(src + 72); ac_compression = AV_RL64(src + 80); - if (compressed_size < 88LL + lo_size + ac_size + dc_size + rle_csize) + if ( compressed_size < (uint64_t)(lo_size | ac_size | dc_size | rle_csize) || compressed_size < 88LL + lo_size + ac_size + dc_size + rle_csize + || ac_count > (uint64_t)INT_MAX/2 + ) return AVERROR_INVALIDDATA; bytestream2_init(&gb, src + 88, compressed_size - 88); @@ -1026,12 +1036,14 @@ static int dwa_uncompress(EXRContext *s, const uint8_t *src, int compressed_size } if (ac_size > 0) { - unsigned long dest_len = ac_count * 2LL; + unsigned long dest_len; GetByteContext agb = gb; if (ac_count > 3LL * td->xsize * s->scan_lines_per_block) return AVERROR_INVALIDDATA; + dest_len = ac_count * 2LL; + av_fast_padded_malloc(&td->ac_data, &td->ac_size, dest_len); if (!td->ac_data) return AVERROR(ENOMEM); @@ -1054,13 +1066,15 @@ static int dwa_uncompress(EXRContext *s, const uint8_t *src, int compressed_size bytestream2_skip(&gb, ac_size); } - if (dc_size > 0) { - unsigned long dest_len = dc_count * 2LL; + { + unsigned long dest_len; GetByteContext agb = gb; - if (dc_count > (6LL * td->xsize * td->ysize + 63) / 64) + if (dc_count != dc_w * dc_h * 3) return AVERROR_INVALIDDATA; + dest_len = dc_count * 2LL; + av_fast_padded_malloc(&td->dc_data, &td->dc_size, FFALIGN(dest_len, 64) * 2); if (!td->dc_data) return AVERROR(ENOMEM); @@ -1229,7 +1243,8 @@ static int decode_block(AVCodecContext *avctx, void *tdata, td->ysize = FFMIN(s->tile_attr.ySize, s->ydelta - tile_y * s->tile_attr.ySize); td->xsize = FFMIN(s->tile_attr.xSize, s->xdelta - tile_x * s->tile_attr.xSize); - if (td->xsize * (uint64_t)s->current_channel_offset > INT_MAX) + if (td->xsize * (uint64_t)s->current_channel_offset > INT_MAX || + av_image_check_size2(td->xsize, td->ysize, s->avctx->max_pixels, AV_PIX_FMT_NONE, 0, s->avctx) < 0) return AVERROR_INVALIDDATA; td->channel_line_size = td->xsize * s->current_channel_offset;/* uncompress size of one line */ @@ -1253,7 +1268,8 @@ static int decode_block(AVCodecContext *avctx, void *tdata, td->ysize = FFMIN(s->scan_lines_per_block, s->ymax - line + 1); /* s->ydelta - line ?? */ td->xsize = s->xdelta; - if (td->xsize * (uint64_t)s->current_channel_offset > INT_MAX) + if (td->xsize * (uint64_t)s->current_channel_offset > INT_MAX || + av_image_check_size2(td->xsize, td->ysize, s->avctx->max_pixels, AV_PIX_FMT_NONE, 0, s->avctx) < 0) return AVERROR_INVALIDDATA; td->channel_line_size = td->xsize * s->current_channel_offset;/* uncompress size of one line */ @@ -1790,6 +1806,7 @@ static int decode_header(EXRContext *s, AVFrame *frame) ymax = bytestream2_get_le32(gb); if (xmin > xmax || ymin > ymax || + ymax == INT_MAX || xmax == INT_MAX || (unsigned)xmax - xmin >= INT_MAX || (unsigned)ymax - ymin >= INT_MAX) { ret = AVERROR_INVALIDDATA; @@ -1817,8 +1834,8 @@ static int decode_header(EXRContext *s, AVFrame *frame) dx = bytestream2_get_le32(gb); dy = bytestream2_get_le32(gb); - s->w = dx - sx + 1; - s->h = dy - sy + 1; + s->w = (unsigned)dx - sx + 1; + s->h = (unsigned)dy - sy + 1; continue; } else if ((var_size = check_header_variable(s, "lineOrder", @@ -1925,18 +1942,27 @@ static int decode_header(EXRContext *s, AVFrame *frame) bytestream2_get_buffer(gb, key, FFMIN(sizeof(key) - 1, var_size)); if (strncmp("scanlineimage", key, var_size) && - strncmp("tiledimage", key, var_size)) - return AVERROR_PATCHWELCOME; + strncmp("tiledimage", key, var_size)) { + ret = AVERROR_PATCHWELCOME; + goto fail; + } continue; } else if ((var_size = check_header_variable(s, "preview", "preview", 16)) >= 0) { uint32_t pw = bytestream2_get_le32(gb); uint32_t ph = bytestream2_get_le32(gb); - int64_t psize = 4LL * pw * ph; + uint64_t psize = pw * (uint64_t)ph; + if (psize > INT64_MAX / 4) { + ret = AVERROR_INVALIDDATA; + goto fail; + } + psize *= 4; - if (psize >= bytestream2_get_bytes_left(gb)) - return AVERROR_INVALIDDATA; + if ((int64_t)psize >= bytestream2_get_bytes_left(gb)) { + ret = AVERROR_INVALIDDATA; + goto fail; + } bytestream2_skip(gb, psize); diff --git a/libavcodec/faxcompr.c b/libavcodec/faxcompr.c index 3dd64cf730..b283831dae 100644 --- a/libavcodec/faxcompr.c +++ b/libavcodec/faxcompr.c @@ -144,6 +144,8 @@ static int decode_uncompressed(AVCodecContext *avctx, GetBitContext *gb, return AVERROR_INVALIDDATA; } cwi = 10 - av_log2(cwi); + if (get_bits_left(gb) < cwi + 1) + return AVERROR_INVALIDDATA; skip_bits(gb, cwi + 1); if (cwi > 5) { newmode = get_bits1(gb); @@ -209,6 +211,8 @@ static int decode_group3_1d_line(AVCodecContext *avctx, GetBitContext *gb, unsigned int run = 0; unsigned int t; for (;;) { + if (get_bits_left(gb) <= 0) + return AVERROR_INVALIDDATA; t = get_vlc2(gb, ccitt_vlc[mode].table, 9, 2); run += t; if (t < 64) { @@ -227,7 +231,7 @@ static int decode_group3_1d_line(AVCodecContext *avctx, GetBitContext *gb, run = 0; mode = !mode; } else if ((int)t == -1) { - if (show_bits(gb, 12) == 15) { + if (get_bits_left(gb) > 12 && show_bits(gb, 12) == 15) { int ret; skip_bits(gb, 12); ret = decode_uncompressed(avctx, gb, &pix_left, &runs, runend, &mode); @@ -254,7 +258,10 @@ static int decode_group3_2d_line(AVCodecContext *avctx, GetBitContext *gb, unsigned int offs = 0, run = 0; while (offs < width) { - int cmode = get_vlc2(gb, ccitt_group3_2d_vlc.table, 9, 1); + int cmode; + if (get_bits_left(gb) <= 0) + return AVERROR_INVALIDDATA; + cmode = get_vlc2(gb, ccitt_group3_2d_vlc.table, 9, 1); if (cmode == -1) { av_log(avctx, AV_LOG_ERROR, "Incorrect mode VLC\n"); return AVERROR_INVALIDDATA; @@ -276,6 +283,8 @@ static int decode_group3_2d_line(AVCodecContext *avctx, GetBitContext *gb, for (k = 0; k < 2; k++) { run = 0; for (;;) { + if (get_bits_left(gb) <= 0) + return AVERROR_INVALIDDATA; t = get_vlc2(gb, ccitt_vlc[mode].table, 9, 2); if (t == -1) { av_log(avctx, AV_LOG_ERROR, "Incorrect code\n"); @@ -299,7 +308,10 @@ static int decode_group3_2d_line(AVCodecContext *avctx, GetBitContext *gb, mode = !mode; } } else if (cmode == 9 || cmode == 10) { - int xxx = get_bits(gb, 3); + int xxx; + if (get_bits_left(gb) < 3) + return AVERROR_INVALIDDATA; + xxx = get_bits(gb, 3); if (cmode == 9 && xxx == 7) { int ret; int pix_left = width - offs; diff --git a/libavcodec/ffv1.c b/libavcodec/ffv1.c index 1c580c3b49..56a8fb847e 100644 --- a/libavcodec/ffv1.c +++ b/libavcodec/ffv1.c @@ -113,6 +113,13 @@ av_cold int ff_ffv1_init_slices_state(FFV1Context *f) return 0; } +int ff_need_new_slices(int width, int num_h_slices, int chroma_shift) { + int mpw = 1<num_h_slices * f->num_v_slices; diff --git a/libavcodec/ffv1.h b/libavcodec/ffv1.h index 147fe7ae16..cddf170a6b 100644 --- a/libavcodec/ffv1.h +++ b/libavcodec/ffv1.h @@ -146,6 +146,7 @@ int ff_ffv1_init_slice_contexts(FFV1Context *f); int ff_ffv1_allocate_initial_states(FFV1Context *f); void ff_ffv1_clear_slice_state(FFV1Context *f, FFV1Context *fs); int ff_ffv1_close(AVCodecContext *avctx); +int ff_need_new_slices(int width, int num_h_slices, int chroma_shift); static av_always_inline int fold(int diff, int bits) { diff --git a/libavcodec/ffv1dec.c b/libavcodec/ffv1dec.c index 8516fef5d7..0be1c94bb2 100644 --- a/libavcodec/ffv1dec.c +++ b/libavcodec/ffv1dec.c @@ -166,24 +166,34 @@ static int decode_slice_header(FFV1Context *f, FFV1Context *fs) RangeCoder *c = &fs->c; uint8_t state[CONTEXT_SIZE]; unsigned ps, i, context_count; + int sx, sy, sw, sh; + memset(state, 128, sizeof(state)); + sx = get_symbol(c, state, 0); + sy = get_symbol(c, state, 0); + sw = get_symbol(c, state, 0) + 1U; + sh = get_symbol(c, state, 0) + 1U; av_assert0(f->version > 2); - fs->slice_x = get_symbol(c, state, 0) * f->width ; - fs->slice_y = get_symbol(c, state, 0) * f->height; - fs->slice_width = (get_symbol(c, state, 0) + 1) * f->width + fs->slice_x; - fs->slice_height = (get_symbol(c, state, 0) + 1) * f->height + fs->slice_y; - fs->slice_x /= f->num_h_slices; - fs->slice_y /= f->num_v_slices; - fs->slice_width = fs->slice_width /f->num_h_slices - fs->slice_x; - fs->slice_height = fs->slice_height/f->num_v_slices - fs->slice_y; - if ((unsigned)fs->slice_width > f->width || (unsigned)fs->slice_height > f->height) - return -1; - if ( (unsigned)fs->slice_x + (uint64_t)fs->slice_width > f->width - || (unsigned)fs->slice_y + (uint64_t)fs->slice_height > f->height) - return -1; + if (sx < 0 || sy < 0 || sw <= 0 || sh <= 0) + return AVERROR_INVALIDDATA; + if (sx > f->num_h_slices - sw || sy > f->num_v_slices - sh) + return AVERROR_INVALIDDATA; + + fs->slice_x = sx * (int64_t)f->width / f->num_h_slices; + fs->slice_y = sy * (int64_t)f->height / f->num_v_slices; + fs->slice_width = (sx + sw) * (int64_t)f->width / f->num_h_slices - fs->slice_x; + fs->slice_height = (sy + sh) * (int64_t)f->height / f->num_v_slices - fs->slice_y; + + av_assert0((unsigned)fs->slice_width <= f->width && + (unsigned)fs->slice_height <= f->height); + av_assert0 ( (unsigned)fs->slice_x + (uint64_t)fs->slice_width <= f->width + && (unsigned)fs->slice_y + (uint64_t)fs->slice_height <= f->height); + + if (fs->ac == AC_GOLOMB_RICE && fs->slice_width >= (1<<23)) + return AVERROR_INVALIDDATA; for (i = 0; i < f->plane_count; i++) { PlaneContext * const p = &fs->plane[i]; @@ -298,8 +308,11 @@ static int decode_slice(AVCodecContext *c, void *arg) } if ((ret = ff_ffv1_init_slice_state(f, fs)) < 0) return ret; - if (f->cur->key_frame || fs->slice_reset_contexts) + if (f->cur->key_frame || fs->slice_reset_contexts) { ff_ffv1_clear_slice_state(f, fs); + } else if (fs->slice_damaged) { + return AVERROR_INVALIDDATA; + } width = fs->slice_width; height = fs->slice_height; @@ -348,7 +361,7 @@ static int decode_slice(AVCodecContext *c, void *arg) if (fs->ac != AC_GOLOMB_RICE && f->version > 2) { int v; get_rac(&fs->c, (uint8_t[]) { 129 }); - v = fs->c.bytestream_end - fs->c.bytestream - 2 - 5*f->ec; + v = fs->c.bytestream_end - fs->c.bytestream - 2 - 5*!!f->ec; if (v) { av_log(f->avctx, AV_LOG_ERROR, "bytestream end mismatching by %d\n", v); fs->slice_damaged = 1; @@ -462,6 +475,11 @@ static int read_extra_header(FFV1Context *f) return AVERROR_INVALIDDATA; } + if (f->num_h_slices > MAX_SLICES / f->num_v_slices) { + av_log(f->avctx, AV_LOG_ERROR, "slice count unsupported\n"); + return AVERROR_PATCHWELCOME; + } + f->quant_table_count = get_symbol(c, state, 0); 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); @@ -764,21 +782,25 @@ static int read_header(FFV1Context *f) fs->slice_damaged = 0; if (f->version == 2) { - fs->slice_x = get_symbol(c, state, 0) * f->width ; - fs->slice_y = get_symbol(c, state, 0) * f->height; - fs->slice_width = (get_symbol(c, state, 0) + 1) * f->width + fs->slice_x; - fs->slice_height = (get_symbol(c, state, 0) + 1) * f->height + fs->slice_y; + int sx = get_symbol(c, state, 0); + int sy = get_symbol(c, state, 0); + int sw = get_symbol(c, state, 0) + 1U; + int sh = get_symbol(c, state, 0) + 1U; - fs->slice_x /= f->num_h_slices; - fs->slice_y /= f->num_v_slices; - fs->slice_width = fs->slice_width / f->num_h_slices - fs->slice_x; - fs->slice_height = fs->slice_height / f->num_v_slices - fs->slice_y; - if ((unsigned)fs->slice_width > f->width || - (unsigned)fs->slice_height > f->height) + if (sx < 0 || sy < 0 || sw <= 0 || sh <= 0) return AVERROR_INVALIDDATA; - if ( (unsigned)fs->slice_x + (uint64_t)fs->slice_width > f->width - || (unsigned)fs->slice_y + (uint64_t)fs->slice_height > f->height) + if (sx > f->num_h_slices - sw || sy > f->num_v_slices - sh) return AVERROR_INVALIDDATA; + + fs->slice_x = sx * (int64_t)f->width / f->num_h_slices; + fs->slice_y = sy * (int64_t)f->height / f->num_v_slices; + fs->slice_width = (sx + sw) * (int64_t)f->width / f->num_h_slices - fs->slice_x; + fs->slice_height = (sy + sh) * (int64_t)f->height / f->num_v_slices - fs->slice_y; + + av_assert0((unsigned)fs->slice_width <= f->width && + (unsigned)fs->slice_height <= f->height); + av_assert0 ( (unsigned)fs->slice_x + (uint64_t)fs->slice_width <= f->width + && (unsigned)fs->slice_y + (uint64_t)fs->slice_height <= f->height); } for (i = 0; i < f->plane_count; i++) { diff --git a/libavcodec/ffv1dec_template.c b/libavcodec/ffv1dec_template.c index 0b1d176ba1..9b1d65e825 100644 --- a/libavcodec/ffv1dec_template.c +++ b/libavcodec/ffv1dec_template.c @@ -93,11 +93,11 @@ static av_always_inline int RENAME(decode_line)(FFV1Context *s, int w, run_count--; } } else { - while (run_count > 1 && w-x > 1) { - sample[1][x] = RENAME(predict)(sample[1] + x, sample[0] + x); - x++; - run_count--; - } + while (run_count > 1 && w-x > 1) { + sample[1][x] = RENAME(predict)(sample[1] + x, sample[0] + x); + x++; + run_count--; + } } run_count--; if (run_count < 0) { diff --git a/libavcodec/ffv1enc.c b/libavcodec/ffv1enc.c index 611b250e96..7319dc602a 100644 --- a/libavcodec/ffv1enc.c +++ b/libavcodec/ffv1enc.c @@ -199,7 +199,7 @@ static av_always_inline av_flatten void put_symbol_inline(RangeCoder *c, } while (0) if (v) { - const int a = FFABS(v); + const unsigned a = is_signed ? FFABS(v) : v; const int e = av_log2(a); put_rac(c, state + 0, 0); if (e <= 9) { @@ -526,6 +526,11 @@ static av_cold int encode_init(AVCodecContext *avctx) avctx->slices > 1) s->version = FFMAX(s->version, 2); + if ((avctx->flags & (AV_CODEC_FLAG_PASS1 | AV_CODEC_FLAG_PASS2)) && s->ac == AC_GOLOMB_RICE) { + av_log(avctx, AV_LOG_ERROR, "2 Pass mode is not possible with golomb coding\n"); + return AVERROR(EINVAL); + } + // Unspecified level & slices, we choose version 1.2+ to ensure multithreaded decodability if (avctx->slices == 0 && avctx->level < 0 && avctx->width * avctx->height > 720*576) s->version = FFMAX(s->version, 2); @@ -550,7 +555,7 @@ static av_cold int encode_init(AVCodecContext *avctx) s->version = FFMAX(s->version, 3); if ((s->version == 2 || s->version>3) && avctx->strict_std_compliance > FF_COMPLIANCE_EXPERIMENTAL) { - av_log(avctx, AV_LOG_ERROR, "Version 2 needed for requested features but version 2 is experimental and not enabled\n"); + av_log(avctx, AV_LOG_ERROR, "Version 2 or 4 needed for requested features but version 2 or 4 is experimental and not enabled\n"); return AVERROR_INVALIDDATA; } @@ -735,19 +740,21 @@ FF_ENABLE_DEPRECATION_WARNINGS s->quant_tables[1][2][i]= 11*11*quant5 [i]; s->quant_tables[1][3][i]= 5*11*11*quant5 [i]; s->quant_tables[1][4][i]= 5*5*11*11*quant5 [i]; + s->context_count[0] = (11 * 11 * 11 + 1) / 2; + s->context_count[1] = (11 * 11 * 5 * 5 * 5 + 1) / 2; } else { s->quant_tables[0][0][i]= quant9_10bit[i]; - s->quant_tables[0][1][i]= 11*quant9_10bit[i]; - s->quant_tables[0][2][i]= 11*11*quant9_10bit[i]; + s->quant_tables[0][1][i]= 9*quant9_10bit[i]; + s->quant_tables[0][2][i]= 9*9*quant9_10bit[i]; s->quant_tables[1][0][i]= quant9_10bit[i]; - s->quant_tables[1][1][i]= 11*quant9_10bit[i]; - s->quant_tables[1][2][i]= 11*11*quant5_10bit[i]; - s->quant_tables[1][3][i]= 5*11*11*quant5_10bit[i]; - s->quant_tables[1][4][i]= 5*5*11*11*quant5_10bit[i]; + s->quant_tables[1][1][i]= 9*quant9_10bit[i]; + s->quant_tables[1][2][i]= 9*9*quant5_10bit[i]; + s->quant_tables[1][3][i]= 5*9*9*quant5_10bit[i]; + s->quant_tables[1][4][i]= 5*5*9*9*quant5_10bit[i]; + s->context_count[0] = (9 * 9 * 9 + 1) / 2; + s->context_count[1] = (9 * 9 * 5 * 5 * 5 + 1) / 2; } } - s->context_count[0] = (11 * 11 * 11 + 1) / 2; - s->context_count[1] = (11 * 11 * 5 * 5 * 5 + 1) / 2; memcpy(s->quant_table, s->quant_tables[s->context_model], sizeof(s->quant_table)); @@ -885,6 +892,10 @@ FF_ENABLE_DEPRECATION_WARNINGS continue; if (maxw * maxh * (int64_t)(s->bits_per_raw_sample+1) * plane_count > 8<<24) continue; + if (s->version < 4) + if ( ff_need_new_slices(avctx->width , s->num_h_slices, s->chroma_h_shift) + ||ff_need_new_slices(avctx->height, s->num_v_slices, s->chroma_v_shift)) + continue; if (avctx->slices == s->num_h_slices * s->num_v_slices && avctx->slices <= MAX_SLICES || !avctx->slices) goto slices_ok; } @@ -933,8 +944,8 @@ static void encode_slice_header(FFV1Context *f, FFV1Context *fs) put_symbol(c, state, (fs->slice_x +1)*f->num_h_slices / f->width , 0); put_symbol(c, state, (fs->slice_y +1)*f->num_v_slices / f->height , 0); - put_symbol(c, state, (fs->slice_width +1)*f->num_h_slices / f->width -1, 0); - put_symbol(c, state, (fs->slice_height+1)*f->num_v_slices / f->height-1, 0); + put_symbol(c, state, 0, 0); + put_symbol(c, state, 0, 0); for (j=0; jplane_count; j++) { put_symbol(c, state, f->plane[j].quant_table_index, 0); av_assert0(f->plane[j].quant_table_index == f->context_model); diff --git a/libavcodec/ffwavesynth.c b/libavcodec/ffwavesynth.c index 7e7e1f6954..3f982d07cf 100644 --- a/libavcodec/ffwavesynth.c +++ b/libavcodec/ffwavesynth.c @@ -188,7 +188,7 @@ static uint64_t frac64(uint64_t a, uint64_t b) static uint64_t phi_at(struct ws_interval *in, int64_t ts) { - uint64_t dt = ts - in->ts_start; + uint64_t dt = ts - (uint64_t)in->ts_start; uint64_t dt2 = dt & 1 ? /* dt * (dt - 1) / 2 without overflow */ dt * ((dt - 1) >> 1) : (dt >> 1) * (dt - 1); return in->phi0 + dt * in->dphi0 + dt2 * in->ddphi; diff --git a/libavcodec/flac_parser.c b/libavcodec/flac_parser.c index 3424583c49..c423398139 100644 --- a/libavcodec/flac_parser.c +++ b/libavcodec/flac_parser.c @@ -55,6 +55,7 @@ /** largest possible size of flac header */ #define MAX_FRAME_HEADER_SIZE 16 +#define MAX_FRAME_VERIFY_SIZE (MAX_FRAME_HEADER_SIZE) typedef struct FLACHeaderMarker { int offset; /**< byte offset from start of FLACParseContext->buffer */ @@ -170,7 +171,7 @@ static int find_headers_search_validate(FLACParseContext *fpc, int offset) uint8_t *header_buf; int size = 0; header_buf = flac_fifo_read_wrap(fpc, offset, - MAX_FRAME_HEADER_SIZE, + MAX_FRAME_VERIFY_SIZE + AV_INPUT_BUFFER_PADDING_SIZE, &fpc->wrap_buf, &fpc->wrap_buf_allocated_size); if (frame_header_is_valid(fpc->avctx, header_buf, &fi)) { @@ -358,6 +359,8 @@ static int check_header_mismatch(FLACParseContext *fpc, for (i = 0; i < FLAC_MAX_SEQUENTIAL_HEADERS && curr != child; i++) curr = curr->next; + av_assert0(i < FLAC_MAX_SEQUENTIAL_HEADERS); + if (header->link_penalty[i] < FLAC_HEADER_CRC_FAIL_PENALTY || header->link_penalty[i] == FLAC_HEADER_NOT_PENALIZED_YET) { FLACHeaderMarker *start, *end; diff --git a/libavcodec/flacenc.c b/libavcodec/flacenc.c index 8e7dbc52b4..a2aa4bdf17 100644 --- a/libavcodec/flacenc.c +++ b/libavcodec/flacenc.c @@ -1513,4 +1513,5 @@ AVCodec ff_flac_encoder = { AV_SAMPLE_FMT_S32, AV_SAMPLE_FMT_NONE }, .priv_class = &flac_encoder_class, + .caps_internal = FF_CODEC_CAP_INIT_CLEANUP, }; diff --git a/libavcodec/flashsv2enc.c b/libavcodec/flashsv2enc.c index 430b6806c8..00aedf0795 100644 --- a/libavcodec/flashsv2enc.c +++ b/libavcodec/flashsv2enc.c @@ -159,7 +159,7 @@ static void init_blocks(FlashSV2Context * s, Block * blocks, b->enc = encbuf; b->data = databuf; encbuf += b->width * b->height * 3; - databuf += !databuf ? 0 : b->width * b->height * 6; + databuf = databuf ? databuf + b->width * b->height * 6 : NULL; } } } diff --git a/libavcodec/flicvideo.c b/libavcodec/flicvideo.c index 276c2ff2a6..67fbaa7249 100644 --- a/libavcodec/flicvideo.c +++ b/libavcodec/flicvideo.c @@ -735,6 +735,8 @@ static int flic_decode_frame_15_16BPP(AVCodecContext *avctx, bytestream2_skip(&g2, chunk_size - 6); } else { + if (bytestream2_get_bytes_left(&g2) < 2 * s->avctx->width * s->avctx->height ) + return AVERROR_INVALIDDATA; for (y_ptr = 0; y_ptr < s->frame->linesize[0] * s->avctx->height; y_ptr += s->frame->linesize[0]) { diff --git a/libavcodec/fmvc.c b/libavcodec/fmvc.c index 3701b0849b..76b1355da2 100644 --- a/libavcodec/fmvc.c +++ b/libavcodec/fmvc.c @@ -100,7 +100,6 @@ static int decode_type2(GetByteContext *gb, PutByteContext *pb) continue; } } - repeat = 0; } repeat = 1; } @@ -401,20 +400,17 @@ static int decode_frame(AVCodecContext *avctx, void *data, PutByteContext *pb = &s->pb; AVFrame *frame = data; int ret, y, x; + int key_frame; if (avpkt->size < 8) return AVERROR_INVALIDDATA; - if ((ret = ff_get_buffer(avctx, frame, 0)) < 0) - return ret; - bytestream2_init(gb, avpkt->data, avpkt->size); bytestream2_skip(gb, 2); - frame->key_frame = !!bytestream2_get_le16(gb); - frame->pict_type = frame->key_frame ? AV_PICTURE_TYPE_I : AV_PICTURE_TYPE_P; + key_frame = !!bytestream2_get_le16(gb); - if (frame->key_frame) { + if (key_frame) { const uint8_t *src; unsigned type, size; uint8_t *dst; @@ -434,6 +430,12 @@ static int decode_frame(AVCodecContext *avctx, void *data, return AVERROR_PATCHWELCOME; } + if ((ret = ff_get_buffer(avctx, frame, 0)) < 0) + return ret; + + frame->key_frame = 1; + frame->pict_type = AV_PICTURE_TYPE_I; + src = s->buffer; dst = frame->data[0] + (avctx->height - 1) * frame->linesize[0]; for (y = 0; y < avctx->height; y++) { @@ -514,6 +516,12 @@ static int decode_frame(AVCodecContext *avctx, void *data, dst = &rect[block_h * s->stride]; } + if ((ret = ff_get_buffer(avctx, frame, 0)) < 0) + return ret; + + frame->key_frame = 0; + frame->pict_type = AV_PICTURE_TYPE_P; + ssrc = s->buffer; ddst = frame->data[0] + (avctx->height - 1) * frame->linesize[0]; for (y = 0; y < avctx->height; y++) { diff --git a/libavcodec/frame_thread_encoder.c b/libavcodec/frame_thread_encoder.c index 778317d60b..0d52f066e5 100644 --- a/libavcodec/frame_thread_encoder.c +++ b/libavcodec/frame_thread_encoder.c @@ -124,7 +124,7 @@ end: int ff_frame_thread_encoder_init(AVCodecContext *avctx, AVDictionary *options){ int i=0; ThreadContext *c; - + AVCodecContext *thread_avctx = NULL; if( !(avctx->thread_type & FF_THREAD_FRAME) || !(avctx->codec->capabilities & AV_CODEC_CAP_FRAME_THREADS)) @@ -205,16 +205,17 @@ int ff_frame_thread_encoder_init(AVCodecContext *avctx, AVDictionary *options){ AVDictionary *tmp = NULL; int ret; void *tmpv; - AVCodecContext *thread_avctx = avcodec_alloc_context3(avctx->codec); + thread_avctx = avcodec_alloc_context3(avctx->codec); if(!thread_avctx) goto fail; tmpv = thread_avctx->priv_data; *thread_avctx = *avctx; + thread_avctx->priv_data = tmpv; + thread_avctx->internal = NULL; + thread_avctx->hw_frames_ctx = NULL; ret = av_opt_copy(thread_avctx, avctx); if (ret < 0) goto fail; - thread_avctx->priv_data = tmpv; - thread_avctx->internal = NULL; if (avctx->codec->priv_class) { int ret = av_opt_copy(thread_avctx->priv_data, avctx->priv_data); if (ret < 0) @@ -243,6 +244,8 @@ int ff_frame_thread_encoder_init(AVCodecContext *avctx, AVDictionary *options){ return 0; fail: + avcodec_close(thread_avctx); + av_freep(&thread_avctx); avctx->thread_count = i; av_log(avctx, AV_LOG_ERROR, "ff_frame_thread_encoder_init failed\n"); ff_frame_thread_encoder_free(avctx); diff --git a/libavcodec/frame_thread_encoder.h b/libavcodec/frame_thread_encoder.h index c400d6b32c..9733fcdc2d 100644 --- a/libavcodec/frame_thread_encoder.h +++ b/libavcodec/frame_thread_encoder.h @@ -23,6 +23,10 @@ #include "avcodec.h" +/** + * Initialize frame thread encoder. + * @note hardware encoders are not supported + */ int ff_frame_thread_encoder_init(AVCodecContext *avctx, AVDictionary *options); void ff_frame_thread_encoder_free(AVCodecContext *avctx); int ff_thread_video_encode_frame(AVCodecContext *avctx, AVPacket *pkt, diff --git a/libavcodec/g2meet.c b/libavcodec/g2meet.c index 68b1b9dc74..f852d74f6c 100644 --- a/libavcodec/g2meet.c +++ b/libavcodec/g2meet.c @@ -145,7 +145,8 @@ typedef struct G2MContext { int got_header; uint8_t *framebuf; - int framebuf_stride, old_width, old_height; + int framebuf_stride; + unsigned int framebuf_allocated; uint8_t *synth_tile, *jpeg_tile, *epic_buf, *epic_buf_base; int tile_stride, epic_buf_stride, old_tile_w, old_tile_h; @@ -1029,7 +1030,7 @@ static int kempf_restore_buf(const uint8_t *src, int len, else if (npal <= 16) nb = 4; else nb = 8; - for (j = 0; j < height; j++, dst += stride, jpeg_tile += tile_stride) { + for (j = 0; j < height; j++, dst += stride, jpeg_tile = FF_PTR_ADD(jpeg_tile, tile_stride)) { if (get_bits(&gb, 8)) continue; for (i = 0; i < width; i++) { @@ -1160,14 +1161,13 @@ static int g2m_init_buffers(G2MContext *c) { int aligned_height; - if (!c->framebuf || c->old_width < c->width || c->old_height < c->height) { - c->framebuf_stride = FFALIGN(c->width + 15, 16) * 3; - aligned_height = c->height + 15; - av_free(c->framebuf); - c->framebuf = av_mallocz_array(c->framebuf_stride, aligned_height); - if (!c->framebuf) - return AVERROR(ENOMEM); - } + c->framebuf_stride = FFALIGN(c->width + 15, 16) * 3; + aligned_height = c->height + 15; + + av_fast_mallocz(&c->framebuf, &c->framebuf_allocated, c->framebuf_stride * aligned_height); + if (!c->framebuf) + return AVERROR(ENOMEM); + if (!c->synth_tile || !c->jpeg_tile || (c->compression == 2 && !c->epic_buf_base) || c->old_tile_w < c->tile_width || @@ -1619,6 +1619,7 @@ static av_cold int g2m_decode_end(AVCodecContext *avctx) av_freep(&c->jpeg_tile); av_freep(&c->cursor); av_freep(&c->framebuf); + c->framebuf_allocated = 0; return 0; } diff --git a/libavcodec/g729_parser.c b/libavcodec/g729_parser.c index 010f688104..ef08b48bf3 100644 --- a/libavcodec/g729_parser.c +++ b/libavcodec/g729_parser.c @@ -49,6 +49,9 @@ static int g729_parse(AVCodecParserContext *s1, AVCodecContext *avctx, s->block_size = (avctx->bit_rate < 8000) ? G729D_6K4_BLOCK_SIZE : G729_8K_BLOCK_SIZE; if (avctx->codec_id == AV_CODEC_ID_ACELP_KELVIN) s->block_size++; + // channels > 2 is invalid, we pass the packet on unchanged + if (avctx->channels > 2) + s->block_size = 0; s->block_size *= avctx->channels; s->duration = avctx->frame_size; } diff --git a/libavcodec/g729postfilter.c b/libavcodec/g729postfilter.c index 617744ec8e..7ca569530a 100644 --- a/libavcodec/g729postfilter.c +++ b/libavcodec/g729postfilter.c @@ -350,7 +350,7 @@ static int16_t long_term_filter(AudioDSPContext *adsp, int pitch_delay_int, if (tmp > 0) L_temp0 >>= tmp; else - L_temp1 >>= -tmp; + L_temp1 >>= FFMIN(-tmp, 31); /* Check if longer filter increases the values of R'(k). */ if (L_temp1 > L_temp0) { @@ -578,7 +578,7 @@ void ff_g729_postfilter(AudioDSPContext *adsp, int16_t* ht_prev_data, int* voici int16_t ff_g729_adaptive_gain_control(int gain_before, int gain_after, int16_t *speech, int subframe_size, int16_t gain_prev) { - int gain; // (3.12) + unsigned gain; // (3.12) int n; int exp_before, exp_after; @@ -600,7 +600,7 @@ int16_t ff_g729_adaptive_gain_control(int gain_before, int gain_after, int16_t * gain = ((gain_before - gain_after) << 14) / gain_after + 0x4000; gain = bidir_sal(gain, exp_after - exp_before); } - gain = av_clip_int16(gain); + gain = FFMIN(gain, 32767); gain = (gain * G729_AGC_FAC1 + 0x4000) >> 15; // gain * (1-0.9875) } else gain = 0; diff --git a/libavcodec/golomb.h b/libavcodec/golomb.h index 4d531cf805..defee7139b 100644 --- a/libavcodec/golomb.h +++ b/libavcodec/golomb.h @@ -404,6 +404,7 @@ static inline int get_ur_golomb(GetBitContext *gb, int k, int limit, log = av_log2(buf); if (log > 31 - limit) { + av_assert2(log >= k); buf >>= log - k; buf += (30U - log) << k; LAST_SKIP_BITS(re, gb, 32 + k - log); @@ -426,6 +427,8 @@ static inline int get_ur_golomb(GetBitContext *gb, int k, int limit, /** * read unsigned golomb rice code (jpegls). + * + * @returns -1 on error */ static inline int get_ur_golomb_jpegls(GetBitContext *gb, int k, int limit, int esc_len) @@ -537,6 +540,8 @@ static inline int get_sr_golomb(GetBitContext *gb, int k, int limit, /** * read signed golomb rice code (flac). + * + * @returns INT_MIN on error */ static inline int get_sr_golomb_flac(GetBitContext *gb, int k, int limit, int esc_len) diff --git a/libavcodec/h261dec.c b/libavcodec/h261dec.c index 5c25aa9cb3..eb544e6046 100644 --- a/libavcodec/h261dec.c +++ b/libavcodec/h261dec.c @@ -678,6 +678,6 @@ AVCodec ff_h261_decoder = { .close = h261_decode_end, .decode = h261_decode_frame, .capabilities = AV_CODEC_CAP_DR1, - .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE | FF_CODEC_CAP_INIT_CLEANUP, + .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE, .max_lowres = 3, }; diff --git a/libavcodec/h263.c b/libavcodec/h263.c index bc5c0d599f..4a03c710a6 100644 --- a/libavcodec/h263.c +++ b/libavcodec/h263.c @@ -29,6 +29,7 @@ #include +#include "libavutil/thread.h" #include "avcodec.h" #include "mpegvideo.h" #include "h263.h" @@ -38,6 +39,17 @@ #include "flv.h" #include "mpeg4video.h" +static av_cold void h263_init_rl_inter(void) +{ + static uint8_t h263_rl_inter_table[2][2 * MAX_RUN + MAX_LEVEL + 3]; + ff_rl_init(&ff_h263_rl_inter, h263_rl_inter_table); +} + +av_cold void ff_h263_init_rl_inter(void) +{ + static AVOnce init_static_once = AV_ONCE_INIT; + ff_thread_once(&init_static_once, h263_init_rl_inter); +} void ff_h263_update_motion_val(MpegEncContext * s){ const int mb_xy = s->mb_y * s->mb_stride + s->mb_x; diff --git a/libavcodec/h263.h b/libavcodec/h263.h index 998f7d0d59..f5355e7ced 100644 --- a/libavcodec/h263.h +++ b/libavcodec/h263.h @@ -66,6 +66,7 @@ int16_t *ff_h263_pred_motion(MpegEncContext * s, int block, int dir, int *px, int *py); void ff_h263_encode_init(MpegEncContext *s); void ff_h263_decode_init_vlc(void); +void ff_h263_init_rl_inter(void); int ff_h263_decode_picture_header(MpegEncContext *s); int ff_h263_decode_gob_header(MpegEncContext *s); void ff_h263_update_motion_val(MpegEncContext * s); @@ -99,15 +100,16 @@ void ff_h263_encode_motion(PutBitContext *pb, int val, int f_code); static inline int h263_get_motion_length(int val, int f_code){ - int l, bit_size, code; + int bit_size, code, sign; if (val == 0) { return ff_mvtab[0][1]; } else { bit_size = f_code - 1; /* modulo encoding */ - l= INT_BIT - 6 - bit_size; - val = (val<>l; + val = sign_extend(val, 6 + bit_size); + sign = val >> 31; + val = (val ^ sign) - sign; /* val = FFABS(val) */ val--; code = (val >> bit_size) + 1; diff --git a/libavcodec/h263data.c b/libavcodec/h263data.c index 604a0425e1..20d0436fda 100644 --- a/libavcodec/h263data.c +++ b/libavcodec/h263data.c @@ -25,8 +25,6 @@ #include -#include "libavutil/thread.h" - #include "h263data.h" #include "mpegvideo.h" @@ -290,15 +288,3 @@ const AVRational ff_h263_pixel_aspect[16] = { { 0, 1 }, { 0, 1 }, }; - -static av_cold void h263_init_rl_inter(void) -{ - static uint8_t h263_rl_inter_table[2][2 * MAX_RUN + MAX_LEVEL + 3]; - ff_rl_init(&ff_h263_rl_inter, h263_rl_inter_table); -} - -av_cold void ff_h263_init_rl_inter(void) -{ - static AVOnce init_static_once = AV_ONCE_INIT; - ff_thread_once(&init_static_once, h263_init_rl_inter); -} diff --git a/libavcodec/h263data.h b/libavcodec/h263data.h index 144704d12b..06554bdf0d 100644 --- a/libavcodec/h263data.h +++ b/libavcodec/h263data.h @@ -61,7 +61,6 @@ extern const int8_t ff_inter_run[102]; extern RLTable ff_h263_rl_inter; extern RLTable ff_rl_intra_aic; -void ff_h263_init_rl_inter(void); extern const uint16_t ff_h263_format[8][2]; diff --git a/libavcodec/h263dec.c b/libavcodec/h263dec.c index dafa54d8d4..8801596d63 100644 --- a/libavcodec/h263dec.c +++ b/libavcodec/h263dec.c @@ -301,7 +301,7 @@ static int decode_slice(MpegEncContext *s) ff_er_add_slice(&s->er, s->resync_mb_x, s->resync_mb_y, s->mb_x, s->mb_y, ER_MB_ERROR & part_mask); - if (s->avctx->err_recognition & AV_EF_IGNORE_ERR) + if ((s->avctx->err_recognition & AV_EF_IGNORE_ERR) && get_bits_left(&s->gb) > 0) continue; return AVERROR_INVALIDDATA; } @@ -427,7 +427,9 @@ int ff_h263_decode_frame(AVCodecContext *avctx, void *data, int *got_frame, MpegEncContext *s = avctx->priv_data; int ret; int slice_ret = 0; + AVFrame *pict = data; + int bak_width, bak_height; /* no supplementary picture */ if (buf_size == 0) { @@ -491,6 +493,9 @@ retry: // we need the idct permutation for reading a custom matrix ff_mpv_idct_init(s); + bak_width = s->width; + bak_height = s->height; + /* let's go :-) */ if (CONFIG_WMV2_DECODER && s->msmpeg4_version == 5) { ret = ff_wmv2_decode_picture_header(s); @@ -513,11 +518,12 @@ retry: } if (ret < 0 || ret == FRAME_SKIPPED) { - if ( s->width != avctx->coded_width - || s->height != avctx->coded_height) { + if ( s->width != bak_width + || s->height != bak_height) { av_log(s->avctx, AV_LOG_WARNING, "Reverting picture dimensions change due to header decoding failure\n"); - s->width = avctx->coded_width; - s->height= avctx->coded_height; + s->width = bak_width; + s->height= bak_height; + } } if (ret == FRAME_SKIPPED) @@ -545,6 +551,8 @@ retry: avctx->has_b_frames = !s->low_delay; if (CONFIG_MPEG4_DECODER && avctx->codec_id == AV_CODEC_ID_MPEG4) { + if (s->pict_type != AV_PICTURE_TYPE_B && s->mb_num/2 > get_bits_left(&s->gb)) + return AVERROR_INVALIDDATA; if (ff_mpeg4_workaround_bugs(avctx) == 1) goto retry; if (s->studio_profile != (s->idsp.idct == NULL)) @@ -771,7 +779,7 @@ AVCodec ff_h263_decoder = { .decode = ff_h263_decode_frame, .capabilities = AV_CODEC_CAP_DRAW_HORIZ_BAND | AV_CODEC_CAP_DR1 | AV_CODEC_CAP_TRUNCATED | AV_CODEC_CAP_DELAY, - .caps_internal = FF_CODEC_CAP_SKIP_FRAME_FILL_PARAM | FF_CODEC_CAP_INIT_CLEANUP, + .caps_internal = FF_CODEC_CAP_SKIP_FRAME_FILL_PARAM, .flush = ff_mpeg_flush, .max_lowres = 3, .pix_fmts = ff_h263_hwaccel_pixfmt_list_420, @@ -789,7 +797,7 @@ AVCodec ff_h263p_decoder = { .decode = ff_h263_decode_frame, .capabilities = AV_CODEC_CAP_DRAW_HORIZ_BAND | AV_CODEC_CAP_DR1 | AV_CODEC_CAP_TRUNCATED | AV_CODEC_CAP_DELAY, - .caps_internal = FF_CODEC_CAP_SKIP_FRAME_FILL_PARAM | FF_CODEC_CAP_INIT_CLEANUP, + .caps_internal = FF_CODEC_CAP_SKIP_FRAME_FILL_PARAM, .flush = ff_mpeg_flush, .max_lowres = 3, .pix_fmts = ff_h263_hwaccel_pixfmt_list_420, diff --git a/libavcodec/h2645_parse.h b/libavcodec/h2645_parse.h index 3e47f86c53..a3157adf5d 100644 --- a/libavcodec/h2645_parse.h +++ b/libavcodec/h2645_parse.h @@ -122,7 +122,7 @@ static inline int get_nalsize(int nal_length_size, const uint8_t *buf, if (*buf_index >= buf_size - nal_length_size) { // the end of the buffer is reached, refill it - return AVERROR(EAGAIN); + return AVERROR_INVALIDDATA; } for (i = 0; i < nal_length_size; i++) diff --git a/libavcodec/h264_mb.c b/libavcodec/h264_mb.c index 3cd17b7e4b..226c0ff09a 100644 --- a/libavcodec/h264_mb.c +++ b/libavcodec/h264_mb.c @@ -406,7 +406,7 @@ static av_always_inline void mc_part_weighted(const H264Context *h, H264SliceCon /* don't optimize for luma-only case, since B-frames usually * use implicit weights => chroma too. */ uint8_t *tmp_cb = sl->bipred_scratchpad; - uint8_t *tmp_cr = sl->bipred_scratchpad + (16 << pixel_shift); + uint8_t *tmp_cr = sl->bipred_scratchpad + (8 << pixel_shift + (chroma_idc == 3)); uint8_t *tmp_y = sl->bipred_scratchpad + 16 * sl->mb_uvlinesize; int refn0 = sl->ref_cache[0][scan8[n]]; int refn1 = sl->ref_cache[1][scan8[n]]; diff --git a/libavcodec/h264_metadata_bsf.c b/libavcodec/h264_metadata_bsf.c index 6e58c0be1d..06d23e3142 100644 --- a/libavcodec/h264_metadata_bsf.c +++ b/libavcodec/h264_metadata_bsf.c @@ -466,7 +466,7 @@ static int h264_metadata_update_fragment(AVBSFContext *bsf, AVPacket *pkt, if (ctx->aud == BSF_ELEMENT_REMOVE) ff_cbs_delete_unit(au, 0); } else { - if (ctx->aud == BSF_ELEMENT_INSERT) { + if (pkt && ctx->aud == BSF_ELEMENT_INSERT) { err = h264_metadata_insert_aud(bsf, au); if (err < 0) return err; diff --git a/libavcodec/h264_parser.c b/libavcodec/h264_parser.c index aacd44cf3b..7cb7733116 100644 --- a/libavcodec/h264_parser.c +++ b/libavcodec/h264_parser.c @@ -625,10 +625,10 @@ static int h264_parse(AVCodecParserContext *s, int64_t num = avctx->time_base.num * (int64_t)avctx->pkt_timebase.den; if (s->dts != AV_NOPTS_VALUE) { // got DTS from the stream, update reference timestamp - p->reference_dts = s->dts - av_rescale(s->dts_ref_dts_delta, num, den); + p->reference_dts = av_sat_sub64(s->dts, av_rescale(s->dts_ref_dts_delta, num, den)); } else if (p->reference_dts != AV_NOPTS_VALUE) { // compute DTS based on reference timestamp - s->dts = p->reference_dts + av_rescale(s->dts_ref_dts_delta, num, den); + s->dts = av_sat_add64(p->reference_dts, av_rescale(s->dts_ref_dts_delta, num, den)); } if (p->reference_dts != AV_NOPTS_VALUE && s->pts == AV_NOPTS_VALUE) diff --git a/libavcodec/h264_slice.c b/libavcodec/h264_slice.c index 14b945756b..411fe619db 100644 --- a/libavcodec/h264_slice.c +++ b/libavcodec/h264_slice.c @@ -304,9 +304,8 @@ int ff_h264_update_thread_context(AVCodecContext *dst, if (dst == src) return 0; - // We can't fail if SPS isn't set at it breaks current skip_frame code - //if (!h1->ps.sps) - // return AVERROR_INVALIDDATA; + if (inited && !h1->ps.sps) + return AVERROR_INVALIDDATA; if (inited && (h->width != h1->width || @@ -922,6 +921,11 @@ static int h264_slice_header_init(H264Context *h) const SPS *sps = h->ps.sps; int i, ret; + if (!sps) { + ret = AVERROR_INVALIDDATA; + goto fail; + } + ff_set_sar(h->avctx, sps->sar); av_pix_fmt_get_chroma_sub_sample(h->avctx->pix_fmt, &h->chroma_x_shift, &h->chroma_y_shift); @@ -1461,7 +1465,7 @@ static int h264_field_start(H264Context *h, const H264SliceContext *sl, sps = h->ps.sps; - if (sps && sps->bitstream_restriction_flag && + if (sps->bitstream_restriction_flag && h->avctx->has_b_frames < sps->num_reorder_frames) { h->avctx->has_b_frames = sps->num_reorder_frames; } @@ -1827,6 +1831,8 @@ static int h264_slice_header_parse(const H264Context *h, H264SliceContext *sl, if (nal->type == H264_NAL_IDR_SLICE) get_ue_golomb_long(&sl->gb); /* idr_pic_id */ + sl->poc_lsb = 0; + sl->delta_poc_bottom = 0; if (sps->poc_type == 0) { sl->poc_lsb = get_bits(&sl->gb, sps->log2_max_poc_lsb); @@ -1834,6 +1840,7 @@ static int h264_slice_header_parse(const H264Context *h, H264SliceContext *sl, sl->delta_poc_bottom = get_se_golomb(&sl->gb); } + sl->delta_poc[0] = sl->delta_poc[1] = 0; if (sps->poc_type == 1 && !sps->delta_pic_order_always_zero_flag) { sl->delta_poc[0] = get_se_golomb(&sl->gb); diff --git a/libavcodec/h264dec.c b/libavcodec/h264dec.c index 47b9abbc5c..bf3ab88da4 100644 --- a/libavcodec/h264dec.c +++ b/libavcodec/h264dec.c @@ -654,6 +654,10 @@ static int decode_nal_units(H264Context *h, const uint8_t *buf, int buf_size) avpriv_request_sample(avctx, "data partitioning"); break; case H264_NAL_SEI: + if (h->setup_finished) { + avpriv_request_sample(avctx, "Late SEI"); + break; + } ret = ff_h264_sei_decode(&h->sei, &nal->gb, &h->ps, avctx); h->has_recovery_point = h->has_recovery_point || h->sei.recovery_point.recovery_frame_cnt != -1; if (avctx->debug & FF_DEBUG_GREEN_MD) @@ -914,7 +918,7 @@ static int finalize_frame(H264Context *h, AVFrame *dst, H264Picture *out, int *g out->qscale_table, out->motion_val, NULL, - h->mb_width, h->mb_height, h->mb_stride, 1); + out->mb_width, out->mb_height, out->mb_stride, 1); } } diff --git a/libavcodec/h265_metadata_bsf.c b/libavcodec/h265_metadata_bsf.c index 59325c0471..d841839762 100644 --- a/libavcodec/h265_metadata_bsf.c +++ b/libavcodec/h265_metadata_bsf.c @@ -335,7 +335,7 @@ static int h265_metadata_update_fragment(AVBSFContext *bsf, AVPacket *pkt, int err, i; // If an AUD is present, it must be the first NAL unit. - if (au->units[0].type == HEVC_NAL_AUD) { + if (au->nb_units && au->units[0].type == HEVC_NAL_AUD) { if (ctx->aud == BSF_ELEMENT_REMOVE) ff_cbs_delete_unit(au, 0); } else { diff --git a/libavcodec/hapdec.c b/libavcodec/hapdec.c index 692bb6e750..0f9d7fb6c4 100644 --- a/libavcodec/hapdec.c +++ b/libavcodec/hapdec.c @@ -372,6 +372,7 @@ static int hap_decode(AVCodecContext *avctx, void *data, ret = av_reallocp(&ctx->tex_buf, ctx->tex_size); if (ret < 0) return ret; + memset(ctx->tex_buf, 0, ctx->tex_size); avctx->execute2(avctx, decompress_chunks_thread, NULL, ctx->chunk_results, ctx->chunk_count); diff --git a/libavcodec/hcadec.c b/libavcodec/hcadec.c index 9c3eda21af..3e543c62cd 100644 --- a/libavcodec/hcadec.c +++ b/libavcodec/hcadec.c @@ -110,6 +110,7 @@ static av_cold int decode_init(AVCodecContext *avctx) float scale = 1.f / 8.f; unsigned b, chunk; int version, ret; + unsigned hfr_group_count; avctx->sample_fmt = AV_SAMPLE_FMT_FLTP; c->crc_table = av_crc_get_table(AV_CRC_16_ANSI); @@ -233,11 +234,12 @@ static av_cold int decode_init(AVCodecContext *avctx) if (c->total_band_count < c->base_band_count) return AVERROR_INVALIDDATA; - c->hfr_group_count = ceil2(c->total_band_count - (c->base_band_count + c->stereo_band_count), + hfr_group_count = ceil2(c->total_band_count - (c->base_band_count + c->stereo_band_count), c->bands_per_hfr_group); - if (c->base_band_count + c->stereo_band_count + (unsigned long)c->hfr_group_count > 128ULL) + if (c->base_band_count + c->stereo_band_count + (uint64_t)hfr_group_count > 128ULL) return AVERROR_INVALIDDATA; + c->hfr_group_count = hfr_group_count; for (int i = 0; i < avctx->channels; i++) { c->ch[i].chan_type = r[i]; diff --git a/libavcodec/hevc_filter.c b/libavcodec/hevc_filter.c index 6b9824088c..a45cb6f0fb 100644 --- a/libavcodec/hevc_filter.c +++ b/libavcodec/hevc_filter.c @@ -145,11 +145,22 @@ int i, j; if (((intptr_t)dst | (intptr_t)src | stride_dst | stride_src) & 15) { for (i = 0; i < height; i++) { - for (j = 0; j < width; j+=8) + for (j = 0; j < width - 7; j+=8) AV_COPY64U(dst+j, src+j); dst += stride_dst; src += stride_src; } + if (width&7) { + dst += ((width>>3)<<3) - stride_dst * height; + src += ((width>>3)<<3) - stride_src * height; + width &= 7; + for (i = 0; i < height; i++) { + for (j = 0; j < width; j++) + dst[j] = src[j]; + dst += stride_dst; + src += stride_src; + } + } } else { for (i = 0; i < height; i++) { for (j = 0; j < width; j+=16) diff --git a/libavcodec/hevc_sei.c b/libavcodec/hevc_sei.c index c881c4338c..e6ae777852 100644 --- a/libavcodec/hevc_sei.c +++ b/libavcodec/hevc_sei.c @@ -386,7 +386,7 @@ static int decode_nal_sei_timecode(HEVCSEITimeCode *s, GetBitContext *gb) s->time_offset_length[i] = get_bits(gb, 5); if (s->time_offset_length[i] > 0) { - s->time_offset_value[i] = get_bits(gb, s->time_offset_length[i]); + s->time_offset_value[i] = get_bits_long(gb, s->time_offset_length[i]); } } } diff --git a/libavcodec/hevcdec.c b/libavcodec/hevcdec.c index 2231aed259..273eecca5b 100644 --- a/libavcodec/hevcdec.c +++ b/libavcodec/hevcdec.c @@ -609,6 +609,10 @@ static int hls_slice_header(HEVCContext *s) if (s->ps.pps->dependent_slice_segments_enabled_flag) sh->dependent_slice_segment_flag = get_bits1(gb); + if (sh->dependent_slice_segment_flag && !s->slice_initialized) { + av_log(s->avctx, AV_LOG_ERROR, "Independent slice segment missing.\n"); + return AVERROR_INVALIDDATA; + } slice_address_length = av_ceil_log2(s->ps.sps->ctb_width * s->ps.sps->ctb_height); @@ -877,9 +881,6 @@ static int hls_slice_header(HEVCContext *s) } else { sh->slice_loop_filter_across_slices_enabled_flag = s->ps.pps->seq_loop_filter_across_slices_enabled_flag; } - } else if (!s->slice_initialized) { - av_log(s->avctx, AV_LOG_ERROR, "Independent slice segment missing.\n"); - return AVERROR_INVALIDDATA; } sh->num_entry_point_offsets = 0; @@ -1498,7 +1499,8 @@ static void luma_mc_uni(HEVCContext *s, uint8_t *dst, ptrdiff_t dststride, if (x_off < QPEL_EXTRA_BEFORE || y_off < QPEL_EXTRA_AFTER || x_off >= pic_width - block_w - QPEL_EXTRA_AFTER || - y_off >= pic_height - block_h - QPEL_EXTRA_AFTER) { + y_off >= pic_height - block_h - QPEL_EXTRA_AFTER || + ref == s->frame) { const ptrdiff_t edge_emu_stride = EDGE_EMU_BUFFER_STRIDE << s->ps.sps->pixel_shift; int offset = QPEL_EXTRA_BEFORE * srcstride + (QPEL_EXTRA_BEFORE << s->ps.sps->pixel_shift); int buf_offset = QPEL_EXTRA_BEFORE * edge_emu_stride + (QPEL_EXTRA_BEFORE << s->ps.sps->pixel_shift); @@ -1646,6 +1648,7 @@ static void chroma_mc_uni(HEVCContext *s, uint8_t *dst0, intptr_t my = av_mod_uintp2(mv->y, 2 + vshift); intptr_t _mx = mx << (1 - hshift); intptr_t _my = my << (1 - vshift); + int emu = src0 == s->frame->data[1] || src0 == s->frame->data[2]; x_off += mv->x >> (2 + hshift); y_off += mv->y >> (2 + vshift); @@ -1653,7 +1656,8 @@ static void chroma_mc_uni(HEVCContext *s, uint8_t *dst0, if (x_off < EPEL_EXTRA_BEFORE || y_off < EPEL_EXTRA_AFTER || x_off >= pic_width - block_w - EPEL_EXTRA_AFTER || - y_off >= pic_height - block_h - EPEL_EXTRA_AFTER) { + y_off >= pic_height - block_h - EPEL_EXTRA_AFTER || + emu) { const int edge_emu_stride = EDGE_EMU_BUFFER_STRIDE << s->ps.sps->pixel_shift; int offset0 = EPEL_EXTRA_BEFORE * (srcstride + (1 << s->ps.sps->pixel_shift)); int buf_offset0 = EPEL_EXTRA_BEFORE * @@ -1892,13 +1896,13 @@ static void hls_prediction_unit(HEVCContext *s, int x0, int y0, if (current_mv.pred_flag & PF_L0) { ref0 = refPicList[0].ref[current_mv.ref_idx[0]]; - if (!ref0) + if (!ref0 || !ref0->frame) return; hevc_await_progress(s, ref0, ¤t_mv.mv[0], y0, nPbH); } if (current_mv.pred_flag & PF_L1) { ref1 = refPicList[1].ref[current_mv.ref_idx[1]]; - if (!ref1) + if (!ref1 || !ref1->frame) return; hevc_await_progress(s, ref1, ¤t_mv.mv[1], y0, nPbH); } @@ -3035,8 +3039,11 @@ static int decode_nal_unit(HEVCContext *s, const H2645NAL *nal) case HEVC_NAL_RASL_N: case HEVC_NAL_RASL_R: ret = hls_slice_header(s); - if (ret < 0) + if (ret < 0) { + // hls_slice_header() does not cleanup on failure thus the state now is inconsistant so we cannot use it on depandant slices + s->slice_initialized = 0; return ret; + } if (ret == 1) { ret = AVERROR_INVALIDDATA; goto fail; @@ -3338,7 +3345,7 @@ static int hevc_decode_frame(AVCodecContext *avctx, void *data, int *got_output, } } else { /* verify the SEI checksum */ - if (avctx->err_recognition & AV_EF_CRCCHECK && s->is_decoded && + if (avctx->err_recognition & AV_EF_CRCCHECK && s->ref && s->is_decoded && s->sei.picture_hash.is_md5) { ret = verify_md5(s, s->ref->frame); if (ret < 0 && avctx->err_recognition & AV_EF_EXPLODE) { diff --git a/libavcodec/hevcdsp_template.c b/libavcodec/hevcdsp_template.c index 56cd9e605d..61425975cd 100644 --- a/libavcodec/hevcdsp_template.c +++ b/libavcodec/hevcdsp_template.c @@ -313,7 +313,7 @@ static void FUNC(sao_band_filter)(uint8_t *_dst, uint8_t *_src, offset_table[(k + sao_left_class) & 31] = sao_offset_val[k + 1]; for (y = 0; y < height; y++) { for (x = 0; x < width; x++) - dst[x] = av_clip_pixel(src[x] + offset_table[src[x] >> shift]); + dst[x] = av_clip_pixel(src[x] + offset_table[(src[x] >> shift) & 31]); dst += stride_dst; src += stride_src; } diff --git a/libavcodec/huffyuvdec.c b/libavcodec/huffyuvdec.c index e713b91e4d..2b1a9c53b1 100644 --- a/libavcodec/huffyuvdec.c +++ b/libavcodec/huffyuvdec.c @@ -662,9 +662,9 @@ static void decode_422_bitstream(HYuvContext *s, int count) /* TODO instead of restarting the read when the code isn't in the first level * of the joint table, jump into the 2nd level of the individual table. */ #define READ_2PIX_PLANE16(dst0, dst1, plane){\ - dst0 = get_vlc2(&s->gb, s->vlc[plane].table, VLC_BITS, 3)<<2;\ + dst0 = get_vlc2(&s->gb, s->vlc[plane].table, VLC_BITS, 3)*4;\ dst0 += get_bits(&s->gb, 2);\ - dst1 = get_vlc2(&s->gb, s->vlc[plane].table, VLC_BITS, 3)<<2;\ + dst1 = get_vlc2(&s->gb, s->vlc[plane].table, VLC_BITS, 3)*4;\ dst1 += get_bits(&s->gb, 2);\ } static void decode_plane_bitstream(HYuvContext *s, int width, int plane) @@ -722,7 +722,7 @@ static void decode_plane_bitstream(HYuvContext *s, int width, int plane) } } if( width&1 && get_bits_left(&s->gb)>0 ) { - int dst = get_vlc2(&s->gb, s->vlc[plane].table, VLC_BITS, 3)<<2; + int dst = (unsigned)get_vlc2(&s->gb, s->vlc[plane].table, VLC_BITS, 3)<<2; s->temp16[0][width-1] = dst + get_bits(&s->gb, 2); } } @@ -738,6 +738,8 @@ static void decode_gray_bitstream(HYuvContext *s, int count) for (i = 0; i < count && BITS_LEFT(re, &s->gb) > 0; i++) { READ_2PIX(s->temp[0][2 * i], s->temp[0][2 * i + 1], 0); } + for (; i < count; i++) + s->temp[0][2 * i] = s->temp[0][2 * i + 1] = 0; } else { for (i = 0; i < count; i++) { READ_2PIX(s->temp[0][2 * i], s->temp[0][2 * i + 1], 0); diff --git a/libavcodec/iff.c b/libavcodec/iff.c index 79f6215c77..629c58dfbd 100644 --- a/libavcodec/iff.c +++ b/libavcodec/iff.c @@ -583,7 +583,7 @@ static int decode_byterun2(uint8_t *dst, int height, int line_size, GetByteContext *gb) { GetByteContext cmds; - unsigned count; + int count; int i, y_pos = 0, x_pos = 0; if (bytestream2_get_be32(gb) != MKBETAG('V', 'D', 'A', 'T')) @@ -591,7 +591,7 @@ static int decode_byterun2(uint8_t *dst, int height, int line_size, bytestream2_skip(gb, 4); count = bytestream2_get_be16(gb) - 2; - if (bytestream2_get_bytes_left(gb) < count) + if (count < 0 || bytestream2_get_bytes_left(gb) < count) return 0; bytestream2_init(&cmds, gb->buffer, count); @@ -1848,7 +1848,8 @@ static int decode_frame(AVCodecContext *avctx, buf += s->planesize; } } - memcpy(frame->data[1], s->pal, 256 * 4); + if (avctx->pix_fmt == AV_PIX_FMT_PAL8) + memcpy(frame->data[1], s->pal, 256 * 4); } else if (s->ham) { int i, count = 1 << s->ham; diff --git a/libavcodec/ilbcdec.c b/libavcodec/ilbcdec.c index 33f4e2c1eb..1aa6dddac8 100644 --- a/libavcodec/ilbcdec.c +++ b/libavcodec/ilbcdec.c @@ -653,7 +653,7 @@ static void get_codebook(int16_t * cbvec, /* (o) Constructed codebook vector * int16_t k, base_size; int16_t lag; /* Stack based */ - int16_t tempbuff2[SUBL + 5]; + int16_t tempbuff2[SUBL + 5] = {0}; /* Determine size of codebook sections */ base_size = lMem - cbveclen + 1; @@ -1092,12 +1092,6 @@ static void do_plc(int16_t *plc_residual, /* (o) concealed residual */ if (s->consPLICount * s->block_samples > 320) { use_gain = 29491; /* 0.9 in Q15 */ - } else if (s->consPLICount * s->block_samples > 640) { - use_gain = 22938; /* 0.7 in Q15 */ - } else if (s->consPLICount * s->block_samples > 960) { - use_gain = 16384; /* 0.5 in Q15 */ - } else if (s->consPLICount * s->block_samples > 1280) { - use_gain = 0; /* 0.0 in Q15 */ } /* Compute mixing factor of picth repeatition and noise: diff --git a/libavcodec/imm4.c b/libavcodec/imm4.c index 636130dd54..6f6858864d 100644 --- a/libavcodec/imm4.c +++ b/libavcodec/imm4.c @@ -220,12 +220,15 @@ static int decode_intra(AVCodecContext *avctx, GetBitContext *gb, AVFrame *frame for (y = 0; y < avctx->height; y += 16) { for (x = 0; x < avctx->width; x += 16) { - unsigned flag, cbphi, cbplo; + unsigned flag, cbplo; + int cbphi; cbplo = get_vlc2(gb, cbplo_tab.table, CBPLO_VLC_BITS, 1); flag = get_bits1(gb); cbphi = get_cbphi(gb, 1); + if (cbphi < 0) + return cbphi; ret = decode_blocks(avctx, gb, cbplo | (cbphi << 2), 0, offset, flag); if (ret < 0) @@ -273,7 +276,8 @@ static int decode_inter(AVCodecContext *avctx, GetBitContext *gb, for (y = 0; y < avctx->height; y += 16) { for (x = 0; x < avctx->width; x += 16) { int reverse, intra_block, value; - unsigned cbphi, cbplo, flag2 = 0; + unsigned cbplo, flag2 = 0; + int cbphi; if (get_bits1(gb)) { copy_block16(frame->data[0] + y * frame->linesize[0] + x, @@ -299,6 +303,9 @@ static int decode_inter(AVCodecContext *avctx, GetBitContext *gb, cbplo = value >> 4; cbphi = get_cbphi(gb, reverse); + if (cbphi < 0) + return cbphi; + if (intra_block) { ret = decode_blocks(avctx, gb, cbplo | (cbphi << 2), 0, offset, flag2); if (ret < 0) diff --git a/libavcodec/indeo3.c b/libavcodec/indeo3.c index 5257d983c2..134e1647fa 100644 --- a/libavcodec/indeo3.c +++ b/libavcodec/indeo3.c @@ -169,6 +169,9 @@ static av_cold int allocate_frame_buffers(Indeo3DecodeContext *ctx, int luma_size, chroma_size; ptrdiff_t luma_pitch, chroma_pitch; + luma_width = FFALIGN(luma_width , 2); + luma_height = FFALIGN(luma_height, 2); + if (luma_width < 16 || luma_width > 640 || luma_height < 16 || luma_height > 480 || luma_width & 1 || luma_height & 1) { diff --git a/libavcodec/internal.h b/libavcodec/internal.h index b57b996816..d889c1883e 100644 --- a/libavcodec/internal.h +++ b/libavcodec/internal.h @@ -78,6 +78,11 @@ * Codec handles avctx->thread_count == 0 (auto) internally. */ #define FF_CODEC_CAP_AUTO_THREADS (1 << 7) +/** + * Codec handles output frame properties internally instead of letting the + * internal logic derive them from AVCodecInternal.last_pkt_props. + */ +#define FF_CODEC_CAP_SETS_FRAME_PROPS (1 << 8) /** * AVCodec.codec_tags termination value diff --git a/libavcodec/j2kenc.c b/libavcodec/j2kenc.c index e3c5a32188..b776e275f7 100644 --- a/libavcodec/j2kenc.c +++ b/libavcodec/j2kenc.c @@ -719,11 +719,10 @@ static void encode_cblk(Jpeg2000EncoderContext *s, Jpeg2000T1Context *t1, Jpeg20 if (max == 0){ cblk->nonzerobits = 0; - bpno = 0; } else{ cblk->nonzerobits = av_log2(max) + 1 - NMSEDEC_FRACBITS; - bpno = cblk->nonzerobits - 1; } + bpno = cblk->nonzerobits - 1; cblk->data[0] = 0; ff_mqc_initenc(&t1->mqc, cblk->data + 1); @@ -1531,6 +1530,7 @@ static int encode_frame(AVCodecContext *avctx, AVPacket *pkt, int tileno, ret; Jpeg2000EncoderContext *s = avctx->priv_data; uint8_t *chunkstart, *jp2cstart, *jp2hstart; + const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(avctx->pix_fmt); if ((ret = ff_alloc_packet2(avctx, pkt, avctx->width*avctx->height*9 + AV_INPUT_BUFFER_MIN_SIZE, 0)) < 0) return ret; @@ -1543,7 +1543,7 @@ static int encode_frame(AVCodecContext *avctx, AVPacket *pkt, s->lambda = s->picture->quality * LAMBDA_SCALE; - if (avctx->pix_fmt == AV_PIX_FMT_BGR48 || avctx->pix_fmt == AV_PIX_FMT_GRAY16) + if (s->cbps[0] > 8) copy_frame_16(s); else copy_frame_8(s); @@ -1587,7 +1587,7 @@ static int encode_frame(AVCodecContext *avctx, AVPacket *pkt, bytestream_put_byte(&s->buf, 1); bytestream_put_byte(&s->buf, 0); bytestream_put_byte(&s->buf, 0); - if (avctx->pix_fmt == AV_PIX_FMT_RGB24 || avctx->pix_fmt == AV_PIX_FMT_PAL8) { + if ((desc->flags & AV_PIX_FMT_FLAG_RGB) || avctx->pix_fmt == AV_PIX_FMT_PAL8) { bytestream_put_be32(&s->buf, 16); } else if (s->ncomponents == 1) { bytestream_put_be32(&s->buf, 17); @@ -1679,7 +1679,7 @@ static int parse_layer_rates(Jpeg2000EncoderContext *s) } token = av_strtok(s->lr_str, ",", &saveptr); - if (rate = strtol(token, NULL, 10)) { + if (token && (rate = strtol(token, NULL, 10))) { s->layer_rates[0] = rate <= 1 ? 0:rate; nlayers++; } else { @@ -1717,6 +1717,7 @@ static av_cold int j2kenc_init(AVCodecContext *avctx) Jpeg2000EncoderContext *s = avctx->priv_data; Jpeg2000CodingStyle *codsty = &s->codsty; Jpeg2000QuantStyle *qntsty = &s->qntsty; + const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(avctx->pix_fmt); s->avctx = avctx; av_log(s->avctx, AV_LOG_DEBUG, "init\n"); @@ -1736,7 +1737,7 @@ FF_ENABLE_DEPRECATION_WARNINGS if (avctx->pix_fmt == AV_PIX_FMT_PAL8 && (s->pred != FF_DWT97_INT || s->format != CODEC_JP2)) { av_log(s->avctx, AV_LOG_WARNING, "Forcing lossless jp2 for pal8\n"); - s->pred = FF_DWT97_INT; + s->pred = 1; s->format = CODEC_JP2; } @@ -1766,20 +1767,13 @@ FF_ENABLE_DEPRECATION_WARNINGS s->width = avctx->width; s->height = avctx->height; + s->ncomponents = desc->nb_components; for (i = 0; i < 3; i++) { - if (avctx->pix_fmt == AV_PIX_FMT_GRAY16 || avctx->pix_fmt == AV_PIX_FMT_RGB48) - s->cbps[i] = 16; - else - s->cbps[i] = 8; + s->cbps[i] = desc->comp[i].depth; } - if (avctx->pix_fmt == AV_PIX_FMT_RGB24 || avctx->pix_fmt == AV_PIX_FMT_RGB48){ - s->ncomponents = 3; - } else if (avctx->pix_fmt == AV_PIX_FMT_GRAY8 || avctx->pix_fmt == AV_PIX_FMT_PAL8 || avctx->pix_fmt == AV_PIX_FMT_GRAY16){ - s->ncomponents = 1; - } else{ // planar YUV + if ((desc->flags & AV_PIX_FMT_FLAG_PLANAR) && s->ncomponents > 1) { s->planar = 1; - s->ncomponents = 3; ret = av_pix_fmt_get_chroma_sub_sample(avctx->pix_fmt, s->chroma_shift, s->chroma_shift + 1); if (ret) @@ -1819,7 +1813,7 @@ static const AVOption options[] = { { "tile_height", "Tile Height", OFFSET(tile_height), AV_OPT_TYPE_INT, { .i64 = 256 }, 1, 1<<30, VE, }, { "pred", "DWT Type", OFFSET(pred), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 1, VE, "pred" }, { "dwt97int", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = 0 }, INT_MIN, INT_MAX, VE, "pred" }, - { "dwt53", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = 0 }, INT_MIN, INT_MAX, VE, "pred" }, + { "dwt53", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = 1 }, INT_MIN, INT_MAX, VE, "pred" }, { "sop", "SOP marker", OFFSET(sop), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 1, VE, }, { "eph", "EPH marker", OFFSET(eph), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, 1, VE, }, { "prog", "Progression Order", OFFSET(prog), AV_OPT_TYPE_INT, { .i64 = 0 }, JPEG2000_PGOD_LRCP, JPEG2000_PGOD_CPRL, VE, "prog" }, diff --git a/libavcodec/jfdctint_template.c b/libavcodec/jfdctint_template.c index 67fb77b5e1..126c3d913c 100644 --- a/libavcodec/jfdctint_template.c +++ b/libavcodec/jfdctint_template.c @@ -69,7 +69,7 @@ #define GLOBAL(x) x #define RIGHT_SHIFT(x, n) ((x) >> (n)) #define MULTIPLY16C16(var,const) ((var)*(const)) -#define DESCALE(x,n) RIGHT_SHIFT((x) + (1 << ((n) - 1)), n) +#define DESCALE(x,n) RIGHT_SHIFT((int)(x) + (1 << ((n) - 1)), n) /* @@ -175,7 +175,7 @@ #if BITS_IN_JSAMPLE == 8 && CONST_BITS<=13 && PASS1_BITS<=2 #define MULTIPLY(var,const) MULTIPLY16C16(var,const) #else -#define MULTIPLY(var,const) ((var) * (const)) +#define MULTIPLY(var,const) (int)((var) * (unsigned)(const)) #endif @@ -183,7 +183,7 @@ static av_always_inline void FUNC(row_fdct)(int16_t *data) { int tmp0, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7; int tmp10, tmp11, tmp12, tmp13; - int z1, z2, z3, z4, z5; + unsigned z1, z2, z3, z4, z5; int16_t *dataptr; int ctr; @@ -261,7 +261,7 @@ FUNC(ff_jpeg_fdct_islow)(int16_t *data) { int tmp0, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7; int tmp10, tmp11, tmp12, tmp13; - int z1, z2, z3, z4, z5; + unsigned z1, z2, z3, z4, z5; int16_t *dataptr; int ctr; diff --git a/libavcodec/jpeg2000dec.c b/libavcodec/jpeg2000dec.c index 63edbcda09..9b3654dbc6 100644 --- a/libavcodec/jpeg2000dec.c +++ b/libavcodec/jpeg2000dec.c @@ -323,6 +323,16 @@ static int get_siz(Jpeg2000DecoderContext *s) return AVERROR_INVALIDDATA; } + if (s->image_offset_x >= s->width || s->image_offset_y >= s->height) { + av_log(s->avctx, AV_LOG_ERROR, "image offsets outside image"); + return AVERROR_INVALIDDATA; + } + + if (s->reduction_factor && (s->image_offset_x || s->image_offset_y) ){ + av_log(s->avctx, AV_LOG_ERROR, "reduction factor with image offsets is not fully implemented"); + return AVERROR_PATCHWELCOME; + } + s->ncomponents = ncomponents; if (s->tile_width <= 0 || s->tile_height <= 0) { @@ -901,9 +911,6 @@ static int get_tlm(Jpeg2000DecoderContext *s, int n) case 2: bytestream2_get_be16(&s->g); break; - case 3: - bytestream2_get_be32(&s->g); - break; } if (SP == 0) { bytestream2_get_be16(&s->g); @@ -2361,6 +2368,8 @@ static int jp2_find_codestream(Jpeg2000DecoderContext *s) atom_size >= 16) { uint32_t atom2_size, atom2, atom2_end; do { + if (bytestream2_get_bytes_left(&s->g) < 8) + break; atom2_size = bytestream2_get_be32u(&s->g); atom2 = bytestream2_get_be32u(&s->g); atom2_end = bytestream2_tell(&s->g) + atom2_size - 8; diff --git a/libavcodec/jpeglsdec.c b/libavcodec/jpeglsdec.c index 69980eaa49..1bc94c5070 100644 --- a/libavcodec/jpeglsdec.c +++ b/libavcodec/jpeglsdec.c @@ -67,7 +67,7 @@ int ff_jpegls_decode_lse(MJpegDecodeContext *s) s->t3 = get_bits(&s->gb, 16); s->reset = get_bits(&s->gb, 16); - if(s->avctx->debug & FF_DEBUG_PICT_INFO) { + if (s->avctx->debug & FF_DEBUG_PICT_INFO) { av_log(s->avctx, AV_LOG_DEBUG, "Coding parameters maxval:%d T1:%d T2:%d T3:%d reset:%d\n", s->maxval, s->t1, s->t2, s->t3, s->reset); } @@ -96,7 +96,7 @@ int ff_jpegls_decode_lse(MJpegDecodeContext *s) else maxtab = 65530/wt - 1; - if(s->avctx->debug & FF_DEBUG_PICT_INFO) { + if (s->avctx->debug & FF_DEBUG_PICT_INFO) { av_log(s->avctx, AV_LOG_DEBUG, "LSE palette %d tid:%d wt:%d maxtab:%d\n", id, tid, wt, maxtab); } if (maxtab >= 256) { @@ -122,7 +122,7 @@ int ff_jpegls_decode_lse(MJpegDecodeContext *s) s->avctx->pix_fmt = AV_PIX_FMT_PAL8; for (i=s->palette_index; i<=maxtab; i++) { uint8_t k = i << shift; - pal[k] = 0; + pal[k] = wt < 4 ? 0xFF000000 : 0; for (j=0; jgb, 8) << (8*(wt-j-1)); } @@ -186,7 +186,7 @@ static inline int ls_get_code_runterm(GetBitContext *gb, JLSState *state, if (RItype) temp += state->N[Q] >> 1; - for (k = 0; (state->N[Q] << k) < temp; k++) + for (k = 0; ((unsigned)state->N[Q] << k) < temp; k++) ; #ifdef JLS_BROKEN @@ -195,6 +195,8 @@ static inline int ls_get_code_runterm(GetBitContext *gb, JLSState *state, #endif ret = get_ur_golomb_jpegls(gb, k, state->limit - limit_add - 1, state->qbpp); + if (ret < 0) + return -0x10000; /* decode mapped error */ map = 0; @@ -209,7 +211,7 @@ static inline int ls_get_code_runterm(GetBitContext *gb, JLSState *state, ret = ret >> 1; } - if(FFABS(ret) > 0xFFFF) + if (FFABS(ret) > 0xFFFF) return -0x10000; /* update state */ state->A[Q] += FFABS(ret) - RItype; @@ -374,6 +376,19 @@ int ff_jpegls_decode_picture(MJpegDecodeContext *s, int near, state->T3 = s->t3; state->reset = s->reset; ff_jpegls_reset_coding_parameters(state, 0); + + /* Testing parameters here, we cannot test in LSE or SOF because + * these interdepend and are allowed in either order + */ + if (state->maxval >= (1<bpp) || + state->T1 > state->T2 || + state->T2 > state->T3 || + state->T3 > state->maxval || + state->reset > FFMAX(255, state->maxval)) { + ret = AVERROR_INVALIDDATA; + goto end; + } + ff_jpegls_init_state(state); if (s->bits <= 8) @@ -476,19 +491,19 @@ int ff_jpegls_decode_picture(MJpegDecodeContext *s, int near, for (i = 0; i < s->height; i++) { switch(s->xfrm) { case 1: - for (x = off; x < w; x += 3) { + for (x = off; x + 2 < w; x += 3) { src[x ] += src[x+1] + 128; src[x+2] += src[x+1] + 128; } break; case 2: - for (x = off; x < w; x += 3) { + for (x = off; x + 2 < w; x += 3) { src[x ] += src[x+1] + 128; src[x+2] += ((src[x ] + src[x+1])>>1) + 128; } break; case 3: - for (x = off; x < w; x += 3) { + for (x = off; x + 2 < w; x += 3) { int g = src[x+0] - ((src[x+2]+src[x+1])>>2) + 64; src[x+0] = src[x+2] + g + 128; src[x+2] = src[x+1] + g + 128; @@ -496,7 +511,7 @@ int ff_jpegls_decode_picture(MJpegDecodeContext *s, int near, } break; case 4: - for (x = off; x < w; x += 3) { + for (x = off; x + 2 < w; x += 3) { int r = src[x+0] - (( 359 * (src[x+2]-128) + 490) >> 8); int g = src[x+0] - (( 88 * (src[x+1]-128) - 183 * (src[x+2]-128) + 30) >> 8); int b = src[x+0] + ((454 * (src[x+1]-128) + 574) >> 8); diff --git a/libavcodec/lagarith.c b/libavcodec/lagarith.c index d81e55cf4c..1b08e9308e 100644 --- a/libavcodec/lagarith.c +++ b/libavcodec/lagarith.c @@ -408,6 +408,9 @@ output_zeros: if (zero_run) { zero_run = 0; i += esc_count; + if (i > end - dst || + i >= src_end - src) + return AVERROR_INVALIDDATA; memcpy(dst, src, i); dst += i; l->zeros_rem = lag_calc_zero_run(src[i]); diff --git a/libavcodec/lcldec.c b/libavcodec/lcldec.c index 2dcd249b65..9317f8ef85 100644 --- a/libavcodec/lcldec.c +++ b/libavcodec/lcldec.c @@ -148,6 +148,8 @@ static int zlib_decomp(AVCodecContext *avctx, const uint8_t *src, int src_len, i if (expected != (unsigned int)c->zstream.total_out) { av_log(avctx, AV_LOG_ERROR, "Decoded size differs (%d != %lu)\n", expected, c->zstream.total_out); + if (expected > (unsigned int)c->zstream.total_out) + return (unsigned int)c->zstream.total_out; return AVERROR_UNKNOWN; } return c->zstream.total_out; @@ -166,14 +168,14 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame, AVPac int row, col; unsigned char *encoded = avpkt->data, *outptr; uint8_t *y_out, *u_out, *v_out; - unsigned int width = avctx->width; // Real image width - unsigned int height = avctx->height; // Real image height + int width = avctx->width; // Real image width + int height = avctx->height; // Real image height unsigned int mszh_dlen; unsigned char yq, y1q, uq, vq; int uqvq, ret; unsigned int mthread_inlen, mthread_outlen; unsigned int len = buf_size; - int linesize; + int linesize, offset; if ((ret = ff_thread_get_buffer(avctx, &tframe, 0)) < 0) return ret; @@ -224,16 +226,19 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame, AVPac break; case COMP_MSZH_NOCOMP: { int bppx2; + int aligned_width = width; switch (c->imgtype) { case IMGTYPE_YUV111: case IMGTYPE_RGB24: bppx2 = 6; break; case IMGTYPE_YUV422: + aligned_width &= ~3; case IMGTYPE_YUV211: bppx2 = 4; break; case IMGTYPE_YUV411: + aligned_width &= ~3; case IMGTYPE_YUV420: bppx2 = 3; break; @@ -241,7 +246,7 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame, AVPac bppx2 = 0; // will error out below break; } - if (len < ((width * height * bppx2) >> 1)) + if (len < ((aligned_width * height * bppx2) >> 1)) return AVERROR_INVALIDDATA; break; } @@ -273,12 +278,13 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame, AVPac ret = zlib_decomp(avctx, buf + 8 + mthread_inlen, len - 8 - mthread_inlen, mthread_outlen, mthread_outlen); if (ret < 0) return ret; + len = c->decomp_size; } else { int ret = zlib_decomp(avctx, buf, len, 0, c->decomp_size); if (ret < 0) return ret; + len = ret; } encoded = c->decomp_buf; - len = c->decomp_size; break; #endif default: @@ -306,8 +312,8 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame, AVPac } break; case IMGTYPE_YUV422: + pixel_ptr = 0; for (row = 0; row < height; row++) { - pixel_ptr = row * width * 2; yq = uq = vq =0; for (col = 0; col < width/4; col++) { encoded[pixel_ptr] = yq -= encoded[pixel_ptr]; @@ -323,8 +329,8 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame, AVPac } break; case IMGTYPE_YUV411: + pixel_ptr = 0; for (row = 0; row < height; row++) { - pixel_ptr = row * width / 2 * 3; yq = uq = vq =0; for (col = 0; col < width/4; col++) { encoded[pixel_ptr] = yq -= encoded[pixel_ptr]; @@ -373,8 +379,10 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame, AVPac /* Convert colorspace */ y_out = frame->data[0] + (height - 1) * frame->linesize[0]; - u_out = frame->data[1] + (height - 1) * frame->linesize[1]; - v_out = frame->data[2] + (height - 1) * frame->linesize[2]; + offset = (height - 1) * frame->linesize[1]; + u_out = FF_PTR_ADD(frame->data[1], offset); + offset = (height - 1) * frame->linesize[2]; + v_out = FF_PTR_ADD(frame->data[2], offset); switch (c->imgtype) { case IMGTYPE_YUV111: for (row = 0; row < height; row++) { @@ -398,6 +406,11 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame, AVPac v_out[ col >> 1 ] = *encoded++ + 128; v_out[(col >> 1) + 1] = *encoded++ + 128; } + if (col && col < width) { + u_out[ col >> 1 ] = u_out[(col>>1) - 1]; + v_out[ col >> 1 ] = v_out[(col>>1) - 1]; + } + y_out -= frame->linesize[0]; u_out -= frame->linesize[1]; v_out -= frame->linesize[2]; @@ -419,6 +432,10 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame, AVPac u_out[col >> 2] = *encoded++ + 128; v_out[col >> 2] = *encoded++ + 128; } + if (col && col < width) { + u_out[col >> 2] = u_out[(col>>2) - 1]; + v_out[col >> 2] = v_out[(col>>2) - 1]; + } y_out -= frame->linesize[0]; u_out -= frame->linesize[1]; v_out -= frame->linesize[2]; @@ -476,6 +493,7 @@ static av_cold int decode_init(AVCodecContext *avctx) FFALIGN(avctx->height, 4); unsigned int max_decomp_size; int subsample_h, subsample_v; + int partial_h_supported = 0; if (avctx->extradata_size < 8) { av_log(avctx, AV_LOG_ERROR, "Extradata size too small.\n"); @@ -497,26 +515,24 @@ static av_cold int decode_init(AVCodecContext *avctx) av_log(avctx, AV_LOG_DEBUG, "Image type is YUV 1:1:1.\n"); break; case IMGTYPE_YUV422: - c->decomp_size = basesize * 2; + c->decomp_size = (avctx->width & ~3) * avctx->height * 2; max_decomp_size = max_basesize * 2; avctx->pix_fmt = AV_PIX_FMT_YUV422P; av_log(avctx, AV_LOG_DEBUG, "Image type is YUV 4:2:2.\n"); - if (avctx->width % 4) { - avpriv_request_sample(avctx, "Unsupported dimensions"); - return AVERROR_INVALIDDATA; - } + partial_h_supported = 1; break; case IMGTYPE_RGB24: - c->decomp_size = basesize * 3; + c->decomp_size = FFALIGN(avctx->width*3, 4) * avctx->height; max_decomp_size = max_basesize * 3; avctx->pix_fmt = AV_PIX_FMT_BGR24; av_log(avctx, AV_LOG_DEBUG, "Image type is RGB 24.\n"); break; case IMGTYPE_YUV411: - c->decomp_size = basesize / 2 * 3; + c->decomp_size = (avctx->width & ~3) * avctx->height / 2 * 3; max_decomp_size = max_basesize / 2 * 3; avctx->pix_fmt = AV_PIX_FMT_YUV411P; av_log(avctx, AV_LOG_DEBUG, "Image type is YUV 4:1:1.\n"); + partial_h_supported = 1; break; case IMGTYPE_YUV211: c->decomp_size = basesize * 2; @@ -536,7 +552,7 @@ static av_cold int decode_init(AVCodecContext *avctx) } av_pix_fmt_get_chroma_sub_sample(avctx->pix_fmt, &subsample_h, &subsample_v); - if (avctx->width % (1<height % (1<width % (1<height % (1< (x) || DAV1D_API_VERSION_MAJOR == (x) && DAV1D_API_VERSION_MINOR >= (y)) + typedef struct Libdav1dContext { AVClass *class; Dav1dContext *c; @@ -124,7 +127,11 @@ static av_cold int libdav1d_init(AVCodecContext *c) { Libdav1dContext *dav1d = c->priv_data; Dav1dSettings s; +#if FF_DAV1D_VERSION_AT_LEAST(6,0) + int threads = c->thread_count; +#else int threads = (c->thread_count ? c->thread_count : av_cpu_count()) * 3 / 2; +#endif int res; av_log(c, AV_LOG_INFO, "libdav1d %s\n", dav1d_version()); @@ -145,6 +152,15 @@ static av_cold int libdav1d_init(AVCodecContext *c) if (dav1d->operating_point >= 0) s.operating_point = dav1d->operating_point; +#if FF_DAV1D_VERSION_AT_LEAST(6,0) + if (dav1d->frame_threads || dav1d->tile_threads) + s.n_threads = FFMAX(dav1d->frame_threads, dav1d->tile_threads); + else + s.n_threads = FFMIN(threads, DAV1D_MAX_THREADS); + s.max_frame_delay = (c->flags & AV_CODEC_FLAG_LOW_DELAY) ? 1 : 0; + av_log(c, AV_LOG_DEBUG, "Using %d threads, %d max_frame_delay\n", + s.n_threads, s.max_frame_delay); +#else s.n_tile_threads = dav1d->tile_threads ? dav1d->tile_threads : FFMIN(floor(sqrt(threads)), DAV1D_MAX_TILE_THREADS); @@ -153,6 +169,7 @@ static av_cold int libdav1d_init(AVCodecContext *c) : FFMIN(ceil(threads / s.n_tile_threads), DAV1D_MAX_FRAME_THREADS); av_log(c, AV_LOG_DEBUG, "Using %d frame threads, %d tile threads\n", s.n_frame_threads, s.n_tile_threads); +#endif res = dav1d_open(&dav1d->c, &s); if (res < 0) @@ -231,8 +248,10 @@ static int libdav1d_receive_frame(AVCodecContext *c, AVFrame *frame) if (res < 0) { if (res == AVERROR(EINVAL)) res = AVERROR_INVALIDDATA; - if (res != AVERROR(EAGAIN)) + if (res != AVERROR(EAGAIN)) { + dav1d_data_unref(data); return res; + } } res = dav1d_get_picture(dav1d->c, p); @@ -456,6 +475,13 @@ static av_cold int libdav1d_close(AVCodecContext *c) return 0; } +#ifndef DAV1D_MAX_FRAME_THREADS +#define DAV1D_MAX_FRAME_THREADS DAV1D_MAX_THREADS +#endif +#ifndef DAV1D_MAX_TILE_THREADS +#define DAV1D_MAX_TILE_THREADS DAV1D_MAX_THREADS +#endif + #define OFFSET(x) offsetof(Libdav1dContext, x) #define VD AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_DECODING_PARAM static const AVOption libdav1d_options[] = { diff --git a/libavcodec/libkvazaar.c b/libavcodec/libkvazaar.c index 4432649853..7389265415 100644 --- a/libavcodec/libkvazaar.c +++ b/libavcodec/libkvazaar.c @@ -210,13 +210,19 @@ static int libkvazaar_encode(AVCodecContext *avctx, // Copy pixels from frame to input_pic. { + uint8_t *dst[4] = { + input_pic->data[0], + input_pic->data[1], + input_pic->data[2], + NULL, + }; int dst_linesizes[4] = { frame->width, frame->width / 2, frame->width / 2, 0 }; - av_image_copy(input_pic->data, dst_linesizes, + av_image_copy(dst, dst_linesizes, (const uint8_t **)frame->data, frame->linesize, frame->format, frame->width, frame->height); } diff --git a/libavcodec/libopenh264dec.c b/libavcodec/libopenh264dec.c index c7aa7fa19c..dcd781dd84 100644 --- a/libavcodec/libopenh264dec.c +++ b/libavcodec/libopenh264dec.c @@ -91,8 +91,8 @@ static int svc_decode_frame(AVCodecContext *avctx, void *data, { SVCContext *s = avctx->priv_data; SBufferInfo info = { 0 }; - uint8_t* ptrs[3]; - int ret, linesize[3]; + uint8_t *ptrs[4] = { NULL }; + int ret, linesize[4]; AVFrame *avframe = data; DECODING_STATE state; #if OPENH264_VER_AT_LEAST(1, 7) @@ -140,6 +140,7 @@ static int svc_decode_frame(AVCodecContext *avctx, void *data, linesize[0] = info.UsrData.sSystemBuffer.iStride[0]; linesize[1] = linesize[2] = info.UsrData.sSystemBuffer.iStride[1]; + linesize[3] = 0; av_image_copy(avframe->data, avframe->linesize, (const uint8_t **) ptrs, linesize, avctx->pix_fmt, avctx->width, avctx->height); avframe->pts = info.uiOutYuvTimeStamp; diff --git a/libavcodec/libsvtav1.c b/libavcodec/libsvtav1.c index cfd93a2484..38777b0fb7 100644 --- a/libavcodec/libsvtav1.c +++ b/libavcodec/libsvtav1.c @@ -120,16 +120,12 @@ static int svt_print_error(void *log_ctx, EbErrorType err, static int alloc_buffer(EbSvtAv1EncConfiguration *config, SvtContext *svt_enc) { - const int pack_mode_10bit = - (config->encoder_bit_depth > 8) && (config->compressed_ten_bit_format == 0) ? 1 : 0; - const size_t luma_size_8bit = - config->source_width * config->source_height * (1 << pack_mode_10bit); - const size_t luma_size_10bit = - (config->encoder_bit_depth > 8 && pack_mode_10bit == 0) ? luma_size_8bit : 0; + const size_t luma_size = config->source_width * config->source_height * + (config->encoder_bit_depth > 8 ? 2 : 1); EbSvtIOFormat *in_data; - svt_enc->raw_size = (luma_size_8bit + luma_size_10bit) * 3 / 2; + svt_enc->raw_size = luma_size * 3 / 2; // allocate buffer for in and out svt_enc->in_buf = av_mallocz(sizeof(*svt_enc->in_buf)); diff --git a/libavcodec/libtheoraenc.c b/libavcodec/libtheoraenc.c index 16966ed433..a16211c403 100644 --- a/libavcodec/libtheoraenc.c +++ b/libavcodec/libtheoraenc.c @@ -232,7 +232,7 @@ static av_cold int encode_init(AVCodecContext* avc_context) return AVERROR_EXTERNAL; } - h->keyframe_mask = (1 << t_info.keyframe_granule_shift) - 1; + h->keyframe_mask = (1 << av_ceil_log2(avc_context->gop_size)) - 1; /* Clear up theora_info struct */ th_info_clear(&t_info); diff --git a/libavcodec/libuavs3d.c b/libavcodec/libuavs3d.c index be03da39e2..59b50a2843 100644 --- a/libavcodec/libuavs3d.c +++ b/libavcodec/libuavs3d.c @@ -208,7 +208,9 @@ static int libuavs3d_decode_frame(AVCodecContext *avctx, void *data, int *got_fr } avctx->has_b_frames = !seqh->low_delay; avctx->pix_fmt = seqh->bit_depth_internal == 8 ? AV_PIX_FMT_YUV420P : AV_PIX_FMT_YUV420P10LE; - ff_set_dimensions(avctx, seqh->horizontal_size, seqh->vertical_size); + ret = ff_set_dimensions(avctx, seqh->horizontal_size, seqh->vertical_size); + if (ret < 0) + return ret; h->got_seqhdr = 1; if (seqh->colour_description) { diff --git a/libavcodec/libx265.c b/libavcodec/libx265.c index b2008e96f1..6a3abe4ab8 100644 --- a/libavcodec/libx265.c +++ b/libavcodec/libx265.c @@ -476,7 +476,13 @@ static int libx265_encode_frame(AVCodecContext *avctx, AVPacket *pkt, { libx265Context *ctx = avctx->priv_data; x265_picture x265pic; - x265_picture x265pic_out = { 0 }; +#if (X265_BUILD >= 210) && (X265_BUILD < 213) + x265_picture x265pic_layers_out[MAX_SCALABLE_LAYERS]; + x265_picture* x265pic_lyrptr_out[MAX_SCALABLE_LAYERS]; +#else + x265_picture x265pic_solo_out = { 0 }; +#endif + x265_picture* x265pic_out; x265_nal *nal; uint8_t *dst; int pict_type; @@ -517,8 +523,16 @@ static int libx265_encode_frame(AVCodecContext *avctx, AVPacket *pkt, } } +#if (X265_BUILD >= 210) && (X265_BUILD < 213) + for (i = 0; i < MAX_SCALABLE_LAYERS; i++) + x265pic_lyrptr_out[i] = &x265pic_layers_out[i]; + ret = ctx->api->encoder_encode(ctx->encoder, &nal, &nnal, - pic ? &x265pic : NULL, &x265pic_out); + pic ? &x265pic : NULL, x265pic_lyrptr_out); +#else + ret = ctx->api->encoder_encode(ctx->encoder, &nal, &nnal, + pic ? &x265pic : NULL, &x265pic_solo_out); +#endif av_freep(&x265pic.quantOffsets); @@ -546,10 +560,16 @@ static int libx265_encode_frame(AVCodecContext *avctx, AVPacket *pkt, pkt->flags |= AV_PKT_FLAG_KEY; } - pkt->pts = x265pic_out.pts; - pkt->dts = x265pic_out.dts; +#if (X265_BUILD >= 210) && (X265_BUILD < 213) + x265pic_out = x265pic_lyrptr_out[0]; +#else + x265pic_out = &x265pic_solo_out; +#endif - switch (x265pic_out.sliceType) { + pkt->pts = x265pic_out->pts; + pkt->dts = x265pic_out->dts; + + switch (x265pic_out->sliceType) { case X265_TYPE_IDR: case X265_TYPE_I: pict_type = AV_PICTURE_TYPE_I; @@ -573,17 +593,17 @@ FF_ENABLE_DEPRECATION_WARNINGS #endif #if X265_BUILD >= 130 - if (x265pic_out.sliceType == X265_TYPE_B) + if (x265pic_out->sliceType == X265_TYPE_B) #else - if (x265pic_out.frameData.sliceType == 'b') + if (x265pic_out->frameData.sliceType == 'b') #endif pkt->flags |= AV_PKT_FLAG_DISPOSABLE; - ff_side_data_set_encoder_stats(pkt, x265pic_out.frameData.qp * FF_QP2LAMBDA, NULL, 0, pict_type); + ff_side_data_set_encoder_stats(pkt, x265pic_out->frameData.qp * FF_QP2LAMBDA, NULL, 0, pict_type); - if (x265pic_out.userData) { - memcpy(&avctx->reordered_opaque, x265pic_out.userData, sizeof(avctx->reordered_opaque)); - av_freep(&x265pic_out.userData); + if (x265pic_out->userData) { + memcpy(&avctx->reordered_opaque, x265pic_out->userData, sizeof(avctx->reordered_opaque)); + av_freep(&x265pic_out->userData); } else avctx->reordered_opaque = 0; diff --git a/libavcodec/libxavs2.c b/libavcodec/libxavs2.c index 2a4a3e36bd..f33240f300 100644 --- a/libavcodec/libxavs2.c +++ b/libavcodec/libxavs2.c @@ -205,7 +205,7 @@ static int xavs2_encode_frame(AVCodecContext *avctx, AVPacket *pkt, ret = cae->api->encoder_encode(cae->encoder, &pic, &cae->packet); if (ret) { - av_log(avctx, AV_LOG_ERROR, "Encoding error occured.\n"); + av_log(avctx, AV_LOG_ERROR, "Encoding error occurred.\n"); return AVERROR_EXTERNAL; } diff --git a/libavcodec/loco.c b/libavcodec/loco.c index 99e3a1d021..92a5e8f2ce 100644 --- a/libavcodec/loco.c +++ b/libavcodec/loco.c @@ -91,10 +91,15 @@ static inline int loco_get_rice(RICEContext *r) if (get_bits_left(&r->gb) < 1) return INT_MIN; v = get_ur_golomb_jpegls(&r->gb, loco_get_rice_param(r), INT_MAX, 0); + if (v == -1) + return INT_MIN; loco_update_rice_param(r, (v + 1) >> 1); if (!v) { if (r->save >= 0) { - r->run = get_ur_golomb_jpegls(&r->gb, 2, INT_MAX, 0); + int run = get_ur_golomb_jpegls(&r->gb, 2, INT_MAX, 0); + if (run == -1) + return INT_MIN; + r->run = run; if (r->run > 1) r->save += r->run + 1; else @@ -151,6 +156,8 @@ static int loco_decode_plane(LOCOContext *l, uint8_t *data, int width, int heigh /* restore top left pixel */ val = loco_get_rice(&rc); + if (val == INT_MIN) + return AVERROR_INVALIDDATA; data[0] = 128 + val; /* restore top line */ for (i = 1; i < width; i++) { diff --git a/libavcodec/lpc.c b/libavcodec/lpc.c index 1d1d04fd80..f9c4bcaf98 100644 --- a/libavcodec/lpc.c +++ b/libavcodec/lpc.c @@ -189,7 +189,7 @@ double ff_lpc_calc_ref_coefs_f(LPCContext *s, const float *samples, int len, compute_ref_coefs(autoc, order, ref, error); for (i = 0; i < order; i++) avg_err = (avg_err + error[i])/2.0f; - return signal/avg_err; + return avg_err ? signal/avg_err : NAN; } /** @@ -244,8 +244,10 @@ int ff_lpc_calc_coefs(LPCContext *s, double av_uninit(weight); memset(var, 0, FFALIGN(MAX_LPC_ORDER+1,4)*sizeof(*var)); - for(j=0; j 1) + for(j=0; jzstream.avail_in = FFMIN(length, bytestream2_get_bytes_left(&s->gb)); s->zstream.next_in = s->gb.buffer; + + if (length <= 0) + return AVERROR_INVALIDDATA; + bytestream2_skip(&s->gb, length); /* decode one line if possible */ diff --git a/libavcodec/mfenc.c b/libavcodec/mfenc.c index d70e49351a..d088f86c2c 100644 --- a/libavcodec/mfenc.c +++ b/libavcodec/mfenc.c @@ -246,7 +246,7 @@ static int mf_sample_to_avpacket(AVCodecContext *avctx, IMFSample *sample, AVPac if ((ret = ff_get_encode_buffer(avctx, avpkt, len, 0)) < 0) return ret; - IMFSample_ConvertToContiguousBuffer(sample, &buffer); + hr = IMFSample_ConvertToContiguousBuffer(sample, &buffer); if (FAILED(hr)) return AVERROR_EXTERNAL; diff --git a/libavcodec/midivid.c b/libavcodec/midivid.c index 2200440e2c..3e6a9ca3d9 100644 --- a/libavcodec/midivid.c +++ b/libavcodec/midivid.c @@ -202,12 +202,7 @@ static int decode_frame(AVCodecContext *avctx, void *data, bytestream2_skip(gb, 8); uncompressed = bytestream2_get_le32(gb); - if ((ret = ff_reget_buffer(avctx, s->frame, 0)) < 0) - return ret; - - if (uncompressed) { - ret = decode_mvdv(s, avctx, frame); - } else { + if (!uncompressed) { av_fast_padded_malloc(&s->uncompressed, &s->uncompressed_size, 16LL * (avpkt->size - 12)); if (!s->uncompressed) return AVERROR(ENOMEM); @@ -216,9 +211,13 @@ static int decode_frame(AVCodecContext *avctx, void *data, if (ret < 0) return ret; bytestream2_init(gb, s->uncompressed, ret); - ret = decode_mvdv(s, avctx, frame); } + if ((ret = ff_reget_buffer(avctx, s->frame, 0)) < 0) + return ret; + + ret = decode_mvdv(s, avctx, frame); + if (ret < 0) return ret; key = ret; diff --git a/libavcodec/mjpegbdec.c b/libavcodec/mjpegbdec.c index 7666674908..3fab4a66bc 100644 --- a/libavcodec/mjpegbdec.c +++ b/libavcodec/mjpegbdec.c @@ -57,6 +57,7 @@ static int mjpegb_decode_frame(AVCodecContext *avctx, buf_end = buf + buf_size; s->got_picture = 0; s->adobe_transform = -1; + s->buf_size = buf_size; read_header: /* reset on every SOI */ @@ -119,9 +120,13 @@ read_header: 8 * FFMIN(field_size, buf_end - buf_ptr - sos_offs)); s->mjpb_skiptosod = (sod_offs - sos_offs - show_bits(&s->gb, 16)); s->start_code = SOS; - ret = ff_mjpeg_decode_sos(s, NULL, 0, NULL); - if (ret < 0 && (avctx->err_recognition & AV_EF_EXPLODE)) - return ret; + if (avctx->skip_frame == AVDISCARD_ALL) { + skip_bits(&s->gb, get_bits_left(&s->gb)); + } else { + ret = ff_mjpeg_decode_sos(s, NULL, 0, NULL); + if (ret < 0 && (avctx->err_recognition & AV_EF_EXPLODE)) + return ret; + } } if (s->interlaced) { diff --git a/libavcodec/mjpegdec.c b/libavcodec/mjpegdec.c index 20f310fd70..03597ba3e2 100644 --- a/libavcodec/mjpegdec.c +++ b/libavcodec/mjpegdec.c @@ -76,6 +76,7 @@ static int init_default_huffman_tables(MJpegDecodeContext *s) int i, ret; for (i = 0; i < FF_ARRAY_ELEMS(ht); i++) { + ff_free_vlc(&s->vlcs[ht[i].class][ht[i].index]); ret = ff_mjpeg_build_vlc(&s->vlcs[ht[i].class][ht[i].index], ht[i].bits, ht[i].values, ht[i].class == 1, s->avctx); @@ -153,7 +154,8 @@ av_cold int ff_mjpeg_decode_init(AVCodecContext *avctx) if (ff_mjpeg_decode_dht(s)) { av_log(avctx, AV_LOG_ERROR, "error using external huffman table, switching back to internal\n"); - init_default_huffman_tables(s); + if ((ret = init_default_huffman_tables(s)) < 0) + return ret; } } if (avctx->field_order == AV_FIELD_BB) { /* quicktime icefloe 019 */ @@ -460,6 +462,10 @@ int ff_mjpeg_decode_sof(MJpegDecodeContext *s) if (s->avctx->height <= 0) return AVERROR_INVALIDDATA; } + if (s->bayer && s->progressive) { + avpriv_request_sample(s->avctx, "progressively coded bayer picture"); + return AVERROR_INVALIDDATA; + } if (s->got_picture && s->interlaced && (s->bottom_field == !s->interlace_polarity)) { if (s->progressive) { @@ -1080,6 +1086,10 @@ static int ljpeg_decode_rgb_scan(MJpegDecodeContext *s, int nb_components, int p return AVERROR_INVALIDDATA; if (s->v_max != 1 || s->h_max != 1 || !s->lossless) return AVERROR_INVALIDDATA; + if (s->bayer) { + if (s->rct || s->pegasus_rct) + return AVERROR_INVALIDDATA; + } s->restart_count = s->restart_interval; @@ -1196,6 +1206,8 @@ static int ljpeg_decode_rgb_scan(MJpegDecodeContext *s, int nb_components, int p ptr[3*mb_x + 2] = buffer[mb_x][2] + ptr[3*mb_x + 1]; } } else if (s->bayer) { + if (s->bits <= 8) + return AVERROR_PATCHWELCOME; if (nb_components == 1) { /* Leave decoding to the TIFF/DNG decoder (see comment in ff_mjpeg_decode_sof) */ for (mb_x = 0; mb_x < width; mb_x++) @@ -1571,6 +1583,9 @@ static int mjpeg_decode_scan_progressive_ac(MJpegDecodeContext *s, int ss, else ret = decode_block_progressive(s, *block, last_nnz, s->ac_index[0], quant_matrix, ss, se, Al, &EOBRUN); + + if (ret >= 0 && get_bits_left(&s->gb) < 0) + ret = AVERROR_INVALIDDATA; if (ret < 0) { av_log(s->avctx, AV_LOG_ERROR, "error y=%d x=%d\n", mb_y, mb_x); @@ -1927,6 +1942,8 @@ static int mjpeg_decode_app(MJpegDecodeContext *s) } len -= 9; + if (s->bayer) + goto out; if (s->got_picture) if (rgb != s->rgb || pegasus_rct != s->pegasus_rct) { av_log(s->avctx, AV_LOG_WARNING, "Mismatching LJIF tag\n"); @@ -2085,28 +2102,26 @@ static int mjpeg_decode_app(MJpegDecodeContext *s) /* Allocate if this is the first APP2 we've seen. */ if (s->iccnum == 0) { - s->iccdata = av_mallocz(nummarkers * sizeof(*(s->iccdata))); - s->iccdatalens = av_mallocz(nummarkers * sizeof(*(s->iccdatalens))); - if (!s->iccdata || !s->iccdatalens) { + if (!FF_ALLOCZ_TYPED_ARRAY(s->iccentries, nummarkers)) { av_log(s->avctx, AV_LOG_ERROR, "Could not allocate ICC data arrays\n"); return AVERROR(ENOMEM); } s->iccnum = nummarkers; } - if (s->iccdata[seqno - 1]) { + if (s->iccentries[seqno - 1].data) { av_log(s->avctx, AV_LOG_WARNING, "Duplicate ICC sequence number\n"); goto out; } - s->iccdatalens[seqno - 1] = len; - s->iccdata[seqno - 1] = av_malloc(len); - if (!s->iccdata[seqno - 1]) { + s->iccentries[seqno - 1].length = len; + s->iccentries[seqno - 1].data = av_malloc(len); + if (!s->iccentries[seqno - 1].data) { av_log(s->avctx, AV_LOG_ERROR, "Could not allocate ICC data buffer\n"); return AVERROR(ENOMEM); } - memcpy(s->iccdata[seqno - 1], align_get_bits(&s->gb), len); + memcpy(s->iccentries[seqno - 1].data, align_get_bits(&s->gb), len); skip_bits(&s->gb, len << 3); len = 0; s->iccread++; @@ -2315,11 +2330,11 @@ static void reset_icc_profile(MJpegDecodeContext *s) { int i; - if (s->iccdata) + if (s->iccentries) { for (i = 0; i < s->iccnum; i++) - av_freep(&s->iccdata[i]); - av_freep(&s->iccdata); - av_freep(&s->iccdatalens); + av_freep(&s->iccentries[i].data); + av_freep(&s->iccentries); + } s->iccread = 0; s->iccnum = 0; @@ -2835,7 +2850,7 @@ the_end: /* Sum size of all parts. */ for (i = 0; i < s->iccnum; i++) - total_size += s->iccdatalens[i]; + total_size += s->iccentries[i].length; sd = av_frame_new_side_data(frame, AV_FRAME_DATA_ICC_PROFILE, total_size); if (!sd) { @@ -2845,8 +2860,8 @@ the_end: /* Reassemble the parts, which are now in-order. */ for (i = 0; i < s->iccnum; i++) { - memcpy(sd->data + offset, s->iccdata[i], s->iccdatalens[i]); - offset += s->iccdatalens[i]; + memcpy(sd->data + offset, s->iccentries[i].data, s->iccentries[i].length); + offset += s->iccentries[i].length; } } diff --git a/libavcodec/mjpegdec.h b/libavcodec/mjpegdec.h index 732aeab994..0d69d9101b 100644 --- a/libavcodec/mjpegdec.h +++ b/libavcodec/mjpegdec.h @@ -44,6 +44,11 @@ #define MAX_COMPONENTS 4 +typedef struct ICCEntry { + uint8_t *data; + int length; +} ICCEntry; + typedef struct MJpegDecodeContext { AVClass *class; AVCodecContext *avctx; @@ -138,8 +143,7 @@ typedef struct MJpegDecodeContext { const AVPixFmtDescriptor *pix_desc; - uint8_t **iccdata; - int *iccdatalens; + ICCEntry *iccentries; int iccnum; int iccread; diff --git a/libavcodec/mjpegenc.c b/libavcodec/mjpegenc.c index 22af094da7..4d7755cc88 100644 --- a/libavcodec/mjpegenc.c +++ b/libavcodec/mjpegenc.c @@ -312,8 +312,10 @@ av_cold int ff_mjpeg_encode_init(MpegEncContext *s) av_cold void ff_mjpeg_encode_close(MpegEncContext *s) { - av_freep(&s->mjpeg_ctx->huff_buffer); - av_freep(&s->mjpeg_ctx); + if (s->mjpeg_ctx) { + av_freep(&s->mjpeg_ctx->huff_buffer); + av_freep(&s->mjpeg_ctx); + } } /** diff --git a/libavcodec/mjpegenc_common.c b/libavcodec/mjpegenc_common.c index 12dd7be2e8..0845814834 100644 --- a/libavcodec/mjpegenc_common.c +++ b/libavcodec/mjpegenc_common.c @@ -247,7 +247,7 @@ void ff_mjpeg_encode_picture_header(AVCodecContext *avctx, PutBitContext *pb, default: av_assert0(0); } - put_bits(pb, 16, 17); + put_bits(pb, 16, 8 + 3 * components); if (lossless && ( avctx->pix_fmt == AV_PIX_FMT_BGR0 || avctx->pix_fmt == AV_PIX_FMT_BGRA || avctx->pix_fmt == AV_PIX_FMT_BGR24)) diff --git a/libavcodec/mlpdec.c b/libavcodec/mlpdec.c index 0c30034dd4..7563fb0b12 100644 --- a/libavcodec/mlpdec.c +++ b/libavcodec/mlpdec.c @@ -521,7 +521,7 @@ static int read_restart_header(MLPDecodeContext *m, GetBitContext *gbp, /* This should happen for TrueHD streams with >6 channels and MLP's noise * type. It is not yet known if this is allowed. */ - if (max_channel > MAX_MATRIX_CHANNEL_MLP && !noise_type) { + if (max_matrix_channel > MAX_MATRIX_CHANNEL_MLP && !noise_type) { avpriv_request_sample(m->avctx, "%d channels (more than the " "maximum supported by the decoder)", diff --git a/libavcodec/mobiclip.c b/libavcodec/mobiclip.c index bf47a5bc41..4baf347446 100644 --- a/libavcodec/mobiclip.c +++ b/libavcodec/mobiclip.c @@ -329,7 +329,7 @@ static av_cold int mobiclip_init(AVCodecContext *avctx) return 0; } -static int setup_qtables(AVCodecContext *avctx, int quantizer) +static int setup_qtables(AVCodecContext *avctx, int64_t quantizer) { MobiClipContext *s = avctx->priv_data; int qx, qy; @@ -1256,7 +1256,7 @@ static int mobiclip_decode(AVCodecContext *avctx, void *data, frame->key_frame = 0; s->dct_tab_idx = 0; - ret = setup_qtables(avctx, s->quantizer + get_se_golomb(gb)); + ret = setup_qtables(avctx, s->quantizer + (int64_t)get_se_golomb(gb)); if (ret < 0) return ret; diff --git a/libavcodec/motion_est.c b/libavcodec/motion_est.c index 5a339fc1c7..26da3e3a2f 100644 --- a/libavcodec/motion_est.c +++ b/libavcodec/motion_est.c @@ -109,8 +109,8 @@ static av_always_inline int cmp_direct_inline(MpegEncContext *s, const int x, co me_cmp_func cmp_func, me_cmp_func chroma_cmp_func, int qpel){ MotionEstContext * const c= &s->me; const int stride= c->stride; - const int hx= subx + (x<<(1+qpel)); - const int hy= suby + (y<<(1+qpel)); + const int hx = subx + x * (1 << (1 + qpel)); + const int hy = suby + y * (1 << (1 + qpel)); uint8_t * const * const ref= c->ref[ref_index]; uint8_t * const * const src= c->src[src_index]; int d; @@ -599,7 +599,7 @@ static inline int h263_mv4_search(MpegEncContext *s, int mx, int my, int shift) P_LEFT[0] = s->current_picture.motion_val[0][mot_xy - 1][0]; P_LEFT[1] = s->current_picture.motion_val[0][mot_xy - 1][1]; - if(P_LEFT[0] > (c->xmax<xmax< c->xmax * (1 << shift)) P_LEFT[0] = c->xmax * (1 << shift); /* special case for first line */ if (s->first_slice_line && block<2) { @@ -610,10 +610,10 @@ static inline int h263_mv4_search(MpegEncContext *s, int mx, int my, int shift) P_TOP[1] = s->current_picture.motion_val[0][mot_xy - mot_stride ][1]; P_TOPRIGHT[0] = s->current_picture.motion_val[0][mot_xy - mot_stride + off[block]][0]; P_TOPRIGHT[1] = s->current_picture.motion_val[0][mot_xy - mot_stride + off[block]][1]; - if(P_TOP[1] > (c->ymax<ymax<xmin<xmin< (c->xmax<xmax< (c->ymax<ymax< c->ymax * (1 << shift)) P_TOP[1] = c->ymax * (1 << shift); + if (P_TOPRIGHT[0] < c->xmin * (1 << shift)) P_TOPRIGHT[0] = c->xmin * (1 << shift); + if (P_TOPRIGHT[0] > c->xmax * (1 << shift)) P_TOPRIGHT[0] = c->xmax * (1 << shift); + if (P_TOPRIGHT[1] > c->ymax * (1 << shift)) P_TOPRIGHT[1] = c->ymax * (1 << shift); P_MEDIAN[0]= mid_pred(P_LEFT[0], P_TOP[0], P_TOPRIGHT[0]); P_MEDIAN[1]= mid_pred(P_LEFT[1], P_TOP[1], P_TOPRIGHT[1]); @@ -629,8 +629,8 @@ static inline int h263_mv4_search(MpegEncContext *s, int mx, int my, int shift) continue; if (i>4 && i<9) continue; - if(P[i][0] > (c->xmax<xmax< (c->ymax<ymax< c->xmax * (1 << shift)) P[i][0] = c->xmax * (1 << shift); + if (P[i][1] > c->ymax * (1 << shift)) P[i][1] = c->ymax * (1 <p_mv_table, (1<<16)>>shift, 1); @@ -785,7 +785,7 @@ static int interlaced_search(MpegEncContext *s, int ref_index, P_TOPRIGHT[0] = mv_table[xy - mot_stride + 1][0]; P_TOPRIGHT[1] = mv_table[xy - mot_stride + 1][1]; if(P_TOP[1] > (c->ymax<<1)) P_TOP[1] = (c->ymax<<1); - if(P_TOPRIGHT[0] < (c->xmin<<1)) P_TOPRIGHT[0]= (c->xmin<<1); + if (P_TOPRIGHT[0] < c->xmin * (1 << 1)) P_TOPRIGHT[0] = c->xmin * (1 << 1); if(P_TOPRIGHT[0] > (c->xmax<<1)) P_TOPRIGHT[0]= (c->xmax<<1); if(P_TOPRIGHT[1] > (c->ymax<<1)) P_TOPRIGHT[1]= (c->ymax<<1); @@ -839,7 +839,7 @@ static int interlaced_search(MpegEncContext *s, int ref_index, dmin_sum += best_dmin; } - c->ymin<<=1; + c->ymin *= 2; c->ymax<<=1; c->stride>>=1; c->uvstride>>=1; @@ -981,8 +981,8 @@ void ff_estimate_p_frame_motion(MpegEncContext * s, if(mx || my) mb_type |= CANDIDATE_MB_TYPE_SKIPPED; //FIXME check difference }else{ - mx <<=shift; - my <<=shift; + mx *= 1 << shift; + my *= 1 << shift; } if ((s->avctx->flags & AV_CODEC_FLAG_4MV) && !c->skip && varc>50<<8 && vard>10<<8){ @@ -1143,7 +1143,7 @@ static int estimate_motion_b(MpegEncContext *s, int mb_x, int mb_y, P_TOPRIGHT[0] = mv_table[mot_xy - mot_stride + 1][0]; P_TOPRIGHT[1] = mv_table[mot_xy - mot_stride + 1][1]; if (P_TOP[1] > (c->ymax << shift)) P_TOP[1] = (c->ymax << shift); - if (P_TOPRIGHT[0] < (c->xmin << shift)) P_TOPRIGHT[0] = (c->xmin << shift); + if (P_TOPRIGHT[0] < c->xmin * (1 << shift)) P_TOPRIGHT[0] = c->xmin * (1 << shift); if (P_TOPRIGHT[1] > (c->ymax << shift)) P_TOPRIGHT[1] = (c->ymax << shift); P_MEDIAN[0] = mid_pred(P_LEFT[0], P_TOP[0], P_TOPRIGHT[0]); @@ -1155,7 +1155,7 @@ static int estimate_motion_b(MpegEncContext *s, int mb_x, int mb_y, if(mv_table == s->b_forw_mv_table){ mv_scale= (s->pb_time<<16) / (s->pp_time<pb_time - s->pp_time)<<16) / (s->pp_time<pb_time - s->pp_time) * (1 << 16)) / (s->pp_time<p_mv_table, mv_scale, 0, 16); @@ -1255,8 +1255,8 @@ static inline int bidir_refine(MpegEncContext * s, int mb_x, int mb_y) const int flags= c->sub_flags; const int qpel= flags&FLAG_QPEL; const int shift= 1+qpel; - const int xmin= c->xmin<ymin<xmin * (1 << shift); + const int ymin= c->ymin * (1 << shift); const int xmax= c->xmax<ymax<b_direct_mv_table[mot_xy][0]= 0; s->b_direct_mv_table[mot_xy][1]= 0; - return 256*256*256*64; + return 256*256*256*64-1; } c->xmin= xmin; @@ -1454,15 +1454,15 @@ static inline int direct_search(MpegEncContext * s, int mb_x, int mb_y) c->pred_x=0; c->pred_y=0; - P_LEFT[0] = av_clip(mv_table[mot_xy - 1][0], xmin<first_slice_line) { //FIXME maybe allow this over thread boundary as it is clipped - P_TOP[0] = av_clip(mv_table[mot_xy - mot_stride ][0], xmin<mb_height; y++){ int x; int xy= y*s->mb_stride; - for(x=0; xmb_width; x++){ + for(x=0; xmb_width; x++, xy++){ if(s->mb_type[xy] & type){ int mx= mv_table[xy][0]; int my= mv_table[xy][1]; @@ -1622,16 +1622,15 @@ int ff_get_best_fcode(MpegEncContext * s, int16_t (*mv_table)[2], int type) fcode_tab[my + MAX_MV]); int j; - if(mx >= range || mx < -range || - my >= range || my < -range) - continue; + if (mx >= range || mx < -range || + my >= range || my < -range) + continue; for(j=0; jpict_type==AV_PICTURE_TYPE_B || s->current_picture.mc_mb_var[xy] < s->current_picture.mb_var[xy]) score[j]-= 170; } } - xy++; } } diff --git a/libavcodec/motion_est_template.c b/libavcodec/motion_est_template.c index d3b2f97744..6ab0ea13dc 100644 --- a/libavcodec/motion_est_template.c +++ b/libavcodec/motion_est_template.c @@ -82,7 +82,7 @@ static int hpel_motion_search(MpegEncContext * s, if (mx > xmin && mx < xmax && my > ymin && my < ymax) { int d= dmin; - const int index= (my<penalty_factor; const int l= score_map[(index- 1 )&(ME_MAP_SIZE-1)] @@ -95,13 +95,13 @@ static int hpel_motion_search(MpegEncContext * s, #if defined(ASSERT_LEVEL) && ASSERT_LEVEL > 1 unsigned key; unsigned map_generation= c->map_generation; - key= ((my-1)<map[(index-(1<map[(index+(1<map[(index+1)&(ME_MAP_SIZE-1)] == key); - key= ((my)<map[(index-1)&(ME_MAP_SIZE-1)] == key); #endif if(t<=b){ @@ -246,7 +246,7 @@ static int qpel_motion_search(MpegEncContext * s, int bx=4*mx, by=4*my; int d= dmin; int i, nx, ny; - const int index= (my<frame->data[0][y * mp->frame->linesize[0] + x * 2]; - return mp_rgb_yuv_table[color]; + return mp_rgb_yuv_table[color & 0x7FFF]; } static void mp_set_rgb_from_yuv(MotionPixelsContext *mp, int x, int y, const YuvPixel *p) diff --git a/libavcodec/movtextenc.c b/libavcodec/movtextenc.c index cf30adbd0a..b36354b14e 100644 --- a/libavcodec/movtextenc.c +++ b/libavcodec/movtextenc.c @@ -85,7 +85,7 @@ typedef struct { uint8_t box_flags; StyleBox d; uint16_t text_pos; - uint16_t byte_count; + unsigned byte_count; char **fonts; int font_count; double font_scale_factor; @@ -585,9 +585,9 @@ static void mov_text_cancel_overrides_cb(void *priv, const char *style_name) mov_text_ass_style_set(s, style); } -static uint16_t utf8_strlen(const char *text, int len) +static unsigned utf8_strlen(const char *text, int len) { - uint16_t i = 0, ret = 0; + unsigned i = 0, ret = 0; while (i < len) { char c = text[i]; if ((c & 0x80) == 0) @@ -607,7 +607,7 @@ static uint16_t utf8_strlen(const char *text, int len) static void mov_text_text_cb(void *priv, const char *text, int len) { - uint16_t utf8_len = utf8_strlen(text, len); + unsigned utf8_len = utf8_strlen(text, len); MovTextContext *s = priv; av_bprint_append_data(&s->buffer, text, len); // If it's not utf-8, just use the byte length diff --git a/libavcodec/mpeg12dec.c b/libavcodec/mpeg12dec.c index 92dd6a0b24..b6a2b44bc6 100644 --- a/libavcodec/mpeg12dec.c +++ b/libavcodec/mpeg12dec.c @@ -1538,6 +1538,10 @@ static void mpeg_decode_picture_coding_extension(Mpeg1Context *s1) s->mpeg_f_code[0][1] = get_bits(&s->gb, 4); s->mpeg_f_code[1][0] = get_bits(&s->gb, 4); s->mpeg_f_code[1][1] = get_bits(&s->gb, 4); + s->mpeg_f_code[0][0] += !s->mpeg_f_code[0][0]; + s->mpeg_f_code[0][1] += !s->mpeg_f_code[0][1]; + s->mpeg_f_code[1][0] += !s->mpeg_f_code[1][0]; + s->mpeg_f_code[1][1] += !s->mpeg_f_code[1][1]; if (!s->pict_type && s1->mpeg_enc_ctx_allocated) { av_log(s->avctx, AV_LOG_ERROR, "Missing picture start code, guessing missing values\n"); @@ -1551,10 +1555,6 @@ static void mpeg_decode_picture_coding_extension(Mpeg1Context *s1) s->current_picture.f->pict_type = s->pict_type; s->current_picture.f->key_frame = s->pict_type == AV_PICTURE_TYPE_I; } - s->mpeg_f_code[0][0] += !s->mpeg_f_code[0][0]; - s->mpeg_f_code[0][1] += !s->mpeg_f_code[0][1]; - s->mpeg_f_code[1][0] += !s->mpeg_f_code[1][0]; - s->mpeg_f_code[1][1] += !s->mpeg_f_code[1][1]; s->intra_dc_precision = get_bits(&s->gb, 2); s->picture_structure = get_bits(&s->gb, 2); @@ -2880,7 +2880,8 @@ static av_cold int mpeg_decode_end(AVCodecContext *avctx) { Mpeg1Context *s = avctx->priv_data; - ff_mpv_common_end(&s->mpeg_enc_ctx); + if (s->mpeg_enc_ctx_allocated) + ff_mpv_common_end(&s->mpeg_enc_ctx); av_buffer_unref(&s->a53_buf_ref); return 0; } @@ -2897,7 +2898,7 @@ AVCodec ff_mpeg1video_decoder = { .capabilities = AV_CODEC_CAP_DRAW_HORIZ_BAND | AV_CODEC_CAP_DR1 | AV_CODEC_CAP_TRUNCATED | AV_CODEC_CAP_DELAY | AV_CODEC_CAP_SLICE_THREADS, - .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE | FF_CODEC_CAP_INIT_CLEANUP | + .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE | FF_CODEC_CAP_SKIP_FRAME_FILL_PARAM, .flush = flush, .max_lowres = 3, @@ -2931,7 +2932,7 @@ AVCodec ff_mpeg2video_decoder = { .capabilities = AV_CODEC_CAP_DRAW_HORIZ_BAND | AV_CODEC_CAP_DR1 | AV_CODEC_CAP_TRUNCATED | AV_CODEC_CAP_DELAY | AV_CODEC_CAP_SLICE_THREADS, - .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE | FF_CODEC_CAP_INIT_CLEANUP | + .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE | FF_CODEC_CAP_SKIP_FRAME_FILL_PARAM, .flush = flush, .max_lowres = 3, @@ -2976,7 +2977,7 @@ AVCodec ff_mpegvideo_decoder = { .close = mpeg_decode_end, .decode = mpeg_decode_frame, .capabilities = AV_CODEC_CAP_DRAW_HORIZ_BAND | AV_CODEC_CAP_DR1 | AV_CODEC_CAP_TRUNCATED | AV_CODEC_CAP_DELAY | AV_CODEC_CAP_SLICE_THREADS, - .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE | FF_CODEC_CAP_INIT_CLEANUP | + .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE | FF_CODEC_CAP_SKIP_FRAME_FILL_PARAM, .flush = flush, .max_lowres = 3, @@ -2998,6 +2999,10 @@ static int ipu_decode_frame(AVCodecContext *avctx, void *data, AVFrame * const frame = data; int ret; + // Check for minimal intra MB size (considering mb header, luma & chroma dc VLC, ac EOB VLC) + if (avpkt->size*8LL < (avctx->width+15)/16 * ((avctx->height+15)/16) * (2LL + 3*4 + 2*2 + 2*6)) + return AVERROR_INVALIDDATA; + ret = ff_get_buffer(avctx, frame, 0); if (ret < 0) return ret; diff --git a/libavcodec/mpeg4videodec.c b/libavcodec/mpeg4videodec.c index 2ca804fdc6..f7f08d5eca 100644 --- a/libavcodec/mpeg4videodec.c +++ b/libavcodec/mpeg4videodec.c @@ -349,6 +349,8 @@ static int mpeg4_decode_sprite_trajectory(Mpeg4DecContext *ctx, GetBitContext *g ctx->sprite_shift[0] = alpha + beta + rho - min_ab; ctx->sprite_shift[1] = alpha + beta + rho - min_ab + 2; break; + default: + av_assert0(0); } /* try to simplify the situation */ if (sprite_delta[0][0] == a << ctx->sprite_shift[0] && @@ -614,7 +616,7 @@ static inline int get_amv(Mpeg4DecContext *ctx, int n) for (y = 0; y < 16; y++) { int v; - v = mb_v + dy * y; + v = mb_v + (unsigned)dy * y; // FIXME optimize for (x = 0; x < 16; x++) { sum += v >> shift; @@ -1187,7 +1189,7 @@ static inline int mpeg4_decode_block(Mpeg4DecContext *ctx, int16_t *block, if (SHOW_UBITS(re, &s->gb, 1) == 0) { av_log(s->avctx, AV_LOG_ERROR, "1. marker bit missing in 3. esc\n"); - if (!(s->avctx->err_recognition & AV_EF_IGNORE_ERR)) + if (!(s->avctx->err_recognition & AV_EF_IGNORE_ERR) || get_bits_left(&s->gb) <= 0) return AVERROR_INVALIDDATA; } SKIP_CACHE(re, &s->gb, 1); @@ -1198,7 +1200,7 @@ static inline int mpeg4_decode_block(Mpeg4DecContext *ctx, int16_t *block, if (SHOW_UBITS(re, &s->gb, 1) == 0) { av_log(s->avctx, AV_LOG_ERROR, "2. marker bit missing in 3. esc\n"); - if (!(s->avctx->err_recognition & AV_EF_IGNORE_ERR)) + if (!(s->avctx->err_recognition & AV_EF_IGNORE_ERR) || get_bits_left(&s->gb) <= 0) return AVERROR_INVALIDDATA; } @@ -3579,8 +3581,7 @@ AVCodec ff_mpeg4_decoder = { AV_CODEC_CAP_TRUNCATED | AV_CODEC_CAP_DELAY | AV_CODEC_CAP_FRAME_THREADS, .caps_internal = FF_CODEC_CAP_SKIP_FRAME_FILL_PARAM | - FF_CODEC_CAP_ALLOCATE_PROGRESS | - FF_CODEC_CAP_INIT_CLEANUP, + FF_CODEC_CAP_ALLOCATE_PROGRESS, .flush = ff_mpeg_flush, .max_lowres = 3, .pix_fmts = ff_h263_hwaccel_pixfmt_list_420, diff --git a/libavcodec/mpegaudiodec_template.c b/libavcodec/mpegaudiodec_template.c index 4fd9e3a690..642fa5ac79 100644 --- a/libavcodec/mpegaudiodec_template.c +++ b/libavcodec/mpegaudiodec_template.c @@ -372,7 +372,7 @@ static int handle_crc(MPADecodeContext *s, int sec_len) crc_val = av_crc(crc_tab, crc_val, &buf[6], sec_byte_len); AV_WB32(tmp_buf, - ((buf[6 + sec_byte_len] & (0xFF00 >> sec_rem_bits)) << 24) + + ((buf[6 + sec_byte_len] & (0xFF00U >> sec_rem_bits)) << 24) + ((s->crc << 16) >> sec_rem_bits)); crc_val = av_crc(crc_tab, crc_val, tmp_buf, 3); diff --git a/libavcodec/mpegpicture.c b/libavcodec/mpegpicture.c index e3f648895d..0652b7c879 100644 --- a/libavcodec/mpegpicture.c +++ b/libavcodec/mpegpicture.c @@ -79,8 +79,11 @@ int ff_mpeg_framesize_alloc(AVCodecContext *avctx, MotionEstContext *me, // linesize * interlaced * MBsize // we also use this buffer for encoding in encode_mb_internal() needig an additional 32 lines if (!FF_ALLOCZ_TYPED_ARRAY(sc->edge_emu_buffer, alloc_size * EMU_EDGE_HEIGHT) || - !FF_ALLOCZ_TYPED_ARRAY(me->scratchpad, alloc_size * 4 * 16 * 2)) + !FF_ALLOCZ_TYPED_ARRAY(me->scratchpad, alloc_size * 4 * 16 * 2)) { + av_freep(&sc->edge_emu_buffer); return AVERROR(ENOMEM); + } + me->temp = me->scratchpad; sc->rd_scratchpad = me->scratchpad; sc->b_scratchpad = me->scratchpad; diff --git a/libavcodec/mpegvideo.c b/libavcodec/mpegvideo.c index 988dd18a33..5de0719f83 100644 --- a/libavcodec/mpegvideo.c +++ b/libavcodec/mpegvideo.c @@ -366,13 +366,6 @@ static int init_duplicate_context(MpegEncContext *s) if (s->mb_height & 1) yc_size += 2*s->b8_stride + 2*s->mb_stride; - s->sc.edge_emu_buffer = - s->me.scratchpad = - s->me.temp = - s->sc.rd_scratchpad = - s->sc.b_scratchpad = - s->sc.obmc_scratchpad = NULL; - if (s->encoding) { if (!FF_ALLOCZ_TYPED_ARRAY(s->me.map, ME_MAP_SIZE) || !FF_ALLOCZ_TYPED_ARRAY(s->me.score_map, ME_MAP_SIZE)) @@ -413,6 +406,35 @@ static int init_duplicate_context(MpegEncContext *s) return 0; } +/** + * Initialize an MpegEncContext's thread contexts. Presumes that + * slice_context_count is already set and that all the fields + * that are freed/reset in free_duplicate_context() are NULL. + */ +static int init_duplicate_contexts(MpegEncContext *s) +{ + int nb_slices = s->slice_context_count, ret; + + /* We initialize the copies before the original so that + * fields allocated in init_duplicate_context are NULL after + * copying. This prevents double-frees upon allocation error. */ + for (int i = 1; i < nb_slices; i++) { + s->thread_context[i] = av_memdup(s, sizeof(MpegEncContext)); + if (!s->thread_context[i]) + return AVERROR(ENOMEM); + if ((ret = init_duplicate_context(s->thread_context[i])) < 0) + return ret; + s->thread_context[i]->start_mb_y = + (s->mb_height * (i ) + nb_slices / 2) / nb_slices; + s->thread_context[i]->end_mb_y = + (s->mb_height * (i + 1) + nb_slices / 2) / nb_slices; + } + s->start_mb_y = 0; + s->end_mb_y = nb_slices > 1 ? (s->mb_height + nb_slices / 2) / nb_slices + : s->mb_height; + return init_duplicate_context(s); +} + static void free_duplicate_context(MpegEncContext *s) { if (!s) @@ -435,6 +457,15 @@ static void free_duplicate_context(MpegEncContext *s) s->block = NULL; } +static void free_duplicate_contexts(MpegEncContext *s) +{ + for (int i = 1; i < s->slice_context_count; i++) { + free_duplicate_context(s->thread_context[i]); + av_freep(&s->thread_context[i]); + } + free_duplicate_context(s); +} + static void backup_duplicate_context(MpegEncContext *bak, MpegEncContext *src) { #define COPY(a) bak->a = src->a @@ -524,7 +555,6 @@ int ff_mpeg_update_thread_context(AVCodecContext *dst, } if (s->height != s1->height || s->width != s1->width || s->context_reinit) { - s->context_reinit = 0; s->height = s1->height; s->width = s1->width; if ((ret = ff_mpv_common_frame_size_change(s)) < 0) @@ -932,53 +962,42 @@ av_cold int ff_mpv_common_init(MpegEncContext *s) for (i = 0; i < MAX_PICTURE_COUNT; i++) { s->picture[i].f = av_frame_alloc(); if (!s->picture[i].f) - return AVERROR(ENOMEM); + goto fail_nomem; } if (!(s->next_picture.f = av_frame_alloc()) || !(s->last_picture.f = av_frame_alloc()) || !(s->current_picture.f = av_frame_alloc()) || !(s->new_picture.f = av_frame_alloc())) - return AVERROR(ENOMEM); + goto fail_nomem; if ((ret = init_context_frame(s))) - return AVERROR(ENOMEM); + goto fail; s->parse_context.state = -1; s->context_initialized = 1; memset(s->thread_context, 0, sizeof(s->thread_context)); s->thread_context[0] = s; + s->slice_context_count = nb_slices; // if (s->width && s->height) { - if (nb_slices > 1) { - for (i = 0; i < nb_slices; i++) { - if (i) { - s->thread_context[i] = av_memdup(s, sizeof(MpegEncContext)); - if (!s->thread_context[i]) - return AVERROR(ENOMEM); - } - if ((ret = init_duplicate_context(s->thread_context[i])) < 0) - return ret; - s->thread_context[i]->start_mb_y = - (s->mb_height * (i) + nb_slices / 2) / nb_slices; - s->thread_context[i]->end_mb_y = - (s->mb_height * (i + 1) + nb_slices / 2) / nb_slices; - } - } else { - if ((ret = init_duplicate_context(s)) < 0) - return ret; - s->start_mb_y = 0; - s->end_mb_y = s->mb_height; - } - s->slice_context_count = nb_slices; + ret = init_duplicate_contexts(s); + if (ret < 0) + goto fail; // } return 0; + fail_nomem: + ret = AVERROR(ENOMEM); + fail: + ff_mpv_common_end(s); + return ret; } /** - * Frees and resets MpegEncContext fields depending on the resolution. + * Frees and resets MpegEncContext fields depending on the resolution + * as well as the slice thread contexts. * Is used during resolution changes to avoid a full reinitialization of the * codec. */ @@ -986,6 +1005,8 @@ static void free_context_frame(MpegEncContext *s) { int i, j, k; + free_duplicate_contexts(s); + av_freep(&s->mb_type); av_freep(&s->p_mv_table_base); av_freep(&s->b_forw_mv_table_base); @@ -1038,16 +1059,6 @@ int ff_mpv_common_frame_size_change(MpegEncContext *s) if (!s->context_initialized) return AVERROR(EINVAL); - if (s->slice_context_count > 1) { - for (i = 0; i < s->slice_context_count; i++) { - free_duplicate_context(s->thread_context[i]); - } - for (i = 1; i < s->slice_context_count; i++) { - av_freep(&s->thread_context[i]); - } - } else - free_duplicate_context(s); - free_context_frame(s); if (s->picture) @@ -1067,42 +1078,33 @@ int ff_mpv_common_frame_size_change(MpegEncContext *s) if ((s->width || s->height) && (err = av_image_check_size(s->width, s->height, 0, s->avctx)) < 0) - return err; + goto fail; + + /* set chroma shifts */ + err = av_pix_fmt_get_chroma_sub_sample(s->avctx->pix_fmt, + &s->chroma_x_shift, + &s->chroma_y_shift); + if (err < 0) + goto fail; if ((err = init_context_frame(s))) - return err; + goto fail; memset(s->thread_context, 0, sizeof(s->thread_context)); s->thread_context[0] = s; if (s->width && s->height) { - int nb_slices = s->slice_context_count; - if (nb_slices > 1) { - for (i = 0; i < nb_slices; i++) { - if (i) { - s->thread_context[i] = av_memdup(s, sizeof(MpegEncContext)); - if (!s->thread_context[i]) { - return AVERROR(ENOMEM); - } - } - if ((err = init_duplicate_context(s->thread_context[i])) < 0) - return err; - s->thread_context[i]->start_mb_y = - (s->mb_height * (i) + nb_slices / 2) / nb_slices; - s->thread_context[i]->end_mb_y = - (s->mb_height * (i + 1) + nb_slices / 2) / nb_slices; - } - } else { - err = init_duplicate_context(s); - if (err < 0) - return err; - s->start_mb_y = 0; - s->end_mb_y = s->mb_height; - } - s->slice_context_count = nb_slices; + err = init_duplicate_contexts(s); + if (err < 0) + goto fail; } + s->context_reinit = 0; return 0; + fail: + free_context_frame(s); + s->context_reinit = 1; + return err; } /* init common structure for both encoder and decoder */ @@ -1113,15 +1115,9 @@ void ff_mpv_common_end(MpegEncContext *s) if (!s) return; - if (s->slice_context_count > 1) { - for (i = 0; i < s->slice_context_count; i++) { - free_duplicate_context(s->thread_context[i]); - } - for (i = 1; i < s->slice_context_count; i++) { - av_freep(&s->thread_context[i]); - } + free_context_frame(s); + if (s->slice_context_count > 1) s->slice_context_count = 1; - } else free_duplicate_context(s); av_freep(&s->parse_context.buffer); s->parse_context.buffer_size = 0; @@ -1153,9 +1149,8 @@ void ff_mpv_common_end(MpegEncContext *s) ff_mpeg_unref_picture(s->avctx, &s->new_picture); av_frame_free(&s->new_picture.f); - free_context_frame(s); - s->context_initialized = 0; + s->context_reinit = 0; s->last_picture_ptr = s->next_picture_ptr = s->current_picture_ptr = NULL; diff --git a/libavcodec/mpegvideo_enc.c b/libavcodec/mpegvideo_enc.c index 7eecfce27c..75086f5368 100644 --- a/libavcodec/mpegvideo_enc.c +++ b/libavcodec/mpegvideo_enc.c @@ -509,9 +509,13 @@ FF_ENABLE_DEPRECATION_WARNINGS if (!s->fixed_qscale && avctx->bit_rate * av_q2d(avctx->time_base) > avctx->bit_rate_tolerance) { + double nbt = avctx->bit_rate * av_q2d(avctx->time_base) * 5; av_log(avctx, AV_LOG_WARNING, "bitrate tolerance %d too small for bitrate %"PRId64", overriding\n", avctx->bit_rate_tolerance, avctx->bit_rate); - avctx->bit_rate_tolerance = 5 * avctx->bit_rate * av_q2d(avctx->time_base); + if (nbt <= INT_MAX) { + avctx->bit_rate_tolerance = nbt; + } else + avctx->bit_rate_tolerance = INT_MAX; } if (avctx->rc_max_rate && @@ -575,6 +579,12 @@ FF_ENABLE_DEPRECATION_WARNINGS av_log(avctx, AV_LOG_ERROR, "H.263 does not support resolutions above 2048x1152\n"); return AVERROR(EINVAL); } + if (s->codec_id == AV_CODEC_ID_FLV1 && + (avctx->width > 65535 || + avctx->height > 65535 )) { + av_log(avctx, AV_LOG_ERROR, "FLV does not support resolutions above 16bit\n"); + return AVERROR(EINVAL); + } if ((s->codec_id == AV_CODEC_ID_H263 || s->codec_id == AV_CODEC_ID_H263P) && ((avctx->width &3) || @@ -627,7 +637,7 @@ FF_ENABLE_DEPRECATION_WARNINGS #if FF_API_PRIVATE_OPT FF_DISABLE_DEPRECATION_WARNINGS if (avctx->mpeg_quant) - s->mpeg_quant = avctx->mpeg_quant; + s->mpeg_quant = 1; FF_ENABLE_DEPRECATION_WARNINGS #endif @@ -1008,8 +1018,7 @@ FF_ENABLE_DEPRECATION_WARNINGS if (CONFIG_H263_ENCODER && s->out_format == FMT_H263) ff_h263_encode_init(s); if (CONFIG_MSMPEG4_ENCODER && s->msmpeg4_version) - if ((ret = ff_msmpeg4_encode_init(s)) < 0) - return ret; + ff_msmpeg4_encode_init(s); if ((CONFIG_MPEG1VIDEO_ENCODER || CONFIG_MPEG2VIDEO_ENCODER) && s->out_format == FMT_MPEG1) ff_mpeg1_encode_init(s); @@ -1256,12 +1265,12 @@ static int load_input_picture(MpegEncContext *s, const AVFrame *pic_arg) &v_chroma_shift); for (i = 0; i < 3; i++) { - int src_stride = pic_arg->linesize[i]; - int dst_stride = i ? s->uvlinesize : s->linesize; + ptrdiff_t src_stride = pic_arg->linesize[i]; + ptrdiff_t dst_stride = i ? s->uvlinesize : s->linesize; int h_shift = i ? h_chroma_shift : 0; int v_shift = i ? v_chroma_shift : 0; - int w = s->width >> h_shift; - int h = s->height >> v_shift; + int w = AV_CEIL_RSHIFT(s->width , h_shift); + int h = AV_CEIL_RSHIFT(s->height, v_shift); uint8_t *src = pic_arg->data[i]; uint8_t *dst = pic->f->data[i]; int vpad = 16; @@ -1275,7 +1284,7 @@ static int load_input_picture(MpegEncContext *s, const AVFrame *pic_arg) dst += INPLACE_OFFSET; if (src_stride == dst_stride) - memcpy(dst, src, src_stride * h); + memcpy(dst, src, src_stride * h - src_stride + w); else { int h2 = h; uint8_t *dst2 = dst; @@ -1318,6 +1327,8 @@ static int load_input_picture(MpegEncContext *s, const AVFrame *pic_arg) /* shift buffer entries */ for (i = flush_offset; i < MAX_PICTURE_COUNT /*s->encoding_delay + 1*/; i++) s->input_picture[i - flush_offset] = s->input_picture[i]; + for (int i = MAX_B_FRAMES + 1 - flush_offset; i <= MAX_B_FRAMES; i++) + s->input_picture[i] = NULL; s->input_picture[encoding_delay] = (Picture*) pic; @@ -1501,7 +1512,7 @@ static int estimate_best_b_count(MpegEncContext *s) goto fail; } - rd += (out_size * lambda2) >> (FF_LAMBDA_SHIFT - 3); + rd += (out_size * (uint64_t)lambda2) >> (FF_LAMBDA_SHIFT - 3); } /* get the delayed frames */ @@ -1510,7 +1521,7 @@ static int estimate_best_b_count(MpegEncContext *s) ret = out_size; goto fail; } - rd += (out_size * lambda2) >> (FF_LAMBDA_SHIFT - 3); + rd += (out_size * (uint64_t)lambda2) >> (FF_LAMBDA_SHIFT - 3); rd += c->error[0] + c->error[1] + c->error[2]; @@ -1696,7 +1707,8 @@ no_output_pic: // input is not a shared pix -> reuse buffer for current_pix s->current_picture_ptr = s->reordered_input_picture[0]; for (i = 0; i < 4; i++) { - s->new_picture.f->data[i] += INPLACE_OFFSET; + if (s->new_picture.f->data[i]) + s->new_picture.f->data[i] += INPLACE_OFFSET; } } ff_mpeg_unref_picture(s->avctx, &s->current_picture); @@ -2016,6 +2028,7 @@ FF_ENABLE_DEPRECATION_WARNINGS break; default: av_log(avctx, AV_LOG_ERROR, "vbv buffer overflow\n"); + s->stuffing_bits = 0; } flush_put_bits(&s->pb); s->frame_bits = put_bits_count(&s->pb); diff --git a/libavcodec/mscc.c b/libavcodec/mscc.c index fe02649623..a2768dd7a1 100644 --- a/libavcodec/mscc.c +++ b/libavcodec/mscc.c @@ -52,6 +52,9 @@ static int rle_uncompress(AVCodecContext *avctx, GetByteContext *gb, PutByteCont unsigned run = bytestream2_get_byte(gb); if (run) { + if (bytestream2_get_bytes_left_p(pb) < run * s->bpp) + return AVERROR_INVALIDDATA; + switch (avctx->bits_per_coded_sample) { case 8: fill = bytestream2_get_byte(gb); @@ -100,6 +103,9 @@ static int rle_uncompress(AVCodecContext *avctx, GetByteContext *gb, PutByteCont bytestream2_seek_p(pb, y * avctx->width * s->bpp + x * s->bpp, SEEK_SET); } else { + if (bytestream2_get_bytes_left_p(pb) < copy * s->bpp) + return AVERROR_INVALIDDATA; + for (j = 0; j < copy; j++) { switch (avctx->bits_per_coded_sample) { case 8: diff --git a/libavcodec/msmpeg4.h b/libavcodec/msmpeg4.h index f9c63b5022..483c965b9d 100644 --- a/libavcodec/msmpeg4.h +++ b/libavcodec/msmpeg4.h @@ -50,7 +50,7 @@ void ff_msmpeg4_encode_motion(MpegEncContext * s, int mx, int my); int ff_msmpeg4_coded_block_pred(MpegEncContext * s, int n, uint8_t **coded_block_ptr); -int ff_msmpeg4_encode_init(MpegEncContext *s); +void ff_msmpeg4_encode_init(MpegEncContext *s); void ff_msmpeg4_encode_picture_header(MpegEncContext *s, int picture_number); void ff_msmpeg4_encode_ext_header(MpegEncContext *s); void ff_msmpeg4_encode_mb(MpegEncContext *s, int16_t block[6][64], diff --git a/libavcodec/msmpeg4dec.c b/libavcodec/msmpeg4dec.c index 405fda4b83..63f9faa1bb 100644 --- a/libavcodec/msmpeg4dec.c +++ b/libavcodec/msmpeg4dec.c @@ -870,7 +870,7 @@ AVCodec ff_msmpeg4v1_decoder = { .close = ff_h263_decode_end, .decode = ff_h263_decode_frame, .capabilities = AV_CODEC_CAP_DRAW_HORIZ_BAND | AV_CODEC_CAP_DR1, - .caps_internal = FF_CODEC_CAP_SKIP_FRAME_FILL_PARAM | FF_CODEC_CAP_INIT_CLEANUP, + .caps_internal = FF_CODEC_CAP_SKIP_FRAME_FILL_PARAM, .max_lowres = 3, .pix_fmts = (const enum AVPixelFormat[]) { AV_PIX_FMT_YUV420P, @@ -888,7 +888,7 @@ AVCodec ff_msmpeg4v2_decoder = { .close = ff_h263_decode_end, .decode = ff_h263_decode_frame, .capabilities = AV_CODEC_CAP_DRAW_HORIZ_BAND | AV_CODEC_CAP_DR1, - .caps_internal = FF_CODEC_CAP_SKIP_FRAME_FILL_PARAM | FF_CODEC_CAP_INIT_CLEANUP, + .caps_internal = FF_CODEC_CAP_SKIP_FRAME_FILL_PARAM, .max_lowres = 3, .pix_fmts = (const enum AVPixelFormat[]) { AV_PIX_FMT_YUV420P, @@ -906,7 +906,7 @@ AVCodec ff_msmpeg4v3_decoder = { .close = ff_h263_decode_end, .decode = ff_h263_decode_frame, .capabilities = AV_CODEC_CAP_DRAW_HORIZ_BAND | AV_CODEC_CAP_DR1, - .caps_internal = FF_CODEC_CAP_SKIP_FRAME_FILL_PARAM | FF_CODEC_CAP_INIT_CLEANUP, + .caps_internal = FF_CODEC_CAP_SKIP_FRAME_FILL_PARAM, .max_lowres = 3, .pix_fmts = (const enum AVPixelFormat[]) { AV_PIX_FMT_YUV420P, @@ -924,7 +924,7 @@ AVCodec ff_wmv1_decoder = { .close = ff_h263_decode_end, .decode = ff_h263_decode_frame, .capabilities = AV_CODEC_CAP_DRAW_HORIZ_BAND | AV_CODEC_CAP_DR1, - .caps_internal = FF_CODEC_CAP_SKIP_FRAME_FILL_PARAM | FF_CODEC_CAP_INIT_CLEANUP, + .caps_internal = FF_CODEC_CAP_SKIP_FRAME_FILL_PARAM, .max_lowres = 3, .pix_fmts = (const enum AVPixelFormat[]) { AV_PIX_FMT_YUV420P, diff --git a/libavcodec/msmpeg4enc.c b/libavcodec/msmpeg4enc.c index 5f809c2aeb..59a18532c2 100644 --- a/libavcodec/msmpeg4enc.c +++ b/libavcodec/msmpeg4enc.c @@ -32,7 +32,6 @@ #include "libavutil/attributes.h" #include "libavutil/avutil.h" -#include "libavutil/mem.h" #include "mpegvideo.h" #include "h263.h" #include "internal.h" @@ -46,13 +45,11 @@ static uint8_t rl_length[NB_RL_TABLES][MAX_LEVEL+1][MAX_RUN+1][2]; /* build the table which associate a (x,y) motion vector to a vlc */ -static av_cold int init_mv_table(MVTable *tab) +static av_cold void init_mv_table(MVTable *tab, uint16_t table_mv_index[4096]) { int i, x, y; - tab->table_mv_index = av_malloc(sizeof(uint16_t) * 4096); - if (!tab->table_mv_index) - return AVERROR(ENOMEM); + tab->table_mv_index = table_mv_index; /* mark all entries as not used */ for(i=0;i<4096;i++) @@ -63,8 +60,6 @@ static av_cold int init_mv_table(MVTable *tab) y = tab->table_mvy[i]; tab->table_mv_index[(x << 6) | y] = i; } - - return 0; } void ff_msmpeg4_code012(PutBitContext *pb, int n) @@ -118,10 +113,10 @@ static int get_size_of_code(MpegEncContext * s, RLTable *rl, int last, int run, return size; } -av_cold int ff_msmpeg4_encode_init(MpegEncContext *s) +av_cold void ff_msmpeg4_encode_init(MpegEncContext *s) { static int init_done=0; - int i, ret; + int i; ff_msmpeg4_common_init(s); if(s->msmpeg4_version>=4){ @@ -130,12 +125,12 @@ av_cold int ff_msmpeg4_encode_init(MpegEncContext *s) } if (!init_done) { + static uint16_t mv_index_tables[2][4096]; /* init various encoding tables */ init_done = 1; - if ((ret = init_mv_table(&ff_mv_tables[0])) < 0) - return ret; - if ((ret = init_mv_table(&ff_mv_tables[1])) < 0) - return ret; + init_mv_table(&ff_mv_tables[0], mv_index_tables[0]); + init_mv_table(&ff_mv_tables[1], mv_index_tables[1]); + for(i=0;idata[0] + y * p->linesize[0] + x, gb.buffer, FFMIN(size, width - x)); bytestream2_skip(&gb, size); } else { diff --git a/libavcodec/mss12.c b/libavcodec/mss12.c index 5a5bd9a91b..5afdaacfe6 100644 --- a/libavcodec/mss12.c +++ b/libavcodec/mss12.c @@ -291,14 +291,15 @@ static int decode_pixel_in_context(ArithCoder *acoder, PixContext *pctx, return decode_pixel(acoder, pctx, ref_pix, nlen, 1); } -static int decode_region(ArithCoder *acoder, uint8_t *dst, uint8_t *rgb_pic, +static int decode_region(ArithCoder *acoder, uint8_t *dst, uint8_t *rgb_dst, int x, int y, int width, int height, ptrdiff_t stride, ptrdiff_t rgb_stride, PixContext *pctx, const uint32_t *pal) { int i, j, p; - uint8_t *rgb_dst = rgb_pic + x * 3 + y * rgb_stride; + rgb_stride = rgb_dst ? rgb_stride : 0; + rgb_dst = rgb_dst ? rgb_dst + x * 3 + y * rgb_stride : NULL; dst += x + y * stride; for (j = 0; j < height; j++) { @@ -312,11 +313,11 @@ static int decode_region(ArithCoder *acoder, uint8_t *dst, uint8_t *rgb_pic, return p; dst[i] = p; - if (rgb_pic) + if (rgb_dst) AV_WB24(rgb_dst + i * 3, pal[p]); } dst += stride; - rgb_dst += rgb_stride; + rgb_dst = FF_PTR_ADD(rgb_dst, rgb_stride); } return 0; @@ -476,17 +477,19 @@ static int decode_region_intra(SliceContext *sc, ArithCoder *acoder, ptrdiff_t stride = c->pal_stride; ptrdiff_t rgb_stride = c->rgb_stride; uint8_t *dst = c->pal_pic + x + y * stride; - uint8_t *rgb_dst = c->rgb_pic + x * 3 + y * rgb_stride; + uint8_t *rgb_dst = c->rgb_pic ? c->rgb_pic + x * 3 + y * rgb_stride : NULL; pix = decode_pixel(acoder, &sc->intra_pix_ctx, NULL, 0, 0); if (pix < 0) return pix; rgb_pix = c->pal[pix]; - for (i = 0; i < height; i++, dst += stride, rgb_dst += rgb_stride) { + for (i = 0; i < height; i++, dst += stride) { memset(dst, pix, width); - if (c->rgb_pic) + if (rgb_dst) { for (j = 0; j < width * 3; j += 3) AV_WB24(rgb_dst + j, rgb_pix); + rgb_dst += rgb_stride; + } } } else { return decode_region(acoder, c->pal_pic, c->rgb_pic, diff --git a/libavcodec/mss4.c b/libavcodec/mss4.c index 7f11f30dc8..4ad653c443 100644 --- a/libavcodec/mss4.c +++ b/libavcodec/mss4.c @@ -26,6 +26,7 @@ */ #include "libavutil/thread.h" +#include "libavutil/imgutils.h" #include "avcodec.h" #include "bytestream.h" @@ -476,6 +477,9 @@ static int mss4_decode_frame(AVCodecContext *avctx, void *data, int *got_frame, width, height); return AVERROR_INVALIDDATA; } + if (av_image_check_size2(width, height, avctx->max_pixels, AV_PIX_FMT_NONE, 0, avctx) < 0) + return AVERROR_INVALIDDATA; + if (quality < 1 || quality > 100) { av_log(avctx, AV_LOG_ERROR, "Invalid quality setting %d\n", quality); return AVERROR_INVALIDDATA; diff --git a/libavcodec/mvha.c b/libavcodec/mvha.c index c603ef6975..caae39da97 100644 --- a/libavcodec/mvha.c +++ b/libavcodec/mvha.c @@ -187,6 +187,8 @@ static int decode_frame(AVCodecContext *avctx, av_log(avctx, AV_LOG_ERROR, "Inflate error: %d\n", ret); return AVERROR_EXTERNAL; } + if (s->zstream.avail_out > 0) + memset(s->zstream.next_out, 0, s->zstream.avail_out); } } } else if (type == MKTAG('H','U','F','Y')) { diff --git a/libavcodec/mwsc.c b/libavcodec/mwsc.c index 4db7642e85..94554ebd4a 100644 --- a/libavcodec/mwsc.c +++ b/libavcodec/mwsc.c @@ -50,6 +50,10 @@ static int rle_uncompress(GetByteContext *gb, PutByteContext *pb, GetByteContext if (run == 0) { run = bytestream2_get_le32(gb); + + if (bytestream2_tell_p(pb) + width - w < run) + return AVERROR_INVALIDDATA; + for (int j = 0; j < run; j++, w++) { if (w == width) { w = 0; @@ -61,6 +65,10 @@ static int rle_uncompress(GetByteContext *gb, PutByteContext *pb, GetByteContext int pos = bytestream2_tell_p(pb); bytestream2_seek(gbp, pos, SEEK_SET); + + if (pos + width - w < fill) + return AVERROR_INVALIDDATA; + for (int j = 0; j < fill; j++, w++) { if (w == width) { w = 0; @@ -72,6 +80,9 @@ static int rle_uncompress(GetByteContext *gb, PutByteContext *pb, GetByteContext intra = 0; } else { + if (bytestream2_tell_p(pb) + width - w < run) + return AVERROR_INVALIDDATA; + for (int j = 0; j < run; j++, w++) { if (w == width) { w = 0; diff --git a/libavcodec/mxpegdec.c b/libavcodec/mxpegdec.c index 763ce5871d..a068baf758 100644 --- a/libavcodec/mxpegdec.c +++ b/libavcodec/mxpegdec.c @@ -193,6 +193,9 @@ static int mxpeg_decode_frame(AVCodecContext *avctx, int start_code; int ret; + if (avctx->skip_frame == AVDISCARD_ALL) + return AVERROR_PATCHWELCOME; + buf_ptr = buf; buf_end = buf + buf_size; jpg->got_picture = 0; diff --git a/libavcodec/nellymoserenc.c b/libavcodec/nellymoserenc.c index 99ede2f42b..8670431dcc 100644 --- a/libavcodec/nellymoserenc.c +++ b/libavcodec/nellymoserenc.c @@ -138,10 +138,8 @@ static av_cold int encode_end(AVCodecContext *avctx) ff_mdct_end(&s->mdct_ctx); - if (s->avctx->trellis) { - av_freep(&s->opt); - av_freep(&s->path); - } + av_freep(&s->opt); + av_freep(&s->path); ff_af_queue_close(&s->afq); av_freep(&s->fdsp); diff --git a/libavcodec/noise_bsf.c b/libavcodec/noise_bsf.c index 6ebd369633..2a60b29023 100644 --- a/libavcodec/noise_bsf.c +++ b/libavcodec/noise_bsf.c @@ -42,6 +42,11 @@ static int noise(AVBSFContext *ctx, AVPacket *pkt) if (amount <= 0) return AVERROR(EINVAL); + if (ctx->par_in->codec_id == AV_CODEC_ID_WRAPPED_AVFRAME) { + av_log(ctx, AV_LOG_ERROR, "Wrapped AVFrame noising is unsupported\n"); + return AVERROR_PATCHWELCOME; + } + ret = ff_bsf_get_packet_ref(ctx, pkt); if (ret < 0) return ret; diff --git a/libavcodec/notchlc.c b/libavcodec/notchlc.c index 9a53cad9cb..15b383d626 100644 --- a/libavcodec/notchlc.c +++ b/libavcodec/notchlc.c @@ -92,6 +92,9 @@ static int lz4_decompress(AVCodecContext *avctx, } while (current == 255); } + if (bytestream2_get_bytes_left(gb) < num_literals) + return AVERROR_INVALIDDATA; + if (pos + num_literals < HISTORY_SIZE) { bytestream2_get_buffer(gb, history + pos, num_literals); pos += num_literals; @@ -242,7 +245,9 @@ static int decode_blocks(AVCodecContext *avctx, AVFrame *p, ThreadFrame *frame, bytestream2_seek(&dgb, s->y_data_offset + row_offset, SEEK_SET); - init_get_bits8(&bit, dgb.buffer, bytestream2_get_bytes_left(&dgb)); + ret = init_get_bits8(&bit, dgb.buffer, bytestream2_get_bytes_left(&dgb)); + if (ret < 0) + return ret; for (int x = 0; x < avctx->width; x += 4) { unsigned item = bytestream2_get_le32(gb); unsigned y_min = item & 4095; diff --git a/libavcodec/nvdec.c b/libavcodec/nvdec.c index d6b6608866..caf9715707 100644 --- a/libavcodec/nvdec.c +++ b/libavcodec/nvdec.c @@ -263,8 +263,8 @@ int ff_nvdec_decode_uninit(AVCodecContext *avctx) { NVDECContext *ctx = avctx->internal->hwaccel_priv_data; - av_freep(&ctx->bitstream); av_freep(&ctx->bitstream_internal); + ctx->bitstream = NULL; ctx->bitstream_len = 0; ctx->bitstream_allocated = 0; @@ -667,6 +667,8 @@ int ff_nvdec_simple_end_frame(AVCodecContext *avctx) NVDECContext *ctx = avctx->internal->hwaccel_priv_data; int ret = ff_nvdec_end_frame(avctx); ctx->bitstream = NULL; + ctx->bitstream_len = 0; + ctx->nb_slices = 0; return ret; } diff --git a/libavcodec/nvdec_h264.c b/libavcodec/nvdec_h264.c index 116bd4fb5d..a9ccd6d53b 100644 --- a/libavcodec/nvdec_h264.c +++ b/libavcodec/nvdec_h264.c @@ -137,11 +137,11 @@ static int nvdec_h264_decode_slice(AVCodecContext *avctx, const uint8_t *buffer, const H264SliceContext *sl = &h->slice_ctx[0]; void *tmp; - tmp = av_fast_realloc(ctx->bitstream, &ctx->bitstream_allocated, + tmp = av_fast_realloc(ctx->bitstream_internal, &ctx->bitstream_allocated, ctx->bitstream_len + size + 3); if (!tmp) return AVERROR(ENOMEM); - ctx->bitstream = tmp; + ctx->bitstream = ctx->bitstream_internal = tmp; tmp = av_fast_realloc(ctx->slice_offsets, &ctx->slice_offsets_allocated, (ctx->nb_slices + 1) * sizeof(*ctx->slice_offsets)); diff --git a/libavcodec/nvdec_hevc.c b/libavcodec/nvdec_hevc.c index 590278ba04..1f2b5ae9d0 100644 --- a/libavcodec/nvdec_hevc.c +++ b/libavcodec/nvdec_hevc.c @@ -273,11 +273,11 @@ static int nvdec_hevc_decode_slice(AVCodecContext *avctx, const uint8_t *buffer, NVDECContext *ctx = avctx->internal->hwaccel_priv_data; void *tmp; - tmp = av_fast_realloc(ctx->bitstream, &ctx->bitstream_allocated, + tmp = av_fast_realloc(ctx->bitstream_internal, &ctx->bitstream_allocated, ctx->bitstream_len + size + 3); if (!tmp) return AVERROR(ENOMEM); - ctx->bitstream = tmp; + ctx->bitstream = ctx->bitstream_internal = tmp; tmp = av_fast_realloc(ctx->slice_offsets, &ctx->slice_offsets_allocated, (ctx->nb_slices + 1) * sizeof(*ctx->slice_offsets)); diff --git a/libavcodec/nvdec_mpeg12.c b/libavcodec/nvdec_mpeg12.c index 9a9030d8d3..746d720888 100644 --- a/libavcodec/nvdec_mpeg12.c +++ b/libavcodec/nvdec_mpeg12.c @@ -80,8 +80,9 @@ static int nvdec_mpeg12_start_frame(AVCodecContext *avctx, const uint8_t *buffer }; for (i = 0; i < 64; ++i) { - ppc->QuantMatrixIntra[i] = s->intra_matrix[i]; - ppc->QuantMatrixInter[i] = s->inter_matrix[i]; + int n = s->idsp.idct_permutation[i]; + ppc->QuantMatrixIntra[i] = s->intra_matrix[n]; + ppc->QuantMatrixInter[i] = s->inter_matrix[n]; } return 0; diff --git a/libavcodec/nvdec_mpeg4.c b/libavcodec/nvdec_mpeg4.c index 739b049933..5404e4e330 100644 --- a/libavcodec/nvdec_mpeg4.c +++ b/libavcodec/nvdec_mpeg4.c @@ -86,8 +86,9 @@ static int nvdec_mpeg4_start_frame(AVCodecContext *avctx, const uint8_t *buffer, }; for (i = 0; i < 64; ++i) { - ppc->QuantMatrixIntra[i] = s->intra_matrix[i]; - ppc->QuantMatrixInter[i] = s->inter_matrix[i]; + int n = s->idsp.idct_permutation[i]; + ppc->QuantMatrixIntra[i] = s->intra_matrix[n]; + ppc->QuantMatrixInter[i] = s->inter_matrix[n]; } // We need to pass the full frame buffer and not just the slice diff --git a/libavcodec/nvenc.c b/libavcodec/nvenc.c index dddee8cac1..c6498864c8 100644 --- a/libavcodec/nvenc.c +++ b/libavcodec/nvenc.c @@ -144,6 +144,70 @@ static int nvenc_print_error(AVCodecContext *avctx, NVENCSTATUS err, return ret; } +typedef struct GUIDTuple { + const GUID guid; + int flags; +} GUIDTuple; + +#define PRESET_ALIAS(alias, name, ...) \ + [PRESET_ ## alias] = { NV_ENC_PRESET_ ## name ## _GUID, __VA_ARGS__ } + +#define PRESET(name, ...) PRESET_ALIAS(name, name, __VA_ARGS__) + +static void nvenc_map_preset(NvencContext *ctx) +{ + GUIDTuple presets[] = { +#ifdef NVENC_HAVE_NEW_PRESETS + PRESET(P1), + PRESET(P2), + PRESET(P3), + PRESET(P4), + PRESET(P5), + PRESET(P6), + PRESET(P7), + PRESET_ALIAS(SLOW, P7, NVENC_TWO_PASSES), + PRESET_ALIAS(MEDIUM, P4, NVENC_ONE_PASS), + PRESET_ALIAS(FAST, P1, NVENC_ONE_PASS), + // Compat aliases + PRESET_ALIAS(DEFAULT, P4, NVENC_DEPRECATED_PRESET), + PRESET_ALIAS(HP, P1, NVENC_DEPRECATED_PRESET), + PRESET_ALIAS(HQ, P7, NVENC_DEPRECATED_PRESET), + PRESET_ALIAS(BD, P5, NVENC_DEPRECATED_PRESET), + PRESET_ALIAS(LOW_LATENCY_DEFAULT, P4, NVENC_DEPRECATED_PRESET | NVENC_LOWLATENCY), + PRESET_ALIAS(LOW_LATENCY_HP, P1, NVENC_DEPRECATED_PRESET | NVENC_LOWLATENCY), + PRESET_ALIAS(LOW_LATENCY_HQ, P7, NVENC_DEPRECATED_PRESET | NVENC_LOWLATENCY), + PRESET_ALIAS(LOSSLESS_DEFAULT, P4, NVENC_DEPRECATED_PRESET | NVENC_LOSSLESS), + PRESET_ALIAS(LOSSLESS_HP, P1, NVENC_DEPRECATED_PRESET | NVENC_LOSSLESS), +#else + PRESET(DEFAULT), + PRESET(HP), + PRESET(HQ), + PRESET(BD), + PRESET_ALIAS(SLOW, HQ, NVENC_TWO_PASSES), + PRESET_ALIAS(MEDIUM, HQ, NVENC_ONE_PASS), + PRESET_ALIAS(FAST, HP, NVENC_ONE_PASS), + PRESET(LOW_LATENCY_DEFAULT, NVENC_LOWLATENCY), + PRESET(LOW_LATENCY_HP, NVENC_LOWLATENCY), + PRESET(LOW_LATENCY_HQ, NVENC_LOWLATENCY), + PRESET(LOSSLESS_DEFAULT, NVENC_LOSSLESS), + PRESET(LOSSLESS_HP, NVENC_LOSSLESS), +#endif + }; + + GUIDTuple *t = &presets[ctx->preset]; + + ctx->init_encode_params.presetGUID = t->guid; + ctx->flags = t->flags; + +#ifdef NVENC_HAVE_NEW_PRESETS + if (ctx->tuning_info == NV_ENC_TUNING_INFO_LOSSLESS) + ctx->flags |= NVENC_LOSSLESS; +#endif +} + +#undef PRESET +#undef PRESET_ALIAS + static void nvenc_print_driver_requirement(AVCodecContext *avctx, int level) { #if NVENCAPI_CHECK_VERSION(11, 1) @@ -358,7 +422,7 @@ static int nvenc_check_capabilities(AVCodecContext *avctx) } ret = nvenc_check_cap(avctx, NV_ENC_CAPS_SUPPORT_LOSSLESS_ENCODE); - if (ctx->preset >= PRESET_LOSSLESS_DEFAULT && ret <= 0) { + if (ctx->flags & NVENC_LOSSLESS && ret <= 0) { av_log(avctx, AV_LOG_WARNING, "Lossless encoding not supported\n"); return AVERROR(ENOSYS); } @@ -548,6 +612,11 @@ static av_cold int nvenc_setup_device(AVCodecContext *avctx) return AVERROR_BUG; } + nvenc_map_preset(ctx); + + if (ctx->flags & NVENC_DEPRECATED_PRESET) + av_log(avctx, AV_LOG_WARNING, "The selected preset is deprecated. Use p1 to p7 + -tune or fast/medium/slow.\n"); + if (avctx->pix_fmt == AV_PIX_FMT_CUDA || avctx->pix_fmt == AV_PIX_FMT_D3D11 || avctx->hw_frames_ctx || avctx->hw_device_ctx) { AVHWFramesContext *frames_ctx; AVHWDeviceContext *hwdev_ctx; @@ -638,65 +707,6 @@ static av_cold int nvenc_setup_device(AVCodecContext *avctx) return 0; } -typedef struct GUIDTuple { - const GUID guid; - int flags; -} GUIDTuple; - -#define PRESET_ALIAS(alias, name, ...) \ - [PRESET_ ## alias] = { NV_ENC_PRESET_ ## name ## _GUID, __VA_ARGS__ } - -#define PRESET(name, ...) PRESET_ALIAS(name, name, __VA_ARGS__) - -static void nvenc_map_preset(NvencContext *ctx) -{ - GUIDTuple presets[] = { -#ifdef NVENC_HAVE_NEW_PRESETS - PRESET(P1), - PRESET(P2), - PRESET(P3), - PRESET(P4), - PRESET(P5), - PRESET(P6), - PRESET(P7), - PRESET_ALIAS(SLOW, P7, NVENC_TWO_PASSES), - PRESET_ALIAS(MEDIUM, P4, NVENC_ONE_PASS), - PRESET_ALIAS(FAST, P1, NVENC_ONE_PASS), - // Compat aliases - PRESET_ALIAS(DEFAULT, P4, NVENC_DEPRECATED_PRESET), - PRESET_ALIAS(HP, P1, NVENC_DEPRECATED_PRESET), - PRESET_ALIAS(HQ, P7, NVENC_DEPRECATED_PRESET), - PRESET_ALIAS(BD, P5, NVENC_DEPRECATED_PRESET), - PRESET_ALIAS(LOW_LATENCY_DEFAULT, P4, NVENC_DEPRECATED_PRESET | NVENC_LOWLATENCY), - PRESET_ALIAS(LOW_LATENCY_HP, P1, NVENC_DEPRECATED_PRESET | NVENC_LOWLATENCY), - PRESET_ALIAS(LOW_LATENCY_HQ, P7, NVENC_DEPRECATED_PRESET | NVENC_LOWLATENCY), - PRESET_ALIAS(LOSSLESS_DEFAULT, P4, NVENC_DEPRECATED_PRESET | NVENC_LOSSLESS), - PRESET_ALIAS(LOSSLESS_HP, P1, NVENC_DEPRECATED_PRESET | NVENC_LOSSLESS), -#else - PRESET(DEFAULT), - PRESET(HP), - PRESET(HQ), - PRESET(BD), - PRESET_ALIAS(SLOW, HQ, NVENC_TWO_PASSES), - PRESET_ALIAS(MEDIUM, HQ, NVENC_ONE_PASS), - PRESET_ALIAS(FAST, HP, NVENC_ONE_PASS), - PRESET(LOW_LATENCY_DEFAULT, NVENC_LOWLATENCY), - PRESET(LOW_LATENCY_HP, NVENC_LOWLATENCY), - PRESET(LOW_LATENCY_HQ, NVENC_LOWLATENCY), - PRESET(LOSSLESS_DEFAULT, NVENC_LOSSLESS), - PRESET(LOSSLESS_HP, NVENC_LOSSLESS), -#endif - }; - - GUIDTuple *t = &presets[ctx->preset]; - - ctx->init_encode_params.presetGUID = t->guid; - ctx->flags = t->flags; -} - -#undef PRESET -#undef PRESET_ALIAS - static av_cold void set_constqp(AVCodecContext *avctx) { NvencContext *ctx = avctx->priv_data; @@ -1015,8 +1025,9 @@ static av_cold void nvenc_setup_rate_control(AVCodecContext *avctx) av_log(avctx, AV_LOG_VERBOSE, "CQ(%d) mode enabled.\n", tmp_quality); - //CQ mode shall discard avg bitrate & honor max bitrate; + // CQ mode shall discard avg bitrate/vbv buffer size and honor only max bitrate ctx->encode_config.rcParams.averageBitRate = avctx->bit_rate = 0; + ctx->encode_config.rcParams.vbvBufferSize = avctx->rc_buffer_size = 0; ctx->encode_config.rcParams.maxBitRate = avctx->rc_max_rate; } } @@ -1254,18 +1265,15 @@ static av_cold int nvenc_setup_encoder(AVCodecContext *avctx) ctx->init_encode_params.encodeConfig = &ctx->encode_config; - nvenc_map_preset(ctx); - - if (ctx->flags & NVENC_DEPRECATED_PRESET) - av_log(avctx, AV_LOG_WARNING, "The selected preset is deprecated. Use p1 to p7 + -tune or fast/medium/slow.\n"); - preset_config.version = NV_ENC_PRESET_CONFIG_VER; preset_config.presetCfg.version = NV_ENC_CONFIG_VER; #ifdef NVENC_HAVE_NEW_PRESETS ctx->init_encode_params.tuningInfo = ctx->tuning_info; - if (ctx->flags & NVENC_LOWLATENCY) + if (ctx->flags & NVENC_LOSSLESS) + ctx->init_encode_params.tuningInfo = NV_ENC_TUNING_INFO_LOSSLESS; + else if (ctx->flags & NVENC_LOWLATENCY) ctx->init_encode_params.tuningInfo = NV_ENC_TUNING_INFO_LOW_LATENCY; nv_status = p_nvenc->nvEncGetEncodePresetConfigEx(ctx->nvencoder, @@ -1307,9 +1315,6 @@ static av_cold int nvenc_setup_encoder(AVCodecContext *avctx) * */ if (ctx->rc_lookahead == 0 && ctx->encode_config.rcParams.enableLookahead) ctx->rc_lookahead = ctx->encode_config.rcParams.lookaheadDepth; - - if (ctx->init_encode_params.tuningInfo == NV_ENC_TUNING_INFO_LOSSLESS) - ctx->flags |= NVENC_LOSSLESS; #endif if (ctx->weighted_pred == 1) @@ -1756,7 +1761,7 @@ static int nvenc_register_frame(AVCodecContext *avctx, const AVFrame *frame) NV_ENCODE_API_FUNCTION_LIST *p_nvenc = &dl_fn->nvenc_funcs; AVHWFramesContext *frames_ctx = (AVHWFramesContext*)frame->hw_frames_ctx->data; - NV_ENC_REGISTER_RESOURCE reg; + NV_ENC_REGISTER_RESOURCE reg = { 0 }; int i, idx, ret; for (i = 0; i < ctx->nb_registered_frames; i++) { @@ -1921,7 +1926,7 @@ static int nvenc_set_timestamp(AVCodecContext *avctx, pkt->pts = params->outputTimeStamp; pkt->dts = timestamp_queue_dequeue(ctx->timestamp_list); - pkt->dts -= FFMAX(ctx->encode_config.frameIntervalP - 1, 0) * FFMAX(avctx->ticks_per_frame, 1); + pkt->dts -= FFMAX(ctx->encode_config.frameIntervalP - 1, 0) * FFMAX(avctx->ticks_per_frame, 1) * FFMAX(avctx->time_base.num, 1); return 0; } diff --git a/libavcodec/nvenc.h b/libavcodec/nvenc.h index fefc5f7f0b..314c270e74 100644 --- a/libavcodec/nvenc.h +++ b/libavcodec/nvenc.h @@ -103,7 +103,7 @@ enum { PRESET_LOW_LATENCY_DEFAULT , PRESET_LOW_LATENCY_HQ , PRESET_LOW_LATENCY_HP, - PRESET_LOSSLESS_DEFAULT, // lossless presets must be the last ones + PRESET_LOSSLESS_DEFAULT, PRESET_LOSSLESS_HP, #ifdef NVENC_HAVE_NEW_PRESETS PRESET_P1, diff --git a/libavcodec/nvenc_hevc.c b/libavcodec/nvenc_hevc.c index 441e7871d2..82fbb23bf7 100644 --- a/libavcodec/nvenc_hevc.c +++ b/libavcodec/nvenc_hevc.c @@ -148,7 +148,7 @@ static const AVOption options[] = { { "middle", "", 0, AV_OPT_TYPE_CONST, { .i64 = 2 }, 0, 0, VE, "b_ref_mode" }, #endif { "a53cc", "Use A53 Closed Captions (if available)", OFFSET(a53_cc), AV_OPT_TYPE_BOOL, { .i64 = 1 }, 0, 1, VE }, - { "s12m_tc", "Use timecode (if available)", OFFSET(s12m_tc), AV_OPT_TYPE_BOOL, { .i64 = 1 }, 0, 1, VE }, + { "s12m_tc", "Use timecode (if available)", OFFSET(s12m_tc), AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, VE }, { "dpb_size", "Specifies the DPB size used for encoding (0 means automatic)", OFFSET(dpb_size), AV_OPT_TYPE_INT, { .i64 = 0 }, 0, INT_MAX, VE }, #ifdef NVENC_HAVE_MULTIPASS diff --git a/libavcodec/opus_silk.c b/libavcodec/opus_silk.c index 913053c5e2..8523b55ada 100644 --- a/libavcodec/opus_silk.c +++ b/libavcodec/opus_silk.c @@ -198,7 +198,8 @@ static inline int silk_is_lpc_stable(const int16_t lpc[16], int order) } } -static void silk_lsp2poly(const int32_t lsp[16], int32_t pol[16], int half_order) +static void silk_lsp2poly(const int32_t lsp[/* 2 * half_order - 1 */], + int32_t pol[/* half_order + 1 */], int half_order) { int i, j; diff --git a/libavcodec/parser.c b/libavcodec/parser.c index f4bc00da7d..f3d07cd0ae 100644 --- a/libavcodec/parser.c +++ b/libavcodec/parser.c @@ -179,6 +179,9 @@ int av_parser_parse2(AVCodecParserContext *s, AVCodecContext *avctx, /* offset of the next frame */ s->next_frame_offset = s->cur_offset + index; s->fetch_timestamp = 1; + } else { + /* Don't return a pointer to dummy_buf. */ + *poutbuf = NULL; } if (index < 0) index = 0; @@ -268,6 +271,7 @@ int ff_combine_frame(ParseContext *pc, int next, } pc->buffer = new_buffer; memcpy(&pc->buffer[pc->index], *buf, *buf_size); + memset(&pc->buffer[pc->index + *buf_size], 0, AV_INPUT_BUFFER_PADDING_SIZE); pc->index += *buf_size; return -1; } diff --git a/libavcodec/pictordec.c b/libavcodec/pictordec.c index 6340902526..4d81c311c3 100644 --- a/libavcodec/pictordec.c +++ b/libavcodec/pictordec.c @@ -245,8 +245,6 @@ static int decode_frame(AVCodecContext *avctx, run = bytestream2_get_le16(&s->g); val = bytestream2_get_byte(&s->g); } - if (!bytestream2_get_bytes_left(&s->g)) - break; if (bits_per_plane == 8) { picmemset_8bpp(s, frame, val, run, &x, &y); diff --git a/libavcodec/pixlet.c b/libavcodec/pixlet.c index ad9d830af7..488672f921 100644 --- a/libavcodec/pixlet.c +++ b/libavcodec/pixlet.c @@ -231,8 +231,8 @@ static int read_high_coeffs(AVCodecContext *avctx, uint8_t *src, int16_t *dst, if (cnt1 >= length) { cnt1 = get_bits(bc, nbits); } else { - pfx = 14 + ((((uint64_t)(value - 14)) >> 32) & (value - 14)); - if (pfx < 1 || pfx > 25) + pfx = FFMIN(value, 14); + if (pfx < 1) return AVERROR_INVALIDDATA; cnt1 *= (1 << pfx) - 1; shbits = show_bits(bc, pfx); @@ -405,7 +405,7 @@ static void filterfn(int16_t *dest, int16_t *tmp, unsigned size, int64_t scale) (int64_t) low [i - 1] * -INT64_C(325392907) + (int64_t) high[i + 0] * INT64_C(1518500249) + (int64_t) high[i - 1] * INT64_C(1518500249); - dest[i * 2] = av_clip_int16(((value >> 32) * scale) >> 32); + dest[i * 2] = av_clip_int16(((value >> 32) * (uint64_t)scale) >> 32); } for (i = 0; i < hsize; i++) { @@ -416,7 +416,7 @@ static void filterfn(int16_t *dest, int16_t *tmp, unsigned size, int64_t scale) (int64_t) high[i + 1] * INT64_C(303700064) + (int64_t) high[i + 0] * -INT64_C(3644400640) + (int64_t) high[i - 1] * INT64_C(303700064); - dest[i * 2 + 1] = av_clip_int16(((value >> 32) * scale) >> 32); + dest[i * 2 + 1] = av_clip_int16(((value >> 32) * (uint64_t)scale) >> 32); } } diff --git a/libavcodec/pngdec.c b/libavcodec/pngdec.c index 63c22063d9..9e9f5c2219 100644 --- a/libavcodec/pngdec.c +++ b/libavcodec/pngdec.c @@ -57,6 +57,18 @@ typedef struct PNGDecContext { ThreadFrame last_picture; ThreadFrame picture; + AVDictionary *frame_metadata; + + uint8_t iccp_name[82]; + uint8_t *iccp_data; + size_t iccp_data_len; + + int stereo_mode; + + int have_chrm; + uint32_t white_point[2]; + uint32_t display_primaries[3][2]; + enum PNGHeaderState hdr_state; enum PNGImageState pic_state; int width, height; @@ -77,8 +89,8 @@ typedef struct PNGDecContext { int has_trns; uint8_t transparent_color_be[6]; - uint8_t *image_buf; - int image_linesize; + uint8_t *background_buf; + unsigned background_buf_allocated; uint32_t palette[256]; uint8_t *crow_buf; uint8_t *last_row; @@ -310,7 +322,7 @@ void ff_png_filter_row(PNGDSPContext *dsp, uint8_t *dst, int filter_type, static void deloco_ ## NAME(TYPE *dst, int size, int alpha) \ { \ int i; \ - for (i = 0; i < size; i += 3 + alpha) { \ + for (i = 0; i < size - 2; i += 3 + alpha) { \ int g = dst [i + 1]; \ dst[i + 0] += g; \ dst[i + 2] += g; \ @@ -330,27 +342,27 @@ static int percent_missing(PNGDecContext *s) } /* process exactly one decompressed row */ -static void png_handle_row(PNGDecContext *s) +static void png_handle_row(PNGDecContext *s, uint8_t *dst, ptrdiff_t dst_stride) { uint8_t *ptr, *last_row; int got_line; if (!s->interlace_type) { - ptr = s->image_buf + s->image_linesize * (s->y + s->y_offset) + s->x_offset * s->bpp; + ptr = dst + dst_stride * (s->y + s->y_offset) + s->x_offset * s->bpp; if (s->y == 0) last_row = s->last_row; else - last_row = ptr - s->image_linesize; + last_row = ptr - dst_stride; ff_png_filter_row(&s->dsp, ptr, s->crow_buf[0], s->crow_buf + 1, last_row, s->row_size, s->bpp); /* loco lags by 1 row so that it doesn't interfere with top prediction */ if (s->filter_type == PNG_FILTER_TYPE_LOCO && s->y > 0) { if (s->bit_depth == 16) { - deloco_rgb16((uint16_t *)(ptr - s->image_linesize), s->row_size / 2, + deloco_rgb16((uint16_t *)(ptr - dst_stride), s->row_size / 2, s->color_type == PNG_COLOR_TYPE_RGB_ALPHA); } else { - deloco_rgb8(ptr - s->image_linesize, s->row_size, + deloco_rgb8(ptr - dst_stride, s->row_size, s->color_type == PNG_COLOR_TYPE_RGB_ALPHA); } } @@ -370,7 +382,7 @@ static void png_handle_row(PNGDecContext *s) } else { got_line = 0; for (;;) { - ptr = s->image_buf + s->image_linesize * (s->y + s->y_offset) + s->x_offset * s->bpp; + ptr = dst + dst_stride * (s->y + s->y_offset) + s->x_offset * s->bpp; if ((ff_png_pass_ymask[s->pass] << (s->y & 7)) & 0x80) { /* if we already read one row, it is time to stop to * wait for the next one */ @@ -411,7 +423,8 @@ the_end:; } } -static int png_decode_idat(PNGDecContext *s, int length) +static int png_decode_idat(PNGDecContext *s, int length, + uint8_t *dst, ptrdiff_t dst_stride) { int ret; s->zstream.avail_in = FFMIN(length, bytestream2_get_bytes_left(&s->gb)); @@ -427,7 +440,7 @@ static int png_decode_idat(PNGDecContext *s, int length) } if (s->zstream.avail_out == 0) { if (!(s->pic_state & PNG_ALLIMAGE)) { - png_handle_row(s); + png_handle_row(s, dst, dst_stride); } s->zstream.avail_out = s->crow_size; s->zstream.next_out = s->crow_buf; @@ -509,8 +522,7 @@ static uint8_t *iso88591_to_utf8(const uint8_t *in, size_t size_in) return out; } -static int decode_text_chunk(PNGDecContext *s, uint32_t length, int compressed, - AVDictionary **dict) +static int decode_text_chunk(PNGDecContext *s, uint32_t length, int compressed) { int ret, method; const uint8_t *data = s->gb.buffer; @@ -552,7 +564,7 @@ static int decode_text_chunk(PNGDecContext *s, uint32_t length, int compressed, return AVERROR(ENOMEM); } - av_dict_set(dict, kw_utf8, txt_utf8, + av_dict_set(&s->frame_metadata, kw_utf8, txt_utf8, AV_DICT_DONT_STRDUP_KEY | AV_DICT_DONT_STRDUP_VAL); return 0; } @@ -631,6 +643,8 @@ static int decode_idat_chunk(AVCodecContext *avctx, PNGDecContext *s, int ret; size_t byte_depth = s->bit_depth > 8 ? 2 : 1; + if (!p) + return AVERROR_INVALIDDATA; if (!(s->hdr_state & PNG_IHDR)) { av_log(avctx, AV_LOG_ERROR, "IDAT without IHDR\n"); return AVERROR_INVALIDDATA; @@ -732,8 +746,7 @@ static int decode_idat_chunk(AVCodecContext *avctx, PNGDecContext *s, } ff_dlog(avctx, "row_size=%d crow_size =%d\n", s->row_size, s->crow_size); - s->image_buf = p->data[0]; - s->image_linesize = p->linesize[0]; + /* copy the palette if needed */ if (avctx->pix_fmt == AV_PIX_FMT_PAL8) memcpy(p->data[1], s->palette, 256 * sizeof(uint32_t)); @@ -764,7 +777,7 @@ static int decode_idat_chunk(AVCodecContext *avctx, PNGDecContext *s, if (s->has_trns && s->color_type != PNG_COLOR_TYPE_PALETTE) s->bpp -= byte_depth; - ret = png_decode_idat(s, length); + ret = png_decode_idat(s, length, p->data[0], p->linesize[0]); if (s->has_trns && s->color_type != PNG_COLOR_TYPE_PALETTE) s->bpp += byte_depth; @@ -848,24 +861,24 @@ static int decode_trns_chunk(AVCodecContext *avctx, PNGDecContext *s, return 0; } -static int decode_iccp_chunk(PNGDecContext *s, int length, AVFrame *f) +static int decode_iccp_chunk(PNGDecContext *s, int length) { int ret, cnt = 0; - uint8_t *data, profile_name[82]; AVBPrint bp; - AVFrameSideData *sd; - while ((profile_name[cnt++] = bytestream2_get_byte(&s->gb)) && cnt < 81); + while ((s->iccp_name[cnt++] = bytestream2_get_byte(&s->gb)) && cnt < 81); if (cnt > 80) { av_log(s->avctx, AV_LOG_ERROR, "iCCP with invalid name!\n"); - return AVERROR_INVALIDDATA; + ret = AVERROR_INVALIDDATA; + goto fail; } length = FFMAX(length - cnt, 0); if (bytestream2_get_byte(&s->gb) != 0) { av_log(s->avctx, AV_LOG_ERROR, "iCCP with invalid compression!\n"); - return AVERROR_INVALIDDATA; + ret = AVERROR_INVALIDDATA; + goto fail; } length = FFMAX(length - 1, 0); @@ -873,24 +886,19 @@ static int decode_iccp_chunk(PNGDecContext *s, int length, AVFrame *f) if ((ret = decode_zbuf(&bp, s->gb.buffer, s->gb.buffer + length)) < 0) return ret; - ret = av_bprint_finalize(&bp, (char **)&data); + av_freep(&s->iccp_data); + ret = av_bprint_finalize(&bp, (char **)&s->iccp_data); if (ret < 0) return ret; - - sd = av_frame_new_side_data(f, AV_FRAME_DATA_ICC_PROFILE, bp.len); - if (!sd) { - av_free(data); - return AVERROR(ENOMEM); - } - - av_dict_set(&sd->metadata, "name", profile_name, 0); - memcpy(sd->data, data, bp.len); - av_free(data); + s->iccp_data_len = bp.len; /* ICC compressed data and CRC */ bytestream2_skip(&s->gb, length + 4); return 0; +fail: + s->iccp_name[0] = 0; + return ret; } static void handle_small_bpp(PNGDecContext *s, AVFrame *p) @@ -913,7 +921,7 @@ static void handle_small_bpp(PNGDecContext *s, AVFrame *p) pd[8*i + 1]= (pd[i]>>6) & 1; pd[8*i + 0]= pd[i]>>7; } - pd += s->image_linesize; + pd += p->linesize[0]; } } else if (s->bits_per_pixel == 2) { int i, j; @@ -941,7 +949,7 @@ static void handle_small_bpp(PNGDecContext *s, AVFrame *p) pd[4*i + 0]= ( pd[i]>>6 )*0x55; } } - pd += s->image_linesize; + pd += p->linesize[0]; } } else if (s->bits_per_pixel == 4) { int i, j; @@ -961,7 +969,7 @@ static void handle_small_bpp(PNGDecContext *s, AVFrame *p) pd[2*i + 0] = (pd[i] >> 4) * 0x11; } } - pd += s->image_linesize; + pd += p->linesize[0]; } } } @@ -1016,7 +1024,7 @@ static int decode_fctl_chunk(AVCodecContext *avctx, PNGDecContext *s, return AVERROR_INVALIDDATA; } - if ((sequence_number == 0 || !s->last_picture.f->data[0]) && + if ((sequence_number == 0 || !s->last_picture.f) && dispose_op == APNG_DISPOSE_OP_PREVIOUS) { // No previous frame to revert to for the first frame // Spec says to just treat it as a APNG_DISPOSE_OP_BACKGROUND @@ -1056,8 +1064,8 @@ static void handle_p_frame_png(PNGDecContext *s, AVFrame *p) for (j = 0; j < s->height; j++) { for (i = 0; i < ls; i++) pd[i] += pd_last[i]; - pd += s->image_linesize; - pd_last += s->image_linesize; + pd += p->linesize[0]; + pd_last += s->last_picture.f->linesize[0]; } } @@ -1068,8 +1076,12 @@ static void handle_p_frame_png(PNGDecContext *s, AVFrame *p) static int handle_p_frame_apng(AVCodecContext *avctx, PNGDecContext *s, AVFrame *p) { + uint8_t *dst = p->data[0]; + ptrdiff_t dst_stride = p->linesize[0]; + const uint8_t *src = s->last_picture.f->data[0]; + ptrdiff_t src_stride = s->last_picture.f->linesize[0]; + size_t x, y; - uint8_t *buffer; if (s->blend_op == APNG_BLEND_OP_OVER && avctx->pix_fmt != AV_PIX_FMT_RGBA && @@ -1083,32 +1095,39 @@ static int handle_p_frame_apng(AVCodecContext *avctx, PNGDecContext *s, ff_thread_await_progress(&s->last_picture, INT_MAX, 0); // need to reset a rectangle to background: - // create a new writable copy if (s->last_dispose_op == APNG_DISPOSE_OP_BACKGROUND) { - int ret = av_frame_make_writable(s->last_picture.f); - if (ret < 0) - return ret; + av_fast_malloc(&s->background_buf, &s->background_buf_allocated, + src_stride * p->height); + if (!s->background_buf) + return AVERROR(ENOMEM); + + memcpy(s->background_buf, src, src_stride * p->height); for (y = s->last_y_offset; y < s->last_y_offset + s->last_h; y++) { - memset(s->last_picture.f->data[0] + s->image_linesize * y + + memset(s->background_buf + src_stride * y + s->bpp * s->last_x_offset, 0, s->bpp * s->last_w); } + + src = s->background_buf; } - buffer = av_memdup(s->last_picture.f->data[0], s->image_linesize * s->height); - if (!buffer) - return AVERROR(ENOMEM); + // copy unchanged rectangles from the last frame + for (y = 0; y < s->y_offset; y++) + memcpy(dst + y * dst_stride, src + y * src_stride, p->width * s->bpp); + for (y = s->y_offset; y < s->y_offset + s->cur_h; y++) { + memcpy(dst + y * dst_stride, src + y * src_stride, s->x_offset * s->bpp); + memcpy(dst + y * dst_stride + (s->x_offset + s->cur_w) * s->bpp, + src + y * src_stride + (s->x_offset + s->cur_w) * s->bpp, + (p->width - s->cur_w - s->x_offset) * s->bpp); + } + for (y = s->y_offset + s->cur_h; y < p->height; y++) + memcpy(dst + y * dst_stride, src + y * src_stride, p->width * s->bpp); - // Perform blending - if (s->blend_op == APNG_BLEND_OP_SOURCE) { + if (s->blend_op == APNG_BLEND_OP_OVER) { + // Perform blending for (y = s->y_offset; y < s->y_offset + s->cur_h; ++y) { - size_t row_start = s->image_linesize * y + s->bpp * s->x_offset; - memcpy(buffer + row_start, p->data[0] + row_start, s->bpp * s->cur_w); - } - } else { // APNG_BLEND_OP_OVER - for (y = s->y_offset; y < s->y_offset + s->cur_h; ++y) { - uint8_t *foreground = p->data[0] + s->image_linesize * y + s->bpp * s->x_offset; - uint8_t *background = buffer + s->image_linesize * y + s->bpp * s->x_offset; + uint8_t *foreground = dst + dst_stride * y + s->bpp * s->x_offset; + const uint8_t *background = src + src_stride * y + s->bpp * s->x_offset; for (x = s->x_offset; x < s->x_offset + s->cur_w; ++x, foreground += s->bpp, background += s->bpp) { size_t b; uint8_t foreground_alpha, background_alpha, output_alpha; @@ -1135,18 +1154,17 @@ static int handle_p_frame_apng(AVCodecContext *avctx, PNGDecContext *s, break; } - if (foreground_alpha == 0) + if (foreground_alpha == 255) continue; - if (foreground_alpha == 255) { - memcpy(background, foreground, s->bpp); + if (foreground_alpha == 0) { + memcpy(foreground, background, s->bpp); continue; } if (avctx->pix_fmt == AV_PIX_FMT_PAL8) { // TODO: Alpha blending with PAL8 will likely need the entire image converted over to RGBA first avpriv_request_sample(avctx, "Alpha blending palette samples"); - background[0] = foreground[0]; continue; } @@ -1164,15 +1182,11 @@ static int handle_p_frame_apng(AVCodecContext *avctx, PNGDecContext *s, } } output[b] = output_alpha; - memcpy(background, output, s->bpp); + memcpy(foreground, output, s->bpp); } } } - // Copy blended buffer into the frame and free - memcpy(p->data[0], buffer, s->image_linesize * s->height); - av_free(buffer); - return 0; } @@ -1180,7 +1194,6 @@ static int decode_frame_common(AVCodecContext *avctx, PNGDecContext *s, AVFrame *p, const AVPacket *avpkt) { const AVCRC *crc_tab = av_crc_get_table(AV_CRC_32_IEEE_LE); - AVDictionary **metadatap = NULL; uint32_t tag, length; int decode_next_dat = 0; int i, ret; @@ -1209,7 +1222,7 @@ static int decode_frame_common(AVCodecContext *avctx, PNGDecContext *s, } length = bytestream2_get_be32(&s->gb); - if (length > 0x7fffffff || length > bytestream2_get_bytes_left(&s->gb)) { + if (length > 0x7fffffff || length + 8 > bytestream2_get_bytes_left(&s->gb)) { av_log(avctx, AV_LOG_ERROR, "chunk too big\n"); ret = AVERROR_INVALIDDATA; goto fail; @@ -1248,7 +1261,6 @@ static int decode_frame_common(AVCodecContext *avctx, PNGDecContext *s, } } - metadatap = &p->metadata; switch (tag) { case MKTAG('I', 'H', 'D', 'R'): if ((ret = decode_ihdr_chunk(avctx, s, length)) < 0) @@ -1290,26 +1302,20 @@ static int decode_frame_common(AVCodecContext *avctx, PNGDecContext *s, goto skip_tag; break; case MKTAG('t', 'E', 'X', 't'): - if (decode_text_chunk(s, length, 0, metadatap) < 0) + if (decode_text_chunk(s, length, 0) < 0) av_log(avctx, AV_LOG_WARNING, "Broken tEXt chunk\n"); bytestream2_skip(&s->gb, length + 4); break; case MKTAG('z', 'T', 'X', 't'): - if (decode_text_chunk(s, length, 1, metadatap) < 0) + if (decode_text_chunk(s, length, 1) < 0) av_log(avctx, AV_LOG_WARNING, "Broken zTXt chunk\n"); bytestream2_skip(&s->gb, length + 4); break; case MKTAG('s', 'T', 'E', 'R'): { int mode = bytestream2_get_byte(&s->gb); - AVStereo3D *stereo3d = av_stereo3d_create_side_data(p); - if (!stereo3d) { - ret = AVERROR(ENOMEM); - goto fail; - } if (mode == 0 || mode == 1) { - stereo3d->type = AV_STEREO3D_SIDEBYSIDE; - stereo3d->flags = mode ? 0 : AV_STEREO3D_FLAG_INVERT; + s->stereo_mode = mode; } else { av_log(avctx, AV_LOG_WARNING, "Unknown value in sTER chunk (%d)\n", mode); @@ -1318,27 +1324,22 @@ static int decode_frame_common(AVCodecContext *avctx, PNGDecContext *s, break; } case MKTAG('i', 'C', 'C', 'P'): { - if ((ret = decode_iccp_chunk(s, length, p)) < 0) + if ((ret = decode_iccp_chunk(s, length)) < 0) goto fail; break; } case MKTAG('c', 'H', 'R', 'M'): { - AVMasteringDisplayMetadata *mdm = av_mastering_display_metadata_create_side_data(p); - if (!mdm) { - ret = AVERROR(ENOMEM); - goto fail; - } + s->have_chrm = 1; - mdm->white_point[0] = av_make_q(bytestream2_get_be32(&s->gb), 100000); - mdm->white_point[1] = av_make_q(bytestream2_get_be32(&s->gb), 100000); + s->white_point[0] = bytestream2_get_be32(&s->gb); + s->white_point[1] = bytestream2_get_be32(&s->gb); /* RGB Primaries */ for (i = 0; i < 3; i++) { - mdm->display_primaries[i][0] = av_make_q(bytestream2_get_be32(&s->gb), 100000); - mdm->display_primaries[i][1] = av_make_q(bytestream2_get_be32(&s->gb), 100000); + s->display_primaries[i][0] = bytestream2_get_be32(&s->gb); + s->display_primaries[i][1] = bytestream2_get_be32(&s->gb); } - mdm->has_primaries = 1; bytestream2_skip(&s->gb, 4); /* crc */ break; } @@ -1353,7 +1354,7 @@ static int decode_frame_common(AVCodecContext *avctx, PNGDecContext *s, if (ret < 0) return ret; - av_dict_set(&p->metadata, "gamma", gamma_str, AV_DICT_DONT_STRDUP_VAL); + av_dict_set(&s->frame_metadata, "gamma", gamma_str, AV_DICT_DONT_STRDUP_VAL); bytestream2_skip(&s->gb, 4); /* crc */ break; @@ -1376,6 +1377,9 @@ skip_tag: } exit_loop: + if (!p) + return AVERROR_INVALIDDATA; + if (avctx->codec_id == AV_CODEC_ID_PNG && avctx->skip_frame == AVDISCARD_ALL) { return 0; @@ -1396,7 +1400,7 @@ exit_loop: av_assert0(s->bit_depth > 1); for (y = 0; y < s->height; ++y) { - uint8_t *row = &s->image_buf[s->image_linesize * y]; + uint8_t *row = &p->data[0][p->linesize[0] * y]; if (s->bpp == 2 && byte_depth == 1) { uint8_t *pixel = &row[2 * s->width - 1]; @@ -1456,6 +1460,77 @@ fail: return ret; } +static void clear_frame_metadata(PNGDecContext *s) +{ + av_freep(&s->iccp_data); + s->iccp_data_len = 0; + s->iccp_name[0] = 0; + + s->stereo_mode = -1; + + s->have_chrm = 0; + + av_dict_free(&s->frame_metadata); +} + +static int output_frame(PNGDecContext *s, AVFrame *f, + const AVFrame *src) +{ + int ret; + + ret = av_frame_ref(f, src); + if (ret < 0) + return ret; + + if (s->iccp_data) { + AVFrameSideData *sd = av_frame_new_side_data(f, AV_FRAME_DATA_ICC_PROFILE, s->iccp_data_len); + if (!sd) { + ret = AVERROR(ENOMEM); + goto fail; + } + memcpy(sd->data, s->iccp_data, s->iccp_data_len); + + av_dict_set(&sd->metadata, "name", s->iccp_name, 0); + } + + if (s->stereo_mode >= 0) { + AVStereo3D *stereo3d = av_stereo3d_create_side_data(f); + if (!stereo3d) { + ret = AVERROR(ENOMEM); + goto fail; + } + + stereo3d->type = AV_STEREO3D_SIDEBYSIDE; + stereo3d->flags = s->stereo_mode ? 0 : AV_STEREO3D_FLAG_INVERT; + } + + if (s->have_chrm) { + AVMasteringDisplayMetadata *mdm = av_mastering_display_metadata_create_side_data(f); + if (!mdm) { + ret = AVERROR(ENOMEM); + goto fail; + } + + mdm->white_point[0] = av_make_q(s->white_point[0], 100000); + mdm->white_point[1] = av_make_q(s->white_point[1], 100000); + + /* RGB Primaries */ + for (int i = 0; i < 3; i++) { + mdm->display_primaries[i][0] = av_make_q(s->display_primaries[i][0], 100000); + mdm->display_primaries[i][1] = av_make_q(s->display_primaries[i][1], 100000); + } + + mdm->has_primaries = 1; + } + + FFSWAP(AVDictionary*, f->metadata, s->frame_metadata); + + return 0; +fail: + av_frame_unref(f); + return ret; +} + #if CONFIG_PNG_DECODER static int decode_frame_png(AVCodecContext *avctx, void *data, int *got_frame, @@ -1464,10 +1539,13 @@ static int decode_frame_png(AVCodecContext *avctx, PNGDecContext *const s = avctx->priv_data; const uint8_t *buf = avpkt->data; int buf_size = avpkt->size; + AVFrame *dst_frame = data; AVFrame *p = s->picture.f; int64_t sig; int ret; + clear_frame_metadata(s); + bytestream2_init(&s->gb, buf, buf_size); /* check signature */ @@ -1501,7 +1579,8 @@ static int decode_frame_png(AVCodecContext *avctx, goto the_end; } - if ((ret = av_frame_ref(data, s->picture.f)) < 0) + ret = output_frame(s, dst_frame, s->picture.f); + if (ret < 0) goto the_end; if (!(avctx->active_thread_type & FF_THREAD_FRAME)) { @@ -1525,9 +1604,12 @@ static int decode_frame_apng(AVCodecContext *avctx, AVPacket *avpkt) { PNGDecContext *const s = avctx->priv_data; + AVFrame *dst_frame = data; int ret; AVFrame *p = s->picture.f; + clear_frame_metadata(s); + if (!(s->hdr_state & PNG_IHDR)) { if (!avctx->extradata_size) return AVERROR_INVALIDDATA; @@ -1537,7 +1619,7 @@ static int decode_frame_apng(AVCodecContext *avctx, s->zstream.zfree = ff_png_zfree; bytestream2_init(&s->gb, avctx->extradata, avctx->extradata_size); - if ((ret = decode_frame_common(avctx, s, p, avpkt)) < 0) + if ((ret = decode_frame_common(avctx, s, NULL, avpkt)) < 0) goto end; } @@ -1559,13 +1641,15 @@ static int decode_frame_apng(AVCodecContext *avctx, ret = AVERROR_INVALIDDATA; goto end; } - if ((ret = av_frame_ref(data, s->picture.f)) < 0) + + ret = output_frame(s, dst_frame, s->picture.f); + if (ret < 0) goto end; if (!(avctx->active_thread_type & FF_THREAD_FRAME)) { if (s->dispose_op == APNG_DISPOSE_OP_PREVIOUS) { ff_thread_release_buffer(avctx, &s->picture); - } else if (s->dispose_op == APNG_DISPOSE_OP_NONE) { + } else { ff_thread_release_buffer(avctx, &s->last_picture); FFSWAP(ThreadFrame, s->picture, s->last_picture); } @@ -1614,8 +1698,8 @@ static int update_thread_context(AVCodecContext *dst, const AVCodecContext *src) pdst->hdr_state |= psrc->hdr_state; } - src_frame = psrc->dispose_op == APNG_DISPOSE_OP_NONE ? - &psrc->picture : &psrc->last_picture; + src_frame = psrc->dispose_op == APNG_DISPOSE_OP_PREVIOUS ? + &psrc->last_picture : &psrc->picture; ff_thread_release_buffer(dst, &pdst->last_picture); if (src_frame && src_frame->f->data[0]) { @@ -1662,6 +1746,10 @@ static av_cold int png_dec_end(AVCodecContext *avctx) s->last_row_size = 0; av_freep(&s->tmp_row); s->tmp_row_size = 0; + av_freep(&s->background_buf); + + av_freep(&s->iccp_data); + av_dict_free(&s->frame_metadata); return 0; } diff --git a/libavcodec/pnm_parser.c b/libavcodec/pnm_parser.c index f3be6d640c..a822c17a2e 100644 --- a/libavcodec/pnm_parser.c +++ b/libavcodec/pnm_parser.c @@ -111,7 +111,7 @@ retry: } else { int ret = av_image_get_buffer_size(avctx->pix_fmt, avctx->width, avctx->height, 1); next = pnmctx.bytestream - pnmctx.bytestream_start + skip; - if (ret >= 0) + if (ret >= 0 && next + (uint64_t)ret <= INT_MAX) next += ret; } if (next != END_NOT_FOUND && pnmctx.bytestream_start != buf + skip) diff --git a/libavcodec/pnmdec.c b/libavcodec/pnmdec.c index 4d5ce0bcb5..21e5247b05 100644 --- a/libavcodec/pnmdec.c +++ b/libavcodec/pnmdec.c @@ -256,7 +256,7 @@ static int pnm_decode_frame(AVCodecContext *avctx, void *data, } break; case AV_PIX_FMT_GBRPF32: - if (avctx->width * avctx->height * 12 > s->bytestream_end - s->bytestream) + if (avctx->width * avctx->height * 12LL > s->bytestream_end - s->bytestream) return AVERROR_INVALIDDATA; scale = 1.f / s->scale; if (s->endian) { diff --git a/libavcodec/proresdec2.c b/libavcodec/proresdec2.c index 136f341c08..3c6cd85267 100644 --- a/libavcodec/proresdec2.c +++ b/libavcodec/proresdec2.c @@ -490,7 +490,7 @@ static av_always_inline int decode_ac_coeffs(AVCodecContext *avctx, GetBitContex for (pos = block_mask;;) { bits_left = gb->size_in_bits - re_index; - if (!bits_left || (bits_left < 32 && !SHOW_UBITS(re, gb, bits_left))) + if (bits_left <= 0 || (bits_left < 32 && !SHOW_UBITS(re, gb, bits_left))) break; DECODE_CODEWORD(run, run_to_cb[FFMIN(run, 15)], LAST_SKIP_BITS); @@ -623,8 +623,8 @@ static int decode_slice_thread(AVCodecContext *avctx, void *arg, int jobnr, int AVFrame *pic = ctx->frame; int i, hdr_size, qscale, log2_chroma_blocks_per_mb; int luma_stride, chroma_stride; - int y_data_size, u_data_size, v_data_size, a_data_size; - uint8_t *dest_y, *dest_u, *dest_v, *dest_a; + int y_data_size, u_data_size, v_data_size, a_data_size, offset; + uint8_t *dest_y, *dest_u, *dest_v; LOCAL_ALIGNED_16(int16_t, qmat_luma_scaled, [64]); LOCAL_ALIGNED_16(int16_t, qmat_chroma_scaled,[64]); int mb_x_shift; @@ -676,16 +676,16 @@ static int decode_slice_thread(AVCodecContext *avctx, void *arg, int jobnr, int log2_chroma_blocks_per_mb = 1; } - dest_y = pic->data[0] + (slice->mb_y << 4) * luma_stride + (slice->mb_x << 5); + offset = (slice->mb_y << 4) * luma_stride + (slice->mb_x << 5); + dest_y = pic->data[0] + offset; dest_u = pic->data[1] + (slice->mb_y << 4) * chroma_stride + (slice->mb_x << mb_x_shift); dest_v = pic->data[2] + (slice->mb_y << 4) * chroma_stride + (slice->mb_x << mb_x_shift); - dest_a = pic->data[3] + (slice->mb_y << 4) * luma_stride + (slice->mb_x << 5); if (ctx->frame_type && ctx->first_field ^ ctx->frame->top_field_first) { dest_y += pic->linesize[0]; dest_u += pic->linesize[1]; dest_v += pic->linesize[2]; - dest_a += pic->linesize[3]; + offset += pic->linesize[3]; } ret = decode_slice_luma(avctx, slice, (uint16_t*)dest_y, luma_stride, @@ -722,10 +722,12 @@ static int decode_slice_thread(AVCodecContext *avctx, void *arg, int jobnr, int } /* decode alpha plane if available */ - if (ctx->alpha_info && pic->data[3] && a_data_size) + if (ctx->alpha_info && pic->data[3] && a_data_size) { + uint8_t *dest_a = pic->data[3] + offset; decode_slice_alpha(ctx, (uint16_t*)dest_a, luma_stride, buf + y_data_size + u_data_size + v_data_size, a_data_size, slice->mb_count); + } slice->ret = 0; return 0; diff --git a/libavcodec/proresenc_anatoliy.c b/libavcodec/proresenc_anatoliy.c index c34e55f873..2d03f4d8c4 100644 --- a/libavcodec/proresenc_anatoliy.c +++ b/libavcodec/proresenc_anatoliy.c @@ -957,6 +957,7 @@ AVCodec ff_prores_aw_encoder = { .capabilities = AV_CODEC_CAP_FRAME_THREADS, .priv_class = &proresaw_enc_class, .profiles = NULL_IF_CONFIG_SMALL(ff_prores_profiles), + .caps_internal = FF_CODEC_CAP_INIT_CLEANUP, }; AVCodec ff_prores_encoder = { @@ -972,4 +973,5 @@ AVCodec ff_prores_encoder = { .capabilities = AV_CODEC_CAP_FRAME_THREADS, .priv_class = &prores_enc_class, .profiles = NULL_IF_CONFIG_SMALL(ff_prores_profiles), + .caps_internal = FF_CODEC_CAP_INIT_CLEANUP, }; diff --git a/libavcodec/proresenc_kostya.c b/libavcodec/proresenc_kostya.c index 0e70163bcc..b00f5f5c5f 100644 --- a/libavcodec/proresenc_kostya.c +++ b/libavcodec/proresenc_kostya.c @@ -3,9 +3,6 @@ * * Copyright (c) 2012 Konstantin Shishkov * - * This encoder appears to be based on Anatoliy Wassermans considering - * similarities in the bugs. - * * This file is part of FFmpeg. * * FFmpeg is free software; you can redistribute it and/or @@ -343,7 +340,7 @@ static void get_slice_data(ProresContext *ctx, const uint16_t *src, static void get_alpha_data(ProresContext *ctx, const uint16_t *src, ptrdiff_t linesize, int x, int y, int w, int h, - int16_t *blocks, int mbs_per_slice, int abits) + uint16_t *blocks, int mbs_per_slice, int abits) { const int slice_width = 16 * mbs_per_slice; int i, j, copy_w, copy_h; diff --git a/libavcodec/pthread_frame.c b/libavcodec/pthread_frame.c index 7bcb9a7bcc..6f48d2c208 100644 --- a/libavcodec/pthread_frame.c +++ b/libavcodec/pthread_frame.c @@ -64,6 +64,12 @@ enum { STATE_SETUP_FINISHED, }; +enum { + UNINITIALIZED, ///< Thread has not been created, AVCodec->close mustn't be called + NEEDS_CLOSE, ///< AVCodec->close needs to be called + INITIALIZED, ///< Thread has been properly set up +}; + /** * Context used by codec threads and stored in their AVCodecInternal thread_ctx. */ @@ -72,6 +78,7 @@ typedef struct PerThreadContext { pthread_t thread; int thread_init; + unsigned pthread_init_cnt;///< Number of successfully initialized mutexes/conditions pthread_cond_t input_cond; ///< Used to wait for a new packet from the main thread. pthread_cond_t progress_cond; ///< Used by child threads to wait for progress to change. pthread_cond_t output_cond; ///< Used by the main thread to wait for frames to finish. @@ -120,6 +127,7 @@ typedef struct FrameThreadContext { PerThreadContext *threads; ///< The contexts for each thread. PerThreadContext *prev_thread; ///< The last thread submit_packet() was called on. + unsigned pthread_init_cnt; ///< Number of successfully initialized mutexes/conditions pthread_mutex_t buffer_mutex; ///< Mutex used to protect get/release_buffer(). /** * This lock is used for ensuring threads run in serial when hwaccel @@ -137,6 +145,12 @@ typedef struct FrameThreadContext { * Set for the first N packets, where N is the number of threads. * While it is set, ff_thread_en/decode_frame won't return any results. */ + + /* hwaccel state is temporarily stored here in order to transfer its ownership + * to the next decoding thread without the need for extra synchronization */ + const AVHWAccel *stash_hwaccel; + void *stash_hwaccel_context; + void *stash_hwaccel_priv; } FrameThreadContext; #if FF_API_THREAD_SAFE_CALLBACKS @@ -221,9 +235,17 @@ FF_ENABLE_DEPRECATION_WARNINGS ff_thread_finish_setup(avctx); if (p->hwaccel_serializing) { + /* wipe hwaccel state to avoid stale pointers lying around; + * the state was transferred to FrameThreadContext in + * ff_thread_finish_setup(), so nothing is leaked */ + avctx->hwaccel = NULL; + avctx->hwaccel_context = NULL; + avctx->internal->hwaccel_priv_data = NULL; + p->hwaccel_serializing = 0; pthread_mutex_unlock(&p->parent->hwaccel_mutex); } + av_assert0(!avctx->hwaccel); if (p->async_serializing) { p->async_serializing = 0; @@ -285,14 +307,10 @@ static int update_context_from_thread(AVCodecContext *dst, AVCodecContext *src, dst->color_range = src->color_range; dst->chroma_sample_location = src->chroma_sample_location; - dst->hwaccel = src->hwaccel; - dst->hwaccel_context = src->hwaccel_context; - dst->channels = src->channels; dst->sample_rate = src->sample_rate; dst->sample_fmt = src->sample_fmt; dst->channel_layout = src->channel_layout; - dst->internal->hwaccel_priv_data = src->internal->hwaccel_priv_data; if (!!dst->hw_frames_ctx != !!src->hw_frames_ctx || (dst->hw_frames_ctx && dst->hw_frames_ctx->data != src->hw_frames_ctx->data)) { @@ -438,6 +456,12 @@ static int submit_packet(PerThreadContext *p, AVCodecContext *user_avctx, } } + /* transfer the stashed hwaccel state, if any */ + av_assert0(!p->avctx->hwaccel); + FFSWAP(const AVHWAccel*, p->avctx->hwaccel, fctx->stash_hwaccel); + FFSWAP(void*, p->avctx->hwaccel_context, fctx->stash_hwaccel_context); + FFSWAP(void*, p->avctx->internal->hwaccel_priv_data, fctx->stash_hwaccel_priv); + av_packet_unref(p->avpkt); ret = av_packet_ref(p->avpkt, avpkt); if (ret < 0) { @@ -641,6 +665,14 @@ void ff_thread_finish_setup(AVCodecContext *avctx) { async_lock(p->parent); } + /* save hwaccel state for passing to the next thread; + * this is done here so that this worker thread can wipe its own hwaccel + * state after decoding, without requiring synchronization */ + av_assert0(!p->parent->stash_hwaccel); + p->parent->stash_hwaccel = avctx->hwaccel; + p->parent->stash_hwaccel_context = avctx->hwaccel_context; + p->parent->stash_hwaccel_priv = avctx->internal->hwaccel_priv_data; + pthread_mutex_lock(&p->progress_mutex); if(atomic_load(&p->state) == STATE_SETUP_FINISHED){ av_log(avctx, AV_LOG_WARNING, "Multiple ff_thread_finish_setup() calls\n"); @@ -674,6 +706,59 @@ static void park_frame_worker_threads(FrameThreadContext *fctx, int thread_count async_lock(fctx); } +#define SENTINEL 0 // This forbids putting a mutex/condition variable at the front. +#define OFFSET_ARRAY(...) __VA_ARGS__, SENTINEL +#define DEFINE_OFFSET_ARRAY(type, name, mutexes, conds) \ +static const unsigned name ## _offsets[] = { offsetof(type, pthread_init_cnt),\ + OFFSET_ARRAY mutexes, \ + OFFSET_ARRAY conds } + +#define OFF(member) offsetof(FrameThreadContext, member) +DEFINE_OFFSET_ARRAY(FrameThreadContext, thread_ctx, + (OFF(buffer_mutex), OFF(hwaccel_mutex), OFF(async_mutex)), + (OFF(async_cond))); +#undef OFF + +#define OFF(member) offsetof(PerThreadContext, member) +DEFINE_OFFSET_ARRAY(PerThreadContext, per_thread, + (OFF(progress_mutex), OFF(mutex)), + (OFF(input_cond), OFF(progress_cond), OFF(output_cond))); +#undef OFF + +static av_cold void free_pthread(void *obj, const unsigned offsets[]) +{ + unsigned cnt = *(unsigned*)((char*)obj + offsets[0]); + const unsigned *cur_offset = offsets; + + for (; *(++cur_offset) != SENTINEL && cnt; cnt--) + pthread_mutex_destroy((pthread_mutex_t*)((char*)obj + *cur_offset)); + for (; *(++cur_offset) != SENTINEL && cnt; cnt--) + pthread_cond_destroy ((pthread_cond_t *)((char*)obj + *cur_offset)); +} + +static av_cold int init_pthread(void *obj, const unsigned offsets[]) +{ + const unsigned *cur_offset = offsets; + unsigned cnt = 0; + int err; + +#define PTHREAD_INIT_LOOP(type) \ + for (; *(++cur_offset) != SENTINEL; cnt++) { \ + pthread_ ## type ## _t *dst = (void*)((char*)obj + *cur_offset); \ + err = pthread_ ## type ## _init(dst, NULL); \ + if (err) { \ + err = AVERROR(err); \ + goto fail; \ + } \ + } + PTHREAD_INIT_LOOP(mutex) + PTHREAD_INIT_LOOP(cond) + +fail: + *(unsigned*)((char*)obj + offsets[0]) = cnt; + return err; +} + void ff_frame_thread_free(AVCodecContext *avctx, int thread_count) { FrameThreadContext *fctx = avctx->internal->thread_ctx; @@ -682,13 +767,6 @@ void ff_frame_thread_free(AVCodecContext *avctx, int thread_count) park_frame_worker_threads(fctx, thread_count); - if (fctx->prev_thread && avctx->internal->hwaccel_priv_data != - fctx->prev_thread->avctx->internal->hwaccel_priv_data) { - if (update_context_from_thread(avctx, fctx->prev_thread->avctx, 1) < 0) { - av_log(avctx, AV_LOG_ERROR, "Failed to update user thread.\n"); - } - } - if (fctx->prev_thread && fctx->prev_thread != fctx->threads) if (update_context_from_thread(fctx->threads->avctx, fctx->prev_thread->avctx, 0) < 0) { av_log(avctx, AV_LOG_ERROR, "Final thread update failed\n"); @@ -698,63 +776,56 @@ void ff_frame_thread_free(AVCodecContext *avctx, int thread_count) for (i = 0; i < thread_count; i++) { PerThreadContext *p = &fctx->threads[i]; + AVCodecContext *ctx = p->avctx; - pthread_mutex_lock(&p->mutex); - p->die = 1; - pthread_cond_signal(&p->input_cond); - pthread_mutex_unlock(&p->mutex); + if (ctx->internal) { + if (p->thread_init == INITIALIZED) { + pthread_mutex_lock(&p->mutex); + p->die = 1; + pthread_cond_signal(&p->input_cond); + pthread_mutex_unlock(&p->mutex); - if (p->thread_init) - pthread_join(p->thread, NULL); - p->thread_init=0; - - if (codec->close && p->avctx) - codec->close(p->avctx); + pthread_join(p->thread, NULL); + } + if (codec->close && p->thread_init != UNINITIALIZED) + codec->close(ctx); #if FF_API_THREAD_SAFE_CALLBACKS - release_delayed_buffers(p); + release_delayed_buffers(p); + for (int j = 0; j < p->released_buffers_allocated; j++) + av_frame_free(&p->released_buffers[j]); + av_freep(&p->released_buffers); #endif + if (ctx->priv_data) { + if (codec->priv_class) + av_opt_free(ctx->priv_data); + av_freep(&ctx->priv_data); + } + + av_freep(&ctx->slice_offset); + + av_buffer_unref(&ctx->internal->pool); + av_freep(&ctx->internal); + av_buffer_unref(&ctx->hw_frames_ctx); + } + av_frame_free(&p->frame); - } - for (i = 0; i < thread_count; i++) { - PerThreadContext *p = &fctx->threads[i]; - - pthread_mutex_destroy(&p->mutex); - pthread_mutex_destroy(&p->progress_mutex); - pthread_cond_destroy(&p->input_cond); - pthread_cond_destroy(&p->progress_cond); - pthread_cond_destroy(&p->output_cond); + free_pthread(p, per_thread_offsets); av_packet_free(&p->avpkt); -#if FF_API_THREAD_SAFE_CALLBACKS - for (int j = 0; j < p->released_buffers_allocated; j++) - av_frame_free(&p->released_buffers[j]); - av_freep(&p->released_buffers); -#endif - - if (p->avctx) { - if (codec->priv_class) - av_opt_free(p->avctx->priv_data); - av_freep(&p->avctx->priv_data); - - av_freep(&p->avctx->slice_offset); - } - - if (p->avctx) { - av_buffer_unref(&p->avctx->internal->pool); - av_freep(&p->avctx->internal); - av_buffer_unref(&p->avctx->hw_frames_ctx); - } - av_freep(&p->avctx); } av_freep(&fctx->threads); - pthread_mutex_destroy(&fctx->buffer_mutex); - pthread_mutex_destroy(&fctx->hwaccel_mutex); - pthread_mutex_destroy(&fctx->async_mutex); - pthread_cond_destroy(&fctx->async_cond); + free_pthread(fctx, thread_ctx_offsets); + + /* if we have stashed hwaccel state, move it to the user-facing context, + * so it will be freed in avcodec_close() */ + av_assert0(!avctx->hwaccel); + FFSWAP(const AVHWAccel*, avctx->hwaccel, fctx->stash_hwaccel); + FFSWAP(void*, avctx->hwaccel_context, fctx->stash_hwaccel_context); + FFSWAP(void*, avctx->internal->hwaccel_priv_data, fctx->stash_hwaccel_priv); av_freep(&avctx->internal->thread_ctx); @@ -763,13 +834,89 @@ void ff_frame_thread_free(AVCodecContext *avctx, int thread_count) avctx->codec = NULL; } +static av_cold int init_thread(PerThreadContext *p, int *threads_to_free, + FrameThreadContext *fctx, AVCodecContext *avctx, + AVCodecContext *src, const AVCodec *codec, int first) +{ + AVCodecContext *copy; + int err; + + atomic_init(&p->state, STATE_INPUT_READY); + + copy = av_memdup(src, sizeof(*src)); + if (!copy) + return AVERROR(ENOMEM); + copy->priv_data = NULL; + + /* From now on, this PerThreadContext will be cleaned up by + * ff_frame_thread_free in case of errors. */ + (*threads_to_free)++; + + p->parent = fctx; + p->avctx = copy; + + copy->internal = av_memdup(src->internal, sizeof(*src->internal)); + if (!copy->internal) + return AVERROR(ENOMEM); + copy->internal->thread_ctx = p; + + copy->delay = avctx->delay; + + if (codec->priv_data_size) { + copy->priv_data = av_mallocz(codec->priv_data_size); + if (!copy->priv_data) + return AVERROR(ENOMEM); + + if (codec->priv_class) { + *(const AVClass **)copy->priv_data = codec->priv_class; + err = av_opt_copy(copy->priv_data, src->priv_data); + if (err < 0) + return err; + } + } + + err = init_pthread(p, per_thread_offsets); + if (err < 0) + return err; + + if (!(p->frame = av_frame_alloc()) || + !(p->avpkt = av_packet_alloc())) + return AVERROR(ENOMEM); + copy->internal->last_pkt_props = p->avpkt; + + if (!first) + copy->internal->is_copy = 1; + + if (codec->init) { + err = codec->init(copy); + if (err < 0) { + if (codec->caps_internal & FF_CODEC_CAP_INIT_CLEANUP) + p->thread_init = NEEDS_CLOSE; + return err; + } + } + p->thread_init = NEEDS_CLOSE; + + if (first) + update_context_from_thread(avctx, copy, 1); + + atomic_init(&p->debug_threads, (copy->debug & FF_DEBUG_THREADS) != 0); + + err = AVERROR(pthread_create(&p->thread, NULL, frame_worker_thread, p)); + if (err < 0) + return err; + p->thread_init = INITIALIZED; + + return 0; +} + int ff_frame_thread_init(AVCodecContext *avctx) { int thread_count = avctx->thread_count; const AVCodec *codec = avctx->codec; AVCodecContext *src = avctx; FrameThreadContext *fctx; - int i, err = 0; + int err, i = 0; if (!thread_count) { int nb_cpus = av_cpu_count(); @@ -789,107 +936,38 @@ int ff_frame_thread_init(AVCodecContext *avctx) if (!fctx) return AVERROR(ENOMEM); - fctx->threads = av_mallocz_array(thread_count, sizeof(PerThreadContext)); - if (!fctx->threads) { + err = init_pthread(fctx, thread_ctx_offsets); + if (err < 0) { + free_pthread(fctx, thread_ctx_offsets); av_freep(&avctx->internal->thread_ctx); - return AVERROR(ENOMEM); + return err; } - pthread_mutex_init(&fctx->buffer_mutex, NULL); - pthread_mutex_init(&fctx->hwaccel_mutex, NULL); - pthread_mutex_init(&fctx->async_mutex, NULL); - pthread_cond_init(&fctx->async_cond, NULL); - fctx->async_lock = 1; fctx->delaying = 1; if (codec->type == AVMEDIA_TYPE_VIDEO) avctx->delay = src->thread_count - 1; - for (i = 0; i < thread_count; i++) { - AVCodecContext *copy = av_malloc(sizeof(AVCodecContext)); + fctx->threads = av_mallocz_array(thread_count, sizeof(PerThreadContext)); + if (!fctx->threads) { + err = AVERROR(ENOMEM); + goto error; + } + + for (; i < thread_count; ) { PerThreadContext *p = &fctx->threads[i]; + int first = !i; - pthread_mutex_init(&p->mutex, NULL); - pthread_mutex_init(&p->progress_mutex, NULL); - pthread_cond_init(&p->input_cond, NULL); - pthread_cond_init(&p->progress_cond, NULL); - pthread_cond_init(&p->output_cond, NULL); - - p->frame = av_frame_alloc(); - if (!p->frame) { - av_freep(©); - err = AVERROR(ENOMEM); - goto error; - } - p->avpkt = av_packet_alloc(); - if (!p->avpkt) { - av_freep(©); - err = AVERROR(ENOMEM); - goto error; - } - - p->parent = fctx; - p->avctx = copy; - - if (!copy) { - err = AVERROR(ENOMEM); - goto error; - } - - *copy = *src; - - copy->internal = av_malloc(sizeof(AVCodecInternal)); - if (!copy->internal) { - copy->priv_data = NULL; - err = AVERROR(ENOMEM); - goto error; - } - *copy->internal = *src->internal; - copy->internal->thread_ctx = p; - copy->internal->last_pkt_props = p->avpkt; - - copy->delay = avctx->delay; - - if (codec->priv_data_size) { - copy->priv_data = av_mallocz(codec->priv_data_size); - if (!copy->priv_data) { - err = AVERROR(ENOMEM); - goto error; - } - - if (codec->priv_class) { - *(const AVClass **)copy->priv_data = codec->priv_class; - err = av_opt_copy(copy->priv_data, src->priv_data); - if (err < 0) - goto error; - } - } - - if (i) - copy->internal->is_copy = 1; - - if (codec->init) - err = codec->init(copy); - - if (err) goto error; - - if (!i) - update_context_from_thread(avctx, copy, 1); - - atomic_init(&p->debug_threads, (copy->debug & FF_DEBUG_THREADS) != 0); - - err = AVERROR(pthread_create(&p->thread, NULL, frame_worker_thread, p)); - p->thread_init= !err; - if(!p->thread_init) + err = init_thread(p, &i, fctx, avctx, src, codec, first); + if (err < 0) goto error; } return 0; error: - ff_frame_thread_free(avctx, i+1); - + ff_frame_thread_free(avctx, i); return err; } diff --git a/libavcodec/put_bits.h b/libavcodec/put_bits.h index cd66a82a44..f07944a8fb 100644 --- a/libavcodec/put_bits.h +++ b/libavcodec/put_bits.h @@ -35,16 +35,9 @@ #include "version.h" -#if ARCH_X86_64 -// TODO: Benchmark and optionally enable on other 64-bit architectures. -typedef uint64_t BitBuf; -#define AV_WBBUF AV_WB64 -#define AV_WLBUF AV_WL64 -#else typedef uint32_t BitBuf; #define AV_WBBUF AV_WB32 #define AV_WLBUF AV_WL32 -#endif static const int BUF_BITS = 8 * sizeof(BitBuf); diff --git a/libavcodec/qdrw.c b/libavcodec/qdrw.c index 65279c9805..c04c756d71 100644 --- a/libavcodec/qdrw.c +++ b/libavcodec/qdrw.c @@ -369,7 +369,7 @@ static int decode_frame(AVCodecContext *avctx, bytestream2_skip(&gbc, 18); colors = bytestream2_get_be16(&gbc); - if (colors < 0 || colors > 256) { + if (colors < 0 || colors > 255) { av_log(avctx, AV_LOG_ERROR, "Error color count - %i(0x%X)\n", colors, colors); return AVERROR_INVALIDDATA; diff --git a/libavcodec/qpeldsp.c b/libavcodec/qpeldsp.c index 6e52b33657..d99b8fd0ba 100644 --- a/libavcodec/qpeldsp.c +++ b/libavcodec/qpeldsp.c @@ -198,7 +198,7 @@ static void OPNAME ## qpel8_mc01_c(uint8_t *dst, const uint8_t *src, \ uint8_t full[16 * 9]; \ uint8_t half[64]; \ \ - copy_block9(full, src, 16, stride, 9); \ + copy_block8(full, src, 16, stride, 9); \ put ## RND ## mpeg4_qpel8_v_lowpass(half, full, 8, 16); \ OPNAME ## pixels8_l2_8(dst, full, half, stride, 16, 8, 8); \ } \ @@ -208,7 +208,7 @@ static void OPNAME ## qpel8_mc02_c(uint8_t *dst, const uint8_t *src, \ { \ uint8_t full[16 * 9]; \ \ - copy_block9(full, src, 16, stride, 9); \ + copy_block8(full, src, 16, stride, 9); \ OPNAME ## mpeg4_qpel8_v_lowpass(dst, full, stride, 16); \ } \ \ @@ -218,7 +218,7 @@ static void OPNAME ## qpel8_mc03_c(uint8_t *dst, const uint8_t *src, \ uint8_t full[16 * 9]; \ uint8_t half[64]; \ \ - copy_block9(full, src, 16, stride, 9); \ + copy_block8(full, src, 16, stride, 9); \ put ## RND ## mpeg4_qpel8_v_lowpass(half, full, 8, 16); \ OPNAME ## pixels8_l2_8(dst, full + 16, half, stride, 16, 8, 8); \ } \ @@ -458,7 +458,7 @@ static void OPNAME ## qpel16_mc01_c(uint8_t *dst, const uint8_t *src, \ uint8_t full[24 * 17]; \ uint8_t half[256]; \ \ - copy_block17(full, src, 24, stride, 17); \ + copy_block16(full, src, 24, stride, 17); \ put ## RND ## mpeg4_qpel16_v_lowpass(half, full, 16, 24); \ OPNAME ## pixels16_l2_8(dst, full, half, stride, 24, 16, 16); \ } \ @@ -468,7 +468,7 @@ static void OPNAME ## qpel16_mc02_c(uint8_t *dst, const uint8_t *src, \ { \ uint8_t full[24 * 17]; \ \ - copy_block17(full, src, 24, stride, 17); \ + copy_block16(full, src, 24, stride, 17); \ OPNAME ## mpeg4_qpel16_v_lowpass(dst, full, stride, 24); \ } \ \ @@ -478,7 +478,7 @@ static void OPNAME ## qpel16_mc03_c(uint8_t *dst, const uint8_t *src, \ uint8_t full[24 * 17]; \ uint8_t half[256]; \ \ - copy_block17(full, src, 24, stride, 17); \ + copy_block16(full, src, 24, stride, 17); \ put ## RND ## mpeg4_qpel16_v_lowpass(half, full, 16, 24); \ OPNAME ## pixels16_l2_8(dst, full + 24, half, stride, 24, 16, 16); \ } \ diff --git a/libavcodec/qsvdec.c b/libavcodec/qsvdec.c index 5f2e641373..ccc3de1e10 100644 --- a/libavcodec/qsvdec.c +++ b/libavcodec/qsvdec.c @@ -290,9 +290,12 @@ static int qsv_decode_init_context(AVCodecContext *avctx, QSVContext *q, mfxVide q->frame_info = param->mfx.FrameInfo; - if (!avctx->hw_frames_ctx) - q->pool = av_buffer_pool_init(av_image_get_buffer_size(avctx->pix_fmt, - FFALIGN(avctx->width, 128), FFALIGN(avctx->height, 64), 1), av_buffer_allocz); + if (!avctx->hw_frames_ctx) { + ret = av_image_get_buffer_size(avctx->pix_fmt, FFALIGN(avctx->width, 128), FFALIGN(avctx->height, 64), 1); + if (ret < 0) + return ret; + q->pool = av_buffer_pool_init(ret, av_buffer_allocz); + } return 0; } diff --git a/libavcodec/qtrleenc.c b/libavcodec/qtrleenc.c index 8b0edf7b3d..f7eee4a591 100644 --- a/libavcodec/qtrleenc.c +++ b/libavcodec/qtrleenc.c @@ -155,10 +155,14 @@ static void qtrle_encode_line(QtrleEncContext *s, const AVFrame *p, int line, ui int sec_lowest_bulk_cost; int sec_lowest_bulk_cost_index; - uint8_t *this_line = p-> data[0] + line*p-> linesize[0] + - (width - 1)*s->pixel_size; - uint8_t *prev_line = s->previous_frame->data[0] + line * s->previous_frame->linesize[0] + - (width - 1)*s->pixel_size; + const uint8_t *this_line = p->data[0] + line * p->linesize[0] + width * s->pixel_size; + /* There might be no earlier frame if the current frame is a keyframe. + * So just use a pointer to the current frame to avoid a check + * to avoid NULL - s->pixel_size (which is undefined behaviour). */ + const uint8_t *prev_line = s->key_frame ? this_line + : s->previous_frame->data[0] + + line * s->previous_frame->linesize[0] + + width * s->pixel_size; s->length_table[width] = 0; skipcount = 0; @@ -175,6 +179,9 @@ static void qtrle_encode_line(QtrleEncContext *s, const AVFrame *p, int line, ui int prev_bulk_cost; + this_line -= s->pixel_size; + prev_line -= s->pixel_size; + /* If our lowest bulk cost index is too far away, replace it * with the next lowest bulk cost */ if (FFMIN(width, i + MAX_RLE_BULK) < lowest_bulk_cost_index) { @@ -259,10 +266,6 @@ static void qtrle_encode_line(QtrleEncContext *s, const AVFrame *p, int line, ui /* These bulk costs increase every iteration */ lowest_bulk_cost += s->pixel_size; sec_lowest_bulk_cost += s->pixel_size; - if (this_line >= p->data[0] + s->pixel_size) - this_line -= s->pixel_size; - if (prev_line >= s->previous_frame->data[0] + s->pixel_size) - prev_line -= s->pixel_size; } /* Good! Now we have the best sequence for this line, let's output it. */ @@ -369,7 +372,8 @@ static int qtrle_encode_frame(AVCodecContext *avctx, AVPacket *pkt, if ((ret = ff_alloc_packet2(avctx, pkt, s->max_buf_size, 0)) < 0) return ret; - if (avctx->gop_size == 0 || (s->avctx->frame_number % avctx->gop_size) == 0) { + if (avctx->gop_size == 0 || !s->previous_frame->data[0] || + (s->avctx->frame_number % avctx->gop_size) == 0) { /* I-Frame */ s->key_frame = 1; } else { diff --git a/libavcodec/r210enc.c b/libavcodec/r210enc.c index be1943f5f9..e5e0e775c5 100644 --- a/libavcodec/r210enc.c +++ b/libavcodec/r210enc.c @@ -31,7 +31,7 @@ static av_cold int encode_init(AVCodecContext *avctx) avctx->bits_per_coded_sample = 32; if (avctx->width > 0) - avctx->bit_rate = ff_guess_coded_bitrate(avctx) * aligned_width / avctx->width; + avctx->bit_rate = av_rescale(ff_guess_coded_bitrate(avctx), aligned_width, avctx->width); return 0; } diff --git a/libavcodec/rangecoder.h b/libavcodec/rangecoder.h index 4495f6df1a..7b4f385e15 100644 --- a/libavcodec/rangecoder.h +++ b/libavcodec/rangecoder.h @@ -62,7 +62,6 @@ void ff_build_rac_states(RangeCoder *c, int factor, int max_p); static inline void renorm_encoder(RangeCoder *c) { // FIXME: optimize - while (c->range < 0x100) { if (c->outstanding_byte < 0) { c->outstanding_byte = c->low >> 8; } else if (c->low <= 0xFF00) { @@ -81,7 +80,6 @@ static inline void renorm_encoder(RangeCoder *c) c->low = (c->low & 0xFF) << 8; c->range <<= 8; - } } static inline int get_rac_count(RangeCoder *c) @@ -108,7 +106,8 @@ static inline void put_rac(RangeCoder *c, uint8_t *const state, int bit) *state = c->one_state[*state]; } - renorm_encoder(c); + while (c->range < 0x100) + renorm_encoder(c); } static inline void refill(RangeCoder *c) diff --git a/libavcodec/rasc.c b/libavcodec/rasc.c index 207d50c452..5ed1333886 100644 --- a/libavcodec/rasc.c +++ b/libavcodec/rasc.c @@ -722,6 +722,7 @@ static int decode_frame(AVCodecContext *avctx, break; default: bytestream2_skip(gb, size); + ret = 0; } if (ret < 0) diff --git a/libavcodec/rawdec.c b/libavcodec/rawdec.c index c18c3dd3e1..aaafbd46eb 100644 --- a/libavcodec/rawdec.c +++ b/libavcodec/rawdec.c @@ -493,6 +493,7 @@ static av_cold int raw_close_decoder(AVCodecContext *avctx) RawVideoContext *context = avctx->priv_data; av_buffer_unref(&context->palette); + av_freep(&context->bitstream_buf); return 0; } diff --git a/libavcodec/rpzaenc.c b/libavcodec/rpzaenc.c index baf067c205..b208753e2b 100644 --- a/libavcodec/rpzaenc.c +++ b/libavcodec/rpzaenc.c @@ -204,7 +204,7 @@ static void get_max_component_diff(BlockInfo *bi, uint16_t *block_ptr, // loop thru and compare pixels for (y = 0; y < bi->block_height; y++) { - for (x = 0; x < bi->block_width; x++){ + for (x = 0; x < bi->block_width; x++) { // TODO: optimize min_r = FFMIN(R(block_ptr[x]), min_r); min_g = FFMIN(G(block_ptr[x]), min_g); @@ -276,7 +276,7 @@ static int leastsquares(uint16_t *block_ptr, BlockInfo *bi, return -1; for (i = 0; i < bi->block_height; i++) { - for (j = 0; j < bi->block_width; j++){ + for (j = 0; j < bi->block_width; j++) { x = GET_CHAN(block_ptr[j], xchannel); y = GET_CHAN(block_ptr[j], ychannel); sumx += x; @@ -323,7 +323,7 @@ static int calc_lsq_max_fit_error(uint16_t *block_ptr, BlockInfo *bi, int max_err = 0; for (i = 0; i < bi->block_height; i++) { - for (j = 0; j < bi->block_width; j++){ + for (j = 0; j < bi->block_width; j++) { int x_inc, lin_y, lin_x; x = GET_CHAN(block_ptr[j], xchannel); y = GET_CHAN(block_ptr[j], ychannel); @@ -418,7 +418,9 @@ static void update_block_in_prev_frame(const uint16_t *src_pixels, uint16_t *dest_pixels, const BlockInfo *bi, int block_counter) { - for (int y = 0; y < 4; y++) { + const int y_size = FFMIN(4, bi->image_height - bi->row * 4); + + for (int y = 0; y < y_size; y++) { memcpy(dest_pixels, src_pixels, 8); dest_pixels += bi->rowstride; src_pixels += bi->rowstride; @@ -728,14 +730,15 @@ post_skip : if (err > s->sixteen_color_thresh) { // DO SIXTEEN COLOR BLOCK uint16_t *row_ptr; - int rgb555; + int y_size, rgb555; block_offset = get_block_info(&bi, block_counter); row_ptr = &src_pixels[block_offset]; + y_size = FFMIN(4, bi.image_height - bi.row * 4); - for (int y = 0; y < 4; y++) { - for (int x = 0; x < 4; x++){ + for (int y = 0; y < y_size; y++) { + for (int x = 0; x < 4; x++) { rgb555 = row_ptr[x] & ~0x8000; put_bits(&s->pb, 16, rgb555); @@ -743,6 +746,11 @@ post_skip : row_ptr += bi.rowstride; } + for (int y = y_size; y < 4; y++) { + for (int x = 0; x < 4; x++) + put_bits(&s->pb, 16, 0); + } + block_counter++; } else { // FOUR COLOR BLOCK block_counter += encode_four_color_block(min_color, max_color, diff --git a/libavcodec/rv10.c b/libavcodec/rv10.c index d5c7480611..9c3a48c251 100644 --- a/libavcodec/rv10.c +++ b/libavcodec/rv10.c @@ -154,7 +154,7 @@ static int rv10_decode_picture_header(MpegEncContext *s) return mb_count; } -static int rv20_decode_picture_header(RVDecContext *rv) +static int rv20_decode_picture_header(RVDecContext *rv, int whole_size) { MpegEncContext *s = &rv->m; int seq, mb_pos, i, ret; @@ -226,12 +226,16 @@ static int rv20_decode_picture_header(RVDecContext *rv) new_w = rv->orig_width; new_h = rv->orig_height; } - if (new_w != s->width || new_h != s->height) { + if (new_w != s->width || new_h != s->height || !s->context_initialized) { AVRational old_aspect = s->avctx->sample_aspect_ratio; av_log(s->avctx, AV_LOG_DEBUG, "attempting to change resolution to %dx%d\n", new_w, new_h); if (av_image_check_size(new_w, new_h, 0, s->avctx) < 0) return AVERROR_INVALIDDATA; + + if (whole_size < (new_w + 15)/16 * ((new_h + 15)/16) / 8) + return AVERROR_INVALIDDATA; + ff_mpv_common_end(s); // attempt to keep aspect during typical resolution switches @@ -447,7 +451,7 @@ static int rv10_decode_packet(AVCodecContext *avctx, const uint8_t *buf, if (s->codec_id == AV_CODEC_ID_RV10) mb_count = rv10_decode_picture_header(s); else - mb_count = rv20_decode_picture_header(rv); + mb_count = rv20_decode_picture_header(rv, whole_size); if (mb_count < 0) { if (mb_count != ERROR_SKIP_FRAME) av_log(s->avctx, AV_LOG_ERROR, "HEADER ERROR\n"); @@ -687,7 +691,6 @@ AVCodec ff_rv10_decoder = { .close = rv10_decode_end, .decode = rv10_decode_frame, .capabilities = AV_CODEC_CAP_DR1, - .caps_internal = FF_CODEC_CAP_INIT_CLEANUP, .max_lowres = 3, .pix_fmts = (const enum AVPixelFormat[]) { AV_PIX_FMT_YUV420P, @@ -705,7 +708,6 @@ AVCodec ff_rv20_decoder = { .close = rv10_decode_end, .decode = rv10_decode_frame, .capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_DELAY, - .caps_internal = FF_CODEC_CAP_INIT_CLEANUP, .flush = ff_mpeg_flush, .max_lowres = 3, .pix_fmts = (const enum AVPixelFormat[]) { diff --git a/libavcodec/rv34.c b/libavcodec/rv34.c index 7e5bfe0e22..6cd42e585b 100644 --- a/libavcodec/rv34.c +++ b/libavcodec/rv34.c @@ -96,6 +96,8 @@ static void rv34_gen_vlc(const uint8_t *bits, int size, VLC *vlc, const uint8_t uint16_t cw[MAX_VLC_SIZE]; int maxbits; + av_assert1(size > 0); + for (int i = 0; i < size; i++) counts[bits[i]]++; @@ -1383,6 +1385,7 @@ static int rv34_decoder_alloc(RV34DecContext *r) if (!(r->cbp_chroma && r->cbp_luma && r->deblock_coefs && r->intra_types_hist && r->mb_type)) { + r->s.context_reinit = 1; rv34_decoder_free(r); return AVERROR(ENOMEM); } @@ -1530,7 +1533,7 @@ int ff_rv34_decode_update_thread_context(AVCodecContext *dst, const AVCodecConte if (dst == src || !s1->context_initialized) return 0; - if (s->height != s1->height || s->width != s1->width) { + if (s->height != s1->height || s->width != s1->width || s->context_reinit) { s->height = s1->height; s->width = s1->width; if ((err = ff_mpv_common_frame_size_change(s)) < 0) @@ -1667,11 +1670,12 @@ int ff_rv34_decode_frame(AVCodecContext *avctx, if (s->mb_num_left > 0 && s->current_picture_ptr) { av_log(avctx, AV_LOG_ERROR, "New frame but still %d MB left.\n", s->mb_num_left); - ff_er_frame_end(&s->er); + if (!s->context_reinit) + ff_er_frame_end(&s->er); ff_mpv_frame_end(s); } - if (s->width != si.width || s->height != si.height) { + if (s->width != si.width || s->height != si.height || s->context_reinit) { int err; av_log(s->avctx, AV_LOG_WARNING, "Changing dimensions to %dx%d\n", @@ -1689,7 +1693,6 @@ int ff_rv34_decode_frame(AVCodecContext *avctx, err = ff_set_dimensions(s->avctx, s->width, s->height); if (err < 0) return err; - if ((err = ff_mpv_common_frame_size_change(s)) < 0) return err; if ((err = rv34_decoder_realloc(r)) < 0) @@ -1744,6 +1747,10 @@ int ff_rv34_decode_frame(AVCodecContext *avctx, } s->mb_x = s->mb_y = 0; ff_thread_finish_setup(s->avctx); + } else if (s->context_reinit) { + av_log(s->avctx, AV_LOG_ERROR, "Decoder needs full frames to " + "reinitialize (start MB is %d).\n", si.start); + return AVERROR_INVALIDDATA; } else if (HAVE_THREADS && (s->avctx->active_thread_type & FF_THREAD_FRAME)) { av_log(s->avctx, AV_LOG_ERROR, "Decoder needs full frames in frame " diff --git a/libavcodec/sbrdsp_fixed.c b/libavcodec/sbrdsp_fixed.c index 91fa664c08..0d34a2a710 100644 --- a/libavcodec/sbrdsp_fixed.c +++ b/libavcodec/sbrdsp_fixed.c @@ -87,7 +87,7 @@ static void sbr_neg_odd_64_c(int *x) { int i; for (i = 1; i < 64; i += 2) - x[i] = -x[i]; + x[i] = -(unsigned)x[i]; } static void sbr_qmf_pre_shuffle_c(int *z) @@ -114,8 +114,8 @@ static void sbr_qmf_deint_neg_c(int *v, const int *src) { int i; for (i = 0; i < 32; i++) { - v[ i] = ( src[63 - 2*i ] + 0x10) >> 5; - v[63 - i] = (-src[63 - 2*i - 1] + 0x10) >> 5; + v[ i] = (int)(0x10U + src[63 - 2*i ]) >> 5; + v[63 - i] = (int)(0x10U - src[63 - 2*i - 1]) >> 5; } } diff --git a/libavcodec/scpr.c b/libavcodec/scpr.c index 2a0ebcecfc..f78f43b5cd 100644 --- a/libavcodec/scpr.c +++ b/libavcodec/scpr.c @@ -459,6 +459,9 @@ static int decompress_p(AVCodecContext *avctx, int run, bx = x * 16 + sx1, by = y * 16 + sy1; uint32_t r, g, b, clr, ptype = 0; + if (bx >= avctx->width) + return AVERROR_INVALIDDATA; + for (; by < y * 16 + sy2 && by < avctx->height;) { ret = decode_value(s, s->op_model[ptype], 6, 1000, &ptype); if (ret < 0) diff --git a/libavcodec/scpr3.c b/libavcodec/scpr3.c index 78c58889cb..85524feafe 100644 --- a/libavcodec/scpr3.c +++ b/libavcodec/scpr3.c @@ -466,6 +466,8 @@ static int decode_adaptive6(PixelModel3 *m, uint32_t code, uint32_t *value, return 0; grow_dec(m); c = add_dec(m, q, g, f); + if (c < 0) + return AVERROR_INVALIDDATA; } incr_cntdec(m, c); @@ -869,11 +871,11 @@ static int decode_unit3(SCPRContext *s, PixelModel3 *m, uint32_t code, uint32_t sync_code3(gb, rc); break; case 6: - if (!decode_adaptive6(m, code, value, &a, &b)) { + ret = decode_adaptive6(m, code, value, &a, &b); + if (!ret) ret = update_model6_to_7(m); - if (ret < 0) - return AVERROR_INVALIDDATA; - } + if (ret < 0) + return ret; decode3(gb, rc, a, b); sync_code3(gb, rc); break; @@ -1168,6 +1170,9 @@ static int decompress_p3(AVCodecContext *avctx, int run, bx = x * 16 + sx1, by = y * 16 + sy1; uint32_t clr, ptype = 0, r, g, b; + if (bx >= avctx->width) + return AVERROR_INVALIDDATA; + for (; by < y * 16 + sy2 && by < avctx->height;) { ret = decode_value3(s, 5, &s->op_model3[ptype].cntsum, s->op_model3[ptype].freqs[0], diff --git a/libavcodec/setts_bsf.c b/libavcodec/setts_bsf.c index 5b6b256915..2558e38f51 100644 --- a/libavcodec/setts_bsf.c +++ b/libavcodec/setts_bsf.c @@ -152,7 +152,7 @@ static int setts_filter(AVBSFContext *ctx, AVPacket *pkt) s->var_values[VAR_PREV_OUTDTS] = s->prev_outdts; s->var_values[VAR_STARTPTS] = s->start_pts; s->var_values[VAR_STARTDTS] = s->start_dts; - s->var_values[VAR_TB] = av_q2d(ctx->time_base_out); + s->var_values[VAR_TB] = ctx->time_base_out.den ? av_q2d(ctx->time_base_out) : 0; s->var_values[VAR_SR] = ctx->par_in->sample_rate; new_ts = llrint(av_expr_eval(s->ts_expr, s->var_values, NULL)); diff --git a/libavcodec/sga.c b/libavcodec/sga.c index 00752a5843..53a1abd5cd 100644 --- a/libavcodec/sga.c +++ b/libavcodec/sga.c @@ -72,7 +72,7 @@ static int decode_palette(GetByteContext *gb, uint32_t *pal) return AVERROR_INVALIDDATA; memset(pal, 0, 16 * sizeof(*pal)); - init_get_bits8(&gbit, gb->buffer, 18); + (void)init_get_bits8(&gbit, gb->buffer, 18); for (int RGBIndex = 0; RGBIndex < 3; RGBIndex++) { for (int index = 0; index < 16; index++) { @@ -232,7 +232,7 @@ static int lzss_decompress(AVCodecContext *avctx, if (offset <= 0) offset = 1; - if (oi < offset) + if (oi < offset || oi + count * 2 > dst_size) return AVERROR_INVALIDDATA; for (int j = 0; j < count * 2; j++) { dst[oi] = dst[oi - offset]; @@ -254,11 +254,13 @@ static int decode_palmapdata(AVCodecContext *avctx) const int bits = (s->nb_pal + 1) / 2; GetByteContext *gb = &s->gb; GetBitContext pm; + int ret; bytestream2_seek(gb, s->palmapdata_offset, SEEK_SET); if (bytestream2_get_bytes_left(gb) < s->palmapdata_size) return AVERROR_INVALIDDATA; - init_get_bits8(&pm, gb->buffer, s->palmapdata_size); + ret = init_get_bits8(&pm, gb->buffer, s->palmapdata_size); + av_assert1(ret >= 0); for (int y = 0; y < s->tiles_h; y++) { uint8_t *dst = s->palmapindex_data + y * s->tiles_w; @@ -277,11 +279,13 @@ static int decode_tiledata(AVCodecContext *avctx) SGAVideoContext *s = avctx->priv_data; GetByteContext *gb = &s->gb; GetBitContext tm; + int ret; bytestream2_seek(gb, s->tiledata_offset, SEEK_SET); if (bytestream2_get_bytes_left(gb) < s->tiledata_size) return AVERROR_INVALIDDATA; - init_get_bits8(&tm, gb->buffer, s->tiledata_size); + ret = init_get_bits8(&tm, gb->buffer, s->tiledata_size); + av_assert1(ret >= 0); for (int n = 0; n < s->nb_tiles; n++) { uint8_t *dst = s->tileindex_data + n * 64; diff --git a/libavcodec/shorten.c b/libavcodec/shorten.c index 70d164a0b3..31391baa98 100644 --- a/libavcodec/shorten.c +++ b/libavcodec/shorten.c @@ -558,6 +558,7 @@ static int shorten_decode_frame(AVCodecContext *avctx, void *data, buf = &s->bitstream[s->bitstream_index]; buf_size += s->bitstream_size; s->bitstream_size = buf_size; + memset(buf + buf_size, 0, AV_INPUT_BUFFER_PADDING_SIZE); /* do not decode until buffer has at least max_framesize bytes or * the end of the file has been reached */ diff --git a/libavcodec/snow.c b/libavcodec/snow.c index bb65a6f43f..cbb225c490 100644 --- a/libavcodec/snow.c +++ b/libavcodec/snow.c @@ -499,7 +499,7 @@ av_cold int ff_snow_common_init(AVCodecContext *avctx){ !FF_ALLOCZ_TYPED_ARRAY(s->spatial_dwt_buffer, width * height) || //FIXME this does not belong here !FF_ALLOCZ_TYPED_ARRAY(s->temp_dwt_buffer, width) || !FF_ALLOCZ_TYPED_ARRAY(s->temp_idwt_buffer, width) || - !FF_ALLOCZ_TYPED_ARRAY(s->run_buffer, ((width + 1) >> 1) * ((height + 1) >> 1))) + !FF_ALLOCZ_TYPED_ARRAY(s->run_buffer, ((width + 1) >> 1) * ((height + 1) >> 1) + 1)) return AVERROR(ENOMEM); for(i=0; ispatial_decomposition_count ); - av_assert0(!s->avmv); if (s->avctx->export_side_data & AV_CODEC_EXPORT_DATA_MVS) { - s->avmv = av_malloc_array(s->b_width * s->b_height, sizeof(AVMotionVector) << (s->block_max_depth*2)); + size_t size; + res = av_size_mult(s->b_width * s->b_height, sizeof(AVMotionVector) << (s->block_max_depth*2), &size); + if (res) + return res; + av_fast_malloc(&s->avmv, &s->avmv_size, size); + if (!s->avmv) + return AVERROR(ENOMEM); + } else { + s->avmv_size = 0; + av_freep(&s->avmv); } s->avmv_index = 0; @@ -624,8 +632,6 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame, memcpy(sd->data, s->avmv, s->avmv_index * sizeof(AVMotionVector)); } - av_freep(&s->avmv); - if (res < 0) return res; @@ -645,6 +651,9 @@ static av_cold int decode_end(AVCodecContext *avctx) ff_snow_common_end(s); + s->avmv_size = 0; + av_freep(&s->avmv); + return 0; } diff --git a/libavcodec/snowenc.c b/libavcodec/snowenc.c index 16d2b7c302..2948c76cb0 100644 --- a/libavcodec/snowenc.c +++ b/libavcodec/snowenc.c @@ -269,6 +269,7 @@ static int encode_q_branch(SnowContext *s, int level, int x, int y){ int my_context= av_log2(2*FFABS(left->my - top->my)); int s_context= 2*left->level + 2*top->level + tl->level + tr->level; int ref, best_ref, ref_score, ref_mx, ref_my; + int range = MAX_MV >> (1 + qpel); av_assert0(sizeof(s->block_state) >= 256); if(s->keyframe){ @@ -310,6 +311,11 @@ static int encode_q_branch(SnowContext *s, int level, int x, int y){ c->xmax = - (x+1)*block_w + (w<<(LOG2_MB_SIZE - s->block_max_depth)) + 16-3; c->ymax = - (y+1)*block_w + (h<<(LOG2_MB_SIZE - s->block_max_depth)) + 16-3; + c->xmin = FFMAX(c->xmin,-range); + c->xmax = FFMIN(c->xmax, range); + c->ymin = FFMAX(c->ymin,-range); + c->ymax = FFMIN(c->ymax, range); + if(P_LEFT[0] > (c->xmax<xmax< (c->ymax<ymax< (c->xmax<xmax<spatial_decomposition_count; level++){ + int64_t error=0; for(orientation=level ? 1 : 0; orientation<4; orientation++){ SubBand *b= &p->band[level][orientation]; IDWTELEM *ibuf= b->ibuf; - int64_t error=0; memset(s->spatial_idwt_buffer, 0, sizeof(*s->spatial_idwt_buffer)*width*height); ibuf[b->width/2 + b->height/2*b->stride]= 256*16; @@ -1558,9 +1564,13 @@ static void calculate_visual_weight(SnowContext *s, Plane *p){ error += d*d; } } - + if (orientation == 2) + error /= 2; b->qlog= (int)(QROOT * log2(352256.0/sqrt(error)) + 0.5); + if (orientation != 1) + error = 0; } + p->band[level][1].qlog = p->band[level][2].qlog; } } diff --git a/libavcodec/sonic.c b/libavcodec/sonic.c index 32e94d24f6..b13cdc3c12 100644 --- a/libavcodec/sonic.c +++ b/libavcodec/sonic.c @@ -467,7 +467,7 @@ static void predictor_init_state(int *k, int *state, int order) static int predictor_calc_error(int *k, int *state, int order, int error) { - int i, x = error - shift_down(k[order-1] * (unsigned)state[order-1], LATTICE_SHIFT); + int i, x = error - (unsigned)shift_down(k[order-1] * (unsigned)state[order-1], LATTICE_SHIFT); #if 1 int *k_ptr = &(k[order-2]), @@ -475,13 +475,13 @@ static int predictor_calc_error(int *k, int *state, int order, int error) for (i = order-2; i >= 0; i--, k_ptr--, state_ptr--) { int k_value = *k_ptr, state_value = *state_ptr; - x -= shift_down(k_value * (unsigned)state_value, LATTICE_SHIFT); + x -= (unsigned)shift_down(k_value * (unsigned)state_value, LATTICE_SHIFT); state_ptr[1] = state_value + shift_down(k_value * (unsigned)x, LATTICE_SHIFT); } #else for (i = order-2; i >= 0; i--) { - x -= shift_down(k[i] * state[i], LATTICE_SHIFT); + x -= (unsigned)shift_down(k[i] * state[i], LATTICE_SHIFT); state[i+1] = state[i] + shift_down(k[i] * x, LATTICE_SHIFT); } #endif @@ -917,6 +917,9 @@ static av_cold int sonic_decode_init(AVCodecContext *avctx) if (get_bits1(&gb)) // XXX FIXME av_log(avctx, AV_LOG_INFO, "Custom quant table\n"); + if (s->num_taps > 128) + return AVERROR_INVALIDDATA; + s->block_align = 2048LL*s->samplerate/(44100*s->downsampling); s->frame_size = s->channels*s->block_align*s->downsampling; // avctx->frame_size = s->block_align; @@ -1004,12 +1007,12 @@ static int sonic_decode_frame(AVCodecContext *avctx, // dequantize for (i = 0; i < s->num_taps; i++) - s->predictor_k[i] *= s->tap_quant[i]; + s->predictor_k[i] *= (unsigned) s->tap_quant[i]; if (s->lossless) quant = 1; else - quant = get_symbol(&c, state, 0) * SAMPLE_FACTOR; + quant = get_symbol(&c, state, 0) * (unsigned)SAMPLE_FACTOR; // av_log(NULL, AV_LOG_INFO, "quant: %d\n", quant); diff --git a/libavcodec/speedhq.c b/libavcodec/speedhq.c index 711bcd66d7..5bf03a35e6 100644 --- a/libavcodec/speedhq.c +++ b/libavcodec/speedhq.c @@ -498,7 +498,9 @@ static int speedhq_decode_frame(AVCodecContext *avctx, uint32_t second_field_offset; int ret; - if (buf_size < 4 || avctx->width < 8) + if (buf_size < 4 || avctx->width < 8 || avctx->width % 8 != 0) + return AVERROR_INVALIDDATA; + if (buf_size < avctx->width*avctx->height / 64 / 4) return AVERROR_INVALIDDATA; quality = buf[0]; diff --git a/libavcodec/sunrast.c b/libavcodec/sunrast.c index e1ec8a0832..991915fa62 100644 --- a/libavcodec/sunrast.c +++ b/libavcodec/sunrast.c @@ -19,6 +19,7 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ +#include "libavutil/avassert.h" #include "libavutil/common.h" #include "libavutil/intreadwrite.h" #include "libavutil/imgutils.h" @@ -75,6 +76,12 @@ static int sunrast_decode_frame(AVCodecContext *avctx, void *data, return AVERROR_PATCHWELCOME; } + if (maplength > 768) { + av_log(avctx, AV_LOG_WARNING, "invalid colormap length\n"); + return AVERROR_INVALIDDATA; + } + + // This also checks depth to be valid switch (depth) { case 1: avctx->pix_fmt = maplength ? AV_PIX_FMT_PAL8 : AV_PIX_FMT_MONOWHITE; @@ -96,15 +103,23 @@ static int sunrast_decode_frame(AVCodecContext *avctx, void *data, return AVERROR_INVALIDDATA; } + // This checks w and h to be valid in the sense that bytes of a padded bitmap are addressable with 32bit int ret = ff_set_dimensions(avctx, w, h); if (ret < 0) return ret; + // ensured by ff_set_dimensions() + av_assert0(w <= (INT32_MAX - 7) / depth); + /* scanlines are aligned on 16 bit boundaries */ len = (depth * w + 7) >> 3; alen = len + (len & 1); - if (buf_end - buf < maplength + (len * h) * 3 / 256) + // ensured by ff_set_dimensions() + av_assert0(h <= INT32_MAX / (3 * len)); + + // maplength is limited to 768 and the right term is limited to INT32_MAX / 256 so the add needs no check + if (buf_end - buf < (uint64_t)maplength + (len * h) * 3 / 256) return AVERROR_INVALIDDATA; if ((ret = ff_get_buffer(avctx, p, 0)) < 0) @@ -118,7 +133,7 @@ static int sunrast_decode_frame(AVCodecContext *avctx, void *data, } else if (maplength) { unsigned int len = maplength / 3; - if (maplength % 3 || maplength > 768) { + if (maplength % 3) { av_log(avctx, AV_LOG_WARNING, "invalid colormap length\n"); return AVERROR_INVALIDDATA; } diff --git a/libavcodec/svq1enc.c b/libavcodec/svq1enc.c index 4fac0c26e5..1b5da03245 100644 --- a/libavcodec/svq1enc.c +++ b/libavcodec/svq1enc.c @@ -487,9 +487,10 @@ static av_cold int svq1_encode_end(AVCodecContext *avctx) SVQ1EncContext *const s = avctx->priv_data; int i; - av_log(avctx, AV_LOG_DEBUG, "RD: %f\n", - s->rd_total / (double)(avctx->width * avctx->height * - avctx->frame_number)); + if (avctx->frame_number) + av_log(avctx, AV_LOG_DEBUG, "RD: %f\n", + s->rd_total / (double)(avctx->width * avctx->height * + avctx->frame_number)); s->m.mb_type = NULL; ff_mpv_common_end(&s->m); diff --git a/libavcodec/svq3.c b/libavcodec/svq3.c index 54ef4add06..a7d74b2e5f 100644 --- a/libavcodec/svq3.c +++ b/libavcodec/svq3.c @@ -1259,6 +1259,7 @@ static av_cold int svq3_decode_init(AVCodecContext *avctx) uint8_t *buf; if (watermark_height <= 0 || + get_bits_left(&gb) <= 0 || (uint64_t)watermark_width * 4 > UINT_MAX / watermark_height) return AVERROR_INVALIDDATA; @@ -1417,6 +1418,9 @@ static int svq3_decode_frame(AVCodecContext *avctx, void *data, if (svq3_decode_slice_header(avctx)) return -1; + if (avpkt->size < s->mb_width * s->mb_height / 8) + return AVERROR_INVALIDDATA; + s->pict_type = s->slice_type; if (s->pict_type != AV_PICTURE_TYPE_B) diff --git a/libavcodec/tak.c b/libavcodec/tak.c index 8aa956b661..7989afbd97 100644 --- a/libavcodec/tak.c +++ b/libavcodec/tak.c @@ -167,6 +167,9 @@ int ff_tak_decode_frame_header(AVCodecContext *avctx, GetBitContext *gb, if (ti->flags & TAK_FRAME_FLAG_HAS_METADATA) return AVERROR_INVALIDDATA; + if (get_bits_left(gb) < 24) + return AVERROR_INVALIDDATA; + skip_bits(gb, 24); return 0; diff --git a/libavcodec/takdec.c b/libavcodec/takdec.c index 931e5d3fb4..f603386015 100644 --- a/libavcodec/takdec.c +++ b/libavcodec/takdec.c @@ -432,6 +432,9 @@ static int decode_subframe(TAKDecContext *s, int32_t *decoded, return AVERROR_INVALIDDATA; } + if (get_bits_left(gb) < 2*10 + 2*size) + return AVERROR_INVALIDDATA; + s->predictors[0] = get_sbits(gb, 10); s->predictors[1] = get_sbits(gb, 10); s->predictors[2] = get_sbits(gb, size) * (1 << (10 - size)); diff --git a/libavcodec/takdsp.c b/libavcodec/takdsp.c index 9cb8052596..f5dc47988f 100644 --- a/libavcodec/takdsp.c +++ b/libavcodec/takdsp.c @@ -28,8 +28,8 @@ static void decorrelate_ls(int32_t *p1, int32_t *p2, int length) int i; for (i = 0; i < length; i++) { - int32_t a = p1[i]; - int32_t b = p2[i]; + uint32_t a = p1[i]; + uint32_t b = p2[i]; p2[i] = a + b; } } @@ -39,8 +39,8 @@ static void decorrelate_sr(int32_t *p1, int32_t *p2, int length) int i; for (i = 0; i < length; i++) { - int32_t a = p1[i]; - int32_t b = p2[i]; + uint32_t a = p1[i]; + uint32_t b = p2[i]; p1[i] = b - a; } } @@ -50,7 +50,7 @@ static void decorrelate_sm(int32_t *p1, int32_t *p2, int length) int i; for (i = 0; i < length; i++) { - int32_t a = p1[i]; + uint32_t a = p1[i]; int32_t b = p2[i]; a -= b >> 1; p1[i] = a; @@ -63,9 +63,9 @@ static void decorrelate_sf(int32_t *p1, int32_t *p2, int length, int dshift, int int i; for (i = 0; i < length; i++) { - int32_t a = p1[i]; + uint32_t a = p1[i]; int32_t b = p2[i]; - b = (unsigned)(dfactor * (b >> dshift) + 128 >> 8) << dshift; + b = (unsigned)((int)(dfactor * (unsigned)(b >> dshift) + 128) >> 8) << dshift; p1[i] = b - a; } } diff --git a/libavcodec/targaenc.c b/libavcodec/targaenc.c index 79030a012b..e939b90414 100644 --- a/libavcodec/targaenc.c +++ b/libavcodec/targaenc.c @@ -21,6 +21,7 @@ #include +#include "libavutil/avassert.h" #include "libavutil/imgutils.h" #include "libavutil/internal.h" #include "libavutil/intreadwrite.h" @@ -88,10 +89,11 @@ static int targa_encode_frame(AVCodecContext *avctx, AVPacket *pkt, TargaContext *s = avctx->priv_data; int bpp, picsize, datasize = -1, ret, i; uint8_t *out; + int maxpal = 32*32; picsize = av_image_get_buffer_size(avctx->pix_fmt, avctx->width, avctx->height, 1); - if ((ret = ff_alloc_packet2(avctx, pkt, picsize + 45, 0)) < 0) + if ((ret = ff_alloc_packet2(avctx, pkt, picsize + 45 + maxpal, 0)) < 0) return ret; /* zero out the header and only set applicable fields */ @@ -124,6 +126,7 @@ static int targa_encode_frame(AVCodecContext *avctx, AVPacket *pkt, AV_WL24(pkt->data + 18 + 3 * i, *(uint32_t *)(p->data[1] + i * 4)); } out += 32 * pal_bpp; /* skip past the palette we just output */ + av_assert0(32 * pal_bpp <= maxpal); break; } case AV_PIX_FMT_GRAY8: diff --git a/libavcodec/tests/dct.c b/libavcodec/tests/dct.c index eab39e9468..269b4993b3 100644 --- a/libavcodec/tests/dct.c +++ b/libavcodec/tests/dct.c @@ -223,8 +223,8 @@ static int dct_error(const struct algo *dct, int test, int is_idct, int speed, c v = abs(err); if (v > err_inf) err_inf = v; - err2_matrix[i] += v * v; - err2 += v * v; + err2_matrix[i] += v * (int64_t)v; + err2 += v * (int64_t)v; sysErr[i] += block[i] - block1[i]; blockSumErr += v; if (abs(block[i]) > maxout) diff --git a/libavcodec/tests/jpeg2000dwt.c b/libavcodec/tests/jpeg2000dwt.c index 80b33bee79..a6cf9f6824 100644 --- a/libavcodec/tests/jpeg2000dwt.c +++ b/libavcodec/tests/jpeg2000dwt.c @@ -47,12 +47,12 @@ static int test_dwt(int *array, int *ref, int border[2][2], int decomp_levels, i return 1; } for (j = 0; j max_diff) { + if (FFABS(array[j] - (int64_t)ref[j]) > max_diff) { fprintf(stderr, "missmatch at %d (%d != %d) decomp:%d border %d %d %d %d\n", j, array[j], ref[j],decomp_levels, border[0][0], border[0][1], border[1][0], border[1][1]); return 2; } - err2 += (array[j] - ref[j]) * (array[j] - ref[j]); + err2 += (array[j] - ref[j]) * (int64_t)(array[j] - ref[j]); array[j] = ref[j]; } ff_dwt_destroy(s); diff --git a/libavcodec/tests/snowenc.c b/libavcodec/tests/snowenc.c index d5f94e8a61..65699158ca 100644 --- a/libavcodec/tests/snowenc.c +++ b/libavcodec/tests/snowenc.c @@ -31,11 +31,13 @@ int main(void){ #define width 256 #define height 256 int buffer[2][width*height]; + short obuffer[width*height]; SnowContext s; int i; AVLFG prng; s.spatial_decomposition_count=6; s.spatial_decomposition_type=1; + int ret = 0; s.temp_dwt_buffer = av_mallocz_array(width, sizeof(DWTELEM)); s.temp_idwt_buffer = av_mallocz_array(width, sizeof(IDWTELEM)); @@ -49,24 +51,34 @@ int main(void){ printf("testing 5/3 DWT\n"); for(i=0; i20) printf("fsck: %6d %12d %7d\n",i, buffer[0][i], buffer[1][i]); + if(FFABS(buffer[1][i] - obuffer[i])>20) { + printf("fsck: %4dx%4d %12d %7d\n",i%width, i/width, buffer[1][i], obuffer[i]); + ret = 1; + } { int level, orientation, x, y; @@ -81,18 +93,18 @@ int main(void){ int w= width >> (s.spatial_decomposition_count-level); int h= height >> (s.spatial_decomposition_count-level); int stride= width << (s.spatial_decomposition_count-level); - DWTELEM *buf= buffer[0]; + IDWTELEM *buf= obuffer; int64_t error=0; if(orientation&1) buf+=w; if(orientation>1) buf+=stride>>1; - memset(buffer[0], 0, sizeof(int)*width*height); - buf[w/2 + h/2*stride]= 256*256; - ff_spatial_idwt((IDWTELEM*)buffer[0], s.temp_idwt_buffer, width, height, width, s.spatial_decomposition_type, s.spatial_decomposition_count); + memset(obuffer, 0, sizeof(short)*width*height); + buf[w/2 + h/2*stride]= 8*256; + ff_spatial_idwt(obuffer, s.temp_idwt_buffer, width, height, width, s.spatial_decomposition_type, s.spatial_decomposition_count); for(y=0; y maxv) + else if (bp[x * 4 + y * stride] > maxv) maxv = bp[x * 4 + y * stride]; } } diff --git a/libavcodec/tiff.c b/libavcodec/tiff.c index 0878098b90..9819f9924e 100644 --- a/libavcodec/tiff.c +++ b/libavcodec/tiff.c @@ -100,7 +100,6 @@ typedef struct TiffContext { int is_tiled; int tile_byte_counts_offset, tile_offsets_offset; int tile_width, tile_length; - int tile_count; int is_jpeg; @@ -275,9 +274,101 @@ static int add_metadata(int count, int type, }; } +/** + * Map stored raw sensor values into linear reference values (see: DNG Specification - Chapter 5) + */ +static uint16_t av_always_inline dng_process_color16(uint16_t value, + const uint16_t *lut, + uint16_t black_level, + float scale_factor) +{ + float value_norm; + + // Lookup table lookup + if (lut) + value = lut[value]; + + // Black level subtraction + value = av_clip_uint16_c((unsigned)value - black_level); + + // Color scaling + value_norm = (float)value * scale_factor; + + value = av_clip_uint16_c(value_norm * 65535); + + return value; +} + +static uint16_t av_always_inline dng_process_color8(uint16_t value, + const uint16_t *lut, + uint16_t black_level, + float scale_factor) +{ + return dng_process_color16(value, lut, black_level, scale_factor) >> 8; +} + static void av_always_inline dng_blit(TiffContext *s, uint8_t *dst, int dst_stride, const uint8_t *src, int src_stride, int width, int height, - int is_single_comp, int is_u16); + int is_single_comp, int is_u16) +{ + int line, col; + float scale_factor; + + scale_factor = 1.0f / (s->white_level - s->black_level); + + if (is_single_comp) { + if (!is_u16) + return; /* <= 8bpp unsupported */ + + /* Image is double the width and half the height we need, each row comprises 2 rows of the output + (split vertically in the middle). */ + for (line = 0; line < height / 2; line++) { + uint16_t *dst_u16 = (uint16_t *)dst; + uint16_t *src_u16 = (uint16_t *)src; + + /* Blit first half of input row row to initial row of output */ + for (col = 0; col < width; col++) + *dst_u16++ = dng_process_color16(*src_u16++, s->dng_lut, s->black_level, scale_factor); + + /* Advance the destination pointer by a row (source pointer remains in the same place) */ + dst += dst_stride * sizeof(uint16_t); + dst_u16 = (uint16_t *)dst; + + /* Blit second half of input row row to next row of output */ + for (col = 0; col < width; col++) + *dst_u16++ = dng_process_color16(*src_u16++, s->dng_lut, s->black_level, scale_factor); + + dst += dst_stride * sizeof(uint16_t); + src += src_stride * sizeof(uint16_t); + } + } else { + /* Input and output image are the same size and the MJpeg decoder has done per-component + deinterleaving, so blitting here is straightforward. */ + if (is_u16) { + for (line = 0; line < height; line++) { + uint16_t *dst_u16 = (uint16_t *)dst; + uint16_t *src_u16 = (uint16_t *)src; + + for (col = 0; col < width; col++) + *dst_u16++ = dng_process_color16(*src_u16++, s->dng_lut, s->black_level, scale_factor); + + dst += dst_stride * sizeof(uint16_t); + src += src_stride * sizeof(uint16_t); + } + } else { + for (line = 0; line < height; line++) { + uint8_t *dst_u8 = dst; + const uint8_t *src_u8 = src; + + for (col = 0; col < width; col++) + *dst_u8++ = dng_process_color8(*src_u8++, s->dng_lut, s->black_level, scale_factor); + + dst += dst_stride; + src += src_stride; + } + } + } +} static void av_always_inline horizontal_fill(TiffContext *s, unsigned int bpp, uint8_t* dst, @@ -319,7 +410,8 @@ static void av_always_inline horizontal_fill(TiffContext *s, uint8_t shift = is_dng ? 0 : 16 - bpp; GetBitContext gb; - init_get_bits8(&gb, src, width); + int ret = init_get_bits8(&gb, src, width); + av_assert1(ret >= 0); for (int i = 0; i < s->width; i++) { dst16[i] = get_bits(&gb, bpp) << shift; } @@ -353,7 +445,8 @@ static void unpack_gray(TiffContext *s, AVFrame *p, GetBitContext gb; uint16_t *dst = (uint16_t *)(p->data[0] + lnum * p->linesize[0]); - init_get_bits8(&gb, src, width); + int ret = init_get_bits8(&gb, src, width); + av_assert1(ret >= 0); for (int i = 0; i < s->width; i++) { dst[i] = get_bits(&gb, bpp); @@ -553,7 +646,95 @@ static int tiff_unpack_fax(TiffContext *s, uint8_t *dst, int stride, return ret; } -static int dng_decode_strip(AVCodecContext *avctx, AVFrame *frame); +static int dng_decode_jpeg(AVCodecContext *avctx, AVFrame *frame, + int tile_byte_count, int dst_x, int dst_y, int w, int h) +{ + TiffContext *s = avctx->priv_data; + uint8_t *dst_data, *src_data; + uint32_t dst_offset; /* offset from dst buffer in pixels */ + int is_single_comp, is_u16, pixel_size; + int ret; + + if (tile_byte_count < 0 || tile_byte_count > bytestream2_get_bytes_left(&s->gb)) + return AVERROR_INVALIDDATA; + + /* Prepare a packet and send to the MJPEG decoder */ + av_packet_unref(s->jpkt); + s->jpkt->data = (uint8_t*)s->gb.buffer; + s->jpkt->size = tile_byte_count; + + if (s->is_bayer) { + MJpegDecodeContext *mjpegdecctx = s->avctx_mjpeg->priv_data; + /* We have to set this information here, there is no way to know if a given JPEG is a DNG-embedded + image or not from its own data (and we need that information when decoding it). */ + mjpegdecctx->bayer = 1; + } + + ret = avcodec_send_packet(s->avctx_mjpeg, s->jpkt); + if (ret < 0) { + av_log(avctx, AV_LOG_ERROR, "Error submitting a packet for decoding\n"); + return ret; + } + + ret = avcodec_receive_frame(s->avctx_mjpeg, s->jpgframe); + if (ret < 0) { + av_log(avctx, AV_LOG_ERROR, "JPEG decoding error: %s.\n", av_err2str(ret)); + + /* Normally skip, error if explode */ + if (avctx->err_recognition & AV_EF_EXPLODE) + return AVERROR_INVALIDDATA; + else + return 0; + } + + is_u16 = (s->bpp > 8); + + /* Copy the outputted tile's pixels from 'jpgframe' to 'frame' (final buffer) */ + + if (s->jpgframe->width != s->avctx_mjpeg->width || + s->jpgframe->height != s->avctx_mjpeg->height || + s->jpgframe->format != s->avctx_mjpeg->pix_fmt) + return AVERROR_INVALIDDATA; + + /* See dng_blit for explanation */ + if (s->avctx_mjpeg->width == w * 2 && + s->avctx_mjpeg->height == h / 2 && + s->avctx_mjpeg->pix_fmt == AV_PIX_FMT_GRAY16LE) { + is_single_comp = 1; + } else if (s->avctx_mjpeg->width >= w && + s->avctx_mjpeg->height >= h && + s->avctx_mjpeg->pix_fmt == (is_u16 ? AV_PIX_FMT_GRAY16 : AV_PIX_FMT_GRAY8) + ) { + is_single_comp = 0; + } else + return AVERROR_INVALIDDATA; + + pixel_size = (is_u16 ? sizeof(uint16_t) : sizeof(uint8_t)); + + if (is_single_comp && !is_u16) { + av_log(s->avctx, AV_LOG_ERROR, "DNGs with bpp <= 8 and 1 component are unsupported\n"); + av_frame_unref(s->jpgframe); + return AVERROR_PATCHWELCOME; + } + + dst_offset = dst_x + frame->linesize[0] * dst_y / pixel_size; + dst_data = frame->data[0] + dst_offset * pixel_size; + src_data = s->jpgframe->data[0]; + + dng_blit(s, + dst_data, + frame->linesize[0] / pixel_size, + src_data, + s->jpgframe->linesize[0] / pixel_size, + w, + h, + is_single_comp, + is_u16); + + av_frame_unref(s->jpgframe); + + return 0; +} static int tiff_unpack_strip(TiffContext *s, AVFrame *p, uint8_t *dst, int stride, const uint8_t *src, int size, int strip_start, int lines) @@ -593,6 +774,7 @@ static int tiff_unpack_strip(TiffContext *s, AVFrame *p, uint8_t *dst, int strid if (s->is_bayer) { av_assert0(width == (s->bpp * s->width + 7) >> 3); } + av_assert0(!(s->is_bayer && is_yuv)); if (p->format == AV_PIX_FMT_GRAY12) { av_fast_padded_malloc(&s->yuv_line, &s->yuv_line_size, width); if (s->yuv_line == NULL) { @@ -676,7 +858,9 @@ static int tiff_unpack_strip(TiffContext *s, AVFrame *p, uint8_t *dst, int strid av_log(s->avctx, AV_LOG_ERROR, "More than one DNG JPEG strips unsupported\n"); return AVERROR_PATCHWELCOME; } - if ((ret = dng_decode_strip(s->avctx, p)) < 0) + if (!s->is_bayer) + return AVERROR_PATCHWELCOME; + if ((ret = dng_decode_jpeg(s->avctx, p, s->stripsize, 0, 0, s->width, s->height)) < 0) return ret; return 0; } @@ -780,190 +964,6 @@ static int tiff_unpack_strip(TiffContext *s, AVFrame *p, uint8_t *dst, int strid return 0; } -/** - * Map stored raw sensor values into linear reference values (see: DNG Specification - Chapter 5) - */ -static uint16_t av_always_inline dng_process_color16(uint16_t value, - const uint16_t *lut, - uint16_t black_level, - float scale_factor) { - float value_norm; - - // Lookup table lookup - if (lut) - value = lut[value]; - - // Black level subtraction - value = av_clip_uint16_c((unsigned)value - black_level); - - // Color scaling - value_norm = (float)value * scale_factor; - - value = av_clip_uint16_c(value_norm * 65535); - - return value; -} - -static uint16_t av_always_inline dng_process_color8(uint16_t value, - const uint16_t *lut, - uint16_t black_level, - float scale_factor) { - return dng_process_color16(value, lut, black_level, scale_factor) >> 8; -} - -static void dng_blit(TiffContext *s, uint8_t *dst, int dst_stride, - const uint8_t *src, int src_stride, - int width, int height, int is_single_comp, int is_u16) -{ - int line, col; - float scale_factor; - - scale_factor = 1.0f / (s->white_level - s->black_level); - - if (is_single_comp) { - if (!is_u16) - return; /* <= 8bpp unsupported */ - - /* Image is double the width and half the height we need, each row comprises 2 rows of the output - (split vertically in the middle). */ - for (line = 0; line < height / 2; line++) { - uint16_t *dst_u16 = (uint16_t *)dst; - uint16_t *src_u16 = (uint16_t *)src; - - /* Blit first half of input row row to initial row of output */ - for (col = 0; col < width; col++) - *dst_u16++ = dng_process_color16(*src_u16++, s->dng_lut, s->black_level, scale_factor); - - /* Advance the destination pointer by a row (source pointer remains in the same place) */ - dst += dst_stride * sizeof(uint16_t); - dst_u16 = (uint16_t *)dst; - - /* Blit second half of input row row to next row of output */ - for (col = 0; col < width; col++) - *dst_u16++ = dng_process_color16(*src_u16++, s->dng_lut, s->black_level, scale_factor); - - dst += dst_stride * sizeof(uint16_t); - src += src_stride * sizeof(uint16_t); - } - } else { - /* Input and output image are the same size and the MJpeg decoder has done per-component - deinterleaving, so blitting here is straightforward. */ - if (is_u16) { - for (line = 0; line < height; line++) { - uint16_t *dst_u16 = (uint16_t *)dst; - uint16_t *src_u16 = (uint16_t *)src; - - for (col = 0; col < width; col++) - *dst_u16++ = dng_process_color16(*src_u16++, s->dng_lut, s->black_level, scale_factor); - - dst += dst_stride * sizeof(uint16_t); - src += src_stride * sizeof(uint16_t); - } - } else { - for (line = 0; line < height; line++) { - uint8_t *dst_u8 = dst; - const uint8_t *src_u8 = src; - - for (col = 0; col < width; col++) - *dst_u8++ = dng_process_color8(*src_u8++, s->dng_lut, s->black_level, scale_factor); - - dst += dst_stride; - src += src_stride; - } - } - } -} - -static int dng_decode_jpeg(AVCodecContext *avctx, AVFrame *frame, - int tile_byte_count, int dst_x, int dst_y, int w, int h) -{ - TiffContext *s = avctx->priv_data; - uint8_t *dst_data, *src_data; - uint32_t dst_offset; /* offset from dst buffer in pixels */ - int is_single_comp, is_u16, pixel_size; - int ret; - - if (tile_byte_count < 0 || tile_byte_count > bytestream2_get_bytes_left(&s->gb)) - return AVERROR_INVALIDDATA; - - /* Prepare a packet and send to the MJPEG decoder */ - av_packet_unref(s->jpkt); - s->jpkt->data = (uint8_t*)s->gb.buffer; - s->jpkt->size = tile_byte_count; - - if (s->is_bayer) { - MJpegDecodeContext *mjpegdecctx = s->avctx_mjpeg->priv_data; - /* We have to set this information here, there is no way to know if a given JPEG is a DNG-embedded - image or not from its own data (and we need that information when decoding it). */ - mjpegdecctx->bayer = 1; - } - - ret = avcodec_send_packet(s->avctx_mjpeg, s->jpkt); - if (ret < 0) { - av_log(avctx, AV_LOG_ERROR, "Error submitting a packet for decoding\n"); - return ret; - } - - ret = avcodec_receive_frame(s->avctx_mjpeg, s->jpgframe); - if (ret < 0) { - av_log(avctx, AV_LOG_ERROR, "JPEG decoding error: %s.\n", av_err2str(ret)); - - /* Normally skip, error if explode */ - if (avctx->err_recognition & AV_EF_EXPLODE) - return AVERROR_INVALIDDATA; - else - return 0; - } - - is_u16 = (s->bpp > 8); - - /* Copy the outputted tile's pixels from 'jpgframe' to 'frame' (final buffer) */ - - if (s->jpgframe->width != s->avctx_mjpeg->width || - s->jpgframe->height != s->avctx_mjpeg->height || - s->jpgframe->format != s->avctx_mjpeg->pix_fmt) - return AVERROR_INVALIDDATA; - - /* See dng_blit for explanation */ - if (s->avctx_mjpeg->width == w * 2 && - s->avctx_mjpeg->height == h / 2 && - s->avctx_mjpeg->pix_fmt == AV_PIX_FMT_GRAY16LE) { - is_single_comp = 1; - } else if (s->avctx_mjpeg->width >= w && - s->avctx_mjpeg->height >= h && - s->avctx_mjpeg->pix_fmt == (is_u16 ? AV_PIX_FMT_GRAY16 : AV_PIX_FMT_GRAY8) - ) { - is_single_comp = 0; - } else - return AVERROR_INVALIDDATA; - - pixel_size = (is_u16 ? sizeof(uint16_t) : sizeof(uint8_t)); - - if (is_single_comp && !is_u16) { - av_log(s->avctx, AV_LOG_ERROR, "DNGs with bpp <= 8 and 1 component are unsupported\n"); - av_frame_unref(s->jpgframe); - return AVERROR_PATCHWELCOME; - } - - dst_offset = dst_x + frame->linesize[0] * dst_y / pixel_size; - dst_data = frame->data[0] + dst_offset * pixel_size; - src_data = s->jpgframe->data[0]; - - dng_blit(s, - dst_data, - frame->linesize[0] / pixel_size, - src_data, - s->jpgframe->linesize[0] / pixel_size, - w, - h, - is_single_comp, - is_u16); - - av_frame_unref(s->jpgframe); - - return 0; -} - static int dng_decode_tiles(AVCodecContext *avctx, AVFrame *frame, const AVPacket *avpkt) { @@ -978,11 +978,8 @@ static int dng_decode_tiles(AVCodecContext *avctx, AVFrame *frame, int pos_x = 0, pos_y = 0; int ret; - s->jpgframe->width = s->tile_width; - s->jpgframe->height = s->tile_length; - - s->avctx_mjpeg->width = s->tile_width; - s->avctx_mjpeg->height = s->tile_length; + if (s->tile_width <= 0 || s->tile_length <= 0) + return AVERROR_INVALIDDATA; has_width_leftover = (s->width % s->tile_width != 0); has_height_leftover = (s->height % s->tile_length != 0); @@ -992,7 +989,7 @@ static int dng_decode_tiles(AVCodecContext *avctx, AVFrame *frame, tile_count_y = (s->height + s->tile_length - 1) / s->tile_length; /* Iterate over the number of tiles */ - for (tile_idx = 0; tile_idx < s->tile_count; tile_idx++) { + for (tile_idx = 0; tile_idx < tile_count_x * tile_count_y; tile_idx++) { tile_x = tile_idx % tile_count_x; tile_y = tile_idx / tile_count_x; @@ -1040,19 +1037,6 @@ static int dng_decode_tiles(AVCodecContext *avctx, AVFrame *frame, return avpkt->size; } -static int dng_decode_strip(AVCodecContext *avctx, AVFrame *frame) -{ - TiffContext *s = avctx->priv_data; - - s->jpgframe->width = s->width; - s->jpgframe->height = s->height; - - s->avctx_mjpeg->width = s->width; - s->avctx_mjpeg->height = s->height; - - return dng_decode_jpeg(avctx, frame, s->stripsize, 0, 0, s->width, s->height); -} - static int init_image(TiffContext *s, ThreadFrame *frame) { int ret; @@ -1297,9 +1281,13 @@ static int tiff_decode_tag(TiffContext *s, AVFrame *frame) s->is_thumbnail = (value != 0); break; case TIFF_WIDTH: + if (value > INT_MAX) + return AVERROR_INVALIDDATA; s->width = value; break; case TIFF_HEIGHT: + if (value > INT_MAX) + return AVERROR_INVALIDDATA; s->height = value; break; case TIFF_BPP: @@ -1425,19 +1413,24 @@ static int tiff_decode_tag(TiffContext *s, AVFrame *frame) break; case TIFF_TILE_OFFSETS: s->tile_offsets_offset = off; - s->tile_count = count; s->is_tiled = 1; break; case TIFF_TILE_BYTE_COUNTS: s->tile_byte_counts_offset = off; break; case TIFF_TILE_LENGTH: + if (value > INT_MAX) + return AVERROR_INVALIDDATA; s->tile_length = value; break; case TIFF_TILE_WIDTH: + if (value > INT_MAX) + return AVERROR_INVALIDDATA; s->tile_width = value; break; case TIFF_PREDICTOR: + if (value > INT_MAX) + return AVERROR_INVALIDDATA; s->predictor = value; break; case TIFF_SUB_IFDS: @@ -1447,7 +1440,7 @@ static int tiff_decode_tag(TiffContext *s, AVFrame *frame) s->sub_ifd = ff_tget(&s->gb, TIFF_LONG, s->le); /** Only get the first SubIFD */ break; case DNG_LINEARIZATION_TABLE: - if (count > FF_ARRAY_ELEMS(s->dng_lut)) + if (count < 1 || count > FF_ARRAY_ELEMS(s->dng_lut)) return AVERROR_INVALIDDATA; for (int i = 0; i < count; i++) s->dng_lut[i] = ff_tget(&s->gb, type, s->le); @@ -1568,12 +1561,18 @@ static int tiff_decode_tag(TiffContext *s, AVFrame *frame) } break; case TIFF_T4OPTIONS: - if (s->compr == TIFF_G3) + if (s->compr == TIFF_G3) { + if (value > INT_MAX) + return AVERROR_INVALIDDATA; s->fax_opts = value; + } break; case TIFF_T6OPTIONS: - if (s->compr == TIFF_G4) + if (s->compr == TIFF_G4) { + if (value > INT_MAX) + return AVERROR_INVALIDDATA; s->fax_opts = value; + } break; #define ADD_METADATA(count, name, sep)\ if ((ret = add_metadata(count, type, name, sep, s, frame)) < 0) {\ @@ -1781,7 +1780,7 @@ static int decode_frame(AVCodecContext *avctx, TiffContext *const s = avctx->priv_data; AVFrame *const p = data; ThreadFrame frame = { .f = data }; - unsigned off, last_off; + unsigned off, last_off = 0; int le, ret, plane, planes; int i, j, entries, stride; unsigned soff, ssize; @@ -1846,7 +1845,6 @@ again: /** whether we should process this multi-page IFD's next page */ retry_for_page = s->get_page && s->cur_page + 1 < s->get_page; // get_page is 1-indexed - last_off = off; if (retry_for_page) { // set offset to the next IFD off = ff_tget_long(&s->gb, le); @@ -1864,6 +1862,7 @@ again: avpriv_request_sample(s->avctx, "non increasing IFD offset"); return AVERROR_INVALIDDATA; } + last_off = off; if (off >= UINT_MAX - 14 || avpkt->size < off + 14) { av_log(avctx, AV_LOG_ERROR, "IFD offset is greater than image size\n"); return AVERROR_INVALIDDATA; @@ -1920,7 +1919,7 @@ again: return AVERROR_INVALIDDATA; } - has_tile_bits = s->is_tiled || s->tile_byte_counts_offset || s->tile_offsets_offset || s->tile_width || s->tile_length || s->tile_count; + has_tile_bits = s->is_tiled || s->tile_byte_counts_offset || s->tile_offsets_offset || s->tile_width || s->tile_length; has_strip_bits = s->strippos || s->strips || s->stripoff || s->rps || s->sot || s->sstype || s->stripsize || s->stripsizesoff; if (has_tile_bits && has_strip_bits) { @@ -2173,6 +2172,7 @@ static av_cold int tiff_init(AVCodecContext *avctx) s->avctx_mjpeg->flags2 = avctx->flags2; s->avctx_mjpeg->dct_algo = avctx->dct_algo; s->avctx_mjpeg->idct_algo = avctx->idct_algo; + s->avctx_mjpeg->max_pixels = avctx->max_pixels; ret = avcodec_open2(s->avctx_mjpeg, codec, NULL); if (ret < 0) { return ret; diff --git a/libavcodec/truemotion1.c b/libavcodec/truemotion1.c index 94782fef4b..930b43b6ef 100644 --- a/libavcodec/truemotion1.c +++ b/libavcodec/truemotion1.c @@ -407,6 +407,11 @@ static int truemotion1_decode_header(TrueMotion1Context *s) return AVERROR_PATCHWELCOME; } + if (s->h & 3) { + avpriv_request_sample(s->avctx, "Frame with height not being a multiple of 4"); + return AVERROR_PATCHWELCOME; + } + if (s->w != s->avctx->width || s->h != s->avctx->height || new_pix_fmt != s->avctx->pix_fmt) { av_frame_unref(s->frame); diff --git a/libavcodec/tta.c b/libavcodec/tta.c index f1e159b03d..f92be311c3 100644 --- a/libavcodec/tta.c +++ b/libavcodec/tta.c @@ -335,7 +335,7 @@ static int tta_decode_frame(AVCodecContext *avctx, void *data, if (s->channels > 1) { int32_t *r = p - 1; for (*p += *r / 2; r > (int32_t*)p - s->channels; r--) - *r = *(r + 1) - *r; + *r = *(r + 1) - (unsigned)*r; } cur_chan = 0; i++; @@ -371,8 +371,15 @@ static int tta_decode_frame(AVCodecContext *avctx, void *data, case 3: { // shift samples for 24-bit sample format int32_t *samples = (int32_t *)frame->data[0]; - for (i = 0; i < framelen * s->channels; i++) - *samples++ *= 256; + int overflow = 0; + + for (i = 0; i < framelen * s->channels; i++) { + int scaled = *samples * 256U; + overflow += (scaled >> 8 != *samples); + *samples++ = scaled; + } + if (overflow) + av_log(avctx, AV_LOG_WARNING, "%d overflows occurred on 24bit upscale\n", overflow); // reset decode buffer s->decode_buffer = NULL; break; diff --git a/libavcodec/ttadata.c b/libavcodec/ttadata.c index bf793a4cc8..aa9f418a7d 100644 --- a/libavcodec/ttadata.c +++ b/libavcodec/ttadata.c @@ -30,7 +30,8 @@ const uint32_t ff_tta_shift_1[] = { 0x01000000, 0x02000000, 0x04000000, 0x08000000, 0x10000000, 0x20000000, 0x40000000, 0x80000000, 0x80000000, 0x80000000, 0x80000000, 0x80000000, - 0x80000000, 0x80000000, 0x80000000, 0x80000000 + 0x80000000, 0x80000000, 0x80000000, 0x80000000, + 0xFFFFFFFF }; const uint32_t * const ff_tta_shift_16 = ff_tta_shift_1 + 4; diff --git a/libavcodec/ttadsp.c b/libavcodec/ttadsp.c index 1d1443aee0..99dd66a0c2 100644 --- a/libavcodec/ttadsp.c +++ b/libavcodec/ttadsp.c @@ -47,9 +47,9 @@ static void tta_filter_process_c(int32_t *qmi, int32_t *dx, int32_t *dl, *error = *in; *in += (round >> shift); - dl[4] = -dl[5]; dl[5] = -dl[6]; - dl[6] = *in - dl[7]; dl[7] = *in; - dl[5] += dl[6]; dl[4] += dl[5]; + dl[4] = -(unsigned)dl[5]; dl[5] = -(unsigned)dl[6]; + dl[6] = *in -(unsigned)dl[7]; dl[7] = *in; + dl[5] += (unsigned)dl[6]; dl[4] += (unsigned)dl[5]; } av_cold void ff_ttadsp_init(TTADSPContext *c) diff --git a/libavcodec/ttmlenc.c b/libavcodec/ttmlenc.c index 3972b4368c..695651bb94 100644 --- a/libavcodec/ttmlenc.c +++ b/libavcodec/ttmlenc.c @@ -206,5 +206,5 @@ AVCodec ff_ttml_encoder = { .init = ttml_encode_init, .encode_sub = ttml_encode_frame, .close = ttml_encode_close, - .capabilities = FF_CODEC_CAP_INIT_CLEANUP, + .caps_internal = FF_CODEC_CAP_INIT_CLEANUP, }; diff --git a/libavcodec/utils.c b/libavcodec/utils.c index 896b99dc3f..b948ba0871 100644 --- a/libavcodec/utils.c +++ b/libavcodec/utils.c @@ -236,6 +236,8 @@ void avcodec_align_dimensions2(AVCodecContext *s, int *width, int *height, case AV_PIX_FMT_GBRAP16BE: w_align = 16; //FIXME assume 16 pixel per macroblock h_align = 16 * 2; // interlaced needs 2 macroblocks height + if (s->codec_id == AV_CODEC_ID_BINKVIDEO) + w_align = 16*2; break; case AV_PIX_FMT_YUV411P: case AV_PIX_FMT_YUVJ411P: @@ -247,6 +249,9 @@ void avcodec_align_dimensions2(AVCodecContext *s, int *width, int *height, if (s->codec_id == AV_CODEC_ID_SVQ1) { w_align = 64; h_align = 64; + } else if (s->codec_id == AV_CODEC_ID_SNOW) { + w_align = 16; + h_align = 16; } break; case AV_PIX_FMT_RGB555: @@ -268,10 +273,21 @@ void avcodec_align_dimensions2(AVCodecContext *s, int *width, int *height, h_align = 4; } if (s->codec_id == AV_CODEC_ID_JV || + s->codec_id == AV_CODEC_ID_ARGO || s->codec_id == AV_CODEC_ID_INTERPLAY_VIDEO) { w_align = 8; h_align = 8; } + if (s->codec_id == AV_CODEC_ID_MJPEG || + s->codec_id == AV_CODEC_ID_MJPEGB || + s->codec_id == AV_CODEC_ID_LJPEG || + s->codec_id == AV_CODEC_ID_SMVJPEG || + s->codec_id == AV_CODEC_ID_AMV || + s->codec_id == AV_CODEC_ID_SP5X || + s->codec_id == AV_CODEC_ID_JPEGLS) { + w_align = 8; + h_align = 2*8; + } break; case AV_PIX_FMT_BGR24: if ((s->codec_id == AV_CODEC_ID_MSZH) || @@ -286,17 +302,24 @@ void avcodec_align_dimensions2(AVCodecContext *s, int *width, int *height, h_align = 4; } break; + case AV_PIX_FMT_BGR0: + if (s->codec_id == AV_CODEC_ID_ARGO) { + w_align = 8; + h_align = 8; + } + break; default: break; } if (s->codec_id == AV_CODEC_ID_IFF_ILBM) { - w_align = FFMAX(w_align, 8); + w_align = FFMAX(w_align, 16); } *width = FFALIGN(*width, w_align); *height = FFALIGN(*height, h_align); if (s->codec_id == AV_CODEC_ID_H264 || s->lowres || + s->codec_id == AV_CODEC_ID_VC1 || s->codec_id == AV_CODEC_ID_WMV3 || s->codec_id == AV_CODEC_ID_VP5 || s->codec_id == AV_CODEC_ID_VP6 || s->codec_id == AV_CODEC_ID_VP6F || s->codec_id == AV_CODEC_ID_VP6A ) { @@ -310,6 +333,9 @@ void avcodec_align_dimensions2(AVCodecContext *s, int *width, int *height, // the next rounded up width is 32 *width = FFMAX(*width, 32); } + if (s->codec_id == AV_CODEC_ID_SVQ3) { + *width = FFMAX(*width, 32); + } for (i = 0; i < 4; i++) linesize_align[i] = STRIDE_ALIGN; @@ -668,9 +694,9 @@ static int get_audio_frame_duration(enum AVCodecID id, int sr, int ch, int ba, if (sr > 0) { /* calc from sample rate */ if (id == AV_CODEC_ID_TTA) - return 256 * sr / 245; + return 256ll * sr / 245; else if (id == AV_CODEC_ID_DST) - return 588 * sr / 44100; + return 588ll * sr / 44100; else if (id == AV_CODEC_ID_BINKAUDIO_DCT) { if (sr / 22050 > 22) return 0; @@ -739,7 +765,7 @@ static int get_audio_frame_duration(enum AVCodecID id, int sr, int ch, int ba, case AV_CODEC_ID_ADPCM_THP: case AV_CODEC_ID_ADPCM_THP_LE: if (extradata) - return frame_bytes * 14 / (8 * ch); + return frame_bytes * 14LL / (8 * ch); break; case AV_CODEC_ID_ADPCM_XA: return (frame_bytes / 128) * 224 / ch; @@ -773,21 +799,33 @@ static int get_audio_frame_duration(enum AVCodecID id, int sr, int ch, int ba, if (ba > 0) { /* calc from frame_bytes, channels, and block_align */ int blocks = frame_bytes / ba; + int64_t tmp = 0; switch (id) { case AV_CODEC_ID_ADPCM_IMA_WAV: if (bps < 2 || bps > 5) return 0; - return blocks * (1 + (ba - 4 * ch) / (bps * ch) * 8); + tmp = blocks * (1LL + (ba - 4 * ch) / (bps * ch) * 8LL); + break; case AV_CODEC_ID_ADPCM_IMA_DK3: - return blocks * (((ba - 16) * 2 / 3 * 4) / ch); + tmp = blocks * (((ba - 16LL) * 2 / 3 * 4) / ch); + break; case AV_CODEC_ID_ADPCM_IMA_DK4: - return blocks * (1 + (ba - 4 * ch) * 2 / ch); + tmp = blocks * (1 + (ba - 4LL * ch) * 2 / ch); + break; case AV_CODEC_ID_ADPCM_IMA_RAD: - return blocks * ((ba - 4 * ch) * 2 / ch); + tmp = blocks * ((ba - 4LL * ch) * 2 / ch); + break; case AV_CODEC_ID_ADPCM_MS: - return blocks * (2 + (ba - 7 * ch) * 2LL / ch); + tmp = blocks * (2 + (ba - 7LL * ch) * 2LL / ch); + break; case AV_CODEC_ID_ADPCM_MTAF: - return blocks * (ba - 16) * 2 / ch; + tmp = blocks * (ba - 16LL) * 2 / ch; + break; + } + if (tmp) { + if (tmp != (int)tmp) + return 0; + return tmp; } } @@ -825,20 +863,22 @@ static int get_audio_frame_duration(enum AVCodecID id, int sr, int ch, int ba, int av_get_audio_frame_duration(AVCodecContext *avctx, int frame_bytes) { - return get_audio_frame_duration(avctx->codec_id, avctx->sample_rate, + int duration = get_audio_frame_duration(avctx->codec_id, avctx->sample_rate, avctx->channels, avctx->block_align, avctx->codec_tag, avctx->bits_per_coded_sample, avctx->bit_rate, avctx->extradata, avctx->frame_size, frame_bytes); + return FFMAX(0, duration); } int av_get_audio_frame_duration2(AVCodecParameters *par, int frame_bytes) { - return get_audio_frame_duration(par->codec_id, par->sample_rate, + int duration = get_audio_frame_duration(par->codec_id, par->sample_rate, par->channels, par->block_align, par->codec_tag, par->bits_per_coded_sample, par->bit_rate, par->extradata, par->frame_size, frame_bytes); + return FFMAX(0, duration); } #if !HAVE_THREADS diff --git a/libavcodec/utvideoenc.c b/libavcodec/utvideoenc.c index 5c87eb50ac..75983f8ad0 100644 --- a/libavcodec/utvideoenc.c +++ b/libavcodec/utvideoenc.c @@ -252,7 +252,7 @@ FF_ENABLE_DEPRECATION_WARNINGS * - Compression mode (none/huff) * And write the flags. */ - c->flags = (c->slices - 1) << 24; + c->flags = (c->slices - 1U) << 24; c->flags |= 0 << 11; // bit field to signal interlaced encoding mode c->flags |= c->compression; diff --git a/libavcodec/vaapi_av1.c b/libavcodec/vaapi_av1.c index 1809b485aa..5985493b8d 100644 --- a/libavcodec/vaapi_av1.c +++ b/libavcodec/vaapi_av1.c @@ -21,8 +21,28 @@ #include "libavutil/pixdesc.h" #include "hwconfig.h" #include "vaapi_decode.h" +#include "internal.h" #include "av1dec.h" +typedef struct VAAPIAV1FrameRef { + ThreadFrame frame; + int valid; +} VAAPIAV1FrameRef; + +typedef struct VAAPIAV1DecContext { + VAAPIDecodeContext base; + + /** + * For film grain case, VAAPI generate 2 output for each frame, + * current_frame will not apply film grain, and will be used for + * references for next frames. Maintain the reference list without + * applying film grain here. And current_display_picture will be + * used to apply film grain and push to downstream. + */ + VAAPIAV1FrameRef ref_tab[AV1_NUM_REF_FRAMES]; + ThreadFrame tmp_frame; +} VAAPIAV1DecContext; + static VASurfaceID vaapi_av1_surface_id(AV1Frame *vf) { if (vf) @@ -49,6 +69,48 @@ static int8_t vaapi_av1_get_bit_depth_idx(AVCodecContext *avctx) return bit_depth == 8 ? 0 : bit_depth == 10 ? 1 : 2; } +static int vaapi_av1_decode_init(AVCodecContext *avctx) +{ + VAAPIAV1DecContext *ctx = avctx->internal->hwaccel_priv_data; + + ctx->tmp_frame.f = av_frame_alloc(); + if (!ctx->tmp_frame.f) { + av_log(avctx, AV_LOG_ERROR, + "Failed to allocate frame.\n"); + return AVERROR(ENOMEM); + } + + for (int i = 0; i < FF_ARRAY_ELEMS(ctx->ref_tab); i++) { + ctx->ref_tab[i].frame.f = av_frame_alloc(); + if (!ctx->ref_tab[i].frame.f) { + av_log(avctx, AV_LOG_ERROR, + "Failed to allocate reference table frame %d.\n", i); + return AVERROR(ENOMEM); + } + ctx->ref_tab[i].valid = 0; + } + + return ff_vaapi_decode_init(avctx); +} + +static int vaapi_av1_decode_uninit(AVCodecContext *avctx) +{ + VAAPIAV1DecContext *ctx = avctx->internal->hwaccel_priv_data; + + if (ctx->tmp_frame.f->buf[0]) + ff_thread_release_buffer(avctx, &ctx->tmp_frame); + av_frame_free(&ctx->tmp_frame.f); + + for (int i = 0; i < FF_ARRAY_ELEMS(ctx->ref_tab); i++) { + if (ctx->ref_tab[i].frame.f->buf[0]) + ff_thread_release_buffer(avctx, &ctx->ref_tab[i].frame); + av_frame_free(&ctx->ref_tab[i].frame.f); + } + + return ff_vaapi_decode_uninit(avctx); +} + + static int vaapi_av1_start_frame(AVCodecContext *avctx, av_unused const uint8_t *buffer, av_unused uint32_t size) @@ -58,40 +120,62 @@ static int vaapi_av1_start_frame(AVCodecContext *avctx, const AV1RawFrameHeader *frame_header = s->raw_frame_header; const AV1RawFilmGrainParams *film_grain = &s->cur_frame.film_grain; VAAPIDecodePicture *pic = s->cur_frame.hwaccel_picture_private; + VAAPIAV1DecContext *ctx = avctx->internal->hwaccel_priv_data; VADecPictureParameterBufferAV1 pic_param; int8_t bit_depth_idx; int err = 0; int apply_grain = !(avctx->export_side_data & AV_CODEC_EXPORT_DATA_FILM_GRAIN) && film_grain->apply_grain; uint8_t remap_lr_type[4] = {AV1_RESTORE_NONE, AV1_RESTORE_SWITCHABLE, AV1_RESTORE_WIENER, AV1_RESTORE_SGRPROJ}; - - pic->output_surface = vaapi_av1_surface_id(&s->cur_frame); + uint8_t segmentation_feature_signed[AV1_SEG_LVL_MAX] = {1, 1, 1, 1, 1, 0, 0, 0}; + uint8_t segmentation_feature_max[AV1_SEG_LVL_MAX] = {255, AV1_MAX_LOOP_FILTER, + AV1_MAX_LOOP_FILTER, AV1_MAX_LOOP_FILTER, AV1_MAX_LOOP_FILTER, 7 , 0 , 0 }; bit_depth_idx = vaapi_av1_get_bit_depth_idx(avctx); if (bit_depth_idx < 0) goto fail; + if (apply_grain) { + if (ctx->tmp_frame.f->buf[0]) + ff_thread_release_buffer(avctx, &ctx->tmp_frame); + err = ff_thread_get_buffer(avctx, &ctx->tmp_frame, AV_GET_BUFFER_FLAG_REF); + if (err < 0) + goto fail; + pic->output_surface = ff_vaapi_get_surface_id(ctx->tmp_frame.f); + } else { + pic->output_surface = vaapi_av1_surface_id(&s->cur_frame); + } + memset(&pic_param, 0, sizeof(VADecPictureParameterBufferAV1)); pic_param = (VADecPictureParameterBufferAV1) { - .profile = seq->seq_profile, - .order_hint_bits_minus_1 = seq->order_hint_bits_minus_1, - .bit_depth_idx = bit_depth_idx, - .current_frame = pic->output_surface, - .current_display_picture = pic->output_surface, - .frame_width_minus1 = frame_header->frame_width_minus_1, - .frame_height_minus1 = frame_header->frame_height_minus_1, - .primary_ref_frame = frame_header->primary_ref_frame, - .order_hint = frame_header->order_hint, - .tile_cols = frame_header->tile_cols, - .tile_rows = frame_header->tile_rows, - .context_update_tile_id = frame_header->context_update_tile_id, - .interp_filter = frame_header->interpolation_filter, - .filter_level[0] = frame_header->loop_filter_level[0], - .filter_level[1] = frame_header->loop_filter_level[1], - .filter_level_u = frame_header->loop_filter_level[2], - .filter_level_v = frame_header->loop_filter_level[3], - .base_qindex = frame_header->base_q_idx, - .cdef_damping_minus_3 = frame_header->cdef_damping_minus_3, - .cdef_bits = frame_header->cdef_bits, + .profile = seq->seq_profile, + .order_hint_bits_minus_1 = seq->order_hint_bits_minus_1, + .bit_depth_idx = bit_depth_idx, + .matrix_coefficients = seq->color_config.matrix_coefficients, + .current_frame = pic->output_surface, + .current_display_picture = vaapi_av1_surface_id(&s->cur_frame), + .frame_width_minus1 = frame_header->frame_width_minus_1, + .frame_height_minus1 = frame_header->frame_height_minus_1, + .primary_ref_frame = frame_header->primary_ref_frame, + .order_hint = frame_header->order_hint, + .tile_cols = frame_header->tile_cols, + .tile_rows = frame_header->tile_rows, + .context_update_tile_id = frame_header->context_update_tile_id, + .superres_scale_denominator = frame_header->use_superres ? + frame_header->coded_denom + AV1_SUPERRES_DENOM_MIN : + AV1_SUPERRES_NUM, + .interp_filter = frame_header->interpolation_filter, + .filter_level[0] = frame_header->loop_filter_level[0], + .filter_level[1] = frame_header->loop_filter_level[1], + .filter_level_u = frame_header->loop_filter_level[2], + .filter_level_v = frame_header->loop_filter_level[3], + .base_qindex = frame_header->base_q_idx, + .y_dc_delta_q = frame_header->delta_q_y_dc, + .u_dc_delta_q = frame_header->delta_q_u_dc, + .u_ac_delta_q = frame_header->delta_q_u_ac, + .v_dc_delta_q = frame_header->delta_q_v_dc, + .v_ac_delta_q = frame_header->delta_q_v_ac, + .cdef_damping_minus_3 = frame_header->cdef_damping_minus_3, + .cdef_bits = frame_header->cdef_bits, .seq_info_fields.fields = { .still_picture = seq->still_picture, .use_128x128_superblock = seq->use_128x128_superblock, @@ -162,12 +246,15 @@ static int vaapi_av1_start_frame(AVCodecContext *avctx, .mode_ref_delta_update = frame_header->loop_filter_delta_update, }, .mode_control_fields.bits = { - .delta_q_present_flag = frame_header->delta_q_present, - .log2_delta_q_res = frame_header->delta_q_res, - .tx_mode = frame_header->tx_mode, - .reference_select = frame_header->reference_select, - .reduced_tx_set_used = frame_header->reduced_tx_set, - .skip_mode_present = frame_header->skip_mode_present, + .delta_q_present_flag = frame_header->delta_q_present, + .log2_delta_q_res = frame_header->delta_q_res, + .delta_lf_present_flag = frame_header->delta_lf_present, + .log2_delta_lf_res = frame_header->delta_lf_res, + .delta_lf_multi = frame_header->delta_lf_multi, + .tx_mode = frame_header->tx_mode, + .reference_select = frame_header->reference_select, + .reduced_tx_set_used = frame_header->reduced_tx_set, + .skip_mode_present = frame_header->skip_mode_present, }, .loop_restoration_fields.bits = { .yframe_restoration_type = remap_lr_type[frame_header->lr_type[0]], @@ -178,6 +265,9 @@ static int vaapi_av1_start_frame(AVCodecContext *avctx, }, .qmatrix_fields.bits = { .using_qmatrix = frame_header->using_qmatrix, + .qm_y = frame_header->qm_y, + .qm_u = frame_header->qm_u, + .qm_v = frame_header->qm_v, } }; @@ -185,7 +275,9 @@ static int vaapi_av1_start_frame(AVCodecContext *avctx, if (pic_param.pic_info_fields.bits.frame_type == AV1_FRAME_KEY) pic_param.ref_frame_map[i] = VA_INVALID_ID; else - pic_param.ref_frame_map[i] = vaapi_av1_surface_id(&s->ref[i]); + pic_param.ref_frame_map[i] = ctx->ref_tab[i].valid ? + ff_vaapi_get_surface_id(ctx->ref_tab[i].frame.f) : + vaapi_av1_surface_id(&s->ref[i]); } for (int i = 0; i < AV1_REFS_PER_FRAME; i++) { pic_param.ref_frame_idx[i] = frame_header->ref_frame_idx[i]; @@ -213,10 +305,22 @@ static int vaapi_av1_start_frame(AVCodecContext *avctx, frame_header->height_in_sbs_minus_1[i]; } for (int i = AV1_REF_FRAME_LAST; i <= AV1_REF_FRAME_ALTREF; i++) { - pic_param.wm[i - 1].wmtype = s->cur_frame.gm_type[i]; + pic_param.wm[i - 1].invalid = s->cur_frame.gm_invalid[i]; + pic_param.wm[i - 1].wmtype = s->cur_frame.gm_type[i]; for (int j = 0; j < 6; j++) pic_param.wm[i - 1].wmmat[j] = s->cur_frame.gm_params[i][j]; } + for (int i = 0; i < AV1_MAX_SEGMENTS; i++) { + for (int j = 0; j < AV1_SEG_LVL_MAX; j++) { + pic_param.seg_info.feature_mask[i] |= (frame_header->feature_enabled[i][j] << j); + if (segmentation_feature_signed[j]) + pic_param.seg_info.feature_data[i][j] = av_clip(frame_header->feature_value[i][j], + -segmentation_feature_max[j], segmentation_feature_max[j]); + else + pic_param.seg_info.feature_data[i][j] = av_clip(frame_header->feature_value[i][j], + 0, segmentation_feature_max[j]); + } + } if (apply_grain) { for (int i = 0; i < film_grain->num_y_points; i++) { pic_param.film_grain_info.point_y_value[i] = @@ -263,8 +367,34 @@ fail: static int vaapi_av1_end_frame(AVCodecContext *avctx) { const AV1DecContext *s = avctx->priv_data; + const AV1RawFrameHeader *header = s->raw_frame_header; + const AV1RawFilmGrainParams *film_grain = &s->cur_frame.film_grain; VAAPIDecodePicture *pic = s->cur_frame.hwaccel_picture_private; - return ff_vaapi_decode_issue(avctx, pic); + VAAPIAV1DecContext *ctx = avctx->internal->hwaccel_priv_data; + + int apply_grain = !(avctx->export_side_data & AV_CODEC_EXPORT_DATA_FILM_GRAIN) && film_grain->apply_grain; + int ret; + ret = ff_vaapi_decode_issue(avctx, pic); + if (ret < 0) + return ret; + + for (int i = 0; i < AV1_NUM_REF_FRAMES; i++) { + if (header->refresh_frame_flags & (1 << i)) { + if (ctx->ref_tab[i].frame.f->buf[0]) + ff_thread_release_buffer(avctx, &ctx->ref_tab[i].frame); + + if (apply_grain) { + ret = ff_thread_ref_frame(&ctx->ref_tab[i].frame, &ctx->tmp_frame); + if (ret < 0) + return ret; + ctx->ref_tab[i].valid = 1; + } else { + ctx->ref_tab[i].valid = 0; + } + } + } + + return 0; } static int vaapi_av1_decode_slice(AVCodecContext *avctx, @@ -292,7 +422,7 @@ static int vaapi_av1_decode_slice(AVCodecContext *avctx, err = ff_vaapi_decode_make_slice_buffer(avctx, pic, &slice_param, sizeof(VASliceParameterBufferAV1), buffer, - s->tile_group_info[i].tile_size); + size); if (err) { ff_vaapi_decode_cancel(avctx, pic); return err; @@ -311,9 +441,9 @@ const AVHWAccel ff_av1_vaapi_hwaccel = { .end_frame = vaapi_av1_end_frame, .decode_slice = vaapi_av1_decode_slice, .frame_priv_data_size = sizeof(VAAPIDecodePicture), - .init = ff_vaapi_decode_init, - .uninit = ff_vaapi_decode_uninit, + .init = vaapi_av1_decode_init, + .uninit = vaapi_av1_decode_uninit, .frame_params = ff_vaapi_common_frame_params, - .priv_data_size = sizeof(VAAPIDecodeContext), + .priv_data_size = sizeof(VAAPIAV1DecContext), .caps_internal = HWACCEL_CAP_ASYNC_SAFE, }; diff --git a/libavcodec/vaapi_decode.c b/libavcodec/vaapi_decode.c index 57a0eb4e6e..032e8531f2 100644 --- a/libavcodec/vaapi_decode.c +++ b/libavcodec/vaapi_decode.c @@ -577,10 +577,10 @@ static int vaapi_decode_make_config(AVCodecContext *avctx, switch (avctx->codec_id) { case AV_CODEC_ID_H264: case AV_CODEC_ID_HEVC: + case AV_CODEC_ID_AV1: frames->initial_pool_size += 16; break; case AV_CODEC_ID_VP9: - case AV_CODEC_ID_AV1: frames->initial_pool_size += 8; break; case AV_CODEC_ID_VP8: diff --git a/libavcodec/vaapi_encode.c b/libavcodec/vaapi_encode.c index 607858435f..7e93afcb12 100644 --- a/libavcodec/vaapi_encode.c +++ b/libavcodec/vaapi_encode.c @@ -2366,6 +2366,11 @@ av_cold int ff_vaapi_encode_init(AVCodecContext *avctx) VAStatus vas; int err; + ctx->va_config = VA_INVALID_ID; + ctx->va_context = VA_INVALID_ID; + + /* If you add something that can fail above this av_frame_alloc(), + * modify ff_vaapi_encode_close() accordingly. */ ctx->frame = av_frame_alloc(); if (!ctx->frame) { return AVERROR(ENOMEM); @@ -2377,9 +2382,6 @@ av_cold int ff_vaapi_encode_init(AVCodecContext *avctx) return AVERROR(EINVAL); } - ctx->va_config = VA_INVALID_ID; - ctx->va_context = VA_INVALID_ID; - ctx->input_frames_ref = av_buffer_ref(avctx->hw_frames_ctx); if (!ctx->input_frames_ref) { err = AVERROR(ENOMEM); @@ -2531,6 +2533,11 @@ av_cold int ff_vaapi_encode_close(AVCodecContext *avctx) VAAPIEncodeContext *ctx = avctx->priv_data; VAAPIEncodePicture *pic, *next; + /* We check ctx->frame to know whether ff_vaapi_encode_init() + * has been called and va_config/va_context initialized. */ + if (!ctx->frame) + return 0; + for (pic = ctx->pic_start; pic; pic = next) { next = pic->next; vaapi_encode_free(avctx, pic); @@ -2539,12 +2546,14 @@ av_cold int ff_vaapi_encode_close(AVCodecContext *avctx) av_buffer_pool_uninit(&ctx->output_buffer_pool); if (ctx->va_context != VA_INVALID_ID) { - vaDestroyContext(ctx->hwctx->display, ctx->va_context); + if (ctx->hwctx) + vaDestroyContext(ctx->hwctx->display, ctx->va_context); ctx->va_context = VA_INVALID_ID; } if (ctx->va_config != VA_INVALID_ID) { - vaDestroyConfig(ctx->hwctx->display, ctx->va_config); + if (ctx->hwctx) + vaDestroyConfig(ctx->hwctx->display, ctx->va_config); ctx->va_config = VA_INVALID_ID; } diff --git a/libavcodec/vble.c b/libavcodec/vble.c index 2cddd550b1..f2ad2f8366 100644 --- a/libavcodec/vble.c +++ b/libavcodec/vble.c @@ -193,6 +193,9 @@ static av_cold int vble_decode_init(AVCodecContext *avctx) ctx->size = av_image_get_buffer_size(avctx->pix_fmt, avctx->width, avctx->height, 1); + if (ctx->size < 0) + return ctx->size; + ctx->val = av_malloc_array(ctx->size, sizeof(*ctx->val)); if (!ctx->val) { diff --git a/libavcodec/vc1.c b/libavcodec/vc1.c index cd9975d8cf..ab5e3008e0 100644 --- a/libavcodec/vc1.c +++ b/libavcodec/vc1.c @@ -672,6 +672,8 @@ int ff_vc1_parse_frame_header(VC1Context *v, GetBitContext* gb) if (v->s.pict_type == AV_PICTURE_TYPE_P) v->rnd ^= 1; + if (get_bits_left(gb) < 5) + return AVERROR_INVALIDDATA; /* Quantizer stuff */ pqindex = get_bits(gb, 5); if (!pqindex) @@ -764,6 +766,9 @@ int ff_vc1_parse_frame_header(VC1Context *v, GetBitContext* gb) av_log(v->s.avctx, AV_LOG_DEBUG, "MB Skip plane encoding: " "Imode: %i, Invert: %i\n", status>>1, status&1); + if (get_bits_left(gb) < 4) + return AVERROR_INVALIDDATA; + /* Hopefully this is correct for P-frames */ v->s.mv_table_index = get_bits(gb, 2); //but using ff_vc1_ tables v->cbptab = get_bits(gb, 2); diff --git a/libavcodec/vc1_block.c b/libavcodec/vc1_block.c index b6ace37658..d50d4512c8 100644 --- a/libavcodec/vc1_block.c +++ b/libavcodec/vc1_block.c @@ -1301,6 +1301,7 @@ static int vc1_decode_p_mb(VC1Context *v) int dst_idx, off; int skipped, fourmv; int block_cbp = 0, pat, block_tt = 0, block_intra = 0; + int ret; mquant = v->pq; /* lossy initialization */ @@ -1359,8 +1360,10 @@ static int vc1_decode_p_mb(VC1Context *v) if (i == 1 || i == 3 || s->mb_x) v->c_avail = v->mb_type[0][s->block_index[i] - 1]; - vc1_decode_intra_block(v, v->block[v->cur_blk_idx][block_map[i]], i, val, mquant, - (i & 4) ? v->codingset2 : v->codingset); + ret = vc1_decode_intra_block(v, v->block[v->cur_blk_idx][block_map[i]], i, val, mquant, + (i & 4) ? v->codingset2 : v->codingset); + if (ret < 0) + return ret; if (CONFIG_GRAY && (i > 3) && (s->avctx->flags & AV_CODEC_FLAG_GRAY)) continue; v->vc1dsp.vc1_inv_trans_8x8(v->block[v->cur_blk_idx][block_map[i]]); @@ -1462,8 +1465,10 @@ static int vc1_decode_p_mb(VC1Context *v) if (i == 1 || i == 3 || s->mb_x) v->c_avail = v->mb_type[0][s->block_index[i] - 1]; - vc1_decode_intra_block(v, v->block[v->cur_blk_idx][block_map[i]], i, is_coded[i], mquant, - (i & 4) ? v->codingset2 : v->codingset); + ret = vc1_decode_intra_block(v, v->block[v->cur_blk_idx][block_map[i]], i, is_coded[i], mquant, + (i & 4) ? v->codingset2 : v->codingset); + if (ret < 0) + return ret; if (CONFIG_GRAY && (i > 3) && (s->avctx->flags & AV_CODEC_FLAG_GRAY)) continue; v->vc1dsp.vc1_inv_trans_8x8(v->block[v->cur_blk_idx][block_map[i]]); @@ -1534,6 +1539,7 @@ static int vc1_decode_p_mb_intfr(VC1Context *v) int block_cbp = 0, pat, block_tt = 0; int idx_mbmode = 0, mvbp; int fieldtx; + int ret; mquant = v->pq; /* Lossy initialization */ @@ -1606,8 +1612,10 @@ static int vc1_decode_p_mb_intfr(VC1Context *v) if (i == 1 || i == 3 || s->mb_x) v->c_avail = v->mb_type[0][s->block_index[i] - 1]; - vc1_decode_intra_block(v, v->block[v->cur_blk_idx][block_map[i]], i, val, mquant, - (i & 4) ? v->codingset2 : v->codingset); + ret = vc1_decode_intra_block(v, v->block[v->cur_blk_idx][block_map[i]], i, val, mquant, + (i & 4) ? v->codingset2 : v->codingset); + if (ret < 0) + return ret; if (CONFIG_GRAY && (i > 3) && (s->avctx->flags & AV_CODEC_FLAG_GRAY)) continue; v->vc1dsp.vc1_inv_trans_8x8(v->block[v->cur_blk_idx][block_map[i]]); @@ -1743,6 +1751,7 @@ static int vc1_decode_p_mb_intfi(VC1Context *v) int pred_flag = 0; int block_cbp = 0, pat, block_tt = 0; int idx_mbmode = 0; + int ret; mquant = v->pq; /* Lossy initialization */ @@ -1774,8 +1783,10 @@ static int vc1_decode_p_mb_intfi(VC1Context *v) if (i == 1 || i == 3 || s->mb_x) v->c_avail = v->mb_type[0][s->block_index[i] - 1]; - vc1_decode_intra_block(v, v->block[v->cur_blk_idx][block_map[i]], i, val, mquant, - (i & 4) ? v->codingset2 : v->codingset); + ret = vc1_decode_intra_block(v, v->block[v->cur_blk_idx][block_map[i]], i, val, mquant, + (i & 4) ? v->codingset2 : v->codingset); + if (ret < 0) + return ret; if (CONFIG_GRAY && (i > 3) && (s->avctx->flags & AV_CODEC_FLAG_GRAY)) continue; v->vc1dsp.vc1_inv_trans_8x8(v->block[v->cur_blk_idx][block_map[i]]); @@ -1866,6 +1877,7 @@ static int vc1_decode_b_mb(VC1Context *v) int skipped, direct; int dmv_x[2], dmv_y[2]; int bmvtype = BMV_TYPE_BACKWARD; + int ret; mquant = v->pq; /* lossy initialization */ s->mb_intra = 0; @@ -1978,8 +1990,10 @@ static int vc1_decode_b_mb(VC1Context *v) if (i == 1 || i == 3 || s->mb_x) v->c_avail = v->mb_type[0][s->block_index[i] - 1]; - vc1_decode_intra_block(v, s->block[i], i, val, mquant, - (i & 4) ? v->codingset2 : v->codingset); + ret = vc1_decode_intra_block(v, s->block[i], i, val, mquant, + (i & 4) ? v->codingset2 : v->codingset); + if (ret < 0) + return ret; if (CONFIG_GRAY && (i > 3) && (s->avctx->flags & AV_CODEC_FLAG_GRAY)) continue; v->vc1dsp.vc1_inv_trans_8x8(s->block[i]); @@ -2025,6 +2039,7 @@ static int vc1_decode_b_mb_intfi(VC1Context *v) int bmvtype = BMV_TYPE_BACKWARD; int block_cbp = 0, pat, block_tt = 0; int idx_mbmode; + int ret; mquant = v->pq; /* Lossy initialization */ s->mb_intra = 0; @@ -2057,8 +2072,10 @@ static int vc1_decode_b_mb_intfi(VC1Context *v) if (i == 1 || i == 3 || s->mb_x) v->c_avail = v->mb_type[0][s->block_index[i] - 1]; - vc1_decode_intra_block(v, s->block[i], i, val, mquant, - (i & 4) ? v->codingset2 : v->codingset); + ret = vc1_decode_intra_block(v, s->block[i], i, val, mquant, + (i & 4) ? v->codingset2 : v->codingset); + if (ret < 0) + return ret; if (CONFIG_GRAY && (i > 3) && (s->avctx->flags & AV_CODEC_FLAG_GRAY)) continue; v->vc1dsp.vc1_inv_trans_8x8(s->block[i]); @@ -2195,6 +2212,7 @@ static int vc1_decode_b_mb_intfr(VC1Context *v) int stride_y, fieldtx; int bmvtype = BMV_TYPE_BACKWARD; int dir, dir2; + int ret; mquant = v->pq; /* Lossy initialization */ s->mb_intra = 0; @@ -2251,8 +2269,10 @@ static int vc1_decode_b_mb_intfr(VC1Context *v) if (i == 1 || i == 3 || s->mb_x) v->c_avail = v->mb_type[0][s->block_index[i] - 1]; - vc1_decode_intra_block(v, s->block[i], i, val, mquant, - (i & 4) ? v->codingset2 : v->codingset); + ret = vc1_decode_intra_block(v, s->block[i], i, val, mquant, + (i & 4) ? v->codingset2 : v->codingset); + if (ret < 0) + return ret; if (CONFIG_GRAY && i > 3 && (s->avctx->flags & AV_CODEC_FLAG_GRAY)) continue; v->vc1dsp.vc1_inv_trans_8x8(s->block[i]); @@ -2796,6 +2816,7 @@ static void vc1_decode_p_blocks(VC1Context *v) { MpegEncContext *s = &v->s; int apply_loop_filter; + int ret; /* select coding mode used for VLC tables selection */ switch (v->c_ac_table_index) { @@ -2838,22 +2859,22 @@ static void vc1_decode_p_blocks(VC1Context *v) } if (v->fcm == ILACE_FIELD) { - vc1_decode_p_mb_intfi(v); + ret = vc1_decode_p_mb_intfi(v); if (apply_loop_filter) ff_vc1_p_loop_filter(v); } else if (v->fcm == ILACE_FRAME) { - vc1_decode_p_mb_intfr(v); + ret = vc1_decode_p_mb_intfr(v); if (apply_loop_filter) ff_vc1_p_intfr_loop_filter(v); } else { - vc1_decode_p_mb(v); + ret = vc1_decode_p_mb(v); if (apply_loop_filter) ff_vc1_p_loop_filter(v); } - if (get_bits_left(&s->gb) < 0 || get_bits_count(&s->gb) < 0) { + if (ret < 0 || get_bits_left(&s->gb) < 0 || get_bits_count(&s->gb) < 0) { // TODO: may need modification to handle slice coding ff_er_add_slice(&s->er, 0, s->start_mb_y, s->mb_x, s->mb_y, ER_MB_ERROR); - av_log(s->avctx, AV_LOG_ERROR, "Bits overconsumption: %i > %i at %ix%i\n", + av_log(s->avctx, AV_LOG_ERROR, "Error or Bits overconsumption: %i > %i at %ix%i\n", get_bits_count(&s->gb), s->gb.size_in_bits, s->mb_x, s->mb_y); return; } diff --git a/libavcodec/vc1_loopfilter.c b/libavcodec/vc1_loopfilter.c index 0f990cccef..ee694ede28 100644 --- a/libavcodec/vc1_loopfilter.c +++ b/libavcodec/vc1_loopfilter.c @@ -1125,10 +1125,7 @@ static av_always_inline void vc1_b_h_intfi_loop_filter(VC1Context *v, uint8_t *d dst = dest + (block_num & 2) * 4 * s->linesize + (block_num & 1) * 8; if (!(flags & RIGHT_EDGE) || !(block_num & 5)) { - if (block_num > 3) - v->vc1dsp.vc1_h_loop_filter8(dst + 8, linesize, pq); - else - v->vc1dsp.vc1_h_loop_filter8(dst + 8, linesize, pq); + v->vc1dsp.vc1_h_loop_filter8(dst + 8, linesize, pq); } tt = ttblk[0] >> (block_num * 4) & 0xf; diff --git a/libavcodec/vc1dec.c b/libavcodec/vc1dec.c index 47940fb886..34330106c2 100644 --- a/libavcodec/vc1dec.c +++ b/libavcodec/vc1dec.c @@ -344,7 +344,7 @@ av_cold int ff_vc1_decode_init_alloc_tables(VC1Context *v) if (!v->block || !v->cbp_base) goto error; v->cbp = v->cbp_base + 2 * s->mb_stride; - v->ttblk_base = av_malloc(sizeof(v->ttblk_base[0]) * 3 * s->mb_stride); + v->ttblk_base = av_mallocz(sizeof(v->ttblk_base[0]) * 3 * s->mb_stride); if (!v->ttblk_base) goto error; v->ttblk = v->ttblk_base + 2 * s->mb_stride; @@ -358,7 +358,7 @@ av_cold int ff_vc1_decode_init_alloc_tables(VC1Context *v) v->luma_mv = v->luma_mv_base + 2 * s->mb_stride; /* allocate block type info in that way so it could be used with s->block_index[] */ - v->mb_type_base = av_malloc(s->b8_stride * (mb_height * 2 + 1) + s->mb_stride * (mb_height + 1) * 2); + v->mb_type_base = av_mallocz(s->b8_stride * (mb_height * 2 + 1) + s->mb_stride * (mb_height + 1) * 2); if (!v->mb_type_base) goto error; v->mb_type[0] = v->mb_type_base + s->b8_stride + 1; @@ -384,7 +384,7 @@ av_cold int ff_vc1_decode_init_alloc_tables(VC1Context *v) if (s->avctx->codec_id == AV_CODEC_ID_WMV3IMAGE || s->avctx->codec_id == AV_CODEC_ID_VC1IMAGE) { for (i = 0; i < 4; i++) if (!(v->sr_rows[i >> 1][i & 1] = av_malloc(v->output_width))) - return AVERROR(ENOMEM); + goto error; } ret = ff_intrax8_common_init(s->avctx, &v->x8, &s->idsp, @@ -539,12 +539,6 @@ static av_cold int vc1_decode_init(AVCodecContext *avctx) ff_h264chroma_init(&v->h264chroma, 8); ff_qpeldsp_init(&s->qdsp); - // Must happen after calling ff_vc1_decode_end - // to avoid de-allocating the sprite_output_frame - v->sprite_output_frame = av_frame_alloc(); - if (!v->sprite_output_frame) - return AVERROR(ENOMEM); - avctx->has_b_frames = !!avctx->max_b_frames; if (v->color_prim == 1 || v->color_prim == 5 || v->color_prim == 6) @@ -577,20 +571,15 @@ static av_cold int vc1_decode_init(AVCodecContext *avctx) v->sprite_height > 1 << 14 || v->output_width > 1 << 14 || v->output_height > 1 << 14) { - ret = AVERROR_INVALIDDATA; - goto error; + return AVERROR_INVALIDDATA; } if ((v->sprite_width&1) || (v->sprite_height&1)) { avpriv_request_sample(avctx, "odd sprites support"); - ret = AVERROR_PATCHWELCOME; - goto error; + return AVERROR_PATCHWELCOME; } } return 0; -error: - av_frame_free(&v->sprite_output_frame); - return ret; } /** Close a VC1/WMV3 decoder @@ -608,6 +597,7 @@ av_cold int ff_vc1_decode_end(AVCodecContext *avctx) av_freep(&v->hrd_rate); av_freep(&v->hrd_buffer); ff_mpv_common_end(&v->s); + memset(v->s.block_index, 0, sizeof(v->s.block_index)); av_freep(&v->mv_type_mb_plane); av_freep(&v->direct_mb_plane); av_freep(&v->forward_mb_plane); @@ -1135,7 +1125,9 @@ static int vc1_decode_frame(AVCodecContext *avctx, void *data, ret = AVERROR_INVALIDDATA; goto err; } - if (!v->field_mode) + if ( !v->field_mode + && avctx->codec_id != AV_CODEC_ID_WMV3IMAGE + && avctx->codec_id != AV_CODEC_ID_VC1IMAGE) ff_er_frame_end(&s->er); } @@ -1147,6 +1139,11 @@ image: avctx->height = avctx->coded_height = v->output_height; if (avctx->skip_frame >= AVDISCARD_NONREF) goto end; + if (!v->sprite_output_frame && + !(v->sprite_output_frame = av_frame_alloc())) { + ret = AVERROR(ENOMEM); + goto err; + } #if CONFIG_WMV3IMAGE_DECODER || CONFIG_VC1IMAGE_DECODER if ((ret = vc1_decode_sprites(v, &s->gb)) < 0) goto err; @@ -1158,12 +1155,14 @@ image: if (s->pict_type == AV_PICTURE_TYPE_B || s->low_delay) { if ((ret = av_frame_ref(pict, s->current_picture_ptr->f)) < 0) goto err; - ff_print_debug_info(s, s->current_picture_ptr, pict); + if (!v->field_mode) + ff_print_debug_info(s, s->current_picture_ptr, pict); *got_frame = 1; } else if (s->last_picture_ptr) { if ((ret = av_frame_ref(pict, s->last_picture_ptr->f)) < 0) goto err; - ff_print_debug_info(s, s->last_picture_ptr, pict); + if (!v->field_mode) + ff_print_debug_info(s, s->last_picture_ptr, pict); *got_frame = 1; } } diff --git a/libavcodec/vc2enc.c b/libavcodec/vc2enc.c index 7bd2e4c2ab..0eb486ef10 100644 --- a/libavcodec/vc2enc.c +++ b/libavcodec/vc2enc.c @@ -183,7 +183,9 @@ typedef struct VC2EncContext { static av_always_inline void put_vc2_ue_uint(PutBitContext *pb, uint32_t val) { int i; - int pbits = 0, bits = 0, topbit = 1, maxval = 1; + int bits = 0; + unsigned topbit = 1, maxval = 1; + uint64_t pbits = 0; if (!val++) { put_bits(pb, 1, 1); @@ -200,12 +202,13 @@ static av_always_inline void put_vc2_ue_uint(PutBitContext *pb, uint32_t val) for (i = 0; i < bits; i++) { topbit >>= 1; + av_assert2(pbits <= UINT64_MAX>>3); pbits <<= 2; if (val & topbit) pbits |= 0x1; } - put_bits(pb, bits*2 + 1, (pbits << 1) | 1); + put_bits64(pb, bits*2 + 1, (pbits << 1) | 1); } static av_always_inline int count_vc2_ue_uint(uint32_t val) @@ -982,6 +985,8 @@ static av_cold int vc2_encode_frame(AVCodecContext *avctx, AVPacket *avpkt, } s->slice_min_bytes = s->slice_max_bytes - s->slice_max_bytes*(s->tolerance/100.0f); + if (s->slice_min_bytes < 0 || s->slice_max_bytes > INT_MAX >> 3) + return AVERROR(EINVAL); ret = encode_frame(s, avpkt, frame, aux_data, header_size, s->interlaced); if (ret) diff --git a/libavcodec/vdpau_mpeg12.c b/libavcodec/vdpau_mpeg12.c index 72220ffb4e..0860af815e 100644 --- a/libavcodec/vdpau_mpeg12.c +++ b/libavcodec/vdpau_mpeg12.c @@ -73,8 +73,9 @@ static int vdpau_mpeg_start_frame(AVCodecContext *avctx, info->f_code[1][0] = s->mpeg_f_code[1][0]; info->f_code[1][1] = s->mpeg_f_code[1][1]; for (i = 0; i < 64; ++i) { - info->intra_quantizer_matrix[i] = s->intra_matrix[i]; - info->non_intra_quantizer_matrix[i] = s->inter_matrix[i]; + int n = s->idsp.idct_permutation[i]; + info->intra_quantizer_matrix[i] = s->intra_matrix[n]; + info->non_intra_quantizer_matrix[i] = s->inter_matrix[n]; } return ff_vdpau_common_start_frame(pic_ctx, buffer, size); diff --git a/libavcodec/vdpau_mpeg4.c b/libavcodec/vdpau_mpeg4.c index 93b25beb1f..59cdb96378 100644 --- a/libavcodec/vdpau_mpeg4.c +++ b/libavcodec/vdpau_mpeg4.c @@ -74,8 +74,9 @@ static int vdpau_mpeg4_start_frame(AVCodecContext *avctx, info->alternate_vertical_scan_flag = s->alternate_scan; info->top_field_first = s->top_field_first; for (i = 0; i < 64; ++i) { - info->intra_quantizer_matrix[i] = s->intra_matrix[i]; - info->non_intra_quantizer_matrix[i] = s->inter_matrix[i]; + int n = s->idsp.idct_permutation[i]; + info->intra_quantizer_matrix[i] = s->intra_matrix[n]; + info->non_intra_quantizer_matrix[i] = s->inter_matrix[n]; } ff_vdpau_common_start_frame(pic_ctx, buffer, size); diff --git a/libavcodec/videodsp_template.c b/libavcodec/videodsp_template.c index 55123a5844..8743d725c6 100644 --- a/libavcodec/videodsp_template.c +++ b/libavcodec/videodsp_template.c @@ -60,7 +60,7 @@ void FUNC(ff_emulated_edge_mc)(uint8_t *buf, const uint8_t *src, av_assert2(start_x < end_x && block_w); w = end_x - start_x; - src += start_y * src_linesize + start_x * sizeof(pixel); + src += start_y * src_linesize + start_x * (ptrdiff_t)sizeof(pixel); buf += start_x * sizeof(pixel); // top @@ -83,7 +83,7 @@ void FUNC(ff_emulated_edge_mc)(uint8_t *buf, const uint8_t *src, buf += buf_linesize; } - buf -= block_h * buf_linesize + start_x * sizeof(pixel); + buf -= block_h * buf_linesize + start_x * (ptrdiff_t)sizeof(pixel); while (block_h--) { pixel *bufp = (pixel *) buf; diff --git a/libavcodec/videotoolbox.c b/libavcodec/videotoolbox.c index 49e726a75f..2357401412 100644 --- a/libavcodec/videotoolbox.c +++ b/libavcodec/videotoolbox.c @@ -608,8 +608,7 @@ static void videotoolbox_decoder_callback(void *opaque, CMTime pts, CMTime duration) { - AVCodecContext *avctx = opaque; - VTContext *vtctx = avctx->internal->hwaccel_priv_data; + VTContext *vtctx = opaque; if (vtctx->frame) { CVPixelBufferRelease(vtctx->frame); @@ -617,7 +616,8 @@ static void videotoolbox_decoder_callback(void *opaque, } if (!image_buffer) { - av_log(avctx, AV_LOG_DEBUG, "vt decoder cb: output image buffer is null\n"); + av_log(vtctx->logctx, AV_LOG_DEBUG, + "vt decoder cb: output image buffer is null: %i\n", status); return; } @@ -828,7 +828,7 @@ static int videotoolbox_start(AVCodecContext *avctx) videotoolbox->cv_pix_fmt_type); decoder_cb.decompressionOutputCallback = videotoolbox_decoder_callback; - decoder_cb.decompressionOutputRefCon = avctx; + decoder_cb.decompressionOutputRefCon = avctx->internal->hwaccel_priv_data; status = VTDecompressionSessionCreate(NULL, // allocator videotoolbox->cm_fmt_desc, // videoFormatDescription @@ -1040,6 +1040,8 @@ static int videotoolbox_common_init(AVCodecContext *avctx) AVHWFramesContext *hw_frames; int err; + vtctx->logctx = avctx; + // Old API - do nothing. if (avctx->hwaccel_context) return 0; diff --git a/libavcodec/videotoolboxenc.c b/libavcodec/videotoolboxenc.c index 9b7ee6720c..8a02d3d1a0 100644 --- a/libavcodec/videotoolboxenc.c +++ b/libavcodec/videotoolboxenc.c @@ -49,6 +49,10 @@ enum { kCVPixelFormatType_420YpCbCr10BiPlanarFullRange = 'xf20' }; enum { kCVPixelFormatType_420YpCbCr10BiPlanarVideoRange = 'x420' }; #endif +#ifndef TARGET_CPU_ARM64 +# define TARGET_CPU_ARM64 0 +#endif + typedef OSStatus (*getParameterSetAtIndex)(CMFormatDescriptionRef videoDesc, size_t parameterSetIndex, const uint8_t **parameterSetPointerOut, diff --git a/libavcodec/vmdvideo.c b/libavcodec/vmdvideo.c index c1dc5b9696..bb9306e4ff 100644 --- a/libavcodec/vmdvideo.c +++ b/libavcodec/vmdvideo.c @@ -194,7 +194,7 @@ static int vmd_decode(VmdVideoContext *s, AVFrame *frame) unsigned char len; int ofs; - int frame_x, frame_y; + int frame_x, frame_y, prev_linesize; int frame_width, frame_height; frame_x = AV_RL16(&s->buf[6]); @@ -282,7 +282,13 @@ static int vmd_decode(VmdVideoContext *s, AVFrame *frame) } dp = &frame->data[0][frame_y * frame->linesize[0] + frame_x]; - pp = &s->prev_frame->data[0][frame_y * s->prev_frame->linesize[0] + frame_x]; + if (s->prev_frame->data[0]) { + prev_linesize = s->prev_frame->linesize[0]; + pp = s->prev_frame->data[0] + frame_y * prev_linesize + frame_x; + } else { + pp = NULL; + prev_linesize = 0; + } switch (meth) { case 1: for (i = 0; i < frame_height; i++) { @@ -298,7 +304,7 @@ static int vmd_decode(VmdVideoContext *s, AVFrame *frame) ofs += len; } else { /* interframe pixel copy */ - if (ofs + len + 1 > frame_width || !s->prev_frame->data[0]) + if (ofs + len + 1 > frame_width || !pp) return AVERROR_INVALIDDATA; memcpy(&dp[ofs], &pp[ofs], len + 1); ofs += len + 1; @@ -311,7 +317,7 @@ static int vmd_decode(VmdVideoContext *s, AVFrame *frame) return AVERROR_INVALIDDATA; } dp += frame->linesize[0]; - pp += s->prev_frame->linesize[0]; + pp = FF_PTR_ADD(pp, prev_linesize); } break; @@ -319,7 +325,6 @@ static int vmd_decode(VmdVideoContext *s, AVFrame *frame) for (i = 0; i < frame_height; i++) { bytestream2_get_buffer(&gb, dp, frame_width); dp += frame->linesize[0]; - pp += s->prev_frame->linesize[0]; } break; @@ -347,7 +352,7 @@ static int vmd_decode(VmdVideoContext *s, AVFrame *frame) } } else { /* interframe pixel copy */ - if (ofs + len + 1 > frame_width || !s->prev_frame->data[0]) + if (ofs + len + 1 > frame_width || !pp) return AVERROR_INVALIDDATA; memcpy(&dp[ofs], &pp[ofs], len + 1); ofs += len + 1; @@ -360,7 +365,7 @@ static int vmd_decode(VmdVideoContext *s, AVFrame *frame) return AVERROR_INVALIDDATA; } dp += frame->linesize[0]; - pp += s->prev_frame->linesize[0]; + pp = FF_PTR_ADD(pp, prev_linesize); } break; } diff --git a/libavcodec/vorbisdec.c b/libavcodec/vorbisdec.c index 169df591b3..7e49ef8cdb 100644 --- a/libavcodec/vorbisdec.c +++ b/libavcodec/vorbisdec.c @@ -363,6 +363,10 @@ static int vorbis_parse_setup_hdr_codebooks(vorbis_context *vc) unsigned codebook_value_bits = get_bits(gb, 4) + 1; unsigned codebook_sequence_p = get_bits1(gb); + if (!isfinite(codebook_minimum_value) || !isfinite(codebook_delta_value)) { + ret = AVERROR_INVALIDDATA; + goto error; + } ff_dlog(NULL, " We expect %d numbers for building the codevectors. \n", codebook_lookup_values); ff_dlog(NULL, " delta %f minmum %f \n", @@ -1447,6 +1451,11 @@ static av_always_inline int vorbis_residue_decode_internal(vorbis_context *vc, unsigned step = FASTDIV(vr->partition_size << 1, dim << 1); vorbis_codebook codebook = vc->codebooks[vqbook]; + if (get_bits_left(gb) < 0) { + av_log(vc->avctx, AV_LOG_ERROR, "Overread %d bits\n", -get_bits_left(gb)); + return 0; + } + if (vr_type == 0) { voffs = voffset+j*vlen; diff --git a/libavcodec/vp3.c b/libavcodec/vp3.c index 57c6eb1ff9..3c5f8d710e 100644 --- a/libavcodec/vp3.c +++ b/libavcodec/vp3.c @@ -2012,8 +2012,7 @@ static int vp4_mc_loop_filter(Vp3DecodeContext *s, int plane, int motion_x, int x_offset = (-(x + 2) & 7) + 2; y_offset = (-(y + 2) & 7) + 2; - if (x_offset > 8 + x_subpel && y_offset > 8 + y_subpel) - return 0; + av_assert1(!(x_offset > 8 + x_subpel && y_offset > 8 + y_subpel)); s->vdsp.emulated_edge_mc(loop, motion_source - stride - 1, loop_stride, stride, @@ -2345,6 +2344,8 @@ static av_cold int vp3_decode_init(AVCodecContext *avctx) s->avctx = avctx; s->width = FFALIGN(avctx->coded_width, 16); s->height = FFALIGN(avctx->coded_height, 16); + if (s->width < 18) + return AVERROR_PATCHWELCOME; if (avctx->codec_id != AV_CODEC_ID_THEORA) avctx->pix_fmt = AV_PIX_FMT_YUV420P; avctx->chroma_sample_location = AVCHROMA_LOC_CENTER; @@ -2683,15 +2684,27 @@ static int vp3_decode_frame(AVCodecContext *avctx, if ((ret = ff_thread_get_buffer(avctx, &s->current_frame, AV_GET_BUFFER_FLAG_REF)) < 0) goto error; - if (!s->edge_emu_buffer) + if (!s->edge_emu_buffer) { s->edge_emu_buffer = av_malloc(9 * FFABS(s->current_frame.f->linesize[0])); + if (!s->edge_emu_buffer) { + ret = AVERROR(ENOMEM); + goto error; + } + } if (s->keyframe) { if (!s->theora) { skip_bits(&gb, 4); /* width code */ skip_bits(&gb, 4); /* height code */ if (s->version) { - s->version = get_bits(&gb, 5); + int version = get_bits(&gb, 5); +#if !CONFIG_VP4_DECODER + if (version >= 2) { + av_log(avctx, AV_LOG_ERROR, "This build does not support decoding VP4.\n"); + return AVERROR_DECODER_NOT_FOUND; + } +#endif + s->version = version; if (avctx->frame_number == 0) av_log(s->avctx, AV_LOG_DEBUG, "VP version: %d\n", s->version); @@ -2910,7 +2923,9 @@ static int theora_decode_header(AVCodecContext *avctx, GetBitContext *gb) /* sanity check */ if (av_image_check_size(visible_width, visible_height, 0, avctx) < 0 || visible_width + offset_x > s->width || - visible_height + offset_y > s->height) { + visible_height + offset_y > s->height || + visible_width < 18 + ) { av_log(avctx, AV_LOG_ERROR, "Invalid frame dimensions - w:%d h:%d x:%d y:%d (%dx%d).\n", visible_width, visible_height, offset_x, offset_y, @@ -2956,6 +2971,8 @@ static int theora_decode_header(AVCodecContext *avctx, GetBitContext *gb) } else avctx->pix_fmt = AV_PIX_FMT_YUV420P; + if (s->width < 18) + return AVERROR_PATCHWELCOME; ret = ff_set_dimensions(avctx, s->width, s->height); if (ret < 0) return ret; diff --git a/libavcodec/vp8.c b/libavcodec/vp8.c index d16e7b6aa3..06b38bc9c8 100644 --- a/libavcodec/vp8.c +++ b/libavcodec/vp8.c @@ -239,8 +239,16 @@ int update_dimensions(VP8Context *s, int width, int height, int is_vp7) return AVERROR(ENOMEM); } #if HAVE_THREADS - pthread_mutex_init(&s->thread_data[i].lock, NULL); - pthread_cond_init(&s->thread_data[i].cond, NULL); + ret = pthread_mutex_init(&s->thread_data[i].lock, NULL); + if (ret) { + free_buffers(s); + return AVERROR(ret); + } + ret = pthread_cond_init(&s->thread_data[i].cond, NULL); + if (ret) { + free_buffers(s); + return AVERROR(ret); + } #endif } diff --git a/libavcodec/vp9.c b/libavcodec/vp9.c index 4659f94ee8..43b11ebede 100644 --- a/libavcodec/vp9.c +++ b/libavcodec/vp9.c @@ -715,6 +715,12 @@ static int decode_frame_header(AVCodecContext *avctx, s->s.h.segmentation.feat[i].skip_enabled = get_bits1(&s->gb); } } + } else { + // Reset fields under segmentation switch if segmentation is disabled. + // This is necessary because some hwaccels don't ignore these fields + // if segmentation is disabled. + s->s.h.segmentation.temporal = 0; + s->s.h.segmentation.update_map = 0; } // set qmul[] based on Y/UV, AC/DC and segmentation Q idx deltas diff --git a/libavcodec/vp9recon.c b/libavcodec/vp9recon.c index e38cf99ec5..6bad63598d 100644 --- a/libavcodec/vp9recon.c +++ b/libavcodec/vp9recon.c @@ -319,7 +319,11 @@ static av_always_inline void mc_luma_unscaled(VP9TileData *td, vp9_mc_func (*mc) // The arm/aarch64 _hv filters read one more row than what actually is // needed, so switch to emulated edge one pixel sooner vertically // (!!my * 5) than horizontally (!!mx * 4). + // The arm/aarch64 _h filters read one more pixel than what actually is + // needed, so switch to emulated edge if that would read beyond the bottom + // right block. if (x < !!mx * 3 || y < !!my * 3 || + ((ARCH_AARCH64 || ARCH_ARM) && (x + !!mx * 5 > w - bw) && (y + !!my * 5 + 1 > h - bh)) || x + !!mx * 4 > w - bw || y + !!my * 5 > h - bh) { s->vdsp.emulated_edge_mc(td->edge_emu_buffer, ref - !!my * 3 * ref_stride - !!mx * 3 * bytesperpixel, @@ -358,7 +362,11 @@ static av_always_inline void mc_chroma_unscaled(VP9TileData *td, vp9_mc_func (*m // The arm/aarch64 _hv filters read one more row than what actually is // needed, so switch to emulated edge one pixel sooner vertically // (!!my * 5) than horizontally (!!mx * 4). + // The arm/aarch64 _h filters read one more pixel than what actually is + // needed, so switch to emulated edge if that would read beyond the bottom + // right block. if (x < !!mx * 3 || y < !!my * 3 || + ((ARCH_AARCH64 || ARCH_ARM) && (x + !!mx * 5 > w - bw) && (y + !!my * 5 + 1 > h - bh)) || x + !!mx * 4 > w - bw || y + !!my * 5 > h - bh) { s->vdsp.emulated_edge_mc(td->edge_emu_buffer, ref_u - !!my * 3 * src_stride_u - !!mx * 3 * bytesperpixel, diff --git a/libavcodec/vqavideo.c b/libavcodec/vqavideo.c index f45390cfe5..d0e1927444 100644 --- a/libavcodec/vqavideo.c +++ b/libavcodec/vqavideo.c @@ -588,13 +588,14 @@ static int vqa_decode_chunk(VqaContext *s, AVFrame *frame) if (s->partial_countdown <= 0) { bytestream2_init(&s->gb, s->next_codebook_buffer, s->next_codebook_buffer_index); /* decompress codebook */ - if ((res = decode_format80(s, s->next_codebook_buffer_index, - s->codebook, s->codebook_size, 0)) < 0) - return res; + res = decode_format80(s, s->next_codebook_buffer_index, + s->codebook, s->codebook_size, 0); /* reset accounting */ s->next_codebook_buffer_index = 0; s->partial_countdown = s->partial_count; + if (res < 0) + return res; } } diff --git a/libavcodec/vt_internal.h b/libavcodec/vt_internal.h index fb64735b8c..08d9c77090 100644 --- a/libavcodec/vt_internal.h +++ b/libavcodec/vt_internal.h @@ -42,6 +42,8 @@ typedef struct VTContext { // Current H264 parameters (used to trigger decoder restart on SPS changes). uint8_t sps[3]; bool reconfig_needed; + + void *logctx; } VTContext; int ff_videotoolbox_alloc_frame(AVCodecContext *avctx, AVFrame *frame); diff --git a/libavcodec/wavpack.c b/libavcodec/wavpack.c index 2d49172eaf..4b865087bb 100644 --- a/libavcodec/wavpack.c +++ b/libavcodec/wavpack.c @@ -128,7 +128,7 @@ static av_always_inline unsigned get_tail(GetBitContext *gb, int k) e = (1 << (p + 1)) - k - 1; res = get_bitsz(gb, p); if (res >= e) - res = (res << 1) - e + get_bits1(gb); + res = res * 2U - e + get_bits1(gb); return res; } @@ -498,6 +498,8 @@ static int wv_unpack_dsd_high(WavpackFrameContext *s, uint8_t *dst_left, uint8_t sp[0].fltr0 = 0; } + if (DSD_BYTE_READY(high, low) && !bytestream2_get_bytes_left(&s->gbyte)) + return AVERROR_INVALIDDATA; while (DSD_BYTE_READY(high, low) && bytestream2_get_bytes_left(&s->gbyte)) { value = (value << 8) | bytestream2_get_byte(&s->gbyte); high = (high << 8) | 0xff; @@ -533,6 +535,8 @@ static int wv_unpack_dsd_high(WavpackFrameContext *s, uint8_t *dst_left, uint8_t sp[1].fltr0 = 0; } + if (DSD_BYTE_READY(high, low) && !bytestream2_get_bytes_left(&s->gbyte)) + return AVERROR_INVALIDDATA; while (DSD_BYTE_READY(high, low) && bytestream2_get_bytes_left(&s->gbyte)) { value = (value << 8) | bytestream2_get_byte(&s->gbyte); high = (high << 8) | 0xff; diff --git a/libavcodec/wavpackenc.c b/libavcodec/wavpackenc.c index 0a798438bc..4dca7728d0 100644 --- a/libavcodec/wavpackenc.c +++ b/libavcodec/wavpackenc.c @@ -1976,7 +1976,7 @@ static void encode_flush(WavPackEncodeContext *s) put_bits(pb, 31, 0x7FFFFFFF); cbits -= 31; } else { - put_bits(pb, cbits, (1 << cbits) - 1); + put_bits(pb, cbits, (1U << cbits) - 1); cbits = 0; } } while (cbits); @@ -2005,7 +2005,7 @@ static void encode_flush(WavPackEncodeContext *s) put_bits(pb, 31, 0x7FFFFFFF); cbits -= 31; } else { - put_bits(pb, cbits, (1 << cbits) - 1); + put_bits(pb, cbits, (1U << cbits) - 1); cbits = 0; } } while (cbits); diff --git a/libavcodec/webp.c b/libavcodec/webp.c index 5a7aebc587..a00db09165 100644 --- a/libavcodec/webp.c +++ b/libavcodec/webp.c @@ -627,6 +627,9 @@ static int decode_entropy_coded_image(WebPContext *s, enum ImageRole role, while (y < img->frame->height) { int v; + if (get_bits_left(&s->gb) < 0) + return AVERROR_INVALIDDATA; + hg = get_huffman_group(s, img, x, y); v = huff_reader_get_symbol(&hg[HUFF_IDX_GREEN], &s->gb); if (v < NUM_LITERAL_CODES) { @@ -698,6 +701,9 @@ static int decode_entropy_coded_image(WebPContext *s, enum ImageRole role, ref_x = FFMAX(0, ref_x); ref_y = FFMAX(0, ref_y); + if (ref_y == y && ref_x >= x) + return AVERROR_INVALIDDATA; + /* copy pixels * source and dest regions can overlap and wrap lines, so just * copy per-pixel */ diff --git a/libavcodec/wma.c b/libavcodec/wma.c index cfa5fa3355..a979a112bd 100644 --- a/libavcodec/wma.c +++ b/libavcodec/wma.c @@ -457,7 +457,7 @@ int ff_wma_run_level_decode(AVCodecContext *avctx, GetBitContext *gb, if (get_bits1(gb)) { av_log(avctx, AV_LOG_ERROR, "broken escape sequence\n"); - return -1; + return AVERROR_INVALIDDATA; } else offset += get_bits(gb, frame_len_bits) + 4; } else @@ -475,7 +475,7 @@ int ff_wma_run_level_decode(AVCodecContext *avctx, GetBitContext *gb, offset, num_coefs ); - return -1; + return AVERROR_INVALIDDATA; } return 0; diff --git a/libavcodec/wmadec.c b/libavcodec/wmadec.c index 9c79556bb5..f5408a1789 100644 --- a/libavcodec/wmadec.c +++ b/libavcodec/wmadec.c @@ -590,15 +590,18 @@ static int wma_decode_block(WMACodecContext *s) if (s->channel_coded[ch]) { int tindex; WMACoef *ptr = &s->coefs1[ch][0]; + int ret; /* special VLC tables are used for ms stereo because * there is potentially less energy there */ tindex = (ch == 1 && s->ms_stereo); memset(ptr, 0, s->block_len * sizeof(WMACoef)); - ff_wma_run_level_decode(s->avctx, &s->gb, &s->coef_vlc[tindex], - s->level_table[tindex], s->run_table[tindex], - 0, ptr, 0, nb_coefs[ch], - s->block_len, s->frame_len_bits, coef_nb_bits); + ret = ff_wma_run_level_decode(s->avctx, &s->gb, &s->coef_vlc[tindex], + s->level_table[tindex], s->run_table[tindex], + 0, ptr, 0, nb_coefs[ch], + s->block_len, s->frame_len_bits, coef_nb_bits); + if (ret < 0) + return ret; } if (s->version == 1 && s->avctx->channels >= 2) align_get_bits(&s->gb); @@ -977,6 +980,7 @@ AVCodec ff_wmav1_decoder = { .capabilities = AV_CODEC_CAP_DR1, .sample_fmts = (const enum AVSampleFormat[]) { AV_SAMPLE_FMT_FLTP, AV_SAMPLE_FMT_NONE }, + .caps_internal = FF_CODEC_CAP_INIT_CLEANUP, }; #endif #if CONFIG_WMAV2_DECODER @@ -993,5 +997,6 @@ AVCodec ff_wmav2_decoder = { .capabilities = AV_CODEC_CAP_DR1, .sample_fmts = (const enum AVSampleFormat[]) { AV_SAMPLE_FMT_FLTP, AV_SAMPLE_FMT_NONE }, + .caps_internal = FF_CODEC_CAP_INIT_CLEANUP, }; #endif diff --git a/libavcodec/wmaenc.c b/libavcodec/wmaenc.c index 6a7e23d016..a28a0c387b 100644 --- a/libavcodec/wmaenc.c +++ b/libavcodec/wmaenc.c @@ -436,6 +436,7 @@ AVCodec ff_wmav1_encoder = { .close = ff_wma_end, .sample_fmts = (const enum AVSampleFormat[]) { AV_SAMPLE_FMT_FLTP, AV_SAMPLE_FMT_NONE }, + .caps_internal = FF_CODEC_CAP_INIT_CLEANUP, }; #endif #if CONFIG_WMAV2_ENCODER @@ -450,5 +451,6 @@ AVCodec ff_wmav2_encoder = { .close = ff_wma_end, .sample_fmts = (const enum AVSampleFormat[]) { AV_SAMPLE_FMT_FLTP, AV_SAMPLE_FMT_NONE }, + .caps_internal = FF_CODEC_CAP_INIT_CLEANUP, }; #endif diff --git a/libavcodec/wmaprodec.c b/libavcodec/wmaprodec.c index 8024ce1611..7c3044b0b0 100644 --- a/libavcodec/wmaprodec.c +++ b/libavcodec/wmaprodec.c @@ -985,13 +985,16 @@ static int decode_coeffs(WMAProDecodeCtx *s, int c) /** decode run level coded coefficients */ if (cur_coeff < s->subframe_len) { + int ret; + memset(&ci->coeffs[cur_coeff], 0, sizeof(*ci->coeffs) * (s->subframe_len - cur_coeff)); - if (ff_wma_run_level_decode(s->avctx, &s->gb, vlc, - level, run, 1, ci->coeffs, - cur_coeff, s->subframe_len, - s->subframe_len, s->esc_len, 0)) - return AVERROR_INVALIDDATA; + ret = ff_wma_run_level_decode(s->avctx, &s->gb, vlc, + level, run, 1, ci->coeffs, + cur_coeff, s->subframe_len, + s->subframe_len, s->esc_len, 0); + if (ret < 0) + return ret; } return 0; diff --git a/libavcodec/wmavoice.c b/libavcodec/wmavoice.c index fbdb865360..283e4e6644 100644 --- a/libavcodec/wmavoice.c +++ b/libavcodec/wmavoice.c @@ -367,7 +367,7 @@ static av_cold void wmavoice_flush(AVCodecContext *ctx) static av_cold int wmavoice_decode_init(AVCodecContext *ctx) { static AVOnce init_static_once = AV_ONCE_INIT; - int n, flags, pitch_range, lsp16_flag; + int n, flags, pitch_range, lsp16_flag, ret; WMAVoiceContext *s = ctx->priv_data; ff_thread_once(&init_static_once, wmavoice_init_static_data); @@ -395,10 +395,11 @@ static av_cold int wmavoice_decode_init(AVCodecContext *ctx) s->spillover_bitsize = 3 + av_ceil_log2(ctx->block_align); s->do_apf = flags & 0x1; if (s->do_apf) { - ff_rdft_init(&s->rdft, 7, DFT_R2C); - ff_rdft_init(&s->irdft, 7, IDFT_C2R); - ff_dct_init(&s->dct, 6, DCT_I); - ff_dct_init(&s->dst, 6, DST_I); + if ((ret = ff_rdft_init(&s->rdft, 7, DFT_R2C)) < 0 || + (ret = ff_rdft_init(&s->irdft, 7, IDFT_C2R)) < 0 || + (ret = ff_dct_init (&s->dct, 6, DCT_I)) < 0 || + (ret = ff_dct_init (&s->dst, 6, DST_I)) < 0) + return ret; ff_sine_window_init(s->cos, 256); memcpy(&s->sin[255], s->cos, 256 * sizeof(s->cos[0])); @@ -1491,6 +1492,8 @@ static int synth_frame(AVCodecContext *ctx, GetBitContext *gb, int frame_idx, /* Parse frame type ("frame header"), see frame_descs */ int bd_idx = s->vbm_tree[get_vlc2(gb, frame_type_vlc.table, 6, 3)], block_nsamples; + pitch[0] = INT_MAX; + if (bd_idx < 0) { av_log(ctx, AV_LOG_ERROR, "Invalid frame type VLC code, skipping\n"); @@ -1608,6 +1611,9 @@ static int synth_frame(AVCodecContext *ctx, GetBitContext *gb, int frame_idx, double i_lsps[MAX_LSPS]; float lpcs[MAX_LSPS]; + if(frame_descs[bd_idx].fcb_type >= FCB_TYPE_AW_PULSES && pitch[0] == INT_MAX) + return AVERROR_INVALIDDATA; + for (n = 0; n < s->lsps; n++) // LSF -> LSP i_lsps[n] = cos(0.5 * (prev_lsps[n] + lsps[n])); ff_acelp_lspd2lpc(i_lsps, lpcs, s->lsps >> 1); diff --git a/libavcodec/wnv1.c b/libavcodec/wnv1.c index dcf417763c..fd9721f4ca 100644 --- a/libavcodec/wnv1.c +++ b/libavcodec/wnv1.c @@ -126,6 +126,9 @@ static av_cold int decode_init(AVCodecContext *avctx) { static AVOnce init_static_once = AV_ONCE_INIT; + if (avctx->width <= 1) + return AVERROR_INVALIDDATA; + avctx->pix_fmt = AV_PIX_FMT_YUV422P; ff_thread_once(&init_static_once, wnv1_init_static); diff --git a/libavcodec/x86/mathops.h b/libavcodec/x86/mathops.h index 6298f5ed19..ca7e2dffc1 100644 --- a/libavcodec/x86/mathops.h +++ b/libavcodec/x86/mathops.h @@ -35,12 +35,20 @@ static av_always_inline av_const int MULL(int a, int b, unsigned shift) { int rt, dummy; + if (__builtin_constant_p(shift)) __asm__ ( "imull %3 \n\t" "shrdl %4, %%edx, %%eax \n\t" :"=a"(rt), "=d"(dummy) - :"a"(a), "rm"(b), "ci"((uint8_t)shift) + :"a"(a), "rm"(b), "i"(shift & 0x1F) ); + else + __asm__ ( + "imull %3 \n\t" + "shrdl %4, %%edx, %%eax \n\t" + :"=a"(rt), "=d"(dummy) + :"a"(a), "rm"(b), "c"((uint8_t)shift) + ); return rt; } @@ -113,19 +121,31 @@ __asm__ volatile(\ // avoid +32 for shift optimization (gcc should do that ...) #define NEG_SSR32 NEG_SSR32 static inline int32_t NEG_SSR32( int32_t a, int8_t s){ + if (__builtin_constant_p(s)) __asm__ ("sarl %1, %0\n\t" : "+r" (a) - : "ic" ((uint8_t)(-s)) + : "i" (-s & 0x1F) ); + else + __asm__ ("sarl %1, %0\n\t" + : "+r" (a) + : "c" ((uint8_t)(-s)) + ); return a; } #define NEG_USR32 NEG_USR32 static inline uint32_t NEG_USR32(uint32_t a, int8_t s){ + if (__builtin_constant_p(s)) __asm__ ("shrl %1, %0\n\t" : "+r" (a) - : "ic" ((uint8_t)(-s)) + : "i" (-s & 0x1F) ); + else + __asm__ ("shrl %1, %0\n\t" + : "+r" (a) + : "c" ((uint8_t)(-s)) + ); return a; } diff --git a/libavcodec/x86/vp3dsp_init.c b/libavcodec/x86/vp3dsp_init.c index ba47e1c6cd..d23420c89b 100644 --- a/libavcodec/x86/vp3dsp_init.c +++ b/libavcodec/x86/vp3dsp_init.c @@ -60,7 +60,7 @@ av_cold void ff_vp3dsp_init_x86(VP3DSPContext *c, int flags) if (!(flags & AV_CODEC_FLAG_BITEXACT)) { c->v_loop_filter = c->v_loop_filter_unaligned = ff_vp3_v_loop_filter_mmxext; - c->h_loop_filter = c->v_loop_filter_unaligned = ff_vp3_h_loop_filter_mmxext; + c->h_loop_filter = c->h_loop_filter_unaligned = ff_vp3_h_loop_filter_mmxext; } } diff --git a/libavcodec/xan.c b/libavcodec/xan.c index 6bf754f151..84f1858750 100644 --- a/libavcodec/xan.c +++ b/libavcodec/xan.c @@ -610,6 +610,9 @@ static int xan_decode_frame(AVCodecContext *avctx, return AVERROR_INVALIDDATA; } + if (buf_size < 9) + return AVERROR_INVALIDDATA; + if ((ret = ff_get_buffer(avctx, frame, AV_GET_BUFFER_FLAG_REF)) < 0) return ret; diff --git a/libavcodec/xpmdec.c b/libavcodec/xpmdec.c index 922dfc0f67..6db95285ce 100644 --- a/libavcodec/xpmdec.c +++ b/libavcodec/xpmdec.c @@ -341,9 +341,6 @@ static int xpm_decode_frame(AVCodecContext *avctx, void *data, if ((ret = ff_set_dimensions(avctx, width, height)) < 0) return ret; - if ((ret = ff_get_buffer(avctx, p, 0)) < 0) - return ret; - if (cpp <= 0 || cpp >= 5) { av_log(avctx, AV_LOG_ERROR, "unsupported/invalid number of chars per pixel: %d\n", cpp); return AVERROR_INVALIDDATA; @@ -358,16 +355,22 @@ static int xpm_decode_frame(AVCodecContext *avctx, void *data, return AVERROR_INVALIDDATA; } - size *= 4; - - av_fast_padded_malloc(&x->pixels, &x->pixels_size, size); - if (!x->pixels) + if (size > SIZE_MAX / 4) return AVERROR(ENOMEM); + size *= 4; + ptr += mod_strcspn(ptr, ",") + 1; if (end - ptr < 1) return AVERROR_INVALIDDATA; + if ((ret = ff_get_buffer(avctx, p, 0)) < 0) + return ret; + + av_fast_padded_malloc(&x->pixels, &x->pixels_size, size); + if (!x->pixels) + return AVERROR(ENOMEM); + for (i = 0; i < ncolors; i++) { const uint8_t *index; int len; diff --git a/libavcodec/xsubdec.c b/libavcodec/xsubdec.c index 87ac910577..3be7393651 100644 --- a/libavcodec/xsubdec.c +++ b/libavcodec/xsubdec.c @@ -58,6 +58,7 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_sub_ptr, int64_t packet_time = 0; GetBitContext gb; int has_alpha = avctx->codec_tag == MKTAG('D','X','S','A'); + int64_t start_display_time, end_display_time; // check that at least header fits if (buf_size < 27 + 7 * 2 + 4 * (3 + has_alpha)) { @@ -72,8 +73,14 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_sub_ptr, } if (avpkt->pts != AV_NOPTS_VALUE) packet_time = av_rescale_q(avpkt->pts, AV_TIME_BASE_Q, (AVRational){1, 1000}); - sub->start_display_time = parse_timecode(buf + 1, packet_time); - sub->end_display_time = parse_timecode(buf + 14, packet_time); + + sub->start_display_time = start_display_time = parse_timecode(buf + 1, packet_time); + sub->end_display_time = end_display_time = parse_timecode(buf + 14, packet_time); + if (sub->start_display_time != start_display_time || + sub-> end_display_time != end_display_time) { + av_log(avctx, AV_LOG_ERROR, "time code not representable in 32bit\n"); + return -1; + } buf += 27; // read header diff --git a/libavcodec/xvididct.c b/libavcodec/xvididct.c index 360deb3244..ced8c7235a 100644 --- a/libavcodec/xvididct.c +++ b/libavcodec/xvididct.c @@ -56,37 +56,37 @@ static const int TAB35[] = { 26722, 25172, 22654, 19266, 15137, 10426, 5315 }; static int idct_row(short *in, const int *const tab, int rnd) { - const int c1 = tab[0]; - const int c2 = tab[1]; - const int c3 = tab[2]; - const int c4 = tab[3]; - const int c5 = tab[4]; - const int c6 = tab[5]; - const int c7 = tab[6]; + const unsigned c1 = tab[0]; + const unsigned c2 = tab[1]; + const unsigned c3 = tab[2]; + const unsigned c4 = tab[3]; + const unsigned c5 = tab[4]; + const unsigned c6 = tab[5]; + const unsigned c7 = tab[6]; const int right = in[5] | in[6] | in[7]; const int left = in[1] | in[2] | in[3]; if (!(right | in[4])) { const int k = c4 * in[0] + rnd; if (left) { - const int a0 = k + c2 * in[2]; - const int a1 = k + c6 * in[2]; - const int a2 = k - c6 * in[2]; - const int a3 = k - c2 * in[2]; + const unsigned a0 = k + c2 * in[2]; + const unsigned a1 = k + c6 * in[2]; + const unsigned a2 = k - c6 * in[2]; + const unsigned a3 = k - c2 * in[2]; const int b0 = c1 * in[1] + c3 * in[3]; const int b1 = c3 * in[1] - c7 * in[3]; const int b2 = c5 * in[1] - c1 * in[3]; const int b3 = c7 * in[1] - c5 * in[3]; - in[0] = (a0 + b0) >> ROW_SHIFT; - in[1] = (a1 + b1) >> ROW_SHIFT; - in[2] = (a2 + b2) >> ROW_SHIFT; - in[3] = (a3 + b3) >> ROW_SHIFT; - in[4] = (a3 - b3) >> ROW_SHIFT; - in[5] = (a2 - b2) >> ROW_SHIFT; - in[6] = (a1 - b1) >> ROW_SHIFT; - in[7] = (a0 - b0) >> ROW_SHIFT; + in[0] = (int)(a0 + b0) >> ROW_SHIFT; + in[1] = (int)(a1 + b1) >> ROW_SHIFT; + in[2] = (int)(a2 + b2) >> ROW_SHIFT; + in[3] = (int)(a3 + b3) >> ROW_SHIFT; + in[4] = (int)(a3 - b3) >> ROW_SHIFT; + in[5] = (int)(a2 - b2) >> ROW_SHIFT; + in[6] = (int)(a1 - b1) >> ROW_SHIFT; + in[7] = (int)(a0 - b0) >> ROW_SHIFT; } else { const int a0 = k >> ROW_SHIFT; if (a0) { @@ -102,8 +102,8 @@ static int idct_row(short *in, const int *const tab, int rnd) return 0; } } else if (!(left | right)) { - const int a0 = (rnd + c4 * (in[0] + in[4])) >> ROW_SHIFT; - const int a1 = (rnd + c4 * (in[0] - in[4])) >> ROW_SHIFT; + const int a0 = (int)(rnd + c4 * (in[0] + in[4])) >> ROW_SHIFT; + const int a1 = (int)(rnd + c4 * (in[0] - in[4])) >> ROW_SHIFT; in[0] = a0; in[3] = a0; @@ -114,7 +114,7 @@ static int idct_row(short *in, const int *const tab, int rnd) in[5] = a1; in[6] = a1; } else { - const int k = c4 * in[0] + rnd; + const unsigned int k = c4 * in[0] + rnd; const unsigned int a0 = k + c2 * in[2] + c4 * in[4] + c6 * in[6]; const unsigned int a1 = k + c6 * in[2] - c4 * in[4] - c2 * in[6]; const unsigned int a2 = k - c6 * in[2] - c4 * in[4] + c2 * in[6]; diff --git a/libavcodec/zmbvenc.c b/libavcodec/zmbvenc.c index 319381dd48..d050cc2ef0 100644 --- a/libavcodec/zmbvenc.c +++ b/libavcodec/zmbvenc.c @@ -73,6 +73,7 @@ typedef struct ZmbvEncContext { int keyint, curfrm; int bypp; enum ZmbvFormat fmt; + int zlib_init_ok; z_stream zstream; int score_tab[ZMBV_BLOCK * ZMBV_BLOCK * 4 + 1]; @@ -310,8 +311,9 @@ static av_cold int encode_end(AVCodecContext *avctx) av_freep(&c->comp_buf); av_freep(&c->work_buf); - deflateEnd(&c->zstream); av_freep(&c->prev_buf); + if (c->zlib_init_ok) + deflateEnd(&c->zstream); return 0; } @@ -381,8 +383,6 @@ static av_cold int encode_init(AVCodecContext *avctx) return AVERROR(EINVAL); } - // Needed if zlib unused or init aborted before deflateInit - memset(&c->zstream, 0, sizeof(z_stream)); c->comp_size = avctx->width * c->bypp * avctx->height + 1024 + ((avctx->width + ZMBV_BLOCK - 1) / ZMBV_BLOCK) * ((avctx->height + ZMBV_BLOCK - 1) / ZMBV_BLOCK) * 2 + 4; if (!(c->work_buf = av_malloc(c->comp_size))) { @@ -424,6 +424,7 @@ static av_cold int encode_init(AVCodecContext *avctx) av_log(avctx, AV_LOG_ERROR, "Inflate init error: %d\n", zret); return -1; } + c->zlib_init_ok = 1; return 0; } @@ -445,4 +446,5 @@ AVCodec ff_zmbv_encoder = { #endif //ZMBV_ENABLE_24BPP AV_PIX_FMT_BGR0, AV_PIX_FMT_NONE }, + .caps_internal = FF_CODEC_CAP_INIT_CLEANUP, }; diff --git a/libavdevice/dshow.c b/libavdevice/dshow.c index 73a9a48b20..c0d8b12d5e 100644 --- a/libavdevice/dshow.c +++ b/libavdevice/dshow.c @@ -778,10 +778,10 @@ dshow_open_device(AVFormatContext *avctx, ICreateDevEnum *devenum, goto error; } } - if (ctx->device_filter[otherDevType]) { + if (ctx->device_filter[otherDevType]) { // avoid adding add two instances of the same device to the graph, one for video, one for audio // a few devices don't support this (could also do this check earlier to avoid double crossbars, etc. but they seem OK) - if (strcmp(device_filter_unique_name, ctx->device_unique_name[otherDevType]) == 0) { + if (!device_filter_unique_name || strcmp(device_filter_unique_name, ctx->device_unique_name[otherDevType]) == 0) { av_log(avctx, AV_LOG_DEBUG, "reusing previous graph capture filter... %s\n", device_filter_unique_name); IBaseFilter_Release(device_filter); device_filter = ctx->device_filter[otherDevType]; @@ -873,7 +873,7 @@ dshow_open_device(AVFormatContext *avctx, ICreateDevEnum *devenum, av_log(avctx, AV_LOG_ERROR, "Could not create CaptureGraphBuilder2\n"); goto error; } - ICaptureGraphBuilder2_SetFiltergraph(graph_builder2, graph); + r = ICaptureGraphBuilder2_SetFiltergraph(graph_builder2, graph); if (r != S_OK) { av_log(avctx, AV_LOG_ERROR, "Could not set graph for CaptureGraphBuilder2\n"); goto error; diff --git a/libavdevice/dshow_capture.h b/libavdevice/dshow_capture.h index 06ded2ba96..f2e35bd600 100644 --- a/libavdevice/dshow_capture.h +++ b/libavdevice/dshow_capture.h @@ -125,14 +125,15 @@ void ff_dshow_##prefix##_Destroy(class *this) \ class *ff_dshow_##prefix##_Create(__VA_ARGS__) \ { \ class *this = CoTaskMemAlloc(sizeof(class)); \ - void *vtbl = CoTaskMemAlloc(sizeof(*this->vtbl)); \ dshowdebug("ff_dshow_"AV_STRINGIFY(prefix)"_Create(%p)\n", this); \ - if (!this || !vtbl) \ + if (!this) \ goto fail; \ ZeroMemory(this, sizeof(class)); \ - ZeroMemory(vtbl, sizeof(*this->vtbl)); \ + this->vtbl = CoTaskMemAlloc(sizeof(*this->vtbl)); \ + if (!this->vtbl) \ + goto fail; \ + ZeroMemory(this->vtbl, sizeof(*this->vtbl)); \ this->ref = 1; \ - this->vtbl = vtbl; \ if (!setup) \ goto fail; \ dshowdebug("created ff_dshow_"AV_STRINGIFY(prefix)" %p\n", this); \ diff --git a/libavdevice/dshow_filter.c b/libavdevice/dshow_filter.c index 61e057a836..4295f42aa2 100644 --- a/libavdevice/dshow_filter.c +++ b/libavdevice/dshow_filter.c @@ -135,7 +135,7 @@ long ff_dshow_filter_JoinFilterGraph(DShowFilter *this, IFilterGraph *graph, this->info.pGraph = graph; if (name) - wcscpy(this->info.achName, name); + wcscpy_s(this->info.achName, sizeof(this->info.achName) / sizeof(wchar_t), name); return S_OK; } diff --git a/libavdevice/v4l2.c b/libavdevice/v4l2.c index 365bacd771..f90490eebf 100644 --- a/libavdevice/v4l2.c +++ b/libavdevice/v4l2.c @@ -95,10 +95,10 @@ struct video_data { int (*open_f)(const char *file, int oflag, ...); int (*close_f)(int fd); int (*dup_f)(int fd); -#ifdef __GLIBC__ - int (*ioctl_f)(int fd, unsigned long int request, ...); -#else +#if HAVE_POSIX_IOCTL int (*ioctl_f)(int fd, int request, ...); +#else + int (*ioctl_f)(int fd, unsigned long int request, ...); #endif ssize_t (*read_f)(int fd, void *buffer, size_t n); void *(*mmap_f)(void *start, size_t length, int prot, int flags, int fd, int64_t offset); diff --git a/libavdevice/xcbgrab.c b/libavdevice/xcbgrab.c index 8e3292e577..b4968e42ff 100644 --- a/libavdevice/xcbgrab.c +++ b/libavdevice/xcbgrab.c @@ -826,7 +826,10 @@ static av_cold int xcbgrab_read_header(AVFormatContext *s) if (!sscanf(s->url, "%[^+]+%d,%d", display_name, &c->x, &c->y)) { *display_name = 0; - sscanf(s->url, "+%d,%d", &c->x, &c->y); + if(sscanf(s->url, "+%d,%d", &c->x, &c->y) != 2) { + if (*s->url) + av_log(s, AV_LOG_WARNING, "Ambigous URL: %s\n", s->url); + } } c->conn = xcb_connect(display_name[0] ? display_name : NULL, &screen_num); diff --git a/libavdevice/xv.c b/libavdevice/xv.c index 50dc4e0d04..33507291d2 100644 --- a/libavdevice/xv.c +++ b/libavdevice/xv.c @@ -296,7 +296,7 @@ static int write_picture(AVFormatContext *s, uint8_t *input_data[4], { XVContext *xv = s->priv_data; XvImage *img = xv->yuv_image; - uint8_t *data[3] = { + uint8_t *data[4] = { img->data + img->offsets[0], img->data + img->offsets[1], img->data + img->offsets[2] diff --git a/libavfilter/aeval.c b/libavfilter/aeval.c index d5437431ab..7636063bcf 100644 --- a/libavfilter/aeval.c +++ b/libavfilter/aeval.c @@ -124,11 +124,10 @@ static int parse_channel_expressions(AVFilterContext *ctx, } #define ADD_EXPRESSION(expr_) do { \ - if (!av_dynarray2_add((void **)&eval->expr, &eval->nb_channels, \ - sizeof(*eval->expr), NULL)) { \ - ret = AVERROR(ENOMEM); \ + ret = av_dynarray_add_nofree(&eval->expr, \ + &eval->nb_channels, NULL); \ + if (ret < 0) \ goto end; \ - } \ eval->expr[eval->nb_channels-1] = NULL; \ ret = av_expr_parse(&eval->expr[eval->nb_channels - 1], expr_, \ var_names, func1_names, func1, \ diff --git a/libavfilter/af_aderivative.c b/libavfilter/af_aderivative.c index a591515cbf..56a59d517e 100644 --- a/libavfilter/af_aderivative.c +++ b/libavfilter/af_aderivative.c @@ -150,6 +150,7 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *in) s->prev = ff_get_audio_buffer(inlink, 1); if (!s->prev) { av_frame_free(&in); + av_frame_free(&out); return AVERROR(ENOMEM); } } diff --git a/libavfilter/af_alimiter.c b/libavfilter/af_alimiter.c index c41e95576f..f941768848 100644 --- a/libavfilter/af_alimiter.c +++ b/libavfilter/af_alimiter.c @@ -176,10 +176,11 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *in) } else { for (i = s->nextiter; i < s->nextiter + s->nextlen; i++) { int j = i % buffer_size; - double ppeak, pdelta; + double ppeak = 0, pdelta; - ppeak = fabs(buffer[nextpos[j]]) > fabs(buffer[nextpos[j] + 1]) ? - fabs(buffer[nextpos[j]]) : fabs(buffer[nextpos[j] + 1]); + if (nextpos[j] >= 0) + ppeak = fabs(buffer[nextpos[j]]) > fabs(buffer[nextpos[j] + 1]) ? + fabs(buffer[nextpos[j]]) : fabs(buffer[nextpos[j] + 1]); pdelta = (limit / peak - limit / ppeak) / (((buffer_size - nextpos[j] + s->pos) % buffer_size) / channels); if (pdelta < nextdelta[j]) { nextdelta[j] = pdelta; diff --git a/libavfilter/af_drmeter.c b/libavfilter/af_drmeter.c index ecccb65186..425c25ae87 100644 --- a/libavfilter/af_drmeter.c +++ b/libavfilter/af_drmeter.c @@ -167,6 +167,11 @@ static void print_stats(AVFilterContext *ctx) float chdr, secondpeak, rmssum = 0; int i, j, first = 0; + if (!p->nb_samples) { + av_log(ctx, AV_LOG_INFO, "No data, dynamic range not meassurable\n"); + return; + } + finish_block(p); for (i = 0; i <= 10000; i++) { diff --git a/libavfilter/af_hdcd.c b/libavfilter/af_hdcd.c index 251d03229a..978f63599b 100644 --- a/libavfilter/af_hdcd.c +++ b/libavfilter/af_hdcd.c @@ -1053,7 +1053,7 @@ static int hdcd_integrate(HDCDContext *ctx, hdcd_state *states, int channels, in for (j = result - 1; j >= 0; j--) { for (i = 0; i < channels; i++) - bits[i] |= (*(samples++) & 1) << j; + bits[i] |= (*(samples++) & 1U) << j; samples += stride - channels; } @@ -1210,7 +1210,7 @@ static int hdcd_analyze(int32_t *samples, int count, int stride, int gain, int t int32_t *samples_end = samples + stride * count; for (i = 0; i < count; i++) { - samples[i * stride] <<= 15; + samples[i * stride] *= 1 << 15; if (mode == HDCD_ANA_PE) { int pel = (samples[i * stride] >> 16) & 1; int32_t sample = samples[i * stride]; @@ -1284,13 +1284,13 @@ static int hdcd_envelope(int32_t *samples, int count, int stride, int vbits, int av_assert0(asample <= max_asample); sample = sample >= 0 ? peaktab[asample] : -peaktab[asample]; } else - sample <<= shft; + sample *= (1 << shft); samples[i * stride] = sample; } } else { for (i = 0; i < count; i++) - samples[i * stride] <<= shft; + samples[i * stride] *= (1 << shft); } if (gain <= target_gain) { diff --git a/libavfilter/af_mcompand.c b/libavfilter/af_mcompand.c index ce4f366ad7..9ac1940a52 100644 --- a/libavfilter/af_mcompand.c +++ b/libavfilter/af_mcompand.c @@ -445,8 +445,8 @@ static int config_output(AVFilterLink *outlink) } new_nb_items += sscanf(tstr2, "%lf", &s->bands[i].topfreq) == 1; - if (s->bands[i].topfreq < 0 || s->bands[i].topfreq >= outlink->sample_rate / 2) { - av_log(ctx, AV_LOG_ERROR, "crossover_frequency: %f, should be >=0 and lower than half of sample rate: %d.\n", s->bands[i].topfreq, outlink->sample_rate / 2); + if (s->bands[i].topfreq < 0 || s->bands[i].topfreq >= outlink->sample_rate / 2.0) { + av_log(ctx, AV_LOG_ERROR, "crossover_frequency: %f, should be >=0 and lower than half of sample rate: %f.\n", s->bands[i].topfreq, outlink->sample_rate / 2.0); return AVERROR(EINVAL); } diff --git a/libavfilter/af_pan.c b/libavfilter/af_pan.c index b628177071..11034fb257 100644 --- a/libavfilter/af_pan.c +++ b/libavfilter/af_pan.c @@ -126,6 +126,14 @@ static av_cold int init(AVFilterContext *ctx) if (ret < 0) goto fail; + if (pan->nb_output_channels > MAX_CHANNELS) { + av_log(ctx, AV_LOG_ERROR, + "af_pan supports a maximum of %d channels. " + "Feel free to ask for a higher limit.\n", MAX_CHANNELS); + ret = AVERROR_PATCHWELCOME; + goto fail; + } + /* parse channel specifications */ while ((arg = arg0 = av_strtok(NULL, "|", &tokenizer))) { int used_in_ch[MAX_CHANNELS] = {0}; @@ -178,7 +186,7 @@ static av_cold int init(AVFilterContext *ctx) sign = 1; while (1) { gain = 1; - if (sscanf(arg, "%lf%n *%n", &gain, &len, &len)) + if (sscanf(arg, "%lf%n *%n", &gain, &len, &len) >= 1) arg += len; if (parse_channel_name(&arg, &in_ch_id, &named)){ av_log(ctx, AV_LOG_ERROR, diff --git a/libavfilter/af_stereowiden.c b/libavfilter/af_stereowiden.c index 251f08438e..8ce2dd02d3 100644 --- a/libavfilter/af_stereowiden.c +++ b/libavfilter/af_stereowiden.c @@ -75,6 +75,8 @@ static int config_input(AVFilterLink *inlink) s->length = s->delay * inlink->sample_rate / 1000; s->length *= 2; + if (s->length == 0) + return AVERROR(EINVAL); s->buffer = av_calloc(s->length, sizeof(*s->buffer)); if (!s->buffer) return AVERROR(ENOMEM); diff --git a/libavfilter/af_surround.c b/libavfilter/af_surround.c index d18b3146e7..c0b8b002c2 100644 --- a/libavfilter/af_surround.c +++ b/libavfilter/af_surround.c @@ -203,13 +203,13 @@ static int config_input(AVFilterLink *inlink) s->rdft = av_calloc(inlink->channels, sizeof(*s->rdft)); if (!s->rdft) return AVERROR(ENOMEM); + s->nb_in_channels = inlink->channels; for (ch = 0; ch < inlink->channels; ch++) { s->rdft[ch] = av_rdft_init(ff_log2(s->buf_size), DFT_R2C); if (!s->rdft[ch]) return AVERROR(ENOMEM); } - s->nb_in_channels = inlink->channels; s->input_levels = av_malloc_array(s->nb_in_channels, sizeof(*s->input_levels)); if (!s->input_levels) return AVERROR(ENOMEM); @@ -266,13 +266,13 @@ static int config_output(AVFilterLink *outlink) s->irdft = av_calloc(outlink->channels, sizeof(*s->irdft)); if (!s->irdft) return AVERROR(ENOMEM); + s->nb_out_channels = outlink->channels; for (ch = 0; ch < outlink->channels; ch++) { s->irdft[ch] = av_rdft_init(ff_log2(s->buf_size), IDFT_C2R); if (!s->irdft[ch]) return AVERROR(ENOMEM); } - s->nb_out_channels = outlink->channels; s->output_levels = av_malloc_array(s->nb_out_channels, sizeof(*s->output_levels)); if (!s->output_levels) return AVERROR(ENOMEM); diff --git a/libavfilter/af_vibrato.c b/libavfilter/af_vibrato.c index 5db1f0f6c9..64d6068b39 100644 --- a/libavfilter/af_vibrato.c +++ b/libavfilter/af_vibrato.c @@ -157,11 +157,11 @@ static int config_input(AVFilterLink *inlink) int c; AVFilterContext *ctx = inlink->dst; VibratoContext *s = ctx->priv; - s->channels = inlink->channels; s->buf = av_calloc(inlink->channels, sizeof(*s->buf)); if (!s->buf) return AVERROR(ENOMEM); + s->channels = inlink->channels; s->buf_size = lrint(inlink->sample_rate * 0.005 + 0.5); for (c = 0; c < s->channels; c++) { s->buf[c] = av_malloc_array(s->buf_size, sizeof(*s->buf[c])); diff --git a/libavfilter/asrc_flite.c b/libavfilter/asrc_flite.c index 3e543a3ab6..6373ae761d 100644 --- a/libavfilter/asrc_flite.c +++ b/libavfilter/asrc_flite.c @@ -196,10 +196,12 @@ static av_cold void uninit(AVFilterContext *ctx) { FliteContext *flite = ctx->priv; - if (!--flite->voice_entry->usage_count) - flite->voice_entry->unregister_fn(flite->voice); - flite->voice = NULL; - flite->voice_entry = NULL; + if (flite->voice_entry) { + if (!--flite->voice_entry->usage_count) { + flite->voice_entry->unregister_fn(flite->voice); + flite->voice_entry->voice = NULL; + } + } delete_wave(flite->wave); flite->wave = NULL; } diff --git a/libavfilter/asrc_sine.c b/libavfilter/asrc_sine.c index 6fe080efb6..3b7d2e6d00 100644 --- a/libavfilter/asrc_sine.c +++ b/libavfilter/asrc_sine.c @@ -247,7 +247,7 @@ static int request_frame(AVFilterLink *outlink) samples[i] = sine->sin[sine->phi >> (32 - LOG_PERIOD)]; sine->phi += sine->dphi; if (sine->beep_index < sine->beep_length) { - samples[i] += sine->sin[sine->phi_beep >> (32 - LOG_PERIOD)] << 1; + samples[i] += sine->sin[sine->phi_beep >> (32 - LOG_PERIOD)] * 2; sine->phi_beep += sine->dphi_beep; } if (++sine->beep_index == sine->beep_period) diff --git a/libavfilter/avfilter.c b/libavfilter/avfilter.c index 22ecad5f77..6a344282eb 100644 --- a/libavfilter/avfilter.c +++ b/libavfilter/avfilter.c @@ -925,6 +925,8 @@ int avfilter_init_dict(AVFilterContext *ctx, AVDictionary **options) ret = ctx->filter->init(ctx); else if (ctx->filter->init_dict) ret = ctx->filter->init_dict(ctx, options); + if (ret < 0) + return ret; if (ctx->enable_str) { ret = set_enable_expr(ctx, ctx->enable_str); @@ -932,7 +934,7 @@ int avfilter_init_dict(AVFilterContext *ctx, AVDictionary **options) return ret; } - return ret; + return 0; } int avfilter_init_str(AVFilterContext *filter, const char *args) diff --git a/libavfilter/buffersrc.c b/libavfilter/buffersrc.c index da1cf9941e..89efbb448a 100644 --- a/libavfilter/buffersrc.c +++ b/libavfilter/buffersrc.c @@ -337,6 +337,11 @@ static av_cold int init_audio(AVFilterContext *ctx) return AVERROR(EINVAL); } + if (s->sample_rate <= 0) { + av_log(ctx, AV_LOG_ERROR, "Sample rate not set\n"); + return AVERROR(EINVAL); + } + if (!s->time_base.num) s->time_base = (AVRational){1, s->sample_rate}; diff --git a/libavfilter/f_metadata.c b/libavfilter/f_metadata.c index 598257b15b..3332d91a3e 100644 --- a/libavfilter/f_metadata.c +++ b/libavfilter/f_metadata.c @@ -304,9 +304,6 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *frame) AVDictionary **metadata = &frame->metadata; AVDictionaryEntry *e; - if (!*metadata && s->mode != METADATA_ADD) - return ff_filter_frame(outlink, frame); - e = av_dict_get(*metadata, !s->key ? "" : s->key, NULL, !s->key ? AV_DICT_IGNORE_SUFFIX: 0); diff --git a/libavfilter/scale_eval.c b/libavfilter/scale_eval.c index dfec081e15..ea71260dcb 100644 --- a/libavfilter/scale_eval.c +++ b/libavfilter/scale_eval.c @@ -114,7 +114,7 @@ int ff_scale_adjust_dimensions(AVFilterLink *inlink, int *ret_w, int *ret_h, int force_original_aspect_ratio, int force_divisible_by) { - int w, h; + int64_t w, h; int factor_w, factor_h; w = *ret_w; @@ -148,8 +148,8 @@ int ff_scale_adjust_dimensions(AVFilterLink *inlink, * dimensions so that it is not divisible by the set factors anymore * unless force_divisible_by is defined as well */ if (force_original_aspect_ratio) { - int tmp_w = av_rescale(h, inlink->w, inlink->h); - int tmp_h = av_rescale(w, inlink->h, inlink->w); + int64_t tmp_w = av_rescale(h, inlink->w, inlink->h); + int64_t tmp_h = av_rescale(w, inlink->h, inlink->w); if (force_original_aspect_ratio == 1) { w = FFMIN(tmp_w, w); @@ -170,6 +170,9 @@ int ff_scale_adjust_dimensions(AVFilterLink *inlink, } } + if ((int32_t)w != w || (int32_t)h != h) + return AVERROR(EINVAL); + *ret_w = w; *ret_h = h; diff --git a/libavfilter/scale_eval.h b/libavfilter/scale_eval.h index fceb023fec..658092962d 100644 --- a/libavfilter/scale_eval.h +++ b/libavfilter/scale_eval.h @@ -40,7 +40,7 @@ int ff_scale_eval_dimensions(void *ctx, * or both of the evaluated values are of the form '-n' or if * force_original_aspect_ratio is set. * - * Returns 0. + * Returns negative error code on error or non negative on success */ int ff_scale_adjust_dimensions(AVFilterLink *inlink, int *ret_w, int *ret_h, diff --git a/libavfilter/signature_lookup.c b/libavfilter/signature_lookup.c index 272c717c77..ba0dcfbf34 100644 --- a/libavfilter/signature_lookup.c +++ b/libavfilter/signature_lookup.c @@ -37,6 +37,16 @@ #define STATUS_END_REACHED 1 #define STATUS_BEGIN_REACHED 2 +static void sll_free(MatchingInfo **sll) +{ + while (*sll) { + MatchingInfo *tmp = *sll; + *sll = tmp->next; + tmp->next = NULL; + av_free(tmp); + } +} + static void fill_l1distlut(uint8_t lut[]) { int i, j, tmp_i, tmp_j,count; @@ -289,6 +299,11 @@ static MatchingInfo* get_matching_parameters(AVFilterContext *ctx, SignatureCont if (!c->next) av_log(ctx, AV_LOG_FATAL, "Could not allocate memory"); c = c->next; + + } + if (!c) { + sll_free(&cands); + goto error; } c->framerateratio = (i+1.0) / 30; c->score = hspace[i][j].score; @@ -305,6 +320,7 @@ static MatchingInfo* get_matching_parameters(AVFilterContext *ctx, SignatureCont } } } + error: for (i = 0; i < MAX_FRAMERATE; i++) { av_freep(&hspace[i]); } @@ -437,14 +453,14 @@ static MatchingInfo evaluate_parameters(AVFilterContext *ctx, SignatureContext * } if (tolerancecount > 2) { - a = aprev; - b = bprev; if (dir == DIR_NEXT) { /* turn around */ a = infos->first; b = infos->second; dir = DIR_PREV; } else { + a = aprev; + b = bprev; break; } } @@ -485,10 +501,10 @@ static MatchingInfo evaluate_parameters(AVFilterContext *ctx, SignatureContext * continue; /* matching sequence is too short */ if ((double) goodfcount / (double) fcount < sc->thit) continue; - if ((double) goodfcount*0.5 < FFMAX(gooda, goodb)) + if ((double) goodfcount*0.5 <= FFMAX(gooda, goodb)) continue; - meandist = (double) goodfcount / (double) distsum; + meandist = (double) distsum / (double) goodfcount; if (meandist < minmeandist || status == STATUS_END_REACHED | STATUS_BEGIN_REACHED || @@ -520,16 +536,6 @@ static MatchingInfo evaluate_parameters(AVFilterContext *ctx, SignatureContext * return bestmatch; } -static void sll_free(MatchingInfo *sll) -{ - void *tmp; - while (sll) { - tmp = sll; - sll = sll->next; - av_freep(&tmp); - } -} - static MatchingInfo lookup_signatures(AVFilterContext *ctx, SignatureContext *sc, StreamContext *first, StreamContext *second, int mode) { CoarseSignature *cs, *cs2; @@ -572,7 +578,7 @@ static MatchingInfo lookup_signatures(AVFilterContext *ctx, SignatureContext *sc "ratio %f, offset %d, score %d, %d frames matching\n", bestmatch.first->index, bestmatch.second->index, bestmatch.framerateratio, bestmatch.offset, bestmatch.score, bestmatch.matchframes); - sll_free(infos); + sll_free(&infos); } } while (find_next_coarsecandidate(sc, second->coarsesiglist, &cs, &cs2, 0) && !bestmatch.whole); return bestmatch; diff --git a/libavfilter/vf_addroi.c b/libavfilter/vf_addroi.c index d6b83ee854..f8caaffe3c 100644 --- a/libavfilter/vf_addroi.c +++ b/libavfilter/vf_addroi.c @@ -38,6 +38,7 @@ enum { static const char *const addroi_var_names[] = { "iw", "ih", + NULL, }; typedef struct AddROIContext { diff --git a/libavfilter/vf_avgblur.c b/libavfilter/vf_avgblur.c index 7fd65eabfc..070500c37a 100644 --- a/libavfilter/vf_avgblur.c +++ b/libavfilter/vf_avgblur.c @@ -273,7 +273,7 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *in) const int width = s->planewidth[plane]; if (!(s->planes & (1 << plane))) { - if (out != in) + if (out->data[plane] != in->data[plane]) av_image_copy_plane(out->data[plane], out->linesize[plane], in->data[plane], in->linesize[plane], width * ((s->depth + 7) / 8), height); diff --git a/libavfilter/vf_bm3d.c b/libavfilter/vf_bm3d.c index 18d13b25ff..0bb7e41eff 100644 --- a/libavfilter/vf_bm3d.c +++ b/libavfilter/vf_bm3d.c @@ -279,7 +279,7 @@ static void do_block_matching_multi(BM3DContext *s, const uint8_t *src, int src_ int r_y, int r_x, int plane, int jobnr) { SliceContext *sc = &s->slices[jobnr]; - double MSE2SSE = s->group_size * s->block_size * s->block_size * src_range * src_range / (s->max * s->max); + double MSE2SSE = s->group_size * s->block_size * s->block_size * src_range * src_range / (double)(s->max * s->max); double distMul = 1. / MSE2SSE; double th_sse = th_mse * MSE2SSE; int i, index = sc->nb_match_blocks; diff --git a/libavfilter/vf_bwdif.c b/libavfilter/vf_bwdif.c index b6aed7a450..e4b4ec79b0 100644 --- a/libavfilter/vf_bwdif.c +++ b/libavfilter/vf_bwdif.c @@ -343,13 +343,14 @@ static int config_props(AVFilterLink *link) if(yadif->mode&1) link->frame_rate = av_mul_q(link->src->inputs[0]->frame_rate, (AVRational){2,1}); - if (link->w < 3 || link->h < 4) { - av_log(ctx, AV_LOG_ERROR, "Video of less than 3 columns or 4 lines is not supported\n"); + yadif->csp = av_pix_fmt_desc_get(link->format); + yadif->filter = filter; + + if (AV_CEIL_RSHIFT(link->w, yadif->csp->log2_chroma_w) < 3 || AV_CEIL_RSHIFT(link->h, yadif->csp->log2_chroma_h) < 4) { + av_log(ctx, AV_LOG_ERROR, "Video with planes less than 3 columns or 4 lines is not supported\n"); return AVERROR(EINVAL); } - yadif->csp = av_pix_fmt_desc_get(link->format); - yadif->filter = filter; if (yadif->csp->comp[0].depth > 8) { s->filter_intra = filter_intra_16bit; s->filter_line = filter_line_c_16bit; diff --git a/libavfilter/vf_ciescope.c b/libavfilter/vf_ciescope.c index 719e66ad0f..2ddec3d06b 100644 --- a/libavfilter/vf_ciescope.c +++ b/libavfilter/vf_ciescope.c @@ -849,7 +849,8 @@ rgb_to_xy(double rc, *z = m[2][0] * rc + m[2][1] * gc + m[2][2] * bc; sum = *x + *y + *z; - + if (sum == 0) + sum = 1; *x = *x / sum; *y = *y / sum; } diff --git a/libavfilter/vf_codecview.c b/libavfilter/vf_codecview.c index 197dc96136..28ac2df72f 100644 --- a/libavfilter/vf_codecview.c +++ b/libavfilter/vf_codecview.c @@ -141,7 +141,7 @@ static void draw_line(uint8_t *buf, int sx, int sy, int ex, int ey, } buf += sx + sy * stride; ex -= sx; - f = ((ey - sy) << 16) / ex; + f = ((ey - sy) * (1 << 16)) / ex; for (x = 0; x <= ex; x++) { y = (x * f) >> 16; fr = (x * f) & 0xFFFF; @@ -156,7 +156,7 @@ static void draw_line(uint8_t *buf, int sx, int sy, int ex, int ey, buf += sx + sy * stride; ey -= sy; if (ey) - f = ((ex - sx) << 16) / ey; + f = ((ex - sx) * (1 << 16)) / ey; else f = 0; for(y= 0; y <= ey; y++){ @@ -199,8 +199,8 @@ static void draw_arrow(uint8_t *buf, int sx, int sy, int ex, int length = sqrt((rx * rx + ry * ry) << 8); // FIXME subpixel accuracy - rx = ROUNDED_DIV(rx * 3 << 4, length); - ry = ROUNDED_DIV(ry * 3 << 4, length); + rx = ROUNDED_DIV(rx * (3 << 4), length); + ry = ROUNDED_DIV(ry * (3 << 4), length); if (tail) { rx = -rx; diff --git a/libavfilter/vf_dctdnoiz.c b/libavfilter/vf_dctdnoiz.c index a89f2631c8..2019a5b456 100644 --- a/libavfilter/vf_dctdnoiz.c +++ b/libavfilter/vf_dctdnoiz.c @@ -564,6 +564,9 @@ static int config_input(AVFilterLink *inlink) inlink->h - s->pr_height); max_slice_h = s->pr_height / ((s->bsize - 1) * 2); + if (max_slice_h == 0) + return AVERROR(EINVAL); + s->nb_threads = FFMIN3(MAX_THREADS, ff_filter_get_nb_threads(ctx), max_slice_h); av_log(ctx, AV_LOG_DEBUG, "threads: [max=%d hmax=%d user=%d] => %d\n", MAX_THREADS, max_slice_h, ff_filter_get_nb_threads(ctx), s->nb_threads); diff --git a/libavfilter/vf_deshake_opencl.c b/libavfilter/vf_deshake_opencl.c index 4f1bb09362..6a46fff9e2 100644 --- a/libavfilter/vf_deshake_opencl.c +++ b/libavfilter/vf_deshake_opencl.c @@ -712,7 +712,7 @@ static int minimize_error( total_err += deshake_ctx->ransac_err[j]; } - if (total_err < best_err) { + if (i == 0 || total_err < best_err) { for (int mi = 0; mi < 6; ++mi) { best_model[mi] = model[mi]; } diff --git a/libavfilter/vf_fftdnoiz.c b/libavfilter/vf_fftdnoiz.c index 856d716be5..eea1887e40 100644 --- a/libavfilter/vf_fftdnoiz.c +++ b/libavfilter/vf_fftdnoiz.c @@ -161,7 +161,7 @@ static void export_row8(FFTComplex *src, uint8_t *dst, int rw, float scale, int int j; for (j = 0; j < rw; j++) - dst[j] = av_clip_uint8(src[j].re * scale + 0.5f); + dst[j] = av_clip_uint8(lrintf(src[j].re * scale)); } static void import_row16(FFTComplex *dst, uint8_t *srcp, int rw) diff --git a/libavfilter/vf_frei0r.c b/libavfilter/vf_frei0r.c index 2ec4707d97..ed0ba9f866 100644 --- a/libavfilter/vf_frei0r.c +++ b/libavfilter/vf_frei0r.c @@ -353,15 +353,21 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *in) { Frei0rContext *s = inlink->dst->priv; AVFilterLink *outlink = inlink->dst->outputs[0]; - AVFrame *out; + AVFrame *out = ff_default_get_video_buffer2(outlink, outlink->w, outlink->h, 16); + if (!out) + goto fail; - out = ff_get_video_buffer(outlink, outlink->w, outlink->h); - if (!out) { - av_frame_free(&in); - return AVERROR(ENOMEM); - } av_frame_copy_props(out, in); + if (in->linesize[0] != out->linesize[0]) { + AVFrame *in2 = ff_default_get_video_buffer2(outlink, outlink->w, outlink->h, 16); + if (!in2) + goto fail; + av_frame_copy(in2, in); + av_frame_free(&in); + in = in2; + } + s->update(s->instance, in->pts * av_q2d(inlink->time_base) * 1000, (const uint32_t *)in->data[0], (uint32_t *)out->data[0]); @@ -369,6 +375,10 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *in) av_frame_free(&in); return ff_filter_frame(outlink, out); +fail: + av_frame_free(&in); + av_frame_free(&out); + return AVERROR(ENOMEM); } static int process_command(AVFilterContext *ctx, const char *cmd, const char *args, @@ -467,7 +477,7 @@ static int source_config_props(AVFilterLink *outlink) static int source_request_frame(AVFilterLink *outlink) { Frei0rContext *s = outlink->src->priv; - AVFrame *frame = ff_get_video_buffer(outlink, outlink->w, outlink->h); + AVFrame *frame = ff_default_get_video_buffer2(outlink, outlink->w, outlink->h, 16); if (!frame) return AVERROR(ENOMEM); diff --git a/libavfilter/vf_gradfun.c b/libavfilter/vf_gradfun.c index 28da37ff93..31c2bf19c3 100644 --- a/libavfilter/vf_gradfun.c +++ b/libavfilter/vf_gradfun.c @@ -93,7 +93,7 @@ static void filter(GradFunContext *ctx, uint8_t *dst, const uint8_t *src, int wi for (y = 0; y < r; y++) ctx->blur_line(dc, buf + y * bstride, buf + (y - 1) * bstride, src + 2 * y * src_linesize, src_linesize, width / 2); for (;;) { - if (y < height - r) { + if (y + 1 < height - r) { int mod = ((y + r) / 2) % r; uint16_t *buf0 = buf + mod * bstride; uint16_t *buf1 = buf + (mod ? mod - 1 : r - 1) * bstride; diff --git a/libavfilter/vf_hwupload_cuda.c b/libavfilter/vf_hwupload_cuda.c index 33906f2515..afc1b265ed 100644 --- a/libavfilter/vf_hwupload_cuda.c +++ b/libavfilter/vf_hwupload_cuda.c @@ -57,7 +57,7 @@ static int cudaupload_query_formats(AVFilterContext *ctx) int ret; static const enum AVPixelFormat input_pix_fmts[] = { - AV_PIX_FMT_NV12, AV_PIX_FMT_YUV420P, AV_PIX_FMT_YUV444P, + AV_PIX_FMT_NV12, AV_PIX_FMT_YUV420P, AV_PIX_FMT_YUVA420P, AV_PIX_FMT_YUV444P, AV_PIX_FMT_P010, AV_PIX_FMT_P016, AV_PIX_FMT_YUV444P16, AV_PIX_FMT_0RGB32, AV_PIX_FMT_0BGR32, #if CONFIG_VULKAN diff --git a/libavfilter/vf_idet.c b/libavfilter/vf_idet.c index 02ae2edcb9..cc08722b06 100644 --- a/libavfilter/vf_idet.c +++ b/libavfilter/vf_idet.c @@ -336,20 +336,19 @@ static int request_frame(AVFilterLink *link) static av_cold void uninit(AVFilterContext *ctx) { IDETContext *idet = ctx->priv; - int level = strncmp(ctx->name, "auto-inserted", 13) ? AV_LOG_INFO : AV_LOG_DEBUG; - av_log(ctx, level, "Repeated Fields: Neither:%6"PRId64" Top:%6"PRId64" Bottom:%6"PRId64"\n", + av_log(ctx, AV_LOG_INFO, "Repeated Fields: Neither:%6"PRId64" Top:%6"PRId64" Bottom:%6"PRId64"\n", idet->total_repeats[REPEAT_NONE], idet->total_repeats[REPEAT_TOP], idet->total_repeats[REPEAT_BOTTOM] ); - av_log(ctx, level, "Single frame detection: TFF:%6"PRId64" BFF:%6"PRId64" Progressive:%6"PRId64" Undetermined:%6"PRId64"\n", + av_log(ctx, AV_LOG_INFO, "Single frame detection: TFF:%6"PRId64" BFF:%6"PRId64" Progressive:%6"PRId64" Undetermined:%6"PRId64"\n", idet->total_prestat[TFF], idet->total_prestat[BFF], idet->total_prestat[PROGRESSIVE], idet->total_prestat[UNDETERMINED] ); - av_log(ctx, level, "Multi frame detection: TFF:%6"PRId64" BFF:%6"PRId64" Progressive:%6"PRId64" Undetermined:%6"PRId64"\n", + av_log(ctx, AV_LOG_INFO, "Multi frame detection: TFF:%6"PRId64" BFF:%6"PRId64" Progressive:%6"PRId64" Undetermined:%6"PRId64"\n", idet->total_poststat[TFF], idet->total_poststat[BFF], idet->total_poststat[PROGRESSIVE], diff --git a/libavfilter/vf_lut3d.c b/libavfilter/vf_lut3d.c index 8b1aeb75e7..106e096579 100644 --- a/libavfilter/vf_lut3d.c +++ b/libavfilter/vf_lut3d.c @@ -757,7 +757,8 @@ try_again: else if (!strncmp(line + 7, "MAX ", 4)) vals = max; if (!vals) return AVERROR_INVALIDDATA; - av_sscanf(line + 11, "%f %f %f", vals, vals + 1, vals + 2); + if (av_sscanf(line + 11, "%f %f %f", vals, vals + 1, vals + 2) != 3) + return AVERROR_INVALIDDATA; av_log(ctx, AV_LOG_DEBUG, "min: %f %f %f | max: %f %f %f\n", min[0], min[1], min[2], max[0], max[1], max[2]); goto try_again; @@ -1785,12 +1786,14 @@ try_again: else if (!strncmp(line + 7, "MAX ", 4)) vals = max; if (!vals) return AVERROR_INVALIDDATA; - av_sscanf(line + 11, "%f %f %f", vals, vals + 1, vals + 2); + if (av_sscanf(line + 11, "%f %f %f", vals, vals + 1, vals + 2) != 3) + return AVERROR_INVALIDDATA; av_log(ctx, AV_LOG_DEBUG, "min: %f %f %f | max: %f %f %f\n", min[0], min[1], min[2], max[0], max[1], max[2]); goto try_again; } else if (!strncmp(line, "LUT_1D_INPUT_RANGE ", 19)) { - av_sscanf(line + 19, "%f %f", min, max); + if (av_sscanf(line + 19, "%f %f", min, max) != 2) + return AVERROR_INVALIDDATA; min[1] = min[2] = min[0]; max[1] = max[2] = max[0]; goto try_again; diff --git a/libavfilter/vf_mestimate.c b/libavfilter/vf_mestimate.c index 7ecfe7da60..9a2865a0cb 100644 --- a/libavfilter/vf_mestimate.c +++ b/libavfilter/vf_mestimate.c @@ -100,6 +100,9 @@ static int config_input(AVFilterLink *inlink) s->b_height = inlink->h >> s->log2_mb_size; s->b_count = s->b_width * s->b_height; + if (s->b_count == 0) + return AVERROR(EINVAL); + for (i = 0; i < 3; i++) { s->mv_table[i] = av_mallocz_array(s->b_count, sizeof(*s->mv_table[0])); if (!s->mv_table[i]) diff --git a/libavfilter/vf_minterpolate.c b/libavfilter/vf_minterpolate.c index 969463f021..cc59f02c21 100644 --- a/libavfilter/vf_minterpolate.c +++ b/libavfilter/vf_minterpolate.c @@ -1087,8 +1087,13 @@ static void interpolate(AVFilterLink *inlink, AVFrame *avf_out) pts = av_rescale(avf_out->pts, (int64_t) ALPHA_MAX * outlink->time_base.num * inlink->time_base.den, (int64_t) outlink->time_base.den * inlink->time_base.num); - alpha = (pts - mi_ctx->frames[1].avf->pts * ALPHA_MAX) / (mi_ctx->frames[2].avf->pts - mi_ctx->frames[1].avf->pts); - alpha = av_clip(alpha, 0, ALPHA_MAX); + if (mi_ctx->frames[2].avf->pts > mi_ctx->frames[1].avf->pts) { + alpha = (pts - mi_ctx->frames[1].avf->pts * ALPHA_MAX) / (mi_ctx->frames[2].avf->pts - mi_ctx->frames[1].avf->pts); + alpha = av_clip(alpha, 0, ALPHA_MAX); + } else { + av_log(ctx, AV_LOG_DEBUG, "duplicate input PTS detected\n"); + alpha = 0; + } if (alpha == 0 || alpha == ALPHA_MAX) { av_frame_copy(avf_out, alpha ? mi_ctx->frames[2].avf : mi_ctx->frames[1].avf); diff --git a/libavfilter/vf_overlay_cuda.c b/libavfilter/vf_overlay_cuda.c index 2f0f860e50..34241c8e1b 100644 --- a/libavfilter/vf_overlay_cuda.c +++ b/libavfilter/vf_overlay_cuda.c @@ -63,6 +63,7 @@ typedef struct OverlayCUDAContext { enum AVPixelFormat in_format_overlay; enum AVPixelFormat in_format_main; + AVBufferRef *hw_device_ctx; AVCUDADeviceContext *hwctx; CUcontext cu_ctx; @@ -157,9 +158,12 @@ static int overlay_cuda_blend(FFFrameSync *fs) if (ret < 0) return ret; - if (!input_main || !input_overlay) + if (!input_main) return AVERROR_BUG; + if (!input_overlay) + return ff_filter_frame(outlink, input_main); + ret = av_frame_make_writable(input_main); if (ret < 0) { av_frame_free(&input_main); @@ -253,6 +257,9 @@ static av_cold void overlay_cuda_uninit(AVFilterContext *avctx) CHECK_CU(cu->cuModuleUnload(ctx->cu_module)); CHECK_CU(cu->cuCtxPopCurrent(&dummy)); } + + av_buffer_unref(&ctx->hw_device_ctx); + ctx->hwctx = NULL; } /** @@ -338,13 +345,19 @@ static int overlay_cuda_config_output(AVFilterLink *outlink) // initialize - ctx->hwctx = frames_ctx->device_ctx->hwctx; + ctx->hw_device_ctx = av_buffer_ref(frames_ctx->device_ref); + if (!ctx->hw_device_ctx) + return AVERROR(ENOMEM); + ctx->hwctx = ((AVHWDeviceContext*)ctx->hw_device_ctx->data)->hwctx; + cuda_ctx = ctx->hwctx->cuda_ctx; ctx->fs.time_base = inlink->time_base; ctx->cu_stream = ctx->hwctx->stream; outlink->hw_frames_ctx = av_buffer_ref(inlink->hw_frames_ctx); + if (!outlink->hw_frames_ctx) + return AVERROR(ENOMEM); // load functions diff --git a/libavfilter/vf_paletteuse.c b/libavfilter/vf_paletteuse.c index fc07c2581d..f4c7d60435 100644 --- a/libavfilter/vf_paletteuse.c +++ b/libavfilter/vf_paletteuse.c @@ -152,9 +152,10 @@ static int query_formats(AVFilterContext *ctx) return 0; } -static av_always_inline int dither_color(uint32_t px, int er, int eg, int eb, int scale, int shift) +static av_always_inline uint32_t dither_color(uint32_t px, int er, int eg, + int eb, int scale, int shift) { - return av_clip_uint8( px >> 24 ) << 24 + return px >> 24 << 24 | av_clip_uint8((px >> 16 & 0xff) + ((er * scale) / (1<> 8 & 0xff) + ((eg * scale) / (1<draw, inlink->format, 0); + ret = ff_draw_init(&rot->draw, inlink->format, 0); + if (ret < 0) + return ret; ff_draw_color(&rot->draw, &rot->color, rot->fillcolor); rot->hsub = pixdesc->log2_chroma_w; diff --git a/libavfilter/vf_scale.c b/libavfilter/vf_scale.c index 58eee96744..ba50fbf492 100644 --- a/libavfilter/vf_scale.c +++ b/libavfilter/vf_scale.c @@ -493,18 +493,21 @@ static int config_props(AVFilterLink *outlink) if ((ret = scale_eval_dimensions(ctx)) < 0) goto fail; - ff_scale_adjust_dimensions(inlink, &scale->w, &scale->h, + outlink->w = scale->w; + outlink->h = scale->h; + + ret = ff_scale_adjust_dimensions(inlink, &outlink->w, &outlink->h, scale->force_original_aspect_ratio, scale->force_divisible_by); - if (scale->w > INT_MAX || - scale->h > INT_MAX || - (scale->h * inlink->w) > INT_MAX || - (scale->w * inlink->h) > INT_MAX) - av_log(ctx, AV_LOG_ERROR, "Rescaled value for width or height is too big.\n"); + if (ret < 0) + goto fail; - outlink->w = scale->w; - outlink->h = scale->h; + if (outlink->w > INT_MAX || + outlink->h > INT_MAX || + (outlink->h * inlink->w) > INT_MAX || + (outlink->w * inlink->h) > INT_MAX) + av_log(ctx, AV_LOG_ERROR, "Rescaled value for width or height is too big.\n"); /* TODO: make algorithm configurable */ @@ -635,8 +638,8 @@ static int scale_slice(AVFilterLink *link, AVFrame *out_buf, AVFrame *cur_pic, s int vsub= ((i+1)&2) ? scale->vsub : 0; in_stride[i] = cur_pic->linesize[i] * mul; out_stride[i] = out_buf->linesize[i] * mul; - in[i] = cur_pic->data[i] + ((y>>vsub)+field) * cur_pic->linesize[i]; - out[i] = out_buf->data[i] + field * out_buf->linesize[i]; + in[i] = FF_PTR_ADD(cur_pic->data[i], ((y>>vsub)+field) * cur_pic->linesize[i]); + out[i] = FF_PTR_ADD(out_buf->data[i], field * out_buf->linesize[i]); } if (scale->input_is_pal) in[1] = cur_pic->data[1]; @@ -684,9 +687,9 @@ static int scale_frame(AVFilterLink *link, AVFrame *in, AVFrame **frame_out) goto scale; if (scale->eval_mode == EVAL_MODE_INIT) { - snprintf(buf, sizeof(buf)-1, "%d", outlink->w); + snprintf(buf, sizeof(buf) - 1, "%d", scale->w); av_opt_set(scale, "w", buf, 0); - snprintf(buf, sizeof(buf)-1, "%d", outlink->h); + snprintf(buf, sizeof(buf) - 1, "%d", scale->h); av_opt_set(scale, "h", buf, 0); ret = scale_parse_expr(ctx, NULL, &scale->w_pexpr, "width", scale->w_expr); @@ -739,6 +742,18 @@ scale: out->width = outlink->w; out->height = outlink->h; + // Sanity checks: + // 1. If the output is RGB, set the matrix coefficients to RGB. + // 2. If the output is not RGB and we've got the RGB/XYZ (identity) + // matrix configured, unset the matrix. + // In theory these should be in swscale itself as the AVFrame + // based API gets in, so that not every swscale API user has + // to go through duplicating such sanity checks. + if (av_pix_fmt_desc_get(out->format)->flags & AV_PIX_FMT_FLAG_RGB) + out->colorspace = AVCOL_SPC_RGB; + else if (out->colorspace == AVCOL_SPC_RGB) + out->colorspace = AVCOL_SPC_UNSPECIFIED; + if (scale->output_is_pal) avpriv_set_systematic_pal2((uint32_t*)out->data[1], outlink->format == AV_PIX_FMT_PAL8 ? AV_PIX_FMT_BGR8 : outlink->format); diff --git a/libavfilter/vf_scale_npp.c b/libavfilter/vf_scale_npp.c index 502ecfda94..34debc3135 100644 --- a/libavfilter/vf_scale_npp.c +++ b/libavfilter/vf_scale_npp.c @@ -481,13 +481,16 @@ static int nppscale_scale(AVFilterContext *ctx, AVFrame *out, AVFrame *in) src = s->stages[i].frame; last_stage = i; } - if (last_stage < 0) return AVERROR_BUG; + ret = av_hwframe_get_buffer(src->hw_frames_ctx, s->tmp_frame, 0); if (ret < 0) return ret; + s->tmp_frame->width = src->width; + s->tmp_frame->height = src->height; + av_frame_move_ref(out, src); av_frame_move_ref(src, s->tmp_frame); diff --git a/libavfilter/vf_showinfo.c b/libavfilter/vf_showinfo.c index 6208892005..0b67cd7205 100644 --- a/libavfilter/vf_showinfo.c +++ b/libavfilter/vf_showinfo.c @@ -454,12 +454,15 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *frame) av_log(ctx, AV_LOG_INFO, " %08"PRIX32, plane_checksum[plane]); av_log(ctx, AV_LOG_INFO, "] mean:["); for (plane = 0; plane < 4 && frame->data[plane] && frame->linesize[plane]; plane++) - av_log(ctx, AV_LOG_INFO, "%"PRId64" ", (sum[plane] + pixelcount[plane]/2) / pixelcount[plane]); - av_log(ctx, AV_LOG_INFO, "\b] stdev:["); + av_log(ctx, AV_LOG_INFO, "%s%"PRId64, + plane ? " ":"", + (sum[plane] + pixelcount[plane]/2) / pixelcount[plane]); + av_log(ctx, AV_LOG_INFO, "] stdev:["); for (plane = 0; plane < 4 && frame->data[plane] && frame->linesize[plane]; plane++) - av_log(ctx, AV_LOG_INFO, "%3.1f ", + av_log(ctx, AV_LOG_INFO, "%s%3.1f", + plane ? " ":"", sqrt((sum2[plane] - sum[plane]*(double)sum[plane]/pixelcount[plane])/pixelcount[plane])); - av_log(ctx, AV_LOG_INFO, "\b]"); + av_log(ctx, AV_LOG_INFO, "]"); } av_log(ctx, AV_LOG_INFO, "\n"); diff --git a/libavfilter/vf_signature.c b/libavfilter/vf_signature.c index 32a6405e14..fc0ca92d37 100644 --- a/libavfilter/vf_signature.c +++ b/libavfilter/vf_signature.c @@ -224,7 +224,7 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *picref) dw1 = inlink->w / 32; if (inlink->w % 32) dw2 = dw1 + 1; - denom = (sc->divide) ? dh1 * dh2 * dw1 * dw2 : 1; + denom = (sc->divide) ? dh1 * (int64_t)dh2 * dw1 * dw2 : 1; for (i = 0; i < 32; i++) { rowcount = 0; @@ -250,7 +250,7 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *picref) } } - denom = (sc->divide) ? 1 : dh1 * dh2 * dw1 * dw2; + denom = (sc->divide) ? 1 : dh1 * (int64_t)dh2 * dw1 * dw2; for (i = 0; i < ELEMENT_COUNT; i++) { const ElemCat* elemcat = elements[i]; @@ -391,6 +391,9 @@ static int xml_export(AVFilterContext *ctx, StreamContext *sc, const char* filen FILE* f; unsigned int pot3[5] = { 3*3*3*3, 3*3*3, 3*3, 3, 1 }; + if (!sc->coarseend->last) + return AVERROR(EINVAL); // No frames ? + f = fopen(filename, "w"); if (!f) { int err = AVERROR(EINVAL); diff --git a/libavfilter/vf_subtitles.c b/libavfilter/vf_subtitles.c index de74afa2b7..b57dd80b13 100644 --- a/libavfilter/vf_subtitles.c +++ b/libavfilter/vf_subtitles.c @@ -145,9 +145,16 @@ static int config_input(AVFilterLink *inlink) ff_draw_init(&ass->draw, inlink->format, ass->alpha ? FF_DRAW_PROCESS_ALPHA : 0); ass_set_frame_size (ass->renderer, inlink->w, inlink->h); - if (ass->original_w && ass->original_h) + if (ass->original_w && ass->original_h) { ass_set_aspect_ratio(ass->renderer, (double)inlink->w / inlink->h, (double)ass->original_w / ass->original_h); +#if LIBASS_VERSION > 0x01010000 + ass_set_storage_size(ass->renderer, ass->original_w, ass->original_h); + } else { + ass_set_storage_size(ass->renderer, inlink->w, inlink->h); +#endif + } + if (ass->shaping != -1) ass_set_shaper(ass->renderer, ass->shaping); diff --git a/libavfilter/vf_swaprect.c b/libavfilter/vf_swaprect.c index 66bed161f4..9a96b0b9cb 100644 --- a/libavfilter/vf_swaprect.c +++ b/libavfilter/vf_swaprect.c @@ -18,6 +18,7 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ +#include "libavutil/avassert.h" #include "libavutil/avstring.h" #include "libavutil/eval.h" #include "libavutil/imgutils.h" @@ -146,10 +147,10 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *in) w = dw; h = dh; x1[0] = dx1; y1[0] = dy1; x2[0] = dx2; y2[0] = dy2; x1[0] = av_clip(x1[0], 0, inlink->w - 1); - y1[0] = av_clip(y1[0], 0, inlink->w - 1); + y1[0] = av_clip(y1[0], 0, inlink->h - 1); x2[0] = av_clip(x2[0], 0, inlink->w - 1); - y2[0] = av_clip(y2[0], 0, inlink->w - 1); + y2[0] = av_clip(y2[0], 0, inlink->h - 1); ah[1] = ah[2] = AV_CEIL_RSHIFT(h, s->desc->log2_chroma_h); ah[0] = ah[3] = h; @@ -169,16 +170,20 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *in) lw[1] = lw[2] = AV_CEIL_RSHIFT(inlink->w, s->desc->log2_chroma_w); lw[0] = lw[3] = inlink->w; - x1[1] = x1[2] = AV_CEIL_RSHIFT(x1[0], s->desc->log2_chroma_w); + x1[1] = x1[2] = (x1[0] >> s->desc->log2_chroma_w); x1[0] = x1[3] = x1[0]; - y1[1] = y1[2] = AV_CEIL_RSHIFT(y1[0], s->desc->log2_chroma_h); + y1[1] = y1[2] = (y1[0] >> s->desc->log2_chroma_h); y1[0] = y1[3] = y1[0]; - x2[1] = x2[2] = AV_CEIL_RSHIFT(x2[0], s->desc->log2_chroma_w); + x2[1] = x2[2] = (x2[0] >> s->desc->log2_chroma_w); x2[0] = x2[3] = x2[0]; - y2[1] = y2[2] = AV_CEIL_RSHIFT(y2[0], s->desc->log2_chroma_h); + y2[1] = y2[2] = (y2[0] >> s->desc->log2_chroma_h); y2[0] = y2[3] = y2[0]; + + av_assert0(FFMAX(x1[1], x2[1]) + pw[1] <= lw[1]); + av_assert0(FFMAX(y1[1], y2[1]) + ph[1] <= lh[1]); + for (p = 0; p < s->nb_planes; p++) { if (ph[p] == ah[p] && pw[p] == aw[p]) { uint8_t *src = in->data[p] + y1[p] * in->linesize[p] + x1[p] * s->pixsteps[p]; diff --git a/libavfilter/vf_thumbnail_cuda.c b/libavfilter/vf_thumbnail_cuda.c index 0c06815643..de61afd1f5 100644 --- a/libavfilter/vf_thumbnail_cuda.c +++ b/libavfilter/vf_thumbnail_cuda.c @@ -288,7 +288,7 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *frame) hist[i] = 4 * hist[i]; } - CHECK_CU(cu->cuCtxPopCurrent(&dummy)); + ret = CHECK_CU(cu->cuCtxPopCurrent(&dummy)); if (ret < 0) return ret; diff --git a/libavfilter/vf_tonemap_opencl.c b/libavfilter/vf_tonemap_opencl.c index 2681ebd1b5..090804aae4 100644 --- a/libavfilter/vf_tonemap_opencl.c +++ b/libavfilter/vf_tonemap_opencl.c @@ -345,8 +345,7 @@ static int tonemap_opencl_filter_frame(AVFilterLink *inlink, AVFrame *input) int err; double peak = ctx->peak; - AVHWFramesContext *input_frames_ctx = - (AVHWFramesContext*)input->hw_frames_ctx->data; + AVHWFramesContext *input_frames_ctx; av_log(ctx, AV_LOG_DEBUG, "Filter input: %s, %ux%u (%"PRId64").\n", av_get_pix_fmt_name(input->format), @@ -354,6 +353,7 @@ static int tonemap_opencl_filter_frame(AVFilterLink *inlink, AVFrame *input) if (!input->hw_frames_ctx) return AVERROR(EINVAL); + input_frames_ctx = (AVHWFramesContext*)input->hw_frames_ctx->data; output = ff_get_video_buffer(outlink, outlink->w, outlink->h); if (!output) { diff --git a/libavfilter/vf_untile.c b/libavfilter/vf_untile.c index 9a2eb24901..df805141e0 100644 --- a/libavfilter/vf_untile.c +++ b/libavfilter/vf_untile.c @@ -139,8 +139,8 @@ static int activate(AVFilterContext *ctx) if (!(s->desc->flags & AV_PIX_FMT_FLAG_PAL || s->desc->flags & FF_PSEUDOPAL)) { for (i = 1; i < 3; i ++) { if (out->data[i]) { - out->data[i] += (y >> s->desc->log2_chroma_w) * out->linesize[i]; - out->data[i] += (x >> s->desc->log2_chroma_h) * s->max_step[i]; + out->data[i] += (y >> s->desc->log2_chroma_h) * out->linesize[i]; + out->data[i] += (x >> s->desc->log2_chroma_w) * s->max_step[i]; } } } diff --git a/libavfilter/vf_v360.c b/libavfilter/vf_v360.c index 94473cd5b3..9875d0457a 100644 --- a/libavfilter/vf_v360.c +++ b/libavfilter/vf_v360.c @@ -3637,6 +3637,8 @@ static int barrelsplit_to_xyz(const V360Context *s, l_y = 0.5f; l_z = (-0.5f + vf) / scaleh; break; + default: + av_assert0(0); } } @@ -4102,8 +4104,8 @@ static av_always_inline int v360_slice(AVFilterContext *ctx, void *arg, int jobn int16_t *u = r->u[p] + ((j - slice_start) * uv_linesize + i) * elements; int16_t *v = r->v[p] + ((j - slice_start) * uv_linesize + i) * elements; int16_t *ker = r->ker[p] + ((j - slice_start) * uv_linesize + i) * elements; - uint8_t *mask8 = p ? NULL : r->mask + ((j - slice_start) * s->pr_width[0] + i); - uint16_t *mask16 = p ? NULL : (uint16_t *)r->mask + ((j - slice_start) * s->pr_width[0] + i); + uint8_t *mask8 = (p || !r->mask) ? NULL : r->mask + ((j - slice_start) * s->pr_width[0] + i); + uint16_t *mask16 = (p || !r->mask) ? NULL : (uint16_t *)r->mask + ((j - slice_start) * s->pr_width[0] + i); int in_mask, out_mask; if (s->out_transpose) diff --git a/libavfilter/vf_vidstabdetect.c b/libavfilter/vf_vidstabdetect.c index fd7ff3be24..7b4ba3df17 100644 --- a/libavfilter/vf_vidstabdetect.c +++ b/libavfilter/vf_vidstabdetect.c @@ -176,7 +176,7 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *in) } if (vsMotionDetection(md, &localmotions, &frame) != VS_OK) { av_log(ctx, AV_LOG_ERROR, "motion detection failed"); - return AVERROR(AVERROR_EXTERNAL); + return AVERROR_EXTERNAL; } else { if (vsWriteToFile(md, s->f, &localmotions) != VS_OK) { int ret = AVERROR(errno); diff --git a/libavfilter/vf_vmafmotion.c b/libavfilter/vf_vmafmotion.c index 88d0b35095..0730147e7d 100644 --- a/libavfilter/vf_vmafmotion.c +++ b/libavfilter/vf_vmafmotion.c @@ -238,6 +238,9 @@ int ff_vmafmotion_init(VMAFMotionData *s, int i; const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(fmt); + if (w < 3 || h < 3) + return AVERROR(EINVAL); + s->width = w; s->height = h; s->stride = FFALIGN(w * sizeof(uint16_t), 32); diff --git a/libavfilter/vf_w3fdif.c b/libavfilter/vf_w3fdif.c index 1a64b2b953..d380fdd4de 100644 --- a/libavfilter/vf_w3fdif.c +++ b/libavfilter/vf_w3fdif.c @@ -283,7 +283,7 @@ static int config_input(AVFilterLink *inlink) AVFilterContext *ctx = inlink->dst; W3FDIFContext *s = ctx->priv; const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(inlink->format); - int ret, i, depth; + int ret, i, depth, nb_threads; if ((ret = av_image_fill_linesizes(s->linesize, inlink->format, inlink->w)) < 0) return ret; @@ -297,10 +297,11 @@ static int config_input(AVFilterLink *inlink) } s->nb_planes = av_pix_fmt_count_planes(inlink->format); - s->nb_threads = ff_filter_get_nb_threads(ctx); - s->work_line = av_calloc(s->nb_threads, sizeof(*s->work_line)); + nb_threads = ff_filter_get_nb_threads(ctx); + s->work_line = av_calloc(nb_threads, sizeof(*s->work_line)); if (!s->work_line) return AVERROR(ENOMEM); + s->nb_threads = nb_threads; for (i = 0; i < s->nb_threads; i++) { s->work_line[i] = av_calloc(FFALIGN(s->linesize[0], 32), sizeof(*s->work_line[0])); diff --git a/libavfilter/vf_weave.c b/libavfilter/vf_weave.c index 6139844b20..a45d650f67 100644 --- a/libavfilter/vf_weave.c +++ b/libavfilter/vf_weave.c @@ -30,6 +30,7 @@ typedef struct WeaveContext { int double_weave; int nb_planes; int planeheight[4]; + int outheight[4]; int linesize[4]; AVFrame *prev; @@ -85,6 +86,9 @@ static int config_props_output(AVFilterLink *outlink) s->planeheight[1] = s->planeheight[2] = AV_CEIL_RSHIFT(inlink->h, desc->log2_chroma_h); s->planeheight[0] = s->planeheight[3] = inlink->h; + s->outheight[1] = s->outheight[2] = AV_CEIL_RSHIFT(2*inlink->h, desc->log2_chroma_h); + s->outheight[0] = s->outheight[3] = 2*inlink->h; + s->nb_planes = av_pix_fmt_count_planes(inlink->format); return 0; @@ -110,19 +114,20 @@ static int weave_slice(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs) const int height = s->planeheight[i]; const int start = (height * jobnr) / nb_jobs; const int end = (height * (jobnr+1)) / nb_jobs; + const int compensation = 2*end > s->outheight[i]; av_image_copy_plane(out->data[i] + out->linesize[i] * field1 + out->linesize[i] * start * 2, out->linesize[i] * 2, in->data[i] + start * in->linesize[i], in->linesize[i], - s->linesize[i], end - start); + s->linesize[i], end - start - compensation * field1); av_image_copy_plane(out->data[i] + out->linesize[i] * field2 + out->linesize[i] * start * 2, out->linesize[i] * 2, s->prev->data[i] + start * s->prev->linesize[i], s->prev->linesize[i], - s->linesize[i], end - start); + s->linesize[i], end - start - compensation * field2); } return 0; diff --git a/libavfilter/vf_xfade.c b/libavfilter/vf_xfade.c index cb4fae21d9..35869aff12 100644 --- a/libavfilter/vf_xfade.c +++ b/libavfilter/vf_xfade.c @@ -916,7 +916,7 @@ static void vertopen##name##_transition(AVFilterContext *ctx, { \ XFadeContext *s = ctx->priv; \ const int width = out->width; \ - const float w2 = out->width / 2; \ + const float w2 = out->width / 2.0; \ \ for (int y = slice_start; y < slice_end; y++) { \ for (int x = 0; x < width; x++) { \ @@ -943,7 +943,7 @@ static void vertclose##name##_transition(AVFilterContext *ctx, { \ XFadeContext *s = ctx->priv; \ const int width = out->width; \ - const float w2 = out->width / 2; \ + const float w2 = out->width / 2.0; \ \ for (int y = slice_start; y < slice_end; y++) { \ for (int x = 0; x < width; x++) { \ @@ -970,7 +970,7 @@ static void horzopen##name##_transition(AVFilterContext *ctx, { \ XFadeContext *s = ctx->priv; \ const int width = out->width; \ - const float h2 = out->height / 2; \ + const float h2 = out->height / 2.0; \ \ for (int y = slice_start; y < slice_end; y++) { \ const float smooth = 2.f - fabsf((y - h2) / h2) - progress * 2.f; \ @@ -997,7 +997,7 @@ static void horzclose##name##_transition(AVFilterContext *ctx, { \ XFadeContext *s = ctx->priv; \ const int width = out->width; \ - const float h2 = out->height / 2; \ + const float h2 = out->height / 2.0; \ \ for (int y = slice_start; y < slice_end; y++) { \ const float smooth = 1.f + fabsf((y - h2) / h2) - progress * 2.f; \ diff --git a/libavfilter/vf_xfade_opencl.c b/libavfilter/vf_xfade_opencl.c index 4736043147..12221c9081 100644 --- a/libavfilter/vf_xfade_opencl.c +++ b/libavfilter/vf_xfade_opencl.c @@ -294,7 +294,9 @@ static int xfade_opencl_activate(AVFilterContext *avctx) if (ctx->first_pts + ctx->offset_pts > ctx->xf[0]->pts) { ctx->xf[0] = NULL; ctx->need_second = 0; - ff_inlink_consume_frame(avctx->inputs[0], &in); + ret = ff_inlink_consume_frame(avctx->inputs[0], &in); + if (ret < 0) + return ret; return ff_filter_frame(outlink, in); } @@ -303,8 +305,14 @@ static int xfade_opencl_activate(AVFilterContext *avctx) } if (ctx->xf[0] && ff_inlink_queued_frames(avctx->inputs[1]) > 0) { - ff_inlink_consume_frame(avctx->inputs[0], &ctx->xf[0]); - ff_inlink_consume_frame(avctx->inputs[1], &ctx->xf[1]); + ret = ff_inlink_consume_frame(avctx->inputs[0], &ctx->xf[0]); + if (ret < 0) + return ret; + ret = ff_inlink_consume_frame(avctx->inputs[1], &ctx->xf[1]); + if (ret < 0) { + av_frame_free(&ctx->xf[0]); + return ret; + } ctx->last_pts = ctx->xf[1]->pts; ctx->pts = ctx->xf[0]->pts; diff --git a/libavfilter/vf_yadif.c b/libavfilter/vf_yadif.c index 43dea67add..06fd24ecfa 100644 --- a/libavfilter/vf_yadif.c +++ b/libavfilter/vf_yadif.c @@ -123,20 +123,22 @@ static void filter_edges(void *dst1, void *prev1, void *cur1, void *next1, uint8_t *next2 = parity ? cur : next; const int edge = MAX_ALIGN - 1; + int offset = FFMAX(w - edge, 3); /* Only edge pixels need to be processed here. A constant value of false * for is_not_edge should let the compiler ignore the whole branch. */ - FILTER(0, 3, 0) + FILTER(0, FFMIN(3, w), 0) - dst = (uint8_t*)dst1 + w - edge; - prev = (uint8_t*)prev1 + w - edge; - cur = (uint8_t*)cur1 + w - edge; - next = (uint8_t*)next1 + w - edge; + dst = (uint8_t*)dst1 + offset; + prev = (uint8_t*)prev1 + offset; + cur = (uint8_t*)cur1 + offset; + next = (uint8_t*)next1 + offset; prev2 = (uint8_t*)(parity ? prev : cur); next2 = (uint8_t*)(parity ? cur : next); - FILTER(w - edge, w - 3, 1) - FILTER(w - 3, w, 0) + FILTER(offset, w - 3, 1) + offset = FFMAX(offset, w - 3); + FILTER(offset, w, 0) } @@ -170,21 +172,23 @@ static void filter_edges_16bit(void *dst1, void *prev1, void *cur1, void *next1, uint16_t *next2 = parity ? cur : next; const int edge = MAX_ALIGN / 2 - 1; + int offset = FFMAX(w - edge, 3); mrefs /= 2; prefs /= 2; - FILTER(0, 3, 0) + FILTER(0, FFMIN(3, w), 0) - dst = (uint16_t*)dst1 + w - edge; - prev = (uint16_t*)prev1 + w - edge; - cur = (uint16_t*)cur1 + w - edge; - next = (uint16_t*)next1 + w - edge; + dst = (uint16_t*)dst1 + offset; + prev = (uint16_t*)prev1 + offset; + cur = (uint16_t*)cur1 + offset; + next = (uint16_t*)next1 + offset; prev2 = (uint16_t*)(parity ? prev : cur); next2 = (uint16_t*)(parity ? cur : next); - FILTER(w - edge, w - 3, 1) - FILTER(w - 3, w, 0) + FILTER(offset, w - 3, 1) + offset = FFMAX(offset, w - 3); + FILTER(offset, w, 0) } static int filter_slice(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs) diff --git a/libavfilter/video.c b/libavfilter/video.c index 7a8e587798..b049804419 100644 --- a/libavfilter/video.c +++ b/libavfilter/video.c @@ -41,7 +41,7 @@ AVFrame *ff_null_get_video_buffer(AVFilterLink *link, int w, int h) return ff_get_video_buffer(link->dst->outputs[0], w, h); } -AVFrame *ff_default_get_video_buffer(AVFilterLink *link, int w, int h) +AVFrame *ff_default_get_video_buffer2(AVFilterLink *link, int w, int h, int align) { AVFrame *frame = NULL; int pool_width = 0; @@ -96,6 +96,11 @@ AVFrame *ff_default_get_video_buffer(AVFilterLink *link, int w, int h) return frame; } +AVFrame *ff_default_get_video_buffer(AVFilterLink *link, int w, int h) +{ + return ff_default_get_video_buffer2(link, w, h, av_cpu_max_align()); +} + AVFrame *ff_get_video_buffer(AVFilterLink *link, int w, int h) { AVFrame *ret = NULL; diff --git a/libavfilter/video.h b/libavfilter/video.h index 56c58d6766..f9174a4a0b 100644 --- a/libavfilter/video.h +++ b/libavfilter/video.h @@ -24,6 +24,7 @@ #include "avfilter.h" AVFrame *ff_default_get_video_buffer(AVFilterLink *link, int w, int h); +AVFrame *ff_default_get_video_buffer2(AVFilterLink *link, int w, int h, int align); AVFrame *ff_null_get_video_buffer(AVFilterLink *link, int w, int h); /** diff --git a/libavfilter/vsrc_mandelbrot.c b/libavfilter/vsrc_mandelbrot.c index 761c915103..ed31a23c31 100644 --- a/libavfilter/vsrc_mandelbrot.c +++ b/libavfilter/vsrc_mandelbrot.c @@ -134,6 +134,9 @@ static av_cold int init(AVFilterContext *ctx) s-> next_cache= av_malloc_array(s->cache_allocated, sizeof(*s-> next_cache)); s-> zyklus = av_malloc_array(s->maxiter + 16, sizeof(*s->zyklus)); + if (!s->point_cache || !s->next_cache || !s->zyklus) + return AVERROR(ENOMEM); + return 0; } diff --git a/libavformat/4xm.c b/libavformat/4xm.c index 30f1b05324..cfee8a02f4 100644 --- a/libavformat/4xm.c +++ b/libavformat/4xm.c @@ -137,7 +137,8 @@ static int parse_strk(AVFormatContext *s, return AVERROR_INVALIDDATA; track = AV_RL32(buf + 8); - if ((unsigned)track >= UINT_MAX / sizeof(AudioTrack) - 1) { + if ((unsigned)track >= UINT_MAX / sizeof(AudioTrack) - 1 || + track >= s->max_streams) { av_log(s, AV_LOG_ERROR, "current_track too large\n"); return AVERROR_INVALIDDATA; } @@ -148,6 +149,9 @@ static int parse_strk(AVFormatContext *s, memset(&fourxm->tracks[fourxm->track_count], 0, sizeof(AudioTrack) * (track + 1 - fourxm->track_count)); fourxm->track_count = track + 1; + } else { + if (fourxm->tracks[track].bits) + return AVERROR_INVALIDDATA; } fourxm->tracks[track].adpcm = AV_RL32(buf + 12); fourxm->tracks[track].channels = AV_RL32(buf + 36); diff --git a/libavformat/aadec.c b/libavformat/aadec.c index 80ca2c12d7..90796c9599 100644 --- a/libavformat/aadec.c +++ b/libavformat/aadec.c @@ -130,8 +130,8 @@ static int aa_read_header(AVFormatContext *s) AV_WB32(&header_key[idx * 4], header_key_part[idx]); // convert each part to BE! } av_log(s, AV_LOG_DEBUG, "Processed HeaderKey is "); - for (i = 0; i < 16; i++) - av_log(s, AV_LOG_DEBUG, "%02x", header_key[i]); + for (int j = 0; j < 16; j++) + av_log(s, AV_LOG_DEBUG, "%02x", header_key[j]); av_log(s, AV_LOG_DEBUG, "\n"); } else { av_dict_set(&s->metadata, key, val, 0); @@ -229,8 +229,11 @@ static int aa_read_header(AVFormatContext *s) chapter_pos -= start + CHAPTER_HEADER_SIZE * chapter_idx; avio_skip(pb, 4 + chapter_size); if (!avpriv_new_chapter(s, chapter_idx, st->time_base, - chapter_pos * TIMEPREC, (chapter_pos + chapter_size) * TIMEPREC, NULL)) - return AVERROR(ENOMEM); + chapter_pos * TIMEPREC, + (chapter_pos + chapter_size) * TIMEPREC, NULL)) { + av_freep(&c->tea_ctx); + return AVERROR(ENOMEM); + } } st->duration = (largest_size - CHAPTER_HEADER_SIZE * s->nb_chapters) * TIMEPREC; diff --git a/libavformat/aaxdec.c b/libavformat/aaxdec.c index c6d2d1c8d1..ad893efadd 100644 --- a/libavformat/aaxdec.c +++ b/libavformat/aaxdec.c @@ -117,6 +117,7 @@ static int aax_read_header(AVFormatContext *s) int64_t column_offset = 0; int ret, extradata_size; char *codec; + int64_t ret64; avio_skip(pb, 4); a->table_size = avio_rb32(pb) + 8LL; @@ -218,7 +219,10 @@ static int aax_read_header(AVFormatContext *s) } } - avio_seek(pb, a->strings_offset, SEEK_SET); + ret = ret64 = avio_seek(pb, a->strings_offset, SEEK_SET); + if (ret64 < 0) + goto fail; + ret = avio_read(pb, a->string_table, a->strings_size); if (ret != a->strings_size) { if (ret < 0) @@ -249,12 +253,17 @@ static int aax_read_header(AVFormatContext *s) goto fail; } - avio_seek(pb, data_offset, SEEK_SET); + ret = ret64 = avio_seek(pb, data_offset, SEEK_SET); + if (ret64 < 0) + goto fail; + if (type == COLUMN_TYPE_VLDATA) { int64_t start, size; start = avio_rb32(pb); size = avio_rb32(pb); + if (!size) + return AVERROR_INVALIDDATA; a->segments[r].start = start + a->data_offset; a->segments[r].end = a->segments[r].start + size; } else { @@ -281,8 +290,8 @@ static int aax_read_header(AVFormatContext *s) codec = a->string_table + a->name_offset; if (!strcmp(codec, "AAX")) { par->codec_id = AV_CODEC_ID_ADPCM_ADX; - avio_seek(pb, a->segments[0].start, SEEK_SET); - if (avio_rb16(pb) != 0x8000) { + ret64 = avio_seek(pb, a->segments[0].start, SEEK_SET); + if (ret64 < 0 || avio_rb16(pb) != 0x8000) { ret = AVERROR_INVALIDDATA; goto fail; } diff --git a/libavformat/act.c b/libavformat/act.c index 26425ca1bb..f6edfb44ab 100644 --- a/libavformat/act.c +++ b/libavformat/act.c @@ -66,6 +66,7 @@ static int read_header(AVFormatContext *s) AVIOContext *pb = s->pb; int size; AVStream* st; + int ret; int min,sec,msec; @@ -75,7 +76,9 @@ static int read_header(AVFormatContext *s) avio_skip(pb, 16); size=avio_rl32(pb); - ff_get_wav_header(s, pb, st->codecpar, size, 0); + ret = ff_get_wav_header(s, pb, st->codecpar, size, 0); + if (ret < 0) + return ret; /* 8000Hz (Fine-rec) file format has 10 bytes long diff --git a/libavformat/adtsenc.c b/libavformat/adtsenc.c index 3595cb3bb2..c35a12a628 100644 --- a/libavformat/adtsenc.c +++ b/libavformat/adtsenc.c @@ -51,9 +51,11 @@ static int adts_decode_extradata(AVFormatContext *s, ADTSContext *adts, const ui GetBitContext gb; PutBitContext pb; MPEG4AudioConfig m4ac; - int off; + int off, ret; - init_get_bits(&gb, buf, size * 8); + ret = init_get_bits8(&gb, buf, size); + if (ret < 0) + return ret; off = avpriv_mpeg4audio_get_config2(&m4ac, buf, size, 1, s); if (off < 0) return off; diff --git a/libavformat/aiffdec.c b/libavformat/aiffdec.c index dcaf1560b6..f14044d61c 100644 --- a/libavformat/aiffdec.c +++ b/libavformat/aiffdec.c @@ -53,9 +53,9 @@ static enum AVCodecID aiff_codec_get_id(int bps) } /* returns the size of the found tag */ -static int get_tag(AVIOContext *pb, uint32_t * tag) +static int64_t get_tag(AVIOContext *pb, uint32_t * tag) { - int size; + int64_t size; if (avio_feof(pb)) return AVERROR(EIO); @@ -63,16 +63,16 @@ static int get_tag(AVIOContext *pb, uint32_t * tag) *tag = avio_rl32(pb); size = avio_rb32(pb); - if (size < 0) - size = 0x7fffffff; - return size; } /* Metadata string read */ -static void get_meta(AVFormatContext *s, const char *key, int size) +static void get_meta(AVFormatContext *s, const char *key, int64_t size) { - uint8_t *str = av_malloc(size+1); + uint8_t *str = NULL; + + if (size < SIZE_MAX) + str = av_malloc(size+1); if (str) { int res = avio_read(s->pb, str, size); @@ -89,7 +89,7 @@ static void get_meta(AVFormatContext *s, const char *key, int size) } /* Returns the number of sound data frames or negative on error */ -static int get_aiff_header(AVFormatContext *s, int size, +static int get_aiff_header(AVFormatContext *s, int64_t size, unsigned version) { AVIOContext *pb = s->pb; @@ -117,6 +117,9 @@ static int get_aiff_header(AVFormatContext *s, int size, sample_rate = val << exp; else sample_rate = (val + (1ULL<<(-exp-1))) >> -exp; + if (sample_rate <= 0) + return AVERROR_INVALIDDATA; + par->sample_rate = sample_rate; if (size < 18) return AVERROR_INVALIDDATA; @@ -179,8 +182,10 @@ static int get_aiff_header(AVFormatContext *s, int size, par->block_align = (av_get_bits_per_sample(par->codec_id) * par->channels) >> 3; if (aiff->block_duration) { - par->bit_rate = (int64_t)par->sample_rate * (par->block_align << 3) / - aiff->block_duration; + par->bit_rate = av_rescale(par->sample_rate, par->block_align * 8LL, + aiff->block_duration); + if (par->bit_rate < 0) + par->bit_rate = 0; } /* Chunk is over */ @@ -205,7 +210,8 @@ static int aiff_probe(const AVProbeData *p) /* aiff input */ static int aiff_read_header(AVFormatContext *s) { - int ret, size, filesize; + int ret; + int64_t filesize, size; int64_t offset = 0, position; uint32_t tag; unsigned version = AIFF_C_VERSION1; @@ -216,7 +222,7 @@ static int aiff_read_header(AVFormatContext *s) /* check FORM header */ filesize = get_tag(pb, &tag); - if (filesize < 0 || tag != MKTAG('F', 'O', 'R', 'M')) + if (filesize < 4 || tag != MKTAG('F', 'O', 'R', 'M')) return AVERROR_INVALIDDATA; /* AIFF data type */ @@ -243,10 +249,7 @@ static int aiff_read_header(AVFormatContext *s) if (size < 0) return size; - if (size >= 0x7fffffff - 8) - filesize = 0; - else - filesize -= size + 8; + filesize -= size + 8; switch (tag) { case MKTAG('C', 'O', 'M', 'M'): /* Common chunk */ @@ -362,10 +365,12 @@ got_sound: if (!st->codecpar->block_align && st->codecpar->codec_id == AV_CODEC_ID_QCELP) { av_log(s, AV_LOG_WARNING, "qcelp without wave chunk, assuming full rate\n"); st->codecpar->block_align = 35; - } else if (!st->codecpar->block_align) { + } else if (st->codecpar->block_align <= 0) { av_log(s, AV_LOG_ERROR, "could not find COMM tag or invalid block_align value\n"); return -1; } + if (aiff->block_duration < 0) + return AVERROR_INVALIDDATA; /* Now positioned, get the sound data start and end */ avpriv_set_pts_info(st, 64, 1, st->codecpar->sample_rate); @@ -420,7 +425,7 @@ static int aiff_read_packet(AVFormatContext *s, pkt->flags &= ~AV_PKT_FLAG_CORRUPT; /* Only one stream in an AIFF file */ pkt->stream_index = 0; - pkt->duration = (res / st->codecpar->block_align) * aiff->block_duration; + pkt->duration = (res / st->codecpar->block_align) * (int64_t) aiff->block_duration; return 0; } diff --git a/libavformat/alp.c b/libavformat/alp.c index f2b0c37730..222cc246a2 100644 --- a/libavformat/alp.c +++ b/libavformat/alp.c @@ -72,38 +72,39 @@ static int alp_read_header(AVFormatContext *s) { int ret; AVStream *st; - ALPHeader hdr; + ALPHeader *hdr = s->priv_data; AVCodecParameters *par; - if ((hdr.magic = avio_rl32(s->pb)) != ALP_TAG) + if ((hdr->magic = avio_rl32(s->pb)) != ALP_TAG) return AVERROR_INVALIDDATA; - hdr.header_size = avio_rl32(s->pb); + hdr->header_size = avio_rl32(s->pb); - if (hdr.header_size != 8 && hdr.header_size != 12) { + if (hdr->header_size != 8 && hdr->header_size != 12) { return AVERROR_INVALIDDATA; } - if ((ret = avio_read(s->pb, hdr.adpcm, sizeof(hdr.adpcm))) < 0) + if ((ret = avio_read(s->pb, hdr->adpcm, sizeof(hdr->adpcm))) < 0) return ret; - else if (ret != sizeof(hdr.adpcm)) + else if (ret != sizeof(hdr->adpcm)) return AVERROR(EIO); - if (strncmp("ADPCM", hdr.adpcm, sizeof(hdr.adpcm)) != 0) + if (strncmp("ADPCM", hdr->adpcm, sizeof(hdr->adpcm)) != 0) return AVERROR_INVALIDDATA; - hdr.unk1 = avio_r8(s->pb); - hdr.num_channels = avio_r8(s->pb); + hdr->unk1 = avio_r8(s->pb); + hdr->num_channels = avio_r8(s->pb); - if (hdr.header_size == 8) { + if (hdr->header_size == 8) { /* .TUN music file */ - hdr.sample_rate = 22050; + hdr->sample_rate = 22050; + } else { /* .PCM sound file */ - hdr.sample_rate = avio_rl32(s->pb); + hdr->sample_rate = avio_rl32(s->pb); } - if (hdr.sample_rate > 44100) { + if (hdr->sample_rate > 44100) { avpriv_request_sample(s, "Sample Rate > 44100"); return AVERROR_PATCHWELCOME; } @@ -115,12 +116,12 @@ static int alp_read_header(AVFormatContext *s) par->codec_type = AVMEDIA_TYPE_AUDIO; par->codec_id = AV_CODEC_ID_ADPCM_IMA_ALP; par->format = AV_SAMPLE_FMT_S16; - par->sample_rate = hdr.sample_rate; - par->channels = hdr.num_channels; + par->sample_rate = hdr->sample_rate; + par->channels = hdr->num_channels; - if (hdr.num_channels == 1) + if (hdr->num_channels == 1) par->channel_layout = AV_CH_LAYOUT_MONO; - else if (hdr.num_channels == 2) + else if (hdr->num_channels == 2) par->channel_layout = AV_CH_LAYOUT_STEREO; else return AVERROR_INVALIDDATA; @@ -151,12 +152,25 @@ static int alp_read_packet(AVFormatContext *s, AVPacket *pkt) return 0; } +static int alp_seek(AVFormatContext *s, int stream_index, + int64_t pts, int flags) +{ + const ALPHeader *hdr = s->priv_data; + + if (pts != 0) + return AVERROR(EINVAL); + + return avio_seek(s->pb, hdr->header_size + 8, SEEK_SET); +} + AVInputFormat ff_alp_demuxer = { .name = "alp", .long_name = NULL_IF_CONFIG_SMALL("LEGO Racers ALP"), + .priv_data_size = sizeof(ALPHeader), .read_probe = alp_probe, .read_header = alp_read_header, - .read_packet = alp_read_packet + .read_packet = alp_read_packet, + .read_seek = alp_seek, }; #endif diff --git a/libavformat/ape.c b/libavformat/ape.c index 4c161235fe..8a876d7fd9 100644 --- a/libavformat/ape.c +++ b/libavformat/ape.c @@ -42,8 +42,8 @@ typedef struct APEFrame { int64_t pos; + int64_t size; int nblocks; - int size; int skip; int64_t pts; } APEFrame; @@ -130,7 +130,7 @@ static void ape_dumpinfo(AVFormatContext * s, APEContext * ape_ctx) av_log(s, AV_LOG_DEBUG, "\nFrames\n\n"); for (i = 0; i < ape_ctx->totalframes; i++) - av_log(s, AV_LOG_DEBUG, "%8d %8"PRId64" %8d (%d samples)\n", i, + av_log(s, AV_LOG_DEBUG, "%8d %8"PRId64" %8"PRId64" (%d samples)\n", i, ape_ctx->frames[i].pos, ape_ctx->frames[i].size, ape_ctx->frames[i].nblocks); @@ -148,7 +148,8 @@ static int ape_read_header(AVFormatContext * s) AVStream *st; uint32_t tag; int i, ret; - int total_blocks, final_size = 0; + int total_blocks; + int64_t final_size = 0; int64_t pts, file_size; /* Skip any leading junk such as id3v2 tags */ @@ -292,7 +293,7 @@ static int ape_read_header(AVFormatContext * s) final_size -= final_size & 3; } if (file_size <= 0 || final_size <= 0) - final_size = ape->finalframeblocks * 8; + final_size = ape->finalframeblocks * 8LL; ape->frames[ape->totalframes - 1].size = final_size; for (i = 0; i < ape->totalframes; i++) { @@ -300,6 +301,8 @@ static int ape_read_header(AVFormatContext * s) ape->frames[i].pos -= ape->frames[i].skip; ape->frames[i].size += ape->frames[i].skip; } + if (ape->frames[i].size > INT_MAX - 3) + return AVERROR_INVALIDDATA; ape->frames[i].size = (ape->frames[i].size + 3) & ~3; } if (ape->fileversion < 3810) { @@ -397,7 +400,7 @@ static int ape_read_packet(AVFormatContext * s, AVPacket * pkt) if (ape->frames[ape->currentframe].size <= 0 || ape->frames[ape->currentframe].size > INT_MAX - extra_size) { - av_log(s, AV_LOG_ERROR, "invalid packet size: %d\n", + av_log(s, AV_LOG_ERROR, "invalid packet size: %8"PRId64"\n", ape->frames[ape->currentframe].size); ape->currentframe++; return AVERROR(EIO); @@ -444,7 +447,7 @@ static int ape_read_seek(AVFormatContext *s, int stream_index, int64_t timestamp if (index < 0) return -1; - if ((ret = avio_seek(s->pb, st->internal->index_entries[index].pos, SEEK_SET)) < 0) + if ((ret = avio_seek(s->pb, st->index_entries[index].pos, SEEK_SET)) < 0) return ret; ape->currentframe = index; return 0; diff --git a/libavformat/apetag.c b/libavformat/apetag.c index 454c6c688b..a7dfe45df1 100644 --- a/libavformat/apetag.c +++ b/libavformat/apetag.c @@ -129,7 +129,8 @@ int64_t ff_ape_parse_tag(AVFormatContext *s) avio_seek(pb, file_size - APE_TAG_FOOTER_BYTES, SEEK_SET); - avio_read(pb, buf, 8); /* APETAGEX */ + if(avio_read(pb, buf, 8) != 8) /* APETAGEX */ + return 0; if (strncmp(buf, APE_TAG_PREAMBLE, 8)) { return 0; } diff --git a/libavformat/aqtitledec.c b/libavformat/aqtitledec.c index 81630d73b0..960a5d8ef5 100644 --- a/libavformat/aqtitledec.c +++ b/libavformat/aqtitledec.c @@ -74,7 +74,8 @@ static int aqt_read_header(AVFormatContext *s) new_event = 1; pos = avio_tell(s->pb); if (sub) { - sub->duration = frame - sub->pts; + if (frame >= sub->pts && (uint64_t)frame - sub->pts < INT64_MAX) + sub->duration = frame - sub->pts; sub = NULL; } } else if (*line) { diff --git a/libavformat/argo_asf.c b/libavformat/argo_asf.c index 8e2bf21c71..e5da23a6bc 100644 --- a/libavformat/argo_asf.c +++ b/libavformat/argo_asf.c @@ -257,7 +257,7 @@ static int argo_asf_seek(AVFormatContext *s, int stream_index, return -1; offset = asf->fhdr.chunk_offset + ASF_CHUNK_HEADER_SIZE + - (block * st->codecpar->block_align); + block * (int64_t)st->codecpar->block_align; if ((offset = avio_seek(s->pb, offset, SEEK_SET)) < 0) return offset; @@ -422,7 +422,7 @@ static int argo_asf_write_trailer(AVFormatContext *s) ArgoASFMuxContext *ctx = s->priv_data; int64_t ret; - if ((ret = avio_seek(s->pb, ASF_FILE_HEADER_SIZE, SEEK_SET) < 0)) + if ((ret = avio_seek(s->pb, ASF_FILE_HEADER_SIZE, SEEK_SET)) < 0) return ret; avio_wl32(s->pb, (uint32_t)ctx->nb_blocks); diff --git a/libavformat/argo_brp.c b/libavformat/argo_brp.c index 6d6da851e9..c461400250 100644 --- a/libavformat/argo_brp.c +++ b/libavformat/argo_brp.c @@ -379,8 +379,8 @@ static int argo_brp_read_packet(AVFormatContext *s, AVPacket *pkt) if (blk.size < ASF_CHUNK_HEADER_SIZE) return AVERROR_INVALIDDATA; - if ((ret = avio_read(s->pb, buf, ASF_CHUNK_HEADER_SIZE)) < 0) - return ret; + if (avio_read(s->pb, buf, ASF_CHUNK_HEADER_SIZE) != ASF_CHUNK_HEADER_SIZE) + return AVERROR_INVALIDDATA; ff_argo_asf_parse_chunk_header(&ckhdr, buf); diff --git a/libavformat/asfdec_f.c b/libavformat/asfdec_f.c index 1484b544d9..f0b1639b21 100644 --- a/libavformat/asfdec_f.c +++ b/libavformat/asfdec_f.c @@ -104,7 +104,7 @@ typedef struct ASFContext { int ts_is_pts; int packet_multi_size; int packet_time_delta; - int packet_time_start; + int64_t packet_time_start; int64_t packet_pos; int stream_index; @@ -522,7 +522,7 @@ static int asf_read_stream_properties(AVFormatContext *s, int64_t size) tag1 = avio_rl32(pb); avio_skip(pb, 20); if (sizeX > 40) { - if (size < sizeX - 40) + if (size < sizeX - 40 || sizeX - 40 > INT_MAX - AV_INPUT_BUFFER_PADDING_SIZE) return AVERROR_INVALIDDATA; st->codecpar->extradata_size = ffio_limit(pb, sizeX - 40); st->codecpar->extradata = av_mallocz(st->codecpar->extradata_size + @@ -774,7 +774,7 @@ static int asf_read_marker(AVFormatContext *s, int64_t size) avio_rl64(pb); // offset, 8 bytes pres_time = avio_rl64(pb); // presentation time - pres_time -= asf->hdr.preroll * 10000; + pres_time = av_sat_sub64(pres_time, asf->hdr.preroll * 10000LL); avio_rl16(pb); // entry length avio_rl32(pb); // send time avio_rl32(pb); // flags @@ -1321,10 +1321,12 @@ static int asf_parse_packet(AVFormatContext *s, AVIOContext *pb, AVPacket *pkt) if ((ret = av_new_packet(&asf_st->pkt, asf_st->packet_obj_size)) < 0) return ret; asf_st->seq = asf->packet_seq; - if (asf->ts_is_pts) { - asf_st->pkt.pts = asf->packet_frag_timestamp - asf->hdr.preroll; - } else - asf_st->pkt.dts = asf->packet_frag_timestamp - asf->hdr.preroll; + if (asf->packet_frag_timestamp != AV_NOPTS_VALUE) { + if (asf->ts_is_pts) { + asf_st->pkt.pts = asf->packet_frag_timestamp - asf->hdr.preroll; + } else + asf_st->pkt.dts = asf->packet_frag_timestamp - asf->hdr.preroll; + } asf_st->pkt.stream_index = asf->stream_index; asf_st->pkt.pos = asf_st->packet_pos = asf->packet_pos; asf_st->pkt_clean = 0; @@ -1690,11 +1692,11 @@ static int asf_read_seek(AVFormatContext *s, int stream_index, asf->index_read = -1; } - if (asf->index_read > 0 && st->internal->index_entries) { + if (asf->index_read > 0 && st->index_entries) { int index = av_index_search_timestamp(st, pts, flags); if (index >= 0) { /* find the position */ - uint64_t pos = st->internal->index_entries[index].pos; + uint64_t pos = st->index_entries[index].pos; /* do the seek */ av_log(s, AV_LOG_DEBUG, "SEEKTO: %"PRId64"\n", pos); diff --git a/libavformat/asfdec_o.c b/libavformat/asfdec_o.c index 34ae541934..defb3fe892 100644 --- a/libavformat/asfdec_o.c +++ b/libavformat/asfdec_o.c @@ -113,6 +113,7 @@ typedef struct ASFContext { int64_t data_offset; int64_t first_packet_offset; // packet offset int64_t unknown_offset; // for top level header objects or subobjects without specified behavior + int in_asf_read_unknown; // ASF file must not contain more than 128 streams according to the specification ASFStream *asf_st[ASF_MAX_STREAMS]; @@ -177,7 +178,7 @@ static int asf_read_unknown(AVFormatContext *s, const GUIDParseTable *g) uint64_t size = avio_rl64(pb); int ret; - if (size > INT64_MAX) + if (size > INT64_MAX || asf->in_asf_read_unknown > 5) return AVERROR_INVALIDDATA; if (asf->is_header) @@ -186,8 +187,11 @@ static int asf_read_unknown(AVFormatContext *s, const GUIDParseTable *g) if (!g->is_subobject) { if (!(ret = strcmp(g->name, "Header Extension"))) avio_skip(pb, 22); // skip reserved fields and Data Size - if ((ret = detect_unknown_subobject(s, asf->unknown_offset, - asf->unknown_size)) < 0) + asf->in_asf_read_unknown ++; + ret = detect_unknown_subobject(s, asf->unknown_offset, + asf->unknown_size); + asf->in_asf_read_unknown --; + if (ret < 0) return ret; } else { if (size < 24) { @@ -685,7 +689,7 @@ static int asf_read_properties(AVFormatContext *s, const GUIDParseTable *g) return 0; } -static int parse_video_info(AVIOContext *pb, AVStream *st) +static int parse_video_info(AVFormatContext *avfmt, AVIOContext *pb, AVStream *st) { uint16_t size_asf; // ASF-specific Format Data size uint32_t size_bmp; // BMP_HEADER-specific Format Data size @@ -700,19 +704,10 @@ static int parse_video_info(AVIOContext *pb, AVStream *st) st->codecpar->codec_id = ff_codec_get_id(ff_codec_bmp_tags, tag); size_bmp = FFMAX(size_asf, size_bmp); - if (size_bmp > BMP_HEADER_SIZE && - size_bmp < INT_MAX - AV_INPUT_BUFFER_PADDING_SIZE) { - int ret; - st->codecpar->extradata_size = size_bmp - BMP_HEADER_SIZE; - if (!(st->codecpar->extradata = av_malloc(st->codecpar->extradata_size + - AV_INPUT_BUFFER_PADDING_SIZE))) { - st->codecpar->extradata_size = 0; - return AVERROR(ENOMEM); - } - memset(st->codecpar->extradata + st->codecpar->extradata_size , 0, - AV_INPUT_BUFFER_PADDING_SIZE); - if ((ret = avio_read(pb, st->codecpar->extradata, - st->codecpar->extradata_size)) < 0) + if (size_bmp > BMP_HEADER_SIZE) { + int ret = ff_get_extradata(avfmt, st->codecpar, pb, size_bmp - BMP_HEADER_SIZE); + + if (ret < 0) return ret; } return 0; @@ -795,7 +790,7 @@ static int asf_read_stream_properties(AVFormatContext *s, const GUIDParseTable * break; case AVMEDIA_TYPE_VIDEO: asf_st->type = AVMEDIA_TYPE_VIDEO; - if ((ret = parse_video_info(pb, st)) < 0) + if ((ret = parse_video_info(s, pb, st)) < 0) return ret; break; default: @@ -981,6 +976,9 @@ static int asf_read_simple_index(AVFormatContext *s, const GUIDParseTable *g) int64_t offset; uint64_t size = avio_rl64(pb); + if (size < 24) + return AVERROR_INVALIDDATA; + // simple index objects should be ordered by stream number, this loop tries to find // the first not indexed video stream for (i = 0; i < asf->nb_streams; i++) { @@ -1359,6 +1357,8 @@ static int asf_read_packet_header(AVFormatContext *s) unsigned char error_flags, len_flags, pay_flags; asf->packet_offset = avio_tell(pb); + if (asf->packet_offset > INT64_MAX/2) + asf->packet_offset = 0; error_flags = avio_r8(pb); // read Error Correction Flags if (error_flags & ASF_PACKET_FLAG_ERROR_CORRECTION_PRESENT) { if (!(error_flags & ASF_ERROR_CORRECTION_LENGTH_TYPE)) { @@ -1636,11 +1636,11 @@ static int asf_read_seek(AVFormatContext *s, int stream_index, ASFContext *asf = s->priv_data; int idx, ret; - if (s->streams[stream_index]->internal->nb_index_entries && asf->is_simple_index) { + if (s->streams[stream_index]->nb_index_entries && asf->is_simple_index) { idx = av_index_search_timestamp(s->streams[stream_index], timestamp, flags); - if (idx < 0 || idx >= s->streams[stream_index]->internal->nb_index_entries) + if (idx < 0 || idx >= s->streams[stream_index]->nb_index_entries) return AVERROR_INVALIDDATA; - avio_seek(s->pb, s->streams[stream_index]->internal->index_entries[idx].pos, SEEK_SET); + avio_seek(s->pb, s->streams[stream_index]->index_entries[idx].pos, SEEK_SET); } else { if ((ret = ff_seek_frame_binary(s, stream_index, timestamp, flags)) < 0) return ret; diff --git a/libavformat/avformat.h b/libavformat/avformat.h index 822aa4c631..56708c0241 100644 --- a/libavformat/avformat.h +++ b/libavformat/avformat.h @@ -954,11 +954,7 @@ typedef struct AVStream { * decoding: set by libavformat, must not be modified by the caller. * encoding: unused */ -#if FF_API_INIT_PACKET AVPacket attached_pic; -#else - AVPacket *attached_pic; -#endif /** * An array of side data that applies to the whole stream (i.e. the @@ -1092,10 +1088,11 @@ typedef struct AVStream { void *unused7; AVProbeData unused6; int64_t unused5[16+1]; - void *unused2; - int unused3; - unsigned int unused4; #endif + AVIndexEntry *index_entries; /**< Only used if the format does not + support seeking natively. */ + int nb_index_entries; + unsigned int index_entries_allocated_size; /** * Stream Identifier diff --git a/libavformat/avidec.c b/libavformat/avidec.c index fa0599501a..7da14d07f6 100644 --- a/libavformat/avidec.c +++ b/libavformat/avidec.c @@ -79,6 +79,8 @@ typedef struct AVIContext { int stream_index; DVDemuxContext *dv_demux; int odml_depth; + int64_t odml_read; + int64_t odml_max_pos; int use_odml; #define MAX_ODML_DEPTH 1000 int64_t dts_max; @@ -165,7 +167,7 @@ static int get_riff(AVFormatContext *s, AVIOContext *pb) return 0; } -static int read_odml_index(AVFormatContext *s, int frame_num) +static int read_odml_index(AVFormatContext *s, int64_t frame_num) { AVIContext *avi = s->priv_data; AVIOContext *pb = s->pb; @@ -185,7 +187,7 @@ static int read_odml_index(AVFormatContext *s, int frame_num) av_log(s, AV_LOG_TRACE, "longs_per_entry:%d index_type:%d entries_in_use:%d " - "chunk_id:%X base:%16"PRIX64" frame_num:%d\n", + "chunk_id:%X base:%16"PRIX64" frame_num:%"PRId64"\n", longs_per_entry, index_type, entries_in_use, @@ -198,7 +200,7 @@ static int read_odml_index(AVFormatContext *s, int frame_num) st = s->streams[stream_id]; ast = st->priv_data; - if (index_sub_type) + if (index_sub_type || entries_in_use < 0) return AVERROR_INVALIDDATA; avio_rl32(pb); @@ -219,11 +221,18 @@ static int read_odml_index(AVFormatContext *s, int frame_num) } for (i = 0; i < entries_in_use; i++) { + avi->odml_max_pos = FFMAX(avi->odml_max_pos, avio_tell(pb)); + + // If we read more than there are bytes then we must have been reading something twice + if (avi->odml_read > avi->odml_max_pos) + return AVERROR_INVALIDDATA; + if (index_type) { int64_t pos = avio_rl32(pb) + base - 8; int len = avio_rl32(pb); int key = len >= 0; len &= 0x7FFFFFFF; + avi->odml_read += 8; av_log(s, AV_LOG_TRACE, "pos:%"PRId64", len:%X\n", pos, len); @@ -241,11 +250,14 @@ static int read_odml_index(AVFormatContext *s, int frame_num) } else { int64_t offset, pos; int duration; + int ret; + avi->odml_read += 16; + offset = avio_rl64(pb); avio_rl32(pb); /* size */ duration = avio_rl32(pb); - if (avio_feof(pb)) + if (avio_feof(pb) || offset > INT64_MAX - 8) return AVERROR_INVALIDDATA; pos = avio_tell(pb); @@ -258,7 +270,7 @@ static int read_odml_index(AVFormatContext *s, int frame_num) if (avio_seek(pb, offset + 8, SEEK_SET) < 0) return -1; avi->odml_depth++; - read_odml_index(s, frame_num); + ret = read_odml_index(s, frame_num); avi->odml_depth--; frame_num += duration; @@ -266,7 +278,8 @@ static int read_odml_index(AVFormatContext *s, int frame_num) av_log(s, AV_LOG_ERROR, "Failed to restore position after reading index\n"); return -1; } - + if (ret < 0) + return ret; } } avi->index_loaded = 2; @@ -281,7 +294,7 @@ static void clean_index(AVFormatContext *s) for (i = 0; i < s->nb_streams; i++) { AVStream *st = s->streams[i]; AVIStream *ast = st->priv_data; - int n = st->internal->nb_index_entries; + int n = st->nb_index_entries; int max = ast->sample_size; int64_t pos, size, ts; @@ -291,9 +304,9 @@ static void clean_index(AVFormatContext *s) while (max < 1024) max += max; - pos = st->internal->index_entries[0].pos; - size = st->internal->index_entries[0].size; - ts = st->internal->index_entries[0].timestamp; + pos = st->index_entries[0].pos; + size = st->index_entries[0].size; + ts = st->index_entries[0].timestamp; for (j = 0; j < size; j += max) av_add_index_entry(st, pos + j, ts + j, FFMIN(max, size - j), 0, @@ -441,12 +454,12 @@ static int calculate_bitrate(AVFormatContext *s) int64_t len = 0; AVStream *st = s->streams[i]; - if (!st->internal->nb_index_entries) + if (!st->nb_index_entries) continue; - for (j = 0; j < st->internal->nb_index_entries; j++) - len += st->internal->index_entries[j].size; - maxpos = FFMAX(maxpos, st->internal->index_entries[j-1].pos); + for (j = 0; j < st->nb_index_entries; j++) + len += st->index_entries[j].size; + maxpos = FFMAX(maxpos, st->index_entries[j-1].pos); lensum += len; } if (maxpos < av_rescale(avi->io_fsize, 9, 10)) // index does not cover the whole file @@ -460,12 +473,12 @@ static int calculate_bitrate(AVFormatContext *s) int64_t duration; int64_t bitrate; - for (j = 0; j < st->internal->nb_index_entries; j++) - len += st->internal->index_entries[j].size; + for (j = 0; j < st->nb_index_entries; j++) + len += st->index_entries[j].size; - if (st->internal->nb_index_entries < 2 || st->codecpar->bit_rate > 0) + if (st->nb_index_entries < 2 || st->codecpar->bit_rate > 0) continue; - duration = st->internal->index_entries[j-1].timestamp - st->internal->index_entries[0].timestamp; + duration = st->index_entries[j-1].timestamp - st->index_entries[0].timestamp; bitrate = av_rescale(8*len, st->time_base.den, duration * st->time_base.num); if (bitrate > 0) { st->codecpar->bit_rate = bitrate; @@ -856,6 +869,8 @@ static int avi_read_header(AVFormatContext *s) memcpy(st->codecpar->extradata + st->codecpar->extradata_size - 9, "BottomUp", 9); } + if (st->codecpar->height == INT_MIN) + return AVERROR_INVALIDDATA; st->codecpar->height = FFABS(st->codecpar->height); // avio_skip(pb, size - 5 * 4); @@ -1057,7 +1072,7 @@ end_of_header: for (i = 0; i < s->nb_streams; i++) { AVStream *st = s->streams[i]; - if (st->internal->nb_index_entries) + if (st->nb_index_entries) break; } // DV-in-AVI cannot be non-interleaved, if set this must be @@ -1097,6 +1112,10 @@ static int read_gab2_sub(AVFormatContext *s, AVStream *st, AVPacket *pkt) int size; AVProbeData pd; unsigned int desc_len; + + if (ast->sub_ctx) + return 0; + AVIOContext *pb = avio_alloc_context(pkt->data + 7, pkt->size - 7, 0, NULL, NULL, NULL, NULL); @@ -1288,7 +1307,7 @@ start_sync: AVStream *st1 = s->streams[1]; AVIStream *ast1 = st1->priv_data; // workaround for broken small-file-bug402.avi - if ( d[2] == 'w' && d[3] == 'b' + if (ast1 && d[2] == 'w' && d[3] == 'b' && n == 0 && st ->codecpar->codec_type == AVMEDIA_TYPE_VIDEO && st1->codecpar->codec_type == AVMEDIA_TYPE_AUDIO @@ -1347,8 +1366,8 @@ start_sync: if (size) { uint64_t pos = avio_tell(pb) - 8; - if (!st->internal->index_entries || !st->internal->nb_index_entries || - st->internal->index_entries[st->internal->nb_index_entries - 1].pos < pos) { + if (!st->index_entries || !st->nb_index_entries || + st->index_entries[st->nb_index_entries - 1].pos < pos) { av_add_index_entry(st, pos, ast->frame_offset, size, 0, AVINDEX_KEYFRAME); } @@ -1378,10 +1397,10 @@ static int ni_prepare_read(AVFormatContext *s) int64_t ts = ast->frame_offset; int64_t last_ts; - if (!st->internal->nb_index_entries) + if (!st->nb_index_entries) continue; - last_ts = st->internal->index_entries[st->internal->nb_index_entries - 1].timestamp; + last_ts = st->index_entries[st->nb_index_entries - 1].timestamp; if (!ast->remaining && ts > last_ts) continue; @@ -1410,11 +1429,11 @@ static int ni_prepare_read(AVFormatContext *s) } else { i = av_index_search_timestamp(best_st, best_ts, AVSEEK_FLAG_ANY); if (i >= 0) - best_ast->frame_offset = best_st->internal->index_entries[i].timestamp; + best_ast->frame_offset = best_st->index_entries[i].timestamp; } if (i >= 0) { - int64_t pos = best_st->internal->index_entries[i].pos; + int64_t pos = best_st->index_entries[i].pos; pos += best_ast->packet_size - best_ast->remaining; if (avio_seek(s->pb, pos + 8, SEEK_SET) < 0) return AVERROR_EOF; @@ -1424,7 +1443,7 @@ static int ni_prepare_read(AVFormatContext *s) avi->stream_index = best_stream_index; if (!best_ast->remaining) best_ast->packet_size = - best_ast->remaining = best_st->internal->index_entries[i].size; + best_ast->remaining = best_st->index_entries[i].size; } else return AVERROR_EOF; @@ -1515,15 +1534,15 @@ resync: pkt->dts /= ast->sample_size; pkt->stream_index = avi->stream_index; - if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO && st->internal->index_entries) { + if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO && st->index_entries) { AVIndexEntry *e; int index; index = av_index_search_timestamp(st, ast->frame_offset, AVSEEK_FLAG_ANY); - e = &st->internal->index_entries[index]; + e = &st->index_entries[index]; if (index >= 0 && e->timestamp == ast->frame_offset) { - if (index == st->internal->nb_index_entries-1) { + if (index == st->nb_index_entries-1) { int key=1; uint32_t state=-1; if (st->codecpar->codec_id == AV_CODEC_ID_MPEG4) { @@ -1559,7 +1578,7 @@ resync: } ast->seek_pos= 0; - if (!avi->non_interleaved && st->internal->nb_index_entries>1 && avi->index_loaded>1) { + if (!avi->non_interleaved && st->nb_index_entries>1 && avi->index_loaded>1) { int64_t dts= av_rescale_q(pkt->dts, st->time_base, AV_TIME_BASE_Q); if (avi->dts_max < dts) { @@ -1659,8 +1678,8 @@ static int avi_read_idx1(AVFormatContext *s, int size) if (!anykey) { for (index = 0; index < s->nb_streams; index++) { st = s->streams[index]; - if (st->internal->nb_index_entries) - st->internal->index_entries[0].flags |= AVINDEX_KEYFRAME; + if (st->nb_index_entries) + st->index_entries[0].flags |= AVINDEX_KEYFRAME; } } return 0; @@ -1685,16 +1704,16 @@ static int check_stream_max_drift(AVFormatContext *s) for (i = 0; i < s->nb_streams; i++) { AVStream *st = s->streams[i]; AVIStream *ast = st->priv_data; - int n = st->internal->nb_index_entries; - while (idx[i] < n && st->internal->index_entries[idx[i]].pos < pos) + int n = st->nb_index_entries; + while (idx[i] < n && st->index_entries[idx[i]].pos < pos) idx[i]++; if (idx[i] < n) { int64_t dts; - dts = av_rescale_q(st->internal->index_entries[idx[i]].timestamp / + dts = av_rescale_q(st->index_entries[idx[i]].timestamp / FFMAX(ast->sample_size, 1), st->time_base, AV_TIME_BASE_Q); min_dts = FFMIN(min_dts, dts); - min_pos = FFMIN(min_pos, st->internal->index_entries[idx[i]].pos); + min_pos = FFMIN(min_pos, st->index_entries[idx[i]].pos); } } for (i = 0; i < s->nb_streams; i++) { @@ -1703,7 +1722,7 @@ static int check_stream_max_drift(AVFormatContext *s) if (idx[i] && min_dts != INT64_MAX / 2) { int64_t dts, delta_dts; - dts = av_rescale_q(st->internal->index_entries[idx[i] - 1].timestamp / + dts = av_rescale_q(st->index_entries[idx[i] - 1].timestamp / FFMAX(ast->sample_size, 1), st->time_base, AV_TIME_BASE_Q); delta_dts = av_sat_sub64(dts, min_dts); @@ -1733,30 +1752,30 @@ static int guess_ni_flag(AVFormatContext *s) for (i = 0; i < s->nb_streams; i++) { AVStream *st = s->streams[i]; - int n = st->internal->nb_index_entries; + int n = st->nb_index_entries; unsigned int size; if (n <= 0) continue; if (n >= 2) { - int64_t pos = st->internal->index_entries[0].pos; + int64_t pos = st->index_entries[0].pos; unsigned tag[2]; avio_seek(s->pb, pos, SEEK_SET); tag[0] = avio_r8(s->pb); tag[1] = avio_r8(s->pb); avio_rl16(s->pb); size = avio_rl32(s->pb); - if (get_stream_idx(tag) == i && pos + size > st->internal->index_entries[1].pos) + if (get_stream_idx(tag) == i && pos + size > st->index_entries[1].pos) last_start = INT64_MAX; - if (get_stream_idx(tag) == i && size == st->internal->index_entries[0].size + 8) + if (get_stream_idx(tag) == i && size == st->index_entries[0].size + 8) last_start = INT64_MAX; } - if (st->internal->index_entries[0].pos > last_start) - last_start = st->internal->index_entries[0].pos; - if (st->internal->index_entries[n - 1].pos < first_end) - first_end = st->internal->index_entries[n - 1].pos; + if (st->index_entries[0].pos > last_start) + last_start = st->index_entries[0].pos; + if (st->index_entries[n - 1].pos < first_end) + first_end = st->index_entries[n - 1].pos; } avio_seek(s->pb, oldpos, SEEK_SET); @@ -1783,7 +1802,10 @@ static int avi_load_index(AVFormatContext *s) size = avio_rl32(pb); if (avio_feof(pb)) break; - next = avio_tell(pb) + size + (size & 1); + next = avio_tell(pb); + if (next < 0 || next > INT64_MAX - size - (size & 1)) + break; + next += size + (size & 1LL); if (tag == MKTAG('i', 'd', 'x', '1') && avi_read_idx1(s, size) >= 0) { @@ -1844,20 +1866,20 @@ static int avi_read_seek(AVFormatContext *s, int stream_index, timestamp * FFMAX(ast->sample_size, 1), flags); if (index < 0) { - if (st->internal->nb_index_entries > 0) + if (st->nb_index_entries > 0) av_log(s, AV_LOG_DEBUG, "Failed to find timestamp %"PRId64 " in index %"PRId64 " .. %"PRId64 "\n", timestamp * FFMAX(ast->sample_size, 1), - st->internal->index_entries[0].timestamp, - st->internal->index_entries[st->internal->nb_index_entries - 1].timestamp); + st->index_entries[0].timestamp, + st->index_entries[st->nb_index_entries - 1].timestamp); return AVERROR_INVALIDDATA; } /* find the position */ - pos = st->internal->index_entries[index].pos; - timestamp = st->internal->index_entries[index].timestamp / FFMAX(ast->sample_size, 1); + pos = st->index_entries[index].pos; + timestamp = st->index_entries[index].timestamp / FFMAX(ast->sample_size, 1); av_log(s, AV_LOG_TRACE, "XX %"PRId64" %d %"PRId64"\n", - timestamp, index, st->internal->index_entries[index].timestamp); + timestamp, index, st->index_entries[index].timestamp); if (CONFIG_DV_DEMUXER && avi->dv_demux) { /* One and only one real stream for DV in AVI, and it has video */ @@ -1888,7 +1910,7 @@ static int avi_read_seek(AVFormatContext *s, int stream_index, continue; } - if (st2->internal->nb_index_entries <= 0) + if (st2->nb_index_entries <= 0) continue; // av_assert1(st2->codecpar->block_align); @@ -1902,14 +1924,14 @@ static int avi_read_seek(AVFormatContext *s, int stream_index, (st2->codecpar->codec_type != AVMEDIA_TYPE_VIDEO ? AVSEEK_FLAG_ANY : 0)); if (index < 0) index = 0; - ast2->seek_pos = st2->internal->index_entries[index].pos; + ast2->seek_pos = st2->index_entries[index].pos; pos_min = FFMIN(pos_min,ast2->seek_pos); } for (i = 0; i < s->nb_streams; i++) { AVStream *st2 = s->streams[i]; AVIStream *ast2 = st2->priv_data; - if (ast2->sub_ctx || st2->internal->nb_index_entries <= 0) + if (ast2->sub_ctx || st2->nb_index_entries <= 0) continue; index = av_index_search_timestamp( @@ -1918,9 +1940,9 @@ static int avi_read_seek(AVFormatContext *s, int stream_index, flags | AVSEEK_FLAG_BACKWARD | (st2->codecpar->codec_type != AVMEDIA_TYPE_VIDEO ? AVSEEK_FLAG_ANY : 0)); if (index < 0) index = 0; - while (!avi->non_interleaved && index>0 && st2->internal->index_entries[index-1].pos >= pos_min) + while (!avi->non_interleaved && index>0 && st2->index_entries[index-1].pos >= pos_min) index--; - ast2->frame_offset = st2->internal->index_entries[index].timestamp; + ast2->frame_offset = st2->index_entries[index].timestamp; } /* do the seek */ diff --git a/libavformat/avio.c b/libavformat/avio.c index 8011482e76..cd9b5d9e7f 100644 --- a/libavformat/avio.c +++ b/libavformat/avio.c @@ -316,8 +316,11 @@ int ffurl_open_whitelist(URLContext **puc, const char *filename, int flags, int ret = ffurl_alloc(puc, filename, flags, int_cb); if (ret < 0) return ret; - if (parent) - av_opt_copy(*puc, parent); + if (parent) { + ret = av_opt_copy(*puc, parent); + if (ret < 0) + goto fail; + } if (options && (ret = av_opt_set_dict(*puc, options)) < 0) goto fail; diff --git a/libavformat/aviobuf.c b/libavformat/aviobuf.c index 518cb11129..1fb30644ff 100644 --- a/libavformat/aviobuf.c +++ b/libavformat/aviobuf.c @@ -1005,6 +1005,9 @@ int ffio_ensure_seekback(AVIOContext *s, int64_t buf_size) if (buf_size <= s->buf_end - s->buf_ptr) return 0; + if (buf_size > INT_MAX - max_buffer_size) + return AVERROR(EINVAL); + buf_size += max_buffer_size - 1; if (buf_size + s->buf_ptr - s->buffer <= s->buffer_size || s->seekable || !s->read_packet) diff --git a/libavformat/avr.c b/libavformat/avr.c index c4ce70142a..a79898f146 100644 --- a/libavformat/avr.c +++ b/libavformat/avr.c @@ -70,6 +70,9 @@ static int avr_read_header(AVFormatContext *s) avio_skip(s->pb, 1); // replay speed st->codecpar->sample_rate = avio_rb24(s->pb); + if (st->codecpar->sample_rate == 0) + return AVERROR_INVALIDDATA; + avio_skip(s->pb, 4 * 3); avio_skip(s->pb, 2 * 3); avio_skip(s->pb, 20); diff --git a/libavformat/avs.c b/libavformat/avs.c index 097c171908..88694e951b 100644 --- a/libavformat/avs.c +++ b/libavformat/avs.c @@ -140,6 +140,10 @@ static int avs_read_audio_packet(AVFormatContext * s, AVPacket * pkt) return 0; /* this indicate EOS */ if (ret < 0) return ret; + if (size != (int)size) { + av_packet_unref(pkt); + return AVERROR(EDOM); + } pkt->stream_index = avs->st_audio->index; pkt->flags |= AV_PKT_FLAG_KEY; diff --git a/libavformat/bfi.c b/libavformat/bfi.c index 2dab986f3a..35b6816aad 100644 --- a/libavformat/bfi.c +++ b/libavformat/bfi.c @@ -73,6 +73,8 @@ static int bfi_read_header(AVFormatContext * s) return AVERROR_INVALIDDATA; bfi->nframes = avio_rl32(pb); + if (bfi->nframes < 0) + return AVERROR_INVALIDDATA; avio_rl32(pb); avio_rl32(pb); avio_rl32(pb); @@ -138,12 +140,12 @@ static int bfi_read_packet(AVFormatContext * s, AVPacket * pkt) audio_offset = avio_rl32(pb); avio_rl32(pb); video_offset = avio_rl32(pb); - audio_size = video_offset - audio_offset; - bfi->video_size = chunk_size - video_offset; - if (audio_size < 0 || bfi->video_size < 0) { + if (audio_offset < 0 || video_offset < audio_offset || chunk_size < video_offset) { av_log(s, AV_LOG_ERROR, "Invalid audio/video offsets or chunk size\n"); return AVERROR_INVALIDDATA; } + audio_size = video_offset - audio_offset; + bfi->video_size = chunk_size - video_offset; //Tossing an audio packet at the audio decoder. ret = av_get_packet(pb, pkt, audio_size); diff --git a/libavformat/bink.c b/libavformat/bink.c index 99bbd27ef3..08125ba8f1 100644 --- a/libavformat/bink.c +++ b/libavformat/bink.c @@ -225,8 +225,8 @@ static int read_header(AVFormatContext *s) return ret; } - if (vst->internal->index_entries) - avio_seek(pb, vst->internal->index_entries[0].pos + bink->smush_size, SEEK_SET); + if (vst->index_entries) + avio_seek(pb, vst->index_entries[0].pos + bink->smush_size, SEEK_SET); else avio_skip(pb, 4); @@ -256,8 +256,8 @@ static int read_packet(AVFormatContext *s, AVPacket *pkt) return AVERROR(EIO); } - bink->remain_packet_size = st->internal->index_entries[index_entry].size; - bink->flags = st->internal->index_entries[index_entry].flags; + bink->remain_packet_size = st->index_entries[index_entry].size; + bink->flags = st->index_entries[index_entry].flags; bink->current_track = 0; } @@ -313,7 +313,7 @@ static int read_seek(AVFormatContext *s, int stream_index, int64_t timestamp, in return -1; /* seek to the first frame */ - ret = avio_seek(s->pb, vst->internal->index_entries[0].pos + bink->smush_size, SEEK_SET); + ret = avio_seek(s->pb, vst->index_entries[0].pos + bink->smush_size, SEEK_SET); if (ret < 0) return ret; diff --git a/libavformat/bintext.c b/libavformat/bintext.c index bc0f6bd099..f0c365b7be 100644 --- a/libavformat/bintext.c +++ b/libavformat/bintext.c @@ -90,9 +90,12 @@ static int next_tag_read(AVFormatContext *avctx, uint64_t *fsize) AVIOContext *pb = avctx->pb; char buf[36]; int len; - uint64_t start_pos = avio_size(pb) - 256; + int64_t start_pos = avio_size(pb); - avio_seek(pb, start_pos, SEEK_SET); + if (start_pos < 256) + return AVERROR_INVALIDDATA; + + avio_seek(pb, start_pos - 256, SEEK_SET); if (avio_read(pb, buf, sizeof(next_magic)) != sizeof(next_magic)) return -1; if (memcmp(buf, next_magic, sizeof(next_magic))) @@ -250,7 +253,10 @@ static int xbin_read_header(AVFormatContext *s) return AVERROR(EIO); if (pb->seekable & AVIO_SEEKABLE_NORMAL) { - bin->fsize = avio_size(pb) - 9 - st->codecpar->extradata_size; + int64_t fsize = avio_size(pb); + if (fsize < 9 + st->codecpar->extradata_size) + return 0; + bin->fsize = fsize - 9 - st->codecpar->extradata_size; ff_sauce_read(s, &bin->fsize, NULL, 0); avio_seek(pb, 9 + st->codecpar->extradata_size, SEEK_SET); } @@ -290,7 +296,10 @@ static int adf_read_header(AVFormatContext *s) if (pb->seekable & AVIO_SEEKABLE_NORMAL) { int got_width = 0; - bin->fsize = avio_size(pb) - 1 - 192 - 4096; + int64_t fsize = avio_size(pb); + if (fsize < 1 + 192 + 4096) + return 0; + bin->fsize = fsize - 1 - 192 - 4096; st->codecpar->width = 80<<3; ff_sauce_read(s, &bin->fsize, &got_width, 0); if (st->codecpar->width < 8) @@ -323,6 +332,7 @@ static int idf_read_header(AVFormatContext *s) AVIOContext *pb = s->pb; AVStream *st; int got_width = 0, ret; + int64_t fsize; if (!(pb->seekable & AVIO_SEEKABLE_NORMAL)) return AVERROR(EIO); @@ -337,14 +347,18 @@ static int idf_read_header(AVFormatContext *s) st->codecpar->extradata[0] = 16; st->codecpar->extradata[1] = BINTEXT_PALETTE|BINTEXT_FONT; - avio_seek(pb, avio_size(pb) - 4096 - 48, SEEK_SET); + fsize = avio_size(pb); + if (fsize < 12 + 4096 + 48) + return AVERROR_INVALIDDATA; + bin->fsize = fsize - 12 - 4096 - 48; + + avio_seek(pb, bin->fsize + 12, SEEK_SET); if (avio_read(pb, st->codecpar->extradata + 2 + 48, 4096) < 0) return AVERROR(EIO); if (avio_read(pb, st->codecpar->extradata + 2, 48) < 0) return AVERROR(EIO); - bin->fsize = avio_size(pb) - 12 - 4096 - 48; ff_sauce_read(s, &bin->fsize, &got_width, 0); if (st->codecpar->width < 8) return AVERROR_INVALIDDATA; diff --git a/libavformat/cafdec.c b/libavformat/cafdec.c index d56187f71f..a33b405f05 100644 --- a/libavformat/cafdec.c +++ b/libavformat/cafdec.c @@ -79,7 +79,7 @@ static int read_desc_chunk(AVFormatContext *s) st->codecpar->channels = avio_rb32(pb); st->codecpar->bits_per_coded_sample = avio_rb32(pb); - if (caf->bytes_per_packet < 0 || caf->frames_per_packet < 0) + if (caf->bytes_per_packet < 0 || caf->frames_per_packet < 0 || st->codecpar->channels < 0) return AVERROR_INVALIDDATA; /* calculate bit rate for constant size packets */ @@ -204,18 +204,23 @@ static int read_pakt_chunk(AVFormatContext *s, int64_t size) st->nb_frames += avio_rb32(pb); /* priming frames */ st->nb_frames += avio_rb32(pb); /* remainder frames */ - st->duration = 0; - for (i = 0; i < num_packets; i++) { - if (avio_feof(pb)) - return AVERROR_INVALIDDATA; - ret = av_add_index_entry(s->streams[0], pos, st->duration, 0, 0, AVINDEX_KEYFRAME); - if (ret < 0) - return ret; - pos += caf->bytes_per_packet ? caf->bytes_per_packet : ff_mp4_read_descr_len(pb); - st->duration += caf->frames_per_packet ? caf->frames_per_packet : ff_mp4_read_descr_len(pb); + if (caf->bytes_per_packet > 0 && caf->frames_per_packet > 0) { + st->duration = caf->frames_per_packet * num_packets; + pos = caf-> bytes_per_packet * num_packets; + } else { + st->duration = 0; + for (i = 0; i < num_packets; i++) { + if (avio_feof(pb)) + return AVERROR_INVALIDDATA; + ret = av_add_index_entry(s->streams[0], pos, st->duration, 0, 0, AVINDEX_KEYFRAME); + if (ret < 0) + return ret; + pos += caf->bytes_per_packet ? caf->bytes_per_packet : ff_mp4_read_descr_len(pb); + st->duration += caf->frames_per_packet ? caf->frames_per_packet : ff_mp4_read_descr_len(pb); + } } - if (avio_tell(pb) - ccount > size) { + if (avio_tell(pb) - ccount > size || size > INT64_MAX - ccount) { av_log(s, AV_LOG_ERROR, "error reading packet table\n"); return AVERROR_INVALIDDATA; } @@ -236,6 +241,8 @@ static void read_info_chunk(AVFormatContext *s, int64_t size) char value[1024]; avio_get_str(pb, INT_MAX, key, sizeof(key)); avio_get_str(pb, INT_MAX, value, sizeof(value)); + if (!*key) + continue; av_dict_set(&s->metadata, key, value, 0); } } @@ -285,6 +292,9 @@ static int read_header(AVFormatContext *s) avio_skip(pb, 4); /* edit count */ caf->data_start = avio_tell(pb); caf->data_size = size < 0 ? -1 : size - 4; + if (caf->data_start < 0 || caf->data_size > INT64_MAX - caf->data_start) + return AVERROR_INVALIDDATA; + if (caf->data_size > 0 && (pb->seekable & AVIO_SEEKABLE_NORMAL)) avio_skip(pb, caf->data_size); found_data = 1; @@ -335,9 +345,9 @@ static int read_header(AVFormatContext *s) found_data: if (caf->bytes_per_packet > 0 && caf->frames_per_packet > 0) { - if (caf->data_size > 0) + if (caf->data_size > 0 && caf->data_size / caf->bytes_per_packet < INT64_MAX / caf->frames_per_packet) st->nb_frames = (caf->data_size / caf->bytes_per_packet) * caf->frames_per_packet; - } else if (st->internal->nb_index_entries && st->duration > 0) { + } else if (st->nb_index_entries && st->duration > 0) { if (st->codecpar->sample_rate && caf->data_size / st->duration > INT64_MAX / st->codecpar->sample_rate / 8) { av_log(s, AV_LOG_ERROR, "Overflow during bit rate calculation %d * 8 * %"PRId64"\n", st->codecpar->sample_rate, caf->data_size / st->duration); @@ -390,13 +400,13 @@ static int read_packet(AVFormatContext *s, AVPacket *pkt) pkt_size = (CAF_MAX_PKT_SIZE / pkt_size) * pkt_size; pkt_size = FFMIN(pkt_size, left); pkt_frames = pkt_size / caf->bytes_per_packet; - } else if (st->internal->nb_index_entries) { - if (caf->packet_cnt < st->internal->nb_index_entries - 1) { - pkt_size = st->internal->index_entries[caf->packet_cnt + 1].pos - st->internal->index_entries[caf->packet_cnt].pos; - pkt_frames = st->internal->index_entries[caf->packet_cnt + 1].timestamp - st->internal->index_entries[caf->packet_cnt].timestamp; - } else if (caf->packet_cnt == st->internal->nb_index_entries - 1) { - pkt_size = caf->num_bytes - st->internal->index_entries[caf->packet_cnt].pos; - pkt_frames = st->duration - st->internal->index_entries[caf->packet_cnt].timestamp; + } else if (st->nb_index_entries) { + if (caf->packet_cnt < st->nb_index_entries - 1) { + pkt_size = st->index_entries[caf->packet_cnt + 1].pos - st->index_entries[caf->packet_cnt].pos; + pkt_frames = st->index_entries[caf->packet_cnt + 1].timestamp - st->index_entries[caf->packet_cnt].timestamp; + } else if (caf->packet_cnt == st->nb_index_entries - 1) { + pkt_size = caf->num_bytes - st->index_entries[caf->packet_cnt].pos; + pkt_frames = st->duration - st->index_entries[caf->packet_cnt].timestamp; } else { return AVERROR(EIO); } @@ -435,10 +445,10 @@ static int read_seek(AVFormatContext *s, int stream_index, pos = FFMIN(pos, caf->data_size); packet_cnt = pos / caf->bytes_per_packet; frame_cnt = caf->frames_per_packet * packet_cnt; - } else if (st->internal->nb_index_entries) { + } else if (st->nb_index_entries) { packet_cnt = av_index_search_timestamp(st, timestamp, flags); - frame_cnt = st->internal->index_entries[packet_cnt].timestamp; - pos = st->internal->index_entries[packet_cnt].pos; + frame_cnt = st->index_entries[packet_cnt].timestamp; + pos = st->index_entries[packet_cnt].pos; } else { return -1; } diff --git a/libavformat/cafenc.c b/libavformat/cafenc.c index 7e44797a52..c5e47f20a6 100644 --- a/libavformat/cafenc.c +++ b/libavformat/cafenc.c @@ -28,7 +28,6 @@ typedef struct { int64_t data; - uint8_t *pkt_sizes; int size_buffer_size; int size_entries_used; int packets; @@ -209,30 +208,29 @@ static int caf_write_header(AVFormatContext *s) static int caf_write_packet(AVFormatContext *s, AVPacket *pkt) { CAFContext *caf = s->priv_data; + AVStream *const st = s->streams[0]; - avio_write(s->pb, pkt->data, pkt->size); - if (!s->streams[0]->codecpar->block_align) { - void *pkt_sizes = caf->pkt_sizes; - int i, alloc_size = caf->size_entries_used + 5; - if (alloc_size < 0) { - caf->pkt_sizes = NULL; - } else { - caf->pkt_sizes = av_fast_realloc(caf->pkt_sizes, - &caf->size_buffer_size, - alloc_size); - } - if (!caf->pkt_sizes) { - av_free(pkt_sizes); + if (!st->codecpar->block_align) { + uint8_t *pkt_sizes; + int i, alloc_size = caf->size_entries_used + 5U; + if (alloc_size < 0) + return AVERROR(ERANGE); + + pkt_sizes = av_fast_realloc(st->priv_data, + &caf->size_buffer_size, + alloc_size); + if (!pkt_sizes) return AVERROR(ENOMEM); - } + st->priv_data = pkt_sizes; for (i = 4; i > 0; i--) { unsigned top = pkt->size >> i * 7; if (top) - caf->pkt_sizes[caf->size_entries_used++] = 128 | top; + pkt_sizes[caf->size_entries_used++] = 128 | top; } - caf->pkt_sizes[caf->size_entries_used++] = pkt->size & 127; + pkt_sizes[caf->size_entries_used++] = pkt->size & 127; caf->packets++; } + avio_write(s->pb, pkt->data, pkt->size); return 0; } @@ -240,7 +238,8 @@ static int caf_write_trailer(AVFormatContext *s) { CAFContext *caf = s->priv_data; AVIOContext *pb = s->pb; - AVCodecParameters *par = s->streams[0]->codecpar; + AVStream *st = s->streams[0]; + AVCodecParameters *par = st->codecpar; if (pb->seekable & AVIO_SEEKABLE_NORMAL) { int64_t file_size = avio_tell(pb); @@ -250,16 +249,14 @@ static int caf_write_trailer(AVFormatContext *s) avio_seek(pb, file_size, SEEK_SET); if (!par->block_align) { ffio_wfourcc(pb, "pakt"); - avio_wb64(pb, caf->size_entries_used + 24); + avio_wb64(pb, caf->size_entries_used + 24U); avio_wb64(pb, caf->packets); ///< mNumberPackets avio_wb64(pb, caf->packets * samples_per_packet(par->codec_id, par->channels, par->block_align)); ///< mNumberValidFrames avio_wb32(pb, 0); ///< mPrimingFrames avio_wb32(pb, 0); ///< mRemainderFrames - avio_write(pb, caf->pkt_sizes, caf->size_entries_used); - caf->size_buffer_size = 0; + avio_write(pb, st->priv_data, caf->size_entries_used); } } - av_freep(&caf->pkt_sizes); return 0; } diff --git a/libavformat/cinedec.c b/libavformat/cinedec.c index e5c6468c39..88f5e56902 100644 --- a/libavformat/cinedec.c +++ b/libavformat/cinedec.c @@ -288,10 +288,10 @@ static int cine_read_packet(AVFormatContext *avctx, AVPacket *pkt) AVIOContext *pb = avctx->pb; int n, size, ret; - if (cine->pts >= st->internal->nb_index_entries) + if (cine->pts >= st->nb_index_entries) return AVERROR_EOF; - avio_seek(pb, st->internal->index_entries[cine->pts].pos, SEEK_SET); + avio_seek(pb, st->index_entries[cine->pts].pos, SEEK_SET); n = avio_rl32(pb); if (n < 8) return AVERROR_INVALIDDATA; diff --git a/libavformat/concatdec.c b/libavformat/concatdec.c index 32d4a99010..d45e52d7c6 100644 --- a/libavformat/concatdec.c +++ b/libavformat/concatdec.c @@ -317,7 +317,7 @@ static int64_t get_best_effort_duration(ConcatFile *file, AVFormatContext *avf) if (file->user_duration != AV_NOPTS_VALUE) return file->user_duration; if (file->outpoint != AV_NOPTS_VALUE) - return file->outpoint - file->file_inpoint; + return av_sat_sub64(file->outpoint, file->file_inpoint); if (avf->duration > 0) return avf->duration - (file->file_inpoint - file->file_start_time); if (file->next_dts != AV_NOPTS_VALUE) @@ -494,11 +494,15 @@ static int concat_read_header(AVFormatContext *avf) else time = cat->files[i].start_time; if (cat->files[i].user_duration == AV_NOPTS_VALUE) { - if (cat->files[i].inpoint == AV_NOPTS_VALUE || cat->files[i].outpoint == AV_NOPTS_VALUE) + if (cat->files[i].inpoint == AV_NOPTS_VALUE || cat->files[i].outpoint == AV_NOPTS_VALUE || + cat->files[i].outpoint - (uint64_t)cat->files[i].inpoint != av_sat_sub64(cat->files[i].outpoint, cat->files[i].inpoint) + ) break; cat->files[i].user_duration = cat->files[i].outpoint - cat->files[i].inpoint; } cat->files[i].duration = cat->files[i].user_duration; + if (time + (uint64_t)cat->files[i].user_duration > INT64_MAX) + return AVERROR_INVALIDDATA; time += cat->files[i].user_duration; } if (i == cat->nb_files) { diff --git a/libavformat/dashdec.c b/libavformat/dashdec.c index 6f3f28dcc7..c9871aaf9a 100644 --- a/libavformat/dashdec.c +++ b/libavformat/dashdec.c @@ -441,7 +441,7 @@ static int open_url(AVFormatContext *s, AVIOContext **pb, const char *url, av_freep(pb); av_dict_copy(&tmp, *opts, 0); av_dict_copy(&tmp, opts2, 0); - ret = avio_open2(pb, url, AVIO_FLAG_READ, c->interrupt_callback, &tmp); + ret = ffio_open_whitelist(pb, url, AVIO_FLAG_READ, c->interrupt_callback, &tmp, s->protocol_whitelist, s->protocol_blacklist); if (ret >= 0) { // update cookies on http response with setcookies. char *new_cookies = NULL; @@ -1216,7 +1216,7 @@ static int parse_manifest(AVFormatContext *s, const char *url, AVIOContext *in) close_in = 1; av_dict_copy(&opts, c->avio_opts, 0); - ret = avio_open2(&in, url, AVIO_FLAG_READ, c->interrupt_callback, &opts); + ret = ffio_open_whitelist(&in, url, AVIO_FLAG_READ, c->interrupt_callback, &opts, s->protocol_whitelist, s->protocol_blacklist); av_dict_free(&opts); if (ret < 0) return ret; diff --git a/libavformat/dhav.c b/libavformat/dhav.c index 526331ae4c..d5d25801ca 100644 --- a/libavformat/dhav.c +++ b/libavformat/dhav.c @@ -434,10 +434,10 @@ static int dhav_read_seek(AVFormatContext *s, int stream_index, if (index < 0) return -1; - if (avio_seek(s->pb, st->internal->index_entries[index].pos, SEEK_SET) < 0) + if (avio_seek(s->pb, st->index_entries[index].pos, SEEK_SET) < 0) return -1; - pts = st->internal->index_entries[index].timestamp; + pts = st->index_entries[index].timestamp; for (int n = 0; n < s->nb_streams; n++) { AVStream *st = s->streams[n]; diff --git a/libavformat/dsfdec.c b/libavformat/dsfdec.c index 1df163e114..71dbf2f112 100644 --- a/libavformat/dsfdec.c +++ b/libavformat/dsfdec.c @@ -129,7 +129,7 @@ static int dsf_read_header(AVFormatContext *s) return AVERROR_INVALIDDATA; } st->codecpar->block_align *= st->codecpar->channels; - st->codecpar->bit_rate = st->codecpar->channels * st->codecpar->sample_rate * 8LL; + st->codecpar->bit_rate = st->codecpar->channels * 8LL * st->codecpar->sample_rate; avpriv_set_pts_info(st, 64, 1, st->codecpar->sample_rate); avio_skip(pb, 4); diff --git a/libavformat/dsicin.c b/libavformat/dsicin.c index b18f43b9a0..5a1f256595 100644 --- a/libavformat/dsicin.c +++ b/libavformat/dsicin.c @@ -166,7 +166,8 @@ static int cin_read_packet(AVFormatContext *s, AVPacket *pkt) CinDemuxContext *cin = s->priv_data; AVIOContext *pb = s->pb; CinFrameHeader *hdr = &cin->frame_header; - int rc, palette_type, pkt_size; + int rc, palette_type; + int64_t pkt_size; int ret; if (cin->audio_buffer_size == 0) { @@ -182,7 +183,9 @@ static int cin_read_packet(AVFormatContext *s, AVPacket *pkt) } /* palette and video packet */ - pkt_size = (palette_type + 3) * hdr->pal_colors_count + hdr->video_frame_size; + pkt_size = (palette_type + 3LL) * hdr->pal_colors_count + hdr->video_frame_size; + if (pkt_size + 4 > INT_MAX) + return AVERROR_INVALIDDATA; pkt_size = ffio_limit(pb, pkt_size); diff --git a/libavformat/dss.c b/libavformat/dss.c index 0585049130..468de3fe84 100644 --- a/libavformat/dss.c +++ b/libavformat/dss.c @@ -219,7 +219,6 @@ static int dss_sp_read_packet(AVFormatContext *s, AVPacket *pkt) } else read_size = DSS_FRAME_SIZE; - ctx->counter -= read_size; ctx->packet_size = DSS_FRAME_SIZE - 1; ret = av_new_packet(pkt, DSS_FRAME_SIZE); @@ -231,17 +230,16 @@ static int dss_sp_read_packet(AVFormatContext *s, AVPacket *pkt) pkt->stream_index = 0; s->bit_rate = 8LL * ctx->packet_size * st->codecpar->sample_rate * 512 / (506 * pkt->duration); - if (ctx->counter < 0) { - int size2 = ctx->counter + read_size; - - ret = avio_read(s->pb, ctx->dss_sp_buf + offset + buff_offset, - size2 - offset); - if (ret < size2 - offset) + if (ctx->counter < read_size) { + ret = avio_read(s->pb, ctx->dss_sp_buf + buff_offset, + ctx->counter); + if (ret < ctx->counter) goto error_eof; + offset = ctx->counter; dss_skip_audio_header(s, pkt); - offset = size2; } + ctx->counter -= read_size; ret = avio_read(s->pb, ctx->dss_sp_buf + offset + buff_offset, read_size - offset); @@ -278,7 +276,7 @@ static int dss_723_1_read_packet(AVFormatContext *s, AVPacket *pkt) size = frame_size[byte & 3]; ctx->packet_size = size; - ctx->counter -= size; + ctx->counter--; ret = av_new_packet(pkt, size); if (ret < 0) @@ -288,27 +286,26 @@ static int dss_723_1_read_packet(AVFormatContext *s, AVPacket *pkt) pkt->data[0] = byte; offset = 1; pkt->duration = 240; - s->bit_rate = 8LL * size * st->codecpar->sample_rate * 512 / (506 * pkt->duration); + s->bit_rate = 8LL * size-- * st->codecpar->sample_rate * 512 / (506 * pkt->duration); pkt->stream_index = 0; - if (ctx->counter < 0) { - int size2 = ctx->counter + size; - + if (ctx->counter < size) { ret = avio_read(s->pb, pkt->data + offset, - size2 - offset); - if (ret < size2 - offset) { + ctx->counter); + if (ret < ctx->counter) return ret < 0 ? ret : AVERROR_EOF; - } + offset += ctx->counter; + size -= ctx->counter; + ctx->counter = 0; dss_skip_audio_header(s, pkt); - offset = size2; } + ctx->counter -= size; - ret = avio_read(s->pb, pkt->data + offset, size - offset); - if (ret < size - offset) { + ret = avio_read(s->pb, pkt->data + offset, size); + if (ret < size) return ret < 0 ? ret : AVERROR_EOF; - } return pkt->size; } diff --git a/libavformat/dxa.c b/libavformat/dxa.c index 909c5ba2ba..831ba7a501 100644 --- a/libavformat/dxa.c +++ b/libavformat/dxa.c @@ -79,7 +79,7 @@ static int dxa_read_header(AVFormatContext *s) if(fps > 0){ den = 1000; num = fps; - }else if (fps < 0){ + }else if (fps < 0 && fps > INT_MIN){ den = 100000; num = -fps; }else{ @@ -118,9 +118,14 @@ static int dxa_read_header(AVFormatContext *s) if(tag == MKTAG('d', 'a', 't', 'a')) break; avio_skip(pb, fsize); } - c->bpc = (fsize + c->frames - 1) / c->frames; - if(ast->codecpar->block_align) - c->bpc = ((c->bpc + ast->codecpar->block_align - 1) / ast->codecpar->block_align) * ast->codecpar->block_align; + c->bpc = (fsize + (int64_t)c->frames - 1) / c->frames; + if (c->bpc < 0) + return AVERROR_INVALIDDATA; + if(ast->codecpar->block_align) { + if (c->bpc > INT_MAX - ast->codecpar->block_align + 1) + return AVERROR_INVALIDDATA; + c->bpc = ((c->bpc - 1 + ast->codecpar->block_align) / ast->codecpar->block_align) * ast->codecpar->block_align; + } c->bytes_left = fsize; c->wavpos = avio_tell(pb); avio_seek(pb, c->vidpos, SEEK_SET); diff --git a/libavformat/fifo.c b/libavformat/fifo.c index 17748e94ce..a1dca1bc16 100644 --- a/libavformat/fifo.c +++ b/libavformat/fifo.c @@ -593,7 +593,7 @@ static int fifo_write_packet(AVFormatContext *avf, AVPacket *pkt) goto fail; } - if (fifo->timeshift && pkt->dts != AV_NOPTS_VALUE) + if (fifo->timeshift && pkt && pkt->dts != AV_NOPTS_VALUE) atomic_fetch_add_explicit(&fifo->queue_duration, next_duration(avf, pkt, &fifo->last_sent_dts), memory_order_relaxed); return ret; diff --git a/libavformat/flacdec.c b/libavformat/flacdec.c index f7b21986dc..f11aecce3c 100644 --- a/libavformat/flacdec.c +++ b/libavformat/flacdec.c @@ -40,8 +40,8 @@ static void reset_index_position(int64_t metadata_head_size, AVStream *st) { /* the real seek index offset should be the size of metadata blocks with the offset in the frame blocks */ int i; - for(i=0; iinternal->nb_index_entries; i++) { - st->internal->index_entries[i].pos += metadata_head_size; + for(i=0; inb_index_entries; i++) { + st->index_entries[i].pos += metadata_head_size; } } @@ -68,7 +68,7 @@ static int flac_read_header(AVFormatContext *s) /* process metadata blocks */ while (!avio_feof(s->pb) && !metadata_last) { if (avio_read(s->pb, header, 4) != 4) - return AVERROR(AVERROR_INVALIDDATA); + return AVERROR_INVALIDDATA; flac_parse_block_header(header, &metadata_last, &metadata_type, &metadata_size); switch (metadata_type) { @@ -318,10 +318,10 @@ static int flac_seek(AVFormatContext *s, int stream_index, int64_t timestamp, in } index = av_index_search_timestamp(s->streams[0], timestamp, flags); - if(index<0 || index >= s->streams[0]->internal->nb_index_entries) + if(index<0 || index >= s->streams[0]->nb_index_entries) return -1; - e = s->streams[0]->internal->index_entries[index]; + e = s->streams[0]->index_entries[index]; pos = avio_seek(s->pb, e.pos, SEEK_SET); if (pos >= 0) { return 0; diff --git a/libavformat/flic.c b/libavformat/flic.c index 9a7b8081ed..4552bff69c 100644 --- a/libavformat/flic.c +++ b/libavformat/flic.c @@ -268,7 +268,7 @@ static int flic_read_seek(AVFormatContext *s, int stream_index, int64_t pos, ts; int index; - if (!st->internal->index_entries || stream_index != flic->video_stream_index) + if (!st->index_entries || stream_index != flic->video_stream_index) return -1; index = av_index_search_timestamp(st, pts, flags); @@ -278,8 +278,8 @@ static int flic_read_seek(AVFormatContext *s, int stream_index, if (index < 0) return -1; - pos = st->internal->index_entries[index].pos; - ts = st->internal->index_entries[index].timestamp; + pos = st->index_entries[index].pos; + ts = st->index_entries[index].timestamp; flic->frame_number = ts; avio_seek(s->pb, pos, SEEK_SET); return 0; diff --git a/libavformat/flvdec.c b/libavformat/flvdec.c index e4b40a195c..4a1c01a714 100644 --- a/libavformat/flvdec.c +++ b/libavformat/flvdec.c @@ -64,7 +64,7 @@ typedef struct FLVContext { uint8_t resync_buffer[2*RESYNC_BUFFER_SIZE]; int broken_sizes; - int sum_flv_tag_size; + int64_t sum_flv_tag_size; int last_keyframe_stream_index; int keyframe_count; @@ -142,7 +142,7 @@ static void add_keyframes_index(AVFormatContext *s) av_assert0(flv->last_keyframe_stream_index <= s->nb_streams); stream = s->streams[flv->last_keyframe_stream_index]; - if (stream->internal->nb_index_entries == 0) { + if (stream->nb_index_entries == 0) { for (i = 0; i < flv->keyframe_count; i++) { av_log(s, AV_LOG_TRACE, "keyframe filepositions = %"PRId64" times = %"PRId64"\n", flv->keyframe_filepositions[i], flv->keyframe_times[i] * 1000); @@ -459,6 +459,10 @@ static int parse_keyframes_index(AVFormatContext *s, AVIOContext *ioc, int64_t m d = av_int2double(avio_rb64(ioc)); if (isnan(d) || d < INT64_MIN || d > INT64_MAX) goto invalid; + if (current_array == × && (d <= INT64_MIN / 1000 || d >= INT64_MAX / 1000)) + goto invalid; + if (avio_feof(ioc)) + goto invalid; current_array[0][i] = d; } if (times && filepositions) { @@ -844,10 +848,10 @@ static void clear_index_entries(AVFormatContext *s, int64_t pos) AVStream *st = s->streams[i]; /* Remove all index entries that point to >= pos */ out = 0; - for (j = 0; j < st->internal->nb_index_entries; j++) - if (st->internal->index_entries[j].pos < pos) - st->internal->index_entries[out++] = st->internal->index_entries[j]; - st->internal->nb_index_entries = out; + for (j = 0; j < st->nb_index_entries; j++) + if (st->index_entries[j].pos < pos) + st->index_entries[out++] = st->index_entries[j]; + st->nb_index_entries = out; } } @@ -875,6 +879,8 @@ static int amf_skip_tag(AVIOContext *pb, AMFDataType type, int depth) parse_name = 0; case AMF_DATA_TYPE_MIXEDARRAY: nb = avio_rb32(pb); + if (nb < 0) + return AVERROR_INVALIDDATA; case AMF_DATA_TYPE_OBJECT: while(!pb->eof_reached && (nb-- > 0 || type != AMF_DATA_TYPE_ARRAY)) { if (parse_name) { @@ -1027,7 +1033,7 @@ retry: type = (avio_r8(s->pb) & 0x1F); orig_size = size = avio_rb24(s->pb); - flv->sum_flv_tag_size += size + 11; + flv->sum_flv_tag_size += size + 11LL; dts = avio_rb24(s->pb); dts |= (unsigned)avio_r8(s->pb) << 24; av_log(s, AV_LOG_TRACE, "type:%d, size:%d, last:%d, dts:%"PRId64" pos:%"PRId64"\n", type, size, last, dts, avio_tell(s->pb)); @@ -1329,7 +1335,7 @@ leave: !avio_feof(s->pb) && (last != orig_size || !last) && last != flv->sum_flv_tag_size && !flv->broken_sizes) { - av_log(s, AV_LOG_ERROR, "Packet mismatch %d %d %d\n", last, orig_size + 11, flv->sum_flv_tag_size); + av_log(s, AV_LOG_ERROR, "Packet mismatch %d %d %"PRId64"\n", last, orig_size + 11, flv->sum_flv_tag_size); avio_seek(s->pb, pos + 1, SEEK_SET); ret = resync(s); av_packet_unref(pkt); diff --git a/libavformat/format.c b/libavformat/format.c index c47490c8eb..ed46773cca 100644 --- a/libavformat/format.c +++ b/libavformat/format.c @@ -48,6 +48,31 @@ int av_match_ext(const char *filename, const char *extensions) return 0; } +int ff_match_url_ext(const char *url, const char *extensions) +{ + const char *ext; + URLComponents uc; + int ret; + char scratchpad[128]; + + if (!url) + return 0; + + ret = ff_url_decompose(&uc, url, NULL); + if (ret < 0 || !URL_COMPONENT_HAVE(uc, scheme)) + return ret; + for (ext = uc.query; *ext != '.' && ext > uc.path; ext--) + ; + + if (*ext != '.') + return 0; + if (uc.query - ext > sizeof(scratchpad)) + return AVERROR(ENOMEM); //not enough memory in our scratchpad + av_strlcpy(scratchpad, ext + 1, FFMIN(sizeof(scratchpad), uc.query - ext)); + + return av_match_name(scratchpad, extensions); +} + ff_const59 AVOutputFormat *av_guess_format(const char *short_name, const char *filename, const char *mime_type) { @@ -228,6 +253,7 @@ int av_probe_input_buffer2(AVIOContext *pb, ff_const59 AVInputFormat **fmt, int ret = 0, probe_size, buf_offset = 0; int score = 0; int ret2; + int eof = 0; if (!max_probe_size) max_probe_size = PROBE_BUF_MAX; @@ -251,7 +277,7 @@ int av_probe_input_buffer2(AVIOContext *pb, ff_const59 AVInputFormat **fmt, } } - for (probe_size = PROBE_BUF_MIN; probe_size <= max_probe_size && !*fmt; + for (probe_size = PROBE_BUF_MIN; probe_size <= max_probe_size && !*fmt && !eof; probe_size = FFMIN(probe_size << 1, FFMAX(max_probe_size, probe_size + 1))) { score = probe_size < max_probe_size ? AVPROBE_SCORE_RETRY : 0; @@ -267,6 +293,7 @@ int av_probe_input_buffer2(AVIOContext *pb, ff_const59 AVInputFormat **fmt, score = 0; ret = 0; /* error was end of file, nothing read */ + eof = 1; } buf_offset += ret; if (buf_offset < offset) diff --git a/libavformat/ftp.c b/libavformat/ftp.c index caeea42920..69caa7670c 100644 --- a/libavformat/ftp.c +++ b/libavformat/ftp.c @@ -972,6 +972,8 @@ static int ftp_parse_entry_mlsd(char *mlsd, AVIODirEntry *next) continue; } fact = av_strtok(fact, "=", &value); + if (!fact) + continue; if (!av_strcasecmp(fact, "type")) { if (!av_strcasecmp(value, "cdir") || !av_strcasecmp(value, "pdir")) return 1; diff --git a/libavformat/fwse.c b/libavformat/fwse.c index 00e2e13b11..2fecd68e56 100644 --- a/libavformat/fwse.c +++ b/libavformat/fwse.c @@ -67,7 +67,7 @@ static int fwse_read_header(AVFormatContext *s) par->channel_layout = AV_CH_LAYOUT_STEREO; st->duration = avio_rl32(pb); par->sample_rate = avio_rl32(pb); - if (par->sample_rate <= 0 || par->sample_rate > INT_MAX) + if (par->sample_rate <= 0) return AVERROR_INVALIDDATA; par->block_align = 1; diff --git a/libavformat/genh.c b/libavformat/genh.c index 698104a9d6..0b55a8884a 100644 --- a/libavformat/genh.c +++ b/libavformat/genh.c @@ -67,6 +67,9 @@ static int genh_read_header(AVFormatContext *s) return AVERROR_INVALIDDATA; st->codecpar->block_align = align * st->codecpar->channels; st->codecpar->sample_rate = avio_rl32(s->pb); + if (st->codecpar->sample_rate < 0) + return AVERROR_INVALIDDATA; + avio_skip(s->pb, 4); st->duration = avio_rl32(s->pb); diff --git a/libavformat/gxf.c b/libavformat/gxf.c index b787d4f521..bbad47c240 100644 --- a/libavformat/gxf.c +++ b/libavformat/gxf.c @@ -575,9 +575,9 @@ static int gxf_seek(AVFormatContext *s, int stream_index, int64_t timestamp, int AVSEEK_FLAG_ANY | AVSEEK_FLAG_BACKWARD); if (idx < 0) return -1; - pos = st->internal->index_entries[idx].pos; - if (idx < st->internal->nb_index_entries - 2) - maxlen = st->internal->index_entries[idx + 2].pos - pos; + pos = st->index_entries[idx].pos; + if (idx < st->nb_index_entries - 2) + maxlen = st->index_entries[idx + 2].pos - pos; maxlen = FFMAX(maxlen, 200 * 1024); res = avio_seek(s->pb, pos, SEEK_SET); if (res < 0) diff --git a/libavformat/hls.c b/libavformat/hls.c index 597bea7f25..d22d06c5ae 100644 --- a/libavformat/hls.c +++ b/libavformat/hls.c @@ -208,6 +208,8 @@ typedef struct HLSContext { AVIOInterruptCB *interrupt_callback; AVDictionary *avio_opts; char *allowed_extensions; + char *allowed_segment_extensions; + int extension_picky; int max_reload; int http_persistent; int http_multiple; @@ -236,6 +238,7 @@ static void free_init_section_list(struct playlist *pls) { int i; for (i = 0; i < pls->n_init_sections; i++) { + av_freep(&pls->init_sections[i]->key); av_freep(&pls->init_sections[i]->url); av_freep(&pls->init_sections[i]); } @@ -708,6 +711,50 @@ static int open_url(AVFormatContext *s, AVIOContext **pb, const char *url, return ret; } +static int test_segment(AVFormatContext *s, const AVInputFormat *in_fmt, struct playlist *pls, struct segment *seg) +{ + HLSContext *c = s->priv_data; + int matchA = 3; + int matchF = 0; + + if (!c->extension_picky) + return 0; + + if (strcmp(c->allowed_segment_extensions, "ALL")) + matchA = av_match_ext (seg->url, c->allowed_segment_extensions) + + 2*(ff_match_url_ext(seg->url, c->allowed_segment_extensions) > 0); + + if (!matchA) { + av_log(s, AV_LOG_ERROR, "URL %s is not in allowed_segment_extensions\n", seg->url); + return AVERROR_INVALIDDATA; + } + + if (in_fmt) { + if (in_fmt->extensions) { + matchF = av_match_ext( seg->url, in_fmt->extensions) + + 2*(ff_match_url_ext(seg->url, in_fmt->extensions) > 0); + // Youtube uses aac files with .ts extension + if(av_match_name("mp4", in_fmt->name) || av_match_name("aac", in_fmt->name)) { + matchF |= av_match_ext( seg->url, "ts,m2t,m2ts,mts,mpg,m4s,mpeg,mpegts") + + 2*(ff_match_url_ext(seg->url, "ts,m2t,m2ts,mts,mpg,m4s,mpeg,mpegts") > 0); + } + } else if (!strcmp(in_fmt->name, "mpegts")) { + const char *str = "ts,m2t,m2ts,mts,mpg,m4s,mpeg,mpegts" + ",html" // https://flash1.bogulus.cfd/ + ; + matchF = av_match_ext( seg->url, str) + + 2*(ff_match_url_ext(seg->url, str) > 0); + } + + if (!(matchA & matchF)) { + av_log(s, AV_LOG_ERROR, "detected format %s extension %s mismatches allowed extensions in url %s\n", in_fmt->name, in_fmt->extensions ? in_fmt->extensions : "none", seg->url); + return AVERROR_INVALIDDATA; + } + } + + return 0; +} + static int parse_playlist(HLSContext *c, const char *url, struct playlist *pls, AVIOContext *in) { @@ -810,20 +857,26 @@ static int parse_playlist(HLSContext *c, const char *url, &info); new_rendition(c, &info, url); } else if (av_strstart(line, "#EXT-X-TARGETDURATION:", &ptr)) { + int64_t t; ret = ensure_playlist(c, &pls, url); if (ret < 0) goto fail; - pls->target_duration = strtoll(ptr, NULL, 10) * AV_TIME_BASE; + t = strtoll(ptr, NULL, 10); + if (t < 0 || t >= INT64_MAX / AV_TIME_BASE) { + ret = AVERROR_INVALIDDATA; + goto fail; + } + pls->target_duration = t * AV_TIME_BASE; } else if (av_strstart(line, "#EXT-X-MEDIA-SEQUENCE:", &ptr)) { uint64_t seq_no; ret = ensure_playlist(c, &pls, url); if (ret < 0) goto fail; seq_no = strtoull(ptr, NULL, 10); - if (seq_no > INT64_MAX) { + if (seq_no > INT64_MAX/2) { av_log(c->ctx, AV_LOG_DEBUG, "MEDIA-SEQUENCE higher than " - "INT64_MAX, mask out the highest bit\n"); - seq_no &= INT64_MAX; + "INT64_MAX/2, mask out the highest bit\n"); + seq_no &= INT64_MAX/2; } pls->start_seq_no = seq_no; } else if (av_strstart(line, "#EXT-X-PLAYLIST-TYPE:", &ptr)) { @@ -903,7 +956,7 @@ static int parse_playlist(HLSContext *c, const char *url, if (has_iv) { memcpy(seg->iv, iv, sizeof(iv)); } else { - int64_t seq = pls->start_seq_no + pls->n_segments; + uint64_t seq = pls->start_seq_no + (uint64_t)pls->n_segments; memset(seg->iv, 0, sizeof(seg->iv)); AV_WB64(seg->iv + 8, seq); } @@ -941,6 +994,14 @@ static int parse_playlist(HLSContext *c, const char *url, goto fail; } + ret = test_segment(c->ctx, pls->ctx ? pls->ctx->iformat : NULL, pls, seg); + if (ret < 0) { + av_free(seg->url); + av_free(seg->key); + av_free(seg); + goto fail; + } + if (duration < 0.001 * AV_TIME_BASE) { av_log(c->ctx, AV_LOG_WARNING, "Cannot get correct #EXTINF value of segment %s," " set to default value to 1ms.\n", seg->url); @@ -1994,6 +2055,11 @@ static int hls_read_header(AVFormatContext *s) pls->ctx->interrupt_callback = s->interrupt_callback; url = av_strdup(pls->segments[0]->url); ret = av_probe_input_buffer(&pls->pb, &in_fmt, url, NULL, 0, 0); + + for (int n = 0; n < pls->n_segments; n++) + if (ret >= 0) + ret = test_segment(s, in_fmt, pls, pls->segments[n]); + if (ret < 0) { /* Free the ctx - it isn't initialized properly at this point, * so avformat_close_input shouldn't be called. If @@ -2387,10 +2453,25 @@ static const AVOption hls_options[] = { OFFSET(live_start_index), AV_OPT_TYPE_INT, {.i64 = -3}, INT_MIN, INT_MAX, FLAGS}, {"allowed_extensions", "List of file extensions that hls is allowed to access", OFFSET(allowed_extensions), AV_OPT_TYPE_STRING, - {.str = "3gp,aac,avi,ac3,eac3,flac,mkv,m3u8,m4a,m4s,m4v,mpg,mov,mp2,mp3,mp4,mpeg,mpegts,ogg,ogv,oga,ts,vob,wav"}, + {.str = "3gp,aac,avi,ac3,eac3,flac,mkv,m3u8,m4a,m4s,m4v,mpg,mov,mp2,mp3,mp4,mpeg,mpegts,ogg,ogv,oga,ts,vob,vtt,wav,webvtt" + ",cmfv,cmfa" // Ticket11526 www.nicovideo.jp + ",ec3" // part of Ticket11435 (Elisa Viihde (Finnish online recording service)) + ",fmp4" // https://github.com/yt-dlp/yt-dlp/issues/12700 + }, INT_MIN, INT_MAX, FLAGS}, + {"allowed_segment_extensions", "List of file extensions that hls is allowed to access", + OFFSET(allowed_segment_extensions), AV_OPT_TYPE_STRING, + {.str = "3gp,aac,avi,ac3,eac3,flac,mkv,m3u8,m4a,m4s,m4v,mpg,mov,mp2,mp3,mp4,mpeg,mpegts,ogg,ogv,oga,ts,vob,vtt,wav,webvtt" + ",cmfv,cmfa" // Ticket11526 www.nicovideo.jp + ",ec3" // part of Ticket11435 (Elisa Viihde (Finnish online recording service)) + ",fmp4" // https://github.com/yt-dlp/yt-dlp/issues/12700 + ",html" // https://flash1.bogulus.cfd/ + }, + INT_MIN, INT_MAX, FLAGS}, + {"extension_picky", "Be picky with all extensions matching", + OFFSET(extension_picky), AV_OPT_TYPE_BOOL, {.i64 = 1}, 0, 1, FLAGS}, {"max_reload", "Maximum number of times a insufficient list is attempted to be reloaded", - OFFSET(max_reload), AV_OPT_TYPE_INT, {.i64 = 1000}, 0, INT_MAX, FLAGS}, + OFFSET(max_reload), AV_OPT_TYPE_INT, {.i64 = 100}, 0, INT_MAX, FLAGS}, {"m3u8_hold_counters", "The maximum number of times to load m3u8 when it refreshes without new segments", OFFSET(m3u8_hold_counters), AV_OPT_TYPE_INT, {.i64 = 1000}, 0, INT_MAX, FLAGS}, {"http_persistent", "Use persistent HTTP connections", diff --git a/libavformat/hlsenc.c b/libavformat/hlsenc.c index 7d97ce1789..3f3ab8844d 100644 --- a/libavformat/hlsenc.c +++ b/libavformat/hlsenc.c @@ -412,8 +412,11 @@ static void write_codec_attr(AVStream *st, VariantStream *vs) } else if (st->codecpar->codec_id == AV_CODEC_ID_MP3) { snprintf(attr, sizeof(attr), "mp4a.40.34"); } else if (st->codecpar->codec_id == AV_CODEC_ID_AAC) { - /* TODO : For HE-AAC, HE-AACv2, the last digit needs to be set to 5 and 29 respectively */ - snprintf(attr, sizeof(attr), "mp4a.40.2"); + if (st->codecpar->profile != FF_PROFILE_UNKNOWN) + snprintf(attr, sizeof(attr), "mp4a.40.%d", st->codecpar->profile+1); + else + // This is for backward compatibility with the previous implementation. + snprintf(attr, sizeof(attr), "mp4a.40.2"); } else if (st->codecpar->codec_id == AV_CODEC_ID_AC3) { snprintf(attr, sizeof(attr), "ac-3"); } else if (st->codecpar->codec_id == AV_CODEC_ID_EAC3) { @@ -2593,8 +2596,10 @@ static int hls_write_packet(AVFormatContext *s, AVPacket *pkt) " will retry with a new http session.\n"); ff_format_io_close(s, &vs->out); ret = hlsenc_io_open(s, &vs->out, filename, &options); - reflush_dynbuf(vs, &range_length); - ret = hlsenc_io_close(s, &vs->out, filename); + if (ret >= 0) { + reflush_dynbuf(vs, &range_length); + ret = hlsenc_io_close(s, &vs->out, filename); + } } av_dict_free(&options); av_freep(&vs->temp_buffer); @@ -2605,6 +2610,9 @@ static int hls_write_packet(AVFormatContext *s, AVPacket *pkt) hls_rename_temp_file(s, oc); } + if (ret < 0) + return ret; + old_filename = av_strdup(oc->url); if (!old_filename) { return AVERROR(ENOMEM); @@ -2672,14 +2680,13 @@ static int hls_write_packet(AVFormatContext *s, AVPacket *pkt) vs->packets_written++; if (oc->pb) { - int64_t keyframe_pre_pos = avio_tell(oc->pb); ret = ff_write_chained(oc, stream_index, pkt, s, 0); - if ((st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) && - (pkt->flags & AV_PKT_FLAG_KEY) && !keyframe_pre_pos) { - av_write_frame(oc, NULL); /* Flush any buffered data */ - vs->video_keyframe_size = avio_tell(oc->pb) - keyframe_pre_pos; + vs->video_keyframe_size += pkt->size; + if ((st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) && (pkt->flags & AV_PKT_FLAG_KEY)) { + vs->video_keyframe_size = avio_tell(oc->pb); + } else { + vs->video_keyframe_pos = avio_tell(vs->out); } - vs->video_keyframe_pos = vs->start_pos; if (hls->ignore_io_errors) ret = 0; } diff --git a/libavformat/hnm.c b/libavformat/hnm.c index f06add5cf8..2cec5cb876 100644 --- a/libavformat/hnm.c +++ b/libavformat/hnm.c @@ -113,6 +113,8 @@ static int hnm_read_packet(AVFormatContext *s, AVPacket *pkt) if (hnm->superchunk_remaining == 0) { /* parse next superchunk */ superchunk_size = avio_rl24(pb); + if (superchunk_size < 4) + return AVERROR_INVALIDDATA; avio_skip(pb, 1); hnm->superchunk_remaining = superchunk_size - 4; @@ -123,7 +125,7 @@ static int hnm_read_packet(AVFormatContext *s, AVPacket *pkt) chunk_id = avio_rl16(pb); avio_skip(pb, 2); - if (chunk_size > hnm->superchunk_remaining || !chunk_size) { + if (chunk_size > hnm->superchunk_remaining || chunk_size < 8) { av_log(s, AV_LOG_ERROR, "invalid chunk size: %"PRIu32", offset: %"PRId64"\n", chunk_size, avio_tell(pb)); diff --git a/libavformat/icodec.c b/libavformat/icodec.c index 93179bb41e..128a495948 100644 --- a/libavformat/icodec.c +++ b/libavformat/icodec.c @@ -203,6 +203,9 @@ static int read_packet(AVFormatContext *s, AVPacket *pkt) AV_WL32(buf + 32, image->nb_pal); } + if (image->nb_pal > INT_MAX / 4 - 14 - 40U) + return AVERROR_INVALIDDATA; + AV_WL32(buf - 4, 14 + 40 + image->nb_pal * 4); AV_WL32(buf + 8, AV_RL32(buf + 8) / 2); } diff --git a/libavformat/id3v2.c b/libavformat/id3v2.c index f33b7ba93a..9398897873 100644 --- a/libavformat/id3v2.c +++ b/libavformat/id3v2.c @@ -365,7 +365,7 @@ static void read_uslt(AVFormatContext *s, AVIOContext *pb, int taglen, int encoding; int ok = 0; - if (taglen < 1) + if (taglen < 4) goto error; encoding = avio_r8(pb); @@ -376,10 +376,10 @@ static void read_uslt(AVFormatContext *s, AVIOContext *pb, int taglen, lang[3] = '\0'; taglen -= 3; - if (decode_str(s, pb, encoding, &descriptor, &taglen) < 0) + if (decode_str(s, pb, encoding, &descriptor, &taglen) < 0 || taglen < 0) goto error; - if (decode_str(s, pb, encoding, &text, &taglen) < 0) + if (decode_str(s, pb, encoding, &text, &taglen) < 0 || taglen < 0) goto error; // FFmpeg does not support hierarchical metadata, so concatenate the keys. @@ -816,7 +816,7 @@ static void id3v2_parse(AVIOContext *pb, AVDictionary **metadata, int isv34, unsync; unsigned tlen; char tag[5]; - int64_t next, end = avio_tell(pb) + len; + int64_t next, end = avio_tell(pb); int taghdrlen; const char *reason = NULL; AVIOContext pb_local; @@ -828,6 +828,10 @@ static void id3v2_parse(AVIOContext *pb, AVDictionary **metadata, av_unused int uncompressed_buffer_size = 0; const char *comm_frame; + if (end > INT64_MAX - len - 10) + return; + end += len; + av_log(s, AV_LOG_DEBUG, "id3v2 ver:%d flags:%02X len:%d\n", version, flags, len); switch (version) { diff --git a/libavformat/iff.c b/libavformat/iff.c index b07b6c8b18..4a46b4b393 100644 --- a/libavformat/iff.c +++ b/libavformat/iff.c @@ -217,7 +217,7 @@ static int parse_dsd_diin(AVFormatContext *s, AVStream *st, uint64_t eof) { AVIOContext *pb = s->pb; - while (avio_tell(pb) + 12 <= eof && !avio_feof(pb)) { + while (av_sat_add64(avio_tell(pb), 12) <= eof && !avio_feof(pb)) { uint32_t tag = avio_rl32(pb); uint64_t size = avio_rb64(pb); uint64_t orig_pos = avio_tell(pb); @@ -254,7 +254,7 @@ static int parse_dsd_prop(AVFormatContext *s, AVStream *st, uint64_t eof) int dsd_layout[6]; ID3v2ExtraMeta *id3v2_extra_meta; - while (avio_tell(pb) + 12 <= eof && !avio_feof(pb)) { + while (av_sat_add64(avio_tell(pb), 12) <= eof && !avio_feof(pb)) { uint32_t tag = avio_rl32(pb); uint64_t size = avio_rb64(pb); uint64_t orig_pos = avio_tell(pb); @@ -359,6 +359,9 @@ static int read_dst_frame(AVFormatContext *s, AVPacket *pkt) uint64_t chunk_pos, data_pos, data_size; int ret = AVERROR_EOF; + if (s->nb_streams < 1) + return AVERROR_INVALIDDATA; + while (!avio_feof(pb)) { chunk_pos = avio_tell(pb); if (chunk_pos >= iff->body_end) @@ -385,7 +388,7 @@ static int read_dst_frame(AVFormatContext *s, AVPacket *pkt) avio_skip(pb, 1); pkt->flags |= AV_PKT_FLAG_KEY; pkt->stream_index = 0; - pkt->duration = 588 * s->streams[0]->codecpar->sample_rate / 44100; + pkt->duration = s->streams[0]->codecpar->sample_rate / 75; pkt->pos = chunk_pos; chunk_pos = avio_tell(pb); @@ -398,7 +401,8 @@ static int read_dst_frame(AVFormatContext *s, AVPacket *pkt) case ID_FRTE: if (data_size < 4) return AVERROR_INVALIDDATA; - s->streams[0]->duration = avio_rb32(pb) * 588LL * s->streams[0]->codecpar->sample_rate / 44100; + s->streams[0]->duration = avio_rb32(pb) * (uint64_t)s->streams[0]->codecpar->sample_rate / 75; + break; } @@ -501,6 +505,9 @@ static int iff_read_header(AVFormatContext *s) case ID_DST: case ID_MDAT: iff->body_pos = avio_tell(pb); + if (iff->body_pos < 0 || iff->body_pos + data_size > INT64_MAX) + return AVERROR_INVALIDDATA; + iff->body_end = iff->body_pos + data_size; iff->body_size = data_size; if (chunk_id == ID_DST) { diff --git a/libavformat/ifv.c b/libavformat/ifv.c index bca8f85d09..4e904fa828 100644 --- a/libavformat/ifv.c +++ b/libavformat/ifv.c @@ -195,15 +195,15 @@ static int ifv_read_packet(AVFormatContext *s, AVPacket *pkt) if (ifv->next_video_index < ifv->total_vframes) { st = s->streams[ifv->video_stream_index]; - if (ifv->next_video_index < st->internal->nb_index_entries) - e_next = ev = &st->internal->index_entries[ifv->next_video_index]; + if (ifv->next_video_index < st->nb_index_entries) + e_next = ev = &st->index_entries[ifv->next_video_index]; } if (ifv->is_audio_present && ifv->next_audio_index < ifv->total_aframes) { st = s->streams[ifv->audio_stream_index]; - if (ifv->next_audio_index < st->internal->nb_index_entries) { - ea = &st->internal->index_entries[ifv->next_audio_index]; + if (ifv->next_audio_index < st->nb_index_entries) { + ea = &st->index_entries[ifv->next_audio_index]; if (!ev || ea->timestamp < ev->timestamp) e_next = ea; } diff --git a/libavformat/ilbc.c b/libavformat/ilbc.c index 188c0f091a..723fd926bc 100644 --- a/libavformat/ilbc.c +++ b/libavformat/ilbc.c @@ -68,7 +68,8 @@ static int ilbc_read_header(AVFormatContext *s) AVStream *st; uint8_t header[9]; - avio_read(pb, header, 9); + if (avio_read(pb, header, 9) != 9) + return AVERROR_INVALIDDATA; st = avformat_new_stream(s, NULL); if (!st) diff --git a/libavformat/img2dec.c b/libavformat/img2dec.c index be7149bb2f..e4cf1f6b7a 100644 --- a/libavformat/img2dec.c +++ b/libavformat/img2dec.c @@ -23,6 +23,7 @@ #define _DEFAULT_SOURCE #define _BSD_SOURCE #include +#include "libavutil/avassert.h" #include "libavutil/avstring.h" #include "libavutil/log.h" #include "libavutil/opt.h" @@ -497,6 +498,7 @@ int ff_img_read_packet(AVFormatContext *s1, AVPacket *pkt) pkt->flags |= AV_PKT_FLAG_KEY; if (s->ts_from_file) { struct stat img_stat; + av_assert0(!s->is_pipe); // The ts_from_file option is not supported by piped input demuxers if (stat(filename, &img_stat)) { res = AVERROR(EIO); goto fail; @@ -554,6 +556,7 @@ int ff_img_read_packet(AVFormatContext *s1, AVPacket *pkt) } goto fail; } else { + memset(pkt->data + pkt->size, 0, AV_INPUT_BUFFER_PADDING_SIZE); s->img_count++; s->img_number++; s->pts++; @@ -590,7 +593,7 @@ static int img_read_seek(AVFormatContext *s, int stream_index, int64_t timestamp int index = av_index_search_timestamp(st, timestamp, flags); if(index < 0) return -1; - s1->img_number = st->internal->index_entries[index].pos; + s1->img_number = st->index_entries[index].pos; return 0; } @@ -787,7 +790,6 @@ static int jpeg_probe(const AVProbeData *p) return 0; state = EOI; break; - case DQT: case APP0: case APP1: case APP2: @@ -804,6 +806,7 @@ static int jpeg_probe(const AVProbeData *p) case APP13: case APP14: case APP15: + case DQT: /* fallthrough */ case COM: i += AV_RB16(&b[i + 2]) + 1; break; diff --git a/libavformat/imx.c b/libavformat/imx.c index d203ed7a28..22fca0bdc0 100644 --- a/libavformat/imx.c +++ b/libavformat/imx.c @@ -113,6 +113,8 @@ retry: imx->first_video_packet_pos = pos; break; case 0xAA98: + if (chunk_size > 256 * 3) + return AVERROR_INVALIDDATA; for (int i = 0; i < chunk_size / 3; i++) { unsigned r = avio_r8(pb) << 18; unsigned g = avio_r8(pb) << 10; diff --git a/libavformat/internal.h b/libavformat/internal.h index 3c6b2921c1..e8b6105427 100644 --- a/libavformat/internal.h +++ b/libavformat/internal.h @@ -236,11 +236,6 @@ struct AVStreamInternal { } *info; - AVIndexEntry *index_entries; /**< Only used if the format does not - support seeking natively. */ - int nb_index_entries; - unsigned int index_entries_allocated_size; - int64_t interleaver_chunk_size; int64_t interleaver_chunk_duration; @@ -892,6 +887,15 @@ int ff_unlock_avformat(void); */ void ff_format_set_url(AVFormatContext *s, char *url); +/** + * Return a positive value if the given url has one of the given + * extensions, negative AVERROR on error, 0 otherwise. + * + * @param url url to check against the given extensions + * @param extensions a comma-separated list of filename extensions + */ +int ff_match_url_ext(const char *url, const char *extensions); + void avpriv_register_devices(const AVOutputFormat * const o[], const AVInputFormat * const i[]); #endif /* AVFORMAT_INTERNAL_H */ diff --git a/libavformat/ipmovie.c b/libavformat/ipmovie.c index 3234d591da..313973b878 100644 --- a/libavformat/ipmovie.c +++ b/libavformat/ipmovie.c @@ -639,7 +639,8 @@ static int ipmovie_read_header(AVFormatContext *s) ipmovie->avf = s; - avio_read(pb, signature_buffer, sizeof(signature_buffer)); + if (avio_read(pb, signature_buffer, sizeof(signature_buffer)) != sizeof(signature_buffer)) + return AVERROR_INVALIDDATA; while (memcmp(signature_buffer, signature, sizeof(signature))) { memmove(signature_buffer, signature_buffer + 1, sizeof(signature_buffer) - 1); signature_buffer[sizeof(signature_buffer) - 1] = avio_r8(pb); diff --git a/libavformat/jacosubdec.c b/libavformat/jacosubdec.c index b44e3b7783..a0d6b17e32 100644 --- a/libavformat/jacosubdec.c +++ b/libavformat/jacosubdec.c @@ -125,39 +125,42 @@ static const char *read_ts(JACOsubContext *jacosub, const char *buf, return NULL; shift_and_ret: - ts_start64 = (ts_start + jacosub->shift) * 100LL / jacosub->timeres; - ts_end64 = (ts_end + jacosub->shift) * 100LL / jacosub->timeres; + ts_start64 = (ts_start + (int64_t)jacosub->shift) * 100LL / jacosub->timeres; + ts_end64 = (ts_end + (int64_t)jacosub->shift) * 100LL / jacosub->timeres; *start = ts_start64; *duration = ts_end64 - ts_start64; return buf + len; } -static int get_shift(int timeres, const char *buf) +static int get_shift(unsigned timeres, const char *buf) { int sign = 1; - int a = 0, b = 0, c = 0, d = 0; + int h = 0, m = 0, s = 0, d = 0; int64_t ret; #define SSEP "%*1[.:]" - int n = sscanf(buf, "%d"SSEP"%d"SSEP"%d"SSEP"%d", &a, &b, &c, &d); + int n = sscanf(buf, "%d"SSEP"%d"SSEP"%d"SSEP"%d", &h, &m, &s, &d); #undef SSEP - if (*buf == '-' || a < 0) { + if (h == INT_MIN) + return 0; + + if (*buf == '-' || h < 0) { sign = -1; - a = FFABS(a); + h = FFABS(h); } ret = 0; switch (n) { - case 4: - ret = sign * (((int64_t)a*3600 + b*60 + c) * timeres + d); - break; - case 3: - ret = sign * (( (int64_t)a*60 + b) * timeres + c); - break; - case 2: - ret = sign * (( (int64_t)a) * timeres + b); - break; + case 1: h = 0; //clear all in case of a single parameter + case 2: s = m; m = h; h = 0; //shift into second subsecondd + case 3: d = s; s = m; m = h; h = 0; //shift into minute second subsecond } + + ret = (int64_t)h*3600 + (int64_t)m*60 + s; + if (FFABS(ret) > (INT64_MAX - FFABS((int64_t)d)) / timeres) + return 0; + ret = sign * (ret * timeres + d); + if ((int)ret != ret) ret = 0; @@ -199,6 +202,7 @@ static int jacosub_read_header(AVFormatContext *s) sub = ff_subtitles_queue_insert(&jacosub->q, line, len, merge_line); if (!sub) { + av_bprint_finalize(&header, NULL); ret = AVERROR(ENOMEM); goto fail; } @@ -232,14 +236,17 @@ static int jacosub_read_header(AVFormatContext *s) } av_bprintf(&header, "#S %s", p); break; - case 'T': // ...but must be placed after TIMERES - jacosub->timeres = strtol(p, NULL, 10); - if (!jacosub->timeres) + case 'T': { // ...but must be placed after TIMERES + int64_t timeres = strtol(p, NULL, 10); + if (timeres <= 0 || timeres > UINT32_MAX) { jacosub->timeres = 30; - else + } else { + jacosub->timeres = timeres; av_bprintf(&header, "#T %s", p); + } break; } + } } /* general/essential directives in the extradata */ diff --git a/libavformat/jacosubenc.c b/libavformat/jacosubenc.c index 77575c6b3c..1213a58d52 100644 --- a/libavformat/jacosubenc.c +++ b/libavformat/jacosubenc.c @@ -24,7 +24,7 @@ static int jacosub_write_header(AVFormatContext *s) const AVCodecParameters *par = s->streams[0]->codecpar; if (par->extradata_size) { - avio_write(s->pb, par->extradata, par->extradata_size - 1); + avio_write(s->pb, par->extradata, par->extradata_size); } return 0; } diff --git a/libavformat/jvdec.c b/libavformat/jvdec.c index 47d18e2beb..551f8069e6 100644 --- a/libavformat/jvdec.c +++ b/libavformat/jvdec.c @@ -92,7 +92,7 @@ static int read_header(AVFormatContext *s) vst->codecpar->height = avio_rl16(pb); vst->duration = vst->nb_frames = - ast->internal->nb_index_entries = avio_rl16(pb); + ast->nb_index_entries = avio_rl16(pb); avpriv_set_pts_info(vst, 64, avio_rl16(pb), 1000); avio_skip(pb, 4); @@ -107,19 +107,19 @@ static int read_header(AVFormatContext *s) avio_skip(pb, 10); - ast->internal->index_entries = av_malloc(ast->internal->nb_index_entries * - sizeof(*ast->internal->index_entries)); - if (!ast->internal->index_entries) + ast->index_entries = av_malloc(ast->nb_index_entries * + sizeof(*ast->index_entries)); + if (!ast->index_entries) return AVERROR(ENOMEM); - jv->frames = av_malloc(ast->internal->nb_index_entries * sizeof(JVFrame)); + jv->frames = av_malloc(ast->nb_index_entries * sizeof(JVFrame)); if (!jv->frames) { - av_freep(&ast->internal->index_entries); + av_freep(&ast->index_entries); return AVERROR(ENOMEM); } - offset = 0x68 + ast->internal->nb_index_entries * 16; - for (i = 0; i < ast->internal->nb_index_entries; i++) { - AVIndexEntry *e = ast->internal->index_entries + i; + offset = 0x68 + ast->nb_index_entries * 16; + for (i = 0; i < ast->nb_index_entries; i++) { + AVIndexEntry *e = ast->index_entries + i; JVFrame *jvf = jv->frames + i; /* total frame size including audio, video, palette data and padding */ @@ -139,7 +139,7 @@ static int read_header(AVFormatContext *s) if (s->error_recognition & AV_EF_EXPLODE) { read_close(s); av_freep(&jv->frames); - av_freep(&ast->internal->index_entries); + av_freep(&ast->index_entries); return AVERROR_INVALIDDATA; } jvf->audio_size = @@ -170,8 +170,8 @@ static int read_packet(AVFormatContext *s, AVPacket *pkt) AVStream *ast = s->streams[0]; int ret; - while (!avio_feof(s->pb) && jv->pts < ast->internal->nb_index_entries) { - const AVIndexEntry *e = ast->internal->index_entries + jv->pts; + while (!avio_feof(s->pb) && jv->pts < ast->nb_index_entries) { + const AVIndexEntry *e = ast->index_entries + jv->pts; const JVFrame *jvf = jv->frames + jv->pts; switch (jv->state) { @@ -244,9 +244,9 @@ static int read_seek(AVFormatContext *s, int stream_index, return 0; } - if (i < 0 || i >= ast->internal->nb_index_entries) + if (i < 0 || i >= ast->nb_index_entries) return 0; - if (avio_seek(s->pb, ast->internal->index_entries[i].pos, SEEK_SET) < 0) + if (avio_seek(s->pb, ast->index_entries[i].pos, SEEK_SET) < 0) return -1; jv->state = JV_AUDIO; diff --git a/libavformat/kvag.c b/libavformat/kvag.c index 8f641873b9..64574905f0 100644 --- a/libavformat/kvag.c +++ b/libavformat/kvag.c @@ -31,7 +31,7 @@ typedef struct KVAGHeader { uint32_t magic; uint32_t data_size; - uint32_t sample_rate; + int sample_rate; uint16_t stereo; } KVAGHeader; @@ -65,6 +65,9 @@ static int kvag_read_header(AVFormatContext *s) hdr.sample_rate = AV_RL32(buf + 8); hdr.stereo = AV_RL16(buf + 12); + if (hdr.sample_rate <= 0) + return AVERROR_INVALIDDATA; + par = st->codecpar; par->codec_type = AVMEDIA_TYPE_AUDIO; par->codec_id = AV_CODEC_ID_ADPCM_IMA_SSI; @@ -110,12 +113,22 @@ static int kvag_read_packet(AVFormatContext *s, AVPacket *pkt) return 0; } +static int kvag_seek(AVFormatContext *s, int stream_index, + int64_t pts, int flags) +{ + if (pts != 0) + return AVERROR(EINVAL); + + return avio_seek(s->pb, KVAG_HEADER_SIZE, SEEK_SET); +} + AVInputFormat ff_kvag_demuxer = { .name = "kvag", .long_name = NULL_IF_CONFIG_SMALL("Simon & Schuster Interactive VAG"), .read_probe = kvag_probe, .read_header = kvag_read_header, - .read_packet = kvag_read_packet + .read_packet = kvag_read_packet, + .read_seek = kvag_seek, }; #endif diff --git a/libavformat/libgme.c b/libavformat/libgme.c index e6c56c4872..f9d9abaad5 100644 --- a/libavformat/libgme.c +++ b/libavformat/libgme.c @@ -31,7 +31,6 @@ typedef struct GMEContext { const AVClass *class; Music_Emu *music_emu; - gme_info_t *info; ///< selected track /* options */ int track_index; @@ -55,12 +54,16 @@ static void add_meta(AVFormatContext *s, const char *name, const char *value) av_dict_set(&s->metadata, name, value, 0); } -static int load_metadata(AVFormatContext *s) +static int load_metadata(AVFormatContext *s, int64_t *duration) { GMEContext *gme = s->priv_data; - gme_info_t *info = gme->info; + gme_info_t *info = NULL; char buf[30]; + if (gme_track_info(gme->music_emu, &info, gme->track_index)) + return AVERROR_STREAM_NOT_FOUND; + + *duration = info->length; add_meta(s, "system", info->system); add_meta(s, "game", info->game); add_meta(s, "song", info->song); @@ -71,20 +74,30 @@ static int load_metadata(AVFormatContext *s) snprintf(buf, sizeof(buf), "%d", (int)gme_track_count(gme->music_emu)); add_meta(s, "tracks", buf); + gme_free_info(info); return 0; } #define AUDIO_PKT_SIZE 512 +static int read_close_gme(AVFormatContext *s) +{ + GMEContext *gme = s->priv_data; + gme_delete(gme->music_emu); + return 0; +} + static int read_header_gme(AVFormatContext *s) { AVStream *st; AVIOContext *pb = s->pb; GMEContext *gme = s->priv_data; int64_t sz = avio_size(pb); + int64_t duration; char *buf; char dummy; + int ret; if (sz < 0) { av_log(s, AV_LOG_WARNING, "Could not determine file size\n"); @@ -103,6 +116,7 @@ static int read_header_gme(AVFormatContext *s) av_log(s, AV_LOG_ERROR, "File size is larger than max_size option " "value %"PRIi64", consider increasing the max_size option\n", gme->max_size); + av_freep(&buf); return AVERROR_BUFFER_TOO_SMALL; } @@ -112,20 +126,24 @@ static int read_header_gme(AVFormatContext *s) } av_freep(&buf); - if (gme_track_info(gme->music_emu, &gme->info, gme->track_index)) - return AVERROR_STREAM_NOT_FOUND; - - if (gme_start_track(gme->music_emu, gme->track_index)) + ret = load_metadata(s, &duration); + if (ret < 0) { + read_close_gme(s); + return ret; + } + if (gme_start_track(gme->music_emu, gme->track_index)) { + read_close_gme(s); return AVERROR_UNKNOWN; - - load_metadata(s); + } st = avformat_new_stream(s, NULL); - if (!st) + if (!st) { + read_close_gme(s); return AVERROR(ENOMEM); + } avpriv_set_pts_info(st, 64, 1, 1000); if (st->duration > 0) - st->duration = gme->info->length; + st->duration = duration; st->codecpar->codec_type = AVMEDIA_TYPE_AUDIO; st->codecpar->codec_id = AV_NE(AV_CODEC_ID_PCM_S16BE, AV_CODEC_ID_PCM_S16LE); st->codecpar->channels = 2; @@ -153,14 +171,6 @@ static int read_packet_gme(AVFormatContext *s, AVPacket *pkt) return 0; } -static int read_close_gme(AVFormatContext *s) -{ - GMEContext *gme = s->priv_data; - gme_free_info(gme->info); - gme_delete(gme->music_emu); - return 0; -} - static int read_seek_gme(AVFormatContext *s, int stream_idx, int64_t ts, int flags) { GMEContext *gme = s->priv_data; diff --git a/libavformat/libmodplug.c b/libavformat/libmodplug.c index 6e567f5f98..b85269341b 100644 --- a/libavformat/libmodplug.c +++ b/libavformat/libmodplug.c @@ -99,6 +99,14 @@ static const AVOption options[] = { {NULL}, }; +static int modplug_read_close(AVFormatContext *s) +{ + ModPlugContext *modplug = s->priv_data; + ModPlug_Unload(modplug->f); + av_freep(&modplug->buf); + return 0; +} + #define SET_OPT_IF_REQUESTED(libopt, opt, flag) do { \ if (modplug->opt) { \ settings.libopt = modplug->opt; \ @@ -168,6 +176,7 @@ static int modplug_read_header(AVFormatContext *s) ModPlug_Settings settings; ModPlugContext *modplug = s->priv_data; int64_t sz = avio_size(pb); + int ret; if (sz < 0) { av_log(s, AV_LOG_WARNING, "Could not determine file size\n"); @@ -221,8 +230,10 @@ static int modplug_read_header(AVFormatContext *s) return AVERROR_INVALIDDATA; } st = avformat_new_stream(s, NULL); - if (!st) - return AVERROR(ENOMEM); + if (!st) { + ret = AVERROR(ENOMEM); + goto fail; + } avpriv_set_pts_info(st, 64, 1, 1000); st->duration = ModPlug_GetLength(modplug->f); st->codecpar->codec_type = AVMEDIA_TYPE_AUDIO; @@ -235,8 +246,10 @@ static int modplug_read_header(AVFormatContext *s) if (modplug->video_stream) { AVStream *vst = avformat_new_stream(s, NULL); - if (!vst) - return AVERROR(ENOMEM); + if (!vst) { + ret = AVERROR(ENOMEM); + goto fail; + } avpriv_set_pts_info(vst, 64, 1, 1000); vst->duration = st->duration; vst->codecpar->codec_type = AVMEDIA_TYPE_VIDEO; @@ -247,7 +260,13 @@ static int modplug_read_header(AVFormatContext *s) modplug->fsize = modplug->linesize * modplug->h; } - return modplug_load_metadata(s); + ret = modplug_load_metadata(s); + if (ret < 0) + goto fail; + return 0; +fail: + modplug_read_close(s); + return ret; } static void write_text(uint8_t *dst, const char *s, int linesize, int x, int y) @@ -332,14 +351,6 @@ static int modplug_read_packet(AVFormatContext *s, AVPacket *pkt) return 0; } -static int modplug_read_close(AVFormatContext *s) -{ - ModPlugContext *modplug = s->priv_data; - ModPlug_Unload(modplug->f); - av_freep(&modplug->buf); - return 0; -} - static int modplug_read_seek(AVFormatContext *s, int stream_idx, int64_t ts, int flags) { ModPlugContext *modplug = s->priv_data; diff --git a/libavformat/libzmq.c b/libavformat/libzmq.c index 1b0d8638db..da84efee73 100644 --- a/libavformat/libzmq.c +++ b/libavformat/libzmq.c @@ -51,7 +51,7 @@ static int zmq_proto_wait(URLContext *h, void *socket, int write) zmq_pollitem_t items = { .socket = socket, .fd = 0, .events = ev, .revents = 0 }; ret = zmq_poll(&items, 1, POLLING_TIME); if (ret == -1) { - av_log(h, AV_LOG_ERROR, "Error occured during zmq_poll(): %s\n", ZMQ_STRERROR); + av_log(h, AV_LOG_ERROR, "Error occurred during zmq_poll(): %s\n", ZMQ_STRERROR); return AVERROR_EXTERNAL; } return items.revents & ev ? 0 : AVERROR(EAGAIN); @@ -90,23 +90,26 @@ static int zmq_proto_open(URLContext *h, const char *uri, int flags) s->context = zmq_ctx_new(); if (!s->context) { /*errno not set on failure during zmq_ctx_new()*/ - av_log(h, AV_LOG_ERROR, "Error occured during zmq_ctx_new()\n"); + av_log(h, AV_LOG_ERROR, "Error occurred during zmq_ctx_new()\n"); return AVERROR_EXTERNAL; } - av_strstart(uri, "zmq:", &uri); + if (!av_strstart(uri, "zmq:", &uri)) { + av_log(h, AV_LOG_ERROR, "URL %s lacks prefix\n", uri); + return AVERROR(EINVAL); + } /*publish during write*/ if (h->flags & AVIO_FLAG_WRITE) { s->socket = zmq_socket(s->context, ZMQ_PUB); if (!s->socket) { - av_log(h, AV_LOG_ERROR, "Error occured during zmq_socket(): %s\n", ZMQ_STRERROR); + av_log(h, AV_LOG_ERROR, "Error occurred during zmq_socket(): %s\n", ZMQ_STRERROR); goto fail_term; } ret = zmq_bind(s->socket, uri); if (ret == -1) { - av_log(h, AV_LOG_ERROR, "Error occured during zmq_bind(): %s\n", ZMQ_STRERROR); + av_log(h, AV_LOG_ERROR, "Error occurred during zmq_bind(): %s\n", ZMQ_STRERROR); goto fail_close; } } @@ -115,19 +118,19 @@ static int zmq_proto_open(URLContext *h, const char *uri, int flags) if (h->flags & AVIO_FLAG_READ) { s->socket = zmq_socket(s->context, ZMQ_SUB); if (!s->socket) { - av_log(h, AV_LOG_ERROR, "Error occured during zmq_socket(): %s\n", ZMQ_STRERROR); + av_log(h, AV_LOG_ERROR, "Error occurred during zmq_socket(): %s\n", ZMQ_STRERROR); goto fail_term; } ret = zmq_setsockopt(s->socket, ZMQ_SUBSCRIBE, "", 0); if (ret == -1) { - av_log(h, AV_LOG_ERROR, "Error occured during zmq_setsockopt(): %s\n", ZMQ_STRERROR); + av_log(h, AV_LOG_ERROR, "Error occurred during zmq_setsockopt(): %s\n", ZMQ_STRERROR); goto fail_close; } ret = zmq_connect(s->socket, uri); if (ret == -1) { - av_log(h, AV_LOG_ERROR, "Error occured during zmq_connect(): %s\n", ZMQ_STRERROR); + av_log(h, AV_LOG_ERROR, "Error occurred during zmq_connect(): %s\n", ZMQ_STRERROR); goto fail_close; } } @@ -150,7 +153,7 @@ static int zmq_proto_write(URLContext *h, const unsigned char *buf, int size) return ret; ret = zmq_send(s->socket, buf, size, 0); if (ret == -1) { - av_log(h, AV_LOG_ERROR, "Error occured during zmq_send(): %s\n", ZMQ_STRERROR); + av_log(h, AV_LOG_ERROR, "Error occurred during zmq_send(): %s\n", ZMQ_STRERROR); return AVERROR_EXTERNAL; } return ret; /*number of bytes sent*/ @@ -166,7 +169,7 @@ static int zmq_proto_read(URLContext *h, unsigned char *buf, int size) return ret; ret = zmq_recv(s->socket, buf, size, 0); if (ret == -1) { - av_log(h, AV_LOG_ERROR, "Error occured during zmq_recv(): %s\n", ZMQ_STRERROR); + av_log(h, AV_LOG_ERROR, "Error occurred during zmq_recv(): %s\n", ZMQ_STRERROR); return AVERROR_EXTERNAL; } if (ret > size) { diff --git a/libavformat/lmlm4.c b/libavformat/lmlm4.c index 79d703a8fc..186bffba3a 100644 --- a/libavformat/lmlm4.c +++ b/libavformat/lmlm4.c @@ -94,15 +94,15 @@ static int lmlm4_read_packet(AVFormatContext *s, AVPacket *pkt) if (frame_type > LMLM4_MPEG1L2 || frame_type == LMLM4_INVALID) { av_log(s, AV_LOG_ERROR, "invalid or unsupported frame_type\n"); - return AVERROR(EIO); + return AVERROR_INVALIDDATA; } if (packet_size > LMLM4_MAX_PACKET_SIZE || packet_size<=8) { av_log(s, AV_LOG_ERROR, "packet size %d is invalid\n", packet_size); - return AVERROR(EIO); + return AVERROR_INVALIDDATA; } if ((ret = av_get_packet(pb, pkt, frame_size)) <= 0) - return AVERROR(EIO); + return ret < 0 ? ret : AVERROR(EIO); avio_skip(pb, padding); diff --git a/libavformat/matroskadec.c b/libavformat/matroskadec.c index 9acfdf5b32..adc95c09ad 100644 --- a/libavformat/matroskadec.c +++ b/libavformat/matroskadec.c @@ -802,20 +802,22 @@ static int matroska_read_close(AVFormatContext *s); static int matroska_reset_status(MatroskaDemuxContext *matroska, uint32_t id, int64_t position) { + int64_t err = 0; if (position >= 0) { - int64_t err = avio_seek(matroska->ctx->pb, position, SEEK_SET); - if (err < 0) - return err; - } + err = avio_seek(matroska->ctx->pb, position, SEEK_SET); + if (err > 0) + err = 0; + } else + position = avio_tell(matroska->ctx->pb); matroska->current_id = id; matroska->num_levels = 1; matroska->unknown_count = 0; - matroska->resync_pos = avio_tell(matroska->ctx->pb); + matroska->resync_pos = position; if (id) matroska->resync_pos -= (av_log2(id) + 7) / 8; - return 0; + return err; } static int matroska_resync(MatroskaDemuxContext *matroska, int64_t last_pos) @@ -1688,7 +1690,7 @@ static int matroska_decode_buffer(uint8_t **buf, int *buf_size, case MATROSKA_TRACK_ENCODING_COMP_ZLIB: { z_stream zstream = { 0 }; - if (inflateInit(&zstream) != Z_OK) + if (!pkt_size || inflateInit(&zstream) != Z_OK) return -1; zstream.next_in = data; zstream.avail_in = isize; @@ -1721,7 +1723,7 @@ static int matroska_decode_buffer(uint8_t **buf, int *buf_size, case MATROSKA_TRACK_ENCODING_COMP_BZLIB: { bz_stream bzstream = { 0 }; - if (BZ2_bzDecompressInit(&bzstream, 0, 0) != BZ_OK) + if (!pkt_size || BZ2_bzDecompressInit(&bzstream, 0, 0) != BZ_OK) return -1; bzstream.next_in = data; bzstream.avail_in = isize; @@ -1871,6 +1873,7 @@ static int matroska_parse_seekhead_entry(MatroskaDemuxContext *matroska, uint32_t saved_id = matroska->current_id; int64_t before_pos = avio_tell(matroska->ctx->pb); int ret = 0; + int ret2; /* seek */ if (avio_seek(matroska->ctx->pb, pos, SEEK_SET) == pos) { @@ -1895,7 +1898,9 @@ static int matroska_parse_seekhead_entry(MatroskaDemuxContext *matroska, } /* Seek back - notice that in all instances where this is used * it is safe to set the level to 1. */ - matroska_reset_status(matroska, saved_id, before_pos); + ret2 = matroska_reset_status(matroska, saved_id, before_pos); + if (ret >= 0) + ret = ret2; return ret; } @@ -2735,6 +2740,10 @@ static int matroska_parse_tracks(AVFormatContext *s) track->time_scale); track->time_scale = 1.0; } + + if (matroska->time_scale * track->time_scale > UINT_MAX) + return AVERROR_INVALIDDATA; + avpriv_set_pts_info(st, 64, matroska->time_scale * track->time_scale, 1000 * 1000 * 1000); /* 64 bit pts in ns */ @@ -2797,18 +2806,22 @@ static int matroska_parse_tracks(AVFormatContext *s) mkv_stereo_mode_display_mul(track->video.stereo_mode, &display_width_mul, &display_height_mul); if (track->video.display_unit < MATROSKA_VIDEO_DISPLAYUNIT_UNKNOWN) { - av_reduce(&st->sample_aspect_ratio.num, - &st->sample_aspect_ratio.den, - st->codecpar->height * track->video.display_width * display_width_mul, - st->codecpar->width * track->video.display_height * display_height_mul, - 255); + if (track->video.display_width && track->video.display_height && + st->codecpar->height < INT64_MAX / track->video.display_width / display_width_mul && + st->codecpar->width < INT64_MAX / track->video.display_height / display_height_mul) + av_reduce(&st->sample_aspect_ratio.num, + &st->sample_aspect_ratio.den, + st->codecpar->height * track->video.display_width * display_width_mul, + st->codecpar->width * track->video.display_height * display_height_mul, + INT_MAX); } if (st->codecpar->codec_id != AV_CODEC_ID_HEVC) st->need_parsing = AVSTREAM_PARSE_HEADERS; if (track->default_duration) { + int div = track->default_duration <= INT64_MAX ? 1 : 2; av_reduce(&st->avg_frame_rate.num, &st->avg_frame_rate.den, - 1000000000, track->default_duration, 30000); + 1000000000 / div, track->default_duration / div, 30000); #if FF_API_R_FRAME_RATE if ( st->avg_frame_rate.num < st->avg_frame_rate.den * 1000LL && st->avg_frame_rate.num > st->avg_frame_rate.den * 5LL) @@ -2969,6 +2982,8 @@ static int matroska_read_header(AVFormatContext *s) if (!matroska->time_scale) matroska->time_scale = 1000000; + if (isnan(matroska->duration)) + matroska->duration = 0; if (matroska->duration) matroska->ctx->duration = matroska->duration * matroska->time_scale * 1000 / AV_TIME_BASE; @@ -3761,7 +3776,7 @@ static int matroska_parse_cluster(MatroskaDemuxContext *matroska) MatroskaBlock *block = &cluster->block; int res; - av_assert0(matroska->num_levels <= 2); + av_assert0(matroska->num_levels <= 2U); if (matroska->num_levels == 1) { res = ebml_parse(matroska, matroska_segment, NULL); @@ -3845,13 +3860,13 @@ static int matroska_read_seek(AVFormatContext *s, int stream_index, matroska_parse_cues(matroska); } - if (!st->internal->nb_index_entries) + if (!st->nb_index_entries) goto err; - timestamp = FFMAX(timestamp, st->internal->index_entries[0].timestamp); + timestamp = FFMAX(timestamp, st->index_entries[0].timestamp); - if ((index = av_index_search_timestamp(st, timestamp, flags)) < 0 || index == st->internal->nb_index_entries - 1) { - matroska_reset_status(matroska, 0, st->internal->index_entries[st->internal->nb_index_entries - 1].pos); - while ((index = av_index_search_timestamp(st, timestamp, flags)) < 0 || index == st->internal->nb_index_entries - 1) { + if ((index = av_index_search_timestamp(st, timestamp, flags)) < 0 || index == st->nb_index_entries - 1) { + matroska_reset_status(matroska, 0, st->index_entries[st->nb_index_entries - 1].pos); + while ((index = av_index_search_timestamp(st, timestamp, flags)) < 0 || index == st->nb_index_entries - 1) { matroska_clear_queue(matroska); if (matroska_parse_cluster(matroska) < 0) break; @@ -3859,7 +3874,7 @@ static int matroska_read_seek(AVFormatContext *s, int stream_index, } matroska_clear_queue(matroska); - if (index < 0 || (matroska->cues_parsing_deferred < 0 && index == st->internal->nb_index_entries - 1)) + if (index < 0 || (matroska->cues_parsing_deferred < 0 && index == st->nb_index_entries - 1)) goto err; tracks = matroska->tracks.elem; @@ -3871,17 +3886,17 @@ static int matroska_read_seek(AVFormatContext *s, int stream_index, } /* We seek to a level 1 element, so set the appropriate status. */ - matroska_reset_status(matroska, 0, st->internal->index_entries[index].pos); + matroska_reset_status(matroska, 0, st->index_entries[index].pos); if (flags & AVSEEK_FLAG_ANY) { st->internal->skip_to_keyframe = 0; matroska->skip_to_timecode = timestamp; } else { st->internal->skip_to_keyframe = 1; - matroska->skip_to_timecode = st->internal->index_entries[index].timestamp; + matroska->skip_to_timecode = st->index_entries[index].timestamp; } matroska->skip_to_keyframe = 1; matroska->done = 0; - ff_update_cur_dts(s, st, st->internal->index_entries[index].timestamp); + ff_update_cur_dts(s, st, st->index_entries[index].timestamp); return 0; err: // slightly hackish but allows proper fallback to @@ -3927,9 +3942,11 @@ static CueDesc get_cue_desc(AVFormatContext *s, int64_t ts, int64_t cues_start) MatroskaDemuxContext *matroska = s->priv_data; CueDesc cue_desc; int i; - int nb_index_entries = s->streams[0]->internal->nb_index_entries; - AVIndexEntry *index_entries = s->streams[0]->internal->index_entries; - if (ts >= matroska->duration * matroska->time_scale) return (CueDesc) {-1, -1, -1, -1}; + int nb_index_entries = s->streams[0]->nb_index_entries; + AVIndexEntry *index_entries = s->streams[0]->index_entries; + + if (ts >= (int64_t)(matroska->duration * matroska->time_scale)) + return (CueDesc) {-1, -1, -1, -1}; for (i = 1; i < nb_index_entries; i++) { if (index_entries[i - 1].timestamp * matroska->time_scale <= ts && index_entries[i].timestamp * matroska->time_scale > ts) { @@ -3958,11 +3975,11 @@ static int webm_clusters_start_with_keyframe(AVFormatContext *s) uint32_t id = matroska->current_id; int64_t cluster_pos, before_pos; int index, rv = 1; - if (s->streams[0]->internal->nb_index_entries <= 0) return 0; + if (s->streams[0]->nb_index_entries <= 0) return 0; // seek to the first cluster using cues. index = av_index_search_timestamp(s->streams[0], 0, 0); if (index < 0) return 0; - cluster_pos = s->streams[0]->internal->index_entries[index].pos; + cluster_pos = s->streams[0]->index_entries[index].pos; before_pos = avio_tell(s->pb); while (1) { uint64_t cluster_id, cluster_length; @@ -4086,20 +4103,23 @@ static int64_t webm_dash_manifest_compute_bandwidth(AVFormatContext *s, int64_t double bandwidth = 0.0; int i; - for (i = 0; i < st->internal->nb_index_entries; i++) { + for (i = 0; i < st->nb_index_entries; i++) { int64_t prebuffer_ns = 1000000000; - int64_t time_ns = st->internal->index_entries[i].timestamp * matroska->time_scale; + int64_t time_ns = st->index_entries[i].timestamp * matroska->time_scale; double nano_seconds_per_second = 1000000000.0; - int64_t prebuffered_ns = time_ns + prebuffer_ns; + int64_t prebuffered_ns; double prebuffer_bytes = 0.0; int64_t temp_prebuffer_ns = prebuffer_ns; int64_t pre_bytes, pre_ns; double pre_sec, prebuffer, bits_per_second; CueDesc desc_beg = get_cue_desc(s, time_ns, cues_start); - // Start with the first Cue. CueDesc desc_end = desc_beg; + if (time_ns > INT64_MAX - prebuffer_ns) + return -1; + prebuffered_ns = time_ns + prebuffer_ns; + // Figure out how much data we have downloaded for the prebuffer. This will // be used later to adjust the bits per sample to try. while (desc_end.start_time_ns != -1 && desc_end.end_time_ns < prebuffered_ns) { @@ -4117,6 +4137,9 @@ static int64_t webm_dash_manifest_compute_bandwidth(AVFormatContext *s, int64_t // The prebuffer ends in the last Cue. Estimate how much data was // prebuffered. pre_bytes = desc_end.end_offset - desc_end.start_offset; + if (desc_end.end_time_ns <= desc_end.start_time_ns || + desc_end.end_time_ns - (uint64_t)desc_end.start_time_ns > INT64_MAX) + return -1; pre_ns = desc_end.end_time_ns - desc_end.start_time_ns; pre_sec = pre_ns / nano_seconds_per_second; prebuffer_bytes += @@ -4129,12 +4152,16 @@ static int64_t webm_dash_manifest_compute_bandwidth(AVFormatContext *s, int64_t do { int64_t desc_bytes = desc_end.end_offset - desc_beg.start_offset; int64_t desc_ns = desc_end.end_time_ns - desc_beg.start_time_ns; - double desc_sec = desc_ns / nano_seconds_per_second; - double calc_bits_per_second = (desc_bytes * 8) / desc_sec; + double desc_sec, calc_bits_per_second, percent, mod_bits_per_second; + if (desc_bytes <= 0 || desc_bytes > INT64_MAX/8) + return -1; + + desc_sec = desc_ns / nano_seconds_per_second; + calc_bits_per_second = (desc_bytes * 8) / desc_sec; // Drop the bps by the percentage of bytes buffered. - double percent = (desc_bytes - prebuffer_bytes) / desc_bytes; - double mod_bits_per_second = calc_bits_per_second * percent; + percent = (desc_bytes - prebuffer_bytes) / desc_bytes; + mod_bits_per_second = calc_bits_per_second * percent; if (prebuffer < desc_sec) { double search_sec = @@ -4226,14 +4253,14 @@ static int webm_dash_manifest_cues(AVFormatContext *s, int64_t init_range) // store cue point timestamps as a comma separated list for checking subsegment alignment in // the muxer. assumes that each timestamp cannot be more than 20 characters long. - buf = av_malloc_array(s->streams[0]->internal->nb_index_entries, 20); + buf = av_malloc_array(s->streams[0]->nb_index_entries, 20); if (!buf) return -1; strcpy(buf, ""); - for (i = 0; i < s->streams[0]->internal->nb_index_entries; i++) { + for (i = 0; i < s->streams[0]->nb_index_entries; i++) { int ret = snprintf(buf + end, 20, - "%" PRId64"%s", s->streams[0]->internal->index_entries[i].timestamp, - i != s->streams[0]->internal->nb_index_entries - 1 ? "," : ""); - if (ret <= 0 || (ret == 20 && i == s->streams[0]->internal->nb_index_entries - 1)) { + "%" PRId64"%s", s->streams[0]->index_entries[i].timestamp, + i != s->streams[0]->nb_index_entries - 1 ? "," : ""); + if (ret <= 0 || (ret == 20 && i == s->streams[0]->nb_index_entries - 1)) { av_log(s, AV_LOG_ERROR, "timestamp too long.\n"); av_free(buf); return AVERROR_INVALIDDATA; diff --git a/libavformat/matroskaenc.c b/libavformat/matroskaenc.c index bbf231f2a4..b4284a8778 100644 --- a/libavformat/matroskaenc.c +++ b/libavformat/matroskaenc.c @@ -1768,6 +1768,7 @@ static int mkv_write_attachments(AVFormatContext *s) put_ebml_string(dyn_cp, MATROSKA_ID_FILEDESC, t->value); if (!(t = av_dict_get(st->metadata, "filename", NULL, 0))) { av_log(s, AV_LOG_ERROR, "Attachment stream %d has no filename tag.\n", i); + ffio_free_dyn_buf(&dyn_cp); return AVERROR(EINVAL); } put_ebml_string(dyn_cp, MATROSKA_ID_FILENAME, t->value); diff --git a/libavformat/mccdec.c b/libavformat/mccdec.c index 2a0b7905a0..0742061a76 100644 --- a/libavformat/mccdec.c +++ b/libavformat/mccdec.c @@ -92,7 +92,7 @@ static int mcc_read_header(AVFormatContext *s) { MCCContext *mcc = s->priv_data; AVStream *st = avformat_new_stream(s, NULL); - AVRational rate; + AVRational rate = {0}; int64_t ts, pos; uint8_t out[4096]; char line[4096]; @@ -127,8 +127,7 @@ static int mcc_read_header(AVFormatContext *s) num = strtol(rate_str, &df, 10); den = 1; if (df && !av_strncasecmp(df, "DF", 2)) { - num *= 1000; - den = 1001; + av_reduce(&num, &den, num * 1000LL, 1001, INT_MAX); } } @@ -139,7 +138,7 @@ static int mcc_read_header(AVFormatContext *s) continue; } - if (av_sscanf(line, "%d:%d:%d:%d", &hh, &mm, &ss, &fs) != 4) + if (av_sscanf(line, "%d:%d:%d:%d", &hh, &mm, &ss, &fs) != 4 || rate.den <= 0) continue; ts = av_sat_add64(av_rescale(hh * 3600LL + mm * 60LL + ss, rate.num, rate.den), fs); diff --git a/libavformat/mlvdec.c b/libavformat/mlvdec.c index 1ddef3461e..645ce55e6c 100644 --- a/libavformat/mlvdec.c +++ b/libavformat/mlvdec.c @@ -82,13 +82,15 @@ static int check_file_header(AVIOContext *pb, uint64_t guid) static void read_string(AVFormatContext *avctx, AVIOContext *pb, const char *tag, unsigned size) { char * value = av_malloc(size + 1); + int ret; + if (!value) { avio_skip(pb, size); return; } - avio_read(pb, value, size); - if (!value[0]) { + ret = avio_read(pb, value, size); + if (ret != size || !value[0]) { av_free(value); return; } @@ -191,12 +193,12 @@ static int scan_file(AVFormatContext *avctx, AVStream *vst, AVStream *ast, int f } } else if (vst && type == MKTAG('V', 'I', 'D', 'F') && size >= 4) { uint64_t pts = avio_rl32(pb); - ff_add_index_entry(&vst->internal->index_entries, &vst->internal->nb_index_entries, &vst->internal->index_entries_allocated_size, + ff_add_index_entry(&vst->index_entries, &vst->nb_index_entries, &vst->index_entries_allocated_size, avio_tell(pb) - 20, pts, file, 0, AVINDEX_KEYFRAME); size -= 4; } else if (ast && type == MKTAG('A', 'U', 'D', 'F') && size >= 4) { uint64_t pts = avio_rl32(pb); - ff_add_index_entry(&ast->internal->index_entries, &ast->internal->nb_index_entries, &ast->internal->index_entries_allocated_size, + ff_add_index_entry(&ast->index_entries, &ast->nb_index_entries, &ast->index_entries_allocated_size, avio_tell(pb) - 20, pts, file, 0, AVINDEX_KEYFRAME); size -= 4; } else if (vst && type == MKTAG('W','B','A','L') && size >= 28) { @@ -374,22 +376,22 @@ static int read_header(AVFormatContext *avctx) } if (vst) - vst->duration = vst->internal->nb_index_entries; + vst->duration = vst->nb_index_entries; if (ast) - ast->duration = ast->internal->nb_index_entries; + ast->duration = ast->nb_index_entries; - if ((vst && !vst->internal->nb_index_entries) || (ast && !ast->internal->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"); read_close(avctx); return AVERROR_INVALIDDATA; } if (vst && ast) - avio_seek(pb, FFMIN(vst->internal->index_entries[0].pos, ast->internal->index_entries[0].pos), SEEK_SET); + avio_seek(pb, FFMIN(vst->index_entries[0].pos, ast->index_entries[0].pos), SEEK_SET); else if (vst) - avio_seek(pb, vst->internal->index_entries[0].pos, SEEK_SET); + avio_seek(pb, vst->index_entries[0].pos, SEEK_SET); else if (ast) - avio_seek(pb, ast->internal->index_entries[0].pos, SEEK_SET); + avio_seek(pb, ast->index_entries[0].pos, SEEK_SET); return 0; } @@ -415,31 +417,37 @@ static int read_packet(AVFormatContext *avctx, AVPacket *pkt) return AVERROR(EIO); } - pb = mlv->pb[st->internal->index_entries[index].size]; + pb = mlv->pb[st->index_entries[index].size]; if (!pb) { ret = FFERROR_REDO; goto next_packet; } - avio_seek(pb, st->internal->index_entries[index].pos, SEEK_SET); + avio_seek(pb, st->index_entries[index].pos, SEEK_SET); avio_skip(pb, 4); // blockType size = avio_rl32(pb); if (size < 16) return AVERROR_INVALIDDATA; avio_skip(pb, 12); //timestamp, frameNumber - if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) + size -= 12; + if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) { + if (size < 8) + return AVERROR_INVALIDDATA; avio_skip(pb, 8); // cropPosX, cropPosY, panPosX, panPosY + size -= 8; + } space = avio_rl32(pb); + if (size < space + 4LL) + return AVERROR_INVALIDDATA; avio_skip(pb, space); + size -= space; if ((mlv->class[st->id] & (MLV_CLASS_FLAG_DELTA|MLV_CLASS_FLAG_LZMA))) { ret = AVERROR_PATCHWELCOME; } else if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) { ret = av_get_packet(pb, pkt, (st->codecpar->width * st->codecpar->height * st->codecpar->bits_per_coded_sample + 7) >> 3); } else { // AVMEDIA_TYPE_AUDIO - if (space > UINT_MAX - 24 || size < (24 + space)) - return AVERROR_INVALIDDATA; - ret = av_get_packet(pb, pkt, size - (24 + space)); + ret = av_get_packet(pb, pkt, size - 4); } if (ret < 0) diff --git a/libavformat/mm.c b/libavformat/mm.c index 02ffbcd824..097c3efc1c 100644 --- a/libavformat/mm.c +++ b/libavformat/mm.c @@ -94,7 +94,7 @@ static int read_header(AVFormatContext *s) type = avio_rl16(pb); length = avio_rl32(pb); - if (type != MM_TYPE_HEADER) + if (type != MM_TYPE_HEADER || length < 10) return AVERROR_INVALIDDATA; /* read header */ diff --git a/libavformat/moflex.c b/libavformat/moflex.c index 41335ada78..ca40b51c3e 100644 --- a/libavformat/moflex.c +++ b/libavformat/moflex.c @@ -172,8 +172,7 @@ static int moflex_read_sync(AVFormatContext *s) unsigned type, ssize, codec_id = 0; unsigned codec_type, width = 0, height = 0, sample_rate = 0, channels = 0; int stream_index = -1; - int format; - AVRational fps; + AVRational tb = av_make_q(0, 1); read_var_byte(s, &type); read_var_byte(s, &ssize); @@ -196,6 +195,7 @@ static int moflex_read_sync(AVFormatContext *s) return AVERROR_PATCHWELCOME; } sample_rate = avio_rb24(pb) + 1; + tb = av_make_q(1, sample_rate); channels = avio_r8(pb) + 1; break; case 1: @@ -209,11 +209,10 @@ static int moflex_read_sync(AVFormatContext *s) av_log(s, AV_LOG_ERROR, "Unsupported video codec: %d\n", codec_id); return AVERROR_PATCHWELCOME; } - fps.num = avio_rb16(pb); - fps.den = avio_rb16(pb); + tb.den = avio_rb16(pb); + tb.num = avio_rb16(pb); width = avio_rb16(pb); height = avio_rb16(pb); - format = AV_PIX_FMT_YUV420P; avio_skip(pb, type == 3 ? 3 : 2); break; case 4: @@ -235,15 +234,12 @@ static int moflex_read_sync(AVFormatContext *s) st->codecpar->height = height; st->codecpar->sample_rate= sample_rate; st->codecpar->channels = channels; - st->codecpar->format = format; st->priv_data = av_packet_alloc(); if (!st->priv_data) return AVERROR(ENOMEM); - if (sample_rate) - avpriv_set_pts_info(st, 63, 1, sample_rate); - else - avpriv_set_pts_info(st, 63, fps.den, fps.num); + if (tb.num) + avpriv_set_pts_info(st, 63, tb.num, tb.den); } } diff --git a/libavformat/mov.c b/libavformat/mov.c index f9c4dbe5d4..b03a8f8295 100644 --- a/libavformat/mov.c +++ b/libavformat/mov.c @@ -294,6 +294,8 @@ static int mov_metadata_hmmt(MOVContext *c, AVIOContext *pb, unsigned len) int moment_time = avio_rb32(pb); avpriv_new_chapter(c->fc, i, av_make_q(1, 1000), moment_time, AV_NOPTS_VALUE, NULL); } + if (avio_feof(pb)) + return AVERROR_INVALIDDATA; return 0; } @@ -304,7 +306,8 @@ static int mov_read_udta_string(MOVContext *c, AVIOContext *pb, MOVAtom atom) char *str = NULL; const char *key = NULL; uint16_t langcode = 0; - uint32_t data_type = 0, str_size, str_size_alloc; + uint32_t data_type = 0, str_size_alloc; + uint64_t str_size; int (*parse)(MOVContext*, AVIOContext*, unsigned, const char*) = NULL; int raw = 0; int num = 0; @@ -605,11 +608,13 @@ static int mov_read_dref(MOVContext *c, AVIOContext *pb, MOVAtom atom) for (i = 0; i < entries; i++) { MOVDref *dref = &sc->drefs[i]; uint32_t size = avio_rb32(pb); - int64_t next = avio_tell(pb) + size - 4; + int64_t next = avio_tell(pb); - if (size < 12) + if (size < 12 || next < 0 || next > INT64_MAX - size) return AVERROR_INVALIDDATA; + next += size - 4; + dref->type = avio_rl32(pb); avio_rb32(pb); // version + flags @@ -1130,6 +1135,12 @@ static int mov_read_ftyp(MOVContext *c, AVIOContext *pb, MOVAtom atom) int ret = ffio_read_size(pb, type, 4); if (ret < 0) return ret; + if (c->fc->nb_streams) { + if (c->fc->strict_std_compliance >= FF_COMPLIANCE_STRICT) + return AVERROR_INVALIDDATA; + av_log(c->fc, AV_LOG_DEBUG, "Ignoring duplicate FTYP\n"); + return 0; + } if (strcmp(type, "qt ")) c->isom = 1; @@ -1940,6 +1951,8 @@ static int mov_read_glbl(MOVContext *c, AVIOContext *pb, MOVAtom atom) // wrap a whole fiel atom inside of a glbl atom. unsigned size = avio_rb32(pb); unsigned type = avio_rl32(pb); + if (avio_feof(pb)) + return AVERROR_INVALIDDATA; avio_seek(pb, -8, SEEK_CUR); if (type == MKTAG('f','i','e','l') && size == atom.size) return mov_read_default(c, pb, atom); @@ -2037,8 +2050,10 @@ static int mov_read_stco(MOVContext *c, AVIOContext *pb, MOVAtom atom) if (!entries) return 0; - if (sc->chunk_offsets) - av_log(c->fc, AV_LOG_WARNING, "Duplicated STCO atom\n"); + if (sc->chunk_offsets) { + av_log(c->fc, AV_LOG_WARNING, "Ignoring duplicated STCO atom\n"); + return 0; + } av_free(sc->chunk_offsets); sc->chunk_count = 0; sc->chunk_offsets = av_malloc_array(entries, sizeof(*sc->chunk_offsets)); @@ -2050,8 +2065,13 @@ static int mov_read_stco(MOVContext *c, AVIOContext *pb, MOVAtom atom) for (i = 0; i < entries && !pb->eof_reached; i++) sc->chunk_offsets[i] = avio_rb32(pb); else if (atom.type == MKTAG('c','o','6','4')) - for (i = 0; i < entries && !pb->eof_reached; i++) + for (i = 0; i < entries && !pb->eof_reached; i++) { sc->chunk_offsets[i] = avio_rb64(pb); + if (sc->chunk_offsets[i] < 0) { + av_log(c->fc, AV_LOG_WARNING, "Impossible chunk_offset\n"); + sc->chunk_offsets[i] = 0; + } + } else return AVERROR_INVALIDDATA; @@ -2263,7 +2283,7 @@ static void mov_parse_stsd_audio(MOVContext *c, AVIOContext *pb, } bits_per_sample = av_get_bits_per_sample(st->codecpar->codec_id); - if (bits_per_sample) { + if (bits_per_sample && (bits_per_sample >> 3) * (uint64_t)st->codecpar->channels <= INT_MAX) { st->codecpar->bits_per_coded_sample = bits_per_sample; sc->sample_size = (bits_per_sample >> 3) * st->codecpar->channels; } @@ -2547,6 +2567,10 @@ int ff_mov_read_stsd_entries(MOVContext *c, AVIOContext *pb, int entries) av_log(c->fc, AV_LOG_ERROR, "Invalid sample rate %d\n", st->codecpar->sample_rate); return AVERROR_INVALIDDATA; } + if (st->codecpar->channels < 0) { + av_log(c->fc, AV_LOG_ERROR, "Invalid channels %d\n", st->codecpar->channels); + return AVERROR_INVALIDDATA; + } } else if (st->codecpar->codec_type==AVMEDIA_TYPE_SUBTITLE){ mov_parse_stsd_subtitle(c, pb, st, sc, size - (avio_tell(pb) - start_pos)); @@ -2671,8 +2695,10 @@ static int mov_read_stsc(MOVContext *c, AVIOContext *pb, MOVAtom atom) if (!entries) return 0; - if (sc->stsc_data) - av_log(c->fc, AV_LOG_WARNING, "Duplicated STSC atom\n"); + if (sc->stsc_data) { + av_log(c->fc, AV_LOG_WARNING, "Ignoring duplicated STSC atom\n"); + return 0; + } av_free(sc->stsc_data); sc->stsc_count = 0; sc->stsc_data = av_malloc_array(entries, sizeof(*sc->stsc_data)); @@ -3018,7 +3044,7 @@ static int mov_read_sdtp(MOVContext *c, AVIOContext *pb, MOVAtom atom) av_freep(&sc->sdtp_data); sc->sdtp_count = 0; - sc->sdtp_data = av_mallocz(entries); + sc->sdtp_data = av_malloc(entries); if (!sc->sdtp_data) return AVERROR(ENOMEM); @@ -3176,6 +3202,10 @@ static int get_edit_list_entry(MOVContext *mov, } *edit_list_duration = av_rescale(*edit_list_duration, msc->time_scale, global_timescale); + + if (*edit_list_duration + (uint64_t)*edit_list_media_time > INT64_MAX) + *edit_list_duration = 0; + return 1; } @@ -3210,8 +3240,8 @@ static int find_prev_closest_index(AVStream *st, int64_t* ctts_sample) { MOVStreamContext *msc = st->priv_data; - AVIndexEntry *e_keep = st->internal->index_entries; - int nb_keep = st->internal->nb_index_entries; + AVIndexEntry *e_keep = st->index_entries; + int nb_keep = st->nb_index_entries; int64_t i = 0; int64_t index_ctts_count; @@ -3224,8 +3254,8 @@ static int find_prev_closest_index(AVStream *st, timestamp_pts -= msc->dts_shift; } - st->internal->index_entries = e_old; - st->internal->nb_index_entries = nb_old; + st->index_entries = e_old; + st->nb_index_entries = nb_old; *index = av_index_search_timestamp(st, timestamp_pts, flag | AVSEEK_FLAG_BACKWARD); // Keep going backwards in the index entries until the timestamp is the same. @@ -3278,14 +3308,14 @@ static int find_prev_closest_index(AVStream *st, } /* restore AVStream state*/ - st->internal->index_entries = e_keep; - st->internal->nb_index_entries = nb_keep; + st->index_entries = e_keep; + st->nb_index_entries = nb_keep; return *index >= 0 ? 0 : -1; } /** - * Add index entry with the given values, to the end of st->internal->index_entries. - * Returns the new size st->internal->index_entries if successful, else returns -1. + * Add index entry with the given values, to the end of st->index_entries. + * Returns the new size st->index_entries if successful, else returns -1. * * This function is similar to ff_add_index_entry in libavformat/utils.c * except that here we are always unconditionally adding an index entry to @@ -3299,27 +3329,27 @@ static int64_t add_index_entry(AVStream *st, int64_t pos, int64_t timestamp, { AVIndexEntry *entries, *ie; int64_t index = -1; - const size_t min_size_needed = (st->internal->nb_index_entries + 1) * sizeof(AVIndexEntry); + const size_t min_size_needed = (st->nb_index_entries + 1) * sizeof(AVIndexEntry); // Double the allocation each time, to lower memory fragmentation. // Another difference from ff_add_index_entry function. const size_t requested_size = - min_size_needed > st->internal->index_entries_allocated_size ? - FFMAX(min_size_needed, 2 * st->internal->index_entries_allocated_size) : + min_size_needed > st->index_entries_allocated_size ? + FFMAX(min_size_needed, 2 * st->index_entries_allocated_size) : min_size_needed; - if (st->internal->nb_index_entries + 1U >= UINT_MAX / sizeof(AVIndexEntry)) + if (st->nb_index_entries + 1U >= UINT_MAX / sizeof(AVIndexEntry)) return -1; - entries = av_fast_realloc(st->internal->index_entries, - &st->internal->index_entries_allocated_size, + entries = av_fast_realloc(st->index_entries, + &st->index_entries_allocated_size, requested_size); if (!entries) return -1; - st->internal->index_entries= entries; + st->index_entries= entries; - index= st->internal->nb_index_entries++; + index= st->nb_index_entries++; ie= &entries[index]; ie->pos = pos; @@ -3338,10 +3368,10 @@ static void fix_index_entry_timestamps(AVStream* st, int end_index, int64_t end_ int64_t* frame_duration_buffer, int frame_duration_buffer_size) { int i = 0; - av_assert0(end_index >= 0 && end_index <= st->internal->nb_index_entries); + av_assert0(end_index >= 0 && end_index <= st->nb_index_entries); for (i = 0; i < frame_duration_buffer_size; i++) { end_ts -= frame_duration_buffer[frame_duration_buffer_size - 1 - i]; - st->internal->index_entries[end_index - 1 - i].timestamp = end_ts; + st->index_entries[end_index - 1 - i].timestamp = end_ts; } } @@ -3393,14 +3423,14 @@ static void mov_estimate_video_delay(MOVContext *c, AVStream* st) if (st->codecpar->video_delay <= 0 && msc->ctts_data && st->codecpar->codec_id == AV_CODEC_ID_H264) { st->codecpar->video_delay = 0; - for (ind = 0; ind < st->internal->nb_index_entries && ctts_ind < msc->ctts_count; ++ind) { + for (ind = 0; ind < st->nb_index_entries && ctts_ind < msc->ctts_count; ++ind) { // Point j to the last elem of the buffer and insert the current pts there. j = buf_start; buf_start = (buf_start + 1); if (buf_start == MAX_REORDER_DELAY + 1) buf_start = 0; - pts_buf[j] = st->internal->index_entries[ind].timestamp + msc->ctts_data[ctts_ind].duration; + pts_buf[j] = st->index_entries[ind].timestamp + msc->ctts_data[ctts_ind].duration; // The timestamps that are already in the sorted buffer, and are greater than the // current pts, are exactly the timestamps that need to be buffered to output PTS @@ -3480,7 +3510,7 @@ static void mov_current_sample_set(MOVStreamContext *sc, int current_sample) } /** - * Fix st->internal->index_entries, so that it contains only the entries (and the entries + * Fix st->index_entries, so that it contains only the entries (and the entries * which are needed to decode them) that fall in the edit list time ranges. * Also fixes the timestamps of the index entries to match the timeline * specified the edit lists. @@ -3488,8 +3518,8 @@ static void mov_current_sample_set(MOVStreamContext *sc, int current_sample) static void mov_fix_index(MOVContext *mov, AVStream *st) { MOVStreamContext *msc = st->priv_data; - AVIndexEntry *e_old = st->internal->index_entries; - int nb_old = st->internal->nb_index_entries; + AVIndexEntry *e_old = st->index_entries; + int nb_old = st->nb_index_entries; const AVIndexEntry *e_old_end = e_old + nb_old; const AVIndexEntry *current = NULL; MOVStts *ctts_data_old = msc->ctts_data; @@ -3534,9 +3564,9 @@ static void mov_fix_index(MOVContext *mov, AVStream *st) current_index_range = msc->index_ranges - 1; // Clean AVStream from traces of old index - st->internal->index_entries = NULL; - st->internal->index_entries_allocated_size = 0; - st->internal->nb_index_entries = 0; + st->index_entries = NULL; + st->index_entries_allocated_size = 0; + st->nb_index_entries = 0; // Clean ctts fields of MOVStreamContext msc->ctts_data = NULL; @@ -3665,7 +3695,7 @@ static void mov_fix_index(MOVContext *mov, AVStream *st) // Make timestamps strictly monotonically increasing for audio, by rewriting timestamps for // discarded packets. if (frame_duration_buffer) { - fix_index_entry_timestamps(st, st->internal->nb_index_entries, edit_list_dts_counter, + fix_index_entry_timestamps(st, st->nb_index_entries, edit_list_dts_counter, frame_duration_buffer, num_discarded_begin); av_freep(&frame_duration_buffer); } @@ -3704,7 +3734,7 @@ static void mov_fix_index(MOVContext *mov, AVStream *st) // Make timestamps strictly monotonically increasing by rewriting timestamps for // discarded packets. if (frame_duration_buffer) { - fix_index_entry_timestamps(st, st->internal->nb_index_entries, edit_list_dts_counter, + fix_index_entry_timestamps(st, st->nb_index_entries, edit_list_dts_counter, frame_duration_buffer, num_discarded_begin); av_freep(&frame_duration_buffer); } @@ -3765,8 +3795,8 @@ static void mov_fix_index(MOVContext *mov, AVStream *st) if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) { if (msc->min_corrected_pts > 0) { av_log(mov->fc, AV_LOG_DEBUG, "Offset DTS by %"PRId64" to make first pts zero.\n", msc->min_corrected_pts); - for (i = 0; i < st->internal->nb_index_entries; ++i) { - st->internal->index_entries[i].timestamp -= msc->min_corrected_pts; + for (i = 0; i < st->nb_index_entries; ++i) { + st->index_entries[i].timestamp -= msc->min_corrected_pts; } } } @@ -3831,7 +3861,11 @@ static void mov_build_index(MOVContext *mov, AVStream *st) if ((empty_duration || start_time) && mov->time_scale > 0) { if (empty_duration) empty_duration = av_rescale(empty_duration, sc->time_scale, mov->time_scale); - sc->time_offset = start_time - empty_duration; + + if (av_sat_sub64(start_time, empty_duration) != start_time - (uint64_t)empty_duration) + av_log(mov->fc, AV_LOG_WARNING, "start_time - empty_duration is not representable\n"); + + sc->time_offset = start_time - (uint64_t)empty_duration; sc->min_corrected_pts = start_time; if (!mov->advanced_editlist) current_dts = -sc->time_offset; @@ -3859,17 +3893,17 @@ static void mov_build_index(MOVContext *mov, AVStream *st) current_dts -= sc->dts_shift; last_dts = current_dts; - if (!sc->sample_count || st->internal->nb_index_entries) + if (!sc->sample_count || st->nb_index_entries) return; - if (sc->sample_count >= UINT_MAX / sizeof(*st->internal->index_entries) - st->internal->nb_index_entries) + if (sc->sample_count >= UINT_MAX / sizeof(*st->index_entries) - st->nb_index_entries) return; - if (av_reallocp_array(&st->internal->index_entries, - st->internal->nb_index_entries + sc->sample_count, - sizeof(*st->internal->index_entries)) < 0) { - st->internal->nb_index_entries = 0; + if (av_reallocp_array(&st->index_entries, + st->nb_index_entries + sc->sample_count, + sizeof(*st->index_entries)) < 0) { + st->nb_index_entries = 0; return; } - st->internal->index_entries_allocated_size = (st->internal->nb_index_entries + sc->sample_count) * sizeof(*st->internal->index_entries); + st->index_entries_allocated_size = (st->nb_index_entries + sc->sample_count) * sizeof(*st->index_entries); if (ctts_data_old) { // Expand ctts entries such that we have a 1-1 mapping with samples @@ -3945,6 +3979,13 @@ static void mov_build_index(MOVContext *mov, AVStream *st) if (keyframe) distance = 0; sample_size = sc->stsz_sample_size > 0 ? sc->stsz_sample_size : sc->sample_sizes[current_sample]; + if (current_offset > INT64_MAX - sample_size) { + av_log(mov->fc, AV_LOG_ERROR, "Current offset %"PRId64" or sample size %u is too large\n", + current_offset, + sample_size); + return; + } + if (sc->pseudo_stream_id == -1 || sc->stsc_data[stsc_index].id - 1 == sc->pseudo_stream_id) { AVIndexEntry *e; @@ -3952,7 +3993,7 @@ static void mov_build_index(MOVContext *mov, AVStream *st) av_log(mov->fc, AV_LOG_ERROR, "Sample size %u is too large\n", sample_size); return; } - e = &st->internal->index_entries[st->internal->nb_index_entries++]; + e = &st->index_entries[st->nb_index_entries++]; e->pos = current_offset; e->timestamp = current_dts; e->size = sample_size; @@ -3961,7 +4002,7 @@ static void mov_build_index(MOVContext *mov, AVStream *st) av_log(mov->fc, AV_LOG_TRACE, "AVIndex stream %d, sample %u, offset %"PRIx64", dts %"PRId64", " "size %u, distance %u, keyframe %d\n", st->index, current_sample, current_offset, current_dts, sample_size, distance, keyframe); - if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO && st->internal->nb_index_entries < 100) + if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO && st->nb_index_entries < 100) ff_rfps_add_frame(mov->fc, st, current_dts); } @@ -4033,15 +4074,15 @@ static void mov_build_index(MOVContext *mov, AVStream *st) } av_log(mov->fc, AV_LOG_TRACE, "chunk count %u\n", total); - if (total >= UINT_MAX / sizeof(*st->internal->index_entries) - st->internal->nb_index_entries) + if (total >= UINT_MAX / sizeof(*st->index_entries) - st->nb_index_entries) return; - if (av_reallocp_array(&st->internal->index_entries, - st->internal->nb_index_entries + total, - sizeof(*st->internal->index_entries)) < 0) { - st->internal->nb_index_entries = 0; + if (av_reallocp_array(&st->index_entries, + st->nb_index_entries + total, + sizeof(*st->index_entries)) < 0) { + st->nb_index_entries = 0; return; } - st->internal->index_entries_allocated_size = (st->internal->nb_index_entries + total) * sizeof(*st->internal->index_entries); + st->index_entries_allocated_size = (st->nb_index_entries + total) * sizeof(*st->index_entries); // populate index for (i = 0; i < sc->chunk_count; i++) { @@ -4076,7 +4117,7 @@ static void mov_build_index(MOVContext *mov, AVStream *st) } } - if (st->internal->nb_index_entries >= total) { + if (st->nb_index_entries >= total) { av_log(mov->fc, AV_LOG_ERROR, "wrong chunk count %u\n", total); return; } @@ -4084,7 +4125,7 @@ static void mov_build_index(MOVContext *mov, AVStream *st) av_log(mov->fc, AV_LOG_ERROR, "Sample size %u is too large\n", size); return; } - e = &st->internal->index_entries[st->internal->nb_index_entries++]; + e = &st->index_entries[st->nb_index_entries++]; e->pos = current_offset; e->timestamp = current_dts; e->size = size; @@ -4107,8 +4148,8 @@ static void mov_build_index(MOVContext *mov, AVStream *st) } // Update start time of the stream. - if (st->start_time == AV_NOPTS_VALUE && st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO && st->internal->nb_index_entries > 0) { - st->start_time = st->internal->index_entries[0].timestamp + sc->dts_shift; + if (st->start_time == AV_NOPTS_VALUE && st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO && st->nb_index_entries > 0) { + st->start_time = st->index_entries[0].timestamp + sc->dts_shift; if (sc->ctts_data) { st->start_time += sc->ctts_data[0].duration; } @@ -4390,12 +4431,13 @@ static int mov_read_keys(MOVContext *c, AVIOContext *pb, MOVAtom atom) for (i = 1; i <= count; ++i) { uint32_t key_size = avio_rb32(pb); uint32_t type = avio_rl32(pb); - if (key_size < 8) { + if (key_size < 8 || key_size > atom.size) { av_log(c->fc, AV_LOG_ERROR, "The key# %"PRIu32" in meta has invalid size:" "%"PRIu32"\n", i, key_size); return AVERROR_INVALIDDATA; } + atom.size -= key_size; key_size -= 8; if (type != MKTAG('m','d','t','a')) { avio_skip(pb, key_size); @@ -4696,6 +4738,8 @@ static int mov_read_chap(MOVContext *c, AVIOContext *pb, MOVAtom atom) for (i = 0; i < num && !pb->eof_reached; i++) c->chapter_tracks[i] = avio_rb32(pb); + c->nb_chapter_tracks = i; + return 0; } @@ -4806,7 +4850,7 @@ static int mov_read_trun(MOVContext *c, AVIOContext *pb, MOVAtom atom) // A valid index_entry means the trun for the fragment was read // and it's samples are in index_entries at the given position. // New index entries will be inserted before the index_entry found. - index_entry_pos = st->internal->nb_index_entries; + index_entry_pos = st->nb_index_entries; for (i = c->frag_index.current + 1; i < c->frag_index.nb_items; i++) { frag_stream_info = get_frag_stream_info(&c->frag_index, i, frag->track_id); if (frag_stream_info && frag_stream_info->index_entry >= 0) { @@ -4815,7 +4859,7 @@ static int mov_read_trun(MOVContext *c, AVIOContext *pb, MOVAtom atom) break; } } - av_assert0(index_entry_pos <= st->internal->nb_index_entries); + av_assert0(index_entry_pos <= st->nb_index_entries); avio_r8(pb); /* version */ flags = avio_rb24(pb); @@ -4866,22 +4910,22 @@ static int mov_read_trun(MOVContext *c, AVIOContext *pb, MOVAtom atom) av_log(c->fc, AV_LOG_TRACE, "first sample flags 0x%x\n", first_sample_flags); // realloc space for new index entries - if((uint64_t)st->internal->nb_index_entries + entries >= UINT_MAX / sizeof(AVIndexEntry)) { - entries = UINT_MAX / sizeof(AVIndexEntry) - st->internal->nb_index_entries; + if((uint64_t)st->nb_index_entries + entries >= UINT_MAX / sizeof(AVIndexEntry)) { + entries = UINT_MAX / sizeof(AVIndexEntry) - st->nb_index_entries; av_log(c->fc, AV_LOG_ERROR, "Failed to add index entry\n"); } if (entries == 0) return 0; - requested_size = (st->internal->nb_index_entries + entries) * sizeof(AVIndexEntry); - new_entries = av_fast_realloc(st->internal->index_entries, - &st->internal->index_entries_allocated_size, + requested_size = (st->nb_index_entries + entries) * sizeof(AVIndexEntry); + new_entries = av_fast_realloc(st->index_entries, + &st->index_entries_allocated_size, requested_size); if (!new_entries) return AVERROR(ENOMEM); - st->internal->index_entries= new_entries; + st->index_entries= new_entries; - requested_size = (st->internal->nb_index_entries + entries) * sizeof(*sc->ctts_data); + requested_size = (st->nb_index_entries + entries) * sizeof(*sc->ctts_data); old_ctts_allocated_size = sc->ctts_allocated_size; ctts_data = av_fast_realloc(sc->ctts_data, &sc->ctts_allocated_size, requested_size); @@ -4895,12 +4939,12 @@ static int mov_read_trun(MOVContext *c, AVIOContext *pb, MOVAtom atom) memset((uint8_t*)(sc->ctts_data) + old_ctts_allocated_size, 0, sc->ctts_allocated_size - old_ctts_allocated_size); - if (index_entry_pos < st->internal->nb_index_entries) { + if (index_entry_pos < st->nb_index_entries) { // Make hole in index_entries and ctts_data for new samples - memmove(st->internal->index_entries + index_entry_pos + entries, - st->internal->index_entries + index_entry_pos, - sizeof(*st->internal->index_entries) * - (st->internal->nb_index_entries - index_entry_pos)); + memmove(st->index_entries + index_entry_pos + entries, + st->index_entries + index_entry_pos, + sizeof(*st->index_entries) * + (st->nb_index_entries - index_entry_pos)); memmove(sc->ctts_data + index_entry_pos + entries, sc->ctts_data + index_entry_pos, sizeof(*sc->ctts_data) * (sc->ctts_count - index_entry_pos)); @@ -4909,15 +4953,15 @@ static int mov_read_trun(MOVContext *c, AVIOContext *pb, MOVAtom atom) } } - st->internal->nb_index_entries += entries; - sc->ctts_count = st->internal->nb_index_entries; + st->nb_index_entries += entries; + sc->ctts_count = st->nb_index_entries; // Record the index_entry position in frag_index of this fragment if (frag_stream_info) frag_stream_info->index_entry = index_entry_pos; if (index_entry_pos > 0) - prev_dts = st->internal->index_entries[index_entry_pos-1].timestamp; + prev_dts = st->index_entries[index_entry_pos-1].timestamp; for (i = 0; i < entries && !pb->eof_reached; i++) { unsigned sample_size = frag->size; @@ -4966,11 +5010,11 @@ static int mov_read_trun(MOVContext *c, AVIOContext *pb, MOVAtom atom) if (prev_dts >= dts) index_entry_flags |= AVINDEX_DISCARD_FRAME; - st->internal->index_entries[index_entry_pos].pos = offset; - st->internal->index_entries[index_entry_pos].timestamp = dts; - st->internal->index_entries[index_entry_pos].size= sample_size; - st->internal->index_entries[index_entry_pos].min_distance= distance; - st->internal->index_entries[index_entry_pos].flags = index_entry_flags; + st->index_entries[index_entry_pos].pos = offset; + st->index_entries[index_entry_pos].timestamp = dts; + st->index_entries[index_entry_pos].size= sample_size; + st->index_entries[index_entry_pos].min_distance= distance; + st->index_entries[index_entry_pos].flags = index_entry_flags; sc->ctts_data[index_entry_pos].count = 1; sc->ctts_data[index_entry_pos].duration = ctts_duration; @@ -4980,6 +5024,8 @@ static int mov_read_trun(MOVContext *c, AVIOContext *pb, MOVAtom atom) "size %u, distance %d, keyframe %d\n", st->index, index_entry_pos, offset, dts, sample_size, distance, keyframe); distance++; + if (av_sat_add64(dts, sample_duration) != dts + (uint64_t)sample_duration) + return AVERROR_INVALIDDATA; dts += sample_duration; offset += sample_size; sc->data_size += sample_size; @@ -4997,16 +5043,16 @@ static int mov_read_trun(MOVContext *c, AVIOContext *pb, MOVAtom atom) // EOF found before reading all entries. Fix the hole this would // leave in index_entries and ctts_data int gap = entries - i; - memmove(st->internal->index_entries + index_entry_pos, - st->internal->index_entries + index_entry_pos + gap, - sizeof(*st->internal->index_entries) * - (st->internal->nb_index_entries - (index_entry_pos + gap))); + memmove(st->index_entries + index_entry_pos, + st->index_entries + index_entry_pos + gap, + sizeof(*st->index_entries) * + (st->nb_index_entries - (index_entry_pos + gap))); memmove(sc->ctts_data + index_entry_pos, sc->ctts_data + index_entry_pos + gap, sizeof(*sc->ctts_data) * (sc->ctts_count - (index_entry_pos + gap))); - st->internal->nb_index_entries -= gap; + st->nb_index_entries -= gap; sc->ctts_count -= gap; if (index_entry_pos < sc->current_sample) { sc->current_sample -= gap; @@ -5019,11 +5065,11 @@ static int mov_read_trun(MOVContext *c, AVIOContext *pb, MOVAtom atom) // fragment that overlap with AVINDEX_DISCARD_FRAME prev_dts = AV_NOPTS_VALUE; if (index_entry_pos > 0) - prev_dts = st->internal->index_entries[index_entry_pos-1].timestamp; - for (i = index_entry_pos; i < st->internal->nb_index_entries; i++) { - if (prev_dts < st->internal->index_entries[i].timestamp) + prev_dts = st->index_entries[index_entry_pos-1].timestamp; + for (i = index_entry_pos; i < st->nb_index_entries; i++) { + if (prev_dts < st->index_entries[i].timestamp) break; - st->internal->index_entries[i].flags |= AVINDEX_DISCARD_FRAME; + st->index_entries[i].flags |= AVINDEX_DISCARD_FRAME; } // If a hole was created to insert the new index_entries into, @@ -5102,6 +5148,8 @@ static int mov_read_sidx(MOVContext *c, AVIOContext *pb, MOVAtom atom) avio_rb16(pb); // reserved item_count = avio_rb16(pb); + if (item_count == 0) + return AVERROR_INVALIDDATA; for (i = 0; i < item_count; i++) { int index; @@ -5120,7 +5168,9 @@ static int mov_read_sidx(MOVContext *c, AVIOContext *pb, MOVAtom atom) if (frag_stream_info) frag_stream_info->sidx_pts = timestamp; - if (av_sat_add64(offset, size) != offset + size) + if (av_sat_add64(offset, size) != offset + (uint64_t)size || + av_sat_add64(pts, duration) != pts + (uint64_t)duration + ) return AVERROR_INVALIDDATA; offset += size; pts += duration; @@ -5132,7 +5182,7 @@ static int mov_read_sidx(MOVContext *c, AVIOContext *pb, MOVAtom atom) // See if the remaining bytes are just an mfra which we can ignore. is_complete = offset == stream_size; - if (!is_complete && (pb->seekable & AVIO_SEEKABLE_NORMAL)) { + if (!is_complete && (pb->seekable & AVIO_SEEKABLE_NORMAL) && stream_size > 0 ) { int64_t ret; int64_t original_pos = avio_tell(pb); if (!c->have_read_mfra_size) { @@ -5143,7 +5193,7 @@ static int mov_read_sidx(MOVContext *c, AVIOContext *pb, MOVAtom atom) if ((ret = avio_seek(pb, original_pos, SEEK_SET)) < 0) return ret; } - if (offset + c->mfra_size == stream_size) + if (offset == stream_size - c->mfra_size) is_complete = 1; } @@ -5316,6 +5366,11 @@ static int mov_read_elst(MOVContext *c, AVIOContext *pb, MOVAtom atom) c->fc->nb_streams-1, i, e->time); return AVERROR_INVALIDDATA; } + if (e->duration < 0) { + av_log(c->fc, AV_LOG_ERROR, "Track %d, edit %d: Invalid edit list duration=%"PRId64"\n", + c->fc->nb_streams-1, i, e->duration); + return AVERROR_INVALIDDATA; + } } sc->elst_count = i; @@ -5425,6 +5480,11 @@ static int mov_read_smdm(MOVContext *c, AVIOContext *pb, MOVAtom atom) av_log(c->fc, AV_LOG_WARNING, "Unsupported Mastering Display Metadata box version %d\n", version); return 0; } + if (sc->mastering) { + av_log(c->fc, AV_LOG_WARNING, "Ignoring duplicate Mastering Display Metadata\n"); + return 0; + } + avio_skip(pb, 3); /* flags */ sc->mastering = av_mastering_display_metadata_alloc(); @@ -5465,6 +5525,11 @@ static int mov_read_mdcv(MOVContext *c, AVIOContext *pb, MOVAtom atom) return AVERROR_INVALIDDATA; } + if (sc->mastering) { + av_log(c->fc, AV_LOG_WARNING, "Ignoring duplicate Mastering Display Color Volume\n"); + return 0; + } + sc->mastering = av_mastering_display_metadata_alloc(); if (!sc->mastering) return AVERROR(ENOMEM); @@ -5508,6 +5573,11 @@ static int mov_read_coll(MOVContext *c, AVIOContext *pb, MOVAtom atom) } avio_skip(pb, 3); /* flags */ + if (sc->coll){ + av_log(c->fc, AV_LOG_WARNING, "Ignoring duplicate COLL\n"); + return 0; + } + sc->coll = av_content_light_metadata_alloc(&sc->coll_size); if (!sc->coll) return AVERROR(ENOMEM); @@ -5532,6 +5602,11 @@ static int mov_read_clli(MOVContext *c, AVIOContext *pb, MOVAtom atom) return AVERROR_INVALIDDATA; } + if (sc->coll){ + av_log(c->fc, AV_LOG_WARNING, "Ignoring duplicate CLLI/COLL\n"); + return 0; + } + sc->coll = av_content_light_metadata_alloc(&sc->coll_size); if (!sc->coll) return AVERROR(ENOMEM); @@ -6103,6 +6178,8 @@ static int mov_read_senc(MOVContext *c, AVIOContext *pb, MOVAtom atom) } if (pb->eof_reached) { av_log(c->fc, AV_LOG_ERROR, "Hit EOF while reading senc\n"); + if (ret >= 0) + av_encryption_info_free(encryption_index->encrypted_samples[i]); ret = AVERROR_INVALIDDATA; } @@ -7041,6 +7118,8 @@ static int mov_read_default(MOVContext *c, AVIOContext *pb, MOVAtom atom) if (a.size == 0) { a.size = atom.size - total_size + 8; } + if (a.size < 0) + break; a.size -= 8; if (a.size < 0) break; @@ -7118,10 +7197,10 @@ static int mov_probe(const AVProbeData *p) int64_t size; int minsize = 8; /* ignore invalid offset */ - if ((offset + 8) > (unsigned int)p->buf_size) + if ((offset + 8ULL) > (unsigned int)p->buf_size) break; size = AV_RB32(p->buf + offset); - if (size == 1 && offset + 16 > (unsigned int)p->buf_size) { + if (size == 1 && offset + 16 <= (unsigned int)p->buf_size) { size = AV_RB64(p->buf+offset + 8); minsize = 16; } else if (size == 0) { @@ -7165,6 +7244,8 @@ static int mov_probe(const AVProbeData *p) score = FFMAX(score, AVPROBE_SCORE_EXTENSION); break; } + if (size > INT64_MAX - offset) + break; offset += size; } if (score > AVPROBE_SCORE_MAX - 50 && moov_offset != -1) { @@ -7221,9 +7302,9 @@ static void mov_read_chapters(AVFormatContext *s) if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) { st->disposition |= AV_DISPOSITION_ATTACHED_PIC | AV_DISPOSITION_TIMED_THUMBNAILS; - if (st->internal->nb_index_entries) { + if (st->nb_index_entries) { // Retrieve the first frame, if possible - AVIndexEntry *sample = &st->internal->index_entries[0]; + AVIndexEntry *sample = &st->index_entries[0]; if (avio_seek(sc->pb, sample->pos, SEEK_SET) != sample->pos) { av_log(s, AV_LOG_ERROR, "Failed to retrieve first frame\n"); goto finish; @@ -7239,9 +7320,9 @@ static void mov_read_chapters(AVFormatContext *s) st->codecpar->codec_type = AVMEDIA_TYPE_DATA; st->codecpar->codec_id = AV_CODEC_ID_BIN_DATA; st->discard = AVDISCARD_ALL; - for (i = 0; i < st->internal->nb_index_entries; i++) { - AVIndexEntry *sample = &st->internal->index_entries[i]; - int64_t end = i+1 < st->internal->nb_index_entries ? st->internal->index_entries[i+1].timestamp : st->duration; + for (i = 0; i < st->nb_index_entries; i++) { + AVIndexEntry *sample = &st->index_entries[i]; + int64_t end = i+1 < st->nb_index_entries ? st->index_entries[i+1].timestamp : st->duration; uint8_t *title; uint16_t ch; int len, title_len; @@ -7314,10 +7395,10 @@ static int mov_read_rtmd_track(AVFormatContext *s, AVStream *st) int64_t cur_pos = avio_tell(sc->pb); int hh, mm, ss, ff, drop; - if (!st->internal->nb_index_entries) + if (!st->nb_index_entries) return -1; - avio_seek(sc->pb, st->internal->index_entries->pos, SEEK_SET); + avio_seek(sc->pb, st->index_entries->pos, SEEK_SET); avio_skip(s->pb, 13); hh = avio_r8(s->pb); mm = avio_r8(s->pb); @@ -7339,10 +7420,10 @@ static int mov_read_timecode_track(AVFormatContext *s, AVStream *st) int64_t cur_pos = avio_tell(sc->pb); uint32_t value; - if (!st->internal->nb_index_entries) + if (!st->nb_index_entries) return -1; - avio_seek(sc->pb, st->internal->index_entries->pos, SEEK_SET); + avio_seek(sc->pb, st->index_entries->pos, SEEK_SET); value = avio_rb32(s->pb); if (sc->tmcd_flags & 0x0001) flags |= AV_TIMECODE_FLAG_DROPFRAME; @@ -7807,15 +7888,16 @@ static AVIndexEntry *mov_find_next_sample(AVFormatContext *s, AVStream **st) for (i = 0; i < s->nb_streams; i++) { AVStream *avst = s->streams[i]; MOVStreamContext *msc = avst->priv_data; - if (msc->pb && msc->current_sample < avst->internal->nb_index_entries) { - AVIndexEntry *current_sample = &avst->internal->index_entries[msc->current_sample]; + if (msc->pb && msc->current_sample < avst->nb_index_entries) { + AVIndexEntry *current_sample = &avst->index_entries[msc->current_sample]; int64_t dts = av_rescale(current_sample->timestamp, AV_TIME_BASE, msc->time_scale); + uint64_t dtsdiff = best_dts > dts ? best_dts - (uint64_t)dts : ((uint64_t)dts - best_dts); av_log(s, AV_LOG_TRACE, "stream %d, sample %d, dts %"PRId64"\n", i, msc->current_sample, dts); if (!sample || (!(s->pb->seekable & AVIO_SEEKABLE_NORMAL) && current_sample->pos < sample->pos) || ((s->pb->seekable & AVIO_SEEKABLE_NORMAL) && ((msc->pb != s->pb && dts < best_dts) || (msc->pb == s->pb && dts != AV_NOPTS_VALUE && - ((FFABS(best_dts - dts) <= AV_TIME_BASE && current_sample->pos < sample->pos) || - (FFABS(best_dts - dts) > AV_TIME_BASE && dts < best_dts)))))) { + ((dtsdiff <= AV_TIME_BASE && current_sample->pos < sample->pos) || + (dtsdiff > AV_TIME_BASE && dts < best_dts)))))) { sample = current_sample; best_dts = dts; *st = avst; @@ -7891,25 +7973,73 @@ static int mov_change_extradata(MOVStreamContext *sc, AVPacket *pkt) return 0; } -static int get_eia608_packet(AVIOContext *pb, AVPacket *pkt, int size) +static int get_eia608_packet(AVIOContext *pb, AVPacket *pkt, int src_size) { - int new_size, ret; + /* We can't make assumptions about the structure of the payload, + because it may include multiple cdat and cdt2 samples. */ + const uint32_t cdat = AV_RB32("cdat"); + const uint32_t cdt2 = AV_RB32("cdt2"); + int ret, out_size = 0; - if (size <= 8) + /* a valid payload must have size, 4cc, and at least 1 byte pair: */ + if (src_size < 10) return AVERROR_INVALIDDATA; - new_size = ((size - 8) / 2) * 3; - ret = av_new_packet(pkt, new_size); + + /* avoid an int overflow: */ + if ((src_size - 8) / 2 >= INT_MAX / 3) + return AVERROR_INVALIDDATA; + + ret = av_new_packet(pkt, ((src_size - 8) / 2) * 3); if (ret < 0) return ret; - avio_skip(pb, 8); - for (int j = 0; j < new_size; j += 3) { - pkt->data[j] = 0xFC; - pkt->data[j+1] = avio_r8(pb); - pkt->data[j+2] = avio_r8(pb); + /* parse and re-format the c608 payload in one pass. */ + while (src_size >= 10) { + const uint32_t atom_size = avio_rb32(pb); + const uint32_t atom_type = avio_rb32(pb); + const uint32_t data_size = atom_size - 8; + const uint8_t cc_field = + atom_type == cdat ? 1 : + atom_type == cdt2 ? 2 : + 0; + + /* account for bytes consumed for atom size and type. */ + src_size -= 8; + + /* make sure the data size stays within the buffer boundaries. */ + if (data_size < 2 || data_size > src_size) { + ret = AVERROR_INVALIDDATA; + break; + } + + /* make sure the data size is consistent with N byte pairs. */ + if (data_size % 2 != 0) { + ret = AVERROR_INVALIDDATA; + break; + } + + if (!cc_field) { + /* neither cdat or cdt2 ... skip it */ + avio_skip(pb, data_size); + src_size -= data_size; + continue; + } + + for (uint32_t i = 0; i < data_size; i += 2) { + pkt->data[out_size] = (0x1F << 3) | (1 << 2) | (cc_field - 1); + pkt->data[out_size + 1] = avio_r8(pb); + pkt->data[out_size + 2] = avio_r8(pb); + out_size += 3; + src_size -= 2; + } } - return 0; + if (src_size > 0) + /* skip any remaining unread portion of the input payload */ + avio_skip(pb, src_size); + + av_shrink_packet(pkt, out_size); + return ret; } static int mov_read_packet(AVFormatContext *s, AVPacket *pkt) @@ -8002,7 +8132,7 @@ static int mov_read_packet(AVFormatContext *s, AVPacket *pkt) pkt->flags |= AV_PKT_FLAG_DISCARD; } if (sc->ctts_data && sc->ctts_index < sc->ctts_count) { - pkt->pts = pkt->dts + sc->dts_shift + sc->ctts_data[sc->ctts_index].duration; + pkt->pts = av_sat_add64(pkt->dts, av_sat_add64(sc->dts_shift, sc->ctts_data[sc->ctts_index].duration)); /* update ctts context */ sc->ctts_sample++; if (sc->ctts_index < sc->ctts_count && @@ -8011,8 +8141,8 @@ static int mov_read_packet(AVFormatContext *s, AVPacket *pkt) sc->ctts_sample = 0; } } else { - int64_t next_dts = (sc->current_sample < st->internal->nb_index_entries) ? - st->internal->index_entries[sc->current_sample].timestamp : st->duration; + int64_t next_dts = (sc->current_sample < st->nb_index_entries) ? + st->index_entries[sc->current_sample].timestamp : st->duration; if (next_dts >= pkt->dts) pkt->duration = next_dts - pkt->dts; @@ -8093,7 +8223,7 @@ static int mov_seek_stream(AVFormatContext *s, AVStream *st, int64_t timestamp, sample = av_index_search_timestamp(st, timestamp, flags); av_log(s, AV_LOG_TRACE, "stream %d, timestamp %"PRId64", sample %d\n", st->index, timestamp, sample); - if (sample < 0 && st->internal->nb_index_entries && timestamp < st->internal->index_entries[0].timestamp) + if (sample < 0 && st->nb_index_entries && timestamp < st->index_entries[0].timestamp) sample = 0; if (sample < 0) /* not sure what to do */ return AVERROR_INVALIDDATA; @@ -8134,8 +8264,8 @@ static int mov_seek_stream(AVFormatContext *s, AVStream *st, int64_t timestamp, static int64_t mov_get_skip_samples(AVStream *st, int sample) { MOVStreamContext *sc = st->priv_data; - int64_t first_ts = st->internal->index_entries[0].timestamp; - int64_t ts = st->internal->index_entries[sample].timestamp; + int64_t first_ts = st->index_entries[0].timestamp; + int64_t ts = st->index_entries[sample].timestamp; int64_t off; if (st->codecpar->codec_type != AVMEDIA_TYPE_AUDIO) @@ -8164,7 +8294,7 @@ static int mov_read_seek(AVFormatContext *s, int stream_index, int64_t sample_ti if (mc->seek_individually) { /* adjust seek timestamp to found sample timestamp */ - int64_t seek_timestamp = st->internal->index_entries[sample].timestamp; + int64_t seek_timestamp = st->index_entries[sample].timestamp; st->internal->skip_samples = mov_get_skip_samples(st, sample); for (i = 0; i < s->nb_streams; i++) { diff --git a/libavformat/movenc.c b/libavformat/movenc.c index 6790fe6c45..b7914e5e56 100644 --- a/libavformat/movenc.c +++ b/libavformat/movenc.c @@ -91,7 +91,7 @@ static const AVOption options[] = { { "frag_duration", "Maximum fragment duration", offsetof(MOVMuxContext, max_fragment_duration), AV_OPT_TYPE_INT, {.i64 = 0}, 0, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM}, { "min_frag_duration", "Minimum fragment duration", offsetof(MOVMuxContext, min_fragment_duration), AV_OPT_TYPE_INT, {.i64 = 0}, 0, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM}, { "frag_size", "Maximum fragment size", offsetof(MOVMuxContext, max_fragment_size), AV_OPT_TYPE_INT, {.i64 = 0}, 0, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM}, - { "ism_lookahead", "Number of lookahead entries for ISM files", offsetof(MOVMuxContext, ism_lookahead), AV_OPT_TYPE_INT, {.i64 = 0}, 0, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM}, + { "ism_lookahead", "Number of lookahead entries for ISM files", offsetof(MOVMuxContext, ism_lookahead), AV_OPT_TYPE_INT, {.i64 = 0}, 0, 255, AV_OPT_FLAG_ENCODING_PARAM}, { "video_track_timescale", "set timescale of all video tracks", offsetof(MOVMuxContext, video_track_timescale), AV_OPT_TYPE_INT, {.i64 = 0}, 0, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM}, { "brand", "Override major brand", offsetof(MOVMuxContext, major_brand), AV_OPT_TYPE_STRING, {.str = NULL}, .flags = AV_OPT_FLAG_ENCODING_PARAM }, { "use_editlist", "use edit list", offsetof(MOVMuxContext, use_editlist), AV_OPT_TYPE_BOOL, {.i64 = -1}, -1, 1, AV_OPT_FLAG_ENCODING_PARAM}, @@ -797,6 +797,7 @@ static int mov_write_dfla_tag(AVIOContext *pb, MOVTrack *track) static int mov_write_dops_tag(AVFormatContext *s, AVIOContext *pb, MOVTrack *track) { int64_t pos = avio_tell(pb); + int channels, channel_map; avio_wb32(pb, 0); ffio_wfourcc(pb, "dOps"); avio_w8(pb, 0); /* Version */ @@ -807,12 +808,22 @@ static int mov_write_dops_tag(AVFormatContext *s, AVIOContext *pb, MOVTrack *tra /* extradata contains an Ogg OpusHead, other than byte-ordering and OpusHead's preceeding magic/version, OpusSpecificBox is currently identical. */ - avio_w8(pb, AV_RB8(track->par->extradata + 9)); /* OuputChannelCount */ + channels = AV_RB8(track->par->extradata + 9); + channel_map = AV_RB8(track->par->extradata + 18); + + avio_w8(pb, channels); /* OuputChannelCount */ avio_wb16(pb, AV_RL16(track->par->extradata + 10)); /* PreSkip */ avio_wb32(pb, AV_RL32(track->par->extradata + 12)); /* InputSampleRate */ avio_wb16(pb, AV_RL16(track->par->extradata + 16)); /* OutputGain */ + avio_w8(pb, channel_map); /* ChannelMappingFamily */ /* Write the rest of the header out without byte-swapping. */ - avio_write(pb, track->par->extradata + 18, track->par->extradata_size - 18); + if (channel_map) { + if (track->par->extradata_size < 21 + channels) { + av_log(s, AV_LOG_ERROR, "invalid extradata size\n"); + return AVERROR_INVALIDDATA; + } + avio_write(pb, track->par->extradata + 19, 2 + channels); /* ChannelMappingTable */ + } return update_size(pb, pos); } @@ -2166,11 +2177,13 @@ static int mov_write_video_tag(AVFormatContext *s, AVIOContext *pb, MOVMuxContex avio_wb16(pb, 0x18); /* Reserved */ if (track->mode == MODE_MOV && track->par->format == AV_PIX_FMT_PAL8) { - int pal_size = 1 << track->par->bits_per_coded_sample; - int i; + int pal_size, i; avio_wb16(pb, 0); /* Color table ID */ avio_wb32(pb, 0); /* Color table seed */ avio_wb16(pb, 0x8000); /* Color table flags */ + if (track->par->bits_per_coded_sample < 0 || track->par->bits_per_coded_sample > 8) + return AVERROR(EINVAL); + pal_size = 1 << track->par->bits_per_coded_sample; avio_wb16(pb, pal_size - 1); /* Color table size (zero-relative) */ for (i = 0; i < pal_size; i++) { uint32_t rgb = track->palette[i]; @@ -5568,6 +5581,12 @@ int ff_mov_write_packet(AVFormatContext *s, AVPacket *pkt) if (ret < 0) return ret; + if (pkt->pts != AV_NOPTS_VALUE && + (uint64_t)pkt->dts - pkt->pts != (int32_t)((uint64_t)pkt->dts - pkt->pts)) { + av_log(s, AV_LOG_WARNING, "pts/dts pair unsupported\n"); + return AVERROR_PATCHWELCOME; + } + if (mov->flags & FF_MOV_FLAG_FRAGMENT) { int ret; if (mov->moov_written || mov->flags & FF_MOV_FLAG_EMPTY_MOOV) { @@ -5746,11 +5765,12 @@ int ff_mov_write_packet(AVFormatContext *s, AVPacket *pkt) if (trk->entry >= trk->cluster_capacity) { unsigned new_capacity = trk->entry + MOV_INDEX_CLUSTER_SIZE; - if (av_reallocp_array(&trk->cluster, new_capacity, - sizeof(*trk->cluster))) { + void *cluster = av_realloc_array(trk->cluster, new_capacity, sizeof(*trk->cluster)); + if (!cluster) { ret = AVERROR(ENOMEM); goto err; } + trk->cluster = cluster; trk->cluster_capacity = new_capacity; } diff --git a/libavformat/mp3dec.c b/libavformat/mp3dec.c index 53f803ef55..e3cafc30ce 100644 --- a/libavformat/mp3dec.c +++ b/libavformat/mp3dec.c @@ -137,9 +137,10 @@ static void read_xing_toc(AVFormatContext *s, int64_t filesize, int64_t duration int fill_index = (mp3->usetoc || fast_seek) && duration > 0; if (!filesize && - !(filesize = avio_size(s->pb))) { + (filesize = avio_size(s->pb)) <= 0) { av_log(s, AV_LOG_WARNING, "Cannot determine file size, skipping TOC table.\n"); fill_index = 0; + filesize = 0; } for (i = 0; i < XING_TOC_COUNT; i++) { @@ -431,8 +432,8 @@ static int mp3_read_header(AVFormatContext *s) } // the seek index is relative to the end of the xing vbr headers - for (i = 0; i < st->internal->nb_index_entries; i++) - st->internal->index_entries[i].pos += avio_tell(s->pb); + for (i = 0; i < st->nb_index_entries; i++) + st->index_entries[i].pos += avio_tell(s->pb); /* the parameters will be extracted from the compressed bitstream */ return 0; @@ -567,7 +568,7 @@ static int mp3_seek(AVFormatContext *s, int stream_index, int64_t timestamp, if (ret < 0) return ret; - ie = &st->internal->index_entries[ret]; + ie = &st->index_entries[ret]; } else if (fast_seek && st->duration > 0 && filesize > 0) { if (!mp3->is_cbr) av_log(s, AV_LOG_WARNING, "Using scaling to seek VBR MP3; may be imprecise.\n"); @@ -584,7 +585,7 @@ static int mp3_seek(AVFormatContext *s, int stream_index, int64_t timestamp, if (best_pos < 0) return best_pos; - if (mp3->is_cbr && ie == &ie1 && mp3->frames) { + if (mp3->is_cbr && ie == &ie1 && mp3->frames && mp3->header_filesize > 0) { int frame_duration = av_rescale(st->duration, 1, mp3->frames); ie1.timestamp = frame_duration * av_rescale(best_pos - s->internal->data_offset, mp3->frames, mp3->header_filesize); } diff --git a/libavformat/mpc.c b/libavformat/mpc.c index 31a2072406..6a94b5d1d0 100644 --- a/libavformat/mpc.c +++ b/libavformat/mpc.c @@ -194,8 +194,8 @@ static int mpc_read_seek(AVFormatContext *s, int stream_index, int64_t timestamp uint32_t lastframe; /* if found, seek there */ - if (index >= 0 && st->internal->index_entries[st->internal->nb_index_entries-1].timestamp >= timestamp - DELAY_FRAMES){ - c->curframe = st->internal->index_entries[index].pos; + if (index >= 0 && st->index_entries[st->nb_index_entries-1].timestamp >= timestamp - DELAY_FRAMES){ + c->curframe = st->index_entries[index].pos; return 0; } /* if timestamp is out of bounds, return error */ diff --git a/libavformat/mpc8.c b/libavformat/mpc8.c index ff7da2ef55..c3d7e115a7 100644 --- a/libavformat/mpc8.c +++ b/libavformat/mpc8.c @@ -127,7 +127,11 @@ static void mpc8_get_chunk_header(AVIOContext *pb, int *tag, int64_t *size) pos = avio_tell(pb); *tag = avio_rl16(pb); *size = ffio_read_varlen(pb); - *size -= avio_tell(pb) - pos; + pos -= avio_tell(pb); + if (av_sat_add64(*size, pos) != (uint64_t)*size + pos) { + *size = -1; + } else + *size += pos; } static void mpc8_parse_seektable(AVFormatContext *s, int64_t off) @@ -173,7 +177,13 @@ static void mpc8_parse_seektable(AVFormatContext *s, int64_t off) } seekd = get_bits(&gb, 4); for(i = 0; i < 2; i++){ - pos = gb_get_v(&gb) + c->header_pos; + pos = gb_get_v(&gb); + if (av_sat_add64(pos, c->header_pos) != pos + (uint64_t)c->header_pos) { + av_free(buf); + return; + } + + pos += c->header_pos; ppos[1 - i] = pos; av_add_index_entry(s->streams[0], pos, i, 0, 0, AVINDEX_KEYFRAME); } @@ -201,8 +211,11 @@ static void mpc8_handle_chunk(AVFormatContext *s, int tag, int64_t chunk_pos, in switch(tag){ case TAG_SEEKTBLOFF: - pos = avio_tell(pb) + size; + pos = avio_tell(pb); off = ffio_read_varlen(pb); + if (pos > INT64_MAX - size || off < 0 || off > INT64_MAX - chunk_pos) + return; + pos += size; mpc8_parse_seektable(s, chunk_pos + off); avio_seek(pb, pos, SEEK_SET); break; @@ -314,9 +327,9 @@ static int mpc8_read_seek(AVFormatContext *s, int stream_index, int64_t timestam int index = av_index_search_timestamp(st, timestamp, flags); if(index < 0) return -1; - if (avio_seek(s->pb, st->internal->index_entries[index].pos, SEEK_SET) < 0) + if (avio_seek(s->pb, st->index_entries[index].pos, SEEK_SET) < 0) return -1; - ff_update_cur_dts(s, st, st->internal->index_entries[index].timestamp); + ff_update_cur_dts(s, st, st->index_entries[index].timestamp); return 0; } diff --git a/libavformat/mpeg.c b/libavformat/mpeg.c index 79610ec600..55789ebb67 100644 --- a/libavformat/mpeg.c +++ b/libavformat/mpeg.c @@ -71,6 +71,9 @@ static int mpegps_probe(const AVProbeData *p) int pes = endpes <= i && check_pes(p->buf + i, p->buf + p->buf_size); int pack = check_pack_header(p->buf + i); + if (len > INT_MAX - i) + break; + if (code == SYSTEM_HEADER_START_CODE) sys++; else if (code == PACK_START_CODE && pack) @@ -551,7 +554,9 @@ redo: static const unsigned char avs_seqh[4] = { 0, 0, 1, 0xb0 }; unsigned char buf[8]; - avio_read(s->pb, buf, 8); + ret = avio_read(s->pb, buf, 8); + if (ret != 8) + return AVERROR_INVALIDDATA; avio_seek(s->pb, -8, SEEK_CUR); if (!memcmp(buf, avs_seqh, 4) && (buf[6] != 0 || buf[7] != 1)) codec_id = AV_CODEC_ID_CAVS; diff --git a/libavformat/mpegts.c b/libavformat/mpegts.c index 6e0d9d7496..4771f5270a 100644 --- a/libavformat/mpegts.c +++ b/libavformat/mpegts.c @@ -1641,6 +1641,8 @@ static int mp4_read_iods(AVFormatContext *s, const uint8_t *buf, unsigned size, MP4DescrParseContext d; int ret; + d.predefined_SLConfigDescriptor_seen = 0; + ret = init_MP4DescrParseContext(&d, s, buf, size, descr, max_descr_count); if (ret < 0) return ret; @@ -2026,6 +2028,7 @@ int ff_parse_mpeg2_descriptor(AVFormatContext *fc, AVStream *st, int stream_type return AVERROR_INVALIDDATA; if (channel_config_code <= 0x8) { st->codecpar->extradata[9] = channels = channel_config_code ? channel_config_code : 2; + AV_WL32(&st->codecpar->extradata[12], 48000); st->codecpar->extradata[18] = channel_config_code ? (channels > 2) : /* Dual Mono */ 255; st->codecpar->extradata[19] = opus_stream_cnt[channel_config_code]; st->codecpar->extradata[20] = opus_coupled_stream_cnt[channel_config_code]; @@ -2555,7 +2558,8 @@ static void pat_cb(MpegTSFilter *filter, const uint8_t *section, int section_len FFSWAP(struct Program, ts->prg[nb_prg], ts->prg[prg_idx]); if (prg_idx >= nb_prg) nb_prg++; - } + } else + nb_prg = 0; } } ts->nb_prg = nb_prg; @@ -2861,8 +2865,8 @@ static int mpegts_resync(AVFormatContext *s, int seekback, const uint8_t *curren int64_t back = FFMIN(seekback, pos); //Special case for files like 01c56b0dc1.ts - if (current_packet[0] == 0x80 && current_packet[12] == 0x47) { - avio_seek(pb, 12 - back, SEEK_CUR); + if (current_packet[0] == 0x80 && current_packet[12] == 0x47 && pos >= TS_PACKET_SIZE) { + avio_seek(pb, 12 - TS_PACKET_SIZE, SEEK_CUR); return 0; } diff --git a/libavformat/msf.c b/libavformat/msf.c index 155f488e44..1eaed54357 100644 --- a/libavformat/msf.c +++ b/libavformat/msf.c @@ -70,6 +70,8 @@ static int msf_read_header(AVFormatContext *s) case 4: case 5: case 6: st->codecpar->block_align = (codec == 4 ? 96 : codec == 5 ? 152 : 192) * st->codecpar->channels; + if (st->codecpar->channels > UINT16_MAX / 2048) + return AVERROR_INVALIDDATA; ret = ff_alloc_extradata(st->codecpar, 14); if (ret < 0) return ret; diff --git a/libavformat/mux.c b/libavformat/mux.c index e98b86a81e..6a557d294e 100644 --- a/libavformat/mux.c +++ b/libavformat/mux.c @@ -1308,7 +1308,7 @@ int av_write_trailer(AVFormatContext *s) ret = s->pb ? s->pb->error : 0; for (i = 0; i < s->nb_streams; i++) { av_freep(&s->streams[i]->priv_data); - av_freep(&s->streams[i]->internal->index_entries); + av_freep(&s->streams[i]->index_entries); } if (s->oformat->priv_class) av_opt_free(s->priv_data); diff --git a/libavformat/mvdec.c b/libavformat/mvdec.c index 2aef93a735..aa7f1a8bca 100644 --- a/libavformat/mvdec.c +++ b/libavformat/mvdec.c @@ -156,7 +156,10 @@ static int parse_audio_var(AVFormatContext *avctx, AVStream *st, } else if (!strcmp(name, "NUM_CHANNELS")) { return set_channels(avctx, st, var_read_int(pb, size)); } else if (!strcmp(name, "SAMPLE_RATE")) { - st->codecpar->sample_rate = var_read_int(pb, size); + int sample_rate = var_read_int(pb, size); + if (sample_rate <= 0) + return AVERROR_INVALIDDATA; + st->codecpar->sample_rate = sample_rate; avpriv_set_pts_info(st, 33, 1, st->codecpar->sample_rate); } else if (!strcmp(name, "SAMPLE_WIDTH")) { uint64_t bpc = var_read_int(pb, size) * (uint64_t)8; @@ -248,7 +251,8 @@ static int read_table(AVFormatContext *avctx, AVStream *st, if (avio_feof(pb)) return AVERROR_EOF; - avio_read(pb, name, 16); + if (avio_read(pb, name, 16) != 16) + return AVERROR_INVALIDDATA; name[sizeof(name) - 1] = 0; size = avio_rb32(pb); if (size < 0) { @@ -438,8 +442,8 @@ static int mv_read_packet(AVFormatContext *avctx, AVPacket *pkt) int64_t ret; uint64_t pos; - if (frame < st->internal->nb_index_entries) { - index = &st->internal->index_entries[frame]; + if (frame < st->nb_index_entries) { + index = &st->index_entries[frame]; pos = avio_tell(pb); if (index->pos > pos) avio_skip(pb, index->pos - pos); diff --git a/libavformat/mvi.c b/libavformat/mvi.c index cfdbe5d273..d005001f5a 100644 --- a/libavformat/mvi.c +++ b/libavformat/mvi.c @@ -32,7 +32,6 @@ typedef struct MviDemuxContext { unsigned int (*get_int)(AVIOContext *); - uint32_t audio_data_size; uint64_t audio_size_counter; uint64_t audio_frame_size; int audio_size_left; @@ -46,6 +45,7 @@ static int read_header(AVFormatContext *s) AVStream *ast, *vst; unsigned int version, frames_count, msecs_per_frame, player_version; int ret; + int audio_data_size; ast = avformat_new_stream(s, NULL); if (!ast) @@ -67,13 +67,13 @@ static int read_header(AVFormatContext *s) vst->codecpar->height = avio_rl16(pb); avio_r8(pb); ast->codecpar->sample_rate = avio_rl16(pb); - mvi->audio_data_size = avio_rl32(pb); + audio_data_size = avio_rl32(pb); avio_r8(pb); player_version = avio_rl32(pb); avio_rl16(pb); avio_r8(pb); - if (frames_count == 0 || mvi->audio_data_size == 0) + if (frames_count == 0 || audio_data_size <= 0) return AVERROR_INVALIDDATA; if (version != 7 || player_version > 213) { @@ -96,16 +96,16 @@ static int read_header(AVFormatContext *s) mvi->get_int = (vst->codecpar->width * (int64_t)vst->codecpar->height < (1 << 16)) ? avio_rl16 : avio_rl24; - mvi->audio_frame_size = ((uint64_t)mvi->audio_data_size << MVI_FRAC_BITS) / frames_count; + mvi->audio_frame_size = ((uint64_t)audio_data_size << MVI_FRAC_BITS) / frames_count; if (mvi->audio_frame_size <= 1 << MVI_FRAC_BITS - 1) { av_log(s, AV_LOG_ERROR, - "Invalid audio_data_size (%"PRIu32") or frames_count (%u)\n", - mvi->audio_data_size, frames_count); + "Invalid audio_data_size (%d) or frames_count (%u)\n", + audio_data_size, frames_count); return AVERROR_INVALIDDATA; } mvi->audio_size_counter = (ast->codecpar->sample_rate * 830 / mvi->audio_frame_size - 1) * mvi->audio_frame_size; - mvi->audio_size_left = mvi->audio_data_size; + mvi->audio_size_left = audio_data_size; return 0; } diff --git a/libavformat/mxfdec.c b/libavformat/mxfdec.c index 1f372affcb..6fe0bed8bf 100644 --- a/libavformat/mxfdec.c +++ b/libavformat/mxfdec.c @@ -60,6 +60,7 @@ #include "mxf.h" #define MXF_MAX_CHUNK_SIZE (32 << 20) +#define RUN_IN_MAX (65535+1) // S377m-2004 section 5.5 and S377-1-2009 section 6.5, the +1 is to be slightly more tolerant typedef enum { Header, @@ -223,7 +224,7 @@ typedef struct MXFDescriptor { typedef struct MXFIndexTableSegment { UID uid; enum MXFMetadataSetType type; - int edit_unit_byte_count; + unsigned edit_unit_byte_count; int index_sid; int body_sid; AVRational index_edit_rate; @@ -419,12 +420,15 @@ static int mxf_read_sync(AVIOContext *pb, const uint8_t *key, unsigned size) return i == size; } -static int klv_read_packet(KLVPacket *klv, AVIOContext *pb) +static int klv_read_packet(MXFContext *mxf, KLVPacket *klv, AVIOContext *pb) { int64_t length, pos; if (!mxf_read_sync(pb, mxf_klv_key, 4)) return AVERROR_INVALIDDATA; klv->offset = avio_tell(pb) - 4; + if (klv->offset < mxf->run_in) + return AVERROR_INVALIDDATA; + memcpy(klv->key, mxf_klv_key, 4); avio_read(pb, klv->key + 4, 12); length = klv_decode_ber_length(pb); @@ -565,6 +569,10 @@ static int mxf_get_d10_aes3_packet(AVIOContext *pb, AVStream *st, AVPacket *pkt, data_ptr = pkt->data; end_ptr = pkt->data + length; buf_ptr = pkt->data + 4; /* skip SMPTE 331M header */ + + if (st->codecpar->channels > 8) + return AVERROR_INVALIDDATA; + for (; end_ptr - buf_ptr >= st->codecpar->channels * 4; ) { for (i = 0; i < st->codecpar->channels; i++) { uint32_t sample = bytestream_get_le32(&buf_ptr); @@ -624,10 +632,11 @@ static int mxf_decrypt_triplet(AVFormatContext *s, AVPacket *pkt, KLVPacket *klv return AVERROR_INVALIDDATA; // enc. code size = klv_decode_ber_length(pb); - if (size < 32 || size - 32 < orig_size) + if (size < 32 || size - 32 < orig_size || (int)orig_size != orig_size) return AVERROR_INVALIDDATA; avio_read(pb, ivec, 16); - avio_read(pb, tmpbuf, 16); + if (avio_read(pb, tmpbuf, 16) != 16) + return AVERROR_INVALIDDATA; if (mxf->aesc) av_aes_crypt(mxf->aesc, tmpbuf, tmpbuf, 1, ivec, 1); if (memcmp(tmpbuf, checkv, 16)) @@ -736,6 +745,9 @@ static int mxf_read_partition_pack(void *arg, AVIOContext *pb, int tag, int size partition->index_sid = avio_rb32(pb); partition->body_offset = avio_rb64(pb); partition->body_sid = avio_rb32(pb); + if (partition->body_offset < 0) + return AVERROR_INVALIDDATA; + if (avio_read(pb, op, sizeof(UID)) != sizeof(UID)) { av_log(mxf->fc, AV_LOG_ERROR, "Failed reading UID\n"); return AVERROR_INVALIDDATA; @@ -871,15 +883,27 @@ static int mxf_read_cryptographic_context(void *arg, AVIOContext *pb, int tag, i static int mxf_read_strong_ref_array(AVIOContext *pb, UID **refs, int *count) { - *count = avio_rb32(pb); + int64_t ret; + unsigned c = avio_rb32(pb); + + //avio_read() used int + if (c > INT_MAX / sizeof(UID)) + return AVERROR_PATCHWELCOME; + *count = c; + av_free(*refs); - *refs = av_calloc(*count, sizeof(UID)); + *refs = av_malloc_array(*count, sizeof(UID)); if (!*refs) { *count = 0; return AVERROR(ENOMEM); } avio_skip(pb, 4); /* useless size of objects, always 16 according to specs */ - avio_read(pb, (uint8_t *)*refs, *count * sizeof(UID)); + ret = avio_read(pb, (uint8_t *)*refs, *count * sizeof(UID)); + if (ret != *count * sizeof(UID)) { + *count = ret < 0 ? 0 : ret / sizeof(UID); + return ret < 0 ? ret : AVERROR_INVALIDDATA; + } + return 0; } @@ -1088,6 +1112,9 @@ static int mxf_read_index_entry_array(AVIOContext *pb, MXFIndexTableSegment *seg { int i, length; + if (segment->temporal_offset_entries) + return AVERROR_INVALIDDATA; + segment->nb_index_entries = avio_rb32(pb); length = avio_rb32(pb); @@ -1136,6 +1163,9 @@ static int mxf_read_index_table_segment(void *arg, AVIOContext *pb, int tag, int case 0x3F0B: segment->index_edit_rate.num = avio_rb32(pb); segment->index_edit_rate.den = avio_rb32(pb); + if (segment->index_edit_rate.num <= 0 || + segment->index_edit_rate.den <= 0) + return AVERROR_INVALIDDATA; av_log(NULL, AV_LOG_TRACE, "IndexEditRate %d/%d\n", segment->index_edit_rate.num, segment->index_edit_rate.den); break; @@ -1350,7 +1380,8 @@ static int mxf_read_indirect_value(void *arg, AVIOContext *pb, int size) if (size <= 17) return 0; - avio_read(pb, key, 17); + if (avio_read(pb, key, 17) != 17) + return AVERROR_INVALIDDATA; /* TODO: handle other types of of indirect values */ if (memcmp(key, mxf_indirect_value_utf16le, 17) == 0) { return mxf_read_utf16le_string(pb, size - 17, &tagged_value->value); @@ -1668,9 +1699,13 @@ static int mxf_edit_unit_absolute_offset(MXFContext *mxf, MXFIndexTable *index_t if (edit_unit < s->index_start_position + s->index_duration) { int64_t index = edit_unit - s->index_start_position; - if (s->edit_unit_byte_count) + if (s->edit_unit_byte_count) { + if (index > INT64_MAX / s->edit_unit_byte_count || + s->edit_unit_byte_count * index > INT64_MAX - offset_temp) + return AVERROR_INVALIDDATA; + offset_temp += s->edit_unit_byte_count * index; - else { + } else { if (s->nb_index_entries == 2 * s->index_duration + 1) index *= 2; /* Avid index */ @@ -1689,6 +1724,11 @@ static int mxf_edit_unit_absolute_offset(MXFContext *mxf, MXFIndexTable *index_t return mxf_absolute_bodysid_offset(mxf, index_table->body_sid, offset_temp, offset_out, partition_out); } else { /* EditUnitByteCount == 0 for VBR indexes, which is fine since they use explicit StreamOffsets */ + if (s->edit_unit_byte_count && (s->index_duration > INT64_MAX / s->edit_unit_byte_count || + s->edit_unit_byte_count * s->index_duration > INT64_MAX - offset_temp) + ) + return AVERROR_INVALIDDATA; + offset_temp += s->edit_unit_byte_count * s->index_duration; } } @@ -2194,6 +2234,9 @@ static int mxf_parse_physical_source_package(MXFContext *mxf, MXFTrack *source_t physical_track->edit_rate, source_track->edit_rate); + if (av_sat_add64(start_position, mxf_tc->start_frame) != start_position + (uint64_t)mxf_tc->start_frame) + return AVERROR_INVALIDDATA; + if (av_timecode_init(&tc, mxf_tc->rate, flags, start_position + mxf_tc->start_frame, mxf->fc) == 0) { mxf_add_timecode_metadata(&st->metadata, "timecode", &tc); return 0; @@ -2249,12 +2292,12 @@ static enum AVColorRange mxf_get_color_range(MXFContext *mxf, MXFDescriptor *des /* CDCI range metadata */ if (!descriptor->component_depth) return AVCOL_RANGE_UNSPECIFIED; - if (descriptor->black_ref_level == 0 && + if (descriptor->black_ref_level == 0 && descriptor->component_depth < 31 && descriptor->white_ref_level == ((1<component_depth) - 1) && (descriptor->color_range == (1<component_depth) || descriptor->color_range == ((1<component_depth) - 1))) return AVCOL_RANGE_JPEG; - if (descriptor->component_depth >= 8 && + if (descriptor->component_depth >= 8 && descriptor->component_depth < 31 && descriptor->black_ref_level == (1 <<(descriptor->component_depth - 4)) && descriptor->white_ref_level == (235<<(descriptor->component_depth - 8)) && descriptor->color_range == ((14<<(descriptor->component_depth - 4)) + 1)) @@ -2672,6 +2715,7 @@ static int mxf_parse_structural_metadata(MXFContext *mxf) if (container_ul->desc) av_dict_set(&st->metadata, "data_type", container_ul->desc, 0); if (mxf->eia608_extract && + container_ul->desc && !strcmp(container_ul->desc, "vbi_vanc_smpte_436M")) { st->codecpar->codec_type = AVMEDIA_TYPE_SUBTITLE; st->codecpar->codec_id = AV_CODEC_ID_EIA_608; @@ -2903,7 +2947,7 @@ static int mxf_read_local_tags(MXFContext *mxf, KLVPacket *klv, MXFMetadataReadF meta = NULL; ctx = mxf; } - while (avio_tell(pb) + 4 < klv_end && !avio_feof(pb)) { + while (avio_tell(pb) + 4ULL < klv_end && !avio_feof(pb)) { int ret; int tag = avio_rb16(pb); int size = avio_rb16(pb); /* KLV specified by 0x53 */ @@ -3029,7 +3073,7 @@ static int mxf_seek_to_previous_partition(MXFContext *mxf) /* Make sure this is actually a PartitionPack, and if so parse it. * See deadlock2.mxf */ - if ((ret = klv_read_packet(&klv, pb)) < 0) { + if ((ret = klv_read_packet(mxf, &klv, pb)) < 0) { av_log(mxf->fc, AV_LOG_ERROR, "failed to read PartitionPack KLV\n"); return ret; } @@ -3311,7 +3355,7 @@ static void mxf_read_random_index_pack(AVFormatContext *s) if (length < min_rip_length || length > max_rip_length) goto end; avio_seek(s->pb, file_size - length, SEEK_SET); - if (klv_read_packet(&klv, s->pb) < 0 || + if (klv_read_packet(mxf, &klv, s->pb) < 0 || !IS_KLV_KEY(klv.key, ff_mxf_random_index_pack_key)) goto end; if (klv.next_klv != file_size || klv.length <= 4 || (klv.length - 4) % 12) { @@ -3338,6 +3382,7 @@ static int mxf_read_header(AVFormatContext *s) KLVPacket klv; int64_t essence_offset = 0; int ret; + int64_t run_in; mxf->last_forward_tell = INT64_MAX; @@ -3348,14 +3393,17 @@ static int mxf_read_header(AVFormatContext *s) } avio_seek(s->pb, -14, SEEK_CUR); mxf->fc = s; - mxf->run_in = avio_tell(s->pb); + run_in = avio_tell(s->pb); + if (run_in < 0 || run_in > RUN_IN_MAX) + return AVERROR_INVALIDDATA; + mxf->run_in = run_in; mxf_read_random_index_pack(s); while (!avio_feof(s->pb)) { const MXFMetadataReadTableEntry *metadata; - if (klv_read_packet(&klv, s->pb) < 0) { + if (klv_read_packet(mxf, &klv, s->pb) < 0) { /* EOF - seek to previous partition or stop */ if(mxf_parse_handle_partition_or_eof(mxf) <= 0) break; @@ -3462,9 +3510,8 @@ static int mxf_get_next_track_edit_unit(MXFContext *mxf, MXFTrack *track, int64_ a = -1; b = track->original_duration; - - while (b - a > 1) { - m = (a + b) >> 1; + while (b - 1 > a) { + m = (a + (uint64_t)b) >> 1; if (mxf_edit_unit_absolute_offset(mxf, t, m, track->edit_rate, NULL, &offset, NULL, 0) < 0) return -1; if (offset < current_offset) @@ -3492,8 +3539,8 @@ static int64_t mxf_compute_sample_count(MXFContext *mxf, AVStream *st, if ((sample_rate.num / sample_rate.den) == 48000) { return av_rescale_q(edit_unit, sample_rate, track->edit_rate); } else { - int remainder = (sample_rate.num * time_base.num) % - (time_base.den * sample_rate.den); + int64_t remainder = (sample_rate.num * (int64_t) time_base.num) % + ( time_base.den * (int64_t)sample_rate.den); if (remainder) av_log(mxf->fc, AV_LOG_WARNING, "seeking detected on stream #%d with time base (%d/%d) and " @@ -3517,7 +3564,7 @@ static int64_t mxf_set_current_edit_unit(MXFContext *mxf, AVStream *st, int64_t int64_t new_edit_unit; MXFIndexTable *t = mxf_find_index_table(mxf, track->index_sid); - if (!t || track->wrapping == UnknownWrapped) + if (!t || track->wrapping == UnknownWrapped || edit_unit > INT64_MAX - track->edit_units_per_packet) return -1; if (mxf_edit_unit_absolute_offset(mxf, t, edit_unit + track->edit_units_per_packet, track->edit_rate, NULL, &next_ofs, NULL, 0) < 0 && @@ -3611,7 +3658,7 @@ static int mxf_read_packet(AVFormatContext *s, AVPacket *pkt) if (pos < mxf->current_klv_data.next_klv - mxf->current_klv_data.length || pos >= mxf->current_klv_data.next_klv) { mxf->current_klv_data = (KLVPacket){{0}}; - ret = klv_read_packet(&klv, s->pb); + ret = klv_read_packet(mxf, &klv, s->pb); if (ret < 0) break; max_data_size = klv.length; @@ -3761,7 +3808,7 @@ static int mxf_read_close(AVFormatContext *s) static int mxf_probe(const AVProbeData *p) { const uint8_t *bufp = p->buf; - const uint8_t *end = p->buf + p->buf_size; + const uint8_t *end = p->buf + FFMIN(p->buf_size, RUN_IN_MAX + 1 + sizeof(mxf_header_partition_pack_key)); if (p->buf_size < sizeof(mxf_header_partition_pack_key)) return 0; diff --git a/libavformat/nistspheredec.c b/libavformat/nistspheredec.c index 78e938da10..b2cbbfefaa 100644 --- a/libavformat/nistspheredec.c +++ b/libavformat/nistspheredec.c @@ -34,7 +34,7 @@ static int nist_probe(const AVProbeData *p) static int nist_read_header(AVFormatContext *s) { - char buffer[256], coding[32] = "pcm", format[32] = "01"; + char buffer[256]= {0}, coding[32] = "pcm", format[32] = "01"; int bps = 0, be = 0; int32_t header_size = -1; AVStream *st; diff --git a/libavformat/nsvdec.c b/libavformat/nsvdec.c index 4fab52ed36..d57a644c67 100644 --- a/libavformat/nsvdec.c +++ b/libavformat/nsvdec.c @@ -603,7 +603,7 @@ null_chunk_retry: pkt = &nsv->ahead[NSV_ST_AUDIO]; /* read raw audio specific header on the first audio chunk... */ /* on ALL audio chunks ?? seems so! */ - if (asize && st[NSV_ST_AUDIO]->codecpar->codec_tag == MKTAG('P', 'C', 'M', ' ')/* && fill_header*/) { + if (asize >= 4 && st[NSV_ST_AUDIO]->codecpar->codec_tag == MKTAG('P', 'C', 'M', ' ')/* && fill_header*/) { uint8_t bps; uint8_t channels; uint16_t samplerate; @@ -682,10 +682,10 @@ static int nsv_read_seek(AVFormatContext *s, int stream_index, int64_t timestamp if(index < 0) return -1; - if (avio_seek(s->pb, st->internal->index_entries[index].pos, SEEK_SET) < 0) + if (avio_seek(s->pb, st->index_entries[index].pos, SEEK_SET) < 0) return -1; - nst->frame_offset = st->internal->index_entries[index].timestamp; + nst->frame_offset = st->index_entries[index].timestamp; nsv->state = NSV_UNSYNC; return 0; } diff --git a/libavformat/nutdec.c b/libavformat/nutdec.c index d1f3496990..5de3ee553a 100644 --- a/libavformat/nutdec.c +++ b/libavformat/nutdec.c @@ -199,6 +199,8 @@ static int decode_main_header(NUTContext *nut) int tmp_stream, tmp_mul, tmp_pts, tmp_size, tmp_res, tmp_head_idx; length = get_packetheader(nut, bc, 1, MAIN_STARTCODE); + if (length == (uint64_t)-1) + return AVERROR_INVALIDDATA; end = length + avio_tell(bc); nut->version = ffio_read_varlen(bc); @@ -242,6 +244,11 @@ static int decode_main_header(NUTContext *nut) for (i = 0; i < 256;) { int tmp_flags = ffio_read_varlen(bc); int tmp_fields = ffio_read_varlen(bc); + if (tmp_fields < 0) { + av_log(s, AV_LOG_ERROR, "fields %d is invalid\n", tmp_fields); + ret = AVERROR_INVALIDDATA; + goto fail; + } if (tmp_fields > 0) tmp_pts = get_s(bc); @@ -286,6 +293,11 @@ static int decode_main_header(NUTContext *nut) ret = AVERROR_INVALIDDATA; goto fail; } + if (tmp_size < 0 || tmp_size > INT_MAX - count) { + av_log(s, AV_LOG_ERROR, "illegal size\n"); + ret = AVERROR_INVALIDDATA; + goto fail; + } for (j = 0; j < count; j++, i++) { if (i == 'N') { @@ -346,8 +358,12 @@ static int decode_main_header(NUTContext *nut) ret = AVERROR(ENOMEM); goto fail; } - for (i = 0; i < stream_count; i++) - avformat_new_stream(s, NULL); + for (i = 0; i < stream_count; i++) { + if (!avformat_new_stream(s, NULL)) { + ret = AVERROR(ENOMEM); + goto fail; + } + } return 0; fail: @@ -795,19 +811,23 @@ 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; nut->avf = s; /* main header */ pos = 0; + ret = 0; do { + if (ret == AVERROR(ENOMEM)) + return ret; + pos = find_startcode(bc, MAIN_STARTCODE, pos) + 1; if (pos < 0 + 1) { av_log(s, AV_LOG_ERROR, "No main startcode found.\n"); goto fail; } - } while (decode_main_header(nut) < 0); + } while ((ret = decode_main_header(nut)) < 0); /* stream headers */ pos = 0; @@ -1235,15 +1255,15 @@ static int read_seek(AVFormatContext *s, int stream_index, return AVERROR(ENOSYS); } - if (st->internal->index_entries) { + if (st->index_entries) { int index = av_index_search_timestamp(st, pts, flags); if (index < 0) index = av_index_search_timestamp(st, pts, flags ^ AVSEEK_FLAG_BACKWARD); if (index < 0) return -1; - pos2 = st->internal->index_entries[index].pos; - ts = st->internal->index_entries[index].timestamp; + pos2 = st->index_entries[index].pos; + ts = st->index_entries[index].timestamp; } else { av_tree_find(nut->syncpoints, &dummy, ff_nut_sp_pts_cmp, (void **) next_node); diff --git a/libavformat/nutenc.c b/libavformat/nutenc.c index 1dcb2be1b1..6d3bf6c21e 100644 --- a/libavformat/nutenc.c +++ b/libavformat/nutenc.c @@ -1013,12 +1013,12 @@ static int nut_write_packet(AVFormatContext *s, AVPacket *pkt) int index = av_index_search_timestamp(st, dts_tb, AVSEEK_FLAG_BACKWARD); if (index >= 0) { - sp_pos = FFMIN(sp_pos, st->internal->index_entries[index].pos); - if (!nut->write_index && 2*index > st->internal->nb_index_entries) { - memmove(st->internal->index_entries, - st->internal->index_entries + index, - sizeof(*st->internal->index_entries) * (st->internal->nb_index_entries - index)); - st->internal->nb_index_entries -= index; + sp_pos = FFMIN(sp_pos, st->index_entries[index].pos); + if (!nut->write_index && 2*index > st->nb_index_entries) { + memmove(st->index_entries, + st->index_entries + index, + sizeof(*st->index_entries) * (st->nb_index_entries - index)); + st->nb_index_entries -= index; } } } diff --git a/libavformat/oggparsetheora.c b/libavformat/oggparsetheora.c index d1064e4328..293d2928b5 100644 --- a/libavformat/oggparsetheora.c +++ b/libavformat/oggparsetheora.c @@ -196,7 +196,7 @@ static int theora_packet(AVFormatContext *s, int idx) if(s->streams[idx]->start_time == AV_NOPTS_VALUE && os->lastpts != AV_NOPTS_VALUE) { s->streams[idx]->start_time = os->lastpts; if (s->streams[idx]->duration > 0) - s->streams[idx]->duration -= s->streams[idx]->start_time; + s->streams[idx]->duration = av_sat_sub64(s->streams[idx]->duration, s->streams[idx]->start_time); } } diff --git a/libavformat/omadec.c b/libavformat/omadec.c index d31b475fd2..0f1c93c0be 100644 --- a/libavformat/omadec.c +++ b/libavformat/omadec.c @@ -494,7 +494,7 @@ static int oma_read_header(AVFormatContext *s) AV_WL16(&edata[6], jsflag); // coding mode AV_WL16(&edata[8], jsflag); // coding mode AV_WL16(&edata[10], 1); // always 1 - // AV_WL16(&edata[12], 0); // always 0 + AV_WL16(&edata[12], 0); // always 0 avpriv_set_pts_info(st, 64, 1, st->codecpar->sample_rate); break; diff --git a/libavformat/pp_bnk.c b/libavformat/pp_bnk.c index 4aa77c1c9d..5ffe733b18 100644 --- a/libavformat/pp_bnk.c +++ b/libavformat/pp_bnk.c @@ -223,7 +223,7 @@ static int pp_bnk_read_header(AVFormatContext *s) par->bits_per_coded_sample = 4; par->bits_per_raw_sample = 16; par->block_align = 1; - par->bit_rate = par->sample_rate * par->bits_per_coded_sample * par->channels; + par->bit_rate = par->sample_rate * (int64_t)par->bits_per_coded_sample * par->channels; avpriv_set_pts_info(st, 64, 1, par->sample_rate); st->start_time = 0; @@ -265,29 +265,25 @@ static int pp_bnk_read_packet(AVFormatContext *s, AVPacket *pkt) size = FFMIN(trk->data_size - trk->bytes_read, PP_BNK_MAX_READ_SIZE); - if (!ctx->is_music) - ret = av_new_packet(pkt, size); - else if (ctx->current_track == 0) - ret = av_new_packet(pkt, size * 2); - else - ret = 0; - + if (!ctx->is_music) { + ret = av_get_packet(s->pb, pkt, size); + if (ret == AVERROR_EOF) { + /* If we've hit EOF, don't attempt this track again. */ + trk->data_size = trk->bytes_read; + continue; + } + } else { + if (!pkt->data && (ret = av_new_packet(pkt, size * 2)) < 0) + return ret; + ret = avio_read(s->pb, pkt->data + size * ctx->current_track, size); + if (ret >= 0 && ret != size) { + /* Only return stereo packets if both tracks could be read. */ + ret = AVERROR_EOF; + } + } if (ret < 0) return ret; - if (ctx->is_music) - ret = avio_read(s->pb, pkt->data + size * ctx->current_track, size); - else - ret = avio_read(s->pb, pkt->data, size); - - if (ret == AVERROR_EOF) { - /* If we've hit EOF, don't attempt this track again. */ - trk->data_size = trk->bytes_read; - continue; - } else if (ret < 0) { - return ret; - } - trk->bytes_read += ret; pkt->flags &= ~AV_PKT_FLAG_CORRUPT; pkt->stream_index = ctx->current_track; @@ -298,8 +294,6 @@ static int pp_bnk_read_packet(AVFormatContext *s, AVPacket *pkt) continue; pkt->stream_index = 0; - } else { - pkt->size = ret; } ctx->current_track++; @@ -319,6 +313,25 @@ static int pp_bnk_read_close(AVFormatContext *s) return 0; } +static int pp_bnk_seek(AVFormatContext *s, int stream_index, + int64_t pts, int flags) +{ + PPBnkCtx *ctx = s->priv_data; + + if (pts != 0) + return AVERROR(EINVAL); + + if (ctx->is_music) { + av_assert0(stream_index == 0); + ctx->tracks[0].bytes_read = 0; + ctx->tracks[1].bytes_read = 0; + } else { + ctx->tracks[stream_index].bytes_read = 0; + } + + return 0; +} + AVInputFormat ff_pp_bnk_demuxer = { .name = "pp_bnk", .long_name = NULL_IF_CONFIG_SMALL("Pro Pinball Series Soundbank"), @@ -326,5 +339,6 @@ AVInputFormat ff_pp_bnk_demuxer = { .read_probe = pp_bnk_probe, .read_header = pp_bnk_read_header, .read_packet = pp_bnk_read_packet, - .read_close = pp_bnk_read_close + .read_close = pp_bnk_read_close, + .read_seek = pp_bnk_seek, }; diff --git a/libavformat/qcp.c b/libavformat/qcp.c index 168030dc16..4478875f2d 100644 --- a/libavformat/qcp.c +++ b/libavformat/qcp.c @@ -93,7 +93,8 @@ static int qcp_read_header(AVFormatContext *s) QCPContext *c = s->priv_data; AVStream *st = avformat_new_stream(s, NULL); uint8_t buf[16]; - int i, nb_rates; + int i; + unsigned nb_rates; if (!st) return AVERROR(ENOMEM); diff --git a/libavformat/rdt.c b/libavformat/rdt.c index e5824f6a48..990a828b9b 100644 --- a/libavformat/rdt.c +++ b/libavformat/rdt.c @@ -204,6 +204,8 @@ ff_rdt_parse_header(const uint8_t *buf, int len, return -1; /* not followed by a data packet */ pkt_len = AV_RB16(buf+3); + if (pkt_len > len) + return AVERROR_INVALIDDATA; buf += pkt_len; len -= pkt_len; consumed += pkt_len; diff --git a/libavformat/realtextdec.c b/libavformat/realtextdec.c index f534774420..368a741240 100644 --- a/libavformat/realtextdec.c +++ b/libavformat/realtextdec.c @@ -111,10 +111,11 @@ static int realtext_read_header(AVFormatContext *s) if (!merge) { const char *begin = ff_smil_get_attr_ptr(buf.str, "begin"); const char *end = ff_smil_get_attr_ptr(buf.str, "end"); + int64_t endi = end ? read_ts(end) : 0; sub->pos = pos; sub->pts = begin ? read_ts(begin) : 0; - sub->duration = end ? (read_ts(end) - sub->pts) : duration; + sub->duration = (end && endi > sub->pts && endi - (uint64_t)sub->pts <= INT64_MAX) ? endi - sub->pts : duration; } } av_bprint_clear(&buf); diff --git a/libavformat/replaygain.c b/libavformat/replaygain.c index 707d3cd4f1..01db483257 100644 --- a/libavformat/replaygain.c +++ b/libavformat/replaygain.c @@ -61,7 +61,7 @@ static int32_t parse_value(const char *value, int32_t min) } } - if (abs(db) > (INT32_MAX - mb) / 100000) + if (llabs(db) > (INT32_MAX - mb) / 100000) return min; return db * 100000 + sign * mb; diff --git a/libavformat/rl2.c b/libavformat/rl2.c index fa1b38b133..cfde23a945 100644 --- a/libavformat/rl2.c +++ b/libavformat/rl2.c @@ -237,9 +237,9 @@ static int rl2_read_packet(AVFormatContext *s, /** check if there is a valid video or audio entry that can be used */ for(i=0; inb_streams; i++){ - if(rl2->index_pos[i] < s->streams[i]->internal->nb_index_entries - && s->streams[i]->internal->index_entries[ rl2->index_pos[i] ].pos < pos){ - sample = &s->streams[i]->internal->index_entries[ rl2->index_pos[i] ]; + if(rl2->index_pos[i] < s->streams[i]->nb_index_entries + && s->streams[i]->index_entries[ rl2->index_pos[i] ].pos < pos){ + sample = &s->streams[i]->index_entries[ rl2->index_pos[i] ]; pos= sample->pos; stream_id= i; } @@ -283,7 +283,7 @@ static int rl2_read_seek(AVFormatContext *s, int stream_index, int64_t timestamp return -1; rl2->index_pos[stream_index] = index; - timestamp = st->internal->index_entries[index].timestamp; + timestamp = st->index_entries[index].timestamp; for(i=0; i < s->nb_streams; i++){ AVStream *st2 = s->streams[i]; diff --git a/libavformat/rmdec.c b/libavformat/rmdec.c index 610189ecb4..2e5762d87a 100644 --- a/libavformat/rmdec.c +++ b/libavformat/rmdec.c @@ -189,7 +189,8 @@ static int rm_read_audio_stream_info(AVFormatContext *s, AVIOContext *pb, st->codecpar->channels = avio_rb16(pb); if (version == 5) { ast->deint_id = avio_rl32(pb); - avio_read(pb, buf, 4); + if (avio_read(pb, buf, 4) != 4) + return AVERROR_INVALIDDATA; buf[4] = 0; } else { AV_WL32(buf, 0); @@ -269,9 +270,9 @@ static int rm_read_audio_stream_info(AVFormatContext *s, AVIOContext *pb, case DEINT_ID_INT4: if (ast->coded_framesize > ast->audio_framesize || sub_packet_h <= 1 || - ast->coded_framesize * sub_packet_h > (2 + (sub_packet_h & 1)) * ast->audio_framesize) + ast->coded_framesize * (uint64_t)sub_packet_h > (2LL + (sub_packet_h & 1)) * ast->audio_framesize) return AVERROR_INVALIDDATA; - if (ast->coded_framesize * sub_packet_h != 2*ast->audio_framesize) { + if (ast->coded_framesize * (uint64_t)sub_packet_h != 2LL*ast->audio_framesize) { avpriv_request_sample(s, "mismatching interleaver parameters"); return AVERROR_INVALIDDATA; } @@ -296,7 +297,7 @@ static int rm_read_audio_stream_info(AVFormatContext *s, AVIOContext *pb, ast->deint_id == DEINT_ID_GENR || ast->deint_id == DEINT_ID_SIPR) { if (st->codecpar->block_align <= 0 || - ast->audio_framesize * sub_packet_h > (unsigned)INT_MAX || + ast->audio_framesize * (uint64_t)sub_packet_h > (unsigned)INT_MAX || ast->audio_framesize * sub_packet_h < st->codecpar->block_align) return AVERROR_INVALIDDATA; if (av_new_packet(&ast->pkt, ast->audio_framesize * sub_packet_h) < 0) @@ -327,6 +328,11 @@ int ff_rm_read_mdpr_codecdata(AVFormatContext *s, AVIOContext *pb, if (codec_data_size == 0) return 0; + // Duplicate tags + if ( st->codecpar->codec_type != AVMEDIA_TYPE_UNKNOWN + && st->codecpar->codec_type != AVMEDIA_TYPE_DATA) + return AVERROR_INVALIDDATA; + avpriv_set_pts_info(st, 64, 1, 1000); codec_pos = avio_tell(pb); v = avio_rb32(pb); @@ -560,6 +566,8 @@ static int rm_read_header(AVFormatContext *s) } tag_size = avio_rb32(pb); + if (tag_size < 0) + return AVERROR_INVALIDDATA; avio_skip(pb, tag_size - 8); for(;;) { @@ -614,8 +622,10 @@ static int rm_read_header(AVFormatContext *s) get_str8(pb, mime, sizeof(mime)); /* mimetype */ st->codecpar->codec_type = AVMEDIA_TYPE_DATA; st->priv_data = ff_rm_alloc_rmstream(); - if (!st->priv_data) - return AVERROR(ENOMEM); + if (!st->priv_data) { + ret = AVERROR(ENOMEM); + goto fail; + } size = avio_rb32(pb); codec_pos = avio_tell(pb); @@ -1010,8 +1020,8 @@ static int rm_read_packet(AVFormatContext *s, AVPacket *pkt) { RMDemuxContext *rm = s->priv_data; AVStream *st = NULL; // init to silence compiler warning - int i, len, res, seq = 1; - int64_t timestamp, pos; + int i, res, seq = 1; + int64_t timestamp, pos, len; int flags; for (;;) { @@ -1030,7 +1040,9 @@ static int rm_read_packet(AVFormatContext *s, AVPacket *pkt) ast = st->priv_data; timestamp = AV_NOPTS_VALUE; len = !ast->audio_framesize ? RAW_PACKET_SIZE : - ast->coded_framesize * ast->sub_packet_h / 2; + ast->coded_framesize * (int64_t)ast->sub_packet_h / 2; + if (len > INT_MAX) + return AVERROR_INVALIDDATA; flags = (seq++ == 1) ? 2 : 0; pos = avio_tell(s->pb); } else { @@ -1249,20 +1261,19 @@ static int ivr_read_header(AVFormatContext *s) } for (n = 0; n < nb_streams; n++) { - st = avformat_new_stream(s, NULL); - if (!st) - return AVERROR(ENOMEM); - st->priv_data = ff_rm_alloc_rmstream(); - if (!st->priv_data) - return AVERROR(ENOMEM); + if (!(st = avformat_new_stream(s, NULL)) || + !(st->priv_data = ff_rm_alloc_rmstream())) { + ret = AVERROR(ENOMEM); + goto fail; + } if (avio_r8(pb) != 1) - return AVERROR_INVALIDDATA; + goto invalid_data; count = avio_rb32(pb); for (i = 0; i < count; i++) { if (avio_feof(pb)) - return AVERROR_INVALIDDATA; + goto invalid_data; type = avio_r8(pb); tlen = avio_rb32(pb); @@ -1274,25 +1285,25 @@ static int ivr_read_header(AVFormatContext *s) } else if (type == 4 && !strncmp(key, "OpaqueData", tlen)) { ret = ffio_ensure_seekback(pb, 4); if (ret < 0) - return ret; + goto fail; if (avio_rb32(pb) == MKBETAG('M', 'L', 'T', 'I')) { ret = rm_read_multi(s, pb, st, NULL); } else { if (avio_feof(pb)) - return AVERROR_INVALIDDATA; + goto invalid_data; avio_seek(pb, -4, SEEK_CUR); ret = ff_rm_read_mdpr_codecdata(s, pb, st, st->priv_data, len, NULL); } if (ret < 0) - return ret; + goto fail; } else if (type == 4) { int j; av_log(s, AV_LOG_DEBUG, "%s = '0x", key); for (j = 0; j < len; j++) { if (avio_feof(pb)) - return AVERROR_INVALIDDATA; + goto invalid_data; av_log(s, AV_LOG_DEBUG, "%X", avio_r8(pb)); } av_log(s, AV_LOG_DEBUG, "'\n"); @@ -1309,14 +1320,19 @@ static int ivr_read_header(AVFormatContext *s) } if (avio_r8(pb) != 6) - return AVERROR_INVALIDDATA; + goto invalid_data; avio_skip(pb, 12); - avio_skip(pb, avio_rb64(pb) + pos - avio_tell(s->pb)); + avio_seek(pb, avio_rb64(pb) + pos, SEEK_SET); if (avio_r8(pb) != 8) - return AVERROR_INVALIDDATA; + goto invalid_data; avio_skip(pb, 8); return 0; +invalid_data: + ret = AVERROR_INVALIDDATA; +fail: + rm_read_close(s); + return ret; } static int ivr_read_packet(AVFormatContext *s, AVPacket *pkt) diff --git a/libavformat/rpl.c b/libavformat/rpl.c index b98488c7b1..5f1eaa2957 100644 --- a/libavformat/rpl.c +++ b/libavformat/rpl.c @@ -101,9 +101,9 @@ static AVRational read_fps(const char* line, int* error) line++; for (; *line>='0' && *line<='9'; line++) { // Truncate any numerator too large to fit into an int64_t - if (num > (INT64_MAX - 9) / 10 || den > INT64_MAX / 10) + if (num > (INT64_MAX - 9) / 10ULL || den > INT64_MAX / 10ULL) break; - num = 10 * num + *line - '0'; + num = 10 * num + (*line - '0'); den *= 10; } if (!num) @@ -117,7 +117,7 @@ static int rpl_read_header(AVFormatContext *s) AVIOContext *pb = s->pb; RPLContext *rpl = s->priv_data; AVStream *vst = NULL, *ast = NULL; - int total_audio_size; + int64_t total_audio_size; int error = 0; const char *endptr; char audio_type[RPL_LINE_LENGTH]; @@ -207,8 +207,10 @@ static int rpl_read_header(AVFormatContext *s) ast->codecpar->bits_per_coded_sample = 4; ast->codecpar->bit_rate = ast->codecpar->sample_rate * - ast->codecpar->bits_per_coded_sample * - ast->codecpar->channels; + (int64_t)ast->codecpar->channels; + if (ast->codecpar->bit_rate > INT64_MAX / ast->codecpar->bits_per_coded_sample) + return AVERROR_INVALIDDATA; + ast->codecpar->bit_rate *= ast->codecpar->bits_per_coded_sample; ast->codecpar->codec_id = AV_CODEC_ID_NONE; switch (audio_format) { @@ -263,6 +265,9 @@ static int rpl_read_header(AVFormatContext *s) "Video stream will be broken!\n", av_fourcc2str(vst->codecpar->codec_tag)); number_of_chunks = read_line_and_int(pb, &error); // number of chunks in the file + if (number_of_chunks == INT_MAX) + return AVERROR_INVALIDDATA; + // The number in the header is actually the index of the last chunk. number_of_chunks++; @@ -274,7 +279,7 @@ static int rpl_read_header(AVFormatContext *s) error |= read_line(pb, line, sizeof(line)); // size of "helpful" sprite if (vst) { error |= read_line(pb, line, sizeof(line)); // offset to key frame list - vst->duration = number_of_chunks * rpl->frames_per_chunk; + vst->duration = number_of_chunks * (int64_t)rpl->frames_per_chunk; } // Read the index @@ -294,6 +299,8 @@ static int rpl_read_header(AVFormatContext *s) if (ast) av_add_index_entry(ast, offset + video_size, total_audio_size, audio_size, audio_size * 8, 0); + if (total_audio_size/8 + (uint64_t)audio_size >= INT64_MAX/8) + return AVERROR_INVALIDDATA; total_audio_size += audio_size * 8; } @@ -317,10 +324,10 @@ static int rpl_read_packet(AVFormatContext *s, AVPacket *pkt) stream = s->streams[rpl->chunk_part]; - if (rpl->chunk_number >= stream->internal->nb_index_entries) + if (rpl->chunk_number >= stream->nb_index_entries) return AVERROR_EOF; - index_entry = &stream->internal->index_entries[rpl->chunk_number]; + index_entry = &stream->index_entries[rpl->chunk_number]; if (rpl->frame_in_part == 0) if (avio_seek(pb, index_entry->pos, SEEK_SET) < 0) @@ -334,7 +341,7 @@ static int rpl_read_packet(AVFormatContext *s, AVPacket *pkt) avio_skip(pb, 4); /* flags */ frame_size = avio_rl32(pb); - if (avio_seek(pb, -8, SEEK_CUR) < 0) + if (avio_feof(pb) || avio_seek(pb, -8, SEEK_CUR) < 0 || !frame_size) return AVERROR(EIO); ret = av_get_packet(pb, pkt, frame_size); diff --git a/libavformat/rtmppkt.c b/libavformat/rtmppkt.c index 00eb0873b2..886d1f4d6f 100644 --- a/libavformat/rtmppkt.c +++ b/libavformat/rtmppkt.c @@ -429,7 +429,6 @@ static int amf_tag_skip(GetByteContext *gb) { AMFDataType type; unsigned nb = -1; - int parse_key = 1; if (bytestream2_get_bytes_left(gb) < 1) return -1; @@ -454,13 +453,12 @@ static int amf_tag_skip(GetByteContext *gb) bytestream2_skip(gb, 10); return 0; case AMF_DATA_TYPE_ARRAY: - parse_key = 0; case AMF_DATA_TYPE_MIXEDARRAY: nb = bytestream2_get_be32(gb); case AMF_DATA_TYPE_OBJECT: - while (nb-- > 0 || type != AMF_DATA_TYPE_ARRAY) { + while (type != AMF_DATA_TYPE_ARRAY || nb-- > 0) { int t; - if (parse_key) { + if (type != AMF_DATA_TYPE_ARRAY) { int size = bytestream2_get_be16(gb); if (!size) { bytestream2_get_byte(gb); diff --git a/libavformat/rtmpproto.c b/libavformat/rtmpproto.c index 5a540e3240..5b5cff63f8 100644 --- a/libavformat/rtmpproto.c +++ b/libavformat/rtmpproto.c @@ -2881,10 +2881,6 @@ reconnect: return 0; fail: - av_freep(&rt->playpath); - av_freep(&rt->tcurl); - av_freep(&rt->flashver); - av_dict_free(opts); rtmp_close(s); return ret; } diff --git a/libavformat/rtpenc_mpegts.c b/libavformat/rtpenc_mpegts.c index 50cebf68a3..da17b1d776 100644 --- a/libavformat/rtpenc_mpegts.c +++ b/libavformat/rtpenc_mpegts.c @@ -20,18 +20,22 @@ */ #include "libavutil/mathematics.h" +#include "libavutil/opt.h" #include "avformat.h" #include "avio_internal.h" -struct MuxChain { +typedef struct MuxChain { + const AVClass *class; AVFormatContext *mpegts_ctx; AVFormatContext *rtp_ctx; AVPacket *pkt; -}; + AVDictionary* mpegts_muxer_options; + AVDictionary* rtp_muxer_options; +} MuxChain; static int rtp_mpegts_write_close(AVFormatContext *s) { - struct MuxChain *chain = s->priv_data; + MuxChain *chain = s->priv_data; if (chain->mpegts_ctx) { av_write_trailer(chain->mpegts_ctx); @@ -50,12 +54,14 @@ static int rtp_mpegts_write_close(AVFormatContext *s) static int rtp_mpegts_write_header(AVFormatContext *s) { - struct MuxChain *chain = s->priv_data; + MuxChain *chain = s->priv_data; AVFormatContext *mpegts_ctx = NULL, *rtp_ctx = NULL; ff_const59 AVOutputFormat *mpegts_format = av_guess_format("mpegts", NULL, NULL); ff_const59 AVOutputFormat *rtp_format = av_guess_format("rtp", NULL, NULL); int i, ret = AVERROR(ENOMEM); AVStream *st; + AVDictionary *mpegts_muxer_options = NULL; + AVDictionary *rtp_muxer_options = NULL; if (!mpegts_format || !rtp_format) return AVERROR(ENOSYS); @@ -74,12 +80,19 @@ static int rtp_mpegts_write_header(AVFormatContext *s) goto fail; st->time_base = s->streams[i]->time_base; st->sample_aspect_ratio = s->streams[i]->sample_aspect_ratio; + st->id = s->streams[i]->id; avcodec_parameters_copy(st->codecpar, s->streams[i]->codecpar); } if ((ret = avio_open_dyn_buf(&mpegts_ctx->pb)) < 0) goto fail; - if ((ret = avformat_write_header(mpegts_ctx, NULL)) < 0) + + av_dict_copy(&mpegts_muxer_options, chain->mpegts_muxer_options, 0); + + ret = avformat_write_header(mpegts_ctx, &mpegts_muxer_options); + av_dict_free(&mpegts_muxer_options); + if (ret < 0) goto fail; + for (i = 0; i < s->nb_streams; i++) s->streams[i]->time_base = mpegts_ctx->streams[i]->time_base; @@ -101,8 +114,12 @@ static int rtp_mpegts_write_header(AVFormatContext *s) st->time_base.den = 90000; st->codecpar->codec_id = AV_CODEC_ID_MPEG2TS; rtp_ctx->pb = s->pb; - if ((ret = avformat_write_header(rtp_ctx, NULL)) < 0) + av_dict_copy(&rtp_muxer_options, chain->rtp_muxer_options, 0); + ret = avformat_write_header(rtp_ctx, &rtp_muxer_options); + av_dict_free(&rtp_muxer_options); + if (ret < 0) goto fail; + chain->rtp_ctx = rtp_ctx; return 0; @@ -120,7 +137,7 @@ fail: static int rtp_mpegts_write_packet(AVFormatContext *s, AVPacket *pkt) { - struct MuxChain *chain = s->priv_data; + MuxChain *chain = s->priv_data; int ret = 0, size; uint8_t *buf; AVPacket *local_pkt = chain->pkt; @@ -155,13 +172,29 @@ static int rtp_mpegts_write_packet(AVFormatContext *s, AVPacket *pkt) return ret; } +#define OFFSET(x) offsetof(MuxChain, x) +#define E AV_OPT_FLAG_ENCODING_PARAM +static const AVOption options[] = { + { "mpegts_muxer_options", "set list of options for the MPEG-TS muxer", OFFSET(mpegts_muxer_options), AV_OPT_TYPE_DICT, {.str = NULL}, 0, 0, E }, + { "rtp_muxer_options", "set list of options for the RTP muxer", OFFSET(rtp_muxer_options), AV_OPT_TYPE_DICT, {.str = NULL}, 0, 0, E }, + { NULL }, +}; + +static const AVClass rtp_mpegts_class = { + .class_name = "rtp_mpegts muxer", + .item_name = av_default_item_name, + .option = options, + .version = LIBAVUTIL_VERSION_INT, +}; + AVOutputFormat ff_rtp_mpegts_muxer = { .name = "rtp_mpegts", .long_name = NULL_IF_CONFIG_SMALL("RTP/mpegts output format"), - .priv_data_size = sizeof(struct MuxChain), + .priv_data_size = sizeof(MuxChain), .audio_codec = AV_CODEC_ID_AAC, .video_codec = AV_CODEC_ID_MPEG4, .write_header = rtp_mpegts_write_header, .write_packet = rtp_mpegts_write_packet, .write_trailer = rtp_mpegts_write_close, + .priv_class = &rtp_mpegts_class, }; diff --git a/libavformat/rtpenc_vc2hq.c b/libavformat/rtpenc_vc2hq.c index 085204fa64..cf548191d2 100644 --- a/libavformat/rtpenc_vc2hq.c +++ b/libavformat/rtpenc_vc2hq.c @@ -45,7 +45,7 @@ static void send_packet(AVFormatContext *ctx, uint8_t parse_code, int info_hdr_s ff_rtp_send_data(ctx, rtp_ctx->buf, RTP_VC2HQ_PL_HEADER_SIZE + info_hdr_size + size, rtp_m); } -static void send_picture(AVFormatContext *ctx, const uint8_t *buf, int size, int interlaced) +static int send_picture(AVFormatContext *ctx, const uint8_t *buf, int size, int interlaced) { RTPMuxContext *rtp_ctx = ctx->priv_data; GetBitContext gc; @@ -54,6 +54,9 @@ static void send_picture(AVFormatContext *ctx, const uint8_t *buf, int size, int uint16_t frag_len; char *info_hdr = &rtp_ctx->buf[4]; + if (size < DIRAC_PIC_NR_SIZE) + return AVERROR(EINVAL); + pic_nr = AV_RB32(&buf[0]); buf += DIRAC_PIC_NR_SIZE; size -= DIRAC_PIC_NR_SIZE; @@ -97,6 +100,7 @@ static void send_picture(AVFormatContext *ctx, const uint8_t *buf, int size, int send_packet(ctx, DIRAC_RTP_PCODE_HQ_PIC_FRAGMENT, 16, buf, frag_len, interlaced, second_field, size > 0 ? 0 : 1); buf += frag_len; } + return 0; } void ff_rtp_send_vc2hq(AVFormatContext *ctx, const uint8_t *frame_buf, int frame_size, int interlaced) @@ -110,16 +114,21 @@ void ff_rtp_send_vc2hq(AVFormatContext *ctx, const uint8_t *frame_buf, int frame parse_code = unit[4]; unit_size = AV_RB32(&unit[5]); + if (unit_size > end - unit) + break; + switch (parse_code) { /* sequence header */ /* end of sequence */ case DIRAC_PCODE_SEQ_HEADER: case DIRAC_PCODE_END_SEQ: - send_packet(ctx, parse_code, 0, unit + DIRAC_DATA_UNIT_HEADER_SIZE, unit_size - DIRAC_DATA_UNIT_HEADER_SIZE, 0, 0, 0); + if (unit_size >= DIRAC_DATA_UNIT_HEADER_SIZE) + send_packet(ctx, parse_code, 0, unit + DIRAC_DATA_UNIT_HEADER_SIZE, unit_size - DIRAC_DATA_UNIT_HEADER_SIZE, 0, 0, 0); break; /* HQ picture */ case DIRAC_PCODE_PICTURE_HQ: - send_picture(ctx, unit + DIRAC_DATA_UNIT_HEADER_SIZE, unit_size - DIRAC_DATA_UNIT_HEADER_SIZE, interlaced); + if (unit_size >= DIRAC_DATA_UNIT_HEADER_SIZE) + send_picture(ctx, unit + DIRAC_DATA_UNIT_HEADER_SIZE, unit_size - DIRAC_DATA_UNIT_HEADER_SIZE, interlaced); break; /* parse codes without specification */ case DIRAC_PCODE_AUX: diff --git a/libavformat/rtsp.c b/libavformat/rtsp.c index 25bdf475b3..2ee430a424 100644 --- a/libavformat/rtsp.c +++ b/libavformat/rtsp.c @@ -412,7 +412,7 @@ static void parse_fmtp(AVFormatContext *s, RTSPState *rt, if (rtsp_st->sdp_payload_type == payload_type && rtsp_st->dynamic_handler && rtsp_st->dynamic_handler->parse_sdp_a_line) { - rtsp_st->dynamic_handler->parse_sdp_a_line(s, i, + rtsp_st->dynamic_handler->parse_sdp_a_line(s, rtsp_st->stream_index, rtsp_st->dynamic_protocol_context, line); } } @@ -952,6 +952,8 @@ static void rtsp_parse_transport(AVFormatContext *s, ";,", &p); } th->transport = RTSP_TRANSPORT_RAW; + } else { + break; } if (!av_strcasecmp(lower_transport, "TCP")) th->lower_transport = RTSP_LOWER_TRANSPORT_TCP; @@ -1419,7 +1421,7 @@ retry: cur_auth_type = rt->auth_state.auth_type; if ((ret = rtsp_send_cmd_with_content_async(s, method, url, header, send_content, - send_content_length))) + send_content_length)) < 0) return ret; if ((ret = ff_rtsp_read_reply(s, reply, content_ptr, 0, method) ) < 0) @@ -1452,6 +1454,8 @@ int ff_rtsp_make_setup_request(AVFormatContext *s, const char *host, int port, char cmd[MAX_URL_SIZE]; const char *trans_pref; + memset(&reply1, 0, sizeof(reply1)); + if (rt->transport == RTSP_TRANSPORT_RDT) trans_pref = "x-pn-tng"; else if (rt->transport == RTSP_TRANSPORT_RAW) @@ -1564,7 +1568,11 @@ int ff_rtsp_make_setup_request(AVFormatContext *s, const char *host, int port, else if (lower_transport == RTSP_LOWER_TRANSPORT_UDP_MULTICAST) { snprintf(transport, sizeof(transport) - 1, "%s/UDP;multicast", trans_pref); + } else { + err = AVERROR(EINVAL); + goto fail; // transport would be uninitialized } + if (s->oformat) { av_strlcat(transport, ";mode=record", sizeof(transport)); } else if (rt->server_type == RTSP_SERVER_REAL || diff --git a/libavformat/sapdec.c b/libavformat/sapdec.c index eec73aa2f4..ef60a1272b 100644 --- a/libavformat/sapdec.c +++ b/libavformat/sapdec.c @@ -198,6 +198,9 @@ static int sap_fetch_packet(AVFormatContext *s, AVPacket *pkt) struct pollfd p = {fd, POLLIN, 0}; uint8_t recvbuf[RTP_MAX_PACKET_LENGTH]; + if (fd < 0) + return fd; + if (sap->eof) return AVERROR_EOF; diff --git a/libavformat/sauce.c b/libavformat/sauce.c index 5ac9ca9d14..a9ee9697a3 100644 --- a/libavformat/sauce.c +++ b/libavformat/sauce.c @@ -34,7 +34,12 @@ int ff_sauce_read(AVFormatContext *avctx, uint64_t *fsize, int *got_width, int g AVIOContext *pb = avctx->pb; char buf[36]; int datatype, filetype, t1, t2, nb_comments; - uint64_t start_pos = avio_size(pb) - 128; + int64_t start_pos = avio_size(pb); + + if (start_pos < 128) + return AVERROR_INVALIDDATA; + + start_pos -= 128; avio_seek(pb, start_pos, SEEK_SET); if (avio_read(pb, buf, 7) != 7) diff --git a/libavformat/sbgdec.c b/libavformat/sbgdec.c index 64c84c1618..a20bc13c8f 100644 --- a/libavformat/sbgdec.c +++ b/libavformat/sbgdec.c @@ -384,7 +384,7 @@ static int parse_options(struct sbg_parser *p) case 'L': FORWARD_ERROR(parse_optarg(p, opt, &oarg)); r = str_to_time(oarg.s, &p->scs.opt_duration); - if (oarg.e != oarg.s + r) { + if (oarg.e != oarg.s + r || p->scs.opt_duration < 0) { snprintf(p->err_msg, sizeof(p->err_msg), "syntax error for option -L"); return AVERROR_INVALIDDATA; @@ -891,7 +891,7 @@ fail: return size; } -static void expand_timestamps(void *log, struct sbg_script *s) +static int expand_timestamps(void *log, struct sbg_script *s) { int i, nb_rel = 0; int64_t now, cur_ts, delta = 0; @@ -935,14 +935,20 @@ static void expand_timestamps(void *log, struct sbg_script *s) } if (s->start_ts == AV_NOPTS_VALUE) s->start_ts = (s->opt_start_at_first && s->tseq) ? s->tseq[0].ts.t : now; + if (s->start_ts > INT64_MAX - s->opt_duration) + return AVERROR_INVALIDDATA; + s->end_ts = s->opt_duration ? s->start_ts + s->opt_duration : AV_NOPTS_VALUE; /* may be overridden later by -E option */ cur_ts = now; for (i = 0; i < s->nb_tseq; i++) { + if (av_sat_add64(s->tseq[i].ts.t, delta) != s->tseq[i].ts.t + (uint64_t)delta) + return AVERROR_INVALIDDATA; if (s->tseq[i].ts.t + delta < cur_ts) delta += DAY_TS; cur_ts = s->tseq[i].ts.t += delta; } + return 0; } static int expand_tseq(void *log, struct sbg_script *s, int *nb_ev_max, @@ -958,6 +964,9 @@ static int expand_tseq(void *log, struct sbg_script *s, int *nb_ev_max, tseq->name_len, tseq->name); return AVERROR(EINVAL); } + if (t0 + (uint64_t)tseq->ts.t != av_sat_add64(t0, tseq->ts.t)) + return AVERROR(EINVAL); + t0 += tseq->ts.t; for (i = 0; i < s->nb_def; i++) { if (s->def[i].name_len == tseq->name_len && @@ -995,7 +1004,9 @@ static int expand_script(void *log, struct sbg_script *s) { int i, r, nb_events_max = 0; - expand_timestamps(log, s); + r = expand_timestamps(log, s); + if (r < 0) + return r; for (i = 0; i < s->nb_tseq; i++) { r = expand_tseq(log, s, &nb_events_max, 0, &s->tseq[i]); if (r < 0) @@ -1277,7 +1288,10 @@ static int generate_intervals(void *log, struct sbg_script *s, int sample_rate, /* SBaGen handles the time before and after the extremal events, and the corresponding transitions, as if the sequence were cyclic with a 24-hours period. */ - period = s->events[s->nb_events - 1].ts - s->events[0].ts; + period = s->events[s->nb_events - 1].ts - (uint64_t)s->events[0].ts; + if (period < 0) + return AVERROR_INVALIDDATA; + period = (period + (DAY_TS - 1)) / DAY_TS * DAY_TS; period = FFMAX(period, DAY_TS); @@ -1286,6 +1300,10 @@ static int generate_intervals(void *log, struct sbg_script *s, int sample_rate, ev1 = &s->events[i]; ev2 = &s->events[(i + 1) % s->nb_events]; ev1->ts_int = ev1->ts; + + if (!ev1->fade.slide && ev1 >= ev2 && ev2->ts > INT64_MAX - period) + return AVERROR_INVALIDDATA; + ev1->ts_trans = ev1->fade.slide ? ev1->ts : ev2->ts + (ev1 < ev2 ? 0 : period); } @@ -1301,6 +1319,8 @@ static int generate_intervals(void *log, struct sbg_script *s, int sample_rate, /* Pseudo event before the first one */ ev0 = s->events[s->nb_events - 1]; + if (av_sat_sub64(ev0.ts_int, period) != (uint64_t)ev0.ts_int - period) + return AVERROR_INVALIDDATA; ev0.ts_int -= period; ev0.ts_trans -= period; ev0.ts_next -= period; diff --git a/libavformat/sccdec.c b/libavformat/sccdec.c index 1786520944..d420f3c461 100644 --- a/libavformat/sccdec.c +++ b/libavformat/sccdec.c @@ -63,8 +63,7 @@ static int scc_read_header(AVFormatContext *s) { SCCContext *scc = s->priv_data; AVStream *st = avformat_new_stream(s, NULL); - char line2[4096], line[4096]; - int64_t pos, ts, next_ts = AV_NOPTS_VALUE; + AVPacket *sub = NULL; ptrdiff_t len; uint8_t out[4096]; FFTextReader tr; @@ -77,47 +76,26 @@ static int scc_read_header(AVFormatContext *s) st->codecpar->codec_type = AVMEDIA_TYPE_SUBTITLE; st->codecpar->codec_id = AV_CODEC_ID_EIA_608; - while (!ff_text_eof(&tr) || next_ts == AV_NOPTS_VALUE || line2[0]) { + while (1) { char *saveptr = NULL, *lline; int hh, mm, ss, fs, i; - AVPacket *sub; + char line[4096]; + int64_t pos, ts; - if (next_ts == AV_NOPTS_VALUE) { - while (!ff_text_eof(&tr)) { - len = ff_subtitles_read_line(&tr, line, sizeof(line)); - if (len <= 13) - continue; + len = ff_subtitles_read_line(&tr, line, sizeof(line)); + if (len <= 13) { + if (ff_text_eof(&tr)) + break; + continue; + } if (!strncmp(line, "Scenarist_SCC V1.0", 18)) continue; - if (av_sscanf(line, "%d:%d:%d%*[:;]%d", &hh, &mm, &ss, &fs) == 4) - break; - } + if (av_sscanf(line, "%d:%d:%d%*[:;]%d", &hh, &mm, &ss, &fs) != 4) + continue; - ts = (hh * 3600LL + mm * 60LL + ss) * 1000LL + fs * 33LL; - - while (!ff_text_eof(&tr)) { - len = ff_subtitles_read_line(&tr, line2, sizeof(line2)); - if (len <= 13) - continue; - - if (av_sscanf(line2, "%d:%d:%d%*[:;]%d", &hh, &mm, &ss, &fs) == 4) - break; - } - } else { - memmove(line, line2, sizeof(line)); - line2[0] = 0; - - while (!ff_text_eof(&tr)) { - len = ff_subtitles_read_line(&tr, line2, sizeof(line2)); - if (len <= 13) - continue; - - if (av_sscanf(line2, "%d:%d:%d%*[:;]%d", &hh, &mm, &ss, &fs) == 4) - break; - } - } - - next_ts = (hh * 3600LL + mm * 60LL + ss) * 1000LL + fs * 33LL; + ts = (hh * 3600LL + mm * 60LL + ss) * 1000LL + fs * 33LL; + if (sub) + sub->duration = ts - sub->pts; pos = ff_text_pos(&tr); lline = (char *)&line; @@ -168,8 +146,6 @@ static int scc_read_header(AVFormatContext *s) sub->pos = pos; sub->pts = ts; - sub->duration = next_ts - ts; - ts = next_ts; } ff_subtitles_queue_finalize(s, &scc->q); diff --git a/libavformat/sctp.c b/libavformat/sctp.c index 9a80e9b015..be0cb47865 100644 --- a/libavformat/sctp.c +++ b/libavformat/sctp.c @@ -282,6 +282,8 @@ fail: goto restart; } fail1: + if (fd >= 0) + closesocket(fd); ret = AVERROR(EIO); freeaddrinfo(ai); return ret; diff --git a/libavformat/sdp.c b/libavformat/sdp.c index 95f3fbb876..334ee0f9df 100644 --- a/libavformat/sdp.c +++ b/libavformat/sdp.c @@ -195,6 +195,8 @@ static char *extradata2psets(AVFormatContext *s, AVCodecParameters *par) continue; } if (p != (psets + strlen(pset_string))) { + if (p - psets >= MAX_PSET_SIZE) + goto fail_in_loop; *p = ','; p++; } @@ -204,6 +206,7 @@ static char *extradata2psets(AVFormatContext *s, AVCodecParameters *par) } if (!av_base64_encode(p, MAX_PSET_SIZE - (p - psets), r, r1 - r)) { av_log(s, AV_LOG_ERROR, "Cannot Base64-encode %"PTRDIFF_SPECIFIER" %"PTRDIFF_SPECIFIER"!\n", MAX_PSET_SIZE - (p - psets), r1 - r); +fail_in_loop: av_free(psets); av_free(tmpbuf); diff --git a/libavformat/sdsdec.c b/libavformat/sdsdec.c index c70f5af849..2289e1bdac 100644 --- a/libavformat/sdsdec.c +++ b/libavformat/sdsdec.c @@ -112,7 +112,7 @@ static int sds_read_header(AVFormatContext *ctx) st->codecpar->codec_type = AVMEDIA_TYPE_AUDIO; st->codecpar->channels = 1; st->codecpar->sample_rate = sample_period ? 1000000000 / sample_period : 16000; - st->duration = (avio_size(pb) - 21) / (127) * s->size / 4; + st->duration = av_rescale((avio_size(pb) - 21) / 127, s->size, 4); avpriv_set_pts_info(st, 64, 1, st->codecpar->sample_rate); diff --git a/libavformat/segafilm.c b/libavformat/segafilm.c index 1225227138..b2d4daf9e1 100644 --- a/libavformat/segafilm.c +++ b/libavformat/segafilm.c @@ -239,6 +239,7 @@ static int film_read_header(AVFormatContext *s) else if (film->audio_type != AV_CODEC_ID_NONE) audio_frame_counter += (film->sample_table[i].sample_size / (film->audio_channels * film->audio_bits / 8)); + film->sample_table[i].keyframe = 1; } else { film->sample_table[i].stream = film->video_stream_index; film->sample_table[i].pts = AV_RB32(&scratch[8]) & 0x7FFFFFFF; @@ -324,7 +325,7 @@ static int film_read_seek(AVFormatContext *s, int stream_index, int64_t timestam if (ret < 0) return ret; - pos = avio_seek(s->pb, st->internal->index_entries[ret].pos, SEEK_SET); + pos = avio_seek(s->pb, st->index_entries[ret].pos, SEEK_SET); if (pos < 0) return pos; diff --git a/libavformat/siff.c b/libavformat/siff.c index 60a867df14..af39bb3734 100644 --- a/libavformat/siff.c +++ b/libavformat/siff.c @@ -199,7 +199,10 @@ static int siff_read_packet(AVFormatContext *s, AVPacket *pkt) if (c->cur_frame >= c->frames) return AVERROR_EOF; if (c->curstrm == -1) { - c->pktsize = avio_rl32(s->pb) - 4; + unsigned pktsize = avio_rl32(s->pb); + if (pktsize < 4) + return AVERROR_INVALIDDATA; + c->pktsize = pktsize - 4; c->flags = avio_rl16(s->pb); if (c->flags & VB_HAS_AUDIO && !c->has_audio) return AVERROR_INVALIDDATA; diff --git a/libavformat/spdifdec.c b/libavformat/spdifdec.c index 1808fa9d65..03b95bd48a 100644 --- a/libavformat/spdifdec.c +++ b/libavformat/spdifdec.c @@ -226,7 +226,7 @@ int ff_spdif_read_packet(AVFormatContext *s, AVPacket *pkt) if (!s->bit_rate && s->streams[0]->codecpar->sample_rate) /* stream bitrate matches 16-bit stereo PCM bitrate for currently supported codecs */ - s->bit_rate = 2 * 16 * s->streams[0]->codecpar->sample_rate; + s->bit_rate = 2 * 16LL * s->streams[0]->codecpar->sample_rate; return 0; } diff --git a/libavformat/subfile.c b/libavformat/subfile.c index 300672e657..e6712806a9 100644 --- a/libavformat/subfile.c +++ b/libavformat/subfile.c @@ -125,9 +125,9 @@ static int64_t subfile_seek(URLContext *h, int64_t pos, int whence) return end; } - if (whence == AVSEEK_SIZE) - return end - c->start; switch (whence) { + case AVSEEK_SIZE: + return end - c->start; case SEEK_SET: new_pos = c->start + pos; break; @@ -137,6 +137,8 @@ static int64_t subfile_seek(URLContext *h, int64_t pos, int whence) case SEEK_END: new_pos = end + pos; break; + default: + av_assert0(0); } if (new_pos < c->start) return AVERROR(EINVAL); diff --git a/libavformat/subtitles.c b/libavformat/subtitles.c index 05c07cd852..576b2c49f1 100644 --- a/libavformat/subtitles.c +++ b/libavformat/subtitles.c @@ -206,7 +206,7 @@ void ff_subtitles_queue_finalize(void *log_ctx, FFDemuxSubtitlesQueue *q) q->sort == SUB_SORT_TS_POS ? cmp_pkt_sub_ts_pos : cmp_pkt_sub_pos_ts); for (i = 0; i < q->nb_subs; i++) - if (q->subs[i]->duration < 0 && i < q->nb_subs - 1) + if (q->subs[i]->duration < 0 && i < q->nb_subs - 1 && q->subs[i + 1]->pts - (uint64_t)q->subs[i]->pts <= INT64_MAX) q->subs[i]->duration = q->subs[i + 1]->pts - q->subs[i]->pts; if (!q->keep_duplicates) @@ -418,6 +418,7 @@ ptrdiff_t ff_subtitles_read_line(FFTextReader *tr, char *buf, size_t size) size_t cur = 0; if (!size) return 0; + buf[0] = '\0'; while (cur + 1 < size) { unsigned char c = ff_text_r8(tr); if (!c) diff --git a/libavformat/subviewerdec.c b/libavformat/subviewerdec.c index 5c2fe676f1..0a2f0da3b1 100644 --- a/libavformat/subviewerdec.c +++ b/libavformat/subviewerdec.c @@ -51,26 +51,32 @@ static int subviewer_probe(const AVProbeData *p) return 0; } +static int get_multiplier(int e) { + switch (e) { + case 1 : return 100; + case 2 : return 10; + case 3 : return 1; + default : return -1; + } +} + static int read_ts(const char *s, int64_t *start, int *duration) { int64_t end; int hh1, mm1, ss1, ms1; int hh2, mm2, ss2, ms2; - int multiplier = 1; + int multiplier1, multiplier2; + int ms1p1, ms1p2, ms2p1, ms2p2; - if (sscanf(s, "%u:%u:%u.%2u,%u:%u:%u.%2u", - &hh1, &mm1, &ss1, &ms1, &hh2, &mm2, &ss2, &ms2) == 8) { - multiplier = 10; - } else if (sscanf(s, "%u:%u:%u.%1u,%u:%u:%u.%1u", - &hh1, &mm1, &ss1, &ms1, &hh2, &mm2, &ss2, &ms2) == 8) { - multiplier = 100; - } - if (sscanf(s, "%u:%u:%u.%u,%u:%u:%u.%u", - &hh1, &mm1, &ss1, &ms1, &hh2, &mm2, &ss2, &ms2) == 8) { - ms1 = FFMIN(ms1, 999); - ms2 = FFMIN(ms2, 999); - end = (hh2*3600LL + mm2*60LL + ss2) * 1000LL + ms2 * multiplier; - *start = (hh1*3600LL + mm1*60LL + ss1) * 1000LL + ms1 * multiplier; + if (sscanf(s, "%u:%u:%u.%n%u%n,%u:%u:%u.%n%u%n", + &hh1, &mm1, &ss1, &ms1p1, &ms1, &ms1p2, &hh2, &mm2, &ss2, &ms2p1, &ms2, &ms2p2) == 8) { + multiplier1 = get_multiplier(ms1p2 - ms1p1); + multiplier2 = get_multiplier(ms2p2 - ms2p1); + if (multiplier1 <= 0 ||multiplier2 <= 0) + return -1; + + end = (hh2*3600LL + mm2*60LL + ss2) * 1000LL + ms2 * multiplier2; + *start = (hh1*3600LL + mm1*60LL + ss1) * 1000LL + ms1 * multiplier1; *duration = end - *start; return 0; } diff --git a/libavformat/tee.c b/libavformat/tee.c index c0b69a386c..6fafc0a99d 100644 --- a/libavformat/tee.c +++ b/libavformat/tee.c @@ -124,6 +124,7 @@ static int close_slave(TeeSlave *tee_slave) unsigned i; int ret = 0; + av_dict_free(&tee_slave->fifo_options); avf = tee_slave->avf; if (!avf) return 0; @@ -229,6 +230,7 @@ static int open_slave(AVFormatContext *avf, char *slave, TeeSlave *tee_slave) av_dict_free(&options); options = tee_slave->fifo_options; + tee_slave->fifo_options = NULL; } ret = avformat_alloc_output_context2(&avf2, NULL, tee_slave->use_fifo ? "fifo" :format, filename); @@ -403,6 +405,8 @@ end: av_free(format); av_free(select); av_free(on_fail); + av_free(use_fifo); + av_free(fifo_options_str); av_dict_free(&options); av_dict_free(&bsf_options); av_freep(&tmp_select); diff --git a/libavformat/tests/url.c b/libavformat/tests/url.c index 2eb597bb5e..8644a3e826 100644 --- a/libavformat/tests/url.c +++ b/libavformat/tests/url.c @@ -18,6 +18,7 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ +#include "config.h" #include "libavformat/url.h" #include "libavformat/avformat.h" @@ -48,19 +49,30 @@ static void test_decompose(const char *url) static void test(const char *base, const char *rel) { - char buf[200], buf2[200]; + char buf[200], buf2[200], buf_dos[200], buf_native[200]; int ret; - ret = ff_make_absolute_url(buf, sizeof(buf), base, rel); + ret = ff_make_absolute_url2(buf, sizeof(buf), base, rel, 0); if (ret < 0) { printf("%50s %-20s => error %s\n", base, rel, av_err2str(ret)); return; } printf("%50s %-20s => %s\n", base, rel, buf); + ret = ff_make_absolute_url2(buf_dos, sizeof(buf_dos), base, rel, 1); + if (ret < 0) + snprintf(buf_dos, sizeof(buf_dos), "error %s", av_err2str(ret)); + ret = ff_make_absolute_url(buf_native, sizeof(buf_native), base, rel); + if (ret < 0) + snprintf(buf_native, sizeof(buf_native), "error %s", av_err2str(ret)); + if (strcmp(buf, buf_dos)) + printf("%50s %-20sDOS %s\n", base, rel, buf_dos); + if (HAVE_DOS_PATHS && strcmp(buf_dos, buf_native) || + !HAVE_DOS_PATHS && strcmp(buf, buf_native)) + printf("Native mismatch\n"); if (base) { /* Test in-buffer replacement */ snprintf(buf2, sizeof(buf2), "%s", base); - ff_make_absolute_url(buf2, sizeof(buf2), buf2, rel); + ff_make_absolute_url2(buf2, sizeof(buf2), buf2, rel, 0); if (strcmp(buf, buf2)) { printf("In-place handling of %s + %s failed\n", base, rel); exit(1); @@ -121,6 +133,21 @@ int main(void) test("http://server/foo/bar", "..doubledotfile"); test("http://server/foo/bar", "double..dotfile"); test("http://server/foo/bar", "doubledotfile.."); + test("file1", "file2"); + test("dir/file1", "file2"); + test("dir/file1", "../file2"); + test("dir\\file1", "file2"); + test("\\\\srv\\shr\\file", "..\\..\\dummy"); + test("\\\\srv\\shr\\file", "dummy"); + test("\\\\srv\\shr\\file", "\\\\srv2\\shr2\\file2"); + test("\\\\srv\\shr\\file", "d:/file"); + test("C:\\dir\\a", "..\\file"); + test("C:\\dir\\a", "\\\\srv\\shr\\file"); + test("C:\\dir\\a", "d:\\file"); + test("http://a/b", "\\\\srv\\shr\\file"); + test("http://a/b", "//srv/shr/file"); + test("http://a/b", "d:\\file"); + test("http://a/b", "C:/file"); /* From https://tools.ietf.org/html/rfc3986#section-5.4 */ test("http://a/b/c/d;p?q", "g:h"); // g:h diff --git a/libavformat/tls_mbedtls.c b/libavformat/tls_mbedtls.c index aadf17760d..beb6e1cf08 100644 --- a/libavformat/tls_mbedtls.c +++ b/libavformat/tls_mbedtls.c @@ -19,8 +19,7 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ -#include -#include +#include #include #include #include @@ -130,9 +129,15 @@ static void handle_pk_parse_error(URLContext *h, int ret) static void handle_handshake_error(URLContext *h, int ret) { switch (ret) { +#if MBEDTLS_VERSION_MAJOR < 3 case MBEDTLS_ERR_SSL_NO_USABLE_CIPHERSUITE: av_log(h, AV_LOG_ERROR, "None of the common ciphersuites is usable. Was the local certificate correctly set?\n"); break; +#else + case MBEDTLS_ERR_SSL_HANDSHAKE_FAILURE: + av_log(h, AV_LOG_ERROR, "TLS handshake failed.\n"); + break; +#endif case MBEDTLS_ERR_SSL_FATAL_ALERT_MESSAGE: av_log(h, AV_LOG_ERROR, "A fatal alert message was received from the peer, has the peer a correct certificate?\n"); break; @@ -195,16 +200,6 @@ static int tls_open(URLContext *h, const char *uri, int flags, AVDictionary **op } } - // load key file - if (shr->key_file) { - if ((ret = mbedtls_pk_parse_keyfile(&tls_ctx->priv_key, - shr->key_file, - tls_ctx->priv_key_pw)) != 0) { - handle_pk_parse_error(h, ret); - goto fail; - } - } - // seed the random number generator if ((ret = mbedtls_ctr_drbg_seed(&tls_ctx->ctr_drbg_context, mbedtls_entropy_func, @@ -214,6 +209,21 @@ static int tls_open(URLContext *h, const char *uri, int flags, AVDictionary **op goto fail; } + // load key file + if (shr->key_file) { + if ((ret = mbedtls_pk_parse_keyfile(&tls_ctx->priv_key, + shr->key_file, + tls_ctx->priv_key_pw +#if MBEDTLS_VERSION_MAJOR >= 3 + , mbedtls_ctr_drbg_random, + &tls_ctx->ctr_drbg_context +#endif + )) != 0) { + handle_pk_parse_error(h, ret); + goto fail; + } + } + if ((ret = mbedtls_ssl_config_defaults(&tls_ctx->ssl_config, shr->listen ? MBEDTLS_SSL_IS_SERVER : MBEDTLS_SSL_IS_CLIENT, MBEDTLS_SSL_TRANSPORT_STREAM, diff --git a/libavformat/tls_schannel.c b/libavformat/tls_schannel.c index d4959f75fa..bbeb8a81f2 100644 --- a/libavformat/tls_schannel.c +++ b/libavformat/tls_schannel.c @@ -388,7 +388,7 @@ static int tls_read(URLContext *h, uint8_t *buf, int len) SECURITY_STATUS sspi_ret = SEC_E_OK; SecBuffer inbuf[4]; SecBufferDesc inbuf_desc; - int size, ret; + int size, ret = 0; int min_enc_buf_size = len + SCHANNEL_FREE_BUFFER_SIZE; /* If we have some left-over data from previous network activity, diff --git a/libavformat/tmv.c b/libavformat/tmv.c index b74af547c5..57f2e09df6 100644 --- a/libavformat/tmv.c +++ b/libavformat/tmv.c @@ -103,6 +103,10 @@ static int tmv_read_header(AVFormatContext *s) char_cols = avio_r8(pb); char_rows = avio_r8(pb); tmv->video_chunk_size = char_cols * char_rows * 2; + if (!tmv->video_chunk_size) { + av_log(s, AV_LOG_ERROR, "invalid video chunk size\n"); + return AVERROR_INVALIDDATA; + } features = avio_r8(pb); if (features & ~(TMV_PADDING | TMV_STEREO)) { diff --git a/libavformat/tta.c b/libavformat/tta.c index 46c2508bce..b34630d1d7 100644 --- a/libavformat/tta.c +++ b/libavformat/tta.c @@ -91,7 +91,7 @@ static int tta_read_header(AVFormatContext *s) c->totalframes = nb_samples / c->frame_size + (c->last_frame_size < c->frame_size); c->currentframe = 0; - if(c->totalframes >= UINT_MAX/sizeof(uint32_t) || c->totalframes <= 0){ + if(c->totalframes >= (INT_MAX - 4)/sizeof(uint32_t) || c->totalframes <= 0){ av_log(s, AV_LOG_ERROR, "totalframes %d invalid\n", c->totalframes); return AVERROR_INVALIDDATA; } @@ -119,6 +119,8 @@ static int tta_read_header(AVFormatContext *s) for (i = 0; i < c->totalframes; i++) { uint32_t size = avio_rl32(s->pb); int r; + if (avio_feof(s->pb)) + return AVERROR_INVALIDDATA; if ((r = av_add_index_entry(st, framepos, i * (int64_t)c->frame_size, size, 0, AVINDEX_KEYFRAME)) < 0) return r; @@ -155,15 +157,15 @@ static int tta_read_packet(AVFormatContext *s, AVPacket *pkt) if (c->currentframe >= c->totalframes) return AVERROR_EOF; - if (st->internal->nb_index_entries < c->totalframes) { + if (st->nb_index_entries < c->totalframes) { av_log(s, AV_LOG_ERROR, "Index entry disappeared\n"); return AVERROR_INVALIDDATA; } - size = st->internal->index_entries[c->currentframe].size; + size = st->index_entries[c->currentframe].size; ret = av_get_packet(s->pb, pkt, size); - pkt->dts = st->internal->index_entries[c->currentframe++].timestamp; + pkt->dts = st->index_entries[c->currentframe++].timestamp; pkt->duration = c->currentframe == c->totalframes ? c->last_frame_size : c->frame_size; return ret; @@ -176,7 +178,7 @@ static int tta_read_seek(AVFormatContext *s, int stream_index, int64_t timestamp int index = av_index_search_timestamp(st, timestamp, flags); if (index < 0) return -1; - if (avio_seek(s->pb, st->internal->index_entries[index].pos, SEEK_SET) < 0) + if (avio_seek(s->pb, st->index_entries[index].pos, SEEK_SET) < 0) return -1; c->currentframe = index; diff --git a/libavformat/tty.c b/libavformat/tty.c index aed5c888c3..b47f874c60 100644 --- a/libavformat/tty.c +++ b/libavformat/tty.c @@ -122,13 +122,16 @@ static int read_header(AVFormatContext *avctx) s->chars_per_frame = FFMAX(av_q2d(st->time_base)*s->chars_per_frame, 1); if (avctx->pb->seekable & AVIO_SEEKABLE_NORMAL) { - s->fsize = avio_size(avctx->pb); - st->duration = (s->fsize + s->chars_per_frame - 1) / s->chars_per_frame; + int64_t fsize = avio_size(avctx->pb); + if (fsize > 0) { + s->fsize = fsize; + st->duration = (s->fsize + s->chars_per_frame - 1) / s->chars_per_frame; - if (ff_sauce_read(avctx, &s->fsize, 0, 0) < 0) - efi_read(avctx, s->fsize - 51); + if (ff_sauce_read(avctx, &s->fsize, 0, 0) < 0) + efi_read(avctx, s->fsize - 51); - avio_seek(avctx->pb, 0, SEEK_SET); + avio_seek(avctx->pb, 0, SEEK_SET); + } } fail: diff --git a/libavformat/ty.c b/libavformat/ty.c index c8e1067c0e..c5ea4bf98d 100644 --- a/libavformat/ty.c +++ b/libavformat/ty.c @@ -47,7 +47,7 @@ static const uint8_t ty_AC3AudioPacket[] = { 0x00, 0x00, 0x01, 0xbd }; #define CHUNK_PEEK_COUNT 3 /* number of chunks to probe */ typedef struct TyRecHdr { - int64_t rec_size; + int32_t rec_size; uint8_t ex[2]; uint8_t rec_type; uint8_t subrec_type; diff --git a/libavformat/udp.c b/libavformat/udp.c index 9b9d3de197..1f8b85cfca 100644 --- a/libavformat/udp.c +++ b/libavformat/udp.c @@ -740,8 +740,10 @@ static int udp_open(URLContext *h, const char *uri, int flags) /* XXX: fix av_url_split */ if (hostname[0] == '\0' || hostname[0] == '?') { /* only accepts null hostname if input */ - if (!(flags & AVIO_FLAG_READ)) + if (!(flags & AVIO_FLAG_READ)) { + ret = AVERROR(EINVAL); goto fail; + } } else { if ((ret = ff_udp_set_remote_url(h, uri)) < 0) goto fail; @@ -754,8 +756,10 @@ static int udp_open(URLContext *h, const char *uri, int flags) udp_fd = udp_socket_create(h, &my_addr, &len, localaddr); else udp_fd = udp_socket_create(h, &my_addr, &len, s->localaddr); - if (udp_fd < 0) + if (udp_fd < 0) { + ret = AVERROR(EIO); goto fail; + } s->local_addr_storage=my_addr; //store for future multicast join diff --git a/libavformat/url.c b/libavformat/url.c index 77d610d95f..f53fdf59d8 100644 --- a/libavformat/url.c +++ b/libavformat/url.c @@ -149,6 +149,18 @@ int ff_url_decompose(URLComponents *uc, const char *url, const char *end) return 0; } +static int is_fq_dos_path(const char *path) +{ + if ((path[0] >= 'a' && path[0] <= 'z' || path[0] >= 'A' && path[0] <= 'Z') && + path[1] == ':' && + (path[2] == '/' || path[2] == '\\')) + return 1; + if ((path[0] == '/' || path[0] == '\\') && + (path[1] == '/' || path[1] == '\\')) + return 1; + return 0; +} + static int append_path(char *root, char *out_end, char **rout, const char *in, const char *in_end) { @@ -178,13 +190,14 @@ static int append_path(char *root, char *out_end, char **rout, return 0; } -int ff_make_absolute_url(char *buf, int size, const char *base, - const char *rel) +int ff_make_absolute_url2(char *buf, int size, const char *base, + const char *rel, int handle_dos_paths) { URLComponents ub, uc; char *out, *out_end, *path; const char *keep, *base_path_end; int use_base_path, simplify_path = 0, ret; + const char *base_separators = "/"; /* This is tricky. For HTTP, http://server/site/page + ../media/file @@ -211,6 +224,15 @@ int ff_make_absolute_url(char *buf, int size, const char *base, if (!base) base = ""; + if (handle_dos_paths) { + if ((ret = ff_url_decompose(&ub, base, NULL)) < 0) + goto error; + if (is_fq_dos_path(base) || av_strstart(base, "file:", NULL) || ub.path == ub.url) { + base_separators = "/\\"; + if (is_fq_dos_path(rel)) + base = ""; + } + } if ((ret = ff_url_decompose(&ub, base, NULL)) < 0 || (ret = ff_url_decompose(&uc, rel, NULL)) < 0) goto error; @@ -249,7 +271,7 @@ int ff_make_absolute_url(char *buf, int size, const char *base, if (use_base_path) { base_path_end = ub.url_component_end_path; if (URL_COMPONENT_HAVE(uc, path)) - while (base_path_end > ub.path && base_path_end[-1] != '/') + while (base_path_end > ub.path && !strchr(base_separators, base_path_end[-1])) base_path_end--; } if (keep > ub.path) @@ -294,6 +316,12 @@ error: return ret; } +int ff_make_absolute_url(char *buf, int size, const char *base, + const char *rel) +{ + return ff_make_absolute_url2(buf, size, base, rel, HAVE_DOS_PATHS); +} + AVIODirEntry *ff_alloc_dir_entry(void) { AVIODirEntry *entry = av_mallocz(sizeof(AVIODirEntry)); diff --git a/libavformat/url.h b/libavformat/url.h index f13e851a14..3bb1cf89f7 100644 --- a/libavformat/url.h +++ b/libavformat/url.h @@ -308,6 +308,16 @@ int ff_url_join(char *str, int size, const char *proto, * @param size the size of buf * @param base the base url, may be equal to buf. * @param rel the new url, which is interpreted relative to base + * @param handle_dos_paths handle DOS paths for file or unspecified protocol + */ +int ff_make_absolute_url2(char *buf, int size, const char *base, + const char *rel, int handle_dos_paths); + +/** + * Convert a relative url into an absolute url, given a base url. + * + * Same as ff_make_absolute_url2 with handle_dos_paths being equal to + * HAVE_DOS_PATHS config variable. */ int ff_make_absolute_url(char *buf, int size, const char *base, const char *rel); diff --git a/libavformat/utils.c b/libavformat/utils.c index 295e676c9c..d79a13ca7a 100644 --- a/libavformat/utils.c +++ b/libavformat/utils.c @@ -1208,7 +1208,9 @@ static void update_initial_durations(AVFormatContext *s, AVStream *st, (pktl->pkt.dts == AV_NOPTS_VALUE || pktl->pkt.dts == st->first_dts || pktl->pkt.dts == RELATIVE_TS_BASE) && - !pktl->pkt.duration) { + !pktl->pkt.duration && + av_sat_add64(cur_dts, duration) == cur_dts + (uint64_t)duration + ) { pktl->pkt.dts = cur_dts; if (!st->internal->avctx->has_b_frames) pktl->pkt.pts = cur_dts; @@ -1275,7 +1277,7 @@ static void compute_pkt_fields(AVFormatContext *s, AVStream *st, presentation_delayed = 1; if (pkt->pts != AV_NOPTS_VALUE && pkt->dts != AV_NOPTS_VALUE && - st->pts_wrap_bits < 63 && pkt->dts > INT64_MIN + (1LL << (st->pts_wrap_bits - 1)) && + st->pts_wrap_bits < 63 && pkt->dts > INT64_MIN + (1LL << st->pts_wrap_bits) && pkt->dts - (1LL << (st->pts_wrap_bits - 1)) > pkt->pts) { if (is_relative(st->cur_dts) || pkt->dts - (1LL<<(st->pts_wrap_bits - 1)) > st->cur_dts) { pkt->dts -= 1LL << st->pts_wrap_bits; @@ -1941,11 +1943,11 @@ void ff_reduce_index(AVFormatContext *s, int stream_index) AVStream *st = s->streams[stream_index]; unsigned int max_entries = s->max_index_size / sizeof(AVIndexEntry); - if ((unsigned) st->internal->nb_index_entries >= max_entries) { + if ((unsigned) st->nb_index_entries >= max_entries) { int i; - for (i = 0; 2 * i < st->internal->nb_index_entries; i++) - st->internal->index_entries[i] = st->internal->index_entries[2 * i]; - st->internal->nb_index_entries = i; + for (i = 0; 2 * i < st->nb_index_entries; i++) + st->index_entries[i] = st->index_entries[2 * i]; + st->nb_index_entries = i; } } @@ -2012,8 +2014,8 @@ int av_add_index_entry(AVStream *st, int64_t pos, int64_t timestamp, int size, int distance, int flags) { timestamp = wrap_timestamp(st, timestamp); - return ff_add_index_entry(&st->internal->index_entries, &st->internal->nb_index_entries, - &st->internal->index_entries_allocated_size, pos, + return ff_add_index_entry(&st->index_entries, &st->nb_index_entries, + &st->index_entries_allocated_size, pos, timestamp, size, distance, flags); } @@ -2089,13 +2091,13 @@ void ff_configure_buffers_for_index(AVFormatContext *s, int64_t time_tolerance) if (ist1 == ist2) continue; - for (i1 = i2 = 0; i1 < st1->internal->nb_index_entries; i1++) { - AVIndexEntry *e1 = &st1->internal->index_entries[i1]; + for (i1 = i2 = 0; i1 < st1->nb_index_entries; i1++) { + AVIndexEntry *e1 = &st1->index_entries[i1]; int64_t e1_pts = av_rescale_q(e1->timestamp, st1->time_base, AV_TIME_BASE_Q); skip = FFMAX(skip, e1->size); - for (; i2 < st2->internal->nb_index_entries; i2++) { - AVIndexEntry *e2 = &st2->internal->index_entries[i2]; + for (; i2 < st2->nb_index_entries; i2++) { + AVIndexEntry *e2 = &st2->index_entries[i2]; int64_t e2_pts = av_rescale_q(e2->timestamp, st2->time_base, AV_TIME_BASE_Q); if (e2_pts < e1_pts || e2_pts - (uint64_t)e1_pts < time_tolerance) continue; @@ -2127,7 +2129,7 @@ void ff_configure_buffers_for_index(AVFormatContext *s, int64_t time_tolerance) int av_index_search_timestamp(AVStream *st, int64_t wanted_timestamp, int flags) { - return ff_index_search_timestamp(st->internal->index_entries, st->internal->nb_index_entries, + return ff_index_search_timestamp(st->index_entries, st->nb_index_entries, wanted_timestamp, flags); } @@ -2144,7 +2146,7 @@ int ff_seek_frame_binary(AVFormatContext *s, int stream_index, int64_t target_ts, int flags) { const AVInputFormat *avif = s->iformat; - int64_t av_uninit(pos_min), av_uninit(pos_max), pos, pos_limit; + int64_t pos_min = 0, pos_max = 0, pos, pos_limit; int64_t ts_min, ts_max, ts; int index; int64_t ret; @@ -2160,7 +2162,7 @@ int ff_seek_frame_binary(AVFormatContext *s, int stream_index, pos_limit = -1; // GCC falsely says it may be uninitialized. st = s->streams[stream_index]; - if (st->internal->index_entries) { + if (st->index_entries) { AVIndexEntry *e; /* FIXME: Whole function must be checked for non-keyframe entries in @@ -2168,7 +2170,7 @@ int ff_seek_frame_binary(AVFormatContext *s, int stream_index, index = av_index_search_timestamp(st, target_ts, flags | AVSEEK_FLAG_BACKWARD); index = FFMAX(index, 0); - e = &st->internal->index_entries[index]; + e = &st->index_entries[index]; if (e->timestamp <= target_ts || e->pos == e->min_distance) { pos_min = e->pos; @@ -2181,9 +2183,9 @@ int ff_seek_frame_binary(AVFormatContext *s, int stream_index, index = av_index_search_timestamp(st, target_ts, flags & ~AVSEEK_FLAG_BACKWARD); - av_assert0(index < st->internal->nb_index_entries); + av_assert0(index < st->nb_index_entries); if (index >= 0) { - e = &st->internal->index_entries[index]; + e = &st->index_entries[index]; av_assert1(e->timestamp >= target_ts); pos_max = e->pos; ts_max = e->timestamp; @@ -2384,17 +2386,17 @@ static int seek_frame_generic(AVFormatContext *s, int stream_index, index = av_index_search_timestamp(st, timestamp, flags); - if (index < 0 && st->internal->nb_index_entries && - timestamp < st->internal->index_entries[0].timestamp) + if (index < 0 && st->nb_index_entries && + timestamp < st->index_entries[0].timestamp) return -1; - if (index < 0 || index == st->internal->nb_index_entries - 1) { + if (index < 0 || index == st->nb_index_entries - 1) { AVPacket *pkt = s->internal->pkt; int nonkey = 0; - if (st->internal->nb_index_entries) { - av_assert0(st->internal->index_entries); - ie = &st->internal->index_entries[st->internal->nb_index_entries - 1]; + if (st->nb_index_entries) { + av_assert0(st->index_entries); + ie = &st->index_entries[st->nb_index_entries - 1]; if ((ret = avio_seek(s->pb, ie->pos, SEEK_SET)) < 0) return ret; ff_update_cur_dts(s, st, ie->timestamp); @@ -2432,7 +2434,7 @@ static int seek_frame_generic(AVFormatContext *s, int stream_index, if (s->iformat->read_seek) if (s->iformat->read_seek(s, stream_index, timestamp, flags) >= 0) return 0; - ie = &st->internal->index_entries[index]; + ie = &st->index_entries[index]; if ((ret = avio_seek(s->pb, ie->pos, SEEK_SET)) < 0) return ret; ff_update_cur_dts(s, st, ie->timestamp); @@ -3415,7 +3417,8 @@ void ff_rfps_calculate(AVFormatContext *ic) // the check for tb_unreliable() is not completely correct, since this is not about handling // an unreliable/inexact time base, but a time base that is finer than necessary, as e.g. // ipmovie.c produces. - if (tb_unreliable(st->internal->avctx) && st->internal->info->duration_count > 15 && st->internal->info->duration_gcd > FFMAX(1, st->time_base.den/(500LL*st->time_base.num)) && !st->r_frame_rate.num) + if (tb_unreliable(st->internal->avctx) && st->internal->info->duration_count > 15 && st->internal->info->duration_gcd > FFMAX(1, st->time_base.den/(500LL*st->time_base.num)) && !st->r_frame_rate.num && + st->internal->info->duration_gcd < INT64_MAX / st->time_base.num) av_reduce(&st->r_frame_rate.num, &st->r_frame_rate.den, st->time_base.den, st->time_base.num * st->internal->info->duration_gcd, INT_MAX); if (st->internal->info->duration_count>1 && !st->r_frame_rate.num && tb_unreliable(st->internal->avctx)) { @@ -3911,8 +3914,10 @@ FF_ENABLE_DEPRECATION_WARNINGS av_packet_unref(pkt1); break; } - if (pkt->duration) { - if (avctx->codec_type == AVMEDIA_TYPE_SUBTITLE && pkt->pts != AV_NOPTS_VALUE && st->start_time != AV_NOPTS_VALUE && pkt->pts >= st->start_time) { + if (pkt->duration > 0) { + if (avctx->codec_type == AVMEDIA_TYPE_SUBTITLE && pkt->pts != AV_NOPTS_VALUE && st->start_time != AV_NOPTS_VALUE && pkt->pts >= st->start_time + && (uint64_t)pkt->pts - st->start_time < INT64_MAX + ) { st->internal->info->codec_info_duration = FFMIN(pkt->pts - st->start_time, st->internal->info->codec_info_duration + pkt->duration); } else st->internal->info->codec_info_duration += pkt->duration; @@ -4058,7 +4063,7 @@ FF_ENABLE_DEPRECATION_WARNINGS if (!st->r_frame_rate.num) { if ( avctx->time_base.den * (int64_t) st->time_base.num - <= avctx->time_base.num * avctx->ticks_per_frame * (uint64_t) st->time_base.den) { + <= avctx->time_base.num * (uint64_t)avctx->ticks_per_frame * st->time_base.den) { av_reduce(&st->r_frame_rate.num, &st->r_frame_rate.den, avctx->time_base.den, (int64_t)avctx->time_base.num * avctx->ticks_per_frame, INT_MAX); } else { @@ -4391,7 +4396,7 @@ static void free_stream(AVStream **pst) avcodec_free_context(&st->internal->avctx); av_bsf_free(&st->internal->bsfc); av_freep(&st->internal->priv_pts); - av_freep(&st->internal->index_entries); + av_freep(&st->index_entries); av_freep(&st->internal->probe_data.buf); av_bsf_free(&st->internal->extract_extradata.bsf); @@ -4602,7 +4607,7 @@ fail: AVProgram *av_new_program(AVFormatContext *ac, int id) { AVProgram *program = NULL; - int i; + int i, ret; av_log(ac, AV_LOG_TRACE, "new_program: id=0x%04x\n", id); @@ -4614,7 +4619,11 @@ AVProgram *av_new_program(AVFormatContext *ac, int id) program = av_mallocz(sizeof(AVProgram)); if (!program) return NULL; - dynarray_add(&ac->programs, &ac->nb_programs, program); + ret = av_dynarray_add_nofree(&ac->programs, &ac->nb_programs, program); + if (ret < 0) { + av_free(program); + return NULL; + } program->discard = AVDISCARD_NONE; program->pmt_version = -1; program->id = id; @@ -4634,7 +4643,7 @@ AVChapter *avpriv_new_chapter(AVFormatContext *s, int64_t id, AVRational time_ba int64_t start, int64_t end, const char *title) { AVChapter *chapter = NULL; - int i; + int i, ret; if (end != AV_NOPTS_VALUE && start > end) { av_log(s, AV_LOG_ERROR, "Chapter end time %"PRId64" before start %"PRId64"\n", end, start); @@ -4654,7 +4663,11 @@ AVChapter *avpriv_new_chapter(AVFormatContext *s, int64_t id, AVRational time_ba chapter = av_mallocz(sizeof(AVChapter)); if (!chapter) return NULL; - dynarray_add(&s->chapters, &s->nb_chapters, chapter); + ret = av_dynarray_add_nofree(&s->chapters, &s->nb_chapters, chapter); + if (ret < 0) { + av_free(chapter); + return NULL; + } } av_dict_set(&chapter->metadata, "title", title, 0); chapter->id = id; @@ -4984,7 +4997,7 @@ void ff_parse_key_value(const char *str, ff_parse_key_val_cb callback_get_buf, key_len = ptr - key; callback_get_buf(context, key, key_len, &dest, &dest_len); - dest_end = dest + dest_len - 1; + dest_end = dest ? dest + dest_len - 1 : NULL; if (*ptr == '\"') { ptr++; diff --git a/libavformat/vividas.c b/libavformat/vividas.c index d745770dc4..f42d16e462 100644 --- a/libavformat/vividas.c +++ b/libavformat/vividas.c @@ -267,7 +267,7 @@ static uint8_t *read_sb_block(AVIOContext *src, unsigned *size, *size = n; n -= 8; - if (avio_read(src, buf+8, n) < n) { + if (avio_read(src, buf+8, n) != n) { av_free(buf); return NULL; } @@ -561,7 +561,8 @@ static int viv_read_header(AVFormatContext *s) v = avio_r8(pb); avio_seek(pb, v, SEEK_CUR); - avio_read(pb, keybuffer, 187); + if (avio_read(pb, keybuffer, 187) != 187) + return AVERROR_INVALIDDATA; key = decode_key(keybuffer); viv->sb_key = key; @@ -683,6 +684,7 @@ static int viv_read_packet(AVFormatContext *s, if (viv->sb_entries[viv->current_sb_entry].flag == 0) { uint64_t v_size = ffio_read_varlen(pb); + int last = 0, last_start; if (!viv->num_audio) return AVERROR_INVALIDDATA; @@ -706,12 +708,18 @@ static int viv_read_packet(AVFormatContext *s, if (i > 0 && start == 0) break; + if (start < last) + return AVERROR_INVALIDDATA; viv->n_audio_subpackets = i + 1; + last = viv->audio_subpackets[i].start = start; viv->audio_subpackets[i].pcm_bytes = pcm_bytes; } + last_start = viv->audio_subpackets[viv->n_audio_subpackets].start = (int)(off - avio_tell(pb)); + if (last_start < last) + return AVERROR_INVALIDDATA; viv->current_audio_subpacket = 0; } else { @@ -757,18 +765,23 @@ static int viv_read_seek(AVFormatContext *s, int stream_index, int64_t timestamp for (int i = 0; i < viv->n_sb_blocks; i++) { if (frame >= viv->sb_blocks[i].packet_offset && frame < viv->sb_blocks[i].packet_offset + viv->sb_blocks[i].n_packets) { - // flush audio packet queue - viv->current_audio_subpacket = 0; - viv->n_audio_subpackets = 0; viv->current_sb = i; // seek to ith sb block avio_seek(s->pb, viv->sb_offset + viv->sb_blocks[i].byte_offset, SEEK_SET); // load the block load_sb_block(s, viv, 0); - // most problematic part: guess audio offset - viv->audio_sample = av_rescale_q(viv->sb_blocks[i].packet_offset, av_make_q(s->streams[1]->codecpar->sample_rate, 1), av_inv_q(s->streams[0]->time_base)); - // hand-tuned 1.s a/v offset - viv->audio_sample += s->streams[1]->codecpar->sample_rate; + if (viv->num_audio) { + const AVCodecParameters *par = s->streams[1]->codecpar; + // flush audio packet queue + viv->current_audio_subpacket = 0; + viv->n_audio_subpackets = 0; + // most problematic part: guess audio offset + viv->audio_sample = av_rescale_q(viv->sb_blocks[i].packet_offset, + av_make_q(par->sample_rate, 1), + av_inv_q(s->streams[0]->time_base)); + // hand-tuned 1.s a/v offset + viv->audio_sample += par->sample_rate; + } viv->current_sb_entry = 0; return 1; } diff --git a/libavformat/vivo.c b/libavformat/vivo.c index fb58aa6178..78d1377e6b 100644 --- a/libavformat/vivo.c +++ b/libavformat/vivo.c @@ -26,6 +26,7 @@ * @sa http://wiki.multimedia.cx/index.php?title=Vivo */ +#include "libavutil/avstring.h" #include "libavutil/parseutils.h" #include "avformat.h" #include "internal.h" @@ -120,7 +121,7 @@ static int vivo_get_packet_header(AVFormatContext *s) static int vivo_read_header(AVFormatContext *s) { VivoContext *vivo = s->priv_data; - AVRational fps = { 1, 25}; + AVRational fps = { 0 }; AVStream *ast, *vst; unsigned char *line, *line_end, *key, *value; long value_int; @@ -206,17 +207,21 @@ static int vivo_read_header(AVFormatContext *s) return AVERROR_INVALIDDATA; value_used = 1; } else if (!strcmp(key, "FPS")) { - AVRational tmp; + double d; + if (av_sscanf(value, "%f", &d) != 1) + return AVERROR_INVALIDDATA; value_used = 1; - if (!av_parse_ratio(&tmp, value, 10000, AV_LOG_WARNING, s)) - fps = av_inv_q(tmp); + if (!fps.num && !fps.den) + fps = av_inv_q(av_d2q(d, 10000)); } if (!value_used) av_dict_set(&s->metadata, key, value, 0); } } + if (!fps.num || !fps.den) + fps = (AVRational){ 1, 25 }; avpriv_set_pts_info(ast, 64, 1, ast->codecpar->sample_rate); avpriv_set_pts_info(vst, 64, fps.num, fps.den); diff --git a/libavformat/vocdec.c b/libavformat/vocdec.c index 6cdc720ee7..2ccabf0fa8 100644 --- a/libavformat/vocdec.c +++ b/libavformat/vocdec.c @@ -83,14 +83,14 @@ static int voc_read_seek(AVFormatContext *s, int stream_index, st = s->streams[stream_index]; index = av_index_search_timestamp(st, timestamp, flags); - if (index >= 0 && index < st->internal->nb_index_entries - 1) { - AVIndexEntry *e = &st->internal->index_entries[index]; + if (index >= 0 && index < st->nb_index_entries - 1) { + AVIndexEntry *e = &st->index_entries[index]; avio_seek(s->pb, e->pos, SEEK_SET); voc->pts = e->timestamp; voc->remaining_size = e->size; return 0; - } else if (st->internal->nb_index_entries && st->internal->index_entries[0].timestamp <= timestamp) { - AVIndexEntry *e = &st->internal->index_entries[st->internal->nb_index_entries - 1]; + } else if (st->nb_index_entries && st->index_entries[0].timestamp <= timestamp) { + AVIndexEntry *e = &st->index_entries[st->nb_index_entries - 1]; // prepare context for seek_frame_generic() voc->pts = e->timestamp; voc->remaining_size = e->size; diff --git a/libavformat/vqf.c b/libavformat/vqf.c index 449f4061f7..48942a2822 100644 --- a/libavformat/vqf.c +++ b/libavformat/vqf.c @@ -49,22 +49,28 @@ static int vqf_probe(const AVProbeData *probe_packet) return AVPROBE_SCORE_EXTENSION; } -static void add_metadata(AVFormatContext *s, uint32_t tag, +static int add_metadata(AVFormatContext *s, uint32_t tag, unsigned int tag_len, unsigned int remaining) { int len = FFMIN(tag_len, remaining); char *buf, key[5] = {0}; + int ret; if (len == UINT_MAX) - return; + return AVERROR_INVALIDDATA; buf = av_malloc(len+1); if (!buf) - return; - avio_read(s->pb, buf, len); + return AVERROR(ENOMEM); + + ret = avio_read(s->pb, buf, len); + if (ret < 0) + return ret; + if (len != ret) + return AVERROR_INVALIDDATA; buf[len] = 0; AV_WL32(key, tag); - av_dict_set(&s->metadata, key, buf, AV_DICT_DONT_STRDUP_VAL); + return av_dict_set(&s->metadata, key, buf, AV_DICT_DONT_STRDUP_VAL); } static const AVMetadataConv vqf_metadata_conv[] = { @@ -162,7 +168,9 @@ static int vqf_read_header(AVFormatContext *s) avio_skip(s->pb, FFMIN(len, header_size)); break; default: - add_metadata(s, chunk_tag, len, header_size); + ret = add_metadata(s, chunk_tag, len, header_size); + if (ret < 0) + return ret; break; } diff --git a/libavformat/wavdec.c b/libavformat/wavdec.c index 8214ab8498..37a214b27e 100644 --- a/libavformat/wavdec.c +++ b/libavformat/wavdec.c @@ -442,7 +442,7 @@ static int wav_read_header(AVFormatContext *s) } if (rf64 || bw64) { - next_tag_ofs = wav->data_end = avio_tell(pb) + data_size; + next_tag_ofs = wav->data_end = av_sat_add64(avio_tell(pb), data_size); } else if (size != 0xFFFFFFFF) { data_size = size; next_tag_ofs = wav->data_end = size ? next_tag_ofs : INT64_MAX; @@ -498,6 +498,8 @@ static int wav_read_header(AVFormatContext *s) wav->smv_data_ofs = avio_tell(pb) + (size - 5) * 3; avio_rl24(pb); wav->smv_block_size = avio_rl24(pb); + if (!wav->smv_block_size) + return AVERROR_INVALIDDATA; avpriv_set_pts_info(vst, 32, 1, avio_rl24(pb)); vst->duration = avio_rl24(pb); avio_rl24(pb); @@ -718,12 +720,16 @@ smv_retry: if (wav->smv_last_stream) { uint64_t old_pos = avio_tell(s->pb); uint64_t new_pos = wav->smv_data_ofs + - wav->smv_block * wav->smv_block_size; + wav->smv_block * (int64_t)wav->smv_block_size; if (avio_seek(s->pb, new_pos, SEEK_SET) < 0) { ret = AVERROR_EOF; goto smv_out; } size = avio_rl24(s->pb); + if (size > wav->smv_block_size) { + ret = AVERROR_EOF; + goto smv_out; + } ret = av_get_packet(s->pb, pkt, size); if (ret < 0) goto smv_out; @@ -759,6 +765,8 @@ smv_out: goto smv_retry; return AVERROR_EOF; } + if (INT64_MAX - left < avio_tell(s->pb)) + return AVERROR_INVALIDDATA; wav->data_end = avio_tell(s->pb) + left; } @@ -851,8 +859,7 @@ static int w64_read_header(AVFormatContext *s) uint8_t guid[16]; int ret; - avio_read(pb, guid, 16); - if (memcmp(guid, ff_w64_guid_riff, 16)) + if (avio_read(pb, guid, 16) != 16 || memcmp(guid, ff_w64_guid_riff, 16)) return AVERROR_INVALIDDATA; /* riff + wave + fmt + sizes */ diff --git a/libavformat/webmdashenc.c b/libavformat/webmdashenc.c index 332d0466e1..181ae9db69 100644 --- a/libavformat/webmdashenc.c +++ b/libavformat/webmdashenc.c @@ -93,7 +93,7 @@ static int write_header(AVFormatContext *s) } avio_printf(pb, " minBufferTime=\"PT%gS\"\n", min_buffer_time); avio_printf(pb, " profiles=\"%s\"%s", - w->is_live ? "urn:mpeg:dash:profile:isoff-live:2011" : "urn:webm:dash:profile:webm-on-demand:2012", + w->is_live ? "urn:mpeg:dash:profile:isoff-live:2011" : "urn:mpeg:dash:profile:webm-on-demand:2012", w->is_live ? "\n" : ">\n"); if (w->is_live) { time_t local_time = time(NULL); @@ -155,7 +155,8 @@ static int bitstream_switching(AVFormatContext *s, const AdaptationSet *as) !av_strstart(track_num->value, gold_track_num->value, NULL) || gold_par->codec_id != par->codec_id || gold_par->extradata_size != par->extradata_size || - memcmp(gold_par->extradata, par->extradata, par->extradata_size)) { + (par->extradata_size > 0 && + memcmp(gold_par->extradata, par->extradata, par->extradata_size))) { return 0; } } diff --git a/libavformat/webpenc.c b/libavformat/webpenc.c index 9fb472257d..99aa23bad4 100644 --- a/libavformat/webpenc.c +++ b/libavformat/webpenc.c @@ -53,24 +53,22 @@ static int webp_write_header(AVFormatContext *s) static int is_animated_webp_packet(AVPacket *pkt) { - if (pkt->size) { int skip = 0; unsigned flags = 0; if (pkt->size < 4) - return 0; + return AVERROR_INVALIDDATA; if (AV_RL32(pkt->data) == AV_RL32("RIFF")) skip = 12; - + // Safe to do this as a valid WebP bitstream is >=30 bytes. if (pkt->size < skip + 4) - return 0; + return AVERROR_INVALIDDATA; if (AV_RL32(pkt->data + skip) == AV_RL32("VP8X")) { flags |= pkt->data[skip + 4 + 4]; } if (flags & 2) // ANIMATION_FLAG is on return 1; - } return 0; } @@ -84,13 +82,9 @@ static int flush(AVFormatContext *s, int trailer, int64_t pts) unsigned flags = 0; int vp8x = 0; - if (w->last_pkt.size < 4) - return 0; if (AV_RL32(w->last_pkt.data) == AV_RL32("RIFF")) skip = 12; - if (w->last_pkt.size < skip + 4) - return 0; // Safe to do this as a valid WebP bitstream is >=30 bytes. if (AV_RL32(w->last_pkt.data + skip) == AV_RL32("VP8X")) { flags |= w->last_pkt.data[skip + 4 + 4]; vp8x = 1; @@ -149,7 +143,14 @@ static int flush(AVFormatContext *s, int trailer, int64_t pts) static int webp_write_packet(AVFormatContext *s, AVPacket *pkt) { WebpContext *w = s->priv_data; - w->using_webp_anim_encoder |= is_animated_webp_packet(pkt); + int ret; + + if (!pkt->size) + return 0; + ret = is_animated_webp_packet(pkt); + if (ret < 0) + return ret; + w->using_webp_anim_encoder |= ret; if (w->using_webp_anim_encoder) { avio_write(s->pb, pkt->data, pkt->size); @@ -190,6 +191,13 @@ static int webp_write_trailer(AVFormatContext *s) return 0; } +static void webp_deinit(AVFormatContext *s) +{ + WebpContext *w = s->priv_data; + + av_packet_unref(&w->last_pkt); +} + #define OFFSET(x) offsetof(WebpContext, x) #define ENC AV_OPT_FLAG_ENCODING_PARAM static const AVOption options[] = { @@ -213,6 +221,7 @@ AVOutputFormat ff_webp_muxer = { .write_header = webp_write_header, .write_packet = webp_write_packet, .write_trailer = webp_write_trailer, + .deinit = webp_deinit, .priv_class = &webp_muxer_class, .flags = AVFMT_VARIABLE_FPS, }; diff --git a/libavformat/westwood_vqa.c b/libavformat/westwood_vqa.c index a0db854b1c..c83b84c4ba 100644 --- a/libavformat/westwood_vqa.c +++ b/libavformat/westwood_vqa.c @@ -163,13 +163,15 @@ static int wsvqa_read_packet(AVFormatContext *s, int ret = -1; uint8_t preamble[VQA_PREAMBLE_SIZE]; uint32_t chunk_type; - uint32_t chunk_size; - int skip_byte; + int chunk_size; + unsigned skip_byte; while (avio_read(pb, preamble, VQA_PREAMBLE_SIZE) == VQA_PREAMBLE_SIZE) { chunk_type = AV_RB32(&preamble[0]); chunk_size = AV_RB32(&preamble[4]); + if (chunk_size < 0) + return AVERROR_INVALIDDATA; skip_byte = chunk_size & 0x01; if ((chunk_type == SND0_TAG) || (chunk_type == SND1_TAG) || @@ -230,7 +232,7 @@ static int wsvqa_read_packet(AVFormatContext *s, break; case SND2_TAG: /* 2 samples/byte, 1 or 2 samples per frame depending on stereo */ - pkt->duration = (chunk_size * 2) / wsvqa->channels; + pkt->duration = (chunk_size * 2LL) / wsvqa->channels; break; } break; diff --git a/libavformat/wtvdec.c b/libavformat/wtvdec.c index 7def9d2348..48661f4720 100644 --- a/libavformat/wtvdec.c +++ b/libavformat/wtvdec.c @@ -182,7 +182,7 @@ static AVIOContext * wtvfile_open_sector(unsigned first_sector, uint64_t length, int nb_sectors1 = read_ints(s->pb, sectors1, WTV_SECTOR_SIZE / 4); int i; - wf->sectors = av_malloc_array(nb_sectors1, 1 << WTV_SECTOR_BITS); + wf->sectors = av_calloc(nb_sectors1, 1 << WTV_SECTOR_BITS); if (!wf->sectors) { av_free(wf); return NULL; @@ -660,6 +660,8 @@ static AVStream * parse_media_type(AVFormatContext *s, AVStream *st, int sid, avio_skip(pb, size - 32); ff_get_guid(pb, &actual_subtype); ff_get_guid(pb, &actual_formattype); + if (avio_feof(pb)) + return NULL; avio_seek(pb, -size, SEEK_CUR); st = parse_media_type(s, st, sid, mediatype, actual_subtype, actual_formattype, size - 32); @@ -817,6 +819,8 @@ static int parse_chunks(AVFormatContext *s, int mode, int64_t seekts, int *len_p avio_skip(pb, 12); ff_get_guid(pb, &formattype); size = avio_rl32(pb); + if (size < 0 || size > INT_MAX - 92 - consumed) + return AVERROR_INVALIDDATA; parse_media_type(s, 0, sid, mediatype, subtype, formattype, size); consumed += 92 + size; } @@ -831,6 +835,8 @@ static int parse_chunks(AVFormatContext *s, int mode, int64_t seekts, int *len_p avio_skip(pb, 12); ff_get_guid(pb, &formattype); size = avio_rl32(pb); + if (size < 0 || size > INT_MAX - 76 - consumed) + return AVERROR_INVALIDDATA; parse_media_type(s, s->streams[stream_index], sid, mediatype, subtype, formattype, size); consumed += 76 + size; } @@ -843,7 +849,7 @@ static int parse_chunks(AVFormatContext *s, int mode, int64_t seekts, int *len_p int stream_index = ff_find_stream_index(s, sid); if (stream_index >= 0) { AVStream *st = s->streams[stream_index]; - uint8_t buf[258]; + uint8_t buf[258] = {0}; const uint8_t *pbuf = buf; int buf_size; @@ -856,7 +862,8 @@ static int parse_chunks(AVFormatContext *s, int mode, int64_t seekts, int *len_p } buf_size = FFMIN(len - consumed, sizeof(buf)); - avio_read(pb, buf, buf_size); + if (avio_read(pb, buf, buf_size) != buf_size) + return AVERROR_INVALIDDATA; consumed += buf_size; ff_parse_mpeg2_descriptor(s, st, 0, &pbuf, buf + buf_size, NULL, 0, 0, NULL); } diff --git a/libavformat/xmv.c b/libavformat/xmv.c index 0c69d267de..6f94d20514 100644 --- a/libavformat/xmv.c +++ b/libavformat/xmv.c @@ -223,6 +223,8 @@ static int xmv_read_header(AVFormatContext *s) /* Initialize the packet context */ xmv->next_packet_offset = avio_tell(pb); + if (this_packet_size < xmv->next_packet_offset) + return AVERROR_INVALIDDATA; xmv->next_packet_size = this_packet_size - xmv->next_packet_offset; xmv->stream_count = xmv->audio_track_count + 1; diff --git a/libavformat/xwma.c b/libavformat/xwma.c index aedadcf140..61372b08cb 100644 --- a/libavformat/xwma.c +++ b/libavformat/xwma.c @@ -151,7 +151,7 @@ static int xwma_read_header(AVFormatContext *s) st->codecpar->channels); return AVERROR_INVALIDDATA; } - if (!st->codecpar->bits_per_coded_sample) { + if (!st->codecpar->bits_per_coded_sample || st->codecpar->bits_per_coded_sample > 64) { av_log(s, AV_LOG_WARNING, "Invalid bits_per_coded_sample: %d\n", st->codecpar->bits_per_coded_sample); return AVERROR_INVALIDDATA; @@ -278,7 +278,7 @@ static int xwma_read_header(AVFormatContext *s) * the total duration using the average bits per sample and the * total data length. */ - st->duration = (size<<3) * st->codecpar->sample_rate / st->codecpar->bit_rate; + st->duration = av_rescale((size<<3), st->codecpar->sample_rate, st->codecpar->bit_rate); } fail: diff --git a/libavutil/avstring.c b/libavutil/avstring.c index 49e8df55aa..bd335815be 100644 --- a/libavutil/avstring.c +++ b/libavutil/avstring.c @@ -460,10 +460,12 @@ int av_match_list(const char *name, const char *list, char separator) if (k && (!p[k] || p[k] == separator)) return 1; q = strchr(q, separator); - q += !!q; + if(q) + q++; } p = strchr(p, separator); - p += !!p; + if (p) + p++; } return 0; diff --git a/libavutil/base64.c b/libavutil/base64.c index 25ae8c411c..80919d8bee 100644 --- a/libavutil/base64.c +++ b/libavutil/base64.c @@ -79,12 +79,16 @@ static const uint8_t map2[256] = int av_base64_decode(uint8_t *out, const char *in_str, int out_size) { uint8_t *dst = out; - uint8_t *end = out + out_size; + uint8_t *end; // no sign extension const uint8_t *in = in_str; unsigned bits = 0xff; unsigned v; + if (!out) + goto validity_check; + + end = out + out_size; while (end - dst > 3) { BASE64_DEC_STEP(0); BASE64_DEC_STEP(1); @@ -108,6 +112,7 @@ int av_base64_decode(uint8_t *out, const char *in_str, int out_size) *dst++ = v; in += 4; } +validity_check: while (1) { BASE64_DEC_STEP(0); in++; @@ -120,13 +125,15 @@ int av_base64_decode(uint8_t *out, const char *in_str, int out_size) } out3: - *dst++ = v >> 10; + if (end - dst) + *dst++ = v >> 10; v <<= 2; out2: - *dst++ = v >> 4; + if (end - dst) + *dst++ = v >> 4; out1: out0: - return bits & 1 ? AVERROR_INVALIDDATA : dst - out; + return bits & 1 ? AVERROR_INVALIDDATA : out ? dst - out : 0; } /***************************************************************************** diff --git a/libavutil/buffer.c b/libavutil/buffer.c index 858633e8c7..1785a284a2 100644 --- a/libavutil/buffer.c +++ b/libavutil/buffer.c @@ -250,7 +250,10 @@ AVBufferPool *av_buffer_pool_init2(buffer_size_t size, void *opaque, if (!pool) return NULL; - ff_mutex_init(&pool->mutex, NULL); + if (ff_mutex_init(&pool->mutex, NULL)) { + av_free(pool); + return NULL; + } pool->size = size; pool->opaque = opaque; @@ -269,7 +272,10 @@ AVBufferPool *av_buffer_pool_init(buffer_size_t size, AVBufferRef* (*alloc)(buff if (!pool) return NULL; - ff_mutex_init(&pool->mutex, NULL); + if (ff_mutex_init(&pool->mutex, NULL)) { + av_free(pool); + return NULL; + } pool->size = size; pool->alloc = alloc ? alloc : av_buffer_alloc; diff --git a/libavutil/cpu.c b/libavutil/cpu.c index 52f6b9a3bf..6bd0f07a62 100644 --- a/libavutil/cpu.c +++ b/libavutil/cpu.c @@ -291,6 +291,12 @@ int av_cpu_count(void) DWORD_PTR proc_aff, sys_aff; if (GetProcessAffinityMask(GetCurrentProcess(), &proc_aff, &sys_aff)) nb_cpus = av_popcount64(proc_aff); +#elif HAVE_SYSCTL && defined(HW_NCPUONLINE) + int mib[2] = { CTL_HW, HW_NCPUONLINE }; + size_t len = sizeof(nb_cpus); + + if (sysctl(mib, 2, &nb_cpus, &len, NULL, 0) == -1) + nb_cpus = 0; #elif HAVE_SYSCTL && defined(HW_NCPU) int mib[2] = { CTL_HW, HW_NCPU }; size_t len = sizeof(nb_cpus); diff --git a/libavutil/frame.c b/libavutil/frame.c index 75e347bf2f..5418e28f3b 100644 --- a/libavutil/frame.c +++ b/libavutil/frame.c @@ -937,7 +937,7 @@ int av_frame_apply_cropping(AVFrame *frame, int flags) if (log2_crop_align < min_log2_align) return AVERROR_BUG; - if (min_log2_align < 5) { + if (min_log2_align < 5 && log2_crop_align != INT_MAX) { frame->crop_left &= ~((1 << (5 + log2_crop_align - min_log2_align)) - 1); calc_cropping_offsets(offsets, frame, desc); } diff --git a/libavutil/hwcontext_d3d11va.c b/libavutil/hwcontext_d3d11va.c index 2a3549ebd8..3d4dfe1943 100644 --- a/libavutil/hwcontext_d3d11va.c +++ b/libavutil/hwcontext_d3d11va.c @@ -164,7 +164,7 @@ static AVBufferRef *wrap_texture_buf(ID3D11Texture2D *tex, int index) desc->texture = tex; desc->index = index; - buf = av_buffer_create((uint8_t *)desc, sizeof(desc), free_texture, tex, 0); + buf = av_buffer_create((uint8_t *)desc, sizeof(*desc), free_texture, tex, 0); if (!buf) { ID3D11Texture2D_Release(tex); av_free(desc); diff --git a/libavutil/hwcontext_dxva2.c b/libavutil/hwcontext_dxva2.c index 33b3dc80ff..88961d05e8 100644 --- a/libavutil/hwcontext_dxva2.c +++ b/libavutil/hwcontext_dxva2.c @@ -133,7 +133,7 @@ static AVBufferRef *dxva2_pool_alloc(void *opaque, buffer_size_t size) if (s->nb_surfaces_used < hwctx->nb_surfaces) { s->nb_surfaces_used++; return av_buffer_create((uint8_t*)s->surfaces_internal[s->nb_surfaces_used - 1], - sizeof(*hwctx->surfaces), dxva2_pool_release_dummy, 0, 0); + sizeof(**hwctx->surfaces), dxva2_pool_release_dummy, 0, 0); } return NULL; diff --git a/libavutil/imgutils.c b/libavutil/imgutils.c index bd1333170a..1cdffd4dfe 100644 --- a/libavutil/imgutils.c +++ b/libavutil/imgutils.c @@ -297,7 +297,7 @@ int av_image_check_size2(unsigned int w, unsigned int h, int64_t max_pixels, enu stride = 8LL*w; stride += 128*8; - if ((int)w<=0 || (int)h<=0 || stride >= INT_MAX || stride*(uint64_t)(h+128) >= INT_MAX) { + if (w==0 || h==0 || w > INT32_MAX || h > INT32_MAX || stride >= INT_MAX || stride*(h + 128ULL) >= INT_MAX) { av_log(&imgutils, AV_LOG_ERROR, "Picture size %ux%u is invalid\n", w, h); return AVERROR(EINVAL); } diff --git a/libavutil/internal.h b/libavutil/internal.h index 572daefec3..2ed1c2abb1 100644 --- a/libavutil/internal.h +++ b/libavutil/internal.h @@ -102,6 +102,8 @@ #define FF_ALLOC_TYPED_ARRAY(p, nelem) (p = av_malloc_array(nelem, sizeof(*p))) #define FF_ALLOCZ_TYPED_ARRAY(p, nelem) (p = av_mallocz_array(nelem, sizeof(*p))) +#define FF_PTR_ADD(ptr, off) ((off) ? (ptr) + (off) : (ptr)) + #include "libm.h" /** diff --git a/libavutil/mathematics.h b/libavutil/mathematics.h index 54901800ba..64d4137a60 100644 --- a/libavutil/mathematics.h +++ b/libavutil/mathematics.h @@ -134,6 +134,7 @@ int64_t av_rescale(int64_t a, int64_t b, int64_t c) av_const; * * The operation is mathematically equivalent to `a * b / c`, but writing that * directly can overflow, and does not support different rounding methods. + * If the result is not representable then INT64_MIN is returned. * * @see av_rescale(), av_rescale_q(), av_rescale_q_rnd() */ diff --git a/libavutil/pixdesc.c b/libavutil/pixdesc.c index 2a919461a5..18c7a0efc8 100644 --- a/libavutil/pixdesc.c +++ b/libavutil/pixdesc.c @@ -2659,7 +2659,7 @@ void ff_check_pixfmt_descriptors(void){ continue; av_read_image_line(tmp, (void*)data, linesize, d, 0, 0, j, 2, 0); av_assert0(tmp[0] == 0 && tmp[1] == 0); - tmp[0] = tmp[1] = (1<depth) - 1; + tmp[0] = tmp[1] = (1ULL << c->depth) - 1; av_write_image_line(tmp, data, linesize, d, 0, 0, j, 2); } } diff --git a/libavutil/ppc/cpu.c b/libavutil/ppc/cpu.c index b022149fa0..2b13cda662 100644 --- a/libavutil/ppc/cpu.c +++ b/libavutil/ppc/cpu.c @@ -27,8 +27,8 @@ #if HAVE_UNISTD_H #include #endif -#elif defined(__OpenBSD__) -#include +#elif defined(__NetBSD__) || defined(__OpenBSD__) +#include #include #include #elif defined(__AMIGAOS4__) @@ -56,8 +56,8 @@ int ff_get_cpu_flags_ppc(void) if (result == VECTORTYPE_ALTIVEC) return AV_CPU_FLAG_ALTIVEC; return 0; -#elif defined(__APPLE__) || defined(__OpenBSD__) -#ifdef __OpenBSD__ +#elif defined(__APPLE__) || defined(__NetBSD__) || defined(__OpenBSD__) +#if defined(__NetBSD__) || defined(__OpenBSD__) int sels[2] = {CTL_MACHDEP, CPU_ALTIVEC}; #else int sels[2] = {CTL_HW, HW_VECTORUNIT}; @@ -95,12 +95,15 @@ int ff_get_cpu_flags_ppc(void) #endif if (ret & AV_CPU_FLAG_VSX) av_assert0(ret & AV_CPU_FLAG_ALTIVEC); - } else if (buf[i] == AT_HWCAP2) { + } +#ifdef AT_HWCAP2 /* not introduced until glibc 2.18 */ + else if (buf[i] == AT_HWCAP2) { #ifdef PPC_FEATURE2_ARCH_2_07 if (buf[i + 1] & PPC_FEATURE2_ARCH_2_07) ret |= AV_CPU_FLAG_POWER8; #endif } +#endif /* AT_HWCAP2 */ } } diff --git a/libavutil/rational.h b/libavutil/rational.h index cbb08a0baf..790f089527 100644 --- a/libavutil/rational.h +++ b/libavutil/rational.h @@ -168,6 +168,10 @@ static av_always_inline AVRational av_inv_q(AVRational q) * In case of infinity, the returned value is expressed as `{1, 0}` or * `{-1, 0}` depending on the sign. * + * In general rational numbers with |num| <= 1<<26 && |den| <= 1<<26 + * can be recovered exactly from their double representation. + * (no exceptions were found within 1B random ones) + * * @param d `double` to convert * @param max Maximum allowed numerator and denominator * @return `d` in AVRational form diff --git a/libavutil/slicethread.c b/libavutil/slicethread.c index dfbe551ef2..45d085001c 100644 --- a/libavutil/slicethread.c +++ b/libavutil/slicethread.c @@ -98,6 +98,7 @@ int avpriv_slicethread_create(AVSliceThread **pctx, void *priv, { AVSliceThread *ctx; int nb_workers, i; + int ret; av_assert0(nb_threads >= 0); if (!nb_threads) { @@ -131,16 +132,37 @@ int avpriv_slicethread_create(AVSliceThread **pctx, void *priv, atomic_init(&ctx->first_job, 0); atomic_init(&ctx->current_job, 0); - pthread_mutex_init(&ctx->done_mutex, NULL); - pthread_cond_init(&ctx->done_cond, NULL); + ret = pthread_mutex_init(&ctx->done_mutex, NULL); + if (ret) { + av_freep(&ctx->workers); + av_freep(pctx); + return AVERROR(ret); + } + ret = pthread_cond_init(&ctx->done_cond, NULL); + if (ret) { + ctx->nb_threads = main_func ? 0 : 1; + avpriv_slicethread_free(pctx); + return AVERROR(ret); + } ctx->done = 0; for (i = 0; i < nb_workers; i++) { WorkerContext *w = &ctx->workers[i]; int ret; w->ctx = ctx; - pthread_mutex_init(&w->mutex, NULL); - pthread_cond_init(&w->cond, NULL); + ret = pthread_mutex_init(&w->mutex, NULL); + if (ret) { + ctx->nb_threads = main_func ? i : i + 1; + avpriv_slicethread_free(pctx); + return AVERROR(ret); + } + ret = pthread_cond_init(&w->cond, NULL); + if (ret) { + pthread_mutex_destroy(&w->mutex); + ctx->nb_threads = main_func ? i : i + 1; + avpriv_slicethread_free(pctx); + return AVERROR(ret); + } pthread_mutex_lock(&w->mutex); w->done = 0; diff --git a/libavutil/softfloat.h b/libavutil/softfloat.h index a651406f74..399ca6d682 100644 --- a/libavutil/softfloat.h +++ b/libavutil/softfloat.h @@ -236,6 +236,10 @@ static av_always_inline SoftFloat av_sqrt_sf(SoftFloat val) /** * Rounding-to-nearest used. + * + * @param a angle in units of (1ULL<<30)/M_PI radians + * @param s pointer to where sine in units of (1<<30) is returned + * @param c pointer to where cosine in units of (1<<30) is returned */ static av_unused void av_sincos_sf(int a, int *s, int *c) { @@ -281,7 +285,7 @@ static av_unused void av_sincos_sf(int a, int *s, int *c) (int64_t)av_sintbl_4_sf[(idx & 0x1f) + 1] * (a & 0x7ff) + 0x400) >> 11); - *c = (int)(((int64_t)cv * ct + (int64_t)sv * st + 0x20000000) >> 30); + *c = (int)(((int64_t)cv * ct - (int64_t)sv * st + 0x20000000) >> 30); *s = (int)(((int64_t)cv * st + (int64_t)sv * ct + 0x20000000) >> 30); } diff --git a/libavutil/tests/base64.c b/libavutil/tests/base64.c index 400e01cefe..66d0fdc1fc 100644 --- a/libavutil/tests/base64.c +++ b/libavutil/tests/base64.c @@ -64,6 +64,16 @@ static int test_encode_decode(const uint8_t *data, unsigned int data_size, printf("Failed: decode to NULL buffer\n"); return 1; } + if (data_size > 0 && (data2_size = av_base64_decode(data2, encoded, data_size - 1)) != data_size - 1) { + printf("Failed: out of array write\n" + "Encoded:\n%s\n", encoded); + return 1; + } + if (data_size > 1 && (data2_size = av_base64_decode(data2, encoded, data_size - 2)) != data_size - 2) { + printf("Failed: out of array write\n" + "Encoded:\n%s\n", encoded); + return 1; + } if (strlen(encoded)) { char *end = strchr(encoded, '='); if (!end) diff --git a/libavutil/tests/dict.c b/libavutil/tests/dict.c index 56e98557a7..4c526f72f4 100644 --- a/libavutil/tests/dict.c +++ b/libavutil/tests/dict.c @@ -122,12 +122,15 @@ int main(void) //valgrind sensible test printf("\nTesting av_dict_set() with existing AVDictionaryEntry.key as key\n"); - av_dict_set(&dict, "key", "old", 0); + if (av_dict_set(&dict, "key", "old", 0) < 0) + return 1; e = av_dict_get(dict, "key", NULL, 0); - av_dict_set(&dict, e->key, "new val OK", 0); + if (av_dict_set(&dict, e->key, "new val OK", 0) < 0) + return 1; e = av_dict_get(dict, "key", NULL, 0); printf("%s\n", e->value); - av_dict_set(&dict, e->key, e->value, 0); + if (av_dict_set(&dict, e->key, e->value, 0) < 0) + return 1; e = av_dict_get(dict, "key", NULL, 0); printf("%s\n", e->value); av_dict_free(&dict); diff --git a/libavutil/tests/opt.c b/libavutil/tests/opt.c index 3134ffd354..cdbe66e336 100644 --- a/libavutil/tests/opt.c +++ b/libavutil/tests/opt.c @@ -216,6 +216,7 @@ int main(void) { TestContext test_ctx = { 0 }; char *buf; + int ret; test_ctx.class = &test_class; av_log_set_level(AV_LOG_QUIET); @@ -226,8 +227,10 @@ int main(void) av_opt_free(&test_ctx); memset(&test_ctx, 0, sizeof(test_ctx)); test_ctx.class = &test_class; - av_set_options_string(&test_ctx, buf, "=", ","); + ret = av_set_options_string(&test_ctx, buf, "=", ","); av_free(buf); + if (ret < 0) + printf("Error ret '%d'\n", ret); if (av_opt_serialize(&test_ctx, 0, 0, &buf, '=', ',') >= 0) { printf("%s\n", buf); av_free(buf); diff --git a/libavutil/tests/softfloat.c b/libavutil/tests/softfloat.c index c06de44933..a2e628fe81 100644 --- a/libavutil/tests/softfloat.c +++ b/libavutil/tests/softfloat.c @@ -148,7 +148,7 @@ int main(void){ av_sincos_sf(i*(1ULL<<32)/36/4, &s, &c); errs = (double)s/ (1<<30) - sin(i*M_PI/36); errc = (double)c/ (1<<30) - cos(i*M_PI/36); - if (fabs(errs) > 0.00000002 || fabs(errc) >0.001) { + if (fabs(errs) > 0.000000004 || fabs(errc) >0.000000004) { printf("sincos FAIL %d %f %f %f %f\n", i, (float)s/ (1<<30), (float)c/ (1<<30), sin(i*M_PI/36), cos(i*M_PI/36)); } diff --git a/libavutil/timecode.c b/libavutil/timecode.c index 2fc3295e25..9d5a9b9698 100644 --- a/libavutil/timecode.c +++ b/libavutil/timecode.c @@ -60,8 +60,8 @@ uint32_t av_timecode_get_smpte_from_framenum(const AVTimecode *tc, int framenum) framenum = av_timecode_adjust_ntsc_framenum2(framenum, tc->fps); ff = framenum % fps; ss = framenum / fps % 60; - mm = framenum / (fps*60) % 60; - hh = framenum / (fps*3600) % 24; + mm = framenum / (fps*60LL) % 60; + hh = framenum / (fps*3600LL) % 24; return av_timecode_get_smpte(tc->rate, drop, hh, mm, ss, ff); } @@ -208,7 +208,7 @@ static int fps_from_frame_rate(AVRational rate) { if (!rate.den || !rate.num) return -1; - return (rate.num + rate.den/2) / rate.den; + return (rate.num + rate.den/2LL) / rate.den; } int av_timecode_check_frame_rate(AVRational rate) diff --git a/libavutil/utils.c b/libavutil/utils.c index c1cd452eee..ea9b5097b8 100644 --- a/libavutil/utils.c +++ b/libavutil/utils.c @@ -37,10 +37,6 @@ const char *av_version_info(void) unsigned avutil_version(void) { - static int checks_done; - if (checks_done) - return LIBAVUTIL_VERSION_INT; - av_assert0(AV_SAMPLE_FMT_DBLP == 9); av_assert0(AVMEDIA_TYPE_ATTACHMENT == 4); av_assert0(AV_PICTURE_TYPE_BI == 7); @@ -58,7 +54,6 @@ unsigned avutil_version(void) av_log(NULL, AV_LOG_ERROR, "Libavutil has been linked to a broken llrint()\n"); } - checks_done = 1; return LIBAVUTIL_VERSION_INT; } diff --git a/libpostproc/postprocess.c b/libpostproc/postprocess.c index 8d44165dee..4c79295f31 100644 --- a/libpostproc/postprocess.c +++ b/libpostproc/postprocess.c @@ -945,6 +945,11 @@ void pp_postprocess(const uint8_t * src[3], const int srcStride[3], int minStride= FFMAX(FFABS(srcStride[0]), FFABS(dstStride[0])); int absQPStride = FFABS(QPStride); + if (width < 16 || height < 16) { + av_log(c, AV_LOG_ERROR, "Postproc is designed to filter 16x16 macroblock based formats, the minimum size is 1 macroblock\n"); + return; + } + // c->stride and c->QPStride are always positive if(c->stride < minStride || c->qpStride < absQPStride) reallocBuffers(c, width, height, diff --git a/libswresample/audioconvert.c b/libswresample/audioconvert.c index 89ee7bfae3..500aa0e5c5 100644 --- a/libswresample/audioconvert.c +++ b/libswresample/audioconvert.c @@ -237,10 +237,10 @@ int swri_audio_convert(AudioConvert *ctx, AudioData *out, AudioData *in, int len const int ich= ctx->ch_map ? ctx->ch_map[ch] : ch; const int is= ich < 0 ? 0 : (in->planar ? 1 : in->ch_count) * in->bps; const uint8_t *pi= ich < 0 ? ctx->silence : in->ch[ich]; - uint8_t *po= out->ch[ch]; - uint8_t *end= po + os*len; + uint8_t *end, *po = out->ch[ch]; if(!po) continue; + end = po + os * len; ctx->conv_f(po+off*os, pi+off*is, is, os, end); } return 0; diff --git a/libswscale/aarch64/yuv2rgb_neon.S b/libswscale/aarch64/yuv2rgb_neon.S index f4b220fb60..f341268c5d 100644 --- a/libswscale/aarch64/yuv2rgb_neon.S +++ b/libswscale/aarch64/yuv2rgb_neon.S @@ -118,8 +118,8 @@ .endm .macro increment_yuv422p - add x6, x6, w7, UXTW // srcU += incU - add x13, x13, w14, UXTW // srcV += incV + add x6, x6, w7, SXTW // srcU += incU + add x13, x13, w14, SXTW // srcV += incV .endm .macro compute_rgba r1 g1 b1 a1 r2 g2 b2 a2 @@ -189,8 +189,8 @@ function ff_\ifmt\()_to_\ofmt\()_neon, export=1 st4 {v16.8B,v17.8B,v18.8B,v19.8B}, [x2], #32 subs w8, w8, #16 // width -= 16 b.gt 2b - add x2, x2, w3, UXTW // dst += padding - add x4, x4, w5, UXTW // srcY += paddingY + add x2, x2, w3, SXTW // dst += padding + add x4, x4, w5, SXTW // srcY += paddingY increment_\ifmt subs w1, w1, #1 // height -= 1 b.gt 1b diff --git a/libswscale/alphablend.c b/libswscale/alphablend.c index b5686599c0..b5967c889b 100644 --- a/libswscale/alphablend.c +++ b/libswscale/alphablend.c @@ -26,7 +26,7 @@ int ff_sws_alphablendaway(SwsContext *c, const uint8_t *src[], { const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(c->srcFormat); int nb_components = desc->nb_components; - int plane, x, y; + int plane, x, ysrc; int plane_count = isGray(c->srcFormat) ? 1 : 3; int sixteen_bits = desc->comp[0].depth >= 9; unsigned off = 1<<(desc->comp[0].depth - 1); @@ -50,14 +50,15 @@ int ff_sws_alphablendaway(SwsContext *c, const uint8_t *src[], int w = plane ? c->chrSrcW : c->srcW; int x_subsample = plane ? desc->log2_chroma_w: 0; int y_subsample = plane ? desc->log2_chroma_h: 0; - for (y = srcSliceY >> y_subsample; y < AV_CEIL_RSHIFT(srcSliceH, y_subsample); y++) { + for (ysrc = 0; ysrc < AV_CEIL_RSHIFT(srcSliceH, y_subsample); ysrc++) { + int y = ysrc + (srcSliceY >> y_subsample); if (x_subsample || y_subsample) { int alpha; unsigned u; if (sixteen_bits) { ptrdiff_t alpha_step = srcStride[plane_count] >> 1; - const uint16_t *s = (const uint16_t *)(src[plane ] + srcStride[plane ] * y); - const uint16_t *a = (const uint16_t *)(src[plane_count] + (srcStride[plane_count] * y << y_subsample)); + const uint16_t *s = (const uint16_t *)(src[plane ] + srcStride[plane ] * ysrc); + const uint16_t *a = (const uint16_t *)(src[plane_count] + (srcStride[plane_count] * ysrc << y_subsample)); uint16_t *d = ( uint16_t *)(dst[plane ] + dstStride[plane ] * y); if ((!isBE(c->srcFormat)) == !HAVE_BIGENDIAN) { for (x = 0; x < w; x++) { @@ -82,8 +83,8 @@ int ff_sws_alphablendaway(SwsContext *c, const uint8_t *src[], } } else { ptrdiff_t alpha_step = srcStride[plane_count]; - const uint8_t *s = src[plane ] + srcStride[plane] * y; - const uint8_t *a = src[plane_count] + (srcStride[plane_count] * y << y_subsample); + const uint8_t *s = src[plane ] + srcStride[plane] * ysrc; + const uint8_t *a = src[plane_count] + (srcStride[plane_count] * ysrc << y_subsample); uint8_t *d = dst[plane ] + dstStride[plane] * y; for (x = 0; x < w; x++) { if (y_subsample) { @@ -97,8 +98,8 @@ int ff_sws_alphablendaway(SwsContext *c, const uint8_t *src[], } } else { if (sixteen_bits) { - const uint16_t *s = (const uint16_t *)(src[plane ] + srcStride[plane ] * y); - const uint16_t *a = (const uint16_t *)(src[plane_count] + srcStride[plane_count] * y); + const uint16_t *s = (const uint16_t *)(src[plane ] + srcStride[plane ] * ysrc); + const uint16_t *a = (const uint16_t *)(src[plane_count] + srcStride[plane_count] * ysrc); uint16_t *d = ( uint16_t *)(dst[plane ] + dstStride[plane ] * y); if ((!isBE(c->srcFormat)) == !HAVE_BIGENDIAN) { for (x = 0; x < w; x++) { @@ -113,8 +114,8 @@ int ff_sws_alphablendaway(SwsContext *c, const uint8_t *src[], } } } else { - const uint8_t *s = src[plane ] + srcStride[plane] * y; - const uint8_t *a = src[plane_count] + srcStride[plane_count] * y; + const uint8_t *s = src[plane ] + srcStride[plane] * ysrc; + const uint8_t *a = src[plane_count] + srcStride[plane_count] * ysrc; uint8_t *d = dst[plane ] + dstStride[plane] * y; for (x = 0; x < w; x++) { unsigned u = s[x]*a[x] + target_table[((x^y)>>5)&1][plane]*(255-a[x]) + 128; @@ -127,10 +128,11 @@ int ff_sws_alphablendaway(SwsContext *c, const uint8_t *src[], } else { int alpha_pos = desc->comp[plane_count].offset; int w = c->srcW; - for (y = srcSliceY; y < srcSliceH; y++) { + for (ysrc = 0; ysrc < srcSliceH; ysrc++) { + int y = ysrc + srcSliceY; if (sixteen_bits) { - const uint16_t *s = (const uint16_t *)(src[0] + srcStride[0] * y + 2*!alpha_pos); - const uint16_t *a = (const uint16_t *)(src[0] + srcStride[0] * y + alpha_pos); + const uint16_t *s = (const uint16_t *)(src[0] + srcStride[0] * ysrc + 2*!alpha_pos); + const uint16_t *a = (const uint16_t *)(src[0] + srcStride[0] * ysrc + alpha_pos); uint16_t *d = ( uint16_t *)(dst[0] + dstStride[0] * y); if ((!isBE(c->srcFormat)) == !HAVE_BIGENDIAN) { for (x = 0; x < w; x++) { @@ -151,8 +153,8 @@ int ff_sws_alphablendaway(SwsContext *c, const uint8_t *src[], } } } else { - const uint8_t *s = src[0] + srcStride[0] * y + !alpha_pos; - const uint8_t *a = src[0] + srcStride[0] * y + alpha_pos; + const uint8_t *s = src[0] + srcStride[0] * ysrc + !alpha_pos; + const uint8_t *a = src[0] + srcStride[0] * ysrc + alpha_pos; uint8_t *d = dst[0] + dstStride[0] * y; for (x = 0; x < w; x++) { for (plane = 0; plane < plane_count; plane++) { diff --git a/libswscale/input.c b/libswscale/input.c index 6850801a44..197152f65b 100644 --- a/libswscale/input.c +++ b/libswscale/input.c @@ -84,9 +84,9 @@ rgb64ToUV_half_c_template(uint16_t *dstU, uint16_t *dstV, int32_t rv = rgb2yuv[RV_IDX], gv = rgb2yuv[GV_IDX], bv = rgb2yuv[BV_IDX]; av_assert1(src1==src2); for (i = 0; i < width; i++) { - int r_b = (input_pixel(&src1[8 * i + 0]) + input_pixel(&src1[8 * i + 4]) + 1) >> 1; - int g = (input_pixel(&src1[8 * i + 1]) + input_pixel(&src1[8 * i + 5]) + 1) >> 1; - int b_r = (input_pixel(&src1[8 * i + 2]) + input_pixel(&src1[8 * i + 6]) + 1) >> 1; + unsigned r_b = (input_pixel(&src1[8 * i + 0]) + input_pixel(&src1[8 * i + 4]) + 1) >> 1; + unsigned g = (input_pixel(&src1[8 * i + 1]) + input_pixel(&src1[8 * i + 5]) + 1) >> 1; + unsigned b_r = (input_pixel(&src1[8 * i + 2]) + input_pixel(&src1[8 * i + 6]) + 1) >> 1; dstU[i]= (ru*r + gu*g + bu*b + (0x10001<<(RGB2YUV_SHIFT-1))) >> RGB2YUV_SHIFT; dstV[i]= (rv*r + gv*g + bv*b + (0x10001<<(RGB2YUV_SHIFT-1))) >> RGB2YUV_SHIFT; @@ -156,9 +156,9 @@ static av_always_inline void rgb48ToUV_c_template(uint16_t *dstU, int32_t rv = rgb2yuv[RV_IDX], gv = rgb2yuv[GV_IDX], bv = rgb2yuv[BV_IDX]; av_assert1(src1 == src2); for (i = 0; i < width; i++) { - int r_b = input_pixel(&src1[i * 3 + 0]); - int g = input_pixel(&src1[i * 3 + 1]); - int b_r = input_pixel(&src1[i * 3 + 2]); + unsigned r_b = input_pixel(&src1[i * 3 + 0]); + unsigned g = input_pixel(&src1[i * 3 + 1]); + unsigned b_r = input_pixel(&src1[i * 3 + 2]); dstU[i] = (ru*r + gu*g + bu*b + (0x10001 << (RGB2YUV_SHIFT - 1))) >> RGB2YUV_SHIFT; dstV[i] = (rv*r + gv*g + bv*b + (0x10001 << (RGB2YUV_SHIFT - 1))) >> RGB2YUV_SHIFT; @@ -178,12 +178,12 @@ static av_always_inline void rgb48ToUV_half_c_template(uint16_t *dstU, int32_t rv = rgb2yuv[RV_IDX], gv = rgb2yuv[GV_IDX], bv = rgb2yuv[BV_IDX]; av_assert1(src1 == src2); for (i = 0; i < width; i++) { - int r_b = (input_pixel(&src1[6 * i + 0]) + - input_pixel(&src1[6 * i + 3]) + 1) >> 1; - int g = (input_pixel(&src1[6 * i + 1]) + - input_pixel(&src1[6 * i + 4]) + 1) >> 1; - int b_r = (input_pixel(&src1[6 * i + 2]) + - input_pixel(&src1[6 * i + 5]) + 1) >> 1; + unsigned r_b = (input_pixel(&src1[6 * i + 0]) + + input_pixel(&src1[6 * i + 3]) + 1) >> 1; + unsigned g = (input_pixel(&src1[6 * i + 1]) + + input_pixel(&src1[6 * i + 4]) + 1) >> 1; + unsigned b_r = (input_pixel(&src1[6 * i + 2]) + + input_pixel(&src1[6 * i + 5]) + 1) >> 1; dstU[i] = (ru*r + gu*g + bu*b + (0x10001 << (RGB2YUV_SHIFT - 1))) >> RGB2YUV_SHIFT; dstV[i] = (rv*r + gv*g + bv*b + (0x10001 << (RGB2YUV_SHIFT - 1))) >> RGB2YUV_SHIFT; diff --git a/libswscale/output.c b/libswscale/output.c index e855ad606a..be22279229 100644 --- a/libswscale/output.c +++ b/libswscale/output.c @@ -611,7 +611,7 @@ yuv2mono_2_c_template(SwsContext *c, const int16_t *buf[2], if (c->dither == SWS_DITHER_ED) { int err = 0; - int acc = 0; + unsigned acc = 0; for (i = 0; i < dstW; i +=2) { int Y; @@ -633,7 +633,8 @@ yuv2mono_2_c_template(SwsContext *c, const int16_t *buf[2], c->dither_error[0][i] = err; } else { for (i = 0; i < dstW; i += 8) { - int Y, acc = 0; + int Y; + unsigned acc = 0; Y = (buf0[i + 0] * yalpha1 + buf1[i + 0] * yalpha) >> 19; accumulate_bit(acc, Y + d128[0]); @@ -668,7 +669,7 @@ yuv2mono_1_c_template(SwsContext *c, const int16_t *buf0, if (c->dither == SWS_DITHER_ED) { int err = 0; - int acc = 0; + unsigned acc = 0; for (i = 0; i < dstW; i +=2) { int Y; @@ -690,7 +691,7 @@ yuv2mono_1_c_template(SwsContext *c, const int16_t *buf0, c->dither_error[0][i] = err; } else { for (i = 0; i < dstW; i += 8) { - int acc = 0; + unsigned acc = 0; accumulate_bit(acc, ((buf0[i + 0] + 64) >> 7) + d128[0]); accumulate_bit(acc, ((buf0[i + 1] + 64) >> 7) + d128[1]); accumulate_bit(acc, ((buf0[i + 2] + 64) >> 7) + d128[2]); @@ -1002,8 +1003,8 @@ yuv2rgba64_X_c_template(SwsContext *c, const int16_t *lumFilter, for (i = 0; i < ((dstW + 1) >> 1); i++) { int j; - int Y1 = -0x40000000; - int Y2 = -0x40000000; + unsigned Y1 = -0x40000000; + unsigned Y2 = -0x40000000; int U = -(128 << 23); // 19 int V = -(128 << 23); int R, G, B; @@ -1031,9 +1032,9 @@ yuv2rgba64_X_c_template(SwsContext *c, const int16_t *lumFilter, } // 8 bits: 12+15=27; 16 bits: 12+19=31 - Y1 >>= 14; // 10 + Y1 = (int)Y1 >> 14; // 10 Y1 += 0x10000; - Y2 >>= 14; + Y2 = (int)Y2 >> 14; Y2 += 0x10000; U >>= 14; V >>= 14; @@ -1043,8 +1044,8 @@ yuv2rgba64_X_c_template(SwsContext *c, const int16_t *lumFilter, Y2 -= c->yuv2rgb_y_offset; Y1 *= c->yuv2rgb_y_coeff; Y2 *= c->yuv2rgb_y_coeff; - Y1 += 1 << 13; // 21 - Y2 += 1 << 13; + Y1 += (1 << 13) - (1 << 29); // 21 + Y2 += (1 << 13) - (1 << 29); // 8 bits: 17 + 13 bits = 30 bits, 16 bits: 17 + 13 bits = 30 bits R = V * c->yuv2rgb_v2r_coeff; @@ -1052,20 +1053,20 @@ yuv2rgba64_X_c_template(SwsContext *c, const int16_t *lumFilter, B = U * c->yuv2rgb_u2b_coeff; // 8 bits: 30 - 22 = 8 bits, 16 bits: 30 bits - 14 = 16 bits - output_pixel(&dest[0], av_clip_uintp2(R_B + Y1, 30) >> 14); - output_pixel(&dest[1], av_clip_uintp2( G + Y1, 30) >> 14); - output_pixel(&dest[2], av_clip_uintp2(B_R + Y1, 30) >> 14); + output_pixel(&dest[0], av_clip_uintp2(((int)(R_B + Y1) >> 14) + (1<<15), 16)); + output_pixel(&dest[1], av_clip_uintp2(((int)( G + Y1) >> 14) + (1<<15), 16)); + output_pixel(&dest[2], av_clip_uintp2(((int)(B_R + Y1) >> 14) + (1<<15), 16)); if (eightbytes) { output_pixel(&dest[3], av_clip_uintp2(A1 , 30) >> 14); - output_pixel(&dest[4], av_clip_uintp2(R_B + Y2, 30) >> 14); - output_pixel(&dest[5], av_clip_uintp2( G + Y2, 30) >> 14); - output_pixel(&dest[6], av_clip_uintp2(B_R + Y2, 30) >> 14); + output_pixel(&dest[4], av_clip_uintp2(((int)(R_B + Y2) >> 14) + (1<<15), 16)); + output_pixel(&dest[5], av_clip_uintp2(((int)( G + Y2) >> 14) + (1<<15), 16)); + output_pixel(&dest[6], av_clip_uintp2(((int)(B_R + Y2) >> 14) + (1<<15), 16)); output_pixel(&dest[7], av_clip_uintp2(A2 , 30) >> 14); dest += 8; } else { - output_pixel(&dest[3], av_clip_uintp2(R_B + Y2, 30) >> 14); - output_pixel(&dest[4], av_clip_uintp2( G + Y2, 30) >> 14); - output_pixel(&dest[5], av_clip_uintp2(B_R + Y2, 30) >> 14); + output_pixel(&dest[3], av_clip_uintp2(((int)(R_B + Y2) >> 14) + (1<<15), 16)); + output_pixel(&dest[4], av_clip_uintp2(((int)( G + Y2) >> 14) + (1<<15), 16)); + output_pixel(&dest[5], av_clip_uintp2(((int)(B_R + Y2) >> 14) + (1<<15), 16)); dest += 6; } } @@ -1092,8 +1093,8 @@ yuv2rgba64_2_c_template(SwsContext *c, const int32_t *buf[2], av_assert2(uvalpha <= 4096U); for (i = 0; i < ((dstW + 1) >> 1); i++) { - int Y1 = (buf0[i * 2] * yalpha1 + buf1[i * 2] * yalpha) >> 14; - int Y2 = (buf0[i * 2 + 1] * yalpha1 + buf1[i * 2 + 1] * yalpha) >> 14; + unsigned Y1 = (buf0[i * 2] * yalpha1 + buf1[i * 2] * yalpha) >> 14; + unsigned Y2 = (buf0[i * 2 + 1] * yalpha1 + buf1[i * 2 + 1] * yalpha) >> 14; int U = (ubuf0[i] * uvalpha1 + ubuf1[i] * uvalpha - (128 << 23)) >> 14; int V = (vbuf0[i] * uvalpha1 + vbuf1[i] * uvalpha - (128 << 23)) >> 14; int R, G, B; @@ -1102,8 +1103,8 @@ yuv2rgba64_2_c_template(SwsContext *c, const int32_t *buf[2], Y2 -= c->yuv2rgb_y_offset; Y1 *= c->yuv2rgb_y_coeff; Y2 *= c->yuv2rgb_y_coeff; - Y1 += 1 << 13; - Y2 += 1 << 13; + Y1 += (1 << 13) - (1 << 29); + Y2 += (1 << 13) - (1 << 29); R = V * c->yuv2rgb_v2r_coeff; G = V * c->yuv2rgb_v2g_coeff + U * c->yuv2rgb_u2g_coeff; @@ -1117,20 +1118,20 @@ yuv2rgba64_2_c_template(SwsContext *c, const int32_t *buf[2], A2 += 1 << 13; } - output_pixel(&dest[0], av_clip_uintp2(R_B + Y1, 30) >> 14); - output_pixel(&dest[1], av_clip_uintp2( G + Y1, 30) >> 14); - output_pixel(&dest[2], av_clip_uintp2(B_R + Y1, 30) >> 14); + output_pixel(&dest[0], av_clip_uintp2(((int)(R_B + Y1) >> 14) + (1<<15), 16)); + output_pixel(&dest[1], av_clip_uintp2(((int)( G + Y1) >> 14) + (1<<15), 16)); + output_pixel(&dest[2], av_clip_uintp2(((int)(B_R + Y1) >> 14) + (1<<15), 16)); if (eightbytes) { output_pixel(&dest[3], av_clip_uintp2(A1 , 30) >> 14); - output_pixel(&dest[4], av_clip_uintp2(R_B + Y2, 30) >> 14); - output_pixel(&dest[5], av_clip_uintp2( G + Y2, 30) >> 14); - output_pixel(&dest[6], av_clip_uintp2(B_R + Y2, 30) >> 14); + output_pixel(&dest[4], av_clip_uintp2(((int)(R_B + Y2) >> 14) + (1<<15), 16)); + output_pixel(&dest[5], av_clip_uintp2(((int)( G + Y2) >> 14) + (1<<15), 16)); + output_pixel(&dest[6], av_clip_uintp2(((int)(B_R + Y2) >> 14) + (1<<15), 16)); output_pixel(&dest[7], av_clip_uintp2(A2 , 30) >> 14); dest += 8; } else { - output_pixel(&dest[3], av_clip_uintp2(R_B + Y2, 30) >> 14); - output_pixel(&dest[4], av_clip_uintp2( G + Y2, 30) >> 14); - output_pixel(&dest[5], av_clip_uintp2(B_R + Y2, 30) >> 14); + output_pixel(&dest[3], av_clip_uintp2(((int)(R_B + Y2) >> 14) + (1<<15), 16)); + output_pixel(&dest[4], av_clip_uintp2(((int)( G + Y2) >> 14) + (1<<15), 16)); + output_pixel(&dest[5], av_clip_uintp2(((int)(B_R + Y2) >> 14) + (1<<15), 16)); dest += 6; } } @@ -1148,8 +1149,8 @@ yuv2rgba64_1_c_template(SwsContext *c, const int32_t *buf0, if (uvalpha < 2048) { for (i = 0; i < ((dstW + 1) >> 1); i++) { - int Y1 = (buf0[i * 2] ) >> 2; - int Y2 = (buf0[i * 2 + 1]) >> 2; + SUINT Y1 = (buf0[i * 2] ) >> 2; + SUINT Y2 = (buf0[i * 2 + 1]) >> 2; int U = (ubuf0[i] - (128 << 11)) >> 2; int V = (vbuf0[i] - (128 << 11)) >> 2; int R, G, B; @@ -1158,12 +1159,12 @@ yuv2rgba64_1_c_template(SwsContext *c, const int32_t *buf0, Y2 -= c->yuv2rgb_y_offset; Y1 *= c->yuv2rgb_y_coeff; Y2 *= c->yuv2rgb_y_coeff; - Y1 += 1 << 13; - Y2 += 1 << 13; + Y1 += (1 << 13) - (1 << 29); + Y2 += (1 << 13) - (1 << 29); if (hasAlpha) { - A1 = abuf0[i * 2 ] << 11; - A2 = abuf0[i * 2 + 1] << 11; + A1 = abuf0[i * 2 ] * (1 << 11); + A2 = abuf0[i * 2 + 1] * (1 << 11); A1 += 1 << 13; A2 += 1 << 13; @@ -1173,20 +1174,20 @@ yuv2rgba64_1_c_template(SwsContext *c, const int32_t *buf0, G = V * c->yuv2rgb_v2g_coeff + U * c->yuv2rgb_u2g_coeff; B = U * c->yuv2rgb_u2b_coeff; - output_pixel(&dest[0], av_clip_uintp2(R_B + Y1, 30) >> 14); - output_pixel(&dest[1], av_clip_uintp2( G + Y1, 30) >> 14); - output_pixel(&dest[2], av_clip_uintp2(B_R + Y1, 30) >> 14); + output_pixel(&dest[0], av_clip_uintp2(((int)(R_B + Y1) >> 14) + (1<<15), 16)); + output_pixel(&dest[1], av_clip_uintp2(((int)( G + Y1) >> 14) + (1<<15), 16)); + output_pixel(&dest[2], av_clip_uintp2(((int)(B_R + Y1) >> 14) + (1<<15), 16)); if (eightbytes) { output_pixel(&dest[3], av_clip_uintp2(A1 , 30) >> 14); - output_pixel(&dest[4], av_clip_uintp2(R_B + Y2, 30) >> 14); - output_pixel(&dest[5], av_clip_uintp2( G + Y2, 30) >> 14); - output_pixel(&dest[6], av_clip_uintp2(B_R + Y2, 30) >> 14); + output_pixel(&dest[4], av_clip_uintp2(((int)(R_B + Y2) >> 14) + (1<<15), 16)); + output_pixel(&dest[5], av_clip_uintp2(((int)( G + Y2) >> 14) + (1<<15), 16)); + output_pixel(&dest[6], av_clip_uintp2(((int)(B_R + Y2) >> 14) + (1<<15), 16)); output_pixel(&dest[7], av_clip_uintp2(A2 , 30) >> 14); dest += 8; } else { - output_pixel(&dest[3], av_clip_uintp2(R_B + Y2, 30) >> 14); - output_pixel(&dest[4], av_clip_uintp2( G + Y2, 30) >> 14); - output_pixel(&dest[5], av_clip_uintp2(B_R + Y2, 30) >> 14); + output_pixel(&dest[3], av_clip_uintp2(((int)(R_B + Y2) >> 14) + (1<<15), 16)); + output_pixel(&dest[4], av_clip_uintp2(((int)( G + Y2) >> 14) + (1<<15), 16)); + output_pixel(&dest[5], av_clip_uintp2(((int)(B_R + Y2) >> 14) + (1<<15), 16)); dest += 6; } } @@ -1194,8 +1195,8 @@ yuv2rgba64_1_c_template(SwsContext *c, const int32_t *buf0, const int32_t *ubuf1 = ubuf[1], *vbuf1 = vbuf[1]; int A1 = 0xffff<<14, A2 = 0xffff<<14; for (i = 0; i < ((dstW + 1) >> 1); i++) { - int Y1 = (buf0[i * 2] ) >> 2; - int Y2 = (buf0[i * 2 + 1]) >> 2; + SUINT Y1 = (buf0[i * 2] ) >> 2; + SUINT Y2 = (buf0[i * 2 + 1]) >> 2; int U = (ubuf0[i] + ubuf1[i] - (128 << 12)) >> 3; int V = (vbuf0[i] + vbuf1[i] - (128 << 12)) >> 3; int R, G, B; @@ -1204,12 +1205,12 @@ yuv2rgba64_1_c_template(SwsContext *c, const int32_t *buf0, Y2 -= c->yuv2rgb_y_offset; Y1 *= c->yuv2rgb_y_coeff; Y2 *= c->yuv2rgb_y_coeff; - Y1 += 1 << 13; - Y2 += 1 << 13; + Y1 += (1 << 13) - (1 << 29); + Y2 += (1 << 13) - (1 << 29); if (hasAlpha) { - A1 = abuf0[i * 2 ] << 11; - A2 = abuf0[i * 2 + 1] << 11; + A1 = abuf0[i * 2 ] * (1 << 11); + A2 = abuf0[i * 2 + 1] * (1 << 11); A1 += 1 << 13; A2 += 1 << 13; @@ -1219,20 +1220,20 @@ yuv2rgba64_1_c_template(SwsContext *c, const int32_t *buf0, G = V * c->yuv2rgb_v2g_coeff + U * c->yuv2rgb_u2g_coeff; B = U * c->yuv2rgb_u2b_coeff; - output_pixel(&dest[0], av_clip_uintp2(R_B + Y1, 30) >> 14); - output_pixel(&dest[1], av_clip_uintp2( G + Y1, 30) >> 14); - output_pixel(&dest[2], av_clip_uintp2(B_R + Y1, 30) >> 14); + output_pixel(&dest[0], av_clip_uintp2(((int)(R_B + Y1) >> 14) + (1<<15), 16)); + output_pixel(&dest[1], av_clip_uintp2(((int)( G + Y1) >> 14) + (1<<15), 16)); + output_pixel(&dest[2], av_clip_uintp2(((int)(B_R + Y1) >> 14) + (1<<15), 16)); if (eightbytes) { output_pixel(&dest[3], av_clip_uintp2(A1 , 30) >> 14); - output_pixel(&dest[4], av_clip_uintp2(R_B + Y2, 30) >> 14); - output_pixel(&dest[5], av_clip_uintp2( G + Y2, 30) >> 14); - output_pixel(&dest[6], av_clip_uintp2(B_R + Y2, 30) >> 14); + output_pixel(&dest[4], av_clip_uintp2(((int)(R_B + Y2) >> 14) + (1<<15), 16)); + output_pixel(&dest[5], av_clip_uintp2(((int)( G + Y2) >> 14) + (1<<15), 16)); + output_pixel(&dest[6], av_clip_uintp2(((int)(B_R + Y2) >> 14) + (1<<15), 16)); output_pixel(&dest[7], av_clip_uintp2(A2 , 30) >> 14); dest += 8; } else { - output_pixel(&dest[3], av_clip_uintp2(R_B + Y2, 30) >> 14); - output_pixel(&dest[4], av_clip_uintp2( G + Y2, 30) >> 14); - output_pixel(&dest[5], av_clip_uintp2(B_R + Y2, 30) >> 14); + output_pixel(&dest[3], av_clip_uintp2(((int)(R_B + Y2) >> 14) + (1<<15), 16)); + output_pixel(&dest[4], av_clip_uintp2(((int)( G + Y2) >> 14) + (1<<15), 16)); + output_pixel(&dest[5], av_clip_uintp2(((int)(B_R + Y2) >> 14) + (1<<15), 16)); dest += 6; } } @@ -1283,7 +1284,7 @@ yuv2rgba64_full_X_c_template(SwsContext *c, const int16_t *lumFilter, // 8bit: 27 -> 17bit, 16bit: 31 - 14 = 17bit Y -= c->yuv2rgb_y_offset; Y *= c->yuv2rgb_y_coeff; - Y += 1 << 13; // 21 + Y += (1 << 13) - (1<<29); // 21 // 8bit: 17 + 13bit = 30bit, 16bit: 17 + 13bit = 30bit R = V * c->yuv2rgb_v2r_coeff; @@ -1291,9 +1292,9 @@ yuv2rgba64_full_X_c_template(SwsContext *c, const int16_t *lumFilter, B = U * c->yuv2rgb_u2b_coeff; // 8bit: 30 - 22 = 8bit, 16bit: 30bit - 14 = 16bit - output_pixel(&dest[0], av_clip_uintp2(R_B + Y, 30) >> 14); - output_pixel(&dest[1], av_clip_uintp2( G + Y, 30) >> 14); - output_pixel(&dest[2], av_clip_uintp2(B_R + Y, 30) >> 14); + output_pixel(&dest[0], av_clip_uintp2(((int)(R_B + (unsigned)Y)>>14) + (1<<15), 16)); + output_pixel(&dest[1], av_clip_uintp2(((int)( G + (unsigned)Y)>>14) + (1<<15), 16)); + output_pixel(&dest[2], av_clip_uintp2(((int)(B_R + (unsigned)Y)>>14) + (1<<15), 16)); if (eightbytes) { output_pixel(&dest[3], av_clip_uintp2(A, 30) >> 14); dest += 4; @@ -1331,7 +1332,7 @@ yuv2rgba64_full_2_c_template(SwsContext *c, const int32_t *buf[2], Y -= c->yuv2rgb_y_offset; Y *= c->yuv2rgb_y_coeff; - Y += 1 << 13; + Y += (1 << 13) - (1 << 29); R = V * c->yuv2rgb_v2r_coeff; G = V * c->yuv2rgb_v2g_coeff + U * c->yuv2rgb_u2g_coeff; @@ -1343,9 +1344,9 @@ yuv2rgba64_full_2_c_template(SwsContext *c, const int32_t *buf[2], A += 1 << 13; } - output_pixel(&dest[0], av_clip_uintp2(R_B + Y, 30) >> 14); - output_pixel(&dest[1], av_clip_uintp2( G + Y, 30) >> 14); - output_pixel(&dest[2], av_clip_uintp2(B_R + Y, 30) >> 14); + output_pixel(&dest[0], av_clip_uintp2(((R_B + Y) >> 14) + (1<<15), 16)); + output_pixel(&dest[1], av_clip_uintp2((( G + Y) >> 14) + (1<<15), 16)); + output_pixel(&dest[2], av_clip_uintp2(((B_R + Y) >> 14) + (1<<15), 16)); if (eightbytes) { output_pixel(&dest[3], av_clip_uintp2(A, 30) >> 14); dest += 4; @@ -1367,17 +1368,17 @@ yuv2rgba64_full_1_c_template(SwsContext *c, const int32_t *buf0, if (uvalpha < 2048) { for (i = 0; i < dstW; i++) { - int Y = (buf0[i]) >> 2; + SUINT Y = (buf0[i]) >> 2; int U = (ubuf0[i] - (128 << 11)) >> 2; int V = (vbuf0[i] - (128 << 11)) >> 2; int R, G, B; Y -= c->yuv2rgb_y_offset; Y *= c->yuv2rgb_y_coeff; - Y += 1 << 13; + Y += (1 << 13) - (1 << 29); if (hasAlpha) { - A = abuf0[i] << 11; + A = abuf0[i] * (1 << 11); A += 1 << 13; } @@ -1386,9 +1387,9 @@ yuv2rgba64_full_1_c_template(SwsContext *c, const int32_t *buf0, G = V * c->yuv2rgb_v2g_coeff + U * c->yuv2rgb_u2g_coeff; B = U * c->yuv2rgb_u2b_coeff; - output_pixel(&dest[0], av_clip_uintp2(R_B + Y, 30) >> 14); - output_pixel(&dest[1], av_clip_uintp2( G + Y, 30) >> 14); - output_pixel(&dest[2], av_clip_uintp2(B_R + Y, 30) >> 14); + output_pixel(&dest[0], av_clip_uintp2(((int)(R_B + Y) >> 14) + (1<<15), 16)); + output_pixel(&dest[1], av_clip_uintp2(((int)( G + Y) >> 14) + (1<<15), 16)); + output_pixel(&dest[2], av_clip_uintp2(((int)(B_R + Y) >> 14) + (1<<15), 16)); if (eightbytes) { output_pixel(&dest[3], av_clip_uintp2(A, 30) >> 14); dest += 4; @@ -1400,17 +1401,17 @@ yuv2rgba64_full_1_c_template(SwsContext *c, const int32_t *buf0, const int32_t *ubuf1 = ubuf[1], *vbuf1 = vbuf[1]; int A = 0xffff<<14; for (i = 0; i < dstW; i++) { - int Y = (buf0[i] ) >> 2; + SUINT Y = (buf0[i] ) >> 2; int U = (ubuf0[i] + ubuf1[i] - (128 << 12)) >> 3; int V = (vbuf0[i] + vbuf1[i] - (128 << 12)) >> 3; int R, G, B; Y -= c->yuv2rgb_y_offset; Y *= c->yuv2rgb_y_coeff; - Y += 1 << 13; + Y += (1 << 13) - (1 << 29); if (hasAlpha) { - A = abuf0[i] << 11; + A = abuf0[i] * (1 << 11); A += 1 << 13; } @@ -1419,9 +1420,9 @@ yuv2rgba64_full_1_c_template(SwsContext *c, const int32_t *buf0, G = V * c->yuv2rgb_v2g_coeff + U * c->yuv2rgb_u2g_coeff; B = U * c->yuv2rgb_u2b_coeff; - output_pixel(&dest[0], av_clip_uintp2(R_B + Y, 30) >> 14); - output_pixel(&dest[1], av_clip_uintp2( G + Y, 30) >> 14); - output_pixel(&dest[2], av_clip_uintp2(B_R + Y, 30) >> 14); + output_pixel(&dest[0], av_clip_uintp2(((int)(R_B + Y) >> 14) + (1<<15), 16)); + output_pixel(&dest[1], av_clip_uintp2(((int)( G + Y) >> 14) + (1<<15), 16)); + output_pixel(&dest[2], av_clip_uintp2(((int)(B_R + Y) >> 14) + (1<<15), 16)); if (eightbytes) { output_pixel(&dest[3], av_clip_uintp2(A, 30) >> 14); dest += 4; @@ -1860,9 +1861,9 @@ static av_always_inline void yuv2rgb_write_full(SwsContext *c, Y -= c->yuv2rgb_y_offset; Y *= c->yuv2rgb_y_coeff; Y += 1 << 21; - R = (unsigned)Y + V*c->yuv2rgb_v2r_coeff; - G = (unsigned)Y + V*c->yuv2rgb_v2g_coeff + U*c->yuv2rgb_u2g_coeff; - B = (unsigned)Y + U*c->yuv2rgb_u2b_coeff; + R = (unsigned)Y + V*(unsigned)c->yuv2rgb_v2r_coeff; + G = (unsigned)Y + V*(unsigned)c->yuv2rgb_v2g_coeff + U*(unsigned)c->yuv2rgb_u2g_coeff; + B = (unsigned)Y + U*(unsigned)c->yuv2rgb_u2b_coeff; if ((R | G | B) & 0xC0000000) { R = av_clip_uintp2(R, 30); G = av_clip_uintp2(G, 30); @@ -2212,9 +2213,9 @@ yuv2gbrp_full_X_c(SwsContext *c, const int16_t *lumFilter, Y -= c->yuv2rgb_y_offset; Y *= c->yuv2rgb_y_coeff; Y += 1 << (SH-1); - R = Y + V * c->yuv2rgb_v2r_coeff; - G = Y + V * c->yuv2rgb_v2g_coeff + U * c->yuv2rgb_u2g_coeff; - B = Y + U * c->yuv2rgb_u2b_coeff; + R = Y + V * (unsigned)c->yuv2rgb_v2r_coeff; + G = Y + V * (unsigned)c->yuv2rgb_v2g_coeff + U * (unsigned)c->yuv2rgb_u2g_coeff; + B = Y + U * (unsigned)c->yuv2rgb_u2b_coeff; if ((R | G | B) & 0xC0000000) { R = av_clip_uintp2(R, 30); diff --git a/libswscale/ppc/yuv2rgb_altivec.c b/libswscale/ppc/yuv2rgb_altivec.c index 5e1033a973..8b0a93796f 100644 --- a/libswscale/ppc/yuv2rgb_altivec.c +++ b/libswscale/ppc/yuv2rgb_altivec.c @@ -284,7 +284,7 @@ static inline void cvtyuvtoRGB(SwsContext *c, vector signed short Y, * ------------------------------------------------------------------------------ */ -#if !HAVE_VSX +#if !HAVE_VEC_XL static inline vector unsigned char vec_xl(signed long long offset, const ubyte *addr) { const vector unsigned char *v_addr = (const vector unsigned char *) (addr + offset); @@ -292,7 +292,7 @@ static inline vector unsigned char vec_xl(signed long long offset, const ubyte * return (vector unsigned char) vec_perm(v_addr[0], v_addr[1], align_perm); } -#endif /* !HAVE_VSX */ +#endif /* !HAVE_VEC_XL */ #define DEFCSP420_CVT(name, out_pixels) \ static int altivec_ ## name(SwsContext *c, const unsigned char **in, \ diff --git a/libswscale/slice.c b/libswscale/slice.c index d96db13364..d822ed1271 100644 --- a/libswscale/slice.c +++ b/libswscale/slice.c @@ -59,7 +59,7 @@ static int alloc_lines(SwsSlice *s, int size, int width) for (j = 0; j < n; ++j) { // chroma plane line U and V are expected to be contiguous in memory // by mmx vertical scaler code - s->plane[i].line[j] = av_malloc(size * 2 + 32); + s->plane[i].line[j] = av_mallocz(size * 2 + 32); if (!s->plane[i].line[j]) { free_lines(s); return AVERROR(ENOMEM); @@ -288,7 +288,10 @@ int ff_init_filters(SwsContext * c) if (!c->desc) return AVERROR(ENOMEM); c->slice = av_mallocz_array(sizeof(SwsSlice), c->numSlice); - + if (!c->slice) { + res = AVERROR(ENOMEM); + goto cleanup; + } res = alloc_slice(&c->slice[0], c->srcFormat, c->srcH, c->chrSrcH, c->chrSrcHSubSample, c->chrSrcVSubSample, 0); if (res < 0) goto cleanup; diff --git a/libswscale/swscale.c b/libswscale/swscale.c index 12160a169a..e72dff6814 100644 --- a/libswscale/swscale.c +++ b/libswscale/swscale.c @@ -226,7 +226,7 @@ static void lumRangeFromJpeg16_c(int16_t *_dst, int width) int i; int32_t *dst = (int32_t *) _dst; for (i = 0; i < width; i++) - dst[i] = (dst[i]*(14071/4) + (33561947<<4)/4)>>12; + dst[i] = ((int)(dst[i]*(14071U/4) + (33561947<<4)/4)) >> 12; } @@ -770,7 +770,8 @@ int attribute_align_arg sws_scale(struct SwsContext *c, if ((srcSliceY & (macro_height-1)) || ((srcSliceH& (macro_height-1)) && srcSliceY + srcSliceH != c->srcH) || - srcSliceY + srcSliceH > c->srcH) { + srcSliceY + srcSliceH > c->srcH || + (isBayer(c->srcFormat) && srcSliceH <= 1)) { av_log(c, AV_LOG_ERROR, "Slice parameters %d, %d are invalid\n", srcSliceY, srcSliceH); return AVERROR(EINVAL); } diff --git a/libswscale/utils.c b/libswscale/utils.c index 352a8ed116..a5702922b8 100644 --- a/libswscale/utils.c +++ b/libswscale/utils.c @@ -512,7 +512,7 @@ static av_cold int initFilter(int16_t **outFilter, int32_t **filterPos, filter[i * filterSize + j] = coeff; xx++; } - xDstInSrc += 2 * xInc; + xDstInSrc += 2LL * xInc; } } @@ -1763,7 +1763,7 @@ av_cold int sws_init_context(SwsContext *c, SwsFilter *srcFilter, } for (i = 0; i < 4; i++) - if (!FF_ALLOCZ_TYPED_ARRAY(c->dither_error[i], c->dstW + 2)) + if (!FF_ALLOCZ_TYPED_ARRAY(c->dither_error[i], c->dstW + 3)) goto nomem; c->needAlpha = (CONFIG_SWSCALE_ALPHA && isALPHA(c->srcFormat) && isALPHA(c->dstFormat)) ? 1 : 0; @@ -1840,7 +1840,7 @@ av_cold int sws_init_context(SwsContext *c, SwsFilter *srcFilter, /* unscaled special cases */ if (unscaled && !usesHFilter && !usesVFilter && (c->srcRange == c->dstRange || isAnyRGB(dstFormat) || - isFloat(srcFormat) || isFloat(dstFormat))){ + isFloat(srcFormat) || isFloat(dstFormat) || isBayer(srcFormat))){ ff_get_unscaled_swscale(c); if (c->swscale) { diff --git a/libswscale/x86/swscale.c b/libswscale/x86/swscale.c index cc9e8b0155..0848a31461 100644 --- a/libswscale/x86/swscale.c +++ b/libswscale/x86/swscale.c @@ -197,7 +197,8 @@ static void yuv2yuvX_ ##opt(const int16_t *filter, int filterSize, \ const int16_t **src, uint8_t *dest, int dstW, \ const uint8_t *dither, int offset) \ { \ - ff_yuv2yuvX_ ##opt(filter, filterSize - 1, 0, dest - offset, dstW + offset, dither, offset); \ + if(dstW > 0) \ + ff_yuv2yuvX_ ##opt(filter, filterSize - 1, 0, dest - offset, dstW + offset, dither, offset); \ return; \ } @@ -215,7 +216,8 @@ static void yuv2yuvX_ ##opt(const int16_t *filter, int filterSize, \ yuv2yuvX_mmx(filter, filterSize, src, dest, dstW, dither, offset); \ return; \ } \ - ff_yuv2yuvX_ ##opt(filter, filterSize - 1, 0, dest - offset, pixelsProcessed + offset, dither, offset); \ + if(pixelsProcessed > 0) \ + ff_yuv2yuvX_ ##opt(filter, filterSize - 1, 0, dest - offset, pixelsProcessed + offset, dither, offset); \ if(remainder > 0){ \ ff_yuv2yuvX_mmx(filter, filterSize - 1, pixelsProcessed, dest - offset, pixelsProcessed + remainder + offset, dither, offset); \ } \ diff --git a/libswscale/x86/yuv2yuvX.asm b/libswscale/x86/yuv2yuvX.asm index 521880dabe..b6294cb919 100644 --- a/libswscale/x86/yuv2yuvX.asm +++ b/libswscale/x86/yuv2yuvX.asm @@ -37,8 +37,10 @@ SECTION .text cglobal yuv2yuvX, 7, 7, 8, filter, filterSize, src, dest, dstW, dither, offset %if notcpuflag(sse3) %define movr mova +%define unroll 1 %else %define movr movdqu +%define unroll 2 %endif movsxdifnidn dstWq, dstWd movsxdifnidn offsetq, offsetd @@ -70,8 +72,10 @@ cglobal yuv2yuvX, 7, 7, 8, filter, filterSize, src, dest, dstW, dither, offset .outerloop: mova m4, m7 mova m3, m7 +%if cpuflag(sse3) mova m6, m7 mova m1, m7 +%endif .loop: %if cpuflag(avx2) vpbroadcastq m0, [filterSizeq + 8] @@ -84,28 +88,36 @@ cglobal yuv2yuvX, 7, 7, 8, filter, filterSize, src, dest, dstW, dither, offset pmulhw m5, m0, [srcq + offsetq * 2 + mmsize] paddw m3, m3, m2 paddw m4, m4, m5 +%if cpuflag(sse3) pmulhw m2, m0, [srcq + offsetq * 2 + 2 * mmsize] pmulhw m5, m0, [srcq + offsetq * 2 + 3 * mmsize] paddw m6, m6, m2 paddw m1, m1, m5 +%endif add filterSizeq, $10 mov srcq, [filterSizeq] test srcq, srcq jnz .loop psraw m3, m3, 3 psraw m4, m4, 3 +%if cpuflag(sse3) psraw m6, m6, 3 psraw m1, m1, 3 +%endif packuswb m3, m3, m4 +%if cpuflag(sse3) packuswb m6, m6, m1 +%endif mov srcq, [filterq] %if cpuflag(avx2) vpermq m3, m3, 216 vpermq m6, m6, 216 %endif movr [destq + offsetq], m3 +%if cpuflag(sse3) movr [destq + offsetq + mmsize], m6 - add offsetq, mmsize * 2 +%endif + add offsetq, mmsize * unroll mov filterSizeq, filterq cmp offsetq, dstWq jb .outerloop diff --git a/libswscale/yuv2rgb.c b/libswscale/yuv2rgb.c index 6a3956e8e2..eb095a77b1 100644 --- a/libswscale/yuv2rgb.c +++ b/libswscale/yuv2rgb.c @@ -826,7 +826,7 @@ av_cold int ff_yuv2rgb_c_init_tables(SwsContext *c, const int inv_table[4], cbu = (cbu * contrast * saturation) >> 32; cgu = (cgu * contrast * saturation) >> 32; cgv = (cgv * contrast * saturation) >> 32; - oy -= 256 * brightness; + oy -= 256LL * brightness; c->uOffset = 0x0400040004000400LL; c->vOffset = 0x0400040004000400LL; diff --git a/tests/checkasm/sw_scale.c b/tests/checkasm/sw_scale.c index a10118704b..3ac0f9082f 100644 --- a/tests/checkasm/sw_scale.c +++ b/tests/checkasm/sw_scale.c @@ -68,8 +68,8 @@ static void check_yuv2yuvX(void) #define FILTER_SIZES 4 static const int filter_sizes[FILTER_SIZES] = {1, 4, 8, 16}; #define LARGEST_INPUT_SIZE 512 -#define INPUT_SIZES 4 - static const int input_sizes[INPUT_SIZES] = {128, 144, 256, 512}; +#define INPUT_SIZES 6 + static const int input_sizes[INPUT_SIZES] = {8, 24, 128, 144, 256, 512}; declare_func_emms(AV_CPU_FLAG_MMX, void, const int16_t *filter, int filterSize, const int16_t **src, uint8_t *dest, @@ -107,7 +107,7 @@ static void check_yuv2yuvX(void) for(j = 0; j < 4; ++j) vFilterData[i].coeff[j + 4] = filter_coeff[i]; } - if (check_func(ctx->yuv2planeX, "yuv2yuvX_%d_%d", filter_sizes[fsi], osi)){ + if (check_func(ctx->yuv2planeX, "yuv2yuvX_%d_%d_%d", filter_sizes[fsi], osi, dstW)){ memset(dst0, 0, LARGEST_INPUT_SIZE * sizeof(dst0[0])); memset(dst1, 0, LARGEST_INPUT_SIZE * sizeof(dst1[0])); diff --git a/tests/fate/mov.mak b/tests/fate/mov.mak index 0fd20fef96..957bd5ca4e 100644 --- a/tests/fate/mov.mak +++ b/tests/fate/mov.mak @@ -29,6 +29,7 @@ FATE_MOV_FFPROBE = fate-mov-neg-firstpts-discard \ fate-mov-guess-delay-2 \ fate-mov-guess-delay-3 \ fate-mov-mp4-with-mov-in24-ver \ + fate-mov-mp4-extended-atom \ FATE_MOV_FASTSTART = fate-mov-faststart-4gb-overflow \ @@ -124,3 +125,5 @@ fate-mov-faststart-4gb-overflow: CMP = oneline fate-mov-faststart-4gb-overflow: REF = bc875921f151871e787c4b4023269b29 fate-mov-mp4-with-mov-in24-ver: CMD = run ffprobe$(PROGSSUF)$(EXESUF) -show_entries stream=codec_name -select_streams 1 $(TARGET_SAMPLES)/mov/mp4-with-mov-in24-ver.mp4 + +fate-mov-mp4-extended-atom: CMD = run ffprobe$(PROGSSUF)$(EXESUF) -show_packets -print_format compact -select_streams v $(TARGET_SAMPLES)/mov/extended_atom_size_probe diff --git a/tests/fate/subtitles.mak b/tests/fate/subtitles.mak index ee65afe35b..31d8b93521 100644 --- a/tests/fate/subtitles.mak +++ b/tests/fate/subtitles.mak @@ -102,6 +102,7 @@ fate-sub-charenc: CMD = fmtstdout ass -sub_charenc cp1251 -i $(TARGET_SAMPLES)/s FATE_SUBTITLES-$(call DEMDEC, SCC, CCAPTION) += fate-sub-scc fate-sub-scc: CMD = fmtstdout ass -ss 57 -i $(TARGET_SAMPLES)/sub/witch.scc +fate-sub-scc: CMP = diff FATE_SUBTITLES-$(call ALLYES, MPEGTS_DEMUXER DVBSUB_DECODER DVBSUB_ENCODER) += fate-sub-dvb fate-sub-dvb: CMD = framecrc -i $(TARGET_SAMPLES)/sub/dvbsubtest_filter.ts -map s:0 -c dvbsub diff --git a/tests/ref/fate/mov-mp4-extended-atom b/tests/ref/fate/mov-mp4-extended-atom new file mode 100644 index 0000000000..9d01abb2f5 --- /dev/null +++ b/tests/ref/fate/mov-mp4-extended-atom @@ -0,0 +1 @@ +packet|codec_type=video|stream_index=0|pts=0|pts_time=0.000000|dts=0|dts_time=0.000000|duration=1001|duration_time=0.033367|size=14798|pos=16|flags=K_ diff --git a/tests/ref/fate/ts-opus-demux b/tests/ref/fate/ts-opus-demux index 3c5edffb2c..37534350a1 100644 --- a/tests/ref/fate/ts-opus-demux +++ b/tests/ref/fate/ts-opus-demux @@ -1,4 +1,4 @@ -#extradata 0: 30, 0x53be0347 +#extradata 0: 30, 0x69290482 #tb 0: 1/90000 #media_type 0: audio #codec_id 0: opus diff --git a/tests/ref/fate/url b/tests/ref/fate/url index 08e80def7d..8489d10968 100644 --- a/tests/ref/fate/url +++ b/tests/ref/fate/url @@ -79,6 +79,26 @@ Testing ff_make_absolute_url: http://server/foo/bar ..doubledotfile => http://server/foo/..doubledotfile http://server/foo/bar double..dotfile => http://server/foo/double..dotfile http://server/foo/bar doubledotfile.. => http://server/foo/doubledotfile.. + file1 file2 => file2 + dir/file1 file2 => dir/file2 + dir/file1 ../file2 => dir/../file2 + dir\file1 file2 => file2 + dir\file1 file2 DOS dir\file2 + \\srv\shr\file ..\..\dummy => ..\..\dummy + \\srv\shr\file ..\..\dummy DOS \\srv\shr\..\..\dummy + \\srv\shr\file dummy => dummy + \\srv\shr\file dummy DOS \\srv\shr\dummy + \\srv\shr\file \\srv2\shr2\file2 => \\srv2\shr2\file2 + \\srv\shr\file d:/file => d:/file + C:\dir\a ..\file => C:..\file + C:\dir\a ..\file DOS C:\dir\..\file + C:\dir\a \\srv\shr\file => C:\\srv\shr\file + C:\dir\a \\srv\shr\file DOS \\srv\shr\file + C:\dir\a d:\file => d:\file + http://a/b \\srv\shr\file => http://a/\\srv\shr\file + http://a/b //srv/shr/file => http://srv/shr/file + http://a/b d:\file => d:\file + http://a/b C:/file => C:/file http://a/b/c/d;p?q g:h => g:h http://a/b/c/d;p?q g => http://a/b/c/g http://a/b/c/d;p?q ./g => http://a/b/c/g diff --git a/tests/ref/fate/webm-dash-manifest b/tests/ref/fate/webm-dash-manifest index f5fc9121da..3a557fc39f 100644 --- a/tests/ref/fate/webm-dash-manifest +++ b/tests/ref/fate/webm-dash-manifest @@ -6,7 +6,7 @@ type="static" mediaPresentationDuration="PT32.501S" minBufferTime="PT1S" - profiles="urn:webm:dash:profile:webm-on-demand:2012"> + profiles="urn:mpeg:dash:profile:webm-on-demand:2012"> diff --git a/tests/ref/fate/webm-dash-manifest-representations b/tests/ref/fate/webm-dash-manifest-representations index 8556ecebee..41713bb367 100644 --- a/tests/ref/fate/webm-dash-manifest-representations +++ b/tests/ref/fate/webm-dash-manifest-representations @@ -6,7 +6,7 @@ type="static" mediaPresentationDuration="PT32.48S" minBufferTime="PT1S" - profiles="urn:webm:dash:profile:webm-on-demand:2012"> + profiles="urn:mpeg:dash:profile:webm-on-demand:2012"> diff --git a/tests/ref/fate/webm-dash-manifest-unaligned-audio-streams b/tests/ref/fate/webm-dash-manifest-unaligned-audio-streams index 6e9de211fb..b1bc7ecea1 100644 --- a/tests/ref/fate/webm-dash-manifest-unaligned-audio-streams +++ b/tests/ref/fate/webm-dash-manifest-unaligned-audio-streams @@ -6,7 +6,7 @@ type="static" mediaPresentationDuration="PT32.501S" minBufferTime="PT1S" - profiles="urn:webm:dash:profile:webm-on-demand:2012"> + profiles="urn:mpeg:dash:profile:webm-on-demand:2012"> diff --git a/tests/ref/fate/webm-dash-manifest-unaligned-video-streams b/tests/ref/fate/webm-dash-manifest-unaligned-video-streams index ce205638b6..690c2aabe3 100644 --- a/tests/ref/fate/webm-dash-manifest-unaligned-video-streams +++ b/tests/ref/fate/webm-dash-manifest-unaligned-video-streams @@ -6,7 +6,7 @@ type="static" mediaPresentationDuration="PT32.48S" minBufferTime="PT1S" - profiles="urn:webm:dash:profile:webm-on-demand:2012"> + profiles="urn:mpeg:dash:profile:webm-on-demand:2012"> diff --git a/tests/ref/seek/vsynth_lena-snow b/tests/ref/seek/vsynth_lena-snow index 33d6c27463..b2d2d22cda 100644 --- a/tests/ref/seek/vsynth_lena-snow +++ b/tests/ref/seek/vsynth_lena-snow @@ -2,45 +2,45 @@ ret: 0 st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos: 5652 size: 3035 ret: 0 st:-1 flags:0 ts:-1.000000 ret: 0 st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos: 5652 size: 3035 ret: 0 st:-1 flags:1 ts: 1.894167 -ret: 0 st: 0 flags:1 dts: 1.440000 pts: 1.440000 pos: 39806 size: 3640 +ret: 0 st: 0 flags:1 dts: 1.440000 pts: 1.440000 pos: 39690 size: 3640 ret: 0 st: 0 flags:0 ts: 0.800000 -ret: 0 st: 0 flags:1 dts: 0.960000 pts: 0.960000 pos: 27442 size: 3494 +ret: 0 st: 0 flags:1 dts: 0.960000 pts: 0.960000 pos: 27382 size: 3493 ret:-1 st: 0 flags:1 ts:-0.320000 ret:-1 st:-1 flags:0 ts: 2.576668 ret: 0 st:-1 flags:1 ts: 1.470835 -ret: 0 st: 0 flags:1 dts: 1.440000 pts: 1.440000 pos: 39806 size: 3640 +ret: 0 st: 0 flags:1 dts: 1.440000 pts: 1.440000 pos: 39690 size: 3640 ret: 0 st: 0 flags:0 ts: 0.360000 -ret: 0 st: 0 flags:1 dts: 0.480000 pts: 0.480000 pos: 16134 size: 3244 +ret: 0 st: 0 flags:1 dts: 0.480000 pts: 0.480000 pos: 16074 size: 3245 ret:-1 st: 0 flags:1 ts:-0.760000 ret:-1 st:-1 flags:0 ts: 2.153336 ret: 0 st:-1 flags:1 ts: 1.047503 -ret: 0 st: 0 flags:1 dts: 0.960000 pts: 0.960000 pos: 27442 size: 3494 +ret: 0 st: 0 flags:1 dts: 0.960000 pts: 0.960000 pos: 27382 size: 3493 ret: 0 st: 0 flags:0 ts:-0.040000 ret: 0 st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos: 5652 size: 3035 ret: 0 st: 0 flags:1 ts: 2.840000 -ret: 0 st: 0 flags:1 dts: 1.920000 pts: 1.920000 pos: 52608 size: 3582 +ret: 0 st: 0 flags:1 dts: 1.920000 pts: 1.920000 pos: 52538 size: 3582 ret: 0 st:-1 flags:0 ts: 1.730004 -ret: 0 st: 0 flags:1 dts: 1.920000 pts: 1.920000 pos: 52608 size: 3582 +ret: 0 st: 0 flags:1 dts: 1.920000 pts: 1.920000 pos: 52538 size: 3582 ret: 0 st:-1 flags:1 ts: 0.624171 -ret: 0 st: 0 flags:1 dts: 0.480000 pts: 0.480000 pos: 16134 size: 3244 +ret: 0 st: 0 flags:1 dts: 0.480000 pts: 0.480000 pos: 16074 size: 3245 ret: 0 st: 0 flags:0 ts:-0.480000 ret: 0 st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos: 5652 size: 3035 ret: 0 st: 0 flags:1 ts: 2.400000 -ret: 0 st: 0 flags:1 dts: 1.920000 pts: 1.920000 pos: 52608 size: 3582 +ret: 0 st: 0 flags:1 dts: 1.920000 pts: 1.920000 pos: 52538 size: 3582 ret: 0 st:-1 flags:0 ts: 1.306672 -ret: 0 st: 0 flags:1 dts: 1.440000 pts: 1.440000 pos: 39806 size: 3640 +ret: 0 st: 0 flags:1 dts: 1.440000 pts: 1.440000 pos: 39690 size: 3640 ret: 0 st:-1 flags:1 ts: 0.200839 ret: 0 st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos: 5652 size: 3035 ret: 0 st: 0 flags:0 ts:-0.920000 ret: 0 st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos: 5652 size: 3035 ret: 0 st: 0 flags:1 ts: 2.000000 -ret: 0 st: 0 flags:1 dts: 1.920000 pts: 1.920000 pos: 52608 size: 3582 +ret: 0 st: 0 flags:1 dts: 1.920000 pts: 1.920000 pos: 52538 size: 3582 ret: 0 st:-1 flags:0 ts: 0.883340 -ret: 0 st: 0 flags:1 dts: 0.960000 pts: 0.960000 pos: 27442 size: 3494 +ret: 0 st: 0 flags:1 dts: 0.960000 pts: 0.960000 pos: 27382 size: 3493 ret:-1 st:-1 flags:1 ts:-0.222493 ret:-1 st: 0 flags:0 ts: 2.680000 ret: 0 st: 0 flags:1 ts: 1.560000 -ret: 0 st: 0 flags:1 dts: 1.440000 pts: 1.440000 pos: 39806 size: 3640 +ret: 0 st: 0 flags:1 dts: 1.440000 pts: 1.440000 pos: 39690 size: 3640 ret: 0 st:-1 flags:0 ts: 0.460008 -ret: 0 st: 0 flags:1 dts: 0.480000 pts: 0.480000 pos: 16134 size: 3244 +ret: 0 st: 0 flags:1 dts: 0.480000 pts: 0.480000 pos: 16074 size: 3245 ret:-1 st:-1 flags:1 ts:-0.645825 diff --git a/tests/ref/vsynth/vsynth1-jpeg2000-97 b/tests/ref/vsynth/vsynth1-jpeg2000-97 index 6ab5aa4237..c979ab5c36 100644 --- a/tests/ref/vsynth/vsynth1-jpeg2000-97 +++ b/tests/ref/vsynth/vsynth1-jpeg2000-97 @@ -1,4 +1,4 @@ -e4d03b2e3c03e56c7f831b1e662c4031 *tests/data/fate/vsynth1-jpeg2000-97.avi -3643928 tests/data/fate/vsynth1-jpeg2000-97.avi +5e6d32b7205d31245b0d1f015d08b515 *tests/data/fate/vsynth1-jpeg2000-97.avi +3643886 tests/data/fate/vsynth1-jpeg2000-97.avi a2262f1da2f49bc196b780a6b47ec4e8 *tests/data/fate/vsynth1-jpeg2000-97.out.rawvideo stddev: 4.23 PSNR: 35.59 MAXDIFF: 53 bytes: 7603200/ 7603200 diff --git a/tests/ref/vsynth/vsynth1-snow b/tests/ref/vsynth/vsynth1-snow index f20abd2ee4..b0e3a0bfd7 100644 --- a/tests/ref/vsynth/vsynth1-snow +++ b/tests/ref/vsynth/vsynth1-snow @@ -1,4 +1,4 @@ -67c10f8d52fcd1103caa675a1408bf6e *tests/data/fate/vsynth1-snow.avi -136088 tests/data/fate/vsynth1-snow.avi -bfc0bcc4bc7b956933aa58acc587018d *tests/data/fate/vsynth1-snow.out.rawvideo -stddev: 22.77 PSNR: 20.98 MAXDIFF: 175 bytes: 7603200/ 7603200 +c4c77a6fb926b89fe6591c398f5cd4db *tests/data/fate/vsynth1-snow.avi +136160 tests/data/fate/vsynth1-snow.avi +dcf8b3f62d9c3ae2b2d0fbbacbf83e4e *tests/data/fate/vsynth1-snow.out.rawvideo +stddev: 22.74 PSNR: 20.99 MAXDIFF: 173 bytes: 7603200/ 7603200 diff --git a/tests/ref/vsynth/vsynth1-snow-hpel b/tests/ref/vsynth/vsynth1-snow-hpel index 39780ad8a2..72b082b2ce 100644 --- a/tests/ref/vsynth/vsynth1-snow-hpel +++ b/tests/ref/vsynth/vsynth1-snow-hpel @@ -1,4 +1,4 @@ -e62ae25d5040d04622a965bcb27fdb1e *tests/data/fate/vsynth1-snow-hpel.avi -138446 tests/data/fate/vsynth1-snow-hpel.avi -57c914cd150f8fc260b5989ce3e5884c *tests/data/fate/vsynth1-snow-hpel.out.rawvideo -stddev: 22.74 PSNR: 20.99 MAXDIFF: 172 bytes: 7603200/ 7603200 +5c9eb93646eb0e5570d37e9adc9625e4 *tests/data/fate/vsynth1-snow-hpel.avi +138580 tests/data/fate/vsynth1-snow-hpel.avi +3382bdde624d8bb4af206a5ac6614605 *tests/data/fate/vsynth1-snow-hpel.out.rawvideo +stddev: 22.71 PSNR: 21.00 MAXDIFF: 171 bytes: 7603200/ 7603200 diff --git a/tests/ref/vsynth/vsynth2-jpeg2000 b/tests/ref/vsynth/vsynth2-jpeg2000 index d0df0099ea..b60307d5da 100644 --- a/tests/ref/vsynth/vsynth2-jpeg2000 +++ b/tests/ref/vsynth/vsynth2-jpeg2000 @@ -1,4 +1,4 @@ -8c8a68ca748190c71b3ea43e5ab7f502 *tests/data/fate/vsynth2-jpeg2000.avi -1538736 tests/data/fate/vsynth2-jpeg2000.avi +bfe90391779a02319aab98b06dd18e6c *tests/data/fate/vsynth2-jpeg2000.avi +1538724 tests/data/fate/vsynth2-jpeg2000.avi 64fadc87447268cf90503cb294db7f61 *tests/data/fate/vsynth2-jpeg2000.out.rawvideo stddev: 4.91 PSNR: 34.29 MAXDIFF: 55 bytes: 7603200/ 7603200 diff --git a/tests/ref/vsynth/vsynth2-jpeg2000-97 b/tests/ref/vsynth/vsynth2-jpeg2000-97 index 33c1fb2425..591f8b6bb3 100644 --- a/tests/ref/vsynth/vsynth2-jpeg2000-97 +++ b/tests/ref/vsynth/vsynth2-jpeg2000-97 @@ -1,4 +1,4 @@ -c8f76055f59804ca72dbd66eb4db83a2 *tests/data/fate/vsynth2-jpeg2000-97.avi -2464138 tests/data/fate/vsynth2-jpeg2000-97.avi +aa5573136c54b1855d8d00efe2a149bd *tests/data/fate/vsynth2-jpeg2000-97.avi +2464134 tests/data/fate/vsynth2-jpeg2000-97.avi 1f63c8b065e847e4c63d57ce23442ea8 *tests/data/fate/vsynth2-jpeg2000-97.out.rawvideo stddev: 3.21 PSNR: 37.99 MAXDIFF: 26 bytes: 7603200/ 7603200 diff --git a/tests/ref/vsynth/vsynth2-snow b/tests/ref/vsynth/vsynth2-snow index e9607bb7d0..355f89d5f4 100644 --- a/tests/ref/vsynth/vsynth2-snow +++ b/tests/ref/vsynth/vsynth2-snow @@ -1,4 +1,4 @@ -0a41e73ddd2f54936490655b46dad4a3 *tests/data/fate/vsynth2-snow.avi -72868 tests/data/fate/vsynth2-snow.avi -34a75f5cf8a71159f1a572d9cedcfef9 *tests/data/fate/vsynth2-snow.out.rawvideo -stddev: 13.73 PSNR: 25.37 MAXDIFF: 162 bytes: 7603200/ 7603200 +5e130d6a48b69348eee7f7c76c5869a3 *tests/data/fate/vsynth2-snow.avi +72942 tests/data/fate/vsynth2-snow.avi +9b6cee60e3ec0d1f312a8a25a7878fcc *tests/data/fate/vsynth2-snow.out.rawvideo +stddev: 13.39 PSNR: 25.59 MAXDIFF: 154 bytes: 7603200/ 7603200 diff --git a/tests/ref/vsynth/vsynth2-snow-hpel b/tests/ref/vsynth/vsynth2-snow-hpel index 66839fd6f6..ec3b5dfad2 100644 --- a/tests/ref/vsynth/vsynth2-snow-hpel +++ b/tests/ref/vsynth/vsynth2-snow-hpel @@ -1,4 +1,4 @@ -9bc409e4794ee50691a26c9c836d31a7 *tests/data/fate/vsynth2-snow-hpel.avi -79728 tests/data/fate/vsynth2-snow-hpel.avi -2cc64d8171175a1532fd7d3ed3011fbf *tests/data/fate/vsynth2-snow-hpel.out.rawvideo -stddev: 13.70 PSNR: 25.39 MAXDIFF: 162 bytes: 7603200/ 7603200 +8edcf0fd7f066972ff77d5b891ed6dde *tests/data/fate/vsynth2-snow-hpel.avi +79798 tests/data/fate/vsynth2-snow-hpel.avi +7e0f2a24feda6fb3e54b85511a28c45f *tests/data/fate/vsynth2-snow-hpel.out.rawvideo +stddev: 13.35 PSNR: 25.62 MAXDIFF: 157 bytes: 7603200/ 7603200 diff --git a/tests/ref/vsynth/vsynth3-jpeg2000 b/tests/ref/vsynth/vsynth3-jpeg2000 index ecc286b9a4..894dba27dc 100644 --- a/tests/ref/vsynth/vsynth3-jpeg2000 +++ b/tests/ref/vsynth/vsynth3-jpeg2000 @@ -1,4 +1,4 @@ -776bf3234cbf25002f129b89baab42ea *tests/data/fate/vsynth3-jpeg2000.avi -67400 tests/data/fate/vsynth3-jpeg2000.avi +1d039969504abdc143b410f99b5f9171 *tests/data/fate/vsynth3-jpeg2000.avi +67354 tests/data/fate/vsynth3-jpeg2000.avi 098f5980667e1fcd50452b1dc1a74f61 *tests/data/fate/vsynth3-jpeg2000.out.rawvideo stddev: 5.47 PSNR: 33.36 MAXDIFF: 48 bytes: 86700/ 86700 diff --git a/tests/ref/vsynth/vsynth3-jpeg2000-97 b/tests/ref/vsynth/vsynth3-jpeg2000-97 index df10f43270..5d9d083791 100644 --- a/tests/ref/vsynth/vsynth3-jpeg2000-97 +++ b/tests/ref/vsynth/vsynth3-jpeg2000-97 @@ -1,4 +1,4 @@ -cd023db503f03ef72dd83e4617a90c7b *tests/data/fate/vsynth3-jpeg2000-97.avi -85606 tests/data/fate/vsynth3-jpeg2000-97.avi +522e12684aca4262a9d613cb2db7006c *tests/data/fate/vsynth3-jpeg2000-97.avi +85526 tests/data/fate/vsynth3-jpeg2000-97.avi 8def36ad1413ab3a5c2af2e1af4603f9 *tests/data/fate/vsynth3-jpeg2000-97.out.rawvideo stddev: 4.51 PSNR: 35.04 MAXDIFF: 47 bytes: 86700/ 86700 diff --git a/tests/ref/vsynth/vsynth_lena-jpeg2000 b/tests/ref/vsynth/vsynth_lena-jpeg2000 index 88629add21..e2cbc899d3 100644 --- a/tests/ref/vsynth/vsynth_lena-jpeg2000 +++ b/tests/ref/vsynth/vsynth_lena-jpeg2000 @@ -1,4 +1,4 @@ -b8aaa45236f77a2a626791d462fd8ac1 *tests/data/fate/vsynth_lena-jpeg2000.avi -1188886 tests/data/fate/vsynth_lena-jpeg2000.avi +51f061731d7fb987ff4e71789785225e *tests/data/fate/vsynth_lena-jpeg2000.avi +1188882 tests/data/fate/vsynth_lena-jpeg2000.avi 39a2c5b61cd0cf2821c6fb4cceba2fa8 *tests/data/fate/vsynth_lena-jpeg2000.out.rawvideo stddev: 4.30 PSNR: 35.45 MAXDIFF: 45 bytes: 7603200/ 7603200 diff --git a/tests/ref/vsynth/vsynth_lena-jpeg2000-97 b/tests/ref/vsynth/vsynth_lena-jpeg2000-97 index b6f5f75f77..0539300185 100644 --- a/tests/ref/vsynth/vsynth_lena-jpeg2000-97 +++ b/tests/ref/vsynth/vsynth_lena-jpeg2000-97 @@ -1,4 +1,4 @@ -b2d9525433c6300674f504922d762437 *tests/data/fate/vsynth_lena-jpeg2000-97.avi -1937232 tests/data/fate/vsynth_lena-jpeg2000-97.avi +80fe872c8afaad914da6ef037957d93b *tests/data/fate/vsynth_lena-jpeg2000-97.avi +1937216 tests/data/fate/vsynth_lena-jpeg2000-97.avi 1b97333a8dc115a5ba609b0070d89d4d *tests/data/fate/vsynth_lena-jpeg2000-97.out.rawvideo stddev: 2.82 PSNR: 39.10 MAXDIFF: 24 bytes: 7603200/ 7603200 diff --git a/tests/ref/vsynth/vsynth_lena-snow b/tests/ref/vsynth/vsynth_lena-snow index ec29a78483..582c294531 100644 --- a/tests/ref/vsynth/vsynth_lena-snow +++ b/tests/ref/vsynth/vsynth_lena-snow @@ -1,4 +1,4 @@ -8e96f337e8f4ccac7d72ef517e1d2208 *tests/data/fate/vsynth_lena-snow.avi -57680 tests/data/fate/vsynth_lena-snow.avi -90963cfd2359d460001c94d94256dc2b *tests/data/fate/vsynth_lena-snow.out.rawvideo -stddev: 10.48 PSNR: 27.72 MAXDIFF: 119 bytes: 7603200/ 7603200 +bf2cf9cacc1d98388798be98872049ee *tests/data/fate/vsynth_lena-snow.avi +57604 tests/data/fate/vsynth_lena-snow.avi +707a42eb20195913be55ba8dfadf72fb *tests/data/fate/vsynth_lena-snow.out.rawvideo +stddev: 10.37 PSNR: 27.81 MAXDIFF: 120 bytes: 7603200/ 7603200 diff --git a/tests/ref/vsynth/vsynth_lena-snow-hpel b/tests/ref/vsynth/vsynth_lena-snow-hpel index 2d6edd8a79..67effebc8a 100644 --- a/tests/ref/vsynth/vsynth_lena-snow-hpel +++ b/tests/ref/vsynth/vsynth_lena-snow-hpel @@ -1,4 +1,4 @@ -56b14cb1cbb637536233982e87f7ac3e *tests/data/fate/vsynth_lena-snow-hpel.avi -61764 tests/data/fate/vsynth_lena-snow-hpel.avi -244b0266127fa354d8485234b2c388e4 *tests/data/fate/vsynth_lena-snow-hpel.out.rawvideo -stddev: 10.45 PSNR: 27.74 MAXDIFF: 119 bytes: 7603200/ 7603200 +c6ec87a11415a99b1a781f9f5bacb722 *tests/data/fate/vsynth_lena-snow-hpel.avi +61814 tests/data/fate/vsynth_lena-snow-hpel.avi +40f330397b7acf6bdbb3ec6d908be451 *tests/data/fate/vsynth_lena-snow-hpel.out.rawvideo +stddev: 10.34 PSNR: 27.83 MAXDIFF: 118 bytes: 7603200/ 7603200 diff --git a/tools/coverity.c b/tools/coverity.c index 19a132a976..541e108238 100644 --- a/tools/coverity.c +++ b/tools/coverity.c @@ -31,6 +31,17 @@ #define NULL (void *)0 +typedef long long int64_t; + +enum AVRounding { + AV_ROUND_ZERO = 0, + AV_ROUND_INF = 1, + AV_ROUND_DOWN = 2, + AV_ROUND_UP = 3, + AV_ROUND_NEAR_INF = 5, + AV_ROUND_PASS_MINMAX = 8192, +}; + // Based on https://scan.coverity.com/models void *av_malloc(size_t size) { int has_memory; @@ -77,3 +88,10 @@ void *av_free(void *ptr) { __coverity_mark_as_afm_freed__(ptr, "av_free"); } + +int64_t av_rescale_rnd(int64_t a, int64_t b, int64_t c, enum AVRounding rnd) { + __coverity_negative_sink__(b); + __coverity_negative_sink__(c); + + return (double)a * (double)b / (double)c; +} diff --git a/tools/cws2fws.c b/tools/cws2fws.c index 7046b69957..9ce321fe20 100644 --- a/tools/cws2fws.c +++ b/tools/cws2fws.c @@ -89,6 +89,12 @@ int main(int argc, char *argv[]) for (i = 0; i < comp_len - 8;) { int ret, len = read(fd_in, &buf_in, 1024); + if (len == -1) { + printf("read failure\n"); + inflateEnd(&zstream); + goto out; + } + dbgprintf("read %d bytes\n", len); last_out = zstream.total_out; diff --git a/tools/target_dec_fuzzer.c b/tools/target_dec_fuzzer.c index f5a969b603..43449ffb0e 100644 --- a/tools/target_dec_fuzzer.c +++ b/tools/target_dec_fuzzer.c @@ -163,6 +163,7 @@ int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) { case AV_CODEC_ID_G2M: maxpixels /= 1024; break; case AV_CODEC_ID_GDV: maxpixels /= 512; break; case AV_CODEC_ID_GIF: maxpixels /= 16; break; + case AV_CODEC_ID_H264: maxpixels /= 256; break; case AV_CODEC_ID_HAP: maxpixels /= 128; break; case AV_CODEC_ID_HEVC: maxpixels /= 16384; break; case AV_CODEC_ID_HNM4_VIDEO: maxpixels /= 128; break; @@ -171,6 +172,7 @@ int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) { case AV_CODEC_ID_INTERPLAY_ACM: maxsamples /= 16384; break; case AV_CODEC_ID_LAGARITH: maxpixels /= 1024; break; case AV_CODEC_ID_LSCR: maxpixels /= 16; break; + case AV_CODEC_ID_MMVIDEO: maxpixels /= 256; break; case AV_CODEC_ID_MOTIONPIXELS:maxpixels /= 256; break; case AV_CODEC_ID_MP4ALS: maxsamples /= 65536; break; case AV_CODEC_ID_MSA1: maxpixels /= 16384; break; @@ -182,6 +184,7 @@ int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) { case AV_CODEC_ID_APNG: maxpixels /= 128; break; case AV_CODEC_ID_QTRLE: maxpixels /= 16; break; case AV_CODEC_ID_RASC: maxpixels /= 16; break; + case AV_CODEC_ID_RTV1: maxpixels /= 16; break; case AV_CODEC_ID_SANM: maxpixels /= 16; break; case AV_CODEC_ID_SCPR: maxpixels /= 32; break; case AV_CODEC_ID_SCREENPRESSO:maxpixels /= 64; break; diff --git a/tools/target_dem_fuzzer.c b/tools/target_dem_fuzzer.c index af1840b359..3c03c8d17c 100644 --- a/tools/target_dem_fuzzer.c +++ b/tools/target_dem_fuzzer.c @@ -186,10 +186,7 @@ int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) { ret = avformat_open_input(&avfmt, filename, fmt, NULL); if (ret < 0) { - av_freep(&fuzzed_pb->buffer); - av_freep(&fuzzed_pb); - avformat_free_context(avfmt); - return 0; + goto fail; } ret = avformat_find_stream_info(avfmt, NULL); @@ -203,10 +200,12 @@ int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) { av_packet_unref(pkt); } +fail: av_packet_free(&pkt); av_freep(&fuzzed_pb->buffer); avio_context_free(&fuzzed_pb); avformat_close_input(&avfmt); return 0; + }