diff --git a/Changelog b/Changelog index 5d4828b6ff..f5c2e51db7 100644 --- a/Changelog +++ b/Changelog @@ -3,6 +3,299 @@ releases are sorted from youngest to oldest. version next: + +version 0.10.11 + +- pthread: Avoid spurious wakeups +- pthread: Fix deadlock during thread initialization +- mpegvideo: Initialize chroma_*_shift and codec_tag even if the size is 0 +- vc1dec: Don't decode slices when the latest slice header failed to decode +- vc1dec: Make sure last_picture is initialized in vc1_decode_skip_blocks +- r3d: Add more input value validation +- fraps: Make the input buffer size checks more strict +- svq3: Avoid a division by zero +- rmdec: Validate the fps value +- twinvqdec: Check the ibps parameter separately +- asfdec: Check the return value of asf_read_stream_properties +- mxfdec: set audio timebase to 1/samplerate +- pcx: Check the packet size before assuming it fits a palette +- rpza: Fix a buffer size check +- xxan: Disallow odd width +- xan: Only read within the data that actually was initialized +- xan: Use bytestream2 to limit reading to within the buffer +- pcx: Consume the whole packet if giving up due to missing palette +- pngdec: Stop trying to decode once inflate returns Z_STREAM_END +- mov: Make sure the read sample count is nonnegative +- bfi: Add some very basic sanity checks for input packet sizes +- bfi: Avoid divisions by zero +- electronicarts: Add more sanity checking for the number of channels +- riffdec: Add sanity checks for the sample rate +- mvi: Add sanity checking for the audio frame size +- xwma: Avoid division by zero +- avidec: Make sure a packet is large enough before reading its data +- vqf: Make sure the bitrate is in the valid range +- vqf: Make sure sample_rate is set to a valid value +- vc1dec: Undo mpegvideo initialization if unable to allocate tables +- vc1dec: Fix leaks in ff_vc1_decode_init_alloc_tables on errors +- wnv1: Make sure the input packet is large enough +- dca: Validate the lfe parameter +- rl2: Avoid a division by zero +- wtv: Add more sanity checks for a length read from the file +- segafilm: Validate the number of audio channels +- qpeg: Add checks for running out of rows in qpeg_decode_inter +- mpegaudiodec: Validate that the number of channels fits at the given offset +- asv1: Verify the amount of extradata +- idroqdec: Make sure a video stream has been allocated before returning packets +- rv10: Validate the dimensions set from the container +- xmv: Add more sanity checks for parameters read from the bitstream +- ffv1: Make sure at least one slice context is initialized +- truemotion2: Use av_freep properly in an error path +- eacmv: Make sure a reference frame exists before referencing it +- mpeg4videodec: Check the width/height in mpeg4_decode_sprite_trajectory +- ivi_common: Make sure color planes have been initialized +- oggparseogm: Convert to use bytestream2 +- rv34: Check the return value from ff_rv34_decode_init +- matroskadec: Verify realaudio codec parameters +- mace: Make sure that the channel count is set to a valid value +- svq3: Check for any negative return value from ff_h264_check_intra_pred_mode +- vp3: Check the framerate for validity +- cavsdec: Make sure a sequence header has been decoded before decoding pictures +- sierravmd: Do sanity checking of frame sizes +- omadec: Properly check lengths before incrementing the position +- mpc8: Make sure the first stream exists before parsing the seek table +- mpc8: Check the seek table size parsed from the bitstream +- zmbvdec: Check the buffer size for uncompressed data +- ape: Don't allow the seektable to be omitted +- shorten: Break out of loop looking for fmt chunk if none is found +- shorten: Use a checked bytestream reader for the wave header +- smacker: Make sure we don't fill in huffman codes out of range +- smacker: Avoid integer overflow when allocating packets +- smacker: Don't return packets in unallocated streams +- dsicin: Add some basic sanity checks for fields read from the file +- roqvideodec: check dimensions validity +- qdm2: check array index before use, fix out of array accesses +- alsdec: check block length + + +version 0.10.10 + +- x86: fft: Remove 3DNow! optimizations, they break FATE +- x86: ac3dsp: Drop mmx variant of ac3_max_msb_abs_int16 +- aac: Check init_get_bits return value +- aac: return meaningful errors +- dsicinav: K&R formatting cosmetics +- mov: Seek back if overreading an individual atom +- vcr1: add sanity checks +- pictordec: pass correct context to avpriv_request_sample +- dsicinav: Clip the source size to the expected maximum +- alsdec: Clean up error paths +- ogg: Fix potential infinite discard loop +- nuv: check rtjpeg_decode_frame_yuv420 return value +- nuv: Reset the frame on resize +- nuv: Use av_fast_realloc +- nuv: return meaningful error codes. +- nuv: Pad the lzo outbuf +- nuv: Do not ignore lzo decompression failures +- oma: correctly mark and decrypt partial packets +- oma: check geob tag boundary +- oma: refactor seek function +- 8bps: Bound-check the input buffer +- rtmp: Do not misuse memcmp +- rtmp: rename data_size to size +- lavc: set the default rc_initial_buffer_occupancy +- 4xm: Reject not a multiple of 16 dimension +- 4xm: do not overread the prestream buffer +- 4xm: validate the buffer size before parsing it +- indeo: Do not reference mismatched tiles +- indeo: Sanitize ff_ivi_init_planes fail paths +- indeo: Bound-check before applying motion compensation +- indeo: Bound-check before applying transform +- indeo: reject negative array indexes +- indeo: Cosmetic formatting +- indeo: Refactor ff_ivi_init_tiles and ivi_decode_blocks +- indeo: Refactor ff_ivi_dec_huff_desc +- lavf: fix the comparison in an overflow check +- dv: Add a guard to not overread the ppcm array +- mpegvideo: Avoid 32-bit wrapping of linesize multiplications +- mjpegb: Detect changing number of planes in interlaced video +- matroskadec: Check that .lang was allocated and set before reading it +- ape demuxer: check for EOF in potentially long loops +- lavf: avoid integer overflow when estimating bitrate +- pictordec: break out of both decoding loops when y drops below 0 +- ac3: Return proper error codes +- ac3: Clean up the error paths +- ac3: Do not clash with normal AVERROR +- dxa: Make sure the reference frame exists +- h261: check the mtype index +- segafilm: Error out on impossible packet size +- ogg: Always alloc the private context in vorbis_header +- vc1: check mb_height validity. +- vc1: check the source buffer in vc1_mc functions +- bink: Bound check the quantization matrix. +- xl: Make sure the width is valid +- alsdec: Fix the clipping range +- dsicinav: Bound-check the source buffer when needed +- mov: Do not allow updating the time scale after it has been set +- ac3dec: Don't consume more data than the actual input packet size +- indeo: Reject impossible FRAMETYPE_NULL +- indeo5: return proper error codes +- indeo4: Validate scantable dimension +- indeo4: Check the quantization matrix index +- indeo4: Do not access missing reference MV +- adpcm: Unbreak ima-dk4 +- ac3dec: validate channel output mode against channel count +- dca: Respect the current limits in the downmixing capabilities +- dca: Error out on missing DSYNC +- pcm: always use codec->id instead of codec_id +- mlpdec: Do not set invalid context in read_restart_header +- pcx: Do not overread source buffer in pcx_rle_decode +- wmavoice: conceal clearly corrupted blocks +- iff: Do not read over the source buffer +- qdm2: Conceal broken samples +- qdm2: refactor joined stereo support +- adpcm: Write the correct number of samples for ima-dk4 +- imc: Catch a division by zero +- atrac3: Error on impossible encoding/channel combinations +- atrac3: set the getbits context the right buffer_end +- atrac3: fix error handling +- qdm2: check and reset dithering index per channel +- westwood_vqa: do not free extradata on error in read_header +- vqavideo: check the version +- rmdec: Use the AVIOContext given as parameter in rm_read_metadata() +- avio: Handle AVERROR_EOF in the same way as the return value 0 +- wtv: Mark attachment with a negative stream id +- avidec: Let the inner dv demuxer take care of discarding +- swfdec: do better validation of tag length + + +version 0.10.8 +- kmvc: Clip pixel position to valid range +- kmvc: use fixed sized arrays in the context +- indeo: use a typedef for the mc function pointer +- lavc: check for overflow in init_get_bits +- mjpegdec: properly report unsupported disabled features +- jpegls: return meaningful errors +- jpegls: factorize return paths +- jpegls: check the scan offset +- wavpack: validate samples size parsed in wavpack_decode_block +- ljpeg: use the correct number of components in yuv +- mjpeg: Validate sampling factors +- mjpegdec: validate parameters in mjpeg_decode_scan_progressive_ac +- wavpack: check packet size early +- wavpack: return meaningful errors +- apetag: use int64_t for filesize +- tiff: do not overread the source buffer +- Prepare for 0.8.8 Release +- smacker: fix an off by one in huff.length computation +- smacker: check the return value of smacker_decode_tree +- smacker: pad the extradata allocation +- smacker: check frame size validity +- vmdav: convert to bytestream2 +- 4xm: don't rely on get_buffer() initializing the frame. +- 4xm: check the return value of read_huffman_tables(). +- 4xm: use the correct logging context +- 4xm: reject frames not compatible with the declared version +- 4xm: check bitstream_size boundary before using it +- 4xm: do not overread the source buffer in decode_p_block +- avfiltergraph: check for sws opts being non-NULL before using them +- bmv: check for len being valid in bmv_decode_frame() +- dfa: check for invalid access in decode_wdlt() +- indeo3: check motion vectors +- indeo3: fix data size check +- indeo3: switch parsing the header to bytestream2 +- lavf: make sure stream probe data gets freed. +- oggdec: fix faulty cleanup prototype +- oma: Validate sample rates +- qdm2: check that the FFT size is a power of 2 +- rv10: check that extradata is large enough +- xmv: check audio track parameters validity +- xmv: do not leak memory in the error paths in xmv_read_header() +- aac: check the maximum number of channels +- indeo3: fix off by one in MV validity check, Bug #503 +- id3v2: check for end of file while unescaping tags +- wav: Always seek to an even offset, Bug #500, LP: #1174737 +- proresdec: support mixed interlaced/non-interlaced content + + +version 0.10.6: + +- many bug fixes that where found with Coverity + +- The following CVE fixes where backported: + CVE-2012-2796, CVE-2012-2775, CVE-2012-2772, CVE-2012-2776, + CVE-2012-2779, CVE-2012-2787, CVE-2012-2794, CVE-2012-2800, + CVE-2012-2802, CVE-2012-2801, CVE-2012-2786, CVE-2012-2798, + CVE-2012-2793, CVE-2012-2789, CVE-2012-2788, CVE-2012-2790, + CVE-2012-2777, CVE-2012-2784 + +- hundreads of other bug fixes, some possibly security relevant, + see the git log for details. + + +version 0.10.5: + +- Several bugs and crashes have been fixed as well as build problems + with recent mingw64 + + +version 0.10.4: + +- Several bugs and crashes have been fixed + Note, CVE-2012-0851 and CVE-2011-3937 have been fixed in previous releases + +version 0.10.3: + +- Security fixes in the 4xm demuxer, avi demuxer, cook decoder, + mm demuxer, mpegvideo decoder, vqavideo decoder (CVE-2012-0947) and + xmv demuxer. + +- Several bugs and crashes have been fixed in the following codecs: AAC, + APE, H.263, H.264, Indeo 4, Mimic, MJPEG, Motion Pixels Video, RAW, + TTA, VC1, VQA, WMA Voice, vqavideo. + +- Several bugs and crashes have been fixed in the following formats: + ASF, ID3v2, MOV, xWMA + +- This release additionally updates the following codecs to the + bytestream2 API, and therefore benefit from additional overflow + checks: truemotion2, utvideo, vqavideo + + +version 0.10.1 +- Several security fixes, many bugfixes affecting many formats and + codecs, the list below is not complete. + +- swapuv filter + +- Several bugs and crashes have been fixed in the following codecs: AAC, + AC-3, ADPCM, AMR (both NB and WB), ATRAC3, CAVC, Cook, camstudio, DCA, + DPCM, DSI CIN, DV, EA TGQ, FLAC, fraps, G.722 (both encoder and + decoder), H.264, huvffyuv, BB JV decoder, Indeo 3, KGV1, LCL, the + libx264 wrapper, MJPEG, mp3on4, Musepack, MPEG1/2, PNG, QDM2, Qt RLE, + ROQ, RV10, RV30/RV34/RV40, shorten, smacker, subrip, SVQ3, TIFF, + Truemotion2, TTA, VC1, VMware Screen codec, Vorbis, VP5, VP6, WMA, + Westwood SNDx, XXAN. + +- This release additionally updates the following codecs to the + bytestream2 API, and therefore benefit from additional overflow + checks: XXAN, ALG MM, TQG, SMC, Qt SMC, ROQ, PNG + +- Several bugs and crashes have been fixed in the following formats: + AIFF, ASF, DV, Matroska, NSV, MOV, MPEG-TS, Smacker, Sony OpenMG, RM, + SWF. + +- Libswscale has an potential overflow for large image size fixed. + +- The following APIs have been added: + + avcodec_is_open() + avformat_get_riff_video_tags() + avformat_get_riff_audio_tags() + + Please see the file doc/APIchanges and the Doxygen documentation for + further information. + + version 0.10: - Fixes: CVE-2011-3929, CVE-2011-3934, CVE-2011-3935, CVE-2011-3936, CVE-2011-3937, CVE-2011-3940, CVE-2011-3941, CVE-2011-3944, diff --git a/Doxyfile b/Doxyfile index 97896aa071..712e9ddcda 100644 --- a/Doxyfile +++ b/Doxyfile @@ -31,7 +31,7 @@ PROJECT_NAME = FFmpeg # This could be handy for archiving the generated documentation or # if some version control system is used. -PROJECT_NUMBER = +PROJECT_NUMBER = 0.10.16 # With the PROJECT_LOGO tag one can specify an logo or icon that is included # in the documentation. The maximum height of the logo should not exceed 55 diff --git a/MAINTAINERS b/MAINTAINERS index 7a04209493..c3187d13c5 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -14,7 +14,6 @@ and related discussions. Project Leader ============== -Michael Niedermayer final design decisions diff --git a/Makefile b/Makefile index 2253ef1852..fe4db6f2d7 100644 --- a/Makefile +++ b/Makefile @@ -137,7 +137,6 @@ uninstall-data: clean:: $(RM) $(ALLPROGS) $(ALLPROGS_G) $(RM) $(CLEANSUFFIXES) - $(RM) $(TOOLS) $(RM) $(CLEANSUFFIXES:%=tools/%) $(RM) coverage.info $(RM) -r coverage-html @@ -158,6 +157,8 @@ coverage-html: coverage.info $(Q)genhtml -o $@ $< $(Q)touch $@ +check: all alltools checkheaders examples testprogs fate + include $(SRC_PATH)/doc/Makefile include $(SRC_PATH)/tests/Makefile @@ -172,5 +173,5 @@ $(sort $(OBJDIRS)): # so this saves some time on slow systems. .SUFFIXES: -.PHONY: all all-yes alltools *clean config examples install* +.PHONY: all all-yes alltools check *clean config examples install* .PHONY: testprogs uninstall* diff --git a/RELEASE b/RELEASE index 4fda45b376..55a6d615b6 100644 --- a/RELEASE +++ b/RELEASE @@ -1 +1 @@ -0.9.1.git +0.10.16 diff --git a/VERSION b/VERSION new file mode 100644 index 0000000000..55a6d615b6 --- /dev/null +++ b/VERSION @@ -0,0 +1 @@ +0.10.16 diff --git a/cmdutils.c b/cmdutils.c index 386db3d48b..c76ae518f0 100644 --- a/cmdutils.c +++ b/cmdutils.c @@ -56,7 +56,7 @@ struct SwsContext *sws_opts; AVDictionary *format_opts, *codec_opts; -const int this_year = 2012; +const int this_year = 2015; static FILE *report_file; @@ -423,7 +423,10 @@ int opt_default(const char *opt, const char *arg) const AVOption *oc, *of, *os; char opt_stripped[128]; const char *p; - const AVClass *cc = avcodec_get_class(), *fc = avformat_get_class(), *sc; + const AVClass *cc = avcodec_get_class(), *fc = avformat_get_class(); +#if CONFIG_SWSCALE + const AVClass *sc = sws_get_class(); +#endif if (!(p = strchr(opt, ':'))) p = opt + strlen(opt); @@ -438,7 +441,6 @@ int opt_default(const char *opt, const char *arg) AV_OPT_SEARCH_CHILDREN | AV_OPT_SEARCH_FAKE_OBJ))) av_dict_set(&format_opts, opt, arg, FLAGS(of)); #if CONFIG_SWSCALE - sc = sws_get_class(); if ((os = av_opt_find(&sc, opt, NULL, 0, AV_OPT_SEARCH_CHILDREN | AV_OPT_SEARCH_FAKE_OBJ))) { // XXX we only support sws_flags, not arbitrary sws options @@ -806,7 +808,7 @@ int opt_codecs(const char *opt, const char *arg) if (p2 && strcmp(p->name, p2->name) == 0) { if (p->decode) decode = 1; - if (p->encode) + if (p->encode || p->encode2) encode = 1; cap |= p->capabilities; } diff --git a/common.mak b/common.mak index b7786c5c67..c21bff3d1c 100644 --- a/common.mak +++ b/common.mak @@ -117,4 +117,13 @@ CLEANSUFFIXES = *.d *.o *~ *.ho *.map *.ver *.gcno *.gcda DISTCLEANSUFFIXES = *.pc LIBSUFFIXES = *.a *.lib *.so *.so.* *.dylib *.dll *.def *.dll.a *.exp +define RULES +clean:: + $(RM) $(OBJS) $(OBJS:.o=.d) + $(RM) $(HOSTPROGS) + $(RM) $(TOOLS) +endef + +$(eval $(RULES)) + -include $(wildcard $(OBJS:.o=.d) $(TESTOBJS:.o=.d)) diff --git a/configure b/configure index 07d473e861..520631f36e 100755 --- a/configure +++ b/configure @@ -54,6 +54,8 @@ if test "$E1" != 0 || test "$E2" = 0; then exit 1 fi +test -d /usr/xpg4/bin && PATH=/usr/xpg4/bin:$PATH + show_help(){ cat <" +} + check_cppflags(){ log check_cppflags "$@" set -- $($filter_cppflags "$@") @@ -765,7 +774,7 @@ check_func_headers(){ shift 2 { for hdr in $headers; do - echo "#include <$hdr>" + print_include $hdr done for func in $funcs; do echo "long check_$func(void) { return (long) $func; }" @@ -1168,6 +1177,7 @@ HAVE_LIST=" dlfcn_h dlopen dos_paths + dxva_h ebp_available ebx_available exp2 @@ -2559,7 +2569,7 @@ check_host_cflags -std=c99 check_host_cflags -Wall case "$arch" in - alpha|ia64|mips|parisc|sparc) + alpha|ia64|mips|parisc|ppc|sparc) spic=$shared ;; x86) @@ -2899,17 +2909,14 @@ elif enabled ppc; then check_cc <= 3.98.3" lame/lame.h lame_set_VBR_quality -lmp3lame @@ -3201,7 +3210,14 @@ makeinfo --version > /dev/null 2>&1 && enable makeinfo || disable makeinfo check_header linux/fb.h check_header linux/videodev.h check_header linux/videodev2.h -check_struct linux/videodev2.h "struct v4l2_frmivalenum" discrete +check_cc < +int main(void) { +struct v4l2_frmsizeenum vfse; +vfse.discrete.width = 0; +return 0; +} +EOF check_header sys/videoio.h @@ -3354,11 +3370,15 @@ elif enabled gcc; then check_cflags -fno-tree-vectorize check_cflags -Werror=implicit-function-declaration check_cflags -Werror=missing-prototypes + check_cflags -Werror=return-type elif enabled llvm_gcc; then check_cflags -mllvm -stack-alignment=16 elif enabled clang; then check_cflags -mllvm -stack-alignment=16 check_cflags -Qunused-arguments + check_cflags -Werror=return-type + check_cflags -Werror=implicit-function-declaration + check_cflags -Werror=missing-prototypes elif enabled armcc; then # 2523: use of inline assembler is deprecated add_cflags -W${armcc_opt},--diag_suppress=2523 diff --git a/doc/APIchanges b/doc/APIchanges index 2a39f6b094..b35a65821b 100644 --- a/doc/APIchanges +++ b/doc/APIchanges @@ -13,24 +13,40 @@ libavutil: 2011-04-18 API changes, most recent first: +2014-09-16 - 8637f4e - lavu 51.22.3 - cpu.h + Add AV_CPU_FLAG_CMOV. + 2012-01-24 - xxxxxxx - lavfi 2.60.100 Add avfilter_graph_dump. -2012-01-25 - lavf 53.22.0 - f1caf01 Allow doing av_write_frame(ctx, NULL) for flushing possible +2012-01-25 - lavf 53.31.100 / 53.22.0 + 3c5fe5b / f1caf01 Allow doing av_write_frame(ctx, NULL) for flushing possible buffered data within a muxer. Added AVFMT_ALLOW_FLUSH for muxers supporting it (av_write_frame makes sure it is called only for muxers with this flag). -2012-01-15 - lavc 53.34.0 +2012-03-04 - 7f3f855 - lavu 51.22.1 - error.h + Add AVERROR_UNKNOWN + +2012-02-29 - 2ad77c6 - lavf 53.21.1 + Add avformat_get_riff_video_tags() and avformat_get_riff_audio_tags(). + +2012-02-29 - a1556d3 - lavu 51.22.0 - intfloat.h + Add a new installed header libavutil/intfloat.h with int/float punning + functions. + +2012-02-17 - 350d06d - lavc 53.35.0 + Add avcodec_is_open() function. + +2012-01-15 - lavc 53.56.105 / 53.34.0 New audio encoding API: - b2c75b6 Add CODEC_CAP_VARIABLE_FRAME_SIZE capability for use by audio + 67f5650 / b2c75b6 Add CODEC_CAP_VARIABLE_FRAME_SIZE capability for use by audio encoders. - 5ee5fa0 Add avcodec_fill_audio_frame() as a convenience function. - b2c75b6 Add avcodec_encode_audio2() and deprecate avcodec_encode_audio(). + 67f5650 / 5ee5fa0 Add avcodec_fill_audio_frame() as a convenience function. + 67f5650 / b2c75b6 Add avcodec_encode_audio2() and deprecate avcodec_encode_audio(). Add AVCodec.encode2(). -2012-01-12 - 3167dc9 - lavfi 2.15.0 +2012-01-12 - b18e17e / 3167dc9 - lavfi 2.59.100 / 2.15.0 Add a new installed header -- libavfilter/version.h -- with version macros. 2011-12-08 - a502939 - lavfi 2.52.0 @@ -51,37 +67,37 @@ API changes, most recent first: 2011-10-20 - b35e9e1 - lavu 51.22.0 Add av_strtok() to avstring.h. -2011-01-03 - b73ec05 - lavu 51.21.0 +2012-01-03 - ad1c8dd / b73ec05 - lavu 51.34.100 / 51.21.0 Add av_popcount64 -2011-12-18 - 8400b12 - lavc 53.28.1 +2011-12-18 - 7c29313 / 8400b12 - lavc 53.46.1 / 53.28.1 Deprecate AVFrame.age. The field is unused. -2011-12-12 - 5266045 - lavf 53.17.0 +2011-12-12 - 8bc7fe4 / 5266045 - lavf 53.25.0 / 53.17.0 Add avformat_close_input(). Deprecate av_close_input_file() and av_close_input_stream(). -2011-12-02 - 0eea212 - lavc 53.25.0 +2011-12-02 - e4de716 / 0eea212 - lavc 53.40.0 / 53.25.0 Add nb_samples and extended_data fields to AVFrame. Deprecate AVCODEC_MAX_AUDIO_FRAME_SIZE. Deprecate avcodec_decode_audio3() in favor of avcodec_decode_audio4(). avcodec_decode_audio4() writes output samples to an AVFrame, which allows audio decoders to use get_buffer(). -2011-12-04 - 560f773 - lavc 53.24.0 +2011-12-04 - e4de716 / 560f773 - lavc 53.40.0 / 53.24.0 Change AVFrame.data[4]/base[4]/linesize[4]/error[4] to [8] at next major bump. Change AVPicture.data[4]/linesize[4] to [8] at next major bump. Change AVCodecContext.error[4] to [8] at next major bump. Add AV_NUM_DATA_POINTERS to simplify the bump transition. -2011-11-23 - bbb46f3 - lavu 51.18.0 +2011-11-23 - 8e576d5 / bbb46f3 - lavu 51.27.0 / 51.18.0 Add av_samples_get_buffer_size(), av_samples_fill_arrays(), and av_samples_alloc(), to samplefmt.h. -2011-11-23 - 8889cc4 - lavu 51.17.0 +2011-11-23 - 8e576d5 / 8889cc4 - lavu 51.27.0 / 51.17.0 Add planar sample formats and av_sample_fmt_is_planar() to samplefmt.h. -2011-11-19 - f3a29b7 - lavc 53.21.0 +2011-11-19 - dbb38bc / f3a29b7 - lavc 53.36.0 / 53.21.0 Move some AVCodecContext fields to a new private struct, AVCodecInternal, which is accessed from a new field, AVCodecContext.internal. - fields moved: @@ -89,55 +105,55 @@ API changes, most recent first: AVCodecContext.internal_buffer_count --> AVCodecInternal.buffer_count AVCodecContext.is_copy --> AVCodecInternal.is_copy -2011-11-16 - 6270671 - lavu 51.16.0 +2011-11-16 - 8709ba9 / 6270671 - lavu 51.26.0 / 51.16.0 Add av_timegm() -2011-11-13 - lavf 53.15.0 +2011-11-13 - lavf 53.21.0 / 53.15.0 New interrupt callback API, allowing per-AVFormatContext/AVIOContext interrupt callbacks. - 6aa0b98 Add AVIOInterruptCB struct and the interrupt_callback field to + 5f268ca / 6aa0b98 Add AVIOInterruptCB struct and the interrupt_callback field to AVFormatContext. - 1dee0ac Add avio_open2() with additional parameters. Those are + 5f268ca / 1dee0ac Add avio_open2() with additional parameters. Those are an interrupt callback and an options AVDictionary. This will allow passing AVOptions to protocols after lavf 54.0. -2011-11-06 - ba04ecf - lavu 51.14.0 +2011-11-06 - 13b7781 / ba04ecf - lavu 51.24.0 / 51.14.0 Add av_strcasecmp() and av_strncasecmp() to avstring.h. -2011-11-06 - 07b172f - lavu 51.13.0 +2011-11-06 - 13b7781 / 07b172f - lavu 51.24.0 / 51.13.0 Add av_toupper()/av_tolower() -2011-11-05 - b6d08f4 - lavf 53.13.0 +2011-11-05 - d8cab5c / b6d08f4 - lavf 53.19.0 / 53.13.0 Add avformat_network_init()/avformat_network_uninit() -2011-10-27 - 512557b - lavc 53.15.0 +2011-10-27 - 6faf0a2 / 512557b - lavc 53.24.0 / 53.15.0 Remove avcodec_parse_frame. Deprecate AVCodecContext.parse_only and CODEC_CAP_PARSE_ONLY. -2011-10-19 - 569129a - lavf 53.10.0 +2011-10-19 - d049257 / 569129a - lavf 53.17.0 / 53.10.0 Add avformat_new_stream(). Deprecate av_new_stream(). -2011-10-13 - b631fba - lavf 53.9.0 +2011-10-13 - 91eb1b1 / b631fba - lavf 53.16.0 / 53.9.0 Add AVFMT_NO_BYTE_SEEK AVInputFormat flag. -2011-10-12 - lavu 51.12.0 +2011-10-12 - lavu 51.21.0 / 51.12.0 AVOptions API rewrite. - - 145f741 FF_OPT_TYPE* renamed to AV_OPT_TYPE_* + - f884ef0 / 145f741 FF_OPT_TYPE* renamed to AV_OPT_TYPE_* - new setting/getting functions with slightly different semantics: - dac66da av_set_string3 -> av_opt_set + f884ef0 / dac66da av_set_string3 -> av_opt_set av_set_double -> av_opt_set_double av_set_q -> av_opt_set_q av_set_int -> av_opt_set_int - 41d9d51 av_get_string -> av_opt_get + f884ef0 / 41d9d51 av_get_string -> av_opt_get av_get_double -> av_opt_get_double av_get_q -> av_opt_get_q av_get_int -> av_opt_get_int - - 8c5dcaa trivial rename av_next_option -> av_opt_next - - 641c7af new functions - av_opt_child_next, av_opt_child_class_next + - f884ef0 / 8c5dcaa trivial rename av_next_option -> av_opt_next + - f884ef0 / 641c7af new functions - av_opt_child_next, av_opt_child_class_next and av_opt_find2() 2011-09-22 - a70e787 - lavu 51.17.0 @@ -183,31 +199,31 @@ API changes, most recent first: 2011-08-20 - 69e2c1a - lavu 51.13.0 Add av_get_media_type_string(). -2011-09-03 - fb4ca26 - lavc 53.13.0 +2011-09-03 - 1889c67 / fb4ca26 - lavc 53.13.0 lavf 53.11.0 lsws 2.1.0 Add {avcodec,avformat,sws}_get_class(). -2011-08-03 - c11fb82 - lavu 51.15.0 +2011-08-03 - 1889c67 / c11fb82 - lavu 51.15.0 Add AV_OPT_SEARCH_FAKE_OBJ flag for av_opt_find() function. 2011-08-14 - 323b930 - lavu 51.12.0 Add av_fifo_peek2(), deprecate av_fifo_peek(). -2011-08-26 - lavu 51.9.0 - - add41de..abc78a5 Do not include intfloat_readwrite.h, +2011-08-26 - lavu 51.14.0 / 51.9.0 + - 976a8b2 / add41de..976a8b2 / abc78a5 Do not include intfloat_readwrite.h, mathematics.h, rational.h, pixfmt.h, or log.h from avutil.h. -2011-08-16 - 48f9e45 - lavf 53.8.0 +2011-08-16 - 27fbe31 / 48f9e45 - lavf 53.11.0 / 53.8.0 Add avformat_query_codec(). -2011-08-16 - bca06e7 - lavc 53.11.0 +2011-08-16 - 27fbe31 / bca06e7 - lavc 53.11.0 Add avcodec_get_type(). -2011-08-06 - 2f63440 - lavf 53.7.0 +2011-08-06 - 0cb233c / 2f63440 - lavf 53.7.0 Add error_recognition to AVFormatContext. -2011-08-02 - 9d39cbf - lavc 53.9.1 +2011-08-02 - 1d186e9 / 9d39cbf - lavc 53.9.1 Add AV_PKT_FLAG_CORRUPT AVPacket flag. 2011-07-16 - b57df29 - lavfi 2.27.0 @@ -218,10 +234,10 @@ API changes, most recent first: avfilter_set_common_packing_formats() avfilter_all_packing_formats() -2011-07-10 - a67c061 - lavf 53.6.0 +2011-07-10 - 3602ad7 / a67c061 - lavf 53.6.0 Add avformat_find_stream_info(), deprecate av_find_stream_info(). -2011-07-10 - 0b950fe - lavc 53.8.0 +2011-07-10 - 3602ad7 / 0b950fe - lavc 53.8.0 Add avcodec_open2(), deprecate avcodec_open(). 2011-07-01 - b442ca6 - lavf 53.5.0 - avformat.h @@ -260,35 +276,35 @@ API changes, most recent first: 2011-06-12 - 6119b23 - lavfi 2.16.0 - avfilter_graph_parse() Change avfilter_graph_parse() signature. -2011-06-23 - 67e9ae1 - lavu 51.8.0 - attributes.h +2011-06-23 - 686959e / 67e9ae1 - lavu 51.10.0 / 51.8.0 - attributes.h Add av_printf_format(). -2011-06-16 - 05e84c9, 25de595 - lavf 53.2.0 - avformat.h +2011-06-16 - 2905e3f / 05e84c9, 2905e3f / 25de595 - lavf 53.4.0 / 53.2.0 - avformat.h Add avformat_open_input and avformat_write_header(). Deprecate av_open_input_stream, av_open_input_file, AVFormatParameters and av_write_header. -2011-06-16 - 7e83e1c, dc59ec5 - lavu 51.7.0 - opt.h +2011-06-16 - 2905e3f / 7e83e1c, 2905e3f / dc59ec5 - lavu 51.9.0 / 51.7.0 - opt.h Add av_opt_set_dict() and av_opt_find(). Deprecate av_find_opt(). Add AV_DICT_APPEND flag. -2011-06-10 - cb7c11c - lavu 51.6.0 - opt.h +2011-06-10 - 45fb647 / cb7c11c - lavu 51.6.0 - opt.h Add av_opt_flag_is_set(). 2011-06-10 - c381960 - lavfi 2.15.0 - avfilter_get_audio_buffer_ref_from_arrays Add avfilter_get_audio_buffer_ref_from_arrays() to avfilter.h. -2011-06-09 - d9f80ea - lavu 51.8.0 - AVMetadata +2011-06-09 - f9ecb84 / d9f80ea - lavu 51.8.0 - AVMetadata Move AVMetadata from lavf to lavu and rename it to AVDictionary -- new installed header dict.h. All av_metadata_* functions renamed to av_dict_*. -2011-06-07 - a6703fa - lavu 51.8.0 - av_get_bytes_per_sample() +2011-06-07 - d552f61 / a6703fa - lavu 51.8.0 - av_get_bytes_per_sample() Add av_get_bytes_per_sample() in libavutil/samplefmt.h. Deprecate av_get_bits_per_sample_fmt(). -2011-06-05 - b39b062 - lavu 51.8.0 - opt.h +2011-06-05 - f956924 / b39b062 - lavu 51.8.0 - opt.h Add av_opt_free convenience function. 2011-06-06 - 95a0242 - lavfi 2.14.0 - AVFilterBufferRefAudioProps @@ -318,7 +334,7 @@ API changes, most recent first: Add av_get_pix_fmt_name() in libavutil/pixdesc.h, and deprecate avcodec_get_pix_fmt_name() in libavcodec/avcodec.h in its favor. -2011-05-25 - 30315a8 - lavf 53.3.0 - avformat.h +2011-05-25 - 39e4206 / 30315a8 - lavf 53.3.0 - avformat.h Add fps_probe_size to AVFormatContext. 2011-05-22 - 5ecdfd0 - lavf 53.2.0 - avformat.h @@ -334,10 +350,10 @@ API changes, most recent first: 2011-05-14 - 9fdf772 - lavfi 2.6.0 - avcodec.h Add avfilter_get_video_buffer_ref_from_frame() to libavfilter/avcodec.h. -2011-05-18 - 64150ff - lavc 53.7.0 - AVCodecContext.request_sample_fmt +2011-05-18 - 75a37b5 / 64150ff - lavc 53.7.0 - AVCodecContext.request_sample_fmt Add request_sample_fmt field to AVCodecContext. -2011-05-10 - 188dea1 - lavc 53.6.0 - avcodec.h +2011-05-10 - 59eb12f / 188dea1 - lavc 53.6.0 - avcodec.h Deprecate AVLPCType and the following fields in AVCodecContext: lpc_coeff_precision, prediction_order_method, min_partition_order, max_partition_order, lpc_type, lpc_passes. @@ -367,81 +383,81 @@ API changes, most recent first: Add av_dynarray_add function for adding an element to a dynamic array. -2011-04-26 - bebe72f - lavu 51.1.0 - avutil.h +2011-04-26 - d7e5aeb / bebe72f - lavu 51.1.0 - avutil.h Add AVPictureType enum and av_get_picture_type_char(), deprecate FF_*_TYPE defines and av_get_pict_type_char() defined in libavcodec/avcodec.h. -2011-04-26 - 10d3940 - lavfi 2.3.0 - avfilter.h +2011-04-26 - d7e5aeb / 10d3940 - lavfi 2.3.0 - avfilter.h Add pict_type and key_frame fields to AVFilterBufferRefVideo. -2011-04-26 - 7a11c82 - lavfi 2.2.0 - vsrc_buffer +2011-04-26 - d7e5aeb / 7a11c82 - lavfi 2.2.0 - vsrc_buffer Add sample_aspect_ratio fields to vsrc_buffer arguments -2011-04-21 - 94f7451 - lavc 53.1.0 - avcodec.h +2011-04-21 - 8772156 / 94f7451 - lavc 53.1.0 - avcodec.h Add CODEC_CAP_SLICE_THREADS for codecs supporting sliced threading. 2011-04-15 - lavc 52.120.0 - avcodec.h AVPacket structure got additional members for passing side information: - 4de339e introduce side information for AVPacket - 2d8591c make containers pass palette change in AVPacket + c407984 / 4de339e introduce side information for AVPacket + c407984 / 2d8591c make containers pass palette change in AVPacket 2011-04-12 - lavf 52.107.0 - avio.h Avio cleanup, part II - deprecate the entire URLContext API: - 175389c add avio_check as a replacement for url_exist - ff1ec0c add avio_pause and avio_seek_time as replacements + c55780d / 175389c add avio_check as a replacement for url_exist + 9891004 / ff1ec0c add avio_pause and avio_seek_time as replacements for _av_url_read_fseek/fpause - cdc6a87 deprecate av_protocol_next(), avio_enum_protocols + d4d0932 / cdc6a87 deprecate av_protocol_next(), avio_enum_protocols should be used instead. - 80c6e23 rename url_set_interrupt_cb->avio_set_interrupt_cb. - f87b1b3 rename open flags: URL_* -> AVIO_* - f8270bb add avio_enum_protocols. - 5593f03 deprecate URLProtocol. - c486dad deprecate URLContext. - 026e175 deprecate the typedef for URLInterruptCB - 8e76a19 deprecate av_register_protocol2. - b840484 deprecate URL_PROTOCOL_FLAG_NESTED_SCHEME - 1305d93 deprecate av_url_read_seek - fa104e1 deprecate av_url_read_pause - 727c7aa deprecate url_get_filename(). - 5958df3 deprecate url_max_packet_size(). - 1869ea0 deprecate url_get_file_handle(). - 32a97d4 deprecate url_filesize(). - e52a914 deprecate url_close(). - 58a48c6 deprecate url_seek(). - 925e908 deprecate url_write(). - dce3756 deprecate url_read_complete(). - bc371ac deprecate url_read(). - 0589da0 deprecate url_open(). - 62eaaea deprecate url_connect. - 5652bb9 deprecate url_alloc. - 333e894 deprecate url_open_protocol - e230705 deprecate url_poll and URLPollEntry + c88caa5 / 80c6e23 rename url_set_interrupt_cb->avio_set_interrupt_cb. + c88caa5 / f87b1b3 rename open flags: URL_* -> AVIO_* + d4d0932 / f8270bb add avio_enum_protocols. + d4d0932 / 5593f03 deprecate URLProtocol. + d4d0932 / c486dad deprecate URLContext. + d4d0932 / 026e175 deprecate the typedef for URLInterruptCB + c88caa5 / 8e76a19 deprecate av_register_protocol2. + 11d7841 / b840484 deprecate URL_PROTOCOL_FLAG_NESTED_SCHEME + 11d7841 / 1305d93 deprecate av_url_read_seek + 11d7841 / fa104e1 deprecate av_url_read_pause + 434f248 / 727c7aa deprecate url_get_filename(). + 434f248 / 5958df3 deprecate url_max_packet_size(). + 434f248 / 1869ea0 deprecate url_get_file_handle(). + 434f248 / 32a97d4 deprecate url_filesize(). + 434f248 / e52a914 deprecate url_close(). + 434f248 / 58a48c6 deprecate url_seek(). + 434f248 / 925e908 deprecate url_write(). + 434f248 / dce3756 deprecate url_read_complete(). + 434f248 / bc371ac deprecate url_read(). + 434f248 / 0589da0 deprecate url_open(). + 434f248 / 62eaaea deprecate url_connect. + 434f248 / 5652bb9 deprecate url_alloc. + 434f248 / 333e894 deprecate url_open_protocol + 434f248 / e230705 deprecate url_poll and URLPollEntry 2011-04-08 - lavf 52.106.0 - avformat.h Minor avformat.h cleanup: - a9bf9d8 deprecate av_guess_image2_codec - c3675df rename avf_sdp_create->av_sdp_create + d4d0932 / a9bf9d8 deprecate av_guess_image2_codec + d4d0932 / c3675df rename avf_sdp_create->av_sdp_create 2011-04-03 - lavf 52.105.0 - avio.h Large-scale renaming/deprecating of AVIOContext-related functions: - 724f6a0 deprecate url_fdopen - 403ee83 deprecate url_open_dyn_packet_buf - 6dc7d80 rename url_close_dyn_buf -> avio_close_dyn_buf - b92c545 rename url_open_dyn_buf -> avio_open_dyn_buf - 8978fed introduce an AVIOContext.seekable field as a replacement for + 2cae980 / 724f6a0 deprecate url_fdopen + 2cae980 / 403ee83 deprecate url_open_dyn_packet_buf + 2cae980 / 6dc7d80 rename url_close_dyn_buf -> avio_close_dyn_buf + 2cae980 / b92c545 rename url_open_dyn_buf -> avio_open_dyn_buf + 2cae980 / 8978fed introduce an AVIOContext.seekable field as a replacement for AVIOContext.is_streamed and url_is_streamed() - b64030f deprecate get_checksum() - 4c4427a deprecate init_checksum() - 4ec153b deprecate udp_set_remote_url/get_local_port - 933e90a deprecate av_url_read_fseek/fpause - 8d9769a deprecate url_fileno - b7f2fdd rename put_flush_packet -> avio_flush - 35f1023 deprecate url_close_buf - 83fddae deprecate url_open_buf - d9d86e0 rename url_fprintf -> avio_printf - 59f65d9 deprecate url_setbufsize - 3e68b3b deprecate url_ferror + 1caa412 / b64030f deprecate get_checksum() + 1caa412 / 4c4427a deprecate init_checksum() + 2fd41c9 / 4ec153b deprecate udp_set_remote_url/get_local_port + 4fa0e24 / 933e90a deprecate av_url_read_fseek/fpause + 4fa0e24 / 8d9769a deprecate url_fileno + 0fecf26 / b7f2fdd rename put_flush_packet -> avio_flush + 0fecf26 / 35f1023 deprecate url_close_buf + 0fecf26 / 83fddae deprecate url_open_buf + 0fecf26 / d9d86e0 rename url_fprintf -> avio_printf + 0fecf26 / 59f65d9 deprecate url_setbufsize + 6947b0c / 3e68b3b deprecate url_ferror e8bb2e2 deprecate url_fget_max_packet_size 76aa876 rename url_fsize -> avio_size e519753 deprecate url_fgetc @@ -462,7 +478,7 @@ API changes, most recent first: b3db9ce deprecate get_partial_buffer 8d9ac96 rename av_alloc_put_byte -> avio_alloc_context -2011-03-25 - 34b47d7 - lavc 52.115.0 - AVCodecContext.audio_service_type +2011-03-25 - 27ef7b1 / 34b47d7 - lavc 52.115.0 - AVCodecContext.audio_service_type Add audio_service_type field to AVCodecContext. 2011-03-17 - e309fdc - lavu 50.40.0 - pixfmt.h @@ -500,11 +516,11 @@ API changes, most recent first: 2011-02-10 - 12c14cd - lavf 52.99.0 - AVStream.disposition Add AV_DISPOSITION_HEARING_IMPAIRED and AV_DISPOSITION_VISUAL_IMPAIRED. -2011-02-09 - 5592734 - lavc 52.112.0 - avcodec_thread_init() +2011-02-09 - c0b102c - lavc 52.112.0 - avcodec_thread_init() Deprecate avcodec_thread_init()/avcodec_thread_free() use; instead set thread_count before calling avcodec_open. -2011-02-09 - 778b08a - lavc 52.111.0 - threading API +2011-02-09 - 37b00b4 - lavc 52.111.0 - threading API Add CODEC_CAP_FRAME_THREADS with new restrictions on get_buffer()/ release_buffer()/draw_horiz_band() callbacks for appropriate codecs. Add thread_type and active_thread_type fields to AVCodecContext. diff --git a/doc/developer.texi b/doc/developer.texi index 32d666ac68..e0e332a6c2 100644 --- a/doc/developer.texi +++ b/doc/developer.texi @@ -187,8 +187,8 @@ the following snippet into your @file{.vimrc}: set expandtab set shiftwidth=4 set softtabstop=4 -" allow tabs in Makefiles -autocmd FileType make set noexpandtab shiftwidth=8 softtabstop=8 +" Allow tabs in Makefiles. +autocmd FileType make,automake set noexpandtab shiftwidth=8 softtabstop=8 " Trailing whitespace and tabs are forbidden, so highlight them. highlight ForbiddenWhitespace ctermbg=red guibg=red match ForbiddenWhitespace /\s\+$\|\t/ diff --git a/doc/ffmpeg-mt-authorship.txt b/doc/ffmpeg-mt-authorship.txt deleted file mode 100644 index d8c405f948..0000000000 --- a/doc/ffmpeg-mt-authorship.txt +++ /dev/null @@ -1,4561 +0,0 @@ -This file lists authorship of commits that have been merged from -ffmpeg-mt. These commits where not classically merged because this -would have pulled in duplicated history of all commits in ffmpeg. -Which a majority of developers opposed. - - -commit 002a0939cdf01faa8270d41b3045c08ac12d8975 -Author: Alexander Strange -Date: Sat Feb 20 20:24:36 2010 -0500 - - Update todo - -commit 0040d6f2ba7189ca9bab4cf17c0d150416391dec -Author: Alexander Strange -Date: Sun Jan 24 18:33:16 2010 -0500 - - Remove a malloc() per frame by keeping an array of 32 buffers. - - Requested in original review. Should be slightly faster but does - have a 32-element linear search (since buffers are freed out of order). - - Introducing array_next_nonzero or something would speed up this - and h264 decoding. - -commit 00425e98fba903dceecb89763b57b8f3b7a1abf3 -Merge: 20997d6 e320c22 -Author: Alexander Strange -Date: Thu Jul 2 04:59:42 2009 -0400 - - Merge mainline. - - Having to move the setting of key_frame confused me for far too - long. - -commit 0097d3b01e33d1e0f636a19778a0435a730d4590 -Merge: 9e981c8 44c4fd1 -Author: Alexander Strange -Date: Thu Sep 9 19:19:34 2010 -0400 - - Merge mainline and libswscale. - - Another one coming after h264 is converted to yasm. - - Conflicts: - libavcodec/avcodec.h - -commit 00bbca77f3fe0960cbf0986ea214ce022204837c -Author: Alexander Strange -Date: Sun Jan 16 02:18:12 2011 -0500 - - h264: Early-exit condition for await_references() - - Saves even more zero checking in refs[][], although it still leaves many - useless checks when nrefs[i]>1, because the array indexes are scattered. - - About ~.8% faster decoding. - -commit 00c4b0bb5a7801d14627015d38762ec314639d3d -Merge: 63d086d feadf1b -Author: Alexander Strange -Date: Fri Mar 13 23:50:33 2009 -0400 - - Merge mainline. - - Conflicts: - libavcodec/avcodec.h - libavcodec/h263.c - libavcodec/h263dec.c - libavcodec/h264.c - libavcodec/mpeg12.c - libavcodec/mpegvideo.c - libavcodec/options.c - libavutil/log.c - -commit 01006069782b1b8fe0bfe0eabe4876062e057c11 -Author: Alexander Strange -Date: Tue Jan 13 01:30:01 2009 -0500 - - Fix possibly not allocating obmc_scratchpad with PAFF/weighted prediction - -commit 011a76824f384a315ce4b0474a2811d463b5746b -Author: Alexander Strange -Date: Mon Sep 1 00:40:40 2008 -0400 - - Whitespace and variable name cosmetics for clarity. - -commit 02376cec6531a931330798af67c62a029a3435a1 -Author: Alexander Strange -Date: Thu Jun 11 14:40:27 2009 -0700 - - Normalize how decode_postinit() is called. - - Move it next to the hwaccel call to save an if statement. - -commit 031abc50708c616058020dcf7a1b62bc9b895446 -Author: Alexander Strange -Date: Fri Aug 22 20:43:38 2008 -0400 - - Improve comments in thread.h - -commit 032432ad56fd88a7e9ba6ce9ccd39925854b027a -Author: Alexander Strange -Date: Sat Feb 20 20:48:10 2010 -0500 - - Remove FF_THREAD_DEFAULT. - - It obviously makes no sense to define the default in a public header. - -commit 03980f22907206b52e64439ebcc4445719801035 -Author: Alexander Strange -Date: Fri Jul 11 17:22:22 2008 -0400 - - Mark functions inline to avoid unused function warnings. - -commit 0488ed2d9ff609ec4a6be008c81603b62ce67785 -Author: Alexander Strange -Date: Wed Jun 4 15:55:00 2008 -0400 - - Align the stack in decode_frame_thread. - -commit 0553196aa797d58f0687890c66e1b1cdfa52f419 -Author: Alexander Strange -Date: Wed May 28 00:44:13 2008 -0400 - - Add the frame-threading support code. - -commit 056dce6c969acec1224eaa9fc73d930d1e56b299 -Author: Alexander Strange -Date: Fri Aug 15 16:44:33 2008 -0400 - - h264: Redo finding the output frame during header parsing after merging mainline. - - This works with PAFF and CODEC_FLAG2_CHUNKS, though the second is useless and should be removed. - -commit 05a3af85edd15fef223f0376d3241cc5c7aa3ed5 -Merge: 8ba50a9 fa43cf8 -Author: Alexander Strange -Date: Mon Apr 19 02:41:54 2010 -0400 - - Merge mainline. - - Conflicts: - libavcodec/avcodec.h - libavcodec/h264.c - -commit 05e37cada02dc1ac58e7ce93418cbf33e3a09ad6 -Author: Alexander Strange -Date: Tue May 27 21:00:34 2008 -0400 - - Add the AVCodec/AVCodecContext fields needed for multithreading and increment the API minor version. - -commit 061586a260a564080be8c1ed9af4e83888fe3543 -Author: Alexander Strange -Date: Thu Sep 4 01:41:53 2008 -0400 - - Remove error check that can never fail. - -commit 06407ff8706c7fe28c5b925c4b1dd52641714cb9 -Author: Alexander Strange -Date: Mon Jun 16 18:21:04 2008 -0400 - - Multithreading support for MPEG-1. - -commit 065ee0d04a6539c08bddfa1edc628906494c22f2 -Author: Alexander Strange -Date: Mon Nov 1 12:24:37 2010 -0400 - - vp3: Report INT_MAX instead of height at the end of a frame - - This saves having to clip to height in await_reference_row. - -commit 067c30c63499d5cca5613725de936fb70047aec3 -Author: Alexander Strange -Date: Sun Jun 22 03:29:23 2008 -0400 - - Cosmetics: opening function braces on their own line. - -commit 06ac5ac98dbf03889eb7cccf67fe0cb95615613d -Merge: febe154 987789a -Author: Alexander Strange -Date: Sun Jun 20 04:29:03 2010 -0700 - - Merge mainline. - - Document ONLY_IF_THREADS_ENABLED along the way. - - Conflicts: - libavutil/internal.h - -commit 07474003407915e5462ed3582a1dae8baa06f296 -Author: Alexander Strange -Date: Wed Jun 10 11:25:48 2009 -0700 - - Move frame_thread_init() down to avoid prototyping its callees. - -commit 076bf916d79c39ec055a53f2ee5eadf20c21b988 -Author: Alexander Strange -Date: Mon Aug 25 14:32:41 2008 -0400 - - Increase max delayed buffers for safety - -commit 079cd64ef92cb1670a420a16e38c645cc8f28caa -Author: Alexander Strange -Date: Tue Sep 2 11:38:29 2008 -0400 - - Ignore codecs returning NULL when draining frames. - -commit 090c1f4c99b9c5cefa3bad7698f33516baa87c6e -Author: benoit -Date: Tue Nov 6 13:08:04 2007 +0000 - - fix predictor initialization for adpcm-ima encoder not to lose first sample - in block in adpcm-ima decoder - Patch by Timofei V. Bondarenko: tim commit 09bb0dafa746203f98ff478a5121b3b0ffb3f46e -Author: Alexander Strange -Date: Tue Jul 22 22:20:47 2008 -0400 - - Switch from MB row to pixel row precision for h264 progress. - - This makes it easier to think about interlacing and the deblock filter, and also fixes decoding entirely. - -commit 0a51c1e9ebf09d302e44daaca3147e7cca2f0457 -Author: Alexander Strange -Date: Tue Jun 3 16:04:31 2008 -0400 - - Use threading macros in mpeg12.c. - -commit 0ac282b447075a0645036fba56d2881bbcc8f471 -Author: Alexander Strange -Date: Mon Jan 17 03:44:26 2011 -0500 - - Update multithreading.txt for thread_safe_callbacks and pkt_dts - -commit 0b64ceb6b15560313d0a6ac7cffe9270d7b8e0e8 -Merge: 9ec9f08 e220e91 -Author: Alexander Strange -Date: Tue Aug 10 03:22:51 2010 -0700 - - Merge mainline. - - Conflicts: - libavcodec/avcodec.h - -commit 0b8add0862f841dfc8dbbc8d89dfb3712ce3a698 -Author: Alexander Strange -Date: Mon Aug 18 16:47:21 2008 -0400 - - Allow avcodec_default_release_buffer to be called after avcodec_default_free_buffers. - -commit 0b8c3d23339b5f646ae702f30141e223596f9ff9 -Author: Alexander Strange -Date: Sun Jul 27 21:55:53 2008 -0400 - - Reindent. - -commit 0be0d5714347f63b0e391ad3e9202f9d5107bb5f -Merge: f550857 8c00628 -Author: Alexander Strange -Date: Sun Mar 28 03:40:27 2010 -0400 - - Merge mainline. - -commit 0c73945d0cc40a6ade8ca78dfa0d9bea178f4743 -Author: Alexander Strange -Date: Tue Aug 19 01:07:17 2008 -0400 - - Clarify comment for new AVFrame members - - They are set by libavcodec even if they aren't used for anything useful ATM. - -commit 0cac0f3bd81287db20bbbae5aaff22e381e09663 -Author: Alexander Strange -Date: Sun Jul 13 02:40:22 2008 -0400 - - Add report/await_decode_progress for progressive H264 - Multithreading works with no visible problems for progressive sequences, but there is still some problem causing framecrc differences. - 1 thread - 99% cpu 14s - 2 threads - 183% cpu 8.6s - -commit 0cae6d85e8a33b826611ced69902f2a4d16f0c7a -Author: benoit -Date: Fri Jun 1 12:03:33 2007 +0000 - - A bit more clear FAQ 1.2 - Patch by V -�commit 0d25fc9993407335bc98b91296f9f78b634dd8a0 -Author: Alexander Strange -Date: Tue Jun 24 21:39:39 2008 -0400 - - Remove newly-duplicated memset(). - -commit 0e41f7596f06a758c0f1cb9e48e67ef896c5c05a -Author: Alexander Strange -Date: Fri Jul 11 18:09:02 2008 -0400 - - Reindent. - -commit 0ef99ed28b24757a30b1e805f2ff1ea6d90b9b71 -Author: Alexander Strange -Date: Mon Jan 25 03:17:46 2010 -0500 - - Remove item from todo - -commit 0fad6cca0a7e34dfa62c3934eb5316e2c9649e66 -Author: Alexander Strange -Date: Tue Jul 22 01:00:07 2008 -0400 - - Fix height passed to ff_draw_band for interlaced H.264. - - Without this, it passes y 0 h 16, y 32 h 16, etc. - -commit 0fb994fbdbf4f985ec9c0d5a681e7a5bf620a765 -Merge: 5eb0c64 ace7af3 -Author: Alexander Strange -Date: Wed Jan 20 01:58:15 2010 -0500 - - Merge mainline. - - This was done by hand since git can't track the h264/h263 decoder - splits properly. - - Conflicts: - libavcodec/avcodec.h - libavcodec/h263.c - libavcodec/h263dec.c - libavcodec/h264.c - -commit 0ff629947b15955603cdb7978770ca64c2323262 -Author: Alexander Strange -Date: Thu Jun 18 05:09:01 2009 -0400 - - Don't call report_field_progress for non-referenced H264 frames. - -commit 111fa56db1bfefc245c499f465783a5abc04f7c2 -Author: Alexander Strange -Date: Sat Jul 19 00:12:00 2008 -0400 - - Set start/end_mb_y properly in MpegEncContext. - -commit 115adc279240b6c7155781b5a16177a140eaad4f -Author: Alexander Strange -Date: Sat Jun 21 23:10:18 2008 -0400 - - Add an update_context for codecs that just use MpegEncContext. - -commit 116ca147f03ca02b55c2fceef7b82c1b251b32f6 -Author: Alexander Strange -Date: Sat Aug 16 14:10:31 2008 -0400 - - Merge fallout: move AVCodec additions back to the end of the struct - -commit 11b1a8ee92128524a3259903c28da54ffd9a60fa -Author: Alexander Strange -Date: Sun May 30 10:02:16 2010 -0700 - - Update todo. - - I appear to have fixed the bug (the problem doesn't show in test.sh - anymore). Of course, there might be more. - -commit 120d790a3918f77444eed295aec6d8c34e4b532a -Author: Alexander Strange -Date: Thu Jul 17 18:00:07 2008 -0400 - - Simplify draw_edges changes and handle interlacing properly. - -commit 1239bcba12d0c57005ae59405e8b080ac3c7bd65 -Author: Alexander Strange -Date: Mon Aug 18 18:59:29 2008 -0400 - - Simplify: store FrameThreadContext in the user's context. - -commit 1292a1840bb5319f1438b63b7be35363ba4fe5b6 -Author: Alexander Strange -Date: Tue Jan 13 01:33:47 2009 -0500 - - Copy width/height between thread contexts for all codecs. - - This makes it user-visible and fixes compatibility with - bad demuxers that don't set it in avctx. - -commit 12c5de8ead7c7a1b4c03eb095a2db4357aa2538d -Author: benoit -Date: Thu Jan 3 08:39:38 2008 +0000 - - Make filterDelimiters and optionDelimiters two static constant array of - characters, should move them to .rodata. - Patch by Diego 'Flameeyes' Petten -� flameeyes commit 1327c17ca423f248dbce8172476dd69208f7d74b -Author: Alexander Strange -Date: Sat May 23 21:52:24 2009 -0400 - - Stopgap hack: don't crash with size-changing streams+frame threads - - MPEG1 and H.264 need their own checks, otherwise they immediately - deallocate shared data and crash. Another check is added to get_buffer - to cover remaining codecs (although it may not actually do this). - - This currently involves ugly code duplication, which can hopefully - be eventually removed. Unfortunately this is already not handled - well on mainline (such as in the previous commit). - -commit 138ec8aad228862d58582aa4bbd367b7fa7b8d81 -Author: Alexander Strange -Date: Thu Jul 24 16:06:17 2008 -0400 - - Factor out copying picture pointers in update_context. - -commit 13c48792ac24329c9055f6e98b5e61c278f1aa57 -Author: Alexander Strange -Date: Tue Mar 9 00:02:20 2010 -0500 - - Fix wrong timestamps with -threads 2 and BBB 1080p Theora - - It was caused by adding thread delay to has_b_frames. - -threads 2 -> has_b_frames 1 -> "delay==1" is true and the - "invalid dts/pts combination" was triggered. Not sure about this fix, - but I think it's harmless. - -commit 141516ca4f2b0008539ceeb70b46ebb6cfe4a1c0 -Author: Alexander Strange -Date: Sun Jun 15 17:44:29 2008 -0400 - - Cosmetics: use USE_ macro. - -commit 14476d56276a77a237834e88b28427fe491ac689 -Author: Alexander Strange -Date: Sat Aug 16 14:11:41 2008 -0400 - - Correct AVCodec member comments - -commit 14bdf768314413a099fe570891761360733b148c -Author: Alexander Strange -Date: Tue Mar 9 01:15:03 2010 -0500 - - Update sws. - -commit 14df94ceacecf041d33b8600bc9097d4befd79dd -Author: Alexander Strange -Date: Sun Feb 14 23:57:37 2010 -0500 - - Add a convenience function for avoiding deadlocks with decoder errors - -commit 156f6ba4db96f57c3c105b71986acaa9be13d5ab -Author: Alexander Strange -Date: Sun Aug 17 00:19:10 2008 -0400 - - Update todo - -commit 16343b25d2ffc7c18a00ec62db8e76d7f8217de5 -Author: Alexander Strange -Date: Sat Feb 20 22:39:05 2010 -0500 - - Rewrite comments for new codec callbacks - -commit 16b71c003150c3a44135ffa1bbc870ea43c15f7a -Author: Alexander Strange -Date: Thu Dec 18 14:37:04 2008 -0500 - - Some todo entries I forgot to add - -commit 16bde8c7df438f5283de102e3c872ef309a8d0b5 -Author: Alexander Strange -Date: Thu Jun 5 00:11:43 2008 -0400 - - Implement avcodec_flush_buffers for multithreaded codecs. - -commit 17b3c2a080f7ec1f548494e0e2b905ad0e2690c0 -Author: Alexander Strange -Date: Mon Aug 18 20:36:54 2008 -0400 - - Clarify use of is_copy - -commit 17d7a98c7aadc2be1ceadf875ae2ca71b08a5611 -Merge: 0097d3b 981f8d0 -Author: Alexander Strange -Date: Wed Sep 29 22:55:44 2010 -0400 - - Merge mainline. - - Fix misplaced lowres check from previous merge. (or maybe it was fine?) - - Conflicts: - libavcodec/avcodec.h - libavcodec/utils.c - -commit 17dcbec74c0630e44029dd5e4efd8f9bb2ddee13 -Author: Alexander Strange -Date: Fri Jul 24 16:51:14 2009 -0400 - - Fix typo in huffyuv, broke mt decoding with newer huffyuv versions. - -commit 17ef916da54e5cbaf2ce97cba565ba4730dcd847 -Author: Alexander Strange -Date: Tue May 11 14:39:44 2010 -0400 - - Cosmetics: remove stray spaces in pthread.c - -commit 1846cc0549bf3d45fb2a5a2152b7335c794146e8 -Merge: 5323bc6 cd23ede -Author: Alexander Strange -Date: Mon Mar 8 04:30:32 2010 -0500 - - Merge mainline. - - The VP3 decoder has been heavily changed upstream and this commit - removes mt optimizations. They will be readded later. - - Conflicts: - libavcodec/avcodec.h - libavcodec/h264.c - libavcodec/h264.h - libavcodec/h264_direct.c - libavcodec/vp3.c - -commit 1878dce0e65b2fab94612c950fac51e3de741636 -Merge: b7d1826 2b13612 -Author: Alexander Strange -Date: Sun May 24 01:37:21 2009 -0400 - - Merge mainline. - -commit 1884de3ffb775bb23cbfbf977ea48841c2b2ae16 -Author: Alexander Strange -Date: Fri May 8 00:15:50 2009 -0400 - - Correct comment about decoding delay. - -commit 18893e1423c3d8a65ca753806638ac160fefe342 -Author: Alexander Strange -Date: Sat Oct 23 18:13:56 2010 -0400 - - Add a -vsync test to test.sh. - - The files x-1-vsync.txt and x-3-vsync.txt should have the same MD5. - Even more ideally, all files should have the same MD5, but it's not our problem if they don't. - - h264 and theora pass, didn't test others. - -commit 18dc6b6010200c45827d14594a5d7b7b2b28d8e0 -Author: Alexander Strange -Date: Wed Aug 6 20:31:04 2008 -0400 - - Move ff_frame_thread_init above its uses and make it static since it has only one caller. - -commit 190d65b24795208e30c06369e34769ffeb9b5cc8 -Author: Alexander Strange -Date: Sun Aug 24 01:31:00 2008 -0400 - - Add a longer comment for update_context - -commit 19b159260eb5eddfd296cac179d59ba218f881ac -Author: Alexander Strange -Date: Fri Jan 21 01:22:43 2011 -0500 - - Adopt pkt_pts/pkt_dts in lavc clients - - This makes DTS reliable with threads. - -commit 1a0d8d0cd0d7d0dc44d1747b2c8c93c73bc09cd8 -Author: Alexander Strange -Date: Mon Jan 4 03:59:20 2010 -0500 - - Note in todo that 'make test' doesn't pass ATM. - - Also note a harmless warning emitted, which I haven't - though of a good fix for yet. - -commit 1a216093ed2f201814287a32b5d8f22781c6d8d1 -Author: Alexander Strange -Date: Mon Aug 25 01:02:29 2008 -0400 - - Comment another strange line - -commit 1a4740fed38a69202c762e3cd786dd3c7c23dd40 -Author: Alexander Strange -Date: Sat Jan 15 17:02:46 2011 -0500 - - Make ARM asm #error out, since the offset values are out of date here - -commit 1ac02d2ff0dd39d8baf68cf7e0490de4db9b88cc -Author: Alexander Strange -Date: Fri Jul 10 14:24:40 2009 -0400 - - Fix the error in avcodec_thread_init to actually not do anything. - -commit 1b735c493b0fe8c1aaff3d06214c24e8556b111c -Author: Alexander Strange -Date: Mon Aug 25 14:40:54 2008 -0400 - - Remove some context variable copies which were overwriting user settings - -commit 1b755181905bed35b2edd723c137b8f0af9c31c3 -Author: Alexander Strange -Date: Sat Aug 23 23:14:20 2008 -0400 - - Add a FIXME for PAFF - -commit 1c187ba01c332b3d99681cfffb90f0247a836303 -Merge: 8022069 0309093 -Author: Alexander Strange -Date: Mon Nov 15 05:32:06 2010 -0500 - - Merge mainline. - - Conflicts: - doc/APIchanges - libavcodec/avcodec.h - -commit 1c39407876cb6689e313ce27a51d83d77ac0c4e4 -Author: Alexander Strange -Date: Sun May 23 03:40:43 2010 -0400 - - Fix crash with ffplay. - - Caused by the buffer functions being changed after codec init. - -commit 1c70dfb14a5e6e322f66d1175045eb13ac96d2f8 -Author: Alexander Strange -Date: Sat Feb 20 22:10:38 2010 -0500 - - Rewrite thread.h comments for clarity - -commit 1c8037ec029ffe790b39b0cf0e67468db5f8c4a8 -Author: Alexander Strange -Date: Mon Jan 25 03:59:02 2010 -0500 - - Fix references to renamed avail_motion() in the todo. - - Delete the second entry mentioning it, since I don't think it's a - good idea anymore. - -commit 1ca44079c06a2080c2a0deb9cbc8fa757a5be540 -Author: Alexander Strange -Date: Sun Jun 15 20:34:08 2008 -0400 - - Delete unused variables. The frame counters will stay around for now for debugging. - -commit 1d15df4fd2b4583d56159a7938ef3699c7f46261 -Merge: 8f759fa b3b80f1 -Author: Luca Barbato -Date: Sat May 31 17:56:44 2008 +0200 - - Merge branch 'master' of git://git.mplayerhq.hu/ffmpeg - -commit 1da82befe53bc245ba94cf1012fcd0156040353c -Author: benoit -Date: Mon Jan 7 12:40:39 2008 +0000 - - Remove unused symbol. - - Patch by Diego 'Flameeyes' Petten -� flameeyes commit 1e8abec2eecd831c55e34c09fc9a38833d69c180 -Author: Alexander Strange -Date: Fri Jul 10 14:28:54 2009 -0400 - - Fix default value of thread_count. - - Adding a flag named "threads" somehow disabled the default value - of the option named "threads", which allowed thread_count to be 0 - for non-ffmpeg/ffplay clients (which don't always reset it). - - Not sure why AVOption works this way. - -commit 1eff8ec8e1772334cd74129f8cc068483c757b40 -Author: benoit -Date: Fri Aug 10 07:28:18 2007 +0000 - - Prefix with "opt_" the functions ffmpeg.c:show_{version,license,formats}. - patch by Stefano Sabatini [stefano tod sabatini-lala commit 1fae9e952cee3c499313b5a9b5c2e3dda096ee30 -Author: Alexander Strange -Date: Thu Mar 10 01:44:05 2011 -0500 - - Delete the libswscale submodule for svn->git merge. - -commit 2037d9714bc51ccb57a82aba95a52a5b49bdc401 -Author: Alexander Strange -Date: Sun Aug 24 21:16:50 2008 -0400 - - Comment this just in case someone doesn't get it - -commit 2063f77f904af3544021e16d6da76acf5d9beaed -Author: Alexander Strange -Date: Mon Nov 15 05:40:04 2010 -0500 - - Delete beosthread.c which is gone from mainline - -commit 207f434446b40b29311e81233167bd03de16bf0c -Author: Alexander Strange -Date: Wed Jul 30 20:14:56 2008 -0400 - - Cosmetics: whitespace adjustments. - -commit 20997d60c8ec84dd0dd68055901e847c4b4e171a -Author: Alexander Strange -Date: Sat Jun 27 22:33:17 2009 -0400 - - Frame threading for VP3 [2/2]. - - The performance with different thread counts is different from - MPEG codecs; trying more or less granular synchronization would - be interesting. - -commit 20a85842c46b547331c5884e015dd781108c6d17 -Author: Alexander Strange -Date: Sat Oct 11 16:43:39 2008 -0400 - - Save PAFF vs MBAFF information for pictures. - - This already exists differently in mainline, but this way is more useful - since MPEG-2 has field pictures but not MBAFF. - -commit 20d6c336b37a7bf7313865a397f19ef33595adf8 -Author: Alexander Strange -Date: Tue Dec 23 17:49:51 2008 -0500 - - More todo entries - -commit 210b4a63100e5f4ba5ab23e84460614ca59b7817 -Merge: fc957c7 59b0bd5 -Author: Alexander Strange -Date: Mon May 24 22:26:23 2010 -0400 - - Merge mainline. - -commit 21cede4223d4bcfcc0f6a91bbc84354238201fea -Author: Alexander Strange -Date: Mon Apr 19 03:30:45 2010 -0400 - - Fix possible overlapping memcpy()+crash at the end of decode - - Increasingly dissatisfied with having to do this. - -commit 22a56df3f22e5c32c5f2fd06db8d644157da1877 -Author: Alexander Strange -Date: Mon Jul 14 23:12:17 2008 -0400 - - Remove dead code. - -commit 22d953bd1ef2b61ec272be03aa8f81587e0ac046 -Author: Alexander Strange -Date: Wed Jun 25 04:54:34 2008 -0400 - - Remove zeroing mbskip_table - It's unnecessary with the previous commit. - -commit 22e9455a663acc4d34f76130f2603b41b3940b9e -Author: Alexander Strange -Date: Fri Aug 22 16:25:45 2008 -0400 - - Comment and rename context variables in pthread.c. - -commit 2331711a5ff0908a37005a0e500804a5a8a61e5d -Author: Michael Niedermayer -Date: Wed Apr 6 00:15:42 2011 +0200 - - Fix ffmpeg-mt fixme in h264 - - Uncommenting this code no longer seems to cause valgrind problems or crashes. - Behavior is unchanged. - -commit 234887b836f9b0306388d20499c8025ac916e11b -Author: Alexander Strange -Date: Tue Aug 19 21:17:15 2008 -0400 - - Normalize if (err) - -commit 2412ad4778734a19638c997d5567f5d53d135a9a -Author: Alexander Strange -Date: Mon Jan 17 15:57:00 2011 -0500 - - pthread: Document release_delayed_buffers - -commit 24345e509df0b92a3592cfb15db12b1aecd78ffe -Author: Alexander Strange -Date: Tue Aug 26 02:26:07 2008 -0400 - - Fix spelling and rewrap multithreading.txt to the right number of columns. - -commit 2485cfd74cf5012fdce8582b7094ddbd09bd70c9 -Author: Alexander Strange -Date: Sun May 24 03:38:22 2009 -0400 - - 10l: pred_direct_motion fix missed several mb_type accesses - - I have not proven this correct yet; it's not too hard with some work - (record the last row accessed and waited for, and make sure they - correspond). Therefore, I suspect it still isn't correct, since - framecrc still shows mismatches. It does fix the worst visible - errors, though. - -commit 25a2f117ad6d6dc2592e77369bed23e53241b218 -Author: Alexander Strange -Date: Fri Jan 21 03:24:41 2011 -0500 - - Cosmetic: shorter line variable declaration - -commit 26151296236e0381c1c40e0d97ead8c5ab26b57c -Author: Alexander Strange -Date: Tue Nov 2 02:33:12 2010 -0400 - - vp3: Lift up loop-invariant checks and simplify away 'border' which == 1 - -commit 27026500c9a25bf409b55186d9bceada4bf2ba5c -Author: Alexander Strange -Date: Sat Jul 19 02:09:18 2008 -0400 - - Fix mpegvideo crashing without --enable-pthreads due to the number of thread_contexts changing. - - -threads X no longer has any effect since all threading code is now gone without an actual threading library. - I think this is a nice minor size optimization, but if it's necessary to keep regression tests working with frame-threaded encoding I'll have to revisit it. - -commit 2742b2a142ff98e4611f96ddf47ab5a5233f4692 -Author: benoit -Date: Thu Jan 10 10:15:07 2008 +0000 - - Reduce the size of the replaceTable entries. - Patch by Diego 'Flameeyes' Petten -� flameeyes commit 287e761820e85514e00eb6c5958496ecb61825cb -Author: Alexander Strange -Date: Thu Dec 24 22:21:37 2009 -0500 - - Fix error return being ignored in VP3 allocate_tables(). - - Based on a patch by Yuriy M. Kaminskiy. - -commit 29c2b04f5074e49aa63cf50fb90e3a51e853ad9d -Author: Alexander Strange -Date: Sat Apr 4 00:35:28 2009 -0400 - - More todos related to init api - -commit 2a7a86a64f153befafabcbb987e2793fa4bb0e18 -Author: Alexander Strange -Date: Sat Jun 27 22:17:41 2009 -0400 - - Split out error returns in VP3. - -commit 2a9b493a5a0f46f43959ce2466849dd6a6217012 -Author: Alexander Strange -Date: Wed Feb 2 02:12:29 2011 -0500 - - Fix memory abandonment + unnecessary realloc in mpeg4 - - Fixes Sample1.mkv from ffms running out of address space (and more). - Note the file doesn't display properly in ffplay, so there's still bugs left. - -commit 2ae310bf292c1f34be006e9be7fbceb4c0f1b068 -Author: Alexander Strange -Date: Tue Jun 3 04:20:42 2008 -0400 - - Comment next_*_index. - -commit 2b74560715c3d4f331156d8745ce801c1de4d467 -Author: Alexander Strange -Date: Tue Nov 18 14:31:17 2008 -0500 - - Revert accidental warning change - -commit 2b7d2acccb45e89bfc77564bcdaee68fcb4ac4c7 -Author: Alexander Strange -Date: Tue Feb 1 23:05:43 2011 -0500 - - Revert 99ed04d4d7b7183a4d0a1b8833eee3b506e13ff0 - - Broke big_buck_bunny_720p_stereo.ogg with 2 threads. - -commit 2bbb64dae018cbb09ea47a6bdcb184f551136c26 -Author: Alexander Strange -Date: Wed Dec 15 16:15:21 2010 -0500 - - Fix definition of CODEC_CAP_FRAME_THREADS to not conflict. - -commit 2bc23e009291d727eed7a4f803a2793f5fa715b0 -Author: Alexander Strange -Date: Tue Aug 26 03:03:38 2008 -0400 - - Update avcodec.h comments - -commit 2bcbffdbf53bd2918ba6ade66d12fb97021032c7 -Author: Alexander Strange -Date: Sun Jun 15 20:26:59 2008 -0400 - - Combine all the condition variables into one. - -commit 2beb042a202d00dbb2baef3970f058994aeec027 -Author: Alexander Strange -Date: Sat Aug 23 19:32:56 2008 -0400 - - Split thread_algorithm into two more sanely defined variables. - - Also improves correctness in some ways. - -commit 2c0e016af759adfdc34a6a1b8592ec0a1ef56da9 -Merge: d5ea5fc c2c8552 -Author: Alexander Strange -Date: Thu May 7 17:36:13 2009 -0400 - - Merge mainline. - - Uses the minimal changes to get the new AVPacket API working. - - Conflicts: - libavcodec/avcodec.h - libavcodec/h264.c - libavcodec/mimic.c - libavcodec/options.c - libavcodec/utils.c - -commit 2c3cd96bf1cb1757407c973416f7928d492e2156 -Author: Alexander Strange -Date: Mon Aug 18 22:59:19 2008 -0400 - - Cosmetic rearranging of MPEG update_context functions - -commit 2cb0db5ba7d77ed8180f0551462c836047ea262e -Author: Alexander Strange -Date: Thu Jun 18 16:19:33 2009 -0400 - - Fix invalid Mimic stream handling + frame threads - - Releasing a frame after frame_setup_done isn't allowed, and - it must do report_decode_progress as if it was finished. - -commit 2d0370118996148f1c64b9c6b4a2ff632fcaf609 -Author: Alexander Strange -Date: Sun Aug 31 03:56:04 2008 -0400 - - Add fixme for copying packet data. - -commit 2e121780400cb6630a66a0b7bd3fe84ad539b882 -Author: Alexander Strange -Date: Fri Jul 11 18:21:08 2008 -0400 - - Increase the released buffer size to 16. H264 can release this many at an IDR, can other codecs have even more? - -commit 2e5a5baf540ae0d1ac16ae52f66254b7233aabf7 -Merge: 5d82241 31f0027 -Author: Alexander Strange -Date: Tue Mar 29 04:35:46 2011 -0400 - - Merge branch 'master' of git://git.libav.org/libav - - Conflicts: - libavcodec/dsputil.c - libavcodec/mpegvideo.c - libavcodec/snow.c - libavcodec/vp8.c - libavcodec/x86/dsputil_mmx.c - -commit 2e9d8893eac232b782b479378cf13d484ab9cc1e -Author: Alexander Strange -Date: Wed May 28 22:49:33 2008 -0400 - - Add thread.h - -commit 2eeab8f6ad07611e46b3377ddf73e1d7f1f2bb78 -Author: Alexander Strange -Date: Sun Aug 24 21:16:31 2008 -0400 - - General description and porting guide - -commit 2f1fec650f4bb351fa819fb7e11b4766a43fa30f -Author: Alexander Strange -Date: Tue Aug 19 01:20:32 2008 -0400 - - Simplify mimic_decode_end changes - -commit 2f48eac011767ba2d60329c10a22499c228a31d8 -Author: Alexander Strange -Date: Tue Nov 18 15:27:24 2008 -0500 - - Missed fixing pthread.c in merge. - -commit 2f8f77021011eec5af8cab80ee7bdc574ad3f37b -Author: Alexander Strange -Date: Fri Jan 21 03:01:42 2011 -0500 - - pthread: Style and comment nitpick for validate_thread_parameters() - -commit 300b5819426ed6b35aaa480502070382e5295111 -Author: Alexander Strange -Date: Sun Aug 17 14:07:06 2008 -0400 - - Copy aspect ratio info between contexts. - -commit 3029628ce39e37c9ae77cb78f22ab9d4846e6610 -Author: Alexander Strange -Date: Sun Aug 31 15:15:15 2008 -0400 - - Fix compiler warnings - -commit 303cd6307958792faac1ce8c8c81eea2651b002f -Author: Alexander Strange -Date: Thu Jun 19 18:31:17 2008 -0400 - - Use MPV_report_decode_progress in mpeg12, and call it before mb_y++. - -commit 30e540672df8523a47013d92592b744459040904 -Author: Alexander Strange -Date: Mon Oct 13 15:00:39 2008 -0400 - - Make every thread lock the same buffer_mutex for get_buffer. - - Otherwise it isn't actually protecting anything... - -commit 3106e8ebe7c55eba3e41f3a11cc23eb249a4ff3b -Author: Alexander Strange -Date: Mon Jul 14 23:09:47 2008 -0400 - - Always set thread_context[0] in MpegEncContext. - This fixes mpeg* encoders always crashing, but most of the regression tests are still failing. - -commit 3127a4bd6e36bb2d9cd2fe12a96fa776d94fed94 -Author: michaelni -Date: Sat Nov 2 10:47:44 2002 +0000 - - added BeOS net_server support (R5 network stack), basically the same - problems as with winsock (sockets != fd), and the broken select(). - based on older patch by Andrew Bachmann. - patch by (Fran -commit 314c2b1d2f94be3b6aca3dd1ae0f30c05f10f2ee -Merge: 9816b66 bd8850b -Author: Alexander Strange -Date: Tue Feb 17 22:41:31 2009 -0500 - - Merge branch 'master' of git://git.mplayerhq.hu/ffmpeg - - Conflicts: - - libavcodec/avcodec.h - libavcodec/mimic.c - libavcodec/mpeg12.c - libavcodec/mpegvideo.c - -commit 314e5630e389457319ff2d11e856fab6b1d8b250 -Author: benoit -Date: Mon Jan 7 12:47:14 2008 +0000 - - Move wmv1_scantable to .rodata section by making it an array of arrays. - Patch by Diego 'Flameeyes' Petten -� flameeyes commit 31e3f669b598302b2a487dab84e08bf4d1e79983 -Author: Alexander Strange -Date: Thu May 7 18:06:52 2009 -0400 - - Fix mplayer patch's calculation of extra delay. - - It's only (num_threads-1) frames with MT on, not num_threads. - -commit 31f1a603dcfe885c41d123832f102a3ccc55c6dd -Author: Alexander Strange -Date: Sun Aug 24 00:20:03 2008 -0400 - - Rename threading functions with 'decode' in their name - -commit 333777b56b942a11db5d672433357bcbbf0d6e47 -Author: Alexander Strange -Date: Tue Aug 19 01:14:48 2008 -0400 - - Cosmetic changes to mimic - -commit 33bc3cc94a5a6e2679306da899afb1e0ce6b78c6 -Author: Alexander Strange -Date: Thu Aug 14 14:01:15 2008 -0400 - - Reindent. - -commit 3444ffe523dd65b788791dfb2c6cbd7031cfec97 -Author: Alexander Strange -Date: Wed Aug 6 20:24:44 2008 -0400 - - Cosmetics: rename last_thread to prev_thread to avoid final vs. previous confusion. - -commit 344df336a0b5e70ef9fcea33f612f759bc045552 -Author: Alexander Strange -Date: Mon Apr 19 03:31:30 2010 -0400 - - Reindent - -commit 3547c7f44108f1080f90de1844c36fb172528994 -Author: Alexander Strange -Date: Sat Feb 20 19:40:48 2010 -0500 - - API simplification: remove ff_report/await_frame_progress() - - The field variants are enough. - Note that mpegvideo.c thread code doesn't need to support any codecs - with field pictures. - -commit 3630d89a7bd6443f9aeda2f6997fb2ea5da5c97d -Author: Alexander Strange -Date: Thu Dec 18 12:36:20 2008 -0500 - - Copy dequant4/8_buffer between H264 decoding threads. - - Fixes at least: - MSG00 ED.mkv - freedom EP1 sample.mkv - made with unknown encoders. - -commit 36977df5243521eaa3ab1b67f3c89d1a1ba4c8f7 -Author: Alexander Strange -Date: Mon Aug 18 22:03:25 2008 -0400 - - Move copying idct_algo to the right place - -commit 379271216e0d522b675e97189ab5d4e5cf7f5f70 -Author: Alexander Strange -Date: Mon Apr 19 03:35:28 2010 -0400 - - Update todo. - -commit 37b38ff868fa39f75df9c1bd543fd1c2dc7134ae -Author: Alexander Strange -Date: Sat Feb 20 20:31:16 2010 -0500 - - Update the comment for FF_THREAD_FRAME. - -commit 382e06ef4ba568c565b9d67b33b1688a32b2b80e -Author: Alexander Strange -Date: Tue May 11 06:21:06 2010 -0400 - - pthread: Use av_fast_malloc to allocate the frame buffer - - Also delete the FIXME; it's impossible because the AVPacket memory - API doesn't actually work. - -commit 3934d02026fb67b46441176c4160c0f854c12825 -Author: Alexander Strange -Date: Mon Jul 21 18:10:58 2008 -0400 - - Reindent. - -commit 39eee0b91b9b6b75c54ff68d51ecc0ba1816c88f -Author: Alexander Strange -Date: Sun Jun 22 03:36:24 2008 -0400 - - Multithreading support for MPEG-4 - This requires more parallelism barriers than usual because of the horrible skip MB structure in B-frames. - -commit 3ad85b1741ca6d36126bbf674f5b82d550107bae -Merge: ff4c627 4495490 -Author: Alexander Strange -Date: Tue Oct 6 16:12:06 2009 -0400 - - Merge branch 'master' of git://git.mplayerhq.hu/ffmpeg - - Conflicts: - libavcodec/avcodec.h - libavcodec/mpegvideo_enc.c - libavcodec/snow.c - libavcodec/vp3.c - -commit 3afd3f52b940d0bfa756e1a7496a20d103c5a7f0 -Author: Alexander Strange -Date: Fri Jul 25 03:25:00 2008 -0400 - - Merge MPV_update_picture_pointers() into its only caller. - -commit 3ba8143c5da92197eb45fa120bfa95b38adfd3bf -Author: michaelni -Date: Sat Nov 2 10:35:07 2002 +0000 - - added BeOS net_server support (R5 network stack), basically the same - problems as with winsock (sockets != fd), and the broken select(). - based on older patch by Andrew Bachmann. - patch by (Fran -commit 3bac11e47a0ec7c6036c53a1173bce276abccfeb -Merge: 53fff22 3d42d49 -Author: Alexander Strange -Date: Sat Apr 9 21:30:16 2011 -0400 - - Merge mainline. - - Conflicts: - libavcodec/h264.c - -commit 3bef1503e0f23c0f30c2e3b2de64a9b2618807d2 -Author: Alexander Strange -Date: Sat Jun 27 16:18:44 2009 -0400 - - Add debugging hooks to show ff_report/ff_await calls. - -commit 3c3a3648317737830fc863371b455624d093f8e6 -Author: Alexander Strange -Date: Sat Oct 18 17:39:17 2008 -0400 - - Fix possible null pointer access after seek. - -commit 3c7a8d94b97003b118c2438343d06ad7cf26198a -Author: Alexander Strange -Date: Tue Mar 9 00:04:51 2010 -0500 - - Reimplement VP3 multithreading. - - Synchronization is now not very fine-grained, because it reuses - vp3_draw_horiz_band which runs every ~64 pixel rows. - -commit 3cfd7b2e788c3d8e31c91ed529f3e3730f836395 -Author: Alexander Strange -Date: Mon Jun 23 23:14:05 2008 -0400 - - Wrong kind of #if. - -commit 3f7521893b9072181763ea176ef8da0c0ad1922a -Merge: ed42183 206c937 -Author: Alexander Strange -Date: Sun Oct 10 01:47:32 2010 -0400 - - Merge mainline. - - API change: CODEC_CAP_FRAME_THREADS is now defined as 0x800. - - Conflicts: - libavcodec/avcodec.h - -commit 3f858091f8f3cd43f1eed396e85f6956ee5068a0 -Author: Alexander Strange -Date: Tue Aug 19 02:35:52 2008 -0400 - - Fix losing frames at the end of an encode - -commit 3ffe81697018042b27a31f20c1d30c988b688d60 -Author: Alexander Strange -Date: Thu Jun 12 18:22:42 2008 -0400 - - Reindent. - -commit 401a6bc7f0fe26963f63778c5092ae96c4262634 -Author: Alexander Strange -Date: Thu Jun 25 19:07:58 2009 -0400 - - Frame threading for VP3 [1/2] - - update_context function and compatibility fixes. - -commit 40265f10de7698bb2fe23857cf261a0f04fe18a1 -Author: Alexander Strange -Date: Mon Oct 13 14:19:27 2008 -0400 - - Fix edge drawing for non-mod-16 files. - -commit 4074c8bfba918988029ce106eda3d41486f12966 -Author: Alexander Strange -Date: Sat Jul 12 00:11:35 2008 -0400 - - Copy more MpegEncContext variables. - These are needed for proper DivX/H.264 decoding. - -commit 40ffd3a664e36f44ebdf4d2603e42c7c59502599 -Author: Alexander Strange -Date: Thu Jul 23 21:40:06 2009 -0400 - - 100l, fix compile error introduced by automerge - -commit 4118a72e28be1cee657561a1f45dc3ce160dbf07 -Author: Alexander Strange -Date: Thu Mar 10 02:46:14 2011 -0500 - - Update todo.txt - -commit 41e0f81a58493a0a15cb18c7ff00920f0fd124a3 -Author: Alexander Strange -Date: Sun Aug 24 02:52:18 2008 -0400 - - Remove unneeded stubs from thread.h - -commit 4259f9fcf4edc5c92bc02d37d85493b3eb917075 -Merge: 2615129 fb61692 -Author: Alexander Strange -Date: Tue Nov 2 02:36:20 2010 -0400 - - Merge branch 'master' of git://git.mplayerhq.hu/ffmpeg - -commit 4293f5ba301cd751257705bfe6fc8b12337dccab -Author: Alexander Strange -Date: Mon Jul 14 23:20:17 2008 -0400 - - Disable multithreading for packed B-frames. - The bitstream buffer is updated after decoding, so it has to be changed to find the frame end before starting the actual decode. Assuming that's not too slow. - -commit 42b521db9177ed2d4e62845659fdcd44c59757f9 -Author: Alexander Strange -Date: Fri May 8 00:40:57 2009 -0400 - - 10l: dequant_coeff must be copied along with dequant_buffer - - Fixes more Blu-Ray streams which change CQM, including Slumdog - Millionaire. - - Noticed by Haruhiko Yamagata. - -commit 435ace7689e2794ddbb4013de097bdaf487f7365 -Author: Alexander Strange -Date: Sat Apr 9 21:47:12 2011 -0400 - - Update test scripts to use ffmpeg instead of ffmpeg_g - -commit 435adcd213762869c6a6f806481450216720b364 -Merge: 6ee99a7 11dcccd -Author: Alexander Strange -Date: Thu Mar 10 01:25:24 2011 -0500 - - Merge remote-tracking branch 'socrep/last_mainline_point' into last_git_point - -commit 451af22792e7bec6f3b347ba801ba186102a85da -Author: Alexander Strange -Date: Mon Jul 14 04:13:33 2008 -0400 - - Call draw_edges per-MB-row instead of per-frame when possible. - This is necessary for multithreading, since rows aren't complete until their edges are mirrored. - It should also be somewhat more cache-efficient, but I haven't benchmarked it properly yet. - I don't like adding new MpegEncContext variables, but edge_y lets it do the right thing wrt. error resilience and codecs that don't call ff_draw_horiz_slice. - -commit 452fb04633126605afbb2cd0d6383bb75fe01f38 -Author: michaelni -Date: Fri Nov 8 20:54:44 2002 +0000 - - ringbuffer patch by (Fran -commit 4681ac8f618586d4a3ecb04784b9cf896d070f1b -Author: Alexander Strange -Date: Tue May 11 14:43:29 2010 -0400 - - Cosmetics: vertical alignment - -commit 468eba33060aa87117ac6b617d4eae776951cbf6 -Merge: 3c7a8d9 aa86abc -Author: Alexander Strange -Date: Tue Mar 9 00:55:42 2010 -0500 - - Merge mainline. - - The error condition in vp3_decode_frame was uglified to make the - diff simpler. - - Conflicts: - libavcodec/vp3.c - -commit 46a45ad599db4037006b335fca2c7b7bed7018ab -Author: Alexander Strange -Date: Sat Aug 2 00:22:16 2008 -0400 - - Clear thread variables in avcodec after freeing them. - -commit 46b495ebc4a7fb7662580791e4ed10130b00fead -Author: Alexander Strange -Date: Thu Jun 12 17:16:31 2008 -0400 - - Don't allocate duplicate contexts if they're not going to be used. - -commit 46ec6b90e7b2d6b1d83a207025a691c56176d686 -Author: Alexander Strange -Date: Mon Jun 16 18:21:04 2008 -0400 - - Multithreading support for MPEG-1. - -commit 46fc25f5c225e2f33430e31a0d0ad375455e9cef -Author: Alexander Strange -Date: Mon Nov 1 12:20:12 2010 -0400 - - Update todo.txt - -commit 473799e0c3b647d73046c3b4de30e85bf57ba610 -Author: Alexander Strange -Date: Tue Aug 19 21:16:59 2008 -0400 - - Whitespace fix - -commit 47869edb7f0aede0a2bfd178ef9937e28bf8b01f -Author: Alexander Strange -Date: Sun Feb 14 23:41:12 2010 -0500 - - Fix buffer leak in VP3 by allowing update_context() with the same context. - - I assumed update_context() would only be used to copy values, so skipped - calling it with duplicate parameters (during flush and free) for optimization. - - But VP3's release_buffer call was moved from the end of decoding to the - end of update_context(), so flushing would skip releasing a frame and - eventually run out of buffers. - - Unfortunately this makes update_context() much uglier in codecs that - already worked, because memcpy doesn't allow src and dst to be the same. - -commit 480a82da7912bc5034a4b0bc2090879920567521 -Author: Alexander Strange -Date: Thu Sep 30 01:13:43 2010 -0400 - - Update todo. - - ffplay/ffmpeg support for better a/v sync support is in progress. - If Theora uses PTS (I think it does), then once ffmpeg.c i - ready it can be submitted to mainline. - -commit 4845b04ed3d6bc513a272da718629d110bc8186f -Author: benoit -Date: Mon Jan 7 12:43:04 2008 +0000 - - Mark the tables in g726.c as constant. - Patch by Diego 'Flameeyes' Petten -� flameeyes commit 485d8e9e3c5de803075c8440922e6e09b10a1e57 -Author: Alexander Strange -Date: Sun Sep 14 20:45:58 2008 -0400 - - Fix ff_report_*_progress side of H264 multithreading and merge draw_horiz_band into it. - -commit 4874d258345ec305b0eca78c41491878d42a900d -Author: Alexander Strange -Date: Tue May 11 14:45:39 2010 -0400 - - Cosmetics: reorder variable declarations - -commit 48d2183d902db7cc42c9f84d2bad6eccc35d0221 -Author: Ronald Bultje -Date: Mon Apr 11 14:58:11 2011 -0400 - - Release unused pictures even when not calling ff_h264_frame_start() - - Unused pictures assigned to the thread can build up and cause it to - run out of buffers if the thread only ever decodes bottom field pictures. - -commit 48d7f5a8f3f14535d74f0e4b0a736e3f5dc336b2 -Author: Alexander Strange -Date: Mon Aug 18 19:58:18 2008 -0400 - - Factor out freeing delayed released buffers. - -commit 49652059c673eb977e5b69ffb0c8a543c3210e16 -Merge: a2efd25 48e59eb -Author: Alexander Strange -Date: Sat Jan 15 17:01:41 2011 -0500 - - Merge mainline. - - Conflicts: - doc/APIchanges - libavcodec/avcodec.h - libavcodec/h264.c - libavcodec/utils.c - -commit 4969bb89e592c003a560e321f3cacb412a192db9 -Author: Alexander Strange -Date: Thu Jul 31 14:30:40 2008 -0400 - - Copy avcC variables in H264Context. - -commit 496ec27adcef84278e650b29f4d22aba383d705a -Author: Alexander Strange -Date: Sat Sep 13 16:20:03 2008 -0400 - - Correct interlaced draw_edges. - - There is still a race condition when fields are decoded in different threads, - so for now we pretend EMU_EDGE is set instead of using the edges. - -commit 498ddbb3b2d78819540c1b8fff9a2bc495a33346 -Merge: aaa05da 95b6213 -Author: Alexander Strange -Date: Wed Nov 3 18:34:04 2010 -0400 - - Merge mainline. - - Conflicts: - libavcodec/avcodec.h - -commit 49e377f9f23904ed790e98175b1575bba6ecc6cb -Author: Alexander Strange -Date: Tue Jul 15 03:30:28 2008 -0400 - - Add update_context() for H.264. - This seems to lose reference frames for my PAFF sample, which I'll fix after I find out how PAFF works. - -commit 4adb7fbed7dcb12dda0f3919188334a3b96efb0a -Author: Alexander Strange -Date: Mon Aug 18 20:02:12 2008 -0400 - - Cosmetics: get rid of unhelpful comments, useless braces, and some whitespace/align issues - -commit 4af5480a021156089c193ce2215994cfd170e4e6 -Merge: 2f48eac 1bf5327 -Author: Alexander Strange -Date: Fri Nov 28 22:48:24 2008 -0500 - - Merge mainline. - - Conflicts: - - libavcodec/h264.c - libavcodec/mpegvideo_enc.c - -commit 4b9ce55576ab27f6a45d542bfda7c1e21fb967f8 -Merge: 1fae9e9 435adcd -Author: Alexander Strange -Date: Thu Mar 10 01:54:16 2011 -0500 - - Merge branch 'git_equiv_of_mainline' - -commit 4c726e5e30e1f48619eecbec5442acd63e895318 -Author: Alexander Strange -Date: Wed May 28 22:40:30 2008 -0400 - - Rename pthread.c to thread.c - The remaining *thread.c files will be merged into it later. - -commit 4c802e44f13672dd4527f51fc2f07a1e21be4a5c -Author: Alexander Strange -Date: Mon Jun 2 04:31:45 2008 -0400 - - Simplify ff_await_decode_progress. - - Always set and allocate the progress pointer, so ff_await_decode_progress doesn't have to check for threading to be on. - -commit 4cdd15a3cf5dfec32ace278cd445f04130ddbee0 -Author: Alexander Strange -Date: Sat Jan 15 19:26:14 2011 -0500 - - pthread: Call external get_buffer() on the client's thread by default - - This fixes several mplayer VOs that crashed when they were called from decoding - threads. - - Not a complete fix as mplayer still doesn't work right with draw_horiz_band() - being called from decoding threads, but that doesn't crash at least. - -commit 4d2f536b72ec9121b5afe858b69c93d9cc75f20a -Author: Alexander Strange -Date: Sat Aug 30 04:20:20 2008 -0400 - - Simplify draw_edges changes by removing edge_y (which is useless with slices) - -commit 4d8525ab388d34e128629b08ab88c6a16f3aa406 -Author: michaelni -Date: Sun Jul 21 07:59:17 2002 +0000 - - nanosleep patch by Fran -commit 4edb9a7f780a6eaef36512724e6a34c3f38d67ce -Author: Alexander Strange -Date: Mon Feb 15 00:31:31 2010 -0500 - - Disable mpeg1 frame threading. - - Seeking doesn't work (it triggers false error conditions) and it doesn't - pass test.sh (-threads 2-4 match but 1 doesn't somehow). Will be reenabled - when those are fixed. - -commit 4f9364563f388af84b9a02930b375ff52eee1394 -Merge: 3bac11e 347b375 -Author: Alexander Strange -Date: Sat Apr 9 21:30:47 2011 -0400 - - Merge branch 'master' of git://git.libav.org/libav - -commit 4fb1fdf1ca1a48aff176b8f833ca596d245d6d36 -Author: Alexander Strange -Date: Tue Jul 15 03:30:50 2008 -0400 - - Reindent. - -commit 4fb33e68ec34cbc135ce4ebb86f7e1399ba97115 -Author: Alexander Strange -Date: Mon Jun 23 22:11:58 2008 -0400 - - Merge statements. - -commit 5022ee29ac6d4b2ee992115c3bf997e7bd1ab7a4 -Author: Alexander Strange -Date: Thu Jun 5 20:30:27 2008 -0400 - - Add delayed_release_buffer for handling reference frames. - -commit 5066a4656963dd3b4e847a540353bf71d318de14 -Author: michaelni -Date: Tue Nov 5 00:07:05 2002 +0000 - - lrintf detection (based upon a patch by Fran -commit 50d1ce2db57e39b6115642d3c4397e9f67f758e3 -Author: Alexander Strange -Date: Sun May 24 00:08:03 2009 -0400 - - Call codec init at a more reasonable time. - - Previously it was delayed until the first decode_video() call, - but it can be moved into avcodec_thread_init(). This makes pix_fmt - available to clients after init again, which should make them happier. - -commit 50eaf4979eb085e2c58c06912bb0c885404d4470 -Author: Alexander Strange -Date: Thu Aug 28 17:39:28 2008 -0400 - - Simplify changes to non-pthreads and don't call thread_init from open if it was already called. - - This will cause an assert failure if clients call thread_init again after open. - -commit 51428e56c71512a57f81d85acee3ced7cc0d2983 -Merge: 00425e9 03586fd -Author: Alexander Strange -Date: Sat Jul 4 16:41:31 2009 -0400 - - Merge branch 'master' of git://git.mplayerhq.hu/ffmpeg - -commit 517d68c2642aee3c14fc71031c1e44c0803a664e -Author: Alexander Strange -Date: Mon Mar 8 04:43:06 2010 -0500 - - h264: change the definition of col_fieldoff to avoid divisions - -commit 5186276ed120294fb6a4f2cf5a40d5019012482f -Author: Alexander Strange -Date: Sun Jan 16 22:01:18 2011 -0500 - - libavfilter input_get_buffer is thread-safe - - Slightly faster ffplay playback - -commit 51ead6d2c40c5defdd211f435aec49b19f5f6a18 -Author: Ronald Bultje -Date: Mon Apr 11 10:14:38 2011 -0400 - - h264: Fix decoding race condition with PAFF - - A thread can release a Picture and immediately reuse the same Picture - for a different frame. This is fine, unless the picture released was - a field-picture. In that case, there may be a future thread still decoding - the second field of the picture, and reusing it overwrites the shared fields - in the Picture. - - Fixed by tracking ownership of Pictures and allowing it to be reassigned - to the second thread's context. - - Fixes conformance sample HPCAMAPALQ_BRCM_B.264. - vsync still fails, and therefore FATE does as well. - -commit 521f07e3cf2dfb9b0473027ae2fbb6bd4f203ce4 -Merge: 7d0709e 4a8d06e -Author: Alexander Strange -Date: Sun May 31 00:08:08 2009 -0400 - - Merge mainline. - - Conflicts: - libavcodec/avcodec.h - -commit 52b214211060b56e7aac6b9743fa27bc79f789d1 -Author: Alexander Strange -Date: Wed May 28 02:15:47 2008 -0400 - - Enable multithreading for Mimic. - -commit 5323bc6e8adbff2b6849a08e9e071f22241fd807 -Author: Alexander Strange -Date: Sat Feb 20 22:48:51 2010 -0500 - - Cosmetics: add () to function name - -commit 5340d1ffae10b1545d88b9dd8ca86a5a3aaffca7 -Author: Alexander Strange -Date: Wed May 28 02:15:47 2008 -0400 - - Enable multithreading for Mimic. - -commit 534516ac79adc69d8773ff934955532a92db2cf1 -Author: Alexander Strange -Date: Sat Aug 16 00:01:07 2008 -0400 - - Fix a memory corruption bug in update_context and reenable H264 multithreading. - -commit 535de6d374ab6b06041f5e3cb392327abd2ce054 -Merge: 6abde3d cc8161e -Author: Alexander Strange -Date: Tue May 11 04:08:37 2010 -0400 - - Merge mainline. - -commit 5380fee33a871580fe9f3424767eaf2362c8cde0 -Merge: ef2d866 08c0efd -Author: Alexander Strange -Date: Sun Jun 13 23:43:37 2010 -0700 - - Merge mainline. - -commit 538a29e12f115390a64ceb3d4909a4a67cad26cd -Author: Alexander Strange -Date: Tue Aug 19 15:48:55 2008 -0400 - - Make diff smaller - -commit 53c86e82af6757c12df3a99aede6862a311f050b -Merge: fa8a82e ae2df26 -Author: Luca Barbato -Date: Sat May 3 16:13:06 2008 +0200 - - Merge branch 'master' of git://git.mplayerhq.hu/ffmpeg - -commit 53cd195c8885125351a03cfb6f1d93e66d433b86 -Author: Alexander Strange -Date: Mon Nov 15 05:00:01 2010 -0500 - - Rewrite multithreading.txt - -commit 53fff221cdb9f18df2f2f52bd48731ce0fa9e114 -Author: Maksym Veremeyenko -Date: Wed Mar 30 13:20:23 2011 +0300 - - mingw32 compilation after 'unbreak avcodec_thread_init' - -commit 5402adfa2e9c159e7d13ee07e142cb035a77ef95 -Author: Alexander Strange -Date: Tue Dec 16 16:54:20 2008 -0500 - - Only write to stderr once for each av_log(). - - This makes logging somewhat easier to read with multiple threads. - -commit 541d79def90226cc9b17e6ccc9eb2ff2549bea46 -Author: Alexander Strange -Date: Fri May 15 17:54:20 2009 -0400 - - Remove useless volatile qualifiers - - All such accesses must be protected by a mutex anyway, which is - already a memory barrier, so this doesn't change anything (assuming - a working compiler). - -commit 544c6a6709833f1a449b8faf4478ab529e269240 -Author: Alexander Strange -Date: Sun Mar 29 02:28:29 2009 -0400 - - Frame threading support for HuffYUV decoding - -commit 54c0c3d2ce69606a5aa508659d3322f48ada77cb -Author: Alexander Strange -Date: Wed Sep 3 11:59:59 2008 -0400 - - Call decode_postinit from the right place to avoid race conditions - -commit 552a89508fddc64d4217b9d845e458f504b63593 -Author: Alexander Strange -Date: Sat Jun 27 15:22:52 2009 -0400 - - Print md5s of test output files in test.sh. - -commit 55c511eedb24ffb09aef7072c02e911576c9900b -Author: Alexander Strange -Date: Mon Jan 25 02:47:19 2010 -0500 - - Did a todo item - -commit 574d2e5b942aa1e093bf768cc6321f3b081d3aeb -Author: Alexander Strange -Date: Sat Jul 5 23:36:08 2008 -0400 - - Merge enum with its only use. - -commit 578f45c15026e778ef54694d98a9ec446810a897 -Author: Alexander Strange -Date: Sun Jun 15 17:42:56 2008 -0400 - - Reindent. - -commit 5918efedbb7928031b6af745acb8b4233c08fb06 -Merge: 7d09b68 c2a400d -Author: Alexander Strange -Date: Thu Aug 14 21:37:03 2008 -0400 - - Merge branch 'mainline' - -commit 59d787ffccaf42e992229649c23e624ea7d71635 -Author: Alexander Strange -Date: Mon Nov 15 05:39:12 2010 -0500 - - Delete os2thread.c which is gone from mainline - -commit 5a7146bf75a2170f33ff25b88b91f667574d2919 -Author: Alexander Strange -Date: Wed Aug 11 01:33:20 2010 -0700 - - vp3: Fix a crash decoding files with -Date: Fri Apr 1 19:19:34 2011 -0400 - - pthread: validate_thread_parameters() ignored slice-threading being intentionally off - -commit 5b7c668d1f64facfe8b9f86e2491085595fa9bc7 -Author: Alexander Strange -Date: Tue Aug 12 20:26:26 2008 -0400 - - Document thread-safety requirements for user callbacks in AVCodecContext. - -commit 5bacdcc1a52e2b1d32bad9e9f250ceb6cc37f366 -Author: Alexander Strange -Date: Sat Oct 11 15:40:47 2008 -0400 - - Fix progressive height values in avail_motion() - -commit 5c46573ed07b092aea0db6560ade77bc299c28cb -Author: Alexander Strange -Date: Mon May 25 22:16:23 2009 -0400 - - Whitespace error - -commit 5c4c8ed51da0be4f141a4de339db77f4a0a6c783 -Author: Alexander Strange -Date: Mon Sep 1 03:18:55 2008 -0400 - - Remove unused variable - -commit 5d3c2f7512746dd0adf067952ed38d8111d7571d -Merge: 7041a16 5a70b15 -Author: Luca Barbato -Date: Sun Jul 6 12:38:18 2008 +0900 - - Merge branch 'master' of git://git.mplayerhq.hu/ffmpeg - -commit 5d53ada4cbd323d66b61965b1442d0abd63361b2 -Author: Alexander Strange -Date: Sun Jan 24 17:00:18 2010 -0500 - - Don't load PerThreadContext until it's needed in ff_await/report_*. - - Should avoid crashes if anything calls them without using ff_get_buffer. - -commit 5d7dfbb887f263b036224bf4510db176fa6cff73 -Author: Alexander Strange -Date: Mon Jun 16 18:18:53 2008 -0400 - - Utility functions for mpegvideo threading. - -commit 5d82241b49a1fb1dbecd1b279045cce9f099c775 -Author: Alexander Strange -Date: Thu Mar 24 03:34:48 2011 -0400 - - Update todo. - -commit 5eb0c649c780e26a77085bd213f945d88761ad00 -Author: Alexander Strange -Date: Mon Jan 4 04:12:44 2010 -0500 - - Make ffplay -drp the default. - - Ignoring reordered/delayed PTS never works with frame threading. - This may be changing behavior too much; I haven't tested this - with non-mt files, but I think the current behavior must cause - A/V desync even there. - -commit 5eb679f0fff432ba2c9e0cdada254dbe4bd4a45d -Author: Alexander Strange -Date: Mon Nov 15 02:53:14 2010 -0500 - - Remove width/height changing checks from h264/mpeg12 - - These should be moved to pthread.c update_context_from_thread() if they're needed, - not kept in specific codecs. Hopefully the error return from get_buffer() is - enough to make it not crash anyway. - -commit 5edf2cc5acbb410ba50a3770e8565fb39206f406 -Author: Alexander Strange -Date: Mon Jun 16 18:20:54 2008 -0400 - - Multithreading support for mpegvideo decoding in general. - -commit 5ef4af7de47c3913ddc1e09e43887ac04ecfaba3 -Author: Alexander Strange -Date: Sun Jun 15 01:58:15 2008 -0400 - - Fix ff_delayed_release_buffer crashing with slice-threading. - -commit 604ee5471f21d310f4014011a20c00c28a31995b -Merge: 3792712 7838828 -Author: Alexander Strange -Date: Wed Apr 21 22:04:21 2010 -0400 - - Merge branch 'master' of git://git.mplayerhq.hu/ffmpeg - -commit 607edd221a3b7a300fbaa4a5495ffd30f8dc9fa8 -Author: stefano -Date: Mon Jul 26 14:30:47 2010 +0000 - - Define static functions fill_image_linesize() and - fill_image_data_ptr(). ff_fill_linesize() and ff_fill_pointer() now wrap - these functions. - - The new functions are more generic, and are going to be exported in a - future patch. - - Patch by S.N. Hemanth Meenakshisundaram smeenaks # ucsd commit 60be6c15c4d23c5107f14e408043988918a44c76 -Author: Alexander Strange -Date: Sat Jun 20 16:07:58 2009 -0400 - - Add a valgrind script so I don't have to type it all the time. - -commit 614d2308b343ec6af6bf72ada08884684bb66df0 -Author: Alexander Strange -Date: Wed Sep 3 22:55:22 2008 -0400 - - Update header guard - -commit 62830f5772dd8971032aa9f8d52a8f6c00c92487 -Author: Alexander Strange -Date: Thu Jul 17 19:04:19 2008 -0400 - - Remove next_delayed_pic, it doesn't prevent any race conditions. - - This part is now entirely out of sync with mainline. - -commit 62ba7a4acc98b691ab3152356cf0c21a52f7e03b -Author: Alexander Strange -Date: Sun Jun 15 19:22:41 2008 -0400 - - Fix the main thread hanging if there's an error before all of the frame is decoded. - -commit 63d086d2585d3275a6b9068ee1ca957617ecf902 -Merge: 314c2b1 712afbf -Author: Alexander Strange -Date: Wed Feb 18 21:29:44 2009 -0500 - - Merge branch 'master' of git://git.mplayerhq.hu/ffmpeg - -commit 63f663f09320851b9ed76f489fdab590da2fc7f0 -Merge: 64df3aa d61efce -Author: Luca Barbato -Date: Sat May 10 07:51:22 2008 +0200 - - Merge branch 'master' of git://git.mplayerhq.hu/ffmpeg - -commit 63ff6aa525faf65f86dfbc8ec571fd260844100f -Author: Alexander Strange -Date: Sat Oct 23 18:07:14 2010 -0400 - - Don't set avctx->thread_count to 0 in avcodec_thread_init. - - h264 crashes during decode init with 0 (instead of 1) threads. - Note that this isn't a regression from -mt, but is actually a bug present in mainline. - - -threads 0 should preferrably set auto threads, but doesn't. - -commit 641f2752c16aaa25c5854d34726b72f226003b87 -Author: Luca Barbato -Date: Sat May 3 12:20:42 2008 +0200 - - Ignore stuff - -commit 6446d2b0931c6a9637077b18b98af911d438057f -Author: Alexander Strange -Date: Thu May 7 01:38:16 2009 -0400 - - Update mplayer.diff line numbers to match mplayer r29269 (20090505) - -commit 647f6cf3144934e3c2c22b06601d23a1217a2b86 -Author: Alexander Strange -Date: Sat May 23 20:09:07 2009 -0400 - - H264: Print an error instead of failing silently for size changes with slice threads. - -commit 64df3aa6a32a87d96f650b8535c88e1d65b52524 -Merge: 53c86e8 72c8992 -Author: Luca Barbato -Date: Sun May 4 22:24:35 2008 +0200 - - Merge branch 'master' of git://git.mplayerhq.hu/ffmpeg - -commit 65b3e34fc8a52f4f1a48fce7c8cddd80db8fade9 -Author: Alexander Strange -Date: Mon Nov 1 12:20:24 2010 -0400 - - Update the test script to show results more clearly - -commit 65e8486a1dd1efbf2750d0bc25c326f8dc836bcd -Author: Alexander Strange -Date: Sun Mar 29 03:10:53 2009 -0400 - - Fix nonsense 2am code - left the huffman tables uninited. - - It would be faster to copy the VLCs but it would require more code. - And this could be factored into another function. - -commit 661ca4010c548e135ce1c0c819d0c05a94b66985 -Author: Alexander Strange -Date: Fri Jul 10 14:32:04 2009 -0400 - - Cosmetics: get rid of pointless parameter. - -commit 66204771dd8e479d30ef71ad85c162e1a34e4104 -Merge: 3f75218 76dd0e7 -Author: Alexander Strange -Date: Sat Oct 23 17:41:42 2010 -0400 - - Merge mainline. - - Conflicts: - libavcodec/avcodec.h - libavcodec/options.c - -commit 66a34dee4443dd6ccabb53ca09a1c45bc95f4d24 -Author: Alexander Strange -Date: Tue Aug 12 00:39:28 2008 -0400 - - Don't run the last part of decode_update_context() when the last frame was dropped. - - This fixes mplayer -framedrop crashing. Of course, they're still run in some cases when it wouldn't be without threads, but those are all error conditions. - -commit 66cf3f781d73fed502d80cce01dbd16b25bc3a71 -Author: Alexander Strange -Date: Sat Aug 2 19:27:12 2008 -0400 - - Correct 6b037a88 for PAFF/MBAFF. - -commit 66d9c0c9f6b2a4309dd4a41f88dd9a1dccb323e3 -Author: Alexander Strange -Date: Sat Aug 23 19:56:21 2008 -0400 - - Wait for predecode to finish just before calling update_context, instead of as soon as possible. - -commit 66ef4712c357514602f6b47311874e9ebf7376e3 -Author: Alexander Strange -Date: Wed Jun 4 15:57:36 2008 -0400 - - Handle zero-byte input correctly. (for CODEC_CAP_DELAY) - -commit 68682144289b05c830fd64a651526c4708666874 -Author: Alexander Strange -Date: Tue Aug 19 04:08:42 2008 -0400 - - Fix accidentally calling execute_ref_pic_marking() while draining delayed_pics at the end. - -commit 686ea24614fded4d7501f71901aae61f5160f018 -Author: Alexander Strange -Date: Sun Jan 16 22:15:28 2011 -0500 - - Update APIchanges to match mainline_patches branch - -commit 68ef172444124e9e6dd2a69df00ae72a64e795cb -Author: Alexander Strange -Date: Tue May 11 05:34:20 2010 -0400 - - Pass the complete AVPacket through pthread.c decoding - - Part of a patch from VLC. - -commit 6913bf9451bdaef16cd7748c93358baeec57d33b -Author: Michael Niedermayer -Date: Wed Apr 6 00:14:56 2011 +0200 - - Fix REBASE_PICTURE with h.264 - - It was possible for last_picture_ptr to point into h.ref_list - instead of h.s.picture, which caused a bad pointer to be set. - Fixes some valgrind warnings, presumably improves behavior but - no changes were found. - -commit 6998f46dec036f2ab39d6389747a95a7f5808f19 -Author: Alexander Strange -Date: Sat Feb 20 22:32:39 2010 -0500 - - Cosmetics: Rename init_copy and update_context to have 'thread' in the name - -commit 69f085cebf61a64352e623d3c4a5d6032329473d -Author: Alexander Strange -Date: Wed Jun 10 11:33:47 2009 -0700 - - Don't change avctx->thread_count if frame_thread_init() fails. - -commit 69f6e77a9a9ddfc386d43f5a350df5c960c0203d -Author: Alexander Strange -Date: Sun Aug 24 04:11:52 2008 -0400 - - Remove useless check - -commit 6a26fe72383c0ab088c8d92733221bf2911231ce -Author: Alexander Strange -Date: Fri Oct 17 14:45:47 2008 -0400 - - Fix nonsense logic in copy_parameter_set() - -commit 6a3821cf92ef5aaba020a0b7c8d06df5926bd362 -Author: Alexander Strange -Date: Tue Jun 3 04:13:55 2008 -0400 - - Merge statements in mimic. - -commit 6abde3d9e6ccfb062c6f547334171665386b0d85 -Merge: d8014c6 4448f8c -Author: Alexander Strange -Date: Fri May 7 04:42:38 2010 -0400 - - Merge mainline. - - Conflicts: - libavcodec/avcodec.h - libavcodec/options.c - -commit 6ae441be729df8064f1b1244acc82fead9cb1918 -Author: Alexander Strange -Date: Tue Aug 19 01:27:54 2008 -0400 - - Reduce code duplication in MPV_lowest_referenced_row - -commit 6b037a889a34f8f2dd8ad188cda6f4d09d9f4710 -Author: Alexander Strange -Date: Sun Jul 27 00:58:54 2008 -0400 - - Avoid a deadlock in damaged streams where the current picture ends up in h->ref_list. - -commit 6b5aa5cb4d105c4ed118d5ea07f64bbe1e94d135 -Author: Alexander Strange -Date: Sat May 23 23:10:33 2009 -0400 - - Remove inaccurate comment. - - ff_report_frame_setup_done() is called properly for the first field. - -commit 6c575595d9d0e2974e326ad86db61bb61163753a -Author: Alexander Strange -Date: Tue Aug 19 21:01:51 2008 -0400 - - Add flag for thread algorithm - -commit 6d4679e9d5fedff6aa1eed964aa1449716f02682 -Author: Alexander Strange -Date: Wed Jan 20 02:17:36 2010 -0500 - - Add a FIXME comment to a commented-out part of h264.c. - -commit 6e508a7ab927ce7280688d822d3529dfbf17ec88 -Author: Alexander Strange -Date: Thu Sep 4 17:40:59 2008 -0400 - - Fix field progress allocation. - -commit 6fad2f2300fb9e6288d4c9cdf3028d07d3dd63a9 -Author: Alexander Strange -Date: Mon Jan 17 15:41:20 2011 -0500 - - pthread: Fix missing mutex unlock in error condition - - Also remove stray ; - -commit 700a6622f378b5169d8d54ea5bdb4d8b67262a22 -Author: Alexander Strange -Date: Tue Jun 24 23:29:40 2008 -0400 - - Merge another ++. - -commit 701ddc74e17de9f76eabf00a9e8d16adac7c2954 -Author: michaelni -Date: Tue Nov 5 00:38:06 2002 +0000 - - BeOS Audio ouput patch by (Fran -commit 7041a164baed1c643f0cfa1207fbb2fd06d81f38 -Merge: 84cde2e 483385a -Author: Luca Barbato -Date: Sun Jun 29 16:34:45 2008 +0900 - - Merge branch 'master' of git://git.mplayerhq.hu/ffmpeg - -commit 70595dcbdbc01bb1f8f331c0998ee11f04577091 -Author: Alexander Strange -Date: Sun Jan 24 17:33:22 2010 -0500 - - unnecessary freep - -commit 706e94d6531daa0b179613dbef51af8ec5bbe1dd -Merge: 7e928f6 e42b282 -Author: Alexander Strange -Date: Sat Jul 17 18:47:45 2010 -0700 - - Merge mainline and swscale. - - One valgrind test currently fails. - - Conflicts: - libavcodec/avcodec.h - libavcodec/beosthread.c - libavcodec/h264.c - libavcodec/options.c - libavcodec/os2thread.c - libavcodec/utils.c - tests/ref/vsynth1/rgb - tests/ref/vsynth1/yuv - tests/ref/vsynth2/rgb - tests/ref/vsynth2/yuv - -commit 70bf5912700d0519f3d607784654c394633effac -Author: Alexander Strange -Date: Wed Jun 18 21:58:17 2008 -0400 - - Add an mpegvideo wrapper around ff_report_decode_progress. - -commit 70fb3fdcf2c5f01a555d87f8113efb50286493f7 -Merge: 1d15df4 0b034be -Author: Luca Barbato -Date: Mon Jun 9 18:03:54 2008 +0200 - - Merge branch 'master' of git://git.mplayerhq.hu/ffmpeg - -commit 71419720215a7ca7d1b1780564f21cb51d9df0a2 -Author: Alexander Strange -Date: Wed Aug 6 15:45:52 2008 -0400 - - Copy all the MPEG-2 interlacing flags, as well as *_picture, in ff_mpeg_update_context(). - -commit 73608e1fa14434599aab86d2198a05ec4ca21c59 -Merge: a5285ae 6a7ac9c -Author: Alexander Strange -Date: Wed Sep 16 14:38:47 2009 -0400 - - Merge branch 'master' of git://git.mplayerhq.hu/ffmpeg - - The definition of CODEC_CAP_FRAME_THREADS changed, but - clients shouldn't have had to check it for anything. - -commit 73ad08d3b0867db89e5a81b9aec44b053e855ab3 -Author: Alexander Strange -Date: Thu Mar 24 03:31:14 2011 -0400 - - Draw edges in MPV_frame_end when encoding - - These pictures don't get draw_horiz_band called on them. - I thought I had tried this, but after thinking about it realized I'd made - a typo the first time. - - Fixes make test. - -commit 74f382ae597d9cf69c885bc03c716d18fdbd413c -Author: Alexander Strange -Date: Mon Mar 16 23:12:44 2009 -0400 - - Disable frame threading for MPEG-4 - - It seems to have problems with packed B-frames in mplayer. - I don't know if any other players work (at least ffplay does). - -commit 753aecc29f8f4727326f0f371fa99fefbc369d0c -Author: Alexander Strange -Date: Tue Jul 15 02:58:51 2008 -0400 - - Lift H.264 display-order code before decode_slices. - This is needed for multithreading and should get us closer to CODEC_CAP_DRAW_HORIZ_BAND. - -commit 759176e401ebe8911e071f860f59b05d482315d0 -Author: Alexander Strange -Date: Thu Mar 10 02:36:33 2011 -0500 - - Reorder picture_count in mpegvideo to fix ARM asm - -commit 75d4208c3a6ea4b9973b05ce930258ca8c3db224 -Author: Alexander Strange -Date: Wed Jun 25 01:06:31 2008 -0400 - - Disable mbskip copy avoidance harder with threads on - Fixes seeking in mpeg4. - -commit 76211d5890819ae687cc73520bcda17115a65697 -Author: Alexander Strange -Date: Sat Aug 23 23:14:10 2008 -0400 - - Update threading comments in avcodec.h - -commit 776e2fc2d7df09d184caf414cb1d93829fe1c38d -Author: Alexander Strange -Date: Tue Mar 9 01:11:58 2010 -0500 - - Fix missed things in previous VP3 commits - - Optimization improvements only, because the pessimizations hid the bugs. - -commit 77f7818ac7b881a5aa024e31147255ed3a413141 -Author: Alexander Strange -Date: Sun Jan 24 19:00:24 2010 -0500 - - Fixed memory leak in todo - -commit 78c5ca40fac2dc13dac72cada9cc4b80551ee94c -Author: Alexander Strange -Date: Sun Jan 16 02:31:44 2011 -0500 - - Update todo.txt - -commit 78feacc6fae50a72dff68e75d0f718bc136dbe7b -Author: Alexander Strange -Date: Sat Jun 21 23:05:45 2008 -0400 - - Copy the other parts of MpegEncContext needed for h263 - I'm not sure if mbskip can be made compatible with frame threads yet, so it's all zeroed for now. - -commit 795b6f2d87b241e98472c8d9771d4327712c6db9 -Merge: 20d6c33 4f24e1c -Author: Alexander Strange -Date: Tue Jan 13 01:52:27 2009 -0500 - - Merge mainline. - - The conflict fix in h264.c has a strange-looking diff - but probably isn't a problem. - Reverted regression tests to mainline's. - - Conflicts: - - libavcodec/avcodec.h - libavcodec/h264.c - libavcodec/mpegvideo.c - libavcodec/utils.c - tests/seek.regression.ref - -commit 79f3159ebbc55b4f2f885943badc5a847ecd612f -Author: Alexander Strange -Date: Tue Aug 26 03:09:09 2008 -0400 - - Split longer lines - -commit 7a08d7653f38851bd950264fa78174616395fd9a -Author: Alexander Strange -Date: Sat Jun 21 22:09:12 2008 -0400 - - Park all the threads in ff_frame_thread_free before ending them. - -commit 7aabc98254731f46d39fb0770b1445fe332797de -Author: Alexander Strange -Date: Wed Jan 20 02:38:42 2010 -0500 - - The mplayer patch doesn't need to change vd_ffmpeg anymore. - -commit 7b14ed499f5dab39586f3b75ee03e29425b9383e -Author: Alexander Strange -Date: Fri Aug 22 16:25:59 2008 -0400 - - Remove an unused variable. - -commit 7b46b8dc0c04a77108f0150a6fdf58a9b65d4aed -Author: Alexander Strange -Date: Fri Jul 11 18:02:57 2008 -0400 - - Use USE_AVCODEC_EXECUTE instead of checking thread_count in h264. - -commit 7c7f43547b0ad8907d097b99a66f0fc3f171c9f3 -Author: Alexander Strange -Date: Thu Jul 31 18:22:55 2008 -0400 - - Rename H264Context got_avcC to got_extradata. - -commit 7d0709ea04d6f2023052506c969d6db9b79f2963 -Author: Alexander Strange -Date: Tue May 26 00:39:26 2009 -0400 - - Reindent - -commit 7d09b684e9948bbe0e663e40ff0ce616018c0091 -Author: Alexander Strange -Date: Thu Aug 14 20:30:42 2008 -0400 - - Revert some h264 multithreading changes to make merging easier. - -commit 7e85791de30c9005ac722afd59c713c7faef5d7e -Author: Alexander Strange -Date: Tue Aug 19 15:41:14 2008 -0400 - - Retypeset/fix comments - -commit 7e8d959053b29d975c600eb89eb453496a860961 -Author: stefano -Date: Sat May 15 17:34:45 2010 +0000 - - Avoid mixed declaration and code, fix C89 compatibility. - - Patch by Fran -commit 7e928f69148f6c90d35715f4380accb6fc4e88c4 -Author: Alexander Strange -Date: Thu Jun 24 02:41:43 2010 -0700 - - todo: Add secondary bug not fixed in last commit - -commit 7eac0bccc22daa54db7c40b530cf692af3f41274 -Author: Alexander Strange -Date: Thu Jun 18 16:55:03 2009 -0400 - - Update todo. - -commit 7ec92357ae09969eb5254ab6954b712d95b4630f -Author: benoit -Date: Tue May 22 07:58:22 2007 +0000 - - cosmetic v1/v2 renaming - patch by Andreas -�commit 7f86539559480910beab0ef568571dbe524ecda1 -Author: Alexander Strange -Date: Mon Jan 25 02:46:29 2010 -0500 - - Rename avail_motion() and associated functions to something better. - - What did "avail" mean, anyway? - -commit 7fc3b0d1f996b8a832017095244a3187b8d80f38 -Author: Alexander Strange -Date: Sat Apr 4 00:23:21 2009 -0400 - - Remove client calls to avcodec_thread_init. - - This function has no effect under ffmpeg-mt, since avcodec_open() - calls it anyway. - -commit 802206985550e6f685e42595f529133186388acc -Author: Alexander Strange -Date: Mon Nov 15 05:19:58 2010 -0500 - - Update todo.txt - -commit 8047714299aa3fb377b011cd68858b76a666c7cc -Author: Alexander Strange -Date: Mon Aug 25 19:39:24 2008 -0400 - - Whitespace nits - -commit 80a20f0fda854e6c8de05b971164d25425105c82 -Author: Alexander Strange -Date: Sat Aug 23 21:52:47 2008 -0400 - - Don't call ff_report_decode_progress for h264 B-frames. - -commit 80a7538f955a9cd931d840e1cb4e4c81e9d85165 -Author: Alexander Strange -Date: Mon Nov 15 04:14:51 2010 -0500 - - Write APIchanges. - - avcodec_thread_init() will not be deprecated in this repository to - avoid generating warnings for users who shouldn't remove it just yet. - -commit 80ab88e74f9864442afca19ecc6ee0428623ff22 -Author: Alexander Strange -Date: Sun Jun 15 17:46:30 2008 -0400 - - Cosmetics: rename context variable. - -commit 8218d5319067aa1ac06c601e5dc530ebdab7c01f -Author: Alexander Strange -Date: Mon Aug 18 18:43:02 2008 -0400 - - Properly handle error returns from codec functions. - -commit 821c4d0996689ab27d5ab1b6bca0695503b02670 -Author: Alexander Strange -Date: Sat Jun 21 22:54:52 2008 -0400 - - Add 16x8 and 8x8 MVs to MPV_lowest_referenced_row() - -commit 822ed86c0ac4de7c38d443e23fcabf1b627118ea -Merge: e340cac 17c125c -Author: Alexander Strange -Date: Tue Nov 18 13:58:23 2008 -0500 - - Merge mainline. - - Conflicts: - - libavcodec/h264.c - libavcodec/mpegvideo_enc.c - -commit 82324906156d303d5f3b3e10a1855bf05614ebfc -Author: Alexander Strange -Date: Sun Jul 18 02:24:09 2010 -0700 - - Revisit d812c6f8b1d897734d6f7b5f1a5c95d3aa10a3ea - - The sps/pps_buffers logic wasn't correct, considering that SPS/PPS - can be found far before the first working frame. - - Unfortunately this adds more code than it removes. - - Fixes a crash and a memory leak in premiere_paff.ts. - -commit 824ee1ac826b89b84cc93fb77f38ec6530909f2b -Merge: 686ea24 11dcccd -Author: Alexander Strange -Date: Mon Jan 17 03:39:49 2011 -0500 - - Merge remote branch 'mainline/master' - -commit 83b344d87b97ef6b72e84c145f2185f87ce22e9b -Author: Alexander Strange -Date: Sat Apr 4 00:27:47 2009 -0400 - - Forbid calling avcodec_thread_init after avcodec_open. - - Although ffplay used to do this, it never worked, since codecs - were free to check thread_count in their init functions. - -commit 83c7cc1ca1afe68b339b8554634a3a1effc76b45 -Author: Alexander Strange -Date: Tue Aug 19 21:24:03 2008 -0400 - - Add more to todo - -commit 83cbbb1a92d58a850d5b254b5f54e78a7bad8ca5 -Merge: ae7e6bb 7e61a90 -Author: Alexander Strange -Date: Sun May 30 09:59:29 2010 -0700 - - Merge mainline. - - Conflicts: - libavcodec/avcodec.h - libavcodec/h264.c - -commit 8414fc85d03776bc622c9451e9b08f047af42676 -Author: Uoti Urpala -Date: Sun Jan 2 11:52:30 2011 +0200 - - pthread: fix failure to initialize frame fields after flush - - Commit b67d7055bf ("Clear returned pictures immediately after copying - them.") moved some code used to (re)initialize per-thread data before - starting to decode a new frame. The commit changed this to be done - after the results of decoding the previous frame had been returned to - the caller. This was buggy: when decoding state is flushed some - decoded frames may never be returned to caller, and thus there would - be no reinitialization before reusing the same thread for another - frame after the flush. In particular, *got_picture_ptr could be - incorrectly set when calling avcodec_decode_video2() after seeking. - - Move the initialization code back to the previous location before - starting to decode a frame, but leave a line setting - PerThreadContext->got_picture to 0 also after returning a frame and - add a comment explaining why it is there. - -commit 846ae640182b4775db5b32cb027d964bf85d54a5 -Author: Alexander Strange -Date: Fri Jan 21 03:16:03 2011 -0500 - - Longer comments in thread.h - -commit 84a94407509525ffca2e1691a73d186d0d10b1fd -Author: Alexander Strange -Date: Tue Aug 19 01:14:36 2008 -0400 - - Remove whitespace change from mainline - -commit 84cde2e4c7d97f3a9b5f9d4a4c722ccf38c82742 -Merge: f139f42 e73c602 -Author: Luca Barbato -Date: Tue Jun 24 13:31:01 2008 +0200 - - Merge branch 'master' of git://git.mplayerhq.hu/ffmpeg - -commit 854cff1a75a0c4433d6a25517326b2660a56693d -Author: Alexander Strange -Date: Wed May 28 01:05:33 2008 -0400 - - Enable multithreaded MDEC. - -commit 85730bc96115f75524f2780059a26ee6dbd8695e -Author: Alexander Strange -Date: Sat Aug 16 01:30:59 2008 -0400 - - H264: Skip filling in the parts of frame num gaps that are bigger than the number of reference frames. - - My sample with a 256 frame or so gap doesn't work with ff_delayed_release_buffer otherwise. - No change on MR3_TANDBERG_B.264. - -commit 8666b987a1df652d830db8bae9c2d56287a8fc88 -Author: Alexander Strange -Date: Sat Aug 16 14:18:13 2008 -0400 - - Clarify comment for AVCodecContext frame_number - - Number of frames returned vs. decoded isn't the same anymore - -commit 8682f8c0c7396bfe1bf9b4be3293beb4c6a10927 -Author: Alexander Strange -Date: Fri Aug 22 03:25:03 2008 -0400 - - Rename and update comments for AVCodecContext variables. - -commit 86c6c4cff0bf8a734592f31591ec6fafb456387b -Author: Alexander Strange -Date: Tue Mar 9 01:46:32 2010 -0500 - - Cosmetics: fix overindent - -commit 878ad7601ad8eddec124877eb9b30b3df4a8c8b8 -Author: Alexander Strange -Date: Tue Feb 1 21:45:18 2011 -0500 - - Add missing test script. - - Haven't used this one in a while. - -commit 87a9ad1b28ec7a4c9b08b949486010098c06a752 -Author: Alexander Strange -Date: Mon Jul 14 23:17:13 2008 -0400 - - Don't copy padding_bug_score. - This changes during h263 decode so it introduces a race condition. - Having a score for only every 1/n-threads frames is hopefully not too much less inaccurate. - -commit 880990f352fd8d557538535fc0496aec47d1c407 -Author: Alexander Strange -Date: Tue Aug 19 00:42:56 2008 -0400 - - Cosmetics: rename input and output context members - -commit 8884655418183d2ccde654febc9a88e8398c978a -Merge: 8232490 f991c07 -Author: Alexander Strange -Date: Sun Aug 1 04:46:21 2010 -0700 - - Merge mainline. - - Conflicts: - libavcodec/avcodec.h - libavcodec/vp8.c - -commit 8919a66d8ff492adc9455fd73f1da05d154281ff -Author: Alexander Strange -Date: Sat Jan 15 19:27:39 2011 -0500 - - Re-enable multithreaded mpeg4. - - Seems to work in mplayer, and is needed so I can investigate fixing the buffer - age+skip optimization. - -commit 8969edf8b07437e9110db82b7c75e57c00c3e842 -Author: Alexander Strange -Date: Fri Aug 22 02:53:04 2008 -0400 - - Split a long line further. - -commit 899a30063b23ff008bbea3560c28fa194cfb1d77 -Author: Alexander Strange -Date: Mon Aug 11 18:04:42 2008 -0400 - - Simple patch to keep the non-pthreads OSes working. - - They ignore thread_algorithm being set by the user for some minor simplicity gain, since I'd still like to see these files gone from mainline. - -commit 8a2e487269389d778ddf517baaff590b0a7b3f46 -Author: Alexander Strange -Date: Sun Jan 24 16:55:35 2010 -0500 - - Don't allocate thread_opaque progress with frame threading off. - - It's not needed for anything and the extra check in ff_await/report_* - isn't slow. - -commit 8aa204a70a7f068f46f00e0983b4617f8030544a -Author: Alexander Strange -Date: Thu May 29 00:19:26 2008 -0400 - - Fix comments for new avcodec fields. - -commit 8ae6601b670156b36b227e2a3c0d9cdc72294bd5 -Merge: c91d7a2 cef0309 -Author: Alexander Strange -Date: Sun May 23 01:43:27 2010 -0400 - - Merge mainline. - - Conflicts: - libavcodec/avcodec.h - -commit 8ae9683ebce1e42c5bd1a24a2bcdcbf2cbfe6ccb -Author: Alexander Strange -Date: Sun Jan 16 02:29:08 2011 -0500 - - Update mplayer.diff to work around incompatibility with draw_horiz_band() - -commit 8af63f450185c3b15cc2ca32d2bc1a19f5d2a28e -Author: Alexander Strange -Date: Sat Feb 20 20:02:34 2010 -0500 - - Cosmetics: rename thread.h functions for consistency - -commit 8b7a5375ad0956f546c2b614594b79c3ec54de3d -Merge: 3ad85b1 875fcc3 -Author: Alexander Strange -Date: Wed Oct 28 13:11:58 2009 -0400 - - Merge mainline. - -commit 8ba50a98f87edb2b87df042f09573ea8be4a8696 -Author: Alexander Strange -Date: Sun Mar 28 03:54:31 2010 -0400 - - h264: Fix ff_h264_execute_ref_pic_marking() not being called with PAFF+threads - - With some PAFF files, field_end() can call ff_h264_execute_ref_pic_marking() - during slice header decoding. This was disabled with threads on, which was wrong. - - This patch fixes it at the cost of making control flow more confusing. - - Partial fix for Chalet-Tire.mp4 from ffdshow. - -commit 8c946d1672281fc997dfb2679e7cbed48dd09216 -Author: Alexander Strange -Date: Mon Jul 14 23:07:07 2008 -0400 - - Set decoding progress as high as possible when multithreading is off. - This avoids possible crashes from trying to lock progress_mutex when it hasn't been created. - -commit 8d466e182aa89ca8cfbe57ce60f2a1e2a7ecebc7 -Author: Alexander Strange -Date: Mon Oct 13 14:37:22 2008 -0400 - - Fix incorrect frame num gap handling. - - Fixes ORF1HD.Demo-Loop.720p.DD5.1.mkv from x264 samples. - -commit 8d8229014f489e1b2417676d9753f784d995e6c0 -Author: Alexander Strange -Date: Mon Dec 1 17:21:38 2008 -0500 - - Don't crash if flush_buffers is called after init and before the first decode. - - Fixes mplayer -ss - -commit 8f759fa0e956f8cc33ccd423cefae23e25c16caf -Merge: 9be00ab 1e8ecf7 -Author: Luca Barbato -Date: Tue May 20 11:46:04 2008 +0200 - - Merge branch 'master' of git://git.mplayerhq.hu/ffmpeg - -commit 9017898687ebedca27e47fdd13e6e5e208a5fbb6 -Author: Alexander Strange -Date: Thu Aug 28 00:52:29 2008 -0400 - - Pad the frame data properly - -commit 9059683b29cd601361e477289a194e679aa72f8c -Author: Alexander Strange -Date: Thu Jun 12 16:22:27 2008 -0400 - - Limit ff_find_unused_picture to only part of s->picture. - - Otherwise, a thread may call delayed_release_buffer and then later allocate a picture in the same place, reusing the other Picture variables while they're still in use. - -commit 9077d0ba4ed18e1f106723d155e81461c8951764 -Author: Alexander Strange -Date: Wed Feb 17 00:55:36 2010 -0500 - - Comment recent change to update_context API. - - Notes: - - It might be possible to revert this by making the vp3 decoder - behave like mpegvideo. Not faster but the code will be simpler. - - I don't like any of the old comments, they're too wordy. - -commit 9153938f1c1f0933ec59cee14cc26b8f99bd9090 -Merge: 661ca40 e48fb07 -Author: Alexander Strange -Date: Thu Jul 23 21:14:58 2009 -0400 - - Merge mainline. - -commit 91a7b18346baf82e0ccf6dfb53ada22299396f17 -Author: Alexander Strange -Date: Sat Aug 16 16:42:33 2008 -0400 - - Call codec init and free on the first thread context instead of the main context. - - This is needed so we can stop using the main context for decoding threads. - -commit 91a7c2254bb3e82862c4cd916bd9f2ac1dd4c170 -Author: lucabe -Date: Thu Sep 23 09:16:05 2010 +0000 - - Allow to set the frame rate in v4l2 devices - Patch by Jos -� Miguel Gon -commit 91cd95a84759702b85de68047d21a6ef9d32eaca -Merge: 77f7818 f9f7b02 -Author: Alexander Strange -Date: Sun Jan 24 21:39:20 2010 -0500 - - Merge mainline and libswscale. - - Upstream now always calls avcodec_thread_init(). - It's better to do that differently here, so the - current code in ffmpeg.c has been kept. - -commit 92672ea0eee93244cc78e5023f6469c5b21754b5 -Author: Alexander Strange -Date: Mon Aug 18 19:10:01 2008 -0400 - - Simplify: better use of variable names instead of weird struct accesses - -commit 93ac615ccf788df20279aa613f3fdc78d4bfcf18 -Author: Alexander Strange -Date: Mon Jul 14 23:56:22 2008 -0400 - - Simplify assert. - -commit 9457fb1458998f893b7e1f06f1144f8203cd0025 -Author: Alexander Strange -Date: Mon May 25 22:38:36 2009 -0400 - - Don't try to check list1 when it's not filled. - - 9.1s -> 9.0s on 5cm.mp4 - -commit 94985fa9745e2affd0cf3145fa35cb8ae87e7848 -Author: Alexander Strange -Date: Sun May 31 00:08:41 2009 -0400 - - Ensure the minor version is higher than mainline. - - Missed this in previous merges, but I think it's important - to avoid confusing anyone reading ffmpeg tool output. - -commit 9576774bbee0215c0ab7bbb868ff35dff00ab900 -Author: Alexander Strange -Date: Sun Aug 24 03:02:44 2008 -0400 - - Merge ff_*_release_buffer into one function for simplicity and correctness (the non-delayed version was not really ever safe). - -commit 967e65496780c089956f2dc199b541dae3a3d9cb -Author: Alexander Strange -Date: Thu Dec 18 14:37:04 2008 -0500 - - Some todo entries I forgot to add - -commit 96d6751af35556785037bdddb500eeb7b47795e6 -Author: Alexander Strange -Date: Mon Jul 14 23:08:45 2008 -0400 - - Call ff_thread_init() before the codec init. - This makes USE_AVCODEC_EXECUTE() properly available during init. - -commit 9816b66fb55fe03fd6f2a4db9390bdaa59eac697 -Merge: 1292a18 918f7b5 -Author: Alexander Strange -Date: Thu Jan 22 03:39:04 2009 -0500 - - Merge branch 'master' of git://git.mplayerhq.hu/ffmpeg - - Changed the value of CODEC_CAP_FRAME_THREADS and - adjusted use of config variables to match mainline. - - Conflicts: - - libavcodec/h263.c - libavcodec/h264.c - libavcodec/mpeg12.c - libavcodec/mpegvideo.c - libavcodec/pthread.c - libavutil/common.h - -commit 99ed04d4d7b7183a4d0a1b8833eee3b506e13ff0 -Author: Alexander Strange -Date: Fri Jan 21 01:34:57 2011 -0500 - - Remove change to compute_pkt_fields which is no longer needed - - May have been fixed by introduction of pkt_dts, but I'm not sure. - Either way, tests pass. - -commit 9a88884c03cd40d1fcbd247f1b004848fb629a11 -Author: Alexander Strange -Date: Wed Aug 6 20:55:20 2008 -0400 - - Simplify thread init and make more of its functions static. - -commit 9b27ce1e721a021128380e47e83a06f25c52e998 -Author: Alexander Strange -Date: Fri May 15 15:53:28 2009 -0400 - - Fix race condition decoding H264 direct prediction - - There may be some code merging possible here. - -commit 9bac2ee137d9b8152e3beb98681b07f665cd58ee -Author: Alexander Strange -Date: Thu Jun 5 20:36:38 2008 -0400 - - Cosmetics: rename ff_mt_*_buffer. - -commit 9be00ab6113d71a020eea4fd4483b8483efbb29d -Merge: 63f663f 1531623 -Author: Luca Barbato -Date: Sun May 11 08:53:10 2008 +0200 - - Merge branch 'master' of git://git.mplayerhq.hu/ffmpeg - -commit 9c241058a255e1da6adec7db81e22d4ff8b2b6b2 -Author: Alexander Strange -Date: Tue Aug 19 04:09:25 2008 -0400 - - Copy the entire reference list arrays in case they're used. - - And that's it for SoC period commits. - -commit 9cd1083269334de974acdf13dd94451c178a0eca -Author: Alexander Strange -Date: Tue Mar 29 04:47:23 2011 -0400 - - Fix mdec - - init_copy rotted due to data structure changes. - -commit 9e0e492fe88ec0c7ec400e9afdbef8356280fc16 -Author: Alexander Strange -Date: Tue Aug 5 00:21:25 2008 -0400 - - Update the guard clause on avcodec_thread_execute(). - - It already works fine, since all codecs check USE_AVCODEC_EXECUTE themselves before calling it, but the function is for some reason part of the public API. - -commit 9e615b8534c98947cbbe6ada5047e95c36e14cde -Author: Alexander Strange -Date: Wed Sep 3 20:40:45 2008 -0400 - - Rename symbols to not mention decoding - -commit 9e981c8d263986e67de6170895125b1de7e62ddd -Author: Alexander Strange -Date: Wed Aug 11 02:05:50 2010 -0700 - - vp3: fix mt decode of 4:2:2 and 4:4:4 content - - The threading improvements are poor and looks strange: - real 0m14.337s - user 0m13.200s - sys 0m1.132s - - real 0m13.434s - user 0m19.409s - sys 0m7.091s - - real 0m11.610s - user 0m21.870s - sys 0m7.303s - - real 0m7.976s - user 0m20.681s - sys 0m3.277s - - There may be a bug related to await_reference_row() being called too many times, - as it's in a loop per-chroma superblock and there are 2x as many of those - in 4:2:2, but not 2x as many MVs. - - No idea why 4 threads have less sys overhead. - -commit 9ec47e33af6776b94875c91288db852a333a6f63 -Author: Alexander Strange -Date: Sat Jun 21 22:01:43 2008 -0400 - - Split the code for completing all current frames out of ff_frame_thread_flush. - -commit 9ec9f0868de2df3d3448dec887e7440ebb006b27 -Author: Alexander Strange -Date: Mon Aug 2 16:14:21 2010 -0700 - - Fix the last commit testing the wrong variable. - - Luckily the idea was still right. - -commit 9ede817a98a263093ca7965f8754a1770ef031de -Author: Alexander Strange -Date: Fri Jul 11 23:01:47 2008 -0400 - - Add a new -debug for tracing get_buffer calls. - -commit 9f15b87679392902206264383c16c7440d8c0f06 -Author: Alexander Strange -Date: Sun Jul 6 15:35:10 2008 -0400 - - Extra line snuck in while merging mainline. - -commit 9f6a425684e0fd0ac3f8bbd37ca4e2bc96e05d5b -Author: Alexander Strange -Date: Mon May 25 20:30:08 2009 -0400 - - Fix race condition with MBAFF frames. - - mb_linesize is 2*linesize for MB_MBAFF too, which wasn't counted - in mc_dir_part_y, so the part of the MV added to 16*mb_y was 1/2 - the right magnitude. Fix this by halving mb_y too (safe) and - doubling row values for MBAFF later. - -commit 9ff8764a15cce3fcf3f64270d7d4ec52a3ca7d1a -Merge: 94985fa 08bbd7d -Author: Alexander Strange -Date: Sun May 31 01:19:07 2009 -0400 - - Merge branch 'master' of git://git.mplayerhq.hu/ffmpeg - -commit a1005396f05f5bc13c6aa6875337dbd0e6c4cd03 -Author: Alexander Strange -Date: Wed Aug 6 20:45:06 2008 -0400 - - Merge framethread.c into pthread.c. - - Git doesn't track this very well... - -commit a1a5c549efd3a376fd5c8c77d49acfab89f8fdba -Author: Alexander Strange -Date: Sat Jul 12 02:19:59 2008 -0400 - - Factor out size of delayed_pic. - -commit a210b422361b051ba73c115fe6bf65eaa745b19a -Merge: f9515a4 ec6213f -Author: Alexander Strange -Date: Thu Dec 24 22:08:34 2009 -0500 - - Merge mainline and update swscale. - - As a side effect, this fixes Theora/VP3 decode being broken. - - Conflicts: - ffmpeg.c - libavcodec/avcodec.h - libavcodec/h264.c - libavcodec/mpeg12.c - libavcodec/mpegvideo.c - libavcodec/vp3.c - -commit a2371d6c9b8837b472e22539642883979eac2ddf -Author: Alexander Strange -Date: Tue Nov 18 14:26:37 2008 -0500 - - Update todo. - -commit a2efd25ba04e0cb61823cbf765651f437b691b09 -Author: Alexander Strange -Date: Thu Jan 6 06:31:45 2011 -0500 - - Update todo.txt and move one issue out of bug fixes that isn't a major issue - -commit a2fb22fb6988742ee28ee61e2e21fa05125517a9 -Author: Alexander Strange -Date: Sat Aug 30 04:20:03 2008 -0400 - - Don't prefix static function names. - -commit a3a2674e27f8f2641d1603ee9e92e854289a0527 -Author: Alexander Strange -Date: Tue Feb 1 23:13:49 2011 -0500 - - Fix pkt_pts change to ffmpeg.c - - Caused tons of regressions in make fate. - This needs to be merged to mainline_patches. - -commit a4599a7f4e4a865a0b402297b4f5a11e9ca34a27 -Author: benoit -Date: Thu Jan 10 10:16:36 2008 +0000 - - Make pp_help a constant array of characters to move it to .rodata. - Patch by Diego 'Flameeyes' Petten -� flameeyes commit a5285ae4d452abed92f43e2a7a24dd821343a39c -Merge: a7b8cb3 6a3f0e9 -Author: Alexander Strange -Date: Sun Aug 23 22:31:19 2009 -0400 - - Merge branch 'master' of git://git.mplayerhq.hu/ffmpeg - -commit a564fda546ce3bfd04cf8a0e4ec4fb1b6d40e010 -Merge: 287e761 5b4608b -Author: Alexander Strange -Date: Mon Jan 4 03:56:32 2010 -0500 - - Merge mainline and libswscale. - - Auto-merge failed on h263.c for no apparent reason; the patch was - reimplemented by hand. Note that mt isn't enabled for h263 at the moment. - - Conflicts: - ffmpeg.c - ffplay.c - libavcodec/h263.c - -commit a5cdcc9d4efcc043c01019f632dc1e5ad318802a -Author: Alexander Strange -Date: Mon May 25 20:16:54 2009 -0400 - - Rewrite mc_dir_part_y(). - - The previous one used a completely wrong value for filter_height - and didn't properly account for MVs extending past the top of the screen. - I'm not sure if MVs can be more than -pic_height, if they can this - may still be wrong. - -commit a61ab604725f647c1bcb46aa8cfb303a5c78a2b0 -Author: Alexander Strange -Date: Thu Jun 25 16:39:14 2009 -0400 - - Theora: factor out updating last_frame. - -commit a74b85567073a424d5b7fc4bd8cc1e125df170f5 -Author: Alexander Strange -Date: Mon Sep 1 02:34:59 2008 -0400 - - Comment adjustment - -commit a7b8cb3c942fed6c80111519ba5505f11d61f3af -Merge: 17dcbec 23e6da5 -Author: Alexander Strange -Date: Thu Aug 20 16:47:50 2009 -0400 - - Merge branch 'master' of git://git.mplayerhq.hu/ffmpeg - -commit a903974adc7c8dd33dfb0acc4e2d6d10c09a23c8 -Author: Alexander Strange -Date: Wed Nov 11 12:45:09 2009 -0500 - - Add a next_outputed_poc to H264Context. - - Doesn't do anything yet, but makes the next merge easier. - -commit aa11b5e0df5dfcaba21552e4864807f7aa65f5c5 -Author: Alexander Strange -Date: Tue May 11 06:36:55 2010 -0400 - - pthread: Remove pointless line from frame_worker_thread() - - It was introduced in the first commit, where it probably did something. - -commit aaa05da15fa7710503544d4a94319cb10d49a8f2 -Author: Alexander Strange -Date: Tue Nov 2 02:59:16 2010 -0400 - - vp3: Remove redundant y*fragment_width+x calculations - -commit aacc74c0e2b047340a1a22f5c28aa03a4294aa03 -Author: Alexander Strange -Date: Mon Jul 14 03:40:15 2008 -0400 - - Reindent. - -commit ab4c84dd28c0375a6ed4f77f37ada3b94b2136a0 -Author: Alexander Strange -Date: Mon Dec 1 17:20:10 2008 -0500 - - Don't hide the warning about direct rendering in mplayer. - -commit abb53ce0e02d31fb282f55cecb58f9b0c4f5c136 -Author: Alexander Strange -Date: Sun Feb 6 19:18:31 2011 -0500 - - pthread: Remove useless line - -commit ac2e1b12b5e608b80581d731c4f3a0d6c033e9e0 -Author: benoit -Date: Tue May 29 14:35:29 2007 +0000 - - allocate PPS and SPS dynamically - patch by Andreas -�commit ac4539fba6d825d683d4a7d27f0045d068fe4595 -Author: benoit -Date: Mon Jan 7 12:48:42 2008 +0000 - - Mark the ff_svq1_frame_size_table as constant. - Patch by Diego 'Flameeyes' Petten -� flameeyes commit ac4c37360b21a14e9b26502a299f831b8448a10b -Author: Alexander Strange -Date: Mon Nov 15 02:43:15 2010 -0500 - - Cosmetics: remove the COPY() macro - -commit ac7f2102c4249a89144c36944e13bf6be56e9190 -Author: kabi -Date: Mon Apr 8 12:32:01 2002 +0000 - - * support for .au .gif .mov .mp4 by Fran -commit adfaa1f86196156e30c54799303269f4a4f84a2d -Author: Alexander Strange -Date: Sat Jul 26 16:14:00 2008 -0400 - - Cosmetics: split a long line. - -commit ae2790af78a332a6aa836607a14546c5cc1865e5 -Author: Alexander Strange -Date: Sun Oct 12 18:55:48 2008 -0400 - - Add multithreading for PAFF/MBAFF. - -commit ae4251429ee5e333fc705c61959417c1d9364b9e -Author: Alexander Strange -Date: Tue Nov 18 14:15:24 2008 -0500 - - Switch to mphq git module - -commit ae7e6bb9708a0f0dac89295c788266e0f15899d2 -Author: Alexander Strange -Date: Tue May 25 03:14:27 2010 -0400 - - H.264: Fix rare race condition. - - h->mb was not cleared when initializing a new decoder thread. - This could cause wrong pixel values in the first macroblock of - the first frame to be decoded by each thread. - - I suspect this is nearly the last visible bug affecting x264 content. - - Fixes [SS]_Angel_Beats!_-_06_(1280x720_H.264)_[A01DDBD8].mkv. - -commit af52a126f36cd6339f9f4a1152103ef88b4b8fee -Author: Alexander Strange -Date: Sat Jun 27 18:09:49 2009 -0400 - - Call handle_delayed_releases() before update_context(). - - This allows releasing frames in update_context(), which would - previously cause a race condition/deadlock. - -commit af79370b65b396e05c319d29356e456a8f5e8233 -Author: benoit -Date: Mon Jan 7 12:44:49 2008 +0000 - - Make the av_class member of PPContext a poiner to constant AVClass. - Patch by Diego 'Flameeyes' Petten -� flameeyes commit afafe7361da5a9373d02dc60d597da8f2185edd3 -Author: michaelni -Date: Sat Nov 2 10:31:37 2002 +0000 - - added perm inheritance from ffmpeg_g (it looks like 'strip' in BeOS doesn't keep them, though the Linux one does !?) - patch by (Fran -commit afc391b7ab5eda271733bbe55ef46118aba75bff -Author: michaelni -Date: Sat Jul 20 20:05:50 2002 +0000 - - beos/mov/adpcm patch by Fran -commit afe0428ae38f68a467b43cc9358b7a1a2f85d36b -Author: Alexander Strange -Date: Sat Aug 16 18:09:11 2008 -0400 - - Fix memory leak in mpegvideo - -commit b05eb30ba838b981c769217e1d2215777484f25a -Author: Alexander Strange -Date: Fri Jan 21 02:34:46 2011 -0500 - - Make the src parameter of update_thread_context() const - -commit b07e45974b2772e3a747502f976dc08d0ffcff74 -Author: Alexander Strange -Date: Thu Jun 18 16:21:03 2009 -0400 - - Indent. - -commit b125b68fe6dc2d0064d45d0cffc3bcb47263f32c -Author: Alexander Strange -Date: Sun Jan 24 18:50:32 2010 -0500 - - Remove fixed entry from the todo. - -commit b18683e3adc997b19cf56f459ce5f8a7428c0909 -Author: diego -Date: Sun Oct 18 14:34:45 2009 +0000 - - Fix typo that mistakenly slipped into previous commit: - CONFIG_MPEG_XVMC_DECODER was changed to CONFIG_MPEGVIDEO_XVMC_DECODER. - patch by Onur K -� -commit b1c8c18fe11d3155b1df6a19117d14fa633bcd15 -Author: michaelni -Date: Sat Nov 2 10:39:22 2002 +0000 - - added MACE (Macintosh Audio Compression/Expansion) 3:1 & 6:1 support - contribution by Laszlo Torok - 4CC 'MAC3' and 'MAC6' in Quicktime. - It works for mono streams, needs to be fixed for stereo when I get my hands on a stereo sample :) - patch by (Fran -commit b3cdfccd2b11e247e0c17e02d0c958888da5585b -Author: Alexander Strange -Date: Mon Nov 15 04:14:41 2010 -0500 - - avcodec.h: Update comments - -commit b3d5e9333051802b20446076605b404e418323c4 -Author: Alexander Strange -Date: Tue May 26 00:34:11 2009 -0400 - - Skip unnecessary lock-wait-unlocks for condition variables. - -commit b3e3f071ca5ad99444bac95e4128c01a8ae7bae3 -Author: Alexander Strange -Date: Thu Jun 11 11:32:00 2009 -0700 - - Split out if (current_slice == 1) - -commit b4221d5453d6dc893e87b77eecc845da121ddb56 -Author: Alexander Strange -Date: Mon Aug 18 17:06:32 2008 -0400 - - Reorder ff_frame_thread_free to fix memory errors. - - This fixes using mutexes after they're destroyed and not calling release_buffer on every buffer. - Unfortunately the change to MPV_common_end is exactly the opposite of what's needed for supporting width/height changes. - -commit b483ed4f4af9444cfaa6ff9336645d799d2254dd -Author: Alexander Strange -Date: Wed Aug 6 20:33:51 2008 -0400 - - Remove the unused debugging counters from frame threading. - -commit b67d7055bf60313c40b6369f98cfc9d1eae3aefb -Author: Alexander Strange -Date: Tue Sep 2 00:52:48 2008 -0400 - - Clear returned pictures immediately after copying them. - - This isn't protected by a mutex but is still safe. - Needed for the next commit. - -commit b68110d079914d16c9fc5d1cc8c6e10d78dbdbca -Author: Alexander Strange -Date: Sat Aug 16 15:05:49 2008 -0400 - - H264: Set the decode progress for fake reference frames to the maximum. - - Fixes deadlock in premiere-paff.ts at the expense of some indeterminism on the first frame. - -commit b77accec9077ae8f072091fc7301d661bc9487ba -Merge: 5d3c2f7 392faa1 -Author: Luca Barbato -Date: Tue Jul 29 15:11:05 2008 +0200 - - Merge branch 'master' of git://git.mplayerhq.hu/ffmpeg - -commit b7d182610b592eef0714c1d2de18c3233a289b69 -Author: Alexander Strange -Date: Sun May 24 01:06:33 2009 -0400 - - Update mplayer.diff whitespace - -commit b7e0f1a3bfd00b0256dcdd3efc4b7b77c086e70e -Author: Alexander Strange -Date: Sun Aug 24 22:38:42 2008 -0400 - - Rename doxygen group to not conflict with h264 - -commit b88c3baf94247f2687ca0c05b0ce6af7c905e02a -Author: Alexander Strange -Date: Mon May 24 22:40:00 2010 -0400 - - Fix more old merge glitches. - -commit b9a8973031be583af53be890ccdef07841394385 -Author: Alexander Strange -Date: Sun Jun 15 22:31:35 2008 -0400 - - Use output_cond for notifying the main thread. - -commit ba073d39f18679835b48b96f20feae96dad1f343 -Author: Alexander Strange -Date: Mon Apr 11 23:00:19 2011 -0400 - - h264: cosmetic whitespace change - -commit ba8b789143dc6a14c29393e40fb361c1a3e2ccd4 -Author: Alexander Strange -Date: Sat Aug 16 01:53:10 2008 -0400 - - Update todo - -commit babb66241ae51e2956aa698d425c645ad056936e -Author: Alexander Strange -Date: Fri Oct 17 14:52:35 2008 -0400 - - Copy avctx->height/width for mpegvideo. - - Not sure what the difference between the three width variables is, really. - -commit bad2bf8621c04791f0d9a0a2873a3b6042d4ba83 -Author: Alexander Strange -Date: Sun May 24 00:48:57 2009 -0400 - - Copy new fields in update_context_from_copy(). - -commit bb67674aa57e23893f2f19bd4ffb4a92b5a01e83 -Merge: 06ac5ac 6051838 -Author: Alexander Strange -Date: Sun Jun 20 17:39:15 2010 -0700 - - Merge branch 'master' of git://git.mplayerhq.hu/ffmpeg - -commit bba0e098a75f14af80bfd4fdfdf9edcaf8f3fee5 -Author: Alexander Strange -Date: Sat Jun 20 03:32:19 2009 -0400 - - Factor out vp3 table allocation into new function. - -commit bbc5744117da188c43e00c4f02f6ff0fe984d4f8 -Author: Alexander Strange -Date: Sun Jul 13 15:52:21 2008 -0400 - - Print the AVCodecContext address in av_log instead of AVClass. - This makes logging much easier to read when there's more than one context. - -commit bc1cc6f39a0f6df2cc1d0fecd3eb14efd150763a -Author: Alexander Strange -Date: Wed Feb 3 01:29:21 2010 -0500 - - Cosmetics: Don't use #if HAVE_PTHREADS in thread.h. - - These two macros will be removed entirely in the future. - -commit bd392934097dc5c909e9b06550ec1d13d92fa134 -Author: Alexander Strange -Date: Fri Aug 15 23:34:32 2008 -0400 - - Set output_size properly before calling the decoder so it doesn't return nonsense and crash at the end - -commit bd63cf4721466aea490f6f0455a32060d572d5ba -Author: michaelni -Date: Sun Jul 21 07:54:53 2002 +0000 - - YUV410P to YUV420P patch by Fran -commit bdaeaaa58f24393027e112c02896b23fe0b3cc01 -Author: Alexander Strange -Date: Mon Oct 13 11:23:47 2008 -0400 - - Add buffer padding to the end of bitstream_buffer. - - Fixes a warning in valgrind. - -commit bdef29429d4f488012cb492e61cf20ffe0b858a7 -Author: Alexander Strange -Date: Sun Jul 6 15:48:52 2008 -0400 - - Fix compilation with threads disabled. - -commit be45bc423ba576e1d06df3664cfe91e02d78ffa5 -Author: Alexander Strange -Date: Mon Feb 15 00:00:35 2010 -0500 - - Fix a deadlock in mpeg1 threaded decoding - - Fake frames need their progress set to INT_MAX. - - This can be triggered by seeking in mpeg1, but this is not the correct fix, - since seeking to keyframes does seem to work properly without threads. - -commit bf806642ab67148d93a4f24e7dbdc8644575c45b -Author: Alexander Strange -Date: Sun Jan 24 18:59:28 2010 -0500 - - When frame_thread_init() fails, free the failed thread context as well. - -commit bffb1c874ec2c9f7ea9c6830d852955a3c2805a0 -Author: Alexander Strange -Date: Wed Aug 6 20:51:34 2008 -0400 - - Make ff_*_thread_free static. - -commit c01185fe11dd2ce35f798d16faec17fcfc64c7c4 -Author: kabi -Date: Fri Mar 8 09:09:57 2002 +0000 - - * BeOS patch by Fran -commit c05a51580b56d1479083b1460dc29492b3fb6b16 -Author: Alexander Strange -Date: Tue Aug 19 00:53:15 2008 -0400 - - Track allocated buffer size properly. Don't allocate buffer padding since the user already did it. - -commit c1b0bddeaf947ef49c63b412918d73fe7a645ba5 -Author: Alexander Strange -Date: Mon Nov 15 04:08:01 2010 -0500 - - pthread: Update and sort the fields copied in update_context_from_thread/update_context_from_user - - Changes to pthread.c are finished. - -commit c29d645dfd2c8168e7c9009638ddb88928e706be -Author: Alexander Strange -Date: Tue May 11 06:12:26 2010 -0400 - - Copy time_base between threads. - - Appears to be used by the h263 decoder. - -commit c2a400d3a5da10f8f2a9c2aa89d9396efe428029 -Merge: b77acce e96a4b0 -Author: Luca Barbato -Date: Thu Aug 14 22:16:09 2008 +0200 - - Merge branch 'master' of git://git.mplayerhq.hu/ffmpeg - -commit c2e19261fe08c2d96d4bf082e97bebcdf12566f2 -Author: Alexander Strange -Date: Sat Feb 20 21:24:24 2010 -0500 - - Remove USE_FRAME_THREADING and USE_AVCODEC_EXECUTE macros. - - Requested in original review, might help making sure pthread emulation - works for encoding tests. - -commit c2e9a1fc965de63271c7c4ddffd7e938ce1bfd93 -Author: benoit -Date: Tue Nov 6 16:28:32 2007 +0000 - - ffplay currently needs special handling for pausing in some protocols. - Patch by Bj -�rn Axelsson: bjorn ; axelsson commit c2eed2a91101a90f2172e81755ca4d655de90443 -Author: Alexander Strange -Date: Wed Nov 3 22:13:07 2010 -0400 - - vp3: Cosmetic changes - -commit c370b927b6d1f0e092e43d58ee29046e5accad1a -Author: Alexander Strange -Date: Sun Feb 6 19:18:10 2011 -0500 - - Improve comment in avcodec.h - -commit c378f545f65d536e55ebe1ac85d170a15e7748eb -Author: Alexander Strange -Date: Wed Aug 6 20:12:01 2008 -0400 - - Reindent. - -commit c45bb41ec61522dcdb97618a0f6fafd8a32d529b -Author: benoit -Date: Mon Jan 7 12:42:02 2008 +0000 - - Make v4l.c's video_formats constant and static. - Patch by Diego 'Flameeyes' Petten -� flameeyes commit c4649d2e370c04c7f5cfcf0b444edc6116ba03f8 -Author: Alexander Strange -Date: Mon Jan 25 03:16:09 2010 -0500 - - Avoid freeing buffers twice when closing mpegvideo. - - This fixes a harmless "unreleased buffers" warning due to the design - of delayed releasing. This is probably a bad way to do it (won't - work if resolution changing is supported) but I can't think of a - better one that's simple. - -commit c5137d0d9e355aecc7e60cef0d2314468b77a147 -Author: Alexander Strange -Date: Sat Jan 15 22:52:30 2011 -0500 - - Update todo.txt - -commit c563b57b187279c1af0f723110bdab815fac6385 -Merge: 65e8486 6a3327b -Author: Alexander Strange -Date: Fri Apr 3 21:23:47 2009 -0400 - - Merge mainline. - - Conflicts: - libavcodec/avcodec.h - libavcodec/mpegvideo.c - -commit c58218c681e51a1b392ddb0177dcff8fc8e99d1c -Author: Alexander Strange -Date: Tue Aug 12 00:45:01 2008 -0400 - - Use HAVE_PTHREADS instead of ENABLE_PTHREADS for mplayer compatibility. - -commit c5ca1f6b5227f8f7a26f889c123c4358ee15596e -Author: Alexander Strange -Date: Sat Jan 15 22:51:43 2011 -0500 - - Pass pkt_dts properly through multithreading - - A/V sync should work in all cases now once guess_correct_pts()/clients - adopt AVFrame.pkt_dts. - -commit c6a59ddd734c7ca92862bce47ec686e16da627ee -Author: Alexander Strange -Date: Fri Jun 19 18:32:12 2009 -0400 - - Remove frame_num stuff from todo. - - The current code is actually correct. - -commit c6bbd5d91408d6dd795dfbbdfba2cef62696d765 -Author: michael -Date: Sun Jan 8 17:06:26 2006 +0000 - - fixing second last time Fran -commit c6f5097967de5ed420cd56a1a77b60a705fcee48 -Author: Alexander Strange -Date: Sat Aug 16 05:09:03 2008 -0400 - - Disable frame threading if low_delay or randomly truncated frames are used. - -commit c75cec5217fc23206476e2d1c894e8a6ddcd81b9 -Author: Alexander Strange -Date: Sun Mar 29 02:25:19 2009 -0400 - - Fix missing ff_get/release_buffer calls in mdec. - -commit c83670eeb613b9509555d4ddcac559a37cc1c5bc -Merge: 2063f77 dde06af -Author: Alexander Strange -Date: Wed Dec 15 15:20:06 2010 -0500 - - Merge mainline. - - Version wasn't updated this time. - - Conflicts: - doc/APIchanges - libavcodec/avcodec.h - -commit c91d7a205df4dd224461b96749b9ce12e2bf6825 -Merge: 4874d25 04c74fc -Author: Alexander Strange -Date: Wed May 19 16:51:42 2010 -0400 - - Merge mainline. - - Conflicts: - libavcodec/avcodec.h - libavcodec/options.c - libavcodec/utils.c - -commit ca89b49eff34604b1354888cd041f474d988c122 -Author: Alexander Strange -Date: Mon Jun 23 04:16:16 2008 -0400 - - Fix ff_frame_thread_flush() - It should setup the context to be just like decoding starting from scratch. - -commit cac4bca0570a9b9ffdd3b49590fe1e41fd5568b0 -Author: Alexander Strange -Date: Sat Jun 27 15:02:21 2009 -0400 - - Fix conditions for drawing edges. - - They shouldn't be drawn for B-frames/intra only (for speed) - and when hwaccel is on (for correctness). - -commit cba830597c99b7a6de57b3cd2209d22598bb72b1 -Author: Alexander Strange -Date: Sat Feb 13 22:45:07 2010 -0500 - - Backport VP3 crash/deadlock fix from mainline r21781. - - Previously, if get_buffer() failed when allocating a golden frame, - it would access it in a later frame without checking it first. - r21781 unintentionally fixed this. - - This should be impossible to trigger, but some other bug in -mt - causes this with frequent seeking. - -commit cbaa375d4cb1320093199e8abe1ce7bcf389036d -Author: michaelni -Date: Sat Nov 2 21:05:54 2002 +0000 - - gcc optimization on BeOS (patch by Fran -commit cbc8d8bec42b371522b0724f27454a96881c4164 -Author: Alexander Strange -Date: Mon Apr 19 02:47:32 2010 -0400 - - Disable multithreading the first field in PAFF. - - At least one PAFF .mp4 file has two fields per packet, which can't - work with -mt - instead it needs to split the fields up like packed - B-frames do. - - Fixes Chalet-Tire.mp4. Pessimizes otherwise working files. - -commit cc33ba7cd7ebbf14b62b0783fb7272e41b484aea -Author: Alexander Strange -Date: Tue May 11 14:41:53 2010 -0400 - - Cosmetics: arbitrary reordering of some pthread struct members - -commit ccd0d039a3d2fd70a9e947cc2faf79ca091dd687 -Author: Luca Barbato -Date: Fri Apr 25 21:52:45 2008 +0200 - - Incorporate swscale as submodule - -commit cd71fb4386961bc860c3abc4cf464b580366d57d -Author: Alexander Strange -Date: Tue Jan 25 16:33:26 2011 -0500 - - Forgot to git add the test failures list - -commit cdc193d0dbc2f0775d177f46036eca0d813f56ff -Author: Alexander Strange -Date: Sun Jul 6 15:53:33 2008 -0400 - - Use static functions instead of macros for consistency. - -commit cf2561f8dcc3143f9c479bba1d9be91339f23726 -Author: Alexander Strange -Date: Fri Jan 21 02:22:56 2011 -0500 - - Write longer comments for callbacks - - Also neglected to update get_buffer to mention thread_safe_callbacks - -commit cf528d74cd7321219880eb06b94a8de0ba5741ff -Author: Alexander Strange -Date: Sun Aug 17 16:50:51 2008 -0400 - - Fix another memory leak. - -commit cf56bb126e7c056740e51c6c13304b03260b4b47 -Merge: ccd0d03 08baa31 -Author: Luca Barbato -Date: Sat May 3 12:18:40 2008 +0200 - - Merge branch 'master' of git://git.mplayerhq.hu/ffmpeg - -commit d0c772c8021702ca79ce2aceeba75902231c0101 -Author: michaelni -Date: Tue Jul 23 22:05:35 2002 +0000 - - patch by Fran -commit d103d4fac41b32915b45534d49d1e6a195b4220b -Author: Alexander Strange -Date: Wed Feb 3 01:00:14 2010 -0500 - - Simplify thread.h by removing the stub functions. - - They don't really help anything, if (HAVE_PTHREADS && ...) is sufficient. - -commit d15ab0f03a257293c0e13eac8b9b031da73c48f3 -Author: Alexander Strange -Date: Tue Jun 3 04:41:33 2008 -0400 - - Macroize some threading checks. - -commit d21f769ead6bd4c24d867b7e9beeb8ffcc86b271 -Author: Alexander Strange -Date: Wed Aug 6 20:36:04 2008 -0400 - - Revert renaming pthread.c. - -commit d2f8287d8526f814bcc88d827775d39ddc5c5f22 -Author: Alexander Strange -Date: Mon Jan 17 14:34:22 2011 -0500 - - Update todo.txt to put important things at the top - -commit d359ab19a25afa7dae20229e62dc0e37b6179ea7 -Author: michaelni -Date: Mon Jul 22 01:44:08 2002 +0000 - - adpcm encoding patch by Fran -commit d419a1c1d30e1b171fba7dc31a909e77a08016ba -Author: Alexander Strange -Date: Sun Aug 24 03:51:18 2008 -0400 - - Comment utility functions in pthread.c - -commit d460fd8d253c90f20536dffe69a6ea20dc113106 -Author: Alexander Strange -Date: Tue Aug 19 15:57:28 2008 -0400 - - Simplify codec close - -commit d4fad7c7f05e6fd7d677eaf1069e04c94b946a0c -Merge: f3f3d11 980ab8d -Author: Alexander Strange -Date: Tue Feb 2 21:41:11 2010 -0500 - - Merge mainline and libswscale. - - ffplay's pts reordering is better now, so ffplay.c has been reverted - to mainline. - - Conflicts: - ffplay.c - libavcodec/avcodec.h - libavcodec/h264.c - -commit d5227efafd855f028338480f937b6ad4a86ef7ac -Author: Alexander Strange -Date: Thu Jun 12 18:24:28 2008 -0400 - - Don't check MAX_THREADS unless slice threading is on. - -commit d5c16c23327d84373fca125b884254550b79c8d7 -Author: mmu_man -Date: Sun Jan 23 09:59:36 2005 +0000 - - Revert the fixed-size-sample patch as it brokes and others - WTF I thought I had commited this yesterday... was probably too asleep :commit d5ea5fc7342e3a1b082659bccd5ffd90a911b780 -Author: Alexander Strange -Date: Thu May 7 01:19:55 2009 -0400 - - Replace the number of frames option with a number of frames to skip. - - The old option wasn't really useful (ffmpeg -t saves more time) - and this is needed to deal with broken stream clips, which are - common and tend to decode differently under mt anyway, which I - don't really care about. - -commit d611b2bcb3ce231242f566cee08a61798a36abc8 -Author: Alexander Strange -Date: Thu Jun 18 05:03:36 2009 -0400 - - Fix race condition upon return from decode_init(). - - We can't call report_frame_progress on every returned frame, - because they may be returned while a past thread is still decoding - them. Instead ensure frames always have this called on them after - their decode is done. - - Should fix all bugs for valid H.264 streams without frame num gaps. - -commit d62b7c03b163c3dc067f122ab9fec44de87b37ae -Author: Alexander Strange -Date: Tue Mar 9 01:54:27 2010 -0500 - - VP3: Only call await_reference_row() for luma - - 4.3% -> 2.1% cpu on big_buck_bunny_1080p_stereo.ogg. - It should be further reducable since VP3 has limited MV range. - -commit d6bb0443c9b316b8cf29720524b4819fb2e6b6a1 -Author: Alexander Strange -Date: Thu Sep 4 01:50:20 2008 -0400 - - Don't mention nonexistant variables in comments - -commit d71a7eef9e540b00b0f91d840116e43206390645 -Author: Alexander Strange -Date: Mon May 24 16:45:27 2010 -0400 - - h264: Delete lines accidentally left behind during a merge - -commit d7cfe6d5cbffa42e178d88d7c647d37431e21861 -Author: Alexander Strange -Date: Tue Feb 1 22:20:19 2011 -0500 - - Fix dropped frames at the beginning of h264 decoding, fixes FATE tests - - Patch by Ronald Bultje (rsbultje@gmail.com) - -commit d8014c67ff1ef20ca05302dea9e262a3089d996e -Merge: 604ee54 4ce0d81 -Author: Alexander Strange -Date: Sat May 1 04:03:03 2010 -0400 - - Merge branch 'master' of git://git.mplayerhq.hu/ffmpeg - -commit d812c6f8b1d897734d6f7b5f1a5c95d3aa10a3ea -Author: Alexander Strange -Date: Thu Jun 24 02:25:25 2010 -0700 - - Fix crash on close when decoding a single-frame h264 file with 3+ threads - - Problematic code path: - 1. sps_buffers[0] is allocated in the first thread's codec context when the - decoder is opened. - 2. The first thread context is memcpy'd to the other threads by frame_thread_init(). - 3. The first thread is closed and its sps_buffers[0] is freed. - 4. The third thread is closed. - Because it never got to decode a frame, update_thread_context was never called, - and sps_buffers[0] still contained the first thread's pointer. - - Fixed by not trying to free sps/pps buffers if the thread wasn't initialized. - I didn't properly consider this when designing it but this seems to be the - best approach anyway. - - Fixes still2.mp4 crash from Chromium - -commit d84fc3dfd3e051c782d063ccba4cc8cadba38797 -Author: michaelni -Date: Tue Nov 5 00:56:08 2002 +0000 - - MIN/MAX sys/param.h patch by (Fran -commit d93fe0ea6b1b8121fdb9521fa7eeac0dc494deeb -Author: benoit -Date: Tue Nov 6 16:19:09 2007 +0000 - - Allow propagation of stream selection through the ASF demuxer to the - MMSH protocol handler. - Patch by Bj -�rn Axelsson: bjorn ; axelsson commit d955ab0dfa73578eaa6a9d1dcb821ce9db409738 -Author: Alexander Strange -Date: Tue Mar 29 04:53:11 2011 -0400 - - Update todo. More items appeared... - -commit da70ded7141aa191b92672c343cd29a0014d861f -Author: Alexander Strange -Date: Thu Dec 18 13:27:51 2008 -0500 - - Update todo - -commit da7bdb1273da15a90bfe08ead91e397247916d11 -Author: Alexander Strange -Date: Tue Jun 24 03:24:17 2008 -0400 - - Get rid of tabs - -commit da86d2da9f6a76238a9d788ecd77f714981e666d -Author: Alexander Strange -Date: Thu Sep 4 01:40:51 2008 -0400 - - Reindent. - -commit da95175e7ce1f911db992fef213322345200feaf -Author: Alexander Strange -Date: Mon Jul 14 01:52:37 2008 -0400 - - Add a parameter to not draw top/bottom in draw_edges. - -commit db2a99d28931128c8598067ae06444ab79f579f8 -Author: Alexander Strange -Date: Tue Jun 9 17:29:47 2009 -0700 - - Fix typo in comment. - -commit dbfbadaa095b65a724ac848d551cfa2aa33e2f6a -Author: Alexander Strange -Date: Tue May 11 05:16:14 2010 -0400 - - Update todo. - - Got another h264 bug report with the same cause as before. - -commit dc53861aadac1d43391b28e4e9793393b26394b9 -Author: Alexander Strange -Date: Wed Jun 18 20:52:34 2008 -0400 - - Always set decode progress to the maximum at the end of decoding - This saves doing it for frames with AC partitioning and such. - We can't do it if the codec didn't return a frame, so there is still an opportunity for deadlocks here, maybe. - -commit dc7c4d436681e43a9f351dd18f70d0dc008aa55e -Author: benoit -Date: Thu Jan 10 10:18:00 2008 +0000 - - Make MMX vectors constants. - Patch by Diego 'Flameeyes' Petten -� flameeyes commit dd9e04497937b7fffdcc65a2b41e36089412d975 -Author: Alexander Strange -Date: Tue Mar 29 17:18:21 2011 -0400 - - Remove unnecessary parameter from ff_thread_init() and fix behavior - - thread_count passed to ff_thread_init() is only used to set AVCodecContext. - thread_count, and can be removed. Instead move it to the legacy implementation - of avcodec_thread_init(). - - This also fixes the problem that calling avcodec_thread_init() with pthreads - enabled did not set it since ff1efc524cb3c60f2f746e3b4550bb1a86c65316. - -commit ddc8310d2a9300139d1821954dfa2d0b775edaa1 -Author: Alexander Strange -Date: Thu Feb 11 22:12:03 2010 -0500 - - Fix mutex leak introduced in 0040d6f2ba. - - If allocate_progress() failed, the error condition returned before - unlocking its mutex. - -commit de365823ec9546a3bd688690e79fc15281a68f1f -Author: Alexander Strange -Date: Wed Jun 23 01:26:42 2010 -0700 - - todo: fix ugly word wrapping - -commit de736aacd945d66109197a6f04baf915d458f5ac -Merge: 7eac0bc 780a37c -Author: Alexander Strange -Date: Thu Jun 18 17:53:09 2009 -0400 - - Merge mainline. - -commit de8abf54671555bb166bb1d44a34fe14e360e2a5 -Author: Alexander Strange -Date: Sun Jan 24 16:37:24 2010 -0500 - - Rename and document MAX_DELAYED_RELEASED_BUFFERS. - -commit dedc2982f2f845357f28dff401fe5df8510c6a8f -Author: benoit -Date: Tue May 22 08:28:32 2007 +0000 - - id3v2 writer - patch by Andreas -�commit df444fadf045bf70058da9b074b8f848fc2209b1 -Merge: 14bdf76 1476e6a -Author: Alexander Strange -Date: Tue Mar 9 02:04:43 2010 -0500 - - Merge branch 'master' of git://git.mplayerhq.hu/ffmpeg - -commit df5d7acdcd0dcbfca6f8fd4f76c9369cb1674435 -Author: Alexander Strange -Date: Sat Aug 16 17:32:24 2008 -0400 - - Don't reuse the user's AVCodecContext for the first decoding thread, and copy more values between them as needed. - - This fixes a large class of race conditions (coded_frame works again) and should improve frame dropping. - -commit dfb8be0a60b9562cf7bb6e54dd67088ff51f83b0 -Author: Alexander Strange -Date: Tue Jun 24 21:35:14 2008 -0400 - - Call avcodec_get_frame_defaults() before decoding. - -commit e0285f04bed7fefba5f75d05c81b145f44fc49f5 -Author: Alexander Strange -Date: Thu Jul 31 18:40:46 2008 -0400 - - Use got_extradata instead of frame_number to guard against rereading extradata. - - frame_number is no longer valid internally, since I don't want to change its definition from the user's perspective. - mpeg12 does the same thing, but I can't find or create any mpeg1+extradata samples to check it. - -commit e044d5c79ab340cf52842ba8452d670959eb37c0 -Merge: 3c3a364 5115473 -Author: Alexander Strange -Date: Fri Nov 7 04:54:47 2008 -0500 - - Merge mainline into ffmpeg-mt - - - Handle reordered_opaque properly - - Picture.field_picture is a duplicate of Picture.mbaff, - but is necessary, since interlaced_frame can't be trusted - and mbaff can't be interpreted without it. - -commit e0dc361e0f0aa315320a549a4fda3424226c556f -Author: Alexander Strange -Date: Mon Sep 1 03:35:23 2008 -0400 - - Update todo - -commit e174657cbb973abf5de9085d00d85ac04d29a475 -Author: Alexander Strange -Date: Thu Aug 28 17:11:09 2008 -0400 - - Move avcodec_thread_init call before avcodec_open in ffplay. - - It makes no sense to have it after, since a decoder is not forbidden from reading it during init. - Encoders already do. - -commit e1f49541b976cdd091aa41f116e7c9fd0c740cf3 -Author: Alexander Strange -Date: Tue Jun 17 23:35:55 2008 -0400 - - Fix rounding for mpeg1 MVs. - -commit e23b687201a076161384fbc7a2f76bd0092dd34c -Author: Alexander Strange -Date: Wed Jan 20 02:36:18 2010 -0500 - - Include the delay from frame threads in has_b_frames. - - This is an API change, but anything that already counted thread_count - just has an incorrectly high max delay size, which shouldn't be a - problem. - -commit e2b9383929e2c703eabd1df8afcb9fa5ad7106ec -Author: Alexander Strange -Date: Sun Jun 15 17:36:59 2008 -0400 - - Add choice of threading algorithm to AVCodecContext. - - Use it to simplify USE_* macros. - FF_THREAD_AUTO needs to be handled better - even if a codec can handle frame-threads, we still don't want to use them if there are enough slices available. - -commit e2ecdd48d664f2660bfd661f1cef6276b986743b -Author: Alexander Strange -Date: Fri Jul 25 03:12:58 2008 -0400 - - Simplify mpeg_decode_update_context. - -commit e303003362829a7f2f1dcbc45d6abc9ac7a59b6a -Author: Alexander Strange -Date: Thu Aug 14 22:59:01 2008 -0400 - - Reindent. - -commit e340cacc56545c5fc3a903c68fec99e8921d579e -Author: Alexander Strange -Date: Sat Nov 8 06:13:23 2008 -0500 - - Disable r15412 for now to avoid crashes. - - update_context can't handle picture pts not pointing to picture and I couldn't think of a better way to do it at 5 am. - May not actually fix anything. - -commit e345a54e5f86d9777e4c3ccb04aad84f9cd77ff0 -Author: Alexander Strange -Date: Mon Mar 8 04:55:43 2010 -0500 - - Add optimization note to todo. - -commit e39c3828e02fe71ce627170bc8c26a558f29f4b8 -Author: Alexander Strange -Date: Mon Feb 15 00:39:39 2010 -0500 - - Update todo - -commit e3f13a4f70b1310309ebb462b1011721cb3692fe -Author: Alexander Strange -Date: Thu Sep 4 14:05:31 2008 -0400 - - Rename new symbols to be shorter - -commit e4565c5731bfcd8808d02f47f115e21dc6fc8b35 -Merge: 4b9ce55 fb61a7c -Author: Alexander Strange -Date: Thu Mar 10 02:25:55 2011 -0500 - - Merge branch 'master' of git://git.ffmpeg.org/ffmpeg - - Conflicts: - .gitignore - doc/APIchanges - ffplay.c - libavcodec/arm/asm-offsets.h - libavcodec/avcodec.h - libavcodec/h264.c - libavcodec/mpegvideo.h - libavcodec/options.c - libavcodec/pthread.c - libavcodec/thread.h - libavcodec/utils.c - libavcodec/vp3.c - libavcodec/vp8.c - libavformat/utils.c - -commit e45cf6d46cb45e6edcf9e4ac368b2a013ba30158 -Author: Alexander Strange -Date: Thu Aug 14 04:01:08 2008 -0400 - - Add todo and some other files. - - Trailing whitespace in mplayer isn't my fault. - -commit e4df986f3d2d3e1be9b0f4eeda463fa854910b8f -Author: Alexander Strange -Date: Thu Aug 28 00:41:52 2008 -0400 - - Revert unnecessary setting of the wrong variable - -commit e53d020b37ca26ffa4cdb22d2b40321897f52ba9 -Author: Alexander Strange -Date: Sat Aug 23 20:39:06 2008 -0400 - - Warn if users try to use frame threading without pthreads. - -commit e717770ee8437c296e012e908b772ba2eaeb2ed3 -Author: Alexander Strange -Date: Tue Jul 15 03:16:22 2008 -0400 - - Create next_delayed_pic for multithreading purposes - unreference_pic is intentionally unchanged. - -commit e71a2b5017728022fa1f992a8b541260615016b2 -Author: Alexander Strange -Date: Wed Jun 18 23:22:01 2008 -0400 - - Use USE_FRAME_THREADING instead of checking for thread_opaque, since it might be the wrong type. - -commit e74ef89858732b9fc4a90c8ec8fbb701407eb987 -Author: Alexander Strange -Date: Wed May 28 22:50:22 2008 -0400 - - Split setting avctx->thread_count from the rest of pthread init. - Make sure it's called from whichever of avcodec_open and avcodec_thread_init comes later. - -commit e7519b6532409e332fc9727ea5a57e148e6655a6 -Author: benoit -Date: Thu May 15 01:03:48 2008 +0000 - - Make av_set_string() fail when number could not be set. - Patch by Stefano Sabatini stefanocommit e8bc7da9d69234ebbcbde371c5a0e20f8b5cfccc -Author: Alexander Strange -Date: Mon Jan 25 02:59:00 2010 -0500 - - Remove accidental extra variable declaration - -commit e95251807c0ae66ffef1e4ad113b9773a287fa5a -Author: Alexander Strange -Date: Sat Jun 27 22:14:45 2009 -0400 - - Get rid of static variables in VP3. - - These are pointless and might behave wrong with thread-local - statics. - -commit e9a0e5eaf5207321baf90160b1094300f3810ecf -Author: Alexander Strange -Date: Mon Jun 23 21:21:44 2008 -0400 - - Use FF_INPUT_BUFFER_PADDING_SIZE for the buffer. - -commit ea396d38059476a54c5855e0bd81955c60238b22 -Author: Alexander Strange -Date: Wed Nov 3 22:50:02 2010 -0400 - - Rewrite comments in thread.h and fix parameter names in ff_thread_decode_frame - -commit ebce21c15f3aaf1b4512436ed8fc2e71a504bb11 -Merge: 3630d89 5570afd -Author: Alexander Strange -Date: Thu Dec 18 12:49:54 2008 -0500 - - Merge mainline. - - Conflicts: - - libavcodec/avcodec.h - libavcodec/mpegvideo.c - libavcodec/utils.c - -commit ed3e2ae1277cc425ef133f10700ace86629381ef -Author: Alexander Strange -Date: Sun Jul 13 16:05:09 2008 -0400 - - Remove useless variable. - -commit ed42183540e2a886a7368b8220e0b50aaf363551 -Author: Alexander Strange -Date: Thu Sep 30 16:53:03 2010 -0400 - - Fix hang decoding VP3/Theora. - - draw_horiz_band changed to only draw the displayed height instead of the - decoded height. This meant that we never reported progress for the last few - decoded pixels, but still awaited them, which deadlocked. - - This shouldn't cause any race conditions, because it always decodes the last - few pixels along with the last decoded pixels. - - Patch by Yuriy Kaminsky (yumkam mail ru). - -commit ed5e8392e2fce8e6b0468de4ae1a4310d338ee46 -Author: Alexander Strange -Date: Thu Aug 28 02:29:08 2008 -0400 - - Simplify(?) threaded avcodec_flush_buffers - -commit ed728b0a05c2154b07cc3d8330d5900dbc45f1d7 -Author: Alexander Strange -Date: Tue May 27 23:25:47 2008 -0400 - - Guard against avcodec_thread_execute() being called without being setup. - -commit edb60439feb2c5d39cda314178686eea151185b3 -Author: Alexander Strange -Date: Mon Nov 1 12:54:47 2010 -0400 - - vp3: Assume MVs are their maximum length of 16 pixels - - This makes it worse (although slightly simpler) in preparation for further - optimization. - -commit ee8430539ec7cc23b7cf6332e26751f539315d5b -Author: Alexander Strange -Date: Sun Jul 6 15:56:28 2008 -0400 - - Don't include the codecs' threading support functions without some kind of threading enabled. - As a side effect this makes non-pthreads threading even more problematic. - -commit eed4b9708287066ccc1b3042110f7c3379f63ee2 -Author: Alexander Strange -Date: Thu Aug 28 01:44:44 2008 -0400 - - Simplify disabling MB skipping - -commit ef26f878e0e581cb61f1e9b376bec4f7ff07397a -Author: Alexander Strange -Date: Tue Mar 9 01:48:18 2010 -0500 - - Cosmetics: fix outdated comment - -commit ef2d8664f1eff56e969801ecd1c5b7c729902819 -Merge: 11b1a8e 9c7037f -Author: Alexander Strange -Date: Tue Jun 8 14:29:22 2010 -0700 - - Merge mainline and libswscale - -commit efd1fb08db3e7964357dc00fd514cfb156b4ee69 -Author: Alexander Strange -Date: Thu Jun 11 11:33:09 2009 -0700 - - Reindent. - -commit f139f42301a5ee861f1a91cdfcceb2a85349fa29 -Merge: 70fb3fd 7210b4e -Author: Luca Barbato -Date: Sun Jun 22 12:08:59 2008 +0200 - - Merge branch 'master' of git://git.mplayerhq.hu/ffmpeg - -commit f143b66d9bf8b23985bf8ec6acf8273c3e9ccd1d -Author: Alexander Strange -Date: Tue Aug 19 21:12:32 2008 -0400 - - Handle NULL threads if they aren't started because of an init error. - -commit f1936d87290c7444090d6cb101b0d7c9270f0a81 -Author: benoit -Date: Thu Jun 24 15:22:33 2010 +0000 - - Set an opaque alpha value when decoding rgba ffv1. - Patch by Thad Ward coderjoe69commit f1fe312cb47cbc540da764cbab3582739a20a8d2 -Author: Alexander Strange -Date: Thu Jun 5 20:30:58 2008 -0400 - - Cosmetics: make thread.h look like other prototypes. - -commit f374d2ee585d7f6c98ffd3a7803223552497904e -Author: Alexander Strange -Date: Fri Jan 21 04:13:06 2011 -0500 - - Simplify change to avcodec_close() and fix a merge glitch in avcodec_open() - -commit f3c88f32b8c806b352cf6e00d6ac80fd32e9f54c -Author: Alexander Strange -Date: Wed Sep 3 11:45:09 2008 -0400 - - Field picture API support - -commit f3f3d1189de648862ca204676dd7591262f590df -Author: Alexander Strange -Date: Mon Jan 25 04:12:34 2010 -0500 - - Add todo note about a change to thread.h I mean to do. - -commit f4d4d43f3a596941b2214ac1e71bb818eb230d6b -Author: Alexander Strange -Date: Fri Jan 21 02:43:30 2011 -0500 - - Minor update to thread.h comment - -commit f4fb456b114eafc22b8ab9bb0bb3e7f13a4fbd9a -Author: Alexander Strange -Date: Tue Nov 2 02:56:12 2010 -0400 - - vp3: Revert motion_y removal - - Although it doesn't have much of an effect on speed either way, I reconsidered - the simplification I wanted to do, and now I'd rather keep this as an example - of proper multithreading structure. - -commit f52df8ebae0ad1db15c5e804a458ca81e04c6156 -Author: Alexander Strange -Date: Mon Aug 25 14:33:09 2008 -0400 - - Fix whitespace mistake - -commit f550857de3ffcb6b2980c4c952b7e84db478d399 -Merge: d62b7c0 a175a04 -Author: Alexander Strange -Date: Sat Mar 27 02:01:59 2010 -0400 - - Merge mainline. - - Conflicts: - libavcodec/avcodec.h - libavcodec/h264.c - libavcodec/options.c - libavcodec/vp3.c - -commit f5596f046c05bc7d8afda7658f891d69587934f0 -Author: Alexander Strange -Date: Mon Nov 15 01:38:36 2010 -0500 - - Rewrite comments and cosmetic changes to pthread.c - - Some small code changes, but there shouldn't be any behavior change. - -commit f695698a78e07a45f4cc9d24ae95fd73f25600e7 -Author: Alexander Strange -Date: Wed Jan 26 12:43:05 2011 -0500 - - Update todo.txt with review feedback - -commit f6d7d0c03c8d7c91a39c9374d9cee83e32627681 -Author: Alexander Strange -Date: Sun Feb 6 19:04:21 2011 -0500 - - pthread: Cosmetic changes and renaming - - Rename frame->packet, picture->frame. - Use /**< to point to the right field in doxygen. - Fix some typos. - -commit f71e7068faabecc32abc798a09b9df403f85e33f -Merge: 2bbb64d a4f892e -Author: Alexander Strange -Date: Thu Jan 6 05:45:03 2011 -0500 - - Merge mainline. - - Conflicts: - doc/APIchanges - -commit f7cc4441b7046a542ef655575ce3e8684ff12e02 -Merge: bba0e09 9eac0a6 -Author: Alexander Strange -Date: Sat Jun 20 15:58:38 2009 -0400 - - Merge mainline. - -commit f9515a4e57356bce4d652451fbaccd071d91dbe9 -Merge: a903974 0c28ee7 -Author: Alexander Strange -Date: Wed Nov 11 15:38:20 2009 -0500 - - Merge mainline. - - In h264, next_outputed_poc is now used in decode_postinit() - where mainline uses outputed_poc. - - Conflicts: - libavcodec/avcodec.h - libavcodec/h263dec.c - libavcodec/h264.c - libavcodec/utils.c - -commit f9b01bbf85d68f23a81ec5325fae81c8518cc385 -Author: Alexander Strange -Date: Mon May 25 20:06:00 2009 -0400 - - Remove unnecessary check from mc_dir_part_y(). - - This was already remove from mc_dir_part(). I hope it's unnecessary - here too. - -commit fa3f68f39f4a96a1170eadfe6ba4677d5d25017f -Author: Alexander Strange -Date: Sat Aug 16 04:23:20 2008 -0400 - - Document functions in thread.h - -commit fa8a82e991280b7ccac89ed2a29b332e609bc370 -Author: Luca Barbato -Date: Sat May 3 15:18:01 2008 +0200 - - Switch to the gitorius mirror of libswscale - -commit fafaae289235b361b6786745dcbdf6fa938c3c2e -Author: Alexander Strange -Date: Thu Dec 4 01:46:22 2008 -0500 - - Don't compare pthread_t to NULL - - It's not required to be a pointer, and it doesn't - need to be validated since pthread_join will just - return an error if it doesn't exist. - - Reverts f143b66d9bf8b23985bf8ec6acf8273c3e9ccd1d - -commit fb1afd9eba5fe2752b83c4b3de24ed88e14b534a -Author: Alexander Strange -Date: Sat Mar 14 00:56:54 2009 -0400 - - Rewrite todo (again...) split up so other people should be able to understand it. - Add yuvcmp, though maybe it should go somewhere else. - -commit fb1f31ff6cbcbbde72920e731223fd0fb8f05d02 -Author: Alexander Strange -Date: Sat Aug 30 04:26:47 2008 -0400 - - Update multithreading doc - -commit fb7dfc0e9e9ff8a5030cde46e28d49d6ce73e453 -Author: Alexander Strange -Date: Sun Jan 24 22:15:56 2010 -0500 - - Always call avcodec_thread_init() in avcodec_open(). - - This matches upstream behavior, but neither of them have any effect. - It allows implementing automatic thread counts, though. - -commit fbb871069bd106bfd47d215216be01d1ef30aec8 -Author: Alexander Strange -Date: Sun Feb 14 23:47:42 2010 -0500 - - Reindent vp3.c. - -commit fc957c71da6c9a7e5c769e15f256652352f7b4a4 -Author: Alexander Strange -Date: Mon May 24 17:31:38 2010 -0400 - - Fix compile with --disable-optimizations. - - gcc can't remove dead code like: - int threaded = HAVE_PTHREADS; - if (threaded) ... - -commit fd1b8587a4186b30c5922e3053c869726cca23df -Author: Alexander Strange -Date: Thu Nov 4 03:55:19 2010 -0400 - - Remove ff_thread_finish_frame() as it seems not useful enough - -commit fd9ae0065aa268c4b3e46706d775cf4ba1df8ed3 -Author: Alexander Strange -Date: Wed May 28 01:34:30 2008 -0400 - - Obfusticate the decoder to make the context copyable earlier. - -commit fda3e64cd474b5886457c6a1ffff8906f76a9bbc -Author: Alexander Strange -Date: Thu Jun 18 16:11:26 2009 -0400 - - Mimic: move up a line changing buf_ptrs. - - No effect on decoding, but it breaks the rule about changing - things after frame_setup_done. - -commit fdb381e68a3828dcc7eb1c93cf174b702cc78d2c -Author: Alexander Strange -Date: Wed Feb 17 00:39:42 2010 -0500 - - Cosmetics: rename function parameters - -commit fe4e238f573bab53760408b3376dbba0255e5b51 -Author: Alexander Strange -Date: Mon May 25 20:00:50 2009 -0400 - - Fix unnecessarily long wait for direct+progressive MBs. - -commit fe529c93b41f2d7406b76e7e5943b82acd789cb4 -Author: benoit -Date: Tue May 22 08:23:45 2007 +0000 - - id3v2 reader - patch by Andreas -�commit febe154099b8f31817e8c047cb3c8dee51b52117 -Author: Alexander Strange -Date: Wed Jun 16 14:54:00 2010 -0700 - - Fix merge glitch: pix_fmts should have been deleted - -commit feca6e0009da2b344b2c1be8f30a55c23623d77e -Merge: 2485cfd feaafaa -Author: Alexander Strange -Date: Mon May 25 19:58:17 2009 -0400 - - Merge branch 'master' of git://git.mplayerhq.hu/ffmpeg - -commit ff08d3a1629ab442f78a1d2fde496b727a1a9deb -Author: Alexander Strange -Date: Sat Jul 12 22:26:43 2008 -0400 - - Fix MPV_lowest_referenced_row to not be completely wrong. - The not handling qpel and emu_edge bugs were masked by the other bugs preventing almost all parallelism. - -commit ff4c627baab555a4ea6275c919d9f4259adc0e58 -Author: Alexander Strange -Date: Tue Oct 6 15:41:35 2009 -0400 - - Word-wrap todo.txt. - - Try to make some of it cleaner - so other people can actually - use it. - -commit ff69da3564ab912f7e7331f8c8389a96a254e16f -Author: Alexander Strange -Date: Sun Aug 1 20:33:57 2010 -0700 - - Fix the decoder not returning any frames if the frame count is less than the number of threads - - Fixes ./mt-work/test.sh with still2.mp4 - diff --git a/doc/ffmpeg.texi b/doc/ffmpeg.texi index ecf147ab55..6daf4ecad7 100644 --- a/doc/ffmpeg.texi +++ b/doc/ffmpeg.texi @@ -407,6 +407,10 @@ prefix is ``ffmpeg2pass''. The complete file name will be @file{PREFIX-N.log}, where N is a number specific to the output stream +Note that this option is overwritten by a local option of the same name +when using @code{-vcodec libx264}. That option maps to the x264 option stats +which has a different syntax. + @item -vlang @var{code} Set the ISO 639 language code (3 letters) of the current video stream. diff --git a/doc/filters.texi b/doc/filters.texi index 7d008bc736..ef10bcb9b2 100644 --- a/doc/filters.texi +++ b/doc/filters.texi @@ -82,7 +82,7 @@ Follows a BNF description for the filtergraph syntax: @var{LINKLABEL} ::= "[" @var{NAME} "]" @var{LINKLABELS} ::= @var{LINKLABEL} [@var{LINKLABELS}] @var{FILTER_ARGUMENTS} ::= sequence of chars (eventually quoted) -@var{FILTER} ::= [@var{LINKNAMES}] @var{NAME} ["=" @var{ARGUMENTS}] [@var{LINKNAMES}] +@var{FILTER} ::= [@var{LINKLABELS}] @var{NAME} ["=" @var{FILTER_ARGUMENTS}] [@var{LINKLABELS}] @var{FILTERCHAIN} ::= @var{FILTER} [,@var{FILTERCHAIN}] @var{FILTERGRAPH} ::= @var{FILTERCHAIN} [;@var{FILTERGRAPH}] @end example @@ -2549,6 +2549,9 @@ For example: will create two separate outputs from the same input, one cropped and one padded. +@section swapuv +Swap U & V plane. + @section thumbnail Select the most representative frame in a given sequence of consecutive frames. diff --git a/doc/issue_tracker.txt b/doc/issue_tracker.txt index d487f66830..27b0009b58 100644 --- a/doc/issue_tracker.txt +++ b/doc/issue_tracker.txt @@ -24,7 +24,7 @@ a mail for every change to every issue. The subscription URL for the ffmpeg-trac list is: http(s)://ffmpeg.org/mailman/listinfo/ffmpeg-trac The URL of the webinterface of the tracker is: -http(s)://ffmpeg.org/trac/ffmpeg +http(s)://trac.ffmpeg.org Type: ----- diff --git a/doc/platform.texi b/doc/platform.texi index b52e13a94d..b79b8b10b8 100644 --- a/doc/platform.texi +++ b/doc/platform.texi @@ -51,14 +51,15 @@ The toolchain provided with Xcode is sufficient to build the basic unacelerated code. Mac OS X on PowerPC or ARM (iPhone) requires a preprocessor from -@url{http://github.com/yuvi/gas-preprocessor} to build the optimized -assembler functions. Just download the Perl script and put it somewhere +@url{https://github.com/FFmpeg/gas-preprocessor} or +@url{https://github.com/yuvi/gas-preprocessor} to build the optimized +assembler functions. Put the Perl script somewhere in your PATH, FFmpeg's configure will pick it up automatically. Mac OS X on amd64 and x86 requires @command{yasm} to build most of the optimized assembler functions. @uref{http://www.finkproject.org/, Fink}, @uref{http://www.gentoo.org/proj/en/gentoo-alt/prefix/bootstrap-macos.xml, Gentoo Prefix}, -@uref{http://mxcl.github.com/homebrew/, Homebrew} +@uref{https://mxcl.github.com/homebrew/, Homebrew} or @uref{http://www.macports.org, MacPorts} can easily provide it. diff --git a/doc/protocols.texi b/doc/protocols.texi index da0e39f56c..cbefc24109 100644 --- a/doc/protocols.texi +++ b/doc/protocols.texi @@ -242,7 +242,7 @@ data transferred over RDT). The muxer can be used to send a stream using RTSP ANNOUNCE to a server supporting it (currently Darwin Streaming Server and Mischa Spiegelmock's -@uref{http://github.com/revmischa/rtsp-server, RTSP server}). +@uref{https://github.com/revmischa/rtsp-server, RTSP server}). The required syntax for a RTSP url is: @example diff --git a/ffmpeg.c b/ffmpeg.c index 463e1f476e..b1fc15800e 100644 --- a/ffmpeg.c +++ b/ffmpeg.c @@ -505,7 +505,7 @@ static int alloc_buffer(AVCodecContext *s, InputStream *ist, FrameBuffer **pbuf) const int v_shift = i==0 ? 0 : v_chroma_shift; if (s->flags & CODEC_FLAG_EMU_EDGE) buf->data[i] = buf->base[i]; - else + else if (buf->base[i]) buf->data[i] = buf->base[i] + FFALIGN((buf->linesize[i]*edge >> v_shift) + (pixel_size*edge >> h_shift), 32); @@ -2626,32 +2626,35 @@ static int transcode_init(OutputFile *output_files, int nb_output_files, break; } /* two pass mode */ - if (codec->codec_id != CODEC_ID_H264 && - (codec->flags & (CODEC_FLAG_PASS1 | CODEC_FLAG_PASS2))) { + if (codec->flags & (CODEC_FLAG_PASS1 | CODEC_FLAG_PASS2)) { char logfilename[1024]; FILE *f; snprintf(logfilename, sizeof(logfilename), "%s-%d.log", pass_logfilename_prefix ? pass_logfilename_prefix : DEFAULT_PASS_LOGFILENAME_PREFIX, i); - if (codec->flags & CODEC_FLAG_PASS2) { - char *logbuffer; - size_t logbuffer_size; - if (cmdutils_read_file(logfilename, &logbuffer, &logbuffer_size) < 0) { - av_log(NULL, AV_LOG_FATAL, "Error reading log file '%s' for pass-2 encoding\n", - logfilename); - exit_program(1); + if (!strcmp(ost->enc->name, "libx264")) { + av_dict_set(&ost->opts, "stats", logfilename, AV_DICT_DONT_OVERWRITE); + } else { + if (codec->flags & CODEC_FLAG_PASS2) { + char *logbuffer; + size_t logbuffer_size; + if (cmdutils_read_file(logfilename, &logbuffer, &logbuffer_size) < 0) { + av_log(NULL, AV_LOG_FATAL, "Error reading log file '%s' for pass-2 encoding\n", + logfilename); + exit_program(1); + } + codec->stats_in = logbuffer; } - codec->stats_in = logbuffer; - } - if (codec->flags & CODEC_FLAG_PASS1) { - f = fopen(logfilename, "wb"); - if (!f) { - av_log(NULL, AV_LOG_FATAL, "Cannot write log file '%s' for pass-1 encoding: %s\n", - logfilename, strerror(errno)); - exit_program(1); + if (codec->flags & CODEC_FLAG_PASS1) { + f = fopen(logfilename, "wb"); + if (!f) { + av_log(NULL, AV_LOG_FATAL, "Cannot write log file '%s' for pass-1 encoding: %s\n", + logfilename, strerror(errno)); + exit_program(1); + } + ost->logfile = f; } - ost->logfile = f; } } } @@ -4054,8 +4057,6 @@ static OutputStream *new_video_stream(OptionsContext *o, AVFormatContext *oc) if (p) p++; } video_enc->rc_override_count = i; - if (!video_enc->rc_initial_buffer_occupancy) - video_enc->rc_initial_buffer_occupancy = video_enc->rc_buffer_size * 3 / 4; video_enc->intra_dc_precision = intra_dc_precision - 8; if (do_psnr) @@ -4065,9 +4066,11 @@ static OutputStream *new_video_stream(OptionsContext *o, AVFormatContext *oc) if (do_pass) { if (do_pass & 1) { video_enc->flags |= CODEC_FLAG_PASS1; + av_dict_set(&ost->opts, "flags", "+pass1", AV_DICT_APPEND); } if (do_pass & 2) { video_enc->flags |= CODEC_FLAG_PASS2; + av_dict_set(&ost->opts, "flags", "+pass2", AV_DICT_APPEND); } } @@ -4693,7 +4696,8 @@ static int opt_target(OptionsContext *o, const char *opt, const char *arg) for (j = 0; j < nb_input_files; j++) { for (i = 0; i < input_files[j].nb_streams; i++) { AVCodecContext *c = input_files[j].ctx->streams[i]->codec; - if (c->codec_type != AVMEDIA_TYPE_VIDEO) + if (c->codec_type != AVMEDIA_TYPE_VIDEO || + !c->time_base.num) continue; fr = c->time_base.den * 1000 / c->time_base.num; if (fr == 25000) { diff --git a/ffplay.c b/ffplay.c index 09623db374..7ebbaa93e5 100644 --- a/ffplay.c +++ b/ffplay.c @@ -1611,7 +1611,7 @@ static int input_reget_buffer(AVCodecContext *codec, AVFrame *pic) if (pic->data[0] == NULL) { pic->buffer_hints |= FF_BUFFER_HINTS_READABLE; - return codec->get_buffer(codec, pic); + return input_get_buffer(codec, pic); } if ((codec->width != ref->video->w) || (codec->height != ref->video->h) || diff --git a/ffprobe.c b/ffprobe.c index ca6133e323..48c813a17c 100644 --- a/ffprobe.c +++ b/ffprobe.c @@ -1790,6 +1790,10 @@ int main(int argc, char **argv) if (!print_format) print_format = av_strdup("default"); + if (!print_format) { + ret = AVERROR(ENOMEM); + goto end; + } w_name = av_strtok(print_format, "=", &buf); w_args = buf; diff --git a/ffserver.c b/ffserver.c index 79463c0e64..ab18d56397 100644 --- a/ffserver.c +++ b/ffserver.c @@ -562,9 +562,11 @@ static void start_multicast(void) default_port = 6000; for(stream = first_stream; stream != NULL; stream = stream->next) { if (stream->is_multicast) { + unsigned random0 = av_lfg_get(&random_state); + unsigned random1 = av_lfg_get(&random_state); /* open the RTP connection */ snprintf(session_id, sizeof(session_id), "%08x%08x", - av_lfg_get(&random_state), av_lfg_get(&random_state)); + random0, random1); /* choose a port if none given */ if (stream->multicast_port == 0) { @@ -3086,9 +3088,12 @@ static void rtsp_cmd_setup(HTTPContext *c, const char *url, found: /* generate session id if needed */ - if (h->session_id[0] == '\0') + if (h->session_id[0] == '\0') { + unsigned random0 = av_lfg_get(&random_state); + unsigned random1 = av_lfg_get(&random_state); snprintf(h->session_id, sizeof(h->session_id), "%08x%08x", - av_lfg_get(&random_state), av_lfg_get(&random_state)); + random0, random1); + } /* find rtp session, and create it if none found */ rtp_c = find_rtp_session(h->session_id); @@ -3457,6 +3462,9 @@ static AVStream *add_av_stream1(FFStream *stream, AVCodecContext *codec, int cop { AVStream *fst; + if(stream->nb_streams >= FF_ARRAY_ELEMS(stream->streams)) + return NULL; + fst = av_mallocz(sizeof(AVStream)); if (!fst) return NULL; @@ -3802,6 +3810,9 @@ static void add_codec(FFStream *stream, AVCodecContext *av) { AVStream *st; + if(stream->nb_streams >= FF_ARRAY_ELEMS(stream->streams)) + return; + /* compute default parameters */ switch(av->codec_type) { case AVMEDIA_TYPE_AUDIO: diff --git a/libavcodec/4xm.c b/libavcodec/4xm.c index d665436844..d089dc3aaf 100644 --- a/libavcodec/4xm.c +++ b/libavcodec/4xm.c @@ -25,6 +25,7 @@ */ #include "libavutil/intreadwrite.h" +#include "libavutil/avassert.h" #include "avcodec.h" #include "dsputil.h" #include "get_bits.h" @@ -347,6 +348,10 @@ static void decode_p_block(FourXContext *f, uint16_t *dst, uint16_t *src, int lo decode_p_block(f, dst , src , log2w, log2h, stride); decode_p_block(f, dst + (1<version<2){ + if (start > src || src > end) { + av_log(f->avctx, AV_LOG_ERROR, "mv out of pic\n"); + return; + } mcdc(dst, src, log2w, h, stride, 1, 0); }else if(code == 4){ if (f->g.buffer_end - f->g.buffer < 1){ @@ -368,6 +373,10 @@ static void decode_p_block(FourXContext *f, uint16_t *dst, uint16_t *src, int lo av_log(f->avctx, AV_LOG_ERROR, "wordstream overread\n"); return; } + if (start > src || src > end) { + av_log(f->avctx, AV_LOG_ERROR, "mv out of pic\n"); + return; + } mcdc(dst, src, log2w, h, stride, 0, bytestream2_get_le16(&f->g2)); }else if(code == 6){ if (f->g2.buffer_end - f->g2.buffer < 2){ @@ -394,6 +403,8 @@ static int decode_p_frame(FourXContext *f, const uint8_t *buf, int length){ unsigned int bitstream_size, bytestream_size, wordstream_size, extra, bytestream_offset, wordstream_offset; if(f->version>1){ + if (length < 20) + return AVERROR_INVALIDDATA; extra=20; if (length < extra) return -1; @@ -551,7 +562,10 @@ static int decode_i_mb(FourXContext *f){ return 0; } -static const uint8_t *read_huffman_tables(FourXContext *f, const uint8_t * const buf, int buf_size){ +static const uint8_t *read_huffman_tables(FourXContext *f, + const uint8_t * const buf, + int buf_size) +{ int frequency[512]; uint8_t flag[512]; int up[512]; @@ -572,6 +586,9 @@ static const uint8_t *read_huffman_tables(FourXContext *f, const uint8_t * const if (start <= end && ptr_end - ptr < end - start + 1 + 1) return NULL; + if (end < start || buf_size < 0) + return NULL; + for(i=start; i<=end; i++){ frequency[i]= *ptr++; } @@ -665,8 +682,8 @@ static int decode_i2_frame(FourXContext *f, const uint8_t *buf, int length){ color[0]= bytestream2_get_le16u(&g3); color[1]= bytestream2_get_le16u(&g3); - if(color[0]&0x8000) av_log(NULL, AV_LOG_ERROR, "unk bit 1\n"); - if(color[1]&0x8000) av_log(NULL, AV_LOG_ERROR, "unk bit 2\n"); + if(color[0]&0x8000) av_log(f->avctx, AV_LOG_ERROR, "unk bit 1\n"); + if(color[1]&0x8000) av_log(f->avctx, AV_LOG_ERROR, "unk bit 2\n"); color[2]= mix(color[0], color[1]); color[3]= mix(color[1], color[0]); @@ -694,7 +711,10 @@ static int decode_i_frame(FourXContext *f, const uint8_t *buf, int length){ unsigned int prestream_size; const uint8_t *prestream; - if (bitstream_size > (1<<26) || length < bitstream_size + 12) { + if (bitstream_size > (1 << 26)) + return AVERROR_INVALIDDATA; + + if (length < bitstream_size + 12) { av_log(f->avctx, AV_LOG_ERROR, "packet size too small\n"); return AVERROR_INVALIDDATA; } @@ -702,15 +722,19 @@ static int decode_i_frame(FourXContext *f, const uint8_t *buf, int length){ prestream_size = 4 * AV_RL32(buf + bitstream_size + 4); prestream = buf + bitstream_size + 12; - if (prestream_size > (1<<26) || - prestream_size != length - (bitstream_size + 12)){ + if(prestream_size + bitstream_size + 12 != length + || prestream_size > (1<<26)){ av_log(f->avctx, AV_LOG_ERROR, "size mismatch %d %d %d\n", prestream_size, bitstream_size, length); return -1; } - prestream= read_huffman_tables(f, prestream, buf + length - prestream); - if (!prestream) - return -1; + prestream = read_huffman_tables(f, prestream, prestream_size); + if (!prestream) { + av_log(f->avctx, AV_LOG_ERROR, "Error reading Huffman tables.\n"); + return AVERROR_INVALIDDATA; + } + + av_assert0(prestream <= buf + length); init_get_bits(&f->gb, buf + 4, 8*bitstream_size); @@ -751,25 +775,35 @@ static int decode_frame(AVCodecContext *avctx, AVFrame *p, temp; int i, frame_4cc, frame_size; - if (buf_size < 12) + if (buf_size < 20) + return AVERROR_INVALIDDATA; + + if (avctx->width % 16 || avctx->height % 16) { + av_log(avctx, AV_LOG_ERROR, + "Dimensions non-multiple of 16 are invalid.\n"); return AVERROR_INVALIDDATA; - frame_4cc= AV_RL32(buf); - if(buf_size != AV_RL32(buf+4)+8 || buf_size < 20){ - av_log(f->avctx, AV_LOG_ERROR, "size mismatch %d %d\n", buf_size, AV_RL32(buf+4)); } + if (buf_size < AV_RL32(buf + 4) + 8) { + av_log(f->avctx, AV_LOG_ERROR, + "size mismatch %d %d\n", buf_size, AV_RL32(buf + 4)); + } + + frame_4cc = AV_RL32(buf); + if(frame_4cc == AV_RL32("cfrm")){ int free_index=-1; - const int data_size= buf_size - 20; - const int id= AV_RL32(buf+12); - const int whole_size= AV_RL32(buf+16); + int id, whole_size; + const int data_size = buf_size - 20; CFrameBuffer *cfrm; + id = AV_RL32(buf + 12); + whole_size = AV_RL32(buf + 16); + if (data_size < 0 || whole_size < 0){ av_log(f->avctx, AV_LOG_ERROR, "sizes invalid\n"); return AVERROR_INVALIDDATA; } - for(i=0; icfrm[i].id && f->cfrm[i].id < avctx->frame_number) av_log(f->avctx, AV_LOG_ERROR, "lost c frame %d\n", f->cfrm[i].id); @@ -805,6 +839,9 @@ static int decode_frame(AVCodecContext *avctx, av_log(f->avctx, AV_LOG_ERROR, "cframe id mismatch %d %d\n", id, avctx->frame_number); } + if (f->version <= 1) + return AVERROR_INVALIDDATA; + cfrm->size= cfrm->id= 0; frame_4cc= AV_RL32("pfrm"); }else @@ -848,6 +885,7 @@ static int decode_frame(AVCodecContext *avctx, av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n"); return -1; } + memset(f->last_picture.data[0], 0, avctx->height * FFABS(f->last_picture.linesize[0])); } p->pict_type= AV_PICTURE_TYPE_P; @@ -915,7 +953,7 @@ static av_cold int decode_end(AVCodecContext *avctx){ av_freep(&f->cfrm[i].data); f->cfrm[i].allocated_size= 0; } - free_vlc(&f->pre_vlc); + ff_free_vlc(&f->pre_vlc); if(f->current_picture.data[0]) avctx->release_buffer(avctx, &f->current_picture); if(f->last_picture.data[0]) diff --git a/libavcodec/8bps.c b/libavcodec/8bps.c index 9207020c9c..64cc82c1b5 100644 --- a/libavcodec/8bps.c +++ b/libavcodec/8bps.c @@ -69,7 +69,7 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *data_size, AVPac unsigned char *pixptr, *pixptr_end; unsigned int height = avctx->height; // Real image height unsigned int dlen, p, row; - const unsigned char *lp, *dp; + const unsigned char *lp, *dp, *ep; unsigned char count; unsigned int planes = c->planes; unsigned char *planemap = c->planemap; @@ -84,6 +84,8 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *data_size, AVPac return -1; } + ep = encoded + buf_size; + /* Set data pointer after line lengths */ dp = encoded + planes * (height << 1); @@ -95,16 +97,18 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *data_size, AVPac for(row = 0; row < height; row++) { pixptr = c->pic.data[0] + row * c->pic.linesize[0] + planemap[p]; pixptr_end = pixptr + c->pic.linesize[0]; + if (ep - lp < row * 2 + 2) + return AVERROR_INVALIDDATA; dlen = av_be2ne16(*(const unsigned short *)(lp+row*2)); /* Decode a row of this plane */ while(dlen > 0) { - if(dp + 1 >= buf+buf_size) return -1; + if(ep - dp <= 1) return -1; if ((count = *dp++) <= 127) { count++; dlen -= count + 1; if (pixptr + count * planes > pixptr_end) break; - if(dp + count > buf+buf_size) return -1; + if(ep - dp < count) return -1; while(count--) { *pixptr = *dp++; pixptr += planes; diff --git a/libavcodec/8svx.c b/libavcodec/8svx.c index f42a35b20b..a3ad6448d9 100644 --- a/libavcodec/8svx.c +++ b/libavcodec/8svx.c @@ -38,6 +38,7 @@ */ #include "avcodec.h" +#include "internal.h" /** decoder context */ typedef struct EightSvxContext { @@ -47,7 +48,7 @@ typedef struct EightSvxContext { /* buffer used to store the whole audio decoded/interleaved chunk, * which is sent with the first packet */ uint8_t *samples; - size_t samples_size; + int64_t samples_size; int samples_idx; } EightSvxContext; @@ -151,7 +152,7 @@ static int eightsvx_decode_frame(AVCodecContext *avctx, void *data, /* get output buffer */ esc->frame.nb_samples = (FFMIN(MAX_FRAME_SIZE, esc->samples_size - esc->samples_idx) +avctx->channels-1) / avctx->channels; - if ((ret = avctx->get_buffer(avctx, &esc->frame)) < 0) { + if ((ret = ff_get_buffer(avctx, &esc->frame)) < 0) { av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n"); return ret; } diff --git a/libavcodec/Makefile b/libavcodec/Makefile index 372b7f1bb9..565387615a 100644 --- a/libavcodec/Makefile +++ b/libavcodec/Makefile @@ -578,7 +578,8 @@ OBJS-$(CONFIG_ADPCM_YAMAHA_ENCODER) += adpcmenc.o adpcm_data.o # libavformat dependencies OBJS-$(CONFIG_ADTS_MUXER) += mpeg4audio.o OBJS-$(CONFIG_ADX_DEMUXER) += adx.o -OBJS-$(CONFIG_CAF_DEMUXER) += mpeg4audio.o mpegaudiodata.o +OBJS-$(CONFIG_CAF_DEMUXER) += mpeg4audio.o mpegaudiodata.o \ + ac3tab.o OBJS-$(CONFIG_DV_DEMUXER) += dvdata.o OBJS-$(CONFIG_DV_MUXER) += dvdata.o timecode.o OBJS-$(CONFIG_FLAC_DEMUXER) += flacdec.o flacdata.o flac.o vorbis_data.o @@ -594,7 +595,7 @@ OBJS-$(CONFIG_MATROSKA_MUXER) += xiph.o mpeg4audio.o \ flacdec.o flacdata.o flac.o \ mpegaudiodata.o vorbis_data.o OBJS-$(CONFIG_MP3_MUXER) += mpegaudiodata.o mpegaudiodecheader.o -OBJS-$(CONFIG_MOV_DEMUXER) += mpeg4audio.o mpegaudiodata.o timecode.o +OBJS-$(CONFIG_MOV_DEMUXER) += mpeg4audio.o mpegaudiodata.o ac3tab.o timecode.o OBJS-$(CONFIG_MOV_MUXER) += mpeg4audio.o mpegaudiodata.o OBJS-$(CONFIG_MPEGTS_MUXER) += mpegvideo.o mpeg4audio.o OBJS-$(CONFIG_MPEGTS_DEMUXER) += mpeg4audio.o mpegaudiodata.o diff --git a/libavcodec/a64multienc.c b/libavcodec/a64multienc.c index 5a665d0592..c029e9e6bf 100644 --- a/libavcodec/a64multienc.c +++ b/libavcodec/a64multienc.c @@ -55,9 +55,13 @@ static void to_meta_with_crop(AVCodecContext *avctx, AVFrame *p, int *dest) for (y = blocky; y < blocky + 8 && y < C64YRES; y++) { for (x = blockx; x < blockx + 8 && x < C64XRES; x += 2) { if(x < width && y < height) { - /* build average over 2 pixels */ - luma = (src[(x + 0 + y * p->linesize[0])] + - src[(x + 1 + y * p->linesize[0])]) / 2; + if (x + 1 < width) { + /* build average over 2 pixels */ + luma = (src[(x + 0 + y * p->linesize[0])] + + src[(x + 1 + y * p->linesize[0])]) / 2; + } else { + luma = src[(x + y * p->linesize[0])]; + } /* write blocks as linear data now so they are suitable for elbg */ dest[0] = luma; } diff --git a/libavcodec/aac_ac3_parser.h b/libavcodec/aac_ac3_parser.h index b1fb0cf59f..517a40246e 100644 --- a/libavcodec/aac_ac3_parser.h +++ b/libavcodec/aac_ac3_parser.h @@ -28,13 +28,13 @@ #include "parser.h" typedef enum { - AAC_AC3_PARSE_ERROR_SYNC = -1, - AAC_AC3_PARSE_ERROR_BSID = -2, - AAC_AC3_PARSE_ERROR_SAMPLE_RATE = -3, - AAC_AC3_PARSE_ERROR_FRAME_SIZE = -4, - AAC_AC3_PARSE_ERROR_FRAME_TYPE = -5, - AAC_AC3_PARSE_ERROR_CRC = -6, - AAC_AC3_PARSE_ERROR_CHANNEL_CFG = -7, + AAC_AC3_PARSE_ERROR_SYNC = -0x1030c0a, + AAC_AC3_PARSE_ERROR_BSID = -0x2030c0a, + AAC_AC3_PARSE_ERROR_SAMPLE_RATE = -0x3030c0a, + AAC_AC3_PARSE_ERROR_FRAME_SIZE = -0x4030c0a, + AAC_AC3_PARSE_ERROR_FRAME_TYPE = -0x5030c0a, + AAC_AC3_PARSE_ERROR_CRC = -0x6030c0a, + AAC_AC3_PARSE_ERROR_CHANNEL_CFG = -0x7030c0a, } AACAC3ParseError; typedef struct AACAC3ParseContext { diff --git a/libavcodec/aac_parser.c b/libavcodec/aac_parser.c index a8ef2f35dd..a6c9ad1352 100644 --- a/libavcodec/aac_parser.c +++ b/libavcodec/aac_parser.c @@ -34,7 +34,7 @@ static int aac_sync(uint64_t state, AACAC3ParseContext *hdr_info, int size; union { uint64_t u64; - uint8_t u8[8]; + uint8_t u8[8 + FF_INPUT_BUFFER_PADDING_SIZE]; } tmp; tmp.u64 = av_be2ne64(state); diff --git a/libavcodec/aaccoder.c b/libavcodec/aaccoder.c index 8738460b81..4d642aea95 100644 --- a/libavcodec/aaccoder.c +++ b/libavcodec/aaccoder.c @@ -713,7 +713,7 @@ static void search_for_quantizers_twoloop(AVCodecContext *avctx, const float lambda) { int start = 0, i, w, w2, g; - int destbits = avctx->bit_rate * 1024.0 / avctx->sample_rate / avctx->channels; + int destbits = avctx->bit_rate * 1024.0 / avctx->sample_rate / avctx->channels * (lambda / 120.f); float dists[128], uplims[128]; float maxvals[128]; int fflag, minscaler; diff --git a/libavcodec/aacdec.c b/libavcodec/aacdec.c index 77ee59f0ab..f009942377 100644 --- a/libavcodec/aacdec.c +++ b/libavcodec/aacdec.c @@ -192,6 +192,8 @@ static av_cold int che_configure(AACContext *ac, enum ChannelPosition che_pos[4][MAX_ELEM_ID], int type, int id, int *channels) { + if (*channels >= MAX_CHANNELS) + return AVERROR_INVALIDDATA; if (che_pos[type][id]) { if (!ac->che[type][id]) { if (!(ac->che[type][id] = av_mallocz(sizeof(ChannelElement)))) @@ -360,7 +362,7 @@ static int decode_pce(AVCodecContext *avctx, MPEG4AudioConfig *m4ac, comment_len = get_bits(gb, 8) * 8; if (get_bits_left(gb) < comment_len) { av_log(avctx, AV_LOG_ERROR, overread_err); - return -1; + return AVERROR_INVALIDDATA; } skip_bits_long(gb, comment_len); return 0; @@ -381,7 +383,7 @@ static av_cold int set_default_channel_config(AVCodecContext *avctx, if (channel_config < 1 || channel_config > 7) { av_log(avctx, AV_LOG_ERROR, "invalid default channel configuration (%d)\n", channel_config); - return -1; + return AVERROR_INVALIDDATA; } /* default channel configurations: @@ -499,20 +501,21 @@ static int decode_audio_specific_config(AACContext *ac, int sync_extension) { GetBitContext gb; - int i; + int i, ret; av_dlog(avctx, "extradata size %d\n", avctx->extradata_size); for (i = 0; i < avctx->extradata_size; i++) av_dlog(avctx, "%02x ", avctx->extradata[i]); av_dlog(avctx, "\n"); - init_get_bits(&gb, data, bit_size); + if ((ret = init_get_bits(&gb, data, bit_size)) < 0) + return ret; if ((i = avpriv_mpeg4audio_get_config(m4ac, data, bit_size, sync_extension)) < 0) - return -1; + return AVERROR_INVALIDDATA; if (m4ac->sampling_index > 12) { av_log(avctx, AV_LOG_ERROR, "invalid sampling rate index %d\n", m4ac->sampling_index); - return -1; + return AVERROR_INVALIDDATA; } skip_bits_long(&gb, i); @@ -521,13 +524,14 @@ static int decode_audio_specific_config(AACContext *ac, case AOT_AAC_MAIN: case AOT_AAC_LC: case AOT_AAC_LTP: - if (decode_ga_specific_config(ac, avctx, &gb, m4ac, m4ac->chan_config)) - return -1; + if ((ret = decode_ga_specific_config(ac, avctx, &gb, + m4ac, m4ac->chan_config)) < 0) + return ret; break; default: av_log(avctx, AV_LOG_ERROR, "Audio object type %s%d is not supported.\n", m4ac->sbr == 1? "SBR+" : "", m4ac->object_type); - return -1; + return AVERROR(ENOSYS); } av_dlog(avctx, "AOT %d chan config %d sampling index %d (%d) SBR %d PS %d\n", @@ -598,16 +602,17 @@ static void reset_predictor_group(PredictorState *ps, int group_num) static av_cold int aac_decode_init(AVCodecContext *avctx) { AACContext *ac = avctx->priv_data; + int ret; float output_scale_factor; ac->avctx = avctx; ac->m4ac.sample_rate = avctx->sample_rate; if (avctx->extradata_size > 0) { - if (decode_audio_specific_config(ac, ac->avctx, &ac->m4ac, + if ((ret = decode_audio_specific_config(ac, ac->avctx, &ac->m4ac, avctx->extradata, - avctx->extradata_size*8, 1) < 0) - return -1; + avctx->extradata_size*8, 1)) < 0) + return ret; } else { int sr, i; enum ChannelPosition new_che_pos[4][MAX_ELEM_ID]; @@ -700,7 +705,7 @@ static int skip_data_stream_element(AACContext *ac, GetBitContext *gb) if (get_bits_left(gb) < 8 * count) { av_log(ac->avctx, AV_LOG_ERROR, overread_err); - return -1; + return AVERROR_INVALIDDATA; } skip_bits_long(gb, 8 * count); return 0; @@ -714,7 +719,7 @@ static int decode_prediction(AACContext *ac, IndividualChannelStream *ics, ics->predictor_reset_group = get_bits(gb, 5); if (ics->predictor_reset_group == 0 || ics->predictor_reset_group > 30) { av_log(ac->avctx, AV_LOG_ERROR, "Invalid Predictor Reset Group.\n"); - return -1; + return AVERROR_INVALIDDATA; } } for (sfb = 0; sfb < FFMIN(ics->max_sfb, ff_aac_pred_sfb_max[ac->m4ac.sampling_index]); sfb++) { @@ -824,21 +829,22 @@ static int decode_band_types(AACContext *ac, enum BandType band_type[120], int sect_band_type = get_bits(gb, 4); if (sect_band_type == 12) { av_log(ac->avctx, AV_LOG_ERROR, "invalid band type\n"); - return -1; + return AVERROR_INVALIDDATA; } - while ((sect_len_incr = get_bits(gb, bits)) == (1 << bits) - 1 && get_bits_left(gb) >= bits) + do { + sect_len_incr = get_bits(gb, bits); sect_end += sect_len_incr; - sect_end += sect_len_incr; - if (get_bits_left(gb) < 0 || sect_len_incr == (1 << bits) - 1) { - av_log(ac->avctx, AV_LOG_ERROR, overread_err); - return -1; - } - if (sect_end > ics->max_sfb) { - av_log(ac->avctx, AV_LOG_ERROR, - "Number of bands (%d) exceeds limit (%d).\n", - sect_end, ics->max_sfb); - return -1; - } + if (get_bits_left(gb) < 0) { + av_log(ac->avctx, AV_LOG_ERROR, overread_err); + return AVERROR_INVALIDDATA; + } + if (sect_end > ics->max_sfb) { + av_log(ac->avctx, AV_LOG_ERROR, + "Number of bands (%d) exceeds limit (%d).\n", + sect_end, ics->max_sfb); + return AVERROR_INVALIDDATA; + } + } while (sect_len_incr == (1 << bits) - 1); for (; k < sect_end; k++) { band_type [idx] = sect_band_type; band_type_run_end[idx++] = sect_end; @@ -908,7 +914,7 @@ static int decode_scalefactors(AACContext *ac, float sf[120], GetBitContext *gb, if (offset[0] > 255U) { av_log(ac->avctx, AV_LOG_ERROR, "%s (%d) out of range.\n", sf_str[0], offset[0]); - return -1; + return AVERROR_INVALIDDATA; } sf[idx] = -ff_aac_pow2sf_tab[offset[0] - 100 + POW_SF2_ZERO]; } @@ -966,7 +972,7 @@ static int decode_tns(AACContext *ac, TemporalNoiseShaping *tns, av_log(ac->avctx, AV_LOG_ERROR, "TNS filter order %d is greater than maximum %d.\n", tns->order[w][filt], tns_max_order); tns->order[w][filt] = 0; - return -1; + return AVERROR_INVALIDDATA; } if (tns->order[w][filt]) { tns->direction[w][filt] = get_bits1(gb); @@ -1249,7 +1255,7 @@ static int decode_spectrum_and_dequant(AACContext *ac, float coef[1024], if (b > 8) { av_log(ac->avctx, AV_LOG_ERROR, "error in spectral data, ESC overflow\n"); - return -1; + return AVERROR_INVALIDDATA; } SKIP_BITS(re, gb, b + 1); @@ -1392,6 +1398,7 @@ static int decode_ics(AACContext *ac, SingleChannelElement *sce, IndividualChannelStream *ics = &sce->ics; float *out = sce->coeffs; int global_gain, pulse_present = 0; + int ret; /* This assignment is to silence a GCC warning about the variable being used * uninitialized when in fact it always is. @@ -1405,25 +1412,27 @@ static int decode_ics(AACContext *ac, SingleChannelElement *sce, return AVERROR_INVALIDDATA; } - if (decode_band_types(ac, sce->band_type, sce->band_type_run_end, gb, ics) < 0) - return -1; - if (decode_scalefactors(ac, sce->sf, gb, global_gain, ics, sce->band_type, sce->band_type_run_end) < 0) - return -1; + if ((ret = decode_band_types(ac, sce->band_type, + sce->band_type_run_end, gb, ics)) < 0) + return ret; + if ((ret = decode_scalefactors(ac, sce->sf, gb, global_gain, ics, + sce->band_type, sce->band_type_run_end)) < 0) + return ret; pulse_present = 0; if (!scale_flag) { if ((pulse_present = get_bits1(gb))) { if (ics->window_sequence[0] == EIGHT_SHORT_SEQUENCE) { av_log(ac->avctx, AV_LOG_ERROR, "Pulse tool not allowed in eight short sequence.\n"); - return -1; + return AVERROR_INVALIDDATA; } if (decode_pulses(&pulse, gb, ics->swb_offset, ics->num_swb)) { av_log(ac->avctx, AV_LOG_ERROR, "Pulse data corrupt or invalid.\n"); - return -1; + return AVERROR_INVALIDDATA; } } if ((tns->present = get_bits1(gb)) && decode_tns(ac, tns, gb, ics)) - return -1; + return AVERROR_INVALIDDATA; if (get_bits1(gb)) { av_log_missing_feature(ac->avctx, "SSR", 1); return -1; @@ -1431,7 +1440,7 @@ static int decode_ics(AACContext *ac, SingleChannelElement *sce, } if (decode_spectrum_and_dequant(ac, out, gb, sce->sf, pulse_present, &pulse, ics, sce->band_type) < 0) - return -1; + return AVERROR_INVALIDDATA; if (ac->m4ac.object_type == AOT_AAC_MAIN && !common_window) apply_prediction(ac, sce); @@ -1529,7 +1538,7 @@ static int decode_cpe(AACContext *ac, GetBitContext *gb, ChannelElement *cpe) ms_present = get_bits(gb, 2); if (ms_present == 3) { av_log(ac->avctx, AV_LOG_ERROR, "ms_present = 3 is reserved.\n"); - return -1; + return AVERROR_INVALIDDATA; } else if (ms_present) decode_mid_side_stereo(cpe, gb, ms_present); } @@ -1765,7 +1774,7 @@ static void apply_tns(float coef[1024], TemporalNoiseShaping *tns, int w, filt, m, i; int bottom, top, order, start, end, size, inc; float lpc[TNS_MAX_ORDER]; - float tmp[TNS_MAX_ORDER]; + float tmp[TNS_MAX_ORDER + 1]; for (w = 0; w < ics->num_windows; w++) { bottom = ics->num_swb; @@ -2267,7 +2276,7 @@ static int aac_decode_frame_int(AVCodecContext *avctx, void *data, if (samples) { /* get output buffer */ ac->frame.nb_samples = samples; - if ((err = avctx->get_buffer(avctx, &ac->frame)) < 0) { + if ((err = ff_get_buffer(avctx, &ac->frame)) < 0) { av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n"); return err; } @@ -2320,7 +2329,8 @@ static int aac_decode_frame(AVCodecContext *avctx, void *data, return AVERROR_INVALIDDATA; } - init_get_bits(&gb, buf, buf_size * 8); + if ((err = init_get_bits(&gb, buf, buf_size * 8)) < 0) + return err; if ((err = aac_decode_frame_int(avctx, data, got_frame_ptr, &gb)) < 0) return err; @@ -2565,7 +2575,8 @@ static int latm_decode_frame(AVCodecContext *avctx, void *out, int muxlength, err; GetBitContext gb; - init_get_bits(&gb, avpkt->data, avpkt->size * 8); + if ((err = init_get_bits(&gb, avpkt->data, avpkt->size * 8)) < 0) + return err; // check for LOAS sync word if (get_bits(&gb, 11) != LOAS_SYNC_WORD) diff --git a/libavcodec/aacenc.c b/libavcodec/aacenc.c index 55f028687c..d66dcfd150 100644 --- a/libavcodec/aacenc.c +++ b/libavcodec/aacenc.c @@ -164,7 +164,7 @@ static void put_audio_specific_config(AVCodecContext *avctx) PutBitContext pb; AACEncContext *s = avctx->priv_data; - init_put_bits(&pb, avctx->extradata, avctx->extradata_size*8); + init_put_bits(&pb, avctx->extradata, avctx->extradata_size); put_bits(&pb, 5, 2); //object type - AAC-LC put_bits(&pb, 4, s->samplerate_index); //sample rate index put_bits(&pb, 4, s->channels); @@ -200,8 +200,8 @@ WINDOW_FUNC(long_start) float *out = sce->ret; dsp->vector_fmul(out, audio, lwindow, 1024); - memcpy(out + 1024, audio, sizeof(out[0]) * 448); - dsp->vector_fmul_reverse(out + 1024 + 448, audio, swindow, 128); + memcpy(out + 1024, audio + 1024, sizeof(out[0]) * 448); + dsp->vector_fmul_reverse(out + 1024 + 448, audio + 1024 + 448, swindow, 128); memset(out + 1024 + 576, 0, sizeof(out[0]) * 448); } @@ -487,10 +487,10 @@ static void deinterleave_input_samples(AACEncContext *s, const float *sptr = samples + channel_map[ch]; /* copy last 1024 samples of previous frame to the start of the current frame */ - memcpy(&s->planar_samples[ch][0], &s->planar_samples[ch][1024], 1024 * sizeof(s->planar_samples[0][0])); + memcpy(&s->planar_samples[ch][1024], &s->planar_samples[ch][2048], 1024 * sizeof(s->planar_samples[0][0])); /* deinterleave */ - for (i = 1024; i < 1024 * 2; i++) { + for (i = 2048; i < 3072; i++) { s->planar_samples[ch][i] = *sptr; sptr += sinc; } diff --git a/libavcodec/aacps.c b/libavcodec/aacps.c index 3b5aa58109..c2afec0af5 100644 --- a/libavcodec/aacps.c +++ b/libavcodec/aacps.c @@ -275,6 +275,10 @@ int ff_ps_read_data(AVCodecContext *avctx, GetBitContext *gb_host, PSContext *ps err: ps->start = 0; skip_bits_long(gb_host, bits_left); + memset(ps->iid_par, 0, sizeof(ps->iid_par)); + memset(ps->icc_par, 0, sizeof(ps->icc_par)); + memset(ps->ipd_par, 0, sizeof(ps->ipd_par)); + memset(ps->opd_par, 0, sizeof(ps->opd_par)); return bits_left; } diff --git a/libavcodec/aacsbr.c b/libavcodec/aacsbr.c index 2f457b61cc..1110bb4a2e 100644 --- a/libavcodec/aacsbr.c +++ b/libavcodec/aacsbr.c @@ -542,7 +542,7 @@ static int sbr_hf_calc_npatches(AACContext *ac, SpectralBandReplication *sbr) k = sbr->n_master; } while (sb != sbr->kx[1] + sbr->m[1]); - if (sbr->patch_num_subbands[sbr->num_patches-1] < 3 && sbr->num_patches > 1) + if (sbr->num_patches > 1 && sbr->patch_num_subbands[sbr->num_patches-1] < 3) sbr->num_patches--; return 0; diff --git a/libavcodec/aasc.c b/libavcodec/aasc.c index 197bfe5f05..5bdfeb8aa9 100644 --- a/libavcodec/aasc.c +++ b/libavcodec/aasc.c @@ -34,17 +34,10 @@ typedef struct AascContext { AVCodecContext *avctx; + GetByteContext gb; AVFrame frame; } AascContext; -#define FETCH_NEXT_STREAM_BYTE() \ - if (stream_ptr >= buf_size) \ - { \ - av_log(s->avctx, AV_LOG_ERROR, " AASC: stream ptr just went out of bounds (fetch)\n"); \ - break; \ - } \ - stream_byte = buf[stream_ptr++]; - static av_cold int aasc_decode_init(AVCodecContext *avctx) { AascContext *s = avctx->priv_data; @@ -89,7 +82,8 @@ static int aasc_decode_frame(AVCodecContext *avctx, } break; case 1: - ff_msrle_decode(avctx, (AVPicture*)&s->frame, 8, buf - 4, buf_size + 4); + bytestream2_init(&s->gb, buf - 4, buf_size + 4); + ff_msrle_decode(avctx, (AVPicture*)&s->frame, 8, &s->gb); break; default: av_log(avctx, AV_LOG_ERROR, "Unknown compression type %d\n", compr); diff --git a/libavcodec/ac3_parser.c b/libavcodec/ac3_parser.c index 14ca196aaf..773f4c289f 100644 --- a/libavcodec/ac3_parser.c +++ b/libavcodec/ac3_parser.c @@ -134,7 +134,7 @@ int avpriv_ac3_parse_header(GetBitContext *gbc, AC3HeaderInfo *hdr) (hdr->num_blocks * 256.0)); hdr->channels = ff_ac3_channels_tab[hdr->channel_mode] + hdr->lfe_on; } - hdr->channel_layout = ff_ac3_channel_layout_tab[hdr->channel_mode]; + hdr->channel_layout = avpriv_ac3_channel_layout_tab[hdr->channel_mode]; if (hdr->lfe_on) hdr->channel_layout |= AV_CH_LOW_FREQUENCY; @@ -147,7 +147,7 @@ static int ac3_sync(uint64_t state, AACAC3ParseContext *hdr_info, int err; union { uint64_t u64; - uint8_t u8[8]; + uint8_t u8[8 + FF_INPUT_BUFFER_PADDING_SIZE]; } tmp = { av_be2ne64(state) }; AC3HeaderInfo hdr; GetBitContext gbc; diff --git a/libavcodec/ac3dec.c b/libavcodec/ac3dec.c index 598255830b..386dc9302a 100644 --- a/libavcodec/ac3dec.c +++ b/libavcodec/ac3dec.c @@ -297,7 +297,7 @@ static int parse_frame_header(AC3DecodeContext *s) return ff_eac3_parse_header(s); } else { av_log(s->avctx, AV_LOG_ERROR, "E-AC-3 support not compiled in\n"); - return -1; + return AVERROR(ENOSYS); } } @@ -822,12 +822,12 @@ static int decode_audio_block(AC3DecodeContext *s, int blk) if (start_subband >= end_subband) { av_log(s->avctx, AV_LOG_ERROR, "invalid spectral extension " "range (%d >= %d)\n", start_subband, end_subband); - return -1; + return AVERROR_INVALIDDATA; } if (dst_start_freq >= src_start_freq) { av_log(s->avctx, AV_LOG_ERROR, "invalid spectral extension " "copy start bin (%d >= %d)\n", dst_start_freq, src_start_freq); - return -1; + return AVERROR_INVALIDDATA; } s->spx_dst_start_freq = dst_start_freq; @@ -904,7 +904,7 @@ static int decode_audio_block(AC3DecodeContext *s, int blk) if (channel_mode < AC3_CHMODE_STEREO) { av_log(s->avctx, AV_LOG_ERROR, "coupling not allowed in mono or dual-mono\n"); - return -1; + return AVERROR_INVALIDDATA; } /* check for enhanced coupling */ @@ -934,7 +934,7 @@ static int decode_audio_block(AC3DecodeContext *s, int blk) if (cpl_start_subband >= cpl_end_subband) { av_log(s->avctx, AV_LOG_ERROR, "invalid coupling range (%d >= %d)\n", cpl_start_subband, cpl_end_subband); - return -1; + return AVERROR_INVALIDDATA; } s->start_freq[CPL_CH] = cpl_start_subband * 12 + 37; s->end_freq[CPL_CH] = cpl_end_subband * 12 + 37; @@ -956,7 +956,7 @@ static int decode_audio_block(AC3DecodeContext *s, int blk) if (!blk) { av_log(s->avctx, AV_LOG_ERROR, "new coupling strategy must " "be present in block 0\n"); - return -1; + return AVERROR_INVALIDDATA; } else { s->cpl_in_use[blk] = s->cpl_in_use[blk-1]; } @@ -986,7 +986,7 @@ static int decode_audio_block(AC3DecodeContext *s, int blk) } else if (!blk) { av_log(s->avctx, AV_LOG_ERROR, "new coupling coordinates must " "be present in block 0\n"); - return -1; + return AVERROR_INVALIDDATA; } } else { /* channel not in coupling */ @@ -1041,7 +1041,7 @@ static int decode_audio_block(AC3DecodeContext *s, int blk) int bandwidth_code = get_bits(gbc, 6); if (bandwidth_code > 60) { av_log(s->avctx, AV_LOG_ERROR, "bandwidth code = %d > 60\n", bandwidth_code); - return -1; + return AVERROR_INVALIDDATA; } s->end_freq[ch] = bandwidth_code * 3 + 73; } @@ -1064,7 +1064,7 @@ static int decode_audio_block(AC3DecodeContext *s, int blk) s->num_exp_groups[ch], s->dexps[ch][0], &s->dexps[ch][s->start_freq[ch]+!!ch])) { av_log(s->avctx, AV_LOG_ERROR, "exponent out-of-range\n"); - return -1; + return AVERROR_INVALIDDATA; } if (ch != CPL_CH && ch != s->lfe_ch) skip_bits(gbc, 2); /* skip gainrng */ @@ -1084,7 +1084,7 @@ static int decode_audio_block(AC3DecodeContext *s, int blk) } else if (!blk) { av_log(s->avctx, AV_LOG_ERROR, "new bit allocation info must " "be present in block 0\n"); - return -1; + return AVERROR_INVALIDDATA; } } @@ -1115,7 +1115,7 @@ static int decode_audio_block(AC3DecodeContext *s, int blk) } } else if (!s->eac3 && !blk) { av_log(s->avctx, AV_LOG_ERROR, "new snr offsets must be present in block 0\n"); - return -1; + return AVERROR_INVALIDDATA; } } @@ -1154,7 +1154,7 @@ static int decode_audio_block(AC3DecodeContext *s, int blk) } else if (!s->eac3 && !blk) { av_log(s->avctx, AV_LOG_ERROR, "new coupling leak info must " "be present in block 0\n"); - return -1; + return AVERROR_INVALIDDATA; } s->first_cpl_leak = 0; } @@ -1166,7 +1166,7 @@ static int decode_audio_block(AC3DecodeContext *s, int blk) s->dba_mode[ch] = get_bits(gbc, 2); if (s->dba_mode[ch] == DBA_RESERVED) { av_log(s->avctx, AV_LOG_ERROR, "delta bit allocation strategy reserved\n"); - return -1; + return AVERROR_INVALIDDATA; } bit_alloc_stages[ch] = FFMAX(bit_alloc_stages[ch], 2); } @@ -1207,7 +1207,7 @@ static int decode_audio_block(AC3DecodeContext *s, int blk) s->dba_offsets[ch], s->dba_lengths[ch], s->dba_values[ch], s->mask[ch])) { av_log(s->avctx, AV_LOG_ERROR, "error in bit allocation\n"); - return -1; + return AVERROR_INVALIDDATA; } } if (bit_alloc_stages[ch] > 0) { @@ -1328,7 +1328,7 @@ static int ac3_decode_frame(AVCodecContext * avctx, void *data, switch (err) { case AAC_AC3_PARSE_ERROR_SYNC: av_log(avctx, AV_LOG_ERROR, "frame sync error\n"); - return -1; + return AVERROR_INVALIDDATA; case AAC_AC3_PARSE_ERROR_BSID: av_log(avctx, AV_LOG_ERROR, "invalid bitstream id\n"); break; @@ -1342,17 +1342,20 @@ static int ac3_decode_frame(AVCodecContext * avctx, void *data, /* skip frame if CRC is ok. otherwise use error concealment. */ /* TODO: add support for substreams and dependent frames */ if (s->frame_type == EAC3_FRAME_TYPE_DEPENDENT || s->substreamid) { - av_log(avctx, AV_LOG_ERROR, "unsupported frame type : " + av_log(avctx, AV_LOG_WARNING, "unsupported frame type : " "skipping frame\n"); *got_frame_ptr = 0; - return s->frame_size; + return buf_size; } else { av_log(avctx, AV_LOG_ERROR, "invalid frame type\n"); } break; - default: - av_log(avctx, AV_LOG_ERROR, "invalid header\n"); + case AAC_AC3_PARSE_ERROR_CRC: + case AAC_AC3_PARSE_ERROR_CHANNEL_CFG: break; + default: // Normal AVERROR do not try to recover. + *got_frame_ptr = 0; + return err; } } else { /* check that reported frame size fits in input buffer */ @@ -1373,8 +1376,10 @@ static int ac3_decode_frame(AVCodecContext * avctx, void *data, if (!err) { avctx->sample_rate = s->sample_rate; avctx->bit_rate = s->bit_rate; + } - /* channel config */ + /* channel config */ + if (!err || (s->channels && s->out_channels != s->channels)) { s->out_channels = s->channels; s->output_mode = s->channel_mode; if (s->lfe_on) @@ -1383,7 +1388,7 @@ static int ac3_decode_frame(AVCodecContext * avctx, void *data, avctx->request_channels < s->channels) { s->out_channels = avctx->request_channels; s->output_mode = avctx->request_channels == 1 ? AC3_CHMODE_MONO : AC3_CHMODE_STEREO; - s->channel_layout = ff_ac3_channel_layout_tab[s->output_mode]; + s->channel_layout = avpriv_ac3_channel_layout_tab[s->output_mode]; } avctx->channels = s->out_channels; avctx->channel_layout = s->channel_layout; @@ -1397,11 +1402,12 @@ static int ac3_decode_frame(AVCodecContext * avctx, void *data, s->fbw_channels == s->out_channels)) { set_downmix_coeffs(s); } - } else if (!s->out_channels) { - s->out_channels = avctx->channels; - if (s->out_channels < s->channels) - s->output_mode = s->out_channels == 1 ? AC3_CHMODE_MONO : AC3_CHMODE_STEREO; + } else if (!s->channels) { + av_log(avctx, AV_LOG_ERROR, "unable to determine channel mode\n"); + return AVERROR_INVALIDDATA; } + avctx->channels = s->out_channels; + /* set audio service type based on bitstream mode for AC-3 */ avctx->audio_service_type = s->bitstream_mode; if (s->bitstream_mode == 0x7 && s->channels > 1) @@ -1409,7 +1415,7 @@ static int ac3_decode_frame(AVCodecContext * avctx, void *data, /* get output buffer */ s->frame.nb_samples = s->num_blocks * 256; - if ((ret = avctx->get_buffer(avctx, &s->frame)) < 0) { + if ((ret = ff_get_buffer(avctx, &s->frame)) < 0) { av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n"); return ret; } diff --git a/libavcodec/ac3dsp.c b/libavcodec/ac3dsp.c index a414db4107..581e5f5071 100644 --- a/libavcodec/ac3dsp.c +++ b/libavcodec/ac3dsp.c @@ -109,7 +109,7 @@ static void ac3_bit_alloc_calc_bap_c(int16_t *mask, int16_t *psd, int snr_offset, int floor, const uint8_t *bap_tab, uint8_t *bap) { - int bin, band; + int bin, band, band_end; /* special case, if snr offset is -960, set all bap's to zero */ if (snr_offset == -960) { @@ -121,12 +121,14 @@ static void ac3_bit_alloc_calc_bap_c(int16_t *mask, int16_t *psd, band = ff_ac3_bin_to_band_tab[start]; do { int m = (FFMAX(mask[band] - snr_offset - floor, 0) & 0x1FE0) + floor; - int band_end = FFMIN(ff_ac3_band_start_tab[band+1], end); + band_end = ff_ac3_band_start_tab[++band]; + band_end = FFMIN(band_end, end); + for (; bin < band_end; bin++) { int address = av_clip((psd[bin] - m) >> 5, 0, 63); bap[bin] = bap_tab[address]; } - } while (end > ff_ac3_band_start_tab[band++]); + } while (end > band_end); } static void ac3_update_bap_counts_c(uint16_t mant_cnt[16], uint8_t *bap, diff --git a/libavcodec/ac3enc_template.c b/libavcodec/ac3enc_template.c index 60472550d1..b6b9e4011d 100644 --- a/libavcodec/ac3enc_template.c +++ b/libavcodec/ac3enc_template.c @@ -261,7 +261,7 @@ static void apply_channel_coupling(AC3EncodeContext *s) energy_cpl = energy[blk][CPL_CH][bnd]; energy_ch = energy[blk][ch][bnd]; blk1 = blk+1; - while (!s->blocks[blk1].new_cpl_coords[ch] && blk1 < s->num_blocks) { + while (blk1 < s->num_blocks && !s->blocks[blk1].new_cpl_coords[ch]) { if (s->blocks[blk1].cpl_in_use) { energy_cpl += energy[blk1][CPL_CH][bnd]; energy_ch += energy[blk1][ch][bnd]; diff --git a/libavcodec/ac3tab.c b/libavcodec/ac3tab.c index 3b3e715655..ccf04ec016 100644 --- a/libavcodec/ac3tab.c +++ b/libavcodec/ac3tab.c @@ -84,7 +84,7 @@ const uint8_t ff_ac3_channels_tab[8] = { /** * Map audio coding mode (acmod) to channel layout mask. */ -const uint16_t ff_ac3_channel_layout_tab[8] = { +const uint16_t avpriv_ac3_channel_layout_tab[8] = { AV_CH_LAYOUT_STEREO, AV_CH_LAYOUT_MONO, AV_CH_LAYOUT_STEREO, diff --git a/libavcodec/ac3tab.h b/libavcodec/ac3tab.h index aa13c8f6e5..d6e0eed86a 100644 --- a/libavcodec/ac3tab.h +++ b/libavcodec/ac3tab.h @@ -33,7 +33,7 @@ extern const uint16_t ff_ac3_frame_size_tab[38][3]; extern const uint8_t ff_ac3_channels_tab[8]; -extern const uint16_t ff_ac3_channel_layout_tab[8]; +extern const uint16_t avpriv_ac3_channel_layout_tab[8]; extern const uint8_t ff_ac3_enc_channel_map[8][2][6]; extern const uint8_t ff_ac3_dec_channel_map[8][2][6]; extern const uint16_t ff_ac3_sample_rate_tab[3]; diff --git a/libavcodec/adpcm.c b/libavcodec/adpcm.c index c21753af48..b90ad917a9 100644 --- a/libavcodec/adpcm.c +++ b/libavcodec/adpcm.c @@ -18,6 +18,7 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include "avcodec.h" +#include "internal.h" #include "get_bits.h" #include "put_bits.h" #include "bytestream.h" @@ -265,8 +266,9 @@ static inline short adpcm_yamaha_expand_nibble(ADPCMChannelStatus *c, unsigned c return c->predictor; } -static void xa_decode(short *out, const unsigned char *in, - ADPCMChannelStatus *left, ADPCMChannelStatus *right, int inc) +static int xa_decode(AVCodecContext *avctx, + short *out, const unsigned char *in, + ADPCMChannelStatus *left, ADPCMChannelStatus *right, int inc) { int i, j; int shift,filter,f0,f1; @@ -277,6 +279,12 @@ static void xa_decode(short *out, const unsigned char *in, shift = 12 - (in[4+i*2] & 15); filter = in[4+i*2] >> 4; + if (filter > 4) { + av_log(avctx, AV_LOG_ERROR, + "Invalid XA-ADPCM filter %d (max. allowed is 4)\n", + filter); + return AVERROR_INVALIDDATA; + } f0 = xa_adpcm_table[filter][0]; f1 = xa_adpcm_table[filter][1]; @@ -304,7 +312,12 @@ static void xa_decode(short *out, const unsigned char *in, shift = 12 - (in[5+i*2] & 15); filter = in[5+i*2] >> 4; - + if (filter > 4) { + av_log(avctx, AV_LOG_ERROR, + "Invalid XA-ADPCM filter %d (max. allowed is 4)\n", + filter); + return AVERROR_INVALIDDATA; + } f0 = xa_adpcm_table[filter][0]; f1 = xa_adpcm_table[filter][1]; @@ -328,6 +341,8 @@ static void xa_decode(short *out, const unsigned char *in, left->sample2 = s_2; } } + + return 0; } /** @@ -542,7 +557,7 @@ static int adpcm_decode_frame(AVCodecContext *avctx, void *data, /* get output buffer */ c->frame.nb_samples = nb_samples; - if ((ret = avctx->get_buffer(avctx, &c->frame)) < 0) { + if ((ret = ff_get_buffer(avctx, &c->frame)) < 0) { av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n"); return ret; } @@ -699,11 +714,11 @@ static int adpcm_decode_frame(AVCodecContext *avctx, void *data, for (channel = 0; channel < avctx->channels; channel++) { cs = &c->status[channel]; cs->predictor = (int16_t)bytestream_get_le16(&src); - cs->step_index = *src++; + cs->step_index = av_clip(*src++, 0, 88); src++; *samples++ = cs->predictor; } - for (n = nb_samples >> (1 - st); n > 0; n--, src++) { + for (n = (nb_samples >> (1 - st)) - 1; n > 0; n--, src++) { uint8_t v = *src; *samples++ = adpcm_ima_expand_nibble(&c->status[0 ], v >> 4 , 3); *samples++ = adpcm_ima_expand_nibble(&c->status[st], v & 0x0F, 3); @@ -722,8 +737,8 @@ static int adpcm_decode_frame(AVCodecContext *avctx, void *data, c->status[0].predictor = (int16_t)AV_RL16(src + 10); c->status[1].predictor = (int16_t)AV_RL16(src + 12); - c->status[0].step_index = src[14]; - c->status[1].step_index = src[15]; + c->status[0].step_index = av_clip(src[14], 0, 88); + c->status[1].step_index = av_clip(src[15], 0, 88); /* sign extend the predictors */ src += 16; diff_channel = c->status[1].predictor; @@ -763,7 +778,7 @@ static int adpcm_decode_frame(AVCodecContext *avctx, void *data, for (channel = 0; channel < avctx->channels; channel++) { cs = &c->status[channel]; cs->predictor = (int16_t)bytestream_get_le16(&src); - cs->step_index = *src++; + cs->step_index = av_clip(*src++, 0, 88); src++; } @@ -815,8 +830,9 @@ static int adpcm_decode_frame(AVCodecContext *avctx, void *data, break; case CODEC_ID_ADPCM_XA: while (buf_size >= 128) { - xa_decode(samples, src, &c->status[0], &c->status[1], - avctx->channels); + if ((ret = xa_decode(avctx, samples, src, &c->status[0], + &c->status[1], avctx->channels)) < 0) + return ret; src += 128; samples += 28 * 8; buf_size -= 128; @@ -826,7 +842,7 @@ static int adpcm_decode_frame(AVCodecContext *avctx, void *data, src += 4; // skip sample count (already read) for (i=0; i<=st; i++) - c->status[i].step_index = bytestream_get_le32(&src); + c->status[i].step_index = av_clip(bytestream_get_le32(&src), 0, 88); for (i=0; i<=st; i++) c->status[i].predictor = bytestream_get_le32(&src); @@ -1043,11 +1059,11 @@ static int adpcm_decode_frame(AVCodecContext *avctx, void *data, case CODEC_ID_ADPCM_IMA_SMJPEG: if (avctx->codec->id == CODEC_ID_ADPCM_IMA_AMV) { c->status[0].predictor = sign_extend(bytestream_get_le16(&src), 16); - c->status[0].step_index = bytestream_get_le16(&src); + c->status[0].step_index = av_clip(bytestream_get_le16(&src), 0, 88); src += 4; } else { c->status[0].predictor = sign_extend(bytestream_get_be16(&src), 16); - c->status[0].step_index = bytestream_get_byte(&src); + c->status[0].step_index = av_clip(bytestream_get_byte(&src), 0, 88); src += 1; } diff --git a/libavcodec/adpcmenc.c b/libavcodec/adpcmenc.c index e500a1cdbf..73da9272ec 100644 --- a/libavcodec/adpcmenc.c +++ b/libavcodec/adpcmenc.c @@ -551,10 +551,10 @@ static int adpcm_encode_frame(AVCodecContext *avctx, { int ch, i; PutBitContext pb; - init_put_bits(&pb, dst, buf_size * 8); + init_put_bits(&pb, dst, buf_size); for (ch = 0; ch < avctx->channels; ch++) { - put_bits(&pb, 9, (c->status[ch].prev_sample + 0x10000) >> 7); + put_bits(&pb, 9, (c->status[ch].prev_sample & 0xFFFF) >> 7); put_bits(&pb, 7, c->status[ch].step_index); if (avctx->trellis > 0) { uint8_t buf[64]; @@ -582,7 +582,7 @@ static int adpcm_encode_frame(AVCodecContext *avctx, { int i; PutBitContext pb; - init_put_bits(&pb, dst, buf_size * 8); + init_put_bits(&pb, dst, buf_size); n = avctx->frame_size - 1; diff --git a/libavcodec/adx.c b/libavcodec/adx.c index 1e5d89c991..41e8e1c8c1 100644 --- a/libavcodec/adx.c +++ b/libavcodec/adx.c @@ -47,7 +47,7 @@ int avpriv_adx_decode_header(AVCodecContext *avctx, const uint8_t *buf, offset = AV_RB16(buf + 2) + 4; /* if copyright string is within the provided data, validate it */ - if (bufsize >= offset && memcmp(buf + offset - 6, "(c)CRI", 6)) + if (bufsize >= offset && offset >= 6 && memcmp(buf + offset - 6, "(c)CRI", 6)) return AVERROR_INVALIDDATA; /* check for encoding=3 block_size=18, sample_size=4 */ diff --git a/libavcodec/adxdec.c b/libavcodec/adxdec.c index ec4b1041af..e5e4f13e5c 100644 --- a/libavcodec/adxdec.c +++ b/libavcodec/adxdec.c @@ -21,6 +21,7 @@ #include "libavutil/intreadwrite.h" #include "avcodec.h" +#include "internal.h" #include "adx.h" #include "get_bits.h" @@ -140,7 +141,7 @@ static int adx_decode_frame(AVCodecContext *avctx, void *data, /* get output buffer */ c->frame.nb_samples = num_blocks * BLOCK_SAMPLES; - if ((ret = avctx->get_buffer(avctx, &c->frame)) < 0) { + if ((ret = ff_get_buffer(avctx, &c->frame)) < 0) { av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n"); return ret; } diff --git a/libavcodec/alac.c b/libavcodec/alac.c index 83e0d810e6..3bfe2c0a91 100644 --- a/libavcodec/alac.c +++ b/libavcodec/alac.c @@ -47,6 +47,7 @@ #include "avcodec.h" +#include "internal.h" #include "get_bits.h" #include "bytestream.h" #include "unary.h" @@ -417,7 +418,7 @@ static int alac_decode_frame(AVCodecContext *avctx, void *data, return AVERROR_INVALIDDATA; } alac->frame.nb_samples = outputsamples; - if ((ret = avctx->get_buffer(avctx, &alac->frame)) < 0) { + if ((ret = ff_get_buffer(avctx, &alac->frame)) < 0) { av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n"); return ret; } @@ -615,6 +616,12 @@ static int alac_set_info(ALACContext *alac) /* buffer size / 2 ? */ alac->setinfo_max_samples_per_frame = bytestream_get_be32(&ptr); + if (!alac->setinfo_max_samples_per_frame || + alac->setinfo_max_samples_per_frame > INT_MAX / sizeof(int32_t)) { + av_log(alac->avctx, AV_LOG_ERROR, "max samples per frame invalid: %u\n", + alac->setinfo_max_samples_per_frame); + return AVERROR_INVALIDDATA; + } ptr++; /* compatible version */ alac->setinfo_sample_size = *ptr++; alac->setinfo_rice_historymult = *ptr++; @@ -636,10 +643,9 @@ static av_cold int alac_decode_init(AVCodecContext * avctx) alac->avctx = avctx; /* initialize from the extradata */ - if (alac->avctx->extradata_size != ALAC_EXTRADATA_SIZE) { - av_log(avctx, AV_LOG_ERROR, "alac: expected %d extradata bytes\n", - ALAC_EXTRADATA_SIZE); - return -1; + if (alac->avctx->extradata_size < ALAC_EXTRADATA_SIZE) { + av_log(avctx, AV_LOG_ERROR, "alac: extradata is too small\n"); + return AVERROR_INVALIDDATA; } if (alac_set_info(alac)) { av_log(avctx, AV_LOG_ERROR, "alac: set_info failed\n"); diff --git a/libavcodec/alacenc.c b/libavcodec/alacenc.c index e8d1bc03f2..5b57837b7e 100644 --- a/libavcodec/alacenc.c +++ b/libavcodec/alacenc.c @@ -259,7 +259,7 @@ static void alac_linear_predictor(AlacEncodeContext *s, int ch) // generate warm-up samples residual[0] = samples[0]; for (i = 1; i <= lpc.lpc_order; i++) - residual[i] = samples[i] - samples[i-1]; + residual[i] = sign_extend(samples[i] - samples[i-1], s->write_sample_size); // perform lpc on remaining samples for (i = lpc.lpc_order + 1; i < s->avctx->frame_size; i++) { diff --git a/libavcodec/alsdec.c b/libavcodec/alsdec.c index 9d371de0c8..2c674502c3 100644 --- a/libavcodec/alsdec.c +++ b/libavcodec/alsdec.c @@ -30,6 +30,7 @@ #include "avcodec.h" +#include "internal.h" #include "get_bits.h" #include "unary.h" #include "mpeg4audio.h" @@ -283,7 +284,7 @@ static av_cold int read_specific_config(ALSDecContext *ctx) GetBitContext gb; uint64_t ht_size; int i, config_offset; - MPEG4AudioConfig m4ac; + MPEG4AudioConfig m4ac = {0}; ALSSpecificConfig *sconf = &ctx->sconf; AVCodecContext *avctx = ctx->avctx; uint32_t als_id, header_size, trailer_size; @@ -294,12 +295,12 @@ static av_cold int read_specific_config(ALSDecContext *ctx) avctx->extradata_size * 8, 1); if (config_offset < 0) - return -1; + return AVERROR_INVALIDDATA; skip_bits_long(&gb, config_offset); if (get_bits_left(&gb) < (30 << 3)) - return -1; + return AVERROR_INVALIDDATA; // read the fixed items als_id = get_bits_long(&gb, 32); @@ -334,7 +335,7 @@ static av_cold int read_specific_config(ALSDecContext *ctx) // check for ALSSpecificConfig struct if (als_id != MKBETAG('A','L','S','\0')) - return -1; + return AVERROR_INVALIDDATA; ctx->cur_frame_length = sconf->frame_length; @@ -349,7 +350,7 @@ static av_cold int read_specific_config(ALSDecContext *ctx) int chan_pos_bits = av_ceil_log2(avctx->channels); int bits_needed = avctx->channels * chan_pos_bits + 7; if (get_bits_left(&gb) < bits_needed) - return -1; + return AVERROR_INVALIDDATA; if (!(sconf->chan_pos = av_malloc(avctx->channels * sizeof(*sconf->chan_pos)))) return AVERROR(ENOMEM); @@ -367,7 +368,7 @@ static av_cold int read_specific_config(ALSDecContext *ctx) // read fixed header and trailer sizes, // if size = 0xFFFFFFFF then there is no data field! if (get_bits_left(&gb) < 64) - return -1; + return AVERROR_INVALIDDATA; header_size = get_bits_long(&gb, 32); trailer_size = get_bits_long(&gb, 32); @@ -381,10 +382,10 @@ static av_cold int read_specific_config(ALSDecContext *ctx) // skip the header and trailer data if (get_bits_left(&gb) < ht_size) - return -1; + return AVERROR_INVALIDDATA; if (ht_size > INT32_MAX) - return -1; + return AVERROR_PATCHWELCOME; skip_bits_long(&gb, ht_size); @@ -392,7 +393,7 @@ static av_cold int read_specific_config(ALSDecContext *ctx) // initialize CRC calculation if (sconf->crc_enabled) { if (get_bits_left(&gb) < 32) - return -1; + return AVERROR_INVALIDDATA; if (avctx->err_recognition & (AV_EF_CRCCHECK|AV_EF_CAREFUL)) { ctx->crc_table = av_crc_get_table(AV_CRC_32_IEEE_LE); @@ -632,7 +633,7 @@ static int read_var_block_data(ALSDecContext *ctx, ALSBlockData *bd) if (bd->block_length & (sub_blocks - 1)) { av_log(avctx, AV_LOG_WARNING, "Block length is not evenly divisible by the number of subblocks.\n"); - return -1; + return AVERROR_INVALIDDATA; } sb_length = bd->block_length >> log2_sub_blocks; @@ -651,6 +652,11 @@ static int read_var_block_data(ALSDecContext *ctx, ALSBlockData *bd) for (k = 1; k < sub_blocks; k++) s[k] = s[k - 1] + decode_rice(gb, 0); } + for (k = 1; k < sub_blocks; k++) + if (s[k] > 32) { + av_log(avctx, AV_LOG_ERROR, "k invalid for rice code.\n"); + return AVERROR_INVALIDDATA; + } if (get_bits1(gb)) *bd->shift_lsbs = get_bits(gb, 4) + 1; @@ -663,6 +669,11 @@ static int read_var_block_data(ALSDecContext *ctx, ALSBlockData *bd) int opt_order_length = av_ceil_log2(av_clip((bd->block_length >> 3) - 1, 2, sconf->max_order + 1)); *bd->opt_order = get_bits(gb, opt_order_length); + if (*bd->opt_order > sconf->max_order) { + *bd->opt_order = sconf->max_order; + av_log(avctx, AV_LOG_ERROR, "Predictor order too large!\n"); + return AVERROR_INVALIDDATA; + } } else { *bd->opt_order = sconf->max_order; } @@ -695,6 +706,10 @@ static int read_var_block_data(ALSDecContext *ctx, ALSBlockData *bd) int rice_param = parcor_rice_table[sconf->coef_table][k][1]; int offset = parcor_rice_table[sconf->coef_table][k][0]; quant_cof[k] = decode_rice(gb, rice_param) + offset; + if (quant_cof[k] < -64 || quant_cof[k] > 63) { + av_log(avctx, AV_LOG_ERROR, "quant_cof %d is out of range\n", quant_cof[k]); + return AVERROR_INVALIDDATA; + } } // read coefficients 20 to 126 @@ -727,7 +742,7 @@ static int read_var_block_data(ALSDecContext *ctx, ALSBlockData *bd) bd->ltp_gain[0] = decode_rice(gb, 1) << 3; bd->ltp_gain[1] = decode_rice(gb, 2) << 3; - r = get_unary(gb, 0, 4); + r = get_unary(gb, 0, 3); c = get_bits(gb, 2); bd->ltp_gain[2] = ltp_gain_values[r][c]; @@ -756,7 +771,6 @@ static int read_var_block_data(ALSDecContext *ctx, ALSBlockData *bd) int delta[8]; unsigned int k [8]; unsigned int b = av_clip((av_ceil_log2(bd->block_length) - 3) >> 1, 0, 5); - unsigned int i = start; // read most significant bits unsigned int high; @@ -767,29 +781,30 @@ static int read_var_block_data(ALSDecContext *ctx, ALSBlockData *bd) current_res = bd->raw_samples + start; - for (sb = 0; sb < sub_blocks; sb++, i = 0) { + for (sb = 0; sb < sub_blocks; sb++) { + unsigned int sb_len = sb_length - (sb ? 0 : start); + k [sb] = s[sb] > b ? s[sb] - b : 0; delta[sb] = 5 - s[sb] + k[sb]; - ff_bgmc_decode(gb, sb_length, current_res, + ff_bgmc_decode(gb, sb_len, current_res, delta[sb], sx[sb], &high, &low, &value, ctx->bgmc_lut, ctx->bgmc_lut_status); - current_res += sb_length; + current_res += sb_len; } ff_bgmc_decode_end(gb); // read least significant bits and tails - i = start; current_res = bd->raw_samples + start; - for (sb = 0; sb < sub_blocks; sb++, i = 0) { + for (sb = 0; sb < sub_blocks; sb++, start = 0) { unsigned int cur_tail_code = tail_code[sx[sb]][delta[sb]]; unsigned int cur_k = k[sb]; unsigned int cur_s = s[sb]; - for (; i < sb_length; i++) { + for (; start < sb_length; start++) { int32_t res = *current_res; if (res == cur_tail_code) { @@ -949,18 +964,18 @@ static int decode_var_block_data(ALSDecContext *ctx, ALSBlockData *bd) */ static int read_block(ALSDecContext *ctx, ALSBlockData *bd) { + int ret = 0; GetBitContext *gb = &ctx->gb; *bd->shift_lsbs = 0; // read block type flag and read the samples accordingly if (get_bits1(gb)) { - if (read_var_block_data(ctx, bd)) - return -1; + ret = read_var_block_data(ctx, bd); } else { read_const_block_data(ctx, bd); } - return 0; + return ret; } @@ -969,12 +984,16 @@ static int read_block(ALSDecContext *ctx, ALSBlockData *bd) static int decode_block(ALSDecContext *ctx, ALSBlockData *bd) { unsigned int smp; + int ret = 0; // read block type flag and read the samples accordingly if (*bd->const_block) decode_const_block_data(ctx, bd); - else if (decode_var_block_data(ctx, bd)) - return -1; + else + ret = decode_var_block_data(ctx, bd); // always return 0 + + if (ret < 0) + return ret; // TODO: read RLSLMS extension data @@ -992,14 +1011,10 @@ static int read_decode_block(ALSDecContext *ctx, ALSBlockData *bd) { int ret; - ret = read_block(ctx, bd); - - if (ret) + if ((ret = read_block(ctx, bd)) < 0) return ret; - ret = decode_block(ctx, bd); - - return ret; + return decode_block(ctx, bd); } @@ -1025,6 +1040,7 @@ static int decode_blocks_ind(ALSDecContext *ctx, unsigned int ra_frame, unsigned int c, const unsigned int *div_blocks, unsigned int *js_blocks) { + int ret; unsigned int b; ALSBlockData bd; @@ -1047,10 +1063,10 @@ static int decode_blocks_ind(ALSDecContext *ctx, unsigned int ra_frame, for (b = 0; b < ctx->num_blocks; b++) { bd.block_length = div_blocks[b]; - if (read_decode_block(ctx, &bd)) { + if ((ret = read_decode_block(ctx, &bd)) < 0) { // damaged block, write zero for the rest of the frame zero_remaining(b, ctx->num_blocks, div_blocks, bd.raw_samples); - return -1; + return ret; } bd.raw_samples += div_blocks[b]; bd.ra_block = 0; @@ -1069,6 +1085,7 @@ static int decode_blocks(ALSDecContext *ctx, unsigned int ra_frame, ALSSpecificConfig *sconf = &ctx->sconf; unsigned int offset = 0; unsigned int b; + int ret; ALSBlockData bd[2]; memset(bd, 0, 2 * sizeof(ALSBlockData)); @@ -1112,12 +1129,10 @@ static int decode_blocks(ALSDecContext *ctx, unsigned int ra_frame, bd[0].raw_other = bd[1].raw_samples; bd[1].raw_other = bd[0].raw_samples; - if(read_decode_block(ctx, &bd[0]) || read_decode_block(ctx, &bd[1])) { - // damaged block, write zero for the rest of the frame - zero_remaining(b, ctx->num_blocks, div_blocks, bd[0].raw_samples); - zero_remaining(b, ctx->num_blocks, div_blocks, bd[1].raw_samples); - return -1; - } + if ((ret = read_decode_block(ctx, &bd[0])) < 0 || + (ret = read_decode_block(ctx, &bd[1])) < 0) + goto fail; + // reconstruct joint-stereo blocks if (bd[0].js_blocks) { @@ -1143,8 +1158,19 @@ static int decode_blocks(ALSDecContext *ctx, unsigned int ra_frame, sizeof(*ctx->raw_samples[c]) * sconf->max_order); return 0; +fail: + // damaged block, write zero for the rest of the frame + zero_remaining(b, ctx->num_blocks, div_blocks, bd[0].raw_samples); + zero_remaining(b, ctx->num_blocks, div_blocks, bd[1].raw_samples); + return ret; } +static inline int als_weighting(GetBitContext *gb, int k, int off) +{ + int idx = av_clip(decode_rice(gb, k) + off, + 0, FF_ARRAY_ELEMS(mcc_weightings) - 1); + return mcc_weightings[idx]; +} /** Read the channel data. */ @@ -1160,19 +1186,19 @@ static int read_channel_data(ALSDecContext *ctx, ALSChannelData *cd, int c) if (current->master_channel >= channels) { av_log(ctx->avctx, AV_LOG_ERROR, "Invalid master channel!\n"); - return -1; + return AVERROR_INVALIDDATA; } if (current->master_channel != c) { current->time_diff_flag = get_bits1(gb); - current->weighting[0] = mcc_weightings[av_clip(decode_rice(gb, 1) + 16, 0, 32)]; - current->weighting[1] = mcc_weightings[av_clip(decode_rice(gb, 2) + 14, 0, 32)]; - current->weighting[2] = mcc_weightings[av_clip(decode_rice(gb, 1) + 16, 0, 32)]; + current->weighting[0] = als_weighting(gb, 1, 16); + current->weighting[1] = als_weighting(gb, 2, 14); + current->weighting[2] = als_weighting(gb, 1, 16); if (current->time_diff_flag) { - current->weighting[3] = mcc_weightings[av_clip(decode_rice(gb, 1) + 16, 0, 32)]; - current->weighting[4] = mcc_weightings[av_clip(decode_rice(gb, 1) + 16, 0, 32)]; - current->weighting[5] = mcc_weightings[av_clip(decode_rice(gb, 1) + 16, 0, 32)]; + current->weighting[3] = als_weighting(gb, 1, 16); + current->weighting[4] = als_weighting(gb, 1, 16); + current->weighting[5] = als_weighting(gb, 1, 16); current->time_diff_sign = get_bits1(gb); current->time_diff_index = get_bits(gb, ctx->ltp_lag_length - 3) + 3; @@ -1185,7 +1211,7 @@ static int read_channel_data(ALSDecContext *ctx, ALSChannelData *cd, int c) if (entries == channels) { av_log(ctx->avctx, AV_LOG_ERROR, "Damaged channel data!\n"); - return -1; + return AVERROR_INVALIDDATA; } align_get_bits(gb); @@ -1217,7 +1243,7 @@ static int revert_channel_correlation(ALSDecContext *ctx, ALSBlockData *bd, if (dep == channels) { av_log(ctx->avctx, AV_LOG_WARNING, "Invalid channel correlation!\n"); - return -1; + return AVERROR_INVALIDDATA; } bd->const_block = ctx->const_block + c; @@ -1290,6 +1316,7 @@ static int read_frame_data(ALSDecContext *ctx, unsigned int ra_frame) unsigned int js_blocks[2]; uint32_t bs_info = 0; + int ret; // skip the size of the ra unit if present in the frame if (sconf->ra_flag == RA_FLAG_FRAMES && ra_frame) @@ -1320,13 +1347,15 @@ static int read_frame_data(ALSDecContext *ctx, unsigned int ra_frame) independent_bs = 1; if (independent_bs) { - if (decode_blocks_ind(ctx, ra_frame, c, div_blocks, js_blocks)) - return -1; - + ret = decode_blocks_ind(ctx, ra_frame, c, + div_blocks, js_blocks); + if (ret < 0) + return ret; independent_bs--; } else { - if (decode_blocks(ctx, ra_frame, c, div_blocks, js_blocks)) - return -1; + ret = decode_blocks(ctx, ra_frame, c, div_blocks, js_blocks); + if (ret < 0) + return ret; c++; } @@ -1345,7 +1374,7 @@ static int read_frame_data(ALSDecContext *ctx, unsigned int ra_frame) for (c = 0; c < avctx->channels; c++) if (ctx->chan_data[c] < ctx->chan_data_buffer) { av_log(ctx->avctx, AV_LOG_ERROR, "Invalid channel data!\n"); - return -1; + return AVERROR_INVALIDDATA; } memset(&bd, 0, sizeof(ALSBlockData)); @@ -1358,6 +1387,11 @@ static int read_frame_data(ALSDecContext *ctx, unsigned int ra_frame) for (b = 0; b < ctx->num_blocks; b++) { bd.block_length = div_blocks[b]; + if (bd.block_length <= 0) { + av_log(ctx->avctx, AV_LOG_WARNING, + "Invalid block length %d in channel data!\n", bd.block_length); + continue; + } for (c = 0; c < avctx->channels; c++) { bd.const_block = ctx->const_block + c; @@ -1377,11 +1411,12 @@ static int read_frame_data(ALSDecContext *ctx, unsigned int ra_frame) return -1; } - for (c = 0; c < avctx->channels; c++) - if (revert_channel_correlation(ctx, &bd, ctx->chan_data, - reverted_channels, offset, c)) - return -1; - + for (c = 0; c < avctx->channels; c++) { + ret = revert_channel_correlation(ctx, &bd, ctx->chan_data, + reverted_channels, offset, c); + if (ret < 0) + return ret; + } for (c = 0; c < avctx->channels; c++) { bd.const_block = ctx->const_block + c; bd.shift_lsbs = ctx->shift_lsbs + c; @@ -1450,7 +1485,7 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame_ptr, /* get output buffer */ ctx->frame.nb_samples = ctx->cur_frame_length; - if ((ret = avctx->get_buffer(avctx, &ctx->frame)) < 0) { + if ((ret = ff_get_buffer(avctx, &ctx->frame)) < 0) { av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n"); return ret; } @@ -1578,29 +1613,30 @@ static av_cold int decode_init(AVCodecContext *avctx) { unsigned int c; unsigned int channel_size; - int num_buffers; + int num_buffers, ret; ALSDecContext *ctx = avctx->priv_data; ALSSpecificConfig *sconf = &ctx->sconf; ctx->avctx = avctx; if (!avctx->extradata) { av_log(avctx, AV_LOG_ERROR, "Missing required ALS extradata.\n"); - return -1; + return AVERROR_INVALIDDATA; } - if (read_specific_config(ctx)) { + if ((ret = read_specific_config(ctx)) < 0) { av_log(avctx, AV_LOG_ERROR, "Reading ALSSpecificConfig failed.\n"); - decode_end(avctx); - return -1; + goto fail; } - if (check_specific_config(ctx)) { - decode_end(avctx); - return -1; + if ((ret = check_specific_config(ctx)) < 0) { + goto fail; } - if (sconf->bgmc) - ff_bgmc_init(avctx, &ctx->bgmc_lut, &ctx->bgmc_lut_status); + if (sconf->bgmc) { + ret = ff_bgmc_init(avctx, &ctx->bgmc_lut, &ctx->bgmc_lut_status); + if (ret < 0) + goto fail; + } if (sconf->floating) { avctx->sample_fmt = AV_SAMPLE_FMT_FLT; @@ -1636,7 +1672,8 @@ static av_cold int decode_init(AVCodecContext *avctx) !ctx->quant_cof_buffer || !ctx->lpc_cof_buffer || !ctx->lpc_cof_reversed_buffer) { av_log(avctx, AV_LOG_ERROR, "Allocating buffer memory failed.\n"); - return AVERROR(ENOMEM); + ret = AVERROR(ENOMEM); + goto fail; } // assign quantized parcor coefficient buffers @@ -1661,8 +1698,8 @@ static av_cold int decode_init(AVCodecContext *avctx) !ctx->use_ltp || !ctx->ltp_lag || !ctx->ltp_gain || !ctx->ltp_gain_buffer) { av_log(avctx, AV_LOG_ERROR, "Allocating buffer memory failed.\n"); - decode_end(avctx); - return AVERROR(ENOMEM); + ret = AVERROR(ENOMEM); + goto fail; } for (c = 0; c < num_buffers; c++) @@ -1679,8 +1716,8 @@ static av_cold int decode_init(AVCodecContext *avctx) if (!ctx->chan_data_buffer || !ctx->chan_data || !ctx->reverted_channels) { av_log(avctx, AV_LOG_ERROR, "Allocating buffer memory failed.\n"); - decode_end(avctx); - return AVERROR(ENOMEM); + ret = AVERROR(ENOMEM); + goto fail; } for (c = 0; c < num_buffers; c++) @@ -1701,8 +1738,8 @@ static av_cold int decode_init(AVCodecContext *avctx) // allocate previous raw sample buffer if (!ctx->prev_raw_samples || !ctx->raw_buffer|| !ctx->raw_samples) { av_log(avctx, AV_LOG_ERROR, "Allocating buffer memory failed.\n"); - decode_end(avctx); - return AVERROR(ENOMEM); + ret = AVERROR(ENOMEM); + goto fail; } // assign raw samples buffers @@ -1719,8 +1756,8 @@ static av_cold int decode_init(AVCodecContext *avctx) av_get_bytes_per_sample(avctx->sample_fmt)); if (!ctx->crc_buffer) { av_log(avctx, AV_LOG_ERROR, "Allocating buffer memory failed.\n"); - decode_end(avctx); - return AVERROR(ENOMEM); + ret = AVERROR(ENOMEM); + goto fail; } } @@ -1730,6 +1767,10 @@ static av_cold int decode_init(AVCodecContext *avctx) avctx->coded_frame = &ctx->frame; return 0; + +fail: + decode_end(avctx); + return ret; } diff --git a/libavcodec/amrnbdec.c b/libavcodec/amrnbdec.c index c560d69e88..f2b0d3c1a7 100644 --- a/libavcodec/amrnbdec.c +++ b/libavcodec/amrnbdec.c @@ -44,6 +44,7 @@ #include #include "avcodec.h" +#include "internal.h" #include "get_bits.h" #include "libavutil/common.h" #include "celp_math.h" @@ -200,6 +201,10 @@ static enum Mode unpack_bitstream(AMRContext *p, const uint8_t *buf, p->bad_frame_indicator = !get_bits1(&gb); // quality bit skip_bits(&gb, 2); // two padding bits + if (mode >= N_MODES || buf_size < frame_sizes_nb[mode] + 1) { + return NO_DATA; + } + if (mode < MODE_DTX) ff_amr_bit_reorder((uint16_t *) &p->frame, sizeof(AMRNBFrame), buf + 1, amr_unpacking_bitmaps_per_mode[mode]); @@ -940,13 +945,17 @@ static int amrnb_decode_frame(AVCodecContext *avctx, void *data, /* get output buffer */ p->avframe.nb_samples = AMR_BLOCK_SIZE; - if ((ret = avctx->get_buffer(avctx, &p->avframe)) < 0) { + if ((ret = ff_get_buffer(avctx, &p->avframe)) < 0) { av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n"); return ret; } buf_out = (float *)p->avframe.data[0]; p->cur_frame_mode = unpack_bitstream(p, buf, buf_size); + if (p->cur_frame_mode == NO_DATA) { + av_log(avctx, AV_LOG_ERROR, "Corrupt bitstream\n"); + return AVERROR_INVALIDDATA; + } if (p->cur_frame_mode == MODE_DTX) { av_log_missing_feature(avctx, "dtx mode", 0); av_log(avctx, AV_LOG_INFO, "Note: libopencore_amrnb supports dtx\n"); diff --git a/libavcodec/amrwbdec.c b/libavcodec/amrwbdec.c index 524979d755..dd8f497e0d 100644 --- a/libavcodec/amrwbdec.c +++ b/libavcodec/amrwbdec.c @@ -27,6 +27,7 @@ #include "libavutil/lfg.h" #include "avcodec.h" +#include "internal.h" #include "get_bits.h" #include "lsp.h" #include "celp_math.h" @@ -898,10 +899,10 @@ static float auto_correlation(float *diff_isf, float mean, int lag) * Extrapolate a ISF vector to the 16kHz range (20th order LP) * used at mode 6k60 LP filter for the high frequency band. * - * @param[out] out Buffer for extrapolated isf - * @param[in] isf Input isf vector + * @param[out] isf Buffer for extrapolated isf; contains LP_ORDER + * values on input */ -static void extrapolate_isf(float out[LP_ORDER_16k], float isf[LP_ORDER]) +static void extrapolate_isf(float isf[LP_ORDER_16k]) { float diff_isf[LP_ORDER - 2], diff_mean; float *diff_hi = diff_isf - LP_ORDER + 1; // diff array for extrapolated indexes @@ -909,8 +910,7 @@ static void extrapolate_isf(float out[LP_ORDER_16k], float isf[LP_ORDER]) float est, scale; int i, i_max_corr; - memcpy(out, isf, (LP_ORDER - 1) * sizeof(float)); - out[LP_ORDER_16k - 1] = isf[LP_ORDER - 1]; + isf[LP_ORDER_16k - 1] = isf[LP_ORDER - 1]; /* Calculate the difference vector */ for (i = 0; i < LP_ORDER - 2; i++) @@ -931,16 +931,16 @@ static void extrapolate_isf(float out[LP_ORDER_16k], float isf[LP_ORDER]) i_max_corr++; for (i = LP_ORDER - 1; i < LP_ORDER_16k - 1; i++) - out[i] = isf[i - 1] + isf[i - 1 - i_max_corr] + isf[i] = isf[i - 1] + isf[i - 1 - i_max_corr] - isf[i - 2 - i_max_corr]; /* Calculate an estimate for ISF(18) and scale ISF based on the error */ - est = 7965 + (out[2] - out[3] - out[4]) / 6.0; - scale = 0.5 * (FFMIN(est, 7600) - out[LP_ORDER - 2]) / - (out[LP_ORDER_16k - 2] - out[LP_ORDER - 2]); + est = 7965 + (isf[2] - isf[3] - isf[4]) / 6.0; + scale = 0.5 * (FFMIN(est, 7600) - isf[LP_ORDER - 2]) / + (isf[LP_ORDER_16k - 2] - isf[LP_ORDER - 2]); for (i = LP_ORDER - 1; i < LP_ORDER_16k - 1; i++) - diff_hi[i] = scale * (out[i] - out[i - 1]); + diff_hi[i] = scale * (isf[i] - isf[i - 1]); /* Stability insurance */ for (i = LP_ORDER; i < LP_ORDER_16k - 1; i++) @@ -952,11 +952,11 @@ static void extrapolate_isf(float out[LP_ORDER_16k], float isf[LP_ORDER]) } for (i = LP_ORDER - 1; i < LP_ORDER_16k - 1; i++) - out[i] = out[i - 1] + diff_hi[i] * (1.0f / (1 << 15)); + isf[i] = isf[i - 1] + diff_hi[i] * (1.0f / (1 << 15)); /* Scale the ISF vector for 16000 Hz */ for (i = 0; i < LP_ORDER_16k - 1; i++) - out[i] *= 0.8; + isf[i] *= 0.8; } /** @@ -1003,7 +1003,7 @@ static void hb_synthesis(AMRWBContext *ctx, int subframe, float *samples, ff_weighted_vector_sumf(e_isf, isf_past, isf, isfp_inter[subframe], 1.0 - isfp_inter[subframe], LP_ORDER); - extrapolate_isf(e_isf, e_isf); + extrapolate_isf(e_isf); e_isf[LP_ORDER_16k - 1] *= 2.0; ff_acelp_lsf2lspd(e_isp, e_isf, LP_ORDER_16k); @@ -1088,30 +1088,34 @@ static int amrwb_decode_frame(AVCodecContext *avctx, void *data, /* get output buffer */ ctx->avframe.nb_samples = 4 * AMRWB_SFR_SIZE_16k; - if ((ret = avctx->get_buffer(avctx, &ctx->avframe)) < 0) { + if ((ret = ff_get_buffer(avctx, &ctx->avframe)) < 0) { av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n"); return ret; } buf_out = (float *)ctx->avframe.data[0]; header_size = decode_mime_header(ctx, buf); + if (ctx->fr_cur_mode > MODE_SID) { + av_log(avctx, AV_LOG_ERROR, + "Invalid mode %d\n", ctx->fr_cur_mode); + return AVERROR_INVALIDDATA; + } expected_fr_size = ((cf_sizes_wb[ctx->fr_cur_mode] + 7) >> 3) + 1; if (buf_size < expected_fr_size) { av_log(avctx, AV_LOG_ERROR, "Frame too small (%d bytes). Truncated file?\n", buf_size); *got_frame_ptr = 0; - return buf_size; + return AVERROR_INVALIDDATA; } if (!ctx->fr_quality || ctx->fr_cur_mode > MODE_SID) av_log(avctx, AV_LOG_ERROR, "Encountered a bad or corrupted frame\n"); - if (ctx->fr_cur_mode == MODE_SID) /* Comfort noise frame */ + if (ctx->fr_cur_mode == MODE_SID) { /* Comfort noise frame */ av_log_missing_feature(avctx, "SID mode", 1); - - if (ctx->fr_cur_mode >= MODE_SID) return -1; + } ff_amr_bit_reorder((uint16_t *) &ctx->frame, sizeof(AMRWBFrame), buf + header_size, amr_bit_orderings_by_mode[ctx->fr_cur_mode]); diff --git a/libavcodec/ansi.c b/libavcodec/ansi.c index ebcc288539..45d0380ab4 100644 --- a/libavcodec/ansi.c +++ b/libavcodec/ansi.c @@ -26,6 +26,7 @@ #include "libavutil/lfg.h" #include "avcodec.h" +#include "internal.h" #include "cga_data.h" #define ATTR_BOLD 0x01 /**< Bold/Bright-foreground (mode 1) */ @@ -222,7 +223,7 @@ static int execute_code(AVCodecContext * avctx, int c) if (s->frame.data[0]) avctx->release_buffer(avctx, &s->frame); avcodec_set_dimensions(avctx, width, height); - ret = avctx->get_buffer(avctx, &s->frame); + ret = ff_get_buffer(avctx, &s->frame); if (ret < 0) { av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n"); return ret; diff --git a/libavcodec/apedec.c b/libavcodec/apedec.c index 73fa030e6e..779e4b7af6 100644 --- a/libavcodec/apedec.c +++ b/libavcodec/apedec.c @@ -22,6 +22,7 @@ #define BITSTREAM_READER_LE #include "avcodec.h" +#include "internal.h" #include "dsputil.h" #include "get_bits.h" #include "bytestream.h" @@ -404,9 +405,12 @@ static inline int ape_decode_value(APEContext *ctx, APERice *rice) if (tmpk <= 16) x = range_decode_bits(ctx, tmpk); - else { + else if (tmpk <= 32) { x = range_decode_bits(ctx, 16); x |= (range_decode_bits(ctx, tmpk - 16) << 16); + } else { + av_log(ctx->avctx, AV_LOG_ERROR, "Too many bits: %d\n", tmpk); + return AVERROR_INVALIDDATA; } x += overflow << tmpk; } else { @@ -819,7 +823,6 @@ static int ape_decode_frame(AVCodecContext *avctx, void *data, int16_t *samples; int i, ret; int blockstodecode; - int bytes_used = 0; /* this should never be negative, but bad things will happen if it is, so check it just to make sure. */ @@ -874,7 +877,6 @@ static int ape_decode_frame(AVCodecContext *avctx, void *data, return AVERROR_INVALIDDATA; } - bytes_used = buf_size; } if (!s->data) { @@ -886,7 +888,7 @@ static int ape_decode_frame(AVCodecContext *avctx, void *data, /* get output buffer */ s->frame.nb_samples = blockstodecode; - if ((ret = avctx->get_buffer(avctx, &s->frame)) < 0) { + if ((ret = ff_get_buffer(avctx, &s->frame)) < 0) { av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n"); return ret; } @@ -917,7 +919,7 @@ static int ape_decode_frame(AVCodecContext *avctx, void *data, *got_frame_ptr = 1; *(AVFrame *)data = s->frame; - return bytes_used; + return (s->samples == 0) ? buf_size : 0; } static void ape_flush(AVCodecContext *avctx) diff --git a/libavcodec/arm/asm.S b/libavcodec/arm/asm.S index e540eac9fa..51b0cfbfae 100644 --- a/libavcodec/arm/asm.S +++ b/libavcodec/arm/asm.S @@ -132,6 +132,13 @@ T ldr \rt, [\rn] T add \rn, \rn, \rm .endm +.macro ldrc_pre cc, rt, rn, rm:vararg +A ldr\cc \rt, [\rn, \rm]! +T itt \cc +T add\cc \rn, \rn, \rm +T ldr\cc \rt, [\rn] +.endm + .macro ldrd_reg rt, rt2, rn, rm A ldrd \rt, \rt2, [\rn, \rm] T add \rt, \rn, \rm diff --git a/libavcodec/arm/dsputil_armv6.S b/libavcodec/arm/dsputil_armv6.S index 1adedf7b8f..c595c4a36a 100644 --- a/libavcodec/arm/dsputil_armv6.S +++ b/libavcodec/arm/dsputil_armv6.S @@ -146,10 +146,11 @@ function ff_put_pixels8_y2_armv6, export=1 eor r7, r5, r7 uadd8 r10, r10, r6 and r7, r7, r12 - ldr_pre r6, r1, r2 + ldrc_pre ne, r6, r1, r2 uadd8 r11, r11, r7 strd_post r8, r9, r0, r2 - ldr r7, [r1, #4] + it ne + ldrne r7, [r1, #4] strd_post r10, r11, r0, r2 bne 1b @@ -198,9 +199,10 @@ function ff_put_pixels8_y2_no_rnd_armv6, export=1 uhadd8 r9, r5, r7 ldr r5, [r1, #4] uhadd8 r12, r4, r6 - ldr_pre r6, r1, r2 + ldrc_pre ne, r6, r1, r2 uhadd8 r14, r5, r7 - ldr r7, [r1, #4] + it ne + ldrne r7, [r1, #4] stm r0, {r8,r9} add r0, r0, r2 stm r0, {r12,r14} diff --git a/libavcodec/arm/dsputil_neon.S b/libavcodec/arm/dsputil_neon.S index c660cb0d4c..344f28bea9 100644 --- a/libavcodec/arm/dsputil_neon.S +++ b/libavcodec/arm/dsputil_neon.S @@ -44,22 +44,22 @@ endfunc .if \avg mov r12, r0 .endif -1: vld1.64 {q0}, [r1], r2 - vld1.64 {q1}, [r1], r2 - vld1.64 {q2}, [r1], r2 +1: vld1.8 {q0}, [r1], r2 + vld1.8 {q1}, [r1], r2 + vld1.8 {q2}, [r1], r2 pld [r1, r2, lsl #2] - vld1.64 {q3}, [r1], r2 + vld1.8 {q3}, [r1], r2 pld [r1] pld [r1, r2] pld [r1, r2, lsl #1] .if \avg - vld1.64 {q8}, [r12,:128], r2 + vld1.8 {q8}, [r12,:128], r2 vrhadd.u8 q0, q0, q8 - vld1.64 {q9}, [r12,:128], r2 + vld1.8 {q9}, [r12,:128], r2 vrhadd.u8 q1, q1, q9 - vld1.64 {q10}, [r12,:128], r2 + vld1.8 {q10}, [r12,:128], r2 vrhadd.u8 q2, q2, q10 - vld1.64 {q11}, [r12,:128], r2 + vld1.8 {q11}, [r12,:128], r2 vrhadd.u8 q3, q3, q11 .endif subs r3, r3, #4 @@ -72,8 +72,8 @@ endfunc .endm .macro pixels16_x2 rnd=1, avg=0 -1: vld1.64 {d0-d2}, [r1], r2 - vld1.64 {d4-d6}, [r1], r2 +1: vld1.8 {d0-d2}, [r1], r2 + vld1.8 {d4-d6}, [r1], r2 pld [r1] pld [r1, r2] subs r3, r3, #2 @@ -88,20 +88,21 @@ endfunc vrhadd.u8 q2, q2, q3 sub r0, r0, r2 .endif - vst1.64 {q0}, [r0,:128], r2 - vst1.64 {q2}, [r0,:128], r2 + vst1.8 {q0}, [r0,:128], r2 + vst1.8 {q2}, [r0,:128], r2 bne 1b bx lr .endm .macro pixels16_y2 rnd=1, avg=0 - vld1.64 {q0}, [r1], r2 - vld1.64 {q1}, [r1], r2 + sub r3, r3, #2 + vld1.8 {q0}, [r1], r2 + vld1.8 {q1}, [r1], r2 1: subs r3, r3, #2 avg q2, q0, q1 - vld1.64 {q0}, [r1], r2 + vld1.8 {q0}, [r1], r2 avg q3, q0, q1 - vld1.64 {q1}, [r1], r2 + vld1.8 {q1}, [r1], r2 pld [r1] pld [r1, r2] .if \avg @@ -111,18 +112,31 @@ endfunc vrhadd.u8 q3, q3, q9 sub r0, r0, r2 .endif - vst1.64 {q2}, [r0,:128], r2 - vst1.64 {q3}, [r0,:128], r2 + vst1.8 {q2}, [r0,:128], r2 + vst1.8 {q3}, [r0,:128], r2 bne 1b + + avg q2, q0, q1 + vld1.8 {q0}, [r1], r2 + avg q3, q0, q1 + .if \avg + vld1.8 {q8}, [r0,:128], r2 + vld1.8 {q9}, [r0,:128] + vrhadd.u8 q2, q2, q8 + vrhadd.u8 q3, q3, q9 + sub r0, r0, r2 + .endif + vst1.8 {q2}, [r0,:128], r2 + vst1.8 {q3}, [r0,:128], r2 + bx lr .endm .macro pixels16_xy2 rnd=1, avg=0 - vld1.64 {d0-d2}, [r1], r2 - vld1.64 {d4-d6}, [r1], r2 - .ifeq \rnd - vmov.i16 q13, #1 - .endif + sub r3, r3, #2 + vld1.8 {d0-d2}, [r1], r2 + vld1.8 {d4-d6}, [r1], r2 +NRND vmov.i16 q13, #1 pld [r1] pld [r1, r2] vext.8 q1, q0, q1, #1 @@ -132,38 +146,30 @@ endfunc vaddl.u8 q9, d4, d6 vaddl.u8 q11, d5, d7 1: subs r3, r3, #2 - vld1.64 {d0-d2}, [r1], r2 + vld1.8 {d0-d2}, [r1], r2 vadd.u16 q12, q8, q9 pld [r1] - .ifeq \rnd - vadd.u16 q12, q12, q13 - .endif +NRND vadd.u16 q12, q12, q13 vext.8 q15, q0, q1, #1 vadd.u16 q1 , q10, q11 shrn d28, q12, #2 - .ifeq \rnd - vadd.u16 q1, q1, q13 - .endif +NRND vadd.u16 q1, q1, q13 shrn d29, q1, #2 .if \avg vld1.8 {q8}, [r0,:128] vrhadd.u8 q14, q14, q8 .endif vaddl.u8 q8, d0, d30 - vld1.64 {d2-d4}, [r1], r2 + vld1.8 {d2-d4}, [r1], r2 vaddl.u8 q10, d1, d31 - vst1.64 {q14}, [r0,:128], r2 + vst1.8 {q14}, [r0,:128], r2 vadd.u16 q12, q8, q9 pld [r1, r2] - .ifeq \rnd - vadd.u16 q12, q12, q13 - .endif +NRND vadd.u16 q12, q12, q13 vext.8 q2, q1, q2, #1 vadd.u16 q0, q10, q11 shrn d30, q12, #2 - .ifeq \rnd - vadd.u16 q0, q0, q13 - .endif +NRND vadd.u16 q0, q0, q13 shrn d31, q0, #2 .if \avg vld1.8 {q9}, [r0,:128] @@ -171,44 +177,72 @@ endfunc .endif vaddl.u8 q9, d2, d4 vaddl.u8 q11, d3, d5 - vst1.64 {q15}, [r0,:128], r2 + vst1.8 {q15}, [r0,:128], r2 bgt 1b + + vld1.8 {d0-d2}, [r1], r2 + vadd.u16 q12, q8, q9 +NRND vadd.u16 q12, q12, q13 + vext.8 q15, q0, q1, #1 + vadd.u16 q1 , q10, q11 + shrn d28, q12, #2 +NRND vadd.u16 q1, q1, q13 + shrn d29, q1, #2 + .if \avg + vld1.8 {q8}, [r0,:128] + vrhadd.u8 q14, q14, q8 + .endif + vaddl.u8 q8, d0, d30 + vaddl.u8 q10, d1, d31 + vst1.8 {q14}, [r0,:128], r2 + vadd.u16 q12, q8, q9 +NRND vadd.u16 q12, q12, q13 + vadd.u16 q0, q10, q11 + shrn d30, q12, #2 +NRND vadd.u16 q0, q0, q13 + shrn d31, q0, #2 + .if \avg + vld1.8 {q9}, [r0,:128] + vrhadd.u8 q15, q15, q9 + .endif + vst1.8 {q15}, [r0,:128], r2 + bx lr .endm .macro pixels8 rnd=1, avg=0 -1: vld1.64 {d0}, [r1], r2 - vld1.64 {d1}, [r1], r2 - vld1.64 {d2}, [r1], r2 +1: vld1.8 {d0}, [r1], r2 + vld1.8 {d1}, [r1], r2 + vld1.8 {d2}, [r1], r2 pld [r1, r2, lsl #2] - vld1.64 {d3}, [r1], r2 + vld1.8 {d3}, [r1], r2 pld [r1] pld [r1, r2] pld [r1, r2, lsl #1] .if \avg - vld1.64 {d4}, [r0,:64], r2 + vld1.8 {d4}, [r0,:64], r2 vrhadd.u8 d0, d0, d4 - vld1.64 {d5}, [r0,:64], r2 + vld1.8 {d5}, [r0,:64], r2 vrhadd.u8 d1, d1, d5 - vld1.64 {d6}, [r0,:64], r2 + vld1.8 {d6}, [r0,:64], r2 vrhadd.u8 d2, d2, d6 - vld1.64 {d7}, [r0,:64], r2 + vld1.8 {d7}, [r0,:64], r2 vrhadd.u8 d3, d3, d7 sub r0, r0, r2, lsl #2 .endif subs r3, r3, #4 - vst1.64 {d0}, [r0,:64], r2 - vst1.64 {d1}, [r0,:64], r2 - vst1.64 {d2}, [r0,:64], r2 - vst1.64 {d3}, [r0,:64], r2 + vst1.8 {d0}, [r0,:64], r2 + vst1.8 {d1}, [r0,:64], r2 + vst1.8 {d2}, [r0,:64], r2 + vst1.8 {d3}, [r0,:64], r2 bne 1b bx lr .endm .macro pixels8_x2 rnd=1, avg=0 -1: vld1.64 {q0}, [r1], r2 +1: vld1.8 {q0}, [r1], r2 vext.8 d1, d0, d1, #1 - vld1.64 {q1}, [r1], r2 + vld1.8 {q1}, [r1], r2 vext.8 d3, d2, d3, #1 pld [r1] pld [r1, r2] @@ -221,20 +255,21 @@ endfunc vrhadd.u8 q0, q0, q2 sub r0, r0, r2 .endif - vst1.64 {d0}, [r0,:64], r2 - vst1.64 {d1}, [r0,:64], r2 + vst1.8 {d0}, [r0,:64], r2 + vst1.8 {d1}, [r0,:64], r2 bne 1b bx lr .endm .macro pixels8_y2 rnd=1, avg=0 - vld1.64 {d0}, [r1], r2 - vld1.64 {d1}, [r1], r2 + sub r3, r3, #2 + vld1.8 {d0}, [r1], r2 + vld1.8 {d1}, [r1], r2 1: subs r3, r3, #2 avg d4, d0, d1 - vld1.64 {d0}, [r1], r2 + vld1.8 {d0}, [r1], r2 avg d5, d0, d1 - vld1.64 {d1}, [r1], r2 + vld1.8 {d1}, [r1], r2 pld [r1] pld [r1, r2] .if \avg @@ -243,18 +278,30 @@ endfunc vrhadd.u8 q2, q2, q1 sub r0, r0, r2 .endif - vst1.64 {d4}, [r0,:64], r2 - vst1.64 {d5}, [r0,:64], r2 + vst1.8 {d4}, [r0,:64], r2 + vst1.8 {d5}, [r0,:64], r2 bne 1b + + avg d4, d0, d1 + vld1.8 {d0}, [r1], r2 + avg d5, d0, d1 + .if \avg + vld1.8 {d2}, [r0,:64], r2 + vld1.8 {d3}, [r0,:64] + vrhadd.u8 q2, q2, q1 + sub r0, r0, r2 + .endif + vst1.8 {d4}, [r0,:64], r2 + vst1.8 {d5}, [r0,:64], r2 + bx lr .endm .macro pixels8_xy2 rnd=1, avg=0 - vld1.64 {q0}, [r1], r2 - vld1.64 {q1}, [r1], r2 - .ifeq \rnd - vmov.i16 q11, #1 - .endif + sub r3, r3, #2 + vld1.8 {q0}, [r1], r2 + vld1.8 {q1}, [r1], r2 +NRND vmov.i16 q11, #1 pld [r1] pld [r1, r2] vext.8 d4, d0, d1, #1 @@ -262,26 +309,22 @@ endfunc vaddl.u8 q8, d0, d4 vaddl.u8 q9, d2, d6 1: subs r3, r3, #2 - vld1.64 {q0}, [r1], r2 + vld1.8 {q0}, [r1], r2 pld [r1] vadd.u16 q10, q8, q9 vext.8 d4, d0, d1, #1 - .ifeq \rnd - vadd.u16 q10, q10, q11 - .endif +NRND vadd.u16 q10, q10, q11 vaddl.u8 q8, d0, d4 shrn d5, q10, #2 - vld1.64 {q1}, [r1], r2 + vld1.8 {q1}, [r1], r2 vadd.u16 q10, q8, q9 pld [r1, r2] .if \avg vld1.8 {d7}, [r0,:64] vrhadd.u8 d5, d5, d7 .endif - .ifeq \rnd - vadd.u16 q10, q10, q11 - .endif - vst1.64 {d5}, [r0,:64], r2 +NRND vadd.u16 q10, q10, q11 + vst1.8 {d5}, [r0,:64], r2 shrn d7, q10, #2 .if \avg vld1.8 {d5}, [r0,:64] @@ -289,8 +332,29 @@ endfunc .endif vext.8 d6, d2, d3, #1 vaddl.u8 q9, d2, d6 - vst1.64 {d7}, [r0,:64], r2 + vst1.8 {d7}, [r0,:64], r2 bgt 1b + + vld1.8 {q0}, [r1], r2 + vadd.u16 q10, q8, q9 + vext.8 d4, d0, d1, #1 +NRND vadd.u16 q10, q10, q11 + vaddl.u8 q8, d0, d4 + shrn d5, q10, #2 + vadd.u16 q10, q8, q9 + .if \avg + vld1.8 {d7}, [r0,:64] + vrhadd.u8 d5, d5, d7 + .endif +NRND vadd.u16 q10, q10, q11 + vst1.8 {d5}, [r0,:64], r2 + shrn d7, q10, #2 + .if \avg + vld1.8 {d5}, [r0,:64] + vrhadd.u8 d7, d7, d5 + .endif + vst1.8 {d7}, [r0,:64], r2 + bx lr .endm @@ -302,6 +366,8 @@ endfunc .macro shrn rd, rn, rm vrshrn.u16 \rd, \rn, \rm .endm + .macro NRND insn:vararg + .endm .else .macro avg rd, rn, rm vhadd.u8 \rd, \rn, \rm @@ -309,12 +375,16 @@ endfunc .macro shrn rd, rn, rm vshrn.u16 \rd, \rn, \rm .endm + .macro NRND insn:vararg + \insn + .endm .endif function ff_\pfx\name\suf\()_neon, export=1 \name \rnd, \avg endfunc .purgem avg .purgem shrn + .purgem NRND .endm .macro pixfunc2 pfx, name, avg=0 @@ -359,147 +429,147 @@ endfunc pixfunc2 avg_, pixels8_xy2, avg=1 function ff_put_pixels_clamped_neon, export=1 - vld1.64 {d16-d19}, [r0,:128]! + vld1.16 {d16-d19}, [r0,:128]! vqmovun.s16 d0, q8 - vld1.64 {d20-d23}, [r0,:128]! + vld1.16 {d20-d23}, [r0,:128]! vqmovun.s16 d1, q9 - vld1.64 {d24-d27}, [r0,:128]! + vld1.16 {d24-d27}, [r0,:128]! vqmovun.s16 d2, q10 - vld1.64 {d28-d31}, [r0,:128]! + vld1.16 {d28-d31}, [r0,:128]! vqmovun.s16 d3, q11 - vst1.64 {d0}, [r1,:64], r2 + vst1.8 {d0}, [r1,:64], r2 vqmovun.s16 d4, q12 - vst1.64 {d1}, [r1,:64], r2 + vst1.8 {d1}, [r1,:64], r2 vqmovun.s16 d5, q13 - vst1.64 {d2}, [r1,:64], r2 + vst1.8 {d2}, [r1,:64], r2 vqmovun.s16 d6, q14 - vst1.64 {d3}, [r1,:64], r2 + vst1.8 {d3}, [r1,:64], r2 vqmovun.s16 d7, q15 - vst1.64 {d4}, [r1,:64], r2 - vst1.64 {d5}, [r1,:64], r2 - vst1.64 {d6}, [r1,:64], r2 - vst1.64 {d7}, [r1,:64], r2 + vst1.8 {d4}, [r1,:64], r2 + vst1.8 {d5}, [r1,:64], r2 + vst1.8 {d6}, [r1,:64], r2 + vst1.8 {d7}, [r1,:64], r2 bx lr endfunc function ff_put_signed_pixels_clamped_neon, export=1 vmov.u8 d31, #128 - vld1.64 {d16-d17}, [r0,:128]! + vld1.16 {d16-d17}, [r0,:128]! vqmovn.s16 d0, q8 - vld1.64 {d18-d19}, [r0,:128]! + vld1.16 {d18-d19}, [r0,:128]! vqmovn.s16 d1, q9 - vld1.64 {d16-d17}, [r0,:128]! + vld1.16 {d16-d17}, [r0,:128]! vqmovn.s16 d2, q8 - vld1.64 {d18-d19}, [r0,:128]! + vld1.16 {d18-d19}, [r0,:128]! vadd.u8 d0, d0, d31 - vld1.64 {d20-d21}, [r0,:128]! + vld1.16 {d20-d21}, [r0,:128]! vadd.u8 d1, d1, d31 - vld1.64 {d22-d23}, [r0,:128]! + vld1.16 {d22-d23}, [r0,:128]! vadd.u8 d2, d2, d31 - vst1.64 {d0}, [r1,:64], r2 + vst1.8 {d0}, [r1,:64], r2 vqmovn.s16 d3, q9 - vst1.64 {d1}, [r1,:64], r2 + vst1.8 {d1}, [r1,:64], r2 vqmovn.s16 d4, q10 - vst1.64 {d2}, [r1,:64], r2 + vst1.8 {d2}, [r1,:64], r2 vqmovn.s16 d5, q11 - vld1.64 {d24-d25}, [r0,:128]! + vld1.16 {d24-d25}, [r0,:128]! vadd.u8 d3, d3, d31 - vld1.64 {d26-d27}, [r0,:128]! + vld1.16 {d26-d27}, [r0,:128]! vadd.u8 d4, d4, d31 vadd.u8 d5, d5, d31 - vst1.64 {d3}, [r1,:64], r2 + vst1.8 {d3}, [r1,:64], r2 vqmovn.s16 d6, q12 - vst1.64 {d4}, [r1,:64], r2 + vst1.8 {d4}, [r1,:64], r2 vqmovn.s16 d7, q13 - vst1.64 {d5}, [r1,:64], r2 + vst1.8 {d5}, [r1,:64], r2 vadd.u8 d6, d6, d31 vadd.u8 d7, d7, d31 - vst1.64 {d6}, [r1,:64], r2 - vst1.64 {d7}, [r1,:64], r2 + vst1.8 {d6}, [r1,:64], r2 + vst1.8 {d7}, [r1,:64], r2 bx lr endfunc function ff_add_pixels_clamped_neon, export=1 mov r3, r1 - vld1.64 {d16}, [r1,:64], r2 - vld1.64 {d0-d1}, [r0,:128]! + vld1.8 {d16}, [r1,:64], r2 + vld1.16 {d0-d1}, [r0,:128]! vaddw.u8 q0, q0, d16 - vld1.64 {d17}, [r1,:64], r2 - vld1.64 {d2-d3}, [r0,:128]! + vld1.8 {d17}, [r1,:64], r2 + vld1.16 {d2-d3}, [r0,:128]! vqmovun.s16 d0, q0 - vld1.64 {d18}, [r1,:64], r2 + vld1.8 {d18}, [r1,:64], r2 vaddw.u8 q1, q1, d17 - vld1.64 {d4-d5}, [r0,:128]! + vld1.16 {d4-d5}, [r0,:128]! vaddw.u8 q2, q2, d18 - vst1.64 {d0}, [r3,:64], r2 + vst1.8 {d0}, [r3,:64], r2 vqmovun.s16 d2, q1 - vld1.64 {d19}, [r1,:64], r2 - vld1.64 {d6-d7}, [r0,:128]! + vld1.8 {d19}, [r1,:64], r2 + vld1.16 {d6-d7}, [r0,:128]! vaddw.u8 q3, q3, d19 vqmovun.s16 d4, q2 - vst1.64 {d2}, [r3,:64], r2 - vld1.64 {d16}, [r1,:64], r2 + vst1.8 {d2}, [r3,:64], r2 + vld1.8 {d16}, [r1,:64], r2 vqmovun.s16 d6, q3 - vld1.64 {d0-d1}, [r0,:128]! + vld1.16 {d0-d1}, [r0,:128]! vaddw.u8 q0, q0, d16 - vst1.64 {d4}, [r3,:64], r2 - vld1.64 {d17}, [r1,:64], r2 - vld1.64 {d2-d3}, [r0,:128]! + vst1.8 {d4}, [r3,:64], r2 + vld1.8 {d17}, [r1,:64], r2 + vld1.16 {d2-d3}, [r0,:128]! vaddw.u8 q1, q1, d17 - vst1.64 {d6}, [r3,:64], r2 + vst1.8 {d6}, [r3,:64], r2 vqmovun.s16 d0, q0 - vld1.64 {d18}, [r1,:64], r2 - vld1.64 {d4-d5}, [r0,:128]! + vld1.8 {d18}, [r1,:64], r2 + vld1.16 {d4-d5}, [r0,:128]! vaddw.u8 q2, q2, d18 - vst1.64 {d0}, [r3,:64], r2 + vst1.8 {d0}, [r3,:64], r2 vqmovun.s16 d2, q1 - vld1.64 {d19}, [r1,:64], r2 + vld1.8 {d19}, [r1,:64], r2 vqmovun.s16 d4, q2 - vld1.64 {d6-d7}, [r0,:128]! + vld1.16 {d6-d7}, [r0,:128]! vaddw.u8 q3, q3, d19 - vst1.64 {d2}, [r3,:64], r2 + vst1.8 {d2}, [r3,:64], r2 vqmovun.s16 d6, q3 - vst1.64 {d4}, [r3,:64], r2 - vst1.64 {d6}, [r3,:64], r2 + vst1.8 {d4}, [r3,:64], r2 + vst1.8 {d6}, [r3,:64], r2 bx lr endfunc function ff_vector_fmul_neon, export=1 subs r3, r3, #8 - vld1.64 {d0-d3}, [r1,:128]! - vld1.64 {d4-d7}, [r2,:128]! + vld1.32 {d0-d3}, [r1,:128]! + vld1.32 {d4-d7}, [r2,:128]! vmul.f32 q8, q0, q2 vmul.f32 q9, q1, q3 beq 3f bics ip, r3, #15 beq 2f 1: subs ip, ip, #16 - vld1.64 {d0-d1}, [r1,:128]! - vld1.64 {d4-d5}, [r2,:128]! + vld1.32 {d0-d1}, [r1,:128]! + vld1.32 {d4-d5}, [r2,:128]! vmul.f32 q10, q0, q2 - vld1.64 {d2-d3}, [r1,:128]! - vld1.64 {d6-d7}, [r2,:128]! + vld1.32 {d2-d3}, [r1,:128]! + vld1.32 {d6-d7}, [r2,:128]! vmul.f32 q11, q1, q3 - vst1.64 {d16-d19},[r0,:128]! - vld1.64 {d0-d1}, [r1,:128]! - vld1.64 {d4-d5}, [r2,:128]! + vst1.32 {d16-d19},[r0,:128]! + vld1.32 {d0-d1}, [r1,:128]! + vld1.32 {d4-d5}, [r2,:128]! vmul.f32 q8, q0, q2 - vld1.64 {d2-d3}, [r1,:128]! - vld1.64 {d6-d7}, [r2,:128]! + vld1.32 {d2-d3}, [r1,:128]! + vld1.32 {d6-d7}, [r2,:128]! vmul.f32 q9, q1, q3 - vst1.64 {d20-d23},[r0,:128]! + vst1.32 {d20-d23},[r0,:128]! bne 1b ands r3, r3, #15 beq 3f -2: vld1.64 {d0-d1}, [r1,:128]! - vld1.64 {d4-d5}, [r2,:128]! - vst1.64 {d16-d17},[r0,:128]! +2: vld1.32 {d0-d1}, [r1,:128]! + vld1.32 {d4-d5}, [r2,:128]! + vst1.32 {d16-d17},[r0,:128]! vmul.f32 q8, q0, q2 - vld1.64 {d2-d3}, [r1,:128]! - vld1.64 {d6-d7}, [r2,:128]! - vst1.64 {d18-d19},[r0,:128]! + vld1.32 {d2-d3}, [r1,:128]! + vld1.32 {d6-d7}, [r2,:128]! + vst1.32 {d18-d19},[r0,:128]! vmul.f32 q9, q1, q3 -3: vst1.64 {d16-d19},[r0,:128]! +3: vst1.32 {d16-d19},[r0,:128]! bx lr endfunc @@ -512,10 +582,10 @@ function ff_vector_fmul_window_neon, export=1 add r4, r3, r5, lsl #3 add ip, r0, r5, lsl #3 mov r5, #-16 - vld1.64 {d0,d1}, [r1,:128]! - vld1.64 {d2,d3}, [r2,:128], r5 - vld1.64 {d4,d5}, [r3,:128]! - vld1.64 {d6,d7}, [r4,:128], r5 + vld1.32 {d0,d1}, [r1,:128]! + vld1.32 {d2,d3}, [r2,:128], r5 + vld1.32 {d4,d5}, [r3,:128]! + vld1.32 {d6,d7}, [r4,:128], r5 1: subs lr, lr, #4 vmul.f32 d22, d0, d4 vrev64.32 q3, q3 @@ -525,19 +595,19 @@ function ff_vector_fmul_window_neon, export=1 vmul.f32 d21, d1, d6 beq 2f vmla.f32 d22, d3, d7 - vld1.64 {d0,d1}, [r1,:128]! + vld1.32 {d0,d1}, [r1,:128]! vmla.f32 d23, d2, d6 - vld1.64 {d18,d19},[r2,:128], r5 + vld1.32 {d18,d19},[r2,:128], r5 vmls.f32 d20, d3, d4 - vld1.64 {d24,d25},[r3,:128]! + vld1.32 {d24,d25},[r3,:128]! vmls.f32 d21, d2, d5 - vld1.64 {d6,d7}, [r4,:128], r5 + vld1.32 {d6,d7}, [r4,:128], r5 vmov q1, q9 vrev64.32 q11, q11 vmov q2, q12 vswp d22, d23 - vst1.64 {d20,d21},[r0,:128]! - vst1.64 {d22,d23},[ip,:128], r5 + vst1.32 {d20,d21},[r0,:128]! + vst1.32 {d22,d23},[ip,:128], r5 b 1b 2: vmla.f32 d22, d3, d7 vmla.f32 d23, d2, d6 @@ -545,8 +615,8 @@ function ff_vector_fmul_window_neon, export=1 vmls.f32 d21, d2, d5 vrev64.32 q11, q11 vswp d22, d23 - vst1.64 {d20,d21},[r0,:128]! - vst1.64 {d22,d23},[ip,:128], r5 + vst1.32 {d20,d21},[r0,:128]! + vst1.32 {d22,d23},[ip,:128], r5 pop {r4,r5,pc} endfunc diff --git a/libavcodec/arm/h264dsp_init_arm.c b/libavcodec/arm/h264dsp_init_arm.c index cc4c688c8b..94dfc52b93 100644 --- a/libavcodec/arm/h264dsp_init_arm.c +++ b/libavcodec/arm/h264dsp_init_arm.c @@ -89,7 +89,7 @@ static void ff_h264dsp_init_neon(H264DSPContext *c, const int bit_depth, const i c->h264_idct_dc_add = ff_h264_idct_dc_add_neon; c->h264_idct_add16 = ff_h264_idct_add16_neon; c->h264_idct_add16intra = ff_h264_idct_add16intra_neon; - if (chroma_format_idc == 1) + if (chroma_format_idc <= 1) c->h264_idct_add8 = ff_h264_idct_add8_neon; c->h264_idct8_add = ff_h264_idct8_add_neon; c->h264_idct8_dc_add = ff_h264_idct8_dc_add_neon; diff --git a/libavcodec/arm/int_neon.S b/libavcodec/arm/int_neon.S index e1353982d0..bb3c9533f9 100644 --- a/libavcodec/arm/int_neon.S +++ b/libavcodec/arm/int_neon.S @@ -66,10 +66,10 @@ function ff_scalarproduct_int16_neon, export=1 3: vpadd.s32 d16, d0, d1 vpadd.s32 d17, d2, d3 - vpadd.s32 d10, d4, d5 - vpadd.s32 d11, d6, d7 + vpadd.s32 d18, d4, d5 + vpadd.s32 d19, d6, d7 vpadd.s32 d0, d16, d17 - vpadd.s32 d1, d10, d11 + vpadd.s32 d1, d18, d19 vpadd.s32 d2, d0, d1 vpaddl.s32 d3, d2 vmov.32 r0, d3[0] @@ -106,10 +106,10 @@ function ff_scalarproduct_and_madd_int16_neon, export=1 vpadd.s32 d16, d0, d1 vpadd.s32 d17, d2, d3 - vpadd.s32 d10, d4, d5 - vpadd.s32 d11, d6, d7 + vpadd.s32 d18, d4, d5 + vpadd.s32 d19, d6, d7 vpadd.s32 d0, d16, d17 - vpadd.s32 d1, d10, d11 + vpadd.s32 d1, d18, d19 vpadd.s32 d2, d0, d1 vpaddl.s32 d3, d2 vmov.32 r0, d3[0] diff --git a/libavcodec/ass_split.c b/libavcodec/ass_split.c index 2a3b76445e..33c1c2714f 100644 --- a/libavcodec/ass_split.c +++ b/libavcodec/ass_split.c @@ -366,7 +366,7 @@ int ff_ass_split_override_codes(const ASSCodesCallbacks *callbacks, void *priv, char new_line[2]; int text_len = 0; - while (*buf) { + while (buf && *buf) { if (text && callbacks->text && (sscanf(buf, "\\%1[nN]", new_line) == 1 || !strncmp(buf, "{\\", 2))) { diff --git a/libavcodec/asv1.c b/libavcodec/asv1.c index 9eeec2675a..d9a5968793 100644 --- a/libavcodec/asv1.c +++ b/libavcodec/asv1.c @@ -535,6 +535,11 @@ static av_cold int decode_init(AVCodecContext *avctx){ int i; const int scale= avctx->codec_id == CODEC_ID_ASV1 ? 1 : 2; + if (avctx->extradata_size < 1) { + av_log(avctx, AV_LOG_ERROR, "No extradata provided\n"); + return AVERROR_INVALIDDATA; + } + common_init(avctx); init_vlcs(a); ff_init_scantable(a->dsp.idct_permutation, &a->scantable, scantab); diff --git a/libavcodec/atrac1.c b/libavcodec/atrac1.c index c796235c80..a20c8e956f 100644 --- a/libavcodec/atrac1.c +++ b/libavcodec/atrac1.c @@ -33,6 +33,7 @@ #include #include "avcodec.h" +#include "internal.h" #include "get_bits.h" #include "dsputil.h" #include "fft.h" @@ -291,7 +292,7 @@ static int atrac1_decode_frame(AVCodecContext *avctx, void *data, /* get output buffer */ q->frame.nb_samples = AT1_SU_SAMPLES; - if ((ret = avctx->get_buffer(avctx, &q->frame)) < 0) { + if ((ret = ff_get_buffer(avctx, &q->frame)) < 0) { av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n"); return ret; } diff --git a/libavcodec/atrac3.c b/libavcodec/atrac3.c index efaadc93fc..ed80ee3f28 100644 --- a/libavcodec/atrac3.c +++ b/libavcodec/atrac3.c @@ -37,6 +37,7 @@ #include #include "avcodec.h" +#include "internal.h" #include "get_bits.h" #include "dsputil.h" #include "bytestream.h" @@ -184,8 +185,11 @@ static int decode_bytes(const uint8_t* inbuffer, uint8_t* out, int bytes){ uint32_t* obuf = (uint32_t*) out; off = (intptr_t)inbuffer & 3; - buf = (const uint32_t*) (inbuffer - off); - c = av_be2ne32((0x537F6103 >> (off*8)) | (0x537F6103 << (32-(off*8)))); + buf = (const uint32_t *)(inbuffer - off); + if (off) + c = av_be2ne32((0x537F6103U >> (off * 8)) | (0x537F6103U << (32 - (off * 8)))); + else + c = av_be2ne32(0x537F6103U); bytes += 3 + off; for (i = 0; i < bytes/4; i++) obuf[i] = c ^ buf[i]; @@ -402,7 +406,7 @@ static int decodeTonalComponents (GetBitContext *gb, tonal_component *pComponent for (k=0; k=64) + if (component_count >= 64) return AVERROR_INVALIDDATA; pComponent[component_count].pos = j * 64 + (get_bits(gb,6)); max_coded_values = SAMPLES_PER_FRAME - pComponent[component_count].pos; @@ -687,7 +691,8 @@ static int decodeChannelSoundUnit (ATRAC3Context *q, GetBitContext *gb, channel_ if (result) return result; pSnd->numComponents = decodeTonalComponents (gb, pSnd->components, pSnd->bandsCoded); - if (pSnd->numComponents == -1) return -1; + if (pSnd->numComponents < 0) + return pSnd->numComponents; numSubbands = decodeSpectrum (gb, pSnd->spectrum); @@ -769,7 +774,7 @@ static int decodeFrame(ATRAC3Context *q, const uint8_t* databuf, /* set the bitstream reader at the start of the second Sound Unit*/ - init_get_bits(&q->gb,ptr1,q->bits_per_frame); + init_get_bits(&q->gb, ptr1, (q->bytes_per_frame - i) * 8); /* Fill the Weighting coeffs delay buffer */ memmove(q->weighting_delay,&(q->weighting_delay[2]),4*sizeof(int)); @@ -848,7 +853,7 @@ static int atrac3_decode_frame(AVCodecContext *avctx, void *data, /* get output buffer */ q->frame.nb_samples = SAMPLES_PER_FRAME; - if ((result = avctx->get_buffer(avctx, &q->frame)) < 0) { + if ((result = ff_get_buffer(avctx, &q->frame)) < 0) { av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n"); return result; } @@ -972,6 +977,8 @@ static av_cold int atrac3_decode_init(AVCodecContext *avctx) if (q->codingMode == STEREO) { av_log(avctx,AV_LOG_DEBUG,"Normal stereo detected.\n"); } else if (q->codingMode == JOINT_STEREO) { + if (avctx->channels != 2) + return AVERROR_INVALIDDATA; av_log(avctx,AV_LOG_DEBUG,"Joint stereo detected.\n"); } else { av_log(avctx,AV_LOG_ERROR,"Unknown channel coding mode %x!\n",q->codingMode); diff --git a/libavcodec/avcodec.h b/libavcodec/avcodec.h index 62e90be012..81849c15bf 100644 --- a/libavcodec/avcodec.h +++ b/libavcodec/avcodec.h @@ -4032,7 +4032,8 @@ AVCodecContext *avcodec_alloc_context2(enum AVMediaType); /** * Allocate an AVCodecContext and set its fields to default values. The - * resulting struct can be deallocated by simply calling av_free(). + * resulting struct can be deallocated by calling avcodec_close() on it followed + * by av_free(). * * @param codec if non-NULL, allocate private data and initialize defaults * for the given codec. It is illegal to then call avcodec_open2() @@ -4178,6 +4179,11 @@ int avcodec_open(AVCodecContext *avctx, AVCodec *codec); * @endcode * * @param avctx The context to initialize. + * @param codec The codec to open this context for. If a non-NULL codec has been + * previously passed to avcodec_alloc_context3() or + * avcodec_get_context_defaults3() for this context, then this + * parameter MUST be either NULL or equal to the previously passed + * codec. * @param options A dictionary filled with AVCodecContext and codec-private options. * On return this object will be filled with options that were not found. * @@ -4463,6 +4469,15 @@ int avcodec_encode_video(AVCodecContext *avctx, uint8_t *buf, int buf_size, int avcodec_encode_subtitle(AVCodecContext *avctx, uint8_t *buf, int buf_size, const AVSubtitle *sub); +/** + * Close a given AVCodecContext and free all the data associated with it + * (but not the AVCodecContext itself). + * + * Calling this function on an AVCodecContext that hasn't been opened will free + * the codec-specific data allocated in avcodec_alloc_context3() / + * avcodec_get_context_defaults3() with a non-NULL codec. Subsequent calls will + * do nothing. + */ int avcodec_close(AVCodecContext *avctx); /** @@ -4874,4 +4889,10 @@ const AVClass *avcodec_get_class(void); */ const AVClass *avcodec_get_frame_class(void); +/** + * @return a positive value if s is open (i.e. avcodec_open2() was called on it + * with no corresponding avcodec_close()), 0 otherwise. + */ +int avcodec_is_open(AVCodecContext *s); + #endif /* AVCODEC_AVCODEC_H */ diff --git a/libavcodec/avs.c b/libavcodec/avs.c index 05cb815fd8..12b42e2239 100644 --- a/libavcodec/avs.c +++ b/libavcodec/avs.c @@ -162,6 +162,7 @@ static av_cold int avs_decode_init(AVCodecContext * avctx) AvsContext *const avs = avctx->priv_data; avctx->pix_fmt = PIX_FMT_PAL8; avcodec_get_frame_defaults(&avs->picture); + avcodec_set_dimensions(avctx, 318, 198); return 0; } diff --git a/libavcodec/bink.c b/libavcodec/bink.c index 39c94a088c..71b7d5fdc2 100644 --- a/libavcodec/bink.c +++ b/libavcodec/bink.c @@ -167,7 +167,7 @@ static void init_lengths(BinkContext *c, int width, int bw) * * @param c decoder context */ -static av_cold void init_bundles(BinkContext *c) +static av_cold int init_bundles(BinkContext *c) { int bw, bh, blocks; int i; @@ -178,8 +178,12 @@ static av_cold void init_bundles(BinkContext *c) for (i = 0; i < BINKB_NB_SRC; i++) { c->bundle[i].data = av_malloc(blocks * 64); + if (!c->bundle[i].data) + return AVERROR(ENOMEM); c->bundle[i].data_end = c->bundle[i].data + blocks * 64; } + + return 0; } /** @@ -675,6 +679,9 @@ static int read_dct_coeffs(GetBitContext *gb, int32_t block[64], const uint8_t * quant_idx = q; } + if (quant_idx >= 16) + return AVERROR_INVALIDDATA; + quant = quant_matrices[quant_idx]; block[0] = (block[0] * quant[0]) >> 11; @@ -1266,7 +1273,7 @@ static av_cold int decode_init(AVCodecContext *avctx) BinkContext * const c = avctx->priv_data; static VLC_TYPE table[16 * 128][2]; static int binkb_initialised = 0; - int i; + int i, ret; int flags; c->version = avctx->codec_tag >> 24; @@ -1301,7 +1308,10 @@ static av_cold int decode_init(AVCodecContext *avctx) dsputil_init(&c->dsp, avctx); ff_binkdsp_init(&c->bdsp); - init_bundles(c); + if ((ret = init_bundles(c)) < 0) { + free_bundles(c); + return ret; + } if (c->version == 'b') { if (!binkb_initialised) { diff --git a/libavcodec/binkaudio.c b/libavcodec/binkaudio.c index 9f51c7a856..778b815f4b 100644 --- a/libavcodec/binkaudio.c +++ b/libavcodec/binkaudio.c @@ -29,6 +29,7 @@ */ #include "avcodec.h" +#include "internal.h" #define BITSTREAM_READER_LE #include "get_bits.h" #include "dsputil.h" @@ -91,9 +92,9 @@ static av_cold int decode_init(AVCodecContext *avctx) frame_len_bits = 11; } - if (avctx->channels > MAX_CHANNELS) { - av_log(avctx, AV_LOG_ERROR, "too many channels: %d\n", avctx->channels); - return -1; + if (avctx->channels < 1 || avctx->channels > MAX_CHANNELS) { + av_log(avctx, AV_LOG_ERROR, "invalid number of channels: %d\n", avctx->channels); + return AVERROR_INVALIDDATA; } s->version_b = avctx->extradata && avctx->extradata[3] == 'b'; @@ -340,7 +341,7 @@ static int decode_frame(AVCodecContext *avctx, void *data, /* get output buffer */ s->frame.nb_samples = s->block_size / avctx->channels; - if ((ret = avctx->get_buffer(avctx, &s->frame)) < 0) { + if ((ret = ff_get_buffer(avctx, &s->frame)) < 0) { av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n"); return ret; } diff --git a/libavcodec/bitstream.c b/libavcodec/bitstream.c index 30aaf75fea..6d07c88c07 100644 --- a/libavcodec/bitstream.c +++ b/libavcodec/bitstream.c @@ -253,9 +253,9 @@ static int build_table(VLC *vlc, int table_nb_bits, int nb_codes, (byte/word/long) to store the 'bits', 'codes', and 'symbols' tables. 'use_static' should be set to 1 for tables, which should be freed - with av_free_static(), 0 if free_vlc() will be used. + with av_free_static(), 0 if ff_free_vlc() will be used. */ -int init_vlc_sparse(VLC *vlc, int nb_bits, int nb_codes, +int ff_init_vlc_sparse(VLC *vlc, int nb_bits, int nb_codes, const void *bits, int bits_wrap, int bits_size, const void *codes, int codes_wrap, int codes_size, const void *symbols, int symbols_wrap, int symbols_size, @@ -318,7 +318,7 @@ int init_vlc_sparse(VLC *vlc, int nb_bits, int nb_codes, } -void free_vlc(VLC *vlc) +void ff_free_vlc(VLC *vlc) { av_freep(&vlc->table); } diff --git a/libavcodec/bmp.c b/libavcodec/bmp.c index b7853d1093..af3c381446 100644 --- a/libavcodec/bmp.c +++ b/libavcodec/bmp.c @@ -53,6 +53,7 @@ static int bmp_decode_frame(AVCodecContext *avctx, uint8_t *ptr; int dsize; const uint8_t *buf0 = buf; + GetByteContext gb; if(buf_size < 14){ av_log(avctx, AV_LOG_ERROR, "buf size too small (%d)\n", buf_size); @@ -117,7 +118,7 @@ static int bmp_decode_frame(AVCodecContext *avctx, depth = bytestream_get_le16(&buf); - if(ihsize == 40 || ihsize == 64 || ihsize == 56) + if (ihsize >= 40) comp = bytestream_get_le32(&buf); else comp = BMP_RGB; @@ -132,8 +133,7 @@ static int bmp_decode_frame(AVCodecContext *avctx, rgb[0] = bytestream_get_le32(&buf); rgb[1] = bytestream_get_le32(&buf); rgb[2] = bytestream_get_le32(&buf); - if (ihsize >= 108) - alpha = bytestream_get_le32(&buf); + alpha = bytestream_get_le32(&buf); } avctx->width = width; @@ -231,9 +231,6 @@ static int bmp_decode_frame(AVCodecContext *avctx, if(comp == BMP_RLE4 || comp == BMP_RLE8) memset(p->data[0], 0, avctx->height * p->linesize[0]); - if(depth == 4 || depth == 8) - memset(p->data[1], 0, 1024); - if(height > 0){ ptr = p->data[0] + (avctx->height - 1) * p->linesize[0]; linesize = -p->linesize[0]; @@ -244,6 +241,9 @@ static int bmp_decode_frame(AVCodecContext *avctx, if(avctx->pix_fmt == PIX_FMT_PAL8){ int colors = 1 << depth; + + memset(p->data[1], 0, 1024); + if(ihsize >= 36){ int t; buf = buf0 + 46; @@ -269,7 +269,8 @@ static int bmp_decode_frame(AVCodecContext *avctx, p->data[0] += p->linesize[0] * (avctx->height - 1); p->linesize[0] = -p->linesize[0]; } - ff_msrle_decode(avctx, (AVPicture*)p, depth, buf, dsize); + bytestream2_init(&gb, buf, dsize); + ff_msrle_decode(avctx, (AVPicture*)p, depth, &gb); if(height < 0){ p->data[0] += p->linesize[0] * (avctx->height - 1); p->linesize[0] = -p->linesize[0]; diff --git a/libavcodec/bmv.c b/libavcodec/bmv.c index 37c844858f..0104f4563a 100644 --- a/libavcodec/bmv.c +++ b/libavcodec/bmv.c @@ -20,7 +20,9 @@ */ #include "avcodec.h" +#include "internal.h" #include "bytestream.h" +#include "libavutil/avassert.h" enum BMVFlags{ BMV_NOP = 0, @@ -52,7 +54,7 @@ typedef struct BMVDecContext { static int decode_bmv_frame(const uint8_t *source, int src_len, uint8_t *frame, int frame_off) { - int val, saved_val = 0; + unsigned val, saved_val = 0; int tmplen = src_len; const uint8_t *src, *source_end = source + src_len; uint8_t *frame_end = frame + SCREEN_WIDE * SCREEN_HIGH; @@ -98,6 +100,8 @@ static int decode_bmv_frame(const uint8_t *source, int src_len, uint8_t *frame, } if (!(val & 0xC)) { for (;;) { + if(shift>22) + return -1; if (!read_two_nibbles) { if (src < source || src >= source_end) return -1; @@ -131,15 +135,16 @@ static int decode_bmv_frame(const uint8_t *source, int src_len, uint8_t *frame, } advance_mode = val & 1; len = (val >> 1) - 1; + av_assert0(len>0); mode += 1 + advance_mode; if (mode >= 4) mode -= 3; - if (FFABS(dst_end - dst) < len) + if (len <= 0 || FFABS(dst_end - dst) < len) return -1; switch (mode) { case 1: if (forward) { - if (dst - frame + SCREEN_WIDE < frame_off || + if (dst - frame + SCREEN_WIDE < -frame_off || frame_end - dst < frame_off + len) return -1; for (i = 0; i < len; i++) @@ -147,7 +152,7 @@ static int decode_bmv_frame(const uint8_t *source, int src_len, uint8_t *frame, dst += len; } else { dst -= len; - if (dst - frame + SCREEN_WIDE < frame_off || + if (dst - frame + SCREEN_WIDE < -frame_off || frame_end - dst < frame_off + len) return -1; for (i = len - 1; i >= 0; i--) @@ -264,8 +269,13 @@ static av_cold int decode_init(AVCodecContext *avctx) c->avctx = avctx; avctx->pix_fmt = PIX_FMT_PAL8; + if (avctx->width != SCREEN_WIDE || avctx->height != SCREEN_HIGH) { + av_log(avctx, AV_LOG_ERROR, "Invalid dimension %dx%d\n", avctx->width, avctx->height); + return AVERROR_INVALIDDATA; + } + c->pic.reference = 1; - if (avctx->get_buffer(avctx, &c->pic) < 0) { + if (ff_get_buffer(avctx, &c->pic) < 0) { av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n"); return -1; } @@ -330,7 +340,7 @@ static int bmv_aud_decode_frame(AVCodecContext *avctx, void *data, /* get output buffer */ c->frame.nb_samples = total_blocks * 32; - if ((ret = avctx->get_buffer(avctx, &c->frame)) < 0) { + if ((ret = ff_get_buffer(avctx, &c->frame)) < 0) { av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n"); return ret; } diff --git a/libavcodec/bytestream.h b/libavcodec/bytestream.h index 71c70aac84..857e050ea2 100644 --- a/libavcodec/bytestream.h +++ b/libavcodec/bytestream.h @@ -1,6 +1,7 @@ /* * Bytestream functions * copyright (c) 2006 Baptiste Coudurier + * Copyright (c) 2012 Aneesh Dogra (lionaneesh) * * This file is part of FFmpeg. * @@ -23,6 +24,7 @@ #define AVCODEC_BYTESTREAM_H #include + #include "libavutil/common.h" #include "libavutil/intreadwrite.h" @@ -30,35 +32,57 @@ typedef struct { const uint8_t *buffer, *buffer_end, *buffer_start; } GetByteContext; -#define DEF_T(type, name, bytes, read, write) \ -static av_always_inline type bytestream_get_ ## name(const uint8_t **b){\ - (*b) += bytes;\ - return read(*b - bytes);\ -}\ -static av_always_inline void bytestream_put_ ##name(uint8_t **b, const type value){\ - write(*b, value);\ - (*b) += bytes;\ -}\ -static av_always_inline type bytestream2_get_ ## name ## u(GetByteContext *g)\ -{\ - return bytestream_get_ ## name(&g->buffer);\ -}\ -static av_always_inline type bytestream2_get_ ## name(GetByteContext *g)\ -{\ - if (g->buffer_end - g->buffer < bytes)\ - return 0;\ - return bytestream2_get_ ## name ## u(g);\ -}\ -static av_always_inline type bytestream2_peek_ ## name(GetByteContext *g)\ -{\ - if (g->buffer_end - g->buffer < bytes)\ - return 0;\ - return read(g->buffer);\ +typedef struct { + uint8_t *buffer, *buffer_end, *buffer_start; + int eof; +} PutByteContext; + +#define DEF_T(type, name, bytes, read, write) \ +static av_always_inline type bytestream_get_ ## name(const uint8_t **b) \ +{ \ + (*b) += bytes; \ + return read(*b - bytes); \ +} \ +static av_always_inline void bytestream_put_ ## name(uint8_t **b, \ + const type value) \ +{ \ + write(*b, value); \ + (*b) += bytes; \ +} \ +static av_always_inline void bytestream2_put_ ## name ## u(PutByteContext *p, \ + const type value) \ +{ \ + bytestream_put_ ## name(&p->buffer, value); \ +} \ +static av_always_inline void bytestream2_put_ ## name(PutByteContext *p, \ + const type value) \ +{ \ + if (!p->eof && (p->buffer_end - p->buffer >= bytes)) { \ + write(p->buffer, value); \ + p->buffer += bytes; \ + } else \ + p->eof = 1; \ +} \ +static av_always_inline type bytestream2_get_ ## name ## u(GetByteContext *g) \ +{ \ + return bytestream_get_ ## name(&g->buffer); \ +} \ +static av_always_inline type bytestream2_get_ ## name(GetByteContext *g) \ +{ \ + if (g->buffer_end - g->buffer < bytes) \ + return 0; \ + return bytestream2_get_ ## name ## u(g); \ +} \ +static av_always_inline type bytestream2_peek_ ## name(GetByteContext *g) \ +{ \ + if (g->buffer_end - g->buffer < bytes) \ + return 0; \ + return read(g->buffer); \ } -#define DEF(name, bytes, read, write) \ +#define DEF(name, bytes, read, write) \ DEF_T(unsigned int, name, bytes, read, write) -#define DEF64(name, bytes, read, write) \ +#define DEF64(name, bytes, read, write) \ DEF_T(uint64_t, name, bytes, read, write) DEF64(le64, 8, AV_RL64, AV_WL64) @@ -112,11 +136,22 @@ DEF (byte, 1, AV_RB8 , AV_WB8 ) #endif static av_always_inline void bytestream2_init(GetByteContext *g, - const uint8_t *buf, int buf_size) + const uint8_t *buf, + int buf_size) { - g->buffer = buf; + g->buffer = buf; g->buffer_start = buf; - g->buffer_end = buf + buf_size; + g->buffer_end = buf + buf_size; +} + +static av_always_inline void bytestream2_init_writer(PutByteContext *p, + uint8_t *buf, + int buf_size) +{ + p->buffer = buf; + p->buffer_start = buf; + p->buffer_end = buf + buf_size; + p->eof = 0; } static av_always_inline unsigned int bytestream2_get_bytes_left(GetByteContext *g) @@ -124,32 +159,71 @@ static av_always_inline unsigned int bytestream2_get_bytes_left(GetByteContext * return g->buffer_end - g->buffer; } +static av_always_inline unsigned int bytestream2_get_bytes_left_p(PutByteContext *p) +{ + return p->buffer_end - p->buffer; +} + static av_always_inline void bytestream2_skip(GetByteContext *g, unsigned int size) { g->buffer += FFMIN(g->buffer_end - g->buffer, size); } +static av_always_inline void bytestream2_skipu(GetByteContext *g, + unsigned int size) +{ + g->buffer += size; +} + +static av_always_inline void bytestream2_skip_p(PutByteContext *p, + unsigned int size) +{ + int size2; + if (p->eof) + return; + size2 = FFMIN(p->buffer_end - p->buffer, size); + if (size2 != size) + p->eof = 1; + p->buffer += size2; +} + static av_always_inline int bytestream2_tell(GetByteContext *g) { return (int)(g->buffer - g->buffer_start); } -static av_always_inline int bytestream2_seek(GetByteContext *g, int offset, +static av_always_inline int bytestream2_tell_p(PutByteContext *p) +{ + return (int)(p->buffer - p->buffer_start); +} + +static av_always_inline int bytestream2_size(GetByteContext *g) +{ + return (int)(g->buffer_end - g->buffer_start); +} + +static av_always_inline int bytestream2_size_p(PutByteContext *p) +{ + return (int)(p->buffer_end - p->buffer_start); +} + +static av_always_inline int bytestream2_seek(GetByteContext *g, + int offset, int whence) { switch (whence) { case SEEK_CUR: - offset = av_clip(offset, -(g->buffer - g->buffer_start), - g->buffer_end - g->buffer); + offset = av_clip(offset, -(g->buffer - g->buffer_start), + g->buffer_end - g->buffer); g->buffer += offset; break; case SEEK_END: - offset = av_clip(offset, -(g->buffer_end - g->buffer_start), 0); + offset = av_clip(offset, -(g->buffer_end - g->buffer_start), 0); g->buffer = g->buffer_end + offset; break; case SEEK_SET: - offset = av_clip(offset, 0, g->buffer_end - g->buffer_start); + offset = av_clip(offset, 0, g->buffer_end - g->buffer_start); g->buffer = g->buffer_start + offset; break; default: @@ -158,6 +232,37 @@ static av_always_inline int bytestream2_seek(GetByteContext *g, int offset, return bytestream2_tell(g); } +static av_always_inline int bytestream2_seek_p(PutByteContext *p, + int offset, + int whence) +{ + p->eof = 0; + switch (whence) { + case SEEK_CUR: + if (p->buffer_end - p->buffer < offset) + p->eof = 1; + offset = av_clip(offset, -(p->buffer - p->buffer_start), + p->buffer_end - p->buffer); + p->buffer += offset; + break; + case SEEK_END: + if (offset > 0) + p->eof = 1; + offset = av_clip(offset, -(p->buffer_end - p->buffer_start), 0); + p->buffer = p->buffer_end + offset; + break; + case SEEK_SET: + if (p->buffer_end - p->buffer_start < offset) + p->eof = 1; + offset = av_clip(offset, 0, p->buffer_end - p->buffer_start); + p->buffer = p->buffer_start + offset; + break; + default: + return AVERROR(EINVAL); + } + return bytestream2_tell_p(p); +} + static av_always_inline unsigned int bytestream2_get_buffer(GetByteContext *g, uint8_t *dst, unsigned int size) @@ -168,14 +273,104 @@ static av_always_inline unsigned int bytestream2_get_buffer(GetByteContext *g, return size2; } -static av_always_inline unsigned int bytestream_get_buffer(const uint8_t **b, uint8_t *dst, unsigned int size) +static av_always_inline unsigned int bytestream2_get_bufferu(GetByteContext *g, + uint8_t *dst, + unsigned int size) +{ + memcpy(dst, g->buffer, size); + g->buffer += size; + return size; +} + +static av_always_inline unsigned int bytestream2_put_buffer(PutByteContext *p, + const uint8_t *src, + unsigned int size) +{ + int size2; + if (p->eof) + return 0; + size2 = FFMIN(p->buffer_end - p->buffer, size); + if (size2 != size) + p->eof = 1; + memcpy(p->buffer, src, size2); + p->buffer += size2; + return size2; +} + +static av_always_inline unsigned int bytestream2_put_bufferu(PutByteContext *p, + const uint8_t *src, + unsigned int size) +{ + memcpy(p->buffer, src, size); + p->buffer += size; + return size; +} + +static av_always_inline void bytestream2_set_buffer(PutByteContext *p, + const uint8_t c, + unsigned int size) +{ + int size2; + if (p->eof) + return; + size2 = FFMIN(p->buffer_end - p->buffer, size); + if (size2 != size) + p->eof = 1; + memset(p->buffer, c, size2); + p->buffer += size2; +} + +static av_always_inline void bytestream2_set_bufferu(PutByteContext *p, + const uint8_t c, + unsigned int size) +{ + memset(p->buffer, c, size); + p->buffer += size; +} + +static av_always_inline unsigned int bytestream2_get_eof(PutByteContext *p) +{ + return p->eof; +} + +static av_always_inline unsigned int bytestream2_copy_bufferu(PutByteContext *p, + GetByteContext *g, + unsigned int size) +{ + memcpy(p->buffer, g->buffer, size); + p->buffer += size; + g->buffer += size; + return size; +} + +static av_always_inline unsigned int bytestream2_copy_buffer(PutByteContext *p, + GetByteContext *g, + unsigned int size) +{ + int size2; + + if (p->eof) + return 0; + size = FFMIN(g->buffer_end - g->buffer, size); + size2 = FFMIN(p->buffer_end - p->buffer, size); + if (size2 != size) + p->eof = 1; + + return bytestream2_copy_bufferu(p, g, size2); +} + +static av_always_inline unsigned int bytestream_get_buffer(const uint8_t **b, + uint8_t *dst, + unsigned int size) { memcpy(dst, *b, size); (*b) += size; return size; } -static av_always_inline void bytestream_put_buffer(uint8_t **b, const uint8_t *src, unsigned int size) +static av_always_inline void bytestream_put_buffer(uint8_t **b, + const uint8_t *src, + unsigned int size) { memcpy(*b, src, size); (*b) += size; diff --git a/libavcodec/cavsdec.c b/libavcodec/cavsdec.c index 16e5474d84..a23deb234b 100644 --- a/libavcodec/cavsdec.c +++ b/libavcodec/cavsdec.c @@ -166,8 +166,8 @@ static inline int decode_residual_inter(AVSContext *h) { /* get coded block pattern */ int cbp= get_ue_golomb(&h->s.gb); - if(cbp > 63U){ - av_log(h->s.avctx, AV_LOG_ERROR, "illegal inter cbp\n"); + if(cbp > 63 || cbp < 0){ + av_log(h->s.avctx, AV_LOG_ERROR, "illegal inter cbp %d\n", cbp); return -1; } h->cbp = cbp_tab[cbp][1]; @@ -226,7 +226,7 @@ static int decode_mb_i(AVSContext *h, int cbp_code) { /* get coded block pattern */ if(h->pic_type == AV_PICTURE_TYPE_I) cbp_code = get_ue_golomb(gb); - if(cbp_code > 63U){ + if(cbp_code > 63 || cbp_code < 0 ){ av_log(h->s.avctx, AV_LOG_ERROR, "illegal intra cbp\n"); return -1; } @@ -468,6 +468,11 @@ static int decode_pic(AVSContext *h) { int skip_count = -1; enum cavs_mb mb_type; + if (!h->top_qp) { + av_log(h, AV_LOG_ERROR, "No sequence header decoded yet\n"); + return AVERROR_INVALIDDATA; + } + if (!s->context_initialized) { s->avctx->idct_algo = FF_IDCT_CAVS; if (MPV_common_init(s) < 0) @@ -609,12 +614,21 @@ static int decode_pic(AVSContext *h) { static int decode_seq_header(AVSContext *h) { MpegEncContext *s = &h->s; int frame_rate_code; + int width, height; h->profile = get_bits(&s->gb,8); h->level = get_bits(&s->gb,8); skip_bits1(&s->gb); //progressive sequence - s->width = get_bits(&s->gb,14); - s->height = get_bits(&s->gb,14); + + width = get_bits(&s->gb, 14); + height = get_bits(&s->gb, 14); + if ((s->width || s->height) && (s->width != width || s->height != height)) { + av_log_missing_feature(s, "Width/height changing in CAVS is", 0); + return AVERROR_PATCHWELCOME; + } + s->width = width; + s->height = height; + skip_bits(&s->gb,2); //chroma format skip_bits(&s->gb,3); //sample_precision h->aspect_ratio = get_bits(&s->gb,4); @@ -656,7 +670,8 @@ static int cavs_decode_frame(AVCodecContext * avctx,void *data, int *data_size, if (buf_size == 0) { if (!s->low_delay && h->DPB[0].f.data[0]) { *data_size = sizeof(AVPicture); - *picture = *(AVFrame *) &h->DPB[0]; + *picture = h->DPB[0].f; + memset(&h->DPB[0], 0, sizeof(h->DPB[0])); } return 0; } diff --git a/libavcodec/cdgraphics.c b/libavcodec/cdgraphics.c index b87ca1d2c3..1b5721533a 100644 --- a/libavcodec/cdgraphics.c +++ b/libavcodec/cdgraphics.c @@ -20,6 +20,7 @@ */ #include "avcodec.h" +#include "internal.h" #include "bytestream.h" /** @@ -268,7 +269,7 @@ static void cdg_scroll(CDGraphicsContext *cc, uint8_t *data, static int cdg_decode_frame(AVCodecContext *avctx, void *data, int *data_size, AVPacket *avpkt) { - const uint8_t *buf = avpkt->data; + GetByteContext gb; int buf_size = avpkt->size; int ret; uint8_t command, inst; @@ -280,6 +281,12 @@ static int cdg_decode_frame(AVCodecContext *avctx, av_log(avctx, AV_LOG_ERROR, "buffer too small for decoder\n"); return AVERROR(EINVAL); } + if (buf_size > CDG_HEADER_SIZE + CDG_DATA_SIZE) { + av_log(avctx, AV_LOG_ERROR, "buffer too big for decoder\n"); + return AVERROR(EINVAL); + } + + bytestream2_init(&gb, avpkt->data, avpkt->size); ret = avctx->reget_buffer(avctx, &cc->frame); if (ret) { @@ -287,11 +294,11 @@ static int cdg_decode_frame(AVCodecContext *avctx, return ret; } - command = bytestream_get_byte(&buf); - inst = bytestream_get_byte(&buf); + command = bytestream2_get_byte(&gb); + inst = bytestream2_get_byte(&gb); inst &= CDG_MASK; - buf += 2; /// skipping 2 unneeded bytes - bytestream_get_buffer(&buf, cdg_data, buf_size - CDG_HEADER_SIZE); + bytestream2_skip(&gb, 2); + bytestream2_get_buffer(&gb, cdg_data, sizeof(cdg_data)); if ((command & CDG_MASK) == CDG_COMMAND) { switch (inst) { @@ -333,7 +340,7 @@ static int cdg_decode_frame(AVCodecContext *avctx, } cdg_init_frame(&new_frame); - ret = avctx->get_buffer(avctx, &new_frame); + ret = ff_get_buffer(avctx, &new_frame); if (ret) { av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n"); return ret; @@ -350,11 +357,10 @@ static int cdg_decode_frame(AVCodecContext *avctx, *data_size = sizeof(AVFrame); } else { *data_size = 0; - buf_size = 0; } *(AVFrame *) data = cc->frame; - return buf_size; + return avpkt->size; } static av_cold int cdg_decode_end(AVCodecContext *avctx) diff --git a/libavcodec/celp_filters.c b/libavcodec/celp_filters.c index 1535060c9d..04ede491ac 100644 --- a/libavcodec/celp_filters.c +++ b/libavcodec/celp_filters.c @@ -133,9 +133,8 @@ void ff_celp_lp_synthesis_filterf(float *out, const float *filter_coeffs, out2 -= val * old_out2; out3 -= val * old_out3; - old_out3 = out[-5]; - for (i = 5; i <= filter_length; i += 2) { + old_out3 = out[-i]; val = filter_coeffs[i-1]; out0 -= val * old_out3; @@ -154,7 +153,6 @@ void ff_celp_lp_synthesis_filterf(float *out, const float *filter_coeffs, FFSWAP(float, old_out0, old_out2); old_out1 = old_out3; - old_out3 = out[-i-2]; } tmp0 = out0; diff --git a/libavcodec/cook.c b/libavcodec/cook.c index e161b1a1bc..f6948a3e94 100644 --- a/libavcodec/cook.c +++ b/libavcodec/cook.c @@ -44,6 +44,7 @@ #include "libavutil/lfg.h" #include "avcodec.h" +#include "internal.h" #include "get_bits.h" #include "dsputil.h" #include "bytestream.h" @@ -321,11 +322,11 @@ static av_cold int cook_decode_close(AVCodecContext *avctx) /* Free the VLC tables. */ for (i = 0; i < 13; i++) - free_vlc(&q->envelope_quant_index[i]); + ff_free_vlc(&q->envelope_quant_index[i]); for (i = 0; i < 7; i++) - free_vlc(&q->sqvh[i]); + ff_free_vlc(&q->sqvh[i]); for (i = 0; i < q->num_subpackets; i++) - free_vlc(&q->subpacket[i].ccpl); + ff_free_vlc(&q->subpacket[i].ccpl); av_log(avctx, AV_LOG_DEBUG, "Memory deallocated.\n"); @@ -366,8 +367,8 @@ static void decode_gain_info(GetBitContext *gb, int *gaininfo) * @param q pointer to the COOKContext * @param quant_index_table pointer to the array */ -static void decode_envelope(COOKContext *q, COOKSubpacket *p, - int *quant_index_table) +static int decode_envelope(COOKContext *q, COOKSubpacket *p, + int *quant_index_table) { int i, j, vlc_index; @@ -388,7 +389,15 @@ static void decode_envelope(COOKContext *q, COOKSubpacket *p, j = get_vlc2(&q->gb, q->envelope_quant_index[vlc_index - 1].table, q->envelope_quant_index[vlc_index - 1].bits, 2); quant_index_table[i] = quant_index_table[i - 1] + j - 12; // differential encoding + if (quant_index_table[i] > 63 || quant_index_table[i] < -63) { + av_log(q->avctx, AV_LOG_ERROR, + "Invalid quantizer %d at position %d, outside [-63, 63] range\n", + quant_index_table[i], i); + return AVERROR_INVALIDDATA; + } } + + return 0; } /** @@ -507,7 +516,11 @@ static inline void expand_category(COOKContext *q, int *category, { int i; for (i = 0; i < q->num_vectors; i++) - ++category[category_index[i]]; + { + int idx = category_index[i]; + if (++category[idx] >= FF_ARRAY_ELEMS(dither_tab)) + --category[idx]; + } } /** @@ -635,20 +648,24 @@ static void decode_vectors(COOKContext *q, COOKSubpacket *p, int *category, * @param q pointer to the COOKContext * @param mlt_buffer pointer to mlt coefficients */ -static void mono_decode(COOKContext *q, COOKSubpacket *p, float *mlt_buffer) +static int mono_decode(COOKContext *q, COOKSubpacket *p, float *mlt_buffer) { int category_index[128]; int quant_index_table[102]; int category[128]; + int res; memset(&category, 0, sizeof(category)); memset(&category_index, 0, sizeof(category_index)); - decode_envelope(q, p, quant_index_table); + if ((res = decode_envelope(q, p, quant_index_table)) < 0) + return res; q->num_vectors = get_bits(&q->gb, p->log2_numvector_size); categorize(q, p, quant_index_table, category, category_index); expand_category(q, category, category_index); decode_vectors(q, p, category, quant_index_table, mlt_buffer); + + return 0; } @@ -798,10 +815,10 @@ static void decouple_float(COOKContext *q, * @param mlt_buffer1 pointer to left channel mlt coefficients * @param mlt_buffer2 pointer to right channel mlt coefficients */ -static void joint_decode(COOKContext *q, COOKSubpacket *p, float *mlt_buffer1, - float *mlt_buffer2) +static int joint_decode(COOKContext *q, COOKSubpacket *p, float *mlt_buffer1, + float *mlt_buffer2) { - int i, j; + int i, j, res; int decouple_tab[SUBBAND_SIZE]; float *decode_buffer = q->decode_buffer_0; int idx, cpl_tmp; @@ -815,7 +832,8 @@ static void joint_decode(COOKContext *q, COOKSubpacket *p, float *mlt_buffer1, memset(mlt_buffer1, 0, 1024 * sizeof(*mlt_buffer1)); memset(mlt_buffer2, 0, 1024 * sizeof(*mlt_buffer2)); decouple_info(q, p, decouple_tab); - mono_decode(q, p, decode_buffer); + if ((res = mono_decode(q, p, decode_buffer)) < 0) + return res; /* The two channels are stored interleaved in decode_buffer. */ for (i = 0; i < p->js_subband_start; i++) { @@ -832,11 +850,13 @@ static void joint_decode(COOKContext *q, COOKSubpacket *p, float *mlt_buffer1, cpl_tmp = cplband[i]; idx -= decouple_tab[cpl_tmp]; cplscale = q->cplscales[p->js_vlc_bits - 2]; // choose decoupler table - f1 = cplscale[decouple_tab[cpl_tmp]]; - f2 = cplscale[idx - 1]; + f1 = cplscale[decouple_tab[cpl_tmp] + 1]; + f2 = cplscale[idx]; q->decouple(q, p, i, f1, f2, decode_buffer, mlt_buffer1, mlt_buffer2); idx = (1 << p->js_vlc_bits) - 1; } + + return 0; } /** @@ -909,10 +929,11 @@ static inline void mlt_compensate_output(COOKContext *q, float *decode_buffer, * @param inbuffer pointer to the inbuffer * @param outbuffer pointer to the outbuffer */ -static void decode_subpacket(COOKContext *q, COOKSubpacket *p, - const uint8_t *inbuffer, float *outbuffer) +static int decode_subpacket(COOKContext *q, COOKSubpacket *p, + const uint8_t *inbuffer, float *outbuffer) { int sub_packet_size = p->size; + int res; /* packet dump */ // for (i = 0; i < sub_packet_size ; i++) // av_log(q->avctx, AV_LOG_ERROR, "%02x", inbuffer[i]); @@ -921,13 +942,16 @@ static void decode_subpacket(COOKContext *q, COOKSubpacket *p, decode_bytes_and_gain(q, p, inbuffer, &p->gains1); if (p->joint_stereo) { - joint_decode(q, p, q->decode_buffer_1, q->decode_buffer_2); + if ((res = joint_decode(q, p, q->decode_buffer_1, q->decode_buffer_2)) < 0) + return res; } else { - mono_decode(q, p, q->decode_buffer_1); + if ((res = mono_decode(q, p, q->decode_buffer_1)) < 0) + return res; if (p->num_channels == 2) { decode_bytes_and_gain(q, p, inbuffer + sub_packet_size / 2, &p->gains2); - mono_decode(q, p, q->decode_buffer_2); + if ((res = mono_decode(q, p, q->decode_buffer_2)) < 0) + return res; } } @@ -941,6 +965,8 @@ static void decode_subpacket(COOKContext *q, COOKSubpacket *p, else mlt_compensate_output(q, q->decode_buffer_2, &p->gains2, p->mono_previous_buffer2, outbuffer, p->ch_idx + 1); + + return 0; } @@ -966,7 +992,7 @@ static int cook_decode_frame(AVCodecContext *avctx, void *data, /* get output buffer */ if (q->discarded_packets >= 2) { q->frame.nb_samples = q->samples_per_channel; - if ((ret = avctx->get_buffer(avctx, &q->frame)) < 0) { + if ((ret = ff_get_buffer(avctx, &q->frame)) < 0) { av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n"); return ret; } @@ -996,7 +1022,8 @@ static int cook_decode_frame(AVCodecContext *avctx, void *data, i, q->subpacket[i].size, q->subpacket[i].joint_stereo, offset, avctx->block_align); - decode_subpacket(q, &q->subpacket[i], buf + offset, samples); + if ((ret = decode_subpacket(q, &q->subpacket[i], buf + offset, samples)) < 0) + return ret; offset += q->subpacket[i].size; chidx += q->subpacket[i].num_channels; av_log(avctx, AV_LOG_DEBUG, "subpacket[%i] %i %i\n", @@ -1078,6 +1105,10 @@ static av_cold int cook_decode_init(AVCodecContext *avctx) q->sample_rate = avctx->sample_rate; q->nb_channels = avctx->channels; q->bit_rate = avctx->bit_rate; + if (!q->nb_channels) { + av_log(avctx, AV_LOG_ERROR, "Invalid number of channels\n"); + return AVERROR_INVALIDDATA; + } /* Initialize RNG. */ av_lfg_init(&q->random_state, 0); @@ -1205,6 +1236,11 @@ static av_cold int cook_decode_init(AVCodecContext *avctx) q->subpacket[s].gains2.now = q->subpacket[s].gain_3; q->subpacket[s].gains2.previous = q->subpacket[s].gain_4; + if (q->num_subpackets + q->subpacket[s].num_channels > q->nb_channels) { + av_log(avctx, AV_LOG_ERROR, "Too many subpackets %d for channels %d\n", q->num_subpackets, q->nb_channels); + return AVERROR_INVALIDDATA; + } + q->num_subpackets++; s++; if (s > MAX_SUBPACKETS) { diff --git a/libavcodec/cookdata.h b/libavcodec/cookdata.h index 15e8e9519f..7b9cba3c11 100644 --- a/libavcodec/cookdata.h +++ b/libavcodec/cookdata.h @@ -36,8 +36,8 @@ static const int expbits_tab[8] = { 52,47,43,37,29,22,16,0, }; -static const float dither_tab[8] = { - 0.0, 0.0, 0.0, 0.0, 0.0, 0.176777, 0.25, 0.707107, +static const float dither_tab[9] = { + 0.0, 0.0, 0.0, 0.0, 0.0, 0.176777, 0.25, 0.707107, 1.0 }; static const float quant_centroid_tab[7][14] = { @@ -510,23 +510,37 @@ static const int cplband[51] = { 19, }; -static const float cplscale2[3] = { +// The 1 and 0 at the beginning/end are to prevent overflows with +// bitstream-read indexes. E.g. if n_bits=5, we can access any +// index from [1, (1<bits_per_coded_sample); - return 1; + return AVERROR_INVALIDDATA; } c->bpp = avctx->bits_per_coded_sample; avcodec_get_frame_defaults(&c->pic); @@ -242,7 +242,7 @@ static av_cold int decode_init(AVCodecContext *avctx) { c->decomp_buf = av_malloc(c->decomp_size + AV_LZO_OUTPUT_PADDING); if (!c->decomp_buf) { av_log(avctx, AV_LOG_ERROR, "Can't allocate decompression buffer.\n"); - return 1; + return AVERROR(ENOMEM); } return 0; } diff --git a/libavcodec/dca.c b/libavcodec/dca.c index cf61a16bb9..434b889782 100644 --- a/libavcodec/dca.c +++ b/libavcodec/dca.c @@ -29,8 +29,10 @@ #include "libavutil/common.h" #include "libavutil/intmath.h" #include "libavutil/intreadwrite.h" +#include "libavutil/mathematics.h" #include "libavutil/audioconvert.h" #include "avcodec.h" +#include "internal.h" #include "dsputil.h" #include "fft.h" #include "get_bits.h" @@ -576,6 +578,11 @@ static int dca_parse_frame_header(DCAContext *s) s->lfe = get_bits(&s->gb, 2); s->predictor_history = get_bits(&s->gb, 1); + if (s->lfe > 2) { + av_log(s->avctx, AV_LOG_ERROR, "Invalid LFE value: %d\n", s->lfe); + return AVERROR_INVALIDDATA; + } + /* TODO: check CRC */ if (s->crc_present) s->header_crc = get_bits(&s->gb, 16); @@ -638,13 +645,20 @@ static int dca_parse_frame_header(DCAContext *s) } -static inline int get_scale(GetBitContext *gb, int level, int value) +static inline int get_scale(GetBitContext *gb, int level, int value, int log2range) { if (level < 5) { /* huffman encoded */ value += get_bitalloc(gb, &dca_scalefactor, level); - } else if (level < 8) - value = get_bits(gb, level + 1); + value = av_clip(value, 0, (1 << log2range) - 1); + } else if (level < 8) { + if (level + 1 > log2range) { + skip_bits(gb, level + 1 - log2range); + value = get_bits(gb, log2range); + } else { + value = get_bits(gb, level + 1); + } + } return value; } @@ -717,28 +731,31 @@ static int dca_subframe_header(DCAContext *s, int base_channel, int block_index) for (j = base_channel; j < s->prim_channels; j++) { const uint32_t *scale_table; - int scale_sum; + int scale_sum, log_size; memset(s->scale_factor[j], 0, s->subband_activity[j] * sizeof(s->scale_factor[0][0][0]) * 2); - if (s->scalefactor_huffman[j] == 6) + if (s->scalefactor_huffman[j] == 6) { scale_table = scale_factor_quant7; - else + log_size = 7; + } else { scale_table = scale_factor_quant6; + log_size = 6; + } /* When huffman coded, only the difference is encoded */ scale_sum = 0; for (k = 0; k < s->subband_activity[j]; k++) { if (k >= s->vq_start_subband[j] || s->bitalloc[j][k] > 0) { - scale_sum = get_scale(&s->gb, s->scalefactor_huffman[j], scale_sum); + scale_sum = get_scale(&s->gb, s->scalefactor_huffman[j], scale_sum, log_size); s->scale_factor[j][k][0] = scale_table[scale_sum]; } if (k < s->vq_start_subband[j] && s->transition_mode[j][k]) { /* Get second scale factor */ - scale_sum = get_scale(&s->gb, s->scalefactor_huffman[j], scale_sum); + scale_sum = get_scale(&s->gb, s->scalefactor_huffman[j], scale_sum, log_size); s->scale_factor[j][k][1] = scale_table[scale_sum]; } } @@ -767,8 +784,7 @@ static int dca_subframe_header(DCAContext *s, int base_channel, int block_index) * (is this valid as well for joint scales ???) */ for (k = s->subband_activity[j]; k < s->subband_activity[source_channel]; k++) { - scale = get_scale(&s->gb, s->joint_huff[j], 0); - scale += 64; /* bias */ + scale = get_scale(&s->gb, s->joint_huff[j], 64 /* bias */, 7); s->joint_scale_factor[j][k] = scale; /*joint_scale_table[scale]; */ } @@ -789,6 +805,18 @@ static int dca_subframe_header(DCAContext *s, int base_channel, int block_index) } } else { int am = s->amode & DCA_CHANNEL_MASK; + if (am >= FF_ARRAY_ELEMS(dca_default_coeffs)) { + av_log(s->avctx, AV_LOG_ERROR, + "Invalid channel mode %d\n", am); + return AVERROR_INVALIDDATA; + } + + if (s->prim_channels > FF_ARRAY_ELEMS(dca_default_coeffs[0])) { + av_log_ask_for_sample(s->avctx, "Downmixing %d channels", + s->prim_channels); + return AVERROR_PATCHWELCOME; + } + for (j = base_channel; j < s->prim_channels; j++) { s->downmix_coef[j][0] = dca_default_coeffs[am][j][0]; s->downmix_coef[j][1] = dca_default_coeffs[am][j][1]; @@ -828,7 +856,8 @@ static int dca_subframe_header(DCAContext *s, int base_channel, int block_index) } /* Scale factor index */ - s->lfe_scale_factor = scale_factor_quant7[get_bits(&s->gb, 8)]; + skip_bits(&s->gb, 1); + s->lfe_scale_factor = scale_factor_quant7[get_bits(&s->gb, 7)]; /* Quantization step size * scale factor */ lfe_scale = 0.035 * s->lfe_scale_factor; @@ -1237,6 +1266,7 @@ static int dca_subsubframe(DCAContext *s, int base_channel, int block_index) #endif } else { av_log(s->avctx, AV_LOG_ERROR, "Didn't get subframe DSYNC\n"); + return AVERROR_INVALIDDATA; } } @@ -1866,7 +1896,7 @@ static int dca_decode_frame(AVCodecContext *avctx, void *data, /* get output buffer */ s->frame.nb_samples = 256 * (s->sample_blocks / 8); - if ((ret = avctx->get_buffer(avctx, &s->frame)) < 0) { + if ((ret = ff_get_buffer(avctx, &s->frame)) < 0) { av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n"); return ret; } diff --git a/libavcodec/dcadata.h b/libavcodec/dcadata.h index 02dbb0fe54..007cc6ba24 100644 --- a/libavcodec/dcadata.h +++ b/libavcodec/dcadata.h @@ -7528,7 +7528,7 @@ static const float dca_downmix_coeffs[65] = { 0.001412537544623, 0.001000000000000, 0.000501187233627, 0.000251188643151, 0.000000000000000, }; -static const uint8_t dca_default_coeffs[16][5][2] = { +static const uint8_t dca_default_coeffs[10][5][2] = { { { 13, 13 }, }, { { 0, 64 }, { 64, 0 }, }, { { 0, 64 }, { 64, 0 }, }, diff --git a/libavcodec/dct-test.c b/libavcodec/dct-test.c index 9fdf7d179d..7dd7f616c5 100644 --- a/libavcodec/dct-test.c +++ b/libavcodec/dct-test.c @@ -234,8 +234,10 @@ static void init_block(DCTELEM block[64], int test, int is_idct, AVLFG *prng, in break; case 1: j = av_lfg_get(prng) % 10 + 1; - for (i = 0; i < j; i++) - block[av_lfg_get(prng) % 64] = av_lfg_get(prng) % (2*vals) -vals; + for (i = 0; i < j; i++) { + int idx = av_lfg_get(prng) % 64; + block[idx] = av_lfg_get(prng) % (2*vals) -vals; + } break; case 2: block[ 0] = av_lfg_get(prng) % (16*vals) - (8*vals); diff --git a/libavcodec/dfa.c b/libavcodec/dfa.c index bce6260bf3..9e0ed893d5 100644 --- a/libavcodec/dfa.c +++ b/libavcodec/dfa.c @@ -21,8 +21,10 @@ */ #include "avcodec.h" -#include "libavutil/intreadwrite.h" +#include "internal.h" #include "bytestream.h" + +#include "libavutil/imgutils.h" #include "libavutil/lzo.h" // for av_memcpy_backptr typedef struct DfaContext { @@ -35,9 +37,13 @@ typedef struct DfaContext { static av_cold int dfa_decode_init(AVCodecContext *avctx) { DfaContext *s = avctx->priv_data; + int ret; avctx->pix_fmt = PIX_FMT_PAL8; + if ((ret = av_image_check_size(avctx->width, avctx->height, 0, avctx)) < 0) + return ret; + s->frame_buf = av_mallocz(avctx->width * avctx->height + AV_LZO_OUTPUT_PADDING); if (!s->frame_buf) return AVERROR(ENOMEM); @@ -45,19 +51,16 @@ static av_cold int dfa_decode_init(AVCodecContext *avctx) return 0; } -static int decode_copy(uint8_t *frame, int width, int height, - const uint8_t *src, const uint8_t *src_end) +static int decode_copy(GetByteContext *gb, uint8_t *frame, int width, int height) { const int size = width * height; - if (src_end - src < size) - return -1; - bytestream_get_buffer(&src, frame, size); + if (bytestream2_get_buffer(gb, frame, size) != size) + return AVERROR_INVALIDDATA; return 0; } -static int decode_tsw1(uint8_t *frame, int width, int height, - const uint8_t *src, const uint8_t *src_end) +static int decode_tsw1(GetByteContext *gb, uint8_t *frame, int width, int height) { const uint8_t *frame_start = frame; const uint8_t *frame_end = frame + width * height; @@ -65,31 +68,31 @@ static int decode_tsw1(uint8_t *frame, int width, int height, int v, count, segments; unsigned offset; - segments = bytestream_get_le32(&src); - offset = bytestream_get_le32(&src); + segments = bytestream2_get_le32(gb); + offset = bytestream2_get_le32(gb); if (frame_end - frame <= offset) - return -1; + return AVERROR_INVALIDDATA; frame += offset; while (segments--) { + if (bytestream2_get_bytes_left(gb) < 2) + return AVERROR_INVALIDDATA; if (mask == 0x10000) { - if (src >= src_end) - return -1; - bitbuf = bytestream_get_le16(&src); + bitbuf = bytestream2_get_le16u(gb); mask = 1; } - if (src_end - src < 2 || frame_end - frame < 2) - return -1; + if (frame_end - frame < 2) + return AVERROR_INVALIDDATA; if (bitbuf & mask) { - v = bytestream_get_le16(&src); + v = bytestream2_get_le16(gb); offset = (v & 0x1FFF) << 1; count = ((v >> 13) + 2) << 1; if (frame - frame_start < offset || frame_end - frame < count) - return -1; + return AVERROR_INVALIDDATA; av_memcpy_backptr(frame, offset, count); frame += count; } else { - *frame++ = *src++; - *frame++ = *src++; + *frame++ = bytestream2_get_byte(gb); + *frame++ = bytestream2_get_byte(gb); } mask <<= 1; } @@ -97,39 +100,38 @@ static int decode_tsw1(uint8_t *frame, int width, int height, return 0; } -static int decode_dsw1(uint8_t *frame, int width, int height, - const uint8_t *src, const uint8_t *src_end) +static int decode_dsw1(GetByteContext *gb, uint8_t *frame, int width, int height) { const uint8_t *frame_start = frame; const uint8_t *frame_end = frame + width * height; int mask = 0x10000, bitbuf = 0; int v, offset, count, segments; - segments = bytestream_get_le16(&src); + segments = bytestream2_get_le16(gb); while (segments--) { + if (bytestream2_get_bytes_left(gb) < 2) + return AVERROR_INVALIDDATA; if (mask == 0x10000) { - if (src >= src_end) - return -1; - bitbuf = bytestream_get_le16(&src); + bitbuf = bytestream2_get_le16u(gb); mask = 1; } - if (src_end - src < 2 || frame_end - frame < 2) - return -1; + if (frame_end - frame < 2) + return AVERROR_INVALIDDATA; if (bitbuf & mask) { - v = bytestream_get_le16(&src); + v = bytestream2_get_le16(gb); offset = (v & 0x1FFF) << 1; count = ((v >> 13) + 2) << 1; if (frame - frame_start < offset || frame_end - frame < count) - return -1; + return AVERROR_INVALIDDATA; // can't use av_memcpy_backptr() since it can overwrite following pixels for (v = 0; v < count; v++) frame[v] = frame[v - offset]; frame += count; } else if (bitbuf & (mask << 1)) { - frame += bytestream_get_le16(&src); + frame += bytestream2_get_le16(gb); } else { - *frame++ = *src++; - *frame++ = *src++; + *frame++ = bytestream2_get_byte(gb); + *frame++ = bytestream2_get_byte(gb); } mask <<= 2; } @@ -137,30 +139,28 @@ static int decode_dsw1(uint8_t *frame, int width, int height, return 0; } -static int decode_dds1(uint8_t *frame, int width, int height, - const uint8_t *src, const uint8_t *src_end) +static int decode_dds1(GetByteContext *gb, uint8_t *frame, int width, int height) { const uint8_t *frame_start = frame; const uint8_t *frame_end = frame + width * height; int mask = 0x10000, bitbuf = 0; int i, v, offset, count, segments; - segments = bytestream_get_le16(&src); + segments = bytestream2_get_le16(gb); while (segments--) { + if (bytestream2_get_bytes_left(gb) < 2) + return AVERROR_INVALIDDATA; if (mask == 0x10000) { - if (src >= src_end) - return -1; - bitbuf = bytestream_get_le16(&src); + bitbuf = bytestream2_get_le16u(gb); mask = 1; } - if (src_end - src < 2 || frame_end - frame < 2) - return -1; + if (bitbuf & mask) { - v = bytestream_get_le16(&src); + v = bytestream2_get_le16(gb); offset = (v & 0x1FFF) << 2; count = ((v >> 13) + 2) << 1; if (frame - frame_start < offset || frame_end - frame < count*2 + width) - return -1; + return AVERROR_INVALIDDATA; for (i = 0; i < count; i++) { frame[0] = frame[1] = frame[width] = frame[width + 1] = frame[-offset]; @@ -168,13 +168,18 @@ static int decode_dds1(uint8_t *frame, int width, int height, frame += 2; } } else if (bitbuf & (mask << 1)) { - frame += bytestream_get_le16(&src) * 2; + v = bytestream2_get_le16(gb)*2; + if (frame - frame_end < v) + return AVERROR_INVALIDDATA; + frame += v; } else { + if (frame_end - frame < width + 3) + return AVERROR_INVALIDDATA; frame[0] = frame[1] = - frame[width] = frame[width + 1] = *src++; + frame[width] = frame[width + 1] = bytestream2_get_byte(gb); frame += 2; frame[0] = frame[1] = - frame[width] = frame[width + 1] = *src++; + frame[width] = frame[width + 1] = bytestream2_get_byte(gb); frame += 2; } mask <<= 2; @@ -183,40 +188,40 @@ static int decode_dds1(uint8_t *frame, int width, int height, return 0; } -static int decode_bdlt(uint8_t *frame, int width, int height, - const uint8_t *src, const uint8_t *src_end) +static int decode_bdlt(GetByteContext *gb, uint8_t *frame, int width, int height) { uint8_t *line_ptr; int count, lines, segments; - count = bytestream_get_le16(&src); + count = bytestream2_get_le16(gb); if (count >= height) - return -1; + return AVERROR_INVALIDDATA; frame += width * count; - lines = bytestream_get_le16(&src); - if (count + lines > height || src >= src_end) - return -1; + lines = bytestream2_get_le16(gb); + if (count + lines > height) + return AVERROR_INVALIDDATA; while (lines--) { + if (bytestream2_get_bytes_left(gb) < 1) + return AVERROR_INVALIDDATA; line_ptr = frame; frame += width; - segments = *src++; + segments = bytestream2_get_byteu(gb); while (segments--) { - if (src_end - src < 3) - return -1; - if (frame - line_ptr <= *src) - return -1; - line_ptr += *src++; - count = (int8_t)*src++; + if (frame - line_ptr <= bytestream2_peek_byte(gb)) + return AVERROR_INVALIDDATA; + line_ptr += bytestream2_get_byte(gb); + count = (int8_t)bytestream2_get_byte(gb); if (count >= 0) { - if (frame - line_ptr < count || src_end - src < count) - return -1; - bytestream_get_buffer(&src, line_ptr, count); + if (frame - line_ptr < count) + return AVERROR_INVALIDDATA; + if (bytestream2_get_buffer(gb, line_ptr, count) != count) + return AVERROR_INVALIDDATA; } else { count = -count; - if (frame - line_ptr < count || src >= src_end) - return -1; - memset(line_ptr, *src++, count); + if (frame - line_ptr < count) + return AVERROR_INVALIDDATA; + memset(line_ptr, bytestream2_get_byte(gb), count); } line_ptr += count; } @@ -225,49 +230,55 @@ static int decode_bdlt(uint8_t *frame, int width, int height, return 0; } -static int decode_wdlt(uint8_t *frame, int width, int height, - const uint8_t *src, const uint8_t *src_end) +static int decode_wdlt(GetByteContext *gb, uint8_t *frame, int width, int height) { const uint8_t *frame_end = frame + width * height; uint8_t *line_ptr; int count, i, v, lines, segments; + int y = 0; - lines = bytestream_get_le16(&src); - if (lines > height || src >= src_end) - return -1; + lines = bytestream2_get_le16(gb); + if (lines > height) + return AVERROR_INVALIDDATA; while (lines--) { - segments = bytestream_get_le16(&src); + if (bytestream2_get_bytes_left(gb) < 2) + return AVERROR_INVALIDDATA; + segments = bytestream2_get_le16u(gb); while ((segments & 0xC000) == 0xC000) { + unsigned skip_lines = -(int16_t)segments; unsigned delta = -((int16_t)segments * width); - if (frame_end - frame <= delta) - return -1; + if (frame_end - frame <= delta || y + lines + skip_lines > height) + return AVERROR_INVALIDDATA; frame += delta; - segments = bytestream_get_le16(&src); + y += skip_lines; + segments = bytestream2_get_le16(gb); } if (segments & 0x8000) { frame[width - 1] = segments & 0xFF; - segments = bytestream_get_le16(&src); + segments = bytestream2_get_le16(gb); } line_ptr = frame; + if (frame_end - frame < width) + return AVERROR_INVALIDDATA; frame += width; + y++; while (segments--) { - if (src_end - src < 2) - return -1; - if (frame - line_ptr <= *src) - return -1; - line_ptr += *src++; - count = (int8_t)*src++; + if (frame - line_ptr <= bytestream2_peek_byte(gb)) + return AVERROR_INVALIDDATA; + line_ptr += bytestream2_get_byte(gb); + count = (int8_t)bytestream2_get_byte(gb); if (count >= 0) { - if (frame - line_ptr < count*2 || src_end - src < count*2) - return -1; - bytestream_get_buffer(&src, line_ptr, count*2); + if (frame - line_ptr < count * 2) + return AVERROR_INVALIDDATA; + if (bytestream2_get_buffer(gb, line_ptr, count * 2) != count * 2) + return AVERROR_INVALIDDATA; line_ptr += count * 2; } else { count = -count; - if (frame - line_ptr < count*2 || src_end - src < 2) - return -1; - v = bytestream_get_le16(&src); + if (frame - line_ptr < count * 2) + return AVERROR_INVALIDDATA; + v = bytestream2_get_le16(gb); for (i = 0; i < count; i++) bytestream_put_le16(&line_ptr, v); } @@ -277,22 +288,19 @@ static int decode_wdlt(uint8_t *frame, int width, int height, return 0; } -static int decode_unk6(uint8_t *frame, int width, int height, - const uint8_t *src, const uint8_t *src_end) +static int decode_unk6(GetByteContext *gb, uint8_t *frame, int width, int height) { - return -1; + return AVERROR_PATCHWELCOME; } -static int decode_blck(uint8_t *frame, int width, int height, - const uint8_t *src, const uint8_t *src_end) +static int decode_blck(GetByteContext *gb, uint8_t *frame, int width, int height) { memset(frame, 0, width * height); return 0; } -typedef int (*chunk_decoder)(uint8_t *frame, int width, int height, - const uint8_t *src, const uint8_t *src_end); +typedef int (*chunk_decoder)(GetByteContext *gb, uint8_t *frame, int width, int height); static const chunk_decoder decoder[8] = { decode_copy, decode_tsw1, decode_bdlt, decode_wdlt, @@ -308,9 +316,8 @@ static int dfa_decode_frame(AVCodecContext *avctx, AVPacket *avpkt) { DfaContext *s = avctx->priv_data; + GetByteContext gb; const uint8_t *buf = avpkt->data; - const uint8_t *buf_end = avpkt->data + avpkt->size; - const uint8_t *tmp_buf; uint32_t chunk_type, chunk_size; uint8_t *dst; int ret; @@ -319,35 +326,30 @@ static int dfa_decode_frame(AVCodecContext *avctx, if (s->pic.data[0]) avctx->release_buffer(avctx, &s->pic); - if ((ret = avctx->get_buffer(avctx, &s->pic))) { + if ((ret = ff_get_buffer(avctx, &s->pic))) { av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n"); return ret; } - while (buf < buf_end) { - chunk_size = AV_RL32(buf + 4); - chunk_type = AV_RL32(buf + 8); - buf += 12; - if (buf_end - buf < chunk_size) { - av_log(avctx, AV_LOG_ERROR, "Chunk size is too big (%d bytes)\n", chunk_size); - return -1; - } + bytestream2_init(&gb, avpkt->data, avpkt->size); + while (bytestream2_get_bytes_left(&gb) > 0) { + bytestream2_skip(&gb, 4); + chunk_size = bytestream2_get_le32(&gb); + chunk_type = bytestream2_get_le32(&gb); if (!chunk_type) break; if (chunk_type == 1) { pal_elems = FFMIN(chunk_size / 3, 256); - tmp_buf = buf; for (i = 0; i < pal_elems; i++) { - s->pal[i] = bytestream_get_be24(&tmp_buf) << 2; + s->pal[i] = bytestream2_get_be24(&gb) << 2; s->pal[i] |= 0xFF << 24 | (s->pal[i] >> 6) & 0x30303; } s->pic.palette_has_changed = 1; } else if (chunk_type <= 9) { - if (decoder[chunk_type - 2](s->frame_buf, avctx->width, avctx->height, - buf, buf + chunk_size)) { + if (decoder[chunk_type - 2](&gb, s->frame_buf, avctx->width, avctx->height)) { av_log(avctx, AV_LOG_ERROR, "Error decoding %s chunk\n", chunk_name[chunk_type - 2]); - return -1; + return AVERROR_INVALIDDATA; } } else { av_log(avctx, AV_LOG_WARNING, "Ignoring unknown chunk type %d\n", diff --git a/libavcodec/diracdec.c b/libavcodec/diracdec.c index 03e7d0abde..50457232ab 100644 --- a/libavcodec/diracdec.c +++ b/libavcodec/diracdec.c @@ -491,10 +491,16 @@ static inline void codeblock(DiracContext *s, SubBand *b, } if (s->codeblock_mode && !(s->old_delta_quant && blockcnt_one)) { + int quant = b->quant; if (is_arith) - b->quant += dirac_get_arith_int(c, CTX_DELTA_Q_F, CTX_DELTA_Q_DATA); + quant += dirac_get_arith_int(c, CTX_DELTA_Q_F, CTX_DELTA_Q_DATA); else - b->quant += dirac_get_se_golomb(gb); + quant += dirac_get_se_golomb(gb); + if (quant < 0) { + av_log(s->avctx, AV_LOG_ERROR, "Invalid quant\n"); + return; + } + b->quant = quant; } b->quant = FFMIN(b->quant, MAX_QUANT); @@ -619,7 +625,7 @@ static void decode_component(DiracContext *s, int comp) b->quant = svq3_get_ue_golomb(&s->gb); align_get_bits(&s->gb); b->coeff_data = s->gb.buffer + get_bits_count(&s->gb)/8; - b->length = FFMIN(b->length, get_bits_left(&s->gb)/8); + b->length = FFMIN(b->length, FFMAX(get_bits_left(&s->gb)/8, 0)); skip_bits_long(&s->gb, b->length*8); } } @@ -1172,7 +1178,7 @@ static void propagate_block_data(DiracBlock *block, int stride, int size) * Dirac Specification -> * 12. Block motion data syntax */ -static void dirac_unpack_block_motion_data(DiracContext *s) +static int dirac_unpack_block_motion_data(DiracContext *s) { GetBitContext *gb = &s->gb; uint8_t *sbsplit = s->sbsplit; @@ -1192,7 +1198,9 @@ static void dirac_unpack_block_motion_data(DiracContext *s) ff_dirac_init_arith_decoder(arith, gb, svq3_get_ue_golomb(gb)); /* svq3_get_ue_golomb(gb) is the length */ for (y = 0; y < s->sbheight; y++) { for (x = 0; x < s->sbwidth; x++) { - int split = dirac_get_arith_uint(arith, CTX_SB_F1, CTX_SB_DATA); + unsigned int split = dirac_get_arith_uint(arith, CTX_SB_F1, CTX_SB_DATA); + if (split > 2) + return -1; sbsplit[x] = (split + pred_sbsplit(sbsplit+x, s->sbwidth, x, y)) % 3; } sbsplit += s->sbwidth; @@ -1221,6 +1229,8 @@ static void dirac_unpack_block_motion_data(DiracContext *s) propagate_block_data(block, s->blwidth, step); } } + + return 0; } static int weight(int i, int blen, int offset) @@ -1322,8 +1332,8 @@ static int mc_subpel(DiracContext *s, DiracBlock *block, const uint8_t *src[5], motion_y >>= s->chroma_y_shift; } - mx = motion_x & ~(-1 << s->mv_precision); - my = motion_y & ~(-1 << s->mv_precision); + mx = motion_x & ~(-1U << s->mv_precision); + my = motion_y & ~(-1U << s->mv_precision); motion_x >>= s->mv_precision; motion_y >>= s->mv_precision; /* normalize subpel coordinates to epel */ @@ -1675,7 +1685,8 @@ static int dirac_decode_picture_header(DiracContext *s) if (s->num_refs) { if (dirac_unpack_prediction_parameters(s)) /* [DIRAC_STD] 11.2 Picture Prediction Data. picture_prediction() */ return -1; - dirac_unpack_block_motion_data(s); /* [DIRAC_STD] 12. Block motion data syntax */ + if (dirac_unpack_block_motion_data(s)) /* [DIRAC_STD] 12. Block motion data syntax */ + return -1; } if (dirac_unpack_idwt_params(s)) /* [DIRAC_STD] 11.3 Wavelet transform data */ return -1; diff --git a/libavcodec/dnxhddata.c b/libavcodec/dnxhddata.c index 948a4c6730..da6260e909 100644 --- a/libavcodec/dnxhddata.c +++ b/libavcodec/dnxhddata.c @@ -1038,7 +1038,7 @@ int ff_dnxhd_find_cid(AVCodecContext *avctx, int bit_depth) if (cid->width == avctx->width && cid->height == avctx->height && cid->interlaced == !!(avctx->flags & CODEC_FLAG_INTERLACED_DCT) && cid->bit_depth == bit_depth) { - for (j = 0; j < sizeof(cid->bit_rates); j++) { + for (j = 0; j < FF_ARRAY_ELEMS(cid->bit_rates); j++) { if (cid->bit_rates[j] == mbs) return cid->cid; } diff --git a/libavcodec/dnxhddec.c b/libavcodec/dnxhddec.c index 0f1ce9e2f1..800f99a62c 100644 --- a/libavcodec/dnxhddec.c +++ b/libavcodec/dnxhddec.c @@ -38,6 +38,7 @@ typedef struct DNXHDContext { GetBitContext gb; int cid; ///< compression id unsigned int width, height; + enum PixelFormat pix_fmt; unsigned int mb_width, mb_height; uint32_t mb_scan_index[68]; /* max for 1080p */ int cur_field; ///< current interlaced field @@ -84,9 +85,9 @@ static int dnxhd_init_vlc(DNXHDContext *ctx, int cid) } ctx->cid_table = &ff_dnxhd_cid_table[index]; - free_vlc(&ctx->ac_vlc); - free_vlc(&ctx->dc_vlc); - free_vlc(&ctx->run_vlc); + ff_free_vlc(&ctx->ac_vlc); + ff_free_vlc(&ctx->dc_vlc); + ff_free_vlc(&ctx->run_vlc); init_vlc(&ctx->ac_vlc, DNXHD_VLC_BITS, 257, ctx->cid_table->ac_bits, 1, 1, @@ -129,7 +130,7 @@ static int dnxhd_decode_header(DNXHDContext *ctx, const uint8_t *buf, int buf_si av_dlog(ctx->avctx, "width %d, height %d\n", ctx->width, ctx->height); if (buf[0x21] & 0x40) { - ctx->avctx->pix_fmt = PIX_FMT_YUV422P10; + ctx->pix_fmt = PIX_FMT_YUV422P10; ctx->avctx->bits_per_raw_sample = 10; if (ctx->bit_depth != 10) { dsputil_init(&ctx->dsp, ctx->avctx); @@ -137,7 +138,7 @@ static int dnxhd_decode_header(DNXHDContext *ctx, const uint8_t *buf, int buf_si ctx->decode_dct_block = dnxhd_decode_dct_block_10; } } else { - ctx->avctx->pix_fmt = PIX_FMT_YUV422P; + ctx->pix_fmt = PIX_FMT_YUV422P; ctx->avctx->bits_per_raw_sample = 8; if (ctx->bit_depth != 8) { dsputil_init(&ctx->dsp, ctx->avctx); @@ -380,9 +381,15 @@ static int dnxhd_decode_frame(AVCodecContext *avctx, void *data, int *data_size, avctx->width, avctx->height, ctx->width, ctx->height); first_field = 1; } + if (avctx->pix_fmt != PIX_FMT_NONE && avctx->pix_fmt != ctx->pix_fmt) { + av_log(avctx, AV_LOG_WARNING, "pix_fmt changed: %s -> %s\n", + av_get_pix_fmt_name(avctx->pix_fmt), av_get_pix_fmt_name(ctx->pix_fmt)); + first_field = 1; + } if (av_image_check_size(ctx->width, ctx->height, 0, avctx)) return -1; + avctx->pix_fmt = ctx->pix_fmt; avcodec_set_dimensions(avctx, ctx->width, ctx->height); if (first_field) { @@ -416,9 +423,9 @@ static av_cold int dnxhd_decode_close(AVCodecContext *avctx) if (ctx->picture.data[0]) ff_thread_release_buffer(avctx, &ctx->picture); - free_vlc(&ctx->ac_vlc); - free_vlc(&ctx->dc_vlc); - free_vlc(&ctx->run_vlc); + ff_free_vlc(&ctx->ac_vlc); + ff_free_vlc(&ctx->dc_vlc); + ff_free_vlc(&ctx->run_vlc); return 0; } diff --git a/libavcodec/dnxhdenc.c b/libavcodec/dnxhdenc.c index e4c6274ae4..15543c1a1b 100644 --- a/libavcodec/dnxhdenc.c +++ b/libavcodec/dnxhdenc.c @@ -220,7 +220,7 @@ static int dnxhd_init_qmat(DNXHDEncContext *ctx, int lbias, int cbias) static int dnxhd_init_rc(DNXHDEncContext *ctx) { - FF_ALLOCZ_OR_GOTO(ctx->m.avctx, ctx->mb_rc, 8160*ctx->m.avctx->qmax*sizeof(RCEntry), fail); + FF_ALLOCZ_OR_GOTO(ctx->m.avctx, ctx->mb_rc, 8160*(ctx->m.avctx->qmax + 1)*sizeof(RCEntry), fail); if (ctx->m.avctx->mb_decision != FF_MB_DECISION_RD) FF_ALLOCZ_OR_GOTO(ctx->m.avctx, ctx->mb_cmp, ctx->m.mb_num*sizeof(RCCMPEntry), fail); diff --git a/libavcodec/dpcm.c b/libavcodec/dpcm.c index 8240221076..bba2a2b1cf 100644 --- a/libavcodec/dpcm.c +++ b/libavcodec/dpcm.c @@ -39,6 +39,7 @@ #include "libavutil/intreadwrite.h" #include "avcodec.h" +#include "internal.h" #include "bytestream.h" typedef struct DPCMContext { @@ -183,6 +184,11 @@ static int dpcm_decode_frame(AVCodecContext *avctx, void *data, int stereo = s->channels - 1; int16_t *output_samples; + if (stereo && (buf_size & 1)) { + buf_size--; + buf_end--; + } + /* calculate output size */ switch(avctx->codec->id) { case CODEC_ID_ROQ_DPCM: @@ -211,7 +217,7 @@ static int dpcm_decode_frame(AVCodecContext *avctx, void *data, /* get output buffer */ s->frame.nb_samples = (out + s->channels - 1) / s->channels; - if ((ret = avctx->get_buffer(avctx, &s->frame)) < 0) { + if ((ret = ff_get_buffer(avctx, &s->frame)) < 0) { av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n"); return ret; } @@ -320,7 +326,7 @@ static int dpcm_decode_frame(AVCodecContext *avctx, void *data, *got_frame_ptr = 1; *(AVFrame *)data = s->frame; - return buf_size; + return avpkt->size; } #define DPCM_DECODER(id_, name_, long_name_) \ diff --git a/libavcodec/dsicinav.c b/libavcodec/dsicinav.c index 4c6c41c2fe..81cee7f5f6 100644 --- a/libavcodec/dsicinav.c +++ b/libavcodec/dsicinav.c @@ -25,6 +25,7 @@ */ #include "avcodec.h" +#include "internal.h" #include "bytestream.h" #include "mathops.h" @@ -108,27 +109,31 @@ static av_cold int cinvideo_decode_init(AVCodecContext *avctx) return 0; } -static void cin_apply_delta_data(const unsigned char *src, unsigned char *dst, int size) +static void cin_apply_delta_data(const unsigned char *src, unsigned char *dst, + int size) { while (size--) *dst++ += *src++; } -static int cin_decode_huffman(const unsigned char *src, int src_size, unsigned char *dst, int dst_size) +static int cin_decode_huffman(const unsigned char *src, int src_size, + unsigned char *dst, int dst_size) { int b, huff_code = 0; unsigned char huff_code_table[15]; - unsigned char *dst_cur = dst; - unsigned char *dst_end = dst + dst_size; + unsigned char *dst_cur = dst; + unsigned char *dst_end = dst + dst_size; const unsigned char *src_end = src + src_size; - memcpy(huff_code_table, src, 15); src += 15; src_size -= 15; + memcpy(huff_code_table, src, 15); + src += 15; + src_size -= 15; while (src < src_end) { huff_code = *src++; if ((huff_code >> 4) == 15) { - b = huff_code << 4; - huff_code = *src++; + b = huff_code << 4; + huff_code = *src++; *dst_cur++ = b | (huff_code >> 4); } else *dst_cur++ = huff_code_table[huff_code >> 4]; @@ -147,11 +152,12 @@ static int cin_decode_huffman(const unsigned char *src, int src_size, unsigned c return dst_cur - dst; } -static void cin_decode_lzss(const unsigned char *src, int src_size, unsigned char *dst, int dst_size) +static int cin_decode_lzss(const unsigned char *src, int src_size, + unsigned char *dst, int dst_size) { uint16_t cmd; int i, sz, offset, code; - unsigned char *dst_end = dst + dst_size; + unsigned char *dst_end = dst + dst_size, *dst_start = dst; const unsigned char *src_end = src + src_size; while (src < src_end && dst < dst_end) { @@ -160,11 +166,15 @@ static void cin_decode_lzss(const unsigned char *src, int src_size, unsigned cha if (code & (1 << i)) { *dst++ = *src++; } else { - cmd = AV_RL16(src); src += 2; + cmd = AV_RL16(src); + src += 2; offset = cmd >> 4; + if ((int)(dst - dst_start) < offset + 1) + return AVERROR_INVALIDDATA; sz = (cmd & 0xF) + 2; - /* don't use memcpy/memmove here as the decoding routine (ab)uses */ - /* buffer overlappings to repeat bytes in the destination */ + /* don't use memcpy/memmove here as the decoding routine + * (ab)uses buffer overlappings to repeat bytes in the + * destination */ sz = FFMIN(sz, dst_end - dst); while (sz--) { *dst = *(dst - offset - 1); @@ -173,22 +183,27 @@ static void cin_decode_lzss(const unsigned char *src, int src_size, unsigned cha } } } + + return 0; } -static void cin_decode_rle(const unsigned char *src, int src_size, unsigned char *dst, int dst_size) +static void cin_decode_rle(const unsigned char *src, int src_size, + unsigned char *dst, int dst_size) { int len, code; - unsigned char *dst_end = dst + dst_size; + unsigned char *dst_end = dst + dst_size; const unsigned char *src_end = src + src_size; while (src < src_end && dst < dst_end) { code = *src++; if (code & 0x80) { + if (src >= src_end) + break; len = code - 0x7F; memset(dst, *src++, FFMIN(len, dst_end - dst)); } else { len = code + 1; - memcpy(dst, src, FFMIN(len, dst_end - dst)); + memcpy(dst, src, FFMIN3(len, dst_end - dst, src_end - src)); src += len; } dst += len; @@ -199,21 +214,16 @@ static int cinvideo_decode_frame(AVCodecContext *avctx, void *data, int *data_size, AVPacket *avpkt) { - const uint8_t *buf = avpkt->data; - int buf_size = avpkt->size; + const uint8_t *buf = avpkt->data; + int buf_size = avpkt->size; CinVideoContext *cin = avctx->priv_data; - int i, y, palette_type, palette_colors_count, bitmap_frame_type, bitmap_frame_size; + int i, y, palette_type, palette_colors_count, + bitmap_frame_type, bitmap_frame_size, res = 0; - cin->frame.buffer_hints = FF_BUFFER_HINTS_VALID | FF_BUFFER_HINTS_PRESERVE | FF_BUFFER_HINTS_REUSABLE; - if (avctx->reget_buffer(avctx, &cin->frame)) { - av_log(cin->avctx, AV_LOG_ERROR, "delphinecinvideo: reget_buffer() failed to allocate a frame\n"); - return -1; - } - - palette_type = buf[0]; + palette_type = buf[0]; palette_colors_count = AV_RL16(buf+1); - bitmap_frame_type = buf[3]; - buf += 4; + bitmap_frame_type = buf[3]; + buf += 4; bitmap_frame_size = buf_size - 4; @@ -224,67 +234,85 @@ static int cinvideo_decode_frame(AVCodecContext *avctx, if (palette_colors_count > 256) return AVERROR_INVALIDDATA; for (i = 0; i < palette_colors_count; ++i) { - cin->palette[i] = 0xFF << 24 | bytestream_get_le24(&buf); + cin->palette[i] = 0xFF << 24 | bytestream_get_le24(&buf); bitmap_frame_size -= 3; } } else { for (i = 0; i < palette_colors_count; ++i) { - cin->palette[buf[0]] = 0xFF << 24 | AV_RL24(buf+1); - buf += 4; - bitmap_frame_size -= 4; + cin->palette[buf[0]] = 0xFF << 24 | AV_RL24(buf + 1); + buf += 4; + bitmap_frame_size -= 4; } } - memcpy(cin->frame.data[1], cin->palette, sizeof(cin->palette)); - cin->frame.palette_has_changed = 1; - /* note: the decoding routines below assumes that surface.width = surface.pitch */ + bitmap_frame_size = FFMIN(cin->bitmap_size, bitmap_frame_size); + + /* note: the decoding routines below assumes that + * surface.width = surface.pitch */ switch (bitmap_frame_type) { case 9: cin_decode_rle(buf, bitmap_frame_size, - cin->bitmap_table[CIN_CUR_BMP], cin->bitmap_size); + cin->bitmap_table[CIN_CUR_BMP], cin->bitmap_size); break; case 34: cin_decode_rle(buf, bitmap_frame_size, - cin->bitmap_table[CIN_CUR_BMP], cin->bitmap_size); + cin->bitmap_table[CIN_CUR_BMP], cin->bitmap_size); cin_apply_delta_data(cin->bitmap_table[CIN_PRE_BMP], - cin->bitmap_table[CIN_CUR_BMP], cin->bitmap_size); + cin->bitmap_table[CIN_CUR_BMP], cin->bitmap_size); break; case 35: cin_decode_huffman(buf, bitmap_frame_size, - cin->bitmap_table[CIN_INT_BMP], cin->bitmap_size); + cin->bitmap_table[CIN_INT_BMP], cin->bitmap_size); cin_decode_rle(cin->bitmap_table[CIN_INT_BMP], bitmap_frame_size, - cin->bitmap_table[CIN_CUR_BMP], cin->bitmap_size); + cin->bitmap_table[CIN_CUR_BMP], cin->bitmap_size); break; case 36: bitmap_frame_size = cin_decode_huffman(buf, bitmap_frame_size, - cin->bitmap_table[CIN_INT_BMP], cin->bitmap_size); + cin->bitmap_table[CIN_INT_BMP], + cin->bitmap_size); cin_decode_rle(cin->bitmap_table[CIN_INT_BMP], bitmap_frame_size, - cin->bitmap_table[CIN_CUR_BMP], cin->bitmap_size); + cin->bitmap_table[CIN_CUR_BMP], cin->bitmap_size); cin_apply_delta_data(cin->bitmap_table[CIN_PRE_BMP], - cin->bitmap_table[CIN_CUR_BMP], cin->bitmap_size); + cin->bitmap_table[CIN_CUR_BMP], cin->bitmap_size); break; case 37: cin_decode_huffman(buf, bitmap_frame_size, - cin->bitmap_table[CIN_CUR_BMP], cin->bitmap_size); + cin->bitmap_table[CIN_CUR_BMP], cin->bitmap_size); break; case 38: - cin_decode_lzss(buf, bitmap_frame_size, - cin->bitmap_table[CIN_CUR_BMP], cin->bitmap_size); + res = cin_decode_lzss(buf, bitmap_frame_size, + cin->bitmap_table[CIN_CUR_BMP], + cin->bitmap_size); + if (res < 0) + return res; break; case 39: - cin_decode_lzss(buf, bitmap_frame_size, - cin->bitmap_table[CIN_CUR_BMP], cin->bitmap_size); + res = cin_decode_lzss(buf, bitmap_frame_size, + cin->bitmap_table[CIN_CUR_BMP], + cin->bitmap_size); + if (res < 0) + return res; cin_apply_delta_data(cin->bitmap_table[CIN_PRE_BMP], - cin->bitmap_table[CIN_CUR_BMP], cin->bitmap_size); + cin->bitmap_table[CIN_CUR_BMP], cin->bitmap_size); break; } + cin->frame.buffer_hints = FF_BUFFER_HINTS_VALID | FF_BUFFER_HINTS_PRESERVE | FF_BUFFER_HINTS_REUSABLE; + if ((res = avctx->reget_buffer(avctx, &cin->frame)) < 0) { + av_log(cin->avctx, AV_LOG_ERROR, + "delphinecinvideo: reget_buffer() failed to allocate a frame\n"); + return res; + } + + memcpy(cin->frame.data[1], cin->palette, sizeof(cin->palette)); + cin->frame.palette_has_changed = 1; for (y = 0; y < cin->avctx->height; ++y) memcpy(cin->frame.data[0] + (cin->avctx->height - 1 - y) * cin->frame.linesize[0], - cin->bitmap_table[CIN_CUR_BMP] + y * cin->avctx->width, - cin->avctx->width); + cin->bitmap_table[CIN_CUR_BMP] + y * cin->avctx->width, + cin->avctx->width); - FFSWAP(uint8_t *, cin->bitmap_table[CIN_CUR_BMP], cin->bitmap_table[CIN_PRE_BMP]); + FFSWAP(uint8_t *, cin->bitmap_table[CIN_CUR_BMP], + cin->bitmap_table[CIN_PRE_BMP]); *data_size = sizeof(AVFrame); *(AVFrame *)data = cin->frame; @@ -328,15 +356,15 @@ static av_cold int cinaudio_decode_init(AVCodecContext *avctx) static int cinaudio_decode_frame(AVCodecContext *avctx, void *data, int *got_frame_ptr, AVPacket *avpkt) { - const uint8_t *buf = avpkt->data; - CinAudioContext *cin = avctx->priv_data; + const uint8_t *buf = avpkt->data; + CinAudioContext *cin = avctx->priv_data; const uint8_t *buf_end = buf + avpkt->size; int16_t *samples; int delta, ret; /* get output buffer */ cin->frame.nb_samples = avpkt->size - cin->initial_decode_frame; - if ((ret = avctx->get_buffer(avctx, &cin->frame)) < 0) { + if ((ret = ff_get_buffer(avctx, &cin->frame)) < 0) { av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n"); return ret; } @@ -345,13 +373,13 @@ static int cinaudio_decode_frame(AVCodecContext *avctx, void *data, delta = cin->delta; if (cin->initial_decode_frame) { cin->initial_decode_frame = 0; - delta = sign_extend(AV_RL16(buf), 16); - buf += 2; - *samples++ = delta; + delta = sign_extend(AV_RL16(buf), 16); + buf += 2; + *samples++ = delta; } while (buf < buf_end) { - delta += cinaudio_delta16_table[*buf++]; - delta = av_clip_int16(delta); + delta += cinaudio_delta16_table[*buf++]; + delta = av_clip_int16(delta); *samples++ = delta; } cin->delta = delta; diff --git a/libavcodec/dsputil.c b/libavcodec/dsputil.c index 80ed6503fa..dab74cced2 100644 --- a/libavcodec/dsputil.c +++ b/libavcodec/dsputil.c @@ -367,18 +367,17 @@ void ff_put_pixels_clamped_c(const DCTELEM *block, uint8_t *restrict pixels, int line_size) { int i; - uint8_t *cm = ff_cropTbl + MAX_NEG_CROP; /* read the pixels */ for(i=0;i<8;i++) { - pixels[0] = cm[block[0]]; - pixels[1] = cm[block[1]]; - pixels[2] = cm[block[2]]; - pixels[3] = cm[block[3]]; - pixels[4] = cm[block[4]]; - pixels[5] = cm[block[5]]; - pixels[6] = cm[block[6]]; - pixels[7] = cm[block[7]]; + pixels[0] = av_clip_uint8(block[0]); + pixels[1] = av_clip_uint8(block[1]); + pixels[2] = av_clip_uint8(block[2]); + pixels[3] = av_clip_uint8(block[3]); + pixels[4] = av_clip_uint8(block[4]); + pixels[5] = av_clip_uint8(block[5]); + pixels[6] = av_clip_uint8(block[6]); + pixels[7] = av_clip_uint8(block[7]); pixels += line_size; block += 8; @@ -389,14 +388,13 @@ static void put_pixels_clamped4_c(const DCTELEM *block, uint8_t *restrict pixels int line_size) { int i; - uint8_t *cm = ff_cropTbl + MAX_NEG_CROP; /* read the pixels */ for(i=0;i<4;i++) { - pixels[0] = cm[block[0]]; - pixels[1] = cm[block[1]]; - pixels[2] = cm[block[2]]; - pixels[3] = cm[block[3]]; + pixels[0] = av_clip_uint8(block[0]); + pixels[1] = av_clip_uint8(block[1]); + pixels[2] = av_clip_uint8(block[2]); + pixels[3] = av_clip_uint8(block[3]); pixels += line_size; block += 8; @@ -407,12 +405,11 @@ static void put_pixels_clamped2_c(const DCTELEM *block, uint8_t *restrict pixels int line_size) { int i; - uint8_t *cm = ff_cropTbl + MAX_NEG_CROP; /* read the pixels */ for(i=0;i<2;i++) { - pixels[0] = cm[block[0]]; - pixels[1] = cm[block[1]]; + pixels[0] = av_clip_uint8(block[0]); + pixels[1] = av_clip_uint8(block[1]); pixels += line_size; block += 8; @@ -444,18 +441,17 @@ void ff_add_pixels_clamped_c(const DCTELEM *block, uint8_t *restrict pixels, int line_size) { int i; - uint8_t *cm = ff_cropTbl + MAX_NEG_CROP; /* read the pixels */ for(i=0;i<8;i++) { - pixels[0] = cm[pixels[0] + block[0]]; - pixels[1] = cm[pixels[1] + block[1]]; - pixels[2] = cm[pixels[2] + block[2]]; - pixels[3] = cm[pixels[3] + block[3]]; - pixels[4] = cm[pixels[4] + block[4]]; - pixels[5] = cm[pixels[5] + block[5]]; - pixels[6] = cm[pixels[6] + block[6]]; - pixels[7] = cm[pixels[7] + block[7]]; + pixels[0] = av_clip_uint8(pixels[0] + block[0]); + pixels[1] = av_clip_uint8(pixels[1] + block[1]); + pixels[2] = av_clip_uint8(pixels[2] + block[2]); + pixels[3] = av_clip_uint8(pixels[3] + block[3]); + pixels[4] = av_clip_uint8(pixels[4] + block[4]); + pixels[5] = av_clip_uint8(pixels[5] + block[5]); + pixels[6] = av_clip_uint8(pixels[6] + block[6]); + pixels[7] = av_clip_uint8(pixels[7] + block[7]); pixels += line_size; block += 8; } @@ -465,14 +461,13 @@ static void add_pixels_clamped4_c(const DCTELEM *block, uint8_t *restrict pixels int line_size) { int i; - uint8_t *cm = ff_cropTbl + MAX_NEG_CROP; /* read the pixels */ for(i=0;i<4;i++) { - pixels[0] = cm[pixels[0] + block[0]]; - pixels[1] = cm[pixels[1] + block[1]]; - pixels[2] = cm[pixels[2] + block[2]]; - pixels[3] = cm[pixels[3] + block[3]]; + pixels[0] = av_clip_uint8(pixels[0] + block[0]); + pixels[1] = av_clip_uint8(pixels[1] + block[1]); + pixels[2] = av_clip_uint8(pixels[2] + block[2]); + pixels[3] = av_clip_uint8(pixels[3] + block[3]); pixels += line_size; block += 8; } @@ -482,12 +477,11 @@ static void add_pixels_clamped2_c(const DCTELEM *block, uint8_t *restrict pixels int line_size) { int i; - uint8_t *cm = ff_cropTbl + MAX_NEG_CROP; /* read the pixels */ for(i=0;i<2;i++) { - pixels[0] = cm[pixels[0] + block[0]]; - pixels[1] = cm[pixels[1] + block[1]]; + pixels[0] = av_clip_uint8(pixels[0] + block[0]); + pixels[1] = av_clip_uint8(pixels[1] + block[1]); pixels += line_size; block += 8; } @@ -1918,7 +1912,7 @@ void ff_set_cmp(DSPContext* c, me_cmp_func *cmp, int type){ static void add_bytes_c(uint8_t *dst, uint8_t *src, int w){ long i; - for(i=0; i<=w-sizeof(long); i+=sizeof(long)){ + for (i = 0; i <= w - (int) sizeof(long); i += sizeof(long)) { long a = *(long*)(src+i); long b = *(long*)(dst+i); *(long*)(dst+i) = ((a&pb_7f) + (b&pb_7f)) ^ ((a^b)&pb_80); @@ -1943,7 +1937,7 @@ static void diff_bytes_c(uint8_t *dst, uint8_t *src1, uint8_t *src2, int w){ } }else #endif - for(i=0; i<=w-sizeof(long); i+=sizeof(long)){ + for (i = 0; i <= w - (int) sizeof(long); i += sizeof(long)) { long a = *(long*)(src1+i); long b = *(long*)(src2+i); *(long*)(dst+i) = ((a|pb_80) - (b&pb_7f)) ^ ((a^b^pb_80)&pb_80); @@ -2779,15 +2773,11 @@ static void ff_jref_idct2_add(uint8_t *dest, int line_size, DCTELEM *block) static void ff_jref_idct1_put(uint8_t *dest, int line_size, DCTELEM *block) { - uint8_t *cm = ff_cropTbl + MAX_NEG_CROP; - - dest[0] = cm[(block[0] + 4)>>3]; + dest[0] = av_clip_uint8((block[0] + 4)>>3); } static void ff_jref_idct1_add(uint8_t *dest, int line_size, DCTELEM *block) { - uint8_t *cm = ff_cropTbl + MAX_NEG_CROP; - - dest[0] = cm[dest[0] + ((block[0] + 4)>>3)]; + dest[0] = av_clip_uint8(dest[0] + ((block[0] + 4)>>3)); } static void just_return(void *mem av_unused, int stride av_unused, int h av_unused) { return; } @@ -2832,7 +2822,7 @@ int ff_check_alignment(void){ av_cold void dsputil_init(DSPContext* c, AVCodecContext *avctx) { - int i; + int i, j; ff_check_alignment(); @@ -3194,11 +3184,15 @@ av_cold void dsputil_init(DSPContext* c, AVCodecContext *avctx) if (ARCH_SH4) dsputil_init_sh4 (c, avctx); if (ARCH_BFIN) dsputil_init_bfin (c, avctx); - for(i=0; i<64; i++){ - if(!c->put_2tap_qpel_pixels_tab[0][i]) - c->put_2tap_qpel_pixels_tab[0][i]= c->put_h264_qpel_pixels_tab[0][i]; - if(!c->avg_2tap_qpel_pixels_tab[0][i]) - c->avg_2tap_qpel_pixels_tab[0][i]= c->avg_h264_qpel_pixels_tab[0][i]; + for (i = 0; i < 4; i++) { + for (j = 0; j < 16; j++) { + if(!c->put_2tap_qpel_pixels_tab[i][j]) + c->put_2tap_qpel_pixels_tab[i][j] = + c->put_h264_qpel_pixels_tab[i][j]; + if(!c->avg_2tap_qpel_pixels_tab[i][j]) + c->avg_2tap_qpel_pixels_tab[i][j] = + c->avg_h264_qpel_pixels_tab[i][j]; + } } ff_init_scantable_permutation(c->idct_permutation, diff --git a/libavcodec/dsputil.h b/libavcodec/dsputil.h index a44c146af9..dd2737ea8b 100644 --- a/libavcodec/dsputil.h +++ b/libavcodec/dsputil.h @@ -33,6 +33,7 @@ #include "libavutil/intreadwrite.h" #include "avcodec.h" +typedef int emuedge_linesize_type; //#define DEBUG /* dct code */ diff --git a/libavcodec/dv.c b/libavcodec/dv.c index 413d50fb0d..16dad98353 100644 --- a/libavcodec/dv.c +++ b/libavcodec/dv.c @@ -312,7 +312,7 @@ static av_cold int dvvideo_init(AVCodecContext *avctx) dv_rl_vlc[i].level = level; dv_rl_vlc[i].run = run; } - free_vlc(&dv_vlc); + ff_free_vlc(&dv_vlc); dv_vlc_map_tableinit(); } @@ -372,11 +372,6 @@ typedef struct BlockInfo { static const int vs_total_ac_bits = (100 * 4 + 68*2) * 5; static const int mb_area_start[5] = { 1, 6, 21, 43, 64 }; -static inline int put_bits_left(PutBitContext* s) -{ - return (s->buf_end - s->buf) * 8 - put_bits_count(s); -} - /* decode AC coefficients */ static void dv_decode_ac(GetBitContext *gb, BlockInfo *mb, DCTELEM *block) { diff --git a/libavcodec/dvdsubdec.c b/libavcodec/dvdsubdec.c index f4b54396d9..c09c6be55a 100644 --- a/libavcodec/dvdsubdec.c +++ b/libavcodec/dvdsubdec.c @@ -94,6 +94,12 @@ static int decode_rle(uint8_t *bitmap, int linesize, int w, int h, int x, y, len, color; uint8_t *d; + if (start >= buf_size) + return -1; + + if (w <= 0 || h <= 0) + return -1; + bit_len = (buf_size - start) * 8; init_get_bits(&gb, buf + start, bit_len); @@ -336,10 +342,12 @@ static int decode_dvd_subtitles(DVDSubContext *ctx, AVSubtitle *sub_header, sub_header->rects[0] = av_mallocz(sizeof(AVSubtitleRect)); sub_header->num_rects = 1; sub_header->rects[0]->pict.data[0] = bitmap; - decode_rle(bitmap, w * 2, w, (h + 1) / 2, - buf, offset1, buf_size, is_8bit); - decode_rle(bitmap + w, w * 2, w, h / 2, - buf, offset2, buf_size, is_8bit); + if (decode_rle(bitmap, w * 2, w, (h + 1) / 2, + buf, offset1, buf_size, is_8bit) < 0) + goto fail; + if (decode_rle(bitmap + w, w * 2, w, h / 2, + buf, offset2, buf_size, is_8bit) < 0) + goto fail; sub_header->rects[0]->pict.data[1] = av_mallocz(AVPALETTE_SIZE); if (is_8bit) { if (yuv_palette == 0) diff --git a/libavcodec/dxa.c b/libavcodec/dxa.c index f32fdd33e5..a5bf1a051c 100644 --- a/libavcodec/dxa.c +++ b/libavcodec/dxa.c @@ -255,6 +255,12 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *data_size, AVPac case 5: c->pic.key_frame = !(compr & 1); c->pic.pict_type = (compr & 1) ? AV_PICTURE_TYPE_P : AV_PICTURE_TYPE_I; + + if (!tmpptr && !c->pic.key_frame) { + av_log(avctx, AV_LOG_ERROR, "Missing reference frame.\n"); + return AVERROR_INVALIDDATA; + } + for(j = 0; j < avctx->height; j++){ if(compr & 1){ for(i = 0; i < avctx->width; i++) @@ -295,6 +301,11 @@ static av_cold int decode_init(AVCodecContext *avctx) c->avctx = avctx; avctx->pix_fmt = PIX_FMT_PAL8; + if (avctx->width%4 || avctx->height%4) { + av_log(avctx, AV_LOG_ERROR, "dimensions are not a multiple of 4"); + return AVERROR_INVALIDDATA; + } + avcodec_get_frame_defaults(&c->pic); avcodec_get_frame_defaults(&c->prev); diff --git a/libavcodec/dxtory.c b/libavcodec/dxtory.c index 5f67fbdbef..f8ebb43b63 100644 --- a/libavcodec/dxtory.c +++ b/libavcodec/dxtory.c @@ -21,6 +21,7 @@ */ #include "avcodec.h" +#include "internal.h" #include "libavutil/intreadwrite.h" static av_cold int decode_init(AVCodecContext *avctx) @@ -51,7 +52,7 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *data_size, } pic->reference = 0; - if ((ret = avctx->get_buffer(avctx, pic)) < 0) + if ((ret = ff_get_buffer(avctx, pic)) < 0) return ret; pic->pict_type = AV_PICTURE_TYPE_I; diff --git a/libavcodec/dxva2_internal.h b/libavcodec/dxva2_internal.h index 23d4d87522..fcf45bc664 100644 --- a/libavcodec/dxva2_internal.h +++ b/libavcodec/dxva2_internal.h @@ -25,7 +25,14 @@ #define _WIN32_WINNT 0x0600 #define COBJMACROS + +#include "config.h" + #include "dxva2.h" +#if HAVE_DXVA_H +#include +#endif + #include "avcodec.h" #include "mpegvideo.h" diff --git a/libavcodec/eacmv.c b/libavcodec/eacmv.c index 8a8d6a9cef..d7b8562aca 100644 --- a/libavcodec/eacmv.c +++ b/libavcodec/eacmv.c @@ -112,8 +112,8 @@ static void cmv_decode_inter(CmvContext * s, const uint8_t *buf, const uint8_t * int yoffset = ((buf[i] >> 4)) - 7; if (s->last_frame.data[0]) cmv_motcomp(s->frame.data[0], s->frame.linesize[0], - s->last_frame.data[0], s->last_frame.linesize[0], - x*4, y*4, xoffset, yoffset, s->avctx->width, s->avctx->height); + s->last_frame.data[0], s->last_frame.linesize[0], + x*4, y*4, xoffset, yoffset, s->avctx->width, s->avctx->height); } i++; } diff --git a/libavcodec/eamad.c b/libavcodec/eamad.c index 40fdb37670..02f7eb1c04 100644 --- a/libavcodec/eamad.c +++ b/libavcodec/eamad.c @@ -29,6 +29,7 @@ */ #include "avcodec.h" +#include "bytestream.h" #include "get_bits.h" #include "dsputil.h" #include "aandcttab.h" @@ -143,6 +144,11 @@ static inline int decode_block_intra(MadContext * t, DCTELEM * block) break; } else if (level != 0) { i += run; + if (i > 63) { + av_log(s->avctx, AV_LOG_ERROR, + "ac-tex damaged at %d %d\n", s->mb_x, s->mb_y); + return -1; + } j = scantable[i]; level = (level*quant_matrix[j]) >> 4; level = (level-1)|1; @@ -157,6 +163,11 @@ static inline int decode_block_intra(MadContext * t, DCTELEM * block) run = SHOW_UBITS(re, &s->gb, 6)+1; LAST_SKIP_BITS(re, &s->gb, 6); i += run; + if (i > 63) { + av_log(s->avctx, AV_LOG_ERROR, + "ac-tex damaged at %d %d\n", s->mb_x, s->mb_y); + return -1; + } j = scantable[i]; if (level < 0) { level = -level; @@ -168,10 +179,6 @@ static inline int decode_block_intra(MadContext * t, DCTELEM * block) level = (level-1)|1; } } - if (i > 63) { - av_log(s->avctx, AV_LOG_ERROR, "ac-tex damaged at %d %d\n", s->mb_x, s->mb_y); - return -1; - } block[j] = level; } @@ -246,32 +253,34 @@ static int decode_frame(AVCodecContext *avctx, { const uint8_t *buf = avpkt->data; int buf_size = avpkt->size; - const uint8_t *buf_end = buf+buf_size; MadContext *t = avctx->priv_data; + GetByteContext gb; MpegEncContext *s = &t->s; int chunk_type; int inter; - if (buf_size < 17) { - av_log(avctx, AV_LOG_ERROR, "Input buffer too small\n"); - *data_size = 0; - return -1; - } + bytestream2_init(&gb, buf, buf_size); - chunk_type = AV_RL32(&buf[0]); + chunk_type = bytestream2_get_le32(&gb); inter = (chunk_type == MADm_TAG || chunk_type == MADe_TAG); - buf += 8; + bytestream2_skip(&gb, 10); av_reduce(&avctx->time_base.num, &avctx->time_base.den, - AV_RL16(&buf[6]), 1000, 1<<30); + bytestream2_get_le16(&gb), 1000, 1<<30); - s->width = AV_RL16(&buf[8]); - s->height = AV_RL16(&buf[10]); - calc_intra_matrix(t, buf[13]); - buf += 16; + s->width = bytestream2_get_le16(&gb); + s->height = bytestream2_get_le16(&gb); + bytestream2_skip(&gb, 1); + calc_intra_matrix(t, bytestream2_get_byte(&gb)); + bytestream2_skip(&gb, 2); + + if (bytestream2_get_bytes_left(&gb) < 2) { + av_log(avctx, AV_LOG_ERROR, "Input data too small\n"); + return AVERROR_INVALIDDATA; + } if (avctx->width != s->width || avctx->height != s->height) { - if((s->width * s->height)/2048*7 > buf_end-buf) + if((s->width * s->height)/2048*7 > bytestream2_get_bytes_left(&gb)) return -1; if (av_image_check_size(s->width, s->height, 0, avctx) < 0) return -1; @@ -290,13 +299,14 @@ static int decode_frame(AVCodecContext *avctx, } } - av_fast_malloc(&t->bitstream_buf, &t->bitstream_buf_size, (buf_end-buf) + FF_INPUT_BUFFER_PADDING_SIZE); + av_fast_malloc(&t->bitstream_buf, &t->bitstream_buf_size, + bytestream2_get_bytes_left(&gb) + FF_INPUT_BUFFER_PADDING_SIZE); if (!t->bitstream_buf) return AVERROR(ENOMEM); - bswap16_buf(t->bitstream_buf, (const uint16_t*)buf, (buf_end-buf)/2); - memset((uint8_t*)t->bitstream_buf + (buf_end-buf), 0, FF_INPUT_BUFFER_PADDING_SIZE); - init_get_bits(&s->gb, t->bitstream_buf, 8*(buf_end-buf)); - + bswap16_buf(t->bitstream_buf, (const uint16_t *)(buf + bytestream2_tell(&gb)), + bytestream2_get_bytes_left(&gb) / 2); + memset((uint8_t*)t->bitstream_buf + bytestream2_get_bytes_left(&gb), 0, FF_INPUT_BUFFER_PADDING_SIZE); + init_get_bits(&s->gb, t->bitstream_buf, 8*(bytestream2_get_bytes_left(&gb))); for (s->mb_y=0; s->mb_y < (avctx->height+15)/16; s->mb_y++) for (s->mb_x=0; s->mb_x < (avctx->width +15)/16; s->mb_x++) if(decode_mb(t, inter) < 0) diff --git a/libavcodec/eatgq.c b/libavcodec/eatgq.c index da9ff3bba0..fd314c4ab8 100644 --- a/libavcodec/eatgq.c +++ b/libavcodec/eatgq.c @@ -43,6 +43,7 @@ typedef struct TgqContext { ScanTable scantable; int qtable[64]; DECLARE_ALIGNED(16, DCTELEM, block)[6][64]; + GetByteContext gb; } TgqContext; static av_cold int tgq_decode_init(AVCodecContext *avctx){ @@ -141,39 +142,36 @@ static void tgq_idct_put_mb_dconly(TgqContext *s, int mb_x, int mb_y, const int8 } } -static void tgq_decode_mb(TgqContext *s, int mb_y, int mb_x, const uint8_t **bs, const uint8_t *buf_end){ +static void tgq_decode_mb(TgqContext *s, int mb_y, int mb_x){ int mode; int i; int8_t dc[6]; - mode = bytestream_get_byte(bs); - if (mode>buf_end-*bs) { - av_log(s->avctx, AV_LOG_ERROR, "truncated macroblock\n"); - return; - } - + mode = bytestream2_get_byte(&s->gb); if (mode>12) { GetBitContext gb; - init_get_bits(&gb, *bs, mode*8); + init_get_bits(&gb, s->gb.buffer, FFMIN(s->gb.buffer_end - s->gb.buffer, mode) * 8); for(i=0; i<6; i++) tgq_decode_block(s, s->block[i], &gb); tgq_idct_put_mb(s, s->block, mb_x, mb_y); + bytestream2_skip(&s->gb, mode); }else{ if (mode==3) { - memset(dc, (*bs)[0], 4); - dc[4] = (*bs)[1]; - dc[5] = (*bs)[2]; + memset(dc, bytestream2_get_byte(&s->gb), 4); + dc[4] = bytestream2_get_byte(&s->gb); + dc[5] = bytestream2_get_byte(&s->gb); }else if (mode==6) { - memcpy(dc, *bs, 6); + bytestream2_get_buffer(&s->gb, dc, 6); }else if (mode==12) { - for(i=0; i<6; i++) - dc[i] = (*bs)[i*2]; + for (i = 0; i < 6; i++) { + dc[i] = bytestream2_get_byte(&s->gb); + bytestream2_skip(&s->gb, 1); + } }else{ av_log(s->avctx, AV_LOG_ERROR, "unsupported mb mode %i\n", mode); } tgq_idct_put_mb_dconly(s, mb_x, mb_y, dc); } - *bs += mode; } static void tgq_calculate_qtable(TgqContext *s, int quant){ @@ -193,28 +191,30 @@ static int tgq_decode_frame(AVCodecContext *avctx, AVPacket *avpkt){ const uint8_t *buf = avpkt->data; int buf_size = avpkt->size; - const uint8_t *buf_start = buf; - const uint8_t *buf_end = buf + buf_size; TgqContext *s = avctx->priv_data; int x,y; - int big_endian = AV_RL32(&buf[4]) > 0x000FFFFF; - buf += 8; - if(8>buf_end-buf) { + if (buf_size < 16) { av_log(avctx, AV_LOG_WARNING, "truncated header\n"); return -1; } - s->width = big_endian ? AV_RB16(&buf[0]) : AV_RL16(&buf[0]); - s->height = big_endian ? AV_RB16(&buf[2]) : AV_RL16(&buf[2]); + bytestream2_init(&s->gb, buf + 8, buf_size - 8); + if (big_endian) { + s->width = bytestream2_get_be16u(&s->gb); + s->height = bytestream2_get_be16u(&s->gb); + } else { + s->width = bytestream2_get_le16u(&s->gb); + s->height = bytestream2_get_le16u(&s->gb); + } if (s->avctx->width!=s->width || s->avctx->height!=s->height) { avcodec_set_dimensions(s->avctx, s->width, s->height); if (s->frame.data[0]) avctx->release_buffer(avctx, &s->frame); } - tgq_calculate_qtable(s, buf[4]); - buf += 8; + tgq_calculate_qtable(s, bytestream2_get_byteu(&s->gb)); + bytestream2_skip(&s->gb, 3); if (!s->frame.data[0]) { s->frame.key_frame = 1; @@ -226,14 +226,14 @@ static int tgq_decode_frame(AVCodecContext *avctx, } } - for (y=0; y<(avctx->height+15)/16; y++) - for (x=0; x<(avctx->width+15)/16; x++) - tgq_decode_mb(s, y, x, &buf, buf_end); + for (y = 0; y < FFALIGN(avctx->height, 16) >> 4; y++) + for (x = 0; x < FFALIGN(avctx->width, 16) >> 4; x++) + tgq_decode_mb(s, y, x); *data_size = sizeof(AVFrame); *(AVFrame*)data = s->frame; - return buf-buf_start; + return avpkt->size; } static av_cold int tgq_decode_end(AVCodecContext *avctx){ diff --git a/libavcodec/eatqi.c b/libavcodec/eatqi.c index d650a71713..306aa65fbf 100644 --- a/libavcodec/eatqi.c +++ b/libavcodec/eatqi.c @@ -62,7 +62,7 @@ static int tqi_decode_mb(MpegEncContext *s, DCTELEM (*block)[64]) int n; s->dsp.clear_blocks(block[0]); for (n=0; n<6; n++) - if(ff_mpeg1_decode_block_intra(s, block[n], n)<0) + if (ff_mpeg1_decode_block_intra(s, block[n], n) < 0) return -1; return 0; @@ -137,7 +137,7 @@ static int tqi_decode_frame(AVCodecContext *avctx, for (s->mb_y=0; s->mb_y<(avctx->height+15)/16; s->mb_y++) for (s->mb_x=0; s->mb_x<(avctx->width+15)/16; s->mb_x++) { - if(tqi_decode_mb(s, t->block) < 0) + if (tqi_decode_mb(s, t->block) < 0) break; tqi_idct_put(t, t->block); } diff --git a/libavcodec/elbg.c b/libavcodec/elbg.c index ede863e9be..3af4d052dd 100644 --- a/libavcodec/elbg.c +++ b/libavcodec/elbg.c @@ -110,7 +110,7 @@ static int get_high_utility_cell(elbg_data *elbg) while (elbg->utility_inc[i] < r) i++; - assert(!elbg->cells[i]); + assert(elbg->cells[i]); return i; } diff --git a/libavcodec/error_resilience.c b/libavcodec/error_resilience.c index d55c0006ef..7858d3ce10 100644 --- a/libavcodec/error_resilience.c +++ b/libavcodec/error_resilience.c @@ -440,9 +440,14 @@ static void guess_mv(MpegEncContext *s) if ((!(s->avctx->error_concealment&FF_EC_GUESS_MVS)) || num_avail <= mb_width / 2) { for (mb_y = 0; mb_y < s->mb_height; mb_y++) { + s->mb_x = 0; + s->mb_y = mb_y; + ff_init_block_index(s); for (mb_x = 0; mb_x < s->mb_width; mb_x++) { const int mb_xy = mb_x + mb_y * s->mb_stride; + ff_update_block_index(s); + if (IS_INTRA(s->current_picture.f.mb_type[mb_xy])) continue; if (!(s->error_status_table[mb_xy] & ER_MV_ERROR)) @@ -477,6 +482,9 @@ static void guess_mv(MpegEncContext *s) changed = 0; for (mb_y = 0; mb_y < s->mb_height; mb_y++) { + s->mb_x = 0; + s->mb_y = mb_y; + ff_init_block_index(s); for (mb_x = 0; mb_x < s->mb_width; mb_x++) { const int mb_xy = mb_x + mb_y * s->mb_stride; int mv_predictor[8][2] = { { 0 } }; @@ -488,6 +496,8 @@ static void guess_mv(MpegEncContext *s) const int mot_index = (mb_x + mb_y * mot_stride) * mot_step; int prev_x, prev_y, prev_ref; + ff_update_block_index(s); + if ((mb_x ^ mb_y ^ pass) & 1) continue; @@ -911,6 +921,12 @@ void ff_er_frame_end(MpegEncContext *s) return; }; + if (s->picture_structure == PICT_FRAME && + s->current_picture.f.linesize[0] != s->current_picture_ptr->f.linesize[0]) { + av_log(s->avctx, AV_LOG_ERROR, "Error concealment not possible, frame not fully initialized\n"); + return; + } + if (s->current_picture.f.motion_val[0] == NULL) { av_log(s->avctx, AV_LOG_ERROR, "Warning MVs not available\n"); @@ -1098,11 +1114,16 @@ void ff_er_frame_end(MpegEncContext *s) /* handle inter blocks with damaged AC */ for (mb_y = 0; mb_y < s->mb_height; mb_y++) { + s->mb_x = 0; + s->mb_y = mb_y; + ff_init_block_index(s); for (mb_x = 0; mb_x < s->mb_width; mb_x++) { const int mb_xy = mb_x + mb_y * s->mb_stride; const int mb_type = s->current_picture.f.mb_type[mb_xy]; int dir = !s->last_picture.f.data[0]; + ff_update_block_index(s); + error = s->error_status_table[mb_xy]; if (IS_INTRA(mb_type)) @@ -1140,11 +1161,16 @@ void ff_er_frame_end(MpegEncContext *s) /* guess MVs */ if (s->pict_type == AV_PICTURE_TYPE_B) { for (mb_y = 0; mb_y < s->mb_height; mb_y++) { + s->mb_x = 0; + s->mb_y = mb_y; + ff_init_block_index(s); for (mb_x = 0; mb_x < s->mb_width; mb_x++) { int xy = mb_x * 2 + mb_y * 2 * s->b8_stride; const int mb_xy = mb_x + mb_y * s->mb_stride; const int mb_type = s->current_picture.f.mb_type[mb_xy]; + ff_update_block_index(s); + error = s->error_status_table[mb_xy]; if (IS_INTRA(mb_type)) diff --git a/libavcodec/escape124.c b/libavcodec/escape124.c index c9025fddde..f77edaf1c5 100644 --- a/libavcodec/escape124.c +++ b/libavcodec/escape124.c @@ -48,8 +48,8 @@ typedef struct Escape124Context { CodeBook codebooks[3]; } Escape124Context; -static int can_safely_read(GetBitContext* gb, int bits) { - return get_bits_count(gb) + bits <= gb->size_in_bits; +static int can_safely_read(GetBitContext* gb, uint64_t bits) { + return get_bits_left(gb) >= bits; } /** @@ -90,7 +90,7 @@ static CodeBook unpack_codebook(GetBitContext* gb, unsigned depth, unsigned i, j; CodeBook cb = { 0 }; - if (!can_safely_read(gb, size * 34)) + if (!can_safely_read(gb, size * 34L)) return cb; if (size >= INT_MAX / sizeof(MacroBlock)) diff --git a/libavcodec/faxcompr.c b/libavcodec/faxcompr.c index c157b984d3..01c8c61ae1 100644 --- a/libavcodec/faxcompr.c +++ b/libavcodec/faxcompr.c @@ -110,11 +110,11 @@ av_cold void ff_ccitt_unpack_init(void) ccitt_vlc[1].table = code_table2; ccitt_vlc[1].table_allocated = 648; for(i = 0; i < 2; i++){ - init_vlc_sparse(&ccitt_vlc[i], 9, CCITT_SYMS, - ccitt_codes_lens[i], 1, 1, - ccitt_codes_bits[i], 1, 1, - ccitt_syms, 2, 2, - INIT_VLC_USE_NEW_STATIC); + ff_init_vlc_sparse(&ccitt_vlc[i], 9, CCITT_SYMS, + ccitt_codes_lens[i], 1, 1, + ccitt_codes_bits[i], 1, 1, + ccitt_syms, 2, 2, + INIT_VLC_USE_NEW_STATIC); } INIT_VLC_STATIC(&ccitt_group3_2d_vlc, 9, 11, ccitt_group3_2d_lens, 1, 1, @@ -228,7 +228,7 @@ static int decode_group3_2d_line(AVCodecContext *avctx, GetBitContext *gb, mode = !mode; } //sync line pointers - while(run_off <= offs){ + while(offs < width && run_off <= offs){ run_off += *ref++; run_off += *ref++; } @@ -243,7 +243,7 @@ static void put_line(uint8_t *dst, int size, int width, const int *runs) PutBitContext pb; int run, mode = ~0, pix_left = width, run_idx = 0; - init_put_bits(&pb, dst, size*8); + init_put_bits(&pb, dst, size); while(pix_left > 0){ run = runs[run_idx++]; mode = ~mode; diff --git a/libavcodec/ffv1.c b/libavcodec/ffv1.c index c3034d326c..fd3e4f70b5 100644 --- a/libavcodec/ffv1.c +++ b/libavcodec/ffv1.c @@ -255,7 +255,7 @@ static void find_best_state(uint8_t best_state[256][256], const uint8_t one_stat occ[j]=1.0; for(k=0; k<256; k++){ double newocc[256]={0}; - for(m=0; m<256; m++){ + for(m=1; m<256; m++){ if(occ[m]){ len -=occ[m]*( p *l2tab[ m] + (1-p)*l2tab[256-m]); @@ -451,7 +451,7 @@ static av_always_inline int encode_line(FFV1Context *s, int w, int run_mode=0; if(s->ac){ - if(c->bytestream_end - c->bytestream < w*20){ + if(c->bytestream_end - c->bytestream < w*35){ av_log(s->avctx, AV_LOG_ERROR, "encoded frame too large\n"); return -1; } @@ -722,6 +722,10 @@ static av_cold int init_slice_contexts(FFV1Context *f){ int i; f->slice_count= f->num_h_slices * f->num_v_slices; + if (f->slice_count <= 0) { + av_log(f->avctx, AV_LOG_ERROR, "Invalid number of slices\n"); + return AVERROR(EINVAL); + } for(i=0; islice_count; i++){ FFV1Context *fs= av_mallocz(sizeof(*fs)); @@ -993,7 +997,7 @@ static av_cold int encode_init(AVCodecContext *avctx) } } gob_count= strtol(p, &next, 0); - if(next==p || gob_count <0){ + if(next==p || gob_count <=0){ av_log(avctx, AV_LOG_ERROR, "2Pass file invalid\n"); return -1; } @@ -1547,20 +1551,48 @@ static int read_header(FFV1Context *f){ memset(state, 128, sizeof(state)); if(f->version < 2){ - f->version= get_symbol(c, state, 0); - f->ac= f->avctx->coder_type= get_symbol(c, state, 0); - if(f->ac>1){ - for(i=1; i<256; i++){ - f->state_transition[i]= get_symbol(c, state, 1) + c->one_state[i]; + int chroma_h_shift, chroma_v_shift, colorspace, bits_per_raw_sample; + int transparency; + unsigned v = get_symbol(c, state, 0); + if (v > 1) { + av_log(f->avctx, AV_LOG_ERROR, + "invalid version %d in version 1 header\n", v); + return AVERROR_INVALIDDATA; + } + f->version = v; + + f->ac = f->avctx->coder_type = get_symbol(c, state, 0); + + if (f->ac > 1) { + for (i = 1; i < 256; i++) + f->state_transition[i] = + get_symbol(c, state, 1) + c->one_state[i]; + } + + colorspace = get_symbol(c, state, 0); //YUV cs type + bits_per_raw_sample = f->version > 0 ? get_symbol(c, state, 0) : f->avctx->bits_per_raw_sample; + get_rac(c, state); //no chroma = false + chroma_h_shift = get_symbol(c, state, 0); + chroma_v_shift = get_symbol(c, state, 0); + transparency = get_rac(c, state); + + if (f->plane_count) { + if (colorspace != f->colorspace || + bits_per_raw_sample != f->avctx->bits_per_raw_sample || + chroma_h_shift != f->chroma_h_shift || + chroma_v_shift != f->chroma_v_shift || + transparency != f->transparency) { + av_log(f->avctx, AV_LOG_ERROR, "Invalid change of global parameters\n"); + return AVERROR_INVALIDDATA; } } - f->colorspace= get_symbol(c, state, 0); //YUV cs type - if(f->version>0) - f->avctx->bits_per_raw_sample= get_symbol(c, state, 0); - get_rac(c, state); //no chroma = false - f->chroma_h_shift= get_symbol(c, state, 0); - f->chroma_v_shift= get_symbol(c, state, 0); - f->transparency= get_rac(c, state); + + f->colorspace = colorspace; + f->avctx->bits_per_raw_sample = bits_per_raw_sample; + f->chroma_h_shift = chroma_h_shift; + f->chroma_v_shift = chroma_v_shift; + f->transparency = transparency; + f->plane_count= 2 + f->transparency; } diff --git a/libavcodec/flac_parser.c b/libavcodec/flac_parser.c index ae7edaa052..6be2df3f20 100644 --- a/libavcodec/flac_parser.c +++ b/libavcodec/flac_parser.c @@ -646,7 +646,7 @@ static int flac_parse(AVCodecParserContext *s, AVCodecContext *avctx, handle_error: *poutbuf = NULL; *poutbuf_size = 0; - return read_end - buf; + return buf_size ? read_end - buf : 0; } static int flac_parse_init(AVCodecParserContext *c) diff --git a/libavcodec/flacdata.c b/libavcodec/flacdata.c index 6fcbe3955a..1954f32d32 100644 --- a/libavcodec/flacdata.c +++ b/libavcodec/flacdata.c @@ -27,7 +27,7 @@ const int ff_flac_sample_rate_table[16] = 8000, 16000, 22050, 24000, 32000, 44100, 48000, 96000, 0, 0, 0, 0 }; -const int16_t ff_flac_blocksize_table[16] = { +const int32_t ff_flac_blocksize_table[16] = { 0, 192, 576<<0, 576<<1, 576<<2, 576<<3, 0, 0, 256<<0, 256<<1, 256<<2, 256<<3, 256<<4, 256<<5, 256<<6, 256<<7 }; diff --git a/libavcodec/flacdata.h b/libavcodec/flacdata.h index 96a50b9183..e2c1e5d7f2 100644 --- a/libavcodec/flacdata.h +++ b/libavcodec/flacdata.h @@ -26,6 +26,6 @@ extern const int ff_flac_sample_rate_table[16]; -extern const int16_t ff_flac_blocksize_table[16]; +extern const int32_t ff_flac_blocksize_table[16]; #endif /* AVCODEC_FLACDATA_H */ diff --git a/libavcodec/flacdec.c b/libavcodec/flacdec.c index ca0863107a..dfe5cf5ab7 100644 --- a/libavcodec/flacdec.c +++ b/libavcodec/flacdec.c @@ -422,7 +422,16 @@ static inline int decode_subframe(FLACContext *s, int channel) type = get_bits(&s->gb, 6); if (get_bits1(&s->gb)) { + int left = get_bits_left(&s->gb); wasted = 1; + if ( left < 0 || + (left < s->curr_bps && !show_bits_long(&s->gb, left)) || + !show_bits_long(&s->gb, s->curr_bps)) { + av_log(s->avctx, AV_LOG_ERROR, + "Invalid number of wasted bits > available bits (%d) - left=%d\n", + s->curr_bps, left); + return AVERROR_INVALIDDATA; + } while (!get_bits1(&s->gb)) wasted++; s->curr_bps -= wasted; @@ -590,7 +599,7 @@ static int flac_decode_frame(AVCodecContext *avctx, void *data, /* get output buffer */ s->frame.nb_samples = s->blocksize; - if ((ret = avctx->get_buffer(avctx, &s->frame)) < 0) { + if ((ret = ff_get_buffer(avctx, &s->frame)) < 0) { av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n"); return ret; } diff --git a/libavcodec/flacenc.c b/libavcodec/flacenc.c index 7345a7eef0..3a7cc59a30 100644 --- a/libavcodec/flacenc.c +++ b/libavcodec/flacenc.c @@ -937,14 +937,16 @@ static int encode_residual_ch(FlacEncodeContext *s, int ch) omethod == ORDER_METHOD_8LEVEL) { int levels = 1 << omethod; uint32_t bits[1 << ORDER_METHOD_8LEVEL]; - int order; + int order = -1; int opt_index = levels-1; opt_order = max_order-1; bits[opt_index] = UINT32_MAX; for (i = levels-1; i >= 0; i--) { + int last_order = order; order = min_order + (((max_order-min_order+1) * (i+1)) / levels)-1; - if (order < 0) - order = 0; + order = av_clip(order, min_order - 1, max_order - 1); + if (order == last_order) + continue; encode_residual_lpc(res, smp, n, order+1, coefs[order], shift[order]); bits[i] = find_subframe_rice_params(s, sub, order+1); if (bits[i] < bits[opt_index]) { diff --git a/libavcodec/flashsv.c b/libavcodec/flashsv.c index 3861344cb7..e74c318459 100644 --- a/libavcodec/flashsv.c +++ b/libavcodec/flashsv.c @@ -122,10 +122,11 @@ static av_cold int flashsv_decode_init(AVCodecContext *avctx) } -static void flashsv2_prime(FlashSVContext *s, uint8_t *src, - int size, int unp_size) +static int flashsv2_prime(FlashSVContext *s, uint8_t *src, + int size, int unp_size) { z_stream zs; + int zret; // Zlib return code zs.zalloc = NULL; zs.zfree = NULL; @@ -137,7 +138,8 @@ static void flashsv2_prime(FlashSVContext *s, uint8_t *src, s->zstream.avail_out = s->block_size * 3; inflate(&s->zstream, Z_SYNC_FLUSH); - deflateInit(&zs, 0); + if (deflateInit(&zs, 0) != Z_OK) + return -1; zs.next_in = s->tmpblock; zs.avail_in = s->block_size * 3 - s->zstream.avail_out; zs.next_out = s->deflate_block; @@ -145,13 +147,18 @@ static void flashsv2_prime(FlashSVContext *s, uint8_t *src, deflate(&zs, Z_SYNC_FLUSH); deflateEnd(&zs); - inflateReset(&s->zstream); + if ((zret = inflateReset(&s->zstream)) != Z_OK) { + av_log(s->avctx, AV_LOG_ERROR, "Inflate reset error: %d\n", zret); + return AVERROR_UNKNOWN; + } s->zstream.next_in = s->deflate_block; s->zstream.avail_in = s->deflate_block_size - zs.avail_out; s->zstream.next_out = s->tmpblock; s->zstream.avail_out = s->block_size * 3; inflate(&s->zstream, Z_SYNC_FLUSH); + + return 0; } static int flashsv_decode_block(AVCodecContext *avctx, AVPacket *avpkt, @@ -164,11 +171,14 @@ static int flashsv_decode_block(AVCodecContext *avctx, AVPacket *avpkt, int k; int ret = inflateReset(&s->zstream); if (ret != Z_OK) { - //return -1; + av_log(avctx, AV_LOG_ERROR, "Inflate reset error: %d\n", ret); + return AVERROR_UNKNOWN; } if (s->zlibprime_curr || s->zlibprime_prev) { - flashsv2_prime(s, s->blocks[blk_idx].pos, s->blocks[blk_idx].size, + ret = flashsv2_prime(s, s->blocks[blk_idx].pos, s->blocks[blk_idx].size, s->blocks[blk_idx].unp_size); + if (ret < 0) + return ret; } s->zstream.next_in = avpkt->data + get_bits_count(gb) / 8; s->zstream.avail_in = block_size; @@ -371,8 +381,19 @@ static int flashsv_decode_frame(AVCodecContext *avctx, void *data, } if (has_diff) { + if (!s->keyframe) { + av_log(avctx, AV_LOG_ERROR, + "inter frame without keyframe\n"); + return AVERROR_INVALIDDATA; + } s->diff_start = get_bits(&gb, 8); s->diff_height = get_bits(&gb, 8); + if (s->diff_start + s->diff_height > cur_blk_height) { + av_log(avctx, AV_LOG_ERROR, + "Block parameters invalid: %d + %d > %d\n", + s->diff_start, s->diff_height, cur_blk_height); + return AVERROR_INVALIDDATA; + } av_log(avctx, AV_LOG_DEBUG, "%dx%d diff start %d height %d\n", i, j, s->diff_start, s->diff_height); @@ -390,6 +411,11 @@ static int flashsv_decode_frame(AVCodecContext *avctx, void *data, av_log_missing_feature(avctx, "zlibprime_curr", 1); return AVERROR_PATCHWELCOME; } + if (!s->blocks && (s->zlibprime_curr || s->zlibprime_prev)) { + av_log(avctx, AV_LOG_ERROR, "no data available for zlib " + "priming\n"); + return AVERROR_INVALIDDATA; + } size--; // account for flags byte } diff --git a/libavcodec/flashsv2enc.c b/libavcodec/flashsv2enc.c index 6466be7858..dd477d420d 100644 --- a/libavcodec/flashsv2enc.c +++ b/libavcodec/flashsv2enc.c @@ -270,7 +270,7 @@ static int write_header(FlashSV2Context * s, uint8_t * buf, int buf_size) if (buf_size < 5) return -1; - init_put_bits(&pb, buf, buf_size * 8); + init_put_bits(&pb, buf, buf_size); put_bits(&pb, 4, (s->block_width >> 4) - 1); put_bits(&pb, 12, s->image_width); diff --git a/libavcodec/flashsvenc.c b/libavcodec/flashsvenc.c index 7e21e7d534..8ed92a6381 100644 --- a/libavcodec/flashsvenc.c +++ b/libavcodec/flashsvenc.c @@ -130,7 +130,7 @@ static int encode_bitstream(FlashSVContext *s, AVFrame *p, uint8_t *buf, int buf_pos, res; int pred_blocks = 0; - init_put_bits(&pb, buf, buf_size * 8); + init_put_bits(&pb, buf, buf_size); put_bits(&pb, 4, block_width / 16 - 1); put_bits(&pb, 12, s->image_width); diff --git a/libavcodec/fraps.c b/libavcodec/fraps.c index db0e85fd6a..c1d520cca5 100644 --- a/libavcodec/fraps.c +++ b/libavcodec/fraps.c @@ -113,13 +113,13 @@ static int fraps2_decode_plane(FrapsContext *s, uint8_t *dst, int stride, int w, if(j) dst[i] += dst[i - stride]; else if(Uoff) dst[i] += 0x80; if (get_bits_left(&gb) < 0) { - free_vlc(&vlc); + ff_free_vlc(&vlc); return AVERROR_INVALIDDATA; } } dst += stride; } - free_vlc(&vlc); + ff_free_vlc(&vlc); return 0; } @@ -140,7 +140,12 @@ static int decode_frame(AVCodecContext *avctx, uint32_t offs[4]; int i, j, is_chroma; const int planes = 3; + enum PixelFormat pix_fmt; + if (buf_size < 4) { + av_log(avctx, AV_LOG_ERROR, "Packet is too short\n"); + return AVERROR_INVALIDDATA; + } header = AV_RL32(buf); version = header & 0xff; @@ -155,8 +160,6 @@ static int decode_frame(AVCodecContext *avctx, buf += header_size; - avctx->pix_fmt = version & 1 ? PIX_FMT_BGR24 : PIX_FMT_YUVJ420P; - if (version < 2) { unsigned needed_size = avctx->width*avctx->height*3; if (version == 0) needed_size /= 2; @@ -176,7 +179,13 @@ static int decode_frame(AVCodecContext *avctx, FF_BUFFER_HINTS_PRESERVE | FF_BUFFER_HINTS_REUSABLE; - switch(version) { + pix_fmt = version & 1 ? PIX_FMT_BGR24 : PIX_FMT_YUVJ420P; + if (avctx->pix_fmt != pix_fmt && f->data[0]) { + avctx->release_buffer(avctx, f); + } + avctx->pix_fmt = pix_fmt; + + switch (version) { case 0: default: /* Fraps v0 is a reordered YUV420 */ @@ -215,6 +224,7 @@ static int decode_frame(AVCodecContext *avctx, case 1: /* Fraps v1 is an upside-down BGR24 */ + if (avctx->reget_buffer(avctx, f)) { av_log(avctx, AV_LOG_ERROR, "reget_buffer() failed\n"); return -1; diff --git a/libavcodec/g722dec.c b/libavcodec/g722dec.c index 50a224ba10..9e0a2870b2 100644 --- a/libavcodec/g722dec.c +++ b/libavcodec/g722dec.c @@ -35,6 +35,7 @@ */ #include "avcodec.h" +#include "internal.h" #include "get_bits.h" #include "g722.h" #include "libavutil/opt.h" @@ -96,7 +97,7 @@ static int g722_decode_frame(AVCodecContext *avctx, void *data, /* get output buffer */ c->frame.nb_samples = avpkt->size * 2; - if ((ret = avctx->get_buffer(avctx, &c->frame)) < 0) { + if ((ret = ff_get_buffer(avctx, &c->frame)) < 0) { av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n"); return ret; } @@ -126,8 +127,8 @@ static int g722_decode_frame(AVCodecContext *avctx, void *data, c->prev_samples[c->prev_samples_pos++] = rlow - rhigh; ff_g722_apply_qmf(c->prev_samples + c->prev_samples_pos - 24, &xout1, &xout2); - *out_buf++ = av_clip_int16(xout1 >> 12); - *out_buf++ = av_clip_int16(xout2 >> 12); + *out_buf++ = av_clip_int16(xout1 >> 11); + *out_buf++ = av_clip_int16(xout2 >> 11); if (c->prev_samples_pos >= PREV_SAMPLES_BUF_SIZE) { memmove(c->prev_samples, c->prev_samples + c->prev_samples_pos - 22, 22 * sizeof(c->prev_samples[0])); diff --git a/libavcodec/g722enc.c b/libavcodec/g722enc.c index 1cb0070649..595afae633 100644 --- a/libavcodec/g722enc.c +++ b/libavcodec/g722enc.c @@ -128,8 +128,8 @@ static inline void filter_samples(G722Context *c, const int16_t *samples, c->prev_samples[c->prev_samples_pos++] = samples[0]; c->prev_samples[c->prev_samples_pos++] = samples[1]; ff_g722_apply_qmf(c->prev_samples + c->prev_samples_pos - 24, &xout1, &xout2); - *xlow = xout1 + xout2 >> 13; - *xhigh = xout1 - xout2 >> 13; + *xlow = xout1 + xout2 >> 14; + *xhigh = xout1 - xout2 >> 14; if (c->prev_samples_pos >= PREV_SAMPLES_BUF_SIZE) { memmove(c->prev_samples, c->prev_samples + c->prev_samples_pos - 22, @@ -174,7 +174,7 @@ static void g722_encode_trellis(G722Context *c, int trellis, for (i = 0; i < 2; i++) { nodes[i] = c->nodep_buf[i]; nodes_next[i] = c->nodep_buf[i] + frontier; - memset(c->nodep_buf[i], 0, 2 * frontier * sizeof(*c->nodep_buf)); + memset(c->nodep_buf[i], 0, 2 * frontier * sizeof(*c->nodep_buf[i])); nodes[i][0] = c->node_buf[i] + frontier; nodes[i][0]->ssd = 0; nodes[i][0]->path = 0; diff --git a/libavcodec/g726.c b/libavcodec/g726.c index 8c02a392cc..392a085c7c 100644 --- a/libavcodec/g726.c +++ b/libavcodec/g726.c @@ -448,7 +448,7 @@ static int g726_decode_frame(AVCodecContext *avctx, void *data, /* get output buffer */ c->frame.nb_samples = out_samples; - if ((ret = avctx->get_buffer(avctx, &c->frame)) < 0) { + if ((ret = ff_get_buffer(avctx, &c->frame)) < 0) { av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n"); return ret; } diff --git a/libavcodec/get_bits.h b/libavcodec/get_bits.h index 648c958cb0..38ae4ca1cb 100644 --- a/libavcodec/get_bits.h +++ b/libavcodec/get_bits.h @@ -118,10 +118,23 @@ for examples see get_bits, show_bits, skip_bits, get_vlc # define MIN_CACHE_BITS 25 #endif +#if UNCHECKED_BITSTREAM_READER #define OPEN_READER(name, gb) \ unsigned int name##_index = (gb)->index; \ av_unused unsigned int name##_cache +#define HAVE_BITS_REMAINING(name, gb) 1 +#else +#define OPEN_READER(name, gb) \ + unsigned int name##_index = (gb)->index; \ + unsigned int av_unused name##_cache = 0; \ + unsigned int av_unused name##_size_plus8 = \ + (gb)->size_in_bits_plus8 + +#define HAVE_BITS_REMAINING(name, gb) \ + name##_index < name##_size_plus8 +#endif + #define CLOSE_READER(name, gb) (gb)->index = name##_index #ifdef BITSTREAM_READER_LE @@ -154,7 +167,7 @@ for examples see get_bits, show_bits, skip_bits, get_vlc # define SKIP_COUNTER(name, gb, num) name##_index += (num) #else # define SKIP_COUNTER(name, gb, num) \ - name##_index = FFMIN((gb)->size_in_bits_plus8, name##_index + (num)) + name##_index = FFMIN(name##_size_plus8, name##_index + (num)) #endif #define SKIP_BITS(name, gb, num) do { \ @@ -329,25 +342,33 @@ static inline int check_marker(GetBitContext *s, const char *msg) } /** - * Inititalize GetBitContext. - * @param buffer bitstream buffer, must be FF_INPUT_BUFFER_PADDING_SIZE bytes larger than the actual read bits - * because some optimized bitstream readers read 32 or 64 bit at once and could read over the end + * Initialize GetBitContext. + * @param buffer bitstream buffer, must be FF_INPUT_BUFFER_PADDING_SIZE bytes + * larger than the actual read bits because some optimized bitstream + * readers read 32 or 64 bit at once and could read over the end * @param bit_size the size of the buffer in bits + * @return 0 on success, AVERROR_INVALIDDATA if the buffer_size would overflow. */ -static inline void init_get_bits(GetBitContext *s, const uint8_t *buffer, - int bit_size) +static inline int init_get_bits(GetBitContext *s, const uint8_t *buffer, + int bit_size) { - int buffer_size = (bit_size+7)>>3; - if (buffer_size < 0 || bit_size < 0) { + int buffer_size; + int ret = 0; + + if (bit_size > INT_MAX - 7 || bit_size < 0 || !buffer) { buffer_size = bit_size = 0; buffer = NULL; + ret = AVERROR_INVALIDDATA; } + buffer_size = (bit_size + 7) >> 3; + s->buffer = buffer; s->size_in_bits = bit_size; s->size_in_bits_plus8 = bit_size + 8; s->buffer_end = buffer + buffer_size; s->index = 0; + return ret; } static inline void align_get_bits(GetBitContext *s) @@ -360,19 +381,19 @@ static inline void align_get_bits(GetBitContext *s) bits, bits_wrap, bits_size, \ codes, codes_wrap, codes_size, \ flags) \ - init_vlc_sparse(vlc, nb_bits, nb_codes, \ - bits, bits_wrap, bits_size, \ - codes, codes_wrap, codes_size, \ - NULL, 0, 0, flags) + ff_init_vlc_sparse(vlc, nb_bits, nb_codes, \ + bits, bits_wrap, bits_size, \ + codes, codes_wrap, codes_size, \ + NULL, 0, 0, flags) -int init_vlc_sparse(VLC *vlc, int nb_bits, int nb_codes, +int ff_init_vlc_sparse(VLC *vlc, int nb_bits, int nb_codes, const void *bits, int bits_wrap, int bits_size, const void *codes, int codes_wrap, int codes_size, const void *symbols, int symbols_wrap, int symbols_size, int flags); #define INIT_VLC_LE 2 #define INIT_VLC_USE_NEW_STATIC 4 -void free_vlc(VLC *vlc); +void ff_free_vlc(VLC *vlc); #define INIT_VLC_STATIC(vlc, bits, a,b,c,d,e,f,g, static_size) do { \ static VLC_TYPE table[static_size][2]; \ diff --git a/libavcodec/gifdec.c b/libavcodec/gifdec.c index 83cb36831b..e97d7cd63b 100644 --- a/libavcodec/gifdec.c +++ b/libavcodec/gifdec.c @@ -125,26 +125,21 @@ static int gif_read_image(GifState *s) case 1: y1 += 8; ptr += linesize * 8; - if (y1 >= height) { - y1 = pass ? 2 : 4; - ptr = ptr1 + linesize * y1; - pass++; - } break; case 2: y1 += 4; ptr += linesize * 4; - if (y1 >= height) { - y1 = 1; - ptr = ptr1 + linesize; - pass++; - } break; case 3: y1 += 2; ptr += linesize * 2; break; } + while (y1 >= height) { + y1 = 4 >> pass; + ptr = ptr1 + linesize * y1; + pass++; + } } else { ptr += linesize; } diff --git a/libavcodec/golomb.h b/libavcodec/golomb.h index 638357b470..32e53a456f 100644 --- a/libavcodec/golomb.h +++ b/libavcodec/golomb.h @@ -135,7 +135,7 @@ static inline int svq3_get_ue_golomb(GetBitContext *gb){ ret = (ret << 4) | ff_interleaved_dirac_golomb_vlc_code[buf]; UPDATE_CACHE(re, gb); buf = GET_CACHE(re, gb); - } while(ret<0x8000000U); + } while (ret<0x8000000U && HAVE_BITS_REMAINING(re, gb)); CLOSE_READER(re, gb); return ret - 1; @@ -301,7 +301,7 @@ static inline int get_ur_golomb_jpegls(GetBitContext *gb, int k, int limit, int return buf; }else{ int i; - for(i=0; SHOW_UBITS(re, gb, 1) == 0; i++){ + for (i = 0; i < limit && SHOW_UBITS(re, gb, 1) == 0; i++) { if (gb->size_in_bits <= re_index) return -1; LAST_SKIP_BITS(re, gb, 1); diff --git a/libavcodec/gsmdec.c b/libavcodec/gsmdec.c index eec515b41f..10cb6f0e21 100644 --- a/libavcodec/gsmdec.c +++ b/libavcodec/gsmdec.c @@ -25,6 +25,7 @@ */ #include "avcodec.h" +#include "internal.h" #include "get_bits.h" #include "msgsmdec.h" @@ -72,7 +73,7 @@ static int gsm_decode_frame(AVCodecContext *avctx, void *data, /* get output buffer */ s->frame.nb_samples = avctx->frame_size; - if ((res = avctx->get_buffer(avctx, &s->frame)) < 0) { + if ((res = ff_get_buffer(avctx, &s->frame)) < 0) { av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n"); return res; } diff --git a/libavcodec/h261dec.c b/libavcodec/h261dec.c index ff3d05c514..e7dc925248 100644 --- a/libavcodec/h261dec.c +++ b/libavcodec/h261dec.c @@ -66,7 +66,7 @@ static av_cold void h261_decode_init_vlc(H261Context *h){ INIT_VLC_STATIC(&h261_cbp_vlc, H261_CBP_VLC_BITS, 63, &h261_cbp_tab[0][1], 2, 1, &h261_cbp_tab[0][0], 2, 1, 512); - init_rl(&h261_rl_tcoeff, ff_h261_rl_table_store); + ff_init_rl(&h261_rl_tcoeff, ff_h261_rl_table_store); INIT_VLC_RL(h261_rl_tcoeff, 552); } } @@ -265,7 +265,7 @@ static int h261_decode_mb(H261Context *h){ while( h->mba_diff == MBA_STUFFING ); // stuffing if ( h->mba_diff < 0 ){ - if ( get_bits_count(&s->gb) + 7 >= s->gb.size_in_bits ) + if (get_bits_left(&s->gb) <= 7) return SLICE_END; av_log(s->avctx, AV_LOG_ERROR, "illegal mba at %d %d\n", s->mb_x, s->mb_y); @@ -286,6 +286,11 @@ static int h261_decode_mb(H261Context *h){ // Read mtype h->mtype = get_vlc2(&s->gb, h261_mtype_vlc.table, H261_MTYPE_VLC_BITS, 2); + if (h->mtype < 0) { + av_log(s->avctx, AV_LOG_ERROR, "Invalid mtype index %d\n", + h->mtype); + return SLICE_ERROR; + } h->mtype = h261_mtype_map[h->mtype]; // Read mquant diff --git a/libavcodec/h261enc.c b/libavcodec/h261enc.c index 0110addf73..4968a16d62 100644 --- a/libavcodec/h261enc.c +++ b/libavcodec/h261enc.c @@ -240,7 +240,7 @@ void ff_h261_encode_init(MpegEncContext *s){ if (!done) { done = 1; - init_rl(&h261_rl_tcoeff, ff_h261_rl_table_store); + ff_init_rl(&h261_rl_tcoeff, ff_h261_rl_table_store); } s->min_qcoeff= -127; diff --git a/libavcodec/h263.c b/libavcodec/h263.c index 7c93e9bbe4..5b77106d7d 100644 --- a/libavcodec/h263.c +++ b/libavcodec/h263.c @@ -98,7 +98,7 @@ void ff_h263_update_motion_val(MpegEncContext * s){ } } -int h263_pred_dc(MpegEncContext * s, int n, int16_t **dc_val_ptr) +int ff_h263_pred_dc(MpegEncContext * s, int n, int16_t **dc_val_ptr) { int x, y, wrap, a, c, pred_dc; int16_t *dc_val; @@ -226,7 +226,7 @@ void ff_h263_loop_filter(MpegEncContext * s){ } } -void h263_pred_acdc(MpegEncContext * s, DCTELEM *block, int n) +void ff_h263_pred_acdc(MpegEncContext * s, DCTELEM *block, int n) { int x, y, wrap, a, c, pred_dc, scale, i; int16_t *dc_val, *ac_val, *ac_val1; @@ -313,8 +313,8 @@ void h263_pred_acdc(MpegEncContext * s, DCTELEM *block, int n) ac_val1[8 + i] = block[s->dsp.idct_permutation[i ]]; } -int16_t *h263_pred_motion(MpegEncContext * s, int block, int dir, - int *px, int *py) +int16_t *ff_h263_pred_motion(MpegEncContext * s, int block, int dir, + int *px, int *py) { int wrap; int16_t *A, *B, *C, (*mot_val)[2]; diff --git a/libavcodec/h263.h b/libavcodec/h263.h index 0c11514786..ed9da5352b 100644 --- a/libavcodec/h263.h +++ b/libavcodec/h263.h @@ -38,16 +38,16 @@ extern const AVRational ff_h263_pixel_aspect[16]; extern const uint8_t ff_h263_cbpy_tab[16][2]; -extern const uint8_t cbpc_b_tab[4][2]; +extern const uint8_t ff_cbpc_b_tab[4][2]; -extern const uint8_t mvtab[33][2]; +extern const uint8_t ff_mvtab[33][2]; extern const uint8_t ff_h263_intra_MCBPC_code[9]; extern const uint8_t ff_h263_intra_MCBPC_bits[9]; extern const uint8_t ff_h263_inter_MCBPC_code[28]; extern const uint8_t ff_h263_inter_MCBPC_bits[28]; -extern const uint8_t h263_mbtype_b_tab[15][2]; +extern const uint8_t ff_h263_mbtype_b_tab[15][2]; extern VLC ff_h263_intra_MCBPC_vlc; extern VLC ff_h263_inter_MCBPC_vlc; @@ -55,41 +55,41 @@ extern VLC ff_h263_cbpy_vlc; extern RLTable ff_h263_rl_inter; -extern RLTable rl_intra_aic; +extern RLTable ff_rl_intra_aic; -extern const uint16_t h263_format[8][2]; -extern const uint8_t modified_quant_tab[2][32]; +extern const uint16_t ff_h263_format[8][2]; +extern const uint8_t ff_modified_quant_tab[2][32]; extern const uint16_t ff_mba_max[6]; extern const uint8_t ff_mba_length[7]; extern uint8_t ff_h263_static_rl_table_store[2][2][2*MAX_RUN + MAX_LEVEL + 3]; -int h263_decode_motion(MpegEncContext * s, int pred, int f_code); +int ff_h263_decode_motion(MpegEncContext * s, int pred, int f_code); av_const int ff_h263_aspect_to_info(AVRational aspect); int ff_h263_decode_init(AVCodecContext *avctx); int ff_h263_decode_frame(AVCodecContext *avctx, void *data, int *data_size, AVPacket *avpkt); int ff_h263_decode_end(AVCodecContext *avctx); -void h263_encode_mb(MpegEncContext *s, - DCTELEM block[6][64], - int motion_x, int motion_y); -void h263_encode_picture_header(MpegEncContext *s, int picture_number); -void h263_encode_gob_header(MpegEncContext * s, int mb_line); -int16_t *h263_pred_motion(MpegEncContext * s, int block, int dir, - int *px, int *py); -void h263_encode_init(MpegEncContext *s); -void h263_decode_init_vlc(MpegEncContext *s); -int h263_decode_picture_header(MpegEncContext *s); +void ff_h263_encode_mb(MpegEncContext *s, + DCTELEM block[6][64], + int motion_x, int motion_y); +void ff_h263_encode_picture_header(MpegEncContext *s, int picture_number); +void ff_h263_encode_gob_header(MpegEncContext * s, int mb_line); +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(MpegEncContext *s); +int ff_h263_decode_picture_header(MpegEncContext *s); int ff_h263_decode_gob_header(MpegEncContext *s); void ff_h263_update_motion_val(MpegEncContext * s); void ff_h263_loop_filter(MpegEncContext * s); int ff_h263_decode_mba(MpegEncContext *s); void ff_h263_encode_mba(MpegEncContext *s); void ff_init_qscale_tab(MpegEncContext *s); -int h263_pred_dc(MpegEncContext * s, int n, int16_t **dc_val_ptr); -void h263_pred_acdc(MpegEncContext * s, DCTELEM *block, int n); +int ff_h263_pred_dc(MpegEncContext * s, int n, int16_t **dc_val_ptr); +void ff_h263_pred_acdc(MpegEncContext * s, DCTELEM *block, int n); /** @@ -119,7 +119,7 @@ static inline int h263_get_motion_length(MpegEncContext * s, int val, int f_code int l, bit_size, code; if (val == 0) { - return mvtab[0][1]; + return ff_mvtab[0][1]; } else { bit_size = f_code - 1; /* modulo encoding */ @@ -128,7 +128,7 @@ static inline int h263_get_motion_length(MpegEncContext * s, int val, int f_code val--; code = (val >> bit_size) + 1; - return mvtab[code][1] + 1 + bit_size; + return ff_mvtab[code][1] + 1 + bit_size; } } diff --git a/libavcodec/h263data.h b/libavcodec/h263data.h index 907eae2a65..e245e2f635 100644 --- a/libavcodec/h263data.h +++ b/libavcodec/h263data.h @@ -57,7 +57,7 @@ const uint8_t ff_h263_inter_MCBPC_bits[28] = { 11, 13, 13, 13,/* inter4Q*/ }; -const uint8_t h263_mbtype_b_tab[15][2] = { +const uint8_t ff_h263_mbtype_b_tab[15][2] = { {1, 1}, {3, 3}, {1, 5}, @@ -75,7 +75,7 @@ const uint8_t h263_mbtype_b_tab[15][2] = { {1, 8}, }; -const uint8_t cbpc_b_tab[4][2] = { +const uint8_t ff_cbpc_b_tab[4][2] = { {0, 1}, {2, 2}, {7, 3}, @@ -88,7 +88,7 @@ const uint8_t ff_h263_cbpy_tab[16][2] = {2,5}, {3,6}, {5,4}, {10,4}, {4,4}, {8,4}, {6,4}, {3,2} }; -const uint8_t mvtab[33][2] = +const uint8_t ff_mvtab[33][2] = { {1,1}, {1,2}, {1,3}, {1,4}, {3,6}, {5,7}, {4,7}, {3,7}, {11,9}, {10,9}, {9,9}, {17,10}, {16,10}, {15,10}, {14,10}, {13,10}, @@ -98,7 +98,7 @@ const uint8_t mvtab[33][2] = }; /* third non intra table */ -const uint16_t inter_vlc[103][2] = { +const uint16_t ff_inter_vlc[103][2] = { { 0x2, 2 },{ 0xf, 4 },{ 0x15, 6 },{ 0x17, 7 }, { 0x1f, 8 },{ 0x25, 9 },{ 0x24, 9 },{ 0x21, 10 }, { 0x20, 10 },{ 0x7, 11 },{ 0x6, 11 },{ 0x20, 11 }, @@ -127,7 +127,7 @@ const uint16_t inter_vlc[103][2] = { { 0x5e, 12 },{ 0x5f, 12 },{ 0x3, 7 }, }; -const int8_t inter_level[102] = { +const int8_t ff_inter_level[102] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 1, 2, 3, 4, 5, 6, 1, 2, 3, 4, 1, 2, @@ -143,7 +143,7 @@ const int8_t inter_level[102] = { 1, 1, 1, 1, 1, 1, }; -const int8_t inter_run[102] = { +const int8_t ff_inter_run[102] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, @@ -162,9 +162,9 @@ const int8_t inter_run[102] = { RLTable ff_h263_rl_inter = { 102, 58, - inter_vlc, - inter_run, - inter_level, + ff_inter_vlc, + ff_inter_run, + ff_inter_level, }; static const uint16_t intra_vlc_aic[103][2] = { @@ -228,7 +228,7 @@ static const int8_t intra_level_aic[102] = { 1, 1, 1, 1, 1, 1, }; -RLTable rl_intra_aic = { +RLTable ff_rl_intra_aic = { 102, 58, intra_vlc_aic, @@ -236,7 +236,7 @@ RLTable rl_intra_aic = { intra_level_aic, }; -const uint16_t h263_format[8][2] = { +const uint16_t ff_h263_format[8][2] = { { 0, 0 }, { 128, 96 }, { 176, 144 }, @@ -250,7 +250,7 @@ const uint8_t ff_aic_dc_scale_table[32]={ 0, 2, 4, 6, 8,10,12,14,16,18,20,22,24,26,28,30,32,34,36,38,40,42,44,46,48,50,52,54,56,58,60,62 }; -const uint8_t modified_quant_tab[2][32]={ +const uint8_t ff_modified_quant_tab[2][32]={ // 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 { 0, 3, 1, 2, 3, 4, 5, 6, 7, 8, 9, 9,10,11,12,13,14,15,16,17,18,18,19,20,21,22,23,24,25,26,27,28 diff --git a/libavcodec/h263dec.c b/libavcodec/h263dec.c index 621f7ad9f2..07fa430ce6 100644 --- a/libavcodec/h263dec.c +++ b/libavcodec/h263dec.c @@ -115,7 +115,7 @@ av_cold int ff_h263_decode_init(AVCodecContext *avctx) if (MPV_common_init(s) < 0) return -1; - h263_decode_init_vlc(s); + ff_h263_decode_init_vlc(s); return 0; } @@ -435,7 +435,7 @@ retry: } else if (CONFIG_FLV_DECODER && s->h263_flv) { ret = ff_flv_decode_picture_header(s); } else { - ret = h263_decode_picture_header(s); + ret = ff_h263_decode_picture_header(s); } if(ret==FRAME_SKIPPED) return get_consumed_bytes(s, buf_size); @@ -444,6 +444,13 @@ retry: if (ret < 0){ av_log(s->avctx, AV_LOG_ERROR, "header damaged\n"); return -1; + } else if ((s->width != avctx->coded_width || + s->height != avctx->coded_height || + (s->width + 15) >> 4 != s->mb_width || + (s->height + 15) >> 4 != s->mb_height) && + (HAVE_THREADS && (s->avctx->active_thread_type & FF_THREAD_FRAME))) { + av_log_missing_feature(s->avctx, "Width/height/bit depth/chroma idc changing with threads is", 0); + return AVERROR_PATCHWELCOME; // width / height changed during parallelized decoding } avctx->has_b_frames= !s->low_delay; @@ -571,7 +578,6 @@ retry: if (s->codec_id == CODEC_ID_MPEG4 && s->xvid_build>=0 && avctx->idct_algo == FF_IDCT_AUTO && (av_get_cpu_flags() & AV_CPU_FLAG_MMX)) { avctx->idct_algo= FF_IDCT_XVIDMMX; ff_dct_common_init(s); - s->picture_number=0; } #endif @@ -664,7 +670,7 @@ retry: ret = decode_slice(s); while(s->mb_ymb_height){ if(s->msmpeg4_version){ - if(s->slice_height==0 || s->mb_x!=0 || (s->mb_y%s->slice_height)!=0 || get_bits_count(&s->gb) > s->gb.size_in_bits) + if(s->slice_height==0 || s->mb_x!=0 || (s->mb_y%s->slice_height)!=0 || get_bits_left(&s->gb)<0) break; }else{ int prev_x=s->mb_x, prev_y=s->mb_y; diff --git a/libavcodec/h264.c b/libavcodec/h264.c index 2b18b06f69..988e8195b2 100644 --- a/libavcodec/h264.c +++ b/libavcodec/h264.c @@ -104,12 +104,12 @@ int ff_h264_check_intra4x4_pred_mode(H264Context *h){ return 0; } //FIXME cleanup like check_intra_pred_mode -static int check_intra_pred_mode(H264Context *h, int mode, int is_chroma){ +int ff_h264_check_intra_pred_mode(H264Context *h, int mode, int is_chroma){ MpegEncContext * const s = &h->s; - static const int8_t top [7]= {LEFT_DC_PRED8x8, 1,-1,-1}; - static const int8_t left[7]= { TOP_DC_PRED8x8,-1, 2,-1,DC_128_PRED8x8}; + static const int8_t top[4] = { LEFT_DC_PRED8x8, 1, -1, -1 }; + static const int8_t left[5] = { TOP_DC_PRED8x8, -1, 2, -1, DC_128_PRED8x8 }; - if(mode > 6U) { + if(mode > 3U) { av_log(h->s.avctx, AV_LOG_ERROR, "out of range intra chroma pred mode at %d %d\n", s->mb_x, s->mb_y); return -1; } @@ -136,22 +136,6 @@ static int check_intra_pred_mode(H264Context *h, int mode, int is_chroma){ return mode; } -/** - * checks if the top & left blocks are available if needed & changes the dc mode so it only uses the available blocks. - */ -int ff_h264_check_intra16x16_pred_mode(H264Context *h, int mode) -{ - return check_intra_pred_mode(h, mode, 0); -} - -/** - * checks if the top & left blocks are available if needed & changes the dc mode so it only uses the available blocks. - */ -int ff_h264_check_intra_chroma_pred_mode(H264Context *h, int mode) -{ - return check_intra_pred_mode(h, mode, 1); -} - const uint8_t *ff_h264_decode_nal(H264Context *h, const uint8_t *src, int *dst_length, int *consumed, int length){ int i, si, di; @@ -1240,6 +1224,19 @@ static int decode_update_thread_context(AVCodecContext *dst, const AVCodecContex memcpy(&h->s + 1, &h1->s + 1, sizeof(H264Context) - sizeof(MpegEncContext)); //copy all fields after MpegEnc memset(h->sps_buffers, 0, sizeof(h->sps_buffers)); memset(h->pps_buffers, 0, sizeof(h->pps_buffers)); + + h->intra4x4_pred_mode= NULL; + h->non_zero_count = NULL; + h->slice_table_base = NULL; + h->slice_table = NULL; + h->cbp_table = NULL; + h->chroma_pred_mode_table = NULL; + memset(h->mvd_table, 0, sizeof(h->mvd_table)); + h->direct_table = NULL; + h->list_counts = NULL; + h->mb2b_xy = NULL; + h->mb2br_xy = NULL; + if (ff_h264_alloc_tables(h) < 0) { av_log(dst, AV_LOG_ERROR, "Could not allocate memory for h264\n"); return AVERROR(ENOMEM); @@ -1316,6 +1313,8 @@ int ff_h264_frame_start(H264Context *h){ int i; const int pixel_shift = h->pixel_shift; + h->next_output_pic = NULL; + if(MPV_frame_start(s, s->avctx) < 0) return -1; ff_er_frame_start(s); @@ -1365,8 +1364,6 @@ int ff_h264_frame_start(H264Context *h){ s->current_picture_ptr->field_poc[0]= s->current_picture_ptr->field_poc[1]= INT_MAX; - h->next_output_pic = NULL; - assert(s->current_picture_ptr->long_ref==0); return 0; @@ -2522,8 +2519,8 @@ static int field_end(H264Context *h, int in_setup){ s->mb_y= 0; if (!in_setup && !s->dropable) - ff_thread_report_progress((AVFrame*)s->current_picture_ptr, (16*s->mb_height >> FIELD_PICTURE) - 1, - s->picture_structure==PICT_BOTTOM_FIELD); + ff_thread_report_progress(&s->current_picture_ptr->f, INT_MAX, + s->picture_structure == PICT_BOTTOM_FIELD); if (CONFIG_H264_VDPAU_DECODER && s->avctx->codec->capabilities&CODEC_CAP_HWACCEL_VDPAU) ff_vdpau_h264_set_reference_frames(s); @@ -2623,6 +2620,52 @@ int ff_h264_get_profile(SPS *sps) return profile; } +static int h264_set_parameter_from_sps(H264Context *h) +{ + MpegEncContext *s = &h->s; + + if (s->flags & CODEC_FLAG_LOW_DELAY || + (h->sps.bitstream_restriction_flag && + !h->sps.num_reorder_frames)) { + if (s->avctx->has_b_frames > 1 || h->delayed_pic[0]) + av_log(h->s.avctx, AV_LOG_WARNING, "Delayed frames seen. " + "Reenabling low delay requires a codec flush.\n"); + else + s->low_delay = 1; + } + + if (s->avctx->has_b_frames < 2) + s->avctx->has_b_frames = !s->low_delay; + + if (s->avctx->bits_per_raw_sample != h->sps.bit_depth_luma || + h->cur_chroma_format_idc != h->sps.chroma_format_idc) { + if (s->avctx->codec && + s->avctx->codec->capabilities & CODEC_CAP_HWACCEL_VDPAU && + (h->sps.bit_depth_luma != 8 || h->sps.chroma_format_idc > 1)) { + av_log(s->avctx, AV_LOG_ERROR, + "VDPAU decoding does not support video colorspace.\n"); + return AVERROR_INVALIDDATA; + } + if (h->sps.bit_depth_luma >= 8 && h->sps.bit_depth_luma <= 10) { + s->avctx->bits_per_raw_sample = h->sps.bit_depth_luma; + h->cur_chroma_format_idc = h->sps.chroma_format_idc; + h->pixel_shift = h->sps.bit_depth_luma > 8; + + ff_h264dsp_init(&h->h264dsp, h->sps.bit_depth_luma, + h->sps.chroma_format_idc); + ff_h264_pred_init(&h->hpc, s->codec_id, h->sps.bit_depth_luma, + h->sps.chroma_format_idc); + s->dsp.dct_bits = h->sps.bit_depth_luma > 8 ? 32 : 16; + dsputil_init(&s->dsp, s->avctx); + } else { + av_log(s->avctx, AV_LOG_ERROR, "Unsupported bit depth: %d\n", + h->sps.bit_depth_luma); + return AVERROR_INVALIDDATA; + } + } + return 0; +} + /** * Decode a slice header. * This will also call MPV_common_init() and frame_start() as needed. @@ -2640,9 +2683,7 @@ static int decode_slice_header(H264Context *h, H264Context *h0){ int num_ref_idx_active_override_flag; unsigned int slice_type, tmp, i, j; int default_ref_list_done = 0; - int last_pic_structure; - - s->dropable= h->nal_ref_idc == 0; + int last_pic_structure, last_pic_dropable, ret; /* FIXME: 2tap qpel isn't implemented for high bit depth. */ if((s->avctx->flags2 & CODEC_FLAG2_FAST) && !h->nal_ref_idc && !h->pixel_shift){ @@ -2661,8 +2702,14 @@ static int decode_slice_header(H264Context *h, H264Context *h0){ } h0->current_slice = 0; - if (!s0->first_field) - s->current_picture_ptr= NULL; + if (!s0->first_field) { + if (s->current_picture_ptr && !s->dropable && + s->current_picture_ptr->owner2 == s) { + ff_thread_report_progress(&s->current_picture_ptr->f, INT_MAX, + s->picture_structure == PICT_BOTTOM_FIELD); + } + s->current_picture_ptr = NULL; + } } slice_type= get_ue_golomb_31(&s->gb); @@ -2684,7 +2731,14 @@ static int decode_slice_header(H264Context *h, H264Context *h0){ h->slice_type= slice_type; h->slice_type_nos= slice_type & 3; - s->pict_type= h->slice_type; // to make a few old functions happy, it's wrong though + if (h->nal_unit_type == NAL_IDR_SLICE && + h->slice_type_nos != AV_PICTURE_TYPE_I) { + av_log(h->s.avctx, AV_LOG_ERROR, "A non-intra slice in an IDR NAL unit.\n"); + return AVERROR_INVALIDDATA; + } + + // to make a few old functions happy, it's wrong though + s->pict_type = h->slice_type; pps_id= get_ue_golomb(&s->gb); if(pps_id>=MAX_PPS_COUNT){ @@ -2701,17 +2755,22 @@ static int decode_slice_header(H264Context *h, H264Context *h0){ av_log(h->s.avctx, AV_LOG_ERROR, "non-existing SPS %u referenced\n", h->pps.sps_id); return -1; } - h->sps = *h0->sps_buffers[h->pps.sps_id]; + + if (h->pps.sps_id != h->current_sps_id || + h0->sps_buffers[h->pps.sps_id]->new) { + h0->sps_buffers[h->pps.sps_id]->new = 0; + + h->current_sps_id = h->pps.sps_id; + h->sps = *h0->sps_buffers[h->pps.sps_id]; + + if ((ret = h264_set_parameter_from_sps(h)) < 0) + return ret; + } s->avctx->profile = ff_h264_get_profile(&h->sps); s->avctx->level = h->sps.level_idc; s->avctx->refs = h->sps.ref_frame_count; - if(h == h0 && h->dequant_coeff_pps != pps_id){ - h->dequant_coeff_pps = pps_id; - init_dequant_tables(h); - } - s->mb_width= h->sps.mb_width; s->mb_height= h->sps.mb_height * (2 - h->sps.frame_mbs_only_flag); @@ -2727,9 +2786,9 @@ static int decode_slice_header(H264Context *h, H264Context *h0){ || s->avctx->bits_per_raw_sample != h->sps.bit_depth_luma || h->cur_chroma_format_idc != h->sps.chroma_format_idc || av_cmp_q(h->sps.sar, s->avctx->sample_aspect_ratio))) { - if(h != h0 || (s->avctx->active_thread_type & FF_THREAD_FRAME)) { + if(h != h0 || (HAVE_THREADS && h->s.avctx->active_thread_type & FF_THREAD_FRAME)) { av_log_missing_feature(s->avctx, "Width/height/bit depth/chroma idc changing with threads is", 0); - return -1; // width / height changed during parallelized decoding + return AVERROR_PATCHWELCOME; // width / height changed during parallelized decoding } free_tables(h, 0); flush_dpb(s->avctx); @@ -2806,7 +2865,7 @@ static int decode_slice_header(H264Context *h, H264Context *h0){ else s->avctx->pix_fmt = PIX_FMT_YUV420P10; break; - default: + case 8: if (CHROMA444){ s->avctx->pix_fmt = s->avctx->color_range == AVCOL_RANGE_JPEG ? PIX_FMT_YUVJ444P : PIX_FMT_YUV444P; if (s->avctx->colorspace == AVCOL_SPC_RGB) { @@ -2825,6 +2884,11 @@ static int decode_slice_header(H264Context *h, H264Context *h0){ hwaccel_pixfmt_list_h264_jpeg_420 : ff_hwaccel_pixfmt_list_420); } + break; + default: + av_log(s->avctx, AV_LOG_ERROR, + "Unsupported bit depth: %d\n", h->sps.bit_depth_luma); + return AVERROR_INVALIDDATA; } s->avctx->hwaccel = ff_find_hwaccel(s->avctx->codec->id, s->avctx->pix_fmt); @@ -2870,11 +2934,18 @@ static int decode_slice_header(H264Context *h, H264Context *h0){ } } + if(h == h0 && h->dequant_coeff_pps != pps_id){ + h->dequant_coeff_pps = pps_id; + init_dequant_tables(h); + } + h->frame_num= get_bits(&s->gb, h->sps.log2_max_frame_num); h->mb_mbaff = 0; h->mb_aff_frame = 0; last_pic_structure = s0->picture_structure; + last_pic_dropable = s0->dropable; + s->dropable = h->nal_ref_idc == 0; if(h->sps.frame_mbs_only_flag){ s->picture_structure= PICT_FRAME; }else{ @@ -2891,10 +2962,27 @@ static int decode_slice_header(H264Context *h, H264Context *h0){ } h->mb_field_decoding_flag= s->picture_structure != PICT_FRAME; - if(h0->current_slice == 0){ - // Shorten frame num gaps so we don't have to allocate reference frames just to throw them away - if(h->frame_num != h->prev_frame_num && h->prev_frame_num >= 0) { - int unwrap_prev_frame_num = h->prev_frame_num, max_frame_num = 1<sps.log2_max_frame_num; + if (h0->current_slice != 0) { + if (last_pic_structure != s->picture_structure || + last_pic_dropable != s->dropable) { + av_log(h->s.avctx, AV_LOG_ERROR, + "Changing field mode (%d -> %d) between slices is not allowed\n", + last_pic_structure, s->picture_structure); + s->picture_structure = last_pic_structure; + s->dropable = last_pic_dropable; + return AVERROR_INVALIDDATA; + } else if (!s0->current_picture_ptr) { + av_log(s->avctx, AV_LOG_ERROR, + "unset current_picture_ptr on %d. slice\n", + h0->current_slice + 1); + return AVERROR_INVALIDDATA; + } + } else { + /* Shorten frame num gaps so we don't have to allocate reference + * frames just to throw them away */ + if (h->frame_num != h->prev_frame_num && h->prev_frame_num >= 0) { + int unwrap_prev_frame_num = h->prev_frame_num; + int max_frame_num = 1 << h->sps.log2_max_frame_num; if (unwrap_prev_frame_num > h->frame_num) unwrap_prev_frame_num -= max_frame_num; @@ -2907,12 +2995,80 @@ static int decode_slice_header(H264Context *h, H264Context *h0){ } } - while(h->frame_num != h->prev_frame_num && h->prev_frame_num >= 0 && - h->frame_num != (h->prev_frame_num+1)%(1<sps.log2_max_frame_num)){ + /* See if we have a decoded first field looking for a pair... + * Here, we're using that to see if we should mark previously + * decode frames as "finished". + * We have to do that before the "dummy" in-between frame allocation, + * since that can modify s->current_picture_ptr. */ + if (s0->first_field) { + assert(s0->current_picture_ptr); + assert(s0->current_picture_ptr->f.data[0]); + assert(s0->current_picture_ptr->f.reference != DELAYED_PIC_REF); + + /* Mark old field/frame as completed */ + if (!last_pic_dropable && s0->current_picture_ptr->owner2 == s0) { + ff_thread_report_progress(&s0->current_picture_ptr->f, INT_MAX, + last_pic_structure == PICT_BOTTOM_FIELD); + } + + /* figure out if we have a complementary field pair */ + if (!FIELD_PICTURE || s->picture_structure == last_pic_structure) { + /* Previous field is unmatched. Don't display it, but let it + * remain for reference if marked as such. */ + if (!last_pic_dropable && last_pic_structure != PICT_FRAME) { + ff_thread_report_progress(&s0->current_picture_ptr->f, INT_MAX, + last_pic_structure == PICT_TOP_FIELD); + } + } else { + if (s0->current_picture_ptr->frame_num != h->frame_num) { + /* This and previous field were reference, but had + * different frame_nums. Consider this field first in + * pair. Throw away previous field except for reference + * purposes. */ + if (!last_pic_dropable && last_pic_structure != PICT_FRAME) { + ff_thread_report_progress(&s0->current_picture_ptr->f, INT_MAX, + last_pic_structure == PICT_TOP_FIELD); + } + } else { + /* Second field in complementary pair */ + if (!((last_pic_structure == PICT_TOP_FIELD && + s->picture_structure == PICT_BOTTOM_FIELD) || + (last_pic_structure == PICT_BOTTOM_FIELD && + s->picture_structure == PICT_TOP_FIELD))) { + av_log(s->avctx, AV_LOG_ERROR, + "Invalid field mode combination %d/%d\n", + last_pic_structure, s->picture_structure); + s->picture_structure = last_pic_structure; + s->dropable = last_pic_dropable; + return AVERROR_INVALIDDATA; + } else if (last_pic_dropable != s->dropable) { + av_log(s->avctx, AV_LOG_ERROR, + "Cannot combine reference and non-reference fields in the same frame\n"); + av_log_ask_for_sample(s->avctx, NULL); + s->picture_structure = last_pic_structure; + s->dropable = last_pic_dropable; + return AVERROR_INVALIDDATA; + } + + /* Take ownership of this buffer. Note that if another thread owned + * the first field of this buffer, we're not operating on that pointer, + * so the original thread is still responsible for reporting progress + * on that first field (or if that was us, we just did that above). + * By taking ownership, we assign responsibility to ourselves to + * report progress on the second field. */ + s0->current_picture_ptr->owner2 = s0; + } + } + } + + while (h->frame_num != h->prev_frame_num && h->prev_frame_num >= 0 && + h->frame_num != (h->prev_frame_num + 1) % (1 << h->sps.log2_max_frame_num)) { Picture *prev = h->short_ref_count ? h->short_ref[0] : NULL; av_log(h->s.avctx, AV_LOG_DEBUG, "Frame num gap %d %d\n", h->frame_num, h->prev_frame_num); - if (ff_h264_frame_start(h) < 0) + if (ff_h264_frame_start(h) < 0) { + h0->s.first_field = 0; return -1; + } h->prev_frame_num++; h->prev_frame_num %= 1<sps.log2_max_frame_num; s->current_picture_ptr->frame_num= h->prev_frame_num; @@ -2939,7 +3095,9 @@ static int decode_slice_header(H264Context *h, H264Context *h0){ } } - /* See if we have a decoded first field looking for a pair... */ + /* See if we have a decoded first field looking for a pair... + * We're using that to see whether to continue decoding in that + * frame, or to allocate a new one. */ if (s0->first_field) { assert(s0->current_picture_ptr); assert(s0->current_picture_ptr->f.data[0]); @@ -2956,13 +3114,10 @@ static int decode_slice_header(H264Context *h, H264Context *h0){ } else { if (s0->current_picture_ptr->frame_num != h->frame_num) { - /* - * This and previous field had - * different frame_nums. Consider this field first in - * pair. Throw away previous field except for reference - * purposes. - */ - s0->first_field = 1; + /* This and the previous field had different frame_nums. + * Consider this field first in pair. Throw away previous + * one except for reference purposes. */ + s0->first_field = 1; s0->current_picture_ptr = NULL; } else { @@ -2973,7 +3128,6 @@ static int decode_slice_header(H264Context *h, H264Context *h0){ } else { /* Frame or first field in a potentially complementary pair */ - assert(!s0->current_picture_ptr); s0->first_field = FIELD_PICTURE; } @@ -3041,7 +3195,8 @@ static int decode_slice_header(H264Context *h, H264Context *h0){ h->ref_count[1]= h->pps.ref_count[1]; if(h->slice_type_nos != AV_PICTURE_TYPE_I){ - unsigned max= (16<<(s->picture_structure != PICT_FRAME))-1; + unsigned max= s->picture_structure == PICT_FRAME ? 15 : 31; + if(h->slice_type_nos == AV_PICTURE_TYPE_B){ h->direct_spatial_mv_pred= get_bits1(&s->gb); } @@ -3049,15 +3204,21 @@ static int decode_slice_header(H264Context *h, H264Context *h0){ if(num_ref_idx_active_override_flag){ h->ref_count[0]= get_ue_golomb(&s->gb) + 1; - if(h->slice_type_nos==AV_PICTURE_TYPE_B) + if (h->ref_count[0] < 1) + return AVERROR_INVALIDDATA; + if (h->slice_type_nos == AV_PICTURE_TYPE_B) { h->ref_count[1]= get_ue_golomb(&s->gb) + 1; + if (h->ref_count[1] < 1) + return AVERROR_INVALIDDATA; + } + } - } - if(h->ref_count[0]-1 > max || h->ref_count[1]-1 > max){ + if (h->ref_count[0]-1 > max || h->ref_count[1]-1 > max){ av_log(h->s.avctx, AV_LOG_ERROR, "reference overflow\n"); - h->ref_count[0]= h->ref_count[1]= 1; - return -1; + h->ref_count[0] = h->ref_count[1] = 1; + return AVERROR_INVALIDDATA; } + if(h->slice_type_nos == AV_PICTURE_TYPE_B) h->list_count= 2; else @@ -3140,8 +3301,8 @@ static int decode_slice_header(H264Context *h, H264Context *h0){ } h->deblocking_filter = 1; - h->slice_alpha_c0_offset = 52; - h->slice_beta_offset = 52; + h->slice_alpha_c0_offset = 0; + h->slice_beta_offset = 0; if( h->pps.deblocking_filter_parameters_present ) { tmp= get_ue_golomb_31(&s->gb); if(tmp > 2){ @@ -3152,12 +3313,16 @@ static int decode_slice_header(H264Context *h, H264Context *h0){ if(h->deblocking_filter < 2) h->deblocking_filter^= 1; // 1<->0 - if( h->deblocking_filter ) { - h->slice_alpha_c0_offset += get_se_golomb(&s->gb) << 1; - h->slice_beta_offset += get_se_golomb(&s->gb) << 1; - if( h->slice_alpha_c0_offset > 104U - || h->slice_beta_offset > 104U){ - av_log(s->avctx, AV_LOG_ERROR, "deblocking filter parameters %d %d out of range\n", h->slice_alpha_c0_offset, h->slice_beta_offset); + if (h->deblocking_filter) { + h->slice_alpha_c0_offset = get_se_golomb(&s->gb) * 2; + h->slice_beta_offset = get_se_golomb(&s->gb) * 2; + if (h->slice_alpha_c0_offset > 12 || + h->slice_alpha_c0_offset < -12 || + h->slice_beta_offset > 12 || + h->slice_beta_offset < -12) { + av_log(s->avctx, AV_LOG_ERROR, + "deblocking filter parameters %d %d out of range\n", + h->slice_alpha_c0_offset, h->slice_beta_offset); return -1; } } @@ -3186,14 +3351,12 @@ static int decode_slice_header(H264Context *h, H264Context *h0){ } } } - h->qp_thresh = 15 + 52 - FFMIN(h->slice_alpha_c0_offset, h->slice_beta_offset) - - FFMAX3(0, h->pps.chroma_qp_index_offset[0], h->pps.chroma_qp_index_offset[1]) - + 6 * (h->sps.bit_depth_luma - 8); - -#if 0 //FMO - if( h->pps.num_slice_groups > 1 && h->pps.mb_slice_group_map_type >= 3 && h->pps.mb_slice_group_map_type <= 5) - slice_group_change_cycle= get_bits(&s->gb, ?); -#endif + h->qp_thresh = 15 - + FFMIN(h->slice_alpha_c0_offset, h->slice_beta_offset) - + FFMAX3(0, + h->pps.chroma_qp_index_offset[0], + h->pps.chroma_qp_index_offset[1]) + + 6 * (h->sps.bit_depth_luma - 8); h0->last_slice_type = slice_type; h->slice_num = ++h0->current_slice; @@ -3254,7 +3417,8 @@ static int decode_slice_header(H264Context *h, H264Context *h0){ s->current_picture_ptr->field_poc[0], s->current_picture_ptr->field_poc[1], h->ref_count[0], h->ref_count[1], s->qscale, - h->deblocking_filter, h->slice_alpha_c0_offset/2-26, h->slice_beta_offset/2-26, + h->deblocking_filter, + h->slice_alpha_c0_offset, h->slice_beta_offset, h->use_weight, h->use_weight==1 && h->use_weight_chroma ? "c" : "", h->slice_type == AV_PICTURE_TYPE_B ? (h->direct_spatial_mv_pred ? "SPAT" : "TEMP") : "" @@ -3694,22 +3858,23 @@ static int decode_slice(struct AVCodecContext *avctx, void *arg){ if(s->mb_y >= s->mb_height){ tprintf(s->avctx, "slice end %d %d\n", get_bits_count(&s->gb), s->gb.size_in_bits); - if( get_bits_count(&s->gb) == s->gb.size_in_bits - || get_bits_count(&s->gb) < s->gb.size_in_bits && s->avctx->error_recognition < FF_ER_AGGRESSIVE) { + if ( get_bits_left(&s->gb) == 0 + || get_bits_left(&s->gb) > 0 && !(s->avctx->err_recognition & AV_EF_AGGRESSIVE)) { ff_er_add_slice(s, s->resync_mb_x, s->resync_mb_y, s->mb_x-1, s->mb_y, ER_MB_END&part_mask); return 0; - }else{ - ff_er_add_slice(s, s->resync_mb_x, s->resync_mb_y, s->mb_x, s->mb_y, ER_MB_END&part_mask); - + } else { + ff_er_add_slice(s, s->resync_mb_x, s->resync_mb_y, + s->mb_x, s->mb_y, + ER_MB_END & part_mask); return -1; } } } - if(get_bits_count(&s->gb) >= s->gb.size_in_bits && s->mb_skip_run<=0){ + if (get_bits_left(&s->gb) <= 0 && s->mb_skip_run <= 0){ tprintf(s->avctx, "slice end %d %d\n", get_bits_count(&s->gb), s->gb.size_in_bits); - if(get_bits_count(&s->gb) == s->gb.size_in_bits ){ + if (get_bits_left(&s->gb) == 0) { ff_er_add_slice(s, s->resync_mb_x, s->resync_mb_y, s->mb_x-1, s->mb_y, ER_MB_END&part_mask); if (s->mb_x > lf_x_start) loop_filter(h, lf_x_start, s->mb_x); @@ -3736,6 +3901,12 @@ static int execute_decode_slices(H264Context *h, int context_count){ H264Context *hx; int i; + if (s->mb_y >= s->mb_height) { + av_log(s->avctx, AV_LOG_ERROR, + "Input contains more MB rows than the frame height.\n"); + return AVERROR_INVALIDDATA; + } + if (s->avctx->hwaccel || s->avctx->codec->capabilities&CODEC_CAP_HWACCEL_VDPAU) return 0; if(context_count == 1) { @@ -3798,7 +3969,7 @@ static int decode_nal_units(H264Context *h, const uint8_t *buf, int buf_size){ int consumed; int dst_length; int bit_length; - uint8_t *ptr; + const uint8_t *ptr; int i, nalsize = 0; int err; @@ -3820,7 +3991,11 @@ static int decode_nal_units(H264Context *h, const uint8_t *buf, int buf_size){ break; } - if(buf_index+3 >= buf_size) break; + + if (buf_index + 3 >= buf_size) { + buf_index = buf_size; + break; + } buf_index+=3; if(buf_index >= next_avc) continue; @@ -3829,8 +4004,9 @@ static int decode_nal_units(H264Context *h, const uint8_t *buf, int buf_size){ hx = h->thread_context[context_count]; ptr= ff_h264_decode_nal(hx, buf + buf_index, &dst_length, &consumed, next_avc - buf_index); - if (ptr==NULL || dst_length < 0){ - return -1; + if (ptr == NULL || dst_length < 0) { + buf_index = -1; + goto end; } i= buf_index + consumed; if((s->workaround_bugs & FF_BUG_AUTODETECT) && i+3nal_unit_type != NAL_IDR_SLICE) { av_log(h->s.avctx, AV_LOG_ERROR, "Invalid mix of idr and non-idr slices\n"); - return -1; + buf_index = -1; + goto end; } idr(h); // FIXME ensure we don't lose some frames if there is reordering case NAL_SLICE: @@ -3942,12 +4119,24 @@ static int decode_nal_units(H264Context *h, const uint8_t *buf, int buf_size){ } break; case NAL_DPA: + if (s->flags2 & CODEC_FLAG2_CHUNKS) { + av_log(h->s.avctx, AV_LOG_ERROR, + "Decoding in chunks is not supported for " + "partitioned slices.\n"); + return AVERROR(ENOSYS); + } + init_get_bits(&hx->s.gb, ptr, bit_length); hx->intra_gb_ptr= hx->inter_gb_ptr= NULL; - if ((err = decode_slice_header(hx, h)) < 0) + if ((err = decode_slice_header(hx, h)) < 0) { + /* make sure data_partitioning is cleared if it was set + * before, so we don't try decoding a slice without a valid + * slice header later */ + s->data_partitioning = 0; break; + } hx->s.data_partitioning = 1; @@ -3961,6 +4150,7 @@ static int decode_nal_units(H264Context *h, const uint8_t *buf, int buf_size){ hx->inter_gb_ptr= &hx->inter_gb; if(hx->redundant_pic_count==0 && hx->intra_gb_ptr && hx->s.data_partitioning + && s->current_picture_ptr && s->context_initialized && (avctx->skip_frame < AVDISCARD_NONREF || hx->nal_ref_idc) && (avctx->skip_frame < AVDISCARD_BIDIR || hx->slice_type_nos!=AV_PICTURE_TYPE_B) @@ -3974,19 +4164,17 @@ static int decode_nal_units(H264Context *h, const uint8_t *buf, int buf_size){ break; case NAL_SPS: init_get_bits(&s->gb, ptr, bit_length); - if(ff_h264_decode_seq_parameter_set(h) < 0 && (h->is_avc ? (nalsize != consumed) && nalsize : 1)){ + if (ff_h264_decode_seq_parameter_set(h) < 0 && (h->is_avc ? (nalsize != consumed) && nalsize : 1)){ av_log(h->s.avctx, AV_LOG_DEBUG, "SPS decoding failure, trying alternative mode\n"); if(h->is_avc) av_assert0(next_avc - buf_index + consumed == nalsize); - init_get_bits(&s->gb, &buf[buf_index + 1 - consumed], 8*(next_avc - buf_index + consumed)); + init_get_bits(&s->gb, &buf[buf_index + 1 - consumed], 8*(next_avc - buf_index + consumed - 1)); ff_h264_decode_seq_parameter_set(h); } - if (s->flags& CODEC_FLAG_LOW_DELAY || - (h->sps.bitstream_restriction_flag && !h->sps.num_reorder_frames)) - s->low_delay=1; - - if(avctx->has_b_frames < 2) - avctx->has_b_frames= !s->low_delay; + if (h264_set_parameter_from_sps(h) < 0) { + buf_index = -1; + goto end; + } break; case NAL_PPS: init_get_bits(&s->gb, ptr, bit_length); @@ -4010,9 +4198,10 @@ static int decode_nal_units(H264Context *h, const uint8_t *buf, int buf_size){ context_count = 0; } - if (err < 0) + if (err < 0) { av_log(h->s.avctx, AV_LOG_ERROR, "decode_slice_header error\n"); - else if(err == 1) { + h->ref_count[0] = h->ref_count[1] = h->list_count = 0; + } else if (err == 1) { /* Slice could not be decoded in parallel mode, copy down * NAL unit stuff to context 0 and restart. Note that * rbsp_buffer is not transferred, but since we no longer @@ -4026,6 +4215,15 @@ static int decode_nal_units(H264Context *h, const uint8_t *buf, int buf_size){ } if(context_count) execute_decode_slices(h, context_count); + +end: + /* clean up */ + if (s->current_picture_ptr && s->current_picture_ptr->owner2 == s && + !s->dropable) { + ff_thread_report_progress(&s->current_picture_ptr->f, INT_MAX, + s->picture_structure == PICT_BOTTOM_FIELD); + } + return buf_index; } @@ -4054,6 +4252,9 @@ static int decode_frame(AVCodecContext *avctx, s->flags= avctx->flags; s->flags2= avctx->flags2; + /* reset data partitioning here, to ensure GetBitContexts from previous + * packets do not get used. */ + s->data_partitioning = 0; /* end of stream, output what is still in the buffers */ if (buf_size == 0) { diff --git a/libavcodec/h264.h b/libavcodec/h264.h index 495439f738..0a645f4e45 100644 --- a/libavcodec/h264.h +++ b/libavcodec/h264.h @@ -206,6 +206,7 @@ typedef struct SPS{ int bit_depth_chroma; ///< bit_depth_chroma_minus8 + 8 int residual_color_transform_flag; ///< residual_colour_transform_flag int constraint_set_flags; ///< constraint_set[0-3]_flag + int new; ///< flag to keep track if the decoder context needs re-init due to changed SPS }SPS; /** @@ -332,6 +333,7 @@ typedef struct H264Context{ int emu_edge_width; int emu_edge_height; + unsigned current_sps_id; ///< id of the current SPS SPS sps; ///< current sps /** @@ -671,15 +673,7 @@ void ff_generate_sliding_window_mmcos(H264Context *h); */ int ff_h264_check_intra4x4_pred_mode(H264Context *h); -/** - * Check if the top & left blocks are available if needed & change the dc mode so it only uses the available blocks. - */ -int ff_h264_check_intra16x16_pred_mode(H264Context *h, int mode); - -/** - * Check if the top & left blocks are available if needed & change the dc mode so it only uses the available blocks. - */ -int ff_h264_check_intra_chroma_pred_mode(H264Context *h, int mode); +int ff_h264_check_intra_pred_mode(H264Context *h, int mode, int is_chroma); void ff_h264_hl_decode_mb(H264Context *h); int ff_h264_frame_start(H264Context *h); diff --git a/libavcodec/h264_cabac.c b/libavcodec/h264_cabac.c index cde569bc08..e06e984b78 100644 --- a/libavcodec/h264_cabac.c +++ b/libavcodec/h264_cabac.c @@ -1721,7 +1721,7 @@ decode_cabac_residual_internal(H264Context *h, DCTELEM *block, \ if( coeff_abs >= 15 ) { \ int j = 0; \ - while( get_cabac_bypass( CC ) ) { \ + while (get_cabac_bypass(CC) && j < 30) { \ j++; \ } \ \ @@ -1998,6 +1998,8 @@ decode_intra_mb: } // The pixels are stored in the same order as levels in h->mb array. + if ((int) (h->cabac.bytestream_end - ptr) < mb_size) + return -1; memcpy(h->mb, ptr, mb_size); ptr+=mb_size; ff_init_cabac_decoder(&h->cabac, ptr, h->cabac.bytestream_end - ptr); @@ -2042,14 +2044,14 @@ decode_intra_mb: write_back_intra_pred_mode(h); if( ff_h264_check_intra4x4_pred_mode(h) < 0 ) return -1; } else { - h->intra16x16_pred_mode= ff_h264_check_intra16x16_pred_mode( h, h->intra16x16_pred_mode ); + h->intra16x16_pred_mode= ff_h264_check_intra_pred_mode( h, h->intra16x16_pred_mode, 0 ); if( h->intra16x16_pred_mode < 0 ) return -1; } if(decode_chroma){ h->chroma_pred_mode_table[mb_xy] = pred_mode = decode_cabac_mb_chroma_pre_mode( h ); - pred_mode= ff_h264_check_intra_chroma_pred_mode( h, pred_mode ); + pred_mode= ff_h264_check_intra_pred_mode( h, pred_mode, 1 ); if( pred_mode < 0 ) return -1; h->chroma_pred_mode= pred_mode; } else { diff --git a/libavcodec/h264_cavlc.c b/libavcodec/h264_cavlc.c index f9daeb29d9..e43b937a8f 100644 --- a/libavcodec/h264_cavlc.c +++ b/libavcodec/h264_cavlc.c @@ -708,7 +708,7 @@ int ff_h264_decode_mb_cavlc(H264Context *h){ down the code */ if(h->slice_type_nos != AV_PICTURE_TYPE_I){ if(s->mb_skip_run==-1) - s->mb_skip_run= get_ue_golomb(&s->gb); + s->mb_skip_run= get_ue_golomb_long(&s->gb); if (s->mb_skip_run--) { if(FRAME_MBAFF && (s->mb_y&1) == 0){ @@ -770,6 +770,10 @@ decode_intra_mb: // We assume these blocks are very rare so we do not optimize it. align_get_bits(&s->gb); + if (get_bits_left(&s->gb) < mb_size) { + av_log(s->avctx, AV_LOG_ERROR, "Not enough data for an intra PCM block.\n"); + return AVERROR_INVALIDDATA; + } // The pixels are stored in the same order as levels in h->mb array. for(x=0; x < mb_size; x++){ @@ -823,12 +827,12 @@ decode_intra_mb: if( ff_h264_check_intra4x4_pred_mode(h) < 0) return -1; }else{ - h->intra16x16_pred_mode= ff_h264_check_intra16x16_pred_mode(h, h->intra16x16_pred_mode); + h->intra16x16_pred_mode= ff_h264_check_intra_pred_mode(h, h->intra16x16_pred_mode, 0); if(h->intra16x16_pred_mode < 0) return -1; } if(decode_chroma){ - pred_mode= ff_h264_check_intra_chroma_pred_mode(h, get_ue_golomb_31(&s->gb)); + pred_mode= ff_h264_check_intra_pred_mode(h, get_ue_golomb_31(&s->gb), 1); if(pred_mode < 0) return -1; h->chroma_pred_mode= pred_mode; diff --git a/libavcodec/h264_direct.c b/libavcodec/h264_direct.c index 079c665509..b342ff5a8b 100644 --- a/libavcodec/h264_direct.c +++ b/libavcodec/h264_direct.c @@ -253,7 +253,7 @@ static void pred_spatial_direct_motion(H264Context * const h, int *mb_type){ mb_type_col[1] = h->ref_list[1][0].f.mb_type[mb_xy + s->mb_stride]; b8_stride = 2+4*s->mb_stride; b4_stride *= 6; - if(IS_INTERLACED(mb_type_col[0]) != IS_INTERLACED(mb_type_col[1])){ + if (IS_INTERLACED(mb_type_col[0]) != IS_INTERLACED(mb_type_col[1])) { mb_type_col[0] &= ~MB_TYPE_INTERLACED; mb_type_col[1] &= ~MB_TYPE_INTERLACED; } @@ -443,6 +443,10 @@ static void pred_temp_direct_motion(H264Context * const h, int *mb_type){ mb_type_col[1] = h->ref_list[1][0].f.mb_type[mb_xy + s->mb_stride]; b8_stride = 2+4*s->mb_stride; b4_stride *= 6; + if (IS_INTERLACED(mb_type_col[0]) != IS_INTERLACED(mb_type_col[1])) { + mb_type_col[0] &= ~MB_TYPE_INTERLACED; + mb_type_col[1] &= ~MB_TYPE_INTERLACED; + } sub_mb_type = MB_TYPE_16x16|MB_TYPE_P0L0|MB_TYPE_P0L1|MB_TYPE_DIRECT2; /* B_SUB_8x8 */ diff --git a/libavcodec/h264_loopfilter.c b/libavcodec/h264_loopfilter.c index f3a5ff6783..d98b642c35 100644 --- a/libavcodec/h264_loopfilter.c +++ b/libavcodec/h264_loopfilter.c @@ -254,8 +254,8 @@ static av_always_inline void h264_filter_mb_fast_internal(H264Context *h, int top_type= h->top_type; int qp_bd_offset = 6 * (h->sps.bit_depth_luma - 8); - int a = h->slice_alpha_c0_offset - qp_bd_offset; - int b = h->slice_beta_offset - qp_bd_offset; + int a = 52 + h->slice_alpha_c0_offset - qp_bd_offset; + int b = 52 + h->slice_beta_offset - qp_bd_offset; int mb_type = s->current_picture.f.mb_type[mb_xy]; int qp = s->current_picture.f.qscale_table[mb_xy]; @@ -715,8 +715,8 @@ void ff_h264_filter_mb( H264Context *h, int mb_x, int mb_y, uint8_t *img_y, uint av_unused int dir; int chroma = !(CONFIG_GRAY && (s->flags&CODEC_FLAG_GRAY)); int qp_bd_offset = 6 * (h->sps.bit_depth_luma - 8); - int a = h->slice_alpha_c0_offset - qp_bd_offset; - int b = h->slice_beta_offset - qp_bd_offset; + int a = 52 + h->slice_alpha_c0_offset - qp_bd_offset; + int b = 52 + h->slice_beta_offset - qp_bd_offset; if (FRAME_MBAFF // and current and left pair do not have the same interlaced type diff --git a/libavcodec/h264_mp4toannexb_bsf.c b/libavcodec/h264_mp4toannexb_bsf.c index 5085ecbdfd..8fe88d14ff 100644 --- a/libavcodec/h264_mp4toannexb_bsf.c +++ b/libavcodec/h264_mp4toannexb_bsf.c @@ -156,7 +156,7 @@ pps: goto fail; /* prepend only to the first type 5 NAL unit of an IDR picture */ - if (ctx->first_idr && unit_type == 5) { + if (ctx->first_idr && (unit_type == 5 || unit_type == 7 || unit_type == 8)) { if ((ret=alloc_and_copy(poutbuf, poutbuf_size, avctx->extradata, avctx->extradata_size, buf, nal_size)) < 0) diff --git a/libavcodec/h264_ps.c b/libavcodec/h264_ps.c index 5c21d80265..52a4c902bf 100644 --- a/libavcodec/h264_ps.c +++ b/libavcodec/h264_ps.c @@ -37,6 +37,9 @@ //#undef NDEBUG #include +#define MAX_LOG2_MAX_FRAME_NUM (12 + 4) +#define MIN_LOG2_MAX_FRAME_NUM 4 + static const AVRational pixel_aspect[17]={ {0, 1}, {1, 1}, @@ -241,19 +244,21 @@ static inline int decode_vui_parameters(H264Context *h, SPS *sps){ sps->num_reorder_frames= get_ue_golomb(&s->gb); get_ue_golomb(&s->gb); /*max_dec_frame_buffering*/ - if(get_bits_left(&s->gb) < 0){ + if (get_bits_left(&s->gb) < 0) { sps->num_reorder_frames=0; sps->bitstream_restriction_flag= 0; } if(sps->num_reorder_frames > 16U /*max_dec_frame_buffering || max_dec_frame_buffering > 16*/){ - av_log(h->s.avctx, AV_LOG_ERROR, "illegal num_reorder_frames %d\n", sps->num_reorder_frames); + av_log(h->s.avctx, AV_LOG_ERROR, "Clipping illegal num_reorder_frames %d\n", + sps->num_reorder_frames); + sps->num_reorder_frames = 16; return -1; } } - if(get_bits_left(&s->gb) < 0){ + if (get_bits_left(&s->gb) < 0) { av_log(h->s.avctx, AV_LOG_ERROR, "Overread VUI by %d bits\n", -get_bits_left(&s->gb)); - return -1; + return AVERROR_INVALIDDATA; } return 0; @@ -315,7 +320,7 @@ int ff_h264_decode_seq_parameter_set(H264Context *h){ MpegEncContext * const s = &h->s; int profile_idc, level_idc, constraint_set_flags = 0; unsigned int sps_id; - int i; + int i, log2_max_frame_num_minus4; SPS *sps; profile_idc= get_bits(&s->gb, 8); @@ -346,21 +351,32 @@ int ff_h264_decode_seq_parameter_set(H264Context *h){ sps->scaling_matrix_present = 0; sps->colorspace = 2; //AVCOL_SPC_UNSPECIFIED - if(sps->profile_idc >= 100){ //high profile + if (sps->profile_idc == 100 || sps->profile_idc == 110 || + sps->profile_idc == 122 || sps->profile_idc == 244 || + sps->profile_idc == 44 || sps->profile_idc == 83 || + sps->profile_idc == 86 || sps->profile_idc == 118 || + sps->profile_idc == 128 || sps->profile_idc == 144) { sps->chroma_format_idc= get_ue_golomb_31(&s->gb); if (sps->chroma_format_idc > 3U) { av_log(h->s.avctx, AV_LOG_ERROR, "chroma_format_idc %d is illegal\n", sps->chroma_format_idc); goto fail; - } - if(sps->chroma_format_idc == 3) + } else if(sps->chroma_format_idc == 3) { sps->residual_color_transform_flag = get_bits1(&s->gb); + } sps->bit_depth_luma = get_ue_golomb(&s->gb) + 8; sps->bit_depth_chroma = get_ue_golomb(&s->gb) + 8; - if (sps->bit_depth_luma > 12U || sps->bit_depth_chroma > 12U) { + if (sps->bit_depth_luma < 8 || sps->bit_depth_luma > 12 || + sps->bit_depth_chroma < 8 || sps->bit_depth_chroma > 12 || + sps->bit_depth_luma != sps->bit_depth_chroma) { av_log(h->s.avctx, AV_LOG_ERROR, "illegal bit depth value (%d, %d)\n", sps->bit_depth_luma, sps->bit_depth_chroma); goto fail; } + if (sps->bit_depth_chroma != sps->bit_depth_luma) { + av_log_missing_feature(s->avctx, + "Different bit depth between chroma and luma", 1); + goto fail; + } sps->transform_bypass = get_bits1(&s->gb); decode_scaling_matrices(h, sps, NULL, 1, sps->scaling_matrix4, sps->scaling_matrix8); }else{ @@ -369,7 +385,16 @@ int ff_h264_decode_seq_parameter_set(H264Context *h){ sps->bit_depth_chroma = 8; } - sps->log2_max_frame_num= get_ue_golomb(&s->gb) + 4; + log2_max_frame_num_minus4 = get_ue_golomb(&s->gb); + if (log2_max_frame_num_minus4 < MIN_LOG2_MAX_FRAME_NUM - 4 || + log2_max_frame_num_minus4 > MAX_LOG2_MAX_FRAME_NUM - 4) { + av_log(h->s.avctx, AV_LOG_ERROR, + "log2_max_frame_num_minus4 out of range (0-12): %d\n", + log2_max_frame_num_minus4); + return AVERROR_INVALIDDATA; + } + sps->log2_max_frame_num = log2_max_frame_num_minus4 + 4; + sps->poc_type= get_ue_golomb_31(&s->gb); if(sps->poc_type == 0){ //FIXME #define @@ -471,10 +496,13 @@ int ff_h264_decode_seq_parameter_set(H264Context *h){ sps->bit_depth_luma ); } + sps->new = 1; av_free(h->sps_buffers[sps_id]); - h->sps_buffers[sps_id]= sps; - h->sps = *sps; + h->sps_buffers[sps_id] = sps; + h->sps = *sps; + h->current_sps_id = sps_id; + return 0; fail: av_free(sps); @@ -515,6 +543,9 @@ int ff_h264_decode_picture_parameter_set(H264Context *h, int bit_length){ if(pps_id >= MAX_PPS_COUNT) { av_log(h->s.avctx, AV_LOG_ERROR, "pps_id (%d) out of range\n", pps_id); return -1; + } else if (h->sps.bit_depth_luma > 10) { + av_log(h->s.avctx, AV_LOG_ERROR, "Unimplemented luma bit depth=%d (max=10)\n", h->sps.bit_depth_luma); + return AVERROR_PATCHWELCOME; } pps= av_mallocz(sizeof(PPS)); diff --git a/libavcodec/h264_refs.c b/libavcodec/h264_refs.c index 8432a8a5b6..003d724407 100644 --- a/libavcodec/h264_refs.c +++ b/libavcodec/h264_refs.c @@ -63,20 +63,22 @@ static int split_field_copy(Picture *dest, Picture *src, return match; } -static int build_def_list(Picture *def, Picture **in, int len, int is_long, int sel){ +static int build_def_list(Picture *def, int def_len, + Picture **in, int len, int is_long, int sel) +{ int i[2]={0}; int index=0; - while(i[0]f.reference & sel))) i[0]++; while (i[1] < len && !(in[ i[1] ] && (in[ i[1] ]->f.reference & (sel^3)))) i[1]++; - if(i[0] < len){ + if (i[0] < len && index < def_len) { in[ i[0] ]->pic_id= is_long ? i[0] : in[ i[0] ]->frame_num; split_field_copy(&def[index++], in[ i[0]++ ], sel , 1); } - if(i[1] < len){ + if (i[1] < len && index < def_len) { in[ i[1] ]->pic_id= is_long ? i[1] : in[ i[1] ]->frame_num; split_field_copy(&def[index++], in[ i[1]++ ], sel^3, 0); } @@ -124,9 +126,12 @@ int ff_h264_fill_default_ref_list(H264Context *h){ len= add_sorted(sorted , h->short_ref, h->short_ref_count, cur_poc, 1^list); len+=add_sorted(sorted+len, h->short_ref, h->short_ref_count, cur_poc, 0^list); assert(len<=32); - len= build_def_list(h->default_ref_list[list] , sorted , len, 0, s->picture_structure); - len+=build_def_list(h->default_ref_list[list]+len, h->long_ref, 16 , 1, s->picture_structure); - assert(len<=32); + + len = build_def_list(h->default_ref_list[list], FF_ARRAY_ELEMS(h->default_ref_list[0]), + sorted, len, 0, s->picture_structure); + len += build_def_list(h->default_ref_list[list] + len, + FF_ARRAY_ELEMS(h->default_ref_list[0]) - len, + h->long_ref, 16, 1, s->picture_structure); if(len < h->ref_count[list]) memset(&h->default_ref_list[list][len], 0, sizeof(Picture)*(h->ref_count[list] - len)); @@ -139,19 +144,22 @@ int ff_h264_fill_default_ref_list(H264Context *h){ FFSWAP(Picture, h->default_ref_list[1][0], h->default_ref_list[1][1]); } }else{ - len = build_def_list(h->default_ref_list[0] , h->short_ref, h->short_ref_count, 0, s->picture_structure); - len+= build_def_list(h->default_ref_list[0]+len, h-> long_ref, 16 , 1, s->picture_structure); - assert(len <= 32); + len = build_def_list(h->default_ref_list[0], FF_ARRAY_ELEMS(h->default_ref_list[0]), + h->short_ref, h->short_ref_count, 0, s->picture_structure); + len += build_def_list(h->default_ref_list[0] + len, + FF_ARRAY_ELEMS(h->default_ref_list[0]) - len, + h-> long_ref, 16, 1, s->picture_structure); + if(len < h->ref_count[0]) memset(&h->default_ref_list[0][len], 0, sizeof(Picture)*(h->ref_count[0] - len)); } #ifdef TRACE for (i=0; iref_count[0]; i++) { - tprintf(h->s.avctx, "List0: %s fn:%d 0x%p\n", (h->default_ref_list[0][i].long_ref ? "LT" : "ST"), h->default_ref_list[0][i].pic_id, h->default_ref_list[0][i].data[0]); + tprintf(h->s.avctx, "List0: %s fn:%d 0x%p\n", (h->default_ref_list[0][i].long_ref ? "LT" : "ST"), h->default_ref_list[0][i].pic_id, h->default_ref_list[0][i].f.data[0]); } if(h->slice_type_nos==AV_PICTURE_TYPE_B){ for (i=0; iref_count[1]; i++) { - tprintf(h->s.avctx, "List1: %s fn:%d 0x%p\n", (h->default_ref_list[1][i].long_ref ? "LT" : "ST"), h->default_ref_list[1][i].pic_id, h->default_ref_list[1][i].data[0]); + tprintf(h->s.avctx, "List1: %s fn:%d 0x%p\n", (h->default_ref_list[1][i].long_ref ? "LT" : "ST"), h->default_ref_list[1][i].pic_id, h->default_ref_list[1][i].f.data[0]); } } #endif @@ -516,7 +524,7 @@ int ff_h264_execute_ref_pic_marking(H264Context *h, MMCO *mmco, int mmco_count){ if(!pic){ if(mmco[i].opcode != MMCO_SHORT2LONG || !h->long_ref[mmco[i].long_arg] || h->long_ref[mmco[i].long_arg]->frame_num != frame_num) { - av_log(h->s.avctx, AV_LOG_ERROR, "mmco: unref short failure\n"); + av_log(h->s.avctx, h->short_ref_count ? AV_LOG_ERROR : AV_LOG_DEBUG, "mmco: unref short failure\n"); err = AVERROR_INVALIDDATA; } continue; @@ -653,8 +661,10 @@ int ff_h264_execute_ref_pic_marking(H264Context *h, MMCO *mmco, int mmco_count){ print_short_term(h); print_long_term(h); - if(err >= 0 && h->long_ref_count==0 && h->short_ref_count<=2 && h->pps.ref_count[0]<=1 + (s->picture_structure != PICT_FRAME) && s->current_picture_ptr->f.pict_type == AV_PICTURE_TYPE_I){ + if(err >= 0 && h->long_ref_count==0 && h->short_ref_count<=2 && h->pps.ref_count[0]<=2 + (s->picture_structure != PICT_FRAME) && s->current_picture_ptr->f.pict_type == AV_PICTURE_TYPE_I){ s->current_picture_ptr->sync |= 1; + if(!h->s.avctx->has_b_frames) + h->sync = 2; } return (h->s.avctx->err_recognition & AV_EF_EXPLODE) ? err : 0; diff --git a/libavcodec/h264_sei.c b/libavcodec/h264_sei.c index 80d70e513c..2252dbfc74 100644 --- a/libavcodec/h264_sei.c +++ b/libavcodec/h264_sei.c @@ -164,7 +164,7 @@ static int decode_buffering_period(H264Context *h){ int ff_h264_decode_sei(H264Context *h){ MpegEncContext * const s = &h->s; - while(get_bits_count(&s->gb) + 16 < s->gb.size_in_bits){ + while (get_bits_left(&s->gb) > 16) { int size, type; type=0; @@ -184,6 +184,12 @@ int ff_h264_decode_sei(H264Context *h){ if(s->avctx->debug&FF_DEBUG_STARTCODE) av_log(h->s.avctx, AV_LOG_DEBUG, "SEI %d len:%d\n", type, size); + if (size > get_bits_left(&s->gb) / 8) { + av_log(s->avctx, AV_LOG_ERROR, "SEI type %d truncated at %d\n", + type, get_bits_left(&s->gb)); + return AVERROR_INVALIDDATA; + } + switch(type){ case SEI_TYPE_PIC_TIMING: // Picture timing SEI if(decode_picture_timing(h) < 0) diff --git a/libavcodec/h264dsp.c b/libavcodec/h264dsp.c index bd35aa3065..eeee6a23c8 100644 --- a/libavcodec/h264dsp.c +++ b/libavcodec/h264dsp.c @@ -53,13 +53,13 @@ void ff_h264dsp_init(H264DSPContext *c, const int bit_depth, const int chroma_fo c->h264_idct8_dc_add= FUNC(ff_h264_idct8_dc_add, depth);\ c->h264_idct_add16 = FUNC(ff_h264_idct_add16, depth);\ c->h264_idct8_add4 = FUNC(ff_h264_idct8_add4, depth);\ - if (chroma_format_idc == 1)\ + if (chroma_format_idc <= 1)\ c->h264_idct_add8 = FUNC(ff_h264_idct_add8, depth);\ else\ c->h264_idct_add8 = FUNC(ff_h264_idct_add8_422, depth);\ c->h264_idct_add16intra= FUNC(ff_h264_idct_add16intra, depth);\ c->h264_luma_dc_dequant_idct= FUNC(ff_h264_luma_dc_dequant_idct, depth);\ - if (chroma_format_idc == 1)\ + if (chroma_format_idc <= 1)\ c->h264_chroma_dc_dequant_idct= FUNC(ff_h264_chroma_dc_dequant_idct, depth);\ else\ c->h264_chroma_dc_dequant_idct= FUNC(ff_h264_chroma422_dc_dequant_idct, depth);\ @@ -80,20 +80,20 @@ void ff_h264dsp_init(H264DSPContext *c, const int bit_depth, const int chroma_fo c->h264_h_loop_filter_luma_intra= FUNC(h264_h_loop_filter_luma_intra, depth);\ c->h264_h_loop_filter_luma_mbaff_intra= FUNC(h264_h_loop_filter_luma_mbaff_intra, depth);\ c->h264_v_loop_filter_chroma= FUNC(h264_v_loop_filter_chroma, depth);\ - if (chroma_format_idc == 1)\ + if (chroma_format_idc <= 1)\ c->h264_h_loop_filter_chroma= FUNC(h264_h_loop_filter_chroma, depth);\ else\ c->h264_h_loop_filter_chroma= FUNC(h264_h_loop_filter_chroma422, depth);\ - if (chroma_format_idc == 1)\ + if (chroma_format_idc <= 1)\ c->h264_h_loop_filter_chroma_mbaff= FUNC(h264_h_loop_filter_chroma_mbaff, depth);\ else\ c->h264_h_loop_filter_chroma_mbaff= FUNC(h264_h_loop_filter_chroma422_mbaff, depth);\ c->h264_v_loop_filter_chroma_intra= FUNC(h264_v_loop_filter_chroma_intra, depth);\ - if (chroma_format_idc == 1)\ + if (chroma_format_idc <= 1)\ c->h264_h_loop_filter_chroma_intra= FUNC(h264_h_loop_filter_chroma_intra, depth);\ else\ c->h264_h_loop_filter_chroma_intra= FUNC(h264_h_loop_filter_chroma422_intra, depth);\ - if (chroma_format_idc == 1)\ + if (chroma_format_idc <= 1)\ c->h264_h_loop_filter_chroma_mbaff_intra= FUNC(h264_h_loop_filter_chroma_mbaff_intra, depth);\ else\ c->h264_h_loop_filter_chroma_mbaff_intra= FUNC(h264_h_loop_filter_chroma422_mbaff_intra, depth);\ diff --git a/libavcodec/h264idct_template.c b/libavcodec/h264idct_template.c index c59976a1d9..5c730fdb26 100644 --- a/libavcodec/h264idct_template.c +++ b/libavcodec/h264idct_template.c @@ -49,7 +49,6 @@ static const uint8_t scan8[16*3]={ void FUNCC(ff_h264_idct_add)(uint8_t *_dst, DCTELEM *_block, int stride) { int i; - INIT_CLIP pixel *dst = (pixel*)_dst; dctcoef *block = (dctcoef*)_block; stride >>= sizeof(pixel)-1; @@ -74,16 +73,15 @@ void FUNCC(ff_h264_idct_add)(uint8_t *_dst, DCTELEM *_block, int stride) const int z2= (block[1 + 4*i]>>1) - block[3 + 4*i]; const int z3= block[1 + 4*i] + (block[3 + 4*i]>>1); - dst[i + 0*stride]= CLIP(dst[i + 0*stride] + ((z0 + z3) >> 6)); - dst[i + 1*stride]= CLIP(dst[i + 1*stride] + ((z1 + z2) >> 6)); - dst[i + 2*stride]= CLIP(dst[i + 2*stride] + ((z1 - z2) >> 6)); - dst[i + 3*stride]= CLIP(dst[i + 3*stride] + ((z0 - z3) >> 6)); + dst[i + 0*stride]= av_clip_pixel(dst[i + 0*stride] + ((z0 + z3) >> 6)); + dst[i + 1*stride]= av_clip_pixel(dst[i + 1*stride] + ((z1 + z2) >> 6)); + dst[i + 2*stride]= av_clip_pixel(dst[i + 2*stride] + ((z1 - z2) >> 6)); + dst[i + 3*stride]= av_clip_pixel(dst[i + 3*stride] + ((z0 - z3) >> 6)); } } void FUNCC(ff_h264_idct8_add)(uint8_t *_dst, DCTELEM *_block, int stride){ int i; - INIT_CLIP pixel *dst = (pixel*)_dst; dctcoef *block = (dctcoef*)_block; stride >>= sizeof(pixel)-1; @@ -143,14 +141,14 @@ void FUNCC(ff_h264_idct8_add)(uint8_t *_dst, DCTELEM *_block, int stride){ const int b5 = (a3>>2) - a5; const int b7 = a7 - (a1>>2); - dst[i + 0*stride] = CLIP( dst[i + 0*stride] + ((b0 + b7) >> 6) ); - dst[i + 1*stride] = CLIP( dst[i + 1*stride] + ((b2 + b5) >> 6) ); - dst[i + 2*stride] = CLIP( dst[i + 2*stride] + ((b4 + b3) >> 6) ); - dst[i + 3*stride] = CLIP( dst[i + 3*stride] + ((b6 + b1) >> 6) ); - dst[i + 4*stride] = CLIP( dst[i + 4*stride] + ((b6 - b1) >> 6) ); - dst[i + 5*stride] = CLIP( dst[i + 5*stride] + ((b4 - b3) >> 6) ); - dst[i + 6*stride] = CLIP( dst[i + 6*stride] + ((b2 - b5) >> 6) ); - dst[i + 7*stride] = CLIP( dst[i + 7*stride] + ((b0 - b7) >> 6) ); + dst[i + 0*stride] = av_clip_pixel( dst[i + 0*stride] + ((b0 + b7) >> 6) ); + dst[i + 1*stride] = av_clip_pixel( dst[i + 1*stride] + ((b2 + b5) >> 6) ); + dst[i + 2*stride] = av_clip_pixel( dst[i + 2*stride] + ((b4 + b3) >> 6) ); + dst[i + 3*stride] = av_clip_pixel( dst[i + 3*stride] + ((b6 + b1) >> 6) ); + dst[i + 4*stride] = av_clip_pixel( dst[i + 4*stride] + ((b6 - b1) >> 6) ); + dst[i + 5*stride] = av_clip_pixel( dst[i + 5*stride] + ((b4 - b3) >> 6) ); + dst[i + 6*stride] = av_clip_pixel( dst[i + 6*stride] + ((b2 - b5) >> 6) ); + dst[i + 7*stride] = av_clip_pixel( dst[i + 7*stride] + ((b0 - b7) >> 6) ); } } @@ -158,13 +156,12 @@ void FUNCC(ff_h264_idct8_add)(uint8_t *_dst, DCTELEM *_block, int stride){ void FUNCC(ff_h264_idct_dc_add)(uint8_t *p_dst, DCTELEM *block, int stride){ int i, j; int dc = (((dctcoef*)block)[0] + 32) >> 6; - INIT_CLIP pixel *dst = (pixel*)p_dst; stride >>= sizeof(pixel)-1; for( j = 0; j < 4; j++ ) { for( i = 0; i < 4; i++ ) - dst[i] = CLIP( dst[i] + dc ); + dst[i] = av_clip_pixel( dst[i] + dc ); dst += stride; } } @@ -172,13 +169,12 @@ void FUNCC(ff_h264_idct_dc_add)(uint8_t *p_dst, DCTELEM *block, int stride){ void FUNCC(ff_h264_idct8_dc_add)(uint8_t *p_dst, DCTELEM *block, int stride){ int i, j; int dc = (((dctcoef*)block)[0] + 32) >> 6; - INIT_CLIP pixel *dst = (pixel*)p_dst; stride >>= sizeof(pixel)-1; for( j = 0; j < 8; j++ ) { for( i = 0; i < 8; i++ ) - dst[i] = CLIP( dst[i] + dc ); + dst[i] = av_clip_pixel( dst[i] + dc ); dst += stride; } } diff --git a/libavcodec/h264pred.c b/libavcodec/h264pred.c index a174b4ca3c..e3efdf974a 100644 --- a/libavcodec/h264pred.c +++ b/libavcodec/h264pred.c @@ -434,7 +434,7 @@ void ff_h264_pred_init(H264PredContext *h, int codec_id, const int bit_depth, co h->pred8x8l[TOP_DC_PRED ]= FUNCC(pred8x8l_top_dc , depth);\ h->pred8x8l[DC_128_PRED ]= FUNCC(pred8x8l_128_dc , depth);\ \ - if (chroma_format_idc == 1) {\ + if (chroma_format_idc <= 1) {\ h->pred8x8[VERT_PRED8x8 ]= FUNCC(pred8x8_vertical , depth);\ h->pred8x8[HOR_PRED8x8 ]= FUNCC(pred8x8_horizontal , depth);\ } else {\ @@ -442,7 +442,7 @@ void ff_h264_pred_init(H264PredContext *h, int codec_id, const int bit_depth, co h->pred8x8[HOR_PRED8x8 ]= FUNCC(pred8x16_horizontal , depth);\ }\ if (codec_id != CODEC_ID_VP8) {\ - if (chroma_format_idc == 1) {\ + if (chroma_format_idc <= 1) {\ h->pred8x8[PLANE_PRED8x8]= FUNCC(pred8x8_plane , depth);\ } else {\ h->pred8x8[PLANE_PRED8x8]= FUNCC(pred8x16_plane , depth);\ @@ -450,7 +450,7 @@ void ff_h264_pred_init(H264PredContext *h, int codec_id, const int bit_depth, co } else\ h->pred8x8[PLANE_PRED8x8]= FUNCD(pred8x8_tm_vp8);\ if(codec_id != CODEC_ID_RV40 && codec_id != CODEC_ID_VP8){\ - if (chroma_format_idc == 1) {\ + if (chroma_format_idc <= 1) {\ h->pred8x8[DC_PRED8x8 ]= FUNCC(pred8x8_dc , depth);\ h->pred8x8[LEFT_DC_PRED8x8]= FUNCC(pred8x8_left_dc , depth);\ h->pred8x8[TOP_DC_PRED8x8 ]= FUNCC(pred8x8_top_dc , depth);\ @@ -476,7 +476,7 @@ void ff_h264_pred_init(H264PredContext *h, int codec_id, const int bit_depth, co h->pred8x8[DC_129_PRED8x8]= FUNCC(pred8x8_129_dc , depth);\ }\ }\ - if (chroma_format_idc == 1) {\ + if (chroma_format_idc <= 1) {\ h->pred8x8[DC_128_PRED8x8 ]= FUNCC(pred8x8_128_dc , depth);\ } else {\ h->pred8x8[DC_128_PRED8x8 ]= FUNCC(pred8x16_128_dc , depth);\ @@ -510,7 +510,7 @@ void ff_h264_pred_init(H264PredContext *h, int codec_id, const int bit_depth, co h->pred4x4_add [ HOR_PRED ]= FUNCC(pred4x4_horizontal_add , depth);\ h->pred8x8l_add [VERT_PRED ]= FUNCC(pred8x8l_vertical_add , depth);\ h->pred8x8l_add [ HOR_PRED ]= FUNCC(pred8x8l_horizontal_add , depth);\ - if (chroma_format_idc == 1) {\ + if (chroma_format_idc <= 1) {\ h->pred8x8_add [VERT_PRED8x8]= FUNCC(pred8x8_vertical_add , depth);\ h->pred8x8_add [ HOR_PRED8x8]= FUNCC(pred8x8_horizontal_add , depth);\ } else {\ diff --git a/libavcodec/huffman.c b/libavcodec/huffman.c index 7b33bdd7f3..ee49ae9570 100644 --- a/libavcodec/huffman.c +++ b/libavcodec/huffman.c @@ -61,7 +61,7 @@ static int build_huff_tree(VLC *vlc, Node *nodes, int head, int flags) int pos = 0; get_tree_codes(bits, lens, xlat, nodes, head, 0, 0, &pos, no_zero_count); - return init_vlc_sparse(vlc, 9, pos, lens, 2, 2, bits, 4, 4, xlat, 1, 1, 0); + return ff_init_vlc_sparse(vlc, 9, pos, lens, 2, 2, bits, 4, 4, xlat, 1, 1, 0); } diff --git a/libavcodec/huffyuv.c b/libavcodec/huffyuv.c index 574daacc0b..1c5cc868f3 100644 --- a/libavcodec/huffyuv.c +++ b/libavcodec/huffyuv.c @@ -28,6 +28,7 @@ * huffyuv codec for libavcodec. */ +#include "libavutil/avassert.h" #include "avcodec.h" #include "get_bits.h" #include "put_bits.h" @@ -82,13 +83,15 @@ typedef struct HYuvContext{ DSPContext dsp; }HYuvContext; -static const unsigned char classic_shift_luma[] = { +#define classic_shift_luma_table_size 42 +static const unsigned char classic_shift_luma[classic_shift_luma_table_size + FF_INPUT_BUFFER_PADDING_SIZE] = { 34,36,35,69,135,232,9,16,10,24,11,23,12,16,13,10,14,8,15,8, 16,8,17,20,16,10,207,206,205,236,11,8,10,21,9,23,8,8,199,70, 69,68, 0 }; -static const unsigned char classic_shift_chroma[] = { +#define classic_shift_chroma_table_size 59 +static const unsigned char classic_shift_chroma[classic_shift_chroma_table_size + FF_INPUT_BUFFER_PADDING_SIZE] = { 66,36,37,38,39,40,41,75,76,77,110,239,144,81,82,83,84,85,118,183, 56,57,88,89,56,89,154,57,58,57,26,141,57,56,58,57,58,57,184,119, 214,245,116,83,82,49,80,79,78,77,44,75,41,40,39,38,37,36,34, 0 @@ -212,7 +215,7 @@ static int read_len_table(uint8_t *dst, GetBitContext *gb){ if(repeat==0) repeat= get_bits(gb, 8); //printf("%d %d\n", val, repeat); - if(i+repeat > 256) { + if(i+repeat > 256 || get_bits_left(gb) < 0) { av_log(NULL, AV_LOG_ERROR, "Error reading huffman table\n"); return -1; } @@ -299,22 +302,25 @@ static void generate_len_table(uint8_t *dst, const uint64_t *stats){ } #endif /* CONFIG_HUFFYUV_ENCODER || CONFIG_FFVHUFF_ENCODER */ -static void generate_joint_tables(HYuvContext *s){ +static int generate_joint_tables(HYuvContext *s){ uint16_t symbols[1<bitstream_bpp < 24){ int p, i, y, u; for(p=0; p<3; p++){ for(i=y=0; y<256; y++){ int len0 = s->len[0][y]; int limit = VLC_BITS - len0; - if(limit <= 0) + if(limit <= 0 || !len0) continue; for(u=0; u<256; u++){ int len1 = s->len[p][u]; - if(len1 > limit) + if (len1 > limit || !len1) continue; + av_assert0(i < (1 << VLC_BITS)); len[i] = len0 + len1; bits[i] = (s->bits[0][y] << len1) + s->bits[p][u]; symbols[i] = (y<<8) + u; @@ -322,8 +328,10 @@ static void generate_joint_tables(HYuvContext *s){ i++; } } - free_vlc(&s->vlc[3+p]); - init_vlc_sparse(&s->vlc[3+p], VLC_BITS, i, len, 1, 1, bits, 2, 2, symbols, 2, 2, 0); + ff_free_vlc(&s->vlc[3+p]); + if ((ret = ff_init_vlc_sparse(&s->vlc[3 + p], VLC_BITS, i, len, 1, 1, + bits, 2, 2, symbols, 2, 2, 0)) < 0) + return ret; } }else{ uint8_t (*map)[4] = (uint8_t(*)[4])s->pix_bgr_map; @@ -336,18 +344,19 @@ static void generate_joint_tables(HYuvContext *s){ for(i=0, g=-16; g<16; g++){ int len0 = s->len[p0][g&255]; int limit0 = VLC_BITS - len0; - if(limit0 < 2) + if (limit0 < 2 || !len0) continue; for(b=-16; b<16; b++){ int len1 = s->len[p1][b&255]; int limit1 = limit0 - len1; - if(limit1 < 1) + if (limit1 < 1 || !len1) continue; code = (s->bits[p0][g&255] << len1) + s->bits[p1][b&255]; for(r=-16; r<16; r++){ int len2 = s->len[2][r&255]; - if(len2 > limit1) + if (len2 > limit1 || !len2) continue; + av_assert0(i < (1 << VLC_BITS)); len[i] = len0 + len1 + len2; bits[i] = (code << len2) + s->bits[2][r&255]; if(s->decorrelate){ @@ -363,28 +372,34 @@ static void generate_joint_tables(HYuvContext *s){ } } } - free_vlc(&s->vlc[3]); - init_vlc(&s->vlc[3], VLC_BITS, i, len, 1, 1, bits, 2, 2, 0); + ff_free_vlc(&s->vlc[3]); + if ((ret = init_vlc(&s->vlc[3], VLC_BITS, i, len, 1, 1, + bits, 2, 2, 0)) < 0) + return ret; } + return 0; } static int read_huffman_tables(HYuvContext *s, const uint8_t *src, int length){ GetBitContext gb; - int i; + int i, ret; - init_get_bits(&gb, src, length*8); + if ((ret = init_get_bits(&gb, src, length * 8)) < 0) + return ret; for(i=0; i<3; i++){ - if(read_len_table(s->len[i], &gb)<0) - return -1; - if(generate_bits_table(s->bits[i], s->len[i])<0){ - return -1; - } - free_vlc(&s->vlc[i]); - init_vlc(&s->vlc[i], VLC_BITS, 256, s->len[i], 1, 1, s->bits[i], 4, 4, 0); + if ((ret = read_len_table(s->len[i], &gb)) < 0) + return ret; + if ((ret = generate_bits_table(s->bits[i], s->len[i])) < 0) + return ret; + ff_free_vlc(&s->vlc[i]); + if ((ret = init_vlc(&s->vlc[i], VLC_BITS, 256, s->len[i], 1, 1, + s->bits[i], 4, 4, 0)) < 0) + return ret; } - generate_joint_tables(s); + if ((ret = generate_joint_tables(s)) < 0) + return ret; return (get_bits_count(&gb)+7)/8; } @@ -392,14 +407,18 @@ static int read_huffman_tables(HYuvContext *s, const uint8_t *src, int length){ static int read_old_huffman_tables(HYuvContext *s){ #if 1 GetBitContext gb; - int i; + int i, ret; - init_get_bits(&gb, classic_shift_luma, sizeof(classic_shift_luma)*8); - if(read_len_table(s->len[0], &gb)<0) - return -1; - init_get_bits(&gb, classic_shift_chroma, sizeof(classic_shift_chroma)*8); - if(read_len_table(s->len[1], &gb)<0) - return -1; + if ((ret = init_get_bits(&gb, classic_shift_luma, + classic_shift_luma_table_size * 8)) < 0) + return ret; + if ((ret = read_len_table(s->len[0], &gb)) < 0) + return ret; + if ((ret = init_get_bits(&gb, classic_shift_chroma, + classic_shift_chroma_table_size * 8)) < 0) + return ret; + if ((ret = read_len_table(s->len[1], &gb)) < 0) + return ret; for(i=0; i<256; i++) s->bits[0][i] = classic_add_luma [i]; for(i=0; i<256; i++) s->bits[1][i] = classic_add_chroma[i]; @@ -412,11 +431,14 @@ static int read_old_huffman_tables(HYuvContext *s){ memcpy(s->len[2] , s->len [1], 256*sizeof(uint8_t)); for(i=0; i<3; i++){ - free_vlc(&s->vlc[i]); - init_vlc(&s->vlc[i], VLC_BITS, 256, s->len[i], 1, 1, s->bits[i], 4, 4, 0); + ff_free_vlc(&s->vlc[i]); + if ((ret = init_vlc(&s->vlc[i], VLC_BITS, 256, s->len[i], 1, 1, + s->bits[i], 4, 4, 0)) < 0) + return ret; } - generate_joint_tables(s); + if ((ret = generate_joint_tables(s)) < 0) + return ret; return 0; #else @@ -456,6 +478,7 @@ static av_cold int common_init(AVCodecContext *avctx){ static av_cold int decode_init(AVCodecContext *avctx) { HYuvContext *s = avctx->priv_data; + int ret; common_init(avctx); memset(s->vlc, 0, 3*sizeof(VLC)); @@ -491,8 +514,9 @@ s->bgr32=1; s->interlaced= (interlace==1) ? 1 : (interlace==2) ? 0 : s->interlaced; s->context= ((uint8_t*)avctx->extradata)[2] & 0x40 ? 1 : 0; - if(read_huffman_tables(s, ((uint8_t*)avctx->extradata)+4, avctx->extradata_size-4) < 0) - return -1; + if ((ret = read_huffman_tables(s, ((uint8_t*)avctx->extradata) + 4, + avctx->extradata_size - 4)) < 0) + return ret; }else{ switch(avctx->bits_per_coded_sample&7){ case 1: @@ -519,8 +543,8 @@ s->bgr32=1; s->bitstream_bpp= avctx->bits_per_coded_sample & ~7; s->context= 0; - if(read_old_huffman_tables(s) < 0) - return -1; + if ((ret = read_old_huffman_tables(s)) < 0) + return ret; } switch(s->bitstream_bpp){ @@ -543,7 +567,14 @@ s->bgr32=1; } break; default: - assert(0); + return AVERROR_INVALIDDATA; + } + + if (s->predictor == MEDIAN && avctx->pix_fmt == PIX_FMT_YUV422P && + avctx->width % 4) { + av_log(avctx, AV_LOG_ERROR, "width must be multiple of 4 " + "for this combination of colorspace and predictor type.\n"); + return AVERROR_INVALIDDATA; } alloc_temp(s); @@ -556,7 +587,7 @@ s->bgr32=1; static av_cold int decode_init_thread_copy(AVCodecContext *avctx) { HYuvContext *s = avctx->priv_data; - int i; + int i, ret; avctx->coded_frame= &s->picture; alloc_temp(s); @@ -565,11 +596,12 @@ static av_cold int decode_init_thread_copy(AVCodecContext *avctx) s->vlc[i].table = NULL; if(s->version==2){ - if(read_huffman_tables(s, ((uint8_t*)avctx->extradata)+4, avctx->extradata_size) < 0) - return -1; + if ((ret = read_huffman_tables(s, ((uint8_t*)avctx->extradata) + 4, + avctx->extradata_size)) < 0) + return ret; }else{ - if(read_old_huffman_tables(s) < 0) - return -1; + if ((ret = read_old_huffman_tables(s)) < 0) + return ret; } return 0; @@ -750,7 +782,7 @@ static void decode_422_bitstream(HYuvContext *s, int count){ count/=2; if(count >= (get_bits_left(&s->gb))/(31*4)){ - for(i=0; igb) < s->gb.size_in_bits; i++){ + for (i = 0; i < count && get_bits_left(&s->gb) > 0; i++) { READ_2PIX(s->temp[0][2*i ], s->temp[1][i], 1); READ_2PIX(s->temp[0][2*i+1], s->temp[2][i], 2); } @@ -768,7 +800,7 @@ static void decode_gray_bitstream(HYuvContext *s, int count){ count/=2; if(count >= (get_bits_left(&s->gb))/(31*2)){ - for(i=0; igb) < s->gb.size_in_bits; i++){ + for (i = 0; i < count && get_bits_left(&s->gb) > 0; i++) { READ_2PIX(s->temp[0][2*i ], s->temp[0][2*i+1], 0); } }else{ @@ -992,7 +1024,7 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *data_size, AVPac const int height= s->height; int fake_ystride, fake_ustride, fake_vstride; AVFrame * const p= &s->picture; - int table_size= 0; + int table_size = 0, ret; AVFrame *picture = data; @@ -1007,21 +1039,23 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *data_size, AVPac ff_thread_release_buffer(avctx, p); p->reference= 0; - if(ff_thread_get_buffer(avctx, p) < 0){ + if ((ret = ff_thread_get_buffer(avctx, p)) < 0) { av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n"); - return -1; + return ret; } if(s->context){ table_size = read_huffman_tables(s, s->bitstream_buffer, buf_size); if(table_size < 0) - return -1; + return table_size; } if((unsigned)(buf_size-table_size) >= INT_MAX/8) return -1; - init_get_bits(&s->gb, s->bitstream_buffer+table_size, (buf_size-table_size)*8); + if ((ret = init_get_bits(&s->gb, s->bitstream_buffer + table_size, + (buf_size - table_size) * 8)) < 0) + return ret; fake_ystride= s->interlaced ? p->linesize[0]*2 : p->linesize[0]; fake_ustride= s->interlaced ? p->linesize[1]*2 : p->linesize[1]; @@ -1253,7 +1287,7 @@ static av_cold int decode_end(AVCodecContext *avctx) av_freep(&s->bitstream_buffer); for(i=0; i<6; i++){ - free_vlc(&s->vlc[i]); + ff_free_vlc(&s->vlc[i]); } return 0; diff --git a/libavcodec/iff.c b/libavcodec/iff.c index 24167c722c..de3fe6bba6 100644 --- a/libavcodec/iff.c +++ b/libavcodec/iff.c @@ -28,6 +28,7 @@ #include "libavutil/imgutils.h" #include "bytestream.h" #include "avcodec.h" +#include "internal.h" #include "get_bits.h" // TODO: masking bits @@ -191,7 +192,13 @@ static int extract_header(AVCodecContext *const avctx, const uint8_t *buf; unsigned buf_size; IffContext *s = avctx->priv_data; - int palette_size = avctx->extradata_size - AV_RB16(avctx->extradata); + int palette_size; + + if (avctx->extradata_size < 2) { + av_log(avctx, AV_LOG_ERROR, "not enough extradata\n"); + return AVERROR_INVALIDDATA; + } + palette_size = avctx->extradata_size - AV_RB16(avctx->extradata); if (avpkt) { int image_size; @@ -207,8 +214,6 @@ static int extract_header(AVCodecContext *const avctx, return AVERROR_INVALIDDATA; } } else { - if (avctx->extradata_size < 2) - return AVERROR_INVALIDDATA; buf = avctx->extradata; buf_size = bytestream_get_be16(&buf); if (buf_size <= 1 || palette_size < 0) { @@ -312,7 +317,12 @@ static av_cold int decode_init(AVCodecContext *avctx) int err; if (avctx->bits_per_coded_sample <= 8) { - int palette_size = avctx->extradata_size - AV_RB16(avctx->extradata); + int palette_size; + + if (avctx->extradata_size >= 2) + palette_size = avctx->extradata_size - AV_RB16(avctx->extradata); + else + palette_size = 0; avctx->pix_fmt = (avctx->bits_per_coded_sample < 8) || (avctx->extradata_size >= 2 && palette_size) ? PIX_FMT_PAL8 : PIX_FMT_GRAY8; } else if (avctx->bits_per_coded_sample <= 32) { @@ -470,10 +480,10 @@ static int decode_frame_ilbm(AVCodecContext *avctx, av_log(avctx, AV_LOG_ERROR, "reget_buffer() failed\n"); return res; } - } else if ((res = avctx->get_buffer(avctx, &s->frame)) < 0) { + } else if ((res = ff_get_buffer(avctx, &s->frame)) < 0) { av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n"); return res; - } else if (avctx->bits_per_coded_sample <= 8 && avctx->pix_fmt != PIX_FMT_GRAY8) { + } else if (avctx->bits_per_coded_sample <= 8 && avctx->pix_fmt == PIX_FMT_PAL8) { if ((res = ff_cmap_read_palette(avctx, (uint32_t*)s->frame.data[1])) < 0) return res; } @@ -505,7 +515,7 @@ static int decode_frame_ilbm(AVCodecContext *avctx, } } else if (avctx->codec_tag == MKTAG('I','L','B','M')) { // interleaved if (avctx->pix_fmt == PIX_FMT_PAL8 || avctx->pix_fmt == PIX_FMT_GRAY8) { - for(y = 0; y < avctx->height; y++ ) { + for (y = 0; y < avctx->height && buf < buf_end; y++ ) { uint8_t *row = &s->frame.data[0][ y*s->frame.linesize[0] ]; memset(row, 0, avctx->width); for (plane = 0; plane < s->bpp && buf < buf_end; plane++) { @@ -570,7 +580,7 @@ static int decode_frame_byterun1(AVCodecContext *avctx, av_log(avctx, AV_LOG_ERROR, "reget_buffer() failed\n"); return res; } - } else if ((res = avctx->get_buffer(avctx, &s->frame)) < 0) { + } else if ((res = ff_get_buffer(avctx, &s->frame)) < 0) { av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n"); return res; } else if (avctx->pix_fmt == PIX_FMT_PAL8) { diff --git a/libavcodec/imc.c b/libavcodec/imc.c index d3b8bf5a12..5179bc3621 100644 --- a/libavcodec/imc.c +++ b/libavcodec/imc.c @@ -36,6 +36,7 @@ #include #include "avcodec.h" +#include "internal.h" #include "get_bits.h" #include "dsputil.h" #include "fft.h" @@ -365,6 +366,10 @@ static int bit_allocation (IMCContext* q, int stream_format_code, int freebits, iacc += q->bandWidthT[i]; summa += q->bandWidthT[i] * q->flcoeffs4[i]; } + + if (!iacc) + return AVERROR_INVALIDDATA; + q->bandWidthT[BANDS-1] = 0; summa = (summa * 0.5 - freebits) / iacc; @@ -676,7 +681,7 @@ static int imc_decode_frame(AVCodecContext * avctx, void *data, /* get output buffer */ q->frame.nb_samples = COEFFS; - if ((ret = avctx->get_buffer(avctx, &q->frame)) < 0) { + if ((ret = ff_get_buffer(avctx, &q->frame)) < 0) { av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n"); return ret; } diff --git a/libavcodec/indeo3.c b/libavcodec/indeo3.c index fc38f5e9cb..3e9fa6ea40 100644 --- a/libavcodec/indeo3.c +++ b/libavcodec/indeo3.c @@ -32,6 +32,7 @@ #include "libavutil/imgutils.h" #include "libavutil/intreadwrite.h" #include "avcodec.h" +#include "internal.h" #include "dsputil.h" #include "bytestream.h" #include "get_bits.h" @@ -93,7 +94,7 @@ typedef struct Indeo3DecodeContext { int16_t width, height; uint32_t frame_num; ///< current frame number (zero-based) - uint32_t data_size; ///< size of the frame data in bytes + int data_size; ///< size of the frame data in bytes uint16_t frame_flags; ///< frame properties uint8_t cb_offset; ///< needed for selecting VQ tables uint8_t buf_sel; ///< active frame buffer: 0 - primary, 1 -secondary @@ -194,6 +195,8 @@ static av_cold int allocate_frame_buffers(Indeo3DecodeContext *ctx, /* set buffer pointers = buf_ptr + pitch and thus skip the INTRA prediction line */ ctx->planes[p].pixels[0] = ctx->planes[p].buffers[0] + ctx->planes[p].pitch; ctx->planes[p].pixels[1] = ctx->planes[p].buffers[1] + ctx->planes[p].pitch; + memset(ctx->planes[p].pixels[0], 0, ctx->planes[p].pitch * ctx->planes[p].height); + memset(ctx->planes[p].pixels[1], 0, ctx->planes[p].pitch * ctx->planes[p].height); } return 0; @@ -207,6 +210,7 @@ static av_cold void free_frame_buffers(Indeo3DecodeContext *ctx) for (p = 0; p < 3; p++) { av_freep(&ctx->planes[p].buffers[0]); av_freep(&ctx->planes[p].buffers[1]); + ctx->planes[p].pixels[0] = ctx->planes[p].pixels[1] = 0; } } @@ -219,7 +223,7 @@ static av_cold void free_frame_buffers(Indeo3DecodeContext *ctx) * @param plane pointer to the plane descriptor * @param cell pointer to the cell descriptor */ -static void copy_cell(Indeo3DecodeContext *ctx, Plane *plane, Cell *cell) +static int copy_cell(Indeo3DecodeContext *ctx, Plane *plane, Cell *cell) { int h, w, mv_x, mv_y, offset, offset_dst; uint8_t *src, *dst; @@ -232,6 +236,16 @@ static void copy_cell(Indeo3DecodeContext *ctx, Plane *plane, Cell *cell) mv_x = cell->mv_ptr[1]; }else mv_x= mv_y= 0; + + /* -1 because there is an extra line on top for prediction */ + if ((cell->ypos << 2) + mv_y < -1 || (cell->xpos << 2) + mv_x < 0 || + ((cell->ypos + cell->height) << 2) + mv_y > plane->height || + ((cell->xpos + cell->width) << 2) + mv_x > plane->width) { + av_log(ctx->avctx, AV_LOG_ERROR, + "Motion vectors point out of the frame.\n"); + return AVERROR_INVALIDDATA; + } + offset = offset_dst + mv_y * plane->pitch + mv_x; src = plane->pixels[ctx->buf_sel ^ 1] + offset; @@ -259,6 +273,8 @@ static void copy_cell(Indeo3DecodeContext *ctx, Plane *plane, Cell *cell) dst += 4; } } + + return 0; } @@ -347,8 +363,10 @@ if (*data_ptr >= last_ptr) \ fill_64(dst, pix64, num_lines << 1, row_offset) #define APPLY_DELTA_4 \ - AV_WN16A(dst + line_offset , AV_RN16A(ref ) + delta_tab->deltas[dyad1]);\ - AV_WN16A(dst + line_offset + 2, AV_RN16A(ref + 2) + delta_tab->deltas[dyad2]);\ + AV_WN16A(dst + line_offset ,\ + (AV_RN16A(ref ) + delta_tab->deltas[dyad1]) & 0x7F7F);\ + AV_WN16A(dst + line_offset + 2,\ + (AV_RN16A(ref + 2) + delta_tab->deltas[dyad2]) & 0x7F7F);\ if (mode >= 3) {\ if (is_top_of_cell && !cell->ypos) {\ AV_COPY32(dst, dst + row_offset);\ @@ -361,14 +379,14 @@ if (*data_ptr >= last_ptr) \ /* apply two 32-bit VQ deltas to next even line */\ if (is_top_of_cell) { \ AV_WN32A(dst + row_offset , \ - replicate32(AV_RN32A(ref )) + delta_tab->deltas_m10[dyad1]);\ + (replicate32(AV_RN32A(ref )) + delta_tab->deltas_m10[dyad1]) & 0x7F7F7F7F);\ AV_WN32A(dst + row_offset + 4, \ - replicate32(AV_RN32A(ref + 4)) + delta_tab->deltas_m10[dyad2]);\ + (replicate32(AV_RN32A(ref + 4)) + delta_tab->deltas_m10[dyad2]) & 0x7F7F7F7F);\ } else { \ AV_WN32A(dst + row_offset , \ - AV_RN32A(ref ) + delta_tab->deltas_m10[dyad1]);\ + (AV_RN32A(ref ) + delta_tab->deltas_m10[dyad1]) & 0x7F7F7F7F);\ AV_WN32A(dst + row_offset + 4, \ - AV_RN32A(ref + 4) + delta_tab->deltas_m10[dyad2]);\ + (AV_RN32A(ref + 4) + delta_tab->deltas_m10[dyad2]) & 0x7F7F7F7F);\ } \ /* odd lines are not coded but rather interpolated/replicated */\ /* first line of the cell on the top of image? - replicate */\ @@ -382,22 +400,22 @@ if (*data_ptr >= last_ptr) \ #define APPLY_DELTA_1011_INTER \ if (mode == 10) { \ AV_WN32A(dst , \ - AV_RN32A(dst ) + delta_tab->deltas_m10[dyad1]);\ + (AV_RN32A(dst ) + delta_tab->deltas_m10[dyad1]) & 0x7F7F7F7F);\ AV_WN32A(dst + 4 , \ - AV_RN32A(dst + 4 ) + delta_tab->deltas_m10[dyad2]);\ + (AV_RN32A(dst + 4 ) + delta_tab->deltas_m10[dyad2]) & 0x7F7F7F7F);\ AV_WN32A(dst + row_offset , \ - AV_RN32A(dst + row_offset ) + delta_tab->deltas_m10[dyad1]);\ + (AV_RN32A(dst + row_offset ) + delta_tab->deltas_m10[dyad1]) & 0x7F7F7F7F);\ AV_WN32A(dst + row_offset + 4, \ - AV_RN32A(dst + row_offset + 4) + delta_tab->deltas_m10[dyad2]);\ + (AV_RN32A(dst + row_offset + 4) + delta_tab->deltas_m10[dyad2]) & 0x7F7F7F7F);\ } else { \ AV_WN16A(dst , \ - AV_RN16A(dst ) + delta_tab->deltas[dyad1]);\ + (AV_RN16A(dst ) + delta_tab->deltas[dyad1]) & 0x7F7F);\ AV_WN16A(dst + 2 , \ - AV_RN16A(dst + 2 ) + delta_tab->deltas[dyad2]);\ + (AV_RN16A(dst + 2 ) + delta_tab->deltas[dyad2]) & 0x7F7F);\ AV_WN16A(dst + row_offset , \ - AV_RN16A(dst + row_offset ) + delta_tab->deltas[dyad1]);\ + (AV_RN16A(dst + row_offset ) + delta_tab->deltas[dyad1]) & 0x7F7F);\ AV_WN16A(dst + row_offset + 2, \ - AV_RN16A(dst + row_offset + 2) + delta_tab->deltas[dyad2]);\ + (AV_RN16A(dst + row_offset + 2) + delta_tab->deltas[dyad2]) & 0x7F7F);\ } @@ -419,6 +437,9 @@ static int decode_cell_data(Cell *cell, uint8_t *block, uint8_t *ref_block, blk_row_offset = (row_offset << (2 + v_zoom)) - (cell->width << 2); line_offset = v_zoom ? row_offset : 0; + if (cell->height & v_zoom || cell->width & h_zoom) + return IV3_BAD_DATA; + for (y = 0; y < cell->height; is_first_row = 0, y += 1 + v_zoom) { for (x = 0; x < cell->width; x += 1 + h_zoom) { ref = ref_block; @@ -579,11 +600,23 @@ static int decode_cell(Indeo3DecodeContext *ctx, AVCodecContext *avctx, } else if (mode >= 10) { /* for mode 10 and 11 INTER first copy the predicted cell into the current one */ /* so we don't need to do data copying for each RLE code later */ - copy_cell(ctx, plane, cell); + int ret = copy_cell(ctx, plane, cell); + if (ret < 0) + return ret; } else { /* set the pointer to the reference pixels for modes 0-4 INTER */ mv_y = cell->mv_ptr[0]; mv_x = cell->mv_ptr[1]; + + /* -1 because there is an extra line on top for prediction */ + if ((cell->ypos << 2) + mv_y < -1 || (cell->xpos << 2) + mv_x < 0 || + ((cell->ypos + cell->height) << 2) + mv_y > plane->height || + ((cell->xpos + cell->width) << 2) + mv_x > plane->width) { + av_log(ctx->avctx, AV_LOG_ERROR, + "Motion vectors point out of the frame.\n"); + return AVERROR_INVALIDDATA; + } + offset += mv_y * plane->pitch + mv_x; ref_block = plane->pixels[ctx->buf_sel ^ 1] + offset; } @@ -715,7 +748,7 @@ static int parse_bintree(Indeo3DecodeContext *ctx, AVCodecContext *avctx, const int depth, const int strip_width) { Cell curr_cell; - int bytes_used; + int bytes_used, ret; if (depth <= 0) { av_log(avctx, AV_LOG_ERROR, "Stack overflow (corrupted binary tree)!\n"); @@ -727,6 +760,8 @@ static int parse_bintree(Indeo3DecodeContext *ctx, AVCodecContext *avctx, SPLIT_CELL(ref_cell->height, curr_cell.height); ref_cell->ypos += curr_cell.height; ref_cell->height -= curr_cell.height; + if (ref_cell->height <= 0 || curr_cell.height <= 0) + return AVERROR_INVALIDDATA; } else if (code == V_SPLIT) { if (curr_cell.width > strip_width) { /* split strip */ @@ -735,6 +770,8 @@ static int parse_bintree(Indeo3DecodeContext *ctx, AVCodecContext *avctx, SPLIT_CELL(ref_cell->width, curr_cell.width); ref_cell->xpos += curr_cell.width; ref_cell->width -= curr_cell.width; + if (ref_cell->width <= 0 || curr_cell.width <= 0) + return AVERROR_INVALIDDATA; } while (get_bits_left(&ctx->gb) >= 2) { /* loop until return */ @@ -762,8 +799,8 @@ static int parse_bintree(Indeo3DecodeContext *ctx, AVCodecContext *avctx, CHECK_CELL if (!curr_cell.mv_ptr) return AVERROR_INVALIDDATA; - copy_cell(ctx, plane, &curr_cell); - return 0; + ret = copy_cell(ctx, plane, &curr_cell); + return ret; } break; case INTER_DATA: @@ -846,17 +883,21 @@ static int decode_plane(Indeo3DecodeContext *ctx, AVCodecContext *avctx, static int decode_frame_headers(Indeo3DecodeContext *ctx, AVCodecContext *avctx, const uint8_t *buf, int buf_size) { - const uint8_t *buf_ptr = buf, *bs_hdr; + GetByteContext gb; + const uint8_t *bs_hdr; uint32_t frame_num, word2, check_sum, data_size; - uint32_t y_offset, u_offset, v_offset, starts[3], ends[3]; + int y_offset, u_offset, v_offset; + uint32_t starts[3], ends[3]; uint16_t height, width; int i, j; + bytestream2_init(&gb, buf, buf_size); + /* parse and check the OS header */ - frame_num = bytestream_get_le32(&buf_ptr); - word2 = bytestream_get_le32(&buf_ptr); - check_sum = bytestream_get_le32(&buf_ptr); - data_size = bytestream_get_le32(&buf_ptr); + frame_num = bytestream2_get_le32(&gb); + word2 = bytestream2_get_le32(&gb); + check_sum = bytestream2_get_le32(&gb); + data_size = bytestream2_get_le32(&gb); if ((frame_num ^ word2 ^ data_size ^ OS_HDR_ID) != check_sum) { av_log(avctx, AV_LOG_ERROR, "OS header checksum mismatch!\n"); @@ -864,46 +905,56 @@ static int decode_frame_headers(Indeo3DecodeContext *ctx, AVCodecContext *avctx, } /* parse the bitstream header */ - bs_hdr = buf_ptr; + bs_hdr = gb.buffer; - if (bytestream_get_le16(&buf_ptr) != 32) { + if (bytestream2_get_le16(&gb) != 32) { av_log(avctx, AV_LOG_ERROR, "Unsupported codec version!\n"); return AVERROR_INVALIDDATA; } ctx->frame_num = frame_num; - ctx->frame_flags = bytestream_get_le16(&buf_ptr); - ctx->data_size = (bytestream_get_le32(&buf_ptr) + 7) >> 3; - ctx->cb_offset = *buf_ptr++; + ctx->frame_flags = bytestream2_get_le16(&gb); + ctx->data_size = (bytestream2_get_le32(&gb) + 7) >> 3; + ctx->cb_offset = bytestream2_get_byte(&gb); if (ctx->data_size == 16) return 4; - if (ctx->data_size > buf_size) - ctx->data_size = buf_size; + ctx->data_size = FFMIN(ctx->data_size, buf_size - 16); - buf_ptr += 3; // skip reserved byte and checksum + bytestream2_skip(&gb, 3); // skip reserved byte and checksum /* check frame dimensions */ - height = bytestream_get_le16(&buf_ptr); - width = bytestream_get_le16(&buf_ptr); + height = bytestream2_get_le16(&gb); + width = bytestream2_get_le16(&gb); if (av_image_check_size(width, height, 0, avctx)) return AVERROR_INVALIDDATA; if (width != ctx->width || height != ctx->height) { + int res; + av_dlog(avctx, "Frame dimensions changed!\n"); + if (width < 16 || width > 640 || + height < 16 || height > 480 || + width & 3 || height & 3) { + av_log(avctx, AV_LOG_ERROR, + "Invalid picture dimensions: %d x %d!\n", width, height); + return AVERROR_INVALIDDATA; + } + ctx->width = width; ctx->height = height; free_frame_buffers(ctx); - if(allocate_frame_buffers(ctx, avctx) < 0) - return AVERROR_INVALIDDATA; + if ((res = allocate_frame_buffers(ctx, avctx)) < 0) + return res; avcodec_set_dimensions(avctx, width, height); } - y_offset = bytestream_get_le32(&buf_ptr); - v_offset = bytestream_get_le32(&buf_ptr); - u_offset = bytestream_get_le32(&buf_ptr); + y_offset = bytestream2_get_le32(&gb); + v_offset = bytestream2_get_le32(&gb); + u_offset = bytestream2_get_le32(&gb); + bytestream2_skip(&gb, 4); /* unfortunately there is no common order of planes in the buffer */ /* so we use that sorting algo for determining planes data sizes */ @@ -921,7 +972,9 @@ static int decode_frame_headers(Indeo3DecodeContext *ctx, AVCodecContext *avctx, ctx->y_data_size = ends[0] - starts[0]; ctx->v_data_size = ends[1] - starts[1]; ctx->u_data_size = ends[2] - starts[2]; - if (FFMAX3(y_offset, v_offset, u_offset) >= ctx->data_size - 16 || + if (FFMIN3(y_offset, v_offset, u_offset) < 0 || + FFMAX3(y_offset, v_offset, u_offset) >= ctx->data_size - 16 || + FFMIN3(y_offset, v_offset, u_offset) < gb.buffer - bs_hdr + 16 || FFMIN3(ctx->y_data_size, ctx->v_data_size, ctx->u_data_size) <= 0) { av_log(avctx, AV_LOG_ERROR, "One of the y/u/v offsets is invalid\n"); return AVERROR_INVALIDDATA; @@ -930,7 +983,7 @@ static int decode_frame_headers(Indeo3DecodeContext *ctx, AVCodecContext *avctx, ctx->y_data_ptr = bs_hdr + y_offset; ctx->v_data_ptr = bs_hdr + v_offset; ctx->u_data_ptr = bs_hdr + u_offset; - ctx->alt_quant = buf_ptr + sizeof(uint32_t); + ctx->alt_quant = gb.buffer; if (ctx->data_size == 16) { av_log(avctx, AV_LOG_DEBUG, "Sync frame encountered!\n"); @@ -1047,7 +1100,7 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *data_size, avctx->release_buffer(avctx, &ctx->frame); ctx->frame.reference = 0; - if ((res = avctx->get_buffer(avctx, &ctx->frame)) < 0) { + if ((res = ff_get_buffer(avctx, &ctx->frame)) < 0) { av_log(ctx->avctx, AV_LOG_ERROR, "get_buffer() failed\n"); return res; } diff --git a/libavcodec/indeo4.c b/libavcodec/indeo4.c index 573718e374..9cbd493b5c 100644 --- a/libavcodec/indeo4.c +++ b/libavcodec/indeo4.c @@ -35,9 +35,6 @@ #include "ivi_common.h" #include "indeo4data.h" -#define IVI4_STREAM_ANALYSER 0 -#define IVI4_DEBUG_CHECKSUM 0 - /** * Indeo 4 frame types. */ @@ -54,46 +51,6 @@ enum { #define IVI4_PIC_SIZE_ESC 7 -typedef struct { - GetBitContext gb; - AVFrame frame; - RVMapDesc rvmap_tabs[9]; ///< local corrected copy of the static rvmap tables - - uint32_t frame_num; - int frame_type; - int prev_frame_type; ///< frame type of the previous frame - uint32_t data_size; ///< size of the frame data in bytes from picture header - int is_scalable; - int transp_status; ///< transparency mode status: 1 - enabled - - IVIPicConfig pic_conf; - IVIPlaneDesc planes[3]; ///< color planes - - int buf_switch; ///< used to switch between three buffers - int dst_buf; ///< buffer index for the currently decoded frame - int ref_buf; ///< inter frame reference buffer index - - IVIHuffTab mb_vlc; ///< current macroblock table descriptor - IVIHuffTab blk_vlc; ///< current block table descriptor - - uint16_t checksum; ///< frame checksum - - uint8_t rvmap_sel; - uint8_t in_imf; - uint8_t in_q; ///< flag for explicitly stored quantiser delta - uint8_t pic_glob_quant; - uint8_t unknown1; - -#if IVI4_STREAM_ANALYSER - uint8_t has_b_frames; - uint8_t has_transp; - uint8_t uses_tiling; - uint8_t uses_haar; - uint8_t uses_fullpel; -#endif -} IVI4DecContext; - - static const struct { InvTransformPtr *inv_trans; DCTransformPtr *dc_trans; @@ -158,7 +115,7 @@ static inline int scale_tile_size(int def_size, int size_factor) * @param[in] avctx pointer to the AVCodecContext * @return result code: 0 = OK, negative number = error */ -static int decode_pic_hdr(IVI4DecContext *ctx, AVCodecContext *avctx) +static int decode_pic_hdr(IVI45DecContext *ctx, AVCodecContext *avctx) { int pic_size_indx, i, p; IVIPicConfig pic_conf; @@ -254,6 +211,7 @@ static int decode_pic_hdr(IVI4DecContext *ctx, AVCodecContext *avctx) if (ivi_pic_config_cmp(&pic_conf, &ctx->pic_conf)) { if (ff_ivi_init_planes(ctx->planes, &pic_conf)) { av_log(avctx, AV_LOG_ERROR, "Couldn't reallocate color planes!\n"); + ctx->pic_conf.luma_bands = 0; return AVERROR(ENOMEM); } @@ -322,7 +280,7 @@ static int decode_pic_hdr(IVI4DecContext *ctx, AVCodecContext *avctx) * @param[in] avctx pointer to the AVCodecContext * @return result code: 0 = OK, negative number = error */ -static int decode_band_hdr(IVI4DecContext *ctx, IVIBandDesc *band, +static int decode_band_hdr(IVI45DecContext *ctx, IVIBandDesc *band, AVCodecContext *avctx) { int plane, band_num, indx, transform_id, scan_indx; @@ -372,7 +330,8 @@ static int decode_band_hdr(IVI4DecContext *ctx, IVIBandDesc *band, if (!get_bits1(&ctx->gb) || ctx->frame_type == FRAMETYPE_INTRA) { transform_id = get_bits(&ctx->gb, 5); - if (!transforms[transform_id].inv_trans) { + if (transform_id >= FF_ARRAY_ELEMS(transforms) || + !transforms[transform_id].inv_trans) { av_log_ask_for_sample(avctx, "Unimplemented transform: %d!\n", transform_id); return AVERROR_PATCHWELCOME; } @@ -390,12 +349,25 @@ static int decode_band_hdr(IVI4DecContext *ctx, IVIBandDesc *band, band->inv_transform = transforms[transform_id].inv_trans; band->dc_transform = transforms[transform_id].dc_trans; band->is_2d_trans = transforms[transform_id].is_2d_trans; + if (transform_id < 10) + band->transform_size = 8; + else + band->transform_size = 4; + + if (band->blk_size != band->transform_size) + return AVERROR_INVALIDDATA; scan_indx = get_bits(&ctx->gb, 4); if (scan_indx == 15) { av_log(avctx, AV_LOG_ERROR, "Custom scan pattern encountered!\n"); return AVERROR_INVALIDDATA; } + if (scan_indx > 4 && scan_indx < 10) { + if (band->blk_size != 4) + return AVERROR_INVALIDDATA; + } else if (band->blk_size != 8) + return AVERROR_INVALIDDATA; + band->scan = scan_index_to_tab[scan_indx]; band->quant_mat = get_bits(&ctx->gb, 5); @@ -403,6 +375,11 @@ static int decode_band_hdr(IVI4DecContext *ctx, IVIBandDesc *band, av_log(avctx, AV_LOG_ERROR, "Custom quant matrix encountered!\n"); return AVERROR_INVALIDDATA; } + if (band->quant_mat >= FF_ARRAY_ELEMS(quant_index_to_tab)) { + av_log_ask_for_sample(avctx, "Quantization matrix %d", + band->quant_mat); + return AVERROR_INVALIDDATA; + } } /* decode block huffman codebook */ @@ -457,7 +434,7 @@ static int decode_band_hdr(IVI4DecContext *ctx, IVIBandDesc *band, * @param[in] avctx pointer to the AVCodecContext * @return result code: 0 = OK, negative number = error */ -static int decode_mb_info(IVI4DecContext *ctx, IVIBandDesc *band, +static int decode_mb_info(IVI45DecContext *ctx, IVIBandDesc *band, IVITile *tile, AVCodecContext *avctx) { int x, y, mv_x, mv_y, mv_delta, offs, mb_offset, blks_per_mb, @@ -476,6 +453,11 @@ static int decode_mb_info(IVI4DecContext *ctx, IVIBandDesc *band, mv_scale = (ctx->planes[0].bands[0].mb_size >> 3) - (band->mb_size >> 3); mv_x = mv_y = 0; + if (((tile->width + band->mb_size-1)/band->mb_size) * ((tile->height + band->mb_size-1)/band->mb_size) != tile->num_MBs) { + av_log(avctx, AV_LOG_ERROR, "num_MBs mismatch %d %d %d %d\n", tile->width, tile->height, band->mb_size, tile->num_MBs); + return -1; + } + for (y = tile->ypos; y < tile->ypos + tile->height; y += band->mb_size) { mb_offset = offs; @@ -500,7 +482,7 @@ static int decode_mb_info(IVI4DecContext *ctx, IVIBandDesc *band, } mb->mv_x = mb->mv_y = 0; /* no motion vector coded */ - if (band->inherit_mv) { + if (band->inherit_mv && ref_mb) { /* motion vector inheritance */ if (mv_scale) { mb->mv_x = ivi_scale_mv(ref_mb->mv_x, mv_scale); @@ -512,7 +494,10 @@ static int decode_mb_info(IVI4DecContext *ctx, IVIBandDesc *band, } } else { if (band->inherit_mv) { - mb->type = ref_mb->type; /* copy mb_type from corresponding reference mb */ + /* copy mb_type from corresponding reference mb */ + if (!ref_mb) + return AVERROR_INVALIDDATA; + mb->type = ref_mb->type; } else if (ctx->frame_type == FRAMETYPE_INTRA) { mb->type = 0; /* mb_type is always INTRA for intra-frames */ } else { @@ -535,14 +520,15 @@ static int decode_mb_info(IVI4DecContext *ctx, IVIBandDesc *band, mb->mv_x = mb->mv_y = 0; /* there is no motion vector in intra-macroblocks */ } else { if (band->inherit_mv) { - /* motion vector inheritance */ - if (mv_scale) { - mb->mv_x = ivi_scale_mv(ref_mb->mv_x, mv_scale); - mb->mv_y = ivi_scale_mv(ref_mb->mv_y, mv_scale); - } else { - mb->mv_x = ref_mb->mv_x; - mb->mv_y = ref_mb->mv_y; - } + if (ref_mb) + /* motion vector inheritance */ + if (mv_scale) { + mb->mv_x = ivi_scale_mv(ref_mb->mv_x, mv_scale); + mb->mv_y = ivi_scale_mv(ref_mb->mv_y, mv_scale); + } else { + mb->mv_x = ref_mb->mv_x; + mb->mv_y = ref_mb->mv_y; + } } else { /* decode motion vector deltas */ mv_delta = get_vlc2(&ctx->gb, ctx->mb_vlc.tab->table, @@ -572,126 +558,12 @@ static int decode_mb_info(IVI4DecContext *ctx, IVIBandDesc *band, } -/** - * Decode an Indeo 4 band. - * - * @param[in,out] ctx pointer to the decoder context - * @param[in,out] band pointer to the band descriptor - * @param[in] avctx pointer to the AVCodecContext - * @return result code: 0 = OK, negative number = error - */ -static int decode_band(IVI4DecContext *ctx, int plane_num, - IVIBandDesc *band, AVCodecContext *avctx) -{ - int result, i, t, pos, idx1, idx2; - IVITile *tile; - - band->buf = band->bufs[ctx->dst_buf]; - band->ref_buf = band->bufs[ctx->ref_buf]; - - result = decode_band_hdr(ctx, band, avctx); - if (result) { - av_log(avctx, AV_LOG_ERROR, "Error decoding band header\n"); - return result; - } - - if (band->is_empty) { - av_log(avctx, AV_LOG_ERROR, "Empty band encountered!\n"); - return AVERROR_INVALIDDATA; - } - - band->rv_map = &ctx->rvmap_tabs[band->rvmap_sel]; - - /* apply corrections to the selected rvmap table if present */ - for (i = 0; i < band->num_corr; i++) { - idx1 = band->corr[i * 2]; - idx2 = band->corr[i * 2 + 1]; - FFSWAP(uint8_t, band->rv_map->runtab[idx1], band->rv_map->runtab[idx2]); - FFSWAP(int16_t, band->rv_map->valtab[idx1], band->rv_map->valtab[idx2]); - } - - pos = get_bits_count(&ctx->gb); - - for (t = 0; t < band->num_tiles; t++) { - tile = &band->tiles[t]; - - tile->is_empty = get_bits1(&ctx->gb); - if (tile->is_empty) { - ff_ivi_process_empty_tile(avctx, band, tile, - (ctx->planes[0].bands[0].mb_size >> 3) - (band->mb_size >> 3)); - av_dlog(avctx, "Empty tile encountered!\n"); - } else { - tile->data_size = ff_ivi_dec_tile_data_size(&ctx->gb); - if (!tile->data_size) { - av_log(avctx, AV_LOG_ERROR, "Tile data size is zero!\n"); - return AVERROR_INVALIDDATA; - } - - result = decode_mb_info(ctx, band, tile, avctx); - if (result < 0) - break; - - result = ff_ivi_decode_blocks(&ctx->gb, band, tile); - if (result < 0 || ((get_bits_count(&ctx->gb) - pos) >> 3) != tile->data_size) { - av_log(avctx, AV_LOG_ERROR, "Corrupted tile data encountered!\n"); - break; - } - - pos += tile->data_size << 3; // skip to next tile - } - } - - /* restore the selected rvmap table by applying its corrections in reverse order */ - for (i = band->num_corr - 1; i >= 0; i--) { - idx1 = band->corr[i * 2]; - idx2 = band->corr[i * 2 + 1]; - FFSWAP(uint8_t, band->rv_map->runtab[idx1], band->rv_map->runtab[idx2]); - FFSWAP(int16_t, band->rv_map->valtab[idx1], band->rv_map->valtab[idx2]); - } - -#if defined(DEBUG) && IVI4_DEBUG_CHECKSUM - if (band->checksum_present) { - uint16_t chksum = ivi_calc_band_checksum(band); - if (chksum != band->checksum) { - av_log(avctx, AV_LOG_ERROR, - "Band checksum mismatch! Plane %d, band %d, received: %x, calculated: %x\n", - band->plane, band->band_num, band->checksum, chksum); - } - } -#endif - - align_get_bits(&ctx->gb); - - return 0; -} - - -static av_cold int decode_init(AVCodecContext *avctx) -{ - IVI4DecContext *ctx = avctx->priv_data; - - ff_ivi_init_static_vlc(); - - /* copy rvmap tables in our context so we can apply changes to them */ - memcpy(ctx->rvmap_tabs, ff_ivi_rvmap_tabs, sizeof(ff_ivi_rvmap_tabs)); - - /* Force allocation of the internal buffers */ - /* during picture header decoding. */ - ctx->pic_conf.pic_width = 0; - ctx->pic_conf.pic_height = 0; - - avctx->pix_fmt = PIX_FMT_YUV410P; - - return 0; -} - - /** * Rearrange decoding and reference buffers. * * @param[in,out] ctx pointer to the decoder context */ -static void switch_buffers(IVI4DecContext *ctx) +static void switch_buffers(IVI45DecContext *ctx) { switch (ctx->prev_frame_type) { case FRAMETYPE_INTRA: @@ -720,95 +592,33 @@ static void switch_buffers(IVI4DecContext *ctx) } -static int decode_frame(AVCodecContext *avctx, void *data, int *data_size, - AVPacket *avpkt) +static int is_nonnull_frame(IVI45DecContext *ctx) { - IVI4DecContext *ctx = avctx->priv_data; - const uint8_t *buf = avpkt->data; - int buf_size = avpkt->size; - int result, p, b; - - init_get_bits(&ctx->gb, buf, buf_size * 8); - - result = decode_pic_hdr(ctx, avctx); - if (result) { - av_log(avctx, AV_LOG_ERROR, "Error decoding picture header\n"); - return result; - } - - switch_buffers(ctx); - - if (ctx->frame_type < FRAMETYPE_NULL_FIRST) { - for (p = 0; p < 3; p++) { - for (b = 0; b < ctx->planes[p].num_bands; b++) { - result = decode_band(ctx, p, &ctx->planes[p].bands[b], avctx); - if (result) { - av_log(avctx, AV_LOG_ERROR, - "Error decoding band: %d, plane: %d\n", b, p); - return result; - } - } - } - } - - /* If the bidirectional mode is enabled, next I and the following P frame will */ - /* be sent together. Unfortunately the approach below seems to be the only way */ - /* to handle the B-frames mode. That's exactly the same Intel decoders do. */ - if (ctx->frame_type == FRAMETYPE_INTRA) { - while (get_bits(&ctx->gb, 8)); // skip version string - skip_bits_long(&ctx->gb, 64); // skip padding, TODO: implement correct 8-bytes alignment - if (get_bits_left(&ctx->gb) > 18 && show_bits(&ctx->gb, 18) == 0x3FFF8) - av_log(avctx, AV_LOG_ERROR, "Buffer contains IP frames!\n"); - } - - if (ctx->frame.data[0]) - avctx->release_buffer(avctx, &ctx->frame); - - ctx->frame.reference = 0; - if ((result = avctx->get_buffer(avctx, &ctx->frame)) < 0) { - av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n"); - return result; - } - - if (ctx->is_scalable) { - ff_ivi_recompose_haar(&ctx->planes[0], ctx->frame.data[0], ctx->frame.linesize[0], 4); - } else { - ff_ivi_output_plane(&ctx->planes[0], ctx->frame.data[0], ctx->frame.linesize[0]); - } - - ff_ivi_output_plane(&ctx->planes[2], ctx->frame.data[1], ctx->frame.linesize[1]); - ff_ivi_output_plane(&ctx->planes[1], ctx->frame.data[2], ctx->frame.linesize[2]); - - *data_size = sizeof(AVFrame); - *(AVFrame*)data = ctx->frame; - - return buf_size; + return ctx->frame_type < FRAMETYPE_NULL_FIRST; } -static av_cold int decode_close(AVCodecContext *avctx) +static av_cold int decode_init(AVCodecContext *avctx) { - IVI4DecContext *ctx = avctx->priv_data; + IVI45DecContext *ctx = avctx->priv_data; - ff_ivi_free_buffers(&ctx->planes[0]); + ff_ivi_init_static_vlc(); - if (ctx->frame.data[0]) - avctx->release_buffer(avctx, &ctx->frame); + /* copy rvmap tables in our context so we can apply changes to them */ + memcpy(ctx->rvmap_tabs, ff_ivi_rvmap_tabs, sizeof(ff_ivi_rvmap_tabs)); -#if IVI4_STREAM_ANALYSER - if (ctx->is_scalable) - av_log(avctx, AV_LOG_ERROR, "This video uses scalability mode!\n"); - if (ctx->uses_tiling) - av_log(avctx, AV_LOG_ERROR, "This video uses local decoding!\n"); - if (ctx->has_b_frames) - av_log(avctx, AV_LOG_ERROR, "This video contains B-frames!\n"); - if (ctx->has_transp) - av_log(avctx, AV_LOG_ERROR, "Transparency mode is enabled!\n"); - if (ctx->uses_haar) - av_log(avctx, AV_LOG_ERROR, "This video uses Haar transform!\n"); - if (ctx->uses_fullpel) - av_log(avctx, AV_LOG_ERROR, "This video uses fullpel motion vectors!\n"); -#endif + /* Force allocation of the internal buffers */ + /* during picture header decoding. */ + ctx->pic_conf.pic_width = 0; + ctx->pic_conf.pic_height = 0; + + avctx->pix_fmt = PIX_FMT_YUV410P; + + ctx->decode_pic_hdr = decode_pic_hdr; + ctx->decode_band_hdr = decode_band_hdr; + ctx->decode_mb_info = decode_mb_info; + ctx->switch_buffers = switch_buffers; + ctx->is_nonnull_frame = is_nonnull_frame; return 0; } @@ -818,9 +628,9 @@ AVCodec ff_indeo4_decoder = { .name = "indeo4", .type = AVMEDIA_TYPE_VIDEO, .id = CODEC_ID_INDEO4, - .priv_data_size = sizeof(IVI4DecContext), + .priv_data_size = sizeof(IVI45DecContext), .init = decode_init, - .close = decode_close, - .decode = decode_frame, + .close = ff_ivi_decode_close, + .decode = ff_ivi_decode_frame, .long_name = NULL_IF_CONFIG_SMALL("Intel Indeo Video Interactive 4"), }; diff --git a/libavcodec/indeo5.c b/libavcodec/indeo5.c index 8842f221cf..d27bf41b5c 100644 --- a/libavcodec/indeo5.c +++ b/libavcodec/indeo5.c @@ -48,37 +48,6 @@ enum { #define IVI5_PIC_SIZE_ESC 15 -#define IVI5_IS_PROTECTED 0x20 - -typedef struct { - GetBitContext gb; - AVFrame frame; - RVMapDesc rvmap_tabs[9]; ///< local corrected copy of the static rvmap tables - IVIPlaneDesc planes[3]; ///< color planes - const uint8_t *frame_data; ///< input frame data pointer - int buf_switch; ///< used to switch between three buffers - int inter_scal; ///< signals a sequence of scalable inter frames - int dst_buf; ///< buffer index for the currently decoded frame - int ref_buf; ///< inter frame reference buffer index - int ref2_buf; ///< temporal storage for switching buffers - uint32_t frame_size; ///< frame size in bytes - int frame_type; - int prev_frame_type; ///< frame type of the previous frame - int frame_num; - uint32_t pic_hdr_size; ///< picture header size in bytes - uint8_t frame_flags; - uint16_t checksum; ///< frame checksum - - IVIHuffTab mb_vlc; ///< vlc table for decoding macroblock data - - uint16_t gop_hdr_size; - uint8_t gop_flags; - int is_scalable; - uint32_t lock_word; - IVIPicConfig pic_conf; -} IVI5DecContext; - - /** * Decode Indeo5 GOP (Group of pictures) header. * This header is present in key frames only. @@ -88,7 +57,7 @@ typedef struct { * @param[in] avctx ptr to the AVCodecContext * @return result code: 0 = OK, -1 = error */ -static int decode_gop_header(IVI5DecContext *ctx, AVCodecContext *avctx) +static int decode_gop_header(IVI45DecContext *ctx, AVCodecContext *avctx) { int result, i, p, tile_size, pic_size_indx, mb_size, blk_size, is_scalable; int quant_mat, blk_size_changed = 0; @@ -105,7 +74,7 @@ static int decode_gop_header(IVI5DecContext *ctx, AVCodecContext *avctx) tile_size = (ctx->gop_flags & 0x40) ? 64 << get_bits(&ctx->gb, 2) : 0; if (tile_size > 256) { av_log(avctx, AV_LOG_ERROR, "Invalid tile size: %d\n", tile_size); - return -1; + return AVERROR_INVALIDDATA; } /* decode number of wavelet bands */ @@ -116,7 +85,7 @@ static int decode_gop_header(IVI5DecContext *ctx, AVCodecContext *avctx) if (is_scalable && (pic_conf.luma_bands != 4 || pic_conf.chroma_bands != 1)) { av_log(avctx, AV_LOG_ERROR, "Scalability: unsupported subdivision! Luma bands: %d, chroma bands: %d\n", pic_conf.luma_bands, pic_conf.chroma_bands); - return -1; + return AVERROR_INVALIDDATA; } pic_size_indx = get_bits(&ctx->gb, 4); @@ -129,8 +98,8 @@ static int decode_gop_header(IVI5DecContext *ctx, AVCodecContext *avctx) } if (ctx->gop_flags & 2) { - av_log(avctx, AV_LOG_ERROR, "YV12 picture format not supported!\n"); - return -1; + av_log_missing_feature(avctx, "YV12 picture format", 0); + return AVERROR_PATCHWELCOME; } pic_conf.chroma_height = (pic_conf.pic_height + 3) >> 2; @@ -144,11 +113,11 @@ static int decode_gop_header(IVI5DecContext *ctx, AVCodecContext *avctx) } /* check if picture layout was changed and reallocate buffers */ - if (ivi_pic_config_cmp(&pic_conf, &ctx->pic_conf)) { + if (ivi_pic_config_cmp(&pic_conf, &ctx->pic_conf) || ctx->gop_invalid) { result = ff_ivi_init_planes(ctx->planes, &pic_conf); - if (result) { + if (result < 0) { av_log(avctx, AV_LOG_ERROR, "Couldn't reallocate color planes!\n"); - return -1; + return result; } ctx->pic_conf = pic_conf; ctx->is_scalable = is_scalable; @@ -172,46 +141,54 @@ static int decode_gop_header(IVI5DecContext *ctx, AVCodecContext *avctx) } if (get_bits1(&ctx->gb)) { - av_log(avctx, AV_LOG_ERROR, "Extended transform info encountered!\n"); - return -1; + av_log_missing_feature(avctx, "Extended transform info", 0); + return AVERROR_PATCHWELCOME; } /* select transform function and scan pattern according to plane and band number */ switch ((p << 2) + i) { case 0: - band->inv_transform = ff_ivi_inverse_slant_8x8; - band->dc_transform = ff_ivi_dc_slant_2d; - band->scan = ff_zigzag_direct; + band->inv_transform = ff_ivi_inverse_slant_8x8; + band->dc_transform = ff_ivi_dc_slant_2d; + band->scan = ff_zigzag_direct; + band->transform_size = 8; break; case 1: - band->inv_transform = ff_ivi_row_slant8; - band->dc_transform = ff_ivi_dc_row_slant; - band->scan = ff_ivi_vertical_scan_8x8; + band->inv_transform = ff_ivi_row_slant8; + band->dc_transform = ff_ivi_dc_row_slant; + band->scan = ff_ivi_vertical_scan_8x8; + band->transform_size = 8; break; case 2: - band->inv_transform = ff_ivi_col_slant8; - band->dc_transform = ff_ivi_dc_col_slant; - band->scan = ff_ivi_horizontal_scan_8x8; + band->inv_transform = ff_ivi_col_slant8; + band->dc_transform = ff_ivi_dc_col_slant; + band->scan = ff_ivi_horizontal_scan_8x8; + band->transform_size = 8; break; case 3: - band->inv_transform = ff_ivi_put_pixels_8x8; - band->dc_transform = ff_ivi_put_dc_pixel_8x8; - band->scan = ff_ivi_horizontal_scan_8x8; + band->inv_transform = ff_ivi_put_pixels_8x8; + band->dc_transform = ff_ivi_put_dc_pixel_8x8; + band->scan = ff_ivi_horizontal_scan_8x8; + band->transform_size = 8; break; case 4: - band->inv_transform = ff_ivi_inverse_slant_4x4; - band->dc_transform = ff_ivi_dc_slant_2d; - band->scan = ff_ivi_direct_scan_4x4; + band->inv_transform = ff_ivi_inverse_slant_4x4; + band->dc_transform = ff_ivi_dc_slant_2d; + band->scan = ff_ivi_direct_scan_4x4; + band->transform_size = 4; break; } band->is_2d_trans = band->inv_transform == ff_ivi_inverse_slant_8x8 || band->inv_transform == ff_ivi_inverse_slant_4x4; + if (band->transform_size != band->blk_size) + return AVERROR_INVALIDDATA; + /* select dequant matrix according to plane and band number */ if (!p) { quant_mat = (pic_conf.luma_bands > 1) ? i+1 : 0; @@ -220,6 +197,10 @@ static int decode_gop_header(IVI5DecContext *ctx, AVCodecContext *avctx) } if (band->blk_size == 8) { + if(quant_mat >= 5){ + av_log(avctx, AV_LOG_ERROR, "quant_mat %d too large!\n", quant_mat); + return -1; + } band->intra_base = &ivi5_base_quant_8x8_intra[quant_mat][0]; band->inter_base = &ivi5_base_quant_8x8_inter[quant_mat][0]; band->intra_scale = &ivi5_scale_quant_8x8_intra[quant_mat][0]; @@ -233,7 +214,7 @@ static int decode_gop_header(IVI5DecContext *ctx, AVCodecContext *avctx) if (get_bits(&ctx->gb, 2)) { av_log(avctx, AV_LOG_ERROR, "End marker missing!\n"); - return -1; + return AVERROR_INVALIDDATA; } } } @@ -262,17 +243,17 @@ static int decode_gop_header(IVI5DecContext *ctx, AVCodecContext *avctx) if (blk_size_changed) { result = ff_ivi_init_tiles(ctx->planes, pic_conf.tile_width, pic_conf.tile_height); - if (result) { + if (result < 0) { av_log(avctx, AV_LOG_ERROR, "Couldn't reallocate internal structures!\n"); - return -1; + return result; } } if (ctx->gop_flags & 8) { if (get_bits(&ctx->gb, 3)) { av_log(avctx, AV_LOG_ERROR, "Alignment bits are not zero!\n"); - return -1; + return AVERROR_INVALIDDATA; } if (get_bits1(&ctx->gb)) @@ -319,25 +300,31 @@ static inline void skip_hdr_extension(GetBitContext *gb) * @param[in] avctx ptr to the AVCodecContext * @return result code: 0 = OK, -1 = error */ -static int decode_pic_hdr(IVI5DecContext *ctx, AVCodecContext *avctx) +static int decode_pic_hdr(IVI45DecContext *ctx, AVCodecContext *avctx) { + int ret; + if (get_bits(&ctx->gb, 5) != 0x1F) { av_log(avctx, AV_LOG_ERROR, "Invalid picture start code!\n"); - return -1; + return AVERROR_INVALIDDATA; } ctx->prev_frame_type = ctx->frame_type; ctx->frame_type = get_bits(&ctx->gb, 3); if (ctx->frame_type >= 5) { av_log(avctx, AV_LOG_ERROR, "Invalid frame type: %d \n", ctx->frame_type); - return -1; + return AVERROR_INVALIDDATA; } ctx->frame_num = get_bits(&ctx->gb, 8); if (ctx->frame_type == FRAMETYPE_INTRA) { - if (decode_gop_header(ctx, avctx)) - return -1; + if ((ret = decode_gop_header(ctx, avctx)) < 0) { + av_log(avctx, AV_LOG_ERROR, "Invalid GOP header, skipping frames.\n"); + ctx->gop_invalid = 1; + return ret; + } + ctx->gop_invalid = 0; } if (ctx->frame_type != FRAMETYPE_NULL) { @@ -352,8 +339,10 @@ static int decode_pic_hdr(IVI5DecContext *ctx, AVCodecContext *avctx) skip_hdr_extension(&ctx->gb); /* XXX: untested */ /* decode macroblock huffman codebook */ - if (ff_ivi_dec_huff_desc(&ctx->gb, ctx->frame_flags & 0x40, IVI_MB_HUFF, &ctx->mb_vlc, avctx)) - return -1; + ret = ff_ivi_dec_huff_desc(&ctx->gb, ctx->frame_flags & 0x40, + IVI_MB_HUFF, &ctx->mb_vlc, avctx); + if (ret < 0) + return ret; skip_bits(&ctx->gb, 3); /* FIXME: unknown meaning! */ } @@ -372,10 +361,10 @@ static int decode_pic_hdr(IVI5DecContext *ctx, AVCodecContext *avctx) * @param[in] avctx ptr to the AVCodecContext * @return result code: 0 = OK, -1 = error */ -static int decode_band_hdr(IVI5DecContext *ctx, IVIBandDesc *band, +static int decode_band_hdr(IVI45DecContext *ctx, IVIBandDesc *band, AVCodecContext *avctx) { - int i; + int i, ret; uint8_t band_flags; band_flags = get_bits(&ctx->gb, 8); @@ -399,7 +388,7 @@ static int decode_band_hdr(IVI5DecContext *ctx, IVIBandDesc *band, if (band->num_corr > 61) { av_log(avctx, AV_LOG_ERROR, "Too many corrections: %d\n", band->num_corr); - return -1; + return AVERROR_INVALIDDATA; } /* read correction pairs */ @@ -411,8 +400,10 @@ static int decode_band_hdr(IVI5DecContext *ctx, IVIBandDesc *band, band->rvmap_sel = (band_flags & 0x40) ? get_bits(&ctx->gb, 3) : 8; /* decode block huffman codebook */ - if (ff_ivi_dec_huff_desc(&ctx->gb, band_flags & 0x80, IVI_BLK_HUFF, &band->blk_vlc, avctx)) - return -1; + ret = ff_ivi_dec_huff_desc(&ctx->gb, band_flags & 0x80, IVI_BLK_HUFF, + &band->blk_vlc, avctx); + if (ret < 0) + return ret; band->checksum_present = get_bits1(&ctx->gb); if (band->checksum_present) @@ -442,7 +433,7 @@ static int decode_band_hdr(IVI5DecContext *ctx, IVIBandDesc *band, * @param[in] avctx ptr to the AVCodecContext * @return result code: 0 = OK, -1 = error */ -static int decode_mb_info(IVI5DecContext *ctx, IVIBandDesc *band, +static int decode_mb_info(IVI45DecContext *ctx, IVIBandDesc *band, IVITile *tile, AVCodecContext *avctx) { int x, y, mv_x, mv_y, mv_delta, offs, mb_offset, @@ -458,6 +449,12 @@ static int decode_mb_info(IVI5DecContext *ctx, IVIBandDesc *band, ((band->qdelta_present && band->inherit_qdelta) || band->inherit_mv)) return AVERROR_INVALIDDATA; + if (tile->num_MBs != IVI_MBs_PER_TILE(tile->width, tile->height, band->mb_size)) { + av_log(avctx, AV_LOG_ERROR, "Allocated tile size %d mismatches parameters %d\n", + tile->num_MBs, IVI_MBs_PER_TILE(tile->width, tile->height, band->mb_size)); + return AVERROR_INVALIDDATA; + } + /* scale factor for motion vectors */ mv_scale = (ctx->planes[0].bands[0].mb_size >> 3) - (band->mb_size >> 3); mv_x = mv_y = 0; @@ -473,7 +470,7 @@ static int decode_mb_info(IVI5DecContext *ctx, IVIBandDesc *band, if (get_bits1(&ctx->gb)) { if (ctx->frame_type == FRAMETYPE_INTRA) { av_log(avctx, AV_LOG_ERROR, "Empty macroblock in an INTRA picture!\n"); - return -1; + return AVERROR_INVALIDDATA; } mb->type = 1; /* empty macroblocks are always INTER */ mb->cbp = 0; /* all blocks are empty */ @@ -561,102 +558,12 @@ static int decode_mb_info(IVI5DecContext *ctx, IVIBandDesc *band, } -/** - * Decode an Indeo5 band. - * - * @param[in,out] ctx ptr to the decoder context - * @param[in,out] band ptr to the band descriptor - * @param[in] avctx ptr to the AVCodecContext - * @return result code: 0 = OK, -1 = error - */ -static int decode_band(IVI5DecContext *ctx, int plane_num, - IVIBandDesc *band, AVCodecContext *avctx) -{ - int result, i, t, idx1, idx2, pos; - IVITile *tile; - - band->buf = band->bufs[ctx->dst_buf]; - band->ref_buf = band->bufs[ctx->ref_buf]; - band->data_ptr = ctx->frame_data + (get_bits_count(&ctx->gb) >> 3); - - result = decode_band_hdr(ctx, band, avctx); - if (result) { - av_log(avctx, AV_LOG_ERROR, "Error while decoding band header: %d\n", - result); - return -1; - } - - if (band->is_empty) { - av_log(avctx, AV_LOG_ERROR, "Empty band encountered!\n"); - return -1; - } - - band->rv_map = &ctx->rvmap_tabs[band->rvmap_sel]; - - /* apply corrections to the selected rvmap table if present */ - for (i = 0; i < band->num_corr; i++) { - idx1 = band->corr[i*2]; - idx2 = band->corr[i*2+1]; - FFSWAP(uint8_t, band->rv_map->runtab[idx1], band->rv_map->runtab[idx2]); - FFSWAP(int16_t, band->rv_map->valtab[idx1], band->rv_map->valtab[idx2]); - } - - pos = get_bits_count(&ctx->gb); - - for (t = 0; t < band->num_tiles; t++) { - tile = &band->tiles[t]; - - tile->is_empty = get_bits1(&ctx->gb); - if (tile->is_empty) { - ff_ivi_process_empty_tile(avctx, band, tile, - (ctx->planes[0].bands[0].mb_size >> 3) - (band->mb_size >> 3)); - } else { - tile->data_size = ff_ivi_dec_tile_data_size(&ctx->gb); - - result = decode_mb_info(ctx, band, tile, avctx); - if (result < 0) - break; - - result = ff_ivi_decode_blocks(&ctx->gb, band, tile); - if (result < 0 || (get_bits_count(&ctx->gb) - pos) >> 3 != tile->data_size) { - av_log(avctx, AV_LOG_ERROR, "Corrupted tile data encountered!\n"); - break; - } - pos += tile->data_size << 3; // skip to next tile - } - } - - /* restore the selected rvmap table by applying its corrections in reverse order */ - for (i = band->num_corr-1; i >= 0; i--) { - idx1 = band->corr[i*2]; - idx2 = band->corr[i*2+1]; - FFSWAP(uint8_t, band->rv_map->runtab[idx1], band->rv_map->runtab[idx2]); - FFSWAP(int16_t, band->rv_map->valtab[idx1], band->rv_map->valtab[idx2]); - } - -#ifdef DEBUG - if (band->checksum_present) { - uint16_t chksum = ivi_calc_band_checksum(band); - if (chksum != band->checksum) { - av_log(avctx, AV_LOG_ERROR, - "Band checksum mismatch! Plane %d, band %d, received: %x, calculated: %x\n", - band->plane, band->band_num, band->checksum, chksum); - } - } -#endif - - align_get_bits(&ctx->gb); - - return result; -} - - /** * Switch buffers. * * @param[in,out] ctx ptr to the decoder context */ -static void switch_buffers(IVI5DecContext *ctx) +static void switch_buffers(IVI45DecContext *ctx) { switch (ctx->prev_frame_type) { case FRAMETYPE_INTRA: @@ -694,12 +601,18 @@ static void switch_buffers(IVI5DecContext *ctx) } +static int is_nonnull_frame(IVI45DecContext *ctx) +{ + return ctx->frame_type != FRAMETYPE_NULL; +} + + /** * Initialize Indeo5 decoder. */ static av_cold int decode_init(AVCodecContext *avctx) { - IVI5DecContext *ctx = avctx->priv_data; + IVI45DecContext *ctx = avctx->priv_data; int result; ff_ivi_init_static_vlc(); @@ -723,115 +636,31 @@ static av_cold int decode_init(AVCodecContext *avctx) result = ff_ivi_init_planes(ctx->planes, &ctx->pic_conf); if (result) { av_log(avctx, AV_LOG_ERROR, "Couldn't allocate color planes!\n"); - return -1; + return AVERROR_INVALIDDATA; } ctx->buf_switch = 0; ctx->inter_scal = 0; + ctx->decode_pic_hdr = decode_pic_hdr; + ctx->decode_band_hdr = decode_band_hdr; + ctx->decode_mb_info = decode_mb_info; + ctx->switch_buffers = switch_buffers; + ctx->is_nonnull_frame = is_nonnull_frame; + avctx->pix_fmt = PIX_FMT_YUV410P; return 0; } -/** - * main decoder function - */ -static int decode_frame(AVCodecContext *avctx, void *data, int *data_size, - AVPacket *avpkt) -{ - IVI5DecContext *ctx = avctx->priv_data; - const uint8_t *buf = avpkt->data; - int buf_size = avpkt->size; - int result, p, b; - - init_get_bits(&ctx->gb, buf, buf_size * 8); - ctx->frame_data = buf; - ctx->frame_size = buf_size; - - result = decode_pic_hdr(ctx, avctx); - if (result) { - av_log(avctx, AV_LOG_ERROR, - "Error while decoding picture header: %d\n", result); - return -1; - } - - if (ctx->gop_flags & IVI5_IS_PROTECTED) { - av_log(avctx, AV_LOG_ERROR, "Password-protected clip!\n"); - return -1; - } - - switch_buffers(ctx); - - //{ START_TIMER; - - if (ctx->frame_type != FRAMETYPE_NULL) { - for (p = 0; p < 3; p++) { - for (b = 0; b < ctx->planes[p].num_bands; b++) { - result = decode_band(ctx, p, &ctx->planes[p].bands[b], avctx); - if (result) { - av_log(avctx, AV_LOG_ERROR, - "Error while decoding band: %d, plane: %d\n", b, p); - return -1; - } - } - } - } - - //STOP_TIMER("decode_planes"); } - - if (ctx->frame.data[0]) - avctx->release_buffer(avctx, &ctx->frame); - - ctx->frame.reference = 0; - if (avctx->get_buffer(avctx, &ctx->frame) < 0) { - av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n"); - return -1; - } - - if (ctx->is_scalable) { - ff_ivi_recompose53 (&ctx->planes[0], ctx->frame.data[0], ctx->frame.linesize[0], 4); - } else { - ff_ivi_output_plane(&ctx->planes[0], ctx->frame.data[0], ctx->frame.linesize[0]); - } - - ff_ivi_output_plane(&ctx->planes[2], ctx->frame.data[1], ctx->frame.linesize[1]); - ff_ivi_output_plane(&ctx->planes[1], ctx->frame.data[2], ctx->frame.linesize[2]); - - *data_size = sizeof(AVFrame); - *(AVFrame*)data = ctx->frame; - - return buf_size; -} - - -/** - * Close Indeo5 decoder and clean up its context. - */ -static av_cold int decode_close(AVCodecContext *avctx) -{ - IVI5DecContext *ctx = avctx->priv_data; - - ff_ivi_free_buffers(&ctx->planes[0]); - - if (ctx->mb_vlc.cust_tab.table) - free_vlc(&ctx->mb_vlc.cust_tab); - - if (ctx->frame.data[0]) - avctx->release_buffer(avctx, &ctx->frame); - - return 0; -} - - AVCodec ff_indeo5_decoder = { .name = "indeo5", .type = AVMEDIA_TYPE_VIDEO, .id = CODEC_ID_INDEO5, - .priv_data_size = sizeof(IVI5DecContext), + .priv_data_size = sizeof(IVI45DecContext), .init = decode_init, - .close = decode_close, - .decode = decode_frame, + .close = ff_ivi_decode_close, + .decode = ff_ivi_decode_frame, .long_name = NULL_IF_CONFIG_SMALL("Intel Indeo Video Interactive 5"), }; diff --git a/libavcodec/intelh263dec.c b/libavcodec/intelh263dec.c index 836e98ee88..b6292a0689 100644 --- a/libavcodec/intelh263dec.c +++ b/libavcodec/intelh263dec.c @@ -65,8 +65,8 @@ int ff_intel_h263_decode_picture_header(MpegEncContext *s) s->pb_frame = get_bits1(&s->gb); if (format < 6) { - s->width = h263_format[format][0]; - s->height = h263_format[format][1]; + s->width = ff_h263_format[format][0]; + s->height = ff_h263_format[format][1]; s->avctx->sample_aspect_ratio.num = 12; s->avctx->sample_aspect_ratio.den = 11; } else { @@ -77,7 +77,7 @@ int ff_intel_h263_decode_picture_header(MpegEncContext *s) } if(get_bits(&s->gb, 2)) av_log(s->avctx, AV_LOG_ERROR, "Bad value for reserved field\n"); - s->loop_filter = get_bits1(&s->gb); + s->loop_filter = get_bits1(&s->gb) * !s->avctx->lowres; if(get_bits1(&s->gb)) av_log(s->avctx, AV_LOG_ERROR, "Bad value for reserved field\n"); if(get_bits1(&s->gb)) diff --git a/libavcodec/internal.h b/libavcodec/internal.h index 72a89441c2..3e353be2b0 100644 --- a/libavcodec/internal.h +++ b/libavcodec/internal.h @@ -136,4 +136,7 @@ int avpriv_unlock_avformat(void); */ int ff_alloc_packet(AVPacket *avpkt, int size); + +int ff_get_buffer(AVCodecContext *avctx, AVFrame *frame); + #endif /* AVCODEC_INTERNAL_H */ diff --git a/libavcodec/ituh263dec.c b/libavcodec/ituh263dec.c index f058c9b848..ed3b7db5b6 100644 --- a/libavcodec/ituh263dec.c +++ b/libavcodec/ituh263dec.c @@ -103,7 +103,7 @@ static VLC cbpc_b_vlc; /* init vlcs */ /* XXX: find a better solution to handle static init */ -void h263_decode_init_vlc(MpegEncContext *s) +void ff_h263_decode_init_vlc(MpegEncContext *s) { static int done = 0; @@ -120,18 +120,18 @@ void h263_decode_init_vlc(MpegEncContext *s) &ff_h263_cbpy_tab[0][1], 2, 1, &ff_h263_cbpy_tab[0][0], 2, 1, 64); INIT_VLC_STATIC(&mv_vlc, MV_VLC_BITS, 33, - &mvtab[0][1], 2, 1, - &mvtab[0][0], 2, 1, 538); - init_rl(&ff_h263_rl_inter, ff_h263_static_rl_table_store[0]); - init_rl(&rl_intra_aic, ff_h263_static_rl_table_store[1]); + &ff_mvtab[0][1], 2, 1, + &ff_mvtab[0][0], 2, 1, 538); + ff_init_rl(&ff_h263_rl_inter, ff_h263_static_rl_table_store[0]); + ff_init_rl(&ff_rl_intra_aic, ff_h263_static_rl_table_store[1]); INIT_VLC_RL(ff_h263_rl_inter, 554); - INIT_VLC_RL(rl_intra_aic, 554); + INIT_VLC_RL(ff_rl_intra_aic, 554); INIT_VLC_STATIC(&h263_mbtype_b_vlc, H263_MBTYPE_B_VLC_BITS, 15, - &h263_mbtype_b_tab[0][1], 2, 1, - &h263_mbtype_b_tab[0][0], 2, 1, 80); + &ff_h263_mbtype_b_tab[0][1], 2, 1, + &ff_h263_mbtype_b_tab[0][0], 2, 1, 80); INIT_VLC_STATIC(&cbpc_b_vlc, CBPC_B_VLC_BITS, 4, - &cbpc_b_tab[0][1], 2, 1, - &cbpc_b_tab[0][0], 2, 1, 8); + &ff_cbpc_b_tab[0][1], 2, 1, + &ff_cbpc_b_tab[0][0], 2, 1, 8); } } @@ -271,7 +271,7 @@ int ff_h263_resync(MpegEncContext *s){ return -1; } -int h263_decode_motion(MpegEncContext * s, int pred, int f_code) +int ff_h263_decode_motion(MpegEncContext * s, int pred, int f_code) { int code, val, sign, shift; code = get_vlc2(&s->gb, mv_vlc.table, MV_VLC_BITS, 2); @@ -381,16 +381,16 @@ static void preview_obmc(MpegEncContext *s){ if ((cbpc & 16) == 0) { s->current_picture.f.mb_type[xy] = MB_TYPE_16x16 | MB_TYPE_L0; /* 16x16 motion prediction */ - mot_val= h263_pred_motion(s, 0, 0, &pred_x, &pred_y); + mot_val= ff_h263_pred_motion(s, 0, 0, &pred_x, &pred_y); if (s->umvplus) mx = h263p_decode_umotion(s, pred_x); else - mx = h263_decode_motion(s, pred_x, 1); + mx = ff_h263_decode_motion(s, pred_x, 1); if (s->umvplus) my = h263p_decode_umotion(s, pred_y); else - my = h263_decode_motion(s, pred_y, 1); + my = ff_h263_decode_motion(s, pred_y, 1); mot_val[0 ]= mot_val[2 ]= mot_val[0+stride]= mot_val[2+stride]= mx; @@ -399,16 +399,16 @@ static void preview_obmc(MpegEncContext *s){ } else { s->current_picture.f.mb_type[xy] = MB_TYPE_8x8 | MB_TYPE_L0; for(i=0;i<4;i++) { - mot_val = h263_pred_motion(s, i, 0, &pred_x, &pred_y); + mot_val = ff_h263_pred_motion(s, i, 0, &pred_x, &pred_y); if (s->umvplus) mx = h263p_decode_umotion(s, pred_x); else - mx = h263_decode_motion(s, pred_x, 1); + mx = ff_h263_decode_motion(s, pred_x, 1); if (s->umvplus) my = h263p_decode_umotion(s, pred_y); else - my = h263_decode_motion(s, pred_y, 1); + my = ff_h263_decode_motion(s, pred_y, 1); if (s->umvplus && (mx - pred_x) == 1 && (my - pred_y) == 1) skip_bits1(&s->gb); /* Bit stuffing to prevent PSC */ mot_val[0] = mx; @@ -432,7 +432,7 @@ static void h263_decode_dquant(MpegEncContext *s){ if(s->modified_quant){ if(get_bits1(&s->gb)) - s->qscale= modified_quant_tab[get_bits1(&s->gb)][ s->qscale ]; + s->qscale= ff_modified_quant_tab[get_bits1(&s->gb)][ s->qscale ]; else s->qscale= get_bits(&s->gb, 5); }else @@ -450,7 +450,7 @@ static int h263_decode_block(MpegEncContext * s, DCTELEM * block, scan_table = s->intra_scantable.permutated; if (s->h263_aic && s->mb_intra) { - rl = &rl_intra_aic; + rl = &ff_rl_intra_aic; i = 0; if (s->ac_pred) { if (s->h263_aic_dir) @@ -539,7 +539,7 @@ retry: if (i >= 64){ if(s->alt_inter_vlc && rl == &ff_h263_rl_inter && !s->mb_intra){ //Looks like a hack but no, it's the way it is supposed to work ... - rl = &rl_intra_aic; + rl = &ff_rl_intra_aic; i = 0; s->gb= gb; s->dsp.clear_block(block); @@ -556,7 +556,7 @@ retry: } not_coded: if (s->mb_intra && s->h263_aic) { - h263_pred_acdc(s, block, n); + ff_h263_pred_acdc(s, block, n); i = 63; } s->block_last_index[n] = i; @@ -655,11 +655,11 @@ int ff_h263_decode_mb(MpegEncContext *s, s->current_picture.f.mb_type[xy] = MB_TYPE_16x16 | MB_TYPE_L0; /* 16x16 motion prediction */ s->mv_type = MV_TYPE_16X16; - h263_pred_motion(s, 0, 0, &pred_x, &pred_y); + ff_h263_pred_motion(s, 0, 0, &pred_x, &pred_y); if (s->umvplus) mx = h263p_decode_umotion(s, pred_x); else - mx = h263_decode_motion(s, pred_x, 1); + mx = ff_h263_decode_motion(s, pred_x, 1); if (mx >= 0xffff) return -1; @@ -667,7 +667,7 @@ int ff_h263_decode_mb(MpegEncContext *s, if (s->umvplus) my = h263p_decode_umotion(s, pred_y); else - my = h263_decode_motion(s, pred_y, 1); + my = ff_h263_decode_motion(s, pred_y, 1); if (my >= 0xffff) return -1; @@ -680,18 +680,18 @@ int ff_h263_decode_mb(MpegEncContext *s, s->current_picture.f.mb_type[xy] = MB_TYPE_8x8 | MB_TYPE_L0; s->mv_type = MV_TYPE_8X8; for(i=0;i<4;i++) { - mot_val = h263_pred_motion(s, i, 0, &pred_x, &pred_y); + mot_val = ff_h263_pred_motion(s, i, 0, &pred_x, &pred_y); if (s->umvplus) mx = h263p_decode_umotion(s, pred_x); else - mx = h263_decode_motion(s, pred_x, 1); + mx = ff_h263_decode_motion(s, pred_x, 1); if (mx >= 0xffff) return -1; if (s->umvplus) my = h263p_decode_umotion(s, pred_y); else - my = h263_decode_motion(s, pred_y, 1); + my = ff_h263_decode_motion(s, pred_y, 1); if (my >= 0xffff) return -1; s->mv[0][i][0] = mx; @@ -755,6 +755,8 @@ int ff_h263_decode_mb(MpegEncContext *s, } if(IS_DIRECT(mb_type)){ + if (!s->pp_time) + return AVERROR_INVALIDDATA; s->mv_dir = MV_DIR_FORWARD | MV_DIR_BACKWARD | MV_DIRECT; mb_type |= ff_mpeg4_set_direct_mv(s, 0, 0); }else{ @@ -763,11 +765,11 @@ int ff_h263_decode_mb(MpegEncContext *s, //FIXME UMV if(USES_LIST(mb_type, 0)){ - int16_t *mot_val= h263_pred_motion(s, 0, 0, &mx, &my); + int16_t *mot_val= ff_h263_pred_motion(s, 0, 0, &mx, &my); s->mv_dir = MV_DIR_FORWARD; - mx = h263_decode_motion(s, mx, 1); - my = h263_decode_motion(s, my, 1); + mx = ff_h263_decode_motion(s, mx, 1); + my = ff_h263_decode_motion(s, my, 1); s->mv[0][0][0] = mx; s->mv[0][0][1] = my; @@ -776,11 +778,11 @@ int ff_h263_decode_mb(MpegEncContext *s, } if(USES_LIST(mb_type, 1)){ - int16_t *mot_val= h263_pred_motion(s, 0, 1, &mx, &my); + int16_t *mot_val= ff_h263_pred_motion(s, 0, 1, &mx, &my); s->mv_dir |= MV_DIR_BACKWARD; - mx = h263_decode_motion(s, mx, 1); - my = h263_decode_motion(s, my, 1); + mx = ff_h263_decode_motion(s, mx, 1); + my = ff_h263_decode_motion(s, my, 1); s->mv[1][0][0] = mx; s->mv[1][0][1] = my; @@ -831,8 +833,8 @@ intra: } while(pb_mv_count--){ - h263_decode_motion(s, 0, 1); - h263_decode_motion(s, 0, 1); + ff_h263_decode_motion(s, 0, 1); + ff_h263_decode_motion(s, 0, 1); } /* decode each block */ @@ -854,8 +856,8 @@ end: { int v= show_bits(&s->gb, 16); - if(get_bits_count(&s->gb) + 16 > s->gb.size_in_bits){ - v>>= get_bits_count(&s->gb) + 16 - s->gb.size_in_bits; + if (get_bits_left(&s->gb) < 16) { + v >>= 16 - get_bits_left(&s->gb); } if(v==0) @@ -866,7 +868,7 @@ end: } /* most is hardcoded. should extend to handle all h263 streams */ -int h263_decode_picture_header(MpegEncContext *s) +int ff_h263_decode_picture_header(MpegEncContext *s) { int format, width, height, i; uint32_t startcode; @@ -918,8 +920,8 @@ int h263_decode_picture_header(MpegEncContext *s) if (format != 7 && format != 6) { s->h263_plus = 0; /* H.263v1 */ - width = h263_format[format][0]; - height = h263_format[format][1]; + width = ff_h263_format[format][0]; + height = ff_h263_format[format][1]; if (!width) return -1; @@ -963,6 +965,8 @@ int h263_decode_picture_header(MpegEncContext *s) s->h263_aic = get_bits1(&s->gb); /* Advanced Intra Coding (AIC) */ s->loop_filter= get_bits1(&s->gb); s->unrestricted_mv = s->umvplus || s->obmc || s->loop_filter; + if(s->avctx->lowres) + s->loop_filter = 0; s->h263_slice_structured= get_bits1(&s->gb); if (get_bits1(&s->gb) != 0) { @@ -1026,8 +1030,8 @@ int h263_decode_picture_header(MpegEncContext *s) s->avctx->sample_aspect_ratio= ff_h263_pixel_aspect[s->aspect_ratio_info]; } } else { - width = h263_format[format][0]; - height = h263_format[format][1]; + width = ff_h263_format[format][0]; + height = ff_h263_format[format][1]; s->avctx->sample_aspect_ratio= (AVRational){12,11}; } if ((width == 0) || (height == 0)) diff --git a/libavcodec/ituh263enc.c b/libavcodec/ituh263enc.c index 9d41376ca7..103adb5faa 100644 --- a/libavcodec/ituh263enc.c +++ b/libavcodec/ituh263enc.c @@ -102,7 +102,7 @@ av_const int ff_h263_aspect_to_info(AVRational aspect){ return FF_ASPECT_EXTENDED; } -void h263_encode_picture_header(MpegEncContext * s, int picture_number) +void ff_h263_encode_picture_header(MpegEncContext * s, int picture_number) { int format, coded_frame_rate, coded_frame_rate_base, i, temp_ref; int best_clock_code=1; @@ -141,7 +141,7 @@ void h263_encode_picture_header(MpegEncContext * s, int picture_number) put_bits(&s->pb, 1, 0); /* camera off */ put_bits(&s->pb, 1, 0); /* freeze picture release off */ - format = ff_match_2uint16(h263_format, FF_ARRAY_ELEMS(h263_format), s->width, s->height); + format = ff_match_2uint16(ff_h263_format, FF_ARRAY_ELEMS(ff_h263_format), s->width, s->height); if (!s->h263_plus) { /* H.263v1 */ put_bits(&s->pb, 3, format); @@ -247,7 +247,7 @@ void h263_encode_picture_header(MpegEncContext * s, int picture_number) /** * Encode a group of blocks header. */ -void h263_encode_gob_header(MpegEncContext * s, int mb_line) +void ff_h263_encode_gob_header(MpegEncContext * s, int mb_line) { put_bits(&s->pb, 17, 1); /* GBSC */ @@ -333,7 +333,7 @@ static void h263_encode_block(MpegEncContext * s, DCTELEM * block, int n) } else { i = 0; if (s->h263_aic && s->mb_intra) - rl = &rl_intra_aic; + rl = &ff_rl_intra_aic; if(s->alt_inter_vlc && !s->mb_intra){ int aic_vlc_bits=0; @@ -353,14 +353,14 @@ static void h263_encode_block(MpegEncContext * s, DCTELEM * block, int n) if(level<0) level= -level; code = get_rl_index(rl, last, run, level); - aic_code = get_rl_index(&rl_intra_aic, last, run, level); + aic_code = get_rl_index(&ff_rl_intra_aic, last, run, level); inter_vlc_bits += rl->table_vlc[code][1]+1; - aic_vlc_bits += rl_intra_aic.table_vlc[aic_code][1]+1; + aic_vlc_bits += ff_rl_intra_aic.table_vlc[aic_code][1]+1; if (code == rl->n) { inter_vlc_bits += 1+6+8-1; } - if (aic_code == rl_intra_aic.n) { + if (aic_code == ff_rl_intra_aic.n) { aic_vlc_bits += 1+6+8-1; wrong_pos += run + 1; }else @@ -370,7 +370,7 @@ static void h263_encode_block(MpegEncContext * s, DCTELEM * block, int n) } i = 0; if(aic_vlc_bits < inter_vlc_bits && wrong_pos > 63) - rl = &rl_intra_aic; + rl = &ff_rl_intra_aic; } } @@ -454,9 +454,9 @@ static void h263p_encode_umotion(MpegEncContext * s, int val) } } -void h263_encode_mb(MpegEncContext * s, - DCTELEM block[6][64], - int motion_x, int motion_y) +void ff_h263_encode_mb(MpegEncContext * s, + DCTELEM block[6][64], + int motion_x, int motion_y) { int cbpc, cbpy, i, cbp, pred_x, pred_y; int16_t pred_dc; @@ -500,7 +500,7 @@ void h263_encode_mb(MpegEncContext * s, } /* motion vectors: 16x16 mode */ - h263_pred_motion(s, 0, 0, &pred_x, &pred_y); + ff_h263_pred_motion(s, 0, 0, &pred_x, &pred_y); if (!s->umvplus) { ff_h263_encode_motion_vector(s, motion_x - pred_x, @@ -527,7 +527,7 @@ void h263_encode_mb(MpegEncContext * s, for(i=0; i<4; i++){ /* motion vectors: 8x8 mode*/ - h263_pred_motion(s, i, 0, &pred_x, &pred_y); + ff_h263_pred_motion(s, i, 0, &pred_x, &pred_y); motion_x = s->current_picture.f.motion_val[0][s->block_index[i]][0]; motion_y = s->current_picture.f.motion_val[0][s->block_index[i]][1]; @@ -561,7 +561,7 @@ void h263_encode_mb(MpegEncContext * s, if(i<4) scale= s->y_dc_scale; else scale= s->c_dc_scale; - pred_dc = h263_pred_dc(s, i, &dc_ptr[i]); + pred_dc = ff_h263_pred_dc(s, i, &dc_ptr[i]); level -= pred_dc; /* Quant */ if (level >= 0) @@ -662,7 +662,7 @@ void ff_h263_encode_motion(MpegEncContext * s, int val, int f_code) if (val == 0) { /* zero vector */ code = 0; - put_bits(&s->pb, mvtab[code][1], mvtab[code][0]); + put_bits(&s->pb, ff_mvtab[code][1], ff_mvtab[code][0]); } else { bit_size = f_code - 1; range = 1 << bit_size; @@ -676,7 +676,7 @@ void ff_h263_encode_motion(MpegEncContext * s, int val, int f_code) code = (val >> bit_size) + 1; bits = val & (range - 1); - put_bits(&s->pb, mvtab[code][1] + 1, (mvtab[code][0] << 1) | sign); + put_bits(&s->pb, ff_mvtab[code][1] + 1, (ff_mvtab[code][0] << 1) | sign); if (bit_size > 0) { put_bits(&s->pb, bit_size, bits); } @@ -692,7 +692,7 @@ static void init_mv_penalty_and_fcode(MpegEncContext *s) for(mv=-MAX_MV; mv<=MAX_MV; mv++){ int len; - if(mv==0) len= mvtab[0][1]; + if(mv==0) len= ff_mvtab[0][1]; else{ int val, bit_size, code; @@ -704,9 +704,9 @@ static void init_mv_penalty_and_fcode(MpegEncContext *s) val--; code = (val >> bit_size) + 1; if(code<33){ - len= mvtab[code][1] + 1 + bit_size; + len= ff_mvtab[code][1] + 1 + bit_size; }else{ - len= mvtab[32][1] + av_log2(code>>5) + 2 + bit_size; + len= ff_mvtab[32][1] + av_log2(code>>5) + 2 + bit_size; } } @@ -768,17 +768,17 @@ static void init_uni_h263_rl_tab(RLTable *rl, uint32_t *bits_tab, uint8_t *len_t } } -void h263_encode_init(MpegEncContext *s) +void ff_h263_encode_init(MpegEncContext *s) { static int done = 0; if (!done) { done = 1; - init_rl(&ff_h263_rl_inter, ff_h263_static_rl_table_store[0]); - init_rl(&rl_intra_aic, ff_h263_static_rl_table_store[1]); + ff_init_rl(&ff_h263_rl_inter, ff_h263_static_rl_table_store[0]); + ff_init_rl(&ff_rl_intra_aic, ff_h263_static_rl_table_store[1]); - init_uni_h263_rl_tab(&rl_intra_aic, NULL, uni_h263_intra_aic_rl_len); + init_uni_h263_rl_tab(&ff_rl_intra_aic, NULL, uni_h263_intra_aic_rl_len); init_uni_h263_rl_tab(&ff_h263_rl_inter , NULL, uni_h263_inter_rl_len); init_mv_penalty_and_fcode(s); diff --git a/libavcodec/ivi_common.c b/libavcodec/ivi_common.c index c75769ec31..fa6abdbfd6 100644 --- a/libavcodec/ivi_common.c +++ b/libavcodec/ivi_common.c @@ -28,6 +28,7 @@ #define BITSTREAM_READER_LE #include "avcodec.h" +#include "internal.h" #include "get_bits.h" #include "ivi_common.h" #include "libavutil/common.h" @@ -39,6 +40,29 @@ extern const IVIHuffDesc ff_ivi_blk_huff_desc[8]; ///< static block huffman tabl VLC ff_ivi_mb_vlc_tabs [8]; VLC ff_ivi_blk_vlc_tabs[8]; +typedef void (*ivi_mc_func) (int16_t *buf, const int16_t *ref_buf, + uint32_t pitch, int mc_type); + +static int ivi_mc(IVIBandDesc *band, ivi_mc_func mc, + int offs, int mv_x, int mv_y, int mc_type) +{ + int ref_offs = offs + mv_y * band->pitch + mv_x; + int buf_size = band->pitch * band->aheight; + int min_size = band->pitch * (band->blk_size - 1) + band->blk_size; + int ref_size = (mc_type > 1) * band->pitch + (mc_type & 1); + + if (offs < 0 || ref_offs < 0 || !band->ref_buf) + return AVERROR_INVALIDDATA; + if (buf_size - min_size < offs) + return AVERROR_INVALIDDATA; + if (buf_size - min_size - ref_size < ref_offs) + return AVERROR_INVALIDDATA; + + mc(band->buf + offs, band->ref_buf + ref_offs, band->pitch, mc_type); + + return 0; +} + /** * Reverse "nbits" bits of the value "val" and return the result * in the least significant bits. @@ -48,9 +72,10 @@ static uint16_t inv_bits(uint16_t val, int nbits) uint16_t res; if (nbits <= 8) { - res = av_reverse[val] >> (8-nbits); + res = av_reverse[val] >> (8 - nbits); } else - res = ((av_reverse[val & 0xFF] << 8) + (av_reverse[val >> 8])) >> (16-nbits); + res = ((av_reverse[val & 0xFF] << 8) + + (av_reverse[val >> 8])) >> (16 - nbits); return res; } @@ -74,7 +99,7 @@ int ff_ivi_create_huff_from_desc(const IVIHuffDesc *cb, VLC *vlc, int flag) bits[pos] = i + cb->xbits[i] + not_last_row; if (bits[pos] > IVI_VLC_BITS) - return -1; /* invalid descriptor */ + return AVERROR_INVALIDDATA; /* invalid descriptor */ codewords[pos] = inv_bits((prefix | j), bits[pos]); if (!bits[pos]) @@ -100,10 +125,12 @@ void ff_ivi_init_static_vlc(void) for (i = 0; i < 8; i++) { ff_ivi_mb_vlc_tabs[i].table = table_data + i * 2 * 8192; ff_ivi_mb_vlc_tabs[i].table_allocated = 8192; - ff_ivi_create_huff_from_desc(&ff_ivi_mb_huff_desc[i], &ff_ivi_mb_vlc_tabs[i], 1); + ff_ivi_create_huff_from_desc(&ff_ivi_mb_huff_desc[i], + &ff_ivi_mb_vlc_tabs[i], 1); ff_ivi_blk_vlc_tabs[i].table = table_data + (i * 2 + 1) * 8192; ff_ivi_blk_vlc_tabs[i].table_allocated = 8192; - ff_ivi_create_huff_from_desc(&ff_ivi_blk_huff_desc[i], &ff_ivi_blk_vlc_tabs[i], 1); + ff_ivi_create_huff_from_desc(&ff_ivi_blk_huff_desc[i], + &ff_ivi_blk_vlc_tabs[i], 1); } initialized_vlcs = 1; } @@ -111,42 +138,48 @@ void ff_ivi_init_static_vlc(void) int ff_ivi_dec_huff_desc(GetBitContext *gb, int desc_coded, int which_tab, IVIHuffTab *huff_tab, AVCodecContext *avctx) { - int i, result; + int i, result; IVIHuffDesc new_huff; if (!desc_coded) { /* select default table */ huff_tab->tab = (which_tab) ? &ff_ivi_blk_vlc_tabs[7] - : &ff_ivi_mb_vlc_tabs [7]; - } else { - huff_tab->tab_sel = get_bits(gb, 3); - if (huff_tab->tab_sel == 7) { - /* custom huffman table (explicitly encoded) */ - new_huff.num_rows = get_bits(gb, 4); + : &ff_ivi_mb_vlc_tabs [7]; + return 0; + } - for (i = 0; i < new_huff.num_rows; i++) - new_huff.xbits[i] = get_bits(gb, 4); - - /* Have we got the same custom table? Rebuild if not. */ - if (ff_ivi_huff_desc_cmp(&new_huff, &huff_tab->cust_desc)) { - ff_ivi_huff_desc_copy(&huff_tab->cust_desc, &new_huff); - - if (huff_tab->cust_tab.table) - free_vlc(&huff_tab->cust_tab); - result = ff_ivi_create_huff_from_desc(&huff_tab->cust_desc, - &huff_tab->cust_tab, 0); - if (result) { - av_log(avctx, AV_LOG_ERROR, - "Error while initializing custom vlc table!\n"); - return -1; - } - } - huff_tab->tab = &huff_tab->cust_tab; - } else { - /* select one of predefined tables */ - huff_tab->tab = (which_tab) ? &ff_ivi_blk_vlc_tabs[huff_tab->tab_sel] - : &ff_ivi_mb_vlc_tabs [huff_tab->tab_sel]; + huff_tab->tab_sel = get_bits(gb, 3); + if (huff_tab->tab_sel == 7) { + /* custom huffman table (explicitly encoded) */ + new_huff.num_rows = get_bits(gb, 4); + if (!new_huff.num_rows) { + av_log(avctx, AV_LOG_ERROR, "Empty custom Huffman table!\n"); + return AVERROR_INVALIDDATA; } + + for (i = 0; i < new_huff.num_rows; i++) + new_huff.xbits[i] = get_bits(gb, 4); + + /* Have we got the same custom table? Rebuild if not. */ + if (ff_ivi_huff_desc_cmp(&new_huff, &huff_tab->cust_desc)) { + ff_ivi_huff_desc_copy(&huff_tab->cust_desc, &new_huff); + + if (huff_tab->cust_tab.table) + ff_free_vlc(&huff_tab->cust_tab); + result = ff_ivi_create_huff_from_desc(&huff_tab->cust_desc, + &huff_tab->cust_tab, 0); + if (result) { + huff_tab->cust_desc.num_rows = 0; // reset faulty description + av_log(avctx, AV_LOG_ERROR, + "Error while initializing custom vlc table!\n"); + return result; + } + } + huff_tab->tab = &huff_tab->cust_tab; + } else { + /* select one of predefined tables */ + huff_tab->tab = (which_tab) ? &ff_ivi_blk_vlc_tabs[huff_tab->tab_sel] + : &ff_ivi_mb_vlc_tabs [huff_tab->tab_sel]; } return 0; @@ -166,12 +199,17 @@ void ff_ivi_huff_desc_copy(IVIHuffDesc *dst, const IVIHuffDesc *src) int av_cold ff_ivi_init_planes(IVIPlaneDesc *planes, const IVIPicConfig *cfg) { - int p, b; - uint32_t b_width, b_height, align_fac, width_aligned, height_aligned, buf_size; + int p, b; + uint32_t b_width, b_height, align_fac, width_aligned, + height_aligned, buf_size; IVIBandDesc *band; ff_ivi_free_buffers(planes); + if (cfg->pic_width < 1 || cfg->pic_height < 1 || + cfg->luma_bands < 1 || cfg->chroma_bands < 1) + return AVERROR_INVALIDDATA; + /* fill in the descriptor of the luminance plane */ planes[0].width = cfg->pic_width; planes[0].height = cfg->pic_height; @@ -190,8 +228,10 @@ int av_cold ff_ivi_init_planes(IVIPlaneDesc *planes, const IVIPicConfig *cfg) /* select band dimensions: if there is only one band then it * has the full size, if there are several bands each of them * has only half size */ - b_width = planes[p].num_bands == 1 ? planes[p].width : (planes[p].width + 1) >> 1; - b_height = planes[p].num_bands == 1 ? planes[p].height : (planes[p].height + 1) >> 1; + b_width = planes[p].num_bands == 1 ? planes[p].width + : (planes[p].width + 1) >> 1; + b_height = planes[p].num_bands == 1 ? planes[p].height + : (planes[p].height + 1) >> 1; /* luma band buffers will be aligned on 16x16 (max macroblock size) */ /* chroma band buffers will be aligned on 8x8 (max macroblock size) */ @@ -207,19 +247,20 @@ int av_cold ff_ivi_init_planes(IVIPlaneDesc *planes, const IVIPicConfig *cfg) band->width = b_width; band->height = b_height; band->pitch = width_aligned; - band->bufs[0] = av_malloc(buf_size); - band->bufs[1] = av_malloc(buf_size); + band->aheight = height_aligned; + band->bufs[0] = av_mallocz(buf_size); + band->bufs[1] = av_mallocz(buf_size); if (!band->bufs[0] || !band->bufs[1]) return AVERROR(ENOMEM); /* allocate the 3rd band buffer for scalability mode */ if (cfg->luma_bands > 1) { - band->bufs[2] = av_malloc(buf_size); + band->bufs[2] = av_mallocz(buf_size); if (!band->bufs[2]) return AVERROR(ENOMEM); } - - planes[p].bands[0].blk_vlc.cust_desc.num_rows = 0; /* reset custom vlc */ + /* reset custom vlc */ + planes[p].bands[0].blk_vlc.cust_desc.num_rows = 0; } } @@ -237,20 +278,57 @@ void av_cold ff_ivi_free_buffers(IVIPlaneDesc *planes) av_freep(&planes[p].bands[b].bufs[2]); if (planes[p].bands[b].blk_vlc.cust_tab.table) - free_vlc(&planes[p].bands[b].blk_vlc.cust_tab); + ff_free_vlc(&planes[p].bands[b].blk_vlc.cust_tab); for (t = 0; t < planes[p].bands[b].num_tiles; t++) av_freep(&planes[p].bands[b].tiles[t].mbs); av_freep(&planes[p].bands[b].tiles); } av_freep(&planes[p].bands); + planes[p].num_bands = 0; } } +static int ivi_init_tiles(IVIBandDesc *band, IVITile *ref_tile, + int p, int b, int t_height, int t_width) +{ + int x, y; + IVITile *tile = band->tiles; + + for (y = 0; y < band->height; y += t_height) { + for (x = 0; x < band->width; x += t_width) { + tile->xpos = x; + tile->ypos = y; + tile->mb_size = band->mb_size; + tile->width = FFMIN(band->width - x, t_width); + tile->height = FFMIN(band->height - y, t_height); + tile->is_empty = tile->data_size = 0; + /* calculate number of macroblocks */ + tile->num_MBs = IVI_MBs_PER_TILE(tile->width, tile->height, + band->mb_size); + + av_freep(&tile->mbs); + tile->mbs = av_malloc(tile->num_MBs * sizeof(IVIMbInfo)); + if (!tile->mbs) + return AVERROR(ENOMEM); + + tile->ref_mbs = 0; + if (p || b) { + if (tile->num_MBs != ref_tile->num_MBs) + return AVERROR_INVALIDDATA; + tile->ref_mbs = ref_tile->mbs; + ref_tile++; + } + tile++; + } + } + + return 0; +} + int av_cold ff_ivi_init_tiles(IVIPlaneDesc *planes, int tile_width, int tile_height) { - int p, b, x, y, x_tiles, y_tiles, t_width, t_height; + int p, b, x_tiles, y_tiles, t_width, t_height, ret; IVIBandDesc *band; - IVITile *tile, *ref_tile; for (p = 0; p < 3; p++) { t_width = !p ? tile_width : (tile_width + 3) >> 2; @@ -274,40 +352,14 @@ int av_cold ff_ivi_init_tiles(IVIPlaneDesc *planes, int tile_width, int tile_hei if (!band->tiles) return AVERROR(ENOMEM); - tile = band->tiles; - /* use the first luma band as reference for motion vectors * and quant */ - ref_tile = planes[0].bands[0].tiles; - - for (y = 0; y < band->height; y += t_height) { - for (x = 0; x < band->width; x += t_width) { - tile->xpos = x; - tile->ypos = y; - tile->width = FFMIN(band->width - x, t_width); - tile->height = FFMIN(band->height - y, t_height); - tile->is_empty = tile->data_size = 0; - /* calculate number of macroblocks */ - tile->num_MBs = IVI_MBs_PER_TILE(tile->width, tile->height, - band->mb_size); - - av_freep(&tile->mbs); - tile->mbs = av_malloc(tile->num_MBs * sizeof(IVIMbInfo)); - if (!tile->mbs) - return AVERROR(ENOMEM); - - tile->ref_mbs = 0; - if (p || b) { - tile->ref_mbs = ref_tile->mbs; - ref_tile++; - } - - tile++; - } - } - - }// for b - }// for p + ret = ivi_init_tiles(band, planes[0].bands[0].tiles, + p, b, t_height, t_width); + if (ret < 0) + return ret; + } + } return 0; } @@ -329,26 +381,125 @@ int ff_ivi_dec_tile_data_size(GetBitContext *gb) return len; } +static int ivi_dc_transform(IVIBandDesc *band, int *prev_dc, int buf_offs, + int blk_size) +{ + int buf_size = band->pitch * band->aheight - buf_offs; + int min_size = (blk_size - 1) * band->pitch + blk_size; + + if (!band->dc_transform) + return 0; + + + if (min_size > buf_size) + return AVERROR_INVALIDDATA; + + band->dc_transform(prev_dc, band->buf + buf_offs, + band->pitch, blk_size); + + return 0; +} + +static int ivi_decode_coded_blocks(GetBitContext *gb, IVIBandDesc *band, + ivi_mc_func mc, int mv_x, int mv_y, + int *prev_dc, int is_intra, int mc_type, + uint32_t quant, int offs) +{ + const uint16_t *base_tab = is_intra ? band->intra_base : band->inter_base; + RVMapDesc *rvmap = band->rv_map; + uint8_t col_flags[8]; + int32_t trvec[64]; + uint32_t sym = 0, lo, hi, q; + int pos, run, val; + int blk_size = band->blk_size; + int num_coeffs = blk_size * blk_size; + int col_mask = blk_size - 1; + int scan_pos = -1; + int min_size = band->pitch * (band->transform_size - 1) + + band->transform_size; + int buf_size = band->pitch * band->aheight - offs; + + if (min_size > buf_size) + return AVERROR_INVALIDDATA; + + if (!band->scan) + return AVERROR_INVALIDDATA; + + /* zero transform vector */ + memset(trvec, 0, num_coeffs * sizeof(trvec[0])); + /* zero column flags */ + memset(col_flags, 0, sizeof(col_flags)); + while (scan_pos <= num_coeffs) { + sym = get_vlc2(gb, band->blk_vlc.tab->table, + IVI_VLC_BITS, 1); + if (sym == rvmap->eob_sym) + break; /* End of block */ + + /* Escape - run/val explicitly coded using 3 vlc codes */ + if (sym == rvmap->esc_sym) { + run = get_vlc2(gb, band->blk_vlc.tab->table, IVI_VLC_BITS, 1) + 1; + lo = get_vlc2(gb, band->blk_vlc.tab->table, IVI_VLC_BITS, 1); + hi = get_vlc2(gb, band->blk_vlc.tab->table, IVI_VLC_BITS, 1); + /* merge them and convert into signed val */ + val = IVI_TOSIGNED((hi << 6) | lo); + } else { + if (sym >= 256U) + return AVERROR_INVALIDDATA; + + run = rvmap->runtab[sym]; + val = rvmap->valtab[sym]; + } + + /* de-zigzag and dequantize */ + scan_pos += run; + if (scan_pos >= num_coeffs || scan_pos < 0) + break; + pos = band->scan[scan_pos]; + + q = (base_tab[pos] * quant) >> 9; + if (q > 1) + val = val * q + FFSIGN(val) * (((q ^ 1) - 1) >> 1); + trvec[pos] = val; + /* track columns containing non-zero coeffs */ + col_flags[pos & col_mask] |= !!val; + } + + if (scan_pos < 0 || scan_pos >= num_coeffs && sym != rvmap->eob_sym) + return AVERROR_INVALIDDATA; /* corrupt block data */ + + /* undoing DC coeff prediction for intra-blocks */ + if (is_intra && band->is_2d_trans) { + *prev_dc += trvec[0]; + trvec[0] = *prev_dc; + col_flags[0] |= !!*prev_dc; + } + + /* apply inverse transform */ + band->inv_transform(trvec, band->buf + offs, + band->pitch, col_flags); + + /* apply motion compensation */ + if (!is_intra) + return ivi_mc(band, mc, offs, mv_x, mv_y, mc_type); + + return 0; +} + int ff_ivi_decode_blocks(GetBitContext *gb, IVIBandDesc *band, IVITile *tile) { - int mbn, blk, num_blocks, num_coeffs, blk_size, scan_pos, run, val, - pos, is_intra, mc_type, mv_x, mv_y, col_mask; - uint8_t col_flags[8]; - int32_t prev_dc, trvec[64]; - uint32_t cbp, sym, lo, hi, quant, buf_offs, q; - IVIMbInfo *mb; - RVMapDesc *rvmap = band->rv_map; - void (*mc_with_delta_func)(int16_t *buf, const int16_t *ref_buf, uint32_t pitch, int mc_type); - void (*mc_no_delta_func) (int16_t *buf, const int16_t *ref_buf, uint32_t pitch, int mc_type); - const uint16_t *base_tab; - const uint8_t *scale_tab; - - prev_dc = 0; /* init intra prediction for the DC coefficient */ + int mbn, blk, num_blocks, blk_size, ret, is_intra, mc_type = 0; + int mv_x = 0, mv_y = 0; + int32_t prev_dc; + uint32_t cbp, quant, buf_offs; + IVIMbInfo *mb; + ivi_mc_func mc_with_delta_func, mc_no_delta_func; + const uint8_t *scale_tab; + /* init intra prediction for the DC coefficient */ + prev_dc = 0; blk_size = band->blk_size; - col_mask = blk_size - 1; /* column mask for tracking non-zero coeffs */ - num_blocks = (band->mb_size != blk_size) ? 4 : 1; /* number of blocks per mb */ - num_coeffs = blk_size * blk_size; + /* number of blocks per mb */ + num_blocks = (band->mb_size != blk_size) ? 4 : 1; if (blk_size == 8) { mc_with_delta_func = ff_ivi_mc_8x8_delta; mc_no_delta_func = ff_ivi_mc_8x8_no_delta; @@ -364,7 +515,6 @@ int ff_ivi_decode_blocks(GetBitContext *gb, IVIBandDesc *band, IVITile *tile) quant = av_clip(band->glob_quant + mb->q_delta, 0, 23); - base_tab = is_intra ? band->intra_base : band->inter_base; scale_tab = is_intra ? band->intra_scale : band->inter_scale; if (scale_tab) quant = scale_tab[quant]; @@ -379,6 +529,21 @@ int ff_ivi_decode_blocks(GetBitContext *gb, IVIBandDesc *band, IVITile *tile) mv_x >>= 1; mv_y >>= 1; /* convert halfpel vectors into fullpel ones */ } + if (mb->type) { + int dmv_x, dmv_y, cx, cy; + + dmv_x = mb->mv_x >> band->is_halfpel; + dmv_y = mb->mv_y >> band->is_halfpel; + cx = mb->mv_x & band->is_halfpel; + cy = mb->mv_y & band->is_halfpel; + + if (mb->xpos + dmv_x < 0 || + mb->xpos + dmv_x + band->mb_size + cx > band->pitch || + mb->ypos + dmv_y < 0 || + mb->ypos + dmv_y + band->mb_size + cy > band->aheight) { + return AVERROR_INVALIDDATA; + } + } } for (blk = 0; blk < num_blocks; blk++) { @@ -391,75 +556,25 @@ int ff_ivi_decode_blocks(GetBitContext *gb, IVIBandDesc *band, IVITile *tile) } if (cbp & 1) { /* block coded ? */ - scan_pos = -1; - memset(trvec, 0, num_coeffs*sizeof(trvec[0])); /* zero transform vector */ - memset(col_flags, 0, sizeof(col_flags)); /* zero column flags */ - - while (scan_pos <= num_coeffs) { - sym = get_vlc2(gb, band->blk_vlc.tab->table, IVI_VLC_BITS, 1); - if (sym == rvmap->eob_sym) - break; /* End of block */ - - if (sym == rvmap->esc_sym) { /* Escape - run/val explicitly coded using 3 vlc codes */ - run = get_vlc2(gb, band->blk_vlc.tab->table, IVI_VLC_BITS, 1) + 1; - lo = get_vlc2(gb, band->blk_vlc.tab->table, IVI_VLC_BITS, 1); - hi = get_vlc2(gb, band->blk_vlc.tab->table, IVI_VLC_BITS, 1); - val = IVI_TOSIGNED((hi << 6) | lo); /* merge them and convert into signed val */ - } else { - if (sym >= 256U) { - av_log(NULL, AV_LOG_ERROR, "Invalid sym encountered: %d.\n", sym); - return -1; - } - run = rvmap->runtab[sym]; - val = rvmap->valtab[sym]; - } - - /* de-zigzag and dequantize */ - scan_pos += run; - if (scan_pos >= num_coeffs) - break; - pos = band->scan[scan_pos]; - - if (!val) - av_dlog(NULL, "Val = 0 encountered!\n"); - - q = (base_tab[pos] * quant) >> 9; - if (q > 1) - val = val * q + FFSIGN(val) * (((q ^ 1) - 1) >> 1); - trvec[pos] = val; - col_flags[pos & col_mask] |= !!val; /* track columns containing non-zero coeffs */ - }// while - - if (scan_pos >= num_coeffs && sym != rvmap->eob_sym) - return -1; /* corrupt block data */ - - /* undoing DC coeff prediction for intra-blocks */ - if (is_intra && band->is_2d_trans) { - prev_dc += trvec[0]; - trvec[0] = prev_dc; - col_flags[0] |= !!prev_dc; - } - - /* apply inverse transform */ - band->inv_transform(trvec, band->buf + buf_offs, - band->pitch, col_flags); - - /* apply motion compensation */ - if (!is_intra) - mc_with_delta_func(band->buf + buf_offs, - band->ref_buf + buf_offs + mv_y * band->pitch + mv_x, - band->pitch, mc_type); + ret = ivi_decode_coded_blocks(gb, band, mc_with_delta_func, + mv_x, mv_y, &prev_dc, is_intra, + mc_type, quant, buf_offs); + if (ret < 0) + return ret; } else { /* block not coded */ /* for intra blocks apply the dc slant transform */ /* for inter - perform the motion compensation without delta */ - if (is_intra && band->dc_transform) { - band->dc_transform(&prev_dc, band->buf + buf_offs, - band->pitch, blk_size); - } else - mc_no_delta_func(band->buf + buf_offs, - band->ref_buf + buf_offs + mv_y * band->pitch + mv_x, - band->pitch, mc_type); + if (is_intra) { + ret = ivi_dc_transform(band, &prev_dc, buf_offs, blk_size); + if (ret < 0) + return ret; + } else { + ret = ivi_mc(band, mc_no_delta_func, buf_offs, + mv_x, mv_y, mc_type); + if (ret < 0) + return ret; + } } cbp >>= 1; @@ -471,16 +586,31 @@ int ff_ivi_decode_blocks(GetBitContext *gb, IVIBandDesc *band, IVITile *tile) return 0; } -void ff_ivi_process_empty_tile(AVCodecContext *avctx, IVIBandDesc *band, - IVITile *tile, int32_t mv_scale) +/** + * Handle empty tiles by performing data copying and motion + * compensation respectively. + * + * @param[in] avctx ptr to the AVCodecContext + * @param[in] band pointer to the band descriptor + * @param[in] tile pointer to the tile descriptor + * @param[in] mv_scale scaling factor for motion vectors + */ +static int ivi_process_empty_tile(AVCodecContext *avctx, IVIBandDesc *band, + IVITile *tile, int32_t mv_scale) { int x, y, need_mc, mbn, blk, num_blocks, mv_x, mv_y, mc_type; - int offs, mb_offset, row_offset; + int offs, mb_offset, row_offset, ret; IVIMbInfo *mb, *ref_mb; const int16_t *src; int16_t *dst; - void (*mc_no_delta_func)(int16_t *buf, const int16_t *ref_buf, uint32_t pitch, - int mc_type); + ivi_mc_func mc_no_delta_func; + + if (tile->num_MBs != IVI_MBs_PER_TILE(tile->width, tile->height, band->mb_size)) { + av_log(avctx, AV_LOG_ERROR, "Allocated tile size %d mismatches " + "parameters %d in ivi_process_empty_tile()\n", + tile->num_MBs, IVI_MBs_PER_TILE(tile->width, tile->height, band->mb_size)); + return AVERROR_INVALIDDATA; + } offs = tile->ypos * band->pitch + tile->xpos; mb = tile->mbs; @@ -547,9 +677,10 @@ void ff_ivi_process_empty_tile(AVCodecContext *avctx, IVIBandDesc *band, for (blk = 0; blk < num_blocks; blk++) { /* adjust block position in the buffer according with its number */ offs = mb->buf_offs + band->blk_size * ((blk & 1) + !!(blk & 2) * band->pitch); - mc_no_delta_func(band->buf + offs, - band->ref_buf + offs + mv_y * band->pitch + mv_x, - band->pitch, mc_type); + ret = ivi_mc(band, mc_no_delta_func, offs, + mv_x, mv_y, mc_type); + if (ret < 0) + return ret; } } } else { @@ -562,6 +693,8 @@ void ff_ivi_process_empty_tile(AVCodecContext *avctx, IVIBandDesc *band, dst += band->pitch; } } + + return 0; } @@ -624,6 +757,250 @@ void ff_ivi_output_plane(IVIPlaneDesc *plane, uint8_t *dst, int dst_pitch) } } +/** + * Decode an Indeo 4 or 5 band. + * + * @param[in,out] ctx ptr to the decoder context + * @param[in,out] band ptr to the band descriptor + * @param[in] avctx ptr to the AVCodecContext + * @return result code: 0 = OK, -1 = error + */ +static int decode_band(IVI45DecContext *ctx, int plane_num, + IVIBandDesc *band, AVCodecContext *avctx) +{ + int result, i, t, idx1, idx2, pos; + IVITile *tile; + + band->buf = band->bufs[ctx->dst_buf]; + band->ref_buf = band->bufs[ctx->ref_buf]; + band->data_ptr = ctx->frame_data + (get_bits_count(&ctx->gb) >> 3); + + result = ctx->decode_band_hdr(ctx, band, avctx); + if (result) { + av_log(avctx, AV_LOG_ERROR, "Error while decoding band header: %d\n", + result); + return result; + } + + if (band->is_empty) { + av_log(avctx, AV_LOG_ERROR, "Empty band encountered!\n"); + return AVERROR_INVALIDDATA; + } + + band->rv_map = &ctx->rvmap_tabs[band->rvmap_sel]; + + /* apply corrections to the selected rvmap table if present */ + for (i = 0; i < band->num_corr; i++) { + idx1 = band->corr[i * 2]; + idx2 = band->corr[i * 2 + 1]; + FFSWAP(uint8_t, band->rv_map->runtab[idx1], band->rv_map->runtab[idx2]); + FFSWAP(int16_t, band->rv_map->valtab[idx1], band->rv_map->valtab[idx2]); + } + + pos = get_bits_count(&ctx->gb); + + for (t = 0; t < band->num_tiles; t++) { + tile = &band->tiles[t]; + + if (tile->mb_size != band->mb_size) { + av_log(avctx, AV_LOG_ERROR, "MB sizes mismatch: %d vs. %d\n", + band->mb_size, tile->mb_size); + return AVERROR_INVALIDDATA; + } + tile->is_empty = get_bits1(&ctx->gb); + if (tile->is_empty) { + result = ivi_process_empty_tile(avctx, band, tile, + (ctx->planes[0].bands[0].mb_size >> 3) - (band->mb_size >> 3)); + if (result < 0) + break; + av_dlog(avctx, "Empty tile encountered!\n"); + } else { + tile->data_size = ff_ivi_dec_tile_data_size(&ctx->gb); + if (!tile->data_size) { + av_log(avctx, AV_LOG_ERROR, "Tile data size is zero!\n"); + return AVERROR_INVALIDDATA; + } + + result = ctx->decode_mb_info(ctx, band, tile, avctx); + if (result < 0) + break; + + result = ff_ivi_decode_blocks(&ctx->gb, band, tile); + if (result < 0) { + av_log(avctx, AV_LOG_ERROR, + "Corrupted tile data encountered!\n"); + break; + } + + if (((get_bits_count(&ctx->gb) - pos) >> 3) != tile->data_size) { + av_log(avctx, AV_LOG_ERROR, + "Tile data_size mismatch!\n"); + result = AVERROR_INVALIDDATA; + break; + } + + pos += tile->data_size << 3; // skip to next tile + } + } + + /* restore the selected rvmap table by applying its corrections in + * reverse order */ + for (i = band->num_corr-1; i >= 0; i--) { + idx1 = band->corr[i*2]; + idx2 = band->corr[i*2+1]; + FFSWAP(uint8_t, band->rv_map->runtab[idx1], band->rv_map->runtab[idx2]); + FFSWAP(int16_t, band->rv_map->valtab[idx1], band->rv_map->valtab[idx2]); + } + +#ifdef DEBUG + if (band->checksum_present) { + uint16_t chksum = ivi_calc_band_checksum(band); + if (chksum != band->checksum) { + av_log(avctx, AV_LOG_ERROR, + "Band checksum mismatch! Plane %d, band %d, " + "received: %x, calculated: %x\n", + band->plane, band->band_num, band->checksum, chksum); + } + } +#endif + + align_get_bits(&ctx->gb); + + return result; +} + +int ff_ivi_decode_frame(AVCodecContext *avctx, void *data, int *data_size, + AVPacket *avpkt) +{ + IVI45DecContext *ctx = avctx->priv_data; + const uint8_t *buf = avpkt->data; + int buf_size = avpkt->size; + int result, p, b; + + init_get_bits(&ctx->gb, buf, buf_size * 8); + ctx->frame_data = buf; + ctx->frame_size = buf_size; + + result = ctx->decode_pic_hdr(ctx, avctx); + if (result) { + av_log(avctx, AV_LOG_ERROR, + "Error while decoding picture header: %d\n", result); + return result; + } + if (ctx->gop_invalid) + return AVERROR_INVALIDDATA; + + if (ctx->gop_flags & IVI5_IS_PROTECTED) { + av_log(avctx, AV_LOG_ERROR, "Password-protected clip!\n"); + return AVERROR_PATCHWELCOME; + } + + if (!ctx->planes[0].bands) { + av_log(avctx, AV_LOG_ERROR, "Color planes not initialized yet\n"); + return AVERROR_INVALIDDATA; + } + + ctx->switch_buffers(ctx); + + //{ START_TIMER; + + if (ctx->is_nonnull_frame(ctx)) { + for (p = 0; p < 3; p++) { + for (b = 0; b < ctx->planes[p].num_bands; b++) { + result = decode_band(ctx, p, &ctx->planes[p].bands[b], avctx); + if (result < 0) { + av_log(avctx, AV_LOG_ERROR, + "Error while decoding band: %d, plane: %d\n", b, p); + return result; + } + } + } + } else { + if (ctx->is_scalable) + return AVERROR_INVALIDDATA; + + for (p = 0; p < 3; p++) { + if (!ctx->planes[p].bands[0].buf) + return AVERROR_INVALIDDATA; + } + } + + //STOP_TIMER("decode_planes"); } + + /* If the bidirectional mode is enabled, next I and the following P frame will */ + /* be sent together. Unfortunately the approach below seems to be the only way */ + /* to handle the B-frames mode. That's exactly the same Intel decoders do. */ + if (avctx->codec_id == CODEC_ID_INDEO4 && + ctx->frame_type == 0/*FRAMETYPE_INTRA*/) { + while (get_bits(&ctx->gb, 8)); // skip version string + skip_bits_long(&ctx->gb, 64); // skip padding, TODO: implement correct 8-bytes alignment + if (get_bits_left(&ctx->gb) > 18 && show_bits(&ctx->gb, 18) == 0x3FFF8) + av_log(avctx, AV_LOG_ERROR, "Buffer contains IP frames!\n"); + } + + if (ctx->frame.data[0]) + avctx->release_buffer(avctx, &ctx->frame); + + ctx->frame.reference = 0; + avcodec_set_dimensions(avctx, ctx->planes[0].width, ctx->planes[0].height); + if ((result = ff_get_buffer(avctx, &ctx->frame)) < 0) { + av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n"); + return result; + } + + if (ctx->is_scalable) { + if (avctx->codec_id == CODEC_ID_INDEO4) + ff_ivi_recompose_haar(&ctx->planes[0], ctx->frame.data[0], ctx->frame.linesize[0], 4); + else + ff_ivi_recompose53 (&ctx->planes[0], ctx->frame.data[0], ctx->frame.linesize[0], 4); + } else { + ff_ivi_output_plane(&ctx->planes[0], ctx->frame.data[0], ctx->frame.linesize[0]); + } + + ff_ivi_output_plane(&ctx->planes[2], ctx->frame.data[1], ctx->frame.linesize[1]); + ff_ivi_output_plane(&ctx->planes[1], ctx->frame.data[2], ctx->frame.linesize[2]); + + *data_size = sizeof(AVFrame); + *(AVFrame*)data = ctx->frame; + + return buf_size; +} + +/** + * Close Indeo5 decoder and clean up its context. + */ +av_cold int ff_ivi_decode_close(AVCodecContext *avctx) +{ + IVI45DecContext *ctx = avctx->priv_data; + + ff_ivi_free_buffers(&ctx->planes[0]); + + if (ctx->mb_vlc.cust_tab.table) + ff_free_vlc(&ctx->mb_vlc.cust_tab); + + if (ctx->frame.data[0]) + avctx->release_buffer(avctx, &ctx->frame); + +#if IVI4_STREAM_ANALYSER + if (avctx->codec_id == CODEC_ID_INDEO4) { + if (ctx->is_scalable) + av_log(avctx, AV_LOG_ERROR, "This video uses scalability mode!\n"); + if (ctx->uses_tiling) + av_log(avctx, AV_LOG_ERROR, "This video uses local decoding!\n"); + if (ctx->has_b_frames) + av_log(avctx, AV_LOG_ERROR, "This video contains B-frames!\n"); + if (ctx->has_transp) + av_log(avctx, AV_LOG_ERROR, "Transparency mode is enabled!\n"); + if (ctx->uses_haar) + av_log(avctx, AV_LOG_ERROR, "This video uses Haar transform!\n"); + if (ctx->uses_fullpel) + av_log(avctx, AV_LOG_ERROR, "This video uses fullpel motion vectors!\n"); + } +#endif + + return 0; +} + /** * These are 2x8 predefined Huffman codebooks for coding macroblock/block diff --git a/libavcodec/ivi_common.h b/libavcodec/ivi_common.h index dd060854f3..97bae5a7f0 100644 --- a/libavcodec/ivi_common.h +++ b/libavcodec/ivi_common.h @@ -34,6 +34,8 @@ #include #define IVI_VLC_BITS 13 ///< max number of bits of the ivi's huffman codes +#define IVI4_STREAM_ANALYSER 0 +#define IVI5_IS_PROTECTED 0x20 /** * huffman codebook descriptor @@ -116,6 +118,7 @@ typedef struct { int ypos; int width; int height; + int mb_size; int is_empty; ///< = 1 if this tile doesn't contain any data int data_size; ///< size of the data in bytes int num_MBs; ///< number of macroblocks in this tile @@ -132,6 +135,7 @@ typedef struct { int band_num; ///< band number int width; int height; + int aheight; ///< aligned band height const uint8_t *data_ptr; ///< ptr to the first byte of the band data int data_size; ///< size of the band data int16_t *buf; ///< pointer to the output buffer for this band @@ -158,6 +162,7 @@ typedef struct { int num_tiles; ///< number of tiles in this band IVITile *tiles; ///< array of tile descriptors InvTransformPtr *inv_transform; + int transform_size; DCTransformPtr *dc_transform; int is_2d_trans; ///< 1 indicates that the two-dimensional inverse transform is used int32_t checksum; ///< for debug purposes @@ -192,6 +197,62 @@ typedef struct { uint8_t chroma_bands; } IVIPicConfig; +typedef struct IVI45DecContext { + GetBitContext gb; + AVFrame frame; + RVMapDesc rvmap_tabs[9]; ///< local corrected copy of the static rvmap tables + + uint32_t frame_num; + int frame_type; + int prev_frame_type; ///< frame type of the previous frame + uint32_t data_size; ///< size of the frame data in bytes from picture header + int is_scalable; + int transp_status; ///< transparency mode status: 1 - enabled + const uint8_t *frame_data; ///< input frame data pointer + int inter_scal; ///< signals a sequence of scalable inter frames + uint32_t frame_size; ///< frame size in bytes + uint32_t pic_hdr_size; ///< picture header size in bytes + uint8_t frame_flags; + uint16_t checksum; ///< frame checksum + + IVIPicConfig pic_conf; + IVIPlaneDesc planes[3]; ///< color planes + + int buf_switch; ///< used to switch between three buffers + int dst_buf; ///< buffer index for the currently decoded frame + int ref_buf; ///< inter frame reference buffer index + int ref2_buf; ///< temporal storage for switching buffers + + IVIHuffTab mb_vlc; ///< current macroblock table descriptor + IVIHuffTab blk_vlc; ///< current block table descriptor + + uint8_t rvmap_sel; + uint8_t in_imf; + uint8_t in_q; ///< flag for explicitly stored quantiser delta + uint8_t pic_glob_quant; + uint8_t unknown1; + + uint16_t gop_hdr_size; + uint8_t gop_flags; + uint32_t lock_word; + +#if IVI4_STREAM_ANALYSER + uint8_t has_b_frames; + uint8_t has_transp; + uint8_t uses_tiling; + uint8_t uses_haar; + uint8_t uses_fullpel; +#endif + + int (*decode_pic_hdr) (struct IVI45DecContext *ctx, AVCodecContext *avctx); + int (*decode_band_hdr) (struct IVI45DecContext *ctx, IVIBandDesc *band, AVCodecContext *avctx); + int (*decode_mb_info) (struct IVI45DecContext *ctx, IVIBandDesc *band, IVITile *tile, AVCodecContext *avctx); + void (*switch_buffers) (struct IVI45DecContext *ctx); + int (*is_nonnull_frame)(struct IVI45DecContext *ctx); + + int gop_invalid; +} IVI45DecContext; + /** compare some properties of two pictures */ static inline int ivi_pic_config_cmp(IVIPicConfig *str1, IVIPicConfig *str2) { @@ -315,18 +376,6 @@ int ff_ivi_dec_tile_data_size(GetBitContext *gb); */ int ff_ivi_decode_blocks(GetBitContext *gb, IVIBandDesc *band, IVITile *tile); -/** - * Handle empty tiles by performing data copying and motion - * compensation respectively. - * - * @param[in] avctx ptr to the AVCodecContext - * @param[in] band pointer to the band descriptor - * @param[in] tile pointer to the tile descriptor - * @param[in] mv_scale scaling factor for motion vectors - */ -void ff_ivi_process_empty_tile(AVCodecContext *avctx, IVIBandDesc *band, - IVITile *tile, int32_t mv_scale); - /** * Convert and output the current plane. * This conversion is done by adding back the bias value of 128 @@ -348,4 +397,8 @@ uint16_t ivi_calc_band_checksum (IVIBandDesc *band); */ int ivi_check_band (IVIBandDesc *band, const uint8_t *ref, int pitch); +int ff_ivi_decode_frame(AVCodecContext *avctx, void *data, int *data_size, + AVPacket *avpkt); +av_cold int ff_ivi_decode_close(AVCodecContext *avctx); + #endif /* AVCODEC_IVI_COMMON_H */ diff --git a/libavcodec/j2kdec.c b/libavcodec/j2kdec.c index 78a24698a2..e4da2def00 100644 --- a/libavcodec/j2kdec.c +++ b/libavcodec/j2kdec.c @@ -28,6 +28,7 @@ #include "avcodec.h" #include "bytestream.h" #include "j2k.h" +#include "libavutil/avassert.h" #include "libavutil/common.h" #define JP2_SIG_TYPE 0x6A502020 @@ -289,6 +290,10 @@ static int get_cox(J2kDecoderContext *s, J2kCodingStyle *c) c->log2_cblk_width = bytestream_get_byte(&s->buf) + 2; // cblk width c->log2_cblk_height = bytestream_get_byte(&s->buf) + 2; // cblk height + if (c->log2_cblk_width > 6 || c->log2_cblk_height > 6) { + return AVERROR_PATCHWELCOME; + } + c->cblk_style = bytestream_get_byte(&s->buf); if (c->cblk_style != 0){ // cblk style av_log(s->avctx, AV_LOG_WARNING, "extra cblk styles %X\n", c->cblk_style); @@ -705,6 +710,9 @@ static int decode_cblk(J2kDecoderContext *s, J2kCodingStyle *codsty, J2kT1Contex int bpass_csty_symbol = J2K_CBLK_BYPASS & codsty->cblk_style; int vert_causal_ctx_csty_symbol = J2K_CBLK_VSC & codsty->cblk_style; + av_assert0(width <= J2K_MAX_CBLKW); + av_assert0(height <= J2K_MAX_CBLKH); + for (y = 0; y < height+2; y++) memset(t1->flags[y], 0, (width+2)*sizeof(int)); diff --git a/libavcodec/jpegls.h b/libavcodec/jpegls.h index 2c21f774e8..3304032c2a 100644 --- a/libavcodec/jpegls.h +++ b/libavcodec/jpegls.h @@ -40,7 +40,7 @@ typedef struct JLSState{ int A[367], B[367], C[365], N[367]; int limit, reset, bpp, qbpp, maxval, range; int near, twonear; - int run_index[3]; + int run_index[4]; }JLSState; extern const uint8_t ff_log2_run[32]; diff --git a/libavcodec/jpeglsdec.c b/libavcodec/jpeglsdec.c index 0139c8860f..28fa5940d2 100644 --- a/libavcodec/jpeglsdec.c +++ b/libavcodec/jpeglsdec.c @@ -71,13 +71,13 @@ int ff_jpegls_decode_lse(MJpegDecodeContext *s) case 2: case 3: av_log(s->avctx, AV_LOG_ERROR, "palette not supported\n"); - return -1; + return AVERROR(ENOSYS); case 4: av_log(s->avctx, AV_LOG_ERROR, "oversize image not supported\n"); - return -1; + return AVERROR(ENOSYS); default: av_log(s->avctx, AV_LOG_ERROR, "invalid id %d\n", id); - return -1; + return AVERROR_INVALIDDATA; } // av_log(s->avctx, AV_LOG_DEBUG, "ID=%i, T=%i,%i,%i\n", id, s->t1, s->t2, s->t3); @@ -143,6 +143,8 @@ static inline int ls_get_code_runterm(GetBitContext *gb, JLSState *state, int RI ret = ret >> 1; } + if(FFABS(ret) > 0xFFFF) + return -0x10000; /* update state */ state->A[Q] += FFABS(ret) - RItype; ret *= state->twonear; @@ -198,11 +200,19 @@ static inline void ls_decode_line(JLSState *state, MJpegDecodeContext *s, void * r = ff_log2_run[state->run_index[comp]]; if(r) r = get_bits_long(&s->gb, r); + if(x + r * stride > w) { + r = (w - x) / stride; + } for(i = 0; i < r; i++) { W(dst, x, Ra); x += stride; } + if (x >= w) { + av_log(NULL, AV_LOG_ERROR, "run overflow\n"); + return; + } + /* decode run termination value */ Rb = R(last, x); RItype = (FFABS(Ra - Rb) <= state->near) ? 1 : 0; @@ -260,7 +270,7 @@ int ff_jpegls_decode_picture(MJpegDecodeContext *s, int near, int point_transfor int i, t = 0; uint8_t *zero, *last, *cur; JLSState *state; - int off = 0, stride = 1, width, shift; + int off = 0, stride = 1, width, shift, ret = 0; zero = av_mallocz(s->picture.linesize[0]); last = zero; @@ -286,8 +296,12 @@ int ff_jpegls_decode_picture(MJpegDecodeContext *s, int near, int point_transfor // av_log(s->avctx, AV_LOG_DEBUG, "JPEG-LS params: %ix%i NEAR=%i MV=%i T(%i,%i,%i) RESET=%i, LIMIT=%i, qbpp=%i, RANGE=%i\n",s->width,s->height,state->near,state->maxval,state->T1,state->T2,state->T3,state->reset,state->limit,state->qbpp, state->range); // av_log(s->avctx, AV_LOG_DEBUG, "JPEG params: ILV=%i Pt=%i BPP=%i, scan = %i\n", ilv, point_transform, s->bits, s->cur_scan); if(ilv == 0) { /* separate planes */ + if (s->cur_scan > s->nb_components) { + ret = AVERROR_INVALIDDATA; + goto end; + } stride = (s->nb_components > 1) ? 3 : 1; - off = av_clip(s->cur_scan - 1, 0, stride); + off = av_clip(s->cur_scan - 1, 0, stride - 1); width = s->width * stride; cur += off; for(i = 0; i < s->height; i++) { @@ -325,11 +339,10 @@ int ff_jpegls_decode_picture(MJpegDecodeContext *s, int near, int point_transfor last = cur; cur += s->picture.linesize[0]; } - } else if(ilv == 2) { /* sample interleaving */ + } else if (ilv == 2) { /* sample interleaving */ av_log(s->avctx, AV_LOG_ERROR, "Sample interleaved images are not supported.\n"); - av_free(state); - av_free(zero); - return -1; + ret = AVERROR_PATCHWELCOME; + goto end; } if(shift){ /* we need to do point transform or normalize samples */ @@ -357,10 +370,12 @@ int ff_jpegls_decode_picture(MJpegDecodeContext *s, int near, int point_transfor } } } + +end: av_free(state); av_free(zero); - return 0; + return ret; } diff --git a/libavcodec/jvdec.c b/libavcodec/jvdec.c index 223cef1fa7..6404b6f4fd 100644 --- a/libavcodec/jvdec.c +++ b/libavcodec/jvdec.c @@ -42,6 +42,14 @@ static av_cold int decode_init(AVCodecContext *avctx) JvContext *s = avctx->priv_data; avctx->pix_fmt = PIX_FMT_PAL8; dsputil_init(&s->dsp, avctx); + + if (!avctx->width || !avctx->height || + (avctx->width & 7) || (avctx->height & 7)) { + av_log(avctx, AV_LOG_ERROR, "Invalid video dimensions: %dx%d\n", + avctx->width, avctx->height); + return AVERROR(EINVAL); + } + return 0; } @@ -143,6 +151,10 @@ static int decode_frame(AVCodecContext *avctx, buf += 5; if (video_size) { + if(video_size < 0) { + av_log(avctx, AV_LOG_ERROR, "video size %d invalid\n", video_size); + return AVERROR_INVALIDDATA; + } if (avctx->reget_buffer(avctx, &s->frame) < 0) { av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n"); return -1; @@ -150,7 +162,7 @@ static int decode_frame(AVCodecContext *avctx, if (video_type == 0 || video_type == 1) { GetBitContext gb; - init_get_bits(&gb, buf, FFMIN(video_size, (buf_end - buf) * 8)); + init_get_bits(&gb, buf, 8 * FFMIN(video_size, buf_end - buf)); for (j = 0; j < avctx->height; j += 8) for (i = 0; i < avctx->width; i += 8) diff --git a/libavcodec/kgv1dec.c b/libavcodec/kgv1dec.c index 4566e35b74..cd701ae75f 100644 --- a/libavcodec/kgv1dec.c +++ b/libavcodec/kgv1dec.c @@ -27,13 +27,21 @@ #include "libavutil/intreadwrite.h" #include "libavutil/imgutils.h" #include "avcodec.h" +#include "internal.h" typedef struct { AVCodecContext *avctx; - AVFrame pic; - uint16_t *prev, *cur; + AVFrame prev, cur; } KgvContext; +static void decode_flush(AVCodecContext *avctx) +{ + KgvContext * const c = avctx->priv_data; + + if (c->prev.data[0]) + avctx->release_buffer(avctx, &c->prev); +} + static int decode_frame(AVCodecContext *avctx, void *data, int *data_size, AVPacket *avpkt) { const uint8_t *buf = avpkt->data; @@ -42,7 +50,7 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *data_size, AVPac int offsets[8]; uint16_t *out, *prev; int outcnt = 0, maxcnt; - int w, h, i; + int w, h, i, res; if (avpkt->size < 2) return -1; @@ -54,20 +62,23 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *data_size, AVPac if (av_image_check_size(w, h, 0, avctx)) return -1; - if (w != avctx->width || h != avctx->height) + if (w != avctx->width || h != avctx->height) { + if (c->prev.data[0]) + avctx->release_buffer(avctx, &c->prev); avcodec_set_dimensions(avctx, w, h); + } maxcnt = w * h; - out = av_realloc(c->cur, w * h * 2); - if (!out) - return -1; - c->cur = out; - - prev = av_realloc(c->prev, w * h * 2); - if (!prev) - return -1; - c->prev = prev; + c->cur.reference = 3; + if ((res = ff_get_buffer(avctx, &c->cur)) < 0) + return res; + out = (uint16_t *) c->cur.data[0]; + if (c->prev.data[0]) { + prev = (uint16_t *) c->prev.data[0]; + } else { + prev = NULL; + } for (i = 0; i < 8; i++) offsets[i] = -1; @@ -80,6 +91,7 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *data_size, AVPac out[outcnt++] = code; // rgb555 pixel coded directly } else { int count; + int inp_off; uint16_t *inp; if ((code & 0x6000) == 0x6000) { @@ -101,7 +113,14 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *data_size, AVPac if (maxcnt - start < count) break; - inp = prev + start; + if (!prev) { + av_log(avctx, AV_LOG_ERROR, + "Frame reference does not exist\n"); + break; + } + + inp = prev; + inp_off = start; } else { // copy from earlier in this frame int offset = (code & 0x1FFF) + 1; @@ -119,27 +138,28 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *data_size, AVPac if (outcnt < offset) break; - inp = out + outcnt - offset; + inp = out; + inp_off = outcnt - offset; } if (maxcnt - outcnt < count) break; - for (i = 0; i < count; i++) + for (i = inp_off; i < count + inp_off; i++) { out[outcnt++] = inp[i]; + } } } if (outcnt - maxcnt) av_log(avctx, AV_LOG_DEBUG, "frame finished with %d diff\n", outcnt - maxcnt); - c->pic.data[0] = (uint8_t *)c->cur; - c->pic.linesize[0] = w * 2; - *data_size = sizeof(AVFrame); - *(AVFrame*)data = c->pic; + *(AVFrame*)data = c->cur; - FFSWAP(uint16_t *, c->cur, c->prev); + if (c->prev.data[0]) + avctx->release_buffer(avctx, &c->prev); + FFSWAP(AVFrame, c->cur, c->prev); return avpkt->size; } @@ -150,18 +170,14 @@ static av_cold int decode_init(AVCodecContext *avctx) c->avctx = avctx; avctx->pix_fmt = PIX_FMT_RGB555; - avcodec_get_frame_defaults(&c->pic); + avctx->flags |= CODEC_FLAG_EMU_EDGE; return 0; } static av_cold int decode_end(AVCodecContext *avctx) { - KgvContext * const c = avctx->priv_data; - - av_freep(&c->cur); - av_freep(&c->prev); - + decode_flush(avctx); return 0; } @@ -173,5 +189,6 @@ AVCodec ff_kgv1_decoder = { .init = decode_init, .close = decode_end, .decode = decode_frame, + .flush = decode_flush, .long_name = NULL_IF_CONFIG_SMALL("Kega Game Video"), }; diff --git a/libavcodec/kmvc.c b/libavcodec/kmvc.c index 9c98badbde..4fc50fa761 100644 --- a/libavcodec/kmvc.c +++ b/libavcodec/kmvc.c @@ -29,10 +29,13 @@ #include "avcodec.h" #include "bytestream.h" +#include "internal.h" +#include "libavutil/common.h" #define KMVC_KEYFRAME 0x80 #define KMVC_PALETTE 0x40 #define KMVC_METHOD 0x0F +#define MAX_PALSIZE 256 /* * Decoder context @@ -43,9 +46,9 @@ typedef struct KmvcContext { int setpal; int palsize; - uint32_t pal[256]; + uint32_t pal[MAX_PALSIZE]; uint8_t *cur, *prev; - uint8_t *frm0, *frm1; + uint8_t frm0[320 * 200], frm1[320 * 200]; GetByteContext g; } KmvcContext; @@ -54,7 +57,7 @@ typedef struct BitBuf { int bitbuf; } BitBuf; -#define BLK(data, x, y) data[(x) + (y) * 320] +#define BLK(data, x, y) data[av_clip((x) + (y) * 320, 0, 320 * 200 -1)] #define kmvc_init_getbits(bb, g) bb.bits = 7; bb.bitbuf = bytestream2_get_byte(g); @@ -366,8 +369,6 @@ static av_cold int decode_init(AVCodecContext * avctx) return -1; } - c->frm0 = av_mallocz(320 * 200); - c->frm1 = av_mallocz(320 * 200); c->cur = c->frm0; c->prev = c->frm1; @@ -380,10 +381,10 @@ static av_cold int decode_init(AVCodecContext * avctx) c->palsize = 127; } else { c->palsize = AV_RL16(avctx->extradata + 10); - if (c->palsize > 255U) { + if (c->palsize >= (unsigned)MAX_PALSIZE) { c->palsize = 127; - av_log(NULL, AV_LOG_ERROR, "palsize too big\n"); - return -1; + av_log(avctx, AV_LOG_ERROR, "KMVC palette too large\n"); + return AVERROR_INVALIDDATA; } } @@ -402,30 +403,12 @@ static av_cold int decode_init(AVCodecContext * avctx) return 0; } - - -/* - * Uninit kmvc decoder - */ -static av_cold int decode_end(AVCodecContext * avctx) -{ - KmvcContext *const c = avctx->priv_data; - - av_freep(&c->frm0); - av_freep(&c->frm1); - if (c->pic.data[0]) - avctx->release_buffer(avctx, &c->pic); - - return 0; -} - AVCodec ff_kmvc_decoder = { .name = "kmvc", .type = AVMEDIA_TYPE_VIDEO, .id = CODEC_ID_KMVC, .priv_data_size = sizeof(KmvcContext), .init = decode_init, - .close = decode_end, .decode = decode_frame, .capabilities = CODEC_CAP_DR1, .long_name = NULL_IF_CONFIG_SMALL("Karl Morton's video codec"), diff --git a/libavcodec/lagarith.c b/libavcodec/lagarith.c index 43027cff4e..a1c6dcdaa6 100644 --- a/libavcodec/lagarith.c +++ b/libavcodec/lagarith.c @@ -52,6 +52,7 @@ typedef struct LagarithContext { int zeros; /**< number of consecutive zero bytes encountered */ int zeros_rem; /**< number of zero bytes remaining to output */ uint8_t *rgb_planes; + int rgb_planes_allocated; int rgb_stride; } LagarithContext; @@ -247,24 +248,26 @@ static void lag_pred_line(LagarithContext *l, uint8_t *buf, { int L, TL; - /* Left pixel is actually prev_row[width] */ - L = buf[width - stride - 1]; if (!line) { /* Left prediction only for first line */ L = l->dsp.add_hfyu_left_prediction(buf + 1, buf + 1, width - 1, buf[0]); - return; - } else if (line == 1) { - /* Second line, left predict first pixel, the rest of the line is median predicted - * NOTE: In the case of RGB this pixel is top predicted */ - TL = l->avctx->pix_fmt == PIX_FMT_YUV420P ? buf[-stride] : L; } else { - /* Top left is 2 rows back, last pixel */ - TL = buf[width - (2 * stride) - 1]; - } + /* Left pixel is actually prev_row[width] */ + L = buf[width - stride - 1]; - add_lag_median_prediction(buf, buf - stride, buf, - width, &L, &TL); + if (line == 1) { + /* Second line, left predict first pixel, the rest of the line is median predicted + * NOTE: In the case of RGB this pixel is top predicted */ + TL = l->avctx->pix_fmt == PIX_FMT_YUV420P ? buf[-stride] : L; + } else { + /* Top left is 2 rows back, last pixel */ + TL = buf[width - (2 * stride) - 1]; + } + + add_lag_median_prediction(buf, buf - stride, buf, + width, &L, &TL); + } } static int lag_decode_line(LagarithContext *l, lag_rac *rac, @@ -310,13 +313,13 @@ handle_zeros: } static int lag_decode_zero_run_line(LagarithContext *l, uint8_t *dst, - const uint8_t *src, int width, - int esc_count) + const uint8_t *src, const uint8_t *src_end, + int width, int esc_count) { int i = 0; int count; uint8_t zero_run = 0; - const uint8_t *start = src; + const uint8_t *src_start = src; uint8_t mask1 = -(esc_count < 2); uint8_t mask2 = -(esc_count < 3); uint8_t *end = dst + (width - 2); @@ -324,6 +327,11 @@ static int lag_decode_zero_run_line(LagarithContext *l, uint8_t *dst, output_zeros: if (l->zeros_rem) { count = FFMIN(l->zeros_rem, width - i); + if (end - dst < count) { + av_log(l->avctx, AV_LOG_ERROR, "Too many zeros remaining.\n"); + return AVERROR_INVALIDDATA; + } + memset(dst, 0, count); l->zeros_rem -= count; dst += count; @@ -333,6 +341,8 @@ output_zeros: i = 0; while (!zero_run && dst + i < end) { i++; + if (src + i >= src_end) + return AVERROR_INVALIDDATA; zero_run = !(src[i] | (src[i + 1] & mask1) | (src[i + 2] & mask2)); } @@ -348,9 +358,10 @@ output_zeros: } else { memcpy(dst, src, i); src += i; + dst += i; } } - return start - src; + return src_start - src; } @@ -366,6 +377,7 @@ static int lag_decode_arith_plane(LagarithContext *l, uint8_t *dst, int esc_count = src[0]; GetBitContext gb; lag_rac rac; + const uint8_t *src_end = src + src_size; rac.avctx = l->avctx; l->zeros = 0; @@ -396,10 +408,16 @@ static int lag_decode_arith_plane(LagarithContext *l, uint8_t *dst, esc_count -= 4; if (esc_count > 0) { /* Zero run coding only, no range coding. */ - for (i = 0; i < height; i++) - src += lag_decode_zero_run_line(l, dst + (i * stride), src, - width, esc_count); + for (i = 0; i < height; i++) { + int res = lag_decode_zero_run_line(l, dst + (i * stride), src, + src_end, width, esc_count); + if (res < 0) + return res; + src += res; + } } else { + if (src_size < width * height) + return AVERROR_INVALIDDATA; // buffer not big enough /* Plane is stored uncompressed */ for (i = 0; i < height; i++) { memcpy(dst + (i * stride), src, width); @@ -490,21 +508,28 @@ static int lag_decode_frame(AVCodecContext *avctx, offs[2] = 13; offs[3] = AV_RL32(buf + 9); + l->rgb_stride = FFALIGN(avctx->width, 16); + av_fast_malloc(&l->rgb_planes, &l->rgb_planes_allocated, + l->rgb_stride * avctx->height * 4 + 1); if (!l->rgb_planes) { - l->rgb_stride = FFALIGN(avctx->width, 16); - l->rgb_planes = av_malloc(l->rgb_stride * avctx->height * 4); - if (!l->rgb_planes) { - av_log(avctx, AV_LOG_ERROR, "cannot allocate temporary buffer\n"); - return AVERROR(ENOMEM); - } + av_log(avctx, AV_LOG_ERROR, "cannot allocate temporary buffer\n"); + return AVERROR(ENOMEM); } for (i = 0; i < 4; i++) srcs[i] = l->rgb_planes + (i + 1) * l->rgb_stride * avctx->height - l->rgb_stride; + if (offset_ry >= buf_size || + offset_gu >= buf_size || + offset_bv >= buf_size || + offs[3] >= buf_size) { + av_log(avctx, AV_LOG_ERROR, + "Invalid frame offsets\n"); + return AVERROR_INVALIDDATA; + } for (i = 0; i < 4; i++) lag_decode_arith_plane(l, srcs[i], avctx->width, avctx->height, -l->rgb_stride, buf + offs[i], - buf_size); + buf_size - offs[i]); dst = p->data[0]; for (i = 0; i < 4; i++) srcs[i] = l->rgb_planes + i * l->rgb_stride * avctx->height; @@ -576,15 +601,23 @@ static int lag_decode_frame(AVCodecContext *avctx, return -1; } + if (offset_ry >= buf_size || + offset_gu >= buf_size || + offset_bv >= buf_size) { + av_log(avctx, AV_LOG_ERROR, + "Invalid frame offsets\n"); + return AVERROR_INVALIDDATA; + } + lag_decode_arith_plane(l, p->data[0], avctx->width, avctx->height, p->linesize[0], buf + offset_ry, - buf_size); + buf_size - offset_ry); lag_decode_arith_plane(l, p->data[2], avctx->width / 2, avctx->height / 2, p->linesize[2], - buf + offset_gu, buf_size); + buf + offset_gu, buf_size - offset_gu); lag_decode_arith_plane(l, p->data[1], avctx->width / 2, avctx->height / 2, p->linesize[1], - buf + offset_bv, buf_size); + buf + offset_bv, buf_size - offset_bv); break; default: av_log(avctx, AV_LOG_ERROR, diff --git a/libavcodec/lagarithrac.c b/libavcodec/lagarithrac.c index 56c1d0bcc0..4aba32335b 100644 --- a/libavcodec/lagarithrac.c +++ b/libavcodec/lagarithrac.c @@ -32,15 +32,16 @@ void lag_rac_init(lag_rac *l, GetBitContext *gb, int length) { - int i, j; + int i, j, left; /* According to reference decoder "1st byte is garbage", * however, it gets skipped by the call to align_get_bits() */ align_get_bits(gb); + left = get_bits_left(gb) >> 3; l->bytestream_start = l->bytestream = gb->buffer + get_bits_count(gb) / 8; - l->bytestream_end = l->bytestream_start + length; + l->bytestream_end = l->bytestream_start + FFMIN(length, left); l->range = 0x80; l->low = *l->bytestream >> 1; diff --git a/libavcodec/lagarithrac.h b/libavcodec/lagarithrac.h index 8c78538f21..5b884f0020 100644 --- a/libavcodec/lagarithrac.h +++ b/libavcodec/lagarithrac.h @@ -107,6 +107,9 @@ static inline uint8_t lag_get_rac(lag_rac *l) l->range -= range_scaled * l->prob[255]; } + if (!l->range) + l->range = 0x80; + l->low -= range_scaled * l->prob[val]; return val; diff --git a/libavcodec/lcldec.c b/libavcodec/lcldec.c index 57b04f79f1..f09747b191 100644 --- a/libavcodec/lcldec.c +++ b/libavcodec/lcldec.c @@ -229,8 +229,29 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *data_size, AVPac len = mszh_dlen; } break; - case COMP_MSZH_NOCOMP: + case COMP_MSZH_NOCOMP: { + int bppx2; + switch (c->imgtype) { + case IMGTYPE_YUV111: + case IMGTYPE_RGB24: + bppx2 = 6; + break; + case IMGTYPE_YUV422: + case IMGTYPE_YUV211: + bppx2 = 4; + break; + case IMGTYPE_YUV411: + case IMGTYPE_YUV420: + bppx2 = 3; + break; + default: + bppx2 = 0; // will error out below + break; + } + if (len < ((width * height * bppx2) >> 1)) + return AVERROR_INVALIDDATA; break; + } default: av_log(avctx, AV_LOG_ERROR, "BUG! Unknown MSZH compression in frame decoder.\n"); return -1; @@ -462,7 +483,7 @@ static av_cold int decode_init(AVCodecContext *avctx) avcodec_get_frame_defaults(&c->pic); if (avctx->extradata_size < 8) { av_log(avctx, AV_LOG_ERROR, "Extradata size too small.\n"); - return 1; + return AVERROR_INVALIDDATA; } /* Check codec type */ @@ -511,7 +532,7 @@ static av_cold int decode_init(AVCodecContext *avctx) break; default: av_log(avctx, AV_LOG_ERROR, "Unsupported image format %d.\n", c->imgtype); - return 1; + return AVERROR_INVALIDDATA; } /* Detect compression method */ @@ -528,7 +549,7 @@ static av_cold int decode_init(AVCodecContext *avctx) break; default: av_log(avctx, AV_LOG_ERROR, "Unsupported compression format for MSZH (%d).\n", c->compression); - return 1; + return AVERROR_INVALIDDATA; } break; #if CONFIG_ZLIB_DECODER @@ -546,7 +567,7 @@ static av_cold int decode_init(AVCodecContext *avctx) default: if (c->compression < Z_NO_COMPRESSION || c->compression > Z_BEST_COMPRESSION) { av_log(avctx, AV_LOG_ERROR, "Unsupported compression level for ZLIB: (%d).\n", c->compression); - return 1; + return AVERROR_INVALIDDATA; } av_log(avctx, AV_LOG_DEBUG, "Compression level for ZLIB: (%d).\n", c->compression); } @@ -554,14 +575,14 @@ static av_cold int decode_init(AVCodecContext *avctx) #endif default: av_log(avctx, AV_LOG_ERROR, "BUG! Unknown codec in compression switch.\n"); - return 1; + return AVERROR_INVALIDDATA; } /* Allocate decompression buffer */ if (c->decomp_size) { if ((c->decomp_buf = av_malloc(max_decomp_size)) == NULL) { av_log(avctx, AV_LOG_ERROR, "Can't allocate decompression buffer.\n"); - return 1; + return AVERROR(ENOMEM); } } @@ -587,7 +608,7 @@ static av_cold int decode_init(AVCodecContext *avctx) if (zret != Z_OK) { av_log(avctx, AV_LOG_ERROR, "Inflate init error: %d\n", zret); av_freep(&c->decomp_buf); - return 1; + return AVERROR_UNKNOWN; } } #endif diff --git a/libavcodec/libgsm.c b/libavcodec/libgsm.c index 23950c0c21..52d8b93749 100644 --- a/libavcodec/libgsm.c +++ b/libavcodec/libgsm.c @@ -30,6 +30,7 @@ #include #include "avcodec.h" +#include "internal.h" #include "gsm.h" static av_cold int libgsm_encode_init(AVCodecContext *avctx) { @@ -188,7 +189,7 @@ static int libgsm_decode_frame(AVCodecContext *avctx, void *data, /* get output buffer */ s->frame.nb_samples = avctx->frame_size; - if ((ret = avctx->get_buffer(avctx, &s->frame)) < 0) { + if ((ret = ff_get_buffer(avctx, &s->frame)) < 0) { av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n"); return ret; } diff --git a/libavcodec/libopencore-amr.c b/libavcodec/libopencore-amr.c index 0de7130f19..27a399d796 100644 --- a/libavcodec/libopencore-amr.c +++ b/libavcodec/libopencore-amr.c @@ -20,6 +20,7 @@ */ #include "avcodec.h" +#include "internal.h" #include "libavutil/avstring.h" #include "libavutil/opt.h" @@ -143,7 +144,7 @@ static int amr_nb_decode_frame(AVCodecContext *avctx, void *data, /* get output buffer */ s->frame.nb_samples = 160; - if ((ret = avctx->get_buffer(avctx, &s->frame)) < 0) { + if ((ret = ff_get_buffer(avctx, &s->frame)) < 0) { av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n"); return ret; } @@ -295,7 +296,7 @@ static int amr_wb_decode_frame(AVCodecContext *avctx, void *data, /* get output buffer */ s->frame.nb_samples = 320; - if ((ret = avctx->get_buffer(avctx, &s->frame)) < 0) { + if ((ret = ff_get_buffer(avctx, &s->frame)) < 0) { av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n"); return ret; } diff --git a/libavcodec/libspeexdec.c b/libavcodec/libspeexdec.c index fdc39532b7..de6b806eff 100644 --- a/libavcodec/libspeexdec.c +++ b/libavcodec/libspeexdec.c @@ -23,6 +23,7 @@ #include #include #include "avcodec.h" +#include "internal.h" typedef struct { AVFrame frame; @@ -108,7 +109,7 @@ static int libspeex_decode_frame(AVCodecContext *avctx, void *data, /* get output buffer */ s->frame.nb_samples = s->frame_size; - if ((ret = avctx->get_buffer(avctx, &s->frame)) < 0) { + if ((ret = ff_get_buffer(avctx, &s->frame)) < 0) { av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n"); return ret; } diff --git a/libavcodec/libvorbis.c b/libavcodec/libvorbis.c index 5c35b35bc4..054fddaede 100644 --- a/libavcodec/libvorbis.c +++ b/libavcodec/libvorbis.c @@ -29,6 +29,7 @@ #include "libavutil/opt.h" #include "avcodec.h" #include "bytestream.h" +#include "internal.h" #include "vorbis.h" #include "libavutil/mathematics.h" @@ -59,6 +60,12 @@ static const AVOption options[] = { { "iblock", "Sets the impulse block bias", offsetof(OggVorbisContext, iblock), AV_OPT_TYPE_DOUBLE, { .dbl = 0 }, -15, 0, AV_OPT_FLAG_AUDIO_PARAM | AV_OPT_FLAG_ENCODING_PARAM }, { NULL } }; + +static const AVCodecDefault defaults[] = { + { "b", "0" }, + { NULL }, +}; + static const AVClass class = { "libvorbis", av_default_item_name, options, LIBAVUTIL_VERSION_INT }; static const char * error(int oggerr, int *averr) @@ -75,33 +82,29 @@ static av_cold int oggvorbis_init_encoder(vorbis_info *vi, AVCodecContext *avcco { OggVorbisContext *context = avccontext->priv_data; double cfreq; - int r; - if (avccontext->flags & CODEC_FLAG_QSCALE) { - /* variable bitrate */ - float quality = avccontext->global_quality / (float)FF_QP2LAMBDA; - r = vorbis_encode_setup_vbr(vi, avccontext->channels, + if (avccontext->flags & CODEC_FLAG_QSCALE || !avccontext->bit_rate) { + /* variable bitrate + * NOTE: we use the oggenc range of -1 to 10 for global_quality for + * user convenience, but libvorbis uses -0.1 to 1.0. + */ + float q = avccontext->global_quality / (float)FF_QP2LAMBDA; + /* default to 3 if the user did not set quality or bitrate */ + if (!(avccontext->flags & CODEC_FLAG_QSCALE)) + q = 3.0; + if (vorbis_encode_setup_vbr(vi, avccontext->channels, avccontext->sample_rate, - quality / 10.0); - if (r) { - av_log(avccontext, AV_LOG_ERROR, - "Unable to set quality to %g: %s\n", quality, error(r, &r)); - return r; - } + q / 10.0)) + return -1; } else { int minrate = avccontext->rc_min_rate > 0 ? avccontext->rc_min_rate : -1; - int maxrate = avccontext->rc_min_rate > 0 ? avccontext->rc_max_rate : -1; + int maxrate = avccontext->rc_max_rate > 0 ? avccontext->rc_max_rate : -1; /* constant bitrate */ - r = vorbis_encode_setup_managed(vi, avccontext->channels, - avccontext->sample_rate, minrate, - avccontext->bit_rate, maxrate); - if (r) { - av_log(avccontext, AV_LOG_ERROR, - "Unable to set CBR to %d: %s\n", avccontext->bit_rate, - error(r, &r)); - return r; - } + if (vorbis_encode_setup_managed(vi, avccontext->channels, + avccontext->sample_rate, maxrate, + avccontext->bit_rate, minrate)) + return -1; /* variable bitrate by estimate, disable slow rate management */ if (minrate == -1 && maxrate == -1) @@ -314,4 +317,5 @@ AVCodec ff_libvorbis_encoder = { .sample_fmts = (const enum AVSampleFormat[]) { AV_SAMPLE_FMT_S16, AV_SAMPLE_FMT_NONE }, .long_name = NULL_IF_CONFIG_SMALL("libvorbis Vorbis"), .priv_class = &class, + .defaults = defaults, }; diff --git a/libavcodec/libvpxenc.c b/libavcodec/libvpxenc.c index 621f818c9f..1d33ce9aec 100644 --- a/libavcodec/libvpxenc.c +++ b/libavcodec/libvpxenc.c @@ -483,6 +483,7 @@ static int queue_frames(AVCodecContext *avctx, uint8_t *buf, int buf_size, av_log(avctx, AV_LOG_ERROR, "Data buffer alloc (%zu bytes) failed\n", cx_frame->sz); + av_free(cx_frame); return AVERROR(ENOMEM); } memcpy(cx_frame->buf, pkt->data.frame.buf, pkt->data.frame.sz); diff --git a/libavcodec/libx264.c b/libavcodec/libx264.c index 59257f0199..a82cb2480f 100644 --- a/libavcodec/libx264.c +++ b/libavcodec/libx264.c @@ -174,7 +174,7 @@ static int X264_frame(AVCodecContext *ctx, uint8_t *buf, frame->pict_type == AV_PICTURE_TYPE_P ? X264_TYPE_P : frame->pict_type == AV_PICTURE_TYPE_B ? X264_TYPE_B : X264_TYPE_AUTO; - if (x4->params.b_tff != frame->top_field_first) { + if (x4->params.b_interlaced && x4->params.b_tff != frame->top_field_first) { x4->params.b_tff = frame->top_field_first; x264_encoder_reconfig(x4->enc, &x4->params); } @@ -462,6 +462,7 @@ static av_cold int X264_init(AVCodecContext *avctx) PARSE_X264_OPT("psy-rd", psy_rd); PARSE_X264_OPT("deblock", deblock); PARSE_X264_OPT("partitions", partitions); + PARSE_X264_OPT("stats", stats); if (x4->psy >= 0) x4->params.analyse.b_psy = x4->psy; if (x4->rc_lookahead >= 0) @@ -647,7 +648,8 @@ static const AVOption options[] = { { "spatial", NULL, 0, AV_OPT_TYPE_CONST, { X264_DIRECT_PRED_SPATIAL }, 0, 0, VE, "direct-pred" }, { "temporal", NULL, 0, AV_OPT_TYPE_CONST, { X264_DIRECT_PRED_TEMPORAL }, 0, 0, VE, "direct-pred" }, { "auto", NULL, 0, AV_OPT_TYPE_CONST, { X264_DIRECT_PRED_AUTO }, 0, 0, VE, "direct-pred" }, - { "slice-max-size","Constant quantization parameter rate control method",OFFSET(slice_max_size), AV_OPT_TYPE_INT, {-1 }, -1, INT_MAX, VE }, + { "slice-max-size","Limit the size of each slice in bytes", OFFSET(slice_max_size),AV_OPT_TYPE_INT, {-1 }, -1, INT_MAX, VE }, + { "stats", "Filename for 2 pass stats", OFFSET(stats), AV_OPT_TYPE_STRING, { 0 }, 0, 0, VE }, { NULL }, }; diff --git a/libavcodec/lzw.c b/libavcodec/lzw.c index 185a05d6ab..aed1a43fac 100644 --- a/libavcodec/lzw.c +++ b/libavcodec/lzw.c @@ -101,9 +101,14 @@ void ff_lzw_decode_tail(LZWState *p) struct LZWState *s = (struct LZWState *)p; if(s->mode == FF_LZW_GIF) { - while(s->pbuf < s->ebuf && s->bs>0){ - s->pbuf += s->bs; - s->bs = *s->pbuf++; + while (s->bs > 0) { + if (s->pbuf + s->bs >= s->ebuf) { + s->pbuf = s->ebuf; + break; + } else { + s->pbuf += s->bs; + s->bs = *s->pbuf++; + } } }else s->pbuf= s->ebuf; diff --git a/libavcodec/mace.c b/libavcodec/mace.c index ffa11ad80d..2f510dda53 100644 --- a/libavcodec/mace.c +++ b/libavcodec/mace.c @@ -25,6 +25,7 @@ */ #include "avcodec.h" +#include "internal.h" /* * Adapted to libavcodec by Francois Revol @@ -231,8 +232,8 @@ static av_cold int mace_decode_init(AVCodecContext * avctx) { MACEContext *ctx = avctx->priv_data; - if (avctx->channels > 2) - return -1; + if (avctx->channels > 2 || avctx->channels < 1) + return AVERROR(EINVAL); avctx->sample_fmt = AV_SAMPLE_FMT_S16; avcodec_get_frame_defaults(&ctx->frame); @@ -253,7 +254,7 @@ static int mace_decode_frame(AVCodecContext *avctx, void *data, /* get output buffer */ ctx->frame.nb_samples = 3 * (buf_size << (1 - is_mace3)) / avctx->channels; - if ((ret = avctx->get_buffer(avctx, &ctx->frame)) < 0) { + if ((ret = ff_get_buffer(avctx, &ctx->frame)) < 0) { av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n"); return ret; } diff --git a/libavcodec/mimic.c b/libavcodec/mimic.c index 652dd1bb5d..e1280595ed 100644 --- a/libavcodec/mimic.c +++ b/libavcodec/mimic.c @@ -259,8 +259,8 @@ static int decode(MimicContext *ctx, int quality, int num_coeffs, int index = (ctx->cur_index+backref)&15; uint8_t *p = ctx->flipped_ptrs[index].data[0]; - ff_thread_await_progress(&ctx->buf_ptrs[index], cur_row, 0); - if(p) { + if (index != ctx->cur_index && p) { + ff_thread_await_progress(&ctx->buf_ptrs[index], cur_row, 0); p += src - ctx->flipped_ptrs[ctx->prev_index].data[plane]; ctx->dsp.put_pixels_tab[1][0](dst, p, stride, 8); @@ -310,6 +310,7 @@ static int mimic_decode_frame(AVCodecContext *avctx, void *data, int width, height; int quality, num_coeffs; int swap_buf_size = buf_size - MIMIC_HEADER_SIZE; + int res; if(buf_size < MIMIC_HEADER_SIZE) { av_log(avctx, AV_LOG_ERROR, "insufficient data\n"); @@ -376,10 +377,10 @@ static int mimic_decode_frame(AVCodecContext *avctx, void *data, swap_buf_size>>2); init_get_bits(&ctx->gb, ctx->swap_buf, swap_buf_size << 3); - if(!decode(ctx, quality, num_coeffs, !is_pframe)) { - if (avctx->active_thread_type&FF_THREAD_FRAME) - ff_thread_report_progress(&ctx->buf_ptrs[ctx->cur_index], INT_MAX, 0); - else { + res = decode(ctx, quality, num_coeffs, !is_pframe); + ff_thread_report_progress(&ctx->buf_ptrs[ctx->cur_index], INT_MAX, 0); + if (!res) { + if (!(avctx->active_thread_type & FF_THREAD_FRAME)) { ff_thread_release_buffer(avctx, &ctx->buf_ptrs[ctx->cur_index]); return -1; } @@ -411,7 +412,7 @@ static av_cold int mimic_decode_end(AVCodecContext *avctx) for(i = 0; i < 16; i++) if(ctx->buf_ptrs[i].data[0]) ff_thread_release_buffer(avctx, &ctx->buf_ptrs[i]); - free_vlc(&ctx->vlc); + ff_free_vlc(&ctx->vlc); return 0; } diff --git a/libavcodec/mjpegbdec.c b/libavcodec/mjpegbdec.c index c8b1452e9e..b70311b795 100644 --- a/libavcodec/mjpegbdec.c +++ b/libavcodec/mjpegbdec.c @@ -59,6 +59,9 @@ read_header: s->restart_count = 0; s->mjpb_skiptosod = 0; + if (buf_end - buf_ptr >= 1 << 28) + return AVERROR_INVALIDDATA; + init_get_bits(&hgb, buf_ptr, /*buf_size*/(buf_end - buf_ptr)*8); skip_bits(&hgb, 32); /* reserved zeros */ @@ -66,7 +69,7 @@ read_header: if (get_bits_long(&hgb, 32) != MKBETAG('m','j','p','g')) { av_log(avctx, AV_LOG_WARNING, "not mjpeg-b (bad fourcc)\n"); - return 0; + return AVERROR_INVALIDDATA; } field_size = get_bits_long(&hgb, 32); /* field size */ @@ -111,7 +114,8 @@ read_header: av_log(avctx, AV_LOG_DEBUG, "sod offs: 0x%x\n", sod_offs); if (sos_offs) { - init_get_bits(&s->gb, buf_ptr+sos_offs, FFMIN(field_size, buf_end - (buf_ptr+sos_offs))*8); + init_get_bits(&s->gb, buf_ptr + sos_offs, + 8 * FFMIN(field_size, buf_end - buf_ptr - sos_offs)); s->mjpb_skiptosod = (sod_offs - sos_offs - show_bits(&s->gb, 16)); s->start_code = SOS; if (ff_mjpeg_decode_sos(s, NULL, NULL) < 0 && @@ -145,7 +149,7 @@ read_header: picture->quality*= FF_QP2LAMBDA; } - return buf_ptr - buf; + return buf_size; } AVCodec ff_mjpegb_decoder = { diff --git a/libavcodec/mjpegdec.c b/libavcodec/mjpegdec.c index 2abfea0d6e..655bc8e798 100644 --- a/libavcodec/mjpegdec.c +++ b/libavcodec/mjpegdec.c @@ -63,8 +63,8 @@ static int build_vlc(VLC *vlc, const uint8_t *bits_table, if (is_ac) huff_sym[0] = 16 * 256; - return init_vlc_sparse(vlc, 9, nb_codes, huff_size, 1, 1, - huff_code, 2, 2, huff_sym, 2, 2, use_static); + return ff_init_vlc_sparse(vlc, 9, nb_codes, huff_size, 1, 1, + huff_code, 2, 2, huff_sym, 2, 2, use_static); } static void build_basic_mjpeg_vlc(MJpegDecodeContext *s) @@ -197,7 +197,7 @@ int ff_mjpeg_decode_dht(MJpegDecodeContext *s) len -= n; /* build VLC and flush previous vlc if present */ - free_vlc(&s->vlcs[class][index]); + ff_free_vlc(&s->vlcs[class][index]); av_log(s->avctx, AV_LOG_DEBUG, "class=%d index=%d nb_codes=%d\n", class, index, code_max + 1); if (build_vlc(&s->vlcs[class][index], bits_table, val_table, @@ -205,7 +205,7 @@ int ff_mjpeg_decode_dht(MJpegDecodeContext *s) return -1; if (class > 0) { - free_vlc(&s->vlcs[2][index]); + ff_free_vlc(&s->vlcs[2][index]); if (build_vlc(&s->vlcs[2][index], bits_table, val_table, code_max + 1, 0, 0) < 0) return -1; @@ -216,21 +216,21 @@ int ff_mjpeg_decode_dht(MJpegDecodeContext *s) int ff_mjpeg_decode_sof(MJpegDecodeContext *s) { - int len, nb_components, i, width, height, pix_fmt_id; + int len, nb_components, i, width, height, bits, pix_fmt_id; s->cur_scan = 0; s->upscale_h = s->upscale_v = 0; /* XXX: verify len field validity */ len = get_bits(&s->gb, 16); - s->bits = get_bits(&s->gb, 8); + bits = get_bits(&s->gb, 8); if (s->pegasus_rct) - s->bits = 9; - if (s->bits == 9 && !s->pegasus_rct) + bits = 9; + if (bits == 9 && !s->pegasus_rct) s->rct = 1; // FIXME ugly - if (s->bits != 8 && !s->lossless) { + if (bits != 8 && !s->lossless) { av_log(s->avctx, AV_LOG_ERROR, "only 8 bits/component accepted\n"); return -1; } @@ -255,7 +255,14 @@ int ff_mjpeg_decode_sof(MJpegDecodeContext *s) if (nb_components <= 0 || nb_components > MAX_COMPONENTS) return -1; - if (s->ls && !(s->bits <= 8 || nb_components == 1)) { + if (s->interlaced && (s->bottom_field == !s->interlace_polarity)) { + if (nb_components != s->nb_components) { + av_log(s->avctx, AV_LOG_ERROR, + "nb_components changing in interlaced picture\n"); + return AVERROR_INVALIDDATA; + } + } + if (s->ls && !(bits <= 8 || nb_components == 1)) { av_log(s->avctx, AV_LOG_ERROR, "only <= 8 bits/component or 16-bit gray accepted for JPEG-LS\n"); return -1; @@ -276,6 +283,13 @@ int ff_mjpeg_decode_sof(MJpegDecodeContext *s) s->quant_index[i] = get_bits(&s->gb, 8); if (s->quant_index[i] >= 4) return -1; + if (!s->h_count[i] || !s->v_count[i]) { + av_log(s->avctx, AV_LOG_ERROR, + "Invalid sampling factor in component %d %d:%d\n", + i, s->h_count[i], s->v_count[i]); + return AVERROR_INVALIDDATA; + } + av_log(s->avctx, AV_LOG_DEBUG, "component %d %d:%d id: %d quant:%d\n", i, s->h_count[i], s->v_count[i], s->component_id[i], s->quant_index[i]); @@ -292,11 +306,14 @@ int ff_mjpeg_decode_sof(MJpegDecodeContext *s) /* if different size, realloc/alloc picture */ /* XXX: also check h_count and v_count */ - if (width != s->width || height != s->height) { + if ( width != s->width || height != s->height + || bits != s->bits + ) { av_freep(&s->qscale_table); s->width = width; s->height = height; + s->bits = bits; s->interlaced = 0; /* test interlaced mode */ @@ -316,9 +333,7 @@ int ff_mjpeg_decode_sof(MJpegDecodeContext *s) s->first_picture = 0; } - if (s->interlaced && (s->bottom_field == !s->interlace_polarity)) - return 0; - + if (!(s->interlaced && (s->bottom_field == !s->interlace_polarity))) { /* XXX: not complete test ! */ pix_fmt_id = (s->h_count[0] << 28) | (s->v_count[0] << 24) | (s->h_count[1] << 20) | (s->v_count[1] << 16) | @@ -403,9 +418,12 @@ int ff_mjpeg_decode_sof(MJpegDecodeContext *s) } if (s->ls) { s->upscale_h = s->upscale_v = 0; - if (s->nb_components > 1) + if (s->nb_components == 3) { s->avctx->pix_fmt = PIX_FMT_RGB24; - else if (s->bits <= 8) + } else if (s->nb_components != 1) { + av_log(s->avctx, AV_LOG_ERROR, "Unsupported number of components %d\n", s->nb_components); + return AVERROR_PATCHWELCOME; + } else if (s->bits <= 8) s->avctx->pix_fmt = PIX_FMT_GRAY8; else s->avctx->pix_fmt = PIX_FMT_GRAY16; @@ -431,6 +449,7 @@ int ff_mjpeg_decode_sof(MJpegDecodeContext *s) if (len != (8 + (3 * nb_components))) av_log(s->avctx, AV_LOG_DEBUG, "decode_sof0: error, len(%d) mismatch\n", len); + } /* totally blank picture as progressive JPEG will only add details to it */ if (s->progressive) { @@ -706,6 +725,12 @@ static int ljpeg_decode_rgb_scan(MJpegDecodeContext *s, int nb_components, int p int resync_mb_y = 0; int resync_mb_x = 0; + if (s->nb_components != 3 && s->nb_components != 4) + return AVERROR_INVALIDDATA; + if (s->v_max != 1 || s->h_max != 1 || !s->lossless) + return AVERROR_INVALIDDATA; + + s->restart_count = s->restart_interval; av_fast_malloc(&s->ljpeg_buffer, &s->ljpeg_buffer_size, @@ -784,10 +809,9 @@ static int ljpeg_decode_rgb_scan(MJpegDecodeContext *s, int nb_components, int p } static int ljpeg_decode_yuv_scan(MJpegDecodeContext *s, int predictor, - int point_transform) + int point_transform, int nb_components) { int i, mb_x, mb_y; - const int nb_components=s->nb_components; int bits= (s->bits+7)&~7; int resync_mb_y = 0; int resync_mb_x = 0; @@ -984,9 +1008,9 @@ static int mjpeg_decode_scan(MJpegDecodeContext *s, int nb_components, int Ah, if (s->restart_interval && !s->restart_count) s->restart_count = s->restart_interval; - if (get_bits_count(&s->gb)>s->gb.size_in_bits) { + if (get_bits_left(&s->gb) < 0) { av_log(s->avctx, AV_LOG_ERROR, "overread %d\n", - get_bits_count(&s->gb) - s->gb.size_in_bits); + -get_bits_left(&s->gb)); return -1; } for (i = 0; i < nb_components; i++) { @@ -1005,12 +1029,17 @@ static int mjpeg_decode_scan(MJpegDecodeContext *s, int nb_components, int Ah, if (s->interlaced && s->bottom_field) block_offset += linesize[c] >> 1; - ptr = data[c] + block_offset; + if ( 8*(h * mb_x + x) < s->width + && 8*(v * mb_y + y) < s->height) { + ptr = data[c] + block_offset; + } else + ptr = NULL; if (!s->progressive) { - if (copy_mb) - mjpeg_copy_block(ptr, reference_data[c] + block_offset, - linesize[c], s->avctx->lowres); - else { + if (copy_mb) { + if (ptr) + mjpeg_copy_block(ptr, reference_data[c] + block_offset, + linesize[c], s->avctx->lowres); + } else { s->dsp.clear_block(s->block); if (decode_block(s, s->block, i, s->dc_index[i], s->ac_index[i], @@ -1019,7 +1048,9 @@ static int mjpeg_decode_scan(MJpegDecodeContext *s, int nb_components, int Ah, "error y=%d x=%d\n", mb_y, mb_x); return -1; } - s->dsp.idct_put(ptr, linesize[c], s->block); + if (ptr) { + s->dsp.idct_put(ptr, linesize[c], s->block); + } } } else { int block_idx = s->block_stride[c] * (v * mb_y + y) + @@ -1086,8 +1117,14 @@ static int mjpeg_decode_scan_progressive_ac(MJpegDecodeContext *s, int ss, int last_scan = 0; int16_t *quant_matrix = s->quant_matrixes[s->quant_index[c]]; + + if (ss < 0 || ss >= 64 || + se < ss || se >= 64 || + Ah < 0 || Al < 0) + return AVERROR_INVALIDDATA; + if (!Al) { - s->coefs_finished[c] |= (1LL << (se + 1)) - (1LL << ss); + s->coefs_finished[c] |= (2LL << se) - (1LL << ss); last_scan = !~s->coefs_finished[c]; } @@ -1227,7 +1264,8 @@ int ff_mjpeg_decode_sos(MJpegDecodeContext *s, const uint8_t *mb_bitmask, if (ljpeg_decode_rgb_scan(s, nb_components, predictor, point_transform) < 0) return -1; } else { - if (ljpeg_decode_yuv_scan(s, predictor, point_transform) < 0) + if (ljpeg_decode_yuv_scan(s, predictor, point_transform, + nb_components)) return -1; } } @@ -1269,7 +1307,7 @@ static int mjpeg_decode_app(MJpegDecodeContext *s) len = get_bits(&s->gb, 16); if (len < 5) return -1; - if (8 * len + get_bits_count(&s->gb) > s->gb.size_in_bits) + if (8 * len > get_bits_left(&s->gb)) return -1; id = get_bits_long(&s->gb, 32); @@ -1348,6 +1386,8 @@ static int mjpeg_decode_app(MJpegDecodeContext *s) } if (id == AV_RL32("LJIF")) { + int rgb = s->rgb; + int pegasus_rct = s->pegasus_rct; if (s->avctx->debug & FF_DEBUG_PICT_INFO) av_log(s->avctx, AV_LOG_INFO, "Pegasus lossless jpeg header found\n"); @@ -1357,17 +1397,27 @@ static int mjpeg_decode_app(MJpegDecodeContext *s) skip_bits(&s->gb, 16); /* unknwon always 0? */ switch (get_bits(&s->gb, 8)) { case 1: - s->rgb = 1; - s->pegasus_rct = 0; + rgb = 1; + pegasus_rct = 0; break; case 2: - s->rgb = 1; - s->pegasus_rct = 1; + rgb = 1; + pegasus_rct = 1; break; default: av_log(s->avctx, AV_LOG_ERROR, "unknown colorspace\n"); } + len -= 9; + if (s->got_picture) + if (rgb != s->rgb || pegasus_rct != s->pegasus_rct) { + av_log(s->avctx, AV_LOG_WARNING, "Mismatching LJIF tag\n"); + goto out; + } + + s->rgb = rgb; + s->pegasus_rct = pegasus_rct; + goto out; } @@ -1407,8 +1457,7 @@ out: static int mjpeg_decode_com(MJpegDecodeContext *s) { int len = get_bits(&s->gb, 16); - if (len >= 2 && - 8 * len - 16 + get_bits_count(&s->gb) <= s->gb.size_in_bits) { + if (len >= 2 && 8 * len - 16 <= get_bits_left(&s->gb)) { char *cbuf = av_malloc(len - 1); if (cbuf) { int i; @@ -1534,6 +1583,10 @@ int ff_mjpeg_find_marker(MJpegDecodeContext *s, put_bits(&pb, 8, x); if (x == 0xFF) { x = src[b++]; + if (x & 0x80) { + av_log(s->avctx, AV_LOG_WARNING, "Invalid escape sequence\n"); + x &= 0x7f; + } put_bits(&pb, 7, x); bit_count--; } @@ -1574,6 +1627,10 @@ int ff_mjpeg_decode_frame(AVCodecContext *avctx, void *data, int *data_size, /* EOF */ if (start_code < 0) { goto the_end; + } else if (unescaped_buf_size > (1U<<29)) { + av_log(avctx, AV_LOG_ERROR, "MJPEG packet 0x%x too big (0x%x/0x%x), corrupt data?\n", + start_code, unescaped_buf_ptr, buf_size); + return AVERROR_INVALIDDATA; } else { av_log(avctx, AV_LOG_DEBUG, "marker=%x avail_size_in_buf=%td\n", start_code, buf_end - buf_ptr); @@ -1595,6 +1652,12 @@ int ff_mjpeg_decode_frame(AVCodecContext *avctx, void *data, int *data_size, else if (start_code == COM) mjpeg_decode_com(s); + if (!CONFIG_JPEGLS_DECODER && + (start_code == SOF48 || start_code == LSE)) { + av_log(avctx, AV_LOG_ERROR, "JPEG-LS support not enabled.\n"); + return AVERROR(ENOSYS); + } + switch (start_code) { case SOI: s->restart_interval = 0; @@ -1771,7 +1834,7 @@ av_cold int ff_mjpeg_decode_end(AVCodecContext *avctx) for (i = 0; i < 3; i++) { for (j = 0; j < 4; j++) - free_vlc(&s->vlcs[i][j]); + ff_free_vlc(&s->vlcs[i][j]); } for (i = 0; i < MAX_COMPONENTS; i++) { av_freep(&s->blocks[i]); diff --git a/libavcodec/mlpdec.c b/libavcodec/mlpdec.c index 47aee286ff..07db8d67d5 100644 --- a/libavcodec/mlpdec.c +++ b/libavcodec/mlpdec.c @@ -27,6 +27,7 @@ #include #include "avcodec.h" +#include "internal.h" #include "dsputil.h" #include "libavutil/intreadwrite.h" #include "get_bits.h" @@ -369,9 +370,10 @@ static int read_restart_header(MLPDecodeContext *m, GetBitContext *gbp, uint8_t checksum; uint8_t lossless_check; int start_count = get_bits_count(gbp); - const int max_matrix_channel = m->avctx->codec_id == CODEC_ID_MLP - ? MAX_MATRIX_CHANNEL_MLP - : MAX_MATRIX_CHANNEL_TRUEHD; + int min_channel, max_channel, max_matrix_channel; + const int std_max_matrix_channel = m->avctx->codec_id == CODEC_ID_MLP + ? MAX_MATRIX_CHANNEL_MLP + : MAX_MATRIX_CHANNEL_TRUEHD; sync_word = get_bits(gbp, 13); @@ -390,18 +392,18 @@ static int read_restart_header(MLPDecodeContext *m, GetBitContext *gbp, skip_bits(gbp, 16); /* Output timestamp */ - s->min_channel = get_bits(gbp, 4); - s->max_channel = get_bits(gbp, 4); - s->max_matrix_channel = get_bits(gbp, 4); + min_channel = get_bits(gbp, 4); + max_channel = get_bits(gbp, 4); + max_matrix_channel = get_bits(gbp, 4); - if (s->max_matrix_channel > max_matrix_channel) { + if (max_matrix_channel > std_max_matrix_channel) { av_log(m->avctx, AV_LOG_ERROR, "Max matrix channel cannot be greater than %d.\n", max_matrix_channel); return AVERROR_INVALIDDATA; } - if (s->max_channel != s->max_matrix_channel) { + if (max_channel != max_matrix_channel) { av_log(m->avctx, AV_LOG_ERROR, "Max channel must be equal max matrix channel.\n"); return AVERROR_INVALIDDATA; @@ -416,15 +418,20 @@ static int read_restart_header(MLPDecodeContext *m, GetBitContext *gbp, return AVERROR_INVALIDDATA; } - if (s->min_channel > s->max_channel) { + if (min_channel > max_channel) { av_log(m->avctx, AV_LOG_ERROR, "Substream min channel cannot be greater than max channel.\n"); return AVERROR_INVALIDDATA; } - if (m->avctx->request_channels > 0 - && s->max_channel + 1 >= m->avctx->request_channels - && substr < m->max_decoded_substream) { + + s->min_channel = min_channel; + s->max_channel = max_channel; + s->max_matrix_channel = max_matrix_channel; + + if (m->avctx->request_channels > 0 && + m->avctx->request_channels <= s->max_channel + 1 && + m->max_decoded_substream > substr) { av_log(m->avctx, AV_LOG_DEBUG, "Extracting %d channel downmix from substream %d. " "Further substreams will be skipped.\n", @@ -976,7 +983,7 @@ static int output_data(MLPDecodeContext *m, unsigned int substr, /* get output buffer */ m->frame.nb_samples = s->blockpos; - if ((ret = avctx->get_buffer(avctx, &m->frame)) < 0) { + if ((ret = ff_get_buffer(avctx, &m->frame)) < 0) { av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n"); return ret; } diff --git a/libavcodec/mmvideo.c b/libavcodec/mmvideo.c index ff7d100792..b480533128 100644 --- a/libavcodec/mmvideo.c +++ b/libavcodec/mmvideo.c @@ -33,6 +33,7 @@ #include "libavutil/intreadwrite.h" #include "avcodec.h" +#include "bytestream.h" #define MM_PREAMBLE_SIZE 6 @@ -48,6 +49,7 @@ typedef struct MmContext { AVCodecContext *avctx; AVFrame frame; int palette[AVPALETTE_COUNT]; + GetByteContext gb; } MmContext; static av_cold int mm_decode_init(AVCodecContext *avctx) @@ -58,46 +60,53 @@ static av_cold int mm_decode_init(AVCodecContext *avctx) avctx->pix_fmt = PIX_FMT_PAL8; + if (!avctx->width || !avctx->height || + (avctx->width & 1) || (avctx->height & 1)) { + av_log(avctx, AV_LOG_ERROR, "Invalid video dimensions: %dx%d\n", + avctx->width, avctx->height); + return AVERROR(EINVAL); + } + avcodec_get_frame_defaults(&s->frame); s->frame.reference = 3; return 0; } -static void mm_decode_pal(MmContext *s, const uint8_t *buf, const uint8_t *buf_end) +static int mm_decode_pal(MmContext *s) { int i; - buf += 4; - for (i=0; i<128 && buf+2palette[i] = 0xFF << 24 | AV_RB24(buf); + + bytestream2_skip(&s->gb, 4); + for (i = 0; i < 128; i++) { + s->palette[i] = 0xFF << 24 | bytestream2_get_be24(&s->gb); s->palette[i+128] = s->palette[i]<<2; - buf += 3; } + + return 0; } /** * @param half_horiz Half horizontal resolution (0 or 1) * @param half_vert Half vertical resolution (0 or 1) */ -static void mm_decode_intra(MmContext * s, int half_horiz, int half_vert, const uint8_t *buf, int buf_size) +static int mm_decode_intra(MmContext * s, int half_horiz, int half_vert) { int i, x, y; i=0; x=0; y=0; - while(igb) > 0) { int run_length, color; if (y >= s->avctx->height) - return; + return 0; - if (buf[i] & 0x80) { + color = bytestream2_get_byte(&s->gb); + if (color & 0x80) { run_length = 1; - color = buf[i]; - i++; }else{ - run_length = (buf[i] & 0x7f) + 2; - color = buf[i+1]; - i+=2; + run_length = (color & 0x7f) + 2; + color = bytestream2_get_byte(&s->gb); } if (half_horiz) @@ -105,7 +114,7 @@ static void mm_decode_intra(MmContext * s, int half_horiz, int half_vert, const if (color) { memset(s->frame.data[0] + y*s->frame.linesize[0] + x, color, run_length); - if (half_vert) + if (half_vert && y + half_vert < s->avctx->height) memset(s->frame.data[0] + (y+1)*s->frame.linesize[0] + x, color, run_length); } x+= run_length; @@ -115,23 +124,28 @@ static void mm_decode_intra(MmContext * s, int half_horiz, int half_vert, const y += 1 + half_vert; } } + + return 0; } /* * @param half_horiz Half horizontal resolution (0 or 1) * @param half_vert Half vertical resolution (0 or 1) */ -static void mm_decode_inter(MmContext * s, int half_horiz, int half_vert, const uint8_t *buf, int buf_size) +static int mm_decode_inter(MmContext * s, int half_horiz, int half_vert) { - const int data_ptr = 2 + AV_RL16(&buf[0]); - int d, r, y; - d = data_ptr; r = 2; y = 0; + int data_off = bytestream2_get_le16(&s->gb), y = 0; + GetByteContext data_ptr; - while(r < data_ptr) { + if (bytestream2_get_bytes_left(&s->gb) < data_off) + return AVERROR_INVALIDDATA; + + bytestream2_init(&data_ptr, s->gb.buffer + data_off, bytestream2_get_bytes_left(&s->gb) - data_off); + while (s->gb.buffer < data_ptr.buffer_start) { int i, j; - int length = buf[r] & 0x7f; - int x = buf[r+1] + ((buf[r] & 0x80) << 1); - r += 2; + int length = bytestream2_get_byte(&s->gb); + int x = bytestream2_get_byte(&s->gb) + ((length & 0x80) << 1); + length &= 0x7F; if (length==0) { y += x; @@ -139,13 +153,16 @@ static void mm_decode_inter(MmContext * s, int half_horiz, int half_vert, const } if (y + half_vert >= s->avctx->height) - return; + return 0; for(i=0; igb); for(j=0; j<8; j++) { - int replace = (buf[r+i] >> (7-j)) & 1; + int replace = (replace_array >> (7-j)) & 1; + if (x + half_horiz >= s->avctx->width) + return AVERROR_INVALIDDATA; if (replace) { - int color = buf[d]; + int color = bytestream2_get_byte(&data_ptr); s->frame.data[0][y*s->frame.linesize[0] + x] = color; if (half_horiz) s->frame.data[0][y*s->frame.linesize[0] + x + 1] = color; @@ -154,15 +171,15 @@ static void mm_decode_inter(MmContext * s, int half_horiz, int half_vert, const if (half_horiz) s->frame.data[0][(y+1)*s->frame.linesize[0] + x + 1] = color; } - d++; } x += 1 + half_horiz; } } - r += length; y += 1 + half_vert; } + + return 0; } static int mm_decode_frame(AVCodecContext *avctx, @@ -172,12 +189,14 @@ static int mm_decode_frame(AVCodecContext *avctx, const uint8_t *buf = avpkt->data; int buf_size = avpkt->size; MmContext *s = avctx->priv_data; - const uint8_t *buf_end = buf+buf_size; - int type; + int type, res; + if (buf_size < MM_PREAMBLE_SIZE) + return AVERROR_INVALIDDATA; type = AV_RL16(&buf[0]); buf += MM_PREAMBLE_SIZE; buf_size -= MM_PREAMBLE_SIZE; + bytestream2_init(&s->gb, buf, buf_size); if (avctx->reget_buffer(avctx, &s->frame) < 0) { av_log(avctx, AV_LOG_ERROR, "reget_buffer() failed\n"); @@ -185,16 +204,19 @@ static int mm_decode_frame(AVCodecContext *avctx, } switch(type) { - case MM_TYPE_PALETTE : mm_decode_pal(s, buf, buf_end); return buf_size; - case MM_TYPE_INTRA : mm_decode_intra(s, 0, 0, buf, buf_size); break; - case MM_TYPE_INTRA_HH : mm_decode_intra(s, 1, 0, buf, buf_size); break; - case MM_TYPE_INTRA_HHV : mm_decode_intra(s, 1, 1, buf, buf_size); break; - case MM_TYPE_INTER : mm_decode_inter(s, 0, 0, buf, buf_size); break; - case MM_TYPE_INTER_HH : mm_decode_inter(s, 1, 0, buf, buf_size); break; - case MM_TYPE_INTER_HHV : mm_decode_inter(s, 1, 1, buf, buf_size); break; - default : - return -1; + case MM_TYPE_PALETTE : res = mm_decode_pal(s); return buf_size; + case MM_TYPE_INTRA : res = mm_decode_intra(s, 0, 0); break; + case MM_TYPE_INTRA_HH : res = mm_decode_intra(s, 1, 0); break; + case MM_TYPE_INTRA_HHV : res = mm_decode_intra(s, 1, 1); break; + case MM_TYPE_INTER : res = mm_decode_inter(s, 0, 0); break; + case MM_TYPE_INTER_HH : res = mm_decode_inter(s, 1, 0); break; + case MM_TYPE_INTER_HHV : res = mm_decode_inter(s, 1, 1); break; + default: + res = AVERROR_INVALIDDATA; + break; } + if (res < 0) + return res; memcpy(s->frame.data[1], s->palette, AVPALETTE_SIZE); diff --git a/libavcodec/motion_est.c b/libavcodec/motion_est.c index ad6395296e..0b8c4f4058 100644 --- a/libavcodec/motion_est.c +++ b/libavcodec/motion_est.c @@ -300,7 +300,7 @@ int ff_init_me(MpegEncContext *s){ int cache_size= FFMIN(ME_MAP_SIZE>>ME_MAP_SHIFT, 1<avctx->dia_size)&255, FFABS(s->avctx->pre_dia_size)&255); - if(FFMIN(s->avctx->dia_size, s->avctx->pre_dia_size) < -ME_MAP_SIZE){ + if(FFMIN(s->avctx->dia_size, s->avctx->pre_dia_size) < -FFMIN(ME_MAP_SIZE, MAX_SAB_SIZE)){ av_log(s->avctx, AV_LOG_ERROR, "ME_MAP size is too small for SAB diamond\n"); return -1; } diff --git a/libavcodec/motionpixels.c b/libavcodec/motionpixels.c index f23a8799b1..cf801d1df6 100644 --- a/libavcodec/motionpixels.c +++ b/libavcodec/motionpixels.c @@ -55,6 +55,11 @@ static av_cold int mp_decode_init(AVCodecContext *avctx) int w4 = (avctx->width + 3) & ~3; int h4 = (avctx->height + 3) & ~3; + if(avctx->extradata_size < 2){ + av_log(avctx, AV_LOG_ERROR, "extradata too small\n"); + return AVERROR_INVALIDDATA; + } + motionpixels_tableinit(); mp->avctx = avctx; dsputil_init(&mp->dsp, avctx); @@ -191,10 +196,13 @@ static void mp_decode_line(MotionPixelsContext *mp, GetBitContext *gb, int y) p = mp_get_yuv_from_rgb(mp, x - 1, y); } else { p.y += mp_gradient(mp, 0, mp_get_vlc(mp, gb)); + p.y = av_clip(p.y, 0, 31); if ((x & 3) == 0) { if ((y & 3) == 0) { p.v += mp_gradient(mp, 1, mp_get_vlc(mp, gb)); + p.v = av_clip(p.v, -32, 31); p.u += mp_gradient(mp, 2, mp_get_vlc(mp, gb)); + p.u = av_clip(p.u, -32, 31); mp->hpt[((y / 4) * mp->avctx->width + x) / 4] = p; } else { p.v = mp->hpt[((y / 4) * mp->avctx->width + x) / 4].v; @@ -218,9 +226,12 @@ static void mp_decode_frame_helper(MotionPixelsContext *mp, GetBitContext *gb) p = mp_get_yuv_from_rgb(mp, 0, y); } else { p.y += mp_gradient(mp, 0, mp_get_vlc(mp, gb)); + p.y = av_clip(p.y, 0, 31); if ((y & 3) == 0) { p.v += mp_gradient(mp, 1, mp_get_vlc(mp, gb)); + p.v = av_clip(p.v, -32, 31); p.u += mp_gradient(mp, 2, mp_get_vlc(mp, gb)); + p.u = av_clip(p.u, -32, 31); } mp->vpt[y] = p; mp_set_rgb_from_yuv(mp, 0, y, &p); @@ -287,7 +298,7 @@ static int mp_decode_frame(AVCodecContext *avctx, if (init_vlc(&mp->vlc, mp->max_codes_bits, mp->codes_count, &mp->codes[0].size, sizeof(HuffCode), 1, &mp->codes[0].code, sizeof(HuffCode), 4, 0)) goto end; mp_decode_frame_helper(mp, &gb); - free_vlc(&mp->vlc); + ff_free_vlc(&mp->vlc); end: *data_size = sizeof(AVFrame); diff --git a/libavcodec/mpc.c b/libavcodec/mpc.c index c2975ec732..691b556293 100644 --- a/libavcodec/mpc.c +++ b/libavcodec/mpc.c @@ -78,13 +78,13 @@ void ff_mpc_dequantize_and_synth(MPCContext * c, int maxband, void *data, int ch for(ch = 0; ch < 2; ch++){ if(bands[i].res[ch]){ j = 0; - mul = mpc_CC[bands[i].res[ch]] * mpc_SCF[bands[i].scf_idx[ch][0]]; + mul = mpc_CC[bands[i].res[ch] + 1] * mpc_SCF[bands[i].scf_idx[ch][0]+6]; for(; j < 12; j++) c->sb_samples[ch][j][i] = mul * c->Q[ch][j + off]; - mul = mpc_CC[bands[i].res[ch]] * mpc_SCF[bands[i].scf_idx[ch][1]]; + mul = mpc_CC[bands[i].res[ch] + 1] * mpc_SCF[bands[i].scf_idx[ch][1]+6]; for(; j < 24; j++) c->sb_samples[ch][j][i] = mul * c->Q[ch][j + off]; - mul = mpc_CC[bands[i].res[ch]] * mpc_SCF[bands[i].scf_idx[ch][2]]; + mul = mpc_CC[bands[i].res[ch] + 1] * mpc_SCF[bands[i].scf_idx[ch][2]+6]; for(; j < 36; j++) c->sb_samples[ch][j][i] = mul * c->Q[ch][j + off]; } diff --git a/libavcodec/mpc7.c b/libavcodec/mpc7.c index 0bde329e08..38810cf191 100644 --- a/libavcodec/mpc7.c +++ b/libavcodec/mpc7.c @@ -27,6 +27,7 @@ #include "libavutil/lfg.h" #include "avcodec.h" +#include "internal.h" #include "get_bits.h" #include "dsputil.h" #include "mpegaudiodsp.h" @@ -193,7 +194,7 @@ static int get_scale_idx(GetBitContext *gb, int ref) int t = get_vlc2(gb, dscf_vlc.table, MPC7_DSCF_BITS, 1) - 7; if (t == 8) return get_bits(gb, 6); - return ref + t; + return av_clip_uintp2(ref + t, 7); } static int mpc7_decode_frame(AVCodecContext * avctx, void *data, @@ -217,7 +218,7 @@ static int mpc7_decode_frame(AVCodecContext * avctx, void *data, /* get output buffer */ c->frame.nb_samples = buf[1] ? c->lastframelen : MPC_FRAME_SIZE; - if ((ret = avctx->get_buffer(avctx, &c->frame)) < 0) { + if ((ret = ff_get_buffer(avctx, &c->frame)) < 0) { av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n"); return ret; } @@ -235,7 +236,7 @@ static int mpc7_decode_frame(AVCodecContext * avctx, void *data, int t = 4; if(i) t = get_vlc2(&gb, hdr_vlc.table, MPC7_HDR_BITS, 1) - 5; if(t == 4) bands[i].res[ch] = get_bits(&gb, 4); - else bands[i].res[ch] = bands[i-1].res[ch] + t; + else bands[i].res[ch] = av_clip(bands[i-1].res[ch] + t, 0, 17); } if(bands[i].res[0] || bands[i].res[1]){ diff --git a/libavcodec/mpc8.c b/libavcodec/mpc8.c index a4750ad961..def79f4aab 100644 --- a/libavcodec/mpc8.c +++ b/libavcodec/mpc8.c @@ -27,6 +27,7 @@ #include "libavutil/lfg.h" #include "avcodec.h" +#include "internal.h" #include "get_bits.h" #include "dsputil.h" #include "mpegaudiodsp.h" @@ -138,7 +139,8 @@ static av_cold int mpc8_decode_init(AVCodecContext * avctx) c->frames = 1 << (get_bits(&gb, 3) * 2); avctx->sample_fmt = AV_SAMPLE_FMT_S16; - avctx->channel_layout = (avctx->channels==2) ? AV_CH_LAYOUT_STEREO : AV_CH_LAYOUT_MONO; + avctx->channel_layout = (channels==2) ? AV_CH_LAYOUT_STEREO : AV_CH_LAYOUT_MONO; + avctx->channels = channels; if(vlc_initialized) return 0; av_log(avctx, AV_LOG_DEBUG, "Initing VLC\n"); @@ -184,13 +186,13 @@ static av_cold int mpc8_decode_init(AVCodecContext * avctx) q3_vlc[0].table = q3_0_table; q3_vlc[0].table_allocated = 512; - init_vlc_sparse(&q3_vlc[0], MPC8_Q3_BITS, MPC8_Q3_SIZE, + ff_init_vlc_sparse(&q3_vlc[0], MPC8_Q3_BITS, MPC8_Q3_SIZE, mpc8_q3_bits, 1, 1, mpc8_q3_codes, 1, 1, mpc8_q3_syms, 1, 1, INIT_VLC_USE_NEW_STATIC); q3_vlc[1].table = q3_1_table; q3_vlc[1].table_allocated = 516; - init_vlc_sparse(&q3_vlc[1], MPC8_Q4_BITS, MPC8_Q4_SIZE, + ff_init_vlc_sparse(&q3_vlc[1], MPC8_Q4_BITS, MPC8_Q4_SIZE, mpc8_q4_bits, 1, 1, mpc8_q4_codes, 1, 1, mpc8_q4_syms, 1, 1, INIT_VLC_USE_NEW_STATIC); @@ -252,7 +254,7 @@ static int mpc8_decode_frame(AVCodecContext * avctx, void *data, /* get output buffer */ c->frame.nb_samples = MPC_FRAME_SIZE; - if ((res = avctx->get_buffer(avctx, &c->frame)) < 0) { + if ((res = ff_get_buffer(avctx, &c->frame)) < 0) { av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n"); return res; } diff --git a/libavcodec/mpcdata.h b/libavcodec/mpcdata.h index 03df3da3b5..62f1164b74 100644 --- a/libavcodec/mpcdata.h +++ b/libavcodec/mpcdata.h @@ -22,13 +22,17 @@ #ifndef AVCODEC_MPCDATA_H #define AVCODEC_MPCDATA_H -static const float mpc_CC[18] = { - 65536.0000, 21845.3333, 13107.2000, 9362.2857, 7281.7778, 4369.0667, 2114.0645, +static const float mpc_CC[18+1] = { + 111.285962475327f, // 32768/2/255*sqrt(3) + 65536.0000 /* this value is never used */, + 21845.3333, 13107.2000, 9362.2857, 7281.7778, 4369.0667, 2114.0645, 1040.2539, 516.0315, 257.0039, 128.2505, 64.0626, 32.0156, 16.0039, 8.0010, 4.0002, 2.0001, 1.0000 }; -static const float mpc_SCF[128] = { +static const float mpc_SCF[128+6] = { + 920.016296386718750000, 766.355773925781250000, 638.359558105468750000, + 531.741149902343750000, 442.930114746093750000, 368.952209472656250000, 307.330047607421875000, 255.999984741210937500, 213.243041992187500000, 177.627334594726562500, 147.960128784179687500, 123.247924804687500000, 102.663139343261718750, 85.516410827636718750, 71.233520507812500000, 59.336143493652343750, 49.425861358642578125, 41.170787811279296875, diff --git a/libavcodec/mpeg12.c b/libavcodec/mpeg12.c index d34b54d76c..58456a63cb 100644 --- a/libavcodec/mpeg12.c +++ b/libavcodec/mpeg12.c @@ -83,6 +83,15 @@ static int mpeg_decode_motion(MpegEncContext *s, int fcode, int pred) return sign_extend(val, 5 + shift); } +#define check_scantable_index(ctx, x) \ + do { \ + if ((x) > 63) { \ + av_log(ctx->avctx, AV_LOG_ERROR, "ac-tex damaged at %d %d\n", \ + ctx->mb_x, ctx->mb_y); \ + return AVERROR_INVALIDDATA; \ + } \ + } while (0) \ + static inline int mpeg1_decode_block_intra(MpegEncContext *s, DCTELEM *block, int n) { int level, dc, diff, i, j, run; @@ -114,6 +123,7 @@ static inline int mpeg1_decode_block_intra(MpegEncContext *s, DCTELEM *block, in break; } else if (level != 0) { i += run; + check_scantable_index(s, i); j = scantable[i]; level = (level * qscale * quant_matrix[j]) >> 4; level = (level - 1) | 1; @@ -130,6 +140,7 @@ static inline int mpeg1_decode_block_intra(MpegEncContext *s, DCTELEM *block, in level = SHOW_UBITS(re, &s->gb, 8) ; LAST_SKIP_BITS(re, &s->gb, 8); } i += run; + check_scantable_index(s, i); j = scantable[i]; if (level < 0) { level = -level; @@ -141,10 +152,6 @@ static inline int mpeg1_decode_block_intra(MpegEncContext *s, DCTELEM *block, in level = (level - 1) | 1; } } - if (i > 63) { - av_log(s->avctx, AV_LOG_ERROR, "ac-tex damaged at %d %d\n", s->mb_x, s->mb_y); - return -1; - } block[j] = level; } @@ -264,6 +271,7 @@ static inline int mpeg1_fast_decode_block_inter(MpegEncContext *s, DCTELEM *bloc if (level != 0) { i += run; + check_scantable_index(s, i); j = scantable[i]; level = ((level * 2 + 1) * qscale) >> 1; level = (level - 1) | 1; @@ -280,6 +288,7 @@ static inline int mpeg1_fast_decode_block_inter(MpegEncContext *s, DCTELEM *bloc level = SHOW_UBITS(re, &s->gb, 8) ; SKIP_BITS(re, &s->gb, 8); } i += run; + check_scantable_index(s, i); j = scantable[i]; if (level < 0) { level = -level; @@ -345,6 +354,7 @@ static inline int mpeg2_decode_block_non_intra(MpegEncContext *s, DCTELEM *block if (level != 0) { i += run; + check_scantable_index(s, i); j = scantable[i]; level = ((level * 2 + 1) * qscale * quant_matrix[j]) >> 5; level = (level ^ SHOW_SBITS(re, &s->gb, 1)) - SHOW_SBITS(re, &s->gb, 1); @@ -356,6 +366,7 @@ static inline int mpeg2_decode_block_non_intra(MpegEncContext *s, DCTELEM *block level = SHOW_SBITS(re, &s->gb, 12); SKIP_BITS(re, &s->gb, 12); i += run; + check_scantable_index(s, i); j = scantable[i]; if (level < 0) { level = ((-level * 2 + 1) * qscale * quant_matrix[j]) >> 5; @@ -364,10 +375,6 @@ static inline int mpeg2_decode_block_non_intra(MpegEncContext *s, DCTELEM *block level = ((level * 2 + 1) * qscale * quant_matrix[j]) >> 5; } } - if (i > 63) { - av_log(s->avctx, AV_LOG_ERROR, "ac-tex damaged at %d %d\n", s->mb_x, s->mb_y); - return -1; - } mismatch ^= level; block[j] = level; @@ -414,6 +421,7 @@ static inline int mpeg2_fast_decode_block_non_intra(MpegEncContext *s, if (level != 0) { i += run; + check_scantable_index(s, i); j = scantable[i]; level = ((level * 2 + 1) * qscale) >> 1; level = (level ^ SHOW_SBITS(re, &s->gb, 1)) - SHOW_SBITS(re, &s->gb, 1); @@ -425,6 +433,7 @@ static inline int mpeg2_fast_decode_block_non_intra(MpegEncContext *s, level = SHOW_SBITS(re, &s->gb, 12); SKIP_BITS(re, &s->gb, 12); i += run; + check_scantable_index(s, i); j = scantable[i]; if (level < 0) { level = ((-level * 2 + 1) * qscale) >> 1; @@ -491,6 +500,7 @@ static inline int mpeg2_decode_block_intra(MpegEncContext *s, DCTELEM *block, in break; } else if (level != 0) { i += run; + check_scantable_index(s, i); j = scantable[i]; level = (level * qscale * quant_matrix[j]) >> 4; level = (level ^ SHOW_SBITS(re, &s->gb, 1)) - SHOW_SBITS(re, &s->gb, 1); @@ -501,6 +511,7 @@ static inline int mpeg2_decode_block_intra(MpegEncContext *s, DCTELEM *block, in UPDATE_CACHE(re, &s->gb); level = SHOW_SBITS(re, &s->gb, 12); SKIP_BITS(re, &s->gb, 12); i += run; + check_scantable_index(s, i); j = scantable[i]; if (level < 0) { level = (-level * qscale * quant_matrix[j]) >> 4; @@ -509,10 +520,6 @@ static inline int mpeg2_decode_block_intra(MpegEncContext *s, DCTELEM *block, in level = (level * qscale * quant_matrix[j]) >> 4; } } - if (i > 63) { - av_log(s->avctx, AV_LOG_ERROR, "ac-tex damaged at %d %d\n", s->mb_x, s->mb_y); - return -1; - } mismatch ^= level; block[j] = level; @@ -527,10 +534,10 @@ static inline int mpeg2_decode_block_intra(MpegEncContext *s, DCTELEM *block, in static inline int mpeg2_fast_decode_block_intra(MpegEncContext *s, DCTELEM *block, int n) { - int level, dc, diff, j, run; + int level, dc, diff, i, j, run; int component; RLTable *rl; - uint8_t * scantable = s->intra_scantable.permutated; + uint8_t * const scantable = s->intra_scantable.permutated; const uint16_t *quant_matrix; const int qscale = s->qscale; @@ -549,6 +556,7 @@ static inline int mpeg2_fast_decode_block_intra(MpegEncContext *s, DCTELEM *bloc dc += diff; s->last_dc[component] = dc; block[0] = dc << (3 - s->intra_dc_precision); + i = 0; if (s->intra_vlc_format) rl = &ff_rl_mpeg2; else @@ -564,8 +572,9 @@ static inline int mpeg2_fast_decode_block_intra(MpegEncContext *s, DCTELEM *bloc if (level == 127) { break; } else if (level != 0) { - scantable += run; - j = *scantable; + i += run; + check_scantable_index(s, i); + j = scantable[i]; level = (level * qscale * quant_matrix[j]) >> 4; level = (level ^ SHOW_SBITS(re, &s->gb, 1)) - SHOW_SBITS(re, &s->gb, 1); LAST_SKIP_BITS(re, &s->gb, 1); @@ -574,8 +583,9 @@ static inline int mpeg2_fast_decode_block_intra(MpegEncContext *s, DCTELEM *bloc run = SHOW_UBITS(re, &s->gb, 6) + 1; LAST_SKIP_BITS(re, &s->gb, 6); UPDATE_CACHE(re, &s->gb); level = SHOW_SBITS(re, &s->gb, 12); SKIP_BITS(re, &s->gb, 12); - scantable += run; - j = *scantable; + i += run; + check_scantable_index(s, i); + j = scantable[i]; if (level < 0) { level = (-level * qscale * quant_matrix[j]) >> 4; level = -level; @@ -589,7 +599,7 @@ static inline int mpeg2_fast_decode_block_intra(MpegEncContext *s, DCTELEM *bloc CLOSE_READER(re, &s->gb); } - s->block_last_index[n] = scantable - s->intra_scantable.permutated; + s->block_last_index[n] = i; return 0; } @@ -696,8 +706,8 @@ av_cold void ff_mpeg12_init_vlcs(void) INIT_VLC_STATIC(&mb_btype_vlc, MB_BTYPE_VLC_BITS, 11, &table_mb_btype[0][1], 2, 1, &table_mb_btype[0][0], 2, 1, 64); - init_rl(&ff_rl_mpeg1, ff_mpeg12_static_rl_table_store[0]); - init_rl(&ff_rl_mpeg2, ff_mpeg12_static_rl_table_store[1]); + ff_init_rl(&ff_rl_mpeg1, ff_mpeg12_static_rl_table_store[0]); + ff_init_rl(&ff_rl_mpeg2, ff_mpeg12_static_rl_table_store[1]); INIT_2D_VLC_RL(ff_rl_mpeg1, 680); INIT_2D_VLC_RL(ff_rl_mpeg2, 674); @@ -1250,7 +1260,7 @@ static int mpeg_decode_postinit(AVCodecContext *avctx) s1->save_width != s->width || s1->save_height != s->height || s1->save_aspect_info != s->aspect_ratio_info || - s1->save_progressive_seq != s->progressive_sequence || + (s1->save_progressive_seq != s->progressive_sequence && (s->height&31)) || 0) { @@ -2282,8 +2292,9 @@ static int mpeg_decode_frame(AVCodecContext *avctx, s->slice_count = 0; - if (avctx->extradata && !avctx->frame_number) { + if (avctx->extradata && !s->extradata_decoded) { int ret = decode_chunks(avctx, picture, data_size, avctx->extradata, avctx->extradata_size); + s->extradata_decoded = 1; if (ret < 0 && (avctx->err_recognition & AV_EF_EXPLODE)) return ret; } diff --git a/libavcodec/mpeg12.h b/libavcodec/mpeg12.h index 9a9cc85dee..6e60c8695f 100644 --- a/libavcodec/mpeg12.h +++ b/libavcodec/mpeg12.h @@ -42,6 +42,7 @@ typedef struct Mpeg1Context { AVRational frame_rate_ext; ///< MPEG-2 specific framerate modificator int sync; ///< Did we reach a sync point like a GOP/SEQ/KEYFrame? int tmpgexs; + int extradata_decoded; } Mpeg1Context; extern uint8_t ff_mpeg12_static_rl_table_store[2][2][2*MAX_RUN + MAX_LEVEL + 3]; diff --git a/libavcodec/mpeg12data.c b/libavcodec/mpeg12data.c index c40883692b..309ec4efd6 100644 --- a/libavcodec/mpeg12data.c +++ b/libavcodec/mpeg12data.c @@ -305,7 +305,7 @@ const uint8_t ff_mpeg12_mbMotionVectorTable[17][2] = { { 0xc, 10 }, }; -const AVRational avpriv_frame_rate_tab[] = { +const AVRational avpriv_frame_rate_tab[16] = { { 0, 0}, {24000, 1001}, { 24, 1}, diff --git a/libavcodec/mpeg12enc.c b/libavcodec/mpeg12enc.c index 5dc7652d12..c730f878cb 100644 --- a/libavcodec/mpeg12enc.c +++ b/libavcodec/mpeg12enc.c @@ -463,7 +463,7 @@ static av_always_inline void mpeg1_encode_mb_internal(MpegEncContext *s, } if (cbp == 0 && !first_mb && s->mv_type == MV_TYPE_16X16 && - (mb_x != s->mb_width - 1 || (mb_y != s->mb_height - 1 && s->codec_id == CODEC_ID_MPEG1VIDEO)) && + (mb_x != s->mb_width - 1 || (mb_y != s->end_mb_y - 1 && s->codec_id == CODEC_ID_MPEG1VIDEO)) && ((s->pict_type == AV_PICTURE_TYPE_P && (motion_x | motion_y) == 0) || (s->pict_type == AV_PICTURE_TYPE_B && s->mv_dir == s->last_mv_dir && (((s->mv_dir & MV_DIR_FORWARD) ? ((s->mv[0][0][0] - s->last_mv[0][0][0])|(s->mv[0][0][1] - s->last_mv[0][0][1])) : 0) | ((s->mv_dir & MV_DIR_BACKWARD) ? ((s->mv[1][0][0] - s->last_mv[1][0][0])|(s->mv[1][0][1] - s->last_mv[1][0][1])) : 0)) == 0))) { @@ -729,8 +729,8 @@ void ff_mpeg1_encode_init(MpegEncContext *s) int i; done=1; - init_rl(&ff_rl_mpeg1, ff_mpeg12_static_rl_table_store[0]); - init_rl(&ff_rl_mpeg2, ff_mpeg12_static_rl_table_store[1]); + ff_init_rl(&ff_rl_mpeg1, ff_mpeg12_static_rl_table_store[0]); + ff_init_rl(&ff_rl_mpeg2, ff_mpeg12_static_rl_table_store[1]); for(i=0; i<64; i++) { @@ -974,7 +974,7 @@ AVCodec ff_mpeg1video_encoder = { .close = MPV_encode_end, .supported_framerates= avpriv_frame_rate_tab+1, .pix_fmts= (const enum PixelFormat[]){PIX_FMT_YUV420P, PIX_FMT_NONE}, - .capabilities= CODEC_CAP_DELAY, + .capabilities= CODEC_CAP_DELAY | CODEC_CAP_SLICE_THREADS, .long_name= NULL_IF_CONFIG_SMALL("MPEG-1 video"), .priv_class = &mpeg1_class, }; diff --git a/libavcodec/mpeg4videodec.c b/libavcodec/mpeg4videodec.c index b57395ae8f..859b04f552 100644 --- a/libavcodec/mpeg4videodec.c +++ b/libavcodec/mpeg4videodec.c @@ -160,7 +160,7 @@ static inline int mpeg4_is_resync(MpegEncContext *s){ return 0; } -static int mpeg4_decode_sprite_trajectory(MpegEncContext * s, GetBitContext *gb) +static int mpeg4_decode_sprite_trajectory(MpegEncContext *s, GetBitContext *gb) { int i; int a= 2<sprite_warping_accuracy; @@ -176,8 +176,8 @@ static int mpeg4_decode_sprite_trajectory(MpegEncContext * s, GetBitContext *gb) int h= s->height; int min_ab; - if(w<=0 || h<=0) - return -1; + if (w <= 0 || h <= 0) + return AVERROR_INVALIDDATA; for(i=0; inum_sprite_warping_points; i++){ int length; @@ -415,8 +415,8 @@ int mpeg4_decode_video_packet_header(MpegEncContext *s) skip_bits(&s->gb, 3); /* intra dc vlc threshold */ //FIXME don't just ignore everything if(s->pict_type == AV_PICTURE_TYPE_S && s->vol_sprite_usage==GMC_SPRITE){ - if(mpeg4_decode_sprite_trajectory(s, &s->gb) < 0) - return -1; + if (mpeg4_decode_sprite_trajectory(s, &s->gb) < 0) + return AVERROR_INVALIDDATA; av_log(s->avctx, AV_LOG_ERROR, "untested\n"); } @@ -654,13 +654,13 @@ try_again: if ((cbpc & 16) == 0) { /* 16x16 motion prediction */ - h263_pred_motion(s, 0, 0, &pred_x, &pred_y); + ff_h263_pred_motion(s, 0, 0, &pred_x, &pred_y); if(!s->mcsel){ - mx = h263_decode_motion(s, pred_x, s->f_code); + mx = ff_h263_decode_motion(s, pred_x, s->f_code); if (mx >= 0xffff) return -1; - my = h263_decode_motion(s, pred_y, s->f_code); + my = ff_h263_decode_motion(s, pred_y, s->f_code); if (my >= 0xffff) return -1; s->current_picture.f.mb_type[xy] = MB_TYPE_16x16 | MB_TYPE_L0; @@ -678,12 +678,12 @@ try_again: int i; s->current_picture.f.mb_type[xy] = MB_TYPE_8x8 | MB_TYPE_L0; for(i=0;i<4;i++) { - int16_t *mot_val= h263_pred_motion(s, i, 0, &pred_x, &pred_y); - mx = h263_decode_motion(s, pred_x, s->f_code); + int16_t *mot_val= ff_h263_pred_motion(s, i, 0, &pred_x, &pred_y); + mx = ff_h263_decode_motion(s, pred_x, s->f_code); if (mx >= 0xffff) return -1; - my = h263_decode_motion(s, pred_y, s->f_code); + my = ff_h263_decode_motion(s, pred_y, s->f_code); if (my >= 0xffff) return -1; mot_val[0] = mx; @@ -1248,14 +1248,14 @@ static int mpeg4_decode_mb(MpegEncContext *s, s->field_select[0][0]= get_bits1(&s->gb); s->field_select[0][1]= get_bits1(&s->gb); - h263_pred_motion(s, 0, 0, &pred_x, &pred_y); + ff_h263_pred_motion(s, 0, 0, &pred_x, &pred_y); for(i=0; i<2; i++){ - mx = h263_decode_motion(s, pred_x, s->f_code); + mx = ff_h263_decode_motion(s, pred_x, s->f_code); if (mx >= 0xffff) return -1; - my = h263_decode_motion(s, pred_y/2, s->f_code); + my = ff_h263_decode_motion(s, pred_y/2, s->f_code); if (my >= 0xffff) return -1; @@ -1266,13 +1266,13 @@ static int mpeg4_decode_mb(MpegEncContext *s, s->current_picture.f.mb_type[xy] = MB_TYPE_16x16 | MB_TYPE_L0; /* 16x16 motion prediction */ s->mv_type = MV_TYPE_16X16; - h263_pred_motion(s, 0, 0, &pred_x, &pred_y); - mx = h263_decode_motion(s, pred_x, s->f_code); + ff_h263_pred_motion(s, 0, 0, &pred_x, &pred_y); + mx = ff_h263_decode_motion(s, pred_x, s->f_code); if (mx >= 0xffff) return -1; - my = h263_decode_motion(s, pred_y, s->f_code); + my = ff_h263_decode_motion(s, pred_y, s->f_code); if (my >= 0xffff) return -1; @@ -1283,12 +1283,12 @@ static int mpeg4_decode_mb(MpegEncContext *s, s->current_picture.f.mb_type[xy] = MB_TYPE_8x8 | MB_TYPE_L0; s->mv_type = MV_TYPE_8X8; for(i=0;i<4;i++) { - mot_val = h263_pred_motion(s, i, 0, &pred_x, &pred_y); - mx = h263_decode_motion(s, pred_x, s->f_code); + mot_val = ff_h263_pred_motion(s, i, 0, &pred_x, &pred_y); + mx = ff_h263_decode_motion(s, pred_x, s->f_code); if (mx >= 0xffff) return -1; - my = h263_decode_motion(s, pred_y, s->f_code); + my = ff_h263_decode_motion(s, pred_y, s->f_code); if (my >= 0xffff) return -1; s->mv[0][i][0] = mx; @@ -1384,8 +1384,8 @@ static int mpeg4_decode_mb(MpegEncContext *s, if(USES_LIST(mb_type, 0)){ s->mv_dir = MV_DIR_FORWARD; - mx = h263_decode_motion(s, s->last_mv[0][0][0], s->f_code); - my = h263_decode_motion(s, s->last_mv[0][0][1], s->f_code); + mx = ff_h263_decode_motion(s, s->last_mv[0][0][0], s->f_code); + my = ff_h263_decode_motion(s, s->last_mv[0][0][1], s->f_code); s->last_mv[0][1][0]= s->last_mv[0][0][0]= s->mv[0][0][0] = mx; s->last_mv[0][1][1]= s->last_mv[0][0][1]= s->mv[0][0][1] = my; } @@ -1393,8 +1393,8 @@ static int mpeg4_decode_mb(MpegEncContext *s, if(USES_LIST(mb_type, 1)){ s->mv_dir |= MV_DIR_BACKWARD; - mx = h263_decode_motion(s, s->last_mv[1][0][0], s->b_code); - my = h263_decode_motion(s, s->last_mv[1][0][1], s->b_code); + mx = ff_h263_decode_motion(s, s->last_mv[1][0][0], s->b_code); + my = ff_h263_decode_motion(s, s->last_mv[1][0][1], s->b_code); s->last_mv[1][1][0]= s->last_mv[1][0][0]= s->mv[1][0][0] = mx; s->last_mv[1][1][1]= s->last_mv[1][0][1]= s->mv[1][0][1] = my; } @@ -1405,8 +1405,8 @@ static int mpeg4_decode_mb(MpegEncContext *s, s->mv_dir = MV_DIR_FORWARD; for(i=0; i<2; i++){ - mx = h263_decode_motion(s, s->last_mv[0][i][0] , s->f_code); - my = h263_decode_motion(s, s->last_mv[0][i][1]/2, s->f_code); + mx = ff_h263_decode_motion(s, s->last_mv[0][i][0] , s->f_code); + my = ff_h263_decode_motion(s, s->last_mv[0][i][1]/2, s->f_code); s->last_mv[0][i][0]= s->mv[0][i][0] = mx; s->last_mv[0][i][1]= (s->mv[0][i][1] = my)*2; } @@ -1416,8 +1416,8 @@ static int mpeg4_decode_mb(MpegEncContext *s, s->mv_dir |= MV_DIR_BACKWARD; for(i=0; i<2; i++){ - mx = h263_decode_motion(s, s->last_mv[1][i][0] , s->b_code); - my = h263_decode_motion(s, s->last_mv[1][i][1]/2, s->b_code); + mx = ff_h263_decode_motion(s, s->last_mv[1][i][0] , s->b_code); + my = ff_h263_decode_motion(s, s->last_mv[1][i][1]/2, s->b_code); s->last_mv[1][i][0]= s->mv[1][i][0] = mx; s->last_mv[1][i][1]= (s->mv[1][i][1] = my)*2; } @@ -1429,8 +1429,8 @@ static int mpeg4_decode_mb(MpegEncContext *s, if(IS_SKIP(mb_type)) mx=my=0; else{ - mx = h263_decode_motion(s, 0, 1); - my = h263_decode_motion(s, 0, 1); + mx = ff_h263_decode_motion(s, 0, 1); + my = ff_h263_decode_motion(s, 0, 1); } s->mv_dir = MV_DIR_FORWARD | MV_DIR_BACKWARD | MV_DIRECT; @@ -2056,8 +2056,8 @@ static int decode_vop_header(MpegEncContext *s, GetBitContext *gb){ } if(s->pict_type == AV_PICTURE_TYPE_S && (s->vol_sprite_usage==STATIC_SPRITE || s->vol_sprite_usage==GMC_SPRITE)){ - if(mpeg4_decode_sprite_trajectory(s, gb) < 0) - return -1; + if (mpeg4_decode_sprite_trajectory(s, gb) < 0) + return AVERROR_INVALIDDATA; if(s->sprite_brightness_change) av_log(s->avctx, AV_LOG_ERROR, "sprite_brightness_change not supported\n"); if(s->vol_sprite_usage==STATIC_SPRITE) av_log(s->avctx, AV_LOG_ERROR, "static sprite not supported\n"); } @@ -2237,9 +2237,9 @@ static av_cold int decode_init(AVCodecContext *avctx) if (!done) { done = 1; - init_rl(&ff_mpeg4_rl_intra, ff_mpeg4_static_rl_table_store[0]); - init_rl(&rvlc_rl_inter, ff_mpeg4_static_rl_table_store[1]); - init_rl(&rvlc_rl_intra, ff_mpeg4_static_rl_table_store[2]); + ff_init_rl(&ff_mpeg4_rl_intra, ff_mpeg4_static_rl_table_store[0]); + ff_init_rl(&rvlc_rl_inter, ff_mpeg4_static_rl_table_store[1]); + ff_init_rl(&rvlc_rl_intra, ff_mpeg4_static_rl_table_store[2]); INIT_VLC_RL(ff_mpeg4_rl_intra, 554); INIT_VLC_RL(rvlc_rl_inter, 1072); INIT_VLC_RL(rvlc_rl_intra, 1072); diff --git a/libavcodec/mpeg4videoenc.c b/libavcodec/mpeg4videoenc.c index 02fdf3eaca..2f396364d9 100644 --- a/libavcodec/mpeg4videoenc.c +++ b/libavcodec/mpeg4videoenc.c @@ -705,7 +705,7 @@ void mpeg4_encode_mb(MpegEncContext * s, } /* motion vectors: 16x16 mode */ - h263_pred_motion(s, 0, 0, &pred_x, &pred_y); + ff_h263_pred_motion(s, 0, 0, &pred_x, &pred_y); ff_h263_encode_motion_vector(s, motion_x - pred_x, motion_y - pred_y, s->f_code); @@ -729,7 +729,7 @@ void mpeg4_encode_mb(MpegEncContext * s, } /* motion vectors: 16x8 interlaced mode */ - h263_pred_motion(s, 0, 0, &pred_x, &pred_y); + ff_h263_pred_motion(s, 0, 0, &pred_x, &pred_y); pred_y /=2; put_bits(&s->pb, 1, s->field_select[0][0]); @@ -757,7 +757,7 @@ void mpeg4_encode_mb(MpegEncContext * s, for(i=0; i<4; i++){ /* motion vectors: 8x8 mode*/ - h263_pred_motion(s, i, 0, &pred_x, &pred_y); + ff_h263_pred_motion(s, i, 0, &pred_x, &pred_y); ff_h263_encode_motion_vector(s, s->current_picture.f.motion_val[0][ s->block_index[i] ][0] - pred_x, s->current_picture.f.motion_val[0][ s->block_index[i] ][1] - pred_y, s->f_code); @@ -1240,7 +1240,7 @@ static av_cold int encode_init(AVCodecContext *avctx) init_uni_dc_tab(); - init_rl(&ff_mpeg4_rl_intra, ff_mpeg4_static_rl_table_store[0]); + ff_init_rl(&ff_mpeg4_rl_intra, ff_mpeg4_static_rl_table_store[0]); init_uni_mpeg4_rl_tab(&ff_mpeg4_rl_intra, uni_mpeg4_intra_rl_bits, uni_mpeg4_intra_rl_len); init_uni_mpeg4_rl_tab(&ff_h263_rl_inter, uni_mpeg4_inter_rl_bits, uni_mpeg4_inter_rl_len); diff --git a/libavcodec/mpegaudio_parser.c b/libavcodec/mpegaudio_parser.c index ec7e882c31..283bf04a3d 100644 --- a/libavcodec/mpegaudio_parser.c +++ b/libavcodec/mpegaudio_parser.c @@ -53,6 +53,7 @@ static int mpegaudio_parse(AVCodecParserContext *s1, int inc= FFMIN(buf_size - i, s->frame_size); i += inc; s->frame_size -= inc; + state = 0; if(!s->frame_size){ next= i; diff --git a/libavcodec/mpegaudiodec.c b/libavcodec/mpegaudiodec.c index a6a5d8632b..e4d29019ab 100644 --- a/libavcodec/mpegaudiodec.c +++ b/libavcodec/mpegaudiodec.c @@ -28,6 +28,7 @@ #include "libavutil/audioconvert.h" #include "avcodec.h" +#include "internal.h" #include "get_bits.h" #include "mathops.h" #include "mpegaudiodsp.h" @@ -42,6 +43,7 @@ #define BACKSTEP_SIZE 512 #define EXTRABYTES 24 +#define LAST_BUF_SIZE 2 * BACKSTEP_SIZE + EXTRABYTES /* layer 3 "granule" */ typedef struct GranuleDef { @@ -65,7 +67,7 @@ typedef struct GranuleDef { typedef struct MPADecodeContext { MPA_DECODE_HEADER - uint8_t last_buf[2 * BACKSTEP_SIZE + EXTRABYTES]; + uint8_t last_buf[LAST_BUF_SIZE]; int last_buf_size; /* next header (used in free format parsing) */ uint32_t free_format_next_header; @@ -209,7 +211,7 @@ static void ff_compute_band_indexes(MPADecodeContext *s, GranuleDef *g) else g->long_end = 4; /* 8000 Hz */ - g->short_start = 2 + (s->sample_rate_index != 8); + g->short_start = 3; } else { g->long_end = 0; g->short_start = 0; @@ -1380,18 +1382,18 @@ static int mp_decode_layer3(MPADecodeContext *s) if (!s->adu_mode) { int skip; const uint8_t *ptr = s->gb.buffer + (get_bits_count(&s->gb)>>3); + int extrasize = av_clip(get_bits_left(&s->gb) >> 3, 0, + FFMAX(0, LAST_BUF_SIZE - s->last_buf_size)); assert((get_bits_count(&s->gb) & 7) == 0); /* now we get bits from the main_data_begin offset */ av_dlog(s->avctx, "seekback: %d\n", main_data_begin); //av_log(NULL, AV_LOG_ERROR, "backstep:%d, lastbuf:%d\n", main_data_begin, s->last_buf_size); - if (s->gb.size_in_bits > get_bits_count(&s->gb)) - memcpy(s->last_buf + s->last_buf_size, ptr, - FFMIN(EXTRABYTES, (s->gb.size_in_bits - get_bits_count(&s->gb))>>3)); + memcpy(s->last_buf + s->last_buf_size, ptr, extrasize); s->in_gb = s->gb; init_get_bits(&s->gb, s->last_buf, s->last_buf_size*8); #if !UNCHECKED_BITSTREAM_READER - s->gb.size_in_bits_plus8 += EXTRABYTES * 8; + s->gb.size_in_bits_plus8 += extrasize * 8; #endif skip_bits_long(&s->gb, 8*(s->last_buf_size - main_data_begin)); } @@ -1568,6 +1570,9 @@ static int mp_decode_frame(MPADecodeContext *s, OUT_INT *samples, default: nb_frames = mp_decode_layer3(s); + if (nb_frames < 0) + return nb_frames; + s->last_buf_size=0; if (s->in_gb.buffer) { align_get_bits(&s->gb); @@ -1598,7 +1603,7 @@ static int mp_decode_frame(MPADecodeContext *s, OUT_INT *samples, /* get output buffer */ if (!samples) { s->frame.nb_samples = s->avctx->frame_size; - if ((ret = s->avctx->get_buffer(s->avctx, &s->frame)) < 0) { + if ((ret = ff_get_buffer(s->avctx, &s->frame)) < 0) { av_log(s->avctx, AV_LOG_ERROR, "get_buffer() failed\n"); return ret; } @@ -1629,7 +1634,7 @@ static int decode_frame(AVCodecContext * avctx, void *data, int *got_frame_ptr, int buf_size = avpkt->size; MPADecodeContext *s = avctx->priv_data; uint32_t header; - int out_size; + int ret; if (buf_size < HEADER_SIZE) return AVERROR_INVALIDDATA; @@ -1660,21 +1665,22 @@ static int decode_frame(AVCodecContext * avctx, void *data, int *got_frame_ptr, buf_size= s->frame_size; } - out_size = mp_decode_frame(s, NULL, buf, buf_size); - if (out_size >= 0) { + ret = mp_decode_frame(s, NULL, buf, buf_size); + if (ret >= 0) { *got_frame_ptr = 1; *(AVFrame *)data = s->frame; avctx->sample_rate = s->sample_rate; //FIXME maybe move the other codec info stuff from above here too } else { av_log(avctx, AV_LOG_ERROR, "Error while decoding MPEG audio frame.\n"); - /* Only return an error if the bad frame makes up the whole packet. - If there is more data in the packet, just consume the bad frame - instead of returning an error, which would discard the whole - packet. */ + /* Only return an error if the bad frame makes up the whole packet or + * the error is related to buffer management. + * If there is more data in the packet, just consume the bad frame + * instead of returning an error, which would discard the whole + * packet. */ *got_frame_ptr = 0; - if (buf_size == avpkt->size) - return out_size; + if (buf_size == avpkt->size || ret != AVERROR_INVALIDDATA) + return ret; } s->frame_size = 0; return buf_size; @@ -1695,7 +1701,7 @@ static int decode_frame_adu(AVCodecContext *avctx, void *data, int buf_size = avpkt->size; MPADecodeContext *s = avctx->priv_data; uint32_t header; - int len, out_size; + int len, out_size, ret = 0; len = buf_size; @@ -1732,7 +1738,11 @@ static int decode_frame_adu(AVCodecContext *avctx, void *data, out_size = buf_size; else #endif - out_size = mp_decode_frame(s, NULL, buf, buf_size); + ret = mp_decode_frame(s, NULL, buf, buf_size); + if (ret < 0) { + av_log(avctx, AV_LOG_ERROR, "Error while decoding MPEG audio frame.\n"); + return ret; + } *got_frame_ptr = 1; *(AVFrame *)data = s->frame; @@ -1899,7 +1909,7 @@ static int decode_frame_mp3on4(AVCodecContext *avctx, void *data, /* get output buffer */ s->frame->nb_samples = MPA_FRAME_SIZE; - if ((ret = avctx->get_buffer(avctx, s->frame)) < 0) { + if ((ret = ff_get_buffer(avctx, s->frame)) < 0) { av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n"); return ret; } @@ -1921,6 +1931,10 @@ static int decode_frame_mp3on4(AVCodecContext *avctx, void *data, m = s->mp3decctx[fr]; assert(m != NULL); + if (fsize < HEADER_SIZE) { + av_log(avctx, AV_LOG_ERROR, "Frame size smaller than header size\n"); + return AVERROR_INVALIDDATA; + } header = (AV_RB32(buf) & 0x000fffff) | s->syncword; // patch header if (ff_mpa_check_header(header) < 0) // Bad header, discard block @@ -1928,14 +1942,18 @@ static int decode_frame_mp3on4(AVCodecContext *avctx, void *data, avpriv_mpegaudio_decode_header((MPADecodeHeader *)m, header); - if (ch + m->nb_channels > avctx->channels) { + if (ch + m->nb_channels > avctx->channels || + s->coff[fr] + m->nb_channels > avctx->channels) { av_log(avctx, AV_LOG_ERROR, "frame channel count exceeds codec " "channel count\n"); return AVERROR_INVALIDDATA; } ch += m->nb_channels; - out_size += mp_decode_frame(m, outptr, buf, fsize); + if ((ret = mp_decode_frame(m, outptr, buf, fsize)) < 0) + return ret; + + out_size += ret; buf += fsize; len -= fsize; diff --git a/libavcodec/mpegvideo.c b/libavcodec/mpegvideo.c index 04c149a99b..458d2e447b 100644 --- a/libavcodec/mpegvideo.c +++ b/libavcodec/mpegvideo.c @@ -422,12 +422,12 @@ static int init_duplicate_context(MpegEncContext *s, MpegEncContext *base) // edge emu needs blocksize + filter length - 1 // (= 17x17 for halfpel / 21x21 for h264) FF_ALLOCZ_OR_GOTO(s->avctx, s->edge_emu_buffer, - (s->width + 64) * 2 * 21 * 2, fail); // (width + edge + align)*interlaced*MBsize*tolerance + (s->width + 95) * 2 * 21 * 4, fail); // (width + edge + align)*interlaced*MBsize*tolerance // FIXME should be linesize instead of s->width * 2 // but that is not known before get_buffer() FF_ALLOCZ_OR_GOTO(s->avctx, s->me.scratchpad, - (s->width + 64) * 4 * 16 * 2 * sizeof(uint8_t), fail) + (s->width + 95) * 4 * 16 * 2 * sizeof(uint8_t), fail) s->me.temp = s->me.scratchpad; s->rd_scratchpad = s->me.scratchpad; s->b_scratchpad = s->me.scratchpad; @@ -956,8 +956,8 @@ void MPV_common_end(MpegEncContext *s) avcodec_default_free_buffers(s->avctx); } -void init_rl(RLTable *rl, - uint8_t static_store[2][2 * MAX_RUN + MAX_LEVEL + 3]) +void ff_init_rl(RLTable *rl, + uint8_t static_store[2][2 * MAX_RUN + MAX_LEVEL + 3]) { int8_t max_level[MAX_RUN + 1], max_run[MAX_LEVEL + 1]; uint8_t index_run[MAX_RUN + 1]; @@ -1008,7 +1008,7 @@ void init_rl(RLTable *rl, } } -void init_vlc_rl(RLTable *rl) +void ff_init_vlc_rl(RLTable *rl) { int i, q; @@ -1131,9 +1131,6 @@ int MPV_frame_start(MpegEncContext *s, AVCodecContext *avctx) Picture *pic; s->mb_skipped = 0; - assert(s->last_picture_ptr == NULL || s->out_format != FMT_H264 || - s->codec_id == CODEC_ID_SVQ3); - /* mark & release old frames */ if (s->out_format != FMT_H264 || s->codec_id == CODEC_ID_SVQ3) { if (s->pict_type != AV_PICTURE_TYPE_B && s->last_picture_ptr && @@ -1237,8 +1234,13 @@ int MPV_frame_start(MpegEncContext *s, AVCodecContext *avctx) i = ff_find_unused_picture(s, 0); if (i < 0) return i; - s->last_picture_ptr= &s->picture[i]; + + s->last_picture_ptr = &s->picture[i]; + + s->last_picture_ptr->f.reference = 3; s->last_picture_ptr->f.key_frame = 0; + s->last_picture_ptr->f.pict_type = AV_PICTURE_TYPE_P; + if (ff_alloc_picture(s, s->last_picture_ptr, 0) < 0) return -1; @@ -1259,8 +1261,13 @@ int MPV_frame_start(MpegEncContext *s, AVCodecContext *avctx) i = ff_find_unused_picture(s, 0); if (i < 0) return i; - s->next_picture_ptr= &s->picture[i]; + + s->next_picture_ptr = &s->picture[i]; + + s->next_picture_ptr->f.reference = 3; s->next_picture_ptr->f.key_frame = 0; + s->next_picture_ptr->f.pict_type = AV_PICTURE_TYPE_P; + if (ff_alloc_picture(s, s->next_picture_ptr, 0) < 0) return -1; ff_thread_report_progress((AVFrame *) s->next_picture_ptr, @@ -1394,8 +1401,7 @@ void MPV_frame_end(MpegEncContext *s) s->avctx->coded_frame = (AVFrame *) s->current_picture_ptr; if (s->codec_id != CODEC_ID_H264 && s->current_picture.f.reference) { - ff_thread_report_progress((AVFrame *) s->current_picture_ptr, - s->mb_height - 1, 0); + ff_thread_report_progress((AVFrame *) s->current_picture_ptr, INT_MAX, 0); } } @@ -1430,7 +1436,7 @@ static void draw_line(uint8_t *buf, int sx, int sy, int ex, int ey, y = (x * f) >> 16; fr = (x * f) & 0xFFFF; buf[y * stride + x] += (color * (0x10000 - fr)) >> 16; - buf[(y + 1) * stride + x] += (color * fr ) >> 16; + if(fr) buf[(y + 1) * stride + x] += (color * fr ) >> 16; } } else { if (sy > ey) { @@ -1447,7 +1453,7 @@ static void draw_line(uint8_t *buf, int sx, int sy, int ex, int ey, x = (y*f) >> 16; fr = (y*f) & 0xFFFF; buf[y * stride + x] += (color * (0x10000 - fr)) >> 16; - buf[y * stride + x + 1] += (color * fr ) >> 16; + if(fr) buf[y * stride + x + 1] += (color * fr ) >> 16; } } } @@ -1598,7 +1604,7 @@ void ff_print_debug_info(MpegEncContext *s, AVFrame *pict) int mb_x; for (mb_x = 0; mb_x < s->mb_width; mb_x++) { const int mb_index = mb_x + mb_y * s->mb_stride; - if ((s->avctx->debug_mv) && pict->motion_val) { + if ((s->avctx->debug_mv) && pict->motion_val[0]) { int type; for (type = 0; type < 3; type++) { int direction = 0; @@ -1677,7 +1683,7 @@ void ff_print_debug_info(MpegEncContext *s, AVFrame *pict) } } } - if ((s->avctx->debug & FF_DEBUG_VIS_QP) && pict->motion_val) { + if ((s->avctx->debug & FF_DEBUG_VIS_QP)) { uint64_t c = (pict->qscale_table[mb_index] * 128 / 31) * 0x0101010101010101ULL; int y; @@ -1691,7 +1697,7 @@ void ff_print_debug_info(MpegEncContext *s, AVFrame *pict) } } if ((s->avctx->debug & FF_DEBUG_VIS_MB_TYPE) && - pict->motion_val) { + pict->motion_val[0]) { int mb_type = pict->mb_type[mb_index]; uint64_t u,v; int y; diff --git a/libavcodec/mpegvideo.h b/libavcodec/mpegvideo.h index f7c8fb784e..810367541b 100644 --- a/libavcodec/mpegvideo.h +++ b/libavcodec/mpegvideo.h @@ -686,6 +686,9 @@ typedef struct MpegEncContext { int (*dct_quantize)(struct MpegEncContext *s, DCTELEM *block/*align 16*/, int n, int qscale, int *overflow); int (*fast_dct_quantize)(struct MpegEncContext *s, DCTELEM *block/*align 16*/, int n, int qscale, int *overflow); void (*denoise_dct)(struct MpegEncContext *s, DCTELEM *block); + + uint8_t *pkt_swapped; + int pkt_swapped_allocated; } MpegEncContext; #define REBASE_PICTURE(pic, new_ctx, old_ctx) (pic ? \ diff --git a/libavcodec/mpegvideo_common.h b/libavcodec/mpegvideo_common.h index 2b2e34ffa9..02b2bc1974 100644 --- a/libavcodec/mpegvideo_common.h +++ b/libavcodec/mpegvideo_common.h @@ -244,7 +244,8 @@ void mpeg_motion_internal(MpegEncContext *s, { uint8_t *ptr_y, *ptr_cb, *ptr_cr; int dxy, uvdxy, mx, my, src_x, src_y, - uvsrc_x, uvsrc_y, v_edge_pos, uvlinesize, linesize; + uvsrc_x, uvsrc_y, v_edge_pos; + emuedge_linesize_type uvlinesize, linesize; #if 0 if(s->quarter_sample) @@ -725,7 +726,8 @@ static av_always_inline void MPV_motion_internal(MpegEncContext *s, 0, 0, 0, ref_picture, pix_op, qpix_op, s->mv[dir][0][0], s->mv[dir][0][1], 16); - }else if(!is_mpeg12 && (CONFIG_WMV2_DECODER || CONFIG_WMV2_ENCODER) && s->mspel && s->codec_id == CODEC_ID_WMV2){ + } else if (!is_mpeg12 && (CONFIG_WMV2_DECODER || CONFIG_WMV2_ENCODER) && + s->mspel && s->codec_id == CODEC_ID_WMV2) { ff_mspel_motion(s, dest_y, dest_cb, dest_cr, ref_picture, pix_op, s->mv[dir][0][0], s->mv[dir][0][1], 16); diff --git a/libavcodec/mpegvideo_enc.c b/libavcodec/mpegvideo_enc.c index fd31edc481..e289663ee7 100644 --- a/libavcodec/mpegvideo_enc.c +++ b/libavcodec/mpegvideo_enc.c @@ -595,7 +595,7 @@ av_cold int MPV_encode_init(AVCodecContext *avctx) return -1; } - if (s->avctx->thread_count > 1) + if (s->avctx->slices > 1 || s->avctx->thread_count > 1) s->rtp_mode = 1; if (!avctx->time_base.den || !avctx->time_base.num) { @@ -712,7 +712,7 @@ av_cold int MPV_encode_init(AVCodecContext *avctx) case CODEC_ID_H263: if (!CONFIG_H263_ENCODER) return -1; - if (ff_match_2uint16(h263_format, FF_ARRAY_ELEMS(h263_format), + if (ff_match_2uint16(ff_h263_format, FF_ARRAY_ELEMS(ff_h263_format), s->width, s->height) == 8) { av_log(avctx, AV_LOG_ERROR, "The specified picture size of %dx%d is not valid for " @@ -848,7 +848,7 @@ av_cold int MPV_encode_init(AVCodecContext *avctx) if (CONFIG_H261_ENCODER && s->out_format == FMT_H261) ff_h261_encode_init(s); if (CONFIG_H263_ENCODER && s->out_format == FMT_H263) - h263_encode_init(s); + ff_h263_encode_init(s); if (CONFIG_MSMPEG4_ENCODER && s->msmpeg4_version) ff_msmpeg4_encode_init(s); if ((CONFIG_MPEG1VIDEO_ENCODER || CONFIG_MPEG2VIDEO_ENCODER) @@ -2086,7 +2086,7 @@ static av_always_inline void encode_mb_internal(MpegEncContext *s, case CODEC_ID_RV10: case CODEC_ID_RV20: if (CONFIG_H263_ENCODER) - h263_encode_mb(s, s->block, motion_x, motion_y); + ff_h263_encode_mb(s, s->block, motion_x, motion_y); break; case CODEC_ID_MJPEG: case CODEC_ID_AMV: @@ -2522,7 +2522,7 @@ static int encode_thread(AVCodecContext *c, void *arg){ case CODEC_ID_H263: case CODEC_ID_H263P: if (CONFIG_H263_ENCODER) - h263_encode_gob_header(s, mb_y); + ff_h263_encode_gob_header(s, mb_y); break; } @@ -3298,7 +3298,7 @@ static int encode_picture(MpegEncContext *s, int picture_number) else if (CONFIG_FLV_ENCODER && s->codec_id == CODEC_ID_FLV1) ff_flv_encode_picture_header(s, picture_number); else if (CONFIG_H263_ENCODER) - h263_encode_picture_header(s, picture_number); + ff_h263_encode_picture_header(s, picture_number); break; case FMT_MPEG1: if (CONFIG_MPEG1VIDEO_ENCODER || CONFIG_MPEG2VIDEO_ENCODER) diff --git a/libavcodec/msmpeg4.c b/libavcodec/msmpeg4.c index d37cac9862..02fcab5cba 100644 --- a/libavcodec/msmpeg4.c +++ b/libavcodec/msmpeg4.c @@ -262,7 +262,7 @@ av_cold void ff_msmpeg4_encode_init(MpegEncContext *s) init_mv_table(&mv_tables[0]); init_mv_table(&mv_tables[1]); for(i=0;ipb, mvtab[code][1], mvtab[code][0]); + put_bits(&s->pb, ff_mvtab[code][1], ff_mvtab[code][0]); } else { bit_size = s->f_code - 1; range = 1 << bit_size; @@ -526,7 +526,7 @@ static void msmpeg4v2_encode_motion(MpegEncContext * s, int val) code = (val >> bit_size) + 1; bits = val & (range - 1); - put_bits(&s->pb, mvtab[code][1] + 1, (mvtab[code][0] << 1) | sign); + put_bits(&s->pb, ff_mvtab[code][1] + 1, (ff_mvtab[code][0] << 1) | sign); if (bit_size > 0) { put_bits(&s->pb, bit_size, bits); } @@ -575,7 +575,7 @@ void msmpeg4_encode_mb(MpegEncContext * s, s->misc_bits += get_bits_diff(s); - h263_pred_motion(s, 0, 0, &pred_x, &pred_y); + ff_h263_pred_motion(s, 0, 0, &pred_x, &pred_y); msmpeg4v2_encode_motion(s, motion_x - pred_x); msmpeg4v2_encode_motion(s, motion_y - pred_y); }else{ @@ -586,7 +586,7 @@ void msmpeg4_encode_mb(MpegEncContext * s, s->misc_bits += get_bits_diff(s); /* motion vector */ - h263_pred_motion(s, 0, 0, &pred_x, &pred_y); + ff_h263_pred_motion(s, 0, 0, &pred_x, &pred_y); ff_msmpeg4_encode_motion(s, motion_x - pred_x, motion_y - pred_y); } @@ -1134,7 +1134,7 @@ static int msmpeg4v12_decode_mb(MpegEncContext *s, DCTELEM block[6][64]) cbp|= cbpy<<2; if(s->msmpeg4_version==1 || (cbp&3) != 3) cbp^= 0x3C; - h263_pred_motion(s, 0, 0, &mx, &my); + ff_h263_pred_motion(s, 0, 0, &mx, &my); mx= msmpeg4v2_decode_motion(s, mx, 1); my= msmpeg4v2_decode_motion(s, my, 1); @@ -1220,7 +1220,7 @@ static int msmpeg4v34_decode_mb(MpegEncContext *s, DCTELEM block[6][64]) s->rl_table_index = decode012(&s->gb); s->rl_chroma_table_index = s->rl_table_index; } - h263_pred_motion(s, 0, 0, &mx, &my); + ff_h263_pred_motion(s, 0, 0, &mx, &my); if (ff_msmpeg4_decode_motion(s, &mx, &my) < 0) return -1; s->mv_dir = MV_DIR_FORWARD; @@ -1271,7 +1271,7 @@ av_cold int ff_msmpeg4_decode_init(AVCodecContext *avctx) done = 1; for(i=0;iheight * istride == avpkt->size) { /* assume uncompressed */ - int linesize = (avctx->width * avctx->bits_per_coded_sample + 7) / 8; + int linesize = av_image_get_linesize(avctx->pix_fmt, avctx->width, 0); uint8_t *ptr = s->frame.data[0]; uint8_t *buf = avpkt->data + (avctx->height-1)*istride; int i, j; @@ -127,7 +129,8 @@ static int msrle_decode_frame(AVCodecContext *avctx, ptr += s->frame.linesize[0]; } } else { - ff_msrle_decode(avctx, (AVPicture*)&s->frame, avctx->bits_per_coded_sample, buf, buf_size); + bytestream2_init(&s->gb, buf, buf_size); + ff_msrle_decode(avctx, (AVPicture*)&s->frame, avctx->bits_per_coded_sample, &s->gb); } *data_size = sizeof(AVFrame); diff --git a/libavcodec/msrledec.c b/libavcodec/msrledec.c index 129f0e0bc0..a6cf22faa1 100644 --- a/libavcodec/msrledec.c +++ b/libavcodec/msrledec.c @@ -30,18 +30,9 @@ #include "avcodec.h" #include "msrledec.h" -#define FETCH_NEXT_STREAM_BYTE() \ - if (stream_ptr >= data_size) \ - { \ - av_log(avctx, AV_LOG_ERROR, " MS RLE: stream ptr just went out of bounds (1)\n"); \ - return -1; \ - } \ - stream_byte = data[stream_ptr++]; - static int msrle_decode_pal4(AVCodecContext *avctx, AVPicture *pic, - const uint8_t *data, int data_size) + GetByteContext *gb) { - int stream_ptr = 0; unsigned char rle_code; unsigned char extra_byte, odd_pixel; unsigned char stream_byte; @@ -52,11 +43,16 @@ static int msrle_decode_pal4(AVCodecContext *avctx, AVPicture *pic, int i; while (row_ptr >= 0) { - FETCH_NEXT_STREAM_BYTE(); - rle_code = stream_byte; + if (bytestream2_get_bytes_left(gb) <= 0) { + av_log(avctx, AV_LOG_ERROR, + "MS RLE: bytestream overrun, %d rows left\n", + row_ptr); + return AVERROR_INVALIDDATA; + } + rle_code = stream_byte = bytestream2_get_byteu(gb); if (rle_code == 0) { /* fetch the next byte to see how to handle escape code */ - FETCH_NEXT_STREAM_BYTE(); + stream_byte = bytestream2_get_byte(gb); if (stream_byte == 0) { /* line is done, goto the next one */ row_ptr -= row_dec; @@ -66,24 +62,26 @@ static int msrle_decode_pal4(AVCodecContext *avctx, AVPicture *pic, return 0; } else if (stream_byte == 2) { /* reposition frame decode coordinates */ - FETCH_NEXT_STREAM_BYTE(); + stream_byte = bytestream2_get_byte(gb); pixel_ptr += stream_byte; - FETCH_NEXT_STREAM_BYTE(); + stream_byte = bytestream2_get_byte(gb); row_ptr -= stream_byte * row_dec; } else { // copy pixels from encoded stream odd_pixel = stream_byte & 1; rle_code = (stream_byte + 1) / 2; extra_byte = rle_code & 0x01; - if (row_ptr + pixel_ptr + stream_byte > frame_size) { - av_log(avctx, AV_LOG_ERROR, " MS RLE: frame ptr just went out of bounds (1)\n"); - return -1; + if (row_ptr + pixel_ptr + stream_byte > frame_size || + bytestream2_get_bytes_left(gb) < rle_code) { + av_log(avctx, AV_LOG_ERROR, + "MS RLE: frame/stream ptr just went out of bounds (copy)\n"); + return AVERROR_INVALIDDATA; } for (i = 0; i < rle_code; i++) { if (pixel_ptr >= avctx->width) break; - FETCH_NEXT_STREAM_BYTE(); + stream_byte = bytestream2_get_byteu(gb); pic->data[0][row_ptr + pixel_ptr] = stream_byte >> 4; pixel_ptr++; if (i + 1 == rle_code && odd_pixel) @@ -96,15 +94,16 @@ static int msrle_decode_pal4(AVCodecContext *avctx, AVPicture *pic, // if the RLE code is odd, skip a byte in the stream if (extra_byte) - stream_ptr++; + bytestream2_skip(gb, 1); } } else { // decode a run of data if (row_ptr + pixel_ptr + stream_byte > frame_size) { - av_log(avctx, AV_LOG_ERROR, " MS RLE: frame ptr just went out of bounds (1)\n"); - return -1; + av_log(avctx, AV_LOG_ERROR, + "MS RLE: frame ptr just went out of bounds (run)\n"); + return AVERROR_INVALIDDATA; } - FETCH_NEXT_STREAM_BYTE(); + stream_byte = bytestream2_get_byte(gb); for (i = 0; i < rle_code; i++) { if (pixel_ptr >= avctx->width) break; @@ -118,21 +117,21 @@ static int msrle_decode_pal4(AVCodecContext *avctx, AVPicture *pic, } /* one last sanity check on the way out */ - if (stream_ptr < data_size) { - av_log(avctx, AV_LOG_ERROR, " MS RLE: ended frame decode with bytes left over (%d < %d)\n", - stream_ptr, data_size); - return -1; + if (bytestream2_get_bytes_left(gb)) { + av_log(avctx, AV_LOG_ERROR, + "MS RLE: ended frame decode with %d bytes left over\n", + bytestream2_get_bytes_left(gb)); + return AVERROR_INVALIDDATA; } return 0; } -static int msrle_decode_8_16_24_32(AVCodecContext *avctx, AVPicture *pic, int depth, - const uint8_t *data, int srcsize) +static int msrle_decode_8_16_24_32(AVCodecContext *avctx, AVPicture *pic, + int depth, GetByteContext *gb) { uint8_t *output, *output_end; - const uint8_t* src = data; int p1, p2, line=avctx->height - 1, pos=0, i; uint16_t av_uninit(pix16); uint32_t av_uninit(pix32); @@ -140,23 +139,30 @@ static int msrle_decode_8_16_24_32(AVCodecContext *avctx, AVPicture *pic, int de output = pic->data[0] + (avctx->height - 1) * pic->linesize[0]; output_end = pic->data[0] + avctx->height * pic->linesize[0]; - while(src + 1 < data + srcsize) { - p1 = *src++; + + while (bytestream2_get_bytes_left(gb) > 0) { + p1 = bytestream2_get_byteu(gb); if(p1 == 0) { //Escape code - p2 = *src++; + p2 = bytestream2_get_byte(gb); if(p2 == 0) { //End-of-line - output = pic->data[0] + (--line) * pic->linesize[0]; - if (line < 0 && !(src+1 < data + srcsize && AV_RB16(src) == 1)) { - av_log(avctx, AV_LOG_ERROR, "Next line is beyond picture bounds\n"); - return -1; + if (--line < 0) { + if (bytestream2_get_be16(gb) == 1) { // end-of-picture + return 0; + } else { + av_log(avctx, AV_LOG_ERROR, + "Next line is beyond picture bounds (%d bytes left)\n", + bytestream2_get_bytes_left(gb)); + return AVERROR_INVALIDDATA; + } } + output = pic->data[0] + line * pic->linesize[0]; pos = 0; continue; } else if(p2 == 1) { //End-of-picture return 0; } else if(p2 == 2) { //Skip - p1 = *src++; - p2 = *src++; + p1 = bytestream2_get_byte(gb); + p2 = bytestream2_get_byte(gb); line -= p2; pos += p1; if (line < 0 || pos >= width){ @@ -167,35 +173,31 @@ static int msrle_decode_8_16_24_32(AVCodecContext *avctx, AVPicture *pic, int de continue; } // Copy data - if ((pic->linesize[0] > 0 && output + p2 * (depth >> 3) > output_end) - ||(pic->linesize[0] < 0 && output + p2 * (depth >> 3) < output_end)) { - src += p2 * (depth >> 3); + if ((pic->linesize[0] > 0 && output + p2 * (depth >> 3) > output_end) || + (pic->linesize[0] < 0 && output + p2 * (depth >> 3) < output_end)) { + bytestream2_skip(gb, 2 * (depth >> 3)); continue; + } else if (bytestream2_get_bytes_left(gb) < p2 * (depth >> 3)) { + av_log(avctx, AV_LOG_ERROR, "bytestream overrun\n"); + return AVERROR_INVALIDDATA; } - if(data + srcsize - src < p2 * (depth >> 3)){ - av_log(avctx, AV_LOG_ERROR, "Copy beyond input buffer\n"); - return -1; - } + if ((depth == 8) || (depth == 24)) { for(i = 0; i < p2 * (depth >> 3); i++) { - *output++ = *src++; + *output++ = bytestream2_get_byteu(gb); } // RLE8 copy is actually padded - and runs are not! if(depth == 8 && (p2 & 1)) { - src++; + bytestream2_skip(gb, 1); } } else if (depth == 16) { for(i = 0; i < p2; i++) { - pix16 = AV_RL16(src); - src += 2; - *(uint16_t*)output = pix16; + *(uint16_t*)output = bytestream2_get_le16u(gb); output += 2; } } else if (depth == 32) { for(i = 0; i < p2; i++) { - pix32 = AV_RL32(src); - src += 4; - *(uint32_t*)output = pix32; + *(uint32_t*)output = bytestream2_get_le32u(gb); output += 4; } } @@ -203,21 +205,19 @@ static int msrle_decode_8_16_24_32(AVCodecContext *avctx, AVPicture *pic, int de } else { //run of pixels uint8_t pix[3]; //original pixel switch(depth){ - case 8: pix[0] = *src++; + case 8: pix[0] = bytestream2_get_byte(gb); break; - case 16: pix16 = AV_RL16(src); - src += 2; + case 16: pix16 = bytestream2_get_le16(gb); break; - case 24: pix[0] = *src++; - pix[1] = *src++; - pix[2] = *src++; + case 24: pix[0] = bytestream2_get_byte(gb); + pix[1] = bytestream2_get_byte(gb); + pix[2] = bytestream2_get_byte(gb); break; - case 32: pix32 = AV_RL32(src); - src += 4; + case 32: pix32 = bytestream2_get_le32(gb); break; } - if ((pic->linesize[0] > 0 && output + p1 * (depth >> 3) > output_end) - ||(pic->linesize[0] < 0 && output + p1 * (depth >> 3) < output_end)) + if ((pic->linesize[0] > 0 && output + p1 * (depth >> 3) > output_end) || + (pic->linesize[0] < 0 && output + p1 * (depth >> 3) < output_end)) continue; for(i = 0; i < p1; i++) { switch(depth){ @@ -244,17 +244,17 @@ static int msrle_decode_8_16_24_32(AVCodecContext *avctx, AVPicture *pic, int de } -int ff_msrle_decode(AVCodecContext *avctx, AVPicture *pic, int depth, - const uint8_t* data, int data_size) +int ff_msrle_decode(AVCodecContext *avctx, AVPicture *pic, + int depth, GetByteContext *gb) { switch(depth){ case 4: - return msrle_decode_pal4(avctx, pic, data, data_size); + return msrle_decode_pal4(avctx, pic, gb); case 8: case 16: case 24: case 32: - return msrle_decode_8_16_24_32(avctx, pic, depth, data, data_size); + return msrle_decode_8_16_24_32(avctx, pic, depth, gb); default: av_log(avctx, AV_LOG_ERROR, "Unknown depth %d\n", depth); return -1; diff --git a/libavcodec/msrledec.h b/libavcodec/msrledec.h index 2230162691..84278129f5 100644 --- a/libavcodec/msrledec.h +++ b/libavcodec/msrledec.h @@ -23,6 +23,7 @@ #define AVCODEC_MSRLEDEC_H #include "avcodec.h" +#include "bytestream.h" /** * Decode stream in MS RLE format into frame. @@ -30,11 +31,10 @@ * @param avctx codec context * @param pic destination frame * @param depth bit depth - * @param data input stream - * @param data_size input size + * @param gb input bytestream context */ -int ff_msrle_decode(AVCodecContext *avctx, AVPicture *pic, int depth, - const uint8_t* data, int data_size); +int ff_msrle_decode(AVCodecContext *avctx, AVPicture *pic, + int depth, GetByteContext *gb); #endif /* AVCODEC_MSRLEDEC_H */ diff --git a/libavcodec/mxpegdec.c b/libavcodec/mxpegdec.c index 9f9212ce9b..5c09780112 100644 --- a/libavcodec/mxpegdec.c +++ b/libavcodec/mxpegdec.c @@ -25,8 +25,10 @@ * MxPEG decoder */ +#include "internal.h" #include "mjpeg.h" #include "mjpegdec.h" +#include "internal.h" typedef struct MXpegDecodeContext { MJpegDecodeContext jpg; @@ -250,7 +252,7 @@ static int mxpeg_decode_frame(AVCodecContext *avctx, /* use stored SOF data to allocate current picture */ if (jpg->picture_ptr->data[0]) avctx->release_buffer(avctx, jpg->picture_ptr); - if (avctx->get_buffer(avctx, jpg->picture_ptr) < 0) { + if (ff_get_buffer(avctx, jpg->picture_ptr) < 0) { av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n"); return AVERROR(ENOMEM); } @@ -269,7 +271,7 @@ static int mxpeg_decode_frame(AVCodecContext *avctx, /* allocate dummy reference picture if needed */ if (!reference_ptr->data[0] && - avctx->get_buffer(avctx, reference_ptr) < 0) { + ff_get_buffer(avctx, reference_ptr) < 0) { av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n"); return AVERROR(ENOMEM); } diff --git a/libavcodec/nellymoserdec.c b/libavcodec/nellymoserdec.c index 2a1ec5b4cd..74987e6b0f 100644 --- a/libavcodec/nellymoserdec.c +++ b/libavcodec/nellymoserdec.c @@ -36,6 +36,7 @@ #include "libavutil/random_seed.h" #include "libavutil/audioconvert.h" #include "avcodec.h" +#include "internal.h" #include "dsputil.h" #include "fft.h" #include "fmtconvert.h" @@ -184,7 +185,7 @@ static int decode_tag(AVCodecContext *avctx, void *data, /* get output buffer */ s->frame.nb_samples = NELLY_SAMPLES * blocks; - if ((ret = avctx->get_buffer(avctx, &s->frame)) < 0) { + if ((ret = ff_get_buffer(avctx, &s->frame)) < 0) { av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n"); return ret; } diff --git a/libavcodec/nellymoserenc.c b/libavcodec/nellymoserenc.c index 725270c9fa..54820ad315 100644 --- a/libavcodec/nellymoserenc.c +++ b/libavcodec/nellymoserenc.c @@ -288,7 +288,7 @@ static void encode_block(NellyMoserEncodeContext *s, unsigned char *output, int apply_mdct(s); - init_put_bits(&pb, output, output_size * 8); + init_put_bits(&pb, output, output_size); i = 0; for (band = 0; band < NELLY_BANDS; band++) { diff --git a/libavcodec/noise_bsf.c b/libavcodec/noise_bsf.c index 491fbccc1d..18a7f30886 100644 --- a/libavcodec/noise_bsf.c +++ b/libavcodec/noise_bsf.c @@ -28,6 +28,9 @@ static int noise(AVBitStreamFilterContext *bsfc, AVCodecContext *avctx, const ch int amount= args ? atoi(args) : (*state % 10001+1); int i; + if(amount <= 0) + return AVERROR(EINVAL); + *poutbuf= av_malloc(buf_size + FF_INPUT_BUFFER_PADDING_SIZE); memcpy(*poutbuf, buf, buf_size + FF_INPUT_BUFFER_PADDING_SIZE); diff --git a/libavcodec/nuv.c b/libavcodec/nuv.c index 7f8dc7501b..f1ef1fa540 100644 --- a/libavcodec/nuv.c +++ b/libavcodec/nuv.c @@ -85,7 +85,7 @@ static int get_quant(AVCodecContext *avctx, NuvContext *c, int i; if (size < 2 * 64 * 4) { av_log(avctx, AV_LOG_ERROR, "insufficient rtjpeg quant data\n"); - return -1; + return AVERROR_INVALIDDATA; } for (i = 0; i < 64; i++, buf += 4) c->lq[i] = AV_RL32(buf); @@ -108,6 +108,8 @@ static void get_quant_quality(NuvContext *c, int quality) { static int codec_reinit(AVCodecContext *avctx, int width, int height, int quality) { NuvContext *c = avctx->priv_data; + int ret; + width = FFALIGN(width, 2); height = FFALIGN(height, 2); if (quality >= 0) @@ -115,12 +117,14 @@ static int codec_reinit(AVCodecContext *avctx, int width, int height, int qualit if (width != c->width || height != c->height) { // also reserve space for a possible additional header int buf_size = 24 + height * width * 3 / 2 + AV_LZO_OUTPUT_PADDING; - if (av_image_check_size(height, width, 0, avctx) < 0 || - buf_size > INT_MAX/8) + if (buf_size > INT_MAX/8) return -1; + if ((ret = av_image_check_size(height, width, 0, avctx)) < 0) + return ret; avctx->width = c->width = width; avctx->height = c->height = height; - av_fast_malloc(&c->decomp_buf, &c->decomp_size, buf_size); + av_fast_malloc(&c->decomp_buf, &c->decomp_size, + buf_size); if (!c->decomp_buf) { av_log(avctx, AV_LOG_ERROR, "Can't allocate decompression buffer.\n"); return AVERROR(ENOMEM); @@ -142,13 +146,14 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *data_size, int keyframe; int size_change = 0; int result; + int ret; enum {NUV_UNCOMPRESSED = '0', NUV_RTJPEG = '1', NUV_RTJPEG_IN_LZO = '2', NUV_LZO = '3', NUV_BLACK = 'N', NUV_COPY_LAST = 'L'} comptype; if (buf_size < 12) { av_log(avctx, AV_LOG_ERROR, "coded frame too small\n"); - return -1; + return AVERROR_INVALIDDATA; } // codec data (rtjpeg quant tables) @@ -166,7 +171,7 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *data_size, if (buf[0] != 'V' || buf_size < 12) { av_log(avctx, AV_LOG_ERROR, "not a nuv video frame\n"); - return -1; + return AVERROR_INVALIDDATA; } comptype = buf[1]; switch (comptype) { @@ -183,32 +188,36 @@ retry: buf = &buf[12]; buf_size -= 12; if (comptype == NUV_RTJPEG_IN_LZO || comptype == NUV_LZO) { - int outlen = c->decomp_size - AV_LZO_OUTPUT_PADDING, inlen = buf_size; - if (av_lzo1x_decode(c->decomp_buf, &outlen, buf, &inlen)) + int outlen = c->decomp_size - FFMAX(FF_INPUT_BUFFER_PADDING_SIZE, AV_LZO_OUTPUT_PADDING); + int inlen = buf_size; + if (av_lzo1x_decode(c->decomp_buf, &outlen, buf, &inlen)) { av_log(avctx, AV_LOG_ERROR, "error during lzo decompression\n"); + return AVERROR_INVALIDDATA; + } buf = c->decomp_buf; - buf_size = c->decomp_size - AV_LZO_OUTPUT_PADDING - outlen; + buf_size = c->decomp_size - FFMAX(FF_INPUT_BUFFER_PADDING_SIZE, AV_LZO_OUTPUT_PADDING) - outlen; } if (c->codec_frameheader) { - int w, h, q, res; - if (buf[0] != 'V' || buf_size < 12) { - av_log(avctx, AV_LOG_ERROR, "invalid nuv video frame (wrong codec_tag?)\n"); + int w, h, q; + if (buf_size < RTJPEG_HEADER_SIZE || buf[4] != RTJPEG_HEADER_SIZE || + buf[5] != RTJPEG_FILE_VERSION) { + av_log(avctx, AV_LOG_ERROR, "invalid nuv video frame\n"); return AVERROR_INVALIDDATA; } w = AV_RL16(&buf[6]); h = AV_RL16(&buf[8]); q = buf[10]; - res = codec_reinit(avctx, w, h, q); - if (res < 0) - return res; - if (res) { + if ((result = codec_reinit(avctx, w, h, q)) < 0) + return result; + + if (result) { buf = avpkt->data; buf_size = avpkt->size; size_change = 1; goto retry; } - buf = &buf[12]; - buf_size -= 12; + buf = &buf[RTJPEG_HEADER_SIZE]; + buf_size -= RTJPEG_HEADER_SIZE; } if ((size_change || keyframe) && c->pic.data[0]) @@ -219,7 +228,7 @@ retry: result = avctx->reget_buffer(avctx, &c->pic); if (result < 0) { av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n"); - return -1; + return result; } c->pic.pict_type = keyframe ? AV_PICTURE_TYPE_I : AV_PICTURE_TYPE_P; @@ -238,7 +247,9 @@ retry: } case NUV_RTJPEG_IN_LZO: case NUV_RTJPEG: { - rtjpeg_decode_frame_yuv420(&c->rtj, &c->pic, buf, buf_size); + ret = rtjpeg_decode_frame_yuv420(&c->rtj, &c->pic, buf, buf_size); + if (ret < 0) + return ret; break; } case NUV_BLACK: { @@ -253,7 +264,7 @@ retry: } default: av_log(avctx, AV_LOG_ERROR, "unknown compression\n"); - return -1; + return AVERROR_INVALIDDATA; } *picture = c->pic; @@ -263,6 +274,8 @@ retry: static av_cold int decode_init(AVCodecContext *avctx) { NuvContext *c = avctx->priv_data; + int ret; + avctx->pix_fmt = PIX_FMT_YUV420P; c->pic.data[0] = NULL; c->decomp_buf = NULL; @@ -273,8 +286,9 @@ static av_cold int decode_init(AVCodecContext *avctx) { if (avctx->extradata_size) get_quant(avctx, c, avctx->extradata, avctx->extradata_size); dsputil_init(&c->dsp, avctx); - if (codec_reinit(avctx, avctx->width, avctx->height, -1) < 0) - return 1; + if ((ret = codec_reinit(avctx, avctx->width, avctx->height, -1)) < 0) + return ret; + return 0; } diff --git a/libavcodec/options.c b/libavcodec/options.c index 6b012963de..fb1ada9cc7 100644 --- a/libavcodec/options.c +++ b/libavcodec/options.c @@ -223,15 +223,13 @@ static const AVOption options[]={ {"parse_only", NULL, OFFSET(parse_only), AV_OPT_TYPE_INT, {.dbl = DEFAULT }, INT_MIN, INT_MAX}, #endif {"mpeg_quant", "use MPEG quantizers instead of H.263", OFFSET(mpeg_quant), AV_OPT_TYPE_INT, {.dbl = DEFAULT }, INT_MIN, INT_MAX, V|E}, -{"stats_out", NULL, OFFSET(stats_out), AV_OPT_TYPE_STRING, {.str = NULL}, CHAR_MIN, CHAR_MAX}, -{"stats_in", NULL, OFFSET(stats_in), AV_OPT_TYPE_STRING, {.str = NULL}, CHAR_MIN, CHAR_MAX}, {"qsquish", "how to keep quantizer between qmin and qmax (0 = clip, 1 = use differentiable function)", OFFSET(rc_qsquish), AV_OPT_TYPE_FLOAT, {.dbl = DEFAULT }, 0, 99, V|E}, {"rc_qmod_amp", "experimental quantizer modulation", OFFSET(rc_qmod_amp), AV_OPT_TYPE_FLOAT, {.dbl = DEFAULT }, -FLT_MAX, FLT_MAX, V|E}, {"rc_qmod_freq", "experimental quantizer modulation", OFFSET(rc_qmod_freq), AV_OPT_TYPE_INT, {.dbl = DEFAULT }, INT_MIN, INT_MAX, V|E}, {"rc_override_count", NULL, OFFSET(rc_override_count), AV_OPT_TYPE_INT, {.dbl = DEFAULT }, INT_MIN, INT_MAX}, {"rc_eq", "set rate control equation", OFFSET(rc_eq), AV_OPT_TYPE_STRING, {.str = NULL}, CHAR_MIN, CHAR_MAX, V|E}, -{"maxrate", "set max video bitrate tolerance (in bits/s)", OFFSET(rc_max_rate), AV_OPT_TYPE_INT, {.dbl = DEFAULT }, INT_MIN, INT_MAX, V|E}, -{"minrate", "set min video bitrate tolerance (in bits/s)", OFFSET(rc_min_rate), AV_OPT_TYPE_INT, {.dbl = DEFAULT }, INT_MIN, INT_MAX, V|E}, +{"maxrate", "set max bitrate tolerance (in bits/s)", OFFSET(rc_max_rate), AV_OPT_TYPE_INT, {.dbl = DEFAULT }, INT_MIN, INT_MAX, V|A|E}, +{"minrate", "set min bitrate tolerance (in bits/s)", OFFSET(rc_min_rate), AV_OPT_TYPE_INT, {.dbl = DEFAULT }, INT_MIN, INT_MAX, V|A|E}, {"bufsize", "set ratecontrol buffer size (in bits)", OFFSET(rc_buffer_size), AV_OPT_TYPE_INT, {.dbl = DEFAULT }, INT_MIN, INT_MAX, A|V|E}, {"rc_buf_aggressivity", "currently useless", OFFSET(rc_buffer_aggressivity), AV_OPT_TYPE_FLOAT, {.dbl = 1.0 }, -FLT_MAX, FLT_MAX, V|E}, {"i_qfactor", "qp factor between P and I frames", OFFSET(i_quant_factor), AV_OPT_TYPE_FLOAT, {.dbl = -0.8 }, -FLT_MAX, FLT_MAX, V|E}, @@ -647,7 +645,7 @@ AVCodecContext *avcodec_alloc_context(void){ int avcodec_copy_context(AVCodecContext *dest, const AVCodecContext *src) { - if (dest->codec) { // check that the dest context is uninitialized + if (avcodec_is_open(dest)) { // check that the dest context is uninitialized av_log(dest, AV_LOG_ERROR, "Tried to copy AVCodecContext %p into already-initialized %p\n", src, dest); diff --git a/libavcodec/parser.c b/libavcodec/parser.c index d83d4c3d11..66eca06428 100644 --- a/libavcodec/parser.c +++ b/libavcodec/parser.c @@ -241,8 +241,10 @@ int ff_combine_frame(ParseContext *pc, int next, const uint8_t **buf, int *buf_s if(next == END_NOT_FOUND){ void* new_buffer = av_fast_realloc(pc->buffer, &pc->buffer_size, (*buf_size) + pc->index + FF_INPUT_BUFFER_PADDING_SIZE); - if(!new_buffer) + if(!new_buffer) { + pc->index = 0; return AVERROR(ENOMEM); + } pc->buffer = new_buffer; memcpy(&pc->buffer[pc->index], *buf, *buf_size); pc->index += *buf_size; @@ -255,11 +257,15 @@ int ff_combine_frame(ParseContext *pc, int next, const uint8_t **buf, int *buf_s /* append to buffer */ if(pc->index){ void* new_buffer = av_fast_realloc(pc->buffer, &pc->buffer_size, next + pc->index + FF_INPUT_BUFFER_PADDING_SIZE); - - if(!new_buffer) + if(!new_buffer) { + pc->overread_index = + pc->index = 0; return AVERROR(ENOMEM); + } pc->buffer = new_buffer; - memcpy(&pc->buffer[pc->index], *buf, next + FF_INPUT_BUFFER_PADDING_SIZE ); + if (next > -FF_INPUT_BUFFER_PADDING_SIZE) + memcpy(&pc->buffer[pc->index], *buf, + next + FF_INPUT_BUFFER_PADDING_SIZE); pc->index = 0; *buf= pc->buffer; } diff --git a/libavcodec/pcm-mpeg.c b/libavcodec/pcm-mpeg.c index b9417733ca..cf08373ce1 100644 --- a/libavcodec/pcm-mpeg.c +++ b/libavcodec/pcm-mpeg.c @@ -26,6 +26,7 @@ #include "libavutil/audioconvert.h" #include "avcodec.h" +#include "internal.h" #include "bytestream.h" /* @@ -158,12 +159,12 @@ static int pcm_bluray_decode_frame(AVCodecContext *avctx, void *data, /* There's always an even number of channels in the source */ num_source_channels = FFALIGN(avctx->channels, 2); - sample_size = (num_source_channels * avctx->bits_per_coded_sample) >> 3; + sample_size = (num_source_channels * (avctx->sample_fmt == AV_SAMPLE_FMT_S16 ? 16 : 24)) >> 3; samples = buf_size / sample_size; /* get output buffer */ s->frame.nb_samples = samples; - if ((retval = avctx->get_buffer(avctx, &s->frame)) < 0) { + if ((retval = ff_get_buffer(avctx, &s->frame)) < 0) { av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n"); return retval; } diff --git a/libavcodec/pcm.c b/libavcodec/pcm.c index 650003793c..818a635d22 100644 --- a/libavcodec/pcm.c +++ b/libavcodec/pcm.c @@ -48,6 +48,7 @@ static av_cold int pcm_encode_init(AVCodecContext *avctx) avctx->bits_per_coded_sample = av_get_bits_per_sample(avctx->codec->id); avctx->block_align = avctx->channels * avctx->bits_per_coded_sample/8; + avctx->bit_rate = avctx->block_align * avctx->sample_rate * 8; avctx->coded_frame= avcodec_alloc_frame(); avctx->coded_frame->key_frame= 1; @@ -268,7 +269,7 @@ static int pcm_decode_frame(AVCodecContext *avctx, void *data, /* av_get_bits_per_sample returns 0 for CODEC_ID_PCM_DVD */ samples_per_block = 1; - if (CODEC_ID_PCM_DVD == avctx->codec_id) { + if (avctx->codec->id == CODEC_ID_PCM_DVD) { if (avctx->bits_per_coded_sample != 20 && avctx->bits_per_coded_sample != 24) { av_log(avctx, AV_LOG_ERROR, @@ -304,7 +305,7 @@ static int pcm_decode_frame(AVCodecContext *avctx, void *data, /* get output buffer */ s->frame.nb_samples = n * samples_per_block / avctx->channels; - if ((ret = avctx->get_buffer(avctx, &s->frame)) < 0) { + if ((ret = ff_get_buffer(avctx, &s->frame)) < 0) { av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n"); return ret; } diff --git a/libavcodec/pcx.c b/libavcodec/pcx.c index 6339dc05c8..570bc93aff 100644 --- a/libavcodec/pcx.c +++ b/libavcodec/pcx.c @@ -43,16 +43,19 @@ static av_cold int pcx_init(AVCodecContext *avctx) { /** * @return advanced src pointer */ -static const uint8_t *pcx_rle_decode(const uint8_t *src, uint8_t *dst, - unsigned int bytes_per_scanline, int compressed) { +static const uint8_t *pcx_rle_decode(const uint8_t *src, + const uint8_t *end, + uint8_t *dst, + unsigned int bytes_per_scanline, + int compressed) { unsigned int i = 0; unsigned char run, value; if (compressed) { - while (i= 0xc0) { + if (value >= 0xc0 && src < end) { run = value & 0x3f; value = *src++; } @@ -87,6 +90,7 @@ static int pcx_decode_frame(AVCodecContext *avctx, void *data, int *data_size, unsigned int w, h, bits_per_pixel, bytes_per_line, nplanes, stride, y, x, bytes_per_scanline; uint8_t *ptr; + const uint8_t *buf_end = buf + buf_size; uint8_t const *bufstart = buf; uint8_t *scanline; int ret = -1; @@ -115,7 +119,8 @@ static int pcx_decode_frame(AVCodecContext *avctx, void *data, int *data_size, nplanes = buf[65]; bytes_per_scanline = nplanes * bytes_per_line; - if (bytes_per_scanline < w * bits_per_pixel * nplanes / 8) { + if (bytes_per_scanline < w * bits_per_pixel * nplanes / 8 || + (!compressed && bytes_per_scanline > buf_size / h)) { av_log(avctx, AV_LOG_ERROR, "PCX data is corrupted\n"); return -1; } @@ -163,7 +168,8 @@ static int pcx_decode_frame(AVCodecContext *avctx, void *data, int *data_size, if (nplanes == 3 && bits_per_pixel == 8) { for (y=0; y> (x&7), v = 0; diff --git a/libavcodec/pgssubdec.c b/libavcodec/pgssubdec.c index 2785d25914..fd84af5596 100644 --- a/libavcodec/pgssubdec.c +++ b/libavcodec/pgssubdec.c @@ -207,6 +207,13 @@ static int parse_picture_segment(AVCodecContext *avctx, /* Decode rle bitmap length, stored size includes width/height data */ rle_bitmap_len = bytestream_get_be24(&buf) - 2*2; + if (buf_size > rle_bitmap_len) { + av_log(avctx, AV_LOG_ERROR, + "Buffer dimension %d larger than the expected RLE data %d\n", + buf_size, rle_bitmap_len); + return AVERROR_INVALIDDATA; + } + /* Get bitmap dimensions from data */ width = bytestream_get_be16(&buf); height = bytestream_get_be16(&buf); diff --git a/libavcodec/pictordec.c b/libavcodec/pictordec.c index d788e6474c..247e7f178b 100644 --- a/libavcodec/pictordec.c +++ b/libavcodec/pictordec.c @@ -235,6 +235,8 @@ static int decode_frame(AVCodecContext *avctx, if (bits_per_plane == 8) { picmemset_8bpp(s, val, run, &x, &y); + if (y < 0) + goto finish; } else { picmemset(s, val, run, &x, &y, &plane, bits_per_plane); } @@ -247,6 +249,7 @@ static int decode_frame(AVCodecContext *avctx, y--; } } +finish: *data_size = sizeof(AVFrame); *(AVFrame*)data = s->frame; diff --git a/libavcodec/png.h b/libavcodec/png.h index d6fac3e673..da8dda8055 100644 --- a/libavcodec/png.h +++ b/libavcodec/png.h @@ -26,6 +26,7 @@ #include #include "avcodec.h" +#include "bytestream.h" #define PNG_COLOR_MASK_PALETTE 1 #define PNG_COLOR_MASK_COLOR 2 @@ -73,9 +74,7 @@ int ff_png_pass_row_size(int pass, int bits_per_pixel, int width); void ff_add_png_paeth_prediction(uint8_t *dst, uint8_t *src, uint8_t *top, int w, int bpp); typedef struct PNGDecContext { - const uint8_t *bytestream; - const uint8_t *bytestream_start; - const uint8_t *bytestream_end; + GetByteContext gb; AVFrame picture1, picture2; AVFrame *current_picture, *last_picture; diff --git a/libavcodec/pngdec.c b/libavcodec/pngdec.c index e91bca4f97..ceae67e7c3 100644 --- a/libavcodec/pngdec.c +++ b/libavcodec/pngdec.c @@ -121,7 +121,7 @@ static void png_put_interlaced_row(uint8_t *dst, int width, static void add_bytes_l2_c(uint8_t *dst, uint8_t *src1, uint8_t *src2, int w) { long i; - for(i=0; i<=w-sizeof(long); i+=sizeof(long)){ + for(i=0; i<=w-(int)sizeof(long); i+=sizeof(long)){ long a = *(long*)(src1+i); long b = *(long*)(src2+i); *(long*)(dst+i) = ((a&pb_7f) + (b&pb_7f)) ^ ((a^b)&pb_80); @@ -361,12 +361,9 @@ static void png_handle_row(PNGDecContext *s) static int png_decode_idat(PNGDecContext *s, int length) { int ret; - s->zstream.avail_in = length; - s->zstream.next_in = s->bytestream; - s->bytestream += length; - - if(s->bytestream > s->bytestream_end) - return -1; + s->zstream.avail_in = FFMIN(length, bytestream2_get_bytes_left(&s->gb)); + s->zstream.next_in = s->gb.buffer; + bytestream2_skip(&s->gb, length); /* decode one line if possible */ while (s->zstream.avail_in > 0) { @@ -381,6 +378,10 @@ static int png_decode_idat(PNGDecContext *s, int length) s->zstream.avail_out = s->crow_size; s->zstream.next_out = s->crow_buf; } + if (ret == Z_STREAM_END && s->zstream.avail_in > 0) { + av_log(NULL, AV_LOG_WARNING, "%d undecompressed bytes left in buffer\n", s->zstream.avail_in); + return 0; + } } return 0; } @@ -402,15 +403,13 @@ static int decode_frame(AVCodecContext *avctx, avctx->coded_frame= s->current_picture; p = s->current_picture; - s->bytestream_start= - s->bytestream= buf; - s->bytestream_end= buf + buf_size; - /* check signature */ - if (memcmp(s->bytestream, ff_pngsig, 8) != 0 && - memcmp(s->bytestream, ff_mngsig, 8) != 0) + if (buf_size < 8 || + memcmp(buf, ff_pngsig, 8) != 0 && + memcmp(buf, ff_mngsig, 8) != 0) return -1; - s->bytestream+= 8; + + bytestream2_init(&s->gb, buf + 8, buf_size - 8); s->y= s->state=0; // memset(s, 0, sizeof(PNGDecContext)); @@ -422,14 +421,12 @@ static int decode_frame(AVCodecContext *avctx, if (ret != Z_OK) return -1; for(;;) { - int tag32; - if (s->bytestream >= s->bytestream_end) + if (bytestream2_get_bytes_left(&s->gb) <= 0) goto fail; - length = bytestream_get_be32(&s->bytestream); + length = bytestream2_get_be32(&s->gb); if (length > 0x7fffffff) goto fail; - tag32 = bytestream_get_be32(&s->bytestream); - tag = av_bswap32(tag32); + tag = bytestream2_get_le32(&s->gb); if (avctx->debug & FF_DEBUG_STARTCODE) av_log(avctx, AV_LOG_DEBUG, "png: tag=%c%c%c%c length=%u\n", (tag & 0xff), @@ -440,18 +437,24 @@ static int decode_frame(AVCodecContext *avctx, case MKTAG('I', 'H', 'D', 'R'): if (length != 13) goto fail; - s->width = bytestream_get_be32(&s->bytestream); - s->height = bytestream_get_be32(&s->bytestream); + + if (s->state & PNG_IDAT) { + av_log(avctx, AV_LOG_ERROR, "IHDR after IDAT\n"); + goto fail; + } + + s->width = bytestream2_get_be32(&s->gb); + s->height = bytestream2_get_be32(&s->gb); if(av_image_check_size(s->width, s->height, 0, avctx)){ s->width= s->height= 0; goto fail; } - s->bit_depth = *s->bytestream++; - s->color_type = *s->bytestream++; - s->compression_type = *s->bytestream++; - s->filter_type = *s->bytestream++; - s->interlace_type = *s->bytestream++; - s->bytestream += 4; /* crc */ + s->bit_depth = bytestream2_get_byte(&s->gb); + s->color_type = bytestream2_get_byte(&s->gb); + s->compression_type = bytestream2_get_byte(&s->gb); + s->filter_type = bytestream2_get_byte(&s->gb); + s->interlace_type = bytestream2_get_byte(&s->gb); + bytestream2_skip(&s->gb, 4); /* crc */ s->state |= PNG_IHDR; if (avctx->debug & FF_DEBUG_PICT_INFO) av_log(avctx, AV_LOG_DEBUG, "width=%d height=%d depth=%d color_type=%d compression_type=%d filter_type=%d interlace_type=%d\n", @@ -486,13 +489,14 @@ static int decode_frame(AVCodecContext *avctx, } else if (s->bit_depth == 16 && s->color_type == PNG_COLOR_TYPE_RGB) { avctx->pix_fmt = PIX_FMT_RGB48BE; - } else if (s->color_type == PNG_COLOR_TYPE_PALETTE) { + } else if ((s->bits_per_pixel == 1 || s->bits_per_pixel == 2 || s->bits_per_pixel == 4 || s->bits_per_pixel == 8) && + s->color_type == PNG_COLOR_TYPE_PALETTE) { avctx->pix_fmt = PIX_FMT_PAL8; - } else if (s->bit_depth == 1) { + } else if (s->bit_depth == 1 && s->bits_per_pixel == 1) { avctx->pix_fmt = PIX_FMT_MONOBLACK; } else if (s->bit_depth == 8 && s->color_type == PNG_COLOR_TYPE_GRAY_ALPHA) { - avctx->pix_fmt = PIX_FMT_GRAY8A; + avctx->pix_fmt = PIX_FMT_Y400A; } else { av_log(avctx, AV_LOG_ERROR, "unsupported bit depth %d " "and color type %d\n", @@ -551,7 +555,7 @@ static int decode_frame(AVCodecContext *avctx, s->state |= PNG_IDAT; if (png_decode_idat(s, length) < 0) goto fail; - s->bytestream += 4; /* crc */ + bytestream2_skip(&s->gb, 4); /* crc */ break; case MKTAG('P', 'L', 'T', 'E'): { @@ -562,16 +566,16 @@ static int decode_frame(AVCodecContext *avctx, /* read the palette */ n = length / 3; for(i=0;ibytestream++; - g = *s->bytestream++; - b = *s->bytestream++; + r = bytestream2_get_byte(&s->gb); + g = bytestream2_get_byte(&s->gb); + b = bytestream2_get_byte(&s->gb); s->palette[i] = (0xff << 24) | (r << 16) | (g << 8) | b; } for(;i<256;i++) { s->palette[i] = (0xff << 24); } s->state |= PNG_PLTE; - s->bytestream += 4; /* crc */ + bytestream2_skip(&s->gb, 4); /* crc */ } break; case MKTAG('t', 'R', 'N', 'S'): @@ -584,21 +588,21 @@ static int decode_frame(AVCodecContext *avctx, !(s->state & PNG_PLTE)) goto skip_tag; for(i=0;ibytestream++; + v = bytestream2_get_byte(&s->gb); s->palette[i] = (s->palette[i] & 0x00ffffff) | (v << 24); } - s->bytestream += 4; /* crc */ + bytestream2_skip(&s->gb, 4); /* crc */ } break; case MKTAG('I', 'E', 'N', 'D'): if (!(s->state & PNG_ALLIMAGE)) goto fail; - s->bytestream += 4; /* crc */ + bytestream2_skip(&s->gb, 4); /* crc */ goto exit_loop; default: /* skip tag */ skip_tag: - s->bytestream += length + 4; + bytestream2_skip(&s->gb, length + 4); break; } } @@ -652,9 +656,10 @@ static int decode_frame(AVCodecContext *avctx, int i, j; uint8_t *pd = s->current_picture->data[0]; uint8_t *pd_last = s->last_picture->data[0]; + int ls = FFMIN(av_image_get_linesize(s->current_picture->format, s->width, 0), s->width * s->bpp); for(j=0; j < s->height; j++) { - for(i=0; i < s->width * s->bpp; i++) { + for(i=0; i < ls; i++) { pd[i] += pd_last[i]; } pd += s->image_linesize; @@ -666,7 +671,7 @@ static int decode_frame(AVCodecContext *avctx, *picture= *s->current_picture; *data_size = sizeof(AVFrame); - ret = s->bytestream - s->bytestream_start; + ret = bytestream2_tell(&s->gb); the_end: inflateEnd(&s->zstream); av_free(crow_buf_base); diff --git a/libavcodec/pngenc.c b/libavcodec/pngenc.c index 5933bbb38a..d36914a0fb 100644 --- a/libavcodec/pngenc.c +++ b/libavcodec/pngenc.c @@ -55,7 +55,7 @@ static void png_get_interlaced_row(uint8_t *dst, int row_size, uint8_t *d; const uint8_t *s; - mask = ff_png_pass_mask[pass]; + mask = (int[]){0x80, 0x08, 0x88, 0x22, 0xaa, 0x55, 0xff}[pass]; switch(bits_per_pixel) { case 1: memset(dst, 0, row_size); diff --git a/libavcodec/ppc/h264_altivec.c b/libavcodec/ppc/h264_altivec.c index 9b3622a673..512f245b0b 100644 --- a/libavcodec/ppc/h264_altivec.c +++ b/libavcodec/ppc/h264_altivec.c @@ -1004,7 +1004,7 @@ void ff_h264dsp_init_ppc(H264DSPContext *c, const int bit_depth, const int chrom if (av_get_cpu_flags() & AV_CPU_FLAG_ALTIVEC) { if (bit_depth == 8) { c->h264_idct_add = ff_h264_idct_add_altivec; - if (chroma_format_idc == 1) + if (chroma_format_idc <= 1) c->h264_idct_add8 = ff_h264_idct_add8_altivec; c->h264_idct_add16 = ff_h264_idct_add16_altivec; c->h264_idct_add16intra = ff_h264_idct_add16intra_altivec; diff --git a/libavcodec/proresdec2.c b/libavcodec/proresdec2.c index fe4cfd09b8..9f801e447a 100644 --- a/libavcodec/proresdec2.c +++ b/libavcodec/proresdec2.c @@ -302,7 +302,7 @@ static av_always_inline void decode_dc_coeffs(GetBitContext *gb, DCTELEM *out, code = 5; sign = 0; for (i = 1; i < blocks_per_slice; i++, out += 64) { - DECODE_CODEWORD(code, dc_codebook[FFMIN(code, 6)]); + DECODE_CODEWORD(code, dc_codebook[FFMIN(code, 6U)]); if(code) sign ^= -(code & 1); else sign = 0; prev_dc += (((code + 1) >> 1) ^ sign) - sign; diff --git a/libavcodec/proresdec_lgpl.c b/libavcodec/proresdec_lgpl.c index 5fe47755c2..986e69bca7 100644 --- a/libavcodec/proresdec_lgpl.c +++ b/libavcodec/proresdec_lgpl.c @@ -186,6 +186,8 @@ static int decode_frame_header(ProresContext *ctx, const uint8_t *buf, if (ctx->frame_type) { /* if interlaced */ ctx->picture.interlaced_frame = 1; ctx->picture.top_field_first = ctx->frame_type & 1; + } else { + ctx->picture.interlaced_frame = 0; } ctx->alpha_info = buf[17] & 0xf; diff --git a/libavcodec/proresenc.c b/libavcodec/proresenc.c index 09678a002f..26afe5914f 100644 --- a/libavcodec/proresenc.c +++ b/libavcodec/proresenc.c @@ -302,7 +302,7 @@ static int encode_slice_plane(AVCodecContext *avctx, int mb_count, } blocks_per_slice = mb_count << (2 - chroma); - init_put_bits(&pb, buf, buf_size << 3); + init_put_bits(&pb, buf, buf_size); encode_dc_coeffs(&pb, blocks, blocks_per_slice, qmat); encode_ac_coeffs(avctx, &pb, blocks, blocks_per_slice, qmat); diff --git a/libavcodec/pthread.c b/libavcodec/pthread.c index 6ae763da80..6884ebdd1c 100644 --- a/libavcodec/pthread.c +++ b/libavcodec/pthread.c @@ -78,6 +78,7 @@ typedef struct ThreadContext { pthread_cond_t last_job_cond; pthread_cond_t current_job_cond; pthread_mutex_t current_job_lock; + unsigned current_execute; int current_job; int done; } ThreadContext; @@ -202,6 +203,7 @@ static void* attribute_align_arg worker(void *v) { AVCodecContext *avctx = v; ThreadContext *c = avctx->thread_opaque; + unsigned last_execute = 0; int our_job = c->job_count; int thread_count = avctx->thread_count; int self_id; @@ -213,7 +215,9 @@ static void* attribute_align_arg worker(void *v) if (c->current_job == thread_count + c->job_count) pthread_cond_signal(&c->last_job_cond); - pthread_cond_wait(&c->current_job_cond, &c->current_job_lock); + while (last_execute == c->current_execute && !c->done) + pthread_cond_wait(&c->current_job_cond, &c->current_job_lock); + last_execute = c->current_execute; our_job = self_id; if (c->done) { @@ -233,7 +237,8 @@ static void* attribute_align_arg worker(void *v) static av_always_inline void avcodec_thread_park_workers(ThreadContext *c, int thread_count) { - pthread_cond_wait(&c->last_job_cond, &c->current_job_lock); + while (c->current_job != thread_count + c->job_count) + pthread_cond_wait(&c->last_job_cond, &c->current_job_lock); pthread_mutex_unlock(&c->current_job_lock); } @@ -282,6 +287,7 @@ static int avcodec_thread_execute(AVCodecContext *avctx, action_func* func, void c->rets = &dummy_ret; c->rets_count = 1; } + c->current_execute++; pthread_cond_broadcast(&c->current_job_cond); avcodec_thread_park_workers(c, avctx->thread_count); @@ -390,7 +396,7 @@ static attribute_align_arg void *frame_worker_thread(void *arg) pthread_mutex_lock(&p->progress_mutex); for (i = 0; i < MAX_BUFFERS; i++) - if (p->progress_used[i]) { + if (p->progress_used[i] && (p->got_frame || p->result<0 || avctx->codec_id != CODEC_ID_H264)) { p->progress[i][0] = INT_MAX; p->progress[i][1] = INT_MAX; } @@ -583,7 +589,7 @@ static int submit_packet(PerThreadContext *p, AVPacket *avpkt) pthread_cond_wait(&p->progress_cond, &p->progress_mutex); if (p->state == STATE_GET_BUFFER) { - p->result = p->avctx->get_buffer(p->avctx, p->requested_frame); + p->result = ff_get_buffer(p->avctx, p->requested_frame); p->state = STATE_SETTING_UP; pthread_cond_signal(&p->progress_cond); } @@ -647,10 +653,10 @@ int ff_thread_decode_frame(AVCodecContext *avctx, *picture = p->frame; *got_picture_ptr = p->got_frame; picture->pkt_dts = p->avpkt.dts; - picture->sample_aspect_ratio = avctx->sample_aspect_ratio; - picture->width = avctx->width; - picture->height = avctx->height; - picture->format = avctx->pix_fmt; + picture->sample_aspect_ratio = p->avctx->sample_aspect_ratio; + picture->width = p->avctx->width; + picture->height = p->avctx->height; + picture->format = p->avctx->pix_fmt; /* * A later call with avkpt->size == 0 may loop over all threads, @@ -940,7 +946,7 @@ int ff_thread_get_buffer(AVCodecContext *avctx, AVFrame *f) if (!(avctx->active_thread_type&FF_THREAD_FRAME)) { f->thread_opaque = NULL; - return avctx->get_buffer(avctx, f); + return ff_get_buffer(avctx, f); } if (p->state != STATE_SETTING_UP && @@ -963,7 +969,7 @@ int ff_thread_get_buffer(AVCodecContext *avctx, AVFrame *f) if (avctx->thread_safe_callbacks || avctx->get_buffer == avcodec_default_get_buffer) { - err = avctx->get_buffer(avctx, f); + err = ff_get_buffer(avctx, f); } else { p->requested_frame = f; p->state = STATE_GET_BUFFER; diff --git a/libavcodec/put_bits.h b/libavcodec/put_bits.h index 9256e7fa4d..a5bc7314a7 100644 --- a/libavcodec/put_bits.h +++ b/libavcodec/put_bits.h @@ -72,6 +72,14 @@ static inline int put_bits_count(PutBitContext *s) return (s->buf_ptr - s->buf) * 8 + 32 - s->bit_left; } +/** + * @return the number of bits available in the bitstream. + */ +static inline int put_bits_left(PutBitContext* s) +{ + return (s->buf_end - s->buf_ptr) * 8 - 32 + s->bit_left; +} + /** * Pad the end of the output stream with zeros. */ diff --git a/libavcodec/qcelpdec.c b/libavcodec/qcelpdec.c index ac5c289c3d..33cee193f4 100644 --- a/libavcodec/qcelpdec.c +++ b/libavcodec/qcelpdec.c @@ -697,7 +697,7 @@ static int qcelp_decode_frame(AVCodecContext *avctx, void *data, /* get output buffer */ q->avframe.nb_samples = 160; - if ((ret = avctx->get_buffer(avctx, &q->avframe)) < 0) { + if ((ret = ff_get_buffer(avctx, &q->avframe)) < 0) { av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n"); return ret; } diff --git a/libavcodec/qdm2.c b/libavcodec/qdm2.c index 5da21d757d..e44dc8f470 100644 --- a/libavcodec/qdm2.c +++ b/libavcodec/qdm2.c @@ -37,6 +37,7 @@ #define BITSTREAM_READER_LE #include "avcodec.h" +#include "internal.h" #include "get_bits.h" #include "dsputil.h" #include "rdft.h" @@ -498,7 +499,8 @@ static void build_sb_samples_from_noise (QDM2Context *q, int sb) * @param channels number of channels * @param coding_method q->coding_method[0][0][0] */ -static void fix_coding_method_array (int sb, int channels, sb_int8_array coding_method) +static int fix_coding_method_array(int sb, int channels, + sb_int8_array coding_method) { int j,k; int ch; @@ -507,8 +509,10 @@ static void fix_coding_method_array (int sb, int channels, sb_int8_array coding_ for (ch = 0; ch < channels; ch++) { for (j = 0; j < 64; ) { - if((coding_method[ch][sb][j] - 8) > 22) { - run = 1; + if (coding_method[ch][sb][j] < 8) + return -1; + if ((coding_method[ch][sb][j] - 8) > 22) { + run = 1; case_val = 8; } else { switch (switchtable[coding_method[ch][sb][j]-8]) { @@ -533,6 +537,7 @@ static void fix_coding_method_array (int sb, int channels, sb_int8_array coding_ j += run; } } + return 0; } @@ -769,7 +774,7 @@ static void fill_coding_method_array (sb_int8_array tone_level_idx, sb_int8_arra static void synthfilt_build_sb_samples (QDM2Context *q, GetBitContext *gb, int length, int sb_min, int sb_max) { int sb, j, k, n, ch, run, channels; - int joined_stereo, zero_encoding, chs; + int joined_stereo, zero_encoding; int type34_first; float type34_div = 0; float type34_predictor; @@ -784,8 +789,6 @@ static void synthfilt_build_sb_samples (QDM2Context *q, GetBitContext *gb, int l } for (sb = sb_min; sb < sb_max; sb++) { - FIX_NOISE_IDX(q->noise_idx); - channels = q->nb_channels; if (q->nb_channels <= 1 || sb < 12) @@ -804,11 +807,16 @@ static void synthfilt_build_sb_samples (QDM2Context *q, GetBitContext *gb, int l if (q->coding_method[1][sb][j] > q->coding_method[0][sb][j]) q->coding_method[0][sb][j] = q->coding_method[1][sb][j]; - fix_coding_method_array(sb, q->nb_channels, q->coding_method); + if (fix_coding_method_array(sb, q->nb_channels, + q->coding_method)) { + build_sb_samples_from_noise(q, sb); + continue; + } channels = 1; } for (ch = 0; ch < channels; ch++) { + FIX_NOISE_IDX(q->noise_idx); zero_encoding = (BITS_LEFT(length,gb) >= 1) ? get_bits1(gb) : 0; type34_predictor = 0.0; type34_first = 1; @@ -884,9 +892,13 @@ static void synthfilt_build_sb_samples (QDM2Context *q, GetBitContext *gb, int l break; case 30: - if (BITS_LEFT(length,gb) >= 4) - samples[0] = type30_dequant[qdm2_get_vlc(gb, &vlc_tab_type30, 0, 1)]; - else + if (BITS_LEFT(length,gb) >= 4) { + unsigned index = qdm2_get_vlc(gb, &vlc_tab_type30, 0, 1); + if (index < FF_ARRAY_ELEMS(type30_dequant)) { + samples[0] = type30_dequant[index]; + } else + samples[0] = SB_DITHERING_NOISE(sb,q->noise_idx); + } else samples[0] = SB_DITHERING_NOISE(sb,q->noise_idx); run = 1; @@ -900,8 +912,12 @@ static void synthfilt_build_sb_samples (QDM2Context *q, GetBitContext *gb, int l type34_predictor = samples[0]; type34_first = 0; } else { - samples[0] = type34_delta[qdm2_get_vlc(gb, &vlc_tab_type34, 0, 1)] / type34_div + type34_predictor; - type34_predictor = samples[0]; + unsigned index = qdm2_get_vlc(gb, &vlc_tab_type34, 0, 1); + if (index < FF_ARRAY_ELEMS(type34_delta)) { + samples[0] = type34_delta[index] / type34_div + type34_predictor; + type34_predictor = samples[0]; + } else + samples[0] = SB_DITHERING_NOISE(sb,q->noise_idx); } } else { samples[0] = SB_DITHERING_NOISE(sb,q->noise_idx); @@ -916,16 +932,18 @@ static void synthfilt_build_sb_samples (QDM2Context *q, GetBitContext *gb, int l } if (joined_stereo) { - float tmp[10][MPA_MAX_CHANNELS]; - - for (k = 0; k < run; k++) { - tmp[k][0] = samples[k]; - tmp[k][1] = (sign_bits[(j + k) / 8]) ? -samples[k] : samples[k]; + for (k = 0; k < run && j + k < 128; k++) { + q->sb_samples[0][j + k][sb] = + q->tone_level[0][sb][(j + k) / 2] * samples[k]; + if (q->nb_channels == 2) { + if (sign_bits[(j + k) / 8]) + q->sb_samples[1][j + k][sb] = + q->tone_level[1][sb][(j + k) / 2] * -samples[k]; + else + q->sb_samples[1][j + k][sb] = + q->tone_level[1][sb][(j + k) / 2] * samples[k]; + } } - for (chs = 0; chs < q->nb_channels; chs++) - for (k = 0; k < run; k++) - if ((j + k) < 128) - q->sb_samples[chs][j + k][sb] = q->tone_level[chs][sb][((j + k)/2)] * tmp[k][chs]; } else { for (k = 0; k < run; k++) if ((j + k) < 128) @@ -1233,6 +1251,11 @@ static void qdm2_decode_super_block (QDM2Context *q) for (i = 0; packet_bytes > 0; i++) { int j; + if (i >= FF_ARRAY_ELEMS(q->sub_packet_list_A)) { + SAMPLES_NEEDED_2("too many packet bytes"); + return; + } + q->sub_packet_list_A[i].next = NULL; if (i > 0) { @@ -1874,6 +1897,10 @@ static av_cold int qdm2_decode_init(AVCodecContext *avctx) av_log(avctx, AV_LOG_ERROR, "Unknown FFT order (%d), contact the developers!\n", s->fft_order); return -1; } + if (s->fft_size != (1 << (s->fft_order - 1))) { + av_log(avctx, AV_LOG_ERROR, "FFT size %d not power of 2.\n", s->fft_size); + return AVERROR_INVALIDDATA; + } ff_rdft_init(&s->rdft_ctx, s->fft_order, IDFT_C2R); ff_mpadsp_init(&s->mpadsp); @@ -1981,7 +2008,7 @@ static int qdm2_decode_frame(AVCodecContext *avctx, void *data, /* get output buffer */ s->frame.nb_samples = 16 * s->frame_size; - if ((ret = avctx->get_buffer(avctx, &s->frame)) < 0) { + if ((ret = ff_get_buffer(avctx, &s->frame)) < 0) { av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n"); return ret; } diff --git a/libavcodec/qpeg.c b/libavcodec/qpeg.c index bbb9f71aae..ac4f9a85d8 100644 --- a/libavcodec/qpeg.c +++ b/libavcodec/qpeg.c @@ -171,7 +171,7 @@ static void qpeg_decode_inter(const uint8_t *src, uint8_t *dst, int size, /* check motion vector */ if ((me_x + filled < 0) || (me_x + me_w + filled > width) || - (height - me_y - me_h < 0) || (height - me_y > orig_height) || + (height - me_y - me_h < 0) || (height - me_y >= orig_height) || (filled + me_w > width) || (height - me_h < 0)) av_log(NULL, AV_LOG_ERROR, "Bogus motion vector (%i,%i), block size %ix%i at %i,%i\n", me_x, me_y, me_w, me_h, filled, height); @@ -203,6 +203,8 @@ static void qpeg_decode_inter(const uint8_t *src, uint8_t *dst, int size, filled = 0; dst -= stride; height--; + if (height < 0) + break; } } } else if(code >= 0xC0) { /* copy code: 0xC0..0xDF */ @@ -214,6 +216,8 @@ static void qpeg_decode_inter(const uint8_t *src, uint8_t *dst, int size, filled = 0; dst -= stride; height--; + if (height < 0) + break; } } size -= code + 1; diff --git a/libavcodec/qtrle.c b/libavcodec/qtrle.c index 4ef529d5b2..a5ae4f6004 100644 --- a/libavcodec/qtrle.c +++ b/libavcodec/qtrle.c @@ -77,7 +77,7 @@ static void qtrle_decode_1bpp(QtrleContext *s, int stream_ptr, int row_ptr, int * line' at the beginning. Since we always interpret it as 'go to next line' * in the decoding loop (which makes code simpler/faster), the first line * would not be counted, so we count one more. - * See: https://ffmpeg.org/trac/ffmpeg/ticket/226 + * See: https://trac.ffmpeg.org/ticket/226 * In the following decoding loop, row_ptr will be the position of the * _next_ row. */ lines_to_change++; @@ -424,7 +424,7 @@ static av_cold int qtrle_decode_init(AVCodecContext *avctx) default: av_log (avctx, AV_LOG_ERROR, "Unsupported colorspace: %d bits/sample?\n", avctx->bits_per_coded_sample); - break; + return AVERROR_INVALIDDATA; } avcodec_get_frame_defaults(&s->frame); diff --git a/libavcodec/ra144dec.c b/libavcodec/ra144dec.c index 428f788733..8b2bcacf59 100644 --- a/libavcodec/ra144dec.c +++ b/libavcodec/ra144dec.c @@ -24,6 +24,7 @@ #include "libavutil/intmath.h" #include "avcodec.h" +#include "internal.h" #include "get_bits.h" #include "ra144.h" @@ -77,7 +78,7 @@ static int ra144_decode_frame(AVCodecContext * avctx, void *data, /* get output buffer */ ractx->frame.nb_samples = NBLOCKS * BLOCKSIZE; - if ((ret = avctx->get_buffer(avctx, &ractx->frame)) < 0) { + if ((ret = ff_get_buffer(avctx, &ractx->frame)) < 0) { av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n"); return ret; } diff --git a/libavcodec/ra288.c b/libavcodec/ra288.c index 26b576d804..43538f0186 100644 --- a/libavcodec/ra288.c +++ b/libavcodec/ra288.c @@ -20,6 +20,7 @@ */ #include "avcodec.h" +#include "internal.h" #define BITSTREAM_READER_LE #include "get_bits.h" #include "ra288.h" @@ -188,7 +189,7 @@ static int ra288_decode_frame(AVCodecContext * avctx, void *data, /* get output buffer */ ractx->frame.nb_samples = RA288_BLOCK_SIZE * RA288_BLOCKS_PER_FRAME; - if ((ret = avctx->get_buffer(avctx, &ractx->frame)) < 0) { + if ((ret = ff_get_buffer(avctx, &ractx->frame)) < 0) { av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n"); return ret; } diff --git a/libavcodec/rawdec.c b/libavcodec/rawdec.c index a9156dedab..5229026ade 100644 --- a/libavcodec/rawdec.c +++ b/libavcodec/rawdec.c @@ -139,6 +139,7 @@ static int raw_decode(AVCodecContext *avctx, int buf_size = avpkt->size; int linesize_align = 4; RawVideoContext *context = avctx->priv_data; + int res; AVFrame * frame = (AVFrame *) data; AVPicture * picture = (AVPicture *) data; @@ -155,6 +156,9 @@ static int raw_decode(AVCodecContext *avctx, frame->top_field_first = context->tff; } + if(buf_size < context->length - (avctx->pix_fmt==PIX_FMT_PAL8 ? 256*4 : 0)) + return -1; + //2bpp and 4bpp raw in avi and mov (yes this is ugly ...) if (context->buffer) { int i; @@ -182,10 +186,9 @@ static int raw_decode(AVCodecContext *avctx, avctx->codec_tag == MKTAG('A', 'V', 'u', 'p')) buf += buf_size - context->length; - if(buf_size < context->length - (avctx->pix_fmt==PIX_FMT_PAL8 ? 256*4 : 0)) - return -1; - - avpicture_fill(picture, buf, avctx->pix_fmt, avctx->width, avctx->height); + if ((res = avpicture_fill(picture, buf, avctx->pix_fmt, + avctx->width, avctx->height)) < 0) + return res; if((avctx->pix_fmt==PIX_FMT_PAL8 && buf_size < context->length) || (avctx->pix_fmt!=PIX_FMT_PAL8 && (av_pix_fmt_descriptors[avctx->pix_fmt].flags & PIX_FMT_PAL))){ diff --git a/libavcodec/rl.h b/libavcodec/rl.h index b2445890e6..c80283db7f 100644 --- a/libavcodec/rl.h +++ b/libavcodec/rl.h @@ -53,8 +53,8 @@ typedef struct RLTable { * @param static_store static uint8_t array[2][2*MAX_RUN + MAX_LEVEL + 3] which will hold * the level and run tables, if this is NULL av_malloc() will be used */ -void init_rl(RLTable *rl, uint8_t static_store[2][2*MAX_RUN + MAX_LEVEL + 3]); -void init_vlc_rl(RLTable *rl); +void ff_init_rl(RLTable *rl, uint8_t static_store[2][2*MAX_RUN + MAX_LEVEL + 3]); +void ff_init_vlc_rl(RLTable *rl); #define INIT_VLC_RL(rl, static_size)\ {\ @@ -68,7 +68,7 @@ void init_vlc_rl(RLTable *rl); for(q=0; q<32; q++)\ rl.rl_vlc[q]= rl_vlc_table[q];\ \ - init_vlc_rl(&rl);\ + ff_init_vlc_rl(&rl);\ }\ } diff --git a/libavcodec/roqvideo.h b/libavcodec/roqvideo.h index 3fe11c670b..546bd4c1ce 100644 --- a/libavcodec/roqvideo.h +++ b/libavcodec/roqvideo.h @@ -24,6 +24,7 @@ #include "libavutil/lfg.h" #include "avcodec.h" +#include "bytestream.h" #include "dsputil.h" typedef struct { @@ -53,8 +54,7 @@ typedef struct RoqContext { roq_cell cb2x2[256]; roq_qcell cb4x4[256]; - const unsigned char *buf; - int size; + GetByteContext gb; int width, height; /* Encoder only data */ diff --git a/libavcodec/roqvideodec.c b/libavcodec/roqvideodec.c index 161e7da08a..735d767141 100644 --- a/libavcodec/roqvideodec.c +++ b/libavcodec/roqvideodec.c @@ -38,16 +38,15 @@ static void roqvideo_decode_frame(RoqContext *ri) unsigned int chunk_id = 0, chunk_arg = 0; unsigned long chunk_size = 0; int i, j, k, nv1, nv2, vqflg = 0, vqflg_pos = -1; - int vqid, bpos, xpos, ypos, xp, yp, x, y, mx, my; + int vqid, xpos, ypos, xp, yp, x, y, mx, my; int frame_stats[2][4] = {{0},{0}}; roq_qcell *qcell; - const unsigned char *buf = ri->buf; - const unsigned char *buf_end = ri->buf + ri->size; + int64_t chunk_start; - while (buf < buf_end) { - chunk_id = bytestream_get_le16(&buf); - chunk_size = bytestream_get_le32(&buf); - chunk_arg = bytestream_get_le16(&buf); + while (bytestream2_get_bytes_left(&ri->gb) >= 8) { + chunk_id = bytestream2_get_le16(&ri->gb); + chunk_size = bytestream2_get_le32(&ri->gb); + chunk_arg = bytestream2_get_le16(&ri->gb); if(chunk_id == RoQ_QUAD_VQ) break; @@ -57,33 +56,36 @@ static void roqvideo_decode_frame(RoqContext *ri) if((nv2 = chunk_arg & 0xff) == 0 && nv1 * 6 < chunk_size) nv2 = 256; for(i = 0; i < nv1; i++) { - ri->cb2x2[i].y[0] = *buf++; - ri->cb2x2[i].y[1] = *buf++; - ri->cb2x2[i].y[2] = *buf++; - ri->cb2x2[i].y[3] = *buf++; - ri->cb2x2[i].u = *buf++; - ri->cb2x2[i].v = *buf++; + ri->cb2x2[i].y[0] = bytestream2_get_byte(&ri->gb); + ri->cb2x2[i].y[1] = bytestream2_get_byte(&ri->gb); + ri->cb2x2[i].y[2] = bytestream2_get_byte(&ri->gb); + ri->cb2x2[i].y[3] = bytestream2_get_byte(&ri->gb); + ri->cb2x2[i].u = bytestream2_get_byte(&ri->gb); + ri->cb2x2[i].v = bytestream2_get_byte(&ri->gb); } for(i = 0; i < nv2; i++) for(j = 0; j < 4; j++) - ri->cb4x4[i].idx[j] = *buf++; + ri->cb4x4[i].idx[j] = bytestream2_get_byte(&ri->gb); } } - bpos = xpos = ypos = 0; - if (chunk_size > buf_end - buf) { + chunk_start = bytestream2_tell(&ri->gb); + xpos = ypos = 0; + + if (chunk_size > bytestream2_get_bytes_left(&ri->gb)) { av_log(ri->avctx, AV_LOG_ERROR, "Chunk does not fit in input buffer\n"); - chunk_size = buf_end - buf; + chunk_size = bytestream2_get_bytes_left(&ri->gb); } - while(bpos < chunk_size) { + + while (bytestream2_tell(&ri->gb) < chunk_start + chunk_size) { for (yp = ypos; yp < ypos + 16; yp += 8) for (xp = xpos; xp < xpos + 16; xp += 8) { - if (bpos >= chunk_size) { + if (bytestream2_tell(&ri->gb) >= chunk_start + chunk_size) { av_log(ri->avctx, AV_LOG_ERROR, "Input buffer too small\n"); return; } if (vqflg_pos < 0) { - vqflg = buf[bpos++]; vqflg |= (buf[bpos++] << 8); + vqflg = bytestream2_get_le16(&ri->gb); vqflg_pos = 7; } vqid = (vqflg >> (vqflg_pos * 2)) & 0x3; @@ -93,13 +95,15 @@ static void roqvideo_decode_frame(RoqContext *ri) switch(vqid) { case RoQ_ID_MOT: break; - case RoQ_ID_FCC: - mx = 8 - (buf[bpos] >> 4) - ((signed char) (chunk_arg >> 8)); - my = 8 - (buf[bpos++] & 0xf) - ((signed char) chunk_arg); + case RoQ_ID_FCC: { + int byte = bytestream2_get_byte(&ri->gb); + mx = 8 - (byte >> 4) - ((signed char) (chunk_arg >> 8)); + my = 8 - (byte & 0xf) - ((signed char) chunk_arg); ff_apply_motion_8x8(ri, xp, yp, mx, my); break; + } case RoQ_ID_SLD: - qcell = ri->cb4x4 + buf[bpos++]; + qcell = ri->cb4x4 + bytestream2_get_byte(&ri->gb); ff_apply_vector_4x4(ri, xp, yp, ri->cb2x2 + qcell->idx[0]); ff_apply_vector_4x4(ri, xp+4, yp, ri->cb2x2 + qcell->idx[1]); ff_apply_vector_4x4(ri, xp, yp+4, ri->cb2x2 + qcell->idx[2]); @@ -111,13 +115,12 @@ static void roqvideo_decode_frame(RoqContext *ri) if(k & 0x01) x += 4; if(k & 0x02) y += 4; - if (bpos >= chunk_size) { + if (bytestream2_tell(&ri->gb) >= chunk_start + chunk_size) { av_log(ri->avctx, AV_LOG_ERROR, "Input buffer too small\n"); return; } if (vqflg_pos < 0) { - vqflg = buf[bpos++]; - vqflg |= (buf[bpos++] << 8); + vqflg = bytestream2_get_le16(&ri->gb); vqflg_pos = 7; } vqid = (vqflg >> (vqflg_pos * 2)) & 0x3; @@ -126,24 +129,25 @@ static void roqvideo_decode_frame(RoqContext *ri) switch(vqid) { case RoQ_ID_MOT: break; - case RoQ_ID_FCC: - mx = 8 - (buf[bpos] >> 4) - ((signed char) (chunk_arg >> 8)); - my = 8 - (buf[bpos++] & 0xf) - ((signed char) chunk_arg); + case RoQ_ID_FCC: { + int byte = bytestream2_get_byte(&ri->gb); + mx = 8 - (byte >> 4) - ((signed char) (chunk_arg >> 8)); + my = 8 - (byte & 0xf) - ((signed char) chunk_arg); ff_apply_motion_4x4(ri, x, y, mx, my); break; + } case RoQ_ID_SLD: - qcell = ri->cb4x4 + buf[bpos++]; + qcell = ri->cb4x4 + bytestream2_get_byte(&ri->gb); ff_apply_vector_2x2(ri, x, y, ri->cb2x2 + qcell->idx[0]); ff_apply_vector_2x2(ri, x+2, y, ri->cb2x2 + qcell->idx[1]); ff_apply_vector_2x2(ri, x, y+2, ri->cb2x2 + qcell->idx[2]); ff_apply_vector_2x2(ri, x+2, y+2, ri->cb2x2 + qcell->idx[3]); break; case RoQ_ID_CCC: - ff_apply_vector_2x2(ri, x, y, ri->cb2x2 + buf[bpos]); - ff_apply_vector_2x2(ri, x+2, y, ri->cb2x2 + buf[bpos+1]); - ff_apply_vector_2x2(ri, x, y+2, ri->cb2x2 + buf[bpos+2]); - ff_apply_vector_2x2(ri, x+2, y+2, ri->cb2x2 + buf[bpos+3]); - bpos += 4; + ff_apply_vector_2x2(ri, x, y, ri->cb2x2 + bytestream2_get_byte(&ri->gb)); + ff_apply_vector_2x2(ri, x+2, y, ri->cb2x2 + bytestream2_get_byte(&ri->gb)); + ff_apply_vector_2x2(ri, x, y+2, ri->cb2x2 + bytestream2_get_byte(&ri->gb)); + ff_apply_vector_2x2(ri, x+2, y+2, ri->cb2x2 + bytestream2_get_byte(&ri->gb)); break; } } @@ -169,6 +173,13 @@ static av_cold int roq_decode_init(AVCodecContext *avctx) RoqContext *s = avctx->priv_data; s->avctx = avctx; + + if (avctx->width % 16 || avctx->height % 16) { + av_log(avctx, AV_LOG_ERROR, + "Dimensions must be a multiple of 16\n"); + return AVERROR_PATCHWELCOME; + } + s->width = avctx->width; s->height = avctx->height; avcodec_get_frame_defaults(&s->frames[0]); @@ -199,8 +210,7 @@ static int roq_decode_frame(AVCodecContext *avctx, av_picture_copy((AVPicture*)s->current_frame, (AVPicture*)s->last_frame, avctx->pix_fmt, avctx->width, avctx->height); - s->buf = buf; - s->size = buf_size; + bytestream2_init(&s->gb, buf, buf_size); roqvideo_decode_frame(s); *data_size = sizeof(AVFrame); diff --git a/libavcodec/roqvideoenc.c b/libavcodec/roqvideoenc.c index 88d6224eac..4b008781bd 100644 --- a/libavcodec/roqvideoenc.c +++ b/libavcodec/roqvideoenc.c @@ -59,7 +59,9 @@ #include "roqvideo.h" #include "bytestream.h" #include "elbg.h" +#include "internal.h" #include "mathops.h" +#include "internal.h" #define CHROMA_BIAS 1 @@ -941,6 +943,8 @@ static int roq_encode_init(AVCodecContext *avctx) av_lfg_init(&enc->randctx, 1); + enc->avctx = avctx; + enc->framesSinceKeyframe = 0; if ((avctx->width & 0xf) || (avctx->height & 0xf)) { av_log(avctx, AV_LOG_ERROR, "Dimensions must be divisible by 16\n"); @@ -1031,8 +1035,8 @@ static int roq_encode_frame(AVCodecContext *avctx, unsigned char *buf, int buf_s if (enc->first_frame) { /* Alloc memory for the reconstruction data (we must know the stride for that) */ - if (avctx->get_buffer(avctx, enc->current_frame) || - avctx->get_buffer(avctx, enc->last_frame)) { + if (ff_get_buffer(avctx, enc->current_frame) || + ff_get_buffer(avctx, enc->last_frame)) { av_log(avctx, AV_LOG_ERROR, " RoQ: get_buffer() failed\n"); return -1; } diff --git a/libavcodec/rpza.c b/libavcodec/rpza.c index 4c87b3c1b2..8dafba72c4 100644 --- a/libavcodec/rpza.c +++ b/libavcodec/rpza.c @@ -38,6 +38,7 @@ #include #include +#include "libavutil/common.h" #include "libavutil/intreadwrite.h" #include "avcodec.h" @@ -83,7 +84,7 @@ static void rpza_decode_stream(RpzaContext *s) unsigned short *pixels = (unsigned short *)s->frame.data[0]; int row_ptr = 0; - int pixel_ptr = 0; + int pixel_ptr = -4; int block_ptr; int pixel_x, pixel_y; int total_blocks; @@ -125,6 +126,8 @@ static void rpza_decode_stream(RpzaContext *s) } } + n_blocks = FFMIN(n_blocks, total_blocks); + switch (opcode & 0xe0) { /* Skip blocks */ @@ -139,6 +142,7 @@ static void rpza_decode_stream(RpzaContext *s) colorA = AV_RB16 (&s->buf[stream_ptr]); stream_ptr += 2; while (n_blocks--) { + ADVANCE_BLOCK() block_ptr = row_ptr + pixel_ptr; for (pixel_y = 0; pixel_y < 4; pixel_y++) { for (pixel_x = 0; pixel_x < 4; pixel_x++){ @@ -147,7 +151,6 @@ static void rpza_decode_stream(RpzaContext *s) } block_ptr += row_inc; } - ADVANCE_BLOCK(); } break; @@ -183,7 +186,10 @@ static void rpza_decode_stream(RpzaContext *s) color4[1] |= ((11 * ta + 21 * tb) >> 5); color4[2] |= ((21 * ta + 11 * tb) >> 5); + if (s->size - stream_ptr < n_blocks * 4) + return; while (n_blocks--) { + ADVANCE_BLOCK(); block_ptr = row_ptr + pixel_ptr; for (pixel_y = 0; pixel_y < 4; pixel_y++) { index = s->buf[stream_ptr++]; @@ -194,12 +200,14 @@ static void rpza_decode_stream(RpzaContext *s) } block_ptr += row_inc; } - ADVANCE_BLOCK(); } break; /* Fill block with 16 colors */ case 0x00: + if (s->size - stream_ptr < 30) + return; + ADVANCE_BLOCK(); block_ptr = row_ptr + pixel_ptr; for (pixel_y = 0; pixel_y < 4; pixel_y++) { for (pixel_x = 0; pixel_x < 4; pixel_x++){ @@ -213,7 +221,6 @@ static void rpza_decode_stream(RpzaContext *s) } block_ptr += row_inc; } - ADVANCE_BLOCK(); break; /* Unknown opcode */ diff --git a/libavcodec/rtjpeg.h b/libavcodec/rtjpeg.h index 4bcb9f70ca..73d41f481d 100644 --- a/libavcodec/rtjpeg.h +++ b/libavcodec/rtjpeg.h @@ -25,6 +25,9 @@ #include #include "dsputil.h" +#define RTJPEG_FILE_VERSION 0 +#define RTJPEG_HEADER_SIZE 12 + typedef struct { int w, h; DSPContext *dsp; diff --git a/libavcodec/rv10.c b/libavcodec/rv10.c index d97ed12272..84962f65d0 100644 --- a/libavcodec/rv10.c +++ b/libavcodec/rv10.c @@ -358,6 +358,11 @@ static int rv20_decode_picture_header(MpegEncContext *s) f = get_bits(&s->gb, rpr_bits); if(f){ + if (s->avctx->extradata_size < 8 + 2 * f) { + av_log(s->avctx, AV_LOG_ERROR, "Extradata too small.\n"); + return AVERROR_INVALIDDATA; + } + new_w= 4*((uint8_t*)s->avctx->extradata)[6+2*f]; new_h= 4*((uint8_t*)s->avctx->extradata)[7+2*f]; }else{ @@ -437,12 +442,15 @@ static av_cold int rv10_decode_init(AVCodecContext *avctx) { MpegEncContext *s = avctx->priv_data; static int done=0; - int major_ver, minor_ver, micro_ver; + int major_ver, minor_ver, micro_ver, ret; if (avctx->extradata_size < 8) { av_log(avctx, AV_LOG_ERROR, "Extradata is too small.\n"); return -1; } + if ((ret = av_image_check_size(avctx->coded_width, + avctx->coded_height, 0, avctx)) < 0) + return ret; MPV_decode_defaults(s); @@ -487,7 +495,7 @@ static av_cold int rv10_decode_init(AVCodecContext *avctx) if (MPV_common_init(s) < 0) return -1; - h263_decode_init_vlc(s); + ff_h263_decode_init_vlc(s); /* init rv vlc */ if (!done) { @@ -515,9 +523,10 @@ static int rv10_decode_packet(AVCodecContext *avctx, const uint8_t *buf, int buf_size, int buf_size2) { MpegEncContext *s = avctx->priv_data; - int mb_count, mb_pos, left, start_mb_x; + int mb_count, mb_pos, left, start_mb_x, active_bits_size; - init_get_bits(&s->gb, buf, buf_size*8); + active_bits_size = buf_size * 8; + init_get_bits(&s->gb, buf, FFMAX(buf_size, buf_size2) * 8); if(s->codec_id ==CODEC_ID_RV10) mb_count = rv10_decode_picture_header(s); else @@ -601,13 +610,26 @@ static int rv10_decode_packet(AVCodecContext *avctx, s->mv_type = MV_TYPE_16X16; ret=ff_h263_decode_mb(s, s->block); - if (ret != SLICE_ERROR && s->gb.size_in_bits < get_bits_count(&s->gb) && 8*buf_size2 >= get_bits_count(&s->gb)){ - av_log(avctx, AV_LOG_DEBUG, "update size from %d to %d\n", s->gb.size_in_bits, 8*buf_size2); - s->gb.size_in_bits= 8*buf_size2; + // Repeat the slice end check from ff_h263_decode_mb with our active + // bitstream size + if (ret != SLICE_ERROR) { + int v = show_bits(&s->gb, 16); + + if (get_bits_count(&s->gb) + 16 > active_bits_size) + v >>= get_bits_count(&s->gb) + 16 - active_bits_size; + + if (!v) + ret = SLICE_END; + } + if (ret != SLICE_ERROR && active_bits_size < get_bits_count(&s->gb) && + 8 * buf_size2 >= get_bits_count(&s->gb)) { + active_bits_size = buf_size2 * 8; + av_log(avctx, AV_LOG_DEBUG, "update size from %d to %d\n", + 8 * buf_size, active_bits_size); ret= SLICE_OK; } - if (ret == SLICE_ERROR || s->gb.size_in_bits < get_bits_count(&s->gb)) { + if (ret == SLICE_ERROR || active_bits_size < get_bits_count(&s->gb)) { av_log(s->avctx, AV_LOG_ERROR, "ERROR at MB %d %d\n", s->mb_x, s->mb_y); return -1; } @@ -629,7 +651,7 @@ static int rv10_decode_packet(AVCodecContext *avctx, ff_er_add_slice(s, start_mb_x, s->resync_mb_y, s->mb_x-1, s->mb_y, ER_MB_END); - return s->gb.size_in_bits; + return active_bits_size; } static int get_slice_offset(AVCodecContext *avctx, const uint8_t *buf, int n) @@ -661,8 +683,12 @@ static int rv10_decode_frame(AVCodecContext *avctx, if(!avctx->slice_count){ slice_count = (*buf++) + 1; + buf_size--; slices_hdr = buf + 4; buf += 8 * slice_count; + buf_size -= 8 * slice_count; + if (buf_size <= 0) + return AVERROR_INVALIDDATA; }else slice_count = avctx->slice_count; @@ -708,7 +734,7 @@ static int rv10_decode_frame(AVCodecContext *avctx, s->current_picture_ptr= NULL; //so we can detect if frame_end wasnt called (find some nicer solution...) } - return buf_size; + return avpkt->size; } AVCodec ff_rv10_decoder = { diff --git a/libavcodec/rv30.c b/libavcodec/rv30.c index e60c93db4b..2a44363e4f 100644 --- a/libavcodec/rv30.c +++ b/libavcodec/rv30.c @@ -249,9 +249,11 @@ static void rv30_loop_filter(RV34DecContext *r, int row) static av_cold int rv30_decode_init(AVCodecContext *avctx) { RV34DecContext *r = avctx->priv_data; + int ret; r->rv30 = 1; - ff_rv34_decode_init(avctx); + if ((ret = ff_rv34_decode_init(avctx)) < 0) + return ret; if(avctx->extradata_size < 2){ av_log(avctx, AV_LOG_ERROR, "Extradata is too small.\n"); return -1; diff --git a/libavcodec/rv34.c b/libavcodec/rv34.c index e09d5dcf14..daf0baabc8 100644 --- a/libavcodec/rv34.c +++ b/libavcodec/rv34.c @@ -131,10 +131,10 @@ static void rv34_gen_vlc(const uint8_t *bits, int size, VLC *vlc, const uint8_t vlc->table = &table_data[table_offs[num]]; vlc->table_allocated = table_offs[num + 1] - table_offs[num]; - init_vlc_sparse(vlc, FFMIN(maxbits, 9), realsize, - bits2, 1, 1, - cw, 2, 2, - syms, 2, 2, INIT_VLC_USE_NEW_STATIC); + ff_init_vlc_sparse(vlc, FFMIN(maxbits, 9), realsize, + bits2, 1, 1, + cw, 2, 2, + syms, 2, 2, INIT_VLC_USE_NEW_STATIC); } /** @@ -711,8 +711,7 @@ static inline void rv34_mc(RV34DecContext *r, const int block_type, if (HAVE_THREADS && (s->avctx->active_thread_type & FF_THREAD_FRAME)) { /* wait for the referenced mb row to be finished */ - int mb_row = FFMIN(s->mb_height - 1, - s->mb_y + ((yoff + my + 5 + 8 * height) >> 4)); + int mb_row = s->mb_y + ((yoff + my + 5 + 8 * height) >> 4); AVFrame *f = dir ? &s->next_picture_ptr->f : &s->last_picture_ptr->f; ff_thread_await_progress(f, mb_row, 0); } @@ -1361,11 +1360,58 @@ static int check_slice_end(RV34DecContext *r, MpegEncContext *s) return 0; } + +static void rv34_decoder_free(RV34DecContext *r) +{ + av_freep(&r->intra_types_hist); + r->intra_types = NULL; + av_freep(&r->tmp_b_block_base); + av_freep(&r->mb_type); + av_freep(&r->cbp_luma); + av_freep(&r->cbp_chroma); + av_freep(&r->deblock_coefs); +} + + +static int rv34_decoder_alloc(RV34DecContext *r) +{ + r->intra_types_stride = r->s.mb_width * 4 + 4; + + r->cbp_chroma = av_malloc(r->s.mb_stride * r->s.mb_height * + sizeof(*r->cbp_chroma)); + r->cbp_luma = av_malloc(r->s.mb_stride * r->s.mb_height * + sizeof(*r->cbp_luma)); + r->deblock_coefs = av_malloc(r->s.mb_stride * r->s.mb_height * + sizeof(*r->deblock_coefs)); + r->intra_types_hist = av_malloc(r->intra_types_stride * 4 * 2 * + sizeof(*r->intra_types_hist)); + r->mb_type = av_mallocz(r->s.mb_stride * r->s.mb_height * + sizeof(*r->mb_type)); + + if (!(r->cbp_chroma && r->cbp_luma && r->deblock_coefs && + r->intra_types_hist && r->mb_type)) { + rv34_decoder_free(r); + return AVERROR(ENOMEM); + } + + r->intra_types = r->intra_types_hist + r->intra_types_stride * 4; + + return 0; +} + + +static int rv34_decoder_realloc(RV34DecContext *r) +{ + rv34_decoder_free(r); + return rv34_decoder_alloc(r); +} + + static int rv34_decode_slice(RV34DecContext *r, int end, const uint8_t* buf, int buf_size) { MpegEncContext *s = &r->s; GetBitContext *gb = &s->gb; - int mb_pos; + int mb_pos, slice_type; int res; init_get_bits(&r->s.gb, buf, buf_size*8); @@ -1375,67 +1421,14 @@ static int rv34_decode_slice(RV34DecContext *r, int end, const uint8_t* buf, int return -1; } - if ((s->mb_x == 0 && s->mb_y == 0) || s->current_picture_ptr==NULL) { - if(s->width != r->si.width || s->height != r->si.height){ - av_log(s->avctx, AV_LOG_DEBUG, "Changing dimensions to %dx%d\n", r->si.width,r->si.height); - MPV_common_end(s); - s->width = r->si.width; - s->height = r->si.height; - avcodec_set_dimensions(s->avctx, s->width, s->height); - if(MPV_common_init(s) < 0) - return -1; - r->intra_types_stride = s->mb_width*4 + 4; - r->intra_types_hist = av_realloc(r->intra_types_hist, r->intra_types_stride * 4 * 2 * sizeof(*r->intra_types_hist)); - r->intra_types = r->intra_types_hist + r->intra_types_stride * 4; - r->mb_type = av_realloc(r->mb_type, r->s.mb_stride * r->s.mb_height * sizeof(*r->mb_type)); - r->cbp_luma = av_realloc(r->cbp_luma, r->s.mb_stride * r->s.mb_height * sizeof(*r->cbp_luma)); - r->cbp_chroma = av_realloc(r->cbp_chroma, r->s.mb_stride * r->s.mb_height * sizeof(*r->cbp_chroma)); - r->deblock_coefs = av_realloc(r->deblock_coefs, r->s.mb_stride * r->s.mb_height * sizeof(*r->deblock_coefs)); - av_freep(&r->tmp_b_block_base); - } - s->pict_type = r->si.type ? r->si.type : AV_PICTURE_TYPE_I; - if(MPV_frame_start(s, s->avctx) < 0) - return -1; - ff_er_frame_start(s); - if (!r->tmp_b_block_base) { - int i; - - r->tmp_b_block_base = av_malloc(s->linesize * 48); - for (i = 0; i < 2; i++) - r->tmp_b_block_y[i] = r->tmp_b_block_base + i * 16 * s->linesize; - for (i = 0; i < 4; i++) - r->tmp_b_block_uv[i] = r->tmp_b_block_base + 32 * s->linesize - + (i >> 1) * 8 * s->uvlinesize + (i & 1) * 16; - } - r->cur_pts = r->si.pts; - if(s->pict_type != AV_PICTURE_TYPE_B){ - r->last_pts = r->next_pts; - r->next_pts = r->cur_pts; - }else{ - int refdist = GET_PTS_DIFF(r->next_pts, r->last_pts); - int dist0 = GET_PTS_DIFF(r->cur_pts, r->last_pts); - int dist1 = GET_PTS_DIFF(r->next_pts, r->cur_pts); - - if(!refdist){ - r->weight1 = r->weight2 = 8192; - }else{ - r->weight1 = (dist0 << 14) / refdist; - r->weight2 = (dist1 << 14) / refdist; - } - } - s->mb_x = s->mb_y = 0; - ff_thread_finish_setup(s->avctx); - } else { - int slice_type = r->si.type ? r->si.type : AV_PICTURE_TYPE_I; - - if (slice_type != s->pict_type) { - av_log(s->avctx, AV_LOG_ERROR, "Slice type mismatch\n"); - return AVERROR_INVALIDDATA; - } - if (s->width != r->si.width || s->height != r->si.height) { - av_log(s->avctx, AV_LOG_ERROR, "Size mismatch\n"); - return AVERROR_INVALIDDATA; - } + slice_type = r->si.type ? r->si.type : AV_PICTURE_TYPE_I; + if (slice_type != s->pict_type) { + av_log(s->avctx, AV_LOG_ERROR, "Slice type mismatch\n"); + return AVERROR_INVALIDDATA; + } + if (s->width != r->si.width || s->height != r->si.height) { + av_log(s->avctx, AV_LOG_ERROR, "Size mismatch\n"); + return AVERROR_INVALIDDATA; } r->si.end = end; @@ -1500,6 +1493,7 @@ av_cold int ff_rv34_decode_init(AVCodecContext *avctx) { RV34DecContext *r = avctx->priv_data; MpegEncContext *s = &r->s; + int ret; MPV_decode_defaults(s); s->avctx = avctx; @@ -1516,8 +1510,8 @@ av_cold int ff_rv34_decode_init(AVCodecContext *avctx) avctx->has_b_frames = 1; s->low_delay = 0; - if (MPV_common_init(s) < 0) - return -1; + if ((ret = MPV_common_init(s)) < 0) + return ret; ff_h264_pred_init(&r->h, CODEC_ID_RV40, 8, 1); @@ -1530,15 +1524,8 @@ av_cold int ff_rv34_decode_init(AVCodecContext *avctx) ff_rv40dsp_init(&r->rdsp, &r->s.dsp); #endif - r->intra_types_stride = 4*s->mb_stride + 4; - r->intra_types_hist = av_malloc(r->intra_types_stride * 4 * 2 * sizeof(*r->intra_types_hist)); - r->intra_types = r->intra_types_hist + r->intra_types_stride * 4; - - r->mb_type = av_mallocz(r->s.mb_stride * r->s.mb_height * sizeof(*r->mb_type)); - - r->cbp_luma = av_malloc(r->s.mb_stride * r->s.mb_height * sizeof(*r->cbp_luma)); - r->cbp_chroma = av_malloc(r->s.mb_stride * r->s.mb_height * sizeof(*r->cbp_chroma)); - r->deblock_coefs = av_malloc(r->s.mb_stride * r->s.mb_height * sizeof(*r->deblock_coefs)); + if ((ret = rv34_decoder_alloc(r)) < 0) + return ret; if(!intra_vlcs[0].cbppattern[0].bits) rv34_init_tables(); @@ -1548,40 +1535,17 @@ av_cold int ff_rv34_decode_init(AVCodecContext *avctx) int ff_rv34_decode_init_thread_copy(AVCodecContext *avctx) { + int err; RV34DecContext *r = avctx->priv_data; r->s.avctx = avctx; if (avctx->internal->is_copy) { - r->cbp_chroma = av_malloc(r->s.mb_stride * r->s.mb_height * - sizeof(*r->cbp_chroma)); - r->cbp_luma = av_malloc(r->s.mb_stride * r->s.mb_height * - sizeof(*r->cbp_luma)); - r->deblock_coefs = av_malloc(r->s.mb_stride * r->s.mb_height * - sizeof(*r->deblock_coefs)); - r->intra_types_hist = av_malloc(r->intra_types_stride * 4 * 2 * - sizeof(*r->intra_types_hist)); - r->mb_type = av_malloc(r->s.mb_stride * r->s.mb_height * - sizeof(*r->mb_type)); - - if (!(r->cbp_chroma && r->cbp_luma && r->deblock_coefs && - r->intra_types_hist && r->mb_type)) { - av_freep(&r->cbp_chroma); - av_freep(&r->cbp_luma); - av_freep(&r->deblock_coefs); - av_freep(&r->intra_types_hist); - av_freep(&r->mb_type); - r->intra_types = NULL; - return AVERROR(ENOMEM); - } - - r->intra_types = r->intra_types_hist + r->intra_types_stride * 4; r->tmp_b_block_base = NULL; - - memset(r->mb_type, 0, r->s.mb_stride * r->s.mb_height * - sizeof(*r->mb_type)); - - MPV_common_init(&r->s); + if ((err = MPV_common_init(&r->s)) < 0) + return err; + if ((err = rv34_decoder_alloc(r)) < 0) + return err; } return 0; } @@ -1595,6 +1559,16 @@ 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) { + MPV_common_end(s); + s->height = s1->height; + s->width = s1->width; + if ((err = MPV_common_init(s)) < 0) + return err; + if ((err = rv34_decoder_realloc(r)) < 0) + return err; + } + if ((err = ff_mpeg_update_thread_context(dst, src))) return err; @@ -1604,10 +1578,6 @@ int ff_rv34_decode_update_thread_context(AVCodecContext *dst, const AVCodecConte memset(&r->si, 0, sizeof(r->si)); - /* necessary since it is it the condition checked for in decode_slice - * to call MPV_frame_start. cmp. comment at the end of decode_frame */ - s->current_picture_ptr = NULL; - return 0; } @@ -1617,8 +1587,33 @@ static int get_slice_offset(AVCodecContext *avctx, const uint8_t *buf, int n) else return AV_RL32(buf + n*8 - 4) == 1 ? AV_RL32(buf + n*8) : AV_RB32(buf + n*8); } +static int finish_frame(AVCodecContext *avctx, AVFrame *pict) +{ + RV34DecContext *r = avctx->priv_data; + MpegEncContext *s = &r->s; + int got_picture = 0; + + ff_er_frame_end(s); + MPV_frame_end(s); + + if (HAVE_THREADS && (s->avctx->active_thread_type & FF_THREAD_FRAME)) + ff_thread_report_progress(&s->current_picture_ptr->f, INT_MAX, 0); + + if (s->pict_type == AV_PICTURE_TYPE_B || s->low_delay) { + *pict = s->current_picture_ptr->f; + got_picture = 1; + } else if (s->last_picture_ptr != NULL) { + *pict = s->last_picture_ptr->f; + got_picture = 1; + } + if (got_picture) + ff_print_debug_info(s, pict); + + return got_picture; +} + int ff_rv34_decode_frame(AVCodecContext *avctx, - void *data, int *data_size, + void *data, int *got_picture_ptr, AVPacket *avpkt) { const uint8_t *buf = avpkt->data; @@ -1636,10 +1631,10 @@ int ff_rv34_decode_frame(AVCodecContext *avctx, if (buf_size == 0) { /* special case for last picture */ if (s->low_delay==0 && s->next_picture_ptr) { - *pict = *(AVFrame*)s->next_picture_ptr; + *pict = s->next_picture_ptr->f; s->next_picture_ptr = NULL; - *data_size = sizeof(AVFrame); + *got_picture_ptr = 1; } return 0; } @@ -1656,20 +1651,95 @@ int ff_rv34_decode_frame(AVCodecContext *avctx, if(get_slice_offset(avctx, slices_hdr, 0) < 0 || get_slice_offset(avctx, slices_hdr, 0) > buf_size){ av_log(avctx, AV_LOG_ERROR, "Slice offset is invalid\n"); - return -1; + return AVERROR_INVALIDDATA; } init_get_bits(&s->gb, buf+get_slice_offset(avctx, slices_hdr, 0), (buf_size-get_slice_offset(avctx, slices_hdr, 0))*8); if(r->parse_slice_header(r, &r->s.gb, &si) < 0 || si.start){ av_log(avctx, AV_LOG_ERROR, "First slice header is incorrect\n"); - return -1; + return AVERROR_INVALIDDATA; + } + if ((!s->last_picture_ptr || !s->last_picture_ptr->f.data[0]) && + si.type == AV_PICTURE_TYPE_B) { + av_log(avctx, AV_LOG_ERROR, "Invalid decoder state: B-frame without " + "reference data.\n"); + return AVERROR_INVALIDDATA; } - if ((!s->last_picture_ptr || !s->last_picture_ptr->f.data[0]) && si.type == AV_PICTURE_TYPE_B) - return -1; if( (avctx->skip_frame >= AVDISCARD_NONREF && si.type==AV_PICTURE_TYPE_B) || (avctx->skip_frame >= AVDISCARD_NONKEY && si.type!=AV_PICTURE_TYPE_I) || avctx->skip_frame >= AVDISCARD_ALL) return avpkt->size; + /* first slice */ + if (si.start == 0) { + if (s->mb_num_left > 0) { + av_log(avctx, AV_LOG_ERROR, "New frame but still %d MB left.", + s->mb_num_left); + ff_er_frame_end(s); + MPV_frame_end(s); + } + + if (s->width != si.width || s->height != si.height) { + int err; + + if (HAVE_THREADS && + (s->avctx->active_thread_type & FF_THREAD_FRAME)) { + av_log_missing_feature(s->avctx, "Width/height changing with " + "frame threading is", 0); + return AVERROR_PATCHWELCOME; + } + + av_log(s->avctx, AV_LOG_WARNING, "Changing dimensions to %dx%d\n", + si.width, si.height); + MPV_common_end(s); + s->width = si.width; + s->height = si.height; + avcodec_set_dimensions(s->avctx, s->width, s->height); + if ((err = MPV_common_init(s)) < 0) + return err; + if ((err = rv34_decoder_realloc(r)) < 0) + return err; + } + s->pict_type = si.type ? si.type : AV_PICTURE_TYPE_I; + if (MPV_frame_start(s, s->avctx) < 0) + return -1; + ff_er_frame_start(s); + if (!r->tmp_b_block_base) { + int i; + + r->tmp_b_block_base = av_malloc(s->linesize * 48); + for (i = 0; i < 2; i++) + r->tmp_b_block_y[i] = r->tmp_b_block_base + + i * 16 * s->linesize; + for (i = 0; i < 4; i++) + r->tmp_b_block_uv[i] = r->tmp_b_block_base + 32 * s->linesize + + (i >> 1) * 8 * s->uvlinesize + + (i & 1) * 16; + } + r->cur_pts = si.pts; + if (s->pict_type != AV_PICTURE_TYPE_B) { + r->last_pts = r->next_pts; + r->next_pts = r->cur_pts; + } else { + int refdist = GET_PTS_DIFF(r->next_pts, r->last_pts); + int dist0 = GET_PTS_DIFF(r->cur_pts, r->last_pts); + int dist1 = GET_PTS_DIFF(r->next_pts, r->cur_pts); + + if (!refdist) { + r->weight1 = r->weight2 = 8192; + } else { + r->weight1 = (dist0 << 14) / refdist; + r->weight2 = (dist1 << 14) / refdist; + } + } + s->mb_x = s->mb_y = 0; + ff_thread_finish_setup(s->avctx); + } 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 " + "multithreading mode (start MB is %d).\n", si.start); + return AVERROR_INVALIDDATA; + } + for(i = 0; i < slice_count; i++){ int offset = get_slice_offset(avctx, slices_hdr, i); int size; @@ -1684,6 +1754,8 @@ int ff_rv34_decode_frame(AVCodecContext *avctx, } r->si.end = s->mb_width * s->mb_height; + s->mb_num_left = r->s.mb_x + r->s.mb_y*r->s.mb_width - r->si.start; + if(i+1 < slice_count){ if (get_slice_offset(avctx, slices_hdr, i+1) < 0 || get_slice_offset(avctx, slices_hdr, i+1) > buf_size) { @@ -1704,31 +1776,28 @@ int ff_rv34_decode_frame(AVCodecContext *avctx, break; } last = rv34_decode_slice(r, r->si.end, buf + offset, size); - s->mb_num_left = r->s.mb_x + r->s.mb_y*r->s.mb_width - r->si.start; if(last) break; } - if(last && s->current_picture_ptr){ - if(r->loop_filter) - r->loop_filter(r, s->mb_height - 1); - if (HAVE_THREADS && (s->avctx->active_thread_type & FF_THREAD_FRAME)) - ff_thread_report_progress(&s->current_picture_ptr->f, - s->mb_height - 1, 0); - ff_er_frame_end(s); - MPV_frame_end(s); - if (s->pict_type == AV_PICTURE_TYPE_B || s->low_delay) { - *pict = *(AVFrame*)s->current_picture_ptr; - } else if (s->last_picture_ptr != NULL) { - *pict = *(AVFrame*)s->last_picture_ptr; - } + if (s->current_picture_ptr) { + if (last) { + if(r->loop_filter) + r->loop_filter(r, s->mb_height - 1); - if(s->last_picture_ptr || s->low_delay){ - *data_size = sizeof(AVFrame); - ff_print_debug_info(s, pict); + *got_picture_ptr = finish_frame(avctx, pict); + } else if (HAVE_THREADS && + (s->avctx->active_thread_type & FF_THREAD_FRAME)) { + av_log(avctx, AV_LOG_INFO, "marking unfished frame as finished\n"); + /* always mark the current frame as finished, frame-mt supports + * only complete frames */ + ff_er_frame_end(s); + MPV_frame_end(s); + ff_thread_report_progress(&s->current_picture_ptr->f, INT_MAX, 0); + return AVERROR_INVALIDDATA; } - s->current_picture_ptr = NULL; //so we can detect if frame_end wasnt called (find some nicer solution...) } + return avpkt->size; } @@ -1737,14 +1806,7 @@ av_cold int ff_rv34_decode_end(AVCodecContext *avctx) RV34DecContext *r = avctx->priv_data; MPV_common_end(&r->s); - - av_freep(&r->intra_types_hist); - r->intra_types = NULL; - av_freep(&r->tmp_b_block_base); - av_freep(&r->mb_type); - av_freep(&r->cbp_luma); - av_freep(&r->cbp_chroma); - av_freep(&r->deblock_coefs); + rv34_decoder_free(r); return 0; } diff --git a/libavcodec/rv34data.h b/libavcodec/rv34data.h index 8be26a3943..4b2701fee6 100644 --- a/libavcodec/rv34data.h +++ b/libavcodec/rv34data.h @@ -101,7 +101,7 @@ static const uint8_t rv34_quant_to_vlc_set[2][31] = { /** * table for obtaining the quantizer difference - * @todo Use with modified_quant_tab from h263data.h. + * @todo Use with ff_modified_quant_tab from h263data.h. */ static const uint8_t rv34_dquant_tab[2][32]={ // 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 diff --git a/libavcodec/rv34dsp.c b/libavcodec/rv34dsp.c index e2251773af..919703d1e3 100644 --- a/libavcodec/rv34dsp.c +++ b/libavcodec/rv34dsp.c @@ -55,7 +55,6 @@ static av_always_inline void rv34_row_transform(int temp[16], DCTELEM *block) */ static void rv34_idct_add_c(uint8_t *dst, int stride, DCTELEM *block){ int temp[16]; - uint8_t *cm = ff_cropTbl + MAX_NEG_CROP; int i; rv34_row_transform(temp, block); @@ -67,10 +66,10 @@ static void rv34_idct_add_c(uint8_t *dst, int stride, DCTELEM *block){ const int z2 = 7* temp[4*1+i] - 17*temp[4*3+i]; const int z3 = 17* temp[4*1+i] + 7*temp[4*3+i]; - dst[0] = cm[ dst[0] + ( (z0 + z3) >> 10 ) ]; - dst[1] = cm[ dst[1] + ( (z1 + z2) >> 10 ) ]; - dst[2] = cm[ dst[2] + ( (z1 - z2) >> 10 ) ]; - dst[3] = cm[ dst[3] + ( (z0 - z3) >> 10 ) ]; + dst[0] = av_clip_uint8( dst[0] + ( (z0 + z3) >> 10 ) ); + dst[1] = av_clip_uint8( dst[1] + ( (z1 + z2) >> 10 ) ); + dst[2] = av_clip_uint8( dst[2] + ( (z1 - z2) >> 10 ) ); + dst[3] = av_clip_uint8( dst[3] + ( (z0 - z3) >> 10 ) ); dst += stride; } @@ -103,15 +102,13 @@ static void rv34_inv_transform_noround_c(DCTELEM *block){ static void rv34_idct_dc_add_c(uint8_t *dst, int stride, int dc) { - const uint8_t *cm = ff_cropTbl + MAX_NEG_CROP; int i, j; - cm += (13*13*dc + 0x200) >> 10; - + dc = (13*13*dc + 0x200) >> 10; for (i = 0; i < 4; i++) { for (j = 0; j < 4; j++) - dst[j] = cm[ dst[j] ]; + dst[j] = av_clip_uint8( dst[j] + dc ); dst += stride; } diff --git a/libavcodec/rv40.c b/libavcodec/rv40.c index 3bd1826b70..c46b7ef7e1 100644 --- a/libavcodec/rv40.c +++ b/libavcodec/rv40.c @@ -80,18 +80,18 @@ static av_cold void rv40_init_tables(void) for(i = 0; i < NUM_PTYPE_VLCS; i++){ ptype_vlc[i].table = &ptype_table[i << PTYPE_VLC_BITS]; ptype_vlc[i].table_allocated = 1 << PTYPE_VLC_BITS; - init_vlc_sparse(&ptype_vlc[i], PTYPE_VLC_BITS, PTYPE_VLC_SIZE, - ptype_vlc_bits[i], 1, 1, - ptype_vlc_codes[i], 1, 1, - ptype_vlc_syms, 1, 1, INIT_VLC_USE_NEW_STATIC); + ff_init_vlc_sparse(&ptype_vlc[i], PTYPE_VLC_BITS, PTYPE_VLC_SIZE, + ptype_vlc_bits[i], 1, 1, + ptype_vlc_codes[i], 1, 1, + ptype_vlc_syms, 1, 1, INIT_VLC_USE_NEW_STATIC); } for(i = 0; i < NUM_BTYPE_VLCS; i++){ btype_vlc[i].table = &btype_table[i << BTYPE_VLC_BITS]; btype_vlc[i].table_allocated = 1 << BTYPE_VLC_BITS; - init_vlc_sparse(&btype_vlc[i], BTYPE_VLC_BITS, BTYPE_VLC_SIZE, - btype_vlc_bits[i], 1, 1, - btype_vlc_codes[i], 1, 1, - btype_vlc_syms, 1, 1, INIT_VLC_USE_NEW_STATIC); + ff_init_vlc_sparse(&btype_vlc[i], BTYPE_VLC_BITS, BTYPE_VLC_SIZE, + btype_vlc_bits[i], 1, 1, + btype_vlc_codes[i], 1, 1, + btype_vlc_syms, 1, 1, INIT_VLC_USE_NEW_STATIC); } } @@ -544,9 +544,11 @@ static void rv40_loop_filter(RV34DecContext *r, int row) static av_cold int rv40_decode_init(AVCodecContext *avctx) { RV34DecContext *r = avctx->priv_data; + int ret; r->rv30 = 0; - ff_rv34_decode_init(avctx); + if ((ret = ff_rv34_decode_init(avctx)) < 0) + return ret; if(!aic_top_vlc.bits) rv40_init_tables(); r->parse_slice_header = rv40_parse_slice_header; diff --git a/libavcodec/s302m.c b/libavcodec/s302m.c index 4a17fa102e..828d0ba207 100644 --- a/libavcodec/s302m.c +++ b/libavcodec/s302m.c @@ -22,6 +22,7 @@ #include "libavutil/intreadwrite.h" #include "avcodec.h" +#include "internal.h" #define AES3_HEADER_LEN 4 @@ -104,7 +105,7 @@ static int s302m_decode_frame(AVCodecContext *avctx, void *data, /* get output buffer */ block_size = (avctx->bits_per_coded_sample + 4) / 4; s->frame.nb_samples = 2 * (buf_size / block_size) / avctx->channels; - if ((ret = avctx->get_buffer(avctx, &s->frame)) < 0) { + if ((ret = ff_get_buffer(avctx, &s->frame)) < 0) { av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n"); return ret; } diff --git a/libavcodec/sgidec.c b/libavcodec/sgidec.c index 6a98718131..d6f9949744 100644 --- a/libavcodec/sgidec.c +++ b/libavcodec/sgidec.c @@ -26,6 +26,7 @@ #include "sgi.h" typedef struct SgiState { + AVCodecContext *avctx; AVFrame picture; unsigned int width; unsigned int height; @@ -39,12 +40,12 @@ typedef struct SgiState { * Expand an RLE row into a channel. * @param s the current image state * @param out_buf Points to one line after the output buffer. - * @param out_end end of line in output buffer + * @param len length of out_buf in bytes * @param pixelstride pixel stride of input buffer * @return size of output in bytes, -1 if buffer overflows */ static int expand_rle_row(SgiState *s, uint8_t *out_buf, - uint8_t *out_end, int pixelstride) + int len, int pixelstride) { unsigned char pixel, count; unsigned char *orig = out_buf; @@ -58,7 +59,10 @@ static int expand_rle_row(SgiState *s, uint8_t *out_buf, } /* Check for buffer overflow. */ - if(out_buf + pixelstride * count >= out_end) return -1; + if (pixelstride * (count - 1) >= len) { + av_log(s->avctx, AV_LOG_ERROR, "Invalid pixel count.\n"); + return AVERROR_INVALIDDATA; + } if (pixel & 0x80) { while (count--) { @@ -101,7 +105,7 @@ static int read_rle_sgi(uint8_t *out_buf, SgiState *s) dest_row -= s->linesize; start_offset = bytestream2_get_be32(&g_table); bytestream2_seek(&s->g, start_offset, SEEK_SET); - if (expand_rle_row(s, dest_row + z, dest_row + FFABS(s->linesize), + if (expand_rle_row(s, dest_row + z, FFABS(s->linesize) - z, s->depth) != s->width) { return AVERROR_INVALIDDATA; } @@ -243,6 +247,8 @@ static int decode_frame(AVCodecContext *avctx, static av_cold int sgi_init(AVCodecContext *avctx){ SgiState *s = avctx->priv_data; + s->avctx = avctx; + avcodec_get_frame_defaults(&s->picture); avctx->coded_frame = &s->picture; diff --git a/libavcodec/shorten.c b/libavcodec/shorten.c index ef58aaa6aa..d1dc0dd94f 100644 --- a/libavcodec/shorten.c +++ b/libavcodec/shorten.c @@ -28,6 +28,7 @@ #include #include "avcodec.h" +#include "internal.h" #include "bytestream.h" #include "get_bits.h" #include "golomb.h" @@ -83,7 +84,7 @@ typedef struct ShortenContext { GetBitContext gb; int min_framesize, max_framesize; - int channels; + unsigned channels; int32_t *decoded[MAX_CHANNELS]; int32_t *decoded_base[MAX_CHANNELS]; @@ -108,10 +109,10 @@ typedef struct ShortenContext { int got_quit_command; } ShortenContext; -static av_cold int shorten_decode_init(AVCodecContext * avctx) +static av_cold int shorten_decode_init(AVCodecContext *avctx) { ShortenContext *s = avctx->priv_data; - s->avctx = avctx; + s->avctx = avctx; avctx->sample_fmt = AV_SAMPLE_FMT_S16; avcodec_get_frame_defaults(&s->frame); @@ -126,26 +127,30 @@ static int allocate_buffers(ShortenContext *s) int *coeffs; void *tmp_ptr; - for (chan=0; chanchannels; chan++) { - if(FFMAX(1, s->nmean) >= UINT_MAX/sizeof(int32_t)){ + for (chan = 0; chan < s->channels; chan++) { + if (FFMAX(1, s->nmean) >= UINT_MAX / sizeof(int32_t)) { av_log(s->avctx, AV_LOG_ERROR, "nmean too large\n"); - return -1; + return AVERROR_INVALIDDATA; } - if(s->blocksize + s->nwrap >= UINT_MAX/sizeof(int32_t) || s->blocksize + s->nwrap <= (unsigned)s->nwrap){ - av_log(s->avctx, AV_LOG_ERROR, "s->blocksize + s->nwrap too large\n"); - return -1; + if (s->blocksize + s->nwrap >= UINT_MAX / sizeof(int32_t) || + s->blocksize + s->nwrap <= (unsigned)s->nwrap) { + av_log(s->avctx, AV_LOG_ERROR, + "s->blocksize + s->nwrap too large\n"); + return AVERROR_INVALIDDATA; } - tmp_ptr = av_realloc(s->offset[chan], sizeof(int32_t)*FFMAX(1, s->nmean)); + tmp_ptr = + av_realloc(s->offset[chan], sizeof(int32_t) * FFMAX(1, s->nmean)); if (!tmp_ptr) return AVERROR(ENOMEM); s->offset[chan] = tmp_ptr; - tmp_ptr = av_realloc(s->decoded_base[chan], sizeof(int32_t)*(s->blocksize + s->nwrap)); + tmp_ptr = av_realloc(s->decoded_base[chan], (s->blocksize + s->nwrap) * + sizeof(s->decoded_base[0][0])); if (!tmp_ptr) return AVERROR(ENOMEM); s->decoded_base[chan] = tmp_ptr; - for (i=0; inwrap; i++) + for (i = 0; i < s->nwrap; i++) s->decoded_base[chan][i] = 0; s->decoded[chan] = s->decoded_base[chan] + s->nwrap; } @@ -158,7 +163,6 @@ static int allocate_buffers(ShortenContext *s) return 0; } - static inline unsigned int get_uint(ShortenContext *s, int k) { if (s->version != 0) @@ -166,7 +170,6 @@ static inline unsigned int get_uint(ShortenContext *s, int k) return get_ur_golomb_shorten(&s->gb, k); } - static void fix_bitshift(ShortenContext *s, int32_t *buffer) { int i; @@ -176,22 +179,20 @@ static void fix_bitshift(ShortenContext *s, int32_t *buffer) buffer[i] <<= s->bitshift; } - static int init_offset(ShortenContext *s) { int32_t mean = 0; - int chan, i; + int chan, i; int nblock = FFMAX(1, s->nmean); /* initialise offset */ - switch (s->internal_ftype) - { - case TYPE_S16HL: - case TYPE_S16LH: - mean = 0; - break; - default: - av_log(s->avctx, AV_LOG_ERROR, "unknown audio type"); - return AVERROR_INVALIDDATA; + switch (s->internal_ftype) { + case TYPE_S16HL: + case TYPE_S16LH: + mean = 0; + break; + default: + av_log(s->avctx, AV_LOG_ERROR, "unknown audio type"); + return AVERROR_INVALIDDATA; } for (chan = 0; chan < s->channels; chan++) @@ -205,52 +206,56 @@ static int decode_wave_header(AVCodecContext *avctx, const uint8_t *header, { int len; short wave_format; - const uint8_t *end= header + header_size; + GetByteContext gb; - if (bytestream_get_le32(&header) != MKTAG('R','I','F','F')) { + bytestream2_init(&gb, header, header_size); + + if (bytestream2_get_le32(&gb) != MKTAG('R', 'I', 'F', 'F')) { av_log(avctx, AV_LOG_ERROR, "missing RIFF tag\n"); - return -1; + return AVERROR_INVALIDDATA; } - header += 4; /* chunk size */; + bytestream2_skip(&gb, 4); /* chunk size */ - if (bytestream_get_le32(&header) != MKTAG('W','A','V','E')) { + if (bytestream2_get_le32(&gb) != MKTAG('W', 'A', 'V', 'E')) { av_log(avctx, AV_LOG_ERROR, "missing WAVE tag\n"); - return -1; + return AVERROR_INVALIDDATA; } - while (bytestream_get_le32(&header) != MKTAG('f','m','t',' ')) { - len = bytestream_get_le32(&header); - if(len<0 || end - header - 8 < len) + while (bytestream2_get_le32(&gb) != MKTAG('f', 'm', 't', ' ')) { + len = bytestream2_get_le32(&gb); + bytestream2_skip(&gb, len); + if (bytestream2_get_bytes_left(&gb) < 16) { + av_log(avctx, AV_LOG_ERROR, "no fmt chunk found\n"); return AVERROR_INVALIDDATA; - header += len; + } } - len = bytestream_get_le32(&header); + len = bytestream2_get_le32(&gb); if (len < 16) { av_log(avctx, AV_LOG_ERROR, "fmt chunk was too short\n"); - return -1; + return AVERROR_INVALIDDATA; } - wave_format = bytestream_get_le16(&header); + wave_format = bytestream2_get_le16(&gb); switch (wave_format) { - case WAVE_FORMAT_PCM: - break; - default: - av_log(avctx, AV_LOG_ERROR, "unsupported wave format\n"); - return -1; + case WAVE_FORMAT_PCM: + break; + default: + av_log(avctx, AV_LOG_ERROR, "unsupported wave format\n"); + return AVERROR(ENOSYS); } - header += 2; // skip channels (already got from shorten header) - avctx->sample_rate = bytestream_get_le32(&header); - header += 4; // skip bit rate (represents original uncompressed bit rate) - header += 2; // skip block align (not needed) - avctx->bits_per_coded_sample = bytestream_get_le16(&header); + bytestream2_skip(&gb, 2); // skip channels (already got from shorten header) + avctx->sample_rate = bytestream2_get_le32(&gb); + bytestream2_skip(&gb, 4); // skip bit rate (represents original uncompressed bit rate) + bytestream2_skip(&gb, 2); // skip block align (not needed) + avctx->bits_per_coded_sample = bytestream2_get_le16(&gb); if (avctx->bits_per_coded_sample != 16) { av_log(avctx, AV_LOG_ERROR, "unsupported number of bits per sample\n"); - return -1; + return AVERROR(ENOSYS); } len -= 16; @@ -285,11 +290,12 @@ static int decode_subframe_lpc(ShortenContext *s, int command, int channel, /* read/validate prediction order */ pred_order = get_ur_golomb_shorten(&s->gb, LPCQSIZE); if (pred_order > s->nwrap) { - av_log(s->avctx, AV_LOG_ERROR, "invalid pred_order %d\n", pred_order); + av_log(s->avctx, AV_LOG_ERROR, "invalid pred_order %d\n", + pred_order); return AVERROR(EINVAL); } /* read LPC coefficients */ - for (i=0; icoeffs[i] = get_sr_golomb_shorten(&s->gb, LPCQUANT); coeffs = s->coeffs; @@ -297,7 +303,7 @@ static int decode_subframe_lpc(ShortenContext *s, int command, int channel, } else { /* fixed LPC coeffs */ pred_order = command; - coeffs = fixed_coeffs[pred_order-1]; + coeffs = fixed_coeffs[pred_order - 1]; qshift = 0; } @@ -308,11 +314,12 @@ static int decode_subframe_lpc(ShortenContext *s, int command, int channel, /* decode residual and do LPC prediction */ init_sum = pred_order ? (command == FN_QLPC ? s->lpcqoffset : 0) : coffset; - for (i=0; i < s->blocksize; i++) { + for (i = 0; i < s->blocksize; i++) { sum = init_sum; - for (j=0; jdecoded[channel][i-j-1]; - s->decoded[channel][i] = get_sr_golomb_shorten(&s->gb, residual_size) + (sum >> qshift); + for (j = 0; j < pred_order; j++) + sum += coeffs[j] * s->decoded[channel][i - j - 1]; + s->decoded[channel][i] = get_sr_golomb_shorten(&s->gb, residual_size) + + (sum >> qshift); } /* add offset to current samples */ @@ -330,41 +337,47 @@ static int read_header(ShortenContext *s) /* shorten signature */ if (get_bits_long(&s->gb, 32) != AV_RB32("ajkg")) { av_log(s->avctx, AV_LOG_ERROR, "missing shorten magic 'ajkg'\n"); - return -1; + return AVERROR_INVALIDDATA; } - s->lpcqoffset = 0; - s->blocksize = DEFAULT_BLOCK_SIZE; - s->nmean = -1; - s->version = get_bits(&s->gb, 8); + s->lpcqoffset = 0; + s->blocksize = DEFAULT_BLOCK_SIZE; + s->nmean = -1; + s->version = get_bits(&s->gb, 8); s->internal_ftype = get_uint(s, TYPESIZE); s->channels = get_uint(s, CHANSIZE); + if (!s->channels) { + av_log(s->avctx, AV_LOG_ERROR, "No channels reported\n"); + return AVERROR_INVALIDDATA; + } if (s->channels > MAX_CHANNELS) { av_log(s->avctx, AV_LOG_ERROR, "too many channels: %d\n", s->channels); - return -1; + s->channels = 0; + return AVERROR_INVALIDDATA; } s->avctx->channels = s->channels; /* get blocksize if version > 0 */ if (s->version > 0) { - int skip_bytes, blocksize; + int skip_bytes; + unsigned blocksize; blocksize = get_uint(s, av_log2(DEFAULT_BLOCK_SIZE)); if (!blocksize || blocksize > MAX_BLOCKSIZE) { - av_log(s->avctx, AV_LOG_ERROR, "invalid or unsupported block size: %d\n", + av_log(s->avctx, AV_LOG_ERROR, + "invalid or unsupported block size: %d\n", blocksize); return AVERROR(EINVAL); } s->blocksize = blocksize; - maxnlpc = get_uint(s, LPCQSIZE); + maxnlpc = get_uint(s, LPCQSIZE); s->nmean = get_uint(s, 0); skip_bytes = get_uint(s, NSKIPSIZE); - for (i=0; igb, 8); - } } s->nwrap = FFMAX(NWRAP, maxnlpc); @@ -378,21 +391,24 @@ static int read_header(ShortenContext *s) s->lpcqoffset = V2LPCQOFFSET; if (get_ur_golomb_shorten(&s->gb, FNSIZE) != FN_VERBATIM) { - av_log(s->avctx, AV_LOG_ERROR, "missing verbatim section at beginning of stream\n"); - return -1; + av_log(s->avctx, AV_LOG_ERROR, + "missing verbatim section at beginning of stream\n"); + return AVERROR_INVALIDDATA; } s->header_size = get_ur_golomb_shorten(&s->gb, VERBATIM_CKSIZE_SIZE); - if (s->header_size >= OUT_BUFFER_SIZE || s->header_size < CANONICAL_HEADER_SIZE) { - av_log(s->avctx, AV_LOG_ERROR, "header is wrong size: %d\n", s->header_size); - return -1; + if (s->header_size >= OUT_BUFFER_SIZE || + s->header_size < CANONICAL_HEADER_SIZE) { + av_log(s->avctx, AV_LOG_ERROR, "header is wrong size: %d\n", + s->header_size); + return AVERROR_INVALIDDATA; } - for (i=0; iheader_size; i++) + for (i = 0; i < s->header_size; i++) s->header[i] = (char)get_ur_golomb_shorten(&s->gb, VERBATIM_BYTE_SIZE); - if (decode_wave_header(s->avctx, s->header, s->header_size) < 0) - return -1; + if ((ret = decode_wave_header(s->avctx, s->header, s->header_size)) < 0) + return ret; s->cur_chan = 0; s->bitshift = 0; @@ -406,17 +422,17 @@ static int shorten_decode_frame(AVCodecContext *avctx, void *data, int *got_frame_ptr, AVPacket *avpkt) { const uint8_t *buf = avpkt->data; - int buf_size = avpkt->size; - ShortenContext *s = avctx->priv_data; + int buf_size = avpkt->size; + ShortenContext *s = avctx->priv_data; int i, input_buf_size = 0; int ret; /* allocate internal bitstream buffer */ - if(s->max_framesize == 0){ + if (s->max_framesize == 0) { void *tmp_ptr; - s->max_framesize= 1024; // should hopefully be enough for the first header + s->max_framesize = 1024; // should hopefully be enough for the first header tmp_ptr = av_fast_realloc(s->bitstream, &s->allocated_bitstream_size, - s->max_framesize); + s->max_framesize + FF_INPUT_BUFFER_PADDING_SIZE); if (!tmp_ptr) { av_log(avctx, AV_LOG_ERROR, "error allocating bitstream buffer\n"); return AVERROR(ENOMEM); @@ -425,29 +441,32 @@ static int shorten_decode_frame(AVCodecContext *avctx, void *data, } /* append current packet data to bitstream buffer */ - if(1 && s->max_framesize){//FIXME truncated - buf_size= FFMIN(buf_size, s->max_framesize - s->bitstream_size); - input_buf_size= buf_size; + if (1 && s->max_framesize) { //FIXME truncated + buf_size = FFMIN(buf_size, s->max_framesize - s->bitstream_size); + input_buf_size = buf_size; - if(s->bitstream_index + s->bitstream_size + buf_size > s->allocated_bitstream_size){ - memmove(s->bitstream, &s->bitstream[s->bitstream_index], s->bitstream_size); - s->bitstream_index=0; + if (s->bitstream_index + s->bitstream_size + buf_size > + s->allocated_bitstream_size) { + memmove(s->bitstream, &s->bitstream[s->bitstream_index], + s->bitstream_size); + s->bitstream_index = 0; } if (buf) - memcpy(&s->bitstream[s->bitstream_index + s->bitstream_size], buf, buf_size); - buf= &s->bitstream[s->bitstream_index]; - buf_size += s->bitstream_size; - s->bitstream_size= buf_size; + memcpy(&s->bitstream[s->bitstream_index + s->bitstream_size], buf, + buf_size); + buf = &s->bitstream[s->bitstream_index]; + buf_size += s->bitstream_size; + s->bitstream_size = buf_size; /* do not decode until buffer has at least max_framesize bytes or - the end of the file has been reached */ + * the end of the file has been reached */ if (buf_size < s->max_framesize && avpkt->data) { *got_frame_ptr = 0; return input_buf_size; } } /* init and position bitstream reader */ - init_get_bits(&s->gb, buf, buf_size*8); + init_get_bits(&s->gb, buf, buf_size * 8); skip_bits(&s->gb, s->bitindex); /* process header or next subblock */ @@ -469,7 +488,7 @@ static int shorten_decode_frame(AVCodecContext *avctx, void *data, int cmd; int len; - if (get_bits_left(&s->gb) < 3+FNSIZE) { + if (get_bits_left(&s->gb) < 3 + FNSIZE) { *got_frame_ptr = 0; break; } @@ -485,32 +504,32 @@ static int shorten_decode_frame(AVCodecContext *avctx, void *data, if (!is_audio_command[cmd]) { /* process non-audio command */ switch (cmd) { - case FN_VERBATIM: - len = get_ur_golomb_shorten(&s->gb, VERBATIM_CKSIZE_SIZE); - while (len--) { - get_ur_golomb_shorten(&s->gb, VERBATIM_BYTE_SIZE); - } - break; - case FN_BITSHIFT: - s->bitshift = get_ur_golomb_shorten(&s->gb, BITSHIFTSIZE); - break; - case FN_BLOCKSIZE: { - int blocksize = get_uint(s, av_log2(s->blocksize)); - if (blocksize > s->blocksize) { - av_log(avctx, AV_LOG_ERROR, "Increasing block size is not supported\n"); - return AVERROR_PATCHWELCOME; - } - if (!blocksize || blocksize > MAX_BLOCKSIZE) { - av_log(avctx, AV_LOG_ERROR, "invalid or unsupported " - "block size: %d\n", blocksize); - return AVERROR(EINVAL); - } - s->blocksize = blocksize; - break; + case FN_VERBATIM: + len = get_ur_golomb_shorten(&s->gb, VERBATIM_CKSIZE_SIZE); + while (len--) + get_ur_golomb_shorten(&s->gb, VERBATIM_BYTE_SIZE); + break; + case FN_BITSHIFT: + s->bitshift = get_ur_golomb_shorten(&s->gb, BITSHIFTSIZE); + break; + case FN_BLOCKSIZE: { + unsigned blocksize = get_uint(s, av_log2(s->blocksize)); + if (blocksize > s->blocksize) { + av_log(avctx, AV_LOG_ERROR, + "Increasing block size is not supported\n"); + return AVERROR_PATCHWELCOME; } - case FN_QUIT: - s->got_quit_command = 1; - break; + if (!blocksize || blocksize > MAX_BLOCKSIZE) { + av_log(avctx, AV_LOG_ERROR, "invalid or unsupported " + "block size: %d\n", blocksize); + return AVERROR(EINVAL); + } + s->blocksize = blocksize; + break; + } + case FN_QUIT: + s->got_quit_command = 1; + break; } if (cmd == FN_BLOCKSIZE || cmd == FN_QUIT) { *got_frame_ptr = 0; @@ -535,7 +554,7 @@ static int shorten_decode_frame(AVCodecContext *avctx, void *data, coffset = s->offset[channel][0]; else { int32_t sum = (s->version < 2) ? 0 : s->nmean / 2; - for (i=0; inmean; i++) + for (i = 0; i < s->nmean; i++) sum += s->offset[channel][i]; coffset = sum / s->nmean; if (s->version >= 2) @@ -544,21 +563,22 @@ static int shorten_decode_frame(AVCodecContext *avctx, void *data, /* decode samples for this channel */ if (cmd == FN_ZERO) { - for (i=0; iblocksize; i++) + for (i = 0; i < s->blocksize; i++) s->decoded[channel][i] = 0; } else { - if ((ret = decode_subframe_lpc(s, cmd, channel, residual_size, coffset)) < 0) + if ((ret = decode_subframe_lpc(s, cmd, channel, + residual_size, coffset)) < 0) return ret; } /* update means with info from the current block */ if (s->nmean > 0) { int32_t sum = (s->version < 2) ? 0 : s->blocksize / 2; - for (i=0; iblocksize; i++) + for (i = 0; i < s->blocksize; i++) sum += s->decoded[channel][i]; - for (i=1; inmean; i++) - s->offset[channel][i-1] = s->offset[channel][i]; + for (i = 1; i < s->nmean; i++) + s->offset[channel][i - 1] = s->offset[channel][i]; if (s->version < 2) s->offset[channel][s->nmean - 1] = sum / s->blocksize; @@ -567,11 +587,11 @@ static int shorten_decode_frame(AVCodecContext *avctx, void *data, } /* copy wrap samples for use with next block */ - for (i=-s->nwrap; i<0; i++) + for (i = -s->nwrap; i < 0; i++) s->decoded[channel][i] = s->decoded[channel][i + s->blocksize]; /* shift samples to add in unused zero bits which were removed - during encoding */ + * during encoding */ fix_bitshift(s, s->decoded[channel]); /* if this is the last channel in the block, output the samples */ @@ -579,7 +599,7 @@ static int shorten_decode_frame(AVCodecContext *avctx, void *data, if (s->cur_chan == s->channels) { /* get output buffer */ s->frame.nb_samples = s->blocksize; - if ((ret = avctx->get_buffer(avctx, &s->frame)) < 0) { + if ((ret = ff_get_buffer(avctx, &s->frame)) < 0) { av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n"); return ret; } @@ -596,13 +616,13 @@ static int shorten_decode_frame(AVCodecContext *avctx, void *data, *got_frame_ptr = 0; finish_frame: - s->bitindex = get_bits_count(&s->gb) - 8*((get_bits_count(&s->gb))/8); - i= (get_bits_count(&s->gb))/8; + s->bitindex = get_bits_count(&s->gb) - 8 * (get_bits_count(&s->gb) / 8); + i = get_bits_count(&s->gb) / 8; if (i > buf_size) { av_log(s->avctx, AV_LOG_ERROR, "overread: %d\n", i - buf_size); - s->bitstream_size=0; - s->bitstream_index=0; - return -1; + s->bitstream_size = 0; + s->bitstream_index = 0; + return AVERROR_INVALIDDATA; } if (s->bitstream_size) { s->bitstream_index += i; diff --git a/libavcodec/simple_idct.c b/libavcodec/simple_idct.c index 0676cf65fc..293185074b 100644 --- a/libavcodec/simple_idct.c +++ b/libavcodec/simple_idct.c @@ -53,7 +53,6 @@ static inline void idct4col_put(uint8_t *dest, int line_size, const DCTELEM *col) { int c0, c1, c2, c3, a0, a1, a2, a3; - const uint8_t *cm = ff_cropTbl + MAX_NEG_CROP; a0 = col[8*0]; a1 = col[8*2]; @@ -63,13 +62,13 @@ static inline void idct4col_put(uint8_t *dest, int line_size, const DCTELEM *col c2 = ((a0 - a2) << (CN_SHIFT - 1)) + (1 << (C_SHIFT - 1)); c1 = a1 * C1 + a3 * C2; c3 = a1 * C2 - a3 * C1; - dest[0] = cm[(c0 + c1) >> C_SHIFT]; + dest[0] = av_clip_uint8((c0 + c1) >> C_SHIFT); dest += line_size; - dest[0] = cm[(c2 + c3) >> C_SHIFT]; + dest[0] = av_clip_uint8((c2 + c3) >> C_SHIFT); dest += line_size; - dest[0] = cm[(c2 - c3) >> C_SHIFT]; + dest[0] = av_clip_uint8((c2 - c3) >> C_SHIFT); dest += line_size; - dest[0] = cm[(c0 - c1) >> C_SHIFT]; + dest[0] = av_clip_uint8((c0 - c1) >> C_SHIFT); } #define BF(k) \ @@ -133,7 +132,6 @@ void ff_simple_idct248_put(uint8_t *dest, int line_size, DCTELEM *block) static inline void idct4col_add(uint8_t *dest, int line_size, const DCTELEM *col) { int c0, c1, c2, c3, a0, a1, a2, a3; - const uint8_t *cm = ff_cropTbl + MAX_NEG_CROP; a0 = col[8*0]; a1 = col[8*1]; @@ -143,13 +141,13 @@ static inline void idct4col_add(uint8_t *dest, int line_size, const DCTELEM *col c2 = (a0 - a2)*C3 + (1 << (C_SHIFT - 1)); c1 = a1 * C1 + a3 * C2; c3 = a1 * C2 - a3 * C1; - dest[0] = cm[dest[0] + ((c0 + c1) >> C_SHIFT)]; + dest[0] = av_clip_uint8(dest[0] + ((c0 + c1) >> C_SHIFT)); dest += line_size; - dest[0] = cm[dest[0] + ((c2 + c3) >> C_SHIFT)]; + dest[0] = av_clip_uint8(dest[0] + ((c2 + c3) >> C_SHIFT)); dest += line_size; - dest[0] = cm[dest[0] + ((c2 - c3) >> C_SHIFT)]; + dest[0] = av_clip_uint8(dest[0] + ((c2 - c3) >> C_SHIFT)); dest += line_size; - dest[0] = cm[dest[0] + ((c0 - c1) >> C_SHIFT)]; + dest[0] = av_clip_uint8(dest[0] + ((c0 - c1) >> C_SHIFT)); } #define RN_SHIFT 15 @@ -161,7 +159,6 @@ static inline void idct4col_add(uint8_t *dest, int line_size, const DCTELEM *col static inline void idct4row(DCTELEM *row) { int c0, c1, c2, c3, a0, a1, a2, a3; - //const uint8_t *cm = ff_cropTbl + MAX_NEG_CROP; a0 = row[0]; a1 = row[1]; diff --git a/libavcodec/simple_idct_template.c b/libavcodec/simple_idct_template.c index fdec3aab2b..3c855e3825 100644 --- a/libavcodec/simple_idct_template.c +++ b/libavcodec/simple_idct_template.c @@ -224,50 +224,48 @@ static inline void FUNC(idctSparseColPut)(pixel *dest, int line_size, DCTELEM *col) { int a0, a1, a2, a3, b0, b1, b2, b3; - INIT_CLIP; IDCT_COLS; - dest[0] = CLIP((a0 + b0) >> COL_SHIFT); + dest[0] = av_clip_pixel((a0 + b0) >> COL_SHIFT); dest += line_size; - dest[0] = CLIP((a1 + b1) >> COL_SHIFT); + dest[0] = av_clip_pixel((a1 + b1) >> COL_SHIFT); dest += line_size; - dest[0] = CLIP((a2 + b2) >> COL_SHIFT); + dest[0] = av_clip_pixel((a2 + b2) >> COL_SHIFT); dest += line_size; - dest[0] = CLIP((a3 + b3) >> COL_SHIFT); + dest[0] = av_clip_pixel((a3 + b3) >> COL_SHIFT); dest += line_size; - dest[0] = CLIP((a3 - b3) >> COL_SHIFT); + dest[0] = av_clip_pixel((a3 - b3) >> COL_SHIFT); dest += line_size; - dest[0] = CLIP((a2 - b2) >> COL_SHIFT); + dest[0] = av_clip_pixel((a2 - b2) >> COL_SHIFT); dest += line_size; - dest[0] = CLIP((a1 - b1) >> COL_SHIFT); + dest[0] = av_clip_pixel((a1 - b1) >> COL_SHIFT); dest += line_size; - dest[0] = CLIP((a0 - b0) >> COL_SHIFT); + dest[0] = av_clip_pixel((a0 - b0) >> COL_SHIFT); } static inline void FUNC(idctSparseColAdd)(pixel *dest, int line_size, DCTELEM *col) { int a0, a1, a2, a3, b0, b1, b2, b3; - INIT_CLIP; IDCT_COLS; - dest[0] = CLIP(dest[0] + ((a0 + b0) >> COL_SHIFT)); + dest[0] = av_clip_pixel(dest[0] + ((a0 + b0) >> COL_SHIFT)); dest += line_size; - dest[0] = CLIP(dest[0] + ((a1 + b1) >> COL_SHIFT)); + dest[0] = av_clip_pixel(dest[0] + ((a1 + b1) >> COL_SHIFT)); dest += line_size; - dest[0] = CLIP(dest[0] + ((a2 + b2) >> COL_SHIFT)); + dest[0] = av_clip_pixel(dest[0] + ((a2 + b2) >> COL_SHIFT)); dest += line_size; - dest[0] = CLIP(dest[0] + ((a3 + b3) >> COL_SHIFT)); + dest[0] = av_clip_pixel(dest[0] + ((a3 + b3) >> COL_SHIFT)); dest += line_size; - dest[0] = CLIP(dest[0] + ((a3 - b3) >> COL_SHIFT)); + dest[0] = av_clip_pixel(dest[0] + ((a3 - b3) >> COL_SHIFT)); dest += line_size; - dest[0] = CLIP(dest[0] + ((a2 - b2) >> COL_SHIFT)); + dest[0] = av_clip_pixel(dest[0] + ((a2 - b2) >> COL_SHIFT)); dest += line_size; - dest[0] = CLIP(dest[0] + ((a1 - b1) >> COL_SHIFT)); + dest[0] = av_clip_pixel(dest[0] + ((a1 - b1) >> COL_SHIFT)); dest += line_size; - dest[0] = CLIP(dest[0] + ((a0 - b0) >> COL_SHIFT)); + dest[0] = av_clip_pixel(dest[0] + ((a0 - b0) >> COL_SHIFT)); } static inline void FUNC(idctSparseCol)(DCTELEM *col) diff --git a/libavcodec/sipr.c b/libavcodec/sipr.c index 65440db224..ff7f07d477 100644 --- a/libavcodec/sipr.c +++ b/libavcodec/sipr.c @@ -27,6 +27,7 @@ #include "libavutil/mathematics.h" #include "avcodec.h" +#include "internal.h" #define BITSTREAM_READER_LE #include "get_bits.h" #include "dsputil.h" @@ -486,11 +487,13 @@ static av_cold int sipr_decoder_init(AVCodecContext * avctx) case 29: ctx->mode = MODE_6k5; break; case 37: ctx->mode = MODE_5k0; break; default: - av_log(avctx, AV_LOG_ERROR, "Invalid block_align: %d\n", avctx->block_align); if (avctx->bit_rate > 12200) ctx->mode = MODE_16k; else if (avctx->bit_rate > 7500 ) ctx->mode = MODE_8k5; else if (avctx->bit_rate > 5750 ) ctx->mode = MODE_6k5; else ctx->mode = MODE_5k0; + av_log(avctx, AV_LOG_WARNING, + "Invalid block_align: %d. Mode %s guessed based on bitrate: %d\n", + avctx->block_align, modes[ctx->mode].mode_name, avctx->bit_rate); } av_log(avctx, AV_LOG_DEBUG, "Mode: %s\n", modes[ctx->mode].mode_name); @@ -539,7 +542,7 @@ static int sipr_decode_frame(AVCodecContext *avctx, void *data, /* get output buffer */ ctx->frame.nb_samples = mode_par->frames_per_packet * subframe_size * mode_par->subframe_count; - if ((ret = avctx->get_buffer(avctx, &ctx->frame)) < 0) { + if ((ret = ff_get_buffer(avctx, &ctx->frame)) < 0) { av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n"); return ret; } diff --git a/libavcodec/smacker.c b/libavcodec/smacker.c index 2a8bae8a1b..12645b3849 100644 --- a/libavcodec/smacker.c +++ b/libavcodec/smacker.c @@ -32,6 +32,7 @@ #include #include "avcodec.h" +#include "internal.h" #include "libavutil/audioconvert.h" #include "mathops.h" @@ -128,12 +129,12 @@ static int smacker_decode_tree(GetBitContext *gb, HuffContext *hc, uint32_t pref */ static int smacker_decode_bigtree(GetBitContext *gb, HuffContext *hc, DBCtx *ctx) { + if (hc->current + 1 >= hc->length) { + av_log(NULL, AV_LOG_ERROR, "Tree size exceeded!\n"); + return -1; + } if(!get_bits1(gb)){ //Leaf int val, i1, i2, b1, b2; - if(hc->current >= hc->length){ - av_log(NULL, AV_LOG_ERROR, "Tree size exceeded!\n"); - return -1; - } b1 = get_bits_count(gb); i1 = ctx->v1->table ? get_vlc2(gb, ctx->v1->table, SMKTREE_BITS, 3) : 0; b1 = get_bits_count(gb) - b1; @@ -157,7 +158,7 @@ static int smacker_decode_bigtree(GetBitContext *gb, HuffContext *hc, DBCtx *ctx hc->values[hc->current++] = val; return 1; } else { //Node - int r = 0, t; + int r = 0, r_new, t; t = hc->current++; r = smacker_decode_bigtree(gb, hc, ctx); @@ -165,8 +166,10 @@ static int smacker_decode_bigtree(GetBitContext *gb, HuffContext *hc, DBCtx *ctx return r; hc->values[t] = SMK_NODE | r; r++; - r += smacker_decode_bigtree(gb, hc, ctx); - return r; + r_new = smacker_decode_bigtree(gb, hc, ctx); + if (r_new < 0) + return r_new; + return r + r_new; } } @@ -181,6 +184,7 @@ static int smacker_decode_header_tree(SmackVContext *smk, GetBitContext *gb, int VLC vlc[2]; int escapes[3]; DBCtx ctx; + int err = 0; if(size >= UINT_MAX>>4){ // (((size + 3) >> 2) + 3) << 2 must not overflow av_log(smk->avctx, AV_LOG_ERROR, "size too large\n"); @@ -249,28 +253,30 @@ static int smacker_decode_header_tree(SmackVContext *smk, GetBitContext *gb, int ctx.recode2 = tmp2.values; ctx.last = last; - huff.length = ((size + 3) >> 2) + 3; + huff.length = ((size + 3) >> 2) + 4; huff.maxlength = 0; huff.current = 0; huff.values = av_mallocz(huff.length * sizeof(int)); - smacker_decode_bigtree(gb, &huff, &ctx); + if (smacker_decode_bigtree(gb, &huff, &ctx) < 0) + err = -1; skip_bits1(gb); if(ctx.last[0] == -1) ctx.last[0] = huff.current++; if(ctx.last[1] == -1) ctx.last[1] = huff.current++; if(ctx.last[2] == -1) ctx.last[2] = huff.current++; - if(huff.current > huff.length){ - ctx.last[0] = ctx.last[1] = ctx.last[2] = 1; - av_log(smk->avctx, AV_LOG_ERROR, "bigtree damaged\n"); - return -1; + if (ctx.last[0] >= huff.length || + ctx.last[1] >= huff.length || + ctx.last[2] >= huff.length) { + av_log(smk->avctx, AV_LOG_ERROR, "Huffman codes out of range\n"); + err = AVERROR_INVALIDDATA; } *recodes = huff.values; if(vlc[0].table) - free_vlc(&vlc[0]); + ff_free_vlc(&vlc[0]); if(vlc[1].table) - free_vlc(&vlc[1]); + ff_free_vlc(&vlc[1]); av_free(tmp1.bits); av_free(tmp1.lengths); av_free(tmp1.values); @@ -278,7 +284,7 @@ static int smacker_decode_header_tree(SmackVContext *smk, GetBitContext *gb, int av_free(tmp2.lengths); av_free(tmp2.values); - return 0; + return err; } static int decode_header_trees(SmackVContext *smk) { @@ -632,7 +638,7 @@ static int smka_decode_frame(AVCodecContext *avctx, void *data, /* get output buffer */ s->frame.nb_samples = unp_size / (avctx->channels * (bits + 1)); - if ((ret = avctx->get_buffer(avctx, &s->frame)) < 0) { + if ((ret = ff_get_buffer(avctx, &s->frame)) < 0) { av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n"); return ret; } @@ -650,7 +656,16 @@ static int smka_decode_frame(AVCodecContext *avctx, void *data, h[i].lengths = av_mallocz(256 * sizeof(int)); h[i].values = av_mallocz(256 * sizeof(int)); skip_bits1(&gb); - smacker_decode_tree(&gb, &h[i], 0, 0); + if (smacker_decode_tree(&gb, &h[i], 0, 0) < 0) { + for (; i >= 0; i--) { + if (vlc[i].table) + ff_free_vlc(&vlc[i]); + av_free(h[i].bits); + av_free(h[i].lengths); + av_free(h[i].values); + } + return AVERROR_INVALIDDATA; + } skip_bits1(&gb); if(h[i].current > 1) { res = init_vlc(&vlc[i], SMKTREE_BITS, h[i].length, @@ -664,7 +679,7 @@ static int smka_decode_frame(AVCodecContext *avctx, void *data, } if(bits) { //decode 16-bit data for(i = stereo; i >= 0; i--) - pred[i] = av_bswap16(get_bits(&gb, 16)); + pred[i] = sign_extend(av_bswap16(get_bits(&gb, 16)), 16); for(i = 0; i <= stereo; i++) *samples++ = pred[i]; for(; i < unp_size / 2; i++) { @@ -682,7 +697,7 @@ static int smka_decode_frame(AVCodecContext *avctx, void *data, res = 0; val |= h[3].values[res] << 8; pred[1] += sign_extend(val, 16); - *samples++ = av_clip_int16(pred[1]); + *samples++ = pred[1]; } else { if(vlc[0].table) res = get_vlc2(&gb, vlc[0].table, SMKTREE_BITS, 3); @@ -695,7 +710,7 @@ static int smka_decode_frame(AVCodecContext *avctx, void *data, res = 0; val |= h[1].values[res] << 8; pred[0] += sign_extend(val, 16); - *samples++ = av_clip_int16(pred[0]); + *samples++ = pred[0]; } } } else { //8-bit data @@ -726,7 +741,7 @@ static int smka_decode_frame(AVCodecContext *avctx, void *data, for(i = 0; i < 4; i++) { if(vlc[i].table) - free_vlc(&vlc[i]); + ff_free_vlc(&vlc[i]); av_free(h[i].bits); av_free(h[i].lengths); av_free(h[i].values); diff --git a/libavcodec/smc.c b/libavcodec/smc.c index 9ae19ffb45..f65cbc66a9 100644 --- a/libavcodec/smc.c +++ b/libavcodec/smc.c @@ -34,6 +34,7 @@ #include "libavutil/intreadwrite.h" #include "avcodec.h" +#include "bytestream.h" #define CPAIR 2 #define CQUAD 4 @@ -46,8 +47,7 @@ typedef struct SmcContext { AVCodecContext *avctx; AVFrame frame; - const unsigned char *buf; - int size; + GetByteContext gb; /* SMC color tables */ unsigned char color_pairs[COLORS_PER_TABLE * CPAIR]; @@ -58,7 +58,7 @@ typedef struct SmcContext { } SmcContext; #define GET_BLOCK_COUNT() \ - (opcode & 0x10) ? (1 + s->buf[stream_ptr++]) : 1 + (opcode & 0x0F); + (opcode & 0x10) ? (1 + bytestream2_get_byte(&s->gb)) : 1 + (opcode & 0x0F); #define ADVANCE_BLOCK() \ { \ @@ -69,7 +69,7 @@ typedef struct SmcContext { row_ptr += stride * 4; \ } \ total_blocks--; \ - if (total_blocks < 0) \ + if (total_blocks < !!n_blocks) \ { \ av_log(s->avctx, AV_LOG_INFO, "warning: block counter just went negative (this should not happen)\n"); \ return; \ @@ -82,8 +82,8 @@ static void smc_decode_stream(SmcContext *s) int height = s->avctx->height; int stride = s->frame.linesize[0]; int i; - int stream_ptr = 0; int chunk_size; + int buf_size = (int) (s->gb.buffer_end - s->gb.buffer_start); unsigned char opcode; int n_blocks; unsigned int color_flags; @@ -113,24 +113,18 @@ static void smc_decode_stream(SmcContext *s) /* make the palette available */ memcpy(s->frame.data[1], s->pal, AVPALETTE_SIZE); - chunk_size = AV_RB32(&s->buf[stream_ptr]) & 0x00FFFFFF; - stream_ptr += 4; - if (chunk_size != s->size) + bytestream2_skip(&s->gb, 1); + chunk_size = bytestream2_get_be24(&s->gb); + if (chunk_size != buf_size) av_log(s->avctx, AV_LOG_INFO, "warning: MOV chunk size != encoded chunk size (%d != %d); using MOV chunk size\n", - chunk_size, s->size); + chunk_size, buf_size); - chunk_size = s->size; + chunk_size = buf_size; total_blocks = ((s->avctx->width + 3) / 4) * ((s->avctx->height + 3) / 4); /* traverse through the blocks */ while (total_blocks) { /* sanity checks */ - /* make sure stream ptr hasn't gone out of bounds */ - if (stream_ptr > chunk_size) { - av_log(s->avctx, AV_LOG_INFO, "SMC decoder just went out of bounds (stream ptr = %d, chunk size = %d)\n", - stream_ptr, chunk_size); - return; - } /* make sure the row pointer hasn't gone wild */ if (row_ptr >= image_size) { av_log(s->avctx, AV_LOG_INFO, "SMC decoder just went out of bounds (row ptr = %d, height = %d)\n", @@ -138,7 +132,7 @@ static void smc_decode_stream(SmcContext *s) return; } - opcode = s->buf[stream_ptr++]; + opcode = bytestream2_get_byte(&s->gb); switch (opcode & 0xF0) { /* skip n blocks */ case 0x00: @@ -158,7 +152,7 @@ static void smc_decode_stream(SmcContext *s) if ((row_ptr == 0) && (pixel_ptr == 0)) { av_log(s->avctx, AV_LOG_INFO, "encountered repeat block opcode (%02X) but no blocks rendered yet\n", opcode & 0xF0); - break; + return; } /* figure out where the previous block started */ @@ -192,7 +186,7 @@ static void smc_decode_stream(SmcContext *s) if ((row_ptr == 0) && (pixel_ptr < 2 * 4)) { av_log(s->avctx, AV_LOG_INFO, "encountered repeat block opcode (%02X) but not enough blocks rendered yet\n", opcode & 0xF0); - break; + return; } /* figure out where the previous 2 blocks started */ @@ -233,7 +227,7 @@ static void smc_decode_stream(SmcContext *s) case 0x60: case 0x70: n_blocks = GET_BLOCK_COUNT(); - pixel = s->buf[stream_ptr++]; + pixel = bytestream2_get_byte(&s->gb); while (n_blocks--) { block_ptr = row_ptr + pixel_ptr; @@ -257,7 +251,7 @@ static void smc_decode_stream(SmcContext *s) /* fetch the next 2 colors from bytestream and store in next * available entry in the color pair table */ for (i = 0; i < CPAIR; i++) { - pixel = s->buf[stream_ptr++]; + pixel = bytestream2_get_byte(&s->gb); color_table_index = CPAIR * color_pair_index + i; s->color_pairs[color_table_index] = pixel; } @@ -268,11 +262,10 @@ static void smc_decode_stream(SmcContext *s) if (color_pair_index == COLORS_PER_TABLE) color_pair_index = 0; } else - color_table_index = CPAIR * s->buf[stream_ptr++]; + color_table_index = CPAIR * bytestream2_get_byte(&s->gb); while (n_blocks--) { - color_flags = AV_RB16(&s->buf[stream_ptr]); - stream_ptr += 2; + color_flags = bytestream2_get_be16(&s->gb); flag_mask = 0x8000; block_ptr = row_ptr + pixel_ptr; for (pixel_y = 0; pixel_y < 4; pixel_y++) { @@ -300,7 +293,7 @@ static void smc_decode_stream(SmcContext *s) /* fetch the next 4 colors from bytestream and store in next * available entry in the color quad table */ for (i = 0; i < CQUAD; i++) { - pixel = s->buf[stream_ptr++]; + pixel = bytestream2_get_byte(&s->gb); color_table_index = CQUAD * color_quad_index + i; s->color_quads[color_table_index] = pixel; } @@ -311,11 +304,10 @@ static void smc_decode_stream(SmcContext *s) if (color_quad_index == COLORS_PER_TABLE) color_quad_index = 0; } else - color_table_index = CQUAD * s->buf[stream_ptr++]; + color_table_index = CQUAD * bytestream2_get_byte(&s->gb); while (n_blocks--) { - color_flags = AV_RB32(&s->buf[stream_ptr]); - stream_ptr += 4; + color_flags = bytestream2_get_be32(&s->gb); /* flag mask actually acts as a bit shift count here */ flag_mask = 30; block_ptr = row_ptr + pixel_ptr; @@ -342,7 +334,7 @@ static void smc_decode_stream(SmcContext *s) /* fetch the next 8 colors from bytestream and store in next * available entry in the color octet table */ for (i = 0; i < COCTET; i++) { - pixel = s->buf[stream_ptr++]; + pixel = bytestream2_get_byte(&s->gb); color_table_index = COCTET * color_octet_index + i; s->color_octets[color_table_index] = pixel; } @@ -353,7 +345,7 @@ static void smc_decode_stream(SmcContext *s) if (color_octet_index == COLORS_PER_TABLE) color_octet_index = 0; } else - color_table_index = COCTET * s->buf[stream_ptr++]; + color_table_index = COCTET * bytestream2_get_byte(&s->gb); while (n_blocks--) { /* @@ -363,15 +355,12 @@ static void smc_decode_stream(SmcContext *s) flags_a = xx012456, flags_b = xx89A37B */ /* build the color flags */ - color_flags_a = - ((AV_RB16(s->buf + stream_ptr ) & 0xFFF0) << 8) | - (AV_RB16(s->buf + stream_ptr + 2) >> 4); - color_flags_b = - ((AV_RB16(s->buf + stream_ptr + 4) & 0xFFF0) << 8) | - ((s->buf[stream_ptr + 1] & 0x0F) << 8) | - ((s->buf[stream_ptr + 3] & 0x0F) << 4) | - (s->buf[stream_ptr + 5] & 0x0F); - stream_ptr += 6; + int val1 = bytestream2_get_be16(&s->gb); + int val2 = bytestream2_get_be16(&s->gb); + int val3 = bytestream2_get_be16(&s->gb); + color_flags_a = ((val1 & 0xFFF0) << 8) | (val2 >> 4); + color_flags_b = ((val3 & 0xFFF0) << 8) | + ((val1 & 0x0F) << 8) | ((val2 & 0x0F) << 4) | (val3 & 0x0F); color_flags = color_flags_a; /* flag mask actually acts as a bit shift count here */ @@ -403,7 +392,7 @@ static void smc_decode_stream(SmcContext *s) block_ptr = row_ptr + pixel_ptr; for (pixel_y = 0; pixel_y < 4; pixel_y++) { for (pixel_x = 0; pixel_x < 4; pixel_x++) { - pixels[block_ptr++] = s->buf[stream_ptr++]; + pixels[block_ptr++] = bytestream2_get_byte(&s->gb); } block_ptr += row_inc; } @@ -412,10 +401,12 @@ static void smc_decode_stream(SmcContext *s) break; case 0xF0: - av_log(s->avctx, AV_LOG_INFO, "0xF0 opcode seen in SMC chunk (contact the developers)\n"); + av_log_missing_feature(s->avctx, "0xF0 opcode", 1); break; } } + + return; } static av_cold int smc_decode_init(AVCodecContext *avctx) @@ -440,8 +431,7 @@ static int smc_decode_frame(AVCodecContext *avctx, SmcContext *s = avctx->priv_data; const uint8_t *pal = av_packet_get_side_data(avpkt, AV_PKT_DATA_PALETTE, NULL); - s->buf = buf; - s->size = buf_size; + bytestream2_init(&s->gb, buf, buf_size); s->frame.reference = 3; s->frame.buffer_hints = FF_BUFFER_HINTS_VALID | FF_BUFFER_HINTS_PRESERVE | diff --git a/libavcodec/snow.c b/libavcodec/snow.c index a289ecfbce..910df2a060 100644 --- a/libavcodec/snow.c +++ b/libavcodec/snow.c @@ -385,7 +385,7 @@ mca( 8, 8,8) av_cold int ff_snow_common_init(AVCodecContext *avctx){ SnowContext *s = avctx->priv_data; int width, height; - int i, j; + int i, j, ret; s->avctx= avctx; s->max_ref_frames=1; //just make sure its not an invalid value in case of no initial keyframe @@ -438,17 +438,22 @@ av_cold int ff_snow_common_init(AVCodecContext *avctx){ width= s->avctx->width; height= s->avctx->height; - s->spatial_idwt_buffer= av_mallocz(width*height*sizeof(IDWTELEM)); - s->spatial_dwt_buffer= av_mallocz(width*height*sizeof(DWTELEM)); //FIXME this does not belong here + FF_ALLOCZ_OR_GOTO(avctx, s->spatial_idwt_buffer, width * height * sizeof(IDWTELEM), fail); + FF_ALLOCZ_OR_GOTO(avctx, s->spatial_dwt_buffer, width * height * sizeof(DWTELEM), fail); //FIXME this does not belong here for(i=0; iavctx->get_buffer(s->avctx, &s->mconly_picture); - s->scratchbuf = av_malloc(s->mconly_picture.linesize[0]*7*MB_SIZE); + if ((ret = s->avctx->get_buffer(s->avctx, &s->mconly_picture)) < 0) { + av_log(s->avctx, AV_LOG_ERROR, "get_buffer() failed\n"); + return ret; + } + FF_ALLOC_OR_GOTO(avctx, s->scratchbuf, s->mconly_picture.linesize[0]*7*MB_SIZE, fail); return 0; +fail: + return AVERROR(ENOMEM); } int ff_snow_common_init_after_header(AVCodecContext *avctx) { diff --git a/libavcodec/snow.h b/libavcodec/snow.h index 3a5cdc7175..6a04d694bb 100644 --- a/libavcodec/snow.h +++ b/libavcodec/snow.h @@ -311,7 +311,8 @@ static av_always_inline void add_yblock(SnowContext *s, int sliced, slice_buffer if(!sliced && !offset_dst) dst -= src_x; src_x=0; - }else if(src_x + b_w > w){ + } + if(src_x + b_w > w){ b_w = w - src_x; } if(src_y<0){ @@ -320,7 +321,8 @@ static av_always_inline void add_yblock(SnowContext *s, int sliced, slice_buffer if(!sliced && !offset_dst) dst -= src_y*dst_stride; src_y=0; - }else if(src_y + b_h> h){ + } + if(src_y + b_h> h){ b_h = h - src_y; } diff --git a/libavcodec/snowdec.c b/libavcodec/snowdec.c index 9fd25a5335..5768160766 100644 --- a/libavcodec/snowdec.c +++ b/libavcodec/snowdec.c @@ -132,7 +132,7 @@ static inline void decode_subband_slice_buffered(SnowContext *s, SubBand *b, sli return; } -static void decode_q_branch(SnowContext *s, int level, int x, int y){ +static int decode_q_branch(SnowContext *s, int level, int x, int y){ const int w= s->b_width << s->block_max_depth; const int rem_depth= s->block_max_depth - level; const int index= (x + y*w) << rem_depth; @@ -142,10 +142,11 @@ static void decode_q_branch(SnowContext *s, int level, int x, int y){ const BlockNode *tl = y && x ? &s->block[index-w-1] : left; const BlockNode *tr = y && trxblock[index-w+(1<level + 2*top->level + tl->level + tr->level; + int res; if(s->keyframe){ set_blocks(s, level, x, y, null_block.color[0], null_block.color[1], null_block.color[2], null_block.mx, null_block.my, null_block.ref, BLOCK_INTRA); - return; + return 0; } if(level==s->block_max_depth || get_rac(&s->c, &s->block_state[4 + s_context])){ @@ -153,7 +154,7 @@ static void decode_q_branch(SnowContext *s, int level, int x, int y){ int l = left->color[0]; int cb= left->color[1]; int cr= left->color[2]; - int ref = 0; + unsigned ref = 0; int ref_context= av_log2(2*left->ref) + av_log2(2*top->ref); int mx_context= av_log2(2*FFABS(left->mx - top->mx)) + 0*av_log2(2*FFABS(tr->mx - top->mx)); int my_context= av_log2(2*FFABS(left->my - top->my)) + 0*av_log2(2*FFABS(tr->my - top->my)); @@ -168,17 +169,23 @@ static void decode_q_branch(SnowContext *s, int level, int x, int y){ }else{ if(s->ref_frames > 1) ref= get_symbol(&s->c, &s->block_state[128 + 1024 + 32*ref_context], 0); + if (ref >= s->ref_frames) { + av_log(s->avctx, AV_LOG_ERROR, "Invalid ref\n"); + return AVERROR_INVALIDDATA; + } pred_mv(s, &mx, &my, ref, left, top, tr); mx+= get_symbol(&s->c, &s->block_state[128 + 32*(mx_context + 16*!!ref)], 1); my+= get_symbol(&s->c, &s->block_state[128 + 32*(my_context + 16*!!ref)], 1); } set_blocks(s, level, x, y, l, cb, cr, mx, my, ref, type); }else{ - decode_q_branch(s, level+1, 2*x+0, 2*y+0); - decode_q_branch(s, level+1, 2*x+1, 2*y+0); - decode_q_branch(s, level+1, 2*x+0, 2*y+1); - decode_q_branch(s, level+1, 2*x+1, 2*y+1); + if ((res = decode_q_branch(s, level+1, 2*x+0, 2*y+0)) < 0 || + (res = decode_q_branch(s, level+1, 2*x+1, 2*y+0)) < 0 || + (res = decode_q_branch(s, level+1, 2*x+0, 2*y+1)) < 0 || + (res = decode_q_branch(s, level+1, 2*x+1, 2*y+1)) < 0) + return res; } + return 0; } static void dequantize_slice_buffered(SnowContext *s, slice_buffer * sb, SubBand *b, IDWTELEM *src, int stride, int start_y, int end_y){ @@ -327,6 +334,11 @@ static int decode_header(SnowContext *s){ return -1; } + if (s->chroma_h_shift != 1 || s->chroma_v_shift != 1) { + av_log(s->avctx, AV_LOG_ERROR, "Invalid chroma shift\n"); + return AVERROR_PATCHWELCOME; + } + s->qlog += get_symbol(&s->c, s->header_state, 1); s->mv_scale += get_symbol(&s->c, s->header_state, 1); s->qbias += get_symbol(&s->c, s->header_state, 1); @@ -342,23 +354,31 @@ static int decode_header(SnowContext *s){ static av_cold int decode_init(AVCodecContext *avctx) { + int ret; + avctx->pix_fmt= PIX_FMT_YUV420P; - ff_snow_common_init(avctx); + if ((ret = ff_snow_common_init(avctx)) < 0) { + ff_snow_common_end(avctx->priv_data); + return ret; + } return 0; } -static void decode_blocks(SnowContext *s){ +static int decode_blocks(SnowContext *s){ int x, y; int w= s->b_width; int h= s->b_height; + int res; for(y=0; ydebug&FF_DEBUG_PICT_INFO) av_log(avctx, AV_LOG_ERROR, "keyframe:%d qlog:%d\n", s->keyframe, s->qlog); - decode_blocks(s); + if ((res = decode_blocks(s)) < 0) + return res; for(plane_index=0; plane_index<3; plane_index++){ Plane *p= &s->plane[plane_index]; diff --git a/libavcodec/snowenc.c b/libavcodec/snowenc.c index 284e755732..1e1128eede 100644 --- a/libavcodec/snowenc.c +++ b/libavcodec/snowenc.c @@ -156,7 +156,7 @@ static void dwt_quantize(SnowContext *s, Plane *p, DWTELEM *buffer, int width, i static av_cold int encode_init(AVCodecContext *avctx) { SnowContext *s = avctx->priv_data; - int plane_index; + int plane_index, ret; if(avctx->strict_std_compliance > FF_COMPLIANCE_EXPERIMENTAL){ av_log(avctx, AV_LOG_ERROR, "This codec is under development, files encoded with it may not be decodable with future versions!!!\n" @@ -185,7 +185,10 @@ static av_cold int encode_init(AVCodecContext *avctx) s->plane[plane_index].fast_mc= 1; } - ff_snow_common_init(avctx); + if ((ret = ff_snow_common_init(avctx)) < 0) { + ff_snow_common_end(avctx->priv_data); + return ret; + } ff_snow_alloc_blocks(s); s->version=0; @@ -199,7 +202,7 @@ static av_cold int encode_init(AVCodecContext *avctx) s->m.me.map = av_mallocz(ME_MAP_SIZE*sizeof(uint32_t)); s->m.me.score_map = av_mallocz(ME_MAP_SIZE*sizeof(uint32_t)); s->m.obmc_scratchpad= av_mallocz(MB_SIZE*MB_SIZE*12*sizeof(uint32_t)); - h263_encode_init(&s->m); //mv_penalty + ff_h263_encode_init(&s->m); //mv_penalty s->max_ref_frames = FFMAX(FFMIN(avctx->refs, MAX_REF_FRAMES), 1); diff --git a/libavcodec/sonic.c b/libavcodec/sonic.c index 71641f95ff..c2697ea82c 100644 --- a/libavcodec/sonic.c +++ b/libavcodec/sonic.c @@ -44,6 +44,7 @@ #define RIGHT_SIDE 2 typedef struct SonicContext { + AVFrame frame; int lossless, decorrelation; int num_taps, downsampling; @@ -757,6 +758,9 @@ static av_cold int sonic_decode_init(AVCodecContext *avctx) s->channels = avctx->channels; s->samplerate = avctx->sample_rate; + avcodec_get_frame_defaults(&s->frame); + avctx->coded_frame = &s->frame; + if (!avctx->extradata) { av_log(avctx, AV_LOG_ERROR, "No mandatory headers present\n"); @@ -848,18 +852,25 @@ static av_cold int sonic_decode_close(AVCodecContext *avctx) } static int sonic_decode_frame(AVCodecContext *avctx, - void *data, int *data_size, + void *data, int *got_frame_ptr, AVPacket *avpkt) { const uint8_t *buf = avpkt->data; int buf_size = avpkt->size; SonicContext *s = avctx->priv_data; GetBitContext gb; - int i, quant, ch, j; - short *samples = data; + int i, quant, ch, j, ret; + short *samples; if (buf_size == 0) return 0; + s->frame.nb_samples = s->frame_size; + if ((ret = avctx->get_buffer(avctx, &s->frame)) < 0) { + av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n"); + return ret; + } + samples = s->frame.data[0]; + // av_log(NULL, AV_LOG_INFO, "buf_size: %d\n", buf_size); init_get_bits(&gb, buf, buf_size*8); @@ -930,7 +941,8 @@ static int sonic_decode_frame(AVCodecContext *avctx, align_get_bits(&gb); - *data_size = s->frame_size * 2; + *got_frame_ptr = 1; + *(AVFrame*)data = s->frame; return (get_bits_count(&gb)+7)/8; } @@ -943,6 +955,7 @@ AVCodec ff_sonic_decoder = { .init = sonic_decode_init, .close = sonic_decode_close, .decode = sonic_decode_frame, + .capabilities = CODEC_CAP_DR1, .long_name = NULL_IF_CONFIG_SMALL("Sonic"), }; #endif /* CONFIG_SONIC_DECODER */ diff --git a/libavcodec/sp5xdec.c b/libavcodec/sp5xdec.c index 4bf45f5454..164250a460 100644 --- a/libavcodec/sp5xdec.c +++ b/libavcodec/sp5xdec.c @@ -72,7 +72,7 @@ static int sp5x_decode_frame(AVCodecContext *avctx, for (i = 2; i < buf_size-2 && j < buf_size+1024-2; i++) recoded[j++] = buf[i]; else - for (i = 14; i < buf_size && j < buf_size+1024-2; i++) + for (i = 14; i < buf_size && j < buf_size+1024-3; i++) { recoded[j++] = buf[i]; if (buf[i] == 0xff) diff --git a/libavcodec/srtdec.c b/libavcodec/srtdec.c index aa73f4c7bf..b6f2dade0c 100644 --- a/libavcodec/srtdec.c +++ b/libavcodec/srtdec.c @@ -110,7 +110,7 @@ static const char *srt_to_ass(AVCodecContext *avctx, char *out, char *out_end, for (j=sptr-2; j>=0; j--) if (stack[j].param[i][0]) { out += snprintf(out, out_end-out, - stack[j].param[i]); + "%s", stack[j].param[i]); break; } } else { @@ -146,7 +146,7 @@ static const char *srt_to_ass(AVCodecContext *avctx, char *out, char *out_end, for (i=0; i -extern const uint8_t mvtab[33][2]; +extern const uint8_t ff_mvtab[33][2]; static VLC svq1_block_type; static VLC svq1_motion_component; @@ -644,13 +644,29 @@ static int svq1_decode_frame(AVCodecContext *avctx, return -1; /* swap some header bytes (why?) */ - if (s->f_code != 0x20) { - uint32_t *src = (uint32_t *) (buf + 4); + if (s->f_code != 0x20) { + uint32_t *src; - for (i=0; i < 4; i++) { - src[i] = ((src[i] << 16) | (src[i] >> 16)) ^ src[7 - i]; + if (buf_size < 9 * 4) { + av_log(avctx, AV_LOG_ERROR, "Input packet too small\n"); + return AVERROR_INVALIDDATA; + } + + av_fast_padded_malloc(&s->pkt_swapped, &s->pkt_swapped_allocated, + buf_size); + if (!s->pkt_swapped) + return AVERROR(ENOMEM); + + memcpy(s->pkt_swapped, buf, buf_size); + buf = s->pkt_swapped; + init_get_bits(&s->gb, buf, buf_size * 8); + skip_bits(&s->gb, 22); + + src = (uint32_t *)(s->pkt_swapped + 4); + + for (i = 0; i < 4; i++) + src[i] = ((src[i] << 16) | (src[i] >> 16)) ^ src[7 - i]; } - } result = svq1_decode_frame_header (&s->gb, s); @@ -769,8 +785,8 @@ static av_cold int svq1_decode_init(AVCodecContext *avctx) &ff_svq1_block_type_vlc[0][0], 2, 1, 6); INIT_VLC_STATIC(&svq1_motion_component, 7, 33, - &mvtab[0][1], 2, 1, - &mvtab[0][0], 2, 1, 176); + &ff_mvtab[0][1], 2, 1, + &ff_mvtab[0][0], 2, 1, 176); for (i = 0; i < 6; i++) { static const uint8_t sizes[2][6] = {{14, 10, 14, 18, 16, 18}, {10, 10, 14, 14, 14, 16}}; @@ -804,6 +820,9 @@ static av_cold int svq1_decode_end(AVCodecContext *avctx) { MpegEncContext *s = avctx->priv_data; + av_freep(&s->pkt_swapped); + s->pkt_swapped_allocated = 0; + MPV_common_end(s); return 0; } diff --git a/libavcodec/svq1enc.c b/libavcodec/svq1enc.c index feceaee6e8..3cc73d0a87 100644 --- a/libavcodec/svq1enc.c +++ b/libavcodec/svq1enc.c @@ -402,7 +402,7 @@ static int svq1_encode_plane(SVQ1Context *s, int plane, unsigned char *src_plane int mx, my, pred_x, pred_y, dxy; int16_t *motion_ptr; - motion_ptr= h263_pred_motion(&s->m, 0, 0, &pred_x, &pred_y); + motion_ptr= ff_h263_pred_motion(&s->m, 0, 0, &pred_x, &pred_y); if(s->m.mb_type[x + y*s->m.mb_stride]&CANDIDATE_MB_TYPE_INTER){ for(i=0; i<6; i++) init_put_bits(&s->reorder_pb[i], reorder_buffer[1][i], 7*32); @@ -486,13 +486,14 @@ static av_cold int svq1_encode_init(AVCodecContext *avctx) s->avctx= avctx; s->m.avctx= avctx; + s->m.picture_structure = PICT_FRAME; s->m.me.temp = s->m.me.scratchpad= av_mallocz((avctx->width+64)*2*16*2*sizeof(uint8_t)); s->m.me.map = av_mallocz(ME_MAP_SIZE*sizeof(uint32_t)); s->m.me.score_map = av_mallocz(ME_MAP_SIZE*sizeof(uint32_t)); s->mb_type = av_mallocz((s->y_block_width+1)*s->y_block_height*sizeof(int16_t)); s->dummy = av_mallocz((s->y_block_width+1)*s->y_block_height*sizeof(int32_t)); - h263_encode_init(&s->m); //mv_penalty + ff_h263_encode_init(&s->m); //mv_penalty return 0; } @@ -512,8 +513,8 @@ static int svq1_encode_frame(AVCodecContext *avctx, unsigned char *buf, } if(!s->current_picture.data[0]){ - avctx->get_buffer(avctx, &s->current_picture); - avctx->get_buffer(avctx, &s->last_picture); + ff_get_buffer(avctx, &s->current_picture); + ff_get_buffer(avctx, &s->last_picture); s->scratchbuf = av_malloc(s->current_picture.linesize[0] * 16 * 2); } diff --git a/libavcodec/svq3.c b/libavcodec/svq3.c index d96ce8ee8d..c9fb6c9778 100644 --- a/libavcodec/svq3.c +++ b/libavcodec/svq3.c @@ -175,7 +175,6 @@ void ff_svq3_add_idct_c(uint8_t *dst, DCTELEM *block, int stride, int qp, { const int qmul = svq3_dequant_coeff[qp]; int i; - uint8_t *cm = ff_cropTbl + MAX_NEG_CROP; if (dc) { dc = 13*13*((dc == 1) ? 1538*block[0] : ((qmul*(block[0] >> 3)) / 2)); @@ -201,10 +200,10 @@ void ff_svq3_add_idct_c(uint8_t *dst, DCTELEM *block, int stride, int qp, const int z3 = 17* block[i + 4*1] + 7*block[i + 4*3]; const int rr = (dc + 0x80000); - dst[i + stride*0] = cm[ dst[i + stride*0] + (((z0 + z3)*qmul + rr) >> 20) ]; - dst[i + stride*1] = cm[ dst[i + stride*1] + (((z1 + z2)*qmul + rr) >> 20) ]; - dst[i + stride*2] = cm[ dst[i + stride*2] + (((z1 - z2)*qmul + rr) >> 20) ]; - dst[i + stride*3] = cm[ dst[i + stride*3] + (((z0 - z3)*qmul + rr) >> 20) ]; + dst[i + stride*0] = av_clip_uint8( dst[i + stride*0] + (((z0 + z3)*qmul + rr) >> 20) ); + dst[i + stride*1] = av_clip_uint8( dst[i + stride*1] + (((z1 + z2)*qmul + rr) >> 20) ); + dst[i + stride*2] = av_clip_uint8( dst[i + stride*2] + (((z1 - z2)*qmul + rr) >> 20) ); + dst[i + stride*3] = av_clip_uint8( dst[i + stride*3] + (((z0 - z3)*qmul + rr) >> 20) ); } } @@ -412,17 +411,17 @@ static inline int svq3_mc_dir(H264Context *h, int size, int mode, int dir, int32_t mv = pack16to32(mx,my); if (part_height == 8 && i < 8) { - *(int32_t *) h->mv_cache[dir][scan8[k] + 1*8] = mv; + AV_WN32A(h->mv_cache[dir][scan8[k] + 1*8], mv); if (part_width == 8 && j < 8) { - *(int32_t *) h->mv_cache[dir][scan8[k] + 1 + 1*8] = mv; + AV_WN32A(h->mv_cache[dir][scan8[k] + 1 + 1*8], mv); } } if (part_width == 8 && j < 8) { - *(int32_t *) h->mv_cache[dir][scan8[k] + 1] = mv; + AV_WN32A(h->mv_cache[dir][scan8[k] + 1], mv); } if (part_width == 4 || part_height == 4) { - *(int32_t *) h->mv_cache[dir][scan8[k]] = mv; + AV_WN32A(h->mv_cache[dir][scan8[k]], mv); } } @@ -490,11 +489,11 @@ static int svq3_decode_mb(SVQ3Context *svq3, unsigned int mb_type) for (m = 0; m < 2; m++) { if (s->mb_x > 0 && h->intra4x4_pred_mode[h->mb2br_xy[mb_xy - 1]+6] != -1) { for (i = 0; i < 4; i++) { - *(uint32_t *) h->mv_cache[m][scan8[0] - 1 + i*8] = *(uint32_t *) s->current_picture.f.motion_val[m][b_xy - 1 + i*h->b_stride]; + AV_COPY32(h->mv_cache[m][scan8[0] - 1 + i*8], s->current_picture.f.motion_val[m][b_xy - 1 + i*h->b_stride]); } } else { for (i = 0; i < 4; i++) { - *(uint32_t *) h->mv_cache[m][scan8[0] - 1 + i*8] = 0; + AV_ZERO32(h->mv_cache[m][scan8[0] - 1 + i*8]); } } if (s->mb_y > 0) { @@ -502,14 +501,14 @@ static int svq3_decode_mb(SVQ3Context *svq3, unsigned int mb_type) memset(&h->ref_cache[m][scan8[0] - 1*8], (h->intra4x4_pred_mode[h->mb2br_xy[mb_xy - s->mb_stride]] == -1) ? PART_NOT_AVAILABLE : 1, 4); if (s->mb_x < (s->mb_width - 1)) { - *(uint32_t *) h->mv_cache[m][scan8[0] + 4 - 1*8] = *(uint32_t *) s->current_picture.f.motion_val[m][b_xy - h->b_stride + 4]; + AV_COPY32(h->mv_cache[m][scan8[0] + 4 - 1*8], s->current_picture.f.motion_val[m][b_xy - h->b_stride + 4]); h->ref_cache[m][scan8[0] + 4 - 1*8] = (h->intra4x4_pred_mode[h->mb2br_xy[mb_xy - s->mb_stride + 1]+6] == -1 || h->intra4x4_pred_mode[h->mb2br_xy[mb_xy - s->mb_stride ] ] == -1) ? PART_NOT_AVAILABLE : 1; }else h->ref_cache[m][scan8[0] + 4 - 1*8] = PART_NOT_AVAILABLE; if (s->mb_x > 0) { - *(uint32_t *) h->mv_cache[m][scan8[0] - 1 - 1*8] = *(uint32_t *) s->current_picture.f.motion_val[m][b_xy - h->b_stride - 1]; + AV_COPY32(h->mv_cache[m][scan8[0] - 1 - 1*8], s->current_picture.f.motion_val[m][b_xy - h->b_stride - 1]); h->ref_cache[m][scan8[0] - 1 - 1*8] = (h->intra4x4_pred_mode[h->mb2br_xy[mb_xy - s->mb_stride - 1]+3] == -1) ? PART_NOT_AVAILABLE : 1; }else h->ref_cache[m][scan8[0] - 1 - 1*8] = PART_NOT_AVAILABLE; @@ -614,9 +613,9 @@ static int svq3_decode_mb(SVQ3Context *svq3, unsigned int mb_type) dir = i_mb_type_info[mb_type - 8].pred_mode; dir = (dir >> 1) ^ 3*(dir & 1) ^ 1; - if ((h->intra16x16_pred_mode = ff_h264_check_intra16x16_pred_mode(h, dir)) == -1){ - av_log(h->s.avctx, AV_LOG_ERROR, "check_intra_pred_mode = -1\n"); - return -1; + if ((h->intra16x16_pred_mode = ff_h264_check_intra_pred_mode(h, dir, 0)) < 0) { + av_log(h->s.avctx, AV_LOG_ERROR, "ff_h264_check_intra_pred_mode < 0\n"); + return h->intra16x16_pred_mode; } cbp = i_mb_type_info[mb_type - 8].cbp; @@ -653,7 +652,7 @@ static int svq3_decode_mb(SVQ3Context *svq3, unsigned int mb_type) if (IS_INTRA16x16(mb_type) || (s->pict_type != AV_PICTURE_TYPE_I && s->adaptive_quant && cbp)) { s->qscale += svq3_get_se_golomb(&s->gb); - if (s->qscale > 31U){ + if (s->qscale > 31u){ av_log(h->s.avctx, AV_LOG_ERROR, "qscale:%d\n", s->qscale); return -1; } @@ -713,7 +712,7 @@ static int svq3_decode_mb(SVQ3Context *svq3, unsigned int mb_type) s->current_picture.f.mb_type[mb_xy] = mb_type; if (IS_INTRA(mb_type)) { - h->chroma_pred_mode = ff_h264_check_intra_chroma_pred_mode(h, DC_PRED8x8); + h->chroma_pred_mode = ff_h264_check_intra_pred_mode(h, DC_PRED8x8, 1); } return 0; @@ -813,7 +812,9 @@ static av_cold int svq3_decode_init(AVCodecContext *avctx) MpegEncContext *s = &h->s; int m; unsigned char *extradata; + unsigned char *extradata_end; unsigned int size; + int marker_found = 0; if (ff_h264_decode_init(avctx) < 0) return -1; @@ -834,19 +835,26 @@ static av_cold int svq3_decode_init(AVCodecContext *avctx) /* prowl for the "SEQH" marker in the extradata */ extradata = (unsigned char *)avctx->extradata; - for (m = 0; m < avctx->extradata_size; m++) { - if (!memcmp(extradata, "SEQH", 4)) - break; - extradata++; + extradata_end = avctx->extradata + avctx->extradata_size; + if (extradata) { + for (m = 0; m + 8 < avctx->extradata_size; m++) { + if (!memcmp(extradata, "SEQH", 4)) { + marker_found = 1; + break; + } + extradata++; + } } /* if a match was found, parse the extra data */ - if (extradata && !memcmp(extradata, "SEQH", 4)) { + if (marker_found) { GetBitContext gb; int frame_size_code; size = AV_RB32(&extradata[4]); + if (size > extradata_end - extradata - 8) + return AVERROR_INVALIDDATA; init_get_bits(&gb, extradata + 8, size*8); /* 'frame size code' and optional 'width, height' */ @@ -897,7 +905,8 @@ static av_cold int svq3_decode_init(AVCodecContext *avctx) int offset = (get_bits_count(&gb)+7)>>3; uint8_t *buf; - if ((uint64_t)watermark_width*4 > UINT_MAX/watermark_height) + if (watermark_height > 0 && + (uint64_t)watermark_width * 4 > UINT_MAX / watermark_height) return -1; buf = av_malloc(buf_len); diff --git a/libavcodec/thread.h b/libavcodec/thread.h index 205e45035d..8dcbfc5d06 100644 --- a/libavcodec/thread.h +++ b/libavcodec/thread.h @@ -89,7 +89,7 @@ void ff_thread_await_progress(AVFrame *f, int progress, int field); /** * Wrapper around get_buffer() for frame-multithreaded codecs. - * Call this function instead of avctx->get_buffer(f). + * Call this function instead of ff_get_buffer(f). * Cannot be called after the codec has called ff_thread_finish_setup(). * * @param avctx The current context. diff --git a/libavcodec/tiff.c b/libavcodec/tiff.c index a0424b984a..d6e2295564 100644 --- a/libavcodec/tiff.c +++ b/libavcodec/tiff.c @@ -25,6 +25,7 @@ */ #include "avcodec.h" +#include "bytestream.h" #if CONFIG_ZLIB #include #endif @@ -38,6 +39,7 @@ typedef struct TiffContext { AVCodecContext *avctx; AVFrame picture; + GetByteContext gb; int width, height; unsigned int bpp, bppcount; @@ -52,30 +54,27 @@ typedef struct TiffContext { int strips, rps, sstype; int sot; - const uint8_t* stripdata; - const uint8_t* stripsizes; - int stripsize, stripoff; + int stripsizesoff, stripsize, stripoff, strippos; LZWState *lzw; } TiffContext; -static int tget_short(const uint8_t **p, int le){ - int v = le ? AV_RL16(*p) : AV_RB16(*p); - *p += 2; - return v; +static unsigned tget_short(GetByteContext *gb, int le) +{ + return le ? bytestream2_get_le16(gb) : bytestream2_get_be16(gb); } -static int tget_long(const uint8_t **p, int le){ - int v = le ? AV_RL32(*p) : AV_RB32(*p); - *p += 4; - return v; +static unsigned tget_long(GetByteContext *gb, int le) +{ + return le ? bytestream2_get_le32(gb) : bytestream2_get_be32(gb); } -static int tget(const uint8_t **p, int type, int le){ +static unsigned tget(GetByteContext *gb, int type, int le) +{ switch(type){ - case TIFF_BYTE : return *(*p)++; - case TIFF_SHORT: return tget_short(p, le); - case TIFF_LONG : return tget_long (p, le); - default : return -1; + case TIFF_BYTE: return bytestream2_get_byte(gb); + case TIFF_SHORT: return tget_short(gb, le); + case TIFF_LONG: return tget_long(gb, le); + default: return UINT_MAX; } } @@ -143,8 +142,8 @@ static void av_always_inline horizontal_fill(unsigned int bpp, uint8_t* dst, } static int tiff_unpack_strip(TiffContext *s, uint8_t* dst, int stride, const uint8_t *src, int size, int lines){ + PutByteContext pb; int c, line, pixels, code; - const uint8_t *ssrc = src; int width = ((s->width * s->bpp) + 7) >> 3; #if CONFIG_ZLIB uint8_t *zbuf; unsigned long outlen; @@ -178,6 +177,16 @@ static int tiff_unpack_strip(TiffContext *s, uint8_t* dst, int stride, const uin av_log(s->avctx, AV_LOG_ERROR, "Error initializing LZW decoder\n"); return -1; } + for (line = 0; line < lines; line++) { + pixels = ff_lzw_decode(s->lzw, dst, width); + if (pixels < width) { + av_log(s->avctx, AV_LOG_ERROR, "Decoded only %i bytes of %i\n", + pixels, width); + return AVERROR_INVALIDDATA; + } + dst += stride; + } + return 0; } if(s->compr == TIFF_CCITT_RLE || s->compr == TIFF_G3 || s->compr == TIFF_G4){ int i, ret = 0; @@ -214,62 +223,40 @@ static int tiff_unpack_strip(TiffContext *s, uint8_t* dst, int stride, const uin av_free(src2); return ret; } + + bytestream2_init(&s->gb, src, size); + bytestream2_init_writer(&pb, dst, stride * lines); + for(line = 0; line < lines; line++){ - if(src - ssrc > size){ - av_log(s->avctx, AV_LOG_ERROR, "Source data overread\n"); - return -1; - } + if (bytestream2_get_bytes_left(&s->gb) == 0 || bytestream2_get_eof(&pb)) + break; + bytestream2_seek_p(&pb, stride * line, SEEK_SET); switch(s->compr){ case TIFF_RAW: - if (ssrc + size - src < width) - return AVERROR_INVALIDDATA; if (!s->fill_order) { - horizontal_fill(s->bpp * (s->avctx->pix_fmt == PIX_FMT_PAL8), - dst, 1, src, 0, width, 0); + bytestream2_copy_buffer(&pb, &s->gb, width); } else { int i; for (i = 0; i < width; i++) - dst[i] = av_reverse[src[i]]; + bytestream2_put_byte(&pb, av_reverse[bytestream2_get_byte(&s->gb)]); } - src += width; break; case TIFF_PACKBITS: for(pixels = 0; pixels < width;){ - code = (int8_t)*src++; + code = (int8_t)bytestream2_get_byte(&s->gb); if(code >= 0){ code++; - if(pixels + code > width){ - av_log(s->avctx, AV_LOG_ERROR, "Copy went out of bounds\n"); - return -1; - } - horizontal_fill(s->bpp * (s->avctx->pix_fmt == PIX_FMT_PAL8), - dst, 1, src, 0, code, pixels); - src += code; + bytestream2_copy_buffer(&pb, &s->gb, code); pixels += code; }else if(code != -128){ // -127..-1 code = (-code) + 1; - if(pixels + code > width){ - av_log(s->avctx, AV_LOG_ERROR, "Run went out of bounds\n"); - return -1; - } - c = *src++; - horizontal_fill(s->bpp * (s->avctx->pix_fmt == PIX_FMT_PAL8), - dst, 0, NULL, c, code, pixels); + c = bytestream2_get_byte(&s->gb); + bytestream2_set_buffer(&pb, c, code); pixels += code; } } break; - case TIFF_LZW: - pixels = ff_lzw_decode(s->lzw, dst, width); - if(pixels < width){ - av_log(s->avctx, AV_LOG_ERROR, "Decoded only %i bytes of %i\n", pixels, width); - return -1; - } - if (s->bpp < 8 && s->avctx->pix_fmt == PIX_FMT_PAL8) - horizontal_fill(s->bpp, dst, 1, dst, 0, width, 0); - break; } - dst += stride; } return 0; } @@ -279,6 +266,14 @@ static int init_image(TiffContext *s) int i, ret; uint32_t *pal; + // make sure there is no aliasing in the following switch + if (s->bpp >= 100 || s->bppcount >= 10) { + av_log(s->avctx, AV_LOG_ERROR, + "Unsupported image parameters: bpp=%d, bppcount=%d\n", + s->bpp, s->bppcount); + return AVERROR_INVALIDDATA; + } + switch (s->bpp * 10 + s->bppcount) { case 11: if (!s->palette_is_set) { @@ -338,50 +333,49 @@ static int init_image(TiffContext *s) return 0; } -static int tiff_decode_tag(TiffContext *s, const uint8_t *start, const uint8_t *buf, const uint8_t *end_buf) +static int tiff_decode_tag(TiffContext *s) { - int tag, type, count, off, value = 0; - int i, j; + unsigned tag, type, count, off, value = 0; + int i, start; uint32_t *pal; - const uint8_t *rp, *gp, *bp; - if (end_buf - buf < 12) + if (bytestream2_get_bytes_left(&s->gb) < 12) return -1; - tag = tget_short(&buf, s->le); - type = tget_short(&buf, s->le); - count = tget_long(&buf, s->le); - off = tget_long(&buf, s->le); + tag = tget_short(&s->gb, s->le); + type = tget_short(&s->gb, s->le); + count = tget_long(&s->gb, s->le); + off = tget_long(&s->gb, s->le); + start = bytestream2_tell(&s->gb); + + if (type == 0 || type >= FF_ARRAY_ELEMS(type_sizes)) { + av_log(s->avctx, AV_LOG_DEBUG, "Unknown tiff type (%u) encountered\n", type); + return 0; + } if(count == 1){ switch(type){ case TIFF_BYTE: case TIFF_SHORT: - buf -= 4; - value = tget(&buf, type, s->le); - buf = NULL; + bytestream2_seek(&s->gb, -4, SEEK_CUR); + value = tget(&s->gb, type, s->le); break; case TIFF_LONG: value = off; - buf = NULL; break; case TIFF_STRING: if(count <= 4){ - buf -= 4; + bytestream2_seek(&s->gb, -4, SEEK_CUR); break; } default: - value = -1; - buf = start + off; + value = UINT_MAX; + bytestream2_seek(&s->gb, off, SEEK_SET); } - }else if(type_sizes[type] * count <= 4){ - buf -= 4; - }else{ - buf = start + off; - } - - if(buf && (buf < start || buf > end_buf)){ - av_log(s->avctx, AV_LOG_ERROR, "Tag referencing position outside the image\n"); - return -1; + } else { + if (count <= 4 && type_sizes[type] * count <= 4) + bytestream2_seek(&s->gb, -4, SEEK_CUR); + else + bytestream2_seek(&s->gb, off, SEEK_SET); } switch(tag){ @@ -392,11 +386,11 @@ static int tiff_decode_tag(TiffContext *s, const uint8_t *start, const uint8_t * s->height = value; break; case TIFF_BPP: - s->bppcount = count; - if(count > 4){ - av_log(s->avctx, AV_LOG_ERROR, "This format is not supported (bpp=%d, %d components)\n", s->bpp, count); + if(count > 4U){ + av_log(s->avctx, AV_LOG_ERROR, "This format is not supported (bpp=%d, %d components)\n", value, count); return -1; } + s->bppcount = count; if(count == 1) s->bpp = value; else{ switch(type){ @@ -406,7 +400,8 @@ static int tiff_decode_tag(TiffContext *s, const uint8_t *start, const uint8_t * case TIFF_SHORT: case TIFF_LONG: s->bpp = 0; - for(i = 0; i < count && buf < end_buf; i++) s->bpp += tget(&buf, type, s->le); + for (i = 0; i < count; i++) + s->bpp += tget(&s->gb, type, s->le); break; default: s->bpp = -1; @@ -454,8 +449,8 @@ static int tiff_decode_tag(TiffContext *s, const uint8_t *start, const uint8_t * } break; case TIFF_ROWSPERSTRIP: - if(type == TIFF_LONG && value == -1) - value = s->avctx->height; + if (type == TIFF_LONG && value == UINT_MAX) + value = s->height; if(value < 1){ av_log(s->avctx, AV_LOG_ERROR, "Incorrect value of rows per strip\n"); return -1; @@ -464,32 +459,24 @@ static int tiff_decode_tag(TiffContext *s, const uint8_t *start, const uint8_t * break; case TIFF_STRIP_OFFS: if(count == 1){ - s->stripdata = NULL; + s->strippos = 0; s->stripoff = value; }else - s->stripdata = start + off; + s->strippos = off; s->strips = count; if(s->strips == 1) s->rps = s->height; s->sot = type; - if(s->stripdata > end_buf){ - av_log(s->avctx, AV_LOG_ERROR, "Tag referencing position outside the image\n"); - return -1; - } break; case TIFF_STRIP_SIZE: if(count == 1){ - s->stripsizes = NULL; - s->stripsize = value; - s->strips = 1; + s->stripsizesoff = 0; + s->stripsize = value; + s->strips = 1; }else{ - s->stripsizes = start + off; + s->stripsizesoff = off; } s->strips = count; s->sstype = type; - if(s->stripsizes > end_buf){ - av_log(s->avctx, AV_LOG_ERROR, "Tag referencing position outside the image\n"); - return -1; - } break; case TIFF_TILE_BYTE_COUNTS: case TIFF_TILE_LENGTH: @@ -524,24 +511,27 @@ static int tiff_decode_tag(TiffContext *s, const uint8_t *start, const uint8_t * } s->fill_order = value - 1; break; - case TIFF_PAL: + case TIFF_PAL: { + GetByteContext pal_gb[3]; pal = (uint32_t *) s->palette; off = type_sizes[type]; - if (count / 3 > 256 || end_buf - buf < count / 3 * off * 3) + if (count / 3 > 256 || + bytestream2_get_bytes_left(&s->gb) < count / 3 * off * 3) return -1; - rp = buf; - gp = buf + count / 3 * off; - bp = buf + count / 3 * off * 2; + pal_gb[0] = pal_gb[1] = pal_gb[2] = s->gb; + bytestream2_skip(&pal_gb[1], count / 3 * off); + bytestream2_skip(&pal_gb[2], count / 3 * off * 2); off = (type_sizes[type] - 1) << 3; for(i = 0; i < count / 3; i++){ - j = 0xff << 24; - j |= (tget(&rp, type, s->le) >> off) << 16; - j |= (tget(&gp, type, s->le) >> off) << 8; - j |= tget(&bp, type, s->le) >> off; - pal[i] = j; + uint32_t p = 0xFF000000; + p |= (tget(&pal_gb[0], type, s->le) >> off) << 16; + p |= (tget(&pal_gb[1], type, s->le) >> off) << 8; + p |= tget(&pal_gb[2], type, s->le) >> off; + pal[i] = p; } s->palette_is_set = 1; break; + } case TIFF_PLANAR: if(value == 2){ av_log(s->avctx, AV_LOG_ERROR, "Planar format is not supported\n"); @@ -559,6 +549,14 @@ static int tiff_decode_tag(TiffContext *s, const uint8_t *start, const uint8_t * default: av_log(s->avctx, AV_LOG_DEBUG, "Unknown or unsupported tag %d/0X%0X\n", tag, tag); } + if (s->bpp > 64U) { + av_log(s->avctx, AV_LOG_ERROR, + "This format is not supported (bpp=%d, %d components)\n", + s->bpp, count); + s->bpp = 0; + return AVERROR_INVALIDDATA; + } + bytestream2_seek(&s->gb, start, SEEK_SET); return 0; } @@ -566,23 +564,24 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *data_size, AVPacket *avpkt) { - const uint8_t *buf = avpkt->data; - int buf_size = avpkt->size; TiffContext * const s = avctx->priv_data; AVFrame *picture = data; AVFrame * const p= (AVFrame*)&s->picture; - const uint8_t *orig_buf = buf, *end_buf = buf + buf_size; unsigned off; int id, le, ret; int i, j, entries; int stride; unsigned soff, ssize; uint8_t *dst; + GetByteContext stripsizes; + GetByteContext stripdata; + + bytestream2_init(&s->gb, avpkt->data, avpkt->size); //parse image header - if (end_buf - buf < 8) + if (avpkt->size < 8) return AVERROR_INVALIDDATA; - id = AV_RL16(buf); buf += 2; + id = bytestream2_get_le16(&s->gb); if(id == 0x4949) le = 1; else if(id == 0x4D4D) le = 0; else{ @@ -595,24 +594,25 @@ static int decode_frame(AVCodecContext *avctx, s->fill_order = 0; // As TIFF 6.0 specification puts it "An arbitrary but carefully chosen number // that further identifies the file as a TIFF file" - if(tget_short(&buf, le) != 42){ + if (tget_short(&s->gb, le) != 42) { av_log(avctx, AV_LOG_ERROR, "The answer to life, universe and everything is not correct!\n"); return -1; } + // Reset these offsets so we can tell if they were set this frame + s->stripsizesoff = s->strippos = 0; /* parse image file directory */ - off = tget_long(&buf, le); - if (off >= UINT_MAX - 14 || end_buf - orig_buf < off + 14) { + off = tget_long(&s->gb, le); + 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; } - buf = orig_buf + off; - entries = tget_short(&buf, le); + bytestream2_seek(&s->gb, off, SEEK_SET); + entries = tget_short(&s->gb, le); for(i = 0; i < entries; i++){ - if(tiff_decode_tag(s, orig_buf, buf, end_buf) < 0) + if (tiff_decode_tag(s) < 0) return -1; - buf += 12; } - if(!s->stripdata && !s->stripoff){ + if (!s->strippos && !s->stripoff) { av_log(avctx, AV_LOG_ERROR, "Image data is missing\n"); return -1; } @@ -622,30 +622,41 @@ static int decode_frame(AVCodecContext *avctx, if(s->strips == 1 && !s->stripsize){ av_log(avctx, AV_LOG_WARNING, "Image data size missing\n"); - s->stripsize = buf_size - s->stripoff; + s->stripsize = avpkt->size - s->stripoff; } stride = p->linesize[0]; dst = p->data[0]; + + if (s->stripsizesoff) { + if (s->stripsizesoff >= avpkt->size) + return AVERROR_INVALIDDATA; + bytestream2_init(&stripsizes, avpkt->data + s->stripsizesoff, + avpkt->size - s->stripsizesoff); + } + if (s->strippos) { + if (s->strippos >= avpkt->size) + return AVERROR_INVALIDDATA; + bytestream2_init(&stripdata, avpkt->data + s->strippos, + avpkt->size - s->strippos); + } + for(i = 0; i < s->height; i += s->rps){ - if(s->stripsizes) { - if (s->stripsizes >= end_buf) - return AVERROR_INVALIDDATA; - ssize = tget(&s->stripsizes, s->sstype, s->le); - } else + if (s->stripsizesoff) + ssize = tget(&stripsizes, s->sstype, le); + else ssize = s->stripsize; - if(s->stripdata){ - if (s->stripdata >= end_buf) - return AVERROR_INVALIDDATA; - soff = tget(&s->stripdata, s->sot, s->le); - }else + if (s->strippos) + soff = tget(&stripdata, s->sot, le); + else soff = s->stripoff; - if (soff > buf_size || ssize > buf_size - soff) { + if (soff > avpkt->size || ssize > avpkt->size - soff) { av_log(avctx, AV_LOG_ERROR, "Invalid strip size/offset\n"); return -1; } - if(tiff_unpack_strip(s, dst, stride, orig_buf + soff, ssize, FFMIN(s->rps, s->height - i)) < 0) + if (tiff_unpack_strip(s, dst, stride, avpkt->data + soff, ssize, + FFMIN(s->rps, s->height - i)) < 0) break; dst += s->rps * stride; } @@ -687,7 +698,7 @@ static int decode_frame(AVCodecContext *avctx, *picture= *(AVFrame*)&s->picture; *data_size = sizeof(AVPicture); - return buf_size; + return avpkt->size; } static av_cold int tiff_init(AVCodecContext *avctx){ diff --git a/libavcodec/tiffenc.c b/libavcodec/tiffenc.c index 833acb543b..172ff96b09 100644 --- a/libavcodec/tiffenc.c +++ b/libavcodec/tiffenc.c @@ -336,6 +336,10 @@ static int encode_frame(AVCodecContext * avctx, unsigned char *buf, strip_sizes = av_mallocz(sizeof(*strip_sizes) * strips); strip_offsets = av_mallocz(sizeof(*strip_offsets) * strips); + if (!strip_sizes || !strip_offsets) { + ret = AVERROR(ENOMEM); + goto fail; + } bytes_per_row = (((s->width - 1)/s->subsampling[0] + 1) * s->bpp * s->subsampling[0] * s->subsampling[1] + 7) >> 3; @@ -343,6 +347,7 @@ static int encode_frame(AVCodecContext * avctx, unsigned char *buf, yuv_line = av_malloc(bytes_per_row); if (yuv_line == NULL){ av_log(s->avctx, AV_LOG_ERROR, "Not enough memory\n"); + ret = AVERROR(ENOMEM); goto fail; } } @@ -355,6 +360,10 @@ static int encode_frame(AVCodecContext * avctx, unsigned char *buf, zlen = bytes_per_row * s->rps; zbuf = av_malloc(zlen); + if (!zbuf) { + ret = AVERROR(ENOMEM); + goto fail; + } strip_offsets[0] = ptr - buf; zn = 0; for (j = 0; j < s->rps; j++) { @@ -379,8 +388,13 @@ static int encode_frame(AVCodecContext * avctx, unsigned char *buf, } else #endif { - if(s->compr == TIFF_LZW) + if (s->compr == TIFF_LZW) { s->lzws = av_malloc(ff_lzw_encode_state_size); + if (!s->lzws) { + ret = AVERROR(ENOMEM); + goto fail; + } + } for (i = 0; i < s->height; i++) { if (strip_sizes[i / s->rps] == 0) { if(s->compr == TIFF_LZW){ diff --git a/libavcodec/truemotion1.c b/libavcodec/truemotion1.c index ccebef5495..ecf27aa8d8 100644 --- a/libavcodec/truemotion1.c +++ b/libavcodec/truemotion1.c @@ -320,6 +320,11 @@ static int truemotion1_decode_header(TrueMotion1Context *s) return -1; } + if (header.header_size + 1 > s->size) { + av_log(s->avctx, AV_LOG_ERROR, "Input packet too small.\n"); + return AVERROR_INVALIDDATA; + } + /* unscramble the header bytes with a XOR operation */ memset(header_buffer, 0, 128); for (i = 1; i < header.header_size; i++) @@ -520,6 +525,10 @@ hres,vres,i,i%vres (0 < i < 4) } #define APPLY_C_PREDICTOR() \ + if(index > 1023){\ + av_log(s->avctx, AV_LOG_ERROR, " index %d went out of bounds\n", index); \ + return; \ + }\ predictor_pair = s->c_predictor_table[index]; \ horiz_pred += (predictor_pair >> 1); \ if (predictor_pair & 1) { \ @@ -537,6 +546,10 @@ hres,vres,i,i%vres (0 < i < 4) index++; #define APPLY_C_PREDICTOR_24() \ + if(index > 1023){\ + av_log(s->avctx, AV_LOG_ERROR, " index %d went out of bounds\n", index); \ + return; \ + }\ predictor_pair = s->c_predictor_table[index]; \ horiz_pred += (predictor_pair >> 1); \ if (predictor_pair & 1) { \ @@ -555,6 +568,10 @@ hres,vres,i,i%vres (0 < i < 4) #define APPLY_Y_PREDICTOR() \ + if(index > 1023){\ + av_log(s->avctx, AV_LOG_ERROR, " index %d went out of bounds\n", index); \ + return; \ + }\ predictor_pair = s->y_predictor_table[index]; \ horiz_pred += (predictor_pair >> 1); \ if (predictor_pair & 1) { \ @@ -572,6 +589,10 @@ hres,vres,i,i%vres (0 < i < 4) index++; #define APPLY_Y_PREDICTOR_24() \ + if(index > 1023){\ + av_log(s->avctx, AV_LOG_ERROR, " index %d went out of bounds\n", index); \ + return; \ + }\ predictor_pair = s->y_predictor_table[index]; \ horiz_pred += (predictor_pair >> 1); \ if (predictor_pair & 1) { \ diff --git a/libavcodec/truemotion2.c b/libavcodec/truemotion2.c index e68a68757f..bff8dce0ca 100644 --- a/libavcodec/truemotion2.c +++ b/libavcodec/truemotion2.c @@ -25,6 +25,7 @@ */ #include "avcodec.h" +#include "bytestream.h" #include "get_bits.h" #include "dsputil.h" @@ -59,7 +60,9 @@ typedef struct TM2Context{ int *clast; /* data for current and previous frame */ + int *Y1_base, *U1_base, *V1_base, *Y2_base, *U2_base, *V2_base; int *Y1, *U1, *V1, *Y2, *U2, *V2; + int y_stride, uv_stride; int cur; } TM2Context; @@ -130,12 +133,12 @@ static int tm2_build_huff_table(TM2Context *ctx, TM2Codes *code) /* check for correct codes parameters */ if((huff.val_bits < 1) || (huff.val_bits > 32) || - (huff.max_bits < 0) || (huff.max_bits > 32)) { + (huff.max_bits < 0) || (huff.max_bits > 25)) { av_log(ctx->avctx, AV_LOG_ERROR, "Incorrect tree parameters - literal length: %i, max code length: %i\n", huff.val_bits, huff.max_bits); return -1; } - if((huff.nodes < 0) || (huff.nodes > 0x10000)) { + if((huff.nodes <= 0) || (huff.nodes > 0x10000)) { av_log(ctx->avctx, AV_LOG_ERROR, "Incorrect number of Huffman tree nodes: %i\n", huff.nodes); return -1; } @@ -190,7 +193,7 @@ static void tm2_free_codes(TM2Codes *code) { av_free(code->recode); if(code->vlc.table) - free_vlc(&code->vlc); + ff_free_vlc(&code->vlc); } static inline int tm2_get_token(GetBitContext *gb, TM2Codes *code) @@ -219,8 +222,6 @@ static inline int tm2_read_header(TM2Context *ctx, const uint8_t *buf) av_log (ctx->avctx, AV_LOG_ERROR, "Not a TM2 header: 0x%08X\n", magic); return -1; } - - return buf - obuf; } static int tm2_read_deltas(TM2Context *ctx, int stream_id) { @@ -251,13 +252,14 @@ static int tm2_read_deltas(TM2Context *ctx, int stream_id) { static int tm2_read_stream(TM2Context *ctx, const uint8_t *buf, int stream_id, int buf_size) { int i; - int cur = 0; int skip = 0; - int len, toks; + int len, toks, pos; TM2Codes codes; + GetByteContext gb; /* get stream length in dwords */ - len = AV_RB32(buf); buf += 4; cur += 4; + bytestream2_init(&gb, buf, buf_size); + len = bytestream2_get_be32(&gb); skip = len * 4 + 4; if(len == 0) @@ -268,36 +270,37 @@ static int tm2_read_stream(TM2Context *ctx, const uint8_t *buf, int stream_id, i return -1; } - toks = AV_RB32(buf); buf += 4; cur += 4; + toks = bytestream2_get_be32(&gb); if(toks & 1) { - len = AV_RB32(buf); buf += 4; cur += 4; + len = bytestream2_get_be32(&gb); if(len == TM2_ESCAPE) { - len = AV_RB32(buf); buf += 4; cur += 4; + len = bytestream2_get_be32(&gb); } if(len > 0) { - if (skip <= cur) + pos = bytestream2_tell(&gb); + if (skip <= pos) return -1; - init_get_bits(&ctx->gb, buf, (skip - cur) * 8); + init_get_bits(&ctx->gb, buf + pos, (skip - pos) * 8); if(tm2_read_deltas(ctx, stream_id) == -1) return -1; - buf += ((get_bits_count(&ctx->gb) + 31) >> 5) << 2; - cur += ((get_bits_count(&ctx->gb) + 31) >> 5) << 2; + bytestream2_skip(&gb, ((get_bits_count(&ctx->gb) + 31) >> 5) << 2); } } /* skip unused fields */ - if(AV_RB32(buf) == TM2_ESCAPE) { - buf += 4; cur += 4; /* some unknown length - could be escaped too */ + len = bytestream2_get_be32(&gb); + if(len == TM2_ESCAPE) { /* some unknown length - could be escaped too */ + bytestream2_skip(&gb, 8); /* unused by decoder */ + } else { + bytestream2_skip(&gb, 4); /* unused by decoder */ } - buf += 4; cur += 4; - buf += 4; cur += 4; /* unused by decoder */ - if (skip <= cur) + pos = bytestream2_tell(&gb); + if (skip <= pos) return -1; - init_get_bits(&ctx->gb, buf, (skip - cur) * 8); + init_get_bits(&ctx->gb, buf + pos, (skip - pos) * 8); if(tm2_build_huff_table(ctx, &codes) == -1) return -1; - buf += ((get_bits_count(&ctx->gb) + 31) >> 5) << 2; - cur += ((get_bits_count(&ctx->gb) + 31) >> 5) << 2; + bytestream2_skip(&gb, ((get_bits_count(&ctx->gb) + 31) >> 5) << 2); toks >>= 1; /* check if we have sane number of tokens */ @@ -308,21 +311,33 @@ static int tm2_read_stream(TM2Context *ctx, const uint8_t *buf, int stream_id, i } ctx->tokens[stream_id] = av_realloc(ctx->tokens[stream_id], toks * sizeof(int)); ctx->tok_lens[stream_id] = toks; - len = AV_RB32(buf); buf += 4; cur += 4; + len = bytestream2_get_be32(&gb); if(len > 0) { - if (skip <= cur) + pos = bytestream2_tell(&gb); + if (skip <= pos) return -1; - init_get_bits(&ctx->gb, buf, (skip - cur) * 8); + init_get_bits(&ctx->gb, buf + pos, (skip - pos) * 8); for(i = 0; i < toks; i++) { if (get_bits_left(&ctx->gb) <= 0) { av_log(ctx->avctx, AV_LOG_ERROR, "Incorrect number of tokens: %i\n", toks); return -1; } ctx->tokens[stream_id][i] = tm2_get_token(&ctx->gb, &codes); + if (stream_id <= TM2_MOT && ctx->tokens[stream_id][i] >= TM2_DELTAS) { + av_log(ctx->avctx, AV_LOG_ERROR, "Invalid delta token index %d for type %d, n=%d\n", + ctx->tokens[stream_id][i], stream_id, i); + return AVERROR_INVALIDDATA; + } } } else { - for(i = 0; i < toks; i++) + for(i = 0; i < toks; i++) { ctx->tokens[stream_id][i] = codes.recode[0]; + if (stream_id <= TM2_MOT && ctx->tokens[stream_id][i] >= TM2_DELTAS) { + av_log(ctx->avctx, AV_LOG_ERROR, "Invalid delta token index %d for type %d, n=%d\n", + ctx->tokens[stream_id][i], stream_id, i); + return AVERROR_INVALIDDATA; + } + } } tm2_free_codes(&codes); @@ -347,9 +362,9 @@ static inline int GET_TOK(TM2Context *ctx,int type) { int *Y, *U, *V;\ int Ystride, Ustride, Vstride;\ \ - Ystride = ctx->avctx->width;\ - Vstride = (ctx->avctx->width + 1) >> 1;\ - Ustride = (ctx->avctx->width + 1) >> 1;\ + Ystride = ctx->y_stride;\ + Vstride = ctx->uv_stride;\ + Ustride = ctx->uv_stride;\ Y = (ctx->cur?ctx->Y2:ctx->Y1) + by * 4 * Ystride + bx * 4;\ V = (ctx->cur?ctx->V2:ctx->V1) + by * 2 * Vstride + bx * 2;\ U = (ctx->cur?ctx->U2:ctx->U1) + by * 2 * Ustride + bx * 2;\ @@ -637,6 +652,8 @@ static inline void tm2_motion_block(TM2Context *ctx, AVFrame *pic, int bx, int b mx = GET_TOK(ctx, TM2_MOT); my = GET_TOK(ctx, TM2_MOT); + mx = av_clip(mx, -(bx * 4 + 4), ctx->avctx->width - bx * 4); + my = av_clip(my, -(by * 4 + 4), ctx->avctx->height - by * 4); Yo += my * oYstride + mx; Uo += (my >> 1) * oUstride + (mx >> 1); @@ -677,15 +694,12 @@ static inline void tm2_motion_block(TM2Context *ctx, AVFrame *pic, int bx, int b static int tm2_decode_blocks(TM2Context *ctx, AVFrame *p) { int i, j; - int bw, bh; + int w = ctx->avctx->width, h = ctx->avctx->height, bw = w >> 2, bh = h >> 2, cw = w >> 1; int type; int keyframe = 1; int *Y, *U, *V; uint8_t *dst; - bw = ctx->avctx->width >> 2; - bh = ctx->avctx->height >> 2; - for(i = 0; i < TM2_NUM_STREAMS; i++) ctx->tok_ptrs[i] = 0; @@ -738,17 +752,54 @@ static int tm2_decode_blocks(TM2Context *ctx, AVFrame *p) U = (ctx->cur?ctx->U2:ctx->U1); V = (ctx->cur?ctx->V2:ctx->V1); dst = p->data[0]; - for(j = 0; j < ctx->avctx->height; j++){ - for(i = 0; i < ctx->avctx->width; i++){ + for(j = 0; j < h; j++){ + for(i = 0; i < w; i++){ int y = Y[i], u = U[i >> 1], v = V[i >> 1]; dst[3*i+0] = av_clip_uint8(y + v); dst[3*i+1] = av_clip_uint8(y); dst[3*i+2] = av_clip_uint8(y + u); } - Y += ctx->avctx->width; + + /* horizontal edge extension */ + Y[-4] = Y[-3] = Y[-2] = Y[-1] = Y[0]; + Y[w + 3] = Y[w + 2] = Y[w + 1] = Y[w] = Y[w - 1]; + + /* vertical edge extension */ + if (j == 0) { + memcpy(Y - 4 - 1 * ctx->y_stride, Y - 4, ctx->y_stride); + memcpy(Y - 4 - 2 * ctx->y_stride, Y - 4, ctx->y_stride); + memcpy(Y - 4 - 3 * ctx->y_stride, Y - 4, ctx->y_stride); + memcpy(Y - 4 - 4 * ctx->y_stride, Y - 4, ctx->y_stride); + } else if (j == h - 1) { + memcpy(Y - 4 + 1 * ctx->y_stride, Y - 4, ctx->y_stride); + memcpy(Y - 4 + 2 * ctx->y_stride, Y - 4, ctx->y_stride); + memcpy(Y - 4 + 3 * ctx->y_stride, Y - 4, ctx->y_stride); + memcpy(Y - 4 + 4 * ctx->y_stride, Y - 4, ctx->y_stride); + } + + Y += ctx->y_stride; if (j & 1) { - U += ctx->avctx->width >> 1; - V += ctx->avctx->width >> 1; + /* horizontal edge extension */ + U[-2] = U[-1] = U[0]; + V[-2] = V[-1] = V[0]; + U[cw + 1] = U[cw] = U[cw - 1]; + V[cw + 1] = V[cw] = V[cw - 1]; + + /* vertical edge extension */ + if (j == 1) { + memcpy(U - 2 - 1 * ctx->uv_stride, U - 2, ctx->uv_stride); + memcpy(V - 2 - 1 * ctx->uv_stride, V - 2, ctx->uv_stride); + memcpy(U - 2 - 2 * ctx->uv_stride, U - 2, ctx->uv_stride); + memcpy(V - 2 - 2 * ctx->uv_stride, V - 2, ctx->uv_stride); + } else if (j == h - 1) { + memcpy(U - 2 + 1 * ctx->uv_stride, U - 2, ctx->uv_stride); + memcpy(V - 2 + 1 * ctx->uv_stride, V - 2, ctx->uv_stride); + memcpy(U - 2 + 2 * ctx->uv_stride, U - 2, ctx->uv_stride); + memcpy(V - 2 + 2 * ctx->uv_stride, V - 2, ctx->uv_stride); + } + + U += ctx->uv_stride; + V += ctx->uv_stride; } dst += p->linesize[0]; } @@ -765,7 +816,7 @@ static int decode_frame(AVCodecContext *avctx, AVPacket *avpkt) { const uint8_t *buf = avpkt->data; - int buf_size = avpkt->size; + int buf_size = avpkt->size & ~3; TM2Context * const l = avctx->priv_data; AVFrame * const p= (AVFrame*)&l->pic; int i, skip, t; @@ -790,9 +841,12 @@ static int decode_frame(AVCodecContext *avctx, } for(i = 0; i < TM2_NUM_STREAMS; i++){ - t = tm2_read_stream(l, l->buffer + skip, tm2_stream_order[i], buf_size); - if(t == -1){ - return -1; + if (skip >= buf_size) { + return AVERROR_INVALIDDATA; + } + t = tm2_read_stream(l, l->buffer + skip, tm2_stream_order[i], buf_size - skip); + if(t < 0){ + return t; } skip += t; } @@ -811,7 +865,7 @@ static int decode_frame(AVCodecContext *avctx, static av_cold int decode_init(AVCodecContext *avctx){ TM2Context * const l = avctx->priv_data; - int i; + int i, w = avctx->width, h = avctx->height; if((avctx->width & 3) || (avctx->height & 3)){ av_log(avctx, AV_LOG_ERROR, "Width and height must be multiple of 4\n"); @@ -825,21 +879,46 @@ static av_cold int decode_init(AVCodecContext *avctx){ dsputil_init(&l->dsp, avctx); - l->last = av_malloc(4 * sizeof(int) * (avctx->width >> 2)); - l->clast = av_malloc(4 * sizeof(int) * (avctx->width >> 2)); + l->last = av_malloc(4 * sizeof(*l->last) * (w >> 2)); + l->clast = av_malloc(4 * sizeof(*l->clast) * (w >> 2)); for(i = 0; i < TM2_NUM_STREAMS; i++) { l->tokens[i] = NULL; l->tok_lens[i] = 0; } - l->Y1 = av_malloc(sizeof(int) * avctx->width * avctx->height); - l->U1 = av_malloc(sizeof(int) * ((avctx->width + 1) >> 1) * ((avctx->height + 1) >> 1)); - l->V1 = av_malloc(sizeof(int) * ((avctx->width + 1) >> 1) * ((avctx->height + 1) >> 1)); - l->Y2 = av_malloc(sizeof(int) * avctx->width * avctx->height); - l->U2 = av_malloc(sizeof(int) * ((avctx->width + 1) >> 1) * ((avctx->height + 1) >> 1)); - l->V2 = av_malloc(sizeof(int) * ((avctx->width + 1) >> 1) * ((avctx->height + 1) >> 1)); + w += 8; + h += 8; + l->Y1_base = av_malloc(sizeof(*l->Y1_base) * w * h); + l->Y2_base = av_malloc(sizeof(*l->Y2_base) * w * h); + l->y_stride = w; + w = (w + 1) >> 1; + h = (h + 1) >> 1; + l->U1_base = av_malloc(sizeof(*l->U1_base) * w * h); + l->V1_base = av_malloc(sizeof(*l->V1_base) * w * h); + l->U2_base = av_malloc(sizeof(*l->U2_base) * w * h); + l->V2_base = av_malloc(sizeof(*l->V1_base) * w * h); + l->uv_stride = w; l->cur = 0; + if (!l->Y1_base || !l->Y2_base || !l->U1_base || + !l->V1_base || !l->U2_base || !l->V2_base || + !l->last || !l->clast) { + av_freep(&l->Y1_base); + av_freep(&l->Y2_base); + av_freep(&l->U1_base); + av_freep(&l->U2_base); + av_freep(&l->V1_base); + av_freep(&l->V2_base); + av_freep(&l->last); + av_freep(&l->clast); + return AVERROR(ENOMEM); + } + l->Y1 = l->Y1_base + l->y_stride * 4 + 4; + l->Y2 = l->Y2_base + l->y_stride * 4 + 4; + l->U1 = l->U1_base + l->uv_stride * 2 + 2; + l->U2 = l->U2_base + l->uv_stride * 2 + 2; + l->V1 = l->V1_base + l->uv_stride * 2 + 2; + l->V2 = l->V2_base + l->uv_stride * 2 + 2; return 0; } @@ -854,12 +933,12 @@ static av_cold int decode_end(AVCodecContext *avctx){ for(i = 0; i < TM2_NUM_STREAMS; i++) av_free(l->tokens[i]); if(l->Y1){ - av_free(l->Y1); - av_free(l->U1); - av_free(l->V1); - av_free(l->Y2); - av_free(l->U2); - av_free(l->V2); + av_free(l->Y1_base); + av_free(l->U1_base); + av_free(l->V1_base); + av_free(l->Y2_base); + av_free(l->U2_base); + av_free(l->V2_base); } av_freep(&l->buffer); l->buffer_size = 0; diff --git a/libavcodec/truespeech.c b/libavcodec/truespeech.c index 9bbbf5172e..fb96a3d3d1 100644 --- a/libavcodec/truespeech.c +++ b/libavcodec/truespeech.c @@ -21,6 +21,7 @@ #include "libavutil/intreadwrite.h" #include "avcodec.h" +#include "internal.h" #include "dsputil.h" #include "get_bits.h" @@ -325,7 +326,7 @@ static int truespeech_decode_frame(AVCodecContext *avctx, void *data, /* get output buffer */ c->frame.nb_samples = iterations * 240; - if ((ret = avctx->get_buffer(avctx, &c->frame)) < 0) { + if ((ret = ff_get_buffer(avctx, &c->frame)) < 0) { av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n"); return ret; } diff --git a/libavcodec/tscc.c b/libavcodec/tscc.c index c07f3a87f7..75728778ca 100644 --- a/libavcodec/tscc.c +++ b/libavcodec/tscc.c @@ -58,6 +58,7 @@ typedef struct TsccContext { unsigned int decomp_size; // Decompression buffer unsigned char* decomp_buf; + GetByteContext gb; int height; z_stream zstream; @@ -105,8 +106,11 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *data_size, AVPac } - if(zret != Z_DATA_ERROR) - ff_msrle_decode(avctx, (AVPicture*)&c->pic, c->bpp, c->decomp_buf, c->decomp_size - c->zstream.avail_out); + if (zret != Z_DATA_ERROR) { + bytestream2_init(&c->gb, c->decomp_buf, + c->decomp_size - c->zstream.avail_out); + ff_msrle_decode(avctx, (AVPicture*)&c->pic, c->bpp, &c->gb); + } /* make the palette available on the way out */ if (c->avctx->pix_fmt == PIX_FMT_PAL8) { diff --git a/libavcodec/tta.c b/libavcodec/tta.c index 8d49bc80d2..743344c3e2 100644 --- a/libavcodec/tta.c +++ b/libavcodec/tta.c @@ -31,7 +31,9 @@ //#define DEBUG #include #include "avcodec.h" +#include "internal.h" #include "get_bits.h" +#include "libavutil/crc.h" #define FORMAT_SIMPLE 1 #define FORMAT_ENCRYPTED 2 @@ -58,8 +60,10 @@ typedef struct TTAContext { AVCodecContext *avctx; AVFrame frame; GetBitContext gb; + const AVCRC *crc_table; - int format, channels, bps, data_length; + int format, channels, bps; + unsigned data_length; int frame_length, last_frame_length, total_frames; int32_t *decode_buffer; @@ -198,10 +202,23 @@ static const int64_t tta_channel_layouts[7] = { AV_CH_LAYOUT_7POINT1_WIDE }; +static int tta_check_crc(TTAContext *s, const uint8_t *buf, int buf_size) +{ + uint32_t crc, CRC; + + CRC = AV_RL32(buf + buf_size); + crc = av_crc(s->crc_table, 0xFFFFFFFFU, buf, buf_size); + if (CRC != (crc ^ 0xFFFFFFFFU)) { + av_log(s->avctx, AV_LOG_ERROR, "CRC error\n"); + return AVERROR_INVALIDDATA; + } + + return 0; +} + static av_cold int tta_decode_init(AVCodecContext * avctx) { TTAContext *s = avctx->priv_data; - int i; s->avctx = avctx; @@ -212,8 +229,14 @@ static av_cold int tta_decode_init(AVCodecContext * avctx) init_get_bits(&s->gb, avctx->extradata, avctx->extradata_size * 8); if (show_bits_long(&s->gb, 32) == AV_RL32("TTA1")) { + if (avctx->err_recognition & AV_EF_CRCCHECK) { + s->crc_table = av_crc_get_table(AV_CRC_32_IEEE_LE); + if (tta_check_crc(s, avctx->extradata, 18)) + return AVERROR_INVALIDDATA; + } + /* signature */ - skip_bits(&s->gb, 32); + skip_bits_long(&s->gb, 32); s->format = get_bits(&s->gb, 16); if (s->format > 2) { @@ -231,11 +254,14 @@ static av_cold int tta_decode_init(AVCodecContext * avctx) s->bps = (avctx->bits_per_coded_sample + 7) / 8; avctx->sample_rate = get_bits_long(&s->gb, 32); s->data_length = get_bits_long(&s->gb, 32); - skip_bits(&s->gb, 32); // CRC32 of header + skip_bits_long(&s->gb, 32); // CRC32 of header if (s->channels == 0) { av_log(s->avctx, AV_LOG_ERROR, "Invalid number of channels\n"); return AVERROR_INVALIDDATA; + } else if (avctx->sample_rate == 0) { + av_log(s->avctx, AV_LOG_ERROR, "Invalid samplerate\n"); + return AVERROR_INVALIDDATA; } switch(s->bps) { @@ -255,7 +281,7 @@ static av_cold int tta_decode_init(AVCodecContext * avctx) } // prevent overflow - if (avctx->sample_rate > 0x7FFFFF) { + if (avctx->sample_rate > 0x7FFFFFu) { av_log(avctx, AV_LOG_ERROR, "sample_rate too large\n"); return AVERROR(EINVAL); } @@ -272,9 +298,15 @@ static av_cold int tta_decode_init(AVCodecContext * avctx) s->data_length, s->frame_length, s->last_frame_length, s->total_frames); // FIXME: seek table - for (i = 0; i < s->total_frames; i++) - skip_bits(&s->gb, 32); - skip_bits(&s->gb, 32); // CRC32 of seektable + if (avctx->extradata_size <= 26 || s->total_frames > INT_MAX / 4 || + avctx->extradata_size - 26 < s->total_frames * 4) + av_log(avctx, AV_LOG_WARNING, "Seek table missing or too small\n"); + else if (avctx->err_recognition & AV_EF_CRCCHECK) { + if (tta_check_crc(s, avctx->extradata + 22, s->total_frames * 4)) + return AVERROR_INVALIDDATA; + } + skip_bits_long(&s->gb, 32 * s->total_frames); + skip_bits_long(&s->gb, 32); // CRC32 of seektable if(s->frame_length >= UINT_MAX / (s->channels * sizeof(int32_t))){ av_log(avctx, AV_LOG_ERROR, "frame_length too large\n"); @@ -310,6 +342,11 @@ static int tta_decode_frame(AVCodecContext *avctx, void *data, int cur_chan = 0, framelen = s->frame_length; int32_t *p; + if (avctx->err_recognition & AV_EF_CRCCHECK) { + if (buf_size < 4 || tta_check_crc(s, buf, buf_size - 4)) + return AVERROR_INVALIDDATA; + } + init_get_bits(&s->gb, buf, buf_size*8); // FIXME: seeking @@ -319,7 +356,7 @@ static int tta_decode_frame(AVCodecContext *avctx, void *data, /* get output buffer */ s->frame.nb_samples = framelen; - if ((ret = avctx->get_buffer(avctx, &s->frame)) < 0) { + if ((ret = ff_get_buffer(avctx, &s->frame)) < 0) { av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n"); return ret; } @@ -413,7 +450,7 @@ static int tta_decode_frame(AVCodecContext *avctx, void *data, if (get_bits_left(&s->gb) < 32) return -1; - skip_bits(&s->gb, 32); // frame crc + skip_bits_long(&s->gb, 32); // frame crc // convert to output buffer switch(s->bps) { diff --git a/libavcodec/twinvq.c b/libavcodec/twinvq.c index 6a0bd4d145..abec32fb08 100644 --- a/libavcodec/twinvq.c +++ b/libavcodec/twinvq.c @@ -20,6 +20,7 @@ */ #include "avcodec.h" +#include "internal.h" #include "get_bits.h" #include "dsputil.h" #include "fft.h" @@ -840,7 +841,7 @@ static int twin_decode_frame(AVCodecContext * avctx, void *data, /* get output buffer */ if (tctx->discarded_packets >= 2) { tctx->frame.nb_samples = mtab->size; - if ((ret = avctx->get_buffer(avctx, &tctx->frame)) < 0) { + if ((ret = ff_get_buffer(avctx, &tctx->frame)) < 0) { av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n"); return ret; } @@ -996,18 +997,20 @@ static void linear_perm(int16_t *out, int16_t *in, int n_blocks, int size) out[i] = block_size * (in[i] % n_blocks) + in[i] / n_blocks; } -static av_cold void construct_perm_table(TwinContext *tctx,enum FrameType ftype) +static av_cold void construct_perm_table(TwinContext *tctx, int ftype) { int block_size; const ModeTab *mtab = tctx->mtab; - int size = tctx->avctx->channels*mtab->fmode[ftype].sub; + int size; int16_t *tmp_perm = (int16_t *) tctx->tmp_buf; if (ftype == FT_PPC) { size = tctx->avctx->channels; block_size = mtab->ppc_shape_len; - } else + } else { + size = tctx->avctx->channels * mtab->fmode[ftype].sub; block_size = mtab->size / mtab->fmode[ftype].sub; + } permutate_in_line(tmp_perm, tctx->n_div[ftype], size, block_size, tctx->length[ftype], @@ -1137,6 +1140,10 @@ static av_cold int twin_decode_init(AVCodecContext *avctx) return -1; } ibps = avctx->bit_rate / (1000 * avctx->channels); + if (ibps < 8 || ibps > 48) { + av_log(avctx, AV_LOG_ERROR, "Bad bitrate per channel value %d\n", ibps); + return AVERROR_INVALIDDATA; + } switch ((isampf << 8) + ibps) { case (8 <<8) + 8: tctx->mtab = &mode_08_08; break; diff --git a/libavcodec/utils.c b/libavcodec/utils.c index 1d6a829cc5..a35da92106 100644 --- a/libavcodec/utils.c +++ b/libavcodec/utils.c @@ -202,8 +202,8 @@ void avcodec_align_dimensions2(AVCodecContext *s, int *width, int *height, break; case PIX_FMT_YUV411P: case PIX_FMT_UYYVYY411: - w_align=32; - h_align=8; + w_align = 32; + h_align = 16 * 2; break; case PIX_FMT_YUV410P: if(s->codec_id == CODEC_ID_SVQ1){ @@ -222,6 +222,10 @@ void avcodec_align_dimensions2(AVCodecContext *s, int *width, int *height, w_align=4; h_align=4; } + if (s->codec_id == CODEC_ID_JV) { + w_align = 8; + h_align = 8; + } break; case PIX_FMT_BGR24: if((s->codec_id == CODEC_ID_MSZH) || (s->codec_id == CODEC_ID_ZLIB)){ @@ -614,7 +618,7 @@ int avcodec_default_reget_buffer(AVCodecContext *s, AVFrame *pic){ if(pic->data[0] == NULL) { /* We will copy from buffer, so must be readable */ pic->buffer_hints |= FF_BUFFER_HINTS_READABLE; - return s->get_buffer(s, pic); + return ff_get_buffer(s, pic); } /* If internal buffer type return the same buffer */ @@ -630,7 +634,7 @@ int avcodec_default_reget_buffer(AVCodecContext *s, AVFrame *pic){ pic->data[i] = pic->base[i] = NULL; pic->opaque = NULL; /* Allocate new frame */ - if (s->get_buffer(s, pic)) + if (ff_get_buffer(s, pic)) return -1; /* Copy image data from old buffer to new buffer */ av_picture_copy((AVPicture*)pic, (AVPicture*)&temp_pic, s->pix_fmt, s->width, @@ -703,6 +707,21 @@ int attribute_align_arg avcodec_open2(AVCodecContext *avctx, AVCodec *codec, AVD int ret = 0; AVDictionary *tmp = NULL; + if (avcodec_is_open(avctx)) + return 0; + + if ((!codec && !avctx->codec)) { + av_log(avctx, AV_LOG_ERROR, "No codec provided to avcodec_open2().\n"); + return AVERROR(EINVAL); + } + if ((codec && avctx->codec && codec != avctx->codec)) { + av_log(avctx, AV_LOG_ERROR, "This AVCodecContext was allocated for %s, " + "but %s passed to avcodec_open2().\n", avctx->codec->name, codec->name); + return AVERROR(EINVAL); + } + if (!codec) + codec = avctx->codec; + if (avctx->extradata_size < 0 || avctx->extradata_size >= FF_MAX_EXTRADATA_SIZE) return AVERROR(EINVAL); @@ -722,11 +741,6 @@ int attribute_align_arg avcodec_open2(AVCodecContext *avctx, AVCodec *codec, AVD goto end; } - if(avctx->codec || !codec) { - ret = AVERROR(EINVAL); - goto end; - } - avctx->internal = av_mallocz(sizeof(AVCodecInternal)); if (!avctx->internal) { ret = AVERROR(ENOMEM); @@ -816,6 +830,12 @@ int attribute_align_arg avcodec_open2(AVCodecContext *avctx, AVCodec *codec, AVD avctx->error_recognition, avctx->err_recognition); #endif + if (avctx->codec_type == AVMEDIA_TYPE_AUDIO && + (!avctx->time_base.num || !avctx->time_base.den)) { + avctx->time_base.num = 1; + avctx->time_base.den = avctx->sample_rate; + } + if (!HAVE_THREADS) av_log(avctx, AV_LOG_WARNING, "Warning: not compiled with thread support, using thread emulation\n"); @@ -879,6 +899,9 @@ int attribute_align_arg avcodec_open2(AVCodecContext *avctx, AVCodec *codec, AVD } else if (avctx->channel_layout) { avctx->channels = av_get_channel_layout_nb_channels(avctx->channel_layout); } + + if (!avctx->rc_initial_buffer_occupancy) + avctx->rc_initial_buffer_occupancy = avctx->rc_buffer_size * 3 / 4; } avctx->pts_correction_num_faulty_pts = @@ -1421,14 +1444,17 @@ av_cold int avcodec_close(AVCodecContext *avctx) return -1; } - if (HAVE_THREADS && avctx->thread_opaque) - ff_thread_free(avctx); - if (avctx->codec && avctx->codec->close) - avctx->codec->close(avctx); - avcodec_default_free_buffers(avctx); - avctx->coded_frame = NULL; - av_freep(&avctx->internal); - if (avctx->codec && avctx->codec->priv_class) + if (avcodec_is_open(avctx)) { + if (HAVE_THREADS && avctx->thread_opaque) + ff_thread_free(avctx); + if (avctx->codec && avctx->codec->close) + avctx->codec->close(avctx); + avcodec_default_free_buffers(avctx); + avctx->coded_frame = NULL; + av_freep(&avctx->internal); + } + + if (avctx->priv_data && avctx->codec && avctx->codec->priv_class) av_opt_free(avctx->priv_data); av_opt_free(avctx); av_freep(&avctx->priv_data); @@ -1960,7 +1986,7 @@ int ff_thread_get_buffer(AVCodecContext *avctx, AVFrame *f) ff_init_buffer_info(avctx, f); - return avctx->get_buffer(avctx, f); + return ff_get_buffer(avctx, f); } void ff_thread_release_buffer(AVCodecContext *avctx, AVFrame *f) @@ -2009,3 +2035,21 @@ enum AVMediaType avcodec_get_type(enum CodecID codec_id) return AVMEDIA_TYPE_UNKNOWN; } + +int avcodec_is_open(AVCodecContext *s) +{ + return !!s->internal; +} + +int ff_get_buffer(AVCodecContext *avctx, AVFrame *frame) +{ + switch (avctx->codec_type) { + case AVMEDIA_TYPE_VIDEO: + if (av_image_check_size(avctx->width, avctx->height, 0, avctx)) { + av_log(avctx, AV_LOG_ERROR, "Invalid dimensions %dx%d\n", + avctx->width, avctx->height); + return AVERROR_INVALIDDATA; + } + } + return avctx->get_buffer(avctx, frame); +} diff --git a/libavcodec/utvideo.c b/libavcodec/utvideo.c index a45f13fa54..293de6ed57 100644 --- a/libavcodec/utvideo.c +++ b/libavcodec/utvideo.c @@ -103,10 +103,10 @@ static int build_huff(const uint8_t *src, VLC *vlc, int *fsym) code += 0x80000000u >> (he[i].len - 1); } - return init_vlc_sparse(vlc, FFMIN(he[last].len, 9), last + 1, - bits, sizeof(*bits), sizeof(*bits), - codes, sizeof(*codes), sizeof(*codes), - syms, sizeof(*syms), sizeof(*syms), 0); + return ff_init_vlc_sparse(vlc, FFMIN(he[last].len, 9), last + 1, + bits, sizeof(*bits), sizeof(*bits), + codes, sizeof(*codes), sizeof(*codes), + syms, sizeof(*syms), sizeof(*syms), 0); } static int decode_plane(UtvideoContext *c, int plane_no, @@ -207,11 +207,11 @@ static int decode_plane(UtvideoContext *c, int plane_no, get_bits_left(&gb)); } - free_vlc(&vlc); + ff_free_vlc(&vlc); return 0; fail: - free_vlc(&vlc); + ff_free_vlc(&vlc); return AVERROR_INVALIDDATA; } @@ -246,6 +246,8 @@ static void restore_median(uint8_t *src, int step, int stride, for (slice = 0; slice < slices; slice++) { slice_start = ((slice * height) / slices) & cmask; slice_height = ((((slice + 1) * height) / slices) & cmask) - slice_start; + if (!slice_height) + continue; bsrc = src + slice_start * stride; @@ -301,6 +303,8 @@ static void restore_median_il(uint8_t *src, int step, int stride, slice_start = ((slice * height) / slices) & cmask; slice_height = ((((slice + 1) * height) / slices) & cmask) - slice_start; slice_height >>= 1; + if (!slice_height) + continue; bsrc = src + slice_start * stride; @@ -358,13 +362,12 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *data_size, AVPac { const uint8_t *buf = avpkt->data; int buf_size = avpkt->size; - const uint8_t *buf_end = buf + buf_size; UtvideoContext *c = avctx->priv_data; - const uint8_t *ptr; int i, j; const uint8_t *plane_start[5]; int plane_size, max_slice_size = 0, slice_start, slice_end, slice_size; int ret; + GetByteContext gb; if (c->pic.data[0]) ff_thread_release_buffer(avctx, &c->pic); @@ -379,20 +382,21 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *data_size, AVPac ff_thread_finish_setup(avctx); /* parse plane structure to retrieve frame flags and validate slice offsets */ - ptr = buf; + bytestream2_init(&gb, buf, buf_size); for (i = 0; i < c->planes; i++) { - plane_start[i] = ptr; - if (buf_end - ptr < 256 + 4 * c->slices) { + plane_start[i] = gb.buffer; + if (bytestream2_get_bytes_left(&gb) < 256 + 4 * c->slices) { av_log(avctx, AV_LOG_ERROR, "Insufficient data for a plane\n"); return AVERROR_INVALIDDATA; } - ptr += 256; + bytestream2_skipu(&gb, 256); slice_start = 0; slice_end = 0; for (j = 0; j < c->slices; j++) { - slice_end = bytestream_get_le32(&ptr); + slice_end = bytestream2_get_le32u(&gb); slice_size = slice_end - slice_start; - if (slice_size < 0) { + if (slice_end <= 0 || slice_size <= 0 || + bytestream2_get_bytes_left(&gb) < slice_end) { av_log(avctx, AV_LOG_ERROR, "Incorrect slice size\n"); return AVERROR_INVALIDDATA; } @@ -400,18 +404,14 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *data_size, AVPac max_slice_size = FFMAX(max_slice_size, slice_size); } plane_size = slice_end; - if (buf_end - ptr < plane_size) { - av_log(avctx, AV_LOG_ERROR, "Plane size is bigger than available data\n"); - return AVERROR_INVALIDDATA; - } - ptr += plane_size; + bytestream2_skipu(&gb, plane_size); } - plane_start[c->planes] = ptr; - if (buf_end - ptr < c->frame_info_size) { + plane_start[c->planes] = gb.buffer; + if (bytestream2_get_bytes_left(&gb) < c->frame_info_size) { av_log(avctx, AV_LOG_ERROR, "Not enough data for frame information\n"); return AVERROR_INVALIDDATA; } - c->frame_info = AV_RL32(ptr); + c->frame_info = bytestream2_get_le32u(&gb); av_log(avctx, AV_LOG_DEBUG, "frame information flags %X\n", c->frame_info); c->frame_pred = (c->frame_info >> 8) & 3; diff --git a/libavcodec/vc1.c b/libavcodec/vc1.c index 64884fcc50..e84cc0f88b 100644 --- a/libavcodec/vc1.c +++ b/libavcodec/vc1.c @@ -493,7 +493,7 @@ static int decode_sequence_header_adv(VC1Context *v, GetBitContext *gb) int nr, dr; nr = get_bits(gb, 8); dr = get_bits(gb, 4); - if (nr && nr < 8 && dr && dr < 3) { + if (nr > 0 && nr < 8 && dr > 0 && dr < 3) { v->s.avctx->time_base.num = ff_vc1_fps_dr[dr - 1]; v->s.avctx->time_base.den = ff_vc1_fps_nr[nr - 1] * 1000; } @@ -578,6 +578,8 @@ int vc1_parse_frame_header(VC1Context *v, GetBitContext* gb) { int pqindex, lowquant, status; + v->field_mode = 0; + v->fcm = 0; if (v->finterpflag) v->interpfrm = get_bits1(gb); skip_bits(gb, 2); //framecnt unused @@ -824,7 +826,7 @@ int vc1_parse_frame_header_adv(VC1Context *v, GetBitContext* gb) int mbmodetab, imvtab, icbptab, twomvbptab, fourmvbptab; /* useful only for debugging */ int scale, shift, i; /* for initializing LUT for intensity compensation */ - v->numref=0; + v->numref = 0; v->p_frame_skipped = 0; if (v->second_field) { if(v->fcm!=2 || v->field_mode!=1) @@ -1250,3 +1252,365 @@ int vc1_parse_frame_header_adv(VC1Context *v, GetBitContext* gb) } return 0; } + +static const uint32_t vc1_ac_tables[AC_MODES][186][2] = { +{ +{ 0x0001, 2}, { 0x0005, 3}, { 0x000D, 4}, { 0x0012, 5}, { 0x000E, 6}, { 0x0015, 7}, +{ 0x0013, 8}, { 0x003F, 8}, { 0x004B, 9}, { 0x011F, 9}, { 0x00B8, 10}, { 0x03E3, 10}, +{ 0x0172, 11}, { 0x024D, 12}, { 0x03DA, 12}, { 0x02DD, 13}, { 0x1F55, 13}, { 0x05B9, 14}, +{ 0x3EAE, 14}, { 0x0000, 4}, { 0x0010, 5}, { 0x0008, 7}, { 0x0020, 8}, { 0x0029, 9}, +{ 0x01F4, 9}, { 0x0233, 10}, { 0x01E0, 11}, { 0x012A, 12}, { 0x03DD, 12}, { 0x050A, 13}, +{ 0x1F29, 13}, { 0x0A42, 14}, { 0x1272, 15}, { 0x1737, 15}, { 0x0003, 5}, { 0x0011, 7}, +{ 0x00C4, 8}, { 0x004B, 10}, { 0x00B4, 11}, { 0x07D4, 11}, { 0x0345, 12}, { 0x02D7, 13}, +{ 0x07BF, 13}, { 0x0938, 14}, { 0x0BBB, 14}, { 0x095E, 15}, { 0x0013, 5}, { 0x0078, 7}, +{ 0x0069, 9}, { 0x0232, 10}, { 0x0461, 11}, { 0x03EC, 12}, { 0x0520, 13}, { 0x1F2A, 13}, +{ 0x3E50, 14}, { 0x3E51, 14}, { 0x1486, 15}, { 0x000C, 6}, { 0x0024, 9}, { 0x0094, 11}, +{ 0x08C0, 12}, { 0x0F09, 14}, { 0x1EF0, 15}, { 0x003D, 6}, { 0x0053, 9}, { 0x01A0, 11}, +{ 0x02D6, 13}, { 0x0F08, 14}, { 0x0013, 7}, { 0x007C, 9}, { 0x07C1, 11}, { 0x04AC, 14}, +{ 0x001B, 7}, { 0x00A0, 10}, { 0x0344, 12}, { 0x0F79, 14}, { 0x0079, 7}, { 0x03E1, 10}, +{ 0x02D4, 13}, { 0x2306, 14}, { 0x0021, 8}, { 0x023C, 10}, { 0x0FAE, 12}, { 0x23DE, 14}, +{ 0x0035, 8}, { 0x0175, 11}, { 0x07B3, 13}, { 0x00C5, 8}, { 0x0174, 11}, { 0x0785, 13}, +{ 0x0048, 9}, { 0x01A3, 11}, { 0x049E, 13}, { 0x002C, 9}, { 0x00FA, 10}, { 0x07D6, 11}, +{ 0x0092, 10}, { 0x05CC, 13}, { 0x1EF1, 15}, { 0x00A3, 10}, { 0x03ED, 12}, { 0x093E, 14}, +{ 0x01E2, 11}, { 0x1273, 15}, { 0x07C4, 11}, { 0x1487, 15}, { 0x0291, 12}, { 0x0293, 12}, +{ 0x0F8A, 12}, { 0x0509, 13}, { 0x0508, 13}, { 0x078D, 13}, { 0x07BE, 13}, { 0x078C, 13}, +{ 0x04AE, 14}, { 0x0BBA, 14}, { 0x2307, 14}, { 0x0B9A, 14}, { 0x1736, 15}, { 0x000E, 4}, +{ 0x0045, 7}, { 0x01F3, 9}, { 0x047A, 11}, { 0x05DC, 13}, { 0x23DF, 14}, { 0x0019, 5}, +{ 0x0028, 9}, { 0x0176, 11}, { 0x049D, 13}, { 0x23DD, 14}, { 0x0030, 6}, { 0x00A2, 10}, +{ 0x02EF, 12}, { 0x05B8, 14}, { 0x003F, 6}, { 0x00A5, 10}, { 0x03DB, 12}, { 0x093F, 14}, +{ 0x0044, 7}, { 0x07CB, 11}, { 0x095F, 15}, { 0x0063, 7}, { 0x03C3, 12}, { 0x0015, 8}, +{ 0x08F6, 12}, { 0x0017, 8}, { 0x0498, 13}, { 0x002C, 8}, { 0x07B2, 13}, { 0x002F, 8}, +{ 0x1F54, 13}, { 0x008D, 8}, { 0x07BD, 13}, { 0x008E, 8}, { 0x1182, 13}, { 0x00FB, 8}, +{ 0x050B, 13}, { 0x002D, 8}, { 0x07C0, 11}, { 0x0079, 9}, { 0x1F5F, 13}, { 0x007A, 9}, +{ 0x1F56, 13}, { 0x0231, 10}, { 0x03E4, 10}, { 0x01A1, 11}, { 0x0143, 11}, { 0x01F7, 11}, +{ 0x016F, 12}, { 0x0292, 12}, { 0x02E7, 12}, { 0x016C, 12}, { 0x016D, 12}, { 0x03DC, 12}, +{ 0x0F8B, 12}, { 0x0499, 13}, { 0x03D8, 12}, { 0x078E, 13}, { 0x02D5, 13}, { 0x1F5E, 13}, +{ 0x1F2B, 13}, { 0x078F, 13}, { 0x04AD, 14}, { 0x3EAF, 14}, { 0x23DC, 14}, { 0x004A, 9} +}, +{ +{ 0x0000, 3}, { 0x0003, 4}, { 0x000B, 5}, { 0x0014, 6}, { 0x003F, 6}, { 0x005D, 7}, +{ 0x00A2, 8}, { 0x00AC, 9}, { 0x016E, 9}, { 0x020A, 10}, { 0x02E2, 10}, { 0x0432, 11}, +{ 0x05C9, 11}, { 0x0827, 12}, { 0x0B54, 12}, { 0x04E6, 13}, { 0x105F, 13}, { 0x172A, 13}, +{ 0x20B2, 14}, { 0x2D4E, 14}, { 0x39F0, 14}, { 0x4175, 15}, { 0x5A9E, 15}, { 0x0004, 4}, +{ 0x001E, 5}, { 0x0042, 7}, { 0x00B6, 8}, { 0x0173, 9}, { 0x0395, 10}, { 0x072E, 11}, +{ 0x0B94, 12}, { 0x16A4, 13}, { 0x20B3, 14}, { 0x2E45, 14}, { 0x0005, 5}, { 0x0040, 7}, +{ 0x0049, 9}, { 0x028F, 10}, { 0x05CB, 11}, { 0x048A, 13}, { 0x09DD, 14}, { 0x73E2, 15}, +{ 0x0018, 5}, { 0x0025, 8}, { 0x008A, 10}, { 0x051B, 11}, { 0x0E5F, 12}, { 0x09C9, 14}, +{ 0x139C, 15}, { 0x0029, 6}, { 0x004F, 9}, { 0x0412, 11}, { 0x048D, 13}, { 0x2E41, 14}, +{ 0x0038, 6}, { 0x010E, 9}, { 0x05A8, 11}, { 0x105C, 13}, { 0x39F2, 14}, { 0x0058, 7}, +{ 0x021F, 10}, { 0x0E7E, 12}, { 0x39FF, 14}, { 0x0023, 8}, { 0x02E3, 10}, { 0x04E5, 13}, +{ 0x2E40, 14}, { 0x00A1, 8}, { 0x05BE, 11}, { 0x09C8, 14}, { 0x0083, 8}, { 0x013A, 11}, +{ 0x1721, 13}, { 0x0044, 9}, { 0x0276, 12}, { 0x39F6, 14}, { 0x008B, 10}, { 0x04EF, 13}, +{ 0x5A9B, 15}, { 0x0208, 10}, { 0x1CFE, 13}, { 0x0399, 10}, { 0x1CB4, 13}, { 0x039E, 10}, +{ 0x39F3, 14}, { 0x05AB, 11}, { 0x73E3, 15}, { 0x0737, 11}, { 0x5A9F, 15}, { 0x082D, 12}, +{ 0x0E69, 12}, { 0x0E68, 12}, { 0x0433, 11}, { 0x0B7B, 12}, { 0x2DF8, 14}, { 0x2E56, 14}, +{ 0x2E57, 14}, { 0x39F7, 14}, { 0x51A5, 15}, { 0x0003, 3}, { 0x002A, 6}, { 0x00E4, 8}, +{ 0x028E, 10}, { 0x0735, 11}, { 0x1058, 13}, { 0x1CFA, 13}, { 0x2DF9, 14}, { 0x4174, 15}, +{ 0x0009, 4}, { 0x0054, 8}, { 0x0398, 10}, { 0x048B, 13}, { 0x139D, 15}, { 0x000D, 4}, +{ 0x00AD, 9}, { 0x0826, 12}, { 0x2D4C, 14}, { 0x0011, 5}, { 0x016B, 9}, { 0x0B7F, 12}, +{ 0x51A4, 15}, { 0x0019, 5}, { 0x021B, 10}, { 0x16FD, 13}, { 0x001D, 5}, { 0x0394, 10}, +{ 0x28D3, 14}, { 0x002B, 6}, { 0x05BC, 11}, { 0x5A9A, 15}, { 0x002F, 6}, { 0x0247, 12}, +{ 0x0010, 7}, { 0x0A35, 12}, { 0x003E, 6}, { 0x0B7A, 12}, { 0x0059, 7}, { 0x105E, 13}, +{ 0x0026, 8}, { 0x09CF, 14}, { 0x0055, 8}, { 0x1CB5, 13}, { 0x0057, 8}, { 0x0E5B, 12}, +{ 0x00A0, 8}, { 0x1468, 13}, { 0x0170, 9}, { 0x0090, 10}, { 0x01CE, 9}, { 0x021A, 10}, +{ 0x0218, 10}, { 0x0168, 9}, { 0x021E, 10}, { 0x0244, 12}, { 0x0736, 11}, { 0x0138, 11}, +{ 0x0519, 11}, { 0x0E5E, 12}, { 0x072C, 11}, { 0x0B55, 12}, { 0x09DC, 14}, { 0x20BB, 14}, +{ 0x048C, 13}, { 0x1723, 13}, { 0x2E44, 14}, { 0x16A5, 13}, { 0x0518, 11}, { 0x39FE, 14}, +{ 0x0169, 9} +}, +{ +{ 0x0001, 2}, { 0x0006, 3}, { 0x000F, 4}, { 0x0016, 5}, { 0x0020, 6}, { 0x0018, 7}, +{ 0x0008, 8}, { 0x009A, 8}, { 0x0056, 9}, { 0x013E, 9}, { 0x00F0, 10}, { 0x03A5, 10}, +{ 0x0077, 11}, { 0x01EF, 11}, { 0x009A, 12}, { 0x005D, 13}, { 0x0001, 4}, { 0x0011, 5}, +{ 0x0002, 7}, { 0x000B, 8}, { 0x0012, 9}, { 0x01D6, 9}, { 0x027E, 10}, { 0x0191, 11}, +{ 0x00EA, 12}, { 0x03DC, 12}, { 0x013B, 13}, { 0x0004, 5}, { 0x0014, 7}, { 0x009E, 8}, +{ 0x0009, 10}, { 0x01AC, 11}, { 0x01E2, 11}, { 0x03CA, 12}, { 0x005F, 13}, { 0x0017, 5}, +{ 0x004E, 7}, { 0x005E, 9}, { 0x00F3, 10}, { 0x01AD, 11}, { 0x00EC, 12}, { 0x05F0, 13}, +{ 0x000E, 6}, { 0x00E1, 8}, { 0x03A4, 10}, { 0x009C, 12}, { 0x013D, 13}, { 0x003B, 6}, +{ 0x001C, 9}, { 0x0014, 11}, { 0x09BE, 12}, { 0x0006, 7}, { 0x007A, 9}, { 0x0190, 11}, +{ 0x0137, 13}, { 0x001B, 7}, { 0x0008, 10}, { 0x075C, 11}, { 0x0071, 7}, { 0x00D7, 10}, +{ 0x09BF, 12}, { 0x0007, 8}, { 0x00AF, 10}, { 0x04CC, 11}, { 0x0034, 8}, { 0x0265, 10}, +{ 0x009F, 12}, { 0x00E0, 8}, { 0x0016, 11}, { 0x0327, 12}, { 0x0015, 9}, { 0x017D, 11}, +{ 0x0EBB, 12}, { 0x0014, 9}, { 0x00F6, 10}, { 0x01E4, 11}, { 0x00CB, 10}, { 0x099D, 12}, +{ 0x00CA, 10}, { 0x02FC, 12}, { 0x017F, 11}, { 0x04CD, 11}, { 0x02FD, 12}, { 0x04FE, 11}, +{ 0x013A, 13}, { 0x000A, 4}, { 0x0042, 7}, { 0x01D3, 9}, { 0x04DD, 11}, { 0x0012, 5}, +{ 0x00E8, 8}, { 0x004C, 11}, { 0x0136, 13}, { 0x0039, 6}, { 0x0264, 10}, { 0x0EBA, 12}, +{ 0x0000, 7}, { 0x00AE, 10}, { 0x099C, 12}, { 0x001F, 7}, { 0x04DE, 11}, { 0x0043, 7}, +{ 0x04DC, 11}, { 0x0003, 8}, { 0x03CB, 12}, { 0x0006, 8}, { 0x099E, 12}, { 0x002A, 8}, +{ 0x05F1, 13}, { 0x000F, 8}, { 0x09FE, 12}, { 0x0033, 8}, { 0x09FF, 12}, { 0x0098, 8}, +{ 0x099F, 12}, { 0x00EA, 8}, { 0x013C, 13}, { 0x002E, 8}, { 0x0192, 11}, { 0x0136, 9}, +{ 0x006A, 9}, { 0x0015, 11}, { 0x03AF, 10}, { 0x01E3, 11}, { 0x0074, 11}, { 0x00EB, 12}, +{ 0x02F9, 12}, { 0x005C, 13}, { 0x00ED, 12}, { 0x03DD, 12}, { 0x0326, 12}, { 0x005E, 13}, +{ 0x0016, 7} +}, +{ +{ 0x0004, 3}, { 0x0014, 5}, { 0x0017, 7}, { 0x007F, 8}, { 0x0154, 9}, { 0x01F2, 10}, +{ 0x00BF, 11}, { 0x0065, 12}, { 0x0AAA, 12}, { 0x0630, 13}, { 0x1597, 13}, { 0x03B7, 14}, +{ 0x2B22, 14}, { 0x0BE6, 15}, { 0x000B, 4}, { 0x0037, 7}, { 0x0062, 9}, { 0x0007, 11}, +{ 0x0166, 12}, { 0x00CE, 13}, { 0x1590, 13}, { 0x05F6, 14}, { 0x0BE7, 15}, { 0x0007, 5}, +{ 0x006D, 8}, { 0x0003, 11}, { 0x031F, 12}, { 0x05F2, 14}, { 0x0002, 6}, { 0x0061, 9}, +{ 0x0055, 12}, { 0x01DF, 14}, { 0x001A, 6}, { 0x001E, 10}, { 0x0AC9, 12}, { 0x2B23, 14}, +{ 0x001E, 6}, { 0x001F, 10}, { 0x0AC3, 12}, { 0x2B2B, 14}, { 0x0006, 7}, { 0x0004, 11}, +{ 0x02F8, 13}, { 0x0019, 7}, { 0x0006, 11}, { 0x063D, 13}, { 0x0057, 7}, { 0x0182, 11}, +{ 0x2AA2, 14}, { 0x0004, 8}, { 0x0180, 11}, { 0x059C, 14}, { 0x007D, 8}, { 0x0164, 12}, +{ 0x076D, 15}, { 0x0002, 9}, { 0x018D, 11}, { 0x1581, 13}, { 0x00AD, 8}, { 0x0060, 12}, +{ 0x0C67, 14}, { 0x001C, 9}, { 0x00EE, 13}, { 0x0003, 9}, { 0x02CF, 13}, { 0x00D9, 9}, +{ 0x1580, 13}, { 0x0002, 11}, { 0x0183, 11}, { 0x0057, 12}, { 0x0061, 12}, { 0x0031, 11}, +{ 0x0066, 12}, { 0x0631, 13}, { 0x0632, 13}, { 0x00AC, 13}, { 0x031D, 12}, { 0x0076, 12}, +{ 0x003A, 11}, { 0x0165, 12}, { 0x0C66, 14}, { 0x0003, 2}, { 0x0054, 7}, { 0x02AB, 10}, +{ 0x0016, 13}, { 0x05F7, 14}, { 0x0005, 4}, { 0x00F8, 9}, { 0x0AA9, 12}, { 0x005F, 15}, +{ 0x0004, 4}, { 0x001C, 10}, { 0x1550, 13}, { 0x0004, 5}, { 0x0077, 11}, { 0x076C, 15}, +{ 0x000E, 5}, { 0x000A, 12}, { 0x000C, 5}, { 0x0562, 11}, { 0x0004, 6}, { 0x031C, 12}, +{ 0x0006, 6}, { 0x00C8, 13}, { 0x000D, 6}, { 0x01DA, 13}, { 0x0007, 6}, { 0x00C9, 13}, +{ 0x0001, 7}, { 0x002E, 14}, { 0x0014, 7}, { 0x1596, 13}, { 0x000A, 7}, { 0x0AC2, 12}, +{ 0x0016, 7}, { 0x015B, 14}, { 0x0015, 7}, { 0x015A, 14}, { 0x000F, 8}, { 0x005E, 15}, +{ 0x007E, 8}, { 0x00AB, 8}, { 0x002D, 9}, { 0x00D8, 9}, { 0x000B, 9}, { 0x0014, 10}, +{ 0x02B3, 10}, { 0x01F3, 10}, { 0x003A, 10}, { 0x0000, 10}, { 0x0058, 10}, { 0x002E, 9}, +{ 0x005E, 10}, { 0x0563, 11}, { 0x00EC, 12}, { 0x0054, 12}, { 0x0AC1, 12}, { 0x1556, 13}, +{ 0x02FA, 13}, { 0x0181, 11}, { 0x1557, 13}, { 0x059D, 14}, { 0x2AA3, 14}, { 0x2B2A, 14}, +{ 0x01DE, 14}, { 0x063C, 13}, { 0x00CF, 13}, { 0x1594, 13}, { 0x000D, 9} +}, +{ +{ 0x0002, 2}, { 0x0006, 3}, { 0x000F, 4}, { 0x000D, 5}, { 0x000C, 5}, { 0x0015, 6}, +{ 0x0013, 6}, { 0x0012, 6}, { 0x0017, 7}, { 0x001F, 8}, { 0x001E, 8}, { 0x001D, 8}, +{ 0x0025, 9}, { 0x0024, 9}, { 0x0023, 9}, { 0x0021, 9}, { 0x0021, 10}, { 0x0020, 10}, +{ 0x000F, 10}, { 0x000E, 10}, { 0x0007, 11}, { 0x0006, 11}, { 0x0020, 11}, { 0x0021, 11}, +{ 0x0050, 12}, { 0x0051, 12}, { 0x0052, 12}, { 0x000E, 4}, { 0x0014, 6}, { 0x0016, 7}, +{ 0x001C, 8}, { 0x0020, 9}, { 0x001F, 9}, { 0x000D, 10}, { 0x0022, 11}, { 0x0053, 12}, +{ 0x0055, 12}, { 0x000B, 5}, { 0x0015, 7}, { 0x001E, 9}, { 0x000C, 10}, { 0x0056, 12}, +{ 0x0011, 6}, { 0x001B, 8}, { 0x001D, 9}, { 0x000B, 10}, { 0x0010, 6}, { 0x0022, 9}, +{ 0x000A, 10}, { 0x000D, 6}, { 0x001C, 9}, { 0x0008, 10}, { 0x0012, 7}, { 0x001B, 9}, +{ 0x0054, 12}, { 0x0014, 7}, { 0x001A, 9}, { 0x0057, 12}, { 0x0019, 8}, { 0x0009, 10}, +{ 0x0018, 8}, { 0x0023, 11}, { 0x0017, 8}, { 0x0019, 9}, { 0x0018, 9}, { 0x0007, 10}, +{ 0x0058, 12}, { 0x0007, 4}, { 0x000C, 6}, { 0x0016, 8}, { 0x0017, 9}, { 0x0006, 10}, +{ 0x0005, 11}, { 0x0004, 11}, { 0x0059, 12}, { 0x000F, 6}, { 0x0016, 9}, { 0x0005, 10}, +{ 0x000E, 6}, { 0x0004, 10}, { 0x0011, 7}, { 0x0024, 11}, { 0x0010, 7}, { 0x0025, 11}, +{ 0x0013, 7}, { 0x005A, 12}, { 0x0015, 8}, { 0x005B, 12}, { 0x0014, 8}, { 0x0013, 8}, +{ 0x001A, 8}, { 0x0015, 9}, { 0x0014, 9}, { 0x0013, 9}, { 0x0012, 9}, { 0x0011, 9}, +{ 0x0026, 11}, { 0x0027, 11}, { 0x005C, 12}, { 0x005D, 12}, { 0x005E, 12}, { 0x005F, 12}, +{ 0x0003, 7} +}, +{ +{ 0x0002, 2}, { 0x000F, 4}, { 0x0015, 6}, { 0x0017, 7}, { 0x001F, 8}, { 0x0025, 9}, +{ 0x0024, 9}, { 0x0021, 10}, { 0x0020, 10}, { 0x0007, 11}, { 0x0006, 11}, { 0x0020, 11}, +{ 0x0006, 3}, { 0x0014, 6}, { 0x001E, 8}, { 0x000F, 10}, { 0x0021, 11}, { 0x0050, 12}, +{ 0x000E, 4}, { 0x001D, 8}, { 0x000E, 10}, { 0x0051, 12}, { 0x000D, 5}, { 0x0023, 9}, +{ 0x000D, 10}, { 0x000C, 5}, { 0x0022, 9}, { 0x0052, 12}, { 0x000B, 5}, { 0x000C, 10}, +{ 0x0053, 12}, { 0x0013, 6}, { 0x000B, 10}, { 0x0054, 12}, { 0x0012, 6}, { 0x000A, 10}, +{ 0x0011, 6}, { 0x0009, 10}, { 0x0010, 6}, { 0x0008, 10}, { 0x0016, 7}, { 0x0055, 12}, +{ 0x0015, 7}, { 0x0014, 7}, { 0x001C, 8}, { 0x001B, 8}, { 0x0021, 9}, { 0x0020, 9}, +{ 0x001F, 9}, { 0x001E, 9}, { 0x001D, 9}, { 0x001C, 9}, { 0x001B, 9}, { 0x001A, 9}, +{ 0x0022, 11}, { 0x0023, 11}, { 0x0056, 12}, { 0x0057, 12}, { 0x0007, 4}, { 0x0019, 9}, +{ 0x0005, 11}, { 0x000F, 6}, { 0x0004, 11}, { 0x000E, 6}, { 0x000D, 6}, { 0x000C, 6}, +{ 0x0013, 7}, { 0x0012, 7}, { 0x0011, 7}, { 0x0010, 7}, { 0x001A, 8}, { 0x0019, 8}, +{ 0x0018, 8}, { 0x0017, 8}, { 0x0016, 8}, { 0x0015, 8}, { 0x0014, 8}, { 0x0013, 8}, +{ 0x0018, 9}, { 0x0017, 9}, { 0x0016, 9}, { 0x0015, 9}, { 0x0014, 9}, { 0x0013, 9}, +{ 0x0012, 9}, { 0x0011, 9}, { 0x0007, 10}, { 0x0006, 10}, { 0x0005, 10}, { 0x0004, 10}, +{ 0x0024, 11}, { 0x0025, 11}, { 0x0026, 11}, { 0x0027, 11}, { 0x0058, 12}, { 0x0059, 12}, +{ 0x005A, 12}, { 0x005B, 12}, { 0x005C, 12}, { 0x005D, 12}, { 0x005E, 12}, { 0x005F, 12}, +{ 0x0003, 7} +}, +{ +{ 0x0000, 2}, { 0x0003, 3}, { 0x000D, 4}, { 0x0005, 4}, { 0x001C, 5}, { 0x0016, 5}, +{ 0x003F, 6}, { 0x003A, 6}, { 0x002E, 6}, { 0x0022, 6}, { 0x007B, 7}, { 0x0067, 7}, +{ 0x005F, 7}, { 0x0047, 7}, { 0x0026, 7}, { 0x00EF, 8}, { 0x00CD, 8}, { 0x00C1, 8}, +{ 0x00A9, 8}, { 0x004F, 8}, { 0x01F2, 9}, { 0x01DD, 9}, { 0x0199, 9}, { 0x0185, 9}, +{ 0x015D, 9}, { 0x011B, 9}, { 0x03EF, 10}, { 0x03E1, 10}, { 0x03C8, 10}, { 0x0331, 10}, +{ 0x0303, 10}, { 0x02F1, 10}, { 0x02A0, 10}, { 0x0233, 10}, { 0x0126, 10}, { 0x07C0, 11}, +{ 0x076F, 11}, { 0x076C, 11}, { 0x0661, 11}, { 0x0604, 11}, { 0x0572, 11}, { 0x0551, 11}, +{ 0x046A, 11}, { 0x0274, 11}, { 0x0F27, 12}, { 0x0F24, 12}, { 0x0EDB, 12}, { 0x0C8E, 12}, +{ 0x0C0B, 12}, { 0x0C0A, 12}, { 0x0AE3, 12}, { 0x08D6, 12}, { 0x0490, 12}, { 0x0495, 12}, +{ 0x1F19, 13}, { 0x1DB5, 13}, { 0x0009, 4}, { 0x0010, 5}, { 0x0029, 6}, { 0x0062, 7}, +{ 0x00F3, 8}, { 0x00AD, 8}, { 0x01E5, 9}, { 0x0179, 9}, { 0x009C, 9}, { 0x03B1, 10}, +{ 0x02AE, 10}, { 0x0127, 10}, { 0x076E, 11}, { 0x0570, 11}, { 0x0275, 11}, { 0x0F25, 12}, +{ 0x0EC0, 12}, { 0x0AA0, 12}, { 0x08D7, 12}, { 0x1E4C, 13}, { 0x0008, 5}, { 0x0063, 7}, +{ 0x00AF, 8}, { 0x017B, 9}, { 0x03B3, 10}, { 0x07DD, 11}, { 0x0640, 11}, { 0x0F8D, 12}, +{ 0x0BC1, 12}, { 0x0491, 12}, { 0x0028, 6}, { 0x00C3, 8}, { 0x0151, 9}, { 0x02A1, 10}, +{ 0x0573, 11}, { 0x0EC3, 12}, { 0x1F35, 13}, { 0x0065, 7}, { 0x01DA, 9}, { 0x02AF, 10}, +{ 0x0277, 11}, { 0x08C9, 12}, { 0x1781, 13}, { 0x0025, 7}, { 0x0118, 9}, { 0x0646, 11}, +{ 0x0AA6, 12}, { 0x1780, 13}, { 0x00C9, 8}, { 0x0321, 10}, { 0x0F9B, 12}, { 0x191E, 13}, +{ 0x0048, 8}, { 0x07CC, 11}, { 0x0AA1, 12}, { 0x0180, 9}, { 0x0465, 11}, { 0x1905, 13}, +{ 0x03E2, 10}, { 0x0EC1, 12}, { 0x3C9B, 14}, { 0x02F4, 10}, { 0x08C8, 12}, { 0x07C1, 11}, +{ 0x0928, 13}, { 0x05E1, 11}, { 0x320D, 14}, { 0x0EC2, 12}, { 0x6418, 15}, { 0x1F34, 13}, +{ 0x0078, 7}, { 0x0155, 9}, { 0x0552, 11}, { 0x191F, 13}, { 0x00FA, 8}, { 0x07DC, 11}, +{ 0x1907, 13}, { 0x00AC, 8}, { 0x0249, 11}, { 0x13B1, 14}, { 0x01F6, 9}, { 0x0AE2, 12}, +{ 0x01DC, 9}, { 0x04ED, 12}, { 0x0184, 9}, { 0x1904, 13}, { 0x0156, 9}, { 0x09D9, 13}, +{ 0x03E7, 10}, { 0x0929, 13}, { 0x03B2, 10}, { 0x3B68, 14}, { 0x02F5, 10}, { 0x13B0, 14}, +{ 0x0322, 10}, { 0x3B69, 14}, { 0x0234, 10}, { 0x7935, 15}, { 0x07C7, 11}, { 0xC833, 16}, +{ 0x0660, 11}, { 0x7934, 15}, { 0x024B, 11}, { 0xC832, 16}, { 0x0AA7, 12}, { 0x1F18, 13}, +{ 0x007A, 7} +}, +{ +{ 0x0002, 2}, { 0x0000, 3}, { 0x001E, 5}, { 0x0004, 5}, { 0x0012, 6}, { 0x0070, 7}, +{ 0x001A, 7}, { 0x005F, 8}, { 0x0047, 8}, { 0x01D3, 9}, { 0x00B5, 9}, { 0x0057, 9}, +{ 0x03B5, 10}, { 0x016D, 10}, { 0x0162, 10}, { 0x07CE, 11}, { 0x0719, 11}, { 0x0691, 11}, +{ 0x02C6, 11}, { 0x0156, 11}, { 0x0F92, 12}, { 0x0D2E, 12}, { 0x0D20, 12}, { 0x059E, 12}, +{ 0x0468, 12}, { 0x02A6, 12}, { 0x1DA2, 13}, { 0x1C60, 13}, { 0x1A43, 13}, { 0x0B1D, 13}, +{ 0x08C0, 13}, { 0x055D, 13}, { 0x0003, 3}, { 0x000A, 5}, { 0x0077, 7}, { 0x00E5, 8}, +{ 0x01D9, 9}, { 0x03E5, 10}, { 0x0166, 10}, { 0x0694, 11}, { 0x0152, 11}, { 0x059F, 12}, +{ 0x1F3C, 13}, { 0x1A4B, 13}, { 0x055E, 13}, { 0x000C, 4}, { 0x007D, 7}, { 0x0044, 8}, +{ 0x03E0, 10}, { 0x0769, 11}, { 0x0E31, 12}, { 0x1F26, 13}, { 0x055C, 13}, { 0x001B, 5}, +{ 0x00E2, 8}, { 0x03A5, 10}, { 0x02C9, 11}, { 0x1F23, 13}, { 0x3B47, 14}, { 0x0007, 5}, +{ 0x01D8, 9}, { 0x02D8, 11}, { 0x1F27, 13}, { 0x3494, 14}, { 0x0035, 6}, { 0x03E1, 10}, +{ 0x059C, 12}, { 0x38C3, 14}, { 0x000C, 6}, { 0x0165, 10}, { 0x1D23, 13}, { 0x1638, 14}, +{ 0x0068, 7}, { 0x0693, 11}, { 0x3A45, 14}, { 0x0020, 7}, { 0x0F90, 12}, { 0x7CF6, 15}, +{ 0x00E8, 8}, { 0x058F, 12}, { 0x2CEF, 15}, { 0x0045, 8}, { 0x0B3A, 13}, { 0x01F1, 9}, +{ 0x3B46, 14}, { 0x01A7, 9}, { 0x1676, 14}, { 0x0056, 9}, { 0x692A, 15}, { 0x038D, 10}, +{ 0xE309, 16}, { 0x00AA, 10}, { 0x1C611, 17}, { 0x02DF, 11}, { 0xB3B9, 17}, { 0x02C8, 11}, +{ 0x38C20, 18}, { 0x01B0, 11}, { 0x16390, 18}, { 0x0F9F, 12}, { 0x16771, 18}, { 0x0ED0, 12}, +{ 0x71843, 19}, { 0x0D2A, 12}, { 0xF9E8C, 20}, { 0x0461, 12}, { 0xF9E8E, 20}, { 0x0B67, 13}, +{ 0x055F, 13}, { 0x003F, 6}, { 0x006D, 9}, { 0x0E90, 12}, { 0x054E, 13}, { 0x0013, 6}, +{ 0x0119, 10}, { 0x0B66, 13}, { 0x000B, 6}, { 0x0235, 11}, { 0x7CF5, 15}, { 0x0075, 7}, +{ 0x0D24, 12}, { 0xF9E9, 16}, { 0x002E, 7}, { 0x1F22, 13}, { 0x0021, 7}, { 0x054F, 13}, +{ 0x0014, 7}, { 0x3A44, 14}, { 0x00E4, 8}, { 0x7CF7, 15}, { 0x005E, 8}, { 0x7185, 15}, +{ 0x0037, 8}, { 0x2C73, 15}, { 0x01DB, 9}, { 0x59DD, 16}, { 0x01C7, 9}, { 0x692B, 15}, +{ 0x01A6, 9}, { 0x58E5, 16}, { 0x00B4, 9}, { 0x1F3D0, 17}, { 0x00B0, 9}, { 0xB1C9, 17}, +{ 0x03E6, 10}, { 0x16770, 18}, { 0x016E, 10}, { 0x3E7A2, 18}, { 0x011B, 10}, { 0xF9E8D, 20}, +{ 0x00D9, 10}, { 0xF9E8F, 20}, { 0x00A8, 10}, { 0x2C723, 19}, { 0x0749, 11}, { 0xE3084, 20}, +{ 0x0696, 11}, { 0x58E45, 20}, { 0x02DE, 11}, { 0xB1C88, 21}, { 0x0231, 11}, { 0x1C610A, 21}, +{ 0x01B1, 11}, { 0x71842D, 23}, { 0x0D2B, 12}, { 0x38C217, 22}, { 0x0D2F, 12}, { 0x163913, 22}, +{ 0x05B2, 12}, { 0x163912, 22}, { 0x0469, 12}, { 0x71842C, 23}, { 0x1A42, 13}, { 0x08C1, 13}, +{ 0x0073, 7} +} +}; + +static const uint16_t vlc_offs[] = { + 0, 520, 552, 616, 1128, 1160, 1224, 1740, 1772, 1836, 1900, 2436, + 2986, 3050, 3610, 4154, 4218, 4746, 5326, 5390, 5902, 6554, 7658, 8342, + 9304, 9988, 10630, 11234, 12174, 13006, 13560, 14232, 14786, 15432, 16350, 17522, + 20372, 21818, 22330, 22394, 23166, 23678, 23742, 24820, 25332, 25396, 26460, 26980, + 27048, 27592, 27600, 27608, 27616, 27624, 28224, 28258, 28290, 28802, 28834, 28866, + 29378, 29412, 29444, 29960, 29994, 30026, 30538, 30572, 30604, 31120, 31154, 31186, + 31714, 31746, 31778, 32306, 32340, 32372 +}; + +/** + * Init VC-1 specific tables and VC1Context members + * @param v The VC1Context to initialize + * @return Status + */ +int ff_vc1_init_common(VC1Context *v) +{ + static int done = 0; + int i = 0; + static VLC_TYPE vlc_table[32372][2]; + + v->hrd_rate = v->hrd_buffer = NULL; + + /* VLC tables */ + if (!done) { + INIT_VLC_STATIC(&ff_vc1_bfraction_vlc, VC1_BFRACTION_VLC_BITS, 23, + ff_vc1_bfraction_bits, 1, 1, + ff_vc1_bfraction_codes, 1, 1, 1 << VC1_BFRACTION_VLC_BITS); + INIT_VLC_STATIC(&ff_vc1_norm2_vlc, VC1_NORM2_VLC_BITS, 4, + ff_vc1_norm2_bits, 1, 1, + ff_vc1_norm2_codes, 1, 1, 1 << VC1_NORM2_VLC_BITS); + INIT_VLC_STATIC(&ff_vc1_norm6_vlc, VC1_NORM6_VLC_BITS, 64, + ff_vc1_norm6_bits, 1, 1, + ff_vc1_norm6_codes, 2, 2, 556); + INIT_VLC_STATIC(&ff_vc1_imode_vlc, VC1_IMODE_VLC_BITS, 7, + ff_vc1_imode_bits, 1, 1, + ff_vc1_imode_codes, 1, 1, 1 << VC1_IMODE_VLC_BITS); + for (i = 0; i < 3; i++) { + ff_vc1_ttmb_vlc[i].table = &vlc_table[vlc_offs[i * 3 + 0]]; + ff_vc1_ttmb_vlc[i].table_allocated = vlc_offs[i * 3 + 1] - vlc_offs[i * 3 + 0]; + init_vlc(&ff_vc1_ttmb_vlc[i], VC1_TTMB_VLC_BITS, 16, + ff_vc1_ttmb_bits[i], 1, 1, + ff_vc1_ttmb_codes[i], 2, 2, INIT_VLC_USE_NEW_STATIC); + ff_vc1_ttblk_vlc[i].table = &vlc_table[vlc_offs[i * 3 + 1]]; + ff_vc1_ttblk_vlc[i].table_allocated = vlc_offs[i * 3 + 2] - vlc_offs[i * 3 + 1]; + init_vlc(&ff_vc1_ttblk_vlc[i], VC1_TTBLK_VLC_BITS, 8, + ff_vc1_ttblk_bits[i], 1, 1, + ff_vc1_ttblk_codes[i], 1, 1, INIT_VLC_USE_NEW_STATIC); + ff_vc1_subblkpat_vlc[i].table = &vlc_table[vlc_offs[i * 3 + 2]]; + ff_vc1_subblkpat_vlc[i].table_allocated = vlc_offs[i * 3 + 3] - vlc_offs[i * 3 + 2]; + init_vlc(&ff_vc1_subblkpat_vlc[i], VC1_SUBBLKPAT_VLC_BITS, 15, + ff_vc1_subblkpat_bits[i], 1, 1, + ff_vc1_subblkpat_codes[i], 1, 1, INIT_VLC_USE_NEW_STATIC); + } + for (i = 0; i < 4; i++) { + ff_vc1_4mv_block_pattern_vlc[i].table = &vlc_table[vlc_offs[i * 3 + 9]]; + ff_vc1_4mv_block_pattern_vlc[i].table_allocated = vlc_offs[i * 3 + 10] - vlc_offs[i * 3 + 9]; + init_vlc(&ff_vc1_4mv_block_pattern_vlc[i], VC1_4MV_BLOCK_PATTERN_VLC_BITS, 16, + ff_vc1_4mv_block_pattern_bits[i], 1, 1, + ff_vc1_4mv_block_pattern_codes[i], 1, 1, INIT_VLC_USE_NEW_STATIC); + ff_vc1_cbpcy_p_vlc[i].table = &vlc_table[vlc_offs[i * 3 + 10]]; + ff_vc1_cbpcy_p_vlc[i].table_allocated = vlc_offs[i * 3 + 11] - vlc_offs[i * 3 + 10]; + init_vlc(&ff_vc1_cbpcy_p_vlc[i], VC1_CBPCY_P_VLC_BITS, 64, + ff_vc1_cbpcy_p_bits[i], 1, 1, + ff_vc1_cbpcy_p_codes[i], 2, 2, INIT_VLC_USE_NEW_STATIC); + ff_vc1_mv_diff_vlc[i].table = &vlc_table[vlc_offs[i * 3 + 11]]; + ff_vc1_mv_diff_vlc[i].table_allocated = vlc_offs[i * 3 + 12] - vlc_offs[i * 3 + 11]; + init_vlc(&ff_vc1_mv_diff_vlc[i], VC1_MV_DIFF_VLC_BITS, 73, + ff_vc1_mv_diff_bits[i], 1, 1, + ff_vc1_mv_diff_codes[i], 2, 2, INIT_VLC_USE_NEW_STATIC); + } + for (i = 0; i < 8; i++) { + ff_vc1_ac_coeff_table[i].table = &vlc_table[vlc_offs[i * 2 + 21]]; + ff_vc1_ac_coeff_table[i].table_allocated = vlc_offs[i * 2 + 22] - vlc_offs[i * 2 + 21]; + init_vlc(&ff_vc1_ac_coeff_table[i], AC_VLC_BITS, ff_vc1_ac_sizes[i], + &vc1_ac_tables[i][0][1], 8, 4, + &vc1_ac_tables[i][0][0], 8, 4, INIT_VLC_USE_NEW_STATIC); + /* initialize interlaced MVDATA tables (2-Ref) */ + ff_vc1_2ref_mvdata_vlc[i].table = &vlc_table[vlc_offs[i * 2 + 22]]; + ff_vc1_2ref_mvdata_vlc[i].table_allocated = vlc_offs[i * 2 + 23] - vlc_offs[i * 2 + 22]; + init_vlc(&ff_vc1_2ref_mvdata_vlc[i], VC1_2REF_MVDATA_VLC_BITS, 126, + ff_vc1_2ref_mvdata_bits[i], 1, 1, + ff_vc1_2ref_mvdata_codes[i], 4, 4, INIT_VLC_USE_NEW_STATIC); + } + for (i = 0; i < 4; i++) { + /* initialize 4MV MBMODE VLC tables for interlaced frame P picture */ + ff_vc1_intfr_4mv_mbmode_vlc[i].table = &vlc_table[vlc_offs[i * 3 + 37]]; + ff_vc1_intfr_4mv_mbmode_vlc[i].table_allocated = vlc_offs[i * 3 + 38] - vlc_offs[i * 3 + 37]; + init_vlc(&ff_vc1_intfr_4mv_mbmode_vlc[i], VC1_INTFR_4MV_MBMODE_VLC_BITS, 15, + ff_vc1_intfr_4mv_mbmode_bits[i], 1, 1, + ff_vc1_intfr_4mv_mbmode_codes[i], 2, 2, INIT_VLC_USE_NEW_STATIC); + /* initialize NON-4MV MBMODE VLC tables for the same */ + ff_vc1_intfr_non4mv_mbmode_vlc[i].table = &vlc_table[vlc_offs[i * 3 + 38]]; + ff_vc1_intfr_non4mv_mbmode_vlc[i].table_allocated = vlc_offs[i * 3 + 39] - vlc_offs[i * 3 + 38]; + init_vlc(&ff_vc1_intfr_non4mv_mbmode_vlc[i], VC1_INTFR_NON4MV_MBMODE_VLC_BITS, 9, + ff_vc1_intfr_non4mv_mbmode_bits[i], 1, 1, + ff_vc1_intfr_non4mv_mbmode_codes[i], 1, 1, INIT_VLC_USE_NEW_STATIC); + /* initialize interlaced MVDATA tables (1-Ref) */ + ff_vc1_1ref_mvdata_vlc[i].table = &vlc_table[vlc_offs[i * 3 + 39]]; + ff_vc1_1ref_mvdata_vlc[i].table_allocated = vlc_offs[i * 3 + 40] - vlc_offs[i * 3 + 39]; + init_vlc(&ff_vc1_1ref_mvdata_vlc[i], VC1_1REF_MVDATA_VLC_BITS, 72, + ff_vc1_1ref_mvdata_bits[i], 1, 1, + ff_vc1_1ref_mvdata_codes[i], 4, 4, INIT_VLC_USE_NEW_STATIC); + } + for (i = 0; i < 4; i++) { + /* Initialize 2MV Block pattern VLC tables */ + ff_vc1_2mv_block_pattern_vlc[i].table = &vlc_table[vlc_offs[i + 49]]; + ff_vc1_2mv_block_pattern_vlc[i].table_allocated = vlc_offs[i + 50] - vlc_offs[i + 49]; + init_vlc(&ff_vc1_2mv_block_pattern_vlc[i], VC1_2MV_BLOCK_PATTERN_VLC_BITS, 4, + ff_vc1_2mv_block_pattern_bits[i], 1, 1, + ff_vc1_2mv_block_pattern_codes[i], 1, 1, INIT_VLC_USE_NEW_STATIC); + } + for (i = 0; i < 8; i++) { + /* Initialize interlaced CBPCY VLC tables (Table 124 - Table 131) */ + ff_vc1_icbpcy_vlc[i].table = &vlc_table[vlc_offs[i * 3 + 53]]; + ff_vc1_icbpcy_vlc[i].table_allocated = vlc_offs[i * 3 + 54] - vlc_offs[i * 3 + 53]; + init_vlc(&ff_vc1_icbpcy_vlc[i], VC1_ICBPCY_VLC_BITS, 63, + ff_vc1_icbpcy_p_bits[i], 1, 1, + ff_vc1_icbpcy_p_codes[i], 2, 2, INIT_VLC_USE_NEW_STATIC); + /* Initialize interlaced field picture MBMODE VLC tables */ + ff_vc1_if_mmv_mbmode_vlc[i].table = &vlc_table[vlc_offs[i * 3 + 54]]; + ff_vc1_if_mmv_mbmode_vlc[i].table_allocated = vlc_offs[i * 3 + 55] - vlc_offs[i * 3 + 54]; + init_vlc(&ff_vc1_if_mmv_mbmode_vlc[i], VC1_IF_MMV_MBMODE_VLC_BITS, 8, + ff_vc1_if_mmv_mbmode_bits[i], 1, 1, + ff_vc1_if_mmv_mbmode_codes[i], 1, 1, INIT_VLC_USE_NEW_STATIC); + ff_vc1_if_1mv_mbmode_vlc[i].table = &vlc_table[vlc_offs[i * 3 + 55]]; + ff_vc1_if_1mv_mbmode_vlc[i].table_allocated = vlc_offs[i * 3 + 56] - vlc_offs[i * 3 + 55]; + init_vlc(&ff_vc1_if_1mv_mbmode_vlc[i], VC1_IF_1MV_MBMODE_VLC_BITS, 6, + ff_vc1_if_1mv_mbmode_bits[i], 1, 1, + ff_vc1_if_1mv_mbmode_codes[i], 1, 1, INIT_VLC_USE_NEW_STATIC); + } + done = 1; + } + + /* Other defaults */ + v->pq = -1; + v->mvrange = 0; /* 7.1.1.18, p80 */ + + return 0; +} diff --git a/libavcodec/vc1.h b/libavcodec/vc1.h index 1b39040bef..15434dadc1 100644 --- a/libavcodec/vc1.h +++ b/libavcodec/vc1.h @@ -28,6 +28,8 @@ #include "intrax8.h" #include "vc1dsp.h" +#define AC_VLC_BITS 9 + /** Markers used in VC-1 AP frame data */ //@{ enum VC1Code { @@ -447,5 +449,6 @@ int vc1_decode_entry_point(AVCodecContext *avctx, VC1Context *v, GetBitContext * int vc1_parse_frame_header (VC1Context *v, GetBitContext *gb); int vc1_parse_frame_header_adv(VC1Context *v, GetBitContext *gb); +int ff_vc1_init_common(VC1Context *v); #endif /* AVCODEC_VC1_H */ diff --git a/libavcodec/vc1_parser.c b/libavcodec/vc1_parser.c index a4130d9885..28f29a9708 100644 --- a/libavcodec/vc1_parser.c +++ b/libavcodec/vc1_parser.c @@ -188,7 +188,7 @@ static int vc1_parse_init(AVCodecParserContext *s) { VC1ParseContext *vpc = s->priv_data; vpc->v.s.slice_context_count = 1; - return 0; + return ff_vc1_init_common(&vpc->v); } AVCodecParser ff_vc1_parser = { diff --git a/libavcodec/vc1acdata.h b/libavcodec/vc1acdata.h index 78de0f9a24..a70b44ae05 100644 --- a/libavcodec/vc1acdata.h +++ b/libavcodec/vc1acdata.h @@ -24,232 +24,7 @@ #include -#define AC_MODES 8 - -static const int vc1_ac_sizes[AC_MODES] = { - 186, 169, 133, 149, 103, 103, 163, 175 -}; - -static const uint32_t vc1_ac_tables[AC_MODES][186][2] = { -{ -{ 0x0001, 2}, { 0x0005, 3}, { 0x000D, 4}, { 0x0012, 5}, { 0x000E, 6}, { 0x0015, 7}, -{ 0x0013, 8}, { 0x003F, 8}, { 0x004B, 9}, { 0x011F, 9}, { 0x00B8, 10}, { 0x03E3, 10}, -{ 0x0172, 11}, { 0x024D, 12}, { 0x03DA, 12}, { 0x02DD, 13}, { 0x1F55, 13}, { 0x05B9, 14}, -{ 0x3EAE, 14}, { 0x0000, 4}, { 0x0010, 5}, { 0x0008, 7}, { 0x0020, 8}, { 0x0029, 9}, -{ 0x01F4, 9}, { 0x0233, 10}, { 0x01E0, 11}, { 0x012A, 12}, { 0x03DD, 12}, { 0x050A, 13}, -{ 0x1F29, 13}, { 0x0A42, 14}, { 0x1272, 15}, { 0x1737, 15}, { 0x0003, 5}, { 0x0011, 7}, -{ 0x00C4, 8}, { 0x004B, 10}, { 0x00B4, 11}, { 0x07D4, 11}, { 0x0345, 12}, { 0x02D7, 13}, -{ 0x07BF, 13}, { 0x0938, 14}, { 0x0BBB, 14}, { 0x095E, 15}, { 0x0013, 5}, { 0x0078, 7}, -{ 0x0069, 9}, { 0x0232, 10}, { 0x0461, 11}, { 0x03EC, 12}, { 0x0520, 13}, { 0x1F2A, 13}, -{ 0x3E50, 14}, { 0x3E51, 14}, { 0x1486, 15}, { 0x000C, 6}, { 0x0024, 9}, { 0x0094, 11}, -{ 0x08C0, 12}, { 0x0F09, 14}, { 0x1EF0, 15}, { 0x003D, 6}, { 0x0053, 9}, { 0x01A0, 11}, -{ 0x02D6, 13}, { 0x0F08, 14}, { 0x0013, 7}, { 0x007C, 9}, { 0x07C1, 11}, { 0x04AC, 14}, -{ 0x001B, 7}, { 0x00A0, 10}, { 0x0344, 12}, { 0x0F79, 14}, { 0x0079, 7}, { 0x03E1, 10}, -{ 0x02D4, 13}, { 0x2306, 14}, { 0x0021, 8}, { 0x023C, 10}, { 0x0FAE, 12}, { 0x23DE, 14}, -{ 0x0035, 8}, { 0x0175, 11}, { 0x07B3, 13}, { 0x00C5, 8}, { 0x0174, 11}, { 0x0785, 13}, -{ 0x0048, 9}, { 0x01A3, 11}, { 0x049E, 13}, { 0x002C, 9}, { 0x00FA, 10}, { 0x07D6, 11}, -{ 0x0092, 10}, { 0x05CC, 13}, { 0x1EF1, 15}, { 0x00A3, 10}, { 0x03ED, 12}, { 0x093E, 14}, -{ 0x01E2, 11}, { 0x1273, 15}, { 0x07C4, 11}, { 0x1487, 15}, { 0x0291, 12}, { 0x0293, 12}, -{ 0x0F8A, 12}, { 0x0509, 13}, { 0x0508, 13}, { 0x078D, 13}, { 0x07BE, 13}, { 0x078C, 13}, -{ 0x04AE, 14}, { 0x0BBA, 14}, { 0x2307, 14}, { 0x0B9A, 14}, { 0x1736, 15}, { 0x000E, 4}, -{ 0x0045, 7}, { 0x01F3, 9}, { 0x047A, 11}, { 0x05DC, 13}, { 0x23DF, 14}, { 0x0019, 5}, -{ 0x0028, 9}, { 0x0176, 11}, { 0x049D, 13}, { 0x23DD, 14}, { 0x0030, 6}, { 0x00A2, 10}, -{ 0x02EF, 12}, { 0x05B8, 14}, { 0x003F, 6}, { 0x00A5, 10}, { 0x03DB, 12}, { 0x093F, 14}, -{ 0x0044, 7}, { 0x07CB, 11}, { 0x095F, 15}, { 0x0063, 7}, { 0x03C3, 12}, { 0x0015, 8}, -{ 0x08F6, 12}, { 0x0017, 8}, { 0x0498, 13}, { 0x002C, 8}, { 0x07B2, 13}, { 0x002F, 8}, -{ 0x1F54, 13}, { 0x008D, 8}, { 0x07BD, 13}, { 0x008E, 8}, { 0x1182, 13}, { 0x00FB, 8}, -{ 0x050B, 13}, { 0x002D, 8}, { 0x07C0, 11}, { 0x0079, 9}, { 0x1F5F, 13}, { 0x007A, 9}, -{ 0x1F56, 13}, { 0x0231, 10}, { 0x03E4, 10}, { 0x01A1, 11}, { 0x0143, 11}, { 0x01F7, 11}, -{ 0x016F, 12}, { 0x0292, 12}, { 0x02E7, 12}, { 0x016C, 12}, { 0x016D, 12}, { 0x03DC, 12}, -{ 0x0F8B, 12}, { 0x0499, 13}, { 0x03D8, 12}, { 0x078E, 13}, { 0x02D5, 13}, { 0x1F5E, 13}, -{ 0x1F2B, 13}, { 0x078F, 13}, { 0x04AD, 14}, { 0x3EAF, 14}, { 0x23DC, 14}, { 0x004A, 9} -}, -{ -{ 0x0000, 3}, { 0x0003, 4}, { 0x000B, 5}, { 0x0014, 6}, { 0x003F, 6}, { 0x005D, 7}, -{ 0x00A2, 8}, { 0x00AC, 9}, { 0x016E, 9}, { 0x020A, 10}, { 0x02E2, 10}, { 0x0432, 11}, -{ 0x05C9, 11}, { 0x0827, 12}, { 0x0B54, 12}, { 0x04E6, 13}, { 0x105F, 13}, { 0x172A, 13}, -{ 0x20B2, 14}, { 0x2D4E, 14}, { 0x39F0, 14}, { 0x4175, 15}, { 0x5A9E, 15}, { 0x0004, 4}, -{ 0x001E, 5}, { 0x0042, 7}, { 0x00B6, 8}, { 0x0173, 9}, { 0x0395, 10}, { 0x072E, 11}, -{ 0x0B94, 12}, { 0x16A4, 13}, { 0x20B3, 14}, { 0x2E45, 14}, { 0x0005, 5}, { 0x0040, 7}, -{ 0x0049, 9}, { 0x028F, 10}, { 0x05CB, 11}, { 0x048A, 13}, { 0x09DD, 14}, { 0x73E2, 15}, -{ 0x0018, 5}, { 0x0025, 8}, { 0x008A, 10}, { 0x051B, 11}, { 0x0E5F, 12}, { 0x09C9, 14}, -{ 0x139C, 15}, { 0x0029, 6}, { 0x004F, 9}, { 0x0412, 11}, { 0x048D, 13}, { 0x2E41, 14}, -{ 0x0038, 6}, { 0x010E, 9}, { 0x05A8, 11}, { 0x105C, 13}, { 0x39F2, 14}, { 0x0058, 7}, -{ 0x021F, 10}, { 0x0E7E, 12}, { 0x39FF, 14}, { 0x0023, 8}, { 0x02E3, 10}, { 0x04E5, 13}, -{ 0x2E40, 14}, { 0x00A1, 8}, { 0x05BE, 11}, { 0x09C8, 14}, { 0x0083, 8}, { 0x013A, 11}, -{ 0x1721, 13}, { 0x0044, 9}, { 0x0276, 12}, { 0x39F6, 14}, { 0x008B, 10}, { 0x04EF, 13}, -{ 0x5A9B, 15}, { 0x0208, 10}, { 0x1CFE, 13}, { 0x0399, 10}, { 0x1CB4, 13}, { 0x039E, 10}, -{ 0x39F3, 14}, { 0x05AB, 11}, { 0x73E3, 15}, { 0x0737, 11}, { 0x5A9F, 15}, { 0x082D, 12}, -{ 0x0E69, 12}, { 0x0E68, 12}, { 0x0433, 11}, { 0x0B7B, 12}, { 0x2DF8, 14}, { 0x2E56, 14}, -{ 0x2E57, 14}, { 0x39F7, 14}, { 0x51A5, 15}, { 0x0003, 3}, { 0x002A, 6}, { 0x00E4, 8}, -{ 0x028E, 10}, { 0x0735, 11}, { 0x1058, 13}, { 0x1CFA, 13}, { 0x2DF9, 14}, { 0x4174, 15}, -{ 0x0009, 4}, { 0x0054, 8}, { 0x0398, 10}, { 0x048B, 13}, { 0x139D, 15}, { 0x000D, 4}, -{ 0x00AD, 9}, { 0x0826, 12}, { 0x2D4C, 14}, { 0x0011, 5}, { 0x016B, 9}, { 0x0B7F, 12}, -{ 0x51A4, 15}, { 0x0019, 5}, { 0x021B, 10}, { 0x16FD, 13}, { 0x001D, 5}, { 0x0394, 10}, -{ 0x28D3, 14}, { 0x002B, 6}, { 0x05BC, 11}, { 0x5A9A, 15}, { 0x002F, 6}, { 0x0247, 12}, -{ 0x0010, 7}, { 0x0A35, 12}, { 0x003E, 6}, { 0x0B7A, 12}, { 0x0059, 7}, { 0x105E, 13}, -{ 0x0026, 8}, { 0x09CF, 14}, { 0x0055, 8}, { 0x1CB5, 13}, { 0x0057, 8}, { 0x0E5B, 12}, -{ 0x00A0, 8}, { 0x1468, 13}, { 0x0170, 9}, { 0x0090, 10}, { 0x01CE, 9}, { 0x021A, 10}, -{ 0x0218, 10}, { 0x0168, 9}, { 0x021E, 10}, { 0x0244, 12}, { 0x0736, 11}, { 0x0138, 11}, -{ 0x0519, 11}, { 0x0E5E, 12}, { 0x072C, 11}, { 0x0B55, 12}, { 0x09DC, 14}, { 0x20BB, 14}, -{ 0x048C, 13}, { 0x1723, 13}, { 0x2E44, 14}, { 0x16A5, 13}, { 0x0518, 11}, { 0x39FE, 14}, -{ 0x0169, 9} -}, -{ -{ 0x0001, 2}, { 0x0006, 3}, { 0x000F, 4}, { 0x0016, 5}, { 0x0020, 6}, { 0x0018, 7}, -{ 0x0008, 8}, { 0x009A, 8}, { 0x0056, 9}, { 0x013E, 9}, { 0x00F0, 10}, { 0x03A5, 10}, -{ 0x0077, 11}, { 0x01EF, 11}, { 0x009A, 12}, { 0x005D, 13}, { 0x0001, 4}, { 0x0011, 5}, -{ 0x0002, 7}, { 0x000B, 8}, { 0x0012, 9}, { 0x01D6, 9}, { 0x027E, 10}, { 0x0191, 11}, -{ 0x00EA, 12}, { 0x03DC, 12}, { 0x013B, 13}, { 0x0004, 5}, { 0x0014, 7}, { 0x009E, 8}, -{ 0x0009, 10}, { 0x01AC, 11}, { 0x01E2, 11}, { 0x03CA, 12}, { 0x005F, 13}, { 0x0017, 5}, -{ 0x004E, 7}, { 0x005E, 9}, { 0x00F3, 10}, { 0x01AD, 11}, { 0x00EC, 12}, { 0x05F0, 13}, -{ 0x000E, 6}, { 0x00E1, 8}, { 0x03A4, 10}, { 0x009C, 12}, { 0x013D, 13}, { 0x003B, 6}, -{ 0x001C, 9}, { 0x0014, 11}, { 0x09BE, 12}, { 0x0006, 7}, { 0x007A, 9}, { 0x0190, 11}, -{ 0x0137, 13}, { 0x001B, 7}, { 0x0008, 10}, { 0x075C, 11}, { 0x0071, 7}, { 0x00D7, 10}, -{ 0x09BF, 12}, { 0x0007, 8}, { 0x00AF, 10}, { 0x04CC, 11}, { 0x0034, 8}, { 0x0265, 10}, -{ 0x009F, 12}, { 0x00E0, 8}, { 0x0016, 11}, { 0x0327, 12}, { 0x0015, 9}, { 0x017D, 11}, -{ 0x0EBB, 12}, { 0x0014, 9}, { 0x00F6, 10}, { 0x01E4, 11}, { 0x00CB, 10}, { 0x099D, 12}, -{ 0x00CA, 10}, { 0x02FC, 12}, { 0x017F, 11}, { 0x04CD, 11}, { 0x02FD, 12}, { 0x04FE, 11}, -{ 0x013A, 13}, { 0x000A, 4}, { 0x0042, 7}, { 0x01D3, 9}, { 0x04DD, 11}, { 0x0012, 5}, -{ 0x00E8, 8}, { 0x004C, 11}, { 0x0136, 13}, { 0x0039, 6}, { 0x0264, 10}, { 0x0EBA, 12}, -{ 0x0000, 7}, { 0x00AE, 10}, { 0x099C, 12}, { 0x001F, 7}, { 0x04DE, 11}, { 0x0043, 7}, -{ 0x04DC, 11}, { 0x0003, 8}, { 0x03CB, 12}, { 0x0006, 8}, { 0x099E, 12}, { 0x002A, 8}, -{ 0x05F1, 13}, { 0x000F, 8}, { 0x09FE, 12}, { 0x0033, 8}, { 0x09FF, 12}, { 0x0098, 8}, -{ 0x099F, 12}, { 0x00EA, 8}, { 0x013C, 13}, { 0x002E, 8}, { 0x0192, 11}, { 0x0136, 9}, -{ 0x006A, 9}, { 0x0015, 11}, { 0x03AF, 10}, { 0x01E3, 11}, { 0x0074, 11}, { 0x00EB, 12}, -{ 0x02F9, 12}, { 0x005C, 13}, { 0x00ED, 12}, { 0x03DD, 12}, { 0x0326, 12}, { 0x005E, 13}, -{ 0x0016, 7} -}, -{ -{ 0x0004, 3}, { 0x0014, 5}, { 0x0017, 7}, { 0x007F, 8}, { 0x0154, 9}, { 0x01F2, 10}, -{ 0x00BF, 11}, { 0x0065, 12}, { 0x0AAA, 12}, { 0x0630, 13}, { 0x1597, 13}, { 0x03B7, 14}, -{ 0x2B22, 14}, { 0x0BE6, 15}, { 0x000B, 4}, { 0x0037, 7}, { 0x0062, 9}, { 0x0007, 11}, -{ 0x0166, 12}, { 0x00CE, 13}, { 0x1590, 13}, { 0x05F6, 14}, { 0x0BE7, 15}, { 0x0007, 5}, -{ 0x006D, 8}, { 0x0003, 11}, { 0x031F, 12}, { 0x05F2, 14}, { 0x0002, 6}, { 0x0061, 9}, -{ 0x0055, 12}, { 0x01DF, 14}, { 0x001A, 6}, { 0x001E, 10}, { 0x0AC9, 12}, { 0x2B23, 14}, -{ 0x001E, 6}, { 0x001F, 10}, { 0x0AC3, 12}, { 0x2B2B, 14}, { 0x0006, 7}, { 0x0004, 11}, -{ 0x02F8, 13}, { 0x0019, 7}, { 0x0006, 11}, { 0x063D, 13}, { 0x0057, 7}, { 0x0182, 11}, -{ 0x2AA2, 14}, { 0x0004, 8}, { 0x0180, 11}, { 0x059C, 14}, { 0x007D, 8}, { 0x0164, 12}, -{ 0x076D, 15}, { 0x0002, 9}, { 0x018D, 11}, { 0x1581, 13}, { 0x00AD, 8}, { 0x0060, 12}, -{ 0x0C67, 14}, { 0x001C, 9}, { 0x00EE, 13}, { 0x0003, 9}, { 0x02CF, 13}, { 0x00D9, 9}, -{ 0x1580, 13}, { 0x0002, 11}, { 0x0183, 11}, { 0x0057, 12}, { 0x0061, 12}, { 0x0031, 11}, -{ 0x0066, 12}, { 0x0631, 13}, { 0x0632, 13}, { 0x00AC, 13}, { 0x031D, 12}, { 0x0076, 12}, -{ 0x003A, 11}, { 0x0165, 12}, { 0x0C66, 14}, { 0x0003, 2}, { 0x0054, 7}, { 0x02AB, 10}, -{ 0x0016, 13}, { 0x05F7, 14}, { 0x0005, 4}, { 0x00F8, 9}, { 0x0AA9, 12}, { 0x005F, 15}, -{ 0x0004, 4}, { 0x001C, 10}, { 0x1550, 13}, { 0x0004, 5}, { 0x0077, 11}, { 0x076C, 15}, -{ 0x000E, 5}, { 0x000A, 12}, { 0x000C, 5}, { 0x0562, 11}, { 0x0004, 6}, { 0x031C, 12}, -{ 0x0006, 6}, { 0x00C8, 13}, { 0x000D, 6}, { 0x01DA, 13}, { 0x0007, 6}, { 0x00C9, 13}, -{ 0x0001, 7}, { 0x002E, 14}, { 0x0014, 7}, { 0x1596, 13}, { 0x000A, 7}, { 0x0AC2, 12}, -{ 0x0016, 7}, { 0x015B, 14}, { 0x0015, 7}, { 0x015A, 14}, { 0x000F, 8}, { 0x005E, 15}, -{ 0x007E, 8}, { 0x00AB, 8}, { 0x002D, 9}, { 0x00D8, 9}, { 0x000B, 9}, { 0x0014, 10}, -{ 0x02B3, 10}, { 0x01F3, 10}, { 0x003A, 10}, { 0x0000, 10}, { 0x0058, 10}, { 0x002E, 9}, -{ 0x005E, 10}, { 0x0563, 11}, { 0x00EC, 12}, { 0x0054, 12}, { 0x0AC1, 12}, { 0x1556, 13}, -{ 0x02FA, 13}, { 0x0181, 11}, { 0x1557, 13}, { 0x059D, 14}, { 0x2AA3, 14}, { 0x2B2A, 14}, -{ 0x01DE, 14}, { 0x063C, 13}, { 0x00CF, 13}, { 0x1594, 13}, { 0x000D, 9} -}, -{ -{ 0x0002, 2}, { 0x0006, 3}, { 0x000F, 4}, { 0x000D, 5}, { 0x000C, 5}, { 0x0015, 6}, -{ 0x0013, 6}, { 0x0012, 6}, { 0x0017, 7}, { 0x001F, 8}, { 0x001E, 8}, { 0x001D, 8}, -{ 0x0025, 9}, { 0x0024, 9}, { 0x0023, 9}, { 0x0021, 9}, { 0x0021, 10}, { 0x0020, 10}, -{ 0x000F, 10}, { 0x000E, 10}, { 0x0007, 11}, { 0x0006, 11}, { 0x0020, 11}, { 0x0021, 11}, -{ 0x0050, 12}, { 0x0051, 12}, { 0x0052, 12}, { 0x000E, 4}, { 0x0014, 6}, { 0x0016, 7}, -{ 0x001C, 8}, { 0x0020, 9}, { 0x001F, 9}, { 0x000D, 10}, { 0x0022, 11}, { 0x0053, 12}, -{ 0x0055, 12}, { 0x000B, 5}, { 0x0015, 7}, { 0x001E, 9}, { 0x000C, 10}, { 0x0056, 12}, -{ 0x0011, 6}, { 0x001B, 8}, { 0x001D, 9}, { 0x000B, 10}, { 0x0010, 6}, { 0x0022, 9}, -{ 0x000A, 10}, { 0x000D, 6}, { 0x001C, 9}, { 0x0008, 10}, { 0x0012, 7}, { 0x001B, 9}, -{ 0x0054, 12}, { 0x0014, 7}, { 0x001A, 9}, { 0x0057, 12}, { 0x0019, 8}, { 0x0009, 10}, -{ 0x0018, 8}, { 0x0023, 11}, { 0x0017, 8}, { 0x0019, 9}, { 0x0018, 9}, { 0x0007, 10}, -{ 0x0058, 12}, { 0x0007, 4}, { 0x000C, 6}, { 0x0016, 8}, { 0x0017, 9}, { 0x0006, 10}, -{ 0x0005, 11}, { 0x0004, 11}, { 0x0059, 12}, { 0x000F, 6}, { 0x0016, 9}, { 0x0005, 10}, -{ 0x000E, 6}, { 0x0004, 10}, { 0x0011, 7}, { 0x0024, 11}, { 0x0010, 7}, { 0x0025, 11}, -{ 0x0013, 7}, { 0x005A, 12}, { 0x0015, 8}, { 0x005B, 12}, { 0x0014, 8}, { 0x0013, 8}, -{ 0x001A, 8}, { 0x0015, 9}, { 0x0014, 9}, { 0x0013, 9}, { 0x0012, 9}, { 0x0011, 9}, -{ 0x0026, 11}, { 0x0027, 11}, { 0x005C, 12}, { 0x005D, 12}, { 0x005E, 12}, { 0x005F, 12}, -{ 0x0003, 7} -}, -{ -{ 0x0002, 2}, { 0x000F, 4}, { 0x0015, 6}, { 0x0017, 7}, { 0x001F, 8}, { 0x0025, 9}, -{ 0x0024, 9}, { 0x0021, 10}, { 0x0020, 10}, { 0x0007, 11}, { 0x0006, 11}, { 0x0020, 11}, -{ 0x0006, 3}, { 0x0014, 6}, { 0x001E, 8}, { 0x000F, 10}, { 0x0021, 11}, { 0x0050, 12}, -{ 0x000E, 4}, { 0x001D, 8}, { 0x000E, 10}, { 0x0051, 12}, { 0x000D, 5}, { 0x0023, 9}, -{ 0x000D, 10}, { 0x000C, 5}, { 0x0022, 9}, { 0x0052, 12}, { 0x000B, 5}, { 0x000C, 10}, -{ 0x0053, 12}, { 0x0013, 6}, { 0x000B, 10}, { 0x0054, 12}, { 0x0012, 6}, { 0x000A, 10}, -{ 0x0011, 6}, { 0x0009, 10}, { 0x0010, 6}, { 0x0008, 10}, { 0x0016, 7}, { 0x0055, 12}, -{ 0x0015, 7}, { 0x0014, 7}, { 0x001C, 8}, { 0x001B, 8}, { 0x0021, 9}, { 0x0020, 9}, -{ 0x001F, 9}, { 0x001E, 9}, { 0x001D, 9}, { 0x001C, 9}, { 0x001B, 9}, { 0x001A, 9}, -{ 0x0022, 11}, { 0x0023, 11}, { 0x0056, 12}, { 0x0057, 12}, { 0x0007, 4}, { 0x0019, 9}, -{ 0x0005, 11}, { 0x000F, 6}, { 0x0004, 11}, { 0x000E, 6}, { 0x000D, 6}, { 0x000C, 6}, -{ 0x0013, 7}, { 0x0012, 7}, { 0x0011, 7}, { 0x0010, 7}, { 0x001A, 8}, { 0x0019, 8}, -{ 0x0018, 8}, { 0x0017, 8}, { 0x0016, 8}, { 0x0015, 8}, { 0x0014, 8}, { 0x0013, 8}, -{ 0x0018, 9}, { 0x0017, 9}, { 0x0016, 9}, { 0x0015, 9}, { 0x0014, 9}, { 0x0013, 9}, -{ 0x0012, 9}, { 0x0011, 9}, { 0x0007, 10}, { 0x0006, 10}, { 0x0005, 10}, { 0x0004, 10}, -{ 0x0024, 11}, { 0x0025, 11}, { 0x0026, 11}, { 0x0027, 11}, { 0x0058, 12}, { 0x0059, 12}, -{ 0x005A, 12}, { 0x005B, 12}, { 0x005C, 12}, { 0x005D, 12}, { 0x005E, 12}, { 0x005F, 12}, -{ 0x0003, 7} -}, -{ -{ 0x0000, 2}, { 0x0003, 3}, { 0x000D, 4}, { 0x0005, 4}, { 0x001C, 5}, { 0x0016, 5}, -{ 0x003F, 6}, { 0x003A, 6}, { 0x002E, 6}, { 0x0022, 6}, { 0x007B, 7}, { 0x0067, 7}, -{ 0x005F, 7}, { 0x0047, 7}, { 0x0026, 7}, { 0x00EF, 8}, { 0x00CD, 8}, { 0x00C1, 8}, -{ 0x00A9, 8}, { 0x004F, 8}, { 0x01F2, 9}, { 0x01DD, 9}, { 0x0199, 9}, { 0x0185, 9}, -{ 0x015D, 9}, { 0x011B, 9}, { 0x03EF, 10}, { 0x03E1, 10}, { 0x03C8, 10}, { 0x0331, 10}, -{ 0x0303, 10}, { 0x02F1, 10}, { 0x02A0, 10}, { 0x0233, 10}, { 0x0126, 10}, { 0x07C0, 11}, -{ 0x076F, 11}, { 0x076C, 11}, { 0x0661, 11}, { 0x0604, 11}, { 0x0572, 11}, { 0x0551, 11}, -{ 0x046A, 11}, { 0x0274, 11}, { 0x0F27, 12}, { 0x0F24, 12}, { 0x0EDB, 12}, { 0x0C8E, 12}, -{ 0x0C0B, 12}, { 0x0C0A, 12}, { 0x0AE3, 12}, { 0x08D6, 12}, { 0x0490, 12}, { 0x0495, 12}, -{ 0x1F19, 13}, { 0x1DB5, 13}, { 0x0009, 4}, { 0x0010, 5}, { 0x0029, 6}, { 0x0062, 7}, -{ 0x00F3, 8}, { 0x00AD, 8}, { 0x01E5, 9}, { 0x0179, 9}, { 0x009C, 9}, { 0x03B1, 10}, -{ 0x02AE, 10}, { 0x0127, 10}, { 0x076E, 11}, { 0x0570, 11}, { 0x0275, 11}, { 0x0F25, 12}, -{ 0x0EC0, 12}, { 0x0AA0, 12}, { 0x08D7, 12}, { 0x1E4C, 13}, { 0x0008, 5}, { 0x0063, 7}, -{ 0x00AF, 8}, { 0x017B, 9}, { 0x03B3, 10}, { 0x07DD, 11}, { 0x0640, 11}, { 0x0F8D, 12}, -{ 0x0BC1, 12}, { 0x0491, 12}, { 0x0028, 6}, { 0x00C3, 8}, { 0x0151, 9}, { 0x02A1, 10}, -{ 0x0573, 11}, { 0x0EC3, 12}, { 0x1F35, 13}, { 0x0065, 7}, { 0x01DA, 9}, { 0x02AF, 10}, -{ 0x0277, 11}, { 0x08C9, 12}, { 0x1781, 13}, { 0x0025, 7}, { 0x0118, 9}, { 0x0646, 11}, -{ 0x0AA6, 12}, { 0x1780, 13}, { 0x00C9, 8}, { 0x0321, 10}, { 0x0F9B, 12}, { 0x191E, 13}, -{ 0x0048, 8}, { 0x07CC, 11}, { 0x0AA1, 12}, { 0x0180, 9}, { 0x0465, 11}, { 0x1905, 13}, -{ 0x03E2, 10}, { 0x0EC1, 12}, { 0x3C9B, 14}, { 0x02F4, 10}, { 0x08C8, 12}, { 0x07C1, 11}, -{ 0x0928, 13}, { 0x05E1, 11}, { 0x320D, 14}, { 0x0EC2, 12}, { 0x6418, 15}, { 0x1F34, 13}, -{ 0x0078, 7}, { 0x0155, 9}, { 0x0552, 11}, { 0x191F, 13}, { 0x00FA, 8}, { 0x07DC, 11}, -{ 0x1907, 13}, { 0x00AC, 8}, { 0x0249, 11}, { 0x13B1, 14}, { 0x01F6, 9}, { 0x0AE2, 12}, -{ 0x01DC, 9}, { 0x04ED, 12}, { 0x0184, 9}, { 0x1904, 13}, { 0x0156, 9}, { 0x09D9, 13}, -{ 0x03E7, 10}, { 0x0929, 13}, { 0x03B2, 10}, { 0x3B68, 14}, { 0x02F5, 10}, { 0x13B0, 14}, -{ 0x0322, 10}, { 0x3B69, 14}, { 0x0234, 10}, { 0x7935, 15}, { 0x07C7, 11}, { 0xC833, 16}, -{ 0x0660, 11}, { 0x7934, 15}, { 0x024B, 11}, { 0xC832, 16}, { 0x0AA7, 12}, { 0x1F18, 13}, -{ 0x007A, 7} -}, -{ -{ 0x0002, 2}, { 0x0000, 3}, { 0x001E, 5}, { 0x0004, 5}, { 0x0012, 6}, { 0x0070, 7}, -{ 0x001A, 7}, { 0x005F, 8}, { 0x0047, 8}, { 0x01D3, 9}, { 0x00B5, 9}, { 0x0057, 9}, -{ 0x03B5, 10}, { 0x016D, 10}, { 0x0162, 10}, { 0x07CE, 11}, { 0x0719, 11}, { 0x0691, 11}, -{ 0x02C6, 11}, { 0x0156, 11}, { 0x0F92, 12}, { 0x0D2E, 12}, { 0x0D20, 12}, { 0x059E, 12}, -{ 0x0468, 12}, { 0x02A6, 12}, { 0x1DA2, 13}, { 0x1C60, 13}, { 0x1A43, 13}, { 0x0B1D, 13}, -{ 0x08C0, 13}, { 0x055D, 13}, { 0x0003, 3}, { 0x000A, 5}, { 0x0077, 7}, { 0x00E5, 8}, -{ 0x01D9, 9}, { 0x03E5, 10}, { 0x0166, 10}, { 0x0694, 11}, { 0x0152, 11}, { 0x059F, 12}, -{ 0x1F3C, 13}, { 0x1A4B, 13}, { 0x055E, 13}, { 0x000C, 4}, { 0x007D, 7}, { 0x0044, 8}, -{ 0x03E0, 10}, { 0x0769, 11}, { 0x0E31, 12}, { 0x1F26, 13}, { 0x055C, 13}, { 0x001B, 5}, -{ 0x00E2, 8}, { 0x03A5, 10}, { 0x02C9, 11}, { 0x1F23, 13}, { 0x3B47, 14}, { 0x0007, 5}, -{ 0x01D8, 9}, { 0x02D8, 11}, { 0x1F27, 13}, { 0x3494, 14}, { 0x0035, 6}, { 0x03E1, 10}, -{ 0x059C, 12}, { 0x38C3, 14}, { 0x000C, 6}, { 0x0165, 10}, { 0x1D23, 13}, { 0x1638, 14}, -{ 0x0068, 7}, { 0x0693, 11}, { 0x3A45, 14}, { 0x0020, 7}, { 0x0F90, 12}, { 0x7CF6, 15}, -{ 0x00E8, 8}, { 0x058F, 12}, { 0x2CEF, 15}, { 0x0045, 8}, { 0x0B3A, 13}, { 0x01F1, 9}, -{ 0x3B46, 14}, { 0x01A7, 9}, { 0x1676, 14}, { 0x0056, 9}, { 0x692A, 15}, { 0x038D, 10}, -{ 0xE309, 16}, { 0x00AA, 10}, { 0x1C611, 17}, { 0x02DF, 11}, { 0xB3B9, 17}, { 0x02C8, 11}, -{ 0x38C20, 18}, { 0x01B0, 11}, { 0x16390, 18}, { 0x0F9F, 12}, { 0x16771, 18}, { 0x0ED0, 12}, -{ 0x71843, 19}, { 0x0D2A, 12}, { 0xF9E8C, 20}, { 0x0461, 12}, { 0xF9E8E, 20}, { 0x0B67, 13}, -{ 0x055F, 13}, { 0x003F, 6}, { 0x006D, 9}, { 0x0E90, 12}, { 0x054E, 13}, { 0x0013, 6}, -{ 0x0119, 10}, { 0x0B66, 13}, { 0x000B, 6}, { 0x0235, 11}, { 0x7CF5, 15}, { 0x0075, 7}, -{ 0x0D24, 12}, { 0xF9E9, 16}, { 0x002E, 7}, { 0x1F22, 13}, { 0x0021, 7}, { 0x054F, 13}, -{ 0x0014, 7}, { 0x3A44, 14}, { 0x00E4, 8}, { 0x7CF7, 15}, { 0x005E, 8}, { 0x7185, 15}, -{ 0x0037, 8}, { 0x2C73, 15}, { 0x01DB, 9}, { 0x59DD, 16}, { 0x01C7, 9}, { 0x692B, 15}, -{ 0x01A6, 9}, { 0x58E5, 16}, { 0x00B4, 9}, { 0x1F3D0, 17}, { 0x00B0, 9}, { 0xB1C9, 17}, -{ 0x03E6, 10}, { 0x16770, 18}, { 0x016E, 10}, { 0x3E7A2, 18}, { 0x011B, 10}, { 0xF9E8D, 20}, -{ 0x00D9, 10}, { 0xF9E8F, 20}, { 0x00A8, 10}, { 0x2C723, 19}, { 0x0749, 11}, { 0xE3084, 20}, -{ 0x0696, 11}, { 0x58E45, 20}, { 0x02DE, 11}, { 0xB1C88, 21}, { 0x0231, 11}, { 0x1C610A, 21}, -{ 0x01B1, 11}, { 0x71842D, 23}, { 0x0D2B, 12}, { 0x38C217, 22}, { 0x0D2F, 12}, { 0x163913, 22}, -{ 0x05B2, 12}, { 0x163912, 22}, { 0x0469, 12}, { 0x71842C, 23}, { 0x1A42, 13}, { 0x08C1, 13}, -{ 0x0073, 7} -} -}; +#include "vc1data.h" /* which indexes point to last=1 entries in tables */ static const int vc1_last_decode_table[AC_MODES] = { diff --git a/libavcodec/vc1data.c b/libavcodec/vc1data.c index 7f979ba109..bc065ea60e 100644 --- a/libavcodec/vc1data.c +++ b/libavcodec/vc1data.c @@ -84,7 +84,7 @@ const uint8_t ff_vc1_mbmode_intfrp[2][15][4] = { } }; -const int ff_vc1_fps_nr[5] = { 24, 25, 30, 50, 60 }, +const int ff_vc1_fps_nr[7] = { 24, 25, 30, 50, 60, 48, 72 }, ff_vc1_fps_dr[2] = { 1000, 1001 }; const uint8_t ff_vc1_pquant_table[3][32] = { /* Implicit quantizer */ @@ -1129,3 +1129,7 @@ const uint16_t vc1_b_field_mvpred_scales[7][4] = { { 26, 17, 12, 10 }, // ZONE1OFFSET_X { 7, 4, 3, 3 } // ZONE1OFFSET_Y }; + +const int ff_vc1_ac_sizes[AC_MODES] = { + 186, 169, 133, 149, 103, 103, 163, 175 +}; diff --git a/libavcodec/vc1data.h b/libavcodec/vc1data.h index f11122504b..1514ce1645 100644 --- a/libavcodec/vc1data.h +++ b/libavcodec/vc1data.h @@ -41,7 +41,7 @@ extern const int ff_vc1_ttfrm_to_tt[4]; extern const uint8_t ff_vc1_mv_pmode_table[2][5]; extern const uint8_t ff_vc1_mv_pmode_table2[2][4]; -extern const int ff_vc1_fps_nr[5], ff_vc1_fps_dr[2]; +extern const int ff_vc1_fps_nr[7], ff_vc1_fps_dr[2]; extern const uint8_t ff_vc1_pquant_table[3][32]; /* MBMODE table for interlaced frame P-picture */ @@ -200,4 +200,9 @@ extern const int32_t ff_vc1_dqscale[63]; extern const uint16_t vc1_field_mvpred_scales[2][7][4]; /* B Interlaced field picture backward MV predictor scaling values for first field (Table 115) */ extern const uint16_t vc1_b_field_mvpred_scales[7][4]; + +#define AC_MODES 8 + +extern const int ff_vc1_ac_sizes[AC_MODES]; + #endif /* AVCODEC_VC1DATA_H */ diff --git a/libavcodec/vc1dec.c b/libavcodec/vc1dec.c index 109c009338..5f745ad24e 100644 --- a/libavcodec/vc1dec.c +++ b/libavcodec/vc1dec.c @@ -45,154 +45,12 @@ #define MB_INTRA_VLC_BITS 9 #define DC_VLC_BITS 9 -#define AC_VLC_BITS 9 -static const uint16_t vlc_offs[] = { - 0, 520, 552, 616, 1128, 1160, 1224, 1740, 1772, 1836, 1900, 2436, - 2986, 3050, 3610, 4154, 4218, 4746, 5326, 5390, 5902, 6554, 7658, 8342, - 9304, 9988, 10630, 11234, 12174, 13006, 13560, 14232, 14786, 15432, 16350, 17522, - 20372, 21818, 22330, 22394, 23166, 23678, 23742, 24820, 25332, 25396, 26460, 26980, - 27048, 27592, 27600, 27608, 27616, 27624, 28224, 28258, 28290, 28802, 28834, 28866, - 29378, 29412, 29444, 29960, 29994, 30026, 30538, 30572, 30604, 31120, 31154, 31186, - 31714, 31746, 31778, 32306, 32340, 32372 -}; - // offset tables for interlaced picture MVDATA decoding static const int offset_table1[9] = { 0, 1, 2, 4, 8, 16, 32, 64, 128 }; static const int offset_table2[9] = { 0, 1, 3, 7, 15, 31, 63, 127, 255 }; -/** - * Init VC-1 specific tables and VC1Context members - * @param v The VC1Context to initialize - * @return Status - */ -static int vc1_init_common(VC1Context *v) -{ - static int done = 0; - int i = 0; - static VLC_TYPE vlc_table[32372][2]; - - v->hrd_rate = v->hrd_buffer = NULL; - - /* VLC tables */ - if (!done) { - INIT_VLC_STATIC(&ff_vc1_bfraction_vlc, VC1_BFRACTION_VLC_BITS, 23, - ff_vc1_bfraction_bits, 1, 1, - ff_vc1_bfraction_codes, 1, 1, 1 << VC1_BFRACTION_VLC_BITS); - INIT_VLC_STATIC(&ff_vc1_norm2_vlc, VC1_NORM2_VLC_BITS, 4, - ff_vc1_norm2_bits, 1, 1, - ff_vc1_norm2_codes, 1, 1, 1 << VC1_NORM2_VLC_BITS); - INIT_VLC_STATIC(&ff_vc1_norm6_vlc, VC1_NORM6_VLC_BITS, 64, - ff_vc1_norm6_bits, 1, 1, - ff_vc1_norm6_codes, 2, 2, 556); - INIT_VLC_STATIC(&ff_vc1_imode_vlc, VC1_IMODE_VLC_BITS, 7, - ff_vc1_imode_bits, 1, 1, - ff_vc1_imode_codes, 1, 1, 1 << VC1_IMODE_VLC_BITS); - for (i = 0; i < 3; i++) { - ff_vc1_ttmb_vlc[i].table = &vlc_table[vlc_offs[i * 3 + 0]]; - ff_vc1_ttmb_vlc[i].table_allocated = vlc_offs[i * 3 + 1] - vlc_offs[i * 3 + 0]; - init_vlc(&ff_vc1_ttmb_vlc[i], VC1_TTMB_VLC_BITS, 16, - ff_vc1_ttmb_bits[i], 1, 1, - ff_vc1_ttmb_codes[i], 2, 2, INIT_VLC_USE_NEW_STATIC); - ff_vc1_ttblk_vlc[i].table = &vlc_table[vlc_offs[i * 3 + 1]]; - ff_vc1_ttblk_vlc[i].table_allocated = vlc_offs[i * 3 + 2] - vlc_offs[i * 3 + 1]; - init_vlc(&ff_vc1_ttblk_vlc[i], VC1_TTBLK_VLC_BITS, 8, - ff_vc1_ttblk_bits[i], 1, 1, - ff_vc1_ttblk_codes[i], 1, 1, INIT_VLC_USE_NEW_STATIC); - ff_vc1_subblkpat_vlc[i].table = &vlc_table[vlc_offs[i * 3 + 2]]; - ff_vc1_subblkpat_vlc[i].table_allocated = vlc_offs[i * 3 + 3] - vlc_offs[i * 3 + 2]; - init_vlc(&ff_vc1_subblkpat_vlc[i], VC1_SUBBLKPAT_VLC_BITS, 15, - ff_vc1_subblkpat_bits[i], 1, 1, - ff_vc1_subblkpat_codes[i], 1, 1, INIT_VLC_USE_NEW_STATIC); - } - for (i = 0; i < 4; i++) { - ff_vc1_4mv_block_pattern_vlc[i].table = &vlc_table[vlc_offs[i * 3 + 9]]; - ff_vc1_4mv_block_pattern_vlc[i].table_allocated = vlc_offs[i * 3 + 10] - vlc_offs[i * 3 + 9]; - init_vlc(&ff_vc1_4mv_block_pattern_vlc[i], VC1_4MV_BLOCK_PATTERN_VLC_BITS, 16, - ff_vc1_4mv_block_pattern_bits[i], 1, 1, - ff_vc1_4mv_block_pattern_codes[i], 1, 1, INIT_VLC_USE_NEW_STATIC); - ff_vc1_cbpcy_p_vlc[i].table = &vlc_table[vlc_offs[i * 3 + 10]]; - ff_vc1_cbpcy_p_vlc[i].table_allocated = vlc_offs[i * 3 + 11] - vlc_offs[i * 3 + 10]; - init_vlc(&ff_vc1_cbpcy_p_vlc[i], VC1_CBPCY_P_VLC_BITS, 64, - ff_vc1_cbpcy_p_bits[i], 1, 1, - ff_vc1_cbpcy_p_codes[i], 2, 2, INIT_VLC_USE_NEW_STATIC); - ff_vc1_mv_diff_vlc[i].table = &vlc_table[vlc_offs[i * 3 + 11]]; - ff_vc1_mv_diff_vlc[i].table_allocated = vlc_offs[i * 3 + 12] - vlc_offs[i * 3 + 11]; - init_vlc(&ff_vc1_mv_diff_vlc[i], VC1_MV_DIFF_VLC_BITS, 73, - ff_vc1_mv_diff_bits[i], 1, 1, - ff_vc1_mv_diff_codes[i], 2, 2, INIT_VLC_USE_NEW_STATIC); - } - for (i = 0; i < 8; i++) { - ff_vc1_ac_coeff_table[i].table = &vlc_table[vlc_offs[i * 2 + 21]]; - ff_vc1_ac_coeff_table[i].table_allocated = vlc_offs[i * 2 + 22] - vlc_offs[i * 2 + 21]; - init_vlc(&ff_vc1_ac_coeff_table[i], AC_VLC_BITS, vc1_ac_sizes[i], - &vc1_ac_tables[i][0][1], 8, 4, - &vc1_ac_tables[i][0][0], 8, 4, INIT_VLC_USE_NEW_STATIC); - /* initialize interlaced MVDATA tables (2-Ref) */ - ff_vc1_2ref_mvdata_vlc[i].table = &vlc_table[vlc_offs[i * 2 + 22]]; - ff_vc1_2ref_mvdata_vlc[i].table_allocated = vlc_offs[i * 2 + 23] - vlc_offs[i * 2 + 22]; - init_vlc(&ff_vc1_2ref_mvdata_vlc[i], VC1_2REF_MVDATA_VLC_BITS, 126, - ff_vc1_2ref_mvdata_bits[i], 1, 1, - ff_vc1_2ref_mvdata_codes[i], 4, 4, INIT_VLC_USE_NEW_STATIC); - } - for (i = 0; i < 4; i++) { - /* initialize 4MV MBMODE VLC tables for interlaced frame P picture */ - ff_vc1_intfr_4mv_mbmode_vlc[i].table = &vlc_table[vlc_offs[i * 3 + 37]]; - ff_vc1_intfr_4mv_mbmode_vlc[i].table_allocated = vlc_offs[i * 3 + 38] - vlc_offs[i * 3 + 37]; - init_vlc(&ff_vc1_intfr_4mv_mbmode_vlc[i], VC1_INTFR_4MV_MBMODE_VLC_BITS, 15, - ff_vc1_intfr_4mv_mbmode_bits[i], 1, 1, - ff_vc1_intfr_4mv_mbmode_codes[i], 2, 2, INIT_VLC_USE_NEW_STATIC); - /* initialize NON-4MV MBMODE VLC tables for the same */ - ff_vc1_intfr_non4mv_mbmode_vlc[i].table = &vlc_table[vlc_offs[i * 3 + 38]]; - ff_vc1_intfr_non4mv_mbmode_vlc[i].table_allocated = vlc_offs[i * 3 + 39] - vlc_offs[i * 3 + 38]; - init_vlc(&ff_vc1_intfr_non4mv_mbmode_vlc[i], VC1_INTFR_NON4MV_MBMODE_VLC_BITS, 9, - ff_vc1_intfr_non4mv_mbmode_bits[i], 1, 1, - ff_vc1_intfr_non4mv_mbmode_codes[i], 1, 1, INIT_VLC_USE_NEW_STATIC); - /* initialize interlaced MVDATA tables (1-Ref) */ - ff_vc1_1ref_mvdata_vlc[i].table = &vlc_table[vlc_offs[i * 3 + 39]]; - ff_vc1_1ref_mvdata_vlc[i].table_allocated = vlc_offs[i * 3 + 40] - vlc_offs[i * 3 + 39]; - init_vlc(&ff_vc1_1ref_mvdata_vlc[i], VC1_1REF_MVDATA_VLC_BITS, 72, - ff_vc1_1ref_mvdata_bits[i], 1, 1, - ff_vc1_1ref_mvdata_codes[i], 4, 4, INIT_VLC_USE_NEW_STATIC); - } - for (i = 0; i < 4; i++) { - /* Initialize 2MV Block pattern VLC tables */ - ff_vc1_2mv_block_pattern_vlc[i].table = &vlc_table[vlc_offs[i + 49]]; - ff_vc1_2mv_block_pattern_vlc[i].table_allocated = vlc_offs[i + 50] - vlc_offs[i + 49]; - init_vlc(&ff_vc1_2mv_block_pattern_vlc[i], VC1_2MV_BLOCK_PATTERN_VLC_BITS, 4, - ff_vc1_2mv_block_pattern_bits[i], 1, 1, - ff_vc1_2mv_block_pattern_codes[i], 1, 1, INIT_VLC_USE_NEW_STATIC); - } - for (i = 0; i < 8; i++) { - /* Initialize interlaced CBPCY VLC tables (Table 124 - Table 131) */ - ff_vc1_icbpcy_vlc[i].table = &vlc_table[vlc_offs[i * 3 + 53]]; - ff_vc1_icbpcy_vlc[i].table_allocated = vlc_offs[i * 3 + 54] - vlc_offs[i * 3 + 53]; - init_vlc(&ff_vc1_icbpcy_vlc[i], VC1_ICBPCY_VLC_BITS, 63, - ff_vc1_icbpcy_p_bits[i], 1, 1, - ff_vc1_icbpcy_p_codes[i], 2, 2, INIT_VLC_USE_NEW_STATIC); - /* Initialize interlaced field picture MBMODE VLC tables */ - ff_vc1_if_mmv_mbmode_vlc[i].table = &vlc_table[vlc_offs[i * 3 + 54]]; - ff_vc1_if_mmv_mbmode_vlc[i].table_allocated = vlc_offs[i * 3 + 55] - vlc_offs[i * 3 + 54]; - init_vlc(&ff_vc1_if_mmv_mbmode_vlc[i], VC1_IF_MMV_MBMODE_VLC_BITS, 8, - ff_vc1_if_mmv_mbmode_bits[i], 1, 1, - ff_vc1_if_mmv_mbmode_codes[i], 1, 1, INIT_VLC_USE_NEW_STATIC); - ff_vc1_if_1mv_mbmode_vlc[i].table = &vlc_table[vlc_offs[i * 3 + 55]]; - ff_vc1_if_1mv_mbmode_vlc[i].table_allocated = vlc_offs[i * 3 + 56] - vlc_offs[i * 3 + 55]; - init_vlc(&ff_vc1_if_1mv_mbmode_vlc[i], VC1_IF_1MV_MBMODE_VLC_BITS, 6, - ff_vc1_if_1mv_mbmode_bits[i], 1, 1, - ff_vc1_if_1mv_mbmode_codes[i], 1, 1, INIT_VLC_USE_NEW_STATIC); - } - done = 1; - } - - /* Other defaults */ - v->pq = -1; - v->mvrange = 0; /* 7.1.1.18, p80 */ - - return 0; -} - /***********************************************************************/ /** * @name VC-1 Bitplane decoding @@ -478,7 +336,10 @@ static void vc1_mc_1mv(VC1Context *v, int dir) int dxy, mx, my, uvmx, uvmy, src_x, src_y, uvsrc_x, uvsrc_y; int off, off_uv; int v_edge_pos = s->v_edge_pos >> v->field_mode; - if (!v->field_mode && !v->s.last_picture.f.data[0]) + + if ((!v->field_mode || + (v->ref_field_type[dir] == 1 && v->cur_field_type == 1)) && + !v->s.last_picture.f.data[0]) return; mx = s->mv[dir][0][0]; @@ -534,6 +395,11 @@ static void vc1_mc_1mv(VC1Context *v, int dir) } } + if (!srcY || !srcU) { + av_log(v->s.avctx, AV_LOG_ERROR, "Referenced frame missing.\n"); + return; + } + src_x = s->mb_x * 16 + (mx >> 2); src_y = s->mb_y * 16 + (my >> 2); uvsrc_x = s->mb_x * 8 + (uvmx >> 2); @@ -690,7 +556,9 @@ static void vc1_mc_4mv_luma(VC1Context *v, int n, int dir) int fieldmv = (v->fcm == ILACE_FRAME) ? v->blk_mv_type[s->block_index[n]] : 0; int v_edge_pos = s->v_edge_pos >> v->field_mode; - if (!v->field_mode && !v->s.last_picture.f.data[0]) + if ((!v->field_mode || + (v->ref_field_type[dir] == 1 && v->cur_field_type == 1)) && + !v->s.last_picture.f.data[0]) return; mx = s->mv[dir][n][0]; @@ -707,6 +575,11 @@ static void vc1_mc_4mv_luma(VC1Context *v, int n, int dir) } else srcY = s->next_picture.f.data[0]; + if (!srcY) { + av_log(v->s.avctx, AV_LOG_ERROR, "Referenced frame missing.\n"); + return; + } + if (v->field_mode) { if (v->cur_field_type != v->ref_field_type[dir]) my = my - 2 + 4 * v->cur_field_type; @@ -946,6 +819,8 @@ static void vc1_mc_4mv_chroma(VC1Context *v, int dir) if (dominant) chroma_ref_type = !v->cur_field_type; } + if (v->field_mode && chroma_ref_type == 1 && v->cur_field_type == 1 && !v->s.last_picture.f.data[0]) + return; s->current_picture.f.motion_val[1][s->block_index[0] + v->blocks_off][0] = tx; s->current_picture.f.motion_val[1][s->block_index[0] + v->blocks_off][1] = ty; uvmx = (tx + ((tx & 3) == 3)) >> 1; @@ -991,6 +866,11 @@ static void vc1_mc_4mv_chroma(VC1Context *v, int dir) srcV = s->next_picture.f.data[2] + uvsrc_y * s->uvlinesize + uvsrc_x; } + if (!srcU) { + av_log(v->s.avctx, AV_LOG_ERROR, "Referenced frame missing.\n"); + return; + } + if (v->field_mode) { if (chroma_ref_type) { srcU += s->current_picture_ptr->f.linesize[1]; @@ -2505,6 +2385,7 @@ static inline int vc1_pred_dc(MpegEncContext *s, int overlap, int pq, int n, int16_t *dc_val; int mb_pos = s->mb_x + s->mb_y * s->mb_stride; int q1, q2 = 0; + int dqscale_index; wrap = s->block_wrap[n]; dc_val = s->dc_val[0] + s->block_index[n]; @@ -2517,15 +2398,18 @@ static inline int vc1_pred_dc(MpegEncContext *s, int overlap, int pq, int n, a = dc_val[ - wrap]; /* scale predictors if needed */ q1 = s->current_picture.f.qscale_table[mb_pos]; + dqscale_index = s->y_dc_scale_table[q1] - 1; + if (dqscale_index < 0) + return 0; if (c_avail && (n != 1 && n != 3)) { q2 = s->current_picture.f.qscale_table[mb_pos - 1]; if (q2 && q2 != q1) - c = (c * s->y_dc_scale_table[q2] * ff_vc1_dqscale[s->y_dc_scale_table[q1] - 1] + 0x20000) >> 18; + c = (c * s->y_dc_scale_table[q2] * ff_vc1_dqscale[dqscale_index] + 0x20000) >> 18; } if (a_avail && (n != 2 && n != 3)) { q2 = s->current_picture.f.qscale_table[mb_pos - s->mb_stride]; if (q2 && q2 != q1) - a = (a * s->y_dc_scale_table[q2] * ff_vc1_dqscale[s->y_dc_scale_table[q1] - 1] + 0x20000) >> 18; + a = (a * s->y_dc_scale_table[q2] * ff_vc1_dqscale[dqscale_index] + 0x20000) >> 18; } if (a_avail && c_avail && (n != 3)) { int off = mb_pos; @@ -2535,7 +2419,7 @@ static inline int vc1_pred_dc(MpegEncContext *s, int overlap, int pq, int n, off -= s->mb_stride; q2 = s->current_picture.f.qscale_table[off]; if (q2 && q2 != q1) - b = (b * s->y_dc_scale_table[q2] * ff_vc1_dqscale[s->y_dc_scale_table[q1] - 1] + 0x20000) >> 18; + b = (b * s->y_dc_scale_table[q2] * ff_vc1_dqscale[dqscale_index] + 0x20000) >> 18; } if (a_avail && c_avail) { @@ -2613,7 +2497,7 @@ static void vc1_decode_ac_coeff(VC1Context *v, int *last, int *skip, int index, escape, run = 0, level = 0, lst = 0; index = get_vlc2(gb, ff_vc1_ac_coeff_table[codingset].table, AC_VLC_BITS, 3); - if (index != vc1_ac_sizes[codingset] - 1) { + if (index != ff_vc1_ac_sizes[codingset] - 1) { run = vc1_index_decode_table[codingset][index][0]; level = vc1_index_decode_table[codingset][index][1]; lst = index >= vc1_last_decode_table[codingset] || get_bits_left(gb) < 0; @@ -2952,6 +2836,8 @@ static int vc1_decode_i_block_adv(VC1Context *v, DCTELEM block[64], int n, q1 = q1 * 2 + ((q1 == v->pq) ? v->halfpq : 0) - 1; q2 = q2 * 2 + ((q2 == v->pq) ? v->halfpq : 0) - 1; + if (q1 < 1) + return AVERROR_INVALIDDATA; if (dc_pred_dir) { // left for (k = 1; k < 8; k++) block[k << v->left_blk_sh] += (ac_val[k] * q2 * ff_vc1_dqscale[q1 - 1] + 0x20000) >> 18; @@ -2994,6 +2880,8 @@ static int vc1_decode_i_block_adv(VC1Context *v, DCTELEM block[64], int n, if (q2 && q1 != q2) { q1 = q1 * 2 + ((q1 == v->pq) ? v->halfpq : 0) - 1; q2 = q2 * 2 + ((q2 == v->pq) ? v->halfpq : 0) - 1; + if (q1 < 1) + return AVERROR_INVALIDDATA; for (k = 1; k < 8; k++) ac_val2[k] = (ac_val2[k] * q2 * ff_vc1_dqscale[q1 - 1] + 0x20000) >> 18; } @@ -3004,6 +2892,8 @@ static int vc1_decode_i_block_adv(VC1Context *v, DCTELEM block[64], int n, if (q2 && q1 != q2) { q1 = q1 * 2 + ((q1 == v->pq) ? v->halfpq : 0) - 1; q2 = q2 * 2 + ((q2 == v->pq) ? v->halfpq : 0) - 1; + if (q1 < 1) + return AVERROR_INVALIDDATA; for (k = 1; k < 8; k++) ac_val2[k + 8] = (ac_val2[k + 8] * q2 * ff_vc1_dqscale[q1 - 1] + 0x20000) >> 18; } @@ -3162,6 +3052,8 @@ static int vc1_decode_intra_block(VC1Context *v, DCTELEM block[64], int n, q1 = q1 * 2 + ((q1 == v->pq) ? v->halfpq : 0) - 1; q2 = q2 * 2 + ((q2 == v->pq) ? v->halfpq : 0) - 1; + if (q1 < 1) + return AVERROR_INVALIDDATA; if (dc_pred_dir) { // left for (k = 1; k < 8; k++) block[k << v->left_blk_sh] += (ac_val[k] * q2 * ff_vc1_dqscale[q1 - 1] + 0x20000) >> 18; @@ -3204,6 +3096,8 @@ static int vc1_decode_intra_block(VC1Context *v, DCTELEM block[64], int n, if (q2 && q1 != q2) { q1 = q1 * 2 + ((q1 == v->pq) ? v->halfpq : 0) - 1; q2 = q2 * 2 + ((q2 == v->pq) ? v->halfpq : 0) - 1; + if (q1 < 1) + return AVERROR_INVALIDDATA; for (k = 1; k < 8; k++) ac_val2[k] = (ac_val2[k] * q2 * ff_vc1_dqscale[q1 - 1] + 0x20000) >> 18; } @@ -3214,6 +3108,8 @@ static int vc1_decode_intra_block(VC1Context *v, DCTELEM block[64], int n, if (q2 && q1 != q2) { q1 = q1 * 2 + ((q1 == v->pq) ? v->halfpq : 0) - 1; q2 = q2 * 2 + ((q2 == v->pq) ? v->halfpq : 0) - 1; + if (q1 < 1) + return AVERROR_INVALIDDATA; for (k = 1; k < 8; k++) ac_val2[k + 8] = (ac_val2[k + 8] * q2 * ff_vc1_dqscale[q1 - 1] + 0x20000) >> 18; } @@ -4068,7 +3964,7 @@ static int vc1_decode_p_mb_intfi(VC1Context *v) s->current_picture.f.mb_type[mb_pos + v->mb_off] = MB_TYPE_16x16; for (i = 0; i < 6; i++) v->mb_type[0][s->block_index[i]] = 0; if (idx_mbmode <= 5) { // 1-MV - dmv_x = dmv_y = 0; + dmv_x = dmv_y = pred_flag = 0; if (idx_mbmode & 1) { get_mvdata_interlaced(v, &dmv_x, &dmv_y, &pred_flag); } @@ -4845,6 +4741,9 @@ static void vc1_decode_skip_blocks(VC1Context *v) { MpegEncContext *s = &v->s; + if (!v->s.last_picture.f.data[0]) + return; + ff_er_add_slice(s, 0, s->start_mb_y, s->mb_width - 1, s->end_mb_y - 1, ER_MB_END); s->first_slice_line = 1; for (s->mb_y = s->start_mb_y; s->mb_y < s->end_mb_y; s->mb_y++) { @@ -5230,8 +5129,19 @@ static av_cold int vc1_decode_init_alloc_tables(VC1Context *v) if (!v->mv_type_mb_plane || !v->direct_mb_plane || !v->acpred_plane || !v->over_flags_plane || !v->block || !v->cbp_base || !v->ttblk_base || !v->is_intra_base || !v->luma_mv_base || - !v->mb_type_base) - return -1; + !v->mb_type_base) { + av_freep(&v->mv_type_mb_plane); + av_freep(&v->direct_mb_plane); + av_freep(&v->acpred_plane); + av_freep(&v->over_flags_plane); + av_freep(&v->block); + av_freep(&v->cbp_base); + av_freep(&v->ttblk_base); + av_freep(&v->is_intra_base); + av_freep(&v->luma_mv_base); + av_freep(&v->mb_type_base); + return AVERROR(ENOMEM); + } return 0; } @@ -5266,7 +5176,7 @@ static av_cold int vc1_decode_init(AVCodecContext *avctx) avctx->idct_algo = FF_IDCT_WMV2; } - if (vc1_init_common(v) < 0) + if (ff_vc1_init_common(v) < 0) return -1; ff_vc1dsp_init(&v->vc1dsp); @@ -5579,8 +5489,12 @@ static int vc1_decode_frame(AVCodecContext *avctx, void *data, } if (!s->context_initialized) { - if (ff_msmpeg4_decode_init(avctx) < 0 || vc1_decode_init_alloc_tables(v) < 0) + if (ff_msmpeg4_decode_init(avctx) < 0) return -1; + if (vc1_decode_init_alloc_tables(v) < 0) { + MPV_common_end(s); + return -1; + } s->low_delay = !avctx->has_b_frames || v->res_sprite; @@ -5668,6 +5582,8 @@ static int vc1_decode_frame(AVCodecContext *avctx, void *data, if (avctx->hwaccel->end_frame(avctx) < 0) goto err; } else { + int header_ret = 0; + ff_er_frame_start(s); v->bits = buf_size * 8; @@ -5688,8 +5604,20 @@ static int vc1_decode_frame(AVCodecContext *avctx, void *data, v->mv_f[1] = tmp[1]; } mb_height = s->mb_height >> v->field_mode; + + if (!mb_height) { + av_log(v->s.avctx, AV_LOG_ERROR, "Invalid mb_height.\n"); + goto err; + } + for (i = 0; i <= n_slices; i++) { if (i > 0 && slices[i - 1].mby_start >= mb_height) { + if (v->field_mode <= 0) { + av_log(v->s.avctx, AV_LOG_ERROR, "Slice %d starts beyond " + "picture boundary (%d >= %d)\n", i, + slices[i - 1].mby_start, mb_height); + continue; + } v->second_field = 1; v->blocks_off = s->mb_width * s->mb_height << 1; v->mb_off = s->mb_stride * s->mb_height >> 1; @@ -5700,18 +5628,26 @@ static int vc1_decode_frame(AVCodecContext *avctx, void *data, } if (i) { v->pic_header_flag = 0; - if (v->field_mode && i == n_slices1 + 2) - vc1_parse_frame_header_adv(v, &s->gb); - else if (get_bits1(&s->gb)) { + if (v->field_mode && i == n_slices1 + 2) { + if ((header_ret = vc1_parse_frame_header_adv(v, &s->gb)) < 0) { + av_log(v->s.avctx, AV_LOG_ERROR, "Field header damaged\n"); + continue; + } + } else if (get_bits1(&s->gb)) { v->pic_header_flag = 1; - vc1_parse_frame_header_adv(v, &s->gb); + if ((header_ret = vc1_parse_frame_header_adv(v, &s->gb)) < 0) { + av_log(v->s.avctx, AV_LOG_ERROR, "Slice header damaged\n"); + continue; + } } } + if (header_ret < 0) + continue; s->start_mb_y = (i == 0) ? 0 : FFMAX(0, slices[i-1].mby_start % mb_height); if (!v->field_mode || v->second_field) s->end_mb_y = (i == n_slices ) ? mb_height : FFMIN(mb_height, slices[i].mby_start % mb_height); else - s->end_mb_y = (i == n_slices1 + 1) ? mb_height : FFMIN(mb_height, slices[i].mby_start % mb_height); + s->end_mb_y = (i <= n_slices1 + 1) ? mb_height : FFMIN(mb_height, slices[i].mby_start % mb_height); vc1_decode_blocks(v); if (i != n_slices) s->gb = slices[i].gb; @@ -5794,6 +5730,7 @@ AVCodec ff_vc1_decoder = { .init = vc1_decode_init, .close = vc1_decode_end, .decode = vc1_decode_frame, + .flush = ff_mpeg_flush, .capabilities = CODEC_CAP_DR1 | CODEC_CAP_DELAY, .long_name = NULL_IF_CONFIG_SMALL("SMPTE VC-1"), .pix_fmts = ff_hwaccel_pixfmt_list_420, @@ -5809,6 +5746,7 @@ AVCodec ff_wmv3_decoder = { .init = vc1_decode_init, .close = vc1_decode_end, .decode = vc1_decode_frame, + .flush = ff_mpeg_flush, .capabilities = CODEC_CAP_DR1 | CODEC_CAP_DELAY, .long_name = NULL_IF_CONFIG_SMALL("Windows Media Video 9"), .pix_fmts = ff_hwaccel_pixfmt_list_420, diff --git a/libavcodec/vc1dsp.c b/libavcodec/vc1dsp.c index 83cd0cfe8c..da7593feca 100644 --- a/libavcodec/vc1dsp.c +++ b/libavcodec/vc1dsp.c @@ -139,8 +139,6 @@ static void vc1_h_s_overlap_c(DCTELEM *left, DCTELEM *right) * @see 8.6 */ static av_always_inline int vc1_filter_line(uint8_t* src, int stride, int pq){ - uint8_t *cm = ff_cropTbl + MAX_NEG_CROP; - int a0 = (2*(src[-2*stride] - src[ 1*stride]) - 5*(src[-1*stride] - src[ 0*stride]) + 4) >> 3; int a0_sign = a0 >> 31; /* Store sign */ a0 = (a0 ^ a0_sign) - a0_sign; /* a0 = FFABS(a0); */ @@ -163,8 +161,8 @@ static av_always_inline int vc1_filter_line(uint8_t* src, int stride, int pq){ else{ d = FFMIN(d, clip); d = (d ^ d_sign) - d_sign; /* Restore sign */ - src[-1*stride] = cm[src[-1*stride] - d]; - src[ 0*stride] = cm[src[ 0*stride] + d]; + src[-1*stride] = av_clip_uint8(src[-1*stride] - d); + src[ 0*stride] = av_clip_uint8(src[ 0*stride] + d); } return 1; } @@ -234,19 +232,17 @@ static void vc1_inv_trans_8x8_dc_c(uint8_t *dest, int linesize, DCTELEM *block) { int i; int dc = block[0]; - const uint8_t *cm; dc = (3 * dc + 1) >> 1; dc = (3 * dc + 16) >> 5; - cm = ff_cropTbl + MAX_NEG_CROP + dc; for(i = 0; i < 8; i++){ - dest[0] = cm[dest[0]]; - dest[1] = cm[dest[1]]; - dest[2] = cm[dest[2]]; - dest[3] = cm[dest[3]]; - dest[4] = cm[dest[4]]; - dest[5] = cm[dest[5]]; - dest[6] = cm[dest[6]]; - dest[7] = cm[dest[7]]; + dest[0] = av_clip_uint8(dest[0] + dc); + dest[1] = av_clip_uint8(dest[1] + dc); + dest[2] = av_clip_uint8(dest[2] + dc); + dest[3] = av_clip_uint8(dest[3] + dc); + dest[4] = av_clip_uint8(dest[4] + dc); + dest[5] = av_clip_uint8(dest[5] + dc); + dest[6] = av_clip_uint8(dest[6] + dc); + dest[7] = av_clip_uint8(dest[7] + dc); dest += linesize; } } @@ -326,19 +322,17 @@ static void vc1_inv_trans_8x4_dc_c(uint8_t *dest, int linesize, DCTELEM *block) { int i; int dc = block[0]; - const uint8_t *cm; dc = ( 3 * dc + 1) >> 1; dc = (17 * dc + 64) >> 7; - cm = ff_cropTbl + MAX_NEG_CROP + dc; for(i = 0; i < 4; i++){ - dest[0] = cm[dest[0]]; - dest[1] = cm[dest[1]]; - dest[2] = cm[dest[2]]; - dest[3] = cm[dest[3]]; - dest[4] = cm[dest[4]]; - dest[5] = cm[dest[5]]; - dest[6] = cm[dest[6]]; - dest[7] = cm[dest[7]]; + dest[0] = av_clip_uint8(dest[0] + dc); + dest[1] = av_clip_uint8(dest[1] + dc); + dest[2] = av_clip_uint8(dest[2] + dc); + dest[3] = av_clip_uint8(dest[3] + dc); + dest[4] = av_clip_uint8(dest[4] + dc); + dest[5] = av_clip_uint8(dest[5] + dc); + dest[6] = av_clip_uint8(dest[6] + dc); + dest[7] = av_clip_uint8(dest[7] + dc); dest += linesize; } } @@ -348,7 +342,6 @@ static void vc1_inv_trans_8x4_c(uint8_t *dest, int linesize, DCTELEM *block) int i; register int t1,t2,t3,t4,t5,t6,t7,t8; DCTELEM *src, *dst; - const uint8_t *cm = ff_cropTbl + MAX_NEG_CROP; src = block; dst = block; @@ -388,10 +381,10 @@ static void vc1_inv_trans_8x4_c(uint8_t *dest, int linesize, DCTELEM *block) t3 = 22 * src[ 8] + 10 * src[24]; t4 = 22 * src[24] - 10 * src[ 8]; - dest[0*linesize] = cm[dest[0*linesize] + ((t1 + t3) >> 7)]; - dest[1*linesize] = cm[dest[1*linesize] + ((t2 - t4) >> 7)]; - dest[2*linesize] = cm[dest[2*linesize] + ((t2 + t4) >> 7)]; - dest[3*linesize] = cm[dest[3*linesize] + ((t1 - t3) >> 7)]; + dest[0*linesize] = av_clip_uint8(dest[0*linesize] + ((t1 + t3) >> 7)); + dest[1*linesize] = av_clip_uint8(dest[1*linesize] + ((t2 - t4) >> 7)); + dest[2*linesize] = av_clip_uint8(dest[2*linesize] + ((t2 + t4) >> 7)); + dest[3*linesize] = av_clip_uint8(dest[3*linesize] + ((t1 - t3) >> 7)); src ++; dest++; @@ -404,15 +397,13 @@ static void vc1_inv_trans_4x8_dc_c(uint8_t *dest, int linesize, DCTELEM *block) { int i; int dc = block[0]; - const uint8_t *cm; dc = (17 * dc + 4) >> 3; dc = (12 * dc + 64) >> 7; - cm = ff_cropTbl + MAX_NEG_CROP + dc; for(i = 0; i < 8; i++){ - dest[0] = cm[dest[0]]; - dest[1] = cm[dest[1]]; - dest[2] = cm[dest[2]]; - dest[3] = cm[dest[3]]; + dest[0] = av_clip_uint8(dest[0] + dc); + dest[1] = av_clip_uint8(dest[1] + dc); + dest[2] = av_clip_uint8(dest[2] + dc); + dest[3] = av_clip_uint8(dest[3] + dc); dest += linesize; } } @@ -422,7 +413,6 @@ static void vc1_inv_trans_4x8_c(uint8_t *dest, int linesize, DCTELEM *block) int i; register int t1,t2,t3,t4,t5,t6,t7,t8; DCTELEM *src, *dst; - const uint8_t *cm = ff_cropTbl + MAX_NEG_CROP; src = block; dst = block; @@ -458,14 +448,14 @@ static void vc1_inv_trans_4x8_c(uint8_t *dest, int linesize, DCTELEM *block) t3 = 9 * src[ 8] - 16 * src[24] + 4 * src[40] + 15 * src[56]; t4 = 4 * src[ 8] - 9 * src[24] + 15 * src[40] - 16 * src[56]; - dest[0*linesize] = cm[dest[0*linesize] + ((t5 + t1) >> 7)]; - dest[1*linesize] = cm[dest[1*linesize] + ((t6 + t2) >> 7)]; - dest[2*linesize] = cm[dest[2*linesize] + ((t7 + t3) >> 7)]; - dest[3*linesize] = cm[dest[3*linesize] + ((t8 + t4) >> 7)]; - dest[4*linesize] = cm[dest[4*linesize] + ((t8 - t4 + 1) >> 7)]; - dest[5*linesize] = cm[dest[5*linesize] + ((t7 - t3 + 1) >> 7)]; - dest[6*linesize] = cm[dest[6*linesize] + ((t6 - t2 + 1) >> 7)]; - dest[7*linesize] = cm[dest[7*linesize] + ((t5 - t1 + 1) >> 7)]; + dest[0*linesize] = av_clip_uint8(dest[0*linesize] + ((t5 + t1) >> 7)); + dest[1*linesize] = av_clip_uint8(dest[1*linesize] + ((t6 + t2) >> 7)); + dest[2*linesize] = av_clip_uint8(dest[2*linesize] + ((t7 + t3) >> 7)); + dest[3*linesize] = av_clip_uint8(dest[3*linesize] + ((t8 + t4) >> 7)); + dest[4*linesize] = av_clip_uint8(dest[4*linesize] + ((t8 - t4 + 1) >> 7)); + dest[5*linesize] = av_clip_uint8(dest[5*linesize] + ((t7 - t3 + 1) >> 7)); + dest[6*linesize] = av_clip_uint8(dest[6*linesize] + ((t6 - t2 + 1) >> 7)); + dest[7*linesize] = av_clip_uint8(dest[7*linesize] + ((t5 - t1 + 1) >> 7)); src ++; dest++; @@ -478,15 +468,13 @@ static void vc1_inv_trans_4x4_dc_c(uint8_t *dest, int linesize, DCTELEM *block) { int i; int dc = block[0]; - const uint8_t *cm; dc = (17 * dc + 4) >> 3; dc = (17 * dc + 64) >> 7; - cm = ff_cropTbl + MAX_NEG_CROP + dc; for(i = 0; i < 4; i++){ - dest[0] = cm[dest[0]]; - dest[1] = cm[dest[1]]; - dest[2] = cm[dest[2]]; - dest[3] = cm[dest[3]]; + dest[0] = av_clip_uint8(dest[0] + dc); + dest[1] = av_clip_uint8(dest[1] + dc); + dest[2] = av_clip_uint8(dest[2] + dc); + dest[3] = av_clip_uint8(dest[3] + dc); dest += linesize; } } @@ -496,7 +484,6 @@ static void vc1_inv_trans_4x4_c(uint8_t *dest, int linesize, DCTELEM *block) int i; register int t1,t2,t3,t4; DCTELEM *src, *dst; - const uint8_t *cm = ff_cropTbl + MAX_NEG_CROP; src = block; dst = block; @@ -522,10 +509,10 @@ static void vc1_inv_trans_4x4_c(uint8_t *dest, int linesize, DCTELEM *block) t3 = 22 * src[ 8] + 10 * src[24]; t4 = 22 * src[24] - 10 * src[ 8]; - dest[0*linesize] = cm[dest[0*linesize] + ((t1 + t3) >> 7)]; - dest[1*linesize] = cm[dest[1*linesize] + ((t2 - t4) >> 7)]; - dest[2*linesize] = cm[dest[2*linesize] + ((t2 + t4) >> 7)]; - dest[3*linesize] = cm[dest[3*linesize] + ((t1 - t3) >> 7)]; + dest[0*linesize] = av_clip_uint8(dest[0*linesize] + ((t1 + t3) >> 7)); + dest[1*linesize] = av_clip_uint8(dest[1*linesize] + ((t2 - t4) >> 7)); + dest[2*linesize] = av_clip_uint8(dest[2*linesize] + ((t2 + t4) >> 7)); + dest[3*linesize] = av_clip_uint8(dest[3*linesize] + ((t1 - t3) >> 7)); src ++; dest++; diff --git a/libavcodec/vcr1.c b/libavcodec/vcr1.c index 1526215314..ad91199f2f 100644 --- a/libavcodec/vcr1.c +++ b/libavcodec/vcr1.c @@ -69,9 +69,13 @@ static int decode_frame(AVCodecContext *avctx, p->pict_type= AV_PICTURE_TYPE_I; p->key_frame= 1; + if (buf_size < 32) + goto packet_small; + for(i=0; i<16; i++){ a->delta[i]= *(bytestream++); bytestream++; + buf_size--; } for(y=0; yheight; y++){ @@ -82,8 +86,12 @@ static int decode_frame(AVCodecContext *avctx, uint8_t *cb= &a->picture.data[1][ (y>>2)*a->picture.linesize[1] ]; uint8_t *cr= &a->picture.data[2][ (y>>2)*a->picture.linesize[2] ]; + if (buf_size < 4 + avctx->width) + goto packet_small; + for(i=0; i<4; i++) a->offset[i]= *(bytestream++); + buf_size -= 4; offset= a->offset[0] - a->delta[ bytestream[2]&0xF ]; for(x=0; xwidth; x+=4){ @@ -97,8 +105,12 @@ static int decode_frame(AVCodecContext *avctx, *(cr++) = bytestream[1]; bytestream+= 4; + buf_size -= 4; } }else{ + if (buf_size < avctx->width / 2) + goto packet_small; + offset= a->offset[y&3] - a->delta[ bytestream[2]&0xF ]; for(x=0; xwidth; x+=8){ @@ -112,6 +124,7 @@ static int decode_frame(AVCodecContext *avctx, luma[7]=( offset += a->delta[ bytestream[1]>>4 ]); luma += 8; bytestream+= 4; + buf_size -= 4; } } } @@ -120,6 +133,9 @@ static int decode_frame(AVCodecContext *avctx, *data_size = sizeof(AVPicture); return buf_size; +packet_small: + av_log(avctx, AV_LOG_ERROR, "Input packet too small.\n"); + return AVERROR_INVALIDDATA; } #if CONFIG_VCR1_ENCODER @@ -157,6 +173,11 @@ static av_cold int decode_init(AVCodecContext *avctx){ avctx->pix_fmt= PIX_FMT_YUV410P; + if (avctx->width & 7) { + av_log(avctx, AV_LOG_ERROR, "Width %d is not divisble by 8.\n", avctx->width); + return AVERROR_INVALIDDATA; + } + return 0; } diff --git a/libavcodec/version.h b/libavcodec/version.h index d67ad2f5d2..0a5afef374 100644 --- a/libavcodec/version.h +++ b/libavcodec/version.h @@ -21,7 +21,7 @@ #define AVCODEC_VERSION_H #define LIBAVCODEC_VERSION_MAJOR 53 -#define LIBAVCODEC_VERSION_MINOR 60 +#define LIBAVCODEC_VERSION_MINOR 61 #define LIBAVCODEC_VERSION_MICRO 100 #define LIBAVCODEC_VERSION_INT AV_VERSION_INT(LIBAVCODEC_VERSION_MAJOR, \ diff --git a/libavcodec/vmdav.c b/libavcodec/vmdav.c index 7006f61f2b..2b491ad86a 100644 --- a/libavcodec/vmdav.c +++ b/libavcodec/vmdav.c @@ -45,6 +45,8 @@ #include "libavutil/intreadwrite.h" #include "avcodec.h" +#include "internal.h" +#include "bytestream.h" #define VMD_HEADER_SIZE 0x330 #define PALETTE_COUNT 256 @@ -75,8 +77,6 @@ typedef struct VmdVideoContext { static void lz_unpack(const unsigned char *src, int src_len, unsigned char *dest, int dest_len) { - const unsigned char *s; - const unsigned char *s_end; unsigned char *d; unsigned char *d_end; unsigned char queue[QUEUE_SIZE]; @@ -87,19 +87,17 @@ static void lz_unpack(const unsigned char *src, int src_len, unsigned int speclen; unsigned char tag; unsigned int i, j; + GetByteContext gb; - s = src; - s_end = src + src_len; + bytestream2_init(&gb, src, src_len); d = dest; d_end = d + dest_len; - - if (s_end - s < 8) - return; - dataleft = AV_RL32(s); - s += 4; + dataleft = bytestream2_get_le32(&gb); memset(queue, 0x20, QUEUE_SIZE); - if (AV_RL32(s) == 0x56781234) { - s += 4; + if (bytestream2_get_bytes_left(&gb) < 4) + return; + if (bytestream2_peek_le32(&gb) == 0x56781234) { + bytestream2_get_le32(&gb); qpos = 0x111; speclen = 0xF + 3; } else { @@ -107,13 +105,13 @@ static void lz_unpack(const unsigned char *src, int src_len, speclen = 100; /* no speclen */ } - while (s_end - s > 0 && dataleft > 0) { - tag = *s++; + while (dataleft > 0 && bytestream2_get_bytes_left(&gb) > 0) { + tag = bytestream2_get_byteu(&gb); if ((tag == 0xFF) && (dataleft > 8)) { - if (d_end - d < 8 || s_end - s < 8) + if (d_end - d < 8 || bytestream2_get_bytes_left(&gb) < 8) return; for (i = 0; i < 8; i++) { - queue[qpos++] = *d++ = *s++; + queue[qpos++] = *d++ = bytestream2_get_byteu(&gb); qpos &= QUEUE_MASK; } dataleft -= 8; @@ -122,21 +120,17 @@ static void lz_unpack(const unsigned char *src, int src_len, if (dataleft == 0) break; if (tag & 0x01) { - if (d_end - d < 1 || s_end - s < 1) + if (d_end - d < 1 || bytestream2_get_bytes_left(&gb) < 1) return; - queue[qpos++] = *d++ = *s++; + queue[qpos++] = *d++ = bytestream2_get_byte(&gb); qpos &= QUEUE_MASK; dataleft--; } else { - if (s_end - s < 2) - return; - chainofs = *s++; - chainofs |= ((*s & 0xF0) << 4); - chainlen = (*s++ & 0x0F) + 3; + chainofs = bytestream2_get_byte(&gb); + chainofs |= ((bytestream2_peek_byte(&gb) & 0xF0) << 4); + chainlen = (bytestream2_get_byte(&gb) & 0x0F) + 3; if (chainlen == speclen) { - if (s_end - s < 1) - return; - chainlen = *s++ + 0xF + 3; + chainlen = bytestream2_get_byte(&gb) + 0xF + 3; } if (d_end - d < chainlen) return; @@ -152,51 +146,47 @@ static void lz_unpack(const unsigned char *src, int src_len, } } } - -static int rle_unpack(const unsigned char *src, int src_len, int src_count, - unsigned char *dest, int dest_len) +static int rle_unpack(const unsigned char *src, unsigned char *dest, + int src_count, int src_size, int dest_len) { - const unsigned char *ps; - const unsigned char *ps_end; unsigned char *pd; int i, l; unsigned char *dest_end = dest + dest_len; + GetByteContext gb; - ps = src; - ps_end = src + src_len; + bytestream2_init(&gb, src, src_size); pd = dest; if (src_count & 1) { - if (ps_end - ps < 1) + if (bytestream2_get_bytes_left(&gb) < 1) return 0; - *pd++ = *ps++; + *pd++ = bytestream2_get_byteu(&gb); } src_count >>= 1; i = 0; do { - if (ps_end - ps < 1) + if (bytestream2_get_bytes_left(&gb) < 1) break; - l = *ps++; + l = bytestream2_get_byteu(&gb); if (l & 0x80) { l = (l & 0x7F) * 2; - if (dest_end - pd < l || ps_end - ps < l) - return ps - src; - memcpy(pd, ps, l); - ps += l; + if (dest_end - pd < l || bytestream2_get_bytes_left(&gb) < l) + return bytestream2_tell(&gb); + bytestream2_get_buffer(&gb, pd, l); pd += l; } else { - if (dest_end - pd < i || ps_end - ps < 2) - return ps - src; + if (dest_end - pd < i || bytestream2_get_bytes_left(&gb) < 2) + return bytestream2_tell(&gb); for (i = 0; i < l; i++) { - *pd++ = ps[0]; - *pd++ = ps[1]; + *pd++ = bytestream2_get_byteu(&gb); + *pd++ = bytestream2_get_byteu(&gb); } - ps += 2; + bytestream2_skip(&gb, 2); } i += l; } while (i < src_count); - return ps - src; + return bytestream2_tell(&gb); } static void vmd_decode(VmdVideoContext *s) @@ -205,12 +195,8 @@ static void vmd_decode(VmdVideoContext *s) unsigned int *palette32; unsigned char r, g, b; - /* point to the start of the encoded data */ - const unsigned char *p = s->buf + 16; - const unsigned char *p_end = s->buf + s->size; + GetByteContext gb; - const unsigned char *pb; - const unsigned char *pb_end; unsigned char meth; unsigned char *dp; /* pointer to current frame */ unsigned char *pp; /* pointer to previous frame */ @@ -255,29 +241,31 @@ static void vmd_decode(VmdVideoContext *s) } /* check if there is a new palette */ + bytestream2_init(&gb, s->buf + 16, s->size - 16); if (s->buf[15] & 0x02) { - if (p_end - p < 2 + 3 * PALETTE_COUNT) - return; - p += 2; + bytestream2_skip(&gb, 2); palette32 = (unsigned int *)s->palette; - for (i = 0; i < PALETTE_COUNT; i++) { - r = *p++ * 4; - g = *p++ * 4; - b = *p++ * 4; - palette32[i] = 0xFF << 24 | r << 16 | g << 8 | b; - palette32[i] |= palette32[i] >> 6 & 0x30303; + if (bytestream2_get_bytes_left(&gb) >= PALETTE_COUNT * 3) { + for (i = 0; i < PALETTE_COUNT; i++) { + r = bytestream2_get_byteu(&gb) * 4; + g = bytestream2_get_byteu(&gb) * 4; + b = bytestream2_get_byteu(&gb) * 4; + palette32[i] = 0xFFU << 24 | (r << 16) | (g << 8) | (b); + palette32[i] |= palette32[i] >> 6 & 0x30303; + } } } - if (p < p_end) { + if (s->size > 0) { /* originally UnpackFrame in VAG's code */ - pb = p; - pb_end = p_end; - meth = *pb++; + bytestream2_init(&gb, gb.buffer, s->buf + s->size - gb.buffer); + if (bytestream2_get_bytes_left(&gb) < 1) + return; + meth = bytestream2_get_byteu(&gb); if (meth & 0x80) { - lz_unpack(pb, p_end - pb, s->unpack_buffer, s->unpack_buffer_size); + lz_unpack(gb.buffer, bytestream2_get_bytes_left(&gb), + s->unpack_buffer, s->unpack_buffer_size); meth &= 0x7F; - pb = s->unpack_buffer; - pb_end = s->unpack_buffer + s->unpack_buffer_size; + bytestream2_init(&gb, s->unpack_buffer, s->unpack_buffer_size); } dp = &s->frame.data[0][frame_y * s->frame.linesize[0] + frame_x]; @@ -287,15 +275,12 @@ static void vmd_decode(VmdVideoContext *s) for (i = 0; i < frame_height; i++) { ofs = 0; do { - if (pb_end - pb < 1) - return; - len = *pb++; + len = bytestream2_get_byte(&gb); if (len & 0x80) { len = (len & 0x7F) + 1; - if (ofs + len > frame_width || pb_end - pb < len) + if (ofs + len > frame_width || bytestream2_get_bytes_left(&gb) < len) return; - memcpy(&dp[ofs], pb, len); - pb += len; + bytestream2_get_buffer(&gb, &dp[ofs], len); ofs += len; } else { /* interframe pixel copy */ @@ -317,10 +302,7 @@ static void vmd_decode(VmdVideoContext *s) case 2: for (i = 0; i < frame_height; i++) { - if (pb_end -pb < frame_width) - return; - memcpy(dp, pb, frame_width); - pb += frame_width; + bytestream2_get_buffer(&gb, dp, frame_width); dp += s->frame.linesize[0]; pp += s->prev_frame.linesize[0]; } @@ -330,22 +312,20 @@ static void vmd_decode(VmdVideoContext *s) for (i = 0; i < frame_height; i++) { ofs = 0; do { - if (pb_end - pb < 1) - return; - len = *pb++; + len = bytestream2_get_byte(&gb); if (len & 0x80) { len = (len & 0x7F) + 1; - if (pb_end - pb < 1) - return; - if (*pb++ == 0xFF) - len = rle_unpack(pb, pb_end - pb, len, &dp[ofs], frame_width - ofs); + if (bytestream2_get_byte(&gb) == 0xFF) + len = rle_unpack(gb.buffer, &dp[ofs], + len, bytestream2_get_bytes_left(&gb), + frame_width - ofs); else { - if (pb_end - pb < len) - return; - memcpy(&dp[ofs], pb, len); + if (ofs + len > frame_width || + bytestream2_get_bytes_left(&gb) < len) + return; + bytestream2_get_buffer(&gb, &dp[ofs], len); } - pb += len; - ofs += len; + bytestream2_skip(&gb, len); } else { /* interframe pixel copy */ if (ofs + len + 1 > frame_width || !s->prev_frame.data[0]) @@ -423,7 +403,7 @@ static int vmdvideo_decode_frame(AVCodecContext *avctx, return buf_size; s->frame.reference = 3; - if (avctx->get_buffer(avctx, &s->frame)) { + if (ff_get_buffer(avctx, &s->frame)) { av_log(s->avctx, AV_LOG_ERROR, "VMD Video: get_buffer() failed\n"); return -1; } @@ -596,7 +576,7 @@ static int vmdaudio_decode_frame(AVCodecContext *avctx, void *data, /* get output buffer */ s->frame.nb_samples = ((silent_chunks + audio_chunks) * avctx->block_align) / avctx->channels; - if ((ret = avctx->get_buffer(avctx, &s->frame)) < 0) { + if ((ret = ff_get_buffer(avctx, &s->frame)) < 0) { av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n"); return ret; } diff --git a/libavcodec/vmnc.c b/libavcodec/vmnc.c index 7655103b6a..1a02a75e69 100644 --- a/libavcodec/vmnc.c +++ b/libavcodec/vmnc.c @@ -275,6 +275,11 @@ static int decode_hextile(VmncContext *c, uint8_t* dst, const uint8_t* src, int } xy = *src++; wh = *src++; + if ( (xy >> 4) + (wh >> 4) + 1 > w - i + || (xy & 0xF) + (wh & 0xF)+1 > h - j) { + av_log(c->avctx, AV_LOG_ERROR, "Rectangle outside picture\n"); + return AVERROR_INVALIDDATA; + } paint_rect(dst2, xy >> 4, xy & 0xF, (wh>>4)+1, (wh & 0xF)+1, fg, bpp, stride); } } @@ -484,6 +489,7 @@ static av_cold int decode_init(AVCodecContext *avctx) break; default: av_log(avctx, AV_LOG_ERROR, "Unsupported bitdepth %i\n", c->bpp); + return AVERROR_INVALIDDATA; } return 0; diff --git a/libavcodec/vorbis.c b/libavcodec/vorbis.c index 28176f3b12..90227dd9f9 100644 --- a/libavcodec/vorbis.c +++ b/libavcodec/vorbis.c @@ -123,7 +123,8 @@ int ff_vorbis_len2vlc(uint8_t *bits, uint32_t *codes, unsigned num) return 0; } -void ff_vorbis_ready_floor1_list(vorbis_floor1_entry * list, int values) +int ff_vorbis_ready_floor1_list(AVCodecContext *avccontext, + vorbis_floor1_entry *list, int values) { int i; list[0].sort = 0; @@ -147,6 +148,11 @@ void ff_vorbis_ready_floor1_list(vorbis_floor1_entry * list, int values) for (i = 0; i < values - 1; i++) { int j; for (j = i + 1; j < values; j++) { + if (list[i].x == list[j].x) { + av_log(avccontext, AV_LOG_ERROR, + "Duplicate value found in floor 1 X coordinates\n"); + return AVERROR_INVALIDDATA; + } if (list[list[i].sort].x > list[list[j].sort].x) { int tmp = list[i].sort; list[i].sort = list[j].sort; @@ -154,9 +160,10 @@ void ff_vorbis_ready_floor1_list(vorbis_floor1_entry * list, int values) } } } + return 0; } -static inline void render_line_unrolled(intptr_t x, uint8_t y, int x1, +static inline void render_line_unrolled(intptr_t x, int y, int x1, intptr_t sy, int ady, int adx, float *buf) { @@ -168,30 +175,30 @@ static inline void render_line_unrolled(intptr_t x, uint8_t y, int x1, if (err >= 0) { err += ady - adx; y += sy; - buf[x++] = ff_vorbis_floor1_inverse_db_table[y]; + buf[x++] = ff_vorbis_floor1_inverse_db_table[av_clip_uint8(y)]; } - buf[x] = ff_vorbis_floor1_inverse_db_table[y]; + buf[x] = ff_vorbis_floor1_inverse_db_table[av_clip_uint8(y)]; } if (x <= 0) { if (err + ady >= 0) y += sy; - buf[x] = ff_vorbis_floor1_inverse_db_table[y]; + buf[x] = ff_vorbis_floor1_inverse_db_table[av_clip_uint8(y)]; } } -static void render_line(int x0, uint8_t y0, int x1, int y1, float *buf) +static void render_line(int x0, int y0, int x1, int y1, float *buf) { int dy = y1 - y0; int adx = x1 - x0; int ady = FFABS(dy); int sy = dy < 0 ? -1 : 1; - buf[x0] = ff_vorbis_floor1_inverse_db_table[y0]; + buf[x0] = ff_vorbis_floor1_inverse_db_table[av_clip_uint8(y0)]; if (ady*2 <= adx) { // optimized common case render_line_unrolled(x0, y0, x1, sy, ady, adx, buf); } else { int base = dy / adx; int x = x0; - uint8_t y = y0; + int y = y0; int err = -adx; ady -= FFABS(base) * adx; while (++x < x1) { @@ -201,7 +208,7 @@ static void render_line(int x0, uint8_t y0, int x1, int y1, float *buf) err -= adx; y += sy; } - buf[x] = ff_vorbis_floor1_inverse_db_table[y]; + buf[x] = ff_vorbis_floor1_inverse_db_table[av_clip_uint8(y)]; } } } @@ -210,8 +217,7 @@ void ff_vorbis_floor1_render_list(vorbis_floor1_entry * list, int values, uint16_t *y_list, int *flag, int multiplier, float *out, int samples) { - int lx, i; - uint8_t ly; + int lx, ly, i; lx = 0; ly = y_list[0] * multiplier; for (i = 1; i < values; i++) { diff --git a/libavcodec/vorbis.h b/libavcodec/vorbis.h index cad080ef3a..7a38d9721d 100644 --- a/libavcodec/vorbis.h +++ b/libavcodec/vorbis.h @@ -36,7 +36,8 @@ typedef struct { uint16_t high; } vorbis_floor1_entry; -void ff_vorbis_ready_floor1_list(vorbis_floor1_entry * list, int values); +int ff_vorbis_ready_floor1_list(AVCodecContext *avccontext, + vorbis_floor1_entry *list, int values); unsigned int ff_vorbis_nth_root(unsigned int x, unsigned int n); // x^(1/n) int ff_vorbis_len2vlc(uint8_t *bits, uint32_t *codes, unsigned num); void ff_vorbis_floor1_render_list(vorbis_floor1_entry * list, int values, diff --git a/libavcodec/vorbisdec.c b/libavcodec/vorbisdec.c index 03e3d757cb..12c8cfac77 100644 --- a/libavcodec/vorbisdec.c +++ b/libavcodec/vorbisdec.c @@ -31,6 +31,7 @@ #define BITSTREAM_READER_LE #include "avcodec.h" +#include "internal.h" #include "get_bits.h" #include "dsputil.h" #include "fft.h" @@ -207,7 +208,7 @@ static void vorbis_free(vorbis_context *vc) for (i = 0; i < vc->codebook_count; ++i) { av_free(vc->codebooks[i].codevectors); - free_vlc(&vc->codebooks[i].vlc); + ff_free_vlc(&vc->codebooks[i].vlc); } av_freep(&vc->codebooks); @@ -578,7 +579,11 @@ static int vorbis_parse_setup_hdr_floors(vorbis_context *vc) } // Precalculate order of x coordinates - needed for decode - ff_vorbis_ready_floor1_list(floor_setup->data.t1.list, floor_setup->data.t1.x_list_dim); + if (ff_vorbis_ready_floor1_list(vc->avccontext, + floor_setup->data.t1.list, + floor_setup->data.t1.x_list_dim)) { + return AVERROR_INVALIDDATA; + } for (j=1; jdata.t1.x_list_dim; j++) { if ( floor_setup->data.t1.list[ floor_setup->data.t1.list[j-1].sort ].x @@ -595,6 +600,11 @@ static int vorbis_parse_setup_hdr_floors(vorbis_context *vc) floor_setup->data.t0.order = get_bits(gb, 8); floor_setup->data.t0.rate = get_bits(gb, 16); floor_setup->data.t0.bark_map_size = get_bits(gb, 16); + if (floor_setup->data.t0.bark_map_size == 0) { + av_log(vc->avccontext, AV_LOG_ERROR, + "Floor 0 bark map size is 0.\n"); + return AVERROR_INVALIDDATA; + } floor_setup->data.t0.amplitude_bits = get_bits(gb, 6); /* zero would result in a div by zero later * * 2^0 - 1 == 0 */ @@ -1256,20 +1266,20 @@ static int vorbis_floor1_decode(vorbis_context *vc, floor1_flag[i] = 1; if (val >= room) { if (highroom > lowroom) { - floor1_Y_final[i] = val - lowroom + predicted; + floor1_Y_final[i] = av_clip_uint16(val - lowroom + predicted); } else { - floor1_Y_final[i] = predicted - val + highroom - 1; + floor1_Y_final[i] = av_clip_uint16(predicted - val + highroom - 1); } } else { if (val & 1) { - floor1_Y_final[i] = predicted - (val + 1) / 2; + floor1_Y_final[i] = av_clip_uint16(predicted - (val + 1) / 2); } else { - floor1_Y_final[i] = predicted + val / 2; + floor1_Y_final[i] = av_clip_uint16(predicted + val / 2); } } } else { floor1_flag[i] = 0; - floor1_Y_final[i] = predicted; + floor1_Y_final[i] = av_clip_uint16(predicted); } av_dlog(NULL, " Decoded floor(%d) = %u / val %u\n", @@ -1671,7 +1681,7 @@ static int vorbis_decode_frame(AVCodecContext *avccontext, void *data, /* get output buffer */ vc->frame.nb_samples = len; - if ((ret = avccontext->get_buffer(avccontext, &vc->frame)) < 0) { + if ((ret = ff_get_buffer(avccontext, &vc->frame)) < 0) { av_log(avccontext, AV_LOG_ERROR, "get_buffer() failed\n"); return ret; } diff --git a/libavcodec/vorbisenc.c b/libavcodec/vorbisenc.c index 80d722db4c..cdce0ab16a 100644 --- a/libavcodec/vorbisenc.c +++ b/libavcodec/vorbisenc.c @@ -155,7 +155,7 @@ static int cb_lookup_vals(int lookup, int dimentions, int entries) return 0; } -static void ready_codebook(vorbis_enc_codebook *cb) +static int ready_codebook(vorbis_enc_codebook *cb) { int i; @@ -167,6 +167,8 @@ static void ready_codebook(vorbis_enc_codebook *cb) int vals = cb_lookup_vals(cb->lookup, cb->ndimentions, cb->nentries); cb->dimentions = av_malloc(sizeof(float) * cb->nentries * cb->ndimentions); cb->pow2 = av_mallocz(sizeof(float) * cb->nentries); + if (!cb->dimentions || !cb->pow2) + return AVERROR(ENOMEM); for (i = 0; i < cb->nentries; i++) { float last = 0; int j; @@ -187,13 +189,16 @@ static void ready_codebook(vorbis_enc_codebook *cb) cb->pow2[i] /= 2.; } } + return 0; } -static void ready_residue(vorbis_enc_residue *rc, vorbis_enc_context *venc) +static int ready_residue(vorbis_enc_residue *rc, vorbis_enc_context *venc) { int i; assert(rc->type == 2); rc->maxes = av_mallocz(sizeof(float[2]) * rc->classifications); + if (!rc->maxes) + return AVERROR(ENOMEM); for (i = 0; i < rc->classifications; i++) { int j; vorbis_enc_codebook * cb; @@ -223,15 +228,16 @@ static void ready_residue(vorbis_enc_residue *rc, vorbis_enc_context *venc) rc->maxes[i][0] += 0.8; rc->maxes[i][1] += 0.8; } + return 0; } -static void create_vorbis_context(vorbis_enc_context *venc, - AVCodecContext *avccontext) +static int create_vorbis_context(vorbis_enc_context *venc, + AVCodecContext *avccontext) { vorbis_enc_floor *fc; vorbis_enc_residue *rc; vorbis_enc_mapping *mc; - int i, book; + int i, book, ret; venc->channels = avccontext->channels; venc->sample_rate = avccontext->sample_rate; @@ -239,6 +245,8 @@ static void create_vorbis_context(vorbis_enc_context *venc, venc->ncodebooks = FF_ARRAY_ELEMS(cvectors); venc->codebooks = av_malloc(sizeof(vorbis_enc_codebook) * venc->ncodebooks); + if (!venc->codebooks) + return AVERROR(ENOMEM); // codebook 0..14 - floor1 book, values 0..255 // codebook 15 residue masterbook @@ -255,27 +263,36 @@ static void create_vorbis_context(vorbis_enc_context *venc, cb->lens = av_malloc(sizeof(uint8_t) * cb->nentries); cb->codewords = av_malloc(sizeof(uint32_t) * cb->nentries); + if (!cb->lens || !cb->codewords) + return AVERROR(ENOMEM); memcpy(cb->lens, cvectors[book].clens, cvectors[book].len); memset(cb->lens + cvectors[book].len, 0, cb->nentries - cvectors[book].len); if (cb->lookup) { vals = cb_lookup_vals(cb->lookup, cb->ndimentions, cb->nentries); cb->quantlist = av_malloc(sizeof(int) * vals); + if (!cb->quantlist) + return AVERROR(ENOMEM); for (i = 0; i < vals; i++) cb->quantlist[i] = cvectors[book].quant[i]; } else { cb->quantlist = NULL; } - ready_codebook(cb); + if ((ret = ready_codebook(cb)) < 0) + return ret; } venc->nfloors = 1; venc->floors = av_malloc(sizeof(vorbis_enc_floor) * venc->nfloors); + if (!venc->floors) + return AVERROR(ENOMEM); // just 1 floor fc = &venc->floors[0]; fc->partitions = NUM_FLOOR_PARTITIONS; fc->partition_to_class = av_malloc(sizeof(int) * fc->partitions); + if (!fc->partition_to_class) + return AVERROR(ENOMEM); fc->nclasses = 0; for (i = 0; i < fc->partitions; i++) { static const int a[] = {0, 1, 2, 2, 3, 3, 4, 4}; @@ -284,6 +301,8 @@ static void create_vorbis_context(vorbis_enc_context *venc, } fc->nclasses++; fc->classes = av_malloc(sizeof(vorbis_enc_floor_class) * fc->nclasses); + if (!fc->classes) + return AVERROR(ENOMEM); for (i = 0; i < fc->nclasses; i++) { vorbis_enc_floor_class * c = &fc->classes[i]; int j, books; @@ -292,6 +311,8 @@ static void create_vorbis_context(vorbis_enc_context *venc, c->masterbook = floor_classes[i].masterbook; books = (1 << c->subclass); c->books = av_malloc(sizeof(int) * books); + if (!c->books) + return AVERROR(ENOMEM); for (j = 0; j < books; j++) c->books[j] = floor_classes[i].nbooks[j]; } @@ -303,6 +324,8 @@ static void create_vorbis_context(vorbis_enc_context *venc, fc->values += fc->classes[fc->partition_to_class[i]].dim; fc->list = av_malloc(sizeof(vorbis_floor1_entry) * fc->values); + if (!fc->list) + return AVERROR(ENOMEM); fc->list[0].x = 0; fc->list[1].x = 1 << fc->rangebits; for (i = 2; i < fc->values; i++) { @@ -313,10 +336,13 @@ static void create_vorbis_context(vorbis_enc_context *venc, }; fc->list[i].x = a[i - 2]; } - ff_vorbis_ready_floor1_list(fc->list, fc->values); + if (ff_vorbis_ready_floor1_list(avccontext, fc->list, fc->values)) + return AVERROR_BUG; venc->nresidues = 1; venc->residues = av_malloc(sizeof(vorbis_enc_residue) * venc->nresidues); + if (!venc->residues) + return AVERROR(ENOMEM); // single residue rc = &venc->residues[0]; @@ -327,6 +353,8 @@ static void create_vorbis_context(vorbis_enc_context *venc, rc->classifications = 10; rc->classbook = 15; rc->books = av_malloc(sizeof(*rc->books) * rc->classifications); + if (!rc->books) + return AVERROR(ENOMEM); { static const int8_t a[10][8] = { { -1, -1, -1, -1, -1, -1, -1, -1, }, @@ -342,19 +370,26 @@ static void create_vorbis_context(vorbis_enc_context *venc, }; memcpy(rc->books, a, sizeof a); } - ready_residue(rc, venc); + if ((ret = ready_residue(rc, venc)) < 0) + return ret; venc->nmappings = 1; venc->mappings = av_malloc(sizeof(vorbis_enc_mapping) * venc->nmappings); + if (!venc->mappings) + return AVERROR(ENOMEM); // single mapping mc = &venc->mappings[0]; mc->submaps = 1; mc->mux = av_malloc(sizeof(int) * venc->channels); + if (!mc->mux) + return AVERROR(ENOMEM); for (i = 0; i < venc->channels; i++) mc->mux[i] = 0; mc->floor = av_malloc(sizeof(int) * mc->submaps); mc->residue = av_malloc(sizeof(int) * mc->submaps); + if (!mc->floor || !mc->residue) + return AVERROR(ENOMEM); for (i = 0; i < mc->submaps; i++) { mc->floor[i] = 0; mc->residue[i] = 0; @@ -362,6 +397,8 @@ static void create_vorbis_context(vorbis_enc_context *venc, mc->coupling_steps = venc->channels == 2 ? 1 : 0; mc->magnitude = av_malloc(sizeof(int) * mc->coupling_steps); mc->angle = av_malloc(sizeof(int) * mc->coupling_steps); + if (!mc->magnitude || !mc->angle) + return AVERROR(ENOMEM); if (mc->coupling_steps) { mc->magnitude[0] = 0; mc->angle[0] = 1; @@ -369,6 +406,8 @@ static void create_vorbis_context(vorbis_enc_context *venc, venc->nmodes = 1; venc->modes = av_malloc(sizeof(vorbis_enc_mode) * venc->nmodes); + if (!venc->modes) + return AVERROR(ENOMEM); // single mode venc->modes[0].blockflag = 0; @@ -379,12 +418,18 @@ static void create_vorbis_context(vorbis_enc_context *venc, venc->samples = av_malloc(sizeof(float) * venc->channels * (1 << venc->log2_blocksize[1])); venc->floor = av_malloc(sizeof(float) * venc->channels * (1 << venc->log2_blocksize[1]) / 2); venc->coeffs = av_malloc(sizeof(float) * venc->channels * (1 << venc->log2_blocksize[1]) / 2); + if (!venc->saved || !venc->samples || !venc->floor || !venc->coeffs) + return AVERROR(ENOMEM); venc->win[0] = ff_vorbis_vwin[venc->log2_blocksize[0] - 6]; venc->win[1] = ff_vorbis_vwin[venc->log2_blocksize[1] - 6]; - ff_mdct_init(&venc->mdct[0], venc->log2_blocksize[0], 0, 1.0); - ff_mdct_init(&venc->mdct[1], venc->log2_blocksize[1], 0, 1.0); + if ((ret = ff_mdct_init(&venc->mdct[0], venc->log2_blocksize[0], 0, 1.0)) < 0) + return ret; + if ((ret = ff_mdct_init(&venc->mdct[1], venc->log2_blocksize[1], 0, 1.0)) < 0) + return ret; + + return 0; } static void put_float(PutBitContext *pb, float f) @@ -647,6 +692,8 @@ static int put_main_header(vorbis_enc_context *venc, uint8_t **out) len = hlens[0] + hlens[1] + hlens[2]; p = *out = av_mallocz(64 + len + len/255); + if (!p) + return AVERROR(ENOMEM); *p++ = 2; p += av_xiphlacing(p, hlens[0]); @@ -952,33 +999,6 @@ static int apply_window_and_mdct(vorbis_enc_context *venc, const signed short *a return 1; } -static av_cold int vorbis_encode_init(AVCodecContext *avccontext) -{ - vorbis_enc_context *venc = avccontext->priv_data; - - if (avccontext->channels != 2) { - av_log(avccontext, AV_LOG_ERROR, "Current FFmpeg Vorbis encoder only supports 2 channels.\n"); - return -1; - } - - create_vorbis_context(venc, avccontext); - - if (avccontext->flags & CODEC_FLAG_QSCALE) - venc->quality = avccontext->global_quality / (float)FF_QP2LAMBDA / 10.; - else - venc->quality = 0.03; - venc->quality *= venc->quality; - - avccontext->extradata_size = put_main_header(venc, (uint8_t**)&avccontext->extradata); - - avccontext->frame_size = 1 << (venc->log2_blocksize[0] - 1); - - avccontext->coded_frame = avcodec_alloc_frame(); - avccontext->coded_frame->key_frame = 1; - - return 0; -} - static int vorbis_encode_frame(AVCodecContext *avccontext, unsigned char *packets, int buf_size, void *data) @@ -1102,6 +1122,43 @@ static av_cold int vorbis_encode_close(AVCodecContext *avccontext) return 0 ; } +static av_cold int vorbis_encode_init(AVCodecContext *avccontext) +{ + vorbis_enc_context *venc = avccontext->priv_data; + int ret; + + if (avccontext->channels != 2) { + av_log(avccontext, AV_LOG_ERROR, "Current FFmpeg Vorbis encoder only supports 2 channels.\n"); + return -1; + } + + if ((ret = create_vorbis_context(venc, avccontext)) < 0) + goto error; + + if (avccontext->flags & CODEC_FLAG_QSCALE) + venc->quality = avccontext->global_quality / (float)FF_QP2LAMBDA / 10.; + else + venc->quality = 0.03; + venc->quality *= venc->quality; + + if ((ret = put_main_header(venc, (uint8_t**)&avccontext->extradata)) < 0) + goto error; + avccontext->extradata_size = ret; + + avccontext->frame_size = 1 << (venc->log2_blocksize[0] - 1); + + avccontext->coded_frame = avcodec_alloc_frame(); + if (!avccontext->coded_frame) { + ret = AVERROR(ENOMEM); + goto error; + } + + return 0; +error: + vorbis_encode_close(avccontext); + return ret; +} + AVCodec ff_vorbis_encoder = { .name = "vorbis", .type = AVMEDIA_TYPE_AUDIO, diff --git a/libavcodec/vp3.c b/libavcodec/vp3.c index b5daafcefb..10c5b8c36f 100644 --- a/libavcodec/vp3.c +++ b/libavcodec/vp3.c @@ -292,17 +292,17 @@ static av_cold int vp3_decode_end(AVCodecContext *avctx) return 0; for (i = 0; i < 16; i++) { - free_vlc(&s->dc_vlc[i]); - free_vlc(&s->ac_vlc_1[i]); - free_vlc(&s->ac_vlc_2[i]); - free_vlc(&s->ac_vlc_3[i]); - free_vlc(&s->ac_vlc_4[i]); + ff_free_vlc(&s->dc_vlc[i]); + ff_free_vlc(&s->ac_vlc_1[i]); + ff_free_vlc(&s->ac_vlc_2[i]); + ff_free_vlc(&s->ac_vlc_3[i]); + ff_free_vlc(&s->ac_vlc_4[i]); } - free_vlc(&s->superblock_run_length_vlc); - free_vlc(&s->fragment_run_length_vlc); - free_vlc(&s->mode_code_vlc); - free_vlc(&s->motion_vector_vlc); + ff_free_vlc(&s->superblock_run_length_vlc); + ff_free_vlc(&s->fragment_run_length_vlc); + ff_free_vlc(&s->mode_code_vlc); + ff_free_vlc(&s->motion_vector_vlc); /* release all frames */ vp3_decode_flush(avctx); @@ -2150,6 +2150,10 @@ static int theora_decode_header(AVCodecContext *avctx, GetBitContext *gb) fps.num = get_bits_long(gb, 32); fps.den = get_bits_long(gb, 32); if (fps.num && fps.den) { + if (fps.num < 0 || fps.den < 0) { + av_log(avctx, AV_LOG_ERROR, "Invalid framerate\n"); + return AVERROR_INVALIDDATA; + } av_reduce(&avctx->time_base.num, &avctx->time_base.den, fps.den, fps.num, 1<<30); } diff --git a/libavcodec/vp3dsp.c b/libavcodec/vp3dsp.c index 94efa3b1d2..9fded0f53e 100644 --- a/libavcodec/vp3dsp.c +++ b/libavcodec/vp3dsp.c @@ -41,7 +41,6 @@ static av_always_inline void idct(uint8_t *dst, int stride, int16_t *input, int type) { int16_t *ip = input; - uint8_t *cm = ff_cropTbl + MAX_NEG_CROP; int A, B, C, D, Ad, Bd, Cd, Dd, E, F, G, H; int Ed, Gd, Add, Bdd, Fd, Hd; @@ -147,29 +146,29 @@ static av_always_inline void idct(uint8_t *dst, int stride, int16_t *input, int ip[5*8] = (Fd + Bdd ) >> 4; ip[6*8] = (Fd - Bdd ) >> 4; }else if(type==1){ - dst[0*stride] = cm[(Gd + Cd ) >> 4]; - dst[7*stride] = cm[(Gd - Cd ) >> 4]; + dst[0*stride] = av_clip_uint8((Gd + Cd ) >> 4); + dst[7*stride] = av_clip_uint8((Gd - Cd ) >> 4); - dst[1*stride] = cm[(Add + Hd ) >> 4]; - dst[2*stride] = cm[(Add - Hd ) >> 4]; + dst[1*stride] = av_clip_uint8((Add + Hd ) >> 4); + dst[2*stride] = av_clip_uint8((Add - Hd ) >> 4); - dst[3*stride] = cm[(Ed + Dd ) >> 4]; - dst[4*stride] = cm[(Ed - Dd ) >> 4]; + dst[3*stride] = av_clip_uint8((Ed + Dd ) >> 4); + dst[4*stride] = av_clip_uint8((Ed - Dd ) >> 4); - dst[5*stride] = cm[(Fd + Bdd ) >> 4]; - dst[6*stride] = cm[(Fd - Bdd ) >> 4]; + dst[5*stride] = av_clip_uint8((Fd + Bdd ) >> 4); + dst[6*stride] = av_clip_uint8((Fd - Bdd ) >> 4); }else{ - dst[0*stride] = cm[dst[0*stride] + ((Gd + Cd ) >> 4)]; - dst[7*stride] = cm[dst[7*stride] + ((Gd - Cd ) >> 4)]; + dst[0*stride] = av_clip_uint8(dst[0*stride] + ((Gd + Cd ) >> 4)); + dst[7*stride] = av_clip_uint8(dst[7*stride] + ((Gd - Cd ) >> 4)); - dst[1*stride] = cm[dst[1*stride] + ((Add + Hd ) >> 4)]; - dst[2*stride] = cm[dst[2*stride] + ((Add - Hd ) >> 4)]; + dst[1*stride] = av_clip_uint8(dst[1*stride] + ((Add + Hd ) >> 4)); + dst[2*stride] = av_clip_uint8(dst[2*stride] + ((Add - Hd ) >> 4)); - dst[3*stride] = cm[dst[3*stride] + ((Ed + Dd ) >> 4)]; - dst[4*stride] = cm[dst[4*stride] + ((Ed - Dd ) >> 4)]; + dst[3*stride] = av_clip_uint8(dst[3*stride] + ((Ed + Dd ) >> 4)); + dst[4*stride] = av_clip_uint8(dst[4*stride] + ((Ed - Dd ) >> 4)); - dst[5*stride] = cm[dst[5*stride] + ((Fd + Bdd ) >> 4)]; - dst[6*stride] = cm[dst[6*stride] + ((Fd - Bdd ) >> 4)]; + dst[5*stride] = av_clip_uint8(dst[5*stride] + ((Fd + Bdd ) >> 4)); + dst[6*stride] = av_clip_uint8(dst[6*stride] + ((Fd - Bdd ) >> 4)); } } else { @@ -190,18 +189,18 @@ static av_always_inline void idct(uint8_t *dst, int stride, int16_t *input, int dst[4*stride]= dst[5*stride]= dst[6*stride]= - dst[7*stride]= cm[128 + ((xC4S4 * ip[0*8] + (IdctAdjustBeforeShift<<16))>>20)]; + dst[7*stride]= av_clip_uint8(128 + ((xC4S4 * ip[0*8] + (IdctAdjustBeforeShift<<16))>>20)); }else{ if(ip[0*8]){ int v= ((xC4S4 * ip[0*8] + (IdctAdjustBeforeShift<<16))>>20); - dst[0*stride] = cm[dst[0*stride] + v]; - dst[1*stride] = cm[dst[1*stride] + v]; - dst[2*stride] = cm[dst[2*stride] + v]; - dst[3*stride] = cm[dst[3*stride] + v]; - dst[4*stride] = cm[dst[4*stride] + v]; - dst[5*stride] = cm[dst[5*stride] + v]; - dst[6*stride] = cm[dst[6*stride] + v]; - dst[7*stride] = cm[dst[7*stride] + v]; + dst[0*stride] = av_clip_uint8(dst[0*stride] + v); + dst[1*stride] = av_clip_uint8(dst[1*stride] + v); + dst[2*stride] = av_clip_uint8(dst[2*stride] + v); + dst[3*stride] = av_clip_uint8(dst[3*stride] + v); + dst[4*stride] = av_clip_uint8(dst[4*stride] + v); + dst[5*stride] = av_clip_uint8(dst[5*stride] + v); + dst[6*stride] = av_clip_uint8(dst[6*stride] + v); + dst[7*stride] = av_clip_uint8(dst[7*stride] + v); } } } @@ -225,17 +224,16 @@ void ff_vp3_idct_add_c(uint8_t *dest/*align 8*/, int line_size, DCTELEM *block/* void ff_vp3_idct_dc_add_c(uint8_t *dest/*align 8*/, int line_size, const DCTELEM *block/*align 16*/){ int i, dc = (block[0] + 15) >> 5; - const uint8_t *cm = ff_cropTbl + MAX_NEG_CROP + dc; for(i = 0; i < 8; i++){ - dest[0] = cm[dest[0]]; - dest[1] = cm[dest[1]]; - dest[2] = cm[dest[2]]; - dest[3] = cm[dest[3]]; - dest[4] = cm[dest[4]]; - dest[5] = cm[dest[5]]; - dest[6] = cm[dest[6]]; - dest[7] = cm[dest[7]]; + dest[0] = av_clip_uint8(dest[0] + dc); + dest[1] = av_clip_uint8(dest[1] + dc); + dest[2] = av_clip_uint8(dest[2] + dc); + dest[3] = av_clip_uint8(dest[3] + dc); + dest[4] = av_clip_uint8(dest[4] + dc); + dest[5] = av_clip_uint8(dest[5] + dc); + dest[6] = av_clip_uint8(dest[6] + dc); + dest[7] = av_clip_uint8(dest[7] + dc); dest += line_size; } } diff --git a/libavcodec/vp5.c b/libavcodec/vp5.c index 23d0acc631..918dc177e6 100644 --- a/libavcodec/vp5.c +++ b/libavcodec/vp5.c @@ -49,14 +49,19 @@ static int vp5_parse_header(VP56Context *s, const uint8_t *buf, int buf_size, { vp56_rac_gets(c, 8); if(vp56_rac_gets(c, 5) > 5) - return 0; + return AVERROR_INVALIDDATA; vp56_rac_gets(c, 2); if (vp56_rac_get(c)) { av_log(s->avctx, AV_LOG_ERROR, "interlacing not supported\n"); - return 0; + return AVERROR_PATCHWELCOME; } rows = vp56_rac_gets(c, 8); /* number of stored macroblock rows */ cols = vp56_rac_gets(c, 8); /* number of stored macroblock cols */ + if (!rows || !cols) { + av_log(s->avctx, AV_LOG_ERROR, "Invalid size %dx%d\n", + cols << 4, rows << 4); + return AVERROR_INVALIDDATA; + } vp56_rac_gets(c, 8); /* number of displayed macroblock rows */ vp56_rac_gets(c, 8); /* number of displayed macroblock cols */ vp56_rac_gets(c, 2); @@ -64,11 +69,11 @@ static int vp5_parse_header(VP56Context *s, const uint8_t *buf, int buf_size, 16*cols != s->avctx->coded_width || 16*rows != s->avctx->coded_height) { avcodec_set_dimensions(s->avctx, 16*cols, 16*rows); - return 2; + return VP56_SIZE_CHANGE; } } else if (!s->macroblocks) - return 0; - return 1; + return AVERROR_INVALIDDATA; + return 0; } static void vp5_parse_vector_adjustment(VP56Context *s, VP56mv *vect) diff --git a/libavcodec/vp56.c b/libavcodec/vp56.c index cca3e207b2..f864097099 100644 --- a/libavcodec/vp56.c +++ b/libavcodec/vp56.c @@ -513,10 +513,16 @@ int ff_vp56_decode_frame(AVCodecContext *avctx, void *data, int *data_size, s->modelp = &s->models[is_alpha]; res = s->parse_header(s, buf, remaining_buf_size, &golden_frame); - if (!res) - return -1; + if (res < 0) { + int i; + for (i = 0; i < 4; i++) { + if (s->frames[i].data[0]) + avctx->release_buffer(avctx, &s->frames[i]); + } + return res; + } - if (res == 2) { + if (res == VP56_SIZE_CHANGE) { int i; for (i = 0; i < 4; i++) { if (s->frames[i].data[0]) @@ -535,7 +541,7 @@ int ff_vp56_decode_frame(AVCodecContext *avctx, void *data, int *data_size, return -1; } - if (res == 2) + if (res == VP56_SIZE_CHANGE) if (vp56_size_changed(avctx)) { avctx->release_buffer(avctx, p); return -1; diff --git a/libavcodec/vp56.h b/libavcodec/vp56.h index e135718d20..9e1b5c0599 100644 --- a/libavcodec/vp56.h +++ b/libavcodec/vp56.h @@ -39,6 +39,8 @@ typedef struct { int16_t y; } DECLARE_ALIGNED(4, , VP56mv); +#define VP56_SIZE_CHANGE 1 + typedef void (*VP56ParseVectorAdjustment)(VP56Context *s, VP56mv *vect); typedef void (*VP56Filter)(VP56Context *s, uint8_t *dst, uint8_t *src, diff --git a/libavcodec/vp6.c b/libavcodec/vp6.c index 84876b7146..0cc7a785ff 100644 --- a/libavcodec/vp6.c +++ b/libavcodec/vp6.c @@ -52,7 +52,7 @@ static int vp6_parse_header(VP56Context *s, const uint8_t *buf, int buf_size, int vrt_shift = 0; int sub_version; int rows, cols; - int res = 1; + int res = 0; int separated_coeff = buf[0] & 1; s->framep[VP56_FRAME_CURRENT]->key_frame = !(buf[0] & 0x80); @@ -61,11 +61,11 @@ static int vp6_parse_header(VP56Context *s, const uint8_t *buf, int buf_size, if (s->framep[VP56_FRAME_CURRENT]->key_frame) { sub_version = buf[1] >> 3; if (sub_version > 8) - return 0; + return AVERROR_INVALIDDATA; s->filter_header = buf[1] & 0x06; if (buf[1] & 1) { - av_log(s->avctx, AV_LOG_ERROR, "interlacing not supported\n"); - return 0; + av_log_missing_feature(s->avctx, "Interlacing", 0); + return AVERROR_PATCHWELCOME; } if (separated_coeff || !s->filter_header) { coeff_offset = AV_RB16(buf+2) - 2; @@ -77,6 +77,10 @@ static int vp6_parse_header(VP56Context *s, const uint8_t *buf, int buf_size, cols = buf[3]; /* number of stored macroblock cols */ /* buf[4] is number of displayed macroblock rows */ /* buf[5] is number of displayed macroblock cols */ + if (!rows || !cols) { + av_log(s->avctx, AV_LOG_ERROR, "Invalid size %dx%d\n", cols << 4, rows << 4); + return AVERROR_INVALIDDATA; + } if (!s->macroblocks || /* first frame */ 16*cols != s->avctx->coded_width || @@ -86,7 +90,7 @@ static int vp6_parse_header(VP56Context *s, const uint8_t *buf, int buf_size, s->avctx->width -= s->avctx->extradata[0] >> 4; s->avctx->height -= s->avctx->extradata[0] & 0x0F; } - res = 2; + res = VP56_SIZE_CHANGE; } ff_vp56_init_range_decoder(c, buf+6, buf_size-6); @@ -97,8 +101,8 @@ static int vp6_parse_header(VP56Context *s, const uint8_t *buf, int buf_size, vrt_shift = 5; s->sub_version = sub_version; } else { - if (!s->sub_version) - return 0; + if (!s->sub_version || !s->avctx->coded_width || !s->avctx->coded_height) + return AVERROR_INVALIDDATA; if (separated_coeff || !s->filter_header) { coeff_offset = AV_RB16(buf+1) - 2; @@ -142,7 +146,7 @@ static int vp6_parse_header(VP56Context *s, const uint8_t *buf, int buf_size, if (buf_size < 0) { if (s->framep[VP56_FRAME_CURRENT]->key_frame) avcodec_set_dimensions(s->avctx, 0, 0); - return 0; + return AVERROR_INVALIDDATA; } if (s->use_huffman) { s->parse_coeff = vp6_parse_coeff_huffman; @@ -233,7 +237,7 @@ static int vp6_build_huff_tree(VP56Context *s, uint8_t coeff_model[], nodes[map[2*i+1]].count = b + !b; } - free_vlc(vlc); + ff_free_vlc(vlc); /* then build the huffman tree according to probabilities */ return ff_huff_build_tree(s->avctx, vlc, size, nodes, vp6_huff_cmp, FF_HUFFMAN_FLAG_HNODE_FIRST); @@ -383,7 +387,7 @@ static void vp6_parse_coeff_huffman(VP56Context *s) if (coeff_idx) break; } else { - if (get_bits_count(&s->gb) >= s->gb.size_in_bits) + if (get_bits_left(&s->gb) <= 0) return; coeff = get_vlc2(&s->gb, vlc_coeff->table, 9, 3); if (coeff == 0) { @@ -611,11 +615,11 @@ static av_cold int vp6_decode_free(AVCodecContext *avctx) ff_vp56_free(avctx); for (pt=0; pt<2; pt++) { - free_vlc(&s->dccv_vlc[pt]); - free_vlc(&s->runv_vlc[pt]); + ff_free_vlc(&s->dccv_vlc[pt]); + ff_free_vlc(&s->runv_vlc[pt]); for (ct=0; ct<3; ct++) for (cg=0; cg<6; cg++) - free_vlc(&s->ract_vlc[pt][ct][cg]); + ff_free_vlc(&s->ract_vlc[pt][ct][cg]); } return 0; } diff --git a/libavcodec/vp8.c b/libavcodec/vp8.c index d68a91ea54..bfc34ca4fe 100644 --- a/libavcodec/vp8.c +++ b/libavcodec/vp8.c @@ -318,6 +318,7 @@ static int decode_frame_header(VP8Context *s, const uint8_t *buf, int buf_size) memcpy(s->prob->pred8x8c , vp8_pred8x8c_prob_inter , sizeof(s->prob->pred8x8c)); memcpy(s->prob->mvc , vp8_mv_default_prob , sizeof(s->prob->mvc)); memset(&s->segmentation, 0, sizeof(s->segmentation)); + memset(&s->lf_delta, 0, sizeof(s->lf_delta)); } if (!s->macroblocks_base || /* first frame */ @@ -642,7 +643,7 @@ void decode_mb_mode(VP8Context *s, VP8Macroblock *mb, int mb_x, int mb_y, uint8_ if (s->segmentation.update_map) { int bit = vp56_rac_get_prob(c, s->prob->segmentid[0]); *segment = vp56_rac_get_prob(c, s->prob->segmentid[1+bit]) + 2*bit; - } else + } else if (s->segmentation.enabled) *segment = ref ? *ref : *segment; s->segment = *segment; diff --git a/libavcodec/vp8dsp.c b/libavcodec/vp8dsp.c index ce90675d87..af46b288f4 100644 --- a/libavcodec/vp8dsp.c +++ b/libavcodec/vp8dsp.c @@ -80,7 +80,6 @@ static void vp8_luma_dc_wht_dc_c(DCTELEM block[4][4][16], DCTELEM dc[16]) static void vp8_idct_add_c(uint8_t *dst, DCTELEM block[16], int stride) { int i, t0, t1, t2, t3; - uint8_t *cm = ff_cropTbl + MAX_NEG_CROP; DCTELEM tmp[16]; for (i = 0; i < 4; i++) { @@ -105,10 +104,10 @@ static void vp8_idct_add_c(uint8_t *dst, DCTELEM block[16], int stride) t2 = MUL_35468(tmp[1*4+i]) - MUL_20091(tmp[3*4+i]); t3 = MUL_20091(tmp[1*4+i]) + MUL_35468(tmp[3*4+i]); - dst[0] = cm[dst[0] + ((t0 + t3 + 4) >> 3)]; - dst[1] = cm[dst[1] + ((t1 + t2 + 4) >> 3)]; - dst[2] = cm[dst[2] + ((t1 - t2 + 4) >> 3)]; - dst[3] = cm[dst[3] + ((t0 - t3 + 4) >> 3)]; + dst[0] = av_clip_uint8(dst[0] + ((t0 + t3 + 4) >> 3)); + dst[1] = av_clip_uint8(dst[1] + ((t1 + t2 + 4) >> 3)); + dst[2] = av_clip_uint8(dst[2] + ((t1 - t2 + 4) >> 3)); + dst[3] = av_clip_uint8(dst[3] + ((t0 - t3 + 4) >> 3)); dst += stride; } } @@ -116,14 +115,13 @@ static void vp8_idct_add_c(uint8_t *dst, DCTELEM block[16], int stride) static void vp8_idct_dc_add_c(uint8_t *dst, DCTELEM block[16], int stride) { int i, dc = (block[0] + 4) >> 3; - uint8_t *cm = ff_cropTbl + MAX_NEG_CROP + dc; block[0] = 0; for (i = 0; i < 4; i++) { - dst[0] = cm[dst[0]]; - dst[1] = cm[dst[1]]; - dst[2] = cm[dst[2]]; - dst[3] = cm[dst[3]]; + dst[0] = av_clip_uint8(dst[0] + dc); + dst[1] = av_clip_uint8(dst[1] + dc); + dst[2] = av_clip_uint8(dst[2] + dc); + dst[3] = av_clip_uint8(dst[3] + dc); dst += stride; } } diff --git a/libavcodec/vqavideo.c b/libavcodec/vqavideo.c index ae99c6d9c1..f3ad4f2fbe 100644 --- a/libavcodec/vqavideo.c +++ b/libavcodec/vqavideo.c @@ -70,10 +70,10 @@ #include "libavutil/intreadwrite.h" #include "libavutil/imgutils.h" #include "avcodec.h" +#include "bytestream.h" #define PALETTE_COUNT 256 #define VQA_HEADER_SIZE 0x2A -#define CHUNK_PREAMBLE_SIZE 8 /* allocate the maximum vector space, regardless of the file version: * (0xFF00 codebook vectors + 0x100 solid pixel vectors) * (4x4 pixels/block) */ @@ -94,9 +94,7 @@ typedef struct VqaContext { AVCodecContext *avctx; AVFrame frame; - - const unsigned char *buf; - int size; + GetByteContext gb; uint32_t palette[PALETTE_COUNT]; @@ -123,7 +121,6 @@ typedef struct VqaContext { static av_cold int vqa_decode_init(AVCodecContext *avctx) { VqaContext *s = avctx->priv_data; - unsigned char *vqa_header; int i, j, codebook_index; s->avctx = avctx; @@ -136,21 +133,27 @@ static av_cold int vqa_decode_init(AVCodecContext *avctx) } /* load up the VQA parameters from the header */ - vqa_header = (unsigned char *)s->avctx->extradata; - s->vqa_version = vqa_header[0]; - if (s->vqa_version < 1 || s->vqa_version > 3) { - av_log(s->avctx, AV_LOG_ERROR, " VQA video: unsupported version %d\n", s->vqa_version); - return -1; + s->vqa_version = s->avctx->extradata[0]; + switch (s->vqa_version) { + case 1: + case 2: + break; + case 3: + av_log_missing_feature(avctx, "VQA Version 3", 0); + return AVERROR_PATCHWELCOME; + default: + av_log_missing_feature(avctx, "VQA Version", 1); + return AVERROR_PATCHWELCOME; } - s->width = AV_RL16(&vqa_header[6]); - s->height = AV_RL16(&vqa_header[8]); + s->width = AV_RL16(&s->avctx->extradata[6]); + s->height = AV_RL16(&s->avctx->extradata[8]); if(av_image_check_size(s->width, s->height, 0, avctx)){ s->width= s->height= 0; return -1; } - s->vector_width = vqa_header[10]; - s->vector_height = vqa_header[11]; - s->partial_count = s->partial_countdown = vqa_header[13]; + s->vector_width = s->avctx->extradata[10]; + s->vector_height = s->avctx->extradata[11]; + s->partial_count = s->partial_countdown = s->avctx->extradata[13]; /* the vector dimensions have to meet very stringent requirements */ if ((s->vector_width != 4) || @@ -159,6 +162,11 @@ static av_cold int vqa_decode_init(AVCodecContext *avctx) return -1; } + if (s->width % s->vector_width || s->height % s->vector_height) { + av_log(avctx, AV_LOG_ERROR, "Image size not multiple of block size\n"); + return AVERROR_INVALIDDATA; + } + /* allocate codebooks */ s->codebook_size = MAX_CODEBOOK_SIZE; s->codebook = av_malloc(s->codebook_size); @@ -194,90 +202,88 @@ static av_cold int vqa_decode_init(AVCodecContext *avctx) av_log(NULL, AV_LOG_ERROR, " VQA video: decode_format80 problem: next op would overflow dest_index\n"); \ av_log(NULL, AV_LOG_ERROR, " VQA video: current dest_index = %d, count = %d, dest_size = %d\n", \ dest_index, count, dest_size); \ - return; \ + return AVERROR_INVALIDDATA; \ } -static void decode_format80(const unsigned char *src, int src_size, +#define CHECK_COPY(idx) \ + if (idx < 0 || idx + count > dest_size) { \ + av_log(NULL, AV_LOG_ERROR, " VQA video: decode_format80 problem: next op would overflow dest_index\n"); \ + av_log(NULL, AV_LOG_ERROR, " VQA video: current src_pos = %d, count = %d, dest_size = %d\n", \ + src_pos, count, dest_size); \ + return AVERROR_INVALIDDATA; \ + } + + +static int decode_format80(GetByteContext *gb, int src_size, unsigned char *dest, int dest_size, int check_size) { - int src_index = 0; int dest_index = 0; - int count; + int count, opcode, start; int src_pos; unsigned char color; int i; - while (src_index < src_size) { - - av_dlog(NULL, " opcode %02X: ", src[src_index]); + start = bytestream2_tell(gb); + while (bytestream2_tell(gb) - start < src_size) { + opcode = bytestream2_get_byte(gb); + av_dlog(NULL, " opcode %02X: ", opcode); /* 0x80 means that frame is finished */ - if (src[src_index] == 0x80) - return; + if (opcode == 0x80) + return 0; if (dest_index >= dest_size) { av_log(NULL, AV_LOG_ERROR, " VQA video: decode_format80 problem: dest_index (%d) exceeded dest_size (%d)\n", dest_index, dest_size); - return; + return AVERROR_INVALIDDATA; } - if (src[src_index] == 0xFF) { + if (opcode == 0xFF) { - src_index++; - count = AV_RL16(&src[src_index]); - src_index += 2; - src_pos = AV_RL16(&src[src_index]); - src_index += 2; + count = bytestream2_get_le16(gb); + src_pos = bytestream2_get_le16(gb); av_dlog(NULL, "(1) copy %X bytes from absolute pos %X\n", count, src_pos); CHECK_COUNT(); - if (src_pos + count > dest_size) - return; + CHECK_COPY(src_pos); for (i = 0; i < count; i++) dest[dest_index + i] = dest[src_pos + i]; dest_index += count; - } else if (src[src_index] == 0xFE) { + } else if (opcode == 0xFE) { - src_index++; - count = AV_RL16(&src[src_index]); - src_index += 2; - color = src[src_index++]; + count = bytestream2_get_le16(gb); + color = bytestream2_get_byte(gb); av_dlog(NULL, "(2) set %X bytes to %02X\n", count, color); CHECK_COUNT(); memset(&dest[dest_index], color, count); dest_index += count; - } else if ((src[src_index] & 0xC0) == 0xC0) { + } else if ((opcode & 0xC0) == 0xC0) { - count = (src[src_index++] & 0x3F) + 3; - src_pos = AV_RL16(&src[src_index]); - src_index += 2; + count = (opcode & 0x3F) + 3; + src_pos = bytestream2_get_le16(gb); av_dlog(NULL, "(3) copy %X bytes from absolute pos %X\n", count, src_pos); CHECK_COUNT(); - if (src_pos + count > dest_size) - return; + CHECK_COPY(src_pos); for (i = 0; i < count; i++) dest[dest_index + i] = dest[src_pos + i]; dest_index += count; - } else if (src[src_index] > 0x80) { + } else if (opcode > 0x80) { - count = src[src_index++] & 0x3F; + count = opcode & 0x3F; av_dlog(NULL, "(4) copy %X bytes from source to dest\n", count); CHECK_COUNT(); - memcpy(&dest[dest_index], &src[src_index], count); - src_index += count; + bytestream2_get_buffer(gb, &dest[dest_index], count); dest_index += count; } else { - count = ((src[src_index] & 0x70) >> 4) + 3; - src_pos = AV_RB16(&src[src_index]) & 0x0FFF; - src_index += 2; + count = ((opcode & 0x70) >> 4) + 3; + src_pos = bytestream2_get_byte(gb) | ((opcode & 0x0F) << 8); av_dlog(NULL, "(5) copy %X bytes from relpos %X\n", count, src_pos); CHECK_COUNT(); - if (dest_index < src_pos) - return; + CHECK_COPY(dest_index - src_pos); for (i = 0; i < count; i++) dest[dest_index + i] = dest[dest_index - src_pos + i]; dest_index += count; @@ -292,9 +298,11 @@ static void decode_format80(const unsigned char *src, int src_size, if (dest_index < dest_size) av_log(NULL, AV_LOG_ERROR, " VQA video: decode_format80 problem: decode finished with dest_index (%d) < dest_size (%d)\n", dest_index, dest_size); + + return 0; // let's display what we decoded anyway } -static void vqa_decode_chunk(VqaContext *s) +static int vqa_decode_chunk(VqaContext *s) { unsigned int chunk_type; unsigned int chunk_size; @@ -303,6 +311,7 @@ static void vqa_decode_chunk(VqaContext *s) int i; unsigned char r, g, b; int index_shift; + int res; int cbf0_chunk = -1; int cbfz_chunk = -1; @@ -322,17 +331,11 @@ static void vqa_decode_chunk(VqaContext *s) int hibytes = s->decode_buffer_size / 2; /* first, traverse through the frame and find the subchunks */ - while (index + CHUNK_PREAMBLE_SIZE <= s->size) { - unsigned next_index; + while (bytestream2_get_bytes_left(&s->gb) >= 8) { - chunk_type = AV_RB32(&s->buf[index]); - chunk_size = AV_RB32(&s->buf[index + 4]); - byte_skip = chunk_size & 0x01; - next_index = index + CHUNK_PREAMBLE_SIZE + chunk_size + byte_skip; - if (next_index > s->size) { - av_log(s->avctx, AV_LOG_ERROR, "Dropping incomplete chunk\n"); - break; - } + chunk_type = bytestream2_get_be32u(&s->gb); + index = bytestream2_tell(&s->gb); + chunk_size = bytestream2_get_be32u(&s->gb); switch (chunk_type) { @@ -373,7 +376,9 @@ static void vqa_decode_chunk(VqaContext *s) chunk_type); break; } - index = next_index; + + byte_skip = chunk_size & 0x01; + bytestream2_skip(&s->gb, chunk_size + byte_skip); } /* next, deal with the palette */ @@ -381,7 +386,7 @@ static void vqa_decode_chunk(VqaContext *s) /* a chunk should not have both chunk types */ av_log(s->avctx, AV_LOG_ERROR, " VQA video: problem: found both CPL0 and CPLZ chunks\n"); - return; + return AVERROR_INVALIDDATA; } /* decompress the palette chunk */ @@ -394,19 +399,19 @@ static void vqa_decode_chunk(VqaContext *s) /* convert the RGB palette into the machine's endian format */ if (cpl0_chunk != -1) { - chunk_size = AV_RB32(&s->buf[cpl0_chunk + 4]); + bytestream2_seek(&s->gb, cpl0_chunk, SEEK_SET); + chunk_size = bytestream2_get_be32(&s->gb); /* sanity check the palette size */ - if (chunk_size / 3 > 256) { + if (chunk_size / 3 > 256 || chunk_size > bytestream2_get_bytes_left(&s->gb)) { av_log(s->avctx, AV_LOG_ERROR, " VQA video: problem: found a palette chunk with %d colors\n", chunk_size / 3); - return; + return AVERROR_INVALIDDATA; } - cpl0_chunk += CHUNK_PREAMBLE_SIZE; for (i = 0; i < chunk_size / 3; i++) { /* scale by 4 to transform 6-bit palette -> 8-bit */ - r = s->buf[cpl0_chunk++] * 4; - g = s->buf[cpl0_chunk++] * 4; - b = s->buf[cpl0_chunk++] * 4; + r = bytestream2_get_byteu(&s->gb) * 4; + g = bytestream2_get_byteu(&s->gb) * 4; + b = bytestream2_get_byteu(&s->gb) * 4; s->palette[i] = 0xFF << 24 | r << 16 | g << 8 | b; s->palette[i] |= s->palette[i] >> 6 & 0x30303; } @@ -417,31 +422,32 @@ static void vqa_decode_chunk(VqaContext *s) /* a chunk should not have both chunk types */ av_log(s->avctx, AV_LOG_ERROR, " VQA video: problem: found both CBF0 and CBFZ chunks\n"); - return; + return AVERROR_INVALIDDATA; } /* decompress the full codebook chunk */ if (cbfz_chunk != -1) { - chunk_size = AV_RB32(&s->buf[cbfz_chunk + 4]); - cbfz_chunk += CHUNK_PREAMBLE_SIZE; - decode_format80(&s->buf[cbfz_chunk], chunk_size, - s->codebook, s->codebook_size, 0); + bytestream2_seek(&s->gb, cbfz_chunk, SEEK_SET); + chunk_size = bytestream2_get_be32(&s->gb); + if ((res = decode_format80(&s->gb, chunk_size, s->codebook, + s->codebook_size, 0)) < 0) + return res; } /* copy a full codebook */ if (cbf0_chunk != -1) { - chunk_size = AV_RB32(&s->buf[cbf0_chunk + 4]); + bytestream2_seek(&s->gb, cbf0_chunk, SEEK_SET); + chunk_size = bytestream2_get_be32(&s->gb); /* sanity check the full codebook size */ if (chunk_size > MAX_CODEBOOK_SIZE) { av_log(s->avctx, AV_LOG_ERROR, " VQA video: problem: CBF0 chunk too large (0x%X bytes)\n", chunk_size); - return; + return AVERROR_INVALIDDATA; } - cbf0_chunk += CHUNK_PREAMBLE_SIZE; - memcpy(s->codebook, &s->buf[cbf0_chunk], chunk_size); + bytestream2_get_buffer(&s->gb, s->codebook, chunk_size); } /* decode the frame */ @@ -449,13 +455,14 @@ static void vqa_decode_chunk(VqaContext *s) /* something is wrong if there is no VPTZ chunk */ av_log(s->avctx, AV_LOG_ERROR, " VQA video: problem: no VPTZ chunk found\n"); - return; + return AVERROR_INVALIDDATA; } - chunk_size = AV_RB32(&s->buf[vptz_chunk + 4]); - vptz_chunk += CHUNK_PREAMBLE_SIZE; - decode_format80(&s->buf[vptz_chunk], chunk_size, - s->decode_buffer, s->decode_buffer_size, 1); + bytestream2_seek(&s->gb, vptz_chunk, SEEK_SET); + chunk_size = bytestream2_get_be32(&s->gb); + if ((res = decode_format80(&s->gb, chunk_size, + s->decode_buffer, s->decode_buffer_size, 1)) < 0) + return res; /* render the final PAL8 frame */ if (s->vector_height == 4) @@ -519,17 +526,23 @@ static void vqa_decode_chunk(VqaContext *s) if ((cbp0_chunk != -1) && (cbpz_chunk != -1)) { /* a chunk should not have both chunk types */ av_log(s->avctx, AV_LOG_ERROR, " VQA video: problem: found both CBP0 and CBPZ chunks\n"); - return; + return AVERROR_INVALIDDATA; } if (cbp0_chunk != -1) { - chunk_size = AV_RB32(&s->buf[cbp0_chunk + 4]); - cbp0_chunk += CHUNK_PREAMBLE_SIZE; + bytestream2_seek(&s->gb, cbp0_chunk, SEEK_SET); + chunk_size = bytestream2_get_be32(&s->gb); + + if (chunk_size > MAX_CODEBOOK_SIZE - s->next_codebook_buffer_index) { + av_log(s->avctx, AV_LOG_ERROR, "cbp0 chunk too large (%u bytes)\n", + chunk_size); + return AVERROR_INVALIDDATA; + } /* accumulate partial codebook */ - memcpy(&s->next_codebook_buffer[s->next_codebook_buffer_index], - &s->buf[cbp0_chunk], chunk_size); + bytestream2_get_buffer(&s->gb, &s->next_codebook_buffer[s->next_codebook_buffer_index], + chunk_size); s->next_codebook_buffer_index += chunk_size; s->partial_countdown--; @@ -547,39 +560,45 @@ static void vqa_decode_chunk(VqaContext *s) if (cbpz_chunk != -1) { - chunk_size = AV_RB32(&s->buf[cbpz_chunk + 4]); - cbpz_chunk += CHUNK_PREAMBLE_SIZE; + bytestream2_seek(&s->gb, cbpz_chunk, SEEK_SET); + chunk_size = bytestream2_get_be32(&s->gb); + + if (chunk_size > MAX_CODEBOOK_SIZE - s->next_codebook_buffer_index) { + av_log(s->avctx, AV_LOG_ERROR, "cbpz chunk too large (%u bytes)\n", + chunk_size); + return AVERROR_INVALIDDATA; + } /* accumulate partial codebook */ - memcpy(&s->next_codebook_buffer[s->next_codebook_buffer_index], - &s->buf[cbpz_chunk], chunk_size); + bytestream2_get_buffer(&s->gb, &s->next_codebook_buffer[s->next_codebook_buffer_index], + chunk_size); s->next_codebook_buffer_index += chunk_size; s->partial_countdown--; if (s->partial_countdown == 0) { + GetByteContext gb; + bytestream2_init(&gb, s->next_codebook_buffer, s->next_codebook_buffer_index); /* decompress codebook */ - decode_format80(s->next_codebook_buffer, - s->next_codebook_buffer_index, - s->codebook, s->codebook_size, 0); + if ((res = decode_format80(&gb, s->next_codebook_buffer_index, + s->codebook, s->codebook_size, 0)) < 0) + return res; /* reset accounting */ s->next_codebook_buffer_index = 0; s->partial_countdown = s->partial_count; } } + + return 0; } static int vqa_decode_frame(AVCodecContext *avctx, void *data, int *data_size, AVPacket *avpkt) { - const uint8_t *buf = avpkt->data; - int buf_size = avpkt->size; VqaContext *s = avctx->priv_data; - - s->buf = buf; - s->size = buf_size; + int res; if (s->frame.data[0]) avctx->release_buffer(avctx, &s->frame); @@ -589,7 +608,9 @@ static int vqa_decode_frame(AVCodecContext *avctx, return -1; } - vqa_decode_chunk(s); + bytestream2_init(&s->gb, avpkt->data, avpkt->size); + if ((res = vqa_decode_chunk(s)) < 0) + return res; /* make the palette available on the way out */ memcpy(s->frame.data[1], s->palette, PALETTE_COUNT * 4); @@ -599,7 +620,7 @@ static int vqa_decode_frame(AVCodecContext *avctx, *(AVFrame*)data = s->frame; /* report that the buffer was completely consumed */ - return buf_size; + return avpkt->size; } static av_cold int vqa_decode_end(AVCodecContext *avctx) diff --git a/libavcodec/wavpack.c b/libavcodec/wavpack.c index 9adfc968db..ae4946bc02 100644 --- a/libavcodec/wavpack.c +++ b/libavcodec/wavpack.c @@ -23,6 +23,7 @@ #include "libavutil/audioconvert.h" #include "avcodec.h" +#include "internal.h" #include "get_bits.h" #include "unary.h" @@ -773,13 +774,13 @@ static int wavpack_decode_block(AVCodecContext *avctx, int block_no, if (block_no >= wc->fdec_num && wv_alloc_frame_context(wc) < 0) { av_log(avctx, AV_LOG_ERROR, "Error creating frame decode context\n"); - return -1; + return AVERROR_INVALIDDATA; } s = wc->fdec[block_no]; if (!s) { av_log(avctx, AV_LOG_ERROR, "Context for block %d is not present\n", block_no); - return -1; + return AVERROR_INVALIDDATA; } memset(s->decorr, 0, MAX_TERMS * sizeof(Decorr)); @@ -790,6 +791,9 @@ static int wavpack_decode_block(AVCodecContext *avctx, int block_no, if (!wc->mkv_mode) { s->samples = AV_RL32(buf); buf += 4; + if (s->samples != wc->samples) + return AVERROR_INVALIDDATA; + if (!s->samples) { *got_frame_ptr = 0; return 0; @@ -808,8 +812,8 @@ static int wavpack_decode_block(AVCodecContext *avctx, int block_no, s->hybrid = s->frame_flags & WV_HYBRID_MODE; s->hybrid_bitrate = s->frame_flags & WV_HYBRID_BITRATE; s->post_shift = bpp * 8 - orig_bpp + ((s->frame_flags >> 13) & 0x1f); - s->hybrid_maxclip = (( 1LL << (orig_bpp - 1)) - 1) >> s->post_shift; - s->hybrid_minclip = ((-1LL << (orig_bpp - 1))) >> s->post_shift; + s->hybrid_maxclip = (( 1LL << (orig_bpp - 1)) - 1); + s->hybrid_minclip = ((-1LL << (orig_bpp - 1))); s->CRC = AV_RL32(buf); buf += 4; if (wc->mkv_mode) buf += 4; //skip block size; @@ -906,8 +910,9 @@ static int wavpack_decode_block(AVCodecContext *avctx, int block_no, } else { for (j = 0; j < s->decorr[i].value; j++) { s->decorr[i].samplesA[j] = wp_exp2(AV_RL16(buf)); buf += 2; - if (s->stereo_in) + if (s->stereo_in) { s->decorr[i].samplesB[j] = wp_exp2(AV_RL16(buf)); buf += 2; + } } t += s->decorr[i].value * 2 * (s->stereo_in + 1); } @@ -1018,7 +1023,7 @@ static int wavpack_decode_block(AVCodecContext *avctx, int block_no, case WP_ID_CHANINFO: if (size <= 1) { av_log(avctx, AV_LOG_ERROR, "Insufficient channel information\n"); - return -1; + return AVERROR_INVALIDDATA; } chan = *buf++; switch (size - 2) { @@ -1037,10 +1042,11 @@ static int wavpack_decode_block(AVCodecContext *avctx, int block_no, chmask = avctx->channel_layout; } if (chan != avctx->channels) { - av_log(avctx, AV_LOG_ERROR, "Block reports total %d channels, " - "decoder believes it's %d channels\n", chan, - avctx->channels); - return -1; + av_log(avctx, AV_LOG_ERROR, + "Block reports total %d channels, " + "decoder believes it's %d channels\n", + chan, avctx->channels); + return AVERROR_INVALIDDATA; } if (!avctx->channel_layout) avctx->channel_layout = chmask; @@ -1055,31 +1061,31 @@ static int wavpack_decode_block(AVCodecContext *avctx, int block_no, if (!got_terms) { av_log(avctx, AV_LOG_ERROR, "No block with decorrelation terms\n"); - return -1; + return AVERROR_INVALIDDATA; } if (!got_weights) { av_log(avctx, AV_LOG_ERROR, "No block with decorrelation weights\n"); - return -1; + return AVERROR_INVALIDDATA; } if (!got_samples) { av_log(avctx, AV_LOG_ERROR, "No block with decorrelation samples\n"); - return -1; + return AVERROR_INVALIDDATA; } if (!got_entropy) { av_log(avctx, AV_LOG_ERROR, "No block with entropy info\n"); - return -1; + return AVERROR_INVALIDDATA; } if (s->hybrid && !got_hybrid) { av_log(avctx, AV_LOG_ERROR, "Hybrid config not found\n"); - return -1; + return AVERROR_INVALIDDATA; } if (!got_bs) { av_log(avctx, AV_LOG_ERROR, "Packed samples not found\n"); - return -1; + return AVERROR_INVALIDDATA; } if (!got_float && avctx->sample_fmt == AV_SAMPLE_FMT_FLT) { av_log(avctx, AV_LOG_ERROR, "Float information not found\n"); - return -1; + return AVERROR_INVALIDDATA; } if (s->got_extra_bits && avctx->sample_fmt != AV_SAMPLE_FMT_FLT) { const int size = get_bits_left(&s->gb_extra_bits); @@ -1099,7 +1105,7 @@ static int wavpack_decode_block(AVCodecContext *avctx, int block_no, samplecount = wv_unpack_stereo(s, &s->gb, samples, AV_SAMPLE_FMT_FLT); if (samplecount < 0) - return -1; + return samplecount; samplecount >>= 1; } else { @@ -1113,7 +1119,7 @@ static int wavpack_decode_block(AVCodecContext *avctx, int block_no, samplecount = wv_unpack_mono(s, &s->gb, samples, AV_SAMPLE_FMT_FLT); if (samplecount < 0) - return -1; + return samplecount; if (s->stereo && avctx->sample_fmt == AV_SAMPLE_FMT_S16) { int16_t *dst = (int16_t*)samples + 1; @@ -1168,6 +1174,9 @@ static int wavpack_decode_frame(AVCodecContext *avctx, void *data, int frame_size, ret, frame_flags; int samplecount = 0; + if (avpkt->size < 12 + s->multichannel * 4) + return AVERROR_INVALIDDATA; + s->block = 0; s->ch_offset = 0; @@ -1187,7 +1196,7 @@ static int wavpack_decode_frame(AVCodecContext *avctx, void *data, if (s->samples <= 0) { av_log(avctx, AV_LOG_ERROR, "Invalid number of samples: %d\n", s->samples); - return AVERROR(EINVAL); + return AVERROR_INVALIDDATA; } if (frame_flags & 0x80) { @@ -1200,7 +1209,7 @@ static int wavpack_decode_frame(AVCodecContext *avctx, void *data, /* get output buffer */ s->frame.nb_samples = s->samples; - if ((ret = avctx->get_buffer(avctx, &s->frame)) < 0) { + if ((ret = ff_get_buffer(avctx, &s->frame)) < 0) { av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n"); return ret; } @@ -1221,13 +1230,13 @@ static int wavpack_decode_frame(AVCodecContext *avctx, void *data, av_log(avctx, AV_LOG_ERROR, "Block %d has invalid size (size %d " "vs. %d bytes left)\n", s->block, frame_size, buf_size); wavpack_decode_flush(avctx); - return -1; + return AVERROR_INVALIDDATA; } if ((samplecount = wavpack_decode_block(avctx, s->block, s->frame.data[0], got_frame_ptr, buf, frame_size)) < 0) { wavpack_decode_flush(avctx); - return -1; + return samplecount; } s->block++; buf += frame_size; buf_size -= frame_size; diff --git a/libavcodec/wma.c b/libavcodec/wma.c index feb121b591..fcb516ff09 100644 --- a/libavcodec/wma.c +++ b/libavcodec/wma.c @@ -417,16 +417,16 @@ int ff_wma_end(AVCodecContext *avctx) ff_mdct_end(&s->mdct_ctx[i]); if (s->use_exp_vlc) { - free_vlc(&s->exp_vlc); + ff_free_vlc(&s->exp_vlc); } if (s->use_noise_coding) { - free_vlc(&s->hgain_vlc); + ff_free_vlc(&s->hgain_vlc); } for (i = 0; i < 2; i++) { - free_vlc(&s->coef_vlc[i]); - av_free(s->run_table[i]); - av_free(s->level_table[i]); - av_free(s->int_table[i]); + ff_free_vlc(&s->coef_vlc[i]); + av_freep(&s->run_table[i]); + av_freep(&s->level_table[i]); + av_freep(&s->int_table[i]); } return 0; diff --git a/libavcodec/wma.h b/libavcodec/wma.h index 6c8e944b79..954153fac0 100644 --- a/libavcodec/wma.h +++ b/libavcodec/wma.h @@ -124,7 +124,7 @@ typedef struct WMACodecContext { /* output buffer for one frame and the last for IMDCT windowing */ DECLARE_ALIGNED(32, float, frame_out)[MAX_CHANNELS][BLOCK_MAX_SIZE * 2]; /* last frame info */ - uint8_t last_superframe[MAX_CODED_SUPERFRAME_SIZE + 4]; /* padding added */ + uint8_t last_superframe[MAX_CODED_SUPERFRAME_SIZE + FF_INPUT_BUFFER_PADDING_SIZE]; /* padding added */ int last_bitoffset; int last_superframe_len; float noise_table[NOISE_TAB_SIZE]; diff --git a/libavcodec/wmadec.c b/libavcodec/wmadec.c index 0b2e49981d..a18ae887bd 100644 --- a/libavcodec/wmadec.c +++ b/libavcodec/wmadec.c @@ -34,6 +34,7 @@ */ #include "avcodec.h" +#include "internal.h" #include "wma.h" #undef NDEBUG @@ -85,6 +86,11 @@ static int wma_decode_init(AVCodecContext * avctx) int i, flags2; uint8_t *extradata; + if (!avctx->block_align) { + av_log(avctx, AV_LOG_ERROR, "block_align is not set\n"); + return AVERROR(EINVAL); + } + s->avctx = avctx; /* extract flag infos */ @@ -368,7 +374,7 @@ static int decode_exp_vlc(WMACodecContext *s, int ch) } /* NOTE: this offset is the same as MPEG4 AAC ! */ last_exp += code - 60; - if ((unsigned)last_exp + 60 > FF_ARRAY_ELEMS(pow_tab)) { + if ((unsigned)last_exp + 60 >= FF_ARRAY_ELEMS(pow_tab)) { av_log(s->avctx, AV_LOG_ERROR, "Exponent out of range: %d\n", last_exp); return -1; @@ -529,6 +535,10 @@ static int wma_decode_block(WMACodecContext *s) coef escape coding */ total_gain = 1; for(;;) { + if (get_bits_left(&s->gb) < 7) { + av_log(s->avctx, AV_LOG_ERROR, "total_gain overread\n"); + return AVERROR_INVALIDDATA; + } a = get_bits(&s->gb, 7); total_gain += a; if (a != 127) @@ -834,8 +844,12 @@ static int wma_decode_superframe(AVCodecContext *avctx, void *data, s->last_superframe_len = 0; return 0; } - if (buf_size < s->block_align) - return AVERROR(EINVAL); + if (buf_size < s->block_align) { + av_log(avctx, AV_LOG_ERROR, + "Input packet size too small (%d < %d)\n", + buf_size, s->block_align); + return AVERROR_INVALIDDATA; + } if(s->block_align) buf_size = s->block_align; @@ -851,7 +865,7 @@ static int wma_decode_superframe(AVCodecContext *avctx, void *data, /* get output buffer */ s->frame.nb_samples = nb_frames * s->frame_len; - if ((ret = avctx->get_buffer(avctx, &s->frame)) < 0) { + if ((ret = ff_get_buffer(avctx, &s->frame)) < 0) { av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n"); return ret; } @@ -859,6 +873,12 @@ static int wma_decode_superframe(AVCodecContext *avctx, void *data, if (s->use_bit_reservoir) { bit_offset = get_bits(&s->gb, s->byte_offset_bits + 3); + if (bit_offset > get_bits_left(&s->gb)) { + av_log(avctx, AV_LOG_ERROR, + "Invalid last frame bit offset %d > buf size %d (%d)\n", + bit_offset, get_bits_left(&s->gb), buf_size); + goto fail; + } if (s->last_superframe_len > 0) { // printf("skip=%d\n", s->last_bitoffset); @@ -875,9 +895,10 @@ static int wma_decode_superframe(AVCodecContext *avctx, void *data, if (len > 0) { *q++ = (get_bits)(&s->gb, len) << (8 - len); } + memset(q, 0, FF_INPUT_BUFFER_PADDING_SIZE); /* XXX: bit_offset bits into last frame */ - init_get_bits(&s->gb, s->last_superframe, MAX_CODED_SUPERFRAME_SIZE*8); + init_get_bits(&s->gb, s->last_superframe, s->last_superframe_len * 8 + bit_offset); /* skip unused bits */ if (s->last_bitoffset > 0) skip_bits(&s->gb, s->last_bitoffset); @@ -891,7 +912,9 @@ static int wma_decode_superframe(AVCodecContext *avctx, void *data, /* read each frame starting from bit_offset */ pos = bit_offset + 4 + 4 + s->byte_offset_bits + 3; - init_get_bits(&s->gb, buf + (pos >> 3), (MAX_CODED_SUPERFRAME_SIZE - (pos >> 3))*8); + if (pos >= MAX_CODED_SUPERFRAME_SIZE * 8 || pos > buf_size * 8) + return AVERROR_INVALIDDATA; + init_get_bits(&s->gb, buf + (pos >> 3), (buf_size - (pos >> 3))*8); len = pos & 7; if (len > 0) skip_bits(&s->gb, len); diff --git a/libavcodec/wmaenc.c b/libavcodec/wmaenc.c index 6ec6d7ce57..404fcdd6e1 100644 --- a/libavcodec/wmaenc.c +++ b/libavcodec/wmaenc.c @@ -39,6 +39,12 @@ static int encode_init(AVCodecContext * avctx){ return AVERROR(EINVAL); } + if (avctx->sample_rate > 48000) { + av_log(avctx, AV_LOG_ERROR, "sample rate is too high: %d > 48kHz", + avctx->sample_rate); + return AVERROR(EINVAL); + } + if(avctx->bit_rate < 24*1000) { av_log(avctx, AV_LOG_ERROR, "bitrate too low: got %i, need 24000 or higher\n", avctx->bit_rate); @@ -64,6 +70,8 @@ static int encode_init(AVCodecContext * avctx){ s->use_exp_vlc = flags2 & 0x0001; s->use_bit_reservoir = flags2 & 0x0002; s->use_variable_block_len = flags2 & 0x0004; + if (avctx->channels == 2) + s->ms_stereo = 1; ff_wma_init(avctx, flags2); @@ -71,8 +79,12 @@ static int encode_init(AVCodecContext * avctx){ for(i = 0; i < s->nb_block_sizes; i++) ff_mdct_init(&s->mdct_ctx[i], s->frame_len_bits - i + 1, 0, 1.0); - avctx->block_align= - s->block_align= avctx->bit_rate*(int64_t)s->frame_len / (avctx->sample_rate*8); + s->block_align = avctx->bit_rate * (int64_t)s->frame_len / + (avctx->sample_rate * 8); + s->block_align = FFMIN(s->block_align, MAX_CODED_SUPERFRAME_SIZE); + avctx->block_align = s->block_align; + avctx->bit_rate = avctx->block_align * 8LL * avctx->sample_rate / + s->frame_len; //av_log(NULL, AV_LOG_ERROR, "%d %d %d %d\n", s->block_align, avctx->bit_rate, s->frame_len, avctx->sample_rate); avctx->frame_size= s->frame_len; @@ -181,7 +193,7 @@ static int encode_block(WMACodecContext *s, float (*src_coefs)[BLOCK_MAX_SIZE], } if (s->nb_channels == 2) { - put_bits(&s->pb, 1, s->ms_stereo= 1); + put_bits(&s->pb, 1, !!s->ms_stereo); } for(ch = 0; ch < s->nb_channels; ch++) { @@ -355,6 +367,11 @@ static int encode_superframe(AVCodecContext *avctx, } } + if (buf_size < 2 * MAX_CODED_SUPERFRAME_SIZE) { + av_log(avctx, AV_LOG_ERROR, "output buffer size is too small\n"); + return AVERROR(EINVAL); + } + #if 1 total_gain= 128; for(i=64; i; i>>=1){ diff --git a/libavcodec/wmalosslessdec.c b/libavcodec/wmalosslessdec.c index 3f23b66002..3fcf177c72 100644 --- a/libavcodec/wmalosslessdec.c +++ b/libavcodec/wmalosslessdec.c @@ -238,11 +238,11 @@ typedef struct WmallDecodeCtx { int8_t mclms_order; int8_t mclms_scaling; - int16_t mclms_coeffs[128]; - int16_t mclms_coeffs_cur[4]; - int16_t mclms_prevvalues[64]; // FIXME: should be 32-bit / 16-bit depending on bit-depth - int16_t mclms_updates[64]; - int mclms_recent; + int16_t mclms_coeffs[WMALL_MAX_CHANNELS * WMALL_MAX_CHANNELS * 32]; + int16_t mclms_coeffs_cur[WMALL_MAX_CHANNELS * WMALL_MAX_CHANNELS]; + int16_t mclms_prevvalues[WMALL_MAX_CHANNELS * 2 * 32]; + int16_t mclms_updates[WMALL_MAX_CHANNELS * 2 * 32]; + int mclms_recent; int movave_scaling; int quant_stepsize; diff --git a/libavcodec/wmaprodec.c b/libavcodec/wmaprodec.c index eccfb55432..b40b02000a 100644 --- a/libavcodec/wmaprodec.c +++ b/libavcodec/wmaprodec.c @@ -86,6 +86,7 @@ * subframe in order to reconstruct the output samples. */ +#include "libavutil/avassert.h" #include "libavutil/intfloat.h" #include "libavutil/intreadwrite.h" #include "avcodec.h" @@ -106,6 +107,7 @@ #define WMAPRO_BLOCK_MIN_BITS 6 ///< log2 of min block size #define WMAPRO_BLOCK_MAX_BITS 12 ///< log2 of max block size +#define WMAPRO_BLOCK_MIN_SIZE (1 << WMAPRO_BLOCK_MIN_BITS) ///< minimum block size #define WMAPRO_BLOCK_MAX_SIZE (1 << WMAPRO_BLOCK_MAX_BITS) ///< maximum block size #define WMAPRO_BLOCK_SIZES (WMAPRO_BLOCK_MAX_BITS - WMAPRO_BLOCK_MIN_BITS + 1) ///< possible block sizes @@ -280,6 +282,11 @@ static av_cold int decode_init(AVCodecContext *avctx) int log2_max_num_subframes; int num_possible_block_sizes; + if (!avctx->block_align) { + av_log(avctx, AV_LOG_ERROR, "block_align is not set\n"); + return AVERROR(EINVAL); + } + s->avctx = avctx; dsputil_init(&s->dsp, avctx); ff_fmt_convert_init(&s->fmt_conv, avctx); @@ -330,6 +337,17 @@ static av_cold int decode_init(AVCodecContext *avctx) return AVERROR_INVALIDDATA; } + if (s->min_samples_per_subframe < WMAPRO_BLOCK_MIN_SIZE) { + av_log(avctx, AV_LOG_ERROR, "Invalid minimum block size %i\n", + s->max_num_subframes); + return AVERROR_INVALIDDATA; + } + + if (s->avctx->sample_rate <= 0) { + av_log(avctx, AV_LOG_ERROR, "invalid sample rate\n"); + return AVERROR_INVALIDDATA; + } + s->num_channels = avctx->channels; if (s->num_channels < 0) { @@ -398,6 +416,9 @@ static av_cold int decode_init(AVCodecContext *avctx) offset &= ~3; if (offset > s->sfb_offsets[i][band - 1]) s->sfb_offsets[i][band++] = offset; + + if (offset >= subframe_len) + break; } s->sfb_offsets[i][band - 1] = subframe_len; s->num_sfb[i] = band - 1; @@ -418,7 +439,8 @@ static av_cold int decode_init(AVCodecContext *avctx) for (x = 0; x < num_possible_block_sizes; x++) { int v = 0; while (s->sfb_offsets[x][v + 1] << x < offset) - ++v; + if (++v >= MAX_BANDS) + return AVERROR_INVALIDDATA; s->sf_offsets[i][x][b] = v; } } @@ -710,6 +732,7 @@ static int decode_channel_transform(WMAProDecodeCtx* s) if (get_bits1(&s->gb)) { av_log_ask_for_sample(s->avctx, "unsupported channel transform type\n"); + return AVERROR_PATCHWELCOME; } } else { chgroup->transform = 1; @@ -1112,11 +1135,12 @@ static int decode_subframe(WMAProDecodeCtx *s) cur_subwoofer_cutoff = s->subwoofer_cutoffs[s->table_idx]; /** configure the decoder for the current subframe */ + offset += s->samples_per_frame >> 1; + for (i = 0; i < s->channels_for_cur_subframe; i++) { int c = s->channel_indexes_for_cur_subframe[i]; - s->channel[c].coeffs = &s->channel[c].out[(s->samples_per_frame >> 1) - + offset]; + s->channel[c].coeffs = &s->channel[c].out[offset]; } s->subframe_len = subframe_len; @@ -1157,6 +1181,7 @@ static int decode_subframe(WMAProDecodeCtx *s) transmit_coeffs = 1; } + av_assert0(s->subframe_len <= WMAPRO_BLOCK_MAX_SIZE); if (transmit_coeffs) { int step; int quant_step = 90 * s->bits_per_sample >> 4; @@ -1166,7 +1191,13 @@ static int decode_subframe(WMAProDecodeCtx *s) int num_bits = av_log2((s->subframe_len + 3)/4) + 1; for (i = 0; i < s->channels_for_cur_subframe; i++) { int c = s->channel_indexes_for_cur_subframe[i]; - s->channel[c].num_vec_coeffs = get_bits(&s->gb, num_bits) << 2; + int num_vec_coeffs = get_bits(&s->gb, num_bits) << 2; + if (num_vec_coeffs > s->subframe_len) { + av_log(s->avctx, AV_LOG_ERROR, "num_vec_coeffs %d is too large\n", num_vec_coeffs); + return AVERROR_INVALIDDATA; + } + av_assert0(num_vec_coeffs + offset <= FF_ARRAY_ELEMS(s->channel[c].out)); + s->channel[c].num_vec_coeffs = num_vec_coeffs; } } else { for (i = 0; i < s->channels_for_cur_subframe; i++) { @@ -1359,7 +1390,7 @@ static int decode_frame(WMAProDecodeCtx *s, int *got_frame_ptr) /* get output buffer */ s->frame.nb_samples = s->samples_per_frame; - if ((ret = avctx->get_buffer(avctx, &s->frame)) < 0) { + if ((ret = ff_get_buffer(avctx, &s->frame)) < 0) { av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n"); s->packet_loss = 1; return 0; @@ -1451,6 +1482,14 @@ static void save_bits(WMAProDecodeCtx *s, GetBitContext* gb, int len, return; } + if (len > put_bits_left(&s->pb)) { + av_log(s->avctx, AV_LOG_ERROR, + "Cannot append %d bits, only %d bits available.\n", + len, put_bits_left(&s->pb)); + s->packet_loss = 1; + return; + } + s->num_saved_bits += len; if (!append) { avpriv_copy_bits(&s->pb, gb->buffer + (get_bits_count(gb) >> 3), @@ -1497,8 +1536,11 @@ static int decode_packet(AVCodecContext *avctx, void *data, s->packet_done = 0; /** sanity check for the buffer length */ - if (buf_size < avctx->block_align) - return 0; + if (buf_size < avctx->block_align) { + av_log(avctx, AV_LOG_ERROR, "Input packet too small (%d < %d)\n", + buf_size, avctx->block_align); + return AVERROR_INVALIDDATA; + } s->next_packet_start = buf_size - avctx->block_align; buf_size = avctx->block_align; diff --git a/libavcodec/wmavoice.c b/libavcodec/wmavoice.c index 2be0cf25f2..f9de8945c9 100644 --- a/libavcodec/wmavoice.c +++ b/libavcodec/wmavoice.c @@ -29,6 +29,7 @@ #include #include "avcodec.h" +#include "internal.h" #include "get_bits.h" #include "put_bits.h" #include "wmavoice_data.h" @@ -1046,9 +1047,10 @@ static void aw_parse_coords(WMAVoiceContext *s, GetBitContext *gb, * @param gb bit I/O context * @param block_idx block index in frame [0, 1] * @param fcb structure containing fixed codebook vector info + * @return -1 on error, 0 otherwise */ -static void aw_pulse_set2(WMAVoiceContext *s, GetBitContext *gb, - int block_idx, AMRFixed *fcb) +static int aw_pulse_set2(WMAVoiceContext *s, GetBitContext *gb, + int block_idx, AMRFixed *fcb) { uint16_t use_mask_mem[9]; // only 5 are used, rest is padding uint16_t *use_mask = use_mask_mem + 2; @@ -1110,7 +1112,7 @@ static void aw_pulse_set2(WMAVoiceContext *s, GetBitContext *gb, else if (use_mask[2]) idx = 0x2F; else if (use_mask[3]) idx = 0x3F; else if (use_mask[4]) idx = 0x4F; - else return; + else return -1; idx -= av_log2_16bit(use_mask[idx >> 4]); } if (use_mask[idx >> 4] & (0x8000 >> (idx & 15))) { @@ -1127,6 +1129,7 @@ static void aw_pulse_set2(WMAVoiceContext *s, GetBitContext *gb, /* set offset for next block, relative to start of that block */ n = (MAX_FRAMESIZE / 2 - start_off) % fcb->pitch_lag; s->aw_next_pulse_off_cache = n ? fcb->pitch_lag - n : 0; + return 0; } /** @@ -1289,7 +1292,18 @@ static void synth_block_fcb_acb(WMAVoiceContext *s, GetBitContext *gb, * (fixed) codebook pulses of the speech signal. */ if (frame_desc->fcb_type == FCB_TYPE_AW_PULSES) { aw_pulse_set1(s, gb, block_idx, &fcb); - aw_pulse_set2(s, gb, block_idx, &fcb); + if (aw_pulse_set2(s, gb, block_idx, &fcb)) { + /* Conceal the block with silence and return. + * Skip the correct amount of bits to read the next + * block from the correct offset. */ + int r_idx = pRNG(s->frame_cntr, block_idx, size); + + for (n = 0; n < size; n++) + excitation[n] = + wmavoice_std_codebook[r_idx + n] * s->silence_gain; + skip_bits(gb, 7 + 1); + return; + } } else /* FCB_TYPE_EXC_PULSES */ { int offset_nbits = 5 - frame_desc->log_n_blocks; @@ -1440,8 +1454,7 @@ static int synth_frame(AVCodecContext *ctx, GetBitContext *gb, int frame_idx, int pitch[MAX_BLOCKS], last_block_pitch; /* 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 = MAX_FRAMESIZE / frame_descs[bd_idx].n_blocks; + int bd_idx = s->vbm_tree[get_vlc2(gb, frame_type_vlc.table, 6, 3)], block_nsamples; if (bd_idx < 0) { av_log(ctx, AV_LOG_ERROR, @@ -1449,6 +1462,8 @@ static int synth_frame(AVCodecContext *ctx, GetBitContext *gb, int frame_idx, return -1; } + block_nsamples = MAX_FRAMESIZE / frame_descs[bd_idx].n_blocks; + /* Pitch calculation for ACB_TYPE_ASYMMETRIC ("pitch-per-frame") */ if (frame_descs[bd_idx].acb_type == ACB_TYPE_ASYMMETRIC) { /* Pitch is provided per frame, which is interpreted as the pitch of @@ -1800,7 +1815,7 @@ static int synth_superframe(AVCodecContext *ctx, int *got_frame_ptr) /* get output buffer */ s->frame.nb_samples = 480; - if ((res = ctx->get_buffer(ctx, &s->frame)) < 0) { + if ((res = ff_get_buffer(ctx, &s->frame)) < 0) { av_log(ctx, AV_LOG_ERROR, "get_buffer() failed\n"); return res; } diff --git a/libavcodec/wmv2enc.c b/libavcodec/wmv2enc.c index bc9e4fa0ab..48f84ac737 100644 --- a/libavcodec/wmv2enc.c +++ b/libavcodec/wmv2enc.c @@ -171,7 +171,7 @@ void ff_wmv2_encode_mb(MpegEncContext * s, wmv2_inter_table[w->cbp_table_index][cbp + 64][0]); /* motion vector */ - h263_pred_motion(s, 0, 0, &pred_x, &pred_y); + ff_h263_pred_motion(s, 0, 0, &pred_x, &pred_y); ff_msmpeg4_encode_motion(s, motion_x - pred_x, motion_y - pred_y); } else { diff --git a/libavcodec/wnv1.c b/libavcodec/wnv1.c index 6429a5b748..39b552fcf2 100644 --- a/libavcodec/wnv1.c +++ b/libavcodec/wnv1.c @@ -70,6 +70,11 @@ static int decode_frame(AVCodecContext *avctx, int prev_y = 0, prev_u = 0, prev_v = 0; uint8_t *rbuf; + if (buf_size<=8) { + av_log(avctx, AV_LOG_ERROR, "buf_size %d is too small\n", buf_size); + return AVERROR_INVALIDDATA; + } + rbuf = av_malloc(buf_size + FF_INPUT_BUFFER_PADDING_SIZE); if(!rbuf){ av_log(avctx, AV_LOG_ERROR, "Cannot allocate temporary buffer\n"); diff --git a/libavcodec/ws-snd1.c b/libavcodec/ws-snd1.c index 2cb8bb44a6..8694210f65 100644 --- a/libavcodec/ws-snd1.c +++ b/libavcodec/ws-snd1.c @@ -22,6 +22,7 @@ #include #include "libavutil/intreadwrite.h" #include "avcodec.h" +#include "internal.h" /** * @file @@ -89,7 +90,7 @@ static int ws_snd_decode_frame(AVCodecContext *avctx, void *data, /* get output buffer */ s->frame.nb_samples = out_size; - if ((ret = avctx->get_buffer(avctx, &s->frame)) < 0) { + if ((ret = ff_get_buffer(avctx, &s->frame)) < 0) { av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n"); return ret; } diff --git a/libavcodec/x86/Makefile b/libavcodec/x86/Makefile index 1066b20139..2d28b299a1 100644 --- a/libavcodec/x86/Makefile +++ b/libavcodec/x86/Makefile @@ -3,8 +3,6 @@ OBJS-$(CONFIG_TRUEHD_DECODER) += x86/mlpdsp.o YASM-OBJS-$(CONFIG_DCT) += x86/dct32_sse.o -YASM-OBJS-FFT-$(HAVE_AMD3DNOW) += x86/fft_3dn.o -YASM-OBJS-FFT-$(HAVE_AMD3DNOWEXT) += x86/fft_3dn2.o YASM-OBJS-FFT-$(HAVE_SSE) += x86/fft_sse.o YASM-OBJS-$(CONFIG_FFT) += x86/fft_mmx.o \ $(YASM-OBJS-FFT-yes) diff --git a/libavcodec/x86/ac3dsp.asm b/libavcodec/x86/ac3dsp.asm index 59157b7219..26f5616b1d 100644 --- a/libavcodec/x86/ac3dsp.asm +++ b/libavcodec/x86/ac3dsp.asm @@ -35,7 +35,6 @@ pw_bap_mul2: dw 5, 7, 0, 7, 5, 7, 0, 7 ; used in ff_ac3_extract_exponents() pd_1: times 4 dd 1 pd_151: times 4 dd 151 -pb_shuf_4dwb: db 0, 4, 8, 12 SECTION .text @@ -87,7 +86,6 @@ AC3_EXPONENT_MIN sse2 ; This function uses 2 different methods to calculate a valid result. ; 1) logical 'or' of abs of each element ; This is used for ssse3 because of the pabsw instruction. -; It is also used for mmx because of the lack of min/max instructions. ; 2) calculate min/max for the array, then or(abs(min),abs(max)) ; This is used for mmxext and sse2 because they have pminsw/pmaxsw. ;----------------------------------------------------------------------------- @@ -105,15 +103,9 @@ cglobal ac3_max_msb_abs_int16_%1, 2,2,5, src, len pmaxsw m3, m0 pmaxsw m3, m1 %else ; or_abs -%ifidn %1, mmx - mova m0, [srcq] - mova m1, [srcq+mmsize] - ABS2 m0, m1, m3, m4 -%else ; ssse3 ; using memory args is faster for ssse3 pabsw m0, [srcq] pabsw m1, [srcq+mmsize] -%endif por m2, m0 por m2, m1 %endif @@ -138,9 +130,7 @@ cglobal ac3_max_msb_abs_int16_%1, 2,2,5, src, len %endmacro INIT_MMX -%define ABS2 ABS2_MMX %define PSHUFLW pshufw -AC3_MAX_MSB_ABS_INT16 mmx, or_abs %define ABS2 ABS2_MMX2 AC3_MAX_MSB_ABS_INT16 mmxext, min_max INIT_XMM @@ -404,15 +394,12 @@ cglobal ac3_extract_exponents_3dnow, 3,3,0, exp, coef, len %endif %macro AC3_EXTRACT_EXPONENTS 1 -cglobal ac3_extract_exponents_%1, 3,3,5, exp, coef, len +cglobal ac3_extract_exponents_%1, 3,3,4, exp, coef, len add expq, lenq lea coefq, [coefq+4*lenq] neg lenq mova m2, [pd_1] mova m3, [pd_151] -%ifidn %1, ssse3 ; - movd m4, [pb_shuf_4dwb] -%endif .loop: ; move 4 32-bit coefs to xmm0 mova m0, [coefq+4*lenq] @@ -426,12 +413,11 @@ cglobal ac3_extract_exponents_%1, 3,3,5, exp, coef, len mova m0, m3 psubd m0, m1 ; move the lowest byte in each of 4 dwords to the low dword -%ifidn %1, ssse3 - pshufb m0, m4 -%else + ; NOTE: We cannot just extract the low bytes with pshufb because the dword + ; result for 16777215 is -1 due to float inaccuracy. Using packuswb + ; clips this to 0, which is the correct exponent. packssdw m0, m0 packuswb m0, m0 -%endif movd [expq+lenq], m0 add lenq, 4 diff --git a/libavcodec/x86/ac3dsp_mmx.c b/libavcodec/x86/ac3dsp_mmx.c index 9578e98d8b..df5e77a612 100644 --- a/libavcodec/x86/ac3dsp_mmx.c +++ b/libavcodec/x86/ac3dsp_mmx.c @@ -27,7 +27,6 @@ extern void ff_ac3_exponent_min_mmx (uint8_t *exp, int num_reuse_blocks, int n extern void ff_ac3_exponent_min_mmxext(uint8_t *exp, int num_reuse_blocks, int nb_coefs); extern void ff_ac3_exponent_min_sse2 (uint8_t *exp, int num_reuse_blocks, int nb_coefs); -extern int ff_ac3_max_msb_abs_int16_mmx (const int16_t *src, int len); extern int ff_ac3_max_msb_abs_int16_mmxext(const int16_t *src, int len); extern int ff_ac3_max_msb_abs_int16_sse2 (const int16_t *src, int len); extern int ff_ac3_max_msb_abs_int16_ssse3 (const int16_t *src, int len); @@ -55,7 +54,6 @@ av_cold void ff_ac3dsp_init_x86(AC3DSPContext *c, int bit_exact) if (mm_flags & AV_CPU_FLAG_MMX) { c->ac3_exponent_min = ff_ac3_exponent_min_mmx; - c->ac3_max_msb_abs_int16 = ff_ac3_max_msb_abs_int16_mmx; c->ac3_lshift_int16 = ff_ac3_lshift_int16_mmx; c->ac3_rshift_int32 = ff_ac3_rshift_int32_mmx; } diff --git a/libavcodec/x86/cabac.h b/libavcodec/x86/cabac.h index 2bb0be6374..edcd34a177 100644 --- a/libavcodec/x86/cabac.h +++ b/libavcodec/x86/cabac.h @@ -107,8 +107,8 @@ static av_always_inline int get_cabac_bypass_sign_x86(CABACContext *c, int val) { x86_reg tmp; __asm__ volatile( - "movl %4, %k1 \n\t" - "movl %2, %%eax \n\t" + "movl %a5(%2), %k1 \n\t" + "movl %a3(%2), %%eax \n\t" "shl $17, %k1 \n\t" "add %%eax, %%eax \n\t" "sub %k1, %%eax \n\t" @@ -119,20 +119,23 @@ static av_always_inline int get_cabac_bypass_sign_x86(CABACContext *c, int val) "sub %%edx, %%ecx \n\t" "test %%ax, %%ax \n\t" " jnz 1f \n\t" - "mov %3, %1 \n\t" + "mov %a4(%2), %1 \n\t" "subl $0xFFFF, %%eax \n\t" "movzwl (%1), %%edx \n\t" "bswap %%edx \n\t" "shrl $15, %%edx \n\t" "add $2, %1 \n\t" "addl %%edx, %%eax \n\t" - "mov %1, %3 \n\t" + "mov %1, %a4(%2) \n\t" "1: \n\t" - "movl %%eax, %2 \n\t" + "movl %%eax, %a3(%2) \n\t" - :"+c"(val), "=&r"(tmp), "+m"(c->low), "+m"(c->bytestream) - :"m"(c->range) - : "%eax", "%edx" + : "+c"(val), "=&r"(tmp) + : "r"(c), + "i"(offsetof(CABACContext, low)), + "i"(offsetof(CABACContext, bytestream)), + "i"(offsetof(CABACContext, range)) + : "%eax", "%edx", "memory" ); return val; } diff --git a/libavcodec/x86/dsputil_mmx.c b/libavcodec/x86/dsputil_mmx.c index 6847e6e6f8..3d394a1dfe 100644 --- a/libavcodec/x86/dsputil_mmx.c +++ b/libavcodec/x86/dsputil_mmx.c @@ -2668,7 +2668,8 @@ void dsputil_init_mmx(DSPContext* c, AVCodecContext *avctx) c->add_hfyu_median_prediction = ff_add_hfyu_median_prediction_mmx2; #endif #if HAVE_7REGS - if (HAVE_AMD3DNOW && (mm_flags & AV_CPU_FLAG_3DNOW)) + if (HAVE_AMD3DNOW && (mm_flags & AV_CPU_FLAG_3DNOW) && + (mm_flags & AV_CPU_FLAG_CMOV)) c->add_hfyu_median_prediction = add_hfyu_median_prediction_cmov; #endif diff --git a/libavcodec/x86/dsputil_yasm.asm b/libavcodec/x86/dsputil_yasm.asm index dcd6fa4223..0f533241b1 100644 --- a/libavcodec/x86/dsputil_yasm.asm +++ b/libavcodec/x86/dsputil_yasm.asm @@ -475,7 +475,7 @@ cglobal scalarproduct_float_sse, 3,3,2, v1, v2, offset shufps xmm0, xmm0, 1 addss xmm0, xmm1 %ifndef ARCH_X86_64 - movd r0m, xmm0 + movss r0m, xmm0 fld dword r0m %endif RET diff --git a/libavcodec/x86/dsputilenc_mmx.c b/libavcodec/x86/dsputilenc_mmx.c index f13c1219da..35d50bec9e 100644 --- a/libavcodec/x86/dsputilenc_mmx.c +++ b/libavcodec/x86/dsputilenc_mmx.c @@ -823,6 +823,7 @@ static int vsad16_mmx2(void *v, uint8_t * pix1, uint8_t * pix2, int line_size, i static void diff_bytes_mmx(uint8_t *dst, uint8_t *src1, uint8_t *src2, int w){ x86_reg i=0; + if(w>=16) __asm__ volatile( "1: \n\t" "movq (%2, %0), %%mm0 \n\t" diff --git a/libavcodec/x86/fft.c b/libavcodec/x86/fft.c index d2d157c2d3..7918fcb3fd 100644 --- a/libavcodec/x86/fft.c +++ b/libavcodec/x86/fft.c @@ -39,16 +39,6 @@ av_cold void ff_fft_init_mmx(FFTContext *s) s->fft_permute = ff_fft_permute_sse; s->fft_calc = ff_fft_calc_sse; s->fft_permutation = FF_FFT_PERM_SWAP_LSBS; - } else if (has_vectors & AV_CPU_FLAG_3DNOWEXT && HAVE_AMD3DNOWEXT) { - /* 3DNowEx for K7 */ - s->imdct_calc = ff_imdct_calc_3dn2; - s->imdct_half = ff_imdct_half_3dn2; - s->fft_calc = ff_fft_calc_3dn2; - } else if (has_vectors & AV_CPU_FLAG_3DNOW && HAVE_AMD3DNOW) { - /* 3DNow! for K6-2/3 */ - s->imdct_calc = ff_imdct_calc_3dn; - s->imdct_half = ff_imdct_half_3dn; - s->fft_calc = ff_fft_calc_3dn; } #endif } diff --git a/libavcodec/x86/fft_3dn.c b/libavcodec/x86/fft_3dn.c deleted file mode 100644 index 6f2e2e8353..0000000000 --- a/libavcodec/x86/fft_3dn.c +++ /dev/null @@ -1,23 +0,0 @@ -/* - * FFT/MDCT transform with 3DNow! optimizations - * Copyright (c) 2008 Loren Merritt - * - * This file is part of FFmpeg. - * - * FFmpeg is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * FFmpeg is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#define EMULATE_3DNOWEXT -#include "fft_3dn2.c" diff --git a/libavcodec/x86/fft_3dn2.c b/libavcodec/x86/fft_3dn2.c deleted file mode 100644 index 7a6cac14c4..0000000000 --- a/libavcodec/x86/fft_3dn2.c +++ /dev/null @@ -1,174 +0,0 @@ -/* - * FFT/MDCT transform with Extended 3DNow! optimizations - * Copyright (c) 2006-2008 Zuxy MENG Jie, Loren Merritt - * - * This file is part of FFmpeg. - * - * FFmpeg is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * FFmpeg is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with FFmpeg; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#include "libavutil/x86_cpu.h" -#include "libavcodec/dsputil.h" -#include "fft.h" - -DECLARE_ALIGNED(8, static const unsigned int, m1m1)[2] = { 1U<<31, 1U<<31 }; - -#ifdef EMULATE_3DNOWEXT -#define PSWAPD(s,d)\ - "movq "#s","#d"\n"\ - "psrlq $32,"#d"\n"\ - "punpckldq "#s","#d"\n" -#define ff_fft_calc_3dn2 ff_fft_calc_3dn -#define ff_fft_dispatch_3dn2 ff_fft_dispatch_3dn -#define ff_fft_dispatch_interleave_3dn2 ff_fft_dispatch_interleave_3dn -#define ff_imdct_calc_3dn2 ff_imdct_calc_3dn -#define ff_imdct_half_3dn2 ff_imdct_half_3dn -#else -#define PSWAPD(s,d) "pswapd "#s","#d"\n" -#endif - -void ff_fft_dispatch_3dn2(FFTComplex *z, int nbits); -void ff_fft_dispatch_interleave_3dn2(FFTComplex *z, int nbits); - -void ff_fft_calc_3dn2(FFTContext *s, FFTComplex *z) -{ - int n = 1<nbits; - int i; - ff_fft_dispatch_interleave_3dn2(z, s->nbits); - __asm__ volatile("femms"); - if(n <= 8) - for(i=0; imdct_size; - long n2 = n >> 1; - long n4 = n >> 2; - long n8 = n >> 3; - const uint16_t *revtab = s->revtab; - const FFTSample *tcos = s->tcos; - const FFTSample *tsin = s->tsin; - const FFTSample *in1, *in2; - FFTComplex *z = (FFTComplex *)output; - - /* pre rotation */ - in1 = input; - in2 = input + n2 - 1; -#ifdef EMULATE_3DNOWEXT - __asm__ volatile("movd %0, %%mm7" ::"r"(1U<<31)); -#endif - for(k = 0; k < n4; k++) { - // FIXME a single block is faster, but gcc 2.95 and 3.4.x on 32bit can't compile it - __asm__ volatile( - "movd %0, %%mm0 \n" - "movd %2, %%mm1 \n" - "punpckldq %1, %%mm0 \n" - "punpckldq %3, %%mm1 \n" - "movq %%mm0, %%mm2 \n" - PSWAPD( %%mm1, %%mm3 ) - "pfmul %%mm1, %%mm0 \n" - "pfmul %%mm3, %%mm2 \n" -#ifdef EMULATE_3DNOWEXT - "movq %%mm0, %%mm1 \n" - "punpckhdq %%mm2, %%mm0 \n" - "punpckldq %%mm2, %%mm1 \n" - "pxor %%mm7, %%mm0 \n" - "pfadd %%mm1, %%mm0 \n" -#else - "pfpnacc %%mm2, %%mm0 \n" -#endif - ::"m"(in2[-2*k]), "m"(in1[2*k]), - "m"(tcos[k]), "m"(tsin[k]) - ); - __asm__ volatile( - "movq %%mm0, %0 \n\t" - :"=m"(z[revtab[k]]) - ); - } - - ff_fft_dispatch_3dn2(z, s->nbits); - -#define CMUL(j,mm0,mm1)\ - "movq (%2,"#j",2), %%mm6 \n"\ - "movq 8(%2,"#j",2), "#mm0"\n"\ - "movq %%mm6, "#mm1"\n"\ - "movq "#mm0",%%mm7 \n"\ - "pfmul (%3,"#j"), %%mm6 \n"\ - "pfmul (%4,"#j"), "#mm0"\n"\ - "pfmul (%4,"#j"), "#mm1"\n"\ - "pfmul (%3,"#j"), %%mm7 \n"\ - "pfsub %%mm6, "#mm0"\n"\ - "pfadd %%mm7, "#mm1"\n" - - /* post rotation */ - j = -n2; - k = n2-8; - __asm__ volatile( - "1: \n" - CMUL(%0, %%mm0, %%mm1) - CMUL(%1, %%mm2, %%mm3) - "movd %%mm0, (%2,%0,2) \n" - "movd %%mm1,12(%2,%1,2) \n" - "movd %%mm2, (%2,%1,2) \n" - "movd %%mm3,12(%2,%0,2) \n" - "psrlq $32, %%mm0 \n" - "psrlq $32, %%mm1 \n" - "psrlq $32, %%mm2 \n" - "psrlq $32, %%mm3 \n" - "movd %%mm0, 8(%2,%0,2) \n" - "movd %%mm1, 4(%2,%1,2) \n" - "movd %%mm2, 8(%2,%1,2) \n" - "movd %%mm3, 4(%2,%0,2) \n" - "sub $8, %1 \n" - "add $8, %0 \n" - "jl 1b \n" - :"+r"(j), "+r"(k) - :"r"(z+n8), "r"(tcos+n8), "r"(tsin+n8) - :"memory" - ); - __asm__ volatile("femms"); -} - -void ff_imdct_calc_3dn2(FFTContext *s, FFTSample *output, const FFTSample *input) -{ - x86_reg j, k; - long n = s->mdct_size; - long n4 = n >> 2; - - ff_imdct_half_3dn2(s, output+n4, input); - - j = -n; - k = n-8; - __asm__ volatile( - "movq %4, %%mm7 \n" - "1: \n" - PSWAPD((%2,%1), %%mm0) - PSWAPD((%3,%0), %%mm1) - "pxor %%mm7, %%mm0 \n" - "movq %%mm1, (%3,%1) \n" - "movq %%mm0, (%2,%0) \n" - "sub $8, %1 \n" - "add $8, %0 \n" - "jl 1b \n" - :"+r"(j), "+r"(k) - :"r"(output+n4), "r"(output+n4*3), - "m"(*m1m1) - ); - __asm__ volatile("femms"); -} - diff --git a/libavcodec/x86/h264_deblock_10bit.asm b/libavcodec/x86/h264_deblock_10bit.asm index b34867a36d..553463440f 100644 --- a/libavcodec/x86/h264_deblock_10bit.asm +++ b/libavcodec/x86/h264_deblock_10bit.asm @@ -876,7 +876,7 @@ cglobal deblock_v_chroma_10_%1, 5,7-(mmsize/16),8*(mmsize/16) %if mmsize < 16 add r0, mmsize add r5, mmsize - add r4, mmsize/8 + add r4, mmsize/4 dec r6 jg .loop REP_RET diff --git a/libavcodec/x86/h264_intrapred_init.c b/libavcodec/x86/h264_intrapred_init.c index 540ec87ad3..b9a6fc3e0d 100644 --- a/libavcodec/x86/h264_intrapred_init.c +++ b/libavcodec/x86/h264_intrapred_init.c @@ -176,7 +176,7 @@ void ff_h264_pred_init_x86(H264PredContext *h, int codec_id, const int bit_depth if (mm_flags & AV_CPU_FLAG_MMX) { h->pred16x16[VERT_PRED8x8 ] = ff_pred16x16_vertical_mmx; h->pred16x16[HOR_PRED8x8 ] = ff_pred16x16_horizontal_mmx; - if (chroma_format_idc == 1) { + if (chroma_format_idc <= 1) { h->pred8x8 [VERT_PRED8x8 ] = ff_pred8x8_vertical_mmx; h->pred8x8 [HOR_PRED8x8 ] = ff_pred8x8_horizontal_mmx; } @@ -185,10 +185,11 @@ void ff_h264_pred_init_x86(H264PredContext *h, int codec_id, const int bit_depth h->pred8x8 [PLANE_PRED8x8 ] = ff_pred8x8_tm_vp8_mmx; h->pred4x4 [TM_VP8_PRED ] = ff_pred4x4_tm_vp8_mmx; } else { - if (chroma_format_idc == 1) + if (chroma_format_idc <= 1) h->pred8x8 [PLANE_PRED8x8] = ff_pred8x8_plane_mmx; if (codec_id == CODEC_ID_SVQ3) { - h->pred16x16[PLANE_PRED8x8] = ff_pred16x16_plane_svq3_mmx; + if (mm_flags & AV_CPU_FLAG_CMOV) + h->pred16x16[PLANE_PRED8x8] = ff_pred16x16_plane_svq3_mmx; } else if (codec_id == CODEC_ID_RV40) { h->pred16x16[PLANE_PRED8x8] = ff_pred16x16_plane_rv40_mmx; } else { @@ -200,7 +201,7 @@ void ff_h264_pred_init_x86(H264PredContext *h, int codec_id, const int bit_depth if (mm_flags & AV_CPU_FLAG_MMX2) { h->pred16x16[HOR_PRED8x8 ] = ff_pred16x16_horizontal_mmxext; h->pred16x16[DC_PRED8x8 ] = ff_pred16x16_dc_mmxext; - if (chroma_format_idc == 1) + if (chroma_format_idc <= 1) h->pred8x8[HOR_PRED8x8 ] = ff_pred8x8_horizontal_mmxext; h->pred8x8l [TOP_DC_PRED ] = ff_pred8x8l_top_dc_mmxext; h->pred8x8l [DC_PRED ] = ff_pred8x8l_dc_mmxext; @@ -225,7 +226,7 @@ void ff_h264_pred_init_x86(H264PredContext *h, int codec_id, const int bit_depth h->pred4x4 [HOR_UP_PRED ] = ff_pred4x4_horizontal_up_mmxext; } if (codec_id == CODEC_ID_SVQ3 || codec_id == CODEC_ID_H264) { - if (chroma_format_idc == 1) { + if (chroma_format_idc <= 1) { h->pred8x8[TOP_DC_PRED8x8 ] = ff_pred8x8_top_dc_mmxext; h->pred8x8[DC_PRED8x8 ] = ff_pred8x8_dc_mmxext; } @@ -237,7 +238,7 @@ void ff_h264_pred_init_x86(H264PredContext *h, int codec_id, const int bit_depth h->pred4x4 [TM_VP8_PRED ] = ff_pred4x4_tm_vp8_mmxext; h->pred4x4 [VERT_PRED ] = ff_pred4x4_vertical_vp8_mmxext; } else { - if (chroma_format_idc == 1) + if (chroma_format_idc <= 1) h->pred8x8 [PLANE_PRED8x8] = ff_pred8x8_plane_mmx2; if (codec_id == CODEC_ID_SVQ3) { h->pred16x16[PLANE_PRED8x8 ] = ff_pred16x16_plane_svq3_mmx2; @@ -264,7 +265,7 @@ void ff_h264_pred_init_x86(H264PredContext *h, int codec_id, const int bit_depth h->pred16x16[PLANE_PRED8x8 ] = ff_pred16x16_tm_vp8_sse2; h->pred8x8 [PLANE_PRED8x8 ] = ff_pred8x8_tm_vp8_sse2; } else { - if (chroma_format_idc == 1) + if (chroma_format_idc <= 1) h->pred8x8 [PLANE_PRED8x8] = ff_pred8x8_plane_sse2; if (codec_id == CODEC_ID_SVQ3) { h->pred16x16[PLANE_PRED8x8] = ff_pred16x16_plane_svq3_sse2; @@ -279,7 +280,7 @@ void ff_h264_pred_init_x86(H264PredContext *h, int codec_id, const int bit_depth if (mm_flags & AV_CPU_FLAG_SSSE3) { h->pred16x16[HOR_PRED8x8 ] = ff_pred16x16_horizontal_ssse3; h->pred16x16[DC_PRED8x8 ] = ff_pred16x16_dc_ssse3; - if (chroma_format_idc == 1) + if (chroma_format_idc <= 1) h->pred8x8 [HOR_PRED8x8 ] = ff_pred8x8_horizontal_ssse3; h->pred8x8l [TOP_DC_PRED ] = ff_pred8x8l_top_dc_ssse3; h->pred8x8l [DC_PRED ] = ff_pred8x8l_dc_ssse3; @@ -295,7 +296,7 @@ void ff_h264_pred_init_x86(H264PredContext *h, int codec_id, const int bit_depth h->pred8x8 [PLANE_PRED8x8 ] = ff_pred8x8_tm_vp8_ssse3; h->pred4x4 [TM_VP8_PRED ] = ff_pred4x4_tm_vp8_ssse3; } else { - if (chroma_format_idc == 1) + if (chroma_format_idc <= 1) h->pred8x8 [PLANE_PRED8x8] = ff_pred8x8_plane_ssse3; if (codec_id == CODEC_ID_SVQ3) { h->pred16x16[PLANE_PRED8x8] = ff_pred16x16_plane_svq3_ssse3; @@ -311,7 +312,7 @@ void ff_h264_pred_init_x86(H264PredContext *h, int codec_id, const int bit_depth h->pred4x4[DC_PRED ] = ff_pred4x4_dc_10_mmxext; h->pred4x4[HOR_UP_PRED ] = ff_pred4x4_horizontal_up_10_mmxext; - if (chroma_format_idc == 1) + if (chroma_format_idc <= 1) h->pred8x8[DC_PRED8x8 ] = ff_pred8x8_dc_10_mmxext; h->pred8x8l[DC_128_PRED ] = ff_pred8x8l_128_dc_10_mmxext; @@ -330,7 +331,7 @@ void ff_h264_pred_init_x86(H264PredContext *h, int codec_id, const int bit_depth h->pred4x4[VERT_RIGHT_PRED ] = ff_pred4x4_vertical_right_10_sse2; h->pred4x4[HOR_DOWN_PRED ] = ff_pred4x4_horizontal_down_10_sse2; - if (chroma_format_idc == 1) { + if (chroma_format_idc <= 1) { h->pred8x8[DC_PRED8x8 ] = ff_pred8x8_dc_10_sse2; h->pred8x8[TOP_DC_PRED8x8 ] = ff_pred8x8_top_dc_10_sse2; h->pred8x8[PLANE_PRED8x8 ] = ff_pred8x8_plane_10_sse2; diff --git a/libavcodec/x86/h264_qpel_10bit.asm b/libavcodec/x86/h264_qpel_10bit.asm index 15dd72ca36..cafd4dabf0 100644 --- a/libavcodec/x86/h264_qpel_10bit.asm +++ b/libavcodec/x86/h264_qpel_10bit.asm @@ -619,7 +619,7 @@ MC MC33 %define PAD 12 %define COUNT 2 %else -%define PAD 0 +%define PAD 4 %define COUNT 3 %endif put_hv%2_10_%1: diff --git a/libavcodec/x86/h264dsp_mmx.c b/libavcodec/x86/h264dsp_mmx.c index b337462aec..e3854ff2ea 100644 --- a/libavcodec/x86/h264dsp_mmx.c +++ b/libavcodec/x86/h264dsp_mmx.c @@ -344,7 +344,7 @@ void ff_h264dsp_init_x86(H264DSPContext *c, const int bit_depth, const int chrom { int mm_flags = av_get_cpu_flags(); - if (chroma_format_idc == 1 && mm_flags & AV_CPU_FLAG_MMX2) { + if (chroma_format_idc <= 1 && mm_flags & AV_CPU_FLAG_MMX2) { c->h264_loop_filter_strength= h264_loop_filter_strength_mmx2; } @@ -358,23 +358,24 @@ void ff_h264dsp_init_x86(H264DSPContext *c, const int bit_depth, const int chrom c->h264_idct_add16 = ff_h264_idct_add16_8_mmx; c->h264_idct8_add4 = ff_h264_idct8_add4_8_mmx; - if (chroma_format_idc == 1) + if (chroma_format_idc <= 1) c->h264_idct_add8 = ff_h264_idct_add8_8_mmx; c->h264_idct_add16intra = ff_h264_idct_add16intra_8_mmx; - c->h264_luma_dc_dequant_idct= ff_h264_luma_dc_dequant_idct_mmx; + if (mm_flags & AV_CPU_FLAG_CMOV) + c->h264_luma_dc_dequant_idct = ff_h264_luma_dc_dequant_idct_mmx; if (mm_flags & AV_CPU_FLAG_MMX2) { c->h264_idct_dc_add = ff_h264_idct_dc_add_8_mmx2; c->h264_idct8_dc_add = ff_h264_idct8_dc_add_8_mmx2; c->h264_idct_add16 = ff_h264_idct_add16_8_mmx2; c->h264_idct8_add4 = ff_h264_idct8_add4_8_mmx2; - if (chroma_format_idc == 1) + if (chroma_format_idc <= 1) c->h264_idct_add8 = ff_h264_idct_add8_8_mmx2; c->h264_idct_add16intra= ff_h264_idct_add16intra_8_mmx2; c->h264_v_loop_filter_chroma= ff_deblock_v_chroma_8_mmxext; c->h264_v_loop_filter_chroma_intra= ff_deblock_v_chroma_intra_8_mmxext; - if (chroma_format_idc == 1) { + if (chroma_format_idc <= 1) { c->h264_h_loop_filter_chroma= ff_deblock_h_chroma_8_mmxext; c->h264_h_loop_filter_chroma_intra= ff_deblock_h_chroma_intra_8_mmxext; } @@ -397,7 +398,7 @@ void ff_h264dsp_init_x86(H264DSPContext *c, const int bit_depth, const int chrom c->h264_idct_add16 = ff_h264_idct_add16_8_sse2; c->h264_idct8_add4 = ff_h264_idct8_add4_8_sse2; - if (chroma_format_idc == 1) + if (chroma_format_idc <= 1) c->h264_idct_add8 = ff_h264_idct_add8_8_sse2; c->h264_idct_add16intra = ff_h264_idct_add16intra_8_sse2; c->h264_luma_dc_dequant_idct= ff_h264_luma_dc_dequant_idct_sse2; @@ -448,7 +449,7 @@ void ff_h264dsp_init_x86(H264DSPContext *c, const int bit_depth, const int chrom c->h264_idct8_dc_add = ff_h264_idct8_dc_add_10_sse2; c->h264_idct_add16 = ff_h264_idct_add16_10_sse2; - if (chroma_format_idc == 1) + if (chroma_format_idc <= 1) c->h264_idct_add8 = ff_h264_idct_add8_10_sse2; c->h264_idct_add16intra= ff_h264_idct_add16intra_10_sse2; #if HAVE_ALIGNED_STACK @@ -489,7 +490,7 @@ void ff_h264dsp_init_x86(H264DSPContext *c, const int bit_depth, const int chrom c->h264_idct8_dc_add = ff_h264_idct8_dc_add_10_avx; c->h264_idct_add16 = ff_h264_idct_add16_10_avx; - if (chroma_format_idc == 1) + if (chroma_format_idc <= 1) c->h264_idct_add8 = ff_h264_idct_add8_10_avx; c->h264_idct_add16intra= ff_h264_idct_add16intra_10_avx; #if HAVE_ALIGNED_STACK diff --git a/libavcodec/x86/mathops.h b/libavcodec/x86/mathops.h index 33d9a6c8ff..6fb7c32020 100644 --- a/libavcodec/x86/mathops.h +++ b/libavcodec/x86/mathops.h @@ -72,7 +72,7 @@ static av_always_inline av_const int64_t MUL64(int a, int b) static inline av_const int mid_pred(int a, int b, int c) { int i=b; - __asm__ volatile( + __asm__ ( "cmp %2, %1 \n\t" "cmovg %1, %0 \n\t" "cmovg %2, %1 \n\t" diff --git a/libavcodec/x86/mpegaudiodec_mmx.c b/libavcodec/x86/mpegaudiodec_mmx.c index b85b8a5548..e061d3e05c 100644 --- a/libavcodec/x86/mpegaudiodec_mmx.c +++ b/libavcodec/x86/mpegaudiodec_mmx.c @@ -160,6 +160,7 @@ static void apply_window_mp3(float *in, float *win, int *unused, float *out, } +#if HAVE_YASM #define DECL_IMDCT_BLOCKS(CPU1, CPU2) \ static void imdct36_blocks_ ## CPU1(float *out, float *buf, float *in, \ int count, int switch_point, int block_type) \ @@ -192,7 +193,6 @@ static void imdct36_blocks_ ## CPU1(float *out, float *buf, float *in, \ } \ } -#if HAVE_YASM #if HAVE_SSE DECL_IMDCT_BLOCKS(sse,sse) DECL_IMDCT_BLOCKS(sse2,sse) @@ -202,7 +202,7 @@ DECL_IMDCT_BLOCKS(ssse3,sse) #if HAVE_AVX DECL_IMDCT_BLOCKS(avx,avx) #endif -#endif +#endif /* HAVE_YASM */ void ff_mpadsp_init_mmx(MPADSPContext *s) { diff --git a/libavcodec/xan.c b/libavcodec/xan.c index cfaca81e16..4e33a9e71a 100644 --- a/libavcodec/xan.c +++ b/libavcodec/xan.c @@ -34,6 +34,7 @@ #include "libavutil/intreadwrite.h" #include "avcodec.h" +#include "internal.h" #include "bytestream.h" #define BITSTREAM_READER_LE #include "get_bits.h" @@ -106,6 +107,7 @@ static int xan_huffman_decode(unsigned char *dest, int dest_len, int ptr_len = src_len - 1 - byte*2; unsigned char val = ival; unsigned char *dest_end = dest + dest_len; + unsigned char *dest_start = dest; GetBitContext gb; if (ptr_len < 0) @@ -121,13 +123,13 @@ static int xan_huffman_decode(unsigned char *dest, int dest_len, if (val < 0x16) { if (dest >= dest_end) - return 0; + return dest_len; *dest++ = val; val = ival; } } - return 0; + return dest - dest_start; } /** @@ -276,7 +278,7 @@ static int xan_wc3_decode_frame(XanContext *s) { unsigned char flag = 0; int size = 0; int motion_x, motion_y; - int x, y; + int x, y, ret; unsigned char *opcode_buffer = s->buffer1; unsigned char *opcode_buffer_end = s->buffer1 + s->buffer1_size; @@ -285,8 +287,8 @@ static int xan_wc3_decode_frame(XanContext *s) { /* pointers to segments inside the compressed chunk */ const unsigned char *huffman_segment; - const unsigned char *size_segment; - const unsigned char *vector_segment; + GetByteContext size_segment; + GetByteContext vector_segment; const unsigned char *imagedata_segment; int huffman_offset, size_offset, vector_offset, imagedata_offset, imagedata_size; @@ -306,13 +308,14 @@ static int xan_wc3_decode_frame(XanContext *s) { return AVERROR_INVALIDDATA; huffman_segment = s->buf + huffman_offset; - size_segment = s->buf + size_offset; - vector_segment = s->buf + vector_offset; + bytestream2_init(&size_segment, s->buf + size_offset, s->size - size_offset); + bytestream2_init(&vector_segment, s->buf + vector_offset, s->size - vector_offset); imagedata_segment = s->buf + imagedata_offset; - if (xan_huffman_decode(opcode_buffer, opcode_buffer_size, - huffman_segment, s->size - huffman_offset) < 0) + if ((ret = xan_huffman_decode(opcode_buffer, opcode_buffer_size, + huffman_segment, s->size - huffman_offset)) < 0) return AVERROR_INVALIDDATA; + opcode_buffer_end = opcode_buffer + ret; if (imagedata_segment[0] == 2) { xan_unpack(s->buffer2, s->buffer2_size, @@ -359,19 +362,17 @@ static int xan_wc3_decode_frame(XanContext *s) { case 9: case 19: - size = *size_segment++; + size = bytestream2_get_byte(&size_segment); break; case 10: case 20: - size = AV_RB16(&size_segment[0]); - size_segment += 2; + size = bytestream2_get_be16(&size_segment); break; case 11: case 21: - size = AV_RB24(size_segment); - size_segment += 3; + size = bytestream2_get_be24(&size_segment); break; } @@ -393,9 +394,9 @@ static int xan_wc3_decode_frame(XanContext *s) { } } else { /* run-based motion compensation from last frame */ - motion_x = sign_extend(*vector_segment >> 4, 4); - motion_y = sign_extend(*vector_segment & 0xF, 4); - vector_segment++; + uint8_t vector = bytestream2_get_byte(&vector_segment); + motion_x = sign_extend(vector >> 4, 4); + motion_y = sign_extend(vector & 0xF, 4); /* copy a run of pixels from the previous frame */ xan_wc3_copy_pixel_run(s, x, y, size, motion_x, motion_y); @@ -512,6 +513,10 @@ static int xan_decode_frame(AVCodecContext *avctx, int i; tag = bytestream_get_le32(&buf); size = bytestream_get_be32(&buf); + if(size < 0) { + av_log(avctx, AV_LOG_ERROR, "Invalid tag size %d\n", size); + return AVERROR_INVALIDDATA; + } size = FFMIN(size, buf_end - buf); switch (tag) { case PALT_TAG: @@ -562,7 +567,7 @@ static int xan_decode_frame(AVCodecContext *avctx, return AVERROR_INVALIDDATA; } - if ((ret = avctx->get_buffer(avctx, &s->current_frame))) { + if ((ret = ff_get_buffer(avctx, &s->current_frame))) { av_log(s->avctx, AV_LOG_ERROR, "get_buffer() failed\n"); return ret; } diff --git a/libavcodec/xl.c b/libavcodec/xl.c index 78f34afa4e..50bd5f4fbf 100644 --- a/libavcodec/xl.c +++ b/libavcodec/xl.c @@ -69,6 +69,11 @@ static int decode_frame(AVCodecContext *avctx, stride = avctx->width - 4; + if (avctx->width % 4) { + av_log(avctx, AV_LOG_ERROR, "Width not a multiple of 4.\n"); + return AVERROR_INVALIDDATA; + } + if (buf_size < avctx->width * avctx->height) { av_log(avctx, AV_LOG_ERROR, "Packet is too small\n"); return AVERROR_INVALIDDATA; diff --git a/libavcodec/xxan.c b/libavcodec/xxan.c index 0bfebc8789..350211f128 100644 --- a/libavcodec/xxan.c +++ b/libavcodec/xxan.c @@ -35,6 +35,7 @@ typedef struct XanContext { uint8_t *y_buffer; uint8_t *scratch_buffer; int buffer_size; + GetByteContext gb; } XanContext; static av_cold int xan_decode_init(AVCodecContext *avctx) @@ -45,6 +46,11 @@ static av_cold int xan_decode_init(AVCodecContext *avctx) avctx->pix_fmt = PIX_FMT_YUV420P; + if (avctx->width & 1) { + av_log(avctx, AV_LOG_ERROR, "Invalid frame width: %d.\n", avctx->width); + return AVERROR(EINVAL); + } + s->buffer_size = avctx->width * avctx->height; s->y_buffer = av_malloc(s->buffer_size); if (!s->y_buffer) @@ -58,29 +64,29 @@ static av_cold int xan_decode_init(AVCodecContext *avctx) return 0; } -static int xan_unpack_luma(const uint8_t *src, const int src_size, +static int xan_unpack_luma(XanContext *s, uint8_t *dst, const int dst_size) { int tree_size, eof; - const uint8_t *tree; int bits, mask; int tree_root, node; const uint8_t *dst_end = dst + dst_size; - const uint8_t *src_end = src + src_size; + GetByteContext tree = s->gb; + int start_off = bytestream2_tell(&tree); - tree_size = *src++; - eof = *src++; - tree = src - eof * 2 - 2; + tree_size = bytestream2_get_byte(&s->gb); + eof = bytestream2_get_byte(&s->gb); tree_root = eof + tree_size; - src += tree_size * 2; + bytestream2_skip(&s->gb, tree_size * 2); node = tree_root; - bits = *src++; + bits = bytestream2_get_byte(&s->gb); mask = 0x80; for (;;) { int bit = !!(bits & mask); mask >>= 1; - node = tree[node*2 + bit]; + bytestream2_seek(&tree, start_off + node*2 + bit - eof * 2, SEEK_SET); + node = bytestream2_get_byte(&tree); if (node == eof) break; if (node < eof) { @@ -90,50 +96,51 @@ static int xan_unpack_luma(const uint8_t *src, const int src_size, node = tree_root; } if (!mask) { - bits = *src++; - if (src > src_end) + if (bytestream2_get_bytes_left(&s->gb) <= 0) break; + bits = bytestream2_get_byteu(&s->gb); mask = 0x80; } } - return dst != dst_end; + return dst != dst_end ? AVERROR_INVALIDDATA : 0; } /* almost the same as in xan_wc3 decoder */ -static int xan_unpack(uint8_t *dest, const int dest_len, - const uint8_t *src, const int src_len) +static int xan_unpack(XanContext *s, + uint8_t *dest, const int dest_len) { uint8_t opcode; int size; uint8_t *orig_dest = dest; - const uint8_t *src_end = src + src_len; const uint8_t *dest_end = dest + dest_len; while (dest < dest_end) { - opcode = *src++; + if (bytestream2_get_bytes_left(&s->gb) <= 0) + return AVERROR_INVALIDDATA; + + opcode = bytestream2_get_byteu(&s->gb); if (opcode < 0xe0) { int size2, back; if ((opcode & 0x80) == 0) { size = opcode & 3; - back = ((opcode & 0x60) << 3) + *src++ + 1; + back = ((opcode & 0x60) << 3) + bytestream2_get_byte(&s->gb) + 1; size2 = ((opcode & 0x1c) >> 2) + 3; } else if ((opcode & 0x40) == 0) { - size = *src >> 6; - back = (bytestream_get_be16(&src) & 0x3fff) + 1; + size = bytestream2_peek_byte(&s->gb) >> 6; + back = (bytestream2_get_be16(&s->gb) & 0x3fff) + 1; size2 = (opcode & 0x3f) + 4; } else { size = opcode & 3; - back = ((opcode & 0x10) << 12) + bytestream_get_be16(&src) + 1; - size2 = ((opcode & 0x0c) << 6) + *src++ + 5; + back = ((opcode & 0x10) << 12) + bytestream2_get_be16(&s->gb) + 1; + size2 = ((opcode & 0x0c) << 6) + bytestream2_get_byte(&s->gb) + 5; if (size + size2 > dest_end - dest) break; } - if (src + size > src_end || - dest + size + size2 > dest_end || - dest + size - orig_dest < back ) + if (dest + size + size2 > dest_end || + dest - orig_dest + size < back) return -1; - bytestream_get_buffer(&src, dest, size); + bytestream2_get_buffer(&s->gb, dest, size); dest += size; av_memcpy_backptr(dest, back, size2); dest += size2; @@ -141,9 +148,9 @@ static int xan_unpack(uint8_t *dest, const int dest_len, int finish = opcode >= 0xfc; size = finish ? opcode & 3 : ((opcode & 0x1f) << 2) + 4; - if (src + size > src_end || dest + size > dest_end) + if (dest_end - dest < size) return -1; - bytestream_get_buffer(&src, dest, size); + bytestream2_get_buffer(&s->gb, dest, size); dest += size; if (finish) break; @@ -152,38 +159,37 @@ static int xan_unpack(uint8_t *dest, const int dest_len, return dest - orig_dest; } -static int xan_decode_chroma(AVCodecContext *avctx, AVPacket *avpkt) +static int xan_decode_chroma(AVCodecContext *avctx, unsigned chroma_off) { - const uint8_t *buf = avpkt->data; XanContext *s = avctx->priv_data; uint8_t *U, *V; - unsigned chroma_off; int val, uval, vval; int i, j; const uint8_t *src, *src_end; const uint8_t *table; - int mode, offset, dec_size; + int mode, offset, dec_size, table_size; - chroma_off = AV_RL32(buf + 4); if (!chroma_off) return 0; - if (chroma_off + 10 >= avpkt->size) { + if (chroma_off + 4 >= bytestream2_get_bytes_left(&s->gb)) { av_log(avctx, AV_LOG_ERROR, "Invalid chroma block position\n"); return -1; } - src = avpkt->data + 4 + chroma_off; - table = src + 2; - mode = bytestream_get_le16(&src); - offset = bytestream_get_le16(&src) * 2; + bytestream2_seek(&s->gb, chroma_off + 4, SEEK_SET); + mode = bytestream2_get_le16(&s->gb); + table = s->gb.buffer; + table_size = bytestream2_get_le16(&s->gb); + offset = table_size * 2; + table_size += 1; - if (src - avpkt->data >= avpkt->size - offset) { + if (offset >= bytestream2_get_bytes_left(&s->gb)) { av_log(avctx, AV_LOG_ERROR, "Invalid chroma block offset\n"); return -1; } + bytestream2_skip(&s->gb, offset); memset(s->scratch_buffer, 0, s->buffer_size); - dec_size = xan_unpack(s->scratch_buffer, s->buffer_size, src + offset, - avpkt->size - offset - (src - avpkt->data)); + dec_size = xan_unpack(s, s->scratch_buffer, s->buffer_size); if (dec_size < 0) { av_log(avctx, AV_LOG_ERROR, "Chroma unpacking failed\n"); return -1; @@ -199,7 +205,7 @@ static int xan_decode_chroma(AVCodecContext *avctx, AVPacket *avpkt) if (src_end - src < 1) return 0; val = *src++; - if (val) { + if (val && val < table_size) { val = AV_RL16(table + (val << 1)); uval = (val >> 3) & 0xF8; vval = (val >> 8) & 0xF8; @@ -219,7 +225,7 @@ static int xan_decode_chroma(AVCodecContext *avctx, AVPacket *avpkt) if (src_end - src < 1) return 0; val = *src++; - if (val) { + if (val && val < table_size) { val = AV_RL16(table + (val << 1)); uval = (val >> 3) & 0xF8; vval = (val >> 8) & 0xF8; @@ -237,32 +243,27 @@ static int xan_decode_chroma(AVCodecContext *avctx, AVPacket *avpkt) return 0; } -static int xan_decode_frame_type0(AVCodecContext *avctx, AVPacket *avpkt) +static int xan_decode_frame_type0(AVCodecContext *avctx) { - const uint8_t *buf = avpkt->data; XanContext *s = avctx->priv_data; uint8_t *ybuf, *prev_buf, *src = s->scratch_buffer; unsigned chroma_off, corr_off; - int cur, last, size; + int cur, last; int i, j; int ret; - corr_off = AV_RL32(buf + 8); - chroma_off = AV_RL32(buf + 4); + chroma_off = bytestream2_get_le32(&s->gb); + corr_off = bytestream2_get_le32(&s->gb); - if ((ret = xan_decode_chroma(avctx, avpkt)) != 0) + if ((ret = xan_decode_chroma(avctx, chroma_off)) != 0) return ret; - size = avpkt->size - 4; - if (corr_off >= avpkt->size) { + if (corr_off >= (s->gb.buffer_end - s->gb.buffer_start)) { av_log(avctx, AV_LOG_WARNING, "Ignoring invalid correction block position\n"); corr_off = 0; } - if (corr_off) - size = corr_off; - if (chroma_off) - size = FFMIN(size, chroma_off); - ret = xan_unpack_luma(buf + 12, size, src, s->buffer_size >> 1); + bytestream2_seek(&s->gb, 12, SEEK_SET); + ret = xan_unpack_luma(s, src, s->buffer_size >> 1); if (ret) { av_log(avctx, AV_LOG_ERROR, "Luma decoding failed\n"); return ret; @@ -298,12 +299,11 @@ static int xan_decode_frame_type0(AVCodecContext *avctx, AVPacket *avpkt) if (corr_off) { int corr_end, dec_size; - corr_end = avpkt->size; + corr_end = (s->gb.buffer_end - s->gb.buffer_start); if (chroma_off > corr_off) corr_end = chroma_off; - dec_size = xan_unpack(s->scratch_buffer, s->buffer_size, - avpkt->data + 8 + corr_off, - corr_end - corr_off); + bytestream2_seek(&s->gb, 8 + corr_off, SEEK_SET); + dec_size = xan_unpack(s, s->scratch_buffer, s->buffer_size / 2); if (dec_size < 0) dec_size = 0; else @@ -325,19 +325,19 @@ static int xan_decode_frame_type0(AVCodecContext *avctx, AVPacket *avpkt) return 0; } -static int xan_decode_frame_type1(AVCodecContext *avctx, AVPacket *avpkt) +static int xan_decode_frame_type1(AVCodecContext *avctx) { - const uint8_t *buf = avpkt->data; XanContext *s = avctx->priv_data; uint8_t *ybuf, *src = s->scratch_buffer; int cur, last; int i, j; int ret; - if ((ret = xan_decode_chroma(avctx, avpkt)) != 0) + if ((ret = xan_decode_chroma(avctx, bytestream2_get_le32(&s->gb))) != 0) return ret; - ret = xan_unpack_luma(buf + 16, avpkt->size - 16, src, + bytestream2_seek(&s->gb, 16, SEEK_SET); + ret = xan_unpack_luma(s, src, s->buffer_size >> 1); if (ret) { av_log(avctx, AV_LOG_ERROR, "Luma decoding failed\n"); @@ -387,13 +387,14 @@ static int xan_decode_frame(AVCodecContext *avctx, return ret; } - ftype = AV_RL32(avpkt->data); + bytestream2_init(&s->gb, avpkt->data, avpkt->size); + ftype = bytestream2_get_le32(&s->gb); switch (ftype) { case 0: - ret = xan_decode_frame_type0(avctx, avpkt); + ret = xan_decode_frame_type0(avctx); break; case 1: - ret = xan_decode_frame_type1(avctx, avpkt); + ret = xan_decode_frame_type1(avctx); break; default: av_log(avctx, AV_LOG_ERROR, "Unknown frame type %d\n", ftype); diff --git a/libavcodec/yop.c b/libavcodec/yop.c index e5333db2fd..edcc3fb6bb 100644 --- a/libavcodec/yop.c +++ b/libavcodec/yop.c @@ -26,6 +26,7 @@ #include "libavutil/imgutils.h" #include "avcodec.h" +#include "internal.h" #include "get_bits.h" typedef struct YopDecContext { @@ -89,6 +90,11 @@ static av_cold int yop_decode_init(AVCodecContext *avctx) return -1; } + if (!avctx->extradata) { + av_log(avctx, AV_LOG_ERROR, "extradata missing\n"); + return AVERROR_INVALIDDATA; + } + avctx->pix_fmt = PIX_FMT_PAL8; avcodec_get_frame_defaults(&s->frame); @@ -199,7 +205,12 @@ static int yop_decode_frame(AVCodecContext *avctx, void *data, int *data_size, if (s->frame.data[0]) avctx->release_buffer(avctx, &s->frame); - ret = avctx->get_buffer(avctx, &s->frame); + if (avpkt->size < 4 + 3*s->num_pal_colors) { + av_log(avctx, AV_LOG_ERROR, "packet of size %d too small\n", avpkt->size); + return AVERROR_INVALIDDATA; + } + + ret = ff_get_buffer(avctx, &s->frame); if (ret < 0) { av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n"); return ret; @@ -214,6 +225,10 @@ static int yop_decode_frame(AVCodecContext *avctx, void *data, int *data_size, s->low_nibble = NULL; is_odd_frame = avpkt->data[0]; + if(is_odd_frame>1){ + av_log(avctx, AV_LOG_ERROR, "frame is too odd %d\n", is_odd_frame); + return AVERROR_INVALIDDATA; + } firstcolor = s->first_color[is_odd_frame]; palette = (uint32_t *)s->frame.data[1]; diff --git a/libavcodec/zmbv.c b/libavcodec/zmbv.c index a68e42d789..1ac7274016 100644 --- a/libavcodec/zmbv.c +++ b/libavcodec/zmbv.c @@ -416,11 +416,16 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *data_size, AVPac } /* parse header */ + if (len < 1) + return AVERROR_INVALIDDATA; c->flags = buf[0]; buf++; len--; if (c->flags & ZMBV_KEYFRAME) { void *decode_intra = NULL; c->decode_intra= NULL; + + if (len < 6) + return AVERROR_INVALIDDATA; hi_ver = buf[0]; lo_ver = buf[1]; c->comp = buf[2]; @@ -500,10 +505,13 @@ static int decode_frame(AVCodecContext *avctx, void *data, int *data_size, AVPac return -1; } - if (c->comp == 0) { //Uncompressed data - memcpy(c->decomp_buf, buf, len); - c->decomp_size = 1; - } else { // ZLIB-compressed data + if (c->comp == 0) { //Uncompressed data + if (c->decomp_size < len) { + av_log(avctx, AV_LOG_ERROR, "Buffer too small\n"); + return AVERROR_INVALIDDATA; + } + memcpy(c->decomp_buf, buf, len); + } else { // ZLIB-compressed data c->zstream.total_in = c->zstream.total_out = 0; c->zstream.next_in = buf; c->zstream.avail_in = len; diff --git a/libavfilter/Makefile b/libavfilter/Makefile index 01a1316434..82407e2593 100644 --- a/libavfilter/Makefile +++ b/libavfilter/Makefile @@ -85,6 +85,7 @@ OBJS-$(CONFIG_SETTB_FILTER) += vf_settb.o OBJS-$(CONFIG_SHOWINFO_FILTER) += vf_showinfo.o OBJS-$(CONFIG_SLICIFY_FILTER) += vf_slicify.o OBJS-$(CONFIG_SPLIT_FILTER) += vf_split.o +OBJS-$(CONFIG_SWAPUV_FILTER) += vf_swapuv.o OBJS-$(CONFIG_THUMBNAIL_FILTER) += vf_thumbnail.o OBJS-$(CONFIG_TINTERLACE_FILTER) += vf_tinterlace.o OBJS-$(CONFIG_TRANSPOSE_FILTER) += vf_transpose.o diff --git a/libavfilter/allfilters.c b/libavfilter/allfilters.c index 8286d4d21b..ef99298cb6 100644 --- a/libavfilter/allfilters.c +++ b/libavfilter/allfilters.c @@ -93,6 +93,7 @@ void avfilter_register_all(void) REGISTER_FILTER (SHOWINFO, showinfo, vf); REGISTER_FILTER (SLICIFY, slicify, vf); REGISTER_FILTER (SPLIT, split, vf); + REGISTER_FILTER (SWAPUV, swapuv, vf); REGISTER_FILTER (THUMBNAIL, thumbnail, vf); REGISTER_FILTER (TINTERLACE, tinterlace, vf); REGISTER_FILTER (TRANSPOSE, transpose, vf); diff --git a/libavfilter/asrc_aevalsrc.c b/libavfilter/asrc_aevalsrc.c index 7bd6a89eb3..63fe9164b4 100644 --- a/libavfilter/asrc_aevalsrc.c +++ b/libavfilter/asrc_aevalsrc.c @@ -95,6 +95,12 @@ static int init(AVFilterContext *ctx, const char *args, void *opaque) eval->class = &eval_class; av_opt_set_defaults(eval); + if (!args1) { + av_log(ctx, AV_LOG_ERROR, "Argument is empty\n"); + ret = args ? AVERROR(ENOMEM) : AVERROR(EINVAL); + goto end; + } + /* parse expressions */ buf = args1; i = 0; diff --git a/libavfilter/avfilter.c b/libavfilter/avfilter.c index 706f7e2694..ef54c7c23a 100644 --- a/libavfilter/avfilter.c +++ b/libavfilter/avfilter.c @@ -176,9 +176,9 @@ void avfilter_insert_pad(unsigned idx, unsigned *count, size_t padidx_off, (*links)[idx] = NULL; (*count)++; - for (i = idx+1; i < *count; i++) - if (*links[i]) - (*(unsigned *)((uint8_t *) *links[i] + padidx_off))++; + for (i = idx + 1; i < *count; i++) + if ((*links)[i]) + (*(unsigned *)((uint8_t *) (*links)[i] + padidx_off))++; } int avfilter_link(AVFilterContext *src, unsigned srcpad, diff --git a/libavfilter/avfiltergraph.c b/libavfilter/avfiltergraph.c index c97e495c96..ef13443950 100644 --- a/libavfilter/avfiltergraph.c +++ b/libavfilter/avfiltergraph.c @@ -24,6 +24,7 @@ #include #include "libavutil/audioconvert.h" +#include "libavutil/avstring.h" #include "avfilter.h" #include "avfiltergraph.h" #include "internal.h" @@ -202,6 +203,7 @@ static int query_formats(AVFilterGraph *graph, AVClass *log_ctx) for (j = 0; j < filter->input_count; j++) { AVFilterLink *link = filter->inputs[j]; + if (!link) continue; if (!link->in_formats || !link->out_formats) @@ -211,8 +213,12 @@ static int query_formats(AVFilterGraph *graph, AVClass *log_ctx) !avfilter_merge_formats(link->in_formats, link->out_formats)) { /* couldn't merge format lists, auto-insert scale filter */ - snprintf(filt_args, sizeof(filt_args), "0:0:%s", - graph->scale_sws_opts); + av_strlcpy(filt_args, "0:0", sizeof(filt_args)); + if (graph->scale_sws_opts) { + av_strlcat(filt_args, ":", sizeof(filt_args)); + av_strlcat(filt_args, graph->scale_sws_opts, sizeof(filt_args)); + } + if (ret = insert_conv_filter(graph, link, "scale", filt_args)) return ret; } diff --git a/libavfilter/formats.c b/libavfilter/formats.c index fa2c1be4bb..bde3b0cf06 100644 --- a/libavfilter/formats.c +++ b/libavfilter/formats.c @@ -49,6 +49,9 @@ AVFilterFormats *avfilter_merge_formats(AVFilterFormats *a, AVFilterFormats *b) if (a == b) return a; + if (a == b) + return a; + ret = av_mallocz(sizeof(AVFilterFormats)); /* merge list of formats */ diff --git a/libavfilter/graphparser.c b/libavfilter/graphparser.c index bd3022e035..f0441a308e 100644 --- a/libavfilter/graphparser.c +++ b/libavfilter/graphparser.c @@ -121,7 +121,8 @@ static int create_filter(AVFilterContext **filt_ctx, AVFilterGraph *ctx, int ind return ret; } - if (!strcmp(filt_name, "scale") && args && !strstr(args, "flags")) { + if (!strcmp(filt_name, "scale") && args && !strstr(args, "flags") && + ctx->scale_sws_opts) { snprintf(tmp_args, sizeof(tmp_args), "%s:%s", args, ctx->scale_sws_opts); args = tmp_args; diff --git a/libavfilter/version.h b/libavfilter/version.h index 60e496dcc0..cd8bd95037 100644 --- a/libavfilter/version.h +++ b/libavfilter/version.h @@ -29,7 +29,7 @@ #include "libavutil/avutil.h" #define LIBAVFILTER_VERSION_MAJOR 2 -#define LIBAVFILTER_VERSION_MINOR 60 +#define LIBAVFILTER_VERSION_MINOR 61 #define LIBAVFILTER_VERSION_MICRO 100 #define LIBAVFILTER_VERSION_INT AV_VERSION_INT(LIBAVFILTER_VERSION_MAJOR, \ diff --git a/libavfilter/vf_deshake.c b/libavfilter/vf_deshake.c index bb20551bc9..bf605d37ff 100644 --- a/libavfilter/vf_deshake.c +++ b/libavfilter/vf_deshake.c @@ -315,8 +315,8 @@ static void find_motion(DeshakeContext *deshake, uint8_t *src1, uint8_t *src2, //av_log(NULL, AV_LOG_ERROR, "\n"); } - p_x = (center_x - width / 2); - p_y = (center_y - height / 2); + p_x = (center_x - width / 2.0); + p_y = (center_y - height / 2.0); t->vector.x += (cos(t->angle)-1)*p_x - sin(t->angle)*p_y; t->vector.y += sin(t->angle)*p_x + (cos(t->angle)-1)*p_y; diff --git a/libavfilter/vf_drawtext.c b/libavfilter/vf_drawtext.c index d0d854b994..b31d2e256c 100644 --- a/libavfilter/vf_drawtext.c +++ b/libavfilter/vf_drawtext.c @@ -47,7 +47,6 @@ #undef time #include -#include #include FT_FREETYPE_H #include FT_GLYPH_H diff --git a/libavfilter/vf_fade.c b/libavfilter/vf_fade.c index 7fe0dae3f4..3bde5ddefd 100644 --- a/libavfilter/vf_fade.c +++ b/libavfilter/vf_fade.c @@ -103,14 +103,14 @@ static av_cold int init(AVFilterContext *ctx, const char *args, void *opaque) if ((ret = av_opt_set(fade, "start_frame", expr, 0)) < 0) { av_log(ctx, AV_LOG_ERROR, "Invalid value '%s' for start_frame option\n", expr); - return ret; + goto end; } } if (expr = av_strtok(NULL, ":", &bufptr)) { if ((ret = av_opt_set(fade, "nb_frames", expr, 0)) < 0) { av_log(ctx, AV_LOG_ERROR, "Invalid value '%s' for nb_frames option\n", expr); - return ret; + goto end; } } @@ -191,9 +191,9 @@ static int config_props(AVFilterLink *inlink) fade->alpha = fade->alpha ? ff_fmt_is_in(inlink->format, alpha_pix_fmts) : 0; fade->is_packed_rgb = ff_fill_rgba_map(fade->rgba_map, inlink->format) >= 0; - /* CCIR601/709 black level unless input is RGB or has alpha */ + /* use CCIR601/709 black level for studio-level pixel non-alpha components */ fade->black_level = - ff_fmt_is_in(inlink->format, studio_level_pix_fmts) || fade->alpha ? 0 : 16; + ff_fmt_is_in(inlink->format, studio_level_pix_fmts) && !fade->alpha ? 16 : 0; /* 32768 = 1 << 15, it is an integer representation * of 0.5 and is for rounding. */ fade->black_level_scaled = (fade->black_level << 16) + 32768; diff --git a/libavfilter/vf_gradfun.c b/libavfilter/vf_gradfun.c index 8f8b028e1d..01fb99120c 100644 --- a/libavfilter/vf_gradfun.c +++ b/libavfilter/vf_gradfun.c @@ -113,6 +113,7 @@ static void filter(GradFunContext *ctx, uint8_t *dst, const uint8_t *src, int wi ctx->filter_line(dst + y * dst_linesize, src + y * src_linesize, dc - r / 2, width, thresh, dither[y & 7]); if (++y >= height) break; } + emms_c(); } static av_cold int init(AVFilterContext *ctx, const char *args, void *opaque) diff --git a/libavfilter/vf_pad.c b/libavfilter/vf_pad.c index 1634f789f0..6f95109f94 100644 --- a/libavfilter/vf_pad.c +++ b/libavfilter/vf_pad.c @@ -151,9 +151,9 @@ static int config_input(AVFilterLink *inlink) var_values[VAR_IN_H] = var_values[VAR_IH] = inlink->h; var_values[VAR_OUT_W] = var_values[VAR_OW] = NAN; var_values[VAR_OUT_H] = var_values[VAR_OH] = NAN; - var_values[VAR_A] = (float) inlink->w / inlink->h; + var_values[VAR_A] = (double) inlink->w / inlink->h; var_values[VAR_SAR] = inlink->sample_aspect_ratio.num ? - (float) inlink->sample_aspect_ratio.num / inlink->sample_aspect_ratio.den : 1; + (double) inlink->sample_aspect_ratio.num / inlink->sample_aspect_ratio.den : 1; var_values[VAR_DAR] = var_values[VAR_A] * var_values[VAR_SAR]; var_values[VAR_HSUB] = 1<hsub; var_values[VAR_VSUB] = 1<vsub; @@ -299,6 +299,7 @@ static void start_frame(AVFilterLink *inlink, AVFilterBufferRef *inpicref) { PadContext *pad = inlink->dst->priv; AVFilterBufferRef *outpicref = avfilter_ref_buffer(inpicref, ~0); + AVFilterBufferRef *for_next_filter; int plane; for (plane = 0; plane < 4 && outpicref->data[plane]; plane++) { @@ -335,12 +336,14 @@ static void start_frame(AVFilterLink *inlink, AVFilterBufferRef *inpicref) outpicref->video->w = pad->w; outpicref->video->h = pad->h; - avfilter_start_frame(inlink->dst->outputs[0], outpicref); + for_next_filter = avfilter_ref_buffer(outpicref, ~0); + avfilter_start_frame(inlink->dst->outputs[0], for_next_filter); } static void end_frame(AVFilterLink *link) { avfilter_end_frame(link->dst->outputs[0]); + avfilter_unref_buffer(link->dst->outputs[0]->out_buf); avfilter_unref_buffer(link->cur_buf); } diff --git a/libavfilter/vf_scale.c b/libavfilter/vf_scale.c index 5bca9fc184..890b685f87 100644 --- a/libavfilter/vf_scale.c +++ b/libavfilter/vf_scale.c @@ -154,9 +154,11 @@ static int config_props(AVFilterLink *outlink) var_values[VAR_IN_H] = var_values[VAR_IH] = inlink->h; var_values[VAR_OUT_W] = var_values[VAR_OW] = NAN; var_values[VAR_OUT_H] = var_values[VAR_OH] = NAN; - var_values[VAR_A] = (float) inlink->w / inlink->h; + var_values[VAR_A] = (double) inlink->w / inlink->h; + var_values[VAR_SAR] = inlink->sample_aspect_ratio.num ? - (float) inlink->sample_aspect_ratio.num / inlink->sample_aspect_ratio.den : 1; + + (double) inlink->sample_aspect_ratio.num / inlink->sample_aspect_ratio.den : 1; var_values[VAR_DAR] = var_values[VAR_A] * var_values[VAR_SAR]; var_values[VAR_HSUB] = 1<format].log2_chroma_w; var_values[VAR_VSUB] = 1<format].log2_chroma_h; diff --git a/libavfilter/vf_select.c b/libavfilter/vf_select.c index 5cbe663ea1..3d92b4e7a2 100644 --- a/libavfilter/vf_select.c +++ b/libavfilter/vf_select.c @@ -187,19 +187,6 @@ static int select_frame(AVFilterContext *ctx, AVFilterBufferRef *picref) select->var_values[VAR_PICT_TYPE] = picref->video->pict_type; res = av_expr_eval(select->expr, select->var_values, NULL); - av_log(inlink->dst, AV_LOG_DEBUG, - "n:%d pts:%d t:%f pos:%d interlace_type:%c key:%d pict_type:%c " - "-> select:%f\n", - (int)select->var_values[VAR_N], - (int)select->var_values[VAR_PTS], - select->var_values[VAR_T], - (int)select->var_values[VAR_POS], - select->var_values[VAR_INTERLACE_TYPE] == INTERLACE_TYPE_P ? 'P' : - select->var_values[VAR_INTERLACE_TYPE] == INTERLACE_TYPE_T ? 'T' : - select->var_values[VAR_INTERLACE_TYPE] == INTERLACE_TYPE_B ? 'B' : '?', - (int)select->var_values[VAR_KEY], - av_get_picture_type_char(select->var_values[VAR_PICT_TYPE]), - res); select->var_values[VAR_N] += 1.0; diff --git a/libavfilter/vf_swapuv.c b/libavfilter/vf_swapuv.c new file mode 100644 index 0000000000..317485b2f9 --- /dev/null +++ b/libavfilter/vf_swapuv.c @@ -0,0 +1,93 @@ +/* + * Copyright (c) 2002 Michael Niedermayer + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/** + * @file + * swap UV filter + */ + +#include "avfilter.h" + +static AVFilterBufferRef *get_video_buffer(AVFilterLink *link, int perms, + int w, int h) +{ + AVFilterBufferRef *picref = + avfilter_default_get_video_buffer(link, perms, w, h); + uint8_t *tmp; + int tmp2; + + tmp = picref->data[2]; + picref->data[2] = picref->data[1]; + picref->data[1] = tmp; + + tmp2 = picref->linesize[2]; + picref->linesize[2] = picref->linesize[1]; + picref->linesize[1] = tmp2; + + return picref; +} + +static void start_frame(AVFilterLink *link, AVFilterBufferRef *inpicref) +{ + AVFilterBufferRef *outpicref = avfilter_ref_buffer(inpicref, ~0); + + outpicref->data[1] = inpicref->data[2]; + outpicref->data[2] = inpicref->data[1]; + + outpicref->linesize[1] = inpicref->linesize[2]; + outpicref->linesize[2] = inpicref->linesize[1]; + + avfilter_start_frame(link->dst->outputs[0], outpicref); +} + +static int query_formats(AVFilterContext *ctx) +{ + static const enum PixelFormat pix_fmts[] = { + PIX_FMT_YUV420P, PIX_FMT_YUVJ420P, PIX_FMT_YUVA420P, + PIX_FMT_YUV444P, PIX_FMT_YUVJ444P, + PIX_FMT_YUV440P, PIX_FMT_YUVJ440P, + PIX_FMT_YUV422P, PIX_FMT_YUVJ422P, + PIX_FMT_YUV411P, + PIX_FMT_NONE, + }; + + avfilter_set_common_pixel_formats(ctx, avfilter_make_format_list(pix_fmts)); + return 0; +} + +AVFilter avfilter_vf_swapuv = { + .name = "swapuv", + .description = NULL_IF_CONFIG_SMALL("Swap U and V components."), + .priv_size = 0, + .query_formats = query_formats, + + .inputs = (const AVFilterPad[]) { + { .name = "default", + .type = AVMEDIA_TYPE_VIDEO, + .get_video_buffer = get_video_buffer, + .start_frame = start_frame, }, + { .name = NULL } + }, + .outputs = (const AVFilterPad[]) { + { .name = "default", + .type = AVMEDIA_TYPE_VIDEO, }, + { .name = NULL } + }, +}; diff --git a/libavformat/4xm.c b/libavformat/4xm.c index 3d9c5aea12..c8eb0c0d1f 100644 --- a/libavformat/4xm.c +++ b/libavformat/4xm.c @@ -129,6 +129,10 @@ static int fourxm_read_header(AVFormatContext *s, for (i = 0; i < header_size - 8; i++) { fourcc_tag = AV_RL32(&header[i]); size = AV_RL32(&header[i + 4]); + if (size > header_size - i - 8 && (fourcc_tag == vtrk_TAG || fourcc_tag == strk_TAG)) { + av_log(s, AV_LOG_ERROR, "chunk larger than array %d>%d\n", size, header_size - i - 8); + return AVERROR_INVALIDDATA; + } if (fourcc_tag == std__TAG) { fourxm->fps = av_int2float(AV_RL32(&header[i + 12])); @@ -197,6 +201,11 @@ static int fourxm_read_header(AVFormatContext *s, ret= -1; goto fail; } + if(!fourxm->tracks[current_track].adpcm && fourxm->tracks[current_track].bits<8){ + av_log(s, AV_LOG_ERROR, "bits unspecified for non ADPCM\n"); + ret = AVERROR_INVALIDDATA; + goto fail; + } i += 8 + size; /* allocate a new AVStream */ diff --git a/libavformat/Makefile b/libavformat/Makefile index 623cd65234..bd2b17b6cd 100644 --- a/libavformat/Makefile +++ b/libavformat/Makefile @@ -12,6 +12,7 @@ OBJS = allformats.o \ metadata.o \ options.o \ os_support.o \ + riff.o \ sdp.o \ seek.o \ utils.o \ @@ -29,8 +30,8 @@ OBJS-$(CONFIG_ADX_DEMUXER) += adxdec.o OBJS-$(CONFIG_ADX_MUXER) += rawenc.o OBJS-$(CONFIG_ADTS_MUXER) += adtsenc.o OBJS-$(CONFIG_AEA_DEMUXER) += aea.o pcm.o -OBJS-$(CONFIG_AIFF_DEMUXER) += aiffdec.o riff.o pcm.o isom.o -OBJS-$(CONFIG_AIFF_MUXER) += aiffenc.o riff.o isom.o +OBJS-$(CONFIG_AIFF_DEMUXER) += aiffdec.o pcm.o isom.o +OBJS-$(CONFIG_AIFF_MUXER) += aiffenc.o isom.o OBJS-$(CONFIG_AMR_DEMUXER) += amr.o OBJS-$(CONFIG_AMR_MUXER) += amr.o OBJS-$(CONFIG_ANM_DEMUXER) += anm.o @@ -38,14 +39,14 @@ OBJS-$(CONFIG_APC_DEMUXER) += apc.o OBJS-$(CONFIG_APE_DEMUXER) += ape.o apetag.o OBJS-$(CONFIG_APPLEHTTP_DEMUXER) += applehttp.o OBJS-$(CONFIG_ASF_DEMUXER) += asfdec.o asf.o asfcrypt.o \ - riff.o avlanguage.o -OBJS-$(CONFIG_ASF_MUXER) += asfenc.o asf.o riff.o + avlanguage.o +OBJS-$(CONFIG_ASF_MUXER) += asfenc.o asf.o OBJS-$(CONFIG_ASS_DEMUXER) += assdec.o OBJS-$(CONFIG_ASS_MUXER) += assenc.o OBJS-$(CONFIG_AU_DEMUXER) += au.o pcm.o OBJS-$(CONFIG_AU_MUXER) += au.o -OBJS-$(CONFIG_AVI_DEMUXER) += avidec.o riff.o -OBJS-$(CONFIG_AVI_MUXER) += avienc.o riff.o +OBJS-$(CONFIG_AVI_DEMUXER) += avidec.o +OBJS-$(CONFIG_AVI_MUXER) += avienc.o OBJS-$(CONFIG_AVISYNTH) += avisynth.o OBJS-$(CONFIG_AVM2_MUXER) += swfenc.o OBJS-$(CONFIG_AVS_DEMUXER) += avs.o vocdec.o voc.o @@ -58,7 +59,7 @@ OBJS-$(CONFIG_BIT_MUXER) += bit.o OBJS-$(CONFIG_BMV_DEMUXER) += bmv.o OBJS-$(CONFIG_C93_DEMUXER) += c93.o vocdec.o voc.o OBJS-$(CONFIG_CAF_DEMUXER) += cafdec.o caf.o mov.o mov_chan.o \ - riff.o isom.o + isom.o OBJS-$(CONFIG_CAF_MUXER) += cafenc.o caf.o riff.o isom.o OBJS-$(CONFIG_CAVSVIDEO_DEMUXER) += cavsvideodec.o rawdec.o OBJS-$(CONFIG_CAVSVIDEO_MUXER) += rawenc.o @@ -76,7 +77,7 @@ OBJS-$(CONFIG_DTS_DEMUXER) += dtsdec.o rawdec.o OBJS-$(CONFIG_DTS_MUXER) += rawenc.o OBJS-$(CONFIG_DV_DEMUXER) += dv.o OBJS-$(CONFIG_DV_MUXER) += dvenc.o -OBJS-$(CONFIG_DXA_DEMUXER) += dxa.o riff.o +OBJS-$(CONFIG_DXA_DEMUXER) += dxa.o OBJS-$(CONFIG_EA_CDATA_DEMUXER) += eacdata.o OBJS-$(CONFIG_EA_DEMUXER) += electronicarts.o OBJS-$(CONFIG_EAC3_DEMUXER) += ac3dec.o rawdec.o @@ -125,7 +126,7 @@ OBJS-$(CONFIG_INGENIENT_DEMUXER) += ingenientdec.o rawdec.o OBJS-$(CONFIG_IPMOVIE_DEMUXER) += ipmovie.o OBJS-$(CONFIG_ISS_DEMUXER) += iss.o OBJS-$(CONFIG_IV8_DEMUXER) += iv8.o -OBJS-$(CONFIG_IVF_DEMUXER) += ivfdec.o riff.o +OBJS-$(CONFIG_IVF_DEMUXER) += ivfdec.o OBJS-$(CONFIG_IVF_MUXER) += ivfenc.o OBJS-$(CONFIG_JV_DEMUXER) += jvdec.o OBJS-$(CONFIG_LATM_DEMUXER) += rawdec.o @@ -136,9 +137,9 @@ OBJS-$(CONFIG_LXF_DEMUXER) += lxfdec.o OBJS-$(CONFIG_M4V_DEMUXER) += m4vdec.o rawdec.o OBJS-$(CONFIG_M4V_MUXER) += rawenc.o OBJS-$(CONFIG_MATROSKA_DEMUXER) += matroskadec.o matroska.o \ - riff.o isom.o rmdec.o rm.o + isom.o rmdec.o rm.o OBJS-$(CONFIG_MATROSKA_MUXER) += matroskaenc.o matroska.o \ - riff.o isom.o avc.o \ + isom.o avc.o \ flacenc_header.o avlanguage.o OBJS-$(CONFIG_MD5_MUXER) += md5enc.o OBJS-$(CONFIG_MICRODVD_DEMUXER) += microdvddec.o @@ -149,9 +150,9 @@ OBJS-$(CONFIG_MLP_DEMUXER) += rawdec.o OBJS-$(CONFIG_MLP_MUXER) += rawenc.o OBJS-$(CONFIG_MM_DEMUXER) += mm.o OBJS-$(CONFIG_MMF_DEMUXER) += mmf.o pcm.o -OBJS-$(CONFIG_MMF_MUXER) += mmf.o riff.o -OBJS-$(CONFIG_MOV_DEMUXER) += mov.o riff.o isom.o mov_chan.o -OBJS-$(CONFIG_MOV_MUXER) += movenc.o riff.o isom.o avc.o \ +OBJS-$(CONFIG_MMF_MUXER) += mmf.o +OBJS-$(CONFIG_MOV_DEMUXER) += mov.o isom.o mov_chan.o +OBJS-$(CONFIG_MOV_MUXER) += movenc.o isom.o avc.o \ movenchint.o rtpenc_chain.o \ mov_chan.o OBJS-$(CONFIG_MP2_MUXER) += mp3enc.o rawenc.o @@ -180,9 +181,9 @@ OBJS-$(CONFIG_MXG_DEMUXER) += mxg.o OBJS-$(CONFIG_NC_DEMUXER) += ncdec.o OBJS-$(CONFIG_NSV_DEMUXER) += nsvdec.o OBJS-$(CONFIG_NULL_MUXER) += nullenc.o -OBJS-$(CONFIG_NUT_DEMUXER) += nutdec.o nut.o riff.o -OBJS-$(CONFIG_NUT_MUXER) += nutenc.o nut.o riff.o -OBJS-$(CONFIG_NUV_DEMUXER) += nuv.o riff.o +OBJS-$(CONFIG_NUT_DEMUXER) += nutdec.o nut.o +OBJS-$(CONFIG_NUT_MUXER) += nutenc.o nut.o +OBJS-$(CONFIG_NUV_DEMUXER) += nuv.o OBJS-$(CONFIG_OGG_DEMUXER) += oggdec.o \ oggparsecelt.o \ oggparsedirac.o \ @@ -192,7 +193,6 @@ OBJS-$(CONFIG_OGG_DEMUXER) += oggdec.o \ oggparsespeex.o \ oggparsetheora.o \ oggparsevorbis.o \ - riff.o \ vorbiscomment.o OBJS-$(CONFIG_OGG_MUXER) += oggenc.o \ vorbiscomment.o @@ -319,31 +319,31 @@ OBJS-$(CONFIG_VMD_DEMUXER) += sierravmd.o OBJS-$(CONFIG_VOC_DEMUXER) += vocdec.o voc.o OBJS-$(CONFIG_VOC_MUXER) += vocenc.o voc.o OBJS-$(CONFIG_VQF_DEMUXER) += vqf.o -OBJS-$(CONFIG_W64_DEMUXER) += wav.o riff.o pcm.o -OBJS-$(CONFIG_WAV_DEMUXER) += wav.o riff.o pcm.o -OBJS-$(CONFIG_WAV_MUXER) += wav.o riff.o +OBJS-$(CONFIG_W64_DEMUXER) += wav.o pcm.o +OBJS-$(CONFIG_WAV_DEMUXER) += wav.o pcm.o +OBJS-$(CONFIG_WAV_MUXER) += wav.o OBJS-$(CONFIG_WC3_DEMUXER) += wc3movie.o OBJS-$(CONFIG_WEBM_MUXER) += matroskaenc.o matroska.o \ - riff.o isom.o avc.o \ + isom.o avc.o \ flacenc_header.o avlanguage.o OBJS-$(CONFIG_WSAUD_DEMUXER) += westwood_aud.o OBJS-$(CONFIG_WSVQA_DEMUXER) += westwood_vqa.o OBJS-$(CONFIG_WTV_DEMUXER) += wtvdec.o wtv.o asfdec.o asf.o asfcrypt.o \ - avlanguage.o mpegts.o isom.o riff.o -OBJS-$(CONFIG_WTV_MUXER) += wtvenc.o wtv.o asf.o asfenc.o riff.o + avlanguage.o mpegts.o isom.o +OBJS-$(CONFIG_WTV_MUXER) += wtvenc.o wtv.o asf.o asfenc.o OBJS-$(CONFIG_WV_DEMUXER) += wv.o apetag.o OBJS-$(CONFIG_XA_DEMUXER) += xa.o OBJS-$(CONFIG_XBIN_DEMUXER) += bintext.o sauce.o -OBJS-$(CONFIG_XMV_DEMUXER) += xmv.o riff.o -OBJS-$(CONFIG_XWMA_DEMUXER) += xwma.o riff.o +OBJS-$(CONFIG_XMV_DEMUXER) += xmv.o +OBJS-$(CONFIG_XWMA_DEMUXER) += xwma.o OBJS-$(CONFIG_YOP_DEMUXER) += yop.o OBJS-$(CONFIG_YUV4MPEGPIPE_MUXER) += yuv4mpeg.o OBJS-$(CONFIG_YUV4MPEGPIPE_DEMUXER) += yuv4mpeg.o # external libraries OBJS-$(CONFIG_LIBMODPLUG_DEMUXER) += libmodplug.o -OBJS-$(CONFIG_LIBNUT_DEMUXER) += libnut.o riff.o -OBJS-$(CONFIG_LIBNUT_MUXER) += libnut.o riff.o +OBJS-$(CONFIG_LIBNUT_DEMUXER) += libnut.o +OBJS-$(CONFIG_LIBNUT_MUXER) += libnut.o # protocols I/O OBJS+= avio.o aviobuf.o diff --git a/libavformat/adxdec.c b/libavformat/adxdec.c index ab11d832d8..021042c608 100644 --- a/libavformat/adxdec.c +++ b/libavformat/adxdec.c @@ -41,6 +41,11 @@ static int adx_read_packet(AVFormatContext *s, AVPacket *pkt) AVCodecContext *avctx = s->streams[0]->codec; int ret, size; + if (avctx->channels <= 0) { + av_log(s, AV_LOG_ERROR, "invalid number of channels %d\n", avctx->channels); + return AVERROR_INVALIDDATA; + } + size = BLOCK_SIZE * avctx->channels; pkt->pos = avio_tell(s->pb); diff --git a/libavformat/aiffdec.c b/libavformat/aiffdec.c index e33bd57b7f..156016279b 100644 --- a/libavformat/aiffdec.c +++ b/libavformat/aiffdec.c @@ -271,12 +271,12 @@ static int aiff_read_header(AVFormatContext *s, } } +got_sound: if (!st->codec->block_align) { - av_log(s, AV_LOG_ERROR, "could not find COMM tag\n"); + av_log(s, AV_LOG_ERROR, "could not find COMM tag or invalid block_align value\n"); return -1; } -got_sound: /* Now positioned, get the sound data start and end */ avpriv_set_pts_info(st, 64, 1, st->codec->sample_rate); st->start_time = 0; diff --git a/libavformat/ape.c b/libavformat/ape.c index 72fca5dd46..d345382202 100644 --- a/libavformat/ape.c +++ b/libavformat/ape.c @@ -255,7 +255,7 @@ static int ape_read_header(AVFormatContext * s, AVFormatParameters * ap) ape->totalframes); return -1; } - if (ape->seektablelength && (ape->seektablelength / sizeof(*ape->seektable)) < ape->totalframes) { + if (ape->seektablelength / sizeof(*ape->seektable) < ape->totalframes) { av_log(s, AV_LOG_ERROR, "Number of seek entries is less than number of frames: %zu vs. %"PRIu32"\n", ape->seektablelength / sizeof(*ape->seektable), ape->totalframes); @@ -276,8 +276,13 @@ static int ape_read_header(AVFormatContext * s, AVFormatParameters * ap) ape->seektable = av_malloc(ape->seektablelength); if (!ape->seektable) return AVERROR(ENOMEM); - for (i = 0; i < ape->seektablelength / sizeof(uint32_t); i++) + for (i = 0; + i < ape->seektablelength / sizeof(uint32_t) && !pb->eof_reached; + i++) ape->seektable[i] = avio_rl32(pb); + }else{ + av_log(s, AV_LOG_ERROR, "Missing seektable\n"); + return -1; } ape->frames[0].pos = ape->firstframe; diff --git a/libavformat/apetag.c b/libavformat/apetag.c index 8d53e4cdf7..847b41294a 100644 --- a/libavformat/apetag.c +++ b/libavformat/apetag.c @@ -51,8 +51,10 @@ static int ape_tag_read_field(AVFormatContext *s) av_log(s, AV_LOG_WARNING, "Invalid APE tag key '%s'.\n", key); return -1; } - if (size >= UINT_MAX) - return -1; + if (size > INT32_MAX - FF_INPUT_BUFFER_PADDING_SIZE) { + av_log(s, AV_LOG_ERROR, "APE tag size too large.\n"); + return AVERROR_INVALIDDATA; + } value = av_malloc(size+1); if (!value) return AVERROR(ENOMEM); @@ -65,7 +67,7 @@ static int ape_tag_read_field(AVFormatContext *s) void ff_ape_parse_tag(AVFormatContext *s) { AVIOContext *pb = s->pb; - int file_size = avio_size(pb); + int64_t file_size = avio_size(pb); uint32_t val, fields, tag_bytes; uint8_t buf[8]; int i; diff --git a/libavformat/asfdec.c b/libavformat/asfdec.c index 2aec02c938..9ae0d43c87 100644 --- a/libavformat/asfdec.c +++ b/libavformat/asfdec.c @@ -199,6 +199,8 @@ static int asf_read_file_properties(AVFormatContext *s, int64_t size) asf->hdr.flags = avio_rl32(pb); asf->hdr.min_pktsize = avio_rl32(pb); asf->hdr.max_pktsize = avio_rl32(pb); + if (asf->hdr.min_pktsize >= (1U<<29)) + return AVERROR_INVALIDDATA; asf->hdr.max_bitrate = avio_rl32(pb); s->packet_size = asf->hdr.max_pktsize; @@ -612,9 +614,13 @@ static int asf_read_header(AVFormatContext *s, AVFormatParameters *ap) if (gsize < 24) return -1; if (!ff_guidcmp(&g, &ff_asf_file_header)) { - asf_read_file_properties(s, gsize); + int ret = asf_read_file_properties(s, gsize); + if (ret < 0) + return ret; } else if (!ff_guidcmp(&g, &ff_asf_stream_header)) { - asf_read_stream_properties(s, gsize); + int ret = asf_read_stream_properties(s, gsize); + if (ret < 0) + return ret; } else if (!ff_guidcmp(&g, &ff_asf_comment_header)) { asf_read_content_desc(s, gsize); } else if (!ff_guidcmp(&g, &ff_asf_language_guid)) { @@ -797,6 +803,13 @@ static int ff_asf_get_packet(AVFormatContext *s, AVIOContext *pb) asf->packet_segments = 1; asf->packet_segsizetype = 0x80; } + if (rsize > packet_length - padsize) { + asf->packet_size_left = 0; + av_log(s, AV_LOG_ERROR, + "invalid packet header length %d for pktlen %d-%d at %"PRId64"\n", + rsize, packet_length, padsize, avio_tell(pb)); + return -1; + } asf->packet_size_left = packet_length - padsize - rsize; if (packet_length < asf->hdr.min_pktsize) padsize += asf->hdr.min_pktsize - packet_length; @@ -1089,6 +1102,8 @@ static int ff_asf_parse_packet(AVFormatContext *s, AVIOContext *pb, AVPacket *pk //printf("packet %d %d\n", asf_st->pkt.size, asf->packet_frag_size); asf_st->pkt.size = 0; asf_st->pkt.data = 0; + asf_st->pkt.side_data_elems = 0; + asf_st->pkt.side_data = NULL; break; // packet completed } } diff --git a/libavformat/asfenc.c b/libavformat/asfenc.c index a287ac55ad..322dc61942 100644 --- a/libavformat/asfenc.c +++ b/libavformat/asfenc.c @@ -30,7 +30,7 @@ #define ASF_INDEXED_INTERVAL 10000000 -#define ASF_INDEX_BLOCK 600 +#define ASF_INDEX_BLOCK (1<<9) #define ASF_PACKET_ERROR_CORRECTION_DATA_SIZE 0x2 #define ASF_PACKET_ERROR_CORRECTION_FLAGS (\ @@ -208,11 +208,13 @@ typedef struct { /* only for reading */ uint64_t data_offset; ///< beginning of the first data packet - int64_t last_indexed_pts; ASFIndex* index_ptr; - uint32_t nb_index_count; uint32_t nb_index_memory_alloc; uint16_t maximum_packet; + uint32_t next_packet_number; + uint16_t next_packet_count; + int next_start_sec; + int end_sec; } ASFContext; static const AVCodecTag codec_asf_bmp_tags[] = { @@ -557,10 +559,8 @@ static int asf_write_header(AVFormatContext *s) s->packet_size = PACKET_SIZE; asf->nb_packets = 0; - asf->last_indexed_pts = 0; asf->index_ptr = av_malloc( sizeof(ASFIndex) * ASF_INDEX_BLOCK ); asf->nb_index_memory_alloc = ASF_INDEX_BLOCK; - asf->nb_index_count = 0; asf->maximum_packet = 0; /* the data-chunk-size has to be 50, which is data_size - asf->data_offset @@ -782,14 +782,42 @@ static void put_frame( stream->seq++; } +static void update_index(AVFormatContext *s, int start_sec, + uint32_t packet_number, uint16_t packet_count) +{ + ASFContext *asf = s->priv_data; + + if (start_sec > asf->next_start_sec) { + int i; + + if (!asf->next_start_sec) { + asf->next_packet_number = packet_number; + asf->next_packet_count = packet_count; + } + + if (start_sec > asf->nb_index_memory_alloc) { + asf->nb_index_memory_alloc = (start_sec + ASF_INDEX_BLOCK) & ~(ASF_INDEX_BLOCK - 1); + asf->index_ptr = av_realloc( asf->index_ptr, sizeof(ASFIndex) * asf->nb_index_memory_alloc ); + } + for (i = asf->next_start_sec; i < start_sec; i++) { + asf->index_ptr[i].packet_number = asf->next_packet_number; + asf->index_ptr[i].packet_count = asf->next_packet_count; + } + } + asf->maximum_packet = FFMAX(asf->maximum_packet, packet_count); + asf->next_packet_number = packet_number; + asf->next_packet_count = packet_count; + asf->next_start_sec = start_sec; +} + static int asf_write_packet(AVFormatContext *s, AVPacket *pkt) { ASFContext *asf = s->priv_data; ASFStream *stream; - int64_t duration; AVCodecContext *codec; - int64_t packet_st,pts; - int start_sec,i; + uint32_t packet_number; + int64_t pts; + int start_sec; int flags= pkt->flags; codec = s->streams[pkt->stream_index]->codec; @@ -800,30 +828,22 @@ static int asf_write_packet(AVFormatContext *s, AVPacket *pkt) pts = (pkt->pts != AV_NOPTS_VALUE) ? pkt->pts : pkt->dts; assert(pts != AV_NOPTS_VALUE); - duration = pts * 10000; - asf->duration= FFMAX(asf->duration, duration + pkt->duration * 10000); + pts *= 10000; + asf->duration= FFMAX(asf->duration, pts + pkt->duration * 10000); - packet_st = asf->nb_packets; + packet_number = asf->nb_packets; put_frame(s, stream, s->streams[pkt->stream_index], pkt->dts, pkt->data, pkt->size, flags); + start_sec = (int)((PREROLL_TIME * 10000 + pts + ASF_INDEXED_INTERVAL - 1) + / ASF_INDEXED_INTERVAL); + /* check index */ if ((!asf->is_streamed) && (flags & AV_PKT_FLAG_KEY)) { - start_sec = (int)(duration / INT64_C(10000000)); - if (start_sec != (int)(asf->last_indexed_pts / INT64_C(10000000))) { - for(i=asf->nb_index_count;i=asf->nb_index_memory_alloc) { - asf->nb_index_memory_alloc += ASF_INDEX_BLOCK; - asf->index_ptr = (ASFIndex*)av_realloc( asf->index_ptr, sizeof(ASFIndex) * asf->nb_index_memory_alloc ); - } - // store - asf->index_ptr[i].packet_number = (uint32_t)packet_st; - asf->index_ptr[i].packet_count = (uint16_t)(asf->nb_packets-packet_st); - asf->maximum_packet = FFMAX(asf->maximum_packet, (uint16_t)(asf->nb_packets-packet_st)); - } - asf->nb_index_count = start_sec; - asf->last_indexed_pts = duration; - } + uint16_t packet_count = asf->nb_packets - packet_number; + update_index(s, start_sec, packet_number, packet_count); } + asf->end_sec = start_sec; + return 0; } @@ -858,8 +878,9 @@ static int asf_write_trailer(AVFormatContext *s) /* write index */ data_size = avio_tell(s->pb); - if ((!asf->is_streamed) && (asf->nb_index_count != 0)) { - asf_write_index(s, asf->index_ptr, asf->maximum_packet, asf->nb_index_count); + if (!asf->is_streamed && asf->next_start_sec) { + update_index(s, asf->end_sec + 1, 0, 0); + asf_write_index(s, asf->index_ptr, asf->maximum_packet, asf->next_start_sec); } avio_flush(s->pb); diff --git a/libavformat/avformat.h b/libavformat/avformat.h index c28d1ddb2b..1e8a629489 100644 --- a/libavformat/avformat.h +++ b/libavformat/avformat.h @@ -2147,6 +2147,30 @@ int av_match_ext(const char *filename, const char *extensions); */ int avformat_query_codec(AVOutputFormat *ofmt, enum CodecID codec_id, int std_compliance); +/** + * @defgroup riff_fourcc RIFF FourCCs + * @{ + * Get the tables mapping RIFF FourCCs to libavcodec CodecIDs. The tables are + * meant to be passed to av_codec_get_id()/av_codec_get_tag() as in the + * following code: + * @code + * uint32_t tag = MKTAG('H', '2', '6', '4'); + * const struct AVCodecTag *table[] = { avformat_get_riff_video_tags(), 0 }; + * enum CodecID id = av_codec_get_id(table, tag); + * @endcode + */ +/** + * @return the table mapping RIFF FourCCs for video to libavcodec CodecID. + */ +const struct AVCodecTag *avformat_get_riff_video_tags(void); +/** + * @return the table mapping RIFF FourCCs for audio to CodecID. + */ +const struct AVCodecTag *avformat_get_riff_audio_tags(void); +/** + * @} + */ + /** * @} */ diff --git a/libavformat/avidec.c b/libavformat/avidec.c index ec2204c0a9..25f49517ab 100644 --- a/libavformat/avidec.c +++ b/libavformat/avidec.c @@ -694,7 +694,9 @@ static int avi_read_header(AVFormatContext *s, AVFormatParameters *ap) } break; case MKTAG('s', 't', 'r', 'd'): - if (stream_index >= (unsigned)s->nb_streams || s->streams[stream_index]->codec->extradata_size) { + if (stream_index >= (unsigned)s->nb_streams + || s->streams[stream_index]->codec->extradata_size + || s->streams[stream_index]->codec->codec_tag == MKTAG('H','2','6','4')) { avio_skip(pb, size); } else { uint64_t cur_pos = avio_tell(pb); @@ -779,7 +781,11 @@ static int avi_read_header(AVFormatContext *s, AVFormatParameters *ap) if(!avi->index_loaded && pb->seekable) avi_load_index(s); avi->index_loaded |= 1; - avi->non_interleaved |= guess_ni_flag(s) | (s->flags & AVFMT_FLAG_SORT_DTS); + + if ((ret = guess_ni_flag(s)) < 0) + return ret; + + avi->non_interleaved |= ret | (s->flags & AVFMT_FLAG_SORT_DTS); for(i=0; inb_streams; i++){ AVStream *st = s->streams[i]; if(st->nb_index_entries) @@ -805,8 +811,10 @@ static int avi_read_header(AVFormatContext *s, AVFormatParameters *ap) return 0; } -static int read_gab2_sub(AVStream *st, AVPacket *pkt) { - if (!strcmp(pkt->data, "GAB2") && AV_RL16(pkt->data+5) == 2) { +static int read_gab2_sub(AVStream *st, AVPacket *pkt) +{ + if (pkt->size >= 7 && + !strcmp(pkt->data, "GAB2") && AV_RL16(pkt->data + 5) == 2) { uint8_t desc[256]; int score = AVPROBE_SCORE_MAX / 2, ret; AVIStream *ast = st->priv_data; @@ -936,7 +944,7 @@ start_sync: goto start_sync; } - n= get_stream_idx(d); + n = avi->dv_demux ? 0 : get_stream_idx(d); if(!((i-avi->last_pkt_pos)&1) && get_stream_idx(d+1) < s->nb_streams) continue; @@ -954,6 +962,11 @@ start_sync: st = s->streams[n]; ast = st->priv_data; + if (!ast) { + av_log(s, AV_LOG_WARNING, "Skiping foreign stream %d packet\n", n); + continue; + } + if(s->nb_streams>=2){ AVStream *st1 = s->streams[1]; AVIStream *ast1= st1->priv_data; @@ -973,14 +986,17 @@ start_sync: } - if( (st->discard >= AVDISCARD_DEFAULT && size==0) - /*|| (st->discard >= AVDISCARD_NONKEY && !(pkt->flags & AV_PKT_FLAG_KEY))*/ //FIXME needs a little reordering - || st->discard >= AVDISCARD_ALL){ + if (!avi->dv_demux && + ((st->discard >= AVDISCARD_DEFAULT && size==0) /* || + //FIXME needs a little reordering + (st->discard >= AVDISCARD_NONKEY && + !(pkt->flags & AV_PKT_FLAG_KEY)) */ + || st->discard >= AVDISCARD_ALL)) { if (!exit_early) { ast->frame_offset += get_duration(ast, size); + avio_skip(pb, size); + goto start_sync; } - avio_skip(pb, size); - goto start_sync; } if (d[2] == 'p' && d[3] == 'c' && size<=4*256+4) { @@ -1039,6 +1055,8 @@ static int avi_read_packet(AVFormatContext *s, AVPacket *pkt) int size = avpriv_dv_get_packet(avi->dv_demux, pkt); if (size >= 0) return size; + else + goto resync; } if(avi->non_interleaved){ @@ -1194,7 +1212,7 @@ resync: } ast->frame_offset += get_duration(ast, pkt->size); } - ast->remaining -= size; + ast->remaining -= err; if(!ast->remaining){ avi->stream_index= -1; ast->packet_size= 0; @@ -1216,7 +1234,7 @@ resync: avi->dts_max = dts; } - return size; + return 0; } if ((err = avi_sync(s, 0)) < 0) @@ -1249,6 +1267,11 @@ static int avi_read_idx1(AVFormatContext *s, int size) avi->stream_index = -1; avio_seek(pb, idx1_pos, SEEK_SET); + if (s->nb_streams == 1 && s->streams[0]->codec->codec_tag == AV_RL32("MMES")){ + first_packet_pos = 0; + data_offset = avi->movi_list; + } + /* Read the entries and sort them in each stream component. */ for(i = 0; i < nb_index_entries; i++) { if(url_feof(pb)) @@ -1268,7 +1291,7 @@ static int avi_read_idx1(AVFormatContext *s, int size) st = s->streams[index]; ast = st->priv_data; - if(first_packet && first_packet_pos && len) { + if (first_packet && first_packet_pos) { data_offset = first_packet_pos - pos; first_packet = 0; } @@ -1287,6 +1310,66 @@ static int avi_read_idx1(AVFormatContext *s, int size) return 0; } +/* Scan the index and consider any file with streams more than + * 2 seconds or 64MB apart non-interleaved. */ +static int check_stream_max_drift(AVFormatContext *s) +{ + int64_t min_pos, pos; + int i; + int *idx = av_malloc(s->nb_streams * sizeof(*idx)); + if (!idx) + return AVERROR(ENOMEM); + else + memset(idx, 0, s->nb_streams * sizeof(*idx)); + + for (min_pos = pos = 0; min_pos != INT64_MAX; pos = min_pos + 1LU) { + int64_t max_dts = INT64_MIN / 2; + int64_t min_dts = INT64_MAX / 2; + int64_t max_buffer = 0; + + min_pos = INT64_MAX; + + for (i = 0; i < s->nb_streams; i++) { + AVStream *st = s->streams[i]; + AVIStream *ast = st->priv_data; + 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->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->index_entries[idx[i]].pos); + } + } + for (i = 0; i < s->nb_streams; i++) { + AVStream *st = s->streams[i]; + AVIStream *ast = st->priv_data; + + if (idx[i] && min_dts != INT64_MAX / 2) { + int64_t dts; + dts = av_rescale_q(st->index_entries[idx[i] - 1].timestamp / + FFMAX(ast->sample_size, 1), + st->time_base, AV_TIME_BASE_Q); + max_dts = FFMAX(max_dts, dts); + max_buffer = FFMAX(max_buffer, + av_rescale(dts - min_dts, + st->codec->bit_rate, + AV_TIME_BASE)); + } + } + if (max_dts - min_dts > 2 * AV_TIME_BASE || + max_buffer > 1024 * 1024 * 8 * 8) { + av_free(idx); + return 1; + } + } + av_free(idx); + return 0; +} + static int guess_ni_flag(AVFormatContext *s){ int i; int64_t last_start=0; @@ -1315,7 +1398,11 @@ static int guess_ni_flag(AVFormatContext *s){ first_end= st->index_entries[n-1].pos; } avio_seek(s->pb, oldpos, SEEK_SET); - return last_start > first_end; + + if (last_start > first_end) + return 1; + + return check_stream_max_drift(s); } static int avi_load_index(AVFormatContext *s) @@ -1375,12 +1462,17 @@ static int avi_read_seek(AVFormatContext *s, int stream_index, int64_t timestamp int64_t pos, pos_min; AVIStream *ast; + /* Does not matter which stream is requested dv in avi has the + * stream information in the first video stream. + */ + if (avi->dv_demux) + stream_index = 0; + if (!avi->index_loaded) { /* we only load the index on demand */ avi_load_index(s); avi->index_loaded |= 1; } - assert(stream_index>= 0); st = s->streams[stream_index]; ast= st->priv_data; @@ -1398,7 +1490,6 @@ static int avi_read_seek(AVFormatContext *s, int stream_index, int64_t timestamp /* One and only one real stream for DV in AVI, and it has video */ /* offsets. Calling with other stream indexes should have failed */ /* the av_index_search_timestamp call above. */ - assert(stream_index == 0); if(avio_seek(s->pb, pos, SEEK_SET) < 0) return -1; diff --git a/libavformat/avio.c b/libavformat/avio.c index 418a8a79fc..d9d417c5a9 100644 --- a/libavformat/avio.c +++ b/libavformat/avio.c @@ -297,7 +297,9 @@ int ffurl_alloc(URLContext **puc, const char *filename, int flags, "Missing call to av_register_all()?\n"); } - if (filename[proto_len] != ':' && filename[proto_len] != ',' || is_dos_path(filename)) + if (filename[proto_len] != ':' && + (filename[proto_len] != ',' || !strchr(filename + proto_len + 1, ':')) || + is_dos_path(filename)) strcpy(proto_str, "file"); else av_strlcpy(proto_str, filename, FFMIN(proto_len+1, sizeof(proto_str))); @@ -357,7 +359,7 @@ static inline int retry_transfer_wrapper(URLContext *h, unsigned char *buf, int else usleep(1000); } else if (ret < 1) - return ret < 0 ? ret : len; + return (ret < 0 && ret != AVERROR_EOF) ? ret : len; if (ret) fast_retries = FFMAX(fast_retries, 2); len += ret; diff --git a/libavformat/aviobuf.c b/libavformat/aviobuf.c index d8074780df..3a360a0694 100644 --- a/libavformat/aviobuf.c +++ b/libavformat/aviobuf.c @@ -229,6 +229,9 @@ int64_t avio_seek(AVIOContext *s, int64_t offset, int whence) return offset1; offset += offset1; } + if (offset < 0) + return AVERROR(EINVAL); + offset1 = offset - pos; if (!s->must_flush && offset1 >= 0 && offset1 <= (s->buf_end - s->buffer)) { diff --git a/libavformat/bfi.c b/libavformat/bfi.c index 3886d4bedd..37a15c9b68 100644 --- a/libavformat/bfi.c +++ b/libavformat/bfi.c @@ -130,6 +130,10 @@ static int bfi_read_packet(AVFormatContext * s, AVPacket * pkt) 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) { + av_log(s, AV_LOG_ERROR, "Invalid audio/video offsets or chunk size\n"); + return AVERROR_INVALIDDATA; + } //Tossing an audio packet at the audio decoder. ret = av_get_packet(pb, pkt, audio_size); @@ -138,9 +142,7 @@ static int bfi_read_packet(AVFormatContext * s, AVPacket * pkt) pkt->pts = bfi->audio_frame; bfi->audio_frame += ret; - } - - else { + } else if (bfi->video_size > 0) { //Tossing a video packet at the video decoder. ret = av_get_packet(pb, pkt, bfi->video_size); @@ -152,6 +154,9 @@ static int bfi_read_packet(AVFormatContext * s, AVPacket * pkt) /* One less frame to read. A cursory decrement. */ bfi->nframes--; + } else { + /* Empty video packet */ + ret = AVERROR(EAGAIN); } bfi->avflag = !bfi->avflag; diff --git a/libavformat/bit.c b/libavformat/bit.c index 1249ea1aee..f346cf4df0 100644 --- a/libavformat/bit.c +++ b/libavformat/bit.c @@ -132,6 +132,9 @@ static int write_packet(AVFormatContext *s, AVPacket *pkt) GetBitContext gb; int i; + if (pkt->size != 10) + return AVERROR(EINVAL); + avio_wl16(pb, SYNC_WORD); avio_wl16(pb, 8 * 10); diff --git a/libavformat/dsicin.c b/libavformat/dsicin.c index e0db8ba10e..f7ae216a23 100644 --- a/libavformat/dsicin.c +++ b/libavformat/dsicin.c @@ -153,6 +153,8 @@ static int cin_read_frame_header(CinDemuxContext *cin, AVIOContext *pb) { if (avio_rl32(pb) != 0xAA55AA55) return AVERROR_INVALIDDATA; + if (hdr->video_frame_size < 0 || hdr->audio_frame_size < 0) + return AVERROR_INVALIDDATA; return 0; } diff --git a/libavformat/dv.c b/libavformat/dv.c index 666e3317ab..9e016391c5 100644 --- a/libavformat/dv.c +++ b/libavformat/dv.c @@ -106,7 +106,7 @@ static const uint8_t* dv_extract_pack(uint8_t* frame, enum dv_pack_type t) * 3. Audio is always returned as 16bit linear samples: 12bit nonlinear samples * are converted into 16bit linear ones. */ -static int dv_extract_audio(uint8_t* frame, uint8_t* ppcm[4], +static int dv_extract_audio(uint8_t *frame, uint8_t **ppcm, const DVprofile *sys) { int size, chan, i, j, d, of, smpls, freq, quant, half_ch; @@ -125,6 +125,9 @@ static int dv_extract_audio(uint8_t* frame, uint8_t* ppcm[4], if (quant > 1) return -1; /* unsupported quantization */ + if (freq >= FF_ARRAY_ELEMS(dv_audio_frequency)) + return AVERROR_INVALIDDATA; + size = (sys->audio_min_samples[freq] + smpls) * 4; /* 2ch, 2bytes */ half_ch = sys->difseg_size / 2; @@ -135,6 +138,7 @@ static int dv_extract_audio(uint8_t* frame, uint8_t* ppcm[4], /* for each DIF channel */ for (chan = 0; chan < sys->n_difchan; chan++) { av_assert0(ipcm<4); + /* next stereo channel (50Mbps and 100Mbps only) */ pcm = ppcm[ipcm++]; if (!pcm) break; @@ -186,8 +190,6 @@ static int dv_extract_audio(uint8_t* frame, uint8_t* ppcm[4], frame += 16 * 80; /* 15 Video DIFs + 1 Audio DIF */ } } - - /* next stereo channel (50Mbps and 100Mbps only) */ } return size; @@ -209,6 +211,12 @@ static int dv_extract_audio_info(DVDemuxContext* c, uint8_t* frame) stype = (as_pack[3] & 0x1f); /* 0 - 2CH, 2 - 4CH, 3 - 8CH */ quant = as_pack[4] & 0x07; /* 0 - 16bit linear, 1 - 12bit nonlinear */ + if (freq >= FF_ARRAY_ELEMS(dv_audio_frequency)) { + av_log(c->fctx, AV_LOG_ERROR, + "Unrecognized audio sample rate index (%d)\n", freq); + return 0; + } + if (stype > 3) { av_log(c->fctx, AV_LOG_ERROR, "stype %d is invalid\n", stype); c->ach = 0; @@ -259,9 +267,6 @@ static int dv_extract_video_info(DVDemuxContext *c, uint8_t* frame) avpriv_set_pts_info(c->vst, 64, c->sys->time_base.num, c->sys->time_base.den); avctx->time_base= c->sys->time_base; - if (!avctx->width) - avcodec_set_dimensions(avctx, c->sys->width, c->sys->height); - avctx->pix_fmt = c->sys->pix_fmt; /* finding out SAR is a little bit messy */ vsc_pack = dv_extract_pack(frame, dv_video_control); @@ -369,7 +374,7 @@ int avpriv_dv_produce_packet(DVDemuxContext *c, AVPacket *pkt, uint8_t* buf, int buf_size, int64_t pos) { int size, i; - uint8_t *ppcm[4] = {0}; + uint8_t *ppcm[5] = { 0 }; if (buf_size < DV_PROFILE_BYTES || !(c->sys = avpriv_dv_frame_profile(c->sys, buf, buf_size)) || diff --git a/libavformat/electronicarts.c b/libavformat/electronicarts.c index a0007d2982..859ad7c174 100644 --- a/libavformat/electronicarts.c +++ b/libavformat/electronicarts.c @@ -426,8 +426,9 @@ static int ea_read_header(AVFormatContext *s, } if (ea->audio_codec) { - if (ea->num_channels <= 0) { - av_log(s, AV_LOG_WARNING, "Unsupported number of channels: %d\n", ea->num_channels); + if (ea->num_channels <= 0 || ea->num_channels > 2) { + av_log(s, AV_LOG_WARNING, + "Unsupported number of channels: %d\n", ea->num_channels); ea->audio_codec = 0; return 1; } @@ -476,12 +477,17 @@ static int ea_read_packet(AVFormatContext *s, while (!packet_read) { chunk_type = avio_rl32(pb); - chunk_size = (ea->big_endian ? avio_rb32(pb) : avio_rl32(pb)) - 8; + chunk_size = ea->big_endian ? avio_rb32(pb) : avio_rl32(pb); + if (chunk_size <= 8) + return AVERROR_INVALIDDATA; + chunk_size -= 8; switch (chunk_type) { /* audio data */ case ISNh_TAG: /* header chunk also contains data; skip over the header portion*/ + if (chunk_size < 32) + return AVERROR_INVALIDDATA; avio_skip(pb, 32); chunk_size -= 32; case ISNd_TAG: diff --git a/libavformat/flacdec.c b/libavformat/flacdec.c index 070f9af3f6..6af54712d9 100644 --- a/libavformat/flacdec.c +++ b/libavformat/flacdec.c @@ -143,11 +143,9 @@ static int flac_read_header(AVFormatContext *s, static int flac_probe(AVProbeData *p) { - uint8_t *bufptr = p->buf; - uint8_t *end = p->buf + p->buf_size; - - if(bufptr > end-4 || memcmp(bufptr, "fLaC", 4)) return 0; - else return AVPROBE_SCORE_MAX/2; + if (p->buf_size < 4 || memcmp(p->buf, "fLaC", 4)) + return 0; + return AVPROBE_SCORE_MAX/2; } AVInputFormat ff_flac_demuxer = { diff --git a/libavformat/flvenc.c b/libavformat/flvenc.c index 3f034bc31a..417a1c1986 100644 --- a/libavformat/flvenc.c +++ b/libavformat/flvenc.c @@ -446,8 +446,13 @@ static int flv_write_packet(AVFormatContext *s, AVPacket *pkt) } } else if (enc->codec_id == CODEC_ID_AAC && pkt->size > 2 && (AV_RB16(pkt->data) & 0xfff0) == 0xfff0) { - av_log(s, AV_LOG_ERROR, "malformated aac bitstream, use -absf aac_adtstoasc\n"); - return -1; + if (!s->streams[pkt->stream_index]->nb_frames) { + av_log(s, AV_LOG_ERROR, "Malformed AAC bitstream detected: " + "use audio bitstream filter 'aac_adtstoasc' to fix it " + "('-bsf:a aac_adtstoasc' option with ffmpeg)\n"); + return AVERROR_INVALIDDATA; + } + av_log(s, AV_LOG_WARNING, "aac bitstream error\n"); } if (flv->delay == AV_NOPTS_VALUE) flv->delay = -pkt->dts; diff --git a/libavformat/gxf.c b/libavformat/gxf.c index e773ba7775..fc8df84fc6 100644 --- a/libavformat/gxf.c +++ b/libavformat/gxf.c @@ -531,7 +531,7 @@ static int gxf_packet(AVFormatContext *s, AVPacket *pkt) { } static int gxf_seek(AVFormatContext *s, int stream_index, int64_t timestamp, int flags) { - int res = 0; + int64_t res = 0; uint64_t pos; uint64_t maxlen = 100 * 1024 * 1024; AVStream *st = s->streams[0]; diff --git a/libavformat/h263dec.c b/libavformat/h263dec.c index b07e9782b8..6945821f93 100644 --- a/libavformat/h263dec.c +++ b/libavformat/h263dec.c @@ -35,7 +35,7 @@ static int h263_probe(AVProbeData *p) for(i=0; ibuf_size; i++){ code = (code<<8) + p->buf[i]; if ((code & 0xfffffc0000) == 0x800000) { - src_fmt= (code>>2)&3; + src_fmt= (code>>2)&7; if( src_fmt != last_src_fmt && last_src_fmt>0 && last_src_fmt<6 && src_fmt<6) diff --git a/libavformat/id3v2.c b/libavformat/id3v2.c index 250281c357..dc313b8ccb 100644 --- a/libavformat/id3v2.c +++ b/libavformat/id3v2.c @@ -464,21 +464,21 @@ static void ff_id3v2_parse(AVFormatContext *s, int len, uint8_t version, uint8_t unsync = flags & 0x80; - /* Extended header present, just skip over it */ - if (isv34 && flags & 0x40) { - int size = get_size(s->pb, 4); - if (size < 6) { - reason = "extended header too short."; + if (isv34 && flags & 0x40) { /* Extended header present, just skip over it */ + int extlen = get_size(s->pb, 4); + if (version == 4) + extlen -= 4; // in v2.4 the length includes the length field we just read + + if (extlen < 0) { + reason = "invalid extended header length"; goto error; } - len -= size; + avio_skip(s->pb, extlen); + len -= extlen + 4; if (len < 0) { reason = "extended header too long."; goto error; } - /* already seeked past size, skip the reset */ - size -= 4; - avio_skip(s->pb, size); } while (len >= taghdrlen) { @@ -543,13 +543,15 @@ static void ff_id3v2_parse(AVFormatContext *s, int len, uint8_t version, uint8_t /* check for text tag or supported special meta tag */ } else if (tag[0] == 'T' || (extra_meta && (extra_func = get_extra_meta_func(tag, isv34)))) { if (unsync || tunsync || tcomp) { - int i, j; + int64_t end = avio_tell(s->pb) + tlen; + uint8_t *b; av_fast_malloc(&buffer, &buffer_size, dlen); if (!buffer) { av_log(s, AV_LOG_ERROR, "Failed to alloc %ld bytes\n", dlen); goto seek; } + b = buffer; #if CONFIG_ZLIB if (tcomp) { int n, err; @@ -573,19 +575,25 @@ static void ff_id3v2_parse(AVFormatContext *s, int len, uint8_t version, uint8_t av_log(s, AV_LOG_ERROR, "Failed to uncompress tag: %d\n", err); goto seek; } + b += dlen; } #endif - - for (i = 0, j = 0; i < dlen; i++, j++) { - if (!tcomp) - buffer[j] = avio_r8(s->pb); - if (j > 0 && !buffer[j] && buffer[j - 1] == 0xff) { - /* Unsynchronised byte, skip it */ - j--; + if (unsync || tunsync) { + if (tcomp) { + av_log_ask_for_sample(s, "tcomp with unsync\n"); + goto seek; + } + while (avio_tell(s->pb) < end && !s->pb->eof_reached) { + *b++ = avio_r8(s->pb); + if (*(b - 1) == 0xff && avio_tell(s->pb) < end - 1 && + !s->pb->eof_reached) { + uint8_t val = avio_r8(s->pb); + *b++ = val ? val : avio_r8(s->pb); } } - ffio_init_context(&pb, buffer, j, 0, NULL, NULL, NULL, NULL); - tlen = j; + } + ffio_init_context(&pb, buffer, b - buffer, 0, NULL, NULL, NULL, NULL); + tlen = b - buffer; pbx = &pb; // read from sync buffer } else { pbx = s->pb; // read straight from input diff --git a/libavformat/idcin.c b/libavformat/idcin.c index 57f81c813d..c5e8f376b0 100644 --- a/libavformat/idcin.c +++ b/libavformat/idcin.c @@ -91,7 +91,7 @@ typedef struct IdcinDemuxContext { static int idcin_probe(AVProbeData *p) { - unsigned int number; + unsigned int number, sample_rate; /* * This is what you could call a "probabilistic" file check: id CIN @@ -120,18 +120,18 @@ static int idcin_probe(AVProbeData *p) return 0; /* check the audio sample rate */ - number = AV_RL32(&p->buf[8]); - if ((number != 0) && ((number < 8000) | (number > 48000))) + sample_rate = AV_RL32(&p->buf[8]); + if (sample_rate && (sample_rate < 8000 || sample_rate > 48000)) return 0; /* check the audio bytes/sample */ number = AV_RL32(&p->buf[12]); - if (number > 2) + if (number > 2 || sample_rate && !number) return 0; /* check the audio channels */ number = AV_RL32(&p->buf[16]); - if (number > 2) + if (number > 2 || sample_rate && !number) return 0; /* return half certainly since this check is a bit sketchy */ diff --git a/libavformat/idroqdec.c b/libavformat/idroqdec.c index fffee9d76e..62c017ba6d 100644 --- a/libavformat/idroqdec.c +++ b/libavformat/idroqdec.c @@ -145,6 +145,8 @@ static int roq_read_packet(AVFormatContext *s, break; case RoQ_QUAD_CODEBOOK: + if (roq->video_stream_index < 0) + return AVERROR_INVALIDDATA; /* packet needs to contain both this codebook and next VQ chunk */ codebook_offset = avio_tell(pb) - RoQ_CHUNK_PREAMBLE_SIZE; codebook_size = chunk_size; @@ -187,6 +189,11 @@ static int roq_read_packet(AVFormatContext *s, st->codec->block_align = st->codec->channels * st->codec->bits_per_coded_sample; } case RoQ_QUAD_VQ: + if (chunk_type == RoQ_QUAD_VQ) { + if (roq->video_stream_index < 0) + return AVERROR_INVALIDDATA; + } + /* load up the packet */ if (av_new_packet(pkt, chunk_size + RoQ_CHUNK_PREAMBLE_SIZE)) return AVERROR(EIO); diff --git a/libavformat/iff.c b/libavformat/iff.c index ebc1c35ba5..876b902586 100644 --- a/libavformat/iff.c +++ b/libavformat/iff.c @@ -188,6 +188,11 @@ static int iff_read_header(AVFormatContext *s, break; case ID_CMAP: + if (data_size < 3 || data_size > 768 || data_size % 3) { + av_log(s, AV_LOG_ERROR, "Invalid CMAP chunk size %d\n", + data_size); + return AVERROR_INVALIDDATA; + } st->codec->extradata_size = data_size + IFF_EXTRA_VIDEO_SIZE; st->codec->extradata = av_malloc(data_size + IFF_EXTRA_VIDEO_SIZE + FF_INPUT_BUFFER_PADDING_SIZE); if (!st->codec->extradata) diff --git a/libavformat/isom.c b/libavformat/isom.c index 01a4ec558c..bd54ceb58e 100644 --- a/libavformat/isom.c +++ b/libavformat/isom.c @@ -165,10 +165,13 @@ const AVCodecTag codec_movvideo_tags[] = { { CODEC_ID_MPEG2VIDEO, MKTAG('h', 'd', 'v', '1') }, /* MPEG2 HDV 720p30 */ { CODEC_ID_MPEG2VIDEO, MKTAG('h', 'd', 'v', '2') }, /* MPEG2 HDV 1080i60 */ { CODEC_ID_MPEG2VIDEO, MKTAG('h', 'd', 'v', '3') }, /* MPEG2 HDV 1080i50 */ + { CODEC_ID_MPEG2VIDEO, MKTAG('h', 'd', 'v', '4') }, /* MPEG2 HDV 720p24 */ { CODEC_ID_MPEG2VIDEO, MKTAG('h', 'd', 'v', '5') }, /* MPEG2 HDV 720p25 */ { CODEC_ID_MPEG2VIDEO, MKTAG('h', 'd', 'v', '6') }, /* MPEG2 HDV 1080p24 */ { CODEC_ID_MPEG2VIDEO, MKTAG('h', 'd', 'v', '7') }, /* MPEG2 HDV 1080p25 */ { CODEC_ID_MPEG2VIDEO, MKTAG('h', 'd', 'v', '8') }, /* MPEG2 HDV 1080p30 */ + { CODEC_ID_MPEG2VIDEO, MKTAG('h', 'd', 'v', '9') }, /* MPEG2 HDV 720p60 JVC */ + { CODEC_ID_MPEG2VIDEO, MKTAG('h', 'd', 'v', 'a') }, /* MPEG2 HDV 720p50 */ { CODEC_ID_MPEG2VIDEO, MKTAG('m', 'x', '5', 'n') }, /* MPEG2 IMX NTSC 525/60 50mb/s produced by FCP */ { CODEC_ID_MPEG2VIDEO, MKTAG('m', 'x', '5', 'p') }, /* MPEG2 IMX PAL 625/50 50mb/s produced by FCP */ { CODEC_ID_MPEG2VIDEO, MKTAG('m', 'x', '4', 'n') }, /* MPEG2 IMX NTSC 525/60 40mb/s produced by FCP */ @@ -199,6 +202,8 @@ const AVCodecTag codec_movvideo_tags[] = { { CODEC_ID_MPEG2VIDEO, MKTAG('x', 'd', 'v', 'd') }, /* XDCAM EX 1080p24 VBR */ { CODEC_ID_MPEG2VIDEO, MKTAG('x', 'd', 'v', 'e') }, /* XDCAM EX 1080p25 VBR */ { CODEC_ID_MPEG2VIDEO, MKTAG('x', 'd', 'v', 'f') }, /* XDCAM EX 1080p30 VBR */ + { CODEC_ID_MPEG2VIDEO, MKTAG('x', 'd', 'h', 'd') }, /* XDCAM HD 540p */ + { CODEC_ID_MPEG2VIDEO, MKTAG('x', 'd', 'h', '2') }, /* XDCAM HD422 540p */ { CODEC_ID_MPEG2VIDEO, MKTAG('A', 'V', 'm', 'p') }, /* AVID IMX PAL */ { CODEC_ID_JPEG2000, MKTAG('m', 'j', 'p', '2') }, /* JPEG 2000 produced by FCP */ @@ -258,6 +263,7 @@ const AVCodecTag codec_movaudio_tags[] = { { CODEC_ID_PCM_MULAW, MKTAG('u', 'l', 'a', 'w') }, { CODEC_ID_PCM_S16BE, MKTAG('t', 'w', 'o', 's') }, { CODEC_ID_PCM_S16LE, MKTAG('s', 'o', 'w', 't') }, + { CODEC_ID_PCM_S16BE, MKTAG('l', 'p', 'c', 'm') }, { CODEC_ID_PCM_S16LE, MKTAG('l', 'p', 'c', 'm') }, { CODEC_ID_PCM_S24BE, MKTAG('i', 'n', '2', '4') }, { CODEC_ID_PCM_S24LE, MKTAG('i', 'n', '2', '4') }, @@ -341,7 +347,7 @@ int ff_mov_lang_to_iso639(unsigned code, char to[4]) memset(to, 0, 4); /* is it the mangled iso code? */ /* see http://www.geocities.com/xhelmboyx/quicktime/formats/mp4-layout.txt */ - if (code > 138) { + if (code >= 0x400 && code != 0x7fff) { for (i = 2; i >= 0; i--) { to[i] = 0x60 + (code & 0x1f); code >>= 5; diff --git a/libavformat/libmodplug.c b/libavformat/libmodplug.c index dfbf67c2d2..f3f0e5ee10 100644 --- a/libavformat/libmodplug.c +++ b/libavformat/libmodplug.c @@ -347,6 +347,19 @@ static int modplug_read_seek(AVFormatContext *s, int stream_idx, int64_t ts, int return 0; } +static const char modplug_extensions[] = "669,abc,amf,ams,dbm,dmf,dsm,far,it,mdl,med,mid,mod,mt2,mtm,okt,psm,ptm,s3m,stm,ult,umx,xm,itgz,itr,itz,mdgz,mdr,mdz,s3gz,s3r,s3z,xmgz,xmr,xmz"; + +static int modplug_probe(AVProbeData *p) +{ + if (av_match_ext(p->filename, modplug_extensions)) { + if (p->buf_size < 16384) + return AVPROBE_SCORE_MAX/4-1; + else + return AVPROBE_SCORE_MAX/2; + } + return 0; +} + static const AVClass modplug_class = { .class_name = "ModPlug demuxer", .item_name = av_default_item_name, @@ -358,11 +371,11 @@ AVInputFormat ff_libmodplug_demuxer = { .name = "libmodplug", .long_name = NULL_IF_CONFIG_SMALL("ModPlug demuxer"), .priv_data_size = sizeof(ModPlugContext), + .read_probe = modplug_probe, .read_header = modplug_read_header, .read_packet = modplug_read_packet, .read_close = modplug_read_close, .read_seek = modplug_read_seek, - .extensions = "669,abc,amf,ams,dbm,dmf,dsm,far,it,mdl,med,mid,mod,mt2,mtm,okt,psm,ptm,s3m,stm,ult,umx,xm" - ",itgz,itr,itz,mdgz,mdr,mdz,s3gz,s3r,s3z,xmgz,xmr,xmz", // compressed mods + .extensions = modplug_extensions, .priv_class = &modplug_class, }; diff --git a/libavformat/loasdec.c b/libavformat/loasdec.c index e48c21905a..fbe1cb4aa9 100644 --- a/libavformat/loasdec.c +++ b/libavformat/loasdec.c @@ -55,7 +55,6 @@ static int loas_probe(AVProbeData *p) if (first_frames>=3) return AVPROBE_SCORE_MAX/2+1; else if(max_frames>100)return AVPROBE_SCORE_MAX/2; else if(max_frames>=3) return AVPROBE_SCORE_MAX/4; - else if(max_frames>=1) return 1; else return 0; } diff --git a/libavformat/m4vdec.c b/libavformat/m4vdec.c index 88f838022e..67d6ef4a47 100644 --- a/libavformat/m4vdec.c +++ b/libavformat/m4vdec.c @@ -33,13 +33,15 @@ static int mpeg4video_probe(AVProbeData *probe_packet) for(i=0; ibuf_size; i++){ temp_buffer = (temp_buffer<<8) + probe_packet->buf[i]; - if ((temp_buffer & 0xffffff00) != 0x100) + if (temp_buffer & 0xfffffe00) + continue; + if (temp_buffer < 2) continue; if (temp_buffer == VOP_START_CODE) VOP++; else if (temp_buffer == VISUAL_OBJECT_START_CODE) VISO++; - else if (temp_buffer < 0x120) VO++; - else if (temp_buffer < 0x130) VOL++; + else if (temp_buffer >= 0x100 && temp_buffer < 0x120) VO++; + else if (temp_buffer >= 0x120 && temp_buffer < 0x130) VOL++; else if ( !(0x1AF < temp_buffer && temp_buffer < 0x1B7) && !(0x1B9 < temp_buffer && temp_buffer < 0x1C4)) res++; } diff --git a/libavformat/matroska.c b/libavformat/matroska.c index 52481d7556..a5a4363cc0 100644 --- a/libavformat/matroska.c +++ b/libavformat/matroska.c @@ -21,6 +21,9 @@ #include "matroska.h" +/* If you add a tag here that is not in ff_codec_bmp_tags[] + or ff_codec_wav_tags[], add it also to additional_audio_tags[] + or additional_video_tags[] in matroskaenc.c */ const CodecTags ff_mkv_codec_tags[]={ {"A_AAC" , CODEC_ID_AAC}, {"A_AC3" , CODEC_ID_AC3}, diff --git a/libavformat/matroskadec.c b/libavformat/matroskadec.c index b7f7740647..65aecb0b84 100644 --- a/libavformat/matroskadec.c +++ b/libavformat/matroskadec.c @@ -667,16 +667,19 @@ static int ebml_read_float(AVIOContext *pb, int size, double *num) */ static int ebml_read_ascii(AVIOContext *pb, int size, char **str) { - av_free(*str); + char *res; + /* EBML strings are usually not 0-terminated, so we allocate one * byte more, read the string and NULL-terminate it ourselves. */ - if (!(*str = av_malloc(size + 1))) + if (!(res = av_malloc(size + 1))) return AVERROR(ENOMEM); - if (avio_read(pb, (uint8_t *) *str, size) != size) { - av_freep(str); + if (avio_read(pb, (uint8_t *) res, size) != size) { + av_free(res); return AVERROR(EIO); } - (*str)[size] = '\0'; + (res)[size] = '\0'; + av_free(*str); + *str = res; return 0; } @@ -1111,7 +1114,8 @@ static void matroska_convert_tag(AVFormatContext *s, EbmlList *list, int i; for (i=0; i < list->nb_elem; i++) { - const char *lang = strcmp(tags[i].lang, "und") ? tags[i].lang : NULL; + const char *lang = tags[i].lang && strcmp(tags[i].lang, "und") ? + tags[i].lang : NULL; if (!tags[i].name) { av_log(s, AV_LOG_WARNING, "Skipping invalid tag with no TagName.\n"); @@ -1225,13 +1229,17 @@ static void matroska_execute_seekhead(MatroskaDemuxContext *matroska) EbmlList *seekhead_list = &matroska->seekhead; int64_t before_pos = avio_tell(matroska->ctx->pb); int i; + int nb_elem; // we should not do any seeking in the streaming case if (!matroska->ctx->pb->seekable || (matroska->ctx->flags & AVFMT_FLAG_IGNIDX)) return; - for (i = 0; i < seekhead_list->nb_elem; i++) { + // do not read entries that are added while parsing seekhead entries + nb_elem = seekhead_list->nb_elem; + + for (i = 0; i < nb_elem; i++) { MatroskaSeekhead *seekhead = seekhead_list->elem; if (seekhead[i].pos <= before_pos) continue; @@ -1460,7 +1468,7 @@ static int matroska_read_header(AVFormatContext *s, AVFormatParameters *ap) && track->codec_priv.data != NULL) { int ret; ffio_init_context(&b, track->codec_priv.data, track->codec_priv.size, - AVIO_FLAG_READ, NULL, NULL, NULL, NULL); + 0, NULL, NULL, NULL, NULL); ret = ff_get_wav_header(&b, st->codec, track->codec_priv.size); if (ret < 0) return ret; @@ -1532,6 +1540,10 @@ static int matroska_read_header(AVFormatContext *s, AVFormatParameters *ap) track->audio.sub_packet_h = avio_rb16(&b); track->audio.frame_size = avio_rb16(&b); track->audio.sub_packet_size = avio_rb16(&b); + if (flavor <= 0 || track->audio.coded_framesize <= 0 || + track->audio.sub_packet_h <= 0 || track->audio.frame_size <= 0 || + track->audio.sub_packet_size <= 0) + return AVERROR_INVALIDDATA; track->audio.buf = av_malloc(track->audio.frame_size * track->audio.sub_packet_h); if (codec_id == CODEC_ID_RA_288) { st->codec->block_align = track->audio.coded_framesize; @@ -1712,6 +1724,7 @@ static int matroska_deliver_packet(MatroskaDemuxContext *matroska, */ static void matroska_clear_queue(MatroskaDemuxContext *matroska) { + matroska->prev_pkt = NULL; if (matroska->packets) { int n; for (n = 0; n < matroska->num_packets; n++) { @@ -1876,15 +1889,31 @@ static int matroska_parse_block(MatroskaDemuxContext *matroska, uint8_t *data, if (!track->audio.pkt_cnt) { if (track->audio.sub_packet_cnt == 0) track->audio.buf_timecode = timecode; - if (st->codec->codec_id == CODEC_ID_RA_288) + if (st->codec->codec_id == CODEC_ID_RA_288) { + if (size < cfs * h / 2) { + av_log(matroska->ctx, AV_LOG_ERROR, + "Corrupt int4 RM-style audio packet size\n"); + return AVERROR_INVALIDDATA; + } for (x=0; xaudio.buf+x*2*w+y*cfs, data+x*cfs, cfs); - else if (st->codec->codec_id == CODEC_ID_SIPR) + } else if (st->codec->codec_id == CODEC_ID_SIPR) { + if (size < w) { + av_log(matroska->ctx, AV_LOG_ERROR, + "Corrupt sipr RM-style audio packet size\n"); + return AVERROR_INVALIDDATA; + } memcpy(track->audio.buf + y*w, data, w); - else + } else { + if (size < sps * w / sps) { + av_log(matroska->ctx, AV_LOG_ERROR, + "Corrupt generic RM-style audio packet size\n"); + return AVERROR_INVALIDDATA; + } for (x=0; xaudio.buf+sps*(h*x+((h+1)/2)*(y&1)+(y>>1)), data+x*sps, sps); + } if (++track->audio.sub_packet_cnt >= h) { if (st->codec->codec_id == CODEC_ID_SIPR) @@ -2018,7 +2047,7 @@ static int matroska_read_seek(AVFormatContext *s, int stream_index, int64_t timestamp, int flags) { MatroskaDemuxContext *matroska = s->priv_data; - MatroskaTrack *tracks = matroska->tracks.elem; + MatroskaTrack *tracks = NULL; AVStream *st = s->streams[stream_index]; int i, index, index_sub, index_min; @@ -2047,6 +2076,7 @@ static int matroska_read_seek(AVFormatContext *s, int stream_index, return 0; index_min = index; + tracks = matroska->tracks.elem; for (i=0; i < matroska->tracks.nb_elem; i++) { tracks[i].audio.pkt_cnt = 0; tracks[i].audio.sub_packet_cnt = 0; @@ -2055,10 +2085,11 @@ static int matroska_read_seek(AVFormatContext *s, int stream_index, if (tracks[i].type == MATROSKA_TRACK_TYPE_SUBTITLE && !tracks[i].stream->discard != AVDISCARD_ALL) { index_sub = av_index_search_timestamp(tracks[i].stream, st->index_entries[index].timestamp, AVSEEK_FLAG_BACKWARD); - if (index_sub >= 0 - && st->index_entries[index_sub].pos < st->index_entries[index_min].pos - && st->index_entries[index].timestamp - st->index_entries[index_sub].timestamp < 30000000000/matroska->time_scale) - index_min = index_sub; + while(index_sub >= 0 + && index_min >= 0 + && tracks[i].stream->index_entries[index_sub].pos < st->index_entries[index_min].pos + && st->index_entries[index].timestamp - tracks[i].stream->index_entries[index_sub].timestamp < 30000000000/matroska->time_scale) + index_min--; } } diff --git a/libavformat/matroskaenc.c b/libavformat/matroskaenc.c index e74366fe95..1413bef048 100644 --- a/libavformat/matroskaenc.c +++ b/libavformat/matroskaenc.c @@ -776,7 +776,9 @@ static int mkv_write_tag(AVFormatContext *s, AVDictionary *m, unsigned int eleme end_ebml_master(s->pb, targets); while ((t = av_dict_get(m, "", t, AV_DICT_IGNORE_SUFFIX))) - if (av_strcasecmp(t->key, "title") && av_strcasecmp(t->key, "stereo_mode")) + if (av_strcasecmp(t->key, "title") && + av_strcasecmp(t->key, "stereo_mode") && + av_strcasecmp(t->key, "encoding_tool")) mkv_write_simpletag(s->pb, t); end_ebml_master(s->pb, tag); @@ -936,7 +938,10 @@ static int mkv_write_header(AVFormatContext *s) segment_uid[i] = av_lfg_get(&lfg); put_ebml_string(pb, MATROSKA_ID_MUXINGAPP , LIBAVFORMAT_IDENT); - put_ebml_string(pb, MATROSKA_ID_WRITINGAPP, LIBAVFORMAT_IDENT); + if ((tag = av_dict_get(s->metadata, "encoding_tool", NULL, 0))) + put_ebml_string(pb, MATROSKA_ID_WRITINGAPP, tag->value); + else + put_ebml_string(pb, MATROSKA_ID_WRITINGAPP, LIBAVFORMAT_IDENT); put_ebml_binary(pb, MATROSKA_ID_SEGMENTUID, segment_uid, 16); } @@ -1295,6 +1300,32 @@ static int mkv_query_codec(enum CodecID codec_id, int std_compliance) return 0; } +const AVCodecTag additional_audio_tags[] = { + { CODEC_ID_ALAC, 0XFFFFFFFF }, + { CODEC_ID_EAC3, 0XFFFFFFFF }, + { CODEC_ID_MLP, 0xFFFFFFFF }, + { CODEC_ID_PCM_S16BE, 0xFFFFFFFF }, + { CODEC_ID_PCM_S24BE, 0xFFFFFFFF }, + { CODEC_ID_PCM_S32BE, 0xFFFFFFFF }, + { CODEC_ID_QDM2, 0xFFFFFFFF }, + { CODEC_ID_RA_144, 0xFFFFFFFF }, + { CODEC_ID_RA_288, 0xFFFFFFFF }, + { CODEC_ID_COOK, 0xFFFFFFFF }, + { CODEC_ID_TRUEHD, 0xFFFFFFFF }, + { CODEC_ID_TTA, 0xFFFFFFFF }, + { CODEC_ID_WAVPACK, 0xFFFFFFFF }, + { CODEC_ID_NONE, 0xFFFFFFFF } +}; + +const AVCodecTag additional_video_tags[] = { + { CODEC_ID_PRORES, 0xFFFFFFFF }, + { CODEC_ID_RV10, 0xFFFFFFFF }, + { CODEC_ID_RV20, 0xFFFFFFFF }, + { CODEC_ID_RV30, 0xFFFFFFFF }, + { CODEC_ID_RV40, 0xFFFFFFFF }, + { CODEC_ID_NONE, 0xFFFFFFFF } +}; + #if CONFIG_MATROSKA_MUXER AVOutputFormat ff_matroska_muxer = { .name = "matroska", @@ -1316,6 +1347,10 @@ AVOutputFormat ff_matroska_muxer = { .write_packet = mkv_write_packet, .write_trailer = mkv_write_trailer, .flags = AVFMT_GLOBALHEADER | AVFMT_VARIABLE_FPS, + .codec_tag = (const AVCodecTag* const []){ + ff_codec_bmp_tags, ff_codec_wav_tags, + additional_audio_tags, additional_video_tags, 0 + }, .subtitle_codec = CODEC_ID_SSA, .query_codec = mkv_query_codec, }; @@ -1354,5 +1389,8 @@ AVOutputFormat ff_matroska_audio_muxer = { .write_packet = mkv_write_packet, .write_trailer = mkv_write_trailer, .flags = AVFMT_GLOBALHEADER, + .codec_tag = (const AVCodecTag* const []){ + ff_codec_wav_tags, additional_audio_tags, 0 + }, }; #endif diff --git a/libavformat/mm.c b/libavformat/mm.c index 8bb933babe..0e40c27f42 100644 --- a/libavformat/mm.c +++ b/libavformat/mm.c @@ -175,7 +175,6 @@ static int read_packet(AVFormatContext *s, case MM_TYPE_AUDIO : if (av_get_packet(s->pb, pkt, length)<0) return AVERROR(ENOMEM); - pkt->size = length; pkt->stream_index = 1; pkt->pts = mm->audio_pts++; return 0; diff --git a/libavformat/mov.c b/libavformat/mov.c index b584c0da42..3fcfa79703 100644 --- a/libavformat/mov.c +++ b/libavformat/mov.c @@ -25,12 +25,14 @@ //#define DEBUG //#define MOV_EXPORT_ALL_METADATA +#include "libavutil/audioconvert.h" #include "libavutil/intreadwrite.h" #include "libavutil/intfloat.h" #include "libavutil/mathematics.h" #include "libavutil/avstring.h" #include "libavutil/dict.h" #include "libavutil/opt.h" +#include "libavcodec/ac3tab.h" #include "avformat.h" #include "internal.h" #include "avio_internal.h" @@ -158,7 +160,7 @@ static int mov_read_mac_string(MOVContext *c, AVIOContext *pb, int len, uint8_t t, c = avio_r8(pb); if (c < 0x80 && p < end) *p++ = c; - else + else if (p < end) PUT_UTF8(mac_to_unicode[c-0x80], t, if (p < end) *p++ = t;); } *p = 0; @@ -243,7 +245,7 @@ static int mov_read_udta_string(MOVContext *c, AVIOContext *pb, MOVAtom atom) if (!key) return 0; - if (atom.size < 0) + if (atom.size < 0 || str_size >= INT_MAX/2) return AVERROR_INVALIDDATA; str_size = FFMIN3(sizeof(str)-1, str_size, atom.size); @@ -251,7 +253,7 @@ static int mov_read_udta_string(MOVContext *c, AVIOContext *pb, MOVAtom atom) if (parse) parse(c, pb, str_size, key); else { - if (data_type == 3 || (data_type == 0 && langcode < 0x800)) { // MAC Encoded + if (data_type == 3 || (data_type == 0 && (langcode < 0x400 || langcode == 0x7fff))) { // MAC Encoded mov_read_mac_string(c, pb, str_size, str, sizeof(str)); } else { avio_read(pb, str, str_size); @@ -358,6 +360,12 @@ static int mov_read_default(MOVContext *c, AVIOContext *pb, MOVAtom atom) left = a.size - avio_tell(pb) + start_pos; if (left > 0) /* skip garbage at atom end */ avio_skip(pb, left); + else if (left < 0) { + av_log(c->fc, AV_LOG_WARNING, + "overread end of atom '%.4s' by %"PRId64" bytes\n", + (char*)&a.type, -left); + avio_seek(pb, left, SEEK_CUR); + } } total_size += a.size; @@ -566,6 +574,9 @@ static int mov_read_dac3(MOVContext *c, AVIOContext *pb, MOVAtom atom) acmod = (ac3info >> 11) & 0x7; lfeon = (ac3info >> 10) & 0x1; st->codec->channels = ((int[]){2,1,2,3,3,4,4,5})[acmod] + lfeon; + st->codec->channel_layout = avpriv_ac3_channel_layout_tab[acmod]; + if (lfeon) + st->codec->channel_layout |= AV_CH_LOW_FREQUENCY; st->codec->audio_service_type = bsmod; if (st->codec->channels > 1 && bsmod == 0x7) st->codec->audio_service_type = AV_AUDIO_SERVICE_TYPE_KARAOKE; @@ -749,6 +760,11 @@ static int mov_read_mdhd(MOVContext *c, AVIOContext *pb, MOVAtom atom) st = c->fc->streams[c->fc->nb_streams-1]; sc = st->priv_data; + if (sc->time_scale) { + av_log(c->fc, AV_LOG_ERROR, "Multiple mdhd?\n"); + return AVERROR_INVALIDDATA; + } + version = avio_r8(pb); if (version > 1) { av_log_ask_for_sample(c, "unsupported version %d\n", version); @@ -796,7 +812,8 @@ static int mov_read_mvhd(MOVContext *c, AVIOContext *pb, MOVAtom atom) c->duration = (version == 1) ? avio_rb64(pb) : avio_rb32(pb); /* duration */ // set the AVCodecContext duration because the duration of individual tracks // may be inaccurate - c->fc->duration = av_rescale(c->duration, AV_TIME_BASE, c->time_scale); + if (c->time_scale > 0 && !c->trex_data) + c->fc->duration = av_rescale(c->duration, AV_TIME_BASE, c->time_scale); avio_rb32(pb); /* preferred scale */ avio_rb16(pb); /* preferred volume */ @@ -1566,8 +1583,11 @@ static int mov_read_stss(MOVContext *c, AVIOContext *pb, MOVAtom atom) av_dlog(c->fc, "keyframe_count = %d\n", entries); + if (!entries) + return 0; if (entries >= UINT_MAX / sizeof(int)) return AVERROR_INVALIDDATA; + av_freep(&sc->keyframes); sc->keyframes = av_malloc(entries * sizeof(int)); if (!sc->keyframes) return AVERROR(ENOMEM); @@ -1675,6 +1695,7 @@ static int mov_read_stts(MOVContext *c, AVIOContext *pb, MOVAtom atom) if (entries >= UINT_MAX / sizeof(*sc->stts_data)) return -1; + av_free(sc->stts_data); sc->stts_data = av_malloc(entries * sizeof(*sc->stts_data)); if (!sc->stts_data) return AVERROR(ENOMEM); @@ -1692,6 +1713,10 @@ static int mov_read_stts(MOVContext *c, AVIOContext *pb, MOVAtom atom) av_log(c->fc, AV_LOG_ERROR, "Invalid SampleDelta in STTS %d\n", sample_duration); sample_duration = 1; } + if (sample_count < 0) { + av_log(c->fc, AV_LOG_ERROR, "Invalid sample_count=%d\n", sample_count); + return AVERROR_INVALIDDATA; + } sc->stts_data[i].count= sample_count; sc->stts_data[i].duration= sample_duration; @@ -1760,6 +1785,7 @@ static void mov_build_index(MOVContext *mov, AVStream *st) unsigned int stps_index = 0; unsigned int i, j; uint64_t stream_size = 0; + AVIndexEntry *mem; /* adjust first dts according to edit list */ if ((sc->empty_duration || sc->start_time) && mov->time_scale > 0) { @@ -1789,12 +1815,13 @@ static void mov_build_index(MOVContext *mov, AVStream *st) if (!sc->sample_count) return; - if (sc->sample_count >= UINT_MAX / sizeof(*st->index_entries)) + if (sc->sample_count >= UINT_MAX / sizeof(*st->index_entries) - st->nb_index_entries) return; - st->index_entries = av_malloc(sc->sample_count*sizeof(*st->index_entries)); - if (!st->index_entries) + mem = av_realloc(st->index_entries, (st->nb_index_entries + sc->sample_count) * sizeof(*st->index_entries)); + if (!mem) return; - st->index_entries_allocated_size = sc->sample_count*sizeof(*st->index_entries); + st->index_entries = mem; + st->index_entries_allocated_size = (st->nb_index_entries + sc->sample_count) * sizeof(*st->index_entries); for (i = 0; i < sc->chunk_count; i++) { current_offset = sc->chunk_offsets[i]; @@ -1878,12 +1905,13 @@ static void mov_build_index(MOVContext *mov, AVStream *st) } av_dlog(mov->fc, "chunk count %d\n", total); - if (total >= UINT_MAX / sizeof(*st->index_entries)) + if (total >= UINT_MAX / sizeof(*st->index_entries) - st->nb_index_entries) return; - st->index_entries = av_malloc(total*sizeof(*st->index_entries)); - if (!st->index_entries) + mem = av_realloc(st->index_entries, (st->nb_index_entries + total) * sizeof(*st->index_entries)); + if (!mem) return; - st->index_entries_allocated_size = total*sizeof(*st->index_entries); + st->index_entries = mem; + st->index_entries_allocated_size = (st->nb_index_entries + total) * sizeof(*st->index_entries); // populate index for (i = 0; i < sc->chunk_count; i++) { @@ -2061,9 +2089,6 @@ static int mov_read_trak(MOVContext *c, AVIOContext *pb, MOVAtom atom) #if CONFIG_H263_DECODER case CODEC_ID_H263: #endif -#if CONFIG_H264_DECODER - case CODEC_ID_H264: -#endif #if CONFIG_MPEG4_DECODER case CODEC_ID_MPEG4: #endif @@ -2824,7 +2849,7 @@ static int mov_read_packet(AVFormatContext *s, AVPacket *pkt) pkt->stream_index = sc->ffindex; pkt->dts = sample->timestamp; - if (sc->ctts_data) { + if (sc->ctts_data && sc->ctts_index < sc->ctts_count) { pkt->pts = pkt->dts + sc->dts_shift + sc->ctts_data[sc->ctts_index].duration; /* update ctts context */ sc->ctts_sample++; diff --git a/libavformat/movenc.c b/libavformat/movenc.c index 6ed1005d33..15fa34c598 100644 --- a/libavformat/movenc.c +++ b/libavformat/movenc.c @@ -927,11 +927,12 @@ static int mov_write_video_tag(AVIOContext *pb, MOVTrack *track) mov_write_avcc_tag(pb, track); if(track->mode == MODE_IPOD) mov_write_uuid_tag_ipod(pb); - } else if (track->enc->field_order != AV_FIELD_UNKNOWN) - mov_write_fiel_tag(pb, track); - else if(track->vosLen > 0) + } else if(track->vosLen > 0) mov_write_glbl_tag(pb, track); + if (track->enc->field_order != AV_FIELD_UNKNOWN) + mov_write_fiel_tag(pb, track); + if (track->enc->sample_aspect_ratio.den && track->enc->sample_aspect_ratio.num && track->enc->sample_aspect_ratio.den != track->enc->sample_aspect_ratio.num) { mov_write_pasp_tag(pb, track); @@ -1695,7 +1696,8 @@ static int mov_write_ilst_tag(AVIOContext *pb, MOVMuxContext *mov, mov_write_string_metadata(s, pb, "\251wrt", "composer" , 1); mov_write_string_metadata(s, pb, "\251alb", "album" , 1); mov_write_string_metadata(s, pb, "\251day", "date" , 1); - mov_write_string_tag(pb, "\251too", LIBAVFORMAT_IDENT, 0, 1); + if (!mov_write_string_metadata(s, pb, "\251too", "encoding_tool", 1)) + mov_write_string_tag(pb, "\251too", LIBAVFORMAT_IDENT, 0, 1); mov_write_string_metadata(s, pb, "\251cmt", "comment" , 1); mov_write_string_metadata(s, pb, "\251gen", "genre" , 1); mov_write_string_metadata(s, pb, "\251cpy", "copyright", 1); @@ -2582,6 +2584,14 @@ static int mov_write_packet_internal(AVFormatContext *s, AVPacket *pkt) memcpy(trk->vosData, enc->extradata, trk->vosLen); } + if (enc->codec_id == CODEC_ID_AAC && pkt->size > 2 && + (AV_RB16(pkt->data) & 0xfff0) == 0xfff0) { + if (!s->streams[pkt->stream_index]->nb_frames) { + av_log(s, AV_LOG_ERROR, "malformated aac bitstream, use -absf aac_adtstoasc\n"); + return -1; + } + av_log(s, AV_LOG_WARNING, "aac bitstream error\n"); + } if (enc->codec_id == CODEC_ID_H264 && trk->vosLen > 0 && *(uint8_t *)trk->vosData != 1) { /* from x264 or from bytestream h264 */ /* nal reformating needed */ @@ -2592,10 +2602,6 @@ static int mov_write_packet_internal(AVFormatContext *s, AVPacket *pkt) } else { size = ff_avc_parse_nal_units(pb, pkt->data, pkt->size); } - } else if (enc->codec_id == CODEC_ID_AAC && pkt->size > 2 && - (AV_RB16(pkt->data) & 0xfff0) == 0xfff0) { - av_log(s, AV_LOG_ERROR, "malformated aac bitstream, use -absf aac_adtstoasc\n"); - return -1; } else { avio_write(pb, pkt->data, size); } diff --git a/libavformat/mpc8.c b/libavformat/mpc8.c index 01c1cc725b..01fdcec2a6 100644 --- a/libavformat/mpc8.c +++ b/libavformat/mpc8.c @@ -55,7 +55,7 @@ typedef struct { static inline int64_t bs_get_v(uint8_t **bs) { - int64_t v = 0; + uint64_t v = 0; int br = 0; int c; @@ -89,7 +89,7 @@ static int mpc8_probe(AVProbeData *p) size = bs_get_v(&bs); if (size < 2) return 0; - if (bs + size - 2 >= bs_end) + if (size >= bs_end - bs + 2) return AVPROBE_SCORE_MAX / 4 - 1; //seems to be valid MPC but no header yet if (header_found) { if (size < 11 || size > 28) @@ -106,7 +106,7 @@ static int mpc8_probe(AVProbeData *p) static inline int64_t gb_get_v(GetBitContext *gb) { - int64_t v = 0; + uint64_t v = 0; int bits = 0; while(get_bits1(gb) && bits < 64-7){ v <<= 7; @@ -137,12 +137,21 @@ static void mpc8_parse_seektable(AVFormatContext *s, int64_t off) int i, t, seekd; GetBitContext gb; + if (s->nb_streams == 0) { + av_log(s, AV_LOG_ERROR, "No stream added before parsing seek table\n"); + return; + } + avio_seek(s->pb, off, SEEK_SET); mpc8_get_chunk_header(s->pb, &tag, &size); if(tag != TAG_SEEKTABLE){ av_log(s, AV_LOG_ERROR, "No seek table at given position\n"); return; } + if (size < 0 || size >= INT_MAX / 2) { + av_log(s, AV_LOG_ERROR, "Bad seek table size\n"); + return; + } if(!(buf = av_malloc(size + FF_INPUT_BUFFER_PADDING_SIZE))) return; avio_read(s->pb, buf, size); @@ -205,6 +214,10 @@ static int mpc8_read_header(AVFormatContext *s, AVFormatParameters *ap) while(!url_feof(pb)){ pos = avio_tell(pb); mpc8_get_chunk_header(pb, &tag, &size); + if (size < 0) { + av_log(s, AV_LOG_ERROR, "Invalid chunk length\n"); + return AVERROR_INVALIDDATA; + } if(tag == TAG_STREAMHDR) break; mpc8_handle_chunk(s, tag, pos, size); diff --git a/libavformat/mpegts.c b/libavformat/mpegts.c index 8c1c557050..96400a9564 100644 --- a/libavformat/mpegts.c +++ b/libavformat/mpegts.c @@ -919,7 +919,7 @@ static int mpegts_push_data(MpegTSFilter *filter, /* we got the full header. We parse it and get the payload */ pes->state = MPEGTS_PAYLOAD; pes->data_index = 0; - if (pes->stream_type == 0x12) { + if (pes->stream_type == 0x12 && buf_size > 0) { int sl_header_bytes = read_sl_header(pes, &pes->sl, p, buf_size); pes->pes_header_size += sl_header_bytes; p += sl_header_bytes; @@ -1229,7 +1229,7 @@ static void m4sl_cb(MpegTSFilter *filter, const uint8_t *section, int section_le AVStream *st; if (ts->pids[pid]->es_id != mp4_descr[i].es_id) continue; - if (!(ts->pids[pid] && ts->pids[pid]->type == MPEGTS_PES)) { + if (ts->pids[pid]->type != MPEGTS_PES) { av_log(s, AV_LOG_ERROR, "pid %x is not PES\n", pid); continue; } @@ -1571,12 +1571,18 @@ static void pat_cb(MpegTSFilter *filter, const uint8_t *section, int section_len if (sid == 0x0000) { /* NIT info */ } else { + MpegTSFilter *fil = ts->pids[pmt_pid]; program = av_new_program(ts->stream, sid); program->program_num = sid; program->pmt_pid = pmt_pid; - if (ts->pids[pmt_pid]) - mpegts_close_filter(ts, ts->pids[pmt_pid]); - mpegts_open_section_filter(ts, pmt_pid, pmt_cb, ts, 1); + if (fil) + if ( fil->type != MPEGTS_SECTION + || fil->pid != pmt_pid + || fil->u.section_filter.section_cb != pmt_cb) + mpegts_close_filter(ts, ts->pids[pmt_pid]); + + if (!ts->pids[pmt_pid]) + mpegts_open_section_filter(ts, pmt_pid, pmt_cb, ts, 1); add_pat_entry(ts, sid); add_pid_to_pmt(ts, sid, 0); //add pat pid to program add_pid_to_pmt(ts, sid, pmt_pid); @@ -1626,7 +1632,7 @@ static void sdt_cb(MpegTSFilter *filter, const uint8_t *section, int section_len break; desc_len = get8(&p, desc_list_end); desc_end = p + desc_len; - if (desc_end > desc_list_end) + if (desc_len < 0 || desc_end > desc_list_end) break; av_dlog(ts->stream, "tag: 0x%02x len=%d\n", @@ -1813,7 +1819,7 @@ static int read_packet(AVFormatContext *s, uint8_t *buf, int raw_packet_size) static int handle_packets(MpegTSContext *ts, int nb_packets) { AVFormatContext *s = ts->stream; - uint8_t packet[TS_PACKET_SIZE]; + uint8_t packet[TS_PACKET_SIZE+FF_INPUT_BUFFER_PADDING_SIZE]; int packet_num, ret = 0; if (avio_tell(s->pb) != ts->last_pos) { @@ -1835,6 +1841,7 @@ static int handle_packets(MpegTSContext *ts, int nb_packets) ts->stop_parse = 0; packet_num = 0; + memset(packet + TS_PACKET_SIZE, 0, FF_INPUT_BUFFER_PADDING_SIZE); for(;;) { packet_num++; if (nb_packets != 0 && packet_num >= nb_packets || diff --git a/libavformat/mpegtsenc.c b/libavformat/mpegtsenc.c index 043e578130..261078c757 100644 --- a/libavformat/mpegtsenc.c +++ b/libavformat/mpegtsenc.c @@ -111,6 +111,10 @@ static const AVClass mpegts_muxer_class = { .version = LIBAVUTIL_VERSION_INT, }; +/* The section length is 12 bits. The first 2 are set to 0, the remaining + * 10 bits should not exceed 1021. */ +#define SECTION_LENGTH 1020 + /* NOTE: 4 bytes must be left at the end for the crc32 */ static void mpegts_write_section(MpegTSSection *s, uint8_t *buf, int len) { @@ -222,7 +226,7 @@ static void mpegts_write_pat(AVFormatContext *s) { MpegTSWrite *ts = s->priv_data; MpegTSService *service; - uint8_t data[1012], *q; + uint8_t data[SECTION_LENGTH], *q; int i; q = data; @@ -235,11 +239,10 @@ static void mpegts_write_pat(AVFormatContext *s) data, q - data); } -static void mpegts_write_pmt(AVFormatContext *s, MpegTSService *service) +static int mpegts_write_pmt(AVFormatContext *s, MpegTSService *service) { - // MpegTSWrite *ts = s->priv_data; - uint8_t data[1012], *q, *desc_length_ptr, *program_info_length_ptr; - int val, stream_type, i; + uint8_t data[SECTION_LENGTH], *q, *desc_length_ptr, *program_info_length_ptr; + int val, stream_type, i, err = 0; q = data; put16(&q, 0xe000 | service->pcr_pid); @@ -257,6 +260,11 @@ static void mpegts_write_pmt(AVFormatContext *s, MpegTSService *service) AVStream *st = s->streams[i]; MpegTSWriteStream *ts_st = st->priv_data; AVDictionaryEntry *lang = av_dict_get(st->metadata, "language", NULL,0); + + if (q - data > SECTION_LENGTH - 3 - 2 - 6) { + err = 1; + break; + } switch(st->codec->codec_id) { case CODEC_ID_MPEG1VIDEO: case CODEC_ID_MPEG2VIDEO: @@ -288,6 +296,10 @@ static void mpegts_write_pmt(AVFormatContext *s, MpegTSService *service) stream_type = STREAM_TYPE_PRIVATE_DATA; break; } + + if (q - data > sizeof(data) - 32) + return AVERROR(EINVAL); + *q++ = stream_type; put16(&q, 0xe000 | ts_st->pid); desc_length_ptr = q; @@ -312,6 +324,10 @@ static void mpegts_write_pmt(AVFormatContext *s, MpegTSService *service) *len_ptr = 0; for (p = lang->value; next && *len_ptr < 255 / 4 * 4; p = next + 1) { + if (q - data > SECTION_LENGTH - 4) { + err = 1; + break; + } next = strchr(p, ','); if (strlen(p) != 3 && (!next || next != p + 3)) continue; /* not a 3-letter code */ @@ -346,6 +362,11 @@ static void mpegts_write_pmt(AVFormatContext *s, MpegTSService *service) *q++ = language[1]; *q++ = language[2]; *q++ = 0x10; /* normal subtitles (0x20 = if hearing pb) */ + + if (q - data > SECTION_LENGTH - 4) { + err = 1; + break; + } if(st->codec->extradata_size == 4) { memcpy(q, st->codec->extradata, 4); q += 4; @@ -371,8 +392,17 @@ static void mpegts_write_pmt(AVFormatContext *s, MpegTSService *service) desc_length_ptr[0] = val >> 8; desc_length_ptr[1] = val; } + + if (err) + av_log(s, AV_LOG_ERROR, + "The PMT section is too small for stream %d and following.\n" + "Try reducing the number of languages in the audio streams " + "or the total number of streams.\n", + i); + mpegts_write_section1(&service->pmt, PMT_TID, service->sid, 0, 0, 0, data, q - data); + return 0; } /* NOTE: str == NULL is accepted for an empty string */ @@ -396,7 +426,7 @@ static void mpegts_write_sdt(AVFormatContext *s) { MpegTSWrite *ts = s->priv_data; MpegTSService *service; - uint8_t data[1012], *q, *desc_list_len_ptr, *desc_len_ptr; + uint8_t data[SECTION_LENGTH], *q, *desc_list_len_ptr, *desc_len_ptr; int i, running_status, free_ca_mode, val; q = data; diff --git a/libavformat/mvi.c b/libavformat/mvi.c index 70a9b66919..6dfb28ffdb 100644 --- a/libavformat/mvi.c +++ b/libavformat/mvi.c @@ -91,6 +91,12 @@ static int read_header(AVFormatContext *s, AVFormatParameters *ap) mvi->get_int = (vst->codec->width * vst->codec->height < (1 << 16)) ? avio_rl16 : avio_rl24; mvi->audio_frame_size = ((uint64_t)mvi->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 (%d) or frames_count (%d)\n", + mvi->audio_data_size, frames_count); + return AVERROR_INVALIDDATA; + } + mvi->audio_size_counter = (ast->codec->sample_rate * 830 / mvi->audio_frame_size - 1) * mvi->audio_frame_size; mvi->audio_size_left = mvi->audio_data_size; diff --git a/libavformat/mxfdec.c b/libavformat/mxfdec.c index cb38e5caaf..b7bb4dff19 100644 --- a/libavformat/mxfdec.c +++ b/libavformat/mxfdec.c @@ -1397,8 +1397,17 @@ static int mxf_parse_structural_metadata(MXFContext *mxf) st->codec->codec_id = container_ul->id; st->codec->channels = descriptor->channels; st->codec->bits_per_coded_sample = descriptor->bits_per_sample; - if (descriptor->sample_rate.den > 0) - st->codec->sample_rate = descriptor->sample_rate.num / descriptor->sample_rate.den; + if (descriptor->sample_rate.den > 0) { + st->codec->sample_rate = descriptor->sample_rate.num / descriptor->sample_rate.den; + avpriv_set_pts_info(st, 64, descriptor->sample_rate.den, descriptor->sample_rate.num); + } else { + av_log(mxf->fc, AV_LOG_WARNING, "invalid sample rate (%d/%d) " + "found for stream #%d, time base forced to 1/48000\n", + descriptor->sample_rate.num, descriptor->sample_rate.den, + st->index); + avpriv_set_pts_info(st, 64, 1, 48000); + } + /* TODO: implement CODEC_ID_RAWAUDIO */ if (st->codec->codec_id == CODEC_ID_PCM_S16LE) { if (descriptor->bits_per_sample > 16 && descriptor->bits_per_sample <= 24) @@ -1725,6 +1734,9 @@ static int mxf_read_header(AVFormatContext *s, AVFormatParameters *ap) /* next partition pack - keep going, seek to previous partition or stop */ if(mxf_parse_handle_partition_or_eof(mxf) <= 0) break; + else if (mxf->parsing_backward) + continue; + /* we're still parsing forward. proceed to parsing this partition pack */ } for (metadata = mxf_metadata_read_table; metadata->read; metadata++) { diff --git a/libavformat/nsvdec.c b/libavformat/nsvdec.c index 6a6830ee9f..9e9b161e2d 100644 --- a/libavformat/nsvdec.c +++ b/libavformat/nsvdec.c @@ -313,7 +313,7 @@ static int nsv_parse_NSVf_header(AVFormatContext *s, AVFormatParameters *ap) char *token, *value; char quote; - p = strings = av_mallocz(strings_size + 1); + p = strings = av_mallocz((size_t)strings_size + 1); if (!p) return AVERROR(ENOMEM); endp = strings + strings_size; @@ -350,6 +350,8 @@ static int nsv_parse_NSVf_header(AVFormatContext *s, AVFormatParameters *ap) if((unsigned)table_entries_used >= UINT_MAX / sizeof(uint32_t)) return -1; nsv->nsvs_file_offset = av_malloc((unsigned)table_entries_used * sizeof(uint32_t)); + if (!nsv->nsvs_file_offset) + return AVERROR(ENOMEM); for(i=0;insvs_file_offset[i] = avio_rl32(pb) + size; @@ -357,6 +359,8 @@ static int nsv_parse_NSVf_header(AVFormatContext *s, AVFormatParameters *ap) if(table_entries > table_entries_used && avio_rl32(pb) == MKTAG('T','O','C','2')) { nsv->nsvs_timestamps = av_malloc((unsigned)table_entries_used*sizeof(uint32_t)); + if (!nsv->nsvs_timestamps) + return AVERROR(ENOMEM); for(i=0;insvs_timestamps[i] = avio_rl32(pb); } @@ -527,11 +531,16 @@ static int nsv_read_header(AVFormatContext *s, AVFormatParameters *ap) for (i = 0; i < NSV_MAX_RESYNC_TRIES; i++) { if (nsv_resync(s) < 0) return -1; - if (nsv->state == NSV_FOUND_NSVF) + if (nsv->state == NSV_FOUND_NSVF) { err = nsv_parse_NSVf_header(s, ap); + if (err < 0) + return err; + } /* we need the first NSVs also... */ if (nsv->state == NSV_FOUND_NSVS) { err = nsv_parse_NSVs_header(s, ap); + if (err < 0) + return err; break; /* we just want the first one */ } } diff --git a/libavformat/nutdec.c b/libavformat/nutdec.c index 5dd687c55d..319f9ff6cd 100644 --- a/libavformat/nutdec.c +++ b/libavformat/nutdec.c @@ -81,16 +81,8 @@ static inline int64_t get_s_trace(AVIOContext *bc, char *file, char *func, int l av_log(NULL, AV_LOG_DEBUG, "get_s %5"PRId64" / %"PRIX64" in %s %s:%d\n", v, v, file, func, line); return v; } - -static inline uint64_t get_vb_trace(AVIOContext *bc, char *file, char *func, int line){ - uint64_t v= get_vb(bc); - - av_log(NULL, AV_LOG_DEBUG, "get_vb %5"PRId64" / %"PRIX64" in %s %s:%d\n", v, v, file, func, line); - return v; -} #define ffio_read_varlen(bc) get_v_trace(bc, __FILE__, __PRETTY_FUNCTION__, __LINE__) #define get_s(bc) get_s_trace(bc, __FILE__, __PRETTY_FUNCTION__, __LINE__) -#define get_vb(bc) get_vb_trace(bc, __FILE__, __PRETTY_FUNCTION__, __LINE__) #endif static int get_packetheader(NUTContext *nut, AVIOContext *bc, int calculate_checksum, uint64_t startcode) diff --git a/libavformat/oggdec.c b/libavformat/oggdec.c index ceb4091c6e..5e9db4a28d 100644 --- a/libavformat/oggdec.c +++ b/libavformat/oggdec.c @@ -69,8 +69,7 @@ static int ogg_save(AVFormatContext *s) for (i = 0; i < ogg->nstreams; i++){ struct ogg_stream *os = ogg->streams + i; - os->buf = av_malloc (os->bufsize); - memset (os->buf, 0, os->bufsize); + os->buf = av_mallocz (os->bufsize + FF_INPUT_BUFFER_PADDING_SIZE); memcpy (os->buf, ost->streams[i].buf, os->bufpos); } @@ -161,13 +160,18 @@ static int ogg_new_stream(AVFormatContext *s, uint32_t serial, int new_avstream) AVStream *st; struct ogg_stream *os; - ogg->streams = av_realloc (ogg->streams, - ogg->nstreams * sizeof (*ogg->streams)); + os = av_realloc (ogg->streams, ogg->nstreams * sizeof (*ogg->streams)); + + if (!os) + return AVERROR(ENOMEM); + + ogg->streams = os; + memset (ogg->streams + idx, 0, sizeof (*ogg->streams)); os = ogg->streams + idx; os->serial = serial; os->bufsize = DECODER_BUFFER_SIZE; - os->buf = av_malloc(os->bufsize); + os->buf = av_malloc(os->bufsize + FF_INPUT_BUFFER_PADDING_SIZE); os->header = -1; if (new_avstream) { @@ -185,7 +189,7 @@ static int ogg_new_stream(AVFormatContext *s, uint32_t serial, int new_avstream) static int ogg_new_buf(struct ogg *ogg, int idx) { struct ogg_stream *os = ogg->streams + idx; - uint8_t *nb = av_malloc(os->bufsize); + uint8_t *nb = av_malloc(os->bufsize + FF_INPUT_BUFFER_PADDING_SIZE); int size = os->bufpos - os->pstart; if(os->buf){ memcpy(nb, os->buf + os->pstart, size); @@ -296,7 +300,9 @@ static int ogg_read_page(AVFormatContext *s, int *str) } if (os->bufsize - os->bufpos < size){ - uint8_t *nb = av_malloc (os->bufsize *= 2); + uint8_t *nb = av_malloc ((os->bufsize *= 2) + FF_INPUT_BUFFER_PADDING_SIZE); + if (!nb) + return AVERROR(ENOMEM); memcpy (nb, os->buf, os->bufpos); av_free (os->buf); os->buf = nb; @@ -310,6 +316,7 @@ static int ogg_read_page(AVFormatContext *s, int *str) os->granule = gp; os->flags = flags; + memset(os->buf + os->bufpos, 0, FF_INPUT_BUFFER_PADDING_SIZE); if (str) *str = idx; @@ -368,7 +375,11 @@ static int ogg_packet(AVFormatContext *s, int *str, int *dstart, int *dsize, if (!complete && os->segp == os->nsegs){ ogg->curidx = -1; - os->incomplete = 1; + // Do not set incomplete for empty packets. + // Together with the code in ogg_read_page + // that discards all continuation of empty packets + // we would get an infinite loop. + os->incomplete = !!os->psize; } }while (!complete); @@ -518,15 +529,34 @@ static int ogg_get_length(AVFormatContext *s) return 0; } -static int ogg_read_header(AVFormatContext *s, AVFormatParameters *ap) +static int ogg_read_close(AVFormatContext *s) +{ + struct ogg *ogg = s->priv_data; + int i; + + for (i = 0; i < ogg->nstreams; i++) { + av_free(ogg->streams[i].buf); + if (ogg->streams[i].codec && + ogg->streams[i].codec->cleanup) { + ogg->streams[i].codec->cleanup(s, i); + } + av_free(ogg->streams[i].private); + } + av_free(ogg->streams); + return 0; +} + +static int ogg_read_header(AVFormatContext *s) { struct ogg *ogg = s->priv_data; int ret, i; ogg->curidx = -1; //linear headers seek from start ret = ogg_get_headers(s); - if (ret < 0) + if (ret < 0) { + ogg_read_close(s); return ret; + } for (i = 0; i < ogg->nstreams; i++) if (ogg->streams[i].header < 0) @@ -611,19 +641,6 @@ retry: return psize; } -static int ogg_read_close(AVFormatContext *s) -{ - struct ogg *ogg = s->priv_data; - int i; - - for (i = 0; i < ogg->nstreams; i++){ - av_free (ogg->streams[i].buf); - av_free (ogg->streams[i].private); - } - av_free (ogg->streams); - return 0; -} - static int64_t ogg_read_timestamp(AVFormatContext *s, int stream_index, int64_t *pos_arg, int64_t pos_limit) { diff --git a/libavformat/oggdec.h b/libavformat/oggdec.h index 7f5452f2b0..cbe29f2552 100644 --- a/libavformat/oggdec.h +++ b/libavformat/oggdec.h @@ -51,6 +51,11 @@ struct ogg_codec { * 0 if granule is the end time of the associated packet. */ int granule_is_start; + /** + * Number of expected headers + */ + int nb_header; + void (*cleanup)(AVFormatContext *s, int idx); }; struct ogg_stream { diff --git a/libavformat/oggparseogm.c b/libavformat/oggparseogm.c index 0a8a7c6bd4..b74537c689 100644 --- a/libavformat/oggparseogm.c +++ b/libavformat/oggparseogm.c @@ -37,62 +37,69 @@ ogm_header(AVFormatContext *s, int idx) struct ogg *ogg = s->priv_data; struct ogg_stream *os = ogg->streams + idx; AVStream *st = s->streams[idx]; - const uint8_t *p = os->buf + os->pstart; + GetByteContext p; uint64_t time_unit; uint64_t spu; - if(!(*p & 1)) + bytestream2_init(&p, os->buf + os->pstart, os->psize); + if (!(bytestream2_peek_byte(&p) & 1)) return 0; - if(*p == 1) { - p++; + if (bytestream2_peek_byte(&p) == 1) { + bytestream2_skip(&p, 1); - if(*p == 'v'){ + if (bytestream2_peek_byte(&p) == 'v'){ int tag; st->codec->codec_type = AVMEDIA_TYPE_VIDEO; - p += 8; - tag = bytestream_get_le32(&p); + bytestream2_skip(&p, 8); + tag = bytestream2_get_le32(&p); st->codec->codec_id = ff_codec_get_id(ff_codec_bmp_tags, tag); st->codec->codec_tag = tag; - } else if (*p == 't') { + } else if (bytestream2_peek_byte(&p) == 't') { st->codec->codec_type = AVMEDIA_TYPE_SUBTITLE; st->codec->codec_id = CODEC_ID_TEXT; - p += 12; + bytestream2_skip(&p, 12); } else { - uint8_t acid[5]; + uint8_t acid[5] = { 0 }; int cid; st->codec->codec_type = AVMEDIA_TYPE_AUDIO; - p += 8; - bytestream_get_buffer(&p, acid, 4); + bytestream2_skip(&p, 8); + bytestream2_get_buffer(&p, acid, 4); acid[4] = 0; cid = strtol(acid, NULL, 16); st->codec->codec_id = ff_codec_get_id(ff_codec_wav_tags, cid); st->need_parsing = AVSTREAM_PARSE_FULL; } - p += 4; /* useless size field */ + bytestream2_skip(&p, 4); /* useless size field */ - time_unit = bytestream_get_le64(&p); - spu = bytestream_get_le64(&p); - p += 4; /* default_len */ - p += 8; /* buffersize + bits_per_sample */ + time_unit = bytestream2_get_le64(&p); + spu = bytestream2_get_le64(&p); + if (!time_unit || !spu) { + av_log(s, AV_LOG_ERROR, "Invalid timing values.\n"); + return AVERROR_INVALIDDATA; + } + + bytestream2_skip(&p, 4); /* default_len */ + bytestream2_skip(&p, 8); /* buffersize + bits_per_sample */ if(st->codec->codec_type == AVMEDIA_TYPE_VIDEO){ - st->codec->width = bytestream_get_le32(&p); - st->codec->height = bytestream_get_le32(&p); + st->codec->width = bytestream2_get_le32(&p); + st->codec->height = bytestream2_get_le32(&p); st->codec->time_base.den = spu * 10000000; st->codec->time_base.num = time_unit; avpriv_set_pts_info(st, 64, st->codec->time_base.num, st->codec->time_base.den); } else { - st->codec->channels = bytestream_get_le16(&p); - p += 2; /* block_align */ - st->codec->bit_rate = bytestream_get_le32(&p) * 8; + st->codec->channels = bytestream2_get_le16(&p); + bytestream2_skip(&p, 2); /* block_align */ + st->codec->bit_rate = bytestream2_get_le32(&p) * 8; st->codec->sample_rate = spu * 10000000 / time_unit; avpriv_set_pts_info(st, 64, 1, st->codec->sample_rate); } - } else if (*p == 3) { - if (os->psize > 8) - ff_vorbis_comment(s, &st->metadata, p+7, os->psize-8); + } else if (bytestream2_peek_byte(&p) == 3) { + bytestream2_skip(&p, 7); + if (bytestream2_get_bytes_left(&p) > 1) + ff_vorbis_comment(s, &st->metadata, p.buffer, bytestream2_get_bytes_left(&p) - 1); } return 1; diff --git a/libavformat/oggparsevorbis.c b/libavformat/oggparsevorbis.c index ba9b348456..272e50c9bb 100644 --- a/libavformat/oggparsevorbis.c +++ b/libavformat/oggparsevorbis.c @@ -188,6 +188,16 @@ fixup_vorbis_headers(AVFormatContext * as, struct oggvorbis_private *priv, return offset; } +static void vorbis_cleanup(AVFormatContext *s, int idx) +{ + struct ogg *ogg = s->priv_data; + struct ogg_stream *os = ogg->streams + idx; + struct oggvorbis_private *priv = os->private; + int i; + if (os->private) + for (i = 0; i < 3; i++) + av_freep(&priv->packet[i]); +} static int vorbis_header (AVFormatContext * s, int idx) @@ -198,15 +208,15 @@ vorbis_header (AVFormatContext * s, int idx) struct oggvorbis_private *priv; int pkt_type = os->buf[os->pstart]; - if (!(pkt_type & 1)) - return 0; - if (!os->private) { os->private = av_mallocz(sizeof(struct oggvorbis_private)); if (!os->private) return 0; } + if (!(pkt_type & 1)) + return 0; + if (os->psize < 1 || pkt_type > 5) return -1; @@ -278,5 +288,7 @@ vorbis_header (AVFormatContext * s, int idx) const struct ogg_codec ff_vorbis_codec = { .magic = "\001vorbis", .magicsize = 7, - .header = vorbis_header + .header = vorbis_header, + .cleanup= vorbis_cleanup, + .nb_header = 3, }; diff --git a/libavformat/oma.c b/libavformat/oma.c index 30e86f10bb..0cec34b560 100644 --- a/libavformat/oma.c +++ b/libavformat/oma.c @@ -22,7 +22,7 @@ #include "oma.h" #include "libavcodec/avcodec.h" -const uint16_t ff_oma_srate_tab[6] = { 320, 441, 480, 882, 960, 0 }; +const uint16_t ff_oma_srate_tab[8] = { 320, 441, 480, 882, 960, 0 }; const AVCodecTag ff_oma_codec_tags[] = { { CODEC_ID_ATRAC3, OMA_CODECID_ATRAC3 }, diff --git a/libavformat/oma.h b/libavformat/oma.h index bac8bcb736..1f0ddf9a88 100644 --- a/libavformat/oma.h +++ b/libavformat/oma.h @@ -37,7 +37,7 @@ enum { OMA_CODECID_WMA = 5, }; -extern const uint16_t ff_oma_srate_tab[6]; +extern const uint16_t ff_oma_srate_tab[8]; extern const AVCodecTag ff_oma_codec_tags[]; diff --git a/libavformat/omadec.c b/libavformat/omadec.c index 2980f6fee5..93c661e615 100644 --- a/libavformat/omadec.c +++ b/libavformat/omadec.c @@ -113,13 +113,18 @@ static int kset(AVFormatContext *s, const uint8_t *r_val, const uint8_t *n_val, return 0; } -static int rprobe(AVFormatContext *s, uint8_t *enc_header, const uint8_t *r_val) +#define OMA_RPROBE_M_VAL 48 + 1 + +static int rprobe(AVFormatContext *s, uint8_t *enc_header, unsigned size, + const uint8_t *r_val) { OMAContext *oc = s->priv_data; unsigned int pos; struct AVDES av_des; - if (!enc_header || !r_val) + if (!enc_header || !r_val || + size < OMA_ENC_HEADER_SIZE + oc->k_size + oc->e_size + oc->i_size || + size < OMA_RPROBE_M_VAL) return -1; /* m_val */ @@ -140,19 +145,25 @@ static int rprobe(AVFormatContext *s, uint8_t *enc_header, const uint8_t *r_val) return memcmp(&enc_header[pos], oc->sm_val, 8) ? -1 : 0; } -static int nprobe(AVFormatContext *s, uint8_t *enc_header, int size, const uint8_t *n_val) +static int nprobe(AVFormatContext *s, uint8_t *enc_header, unsigned size, + const uint8_t *n_val) { OMAContext *oc = s->priv_data; - uint32_t pos, taglen, datalen; + uint64_t pos; + uint32_t taglen, datalen; struct AVDES av_des; - if (!enc_header || !n_val) + if (!enc_header || !n_val || + size < OMA_ENC_HEADER_SIZE + oc->k_size + 4) return -1; pos = OMA_ENC_HEADER_SIZE + oc->k_size; if (!memcmp(&enc_header[pos], "EKB ", 4)) pos += 32; + if (size < pos + 44) + return -1; + if (AV_RB32(&enc_header[pos]) != oc->rid) av_log(s, AV_LOG_DEBUG, "Mismatching RID\n"); @@ -162,13 +173,20 @@ static int nprobe(AVFormatContext *s, uint8_t *enc_header, int size, const uint8 if(taglen + (((uint64_t)datalen)<<4) + 44 > size) return -1; - pos += 44 + taglen; + pos += 44; + if (size - pos < taglen) + return -1; + + pos += taglen; + + if (datalen << 4 > size - pos) + return -1; av_des_init(&av_des, n_val, 192, 1); while (datalen-- > 0) { av_des_crypt(&av_des, oc->r_val, &enc_header[pos], 2, NULL, 1); kset(s, oc->r_val, NULL, 16); - if (!rprobe(s, enc_header, oc->r_val)) + if (!rprobe(s, enc_header, size, oc->r_val)) return 0; pos += 16; } @@ -231,15 +249,16 @@ static int decrypt_init(AVFormatContext *s, ID3v2ExtraMeta *em, uint8_t *header) kset(s, s->key, s->key, s->keylen); } if (!memcmp(oc->r_val, (const uint8_t[8]){0}, 8) || - rprobe(s, gdata, oc->r_val) < 0 && + rprobe(s, gdata, geob->datasize, oc->r_val) < 0 && nprobe(s, gdata, geob->datasize, oc->n_val) < 0) { int i; - for (i = 0; i < sizeof(leaf_table); i += 2) { + for (i = 0; i < FF_ARRAY_ELEMS(leaf_table); i += 2) { uint8_t buf[16]; AV_WL64(buf, leaf_table[i]); AV_WL64(&buf[8], leaf_table[i+1]); kset(s, buf, buf, 16); - if (!rprobe(s, gdata, oc->r_val) || !nprobe(s, gdata, geob->datasize, oc->n_val)) + if (!rprobe(s, gdata, geob->datasize, oc->r_val) || + !nprobe(s, gdata, geob->datasize, oc->n_val)) break; } if (i >= sizeof(leaf_table)) { @@ -305,7 +324,11 @@ static int oma_read_header(AVFormatContext *s, switch (buf[32]) { case OMA_CODECID_ATRAC3: - samplerate = ff_oma_srate_tab[(codec_params >> 13) & 7]*100; + samplerate = ff_oma_srate_tab[(codec_params >> 13) & 7] * 100; + if (!samplerate) { + av_log(s, AV_LOG_ERROR, "Unsupported sample rate\n"); + return AVERROR_INVALIDDATA; + } if (samplerate != 44100) av_log_ask_for_sample(s, "Unsupported sample rate: %d\n", samplerate); @@ -335,9 +358,14 @@ static int oma_read_header(AVFormatContext *s, case OMA_CODECID_ATRAC3P: st->codec->channels = (codec_params >> 10) & 7; framesize = ((codec_params & 0x3FF) * 8) + 8; - st->codec->sample_rate = ff_oma_srate_tab[(codec_params >> 13) & 7]*100; - st->codec->bit_rate = st->codec->sample_rate * framesize * 8 / 1024; - avpriv_set_pts_info(st, 64, 1, st->codec->sample_rate); + samplerate = ff_oma_srate_tab[(codec_params >> 13) & 7] * 100; + if (!samplerate) { + av_log(s, AV_LOG_ERROR, "Unsupported sample rate\n"); + return AVERROR_INVALIDDATA; + } + st->codec->sample_rate = samplerate; + st->codec->bit_rate = samplerate * framesize * 8 / 1024; + avpriv_set_pts_info(st, 64, 1, samplerate); av_log(s, AV_LOG_ERROR, "Unsupported codec ATRAC3+!\n"); break; case OMA_CODECID_MP3: @@ -371,14 +399,22 @@ static int oma_read_packet(AVFormatContext *s, AVPacket *pkt) int packet_size = s->streams[0]->codec->block_align; int ret = av_get_packet(s->pb, pkt, packet_size); + if (ret < packet_size) + pkt->flags |= AV_PKT_FLAG_CORRUPT; + if (ret <= 0) return AVERROR(EIO); pkt->stream_index = 0; if (oc->encrypted) { - /* previous unencrypted block saved in IV for the next packet (CBC mode) */ - av_des_crypt(&oc->av_des, pkt->data, pkt->data, (packet_size >> 3), oc->iv, 1); + /* previous unencrypted block saved in IV for + * the next packet (CBC mode) */ + if (ret == packet_size) + av_des_crypt(&oc->av_des, pkt->data, pkt->data, + (packet_size >> 3), oc->iv, 1); + else + memset(oc->iv, 0, 8); } return ret; @@ -416,22 +452,26 @@ static int oma_read_seek(struct AVFormatContext *s, int stream_index, int64_t ti { OMAContext *oc = s->priv_data; - pcm_read_seek(s, stream_index, timestamp, flags); + int err = pcm_read_seek(s, stream_index, timestamp, flags); - if (oc->encrypted) { - /* readjust IV for CBC */ - int64_t pos = avio_tell(s->pb); - if (pos < oc->content_start) - memset(oc->iv, 0, 8); - else { - if (avio_seek(s->pb, -8, SEEK_CUR) < 0 || avio_read(s->pb, oc->iv, 8) < 8) { - memset(oc->iv, 0, 8); - return -1; - } - } + if (!oc->encrypted) + return err; + + /* readjust IV for CBC */ + if (err || avio_tell(s->pb) < oc->content_start) + goto wipe; + if ((err = avio_seek(s->pb, -8, SEEK_CUR)) < 0) + goto wipe; + if ((err = avio_read(s->pb, oc->iv, 8)) < 8) { + if (err >= 0) + err = AVERROR_EOF; + goto wipe; } return 0; +wipe: + memset(oc->iv, 0, 8); + return err; } AVInputFormat ff_oma_demuxer = { diff --git a/libavformat/r3d.c b/libavformat/r3d.c index 874c361406..ada239f550 100644 --- a/libavformat/r3d.c +++ b/libavformat/r3d.c @@ -277,6 +277,10 @@ static int r3d_read_reda(AVFormatContext *s, AVPacket *pkt, Atom *atom) dts = avio_rb32(s->pb); st->codec->sample_rate = avio_rb32(s->pb); + if (st->codec->sample_rate <= 0) { + av_log(s, AV_LOG_ERROR, "Bad sample rate\n"); + return AVERROR_INVALIDDATA; + } samples = avio_rb32(s->pb); diff --git a/libavformat/riff.c b/libavformat/riff.c index 4efd1ad756..703e820333 100644 --- a/libavformat/riff.c +++ b/libavformat/riff.c @@ -600,6 +600,11 @@ int ff_get_wav_header(AVIOContext *pb, AVCodecContext *codec, int size) if (size > 0) avio_skip(pb, size); } + if (codec->sample_rate <= 0) { + av_log(NULL, AV_LOG_ERROR, + "Invalid sample rate: %d\n", codec->sample_rate); + return AVERROR_INVALIDDATA; + } if (codec->codec_id == CODEC_ID_AAC_LATM) { /* channels and sample_rate values are those prior to applying SBR and/or PS */ codec->channels = 0; @@ -707,8 +712,13 @@ int ff_read_riff_info(AVFormatContext *s, int64_t size) chunk_code = avio_rl32(pb); chunk_size = avio_rl32(pb); if (chunk_size > end || end - chunk_size < cur || chunk_size == UINT_MAX) { - av_log(s, AV_LOG_ERROR, "too big INFO subchunk\n"); - return AVERROR_INVALIDDATA; + avio_seek(pb, -9, SEEK_CUR); + chunk_code = avio_rl32(pb); + chunk_size = avio_rl32(pb); + if (chunk_size > end || end - chunk_size < cur || chunk_size == UINT_MAX) { + av_log(s, AV_LOG_ERROR, "too big INFO subchunk\n"); + return AVERROR_INVALIDDATA; + } } chunk_size += (chunk_size & 1); diff --git a/libavformat/rl2.c b/libavformat/rl2.c index 78edec5b18..cd4f51a097 100644 --- a/libavformat/rl2.c +++ b/libavformat/rl2.c @@ -109,6 +109,10 @@ static av_cold int rl2_read_header(AVFormatContext *s, rate = avio_rl16(pb); channels = avio_rl16(pb); def_sound_size = avio_rl16(pb); + if (!channels || channels > 42) { + av_log(s, AV_LOG_ERROR, "Invalid number of channels: %d\n", channels); + return AVERROR_INVALIDDATA; + } /** setup video stream */ st = avformat_new_stream(s, NULL); diff --git a/libavformat/rmdec.c b/libavformat/rmdec.c index ae6cda3866..5fe853974d 100644 --- a/libavformat/rmdec.c +++ b/libavformat/rmdec.c @@ -107,13 +107,14 @@ static int rm_read_extradata(AVIOContext *pb, AVCodecContext *avctx, unsigned si return 0; } -static void rm_read_metadata(AVFormatContext *s, int wide) +static void rm_read_metadata(AVFormatContext *s, AVIOContext *pb, int wide) { char buf[1024]; int i; + for (i=0; ipb) : avio_r8(s->pb); - get_strl(s->pb, buf, sizeof(buf), len); + int len = wide ? avio_rb16(pb) : avio_r8(pb); + get_strl(pb, buf, sizeof(buf), len); av_dict_set(&s->metadata, ff_rm_metadata[i], buf, 0); } } @@ -143,7 +144,7 @@ static int rm_read_audio_stream_info(AVFormatContext *s, AVIOContext *pb, int header_size = avio_rb16(pb); int64_t startpos = avio_tell(pb); avio_skip(pb, 14); - rm_read_metadata(s, 0); + rm_read_metadata(s, pb, 0); if ((startpos + header_size) >= avio_tell(pb) + 2) { // fourcc (should always be "lpcJ") avio_r8(pb); @@ -266,6 +267,7 @@ static int rm_read_audio_stream_info(AVFormatContext *s, AVIOContext *pb, switch (ast->deint_id) { 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) return AVERROR_INVALIDDATA; break; @@ -288,7 +290,7 @@ static int rm_read_audio_stream_info(AVFormatContext *s, AVIOContext *pb, avio_r8(pb); avio_r8(pb); avio_r8(pb); - rm_read_metadata(s, 0); + rm_read_metadata(s, pb, 0); } } return 0; @@ -303,6 +305,9 @@ ff_rm_read_mdpr_codecdata (AVFormatContext *s, AVIOContext *pb, int64_t codec_pos; int ret; + if (codec_data_size < 0) + return AVERROR_INVALIDDATA; + avpriv_set_pts_info(st, 64, 1, 1000); codec_pos = avio_tell(pb); v = avio_rb32(pb); @@ -334,8 +339,13 @@ ff_rm_read_mdpr_codecdata (AVFormatContext *s, AVIOContext *pb, if ((ret = rm_read_extradata(pb, st->codec, codec_data_size - (avio_tell(pb) - codec_pos))) < 0) return ret; - av_reduce(&st->r_frame_rate.den, &st->r_frame_rate.num, - 0x10000, fps, (1 << 30) - 1); + if (fps > 0) { + av_reduce(&st->r_frame_rate.den, &st->r_frame_rate.num, + 0x10000, fps, (1 << 30) - 1); + } else if (s->error_recognition & AV_EF_EXPLODE) { + av_log(s, AV_LOG_ERROR, "Invalid framerate\n"); + return AVERROR_INVALIDDATA; + } st->avg_frame_rate = st->r_frame_rate; } @@ -370,8 +380,19 @@ static int rm_read_index(AVFormatContext *s) st = s->streams[n]; break; } - if (n == s->nb_streams) + if (n == s->nb_streams) { + av_log(s, AV_LOG_ERROR, + "Invalid stream index %d for index at pos %"PRId64"\n", + str_id, avio_tell(pb)); goto skip; + } else if ((avio_size(pb) - avio_tell(pb)) / 14 < n_pkts) { + av_log(s, AV_LOG_ERROR, + "Nr. of packets in packet index for stream index %d " + "exceeds filesize (%"PRId64" at %"PRId64" = %d)\n", + str_id, avio_size(pb), avio_tell(pb), + (avio_size(pb) - avio_tell(pb)) / 14); + goto skip; + } for (n = 0; n < n_pkts; n++) { avio_skip(pb, 2); @@ -383,9 +404,12 @@ static int rm_read_index(AVFormatContext *s) } skip: - if (next_off && avio_tell(pb) != next_off && - avio_seek(pb, next_off, SEEK_SET) < 0) + if (next_off && avio_tell(pb) < next_off && + avio_seek(pb, next_off, SEEK_SET) < 0) { + av_log(s, AV_LOG_ERROR, + "Non-linear index detected, not supported\n"); return -1; + } } while (next_off); return 0; @@ -460,7 +484,7 @@ static int rm_read_header(AVFormatContext *s, AVFormatParameters *ap) flags = avio_rb16(pb); /* flags */ break; case MKTAG('C', 'O', 'N', 'T'): - rm_read_metadata(s, 1); + rm_read_metadata(s, pb, 1); break; case MKTAG('M', 'D', 'P', 'R'): st = avformat_new_stream(s, NULL); @@ -959,6 +983,18 @@ static int64_t rm_read_dts(AVFormatContext *s, int stream_index, return dts; } +static int rm_read_seek(AVFormatContext *s, int stream_index, + int64_t pts, int flags) +{ + RMDemuxContext *rm = s->priv_data; + + if (ff_seek_frame_binary(s, stream_index, pts, flags) < 0) + return -1; + rm->audio_pkt_cnt = 0; + return 0; +} + + AVInputFormat ff_rm_demuxer = { .name = "rm", .long_name = NULL_IF_CONFIG_SMALL("RealMedia format"), @@ -968,6 +1004,7 @@ AVInputFormat ff_rm_demuxer = { .read_packet = rm_read_packet, .read_close = rm_read_close, .read_timestamp = rm_read_dts, + .read_seek = rm_read_seek, }; AVInputFormat ff_rdt_demuxer = { diff --git a/libavformat/rmenc.c b/libavformat/rmenc.c index b3d0cf6a66..59d35fccf2 100644 --- a/libavformat/rmenc.c +++ b/libavformat/rmenc.c @@ -44,6 +44,10 @@ typedef struct { /* in ms */ #define BUFFER_DURATION 0 +/* the header needs at most 7 + 4 + 12 B */ +#define MAX_HEADER_SIZE (7 + 4 + 12) +/* UINT16_MAX is the maximal chunk size */ +#define MAX_PACKET_SIZE (UINT16_MAX - MAX_HEADER_SIZE) static void put_str(AVIOContext *s, const char *tag) @@ -387,6 +391,10 @@ static int rm_write_video(AVFormatContext *s, const uint8_t *buf, int size, int /* Well, I spent some time finding the meaning of these bits. I am not sure I understood everything, but it works !! */ #if 1 + if (size > MAX_PACKET_SIZE) { + av_log_missing_feature(s, "Muxing packets larger than 64 kB", 0); + return AVERROR(ENOSYS); + } write_packet_header(s, stream, size + 7 + (size >= 0x4000)*4, key_frame); /* bit 7: '1' if final packet of a frame converted in several packets */ avio_w8(pb, 0x81); diff --git a/libavformat/rtmppkt.c b/libavformat/rtmppkt.c index 61e159b06a..298d0378f1 100644 --- a/libavformat/rtmppkt.c +++ b/libavformat/rtmppkt.c @@ -75,26 +75,26 @@ int ff_rtmp_packet_read(URLContext *h, RTMPPacket *p, int chunk_size, RTMPPacket *prev_pkt) { uint8_t hdr, t, buf[16]; - int channel_id, timestamp, data_size, offset = 0; + int channel_id, timestamp, size, offset = 0; uint32_t extra = 0; enum RTMPPacketType type; - int size = 0; + int written = 0; if (ffurl_read(h, &hdr, 1) != 1) return AVERROR(EIO); - size++; + written++; channel_id = hdr & 0x3F; if (channel_id < 2) { //special case for channel number >= 64 buf[1] = 0; if (ffurl_read_complete(h, buf, channel_id + 1) != channel_id + 1) return AVERROR(EIO); - size += channel_id + 1; + written += channel_id + 1; channel_id = AV_RL16(buf) + 64; } - data_size = prev_pkt[channel_id].data_size; - type = prev_pkt[channel_id].type; - extra = prev_pkt[channel_id].extra; + size = prev_pkt[channel_id].size; + type = prev_pkt[channel_id].type; + extra = prev_pkt[channel_id].extra; hdr >>= 6; if (hdr == RTMP_PS_ONEBYTE) { @@ -102,21 +102,21 @@ int ff_rtmp_packet_read(URLContext *h, RTMPPacket *p, } else { if (ffurl_read_complete(h, buf, 3) != 3) return AVERROR(EIO); - size += 3; + written += 3; timestamp = AV_RB24(buf); if (hdr != RTMP_PS_FOURBYTES) { if (ffurl_read_complete(h, buf, 3) != 3) return AVERROR(EIO); - size += 3; - data_size = AV_RB24(buf); + written += 3; + size = AV_RB24(buf); if (ffurl_read_complete(h, buf, 1) != 1) return AVERROR(EIO); - size++; + written++; type = buf[0]; if (hdr == RTMP_PS_TWELVEBYTES) { if (ffurl_read_complete(h, buf, 4) != 4) return AVERROR(EIO); - size += 4; + written += 4; extra = AV_RL32(buf); } } @@ -129,33 +129,33 @@ int ff_rtmp_packet_read(URLContext *h, RTMPPacket *p, if (hdr != RTMP_PS_TWELVEBYTES) timestamp += prev_pkt[channel_id].timestamp; - if (ff_rtmp_packet_create(p, channel_id, type, timestamp, data_size)) + if (ff_rtmp_packet_create(p, channel_id, type, timestamp, size)) return -1; p->extra = extra; // save history prev_pkt[channel_id].channel_id = channel_id; prev_pkt[channel_id].type = type; - prev_pkt[channel_id].data_size = data_size; + prev_pkt[channel_id].size = size; prev_pkt[channel_id].ts_delta = timestamp - prev_pkt[channel_id].timestamp; prev_pkt[channel_id].timestamp = timestamp; prev_pkt[channel_id].extra = extra; - while (data_size > 0) { - int toread = FFMIN(data_size, chunk_size); + while (size > 0) { + int toread = FFMIN(size, chunk_size); if (ffurl_read_complete(h, p->data + offset, toread) != toread) { ff_rtmp_packet_destroy(p); return AVERROR(EIO); } - data_size -= chunk_size; - offset += chunk_size; - size += chunk_size; - if (data_size > 0) { + size -= chunk_size; + offset += chunk_size; + written += chunk_size; + if (size > 0) { ffurl_read_complete(h, &t, 1); //marker - size++; + written++; if (t != (0xC0 + channel_id)) return -1; } } - return size; + return written; } int ff_rtmp_packet_write(URLContext *h, RTMPPacket *pkt, @@ -164,7 +164,7 @@ int ff_rtmp_packet_write(URLContext *h, RTMPPacket *pkt, uint8_t pkt_hdr[16], *p = pkt_hdr; int mode = RTMP_PS_TWELVEBYTES; int off = 0; - int size = 0; + int written = 0; pkt->ts_delta = pkt->timestamp - prev_pkt[pkt->channel_id].timestamp; @@ -172,7 +172,7 @@ int ff_rtmp_packet_write(URLContext *h, RTMPPacket *pkt, if (prev_pkt[pkt->channel_id].channel_id && pkt->extra == prev_pkt[pkt->channel_id].extra) { if (pkt->type == prev_pkt[pkt->channel_id].type && - pkt->data_size == prev_pkt[pkt->channel_id].data_size) { + pkt->size == prev_pkt[pkt->channel_id].size) { mode = RTMP_PS_FOURBYTES; if (pkt->ts_delta == prev_pkt[pkt->channel_id].ts_delta) mode = RTMP_PS_ONEBYTE; @@ -196,7 +196,7 @@ int ff_rtmp_packet_write(URLContext *h, RTMPPacket *pkt, timestamp = pkt->ts_delta; bytestream_put_be24(&p, timestamp >= 0xFFFFFF ? 0xFFFFFF : timestamp); if (mode != RTMP_PS_FOURBYTES) { - bytestream_put_be24(&p, pkt->data_size); + bytestream_put_be24(&p, pkt->size); bytestream_put_byte(&p, pkt->type); if (mode == RTMP_PS_TWELVEBYTES) bytestream_put_le32(&p, pkt->extra); @@ -207,7 +207,7 @@ int ff_rtmp_packet_write(URLContext *h, RTMPPacket *pkt, // save history prev_pkt[pkt->channel_id].channel_id = pkt->channel_id; prev_pkt[pkt->channel_id].type = pkt->type; - prev_pkt[pkt->channel_id].data_size = pkt->data_size; + prev_pkt[pkt->channel_id].size = pkt->size; prev_pkt[pkt->channel_id].timestamp = pkt->timestamp; if (mode != RTMP_PS_TWELVEBYTES) { prev_pkt[pkt->channel_id].ts_delta = pkt->ts_delta; @@ -217,18 +217,18 @@ int ff_rtmp_packet_write(URLContext *h, RTMPPacket *pkt, prev_pkt[pkt->channel_id].extra = pkt->extra; ffurl_write(h, pkt_hdr, p-pkt_hdr); - size = p - pkt_hdr + pkt->data_size; - while (off < pkt->data_size) { - int towrite = FFMIN(chunk_size, pkt->data_size - off); + written = p - pkt_hdr + pkt->size; + while (off < pkt->size) { + int towrite = FFMIN(chunk_size, pkt->size - off); ffurl_write(h, pkt->data + off, towrite); off += towrite; - if (off < pkt->data_size) { + if (off < pkt->size) { uint8_t marker = 0xC0 | pkt->channel_id; ffurl_write(h, &marker, 1); - size++; + written++; } } - return size; + return written; } int ff_rtmp_packet_create(RTMPPacket *pkt, int channel_id, RTMPPacketType type, @@ -239,7 +239,7 @@ int ff_rtmp_packet_create(RTMPPacket *pkt, int channel_id, RTMPPacketType type, if (!pkt->data) return AVERROR(ENOMEM); } - pkt->data_size = size; + pkt->size = size; pkt->channel_id = channel_id; pkt->type = type; pkt->timestamp = timestamp; @@ -254,7 +254,7 @@ void ff_rtmp_packet_destroy(RTMPPacket *pkt) if (!pkt) return; av_freep(&pkt->data); - pkt->data_size = 0; + pkt->size = 0; } int ff_amf_tag_size(const uint8_t *data, const uint8_t *data_end) @@ -279,11 +279,11 @@ int ff_amf_tag_size(const uint8_t *data, const uint8_t *data_end) data++; break; } - if (data + size >= data_end || data + size < data) + if (size < 0 || size >= data_end - data) return -1; data += size; t = ff_amf_tag_size(data, data_end); - if (t < 0 || data + t >= data_end) + if (t < 0 || t >= data_end - data) return -1; data += t; } @@ -312,7 +312,7 @@ int ff_amf_get_field_value(const uint8_t *data, const uint8_t *data_end, int size = bytestream_get_be16(&data); if (!size) break; - if (data + size >= data_end || data + size < data) + if (size < 0 || size >= data_end - data) return -1; data += size; if (size == namelen && !memcmp(data-size, name, namelen)) { @@ -333,7 +333,7 @@ int ff_amf_get_field_value(const uint8_t *data, const uint8_t *data_end, return 0; } len = ff_amf_tag_size(data, data_end); - if (len < 0 || data + len >= data_end || data + len < data) + if (len < 0 || len >= data_end - data) return -1; data += len; } @@ -363,7 +363,7 @@ static const char* rtmp_packet_type(int type) static void ff_amf_tag_contents(void *ctx, const uint8_t *data, const uint8_t *data_end) { - int size; + unsigned int size; char buf[1024]; if (data >= data_end) @@ -382,7 +382,7 @@ static void ff_amf_tag_contents(void *ctx, const uint8_t *data, const uint8_t *d } else { size = bytestream_get_be32(&data); } - size = FFMIN(size, 1023); + size = FFMIN(size, sizeof(buf) - 1); memcpy(buf, data, size); buf[size] = 0; av_log(ctx, AV_LOG_DEBUG, " string '%s'\n", buf); @@ -395,22 +395,21 @@ static void ff_amf_tag_contents(void *ctx, const uint8_t *data, const uint8_t *d case AMF_DATA_TYPE_OBJECT: av_log(ctx, AV_LOG_DEBUG, " {\n"); for (;;) { - int size = bytestream_get_be16(&data); int t; - memcpy(buf, data, size); - buf[size] = 0; + size = bytestream_get_be16(&data); + av_strlcpy(buf, data, FFMIN(sizeof(buf), size + 1)); if (!size) { av_log(ctx, AV_LOG_DEBUG, " }\n"); data++; break; } - if (data + size >= data_end || data + size < data) + if (size >= data_end - data) return; data += size; av_log(ctx, AV_LOG_DEBUG, " %s: ", buf); ff_amf_tag_contents(ctx, data, data_end); t = ff_amf_tag_size(data, data_end); - if (t < 0 || data + t >= data_end) + if (t < 0 || t >= data_end - data) return; data += t; } @@ -426,9 +425,9 @@ static void ff_amf_tag_contents(void *ctx, const uint8_t *data, const uint8_t *d void ff_rtmp_packet_dump(void *ctx, RTMPPacket *p) { av_log(ctx, AV_LOG_DEBUG, "RTMP packet type '%s'(%d) for channel %d, timestamp %d, extra field %d size %d\n", - rtmp_packet_type(p->type), p->type, p->channel_id, p->timestamp, p->extra, p->data_size); + rtmp_packet_type(p->type), p->type, p->channel_id, p->timestamp, p->extra, p->size); if (p->type == RTMP_PT_INVOKE || p->type == RTMP_PT_NOTIFY) { - uint8_t *src = p->data, *src_end = p->data + p->data_size; + uint8_t *src = p->data, *src_end = p->data + p->size; while (src < src_end) { int sz; ff_amf_tag_contents(ctx, src, src_end); @@ -443,8 +442,41 @@ void ff_rtmp_packet_dump(void *ctx, RTMPPacket *p) av_log(ctx, AV_LOG_DEBUG, "Client BW = %d\n", AV_RB32(p->data)); } else if (p->type != RTMP_PT_AUDIO && p->type != RTMP_PT_VIDEO && p->type != RTMP_PT_METADATA) { int i; - for (i = 0; i < p->data_size; i++) + for (i = 0; i < p->size; i++) av_log(ctx, AV_LOG_DEBUG, " %02X", p->data[i]); av_log(ctx, AV_LOG_DEBUG, "\n"); } } + +int ff_amf_match_string(const uint8_t *data, int size, const char *str) +{ + int len = strlen(str); + int amf_len, type; + + if (size < 1) + return 0; + + type = *data++; + + if (type != AMF_DATA_TYPE_LONG_STRING && + type != AMF_DATA_TYPE_STRING) + return 0; + + if (type == AMF_DATA_TYPE_LONG_STRING) { + if ((size -= 4 + 1) < 0) + return 0; + amf_len = bytestream_get_be32(&data); + } else { + if ((size -= 2 + 1) < 0) + return 0; + amf_len = bytestream_get_be16(&data); + } + + if (amf_len > size) + return 0; + + if (amf_len != len) + return 0; + + return !memcmp(data, str, len); +} diff --git a/libavformat/rtmppkt.h b/libavformat/rtmppkt.h index 8acbfc116b..ed1a2c61fa 100644 --- a/libavformat/rtmppkt.h +++ b/libavformat/rtmppkt.h @@ -80,7 +80,7 @@ typedef struct RTMPPacket { uint32_t ts_delta; ///< timestamp increment to the previous one in milliseconds (latter only for media packets) uint32_t extra; ///< probably an additional channel ID used during streaming data uint8_t *data; ///< packet payload - int data_size; ///< packet payload size + int size; ///< packet payload size } RTMPPacket; /** @@ -218,6 +218,13 @@ void ff_amf_write_field_name(uint8_t **dst, const char *str); */ void ff_amf_write_object_end(uint8_t **dst); +/** + * Match AMF string with a NULL-terminated string. + * + * @return 0 if the strings do not match. + */ +int ff_amf_match_string(const uint8_t *data, int size, const char *str); + /** @} */ // AMF funcs #endif /* AVFORMAT_RTMPPKT_H */ diff --git a/libavformat/rtmpproto.c b/libavformat/rtmpproto.c index a2c7b5da88..4a9dabc004 100644 --- a/libavformat/rtmpproto.c +++ b/libavformat/rtmpproto.c @@ -147,7 +147,7 @@ static void gen_connect(URLContext *s, RTMPContext *rt, const char *proto, } ff_amf_write_object_end(&p); - pkt.data_size = p - pkt.data; + pkt.size = p - pkt.data; ff_rtmp_packet_write(rt->stream, &pkt, rt->chunk_size, rt->prev_pkt[1]); ff_rtmp_packet_destroy(&pkt); @@ -549,7 +549,7 @@ static int rtmp_handshake(URLContext *s, RTMPContext *rt) static int rtmp_parse_result(URLContext *s, RTMPContext *rt, RTMPPacket *pkt) { int i, t; - const uint8_t *data_end = pkt->data + pkt->data_size; + const uint8_t *data_end = pkt->data + pkt->size; #ifdef DEBUG ff_rtmp_packet_dump(s, pkt); @@ -557,9 +557,9 @@ static int rtmp_parse_result(URLContext *s, RTMPContext *rt, RTMPPacket *pkt) switch (pkt->type) { case RTMP_PT_CHUNK_SIZE: - if (pkt->data_size != 4) { + if (pkt->size != 4) { av_log(s, AV_LOG_ERROR, - "Chunk size change packet is not 4 bytes long (%d)\n", pkt->data_size); + "Chunk size change packet is not 4 bytes long (%d)\n", pkt->size); return -1; } if (!rt->is_input) @@ -577,10 +577,10 @@ static int rtmp_parse_result(URLContext *s, RTMPContext *rt, RTMPPacket *pkt) gen_pong(s, rt, pkt); break; case RTMP_PT_CLIENT_BW: - if (pkt->data_size < 4) { + if (pkt->size < 4) { av_log(s, AV_LOG_ERROR, "Client bandwidth report packet is less than 4 bytes long (%d)\n", - pkt->data_size); + pkt->size); return -1; } av_log(s, AV_LOG_DEBUG, "Client bandwidth = %d\n", AV_RB32(pkt->data)); @@ -588,14 +588,14 @@ static int rtmp_parse_result(URLContext *s, RTMPContext *rt, RTMPPacket *pkt) break; case RTMP_PT_INVOKE: //TODO: check for the messages sent for wrong state? - if (!memcmp(pkt->data, "\002\000\006_error", 9)) { + if (ff_amf_match_string(pkt->data, pkt->size, "_error")) { uint8_t tmpstr[256]; if (!ff_amf_get_field_value(pkt->data + 9, data_end, "description", tmpstr, sizeof(tmpstr))) av_log(s, AV_LOG_ERROR, "Server error: %s\n",tmpstr); return -1; - } else if (!memcmp(pkt->data, "\002\000\007_result", 10)) { + } else if (ff_amf_match_string(pkt->data, pkt->size, "_result")) { switch (rt->state) { case STATE_HANDSHAKED: if (!rt->is_input) { @@ -636,7 +636,7 @@ static int rtmp_parse_result(URLContext *s, RTMPContext *rt, RTMPPacket *pkt) rt->state = STATE_READY; break; } - } else if (!memcmp(pkt->data, "\002\000\010onStatus", 11)) { + } else if (ff_amf_match_string(pkt->data, pkt->size, "onStatus")) { const uint8_t* ptr = pkt->data + 11; uint8_t tmpstr[256]; @@ -683,7 +683,7 @@ static int get_packet(URLContext *s, int for_header) int ret; uint8_t *p; const uint8_t *next; - uint32_t data_size; + uint32_t size; uint32_t ts, cts, pts=0; if (rt->state == STATE_STOPPED) @@ -719,38 +719,39 @@ static int get_packet(URLContext *s, int for_header) ff_rtmp_packet_destroy(&rpkt); return 0; } - if (!rpkt.data_size || !rt->is_input) { + if (!rpkt.size || !rt->is_input) { ff_rtmp_packet_destroy(&rpkt); continue; } if (rpkt.type == RTMP_PT_VIDEO || rpkt.type == RTMP_PT_AUDIO || - (rpkt.type == RTMP_PT_NOTIFY && !memcmp("\002\000\012onMetaData", rpkt.data, 13))) { + (rpkt.type == RTMP_PT_NOTIFY && + ff_amf_match_string(rpkt.data, rpkt.size, "onMetaData"))) { ts = rpkt.timestamp; // generate packet header and put data into buffer for FLV demuxer rt->flv_off = 0; - rt->flv_size = rpkt.data_size + 15; + rt->flv_size = rpkt.size + 15; rt->flv_data = p = av_realloc(rt->flv_data, rt->flv_size); bytestream_put_byte(&p, rpkt.type); - bytestream_put_be24(&p, rpkt.data_size); + bytestream_put_be24(&p, rpkt.size); bytestream_put_be24(&p, ts); bytestream_put_byte(&p, ts >> 24); bytestream_put_be24(&p, 0); - bytestream_put_buffer(&p, rpkt.data, rpkt.data_size); + bytestream_put_buffer(&p, rpkt.data, rpkt.size); bytestream_put_be32(&p, 0); ff_rtmp_packet_destroy(&rpkt); return 0; } else if (rpkt.type == RTMP_PT_METADATA) { // we got raw FLV data, make it available for FLV demuxer rt->flv_off = 0; - rt->flv_size = rpkt.data_size; + rt->flv_size = rpkt.size; rt->flv_data = av_realloc(rt->flv_data, rt->flv_size); /* rewrite timestamps */ next = rpkt.data; ts = rpkt.timestamp; - while (next - rpkt.data < rpkt.data_size - 11) { + while (next - rpkt.data < rpkt.size - 11) { next++; - data_size = bytestream_get_be24(&next); + size = bytestream_get_be24(&next); p=next; cts = bytestream_get_be24(&next); cts |= bytestream_get_byte(&next) << 24; @@ -760,9 +761,9 @@ static int get_packet(URLContext *s, int for_header) pts = cts; bytestream_put_be24(&p, ts); bytestream_put_byte(&p, ts >> 24); - next += data_size + 3 + 4; + next += size + 3 + 4; } - memcpy(rt->flv_data, rpkt.data, rpkt.data_size); + memcpy(rt->flv_data, rpkt.data, rpkt.size); ff_rtmp_packet_destroy(&rpkt); return 0; } @@ -776,7 +777,7 @@ static int rtmp_close(URLContext *h) if (!rt->is_input) { rt->flv_data = NULL; - if (rt->out_pkt.data_size) + if (rt->out_pkt.size) ff_rtmp_packet_destroy(&rt->out_pkt); if (rt->state > STATE_FCPUBLISH) gen_fcunpublish_stream(h, rt); diff --git a/libavformat/rtpenc_h264.c b/libavformat/rtpenc_h264.c index 86930bbac1..5447edcc30 100644 --- a/libavformat/rtpenc_h264.c +++ b/libavformat/rtpenc_h264.c @@ -31,14 +31,14 @@ static const uint8_t *avc_mp4_find_startcode(const uint8_t *start, const uint8_t *end, int nal_length_size) { - int res = 0; + unsigned int res = 0; if (end - start < nal_length_size) return NULL; while (nal_length_size--) res = (res << 8) | *start++; - if (start + res > end || res < 0 || start + res < start) + if (res > end - start) return NULL; return start + res; diff --git a/libavformat/rtsp.c b/libavformat/rtsp.c index c2a0d26e5e..9442ddcf88 100644 --- a/libavformat/rtsp.c +++ b/libavformat/rtsp.c @@ -1720,6 +1720,7 @@ int ff_rtsp_fetch_packet(AVFormatContext *s, AVPacket *pkt) rt->cur_transport_priv = NULL; } +redo: if (rt->transport == RTSP_TRANSPORT_RTP) { int i; int64_t first_queue_time = 0; @@ -1735,12 +1736,15 @@ int ff_rtsp_fetch_packet(AVFormatContext *s, AVPacket *pkt) first_queue_st = rt->rtsp_streams[i]; } } - if (first_queue_time) + if (first_queue_time) { wait_end = first_queue_time + s->max_delay; + } else { + wait_end = 0; + first_queue_st = NULL; + } } /* read next RTP packet */ - redo: if (!rt->recvbuf) { rt->recvbuf = av_malloc(RECVBUF_SIZE); if (!rt->recvbuf) diff --git a/libavformat/segafilm.c b/libavformat/segafilm.c index c2a163d9fc..c12cd770d3 100644 --- a/libavformat/segafilm.c +++ b/libavformat/segafilm.c @@ -76,6 +76,16 @@ static int film_probe(AVProbeData *p) return AVPROBE_SCORE_MAX; } +static int film_read_close(AVFormatContext *s) +{ + FilmDemuxContext *film = s->priv_data; + + av_freep(&film->sample_table); + av_freep(&film->stereo_buffer); + + return 0; +} + static int film_read_header(AVFormatContext *s, AVFormatParameters *ap) { @@ -83,7 +93,7 @@ static int film_read_header(AVFormatContext *s, AVIOContext *pb = s->pb; AVStream *st; unsigned char scratch[256]; - int i; + int i, ret; unsigned int data_offset; unsigned int audio_frame_counter; @@ -113,6 +123,11 @@ static int film_read_header(AVFormatContext *s, return AVERROR(EIO); film->audio_samplerate = AV_RB16(&scratch[24]); film->audio_channels = scratch[21]; + if (!film->audio_channels || film->audio_channels > 2) { + av_log(s, AV_LOG_ERROR, + "Invalid number of channels: %d\n", film->audio_channels); + return AVERROR_INVALIDDATA; + } film->audio_bits = scratch[22]; if (scratch[23] == 2) film->audio_type = CODEC_ID_ADPCM_ADX; @@ -205,12 +220,16 @@ static int film_read_header(AVFormatContext *s, for (i = 0; i < film->sample_count; i++) { /* load the next sample record and transfer it to an internal struct */ if (avio_read(pb, scratch, 16) != 16) { - av_free(film->sample_table); - return AVERROR(EIO); + ret = AVERROR(EIO); + goto fail; } film->sample_table[i].sample_offset = data_offset + AV_RB32(&scratch[0]); film->sample_table[i].sample_size = AV_RB32(&scratch[4]); + if (film->sample_table[i].sample_size > INT_MAX / 4) { + ret = AVERROR_INVALIDDATA; + goto fail; + } if (AV_RB32(&scratch[8]) == 0xFFFFFFFF) { film->sample_table[i].stream = film->audio_stream_index; film->sample_table[i].pts = audio_frame_counter; @@ -233,6 +252,9 @@ static int film_read_header(AVFormatContext *s, film->current_sample = 0; return 0; +fail: + film_read_close(s); + return ret; } static int film_read_packet(AVFormatContext *s, @@ -313,16 +335,6 @@ static int film_read_packet(AVFormatContext *s, return ret; } -static int film_read_close(AVFormatContext *s) -{ - FilmDemuxContext *film = s->priv_data; - - av_free(film->sample_table); - av_free(film->stereo_buffer); - - return 0; -} - AVInputFormat ff_segafilm_demuxer = { .name = "film_cpk", .long_name = NULL_IF_CONFIG_SMALL("Sega FILM/CPK format"), diff --git a/libavformat/sierravmd.c b/libavformat/sierravmd.c index 6fb7d8a700..560ffe6792 100644 --- a/libavformat/sierravmd.c +++ b/libavformat/sierravmd.c @@ -89,7 +89,7 @@ static int vmd_read_header(AVFormatContext *s, unsigned char *raw_frame_table; int raw_frame_table_size; int64_t current_offset; - int i, j; + int i, j, ret; unsigned int total_frames; int64_t current_audio_pts = 0; unsigned char chunk[BYTES_PER_FRAME_RECORD]; @@ -170,15 +170,13 @@ static int vmd_read_header(AVFormatContext *s, raw_frame_table = av_malloc(raw_frame_table_size); vmd->frame_table = av_malloc((vmd->frame_count * vmd->frames_per_block + sound_buffers) * sizeof(vmd_frame)); if (!raw_frame_table || !vmd->frame_table) { - av_free(raw_frame_table); - av_free(vmd->frame_table); - return AVERROR(ENOMEM); + ret = AVERROR(ENOMEM); + goto error; } if (avio_read(pb, raw_frame_table, raw_frame_table_size) != raw_frame_table_size) { - av_free(raw_frame_table); - av_free(vmd->frame_table); - return AVERROR(EIO); + ret = AVERROR(EIO); + goto error; } total_frames = 0; @@ -194,6 +192,11 @@ static int vmd_read_header(AVFormatContext *s, avio_read(pb, chunk, BYTES_PER_FRAME_RECORD); type = chunk[0]; size = AV_RL32(&chunk[2]); + if (size > INT_MAX / 2) { + av_log(s, AV_LOG_ERROR, "Invalid frame size\n"); + ret = AVERROR_INVALIDDATA; + goto error; + } if(!size && type != 1) continue; switch(type) { @@ -230,6 +233,11 @@ static int vmd_read_header(AVFormatContext *s, vmd->frame_count = total_frames; return 0; + +error: + av_free(raw_frame_table); + av_free(vmd->frame_table); + return ret; } static int vmd_read_packet(AVFormatContext *s, diff --git a/libavformat/smacker.c b/libavformat/smacker.c index 26319d4d59..20530814d3 100644 --- a/libavformat/smacker.c +++ b/libavformat/smacker.c @@ -203,7 +203,8 @@ static int smacker_read_header(AVFormatContext *s, AVFormatParameters *ap) /* load trees to extradata, they will be unpacked by decoder */ - st->codec->extradata = av_malloc(smk->treesize + 16); + st->codec->extradata = av_mallocz(smk->treesize + 16 + + FF_INPUT_BUFFER_PADDING_SIZE); st->codec->extradata_size = smk->treesize + 16; if(!st->codec->extradata){ av_log(s, AV_LOG_ERROR, "Cannot allocate %i bytes of extradata\n", smk->treesize + 16); @@ -267,8 +268,15 @@ static int smacker_read_packet(AVFormatContext *s, AVPacket *pkt) sz += (t & 0x7F) + 1; pal += ((t & 0x7F) + 1) * 3; } else if(t & 0x40){ /* copy with offset */ - off = avio_r8(s->pb) * 3; + off = avio_r8(s->pb); j = (t & 0x3F) + 1; + if (off + j - 1 > 0xff) { + av_log(s, AV_LOG_ERROR, + "Invalid palette update, offset=%d length=%d extends beyond palette size\n", + off, j); + return AVERROR_INVALIDDATA; + } + off *= 3; while(j-- && sz < 256) { *pal++ = oldpal[off + 0]; *pal++ = oldpal[off + 1]; @@ -291,12 +299,14 @@ static int smacker_read_packet(AVFormatContext *s, AVPacket *pkt) /* if audio chunks are present, put them to stack and retrieve later */ for(i = 0; i < 7; i++) { if(flags & 1) { - unsigned int size; + uint32_t size; uint8_t *tmpbuf; size = avio_rl32(s->pb) - 4; - if(size + 4L > frame_size) + if (!size || size + 4LL > frame_size) { + av_log(s, AV_LOG_ERROR, "Invalid audio part size\n"); return AVERROR_INVALIDDATA; + } frame_size -= size; frame_size -= 4; smk->curstream++; @@ -312,7 +322,7 @@ static int smacker_read_packet(AVFormatContext *s, AVPacket *pkt) } flags >>= 1; } - if (frame_size < 0) + if (frame_size < 0 || frame_size >= INT_MAX/2) return AVERROR_INVALIDDATA; if (av_new_packet(pkt, frame_size + 769)) return AVERROR(ENOMEM); @@ -328,6 +338,8 @@ static int smacker_read_packet(AVFormatContext *s, AVPacket *pkt) smk->cur_frame++; smk->nextpos = avio_tell(s->pb); } else { + if (smk->stream_id[smk->curstream] < 0) + return AVERROR_INVALIDDATA; if (av_new_packet(pkt, smk->buf_sizes[smk->curstream])) return AVERROR(ENOMEM); memcpy(pkt->data, smk->bufs[smk->curstream], smk->buf_sizes[smk->curstream]); diff --git a/libavformat/swfdec.c b/libavformat/swfdec.c index c0b2e1759b..af93673a5f 100644 --- a/libavformat/swfdec.c +++ b/libavformat/swfdec.c @@ -84,13 +84,17 @@ static int swf_read_packet(AVFormatContext *s, AVPacket *pkt) SWFContext *swf = s->priv_data; AVIOContext *pb = s->pb; AVStream *vst = NULL, *ast = NULL, *st = 0; - int tag, len, i, frame, v; + int tag, len, i, frame, v, res; for(;;) { uint64_t pos = avio_tell(pb); tag = get_swf_tag(pb, &len); if (tag < 0) return tag; + if (len < 0) { + av_log(s, AV_LOG_ERROR, "invalid tag length: %d\n", len); + return AVERROR_INVALIDDATA; + } if (tag == TAG_VIDEOSTREAM) { int ch_id = avio_rl16(pb); len -= 2; @@ -150,7 +154,11 @@ static int swf_read_packet(AVFormatContext *s, AVPacket *pkt) st = s->streams[i]; if (st->codec->codec_type == AVMEDIA_TYPE_VIDEO && st->id == ch_id) { frame = avio_rl16(pb); - av_get_packet(pb, pkt, len-2); + len -= 2; + if (len <= 0) + goto skip; + if ((res = av_get_packet(pb, pkt, len)) < 0) + return res; pkt->pos = pos; pkt->pts = frame; pkt->stream_index = st->index; @@ -163,9 +171,16 @@ static int swf_read_packet(AVFormatContext *s, AVPacket *pkt) if (st->codec->codec_type == AVMEDIA_TYPE_AUDIO && st->id == -1) { if (st->codec->codec_id == CODEC_ID_MP3) { avio_skip(pb, 4); - av_get_packet(pb, pkt, len-4); + len -= 4; + if (len <= 0) + goto skip; + if ((res = av_get_packet(pb, pkt, len)) < 0) + return res; } else { // ADPCM, PCM - av_get_packet(pb, pkt, len); + if (len <= 0) + goto skip; + if ((res = av_get_packet(pb, pkt, len)) < 0) + return res; } pkt->pos = pos; pkt->stream_index = st->index; @@ -190,7 +205,11 @@ static int swf_read_packet(AVFormatContext *s, AVPacket *pkt) st = vst; } avio_rl16(pb); /* BITMAP_ID */ - av_new_packet(pkt, len-2); + len -= 2; + if (len < 4) + goto skip; + if ((res = av_new_packet(pkt, len)) < 0) + return res; avio_read(pb, pkt->data, 4); if (AV_RB32(pkt->data) == 0xffd8ffd9 || AV_RB32(pkt->data) == 0xffd9ffd8) { @@ -206,6 +225,7 @@ static int swf_read_packet(AVFormatContext *s, AVPacket *pkt) return pkt->size; } skip: + len = FFMAX(0, len); avio_skip(pb, len); } } diff --git a/libavformat/swfenc.c b/libavformat/swfenc.c index af812d09eb..0ad7b3342c 100644 --- a/libavformat/swfenc.c +++ b/libavformat/swfenc.c @@ -498,8 +498,10 @@ static int swf_write_trailer(AVFormatContext *s) avio_wl32(pb, file_size); avio_seek(pb, swf->duration_pos, SEEK_SET); avio_wl16(pb, swf->video_frame_number); + if (swf->vframes_pos) { avio_seek(pb, swf->vframes_pos, SEEK_SET); avio_wl16(pb, swf->video_frame_number); + } avio_seek(pb, file_size, SEEK_SET); } return 0; diff --git a/libavformat/thp.c b/libavformat/thp.c index 75f7941ff8..bed3f599c2 100644 --- a/libavformat/thp.c +++ b/libavformat/thp.c @@ -179,6 +179,8 @@ static int thp_read_packet(AVFormatContext *s, pkt->stream_index = thp->video_stream_index; } else { ret = av_get_packet(pb, pkt, thp->audiosize); + if (ret < 0) + return ret; if (ret != thp->audiosize) { av_free_packet(pkt); return AVERROR(EIO); diff --git a/libavformat/utils.c b/libavformat/utils.c index 005704c7f0..836f0ec436 100644 --- a/libavformat/utils.c +++ b/libavformat/utils.c @@ -558,7 +558,6 @@ int av_probe_input_buffer(AVIOContext *pb, AVInputFormat **fmt, for(probe_size= PROBE_BUF_MIN; probe_size<=max_probe_size && !*fmt; probe_size = FFMIN(probe_size<<1, FFMAX(max_probe_size, probe_size+1))) { int score = probe_size < max_probe_size ? AVPROBE_SCORE_MAX/4 : 0; - int buf_offset = (probe_size == PROBE_BUF_MIN) ? 0 : probe_size>>1; void *buftmp; if (probe_size < offset) { @@ -572,7 +571,7 @@ int av_probe_input_buffer(AVIOContext *pb, AVInputFormat **fmt, return AVERROR(ENOMEM); } buf=buftmp; - if ((ret = avio_read(pb, buf + buf_offset, probe_size - buf_offset)) < 0) { + if ((ret = avio_read(pb, buf + pd.buf_size, probe_size - pd.buf_size)) < 0) { /* fail if error was not end of file, otherwise, lower score */ if (ret != AVERROR_EOF) { av_free(buf); @@ -687,7 +686,7 @@ int avformat_open_input(AVFormatContext **ps, const char *filename, AVInputForma } s->duration = s->start_time = AV_NOPTS_VALUE; - av_strlcpy(s->filename, filename, sizeof(s->filename)); + av_strlcpy(s->filename, filename ? filename : "", sizeof(s->filename)); /* allocate private data */ if (s->iformat->priv_data_size > 0) { @@ -902,7 +901,10 @@ static void compute_frame_duration(int *pnum, int *pden, AVStream *st, *pnum = st->codec->time_base.num; *pden = st->codec->time_base.den; if (pc && pc->repeat_pict) { - *pnum = (*pnum) * (1 + pc->repeat_pict); + if (*pnum > INT_MAX / (1 + pc->repeat_pict)) + *pden /= 1 + pc->repeat_pict; + else + *pnum *= 1 + pc->repeat_pict; } //If this codec can be interlaced or progressive then we need a parser to compute duration of a packet //Thus if we have no parser in such case leave duration undefined. @@ -1080,12 +1082,14 @@ static void compute_pkt_fields(AVFormatContext *s, AVStream *st, if (pkt->dts != AV_NOPTS_VALUE) { // got DTS from the stream, update reference timestamp st->reference_dts = pkt->dts - pc->dts_ref_dts_delta * num / den; - pkt->pts = pkt->dts + pc->pts_dts_delta * num / den; } else if (st->reference_dts != AV_NOPTS_VALUE) { // compute DTS based on reference timestamp pkt->dts = st->reference_dts + pc->dts_ref_dts_delta * num / den; - pkt->pts = pkt->dts + pc->pts_dts_delta * num / den; } + + if (st->reference_dts != AV_NOPTS_VALUE && pkt->pts == AV_NOPTS_VALUE) + pkt->pts = pkt->dts + pc->pts_dts_delta * num / den; + if (pc->dts_sync_point > 0) st->reference_dts = pkt->dts; // new reference } @@ -1945,7 +1949,7 @@ int avformat_seek_file(AVFormatContext *s, int stream_index, int64_t min_ts, int //Note the old has somewat different sematics AV_NOWARN_DEPRECATED( if(s->iformat->read_seek || 1) - return av_seek_frame(s, stream_index, ts, flags | (ts - min_ts > (uint64_t)(max_ts - ts) ? AVSEEK_FLAG_BACKWARD : 0)); + return av_seek_frame(s, stream_index, ts, flags | ((uint64_t)ts - min_ts > (uint64_t)max_ts - ts ? AVSEEK_FLAG_BACKWARD : 0)); ) // try some generic seek like seek_frame_generic() but with new ts semantics @@ -2054,8 +2058,13 @@ static void estimate_timings_from_bit_rate(AVFormatContext *ic) bit_rate = 0; for(i=0;inb_streams;i++) { st = ic->streams[i]; - if (st->codec->bit_rate > 0) - bit_rate += st->codec->bit_rate; + if (st->codec->bit_rate > 0) { + if (INT_MAX - st->codec->bit_rate < bit_rate) { + bit_rate = 0; + break; + } + bit_rate += st->codec->bit_rate; + } } ic->bit_rate = bit_rate; } @@ -2236,6 +2245,7 @@ static int has_decode_delay_been_guessed(AVStream *st) st->info->nb_decoded_frames >= 6; } +/* returns 1 or 0 if or if not decoded data was returned, or a negative error */ static int try_decode_frame(AVStream *st, AVPacket *avpkt, AVDictionary **options) { AVCodec *codec; @@ -2243,10 +2253,12 @@ static int try_decode_frame(AVStream *st, AVPacket *avpkt, AVDictionary **option AVFrame picture; AVPacket pkt = *avpkt; - if(!st->codec->codec){ + if (!avcodec_is_open(st->codec)) { AVDictionary *thread_opt = NULL; - codec = avcodec_find_decoder(st->codec->codec_id); + codec = st->codec->codec ? st->codec->codec : + avcodec_find_decoder(st->codec->codec_id); + if (!codec) return -1; @@ -2283,6 +2295,7 @@ static int try_decode_frame(AVStream *st, AVPacket *avpkt, AVDictionary **option st->info->nb_decoded_frames++; pkt.data += ret; pkt.size -= ret; + ret = got_picture; } } if(!pkt.data && !got_picture) @@ -2369,8 +2382,8 @@ static int get_std_framerate(int i){ * And there are "variable" fps files this needs to detect as well. */ static int tb_unreliable(AVCodecContext *c){ - if( c->time_base.den >= 101L*c->time_base.num - || c->time_base.den < 5L*c->time_base.num + if( c->time_base.den >= 101LL*c->time_base.num + || c->time_base.den < 5LL*c->time_base.num /* || c->codec_tag == AV_RL32("DIVX") || c->codec_tag == AV_RL32("XVID")*/ || c->codec_id == CODEC_ID_MPEG2VIDEO @@ -2415,8 +2428,8 @@ int avformat_find_stream_info(AVFormatContext *ic, AVDictionary **options) st->parser->flags |= PARSER_FLAG_COMPLETE_FRAMES; } } - assert(!st->codec->codec); - codec = avcodec_find_decoder(st->codec->codec_id); + codec = st->codec->codec ? st->codec->codec : + avcodec_find_decoder(st->codec->codec_id); /* force thread count to 1 since the h264 decoder will not extract SPS * and PPS to extradata during multi-threaded decoding */ @@ -2589,12 +2602,16 @@ int avformat_find_stream_info(AVFormatContext *ic, AVDictionary **options) st = ic->streams[i]; /* flush the decoders */ - while ((err = try_decode_frame(st, &empty_pkt, + do { + err = try_decode_frame(st, &empty_pkt, (options && i < orig_nb_streams) ? - &options[i] : NULL)) >= 0) - if (has_codec_parameters(st->codec)) - break; + &options[i] : NULL); + } while (err > 0 && !has_codec_parameters(st->codec)); + if (err < 0) { + av_log(ic, AV_LOG_WARNING, + "decoding for stream %d failed\n", st->index); + } if (!has_codec_parameters(st->codec)){ char buf[256]; avcodec_string(buf, sizeof(buf), st->codec, 0); @@ -2608,8 +2625,7 @@ int avformat_find_stream_info(AVFormatContext *ic, AVDictionary **options) // close codecs which were opened in try_decode_frame() for(i=0;inb_streams;i++) { st = ic->streams[i]; - if(st->codec->codec) - avcodec_close(st->codec); + avcodec_close(st->codec); } for(i=0;inb_streams;i++) { st = ic->streams[i]; @@ -2845,6 +2861,7 @@ void avformat_free_context(AVFormatContext *s) av_free_packet(&st->cur_pkt); } av_dict_free(&st->metadata); + av_freep(&st->probe_data.buf); av_freep(&st->index_entries); av_freep(&st->codec->extradata); av_freep(&st->codec->subtitle_header); @@ -4393,3 +4410,12 @@ int ff_add_param_change(AVPacket *pkt, int32_t channels, } return 0; } + +const struct AVCodecTag *avformat_get_riff_video_tags(void) +{ + return ff_codec_bmp_tags; +} +const struct AVCodecTag *avformat_get_riff_audio_tags(void) +{ + return ff_codec_wav_tags; +} diff --git a/libavformat/version.h b/libavformat/version.h index f3848da6bb..aa3928f61f 100644 --- a/libavformat/version.h +++ b/libavformat/version.h @@ -30,7 +30,7 @@ #include "libavutil/avutil.h" #define LIBAVFORMAT_VERSION_MAJOR 53 -#define LIBAVFORMAT_VERSION_MINOR 31 +#define LIBAVFORMAT_VERSION_MINOR 32 #define LIBAVFORMAT_VERSION_MICRO 100 #define LIBAVFORMAT_VERSION_INT AV_VERSION_INT(LIBAVFORMAT_VERSION_MAJOR, \ diff --git a/libavformat/vqf.c b/libavformat/vqf.c index 1014b41e68..88caccacea 100644 --- a/libavformat/vqf.c +++ b/libavformat/vqf.c @@ -174,10 +174,21 @@ static int vqf_read_header(AVFormatContext *s, AVFormatParameters *ap) st->codec->sample_rate = 11025; break; default: + if (rate_flag < 8 || rate_flag > 44) { + av_log(s, AV_LOG_ERROR, "Invalid rate flag %d\n", rate_flag); + return AVERROR_INVALIDDATA; + } st->codec->sample_rate = rate_flag*1000; break; } + if (read_bitrate / st->codec->channels < 8 || + read_bitrate / st->codec->channels > 48) { + av_log(s, AV_LOG_ERROR, "Invalid bitrate per channel %d\n", + read_bitrate / st->codec->channels); + return AVERROR_INVALIDDATA; + } + switch (((st->codec->sample_rate/1000) << 8) + read_bitrate/st->codec->channels) { case (11<<8) + 8 : diff --git a/libavformat/wav.c b/libavformat/wav.c index ab4b3b42e7..8f0d50c270 100644 --- a/libavformat/wav.c +++ b/libavformat/wav.c @@ -238,6 +238,12 @@ static int64_t next_tag(AVIOContext *pb, uint32_t *tag) return avio_rl32(pb); } +/* RIFF chunks are always on a even offset. */ +static int64_t wav_seek_tag(AVIOContext *s, int64_t offset, int whence) +{ + return avio_seek(s, offset + (offset & 1), whence); +} + /* return the size of the found tag */ static int64_t find_tag(AVIOContext *pb, uint32_t tag1) { @@ -250,7 +256,7 @@ static int64_t find_tag(AVIOContext *pb, uint32_t tag1) size = next_tag(pb, &tag); if (tag == tag1) break; - avio_skip(pb, size); + wav_seek_tag(pb, size, SEEK_CUR); } return size; } @@ -508,20 +514,19 @@ static int wav_read_header(AVFormatContext *s, case MKTAG('L', 'I', 'S', 'T'): list_type = avio_rl32(pb); if (size < 4) { - av_log(s, AV_LOG_ERROR, "too short LIST tag\n"); + av_log(s, AV_LOG_ERROR, "too short LIST"); return AVERROR_INVALIDDATA; } switch (list_type) { case MKTAG('I', 'N', 'F', 'O'): - if ((ret = ff_read_riff_info(s, size - 4)) < 0) - return ret; + ff_read_riff_info(s, size - 4); } break; } /* seek to next tag unless we know that we'll run into EOF */ if ((avio_size(pb) > 0 && next_tag_ofs >= avio_size(pb)) || - avio_seek(pb, next_tag_ofs, SEEK_SET) < 0) { + wav_seek_tag(pb, next_tag_ofs, SEEK_SET) < 0) { break; } } diff --git a/libavformat/westwood_vqa.c b/libavformat/westwood_vqa.c index 41dad8e8ab..d78eec3005 100644 --- a/libavformat/westwood_vqa.c +++ b/libavformat/westwood_vqa.c @@ -104,7 +104,6 @@ static int wsvqa_read_header(AVFormatContext *s, header = (unsigned char *)st->codec->extradata; if (avio_read(pb, st->codec->extradata, VQA_HEADER_SIZE) != VQA_HEADER_SIZE) { - av_free(st->codec->extradata); return AVERROR(EIO); } st->codec->width = AV_RL16(&header[6]); diff --git a/libavformat/wtvdec.c b/libavformat/wtvdec.c index db9bb10068..fb768d1244 100644 --- a/libavformat/wtvdec.c +++ b/libavformat/wtvdec.c @@ -258,7 +258,12 @@ static AVIOContext * wtvfile_open2(AVFormatContext *s, const uint8_t *buf, int b dir_length = AV_RL16(buf + 16); file_length = AV_RL64(buf + 24); name_size = 2 * AV_RL32(buf + 32); - if (buf + 48 + name_size > buf_end) { + if (name_size < 0) { + av_log(s, AV_LOG_ERROR, + "bad filename length, remaining directory entries ignored\n"); + break; + } + if (48 + name_size > buf_end - buf) { av_log(s, AV_LOG_ERROR, "filename exceeds buffer size; remaining directory entries ignored\n"); break; } @@ -423,6 +428,7 @@ static void get_attachment(AVFormatContext *s, AVIOContext *pb, int length) st->codec->codec_id = CODEC_ID_MJPEG; st->codec->codec_type = AVMEDIA_TYPE_ATTACHMENT; st->codec->extradata = av_mallocz(filesize); + st->id = -1; if (!st->codec->extradata) goto done; st->codec->extradata_size = filesize; @@ -565,8 +571,10 @@ static AVStream * new_stream(AVFormatContext *s, AVStream *st, int sid, int code if (!wst) return NULL; st = avformat_new_stream(s, NULL); - if (!st) + if (!st) { + av_free(wst); return NULL; + } st->id = sid; st->priv_data = wst; } diff --git a/libavformat/xmv.c b/libavformat/xmv.c index f01e0aa77b..8fbb666b84 100644 --- a/libavformat/xmv.c +++ b/libavformat/xmv.c @@ -48,6 +48,8 @@ XMV_AUDIO_ADPCM51_FRONTCENTERLOW | \ XMV_AUDIO_ADPCM51_REARLEFTRIGHT) +#define XMV_BLOCK_ALIGN_SIZE 36 + /** A video packet with an XMV file. */ typedef struct XMVVideoPacket { int stream_index; ///< The decoder stream index for this video packet. @@ -123,6 +125,15 @@ static int xmv_probe(AVProbeData *p) return 0; } +static int xmv_read_close(AVFormatContext *s) +{ + XMVDemuxContext *xmv = s->priv_data; + + av_free(xmv->audio); + + return 0; +} + static int xmv_read_header(AVFormatContext *s, AVFormatParameters *ap) { @@ -133,6 +144,7 @@ static int xmv_read_header(AVFormatContext *s, uint32_t file_version; uint32_t this_packet_size; uint16_t audio_track; + int ret; avio_skip(pb, 4); /* Next packet size */ @@ -171,8 +183,10 @@ static int xmv_read_header(AVFormatContext *s, avio_skip(pb, 2); /* Unknown (padding?) */ xmv->audio = av_malloc(xmv->audio_track_count * sizeof(XMVAudioPacket)); - if (!xmv->audio) - return AVERROR(ENOMEM); + if (!xmv->audio) { + ret = AVERROR(ENOMEM); + goto fail; + } for (audio_track = 0; audio_track < xmv->audio_track_count; audio_track++) { XMVAudioPacket *packet = &xmv->audio[audio_track]; @@ -187,7 +201,7 @@ static int xmv_read_header(AVFormatContext *s, packet->bit_rate = packet->bits_per_sample * packet->sample_rate * packet->channels; - packet->block_align = 36 * packet->channels; + packet->block_align = XMV_BLOCK_ALIGN_SIZE * packet->channels; packet->block_samples = 64; packet->codec_id = ff_wav_codec_get_id(packet->compression, packet->bits_per_sample); @@ -203,9 +217,19 @@ static int xmv_read_header(AVFormatContext *s, av_log(s, AV_LOG_WARNING, "Unsupported 5.1 ADPCM audio stream " "(0x%04X)\n", packet->flags); + if (!packet->channels || !packet->sample_rate || + packet->channels >= UINT16_MAX / XMV_BLOCK_ALIGN_SIZE) { + av_log(s, AV_LOG_ERROR, "Invalid parameters for audio track %d.\n", + audio_track); + ret = AVERROR_INVALIDDATA; + goto fail; + } + ast = avformat_new_stream(s, NULL); - if (!ast) - return AVERROR(ENOMEM); + if (!ast) { + ret = AVERROR(ENOMEM); + goto fail; + } ast->codec->codec_type = AVMEDIA_TYPE_AUDIO; ast->codec->codec_id = packet->codec_id; @@ -231,6 +255,10 @@ static int xmv_read_header(AVFormatContext *s, xmv->stream_count = xmv->audio_track_count + 1; return 0; + +fail: + xmv_read_close(s); + return ret; } static void xmv_read_extradata(uint8_t *extradata, AVIOContext *pb) @@ -300,7 +328,7 @@ static int xmv_process_packet_header(AVFormatContext *s) xmv->current_stream = 0; if (!xmv->video.frame_count) { xmv->video.frame_count = 1; - xmv->current_stream = 1; + xmv->current_stream = xmv->stream_count > 1; } /* Packet audio header */ @@ -538,15 +566,6 @@ static int xmv_read_packet(AVFormatContext *s, return 0; } -static int xmv_read_close(AVFormatContext *s) -{ - XMVDemuxContext *xmv = s->priv_data; - - av_free(xmv->audio); - - return 0; -} - AVInputFormat ff_xmv_demuxer = { .name = "xmv", .long_name = NULL_IF_CONFIG_SMALL("Microsoft XMV"), diff --git a/libavformat/xwma.c b/libavformat/xwma.c index a4e53fa2d2..551099e8b3 100644 --- a/libavformat/xwma.c +++ b/libavformat/xwma.c @@ -115,6 +115,17 @@ static int xwma_read_header(AVFormatContext *s, AVFormatParameters *ap) } } + if (!st->codec->channels) { + av_log(s, AV_LOG_WARNING, "Invalid channel count: %d\n", + st->codec->channels); + return AVERROR_INVALIDDATA; + } + if (!st->codec->bits_per_coded_sample) { + av_log(s, AV_LOG_WARNING, "Invalid bits_per_coded_sample: %d\n", + st->codec->bits_per_coded_sample); + return AVERROR_INVALIDDATA; + } + /* set the sample rate */ avpriv_set_pts_info(st, 64, 1, st->codec->sample_rate); @@ -189,6 +200,14 @@ static int xwma_read_header(AVFormatContext *s, AVFormatParameters *ap) /* Estimate the duration from the total number of output bytes. */ const uint64_t total_decoded_bytes = dpds_table[dpds_table_size - 1]; + + if (!bytes_per_sample) { + av_log(s, AV_LOG_ERROR, + "Invalid bits_per_coded_sample %d for %d channels\n", + st->codec->bits_per_coded_sample, st->codec->channels); + return AVERROR_INVALIDDATA; + } + st->duration = total_decoded_bytes / bytes_per_sample; /* Use the dpds data to build a seek table. We can only do this after diff --git a/libavformat/yop.c b/libavformat/yop.c index eac3fb6707..9c06404698 100644 --- a/libavformat/yop.c +++ b/libavformat/yop.c @@ -59,6 +59,8 @@ static int yop_read_header(AVFormatContext *s, AVFormatParameters *ap) audio_stream = avformat_new_stream(s, NULL); video_stream = avformat_new_stream(s, NULL); + if (!audio_stream || !video_stream) + return AVERROR(ENOMEM); // Extra data that will be passed to the decoder video_stream->codec->extradata_size = 8; diff --git a/libavformat/yuv4mpeg.c b/libavformat/yuv4mpeg.c index 61c72f5d82..31fb08469a 100644 --- a/libavformat/yuv4mpeg.c +++ b/libavformat/yuv4mpeg.c @@ -156,9 +156,8 @@ static int yuv4_write_header(AVFormatContext *s) return AVERROR(EIO); if (s->streams[0]->codec->codec_id != CODEC_ID_RAWVIDEO) { - av_log(s, AV_LOG_ERROR, - "A non-rawvideo stream was selected, but yuv4mpeg only handles rawvideo streams\n"); - return AVERROR(EINVAL); + av_log(s, AV_LOG_ERROR, "ERROR: Only rawvideo supported.\n"); + return AVERROR_INVALIDDATA; } if (s->streams[0]->codec->pix_fmt == PIX_FMT_YUV411P) { @@ -369,7 +368,7 @@ static int yuv4_read_packet(AVFormatContext *s, AVPacket *pkt) { int i; char header[MAX_FRAME_HEADER+1]; - int packet_size, width, height; + int packet_size, width, height, ret; AVStream *st = s->streams[0]; struct frame_attributes *s1 = s->priv_data; @@ -380,20 +379,28 @@ static int yuv4_read_packet(AVFormatContext *s, AVPacket *pkt) break; } } - if (i == MAX_FRAME_HEADER) - return -1; + if (s->pb->error) + return s->pb->error; + else if (s->pb->eof_reached) + return AVERROR_EOF; + else if (i == MAX_FRAME_HEADER) + return AVERROR_INVALIDDATA; + if (strncmp(header, Y4M_FRAME_MAGIC, strlen(Y4M_FRAME_MAGIC))) - return -1; + return AVERROR_INVALIDDATA; width = st->codec->width; height = st->codec->height; packet_size = avpicture_get_size(st->codec->pix_fmt, width, height); if (packet_size < 0) - return -1; + return packet_size; - if (av_get_packet(s->pb, pkt, packet_size) != packet_size) - return AVERROR(EIO); + ret = av_get_packet(s->pb, pkt, packet_size); + if (ret < 0) + return ret; + else if (ret != packet_size) + return s->pb->eof_reached ? AVERROR_EOF : AVERROR(EIO); if (st->codec->coded_frame) { st->codec->coded_frame->interlaced_frame = s1->interlaced_frame; diff --git a/libavutil/Makefile b/libavutil/Makefile index b6165a1bb6..2cd763c1e7 100644 --- a/libavutil/Makefile +++ b/libavutil/Makefile @@ -19,6 +19,7 @@ HEADERS = adler32.h \ fifo.h \ file.h \ imgutils.h \ + intfloat.h \ intfloat_readwrite.h \ intreadwrite.h \ lfg.h \ diff --git a/libavutil/avutil.h b/libavutil/avutil.h index 3f772621e0..99af12db81 100644 --- a/libavutil/avutil.h +++ b/libavutil/avutil.h @@ -154,8 +154,8 @@ */ #define LIBAVUTIL_VERSION_MAJOR 51 -#define LIBAVUTIL_VERSION_MINOR 34 -#define LIBAVUTIL_VERSION_MICRO 101 +#define LIBAVUTIL_VERSION_MINOR 35 +#define LIBAVUTIL_VERSION_MICRO 100 #define LIBAVUTIL_VERSION_INT AV_VERSION_INT(LIBAVUTIL_VERSION_MAJOR, \ LIBAVUTIL_VERSION_MINOR, \ diff --git a/libavutil/cpu.c b/libavutil/cpu.c index fa64a83cfa..3d65bca3d1 100644 --- a/libavutil/cpu.c +++ b/libavutil/cpu.c @@ -69,6 +69,7 @@ static const struct { { AV_CPU_FLAG_FMA4, "fma4" }, { AV_CPU_FLAG_3DNOW, "3dnow" }, { AV_CPU_FLAG_3DNOWEXT, "3dnowext" }, + { AV_CPU_FLAG_CMOV, "cmov" }, #endif { 0 } }; diff --git a/libavutil/cpu.h b/libavutil/cpu.h index 5f7eed2b60..ed5d8594e9 100644 --- a/libavutil/cpu.h +++ b/libavutil/cpu.h @@ -41,6 +41,7 @@ #define AV_CPU_FLAG_XOP 0x0400 ///< Bulldozer XOP functions #define AV_CPU_FLAG_FMA4 0x0800 ///< Bulldozer FMA4 functions #define AV_CPU_FLAG_IWMMXT 0x0100 ///< XScale IWMMXT +#define AV_CPU_FLAG_CMOV 0x1000 ///< i686 cmov #define AV_CPU_FLAG_ALTIVEC 0x0001 ///< standard /** diff --git a/libavutil/error.c b/libavutil/error.c index 1d944eb368..56841d3e46 100644 --- a/libavutil/error.c +++ b/libavutil/error.c @@ -41,6 +41,7 @@ int av_strerror(int errnum, char *errbuf, size_t errbuf_size) case AVERROR_PATCHWELCOME: errstr = "Not yet implemented in FFmpeg, patches welcome"; break; case AVERROR_PROTOCOL_NOT_FOUND:errstr = "Protocol not found" ; break; case AVERROR_STREAM_NOT_FOUND: errstr = "Stream not found" ; break; + case AVERROR_UNKNOWN: errstr = "Unknown error occurred" ; break; } if (errstr) { diff --git a/libavutil/error.h b/libavutil/error.h index 40e54f1edc..76688c7b69 100644 --- a/libavutil/error.h +++ b/libavutil/error.h @@ -64,6 +64,7 @@ * it has been introduced in Libav after our AVERROR_BUG and with a modified value. */ #define AVERROR_BUG2 (-MKTAG( 'B','U','G',' ')) +#define AVERROR_UNKNOWN (-MKTAG( 'U','N','K','N')) ///< Unknown error, typically from an external library /** * Put a description of the AVERROR code errnum in errbuf. diff --git a/libavutil/eval.c b/libavutil/eval.c index 2ee3965e7c..af1a320709 100644 --- a/libavutil/eval.c +++ b/libavutil/eval.c @@ -312,8 +312,8 @@ static int parse_primary(AVExpr **e, Parser *p) else if (strmatch(next, "eq" )) d->type = e_eq; else if (strmatch(next, "gte" )) d->type = e_gte; else if (strmatch(next, "gt" )) d->type = e_gt; - else if (strmatch(next, "lte" )) { AVExpr *tmp = d->param[1]; d->param[1] = d->param[0]; d->param[0] = tmp; d->type = e_gt; } - else if (strmatch(next, "lt" )) { AVExpr *tmp = d->param[1]; d->param[1] = d->param[0]; d->param[0] = tmp; d->type = e_gte; } + else if (strmatch(next, "lte" )) { AVExpr *tmp = d->param[1]; d->param[1] = d->param[0]; d->param[0] = tmp; d->type = e_gte; } + else if (strmatch(next, "lt" )) { AVExpr *tmp = d->param[1]; d->param[1] = d->param[0]; d->param[0] = tmp; d->type = e_gt; } else if (strmatch(next, "ld" )) d->type = e_ld; else if (strmatch(next, "isnan" )) d->type = e_isnan; else if (strmatch(next, "st" )) d->type = e_st; diff --git a/libavutil/file.c b/libavutil/file.c index e59335a77a..ca78505be5 100644 --- a/libavutil/file.c +++ b/libavutil/file.c @@ -171,6 +171,7 @@ int av_tempfile(const char *prefix, char **filename, int log_offset, void *log_c if (fd < 0) { int err = AVERROR(errno); av_log(&file_log_ctx, AV_LOG_ERROR, "ff_tempfile: Cannot open temporary file %s\n", *filename); + av_freep(filename); return err; } return fd; /* success */ diff --git a/libavutil/lzo.c b/libavutil/lzo.c index 3642308100..9e00da41a4 100644 --- a/libavutil/lzo.c +++ b/libavutil/lzo.c @@ -62,7 +62,13 @@ static inline int get_byte(LZOContext *c) { static inline int get_len(LZOContext *c, int x, int mask) { int cnt = x & mask; if (!cnt) { - while (!(x = get_byte(c))) cnt += 255; + while (!(x = get_byte(c))) { + if (cnt >= INT_MAX - 1000) { + c->error |= AV_LZO_ERROR; + break; + } + cnt += 255; + } cnt += mask + x; } return cnt; @@ -88,6 +94,10 @@ static inline int get_len(LZOContext *c, int x, int mask) { static inline void copy(LZOContext *c, int cnt) { register const uint8_t *src = c->in; register uint8_t *dst = c->out; + if (cnt < 0) { + c->error |= AV_LZO_ERROR; + return; + } if (cnt > c->in_end - src) { cnt = FFMAX(c->in_end - src, 0); c->error |= AV_LZO_INPUT_DEPLETED; @@ -113,15 +123,18 @@ static inline void memcpy_backptr(uint8_t *dst, int back, int cnt); /** * @brief Copies previously decoded bytes to current position. * @param back how many bytes back we start, must be > 0 - * @param cnt number of bytes to copy, must be >= 0 + * @param cnt number of bytes to copy, must be > 0 * * cnt > back is valid, this will copy the bytes we just copied, * thus creating a repeating pattern with a period length of back. */ static inline void copy_backptr(LZOContext *c, int back, int cnt) { - register const uint8_t *src = &c->out[-back]; register uint8_t *dst = c->out; - if (src < c->out_start || src > dst) { + if (cnt <= 0) { + c->error |= AV_LZO_ERROR; + return; + } + if (dst - c->out_start < back) { c->error |= AV_LZO_INVALID_BACKPTR; return; } diff --git a/libavutil/mathematics.c b/libavutil/mathematics.c index 180f72e3f0..2fe4a7c36b 100644 --- a/libavutil/mathematics.c +++ b/libavutil/mathematics.c @@ -23,7 +23,6 @@ * miscellaneous math routines and tables */ -#include #include #include #include "mathematics.h" @@ -77,9 +76,9 @@ int64_t av_gcd(int64_t a, int64_t b){ int64_t av_rescale_rnd(int64_t a, int64_t b, int64_t c, enum AVRounding rnd){ int64_t r=0; - assert(c > 0); - assert(b >=0); - assert((unsigned)rnd<=5 && rnd!=4); + + if (c <= 0 || b < 0 || rnd == 4 || rnd > 5) + return INT64_MIN; if(a<0 && a != INT64_MIN) return -av_rescale_rnd(-a, b, c, rnd ^ ((rnd>>1)&1)); diff --git a/libavutil/opt.c b/libavutil/opt.c index 2f8be3bfba..9f8171541c 100644 --- a/libavutil/opt.c +++ b/libavutil/opt.c @@ -56,8 +56,10 @@ const AVOption *av_next_option(void *obj, const AVOption *last) const AVOption *av_opt_next(void *obj, const AVOption *last) { AVClass *class = *(AVClass**)obj; - if (!last && class->option[0].name) return class->option; - if (last && last[1].name) return ++last; + if (!last && class->option && class->option[0].name) + return class->option; + if (last && last[1].name) + return ++last; return NULL; } diff --git a/libavutil/samplefmt.c b/libavutil/samplefmt.c index f4300036c2..be3bdeb18f 100644 --- a/libavutil/samplefmt.c +++ b/libavutil/samplefmt.c @@ -114,6 +114,13 @@ int av_samples_get_buffer_size(int *linesize, int nb_channels, int nb_samples, if (!sample_size || nb_samples <= 0 || nb_channels <= 0) return AVERROR(EINVAL); + /* auto-select alignment if not specified */ + if (!align) { + if (nb_samples > INT_MAX - 31) + return AVERROR(EINVAL); + align = 32; + } + /* check for integer overflow */ if (nb_channels > INT_MAX / align || (int64_t)nb_channels * nb_samples > (INT_MAX - (align * nb_channels)) / sample_size) diff --git a/libavutil/samplefmt.h b/libavutil/samplefmt.h index 855cffd838..fc25d828eb 100644 --- a/libavutil/samplefmt.h +++ b/libavutil/samplefmt.h @@ -107,6 +107,7 @@ int av_sample_fmt_is_planar(enum AVSampleFormat sample_fmt); * @param nb_channels the number of channels * @param nb_samples the number of samples in a single channel * @param sample_fmt the sample format + * @param align buffer size alignment (0 = default, 1 = no alignment) * @return required buffer size, or negative error code on failure */ int av_samples_get_buffer_size(int *linesize, int nb_channels, int nb_samples, @@ -130,7 +131,7 @@ int av_samples_get_buffer_size(int *linesize, int nb_channels, int nb_samples, * @param nb_channels the number of channels * @param nb_samples the number of samples in a single channel * @param sample_fmt the sample format - * @param align buffer size alignment (1 = no alignment required) + * @param align buffer size alignment (0 = default, 1 = no alignment) * @return 0 on success or a negative error code on failure */ int av_samples_fill_arrays(uint8_t **audio_data, int *linesize, uint8_t *buf, @@ -146,7 +147,7 @@ int av_samples_fill_arrays(uint8_t **audio_data, int *linesize, uint8_t *buf, * @param[out] linesize aligned size for audio buffer(s) * @param nb_channels number of audio channels * @param nb_samples number of samples per channel - * @param align buffer size alignment (1 = no alignment required) + * @param align buffer size alignment (0 = default, 1 = no alignment) * @return 0 on success or a negative error code on failure * @see av_samples_fill_arrays() */ diff --git a/libavutil/x86/cpu.c b/libavutil/x86/cpu.c index 93df737c28..5782ff73cf 100644 --- a/libavutil/x86/cpu.c +++ b/libavutil/x86/cpu.c @@ -83,6 +83,8 @@ int ff_get_cpu_flags_x86(void) cpuid(1, eax, ebx, ecx, std_caps); family = ((eax>>8)&0xf) + ((eax>>20)&0xff); model = ((eax>>4)&0xf) + ((eax>>12)&0xf0); + if (std_caps & (1 << 15)) + rval |= AV_CPU_FLAG_CMOV; if (std_caps & (1<<23)) rval |= AV_CPU_FLAG_MMX; if (std_caps & (1<<25)) diff --git a/libpostproc/postprocess_template.c b/libpostproc/postprocess_template.c index 4b8184c4f4..406af654f4 100644 --- a/libpostproc/postprocess_template.c +++ b/libpostproc/postprocess_template.c @@ -3225,7 +3225,7 @@ static void RENAME(postProcess)(const uint8_t src[], int srcStride, uint8_t dst[ c.frameNum++; // first frame is fscked so we ignore it - if(c.frameNum == 1) yHistogram[0]= width*height/64*15/256; + if(c.frameNum == 1) yHistogram[0]= width*(uint64_t)height/64*15/256; for(i=0; i<256; i++){ sum+= yHistogram[i]; diff --git a/library.mak b/library.mak index 40a364eccc..53b35eb020 100644 --- a/library.mak +++ b/library.mak @@ -51,8 +51,7 @@ endif clean:: $(RM) $(addprefix $(SUBDIR),*-example$(EXESUF) *-test$(EXESUF) $(CLEANFILES) $(CLEANSUFFIXES) $(LIBSUFFIXES)) \ - $(foreach dir,$(DIRS),$(CLEANSUFFIXES:%=$(SUBDIR)$(dir)/%)) \ - $(HOSTOBJS) $(HOSTPROGS) + $(foreach dir,$(DIRS),$(CLEANSUFFIXES:%=$(SUBDIR)$(dir)/%)) distclean:: clean $(RM) $(DISTCLEANSUFFIXES:%=$(SUBDIR)%) \ @@ -84,8 +83,8 @@ uninstall-libs:: -$(RM) "$(SHLIBDIR)/$(SLIBNAME_WITH_MAJOR)" \ "$(SHLIBDIR)/$(SLIBNAME)" \ "$(SHLIBDIR)/$(SLIBNAME_WITH_VERSION)" - -$(RM) $(SLIB_INSTALL_EXTRA_SHLIB:%="$(SHLIBDIR)"%) - -$(RM) $(SLIB_INSTALL_EXTRA_LIB:%="$(LIBDIR)"%) + -$(RM) $(SLIB_INSTALL_EXTRA_SHLIB:%="$(SHLIBDIR)/%") + -$(RM) $(SLIB_INSTALL_EXTRA_LIB:%="$(LIBDIR)/%") -$(RM) "$(LIBDIR)/$(LIBNAME)" uninstall-headers:: diff --git a/libswscale/ppc/swscale_altivec.c b/libswscale/ppc/swscale_altivec.c index f8f109e72d..056ba070fa 100644 --- a/libswscale/ppc/swscale_altivec.c +++ b/libswscale/ppc/swscale_altivec.c @@ -145,7 +145,7 @@ yuv2planeX_altivec(const int16_t *filter, int filterSize, static void hScale_altivec_real(SwsContext *c, int16_t *dst, int dstW, const uint8_t *src, const int16_t *filter, - const int16_t *filterPos, int filterSize) + const int32_t *filterPos, int filterSize) { register int i; DECLARE_ALIGNED(16, int, tempo)[4]; diff --git a/libswscale/swscale-test.c b/libswscale/swscale-test.c index ef6c55ce02..24a4747d02 100644 --- a/libswscale/swscale-test.c +++ b/libswscale/swscale-test.c @@ -87,7 +87,7 @@ static int doTest(uint8_t *ref[4], int refStride[4], int w, int h, static int srcStride[4]; uint8_t *dst[4] = { 0 }; uint8_t *out[4] = { 0 }; - int dstStride[4]; + int dstStride[4] = {0}; int i; uint64_t ssdY, ssdU = 0, ssdV = 0, ssdA = 0; struct SwsContext *dstContext = NULL, *outContext = NULL; diff --git a/libswscale/swscale.c b/libswscale/swscale.c index d8861d6c04..a98a389d0d 100644 --- a/libswscale/swscale.c +++ b/libswscale/swscale.c @@ -2000,7 +2000,7 @@ static void planar_rgb16be_to_uv(uint8_t *_dstU, uint8_t *_dstV, const uint8_t * static void hScale16To19_c(SwsContext *c, int16_t *_dst, int dstW, const uint8_t *_src, const int16_t *filter, - const int16_t *filterPos, int filterSize) + const int32_t *filterPos, int filterSize) { int i; int32_t *dst = (int32_t *) _dst; @@ -2026,7 +2026,7 @@ static void hScale16To19_c(SwsContext *c, int16_t *_dst, int dstW, const uint8_t static void hScale16To15_c(SwsContext *c, int16_t *dst, int dstW, const uint8_t *_src, const int16_t *filter, - const int16_t *filterPos, int filterSize) + const int32_t *filterPos, int filterSize) { int i; const uint16_t *src = (const uint16_t *) _src; @@ -2050,7 +2050,7 @@ static void hScale16To15_c(SwsContext *c, int16_t *dst, int dstW, const uint8_t // bilinear / bicubic scaling static void hScale8To15_c(SwsContext *c, int16_t *dst, int dstW, const uint8_t *src, - const int16_t *filter, const int16_t *filterPos, + const int16_t *filter, const int32_t *filterPos, int filterSize) { int i; @@ -2068,7 +2068,7 @@ static void hScale8To15_c(SwsContext *c, int16_t *dst, int dstW, const uint8_t * } static void hScale8To19_c(SwsContext *c, int16_t *_dst, int dstW, const uint8_t *src, - const int16_t *filter, const int16_t *filterPos, + const int16_t *filter, const int32_t *filterPos, int filterSize) { int i; @@ -2171,7 +2171,7 @@ static void hyscale_fast_c(SwsContext *c, int16_t *dst, int dstWidth, static av_always_inline void hyscale(SwsContext *c, int16_t *dst, int dstWidth, const uint8_t *src_in[4], int srcW, int xInc, const int16_t *hLumFilter, - const int16_t *hLumFilterPos, int hLumFilterSize, + const int32_t *hLumFilterPos, int hLumFilterSize, uint8_t *formatConvBuffer, uint32_t *pal, int isAlpha) { @@ -2219,7 +2219,7 @@ static void hcscale_fast_c(SwsContext *c, int16_t *dst1, int16_t *dst2, static av_always_inline void hcscale(SwsContext *c, int16_t *dst1, int16_t *dst2, int dstWidth, const uint8_t *src_in[4], int srcW, int xInc, const int16_t *hChrFilter, - const int16_t *hChrFilterPos, int hChrFilterSize, + const int32_t *hChrFilterPos, int hChrFilterSize, uint8_t *formatConvBuffer, uint32_t *pal) { const uint8_t *src1 = src_in[1], *src2 = src_in[2]; @@ -2510,10 +2510,10 @@ static int swScale(SwsContext *c, const uint8_t* src[], const int chrXInc= c->chrXInc; const enum PixelFormat dstFormat= c->dstFormat; const int flags= c->flags; - int16_t *vLumFilterPos= c->vLumFilterPos; - int16_t *vChrFilterPos= c->vChrFilterPos; - int16_t *hLumFilterPos= c->hLumFilterPos; - int16_t *hChrFilterPos= c->hChrFilterPos; + int32_t *vLumFilterPos= c->vLumFilterPos; + int32_t *vChrFilterPos= c->vChrFilterPos; + int32_t *hLumFilterPos= c->hLumFilterPos; + int32_t *hChrFilterPos= c->hChrFilterPos; int16_t *hLumFilter= c->hLumFilter; int16_t *hChrFilter= c->hChrFilter; int32_t *lumMmxFilter= c->lumMmxFilter; diff --git a/libswscale/swscale_internal.h b/libswscale/swscale_internal.h index 3c4f3953c1..b2f844ff8c 100644 --- a/libswscale/swscale_internal.h +++ b/libswscale/swscale_internal.h @@ -34,7 +34,7 @@ #define STR(s) AV_TOSTRING(s) // AV_STRINGIFY is too long -#define YUVRGB_TABLE_HEADROOM 128 +#define YUVRGB_TABLE_HEADROOM 256 #define FAST_BGR2YV12 // use 7-bit instead of 15-bit coefficients @@ -299,10 +299,10 @@ typedef struct SwsContext { int16_t *hChrFilter; ///< Array of horizontal filter coefficients for chroma planes. int16_t *vLumFilter; ///< Array of vertical filter coefficients for luma/alpha planes. int16_t *vChrFilter; ///< Array of vertical filter coefficients for chroma planes. - int16_t *hLumFilterPos; ///< Array of horizontal filter starting positions for each dst[i] for luma/alpha planes. - int16_t *hChrFilterPos; ///< Array of horizontal filter starting positions for each dst[i] for chroma planes. - int16_t *vLumFilterPos; ///< Array of vertical filter starting positions for each dst[i] for luma/alpha planes. - int16_t *vChrFilterPos; ///< Array of vertical filter starting positions for each dst[i] for chroma planes. + int32_t *hLumFilterPos; ///< Array of horizontal filter starting positions for each dst[i] for luma/alpha planes. + int32_t *hChrFilterPos; ///< Array of horizontal filter starting positions for each dst[i] for chroma planes. + int32_t *vLumFilterPos; ///< Array of vertical filter starting positions for each dst[i] for luma/alpha planes. + int32_t *vChrFilterPos; ///< Array of vertical filter starting positions for each dst[i] for chroma planes. int hLumFilterSize; ///< Horizontal filter size for luma/alpha pixels. int hChrFilterSize; ///< Horizontal filter size for chroma pixels. int vLumFilterSize; ///< Vertical filter size for luma/alpha pixels. @@ -359,8 +359,8 @@ typedef struct SwsContext { #define V_TEMP "11*8+4*4*256*2+32" #define Y_TEMP "11*8+4*4*256*2+40" #define ALP_MMX_FILTER_OFFSET "11*8+4*4*256*2+48" -#define UV_OFF "11*8+4*4*256*3+48" -#define UV_OFFx2 "11*8+4*4*256*3+56" +#define UV_OFF_PX "11*8+4*4*256*3+48" +#define UV_OFF_BYTE "11*8+4*4*256*3+56" #define DITHER16 "11*8+4*4*256*3+64" #define DITHER32 "11*8+4*4*256*3+80" @@ -515,10 +515,10 @@ typedef struct SwsContext { /** @{ */ void (*hyScale)(struct SwsContext *c, int16_t *dst, int dstW, const uint8_t *src, const int16_t *filter, - const int16_t *filterPos, int filterSize); + const int32_t *filterPos, int filterSize); void (*hcScale)(struct SwsContext *c, int16_t *dst, int dstW, const uint8_t *src, const int16_t *filter, - const int16_t *filterPos, int filterSize); + const int32_t *filterPos, int filterSize); /** @} */ /// Color range conversion function for luma plane if needed. diff --git a/libswscale/swscale_unscaled.c b/libswscale/swscale_unscaled.c index e1ba79926d..d4b39f4a30 100644 --- a/libswscale/swscale_unscaled.c +++ b/libswscale/swscale_unscaled.c @@ -483,6 +483,9 @@ static rgbConvFn findRgbConvFn(SwsContext *c) } } + if ((dstFormat == PIX_FMT_RGB32_1 || dstFormat == PIX_FMT_BGR32_1) && !isRGBA32(srcFormat) && ALT32_CORR<0) + return NULL; + return conv; } diff --git a/libswscale/utils.c b/libswscale/utils.c index 5826c17e31..abd9993ac5 100644 --- a/libswscale/utils.c +++ b/libswscale/utils.c @@ -191,7 +191,7 @@ static double getSplineCoeff(double a, double b, double c, double d, double dist dist-1.0); } -static int initFilter(int16_t **outFilter, int16_t **filterPos, int *outFilterSize, int xInc, +static int initFilter(int16_t **outFilter, int32_t **filterPos, int *outFilterSize, int xInc, int srcW, int dstW, int filterAlign, int one, int flags, int cpu_flags, SwsVector *srcFilter, SwsVector *dstFilter, double param[2]) { @@ -207,7 +207,7 @@ static int initFilter(int16_t **outFilter, int16_t **filterPos, int *outFilterSi emms_c(); //FIXME this should not be required but it IS (even for non-MMX versions) // NOTE: the +3 is for the MMX(+1)/SSE(+3) scaler which reads over the end - FF_ALLOC_OR_GOTO(NULL, *filterPos, (dstW+3)*sizeof(int16_t), fail); + FF_ALLOC_OR_GOTO(NULL, *filterPos, (dstW+3)*sizeof(**filterPos), fail); if (FFABS(xInc - 0x10000) <10) { // unscaled int i; @@ -274,13 +274,13 @@ static int initFilter(int16_t **outFilter, int16_t **filterPos, int *outFilterSi if (xInc <= 1<<16) filterSize= 1 + sizeFactor; // upscale else filterSize= 1 + (sizeFactor*srcW + dstW - 1)/ dstW; - if (filterSize > srcW-2) filterSize=srcW-2; + filterSize = av_clip(filterSize, 1, srcW - 2); FF_ALLOC_OR_GOTO(NULL, filter, dstW*sizeof(*filter)*filterSize, fail); xDstInSrc= xInc - 0x10000; for (i=0; ilumXInc= ((srcW<<16) + (dstW>>1))/dstW; - c->lumYInc= ((srcH<<16) + (dstH>>1))/dstH; + c->lumXInc= (((int64_t)srcW<<16) + (dstW>>1))/dstW; + c->lumYInc= (((int64_t)srcH<<16) + (dstH>>1))/dstH; c->dstFormatBpp = av_get_bits_per_pixel(&av_pix_fmt_descriptors[dstFormat]); c->srcFormatBpp = av_get_bits_per_pixel(&av_pix_fmt_descriptors[srcFormat]); c->vRounder= 4* 0x0001000100010001ULL; @@ -920,8 +920,8 @@ int sws_init_context(SwsContext *c, SwsFilter *srcFilter, SwsFilter *dstFilter) else c->canMMX2BeUsed=0; - c->chrXInc= ((c->chrSrcW<<16) + (c->chrDstW>>1))/c->chrDstW; - c->chrYInc= ((c->chrSrcH<<16) + (c->chrDstH>>1))/c->chrDstH; + c->chrXInc= (((int64_t)c->chrSrcW<<16) + (c->chrDstW>>1))/c->chrDstW; + c->chrYInc= (((int64_t)c->chrSrcH<<16) + (c->chrDstH>>1))/c->chrDstH; // match pixel 0 of the src to pixel 0 of dst and match pixel n-2 of src to pixel n-2 of dst // but only for the FAST_BILINEAR mode otherwise do correct scaling @@ -936,8 +936,8 @@ int sws_init_context(SwsContext *c, SwsFilter *srcFilter, SwsFilter *dstFilter) } //we don't use the x86 asm scaler if MMX is available else if (HAVE_MMX && cpu_flags & AV_CPU_FLAG_MMX && c->dstBpc <= 10) { - c->lumXInc = ((srcW-2)<<16)/(dstW-2) - 20; - c->chrXInc = ((c->chrSrcW-2)<<16)/(c->chrDstW-2) - 20; + c->lumXInc = ((int64_t)(srcW-2)<<16)/(dstW-2) - 20; + c->chrXInc = ((int64_t)(c->chrSrcW-2)<<16)/(c->chrDstW-2) - 20; } } @@ -1044,7 +1044,7 @@ int sws_init_context(SwsContext *c, SwsFilter *srcFilter, SwsFilter *dstFilter) c->vLumBufSize= c->vLumFilterSize; c->vChrBufSize= c->vChrFilterSize; for (i=0; ichrDstH / dstH; + int chrI = (int64_t) i * c->chrDstH / dstH; int nextSlice= FFMAX(c->vLumFilterPos[i ] + c->vLumFilterSize - 1, ((c->vChrFilterPos[chrI] + c->vChrFilterSize - 1)<chrSrcVSubSample)); diff --git a/libswscale/x86/rgb2rgb_template.c b/libswscale/x86/rgb2rgb_template.c index 3bca43c42e..9e28f4bcb1 100644 --- a/libswscale/x86/rgb2rgb_template.c +++ b/libswscale/x86/rgb2rgb_template.c @@ -1959,6 +1959,7 @@ static void RENAME(interleaveBytes)(const uint8_t *src1, const uint8_t *src2, ui for (h=0; h < height; h++) { int w; + if (width >= 16) #if COMPILE_TEMPLATE_SSE2 __asm__( "xor %%"REG_a", %%"REG_a" \n\t" diff --git a/libswscale/x86/scale.asm b/libswscale/x86/scale.asm index 09313b926f..692a88fe39 100644 --- a/libswscale/x86/scale.asm +++ b/libswscale/x86/scale.asm @@ -38,7 +38,7 @@ SECTION .text ; (SwsContext *c, int{16,32}_t *dst, ; int dstW, const uint{8,16}_t *src, ; const int16_t *filter, -; const int16_t *filterPos, int filterSize); +; const int32_t *filterPos, int filterSize); ; ; Scale one horizontal line. Input is either 8-bits width or 16-bits width ; ($source_width can be either 8, 9, 10 or 16, difference is whether we have to @@ -53,6 +53,9 @@ SECTION .text cglobal hscale%1to%2_%4_%5, %6, 7, %7 %ifdef ARCH_X86_64 movsxd r2, r2d +%define mov32 movsxd +%else ; x86-32 +%define mov32 mov %endif ; x86-64 %if %2 == 19 %if mmsize == 8 ; mmx @@ -95,14 +98,14 @@ cglobal hscale%1to%2_%4_%5, %6, 7, %7 %else ; %2 == 19 lea r1, [r1+r2*(4>>r2shr)] %endif ; %2 == 15/19 - lea r5, [r5+r2*(2>>r2shr)] + lea r5, [r5+r2*(4>>r2shr)] neg r2 .loop: %if %3 == 4 ; filterSize == 4 scaling ; load 2x4 or 4x4 source pixels into m0/m1 - movsx r0, word [r5+r2*2+0] ; filterPos[0] - movsx r6, word [r5+r2*2+2] ; filterPos[1] + mov32 r0, dword [r5+r2*4+0] ; filterPos[0] + mov32 r6, dword [r5+r2*4+4] ; filterPos[1] movlh m0, [r3+r0*srcmul] ; src[filterPos[0] + {0,1,2,3}] %if mmsize == 8 movlh m1, [r3+r6*srcmul] ; src[filterPos[1] + {0,1,2,3}] @@ -112,8 +115,8 @@ cglobal hscale%1to%2_%4_%5, %6, 7, %7 %else ; %1 == 8 movd m4, [r3+r6*srcmul] ; src[filterPos[1] + {0,1,2,3}] %endif - movsx r0, word [r5+r2*2+4] ; filterPos[2] - movsx r6, word [r5+r2*2+6] ; filterPos[3] + mov32 r0, dword [r5+r2*4+8] ; filterPos[2] + mov32 r6, dword [r5+r2*4+12] ; filterPos[3] movlh m1, [r3+r0*srcmul] ; src[filterPos[2] + {0,1,2,3}] %if %1 > 8 movhps m1, [r3+r6*srcmul] ; src[filterPos[3] + {0,1,2,3}] @@ -156,8 +159,8 @@ cglobal hscale%1to%2_%4_%5, %6, 7, %7 %endif ; mmx/sse2/ssse3/sse4 %else ; %3 == 8, i.e. filterSize == 8 scaling ; load 2x8 or 4x8 source pixels into m0, m1, m4 and m5 - movsx r0, word [r5+r2*1+0] ; filterPos[0] - movsx r6, word [r5+r2*1+2] ; filterPos[1] + mov32 r0, dword [r5+r2*2+0] ; filterPos[0] + mov32 r6, dword [r5+r2*2+4] ; filterPos[1] movbh m0, [r3+ r0 *srcmul] ; src[filterPos[0] + {0,1,2,3,4,5,6,7}] %if mmsize == 8 movbh m1, [r3+(r0+4)*srcmul] ; src[filterPos[0] + {4,5,6,7}] @@ -165,8 +168,8 @@ cglobal hscale%1to%2_%4_%5, %6, 7, %7 movbh m5, [r3+(r6+4)*srcmul] ; src[filterPos[1] + {4,5,6,7}] %else ; mmsize == 16 movbh m1, [r3+ r6 *srcmul] ; src[filterPos[1] + {0,1,2,3,4,5,6,7}] - movsx r0, word [r5+r2*1+4] ; filterPos[2] - movsx r6, word [r5+r2*1+6] ; filterPos[3] + mov32 r0, dword [r5+r2*2+8] ; filterPos[2] + mov32 r6, dword [r5+r2*2+12] ; filterPos[3] movbh m4, [r3+ r0 *srcmul] ; src[filterPos[2] + {0,1,2,3,4,5,6,7}] movbh m5, [r3+ r6 *srcmul] ; src[filterPos[3] + {0,1,2,3,4,5,6,7}] %endif ; mmsize == 8/16 @@ -251,7 +254,7 @@ cglobal hscale%1to%2_%4_%5, %6, 7, %7 %define r1x r1 %define filter2 r6m %endif ; x86-32/64 - lea r5, [r5+r2*2] + lea r5, [r5+r2*4] %if %2 == 15 lea r1, [r1+r2*2] %else ; %2 == 19 @@ -261,8 +264,8 @@ cglobal hscale%1to%2_%4_%5, %6, 7, %7 neg r2 .loop: - movsx r0, word [r5+r2*2+0] ; filterPos[0] - movsx r1x, word [r5+r2*2+2] ; filterPos[1] + mov32 r0, dword [r5+r2*4+0] ; filterPos[0] + mov32 r1x, dword [r5+r2*4+4] ; filterPos[1] ; FIXME maybe do 4px/iteration on x86-64 (x86-32 wouldn't have enough regs)? pxor m4, m4 pxor m5, m5 @@ -293,7 +296,7 @@ cglobal hscale%1to%2_%4_%5, %6, 7, %7 jl .innerloop %ifidn %4, X4 - movsx r1x, word [r5+r2*2+2] ; filterPos[1] + mov32 r1x, dword [r5+r2*4+4] ; filterPos[1] movlh m0, [src_reg+r0 *srcmul] ; split last 4 srcpx of dstpx[0] sub r1x, r6 ; and first 4 srcpx of dstpx[1] %if %1 > 8 diff --git a/libswscale/x86/swscale_mmx.c b/libswscale/x86/swscale_mmx.c index d0bb861618..fdfd1f215a 100644 --- a/libswscale/x86/swscale_mmx.c +++ b/libswscale/x86/swscale_mmx.c @@ -108,8 +108,8 @@ void updateMMXDitherTables(SwsContext *c, int dstY, int lumBufIndex, int chrBufI int16_t **alpPixBuf= c->alpPixBuf; const int vLumBufSize= c->vLumBufSize; const int vChrBufSize= c->vChrBufSize; - int16_t *vLumFilterPos= c->vLumFilterPos; - int16_t *vChrFilterPos= c->vChrFilterPos; + int32_t *vLumFilterPos= c->vLumFilterPos; + int32_t *vChrFilterPos= c->vChrFilterPos; int16_t *vLumFilter= c->vLumFilter; int16_t *vChrFilter= c->vChrFilter; int32_t *lumMmxFilter= c->lumMmxFilter; @@ -132,6 +132,44 @@ void updateMMXDitherTables(SwsContext *c, int dstY, int lumBufIndex, int chrBufI const int16_t **chrUSrcPtr= (const int16_t **)(void*) chrUPixBuf + chrBufIndex + firstChrSrcY - lastInChrBuf + vChrBufSize; const int16_t **alpSrcPtr= (CONFIG_SWSCALE_ALPHA && alpPixBuf) ? (const int16_t **)(void*) alpPixBuf + lumBufIndex + firstLumSrcY - lastInLumBuf + vLumBufSize : NULL; int i; + + if (firstLumSrcY < 0 || firstLumSrcY + vLumFilterSize > c->srcH) { + const int16_t **tmpY = (const int16_t **) lumPixBuf + 2 * vLumBufSize; + int neg = -firstLumSrcY, i, end = FFMIN(c->srcH - firstLumSrcY, vLumFilterSize); + for (i = 0; i < neg; i++) + tmpY[i] = lumSrcPtr[neg]; + for ( ; i < end; i++) + tmpY[i] = lumSrcPtr[i]; + for ( ; i < vLumFilterSize; i++) + tmpY[i] = tmpY[i-1]; + lumSrcPtr = tmpY; + + if (alpSrcPtr) { + const int16_t **tmpA = (const int16_t **) alpPixBuf + 2 * vLumBufSize; + for (i = 0; i < neg; i++) + tmpA[i] = alpSrcPtr[neg]; + for ( ; i < end; i++) + tmpA[i] = alpSrcPtr[i]; + for ( ; i < vLumFilterSize; i++) + tmpA[i] = tmpA[i - 1]; + alpSrcPtr = tmpA; + } + } + if (firstChrSrcY < 0 || firstChrSrcY + vChrFilterSize > c->chrSrcH) { + const int16_t **tmpU = (const int16_t **) chrUPixBuf + 2 * vChrBufSize; + int neg = -firstChrSrcY, i, end = FFMIN(c->chrSrcH - firstChrSrcY, vChrFilterSize); + for (i = 0; i < neg; i++) { + tmpU[i] = chrUSrcPtr[neg]; + } + for ( ; i < end; i++) { + tmpU[i] = chrUSrcPtr[i]; + } + for ( ; i < vChrFilterSize; i++) { + tmpU[i] = tmpU[i - 1]; + } + chrUSrcPtr = tmpU; + } + if (flags & SWS_ACCURATE_RND) { int s= APCK_SIZE / 8; for (i=0; iredDither), "m" (dummy), "m" (dummy), "m" (dummy), "r" (dest), "m" (dstW_reg), "m"(uv_off) @@ -689,7 +689,7 @@ static void RENAME(yuv2bgr24_X)(SwsContext *c, const int16_t *lumFilter, "pxor %%mm7, %%mm7 \n\t" "lea (%%"REG_a", %%"REG_a", 2), %%"REG_c" \n\t" //FIXME optimize "add %4, %%"REG_c" \n\t" - WRITEBGR24(%%REGc, %5, %%REGa) + WRITEBGR24(%%REGc, "%5", %%REGa) :: "r" (&c->redDither), "m" (dummy), "m" (dummy), "m" (dummy), "r" (dest), "m" (dstW_reg), "m"(uv_off) @@ -710,7 +710,7 @@ static void RENAME(yuv2bgr24_X)(SwsContext *c, const int16_t *lumFilter, MOVNTQ(%%mm7, 8(dst, index, 2))\ \ "add $8, "#index" \n\t"\ - "cmp "#dstw", "#index" \n\t"\ + "cmp "dstw", "#index" \n\t"\ " jb 1b \n\t" #define WRITEYUY2(dst, dstw, index) REAL_WRITEYUY2(dst, dstw, index) @@ -731,7 +731,7 @@ static void RENAME(yuv2yuyv422_X_ar)(SwsContext *c, const int16_t *lumFilter, "psraw $3, %%mm4 \n\t" "psraw $3, %%mm1 \n\t" "psraw $3, %%mm7 \n\t" - WRITEYUY2(%4, %5, %%REGa) + WRITEYUY2(%4, "%5", %%REGa) YSCALEYUV2PACKEDX_END } @@ -752,7 +752,7 @@ static void RENAME(yuv2yuyv422_X)(SwsContext *c, const int16_t *lumFilter, "psraw $3, %%mm4 \n\t" "psraw $3, %%mm1 \n\t" "psraw $3, %%mm7 \n\t" - WRITEYUY2(%4, %5, %%REGa) + WRITEYUY2(%4, "%5", %%REGa) YSCALEYUV2PACKEDX_END } @@ -762,10 +762,10 @@ static void RENAME(yuv2yuyv422_X)(SwsContext *c, const int16_t *lumFilter, "1: \n\t"\ "movq (%2, "#index"), %%mm2 \n\t" /* uvbuf0[eax]*/\ "movq (%3, "#index"), %%mm3 \n\t" /* uvbuf1[eax]*/\ - "add "UV_OFFx2"("#c"), "#index" \n\t" \ + "add "UV_OFF_BYTE"("#c"), "#index" \n\t" \ "movq (%2, "#index"), %%mm5 \n\t" /* uvbuf0[eax+2048]*/\ "movq (%3, "#index"), %%mm4 \n\t" /* uvbuf1[eax+2048]*/\ - "sub "UV_OFFx2"("#c"), "#index" \n\t" \ + "sub "UV_OFF_BYTE"("#c"), "#index" \n\t" \ "psubw %%mm3, %%mm2 \n\t" /* uvbuf0[eax] - uvbuf1[eax]*/\ "psubw %%mm4, %%mm5 \n\t" /* uvbuf0[eax+2048] - uvbuf1[eax+2048]*/\ "movq "CHR_MMX_FILTER_OFFSET"+8("#c"), %%mm0 \n\t"\ @@ -853,7 +853,7 @@ static void RENAME(yuv2rgb32_2)(SwsContext *c, const int16_t *buf[2], "psraw $3, %%mm1 \n\t" /* abuf0[eax] - abuf1[eax] >>7*/ "psraw $3, %%mm7 \n\t" /* abuf0[eax] - abuf1[eax] >>7*/ "packuswb %%mm7, %%mm1 \n\t" - WRITEBGR32(%4, 8280(%5), %%r8, %%mm2, %%mm4, %%mm5, %%mm1, %%mm0, %%mm7, %%mm3, %%mm6) + WRITEBGR32(%4, DSTW_OFFSET"(%5)", %%r8, %%mm2, %%mm4, %%mm5, %%mm1, %%mm0, %%mm7, %%mm3, %%mm6) :: "c" (buf0), "d" (buf1), "S" (ubuf0), "D" (ubuf1), "r" (dest), "a" (&c->redDither), "r" (abuf0), "r" (abuf1) @@ -877,7 +877,7 @@ static void RENAME(yuv2rgb32_2)(SwsContext *c, const int16_t *buf[2], "packuswb %%mm7, %%mm1 \n\t" "pop %1 \n\t" "pop %0 \n\t" - WRITEBGR32(%%REGb, 8280(%5), %%REGBP, %%mm2, %%mm4, %%mm5, %%mm1, %%mm0, %%mm7, %%mm3, %%mm6) + WRITEBGR32(%%REGb, DSTW_OFFSET"(%5)", %%REGBP, %%mm2, %%mm4, %%mm5, %%mm1, %%mm0, %%mm7, %%mm3, %%mm6) "pop %%"REG_BP" \n\t" "mov "ESP_OFFSET"(%5), %%"REG_b" \n\t" :: "c" (buf0), "d" (buf1), "S" (ubuf0), "D" (ubuf1), "m" (dest), @@ -891,7 +891,7 @@ static void RENAME(yuv2rgb32_2)(SwsContext *c, const int16_t *buf[2], "push %%"REG_BP" \n\t" YSCALEYUV2RGB(%%REGBP, %5) "pcmpeqd %%mm7, %%mm7 \n\t" - WRITEBGR32(%%REGb, 8280(%5), %%REGBP, %%mm2, %%mm4, %%mm5, %%mm7, %%mm0, %%mm1, %%mm3, %%mm6) + WRITEBGR32(%%REGb, DSTW_OFFSET"(%5)", %%REGBP, %%mm2, %%mm4, %%mm5, %%mm7, %%mm0, %%mm1, %%mm3, %%mm6) "pop %%"REG_BP" \n\t" "mov "ESP_OFFSET"(%5), %%"REG_b" \n\t" :: "c" (buf0), "d" (buf1), "S" (ubuf0), "D" (ubuf1), "m" (dest), @@ -908,14 +908,13 @@ static void RENAME(yuv2bgr24_2)(SwsContext *c, const int16_t *buf[2], const int16_t *buf0 = buf[0], *buf1 = buf[1], *ubuf0 = ubuf[0], *ubuf1 = ubuf[1]; - //Note 8280 == DSTW_OFFSET but the preprocessor can't handle that there :( __asm__ volatile( "mov %%"REG_b", "ESP_OFFSET"(%5) \n\t" "mov %4, %%"REG_b" \n\t" "push %%"REG_BP" \n\t" YSCALEYUV2RGB(%%REGBP, %5) "pxor %%mm7, %%mm7 \n\t" - WRITEBGR24(%%REGb, 8280(%5), %%REGBP) + WRITEBGR24(%%REGb, DSTW_OFFSET"(%5)", %%REGBP) "pop %%"REG_BP" \n\t" "mov "ESP_OFFSET"(%5), %%"REG_b" \n\t" :: "c" (buf0), "d" (buf1), "S" (ubuf0), "D" (ubuf1), "m" (dest), @@ -931,7 +930,6 @@ static void RENAME(yuv2rgb555_2)(SwsContext *c, const int16_t *buf[2], const int16_t *buf0 = buf[0], *buf1 = buf[1], *ubuf0 = ubuf[0], *ubuf1 = ubuf[1]; - //Note 8280 == DSTW_OFFSET but the preprocessor can't handle that there :( __asm__ volatile( "mov %%"REG_b", "ESP_OFFSET"(%5) \n\t" "mov %4, %%"REG_b" \n\t" @@ -944,7 +942,7 @@ static void RENAME(yuv2rgb555_2)(SwsContext *c, const int16_t *buf[2], "paddusb "GREEN_DITHER"(%5), %%mm4 \n\t" "paddusb "RED_DITHER"(%5), %%mm5 \n\t" #endif - WRITERGB15(%%REGb, 8280(%5), %%REGBP) + WRITERGB15(%%REGb, DSTW_OFFSET"(%5)", %%REGBP) "pop %%"REG_BP" \n\t" "mov "ESP_OFFSET"(%5), %%"REG_b" \n\t" :: "c" (buf0), "d" (buf1), "S" (ubuf0), "D" (ubuf1), "m" (dest), @@ -960,7 +958,6 @@ static void RENAME(yuv2rgb565_2)(SwsContext *c, const int16_t *buf[2], const int16_t *buf0 = buf[0], *buf1 = buf[1], *ubuf0 = ubuf[0], *ubuf1 = ubuf[1]; - //Note 8280 == DSTW_OFFSET but the preprocessor can't handle that there :( __asm__ volatile( "mov %%"REG_b", "ESP_OFFSET"(%5) \n\t" "mov %4, %%"REG_b" \n\t" @@ -973,7 +970,7 @@ static void RENAME(yuv2rgb565_2)(SwsContext *c, const int16_t *buf[2], "paddusb "GREEN_DITHER"(%5), %%mm4 \n\t" "paddusb "RED_DITHER"(%5), %%mm5 \n\t" #endif - WRITERGB16(%%REGb, 8280(%5), %%REGBP) + WRITERGB16(%%REGb, DSTW_OFFSET"(%5)", %%REGBP) "pop %%"REG_BP" \n\t" "mov "ESP_OFFSET"(%5), %%"REG_b" \n\t" :: "c" (buf0), "d" (buf1), "S" (ubuf0), "D" (ubuf1), "m" (dest), @@ -993,10 +990,10 @@ static void RENAME(yuv2rgb565_2)(SwsContext *c, const int16_t *buf[2], "1: \n\t"\ "movq (%2, "#index"), %%mm2 \n\t" /* uvbuf0[eax]*/\ "movq (%3, "#index"), %%mm3 \n\t" /* uvbuf1[eax]*/\ - "add "UV_OFFx2"("#c"), "#index" \n\t" \ + "add "UV_OFF_BYTE"("#c"), "#index" \n\t" \ "movq (%2, "#index"), %%mm5 \n\t" /* uvbuf0[eax+2048]*/\ "movq (%3, "#index"), %%mm4 \n\t" /* uvbuf1[eax+2048]*/\ - "sub "UV_OFFx2"("#c"), "#index" \n\t" \ + "sub "UV_OFF_BYTE"("#c"), "#index" \n\t" \ "psubw %%mm3, %%mm2 \n\t" /* uvbuf0[eax] - uvbuf1[eax]*/\ "psubw %%mm4, %%mm5 \n\t" /* uvbuf0[eax+2048] - uvbuf1[eax+2048]*/\ "movq "CHR_MMX_FILTER_OFFSET"+8("#c"), %%mm0 \n\t"\ @@ -1029,13 +1026,12 @@ static void RENAME(yuv2yuyv422_2)(SwsContext *c, const int16_t *buf[2], const int16_t *buf0 = buf[0], *buf1 = buf[1], *ubuf0 = ubuf[0], *ubuf1 = ubuf[1]; - //Note 8280 == DSTW_OFFSET but the preprocessor can't handle that there :( __asm__ volatile( "mov %%"REG_b", "ESP_OFFSET"(%5) \n\t" "mov %4, %%"REG_b" \n\t" "push %%"REG_BP" \n\t" YSCALEYUV2PACKED(%%REGBP, %5) - WRITEYUY2(%%REGb, 8280(%5), %%REGBP) + WRITEYUY2(%%REGb, DSTW_OFFSET"(%5)", %%REGBP) "pop %%"REG_BP" \n\t" "mov "ESP_OFFSET"(%5), %%"REG_b" \n\t" :: "c" (buf0), "d" (buf1), "S" (ubuf0), "D" (ubuf1), "m" (dest), @@ -1048,9 +1044,9 @@ static void RENAME(yuv2yuyv422_2)(SwsContext *c, const int16_t *buf[2], ".p2align 4 \n\t"\ "1: \n\t"\ "movq (%2, "#index"), %%mm3 \n\t" /* uvbuf0[eax]*/\ - "add "UV_OFFx2"("#c"), "#index" \n\t" \ + "add "UV_OFF_BYTE"("#c"), "#index" \n\t" \ "movq (%2, "#index"), %%mm4 \n\t" /* uvbuf0[eax+2048]*/\ - "sub "UV_OFFx2"("#c"), "#index" \n\t" \ + "sub "UV_OFF_BYTE"("#c"), "#index" \n\t" \ "psraw $4, %%mm3 \n\t" /* uvbuf0[eax] - uvbuf1[eax] >>4*/\ "psraw $4, %%mm4 \n\t" /* uvbuf0[eax+2048] - uvbuf1[eax+2048] >>4*/\ "psubw "U_OFFSET"("#c"), %%mm3 \n\t" /* (U-128)8*/\ @@ -1101,10 +1097,10 @@ static void RENAME(yuv2yuyv422_2)(SwsContext *c, const int16_t *buf[2], "1: \n\t"\ "movq (%2, "#index"), %%mm2 \n\t" /* uvbuf0[eax]*/\ "movq (%3, "#index"), %%mm3 \n\t" /* uvbuf1[eax]*/\ - "add "UV_OFFx2"("#c"), "#index" \n\t" \ + "add "UV_OFF_BYTE"("#c"), "#index" \n\t" \ "movq (%2, "#index"), %%mm5 \n\t" /* uvbuf0[eax+2048]*/\ "movq (%3, "#index"), %%mm4 \n\t" /* uvbuf1[eax+2048]*/\ - "sub "UV_OFFx2"("#c"), "#index" \n\t" \ + "sub "UV_OFF_BYTE"("#c"), "#index" \n\t" \ "paddw %%mm2, %%mm3 \n\t" /* uvbuf0[eax] + uvbuf1[eax]*/\ "paddw %%mm5, %%mm4 \n\t" /* uvbuf0[eax+2048] + uvbuf1[eax+2048]*/\ "psrlw $5, %%mm3 \n\t" /*FIXME might overflow*/\ @@ -1177,7 +1173,7 @@ static void RENAME(yuv2rgb32_1)(SwsContext *c, const int16_t *buf0, "push %%"REG_BP" \n\t" YSCALEYUV2RGB1(%%REGBP, %5) YSCALEYUV2RGB1_ALPHA(%%REGBP) - WRITEBGR32(%%REGb, 8280(%5), %%REGBP, %%mm2, %%mm4, %%mm5, %%mm7, %%mm0, %%mm1, %%mm3, %%mm6) + WRITEBGR32(%%REGb, DSTW_OFFSET"(%5)", %%REGBP, %%mm2, %%mm4, %%mm5, %%mm7, %%mm0, %%mm1, %%mm3, %%mm6) "pop %%"REG_BP" \n\t" "mov "ESP_OFFSET"(%5), %%"REG_b" \n\t" :: "c" (buf0), "d" (abuf0), "S" (ubuf0), "D" (ubuf1), "m" (dest), @@ -1190,7 +1186,7 @@ static void RENAME(yuv2rgb32_1)(SwsContext *c, const int16_t *buf0, "push %%"REG_BP" \n\t" YSCALEYUV2RGB1(%%REGBP, %5) "pcmpeqd %%mm7, %%mm7 \n\t" - WRITEBGR32(%%REGb, 8280(%5), %%REGBP, %%mm2, %%mm4, %%mm5, %%mm7, %%mm0, %%mm1, %%mm3, %%mm6) + WRITEBGR32(%%REGb, DSTW_OFFSET"(%5)", %%REGBP, %%mm2, %%mm4, %%mm5, %%mm7, %%mm0, %%mm1, %%mm3, %%mm6) "pop %%"REG_BP" \n\t" "mov "ESP_OFFSET"(%5), %%"REG_b" \n\t" :: "c" (buf0), "d" (buf1), "S" (ubuf0), "D" (ubuf1), "m" (dest), @@ -1205,7 +1201,7 @@ static void RENAME(yuv2rgb32_1)(SwsContext *c, const int16_t *buf0, "push %%"REG_BP" \n\t" YSCALEYUV2RGB1b(%%REGBP, %5) YSCALEYUV2RGB1_ALPHA(%%REGBP) - WRITEBGR32(%%REGb, 8280(%5), %%REGBP, %%mm2, %%mm4, %%mm5, %%mm7, %%mm0, %%mm1, %%mm3, %%mm6) + WRITEBGR32(%%REGb, DSTW_OFFSET"(%5)", %%REGBP, %%mm2, %%mm4, %%mm5, %%mm7, %%mm0, %%mm1, %%mm3, %%mm6) "pop %%"REG_BP" \n\t" "mov "ESP_OFFSET"(%5), %%"REG_b" \n\t" :: "c" (buf0), "d" (abuf0), "S" (ubuf0), "D" (ubuf1), "m" (dest), @@ -1218,7 +1214,7 @@ static void RENAME(yuv2rgb32_1)(SwsContext *c, const int16_t *buf0, "push %%"REG_BP" \n\t" YSCALEYUV2RGB1b(%%REGBP, %5) "pcmpeqd %%mm7, %%mm7 \n\t" - WRITEBGR32(%%REGb, 8280(%5), %%REGBP, %%mm2, %%mm4, %%mm5, %%mm7, %%mm0, %%mm1, %%mm3, %%mm6) + WRITEBGR32(%%REGb, DSTW_OFFSET"(%5)", %%REGBP, %%mm2, %%mm4, %%mm5, %%mm7, %%mm0, %%mm1, %%mm3, %%mm6) "pop %%"REG_BP" \n\t" "mov "ESP_OFFSET"(%5), %%"REG_b" \n\t" :: "c" (buf0), "d" (buf1), "S" (ubuf0), "D" (ubuf1), "m" (dest), @@ -1243,7 +1239,7 @@ static void RENAME(yuv2bgr24_1)(SwsContext *c, const int16_t *buf0, "push %%"REG_BP" \n\t" YSCALEYUV2RGB1(%%REGBP, %5) "pxor %%mm7, %%mm7 \n\t" - WRITEBGR24(%%REGb, 8280(%5), %%REGBP) + WRITEBGR24(%%REGb, DSTW_OFFSET"(%5)", %%REGBP) "pop %%"REG_BP" \n\t" "mov "ESP_OFFSET"(%5), %%"REG_b" \n\t" :: "c" (buf0), "d" (buf1), "S" (ubuf0), "D" (ubuf1), "m" (dest), @@ -1256,7 +1252,7 @@ static void RENAME(yuv2bgr24_1)(SwsContext *c, const int16_t *buf0, "push %%"REG_BP" \n\t" YSCALEYUV2RGB1b(%%REGBP, %5) "pxor %%mm7, %%mm7 \n\t" - WRITEBGR24(%%REGb, 8280(%5), %%REGBP) + WRITEBGR24(%%REGb, DSTW_OFFSET"(%5)", %%REGBP) "pop %%"REG_BP" \n\t" "mov "ESP_OFFSET"(%5), %%"REG_b" \n\t" :: "c" (buf0), "d" (buf1), "S" (ubuf0), "D" (ubuf1), "m" (dest), @@ -1286,7 +1282,7 @@ static void RENAME(yuv2rgb555_1)(SwsContext *c, const int16_t *buf0, "paddusb "GREEN_DITHER"(%5), %%mm4 \n\t" "paddusb "RED_DITHER"(%5), %%mm5 \n\t" #endif - WRITERGB15(%%REGb, 8280(%5), %%REGBP) + WRITERGB15(%%REGb, DSTW_OFFSET"(%5)", %%REGBP) "pop %%"REG_BP" \n\t" "mov "ESP_OFFSET"(%5), %%"REG_b" \n\t" :: "c" (buf0), "d" (buf1), "S" (ubuf0), "D" (ubuf1), "m" (dest), @@ -1305,7 +1301,7 @@ static void RENAME(yuv2rgb555_1)(SwsContext *c, const int16_t *buf0, "paddusb "GREEN_DITHER"(%5), %%mm4 \n\t" "paddusb "RED_DITHER"(%5), %%mm5 \n\t" #endif - WRITERGB15(%%REGb, 8280(%5), %%REGBP) + WRITERGB15(%%REGb, DSTW_OFFSET"(%5)", %%REGBP) "pop %%"REG_BP" \n\t" "mov "ESP_OFFSET"(%5), %%"REG_b" \n\t" :: "c" (buf0), "d" (buf1), "S" (ubuf0), "D" (ubuf1), "m" (dest), @@ -1335,7 +1331,7 @@ static void RENAME(yuv2rgb565_1)(SwsContext *c, const int16_t *buf0, "paddusb "GREEN_DITHER"(%5), %%mm4 \n\t" "paddusb "RED_DITHER"(%5), %%mm5 \n\t" #endif - WRITERGB16(%%REGb, 8280(%5), %%REGBP) + WRITERGB16(%%REGb, DSTW_OFFSET"(%5)", %%REGBP) "pop %%"REG_BP" \n\t" "mov "ESP_OFFSET"(%5), %%"REG_b" \n\t" :: "c" (buf0), "d" (buf1), "S" (ubuf0), "D" (ubuf1), "m" (dest), @@ -1354,7 +1350,7 @@ static void RENAME(yuv2rgb565_1)(SwsContext *c, const int16_t *buf0, "paddusb "GREEN_DITHER"(%5), %%mm4 \n\t" "paddusb "RED_DITHER"(%5), %%mm5 \n\t" #endif - WRITERGB16(%%REGb, 8280(%5), %%REGBP) + WRITERGB16(%%REGb, DSTW_OFFSET"(%5)", %%REGBP) "pop %%"REG_BP" \n\t" "mov "ESP_OFFSET"(%5), %%"REG_b" \n\t" :: "c" (buf0), "d" (buf1), "S" (ubuf0), "D" (ubuf1), "m" (dest), @@ -1368,9 +1364,9 @@ static void RENAME(yuv2rgb565_1)(SwsContext *c, const int16_t *buf0, ".p2align 4 \n\t"\ "1: \n\t"\ "movq (%2, "#index"), %%mm3 \n\t" /* uvbuf0[eax]*/\ - "add "UV_OFFx2"("#c"), "#index" \n\t" \ + "add "UV_OFF_BYTE"("#c"), "#index" \n\t" \ "movq (%2, "#index"), %%mm4 \n\t" /* uvbuf0[eax+2048]*/\ - "sub "UV_OFFx2"("#c"), "#index" \n\t" \ + "sub "UV_OFF_BYTE"("#c"), "#index" \n\t" \ "psraw $7, %%mm3 \n\t" \ "psraw $7, %%mm4 \n\t" \ "movq (%0, "#index", 2), %%mm1 \n\t" /*buf0[eax]*/\ @@ -1386,10 +1382,10 @@ static void RENAME(yuv2rgb565_1)(SwsContext *c, const int16_t *buf0, "1: \n\t"\ "movq (%2, "#index"), %%mm2 \n\t" /* uvbuf0[eax]*/\ "movq (%3, "#index"), %%mm3 \n\t" /* uvbuf1[eax]*/\ - "add "UV_OFFx2"("#c"), "#index" \n\t" \ + "add "UV_OFF_BYTE"("#c"), "#index" \n\t" \ "movq (%2, "#index"), %%mm5 \n\t" /* uvbuf0[eax+2048]*/\ "movq (%3, "#index"), %%mm4 \n\t" /* uvbuf1[eax+2048]*/\ - "sub "UV_OFFx2"("#c"), "#index" \n\t" \ + "sub "UV_OFF_BYTE"("#c"), "#index" \n\t" \ "paddw %%mm2, %%mm3 \n\t" /* uvbuf0[eax] + uvbuf1[eax]*/\ "paddw %%mm5, %%mm4 \n\t" /* uvbuf0[eax+2048] + uvbuf1[eax+2048]*/\ "psrlw $8, %%mm3 \n\t" \ @@ -1414,7 +1410,7 @@ static void RENAME(yuv2yuyv422_1)(SwsContext *c, const int16_t *buf0, "mov %4, %%"REG_b" \n\t" "push %%"REG_BP" \n\t" YSCALEYUV2PACKED1(%%REGBP, %5) - WRITEYUY2(%%REGb, 8280(%5), %%REGBP) + WRITEYUY2(%%REGb, DSTW_OFFSET"(%5)", %%REGBP) "pop %%"REG_BP" \n\t" "mov "ESP_OFFSET"(%5), %%"REG_b" \n\t" :: "c" (buf0), "d" (buf1), "S" (ubuf0), "D" (ubuf1), "m" (dest), @@ -1426,7 +1422,7 @@ static void RENAME(yuv2yuyv422_1)(SwsContext *c, const int16_t *buf0, "mov %4, %%"REG_b" \n\t" "push %%"REG_BP" \n\t" YSCALEYUV2PACKED1b(%%REGBP, %5) - WRITEYUY2(%%REGb, 8280(%5), %%REGBP) + WRITEYUY2(%%REGb, DSTW_OFFSET"(%5)", %%REGBP) "pop %%"REG_BP" \n\t" "mov "ESP_OFFSET"(%5), %%"REG_b" \n\t" :: "c" (buf0), "d" (buf1), "S" (ubuf0), "D" (ubuf1), "m" (dest), @@ -1579,7 +1575,7 @@ static void RENAME(hyscale_fast)(SwsContext *c, int16_t *dst, int dstWidth, const uint8_t *src, int srcW, int xInc) { - int16_t *filterPos = c->hLumFilterPos; + int32_t *filterPos = c->hLumFilterPos; int16_t *filter = c->hLumFilter; void *mmx2FilterCode= c->lumMmx2FilterCode; int i; @@ -1675,7 +1671,7 @@ static void RENAME(hcscale_fast)(SwsContext *c, int16_t *dst1, int16_t *dst2, int dstWidth, const uint8_t *src1, const uint8_t *src2, int srcW, int xInc) { - int16_t *filterPos = c->hChrFilterPos; + int32_t *filterPos = c->hChrFilterPos; int16_t *filter = c->hChrFilter; void *mmx2FilterCode= c->chrMmx2FilterCode; int i; diff --git a/tests/ref/acodec/adpcm_ima_qt b/tests/ref/acodec/adpcm_ima_qt index c1db43f1aa..a50c30a27c 100644 --- a/tests/ref/acodec/adpcm_ima_qt +++ b/tests/ref/acodec/adpcm_ima_qt @@ -1,4 +1,4 @@ -057d27978b35888776512e4e9669a63b *./tests/data/acodec/adpcm_qt.aiff +23cbae1182e150ebf28e0abfb9cba127 *./tests/data/acodec/adpcm_qt.aiff 281252 ./tests/data/acodec/adpcm_qt.aiff -169c40435c68d50112c9c61fc67e446d *./tests/data/adpcm_ima_qt.acodec.out.wav -stddev: 918.61 PSNR: 37.07 MAXDIFF:34029 bytes: 1058560/ 1058400 +b0fafd002c38fb70acaddfda1a31ed61 *./tests/data/adpcm_ima_qt.acodec.out.wav +stddev: 904.76 PSNR: 37.20 MAXDIFF:34029 bytes: 1058560/ 1058400 diff --git a/tests/ref/acodec/g722 b/tests/ref/acodec/g722 index 67e4442a86..1e766d8455 100644 --- a/tests/ref/acodec/g722 +++ b/tests/ref/acodec/g722 @@ -1,4 +1,4 @@ -b813a52d4efe6cf7974190ea9c4c7e8c *./tests/data/acodec/g722.wav +d1a10c4d35f752f60798114a156be3a8 *./tests/data/acodec/g722.wav 48053 ./tests/data/acodec/g722.wav -d8344d14a11eef0418b856af70694cbe *./tests/data/g722.acodec.out.wav -stddev: 8841.18 PSNR: 17.40 MAXDIFF:36225 bytes: 191980/ 1058400 +8dafe5b74ccd5f08fed2fb2a69c5475f *./tests/data/g722.acodec.out.wav +stddev: 8939.47 PSNR: 17.30 MAXDIFF:40370 bytes: 191980/ 1058400 diff --git a/tests/ref/acodec/pcm_alaw b/tests/ref/acodec/pcm_alaw index 4943831d39..0eba43a0c4 100644 --- a/tests/ref/acodec/pcm_alaw +++ b/tests/ref/acodec/pcm_alaw @@ -1,4 +1,4 @@ -ede2da07839a00c255a43129922f2c7b *./tests/data/acodec/pcm_alaw.wav +a2dd6a934ec6d5ec901a211652e85227 *./tests/data/acodec/pcm_alaw.wav 529258 ./tests/data/acodec/pcm_alaw.wav f323f7551ffad91de8613f44dcb198b6 *./tests/data/pcm_alaw.acodec.out.wav stddev: 101.67 PSNR: 56.19 MAXDIFF: 515 bytes: 1058400/ 1058400 diff --git a/tests/ref/acodec/pcm_mulaw b/tests/ref/acodec/pcm_mulaw index cefd76ba49..e1abcbe60c 100644 --- a/tests/ref/acodec/pcm_mulaw +++ b/tests/ref/acodec/pcm_mulaw @@ -1,4 +1,4 @@ -0c2a55850fb46ad5385a69b15b271f10 *./tests/data/acodec/pcm_mulaw.wav +fd10ee54bd298fc29fd6fc70baa71414 *./tests/data/acodec/pcm_mulaw.wav 529258 ./tests/data/acodec/pcm_mulaw.wav 7ae8c3fc804bd574006fd547fe28980c *./tests/data/pcm_mulaw.acodec.out.wav stddev: 103.38 PSNR: 56.04 MAXDIFF: 644 bytes: 1058400/ 1058400 diff --git a/tests/ref/acodec/wmav1 b/tests/ref/acodec/wmav1 index 916e4a8ab6..117aa12a8c 100644 --- a/tests/ref/acodec/wmav1 +++ b/tests/ref/acodec/wmav1 @@ -1,4 +1,4 @@ -26a7f6b0f0b7181df8df3fa589f6bf81 *./tests/data/acodec/wmav1.asf +0260385b8a54df11ad349f9ba8240fd8 *./tests/data/acodec/wmav1.asf 106004 ./tests/data/acodec/wmav1.asf -stddev:12245.52 PSNR: 14.57 MAXDIFF:65521 bytes: 1064960/ 1058400 -stddev: 2095.89 PSNR: 29.90 MAXDIFF:27658 bytes: 1056768/ 1058400 +stddev:12241.90 PSNR: 14.57 MAXDIFF:65521 bytes: 1064960/ 1058400 +stddev: 2074.79 PSNR: 29.99 MAXDIFF:27658 bytes: 1056768/ 1058400 diff --git a/tests/ref/acodec/wmav2 b/tests/ref/acodec/wmav2 index 622b6fcc36..43b19b7530 100644 --- a/tests/ref/acodec/wmav2 +++ b/tests/ref/acodec/wmav2 @@ -1,4 +1,4 @@ -7c6c0cb692af01b312ae345723674b5f *./tests/data/acodec/wmav2.asf +bdb4c312fb109f990be83a70f8ec9bdc *./tests/data/acodec/wmav2.asf 106044 ./tests/data/acodec/wmav2.asf -stddev:12249.93 PSNR: 14.57 MAXDIFF:65521 bytes: 1064960/ 1058400 -stddev: 2089.21 PSNR: 29.93 MAXDIFF:27650 bytes: 1056768/ 1058400 +stddev:12246.35 PSNR: 14.57 MAXDIFF:65521 bytes: 1064960/ 1058400 +stddev: 2068.08 PSNR: 30.02 MAXDIFF:27650 bytes: 1056768/ 1058400 diff --git a/tests/ref/fate/eval b/tests/ref/fate/eval index 09e310f25d..6122aacf48 100644 --- a/tests/ref/fate/eval +++ b/tests/ref/fate/eval @@ -95,16 +95,16 @@ Evaluating 'st(1, 123); ld(1)' 'st(1, 123); ld(1)' -> 123.000000 Evaluating 'st(0, 1); while(lte(ld(0), 100), st(1, ld(1)+ld(0));st(0, ld(0)+1)); ld(1)' -'st(0, 1); while(lte(ld(0), 100), st(1, ld(1)+ld(0));st(0, ld(0)+1)); ld(1)' -> 4950.000000 +'st(0, 1); while(lte(ld(0), 100), st(1, ld(1)+ld(0));st(0, ld(0)+1)); ld(1)' -> 5050.000000 Evaluating 'st(1, 1); st(2, 2); st(0, 1); while(lte(ld(0),10), st(3, ld(1)+ld(2)); st(1, ld(2)); st(2, ld(3)); st(0, ld(0)+1)); ld(3)' -'st(1, 1); st(2, 2); st(0, 1); while(lte(ld(0),10), st(3, ld(1)+ld(2)); st(1, ld(2)); st(2, ld(3)); st(0, ld(0)+1)); ld(3)' -> 144.000000 +'st(1, 1); st(2, 2); st(0, 1); while(lte(ld(0),10), st(3, ld(1)+ld(2)); st(1, ld(2)); st(2, ld(3)); st(0, ld(0)+1)); ld(3)' -> 233.000000 Evaluating 'while(0, 10)' 'while(0, 10)' -> nan Evaluating 'st(0, 1); while(lte(ld(0),100), st(1, ld(1)+ld(0)); st(0, ld(0)+1))' -'st(0, 1); while(lte(ld(0),100), st(1, ld(1)+ld(0)); st(0, ld(0)+1))' -> 100.000000 +'st(0, 1); while(lte(ld(0),100), st(1, ld(1)+ld(0)); st(0, ld(0)+1))' -> 101.000000 Evaluating 'isnan(1)' 'isnan(1)' -> 0.000000 diff --git a/tests/ref/fate/g722dec-1 b/tests/ref/fate/g722dec-1 index 4c4b2b53e7..cdc54891c8 100644 --- a/tests/ref/fate/g722dec-1 +++ b/tests/ref/fate/g722dec-1 @@ -1,167 +1,167 @@ -0, 0, 4096, 0xde68394d -0, 11520, 4096, 0xa5c28cb7 -0, 23040, 4096, 0x2e3c2f23 -0, 34560, 4096, 0xd7757825 -0, 46080, 4096, 0xafd1fd61 -0, 57600, 4096, 0x686afcbe -0, 69120, 4096, 0x2290e848 -0, 80640, 4096, 0xddd484ad -0, 92160, 4096, 0x148811a6 -0, 103680, 4096, 0x8b965613 -0, 115200, 4096, 0x8b095d51 -0, 126720, 4096, 0xf7625485 -0, 138240, 4096, 0x982a688c -0, 149760, 4096, 0xc290dcfc -0, 161280, 4096, 0x8bdef225 -0, 172800, 4096, 0xfca27fdc -0, 184320, 4096, 0x95eff313 -0, 195840, 4096, 0x691ed4f7 -0, 207360, 4096, 0xd7e7b492 -0, 218880, 4096, 0xb0416bfe -0, 230400, 4096, 0xf94b3ebd -0, 241920, 4096, 0x7f73ca12 -0, 253440, 4096, 0xe91da4a3 -0, 264960, 4096, 0x1f74dc0e -0, 276480, 4096, 0xd95b35e8 -0, 288000, 4096, 0x6dcdde1a -0, 299520, 4096, 0x614fd4e4 -0, 311040, 4096, 0xe38d0fd5 -0, 322560, 4096, 0xfeba2999 -0, 334080, 4096, 0x1bf541e1 -0, 345600, 4096, 0x689f50d8 -0, 357120, 4096, 0x0aa60f5f -0, 368640, 4096, 0x60ac3116 -0, 380160, 4096, 0xfa60e5e6 -0, 391680, 4096, 0xc7207c5b -0, 403200, 4096, 0x01196277 -0, 414720, 4096, 0x609ca46c -0, 426240, 4096, 0xfb799142 -0, 437760, 4096, 0x720910df -0, 449280, 4096, 0xe21a8662 -0, 460800, 4096, 0x07105120 -0, 472320, 4096, 0x593f627e -0, 483840, 4096, 0x28ddc80c -0, 495360, 4096, 0xc69ef356 -0, 506880, 4096, 0x2defc5bd -0, 518400, 4096, 0x82a4f418 -0, 529920, 4096, 0x424cb997 -0, 541440, 4096, 0x167a49b7 -0, 552960, 4096, 0x32a3e0d4 -0, 564480, 4096, 0x08a353ae -0, 576000, 4096, 0x9543577b -0, 587520, 4096, 0x2ed137cf -0, 599040, 4096, 0xd80b0538 -0, 610560, 4096, 0x2ad31bef -0, 622080, 4096, 0x1060cff8 -0, 633600, 4096, 0x76ab5ab8 -0, 645120, 4096, 0x8eedb68d -0, 656640, 4096, 0xf4e2dc46 -0, 668160, 4096, 0xc52d3326 -0, 679680, 4096, 0x25201a26 -0, 691200, 4096, 0x16419378 -0, 702720, 4096, 0x97061f3c -0, 714240, 4096, 0xd54edecd -0, 725760, 4096, 0xc830b07b -0, 737280, 4096, 0x804bae00 -0, 748800, 4096, 0xbb279150 -0, 760320, 4096, 0x95c4d5aa -0, 771840, 4096, 0xc51d5259 -0, 783360, 4096, 0x856e1ab0 -0, 794880, 4096, 0x9e6ccb12 -0, 806400, 4096, 0xa2e5c1bb -0, 817920, 4096, 0xe62fb62f -0, 829440, 4096, 0xf10e3df0 -0, 840960, 4096, 0x76def18b -0, 852480, 4096, 0xc9c3a26d -0, 864000, 4096, 0x8ec0e061 -0, 875520, 4096, 0x3d4e8512 -0, 887040, 4096, 0xec45cd46 -0, 898560, 4096, 0xa34f3ddf -0, 910080, 4096, 0x52b81c53 -0, 921600, 4096, 0xd0f0397a -0, 933120, 4096, 0x7c0de231 -0, 944640, 4096, 0xfe86c032 -0, 956160, 4096, 0x67cdb848 -0, 967680, 4096, 0x90532cc0 -0, 979200, 4096, 0x03bca9e9 -0, 990720, 4096, 0x73169fd1 -0, 1002240, 4096, 0x0b93967d -0, 1013760, 4096, 0x6486d8be -0, 1025280, 4096, 0x555cc2ac -0, 1036800, 4096, 0x07c1912e -0, 1048320, 4096, 0xe0423c66 -0, 1059840, 4096, 0xc12d0fa1 -0, 1071360, 4096, 0xdf497c2f -0, 1082880, 4096, 0x9298d1ba -0, 1094400, 4096, 0x691a4e15 -0, 1105920, 4096, 0x725adc6e -0, 1117440, 4096, 0xf68e88de -0, 1128960, 4096, 0x37a234aa -0, 1140480, 4096, 0x43fb0558 -0, 1152000, 4096, 0x653e4320 -0, 1163520, 4096, 0x651e2f13 -0, 1175040, 4096, 0x179049f9 -0, 1186560, 4096, 0xe02fbb9d -0, 1198080, 4096, 0xb7e9f2a0 -0, 1209600, 4096, 0x94ee81df -0, 1221120, 4096, 0x398a98de -0, 1232640, 4096, 0x1267594a -0, 1244160, 4096, 0x715adbaf -0, 1255680, 4096, 0x28ce1a20 -0, 1267200, 4096, 0x4f8073d0 -0, 1278720, 4096, 0x536846d3 -0, 1290240, 4096, 0x7dc7defe -0, 1301760, 4096, 0x08a28e2a -0, 1313280, 4096, 0xd717c5cd -0, 1324800, 4096, 0x5d6e1efd -0, 1336320, 4096, 0x4d0eea27 -0, 1347840, 4096, 0x70fff90c -0, 1359360, 4096, 0xd5cc8207 -0, 1370880, 4096, 0xf87cae0e -0, 1382400, 4096, 0x26814ab5 -0, 1393920, 4096, 0x9569fb8d -0, 1405440, 4096, 0x7835122e -0, 1416960, 4096, 0xa38840dd -0, 1428480, 4096, 0xfc499ba3 -0, 1440000, 4096, 0x0aa60cb0 -0, 1451520, 4096, 0x530ef56e -0, 1463040, 4096, 0xead968db -0, 1474560, 4096, 0x64484214 -0, 1486080, 4096, 0xfd0cc89e -0, 1497600, 4096, 0x0d452a5d -0, 1509120, 4096, 0x36ef8482 -0, 1520640, 4096, 0x462b641b -0, 1532160, 4096, 0x2a5c1c0c -0, 1543680, 4096, 0x8837ff80 -0, 1555200, 4096, 0x27a3de22 -0, 1566720, 4096, 0xf88d28c1 -0, 1578240, 4096, 0xed85ea97 -0, 1589760, 4096, 0x50c3e7db -0, 1601280, 4096, 0x82bcb480 -0, 1612800, 4096, 0xc50ee536 -0, 1624320, 4096, 0x086280ee -0, 1635840, 4096, 0x6f18f2b2 -0, 1647360, 4096, 0x1c7c0856 -0, 1658880, 4096, 0xc576268a -0, 1670400, 4096, 0x7a9af56d -0, 1681920, 4096, 0x6d058fc5 -0, 1693440, 4096, 0x8fb1107b -0, 1704960, 4096, 0x807588d1 -0, 1716480, 4096, 0x56178443 -0, 1728000, 4096, 0xf2460763 -0, 1739520, 4096, 0x284255f2 -0, 1751040, 4096, 0xb29d17fb -0, 1762560, 4096, 0x5e7e4633 -0, 1774080, 4096, 0x57704db1 -0, 1785600, 4096, 0xd87dcc1d -0, 1797120, 4096, 0x28d4bb93 -0, 1808640, 4096, 0x3a2e5c6c -0, 1820160, 4096, 0xf3581656 -0, 1831680, 4096, 0x42f1942f -0, 1843200, 4096, 0xe75c5092 -0, 1854720, 4096, 0x3fae7f6d -0, 1866240, 4096, 0xf99ad73e -0, 1877760, 4096, 0x80564e3e -0, 1889280, 4096, 0x8ff6ebe5 -0, 1900800, 4096, 0x436d5e69 -0, 1912320, 1368, 0xe0ebeda3 +0, 0, 4096, 0x4f9228b3 +0, 11520, 4096, 0xfab58157 +0, 23040, 4096, 0x0b641c78 +0, 34560, 4096, 0x601c6803 +0, 46080, 4096, 0xb3e2f166 +0, 57600, 4096, 0x5681f206 +0, 69120, 4096, 0x1e69e71f +0, 80640, 4096, 0x05628be3 +0, 92160, 4096, 0x109b1aef +0, 103680, 4096, 0xd5435a9e +0, 115200, 4096, 0xb38b5d28 +0, 126720, 4096, 0x64514c93 +0, 138240, 4096, 0x453350e7 +0, 149760, 4096, 0x6deccce6 +0, 161280, 4096, 0xd427ede1 +0, 172800, 4096, 0xdecb8c42 +0, 184320, 4096, 0x3841e4d2 +0, 195840, 4096, 0x858ac1b1 +0, 207360, 4096, 0x8e9dbfa0 +0, 218880, 4096, 0xcbc0766f +0, 230400, 4096, 0x78d52555 +0, 241920, 4096, 0x600ac7d5 +0, 253440, 4096, 0xafadb7ee +0, 264960, 4096, 0x8009d5a1 +0, 276480, 4096, 0xb07d475e +0, 288000, 4096, 0xfcfecceb +0, 299520, 4096, 0x38b5d85f +0, 311040, 4096, 0xbd48072e +0, 322560, 4096, 0xd04724d8 +0, 334080, 4096, 0x08425144 +0, 345600, 4096, 0x7b14483e +0, 357120, 4096, 0x8858ef4c +0, 368640, 4096, 0x1e3024c2 +0, 380160, 4096, 0xcd6bfe4f +0, 391680, 4096, 0x8cde8d18 +0, 403200, 4096, 0xbbd856b8 +0, 414720, 4096, 0x988c9b7a +0, 426240, 4096, 0x2a858e03 +0, 437760, 4096, 0x6dee1e4a +0, 449280, 4096, 0x8cc38b41 +0, 460800, 4096, 0x48bd5cec +0, 472320, 4096, 0xeb7f606b +0, 483840, 4096, 0x75f5d28c +0, 495360, 4096, 0x5bfeec4b +0, 506880, 4096, 0xfc35c22a +0, 518400, 4096, 0x3a95efba +0, 529920, 4096, 0xefdbce9c +0, 541440, 4096, 0x00594ada +0, 552960, 4096, 0x20ffebfa +0, 564480, 4096, 0x1b31370a +0, 576000, 4096, 0x50766a56 +0, 587520, 4096, 0x0058315a +0, 599040, 4096, 0x98090cbf +0, 610560, 4096, 0x66ed2d40 +0, 622080, 4096, 0xdfd7c0a7 +0, 633600, 4096, 0x2adc57e1 +0, 645120, 4096, 0x838bbc82 +0, 656640, 4096, 0x2c55de1a +0, 668160, 4096, 0xeae027f4 +0, 679680, 4096, 0x09fe00f6 +0, 691200, 4096, 0xa25d9970 +0, 702720, 4096, 0xedb11a20 +0, 714240, 4096, 0x9ce2e63e +0, 725760, 4096, 0xeb699974 +0, 737280, 4096, 0xcc04a296 +0, 748800, 4096, 0xe90e9a12 +0, 760320, 4096, 0xae85c0f7 +0, 771840, 4096, 0x7ee877db +0, 783360, 4096, 0x9ecf14ee +0, 794880, 4096, 0xa821cecd +0, 806400, 4096, 0x2714bb11 +0, 817920, 4096, 0x28f1c1e0 +0, 829440, 4096, 0xf81c4f60 +0, 840960, 4096, 0x1ae0e5a1 +0, 852480, 4096, 0xbdae9d9a +0, 864000, 4096, 0x5202e560 +0, 875520, 4096, 0x82408396 +0, 887040, 4096, 0xc850ce0c +0, 898560, 4096, 0x1d732d88 +0, 910080, 4096, 0xc5c01e33 +0, 921600, 4096, 0x84942d6c +0, 933120, 4096, 0x7c27cd3a +0, 944640, 4096, 0x22adc503 +0, 956160, 4096, 0xfbc3af31 +0, 967680, 4096, 0xe9652b18 +0, 979200, 4096, 0xae75987e +0, 990720, 4096, 0x0f7ea428 +0, 1002240, 4096, 0x92b89582 +0, 1013760, 4096, 0xf393d910 +0, 1025280, 4096, 0x6349b600 +0, 1036800, 4096, 0x16918dbd +0, 1048320, 4096, 0x14ee15ad +0, 1059840, 4096, 0x26b510d3 +0, 1071360, 4096, 0x97007bf8 +0, 1082880, 4096, 0x3718c509 +0, 1094400, 4096, 0x24a54ccd +0, 1105920, 4096, 0xc960df4e +0, 1117440, 4096, 0xc7cb6e6f +0, 1128960, 4096, 0x4c563ae5 +0, 1140480, 4096, 0x0dd51432 +0, 1152000, 4096, 0xdb4243c8 +0, 1163520, 4096, 0x9bb6417f +0, 1175040, 4096, 0xec6a40a1 +0, 1186560, 4096, 0x82d6c3b4 +0, 1198080, 4096, 0xd181e2ec +0, 1209600, 4096, 0xba5d7b55 +0, 1221120, 4096, 0x78fcb938 +0, 1232640, 4096, 0x6691671c +0, 1244160, 4096, 0x44fadee7 +0, 1255680, 4096, 0xa42720d5 +0, 1267200, 4096, 0xc1165a91 +0, 1278720, 4096, 0x86aa3e3f +0, 1290240, 4096, 0xab5ae57d +0, 1301760, 4096, 0x291a91f3 +0, 1313280, 4096, 0xfdf0dcfc +0, 1324800, 4096, 0x1ef91f67 +0, 1336320, 4096, 0xc899efee +0, 1347840, 4096, 0x5ade15ac +0, 1359360, 4096, 0x04516beb +0, 1370880, 4096, 0xbf5ebbb9 +0, 1382400, 4096, 0x4a235122 +0, 1393920, 4096, 0xd7a3f4a6 +0, 1405440, 4096, 0x5f900f20 +0, 1416960, 4096, 0xa90b4365 +0, 1428480, 4096, 0x63149dc4 +0, 1440000, 4096, 0xf12c1ee8 +0, 1451520, 4096, 0x6d0fec8c +0, 1463040, 4096, 0x65e07850 +0, 1474560, 4096, 0x16d951cc +0, 1486080, 4096, 0xd296d0c4 +0, 1497600, 4096, 0x619b2a53 +0, 1509120, 4096, 0x316972d5 +0, 1520640, 4096, 0xcfd64e21 +0, 1532160, 4096, 0xcbcb10c6 +0, 1543680, 4096, 0x20aeff7c +0, 1555200, 4096, 0xd205dabd +0, 1566720, 4096, 0xac9d3001 +0, 1578240, 4096, 0x6d53dfdd +0, 1589760, 4096, 0xbb9fe15c +0, 1601280, 4096, 0x1852b88b +0, 1612800, 4096, 0xb0acec01 +0, 1624320, 4096, 0xb52a9342 +0, 1635840, 4096, 0x7529faee +0, 1647360, 4096, 0x150ff449 +0, 1658880, 4096, 0xa81d31d9 +0, 1670400, 4096, 0xbcb8084a +0, 1681920, 4096, 0x07229514 +0, 1693440, 4096, 0xa85cfd88 +0, 1704960, 4096, 0x0aef9c27 +0, 1716480, 4096, 0x8ec47b39 +0, 1728000, 4096, 0x910b0560 +0, 1739520, 4096, 0x99a8578e +0, 1751040, 4096, 0xb3df1d84 +0, 1762560, 4096, 0x48e52559 +0, 1774080, 4096, 0xb25c4800 +0, 1785600, 4096, 0x913bc8ce +0, 1797120, 4096, 0xb736cc8c +0, 1808640, 4096, 0x13c66646 +0, 1820160, 4096, 0x70a71221 +0, 1831680, 4096, 0x3a50a08e +0, 1843200, 4096, 0xc0a037b0 +0, 1854720, 4096, 0x9a789475 +0, 1866240, 4096, 0xc890ca16 +0, 1877760, 4096, 0xa0d34bed +0, 1889280, 4096, 0x1689fa60 +0, 1900800, 4096, 0x5bac4c83 +0, 1912320, 1368, 0x904be5e5 diff --git a/tests/ref/fate/g722enc b/tests/ref/fate/g722enc index c1094565b5..9b8e469a8b 100644 --- a/tests/ref/fate/g722enc +++ b/tests/ref/fate/g722enc @@ -1 +1 @@ -750269cc236541df28e15da5c7b0df7a +94e2f200d6e05b47cec4aa3e94571cf3 diff --git a/tests/ref/fate/nuv b/tests/ref/fate/nuv index 46765f9086..c43c09cf85 100644 --- a/tests/ref/fate/nuv +++ b/tests/ref/fate/nuv @@ -18,7 +18,6 @@ 1, 20898, 4096, 0x28f7c6e5 0, 21021, 460800, 0x4b7f4df0 1, 22988, 4096, 0xca9d9df2 -0, 24024, 460800, 0xa57f20d0 1, 25078, 4096, 0x5c6b95a9 1, 27167, 4096, 0x0bdfc0bf 1, 29257, 4096, 0xd95a9277 diff --git a/tests/ref/fate/vqa-cc b/tests/ref/fate/vqa-cc index fdc7e72eeb..e15e727fa1 100644 --- a/tests/ref/fate/vqa-cc +++ b/tests/ref/fate/vqa-cc @@ -68,7 +68,6 @@ 1, 218996, 2940, 0xac8bb6c8 0, 222000, 192000, 0xb58c1566 1, 224996, 2940, 0xa503c73b -0, 228000, 192000, 0xb58c1566 1, 230996, 2940, 0x7cd588a3 1, 236996, 2940, 0xa6974b04 1, 242996, 2940, 0xbf448241 diff --git a/tests/ref/lavf/asf b/tests/ref/lavf/asf index c6e6b6baf4..ee819fad22 100644 --- a/tests/ref/lavf/asf +++ b/tests/ref/lavf/asf @@ -1,3 +1,3 @@ -3d410176ebf9ffdf99d2738922cef260 *./tests/data/lavf/lavf.asf -333489 ./tests/data/lavf/lavf.asf +cee474c51df8a3e67d01b733cafbb7e8 *./tests/data/lavf/lavf.asf +333581 ./tests/data/lavf/lavf.asf ./tests/data/lavf/lavf.asf CRC=0x9f5ab3e6 diff --git a/tests/ref/seek/lavf_asf b/tests/ref/seek/lavf_asf index 5aee39e049..868262cd99 100644 --- a/tests/ref/seek/lavf_asf +++ b/tests/ref/seek/lavf_asf @@ -2,9 +2,9 @@ ret: 0 st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos: 689 size: 28487 ret: 0 st:-1 flags:0 ts:-1.000000 ret: 0 st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos: 689 size: 28487 ret: 0 st:-1 flags:1 ts: 1.894167 -ret: 0 st: 1 flags:1 dts: 0.940000 pts: 0.940000 pos: 301489 size: 209 +ret: 0 st: 1 flags:1 dts: 0.444000 pts: 0.444000 pos: 147889 size: 209 ret: 0 st: 0 flags:0 ts: 0.788000 -ret: 0 st: 1 flags:1 dts: 0.940000 pts: 0.940000 pos: 301489 size: 209 +ret: 0 st: 1 flags:1 dts: 0.444000 pts: 0.444000 pos: 147889 size: 209 ret: 0 st: 0 flags:1 ts:-0.317000 ret: 0 st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos: 689 size: 28487 ret: 0 st: 1 flags:0 ts: 2.577000 @@ -22,11 +22,11 @@ ret: 0 st: 1 flags:1 dts: 0.940000 pts: 0.940000 pos: 301489 size: 209 ret: 0 st: 1 flags:0 ts:-0.058000 ret: 0 st: 1 flags:1 dts: 0.000000 pts: 0.000000 pos: 29489 size: 208 ret: 0 st: 1 flags:1 ts: 2.836000 -ret: 0 st: 1 flags:1 dts: 0.967000 pts: 0.967000 pos: 330289 size: 209 +ret: 0 st: 1 flags:1 dts: 0.862000 pts: 0.862000 pos: 279089 size: 209 ret: 0 st:-1 flags:0 ts: 1.730004 ret: 0 st: 1 flags:1 dts: 0.940000 pts: 0.940000 pos: 301489 size: 209 ret: 0 st:-1 flags:1 ts: 0.624171 -ret: 0 st: 1 flags:1 dts: 0.444000 pts: 0.444000 pos: 147889 size: 209 +ret: 0 st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos: 689 size: 28487 ret: 0 st: 0 flags:0 ts:-0.482000 ret: 0 st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos: 689 size: 28487 ret: 0 st: 0 flags:1 ts: 2.413000 @@ -34,19 +34,19 @@ ret: 0 st: 1 flags:1 dts: 0.940000 pts: 0.940000 pos: 301489 size: 209 ret: 0 st: 1 flags:0 ts: 1.307000 ret: 0 st: 1 flags:1 dts: 0.967000 pts: 0.967000 pos: 330289 size: 209 ret: 0 st: 1 flags:1 ts: 0.201000 -ret: 0 st: 1 flags:1 dts: 0.183000 pts: 0.183000 pos: 71089 size: 209 +ret: 0 st: 1 flags:1 dts: 0.967000 pts: 0.967000 pos: 330289 size: 209 ret: 0 st:-1 flags:0 ts:-0.904994 ret: 0 st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos: 689 size: 28487 ret: 0 st:-1 flags:1 ts: 1.989173 ret: 0 st: 1 flags:1 dts: 0.940000 pts: 0.940000 pos: 301489 size: 209 ret: 0 st: 0 flags:0 ts: 0.883000 -ret: 0 st: 1 flags:1 dts: 0.940000 pts: 0.940000 pos: 301489 size: 209 +ret: 0 st: 1 flags:1 dts: 0.444000 pts: 0.444000 pos: 147889 size: 209 ret: 0 st: 0 flags:1 ts:-0.222000 ret: 0 st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos: 689 size: 28487 ret: 0 st: 1 flags:0 ts: 2.672000 ret: 0 st: 1 flags:1 dts: 0.967000 pts: 0.967000 pos: 330289 size: 209 ret: 0 st: 1 flags:1 ts: 1.566000 -ret: 0 st: 1 flags:1 dts: 0.967000 pts: 0.967000 pos: 330289 size: 209 +ret: 0 st: 1 flags:1 dts: 0.862000 pts: 0.862000 pos: 279089 size: 209 ret: 0 st:-1 flags:0 ts: 0.460008 ret: 0 st: 1 flags:1 dts: 0.444000 pts: 0.444000 pos: 147889 size: 209 ret: 0 st:-1 flags:1 ts:-0.645825 diff --git a/tests/ref/seek/lavf_mxf b/tests/ref/seek/lavf_mxf index cc634a8af2..5f2cf5d1b0 100644 --- a/tests/ref/seek/lavf_mxf +++ b/tests/ref/seek/lavf_mxf @@ -7,8 +7,8 @@ ret: 0 st: 0 flags:0 ts: 0.800000 ret: 0 st: 0 flags:1 dts: 0.840000 pts: 0.960000 pos: 460800 size: 24712 ret: 0 st: 0 flags:1 ts:-0.320000 ret: 0 st: 0 flags:1 dts:-0.040000 pts: 0.000000 pos: 6144 size: 24801 -ret:-1 st: 1 flags:0 ts: 2.560000 -ret: 0 st: 1 flags:1 ts: 1.480000 +ret:-1 st: 1 flags:0 ts: 2.576667 +ret: 0 st: 1 flags:1 ts: 1.470833 ret: 0 st: 0 flags:1 dts: 0.840000 pts: 0.960000 pos: 460800 size: 24712 ret: 0 st:-1 flags:0 ts: 0.365002 ret: 0 st: 0 flags:1 dts: 0.360000 pts: 0.480000 pos: 211968 size: 24787 @@ -17,9 +17,9 @@ ret: 0 st: 0 flags:1 dts:-0.040000 pts: 0.000000 pos: 6144 size: 24801 ret:-1 st: 0 flags:0 ts: 2.160000 ret: 0 st: 0 flags:1 ts: 1.040000 ret: 0 st: 0 flags:1 dts: 0.840000 pts: 0.960000 pos: 460800 size: 24712 -ret: 0 st: 1 flags:0 ts:-0.040000 +ret: 0 st: 1 flags:0 ts:-0.058333 ret: 0 st: 0 flags:1 dts:-0.040000 pts: 0.000000 pos: 6144 size: 24801 -ret: 0 st: 1 flags:1 ts: 2.840000 +ret: 0 st: 1 flags:1 ts: 2.835833 ret: 0 st: 0 flags:1 dts: 0.840000 pts: 0.960000 pos: 460800 size: 24712 ret:-1 st:-1 flags:0 ts: 1.730004 ret: 0 st:-1 flags:1 ts: 0.624171 @@ -28,9 +28,9 @@ ret: 0 st: 0 flags:0 ts:-0.480000 ret: 0 st: 0 flags:1 dts:-0.040000 pts: 0.000000 pos: 6144 size: 24801 ret: 0 st: 0 flags:1 ts: 2.400000 ret: 0 st: 0 flags:1 dts: 0.840000 pts: 0.960000 pos: 460800 size: 24712 -ret:-1 st: 1 flags:0 ts: 1.320000 -ret: 0 st: 1 flags:1 ts: 0.200000 -ret: 0 st: 0 flags:1 dts:-0.040000 pts: 0.000000 pos: 6144 size: 24801 +ret:-1 st: 1 flags:0 ts: 1.306667 +ret: 0 st: 1 flags:1 ts: 0.200833 +ret: 0 st: 0 flags:1 dts: 0.840000 pts: 0.960000 pos: 460800 size: 24712 ret: 0 st:-1 flags:0 ts:-0.904994 ret: 0 st: 0 flags:1 dts:-0.040000 pts: 0.000000 pos: 6144 size: 24801 ret: 0 st:-1 flags:1 ts: 1.989173 @@ -39,8 +39,8 @@ ret: 0 st: 0 flags:0 ts: 0.880000 ret: 0 st: 0 flags:1 dts: 0.840000 pts: 0.960000 pos: 460800 size: 24712 ret: 0 st: 0 flags:1 ts:-0.240000 ret: 0 st: 0 flags:1 dts:-0.040000 pts: 0.000000 pos: 6144 size: 24801 -ret:-1 st: 1 flags:0 ts: 2.680000 -ret: 0 st: 1 flags:1 ts: 1.560000 +ret:-1 st: 1 flags:0 ts: 2.671667 +ret: 0 st: 1 flags:1 ts: 1.565833 ret: 0 st: 0 flags:1 dts: 0.840000 pts: 0.960000 pos: 460800 size: 24712 ret: 0 st:-1 flags:0 ts: 0.460008 ret: 0 st: 0 flags:1 dts: 0.840000 pts: 0.960000 pos: 460800 size: 24712 diff --git a/tests/ref/seek/lavf_mxf_d10 b/tests/ref/seek/lavf_mxf_d10 index 4cfe595415..e091c77633 100644 --- a/tests/ref/seek/lavf_mxf_d10 +++ b/tests/ref/seek/lavf_mxf_d10 @@ -7,10 +7,10 @@ ret: 0 st: 0 flags:0 ts: 0.800000 ret: 0 st: 0 flags:1 dts: 0.800000 pts: 0.800000 pos:4265984 size:150000 ret: 0 st: 0 flags:1 ts:-0.320000 ret: 0 st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos: 6144 size:150000 -ret: 0 st: 1 flags:0 ts: 2.560000 -ret: 0 st: 0 flags:1 dts: 0.960000 pts: 0.960000 pos:5117952 size:150000 -ret: 0 st: 1 flags:1 ts: 1.480000 -ret: 0 st: 0 flags:1 dts: 0.960000 pts: 0.960000 pos:5117952 size:150000 +ret: 0 st: 1 flags:0 ts: 2.576667 +ret: 0 st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos:5117952 size:150000 +ret: 0 st: 1 flags:1 ts: 1.470833 +ret: 0 st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos:5117952 size:150000 ret: 0 st:-1 flags:0 ts: 0.365002 ret: 0 st: 0 flags:1 dts: 0.360000 pts: 0.360000 pos:1923072 size:150000 ret: 0 st:-1 flags:1 ts:-0.740831 @@ -19,10 +19,10 @@ ret: 0 st: 0 flags:0 ts: 2.160000 ret: 0 st: 0 flags:1 dts: 0.960000 pts: 0.960000 pos:5117952 size:150000 ret: 0 st: 0 flags:1 ts: 1.040000 ret: 0 st: 0 flags:1 dts: 0.960000 pts: 0.960000 pos:5117952 size:150000 -ret: 0 st: 1 flags:0 ts:-0.040000 +ret: 0 st: 1 flags:0 ts:-0.058333 ret: 0 st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos: 6144 size:150000 -ret: 0 st: 1 flags:1 ts: 2.840000 -ret: 0 st: 0 flags:1 dts: 0.960000 pts: 0.960000 pos:5117952 size:150000 +ret: 0 st: 1 flags:1 ts: 2.835833 +ret: 0 st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos:5117952 size:150000 ret: 0 st:-1 flags:0 ts: 1.730004 ret: 0 st: 0 flags:1 dts: 0.960000 pts: 0.960000 pos:5117952 size:150000 ret: 0 st:-1 flags:1 ts: 0.624171 @@ -31,10 +31,10 @@ ret: 0 st: 0 flags:0 ts:-0.480000 ret: 0 st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos: 6144 size:150000 ret: 0 st: 0 flags:1 ts: 2.400000 ret: 0 st: 0 flags:1 dts: 0.960000 pts: 0.960000 pos:5117952 size:150000 -ret: 0 st: 1 flags:0 ts: 1.320000 -ret: 0 st: 0 flags:1 dts: 0.960000 pts: 0.960000 pos:5117952 size:150000 -ret: 0 st: 1 flags:1 ts: 0.200000 -ret: 0 st: 0 flags:1 dts: 0.200000 pts: 0.200000 pos:1071104 size:150000 +ret: 0 st: 1 flags:0 ts: 1.306667 +ret: 0 st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos:5117952 size:150000 +ret: 0 st: 1 flags:1 ts: 0.200833 +ret: 0 st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos:5117952 size:150000 ret: 0 st:-1 flags:0 ts:-0.904994 ret: 0 st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos: 6144 size:150000 ret: 0 st:-1 flags:1 ts: 1.989173 @@ -43,10 +43,10 @@ ret: 0 st: 0 flags:0 ts: 0.880000 ret: 0 st: 0 flags:1 dts: 0.880000 pts: 0.880000 pos:4691968 size:150000 ret: 0 st: 0 flags:1 ts:-0.240000 ret: 0 st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos: 6144 size:150000 -ret: 0 st: 1 flags:0 ts: 2.680000 -ret: 0 st: 0 flags:1 dts: 0.960000 pts: 0.960000 pos:5117952 size:150000 -ret: 0 st: 1 flags:1 ts: 1.560000 -ret: 0 st: 0 flags:1 dts: 0.960000 pts: 0.960000 pos:5117952 size:150000 +ret: 0 st: 1 flags:0 ts: 2.671667 +ret: 0 st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos:5117952 size:150000 +ret: 0 st: 1 flags:1 ts: 1.565833 +ret: 0 st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos:5117952 size:150000 ret: 0 st:-1 flags:0 ts: 0.460008 ret: 0 st: 0 flags:1 dts: 0.480000 pts: 0.480000 pos:2562048 size:150000 ret: 0 st:-1 flags:1 ts:-0.645825 diff --git a/tests/ref/seek/pcm_alaw_wav b/tests/ref/seek/pcm_alaw_wav index 22d95bf27f..e5466bd2d3 100644 --- a/tests/ref/seek/pcm_alaw_wav +++ b/tests/ref/seek/pcm_alaw_wav @@ -2,52 +2,52 @@ ret: 0 st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos: 58 size: 4096 ret: 0 st:-1 flags:0 ts:-1.000000 ret: 0 st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos: 58 size: 4096 ret: 0 st:-1 flags:1 ts: 1.894167 -ret: 0 st: 0 flags:1 dts: 1.894127 pts: 1.894127 pos: 30364 size: 4096 +ret: 0 st: 0 flags:1 dts: 1.894172 pts: 1.894172 pos: 167124 size: 4096 ret: 0 st: 0 flags:0 ts: 0.788345 -ret: 0 st: 0 flags:1 dts: 0.788367 pts: 0.788367 pos: 12672 size: 4096 +ret: 0 st: 0 flags:1 dts: 0.788345 pts: 0.788345 pos: 69590 size: 4096 ret: 0 st: 0 flags:1 ts:-0.317506 ret: 0 st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos: 58 size: 4096 ret: 0 st:-1 flags:0 ts: 2.576668 -ret: 0 st: 0 flags:1 dts: 2.576757 pts: 2.576757 pos: 41286 size: 4096 +ret: 0 st: 0 flags:1 dts: 2.576667 pts: 2.576667 pos: 227320 size: 4096 ret: 0 st:-1 flags:1 ts: 1.470835 -ret: 0 st: 0 flags:1 dts: 1.470748 pts: 1.470748 pos: 23590 size: 4096 +ret: 0 st: 0 flags:1 dts: 1.470839 pts: 1.470839 pos: 129786 size: 4096 ret: 0 st: 0 flags:0 ts: 0.365011 -ret: 0 st: 0 flags:1 dts: 0.365125 pts: 0.365125 pos: 5900 size: 4096 +ret: 0 st: 0 flags:1 dts: 0.365011 pts: 0.365011 pos: 32252 size: 4096 ret: 0 st: 0 flags:1 ts:-0.740839 ret: 0 st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos: 58 size: 4096 ret: 0 st:-1 flags:0 ts: 2.153336 -ret: 0 st: 0 flags:1 dts: 2.153379 pts: 2.153379 pos: 34512 size: 4096 +ret: 0 st: 0 flags:1 dts: 2.153333 pts: 2.153333 pos: 189982 size: 4096 ret: 0 st:-1 flags:1 ts: 1.047503 -ret: 0 st: 0 flags:1 dts: 1.047506 pts: 1.047506 pos: 16818 size: 4096 +ret: 0 st: 0 flags:1 dts: 1.047506 pts: 1.047506 pos: 92448 size: 4096 ret: 0 st: 0 flags:0 ts:-0.058322 ret: 0 st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos: 58 size: 4096 ret: 0 st: 0 flags:1 ts: 2.835828 -ret: 0 st: 0 flags:1 dts: 2.835760 pts: 2.835760 pos: 45430 size: 4096 +ret: 0 st: 0 flags:1 dts: 2.835828 pts: 2.835828 pos: 250178 size: 4096 ret: 0 st:-1 flags:0 ts: 1.730004 -ret: 0 st: 0 flags:1 dts: 1.730000 pts: 1.730000 pos: 27738 size: 4096 +ret: 0 st: 0 flags:1 dts: 1.730000 pts: 1.730000 pos: 152644 size: 4096 ret: 0 st:-1 flags:1 ts: 0.624171 -ret: 0 st: 0 flags:1 dts: 0.624127 pts: 0.624127 pos: 10044 size: 4096 +ret: 0 st: 0 flags:1 dts: 0.624172 pts: 0.624172 pos: 55110 size: 4096 ret: 0 st: 0 flags:0 ts:-0.481655 ret: 0 st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos: 58 size: 4096 ret: 0 st: 0 flags:1 ts: 2.412494 -ret: 0 st: 0 flags:1 dts: 2.412381 pts: 2.412381 pos: 38656 size: 4096 +ret: 0 st: 0 flags:1 dts: 2.412494 pts: 2.412494 pos: 212840 size: 4096 ret: 0 st:-1 flags:0 ts: 1.306672 -ret: 0 st: 0 flags:1 dts: 1.306757 pts: 1.306757 pos: 20966 size: 4096 +ret: 0 st: 0 flags:1 dts: 1.306667 pts: 1.306667 pos: 115306 size: 4096 ret: 0 st:-1 flags:1 ts: 0.200839 -ret: 0 st: 0 flags:1 dts: 0.200748 pts: 0.200748 pos: 3270 size: 4096 +ret: 0 st: 0 flags:1 dts: 0.200839 pts: 0.200839 pos: 17772 size: 4096 ret: 0 st: 0 flags:0 ts:-0.904989 ret: 0 st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos: 58 size: 4096 ret: 0 st: 0 flags:1 ts: 1.989184 -ret: 0 st: 0 flags:1 dts: 1.989116 pts: 1.989116 pos: 31884 size: 4096 +ret: 0 st: 0 flags:1 dts: 1.989184 pts: 1.989184 pos: 175504 size: 4096 ret: 0 st:-1 flags:0 ts: 0.883340 -ret: 0 st: 0 flags:1 dts: 0.883379 pts: 0.883379 pos: 14192 size: 4096 +ret: 0 st: 0 flags:1 dts: 0.883333 pts: 0.883333 pos: 77968 size: 4096 ret: 0 st:-1 flags:1 ts:-0.222493 ret: 0 st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos: 58 size: 4096 ret: 0 st: 0 flags:0 ts: 2.671678 -ret: 0 st: 0 flags:1 dts: 2.671746 pts: 2.671746 pos: 42806 size: 4096 +ret: 0 st: 0 flags:1 dts: 2.671678 pts: 2.671678 pos: 235700 size: 4096 ret: 0 st: 0 flags:1 ts: 1.565850 -ret: 0 st: 0 flags:1 dts: 1.565760 pts: 1.565760 pos: 25110 size: 4096 +ret: 0 st: 0 flags:1 dts: 1.565850 pts: 1.565850 pos: 138166 size: 4096 ret: 0 st:-1 flags:0 ts: 0.460008 -ret: 0 st: 0 flags:1 dts: 0.460000 pts: 0.460000 pos: 7418 size: 4096 +ret: 0 st: 0 flags:1 dts: 0.460000 pts: 0.460000 pos: 40630 size: 4096 ret: 0 st:-1 flags:1 ts:-0.645825 ret: 0 st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos: 58 size: 4096 diff --git a/tests/ref/seek/pcm_mulaw_wav b/tests/ref/seek/pcm_mulaw_wav index 22d95bf27f..e5466bd2d3 100644 --- a/tests/ref/seek/pcm_mulaw_wav +++ b/tests/ref/seek/pcm_mulaw_wav @@ -2,52 +2,52 @@ ret: 0 st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos: 58 size: 4096 ret: 0 st:-1 flags:0 ts:-1.000000 ret: 0 st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos: 58 size: 4096 ret: 0 st:-1 flags:1 ts: 1.894167 -ret: 0 st: 0 flags:1 dts: 1.894127 pts: 1.894127 pos: 30364 size: 4096 +ret: 0 st: 0 flags:1 dts: 1.894172 pts: 1.894172 pos: 167124 size: 4096 ret: 0 st: 0 flags:0 ts: 0.788345 -ret: 0 st: 0 flags:1 dts: 0.788367 pts: 0.788367 pos: 12672 size: 4096 +ret: 0 st: 0 flags:1 dts: 0.788345 pts: 0.788345 pos: 69590 size: 4096 ret: 0 st: 0 flags:1 ts:-0.317506 ret: 0 st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos: 58 size: 4096 ret: 0 st:-1 flags:0 ts: 2.576668 -ret: 0 st: 0 flags:1 dts: 2.576757 pts: 2.576757 pos: 41286 size: 4096 +ret: 0 st: 0 flags:1 dts: 2.576667 pts: 2.576667 pos: 227320 size: 4096 ret: 0 st:-1 flags:1 ts: 1.470835 -ret: 0 st: 0 flags:1 dts: 1.470748 pts: 1.470748 pos: 23590 size: 4096 +ret: 0 st: 0 flags:1 dts: 1.470839 pts: 1.470839 pos: 129786 size: 4096 ret: 0 st: 0 flags:0 ts: 0.365011 -ret: 0 st: 0 flags:1 dts: 0.365125 pts: 0.365125 pos: 5900 size: 4096 +ret: 0 st: 0 flags:1 dts: 0.365011 pts: 0.365011 pos: 32252 size: 4096 ret: 0 st: 0 flags:1 ts:-0.740839 ret: 0 st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos: 58 size: 4096 ret: 0 st:-1 flags:0 ts: 2.153336 -ret: 0 st: 0 flags:1 dts: 2.153379 pts: 2.153379 pos: 34512 size: 4096 +ret: 0 st: 0 flags:1 dts: 2.153333 pts: 2.153333 pos: 189982 size: 4096 ret: 0 st:-1 flags:1 ts: 1.047503 -ret: 0 st: 0 flags:1 dts: 1.047506 pts: 1.047506 pos: 16818 size: 4096 +ret: 0 st: 0 flags:1 dts: 1.047506 pts: 1.047506 pos: 92448 size: 4096 ret: 0 st: 0 flags:0 ts:-0.058322 ret: 0 st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos: 58 size: 4096 ret: 0 st: 0 flags:1 ts: 2.835828 -ret: 0 st: 0 flags:1 dts: 2.835760 pts: 2.835760 pos: 45430 size: 4096 +ret: 0 st: 0 flags:1 dts: 2.835828 pts: 2.835828 pos: 250178 size: 4096 ret: 0 st:-1 flags:0 ts: 1.730004 -ret: 0 st: 0 flags:1 dts: 1.730000 pts: 1.730000 pos: 27738 size: 4096 +ret: 0 st: 0 flags:1 dts: 1.730000 pts: 1.730000 pos: 152644 size: 4096 ret: 0 st:-1 flags:1 ts: 0.624171 -ret: 0 st: 0 flags:1 dts: 0.624127 pts: 0.624127 pos: 10044 size: 4096 +ret: 0 st: 0 flags:1 dts: 0.624172 pts: 0.624172 pos: 55110 size: 4096 ret: 0 st: 0 flags:0 ts:-0.481655 ret: 0 st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos: 58 size: 4096 ret: 0 st: 0 flags:1 ts: 2.412494 -ret: 0 st: 0 flags:1 dts: 2.412381 pts: 2.412381 pos: 38656 size: 4096 +ret: 0 st: 0 flags:1 dts: 2.412494 pts: 2.412494 pos: 212840 size: 4096 ret: 0 st:-1 flags:0 ts: 1.306672 -ret: 0 st: 0 flags:1 dts: 1.306757 pts: 1.306757 pos: 20966 size: 4096 +ret: 0 st: 0 flags:1 dts: 1.306667 pts: 1.306667 pos: 115306 size: 4096 ret: 0 st:-1 flags:1 ts: 0.200839 -ret: 0 st: 0 flags:1 dts: 0.200748 pts: 0.200748 pos: 3270 size: 4096 +ret: 0 st: 0 flags:1 dts: 0.200839 pts: 0.200839 pos: 17772 size: 4096 ret: 0 st: 0 flags:0 ts:-0.904989 ret: 0 st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos: 58 size: 4096 ret: 0 st: 0 flags:1 ts: 1.989184 -ret: 0 st: 0 flags:1 dts: 1.989116 pts: 1.989116 pos: 31884 size: 4096 +ret: 0 st: 0 flags:1 dts: 1.989184 pts: 1.989184 pos: 175504 size: 4096 ret: 0 st:-1 flags:0 ts: 0.883340 -ret: 0 st: 0 flags:1 dts: 0.883379 pts: 0.883379 pos: 14192 size: 4096 +ret: 0 st: 0 flags:1 dts: 0.883333 pts: 0.883333 pos: 77968 size: 4096 ret: 0 st:-1 flags:1 ts:-0.222493 ret: 0 st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos: 58 size: 4096 ret: 0 st: 0 flags:0 ts: 2.671678 -ret: 0 st: 0 flags:1 dts: 2.671746 pts: 2.671746 pos: 42806 size: 4096 +ret: 0 st: 0 flags:1 dts: 2.671678 pts: 2.671678 pos: 235700 size: 4096 ret: 0 st: 0 flags:1 ts: 1.565850 -ret: 0 st: 0 flags:1 dts: 1.565760 pts: 1.565760 pos: 25110 size: 4096 +ret: 0 st: 0 flags:1 dts: 1.565850 pts: 1.565850 pos: 138166 size: 4096 ret: 0 st:-1 flags:0 ts: 0.460008 -ret: 0 st: 0 flags:1 dts: 0.460000 pts: 0.460000 pos: 7418 size: 4096 +ret: 0 st: 0 flags:1 dts: 0.460000 pts: 0.460000 pos: 40630 size: 4096 ret: 0 st:-1 flags:1 ts:-0.645825 ret: 0 st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos: 58 size: 4096 diff --git a/tools/ffeval.c b/tools/ffeval.c index 027cd48237..d7b736a0cf 100644 --- a/tools/ffeval.c +++ b/tools/ffeval.c @@ -49,7 +49,7 @@ int main(int argc, char **argv) FILE *outfile = NULL, *infile = NULL; const char *prompt = "=> "; int count = 0, echo = 0; - char c; + int c; av_max_alloc(MAX_BLOCK_SIZE); diff --git a/tools/trasher.c b/tools/trasher.c index 61fd395f28..df6caf9932 100644 --- a/tools/trasher.c +++ b/tools/trasher.c @@ -54,7 +54,10 @@ int main(int argc, char **argv) while (count--) { int burst = 1 + ran() * (uint64_t) (abs(maxburst) - 1) / UINT32_MAX; int pos = ran() * (uint64_t) length / UINT32_MAX; - fseek(f, pos, SEEK_SET); + if (fseek(f, pos, SEEK_SET) < 0) { + fprintf(stderr, "seek failed\n"); + return 1; + } if (maxburst < 0) burst = -maxburst;